@executor-js/cli 0.2.1 → 0.2.2
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/README.md +4 -54
- package/dist/commands/schema.d.ts +2 -0
- package/dist/index.js +43 -1391
- package/dist/index.js.map +1 -1
- package/package.json +5 -4
- package/dist/commands/generate.d.ts +0 -2
- package/dist/generators/drizzle.d.ts +0 -2
- package/dist/generators/index.d.ts +0 -5
- package/dist/generators/types.d.ts +0 -15
- /package/dist/{generators/drizzle.test.d.ts → commands/schema.test.d.ts} +0 -0
package/dist/index.js
CHANGED
|
@@ -3,1066 +3,12 @@
|
|
|
3
3
|
// src/index.ts
|
|
4
4
|
import { Command as Command2 } from "commander";
|
|
5
5
|
|
|
6
|
-
// src/commands/
|
|
7
|
-
import { existsSync as
|
|
6
|
+
// src/commands/schema.ts
|
|
7
|
+
import { existsSync as existsSync2 } from "fs";
|
|
8
8
|
import fs from "fs/promises";
|
|
9
9
|
import path2 from "path";
|
|
10
10
|
import { Command } from "commander";
|
|
11
|
-
|
|
12
|
-
// ../sdk/src/index.ts
|
|
13
|
-
import { Context as Context2, Effect as Effect18, Layer as Layer5, Schema as Schema19, Data as Data6, Option as Option6 } from "effect";
|
|
14
|
-
import {
|
|
15
|
-
HttpApi,
|
|
16
|
-
HttpApiBuilder,
|
|
17
|
-
HttpApiClient,
|
|
18
|
-
HttpApiEndpoint,
|
|
19
|
-
HttpApiGroup,
|
|
20
|
-
HttpApiMiddleware,
|
|
21
|
-
HttpApiSchema
|
|
22
|
-
} from "effect/unstable/httpapi";
|
|
23
|
-
|
|
24
|
-
// ../storage-core/src/factory.ts
|
|
25
|
-
import { Effect, Option, Schema } from "effect";
|
|
26
|
-
|
|
27
|
-
// ../storage-core/src/errors.ts
|
|
28
|
-
import { Data } from "effect";
|
|
29
|
-
var StorageError = class extends Data.TaggedError("StorageError") {
|
|
30
|
-
};
|
|
31
|
-
var UniqueViolationError = class extends Data.TaggedError("UniqueViolationError") {
|
|
32
|
-
};
|
|
33
|
-
|
|
34
|
-
// ../storage-core/src/factory.ts
|
|
35
|
-
var decodeJsonFromString = Schema.decodeUnknownOption(Schema.UnknownFromJsonString);
|
|
36
|
-
|
|
37
|
-
// ../sdk/src/ids.ts
|
|
38
|
-
import { Schema as Schema2 } from "effect";
|
|
39
|
-
var ScopeId = Schema2.String.pipe(Schema2.brand("ScopeId"));
|
|
40
|
-
var ToolId = Schema2.String.pipe(Schema2.brand("ToolId"));
|
|
41
|
-
var SecretId = Schema2.String.pipe(Schema2.brand("SecretId"));
|
|
42
|
-
var PolicyId = Schema2.String.pipe(Schema2.brand("PolicyId"));
|
|
43
|
-
var ConnectionId = Schema2.String.pipe(Schema2.brand("ConnectionId"));
|
|
44
|
-
var CredentialBindingId = Schema2.String.pipe(Schema2.brand("CredentialBindingId"));
|
|
45
|
-
|
|
46
|
-
// ../sdk/src/scope.ts
|
|
47
|
-
import { Schema as Schema3 } from "effect";
|
|
48
|
-
var Scope = class extends Schema3.Class("Scope")({
|
|
49
|
-
id: ScopeId,
|
|
50
|
-
name: Schema3.String,
|
|
51
|
-
createdAt: Schema3.Date
|
|
52
|
-
}) {
|
|
53
|
-
};
|
|
54
|
-
|
|
55
|
-
// ../sdk/src/errors.ts
|
|
56
|
-
import { Data as Data2, Schema as Schema4 } from "effect";
|
|
57
|
-
var ToolNotFoundError = class extends Schema4.TaggedErrorClass()(
|
|
58
|
-
"ToolNotFoundError",
|
|
59
|
-
{ toolId: ToolId }
|
|
60
|
-
) {
|
|
61
|
-
};
|
|
62
|
-
var ToolInvocationError = class extends Data2.TaggedError("ToolInvocationError") {
|
|
63
|
-
};
|
|
64
|
-
var PluginNotLoadedError = class extends Schema4.TaggedErrorClass()(
|
|
65
|
-
"PluginNotLoadedError",
|
|
66
|
-
{
|
|
67
|
-
pluginId: Schema4.String,
|
|
68
|
-
toolId: ToolId
|
|
69
|
-
}
|
|
70
|
-
) {
|
|
71
|
-
};
|
|
72
|
-
var NoHandlerError = class extends Schema4.TaggedErrorClass()("NoHandlerError", {
|
|
73
|
-
toolId: ToolId,
|
|
74
|
-
pluginId: Schema4.String
|
|
75
|
-
}) {
|
|
76
|
-
};
|
|
77
|
-
var ToolBlockedError = class extends Schema4.TaggedErrorClass()(
|
|
78
|
-
"ToolBlockedError",
|
|
79
|
-
{
|
|
80
|
-
toolId: ToolId,
|
|
81
|
-
pattern: Schema4.String
|
|
82
|
-
}
|
|
83
|
-
) {
|
|
84
|
-
};
|
|
85
|
-
var SourceNotFoundError = class extends Schema4.TaggedErrorClass()(
|
|
86
|
-
"SourceNotFoundError",
|
|
87
|
-
{ sourceId: Schema4.String }
|
|
88
|
-
) {
|
|
89
|
-
};
|
|
90
|
-
var SourceRemovalNotAllowedError = class extends Schema4.TaggedErrorClass()(
|
|
91
|
-
"SourceRemovalNotAllowedError",
|
|
92
|
-
{ sourceId: Schema4.String }
|
|
93
|
-
) {
|
|
94
|
-
};
|
|
95
|
-
var SecretNotFoundError = class extends Schema4.TaggedErrorClass()(
|
|
96
|
-
"SecretNotFoundError",
|
|
97
|
-
{ secretId: SecretId }
|
|
98
|
-
) {
|
|
99
|
-
};
|
|
100
|
-
var SecretResolutionError = class extends Schema4.TaggedErrorClass()(
|
|
101
|
-
"SecretResolutionError",
|
|
102
|
-
{
|
|
103
|
-
secretId: SecretId,
|
|
104
|
-
message: Schema4.String
|
|
105
|
-
}
|
|
106
|
-
) {
|
|
107
|
-
};
|
|
108
|
-
var SecretOwnedByConnectionError = class extends Schema4.TaggedErrorClass()(
|
|
109
|
-
"SecretOwnedByConnectionError",
|
|
110
|
-
{
|
|
111
|
-
secretId: SecretId,
|
|
112
|
-
connectionId: ConnectionId
|
|
113
|
-
}
|
|
114
|
-
) {
|
|
115
|
-
};
|
|
116
|
-
var SecretInUseError = class extends Schema4.TaggedErrorClass()(
|
|
117
|
-
"SecretInUseError",
|
|
118
|
-
{
|
|
119
|
-
secretId: SecretId,
|
|
120
|
-
usageCount: Schema4.Number
|
|
121
|
-
}
|
|
122
|
-
) {
|
|
123
|
-
};
|
|
124
|
-
var ConnectionNotFoundError = class extends Schema4.TaggedErrorClass()(
|
|
125
|
-
"ConnectionNotFoundError",
|
|
126
|
-
{ connectionId: ConnectionId }
|
|
127
|
-
) {
|
|
128
|
-
};
|
|
129
|
-
var ConnectionProviderNotRegisteredError = class extends Schema4.TaggedErrorClass()(
|
|
130
|
-
"ConnectionProviderNotRegisteredError",
|
|
131
|
-
{
|
|
132
|
-
provider: Schema4.String,
|
|
133
|
-
connectionId: Schema4.optional(ConnectionId)
|
|
134
|
-
}
|
|
135
|
-
) {
|
|
136
|
-
};
|
|
137
|
-
var ConnectionRefreshNotSupportedError = class extends Schema4.TaggedErrorClass()(
|
|
138
|
-
"ConnectionRefreshNotSupportedError",
|
|
139
|
-
{
|
|
140
|
-
connectionId: ConnectionId,
|
|
141
|
-
provider: Schema4.String
|
|
142
|
-
}
|
|
143
|
-
) {
|
|
144
|
-
};
|
|
145
|
-
var ConnectionReauthRequiredError = class extends Schema4.TaggedErrorClass()(
|
|
146
|
-
"ConnectionReauthRequiredError",
|
|
147
|
-
{
|
|
148
|
-
connectionId: ConnectionId,
|
|
149
|
-
provider: Schema4.String,
|
|
150
|
-
message: Schema4.String
|
|
151
|
-
}
|
|
152
|
-
) {
|
|
153
|
-
};
|
|
154
|
-
var ConnectionInUseError = class extends Schema4.TaggedErrorClass()(
|
|
155
|
-
"ConnectionInUseError",
|
|
156
|
-
{
|
|
157
|
-
connectionId: ConnectionId,
|
|
158
|
-
usageCount: Schema4.Number
|
|
159
|
-
}
|
|
160
|
-
) {
|
|
161
|
-
};
|
|
162
|
-
|
|
163
|
-
// ../sdk/src/types.ts
|
|
164
|
-
import { Schema as Schema5 } from "effect";
|
|
165
|
-
var ToolSchema = class extends Schema5.Class("ToolSchema")({
|
|
166
|
-
id: ToolId,
|
|
167
|
-
name: Schema5.optional(Schema5.String),
|
|
168
|
-
description: Schema5.optional(Schema5.String),
|
|
169
|
-
inputSchema: Schema5.optional(Schema5.Unknown),
|
|
170
|
-
outputSchema: Schema5.optional(Schema5.Unknown),
|
|
171
|
-
inputTypeScript: Schema5.optional(Schema5.String),
|
|
172
|
-
outputTypeScript: Schema5.optional(Schema5.String),
|
|
173
|
-
typeScriptDefinitions: Schema5.optional(Schema5.Record(Schema5.String, Schema5.String))
|
|
174
|
-
}) {
|
|
175
|
-
};
|
|
176
|
-
var SourceDetectionResult = class extends Schema5.Class(
|
|
177
|
-
"SourceDetectionResult"
|
|
178
|
-
)({
|
|
179
|
-
/** Plugin id that recognized the URL (e.g. "openapi", "graphql"). */
|
|
180
|
-
kind: Schema5.String,
|
|
181
|
-
/** Confidence tier — UI uses this to pick a winner when multiple
|
|
182
|
-
* plugins claim a URL. */
|
|
183
|
-
confidence: Schema5.Literals(["high", "medium", "low"]),
|
|
184
|
-
/** The (possibly normalized) endpoint the plugin will use. */
|
|
185
|
-
endpoint: Schema5.String,
|
|
186
|
-
/** Human-readable name suggestion, typically derived from spec title
|
|
187
|
-
* or URL hostname. */
|
|
188
|
-
name: Schema5.String,
|
|
189
|
-
/** Namespace suggestion — the plugin's recommendation for the source
|
|
190
|
-
* id. UI may override. */
|
|
191
|
-
namespace: Schema5.String
|
|
192
|
-
}) {
|
|
193
|
-
};
|
|
194
|
-
|
|
195
|
-
// ../sdk/src/core-schema.ts
|
|
196
|
-
var credentialBindingKinds = ["text", "secret", "connection"];
|
|
197
|
-
var coreSchema = {
|
|
198
|
-
source: {
|
|
199
|
-
fields: {
|
|
200
|
-
id: { type: "string", required: true },
|
|
201
|
-
scope_id: { type: "string", required: true, index: true },
|
|
202
|
-
plugin_id: { type: "string", required: true, index: true },
|
|
203
|
-
kind: { type: "string", required: true },
|
|
204
|
-
name: { type: "string", required: true },
|
|
205
|
-
url: { type: "string", required: false },
|
|
206
|
-
can_remove: {
|
|
207
|
-
type: "boolean",
|
|
208
|
-
required: true,
|
|
209
|
-
defaultValue: true
|
|
210
|
-
},
|
|
211
|
-
can_refresh: {
|
|
212
|
-
type: "boolean",
|
|
213
|
-
required: true,
|
|
214
|
-
defaultValue: false
|
|
215
|
-
},
|
|
216
|
-
can_edit: {
|
|
217
|
-
type: "boolean",
|
|
218
|
-
required: true,
|
|
219
|
-
defaultValue: false
|
|
220
|
-
},
|
|
221
|
-
created_at: { type: "date", required: true },
|
|
222
|
-
updated_at: { type: "date", required: true }
|
|
223
|
-
}
|
|
224
|
-
},
|
|
225
|
-
tool: {
|
|
226
|
-
fields: {
|
|
227
|
-
id: { type: "string", required: true },
|
|
228
|
-
scope_id: { type: "string", required: true, index: true },
|
|
229
|
-
source_id: { type: "string", required: true, index: true },
|
|
230
|
-
plugin_id: { type: "string", required: true, index: true },
|
|
231
|
-
name: { type: "string", required: true },
|
|
232
|
-
description: { type: "string", required: true },
|
|
233
|
-
input_schema: { type: "json", required: false },
|
|
234
|
-
output_schema: { type: "json", required: false },
|
|
235
|
-
// NOTE: tool annotations (requiresApproval, approvalDescription,
|
|
236
|
-
// mayElicit) are NOT stored on this row. They're derived at read
|
|
237
|
-
// time from plugin-owned data via `plugin.resolveAnnotations`,
|
|
238
|
-
// because the source of truth already lives in each plugin's own
|
|
239
|
-
// storage (openapi's OperationBinding, etc.) and duplicating it
|
|
240
|
-
// here would just mean bulk-rewriting rows every time the
|
|
241
|
-
// derivation logic changes.
|
|
242
|
-
created_at: { type: "date", required: true },
|
|
243
|
-
updated_at: { type: "date", required: true }
|
|
244
|
-
}
|
|
245
|
-
},
|
|
246
|
-
// Shared JSON-schema `$defs` stored once per source. Tool input/output
|
|
247
|
-
// schemas carry `$ref: "#/$defs/X"` pointers; the read path attaches
|
|
248
|
-
// matching defs under `$defs` before returning. Keyed by synthetic id
|
|
249
|
-
// `${source_id}.${name}` so cleanup on source removal is a single
|
|
250
|
-
// deleteMany by source_id.
|
|
251
|
-
definition: {
|
|
252
|
-
fields: {
|
|
253
|
-
id: { type: "string", required: true },
|
|
254
|
-
scope_id: { type: "string", required: true, index: true },
|
|
255
|
-
source_id: { type: "string", required: true, index: true },
|
|
256
|
-
plugin_id: { type: "string", required: true, index: true },
|
|
257
|
-
name: { type: "string", required: true },
|
|
258
|
-
schema: { type: "json", required: true },
|
|
259
|
-
created_at: { type: "date", required: true }
|
|
260
|
-
}
|
|
261
|
-
},
|
|
262
|
-
// Secrets live in the core surface as metadata (id, display name,
|
|
263
|
-
// provider key). Actual values never touch this table — they live in
|
|
264
|
-
// the secret provider (keychain, 1password, file, etc.) and are
|
|
265
|
-
// resolved on demand via `ctx.secrets.get(id)`.
|
|
266
|
-
//
|
|
267
|
-
// `owned_by_connection_id` ties the row to a connection. Connection-
|
|
268
|
-
// owned secrets are plumbing, not user-facing values: `ctx.secrets.list`
|
|
269
|
-
// filters them out (the user sees the Connection instead), and
|
|
270
|
-
// `ctx.secrets.remove` refuses to delete them (Connection.remove is
|
|
271
|
-
// the single owner of the lifecycle). The FK is nullable so existing
|
|
272
|
-
// "bare" secrets (API keys entered by the user, pre-connection OAuth
|
|
273
|
-
// rows during migration) remain visible and removable unchanged.
|
|
274
|
-
secret: {
|
|
275
|
-
fields: {
|
|
276
|
-
id: { type: "string", required: true },
|
|
277
|
-
scope_id: { type: "string", required: true, index: true },
|
|
278
|
-
name: { type: "string", required: true },
|
|
279
|
-
provider: { type: "string", required: true, index: true },
|
|
280
|
-
owned_by_connection_id: {
|
|
281
|
-
type: "string",
|
|
282
|
-
required: false,
|
|
283
|
-
index: true
|
|
284
|
-
},
|
|
285
|
-
created_at: { type: "date", required: true }
|
|
286
|
-
}
|
|
287
|
-
},
|
|
288
|
-
// Connections — sign-in state for one identity against one remote
|
|
289
|
-
// provider. A Connection owns one or more `secret` rows (access +
|
|
290
|
-
// refresh tokens, etc.) via `secret.owned_by_connection_id`, and the
|
|
291
|
-
// SDK exposes `ctx.connections.accessToken(id)` which transparently
|
|
292
|
-
// refreshes the backing secrets when they're near expiry. Plugins
|
|
293
|
-
// contribute refresh behavior via `plugin.connectionProviders[].refresh`
|
|
294
|
-
// keyed by `provider`, same pattern as `secretProviders`.
|
|
295
|
-
//
|
|
296
|
-
// `provider_state` is plugin-owned opaque JSON — token endpoint URL,
|
|
297
|
-
// scopes, issuer, auth-server metadata — whatever the provider's
|
|
298
|
-
// refresh handler needs to re-hit the token endpoint. It's NOT
|
|
299
|
-
// sensitive (all secrets go through the provider-backed secret rows);
|
|
300
|
-
// it's just enough metadata to drive a refresh without re-running
|
|
301
|
-
// discovery.
|
|
302
|
-
connection: {
|
|
303
|
-
fields: {
|
|
304
|
-
id: { type: "string", required: true },
|
|
305
|
-
scope_id: { type: "string", required: true, index: true },
|
|
306
|
-
/** Routing key into `plugin.connectionProviders`. OAuth2 connections
|
|
307
|
-
* use the shared `oauth2` provider. Mirrors `secret.provider`. */
|
|
308
|
-
provider: { type: "string", required: true, index: true },
|
|
309
|
-
/** Display label shown in the Connections UI. Usually the account
|
|
310
|
-
* email / handle / org name the user signed in as. */
|
|
311
|
-
identity_label: { type: "string", required: false },
|
|
312
|
-
/** Stable id of the access-token secret. Always present. */
|
|
313
|
-
access_token_secret_id: { type: "string", required: true },
|
|
314
|
-
/** Stable id of the refresh-token secret. Null for flows that
|
|
315
|
-
* don't mint a refresh token (client_credentials, etc.). */
|
|
316
|
-
refresh_token_secret_id: { type: "string", required: false },
|
|
317
|
-
/** Epoch ms when the access token expires. Null if the provider
|
|
318
|
-
* didn't declare an expiry. Used as the refresh trigger. Stored as
|
|
319
|
-
* `bigint` because `Date.now()` overflows int32. */
|
|
320
|
-
expires_at: { type: "number", required: false, bigint: true },
|
|
321
|
-
/** Scope string as returned by the token endpoint. */
|
|
322
|
-
scope: { type: "string", required: false },
|
|
323
|
-
/** Opaque plugin-owned JSON — token endpoint URL, scopes list,
|
|
324
|
-
* discovery hints, etc. Never sensitive. */
|
|
325
|
-
provider_state: { type: "json", required: false },
|
|
326
|
-
created_at: { type: "date", required: true },
|
|
327
|
-
updated_at: { type: "date", required: true }
|
|
328
|
-
}
|
|
329
|
-
},
|
|
330
|
-
// Pending OAuth authorization rows shared by every OAuth-capable plugin.
|
|
331
|
-
// Rows are short-lived and deleted after completion/cancel; the resulting
|
|
332
|
-
// `connection` row is the durable sign-in state.
|
|
333
|
-
oauth2_session: {
|
|
334
|
-
fields: {
|
|
335
|
-
id: { type: "string", required: true },
|
|
336
|
-
scope_id: { type: "string", required: true, index: true },
|
|
337
|
-
plugin_id: { type: "string", required: true, index: true },
|
|
338
|
-
strategy: { type: "string", required: true },
|
|
339
|
-
connection_id: { type: "string", required: true, index: true },
|
|
340
|
-
token_scope: { type: "string", required: true },
|
|
341
|
-
redirect_url: { type: "string", required: true },
|
|
342
|
-
payload: { type: "json", required: true },
|
|
343
|
-
expires_at: { type: "number", required: true, bigint: true },
|
|
344
|
-
created_at: { type: "date", required: true }
|
|
345
|
-
}
|
|
346
|
-
},
|
|
347
|
-
// Shared credential slot bindings. Plugins keep source-specific semantics
|
|
348
|
-
// local, but credential ownership and resolution use one scoped shape.
|
|
349
|
-
credential_binding: {
|
|
350
|
-
fields: {
|
|
351
|
-
id: { type: "string", required: true },
|
|
352
|
-
scope_id: { type: "string", required: true, index: true },
|
|
353
|
-
plugin_id: { type: "string", required: true, index: true },
|
|
354
|
-
source_id: { type: "string", required: true, index: true },
|
|
355
|
-
source_scope_id: { type: "string", required: true, index: true },
|
|
356
|
-
slot_key: { type: "string", required: true, index: true },
|
|
357
|
-
/** "text" | "secret" | "connection". */
|
|
358
|
-
kind: { type: credentialBindingKinds, required: true, index: true },
|
|
359
|
-
text_value: { type: "string", required: false },
|
|
360
|
-
secret_id: { type: "string", required: false, index: true },
|
|
361
|
-
secret_scope_id: { type: "string", required: false, index: true },
|
|
362
|
-
connection_id: { type: "string", required: false, index: true },
|
|
363
|
-
created_at: { type: "date", required: true },
|
|
364
|
-
updated_at: { type: "date", required: true }
|
|
365
|
-
}
|
|
366
|
-
},
|
|
367
|
-
// User-authored overrides for tool permissions. Each row is one rule:
|
|
368
|
-
// a glob-ish pattern + an action (approve / require_approval / block).
|
|
369
|
-
// Resolution walks the scope stack innermost-first, then `position`
|
|
370
|
-
// ascending within each scope; first match wins. Plugin-derived
|
|
371
|
-
// annotations from `resolveAnnotations` apply only when no rule
|
|
372
|
-
// matches.
|
|
373
|
-
//
|
|
374
|
-
// Pattern grammar (v1):
|
|
375
|
-
// - `*` every tool id (universal)
|
|
376
|
-
// - `vercel.dns.create` exact tool id
|
|
377
|
-
// - `vercel.dns.*` any tool whose id starts with `vercel.dns.`
|
|
378
|
-
// - `vercel.*` plugin-wide
|
|
379
|
-
// No `**`, no brace expansion, no leading-`*` prefixes (`*foo`, `*.foo`).
|
|
380
|
-
tool_policy: {
|
|
381
|
-
fields: {
|
|
382
|
-
id: { type: "string", required: true },
|
|
383
|
-
scope_id: { type: "string", required: true, index: true },
|
|
384
|
-
pattern: { type: "string", required: true },
|
|
385
|
-
/** "approve" | "require_approval" | "block". */
|
|
386
|
-
action: { type: "string", required: true },
|
|
387
|
-
/** Fractional-indexing key (Jira lexorank style). Lower lex order =
|
|
388
|
-
* higher precedence. New rules default to a key generated above
|
|
389
|
-
* the current minimum. Strings instead of numbers so we can
|
|
390
|
-
* always lengthen the key to insert between two adjacent rows
|
|
391
|
-
* without precision loss; see `fractional-indexing` in
|
|
392
|
-
* `policies.ts`. */
|
|
393
|
-
position: { type: "string", required: true, index: true },
|
|
394
|
-
created_at: { type: "date", required: true },
|
|
395
|
-
updated_at: { type: "date", required: true }
|
|
396
|
-
}
|
|
397
|
-
}
|
|
398
|
-
};
|
|
399
|
-
|
|
400
|
-
// ../sdk/src/policies.ts
|
|
401
|
-
import { Match, Schema as Schema6 } from "effect";
|
|
402
|
-
var ToolPolicyActionSchema = Schema6.Literals(["approve", "require_approval", "block"]);
|
|
403
|
-
|
|
404
|
-
// ../sdk/src/secrets.ts
|
|
405
|
-
import { Schema as Schema7 } from "effect";
|
|
406
|
-
var SecretRef = class extends Schema7.Class("SecretRef")({
|
|
407
|
-
id: SecretId,
|
|
408
|
-
scopeId: ScopeId,
|
|
409
|
-
/** Human-readable label (e.g. "Cloudflare API Token") */
|
|
410
|
-
name: Schema7.String,
|
|
411
|
-
/** Which provider holds the value */
|
|
412
|
-
provider: Schema7.String,
|
|
413
|
-
createdAt: Schema7.Date
|
|
414
|
-
}) {
|
|
415
|
-
};
|
|
416
|
-
var SetSecretInput = class extends Schema7.Class("SetSecretInput")({
|
|
417
|
-
id: SecretId,
|
|
418
|
-
/** Scope id to own this secret. Must be one of the executor's
|
|
419
|
-
* configured scopes. */
|
|
420
|
-
scope: ScopeId,
|
|
421
|
-
/** Display name shown in secret-list UI. */
|
|
422
|
-
name: Schema7.String,
|
|
423
|
-
/** The secret value itself — never persisted outside the provider. */
|
|
424
|
-
value: Schema7.String,
|
|
425
|
-
/** Optional provider routing. If unset the executor picks the first
|
|
426
|
-
* writable provider in registration order. */
|
|
427
|
-
provider: Schema7.optional(Schema7.String)
|
|
428
|
-
}) {
|
|
429
|
-
};
|
|
430
|
-
var RemoveSecretInput = class extends Schema7.Class("RemoveSecretInput")({
|
|
431
|
-
id: SecretId,
|
|
432
|
-
/** Scope id whose secret row/value should be removed. Must be one of
|
|
433
|
-
* the executor's configured scopes. */
|
|
434
|
-
targetScope: ScopeId
|
|
435
|
-
}) {
|
|
436
|
-
};
|
|
437
|
-
|
|
438
|
-
// ../sdk/src/secret-backed-value.ts
|
|
439
|
-
import { Effect as Effect3, Schema as Schema8 } from "effect";
|
|
440
|
-
var SecretBackedValue = Schema8.Union([
|
|
441
|
-
Schema8.String,
|
|
442
|
-
Schema8.Struct({
|
|
443
|
-
secretId: Schema8.String,
|
|
444
|
-
prefix: Schema8.optional(Schema8.String)
|
|
445
|
-
})
|
|
446
|
-
]);
|
|
447
|
-
var SecretBackedMap = Schema8.Record(Schema8.String, SecretBackedValue);
|
|
448
|
-
|
|
449
|
-
// ../sdk/src/credential-bindings.ts
|
|
450
|
-
import { Match as Match2, Schema as Schema9 } from "effect";
|
|
451
|
-
var CredentialBindingKind = Schema9.Literals(credentialBindingKinds);
|
|
452
|
-
var CredentialBindingValue = Schema9.Union([
|
|
453
|
-
Schema9.Struct({
|
|
454
|
-
kind: Schema9.Literal("text"),
|
|
455
|
-
text: Schema9.String
|
|
456
|
-
}),
|
|
457
|
-
Schema9.Struct({
|
|
458
|
-
kind: Schema9.Literal("secret"),
|
|
459
|
-
secretId: SecretId,
|
|
460
|
-
secretScopeId: Schema9.optional(ScopeId)
|
|
461
|
-
}),
|
|
462
|
-
Schema9.Struct({
|
|
463
|
-
kind: Schema9.Literal("connection"),
|
|
464
|
-
connectionId: ConnectionId
|
|
465
|
-
})
|
|
466
|
-
]);
|
|
467
|
-
var ConfiguredCredentialBindingSchema = Schema9.Struct({
|
|
468
|
-
kind: Schema9.Literal("binding"),
|
|
469
|
-
slot: Schema9.String,
|
|
470
|
-
prefix: Schema9.optional(Schema9.String)
|
|
471
|
-
});
|
|
472
|
-
var ConfiguredCredentialBinding = class extends Schema9.Class(
|
|
473
|
-
"ConfiguredCredentialBinding"
|
|
474
|
-
)(ConfiguredCredentialBindingSchema.fields) {
|
|
475
|
-
};
|
|
476
|
-
var ConfiguredCredentialValue = Schema9.Union([Schema9.String, ConfiguredCredentialBinding]);
|
|
477
|
-
var ConfiguredCredentialValueSchema = Schema9.Union([
|
|
478
|
-
Schema9.String,
|
|
479
|
-
ConfiguredCredentialBindingSchema
|
|
480
|
-
]);
|
|
481
|
-
var ScopedSecretCredentialInput = Schema9.Struct({
|
|
482
|
-
secretId: Schema9.String,
|
|
483
|
-
prefix: Schema9.optional(Schema9.String),
|
|
484
|
-
targetScope: ScopeId,
|
|
485
|
-
secretScopeId: Schema9.optional(ScopeId)
|
|
486
|
-
});
|
|
487
|
-
var CredentialBindingRef = class extends Schema9.Class(
|
|
488
|
-
"CredentialBindingRef"
|
|
489
|
-
)({
|
|
490
|
-
id: CredentialBindingId,
|
|
491
|
-
scopeId: ScopeId,
|
|
492
|
-
pluginId: Schema9.String,
|
|
493
|
-
sourceId: Schema9.String,
|
|
494
|
-
sourceScopeId: ScopeId,
|
|
495
|
-
slotKey: Schema9.String,
|
|
496
|
-
value: CredentialBindingValue,
|
|
497
|
-
createdAt: Schema9.Date,
|
|
498
|
-
updatedAt: Schema9.Date
|
|
499
|
-
}) {
|
|
500
|
-
};
|
|
501
|
-
var SetCredentialBindingInput = class extends Schema9.Class(
|
|
502
|
-
"SetCredentialBindingInput"
|
|
503
|
-
)({
|
|
504
|
-
targetScope: ScopeId,
|
|
505
|
-
pluginId: Schema9.String,
|
|
506
|
-
sourceId: Schema9.String,
|
|
507
|
-
sourceScope: ScopeId,
|
|
508
|
-
slotKey: Schema9.String,
|
|
509
|
-
value: CredentialBindingValue
|
|
510
|
-
}) {
|
|
511
|
-
};
|
|
512
|
-
var CredentialBindingSourceInput = class extends Schema9.Class(
|
|
513
|
-
"CredentialBindingSourceInput"
|
|
514
|
-
)({
|
|
515
|
-
pluginId: Schema9.String,
|
|
516
|
-
sourceId: Schema9.String,
|
|
517
|
-
sourceScope: ScopeId
|
|
518
|
-
}) {
|
|
519
|
-
};
|
|
520
|
-
var CredentialBindingSlotInput = class extends Schema9.Class(
|
|
521
|
-
"CredentialBindingSlotInput"
|
|
522
|
-
)({
|
|
523
|
-
pluginId: Schema9.String,
|
|
524
|
-
sourceId: Schema9.String,
|
|
525
|
-
sourceScope: ScopeId,
|
|
526
|
-
slotKey: Schema9.String
|
|
527
|
-
}) {
|
|
528
|
-
};
|
|
529
|
-
var RemoveCredentialBindingInput = class extends Schema9.Class(
|
|
530
|
-
"RemoveCredentialBindingInput"
|
|
531
|
-
)({
|
|
532
|
-
targetScope: ScopeId,
|
|
533
|
-
pluginId: Schema9.String,
|
|
534
|
-
sourceId: Schema9.String,
|
|
535
|
-
sourceScope: ScopeId,
|
|
536
|
-
slotKey: Schema9.String
|
|
537
|
-
}) {
|
|
538
|
-
};
|
|
539
|
-
var ReplaceCredentialBindingValue = class extends Schema9.Class(
|
|
540
|
-
"ReplaceCredentialBindingValue"
|
|
541
|
-
)({
|
|
542
|
-
slotKey: Schema9.String,
|
|
543
|
-
value: CredentialBindingValue
|
|
544
|
-
}) {
|
|
545
|
-
};
|
|
546
|
-
var ReplaceCredentialBindingsInput = class extends Schema9.Class(
|
|
547
|
-
"ReplaceCredentialBindingsInput"
|
|
548
|
-
)({
|
|
549
|
-
targetScope: ScopeId,
|
|
550
|
-
pluginId: Schema9.String,
|
|
551
|
-
sourceId: Schema9.String,
|
|
552
|
-
sourceScope: ScopeId,
|
|
553
|
-
slotPrefixes: Schema9.Array(Schema9.String),
|
|
554
|
-
bindings: Schema9.Array(ReplaceCredentialBindingValue)
|
|
555
|
-
}) {
|
|
556
|
-
};
|
|
557
|
-
var CredentialBindingResolutionStatus = Schema9.Literals([
|
|
558
|
-
"resolved",
|
|
559
|
-
"missing",
|
|
560
|
-
"blocked"
|
|
561
|
-
]);
|
|
562
|
-
var ResolvedCredentialSlot = class extends Schema9.Class(
|
|
563
|
-
"ResolvedCredentialSlot"
|
|
564
|
-
)({
|
|
565
|
-
pluginId: Schema9.String,
|
|
566
|
-
sourceId: Schema9.String,
|
|
567
|
-
sourceScopeId: ScopeId,
|
|
568
|
-
slotKey: Schema9.String,
|
|
569
|
-
bindingScopeId: Schema9.NullOr(ScopeId),
|
|
570
|
-
kind: Schema9.NullOr(CredentialBindingKind),
|
|
571
|
-
status: CredentialBindingResolutionStatus
|
|
572
|
-
}) {
|
|
573
|
-
};
|
|
574
|
-
|
|
575
|
-
// ../sdk/src/usages.ts
|
|
576
|
-
import { Schema as Schema10 } from "effect";
|
|
577
|
-
var Usage = class extends Schema10.Class("Usage")({
|
|
578
|
-
pluginId: Schema10.String,
|
|
579
|
-
scopeId: ScopeId,
|
|
580
|
-
ownerKind: Schema10.String,
|
|
581
|
-
ownerId: Schema10.String,
|
|
582
|
-
ownerName: Schema10.NullOr(Schema10.String),
|
|
583
|
-
slot: Schema10.String
|
|
584
|
-
}) {
|
|
585
|
-
};
|
|
586
|
-
|
|
587
|
-
// ../sdk/src/connections.ts
|
|
588
|
-
import { Data as Data3, Schema as Schema11 } from "effect";
|
|
589
|
-
var ConnectionProviderState = Schema11.Record(Schema11.String, Schema11.Unknown);
|
|
590
|
-
var ConnectionRef = class extends Schema11.Class("ConnectionRef")({
|
|
591
|
-
id: ConnectionId,
|
|
592
|
-
scopeId: ScopeId,
|
|
593
|
-
provider: Schema11.String,
|
|
594
|
-
identityLabel: Schema11.NullOr(Schema11.String),
|
|
595
|
-
accessTokenSecretId: SecretId,
|
|
596
|
-
refreshTokenSecretId: Schema11.NullOr(SecretId),
|
|
597
|
-
/** Epoch ms when the access token expires; null if not declared. */
|
|
598
|
-
expiresAt: Schema11.NullOr(Schema11.Number),
|
|
599
|
-
/** OAuth-style scope string as returned by the token endpoint. Named
|
|
600
|
-
* `oauthScope` to avoid collision with the executor scope id. */
|
|
601
|
-
oauthScope: Schema11.NullOr(Schema11.String),
|
|
602
|
-
providerState: Schema11.NullOr(ConnectionProviderState),
|
|
603
|
-
createdAt: Schema11.Date,
|
|
604
|
-
updatedAt: Schema11.Date
|
|
605
|
-
}) {
|
|
606
|
-
};
|
|
607
|
-
var TokenMaterial = class extends Schema11.Class("TokenMaterial")({
|
|
608
|
-
/** Target secret id. Plugins typically derive this from the source id
|
|
609
|
-
* + a stable suffix (e.g. `${sourceId}.access_token`). */
|
|
610
|
-
secretId: SecretId,
|
|
611
|
-
/** Display name stamped on the secret row. Only visible to code — the
|
|
612
|
-
* Connections UI hides connection-owned secrets. */
|
|
613
|
-
name: Schema11.String,
|
|
614
|
-
value: Schema11.String
|
|
615
|
-
}) {
|
|
616
|
-
};
|
|
617
|
-
var CreateConnectionInput = class extends Schema11.Class(
|
|
618
|
-
"CreateConnectionInput"
|
|
619
|
-
)({
|
|
620
|
-
id: ConnectionId,
|
|
621
|
-
/** Executor scope id that will own this connection + its backing
|
|
622
|
-
* secrets. This is the sharing boundary: a user scope is personal,
|
|
623
|
-
* an org/workspace scope is shared with descendants. */
|
|
624
|
-
scope: ScopeId,
|
|
625
|
-
provider: Schema11.String,
|
|
626
|
-
identityLabel: Schema11.NullOr(Schema11.String),
|
|
627
|
-
accessToken: TokenMaterial,
|
|
628
|
-
refreshToken: Schema11.NullOr(TokenMaterial),
|
|
629
|
-
expiresAt: Schema11.NullOr(Schema11.Number),
|
|
630
|
-
/** OAuth-style scope string. Distinct from the executor scope above. */
|
|
631
|
-
oauthScope: Schema11.NullOr(Schema11.String),
|
|
632
|
-
providerState: Schema11.NullOr(ConnectionProviderState)
|
|
633
|
-
}) {
|
|
634
|
-
};
|
|
635
|
-
var ConnectionRefreshError = class extends Data3.TaggedError("ConnectionRefreshError") {
|
|
636
|
-
};
|
|
637
|
-
var UpdateConnectionTokensInput = class extends Schema11.Class(
|
|
638
|
-
"UpdateConnectionTokensInput"
|
|
639
|
-
)({
|
|
640
|
-
id: ConnectionId,
|
|
641
|
-
accessToken: Schema11.String,
|
|
642
|
-
refreshToken: Schema11.optional(Schema11.NullOr(Schema11.String)),
|
|
643
|
-
expiresAt: Schema11.optional(Schema11.NullOr(Schema11.Number)),
|
|
644
|
-
oauthScope: Schema11.optional(Schema11.NullOr(Schema11.String)),
|
|
645
|
-
providerState: Schema11.optional(Schema11.NullOr(ConnectionProviderState)),
|
|
646
|
-
identityLabel: Schema11.optional(Schema11.NullOr(Schema11.String))
|
|
647
|
-
}) {
|
|
648
|
-
};
|
|
649
|
-
var RemoveConnectionInput = class extends Schema11.Class(
|
|
650
|
-
"RemoveConnectionInput"
|
|
651
|
-
)({
|
|
652
|
-
id: ConnectionId,
|
|
653
|
-
/** Scope id whose connection row and owned token secrets should be removed. */
|
|
654
|
-
targetScope: ScopeId
|
|
655
|
-
}) {
|
|
656
|
-
};
|
|
657
|
-
|
|
658
|
-
// ../sdk/src/elicitation.ts
|
|
659
|
-
import { Schema as Schema12 } from "effect";
|
|
660
|
-
var FormElicitation = class extends Schema12.TaggedClass()("FormElicitation", {
|
|
661
|
-
message: Schema12.String,
|
|
662
|
-
/** JSON Schema describing the fields to collect */
|
|
663
|
-
requestedSchema: Schema12.Record(Schema12.String, Schema12.Unknown)
|
|
664
|
-
}) {
|
|
665
|
-
};
|
|
666
|
-
var UrlElicitation = class extends Schema12.TaggedClass()("UrlElicitation", {
|
|
667
|
-
message: Schema12.String,
|
|
668
|
-
url: Schema12.String,
|
|
669
|
-
/** Unique ID so the host can correlate the callback */
|
|
670
|
-
elicitationId: Schema12.String
|
|
671
|
-
}) {
|
|
672
|
-
};
|
|
673
|
-
var ElicitationAction = Schema12.Literals(["accept", "decline", "cancel"]);
|
|
674
|
-
var ElicitationResponse = class extends Schema12.Class("ElicitationResponse")({
|
|
675
|
-
action: ElicitationAction,
|
|
676
|
-
/** Present when action is "accept" — the data the user provided */
|
|
677
|
-
content: Schema12.optional(Schema12.Record(Schema12.String, Schema12.Unknown))
|
|
678
|
-
}) {
|
|
679
|
-
};
|
|
680
|
-
var ElicitationDeclinedError = class extends Schema12.TaggedErrorClass()(
|
|
681
|
-
"ElicitationDeclinedError",
|
|
682
|
-
{
|
|
683
|
-
toolId: ToolId,
|
|
684
|
-
action: Schema12.Literals(["decline", "cancel"])
|
|
685
|
-
}
|
|
686
|
-
) {
|
|
687
|
-
};
|
|
688
|
-
|
|
689
|
-
// ../sdk/src/blob.ts
|
|
690
|
-
import { Effect as Effect7 } from "effect";
|
|
691
|
-
|
|
692
|
-
// ../sdk/src/oauth.ts
|
|
693
|
-
import { Effect as Effect8, Schema as Schema13 } from "effect";
|
|
694
|
-
var OAuthDynamicDcrStrategy = Schema13.Struct({
|
|
695
|
-
kind: Schema13.Literal("dynamic-dcr"),
|
|
696
|
-
/** Scopes to request. Defaults to whatever `scopes_supported`
|
|
697
|
-
* advertises; caller can narrow or extend. */
|
|
698
|
-
scopes: Schema13.optional(Schema13.Array(Schema13.String))
|
|
699
|
-
});
|
|
700
|
-
var OAuthAuthorizationCodeStrategy = Schema13.Struct({
|
|
701
|
-
kind: Schema13.Literal("authorization-code"),
|
|
702
|
-
authorizationEndpoint: Schema13.String,
|
|
703
|
-
tokenEndpoint: Schema13.String,
|
|
704
|
-
/** Expected authorization-server issuer for ID token validation. Some
|
|
705
|
-
* providers use a token endpoint host that differs from issuer, or a
|
|
706
|
-
* path-scoped issuer such as Okta custom authorization servers. */
|
|
707
|
-
issuerUrl: Schema13.optional(Schema13.NullOr(Schema13.String)),
|
|
708
|
-
/** Secret id holding the `client_id`. Using a secret row rather than
|
|
709
|
-
* an inline string so the value lives at the scope where the caller
|
|
710
|
-
* configured it and shadowing behaves consistently. */
|
|
711
|
-
clientIdSecretId: Schema13.String,
|
|
712
|
-
/** Secret id for `client_secret`. Null for public clients using
|
|
713
|
-
* PKCE without a confidential secret. */
|
|
714
|
-
clientSecretSecretId: Schema13.NullOr(Schema13.String),
|
|
715
|
-
scopes: Schema13.Array(Schema13.String),
|
|
716
|
-
/** Separator between scopes. RFC 6749 says space; some providers
|
|
717
|
-
* (GitHub classic) use comma. */
|
|
718
|
-
scopeSeparator: Schema13.optional(Schema13.String),
|
|
719
|
-
/** Provider-specific params injected at authorization URL build time
|
|
720
|
-
* (Google's `access_type=offline`, `prompt=consent`, ...). */
|
|
721
|
-
extraAuthorizationParams: Schema13.optional(Schema13.Record(Schema13.String, Schema13.String)),
|
|
722
|
-
/** `"body"` (default) sends client creds in the form body; `"basic"`
|
|
723
|
-
* uses HTTP Basic auth. Stripe-style servers require basic. */
|
|
724
|
-
clientAuth: Schema13.optional(Schema13.Literals(["body", "basic"]))
|
|
725
|
-
});
|
|
726
|
-
var OAuthClientCredentialsStrategy = Schema13.Struct({
|
|
727
|
-
kind: Schema13.Literal("client-credentials"),
|
|
728
|
-
tokenEndpoint: Schema13.String,
|
|
729
|
-
clientIdSecretId: Schema13.String,
|
|
730
|
-
clientSecretSecretId: Schema13.String,
|
|
731
|
-
scopes: Schema13.optional(Schema13.Array(Schema13.String)),
|
|
732
|
-
scopeSeparator: Schema13.optional(Schema13.String),
|
|
733
|
-
clientAuth: Schema13.optional(Schema13.Literals(["body", "basic"]))
|
|
734
|
-
});
|
|
735
|
-
var OAuthStrategy = Schema13.Union([
|
|
736
|
-
OAuthDynamicDcrStrategy,
|
|
737
|
-
OAuthAuthorizationCodeStrategy,
|
|
738
|
-
OAuthClientCredentialsStrategy
|
|
739
|
-
]);
|
|
740
|
-
var OAuthProviderState = Schema13.Union([
|
|
741
|
-
Schema13.Struct({
|
|
742
|
-
kind: Schema13.Literal("dynamic-dcr"),
|
|
743
|
-
tokenEndpoint: Schema13.String,
|
|
744
|
-
issuerUrl: Schema13.optional(Schema13.NullOr(Schema13.String)),
|
|
745
|
-
authorizationServerUrl: Schema13.optional(Schema13.NullOr(Schema13.String)),
|
|
746
|
-
authorizationServerMetadataUrl: Schema13.NullOr(Schema13.String),
|
|
747
|
-
idTokenSigningAlgValuesSupported: Schema13.optional(Schema13.Array(Schema13.String)),
|
|
748
|
-
/** DCR-minted client_id. Embedded inline (not a secret) — DCR
|
|
749
|
-
* clients are public-ish by design; the secret part (if the AS
|
|
750
|
-
* issued one) is a separate secret row. */
|
|
751
|
-
clientId: Schema13.String,
|
|
752
|
-
clientSecretSecretId: Schema13.NullOr(Schema13.String),
|
|
753
|
-
clientSecretSecretScopeId: Schema13.optional(Schema13.NullOr(Schema13.String)),
|
|
754
|
-
clientAuth: Schema13.Literals(["body", "basic"]),
|
|
755
|
-
scopes: Schema13.Array(Schema13.String).pipe(Schema13.withDecodingDefaultType(Effect8.succeed([]))),
|
|
756
|
-
scopeSeparator: Schema13.optional(Schema13.String),
|
|
757
|
-
scope: Schema13.NullOr(Schema13.String),
|
|
758
|
-
/** RFC 8707 canonical resource URL. Replayed on refresh so the new
|
|
759
|
-
* access token's audience stays bound to the same resource. */
|
|
760
|
-
resource: Schema13.optional(Schema13.NullOr(Schema13.String))
|
|
761
|
-
}),
|
|
762
|
-
Schema13.Struct({
|
|
763
|
-
kind: Schema13.Literal("authorization-code"),
|
|
764
|
-
tokenEndpoint: Schema13.String,
|
|
765
|
-
issuerUrl: Schema13.optional(Schema13.NullOr(Schema13.String)),
|
|
766
|
-
clientIdSecretId: Schema13.String,
|
|
767
|
-
clientIdSecretScopeId: Schema13.optional(Schema13.NullOr(Schema13.String)),
|
|
768
|
-
clientSecretSecretId: Schema13.NullOr(Schema13.String),
|
|
769
|
-
clientSecretSecretScopeId: Schema13.optional(Schema13.NullOr(Schema13.String)),
|
|
770
|
-
clientAuth: Schema13.Literals(["body", "basic"]),
|
|
771
|
-
scopes: Schema13.Array(Schema13.String).pipe(Schema13.withDecodingDefaultType(Effect8.succeed([]))),
|
|
772
|
-
scopeSeparator: Schema13.optional(Schema13.String),
|
|
773
|
-
scope: Schema13.NullOr(Schema13.String),
|
|
774
|
-
resource: Schema13.optional(Schema13.NullOr(Schema13.String))
|
|
775
|
-
}),
|
|
776
|
-
Schema13.Struct({
|
|
777
|
-
kind: Schema13.Literal("client-credentials"),
|
|
778
|
-
tokenEndpoint: Schema13.String,
|
|
779
|
-
clientIdSecretId: Schema13.String,
|
|
780
|
-
clientIdSecretScopeId: Schema13.optional(Schema13.NullOr(Schema13.String)),
|
|
781
|
-
clientSecretSecretId: Schema13.String,
|
|
782
|
-
clientSecretSecretScopeId: Schema13.optional(Schema13.NullOr(Schema13.String)),
|
|
783
|
-
scopes: Schema13.Array(Schema13.String),
|
|
784
|
-
scopeSeparator: Schema13.optional(Schema13.String),
|
|
785
|
-
clientAuth: Schema13.Literals(["body", "basic"]),
|
|
786
|
-
scope: Schema13.NullOr(Schema13.String)
|
|
787
|
-
})
|
|
788
|
-
]);
|
|
789
|
-
var OAuthProbeError = class extends Schema13.TaggedErrorClass()(
|
|
790
|
-
"OAuthProbeError",
|
|
791
|
-
{
|
|
792
|
-
message: Schema13.String
|
|
793
|
-
},
|
|
794
|
-
{ httpApiStatus: 400 }
|
|
795
|
-
) {
|
|
796
|
-
};
|
|
797
|
-
var OAuthStartError = class extends Schema13.TaggedErrorClass()(
|
|
798
|
-
"OAuthStartError",
|
|
799
|
-
{
|
|
800
|
-
message: Schema13.String,
|
|
801
|
-
/** RFC 6749 §5.2 / RFC 7591 §3.2.2 error code propagated up from the
|
|
802
|
-
* authorization server (e.g. `invalid_client_metadata`). UI surfaces
|
|
803
|
-
* it as the structured "AS rejected the registration" reason. */
|
|
804
|
-
error: Schema13.optional(Schema13.String),
|
|
805
|
-
errorDescription: Schema13.optional(Schema13.String)
|
|
806
|
-
},
|
|
807
|
-
{ httpApiStatus: 400 }
|
|
808
|
-
) {
|
|
809
|
-
};
|
|
810
|
-
var OAuthCompleteError = class extends Schema13.TaggedErrorClass()(
|
|
811
|
-
"OAuthCompleteError",
|
|
812
|
-
{
|
|
813
|
-
message: Schema13.String,
|
|
814
|
-
/** RFC 6749 §5.2 error code, when the token endpoint returned one.
|
|
815
|
-
* Callers distinguish terminal failures (`invalid_grant` ⇒
|
|
816
|
-
* re-auth required) from transient ones. */
|
|
817
|
-
code: Schema13.optional(Schema13.String)
|
|
818
|
-
},
|
|
819
|
-
{ httpApiStatus: 400 }
|
|
820
|
-
) {
|
|
821
|
-
};
|
|
822
|
-
var OAuthSessionNotFoundError = class extends Schema13.TaggedErrorClass()(
|
|
823
|
-
"OAuthSessionNotFoundError",
|
|
824
|
-
{
|
|
825
|
-
sessionId: Schema13.String
|
|
826
|
-
},
|
|
827
|
-
{ httpApiStatus: 404 }
|
|
828
|
-
) {
|
|
829
|
-
};
|
|
830
|
-
var OAUTH2_SESSION_TTL_MS = 15 * 60 * 1e3;
|
|
831
|
-
|
|
832
|
-
// ../sdk/src/oauth-helpers.ts
|
|
833
|
-
import { Data as Data4, Effect as Effect9, Predicate } from "effect";
|
|
834
|
-
var OAuth2Error = class extends Data4.TaggedError("OAuth2Error") {
|
|
835
|
-
};
|
|
836
|
-
var isOAuth2Error = Predicate.isTagged("OAuth2Error");
|
|
837
|
-
|
|
838
|
-
// ../sdk/src/oauth-service.ts
|
|
839
|
-
import { Duration as Duration2, Effect as Effect11, Match as Match3, Option as Option3, Schema as Schema15 } from "effect";
|
|
840
|
-
import { FetchHttpClient as FetchHttpClient2, HttpClient as HttpClient2, HttpClientRequest as HttpClientRequest2 } from "effect/unstable/http";
|
|
841
|
-
|
|
842
|
-
// ../sdk/src/oauth-discovery.ts
|
|
843
|
-
import { Data as Data5, Duration, Effect as Effect10, Option as Option2, Predicate as Predicate2, Result, Schema as Schema14 } from "effect";
|
|
844
|
-
import { FetchHttpClient, HttpClient, HttpClientRequest } from "effect/unstable/http";
|
|
845
|
-
var OAuthDiscoveryError = class extends Data5.TaggedError("OAuthDiscoveryError") {
|
|
846
|
-
};
|
|
847
|
-
var StringArray = Schema14.Array(Schema14.String);
|
|
848
|
-
var OAuthProtectedResourceMetadataSchema = Schema14.Struct({
|
|
849
|
-
resource: Schema14.optional(Schema14.String),
|
|
850
|
-
authorization_servers: Schema14.optional(StringArray),
|
|
851
|
-
scopes_supported: Schema14.optional(StringArray),
|
|
852
|
-
bearer_methods_supported: Schema14.optional(StringArray),
|
|
853
|
-
resource_documentation: Schema14.optional(Schema14.String)
|
|
854
|
-
}).annotate({ identifier: "OAuthProtectedResourceMetadata" });
|
|
855
|
-
var OAuthAuthorizationServerMetadataSchema = Schema14.Struct({
|
|
856
|
-
issuer: Schema14.String,
|
|
857
|
-
authorization_endpoint: Schema14.String,
|
|
858
|
-
token_endpoint: Schema14.String,
|
|
859
|
-
registration_endpoint: Schema14.optional(Schema14.String),
|
|
860
|
-
scopes_supported: Schema14.optional(StringArray),
|
|
861
|
-
response_types_supported: Schema14.optional(StringArray),
|
|
862
|
-
grant_types_supported: Schema14.optional(StringArray),
|
|
863
|
-
code_challenge_methods_supported: Schema14.optional(StringArray),
|
|
864
|
-
token_endpoint_auth_methods_supported: Schema14.optional(StringArray),
|
|
865
|
-
revocation_endpoint: Schema14.optional(Schema14.String),
|
|
866
|
-
introspection_endpoint: Schema14.optional(Schema14.String),
|
|
867
|
-
userinfo_endpoint: Schema14.optional(Schema14.String),
|
|
868
|
-
id_token_signing_alg_values_supported: Schema14.optional(StringArray)
|
|
869
|
-
}).annotate({ identifier: "OAuthAuthorizationServerMetadata" });
|
|
870
|
-
var OAuthClientInformationSchema = Schema14.Struct({
|
|
871
|
-
client_id: Schema14.String,
|
|
872
|
-
client_secret: Schema14.optional(Schema14.String),
|
|
873
|
-
client_id_issued_at: Schema14.optional(Schema14.Number),
|
|
874
|
-
client_secret_expires_at: Schema14.optional(Schema14.Number),
|
|
875
|
-
registration_access_token: Schema14.optional(Schema14.String),
|
|
876
|
-
registration_client_uri: Schema14.optional(Schema14.String),
|
|
877
|
-
token_endpoint_auth_method: Schema14.optional(Schema14.String),
|
|
878
|
-
grant_types: Schema14.optional(StringArray),
|
|
879
|
-
response_types: Schema14.optional(StringArray),
|
|
880
|
-
redirect_uris: Schema14.optional(StringArray),
|
|
881
|
-
client_name: Schema14.optional(Schema14.String),
|
|
882
|
-
scope: Schema14.optional(Schema14.String)
|
|
883
|
-
}).annotate({ identifier: "OAuthClientInformation" });
|
|
884
|
-
var decodeResourceMetadataJson = Schema14.decodeUnknownEffect(
|
|
885
|
-
Schema14.fromJsonString(OAuthProtectedResourceMetadataSchema)
|
|
886
|
-
);
|
|
887
|
-
var decodeAuthServerMetadata = Schema14.decodeUnknownEffect(OAuthAuthorizationServerMetadataSchema);
|
|
888
|
-
var decodeClientInformationJson = Schema14.decodeUnknownEffect(
|
|
889
|
-
Schema14.fromJsonString(OAuthClientInformationSchema)
|
|
890
|
-
);
|
|
891
|
-
var DcrErrorBody = class extends Data5.TaggedError("DcrErrorBody") {
|
|
892
|
-
};
|
|
893
|
-
var DcrTransport = class extends Data5.TaggedError("DcrTransport") {
|
|
894
|
-
};
|
|
895
|
-
var DcrErrorBodyJson = Schema14.Struct({
|
|
896
|
-
error: Schema14.String,
|
|
897
|
-
error_description: Schema14.optional(Schema14.String)
|
|
898
|
-
});
|
|
899
|
-
var decodeDcrErrorBodyJson = Schema14.decodeUnknownOption(Schema14.fromJsonString(DcrErrorBodyJson));
|
|
900
|
-
|
|
901
|
-
// ../sdk/src/oauth-service.ts
|
|
902
|
-
var OAuthAuthorizationServerMetadataJson = Schema15.Record(Schema15.String, Schema15.Unknown);
|
|
903
|
-
var OAuthClientInformationJson = Schema15.Record(Schema15.String, Schema15.Unknown);
|
|
904
|
-
var DynamicDcrSessionPayload = Schema15.Struct({
|
|
905
|
-
kind: Schema15.Literal("dynamic-dcr"),
|
|
906
|
-
identityLabel: Schema15.NullOr(Schema15.String),
|
|
907
|
-
codeVerifier: Schema15.String,
|
|
908
|
-
authorizationServerUrl: Schema15.String,
|
|
909
|
-
authorizationServerMetadataUrl: Schema15.String,
|
|
910
|
-
authorizationServerMetadata: OAuthAuthorizationServerMetadataJson,
|
|
911
|
-
clientInformation: OAuthClientInformationJson,
|
|
912
|
-
resourceMetadataUrl: Schema15.NullOr(Schema15.String),
|
|
913
|
-
resourceMetadata: Schema15.NullOr(Schema15.Record(Schema15.String, Schema15.Unknown)),
|
|
914
|
-
scopes: Schema15.Array(Schema15.String),
|
|
915
|
-
resource: Schema15.NullOr(Schema15.String).pipe(Schema15.withDecodingDefaultType(Effect11.succeed(null)))
|
|
916
|
-
});
|
|
917
|
-
var AuthorizationCodeSessionPayload = Schema15.Struct({
|
|
918
|
-
kind: Schema15.Literal("authorization-code"),
|
|
919
|
-
identityLabel: Schema15.NullOr(Schema15.String),
|
|
920
|
-
codeVerifier: Schema15.String,
|
|
921
|
-
authorizationEndpoint: Schema15.String,
|
|
922
|
-
tokenEndpoint: Schema15.String,
|
|
923
|
-
issuerUrl: Schema15.NullOr(Schema15.String).pipe(
|
|
924
|
-
Schema15.withDecodingDefaultType(Effect11.succeed(null))
|
|
925
|
-
),
|
|
926
|
-
clientIdSecretId: Schema15.String,
|
|
927
|
-
clientIdSecretScopeId: Schema15.NullOr(Schema15.String).pipe(
|
|
928
|
-
Schema15.withDecodingDefaultType(Effect11.succeed(null))
|
|
929
|
-
),
|
|
930
|
-
clientSecretSecretId: Schema15.NullOr(Schema15.String),
|
|
931
|
-
clientSecretSecretScopeId: Schema15.NullOr(Schema15.String).pipe(
|
|
932
|
-
Schema15.withDecodingDefaultType(Effect11.succeed(null))
|
|
933
|
-
),
|
|
934
|
-
scopes: Schema15.Array(Schema15.String),
|
|
935
|
-
scopeSeparator: Schema15.optional(Schema15.String),
|
|
936
|
-
clientAuth: Schema15.Literals(["body", "basic"])
|
|
937
|
-
});
|
|
938
|
-
var OAuthSessionPayload = Schema15.Union([
|
|
939
|
-
DynamicDcrSessionPayload,
|
|
940
|
-
AuthorizationCodeSessionPayload
|
|
941
|
-
]);
|
|
942
|
-
var decodeSessionPayload = Schema15.decodeUnknownSync(OAuthSessionPayload);
|
|
943
|
-
var encodeSessionPayload = Schema15.encodeSync(OAuthSessionPayload);
|
|
944
|
-
var UnknownFromJsonString = Schema15.fromJsonString(Schema15.Unknown);
|
|
945
|
-
var decodeUnknownJsonOption = Schema15.decodeUnknownOption(UnknownFromJsonString);
|
|
946
|
-
var decodeProviderStateSync = Schema15.decodeUnknownSync(OAuthProviderState);
|
|
947
|
-
var encodeProviderStateSync = Schema15.encodeSync(OAuthProviderState);
|
|
948
|
-
|
|
949
|
-
// ../sdk/src/hosted-http-client.ts
|
|
950
|
-
import { Effect as Effect12, Layer as Layer3, Schema as Schema16 } from "effect";
|
|
951
|
-
import { FetchHttpClient as FetchHttpClient3 } from "effect/unstable/http";
|
|
952
|
-
var HostedOutboundRequestBlocked = class extends Schema16.TaggedErrorClass()(
|
|
953
|
-
"HostedOutboundRequestBlocked",
|
|
954
|
-
{
|
|
955
|
-
url: Schema16.String,
|
|
956
|
-
reason: Schema16.String
|
|
957
|
-
}
|
|
958
|
-
) {
|
|
959
|
-
};
|
|
960
|
-
|
|
961
|
-
// ../sdk/src/plugin.ts
|
|
962
|
-
import { Effect as Effect13 } from "effect";
|
|
963
|
-
function definePlugin(authorFactory) {
|
|
964
|
-
return (options) => {
|
|
965
|
-
const {
|
|
966
|
-
storage: storageOverride,
|
|
967
|
-
...rest
|
|
968
|
-
} = options ?? {};
|
|
969
|
-
const hasAuthorOptions = Object.keys(rest).length > 0;
|
|
970
|
-
const spec = authorFactory(hasAuthorOptions ? rest : void 0);
|
|
971
|
-
return {
|
|
972
|
-
...spec,
|
|
973
|
-
storage: storageOverride ?? spec.storage
|
|
974
|
-
};
|
|
975
|
-
};
|
|
976
|
-
}
|
|
977
|
-
|
|
978
|
-
// ../sdk/src/executor.ts
|
|
979
|
-
import {
|
|
980
|
-
Context,
|
|
981
|
-
Deferred,
|
|
982
|
-
Effect as Effect15,
|
|
983
|
-
Match as Match5,
|
|
984
|
-
Option as Option5,
|
|
985
|
-
Result as Result2,
|
|
986
|
-
Schema as Schema17,
|
|
987
|
-
Semaphore
|
|
988
|
-
} from "effect";
|
|
989
|
-
import { FetchHttpClient as FetchHttpClient4 } from "effect/unstable/http";
|
|
990
|
-
|
|
991
|
-
// ../sdk/src/schema-types.ts
|
|
992
|
-
import { Match as Match4, Option as Option4 } from "effect";
|
|
993
|
-
|
|
994
|
-
// ../sdk/src/scoped-adapter.ts
|
|
995
|
-
import { Effect as Effect14 } from "effect";
|
|
996
|
-
|
|
997
|
-
// ../sdk/src/executor.ts
|
|
998
|
-
var collectSchemas = (plugins) => {
|
|
999
|
-
const merged = { ...coreSchema };
|
|
1000
|
-
for (const plugin of plugins) {
|
|
1001
|
-
if (!plugin.schema) continue;
|
|
1002
|
-
for (const [modelKey, model] of Object.entries(plugin.schema)) {
|
|
1003
|
-
if (merged[modelKey]) {
|
|
1004
|
-
throw new StorageError({
|
|
1005
|
-
message: `Duplicate model "${modelKey}" contributed by plugin "${plugin.id}" (reserved by core or another plugin)`,
|
|
1006
|
-
cause: void 0
|
|
1007
|
-
});
|
|
1008
|
-
}
|
|
1009
|
-
merged[modelKey] = model;
|
|
1010
|
-
}
|
|
1011
|
-
}
|
|
1012
|
-
return merged;
|
|
1013
|
-
};
|
|
1014
|
-
var decodeJsonFromString2 = Schema17.decodeUnknownOption(Schema17.UnknownFromJsonString);
|
|
1015
|
-
var decodeProviderState = Schema17.decodeUnknownOption(ConnectionProviderState);
|
|
1016
|
-
var activeAdapterRef = Context.Reference("executor/ActiveAdapter", {
|
|
1017
|
-
defaultValue: () => null
|
|
1018
|
-
});
|
|
1019
|
-
var activeRawAdapterRef = Context.Reference(
|
|
1020
|
-
"executor/ActiveRawAdapter",
|
|
1021
|
-
{
|
|
1022
|
-
defaultValue: () => null
|
|
1023
|
-
}
|
|
1024
|
-
);
|
|
1025
|
-
|
|
1026
|
-
// ../storage-core/src/testing/memory.ts
|
|
1027
|
-
import { Effect as Effect16, Match as Match6 } from "effect";
|
|
1028
|
-
|
|
1029
|
-
// ../sdk/src/test-config.ts
|
|
1030
|
-
import { Effect as Effect17 } from "effect";
|
|
1031
|
-
var memorySecretsPlugin = definePlugin(() => {
|
|
1032
|
-
const store = /* @__PURE__ */ new Map();
|
|
1033
|
-
const provider = {
|
|
1034
|
-
key: "memory",
|
|
1035
|
-
writable: true,
|
|
1036
|
-
get: (id, scope) => Effect17.sync(() => store.get(`${scope}\0${id}`) ?? null),
|
|
1037
|
-
set: (id, value, scope) => Effect17.sync(() => {
|
|
1038
|
-
store.set(`${scope}\0${id}`, value);
|
|
1039
|
-
}),
|
|
1040
|
-
delete: (id, scope) => Effect17.sync(() => store.delete(`${scope}\0${id}`)),
|
|
1041
|
-
list: () => Effect17.sync(
|
|
1042
|
-
() => Array.from(store.keys()).map((key) => {
|
|
1043
|
-
const name = key.split("\0", 2)[1] ?? key;
|
|
1044
|
-
return { id: name, name };
|
|
1045
|
-
})
|
|
1046
|
-
)
|
|
1047
|
-
};
|
|
1048
|
-
return {
|
|
1049
|
-
id: "memory-secrets",
|
|
1050
|
-
storage: () => ({}),
|
|
1051
|
-
secretProviders: [provider]
|
|
1052
|
-
};
|
|
1053
|
-
});
|
|
1054
|
-
|
|
1055
|
-
// ../sdk/src/api-errors.ts
|
|
1056
|
-
import { Schema as Schema18 } from "effect";
|
|
1057
|
-
var InternalError = class extends Schema18.TaggedErrorClass()(
|
|
1058
|
-
"InternalError",
|
|
1059
|
-
{
|
|
1060
|
-
/** Opaque correlation id for backend lookup (Sentry event id, log line, etc.). */
|
|
1061
|
-
traceId: Schema18.String
|
|
1062
|
-
},
|
|
1063
|
-
{ httpApiStatus: 500 }
|
|
1064
|
-
) {
|
|
1065
|
-
};
|
|
11
|
+
import { collectTables } from "@executor-js/sdk/core";
|
|
1066
12
|
|
|
1067
13
|
// src/utils/get-config.ts
|
|
1068
14
|
import { existsSync } from "fs";
|
|
@@ -1102,323 +48,10 @@ var getConfig = async (opts) => {
|
|
|
1102
48
|
return config;
|
|
1103
49
|
};
|
|
1104
50
|
|
|
1105
|
-
// src/
|
|
1106
|
-
|
|
1107
|
-
var getModelName = (key, def) => def.modelName ?? key;
|
|
1108
|
-
var getType = (name, field, dialect) => {
|
|
1109
|
-
if (field.references?.field === "id") {
|
|
1110
|
-
return `text('${name}')`;
|
|
1111
|
-
}
|
|
1112
|
-
const type = field.type;
|
|
1113
|
-
if (typeof type !== "string") {
|
|
1114
|
-
if (Array.isArray(type) && type.every((x) => typeof x === "string")) {
|
|
1115
|
-
return {
|
|
1116
|
-
sqlite: `text({ enum: [${type.map((x) => `'${x}'`).join(", ")}] })`,
|
|
1117
|
-
pg: `text('${name}', { enum: [${type.map((x) => `'${x}'`).join(", ")}] })`,
|
|
1118
|
-
mysql: `mysqlEnum([${type.map((x) => `'${x}'`).join(", ")}])`
|
|
1119
|
-
}[dialect];
|
|
1120
|
-
}
|
|
1121
|
-
throw new TypeError(`Invalid field type for field ${name}`);
|
|
1122
|
-
}
|
|
1123
|
-
const typeMap = {
|
|
1124
|
-
string: {
|
|
1125
|
-
sqlite: `text('${name}')`,
|
|
1126
|
-
pg: `text('${name}')`,
|
|
1127
|
-
mysql: field.unique ? `varchar('${name}', { length: 255 })` : field.references ? `varchar('${name}', { length: 36 })` : field.sortable ? `varchar('${name}', { length: 255 })` : field.index ? `varchar('${name}', { length: 255 })` : `text('${name}')`
|
|
1128
|
-
},
|
|
1129
|
-
boolean: {
|
|
1130
|
-
sqlite: `integer('${name}', { mode: 'boolean' })`,
|
|
1131
|
-
pg: `boolean('${name}')`,
|
|
1132
|
-
mysql: `boolean('${name}')`
|
|
1133
|
-
},
|
|
1134
|
-
number: {
|
|
1135
|
-
sqlite: `integer('${name}')`,
|
|
1136
|
-
pg: field.bigint ? `bigint('${name}', { mode: 'number' })` : `integer('${name}')`,
|
|
1137
|
-
mysql: field.bigint ? `bigint('${name}', { mode: 'number' })` : `int('${name}')`
|
|
1138
|
-
},
|
|
1139
|
-
date: {
|
|
1140
|
-
sqlite: `integer('${name}', { mode: 'timestamp_ms' })`,
|
|
1141
|
-
pg: `timestamp('${name}')`,
|
|
1142
|
-
mysql: `timestamp('${name}', { fsp: 3 })`
|
|
1143
|
-
},
|
|
1144
|
-
"number[]": {
|
|
1145
|
-
sqlite: `text('${name}', { mode: "json" })`,
|
|
1146
|
-
pg: field.bigint ? `bigint('${name}', { mode: 'number' }).array()` : `integer('${name}').array()`,
|
|
1147
|
-
mysql: `text('${name}', { mode: 'json' })`
|
|
1148
|
-
},
|
|
1149
|
-
"string[]": {
|
|
1150
|
-
sqlite: `text('${name}', { mode: "json" })`,
|
|
1151
|
-
pg: `text('${name}').array()`,
|
|
1152
|
-
mysql: `text('${name}', { mode: "json" })`
|
|
1153
|
-
},
|
|
1154
|
-
json: {
|
|
1155
|
-
sqlite: `text('${name}', { mode: "json" })`,
|
|
1156
|
-
pg: `jsonb('${name}')`,
|
|
1157
|
-
mysql: `json('${name}', { mode: "json" })`
|
|
1158
|
-
}
|
|
1159
|
-
};
|
|
1160
|
-
const dbTypeMap = typeMap[type];
|
|
1161
|
-
if (!dbTypeMap) {
|
|
1162
|
-
throw new Error(`Unsupported field type '${field.type}' for field '${name}'.`);
|
|
1163
|
-
}
|
|
1164
|
-
return dbTypeMap[dialect];
|
|
1165
|
-
};
|
|
1166
|
-
var generateDrizzleSchema = async ({ schema, dialect, file }) => {
|
|
1167
|
-
const filePath = file || "./executor-schema.ts";
|
|
1168
|
-
const fileExist = existsSync2(filePath);
|
|
1169
|
-
let code = generateImport({ dialect, schema });
|
|
1170
|
-
for (const [tableKey, tableDef] of Object.entries(schema)) {
|
|
1171
|
-
const modelName = getModelName(tableKey, tableDef);
|
|
1172
|
-
const fields = tableDef.fields;
|
|
1173
|
-
const hasScopeId = Object.prototype.hasOwnProperty.call(fields, "scope_id");
|
|
1174
|
-
const id = hasScopeId ? `text('id').notNull()` : `text('id').primaryKey()`;
|
|
1175
|
-
const extras = [];
|
|
1176
|
-
const assignExtras = (items) => {
|
|
1177
|
-
if (!items.length) return "";
|
|
1178
|
-
const lines = [`, (table) => [`];
|
|
1179
|
-
for (const item of items) {
|
|
1180
|
-
if (item.kind === "primaryKey") {
|
|
1181
|
-
const cols = item.columns.map((c) => `table.${c}`).join(", ");
|
|
1182
|
-
lines.push(` primaryKey({ columns: [${cols}] }),`);
|
|
1183
|
-
} else {
|
|
1184
|
-
const cols = Array.isArray(item.on) ? item.on.map((c) => `table.${c}`).join(", ") : `table.${item.on}`;
|
|
1185
|
-
lines.push(` ${item.kind}("${item.name}").on(${cols}),`);
|
|
1186
|
-
}
|
|
1187
|
-
}
|
|
1188
|
-
lines.push(`]`);
|
|
1189
|
-
return lines.join("\n");
|
|
1190
|
-
};
|
|
1191
|
-
if (hasScopeId) {
|
|
1192
|
-
extras.push({ kind: "primaryKey", columns: ["scope_id", "id"] });
|
|
1193
|
-
}
|
|
1194
|
-
const fieldLines = Object.entries(fields).filter(([fieldName]) => fieldName !== "id").map(([fieldName, attr]) => {
|
|
1195
|
-
const physical = attr.fieldName ?? fieldName;
|
|
1196
|
-
const isToolPolicyCompositeField = tableKey === "tool_policy" && (physical === "scope_id" || physical === "position");
|
|
1197
|
-
if (attr.index && !attr.unique && !isToolPolicyCompositeField) {
|
|
1198
|
-
extras.push({
|
|
1199
|
-
kind: "index",
|
|
1200
|
-
name: `${tableKey}_${physical}_idx`,
|
|
1201
|
-
on: physical
|
|
1202
|
-
});
|
|
1203
|
-
} else if (attr.index && attr.unique) {
|
|
1204
|
-
extras.push({
|
|
1205
|
-
kind: "uniqueIndex",
|
|
1206
|
-
name: `${tableKey}_${physical}_uidx`,
|
|
1207
|
-
on: physical
|
|
1208
|
-
});
|
|
1209
|
-
}
|
|
1210
|
-
let col = getType(physical, attr, dialect);
|
|
1211
|
-
if (attr.defaultValue !== null && typeof attr.defaultValue !== "undefined") {
|
|
1212
|
-
if (typeof attr.defaultValue === "function") {
|
|
1213
|
-
if (attr.type === "date" && attr.defaultValue.toString().includes("new Date()")) {
|
|
1214
|
-
if (dialect === "sqlite") {
|
|
1215
|
-
col += `.default(sql\`(cast(unixepoch('subsecond') * 1000 as integer))\`)`;
|
|
1216
|
-
} else {
|
|
1217
|
-
col += `.defaultNow()`;
|
|
1218
|
-
}
|
|
1219
|
-
}
|
|
1220
|
-
} else if (typeof attr.defaultValue === "string") {
|
|
1221
|
-
col += `.default("${attr.defaultValue}")`;
|
|
1222
|
-
} else {
|
|
1223
|
-
col += `.default(${attr.defaultValue})`;
|
|
1224
|
-
}
|
|
1225
|
-
}
|
|
1226
|
-
if (attr.onUpdate && attr.type === "date") {
|
|
1227
|
-
if (typeof attr.onUpdate === "function") {
|
|
1228
|
-
col += `.$onUpdate(${attr.onUpdate})`;
|
|
1229
|
-
}
|
|
1230
|
-
}
|
|
1231
|
-
return `${physical}: ${col}${attr.required !== false ? ".notNull()" : ""}${attr.unique ? ".unique()" : ""}${attr.references ? `.references(()=> ${attr.references.model}.${attr.references.field ?? "id"}, { onDelete: '${attr.references.onDelete || "cascade"}' })` : ""}`;
|
|
1232
|
-
}).join(",\n ");
|
|
1233
|
-
if (tableKey === "tool_policy") {
|
|
1234
|
-
extras.push({
|
|
1235
|
-
kind: "index",
|
|
1236
|
-
name: "tool_policy_scope_id_position_idx",
|
|
1237
|
-
on: ["scope_id", "position"]
|
|
1238
|
-
});
|
|
1239
|
-
}
|
|
1240
|
-
const tableSchema = `export const ${tableKey} = ${dialect}Table("${modelName}", {
|
|
1241
|
-
id: ${id},
|
|
1242
|
-
${fieldLines}
|
|
1243
|
-
}${assignExtras(extras)});`;
|
|
1244
|
-
code += `
|
|
1245
|
-
${tableSchema}
|
|
1246
|
-
`;
|
|
1247
|
-
}
|
|
1248
|
-
let relationsString = "";
|
|
1249
|
-
for (const [tableKey, tableDef] of Object.entries(schema)) {
|
|
1250
|
-
const modelName = tableKey;
|
|
1251
|
-
const oneRelations = [];
|
|
1252
|
-
const manyRelations = [];
|
|
1253
|
-
const manyRelationsSet = /* @__PURE__ */ new Set();
|
|
1254
|
-
for (const [fieldName, field] of Object.entries(tableDef.fields)) {
|
|
1255
|
-
if (!field.references) continue;
|
|
1256
|
-
const referencedModel = field.references.model;
|
|
1257
|
-
const physical = field.fieldName ?? fieldName;
|
|
1258
|
-
const fieldRef = `${tableKey}.${physical}`;
|
|
1259
|
-
const referenceRef = `${referencedModel}.${field.references.field || "id"}`;
|
|
1260
|
-
oneRelations.push({
|
|
1261
|
-
key: referencedModel,
|
|
1262
|
-
model: referencedModel,
|
|
1263
|
-
type: "one",
|
|
1264
|
-
reference: {
|
|
1265
|
-
field: fieldRef,
|
|
1266
|
-
references: referenceRef,
|
|
1267
|
-
fieldName
|
|
1268
|
-
}
|
|
1269
|
-
});
|
|
1270
|
-
}
|
|
1271
|
-
for (const [otherKey, otherDef] of Object.entries(schema)) {
|
|
1272
|
-
if (otherKey === tableKey) continue;
|
|
1273
|
-
const hasFK = Object.values(otherDef.fields).some(
|
|
1274
|
-
(field) => field.references?.model === tableKey
|
|
1275
|
-
);
|
|
1276
|
-
if (!hasFK) continue;
|
|
1277
|
-
const relationKey = `${otherKey}s`;
|
|
1278
|
-
if (!manyRelationsSet.has(relationKey)) {
|
|
1279
|
-
manyRelationsSet.add(relationKey);
|
|
1280
|
-
manyRelations.push({
|
|
1281
|
-
key: relationKey,
|
|
1282
|
-
model: otherKey,
|
|
1283
|
-
type: "many"
|
|
1284
|
-
});
|
|
1285
|
-
}
|
|
1286
|
-
}
|
|
1287
|
-
const relationsByModel = /* @__PURE__ */ new Map();
|
|
1288
|
-
for (const rel of oneRelations) {
|
|
1289
|
-
if (!rel.reference) continue;
|
|
1290
|
-
const arr = relationsByModel.get(rel.key) ?? [];
|
|
1291
|
-
arr.push(rel);
|
|
1292
|
-
relationsByModel.set(rel.key, arr);
|
|
1293
|
-
}
|
|
1294
|
-
const duplicateRelations = [];
|
|
1295
|
-
const singleRelations = [];
|
|
1296
|
-
for (const [, rels] of relationsByModel.entries()) {
|
|
1297
|
-
if (rels.length > 1) {
|
|
1298
|
-
duplicateRelations.push(...rels);
|
|
1299
|
-
} else {
|
|
1300
|
-
singleRelations.push(rels[0]);
|
|
1301
|
-
}
|
|
1302
|
-
}
|
|
1303
|
-
for (const rel of duplicateRelations) {
|
|
1304
|
-
if (!rel.reference) continue;
|
|
1305
|
-
const relExportName = `${modelName}${rel.reference.fieldName.charAt(0).toUpperCase() + rel.reference.fieldName.slice(1)}Relations`;
|
|
1306
|
-
const block = `export const ${relExportName} = relations(${modelName}, ({ one }) => ({
|
|
1307
|
-
${rel.key}: one(${rel.model}, {
|
|
1308
|
-
fields: [${rel.reference.field}],
|
|
1309
|
-
references: [${rel.reference.references}],
|
|
1310
|
-
})
|
|
1311
|
-
}))`;
|
|
1312
|
-
relationsString += `
|
|
1313
|
-
${block}
|
|
1314
|
-
`;
|
|
1315
|
-
}
|
|
1316
|
-
const hasOne = singleRelations.length > 0;
|
|
1317
|
-
const hasMany = manyRelations.length > 0;
|
|
1318
|
-
if (hasOne || hasMany) {
|
|
1319
|
-
const destructured = [hasOne ? "one" : "", hasMany ? "many" : ""].filter(Boolean).join(", ");
|
|
1320
|
-
const body = [
|
|
1321
|
-
...singleRelations.filter((r) => r.reference).map(
|
|
1322
|
-
(r) => ` ${r.key}: one(${r.model}, {
|
|
1323
|
-
fields: [${r.reference.field}],
|
|
1324
|
-
references: [${r.reference.references}],
|
|
1325
|
-
})`
|
|
1326
|
-
),
|
|
1327
|
-
...manyRelations.map(({ key, model }) => ` ${key}: many(${model})`)
|
|
1328
|
-
].join(",\n");
|
|
1329
|
-
const block = `export const ${modelName}Relations = relations(${modelName}, ({ ${destructured} }) => ({
|
|
1330
|
-
${body}
|
|
1331
|
-
}))`;
|
|
1332
|
-
relationsString += `
|
|
1333
|
-
${block}
|
|
1334
|
-
`;
|
|
1335
|
-
}
|
|
1336
|
-
}
|
|
1337
|
-
code += `
|
|
1338
|
-
${relationsString}`;
|
|
1339
|
-
return {
|
|
1340
|
-
code,
|
|
1341
|
-
fileName: filePath,
|
|
1342
|
-
overwrite: fileExist
|
|
1343
|
-
};
|
|
1344
|
-
};
|
|
1345
|
-
function generateImport({ dialect, schema }) {
|
|
1346
|
-
const rootImports = [];
|
|
1347
|
-
const coreImports = [];
|
|
1348
|
-
let hasBigint = false;
|
|
1349
|
-
let hasJson = false;
|
|
1350
|
-
let hasBoolean = false;
|
|
1351
|
-
let hasNumber = false;
|
|
1352
|
-
let hasDate = false;
|
|
1353
|
-
let hasIndex = false;
|
|
1354
|
-
let hasUniqueIndex = false;
|
|
1355
|
-
let hasReferences = false;
|
|
1356
|
-
let hasCompositePrimaryKey = false;
|
|
1357
|
-
for (const [tableKey, table] of Object.entries(schema)) {
|
|
1358
|
-
for (const field of Object.values(table.fields)) {
|
|
1359
|
-
if (field.bigint) hasBigint = true;
|
|
1360
|
-
if (field.type === "json") hasJson = true;
|
|
1361
|
-
if (field.type === "boolean") hasBoolean = true;
|
|
1362
|
-
if (field.type === "number" && !field.bigint || field.type === "number[]") {
|
|
1363
|
-
hasNumber = true;
|
|
1364
|
-
}
|
|
1365
|
-
if (field.type === "date") hasDate = true;
|
|
1366
|
-
if (field.index && !field.unique) hasIndex = true;
|
|
1367
|
-
if (field.index && field.unique) hasUniqueIndex = true;
|
|
1368
|
-
if (field.references) hasReferences = true;
|
|
1369
|
-
}
|
|
1370
|
-
if (Object.prototype.hasOwnProperty.call(table.fields, "scope_id")) {
|
|
1371
|
-
hasCompositePrimaryKey = true;
|
|
1372
|
-
}
|
|
1373
|
-
void tableKey;
|
|
1374
|
-
}
|
|
1375
|
-
coreImports.push(`${dialect}Table`);
|
|
1376
|
-
coreImports.push("text");
|
|
1377
|
-
if (hasBoolean && dialect !== "sqlite") coreImports.push("boolean");
|
|
1378
|
-
if (hasDate) {
|
|
1379
|
-
if (dialect === "pg") coreImports.push("timestamp");
|
|
1380
|
-
}
|
|
1381
|
-
if (hasNumber || dialect === "sqlite") {
|
|
1382
|
-
if (dialect === "pg") coreImports.push("integer");
|
|
1383
|
-
else if (dialect === "mysql") coreImports.push("int");
|
|
1384
|
-
else coreImports.push("integer");
|
|
1385
|
-
}
|
|
1386
|
-
if (hasBigint && dialect !== "sqlite") coreImports.push("bigint");
|
|
1387
|
-
if (hasJson) {
|
|
1388
|
-
if (dialect === "pg") coreImports.push("jsonb");
|
|
1389
|
-
else if (dialect === "mysql") coreImports.push("json");
|
|
1390
|
-
}
|
|
1391
|
-
if (hasIndex) coreImports.push("index");
|
|
1392
|
-
if (hasUniqueIndex) coreImports.push("uniqueIndex");
|
|
1393
|
-
if (hasCompositePrimaryKey) coreImports.push("primaryKey");
|
|
1394
|
-
if (dialect === "sqlite" && (hasBoolean || hasDate)) {
|
|
1395
|
-
if (!coreImports.includes("integer")) coreImports.push("integer");
|
|
1396
|
-
}
|
|
1397
|
-
if (dialect === "sqlite" && hasNumber) {
|
|
1398
|
-
}
|
|
1399
|
-
const hasSqliteTimestamp = dialect === "sqlite" && Object.values(schema).some(
|
|
1400
|
-
(table) => Object.values(table.fields).some(
|
|
1401
|
-
(field) => field.type === "date" && field.defaultValue && typeof field.defaultValue === "function" && field.defaultValue.toString().includes("new Date()")
|
|
1402
|
-
)
|
|
1403
|
-
);
|
|
1404
|
-
if (hasSqliteTimestamp) {
|
|
1405
|
-
rootImports.push("sql");
|
|
1406
|
-
}
|
|
1407
|
-
if (hasReferences || dialect === "mysql") {
|
|
1408
|
-
}
|
|
1409
|
-
if (hasReferences) rootImports.push("relations");
|
|
1410
|
-
const filteredCore = coreImports.map((x) => x.trim()).filter((x) => x !== "");
|
|
1411
|
-
const uniqueCore = [...new Set(filteredCore)];
|
|
1412
|
-
const uniqueRoot = [...new Set(rootImports)];
|
|
1413
|
-
return `${uniqueRoot.length > 0 ? `import { ${uniqueRoot.join(", ")} } from "drizzle-orm";
|
|
1414
|
-
` : ""}import { ${uniqueCore.join(", ")} } from "drizzle-orm/${dialect}-core";
|
|
1415
|
-
`;
|
|
1416
|
-
}
|
|
1417
|
-
|
|
1418
|
-
// src/commands/generate.ts
|
|
1419
|
-
async function generateAction(opts) {
|
|
51
|
+
// src/commands/schema.ts
|
|
52
|
+
var schemaGenerateAction = async (opts) => {
|
|
1420
53
|
const cwd = path2.resolve(opts.cwd);
|
|
1421
|
-
if (!
|
|
54
|
+
if (!existsSync2(cwd)) {
|
|
1422
55
|
console.error(`The directory "${cwd}" does not exist.`);
|
|
1423
56
|
process.exit(1);
|
|
1424
57
|
}
|
|
@@ -1429,29 +62,48 @@ async function generateAction(opts) {
|
|
|
1429
62
|
);
|
|
1430
63
|
process.exit(1);
|
|
1431
64
|
}
|
|
1432
|
-
|
|
1433
|
-
|
|
1434
|
-
|
|
1435
|
-
dialect: config.dialect,
|
|
1436
|
-
file: opts.output
|
|
1437
|
-
});
|
|
1438
|
-
if (!result.code) {
|
|
1439
|
-
console.log("Schema is already up to date.");
|
|
1440
|
-
process.exit(0);
|
|
65
|
+
if (opts.adapter !== "drizzle") {
|
|
66
|
+
console.error(`Unsupported schema adapter "${opts.adapter}". Supported adapters: drizzle.`);
|
|
67
|
+
process.exit(1);
|
|
1441
68
|
}
|
|
1442
|
-
|
|
1443
|
-
|
|
1444
|
-
|
|
1445
|
-
|
|
69
|
+
if (opts.provider !== "mysql" && opts.provider !== "postgresql" && opts.provider !== "sqlite") {
|
|
70
|
+
console.error(
|
|
71
|
+
`Unsupported drizzle provider "${opts.provider}". Supported providers: mysql, postgresql, sqlite.`
|
|
72
|
+
);
|
|
73
|
+
process.exit(1);
|
|
1446
74
|
}
|
|
1447
|
-
await
|
|
75
|
+
const [{ fumadb }, { drizzleAdapter }, { schema: fumaSchema }] = await Promise.all([
|
|
76
|
+
import("fumadb"),
|
|
77
|
+
import("fumadb/adapters/drizzle"),
|
|
78
|
+
import("fumadb/schema")
|
|
79
|
+
]);
|
|
80
|
+
const schema2 = fumaSchema({
|
|
81
|
+
version: opts.version,
|
|
82
|
+
tables: collectTables(config.plugins())
|
|
83
|
+
});
|
|
84
|
+
const factory = fumadb({
|
|
85
|
+
namespace: opts.namespace,
|
|
86
|
+
schemas: [schema2]
|
|
87
|
+
});
|
|
88
|
+
const generated = factory.client(
|
|
89
|
+
drizzleAdapter({
|
|
90
|
+
db: {},
|
|
91
|
+
provider: opts.provider
|
|
92
|
+
})
|
|
93
|
+
).generateSchema("latest", opts.namespace);
|
|
94
|
+
const output = opts.output ?? generated.path;
|
|
95
|
+
const outPath = path2.resolve(cwd, output);
|
|
96
|
+
await fs.mkdir(path2.dirname(outPath), { recursive: true });
|
|
97
|
+
await fs.writeFile(outPath, generated.code);
|
|
1448
98
|
console.log(`Schema generated: ${path2.relative(cwd, outPath)}`);
|
|
1449
|
-
}
|
|
1450
|
-
var
|
|
99
|
+
};
|
|
100
|
+
var schema = new Command("schema").description("Database schema utilities").addCommand(
|
|
101
|
+
new Command("generate").description("Generate an ORM schema file from the executor config").option("-c, --cwd <cwd>", "the working directory", process.cwd()).option("--config <config>", "path to the executor config file").option("--output <output>", "output file path for the generated schema").option("--namespace <namespace>", "FumaDB namespace", "executor").option("--adapter <adapter>", "FumaDB adapter", "drizzle").option("--provider <provider>", "database provider", "postgresql").option("--version <version>", "FumaDB schema version", "1.0.0").action(schemaGenerateAction)
|
|
102
|
+
);
|
|
1451
103
|
|
|
1452
104
|
// src/index.ts
|
|
1453
105
|
process.on("SIGINT", () => process.exit(0));
|
|
1454
106
|
process.on("SIGTERM", () => process.exit(0));
|
|
1455
|
-
var program = new Command2("executor").version("0.0.1").description("Executor CLI").addCommand(
|
|
1456
|
-
program.
|
|
107
|
+
var program = new Command2("executor-sdk").version("0.0.1").description("Executor SDK CLI").addCommand(schema).action(() => program.help());
|
|
108
|
+
await program.parseAsync();
|
|
1457
109
|
//# sourceMappingURL=index.js.map
|