@metaobjectsdev/metadata 0.24.0-rc.1 → 0.24.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/attr-schema-validate.d.ts.map +1 -1
- package/dist/attr-schema-validate.js +17 -2
- package/dist/attr-schema-validate.js.map +1 -1
- package/dist/core/field/field-constants.d.ts +18 -5
- package/dist/core/field/field-constants.d.ts.map +1 -1
- package/dist/core/field/field-constants.js +21 -5
- package/dist/core/field/field-constants.js.map +1 -1
- package/dist/core/field/field-definition.embedded.d.ts.map +1 -1
- package/dist/core/field/field-definition.embedded.js +8 -3
- package/dist/core/field/field-definition.embedded.js.map +1 -1
- package/dist/core/field/validate-field-mutability.d.ts +22 -0
- package/dist/core/field/validate-field-mutability.d.ts.map +1 -0
- package/dist/core/field/validate-field-mutability.js +208 -0
- package/dist/core/field/validate-field-mutability.js.map +1 -0
- package/dist/core/identity/identity-constants.d.ts +12 -0
- package/dist/core/identity/identity-constants.d.ts.map +1 -1
- package/dist/core/identity/identity-constants.js +15 -0
- package/dist/core/identity/identity-constants.js.map +1 -1
- package/dist/core/object/object-definition.embedded.js +2 -2
- package/dist/core/object/object-definition.embedded.js.map +1 -1
- package/dist/core/requirement/meta-requirement.d.ts +1 -2
- package/dist/core/requirement/meta-requirement.d.ts.map +1 -1
- package/dist/core/requirement/meta-requirement.js +2 -6
- package/dist/core/requirement/meta-requirement.js.map +1 -1
- package/dist/core/requirement/requirement-constants.d.ts +3 -8
- package/dist/core/requirement/requirement-constants.d.ts.map +1 -1
- package/dist/core/requirement/requirement-constants.js +2 -9
- package/dist/core/requirement/requirement-constants.js.map +1 -1
- package/dist/core/requirement/requirement-definition.embedded.d.ts.map +1 -1
- package/dist/core/requirement/requirement-definition.embedded.js +8 -46
- package/dist/core/requirement/requirement-definition.embedded.js.map +1 -1
- package/dist/core/requirement/resolve-claim.d.ts +37 -0
- package/dist/core/requirement/resolve-claim.d.ts.map +1 -0
- package/dist/core/requirement/resolve-claim.js +83 -0
- package/dist/core/requirement/resolve-claim.js.map +1 -0
- package/dist/core-types.d.ts.map +1 -1
- package/dist/core-types.js +10 -10
- package/dist/core-types.js.map +1 -1
- package/dist/errors.d.ts +2 -2
- package/dist/errors.d.ts.map +1 -1
- package/dist/errors.js +16 -2
- package/dist/errors.js.map +1 -1
- package/dist/index.d.ts +7 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +13 -1
- package/dist/index.js.map +1 -1
- package/dist/library/library-sources.d.ts +11 -0
- package/dist/library/library-sources.d.ts.map +1 -1
- package/dist/library/library-sources.js +13 -0
- package/dist/library/library-sources.js.map +1 -1
- package/dist/loader/meta-data-loader.d.ts.map +1 -1
- package/dist/loader/meta-data-loader.js +10 -9
- package/dist/loader/meta-data-loader.js.map +1 -1
- package/dist/loader/validation-passes.js +2 -2
- package/dist/loader/validation-passes.js.map +1 -1
- package/dist/naming-refs.d.ts.map +1 -1
- package/dist/naming-refs.js +2 -3
- package/dist/naming-refs.js.map +1 -1
- package/dist/parser-core.d.ts.map +1 -1
- package/dist/parser-core.js +22 -5
- package/dist/parser-core.js.map +1 -1
- package/dist/persistence/origin/meta-origin.d.ts +0 -10
- package/dist/persistence/origin/meta-origin.d.ts.map +1 -1
- package/dist/persistence/origin/meta-origin.js +1 -15
- package/dist/persistence/origin/meta-origin.js.map +1 -1
- package/dist/persistence/origin/origin-constants.d.ts +2 -4
- package/dist/persistence/origin/origin-constants.d.ts.map +1 -1
- package/dist/persistence/origin/origin-constants.js +9 -7
- package/dist/persistence/origin/origin-constants.js.map +1 -1
- package/dist/persistence/origin/origin-definition.embedded.d.ts.map +1 -1
- package/dist/persistence/origin/origin-definition.embedded.js +0 -16
- package/dist/persistence/origin/origin-definition.embedded.js.map +1 -1
- package/dist/registry-manifest.d.ts +9 -4
- package/dist/registry-manifest.d.ts.map +1 -1
- package/dist/registry-manifest.js +9 -4
- package/dist/registry-manifest.js.map +1 -1
- package/dist/retired-vocabulary.d.ts +92 -0
- package/dist/retired-vocabulary.d.ts.map +1 -0
- package/dist/retired-vocabulary.js +204 -0
- package/dist/retired-vocabulary.js.map +1 -0
- package/dist/super-resolve.d.ts +33 -0
- package/dist/super-resolve.d.ts.map +1 -1
- package/dist/super-resolve.js +56 -1
- package/dist/super-resolve.js.map +1 -1
- package/dist/template/prompt-definition.embedded.js +1 -1
- package/dist/template/prompt-definition.embedded.js.map +1 -1
- package/dist/template/template-constants.d.ts +6 -0
- package/dist/template/template-constants.d.ts.map +1 -1
- package/dist/template/template-constants.js +24 -1
- package/dist/template/template-constants.js.map +1 -1
- package/dist/template/template-definition.embedded.d.ts.map +1 -1
- package/dist/template/template-definition.embedded.js +34 -21
- package/dist/template/template-definition.embedded.js.map +1 -1
- package/dist/vocabulary-rewrite.d.ts +33 -0
- package/dist/vocabulary-rewrite.d.ts.map +1 -0
- package/dist/vocabulary-rewrite.js +310 -0
- package/dist/vocabulary-rewrite.js.map +1 -0
- package/package.json +6 -1
- package/src/attr-schema-validate.ts +17 -2
- package/src/core/field/field-constants.ts +24 -5
- package/src/core/field/field-definition.embedded.ts +8 -3
- package/src/core/field/validate-field-mutability.ts +259 -0
- package/src/core/identity/identity-constants.ts +16 -0
- package/src/core/object/object-definition.embedded.ts +2 -2
- package/src/core/requirement/meta-requirement.ts +1 -7
- package/src/core/requirement/requirement-constants.ts +2 -9
- package/src/core/requirement/requirement-definition.embedded.ts +8 -46
- package/src/core/requirement/resolve-claim.ts +98 -0
- package/src/core-types.ts +9 -10
- package/src/errors.ts +16 -2
- package/src/index.ts +29 -1
- package/src/library/library-sources.ts +14 -0
- package/src/loader/meta-data-loader.ts +10 -9
- package/src/loader/validation-passes.ts +3 -3
- package/src/naming-refs.ts +1 -3
- package/src/parser-core.ts +27 -5
- package/src/persistence/origin/meta-origin.ts +0 -16
- package/src/persistence/origin/origin-constants.ts +9 -8
- package/src/persistence/origin/origin-definition.embedded.ts +0 -16
- package/src/registry-manifest.ts +9 -4
- package/src/retired-vocabulary.ts +280 -0
- package/src/super-resolve.ts +59 -1
- package/src/template/prompt-definition.embedded.ts +1 -1
- package/src/template/template-constants.ts +27 -1
- package/src/template/template-definition.embedded.ts +34 -21
- package/src/vocabulary-rewrite.ts +346 -0
- package/dist/core/field/validate-field-readonly.d.ts +0 -9
- package/dist/core/field/validate-field-readonly.d.ts.map +0 -1
- package/dist/core/field/validate-field-readonly.js +0 -128
- package/dist/core/field/validate-field-readonly.js.map +0 -1
- package/src/core/field/validate-field-readonly.ts +0 -154
package/src/errors.ts
CHANGED
|
@@ -138,8 +138,9 @@ export const ERROR_CODES = [
|
|
|
138
138
|
"ERR_PHYSICAL_NAME_KIND_MISMATCH",
|
|
139
139
|
"ERR_PHYSICAL_NAME_MULTIPLE",
|
|
140
140
|
// FR-013 — field-level @readOnly cross-attribute validation.
|
|
141
|
+
"ERR_MUTABILITY_AUTOSET_CONFLICT",
|
|
142
|
+
"ERR_MUTABILITY_DOWNGRADE",
|
|
141
143
|
"ERR_READONLY_ASSIGNED_PRIMARY",
|
|
142
|
-
"ERR_READONLY_DOWNGRADE",
|
|
143
144
|
// FR-015 — source.rdb @parameterRef typed-input validation.
|
|
144
145
|
"ERR_PARAMETER_REF_UNRESOLVED",
|
|
145
146
|
"ERR_PARAMETER_REF_NOT_VALUE_OBJECT",
|
|
@@ -208,6 +209,18 @@ export const ERROR_CODES = [
|
|
|
208
209
|
// an integer array. An array-of-enum stays string-backed: drop @intValueMap,
|
|
209
210
|
// or make the field scalar.
|
|
210
211
|
"ERR_ENUM_INT_VALUE_MAP_ARRAY",
|
|
212
|
+
// Phase-1 metadata-source-resolution — a path source declared in
|
|
213
|
+
// .metaobjects/config.json does not exist on disk.
|
|
214
|
+
"ERR_SOURCE_UNRESOLVED",
|
|
215
|
+
// Phase-1 metadata-source-resolution — a declared source kind (resource or
|
|
216
|
+
// package) is not supported by this toolchain.
|
|
217
|
+
"ERR_SOURCE_KIND_UNSUPPORTED",
|
|
218
|
+
// Phase-1 metadata-source-resolution — a scope include/exclude package
|
|
219
|
+
// pattern is malformed (empty pattern or empty :: segment).
|
|
220
|
+
"ERR_SCOPE_PATTERN_INVALID",
|
|
221
|
+
// Phase-1 metadata-source-resolution — no metadata collection was discovered:
|
|
222
|
+
// no config declaring sources, and no default metaobjects/ directory.
|
|
223
|
+
"ERR_COLLECTION_NOT_FOUND",
|
|
211
224
|
"ERR_UNKNOWN",
|
|
212
225
|
] as const;
|
|
213
226
|
|
|
@@ -226,7 +239,8 @@ export const WARNING_CODES = [
|
|
|
226
239
|
// FR-013 — @readOnly on a field child of object.value. The persistence
|
|
227
240
|
// implication does not apply to value-objects; the attr is retained for
|
|
228
241
|
// language-specific record/struct treatment (e.g. Kotlin `val` vs `var`).
|
|
229
|
-
"
|
|
242
|
+
"WARN_MUTABILITY_VALUE_OBJECT",
|
|
243
|
+
"WARN_MUTABILITY_READONLY_HOST",
|
|
230
244
|
// #208 — a host object whose source carries @unmanaged also declares an
|
|
231
245
|
// origin.*-bearing (derived) field. Deliberate asymmetry with
|
|
232
246
|
// ERR_ORIGIN_UNDER_SQL_BODY: @unmanaged acts on nothing (the tool never
|
package/src/index.ts
CHANGED
|
@@ -27,6 +27,14 @@ export * from "./shared/base-types.js";
|
|
|
27
27
|
export * from "./shared/structural.js";
|
|
28
28
|
export * from "./core/object/object-constants.js";
|
|
29
29
|
export * from "./core/field/field-constants.js";
|
|
30
|
+
// FR-037 R1 — THE mutability accessors. Every consumer deciding "may this be
|
|
31
|
+
// written, and when?" must go through these rather than reading the attr, so the
|
|
32
|
+
// absent-means-readWrite default lives in exactly one place per port.
|
|
33
|
+
export {
|
|
34
|
+
fieldMutability,
|
|
35
|
+
isReadOnlyMutability,
|
|
36
|
+
isWriteOnceMutability,
|
|
37
|
+
} from "./core/field/validate-field-mutability.js";
|
|
30
38
|
export * from "./core/attr/attr-constants.js";
|
|
31
39
|
export * from "./core/documentation/doc-constants.js";
|
|
32
40
|
export * from "./core/validator/validator-constants.js";
|
|
@@ -34,6 +42,13 @@ export * from "./core/identity/identity-constants.js";
|
|
|
34
42
|
export * from "./core/index/index-constants.js";
|
|
35
43
|
export * from "./core/requirement/requirement-constants.js";
|
|
36
44
|
export { MetaRequirement } from "./core/requirement/meta-requirement.js";
|
|
45
|
+
// Shared `@implementedBy` resolution — one resolver for the CLI's requirement
|
|
46
|
+
// checks and codegen's requirement-test fan-out (FR-038).
|
|
47
|
+
export {
|
|
48
|
+
resolveClaim,
|
|
49
|
+
resolveClaimTarget,
|
|
50
|
+
resolveMember,
|
|
51
|
+
} from "./core/requirement/resolve-claim.js";
|
|
37
52
|
export * from "./core/relationship/relationship-constants.js";
|
|
38
53
|
export * from "./core/query/query-constants.js";
|
|
39
54
|
export * from "./persistence/source/source-constants.js";
|
|
@@ -121,7 +136,6 @@ export {
|
|
|
121
136
|
MetaOrigin,
|
|
122
137
|
MetaPassthroughOrigin,
|
|
123
138
|
MetaAggregateOrigin,
|
|
124
|
-
MetaCollectionOrigin,
|
|
125
139
|
MetaComputedOrigin,
|
|
126
140
|
MetaFirstOrigin,
|
|
127
141
|
} from "./persistence/origin/meta-origin.js";
|
|
@@ -273,3 +287,17 @@ export {
|
|
|
273
287
|
stripPackage,
|
|
274
288
|
} from "./naming.js";
|
|
275
289
|
export type { EntityNameMap, ColumnNamingStrategy } from "./naming.js";
|
|
290
|
+
|
|
291
|
+
// Retired vocabulary: the map the loader reads to explain a retirement, and the raw-document
|
|
292
|
+
// rewriter `meta upgrade` drives from the SAME entries — so the error message and the fix
|
|
293
|
+
// cannot drift apart.
|
|
294
|
+
export {
|
|
295
|
+
RETIRED_VOCABULARY,
|
|
296
|
+
retiredAttr,
|
|
297
|
+
retiredAttrValue,
|
|
298
|
+
retiredSubType,
|
|
299
|
+
retirementHint,
|
|
300
|
+
} from "./retired-vocabulary.js";
|
|
301
|
+
export type { RetirementNote, RetiredEntry, VocabularyRewrite } from "./retired-vocabulary.js";
|
|
302
|
+
export { rewriteDocument } from "./vocabulary-rewrite.js";
|
|
303
|
+
export type { RewriteResult, RewriteChange, RewriteRefusal, RewriteOpts } from "./vocabulary-rewrite.js";
|
|
@@ -51,6 +51,20 @@ function getLibraryDir(): string | undefined {
|
|
|
51
51
|
return (_cache ??= { dir: libraryDirOnDisk() }).dir;
|
|
52
52
|
}
|
|
53
53
|
|
|
54
|
+
/**
|
|
55
|
+
* The library package names this build ships, sorted.
|
|
56
|
+
*
|
|
57
|
+
* `librarySources` skips an unrecognised package silently — the right behaviour for a
|
|
58
|
+
* programmatic caller asking for something a given version may not ship. A name a human
|
|
59
|
+
* typed into a config file is a different case: skipping it silently resurfaces later as
|
|
60
|
+
* `ERR_UNRESOLVED_SUPER` pointing at the adopter's own metadata, which is the wrong place
|
|
61
|
+
* to go looking. Config readers use this to refuse an unknown name and say what IS
|
|
62
|
+
* available (Python's `project_config` draws the same line, in the same place).
|
|
63
|
+
*/
|
|
64
|
+
export function knownLibraryPackages(): string[] {
|
|
65
|
+
return Object.keys(REFS_BY_PACKAGE).sort();
|
|
66
|
+
}
|
|
67
|
+
|
|
54
68
|
/**
|
|
55
69
|
* Returns a list of `MetaDataSource` instances for the requested library packages.
|
|
56
70
|
*
|
|
@@ -24,10 +24,10 @@ import { validateSourceRoles } from "../persistence/source/validate-source-roles
|
|
|
24
24
|
import { validateSourceEscapes } from "../persistence/source/validate-source-escapes.js";
|
|
25
25
|
import { validateSourcePhysicalNames } from "../persistence/source/validate-source-physical-names.js";
|
|
26
26
|
import { validateSourceParameterRef } from "../persistence/source/validate-source-parameter-ref.js";
|
|
27
|
-
import {
|
|
27
|
+
import { validateFieldMutability } from "../core/field/validate-field-mutability.js";
|
|
28
28
|
import { validateEnumNormalizeAmbiguity } from "../core/field/validate-enum-normalize-ambiguity.js";
|
|
29
29
|
import { validateDiscriminator } from "../core/object/validate-discriminator.js";
|
|
30
|
-
import { resolveDeferredSupers } from "../super-resolve.js";
|
|
30
|
+
import { resolveDeferredSupers, EXTENDS_TARGET_MISMATCH_RULE } from "../super-resolve.js";
|
|
31
31
|
import { validateSubtypeRules } from "../subtype-rules.js";
|
|
32
32
|
import { validateMaxOccurs } from "../validate-max-occurs.js";
|
|
33
33
|
import { validateIdentityPassthrough } from "../core/identity/validate-identity-passthrough.js";
|
|
@@ -534,7 +534,7 @@ export class MetaDataLoader {
|
|
|
534
534
|
const t = failure.target;
|
|
535
535
|
errors.push(
|
|
536
536
|
new ParseError(
|
|
537
|
-
`the extends target '${failure.ref}' is ${t?.type}.${t?.subType} but the extending node '${failure.nodeFqn}' is ${r?.type}.${r?.subType} —
|
|
537
|
+
`the extends target '${failure.ref}' is ${t?.type}.${t?.subType} but the extending node '${failure.nodeFqn}' is ${r?.type}.${r?.subType} — ${EXTENDS_TARGET_MISMATCH_RULE}`,
|
|
538
538
|
{
|
|
539
539
|
code: "ERR_EXTENDS_TARGET_MISMATCH",
|
|
540
540
|
source: resolvedSource(failure.source, failure.nodeFqn, failure.ref),
|
|
@@ -650,12 +650,13 @@ export class MetaDataLoader {
|
|
|
650
650
|
errors.push(...physicalNameResult.errors);
|
|
651
651
|
envelopeWarnings.push(...physicalNameResult.warnings);
|
|
652
652
|
|
|
653
|
-
// FR-
|
|
654
|
-
// (
|
|
655
|
-
//
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
653
|
+
// FR-037 R1 — field-level @mutability cross-attribute rules
|
|
654
|
+
// (ERR_MUTABILITY_AUTOSET_CONFLICT / ERR_MUTABILITY_DOWNGRADE /
|
|
655
|
+
// ERR_READONLY_ASSIGNED_PRIMARY / WARN_MUTABILITY_VALUE_OBJECT /
|
|
656
|
+
// WARN_MUTABILITY_READONLY_HOST).
|
|
657
|
+
const mutabilityResult = validateFieldMutability(root);
|
|
658
|
+
errors.push(...mutabilityResult.errors);
|
|
659
|
+
envelopeWarnings.push(...mutabilityResult.warnings);
|
|
659
660
|
|
|
660
661
|
// Authoring guard — a field.enum vocabulary that is ambiguous under the
|
|
661
662
|
// default `@normalize: strip` (a member equal to the concatenation of
|
|
@@ -1109,8 +1109,8 @@ export function validateOriginPaths(root: MetaData): ParseError[] {
|
|
|
1109
1109
|
for (const field of obj.ownChildren().filter((c) => c.type === TYPE_FIELD)) {
|
|
1110
1110
|
for (const origin of field.ownChildren().filter((c) => c.type === TYPE_ORIGIN)) {
|
|
1111
1111
|
// #210 — assembly origins live on projections. A value-hosted field may
|
|
1112
|
-
// not carry origin.aggregate / origin.computed / origin.
|
|
1113
|
-
//
|
|
1112
|
+
// not carry origin.aggregate / origin.computed / origin.first:
|
|
1113
|
+
// a value is constructed — by a caller or by embedding —
|
|
1114
1114
|
// never assembled from a backing store. origin.passthrough STAYS legal
|
|
1115
1115
|
// on a value (FR-015 parameter lineage; the B5 exemption below).
|
|
1116
1116
|
if (
|
|
@@ -1997,7 +1997,7 @@ function checkFilterClauses(
|
|
|
1997
1997
|
// - a plain (extends-bound / no-origin) or origin.passthrough or origin.computed
|
|
1998
1998
|
// field → addressable (a base/joined column, or an inlined row-level expression).
|
|
1999
1999
|
// - an aggregate-derived field (origin.aggregate — count/sum/…/any/all/collect —
|
|
2000
|
-
// or origin.first
|
|
2000
|
+
// or origin.first) → NOT addressable: a WHERE runs before
|
|
2001
2001
|
// aggregation, so it cannot see an aggregate (post-aggregate filtering is HAVING,
|
|
2002
2002
|
// a separate later extension). Fail-closed → ERR_BAD_ATTR_FILTER.
|
|
2003
2003
|
// - a ref naming no declared field → dangling → ERR_BAD_ATTR_FILTER.
|
package/src/naming-refs.ts
CHANGED
|
@@ -37,7 +37,6 @@ import {
|
|
|
37
37
|
ORIGIN_PASSTHROUGH_ATTR_VIA,
|
|
38
38
|
ORIGIN_AGGREGATE_ATTR_OF,
|
|
39
39
|
ORIGIN_AGGREGATE_ATTR_VIA,
|
|
40
|
-
ORIGIN_COLLECTION_ATTR_VIA,
|
|
41
40
|
} from "./persistence/origin/origin-constants.js";
|
|
42
41
|
import { SOURCE_ATTR_PARAMETER_REF } from "./persistence/source/source-constants.js";
|
|
43
42
|
import { TEMPLATE_ATTR_PAYLOAD_REF, TEMPLATE_ATTR_RESPONSE_REF } from "./template/template-constants.js";
|
|
@@ -63,10 +62,9 @@ export const REF_BEARING_ATTR_NAMES: ReadonlySet<string> = new Set<string>([
|
|
|
63
62
|
RELATIONSHIP_ATTR_THROUGH, // ADR-0042: the M:N junction ref joins the desugar+resolution set.
|
|
64
63
|
IDENTITY_REFERENCE_ATTR_REFERENCES,
|
|
65
64
|
ORIGIN_PASSTHROUGH_ATTR_FROM,
|
|
66
|
-
ORIGIN_PASSTHROUGH_ATTR_VIA, // = ORIGIN_AGGREGATE_ATTR_VIA
|
|
65
|
+
ORIGIN_PASSTHROUGH_ATTR_VIA, // = ORIGIN_AGGREGATE_ATTR_VIA ("via")
|
|
67
66
|
ORIGIN_AGGREGATE_ATTR_OF,
|
|
68
67
|
ORIGIN_AGGREGATE_ATTR_VIA,
|
|
69
|
-
ORIGIN_COLLECTION_ATTR_VIA,
|
|
70
68
|
SOURCE_ATTR_PARAMETER_REF,
|
|
71
69
|
TEMPLATE_ATTR_PAYLOAD_REF,
|
|
72
70
|
TEMPLATE_ATTR_RESPONSE_REF,
|
package/src/parser-core.ts
CHANGED
|
@@ -29,9 +29,16 @@ import { MetaRoot } from "./shared/meta-root.js";
|
|
|
29
29
|
import { MetaAttr } from "./core/attr/meta-attr.js";
|
|
30
30
|
import { canonicalSerialize, inferAttrSubType } from "./serializer-json.js";
|
|
31
31
|
import { ParseError, type ErrorCode } from "./errors.js";
|
|
32
|
+
// #337 — see retired-vocabulary.ts. Diagnostic only; no load outcome changes.
|
|
33
|
+
import { retiredSubType, retirementHint } from "./retired-vocabulary.js";
|
|
32
34
|
import { resolvedSource, type ErrorSource, type LoaderWarning, type Contributor } from "./source.js";
|
|
33
35
|
import { semanticDiff } from "./semantic-diff.js";
|
|
34
|
-
import {
|
|
36
|
+
import {
|
|
37
|
+
resolveSuperRef,
|
|
38
|
+
isChildTargetingRef,
|
|
39
|
+
extendsTargetCompatible,
|
|
40
|
+
EXTENDS_TARGET_MISMATCH_RULE,
|
|
41
|
+
} from "./super-resolve.js";
|
|
35
42
|
import { JsonPathBuilder } from "./json-path.js";
|
|
36
43
|
import { getYamlPosition, type YamlPosition } from "./core/yaml-positions.js";
|
|
37
44
|
import {
|
|
@@ -422,8 +429,13 @@ export function buildTree(parsed: unknown, opts: ParseOptions): ParseResult {
|
|
|
422
429
|
_currentPath!.pushKey(rootKey);
|
|
423
430
|
const src = errSource();
|
|
424
431
|
_currentPath!.pop();
|
|
432
|
+
// Same hint at the ROOT door. No retired subtype is root-legal today, so this arm
|
|
433
|
+
// is currently unreachable — wired anyway, because "fixed one door, left the
|
|
434
|
+
// other" is how a rule ends up half-true and passing every probe.
|
|
435
|
+
const retiredRoot = retiredSubType(rootType, rootSubType);
|
|
425
436
|
throw new ParseError(
|
|
426
|
-
`Unknown root type "${rootType}.${rootSubType}" —
|
|
437
|
+
`Unknown root type "${rootType}.${rootSubType}" — ` +
|
|
438
|
+
(retiredRoot !== undefined ? retirementHint(retiredRoot) : "not registered"),
|
|
427
439
|
{ code: rootTypeCode, source: src },
|
|
428
440
|
);
|
|
429
441
|
}
|
|
@@ -607,12 +619,18 @@ function parseNodeFresh(
|
|
|
607
619
|
// FR-024 — a dotted child-targeting ref must resolve to a node of the
|
|
608
620
|
// SAME type and subtype as the extending node. Dotted-only check; the
|
|
609
621
|
// shipped top-level extends behavior is unchanged.
|
|
622
|
+
//
|
|
623
|
+
// The predicate is IMPORTED, not restated: this eager path and
|
|
624
|
+
// super-resolve's deferred path are two doors onto one rule, and they
|
|
625
|
+
// previously held independent copies of the boolean — so #310's relaxation
|
|
626
|
+
// applied to one would have left the other refusing, on whichever path a
|
|
627
|
+
// given loader configuration happens to take.
|
|
610
628
|
if (
|
|
611
629
|
isChildTargetingRef(model.superRef) &&
|
|
612
|
-
(
|
|
630
|
+
!extendsTargetCompatible(model, superModel)
|
|
613
631
|
) {
|
|
614
632
|
throw new ParseError(
|
|
615
|
-
`the extends target '${model.superRef}' is ${superModel.type}.${superModel.subType} but the extending node '${model.fqn()}' is ${model.type}.${model.subType} —
|
|
633
|
+
`the extends target '${model.superRef}' is ${superModel.type}.${superModel.subType} but the extending node '${model.fqn()}' is ${model.type}.${model.subType} — ${EXTENDS_TARGET_MISMATCH_RULE}`,
|
|
616
634
|
{
|
|
617
635
|
code: "ERR_EXTENDS_TARGET_MISMATCH",
|
|
618
636
|
source: resolvedSource(errSource(), model.fqn(), model.superRef),
|
|
@@ -1253,9 +1271,13 @@ function processChildren(
|
|
|
1253
1271
|
const childTypeCode = explicit && registry.allSubTypesOf(childType).length > 0
|
|
1254
1272
|
? "ERR_UNKNOWN_SUBTYPE" as const
|
|
1255
1273
|
: "ERR_UNKNOWN_TYPE" as const;
|
|
1274
|
+
// #337: a subtype we RETIRED (origin.collection) gets its retirement and its
|
|
1275
|
+
// migration, not a bare "not registered" that reads like a broken install.
|
|
1276
|
+
const retiredChild = retiredSubType(childType, childSubType);
|
|
1256
1277
|
errors.push(
|
|
1257
1278
|
new ParseError(
|
|
1258
|
-
`Unknown type "${childType}.${childSubType}" —
|
|
1279
|
+
`Unknown type "${childType}.${childSubType}" — ` +
|
|
1280
|
+
(retiredChild !== undefined ? retirementHint(retiredChild) : "not registered"),
|
|
1259
1281
|
{ code: childTypeCode, source: errSource() },
|
|
1260
1282
|
),
|
|
1261
1283
|
);
|
|
@@ -14,7 +14,6 @@ import {
|
|
|
14
14
|
ORIGIN_AGGREGATE_ATTR_AGG,
|
|
15
15
|
ORIGIN_AGGREGATE_ATTR_OF,
|
|
16
16
|
ORIGIN_AGGREGATE_ATTR_VIA,
|
|
17
|
-
ORIGIN_COLLECTION_ATTR_VIA,
|
|
18
17
|
ORIGIN_COMPUTED_ATTR_EXPR,
|
|
19
18
|
ORIGIN_FIRST_ATTR_OF,
|
|
20
19
|
ORIGIN_FIRST_ATTR_VIA,
|
|
@@ -77,21 +76,6 @@ export class MetaAggregateOrigin extends MetaOrigin {
|
|
|
77
76
|
}
|
|
78
77
|
}
|
|
79
78
|
|
|
80
|
-
/**
|
|
81
|
-
* Collection origin — the (array) field's value is a relationship-derived
|
|
82
|
-
* array of nested view-objects (FR-004 R4). Carries `@via` (required): the
|
|
83
|
-
* dotted relationship path the collection walks (e.g. "Author.posts"), or a
|
|
84
|
-
* wildcard-prefixed selector for a package-spanning collection (e.g. "*.User").
|
|
85
|
-
*/
|
|
86
|
-
export class MetaCollectionOrigin extends MetaOrigin {
|
|
87
|
-
/** The dotted relationship path (or wildcard selector) this collection is sourced from. */
|
|
88
|
-
get via(): string | undefined {
|
|
89
|
-
// ADR-0039: own — origin.* never inherits (ADR-0029), so own is correct.
|
|
90
|
-
const v = this.ownAttr(ORIGIN_COLLECTION_ATTR_VIA);
|
|
91
|
-
return typeof v === "string" ? v : undefined;
|
|
92
|
-
}
|
|
93
|
-
}
|
|
94
|
-
|
|
95
79
|
/**
|
|
96
80
|
* Computed origin (#195) — a row-level value computed from the base entity's own
|
|
97
81
|
* fields via a structured expression tree (`@expr`). No related rows, no `@via`.
|
|
@@ -13,7 +13,15 @@ import { SUBTYPE_BASE } from "../../shared/base-types.js";
|
|
|
13
13
|
|
|
14
14
|
export const ORIGIN_SUBTYPE_PASSTHROUGH = "passthrough";
|
|
15
15
|
export const ORIGIN_SUBTYPE_AGGREGATE = "aggregate";
|
|
16
|
-
|
|
16
|
+
// FR-037 R2 — `collection` is RESERVED, NOT REGISTERED. It duplicated
|
|
17
|
+
// `origin.aggregate @agg: collect` on a strictly smaller attr set (@via only —
|
|
18
|
+
// no @filter, no @orderBy, no @distinct), and nothing dispatched on it: its last
|
|
19
|
+
// real consumer, the payload-VO typing edge, was deleted in 0.20.16 (#270) for
|
|
20
|
+
// being actively wrong. Re-entry bar (ADR-0007 Amendment 2): a member enters the
|
|
21
|
+
// registry only when a shipping consumer dispatches on it. The designated
|
|
22
|
+
// re-entry shape is `@agg: collect` with `@of` made OPTIONAL (absent = whole-
|
|
23
|
+
// object rollup, typed by the field's declared @objectRef + isArray), NOT a
|
|
24
|
+
// restored subtype.
|
|
17
25
|
// #195 — computed: a row-level value from the base entity's own fields via a
|
|
18
26
|
// structured @expr tree (no related rows). first: the single related row picked
|
|
19
27
|
// by @orderBy along @via, projecting @of (argmax-then-project).
|
|
@@ -24,7 +32,6 @@ export const ORIGIN_SUBTYPES = [
|
|
|
24
32
|
SUBTYPE_BASE,
|
|
25
33
|
ORIGIN_SUBTYPE_PASSTHROUGH,
|
|
26
34
|
ORIGIN_SUBTYPE_AGGREGATE,
|
|
27
|
-
ORIGIN_SUBTYPE_COLLECTION,
|
|
28
35
|
ORIGIN_SUBTYPE_COMPUTED,
|
|
29
36
|
ORIGIN_SUBTYPE_FIRST,
|
|
30
37
|
] as const;
|
|
@@ -38,7 +45,6 @@ export type OriginSubType = (typeof ORIGIN_SUBTYPES)[number];
|
|
|
38
45
|
export const ASSEMBLY_ORIGIN_SUBTYPES = [
|
|
39
46
|
ORIGIN_SUBTYPE_AGGREGATE,
|
|
40
47
|
ORIGIN_SUBTYPE_COMPUTED,
|
|
41
|
-
ORIGIN_SUBTYPE_COLLECTION,
|
|
42
48
|
ORIGIN_SUBTYPE_FIRST,
|
|
43
49
|
] as const;
|
|
44
50
|
|
|
@@ -50,11 +56,6 @@ export const ORIGIN_PASSTHROUGH_ATTR_VIA = "via";
|
|
|
50
56
|
// does NOT generate a cast; real type-converting projections are origin.computed (#195/#159).
|
|
51
57
|
export const ORIGIN_PASSTHROUGH_ATTR_CONVERT = "convert";
|
|
52
58
|
|
|
53
|
-
// collection attrs — a relationship-derived array of nested view-objects
|
|
54
|
-
// (FR-004 R4). @via is the dotted relationship path (optionally wildcard-
|
|
55
|
-
// prefixed, e.g. "*.User", for a package-spanning collection).
|
|
56
|
-
export const ORIGIN_COLLECTION_ATTR_VIA = "via";
|
|
57
|
-
|
|
58
59
|
// aggregate attrs
|
|
59
60
|
export const ORIGIN_AGGREGATE_ATTR_AGG = "agg";
|
|
60
61
|
export const ORIGIN_AGGREGATE_ATTR_OF = "of";
|
|
@@ -114,22 +114,6 @@ export const ORIGIN_DEFINITION: ProviderDefinition = {
|
|
|
114
114
|
}
|
|
115
115
|
]
|
|
116
116
|
},
|
|
117
|
-
{
|
|
118
|
-
"type": "origin",
|
|
119
|
-
"subType": "collection",
|
|
120
|
-
"description": "A relationship-derived array of nested view-objects: walks @via to produce the collection (e.g. 'Author.posts'), or a wildcard selector for a package-spanning collection.",
|
|
121
|
-
"whenToUse": "A projection needs an array of nested child view-objects (a parent with its children inline). Declare it instead of hand-assembling the nested query + mapping.",
|
|
122
|
-
"children": [
|
|
123
|
-
{
|
|
124
|
-
"type": "attr",
|
|
125
|
-
"subType": "string",
|
|
126
|
-
"name": "via",
|
|
127
|
-
"min": 1,
|
|
128
|
-
"max": 1,
|
|
129
|
-
"description": "Dotted relationship path the collection walks to produce an array of nested view-objects (e.g. 'Author.posts'), or a wildcard selector for a package-spanning collection (e.g. '*.User')."
|
|
130
|
-
}
|
|
131
|
-
]
|
|
132
|
-
},
|
|
133
117
|
{
|
|
134
118
|
"type": "origin",
|
|
135
119
|
"subType": "computed",
|
package/src/registry-manifest.ts
CHANGED
|
@@ -103,11 +103,16 @@ interface ManifestType {
|
|
|
103
103
|
* manifest (the byte-exact bill of materials), NOT a per-provider or per-file marker:
|
|
104
104
|
* every port emits the same string, asserted by registry-conformance. Pre-1.0 the
|
|
105
105
|
* vocabulary is still `0.x` (semver = unstable, may change) but largely settled going
|
|
106
|
-
* into the quiet period
|
|
107
|
-
*
|
|
108
|
-
*
|
|
106
|
+
* into the quiet period; the 1.0 cut (readiness G1) freezes it to `"1.0"`. Decoupled
|
|
107
|
+
* from every package line — it is the spec version, not a package version.
|
|
108
|
+
*
|
|
109
|
+
* The current value is the declaration below and nothing else. Do not restate it in
|
|
110
|
+
* prose: `scripts/check-metamodel-version.mjs --set` rewrites the declaration, so any
|
|
111
|
+
* copy in a comment goes stale on the very next bump (it said `"0.9"` here while the
|
|
112
|
+
* constant read `"0.10"`). Bump with that script — never by hand — so the manifest and
|
|
113
|
+
* all four port constants move together.
|
|
109
114
|
*/
|
|
110
|
-
export const METAMODEL_VERSION = "0.
|
|
115
|
+
export const METAMODEL_VERSION = "0.10";
|
|
111
116
|
|
|
112
117
|
/** The full canonical manifest. All collections are sorted for byte-stability. */
|
|
113
118
|
interface RegistryManifest {
|