runtypex 0.1.3 → 0.1.5
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/esm/core/index.js +5 -5
- package/dist/esm/index.js +3 -3
- package/dist/esm/transformer/ts-transformer.js +1 -1
- package/dist/esm/transformer/vite-plugin.js +1 -1
- package/package.json +20 -21
- package/dist/cjs/core/emitArrayOrTuple.d.ts +0 -6
- package/dist/cjs/core/emitArrayOrTuple.js +0 -40
- package/dist/cjs/core/emitLiteralOrEnum.d.ts +0 -4
- package/dist/cjs/core/emitLiteralOrEnum.js +0 -47
- package/dist/cjs/core/emitObject.d.ts +0 -6
- package/dist/cjs/core/emitObject.js +0 -28
- package/dist/cjs/core/emitPrimitive.d.ts +0 -6
- package/dist/cjs/core/emitPrimitive.js +0 -29
- package/dist/cjs/core/emitUnionOrIntersection.d.ts +0 -6
- package/dist/cjs/core/emitUnionOrIntersection.js +0 -15
- package/dist/cjs/core/index.d.ts +0 -17
- package/dist/cjs/core/index.js +0 -41
- package/dist/cjs/index.d.ts +0 -3
- package/dist/cjs/index.js +0 -13
- package/dist/cjs/runtime/validate.d.ts +0 -10
- package/dist/cjs/runtime/validate.js +0 -18
- package/dist/cjs/transformer/ts-transformer.d.ts +0 -25
- package/dist/cjs/transformer/ts-transformer.js +0 -103
- package/dist/cjs/transformer/vite-plugin.d.ts +0 -18
- package/dist/cjs/transformer/vite-plugin.js +0 -137
- package/dist/core/emitArrayOrTuple.d.ts +0 -6
- package/dist/core/emitArrayOrTuple.js +0 -38
- package/dist/core/emitArrayOrTuple.js.map +0 -1
- package/dist/core/emitLiteralOrEnum.d.ts +0 -4
- package/dist/core/emitLiteralOrEnum.js +0 -42
- package/dist/core/emitLiteralOrEnum.js.map +0 -1
- package/dist/core/emitObject.d.ts +0 -6
- package/dist/core/emitObject.js +0 -23
- package/dist/core/emitObject.js.map +0 -1
- package/dist/core/emitPrimitive.d.ts +0 -6
- package/dist/core/emitPrimitive.js +0 -24
- package/dist/core/emitPrimitive.js.map +0 -1
- package/dist/core/emitUnionOrIntersection.d.ts +0 -6
- package/dist/core/emitUnionOrIntersection.js +0 -13
- package/dist/core/emitUnionOrIntersection.js.map +0 -1
- package/dist/core/index.d.ts +0 -17
- package/dist/core/index.js +0 -37
- package/dist/core/index.js.map +0 -1
- package/dist/index.d.ts +0 -3
- package/dist/index.js +0 -4
- package/dist/index.js.map +0 -1
- package/dist/runtime/validate.d.ts +0 -10
- package/dist/runtime/validate.js +0 -15
- package/dist/runtime/validate.js.map +0 -1
- package/dist/transformer/ts-transformer.d.ts +0 -25
- package/dist/transformer/ts-transformer.js +0 -98
- package/dist/transformer/ts-transformer.js.map +0 -1
- package/dist/transformer/vite-plugin.d.ts +0 -18
- package/dist/transformer/vite-plugin.js +0 -132
- package/dist/transformer/vite-plugin.js.map +0 -1
|
@@ -1,137 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
-
};
|
|
5
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.default = vitePluginRuntypex;
|
|
7
|
-
const typescript_1 = __importDefault(require("typescript"));
|
|
8
|
-
const node_path_1 = __importDefault(require("node:path"));
|
|
9
|
-
const core_1 = require("../core");
|
|
10
|
-
/**
|
|
11
|
-
* 🧩 vitePluginRuntypex
|
|
12
|
-
* A Vite plugin that performs build-time type → runtime validation transformation.
|
|
13
|
-
*
|
|
14
|
-
* 📘 Purpose
|
|
15
|
-
* - Replace calls like:
|
|
16
|
-
* makeValidate<T>(), makeAssert<T>()
|
|
17
|
-
* with *inline JavaScript guard functions* derived from TypeScript types.
|
|
18
|
-
*
|
|
19
|
-
* 💡 Features
|
|
20
|
-
* - Works in both dev & build mode
|
|
21
|
-
* - Optional: remove validation code in production (`removeInProd`)
|
|
22
|
-
* - Compatible with Rollup / Webpack (via Vite plugin API)
|
|
23
|
-
*/
|
|
24
|
-
function vitePluginRuntypex(options) {
|
|
25
|
-
const removeInProd = !!options?.removeInProd;
|
|
26
|
-
const prod = process.env.NODE_ENV === "production";
|
|
27
|
-
return {
|
|
28
|
-
name: "vite-plugin-runtypex",
|
|
29
|
-
enforce: "pre",
|
|
30
|
-
transform(code, id) {
|
|
31
|
-
const isTS = id.endsWith(".ts") || id.endsWith(".tsx");
|
|
32
|
-
const isTargetFunction = /make(?:Validate|Assert)</.test(code);
|
|
33
|
-
if (!isTS || !isTargetFunction)
|
|
34
|
-
return;
|
|
35
|
-
const { program, checker } = _createProgramFor(id);
|
|
36
|
-
const sf = program.getSourceFile(id);
|
|
37
|
-
if (!sf)
|
|
38
|
-
return;
|
|
39
|
-
let mutated = code;
|
|
40
|
-
// ② makeAssert<T>()
|
|
41
|
-
mutated = mutated.replace(/makeAssert<\s*([^>]+)\s*>\s*\(\s*\)/g, (_m, typeName) => _emitMakeAssert({ program, checker, sf, typeName, prod, removeInProd }) ?? _m);
|
|
42
|
-
// ③ makeValidate<T>()
|
|
43
|
-
mutated = mutated.replace(/makeValidate<\s*([^>]+)\s*>\s*\(\s*\)/g, (_m, typeName) => _emitMakeValidate({ program, checker, sf, typeName, prod, removeInProd }) ?? _m);
|
|
44
|
-
return mutated === code ? null : { code: mutated, map: null };
|
|
45
|
-
},
|
|
46
|
-
};
|
|
47
|
-
}
|
|
48
|
-
// ──────────────────────────────────────────────
|
|
49
|
-
// ① createProgram & TypeChecker
|
|
50
|
-
// ──────────────────────────────────────────────
|
|
51
|
-
function _createProgramFor(file) {
|
|
52
|
-
const tsconfig = _findNearestTsconfig(node_path_1.default.dirname(file));
|
|
53
|
-
const cfg = typescript_1.default.readConfigFile(tsconfig, typescript_1.default.sys.readFile);
|
|
54
|
-
if (cfg.error) {
|
|
55
|
-
throw new Error(typescript_1.default.flattenDiagnosticMessageText(cfg.error.messageText, "\n"));
|
|
56
|
-
}
|
|
57
|
-
const parsed = typescript_1.default.parseJsonConfigFileContent(cfg.config, typescript_1.default.sys, node_path_1.default.dirname(tsconfig));
|
|
58
|
-
const program = typescript_1.default.createProgram({ rootNames: parsed.fileNames, options: parsed.options });
|
|
59
|
-
const checker = program.getTypeChecker();
|
|
60
|
-
return { program, checker };
|
|
61
|
-
}
|
|
62
|
-
function _findNearestTsconfig(start) {
|
|
63
|
-
let dir = start;
|
|
64
|
-
while (true) {
|
|
65
|
-
const candidate = node_path_1.default.join(dir, "tsconfig.json");
|
|
66
|
-
if (typescript_1.default.sys.fileExists(candidate))
|
|
67
|
-
return candidate;
|
|
68
|
-
const parent = node_path_1.default.dirname(dir);
|
|
69
|
-
if (parent === dir)
|
|
70
|
-
break;
|
|
71
|
-
dir = parent;
|
|
72
|
-
}
|
|
73
|
-
const fallback = node_path_1.default.join(process.cwd(), "tsconfig.json");
|
|
74
|
-
if (typescript_1.default.sys.fileExists(fallback))
|
|
75
|
-
return fallback;
|
|
76
|
-
throw new Error("tsconfig.json not found");
|
|
77
|
-
}
|
|
78
|
-
function _emitMakeValidate({ program, checker, sf, typeName, prod, removeInProd, }) {
|
|
79
|
-
if (removeInProd && prod)
|
|
80
|
-
return `((_)=>true)`;
|
|
81
|
-
const type = _resolveTypeByName(program, sf, checker, typeName.trim());
|
|
82
|
-
if (!type)
|
|
83
|
-
return null;
|
|
84
|
-
return (0, core_1.emitGuardFromType)(checker, type);
|
|
85
|
-
}
|
|
86
|
-
function _emitMakeAssert({ program, checker, sf, typeName, prod, removeInProd, }) {
|
|
87
|
-
if (removeInProd && prod)
|
|
88
|
-
return `((_)=>{})`;
|
|
89
|
-
const type = _resolveTypeByName(program, sf, checker, typeName.trim());
|
|
90
|
-
if (!type)
|
|
91
|
-
return null;
|
|
92
|
-
const guard = (0, core_1.emitGuardFromType)(checker, type);
|
|
93
|
-
return `(function(){const G=${guard};return(i)=>{if(!G(i))throw new TypeError("[runtypex] Validation failed.");};})()`;
|
|
94
|
-
}
|
|
95
|
-
// ──────────────────────────────────────────────
|
|
96
|
-
// ③ Type Resolution (support interface/type/enum)
|
|
97
|
-
// ──────────────────────────────────────────────
|
|
98
|
-
function _resolveTypeByName(program, sf, checker, name) {
|
|
99
|
-
// scan all source files for local declaration
|
|
100
|
-
for (const file of program.getSourceFiles()) {
|
|
101
|
-
const decl = _findLocalDeclaration(file, name);
|
|
102
|
-
if (!decl)
|
|
103
|
-
continue;
|
|
104
|
-
// interface / class / enum
|
|
105
|
-
if (typescript_1.default.isInterfaceDeclaration(decl) || typescript_1.default.isClassDeclaration(decl) || typescript_1.default.isEnumDeclaration(decl)) {
|
|
106
|
-
// @ts-ignore
|
|
107
|
-
const symbol = checker.getSymbolAtLocation(decl.name);
|
|
108
|
-
if (symbol)
|
|
109
|
-
return checker.getDeclaredTypeOfSymbol(symbol);
|
|
110
|
-
}
|
|
111
|
-
// type alias
|
|
112
|
-
if (typescript_1.default.isTypeAliasDeclaration(decl)) {
|
|
113
|
-
return checker.getTypeFromTypeNode(decl.type);
|
|
114
|
-
}
|
|
115
|
-
}
|
|
116
|
-
// Scope-based fallback
|
|
117
|
-
const symbol = checker
|
|
118
|
-
.getSymbolsInScope(sf, typescript_1.default.SymbolFlags.Type | typescript_1.default.SymbolFlags.Alias | typescript_1.default.SymbolFlags.Interface)
|
|
119
|
-
.find((s) => s.name === name);
|
|
120
|
-
return symbol ? checker.getDeclaredTypeOfSymbol(symbol) : null;
|
|
121
|
-
}
|
|
122
|
-
function _findLocalDeclaration(sf, name) {
|
|
123
|
-
let found;
|
|
124
|
-
(function walk(node) {
|
|
125
|
-
if ((typescript_1.default.isInterfaceDeclaration(node) ||
|
|
126
|
-
typescript_1.default.isTypeAliasDeclaration(node) ||
|
|
127
|
-
typescript_1.default.isEnumDeclaration(node) ||
|
|
128
|
-
typescript_1.default.isClassDeclaration(node)) &&
|
|
129
|
-
node.name?.text === name) {
|
|
130
|
-
found = node;
|
|
131
|
-
return;
|
|
132
|
-
}
|
|
133
|
-
if (!found)
|
|
134
|
-
node.forEachChild(walk);
|
|
135
|
-
})(sf);
|
|
136
|
-
return found;
|
|
137
|
-
}
|
|
@@ -1,38 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Handles array (T[]) and tuple ([A, B]) types.
|
|
3
|
-
*/
|
|
4
|
-
export function emitArrayOrTuple(ctx, expr, t) {
|
|
5
|
-
if (ctx.checker.isTupleType(t)) {
|
|
6
|
-
return _emitTuple(t, expr, ctx);
|
|
7
|
-
}
|
|
8
|
-
if (ctx.checker.isArrayType(t)) {
|
|
9
|
-
return _emitArray(ctx, expr, t);
|
|
10
|
-
}
|
|
11
|
-
return null;
|
|
12
|
-
}
|
|
13
|
-
/**
|
|
14
|
-
* Generate validation for Array<T>
|
|
15
|
-
*/
|
|
16
|
-
function _emitArray(ctx, expr, t) {
|
|
17
|
-
const arrayCheck = `Array.isArray(${expr})`;
|
|
18
|
-
// Try extracting element type
|
|
19
|
-
const element = ctx.checker.getElementTypeOfArrayType?.(t) ||
|
|
20
|
-
t.typeArguments?.[0] ||
|
|
21
|
-
t.getNumberIndexType?.();
|
|
22
|
-
if (!element)
|
|
23
|
-
return arrayCheck;
|
|
24
|
-
const eachCheck = `${expr}.every(e=>${ctx.emit("e", element)})`;
|
|
25
|
-
return `(${arrayCheck}&&${eachCheck})`;
|
|
26
|
-
}
|
|
27
|
-
/**
|
|
28
|
-
* Generate validation for Tuple [A, B, ...]
|
|
29
|
-
*/
|
|
30
|
-
function _emitTuple(ref, expr, ctx) {
|
|
31
|
-
const elements = ref.typeArguments ?? ctx.checker.getTypeArguments?.(ref) ?? [];
|
|
32
|
-
const arrayCheck = `Array.isArray(${expr})`;
|
|
33
|
-
const lenCheck = `${expr}.length===${elements.length}`;
|
|
34
|
-
const elementChecks = elements.map((el, i) => ctx.emit(`${expr}[${i}]`, el));
|
|
35
|
-
const parts = [arrayCheck, lenCheck, ...elementChecks];
|
|
36
|
-
return `(${parts.join("&&")})`;
|
|
37
|
-
}
|
|
38
|
-
//# sourceMappingURL=emitArrayOrTuple.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"emitArrayOrTuple.js","sourceRoot":"","sources":["../../src/core/emitArrayOrTuple.ts"],"names":[],"mappings":"AAGA;;GAEG;AACH,MAAM,UAAU,gBAAgB,CAAC,GAAe,EAAE,IAAY,EAAE,CAAU;IACxE,IAAI,GAAG,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE,CAAC;QAC/B,OAAO,UAAU,CAAC,CAAqB,EAAE,IAAI,EAAE,GAAG,CAAC,CAAC;IACtD,CAAC;IACD,IAAI,GAAG,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE,CAAC;QAC/B,OAAO,UAAU,CAAC,GAAG,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC;IAClC,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED;;GAEG;AACH,SAAS,UAAU,CAAC,GAAe,EAAE,IAAY,EAAE,CAAU;IAC3D,MAAM,UAAU,GAAG,iBAAiB,IAAI,GAAG,CAAC;IAE5C,8BAA8B;IAC9B,MAAM,OAAO,GACV,GAAG,CAAC,OAAe,CAAC,yBAAyB,EAAE,CAAC,CAAC,CAAC;QAClD,CAAsB,CAAC,aAAa,EAAE,CAAC,CAAC,CAAC;QAC1C,CAAC,CAAC,kBAAkB,EAAE,EAAE,CAAC;IAE3B,IAAI,CAAC,OAAO;QAAE,OAAO,UAAU,CAAC;IAChC,MAAM,SAAS,GAAG,GAAG,IAAI,aAAa,GAAG,CAAC,IAAI,CAAC,GAAG,EAAE,OAAO,CAAC,GAAG,CAAC;IAChE,OAAO,IAAI,UAAU,KAAK,SAAS,GAAG,CAAC;AACzC,CAAC;AAED;;GAEG;AACH,SAAS,UAAU,CAAC,GAAqB,EAAE,IAAY,EAAE,GAAe;IACtE,MAAM,QAAQ,GAAG,GAAG,CAAC,aAAa,IAAK,GAAG,CAAC,OAAe,CAAC,gBAAgB,EAAE,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC;IAEzF,MAAM,UAAU,GAAG,iBAAiB,IAAI,GAAG,CAAC;IAC5C,MAAM,QAAQ,GAAG,GAAG,IAAI,aAAa,QAAQ,CAAC,MAAM,EAAE,CAAC;IACvD,MAAM,aAAa,GAAG,QAAQ,CAAC,GAAG,CAAC,CAAC,EAAW,EAAE,CAAS,EAAE,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,IAAI,IAAI,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC,CAAC;IAE9F,MAAM,KAAK,GAAG,CAAC,UAAU,EAAE,QAAQ,EAAE,GAAG,aAAa,CAAC,CAAC;IACvD,OAAO,IAAI,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC;AACjC,CAAC"}
|
|
@@ -1,42 +0,0 @@
|
|
|
1
|
-
import ts from "typescript";
|
|
2
|
-
/** Handles literal types and enum-like types. */
|
|
3
|
-
export function emitLiteralOrEnum(_, expr, t) {
|
|
4
|
-
if (t.isLiteral()) {
|
|
5
|
-
const value = t.value;
|
|
6
|
-
const isString = typeof value === "string";
|
|
7
|
-
const newValue = isString ? JSON.stringify(value) : String(value);
|
|
8
|
-
return `${expr}===${newValue}`;
|
|
9
|
-
}
|
|
10
|
-
const isEnum = t.flags & ts.TypeFlags.EnumLike;
|
|
11
|
-
if (isEnum) {
|
|
12
|
-
const enumValues = _extractEnumValues(t);
|
|
13
|
-
if (enumValues.length) {
|
|
14
|
-
return `(${enumValues.map(v => `${expr}===${v}`).join("||")})`;
|
|
15
|
-
}
|
|
16
|
-
}
|
|
17
|
-
return null;
|
|
18
|
-
}
|
|
19
|
-
// Extracts numeric or string values from an Enum declaration.
|
|
20
|
-
function _extractEnumValues(t) {
|
|
21
|
-
const symbol = t.getSymbol();
|
|
22
|
-
if (!symbol)
|
|
23
|
-
return [];
|
|
24
|
-
const values = [];
|
|
25
|
-
const declarations = symbol.getDeclarations() ?? [];
|
|
26
|
-
for (const declaration of declarations) {
|
|
27
|
-
const isEnum = ts.isEnumDeclaration(declaration);
|
|
28
|
-
if (!isEnum)
|
|
29
|
-
continue;
|
|
30
|
-
for (const member of declaration.members) {
|
|
31
|
-
const init = member.initializer;
|
|
32
|
-
if (!init)
|
|
33
|
-
continue;
|
|
34
|
-
if (ts.isStringLiteral(init) || ts.isNumericLiteral(init)) {
|
|
35
|
-
const value = ts.isStringLiteral(init) ? JSON.stringify(init.text) : init.text;
|
|
36
|
-
values.push(value);
|
|
37
|
-
}
|
|
38
|
-
}
|
|
39
|
-
}
|
|
40
|
-
return values;
|
|
41
|
-
}
|
|
42
|
-
//# sourceMappingURL=emitLiteralOrEnum.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"emitLiteralOrEnum.js","sourceRoot":"","sources":["../../src/core/emitLiteralOrEnum.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,YAAY,CAAC;AAG5B,iDAAiD;AACjD,MAAM,UAAU,iBAAiB,CAAC,CAAa,EAAE,IAAY,EAAE,CAAU;IACvE,IAAI,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC;QAClB,MAAM,KAAK,GAAI,CAAoB,CAAC,KAAK,CAAC;QAC1C,MAAM,QAAQ,GAAG,OAAO,KAAK,KAAK,QAAQ,CAAC;QAC3C,MAAM,QAAQ,GAAG,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QAElE,OAAO,GAAG,IAAI,MAAM,QAAQ,EAAE,CAAC;IACjC,CAAC;IAED,MAAM,MAAM,GAAG,CAAC,CAAC,KAAK,GAAG,EAAE,CAAC,SAAS,CAAC,QAAQ,CAAC;IAC/C,IAAI,MAAM,EAAE,CAAC;QACX,MAAM,UAAU,GAAG,kBAAkB,CAAC,CAAC,CAAC,CAAC;QACzC,IAAI,UAAU,CAAC,MAAM,EAAE,CAAC;YACtB,OAAO,IAAI,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,IAAI,MAAM,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC;QACjE,CAAC;IACH,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED,8DAA8D;AAC9D,SAAS,kBAAkB,CAAC,CAAU;IACpC,MAAM,MAAM,GAAG,CAAC,CAAC,SAAS,EAAE,CAAC;IAC7B,IAAI,CAAC,MAAM;QAAE,OAAO,EAAE,CAAC;IAEvB,MAAM,MAAM,GAAa,EAAE,CAAC;IAC5B,MAAM,YAAY,GAAG,MAAM,CAAC,eAAe,EAAE,IAAI,EAAE,CAAC;IAEpD,KAAK,MAAM,WAAW,IAAI,YAAY,EAAE,CAAC;QACvC,MAAM,MAAM,GAAG,EAAE,CAAC,iBAAiB,CAAC,WAAW,CAAC,CAAC;QAEjD,IAAI,CAAC,MAAM;YAAE,SAAS;QACtB,KAAK,MAAM,MAAM,IAAI,WAAW,CAAC,OAAO,EAAE,CAAC;YACzC,MAAM,IAAI,GAAG,MAAM,CAAC,WAAW,CAAC;YAChC,IAAI,CAAC,IAAI;gBAAE,SAAS;YAEpB,IAAI,EAAE,CAAC,eAAe,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,gBAAgB,CAAC,IAAI,CAAC,EAAE,CAAC;gBAC1D,MAAM,KAAK,GAAG,EAAE,CAAC,eAAe,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC;gBAC/E,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;YACrB,CAAC;QACH,CAAC;IACH,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC"}
|
package/dist/core/emitObject.js
DELETED
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
import ts from "typescript";
|
|
2
|
-
/**
|
|
3
|
-
* Handles interfaces, classes, and object-like structures.
|
|
4
|
-
*/
|
|
5
|
-
export function emitObject(ctx, expr, t) {
|
|
6
|
-
const isObject = (t.getFlags() & ts.TypeFlags.Object) !== 0;
|
|
7
|
-
if (!isObject)
|
|
8
|
-
return null;
|
|
9
|
-
const props = ctx.checker.getPropertiesOfType(t);
|
|
10
|
-
const parts = [`typeof ${expr}==="object"`, `${expr}!==null`];
|
|
11
|
-
for (const prop of props) {
|
|
12
|
-
const declaration = prop.valueDeclaration ?? prop.declarations?.[0];
|
|
13
|
-
if (!declaration)
|
|
14
|
-
continue;
|
|
15
|
-
const propType = ctx.checker.getTypeOfSymbolAtLocation(prop, declaration);
|
|
16
|
-
const isOptional = (prop.getFlags() & ts.SymbolFlags.Optional) !== 0;
|
|
17
|
-
const condition = ctx.emit(`${expr}.${prop.name}`, propType);
|
|
18
|
-
const checkExpr = isOptional ? `(${expr}.${prop.name}===undefined||${condition})` : condition;
|
|
19
|
-
parts.push(checkExpr);
|
|
20
|
-
}
|
|
21
|
-
return `(${parts.join("&&")})`;
|
|
22
|
-
}
|
|
23
|
-
//# sourceMappingURL=emitObject.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"emitObject.js","sourceRoot":"","sources":["../../src/core/emitObject.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,YAAY,CAAC;AAG5B;;GAEG;AACH,MAAM,UAAU,UAAU,CAAC,GAAe,EAAE,IAAY,EAAE,CAAU;IAClE,MAAM,QAAQ,GAAG,CAAC,CAAC,CAAC,QAAQ,EAAE,GAAG,EAAE,CAAC,SAAS,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;IAE5D,IAAI,CAAC,QAAQ;QAAE,OAAO,IAAI,CAAC;IAE3B,MAAM,KAAK,GAAG,GAAG,CAAC,OAAO,CAAC,mBAAmB,CAAC,CAAC,CAAC,CAAC;IACjD,MAAM,KAAK,GAAa,CAAC,UAAU,IAAI,aAAa,EAAE,GAAG,IAAI,SAAS,CAAC,CAAC;IAExE,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,MAAM,WAAW,GAAG,IAAI,CAAC,gBAAgB,IAAI,IAAI,CAAC,YAAY,EAAE,CAAC,CAAC,CAAC,CAAC;QACpE,IAAI,CAAC,WAAW;YAAE,SAAS;QAE3B,MAAM,QAAQ,GAAG,GAAG,CAAC,OAAO,CAAC,yBAAyB,CAAC,IAAI,EAAE,WAAW,CAAC,CAAC;QAC1E,MAAM,UAAU,GAAG,CAAC,IAAI,CAAC,QAAQ,EAAE,GAAG,EAAE,CAAC,WAAW,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;QACrE,MAAM,SAAS,GAAG,GAAG,CAAC,IAAI,CAAC,GAAG,IAAI,IAAI,IAAI,CAAC,IAAI,EAAE,EAAE,QAAQ,CAAC,CAAC;QAC7D,MAAM,SAAS,GAAG,UAAU,CAAC,CAAC,CAAC,IAAI,IAAI,IAAI,IAAI,CAAC,IAAI,iBAAiB,SAAS,GAAG,CAAC,CAAC,CAAC,SAAS,CAAC;QAE9F,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;IACxB,CAAC;IAED,OAAO,IAAI,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC;AACjC,CAAC"}
|
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
import ts from "typescript";
|
|
2
|
-
/**
|
|
3
|
-
* Handles primitive types like number, string, boolean...
|
|
4
|
-
*/
|
|
5
|
-
export function emitPrimitive(ctx, expr, t) {
|
|
6
|
-
if ((t.flags & (ts.TypeFlags.Any | ts.TypeFlags.Unknown)) !== 0)
|
|
7
|
-
return "true";
|
|
8
|
-
if (t.flags & ts.TypeFlags.Null)
|
|
9
|
-
return `${expr}===null`;
|
|
10
|
-
if (t.flags & ts.TypeFlags.Undefined)
|
|
11
|
-
return `${expr}===undefined`;
|
|
12
|
-
if (t.flags & ts.TypeFlags.BooleanLike)
|
|
13
|
-
return `typeof ${expr}==="boolean"`;
|
|
14
|
-
if (t.flags & ts.TypeFlags.NumberLike)
|
|
15
|
-
return `typeof ${expr}==="number"`;
|
|
16
|
-
if (t.flags & ts.TypeFlags.StringLike)
|
|
17
|
-
return `typeof ${expr}==="string"`;
|
|
18
|
-
if (t.flags & ts.TypeFlags.BigIntLike)
|
|
19
|
-
return `typeof ${expr}==="bigint"`;
|
|
20
|
-
if (t.flags & ts.TypeFlags.ESSymbolLike)
|
|
21
|
-
return `typeof ${expr}==="symbol"`;
|
|
22
|
-
return null;
|
|
23
|
-
}
|
|
24
|
-
//# sourceMappingURL=emitPrimitive.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"emitPrimitive.js","sourceRoot":"","sources":["../../src/core/emitPrimitive.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,YAAY,CAAC;AAG5B;;GAEG;AACH,MAAM,UAAU,aAAa,CAAC,GAAe,EAAE,IAAY,EAAE,CAAU;IACrE,IAAI,CAAC,CAAC,CAAC,KAAK,GAAG,CAAC,EAAE,CAAC,SAAS,CAAC,GAAG,GAAG,EAAE,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC,KAAK,CAAC;QAAE,OAAO,MAAM,CAAC;IAC/E,IAAI,CAAC,CAAC,KAAK,GAAG,EAAE,CAAC,SAAS,CAAC,IAAI;QAAE,OAAO,GAAG,IAAI,SAAS,CAAC;IACzD,IAAI,CAAC,CAAC,KAAK,GAAG,EAAE,CAAC,SAAS,CAAC,SAAS;QAAE,OAAO,GAAG,IAAI,cAAc,CAAC;IACnE,IAAI,CAAC,CAAC,KAAK,GAAG,EAAE,CAAC,SAAS,CAAC,WAAW;QAAE,OAAO,UAAU,IAAI,cAAc,CAAC;IAC5E,IAAI,CAAC,CAAC,KAAK,GAAG,EAAE,CAAC,SAAS,CAAC,UAAU;QAAE,OAAO,UAAU,IAAI,aAAa,CAAC;IAC1E,IAAI,CAAC,CAAC,KAAK,GAAG,EAAE,CAAC,SAAS,CAAC,UAAU;QAAE,OAAO,UAAU,IAAI,aAAa,CAAC;IAC1E,IAAI,CAAC,CAAC,KAAK,GAAG,EAAE,CAAC,SAAS,CAAC,UAAU;QAAE,OAAO,UAAU,IAAI,aAAa,CAAC;IAC1E,IAAI,CAAC,CAAC,KAAK,GAAG,EAAE,CAAC,SAAS,CAAC,YAAY;QAAE,OAAO,UAAU,IAAI,aAAa,CAAC;IAC5E,OAAO,IAAI,CAAC;AACd,CAAC"}
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Handles union (A | B) and intersection (A & B) types.
|
|
3
|
-
*/
|
|
4
|
-
export function emitUnionOrIntersection(ctx, expr, t) {
|
|
5
|
-
if (t.isUnion()) {
|
|
6
|
-
return `(${t.types.map(tt => ctx.emit(expr, tt)).join("||")})`;
|
|
7
|
-
}
|
|
8
|
-
if (t.isIntersection()) {
|
|
9
|
-
return `(${t.types.map(tt => ctx.emit(expr, tt)).join("&&")})`;
|
|
10
|
-
}
|
|
11
|
-
return null;
|
|
12
|
-
}
|
|
13
|
-
//# sourceMappingURL=emitUnionOrIntersection.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"emitUnionOrIntersection.js","sourceRoot":"","sources":["../../src/core/emitUnionOrIntersection.ts"],"names":[],"mappings":"AAGA;;GAEG;AACH,MAAM,UAAU,uBAAuB,CAAC,GAAe,EAAE,IAAY,EAAE,CAAU;IAC/E,IAAI,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC;QAChB,OAAO,IAAI,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC;IACjE,CAAC;IACD,IAAI,CAAC,CAAC,cAAc,EAAE,EAAE,CAAC;QACvB,OAAO,IAAI,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC;IACjE,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC"}
|
package/dist/core/index.d.ts
DELETED
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
import ts from "typescript";
|
|
2
|
-
/**
|
|
3
|
-
* ✅ emitGuardFromType
|
|
4
|
-
* Converts a TypeScript type to a JavaScript runtime validation function string.
|
|
5
|
-
*/
|
|
6
|
-
export declare function emitGuardFromType(checker: ts.TypeChecker, type: ts.Type): string;
|
|
7
|
-
/**
|
|
8
|
-
* ✅ GenContext
|
|
9
|
-
* Internal helper for converting TypeScript types to JS validation expressions.
|
|
10
|
-
*/
|
|
11
|
-
export declare class GenContext {
|
|
12
|
-
checker: ts.TypeChecker;
|
|
13
|
-
private seen;
|
|
14
|
-
constructor(checker: ts.TypeChecker);
|
|
15
|
-
/** Top-level router — delegates each type to the correct handler. */
|
|
16
|
-
emit(expr: string, t: ts.Type): string;
|
|
17
|
-
}
|
package/dist/core/index.js
DELETED
|
@@ -1,37 +0,0 @@
|
|
|
1
|
-
import { emitPrimitive } from "./emitPrimitive";
|
|
2
|
-
import { emitLiteralOrEnum } from "./emitLiteralOrEnum";
|
|
3
|
-
import { emitUnionOrIntersection } from "./emitUnionOrIntersection";
|
|
4
|
-
import { emitArrayOrTuple } from "./emitArrayOrTuple";
|
|
5
|
-
import { emitObject } from "./emitObject";
|
|
6
|
-
/**
|
|
7
|
-
* ✅ emitGuardFromType
|
|
8
|
-
* Converts a TypeScript type to a JavaScript runtime validation function string.
|
|
9
|
-
*/
|
|
10
|
-
export function emitGuardFromType(checker, type) {
|
|
11
|
-
const ctx = new GenContext(checker);
|
|
12
|
-
const condition = ctx.emit("input", type);
|
|
13
|
-
return `(input)=>${condition}`;
|
|
14
|
-
}
|
|
15
|
-
/**
|
|
16
|
-
* ✅ GenContext
|
|
17
|
-
* Internal helper for converting TypeScript types to JS validation expressions.
|
|
18
|
-
*/
|
|
19
|
-
export class GenContext {
|
|
20
|
-
checker;
|
|
21
|
-
seen = new Map();
|
|
22
|
-
constructor(checker) {
|
|
23
|
-
this.checker = checker;
|
|
24
|
-
}
|
|
25
|
-
/** Top-level router — delegates each type to the correct handler. */
|
|
26
|
-
emit(expr, t) {
|
|
27
|
-
if (this.seen.has(t))
|
|
28
|
-
return this.seen.get(t);
|
|
29
|
-
return (emitPrimitive(this, expr, t) ??
|
|
30
|
-
emitLiteralOrEnum(this, expr, t) ??
|
|
31
|
-
emitUnionOrIntersection(this, expr, t) ??
|
|
32
|
-
emitArrayOrTuple(this, expr, t) ??
|
|
33
|
-
emitObject(this, expr, t) ??
|
|
34
|
-
"true");
|
|
35
|
-
}
|
|
36
|
-
}
|
|
37
|
-
//# sourceMappingURL=index.js.map
|
package/dist/core/index.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/core/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAChD,OAAO,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AACxD,OAAO,EAAE,uBAAuB,EAAE,MAAM,2BAA2B,CAAC;AACpE,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AACtD,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAE1C;;;GAGG;AACH,MAAM,UAAU,iBAAiB,CAAC,OAAuB,EAAE,IAAa;IACtE,MAAM,GAAG,GAAG,IAAI,UAAU,CAAC,OAAO,CAAC,CAAC;IACpC,MAAM,SAAS,GAAG,GAAG,CAAC,IAAI,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC;IAC1C,OAAO,YAAY,SAAS,EAAE,CAAC;AACjC,CAAC;AAED;;;GAGG;AACH,MAAM,OAAO,UAAU;IAGF;IAFX,IAAI,GAAG,IAAI,GAAG,EAAmB,CAAC;IAE1C,YAAmB,OAAuB;QAAvB,YAAO,GAAP,OAAO,CAAgB;IAAG,CAAC;IAE9C,qEAAqE;IACrE,IAAI,CAAC,IAAY,EAAE,CAAU;QAC3B,IAAI,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;YAAE,OAAO,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAE,CAAC;QAE/C,OAAO,CACL,aAAa,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC;YAC5B,iBAAiB,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC;YAChC,uBAAuB,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC;YACtC,gBAAgB,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC;YAC/B,UAAU,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC;YACzB,MAAM,CACP,CAAC;IACJ,CAAC;CACF"}
|
package/dist/index.d.ts
DELETED
package/dist/index.js
DELETED
package/dist/index.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,UAAU,EAAmB,MAAM,oBAAoB,CAAA;AAC9E,OAAO,EAAE,OAAO,IAAI,UAAU,EAAE,MAAM,2BAA2B,CAAA;AACjE,OAAO,EAAE,OAAO,IAAI,aAAa,EAAE,MAAM,8BAA8B,CAAA"}
|
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* runtypex — runtime APIs
|
|
3
|
-
* 1) makeValidate<T>() : (v) => v is T
|
|
4
|
-
* 2) makeAssert<T>() : throws on invalid
|
|
5
|
-
*
|
|
6
|
-
* NOTE: These factories are replaced at build-time by the transformer.
|
|
7
|
-
*/
|
|
8
|
-
export type ValidateFn<T> = (value: unknown) => value is T;
|
|
9
|
-
export declare function makeValidate<T>(): ValidateFn<T>;
|
|
10
|
-
export declare function makeAssert<T>(): (value: unknown) => asserts value is T;
|
package/dist/runtime/validate.js
DELETED
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
// Replaced by transformer to generated guard
|
|
2
|
-
function __validate(_value) {
|
|
3
|
-
throw new Error("[runtypex] makeValidate() was not transformed. Add the plugin/transformer.");
|
|
4
|
-
}
|
|
5
|
-
export function makeValidate() {
|
|
6
|
-
return (value) => __validate(value);
|
|
7
|
-
}
|
|
8
|
-
export function makeAssert() {
|
|
9
|
-
const validate = makeValidate();
|
|
10
|
-
return (value) => {
|
|
11
|
-
if (!validate(value))
|
|
12
|
-
throw new TypeError("[runtypex] Validation failed.");
|
|
13
|
-
};
|
|
14
|
-
}
|
|
15
|
-
//# sourceMappingURL=validate.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"validate.js","sourceRoot":"","sources":["../../src/runtime/validate.ts"],"names":[],"mappings":"AASA,6CAA6C;AAC7C,SAAS,UAAU,CAAI,MAAe;IACpC,MAAM,IAAI,KAAK,CAAC,4EAA4E,CAAC,CAAC;AAChG,CAAC;AAED,MAAM,UAAU,YAAY;IAC1B,OAAO,CAAC,KAAc,EAAc,EAAE,CAAC,UAAU,CAAI,KAAK,CAAC,CAAC;AAC9D,CAAC;AAED,MAAM,UAAU,UAAU;IACxB,MAAM,QAAQ,GAAG,YAAY,EAAK,CAAC;IAEnC,OAAO,CAAC,KAAc,EAAsB,EAAE;QAC5C,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC;YAAE,MAAM,IAAI,SAAS,CAAC,+BAA+B,CAAC,CAAC;IAC7E,CAAC,CAAC;AACJ,CAAC"}
|
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
import ts from "typescript";
|
|
2
|
-
/**
|
|
3
|
-
* 🧩 tsTransformer
|
|
4
|
-
* TypeScript custom transformer (BEFORE) factory.
|
|
5
|
-
*
|
|
6
|
-
* 📘 Usage (ts-loader / ttypescript):
|
|
7
|
-
* ```ts
|
|
8
|
-
* getCustomTransformers: (program) => ({
|
|
9
|
-
* before: [ tsTransformer({ program, removeInProd: true }) ]
|
|
10
|
-
* })
|
|
11
|
-
* ```
|
|
12
|
-
*
|
|
13
|
-
* 🧠 Purpose:
|
|
14
|
-
* - Replace makeValidate<T>(), makeAssert<T>() calls
|
|
15
|
-
* with *pre-generated runtime validation code* derived from T.
|
|
16
|
-
*
|
|
17
|
-
* 💡 Effect:
|
|
18
|
-
* ✅ No reflection or runtime type parsing
|
|
19
|
-
* ✅ Validation logic embedded at build-time
|
|
20
|
-
* ✅ Optionally removed in production builds
|
|
21
|
-
*/
|
|
22
|
-
export default function tsTransformer(options: {
|
|
23
|
-
program: ts.Program;
|
|
24
|
-
removeInProd?: boolean;
|
|
25
|
-
}): (context: ts.TransformationContext) => (sf: ts.SourceFile) => ts.Node | undefined;
|
|
@@ -1,98 +0,0 @@
|
|
|
1
|
-
import ts from "typescript";
|
|
2
|
-
import { emitGuardFromType } from "../core";
|
|
3
|
-
/**
|
|
4
|
-
* 🧩 tsTransformer
|
|
5
|
-
* TypeScript custom transformer (BEFORE) factory.
|
|
6
|
-
*
|
|
7
|
-
* 📘 Usage (ts-loader / ttypescript):
|
|
8
|
-
* ```ts
|
|
9
|
-
* getCustomTransformers: (program) => ({
|
|
10
|
-
* before: [ tsTransformer({ program, removeInProd: true }) ]
|
|
11
|
-
* })
|
|
12
|
-
* ```
|
|
13
|
-
*
|
|
14
|
-
* 🧠 Purpose:
|
|
15
|
-
* - Replace makeValidate<T>(), makeAssert<T>() calls
|
|
16
|
-
* with *pre-generated runtime validation code* derived from T.
|
|
17
|
-
*
|
|
18
|
-
* 💡 Effect:
|
|
19
|
-
* ✅ No reflection or runtime type parsing
|
|
20
|
-
* ✅ Validation logic embedded at build-time
|
|
21
|
-
* ✅ Optionally removed in production builds
|
|
22
|
-
*/
|
|
23
|
-
export default function tsTransformer(options) {
|
|
24
|
-
const { program } = options;
|
|
25
|
-
const checker = options.program.getTypeChecker();
|
|
26
|
-
const removeInProd = !!options.removeInProd;
|
|
27
|
-
const prod = process.env.NODE_ENV === "production";
|
|
28
|
-
return (context) => {
|
|
29
|
-
const visit = (node) => {
|
|
30
|
-
if (ts.isCallExpression(node) && ts.isIdentifier(node.expression)) {
|
|
31
|
-
const name = node.expression.text;
|
|
32
|
-
const targetFunctions = ["makeValidate", "makeAssert"];
|
|
33
|
-
if (targetFunctions.includes(name) && node.typeArguments?.length) {
|
|
34
|
-
const typeNode = node.typeArguments[0];
|
|
35
|
-
const typeName = typeNode.getText();
|
|
36
|
-
const type = _resolveTypeByName(program, node.getSourceFile(), checker, typeName);
|
|
37
|
-
if (!type)
|
|
38
|
-
return node;
|
|
39
|
-
const isRemovedInProd = removeInProd && prod;
|
|
40
|
-
switch (name) {
|
|
41
|
-
case "makeValidate":
|
|
42
|
-
return _emitMakeValidate(checker, type, isRemovedInProd);
|
|
43
|
-
case "makeAssert":
|
|
44
|
-
return _emitMakeAssert(checker, type, isRemovedInProd);
|
|
45
|
-
}
|
|
46
|
-
}
|
|
47
|
-
}
|
|
48
|
-
return ts.visitEachChild(node, visit, context);
|
|
49
|
-
};
|
|
50
|
-
return (sf) => ts.visitNode(sf, visit);
|
|
51
|
-
};
|
|
52
|
-
}
|
|
53
|
-
function _resolveTypeByName(program, sf, checker, name) {
|
|
54
|
-
for (const file of program.getSourceFiles()) {
|
|
55
|
-
const decl = _findLocalDeclaration(file, name);
|
|
56
|
-
if (!decl)
|
|
57
|
-
continue;
|
|
58
|
-
if (ts.isInterfaceDeclaration(decl) || ts.isClassDeclaration(decl) || ts.isEnumDeclaration(decl)) {
|
|
59
|
-
// @ts-ignore
|
|
60
|
-
const sym = checker.getSymbolAtLocation(decl.name);
|
|
61
|
-
if (sym)
|
|
62
|
-
return checker.getDeclaredTypeOfSymbol(sym);
|
|
63
|
-
}
|
|
64
|
-
if (ts.isTypeAliasDeclaration(decl)) {
|
|
65
|
-
return checker.getTypeFromTypeNode(decl.type);
|
|
66
|
-
}
|
|
67
|
-
}
|
|
68
|
-
const sym = checker
|
|
69
|
-
.getSymbolsInScope(sf, ts.SymbolFlags.Type | ts.SymbolFlags.Alias | ts.SymbolFlags.Interface)
|
|
70
|
-
.find((s) => s.name === name);
|
|
71
|
-
return sym ? checker.getDeclaredTypeOfSymbol(sym) : null;
|
|
72
|
-
}
|
|
73
|
-
function _findLocalDeclaration(sf, name) {
|
|
74
|
-
let found;
|
|
75
|
-
(function walk(node) {
|
|
76
|
-
if ((ts.isInterfaceDeclaration(node) ||
|
|
77
|
-
ts.isTypeAliasDeclaration(node) ||
|
|
78
|
-
ts.isEnumDeclaration(node) ||
|
|
79
|
-
ts.isClassDeclaration(node)) &&
|
|
80
|
-
node.name?.text === name) {
|
|
81
|
-
found = node;
|
|
82
|
-
return;
|
|
83
|
-
}
|
|
84
|
-
if (!found)
|
|
85
|
-
node.forEachChild(walk);
|
|
86
|
-
})(sf);
|
|
87
|
-
return found;
|
|
88
|
-
}
|
|
89
|
-
function _emitMakeValidate(checker, type, isRemovedInProd) {
|
|
90
|
-
const guard = isRemovedInProd ? "((_)=>true)" : emitGuardFromType(checker, type);
|
|
91
|
-
return ts.factory.createIdentifier(guard);
|
|
92
|
-
}
|
|
93
|
-
function _emitMakeAssert(checker, type, isRemovedInProd) {
|
|
94
|
-
const guard = isRemovedInProd ? "((_)=>{})" : emitGuardFromType(checker, type);
|
|
95
|
-
const txt = `(function(){const G=${guard};return(i)=>{if(!G(i))throw new TypeError("[runtypex] Validation failed.");};})()`;
|
|
96
|
-
return ts.factory.createIdentifier(txt);
|
|
97
|
-
}
|
|
98
|
-
//# sourceMappingURL=ts-transformer.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"ts-transformer.js","sourceRoot":"","sources":["../../src/transformer/ts-transformer.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
import type { Plugin } from "vite";
|
|
2
|
-
/**
|
|
3
|
-
* 🧩 vitePluginRuntypex
|
|
4
|
-
* A Vite plugin that performs build-time type → runtime validation transformation.
|
|
5
|
-
*
|
|
6
|
-
* 📘 Purpose
|
|
7
|
-
* - Replace calls like:
|
|
8
|
-
* makeValidate<T>(), makeAssert<T>()
|
|
9
|
-
* with *inline JavaScript guard functions* derived from TypeScript types.
|
|
10
|
-
*
|
|
11
|
-
* 💡 Features
|
|
12
|
-
* - Works in both dev & build mode
|
|
13
|
-
* - Optional: remove validation code in production (`removeInProd`)
|
|
14
|
-
* - Compatible with Rollup / Webpack (via Vite plugin API)
|
|
15
|
-
*/
|
|
16
|
-
export default function vitePluginRuntypex(options?: {
|
|
17
|
-
removeInProd?: boolean;
|
|
18
|
-
}): Plugin;
|