@atscript/typescript 0.1.32 → 0.1.33
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/cli.cjs +99 -59
- package/dist/index.cjs +99 -59
- package/dist/index.mjs +99 -59
- package/dist/utils.cjs +67 -88
- package/dist/utils.d.ts +9 -2
- package/dist/utils.mjs +67 -89
- package/package.json +2 -2
package/dist/utils.mjs
CHANGED
|
@@ -435,6 +435,25 @@ var ValidatorError = class extends Error {
|
|
|
435
435
|
|
|
436
436
|
//#endregion
|
|
437
437
|
//#region packages/typescript/src/annotated-type.ts
|
|
438
|
+
const COMPLEX_KINDS = new Set([
|
|
439
|
+
"union",
|
|
440
|
+
"intersection",
|
|
441
|
+
"tuple"
|
|
442
|
+
]);
|
|
443
|
+
const NON_PRIMITIVE_KINDS = new Set(["array", "object"]);
|
|
444
|
+
/** Shared validator method reused by all annotated type nodes. */ function validatorMethod(opts) {
|
|
445
|
+
return new Validator(this, opts);
|
|
446
|
+
}
|
|
447
|
+
function createAnnotatedTypeNode(type, metadata, opts) {
|
|
448
|
+
return {
|
|
449
|
+
__is_atscript_annotated_type: true,
|
|
450
|
+
type,
|
|
451
|
+
metadata,
|
|
452
|
+
validator: validatorMethod,
|
|
453
|
+
id: opts?.id,
|
|
454
|
+
optional: opts?.optional
|
|
455
|
+
};
|
|
456
|
+
}
|
|
438
457
|
function isAnnotatedType(type) {
|
|
439
458
|
return type && type.__is_atscript_annotated_type;
|
|
440
459
|
}
|
|
@@ -453,32 +472,22 @@ function cloneRefProp(parentType, propName) {
|
|
|
453
472
|
const existing = objType.props.get(propName);
|
|
454
473
|
if (!existing) return;
|
|
455
474
|
const clonedType = cloneTypeDef(existing.type);
|
|
456
|
-
objType.props.set(propName, {
|
|
457
|
-
__is_atscript_annotated_type: true,
|
|
458
|
-
type: clonedType,
|
|
459
|
-
metadata: new Map(existing.metadata),
|
|
475
|
+
objType.props.set(propName, createAnnotatedTypeNode(clonedType, new Map(existing.metadata), {
|
|
460
476
|
id: existing.id,
|
|
461
|
-
optional: existing.optional
|
|
462
|
-
|
|
463
|
-
return new Validator(this, opts);
|
|
464
|
-
}
|
|
465
|
-
});
|
|
477
|
+
optional: existing.optional
|
|
478
|
+
}));
|
|
466
479
|
}
|
|
467
480
|
function cloneTypeDef(type) {
|
|
468
481
|
if (type.kind === "object") {
|
|
469
482
|
const obj = type;
|
|
483
|
+
const props = new Map();
|
|
484
|
+
for (const [k, v] of obj.props) props.set(k, createAnnotatedTypeNode(v.type, new Map(v.metadata), {
|
|
485
|
+
id: v.id,
|
|
486
|
+
optional: v.optional
|
|
487
|
+
}));
|
|
470
488
|
return {
|
|
471
489
|
kind: "object",
|
|
472
|
-
props
|
|
473
|
-
__is_atscript_annotated_type: true,
|
|
474
|
-
type: v.type,
|
|
475
|
-
metadata: new Map(v.metadata),
|
|
476
|
-
id: v.id,
|
|
477
|
-
optional: v.optional,
|
|
478
|
-
validator(opts) {
|
|
479
|
-
return new Validator(this, opts);
|
|
480
|
-
}
|
|
481
|
-
}])),
|
|
490
|
+
props,
|
|
482
491
|
propsPatterns: [...obj.propsPatterns],
|
|
483
492
|
tags: new Set(obj.tags)
|
|
484
493
|
};
|
|
@@ -508,38 +517,24 @@ function defineAnnotatedType(_kind, base) {
|
|
|
508
517
|
const kind = _kind || "";
|
|
509
518
|
const type = base?.type || {};
|
|
510
519
|
type.kind = kind;
|
|
511
|
-
if ([
|
|
512
|
-
"union",
|
|
513
|
-
"intersection",
|
|
514
|
-
"tuple"
|
|
515
|
-
].includes(kind)) type.items = [];
|
|
520
|
+
if (COMPLEX_KINDS.has(kind)) type.items = [];
|
|
516
521
|
if (kind === "object") {
|
|
517
522
|
type.props = new Map();
|
|
518
523
|
type.propsPatterns = [];
|
|
519
524
|
}
|
|
520
525
|
type.tags = new Set();
|
|
521
526
|
const metadata = base?.metadata || new Map();
|
|
522
|
-
|
|
523
|
-
__is_atscript_annotated_type: true,
|
|
524
|
-
metadata,
|
|
525
|
-
type,
|
|
526
|
-
validator(opts) {
|
|
527
|
-
return new Validator(this, opts);
|
|
528
|
-
}
|
|
529
|
-
});
|
|
530
|
-
else base = {
|
|
527
|
+
const payload = {
|
|
531
528
|
__is_atscript_annotated_type: true,
|
|
532
529
|
metadata,
|
|
533
530
|
type,
|
|
534
|
-
validator
|
|
535
|
-
return new Validator(this, opts);
|
|
536
|
-
}
|
|
531
|
+
validator: validatorMethod
|
|
537
532
|
};
|
|
533
|
+
base = base ? Object.assign(base, payload) : payload;
|
|
538
534
|
const handle = {
|
|
539
535
|
$type: base,
|
|
540
536
|
$def: type,
|
|
541
537
|
$metadata: metadata,
|
|
542
|
-
_existingObject: undefined,
|
|
543
538
|
tags(...tags) {
|
|
544
539
|
for (const tag of tags) this.$def.tags.add(tag);
|
|
545
540
|
return this;
|
|
@@ -580,27 +575,18 @@ else base = {
|
|
|
580
575
|
return this;
|
|
581
576
|
},
|
|
582
577
|
refTo(type$1, chain) {
|
|
578
|
+
if (!isAnnotatedType(type$1)) throw new Error(`${type$1} is not annotated type`);
|
|
583
579
|
let newBase = type$1;
|
|
584
580
|
const typeName = type$1.name || "Unknown";
|
|
585
|
-
if (
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
581
|
+
if (chain) for (let i = 0; i < chain.length; i++) {
|
|
582
|
+
const c = chain[i];
|
|
583
|
+
if (newBase.type.kind === "object" && newBase.type.props.has(c)) newBase = newBase.type.props.get(c);
|
|
584
|
+
else {
|
|
585
|
+
const keys = chain.slice(0, i + 1).map((k) => `["${k}"]`).join("");
|
|
586
|
+
throw new Error(`Can't find prop ${typeName}${keys}`);
|
|
591
587
|
}
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
this.$type = {
|
|
595
|
-
__is_atscript_annotated_type: true,
|
|
596
|
-
type: newBase.type,
|
|
597
|
-
metadata,
|
|
598
|
-
id: newBase.id,
|
|
599
|
-
validator(opts) {
|
|
600
|
-
return new Validator(this, opts);
|
|
601
|
-
}
|
|
602
|
-
};
|
|
603
|
-
} else throw new Error(`${type$1} is not annotated type`);
|
|
588
|
+
}
|
|
589
|
+
this.$type = createAnnotatedTypeNode(newBase.type, metadata, { id: newBase.id });
|
|
604
590
|
return this;
|
|
605
591
|
},
|
|
606
592
|
annotate(key, value, asArray) {
|
|
@@ -618,13 +604,9 @@ function isPhantomType(def) {
|
|
|
618
604
|
return def.type.kind === "" && def.type.designType === "phantom";
|
|
619
605
|
}
|
|
620
606
|
function isAnnotatedTypeOfPrimitive(t) {
|
|
621
|
-
if (
|
|
607
|
+
if (NON_PRIMITIVE_KINDS.has(t.type.kind)) return false;
|
|
622
608
|
if (!t.type.kind) return true;
|
|
623
|
-
if (
|
|
624
|
-
"union",
|
|
625
|
-
"tuple",
|
|
626
|
-
"intersection"
|
|
627
|
-
].includes(t.type.kind)) {
|
|
609
|
+
if (COMPLEX_KINDS.has(t.type.kind)) {
|
|
628
610
|
for (const item of t.type.items) if (!isAnnotatedTypeOfPrimitive(item)) return false;
|
|
629
611
|
return true;
|
|
630
612
|
}
|
|
@@ -663,10 +645,10 @@ function forAnnotatedType(def, handlers) {
|
|
|
663
645
|
const firstObj = items[0].type;
|
|
664
646
|
const candidates = [];
|
|
665
647
|
for (const [propName, propType] of firstObj.props.entries()) if (propType.type.kind === "" && propType.type.value !== undefined) candidates.push(propName);
|
|
666
|
-
|
|
648
|
+
let result = null;
|
|
667
649
|
for (const candidate of candidates) {
|
|
668
650
|
const values = new Set();
|
|
669
|
-
const
|
|
651
|
+
const indexMapping = {};
|
|
670
652
|
let valid = true;
|
|
671
653
|
for (let i = 0; i < items.length; i++) {
|
|
672
654
|
const obj = items[i].type;
|
|
@@ -681,19 +663,21 @@ function forAnnotatedType(def, handlers) {
|
|
|
681
663
|
break;
|
|
682
664
|
}
|
|
683
665
|
values.add(val);
|
|
684
|
-
|
|
666
|
+
indexMapping[String(val)] = i;
|
|
667
|
+
}
|
|
668
|
+
if (valid) {
|
|
669
|
+
if (result) return null;
|
|
670
|
+
result = {
|
|
671
|
+
propertyName: candidate,
|
|
672
|
+
indexMapping
|
|
673
|
+
};
|
|
685
674
|
}
|
|
686
|
-
if (valid) validCandidates.push({
|
|
687
|
-
propertyName: candidate,
|
|
688
|
-
mapping
|
|
689
|
-
});
|
|
690
675
|
}
|
|
691
|
-
|
|
692
|
-
return null;
|
|
676
|
+
return result;
|
|
693
677
|
}
|
|
694
678
|
function buildJsonSchema(type) {
|
|
695
679
|
const defs = {};
|
|
696
|
-
let
|
|
680
|
+
let hasDefs = false;
|
|
697
681
|
const buildObject = (d) => {
|
|
698
682
|
const properties = {};
|
|
699
683
|
const required = [];
|
|
@@ -710,15 +694,15 @@ function buildJsonSchema(type) {
|
|
|
710
694
|
return schema$1;
|
|
711
695
|
};
|
|
712
696
|
const build$1 = (def) => {
|
|
713
|
-
if (def.id && def.type.kind === "object" &&
|
|
697
|
+
if (def.id && def.type.kind === "object" && def !== type) {
|
|
714
698
|
const name = def.id;
|
|
715
699
|
if (!defs[name]) {
|
|
700
|
+
hasDefs = true;
|
|
716
701
|
defs[name] = {};
|
|
717
702
|
defs[name] = buildObject(def);
|
|
718
703
|
}
|
|
719
704
|
return { $ref: `#/$defs/${name}` };
|
|
720
705
|
}
|
|
721
|
-
isRoot = false;
|
|
722
706
|
const meta = def.metadata;
|
|
723
707
|
return forAnnotatedType(def, {
|
|
724
708
|
phantom() {
|
|
@@ -743,11 +727,9 @@ function buildJsonSchema(type) {
|
|
|
743
727
|
if (disc) {
|
|
744
728
|
const oneOf = d.type.items.map(build$1);
|
|
745
729
|
const mapping = {};
|
|
746
|
-
for (const [val,
|
|
747
|
-
const idx = Number.parseInt(origPath.split("/").pop(), 10);
|
|
730
|
+
for (const [val, idx] of Object.entries(disc.indexMapping)) {
|
|
748
731
|
const item = d.type.items[idx];
|
|
749
|
-
|
|
750
|
-
else mapping[val] = origPath;
|
|
732
|
+
mapping[val] = item.id && defs[item.id] ? `#/$defs/${item.id}` : `#/oneOf/${idx}`;
|
|
751
733
|
}
|
|
752
734
|
return {
|
|
753
735
|
oneOf,
|
|
@@ -797,7 +779,7 @@ else schema$1.allOf = (schema$1.allOf || []).concat(patterns.map((p) => ({ patte
|
|
|
797
779
|
});
|
|
798
780
|
};
|
|
799
781
|
const schema = build$1(type);
|
|
800
|
-
if (
|
|
782
|
+
if (hasDefs) return {
|
|
801
783
|
...schema,
|
|
802
784
|
$defs: defs
|
|
803
785
|
};
|
|
@@ -812,6 +794,8 @@ function fromJsonSchema(schema) {
|
|
|
812
794
|
const refName = s.$ref.replace(/^#\/(\$defs|definitions)\//, "");
|
|
813
795
|
if (resolved.has(refName)) return resolved.get(refName);
|
|
814
796
|
if (defsSource[refName]) {
|
|
797
|
+
const placeholder = defineAnnotatedType().designType("any").$type;
|
|
798
|
+
resolved.set(refName, placeholder);
|
|
815
799
|
const type = convert(defsSource[refName]);
|
|
816
800
|
resolved.set(refName, type);
|
|
817
801
|
return type;
|
|
@@ -1222,16 +1206,10 @@ function deserializeAnnotatedType(data) {
|
|
|
1222
1206
|
function deserializeNode(data) {
|
|
1223
1207
|
const metadata = new Map(Object.entries(data.metadata));
|
|
1224
1208
|
const type = deserializeTypeDef(data.type);
|
|
1225
|
-
const result = {
|
|
1226
|
-
|
|
1227
|
-
|
|
1228
|
-
|
|
1229
|
-
validator(opts) {
|
|
1230
|
-
return new Validator(this, opts);
|
|
1231
|
-
}
|
|
1232
|
-
};
|
|
1233
|
-
if (data.optional) result.optional = true;
|
|
1234
|
-
if (data.id) result.id = data.id;
|
|
1209
|
+
const result = createAnnotatedTypeNode(type, metadata, {
|
|
1210
|
+
optional: data.optional || undefined,
|
|
1211
|
+
id: data.id || undefined
|
|
1212
|
+
});
|
|
1235
1213
|
return result;
|
|
1236
1214
|
}
|
|
1237
1215
|
function deserializeTypeDef(t) {
|
|
@@ -1277,4 +1255,4 @@ function deserializeTypeDef(t) {
|
|
|
1277
1255
|
}
|
|
1278
1256
|
|
|
1279
1257
|
//#endregion
|
|
1280
|
-
export { SERIALIZE_VERSION, Validator, ValidatorError, annotate, buildJsonSchema, cloneRefProp, createDataFromAnnotatedType, defineAnnotatedType, deserializeAnnotatedType, flattenAnnotatedType, forAnnotatedType, fromJsonSchema, isAnnotatedType, isAnnotatedTypeOfPrimitive, isPhantomType, mergeJsonSchemas, serializeAnnotatedType, throwFeatureDisabled };
|
|
1258
|
+
export { SERIALIZE_VERSION, Validator, ValidatorError, annotate, buildJsonSchema, cloneRefProp, createAnnotatedTypeNode, createDataFromAnnotatedType, defineAnnotatedType, deserializeAnnotatedType, flattenAnnotatedType, forAnnotatedType, fromJsonSchema, isAnnotatedType, isAnnotatedTypeOfPrimitive, isPhantomType, mergeJsonSchemas, serializeAnnotatedType, throwFeatureDisabled };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@atscript/typescript",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.33",
|
|
4
4
|
"description": "Atscript: typescript-gen support.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"annotations",
|
|
@@ -64,7 +64,7 @@
|
|
|
64
64
|
"vitest": "3.2.4"
|
|
65
65
|
},
|
|
66
66
|
"peerDependencies": {
|
|
67
|
-
"@atscript/core": "^0.1.
|
|
67
|
+
"@atscript/core": "^0.1.33"
|
|
68
68
|
},
|
|
69
69
|
"build": [
|
|
70
70
|
{},
|