@pattern-stack/codegen 0.17.2 → 0.19.0

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.
Files changed (68) hide show
  1. package/CHANGELOG.md +32 -0
  2. package/README.md +157 -2
  3. package/consumer-skills/codegen/SKILL.md +32 -0
  4. package/consumer-skills/entities/SKILL.md +2 -0
  5. package/dist/{chunk-I6UXRJ3Q.js → chunk-43SBT72G.js} +4 -4
  6. package/dist/{chunk-T6SCOJF4.js → chunk-7LKAMLV4.js} +4 -4
  7. package/dist/{chunk-IOQMMH6C.js → chunk-F7KN3U6U.js} +122 -8
  8. package/dist/chunk-F7KN3U6U.js.map +1 -0
  9. package/dist/{chunk-CZQUOIDY.js → chunk-J7JMVS2B.js} +4 -4
  10. package/dist/{chunk-KSTZIULO.js → chunk-K2I6XIK5.js} +4 -4
  11. package/dist/{chunk-ATVGYF3D.js → chunk-PKDS6QIJ.js} +7 -7
  12. package/dist/{chunk-KZDHMZ45.js → chunk-SNH35CNA.js} +8 -8
  13. package/dist/runtime/base-classes/index.js +24 -24
  14. package/dist/runtime/subsystems/analytics/analytics.module.js +2 -2
  15. package/dist/runtime/subsystems/analytics/index.js +4 -4
  16. package/dist/runtime/subsystems/auth/auth.module.js +3 -3
  17. package/dist/runtime/subsystems/auth/index.js +14 -14
  18. package/dist/runtime/subsystems/bridge/bridge-delivery.drizzle-backend.js +2 -2
  19. package/dist/runtime/subsystems/bridge/bridge-outbox-drain-hook.js +1 -1
  20. package/dist/runtime/subsystems/bridge/bridge.module.js +5 -5
  21. package/dist/runtime/subsystems/bridge/index.js +13 -13
  22. package/dist/runtime/subsystems/cache/cache.module.js +1 -1
  23. package/dist/runtime/subsystems/cache/index.js +3 -3
  24. package/dist/runtime/subsystems/index.js +94 -94
  25. package/dist/runtime/subsystems/integration/build-change-source.js +2 -2
  26. package/dist/runtime/subsystems/integration/index.js +36 -36
  27. package/dist/runtime/subsystems/integration/integration.module.js +4 -4
  28. package/dist/src/cli/index.js +1552 -254
  29. package/dist/src/cli/index.js.map +1 -1
  30. package/dist/src/index.d.ts +18 -0
  31. package/dist/src/index.js +12 -12
  32. package/package.json +1 -1
  33. package/src/config/locations.mjs +0 -6
  34. package/src/config/paths.mjs +0 -13
  35. package/templates/entity/new/prompt.js +12 -88
  36. package/dist/chunk-IOQMMH6C.js.map +0 -1
  37. package/templates/entity/new/frontend/_inject-entities-entry.ejs.t +0 -7
  38. package/templates/entity/new/frontend/_inject-entities-import.ejs.t +0 -7
  39. package/templates/entity/new/frontend/collections/_ensure-anchor-collections.ejs.t +0 -10
  40. package/templates/entity/new/frontend/collections/_inject-index.ejs.t +0 -9
  41. package/templates/entity/new/frontend/collections/_inject-schema-import.ejs.t +0 -9
  42. package/templates/entity/new/frontend/collections/collection.ejs.t +0 -86
  43. package/templates/entity/new/frontend/collections/collections-base.ejs.t +0 -35
  44. package/templates/entity/new/frontend/entity/collection.ejs.t +0 -173
  45. package/templates/entity/new/frontend/entity/combined.ejs.t +0 -505
  46. package/templates/entity/new/frontend/entity/fields.ejs.t +0 -105
  47. package/templates/entity/new/frontend/entity/hooks.ejs.t +0 -74
  48. package/templates/entity/new/frontend/entity/index.ejs.t +0 -22
  49. package/templates/entity/new/frontend/entity/mutation-hooks.ejs.t +0 -85
  50. package/templates/entity/new/frontend/entity/mutations.ejs.t +0 -39
  51. package/templates/entity/new/frontend/entity/types.ejs.t +0 -60
  52. package/templates/entity/new/frontend/generated/_inject-index-export.ejs.t +0 -7
  53. package/templates/entity/new/frontend/generated/_inject-index-import.ejs.t +0 -7
  54. package/templates/entity/new/frontend/generated/_inject-index-registry.ejs.t +0 -7
  55. package/templates/entity/new/frontend/store/_inject-collection-import.ejs.t +0 -9
  56. package/templates/entity/new/frontend/store/_inject-collections.ejs.t +0 -9
  57. package/templates/entity/new/frontend/store/_inject-entity.ejs.t +0 -9
  58. package/templates/entity/new/frontend/store/_inject-import.ejs.t +0 -9
  59. package/templates/entity/new/frontend/store/_inject-lookups.ejs.t +0 -9
  60. package/templates/entity/new/frontend/store/_inject-resolve.ejs.t +0 -10
  61. package/templates/entity/new/frontend/store/hooks.ejs.t +0 -73
  62. package/templates/entity/new/frontend/unified-entity.ejs.t +0 -29
  63. /package/dist/{chunk-I6UXRJ3Q.js.map → chunk-43SBT72G.js.map} +0 -0
  64. /package/dist/{chunk-T6SCOJF4.js.map → chunk-7LKAMLV4.js.map} +0 -0
  65. /package/dist/{chunk-CZQUOIDY.js.map → chunk-J7JMVS2B.js.map} +0 -0
  66. /package/dist/{chunk-KSTZIULO.js.map → chunk-K2I6XIK5.js.map} +0 -0
  67. /package/dist/{chunk-ATVGYF3D.js.map → chunk-PKDS6QIJ.js.map} +0 -0
  68. /package/dist/{chunk-KZDHMZ45.js.map → chunk-SNH35CNA.js.map} +0 -0
@@ -89,6 +89,13 @@ interface ParsedEntity {
89
89
  patternConfig?: Record<string, unknown>;
90
90
  /** Whether this entity is a valid scope target for job scoping (JOB-7). */
91
91
  scopeable?: boolean;
92
+ /**
93
+ * Which layers to generate (entity `expose:`, default
94
+ * `['repository', 'rest', 'trpc']`). The frontend field-metadata emitter
95
+ * (FE-3) derives write `capabilities` from whether `repository` or `trpc`
96
+ * is exposed.
97
+ */
98
+ expose: ('repository' | 'rest' | 'trpc' | 'electric')[];
92
99
  folderStructure: 'nested' | 'flat';
93
100
  fields: Map<string, ParsedField>;
94
101
  relationships: Map<string, ParsedRelationship>;
@@ -284,6 +291,7 @@ declare const EntityDefinitionSchema: z.ZodEffects<z.ZodEffects<z.ZodObject<{
284
291
  scopeable: z.ZodOptional<z.ZodBoolean>;
285
292
  surface: z.ZodOptional<z.ZodString>;
286
293
  context: z.ZodOptional<z.ZodString>;
294
+ sync: z.ZodOptional<z.ZodEnum<["api", "electric"]>>;
287
295
  }, "strict", z.ZodTypeAny, {
288
296
  name: string;
289
297
  table: string;
@@ -298,6 +306,7 @@ declare const EntityDefinitionSchema: z.ZodEffects<z.ZodEffects<z.ZodObject<{
298
306
  scopeable?: boolean | undefined;
299
307
  surface?: string | undefined;
300
308
  context?: string | undefined;
309
+ sync?: "electric" | "api" | undefined;
301
310
  }, {
302
311
  name: string;
303
312
  table: string;
@@ -312,6 +321,7 @@ declare const EntityDefinitionSchema: z.ZodEffects<z.ZodEffects<z.ZodObject<{
312
321
  scopeable?: boolean | undefined;
313
322
  surface?: string | undefined;
314
323
  context?: string | undefined;
324
+ sync?: "electric" | "api" | undefined;
315
325
  }>, {
316
326
  name: string;
317
327
  table: string;
@@ -326,6 +336,7 @@ declare const EntityDefinitionSchema: z.ZodEffects<z.ZodEffects<z.ZodObject<{
326
336
  scopeable?: boolean | undefined;
327
337
  surface?: string | undefined;
328
338
  context?: string | undefined;
339
+ sync?: "electric" | "api" | undefined;
329
340
  }, {
330
341
  name: string;
331
342
  table: string;
@@ -340,6 +351,7 @@ declare const EntityDefinitionSchema: z.ZodEffects<z.ZodEffects<z.ZodObject<{
340
351
  scopeable?: boolean | undefined;
341
352
  surface?: string | undefined;
342
353
  context?: string | undefined;
354
+ sync?: "electric" | "api" | undefined;
343
355
  }>;
344
356
  fields: z.ZodRecord<z.ZodString, z.ZodEffects<z.ZodEffects<z.ZodEffects<z.ZodEffects<z.ZodEffects<z.ZodEffects<z.ZodEffects<z.ZodEffects<z.ZodEffects<z.ZodEffects<z.ZodObject<{
345
357
  type: z.ZodEnum<["string", "integer", "decimal", "boolean", "uuid", "date", "datetime", "json", "entity_ref", "string_array", "enum"]>;
@@ -2076,6 +2088,7 @@ declare const EntityDefinitionSchema: z.ZodEffects<z.ZodEffects<z.ZodObject<{
2076
2088
  scopeable?: boolean | undefined;
2077
2089
  surface?: string | undefined;
2078
2090
  context?: string | undefined;
2091
+ sync?: "electric" | "api" | undefined;
2079
2092
  };
2080
2093
  behaviors: (string | {
2081
2094
  name: string;
@@ -2286,6 +2299,7 @@ declare const EntityDefinitionSchema: z.ZodEffects<z.ZodEffects<z.ZodObject<{
2286
2299
  scopeable?: boolean | undefined;
2287
2300
  surface?: string | undefined;
2288
2301
  context?: string | undefined;
2302
+ sync?: "electric" | "api" | undefined;
2289
2303
  };
2290
2304
  relationships?: Record<string, {
2291
2305
  type: "belongs_to" | "has_many" | "has_one";
@@ -2496,6 +2510,7 @@ declare const EntityDefinitionSchema: z.ZodEffects<z.ZodEffects<z.ZodObject<{
2496
2510
  scopeable?: boolean | undefined;
2497
2511
  surface?: string | undefined;
2498
2512
  context?: string | undefined;
2513
+ sync?: "electric" | "api" | undefined;
2499
2514
  };
2500
2515
  behaviors: (string | {
2501
2516
  name: string;
@@ -2706,6 +2721,7 @@ declare const EntityDefinitionSchema: z.ZodEffects<z.ZodEffects<z.ZodObject<{
2706
2721
  scopeable?: boolean | undefined;
2707
2722
  surface?: string | undefined;
2708
2723
  context?: string | undefined;
2724
+ sync?: "electric" | "api" | undefined;
2709
2725
  };
2710
2726
  relationships?: Record<string, {
2711
2727
  type: "belongs_to" | "has_many" | "has_one";
@@ -2916,6 +2932,7 @@ declare const EntityDefinitionSchema: z.ZodEffects<z.ZodEffects<z.ZodObject<{
2916
2932
  scopeable?: boolean | undefined;
2917
2933
  surface?: string | undefined;
2918
2934
  context?: string | undefined;
2935
+ sync?: "electric" | "api" | undefined;
2919
2936
  };
2920
2937
  behaviors: (string | {
2921
2938
  name: string;
@@ -3126,6 +3143,7 @@ declare const EntityDefinitionSchema: z.ZodEffects<z.ZodEffects<z.ZodObject<{
3126
3143
  scopeable?: boolean | undefined;
3127
3144
  surface?: string | undefined;
3128
3145
  context?: string | undefined;
3146
+ sync?: "electric" | "api" | undefined;
3129
3147
  };
3130
3148
  relationships?: Record<string, {
3131
3149
  type: "belongs_to" | "has_many" | "has_one";
package/dist/src/index.js CHANGED
@@ -44,27 +44,27 @@ import {
44
44
  validateOrchestrationProject,
45
45
  validatePatternComposition,
46
46
  validatePatternProject
47
- } from "../chunk-IOQMMH6C.js";
47
+ } from "../chunk-F7KN3U6U.js";
48
48
  import "../chunk-KVOWSC5S.js";
49
- import "../chunk-ATVGYF3D.js";
49
+ import "../chunk-PKDS6QIJ.js";
50
+ import "../chunk-PRWIX6UW.js";
50
51
  import "../chunk-YK5JEVLX.js";
51
52
  import "../chunk-EO2QPOKH.js";
52
- import "../chunk-PRWIX6UW.js";
53
- import "../chunk-XWBK3XJK.js";
54
- import "../chunk-AHV4GDYM.js";
55
53
  import "../chunk-SQDOBLBP.js";
56
- import "../chunk-JEINYUJH.js";
57
- import "../chunk-5TK7MEN4.js";
58
- import "../chunk-4KNXX6TI.js";
59
- import "../chunk-3CJFPU6Q.js";
60
54
  import "../chunk-TDEHU73T.js";
55
+ import "../chunk-LG57S2SC.js";
56
+ import "../chunk-XWBK3XJK.js";
61
57
  import "../chunk-S7C6TIIF.js";
62
58
  import "../chunk-MZ6GV4YF.js";
63
- import "../chunk-LG57S2SC.js";
64
59
  import "../chunk-HNWZFNKP.js";
65
- import "../chunk-I6UXRJ3Q.js";
66
- import "../chunk-TIZXQU26.js";
60
+ import "../chunk-AHV4GDYM.js";
61
+ import "../chunk-43SBT72G.js";
67
62
  import "../chunk-4MF3HKJA.js";
63
+ import "../chunk-TIZXQU26.js";
64
+ import "../chunk-JEINYUJH.js";
65
+ import "../chunk-5TK7MEN4.js";
66
+ import "../chunk-4KNXX6TI.js";
67
+ import "../chunk-3CJFPU6Q.js";
68
68
  import "../chunk-U64T4YZE.js";
69
69
  import "../chunk-2E224ZSN.js";
70
70
  export {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pattern-stack/codegen",
3
- "version": "0.17.2",
3
+ "version": "0.19.0",
4
4
  "description": "Entity-driven code generation for full-stack TypeScript applications",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -113,12 +113,6 @@ const DEFAULT_LOCATIONS = {
113
113
  import: '@/generated/entity-metadata',
114
114
  },
115
115
 
116
- /** Field meta type definitions */
117
- frontendFieldMetaTypes: {
118
- path: 'apps/frontend/src/lib/types',
119
- import: '@/lib/types',
120
- },
121
-
122
116
  /** Auth helpers (for collections) */
123
117
  frontendCollectionsAuth: {
124
118
  path: 'apps/frontend/src/lib/collections/auth',
@@ -611,18 +611,6 @@ export function getProjectConfig() {
611
611
  return projectConfig;
612
612
  }
613
613
 
614
- /**
615
- * Get pipelines configuration from project config.
616
- * Returns the pipelines block (or an empty object if not configured).
617
- *
618
- * Usage:
619
- * const pipelines = getPipelinesConfig();
620
- * const arch = pipelines?.backend?.architecture ?? 'clean';
621
- */
622
- export function getPipelinesConfig() {
623
- return projectConfig?.pipelines ?? {};
624
- }
625
-
626
614
  /**
627
615
  * Resolve the directory codegen writes barrel files to (modules.ts, schema.ts).
628
616
  *
@@ -681,7 +669,6 @@ export default {
681
669
  getLayoutConfig,
682
670
  getDatabaseDialect,
683
671
  getProjectConfig,
684
- getPipelinesConfig,
685
672
  getGenerateConfig,
686
673
  getGeneratedDir,
687
674
  // NEW: Config-driven naming functions
@@ -20,7 +20,6 @@ import {
20
20
  getLayoutConfig,
21
21
  getDatabaseDialect,
22
22
  getProjectConfig,
23
- getPipelinesConfig,
24
23
  getGenerateConfig,
25
24
  } from "../../../src/config/paths.mjs";
26
25
  import { getNamingConfig } from "../../../src/config/naming-config.mjs";
@@ -303,10 +302,6 @@ export default {
303
302
  // specifier the generated entity code carries.
304
303
  const runtimeMode = loadRuntimeMode(process.cwd());
305
304
 
306
- // Load frontend config from project config (used for auth, sync, parsers)
307
- const frontendConfig = getProjectConfig()?.frontend ?? {};
308
- const frontendSync = frontendConfig.sync ?? {};
309
-
310
305
  // Prepare locals for templates
311
306
  const entity = definition.entity;
312
307
  const fields = definition.fields || {};
@@ -463,12 +458,6 @@ export default {
463
458
  const camelName = camelCase(name); // opportunity
464
459
  const repositoryToken = `${pascalCase(name).toUpperCase()}_REPOSITORY`; // OPPORTUNITY_REPOSITORY
465
460
 
466
- // Frontend store naming
467
- const singularCamelName = camelCase(name); // "dealState" from "deal_state"
468
- const pluralCamelName = camelCase(plural); // "dealStates" from "deal_states"
469
- const collectionVarName = singularCamelName + "Collection"; // "dealStateCollection"
470
- const collectionVarNamePlural = pluralCamelName + "Collection"; // "dealStatesCollection"
471
-
472
461
  // Layout configuration (folder structure + file grouping)
473
462
  // See tools/codegen/config/paths.js for options
474
463
  const layout = getLayoutConfig(entity);
@@ -1026,7 +1015,6 @@ export default {
1026
1015
  const architectureTarget = generateConfig.architecture;
1027
1016
  const isCleanArchitecture = architectureTarget === 'clean';
1028
1017
  const isCleanLitePs = architectureTarget === 'clean-lite-ps';
1029
- const frontendEnabled = generateConfig.frontend === true;
1030
1018
 
1031
1019
  // ============================================================================
1032
1020
  // v2: Queries
@@ -1452,12 +1440,6 @@ export default {
1452
1440
  camelName,
1453
1441
  repositoryToken,
1454
1442
 
1455
- // Frontend store naming
1456
- singularCamelName,
1457
- pluralCamelName,
1458
- collectionVarName,
1459
- collectionVarNamePlural,
1460
-
1461
1443
  // Fields
1462
1444
  fields: processedFields,
1463
1445
  requiredFields,
@@ -1510,50 +1492,11 @@ export default {
1510
1492
  // Usage: locations.dbEntities.path, locations.dbEntities.import
1511
1493
  locations: LOCATIONS,
1512
1494
 
1513
- // Frontend configuration
1514
- // Note: Use hasOwnProperty checks for values where null is meaningful (disables the feature)
1515
- frontend: {
1516
- auth: {
1517
- // null means "no auth function" - don't fall back to default
1518
- function: frontendConfig.auth?.hasOwnProperty?.('function')
1519
- ? frontendConfig.auth.function
1520
- : 'getAuthorizationHeader',
1521
- },
1522
- sync: {
1523
- // Read transport for the generated collection:
1524
- // 'electric' (default) → electricCollectionOptions (real-time shape sync)
1525
- // 'api' → queryCollectionOptions (REST via TanStack Query)
1526
- // Additive + default-off: existing consumers are unaffected. The rest of
1527
- // the store (hooks/useLiveQuery, resolve, mutations) is mode-agnostic.
1528
- mode: frontendSync.mode ?? 'electric',
1529
- // 'api' mode only: REST base path; the list endpoint is `${apiUrl}/${plural}`
1530
- // (or `${API_BASE_URL}/${plural}` when apiBaseUrlImport is set).
1531
- apiUrl: frontendSync.apiUrl ?? '/api',
1532
- // 'api' mode only: import path for the shared TanStack QueryClient.
1533
- // null → a sibling './query-client' is assumed (consumer-provided).
1534
- queryClientImport: frontendSync.queryClientImport ?? null,
1535
- shapeUrl: frontendSync.shapeUrl ?? '/v1/shape',
1536
- useTableParam: frontendSync.useTableParam ?? true,
1537
- // Column mapper for snake_case to camelCase conversion (e.g., 'snakeCamelMapper')
1538
- // Set to null/undefined if DB columns already match JS property names
1539
- columnMapper: frontendSync.hasOwnProperty?.('columnMapper')
1540
- ? frontendSync.columnMapper
1541
- : 'snakeCamelMapper',
1542
- // Whether to wrap shapeUrl in new URL() constructor
1543
- wrapInUrlConstructor: frontendSync.wrapInUrlConstructor ?? true,
1544
- // Whether columnMapper needs () to call (true for functions, false for objects)
1545
- columnMapperNeedsCall: frontendSync.columnMapperNeedsCall ?? true,
1546
- // Import path for API_BASE_URL (if needed)
1547
- apiBaseUrlImport: frontendSync.apiBaseUrlImport ?? null,
1548
- },
1549
- parsers: frontendConfig.parsers ?? {
1550
- timestamptz: '(date: string) => new Date(date)',
1551
- },
1552
- collections: {
1553
- // Schema prefix: 'schema.' for namespace import, '' for direct import
1554
- schemaPrefix: frontendConfig.collections?.schemaPrefix ?? 'schema.',
1555
- },
1556
- },
1495
+ // NOTE: the `frontend:` locals block (auth/sync/parsers/collections) was
1496
+ // deleted with the hygen frontend templates (FE-3). The frontend emitter
1497
+ // (src/emitters/frontend/) now reads `frontend.*` from codegen.config.yaml
1498
+ // directly into its own FrontendEmitConfig — no template ever consumed
1499
+ // these locals after the templates were removed.
1557
1500
 
1558
1501
  // Naming configuration (for templates that need it)
1559
1502
  namingConfig,
@@ -1567,15 +1510,14 @@ export default {
1567
1510
  getByIdQueryClass,
1568
1511
  listQueryClass,
1569
1512
 
1570
- // Generation toggles (what to generate)
1513
+ // Generation toggles (backend only — what to generate).
1514
+ //
1515
+ // The frontend toggles (fieldMetadata/collections/collectionsIndex/hooks/
1516
+ // mutations/hookStyle/structure/typeNaming/fkResolution/collectionNaming/
1517
+ // fileNaming/hookReturnStyle) were deleted with the hygen frontend
1518
+ // templates (FE-3). The frontend tree is now emitted by
1519
+ // src/emitters/frontend/ and gated solely by `generate.frontend`.
1571
1520
  generate: {
1572
- fieldMetadata: getProjectConfig()?.generate?.fieldMetadata ?? true,
1573
- collections: getProjectConfig()?.generate?.collections ?? true,
1574
- // Whether to generate index.ts in collections folder (for multi-file collection structure)
1575
- collectionsIndex: getProjectConfig()?.generate?.collectionsIndex ?? false,
1576
- hooks: getProjectConfig()?.generate?.hooks ?? true,
1577
- mutations: getProjectConfig()?.generate?.mutations ?? true,
1578
- // Backend toggles
1579
1521
  drizzleSchema: getProjectConfig()?.generate?.drizzleSchema ?? true,
1580
1522
  commands: getProjectConfig()?.generate?.commands ?? true,
1581
1523
  queries: getProjectConfig()?.generate?.queries ?? true,
@@ -1583,23 +1525,6 @@ export default {
1583
1525
  schemaServer: getProjectConfig()?.generate?.schemaServer ?? false,
1584
1526
  schemaClient: getProjectConfig()?.generate?.schemaClient ?? false,
1585
1527
  electricMigrations: getProjectConfig()?.generate?.electricMigrations ?? false,
1586
- // Hook style: 'collection' uses collection.useMany(), 'useLiveQuery' uses TanStack DB pattern
1587
- hookStyle: getProjectConfig()?.generate?.hookStyle ?? 'collection',
1588
- // Output structure mode: 'entity-first' | 'concern-first' | 'monolithic'
1589
- // entity-first: generated/{entity}/types.ts, collection.ts, hooks.ts...
1590
- // concern-first: generated/types/{entity}.ts, collections/{entity}.ts...
1591
- // monolithic: generated/{entity}.ts (single file per entity)
1592
- structure: getProjectConfig()?.generate?.structure ?? 'monolithic',
1593
- // Type naming: 'plain' = Opportunity, 'entity' = OpportunityEntity
1594
- typeNaming: getProjectConfig()?.generate?.typeNaming ?? 'plain',
1595
- // FK resolution: true = import related collections, false = skip (useful when collections don't exist)
1596
- fkResolution: getProjectConfig()?.generate?.fkResolution ?? true,
1597
- // Collection variable naming: 'singular' = opportunityCollection, 'plural' = opportunitiesCollection
1598
- collectionNaming: getProjectConfig()?.generate?.collectionNaming ?? 'singular',
1599
- // File naming: 'singular' = opportunity.ts, 'plural' = opportunities.ts
1600
- fileNaming: getProjectConfig()?.generate?.fileNaming ?? 'singular',
1601
- // Hook return style: 'generic' = { data }, 'named' = { opportunities }
1602
- hookReturnStyle: getProjectConfig()?.generate?.hookReturnStyle ?? 'generic',
1603
1528
  },
1604
1529
 
1605
1530
  // Pre-computed output paths for templates (avoids ternary in YAML frontmatter)
@@ -1643,7 +1568,6 @@ export default {
1643
1568
  architectureTarget,
1644
1569
  isCleanArchitecture,
1645
1570
  isCleanLitePs,
1646
- frontendEnabled,
1647
1571
 
1648
1572
  // Queries
1649
1573
  hasQueries,