@lunora/codegen 1.0.0-alpha.1 → 1.0.0-alpha.10
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/__assets__/package-og.svg +1 -1
- package/dist/index.d.mts +96 -7
- package/dist/index.d.ts +96 -7
- package/dist/index.mjs +23 -22
- package/dist/packem_shared/{CONTAINERS_FILENAME-0K-pjNb8.mjs → CONTAINERS_FILENAME-DlP6YM_Q.mjs} +1 -1
- package/dist/packem_shared/{CodegenDiagnosticError-54jWDxA9.mjs → CodegenDiagnosticError-DeblMkzO.mjs} +3 -2
- package/dist/packem_shared/{emitApi-hRVC-kE7.mjs → GENERATED_HEADER-BiFXNUvo.mjs} +285 -19
- package/dist/packem_shared/{buildOpenRpcDocument-BZGY1-jT.mjs → OPENRPC_VERSION-B4i9Qp3v.mjs} +1 -1
- package/dist/packem_shared/{createCodegenProject-DGJm0_Pk.mjs → SCHEMA_SNAPSHOT_FILENAME-Bvv7qa_u.mjs} +81 -37
- package/dist/packem_shared/{buildSchemaSnapshot-DzLDbWk3.mjs → SCHEMA_SNAPSHOT_VERSION-wWGP2_5E.mjs} +12 -0
- package/dist/packem_shared/{discoverWorkflows-DRDQdhfq.mjs → WORKFLOWS_FILENAME-D62dcBGg.mjs} +1 -1
- package/dist/packem_shared/{buildOpenApiDocument-yHVN66Xd.mjs → buildOpenApiDocument-Cu3mZl-8.mjs} +1 -1
- package/dist/packem_shared/{discoverAuthApiCalls-C35R6z0T.mjs → discoverAuthApiCalls-CoirYbg6.mjs} +1 -1
- package/dist/packem_shared/{discoverCrons-BL6iGuJ3.mjs → discoverCrons-Cev7RRAf.mjs} +20 -17
- package/dist/packem_shared/{discoverFunctions-DEgAcRuD.mjs → discoverFunctions-BWMczzBx.mjs} +7 -2
- package/dist/packem_shared/{discoverHttpRoutes-C978pBiG.mjs → discoverHttpRoutes-CfP6cMzt.mjs} +2 -2
- package/dist/packem_shared/{discoverInserts-CRQdXvHO.mjs → discoverInserts-C7zxXkUf.mjs} +24 -2
- package/dist/packem_shared/{discoverMaskProcedures-B64zA740.mjs → discoverMaskProcedures-Cm81kwrb.mjs} +1 -1
- package/dist/packem_shared/{discoverMigrations-Doj_-BAA.mjs → discoverMigrations-Bi5nJ0mJ.mjs} +10 -4
- package/dist/packem_shared/{discoverNondeterministicCalls-4KiPQxQU.mjs → discoverNondeterministicCalls-C4M8AXmQ.mjs} +1 -1
- package/dist/packem_shared/{discoverQueries-BkIi0dBD.mjs → discoverQueries-B0wGT-xe.mjs} +1 -1
- package/dist/packem_shared/discoverR2sqlCalls-BVNMd428.mjs +80 -0
- package/dist/packem_shared/{discoverRlsMetadata-DpRB1HMe.mjs → discoverRlsMetadata-BS9GOGC5.mjs} +1 -1
- package/dist/packem_shared/{discoverSchema-BBulgGbH.mjs → discoverSchema-BnWHHJ4T.mjs} +296 -16
- package/dist/packem_shared/{discoverStorageRulesMetadata-DAqJUxUv.mjs → discoverStorageRulesMetadata-Da8BKXcI.mjs} +1 -1
- package/dist/packem_shared/{emitApp-CzZ6GbrD.mjs → emitApp-KfMaKXWe.mjs} +12 -2
- package/dist/packem_shared/{lintSchema-DicbOHvH.mjs → formatAdvisories-8NIv1k0I.mjs} +2 -1
- package/dist/packem_shared/{parse-validator-tuQtHrsr.mjs → parse-validator-Cabb60UV.mjs} +2 -1
- package/package.json +6 -6
|
@@ -1,27 +1,29 @@
|
|
|
1
1
|
import { existsSync, readFileSync, mkdirSync, writeFileSync } from 'node:fs';
|
|
2
2
|
import { join, dirname } from 'node:path';
|
|
3
|
+
import { performance } from 'node:perf_hooks';
|
|
3
4
|
import { Node, SyntaxKind, Project } from 'ts-morph';
|
|
4
|
-
import { lintSchema } from './
|
|
5
|
-
import { listLunoraSourceFiles, lunoraRelativePath, classifyProcedureCall, discoverFunctions } from './discoverFunctions-
|
|
6
|
-
import discoverAuthApiCalls from './discoverAuthApiCalls-
|
|
7
|
-
import { discoverContainers } from './CONTAINERS_FILENAME-
|
|
8
|
-
import discoverCrons from './discoverCrons-
|
|
9
|
-
import discoverHttpRoutes from './discoverHttpRoutes-
|
|
10
|
-
import discoverInserts from './discoverInserts-
|
|
11
|
-
import discoverMaskProcedures, { discoverMaskMetadata } from './discoverMaskProcedures-
|
|
12
|
-
import discoverMigrations from './discoverMigrations-
|
|
13
|
-
import discoverNondeterministicCalls from './discoverNondeterministicCalls-
|
|
14
|
-
import discoverQueries from './discoverQueries-
|
|
15
|
-
import
|
|
16
|
-
import
|
|
17
|
-
import
|
|
5
|
+
import { lintSchema } from './formatAdvisories-8NIv1k0I.mjs';
|
|
6
|
+
import { listLunoraSourceFiles, lunoraRelativePath, classifyProcedureCall, discoverFunctions } from './discoverFunctions-BWMczzBx.mjs';
|
|
7
|
+
import discoverAuthApiCalls from './discoverAuthApiCalls-CoirYbg6.mjs';
|
|
8
|
+
import { discoverContainers } from './CONTAINERS_FILENAME-DlP6YM_Q.mjs';
|
|
9
|
+
import discoverCrons from './discoverCrons-Cev7RRAf.mjs';
|
|
10
|
+
import discoverHttpRoutes from './discoverHttpRoutes-CfP6cMzt.mjs';
|
|
11
|
+
import discoverInserts from './discoverInserts-C7zxXkUf.mjs';
|
|
12
|
+
import discoverMaskProcedures, { discoverMaskMetadata } from './discoverMaskProcedures-Cm81kwrb.mjs';
|
|
13
|
+
import discoverMigrations from './discoverMigrations-Bi5nJ0mJ.mjs';
|
|
14
|
+
import discoverNondeterministicCalls from './discoverNondeterministicCalls-C4M8AXmQ.mjs';
|
|
15
|
+
import discoverQueries from './discoverQueries-B0wGT-xe.mjs';
|
|
16
|
+
import discoverR2sqlCalls from './discoverR2sqlCalls-BVNMd428.mjs';
|
|
17
|
+
import discoverRlsProcedures, { discoverRlsMetadata } from './discoverRlsMetadata-BS9GOGC5.mjs';
|
|
18
|
+
import discoverSchema from './discoverSchema-BnWHHJ4T.mjs';
|
|
19
|
+
import discoverStorageRulesMetadata from './discoverStorageRulesMetadata-Da8BKXcI.mjs';
|
|
18
20
|
import { e as enclosingExportName$1 } from './discover-ast-CT6BgBr4.mjs';
|
|
19
|
-
import { discoverWorkflows } from './
|
|
20
|
-
import { buildStorageColumns, emitDataModel, emitApi, emitServer, emitFunctions, emitShard, emitContainers, emitWorkflows, emitCrons, emitVectors, emitDrizzleSchema, emitSeed, emitWranglerCronTriggers } from './
|
|
21
|
-
import { emitApp } from './emitApp-
|
|
22
|
-
import { buildOpenApiDocument, emitOpenApiModule } from './buildOpenApiDocument-
|
|
23
|
-
import { buildOpenRpcDocument, emitOpenRpcModule } from './
|
|
24
|
-
import { buildSchemaSnapshot, serializeSchemaSnapshot } from './
|
|
21
|
+
import { discoverWorkflows } from './WORKFLOWS_FILENAME-D62dcBGg.mjs';
|
|
22
|
+
import { buildStorageColumns, emitDataModel, emitApi, emitServer, emitFunctions, emitShard, emitContainers, emitWorkflows, emitCrons, emitVectors, emitDrizzleSchema, emitSeed, emitWranglerCronTriggers } from './GENERATED_HEADER-BiFXNUvo.mjs';
|
|
23
|
+
import { emitApp } from './emitApp-KfMaKXWe.mjs';
|
|
24
|
+
import { buildOpenApiDocument, emitOpenApiModule } from './buildOpenApiDocument-Cu3mZl-8.mjs';
|
|
25
|
+
import { buildOpenRpcDocument, emitOpenRpcModule } from './OPENRPC_VERSION-B4i9Qp3v.mjs';
|
|
26
|
+
import { buildSchemaSnapshot, serializeSchemaSnapshot } from './SCHEMA_SNAPSHOT_VERSION-wWGP2_5E.mjs';
|
|
25
27
|
|
|
26
28
|
const HTTP_VERBS = /* @__PURE__ */ new Set(["delete", "get", "head", "options", "patch", "post", "put"]);
|
|
27
29
|
const TERMINAL_STEPS = /* @__PURE__ */ new Set(["handler", "stream"]);
|
|
@@ -246,6 +248,7 @@ const PROBES = {
|
|
|
246
248
|
mail: { moduleSpecifier: "@lunora/mail" },
|
|
247
249
|
payments: { contextProperty: "payments", moduleSpecifier: "@lunora/payment" },
|
|
248
250
|
pipelines: { contextProperty: "pipelines", moduleSpecifier: "@lunora/pipelines" },
|
|
251
|
+
r2sql: { contextProperty: "r2sql", moduleSpecifier: "@lunora/r2sql" },
|
|
249
252
|
scheduler: { contextProperty: "scheduler", moduleSpecifier: "@lunora/scheduler" },
|
|
250
253
|
storage: { contextProperty: "storage", moduleSpecifier: "@lunora/storage" },
|
|
251
254
|
vectors: { contextProperty: "vectors", moduleSpecifier: "@lunora/vectors" },
|
|
@@ -277,6 +280,7 @@ const discoverFeatureUsage = (project, lunoraDirectory) => {
|
|
|
277
280
|
mail: false,
|
|
278
281
|
payments: false,
|
|
279
282
|
pipelines: false,
|
|
283
|
+
r2sql: false,
|
|
280
284
|
scheduler: false,
|
|
281
285
|
storage: false,
|
|
282
286
|
vectors: false,
|
|
@@ -364,26 +368,45 @@ const protectPublicFlags = (call) => {
|
|
|
364
368
|
}
|
|
365
369
|
return { usesCaptcha: Boolean(argument.getProperty("captcha")), usesRateLimit: Boolean(argument.getProperty("rateLimit")) };
|
|
366
370
|
};
|
|
371
|
+
const resolveUseArgumentCall = (argument) => {
|
|
372
|
+
if (Node.isCallExpression(argument)) {
|
|
373
|
+
return argument;
|
|
374
|
+
}
|
|
375
|
+
if (!Node.isIdentifier(argument)) {
|
|
376
|
+
return void 0;
|
|
377
|
+
}
|
|
378
|
+
const declaration = argument.getSourceFile().getVariableDeclaration(argument.getText());
|
|
379
|
+
const initializer = declaration?.getInitializer();
|
|
380
|
+
return initializer && Node.isCallExpression(initializer) ? initializer : void 0;
|
|
381
|
+
};
|
|
382
|
+
const NO_PROTECTIONS = { usesCaptcha: false, usesMask: false, usesRateLimit: false, usesRls: false };
|
|
383
|
+
const useStepProtections = (useArgument) => {
|
|
384
|
+
const argument = resolveUseArgumentCall(useArgument);
|
|
385
|
+
const name = argument ? calleeNameOf(argument) : void 0;
|
|
386
|
+
if (argument && name === "protectPublic") {
|
|
387
|
+
const bundle = protectPublicFlags(argument);
|
|
388
|
+
return { ...NO_PROTECTIONS, usesCaptcha: bundle.usesCaptcha, usesRateLimit: bundle.usesRateLimit };
|
|
389
|
+
}
|
|
390
|
+
if (name !== void 0 && name in MIDDLEWARE_FLAGS) {
|
|
391
|
+
return { ...NO_PROTECTIONS, [MIDDLEWARE_FLAGS[name]]: true };
|
|
392
|
+
}
|
|
393
|
+
return NO_PROTECTIONS;
|
|
394
|
+
};
|
|
367
395
|
const protectionsInChain = (receiver) => {
|
|
368
|
-
const protections = {
|
|
396
|
+
const protections = { ...NO_PROTECTIONS };
|
|
369
397
|
let node = receiver;
|
|
370
398
|
while (Node.isCallExpression(node)) {
|
|
371
399
|
const chainCallee = node.getExpression();
|
|
372
400
|
if (!Node.isPropertyAccessExpression(chainCallee)) {
|
|
373
401
|
break;
|
|
374
402
|
}
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
protections.usesCaptcha ||= bundle.usesCaptcha;
|
|
383
|
-
} else if (name !== void 0 && name in MIDDLEWARE_FLAGS) {
|
|
384
|
-
protections[MIDDLEWARE_FLAGS[name]] = true;
|
|
385
|
-
}
|
|
386
|
-
}
|
|
403
|
+
const useArgument = chainCallee.getName() === "use" ? node.getArguments()[0] : void 0;
|
|
404
|
+
if (useArgument) {
|
|
405
|
+
const step = useStepProtections(useArgument);
|
|
406
|
+
protections.usesCaptcha ||= step.usesCaptcha;
|
|
407
|
+
protections.usesMask ||= step.usesMask;
|
|
408
|
+
protections.usesRateLimit ||= step.usesRateLimit;
|
|
409
|
+
protections.usesRls ||= step.usesRls;
|
|
387
410
|
}
|
|
388
411
|
node = chainCallee.getExpression();
|
|
389
412
|
}
|
|
@@ -654,6 +677,10 @@ const readProjectVersion = (projectRoot) => {
|
|
|
654
677
|
return void 0;
|
|
655
678
|
}
|
|
656
679
|
};
|
|
680
|
+
const isTimingEnabled = () => {
|
|
681
|
+
const flag = process.env["LUNORA_CODEGEN_TIMING"];
|
|
682
|
+
return flag !== void 0 && flag !== "";
|
|
683
|
+
};
|
|
657
684
|
const findTsconfig = (startPath) => {
|
|
658
685
|
let directory = existsSync(startPath) ? startPath : dirname(startPath);
|
|
659
686
|
while (directory && directory !== dirname(directory)) {
|
|
@@ -695,13 +722,15 @@ const refreshCodegenProject = (project, lunoraDirectory) => {
|
|
|
695
722
|
}
|
|
696
723
|
};
|
|
697
724
|
const runCodegen = (options) => {
|
|
725
|
+
const timingEnabled = isTimingEnabled();
|
|
726
|
+
const startedAt = timingEnabled ? performance.now() : 0;
|
|
698
727
|
const lunoraDirectory = join(options.projectRoot, options.lunoraDirectory ?? "lunora");
|
|
699
728
|
const schemaPath = join(lunoraDirectory, "schema.ts");
|
|
700
729
|
if (!existsSync(schemaPath)) {
|
|
701
730
|
throw new Error(`schema.ts not found at ${schemaPath}`);
|
|
702
731
|
}
|
|
703
732
|
const project = options.project ?? createCodegenProject(lunoraDirectory);
|
|
704
|
-
const schema = discoverSchema(project, schemaPath);
|
|
733
|
+
const schema = discoverSchema(project, schemaPath, options.projectRoot);
|
|
705
734
|
const functions = discoverFunctions(project, lunoraDirectory);
|
|
706
735
|
const httpRoutes = discoverHttpRoutes(project, lunoraDirectory);
|
|
707
736
|
const migrations = discoverMigrations(project, lunoraDirectory);
|
|
@@ -723,7 +752,8 @@ const runCodegen = (options) => {
|
|
|
723
752
|
discoverArgumentValidators(project, lunoraDirectory),
|
|
724
753
|
discoverSecrets(project, lunoraDirectory),
|
|
725
754
|
discoverSqlInterpolation(project, lunoraDirectory),
|
|
726
|
-
discoverAdminRoutes(project, lunoraDirectory)
|
|
755
|
+
discoverAdminRoutes(project, lunoraDirectory),
|
|
756
|
+
discoverR2sqlCalls(project, lunoraDirectory)
|
|
727
757
|
);
|
|
728
758
|
const rlsMetadata = discoverRlsMetadata(project, lunoraDirectory);
|
|
729
759
|
const maskMetadata = discoverMaskMetadata(project, lunoraDirectory);
|
|
@@ -737,6 +767,7 @@ const runCodegen = (options) => {
|
|
|
737
767
|
const hasImages = featureUsage.images;
|
|
738
768
|
const hasAnalytics = featureUsage.analytics;
|
|
739
769
|
const hasPipelines = featureUsage.pipelines;
|
|
770
|
+
const hasR2sql = featureUsage.r2sql;
|
|
740
771
|
const dependencies = discoverPackageDependencies(options.projectRoot);
|
|
741
772
|
const studioFeatures = buildStudioFeatures(featureUsage, {
|
|
742
773
|
cronCount: crons.length,
|
|
@@ -747,6 +778,7 @@ const runCodegen = (options) => {
|
|
|
747
778
|
workflowCount: workflows.length
|
|
748
779
|
});
|
|
749
780
|
const useUmbrella = dependencies.has("lunorash");
|
|
781
|
+
const emitStartedAt = timingEnabled ? performance.now() : 0;
|
|
750
782
|
const dataModelContent = emitDataModel(schema, useUmbrella);
|
|
751
783
|
const apiContent = emitApi(functions, workflows, useUmbrella);
|
|
752
784
|
const serverContent = emitServer({
|
|
@@ -759,12 +791,13 @@ const runCodegen = (options) => {
|
|
|
759
791
|
hasKv,
|
|
760
792
|
hasPayments,
|
|
761
793
|
hasPipelines,
|
|
794
|
+
hasR2sql,
|
|
762
795
|
schema,
|
|
763
796
|
storageRuleBuckets: storageRulesMetadata.rules.map((rule) => rule.bucket),
|
|
764
797
|
useUmbrella,
|
|
765
798
|
workflows
|
|
766
799
|
});
|
|
767
|
-
const functionsContent = emitFunctions(functions, migrations);
|
|
800
|
+
const functionsContent = emitFunctions(functions, migrations, useUmbrella);
|
|
768
801
|
const shardContent = emitShard({
|
|
769
802
|
advisories,
|
|
770
803
|
containers,
|
|
@@ -775,6 +808,7 @@ const runCodegen = (options) => {
|
|
|
775
808
|
hasImages,
|
|
776
809
|
hasKv,
|
|
777
810
|
hasPayments,
|
|
811
|
+
hasR2sql,
|
|
778
812
|
maskMetadata,
|
|
779
813
|
rlsMetadata,
|
|
780
814
|
schema,
|
|
@@ -783,7 +817,7 @@ const runCodegen = (options) => {
|
|
|
783
817
|
useUmbrella,
|
|
784
818
|
workflows
|
|
785
819
|
});
|
|
786
|
-
const containersContent = emitContainers(containers);
|
|
820
|
+
const containersContent = emitContainers(containers, schema.jurisdiction);
|
|
787
821
|
const workflowsContent = emitWorkflows(workflows);
|
|
788
822
|
const cronsContent = emitCrons(crons);
|
|
789
823
|
const vectorsContent = emitVectors(schema.vectorIndexes);
|
|
@@ -809,10 +843,13 @@ const runCodegen = (options) => {
|
|
|
809
843
|
hasImages,
|
|
810
844
|
hasKv,
|
|
811
845
|
hasPayments,
|
|
846
|
+
hasR2sql,
|
|
812
847
|
hasScheduler: studioFeatures.scheduler,
|
|
813
848
|
hasStorage: studioFeatures.storage,
|
|
814
849
|
hasVectors: schema.vectorIndexes.length > 0,
|
|
815
850
|
hasWorkflow: workflows.length > 0,
|
|
851
|
+
// Schema `.jurisdiction("…")` → pin the generated worker's DOs to the region.
|
|
852
|
+
jurisdiction: schema.jurisdiction,
|
|
816
853
|
useUmbrella,
|
|
817
854
|
wantsOpenApi,
|
|
818
855
|
wantsOpenRpc
|
|
@@ -862,6 +899,13 @@ const runCodegen = (options) => {
|
|
|
862
899
|
writeIfChanged(schemaSnapshotPath, serializeSchemaSnapshot(schemaSnapshot));
|
|
863
900
|
}
|
|
864
901
|
}
|
|
902
|
+
if (timingEnabled) {
|
|
903
|
+
const finishedAt = performance.now();
|
|
904
|
+
const total = Math.round(finishedAt - startedAt);
|
|
905
|
+
const discovery = Math.round(emitStartedAt - startedAt);
|
|
906
|
+
const emit = Math.round(finishedAt - emitStartedAt);
|
|
907
|
+
console.error(`@lunora/codegen: codegen took ${total.toString()}ms (discovery ${discovery.toString()}ms, emit ${emit.toString()}ms)`);
|
|
908
|
+
}
|
|
865
909
|
return {
|
|
866
910
|
advisories,
|
|
867
911
|
containers,
|
package/dist/packem_shared/{buildSchemaSnapshot-DzLDbWk3.mjs → SCHEMA_SNAPSHOT_VERSION-wWGP2_5E.mjs}
RENAMED
|
@@ -39,6 +39,7 @@ const buildSchemaSnapshot = (schema, migrationIds) => {
|
|
|
39
39
|
tables[table.name] = tableSnapshotOf(table);
|
|
40
40
|
}
|
|
41
41
|
return {
|
|
42
|
+
jurisdiction: schema.jurisdiction,
|
|
42
43
|
migrationIds: [...migrationIds].toSorted((a, b) => a.localeCompare(b)),
|
|
43
44
|
tables: sortKeys(tables),
|
|
44
45
|
version: SCHEMA_SNAPSHOT_VERSION
|
|
@@ -69,7 +70,9 @@ const parseSchemaSnapshot = (content) => {
|
|
|
69
70
|
throw new SchemaSnapshotParseError(`baseline table "${name}" has an invalid structure`);
|
|
70
71
|
}
|
|
71
72
|
}
|
|
73
|
+
const jurisdiction = typeof parsed.jurisdiction === "string" ? parsed.jurisdiction : void 0;
|
|
72
74
|
return {
|
|
75
|
+
jurisdiction,
|
|
73
76
|
migrationIds: Array.isArray(parsed.migrationIds) ? parsed.migrationIds : [],
|
|
74
77
|
tables: parsed.tables,
|
|
75
78
|
version: SCHEMA_SNAPSHOT_VERSION
|
|
@@ -189,6 +192,15 @@ const diffSchemaSnapshots = (baseline, current) => {
|
|
|
189
192
|
});
|
|
190
193
|
}
|
|
191
194
|
}
|
|
195
|
+
if (baseline !== void 0 && baseline.jurisdiction !== current.jurisdiction) {
|
|
196
|
+
const from = baseline.jurisdiction ?? "(none)";
|
|
197
|
+
const to = current.jurisdiction ?? "(none)";
|
|
198
|
+
changes.push({
|
|
199
|
+
severity: "breaking",
|
|
200
|
+
summary: `Durable Object jurisdiction changed from ${from} to ${to} — this re-homes every DO and strands all existing shard, scheduler, and session-DO data in the old region (no in-place migration; export then import to move it). Revert the change, or override the gate to proceed intentionally.`,
|
|
201
|
+
type: "changedJurisdiction"
|
|
202
|
+
});
|
|
203
|
+
}
|
|
192
204
|
return { changes };
|
|
193
205
|
};
|
|
194
206
|
const evaluateSchemaDrift = (options) => {
|
package/dist/packem_shared/{discoverWorkflows-DRDQdhfq.mjs → WORKFLOWS_FILENAME-D62dcBGg.mjs}
RENAMED
|
@@ -2,7 +2,7 @@ import { existsSync } from 'node:fs';
|
|
|
2
2
|
import { join } from 'node:path';
|
|
3
3
|
import { workflowDefaultName, workflowClassName, workflowBindingName } from '@lunora/workflow';
|
|
4
4
|
import { SyntaxKind, Node } from 'ts-morph';
|
|
5
|
-
import { diagnosticAt } from './CodegenDiagnosticError-
|
|
5
|
+
import { diagnosticAt } from './CodegenDiagnosticError-DeblMkzO.mjs';
|
|
6
6
|
|
|
7
7
|
const WORKFLOWS_FILENAME = "workflows.ts";
|
|
8
8
|
const isDefineWorkflow = (identifier) => {
|
package/dist/packem_shared/{buildOpenApiDocument-yHVN66Xd.mjs → buildOpenApiDocument-Cu3mZl-8.mjs}
RENAMED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { GENERATED_HEADER } from './
|
|
1
|
+
import { GENERATED_HEADER } from './GENERATED_HEADER-BiFXNUvo.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
|
|
package/dist/packem_shared/{discoverAuthApiCalls-C35R6z0T.mjs → discoverAuthApiCalls-CoirYbg6.mjs}
RENAMED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { relative, sep } from 'node:path';
|
|
2
2
|
import { SyntaxKind, Node } from 'ts-morph';
|
|
3
3
|
import { T as TS_EXTENSION_RE, e as enclosingExportName } from './discover-ast-CT6BgBr4.mjs';
|
|
4
|
-
import { listLunoraSourceFiles } from './discoverFunctions-
|
|
4
|
+
import { listLunoraSourceFiles } from './discoverFunctions-BWMczzBx.mjs';
|
|
5
5
|
|
|
6
6
|
const isAuthApiCall = (call) => {
|
|
7
7
|
const callee = call.getExpression();
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { isValidCronExpression, compileCronSchedule, CRON_SCHEDULE_KINDS } from '@lunora/scheduler';
|
|
2
2
|
import { SyntaxKind, Node } from 'ts-morph';
|
|
3
|
-
import {
|
|
3
|
+
import { diagnosticAt } from './CodegenDiagnosticError-DeblMkzO.mjs';
|
|
4
|
+
import { listLunoraSourceFiles } from './discoverFunctions-BWMczzBx.mjs';
|
|
4
5
|
import { s as sanitizeNamespace } from './paths-BRd6JHuF.mjs';
|
|
5
6
|
|
|
6
7
|
const CRON_METHODS = /* @__PURE__ */ new Set([...CRON_SCHEDULE_KINDS, "cron"]);
|
|
@@ -71,7 +72,7 @@ const literalValue = (node, jobName) => {
|
|
|
71
72
|
if (Node.isArrayLiteralExpression(node)) {
|
|
72
73
|
return node.getElements().map((element) => literalValue(element, jobName));
|
|
73
74
|
}
|
|
74
|
-
throw
|
|
75
|
+
throw diagnosticAt(node, `Cron job "${jobName}" passes a non-static value where a literal is required; codegen can only read literals.`, {
|
|
75
76
|
code: "CRON_NON_STATIC_VALUE",
|
|
76
77
|
name: "LunoraError",
|
|
77
78
|
status: 500
|
|
@@ -81,8 +82,9 @@ const objectLiteralValue = (object, jobName) => {
|
|
|
81
82
|
const result = {};
|
|
82
83
|
for (const property of object.getProperties()) {
|
|
83
84
|
if (!Node.isPropertyAssignment(property)) {
|
|
84
|
-
throw
|
|
85
|
-
|
|
85
|
+
throw diagnosticAt(
|
|
86
|
+
property,
|
|
87
|
+
`Cron job "${jobName}" uses an unsupported object property (shorthand/spread/method) where a static literal is required.`,
|
|
86
88
|
{
|
|
87
89
|
code: "CRON_NON_STATIC_VALUE",
|
|
88
90
|
name: "LunoraError",
|
|
@@ -100,8 +102,9 @@ const objectLiteralValue = (object, jobName) => {
|
|
|
100
102
|
const functionPathFromArgument = (call, index, jobName) => {
|
|
101
103
|
const argument = call.getArguments()[index];
|
|
102
104
|
if (!argument || !Node.isPropertyAccessExpression(argument)) {
|
|
103
|
-
throw
|
|
104
|
-
|
|
105
|
+
throw diagnosticAt(
|
|
106
|
+
call,
|
|
107
|
+
`Cron job "${jobName}" must reference a function statically (e.g. internal.email.digest); codegen cannot resolve a dynamic reference.`,
|
|
105
108
|
{
|
|
106
109
|
code: "CRON_NON_STATIC_FN",
|
|
107
110
|
name: "LunoraError",
|
|
@@ -112,7 +115,7 @@ const functionPathFromArgument = (call, index, jobName) => {
|
|
|
112
115
|
const functionName = argument.getName();
|
|
113
116
|
const receiver = argument.getExpression();
|
|
114
117
|
if (!Node.isPropertyAccessExpression(receiver)) {
|
|
115
|
-
throw
|
|
118
|
+
throw diagnosticAt(argument, `Cron job "${jobName}" function reference must be of the form internal.file.fn (two property accesses).`, {
|
|
116
119
|
code: "CRON_NON_STATIC_FN",
|
|
117
120
|
name: "LunoraError",
|
|
118
121
|
status: 500
|
|
@@ -133,8 +136,9 @@ const resolveTarget = (call, index, jobName, workflowsByName) => {
|
|
|
133
136
|
if (workflow) {
|
|
134
137
|
return workflowTarget(workflow);
|
|
135
138
|
}
|
|
136
|
-
throw
|
|
137
|
-
|
|
139
|
+
throw diagnosticAt(
|
|
140
|
+
argument,
|
|
141
|
+
`Cron job "${jobName}" targets workflows.${argument.getName()}, but no such workflow is declared in lunora/workflows.ts.`,
|
|
138
142
|
{
|
|
139
143
|
code: "CRON_NON_STATIC_FN",
|
|
140
144
|
name: "LunoraError",
|
|
@@ -149,10 +153,9 @@ const resolveTarget = (call, index, jobName, workflowsByName) => {
|
|
|
149
153
|
if (workflow) {
|
|
150
154
|
return workflowTarget(workflow);
|
|
151
155
|
}
|
|
152
|
-
throw
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
),
|
|
156
|
+
throw diagnosticAt(
|
|
157
|
+
argument,
|
|
158
|
+
`Cron job "${jobName}" references "${argument.getText()}", which is neither a function (internal.file.fn / api.file.fn) nor a declared workflow in lunora/workflows.ts.`,
|
|
156
159
|
{
|
|
157
160
|
code: "CRON_NON_STATIC_FN",
|
|
158
161
|
name: "LunoraError",
|
|
@@ -172,7 +175,7 @@ const cronFromCall = (call, callee, builderNames, workflowsByName) => {
|
|
|
172
175
|
}
|
|
173
176
|
const name = stringArgument(call, 0);
|
|
174
177
|
if (name === void 0 || name.trim() === "") {
|
|
175
|
-
throw
|
|
178
|
+
throw diagnosticAt(call, `A cron ".${method}(...)" registration must pass a non-empty string-literal name as its first argument.`, {
|
|
176
179
|
code: "CRON_NAME_NOT_STATIC",
|
|
177
180
|
name: "LunoraError",
|
|
178
181
|
status: 500
|
|
@@ -182,14 +185,14 @@ const cronFromCall = (call, callee, builderNames, workflowsByName) => {
|
|
|
182
185
|
if (method === "cron") {
|
|
183
186
|
const expression = stringArgument(call, 1);
|
|
184
187
|
if (expression === void 0) {
|
|
185
|
-
throw
|
|
188
|
+
throw diagnosticAt(call, `Cron job "${name}" must pass a string-literal cron expression to ".cron(...)".`, {
|
|
186
189
|
code: "CRON_EXPR_NOT_STATIC",
|
|
187
190
|
name: "LunoraError",
|
|
188
191
|
status: 500
|
|
189
192
|
});
|
|
190
193
|
}
|
|
191
194
|
if (!isValidCronExpression(expression)) {
|
|
192
|
-
throw
|
|
195
|
+
throw diagnosticAt(call, `Cron job "${name}" has an invalid cron expression "${expression}" — expected 5 or 6 space-separated fields.`, {
|
|
193
196
|
code: "CRON_EXPR_INVALID",
|
|
194
197
|
name: "LunoraError",
|
|
195
198
|
status: 500
|
|
@@ -199,7 +202,7 @@ const cronFromCall = (call, callee, builderNames, workflowsByName) => {
|
|
|
199
202
|
} else {
|
|
200
203
|
const scheduleArgument = call.getArguments()[1];
|
|
201
204
|
if (!scheduleArgument || !Node.isObjectLiteralExpression(scheduleArgument)) {
|
|
202
|
-
throw
|
|
205
|
+
throw diagnosticAt(call, `Cron job "${name}" must pass an object-literal schedule to ".${method}(...)".`, {
|
|
203
206
|
code: "CRON_SCHEDULE_NOT_STATIC",
|
|
204
207
|
name: "LunoraError",
|
|
205
208
|
status: 500
|
package/dist/packem_shared/{discoverFunctions-DEgAcRuD.mjs → discoverFunctions-BWMczzBx.mjs}
RENAMED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { readdirSync, lstatSync } from 'node:fs';
|
|
2
2
|
import { join, extname, relative, sep } from 'node:path';
|
|
3
3
|
import { Node, SyntaxKind } from 'ts-morph';
|
|
4
|
-
import { a as parseObjectShape } from './parse-validator-
|
|
4
|
+
import { a as parseObjectShape } from './parse-validator-Cabb60UV.mjs';
|
|
5
5
|
import { s as sanitizeNamespace } from './paths-BRd6JHuF.mjs';
|
|
6
6
|
|
|
7
7
|
const FUNCTION_KINDS = /* @__PURE__ */ new Set(["action", "mutation", "query", "stream"]);
|
|
@@ -344,7 +344,12 @@ const discoverFromCall = (call) => {
|
|
|
344
344
|
if (classified.lifecycle) {
|
|
345
345
|
return { args: {}, kind: classified.kind, lifecycle: classified.lifecycle, returnType: "void", visibility: classified.visibility };
|
|
346
346
|
}
|
|
347
|
-
return {
|
|
347
|
+
return {
|
|
348
|
+
args: argsFromCall(call),
|
|
349
|
+
kind: classified.kind,
|
|
350
|
+
returnType: returnTypeFromCall(call),
|
|
351
|
+
visibility: classified.visibility
|
|
352
|
+
};
|
|
348
353
|
};
|
|
349
354
|
const RE_EXPORT_RESOLVE_LIMIT = 8;
|
|
350
355
|
const resolveExpressionToCall = (node, depth = 0) => {
|
package/dist/packem_shared/{discoverHttpRoutes-C978pBiG.mjs → discoverHttpRoutes-CfP6cMzt.mjs}
RENAMED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { relative, sep } from 'node:path';
|
|
2
2
|
import { Node } from 'ts-morph';
|
|
3
|
-
import { listLunoraSourceFiles } from './discoverFunctions-
|
|
4
|
-
import { p as parseValidator, a as parseObjectShape } from './parse-validator-
|
|
3
|
+
import { listLunoraSourceFiles } from './discoverFunctions-BWMczzBx.mjs';
|
|
4
|
+
import { p as parseValidator, a as parseObjectShape } from './parse-validator-Cabb60UV.mjs';
|
|
5
5
|
|
|
6
6
|
const TS_EXTENSION_RE = /\.ts$/u;
|
|
7
7
|
const HTTP_VERBS = /* @__PURE__ */ new Set(["delete", "get", "head", "options", "patch", "post", "put"]);
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { SyntaxKind, Node } from 'ts-morph';
|
|
2
2
|
import { e as enclosingExportName } from './discover-ast-CT6BgBr4.mjs';
|
|
3
|
-
import { listLunoraSourceFiles, lunoraRelativePath } from './discoverFunctions-
|
|
3
|
+
import { listLunoraSourceFiles, lunoraRelativePath } from './discoverFunctions-BWMczzBx.mjs';
|
|
4
4
|
|
|
5
5
|
const isDatabaseInsertCall = (call) => {
|
|
6
6
|
const callee = call.getExpression();
|
|
@@ -13,9 +13,31 @@ const isDatabaseInsertCall = (call) => {
|
|
|
13
13
|
}
|
|
14
14
|
return Node.isIdentifier(receiver) && receiver.getText() === "db";
|
|
15
15
|
};
|
|
16
|
+
const resolveStringConst = (identifier) => {
|
|
17
|
+
if (!Node.isIdentifier(identifier)) {
|
|
18
|
+
return void 0;
|
|
19
|
+
}
|
|
20
|
+
const symbol = identifier.getSymbol();
|
|
21
|
+
const declarations = symbol?.getAliasedSymbol()?.getDeclarations() ?? symbol?.getDeclarations() ?? [];
|
|
22
|
+
for (const declaration of declarations) {
|
|
23
|
+
if (Node.isVariableDeclaration(declaration)) {
|
|
24
|
+
const initializer = declaration.getInitializer();
|
|
25
|
+
if (initializer && Node.isStringLiteral(initializer)) {
|
|
26
|
+
return initializer.getLiteralText();
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
return void 0;
|
|
31
|
+
};
|
|
16
32
|
const tableOf = (call) => {
|
|
17
33
|
const argument = call.getArguments()[0];
|
|
18
|
-
|
|
34
|
+
if (!argument) {
|
|
35
|
+
return "";
|
|
36
|
+
}
|
|
37
|
+
if (Node.isStringLiteral(argument)) {
|
|
38
|
+
return argument.getLiteralText();
|
|
39
|
+
}
|
|
40
|
+
return resolveStringConst(argument) ?? "";
|
|
19
41
|
};
|
|
20
42
|
const discoverInserts = (project, lunoraDirectory) => {
|
|
21
43
|
const writes = [];
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Node, SyntaxKind } from 'ts-morph';
|
|
2
|
-
import { listLunoraSourceFiles, lunoraRelativePath, classifyProcedureCall } from './discoverFunctions-
|
|
2
|
+
import { listLunoraSourceFiles, lunoraRelativePath, classifyProcedureCall } from './discoverFunctions-BWMczzBx.mjs';
|
|
3
3
|
|
|
4
4
|
const isMaskCall = (node) => {
|
|
5
5
|
if (!Node.isCallExpression(node)) {
|
package/dist/packem_shared/{discoverMigrations-Doj_-BAA.mjs → discoverMigrations-Bi5nJ0mJ.mjs}
RENAMED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { relative, sep } from 'node:path';
|
|
2
2
|
import { SyntaxKind, Node } from 'ts-morph';
|
|
3
|
-
import {
|
|
3
|
+
import { diagnosticAt } from './CodegenDiagnosticError-DeblMkzO.mjs';
|
|
4
|
+
import { listLunoraSourceFiles } from './discoverFunctions-BWMczzBx.mjs';
|
|
4
5
|
|
|
5
6
|
const TS_EXTENSION_RE = /\.ts$/u;
|
|
6
7
|
const isDefineMigration = (identifier) => {
|
|
@@ -43,9 +44,14 @@ const migrationFromDeclaration = (declaration, relativePath) => {
|
|
|
43
44
|
const id = stringProperty(argument, "id");
|
|
44
45
|
const exportName = declaration.getName();
|
|
45
46
|
if (id === void 0 || id.trim() === "") {
|
|
46
|
-
throw
|
|
47
|
-
|
|
48
|
-
|
|
47
|
+
throw diagnosticAt(
|
|
48
|
+
argument,
|
|
49
|
+
`Migration "${exportName}" in "${relativePath}" must declare \`id\` as a non-empty string literal so codegen can key the registry.`,
|
|
50
|
+
{
|
|
51
|
+
code: "MIGRATION_ID_NOT_STATIC",
|
|
52
|
+
name: "LunoraError",
|
|
53
|
+
status: 500
|
|
54
|
+
}
|
|
49
55
|
);
|
|
50
56
|
}
|
|
51
57
|
return { exportName, filePath: relativePath, id, table: stringProperty(argument, "table") ?? "" };
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Node, SyntaxKind } from 'ts-morph';
|
|
2
|
-
import { listLunoraSourceFiles, lunoraRelativePath, classifyProcedureCall } from './discoverFunctions-
|
|
2
|
+
import { listLunoraSourceFiles, lunoraRelativePath, classifyProcedureCall } from './discoverFunctions-BWMczzBx.mjs';
|
|
3
3
|
|
|
4
4
|
const PROPERTY_CALLS = {
|
|
5
5
|
"crypto.getRandomValues": "crypto.getRandomValues",
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { SyntaxKind, Node } from 'ts-morph';
|
|
2
|
-
import { listLunoraSourceFiles, lunoraRelativePath } from './discoverFunctions-
|
|
2
|
+
import { listLunoraSourceFiles, lunoraRelativePath } from './discoverFunctions-BWMczzBx.mjs';
|
|
3
3
|
|
|
4
4
|
const INDEX_METHODS = /* @__PURE__ */ new Set(["withIndex", "withSearchIndex"]);
|
|
5
5
|
const isDatabaseQueryCall = (call) => {
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
import { Node, SyntaxKind } from 'ts-morph';
|
|
2
|
+
import { listLunoraSourceFiles, lunoraRelativePath, classifyProcedureCall } from './discoverFunctions-BWMczzBx.mjs';
|
|
3
|
+
|
|
4
|
+
const handlerOf = (call, receiver) => {
|
|
5
|
+
if (receiver) {
|
|
6
|
+
const handler = call.getArguments()[0];
|
|
7
|
+
return handler && (Node.isArrowFunction(handler) || Node.isFunctionExpression(handler)) ? handler : void 0;
|
|
8
|
+
}
|
|
9
|
+
const first = call.getArguments()[0];
|
|
10
|
+
if (!first || !Node.isObjectLiteralExpression(first)) {
|
|
11
|
+
return void 0;
|
|
12
|
+
}
|
|
13
|
+
const handlerProperty = first.getProperty("handler");
|
|
14
|
+
if (!handlerProperty || !Node.isPropertyAssignment(handlerProperty)) {
|
|
15
|
+
return void 0;
|
|
16
|
+
}
|
|
17
|
+
const initializer = handlerProperty.getInitializer();
|
|
18
|
+
return initializer && (Node.isArrowFunction(initializer) || Node.isFunctionExpression(initializer)) ? initializer : void 0;
|
|
19
|
+
};
|
|
20
|
+
const exportedProcedureHandler = (declaration) => {
|
|
21
|
+
const initializer = declaration.getInitializer();
|
|
22
|
+
if (!initializer || !Node.isCallExpression(initializer)) {
|
|
23
|
+
return void 0;
|
|
24
|
+
}
|
|
25
|
+
const classified = classifyProcedureCall(initializer);
|
|
26
|
+
if (!classified || classified.kind !== "query" && classified.kind !== "mutation") {
|
|
27
|
+
return void 0;
|
|
28
|
+
}
|
|
29
|
+
const handler = handlerOf(initializer, classified.receiver);
|
|
30
|
+
return handler ? { exportName: declaration.getName(), handler, kind: classified.kind } : void 0;
|
|
31
|
+
};
|
|
32
|
+
const r2sqlCalleeOf = (access) => {
|
|
33
|
+
if (!Node.isPropertyAccessExpression(access) || access.getName() !== "r2sql") {
|
|
34
|
+
return void 0;
|
|
35
|
+
}
|
|
36
|
+
const receiver = access.getExpression();
|
|
37
|
+
if (!Node.isIdentifier(receiver) || receiver.getText() !== "ctx") {
|
|
38
|
+
return void 0;
|
|
39
|
+
}
|
|
40
|
+
const parent = access.getParent();
|
|
41
|
+
if (parent && Node.isPropertyAccessExpression(parent) && parent.getExpression() === access) {
|
|
42
|
+
return `ctx.r2sql.${parent.getName()}`;
|
|
43
|
+
}
|
|
44
|
+
return "ctx.r2sql";
|
|
45
|
+
};
|
|
46
|
+
const accessesInHandler = (procedure, file) => {
|
|
47
|
+
const found = [];
|
|
48
|
+
for (const access of procedure.handler.getDescendantsOfKind(SyntaxKind.PropertyAccessExpression)) {
|
|
49
|
+
const callee = r2sqlCalleeOf(access);
|
|
50
|
+
if (callee !== void 0) {
|
|
51
|
+
found.push({ callee, exportName: procedure.exportName, file, kind: procedure.kind, line: access.getStartLineNumber() });
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
return found;
|
|
55
|
+
};
|
|
56
|
+
const accessesInSourceFile = (sourceFile, relativePath) => {
|
|
57
|
+
const found = [];
|
|
58
|
+
for (const statement of sourceFile.getVariableStatements()) {
|
|
59
|
+
if (!statement.isExported()) {
|
|
60
|
+
continue;
|
|
61
|
+
}
|
|
62
|
+
for (const declaration of statement.getDeclarations()) {
|
|
63
|
+
const procedure = exportedProcedureHandler(declaration);
|
|
64
|
+
if (procedure) {
|
|
65
|
+
found.push(...accessesInHandler(procedure, relativePath));
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
return found;
|
|
70
|
+
};
|
|
71
|
+
const discoverR2sqlCalls = (project, lunoraDirectory) => {
|
|
72
|
+
const calls = [];
|
|
73
|
+
for (const filePath of listLunoraSourceFiles(lunoraDirectory)) {
|
|
74
|
+
const sourceFile = project.getSourceFile(filePath) ?? project.addSourceFileAtPath(filePath);
|
|
75
|
+
calls.push(...accessesInSourceFile(sourceFile, lunoraRelativePath(lunoraDirectory, filePath)));
|
|
76
|
+
}
|
|
77
|
+
return calls;
|
|
78
|
+
};
|
|
79
|
+
|
|
80
|
+
export { discoverR2sqlCalls as default };
|
package/dist/packem_shared/{discoverRlsMetadata-DpRB1HMe.mjs → discoverRlsMetadata-BS9GOGC5.mjs}
RENAMED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Node, SyntaxKind } from 'ts-morph';
|
|
2
|
-
import { listLunoraSourceFiles, lunoraRelativePath, classifyProcedureCall } from './discoverFunctions-
|
|
2
|
+
import { listLunoraSourceFiles, lunoraRelativePath, classifyProcedureCall } from './discoverFunctions-BWMczzBx.mjs';
|
|
3
3
|
|
|
4
4
|
const isRlsCall = (node) => {
|
|
5
5
|
if (!Node.isCallExpression(node)) {
|