@executor-js/sdk 1.4.28 → 1.4.30
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/blob.d.ts +2 -1
- package/dist/blob.d.ts.map +1 -1
- package/dist/chunk-2LU3SC64.js +7 -0
- package/dist/chunk-2LU3SC64.js.map +1 -0
- package/dist/chunk-7D4SUZUM.js +38 -0
- package/dist/chunk-7D4SUZUM.js.map +1 -0
- package/dist/chunk-B4YGTZF6.js +22 -0
- package/dist/chunk-B4YGTZF6.js.map +1 -0
- package/dist/chunk-BZNIRSMG.js +7873 -0
- package/dist/chunk-BZNIRSMG.js.map +1 -0
- package/dist/chunk-ECMCGZYE.js +5814 -0
- package/dist/chunk-ECMCGZYE.js.map +1 -0
- package/dist/{chunk-6SQWMOM4.js → chunk-MLNVNVRI.js} +2 -6
- package/dist/chunk-MLNVNVRI.js.map +1 -0
- package/dist/chunk-P2WKYAC5.js +1 -0
- package/dist/chunk-P2WKYAC5.js.map +1 -0
- package/dist/chunk-ZANQD7E2.js +1035 -0
- package/dist/chunk-ZANQD7E2.js.map +1 -0
- package/dist/client.d.ts +3 -0
- package/dist/client.d.ts.map +1 -1
- package/dist/client.js +2 -0
- package/dist/client.js.map +1 -1
- package/dist/config.d.ts +3 -7
- package/dist/config.d.ts.map +1 -1
- package/dist/core-schema.d.ts +283 -408
- package/dist/core-schema.d.ts.map +1 -1
- package/dist/core-tools.d.ts +6 -0
- package/dist/core-tools.d.ts.map +1 -0
- package/dist/core.js +120 -168
- package/dist/core.js.map +1 -1
- package/dist/credential-bindings.d.ts +86 -24
- package/dist/credential-bindings.d.ts.map +1 -1
- package/dist/errors.d.ts +1 -0
- package/dist/errors.d.ts.map +1 -1
- package/dist/executor.d.ts +46 -12
- package/dist/executor.d.ts.map +1 -1
- package/dist/fuma-runtime.d.ts +50 -0
- package/dist/fuma-runtime.d.ts.map +1 -0
- package/dist/http-source.d.ts +109 -0
- package/dist/http-source.d.ts.map +1 -0
- package/dist/http-source.js +155 -0
- package/dist/http-source.js.map +1 -0
- package/dist/index.d.ts +17 -12
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +44 -21
- package/dist/index.js.map +1 -1
- package/dist/oauth-service.d.ts +2 -10
- package/dist/oauth-service.d.ts.map +1 -1
- package/dist/oauth.d.ts +9 -1
- package/dist/oauth.d.ts.map +1 -1
- package/dist/plugin-storage.d.ts +40 -0
- package/dist/plugin-storage.d.ts.map +1 -0
- package/dist/plugin.d.ts +110 -34
- package/dist/plugin.d.ts.map +1 -1
- package/dist/promise-executor.d.ts +33 -8
- package/dist/promise-executor.d.ts.map +1 -1
- package/dist/promise.d.ts +3 -3
- package/dist/promise.d.ts.map +1 -1
- package/dist/schema-refs.d.ts +1 -0
- package/dist/schema-refs.d.ts.map +1 -1
- package/dist/schema-refs.test.d.ts +2 -0
- package/dist/schema-refs.test.d.ts.map +1 -0
- package/dist/schema-types.d.ts +22 -8
- package/dist/schema-types.d.ts.map +1 -1
- package/dist/scope-policy.d.ts +23 -0
- package/dist/scope-policy.d.ts.map +1 -0
- package/dist/scope-policy.test.d.ts +2 -0
- package/dist/scope-policy.test.d.ts.map +1 -0
- package/dist/scope.d.ts +10 -0
- package/dist/scope.d.ts.map +1 -1
- package/dist/secrets.d.ts +1 -1
- package/dist/secrets.d.ts.map +1 -1
- package/dist/shared.d.ts +13 -0
- package/dist/shared.d.ts.map +1 -0
- package/dist/shared.js +103 -0
- package/dist/shared.js.map +1 -0
- package/dist/sqlite-test-db-OK2WQNR5.js +8 -0
- package/dist/sqlite-test-db-OK2WQNR5.js.map +1 -0
- package/dist/sqlite-test-db.d.ts +22 -0
- package/dist/sqlite-test-db.d.ts.map +1 -0
- package/dist/test-config.d.ts +45 -4
- package/dist/test-config.d.ts.map +1 -1
- package/dist/testing/oauth-test-server.d.ts +80 -0
- package/dist/testing/oauth-test-server.d.ts.map +1 -0
- package/dist/testing.d.ts +4 -1
- package/dist/testing.d.ts.map +1 -1
- package/dist/testing.js +706 -18
- package/dist/testing.js.map +1 -1
- package/dist/testing.test.d.ts +2 -0
- package/dist/testing.test.d.ts.map +1 -0
- package/dist/tool-result.d.ts +22 -0
- package/dist/tool-result.d.ts.map +1 -0
- package/dist/tool-result.test.d.ts +2 -0
- package/dist/tool-result.test.d.ts.map +1 -0
- package/dist/types.d.ts +1 -0
- package/dist/types.d.ts.map +1 -1
- package/dist/vendor/json-schema-to-typescript/applySchemaTyping.d.ts +3 -0
- package/dist/vendor/json-schema-to-typescript/applySchemaTyping.d.ts.map +1 -0
- package/dist/vendor/json-schema-to-typescript/compat.d.ts +10 -0
- package/dist/vendor/json-schema-to-typescript/compat.d.ts.map +1 -0
- package/dist/vendor/json-schema-to-typescript/formatter.d.ts +3 -0
- package/dist/vendor/json-schema-to-typescript/formatter.d.ts.map +1 -0
- package/dist/vendor/json-schema-to-typescript/generator.d.ts +7 -0
- package/dist/vendor/json-schema-to-typescript/generator.d.ts.map +1 -0
- package/dist/vendor/json-schema-to-typescript/index.d.ts +93 -0
- package/dist/vendor/json-schema-to-typescript/index.d.ts.map +1 -0
- package/dist/vendor/json-schema-to-typescript/linker.d.ts +8 -0
- package/dist/vendor/json-schema-to-typescript/linker.d.ts.map +1 -0
- package/dist/vendor/json-schema-to-typescript/normalizer.d.ts +5 -0
- package/dist/vendor/json-schema-to-typescript/normalizer.d.ts.map +1 -0
- package/dist/vendor/json-schema-to-typescript/optimizer.d.ts +4 -0
- package/dist/vendor/json-schema-to-typescript/optimizer.d.ts.map +1 -0
- package/dist/vendor/json-schema-to-typescript/optionValidator.d.ts +3 -0
- package/dist/vendor/json-schema-to-typescript/optionValidator.d.ts.map +1 -0
- package/dist/vendor/json-schema-to-typescript/parser.d.ts +8 -0
- package/dist/vendor/json-schema-to-typescript/parser.d.ts.map +1 -0
- package/dist/vendor/json-schema-to-typescript/resolver.d.ts +7 -0
- package/dist/vendor/json-schema-to-typescript/resolver.d.ts.map +1 -0
- package/dist/vendor/json-schema-to-typescript/types/AST.d.ts +108 -0
- package/dist/vendor/json-schema-to-typescript/types/AST.d.ts.map +1 -0
- package/dist/vendor/json-schema-to-typescript/types/JSONSchema.d.ts +103 -0
- package/dist/vendor/json-schema-to-typescript/types/JSONSchema.d.ts.map +1 -0
- package/dist/vendor/json-schema-to-typescript/types/json-schema.d.ts +34 -0
- package/dist/vendor/json-schema-to-typescript/types/json-schema.d.ts.map +1 -0
- package/dist/vendor/json-schema-to-typescript/typesOfSchema.d.ts +11 -0
- package/dist/vendor/json-schema-to-typescript/typesOfSchema.d.ts.map +1 -0
- package/dist/vendor/json-schema-to-typescript/utils.d.ts +30 -0
- package/dist/vendor/json-schema-to-typescript/utils.d.ts.map +1 -0
- package/dist/vendor/json-schema-to-typescript/validator.d.ts +3 -0
- package/dist/vendor/json-schema-to-typescript/validator.d.ts.map +1 -0
- package/package.json +17 -2
- package/dist/chunk-6SQWMOM4.js.map +0 -1
- package/dist/chunk-I2OEQ2GJ.js +0 -103
- package/dist/chunk-I2OEQ2GJ.js.map +0 -1
- package/dist/chunk-OIJL6F6M.js +0 -5507
- package/dist/chunk-OIJL6F6M.js.map +0 -1
- package/dist/error-handling.test.d.ts +0 -2
- package/dist/error-handling.test.d.ts.map +0 -1
- package/dist/scoped-adapter.d.ts +0 -28
- package/dist/scoped-adapter.d.ts.map +0 -1
- package/dist/scoped-adapter.test.d.ts +0 -2
- package/dist/scoped-adapter.test.d.ts.map +0 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/fuma-runtime.ts","../src/ids.ts","../src/core-schema.ts","../src/scope-policy.ts","../src/credential-bindings.ts","../src/oauth.ts","../src/policies.ts","../src/types.ts","../src/usages.ts","../src/errors.ts","../src/plugin-storage.ts"],"sourcesContent":["import { Cause, Context, Data, Effect, Exit, Layer, Predicate } from \"effect\";\nimport type { AbstractQuery } from \"fumadb/query\";\nimport type { AnySchema, AnyTable, Schema as FumaSchema } from \"fumadb/schema\";\n\nexport class StorageError extends Data.TaggedError(\"StorageError\")<{\n readonly message: string;\n readonly cause: unknown;\n}> {}\n\nexport class UniqueViolationError extends Data.TaggedError(\"UniqueViolationError\")<{\n readonly model?: string;\n}> {}\n\nexport type StorageFailure = StorageError | UniqueViolationError;\n\nexport type FumaTables = Record<string, AnyTable>;\ntype EmptyFumaSchema = FumaSchema<\"latest\", Record<never, never>>;\nexport type TablesToFumaSchema<TTables extends FumaTables | undefined> = TTables extends FumaTables\n ? string extends keyof TTables\n ? AnySchema\n : FumaSchema<\"latest\", TTables>\n : EmptyFumaSchema;\nexport type FumaDb<TSchema extends AnySchema = AnySchema> = AbstractQuery<TSchema>;\nexport type FumaQuery<TSchema extends AnySchema = AnySchema> = Omit<\n AbstractQuery<TSchema>,\n \"internal\" | \"withContext\" | \"transaction\"\n> & {\n readonly transaction: <A>(run: (db: FumaQuery<TSchema>) => Promise<A>) => Promise<A>;\n};\nexport type FumaRow<TTable extends AnyTable> = Omit<\n {\n readonly [K in keyof TTable[\"columns\"]]: TTable[\"columns\"][K][\"$out\"];\n },\n \"row_id\"\n>;\n\nconst isUniqueViolation = (cause: unknown): boolean => {\n let current = cause;\n for (let i = 0; i < 5; i += 1) {\n const err =\n current && typeof current === \"object\" ? (current as Record<string, unknown>) : null;\n if (!err) return false;\n const code = err[\"code\"];\n // oxlint-disable-next-line executor/no-unknown-error-message -- boundary: database drivers expose unique-violation details on native error messages\n const message = err[\"message\"];\n const innerCause = err[\"cause\"];\n if (code === \"23505\") return true;\n if (\n typeof message === \"string\" &&\n /unique constraint|duplicate key|violates unique constraint/i.test(message)\n ) {\n return true;\n }\n if (!innerCause || innerCause === current) return false;\n current = innerCause;\n }\n return false;\n};\n\nconst causeMessage = (cause: unknown): string | undefined => {\n const message =\n cause && typeof cause === \"object\"\n ? // oxlint-disable-next-line executor/no-unknown-error-message -- boundary: preserve database driver error text inside typed StorageError\n (cause as Record<string, unknown>)[\"message\"]\n : undefined;\n return typeof message === \"string\" && message.length > 0 ? message : undefined;\n};\n\nexport const isStorageFailure = (error: unknown): error is StorageFailure =>\n Predicate.isTagged(error, \"StorageError\") || Predicate.isTagged(error, \"UniqueViolationError\");\n\nexport const fumaFailureFromCause = (label: string, cause: unknown): StorageFailure => {\n if (isStorageFailure(cause)) return cause;\n if (isUniqueViolation(cause)) return new UniqueViolationError({ model: label });\n return new StorageError({\n message: causeMessage(cause) ?? `FumaDB operation failed: ${label}`,\n cause,\n });\n};\n\nexport const fumaEffect = <A>(\n label: string,\n run: () => Promise<A>,\n): Effect.Effect<A, StorageFailure> =>\n Effect.tryPromise({\n try: run,\n catch: (cause) => fumaFailureFromCause(label, cause),\n });\n\nexport const activeFumaDbRef = Context.Reference<FumaDb | null>(\"executor/ActiveFumaDb\", {\n defaultValue: () => null,\n});\n\nclass TransactionEffectFailure {\n constructor(readonly error: unknown) {}\n}\n\nclass TransactionEffectDefect {\n constructor(readonly cause: unknown) {}\n}\n\nexport type IFumaClient<TSchema extends AnySchema = AnySchema> = Readonly<{\n use: <A>(\n label: string,\n fn: (db: FumaQuery<TSchema>) => Promise<A>,\n ) => Effect.Effect<A, StorageFailure>;\n transaction: <A, E>(effect: Effect.Effect<A, E>) => Effect.Effect<A, E | StorageFailure>;\n}>;\n\nexport interface MakeFumaClientOptions {\n readonly tables?: ReadonlySet<string>;\n}\n\nconst isAllowedTable = (tables: ReadonlySet<string> | undefined, table: PropertyKey): boolean =>\n tables === undefined || (typeof table === \"string\" && tables.has(table));\n\nconst assertAllowedTable = (tables: ReadonlySet<string> | undefined, table: PropertyKey): void => {\n if (isAllowedTable(tables, table)) return;\n // oxlint-disable-next-line executor/no-try-catch-or-throw -- boundary: plugin-facing FumaDB facade rejects unavailable tables synchronously before query execution\n throw new StorageError({\n message: `FumaDB table \"${String(table)}\" is not available through this storage boundary.`,\n cause: undefined,\n });\n};\n\nconst makeSafeFumaQuery = <TSchema extends AnySchema>(\n db: FumaDb<TSchema>,\n options: MakeFumaClientOptions,\n): FumaQuery<TSchema> => {\n const table = <TableName extends keyof TSchema[\"tables\"]>(name: TableName): TableName => {\n assertAllowedTable(options.tables, name);\n return name;\n };\n\n const query: FumaQuery<TSchema> = {\n count: (name, value) => db.count(table(name), value),\n create: (name, value) => db.create(table(name), value),\n createMany: (name, values) => db.createMany(table(name), values),\n deleteMany: (name, value) => db.deleteMany(table(name), value),\n findFirst: (name, value) => db.findFirst(table(name), value),\n findMany: (name, value) => db.findMany(table(name), value),\n transaction: (run) =>\n db.transaction((transactionDb) => run(makeSafeFumaQuery(transactionDb, options))),\n updateMany: (name, value) => db.updateMany(table(name), value),\n upsert: (name, value) => db.upsert(table(name), value),\n };\n\n return Object.freeze(query);\n};\n\nexport const makeFumaClient = (db: FumaDb, options: MakeFumaClientOptions = {}): IFumaClient => {\n const use: IFumaClient[\"use\"] = (label, fn) =>\n Effect.flatMap(Effect.service(activeFumaDbRef), (active) =>\n fumaEffect(label, () => fn(makeSafeFumaQuery(active ?? db, options))),\n ).pipe(Effect.withSpan(`fumadb.${label}`));\n\n const transaction = <A, E>(effect: Effect.Effect<A, E>): Effect.Effect<A, E | StorageFailure> =>\n Effect.flatMap(Effect.service(activeFumaDbRef), (active) => {\n if (active) return effect as Effect.Effect<unknown, unknown>;\n\n return Effect.tryPromise({\n try: () =>\n db.transaction(async (transactionDb) => {\n const exit = await Effect.runPromiseExit(\n effect.pipe(Effect.provideService(activeFumaDbRef, transactionDb)),\n );\n if (Exit.isSuccess(exit)) return exit.value;\n\n const failure = exit.cause.reasons.find(Cause.isFailReason);\n // oxlint-disable-next-line executor/no-try-catch-or-throw -- boundary: FumaDB transactions roll back when the callback rejects\n if (failure) throw new TransactionEffectFailure(failure.error);\n // oxlint-disable-next-line executor/no-try-catch-or-throw -- boundary: FumaDB transactions roll back when the callback rejects\n throw new TransactionEffectDefect(exit.cause);\n }),\n catch: (cause): E | StorageFailure => {\n if (cause instanceof TransactionEffectFailure) return cause.error as E;\n if (cause instanceof TransactionEffectDefect) {\n return fumaFailureFromCause(\"transaction\", cause.cause);\n }\n return fumaFailureFromCause(\"transaction\", cause);\n },\n });\n }).pipe(Effect.withSpan(\"fumadb.transaction\")) as Effect.Effect<A, E | StorageFailure>;\n\n return { use, transaction };\n};\n\nexport class FumaClient extends Context.Service<FumaClient, IFumaClient>()(\"executor/FumaClient\") {\n static layer = (db: FumaDb) => Layer.succeed(this)(makeFumaClient(db));\n}\n","import { Schema } from \"effect\";\n\nexport const ScopeId = Schema.String.pipe(Schema.brand(\"ScopeId\"));\nexport type ScopeId = typeof ScopeId.Type;\n\nexport const ToolId = Schema.String.pipe(Schema.brand(\"ToolId\"));\nexport type ToolId = typeof ToolId.Type;\n\nexport const SecretId = Schema.String.pipe(Schema.brand(\"SecretId\"));\nexport type SecretId = typeof SecretId.Type;\n\nexport const PolicyId = Schema.String.pipe(Schema.brand(\"PolicyId\"));\nexport type PolicyId = typeof PolicyId.Type;\n\nexport const ConnectionId = Schema.String.pipe(Schema.brand(\"ConnectionId\"));\nexport type ConnectionId = typeof ConnectionId.Type;\n\nexport const CredentialBindingId = Schema.String.pipe(Schema.brand(\"CredentialBindingId\"));\nexport type CredentialBindingId = typeof CredentialBindingId.Type;\n","import { column, idColumn, table, type AnyColumn, type AnyTable } from \"fumadb/schema\";\nimport type { FumaRow } from \"./fuma-runtime\";\nimport {\n assertExecutorScopeAllowed,\n assertExecutorScopeTargetValue,\n executorScopePolicyName,\n executorUnscopedPolicyName,\n executorScopeIds,\n requireExecutorScopeTarget,\n type ExecutorScopePolicyContext,\n} from \"./scope-policy\";\n\ntype UserColumns = Record<string, AnyColumn>;\n\nexport const textColumn = (name: string) => column(name, \"string\");\nexport const nullableTextColumn = (name: string) => column(name, \"string\").nullable();\nexport const boolColumn = (name: string, defaultValue: boolean) =>\n column(name, \"bool\").defaultTo(defaultValue);\nexport const bigintColumn = (name: string) => column(name, \"bigint\");\nexport const nullableBigintColumn = (name: string) => column(name, \"bigint\").nullable();\nexport const jsonColumn = (name: string) => column(name, \"json\");\nexport const nullableJsonColumn = (name: string) => column(name, \"json\").nullable();\nexport const dateColumn = (name: string) => column(name, \"timestamp\");\n\nconst unscopedExecutorTable = <const TColumns extends UserColumns>(\n name: string,\n columns: TColumns,\n) => {\n const out = table(name, {\n ...columns,\n row_id: idColumn(\"row_id\", \"varchar(255)\").defaultTo$(\"auto\"),\n id: column(\"id\", \"varchar(255)\"),\n });\n out.unique(`${name}_id_uidx`, [\"id\"]);\n return out.policy({\n name: executorUnscopedPolicyName,\n });\n};\n\nconst scopedExecutorTableBase = <const TColumns extends UserColumns>(\n name: string,\n columns: TColumns,\n) => {\n const out = table(name, {\n ...columns,\n row_id: idColumn(\"row_id\", \"varchar(255)\").defaultTo$(\"auto\"),\n id: column(\"id\", \"varchar(255)\"),\n scope_id: column(\"scope_id\", \"varchar(255)\"),\n });\n out.unique(`${name}_scope_id_id_uidx`, [\"scope_id\", \"id\"]);\n return out;\n};\n\nexport const scopedExecutorTable = <const TColumns extends UserColumns>(\n name: string,\n columns: TColumns,\n) => {\n const out = scopedExecutorTableBase(name, columns);\n return out.policy<ExecutorScopePolicyContext>({\n name: executorScopePolicyName,\n onRead: ({ builder, context }) =>\n builder(\"scope_id\", \"in\", executorScopeIds(name, \"read\", context)),\n onCreate: ({ values, context }) =>\n assertExecutorScopeAllowed(name, \"write\", values.scope_id, context),\n onUpdate: ({ builder, set, create, where, context }) => {\n const target = requireExecutorScopeTarget(name, \"write\", where, context);\n if (set.scope_id !== undefined) {\n assertExecutorScopeTargetValue(name, \"write\", set.scope_id, target, context);\n }\n if (create?.scope_id !== undefined) {\n assertExecutorScopeTargetValue(name, \"write\", create.scope_id, target, context);\n }\n return builder(\"scope_id\", \"=\", target.value);\n },\n onDelete: ({ builder, where, context }) => {\n const target = requireExecutorScopeTarget(name, \"delete\", where, context);\n return builder(\"scope_id\", \"=\", target.value);\n },\n });\n};\n\nconst defineTables = <const TTables extends Record<string, AnyTable>>(tables: TTables): TTables =>\n tables;\n\nexport const credentialBindingKinds = [\"text\", \"secret\", \"connection\"] as const;\n\nconst credentialBindingTable = (() => {\n const out = scopedExecutorTableBase(\"credential_binding\", {\n plugin_id: textColumn(\"plugin_id\"),\n source_id: textColumn(\"source_id\"),\n source_scope_id: textColumn(\"source_scope_id\"),\n slot_key: textColumn(\"slot_key\"),\n kind: textColumn(\"kind\"),\n text_value: nullableTextColumn(\"text_value\"),\n secret_id: nullableTextColumn(\"secret_id\"),\n secret_scope_id: nullableTextColumn(\"secret_scope_id\"),\n connection_id: nullableTextColumn(\"connection_id\"),\n created_at: dateColumn(\"created_at\"),\n updated_at: dateColumn(\"updated_at\"),\n });\n\n return out.policy<ExecutorScopePolicyContext>({\n name: executorScopePolicyName,\n onRead: ({ builder, context }) =>\n builder(\"scope_id\", \"in\", executorScopeIds(\"credential_binding\", \"read\", context)),\n onCreate: ({ values, context }) =>\n assertExecutorScopeAllowed(\"credential_binding\", \"write\", values.scope_id, context),\n onUpdate: ({ builder, set, create, where, context }) => {\n const target = requireExecutorScopeTarget(\"credential_binding\", \"write\", where, context);\n if (set.scope_id !== undefined) {\n assertExecutorScopeTargetValue(\n \"credential_binding\",\n \"write\",\n set.scope_id,\n target,\n context,\n );\n }\n if (create?.scope_id !== undefined) {\n assertExecutorScopeTargetValue(\n \"credential_binding\",\n \"write\",\n create.scope_id,\n target,\n context,\n );\n }\n return builder(\"scope_id\", \"=\", target.value);\n },\n onDelete: ({ builder, where, context }) => {\n const target = requireExecutorScopeTarget(\"credential_binding\", \"delete\", where, context, [\n \"scope_id\",\n \"source_scope_id\",\n ]);\n return builder(target.column, \"=\", target.value);\n },\n });\n})();\n\nexport const coreTables = defineTables({\n source: scopedExecutorTable(\"source\", {\n plugin_id: textColumn(\"plugin_id\"),\n kind: textColumn(\"kind\"),\n name: textColumn(\"name\"),\n url: nullableTextColumn(\"url\"),\n can_remove: boolColumn(\"can_remove\", true),\n can_refresh: boolColumn(\"can_refresh\", false),\n can_edit: boolColumn(\"can_edit\", false),\n created_at: dateColumn(\"created_at\"),\n updated_at: dateColumn(\"updated_at\"),\n }),\n tool: scopedExecutorTable(\"tool\", {\n source_id: textColumn(\"source_id\"),\n plugin_id: textColumn(\"plugin_id\"),\n name: textColumn(\"name\"),\n description: textColumn(\"description\"),\n input_schema: nullableJsonColumn(\"input_schema\"),\n output_schema: nullableJsonColumn(\"output_schema\"),\n created_at: dateColumn(\"created_at\"),\n updated_at: dateColumn(\"updated_at\"),\n }),\n definition: scopedExecutorTable(\"definition\", {\n source_id: textColumn(\"source_id\"),\n plugin_id: textColumn(\"plugin_id\"),\n name: textColumn(\"name\"),\n schema: jsonColumn(\"schema\"),\n created_at: dateColumn(\"created_at\"),\n }),\n secret: scopedExecutorTable(\"secret\", {\n name: textColumn(\"name\"),\n provider: textColumn(\"provider\"),\n owned_by_connection_id: nullableTextColumn(\"owned_by_connection_id\"),\n created_at: dateColumn(\"created_at\"),\n }),\n connection: scopedExecutorTable(\"connection\", {\n provider: textColumn(\"provider\"),\n identity_label: nullableTextColumn(\"identity_label\"),\n access_token_secret_id: textColumn(\"access_token_secret_id\"),\n refresh_token_secret_id: nullableTextColumn(\"refresh_token_secret_id\"),\n expires_at: nullableBigintColumn(\"expires_at\"),\n scope: nullableTextColumn(\"scope\"),\n provider_state: nullableJsonColumn(\"provider_state\"),\n created_at: dateColumn(\"created_at\"),\n updated_at: dateColumn(\"updated_at\"),\n }),\n oauth2_session: scopedExecutorTable(\"oauth2_session\", {\n plugin_id: textColumn(\"plugin_id\"),\n strategy: textColumn(\"strategy\"),\n connection_id: textColumn(\"connection_id\"),\n token_scope: textColumn(\"token_scope\"),\n redirect_url: textColumn(\"redirect_url\"),\n payload: jsonColumn(\"payload\"),\n expires_at: bigintColumn(\"expires_at\"),\n created_at: dateColumn(\"created_at\"),\n }),\n credential_binding: credentialBindingTable,\n plugin_storage: scopedExecutorTable(\"plugin_storage\", {\n plugin_id: textColumn(\"plugin_id\"),\n collection: textColumn(\"collection\"),\n key: textColumn(\"key\"),\n data: jsonColumn(\"data\"),\n created_at: dateColumn(\"created_at\"),\n updated_at: dateColumn(\"updated_at\"),\n }),\n tool_policy: scopedExecutorTable(\"tool_policy\", {\n pattern: textColumn(\"pattern\"),\n action: textColumn(\"action\"),\n position: textColumn(\"position\"),\n created_at: dateColumn(\"created_at\"),\n updated_at: dateColumn(\"updated_at\"),\n }),\n blob: unscopedExecutorTable(\"blob\", {\n namespace: textColumn(\"namespace\"),\n key: textColumn(\"key\"),\n value: textColumn(\"value\"),\n }),\n});\n\nexport const coreSchema = coreTables;\nexport type CoreSchema = typeof coreTables;\n\nexport type SourceRow = FumaRow<CoreSchema[\"source\"]>;\nexport type ToolRow = FumaRow<CoreSchema[\"tool\"]>;\nexport type DefinitionRow = FumaRow<CoreSchema[\"definition\"]>;\nexport type SecretRow = FumaRow<CoreSchema[\"secret\"]>;\nexport type ConnectionRow = FumaRow<CoreSchema[\"connection\"]>;\nexport type PluginStorageRow = FumaRow<CoreSchema[\"plugin_storage\"]>;\n\ntype CredentialBindingRowBase = Omit<\n FumaRow<CoreSchema[\"credential_binding\"]>,\n \"kind\" | \"text_value\" | \"secret_id\" | \"secret_scope_id\" | \"connection_id\"\n>;\n\nexport type CredentialBindingRow = CredentialBindingRowBase &\n (\n | {\n kind: \"text\";\n text_value: string;\n }\n | {\n kind: \"secret\";\n secret_id: string;\n secret_scope_id?: string | null;\n }\n | {\n kind: \"connection\";\n connection_id: string;\n }\n ) &\n Record<string, unknown>;\n\nexport type ToolPolicyRow = FumaRow<CoreSchema[\"tool_policy\"]>;\n\nexport type ToolPolicyAction = \"approve\" | \"require_approval\" | \"block\";\n\nexport const TOOL_POLICY_ACTIONS = [\n \"approve\",\n \"require_approval\",\n \"block\",\n] as const satisfies readonly ToolPolicyAction[];\n\nexport const isToolPolicyAction = (value: unknown): value is ToolPolicyAction =>\n typeof value === \"string\" && (TOOL_POLICY_ACTIONS as readonly string[]).includes(value);\n\nexport interface ToolAnnotations {\n readonly requiresApproval?: boolean;\n readonly approvalDescription?: string;\n readonly mayElicit?: boolean;\n}\n\nexport interface SourceInputTool {\n readonly name: string;\n readonly description: string;\n readonly inputSchema?: unknown;\n readonly outputSchema?: unknown;\n}\n\nexport interface SourceInput {\n readonly id: string;\n readonly scope: string;\n readonly kind: string;\n readonly name: string;\n readonly url?: string;\n readonly canRemove?: boolean;\n readonly canRefresh?: boolean;\n readonly canEdit?: boolean;\n readonly tools: readonly SourceInputTool[];\n}\n\nexport interface DefinitionsInput {\n readonly sourceId: string;\n readonly scope: string;\n readonly definitions: Record<string, unknown>;\n}\n","import { ConditionType, type Condition } from \"fumadb/query\";\nimport type { AnyTable } from \"fumadb/schema\";\n\nimport { StorageError } from \"./fuma-runtime\";\n\nexport const executorScopePolicyName = \"executor.scope\";\nexport const executorUnscopedPolicyName = \"executor.unscoped\";\nconst unscopedExecutorTables = new Set([\"blob\"]);\n\nexport interface ExecutorScopePolicyContext {\n readonly allowedScopeIds: ReadonlySet<string>;\n}\n\nexport type ExecutorScopePolicyAccess = \"read\" | \"write\" | \"delete\";\nexport type ExecutorScopeValue = string | null | undefined;\nexport type ExecutorScopeTargetColumn = \"scope_id\" | \"source_scope_id\";\n\nexport interface ExecutorScopeTarget {\n readonly column: ExecutorScopeTargetColumn;\n readonly value: string;\n}\n\nexport const hasExecutorScopePolicy = (table: AnyTable): boolean =>\n table.policies.some((policy) => policy.name === executorScopePolicyName);\n\nconst scopePolicyViolation = (message: string): never => {\n // oxlint-disable-next-line executor/no-try-catch-or-throw -- boundary: FumaDB table policy callbacks are promise callbacks, not Effect effects\n throw new StorageError({ message, cause: undefined });\n};\n\nexport function assertExecutorScopePolicyTable(table: AnyTable, tableKey?: string): void {\n const tableName = table.ormName || tableKey || table.names.sql;\n const scopedPolicy = table.policies.find((policy) => policy.name === executorScopePolicyName);\n if (\n scopedPolicy?.onRead &&\n scopedPolicy.onCreate &&\n scopedPolicy.onUpdate &&\n scopedPolicy.onDelete\n ) {\n return;\n }\n\n const unscopedPolicy = table.policies.find(\n (policy) => policy.name === executorUnscopedPolicyName,\n );\n if (unscopedPolicy && unscopedExecutorTables.has(tableName)) return;\n\n scopePolicyViolation(`Storage table \"${tableName}\" is missing an executor scope policy.`);\n}\n\nconst requireExecutorScopeContext = (\n tableName: string,\n access: ExecutorScopePolicyAccess,\n context: ExecutorScopePolicyContext | undefined,\n): ExecutorScopePolicyContext => {\n if (context) return context;\n return scopePolicyViolation(\n `Storage ${access} on table \"${tableName}\" is missing executor scope context.`,\n );\n};\n\nexport const isExecutorScopeAllowed = (\n tableName: string,\n access: ExecutorScopePolicyAccess,\n value: ExecutorScopeValue,\n context: ExecutorScopePolicyContext | undefined,\n): boolean => {\n const scopeContext = requireExecutorScopeContext(tableName, access, context);\n return typeof value === \"string\" && scopeContext.allowedScopeIds.has(value);\n};\n\nexport const executorScopeIds = (\n tableName: string,\n access: ExecutorScopePolicyAccess,\n context: ExecutorScopePolicyContext | undefined,\n): string[] => [...requireExecutorScopeContext(tableName, access, context).allowedScopeIds];\n\nconst findScopeTarget = (\n condition: Condition | undefined,\n columns: readonly ExecutorScopeTargetColumn[],\n): ExecutorScopeTarget | null => {\n if (!condition) return null;\n if (condition.type === ConditionType.Compare) {\n const column = columns.find((name) => condition.a.ormName === name);\n if (!column || condition.operator !== \"=\" || typeof condition.b !== \"string\") return null;\n return { column, value: condition.b };\n }\n if (condition.type !== ConditionType.And) return null;\n\n for (const item of condition.items) {\n const target = findScopeTarget(item, columns);\n if (target) return target;\n }\n return null;\n};\n\nexport const requireExecutorScopeTarget = (\n tableName: string,\n access: Extract<ExecutorScopePolicyAccess, \"write\" | \"delete\">,\n where: Condition | undefined,\n context: ExecutorScopePolicyContext | undefined,\n columns: readonly ExecutorScopeTargetColumn[] = [\"scope_id\"],\n): ExecutorScopeTarget => {\n const scopeContext = requireExecutorScopeContext(tableName, access, context);\n const target = findScopeTarget(where, columns);\n if (target && scopeContext.allowedScopeIds.has(target.value)) return target;\n\n return scopePolicyViolation(\n `Storage ${access} on table \"${tableName}\" must target an explicit scope in the executor scope stack.`,\n );\n};\n\nexport const assertExecutorScopeAllowed = (\n tableName: string,\n access: ExecutorScopePolicyAccess,\n value: ExecutorScopeValue,\n context: ExecutorScopePolicyContext | undefined,\n): void => {\n if (isExecutorScopeAllowed(tableName, access, value, context)) return;\n scopePolicyViolation(\n `Storage ${access} on table \"${tableName}\" is outside the executor scope stack.`,\n );\n};\n\nexport const assertExecutorScopeTargetValue = (\n tableName: string,\n access: Extract<ExecutorScopePolicyAccess, \"write\" | \"delete\">,\n value: ExecutorScopeValue,\n target: ExecutorScopeTarget,\n context: ExecutorScopePolicyContext | undefined,\n): void => {\n assertExecutorScopeAllowed(tableName, access, value, context);\n if (value === target.value) return;\n\n scopePolicyViolation(\n `Storage ${access} on table \"${tableName}\" must write the same scope it explicitly targets.`,\n );\n};\n\nexport const assertAnyExecutorScopeAllowed = (\n tableName: string,\n access: ExecutorScopePolicyAccess,\n values: readonly ExecutorScopeValue[],\n context: ExecutorScopePolicyContext | undefined,\n): void => {\n if (values.some((value) => isExecutorScopeAllowed(tableName, access, value, context))) return;\n scopePolicyViolation(\n `Storage ${access} on table \"${tableName}\" is outside the executor scope stack.`,\n );\n};\n","import { Effect, Match, Schema } from \"effect\";\n\nimport type { StorageFailure } from \"./fuma-runtime\";\n\nimport { credentialBindingKinds, type CredentialBindingRow } from \"./core-schema\";\nimport { ConnectionId, CredentialBindingId, ScopeId, SecretId } from \"./ids\";\nimport type { Usage } from \"./usages\";\n\nexport const CredentialBindingKind = Schema.Literals(credentialBindingKinds);\nexport type CredentialBindingKind = typeof CredentialBindingKind.Type;\n\nexport const CredentialBindingValue = Schema.Union([\n Schema.Struct({\n kind: Schema.Literal(\"text\"),\n text: Schema.String,\n }),\n Schema.Struct({\n kind: Schema.Literal(\"secret\"),\n secretId: SecretId,\n secretScopeId: Schema.optional(ScopeId),\n }),\n Schema.Struct({\n kind: Schema.Literal(\"connection\"),\n connectionId: ConnectionId,\n }),\n]);\nexport type CredentialBindingValue = typeof CredentialBindingValue.Type;\n\nexport const ConfiguredCredentialBinding = Schema.Struct({\n kind: Schema.Literal(\"binding\"),\n slot: Schema.String,\n prefix: Schema.optional(Schema.String),\n});\nexport type ConfiguredCredentialBinding = typeof ConfiguredCredentialBinding.Type;\n\nexport const ConfiguredCredentialValue = Schema.Union([Schema.String, ConfiguredCredentialBinding]);\nexport type ConfiguredCredentialValue = typeof ConfiguredCredentialValue.Type;\n\nexport const ScopedSecretCredentialInput = Schema.Struct({\n secretId: Schema.String,\n prefix: Schema.optional(Schema.String),\n targetScope: ScopeId,\n secretScopeId: Schema.optional(ScopeId),\n});\nexport type ScopedSecretCredentialInput = typeof ScopedSecretCredentialInput.Type;\n\nexport const CredentialBindingRef = Schema.Struct({\n id: CredentialBindingId,\n scopeId: ScopeId,\n pluginId: Schema.String,\n sourceId: Schema.String,\n sourceScopeId: ScopeId,\n slotKey: Schema.String,\n value: CredentialBindingValue,\n createdAt: Schema.Date,\n updatedAt: Schema.Date,\n});\nexport type CredentialBindingRef = typeof CredentialBindingRef.Type;\n\nexport type SetPluginCredentialBindingInput = {\n readonly targetScope: ScopeId;\n readonly pluginId: string;\n readonly sourceId: string;\n readonly sourceScope: ScopeId;\n readonly slotKey: string;\n readonly value: CredentialBindingValue;\n};\n\nexport const CredentialBindingSourceInput = Schema.Struct({\n pluginId: Schema.String,\n sourceId: Schema.String,\n sourceScope: ScopeId,\n});\nexport type CredentialBindingSourceInput = typeof CredentialBindingSourceInput.Type;\n\nexport const CredentialBindingSlotInput = Schema.Struct({\n pluginId: Schema.String,\n sourceId: Schema.String,\n sourceScope: ScopeId,\n slotKey: Schema.String,\n});\nexport type CredentialBindingSlotInput = typeof CredentialBindingSlotInput.Type;\n\nexport const RemoveCredentialBindingInput = Schema.Struct({\n targetScope: ScopeId,\n pluginId: Schema.String,\n sourceId: Schema.String,\n sourceScope: ScopeId,\n slotKey: Schema.String,\n});\nexport type RemoveCredentialBindingInput = typeof RemoveCredentialBindingInput.Type;\n\nexport const ReplaceCredentialBindingValue = Schema.Struct({\n slotKey: Schema.String,\n value: CredentialBindingValue,\n});\nexport type ReplaceCredentialBindingValue = typeof ReplaceCredentialBindingValue.Type;\n\nexport const ReplaceCredentialBindingsInput = Schema.Struct({\n targetScope: ScopeId,\n pluginId: Schema.String,\n sourceId: Schema.String,\n sourceScope: ScopeId,\n slotPrefixes: Schema.Array(Schema.String),\n bindings: Schema.Array(ReplaceCredentialBindingValue),\n});\nexport type ReplaceCredentialBindingsInput = typeof ReplaceCredentialBindingsInput.Type;\n\nexport const SourceCredentialBindingSource = Schema.Struct({\n id: Schema.String,\n scope: ScopeId,\n});\nexport type SourceCredentialBindingSource = typeof SourceCredentialBindingSource.Type;\n\nexport const SourceCredentialBindingSourceInput = Schema.Struct({\n source: SourceCredentialBindingSource,\n});\nexport type SourceCredentialBindingSourceInput = typeof SourceCredentialBindingSourceInput.Type;\n\nexport const SourceCredentialBindingSlotInput = Schema.Struct({\n source: SourceCredentialBindingSource,\n slotKey: Schema.String,\n});\nexport type SourceCredentialBindingSlotInput = typeof SourceCredentialBindingSlotInput.Type;\n\nexport const SetSourceCredentialBindingInput = Schema.Struct({\n scope: ScopeId,\n source: SourceCredentialBindingSource,\n slotKey: Schema.String,\n value: CredentialBindingValue,\n});\nexport type SetSourceCredentialBindingInput = typeof SetSourceCredentialBindingInput.Type;\n\nexport const RemoveSourceCredentialBindingInput = Schema.Struct({\n scope: ScopeId,\n source: SourceCredentialBindingSource,\n slotKey: Schema.String,\n});\nexport type RemoveSourceCredentialBindingInput = typeof RemoveSourceCredentialBindingInput.Type;\n\nexport const ReplaceSourceCredentialBindingsInput = Schema.Struct({\n scope: ScopeId,\n source: SourceCredentialBindingSource,\n slotPrefixes: Schema.Array(Schema.String),\n bindings: Schema.Array(ReplaceCredentialBindingValue),\n});\nexport type ReplaceSourceCredentialBindingsInput = typeof ReplaceSourceCredentialBindingsInput.Type;\n\nexport const CredentialBindingResolutionStatus = Schema.Literals([\n \"resolved\",\n \"missing\",\n \"blocked\",\n]);\nexport type CredentialBindingResolutionStatus = typeof CredentialBindingResolutionStatus.Type;\n\nexport const ResolvedCredentialSlot = Schema.Struct({\n pluginId: Schema.String,\n sourceId: Schema.String,\n sourceScopeId: ScopeId,\n slotKey: Schema.String,\n bindingScopeId: Schema.NullOr(ScopeId),\n kind: Schema.NullOr(CredentialBindingKind),\n status: CredentialBindingResolutionStatus,\n});\nexport type ResolvedCredentialSlot = typeof ResolvedCredentialSlot.Type;\n\nexport interface CredentialBindingsFacade {\n readonly listForSource: (\n input: CredentialBindingSourceInput,\n ) => Effect.Effect<readonly CredentialBindingRef[], StorageFailure>;\n readonly resolveBinding: (\n input: CredentialBindingSlotInput,\n ) => Effect.Effect<CredentialBindingRef | null, StorageFailure>;\n readonly resolve: (\n input: CredentialBindingSlotInput,\n ) => Effect.Effect<ResolvedCredentialSlot, StorageFailure>;\n readonly set: (\n input: SetPluginCredentialBindingInput,\n ) => Effect.Effect<CredentialBindingRef, StorageFailure>;\n readonly remove: (input: RemoveCredentialBindingInput) => Effect.Effect<void, StorageFailure>;\n readonly replaceForSource: (\n input: ReplaceCredentialBindingsInput,\n ) => Effect.Effect<readonly CredentialBindingRef[], StorageFailure>;\n readonly removeForSource: (\n input: CredentialBindingSourceInput,\n ) => Effect.Effect<void, StorageFailure>;\n readonly usagesForSecret: (id: string) => Effect.Effect<readonly Usage[], StorageFailure>;\n readonly usagesForConnection: (id: string) => Effect.Effect<readonly Usage[], StorageFailure>;\n}\n\nexport const credentialBindingId = (input: {\n readonly pluginId: string;\n readonly sourceId: string;\n readonly sourceScope: string;\n readonly slotKey: string;\n}): CredentialBindingId =>\n CredentialBindingId.make(\n JSON.stringify([input.pluginId, input.sourceScope, input.sourceId, input.slotKey]),\n );\n\nexport const credentialSlotPart = (value: string): string =>\n value\n .trim()\n .toLowerCase()\n .replace(/[^a-z0-9]+/g, \"-\")\n .replace(/^-+|-+$/g, \"\") || \"default\";\n\nexport const credentialSlotKey = (prefix: string, name: string): string =>\n `${prefix}:${credentialSlotPart(name)}`;\n\nexport const credentialBindingValueFromRow = (row: CredentialBindingRow): CredentialBindingValue =>\n Match.value(row).pipe(\n Match.when({ kind: \"text\" }, ({ text_value }) => ({\n kind: \"text\" as const,\n text: text_value,\n })),\n Match.when({ kind: \"secret\" }, ({ scope_id, secret_id, secret_scope_id }) => ({\n kind: \"secret\" as const,\n secretId: SecretId.make(secret_id),\n secretScopeId: ScopeId.make(secret_scope_id ?? scope_id),\n })),\n Match.when({ kind: \"connection\" }, ({ connection_id }) => ({\n kind: \"connection\" as const,\n connectionId: ConnectionId.make(connection_id),\n })),\n Match.exhaustive,\n );\n\nexport const credentialBindingRowToRef = (row: CredentialBindingRow): CredentialBindingRef => {\n const value = credentialBindingValueFromRow(row);\n return CredentialBindingRef.make({\n id: CredentialBindingId.make(row.id),\n scopeId: ScopeId.make(row.scope_id),\n pluginId: row.plugin_id,\n sourceId: row.source_id,\n sourceScopeId: ScopeId.make(row.source_scope_id),\n slotKey: row.slot_key,\n value,\n createdAt: row.created_at instanceof Date ? row.created_at : new Date(row.created_at),\n updatedAt: row.updated_at instanceof Date ? row.updated_at : new Date(row.updated_at),\n });\n};\n","// ---------------------------------------------------------------------------\n// OAuth — core-level authorization service contract.\n//\n// `ctx.oauth` is the single entry point every plugin uses to mint an\n// OAuth-backed `Connection`. It owns the `oauth2_session` table (pending\n// authorizations), runs the strategy-specific code exchange at\n// completion, and writes the resulting Connection via `ctx.connections`.\n//\n// Plugins supply: the resource URL they want a token for, a\n// pre-decided `connectionId`, and a strategy descriptor. They get back\n// an authorization URL for the user's browser; the callback reaches\n// `ctx.oauth.complete`, and at invoke time the plugin calls\n// `ctx.connections.accessToken(connectionId)` for a fresh Bearer.\n//\n// This replaces four per-plugin state machines (one each in mcp,\n// openapi, google-discovery, graphql) that were all shading the same\n// lifecycle.\n// ---------------------------------------------------------------------------\n\nimport { Effect, Schema } from \"effect\";\n\nimport type { StorageFailure } from \"./fuma-runtime\";\n\nimport { ConnectionId } from \"./ids\";\n\n// ---------------------------------------------------------------------------\n// Strategy descriptors\n//\n// The strategy answers \"how do we turn a resource URL + optional\n// pre-configured credentials into an access token?\" — separate from\n// \"which plugin asked?\" The session row carries the strategy kind so\n// completion / refresh can route without a plugin callback.\n// ---------------------------------------------------------------------------\n\n/** RFC 9728 + RFC 8414 + RFC 7591 + PKCE: discover protected-resource\n * metadata, discover the authorization server, dynamically register a\n * client, then PKCE-encode the authorization URL. Zero pre-configured\n * credentials — the user just pastes a resource URL. */\nexport const OAuthDynamicDcrStrategy = Schema.Struct({\n kind: Schema.Literal(\"dynamic-dcr\"),\n /** Scopes to request. Defaults to whatever `scopes_supported`\n * advertises; caller can narrow or extend. */\n scopes: Schema.optional(Schema.Array(Schema.String)),\n});\nexport type OAuthDynamicDcrStrategy = typeof OAuthDynamicDcrStrategy.Type;\n\n/** RFC 6749 authorization code + PKCE with pre-configured endpoints +\n * client_id. Used when the caller has out-of-band-registered an OAuth\n * app (Google via Cloud Console, GitHub via developer portal, etc.) or\n * when the auth-server URL is declared in an OpenAPI `securityScheme`. */\nexport const OAuthAuthorizationCodeStrategy = Schema.Struct({\n kind: Schema.Literal(\"authorization-code\"),\n authorizationEndpoint: Schema.String,\n tokenEndpoint: Schema.String,\n /** Expected authorization-server issuer for ID token validation. Some\n * providers use a token endpoint host that differs from issuer, or a\n * path-scoped issuer such as Okta custom authorization servers. */\n issuerUrl: Schema.optional(Schema.NullOr(Schema.String)),\n /** Secret id holding the `client_id`. Using a secret row rather than\n * an inline string so the value lives at the scope where the caller\n * configured it and shadowing behaves consistently. */\n clientIdSecretId: Schema.String,\n clientIdSecretScopeId: Schema.optional(Schema.NullOr(Schema.String)),\n /** Secret id for `client_secret`. Null for public clients using\n * PKCE without a confidential secret. */\n clientSecretSecretId: Schema.NullOr(Schema.String),\n clientSecretSecretScopeId: Schema.optional(Schema.NullOr(Schema.String)),\n scopes: Schema.Array(Schema.String),\n /** Separator between scopes. RFC 6749 says space; some providers\n * (GitHub classic) use comma. */\n scopeSeparator: Schema.optional(Schema.String),\n /** Provider-specific params injected at authorization URL build time\n * (Google's `access_type=offline`, `prompt=consent`, ...). */\n extraAuthorizationParams: Schema.optional(Schema.Record(Schema.String, Schema.String)),\n /** `\"body\"` (default) sends client creds in the form body; `\"basic\"`\n * uses HTTP Basic auth. Stripe-style servers require basic. */\n clientAuth: Schema.optional(Schema.Literals([\"body\", \"basic\"])),\n});\nexport type OAuthAuthorizationCodeStrategy = typeof OAuthAuthorizationCodeStrategy.Type;\n\n/** RFC 6749 §4.4 client credentials — no user redirect, no PKCE. Used\n * for server-to-server integrations where the plugin has both\n * `client_id` and `client_secret` and the server will mint tokens\n * directly on the token endpoint. */\nexport const OAuthClientCredentialsStrategy = Schema.Struct({\n kind: Schema.Literal(\"client-credentials\"),\n tokenEndpoint: Schema.String,\n clientIdSecretId: Schema.String,\n clientIdSecretScopeId: Schema.optional(Schema.NullOr(Schema.String)),\n clientSecretSecretId: Schema.String,\n clientSecretSecretScopeId: Schema.optional(Schema.NullOr(Schema.String)),\n scopes: Schema.optional(Schema.Array(Schema.String)),\n scopeSeparator: Schema.optional(Schema.String),\n clientAuth: Schema.optional(Schema.Literals([\"body\", \"basic\"])),\n});\nexport type OAuthClientCredentialsStrategy = typeof OAuthClientCredentialsStrategy.Type;\n\n/** Tagged union of every start-time strategy shape. A new strategy (e.g.\n * device-code) is added here; the service's start/complete routes on\n * `kind`. */\nexport const OAuthStrategy = Schema.Union([\n OAuthDynamicDcrStrategy,\n OAuthAuthorizationCodeStrategy,\n OAuthClientCredentialsStrategy,\n]);\nexport type OAuthStrategy = typeof OAuthStrategy.Type;\n\n// ---------------------------------------------------------------------------\n// Provider state — what the canonical `\"oauth2\"` refresh handler reads\n// off the Connection row. One shape regardless of originating strategy;\n// only the fields needed for refresh are persisted.\n// ---------------------------------------------------------------------------\n\n/** Discriminator mirrors `OAuthStrategy[\"kind\"]`. Refresh reads\n * `tokenEndpoint` + `clientAuth` + client id/secret refs directly and\n * never re-runs discovery. */\nexport const OAuthProviderState = Schema.Union([\n Schema.Struct({\n kind: Schema.Literal(\"dynamic-dcr\"),\n tokenEndpoint: Schema.String,\n issuerUrl: Schema.optional(Schema.NullOr(Schema.String)),\n authorizationServerUrl: Schema.optional(Schema.NullOr(Schema.String)),\n authorizationServerMetadataUrl: Schema.NullOr(Schema.String),\n idTokenSigningAlgValuesSupported: Schema.optional(Schema.Array(Schema.String)),\n /** DCR-minted client_id. Embedded inline (not a secret) — DCR\n * clients are public-ish by design; the secret part (if the AS\n * issued one) is a separate secret row. */\n clientId: Schema.String,\n clientSecretSecretId: Schema.NullOr(Schema.String),\n clientSecretSecretScopeId: Schema.optional(Schema.NullOr(Schema.String)),\n clientAuth: Schema.Literals([\"body\", \"basic\"]),\n scopes: Schema.Array(Schema.String).pipe(Schema.withDecodingDefaultType(Effect.succeed([]))),\n scopeSeparator: Schema.optional(Schema.String),\n scope: Schema.NullOr(Schema.String),\n /** RFC 8707 canonical resource URL. Replayed on refresh so the new\n * access token's audience stays bound to the same resource. */\n resource: Schema.optional(Schema.NullOr(Schema.String)),\n }),\n Schema.Struct({\n kind: Schema.Literal(\"authorization-code\"),\n tokenEndpoint: Schema.String,\n issuerUrl: Schema.optional(Schema.NullOr(Schema.String)),\n clientIdSecretId: Schema.String,\n clientIdSecretScopeId: Schema.optional(Schema.NullOr(Schema.String)),\n clientSecretSecretId: Schema.NullOr(Schema.String),\n clientSecretSecretScopeId: Schema.optional(Schema.NullOr(Schema.String)),\n clientAuth: Schema.Literals([\"body\", \"basic\"]),\n scopes: Schema.Array(Schema.String).pipe(Schema.withDecodingDefaultType(Effect.succeed([]))),\n scopeSeparator: Schema.optional(Schema.String),\n scope: Schema.NullOr(Schema.String),\n resource: Schema.optional(Schema.NullOr(Schema.String)),\n }),\n Schema.Struct({\n kind: Schema.Literal(\"client-credentials\"),\n tokenEndpoint: Schema.String,\n clientIdSecretId: Schema.String,\n clientIdSecretScopeId: Schema.optional(Schema.NullOr(Schema.String)),\n clientSecretSecretId: Schema.String,\n clientSecretSecretScopeId: Schema.optional(Schema.NullOr(Schema.String)),\n scopes: Schema.Array(Schema.String),\n scopeSeparator: Schema.optional(Schema.String),\n clientAuth: Schema.Literals([\"body\", \"basic\"]),\n scope: Schema.NullOr(Schema.String),\n }),\n]);\nexport type OAuthProviderState = typeof OAuthProviderState.Type;\n\n/** The canonical refresh handler key. Every OAuth2-minted connection\n * registers under this single value; the handler switches on\n * `providerState.kind`. */\nexport const OAUTH2_PROVIDER_KEY = \"oauth2\" as const;\n\n// ---------------------------------------------------------------------------\n// Probe — \"does this URL use OAuth, and if so how?\"\n// ---------------------------------------------------------------------------\n\nexport interface OAuthProbeInput {\n readonly endpoint: string;\n readonly headers?: Record<string, string>;\n readonly queryParams?: Record<string, string>;\n}\n\nexport interface OAuthProbeResult {\n /** RFC 9728 resource metadata the server advertises, if any. */\n readonly resourceMetadata: Record<string, unknown> | null;\n readonly resourceMetadataUrl: string | null;\n /** RFC 8414 / OIDC metadata for the authorization server tied to the\n * resource, if the server advertised one and we could fetch it. */\n readonly authorizationServerMetadata: Record<string, unknown> | null;\n readonly authorizationServerMetadataUrl: string | null;\n readonly authorizationServerUrl: string | null;\n /** True iff the AS advertises `registration_endpoint` and\n * `token_endpoint_auth_methods_supported` includes `\"none\"` (public\n * client + PKCE). A `false` value here doesn't mean OAuth is\n * unavailable — just that the dynamic-DCR strategy can't run and the\n * caller must fall back to `authorization-code` with user-supplied\n * client credentials. */\n readonly supportsDynamicRegistration: boolean;\n /** True iff an unauth POST to the endpoint responded with `401` and\n * an MCP-shaped `WWW-Authenticate: Bearer` challenge (RFC 6750).\n * MCP-only signal; non-MCP OAuth-protected APIs usually encode auth\n * failures inside their own protocol envelope and never surface\n * this flag. */\n readonly isBearerChallengeEndpoint: boolean;\n}\n\n// ---------------------------------------------------------------------------\n// Start / complete\n// ---------------------------------------------------------------------------\n\nexport interface OAuthStartInput {\n /** Resource URL the caller wants a token for. For `dynamic-dcr` this\n * is the probe target; for `authorization-code` it's stored only so\n * the UI can display \"signed in to X.\" */\n readonly endpoint: string;\n readonly headers?: Record<string, string>;\n readonly queryParams?: Record<string, string>;\n /** Pre-decided `Connection.id`. Writing it before the flow starts\n * lets callers stamp `{kind:\"oauth2\", connectionId}` onto a source\n * row atomically with the start call. Convention:\n * `${pluginId}-oauth2-${namespace}`. */\n readonly connectionId: string;\n /** Scope where the resulting `Connection` + its backing secrets\n * land. Innermost scope for per-user sign-ins. */\n readonly tokenScope: string;\n /** Redirect URL the authorization server will bounce back to. For\n * strategies that don't redirect (`client-credentials`) pass a\n * placeholder; it's persisted but unused. */\n readonly redirectUrl: string;\n readonly strategy: OAuthStrategy;\n /** Which plugin is initiating the flow. Persisted on the session +\n * stamped on the minted Connection's identity label for UI. */\n readonly pluginId: string;\n /** Optional human label for the minted Connection, e.g. \"Spotify OAuth\". */\n readonly identityLabel?: string;\n}\n\nexport interface OAuthStartResult {\n readonly sessionId: string;\n /** Present for user-interactive strategies. `null` for\n * `client-credentials`, which skips straight to a Connection write\n * inside `start`. */\n readonly authorizationUrl: string | null;\n /** For strategies that don't redirect, the Connection has already\n * been minted. Surfaced so callers can stamp the source row\n * immediately without waiting on a completion callback. */\n readonly completedConnection: { readonly connectionId: string } | null;\n}\n\nexport interface OAuthCompleteInput {\n /** RFC 6749 `state` parameter — maps to a session row id. */\n readonly state: string;\n /** Optional scope check for route-scoped completions. Browser callback\n * completions omit this because the callback URL has no scope path. */\n readonly tokenScope?: string;\n readonly code?: string;\n /** RFC 6749 `error` parameter — set when the AS redirected back with\n * a failure. The service surfaces this as a tagged error. */\n readonly error?: string;\n}\n\nexport interface OAuthCompleteResult {\n readonly connectionId: string;\n readonly expiresAt: number | null;\n readonly scope: string | null;\n}\n\n// ---------------------------------------------------------------------------\n// Errors\n// ---------------------------------------------------------------------------\n\n// Errors use `Schema.TaggedError` (rather than `Data.TaggedError`) so\n// they can be encoded as HTTP 4xx payloads directly — every OAuth-\n// capable plugin group `.addError(OAuthStartError)` etc. and the HTTP\n// edge renders them with the annotated status.\n\nexport class OAuthProbeError extends Schema.TaggedErrorClass<OAuthProbeError>()(\n \"OAuthProbeError\",\n {\n message: Schema.String,\n },\n { httpApiStatus: 400 },\n) {}\n\nexport class OAuthStartError extends Schema.TaggedErrorClass<OAuthStartError>()(\n \"OAuthStartError\",\n {\n message: Schema.String,\n /** RFC 6749 §5.2 / RFC 7591 §3.2.2 error code propagated up from the\n * authorization server (e.g. `invalid_client_metadata`). UI surfaces\n * it as the structured \"AS rejected the registration\" reason. */\n error: Schema.optional(Schema.String),\n errorDescription: Schema.optional(Schema.String),\n },\n { httpApiStatus: 400 },\n) {}\n\nexport class OAuthCompleteError extends Schema.TaggedErrorClass<OAuthCompleteError>()(\n \"OAuthCompleteError\",\n {\n message: Schema.String,\n /** RFC 6749 §5.2 error code, when the token endpoint returned one.\n * Callers distinguish terminal failures (`invalid_grant` ⇒\n * re-auth required) from transient ones. */\n code: Schema.optional(Schema.String),\n },\n { httpApiStatus: 400 },\n) {}\n\nexport class OAuthSessionNotFoundError extends Schema.TaggedErrorClass<OAuthSessionNotFoundError>()(\n \"OAuthSessionNotFoundError\",\n {\n sessionId: Schema.String,\n },\n { httpApiStatus: 404 },\n) {}\n\n// ---------------------------------------------------------------------------\n// Contract — what `ctx.oauth` exposes. Implementation lives in\n// `oauth-service.ts`; this file owns the stable public shape.\n// ---------------------------------------------------------------------------\n\nexport interface OAuthService {\n readonly probe: (input: OAuthProbeInput) => Effect.Effect<OAuthProbeResult, OAuthProbeError>;\n readonly start: (\n input: OAuthStartInput,\n ) => Effect.Effect<OAuthStartResult, OAuthStartError | StorageFailure>;\n readonly complete: (\n input: OAuthCompleteInput,\n ) => Effect.Effect<\n OAuthCompleteResult,\n OAuthCompleteError | OAuthSessionNotFoundError | StorageFailure\n >;\n /** Drop an in-flight session without completing — used when the\n * user cancels the popup or the source is deleted mid-onboarding. */\n readonly cancel: (sessionId: string, tokenScope: string) => Effect.Effect<void, StorageFailure>;\n}\n\n// ---------------------------------------------------------------------------\n// Session TTL — how long a pending authorization stays redeemable.\n// 15 minutes matches every existing per-plugin implementation.\n// ---------------------------------------------------------------------------\n\nexport const OAUTH2_SESSION_TTL_MS = 15 * 60 * 1000;\n\n// Re-export ConnectionId for ergonomics — callers constructing start\n// input shouldn't need to import it from two places.\nexport { ConnectionId };\n","// ---------------------------------------------------------------------------\n// Tool policies — pattern matcher + policy resolution. Pure functions; the\n// executor stitches them into `tools.list`, `tools.invoke`, and the public\n// `executor.policies` CRUD surface. Plugins consume the same surface.\n// ---------------------------------------------------------------------------\n\nimport { Match, Schema } from \"effect\";\n\nimport type { ToolPolicyAction, ToolPolicyRow } from \"./core-schema\";\nimport { PolicyId, ScopeId } from \"./ids\";\n\n// ---------------------------------------------------------------------------\n// Public projection — what callers see when they list policies. Strips the\n// raw `scope_id` to a readable `scopeId`, hides `created_at` typing\n// inconsistencies between adapters, and re-tags `id` as a `PolicyId`.\n// ---------------------------------------------------------------------------\n\nexport interface ToolPolicy {\n readonly id: PolicyId;\n readonly scopeId: ScopeId;\n readonly pattern: string;\n readonly action: ToolPolicyAction;\n /** Fractional-indexing key. Lower lex order = higher precedence.\n * Use `generateKeyBetween(a, b)` from the `fractional-indexing`\n * package to produce a key that sits between two existing rows. */\n readonly position: string;\n readonly createdAt: Date;\n readonly updatedAt: Date;\n}\n\nexport interface CreateToolPolicyInput {\n readonly targetScope: string;\n readonly pattern: string;\n readonly action: ToolPolicyAction;\n /** Optional explicit position. Defaults to a key above the current\n * minimum (top of the scope's list; highest precedence). */\n readonly position?: string;\n}\n\nexport interface UpdateToolPolicyInput {\n readonly id: string;\n readonly targetScope: string;\n readonly pattern?: string;\n readonly action?: ToolPolicyAction;\n readonly position?: string;\n}\n\nexport interface RemoveToolPolicyInput {\n readonly id: string;\n readonly targetScope: string;\n}\n\n// ---------------------------------------------------------------------------\n// Match result — what `resolveToolPolicy` returns when a rule fires. Carries\n// the matched pattern so error messages and approval prompts can show the\n// user *which* rule produced the gate (\"matched policy: vercel.dns.*\").\n// ---------------------------------------------------------------------------\n\nexport interface PolicyMatch {\n readonly action: ToolPolicyAction;\n readonly pattern: string;\n readonly policyId: string;\n}\n\n// ---------------------------------------------------------------------------\n// Effective policy — the single answer to \"what happens when this tool is\n// invoked?\". Combines the user policy layer with the plugin's default\n// `requiresApproval` annotation. Callers (UI, agents, telemetry) shouldn't\n// need to know the layering — they ask once and render one thing.\n//\n// `source` distinguishes user-authored rules from plugin-derived defaults\n// purely for display (\"Matched: vercel.*\" vs \"Plugin default\"). The\n// `action` is what actually drives behavior at invoke time.\n// ---------------------------------------------------------------------------\n\nexport type PolicySource = \"user\" | \"plugin-default\";\n\nexport interface EffectivePolicy {\n readonly action: ToolPolicyAction;\n readonly source: PolicySource;\n /** Matched pattern; populated only when `source === \"user\"`. */\n readonly pattern?: string;\n /** Policy row id; populated only when `source === \"user\"`. */\n readonly policyId?: string;\n}\n\n// ---------------------------------------------------------------------------\n// Pattern matching. v1 grammar:\n// - universal: `*` matches every tool id\n// - exact: `vercel.dns.create` matches only that id\n// - subtree: `vercel.dns.*` matches anything starting with `vercel.dns.`\n// - plugin-wide: `vercel.*` matches anything starting with `vercel.`\n// `*` is only meaningful as a complete trailing segment (or as the\n// entire pattern). Patterns without a wildcard are exact-id matches.\n// ---------------------------------------------------------------------------\n\nexport const matchPattern = (pattern: string, toolId: string): boolean => {\n if (pattern === \"*\") return true;\n if (pattern === toolId) return true;\n if (pattern.endsWith(\".*\")) {\n const prefix = pattern.slice(0, -2);\n if (prefix.length === 0) return false;\n return toolId === prefix || toolId.startsWith(`${prefix}.`);\n }\n return false;\n};\n\n// ---------------------------------------------------------------------------\n// Pattern validation — rejects shapes the matcher can't handle. Used by the\n// CRUD path so a malformed rule never lands in the table.\n// ---------------------------------------------------------------------------\n\nexport const isValidPattern = (pattern: string): boolean => {\n if (pattern.length === 0) return false;\n if (pattern === \"*\") return true;\n if (pattern.startsWith(\".\") || pattern.endsWith(\".\")) return false;\n if (pattern.includes(\"..\")) return false;\n if (pattern.startsWith(\"*\")) return false;\n // `*` is only valid as the entire trailing segment.\n const segments = pattern.split(\".\");\n for (let i = 0; i < segments.length; i++) {\n const seg = segments[i]!;\n if (seg.length === 0) return false;\n if (seg.includes(\"*\") && seg !== \"*\") return false;\n if (seg === \"*\" && i !== segments.length - 1) return false;\n }\n return true;\n};\n\n// ---------------------------------------------------------------------------\n// Resolution — each scope contributes its first matching rule by local\n// position. The final answer is the most restrictive matched action across\n// those scopes, so an inner preference cannot weaken an outer guardrail.\n// Caller passes a `scopeRank` function so the resolver doesn't need to know\n// the executor's scope stack shape.\n// ---------------------------------------------------------------------------\n\n// Lex compare on fractional-indexing key, then id as a stable tiebreak.\n// Two rows with identical `position` (racing inserts that picked the same\n// `generateKeyBetween(null, min)` from independent clients) would otherwise\n// flip on every refetch.\nexport const comparePolicyRow = (\n a: Pick<ToolPolicyRow, \"position\" | \"id\">,\n b: Pick<ToolPolicyRow, \"position\" | \"id\">,\n): number => {\n const pa = a.position;\n const pb = b.position;\n if (pa < pb) return -1;\n if (pa > pb) return 1;\n const ia = a.id;\n const ib = b.id;\n return ia < ib ? -1 : ia > ib ? 1 : 0;\n};\n\nconst actionRestrictionRank = (action: ToolPolicyAction): number =>\n Match.value(action).pipe(\n Match.when(\"block\", () => 3),\n Match.when(\"require_approval\", () => 2),\n Match.when(\"approve\", () => 1),\n Match.exhaustive,\n );\n\nconst moreRestrictive = <T extends { readonly action: ToolPolicyAction }>(\n current: T | undefined,\n candidate: T,\n): T => {\n if (!current) return candidate;\n const currentRank = actionRestrictionRank(current.action);\n const candidateRank = actionRestrictionRank(candidate.action);\n return candidateRank > currentRank ? candidate : current;\n};\n\nexport const resolveToolPolicy = (\n toolId: string,\n policies: readonly ToolPolicyRow[],\n scopeRank: (row: Pick<ToolPolicyRow, \"scope_id\">) => number,\n): PolicyMatch | undefined => {\n if (policies.length === 0) return undefined;\n const sorted = [...policies].sort((a, b) => {\n const sa = scopeRank(a);\n const sb = scopeRank(b);\n if (sa !== sb) return sa - sb;\n return comparePolicyRow(a, b);\n });\n const firstMatchByScope = new Map<string, PolicyMatch>();\n for (const row of sorted) {\n if (firstMatchByScope.has(row.scope_id)) continue;\n if (matchPattern(row.pattern, toolId)) {\n firstMatchByScope.set(row.scope_id, {\n action: row.action as ToolPolicyAction,\n pattern: row.pattern,\n policyId: row.id,\n });\n }\n }\n let selected: PolicyMatch | undefined;\n for (const match of firstMatchByScope.values()) {\n selected = moreRestrictive(selected, match);\n }\n return selected;\n};\n\n// ---------------------------------------------------------------------------\n// Layered resolution — one call returns the effective policy combining\n// user-authored rules and the plugin's default `requiresApproval`\n// annotation. Use this anywhere a UI / agent / log needs the final answer\n// without knowing about the layering.\n//\n// Two flavors:\n// - `resolveEffectivePolicy` takes raw rows + a scopeRank, mirrors\n// `resolveToolPolicy`. Used server-side.\n// - `effectivePolicyFromSorted` takes a pre-sorted list of public\n// `ToolPolicy` projections; for clients that already received\n// policies in evaluation order from the API.\n// ---------------------------------------------------------------------------\n\nconst liftPlugin = (defaultRequiresApproval: boolean | undefined): EffectivePolicy =>\n defaultRequiresApproval\n ? { action: \"require_approval\", source: \"plugin-default\" }\n : { action: \"approve\", source: \"plugin-default\" };\n\nconst liftUser = (match: PolicyMatch): EffectivePolicy => ({\n action: match.action,\n source: \"user\",\n pattern: match.pattern,\n policyId: match.policyId,\n});\n\nexport const resolveEffectivePolicy = (\n toolId: string,\n policies: readonly ToolPolicyRow[],\n scopeRank: (row: Pick<ToolPolicyRow, \"scope_id\">) => number,\n defaultRequiresApproval?: boolean,\n): EffectivePolicy => {\n const match = resolveToolPolicy(toolId, policies, scopeRank);\n return match ? liftUser(match) : liftPlugin(defaultRequiresApproval);\n};\n\nexport const effectivePolicyFromSorted = (\n toolId: string,\n sortedPolicies: readonly (Pick<ToolPolicy, \"pattern\" | \"action\" | \"id\"> &\n Partial<Pick<ToolPolicy, \"scopeId\">>)[],\n defaultRequiresApproval?: boolean,\n): EffectivePolicy => {\n const firstMatchByScope = new Map<string, EffectivePolicy>();\n for (const p of sortedPolicies) {\n const scopeKey = \"scopeId\" in p && p.scopeId ? String(p.scopeId) : \"__flat__\";\n if (firstMatchByScope.has(scopeKey)) continue;\n if (matchPattern(p.pattern, toolId)) {\n firstMatchByScope.set(scopeKey, {\n action: p.action,\n source: \"user\",\n pattern: p.pattern,\n policyId: p.id,\n });\n }\n }\n let selected: EffectivePolicy | undefined;\n for (const match of firstMatchByScope.values()) {\n selected = moreRestrictive(selected, match);\n }\n return selected ?? liftPlugin(defaultRequiresApproval);\n};\n\n// ---------------------------------------------------------------------------\n// Row → public projection.\n// ---------------------------------------------------------------------------\n\nexport const rowToToolPolicy = (row: ToolPolicyRow): ToolPolicy => ({\n id: PolicyId.make(row.id),\n scopeId: ScopeId.make(row.scope_id),\n pattern: row.pattern,\n action: row.action as ToolPolicyAction,\n position: row.position,\n createdAt: row.created_at,\n updatedAt: row.updated_at,\n});\n\n// ---------------------------------------------------------------------------\n// Schema for the action enum — useful for HTTP edges that want to validate\n// inputs with effect/Schema.\n// ---------------------------------------------------------------------------\n\nexport const ToolPolicyActionSchema = Schema.Literals([\"approve\", \"require_approval\", \"block\"]);\n","// ---------------------------------------------------------------------------\n// Public projections — what consumers see when they call\n// `executor.sources.list()` / `executor.tools.list()`. Deliberately leaner\n// than the row shapes in core-schema.ts: no audit columns, no raw JSON.\n// ---------------------------------------------------------------------------\n\nimport { Schema } from \"effect\";\n\nimport type { ToolAnnotations } from \"./core-schema\";\nimport { ToolId } from \"./ids\";\n\nexport interface Source {\n readonly id: string;\n /** Owning scope of the visible source row. Present for dynamic\n * sources; static sources omit it. */\n readonly scopeId?: string;\n readonly kind: string;\n readonly name: string;\n readonly url?: string;\n /** Which plugin owns this source. */\n readonly pluginId: string;\n /** Whether the user can remove this source via\n * `executor.sources.remove({ id, targetScope })`. `false` for\n * static / built-in sources declared by plugins at startup. */\n readonly canRemove: boolean;\n /** Whether the plugin supports `executor.sources.refresh({ id, targetScope })`. */\n readonly canRefresh: boolean;\n /** Whether the source has editable config (headers, base url, etc.).\n * Editing is done via plugin-specific extension methods\n * (`executor.openapi.updateSource(id, patch)` etc.) — this flag is\n * just a UI signal. */\n readonly canEdit: boolean;\n /** True if the source was declared statically by a plugin at startup\n * (in-memory only, no DB row). False if it was added at runtime via\n * `ctx.core.sources.register(...)`. UI differentiates built-in vs\n * user-added with this. */\n readonly runtime: boolean;\n}\n\nexport interface RemoveSourceInput {\n readonly id: string;\n readonly targetScope: string;\n}\n\nexport interface RefreshSourceInput {\n readonly id: string;\n readonly targetScope: string;\n}\n\n// `Tool` is the runtime view used across the SDK (with sourceId/pluginId/\n// annotations); `ToolSchema` below is the separate schema-side view that\n// `executor.tools.schema(toolId)` returns. It can include TypeScript previews.\n// These share a name root but are intentionally distinct shapes.\n// oxlint-disable-next-line executor/prefer-schema-inferred-types\nexport interface Tool {\n readonly id: string;\n readonly sourceId: string;\n /** Which plugin owns this tool. Matches the owning source's `pluginId`. */\n readonly pluginId: string;\n readonly name: string;\n readonly description: string;\n readonly inputSchema?: unknown;\n readonly outputSchema?: unknown;\n readonly annotations?: ToolAnnotations;\n}\n\n// ---------------------------------------------------------------------------\n// ToolSchema — the full schema-side view of a tool, returned by\n// `executor.tools.schema(toolId)`. Includes JSON schema roots plus shared\n// definitions for schema exploration, and optionally TypeScript preview strings\n// rendered from them via `schemaToTypeScriptPreview`.\n// ---------------------------------------------------------------------------\n\nexport const ToolSchema = Schema.Struct({\n id: ToolId,\n name: Schema.optional(Schema.String),\n description: Schema.optional(Schema.String),\n inputSchema: Schema.optional(Schema.Unknown),\n outputSchema: Schema.optional(Schema.Unknown),\n schemaDefinitions: Schema.optional(Schema.Record(Schema.String, Schema.Unknown)),\n inputTypeScript: Schema.optional(Schema.String),\n outputTypeScript: Schema.optional(Schema.String),\n typeScriptDefinitions: Schema.optional(Schema.Record(Schema.String, Schema.String)),\n});\nexport type ToolSchema = typeof ToolSchema.Type;\n\n// ---------------------------------------------------------------------------\n// Source detection — optional capability on `PluginSpec.detect`. When a\n// user pastes a URL in the onboarding UI, `executor.sources.detect(url)`\n// asks every plugin \"is this yours?\" and returns the best-confidence\n// match so the UI can auto-fill the onboarding form for the right\n// plugin.\n// ---------------------------------------------------------------------------\n\nexport const SourceDetectionResult = Schema.Struct({\n /** Plugin id that recognized the URL (e.g. \"openapi\", \"graphql\"). */\n kind: Schema.String,\n /** Confidence tier — UI uses this to pick a winner when multiple\n * plugins claim a URL. */\n confidence: Schema.Literals([\"high\", \"medium\", \"low\"]),\n /** The (possibly normalized) endpoint the plugin will use. */\n endpoint: Schema.String,\n /** Human-readable name suggestion, typically derived from spec title\n * or URL hostname. */\n name: Schema.String,\n /** Namespace suggestion — the plugin's recommendation for the source\n * id. UI may override. */\n namespace: Schema.String,\n});\nexport type SourceDetectionResult = typeof SourceDetectionResult.Type;\n\n// ---------------------------------------------------------------------------\n// Filter passed to `executor.tools.list(...)`. Empty filter = all tools.\n// ---------------------------------------------------------------------------\n\nexport interface ToolListFilter {\n /** Only tools under this source id. */\n readonly sourceId?: string;\n /** Case-insensitive substring match against `name` OR `description`. */\n readonly query?: string;\n /** Resolve plugin-derived annotations. Defaults to true. */\n readonly includeAnnotations?: boolean;\n /** Include tools whose effective `tool_policy` is `block`. Defaults to\n * `false` so the agent-facing surfaces (`searchTools`, sandbox `tools.list`)\n * silently omit blocked tools. The settings UI for managing policies\n * should pass `true` so users can author rules against blocked tools. */\n readonly includeBlocked?: boolean;\n}\n","import { Schema } from \"effect\";\n\nimport { ScopeId, SecretId, ConnectionId } from \"./ids\";\n\n// ---------------------------------------------------------------------------\n// Usage — one row per place a secret or connection is referenced. Each\n// plugin contributes its own usages via `usagesForSecret` /\n// `usagesForConnection`; the executor fans out and concatenates.\n//\n// `pluginId` identifies the plugin that owns the reference. `ownerKind`\n// is plugin-defined (e.g. \"openapi-source-oauth2\", \"mcp-source-auth\",\n// \"graphql-source-header\"); the UI groups by it for a \"used in N\n// sources / M bindings\" summary. `slot` describes which field within\n// the owner holds the ref (\"oauth2.client_secret\", \"header:Authorization\",\n// \"binding:value\") so the user can locate it.\n//\n// `ownerName` is resolved by JOIN at query time from the parent source /\n// binding row. It's nullable because a plugin may have an owner that has\n// no human-readable name (e.g. an unnamed binding row).\n//\n// `scopeId` is the scope the owner row lives in. Plugin stores apply explicit\n// FumaDB scope predicates, so usages from visible outer scopes surface\n// alongside inner ones; the UI uses the scope to render a per-scope label next\n// to each entry.\n// ---------------------------------------------------------------------------\n\nexport const Usage = Schema.Struct({\n pluginId: Schema.String,\n scopeId: ScopeId,\n ownerKind: Schema.String,\n ownerId: Schema.String,\n ownerName: Schema.NullOr(Schema.String),\n slot: Schema.String,\n});\nexport type Usage = typeof Usage.Type;\n\nexport interface UsagesForSecretInput {\n readonly secretId: SecretId;\n}\n\nexport interface UsagesForConnectionInput {\n readonly connectionId: ConnectionId;\n}\n","import { Data, Schema } from \"effect\";\n\nimport { ConnectionId, ToolId, SecretId } from \"./ids\";\n\n// ---------------------------------------------------------------------------\n// Tool lifecycle\n// ---------------------------------------------------------------------------\n\nexport class ToolNotFoundError extends Schema.TaggedErrorClass<ToolNotFoundError>()(\n \"ToolNotFoundError\",\n {\n toolId: ToolId,\n suggestions: Schema.optional(Schema.Array(ToolId)),\n },\n) {}\n\nexport class ToolInvocationError extends Data.TaggedError(\"ToolInvocationError\")<{\n readonly toolId: ToolId;\n readonly message: string;\n readonly cause?: unknown;\n}> {}\n\n/** Tool row exists in the DB but its owning plugin isn't loaded. Means\n * the tool was registered by a plugin that's no longer present in the\n * current executor config — usually a stale row from an older session. */\nexport class PluginNotLoadedError extends Schema.TaggedErrorClass<PluginNotLoadedError>()(\n \"PluginNotLoadedError\",\n {\n pluginId: Schema.String,\n toolId: ToolId,\n },\n) {}\n\n/** Tool was found but its owning plugin has no `invokeTool` handler —\n * the plugin only declares static tools and this one's id matched\n * dynamically somehow. Shouldn't happen in practice; guards against\n * programmer error. */\nexport class NoHandlerError extends Schema.TaggedErrorClass<NoHandlerError>()(\"NoHandlerError\", {\n toolId: ToolId,\n pluginId: Schema.String,\n}) {}\n\n/** Tool invocation was rejected because a workspace `tool_policy` rule\n * with `action: \"block\"` matched. `pattern` is the matched policy\n * pattern so callers / agents can render a useful \"this is blocked\n * by your `vercel.dns.*` rule\" message. */\nexport class ToolBlockedError extends Schema.TaggedErrorClass<ToolBlockedError>()(\n \"ToolBlockedError\",\n {\n toolId: ToolId,\n pattern: Schema.String,\n },\n) {}\n\n// ---------------------------------------------------------------------------\n// Source lifecycle\n// ---------------------------------------------------------------------------\n\nexport class SourceNotFoundError extends Schema.TaggedErrorClass<SourceNotFoundError>()(\n \"SourceNotFoundError\",\n { sourceId: Schema.String },\n) {}\n\n/** `executor.sources.remove({ id, targetScope })` was called on a\n * source with `canRemove: false` — typically a static source declared\n * by a plugin at startup. Removing static sources is a bug in the\n * caller. */\nexport class SourceRemovalNotAllowedError extends Schema.TaggedErrorClass<SourceRemovalNotAllowedError>()(\n \"SourceRemovalNotAllowedError\",\n { sourceId: Schema.String },\n) {}\n\n// ---------------------------------------------------------------------------\n// Secrets\n// ---------------------------------------------------------------------------\n\nexport class SecretNotFoundError extends Schema.TaggedErrorClass<SecretNotFoundError>()(\n \"SecretNotFoundError\",\n { secretId: SecretId },\n) {}\n\nexport class SecretResolutionError extends Schema.TaggedErrorClass<SecretResolutionError>()(\n \"SecretResolutionError\",\n {\n secretId: SecretId,\n message: Schema.String,\n },\n) {}\n\n/** Raised when `secrets.remove({ id, targetScope })` is called on a secret whose row has\n * `owned_by_connection_id` set. The connection owns the lifecycle —\n * callers must go through `connections.remove(connectionId)` to\n * delete it along with its siblings. */\nexport class SecretOwnedByConnectionError extends Schema.TaggedErrorClass<SecretOwnedByConnectionError>()(\n \"SecretOwnedByConnectionError\",\n {\n secretId: SecretId,\n connectionId: ConnectionId,\n },\n) {}\n\n/** Raised when `secrets.remove({ id, targetScope })` is called on a secret that's still\n * referenced by one or more sources / bindings across plugins. The UI's\n * \"Used by\" list tells the user which sources to detach first. App-\n * level RESTRICT — the codebase doesn't enforce DB-level FKs because\n * composite `(scope_id, id)` PKs make single-column references\n * impossible to constrain in sqlite. `usageCount` is a hint for the\n * caller; the full list is queryable via `secrets.usages(id)`. */\nexport class SecretInUseError extends Schema.TaggedErrorClass<SecretInUseError>()(\n \"SecretInUseError\",\n {\n secretId: SecretId,\n usageCount: Schema.Number,\n },\n) {}\n\n// ---------------------------------------------------------------------------\n// Connections\n// ---------------------------------------------------------------------------\n\nexport class ConnectionNotFoundError extends Schema.TaggedErrorClass<ConnectionNotFoundError>()(\n \"ConnectionNotFoundError\",\n { connectionId: ConnectionId },\n) {}\n\nexport class ConnectionProviderNotRegisteredError extends Schema.TaggedErrorClass<ConnectionProviderNotRegisteredError>()(\n \"ConnectionProviderNotRegisteredError\",\n {\n provider: Schema.String,\n connectionId: Schema.optional(ConnectionId),\n },\n) {}\n\nexport class ConnectionRefreshNotSupportedError extends Schema.TaggedErrorClass<ConnectionRefreshNotSupportedError>()(\n \"ConnectionRefreshNotSupportedError\",\n {\n connectionId: ConnectionId,\n provider: Schema.String,\n },\n) {}\n\n/**\n * Raised by `connections.accessToken(id)` when the provider's refresh\n * handler reported that the stored refresh token is permanently\n * invalid (RFC 6749 §5.2 `invalid_grant` and friends). The caller —\n * typically a tool invocation — surfaces this so the UI can prompt the\n * user to sign in again. Distinct from `ConnectionRefreshError` so\n * \"the network flaked, retry later\" and \"the grant is dead, re-auth\"\n * don't collapse into one error tag at the plugin boundary.\n */\nexport class ConnectionReauthRequiredError extends Schema.TaggedErrorClass<ConnectionReauthRequiredError>()(\n \"ConnectionReauthRequiredError\",\n {\n connectionId: ConnectionId,\n provider: Schema.String,\n message: Schema.String,\n },\n) {}\n\n/** Raised when `connections.remove(id)` is called on a connection that's\n * still referenced by sources / bindings. Mirrors `SecretInUseError`. */\nexport class ConnectionInUseError extends Schema.TaggedErrorClass<ConnectionInUseError>()(\n \"ConnectionInUseError\",\n {\n connectionId: ConnectionId,\n usageCount: Schema.Number,\n },\n) {}\n\n// ---------------------------------------------------------------------------\n// Union type for convenience in signatures.\n// ---------------------------------------------------------------------------\n\nexport type ExecutorError =\n | ToolNotFoundError\n | ToolInvocationError\n | PluginNotLoadedError\n | NoHandlerError\n | ToolBlockedError\n | SourceNotFoundError\n | SourceRemovalNotAllowedError\n | SecretNotFoundError\n | SecretResolutionError\n | SecretOwnedByConnectionError\n | SecretInUseError\n | ConnectionNotFoundError\n | ConnectionProviderNotRegisteredError\n | ConnectionRefreshNotSupportedError\n | ConnectionReauthRequiredError\n | ConnectionInUseError;\n","import { Effect } from \"effect\";\n\nimport type { StorageFailure } from \"./fuma-runtime\";\nimport type { ScopeId } from \"./ids\";\n\nexport interface PluginStorageKeyInput {\n readonly collection: string;\n readonly key: string;\n}\n\nexport interface PluginStorageScopedKeyInput extends PluginStorageKeyInput {\n readonly scope: ScopeId | string;\n}\n\nexport interface PluginStorageListInput {\n readonly collection: string;\n readonly keyPrefix?: string;\n}\n\nexport interface PluginStoragePutInput extends PluginStorageScopedKeyInput {\n readonly data: unknown;\n}\n\nexport interface PluginStorageEntry<T = unknown> {\n readonly id: string;\n readonly scopeId: ScopeId | string;\n readonly pluginId: string;\n readonly collection: string;\n readonly key: string;\n readonly data: T;\n readonly createdAt: Date;\n readonly updatedAt: Date;\n}\n\nexport interface PluginStorageFacade {\n readonly get: <T = unknown>(\n input: PluginStorageKeyInput,\n ) => Effect.Effect<PluginStorageEntry<T> | null, StorageFailure>;\n readonly getAtScope: <T = unknown>(\n input: PluginStorageScopedKeyInput,\n ) => Effect.Effect<PluginStorageEntry<T> | null, StorageFailure>;\n readonly list: <T = unknown>(\n input: PluginStorageListInput,\n ) => Effect.Effect<readonly PluginStorageEntry<T>[], StorageFailure>;\n readonly put: <T = unknown>(\n input: PluginStoragePutInput,\n ) => Effect.Effect<PluginStorageEntry<T>, StorageFailure>;\n readonly remove: (input: PluginStorageScopedKeyInput) => Effect.Effect<void, StorageFailure>;\n}\n\nexport const pluginStorageId = (input: {\n readonly pluginId: string;\n readonly collection: string;\n readonly key: string;\n}): string => JSON.stringify([input.pluginId, input.collection, input.key]);\n"],"mappings":"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","names":["table","table","column","Schema","Schema","Effect","Schema","Schema","Effect","Match","Schema","Match","Schema","Schema","Schema","Schema","Schema","Data","Schema","Schema","Data"]}
|
package/dist/client.d.ts
CHANGED
|
@@ -41,6 +41,9 @@ export interface SourcePreset {
|
|
|
41
41
|
/** URL passed as `initialUrl` to the add form. Omit for presets that
|
|
42
42
|
* don't use a URL (e.g. stdio MCP presets). */
|
|
43
43
|
readonly url?: string;
|
|
44
|
+
/** Endpoint passed to agent-facing probe/add tools when their schema
|
|
45
|
+
* uses `endpoint` instead of `url`. */
|
|
46
|
+
readonly endpoint?: string;
|
|
44
47
|
/** Optional icon URL (favicon, logo). */
|
|
45
48
|
readonly icon?: string;
|
|
46
49
|
/** Shown in the top-level grid on the sources page when true. */
|
package/dist/client.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"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"}
|
package/dist/client.js
CHANGED
package/dist/client.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/client.ts"],"sourcesContent":["// ---------------------------------------------------------------------------\n// @executor-js/sdk/client — frontend half of the plugin SDK.\n//\n// Plugins import from this entry to register pages/widgets and consume\n// their own typed reactive client. Server bundles must NOT import this\n// module — it pulls in React + @effect/atom-react. Plugin packages should\n// keep React/atom imports inside `./client.tsx` and Effect/Node imports\n// inside `./server.ts`; shared schema definitions go in `./shared.ts` and\n// can be imported from both halves.\n// ---------------------------------------------------------------------------\n\nimport {\n createContext,\n createElement,\n useContext,\n useEffect,\n useMemo,\n type ComponentType,\n type ReactNode,\n} from \"react\";\nimport { HttpApi } from \"effect/unstable/httpapi\";\nimport type { HttpApiEndpoint, HttpApiGroup } from \"effect/unstable/httpapi\";\nimport { FetchHttpClient, HttpClient, HttpClientRequest } from \"effect/unstable/http\";\nimport * as AtomHttpApi from \"effect/unstable/reactivity/AtomHttpApi\";\n\n// ---------------------------------------------------------------------------\n// Re-exports — the curated set of primitives a plugin author needs to\n// build a typed reactive UI without reaching into `effect/*` directly.\n// ---------------------------------------------------------------------------\n\nexport { Schema } from \"effect\";\nexport { HttpApi, HttpApiEndpoint, HttpApiGroup } from \"effect/unstable/httpapi\";\n\nexport * as AsyncResult from \"effect/unstable/reactivity/AsyncResult\";\nexport * as Atom from \"effect/unstable/reactivity/Atom\";\nexport * as AtomHttpApi from \"effect/unstable/reactivity/AtomHttpApi\";\n\nexport { useAtomValue, useAtomSet, useAtomMount, useAtomRefresh } from \"@effect/atom-react\";\n\n// ---------------------------------------------------------------------------\n// defineClientPlugin — declarative spec for the frontend half of a plugin.\n//\n// Mirror of `definePlugin` on the server, but everything here is React /\n// browser-only. The host treats the value as data: collects routes,\n// widgets, and slot components from every loaded plugin and mounts them\n// alongside the host's own UI.\n// ---------------------------------------------------------------------------\n\nexport interface PageDecl {\n /** Path relative to the plugin's mount point, e.g. `/`, `/edit/$id`. */\n readonly path: string;\n readonly component: ComponentType;\n /** Optional sidebar nav metadata — the host renders these alongside its\n * own nav links. Omit to register a page without a nav entry. */\n readonly nav?: {\n readonly label: string;\n readonly section?: string;\n };\n}\n\nexport interface WidgetProps {\n readonly scopeId?: string;\n}\n\nexport interface WidgetDecl {\n readonly id: string;\n readonly component: ComponentType<WidgetProps>;\n readonly size?: \"half\" | \"full\";\n}\n\n/**\n * Open record of host-defined slot components a plugin can fill. Slot\n * names are part of the host UI contract — plugins opt in by registering\n * a component for the slot they care about. Adding a slot is a host-side\n * change; plugin authors don't define new slots.\n */\nexport type SlotComponent = ComponentType<Record<string, unknown>>;\n\n// ---------------------------------------------------------------------------\n// SourcePlugin / SourcePreset — UI contract for plugins that expose\n// \"sources\" (OpenAPI specs, MCP servers, GraphQL endpoints, etc.). The\n// host owns the source list / detail chrome; the plugin owns the\n// add-flow, edit form, and (optional) summary + sign-in buttons.\n//\n// Lives here, not in `@executor-js/react`, so it's part of the plugin\n// contract: a plugin's `./client` entry assembles its `sourcePlugin`\n// alongside `pages`/`widgets`, and the host derives the union list\n// from `virtual:executor/plugins-client`.\n// ---------------------------------------------------------------------------\n\nexport interface SourcePreset {\n /** Unique id (e.g. \"stripe\", \"github-graphql\"). */\n readonly id: string;\n readonly name: string;\n readonly summary: string;\n /** URL passed as `initialUrl` to the add form. Omit for presets that\n * don't use a URL (e.g. stdio MCP presets). */\n readonly url?: string;\n /** Optional icon URL (favicon, logo). */\n readonly icon?: string;\n /** Shown in the top-level grid on the sources page when true. */\n readonly featured?: boolean;\n}\n\nexport interface SourcePlugin {\n /** Unique key matching the SDK plugin id (e.g. \"openapi\"). */\n readonly key: string;\n readonly label: string;\n readonly add: ComponentType<{\n readonly onComplete: () => void;\n readonly onCancel: () => void;\n readonly initialUrl?: string;\n readonly initialPreset?: string;\n readonly initialNamespace?: string;\n }>;\n readonly edit: ComponentType<{\n readonly sourceId: string;\n readonly onSave: () => void;\n }>;\n readonly summary?: ComponentType<{\n readonly sourceId: string;\n readonly variant?: \"badge\" | \"panel\";\n readonly onAction?: () => void;\n }>;\n readonly presets?: readonly SourcePreset[];\n /** Trigger early download of the plugin's lazy component chunks (add/edit/etc.).\n * Call from the host on intent (hover/focus) so the chunks land before the\n * user navigates into the add page. Idempotent. */\n readonly preload?: () => void;\n}\n\n// ---------------------------------------------------------------------------\n// SecretProviderPlugin — UI contract for plugins that contribute secret\n// providers (1Password, WorkOS Vault, etc.). The host owns the secrets\n// page chrome; the plugin owns the settings card rendered inside.\n// ---------------------------------------------------------------------------\n\nexport interface SecretProviderPlugin {\n /** Unique key matching the SDK plugin id (e.g. \"onepassword\"). */\n readonly key: string;\n readonly label: string;\n readonly settings: ComponentType<Record<string, never>>;\n}\n\nexport interface ClientPluginSpec<TId extends string = string> {\n readonly id: TId;\n readonly pages?: readonly PageDecl[];\n readonly widgets?: readonly WidgetDecl[];\n readonly slots?: Record<string, SlotComponent>;\n /** Source plugin contribution — populated by plugins that expose\n * `kind` rows in the core `source` table (openapi, mcp, graphql,\n * google-discovery). The host's sources page derives its provider\n * list from the union of every loaded plugin's `sourcePlugin`. */\n readonly sourcePlugin?: SourcePlugin;\n /** Secret provider plugin contribution — populated by plugins that\n * also ship a `secretProviders` (or related) server-side capability\n * AND want to expose a settings card on the host's secrets page. */\n readonly secretProviderPlugin?: SecretProviderPlugin;\n}\n\n/**\n * Identity factory — returns the spec unchanged but pins the inferred\n * literal type of `id` so the host can index plugin records by id with\n * full autocomplete. Plugins export this as their package's default\n * (or named) export from `./client`.\n */\nexport const defineClientPlugin = <const TId extends string>(\n spec: ClientPluginSpec<TId>,\n): ClientPluginSpec<TId> => spec;\n\n// ---------------------------------------------------------------------------\n// createPluginAtomClient — typed reactive HTTP client for one plugin.\n//\n// Wraps the plugin's `HttpApiGroup` in a per-plugin `HttpApi`, then\n// hands back an `AtomHttpApi.Service` keyed to that bundle. The\n// resulting service exposes `.query(\"group\", \"endpoint\", opts)` and\n// `.mutation(\"group\", \"endpoint\")` factories — same shape as the host's\n// existing `ExecutorApiClient` (see packages/react/src/api/client.tsx).\n// Per-endpoint payload/response/error types flow through from the\n// imported group, so plugin client code typechecks without codegen.\n//\n// The plugin id (used for the Service Tag and the synthetic API id) is\n// read from `group.identifier` — the same string the plugin passed to\n// `HttpApiGroup.make(\"foo\")`. No second-source duplication.\n// ---------------------------------------------------------------------------\n\nexport interface CreatePluginAtomClientOptions {\n /** Override the base URL. Defaults to `/api` (host strips this prefix\n * when forwarding to the Effect handler) — same convention as the\n * core `ExecutorApiClient`. */\n readonly baseUrl?: string | (() => string);\n}\n\n/**\n * Build a typed reactive client for a plugin's HttpApiGroup.\n *\n * const FooClient = createPluginAtomClient(FooApi)\n * export const fooThings = FooClient.query(\"foo\", \"listThings\", { ... })\n * export const fooSync = FooClient.mutation(\"foo\", \"syncThing\")\n *\n * Each plugin gets a private service Tag (`Plugin_<id>Client`) keyed by\n * the group's `identifier`, so multiple plugins coexist in the same\n * React tree without colliding.\n */\nexport const createPluginAtomClient = <\n G extends HttpApiGroup.HttpApiGroup<string, HttpApiEndpoint.Any, boolean>,\n>(\n group: G,\n options: CreatePluginAtomClientOptions = {},\n) => {\n const { baseUrl = \"/api\" } = options;\n const pluginId = group.identifier;\n const bundle = HttpApi.make(`plugin-${pluginId}`).add(group);\n return AtomHttpApi.Service<`Plugin_${G[\"identifier\"]}Client`>()(`Plugin_${pluginId}Client`, {\n api: bundle,\n httpClient: FetchHttpClient.layer,\n ...(typeof baseUrl === \"function\"\n ? {\n transformClient: HttpClient.mapRequest((request) =>\n HttpClientRequest.prependUrl(request, baseUrl()),\n ),\n }\n : { baseUrl }),\n });\n};\n\n// ---------------------------------------------------------------------------\n// ExecutorPluginsProvider + hooks — host-level distribution of the loaded\n// `ClientPluginSpec[]` via React context.\n//\n// The host wraps once at the root of its tree (typically reading from\n// `virtual:executor/plugins-client`); pages and shared components consume\n// via the focused hooks (`useSourcePlugins` etc.) so they don't import\n// from any host-app aggregator file. Pages stay portable across hosts —\n// the same component renders against whatever plugin set the surrounding\n// `<ExecutorPluginsProvider>` provides.\n//\n// Hooks throw if no provider is in scope so missing setup fails loudly;\n// matches the pattern of `useScope` / `useAuth` already in the codebase.\n// ---------------------------------------------------------------------------\n\ninterface ExecutorPluginsContextValue {\n readonly plugins: readonly ClientPluginSpec[];\n readonly sourcePlugins: readonly SourcePlugin[];\n readonly secretProviderPlugins: readonly SecretProviderPlugin[];\n}\n\nconst ExecutorPluginsContext = createContext<ExecutorPluginsContextValue | null>(null);\nExecutorPluginsContext.displayName = \"ExecutorPluginsContext\";\n\nexport interface ExecutorPluginsProviderProps {\n readonly plugins: readonly ClientPluginSpec[];\n readonly children: ReactNode;\n}\n\nexport function ExecutorPluginsProvider(\n props: ExecutorPluginsProviderProps,\n): ReturnType<typeof createElement> {\n const { plugins, children } = props;\n const value = useMemo<ExecutorPluginsContextValue>(\n () => ({\n plugins,\n sourcePlugins: plugins.flatMap((p) => (p.sourcePlugin ? [p.sourcePlugin] : [])),\n secretProviderPlugins: plugins.flatMap((p) =>\n p.secretProviderPlugin ? [p.secretProviderPlugin] : [],\n ),\n }),\n [plugins],\n );\n // Kick off lazy chunk downloads for every source plugin once the host\n // mounts, so navigating into an add/edit page doesn't suspend.\n useEffect(() => {\n for (const sp of value.sourcePlugins) sp.preload?.();\n }, [value.sourcePlugins]);\n return createElement(ExecutorPluginsContext.Provider, { value }, children);\n}\n\nconst usePluginsCtx = (hookName: string): ExecutorPluginsContextValue => {\n const ctx = useContext(ExecutorPluginsContext);\n if (!ctx) {\n // oxlint-disable-next-line executor/no-try-catch-or-throw, executor/no-error-constructor -- boundary: React hook invariant\n throw new Error(`${hookName} must be called inside an <ExecutorPluginsProvider>.`);\n }\n return ctx;\n};\n\n/** Full list of loaded `ClientPluginSpec` values. */\nexport const useClientPlugins = (): readonly ClientPluginSpec[] =>\n usePluginsCtx(\"useClientPlugins\").plugins;\n\n/** Source plugins extracted from `clientPlugins[].sourcePlugin`. */\nexport const useSourcePlugins = (): readonly SourcePlugin[] =>\n usePluginsCtx(\"useSourcePlugins\").sourcePlugins;\n\n/** Secret-provider plugins extracted from `clientPlugins[].secretProviderPlugin`. */\nexport const useSecretProviderPlugins = (): readonly SecretProviderPlugin[] =>\n usePluginsCtx(\"useSecretProviderPlugins\").secretProviderPlugins;\n"],"mappings":";AAWA;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OAGK;AACP,SAAS,eAAe;AAExB,SAAS,iBAAiB,YAAY,yBAAyB;AAC/D,YAAY,iBAAiB;AAO7B,SAAS,cAAc;AACvB,SAAS,WAAAA,UAAS,iBAAiB,oBAAoB;AAEvD,YAAY,iBAAiB;AAC7B,YAAY,UAAU;AACtB,YAAYC,kBAAiB;AAE7B,SAAS,cAAc,YAAY,cAAc,sBAAsB;AAiIhE,IAAM,qBAAqB,CAChC,SAC0B;AAoCrB,IAAM,yBAAyB,CAGpC,OACA,UAAyC,CAAC,MACvC;AACH,QAAM,EAAE,UAAU,OAAO,IAAI;AAC7B,QAAM,WAAW,MAAM;AACvB,QAAM,SAAS,QAAQ,KAAK,UAAU,QAAQ,EAAE,EAAE,IAAI,KAAK;AAC3D,SAAmB,oBAA2C,EAAE,UAAU,QAAQ,UAAU;AAAA,IAC1F,KAAK;AAAA,IACL,YAAY,gBAAgB;AAAA,IAC5B,GAAI,OAAO,YAAY,aACnB;AAAA,MACE,iBAAiB,WAAW;AAAA,QAAW,CAAC,YACtC,kBAAkB,WAAW,SAAS,QAAQ,CAAC;AAAA,MACjD;AAAA,IACF,IACA,EAAE,QAAQ;AAAA,EAChB,CAAC;AACH;AAuBA,IAAM,yBAAyB,cAAkD,IAAI;AACrF,uBAAuB,cAAc;AAO9B,SAAS,wBACd,OACkC;AAClC,QAAM,EAAE,SAAS,SAAS,IAAI;AAC9B,QAAM,QAAQ;AAAA,IACZ,OAAO;AAAA,MACL;AAAA,MACA,eAAe,QAAQ,QAAQ,CAAC,MAAO,EAAE,eAAe,CAAC,EAAE,YAAY,IAAI,CAAC,CAAE;AAAA,MAC9E,uBAAuB,QAAQ;AAAA,QAAQ,CAAC,MACtC,EAAE,uBAAuB,CAAC,EAAE,oBAAoB,IAAI,CAAC;AAAA,MACvD;AAAA,IACF;AAAA,IACA,CAAC,OAAO;AAAA,EACV;AAGA,YAAU,MAAM;AACd,eAAW,MAAM,MAAM,cAAe,IAAG,UAAU;AAAA,EACrD,GAAG,CAAC,MAAM,aAAa,CAAC;AACxB,SAAO,cAAc,uBAAuB,UAAU,EAAE,MAAM,GAAG,QAAQ;AAC3E;AAEA,IAAM,gBAAgB,CAAC,aAAkD;AACvE,QAAM,MAAM,WAAW,sBAAsB;AAC7C,MAAI,CAAC,KAAK;AAER,UAAM,IAAI,MAAM,GAAG,QAAQ,sDAAsD;AAAA,EACnF;AACA,SAAO;AACT;AAGO,IAAM,mBAAmB,MAC9B,cAAc,kBAAkB,EAAE;AAG7B,IAAM,mBAAmB,MAC9B,cAAc,kBAAkB,EAAE;AAG7B,IAAM,2BAA2B,MACtC,cAAc,0BAA0B,EAAE;","names":["HttpApi","AtomHttpApi"]}
|
|
1
|
+
{"version":3,"sources":["../src/client.ts"],"sourcesContent":["// ---------------------------------------------------------------------------\n// @executor-js/sdk/client — frontend half of the plugin SDK.\n//\n// Plugins import from this entry to register pages/widgets and consume\n// their own typed reactive client. Server bundles must NOT import this\n// module — it pulls in React + @effect/atom-react. Plugin packages should\n// keep React/atom imports inside `./client.tsx` and Effect/Node imports\n// inside `./server.ts`; shared schema definitions go in `./shared.ts` and\n// can be imported from both halves.\n// ---------------------------------------------------------------------------\n\nimport {\n createContext,\n createElement,\n useContext,\n useEffect,\n useMemo,\n type ComponentType,\n type ReactNode,\n} from \"react\";\nimport { HttpApi } from \"effect/unstable/httpapi\";\nimport type { HttpApiEndpoint, HttpApiGroup } from \"effect/unstable/httpapi\";\nimport { FetchHttpClient, HttpClient, HttpClientRequest } from \"effect/unstable/http\";\nimport * as AtomHttpApi from \"effect/unstable/reactivity/AtomHttpApi\";\n\n// ---------------------------------------------------------------------------\n// Re-exports — the curated set of primitives a plugin author needs to\n// build a typed reactive UI without reaching into `effect/*` directly.\n// ---------------------------------------------------------------------------\n\nexport { Schema } from \"effect\";\nexport { HttpApi, HttpApiEndpoint, HttpApiGroup } from \"effect/unstable/httpapi\";\n\nexport * as AsyncResult from \"effect/unstable/reactivity/AsyncResult\";\nexport * as Atom from \"effect/unstable/reactivity/Atom\";\nexport * as AtomHttpApi from \"effect/unstable/reactivity/AtomHttpApi\";\n\nexport { useAtomValue, useAtomSet, useAtomMount, useAtomRefresh } from \"@effect/atom-react\";\n\n// ---------------------------------------------------------------------------\n// defineClientPlugin — declarative spec for the frontend half of a plugin.\n//\n// Mirror of `definePlugin` on the server, but everything here is React /\n// browser-only. The host treats the value as data: collects routes,\n// widgets, and slot components from every loaded plugin and mounts them\n// alongside the host's own UI.\n// ---------------------------------------------------------------------------\n\nexport interface PageDecl {\n /** Path relative to the plugin's mount point, e.g. `/`, `/edit/$id`. */\n readonly path: string;\n readonly component: ComponentType;\n /** Optional sidebar nav metadata — the host renders these alongside its\n * own nav links. Omit to register a page without a nav entry. */\n readonly nav?: {\n readonly label: string;\n readonly section?: string;\n };\n}\n\nexport interface WidgetProps {\n readonly scopeId?: string;\n}\n\nexport interface WidgetDecl {\n readonly id: string;\n readonly component: ComponentType<WidgetProps>;\n readonly size?: \"half\" | \"full\";\n}\n\n/**\n * Open record of host-defined slot components a plugin can fill. Slot\n * names are part of the host UI contract — plugins opt in by registering\n * a component for the slot they care about. Adding a slot is a host-side\n * change; plugin authors don't define new slots.\n */\nexport type SlotComponent = ComponentType<Record<string, unknown>>;\n\n// ---------------------------------------------------------------------------\n// SourcePlugin / SourcePreset — UI contract for plugins that expose\n// \"sources\" (OpenAPI specs, MCP servers, GraphQL endpoints, etc.). The\n// host owns the source list / detail chrome; the plugin owns the\n// add-flow, edit form, and (optional) summary + sign-in buttons.\n//\n// Lives here, not in `@executor-js/react`, so it's part of the plugin\n// contract: a plugin's `./client` entry assembles its `sourcePlugin`\n// alongside `pages`/`widgets`, and the host derives the union list\n// from `virtual:executor/plugins-client`.\n// ---------------------------------------------------------------------------\n\nexport interface SourcePreset {\n /** Unique id (e.g. \"stripe\", \"github-graphql\"). */\n readonly id: string;\n readonly name: string;\n readonly summary: string;\n /** URL passed as `initialUrl` to the add form. Omit for presets that\n * don't use a URL (e.g. stdio MCP presets). */\n readonly url?: string;\n /** Endpoint passed to agent-facing probe/add tools when their schema\n * uses `endpoint` instead of `url`. */\n readonly endpoint?: string;\n /** Optional icon URL (favicon, logo). */\n readonly icon?: string;\n /** Shown in the top-level grid on the sources page when true. */\n readonly featured?: boolean;\n}\n\nexport interface SourcePlugin {\n /** Unique key matching the SDK plugin id (e.g. \"openapi\"). */\n readonly key: string;\n readonly label: string;\n readonly add: ComponentType<{\n readonly onComplete: () => void;\n readonly onCancel: () => void;\n readonly initialUrl?: string;\n readonly initialPreset?: string;\n readonly initialNamespace?: string;\n }>;\n readonly edit: ComponentType<{\n readonly sourceId: string;\n readonly onSave: () => void;\n }>;\n readonly summary?: ComponentType<{\n readonly sourceId: string;\n readonly variant?: \"badge\" | \"panel\";\n readonly onAction?: () => void;\n }>;\n readonly presets?: readonly SourcePreset[];\n /** Trigger early download of the plugin's lazy component chunks (add/edit/etc.).\n * Call from the host on intent (hover/focus) so the chunks land before the\n * user navigates into the add page. Idempotent. */\n readonly preload?: () => void;\n}\n\n// ---------------------------------------------------------------------------\n// SecretProviderPlugin — UI contract for plugins that contribute secret\n// providers (1Password, WorkOS Vault, etc.). The host owns the secrets\n// page chrome; the plugin owns the settings card rendered inside.\n// ---------------------------------------------------------------------------\n\nexport interface SecretProviderPlugin {\n /** Unique key matching the SDK plugin id (e.g. \"onepassword\"). */\n readonly key: string;\n readonly label: string;\n readonly settings: ComponentType<Record<string, never>>;\n}\n\nexport interface ClientPluginSpec<TId extends string = string> {\n readonly id: TId;\n readonly pages?: readonly PageDecl[];\n readonly widgets?: readonly WidgetDecl[];\n readonly slots?: Record<string, SlotComponent>;\n /** Source plugin contribution — populated by plugins that expose\n * `kind` rows in the core `source` table (openapi, mcp, graphql,\n * google-discovery). The host's sources page derives its provider\n * list from the union of every loaded plugin's `sourcePlugin`. */\n readonly sourcePlugin?: SourcePlugin;\n /** Secret provider plugin contribution — populated by plugins that\n * also ship a `secretProviders` (or related) server-side capability\n * AND want to expose a settings card on the host's secrets page. */\n readonly secretProviderPlugin?: SecretProviderPlugin;\n}\n\n/**\n * Identity factory — returns the spec unchanged but pins the inferred\n * literal type of `id` so the host can index plugin records by id with\n * full autocomplete. Plugins export this as their package's default\n * (or named) export from `./client`.\n */\nexport const defineClientPlugin = <const TId extends string>(\n spec: ClientPluginSpec<TId>,\n): ClientPluginSpec<TId> => spec;\n\n// ---------------------------------------------------------------------------\n// createPluginAtomClient — typed reactive HTTP client for one plugin.\n//\n// Wraps the plugin's `HttpApiGroup` in a per-plugin `HttpApi`, then\n// hands back an `AtomHttpApi.Service` keyed to that bundle. The\n// resulting service exposes `.query(\"group\", \"endpoint\", opts)` and\n// `.mutation(\"group\", \"endpoint\")` factories — same shape as the host's\n// existing `ExecutorApiClient` (see packages/react/src/api/client.tsx).\n// Per-endpoint payload/response/error types flow through from the\n// imported group, so plugin client code typechecks without codegen.\n//\n// The plugin id (used for the Service Tag and the synthetic API id) is\n// read from `group.identifier` — the same string the plugin passed to\n// `HttpApiGroup.make(\"foo\")`. No second-source duplication.\n// ---------------------------------------------------------------------------\n\nexport interface CreatePluginAtomClientOptions {\n /** Override the base URL. Defaults to `/api` (host strips this prefix\n * when forwarding to the Effect handler) — same convention as the\n * core `ExecutorApiClient`. */\n readonly baseUrl?: string | (() => string);\n}\n\n/**\n * Build a typed reactive client for a plugin's HttpApiGroup.\n *\n * const FooClient = createPluginAtomClient(FooApi)\n * export const fooThings = FooClient.query(\"foo\", \"listThings\", { ... })\n * export const fooSync = FooClient.mutation(\"foo\", \"syncThing\")\n *\n * Each plugin gets a private service Tag (`Plugin_<id>Client`) keyed by\n * the group's `identifier`, so multiple plugins coexist in the same\n * React tree without colliding.\n */\nexport const createPluginAtomClient = <\n G extends HttpApiGroup.HttpApiGroup<string, HttpApiEndpoint.Any, boolean>,\n>(\n group: G,\n options: CreatePluginAtomClientOptions = {},\n) => {\n const { baseUrl = \"/api\" } = options;\n const pluginId = group.identifier;\n const bundle = HttpApi.make(`plugin-${pluginId}`).add(group);\n return AtomHttpApi.Service<`Plugin_${G[\"identifier\"]}Client`>()(`Plugin_${pluginId}Client`, {\n api: bundle,\n httpClient: FetchHttpClient.layer,\n ...(typeof baseUrl === \"function\"\n ? {\n transformClient: HttpClient.mapRequest((request) =>\n HttpClientRequest.prependUrl(request, baseUrl()),\n ),\n }\n : { baseUrl }),\n });\n};\n\n// ---------------------------------------------------------------------------\n// ExecutorPluginsProvider + hooks — host-level distribution of the loaded\n// `ClientPluginSpec[]` via React context.\n//\n// The host wraps once at the root of its tree (typically reading from\n// `virtual:executor/plugins-client`); pages and shared components consume\n// via the focused hooks (`useSourcePlugins` etc.) so they don't import\n// from any host-app aggregator file. Pages stay portable across hosts —\n// the same component renders against whatever plugin set the surrounding\n// `<ExecutorPluginsProvider>` provides.\n//\n// Hooks throw if no provider is in scope so missing setup fails loudly;\n// matches the pattern of `useScope` / `useAuth` already in the codebase.\n// ---------------------------------------------------------------------------\n\ninterface ExecutorPluginsContextValue {\n readonly plugins: readonly ClientPluginSpec[];\n readonly sourcePlugins: readonly SourcePlugin[];\n readonly secretProviderPlugins: readonly SecretProviderPlugin[];\n}\n\nconst ExecutorPluginsContext = createContext<ExecutorPluginsContextValue | null>(null);\nExecutorPluginsContext.displayName = \"ExecutorPluginsContext\";\n\nexport interface ExecutorPluginsProviderProps {\n readonly plugins: readonly ClientPluginSpec[];\n readonly children: ReactNode;\n}\n\nexport function ExecutorPluginsProvider(\n props: ExecutorPluginsProviderProps,\n): ReturnType<typeof createElement> {\n const { plugins, children } = props;\n const value = useMemo<ExecutorPluginsContextValue>(\n () => ({\n plugins,\n sourcePlugins: plugins.flatMap((p) => (p.sourcePlugin ? [p.sourcePlugin] : [])),\n secretProviderPlugins: plugins.flatMap((p) =>\n p.secretProviderPlugin ? [p.secretProviderPlugin] : [],\n ),\n }),\n [plugins],\n );\n // Kick off lazy chunk downloads for every source plugin once the host\n // mounts, so navigating into an add/edit page doesn't suspend.\n useEffect(() => {\n for (const sp of value.sourcePlugins) sp.preload?.();\n }, [value.sourcePlugins]);\n return createElement(ExecutorPluginsContext.Provider, { value }, children);\n}\n\nconst usePluginsCtx = (hookName: string): ExecutorPluginsContextValue => {\n const ctx = useContext(ExecutorPluginsContext);\n if (!ctx) {\n // oxlint-disable-next-line executor/no-try-catch-or-throw, executor/no-error-constructor -- boundary: React hook invariant\n throw new Error(`${hookName} must be called inside an <ExecutorPluginsProvider>.`);\n }\n return ctx;\n};\n\n/** Full list of loaded `ClientPluginSpec` values. */\nexport const useClientPlugins = (): readonly ClientPluginSpec[] =>\n usePluginsCtx(\"useClientPlugins\").plugins;\n\n/** Source plugins extracted from `clientPlugins[].sourcePlugin`. */\nexport const useSourcePlugins = (): readonly SourcePlugin[] =>\n usePluginsCtx(\"useSourcePlugins\").sourcePlugins;\n\n/** Secret-provider plugins extracted from `clientPlugins[].secretProviderPlugin`. */\nexport const useSecretProviderPlugins = (): readonly SecretProviderPlugin[] =>\n usePluginsCtx(\"useSecretProviderPlugins\").secretProviderPlugins;\n"],"mappings":";;;AAWA;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OAGK;AACP,SAAS,eAAe;AAExB,SAAS,iBAAiB,YAAY,yBAAyB;AAC/D,YAAY,iBAAiB;AAO7B,SAAS,cAAc;AACvB,SAAS,WAAAA,UAAS,iBAAiB,oBAAoB;AAEvD,YAAY,iBAAiB;AAC7B,YAAY,UAAU;AACtB,YAAYC,kBAAiB;AAE7B,SAAS,cAAc,YAAY,cAAc,sBAAsB;AAoIhE,IAAM,qBAAqB,CAChC,SAC0B;AAoCrB,IAAM,yBAAyB,CAGpC,OACA,UAAyC,CAAC,MACvC;AACH,QAAM,EAAE,UAAU,OAAO,IAAI;AAC7B,QAAM,WAAW,MAAM;AACvB,QAAM,SAAS,QAAQ,KAAK,UAAU,QAAQ,EAAE,EAAE,IAAI,KAAK;AAC3D,SAAmB,oBAA2C,EAAE,UAAU,QAAQ,UAAU;AAAA,IAC1F,KAAK;AAAA,IACL,YAAY,gBAAgB;AAAA,IAC5B,GAAI,OAAO,YAAY,aACnB;AAAA,MACE,iBAAiB,WAAW;AAAA,QAAW,CAAC,YACtC,kBAAkB,WAAW,SAAS,QAAQ,CAAC;AAAA,MACjD;AAAA,IACF,IACA,EAAE,QAAQ;AAAA,EAChB,CAAC;AACH;AAuBA,IAAM,yBAAyB,cAAkD,IAAI;AACrF,uBAAuB,cAAc;AAO9B,SAAS,wBACd,OACkC;AAClC,QAAM,EAAE,SAAS,SAAS,IAAI;AAC9B,QAAM,QAAQ;AAAA,IACZ,OAAO;AAAA,MACL;AAAA,MACA,eAAe,QAAQ,QAAQ,CAAC,MAAO,EAAE,eAAe,CAAC,EAAE,YAAY,IAAI,CAAC,CAAE;AAAA,MAC9E,uBAAuB,QAAQ;AAAA,QAAQ,CAAC,MACtC,EAAE,uBAAuB,CAAC,EAAE,oBAAoB,IAAI,CAAC;AAAA,MACvD;AAAA,IACF;AAAA,IACA,CAAC,OAAO;AAAA,EACV;AAGA,YAAU,MAAM;AACd,eAAW,MAAM,MAAM,cAAe,IAAG,UAAU;AAAA,EACrD,GAAG,CAAC,MAAM,aAAa,CAAC;AACxB,SAAO,cAAc,uBAAuB,UAAU,EAAE,MAAM,GAAG,QAAQ;AAC3E;AAEA,IAAM,gBAAgB,CAAC,aAAkD;AACvE,QAAM,MAAM,WAAW,sBAAsB;AAC7C,MAAI,CAAC,KAAK;AAER,UAAM,IAAI,MAAM,GAAG,QAAQ,sDAAsD;AAAA,EACnF;AACA,SAAO;AACT;AAGO,IAAM,mBAAmB,MAC9B,cAAc,kBAAkB,EAAE;AAG7B,IAAM,mBAAmB,MAC9B,cAAc,kBAAkB,EAAE;AAG7B,IAAM,2BAA2B,MACtC,cAAc,0BAA0B,EAAE;","names":["HttpApi","AtomHttpApi"]}
|
package/dist/config.d.ts
CHANGED
|
@@ -1,16 +1,12 @@
|
|
|
1
1
|
import type { AnyPlugin } from "./plugin";
|
|
2
|
-
export type ExecutorDialect = "pg" | "sqlite" | "mysql";
|
|
3
2
|
export type ExecutorPluginsFactory<TDeps extends object = object, TPlugins extends readonly AnyPlugin[] = readonly AnyPlugin[]> = (deps?: TDeps) => TPlugins;
|
|
4
3
|
export interface ExecutorCliConfig<TDeps extends object = object, TPlugins extends readonly AnyPlugin[] = readonly AnyPlugin[]> {
|
|
5
|
-
readonly dialect: ExecutorDialect;
|
|
6
4
|
readonly plugins: ExecutorPluginsFactory<TDeps, TPlugins>;
|
|
7
5
|
}
|
|
8
6
|
/**
|
|
9
|
-
* Declare an executor config.
|
|
10
|
-
*
|
|
11
|
-
* runtime
|
|
12
|
-
* credentials passed to the factory may be stubs from the CLI — only
|
|
13
|
-
* `plugin.schema` is read there.
|
|
7
|
+
* Declare an executor config. Host runtimes import this file to instantiate
|
|
8
|
+
* plugins, and static tooling can read the same plugin metadata without
|
|
9
|
+
* constructing runtime credentials.
|
|
14
10
|
*
|
|
15
11
|
* The `const TPlugins` modifier preserves the tuple-literal inference
|
|
16
12
|
* from the factory's return so per-plugin extension typing flows through
|
package/dist/config.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAmBA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,UAAU,CAAC;AAE1C,MAAM,MAAM,
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAmBA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,UAAU,CAAC;AAE1C,MAAM,MAAM,sBAAsB,CAChC,KAAK,SAAS,MAAM,GAAG,MAAM,EAC7B,QAAQ,SAAS,SAAS,SAAS,EAAE,GAAG,SAAS,SAAS,EAAE,IAC1D,CAAC,IAAI,CAAC,EAAE,KAAK,KAAK,QAAQ,CAAC;AAE/B,MAAM,WAAW,iBAAiB,CAChC,KAAK,SAAS,MAAM,GAAG,MAAM,EAC7B,QAAQ,SAAS,SAAS,SAAS,EAAE,GAAG,SAAS,SAAS,EAAE;IAE5D,QAAQ,CAAC,OAAO,EAAE,sBAAsB,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAC;CAC3D;AAED;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,oBAAoB,GAC/B,KAAK,SAAS,MAAM,EACpB,KAAK,CAAC,QAAQ,SAAS,SAAS,SAAS,EAAE,EAE3C,QAAQ,iBAAiB,CAAC,KAAK,EAAE,QAAQ,CAAC,KACzC,iBAAiB,CAAC,KAAK,EAAE,QAAQ,CAAW,CAAC"}
|