@metaobjectsdev/codegen-ts 0.5.0-rc.1

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 (198) hide show
  1. package/LICENSE +189 -0
  2. package/README.md +101 -0
  3. package/dist/column-mapper.d.ts +38 -0
  4. package/dist/column-mapper.d.ts.map +1 -0
  5. package/dist/column-mapper.js +205 -0
  6. package/dist/column-mapper.js.map +1 -0
  7. package/dist/constants.d.ts +7 -0
  8. package/dist/constants.d.ts.map +1 -0
  9. package/dist/constants.js +8 -0
  10. package/dist/constants.js.map +1 -0
  11. package/dist/errors.d.ts +7 -0
  12. package/dist/errors.d.ts.map +1 -0
  13. package/dist/errors.js +11 -0
  14. package/dist/errors.js.map +1 -0
  15. package/dist/format.d.ts +2 -0
  16. package/dist/format.d.ts.map +1 -0
  17. package/dist/format.js +47 -0
  18. package/dist/format.js.map +1 -0
  19. package/dist/generator.d.ts +44 -0
  20. package/dist/generator.d.ts.map +1 -0
  21. package/dist/generator.js +17 -0
  22. package/dist/generator.js.map +1 -0
  23. package/dist/generators/barrel.d.ts +6 -0
  24. package/dist/generators/barrel.d.ts.map +1 -0
  25. package/dist/generators/barrel.js +17 -0
  26. package/dist/generators/barrel.js.map +1 -0
  27. package/dist/generators/entity-file.d.ts +8 -0
  28. package/dist/generators/entity-file.d.ts.map +1 -0
  29. package/dist/generators/entity-file.js +27 -0
  30. package/dist/generators/entity-file.js.map +1 -0
  31. package/dist/generators/index.d.ts +5 -0
  32. package/dist/generators/index.d.ts.map +1 -0
  33. package/dist/generators/index.js +5 -0
  34. package/dist/generators/index.js.map +1 -0
  35. package/dist/generators/queries-file.d.ts +8 -0
  36. package/dist/generators/queries-file.d.ts.map +1 -0
  37. package/dist/generators/queries-file.js +26 -0
  38. package/dist/generators/queries-file.js.map +1 -0
  39. package/dist/generators/routes-file.d.ts +12 -0
  40. package/dist/generators/routes-file.d.ts.map +1 -0
  41. package/dist/generators/routes-file.js +30 -0
  42. package/dist/generators/routes-file.js.map +1 -0
  43. package/dist/import-path.d.ts +41 -0
  44. package/dist/import-path.d.ts.map +1 -0
  45. package/dist/import-path.js +95 -0
  46. package/dist/import-path.js.map +1 -0
  47. package/dist/index.d.ts +29 -0
  48. package/dist/index.d.ts.map +1 -0
  49. package/dist/index.js +21 -0
  50. package/dist/index.js.map +1 -0
  51. package/dist/metaobjects-config.d.ts +56 -0
  52. package/dist/metaobjects-config.d.ts.map +1 -0
  53. package/dist/metaobjects-config.js +42 -0
  54. package/dist/metaobjects-config.js.map +1 -0
  55. package/dist/naming.d.ts +29 -0
  56. package/dist/naming.d.ts.map +1 -0
  57. package/dist/naming.js +67 -0
  58. package/dist/naming.js.map +1 -0
  59. package/dist/overwrite-policy.d.ts +8 -0
  60. package/dist/overwrite-policy.d.ts.map +1 -0
  61. package/dist/overwrite-policy.js +23 -0
  62. package/dist/overwrite-policy.js.map +1 -0
  63. package/dist/pk-resolver.d.ts +18 -0
  64. package/dist/pk-resolver.d.ts.map +1 -0
  65. package/dist/pk-resolver.js +36 -0
  66. package/dist/pk-resolver.js.map +1 -0
  67. package/dist/projection/extract-view-spec.d.ts +18 -0
  68. package/dist/projection/extract-view-spec.d.ts.map +1 -0
  69. package/dist/projection/extract-view-spec.js +272 -0
  70. package/dist/projection/extract-view-spec.js.map +1 -0
  71. package/dist/projection/index.d.ts +5 -0
  72. package/dist/projection/index.d.ts.map +1 -0
  73. package/dist/projection/index.js +5 -0
  74. package/dist/projection/index.js.map +1 -0
  75. package/dist/projection/projection-detector.d.ts +4 -0
  76. package/dist/projection/projection-detector.d.ts.map +1 -0
  77. package/dist/projection/projection-detector.js +13 -0
  78. package/dist/projection/projection-detector.js.map +1 -0
  79. package/dist/projection/view-ddl-emit.d.ts +10 -0
  80. package/dist/projection/view-ddl-emit.d.ts.map +1 -0
  81. package/dist/projection/view-ddl-emit.js +47 -0
  82. package/dist/projection/view-ddl-emit.js.map +1 -0
  83. package/dist/projection/view-spec.d.ts +56 -0
  84. package/dist/projection/view-spec.d.ts.map +1 -0
  85. package/dist/projection/view-spec.js +2 -0
  86. package/dist/projection/view-spec.js.map +1 -0
  87. package/dist/relation-resolver.d.ts +21 -0
  88. package/dist/relation-resolver.d.ts.map +1 -0
  89. package/dist/relation-resolver.js +62 -0
  90. package/dist/relation-resolver.js.map +1 -0
  91. package/dist/render-context.d.ts +65 -0
  92. package/dist/render-context.d.ts.map +1 -0
  93. package/dist/render-context.js +28 -0
  94. package/dist/render-context.js.map +1 -0
  95. package/dist/runner.d.ts +17 -0
  96. package/dist/runner.d.ts.map +1 -0
  97. package/dist/runner.js +135 -0
  98. package/dist/runner.js.map +1 -0
  99. package/dist/templates/barrel.d.ts +8 -0
  100. package/dist/templates/barrel.d.ts.map +1 -0
  101. package/dist/templates/barrel.js +12 -0
  102. package/dist/templates/barrel.js.map +1 -0
  103. package/dist/templates/drizzle-schema.d.ts +13 -0
  104. package/dist/templates/drizzle-schema.d.ts.map +1 -0
  105. package/dist/templates/drizzle-schema.js +251 -0
  106. package/dist/templates/drizzle-schema.js.map +1 -0
  107. package/dist/templates/entity-constants.d.ts +4 -0
  108. package/dist/templates/entity-constants.d.ts.map +1 -0
  109. package/dist/templates/entity-constants.js +215 -0
  110. package/dist/templates/entity-constants.js.map +1 -0
  111. package/dist/templates/entity-file.d.ts +4 -0
  112. package/dist/templates/entity-file.d.ts.map +1 -0
  113. package/dist/templates/entity-file.js +45 -0
  114. package/dist/templates/entity-file.js.map +1 -0
  115. package/dist/templates/field-meta.d.ts +24 -0
  116. package/dist/templates/field-meta.d.ts.map +1 -0
  117. package/dist/templates/field-meta.js +117 -0
  118. package/dist/templates/field-meta.js.map +1 -0
  119. package/dist/templates/filter-allowlist.d.ts +5 -0
  120. package/dist/templates/filter-allowlist.d.ts.map +1 -0
  121. package/dist/templates/filter-allowlist.js +86 -0
  122. package/dist/templates/filter-allowlist.js.map +1 -0
  123. package/dist/templates/filter-shared.d.ts +15 -0
  124. package/dist/templates/filter-shared.d.ts.map +1 -0
  125. package/dist/templates/filter-shared.js +30 -0
  126. package/dist/templates/filter-shared.js.map +1 -0
  127. package/dist/templates/filter-type.d.ts +4 -0
  128. package/dist/templates/filter-type.d.ts.map +1 -0
  129. package/dist/templates/filter-type.js +78 -0
  130. package/dist/templates/filter-type.js.map +1 -0
  131. package/dist/templates/inferred-types.d.ts +4 -0
  132. package/dist/templates/inferred-types.d.ts.map +1 -0
  133. package/dist/templates/inferred-types.js +14 -0
  134. package/dist/templates/inferred-types.js.map +1 -0
  135. package/dist/templates/projection-decl.d.ts +21 -0
  136. package/dist/templates/projection-decl.d.ts.map +1 -0
  137. package/dist/templates/projection-decl.js +116 -0
  138. package/dist/templates/projection-decl.js.map +1 -0
  139. package/dist/templates/queries-file.d.ts +4 -0
  140. package/dist/templates/queries-file.d.ts.map +1 -0
  141. package/dist/templates/queries-file.js +39 -0
  142. package/dist/templates/queries-file.js.map +1 -0
  143. package/dist/templates/queries.d.ts +9 -0
  144. package/dist/templates/queries.d.ts.map +1 -0
  145. package/dist/templates/queries.js +115 -0
  146. package/dist/templates/queries.js.map +1 -0
  147. package/dist/templates/relations-block.d.ts +9 -0
  148. package/dist/templates/relations-block.d.ts.map +1 -0
  149. package/dist/templates/relations-block.js +45 -0
  150. package/dist/templates/relations-block.js.map +1 -0
  151. package/dist/templates/routes-file.d.ts +4 -0
  152. package/dist/templates/routes-file.d.ts.map +1 -0
  153. package/dist/templates/routes-file.js +158 -0
  154. package/dist/templates/routes-file.js.map +1 -0
  155. package/dist/templates/zod-validators.d.ts +4 -0
  156. package/dist/templates/zod-validators.d.ts.map +1 -0
  157. package/dist/templates/zod-validators.js +129 -0
  158. package/dist/templates/zod-validators.js.map +1 -0
  159. package/package.json +59 -0
  160. package/src/column-mapper.ts +266 -0
  161. package/src/constants.ts +10 -0
  162. package/src/errors.ts +10 -0
  163. package/src/format.ts +50 -0
  164. package/src/generator.ts +73 -0
  165. package/src/generators/barrel.ts +28 -0
  166. package/src/generators/entity-file.ts +33 -0
  167. package/src/generators/index.ts +4 -0
  168. package/src/generators/queries-file.ts +32 -0
  169. package/src/generators/routes-file.ts +36 -0
  170. package/src/import-path.ts +153 -0
  171. package/src/index.ts +45 -0
  172. package/src/metaobjects-config.ts +95 -0
  173. package/src/naming.ts +84 -0
  174. package/src/overwrite-policy.ts +39 -0
  175. package/src/pk-resolver.ts +47 -0
  176. package/src/projection/extract-view-spec.ts +372 -0
  177. package/src/projection/index.ts +4 -0
  178. package/src/projection/projection-detector.ts +26 -0
  179. package/src/projection/view-ddl-emit.ts +66 -0
  180. package/src/projection/view-spec.ts +62 -0
  181. package/src/relation-resolver.ts +87 -0
  182. package/src/render-context.ts +93 -0
  183. package/src/runner.ts +178 -0
  184. package/src/templates/barrel.ts +23 -0
  185. package/src/templates/drizzle-schema.ts +286 -0
  186. package/src/templates/entity-constants.ts +248 -0
  187. package/src/templates/entity-file.ts +51 -0
  188. package/src/templates/field-meta.ts +150 -0
  189. package/src/templates/filter-allowlist.ts +104 -0
  190. package/src/templates/filter-shared.ts +30 -0
  191. package/src/templates/filter-type.ts +93 -0
  192. package/src/templates/inferred-types.ts +16 -0
  193. package/src/templates/projection-decl.ts +146 -0
  194. package/src/templates/queries-file.ts +56 -0
  195. package/src/templates/queries.ts +132 -0
  196. package/src/templates/relations-block.ts +65 -0
  197. package/src/templates/routes-file.ts +179 -0
  198. package/src/templates/zod-validators.ts +140 -0
@@ -0,0 +1,117 @@
1
+ // Shared field-level metadata helpers — consumed by entity-constants.ts,
2
+ // projection-decl.ts, and any future generator that needs per-field inference.
3
+ //
4
+ // All helpers take a MetaField node.
5
+ import { MetaField } from "@metaobjectsdev/metadata";
6
+ import { FIELD_SUBTYPE_STRING, FIELD_SUBTYPE_INT, FIELD_SUBTYPE_LONG, FIELD_SUBTYPE_SHORT, FIELD_SUBTYPE_BYTE, FIELD_SUBTYPE_DOUBLE, FIELD_SUBTYPE_FLOAT, FIELD_SUBTYPE_DECIMAL, FIELD_SUBTYPE_BOOLEAN, FIELD_SUBTYPE_DATE, FIELD_SUBTYPE_TIME, FIELD_SUBTYPE_TIMESTAMP, FIELD_SUBTYPE_CURRENCY, VIEW_SUBTYPE_TEXT, VIEW_SUBTYPE_DATE, VIEW_SUBTYPE_NUMBER, VIEW_SUBTYPE_CHECKBOX, VIEW_SUBTYPE_CURRENCY, FIELD_ATTR_CURRENCY, FIELD_ATTR_CURRENCY_DEFAULT, VIEW_CURRENCY_ATTR_LOCALE, VIEW_CURRENCY_ATTR_LOCALE_DEFAULT, } from "@metaobjectsdev/metadata";
7
+ // ---------------------------------------------------------------------------
8
+ // inferViewKind
9
+ // ---------------------------------------------------------------------------
10
+ /**
11
+ * Resolve the cell-renderer key (view kind) for a field.
12
+ * Explicit view child wins; field subType determines default.
13
+ */
14
+ export function inferViewKind(field) {
15
+ // Explicit view (own or inherited via extends) has highest priority.
16
+ const viewChild = field.views()[0];
17
+ if (viewChild)
18
+ return viewChild.subType;
19
+ // Field subtype → default view.
20
+ return defaultViewForSubType(field.subType);
21
+ }
22
+ function defaultViewForSubType(subType) {
23
+ switch (subType) {
24
+ case FIELD_SUBTYPE_BOOLEAN:
25
+ return VIEW_SUBTYPE_CHECKBOX;
26
+ case FIELD_SUBTYPE_INT:
27
+ case FIELD_SUBTYPE_LONG:
28
+ case FIELD_SUBTYPE_SHORT:
29
+ case FIELD_SUBTYPE_BYTE:
30
+ case FIELD_SUBTYPE_DOUBLE:
31
+ case FIELD_SUBTYPE_FLOAT:
32
+ case FIELD_SUBTYPE_DECIMAL:
33
+ return VIEW_SUBTYPE_NUMBER;
34
+ case FIELD_SUBTYPE_DATE:
35
+ case FIELD_SUBTYPE_TIME:
36
+ case FIELD_SUBTYPE_TIMESTAMP:
37
+ return VIEW_SUBTYPE_DATE;
38
+ case FIELD_SUBTYPE_CURRENCY:
39
+ return VIEW_SUBTYPE_CURRENCY;
40
+ default:
41
+ return VIEW_SUBTYPE_TEXT;
42
+ }
43
+ }
44
+ // ---------------------------------------------------------------------------
45
+ // zodTypeFor
46
+ // ---------------------------------------------------------------------------
47
+ /**
48
+ * Resolve the Zod validator expression for a field's storage type.
49
+ */
50
+ export function zodTypeFor(field) {
51
+ switch (field.subType) {
52
+ case FIELD_SUBTYPE_STRING:
53
+ return "z.string()";
54
+ case FIELD_SUBTYPE_BOOLEAN:
55
+ return "z.boolean()";
56
+ case FIELD_SUBTYPE_DATE:
57
+ case FIELD_SUBTYPE_TIME:
58
+ case FIELD_SUBTYPE_TIMESTAMP:
59
+ // Returned as ISO strings from SQLite/Postgres drivers.
60
+ return "z.string()";
61
+ case FIELD_SUBTYPE_INT:
62
+ case FIELD_SUBTYPE_LONG:
63
+ case FIELD_SUBTYPE_SHORT:
64
+ case FIELD_SUBTYPE_BYTE:
65
+ case FIELD_SUBTYPE_CURRENCY:
66
+ return "z.number().int()";
67
+ case FIELD_SUBTYPE_DOUBLE:
68
+ case FIELD_SUBTYPE_FLOAT:
69
+ case FIELD_SUBTYPE_DECIMAL:
70
+ return "z.number()";
71
+ default:
72
+ return "z.unknown()";
73
+ }
74
+ }
75
+ // ---------------------------------------------------------------------------
76
+ // currencyMetaFor
77
+ // ---------------------------------------------------------------------------
78
+ /**
79
+ * Resolve currency code + locale for a currency-subtype field.
80
+ * Returns null for non-currency fields.
81
+ */
82
+ export function currencyMetaFor(field) {
83
+ if (field.subType !== FIELD_SUBTYPE_CURRENCY)
84
+ return null;
85
+ const currency = field.ownAttr(FIELD_ATTR_CURRENCY) ?? FIELD_ATTR_CURRENCY_DEFAULT;
86
+ const viewChild = field.views().find((c) => c.subType === VIEW_SUBTYPE_CURRENCY);
87
+ const locale = viewChild?.ownAttr(VIEW_CURRENCY_ATTR_LOCALE) ??
88
+ VIEW_CURRENCY_ATTR_LOCALE_DEFAULT;
89
+ return { currency, locale };
90
+ }
91
+ // ---------------------------------------------------------------------------
92
+ // labelFor
93
+ // ---------------------------------------------------------------------------
94
+ /**
95
+ * Resolve the human-readable label for a field.
96
+ * Uses @label attr on a view child if present; otherwise humanizes the field name.
97
+ */
98
+ export function labelFor(field) {
99
+ for (const child of field.views()) {
100
+ const label = child.ownAttr("label");
101
+ if (typeof label === "string" && label.length > 0)
102
+ return label;
103
+ }
104
+ return humanize(field.name);
105
+ }
106
+ // ---------------------------------------------------------------------------
107
+ // Internal
108
+ // ---------------------------------------------------------------------------
109
+ /** Convert a camelCase or PascalCase field name to a human-friendly label. */
110
+ function humanize(s) {
111
+ return s
112
+ .replace(/([a-z])([A-Z])/g, "$1 $2")
113
+ .replace(/_/g, " ")
114
+ .replace(/\b\w/g, (c) => c.toUpperCase())
115
+ .trim();
116
+ }
117
+ //# sourceMappingURL=field-meta.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"field-meta.js","sourceRoot":"","sources":["../../src/templates/field-meta.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,5 @@
1
+ import { type Code } from "ts-poet";
2
+ import { MetaObject } from "@metaobjectsdev/metadata";
3
+ export declare function renderFilterAllowlist(entity: MetaObject): Code;
4
+ export declare function renderSortAllowlist(entity: MetaObject): Code;
5
+ //# sourceMappingURL=filter-allowlist.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"filter-allowlist.d.ts","sourceRoot":"","sources":["../../src/templates/filter-allowlist.ts"],"names":[],"mappings":"AAAA,OAAO,EAAQ,KAAK,IAAI,EAAE,MAAM,SAAS,CAAC;AAC1C,OAAO,EAAa,UAAU,EAAE,MAAM,0BAA0B,CAAC;AAgDjE,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,UAAU,GAAG,IAAI,CAuB9D;AAED,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,UAAU,GAAG,IAAI,CA6B5D"}
@@ -0,0 +1,86 @@
1
+ import { code } from "ts-poet";
2
+ import { MetaField, MetaObject } from "@metaobjectsdev/metadata";
3
+ import { FIELD_ATTR_FILTERABLE, FIELD_ATTR_SORTABLE_DEFAULT_ORDER, FIELD_SUBTYPE_BOOLEAN, FIELD_SUBTYPE_INT, FIELD_SUBTYPE_SHORT, FIELD_SUBTYPE_BYTE, FIELD_SUBTYPE_LONG, FIELD_SUBTYPE_DOUBLE, FIELD_SUBTYPE_FLOAT, FIELD_SUBTYPE_DECIMAL, FIELD_SUBTYPE_DATE, FIELD_SUBTYPE_TIME, FIELD_SUBTYPE_TIMESTAMP, opsForSubType, } from "@metaobjectsdev/metadata";
4
+ import { sortableFields } from "./filter-shared.js";
5
+ const NUMBER_SUBTYPES = new Set([
6
+ FIELD_SUBTYPE_INT,
7
+ FIELD_SUBTYPE_SHORT,
8
+ FIELD_SUBTYPE_BYTE,
9
+ FIELD_SUBTYPE_LONG,
10
+ FIELD_SUBTYPE_DOUBLE,
11
+ FIELD_SUBTYPE_FLOAT,
12
+ FIELD_SUBTYPE_DECIMAL,
13
+ ]);
14
+ const DATETIME_SUBTYPES = new Set([
15
+ FIELD_SUBTYPE_DATE,
16
+ FIELD_SUBTYPE_TIME,
17
+ FIELD_SUBTYPE_TIMESTAMP,
18
+ ]);
19
+ /** Maps a field subtype to the FilterSubType category used in generated FilterAllowlist. */
20
+ function filterSubTypeFor(fieldSubType) {
21
+ if (fieldSubType === FIELD_SUBTYPE_BOOLEAN)
22
+ return "boolean";
23
+ if (NUMBER_SUBTYPES.has(fieldSubType))
24
+ return "number";
25
+ if (DATETIME_SUBTYPES.has(fieldSubType))
26
+ return "datetime";
27
+ return "string";
28
+ }
29
+ function filterableFields(entity) {
30
+ // fields() returns effective fields, so inherited fields (from extends:/super:) are included in allowlists.
31
+ return entity.fields().filter((c) => c.ownAttr(FIELD_ATTR_FILTERABLE) === true);
32
+ }
33
+ export function renderFilterAllowlist(entity) {
34
+ const fields = filterableFields(entity);
35
+ if (fields.length === 0) {
36
+ return code `
37
+ import type { FilterAllowlist } from "@metaobjectsdev/runtime-ts/drizzle-fastify";
38
+
39
+ export const ${entity.name}FilterAllowlist = {} as const satisfies FilterAllowlist;
40
+ `;
41
+ }
42
+ const rows = fields
43
+ .map((f) => {
44
+ const ops = opsForSubType(f.subType).map((o) => JSON.stringify(o)).join(", ");
45
+ const sub = filterSubTypeFor(f.subType);
46
+ return ` ${f.name}: { ops: [${ops}] as const, subType: ${JSON.stringify(sub)} as const, leadingWildcard: false }`;
47
+ })
48
+ .join(",\n");
49
+ return code `
50
+ import type { FilterAllowlist } from "@metaobjectsdev/runtime-ts/drizzle-fastify";
51
+
52
+ export const ${entity.name}FilterAllowlist = {
53
+ ${rows}
54
+ } as const satisfies FilterAllowlist;
55
+ `;
56
+ }
57
+ export function renderSortAllowlist(entity) {
58
+ // Sortable = explicit @sortable === true, OR (no @sortable AND @filterable === true).
59
+ // @sortable: false explicitly opts out.
60
+ // Uses shared isSortableField predicate — must stay in sync with renderFilterType.
61
+ const sortable = sortableFields(entity);
62
+ if (sortable.length === 0) {
63
+ return code `
64
+ import type { SortAllowlist } from "@metaobjectsdev/runtime-ts/drizzle-fastify";
65
+
66
+ export const ${entity.name}SortAllowlist = {} as const satisfies SortAllowlist;
67
+ `;
68
+ }
69
+ const rows = sortable
70
+ .map((f) => {
71
+ const defaultOrder = f.ownAttr(FIELD_ATTR_SORTABLE_DEFAULT_ORDER);
72
+ const rule = defaultOrder === "asc" || defaultOrder === "desc"
73
+ ? `{ defaultOrder: ${JSON.stringify(defaultOrder)} as const }`
74
+ : `{}`;
75
+ return ` ${f.name}: ${rule}`;
76
+ })
77
+ .join(",\n");
78
+ return code `
79
+ import type { SortAllowlist } from "@metaobjectsdev/runtime-ts/drizzle-fastify";
80
+
81
+ export const ${entity.name}SortAllowlist = {
82
+ ${rows}
83
+ } as const satisfies SortAllowlist;
84
+ `;
85
+ }
86
+ //# sourceMappingURL=filter-allowlist.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"filter-allowlist.js","sourceRoot":"","sources":["../../src/templates/filter-allowlist.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAa,MAAM,SAAS,CAAC;AAC1C,OAAO,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,0BAA0B,CAAC;AACjE,OAAO,EACL,qBAAqB,EACrB,iCAAiC,EACjC,qBAAqB,EACrB,iBAAiB,EACjB,mBAAmB,EACnB,kBAAkB,EAClB,kBAAkB,EAClB,oBAAoB,EACpB,mBAAmB,EACnB,qBAAqB,EACrB,kBAAkB,EAClB,kBAAkB,EAClB,uBAAuB,EACvB,aAAa,GACd,MAAM,0BAA0B,CAAC;AAClC,OAAO,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AAEpD,MAAM,eAAe,GAAG,IAAI,GAAG,CAAS;IACtC,iBAAiB;IACjB,mBAAmB;IACnB,kBAAkB;IAClB,kBAAkB;IAClB,oBAAoB;IACpB,mBAAmB;IACnB,qBAAqB;CACtB,CAAC,CAAC;AAEH,MAAM,iBAAiB,GAAG,IAAI,GAAG,CAAS;IACxC,kBAAkB;IAClB,kBAAkB;IAClB,uBAAuB;CACxB,CAAC,CAAC;AAEH,4FAA4F;AAC5F,SAAS,gBAAgB,CAAC,YAAoB;IAC5C,IAAI,YAAY,KAAK,qBAAqB;QAAE,OAAO,SAAS,CAAC;IAC7D,IAAI,eAAe,CAAC,GAAG,CAAC,YAAY,CAAC;QAAE,OAAO,QAAQ,CAAC;IACvD,IAAI,iBAAiB,CAAC,GAAG,CAAC,YAAY,CAAC;QAAE,OAAO,UAAU,CAAC;IAC3D,OAAO,QAAQ,CAAC;AAClB,CAAC;AAED,SAAS,gBAAgB,CAAC,MAAkB;IAC1C,4GAA4G;IAC5G,OAAO,MAAM,CAAC,MAAM,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,qBAAqB,CAAC,KAAK,IAAI,CAAC,CAAC;AAClF,CAAC;AAED,MAAM,UAAU,qBAAqB,CAAC,MAAkB;IACtD,MAAM,MAAM,GAAG,gBAAgB,CAAC,MAAM,CAAC,CAAC;IACxC,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACxB,OAAO,IAAI,CAAA;;;eAGA,MAAM,CAAC,IAAI;CACzB,CAAC;IACA,CAAC;IACD,MAAM,IAAI,GAAG,MAAM;SAChB,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE;QACT,MAAM,GAAG,GAAG,aAAa,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC9E,MAAM,GAAG,GAAG,gBAAgB,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC;QACxC,OAAO,KAAK,CAAC,CAAC,IAAI,aAAa,GAAG,wBAAwB,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,qCAAqC,CAAC;IACrH,CAAC,CAAC;SACD,IAAI,CAAC,KAAK,CAAC,CAAC;IACf,OAAO,IAAI,CAAA;;;eAGE,MAAM,CAAC,IAAI;EACxB,IAAI;;CAEL,CAAC;AACF,CAAC;AAED,MAAM,UAAU,mBAAmB,CAAC,MAAkB;IACpD,sFAAsF;IACtF,wCAAwC;IACxC,mFAAmF;IACnF,MAAM,QAAQ,GAAG,cAAc,CAAC,MAAM,CAAC,CAAC;IACxC,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC1B,OAAO,IAAI,CAAA;;;eAGA,MAAM,CAAC,IAAI;CACzB,CAAC;IACA,CAAC;IACD,MAAM,IAAI,GAAG,QAAQ;SAClB,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE;QACT,MAAM,YAAY,GAAG,CAAC,CAAC,OAAO,CAAC,iCAAiC,CAAuB,CAAC;QACxF,MAAM,IAAI,GACR,YAAY,KAAK,KAAK,IAAI,YAAY,KAAK,MAAM;YAC/C,CAAC,CAAC,mBAAmB,IAAI,CAAC,SAAS,CAAC,YAAY,CAAC,aAAa;YAC9D,CAAC,CAAC,IAAI,CAAC;QACX,OAAO,KAAK,CAAC,CAAC,IAAI,KAAK,IAAI,EAAE,CAAC;IAChC,CAAC,CAAC;SACD,IAAI,CAAC,KAAK,CAAC,CAAC;IACf,OAAO,IAAI,CAAA;;;eAGE,MAAM,CAAC,IAAI;EACxB,IAAI;;CAEL,CAAC;AACF,CAAC"}
@@ -0,0 +1,15 @@
1
+ import { MetaField, MetaObject } from "@metaobjectsdev/metadata";
2
+ /**
3
+ * Returns true if the given field should be included in sort operations.
4
+ *
5
+ * Rules (in priority order):
6
+ * 1. @sortable: true → always sortable (even without @filterable)
7
+ * 2. @sortable: false → never sortable (overrides @filterable)
8
+ * 3. no @sortable → sortable iff @filterable === true
9
+ */
10
+ export declare function isSortableField(field: MetaField): boolean;
11
+ /**
12
+ * Returns all sortable field children of the given entity.
13
+ */
14
+ export declare function sortableFields(entity: MetaObject): MetaField[];
15
+ //# sourceMappingURL=filter-shared.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"filter-shared.d.ts","sourceRoot":"","sources":["../../src/templates/filter-shared.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,0BAA0B,CAAC;AAGjE;;;;;;;GAOG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,SAAS,GAAG,OAAO,CAKzD;AAED;;GAEG;AACH,wBAAgB,cAAc,CAAC,MAAM,EAAE,UAAU,GAAG,SAAS,EAAE,CAG9D"}
@@ -0,0 +1,30 @@
1
+ // Shared predicate for "is this field sortable?" — used by both filter-allowlist.ts
2
+ // (SortAllowlist generation) and filter-type.ts (sort union generation).
3
+ // Both must agree on which fields are sortable; keeping them in sync via this shared
4
+ // helper prevents client/server mismatches.
5
+ import { MetaField, MetaObject } from "@metaobjectsdev/metadata";
6
+ import { FIELD_ATTR_FILTERABLE, FIELD_ATTR_SORTABLE } from "@metaobjectsdev/metadata";
7
+ /**
8
+ * Returns true if the given field should be included in sort operations.
9
+ *
10
+ * Rules (in priority order):
11
+ * 1. @sortable: true → always sortable (even without @filterable)
12
+ * 2. @sortable: false → never sortable (overrides @filterable)
13
+ * 3. no @sortable → sortable iff @filterable === true
14
+ */
15
+ export function isSortableField(field) {
16
+ const sortableAttr = field.ownAttr(FIELD_ATTR_SORTABLE);
17
+ if (sortableAttr === true)
18
+ return true;
19
+ if (sortableAttr === false)
20
+ return false;
21
+ return field.ownAttr(FIELD_ATTR_FILTERABLE) === true;
22
+ }
23
+ /**
24
+ * Returns all sortable field children of the given entity.
25
+ */
26
+ export function sortableFields(entity) {
27
+ // fields() returns effective fields, so inherited fields (from extends:/super:) are included in sort ops.
28
+ return entity.fields().filter(isSortableField);
29
+ }
30
+ //# sourceMappingURL=filter-shared.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"filter-shared.js","sourceRoot":"","sources":["../../src/templates/filter-shared.ts"],"names":[],"mappings":"AAAA,oFAAoF;AACpF,yEAAyE;AACzE,qFAAqF;AACrF,4CAA4C;AAE5C,OAAO,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,0BAA0B,CAAC;AACjE,OAAO,EAAE,qBAAqB,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAC;AAEtF;;;;;;;GAOG;AACH,MAAM,UAAU,eAAe,CAAC,KAAgB;IAC9C,MAAM,YAAY,GAAG,KAAK,CAAC,OAAO,CAAC,mBAAmB,CAAC,CAAC;IACxD,IAAI,YAAY,KAAK,IAAI;QAAE,OAAO,IAAI,CAAC;IACvC,IAAI,YAAY,KAAK,KAAK;QAAE,OAAO,KAAK,CAAC;IACzC,OAAO,KAAK,CAAC,OAAO,CAAC,qBAAqB,CAAC,KAAK,IAAI,CAAC;AACvD,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,cAAc,CAAC,MAAkB;IAC/C,0GAA0G;IAC1G,OAAO,MAAM,CAAC,MAAM,EAAE,CAAC,MAAM,CAAC,eAAe,CAAC,CAAC;AACjD,CAAC"}
@@ -0,0 +1,4 @@
1
+ import { type Code } from "ts-poet";
2
+ import { MetaObject } from "@metaobjectsdev/metadata";
3
+ export declare function renderFilterType(entity: MetaObject): Code;
4
+ //# sourceMappingURL=filter-type.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"filter-type.d.ts","sourceRoot":"","sources":["../../src/templates/filter-type.ts"],"names":[],"mappings":"AAIA,OAAO,EAAQ,KAAK,IAAI,EAAE,MAAM,SAAS,CAAC;AAC1C,OAAO,EAAa,UAAU,EAAE,MAAM,0BAA0B,CAAC;AA4CjE,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,UAAU,GAAG,IAAI,CA2CzD"}
@@ -0,0 +1,78 @@
1
+ // Filter type template — emits <Entity>Filter type with subtype-gated operators.
2
+ // String fields get eq/ne/in/like; numbers get eq/ne/gt/gte/lt/lte/in; booleans get eq/isNull only;
3
+ // datetimes get eq/ne/gt/gte/lt/lte/in.
4
+ import { code } from "ts-poet";
5
+ import { MetaField, MetaObject } from "@metaobjectsdev/metadata";
6
+ import { FIELD_ATTR_FILTERABLE, FIELD_SUBTYPE_BOOLEAN, FIELD_SUBTYPE_INT, FIELD_SUBTYPE_SHORT, FIELD_SUBTYPE_BYTE, FIELD_SUBTYPE_LONG, FIELD_SUBTYPE_DOUBLE, FIELD_SUBTYPE_FLOAT, FIELD_SUBTYPE_DECIMAL, opsForSubType, } from "@metaobjectsdev/metadata";
7
+ import { isSortableField } from "./filter-shared.js";
8
+ const NUMBER_SUBTYPES = new Set([
9
+ FIELD_SUBTYPE_INT,
10
+ FIELD_SUBTYPE_SHORT,
11
+ FIELD_SUBTYPE_BYTE,
12
+ FIELD_SUBTYPE_LONG,
13
+ FIELD_SUBTYPE_DOUBLE,
14
+ FIELD_SUBTYPE_FLOAT,
15
+ FIELD_SUBTYPE_DECIMAL,
16
+ ]);
17
+ /** Maps a field subtype to its TS value type name for operator union codegen. */
18
+ function tsNameFor(fieldSubType) {
19
+ if (fieldSubType === FIELD_SUBTYPE_BOOLEAN)
20
+ return "boolean";
21
+ if (NUMBER_SUBTYPES.has(fieldSubType))
22
+ return "number";
23
+ return "string";
24
+ }
25
+ function renderFieldUnion(field) {
26
+ const ops = opsForSubType(field.subType);
27
+ const tsName = tsNameFor(field.subType);
28
+ const opEntries = ops.map((op) => {
29
+ if (op === "in")
30
+ return `in?: ${tsName}[]`;
31
+ if (op === "isNull")
32
+ return `isNull?: boolean`;
33
+ if (op === "like")
34
+ return `like?: string`;
35
+ return `${op}?: ${tsName}`;
36
+ });
37
+ return `${tsName} | { ${opEntries.join("; ")} }`;
38
+ }
39
+ export function renderFilterType(entity) {
40
+ // fields() returns effective fields, so inherited fields (from extends:/super:) are included in filter types.
41
+ const allFields = entity.fields();
42
+ const filterableFieldsList = allFields.filter((c) => c.ownAttr(FIELD_ATTR_FILTERABLE) === true);
43
+ // Sort union uses isSortableField — same predicate as renderSortAllowlist to prevent
44
+ // client/server mismatches (@filterable: true + @sortable: false must be excluded from both).
45
+ const sortFieldNames = allFields.filter(isSortableField).map((f) => `"${f.name}"`);
46
+ const fieldLines = [];
47
+ for (const f of filterableFieldsList) {
48
+ fieldLines.push(` ${f.name}?: ${renderFieldUnion(f)};`);
49
+ }
50
+ if (fieldLines.length === 0 && sortFieldNames.length === 0) {
51
+ return code `
52
+ export type ${entity.name}Filter = {
53
+ limit?: number;
54
+ offset?: number;
55
+ sort?: string;
56
+ or?: ${entity.name}Filter[];
57
+ and?: ${entity.name}Filter[];
58
+ };
59
+ `;
60
+ }
61
+ const sortType = sortFieldNames.length === 0
62
+ ? `string`
63
+ : (() => {
64
+ const sortUnion = sortFieldNames.join(" | ");
65
+ return `\`\${${sortUnion}}:\${"asc" | "desc"}\` | ${sortUnion}`;
66
+ })();
67
+ return code `
68
+ export type ${entity.name}Filter = {
69
+ limit?: number;
70
+ offset?: number;
71
+ sort?: ${sortType};
72
+ ${fieldLines.join("\n")}
73
+ or?: ${entity.name}Filter[];
74
+ and?: ${entity.name}Filter[];
75
+ };
76
+ `;
77
+ }
78
+ //# sourceMappingURL=filter-type.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"filter-type.js","sourceRoot":"","sources":["../../src/templates/filter-type.ts"],"names":[],"mappings":"AAAA,iFAAiF;AACjF,oGAAoG;AACpG,wCAAwC;AAExC,OAAO,EAAE,IAAI,EAAa,MAAM,SAAS,CAAC;AAC1C,OAAO,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,0BAA0B,CAAC;AACjE,OAAO,EACL,qBAAqB,EACrB,qBAAqB,EACrB,iBAAiB,EACjB,mBAAmB,EACnB,kBAAkB,EAClB,kBAAkB,EAClB,oBAAoB,EACpB,mBAAmB,EACnB,qBAAqB,EACrB,aAAa,GACd,MAAM,0BAA0B,CAAC;AAClC,OAAO,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AAErD,MAAM,eAAe,GAAG,IAAI,GAAG,CAAS;IACtC,iBAAiB;IACjB,mBAAmB;IACnB,kBAAkB;IAClB,kBAAkB;IAClB,oBAAoB;IACpB,mBAAmB;IACnB,qBAAqB;CACtB,CAAC,CAAC;AAEH,iFAAiF;AACjF,SAAS,SAAS,CAAC,YAAoB;IACrC,IAAI,YAAY,KAAK,qBAAqB;QAAE,OAAO,SAAS,CAAC;IAC7D,IAAI,eAAe,CAAC,GAAG,CAAC,YAAY,CAAC;QAAE,OAAO,QAAQ,CAAC;IACvD,OAAO,QAAQ,CAAC;AAClB,CAAC;AAED,SAAS,gBAAgB,CAAC,KAAgB;IACxC,MAAM,GAAG,GAAG,aAAa,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;IACzC,MAAM,MAAM,GAAG,SAAS,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;IACxC,MAAM,SAAS,GAAG,GAAG,CAAC,GAAG,CAAC,CAAC,EAAE,EAAE,EAAE;QAC/B,IAAI,EAAE,KAAK,IAAI;YAAE,OAAO,QAAQ,MAAM,IAAI,CAAC;QAC3C,IAAI,EAAE,KAAK,QAAQ;YAAE,OAAO,kBAAkB,CAAC;QAC/C,IAAI,EAAE,KAAK,MAAM;YAAE,OAAO,eAAe,CAAC;QAC1C,OAAO,GAAG,EAAE,MAAM,MAAM,EAAE,CAAC;IAC7B,CAAC,CAAC,CAAC;IACH,OAAO,GAAG,MAAM,QAAQ,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC;AACnD,CAAC;AAED,MAAM,UAAU,gBAAgB,CAAC,MAAkB;IACjD,8GAA8G;IAC9G,MAAM,SAAS,GAAG,MAAM,CAAC,MAAM,EAAE,CAAC;IAClC,MAAM,oBAAoB,GAAG,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,qBAAqB,CAAC,KAAK,IAAI,CAAC,CAAC;IAChG,qFAAqF;IACrF,8FAA8F;IAC9F,MAAM,cAAc,GAAG,SAAS,CAAC,MAAM,CAAC,eAAe,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,CAAC,IAAI,GAAG,CAAC,CAAC;IAEnF,MAAM,UAAU,GAAa,EAAE,CAAC;IAChC,KAAK,MAAM,CAAC,IAAI,oBAAoB,EAAE,CAAC;QACrC,UAAU,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,IAAI,MAAM,gBAAgB,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;IAC3D,CAAC;IAED,IAAI,UAAU,CAAC,MAAM,KAAK,CAAC,IAAI,cAAc,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC3D,OAAO,IAAI,CAAA;cACD,MAAM,CAAC,IAAI;;;;SAIhB,MAAM,CAAC,IAAI;UACV,MAAM,CAAC,IAAI;;CAEpB,CAAC;IACA,CAAC;IAED,MAAM,QAAQ,GACZ,cAAc,CAAC,MAAM,KAAK,CAAC;QACzB,CAAC,CAAC,QAAQ;QACV,CAAC,CAAC,CAAC,GAAG,EAAE;YACJ,MAAM,SAAS,GAAG,cAAc,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;YAC7C,OAAO,QAAQ,SAAS,4BAA4B,SAAS,EAAE,CAAC;QAClE,CAAC,CAAC,EAAE,CAAC;IAEX,OAAO,IAAI,CAAA;cACC,MAAM,CAAC,IAAI;;;WAGd,QAAQ;EACjB,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC;SACd,MAAM,CAAC,IAAI;UACV,MAAM,CAAC,IAAI;;CAEpB,CAAC;AACF,CAAC"}
@@ -0,0 +1,4 @@
1
+ import { type Code } from "ts-poet";
2
+ import type { MetaObject } from "@metaobjectsdev/metadata";
3
+ export declare function renderInferredTypes(entity: MetaObject): Code;
4
+ //# sourceMappingURL=inferred-types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"inferred-types.d.ts","sourceRoot":"","sources":["../../src/templates/inferred-types.ts"],"names":[],"mappings":"AAEA,OAAO,EAAa,KAAK,IAAI,EAAE,MAAM,SAAS,CAAC;AAC/C,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,0BAA0B,CAAC;AAG3D,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,UAAU,GAAG,IAAI,CAS5D"}
@@ -0,0 +1,14 @@
1
+ // Inferred types template — emits Drizzle's InferSelectModel / InferInsertModel type aliases.
2
+ import { code, imp } from "ts-poet";
3
+ import { variableNameFromEntity } from "../naming.js";
4
+ export function renderInferredTypes(entity) {
5
+ const varName = variableNameFromEntity(entity.name);
6
+ const selectSym = imp("InferSelectModel@drizzle-orm");
7
+ const insertSym = imp("InferInsertModel@drizzle-orm");
8
+ return code `
9
+ export type ${entity.name} = ${selectSym}<typeof ${varName}>;
10
+ export type ${entity.name}Insert = ${insertSym}<typeof ${varName}>;
11
+ export type ${entity.name}Update = Partial<${entity.name}Insert>;
12
+ `;
13
+ }
14
+ //# sourceMappingURL=inferred-types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"inferred-types.js","sourceRoot":"","sources":["../../src/templates/inferred-types.ts"],"names":[],"mappings":"AAAA,8FAA8F;AAE9F,OAAO,EAAE,IAAI,EAAE,GAAG,EAAa,MAAM,SAAS,CAAC;AAE/C,OAAO,EAAE,sBAAsB,EAAE,MAAM,cAAc,CAAC;AAEtD,MAAM,UAAU,mBAAmB,CAAC,MAAkB;IACpD,MAAM,OAAO,GAAG,sBAAsB,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;IACpD,MAAM,SAAS,GAAG,GAAG,CAAC,8BAA8B,CAAC,CAAC;IACtD,MAAM,SAAS,GAAG,GAAG,CAAC,8BAA8B,CAAC,CAAC;IACtD,OAAO,IAAI,CAAA;cACC,MAAM,CAAC,IAAI,MAAM,SAAS,WAAW,OAAO;cAC5C,MAAM,CAAC,IAAI,YAAY,SAAS,WAAW,OAAO;cAClD,MAAM,CAAC,IAAI,oBAAoB,MAAM,CAAC,IAAI;CACvD,CAAC;AACF,CAAC"}
@@ -0,0 +1,21 @@
1
+ import { MetaObject, type MetaRoot } from "@metaobjectsdev/metadata";
2
+ import type { ColumnNamingStrategy } from "../metaobjects-config.js";
3
+ export interface ProjectionDeclOpts {
4
+ readonly columnNamingStrategy: ColumnNamingStrategy;
5
+ readonly dialect: "postgres" | "sqlite";
6
+ readonly apiPrefix?: string;
7
+ }
8
+ /**
9
+ * Render a TypeScript module for a projection entity. Emits:
10
+ * - `<camel>View` — Drizzle `pgView` / `sqliteView` with `.existing()`
11
+ * - `<Projection>Schema` — Zod read schema (no insert/update)
12
+ * - `<Projection>` — `z.infer` type alias
13
+ * - `<Projection>` const — constants block ($entity, $view, $path, per-field metadata)
14
+ *
15
+ * @param projection The projection entity (has a source[dbView] child).
16
+ * @param root The loader's root (all top-level objects as direct children,
17
+ * from `MetaDataLoader.load()` / `FileMetaDataLoader.loadFiles()` as `result.root`).
18
+ * @param opts Column naming strategy + dialect.
19
+ */
20
+ export declare function renderProjectionDecl(projection: MetaObject, root: MetaRoot, opts: ProjectionDeclOpts): string;
21
+ //# sourceMappingURL=projection-decl.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"projection-decl.d.ts","sourceRoot":"","sources":["../../src/templates/projection-decl.ts"],"names":[],"mappings":"AAUA,OAAO,EAAa,UAAU,EAAE,KAAK,QAAQ,EAAE,MAAM,0BAA0B,CAAC;AAIhF,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,0BAA0B,CAAC;AASrE,MAAM,WAAW,kBAAkB;IACjC,QAAQ,CAAC,oBAAoB,EAAE,oBAAoB,CAAC;IACpD,QAAQ,CAAC,OAAO,EAAE,UAAU,GAAG,QAAQ,CAAC;IACxC,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;CAC7B;AAsBD;;;;;;;;;;;GAWG;AACH,wBAAgB,oBAAoB,CAClC,UAAU,EAAE,UAAU,EACtB,IAAI,EAAE,QAAQ,EACd,IAAI,EAAE,kBAAkB,GACvB,MAAM,CAgFR"}
@@ -0,0 +1,116 @@
1
+ // Projection declaration template — emits a Drizzle view declaration,
2
+ // a Zod read schema, the TS type via z.infer, and a constants block.
3
+ //
4
+ // This is the read-only counterpart to entity-file.ts.
5
+ // It does NOT emit:
6
+ // - Drizzle table declaration (view-only)
7
+ // - Zod Insert/Update schemas
8
+ // - Insert/Update types
9
+ import { code, imp, joinCode } from "ts-poet";
10
+ import { MetaField, MetaObject } from "@metaobjectsdev/metadata";
11
+ import { extractViewSpec } from "../projection/extract-view-spec.js";
12
+ import { columnNameFromField, toSnakeCase, pluralize } from "../naming.js";
13
+ import { GENERATED_HEADER } from "../constants.js";
14
+ import { renderFilterAllowlist, renderSortAllowlist } from "./filter-allowlist.js";
15
+ import { renderFilterType } from "./filter-type.js";
16
+ import { inferViewKind, zodTypeFor, currencyMetaFor, labelFor } from "./field-meta.js";
17
+ // ---------------------------------------------------------------------------
18
+ // Helpers
19
+ // ---------------------------------------------------------------------------
20
+ /**
21
+ * Convert a PascalCase projection name to a kebab-pluralized URL path.
22
+ * "ProgramSummary" → "/program-summaries"
23
+ * "CustomerSummary" → "/customer-summaries"
24
+ * "Box" → "/boxes"
25
+ * "Wish" → "/wishes"
26
+ */
27
+ function pathFromProjectionName(name) {
28
+ const kebab = toSnakeCase(pluralize(name)).replace(/_/g, "-");
29
+ return `/${kebab}`;
30
+ }
31
+ // ---------------------------------------------------------------------------
32
+ // Public API
33
+ // ---------------------------------------------------------------------------
34
+ /**
35
+ * Render a TypeScript module for a projection entity. Emits:
36
+ * - `<camel>View` — Drizzle `pgView` / `sqliteView` with `.existing()`
37
+ * - `<Projection>Schema` — Zod read schema (no insert/update)
38
+ * - `<Projection>` — `z.infer` type alias
39
+ * - `<Projection>` const — constants block ($entity, $view, $path, per-field metadata)
40
+ *
41
+ * @param projection The projection entity (has a source[dbView] child).
42
+ * @param root The loader's root (all top-level objects as direct children,
43
+ * from `MetaDataLoader.load()` / `FileMetaDataLoader.loadFiles()` as `result.root`).
44
+ * @param opts Column naming strategy + dialect.
45
+ */
46
+ export function renderProjectionDecl(projection, root, opts) {
47
+ const { dialect, columnNamingStrategy, apiPrefix = "" } = opts;
48
+ const viewFn = dialect === "postgres" ? "pgView" : "sqliteView";
49
+ const viewModule = dialect === "postgres" ? "drizzle-orm/pg-core" : "drizzle-orm/sqlite-core";
50
+ const viewSym = imp(`${viewFn}@${viewModule}`);
51
+ const z = imp("z@zod");
52
+ const spec = extractViewSpec(projection, root, { columnNamingStrategy });
53
+ // Collect fields: inherited from extends parent first, then projection-declared.
54
+ const allFields = [];
55
+ const superModel = projection.superResolved;
56
+ const superName = superModel?.name ?? projection.superRef;
57
+ if (superName) {
58
+ const baseObj = superModel instanceof MetaObject ? superModel : root.findObject(superName);
59
+ if (baseObj) {
60
+ // fields() returns effective fields, so inherited fields (from extends:/super:) are included.
61
+ for (const f of baseObj.fields())
62
+ allFields.push(f);
63
+ }
64
+ }
65
+ for (const f of projection.ownFields())
66
+ allFields.push(f);
67
+ const zodLines = allFields.map((f) => code ` ${f.name}: ${z}.${zodTypeFor(f).replace(/^z\./, "")}`);
68
+ const constFieldLines = allFields.map((f) => {
69
+ const dbCol = columnNameFromField(f.name, columnNamingStrategy);
70
+ const view = inferViewKind(f);
71
+ const label = labelFor(f);
72
+ const baseEntry = `name: ${JSON.stringify(f.name)}, label: ${JSON.stringify(label)}, view: ${JSON.stringify(view)}, dbCol: ${JSON.stringify(dbCol)}`;
73
+ const currencyMeta = currencyMetaFor(f);
74
+ if (currencyMeta !== null) {
75
+ return ` ${f.name}: { ${baseEntry}, currency: ${JSON.stringify(currencyMeta.currency)}, locale: ${JSON.stringify(currencyMeta.locale)} },`;
76
+ }
77
+ return ` ${f.name}: { ${baseEntry} },`;
78
+ });
79
+ const projName = projection.name;
80
+ const camelName = projName.charAt(0).toLowerCase() + projName.slice(1);
81
+ const path = pathFromProjectionName(projName);
82
+ const viewName = spec.viewName;
83
+ const sections = [
84
+ code `
85
+ // View declaration — Drizzle uses this for typed SELECT queries.
86
+ // The SQL view is created/managed by migrate-ts; .existing() tells Drizzle
87
+ // not to attempt DDL for this declaration.
88
+ export const ${camelName}View = ${viewSym}(${JSON.stringify(viewName)}, {}).existing();
89
+ `,
90
+ code `
91
+ export const ${projName}Schema = ${z}.object({
92
+ ${joinCode(zodLines, { on: ",\n" })}
93
+ });
94
+ `,
95
+ code `
96
+ export type ${projName} = ${z}.infer<typeof ${projName}Schema>;
97
+ `,
98
+ code `
99
+ export const ${projName} = {
100
+ $entity: ${JSON.stringify(projName)},
101
+ $view: ${JSON.stringify(viewName)},
102
+ $path: ${JSON.stringify(path)},
103
+ $apiPrefix: ${JSON.stringify(apiPrefix)},
104
+ ${constFieldLines.join("\n")}
105
+ } as const;
106
+ `,
107
+ renderFilterAllowlist(projection),
108
+ renderSortAllowlist(projection),
109
+ renderFilterType(projection),
110
+ ];
111
+ const body = joinCode(sections, { on: "\n" }).toString();
112
+ const header = `// ${GENERATED_HEADER} — DO NOT EDIT.\n` +
113
+ `// Source metadata: ${projName} (${projection.fqn()})\n`;
114
+ return header + body;
115
+ }
116
+ //# sourceMappingURL=projection-decl.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"projection-decl.js","sourceRoot":"","sources":["../../src/templates/projection-decl.ts"],"names":[],"mappings":"AAAA,sEAAsE;AACtE,qEAAqE;AACrE,EAAE;AACF,uDAAuD;AACvD,oBAAoB;AACpB,4CAA4C;AAC5C,gCAAgC;AAChC,0BAA0B;AAE1B,OAAO,EAAE,IAAI,EAAE,GAAG,EAAE,QAAQ,EAAa,MAAM,SAAS,CAAC;AACzD,OAAO,EAAE,SAAS,EAAE,UAAU,EAAiB,MAAM,0BAA0B,CAAC;AAChF,OAAO,EAAE,eAAe,EAAE,MAAM,oCAAoC,CAAC;AACrE,OAAO,EAAE,mBAAmB,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAC3E,OAAO,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AAEnD,OAAO,EAAE,qBAAqB,EAAE,mBAAmB,EAAE,MAAM,uBAAuB,CAAC;AACnF,OAAO,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AACpD,OAAO,EAAE,aAAa,EAAE,UAAU,EAAE,eAAe,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AAYvF,8EAA8E;AAC9E,UAAU;AACV,8EAA8E;AAE9E;;;;;;GAMG;AACH,SAAS,sBAAsB,CAAC,IAAY;IAC1C,MAAM,KAAK,GAAG,WAAW,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,OAAO,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC;IAC9D,OAAO,IAAI,KAAK,EAAE,CAAC;AACrB,CAAC;AAED,8EAA8E;AAC9E,aAAa;AACb,8EAA8E;AAE9E;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,oBAAoB,CAClC,UAAsB,EACtB,IAAc,EACd,IAAwB;IAExB,MAAM,EAAE,OAAO,EAAE,oBAAoB,EAAE,SAAS,GAAG,EAAE,EAAE,GAAG,IAAI,CAAC;IAE/D,MAAM,MAAM,GAAG,OAAO,KAAK,UAAU,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,YAAY,CAAC;IAChE,MAAM,UAAU,GACd,OAAO,KAAK,UAAU,CAAC,CAAC,CAAC,qBAAqB,CAAC,CAAC,CAAC,yBAAyB,CAAC;IAC7E,MAAM,OAAO,GAAG,GAAG,CAAC,GAAG,MAAM,IAAI,UAAU,EAAE,CAAC,CAAC;IAC/C,MAAM,CAAC,GAAG,GAAG,CAAC,OAAO,CAAC,CAAC;IAEvB,MAAM,IAAI,GAAG,eAAe,CAAC,UAAU,EAAE,IAAI,EAAE,EAAE,oBAAoB,EAAE,CAAC,CAAC;IAEzE,iFAAiF;IACjF,MAAM,SAAS,GAAgB,EAAE,CAAC;IAClC,MAAM,UAAU,GAAG,UAAU,CAAC,aAAa,CAAC;IAC5C,MAAM,SAAS,GAAG,UAAU,EAAE,IAAI,IAAI,UAAU,CAAC,QAAQ,CAAC;IAC1D,IAAI,SAAS,EAAE,CAAC;QACd,MAAM,OAAO,GACX,UAAU,YAAY,UAAU,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,SAAS,CAAC,CAAC;QAC7E,IAAI,OAAO,EAAE,CAAC;YACZ,8FAA8F;YAC9F,KAAK,MAAM,CAAC,IAAI,OAAO,CAAC,MAAM,EAAE;gBAAE,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QACtD,CAAC;IACH,CAAC;IACD,KAAK,MAAM,CAAC,IAAI,UAAU,CAAC,SAAS,EAAE;QAAE,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAE1D,MAAM,QAAQ,GAAW,SAAS,CAAC,GAAG,CACpC,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,CAAA,KAAK,CAAC,CAAC,IAAI,KAAK,CAAC,IAAI,UAAU,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,EAAE,CACpE,CAAC;IAEF,MAAM,eAAe,GAAa,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE;QACpD,MAAM,KAAK,GAAG,mBAAmB,CAAC,CAAC,CAAC,IAAI,EAAE,oBAAoB,CAAC,CAAC;QAChE,MAAM,IAAI,GAAG,aAAa,CAAC,CAAC,CAAC,CAAC;QAC9B,MAAM,KAAK,GAAG,QAAQ,CAAC,CAAC,CAAC,CAAC;QAC1B,MAAM,SAAS,GAAG,SAAS,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,YAAY,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,WAAW,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,YAAY,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,EAAE,CAAC;QACrJ,MAAM,YAAY,GAAG,eAAe,CAAC,CAAC,CAAC,CAAC;QACxC,IAAI,YAAY,KAAK,IAAI,EAAE,CAAC;YAC1B,OAAO,KAAK,CAAC,CAAC,IAAI,OAAO,SAAS,eAAe,IAAI,CAAC,SAAS,CAAC,YAAY,CAAC,QAAQ,CAAC,aAAa,IAAI,CAAC,SAAS,CAAC,YAAY,CAAC,MAAM,CAAC,KAAK,CAAC;QAC9I,CAAC;QACD,OAAO,KAAK,CAAC,CAAC,IAAI,OAAO,SAAS,KAAK,CAAC;IAC1C,CAAC,CAAC,CAAC;IAEH,MAAM,QAAQ,GAAG,UAAU,CAAC,IAAI,CAAC;IACjC,MAAM,SAAS,GAAG,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;IACvE,MAAM,IAAI,GAAG,sBAAsB,CAAC,QAAQ,CAAC,CAAC;IAC9C,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,CAAC;IAE/B,MAAM,QAAQ,GAAW;QACvB,IAAI,CAAA;;;;eAIO,SAAS,UAAU,OAAO,IAAI,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC;CACpE;QACG,IAAI,CAAA;eACO,QAAQ,YAAY,CAAC;EAClC,QAAQ,CAAC,QAAQ,EAAE,EAAE,EAAE,EAAE,KAAK,EAAE,CAAC;;CAElC;QACG,IAAI,CAAA;cACM,QAAQ,MAAM,CAAC,iBAAiB,QAAQ;CACrD;QACG,IAAI,CAAA;eACO,QAAQ;gBACP,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC;gBACxB,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC;gBACxB,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC;gBACpB,IAAI,CAAC,SAAS,CAAC,SAAS,CAAC;EACvC,eAAe,CAAC,IAAI,CAAC,IAAI,CAAC;;CAE3B;QACG,qBAAqB,CAAC,UAAU,CAAC;QACjC,mBAAmB,CAAC,UAAU,CAAC;QAC/B,gBAAgB,CAAC,UAAU,CAAC;KAC7B,CAAC;IAEF,MAAM,IAAI,GAAG,QAAQ,CAAC,QAAQ,EAAE,EAAE,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC,QAAQ,EAAE,CAAC;IACzD,MAAM,MAAM,GACV,MAAM,gBAAgB,mBAAmB;QACzC,uBAAuB,QAAQ,KAAK,UAAU,CAAC,GAAG,EAAE,KAAK,CAAC;IAC5D,OAAO,MAAM,GAAG,IAAI,CAAC;AACvB,CAAC"}
@@ -0,0 +1,4 @@
1
+ import { MetaObject } from "@metaobjectsdev/metadata";
2
+ import { type RenderContext } from "../render-context.js";
3
+ export declare function renderQueriesFile(obj: MetaObject, ctx: RenderContext): string;
4
+ //# sourceMappingURL=queries-file.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"queries-file.d.ts","sourceRoot":"","sources":["../../src/templates/queries-file.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,UAAU,EAAE,MAAM,0BAA0B,CAAC;AACtD,OAAO,EAAE,KAAK,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAY1D,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,UAAU,EAAE,GAAG,EAAE,aAAa,GAAG,MAAM,CAsC7E"}
@@ -0,0 +1,39 @@
1
+ // Queries file composer — composes all CRUD function renderers (from queries.ts) into
2
+ // a complete <Entity>.queries.ts file with @generated header and correct imports.
3
+ import { code, joinCode } from "ts-poet";
4
+ import { MetaObject } from "@metaobjectsdev/metadata";
5
+ import {} from "../render-context.js";
6
+ import { entityModuleSpecifier, relativeModuleSpecifier } from "../import-path.js";
7
+ import { renderFindByIdFn, renderListFn, renderCreateFn, renderUpdateFn, renderDeleteByIdFn, } from "./queries.js";
8
+ import { variableNameFromEntity } from "../naming.js";
9
+ import { GENERATED_HEADER } from "../constants.js";
10
+ export function renderQueriesFile(obj, ctx) {
11
+ const entityName = obj.name;
12
+ // Import the entity's own file. Same target → relative "./Entity"; cross
13
+ // target → importBase-qualified package path.
14
+ const entityFileName = entityModuleSpecifier(ctx.selfTarget, ctx.entityModuleTarget, obj.package, entityName, ctx.extStyle);
15
+ const dbImportSpec = relativeModuleSpecifier(ctx.outputLayout, obj.package, ctx.dbImport);
16
+ const varName = variableNameFromEntity(entityName);
17
+ // Literal imports (db + entity types) live in a code block so they sort
18
+ // alongside ts-poet's hoisted imp() imports at the top of the body.
19
+ const literalImports = code `
20
+ import { db } from ${JSON.stringify(dbImportSpec)};
21
+ import { ${varName}, type ${entityName}, ${entityName}InsertSchema } from ${JSON.stringify(entityFileName)};
22
+ `;
23
+ const sections = [
24
+ literalImports,
25
+ renderFindByIdFn(obj, ctx),
26
+ renderListFn(obj, ctx),
27
+ renderCreateFn(obj, ctx),
28
+ renderUpdateFn(obj, ctx),
29
+ renderDeleteByIdFn(obj, ctx),
30
+ ];
31
+ // Render ts-poet body first, then prepend the @generated header so it lands
32
+ // at line 1 ahead of any imports.
33
+ const body = joinCode(sections, { on: "\n" }).toString();
34
+ const header = `// ${GENERATED_HEADER} — DO NOT EDIT.\n` +
35
+ `// Source metadata: ${entityName} (${obj.fqn()})\n` +
36
+ `// Customize via ${entityName}.extra.ts in this directory (additional queries, custom logic).\n`;
37
+ return header + body;
38
+ }
39
+ //# sourceMappingURL=queries-file.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"queries-file.js","sourceRoot":"","sources":["../../src/templates/queries-file.ts"],"names":[],"mappings":"AAAA,sFAAsF;AACtF,kFAAkF;AAElF,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAa,MAAM,SAAS,CAAC;AACpD,OAAO,EAAE,UAAU,EAAE,MAAM,0BAA0B,CAAC;AACtD,OAAO,EAAsB,MAAM,sBAAsB,CAAC;AAC1D,OAAO,EAAE,qBAAqB,EAAE,uBAAuB,EAAE,MAAM,mBAAmB,CAAC;AACnF,OAAO,EACL,gBAAgB,EAChB,YAAY,EACZ,cAAc,EACd,cAAc,EACd,kBAAkB,GACnB,MAAM,cAAc,CAAC;AACtB,OAAO,EAAE,sBAAsB,EAAE,MAAM,cAAc,CAAC;AACtD,OAAO,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AAEnD,MAAM,UAAU,iBAAiB,CAAC,GAAe,EAAE,GAAkB;IACnE,MAAM,UAAU,GAAG,GAAG,CAAC,IAAI,CAAC;IAC5B,yEAAyE;IACzE,8CAA8C;IAC9C,MAAM,cAAc,GAAG,qBAAqB,CAC1C,GAAG,CAAC,UAAU,EACd,GAAG,CAAC,kBAAkB,EACtB,GAAG,CAAC,OAAO,EACX,UAAU,EACV,GAAG,CAAC,QAAQ,CACb,CAAC;IACF,MAAM,YAAY,GAAG,uBAAuB,CAAC,GAAG,CAAC,YAAY,EAAE,GAAG,CAAC,OAAO,EAAE,GAAG,CAAC,QAAQ,CAAC,CAAC;IAC1F,MAAM,OAAO,GAAG,sBAAsB,CAAC,UAAU,CAAC,CAAC;IAEnD,wEAAwE;IACxE,oEAAoE;IACpE,MAAM,cAAc,GAAG,IAAI,CAAA;qBACR,IAAI,CAAC,SAAS,CAAC,YAAY,CAAC;WACtC,OAAO,UAAU,UAAU,KAAK,UAAU,uBAAuB,IAAI,CAAC,SAAS,CAAC,cAAc,CAAC;CACzG,CAAC;IAEA,MAAM,QAAQ,GAAW;QACvB,cAAc;QACd,gBAAgB,CAAC,GAAG,EAAE,GAAG,CAAC;QAC1B,YAAY,CAAC,GAAG,EAAE,GAAG,CAAC;QACtB,cAAc,CAAC,GAAG,EAAE,GAAG,CAAC;QACxB,cAAc,CAAC,GAAG,EAAE,GAAG,CAAC;QACxB,kBAAkB,CAAC,GAAG,EAAE,GAAG,CAAC;KAC7B,CAAC;IAEF,4EAA4E;IAC5E,kCAAkC;IAClC,MAAM,IAAI,GAAG,QAAQ,CAAC,QAAQ,EAAE,EAAE,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC,QAAQ,EAAE,CAAC;IACzD,MAAM,MAAM,GACV,MAAM,gBAAgB,mBAAmB;QACzC,uBAAuB,UAAU,KAAK,GAAG,CAAC,GAAG,EAAE,KAAK;QACpD,oBAAoB,UAAU,mEAAmE,CAAC;IACpG,OAAO,MAAM,GAAG,IAAI,CAAC;AACvB,CAAC"}
@@ -0,0 +1,9 @@
1
+ import { type Code } from "ts-poet";
2
+ import type { MetaObject } from "@metaobjectsdev/metadata";
3
+ import type { RenderContext } from "../render-context.js";
4
+ export declare function renderFindByIdFn(entity: MetaObject, ctx: RenderContext): Code;
5
+ export declare function renderListFn(entity: MetaObject, _ctx: RenderContext): Code;
6
+ export declare function renderCreateFn(entity: MetaObject, _ctx: RenderContext): Code;
7
+ export declare function renderUpdateFn(entity: MetaObject, ctx: RenderContext): Code;
8
+ export declare function renderDeleteByIdFn(entity: MetaObject, ctx: RenderContext): Code;
9
+ //# sourceMappingURL=queries.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"queries.d.ts","sourceRoot":"","sources":["../../src/templates/queries.ts"],"names":[],"mappings":"AAGA,OAAO,EAAa,KAAK,IAAI,EAAE,MAAM,SAAS,CAAC;AAC/C,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,0BAA0B,CAAC;AAE3D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AA0B1D,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,UAAU,EAAE,GAAG,EAAE,aAAa,GAAG,IAAI,CAgC7E;AAED,wBAAgB,YAAY,CAAC,MAAM,EAAE,UAAU,EAAE,IAAI,EAAE,aAAa,GAAG,IAAI,CAe1E;AAED,wBAAgB,cAAc,CAAC,MAAM,EAAE,UAAU,EAAE,IAAI,EAAE,aAAa,GAAG,IAAI,CAc5E;AAED,wBAAgB,cAAc,CAAC,MAAM,EAAE,UAAU,EAAE,GAAG,EAAE,aAAa,GAAG,IAAI,CAgB3E;AAED,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,UAAU,EAAE,GAAG,EAAE,aAAa,GAAG,IAAI,CAc/E"}