@lunora/codegen 1.0.0-alpha.19 → 1.0.0-alpha.20
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/index.d.mts +37 -0
- package/dist/index.d.ts +37 -0
- package/dist/index.mjs +7 -7
- package/dist/packem_shared/{GENERATED_HEADER-D-AbhmRh.mjs → GENERATED_HEADER-CI272wRm.mjs} +116 -5
- package/dist/packem_shared/{OPENRPC_VERSION-DDT4mIzD.mjs → OPENRPC_VERSION-t5pV2NIN.mjs} +1 -1
- package/dist/packem_shared/{SCHEMA_SNAPSHOT_FILENAME-BZH-O4uh.mjs → SCHEMA_SNAPSHOT_FILENAME-BMez-jgr.mjs} +6 -6
- package/dist/packem_shared/{buildOpenApiDocument-DoK7_x1g.mjs → buildOpenApiDocument-Dx5QftUn.mjs} +1 -1
- package/dist/packem_shared/{discoverSchema-BnWHHJ4T.mjs → discoverSchema-KYq55qu3.mjs} +42 -0
- package/dist/packem_shared/{emitApp-CV81L74c.mjs → emitApp-cOSypPuO.mjs} +1 -1
- package/dist/packem_shared/{formatAdvisories-LM8-Ixjw.mjs → formatAdvisories-DdjK7sgh.mjs} +6 -0
- package/package.json +2 -2
package/dist/index.d.mts
CHANGED
|
@@ -109,6 +109,36 @@ interface RelationIR {
|
|
|
109
109
|
/** Target table name. */
|
|
110
110
|
table: string;
|
|
111
111
|
}
|
|
112
|
+
/**
|
|
113
|
+
* Statically-discovered `.source(...)` config (plan 077). Only the bits the
|
|
114
|
+
* advisor lints + DO wiring need are captured; `map`/`tenantBy` are functions and
|
|
115
|
+
* cannot be serialized, so their presence is recorded as `hasTenantBy` rather than
|
|
116
|
+
* the function itself.
|
|
117
|
+
*/
|
|
118
|
+
interface ExternalSourceIR {
|
|
119
|
+
/** The wrangler Hyperdrive binding name. */
|
|
120
|
+
binding: string;
|
|
121
|
+
/** Whether a `columns` projection allow-list was given. */
|
|
122
|
+
columns?: ReadonlyArray<string>;
|
|
123
|
+
/** `true` when a `reconcileEveryMs` was given (the incremental-mode delete-visibility companion). */
|
|
124
|
+
hasReconcile?: boolean;
|
|
125
|
+
/** `true` when a `tenantBy` mapper was given — the tenant-isolation boundary the `external_source_unscoped` lint checks. */
|
|
126
|
+
hasTenantBy: boolean;
|
|
127
|
+
/** The `idColumn` literal, when given (defaults to `"id"` at runtime). */
|
|
128
|
+
idColumn?: string;
|
|
129
|
+
/** Delete-detection mode literal, when given (`"full-pull"` | `"incremental"`). */
|
|
130
|
+
mode?: string;
|
|
131
|
+
/** The membership query literal, when statically knowable. */
|
|
132
|
+
query?: string;
|
|
133
|
+
/**
|
|
134
|
+
* `true` when `.source(...)` was present but its argument was **not** a static
|
|
135
|
+
* object literal (e.g. `.source(buildConfig())`), so none of the fields above
|
|
136
|
+
* could be read. The source still exists — this flag lets `hasSourcedTables`
|
|
137
|
+
* (codegen) and the `external_source_*` lints treat it as a source that can't be
|
|
138
|
+
* verified, instead of mistaking it for no `.source()` at all.
|
|
139
|
+
*/
|
|
140
|
+
unanalyzable?: boolean;
|
|
141
|
+
}
|
|
112
142
|
interface TableIR {
|
|
113
143
|
/**
|
|
114
144
|
* `true` when the table chain carried `.externallyManaged()` — its rows are
|
|
@@ -118,6 +148,13 @@ interface TableIR {
|
|
|
118
148
|
*/
|
|
119
149
|
externallyManaged?: boolean;
|
|
120
150
|
/**
|
|
151
|
+
* Set when the chain carried `.source(...)` — the table is materialized from an
|
|
152
|
+
* external Hyperdrive-backed database by a system poll loop (plan 077). Carries
|
|
153
|
+
* the statically-knowable bits the advisor lints read; the functions (`map`,
|
|
154
|
+
* `tenantBy`) are not serialized, only their presence (`hasTenantBy`).
|
|
155
|
+
*/
|
|
156
|
+
externalSource?: ExternalSourceIR;
|
|
157
|
+
/**
|
|
121
158
|
* Storage backend for a `.global()` table: `"d1"` (default) or
|
|
122
159
|
* `"hyperdrive"` (a Postgres/MySQL database via Cloudflare Hyperdrive). Only
|
|
123
160
|
* meaningful when `shardMode === "global"`; absent for sharded/root tables.
|
package/dist/index.d.ts
CHANGED
|
@@ -109,6 +109,36 @@ interface RelationIR {
|
|
|
109
109
|
/** Target table name. */
|
|
110
110
|
table: string;
|
|
111
111
|
}
|
|
112
|
+
/**
|
|
113
|
+
* Statically-discovered `.source(...)` config (plan 077). Only the bits the
|
|
114
|
+
* advisor lints + DO wiring need are captured; `map`/`tenantBy` are functions and
|
|
115
|
+
* cannot be serialized, so their presence is recorded as `hasTenantBy` rather than
|
|
116
|
+
* the function itself.
|
|
117
|
+
*/
|
|
118
|
+
interface ExternalSourceIR {
|
|
119
|
+
/** The wrangler Hyperdrive binding name. */
|
|
120
|
+
binding: string;
|
|
121
|
+
/** Whether a `columns` projection allow-list was given. */
|
|
122
|
+
columns?: ReadonlyArray<string>;
|
|
123
|
+
/** `true` when a `reconcileEveryMs` was given (the incremental-mode delete-visibility companion). */
|
|
124
|
+
hasReconcile?: boolean;
|
|
125
|
+
/** `true` when a `tenantBy` mapper was given — the tenant-isolation boundary the `external_source_unscoped` lint checks. */
|
|
126
|
+
hasTenantBy: boolean;
|
|
127
|
+
/** The `idColumn` literal, when given (defaults to `"id"` at runtime). */
|
|
128
|
+
idColumn?: string;
|
|
129
|
+
/** Delete-detection mode literal, when given (`"full-pull"` | `"incremental"`). */
|
|
130
|
+
mode?: string;
|
|
131
|
+
/** The membership query literal, when statically knowable. */
|
|
132
|
+
query?: string;
|
|
133
|
+
/**
|
|
134
|
+
* `true` when `.source(...)` was present but its argument was **not** a static
|
|
135
|
+
* object literal (e.g. `.source(buildConfig())`), so none of the fields above
|
|
136
|
+
* could be read. The source still exists — this flag lets `hasSourcedTables`
|
|
137
|
+
* (codegen) and the `external_source_*` lints treat it as a source that can't be
|
|
138
|
+
* verified, instead of mistaking it for no `.source()` at all.
|
|
139
|
+
*/
|
|
140
|
+
unanalyzable?: boolean;
|
|
141
|
+
}
|
|
112
142
|
interface TableIR {
|
|
113
143
|
/**
|
|
114
144
|
* `true` when the table chain carried `.externallyManaged()` — its rows are
|
|
@@ -118,6 +148,13 @@ interface TableIR {
|
|
|
118
148
|
*/
|
|
119
149
|
externallyManaged?: boolean;
|
|
120
150
|
/**
|
|
151
|
+
* Set when the chain carried `.source(...)` — the table is materialized from an
|
|
152
|
+
* external Hyperdrive-backed database by a system poll loop (plan 077). Carries
|
|
153
|
+
* the statically-knowable bits the advisor lints read; the functions (`map`,
|
|
154
|
+
* `tenantBy`) are not serialized, only their presence (`hasTenantBy`).
|
|
155
|
+
*/
|
|
156
|
+
externalSource?: ExternalSourceIR;
|
|
157
|
+
/**
|
|
121
158
|
* Storage backend for a `.global()` table: `"d1"` (default) or
|
|
122
159
|
* `"hyperdrive"` (a Postgres/MySQL database via Cloudflare Hyperdrive). Only
|
|
123
160
|
* meaningful when `shardMode === "global"`; absent for sharded/root tables.
|
package/dist/index.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export { formatAdvisories, lintSchema } from './packem_shared/formatAdvisories-
|
|
1
|
+
export { formatAdvisories, lintSchema } from './packem_shared/formatAdvisories-DdjK7sgh.mjs';
|
|
2
2
|
export { CodegenDiagnosticError, diagnosticAt } from './packem_shared/CodegenDiagnosticError-DeblMkzO.mjs';
|
|
3
3
|
export { default as discoverAuthApiCalls } from './packem_shared/discoverAuthApiCalls-CoirYbg6.mjs';
|
|
4
4
|
export { CONTAINERS_FILENAME, discoverContainers } from './packem_shared/CONTAINERS_FILENAME-DlP6YM_Q.mjs';
|
|
@@ -15,15 +15,15 @@ export { default as discoverQueries } from './packem_shared/discoverQueries-B0wG
|
|
|
15
15
|
export { QUEUES_FILENAME, discoverQueues } from './packem_shared/QUEUES_FILENAME-B5_eWCRe.mjs';
|
|
16
16
|
export { default as discoverR2sqlCalls } from './packem_shared/discoverR2sqlCalls-BVNMd428.mjs';
|
|
17
17
|
export { discoverRlsMetadata, default as discoverRlsProcedures } from './packem_shared/discoverRlsMetadata-BS9GOGC5.mjs';
|
|
18
|
-
export { default as discoverSchema } from './packem_shared/discoverSchema-
|
|
18
|
+
export { default as discoverSchema } from './packem_shared/discoverSchema-KYq55qu3.mjs';
|
|
19
19
|
export { SHAPES_FILENAME, discoverShapes } from './packem_shared/SHAPES_FILENAME-ChV7MqgE.mjs';
|
|
20
20
|
export { default as discoverStorageRulesMetadata } from './packem_shared/discoverStorageRulesMetadata-Da8BKXcI.mjs';
|
|
21
21
|
export { WORKFLOWS_FILENAME, discoverWorkflows } from './packem_shared/WORKFLOWS_FILENAME-CCisG0Vy.mjs';
|
|
22
|
-
export { GENERATED_HEADER, emitApi, emitCollections, emitContainers, emitCrons, emitDataModel, emitDrizzleSchema, emitFunctions, emitServer, emitShard, emitVectors, emitWorkflows, emitWranglerCronTriggers } from './packem_shared/GENERATED_HEADER-
|
|
23
|
-
export { emitApp } from './packem_shared/emitApp-
|
|
24
|
-
export { buildOpenApiDocument, emitOpenApi, emitOpenApiModule } from './packem_shared/buildOpenApiDocument-
|
|
25
|
-
export { OPENRPC_VERSION, buildOpenRpcDocument, emitOpenRpc, emitOpenRpcModule } from './packem_shared/OPENRPC_VERSION-
|
|
26
|
-
export { SCHEMA_SNAPSHOT_FILENAME, createCodegenProject, refreshCodegenProject, runCodegen } from './packem_shared/SCHEMA_SNAPSHOT_FILENAME-
|
|
22
|
+
export { GENERATED_HEADER, emitApi, emitCollections, emitContainers, emitCrons, emitDataModel, emitDrizzleSchema, emitFunctions, emitServer, emitShard, emitVectors, emitWorkflows, emitWranglerCronTriggers } from './packem_shared/GENERATED_HEADER-CI272wRm.mjs';
|
|
23
|
+
export { emitApp } from './packem_shared/emitApp-cOSypPuO.mjs';
|
|
24
|
+
export { buildOpenApiDocument, emitOpenApi, emitOpenApiModule } from './packem_shared/buildOpenApiDocument-Dx5QftUn.mjs';
|
|
25
|
+
export { OPENRPC_VERSION, buildOpenRpcDocument, emitOpenRpc, emitOpenRpcModule } from './packem_shared/OPENRPC_VERSION-t5pV2NIN.mjs';
|
|
26
|
+
export { SCHEMA_SNAPSHOT_FILENAME, createCodegenProject, refreshCodegenProject, runCodegen } from './packem_shared/SCHEMA_SNAPSHOT_FILENAME-BMez-jgr.mjs';
|
|
27
27
|
export { SCHEMA_SNAPSHOT_VERSION, SchemaSnapshotParseError, buildSchemaSnapshot, diffSchemaSnapshots, evaluateSchemaDrift, parseSchemaSnapshot, serializeSchemaSnapshot } from './packem_shared/SCHEMA_SNAPSHOT_VERSION-wWGP2_5E.mjs';
|
|
28
28
|
export { schemaFromIr } from './packem_shared/schemaFromIr-DTYsLBaA.mjs';
|
|
29
29
|
export { LUNORA_ERROR_CODES, validatorIrToJsonSchema } from './packem_shared/LUNORA_ERROR_CODES-CySpQPD3.mjs';
|
|
@@ -2049,6 +2049,7 @@ const emitShard = ({
|
|
|
2049
2049
|
const hasGlobalTables = schema.tables.some((table) => table.shardMode === "global");
|
|
2050
2050
|
const hasHyperdriveGlobal = schema.tables.some((table) => table.shardMode === "global" && table.globalBackend === "hyperdrive");
|
|
2051
2051
|
const hasD1Global = schema.tables.some((table) => table.shardMode === "global" && table.globalBackend !== "hyperdrive");
|
|
2052
|
+
const hasSourcedTables = schema.tables.some((table) => table.externalSource !== void 0);
|
|
2052
2053
|
if (hasD1Global && hasHyperdriveGlobal) {
|
|
2053
2054
|
throw new Error(
|
|
2054
2055
|
'lunora codegen: mixing `.global()` (D1) and `.global({ backend: "hyperdrive" })` tables in one app is not supported yet — use a single global backend.'
|
|
@@ -2125,7 +2126,8 @@ const LUNORA_RLS_READ_REGISTRY = buildRlsReadRegistry(Object.values(LUNORA_FUNCT
|
|
|
2125
2126
|
const shapeGuardImport = hasShapes ? "assertShapeShardable, " : "";
|
|
2126
2127
|
const importLines = [
|
|
2127
2128
|
`import type { ${doTypeImports.join(", ")} } from "${base.do}";`,
|
|
2128
|
-
`import { applyCdcChanges, ${shapeGuardImport}createShardCtxDb, runDataMigration, runShardMigrations, ${relationFanout.importFragment}ShardDO as ShardDOBase } from "${base.do}";`,
|
|
2129
|
+
`import { applyCdcChanges, ${shapeGuardImport}createShardCtxDb, ${hasSourcedTables ? "isSourceDue, pullExternalSourceTick, " : ""}runDataMigration, runShardMigrations, ${relationFanout.importFragment}ShardDO as ShardDOBase } from "${base.do}";`,
|
|
2130
|
+
...hasSourcedTables ? [`import type { ExternalSourceLike, SourceClientLike } from "${base.do}";`] : [],
|
|
2129
2131
|
// `asBucketStorage` (the bucket-aware `ctx.storage` wrapper) and
|
|
2130
2132
|
// `createSecrets` (the `ctx.secrets` core built-in) live in
|
|
2131
2133
|
// `@lunora/server`, the single source — imported here rather than stamped
|
|
@@ -2172,6 +2174,8 @@ const LUNORA_RLS_READ_REGISTRY = buildRlsReadRegistry(Object.values(LUNORA_FUNCT
|
|
|
2172
2174
|
d1?: (env: Record<string, unknown>, request?: { identity?: Record<string, unknown>; userId?: string }) => DatabaseWriterLike | undefined;` : "";
|
|
2173
2175
|
const hyperdriveGlobalConfigField = hasHyperdriveGlobal ? `
|
|
2174
2176
|
hyperdriveGlobal?: (env: Record<string, unknown>, request?: { identity?: Record<string, unknown>; userId?: string }) => DatabaseWriterLike | undefined;` : "";
|
|
2177
|
+
const sourceClientConfigField = hasSourcedTables ? `
|
|
2178
|
+
sourceClient?: (env: Record<string, unknown>, binding: string) => { query: <Row = Record<string, unknown>>(text: string, params?: readonly unknown[]) => Promise<Row[]> } | undefined;` : "";
|
|
2175
2179
|
const globalDatabaseStub = hasGlobalTables ? `
|
|
2176
2180
|
const globalDbStub: DatabaseWriterLike = {
|
|
2177
2181
|
aggregate: async () => {
|
|
@@ -2320,6 +2324,113 @@ const vectorsStub: VectorSearchLike = {
|
|
|
2320
2324
|
|
|
2321
2325
|
return rows;
|
|
2322
2326
|
}
|
|
2327
|
+
` : "";
|
|
2328
|
+
const sourceClientCacheConst = hasSourcedTables ? `
|
|
2329
|
+
const sourceClientCache = new WeakMap<object, Map<string, SourceClientLike>>();
|
|
2330
|
+
const sourcePollAtCache = new WeakMap<object, Map<string, number>>();
|
|
2331
|
+
` : "";
|
|
2332
|
+
const externalSourceOverride = hasSourcedTables ? `
|
|
2333
|
+
protected override async pollExternalSources(): Promise<number> {
|
|
2334
|
+
const env = (this.env ?? {}) as Record<string, unknown>;
|
|
2335
|
+
const sourced = Object.entries((schema as unknown as SchemaLike).tables)
|
|
2336
|
+
.map(([table, definition]) => [table, (definition as { externalSource?: ExternalSourceLike }).externalSource] as const)
|
|
2337
|
+
.filter((entry): entry is [string, ExternalSourceLike] => entry[1] !== undefined);
|
|
2338
|
+
|
|
2339
|
+
if (sourced.length === 0) {
|
|
2340
|
+
return 0;
|
|
2341
|
+
}
|
|
2342
|
+
|
|
2343
|
+
const shardKey = this.currentShardKey();
|
|
2344
|
+
const scheduler = (config.scheduler?.(env) ?? schedulerStub) as SchedulerLike;
|
|
2345
|
+
const writer = createShardCtxDb({
|
|
2346
|
+
broadcast: (delta) => {
|
|
2347
|
+
this.recordChangedTable(delta.table);
|
|
2348
|
+
},
|
|
2349
|
+
cdc: config.cdc ?? false,
|
|
2350
|
+
scheduler,
|
|
2351
|
+
schema: schema as unknown as SchemaLike,
|
|
2352
|
+
sql: this.sql as SqlExec,
|
|
2353
|
+
});
|
|
2354
|
+
|
|
2355
|
+
let clients = sourceClientCache.get(this);
|
|
2356
|
+
|
|
2357
|
+
if (clients === undefined) {
|
|
2358
|
+
clients = new Map();
|
|
2359
|
+
sourceClientCache.set(this, clients);
|
|
2360
|
+
}
|
|
2361
|
+
|
|
2362
|
+
let polledAt = sourcePollAtCache.get(this);
|
|
2363
|
+
|
|
2364
|
+
if (polledAt === undefined) {
|
|
2365
|
+
polledAt = new Map();
|
|
2366
|
+
sourcePollAtCache.set(this, polledAt);
|
|
2367
|
+
}
|
|
2368
|
+
|
|
2369
|
+
const now = Date.now();
|
|
2370
|
+
// \`active\` counts non-manual sources: while > 0 the alarm re-arms; a
|
|
2371
|
+
// manual-only schema returns 0 so the shared alarm goes idle.
|
|
2372
|
+
let active = 0;
|
|
2373
|
+
|
|
2374
|
+
for (const [table, source] of sourced) {
|
|
2375
|
+
if (source.refresh === "manual") {
|
|
2376
|
+
continue;
|
|
2377
|
+
}
|
|
2378
|
+
|
|
2379
|
+
active += 1;
|
|
2380
|
+
|
|
2381
|
+
if (!isSourceDue(source.refresh, polledAt.get(table), now)) {
|
|
2382
|
+
continue;
|
|
2383
|
+
}
|
|
2384
|
+
|
|
2385
|
+
try {
|
|
2386
|
+
let client = clients.get(source.binding);
|
|
2387
|
+
|
|
2388
|
+
if (client === undefined) {
|
|
2389
|
+
client = config.sourceClient?.(env, source.binding);
|
|
2390
|
+
|
|
2391
|
+
if (client !== undefined) {
|
|
2392
|
+
clients.set(source.binding, client);
|
|
2393
|
+
}
|
|
2394
|
+
}
|
|
2395
|
+
|
|
2396
|
+
if (client === undefined) {
|
|
2397
|
+
// No SqlClient resolved for this binding (host never wired
|
|
2398
|
+
// \`config.sourceClient\`, or wired it wrong). Surface it in the
|
|
2399
|
+
// Logs panel and stamp \`polledAt\` so a persistent misconfig backs
|
|
2400
|
+
// off to \`refresh.everyMs\` instead of retrying every alarm tick.
|
|
2401
|
+
this.recordExternalSourceError(table, new Error(\`external-source: no sourceClient resolved for binding "\${source.binding}"\`));
|
|
2402
|
+
polledAt.set(table, now);
|
|
2403
|
+
continue;
|
|
2404
|
+
}
|
|
2405
|
+
|
|
2406
|
+
// eslint-disable-next-line no-await-in-loop -- one sourced table at a time; slices are independent but small and sequential keeps the writer transaction simple
|
|
2407
|
+
await pullExternalSourceTick(this.sql as SqlExec, writer, client, table, source, shardKey);
|
|
2408
|
+
polledAt.set(table, now);
|
|
2409
|
+
} catch (error) {
|
|
2410
|
+
this.recordExternalSourceError(table, error);
|
|
2411
|
+
// Stamp on failure too, so a persistently failing source throttles
|
|
2412
|
+
// to \`refresh.everyMs\` rather than being hammered every tick.
|
|
2413
|
+
polledAt.set(table, now);
|
|
2414
|
+
}
|
|
2415
|
+
}
|
|
2416
|
+
|
|
2417
|
+
return active;
|
|
2418
|
+
}
|
|
2419
|
+
` : "";
|
|
2420
|
+
const sourceConstructorOverride = hasSourcedTables ? `
|
|
2421
|
+
public constructor(state: ShardDOState, env: unknown) {
|
|
2422
|
+
super(state, env);
|
|
2423
|
+
|
|
2424
|
+
const autoSourced = Object.values((schema as unknown as SchemaLike).tables).some((definition) => {
|
|
2425
|
+
const source = (definition as { externalSource?: ExternalSourceLike }).externalSource;
|
|
2426
|
+
|
|
2427
|
+
return source !== undefined && source.refresh !== "manual";
|
|
2428
|
+
});
|
|
2429
|
+
|
|
2430
|
+
if (autoSourced) {
|
|
2431
|
+
void this.scheduleSourcePoll();
|
|
2432
|
+
}
|
|
2433
|
+
}
|
|
2323
2434
|
` : "";
|
|
2324
2435
|
const facadeBlock = hasTables ? `
|
|
2325
2436
|
const facade = db as unknown as Record<string, ReturnType<typeof bindTableFacade>>;
|
|
@@ -2396,7 +2507,7 @@ export interface ShardDOConfig {
|
|
|
2396
2507
|
/** Optional telemetry sink. When supplied, each \`ctx.log.*\` call is forwarded to \`sink.onLog\`. Pass the SAME sink you give \`createWorker({ observability })\` (which drives \`onRpc\`) to route both RPC and log events. */
|
|
2397
2508
|
observability?: (env: Record<string, unknown>) => LogSink | undefined;
|
|
2398
2509
|
scheduler?: (env: Record<string, unknown>) => unknown;
|
|
2399
|
-
storage?: (env: Record<string, unknown>) => unknown;${vectorsConfigField}${aiConfigField}${kvFragments.configField}${flagsFragments.configField}${analyticsFragments.configField}${imagesFragments.configField}${hyperdriveFragments.configField}${browserFragments.configField}${r2sqlFragments.configField}${pipelinesFragments.configField}${paymentsConfigField}${d1ConfigField}${hyperdriveGlobalConfigField}
|
|
2510
|
+
storage?: (env: Record<string, unknown>) => unknown;${vectorsConfigField}${aiConfigField}${kvFragments.configField}${flagsFragments.configField}${analyticsFragments.configField}${imagesFragments.configField}${hyperdriveFragments.configField}${browserFragments.configField}${r2sqlFragments.configField}${pipelinesFragments.configField}${paymentsConfigField}${d1ConfigField}${hyperdriveGlobalConfigField}${sourceClientConfigField}
|
|
2400
2511
|
}
|
|
2401
2512
|
|
|
2402
2513
|
const schedulerStub = {
|
|
@@ -2434,7 +2545,7 @@ const storageStub = {
|
|
|
2434
2545
|
throw new Error("ctx.storage: no storage configured. Pass \`storage\` to createShardDO().");
|
|
2435
2546
|
},
|
|
2436
2547
|
};
|
|
2437
|
-
${globalDatabaseStub}${vectorsStub}${aiStub}${kvFragments.stub}${flagsFragments.stub}${analyticsFragments.stub}${imagesFragments.stub}${hyperdriveFragments.stub}${browserFragments.stub}${r2sqlFragments.stub}${pipelinesFragments.stub}${paymentStub}${bindTableHelper}
|
|
2548
|
+
${globalDatabaseStub}${sourceClientCacheConst}${vectorsStub}${aiStub}${kvFragments.stub}${flagsFragments.stub}${analyticsFragments.stub}${imagesFragments.stub}${hyperdriveFragments.stub}${browserFragments.stub}${r2sqlFragments.stub}${pipelinesFragments.stub}${paymentStub}${bindTableHelper}
|
|
2438
2549
|
// Bound in-process \`ctx.run*\` composition depth so a self- or cyclically-
|
|
2439
2550
|
// referencing call fails loudly with a clear error instead of overflowing the
|
|
2440
2551
|
// stack. Tracked across the awaited handler chain (one DO invocation is
|
|
@@ -2475,7 +2586,7 @@ const dispatchRun = async (expected: FunctionKind, functionPath: string, args: R
|
|
|
2475
2586
|
* from the worker entry so wrangler binds it by name.
|
|
2476
2587
|
*/
|
|
2477
2588
|
export const createShardDO = (config: ShardDOConfig = {}): new (state: ShardDOState, env: unknown) => ShardDOBase =>
|
|
2478
|
-
class extends ShardDOBase {
|
|
2589
|
+
class extends ShardDOBase {${sourceConstructorOverride}
|
|
2479
2590
|
private migrated = false;
|
|
2480
2591
|
|
|
2481
2592
|
public override async handleRpc(functionPath: string, args: Record<string, unknown>): Promise<unknown> {
|
|
@@ -2555,7 +2666,7 @@ ${relationFanout.override}
|
|
|
2555
2666
|
iterator: (signal) => (registered.handler as (context: unknown, args: Record<string, unknown>, signal: AbortSignal) => AsyncIterable<unknown>)(this.buildCtx({ functionPath }), args, signal),
|
|
2556
2667
|
};
|
|
2557
2668
|
}
|
|
2558
|
-
${customMutatorOverride}${shapeResolveOverride}${globalShapeReaderOverride}
|
|
2669
|
+
${customMutatorOverride}${shapeResolveOverride}${globalShapeReaderOverride}${externalSourceOverride}
|
|
2559
2670
|
protected override lifecycleHookPaths(event: "connect" | "disconnect"): readonly string[] {
|
|
2560
2671
|
return LUNORA_LIFECYCLE_HOOKS[event];
|
|
2561
2672
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { GENERATED_HEADER } from './GENERATED_HEADER-
|
|
1
|
+
import { GENERATED_HEADER } from './GENERATED_HEADER-CI272wRm.mjs';
|
|
2
2
|
import { s as sanitizeNamespace } from './paths-BRd6JHuF.mjs';
|
|
3
3
|
import { argsObjectSchema, LUNORA_ERROR_CODES } from './LUNORA_ERROR_CODES-CySpQPD3.mjs';
|
|
4
4
|
|
|
@@ -2,7 +2,7 @@ import { existsSync, readFileSync, mkdirSync, writeFileSync } from 'node:fs';
|
|
|
2
2
|
import { join, dirname } from 'node:path';
|
|
3
3
|
import { performance } from 'node:perf_hooks';
|
|
4
4
|
import { Node, SyntaxKind, Project } from 'ts-morph';
|
|
5
|
-
import { lintSchema } from './formatAdvisories-
|
|
5
|
+
import { lintSchema } from './formatAdvisories-DdjK7sgh.mjs';
|
|
6
6
|
import { listLunoraSourceFiles, lunoraRelativePath, classifyProcedureCall, discoverFunctions } from './discoverFunctions-BWMczzBx.mjs';
|
|
7
7
|
import discoverAuthApiCalls from './discoverAuthApiCalls-CoirYbg6.mjs';
|
|
8
8
|
import { discoverContainers } from './CONTAINERS_FILENAME-DlP6YM_Q.mjs';
|
|
@@ -18,15 +18,15 @@ import discoverQueries from './discoverQueries-B0wGT-xe.mjs';
|
|
|
18
18
|
import { discoverQueues } from './QUEUES_FILENAME-B5_eWCRe.mjs';
|
|
19
19
|
import discoverR2sqlCalls from './discoverR2sqlCalls-BVNMd428.mjs';
|
|
20
20
|
import discoverRlsProcedures, { discoverRlsMetadata } from './discoverRlsMetadata-BS9GOGC5.mjs';
|
|
21
|
-
import discoverSchema from './discoverSchema-
|
|
21
|
+
import discoverSchema from './discoverSchema-KYq55qu3.mjs';
|
|
22
22
|
import { discoverShapes } from './SHAPES_FILENAME-ChV7MqgE.mjs';
|
|
23
23
|
import discoverStorageRulesMetadata from './discoverStorageRulesMetadata-Da8BKXcI.mjs';
|
|
24
24
|
import { e as enclosingExportName$1 } from './discover-ast-CT6BgBr4.mjs';
|
|
25
25
|
import { discoverWorkflows } from './WORKFLOWS_FILENAME-CCisG0Vy.mjs';
|
|
26
|
-
import { buildStorageColumns, emitDataModel, emitApi, emitServer, emitFunctions, emitShard, emitCollections, emitContainers, emitWorkflows, emitQueues, emitCrons, emitVectors, emitDrizzleSchema, emitSeed, emitWranglerCronTriggers } from './GENERATED_HEADER-
|
|
27
|
-
import { emitApp } from './emitApp-
|
|
28
|
-
import { buildOpenApiDocument, emitOpenApiModule } from './buildOpenApiDocument-
|
|
29
|
-
import { buildOpenRpcDocument, emitOpenRpcModule } from './OPENRPC_VERSION-
|
|
26
|
+
import { buildStorageColumns, emitDataModel, emitApi, emitServer, emitFunctions, emitShard, emitCollections, emitContainers, emitWorkflows, emitQueues, emitCrons, emitVectors, emitDrizzleSchema, emitSeed, emitWranglerCronTriggers } from './GENERATED_HEADER-CI272wRm.mjs';
|
|
27
|
+
import { emitApp } from './emitApp-cOSypPuO.mjs';
|
|
28
|
+
import { buildOpenApiDocument, emitOpenApiModule } from './buildOpenApiDocument-Dx5QftUn.mjs';
|
|
29
|
+
import { buildOpenRpcDocument, emitOpenRpcModule } from './OPENRPC_VERSION-t5pV2NIN.mjs';
|
|
30
30
|
import { buildSchemaSnapshot, serializeSchemaSnapshot } from './SCHEMA_SNAPSHOT_VERSION-wWGP2_5E.mjs';
|
|
31
31
|
|
|
32
32
|
const HTTP_VERBS = /* @__PURE__ */ new Set(["delete", "get", "head", "options", "patch", "post", "put"]);
|
package/dist/packem_shared/{buildOpenApiDocument-DoK7_x1g.mjs → buildOpenApiDocument-Dx5QftUn.mjs}
RENAMED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { GENERATED_HEADER } from './GENERATED_HEADER-
|
|
1
|
+
import { GENERATED_HEADER } from './GENERATED_HEADER-CI272wRm.mjs';
|
|
2
2
|
import { s as sanitizeNamespace } from './paths-BRd6JHuF.mjs';
|
|
3
3
|
import { LUNORA_ERROR_CODES, objectSchema, argsObjectSchema, validatorIrToJsonSchema } from './LUNORA_ERROR_CODES-CySpQPD3.mjs';
|
|
4
4
|
|
|
@@ -397,6 +397,42 @@ const softDeleteFieldOf = (optionsArgument) => {
|
|
|
397
397
|
}
|
|
398
398
|
return "deletedAt";
|
|
399
399
|
};
|
|
400
|
+
const stringPropertyOf = (object, property) => {
|
|
401
|
+
const node = object.getProperty(property);
|
|
402
|
+
if (node && Node.isPropertyAssignment(node)) {
|
|
403
|
+
const initializer = node.getInitializer();
|
|
404
|
+
if (initializer && Node.isStringLiteral(initializer)) {
|
|
405
|
+
return initializer.getLiteralText();
|
|
406
|
+
}
|
|
407
|
+
}
|
|
408
|
+
return void 0;
|
|
409
|
+
};
|
|
410
|
+
const stringArrayPropertyOf = (object, property) => {
|
|
411
|
+
const node = object.getProperty(property);
|
|
412
|
+
if (node && Node.isPropertyAssignment(node)) {
|
|
413
|
+
const initializer = node.getInitializer();
|
|
414
|
+
if (initializer && Node.isArrayLiteralExpression(initializer)) {
|
|
415
|
+
const items = initializer.getElements().filter((element) => Node.isStringLiteral(element)).map((element) => element.getLiteralText());
|
|
416
|
+
return items.length > 0 ? items : void 0;
|
|
417
|
+
}
|
|
418
|
+
}
|
|
419
|
+
return void 0;
|
|
420
|
+
};
|
|
421
|
+
const parseSourceCall = (args) => {
|
|
422
|
+
const first = args[0];
|
|
423
|
+
if (!first || !Node.isObjectLiteralExpression(first)) {
|
|
424
|
+
return { binding: "", hasTenantBy: false, unanalyzable: true };
|
|
425
|
+
}
|
|
426
|
+
return {
|
|
427
|
+
binding: stringPropertyOf(first, "binding") ?? "",
|
|
428
|
+
columns: stringArrayPropertyOf(first, "columns"),
|
|
429
|
+
hasReconcile: first.getProperty("reconcileEveryMs") !== void 0,
|
|
430
|
+
hasTenantBy: first.getProperty("tenantBy") !== void 0,
|
|
431
|
+
idColumn: stringPropertyOf(first, "idColumn"),
|
|
432
|
+
mode: stringPropertyOf(first, "mode"),
|
|
433
|
+
query: stringPropertyOf(first, "query")
|
|
434
|
+
};
|
|
435
|
+
};
|
|
400
436
|
const applyTableMethod = (accumulator, method, args, name) => {
|
|
401
437
|
switch (method) {
|
|
402
438
|
case "externallyManaged": {
|
|
@@ -436,6 +472,11 @@ const applyTableMethod = (accumulator, method, args, name) => {
|
|
|
436
472
|
accumulator.softDelete = { field: softDeleteFieldOf(args[0]) };
|
|
437
473
|
break;
|
|
438
474
|
}
|
|
475
|
+
case "source": {
|
|
476
|
+
accumulator.externalSource = parseSourceCall(args);
|
|
477
|
+
accumulator.externallyManaged = true;
|
|
478
|
+
break;
|
|
479
|
+
}
|
|
439
480
|
case "vectorize": {
|
|
440
481
|
const vectorIndex = parseVectorizeCall(args, name);
|
|
441
482
|
if (vectorIndex) {
|
|
@@ -478,6 +519,7 @@ const parseTableBuilder = (expression, name) => {
|
|
|
478
519
|
}
|
|
479
520
|
return {
|
|
480
521
|
externallyManaged: accumulator.externallyManaged,
|
|
522
|
+
externalSource: accumulator.externalSource,
|
|
481
523
|
globalBackend: accumulator.shardMode === "global" ? accumulator.globalBackend ?? "d1" : void 0,
|
|
482
524
|
indexes: accumulator.indexes,
|
|
483
525
|
name,
|
|
@@ -19,6 +19,12 @@ const toAdvisorSchema = (schema) => {
|
|
|
19
19
|
tables: schema.tables.map((table) => {
|
|
20
20
|
return {
|
|
21
21
|
externallyManaged: table.externallyManaged ?? false,
|
|
22
|
+
externalSource: table.externalSource ? {
|
|
23
|
+
hasReconcile: table.externalSource.hasReconcile ?? false,
|
|
24
|
+
hasTenantBy: table.externalSource.hasTenantBy,
|
|
25
|
+
mode: table.externalSource.mode,
|
|
26
|
+
unanalyzable: table.externalSource.unanalyzable
|
|
27
|
+
} : void 0,
|
|
22
28
|
fields: Object.keys(table.shape),
|
|
23
29
|
indexes: flattenIndexes(table),
|
|
24
30
|
name: table.name,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lunora/codegen",
|
|
3
|
-
"version": "1.0.0-alpha.
|
|
3
|
+
"version": "1.0.0-alpha.20",
|
|
4
4
|
"description": "Code generator for Lunora: emits _generated/{api,server,dataModel}.ts from your schema",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"cloudflare",
|
|
@@ -46,7 +46,7 @@
|
|
|
46
46
|
"access": "public"
|
|
47
47
|
},
|
|
48
48
|
"dependencies": {
|
|
49
|
-
"@lunora/advisor": "1.0.0-alpha.
|
|
49
|
+
"@lunora/advisor": "1.0.0-alpha.10",
|
|
50
50
|
"@lunora/container": "1.0.0-alpha.5",
|
|
51
51
|
"@lunora/queue": "1.0.0-alpha.1",
|
|
52
52
|
"@lunora/scheduler": "1.0.0-alpha.3",
|