@metaobjectsdev/metadata 1.0.13 → 1.1.1-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 (233) hide show
  1. package/README.md +2 -0
  2. package/dist/attr-schema-validate.d.ts.map +1 -1
  3. package/dist/attr-schema-validate.js +9 -12
  4. package/dist/attr-schema-validate.js.map +1 -1
  5. package/dist/constants.d.ts +1 -0
  6. package/dist/constants.d.ts.map +1 -1
  7. package/dist/constants.js +1 -0
  8. package/dist/constants.js.map +1 -1
  9. package/dist/core/attr/meta-attr-filter.d.ts.map +1 -1
  10. package/dist/core/attr/meta-attr-filter.js +8 -2
  11. package/dist/core/attr/meta-attr-filter.js.map +1 -1
  12. package/dist/core/attr/meta-attr.d.ts +14 -0
  13. package/dist/core/attr/meta-attr.d.ts.map +1 -1
  14. package/dist/core/attr/meta-attr.js +23 -1
  15. package/dist/core/attr/meta-attr.js.map +1 -1
  16. package/dist/core/field/shared-enum.d.ts +21 -0
  17. package/dist/core/field/shared-enum.d.ts.map +1 -0
  18. package/dist/core/field/shared-enum.js +49 -0
  19. package/dist/core/field/shared-enum.js.map +1 -0
  20. package/dist/core/identity/meta-identity.d.ts +1 -1
  21. package/dist/core/identity/meta-identity.d.ts.map +1 -1
  22. package/dist/core/identity/meta-identity.js +8 -13
  23. package/dist/core/identity/meta-identity.js.map +1 -1
  24. package/dist/core/index.d.ts +2 -0
  25. package/dist/core/index.d.ts.map +1 -1
  26. package/dist/core/index.js +3 -0
  27. package/dist/core/index.js.map +1 -1
  28. package/dist/core/object/object-constants.d.ts +14 -1
  29. package/dist/core/object/object-constants.d.ts.map +1 -1
  30. package/dist/core/object/object-constants.js +18 -0
  31. package/dist/core/object/object-constants.js.map +1 -1
  32. package/dist/core/object/object-definition.embedded.d.ts.map +1 -1
  33. package/dist/core/object/object-definition.embedded.js +80 -0
  34. package/dist/core/object/object-definition.embedded.js.map +1 -1
  35. package/dist/core/relationship/derive-m2m-fields.d.ts +1 -1
  36. package/dist/core/relationship/derive-m2m-fields.d.ts.map +1 -1
  37. package/dist/core/relationship/derive-m2m-fields.js +15 -44
  38. package/dist/core/relationship/derive-m2m-fields.js.map +1 -1
  39. package/dist/core/relationship/find-reference.d.ts.map +1 -1
  40. package/dist/core/relationship/find-reference.js +4 -2
  41. package/dist/core/relationship/find-reference.js.map +1 -1
  42. package/dist/core/relationship/resolve-relationship-reference.d.ts +6 -5
  43. package/dist/core/relationship/resolve-relationship-reference.d.ts.map +1 -1
  44. package/dist/core/relationship/resolve-relationship-reference.js +9 -7
  45. package/dist/core/relationship/resolve-relationship-reference.js.map +1 -1
  46. package/dist/core/reporting/meta-dimension.d.ts +13 -0
  47. package/dist/core/reporting/meta-dimension.d.ts.map +1 -0
  48. package/dist/core/reporting/meta-dimension.js +30 -0
  49. package/dist/core/reporting/meta-dimension.js.map +1 -0
  50. package/dist/core/reporting/meta-measure.d.ts +24 -0
  51. package/dist/core/reporting/meta-measure.d.ts.map +1 -0
  52. package/dist/core/reporting/meta-measure.js +54 -0
  53. package/dist/core/reporting/meta-measure.js.map +1 -0
  54. package/dist/core/reporting/meta-segment.d.ts +6 -0
  55. package/dist/core/reporting/meta-segment.d.ts.map +1 -0
  56. package/dist/core/reporting/meta-segment.js +13 -0
  57. package/dist/core/reporting/meta-segment.js.map +1 -0
  58. package/dist/core/reporting/report-accessors.d.ts +27 -0
  59. package/dist/core/reporting/report-accessors.d.ts.map +1 -0
  60. package/dist/core/reporting/report-accessors.js +56 -0
  61. package/dist/core/reporting/report-accessors.js.map +1 -0
  62. package/dist/core/reporting/report-describe.d.ts +59 -0
  63. package/dist/core/reporting/report-describe.d.ts.map +1 -0
  64. package/dist/core/reporting/report-describe.js +182 -0
  65. package/dist/core/reporting/report-describe.js.map +1 -0
  66. package/dist/core/reporting/report-read-model.d.ts +34 -0
  67. package/dist/core/reporting/report-read-model.d.ts.map +1 -0
  68. package/dist/core/reporting/report-read-model.js +165 -0
  69. package/dist/core/reporting/report-read-model.js.map +1 -0
  70. package/dist/core/reporting/report-shape.d.ts +103 -0
  71. package/dist/core/reporting/report-shape.d.ts.map +1 -0
  72. package/dist/core/reporting/report-shape.js +398 -0
  73. package/dist/core/reporting/report-shape.js.map +1 -0
  74. package/dist/core/reporting/reporting-constants.d.ts +65 -0
  75. package/dist/core/reporting/reporting-constants.d.ts.map +1 -0
  76. package/dist/core/reporting/reporting-constants.js +84 -0
  77. package/dist/core/reporting/reporting-constants.js.map +1 -0
  78. package/dist/core/reporting/reporting-definition.embedded.d.ts +3 -0
  79. package/dist/core/reporting/reporting-definition.embedded.d.ts.map +1 -0
  80. package/dist/core/reporting/reporting-definition.embedded.js +185 -0
  81. package/dist/core/reporting/reporting-definition.embedded.js.map +1 -0
  82. package/dist/core/requirement/resolve-claim.d.ts +8 -0
  83. package/dist/core/requirement/resolve-claim.d.ts.map +1 -1
  84. package/dist/core/requirement/resolve-claim.js +21 -0
  85. package/dist/core/requirement/resolve-claim.js.map +1 -1
  86. package/dist/core/yaml-desugar.d.ts.map +1 -1
  87. package/dist/core/yaml-desugar.js +12 -82
  88. package/dist/core/yaml-desugar.js.map +1 -1
  89. package/dist/core-types.d.ts.map +1 -1
  90. package/dist/core-types.js +28 -1
  91. package/dist/core-types.js.map +1 -1
  92. package/dist/docs-ref.d.ts +19 -0
  93. package/dist/docs-ref.d.ts.map +1 -0
  94. package/dist/docs-ref.js +37 -0
  95. package/dist/docs-ref.js.map +1 -0
  96. package/dist/errors.d.ts +1 -1
  97. package/dist/errors.d.ts.map +1 -1
  98. package/dist/errors.js +17 -6
  99. package/dist/errors.js.map +1 -1
  100. package/dist/fmt.d.ts.map +1 -1
  101. package/dist/fmt.js +3 -1
  102. package/dist/fmt.js.map +1 -1
  103. package/dist/index.d.ts +15 -4
  104. package/dist/index.d.ts.map +1 -1
  105. package/dist/index.js +18 -4
  106. package/dist/index.js.map +1 -1
  107. package/dist/loader/declared-duplicate-fields.d.ts +19 -0
  108. package/dist/loader/declared-duplicate-fields.d.ts.map +1 -0
  109. package/dist/loader/declared-duplicate-fields.js +97 -0
  110. package/dist/loader/declared-duplicate-fields.js.map +1 -0
  111. package/dist/loader/meta-data-loader.d.ts.map +1 -1
  112. package/dist/loader/meta-data-loader.js +18 -1
  113. package/dist/loader/meta-data-loader.js.map +1 -1
  114. package/dist/loader/reporting-validation.d.ts +11 -0
  115. package/dist/loader/reporting-validation.d.ts.map +1 -0
  116. package/dist/loader/reporting-validation.js +883 -0
  117. package/dist/loader/reporting-validation.js.map +1 -0
  118. package/dist/loader/resolve-references.d.ts +8 -0
  119. package/dist/loader/resolve-references.d.ts.map +1 -0
  120. package/dist/loader/resolve-references.js +132 -0
  121. package/dist/loader/resolve-references.js.map +1 -0
  122. package/dist/loader/validation-passes.d.ts.map +1 -1
  123. package/dist/loader/validation-passes.js +14 -9
  124. package/dist/loader/validation-passes.js.map +1 -1
  125. package/dist/loader/validation-registry.d.ts.map +1 -1
  126. package/dist/loader/validation-registry.js +33 -10
  127. package/dist/loader/validation-registry.js.map +1 -1
  128. package/dist/metamodel-docs/index.js +3 -3
  129. package/dist/metamodel-docs/index.js.map +1 -1
  130. package/dist/metamodel-docs/render.js +4 -4
  131. package/dist/metamodel-docs/render.js.map +1 -1
  132. package/dist/naming-refs.d.ts +102 -50
  133. package/dist/naming-refs.d.ts.map +1 -1
  134. package/dist/naming-refs.js +223 -97
  135. package/dist/naming-refs.js.map +1 -1
  136. package/dist/naming.d.ts +42 -7
  137. package/dist/naming.d.ts.map +1 -1
  138. package/dist/naming.js +43 -5
  139. package/dist/naming.js.map +1 -1
  140. package/dist/object-serializer.d.ts.map +1 -1
  141. package/dist/object-serializer.js +6 -9
  142. package/dist/object-serializer.js.map +1 -1
  143. package/dist/parser-core.d.ts.map +1 -1
  144. package/dist/parser-core.js +18 -48
  145. package/dist/parser-core.js.map +1 -1
  146. package/dist/persistence/db/db-definition.embedded.js +2 -2
  147. package/dist/persistence/db/db-definition.embedded.js.map +1 -1
  148. package/dist/persistence/source/meta-source.d.ts +5 -3
  149. package/dist/persistence/source/meta-source.d.ts.map +1 -1
  150. package/dist/persistence/source/meta-source.js +8 -6
  151. package/dist/persistence/source/meta-source.js.map +1 -1
  152. package/dist/registry-manifest-exclusions.js +2 -2
  153. package/dist/registry-manifest-exclusions.js.map +1 -1
  154. package/dist/registry-manifest.d.ts +1 -1
  155. package/dist/registry-manifest.js +1 -1
  156. package/dist/release-docs.d.ts +11 -0
  157. package/dist/release-docs.d.ts.map +1 -0
  158. package/dist/release-docs.js +48 -0
  159. package/dist/release-docs.js.map +1 -0
  160. package/dist/serializer-json.d.ts +15 -1
  161. package/dist/serializer-json.d.ts.map +1 -1
  162. package/dist/serializer-json.js +55 -17
  163. package/dist/serializer-json.js.map +1 -1
  164. package/dist/shared/base-types.d.ts +7 -1
  165. package/dist/shared/base-types.d.ts.map +1 -1
  166. package/dist/shared/base-types.js +9 -0
  167. package/dist/shared/base-types.js.map +1 -1
  168. package/dist/shared/meta-data.d.ts +10 -0
  169. package/dist/shared/meta-data.d.ts.map +1 -1
  170. package/dist/shared/meta-data.js +22 -1
  171. package/dist/shared/meta-data.js.map +1 -1
  172. package/dist/shared/meta-root.d.ts +13 -1
  173. package/dist/shared/meta-root.d.ts.map +1 -1
  174. package/dist/shared/meta-root.js +19 -1
  175. package/dist/shared/meta-root.js.map +1 -1
  176. package/dist/super-resolve.d.ts +4 -1
  177. package/dist/super-resolve.d.ts.map +1 -1
  178. package/dist/super-resolve.js +44 -65
  179. package/dist/super-resolve.js.map +1 -1
  180. package/dist/vocabulary-catalog.js +2 -2
  181. package/dist/vocabulary-catalog.js.map +1 -1
  182. package/package.json +6 -1
  183. package/src/attr-schema-validate.ts +9 -13
  184. package/src/constants.ts +1 -0
  185. package/src/core/attr/meta-attr-filter.ts +8 -1
  186. package/src/core/attr/meta-attr.ts +24 -1
  187. package/src/core/field/shared-enum.ts +53 -0
  188. package/src/core/identity/meta-identity.ts +9 -12
  189. package/src/core/index.ts +5 -0
  190. package/src/core/object/object-constants.ts +19 -0
  191. package/src/core/object/object-definition.embedded.ts +80 -0
  192. package/src/core/relationship/derive-m2m-fields.ts +15 -48
  193. package/src/core/relationship/find-reference.ts +4 -2
  194. package/src/core/relationship/resolve-relationship-reference.ts +11 -9
  195. package/src/core/reporting/meta-dimension.ts +41 -0
  196. package/src/core/reporting/meta-measure.ts +75 -0
  197. package/src/core/reporting/meta-segment.ts +14 -0
  198. package/src/core/reporting/report-accessors.ts +73 -0
  199. package/src/core/reporting/report-describe.ts +206 -0
  200. package/src/core/reporting/report-read-model.ts +177 -0
  201. package/src/core/reporting/report-shape.ts +493 -0
  202. package/src/core/reporting/reporting-constants.ts +104 -0
  203. package/src/core/reporting/reporting-definition.embedded.ts +192 -0
  204. package/src/core/requirement/resolve-claim.ts +20 -0
  205. package/src/core/yaml-desugar.ts +9 -89
  206. package/src/core-types.ts +41 -0
  207. package/src/docs-ref.ts +41 -0
  208. package/src/errors.ts +17 -6
  209. package/src/fmt.ts +3 -1
  210. package/src/index.ts +72 -4
  211. package/src/loader/declared-duplicate-fields.ts +114 -0
  212. package/src/loader/meta-data-loader.ts +25 -1
  213. package/src/loader/reporting-validation.ts +1137 -0
  214. package/src/loader/resolve-references.ts +144 -0
  215. package/src/loader/validation-passes.ts +13 -9
  216. package/src/loader/validation-registry.ts +37 -9
  217. package/src/metamodel-docs/index.ts +3 -3
  218. package/src/metamodel-docs/render.ts +4 -4
  219. package/src/naming-refs.ts +237 -94
  220. package/src/naming.ts +75 -11
  221. package/src/object-serializer.ts +7 -9
  222. package/src/parser-core.ts +19 -56
  223. package/src/persistence/db/db-definition.embedded.ts +2 -2
  224. package/src/persistence/source/meta-source.ts +8 -6
  225. package/src/registry-manifest-exclusions.ts +2 -2
  226. package/src/registry-manifest.ts +1 -1
  227. package/src/release-docs.ts +48 -0
  228. package/src/serializer-json.ts +79 -12
  229. package/src/shared/base-types.ts +9 -0
  230. package/src/shared/meta-data.ts +22 -1
  231. package/src/shared/meta-root.ts +20 -1
  232. package/src/super-resolve.ts +49 -63
  233. package/src/vocabulary-catalog.ts +2 -2
@@ -0,0 +1,192 @@
1
+ // AUTO-GENERATED by scripts/generate-embedded-metamodel.ts — DO NOT EDIT.
2
+ // Canonical source: repo-root spec/metamodel/reporting.json
3
+ // Regenerate: bun run scripts/generate-embedded-metamodel.ts
4
+ //
5
+ // Embeds the canonical FR-033 ProviderDefinition so the provider can register
6
+ // itself wherever the on-disk spec/ tree is unavailable (bundled builds).
7
+ import type { ProviderDefinition } from "../../provider-data.js";
8
+
9
+ export const REPORTING_DEFINITION: ProviderDefinition = {
10
+ "provider": "metaobjects-core-types",
11
+ "types": [
12
+ {
13
+ "type": "dimension",
14
+ "subType": "attribute",
15
+ "description": "A named group-by attribute of the entity that declares it (FR-044). Groups report rows by a column value as-is. @of names Entity.field: the owning entity, or the @via terminal. @via may follow only to-one hops, so grouping by a related row's column can never multiply the measured rows.",
16
+ "whenToUse": "A column a dashboard groups by: product, status, region. Declare it once on the fact entity and reference it by name from reports.",
17
+ "children": [
18
+ {
19
+ "type": "attr",
20
+ "subType": "string",
21
+ "name": "of",
22
+ "min": 1,
23
+ "max": 1,
24
+ "description": "Dotted Entity.field reference naming the grouped column (e.g. 'Purchase.programId', or 'Program.title' with @via)."
25
+ },
26
+ {
27
+ "type": "attr",
28
+ "subType": "string",
29
+ "name": "via",
30
+ "min": 0,
31
+ "max": 1,
32
+ "description": "Optional dotted to-one relationship path from the owning entity to the entity @of names (e.g. 'Purchase.program'). Every hop must be @cardinality: one or an identity.reference."
33
+ }
34
+ ]
35
+ },
36
+ {
37
+ "type": "dimension",
38
+ "subType": "time",
39
+ "description": "A named time dimension (FR-044): groups report rows by a date or timestamp column truncated to a grain. @of names a field.date or field.timestamp. Weeks start on Monday (ISO-8601) in every lowering. A report names it as 'dimension:grain' and the derived report field is <dimension><Grain> (e.g. purchasedAtDay).",
40
+ "whenToUse": "Per-day, per-week or per-month series on a dashboard.",
41
+ "children": [
42
+ {
43
+ "type": "attr",
44
+ "subType": "string",
45
+ "name": "of",
46
+ "min": 1,
47
+ "max": 1,
48
+ "description": "Dotted Entity.field reference naming the date or timestamp column."
49
+ },
50
+ {
51
+ "type": "attr",
52
+ "subType": "string",
53
+ "name": "via",
54
+ "min": 0,
55
+ "max": 1,
56
+ "description": "Optional dotted to-one relationship path, as on dimension.attribute."
57
+ },
58
+ {
59
+ "type": "attr",
60
+ "subType": "string",
61
+ "name": "grains",
62
+ "isArray": true,
63
+ "min": 1,
64
+ "max": 1,
65
+ "allowedValues": [
66
+ "hour",
67
+ "day",
68
+ "week",
69
+ "month",
70
+ "quarter",
71
+ "year"
72
+ ],
73
+ "description": "The grains this dimension supports. Weeks start Monday (ISO-8601). 'hour' is refused on a field.date."
74
+ }
75
+ ]
76
+ },
77
+ {
78
+ "type": "measure",
79
+ "subType": "aggregate",
80
+ "description": "A named aggregate over the declaring entity's own rows (FR-044). @agg count without @distinct counts rows; with @distinct it counts distinct values of @of (a list in @of is a distinct count of the tuple). Unlike origin.aggregate, count is NOT distinct by default: a measure aggregates its own rows and dimensions reach only to-one paths, so no join inflates it.",
81
+ "whenToUse": "A number a dashboard shows: revenue, purchases, distinct buyers, last activity.",
82
+ "children": [
83
+ {
84
+ "type": "attr",
85
+ "subType": "string",
86
+ "name": "agg",
87
+ "min": 1,
88
+ "max": 1,
89
+ "allowedValues": [
90
+ "count",
91
+ "sum",
92
+ "avg",
93
+ "min",
94
+ "max",
95
+ "any",
96
+ "all"
97
+ ],
98
+ "description": "The aggregate function. sum/avg need a numeric field; min/max refuse boolean, object and map fields; any/all (boolean OR / AND, Postgres bool_or / bool_and) type the measure boolean and take either a field.boolean in @of or no @of, when they ask whether some row (any) or every row (all) passes the measure's @filter / @segment."
99
+ },
100
+ {
101
+ "type": "attr",
102
+ "subType": "string",
103
+ "name": "of",
104
+ "isArray": true,
105
+ "min": 0,
106
+ "max": 1,
107
+ "description": "Dotted Entity.field reference(s) on the declaring entity. A bare string is one column; more than one requires @agg: count and @distinct: true. Required for every @agg except any/all, which may omit it to quantify their @filter / @segment over the rows."
108
+ },
109
+ {
110
+ "type": "attr",
111
+ "subType": "boolean",
112
+ "name": "distinct",
113
+ "min": 0,
114
+ "max": 1,
115
+ "description": "Count distinct values. Legal only with @agg: count."
116
+ },
117
+ {
118
+ "type": "attr",
119
+ "subType": "filter",
120
+ "name": "filter",
121
+ "min": 0,
122
+ "max": 1,
123
+ "description": "Optional row scope (a portable attr.filter over the declaring entity's fields). May use relative-date values ({ now: \"-P7D\" }). Combines with @segment by AND."
124
+ },
125
+ {
126
+ "type": "attr",
127
+ "subType": "string",
128
+ "name": "segment",
129
+ "min": 0,
130
+ "max": 1,
131
+ "description": "Optional name of a segment declared on the same entity. Combines with @filter by AND."
132
+ },
133
+ {
134
+ "type": "attr",
135
+ "subType": "int",
136
+ "name": "default",
137
+ "min": 0,
138
+ "max": 1,
139
+ "description": "Optional integer the measure reads when it would otherwise be null: nothing matched, every matched value is null, or (a ratio) the denominator is zero or null. The derived report field is then never null. Refused on @agg: count (a count is never null), on min/max over a field that is not numeric, and on @agg any/all unless it is 0 (false) or 1 (true). A ratio's operand carries its own @default into the ratio."
140
+ }
141
+ ]
142
+ },
143
+ {
144
+ "type": "measure",
145
+ "subType": "ratio",
146
+ "description": "A named quotient of two numeric measure.aggregate siblings (FR-044), lowered as numerator / NULLIF(denominator, 0) and typed decimal. A zero denominator yields null.",
147
+ "whenToUse": "Averages per unit that are not a plain avg: average days engaged per starter.",
148
+ "children": [
149
+ {
150
+ "type": "attr",
151
+ "subType": "string",
152
+ "name": "numerator",
153
+ "min": 1,
154
+ "max": 1,
155
+ "description": "Name of a measure.aggregate on the same entity whose result is numeric: a count, a sum, an avg, or a min or max of a numeric field."
156
+ },
157
+ {
158
+ "type": "attr",
159
+ "subType": "string",
160
+ "name": "denominator",
161
+ "min": 1,
162
+ "max": 1,
163
+ "description": "Name of a measure.aggregate on the same entity whose result is numeric: a count, a sum, an avg, or a min or max of a numeric field."
164
+ },
165
+ {
166
+ "type": "attr",
167
+ "subType": "int",
168
+ "name": "default",
169
+ "min": 0,
170
+ "max": 1,
171
+ "description": "Optional integer the measure reads when it would otherwise be null: nothing matched, every matched value is null, or (a ratio) the denominator is zero or null. The derived report field is then never null. Refused on @agg: count (a count is never null) and on min/max over a field that is not numeric. A ratio's operand carries its own @default into the ratio."
172
+ }
173
+ ]
174
+ },
175
+ {
176
+ "type": "segment",
177
+ "subType": "filter",
178
+ "description": "A named, reusable row filter on the declaring entity (FR-044). Measures and reports reference it by name; exporters emit it as a named segment.",
179
+ "whenToUse": "The same filter (e.g. 'active purchase') would otherwise be repeated in several measures or reports.",
180
+ "children": [
181
+ {
182
+ "type": "attr",
183
+ "subType": "filter",
184
+ "name": "filter",
185
+ "min": 1,
186
+ "max": 1,
187
+ "description": "The row scope: a portable attr.filter over the declaring entity's fields. May use relative-date values."
188
+ }
189
+ ]
190
+ }
191
+ ]
192
+ };
@@ -96,3 +96,23 @@ export function resolveClaim(
96
96
  if (owner === undefined || segs.length === 1) return owner;
97
97
  return resolveMember(owner, segs.slice(1));
98
98
  }
99
+
100
+ /**
101
+ * The package a requirement node resolves in (ADR-0059 D3/D10): its own declared
102
+ * `package`, else the nearest enclosing node that declares one, else the file default
103
+ * package of the top-level node it sits under, else "". One definition for the gate, the summary and
104
+ * codegen's requirement-test fan-out, so nesting and overlay contribution cannot
105
+ * make two call sites disagree.
106
+ */
107
+ export function effectiveRequirementPackage(node: MetaData): string {
108
+ let cur: MetaData = node;
109
+ for (;;) {
110
+ if (cur.package !== undefined && cur.package !== "") return cur.package;
111
+ const parent: MetaData | undefined = cur.parent;
112
+ // The tree root is not an "enclosing node": stop at the top-level node, whose file
113
+ // default package is the answer (a child contributed by another document inherits
114
+ // the merge target's, matching the overlay-declared package case).
115
+ if (parent === undefined || parent.parent === undefined) return cur.fileDefaultPackage ?? "";
116
+ cur = parent;
117
+ }
118
+ }
@@ -35,13 +35,9 @@ import {
35
35
  RESERVED_KEYS,
36
36
  RESERVED_KEY_CHILDREN,
37
37
  RESERVED_KEY_NAME,
38
- RESERVED_KEY_PACKAGE,
39
- RESERVED_KEY_EXTENDS,
40
38
  RESERVED_KEY_IS_ARRAY,
41
39
  TYPE_SUBTYPE_SEPARATOR,
42
- PACKAGE_SEPARATOR,
43
40
  } from "../shared/structural.js";
44
- import { expandRef, REF_BEARING_ATTR_NAMES } from "../naming-refs.js";
45
41
  import {
46
42
  getPositionMap,
47
43
  setPositionMap,
@@ -76,34 +72,13 @@ export interface DesugarResult {
76
72
  /** Desugar a parsed-YAML authoring document into a canonical-shaped object. */
77
73
  export function desugar(input: unknown, registry: TypeRegistry): DesugarResult {
78
74
  const errors: CollectedError[] = [];
79
- // FR-032 (ADR-0032): the desugar threads the effective package context down
80
- // the tree so every ref-bearing attr (extends + @objectRef/@references/@from/
81
- // @of/@via/@parameterRef/@payloadRef/@responseRef) is expanded to its FQN via
82
- // expandRef. The root context is empty (the metadata.root's own `package`
83
- // body key seeds the first real context inside desugarNode).
84
- const node = desugarNode(input, registry, errors, "<root>", "");
75
+ // ADR-0059 R1: the desugar is syntax only. Reference VALUES (extends, @objectRef,
76
+ // @of, ...) pass through exactly as written; the loader's one resolver gives every
77
+ // form its meaning once the whole tree exists.
78
+ const node = desugarNode(input, registry, errors, "<root>");
85
79
  return { canonical: node ?? {}, errors };
86
80
  }
87
81
 
88
- // FR-032: compute a node's effective package from its raw `package` body key
89
- // (inheriting the parent context when absent). Mirrors parser-core's
90
- // expandPackageForPath so the desugar's ref-expansion context matches the JSON
91
- // loader's package resolution. The `package` attr itself is NEVER ref-expanded
92
- // (ADR-0032 §2.1 — it is the node's identity, taken literally/absolute).
93
- function effectivePackageFor(rawBody: unknown, parentPkg: string): string {
94
- if (typeof rawBody !== "object" || rawBody === null || Array.isArray(rawBody)) {
95
- return parentPkg;
96
- }
97
- const rawPkg = (rawBody as Record<string, unknown>)[RESERVED_KEY_PACKAGE];
98
- if (typeof rawPkg !== "string") return parentPkg;
99
- // Legacy expandPackageForPath: a leading "::" on a child package prepends the
100
- // parent; otherwise it is used as-is.
101
- if (parentPkg !== "" && rawPkg.startsWith(PACKAGE_SEPARATOR)) {
102
- return parentPkg + rawPkg;
103
- }
104
- return rawPkg;
105
- }
106
-
107
82
  // Desugar one node — a single-key mapping { "type.subType": body }.
108
83
  // Returns the canonical node object, or undefined if `input` is not a usable
109
84
  // node (the caller substitutes a placeholder).
@@ -112,7 +87,6 @@ function desugarNode(
112
87
  registry: TypeRegistry,
113
88
  errors: CollectedError[],
114
89
  path: string,
115
- parentPkg: string,
116
90
  ): Record<string, unknown> | undefined {
117
91
  if (typeof input !== "object" || input === null || Array.isArray(input)) {
118
92
  errors.push({ message: `Node at ${path} must be a mapping with one type key` });
@@ -149,16 +123,11 @@ function desugarNode(
149
123
  // Rule 1: a bare `type` key → the type's registry default subType.
150
124
  const canonicalKey = resolveKey(key, registry, errors, path);
151
125
 
152
- // FR-032: this node's effective package context (its own `package` body key,
153
- // else inherited). Used to expand its ref-bearing attrs AND threaded to its
154
- // children so their bare/relative refs resolve against the right package.
155
- const nodePkg = effectivePackageFor(rawBody, parentPkg);
156
-
157
126
  // Rule 2: a scalar body → { name: <scalar> }.
158
127
  // FR5b — propagate the wrapper-key's position into the synthesized body
159
128
  // when the input body was a scalar (no body-side positions to inherit).
160
129
  const wrapperKeyPos = wrapperPositions?.[rawKey];
161
- const body = desugarBody(rawBody, registry, canonicalKey, errors, path, wrapperKeyPos, nodePkg);
130
+ const body = desugarBody(rawBody, registry, canonicalKey, errors, path, wrapperKeyPos);
162
131
 
163
132
  // Rule 4 (cont.): stamp isArray onto the canonical body.
164
133
  if (isArray) body[RESERVED_KEY_IS_ARRAY] = true;
@@ -169,7 +138,7 @@ function desugarNode(
169
138
  const children: unknown[] = [];
170
139
  for (let i = 0; i < rawChildren.length; i++) {
171
140
  const childPath = `${path}.${RESERVED_KEY_CHILDREN}[${i}]`;
172
- const child = desugarNode(rawChildren[i], registry, errors, childPath, nodePkg);
141
+ const child = desugarNode(rawChildren[i], registry, errors, childPath);
173
142
  // On a bad child keep an empty-object placeholder so sibling indices
174
143
  // stay stable; the error is already collected.
175
144
  children.push(child ?? {});
@@ -230,10 +199,6 @@ function desugarBody(
230
199
  * empty bodies; for mapping bodies we use the body's own position-by-key
231
200
  * map. */
232
201
  wrapperKeyPos: { line: number; col: number } | undefined,
233
- /** FR-032: this node's effective package context, used to expand its
234
- * ref-bearing attrs (extends + @objectRef/@references/@from/@of/@via/
235
- * @parameterRef/@payloadRef/@responseRef) to FQN via expandRef. */
236
- nodePkg: string,
237
202
  ): Record<string, unknown> {
238
203
  if (
239
204
  typeof rawBody === "string" ||
@@ -280,26 +245,16 @@ function desugarBody(
280
245
  let outKey: string;
281
246
  if (RESERVED_KEYS.has(key) || key.startsWith(ATTR_PREFIX)) {
282
247
  outKey = key;
283
- // FR-032: expand a ref-bearing value to FQN. `extends` (reserved) and the
284
- // @-prefixed ref attrs are expanded; everything else is copied verbatim.
248
+ // ADR-0059 R1: every value, references included, is copied as written.
285
249
  const attrName = key.startsWith(ATTR_PREFIX) ? key.slice(ATTR_PREFIX.length) : "";
286
- if (key === RESERVED_KEY_EXTENDS || (attrName !== "" && REF_BEARING_ATTR_NAMES.has(attrName))) {
287
- out[key] = expandRefValue(src[key], nodePkg, errors, path, key);
288
- } else {
289
- out[key] = src[key];
290
- }
250
+ out[key] = src[key];
291
251
  // D2 also applies to author-written @-keys (the awkward form).
292
252
  if (attrName !== "" && !RESERVED_KEYS.has(attrName)) {
293
253
  checkCoercion(attrName, src[key], schemaIndex, errors, path);
294
254
  }
295
255
  } else {
296
256
  outKey = `${ATTR_PREFIX}${key}`;
297
- // FR-032: a bare (sigil-free) ref-bearing attr is expanded to FQN too.
298
- if (REF_BEARING_ATTR_NAMES.has(key)) {
299
- out[outKey] = expandRefValue(src[key], nodePkg, errors, path, outKey);
300
- } else {
301
- out[outKey] = src[key];
302
- }
257
+ out[outKey] = src[key];
303
258
  checkCoercion(key, src[key], schemaIndex, errors, path);
304
259
  }
305
260
  const pos = srcPositions?.[key];
@@ -312,41 +267,6 @@ function desugarBody(
312
267
  return out;
313
268
  }
314
269
 
315
- // ---------------------------------------------------------------------------
316
- // FR-032 (ADR-0032) — expand a ref-bearing value to FQN.
317
- //
318
- // A ref value is a single string (most refs) or a string-array (@references can
319
- // carry multiple). expandRef preserves any FR-024 dotted child suffix and the
320
- // `package` attr is never touched here (it is not a ref). A parent-relative
321
- // over-drop (more `..::` than the package has segments) throws inside expandRef;
322
- // we collect it as ERR_BAD_ATTR_VALUE and pass the raw value through so the rest
323
- // of the desugar/load proceeds and surfaces a single actionable error.
324
- // ---------------------------------------------------------------------------
325
-
326
- function expandRefValue(
327
- raw: unknown,
328
- nodePkg: string,
329
- errors: CollectedError[],
330
- path: string,
331
- refLabel: string,
332
- ): unknown {
333
- if (typeof raw === "string") {
334
- try {
335
- return expandRef(raw, nodePkg);
336
- } catch (err) {
337
- errors.push({
338
- message: `Cannot expand reference '${refLabel}' at ${path}: ${(err as Error).message}`,
339
- code: "ERR_BAD_ATTR_VALUE",
340
- });
341
- return raw;
342
- }
343
- }
344
- if (Array.isArray(raw)) {
345
- return raw.map((el) => (typeof el === "string" ? expandRefValue(el, nodePkg, errors, path, refLabel) : el));
346
- }
347
- return raw;
348
- }
349
-
350
270
  // ---------------------------------------------------------------------------
351
271
  // D2 — YAML type-coercion guard
352
272
  // ---------------------------------------------------------------------------
package/src/core-types.ts CHANGED
@@ -60,6 +60,15 @@ import { INDEX_SUBTYPES } from "./core/index/index-constants.js";
60
60
  import { MetaRequirement } from "./core/requirement/meta-requirement.js";
61
61
  import { REQUIREMENT_DEFINITION } from "./core/requirement/requirement-definition.embedded.js";
62
62
  import { REQUIREMENT_SUBTYPES } from "./core/requirement/requirement-constants.js";
63
+ import { MetaDimension } from "./core/reporting/meta-dimension.js";
64
+ import { MetaMeasure } from "./core/reporting/meta-measure.js";
65
+ import { MetaSegment } from "./core/reporting/meta-segment.js";
66
+ import { REPORTING_DEFINITION } from "./core/reporting/reporting-definition.embedded.js";
67
+ import {
68
+ DIMENSION_SUBTYPES,
69
+ MEASURE_SUBTYPES,
70
+ SEGMENT_SUBTYPES,
71
+ } from "./core/reporting/reporting-constants.js";
63
72
  import {
64
73
  TYPE_METADATA,
65
74
  TYPE_OBJECT,
@@ -75,6 +84,9 @@ import {
75
84
  TYPE_TEMPLATE,
76
85
  TYPE_INDEX,
77
86
  TYPE_REQUIREMENT,
87
+ TYPE_DIMENSION,
88
+ TYPE_MEASURE,
89
+ TYPE_SEGMENT,
78
90
  SUBTYPE_ROOT,
79
91
  } from "./shared/base-types.js";
80
92
  import { CHILD_RULE_WILDCARD } from "./shared/structural.js";
@@ -510,6 +522,35 @@ function registerCoreTypeDefs(registry: TypeRegistry): void {
510
522
  registry.register(reqDef);
511
523
  }
512
524
 
525
+ // FR-044 reporting vocabulary — dimension / measure / segment. Declared as
526
+ // children of `object.entity` (spec/metamodel/object.json), never root-level, so
527
+ // no root wildcard is added above. Three types in one provider file because they
528
+ // are one vocabulary: a report names dimensions and measures, and both may
529
+ // reference a segment. `measure.derived` is NOT registered (waits for FR-037 R5).
530
+ const REPORTING_FACTORIES: FactoryMap = {
531
+ ...Object.fromEntries(
532
+ DIMENSION_SUBTYPES.map((subType) => [
533
+ `${TYPE_DIMENSION}.${subType}`,
534
+ (typeId: TypeId, name: string) => new MetaDimension(typeId, name),
535
+ ]),
536
+ ),
537
+ ...Object.fromEntries(
538
+ MEASURE_SUBTYPES.map((subType) => [
539
+ `${TYPE_MEASURE}.${subType}`,
540
+ (typeId: TypeId, name: string) => new MetaMeasure(typeId, name),
541
+ ]),
542
+ ),
543
+ ...Object.fromEntries(
544
+ SEGMENT_SUBTYPES.map((subType) => [
545
+ `${TYPE_SEGMENT}.${subType}`,
546
+ (typeId: TypeId, name: string) => new MetaSegment(typeId, name),
547
+ ]),
548
+ ),
549
+ };
550
+ for (const reportingDef of defineProviderFromData(REPORTING_DEFINITION, REPORTING_FACTORIES)) {
551
+ registry.register(reportingDef);
552
+ }
553
+
513
554
  // Declare the core cross-references ON their TypeDefinitions, so the loader's
514
555
  // registry-derived validation resolves them generically (a dangling target fails the
515
556
  // load). Set on the concrete subtypes the parser produces. (Production moves these into
@@ -0,0 +1,41 @@
1
+ // docs-ref.ts — where a guide URL points, derived from the running version.
2
+ //
3
+ // A guide URL that says `blob/main` moves after the release is cut, and no installed
4
+ // package ships the guides, so the CLI and the agent context name the TAG of the release
5
+ // they belong to: `blob/v1.1.0/...`. A prerelease version has no tag, so it keeps `main`.
6
+ // The repository URL and the rule live here once; nothing else spells either. This file is
7
+ // pure (browser-safe, reachable from the root entry); reading the running version is the
8
+ // Node-side `release-docs.ts`.
9
+
10
+ /** The public repository the guides live in. */
11
+ export const DOCS_REPO_URL = "https://github.com/metaobjectsdev/metaobjects";
12
+
13
+ /** The branch a prerelease or an unresolvable version links to. */
14
+ export const DOCS_DEFAULT_REF = "main";
15
+
16
+ const RELEASE_VERSION = /^\d+\.\d+\.\d+$/;
17
+
18
+ /**
19
+ * The git ref a guide URL pins to: `v<version>` for a release (`1.1.0` → `v1.1.0`),
20
+ * `main` for anything with no tag — a prerelease (`1.1.0-rc.7`), the `0.0.0` sentinel a
21
+ * port stamps when it cannot resolve its own version, or text that is not a version.
22
+ */
23
+ export function docsRefForVersion(version: string): string {
24
+ const v = version.trim();
25
+ return RELEASE_VERSION.test(v) && v !== "0.0.0" ? `v${v}` : DOCS_DEFAULT_REF;
26
+ }
27
+
28
+ /** `https://github.com/<repo>/blob/<ref>/<repoRelativePath>`. */
29
+ export function docsBlobUrl(repoRelativePath: string, ref: string = DOCS_DEFAULT_REF): string {
30
+ return `${DOCS_REPO_URL}/blob/${ref}/${repoRelativePath.replace(/^\/+/, "")}`;
31
+ }
32
+
33
+ /**
34
+ * Rewrite every `…/blob/main/` link into this repository, inside `text`, to `ref`.
35
+ * Authors of shipped prose write `main` as the placeholder; the pin is applied once, at
36
+ * render time, so no template carries a version.
37
+ */
38
+ export function pinDocsRefs(text: string, ref: string): string {
39
+ if (ref === DOCS_DEFAULT_REF) return text;
40
+ return text.split(`${DOCS_REPO_URL}/blob/${DOCS_DEFAULT_REF}/`).join(`${DOCS_REPO_URL}/blob/${ref}/`);
41
+ }
package/src/errors.ts CHANGED
@@ -201,12 +201,6 @@ export const ERROR_CODES = [
201
201
  // ADR-0023 — a registration was attempted against a registry sealed after its
202
202
  // agreed metamodel-provider bootstrap. Codegen cannot invent metamodel attrs.
203
203
  "ERR_REGISTRY_SEALED",
204
- // FR-032 (ADR-0032) — a ref-bearing attr (extends/@objectRef/@references/
205
- // origin @from/@of/@via/@parameterRef/@payloadRef/@responseRef) in CANONICAL
206
- // JSON used a relative authoring form (leading `::` or `..::`). Canonical JSON
207
- // is the self-contained interchange form: every ref MUST be fully-qualified.
208
- // Relative navigation is YAML-only (the desugar expands it via expandRef).
209
- "ERR_RELATIVE_REF_IN_CANONICAL",
210
204
  // FR-033 — a provider set's merged metamodel constraint graph is contradictory.
211
205
  // Surfaced by validateConstraints (constraint-validate.ts) at registry compose:
212
206
  // dangling ref / unsatisfiable required child / bad cardinality / closed-set
@@ -218,6 +212,23 @@ export const ERROR_CODES = [
218
212
  // @fields), whichever is declared supplies no key, or a named field does not exist
219
213
  // on the owning entity's effective (resolved via extends) field set.
220
214
  "ERR_INVALID_INDEX",
215
+ // FR-044 — reporting vocabulary (validateReporting, loader/reporting-validation.ts).
216
+ // Rule ids D1-D4 / M1-M6 / R1-R7 are the cross-port rule table; S1/F1/F2 reuse
217
+ // ERR_BAD_ATTR_FILTER.
218
+ // A dimension's @of/@via does not resolve, @via crosses a to-many hop, or a
219
+ // time dimension's column or grains do not fit its type (D1-D4).
220
+ "ERR_INVALID_DIMENSION",
221
+ // A measure's @of is not a field of its own entity, a tuple/@distinct/@agg
222
+ // combination is illegal, @segment does not resolve, or a ratio operand is not a
223
+ // measure.aggregate of the same entity (M1-M6).
224
+ "ERR_INVALID_MEASURE",
225
+ // An object.report's @from is not an entity, a @dimensions/@measures/@segment
226
+ // item does not resolve, it declares a field/identity or a writable source, or
227
+ // two items derive the same report field name (R1-R7).
228
+ "ERR_INVALID_REPORT",
229
+ // An object.report lists a measure that belongs to an entity other than @from;
230
+ // v1 refuses multi-fact reports (R3).
231
+ "ERR_REPORT_FOREIGN_MEASURE",
221
232
  // FR-039 — a requirement.* with @status: retired declares @implementedBy. Refused
222
233
  // rather than exempted: a retired capability has no implementation BY DEFINITION,
223
234
  // so forbidding the attribute makes the dangling-reference class unreachable
package/src/fmt.ts CHANGED
@@ -149,7 +149,9 @@ export function formatMetadataFile(content: string, opts: FormatFileOptions): Fo
149
149
  };
150
150
  }
151
151
 
152
- return { ok: true, text: canonicalSerialize(result.root) };
152
+ // ADR-0059 (C2): formatting never rewrites a reference — refs and packages are
153
+ // written as authored; only layout, key order and sugar are normalized.
154
+ return { ok: true, text: canonicalSerialize(result.root, { refs: "authored" }) };
153
155
  } catch (err) {
154
156
  return {
155
157
  ok: false,
package/src/index.ts CHANGED
@@ -42,9 +42,52 @@ export * from "./core/identity/identity-constants.js";
42
42
  export * from "./core/index/index-constants.js";
43
43
  export * from "./core/requirement/requirement-constants.js";
44
44
  export { MetaRequirement } from "./core/requirement/meta-requirement.js";
45
+ export * from "./core/reporting/reporting-constants.js";
46
+ export { MetaDimension } from "./core/reporting/meta-dimension.js";
47
+ export { MetaMeasure } from "./core/reporting/meta-measure.js";
48
+ export { MetaSegment } from "./core/reporting/meta-segment.js";
49
+ export {
50
+ reportFrom,
51
+ reportSpine,
52
+ reportDimensionItems,
53
+ reportMeasureNames,
54
+ reportMeasureItemName,
55
+ reportMeasureItemOwner,
56
+ reportDerivedFieldName,
57
+ type ReportDimensionItem,
58
+ } from "./core/reporting/report-accessors.js";
59
+ export {
60
+ measureDerivedSubType,
61
+ reportShape,
62
+ reportSpineEntity,
63
+ reportSpineHops,
64
+ reportingMemberOwner,
65
+ reportingViaHops,
66
+ resolveReportingFieldRef,
67
+ resolveDimensionOf,
68
+ type ReportField,
69
+ type ReportFieldRole,
70
+ type ReportShape,
71
+ } from "./core/reporting/report-shape.js";
72
+ export { reportReadModel, reportReadSource } from "./core/reporting/report-read-model.js";
73
+ export {
74
+ describeDimension,
75
+ describeDimensionColumn,
76
+ describeFilter,
77
+ describeMeasure,
78
+ describeReportField,
79
+ describeReportRowScope,
80
+ describeReportRows,
81
+ describeRowScope,
82
+ describeSegment,
83
+ reportFieldTypeName,
84
+ reportNotServedReason,
85
+ reportingDescribedAttrs,
86
+ } from "./core/reporting/report-describe.js";
45
87
  // Shared `@implementedBy` resolution — one resolver for the CLI's requirement
46
88
  // checks and codegen's requirement-test fan-out (FR-038).
47
89
  export {
90
+ effectiveRequirementPackage,
48
91
  resolveClaim,
49
92
  resolveClaimTarget,
50
93
  resolveMember,
@@ -81,6 +124,9 @@ export {
81
124
  // Core node classes
82
125
  export { MetaObject } from "./core/object/meta-object.js";
83
126
  export { MetaField } from "./core/field/meta-field.js";
127
+ // The one authority for "which type does this enum field have" — the loader's #246
128
+ // check and every codegen site share it (ADR-0026 Amendment 1).
129
+ export { isSharedEnumDeclaration, resolveSharedEnumDeclaration } from "./core/field/shared-enum.js";
84
130
  export { MetaAttr } from "./core/attr/meta-attr.js";
85
131
 
86
132
  // Runtime object model — backing objects + FQN→factory binding (Phase A).
@@ -193,7 +239,7 @@ export { ExclusionReason } from "./registry-manifest-exclusions.js";
193
239
 
194
240
  // FR-033 S3 — metamodel doc-gen: tiered, LLM-readable docs FOR THE METAMODEL
195
241
  // (the type/subtype/attr vocabulary), generated from the strict registry.
196
- // Distinct from `meta docs --model` (which documents a user's entities).
242
+ // Distinct from the `docs` generator (which documents a user's entities).
197
243
  export {
198
244
  renderMetamodelDocs,
199
245
  buildMetamodelProvenance,
@@ -251,7 +297,22 @@ export type { FormatFileOptions, FormatFileResult } from "./fmt.js";
251
297
  export { resolveSuperRef } from "./super-resolve.js";
252
298
 
253
299
  // FR-032 (ADR-0032) — canonical reference expansion + FQN object matching.
254
- export { expandRef, isRelativeRef, refMatchesObject, resolveObjectRef, didYouMeanHint, REF_BEARING_ATTR_NAMES } from "./naming-refs.js";
300
+ export {
301
+ expandRef,
302
+ isRelativeRef,
303
+ refMatchesObject,
304
+ resolveObjectRef,
305
+ resolveRef,
306
+ lookupCanonical,
307
+ refTarget,
308
+ spellRef,
309
+ splitChildTail,
310
+ RefOverDropError,
311
+ didYouMeanHint,
312
+ didYouMeanSuperHint,
313
+ REF_BEARING_ATTR_NAMES,
314
+ } from "./naming-refs.js";
315
+ export { resolveReferences } from "./loader/resolve-references.js";
255
316
 
256
317
  // Loader hierarchy
257
318
  export { MetaDataLoader, declaredTopLevelKeys } from "./loader/meta-data-loader.js";
@@ -299,17 +360,24 @@ export type { Scope, CompiledScope } from "./scope.js";
299
360
  export { validateAttrSchema } from "./attr-schema-validate.js";
300
361
  export type { AttrSchemaValidationResult } from "./attr-schema-validate.js";
301
362
 
363
+ // Guide URLs pinned to the running release's tag (prerelease → main).
364
+ export {
365
+ DOCS_REPO_URL, DOCS_DEFAULT_REF, docsRefForVersion, docsBlobUrl, pinDocsRefs,
366
+ } from "./docs-ref.js";
367
+
302
368
  // Naming — hoisted from runtime-ts in v0.2.3 so multiple consumers (runtime-ts, migrate-ts, codegen-ts)
303
369
  // share identical name resolution. See spec §4.1.
304
370
  export {
305
371
  toSnakeCase, toKebabCase, pluralize, pluralizeTableNameLegacy,
306
- applyColumnNamingStrategy, DEFAULT_COLUMN_NAMING_STRATEGY,
372
+ applyColumnNamingStrategy, DEFAULT_COLUMN_NAMING_STRATEGY, COLUMN_NAMING_STRATEGIES,
373
+ TABLE_NAMING_RULES, DEFAULT_PHYSICAL_NAMING, physicalNamingOf, applyTableNamingRule,
374
+ PHYSICAL_NAMING_MIGRATION_GUIDE, PHYSICAL_NAMING_MIGRATION_GUIDE_PATH, physicalNamingRemovedMessage,
307
375
  resolveTableName, resolveColumnName, resolveTableSchema, resolveIndexName,
308
376
  primaryRdbSource, sourceAddressKey,
309
377
  buildNameMap,
310
378
  stripPackage, packageOfResolutionKey,
311
379
  } from "./naming.js";
312
- export type { EntityNameMap, ColumnNamingStrategy } from "./naming.js";
380
+ export type { EntityNameMap, ColumnNamingStrategy, PhysicalNaming, TableNamingRule } from "./naming.js";
313
381
 
314
382
  // Retired vocabulary: the map the loader reads to explain a retirement, and the raw-document
315
383
  // rewriter `meta upgrade` drives from the SAME entries — so the error message and the fix