@ankhorage/devtools 1.19.9 → 1.19.10
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/README.md
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
|
|
4
4
|
# @ankhorage/devtools
|
|
5
5
|
|
|
6
|
-
         
|
|
7
7
|
|
|
8
8
|
Shared tooling, repository automation, runtime policies, and agent standards for Ankhorage TypeScript projects
|
|
9
9
|
|
|
@@ -37,7 +37,7 @@ function ensureStructureDefinition(symbol, type, context) {
|
|
|
37
37
|
}
|
|
38
38
|
/*** Resolve primitives, literals, arrays, unions, and fixed object shapes. */
|
|
39
39
|
function resolveTypeBody(type, context) {
|
|
40
|
-
const primitive = resolvePrimitive(type);
|
|
40
|
+
const primitive = resolvePrimitive(type, context.checker);
|
|
41
41
|
if (primitive)
|
|
42
42
|
return primitive;
|
|
43
43
|
const literal = resolveLiteral(type, context.checker);
|
|
@@ -54,9 +54,11 @@ function resolveTypeBody(type, context) {
|
|
|
54
54
|
throw unsupportedType(type, context, 'unsupported TypeScript type');
|
|
55
55
|
}
|
|
56
56
|
/*** Resolve JSON-safe scalar primitives. */
|
|
57
|
-
function resolvePrimitive(type) {
|
|
57
|
+
function resolvePrimitive(type, checker) {
|
|
58
58
|
if ((type.flags & ts.TypeFlags.String) !== 0)
|
|
59
59
|
return { kind: 'scalar', type: 'string' };
|
|
60
|
+
if (isOpenStringIntersection(type, checker))
|
|
61
|
+
return { kind: 'scalar', type: 'string' };
|
|
60
62
|
if ((type.flags & ts.TypeFlags.Number) !== 0)
|
|
61
63
|
return { kind: 'scalar', type: 'number' };
|
|
62
64
|
if ((type.flags & ts.TypeFlags.Boolean) !== 0)
|
|
@@ -65,6 +67,26 @@ function resolvePrimitive(type) {
|
|
|
65
67
|
return { kind: 'scalar', type: 'null' };
|
|
66
68
|
return null;
|
|
67
69
|
}
|
|
70
|
+
/*** Recognize TypeScript's autocomplete-friendly `string & {}` pattern as scalar string semantics. */
|
|
71
|
+
function isOpenStringIntersection(type, checker) {
|
|
72
|
+
if (!type.isIntersection())
|
|
73
|
+
return false;
|
|
74
|
+
const stringMembers = type.types.filter((member) => (member.flags & ts.TypeFlags.String) !== 0);
|
|
75
|
+
if (stringMembers.length !== 1)
|
|
76
|
+
return false;
|
|
77
|
+
const objectMembers = type.types.filter((member) => (member.flags & ts.TypeFlags.String) === 0);
|
|
78
|
+
const allEmptyObjects = objectMembers.every((member) => isEmptyObjectType(member, checker));
|
|
79
|
+
return objectMembers.length > 0 && allEmptyObjects;
|
|
80
|
+
}
|
|
81
|
+
/*** Accept only structurally empty object members when recognizing an open-string intersection. */
|
|
82
|
+
function isEmptyObjectType(type, checker) {
|
|
83
|
+
return ((type.flags & ts.TypeFlags.Object) !== 0 &&
|
|
84
|
+
type.getProperties().length === 0 &&
|
|
85
|
+
type.getCallSignatures().length === 0 &&
|
|
86
|
+
type.getConstructSignatures().length === 0 &&
|
|
87
|
+
checker.getIndexTypeOfType(type, ts.IndexKind.String) === undefined &&
|
|
88
|
+
checker.getIndexTypeOfType(type, ts.IndexKind.Number) === undefined);
|
|
89
|
+
}
|
|
68
90
|
/*** Resolve one scalar literal while leaving non-literal types untouched. */
|
|
69
91
|
function resolveLiteral(type, checker) {
|
|
70
92
|
if (type.isStringLiteral())
|
|
@@ -89,6 +111,10 @@ function resolveUnion(type, context) {
|
|
|
89
111
|
if (literals.every(isDefinedLiteral)) {
|
|
90
112
|
return { kind: 'enum', values: sortLiterals(literals) };
|
|
91
113
|
}
|
|
114
|
+
if (effective.some((entry) => isOpenStringIntersection(entry, context.checker)) &&
|
|
115
|
+
effective.every((entry) => entry.isStringLiteral() || isOpenStringIntersection(entry, context.checker))) {
|
|
116
|
+
return { kind: 'scalar', type: 'string' };
|
|
117
|
+
}
|
|
92
118
|
const variants = effective.map((entry) => resolveStructureType(entry, context));
|
|
93
119
|
variants.sort((left, right) => JSON.stringify(left).localeCompare(JSON.stringify(right)));
|
|
94
120
|
const discriminator = resolveUnionDiscriminator(effective, context.checker);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ankhorage/devtools",
|
|
3
|
-
"version": "1.19.
|
|
3
|
+
"version": "1.19.10",
|
|
4
4
|
"description": "Shared tooling, repository automation, runtime policies, and agent standards for Ankhorage TypeScript projects",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"homepage": "https://github.com/ankhorage/devtools#readme",
|