@atscript/typescript 0.1.58 → 0.1.60
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/utils.cjs +39 -19
- package/dist/utils.d.ts +0 -17
- package/dist/utils.mjs +39 -19
- package/package.json +4 -4
package/dist/utils.cjs
CHANGED
|
@@ -109,10 +109,32 @@ function throwFeatureDisabled(feature, option, annotation) {
|
|
|
109
109
|
|
|
110
110
|
//#endregion
|
|
111
111
|
//#region packages/typescript/src/runtime/flatten.ts
|
|
112
|
+
/**
|
|
113
|
+
* Flattens an annotated object type into a map of dot-separated paths to their annotated types.
|
|
114
|
+
*
|
|
115
|
+
* For an object like `{ address: { street: string, city: string } }`, the result contains:
|
|
116
|
+
* - `''` → the root object type
|
|
117
|
+
* - `'address'` → the address object type
|
|
118
|
+
* - `'address.street'` → string type
|
|
119
|
+
* - `'address.city'` → string type
|
|
120
|
+
*
|
|
121
|
+
* Arrays are recursed into (their element types are flattened with the same prefix).
|
|
122
|
+
* Unions/intersections/tuples are recursed into (each branch contributes to the same path,
|
|
123
|
+
* merging via synthetic union types when paths collide).
|
|
124
|
+
*
|
|
125
|
+
* @param type - The root annotated type (must be an object type).
|
|
126
|
+
* @param options - Optional hooks for domain-specific processing.
|
|
127
|
+
* @returns A map of dot-separated field paths to their annotated types.
|
|
128
|
+
*/ const EMPTY_ANCESTORS = new Set();
|
|
129
|
+
function extendAncestors(ancestors, id) {
|
|
130
|
+
if (!id || ancestors.has(id)) return ancestors;
|
|
131
|
+
const next = new Set(ancestors);
|
|
132
|
+
next.add(id);
|
|
133
|
+
return next;
|
|
134
|
+
}
|
|
112
135
|
function flattenAnnotatedType(type, options) {
|
|
113
136
|
const flatMap = new Map();
|
|
114
137
|
const skipPhantom = !!options?.excludePhantomTypes;
|
|
115
|
-
const visitedIds = new Set();
|
|
116
138
|
function addFieldToFlatMap(name, def) {
|
|
117
139
|
const existing = flatMap.get(name);
|
|
118
140
|
if (existing) {
|
|
@@ -125,62 +147,60 @@ else flatUnion.item(existing);
|
|
|
125
147
|
flatMap.set(name, flatUnion.$type);
|
|
126
148
|
} else flatMap.set(name, def);
|
|
127
149
|
}
|
|
128
|
-
function flattenArray(def, name) {
|
|
150
|
+
function flattenArray(def, name, ancestors) {
|
|
129
151
|
const resolvedId = def.id;
|
|
130
|
-
if (resolvedId)
|
|
131
|
-
|
|
132
|
-
visitedIds.add(resolvedId);
|
|
133
|
-
}
|
|
152
|
+
if (resolvedId && ancestors.has(resolvedId)) return;
|
|
153
|
+
let childAncestors = extendAncestors(ancestors, resolvedId);
|
|
134
154
|
switch (def.type.kind) {
|
|
135
155
|
case "object": {
|
|
136
156
|
if (!resolvedId && def.id) {
|
|
137
|
-
if (
|
|
138
|
-
|
|
157
|
+
if (ancestors.has(def.id)) return;
|
|
158
|
+
childAncestors = extendAncestors(ancestors, def.id);
|
|
139
159
|
}
|
|
140
160
|
const items = Array.from(def.type.props.entries());
|
|
141
161
|
for (const [key, value] of items) {
|
|
142
162
|
if (skipPhantom && require_json_schema.isPhantomType(value)) continue;
|
|
143
|
-
flattenType(value, name ? `${name}.${key}` : key, true);
|
|
163
|
+
flattenType(value, name ? `${name}.${key}` : key, true, childAncestors);
|
|
144
164
|
}
|
|
145
165
|
break;
|
|
146
166
|
}
|
|
147
167
|
case "union":
|
|
148
168
|
case "intersection":
|
|
149
169
|
case "tuple": {
|
|
150
|
-
for (const item of def.type.items) flattenArray(item, name);
|
|
170
|
+
for (const item of def.type.items) flattenArray(item, name, childAncestors);
|
|
151
171
|
break;
|
|
152
172
|
}
|
|
153
173
|
case "array": {
|
|
154
|
-
flattenArray(def.type.of, name);
|
|
174
|
+
flattenArray(def.type.of, name, childAncestors);
|
|
155
175
|
break;
|
|
156
176
|
}
|
|
157
177
|
default:
|
|
158
178
|
}
|
|
159
179
|
}
|
|
160
|
-
function flattenType(def, prefix = "", inComplexTypeOrArray = false) {
|
|
180
|
+
function flattenType(def, prefix = "", inComplexTypeOrArray = false, ancestors = EMPTY_ANCESTORS) {
|
|
161
181
|
let typeId = def.id;
|
|
162
|
-
if (typeId &&
|
|
182
|
+
if (typeId && ancestors.has(typeId)) {
|
|
163
183
|
addFieldToFlatMap(prefix || "", def);
|
|
164
184
|
if (prefix) options?.onField?.(prefix, def, def.metadata);
|
|
165
185
|
return;
|
|
166
186
|
}
|
|
167
|
-
|
|
187
|
+
let childAncestors = extendAncestors(ancestors, typeId);
|
|
168
188
|
const kind = def.type.kind;
|
|
169
189
|
if (!typeId && def.id) {
|
|
170
190
|
typeId = def.id;
|
|
171
|
-
if (
|
|
191
|
+
if (ancestors.has(typeId)) {
|
|
172
192
|
addFieldToFlatMap(prefix || "", def);
|
|
173
193
|
if (prefix) options?.onField?.(prefix, def, def.metadata);
|
|
174
194
|
return;
|
|
175
195
|
}
|
|
176
|
-
|
|
196
|
+
childAncestors = extendAncestors(ancestors, typeId);
|
|
177
197
|
}
|
|
178
198
|
switch (kind) {
|
|
179
199
|
case "object": {
|
|
180
200
|
addFieldToFlatMap(prefix || "", def);
|
|
181
201
|
for (const [key, value] of def.type.props.entries()) {
|
|
182
202
|
if (skipPhantom && require_json_schema.isPhantomType(value)) continue;
|
|
183
|
-
flattenType(value, prefix ? `${prefix}.${key}` : key, inComplexTypeOrArray);
|
|
203
|
+
flattenType(value, prefix ? `${prefix}.${key}` : key, inComplexTypeOrArray, childAncestors);
|
|
184
204
|
}
|
|
185
205
|
break;
|
|
186
206
|
}
|
|
@@ -192,13 +212,13 @@ else flatUnion.item(existing);
|
|
|
192
212
|
if (options?.topLevelArrayTag) typeArray.metadata.set(options.topLevelArrayTag, true);
|
|
193
213
|
}
|
|
194
214
|
addFieldToFlatMap(prefix || "", typeArray);
|
|
195
|
-
if (!require_json_schema.isAnnotatedTypeOfPrimitive(typeArray.type.of)) flattenArray(typeArray.type.of, prefix);
|
|
215
|
+
if (!require_json_schema.isAnnotatedTypeOfPrimitive(typeArray.type.of)) flattenArray(typeArray.type.of, prefix, childAncestors);
|
|
196
216
|
break;
|
|
197
217
|
}
|
|
198
218
|
case "intersection":
|
|
199
219
|
case "tuple":
|
|
200
220
|
case "union": {
|
|
201
|
-
for (const item of def.type.items) flattenType(item, prefix, true);
|
|
221
|
+
for (const item of def.type.items) flattenType(item, prefix, true, childAncestors);
|
|
202
222
|
addFieldToFlatMap(prefix || "", def);
|
|
203
223
|
if (def.optional) {
|
|
204
224
|
const entry = flatMap.get(prefix || "");
|
package/dist/utils.d.ts
CHANGED
|
@@ -456,23 +456,6 @@ interface TFlattenOptions {
|
|
|
456
456
|
*/
|
|
457
457
|
excludePhantomTypes?: boolean;
|
|
458
458
|
}
|
|
459
|
-
/**
|
|
460
|
-
* Flattens an annotated object type into a map of dot-separated paths to their annotated types.
|
|
461
|
-
*
|
|
462
|
-
* For an object like `{ address: { street: string, city: string } }`, the result contains:
|
|
463
|
-
* - `''` → the root object type
|
|
464
|
-
* - `'address'` → the address object type
|
|
465
|
-
* - `'address.street'` → string type
|
|
466
|
-
* - `'address.city'` → string type
|
|
467
|
-
*
|
|
468
|
-
* Arrays are recursed into (their element types are flattened with the same prefix).
|
|
469
|
-
* Unions/intersections/tuples are recursed into (each branch contributes to the same path,
|
|
470
|
-
* merging via synthetic union types when paths collide).
|
|
471
|
-
*
|
|
472
|
-
* @param type - The root annotated type (must be an object type).
|
|
473
|
-
* @param options - Optional hooks for domain-specific processing.
|
|
474
|
-
* @returns A map of dot-separated field paths to their annotated types.
|
|
475
|
-
*/
|
|
476
459
|
declare function flattenAnnotatedType(type: TAtscriptAnnotatedType<TAtscriptTypeObject>, options?: TFlattenOptions): Map<string, TAtscriptAnnotatedType>;
|
|
477
460
|
|
|
478
461
|
/** Runtime shape of a ref annotation argument (lazy type reference with optional chain). */
|
package/dist/utils.mjs
CHANGED
|
@@ -108,10 +108,32 @@ function throwFeatureDisabled(feature, option, annotation) {
|
|
|
108
108
|
|
|
109
109
|
//#endregion
|
|
110
110
|
//#region packages/typescript/src/runtime/flatten.ts
|
|
111
|
+
/**
|
|
112
|
+
* Flattens an annotated object type into a map of dot-separated paths to their annotated types.
|
|
113
|
+
*
|
|
114
|
+
* For an object like `{ address: { street: string, city: string } }`, the result contains:
|
|
115
|
+
* - `''` → the root object type
|
|
116
|
+
* - `'address'` → the address object type
|
|
117
|
+
* - `'address.street'` → string type
|
|
118
|
+
* - `'address.city'` → string type
|
|
119
|
+
*
|
|
120
|
+
* Arrays are recursed into (their element types are flattened with the same prefix).
|
|
121
|
+
* Unions/intersections/tuples are recursed into (each branch contributes to the same path,
|
|
122
|
+
* merging via synthetic union types when paths collide).
|
|
123
|
+
*
|
|
124
|
+
* @param type - The root annotated type (must be an object type).
|
|
125
|
+
* @param options - Optional hooks for domain-specific processing.
|
|
126
|
+
* @returns A map of dot-separated field paths to their annotated types.
|
|
127
|
+
*/ const EMPTY_ANCESTORS = new Set();
|
|
128
|
+
function extendAncestors(ancestors, id) {
|
|
129
|
+
if (!id || ancestors.has(id)) return ancestors;
|
|
130
|
+
const next = new Set(ancestors);
|
|
131
|
+
next.add(id);
|
|
132
|
+
return next;
|
|
133
|
+
}
|
|
111
134
|
function flattenAnnotatedType(type, options) {
|
|
112
135
|
const flatMap = new Map();
|
|
113
136
|
const skipPhantom = !!options?.excludePhantomTypes;
|
|
114
|
-
const visitedIds = new Set();
|
|
115
137
|
function addFieldToFlatMap(name, def) {
|
|
116
138
|
const existing = flatMap.get(name);
|
|
117
139
|
if (existing) {
|
|
@@ -124,62 +146,60 @@ else flatUnion.item(existing);
|
|
|
124
146
|
flatMap.set(name, flatUnion.$type);
|
|
125
147
|
} else flatMap.set(name, def);
|
|
126
148
|
}
|
|
127
|
-
function flattenArray(def, name) {
|
|
149
|
+
function flattenArray(def, name, ancestors) {
|
|
128
150
|
const resolvedId = def.id;
|
|
129
|
-
if (resolvedId)
|
|
130
|
-
|
|
131
|
-
visitedIds.add(resolvedId);
|
|
132
|
-
}
|
|
151
|
+
if (resolvedId && ancestors.has(resolvedId)) return;
|
|
152
|
+
let childAncestors = extendAncestors(ancestors, resolvedId);
|
|
133
153
|
switch (def.type.kind) {
|
|
134
154
|
case "object": {
|
|
135
155
|
if (!resolvedId && def.id) {
|
|
136
|
-
if (
|
|
137
|
-
|
|
156
|
+
if (ancestors.has(def.id)) return;
|
|
157
|
+
childAncestors = extendAncestors(ancestors, def.id);
|
|
138
158
|
}
|
|
139
159
|
const items = Array.from(def.type.props.entries());
|
|
140
160
|
for (const [key, value] of items) {
|
|
141
161
|
if (skipPhantom && isPhantomType(value)) continue;
|
|
142
|
-
flattenType(value, name ? `${name}.${key}` : key, true);
|
|
162
|
+
flattenType(value, name ? `${name}.${key}` : key, true, childAncestors);
|
|
143
163
|
}
|
|
144
164
|
break;
|
|
145
165
|
}
|
|
146
166
|
case "union":
|
|
147
167
|
case "intersection":
|
|
148
168
|
case "tuple": {
|
|
149
|
-
for (const item of def.type.items) flattenArray(item, name);
|
|
169
|
+
for (const item of def.type.items) flattenArray(item, name, childAncestors);
|
|
150
170
|
break;
|
|
151
171
|
}
|
|
152
172
|
case "array": {
|
|
153
|
-
flattenArray(def.type.of, name);
|
|
173
|
+
flattenArray(def.type.of, name, childAncestors);
|
|
154
174
|
break;
|
|
155
175
|
}
|
|
156
176
|
default:
|
|
157
177
|
}
|
|
158
178
|
}
|
|
159
|
-
function flattenType(def, prefix = "", inComplexTypeOrArray = false) {
|
|
179
|
+
function flattenType(def, prefix = "", inComplexTypeOrArray = false, ancestors = EMPTY_ANCESTORS) {
|
|
160
180
|
let typeId = def.id;
|
|
161
|
-
if (typeId &&
|
|
181
|
+
if (typeId && ancestors.has(typeId)) {
|
|
162
182
|
addFieldToFlatMap(prefix || "", def);
|
|
163
183
|
if (prefix) options?.onField?.(prefix, def, def.metadata);
|
|
164
184
|
return;
|
|
165
185
|
}
|
|
166
|
-
|
|
186
|
+
let childAncestors = extendAncestors(ancestors, typeId);
|
|
167
187
|
const kind = def.type.kind;
|
|
168
188
|
if (!typeId && def.id) {
|
|
169
189
|
typeId = def.id;
|
|
170
|
-
if (
|
|
190
|
+
if (ancestors.has(typeId)) {
|
|
171
191
|
addFieldToFlatMap(prefix || "", def);
|
|
172
192
|
if (prefix) options?.onField?.(prefix, def, def.metadata);
|
|
173
193
|
return;
|
|
174
194
|
}
|
|
175
|
-
|
|
195
|
+
childAncestors = extendAncestors(ancestors, typeId);
|
|
176
196
|
}
|
|
177
197
|
switch (kind) {
|
|
178
198
|
case "object": {
|
|
179
199
|
addFieldToFlatMap(prefix || "", def);
|
|
180
200
|
for (const [key, value] of def.type.props.entries()) {
|
|
181
201
|
if (skipPhantom && isPhantomType(value)) continue;
|
|
182
|
-
flattenType(value, prefix ? `${prefix}.${key}` : key, inComplexTypeOrArray);
|
|
202
|
+
flattenType(value, prefix ? `${prefix}.${key}` : key, inComplexTypeOrArray, childAncestors);
|
|
183
203
|
}
|
|
184
204
|
break;
|
|
185
205
|
}
|
|
@@ -191,13 +211,13 @@ else flatUnion.item(existing);
|
|
|
191
211
|
if (options?.topLevelArrayTag) typeArray.metadata.set(options.topLevelArrayTag, true);
|
|
192
212
|
}
|
|
193
213
|
addFieldToFlatMap(prefix || "", typeArray);
|
|
194
|
-
if (!isAnnotatedTypeOfPrimitive(typeArray.type.of)) flattenArray(typeArray.type.of, prefix);
|
|
214
|
+
if (!isAnnotatedTypeOfPrimitive(typeArray.type.of)) flattenArray(typeArray.type.of, prefix, childAncestors);
|
|
195
215
|
break;
|
|
196
216
|
}
|
|
197
217
|
case "intersection":
|
|
198
218
|
case "tuple":
|
|
199
219
|
case "union": {
|
|
200
|
-
for (const item of def.type.items) flattenType(item, prefix, true);
|
|
220
|
+
for (const item of def.type.items) flattenType(item, prefix, true, childAncestors);
|
|
201
221
|
addFieldToFlatMap(prefix || "", def);
|
|
202
222
|
if (def.optional) {
|
|
203
223
|
const entry = flatMap.get(prefix || "");
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@atscript/typescript",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.60",
|
|
4
4
|
"description": "Atscript: typescript-gen support.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"annotations",
|
|
@@ -63,8 +63,8 @@
|
|
|
63
63
|
"./package.json": "./package.json"
|
|
64
64
|
},
|
|
65
65
|
"dependencies": {
|
|
66
|
-
"@moostjs/event-cli": "^0.6.
|
|
67
|
-
"moost": "^0.6.
|
|
66
|
+
"@moostjs/event-cli": "^0.6.15",
|
|
67
|
+
"moost": "^0.6.15"
|
|
68
68
|
},
|
|
69
69
|
"devDependencies": {
|
|
70
70
|
"@atscript/db": "^0.1.74",
|
|
@@ -73,7 +73,7 @@
|
|
|
73
73
|
},
|
|
74
74
|
"peerDependencies": {
|
|
75
75
|
"@atscript/db": "^0.1.74",
|
|
76
|
-
"@atscript/core": "^0.1.
|
|
76
|
+
"@atscript/core": "^0.1.60"
|
|
77
77
|
},
|
|
78
78
|
"peerDependenciesMeta": {
|
|
79
79
|
"@atscript/db": {
|