@lunora/codegen 1.0.0-alpha.25 → 1.0.0-alpha.27

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.mjs CHANGED
@@ -19,11 +19,11 @@ export { default as discoverSchema } from './packem_shared/discoverSchema-KYq55q
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-BullHnLo.mjs';
23
- export { emitApp } from './packem_shared/emitApp-BUN7hhlY.mjs';
24
- export { buildOpenApiDocument, emitOpenApi, emitOpenApiModule } from './packem_shared/buildOpenApiDocument-Bm56LsBb.mjs';
25
- export { OPENRPC_VERSION, buildOpenRpcDocument, emitOpenRpc, emitOpenRpcModule } from './packem_shared/OPENRPC_VERSION-D7MAVX3K.mjs';
26
- export { SCHEMA_SNAPSHOT_FILENAME, createCodegenProject, refreshCodegenProject, runCodegen } from './packem_shared/SCHEMA_SNAPSHOT_FILENAME-BAcxxSdB.mjs';
22
+ export { GENERATED_HEADER, emitApi, emitCollections, emitContainers, emitCrons, emitDataModel, emitDrizzleSchema, emitFunctions, emitServer, emitShard, emitVectors, emitWorkflows, emitWranglerCronTriggers } from './packem_shared/GENERATED_HEADER-CYaSI_qY.mjs';
23
+ export { emitApp } from './packem_shared/emitApp-C38fHt_1.mjs';
24
+ export { buildOpenApiDocument, emitOpenApi, emitOpenApiModule } from './packem_shared/buildOpenApiDocument-BlpXQe2K.mjs';
25
+ export { OPENRPC_VERSION, buildOpenRpcDocument, emitOpenRpc, emitOpenRpcModule } from './packem_shared/OPENRPC_VERSION-CRe5l79E.mjs';
26
+ export { SCHEMA_SNAPSHOT_FILENAME, createCodegenProject, refreshCodegenProject, runCodegen } from './packem_shared/SCHEMA_SNAPSHOT_FILENAME-B3TwY0JD.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';
@@ -2054,7 +2054,10 @@ const emitShard = ({
2054
2054
  const maskData = maskMetadata ?? { columns: [] };
2055
2055
  const storageRulesData = storageRules ?? { rules: [] };
2056
2056
  const studioFeaturesData = studioFeatures ?? {
2057
+ analytics: false,
2058
+ auth: false,
2057
2059
  flags: false,
2060
+ kv: false,
2058
2061
  mail: false,
2059
2062
  payments: false,
2060
2063
  queues: false,
@@ -1,4 +1,4 @@
1
- import { GENERATED_HEADER } from './GENERATED_HEADER-BullHnLo.mjs';
1
+ import { GENERATED_HEADER } from './GENERATED_HEADER-CYaSI_qY.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
 
@@ -24,10 +24,10 @@ import { discoverShapes } from './SHAPES_FILENAME-ChV7MqgE.mjs';
24
24
  import discoverStorageRulesMetadata from './discoverStorageRulesMetadata-Da8BKXcI.mjs';
25
25
  import { e as enclosingExportName$1 } from './discover-ast-CT6BgBr4.mjs';
26
26
  import { discoverWorkflows } from './WORKFLOWS_FILENAME-CCisG0Vy.mjs';
27
- import { buildStorageColumns, emitDataModel, emitApi, emitServer, emitFunctions, emitShard, emitCollections, emitContainers, emitWorkflows, emitQueues, emitCrons, emitVectors, emitDrizzleSchema, emitSeed, emitWranglerCronTriggers } from './GENERATED_HEADER-BullHnLo.mjs';
28
- import { emitApp } from './emitApp-BUN7hhlY.mjs';
29
- import { buildOpenApiDocument, emitOpenApiModule } from './buildOpenApiDocument-Bm56LsBb.mjs';
30
- import { buildOpenRpcDocument, emitOpenRpcModule } from './OPENRPC_VERSION-D7MAVX3K.mjs';
27
+ import { buildStorageColumns, emitDataModel, emitApi, emitServer, emitFunctions, emitShard, emitCollections, emitContainers, emitWorkflows, emitQueues, emitCrons, emitVectors, emitDrizzleSchema, emitSeed, emitWranglerCronTriggers } from './GENERATED_HEADER-CYaSI_qY.mjs';
28
+ import { emitApp } from './emitApp-C38fHt_1.mjs';
29
+ import { buildOpenApiDocument, emitOpenApiModule } from './buildOpenApiDocument-BlpXQe2K.mjs';
30
+ import { buildOpenRpcDocument, emitOpenRpcModule } from './OPENRPC_VERSION-CRe5l79E.mjs';
31
31
  import { buildSchemaSnapshot, serializeSchemaSnapshot } from './SCHEMA_SNAPSHOT_VERSION-wWGP2_5E.mjs';
32
32
 
33
33
  const HTTP_VERBS = /* @__PURE__ */ new Set(["delete", "get", "head", "options", "patch", "post", "put"]);
@@ -268,20 +268,28 @@ const PROBES = {
268
268
  vectors: { contextProperty: "vectors", moduleSpecifier: "@lunora/bindings/vectors" },
269
269
  workflows: { contextProperty: "workflows", moduleSpecifier: "@lunora/workflow" }
270
270
  };
271
- const readsContextProperty = (sourceFile, property) => {
271
+ const contextPropertiesRead = (sourceFile) => {
272
272
  const reachesContext = (receiver) => Node.isIdentifier(receiver) && receiver.getText() === "ctx";
273
- const directAccess = sourceFile.getDescendantsOfKind(SyntaxKind.PropertyAccessExpression).some((access) => access.getName() === property && reachesContext(access.getExpression()));
274
- if (directAccess) {
275
- return true;
273
+ const names = /* @__PURE__ */ new Set();
274
+ for (const access of sourceFile.getDescendantsOfKind(SyntaxKind.PropertyAccessExpression)) {
275
+ if (reachesContext(access.getExpression())) {
276
+ names.add(access.getName());
277
+ }
276
278
  }
277
- return sourceFile.getDescendantsOfKind(SyntaxKind.VariableDeclaration).some((declaration) => {
279
+ for (const declaration of sourceFile.getDescendantsOfKind(SyntaxKind.VariableDeclaration)) {
278
280
  const initializer = declaration.getInitializer();
279
281
  const nameNode = declaration.getNameNode();
280
282
  if (initializer === void 0 || !reachesContext(initializer) || !Node.isObjectBindingPattern(nameNode)) {
281
- return false;
283
+ continue;
282
284
  }
283
- return nameNode.getElements().some((element) => element.getPropertyNameNode()?.getText() === property || element.getName() === property);
284
- });
285
+ for (const element of nameNode.getElements()) {
286
+ const name = element.getPropertyNameNode()?.getText() ?? element.getName();
287
+ if (name) {
288
+ names.add(name);
289
+ }
290
+ }
291
+ }
292
+ return names;
285
293
  };
286
294
  const discoverFeatureUsage = (project, lunoraDirectory) => {
287
295
  const usage = {
@@ -306,6 +314,7 @@ const discoverFeatureUsage = (project, lunoraDirectory) => {
306
314
  for (const filePath of listLunoraSourceFiles(lunoraDirectory)) {
307
315
  const sourceFile = project.getSourceFile(filePath) ?? project.addSourceFileAtPath(filePath);
308
316
  const importSpecifiers = new Set(sourceFile.getImportDeclarations().map((declaration) => declaration.getModuleSpecifierValue()));
317
+ const contextProperties = contextPropertiesRead(sourceFile);
309
318
  for (const key of keys) {
310
319
  if (usage[key]) {
311
320
  continue;
@@ -315,7 +324,7 @@ const discoverFeatureUsage = (project, lunoraDirectory) => {
315
324
  usage[key] = true;
316
325
  continue;
317
326
  }
318
- if (probe.contextProperty !== void 0 && readsContextProperty(sourceFile, probe.contextProperty)) {
327
+ if (probe.contextProperty !== void 0 && contextProperties.has(probe.contextProperty)) {
319
328
  usage[key] = true;
320
329
  }
321
330
  }
@@ -327,7 +336,10 @@ const discoverFeatureUsage = (project, lunoraDirectory) => {
327
336
  };
328
337
  const buildStudioFeatures = (usage, signals) => {
329
338
  return {
339
+ analytics: usage.analytics || signals.dependencies.has("@lunora/bindings/analytics"),
340
+ auth: signals.dependencies.has("@lunora/auth"),
330
341
  flags: usage.flags || signals.dependencies.has("@lunora/flags"),
342
+ kv: usage.kv || signals.dependencies.has("@lunora/bindings/kv"),
331
343
  mail: usage.mail || signals.dependencies.has("@lunora/mail"),
332
344
  payments: usage.payments || signals.dependencies.has("@lunora/payment"),
333
345
  queues: signals.queueCount > 0 || signals.dependencies.has("@lunora/queue"),
@@ -1021,7 +1033,11 @@ const runCodegen = (options) => {
1021
1033
  hasHyperdrive,
1022
1034
  hasHyperdriveGlobal: schema.tables.some((table) => table.shardMode === "global" && table.globalBackend === "hyperdrive"),
1023
1035
  hasImages,
1024
- hasKv,
1036
+ // Auto-wire the studio's KV introspector on the SAME condition the nav
1037
+ // gates its tab on (`studioFeatures.kv` = ctx.kv usage OR a declared
1038
+ // `@lunora/bindings/kv` dep), so a visible KV tab always has a working
1039
+ // backend — never the reverse. The `ctx.kv` type-seam stays usage-only.
1040
+ hasKv: studioFeatures.kv,
1025
1041
  hasPayments,
1026
1042
  hasR2sql,
1027
1043
  hasQueue: queues.some((queue) => queue.mode === "push"),
@@ -1,4 +1,4 @@
1
- import { GENERATED_HEADER } from './GENERATED_HEADER-BullHnLo.mjs';
1
+ import { GENERATED_HEADER } from './GENERATED_HEADER-CYaSI_qY.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
 
@@ -1,4 +1,4 @@
1
- import { GENERATED_HEADER } from './GENERATED_HEADER-BullHnLo.mjs';
1
+ import { GENERATED_HEADER } from './GENERATED_HEADER-CYaSI_qY.mjs';
2
2
 
3
3
  const LONG_TAIL = [
4
4
  ["hasAi", "ai", "ai", "Override the Workers AI binding backing `ctx.ai` (defaults to `env.AI`)."],
@@ -27,6 +27,7 @@ const buildAccessImports = (hasAccess, hasAuth) => hasAccess ? [
27
27
  `import type { CreateAccessResolverOptions } from "@lunora/cloudflare-access";`,
28
28
  `import { createAccessResolver${hasAuth ? ", composeResolvers" : ""} } from "@lunora/cloudflare-access";`
29
29
  ] : [];
30
+ const buildKvImports = (hasKv) => hasKv ? [`import { createKvIntrospectorFromEnv } from "@lunora/bindings/kv";`] : [];
30
31
  const buildImportLines = (options) => {
31
32
  const {
32
33
  hasAccess,
@@ -34,6 +35,7 @@ const buildImportLines = (options) => {
34
35
  hasFramework,
35
36
  hasGlobal,
36
37
  hasHyperdriveGlobal,
38
+ hasKv,
37
39
  hasQueue,
38
40
  hasScheduler,
39
41
  hasStorage,
@@ -70,6 +72,7 @@ const buildImportLines = (options) => {
70
72
  `import { createHyperdriveGlobalCtxDb } from "@lunora/hyperdrive/global";`,
71
73
  `import type { SqlCtxDbOptions, SqlExec } from "@lunora/sql-store";`
72
74
  ] : [],
75
+ ...buildKvImports(hasKv),
73
76
  ...hasScheduler ? [`import type { DurableObjectNamespaceLike } from "@lunora/scheduler";`, `import { createScheduler } from "@lunora/scheduler";`] : [],
74
77
  ...hasStorage ? [`import type { R2BucketLike, Storage } from "@lunora/storage";`, `import { createBucketStorage, createStorage } from "@lunora/storage";`] : [],
75
78
  ...hasWorkflow ? [`import { createWorkflowsRestClient } from "@lunora/workflow";`] : [],
@@ -351,6 +354,12 @@ const buildWorkerOptionLines = (options) => [
351
354
  Object.assign(options, this.buildStorageAdmin(env));
352
355
  }`
353
356
  ] : [],
357
+ // The studio's KV browser is wired zero-config: `createKvIntrospectorFromEnv`
358
+ // scans `env` for every bound Workers KV namespace, so each `kv_namespaces`
359
+ // entry in wrangler.jsonc appears under its binding name (any name, any count)
360
+ // with no manual `createKvIntrospector` call. A deployment with no KV binding
361
+ // yields an empty namespace list rather than crashing.
362
+ ...options.hasKv ? [` options.kvIntrospector = createKvIntrospectorFromEnv(env);`] : [],
354
363
  ...options.hasAuth ? [
355
364
  ` if (this.authDeclaration) {
356
365
  options.authHandler = (request) => {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lunora/codegen",
3
- "version": "1.0.0-alpha.25",
3
+ "version": "1.0.0-alpha.27",
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.14",
49
+ "@lunora/advisor": "1.0.0-alpha.15",
50
50
  "@lunora/container": "1.0.0-alpha.5",
51
51
  "@lunora/queue": "1.0.0-alpha.2",
52
52
  "@lunora/scheduler": "1.0.0-alpha.4",