integration.ts 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129
  1. export * as Integration from "./integration"
  2. import { Schema } from "effect"
  3. import { optional } from "./schema"
  4. import { define, inventory } from "./event"
  5. import { Connection } from "./connection"
  6. import { ascending } from "./identifier"
  7. import { statics } from "./schema"
  8. import { IntegrationID, IntegrationMethodID } from "./integration-id"
  9. export const ID = IntegrationID
  10. export type ID = typeof ID.Type
  11. export const MethodID = IntegrationMethodID
  12. export type MethodID = typeof MethodID.Type
  13. export interface When extends Schema.Schema.Type<typeof When> {}
  14. export const When = Schema.Struct({
  15. key: Schema.String,
  16. op: Schema.Literals(["eq", "neq"]),
  17. value: Schema.String,
  18. }).annotate({ identifier: "Integration.When" })
  19. export interface TextPrompt extends Schema.Schema.Type<typeof TextPrompt> {}
  20. export const TextPrompt = Schema.Struct({
  21. type: Schema.Literal("text"),
  22. key: Schema.String,
  23. message: Schema.String,
  24. placeholder: optional(Schema.String),
  25. when: optional(When),
  26. }).annotate({ identifier: "Integration.TextPrompt" })
  27. export interface SelectPrompt extends Schema.Schema.Type<typeof SelectPrompt> {}
  28. export const SelectPrompt = Schema.Struct({
  29. type: Schema.Literal("select"),
  30. key: Schema.String,
  31. message: Schema.String,
  32. options: Schema.Array(
  33. Schema.Struct({
  34. label: Schema.String,
  35. value: Schema.String,
  36. hint: optional(Schema.String),
  37. }),
  38. ),
  39. when: optional(When),
  40. }).annotate({ identifier: "Integration.SelectPrompt" })
  41. export const Prompt = Schema.Union([TextPrompt, SelectPrompt]).pipe(Schema.toTaggedUnion("type"))
  42. export type Prompt = typeof Prompt.Type
  43. export interface OAuthMethod extends Schema.Schema.Type<typeof OAuthMethod> {}
  44. export const OAuthMethod = Schema.Struct({
  45. id: MethodID,
  46. type: Schema.Literal("oauth"),
  47. label: Schema.String,
  48. prompts: optional(Schema.Array(Prompt)),
  49. }).annotate({ identifier: "Integration.OAuthMethod" })
  50. export interface KeyMethod extends Schema.Schema.Type<typeof KeyMethod> {}
  51. export const KeyMethod = Schema.Struct({
  52. type: Schema.Literal("key"),
  53. label: optional(Schema.String),
  54. }).annotate({ identifier: "Integration.KeyMethod" })
  55. export interface EnvMethod extends Schema.Schema.Type<typeof EnvMethod> {}
  56. export const EnvMethod = Schema.Struct({
  57. type: Schema.Literal("env"),
  58. names: Schema.Array(Schema.String),
  59. }).annotate({ identifier: "Integration.EnvMethod" })
  60. export const Method = Schema.Union([OAuthMethod, KeyMethod, EnvMethod])
  61. .pipe(Schema.toTaggedUnion("type"))
  62. .annotate({ identifier: "Integration.Method" })
  63. export type Method = typeof Method.Type
  64. export const Inputs = Schema.Record(Schema.String, Schema.String).annotate({ identifier: "Integration.Inputs" })
  65. export type Inputs = typeof Inputs.Type
  66. const Updated = define({
  67. type: "integration.updated",
  68. schema: {},
  69. })
  70. const ConnectionUpdated = define({
  71. type: "integration.connection.updated",
  72. schema: { integrationID: ID },
  73. })
  74. export const Event = { Updated, ConnectionUpdated, Definitions: inventory(Updated, ConnectionUpdated) }
  75. export interface Ref extends Schema.Schema.Type<typeof Ref> {}
  76. export const Ref = Schema.Struct({
  77. id: ID,
  78. name: Schema.String,
  79. }).annotate({ identifier: "Integration.Ref" })
  80. export class Info extends Schema.Class<Info>("Integration.Info")({
  81. id: ID,
  82. name: Schema.String,
  83. methods: Schema.Array(Method),
  84. connections: Schema.Array(Connection.Info),
  85. }) {}
  86. export const AttemptID = Schema.String.pipe(
  87. Schema.brand("Integration.AttemptID"),
  88. statics((schema) => ({ create: () => schema.make("con_" + ascending()) })),
  89. )
  90. export type AttemptID = typeof AttemptID.Type
  91. const AttemptTime = Schema.Struct({
  92. created: Schema.Number,
  93. expires: Schema.Number,
  94. })
  95. export class Attempt extends Schema.Class<Attempt>("Integration.Attempt")({
  96. attemptID: AttemptID,
  97. url: Schema.String,
  98. instructions: Schema.String,
  99. mode: Schema.Literals(["auto", "code"]),
  100. time: AttemptTime,
  101. }) {}
  102. export const AttemptStatus = Schema.Union([
  103. Schema.Struct({ status: Schema.Literal("pending"), time: AttemptTime }),
  104. Schema.Struct({ status: Schema.Literal("complete"), time: AttemptTime }),
  105. Schema.Struct({ status: Schema.Literal("failed"), message: Schema.String, time: AttemptTime }),
  106. Schema.Struct({ status: Schema.Literal("expired"), time: AttemptTime }),
  107. ])
  108. .pipe(Schema.toTaggedUnion("status"))
  109. .annotate({ identifier: "Integration.AttemptStatus" })
  110. export type AttemptStatus = typeof AttemptStatus.Type