@vertekum/schema-builder 0.3.0 → 0.3.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.
- package/CHANGELOG.md +8 -0
- package/docs/modules.md +2 -2
- package/package.json +3 -3
- package/src/build.ts +33 -23
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,13 @@
|
|
|
1
1
|
# @vertekum/schema-builder
|
|
2
2
|
|
|
3
|
+
## 0.3.1
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- [`7f9db48`](https://github.com/moros-oxus/vertekum/commit/7f9db48344c672b90a97f3f4608bf7de893799bf) Thanks [@tschemmer](https://github.com/tschemmer)! - `<@name>` resolution gains key precedence: an import keyed `name` wins outright — its root, else its own `name` production — so sibling imports' public productions can no longer shadow or collide with a keyed module. The cross-import production search remains as the fallback when no key matches.
|
|
8
|
+
- Updated dependencies []:
|
|
9
|
+
- @vertekum/core@0.3.1
|
|
10
|
+
|
|
3
11
|
## 0.3.0
|
|
4
12
|
|
|
5
13
|
### Minor Changes
|
package/docs/modules.md
CHANGED
|
@@ -38,8 +38,8 @@ use "./system/color.dfn" as system-color
|
|
|
38
38
|
|
|
39
39
|
| Reference | Means |
|
|
40
40
|
| -------------------- | ---------------------------------------------------------------------------- |
|
|
41
|
-
| `<@key>` |
|
|
42
|
-
| `<@name>` | the production `name`, searched across every import; unambiguous or an error. |
|
|
41
|
+
| `<@key>` | an import KEYED `key` **wins outright**: its root — else its own `key` production (the fragment idiom) — sibling imports' productions can never shadow or collide with it. |
|
|
42
|
+
| `<@name>` | no key matches: the production `name`, searched across every import; unambiguous or an error. |
|
|
43
43
|
| `<@key/name>` | qualified: that import's production alone — the collision resolver. |
|
|
44
44
|
|
|
45
45
|
When two imports both declare `<accent>`, the unqualified `<@accent>` refuses with the
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@vertekum/schema-builder",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.1",
|
|
4
4
|
"description": "Declare token vocabularies as grammar; build them into JSON Schema files",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"keywords": [
|
|
@@ -37,13 +37,13 @@
|
|
|
37
37
|
"./cli": "./src/cli.ts"
|
|
38
38
|
},
|
|
39
39
|
"peerDependencies": {
|
|
40
|
-
"@vertekum/core": "0.3.
|
|
40
|
+
"@vertekum/core": "0.3.1"
|
|
41
41
|
},
|
|
42
42
|
"dependencies": {
|
|
43
43
|
"zod": "^3.25.76"
|
|
44
44
|
},
|
|
45
45
|
"devDependencies": {
|
|
46
|
-
"@vertekum/core": "0.3.
|
|
46
|
+
"@vertekum/core": "0.3.1",
|
|
47
47
|
"@vertekum/schema-vocabulary": "0.3.0"
|
|
48
48
|
}
|
|
49
49
|
}
|
package/src/build.ts
CHANGED
|
@@ -125,41 +125,51 @@ function target(
|
|
|
125
125
|
};
|
|
126
126
|
}
|
|
127
127
|
|
|
128
|
+
// 1. A module KEY match wins outright — a keyed module cannot be shadowed by (or
|
|
129
|
+
// collide with) sibling imports' productions. Its root; else its OWN production of
|
|
130
|
+
// the same name (the fragment-declares-its-own-name idiom); else the fragment hint.
|
|
131
|
+
const keyed = scope.module.imports.get(ref.name);
|
|
132
|
+
if (keyed) {
|
|
133
|
+
const keyedScope: Scope = {
|
|
134
|
+
module: keyed,
|
|
135
|
+
expanding: new Set(),
|
|
136
|
+
warn: scope.warn,
|
|
137
|
+
};
|
|
138
|
+
if (keyed.module.root) {
|
|
139
|
+
return {
|
|
140
|
+
node: keyed.module.root,
|
|
141
|
+
scope: keyedScope,
|
|
142
|
+
importedRoot: keyed,
|
|
143
|
+
};
|
|
144
|
+
}
|
|
145
|
+
const own = keyed.module.productions.get(ref.name);
|
|
146
|
+
if (own && !keyed.module.private.has(ref.name)) {
|
|
147
|
+
return { node: own, scope: keyedScope };
|
|
148
|
+
}
|
|
149
|
+
throw new DfnError(
|
|
150
|
+
`'${ref.name}' is imported, but it declares no root (a fragment) — reference one of its productions: ${productionsOf(ref.name, keyed)}`,
|
|
151
|
+
ref.line,
|
|
152
|
+
ref.column,
|
|
153
|
+
file,
|
|
154
|
+
);
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
// 2. No key match: the production searched across every import — unambiguous or say so.
|
|
128
158
|
const hits: Array<{
|
|
129
159
|
node: Node;
|
|
130
160
|
scope: Scope;
|
|
131
161
|
importedRoot?: ResolvedModule;
|
|
132
162
|
}> = [];
|
|
133
|
-
for (const
|
|
134
|
-
const importedScope: Scope = {
|
|
135
|
-
module: imported,
|
|
136
|
-
expanding: new Set(),
|
|
137
|
-
warn: scope.warn,
|
|
138
|
-
};
|
|
163
|
+
for (const imported of scope.module.imports.values()) {
|
|
139
164
|
const production = imported.module.productions.get(ref.name);
|
|
140
165
|
if (production && !imported.module.private.has(ref.name)) {
|
|
141
|
-
hits.push({ node: production, scope: importedScope });
|
|
142
|
-
}
|
|
143
|
-
if (key === ref.name && imported.module.root) {
|
|
144
166
|
hits.push({
|
|
145
|
-
node:
|
|
146
|
-
scope:
|
|
147
|
-
importedRoot: imported,
|
|
167
|
+
node: production,
|
|
168
|
+
scope: { module: imported, expanding: new Set(), warn: scope.warn },
|
|
148
169
|
});
|
|
149
170
|
}
|
|
150
171
|
}
|
|
151
172
|
if (hits.length === 0) {
|
|
152
|
-
// The near-miss that reads as a missing `use`: the import EXISTS under this key, but
|
|
153
|
-
// `<@key>` means its root and a fragment has none. Say so, and name the real forms.
|
|
154
|
-
const fragment = scope.module.imports.get(ref.name);
|
|
155
|
-
if (fragment) {
|
|
156
|
-
throw new DfnError(
|
|
157
|
-
`'${ref.name}' is imported, but it declares no root (a fragment) — reference one of its productions: ${productionsOf(ref.name, fragment)}`,
|
|
158
|
-
ref.line,
|
|
159
|
-
ref.column,
|
|
160
|
-
file,
|
|
161
|
-
);
|
|
162
|
-
}
|
|
163
173
|
throw new DfnError(
|
|
164
174
|
`no import provides '<@${ref.name}>'`,
|
|
165
175
|
ref.line,
|