@pattern-stack/codegen 0.20.1 → 0.21.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 (100) hide show
  1. package/CHANGELOG.md +95 -0
  2. package/dist/{chunk-VNBC3VXM.js → chunk-3A34R6CI.js} +7 -7
  3. package/dist/{chunk-I6UXRJ3Q.js → chunk-43SBT72G.js} +4 -4
  4. package/dist/{chunk-BK5ICA2F.js → chunk-4MVGAMUA.js} +4 -4
  5. package/dist/{chunk-KK5A7B2T.js → chunk-524YKITE.js} +134 -20
  6. package/dist/chunk-524YKITE.js.map +1 -0
  7. package/dist/{chunk-P7EZCTIN.js → chunk-6CJRZHV4.js} +11 -11
  8. package/dist/{chunk-COGHTKXY.js → chunk-7625PLY7.js} +4 -4
  9. package/dist/{chunk-5RT7JGKT.js → chunk-7OVCARTQ.js} +4 -4
  10. package/dist/{chunk-BHZP6LOV.js → chunk-CDLWYZVQ.js} +7 -7
  11. package/dist/{chunk-W2UIDI3R.js → chunk-CLWBNXKF.js} +4 -4
  12. package/dist/{chunk-AODME4YK.js → chunk-EEJC66ZF.js} +6 -6
  13. package/dist/{chunk-YK5JEVLX.js → chunk-FFUDEIFF.js} +6 -6
  14. package/dist/{chunk-VOYFPR3S.js → chunk-G3IKPDTP.js} +4 -4
  15. package/dist/chunk-G3IKPDTP.js.map +1 -0
  16. package/dist/{chunk-AJILKWGO.js → chunk-GMRTI7AK.js} +13 -13
  17. package/dist/{chunk-4OC5MSHO.js → chunk-GOO5ZMYO.js} +4 -4
  18. package/dist/{chunk-M3TIZGIB.js → chunk-GV337QP3.js} +9 -9
  19. package/dist/{chunk-CZQUOIDY.js → chunk-J7JMVS2B.js} +4 -4
  20. package/dist/{chunk-SZYZ4SHF.js → chunk-MBFSG4KQ.js} +10 -10
  21. package/dist/{chunk-T6SCOJF4.js → chunk-NXHL5YII.js} +4 -4
  22. package/dist/{chunk-XWBK3XJK.js → chunk-O2A6XHGD.js} +4 -4
  23. package/dist/{chunk-ATVGYF3D.js → chunk-QFUIE37H.js} +3 -3
  24. package/dist/{chunk-SGSWVNNB.js → chunk-R6F6KFIL.js} +7 -7
  25. package/dist/{chunk-MB5VVG4Z.js → chunk-TKU6VYG3.js} +11 -11
  26. package/dist/{chunk-DUMI2J5M.js → chunk-VQOAATIG.js} +4 -4
  27. package/dist/{chunk-E45CSC33.js → chunk-XKWOJZZ4.js} +2 -2
  28. package/dist/{chunk-MVKW2BCR.js → chunk-YULGWXCY.js} +4 -4
  29. package/dist/{chunk-HCAKMT64.js → chunk-YXI7K4MJ.js} +8 -8
  30. package/dist/runtime/base-classes/index.js +17 -17
  31. package/dist/runtime/subsystems/analytics/analytics.module.js +2 -2
  32. package/dist/runtime/subsystems/analytics/index.js +4 -4
  33. package/dist/runtime/subsystems/auth/auth.module.js +3 -3
  34. package/dist/runtime/subsystems/auth/index.js +7 -7
  35. package/dist/runtime/subsystems/bridge/bridge-delivery-handler.js +3 -3
  36. package/dist/runtime/subsystems/bridge/bridge-delivery.drizzle-backend.js +3 -3
  37. package/dist/runtime/subsystems/bridge/bridge-outbox-drain-hook.js +7 -7
  38. package/dist/runtime/subsystems/bridge/bridge.module.js +19 -19
  39. package/dist/runtime/subsystems/bridge/event-flow.service.js +2 -2
  40. package/dist/runtime/subsystems/bridge/index.js +23 -23
  41. package/dist/runtime/subsystems/cache/cache.module.js +2 -2
  42. package/dist/runtime/subsystems/cache/index.js +4 -4
  43. package/dist/runtime/subsystems/events/event-bus.drizzle-backend.js +3 -3
  44. package/dist/runtime/subsystems/events/event-bus.memory-backend.js +2 -2
  45. package/dist/runtime/subsystems/events/events.module.d.ts +24 -7
  46. package/dist/runtime/subsystems/events/events.module.js +5 -5
  47. package/dist/runtime/subsystems/events/index.js +7 -7
  48. package/dist/runtime/subsystems/index.js +75 -75
  49. package/dist/runtime/subsystems/integration/build-change-source.js +2 -2
  50. package/dist/runtime/subsystems/integration/index.js +22 -22
  51. package/dist/runtime/subsystems/integration/integration-cursor-store.drizzle-backend.js +2 -2
  52. package/dist/runtime/subsystems/integration/integration-run-recorder.drizzle-backend.js +2 -2
  53. package/dist/runtime/subsystems/integration/integration.module.js +4 -4
  54. package/dist/runtime/subsystems/jobs/index.js +43 -43
  55. package/dist/runtime/subsystems/jobs/job-orchestrator.bullmq-backend.js +8 -8
  56. package/dist/runtime/subsystems/jobs/job-orchestrator.drizzle-backend.js +4 -4
  57. package/dist/runtime/subsystems/jobs/job-orchestrator.memory-backend.js +2 -2
  58. package/dist/runtime/subsystems/jobs/job-run-service.drizzle-backend.js +3 -3
  59. package/dist/runtime/subsystems/jobs/job-run-service.memory-backend.js +2 -2
  60. package/dist/runtime/subsystems/jobs/job-worker.bullmq-backend.js +3 -3
  61. package/dist/runtime/subsystems/jobs/job-worker.js +4 -4
  62. package/dist/runtime/subsystems/jobs/job-worker.module.js +12 -12
  63. package/dist/runtime/subsystems/jobs/jobs-domain.module.js +10 -10
  64. package/dist/runtime/subsystems/observability/index.js +3 -3
  65. package/dist/runtime/subsystems/observability/observability.module.js +3 -3
  66. package/dist/runtime/subsystems/observability/observability.service.js +2 -2
  67. package/dist/runtime/subsystems/storage/index.js +4 -4
  68. package/dist/runtime/subsystems/storage/storage.module.js +2 -2
  69. package/dist/src/cli/index.js +123 -84
  70. package/dist/src/cli/index.js.map +1 -1
  71. package/dist/src/index.d.ts +111 -1
  72. package/dist/src/index.js +10 -8
  73. package/package.json +1 -1
  74. package/runtime/subsystems/events/events.module.ts +24 -7
  75. package/dist/chunk-KK5A7B2T.js.map +0 -1
  76. package/dist/chunk-VOYFPR3S.js.map +0 -1
  77. /package/dist/{chunk-VNBC3VXM.js.map → chunk-3A34R6CI.js.map} +0 -0
  78. /package/dist/{chunk-I6UXRJ3Q.js.map → chunk-43SBT72G.js.map} +0 -0
  79. /package/dist/{chunk-BK5ICA2F.js.map → chunk-4MVGAMUA.js.map} +0 -0
  80. /package/dist/{chunk-P7EZCTIN.js.map → chunk-6CJRZHV4.js.map} +0 -0
  81. /package/dist/{chunk-COGHTKXY.js.map → chunk-7625PLY7.js.map} +0 -0
  82. /package/dist/{chunk-5RT7JGKT.js.map → chunk-7OVCARTQ.js.map} +0 -0
  83. /package/dist/{chunk-BHZP6LOV.js.map → chunk-CDLWYZVQ.js.map} +0 -0
  84. /package/dist/{chunk-W2UIDI3R.js.map → chunk-CLWBNXKF.js.map} +0 -0
  85. /package/dist/{chunk-AODME4YK.js.map → chunk-EEJC66ZF.js.map} +0 -0
  86. /package/dist/{chunk-YK5JEVLX.js.map → chunk-FFUDEIFF.js.map} +0 -0
  87. /package/dist/{chunk-AJILKWGO.js.map → chunk-GMRTI7AK.js.map} +0 -0
  88. /package/dist/{chunk-4OC5MSHO.js.map → chunk-GOO5ZMYO.js.map} +0 -0
  89. /package/dist/{chunk-M3TIZGIB.js.map → chunk-GV337QP3.js.map} +0 -0
  90. /package/dist/{chunk-CZQUOIDY.js.map → chunk-J7JMVS2B.js.map} +0 -0
  91. /package/dist/{chunk-SZYZ4SHF.js.map → chunk-MBFSG4KQ.js.map} +0 -0
  92. /package/dist/{chunk-T6SCOJF4.js.map → chunk-NXHL5YII.js.map} +0 -0
  93. /package/dist/{chunk-XWBK3XJK.js.map → chunk-O2A6XHGD.js.map} +0 -0
  94. /package/dist/{chunk-ATVGYF3D.js.map → chunk-QFUIE37H.js.map} +0 -0
  95. /package/dist/{chunk-SGSWVNNB.js.map → chunk-R6F6KFIL.js.map} +0 -0
  96. /package/dist/{chunk-MB5VVG4Z.js.map → chunk-TKU6VYG3.js.map} +0 -0
  97. /package/dist/{chunk-DUMI2J5M.js.map → chunk-VQOAATIG.js.map} +0 -0
  98. /package/dist/{chunk-E45CSC33.js.map → chunk-XKWOJZZ4.js.map} +0 -0
  99. /package/dist/{chunk-MVKW2BCR.js.map → chunk-YULGWXCY.js.map} +0 -0
  100. /package/dist/{chunk-HCAKMT64.js.map → chunk-YXI7K4MJ.js.map} +0 -0
@@ -1,21 +1,21 @@
1
1
  import {
2
2
  JobsDomainModule
3
- } from "../../../chunk-AJILKWGO.js";
3
+ } from "../../../chunk-GMRTI7AK.js";
4
+ import "../../../chunk-VQOAATIG.js";
5
+ import "../../../chunk-3A34R6CI.js";
6
+ import "../../../chunk-CDLWYZVQ.js";
7
+ import "../../../chunk-L3LZWWSX.js";
4
8
  import "../../../chunk-DV4RV2DC.js";
5
- import "../../../chunk-MB5VVG4Z.js";
6
- import "../../../chunk-DUMI2J5M.js";
7
9
  import "../../../chunk-PNZSGAB2.js";
8
- import "../../../chunk-VNBC3VXM.js";
9
- import "../../../chunk-BHZP6LOV.js";
10
10
  import "../../../chunk-SNQ3TOWP.js";
11
- import "../../../chunk-T4BIIU5E.js";
12
- import "../../../chunk-L3LZWWSX.js";
13
11
  import "../../../chunk-I6MVCB5A.js";
14
12
  import "../../../chunk-RHVN6NA7.js";
15
- import "../../../chunk-ZPL74UQN.js";
16
- import "../../../chunk-7P5ODGLA.js";
17
- import "../../../chunk-OKXZ63IA.js";
13
+ import "../../../chunk-TKU6VYG3.js";
14
+ import "../../../chunk-T4BIIU5E.js";
18
15
  import "../../../chunk-Q6LRJ4VI.js";
16
+ import "../../../chunk-OKXZ63IA.js";
17
+ import "../../../chunk-7P5ODGLA.js";
18
+ import "../../../chunk-ZPL74UQN.js";
19
19
  import "../../../chunk-GYGNEQSC.js";
20
20
  import "../../../chunk-U64T4YZE.js";
21
21
  import "../../../chunk-2E224ZSN.js";
@@ -5,18 +5,18 @@ import {
5
5
  } from "../../../chunk-EWYCWP4H.js";
6
6
  import {
7
7
  ObservabilityModule
8
- } from "../../../chunk-E45CSC33.js";
8
+ } from "../../../chunk-XKWOJZZ4.js";
9
9
  import {
10
10
  BridgeMetricsReporter
11
11
  } from "../../../chunk-AQFQ4BYM.js";
12
- import "../../../chunk-W2UIDI3R.js";
12
+ import "../../../chunk-CLWBNXKF.js";
13
13
  import {
14
14
  OBSERVABILITY,
15
15
  OBSERVABILITY_MODULE_OPTIONS
16
16
  } from "../../../chunk-Y7RRSEOC.js";
17
17
  import "../../../chunk-ZPL74UQN.js";
18
- import "../../../chunk-4LH67P4U.js";
19
18
  import "../../../chunk-H5NH7KPE.js";
19
+ import "../../../chunk-4LH67P4U.js";
20
20
  import "../../../chunk-GYGNEQSC.js";
21
21
  import "../../../chunk-S7C6TIIF.js";
22
22
  import "../../../chunk-2E224ZSN.js";
@@ -1,12 +1,12 @@
1
1
  import {
2
2
  ObservabilityModule
3
- } from "../../../chunk-E45CSC33.js";
3
+ } from "../../../chunk-XKWOJZZ4.js";
4
4
  import "../../../chunk-AQFQ4BYM.js";
5
- import "../../../chunk-W2UIDI3R.js";
5
+ import "../../../chunk-CLWBNXKF.js";
6
6
  import "../../../chunk-Y7RRSEOC.js";
7
7
  import "../../../chunk-ZPL74UQN.js";
8
- import "../../../chunk-4LH67P4U.js";
9
8
  import "../../../chunk-H5NH7KPE.js";
9
+ import "../../../chunk-4LH67P4U.js";
10
10
  import "../../../chunk-GYGNEQSC.js";
11
11
  import "../../../chunk-S7C6TIIF.js";
12
12
  import "../../../chunk-2E224ZSN.js";
@@ -1,9 +1,9 @@
1
1
  import {
2
2
  ObservabilityService
3
- } from "../../../chunk-W2UIDI3R.js";
3
+ } from "../../../chunk-CLWBNXKF.js";
4
4
  import "../../../chunk-ZPL74UQN.js";
5
- import "../../../chunk-4LH67P4U.js";
6
5
  import "../../../chunk-H5NH7KPE.js";
6
+ import "../../../chunk-4LH67P4U.js";
7
7
  import "../../../chunk-GYGNEQSC.js";
8
8
  import "../../../chunk-S7C6TIIF.js";
9
9
  import "../../../chunk-2E224ZSN.js";
@@ -1,10 +1,7 @@
1
1
  import "../../../chunk-ZUMULSEQ.js";
2
2
  import {
3
3
  StorageModule
4
- } from "../../../chunk-BK5ICA2F.js";
5
- import {
6
- STORAGE
7
- } from "../../../chunk-NYBCQZC7.js";
4
+ } from "../../../chunk-4MVGAMUA.js";
8
5
  import {
9
6
  LocalStorageBackend
10
7
  } from "../../../chunk-JWNHNUYL.js";
@@ -12,6 +9,9 @@ import {
12
9
  MemoryStorageBackend
13
10
  } from "../../../chunk-3SZFUTXE.js";
14
11
  import "../../../chunk-J6MN42LG.js";
12
+ import {
13
+ STORAGE
14
+ } from "../../../chunk-NYBCQZC7.js";
15
15
  import "../../../chunk-GYGNEQSC.js";
16
16
  import "../../../chunk-2E224ZSN.js";
17
17
  export {
@@ -1,10 +1,10 @@
1
1
  import {
2
2
  StorageModule
3
- } from "../../../chunk-BK5ICA2F.js";
4
- import "../../../chunk-NYBCQZC7.js";
3
+ } from "../../../chunk-4MVGAMUA.js";
5
4
  import "../../../chunk-JWNHNUYL.js";
6
5
  import "../../../chunk-3SZFUTXE.js";
7
6
  import "../../../chunk-J6MN42LG.js";
7
+ import "../../../chunk-NYBCQZC7.js";
8
8
  import "../../../chunk-GYGNEQSC.js";
9
9
  import "../../../chunk-2E224ZSN.js";
10
10
  export {
@@ -1,11 +1,15 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  DIRECTION_TO_POOL,
4
+ EAV_DATA_TYPE_TO_FIELD_TYPE,
4
5
  EVENT_FIELD_TYPES,
6
+ EXTERNAL_SYNC_FIELDS,
7
+ EXTERNAL_SYNC_GROUP,
5
8
  _resetRegistryForTests,
6
9
  analyzeDomain,
7
10
  buildManifest,
8
11
  collectEntitySurfaces,
12
+ deriveFieldMeta,
9
13
  detectYamlType,
10
14
  findYamlFiles,
11
15
  formatConsole,
@@ -17,7 +21,9 @@ import {
17
21
  getManifestDir,
18
22
  getOrchestrationPatternNames,
19
23
  getPendingSuggestions,
24
+ hasExternalSyncShape,
20
25
  isActiveProvider,
26
+ isEntityRefField,
21
27
  isManifestStale,
22
28
  loadAppPatterns,
23
29
  loadEntities,
@@ -38,15 +44,19 @@ import {
38
44
  validateOrchestrationProject,
39
45
  validateProviders,
40
46
  writeManifest
41
- } from "../../chunk-KK5A7B2T.js";
47
+ } from "../../chunk-524YKITE.js";
42
48
  import "../../chunk-KVOWSC5S.js";
43
- import "../../chunk-ATVGYF3D.js";
44
- import "../../chunk-YK5JEVLX.js";
49
+ import "../../chunk-QFUIE37H.js";
50
+ import "../../chunk-FFUDEIFF.js";
45
51
  import "../../chunk-EO2QPOKH.js";
46
52
  import "../../chunk-PRWIX6UW.js";
47
- import "../../chunk-XWBK3XJK.js";
53
+ import "../../chunk-O2A6XHGD.js";
54
+ import "../../chunk-HNWZFNKP.js";
48
55
  import "../../chunk-AHV4GDYM.js";
49
56
  import "../../chunk-SQDOBLBP.js";
57
+ import "../../chunk-43SBT72G.js";
58
+ import "../../chunk-4MF3HKJA.js";
59
+ import "../../chunk-TIZXQU26.js";
50
60
  import "../../chunk-JEINYUJH.js";
51
61
  import {
52
62
  isDivisibleCursor
@@ -57,10 +67,6 @@ import "../../chunk-TDEHU73T.js";
57
67
  import "../../chunk-S7C6TIIF.js";
58
68
  import "../../chunk-MZ6GV4YF.js";
59
69
  import "../../chunk-LG57S2SC.js";
60
- import "../../chunk-HNWZFNKP.js";
61
- import "../../chunk-I6UXRJ3Q.js";
62
- import "../../chunk-TIZXQU26.js";
63
- import "../../chunk-4MF3HKJA.js";
64
70
  import "../../chunk-U64T4YZE.js";
65
71
  import "../../chunk-2E224ZSN.js";
66
72
 
@@ -2877,6 +2883,23 @@ var COMPOSERS = {
2877
2883
  ],
2878
2884
  calls: [` IntegrationModule.forRoot({ ${parts.join(", ")} }),`]
2879
2885
  };
2886
+ },
2887
+ // #473 — observability combiner (ADR-025). NO `backend` / `multiTenant`:
2888
+ // it owns no durable state — portability is inherited from whichever
2889
+ // backends the composed siblings run (see `ObservabilityModule` docblock).
2890
+ // The only `forRoot` option is `reporters` (OBS-6); thread the config
2891
+ // block's `reporters:` when a reporter is enabled, else emit a bare
2892
+ // `forRoot()`. Ordered LAST in `COMPOSABLE_ORDER` so it registers after the
2893
+ // read ports it composes via `@Optional()` DI.
2894
+ observability: ({ moduleImport, cfg }) => {
2895
+ const reportersClause = observabilityReportersClause(cfg);
2896
+ const opts = reportersClause ? `{ ${reportersClause} }` : "";
2897
+ return {
2898
+ imports: [
2899
+ `import { ObservabilityModule } from '${moduleImport("observability", "observability.module")}';`
2900
+ ],
2901
+ calls: [` ObservabilityModule.forRoot(${opts}),`]
2902
+ };
2880
2903
  }
2881
2904
  };
2882
2905
  function integrationDifferClause(cfg) {
@@ -2891,6 +2914,18 @@ function integrationDifferClause(cfg) {
2891
2914
  if (Object.keys(inner).length === 0) return "";
2892
2915
  return `differ: ${jsonToTs(inner)}`;
2893
2916
  }
2917
+ function observabilityReportersClause(cfg) {
2918
+ const reporters = cfg?.reporters;
2919
+ if (!reporters || typeof reporters !== "object") return "";
2920
+ const enabled = {};
2921
+ for (const [key, value] of Object.entries(reporters)) {
2922
+ if (value && typeof value === "object" && value.enabled === true) {
2923
+ enabled[key] = value;
2924
+ }
2925
+ }
2926
+ if (Object.keys(enabled).length === 0) return "";
2927
+ return `reporters: ${jsonToTs(enabled)}`;
2928
+ }
2894
2929
  var PACKAGE2 = "@pattern-stack/codegen";
2895
2930
  function makeModuleImport(mode, subsystemsRel) {
2896
2931
  if (mode === "vendored") {
@@ -2898,7 +2933,13 @@ function makeModuleImport(mode, subsystemsRel) {
2898
2933
  }
2899
2934
  return (subsystem) => subsystem === "events" ? `${PACKAGE2}/subsystems` : `${PACKAGE2}/runtime/subsystems/${subsystem}/index`;
2900
2935
  }
2901
- var COMPOSABLE_ORDER = ["events", "jobs", "bridge", "integration"];
2936
+ var COMPOSABLE_ORDER = [
2937
+ "events",
2938
+ "jobs",
2939
+ "bridge",
2940
+ "integration",
2941
+ "observability"
2942
+ ];
2902
2943
  var HEADER5 = `// AUTO-GENERATED by @pattern-stack/codegen. DO NOT EDIT.
2903
2944
  // Subsystem composition barrel \u2014 reflects \`subsystems.install\` in
2904
2945
  // codegen.config.yaml and the per-subsystem option blocks
@@ -5459,79 +5500,11 @@ function emitStore(ctx, outDir) {
5459
5500
 
5460
5501
  // src/emitters/frontend/emit-fields.ts
5461
5502
  import { join as join15 } from "path";
5462
-
5463
- // src/emitters/frontend/field-meta.ts
5464
- var CAMEL2 = (s) => s.replace(/_([a-z])/g, (_, c) => c.toUpperCase());
5465
- function formatLabel(fieldName) {
5466
- return fieldName.replace(/_/g, " ").replace(/\b\w/g, (c) => c.toUpperCase());
5467
- }
5468
- function inferUiType(field) {
5469
- if (field.ui.type) return field.ui.type;
5470
- if (Array.isArray(field.choices) && field.choices.length > 0) return "enum";
5471
- if (field.foreignKey) return "reference";
5472
- const nameLower = field.name.toLowerCase();
5473
- if (nameLower.includes("email")) return "email";
5474
- if (nameLower.includes("url") || nameLower.includes("website")) return "url";
5475
- if (nameLower.includes("password")) return "password";
5476
- if (nameLower.includes("price") || nameLower.includes("amount") || nameLower.includes("cost") || nameLower.includes("value") || nameLower.includes("revenue")) {
5477
- return "money";
5478
- }
5479
- if (nameLower.includes("percent") || nameLower.includes("rate")) {
5480
- return "percentage";
5481
- }
5482
- switch (field.type) {
5483
- case "string":
5484
- return field.constraints.maxLength && field.constraints.maxLength > 500 ? "textarea" : "text";
5485
- case "integer":
5486
- case "decimal":
5487
- return "number";
5488
- case "boolean":
5489
- return "boolean";
5490
- case "uuid":
5491
- return "text";
5492
- case "date":
5493
- return "date";
5494
- case "datetime":
5495
- return "datetime";
5496
- case "json":
5497
- return "json";
5498
- default:
5499
- return "text";
5500
- }
5501
- }
5502
- function inferUiImportance(field) {
5503
- if (field.ui.importance) return field.ui.importance;
5504
- const nameLower = field.name.toLowerCase();
5505
- if (["id", "created_at", "updated_at", "deleted_at"].includes(nameLower)) {
5506
- return "tertiary";
5507
- }
5508
- if (field.foreignKey && nameLower.endsWith("_id")) return "secondary";
5509
- if (field.required) return "primary";
5510
- if (nameLower.includes("name") || nameLower.includes("title")) return "primary";
5511
- return "secondary";
5512
- }
5513
- function isEntityRefField(field) {
5514
- if (field.type === "entity_ref") return true;
5515
- return field.name.endsWith("_entity_type") || field.name.endsWith("_entity_id");
5516
- }
5517
- function deriveFieldMeta(field) {
5518
- const hasChoices = Array.isArray(field.choices) && field.choices.length > 0;
5519
- const meta = {
5520
- field: CAMEL2(field.name),
5521
- label: field.ui.label ?? formatLabel(field.name),
5522
- type: inferUiType(field),
5523
- importance: inferUiImportance(field),
5524
- sortable: field.ui.sortable ?? false,
5525
- filterable: field.ui.filterable ?? false
5526
- };
5527
- if (hasChoices) meta.choices = field.choices;
5528
- if (field.foreignKey) meta.reference = field.foreignKey.table;
5529
- return meta;
5530
- }
5531
-
5532
- // src/emitters/frontend/emit-fields.ts
5533
5503
  var SOURCE_DESC_SET5 = "the entity set";
5534
5504
  function buildFieldMetaTypeFile() {
5505
+ const eavKeys = Object.keys(EAV_DATA_TYPE_TO_FIELD_TYPE);
5506
+ const eavUnion = eavKeys.map((k) => ` | '${k}'`).join("\n");
5507
+ const eavEntries = Object.entries(EAV_DATA_TYPE_TO_FIELD_TYPE).map(([k, v]) => ` ${k}: '${v}',`).join("\n");
5535
5508
  const body = `/**
5536
5509
  * Field metadata types for DataGrid, forms, and admin surfaces.
5537
5510
  */
@@ -5563,37 +5536,85 @@ export interface FieldMeta<T = unknown> {
5563
5536
  importance: FieldImportance;
5564
5537
  sortable?: boolean;
5565
5538
  filterable?: boolean;
5539
+ /** Layout grouping (e.g. 'external_sync'). */
5540
+ group?: string;
5541
+ /** \`false\` \u21D2 hidden by default. Absent means visible. */
5542
+ visible?: boolean;
5543
+ placeholder?: string;
5544
+ /** Help/description text shown alongside the field. */
5545
+ help?: string;
5566
5546
  format?: Record<string, unknown>;
5567
5547
  choices?: string[];
5568
5548
  reference?: string;
5549
+ /** Curated/displayed field \u2014 drives card & preview field selection. */
5550
+ isKeyField?: boolean;
5551
+ /** Sort position within the key-field set. */
5552
+ keyFieldOrder?: number;
5569
5553
  }
5554
+
5555
+ /** EAV \`field_definitions.data_type\` vocabulary. */
5556
+ export type EavDataType =
5557
+ ${eavUnion};
5558
+
5559
+ /**
5560
+ * EAV \`field_definitions.data_type\` \u2192 \`FieldType\` rendering contract: an EAV
5561
+ * field renders through the same vocabulary as a native column. Note both
5562
+ * \`picklist\` and \`multipicklist\` map to \`enum\` \u2014 multi-select rendering is a
5563
+ * consumer-side concern (check the EAV row's cardinality, not the FieldType).
5564
+ */
5565
+ export const EAV_DATA_TYPE_TO_FIELD_TYPE: Record<EavDataType, FieldType> = {
5566
+ ${eavEntries}
5567
+ };
5570
5568
  `;
5571
5569
  return withBanner(SOURCE_DESC_SET5, body);
5572
5570
  }
5573
5571
  function hasTimestamps(parsed) {
5574
5572
  return parsed?.behaviors.includes("timestamps") ?? false;
5575
5573
  }
5574
+ function hasSoftDelete(parsed) {
5575
+ return parsed?.behaviors.includes("soft_delete") ?? false;
5576
+ }
5576
5577
  function displayFields(parsed) {
5577
5578
  if (!parsed) return [];
5579
+ const syncShape = hasExternalSyncShape(parsed.fields.keys());
5578
5580
  const out = [];
5579
5581
  for (const field of parsed.fields.values()) {
5580
5582
  if (field.name === "id") continue;
5581
5583
  if (isEntityRefField(field)) continue;
5582
- out.push(deriveFieldMeta(field));
5584
+ const defaults = syncShape && EXTERNAL_SYNC_FIELDS.has(field.name) ? { group: EXTERNAL_SYNC_GROUP } : void 0;
5585
+ out.push(deriveFieldMeta(field, defaults));
5583
5586
  }
5584
5587
  return out;
5585
5588
  }
5589
+ function quote(s) {
5590
+ return s.replace(/\\/g, "\\\\").replace(/'/g, "\\'");
5591
+ }
5586
5592
  function renderFieldMeta(meta) {
5587
5593
  const lines = [
5588
5594
  ` field: '${meta.field}',`,
5589
- ` label: '${meta.label}',`,
5595
+ ` label: '${quote(meta.label)}',`,
5590
5596
  ` type: '${meta.type}' as FieldType,`,
5591
5597
  ` importance: '${meta.importance}' as FieldImportance,`
5592
5598
  ];
5593
5599
  if (meta.sortable) lines.push(" sortable: true,");
5594
5600
  if (meta.filterable) lines.push(" filterable: true,");
5601
+ if (meta.group !== void 0) lines.push(` group: '${quote(meta.group)}',`);
5602
+ if (meta.visible !== void 0) lines.push(` visible: ${meta.visible},`);
5603
+ if (meta.placeholder !== void 0) {
5604
+ lines.push(` placeholder: '${quote(meta.placeholder)}',`);
5605
+ }
5606
+ if (meta.help !== void 0) lines.push(` help: '${quote(meta.help)}',`);
5607
+ if (meta.format !== void 0) {
5608
+ lines.push(` format: ${JSON.stringify(meta.format)},`);
5609
+ }
5595
5610
  if (meta.choices) lines.push(` choices: ${JSON.stringify(meta.choices)},`);
5596
5611
  if (meta.reference) lines.push(` reference: '${meta.reference}',`);
5612
+ if (meta.isKeyField) {
5613
+ lines.push(" isKeyField: true,");
5614
+ if (meta.keyFieldOrder !== void 0) {
5615
+ lines.push(` keyFieldOrder: ${meta.keyFieldOrder},`);
5616
+ }
5617
+ }
5597
5618
  return ` ${meta.field}: {
5598
5619
  ${lines.join("\n")}
5599
5620
  },`;
@@ -5607,6 +5628,7 @@ function buildEntityFieldsFile(entity, ctx) {
5607
5628
  const fields = displayFields(parsed);
5608
5629
  const rels = resolvableRels(entity, ctx);
5609
5630
  const ts3 = hasTimestamps(parsed);
5631
+ const sd = hasSoftDelete(parsed);
5610
5632
  const fieldEntries = fields.map(renderFieldMeta);
5611
5633
  const relEntries = rels.map(
5612
5634
  (r) => ` ${r.propertyName}: {
@@ -5633,8 +5655,22 @@ function buildEntityFieldsFile(entity, ctx) {
5633
5655
  format: { dateFormat: 'relative' },
5634
5656
  },`
5635
5657
  ] : [];
5636
- const allEntries = [...fieldEntries, ...relEntries, ...tsEntries].join("\n");
5658
+ const sdEntries = sd ? [
5659
+ ` deletedAt: {
5660
+ field: 'deletedAt',
5661
+ label: 'Deleted',
5662
+ type: 'datetime' as FieldType,
5663
+ importance: 'tertiary' as FieldImportance,
5664
+ format: { dateFormat: 'relative' },
5665
+ },`
5666
+ ] : [];
5667
+ const allEntries = [...fieldEntries, ...relEntries, ...tsEntries, ...sdEntries].join(
5668
+ "\n"
5669
+ );
5637
5670
  const primaryFields = fields.filter((f) => f.importance === "primary").map((f) => ` '${f.field}',`).join("\n");
5671
+ const keyFields = fields.filter((f) => f.isKeyField).sort(
5672
+ (a, b) => (a.keyFieldOrder ?? Number.MAX_SAFE_INTEGER) - (b.keyFieldOrder ?? Number.MAX_SAFE_INTEGER)
5673
+ ).map((f) => ` '${f.field}',`).join("\n");
5638
5674
  const searchFields = fields.filter((f) => f.filterable).map((f) => ` '${f.field}',`).join("\n");
5639
5675
  const defaultSortField = ts3 ? "createdAt" : "id";
5640
5676
  const expose = parsed?.expose ?? ["repository", "rest", "trpc"];
@@ -5656,6 +5692,9 @@ export const ${camelName}Metadata = {
5656
5692
 
5657
5693
  primaryFields: [
5658
5694
  ${primaryFields}
5695
+ ],
5696
+ keyFields: [
5697
+ ${keyFields}
5659
5698
  ],
5660
5699
  searchFields: [
5661
5700
  ${searchFields}
@@ -8622,7 +8661,7 @@ function buildAuthImportRewriter(subsystemsRoot) {
8622
8661
  const relPosix = rel2.split(path24.sep).join("/");
8623
8662
  return content.replace(
8624
8663
  AUTH_BARE_IMPORT_RE,
8625
- (_match, quote) => `${quote}${relPosix}${quote}`
8664
+ (_match, quote2) => `${quote2}${relPosix}${quote2}`
8626
8665
  );
8627
8666
  };
8628
8667
  }