@player-tools/xlr-utils 0.0.2-next.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/README.md +3 -0
- package/dist/index.cjs.js +526 -0
- package/dist/index.d.ts +126 -0
- package/dist/index.esm.js +477 -0
- package/package.json +35 -0
- package/src/annotations.ts +230 -0
- package/src/index.ts +5 -0
- package/src/test-helpers.ts +72 -0
- package/src/ts-helpers.ts +356 -0
- package/src/type-checks.ts +106 -0
- package/src/validation-helpers.ts +88 -0
package/README.md
ADDED
|
@@ -0,0 +1,526 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, '__esModule', { value: true });
|
|
4
|
+
|
|
5
|
+
var ts = require('typescript');
|
|
6
|
+
|
|
7
|
+
function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
|
|
8
|
+
|
|
9
|
+
function _interopNamespace(e) {
|
|
10
|
+
if (e && e.__esModule) return e;
|
|
11
|
+
var n = Object.create(null);
|
|
12
|
+
if (e) {
|
|
13
|
+
Object.keys(e).forEach(function (k) {
|
|
14
|
+
if (k !== 'default') {
|
|
15
|
+
var d = Object.getOwnPropertyDescriptor(e, k);
|
|
16
|
+
Object.defineProperty(n, k, d.get ? d : {
|
|
17
|
+
enumerable: true,
|
|
18
|
+
get: function () { return e[k]; }
|
|
19
|
+
});
|
|
20
|
+
}
|
|
21
|
+
});
|
|
22
|
+
}
|
|
23
|
+
n["default"] = e;
|
|
24
|
+
return Object.freeze(n);
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
var ts__namespace = /*#__PURE__*/_interopNamespace(ts);
|
|
28
|
+
var ts__default = /*#__PURE__*/_interopDefaultLegacy(ts);
|
|
29
|
+
|
|
30
|
+
var __defProp$1 = Object.defineProperty;
|
|
31
|
+
var __getOwnPropSymbols$1 = Object.getOwnPropertySymbols;
|
|
32
|
+
var __hasOwnProp$1 = Object.prototype.hasOwnProperty;
|
|
33
|
+
var __propIsEnum$1 = Object.prototype.propertyIsEnumerable;
|
|
34
|
+
var __defNormalProp$1 = (obj, key, value) => key in obj ? __defProp$1(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
35
|
+
var __spreadValues$1 = (a, b) => {
|
|
36
|
+
for (var prop in b || (b = {}))
|
|
37
|
+
if (__hasOwnProp$1.call(b, prop))
|
|
38
|
+
__defNormalProp$1(a, prop, b[prop]);
|
|
39
|
+
if (__getOwnPropSymbols$1)
|
|
40
|
+
for (var prop of __getOwnPropSymbols$1(b)) {
|
|
41
|
+
if (__propIsEnum$1.call(b, prop))
|
|
42
|
+
__defNormalProp$1(a, prop, b[prop]);
|
|
43
|
+
}
|
|
44
|
+
return a;
|
|
45
|
+
};
|
|
46
|
+
function extractDescription(text) {
|
|
47
|
+
if (!text) {
|
|
48
|
+
return {};
|
|
49
|
+
}
|
|
50
|
+
return { description: text };
|
|
51
|
+
}
|
|
52
|
+
function parentIsNonObjectPath(node) {
|
|
53
|
+
return node.parent && (ts__namespace.isArrayTypeNode(node.parent) || ts__namespace.isTupleTypeNode(node.parent) || ts__namespace.isOptionalTypeNode(node.parent) || ts__namespace.isRestTypeNode(node.parent) || ts__namespace.isUnionTypeNode(node.parent));
|
|
54
|
+
}
|
|
55
|
+
function recurseTypeChain(node, child) {
|
|
56
|
+
if (!node) {
|
|
57
|
+
return [];
|
|
58
|
+
}
|
|
59
|
+
if (ts__namespace.isArrayTypeNode(node) && node.parent && ts__namespace.isRestTypeNode(node.parent)) {
|
|
60
|
+
return recurseTypeChain(node.parent, node);
|
|
61
|
+
}
|
|
62
|
+
if (ts__namespace.isRestTypeNode(node)) {
|
|
63
|
+
return recurseTypeChain(node.parent, node);
|
|
64
|
+
}
|
|
65
|
+
if (ts__namespace.isOptionalTypeNode(node)) {
|
|
66
|
+
return recurseTypeChain(node.parent, node);
|
|
67
|
+
}
|
|
68
|
+
if (ts__namespace.isUnionTypeNode(node)) {
|
|
69
|
+
return recurseTypeChain(node.parent, node);
|
|
70
|
+
}
|
|
71
|
+
if (ts__namespace.isParenthesizedTypeNode(node)) {
|
|
72
|
+
return recurseTypeChain(node.parent, node);
|
|
73
|
+
}
|
|
74
|
+
if (ts__namespace.isTypeLiteralNode(node)) {
|
|
75
|
+
return recurseTypeChain(node.parent, node);
|
|
76
|
+
}
|
|
77
|
+
if (ts__namespace.isArrayTypeNode(node)) {
|
|
78
|
+
return ["[]", ...recurseTypeChain(node.parent, node)];
|
|
79
|
+
}
|
|
80
|
+
if (ts__namespace.isTupleTypeNode(node)) {
|
|
81
|
+
const pos = node.elements.indexOf(child);
|
|
82
|
+
return [
|
|
83
|
+
...pos === -1 ? [] : [`${pos}`],
|
|
84
|
+
...recurseTypeChain(node.parent, node)
|
|
85
|
+
];
|
|
86
|
+
}
|
|
87
|
+
if (ts__namespace.isTypeAliasDeclaration(node) || ts__namespace.isInterfaceDeclaration(node) || ts__namespace.isPropertySignature(node)) {
|
|
88
|
+
return [node.name.getText(), ...recurseTypeChain(node.parent, node)];
|
|
89
|
+
}
|
|
90
|
+
if (parentIsNonObjectPath(node)) {
|
|
91
|
+
return recurseTypeChain(node.parent, node);
|
|
92
|
+
}
|
|
93
|
+
return [];
|
|
94
|
+
}
|
|
95
|
+
function extractTitle(node) {
|
|
96
|
+
const typeNames = recurseTypeChain(node, void 0).reverse().join(".");
|
|
97
|
+
if (!typeNames.length) {
|
|
98
|
+
return {};
|
|
99
|
+
}
|
|
100
|
+
return { title: typeNames };
|
|
101
|
+
}
|
|
102
|
+
function stringifyDoc(docString) {
|
|
103
|
+
if (typeof docString === "undefined" || typeof docString === "string") {
|
|
104
|
+
return docString;
|
|
105
|
+
}
|
|
106
|
+
return docString.map(({ text }) => text).join(" ");
|
|
107
|
+
}
|
|
108
|
+
function extractTags(tags) {
|
|
109
|
+
const descriptions = [];
|
|
110
|
+
const examples = [];
|
|
111
|
+
const _default = [];
|
|
112
|
+
const see = [];
|
|
113
|
+
const extractSee = (tag) => {
|
|
114
|
+
var _a, _b, _c;
|
|
115
|
+
return `${tag.tagName ? `${(_a = tag.tagName) == null ? void 0 : _a.getText()} ` : ""}${(_c = (_b = stringifyDoc(tag.comment)) == null ? void 0 : _b.trim()) != null ? _c : ""}`;
|
|
116
|
+
};
|
|
117
|
+
tags.forEach((tag) => {
|
|
118
|
+
var _a, _b, _c, _d, _e, _f;
|
|
119
|
+
if (!tag.comment) {
|
|
120
|
+
return;
|
|
121
|
+
}
|
|
122
|
+
if (tag.tagName.text === "example") {
|
|
123
|
+
examples.push((_b = (_a = stringifyDoc(tag.comment)) == null ? void 0 : _a.trim()) != null ? _b : "");
|
|
124
|
+
} else if (tag.tagName.text === "default") {
|
|
125
|
+
_default.push((_d = (_c = stringifyDoc(tag.comment)) == null ? void 0 : _c.trim()) != null ? _d : "");
|
|
126
|
+
} else if (tag.tagName.text === "see") {
|
|
127
|
+
see.push(extractSee(tag));
|
|
128
|
+
} else {
|
|
129
|
+
const text = (_f = (_e = stringifyDoc(tag.comment)) == null ? void 0 : _e.trim()) != null ? _f : "";
|
|
130
|
+
descriptions.push(`@${tag.tagName.text} ${text}`);
|
|
131
|
+
}
|
|
132
|
+
});
|
|
133
|
+
return __spreadValues$1(__spreadValues$1(__spreadValues$1(__spreadValues$1({}, descriptions.length === 0 ? {} : { description: descriptions.join("\n") }), examples.length === 0 ? {} : { examples }), _default.length === 0 ? {} : { default: _default.join("\n") }), see.length === 0 ? {} : { see });
|
|
134
|
+
}
|
|
135
|
+
function join(t, separator = "\n") {
|
|
136
|
+
const unique = new Set(t).values();
|
|
137
|
+
return Array.from(unique).filter((s) => s !== void 0).join(separator).trim();
|
|
138
|
+
}
|
|
139
|
+
function mergeAnnotations(nodes) {
|
|
140
|
+
var _a;
|
|
141
|
+
const name = (_a = nodes.find((n) => n.name)) == null ? void 0 : _a.name;
|
|
142
|
+
const title = join(nodes.map((n) => n.title), ", ");
|
|
143
|
+
const description = join(nodes.map((n) => n.description));
|
|
144
|
+
const _default = join(nodes.map((n) => n.default));
|
|
145
|
+
const comment = join(nodes.map((n) => n.comment));
|
|
146
|
+
const examples = join(nodes.map((n) => Array.isArray(n.examples) ? join(n.examples) : n.examples));
|
|
147
|
+
const see = join(nodes.map((n) => Array.isArray(n.see) ? join(n.see) : n.see));
|
|
148
|
+
return __spreadValues$1(__spreadValues$1(__spreadValues$1(__spreadValues$1(__spreadValues$1(__spreadValues$1(__spreadValues$1({}, name ? { name } : {}), title ? { title } : {}), description ? { description } : {}), examples ? { examples } : {}), _default ? { default: _default } : {}), see ? { see } : {}), comment ? { comment } : {});
|
|
149
|
+
}
|
|
150
|
+
function decorateNode(node) {
|
|
151
|
+
var _a;
|
|
152
|
+
const { jsDoc } = node;
|
|
153
|
+
const titleAnnotation = extractTitle(node);
|
|
154
|
+
if (jsDoc && jsDoc.length) {
|
|
155
|
+
const first = jsDoc[0];
|
|
156
|
+
return mergeAnnotations([
|
|
157
|
+
extractDescription(stringifyDoc(first.comment)),
|
|
158
|
+
titleAnnotation,
|
|
159
|
+
extractTags((_a = first.tags) != null ? _a : [])
|
|
160
|
+
]);
|
|
161
|
+
}
|
|
162
|
+
return titleAnnotation;
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
function isOptionalProperty(node) {
|
|
166
|
+
var _a;
|
|
167
|
+
return ((_a = node.questionToken) == null ? void 0 : _a.kind) === ts__default["default"].SyntaxKind.QuestionToken;
|
|
168
|
+
}
|
|
169
|
+
function isGenericInterfaceDeclaration(node) {
|
|
170
|
+
var _a;
|
|
171
|
+
const length = (_a = node.typeParameters) == null ? void 0 : _a.length;
|
|
172
|
+
return length ? length > 0 : false;
|
|
173
|
+
}
|
|
174
|
+
function isGenericTypeDeclaration(node) {
|
|
175
|
+
var _a;
|
|
176
|
+
const length = (_a = node.typeParameters) == null ? void 0 : _a.length;
|
|
177
|
+
return length ? length > 0 : false;
|
|
178
|
+
}
|
|
179
|
+
function isTypeReferenceGeneric(node, typeChecker) {
|
|
180
|
+
const symbol = typeChecker.getSymbolAtLocation(node.typeName);
|
|
181
|
+
if (symbol && symbol.declarations) {
|
|
182
|
+
return symbol.declarations[0].kind === ts__default["default"].SyntaxKind.TypeParameter;
|
|
183
|
+
}
|
|
184
|
+
return false;
|
|
185
|
+
}
|
|
186
|
+
function isTopLevelNode(node) {
|
|
187
|
+
return node.kind === ts__default["default"].SyntaxKind.InterfaceDeclaration || node.kind === ts__default["default"].SyntaxKind.TypeAliasDeclaration;
|
|
188
|
+
}
|
|
189
|
+
function isGenericNodeType(nt) {
|
|
190
|
+
var _a;
|
|
191
|
+
return ((_a = nt.genericTokens) == null ? void 0 : _a.length) > 0;
|
|
192
|
+
}
|
|
193
|
+
function isGenericNamedType(nt) {
|
|
194
|
+
var _a;
|
|
195
|
+
return ((_a = nt.genericTokens) == null ? void 0 : _a.length) > 0;
|
|
196
|
+
}
|
|
197
|
+
function isPrimitiveTypeNode(node) {
|
|
198
|
+
return node.type === "string" || node.type === "number" || node.type === "boolean" || node.type === "null" || node.type === "template" || node.type === "any" || node.type === "never" || node.type === "undefined" || node.type === "unknown";
|
|
199
|
+
}
|
|
200
|
+
function isNonNullable(a) {
|
|
201
|
+
return a !== null || a !== void 0;
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
function propertyToTuple(node) {
|
|
205
|
+
var _a, _b;
|
|
206
|
+
let key = (_a = node.children) == null ? void 0 : _a[0].value;
|
|
207
|
+
if (key.includes("-")) {
|
|
208
|
+
key = `'${key}'`;
|
|
209
|
+
}
|
|
210
|
+
return {
|
|
211
|
+
key,
|
|
212
|
+
value: (_b = node.children) == null ? void 0 : _b[1]
|
|
213
|
+
};
|
|
214
|
+
}
|
|
215
|
+
function makePropertyMap(node) {
|
|
216
|
+
var _a;
|
|
217
|
+
const m = new Map();
|
|
218
|
+
(_a = node.children) == null ? void 0 : _a.forEach((child) => {
|
|
219
|
+
const property = propertyToTuple(child);
|
|
220
|
+
m.set(property.key, property.value);
|
|
221
|
+
});
|
|
222
|
+
return m;
|
|
223
|
+
}
|
|
224
|
+
function isNode(obj) {
|
|
225
|
+
return typeof obj !== "string" || typeof obj !== "number" || typeof obj !== "boolean";
|
|
226
|
+
}
|
|
227
|
+
function resolveConditional(conditional) {
|
|
228
|
+
const { left, right } = conditional.check;
|
|
229
|
+
if (isPrimitiveTypeNode(left) && isPrimitiveTypeNode(right)) {
|
|
230
|
+
if (left.const && right.const) {
|
|
231
|
+
return left.const === right.const ? conditional.value.true : conditional.value.false;
|
|
232
|
+
}
|
|
233
|
+
if ((left.type === "any" || left.type === "unknown") && (right.type === "any" || right.type === "unknown")) {
|
|
234
|
+
return conditional.value.true;
|
|
235
|
+
}
|
|
236
|
+
if ((left.type === "null" || left.type === "undefined") && (right.type === "null" || right.type === "undefined")) {
|
|
237
|
+
return conditional.value.true;
|
|
238
|
+
}
|
|
239
|
+
if (left.type === right.type) {
|
|
240
|
+
return conditional.value.true;
|
|
241
|
+
}
|
|
242
|
+
return conditional.value.false;
|
|
243
|
+
}
|
|
244
|
+
return conditional;
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
var __defProp = Object.defineProperty;
|
|
248
|
+
var __defProps = Object.defineProperties;
|
|
249
|
+
var __getOwnPropDescs = Object.getOwnPropertyDescriptors;
|
|
250
|
+
var __getOwnPropSymbols = Object.getOwnPropertySymbols;
|
|
251
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
252
|
+
var __propIsEnum = Object.prototype.propertyIsEnumerable;
|
|
253
|
+
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
254
|
+
var __spreadValues = (a, b) => {
|
|
255
|
+
for (var prop in b || (b = {}))
|
|
256
|
+
if (__hasOwnProp.call(b, prop))
|
|
257
|
+
__defNormalProp(a, prop, b[prop]);
|
|
258
|
+
if (__getOwnPropSymbols)
|
|
259
|
+
for (var prop of __getOwnPropSymbols(b)) {
|
|
260
|
+
if (__propIsEnum.call(b, prop))
|
|
261
|
+
__defNormalProp(a, prop, b[prop]);
|
|
262
|
+
}
|
|
263
|
+
return a;
|
|
264
|
+
};
|
|
265
|
+
var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
|
|
266
|
+
function tsStripOptionalType(node) {
|
|
267
|
+
return ts__namespace.isOptionalTypeNode(node) ? node.type : node;
|
|
268
|
+
}
|
|
269
|
+
function isExportedDeclaration(node) {
|
|
270
|
+
var _a;
|
|
271
|
+
return !!((_a = node.modifiers) == null ? void 0 : _a.some((modifier) => modifier.kind === ts__namespace.SyntaxKind.ExportKeyword));
|
|
272
|
+
}
|
|
273
|
+
function isNodeExported(node) {
|
|
274
|
+
return (ts__namespace.getCombinedModifierFlags(node) & ts__namespace.ModifierFlags.Export) !== 0 || !!node.parent && node.parent.kind === ts__namespace.SyntaxKind.SourceFile;
|
|
275
|
+
}
|
|
276
|
+
function getReferencedType(node, typeChecker) {
|
|
277
|
+
var _a;
|
|
278
|
+
let symbol = typeChecker.getSymbolAtLocation(node.typeName);
|
|
279
|
+
if (symbol && (symbol.flags & ts__namespace.SymbolFlags.Alias) === ts__namespace.SymbolFlags.Alias) {
|
|
280
|
+
symbol = typeChecker.getAliasedSymbol(symbol);
|
|
281
|
+
}
|
|
282
|
+
const varDecl = (_a = symbol == null ? void 0 : symbol.declarations) == null ? void 0 : _a[0];
|
|
283
|
+
if (varDecl && (ts__namespace.isInterfaceDeclaration(varDecl) || ts__namespace.isTypeAliasDeclaration(varDecl))) {
|
|
284
|
+
return { declaration: varDecl, exported: isNodeExported(varDecl) };
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
function getStringLiteralsFromUnion(node) {
|
|
288
|
+
if (ts__namespace.isUnionTypeNode(node)) {
|
|
289
|
+
return new Set(node.types.map((type) => {
|
|
290
|
+
if (ts__namespace.isLiteralTypeNode(type) && ts__namespace.isStringLiteral(type.literal)) {
|
|
291
|
+
return type.literal.text;
|
|
292
|
+
}
|
|
293
|
+
return "";
|
|
294
|
+
}));
|
|
295
|
+
}
|
|
296
|
+
if (ts__namespace.isLiteralTypeNode(node) && ts__namespace.isStringLiteral(node.literal)) {
|
|
297
|
+
return new Set([node.literal.text]);
|
|
298
|
+
}
|
|
299
|
+
return new Set();
|
|
300
|
+
}
|
|
301
|
+
function buildTemplateRegex(node, typeChecker) {
|
|
302
|
+
let regex = node.head.text;
|
|
303
|
+
node.templateSpans.forEach((span) => {
|
|
304
|
+
var _a;
|
|
305
|
+
let type = span.type.kind;
|
|
306
|
+
if (ts__namespace.isTypeReferenceNode(span.type)) {
|
|
307
|
+
let symbol = typeChecker.getSymbolAtLocation(span.type.typeName);
|
|
308
|
+
if (symbol && (symbol.flags & ts__namespace.SymbolFlags.Alias) === ts__namespace.SymbolFlags.Alias) {
|
|
309
|
+
symbol = typeChecker.getAliasedSymbol(symbol);
|
|
310
|
+
}
|
|
311
|
+
type = ((_a = symbol == null ? void 0 : symbol.declarations) == null ? void 0 : _a[0]).type.kind;
|
|
312
|
+
}
|
|
313
|
+
if (type === ts__namespace.SyntaxKind.StringKeyword) {
|
|
314
|
+
regex += ".*";
|
|
315
|
+
} else if (type === ts__namespace.SyntaxKind.NumberKeyword) {
|
|
316
|
+
regex += "[0-9]*";
|
|
317
|
+
} else if (type === ts__namespace.SyntaxKind.BooleanKeyword) {
|
|
318
|
+
regex += "true|false";
|
|
319
|
+
}
|
|
320
|
+
regex += span.literal.text;
|
|
321
|
+
});
|
|
322
|
+
return regex;
|
|
323
|
+
}
|
|
324
|
+
function fillInGenerics(xlrNode, generics) {
|
|
325
|
+
var _a;
|
|
326
|
+
let localGenerics;
|
|
327
|
+
if (generics) {
|
|
328
|
+
localGenerics = new Map(generics);
|
|
329
|
+
} else {
|
|
330
|
+
localGenerics = new Map();
|
|
331
|
+
if (isGenericNodeType(xlrNode)) {
|
|
332
|
+
(_a = xlrNode.genericTokens) == null ? void 0 : _a.forEach((token) => {
|
|
333
|
+
var _a2;
|
|
334
|
+
localGenerics.set(token.symbol, (_a2 = token.default) != null ? _a2 : token.constraints);
|
|
335
|
+
});
|
|
336
|
+
}
|
|
337
|
+
}
|
|
338
|
+
if (xlrNode.type === "ref") {
|
|
339
|
+
if (localGenerics.has(xlrNode.ref)) {
|
|
340
|
+
return __spreadValues(__spreadValues(__spreadValues(__spreadValues(__spreadValues(__spreadValues({}, localGenerics.get(xlrNode.ref)), xlrNode.genericArguments ? {
|
|
341
|
+
genericArguments: xlrNode.genericArguments.map((ga) => fillInGenerics(ga, localGenerics))
|
|
342
|
+
} : {}), xlrNode.title ? { title: xlrNode.title } : {}), xlrNode.name ? { name: xlrNode.name } : {}), xlrNode.description ? { description: xlrNode.description } : {}), xlrNode.comment ? { comment: xlrNode.comment } : {});
|
|
343
|
+
}
|
|
344
|
+
return __spreadValues(__spreadValues({}, xlrNode), xlrNode.genericArguments ? {
|
|
345
|
+
genericArguments: xlrNode.genericArguments.map((ga) => fillInGenerics(ga, localGenerics))
|
|
346
|
+
} : {});
|
|
347
|
+
}
|
|
348
|
+
if (xlrNode.type === "object") {
|
|
349
|
+
const newProperties = {};
|
|
350
|
+
Object.getOwnPropertyNames(xlrNode.properties).forEach((propName) => {
|
|
351
|
+
const prop = xlrNode.properties[propName];
|
|
352
|
+
newProperties[propName] = {
|
|
353
|
+
required: prop.required,
|
|
354
|
+
node: fillInGenerics(prop.node, localGenerics)
|
|
355
|
+
};
|
|
356
|
+
});
|
|
357
|
+
return __spreadProps(__spreadValues({}, xlrNode), {
|
|
358
|
+
properties: newProperties
|
|
359
|
+
});
|
|
360
|
+
}
|
|
361
|
+
if (xlrNode.type === "array") {
|
|
362
|
+
xlrNode.elementType = fillInGenerics(xlrNode.elementType, localGenerics);
|
|
363
|
+
} else if (xlrNode.type === "or" || xlrNode.type === "and") {
|
|
364
|
+
let pointer;
|
|
365
|
+
if (xlrNode.type === "or") {
|
|
366
|
+
pointer = xlrNode.or;
|
|
367
|
+
} else {
|
|
368
|
+
pointer = xlrNode.and;
|
|
369
|
+
}
|
|
370
|
+
return __spreadProps(__spreadValues({}, xlrNode), {
|
|
371
|
+
[xlrNode.type]: pointer.map((prop) => {
|
|
372
|
+
return fillInGenerics(prop, localGenerics);
|
|
373
|
+
})
|
|
374
|
+
});
|
|
375
|
+
} else if (xlrNode.type === "record") {
|
|
376
|
+
return __spreadProps(__spreadValues({}, xlrNode), {
|
|
377
|
+
keyType: fillInGenerics(xlrNode.keyType, localGenerics),
|
|
378
|
+
valueType: fillInGenerics(xlrNode.valueType, localGenerics)
|
|
379
|
+
});
|
|
380
|
+
} else if (xlrNode.type === "conditional") {
|
|
381
|
+
const filledInConditional = __spreadProps(__spreadValues({}, xlrNode), {
|
|
382
|
+
check: {
|
|
383
|
+
left: fillInGenerics(xlrNode.check.left, localGenerics),
|
|
384
|
+
right: fillInGenerics(xlrNode.check.right, localGenerics)
|
|
385
|
+
},
|
|
386
|
+
value: {
|
|
387
|
+
true: fillInGenerics(xlrNode.value.true, localGenerics),
|
|
388
|
+
false: fillInGenerics(xlrNode.value.false, localGenerics)
|
|
389
|
+
}
|
|
390
|
+
});
|
|
391
|
+
if (filledInConditional.check.left.type !== "ref" && filledInConditional.check.right.type !== "ref") {
|
|
392
|
+
return __spreadValues({
|
|
393
|
+
name: xlrNode.name,
|
|
394
|
+
title: xlrNode.title
|
|
395
|
+
}, resolveConditional(filledInConditional));
|
|
396
|
+
}
|
|
397
|
+
return filledInConditional;
|
|
398
|
+
}
|
|
399
|
+
return xlrNode;
|
|
400
|
+
}
|
|
401
|
+
function applyPickOrOmitToNodeType(baseObject, operation, properties) {
|
|
402
|
+
if (baseObject.type === "object") {
|
|
403
|
+
const newObject = __spreadValues({}, baseObject);
|
|
404
|
+
Object.keys(baseObject.properties).forEach((key) => {
|
|
405
|
+
if (operation === "Omit" && properties.has(key) || operation === "Pick" && !properties.has(key)) {
|
|
406
|
+
delete newObject.properties[key];
|
|
407
|
+
}
|
|
408
|
+
});
|
|
409
|
+
if (Object.keys(newObject.properties).length === 0 && (operation !== "Omit" || newObject.additionalProperties === false)) {
|
|
410
|
+
return void 0;
|
|
411
|
+
}
|
|
412
|
+
return newObject;
|
|
413
|
+
}
|
|
414
|
+
let pointer;
|
|
415
|
+
if (baseObject.type === "and") {
|
|
416
|
+
pointer = baseObject.and;
|
|
417
|
+
} else if (baseObject.type === "or") {
|
|
418
|
+
pointer = baseObject.or;
|
|
419
|
+
} else {
|
|
420
|
+
throw new Error(`Error: Can not apply ${operation} to type ${baseObject.type}`);
|
|
421
|
+
}
|
|
422
|
+
const pickedTypes = pointer.map((type) => {
|
|
423
|
+
const node = applyPickOrOmitToNodeType(type, operation, properties);
|
|
424
|
+
if (node === void 0) {
|
|
425
|
+
return void 0;
|
|
426
|
+
}
|
|
427
|
+
return __spreadProps(__spreadValues({}, node), { additionalProperties: false });
|
|
428
|
+
}).filter((type) => type !== void 0);
|
|
429
|
+
if (pickedTypes.length === 0) {
|
|
430
|
+
return void 0;
|
|
431
|
+
}
|
|
432
|
+
if (pickedTypes.length === 1) {
|
|
433
|
+
return pickedTypes[0];
|
|
434
|
+
}
|
|
435
|
+
if (baseObject.type === "and") {
|
|
436
|
+
return __spreadProps(__spreadValues({}, baseObject), { and: pickedTypes });
|
|
437
|
+
}
|
|
438
|
+
return __spreadProps(__spreadValues({}, baseObject), { or: pickedTypes });
|
|
439
|
+
}
|
|
440
|
+
function applyPartialOrRequiredToNodeType(baseObject, modifier) {
|
|
441
|
+
if (baseObject.type === "object") {
|
|
442
|
+
const newObject = __spreadValues({}, baseObject);
|
|
443
|
+
Object.keys(baseObject.properties).forEach((key) => {
|
|
444
|
+
newObject.properties[key].required = modifier;
|
|
445
|
+
});
|
|
446
|
+
return newObject;
|
|
447
|
+
}
|
|
448
|
+
if (baseObject.type === "and") {
|
|
449
|
+
const pickedTypes = baseObject.and.map((type) => applyPartialOrRequiredToNodeType(type, modifier));
|
|
450
|
+
return __spreadProps(__spreadValues({}, baseObject), { and: pickedTypes });
|
|
451
|
+
}
|
|
452
|
+
if (baseObject.type === "or") {
|
|
453
|
+
const pickedTypes = baseObject.or.map((type) => applyPartialOrRequiredToNodeType(type, modifier));
|
|
454
|
+
return __spreadProps(__spreadValues({}, baseObject), { or: pickedTypes });
|
|
455
|
+
}
|
|
456
|
+
throw new Error(`Error: Can not apply ${modifier ? "Required" : "Partial"} to type ${baseObject.type}`);
|
|
457
|
+
}
|
|
458
|
+
|
|
459
|
+
function setupTestEnv(sourceCode, mockFileName = "filename.ts") {
|
|
460
|
+
const sourceFile = ts__namespace.createSourceFile(mockFileName, sourceCode, ts__namespace.ScriptTarget.Latest, true);
|
|
461
|
+
const compilerHost = {
|
|
462
|
+
getSourceFile(filename) {
|
|
463
|
+
if (filename === mockFileName) {
|
|
464
|
+
return sourceFile;
|
|
465
|
+
}
|
|
466
|
+
return void 0;
|
|
467
|
+
},
|
|
468
|
+
writeFile(name, text, writeByteOrderMark) {
|
|
469
|
+
},
|
|
470
|
+
getDefaultLibFileName() {
|
|
471
|
+
return "lib.d.ts";
|
|
472
|
+
},
|
|
473
|
+
useCaseSensitiveFileNames() {
|
|
474
|
+
return false;
|
|
475
|
+
},
|
|
476
|
+
getCanonicalFileName(filename) {
|
|
477
|
+
return filename;
|
|
478
|
+
},
|
|
479
|
+
getCurrentDirectory() {
|
|
480
|
+
return "";
|
|
481
|
+
},
|
|
482
|
+
getNewLine() {
|
|
483
|
+
return "\n";
|
|
484
|
+
},
|
|
485
|
+
fileExists(fileName) {
|
|
486
|
+
if (fileName === mockFileName) {
|
|
487
|
+
return true;
|
|
488
|
+
}
|
|
489
|
+
return false;
|
|
490
|
+
},
|
|
491
|
+
readFile(fileName) {
|
|
492
|
+
if (fileName === mockFileName) {
|
|
493
|
+
return sourceCode;
|
|
494
|
+
}
|
|
495
|
+
return void 0;
|
|
496
|
+
}
|
|
497
|
+
};
|
|
498
|
+
const program = ts__namespace.createProgram([mockFileName], {}, compilerHost);
|
|
499
|
+
return { sf: sourceFile, tc: program.getTypeChecker() };
|
|
500
|
+
}
|
|
501
|
+
|
|
502
|
+
exports.applyPartialOrRequiredToNodeType = applyPartialOrRequiredToNodeType;
|
|
503
|
+
exports.applyPickOrOmitToNodeType = applyPickOrOmitToNodeType;
|
|
504
|
+
exports.buildTemplateRegex = buildTemplateRegex;
|
|
505
|
+
exports.decorateNode = decorateNode;
|
|
506
|
+
exports.fillInGenerics = fillInGenerics;
|
|
507
|
+
exports.getReferencedType = getReferencedType;
|
|
508
|
+
exports.getStringLiteralsFromUnion = getStringLiteralsFromUnion;
|
|
509
|
+
exports.isExportedDeclaration = isExportedDeclaration;
|
|
510
|
+
exports.isGenericInterfaceDeclaration = isGenericInterfaceDeclaration;
|
|
511
|
+
exports.isGenericNamedType = isGenericNamedType;
|
|
512
|
+
exports.isGenericNodeType = isGenericNodeType;
|
|
513
|
+
exports.isGenericTypeDeclaration = isGenericTypeDeclaration;
|
|
514
|
+
exports.isNode = isNode;
|
|
515
|
+
exports.isNodeExported = isNodeExported;
|
|
516
|
+
exports.isNonNullable = isNonNullable;
|
|
517
|
+
exports.isOptionalProperty = isOptionalProperty;
|
|
518
|
+
exports.isPrimitiveTypeNode = isPrimitiveTypeNode;
|
|
519
|
+
exports.isTopLevelNode = isTopLevelNode;
|
|
520
|
+
exports.isTypeReferenceGeneric = isTypeReferenceGeneric;
|
|
521
|
+
exports.makePropertyMap = makePropertyMap;
|
|
522
|
+
exports.propertyToTuple = propertyToTuple;
|
|
523
|
+
exports.resolveConditional = resolveConditional;
|
|
524
|
+
exports.setupTestEnv = setupTestEnv;
|
|
525
|
+
exports.tsStripOptionalType = tsStripOptionalType;
|
|
526
|
+
//# sourceMappingURL=index.cjs.js.map
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
import * as ts from 'typescript';
|
|
2
|
+
import ts__default from 'typescript';
|
|
3
|
+
import { Annotations, NodeType, NodeTypeWithGenerics, NamedType, NamedTypeWithGenerics, PrimitiveTypes, ConditionalType } from '@player-tools/xlr';
|
|
4
|
+
import { Node } from 'jsonc-parser';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Converts JSDoc comments to strings
|
|
8
|
+
*/
|
|
9
|
+
declare function decorateNode(node: ts.Node): Annotations;
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Returns the required type or the optionally required type
|
|
13
|
+
*/
|
|
14
|
+
declare function tsStripOptionalType(node: ts.TypeNode): ts.TypeNode;
|
|
15
|
+
/**
|
|
16
|
+
* Returns if the top level declaration is exported
|
|
17
|
+
*/
|
|
18
|
+
declare function isExportedDeclaration(node: ts.Statement): boolean;
|
|
19
|
+
/**
|
|
20
|
+
* Returns if the node is exported from the source file
|
|
21
|
+
*/
|
|
22
|
+
declare function isNodeExported(node: ts.Node): boolean;
|
|
23
|
+
/**
|
|
24
|
+
* Returns the actual type and will following import chains if needed
|
|
25
|
+
*/
|
|
26
|
+
declare function getReferencedType(node: ts.TypeReferenceNode, typeChecker: ts.TypeChecker): {
|
|
27
|
+
declaration: ts.TypeAliasDeclaration | ts.InterfaceDeclaration;
|
|
28
|
+
exported: boolean;
|
|
29
|
+
} | undefined;
|
|
30
|
+
/**
|
|
31
|
+
* Returns list of string literals from potential union of strings
|
|
32
|
+
*/
|
|
33
|
+
declare function getStringLiteralsFromUnion(node: ts.Node): Set<string>;
|
|
34
|
+
/**
|
|
35
|
+
* Converts a format string into a regex that can be used to validate a given string matches the template
|
|
36
|
+
*/
|
|
37
|
+
declare function buildTemplateRegex(node: ts.TemplateLiteralTypeNode, typeChecker: ts.TypeChecker): string;
|
|
38
|
+
/**
|
|
39
|
+
* Walks generics to fill in values from a combination of the default, constraint, and passed in map values
|
|
40
|
+
*/
|
|
41
|
+
declare function fillInGenerics(xlrNode: NodeType, generics?: Map<string, NodeType>): NodeType;
|
|
42
|
+
/** Applies the TS `Pick` type to an interface/union/intersection */
|
|
43
|
+
declare function applyPickOrOmitToNodeType(baseObject: NodeType, operation: 'Pick' | 'Omit', properties: Set<string>): NodeType | undefined;
|
|
44
|
+
/** Applies the TS `Omit` type to an interface/union/intersection */
|
|
45
|
+
declare function applyPartialOrRequiredToNodeType(baseObject: NodeType, modifier: boolean): NodeType;
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* Returns if the Object Property is optional
|
|
49
|
+
*/
|
|
50
|
+
declare function isOptionalProperty(node: ts__default.PropertySignature): boolean;
|
|
51
|
+
/**
|
|
52
|
+
* Returns if the node is an Interface or Type with Generics
|
|
53
|
+
*/
|
|
54
|
+
declare function isGenericInterfaceDeclaration(node: ts__default.InterfaceDeclaration): boolean;
|
|
55
|
+
/**
|
|
56
|
+
* Returns if the node is an Type Declaration with Generics
|
|
57
|
+
*/
|
|
58
|
+
declare function isGenericTypeDeclaration(node: ts__default.TypeAliasDeclaration): boolean;
|
|
59
|
+
/**
|
|
60
|
+
* Returns if the referenced type is a generic
|
|
61
|
+
*/
|
|
62
|
+
declare function isTypeReferenceGeneric(node: ts__default.TypeReferenceNode, typeChecker: ts__default.TypeChecker): boolean;
|
|
63
|
+
declare type TopLevelDeclaration = ts__default.InterfaceDeclaration | ts__default.TypeAliasDeclaration;
|
|
64
|
+
/**
|
|
65
|
+
* Returns if the node is an interface or a type declaration
|
|
66
|
+
*/
|
|
67
|
+
declare function isTopLevelNode(node: ts__default.Node): node is TopLevelDeclaration;
|
|
68
|
+
/**
|
|
69
|
+
* Returns if the NodeType has generic tokens
|
|
70
|
+
*/
|
|
71
|
+
declare function isGenericNodeType<T extends NodeType = NodeType>(nt: NodeType): nt is NodeTypeWithGenerics<T>;
|
|
72
|
+
/**
|
|
73
|
+
* Returns if the named type has generic tokens
|
|
74
|
+
*/
|
|
75
|
+
declare function isGenericNamedType<T extends NamedType = NamedType>(nt: NodeType): nt is NamedTypeWithGenerics<T>;
|
|
76
|
+
/**
|
|
77
|
+
* Returns if the node is a `PrimitiveTypes`
|
|
78
|
+
*/
|
|
79
|
+
declare function isPrimitiveTypeNode(node: NodeType): node is PrimitiveTypes;
|
|
80
|
+
/**
|
|
81
|
+
* Type Guard for non-null values
|
|
82
|
+
*/
|
|
83
|
+
declare function isNonNullable<T>(a: T | null | undefined): a is NonNullable<T>;
|
|
84
|
+
|
|
85
|
+
interface PropertyNode {
|
|
86
|
+
/** Equivalent Property Name */
|
|
87
|
+
key: string;
|
|
88
|
+
/** Equivalent Property Value */
|
|
89
|
+
value: Node;
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* Takes a property node and returns the underlying Key/Value Pairs
|
|
93
|
+
*/
|
|
94
|
+
declare function propertyToTuple(node: Node): PropertyNode;
|
|
95
|
+
/**
|
|
96
|
+
* Turns a node's children into a map for easy access
|
|
97
|
+
*/
|
|
98
|
+
declare function makePropertyMap(node: Node): Map<string, Node>;
|
|
99
|
+
/**
|
|
100
|
+
* Checks if property is a leaf node or another node
|
|
101
|
+
*/
|
|
102
|
+
declare function isNode(obj: Node | string | number | boolean): obj is Node;
|
|
103
|
+
/**
|
|
104
|
+
* Attempts to resolve a conditional type
|
|
105
|
+
*/
|
|
106
|
+
declare function resolveConditional(conditional: ConditionalType): NodeType;
|
|
107
|
+
|
|
108
|
+
interface SetupReturnType {
|
|
109
|
+
/**
|
|
110
|
+
* Virtual source file containing the passed in text
|
|
111
|
+
*/
|
|
112
|
+
sf: ts.SourceFile;
|
|
113
|
+
/**
|
|
114
|
+
* Type checker for the virtual program
|
|
115
|
+
*/
|
|
116
|
+
tc: ts.TypeChecker;
|
|
117
|
+
}
|
|
118
|
+
/**
|
|
119
|
+
* Setups a virtual TS environment for tests
|
|
120
|
+
*/
|
|
121
|
+
declare function setupTestEnv(sourceCode: string, mockFileName?: string): {
|
|
122
|
+
sf: ts.SourceFile;
|
|
123
|
+
tc: ts.TypeChecker;
|
|
124
|
+
};
|
|
125
|
+
|
|
126
|
+
export { PropertyNode, SetupReturnType, TopLevelDeclaration, applyPartialOrRequiredToNodeType, applyPickOrOmitToNodeType, buildTemplateRegex, decorateNode, fillInGenerics, getReferencedType, getStringLiteralsFromUnion, isExportedDeclaration, isGenericInterfaceDeclaration, isGenericNamedType, isGenericNodeType, isGenericTypeDeclaration, isNode, isNodeExported, isNonNullable, isOptionalProperty, isPrimitiveTypeNode, isTopLevelNode, isTypeReferenceGeneric, makePropertyMap, propertyToTuple, resolveConditional, setupTestEnv, tsStripOptionalType };
|