integration.ts 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154
  1. export * as Integration from "./integration.js"
  2. import { Schema } from "effect"
  3. import { optional } from "./schema.js"
  4. import { ephemeral, inventory } from "./event.js"
  5. import { Connection } from "./connection.js"
  6. import { ascending } from "./identifier.js"
  7. import { statics } from "./schema.js"
  8. import { IntegrationID, IntegrationMethodID } from "./integration-id.js"
  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 CommandMethod extends Schema.Schema.Type<typeof CommandMethod> {}
  51. export const CommandMethod = Schema.Struct({
  52. id: MethodID,
  53. type: Schema.Literal("command"),
  54. label: Schema.String,
  55. command: Schema.Array(Schema.String),
  56. }).annotate({ identifier: "Integration.CommandMethod" })
  57. export interface KeyMethod extends Schema.Schema.Type<typeof KeyMethod> {}
  58. export const KeyMethod = Schema.Struct({
  59. type: Schema.Literal("key"),
  60. label: optional(Schema.String),
  61. }).annotate({ identifier: "Integration.KeyMethod" })
  62. export interface EnvMethod extends Schema.Schema.Type<typeof EnvMethod> {}
  63. export const EnvMethod = Schema.Struct({
  64. type: Schema.Literal("env"),
  65. names: Schema.Array(Schema.String),
  66. }).annotate({ identifier: "Integration.EnvMethod" })
  67. export const Method = Schema.Union([OAuthMethod, CommandMethod, KeyMethod, EnvMethod])
  68. .pipe(Schema.toTaggedUnion("type"))
  69. .annotate({ identifier: "Integration.Method" })
  70. export type Method = typeof Method.Type
  71. export const Inputs = Schema.Record(Schema.String, Schema.String).annotate({ identifier: "Integration.Inputs" })
  72. export type Inputs = typeof Inputs.Type
  73. const Updated = ephemeral({
  74. type: "integration.updated",
  75. schema: {},
  76. })
  77. const ConnectionUpdated = ephemeral({
  78. type: "integration.connection.updated",
  79. schema: { integrationID: ID },
  80. })
  81. export const Event = { Updated, ConnectionUpdated, Definitions: inventory(Updated, ConnectionUpdated) }
  82. export interface Ref extends Schema.Schema.Type<typeof Ref> {}
  83. export const Ref = Schema.Struct({
  84. id: ID,
  85. name: Schema.String,
  86. }).annotate({ identifier: "Integration.Ref" })
  87. export const Info = Schema.Struct({
  88. id: ID,
  89. name: Schema.String,
  90. methods: Schema.Array(Method),
  91. connections: Schema.Array(Connection.Info),
  92. }).annotate({ identifier: "Integration.Info" })
  93. export interface Info extends Schema.Schema.Type<typeof Info> {}
  94. export const AttemptID = Schema.String.pipe(
  95. Schema.brand("Integration.AttemptID"),
  96. statics((schema) => ({ create: () => schema.make("con_" + ascending()) })),
  97. )
  98. export type AttemptID = typeof AttemptID.Type
  99. const AttemptTime = Schema.Struct({
  100. created: Schema.Number,
  101. expires: Schema.Number,
  102. })
  103. export class Attempt extends Schema.Class<Attempt>("Integration.Attempt")({
  104. attemptID: AttemptID,
  105. url: Schema.String,
  106. instructions: Schema.String,
  107. mode: Schema.Literals(["auto", "code"]),
  108. time: AttemptTime,
  109. }) {}
  110. export const AttemptStatus = Schema.Union([
  111. Schema.Struct({ status: Schema.Literal("pending"), time: AttemptTime }),
  112. Schema.Struct({ status: Schema.Literal("complete"), time: AttemptTime }),
  113. Schema.Struct({ status: Schema.Literal("failed"), message: Schema.String, time: AttemptTime }),
  114. Schema.Struct({ status: Schema.Literal("expired"), time: AttemptTime }),
  115. ])
  116. .pipe(Schema.toTaggedUnion("status"))
  117. .annotate({ identifier: "Integration.AttemptStatus" })
  118. export type AttemptStatus = typeof AttemptStatus.Type
  119. export interface CommandAttempt extends Schema.Schema.Type<typeof CommandAttempt> {}
  120. export const CommandAttempt = Schema.Struct({
  121. attemptID: AttemptID,
  122. time: AttemptTime,
  123. }).annotate({ identifier: "Integration.CommandAttempt" })
  124. export const CommandAttemptStatus = Schema.Union([
  125. Schema.Struct({ status: Schema.Literal("pending"), message: optional(Schema.String), time: AttemptTime }),
  126. Schema.Struct({ status: Schema.Literal("complete"), time: AttemptTime }),
  127. Schema.Struct({ status: Schema.Literal("failed"), message: Schema.String, time: AttemptTime }),
  128. Schema.Struct({ status: Schema.Literal("expired"), time: AttemptTime }),
  129. ])
  130. .pipe(Schema.toTaggedUnion("status"))
  131. .annotate({ identifier: "Integration.CommandAttemptStatus" })
  132. export type CommandAttemptStatus = typeof CommandAttemptStatus.Type