@xyd-js/source-react-runtime 0.0.0-build-23166ce-20260423151359
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/CHANGELOG.md +9 -0
- package/LICENSE +21 -0
- package/README.md +121 -0
- package/__fixtures__/-1.vite-lib.custom-property/input/package.json +8 -0
- package/__fixtures__/-1.vite-lib.custom-property/input/src/UserCard.tsx +27 -0
- package/__fixtures__/-1.vite-lib.custom-property/input/src/index.ts +1 -0
- package/__fixtures__/-1.vite-lib.custom-property/input/tsconfig.json +12 -0
- package/__fixtures__/-1.vite-lib.custom-property/input/vite.config.ts +22 -0
- package/__fixtures__/-1.vite-lib.custom-property/output.js +10 -0
- package/__fixtures__/1.vite-lib.user-card/input/package.json +8 -0
- package/__fixtures__/1.vite-lib.user-card/input/src/UserCard.tsx +27 -0
- package/__fixtures__/1.vite-lib.user-card/input/src/index.ts +1 -0
- package/__fixtures__/1.vite-lib.user-card/input/tsconfig.json +12 -0
- package/__fixtures__/1.vite-lib.user-card/input/vite.config.ts +22 -0
- package/__fixtures__/1.vite-lib.user-card/output.js +10 -0
- package/__fixtures__/2.vite-lib.sample-app/input/package.json +8 -0
- package/__fixtures__/2.vite-lib.sample-app/input/src/components/UserProfile.tsx +42 -0
- package/__fixtures__/2.vite-lib.sample-app/input/src/contexts/UserContext.tsx +27 -0
- package/__fixtures__/2.vite-lib.sample-app/input/src/index.ts +3 -0
- package/__fixtures__/2.vite-lib.sample-app/input/src/types/user.ts +18 -0
- package/__fixtures__/2.vite-lib.sample-app/input/tsconfig.json +12 -0
- package/__fixtures__/2.vite-lib.sample-app/input/vite.config.ts +22 -0
- package/__fixtures__/2.vite-lib.sample-app/output.js +27 -0
- package/__fixtures__/3.vite-lib.sample-real-app/input/package.json +8 -0
- package/__fixtures__/3.vite-lib.sample-real-app/input/src/components/AddTodoForm.tsx +51 -0
- package/__fixtures__/3.vite-lib.sample-real-app/input/src/components/FilterBar.tsx +56 -0
- package/__fixtures__/3.vite-lib.sample-real-app/input/src/components/StatsPanel.tsx +44 -0
- package/__fixtures__/3.vite-lib.sample-real-app/input/src/components/TodoItem.tsx +54 -0
- package/__fixtures__/3.vite-lib.sample-real-app/input/src/index.ts +6 -0
- package/__fixtures__/3.vite-lib.sample-real-app/input/src/types/todo.ts +23 -0
- package/__fixtures__/3.vite-lib.sample-real-app/input/tsconfig.json +12 -0
- package/__fixtures__/3.vite-lib.sample-real-app/input/vite.config.ts +22 -0
- package/__fixtures__/3.vite-lib.sample-real-app/output.js +63 -0
- package/__fixtures__/4.vite-app.user-card/input/package.json +8 -0
- package/__fixtures__/4.vite-app.user-card/input/src/UserCard.tsx +27 -0
- package/__fixtures__/4.vite-app.user-card/input/src/index.ts +1 -0
- package/__fixtures__/4.vite-app.user-card/input/tsconfig.json +12 -0
- package/__fixtures__/4.vite-app.user-card/input/vite.config.ts +23 -0
- package/__fixtures__/4.vite-app.user-card/output.js +10 -0
- package/__fixtures__/5.rollup.user-card/input/package.json +8 -0
- package/__fixtures__/5.rollup.user-card/input/rollup.config.mjs +20 -0
- package/__fixtures__/5.rollup.user-card/input/src/UserCard.tsx +27 -0
- package/__fixtures__/5.rollup.user-card/input/src/index.ts +1 -0
- package/__fixtures__/5.rollup.user-card/input/tsconfig.json +12 -0
- package/__fixtures__/5.rollup.user-card/output.js +11 -0
- package/__fixtures__/6.esbuild.user-card/input/esbuild.config.mjs +19 -0
- package/__fixtures__/6.esbuild.user-card/input/package.json +8 -0
- package/__fixtures__/6.esbuild.user-card/input/src/UserCard.tsx +27 -0
- package/__fixtures__/6.esbuild.user-card/input/src/index.ts +1 -0
- package/__fixtures__/6.esbuild.user-card/input/tsconfig.json +12 -0
- package/__fixtures__/6.esbuild.user-card/output.js +11 -0
- package/__fixtures__/7.react-router.app/input/app/components/ProductCard.tsx +26 -0
- package/__fixtures__/7.react-router.app/input/app/entry.server.tsx +36 -0
- package/__fixtures__/7.react-router.app/input/app/root.tsx +23 -0
- package/__fixtures__/7.react-router.app/input/app/routes/cart.tsx +16 -0
- package/__fixtures__/7.react-router.app/input/app/routes/home.tsx +29 -0
- package/__fixtures__/7.react-router.app/input/app/routes/product.tsx +6 -0
- package/__fixtures__/7.react-router.app/input/app/routes.ts +7 -0
- package/__fixtures__/7.react-router.app/input/app/types/product.ts +12 -0
- package/__fixtures__/7.react-router.app/input/package.json +8 -0
- package/__fixtures__/7.react-router.app/input/react-router.config.ts +2 -0
- package/__fixtures__/7.react-router.app/input/tsconfig.json +13 -0
- package/__fixtures__/7.react-router.app/input/vite.config.ts +14 -0
- package/__fixtures__/7.react-router.app/output.js +44 -0
- package/__fixtures__/8.tanstack-router.app/input/index.html +5 -0
- package/__fixtures__/8.tanstack-router.app/input/package.json +8 -0
- package/__fixtures__/8.tanstack-router.app/input/src/components/EmployeeTable.tsx +45 -0
- package/__fixtures__/8.tanstack-router.app/input/src/main.tsx +19 -0
- package/__fixtures__/8.tanstack-router.app/input/src/routeTree.gen.ts +77 -0
- package/__fixtures__/8.tanstack-router.app/input/src/routes/__root.tsx +13 -0
- package/__fixtures__/8.tanstack-router.app/input/src/routes/employees.tsx +23 -0
- package/__fixtures__/8.tanstack-router.app/input/src/routes/index.tsx +5 -0
- package/__fixtures__/8.tanstack-router.app/input/src/types/employee.ts +13 -0
- package/__fixtures__/8.tanstack-router.app/input/tsconfig.json +12 -0
- package/__fixtures__/8.tanstack-router.app/input/vite.config.ts +21 -0
- package/__fixtures__/8.tanstack-router.app/output.js +63 -0
- package/__tests__/source-react-runtime.test.ts +61 -0
- package/__tests__/utils.ts +100 -0
- package/dist/esbuild.d.ts +20 -0
- package/dist/esbuild.js +378 -0
- package/dist/esbuild.js.map +1 -0
- package/dist/index.d.ts +53 -0
- package/dist/index.js +348 -0
- package/dist/index.js.map +1 -0
- package/package.json +47 -0
- package/src/esbuild.ts +45 -0
- package/src/index.ts +437 -0
- package/src/json-schema-to-uniform.ts +108 -0
- package/tsconfig.json +16 -0
- package/tsconfig.tsup.json +6 -0
- package/tsup.config.ts +23 -0
- package/vitest.config.ts +7 -0
package/dist/esbuild.js
ADDED
|
@@ -0,0 +1,378 @@
|
|
|
1
|
+
// src/esbuild.ts
|
|
2
|
+
import * as fs from "fs";
|
|
3
|
+
|
|
4
|
+
// src/index.ts
|
|
5
|
+
import * as path from "path";
|
|
6
|
+
|
|
7
|
+
// src/json-schema-to-uniform.ts
|
|
8
|
+
import {
|
|
9
|
+
schemaObjectToUniformDefinitionProperties
|
|
10
|
+
} from "@xyd-js/openapi";
|
|
11
|
+
function jsonSchemaToUniformReference(componentName, schema) {
|
|
12
|
+
var _a;
|
|
13
|
+
const ref = {
|
|
14
|
+
title: componentName,
|
|
15
|
+
canonical: "",
|
|
16
|
+
description: "",
|
|
17
|
+
definitions: [],
|
|
18
|
+
examples: { groups: [] }
|
|
19
|
+
};
|
|
20
|
+
const rootSchema = resolveRootSchema(schema);
|
|
21
|
+
if (!rootSchema) return ref;
|
|
22
|
+
const schemas = ((_a = schema.components) == null ? void 0 : _a.schemas) || {};
|
|
23
|
+
const inlined = inlineRefs(rootSchema, schemas);
|
|
24
|
+
const result = schemaObjectToUniformDefinitionProperties(inlined);
|
|
25
|
+
const propsDef = {
|
|
26
|
+
title: "Props",
|
|
27
|
+
properties: [],
|
|
28
|
+
meta: [{ name: "type", value: "parameters" }]
|
|
29
|
+
};
|
|
30
|
+
if (Array.isArray(result)) {
|
|
31
|
+
propsDef.properties = result;
|
|
32
|
+
} else if (result) {
|
|
33
|
+
propsDef.rootProperty = result;
|
|
34
|
+
}
|
|
35
|
+
if (propsDef.properties.length > 0 || propsDef.rootProperty) {
|
|
36
|
+
ref.definitions.push(propsDef);
|
|
37
|
+
}
|
|
38
|
+
return ref;
|
|
39
|
+
}
|
|
40
|
+
function resolveRootSchema(output) {
|
|
41
|
+
var _a, _b, _c;
|
|
42
|
+
const rootRef = (_a = output.schemas) == null ? void 0 : _a[0];
|
|
43
|
+
if (!rootRef) return null;
|
|
44
|
+
if ("$ref" in rootRef && rootRef.$ref) {
|
|
45
|
+
const refPath = rootRef.$ref.replace("#/components/schemas/", "");
|
|
46
|
+
return ((_c = (_b = output.components) == null ? void 0 : _b.schemas) == null ? void 0 : _c[refPath]) || null;
|
|
47
|
+
}
|
|
48
|
+
return rootRef;
|
|
49
|
+
}
|
|
50
|
+
function inlineRefs(schema, schemas, visited = /* @__PURE__ */ new Set()) {
|
|
51
|
+
if (!schema || typeof schema !== "object") return schema;
|
|
52
|
+
if (schema.$ref) {
|
|
53
|
+
const refPath = schema.$ref.replace("#/components/schemas/", "");
|
|
54
|
+
if (visited.has(refPath)) {
|
|
55
|
+
return { type: "object", description: `(circular: ${refPath})` };
|
|
56
|
+
}
|
|
57
|
+
const resolved = schemas[refPath];
|
|
58
|
+
if (!resolved) return schema;
|
|
59
|
+
visited.add(refPath);
|
|
60
|
+
const result2 = inlineRefs({ ...resolved }, schemas, visited);
|
|
61
|
+
visited.delete(refPath);
|
|
62
|
+
return result2;
|
|
63
|
+
}
|
|
64
|
+
if (Array.isArray(schema)) {
|
|
65
|
+
return schema.map((item) => inlineRefs(item, schemas, visited));
|
|
66
|
+
}
|
|
67
|
+
const result = {};
|
|
68
|
+
for (const [key, value] of Object.entries(schema)) {
|
|
69
|
+
result[key] = inlineRefs(value, schemas, visited);
|
|
70
|
+
}
|
|
71
|
+
return result;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
// src/index.ts
|
|
75
|
+
function xydSourceReactRuntime(options) {
|
|
76
|
+
let transformedFiles = /* @__PURE__ */ new Map();
|
|
77
|
+
const propName = (options == null ? void 0 : options.propertyName) || "__xydUniform";
|
|
78
|
+
return {
|
|
79
|
+
name: "xyd-source-react-runtime",
|
|
80
|
+
enforce: "pre",
|
|
81
|
+
async buildStart() {
|
|
82
|
+
const tsconfigPath = (options == null ? void 0 : options.tsconfig) || path.resolve(process.cwd(), "tsconfig.json");
|
|
83
|
+
transformedFiles = await buildTypiaSchemas(tsconfigPath);
|
|
84
|
+
},
|
|
85
|
+
// Vite path: transform hook receives the original code
|
|
86
|
+
transform(code, id) {
|
|
87
|
+
if (!id.match(/\.[jt]sx?$/)) return null;
|
|
88
|
+
const transformed = transformedFiles.get(path.resolve(id));
|
|
89
|
+
if (!transformed) return null;
|
|
90
|
+
return convertSchemaToUniform(transformed, propName);
|
|
91
|
+
},
|
|
92
|
+
// Rollup path: load hook returns our compiled JS before Rollup's parser
|
|
93
|
+
load(id) {
|
|
94
|
+
if (!id.match(/\.[jt]sx?$/)) return null;
|
|
95
|
+
const transformed = transformedFiles.get(path.resolve(id));
|
|
96
|
+
if (!transformed) return null;
|
|
97
|
+
return convertSchemaToUniform(transformed, propName);
|
|
98
|
+
}
|
|
99
|
+
};
|
|
100
|
+
}
|
|
101
|
+
async function buildTypiaSchemas(tsconfigPath) {
|
|
102
|
+
const result = /* @__PURE__ */ new Map();
|
|
103
|
+
let ts;
|
|
104
|
+
let typiaTransformModule;
|
|
105
|
+
try {
|
|
106
|
+
ts = await import("typescript");
|
|
107
|
+
typiaTransformModule = await import("typia/lib/transform");
|
|
108
|
+
} catch {
|
|
109
|
+
console.warn("[xyd-source-react-runtime] typia or typescript not found");
|
|
110
|
+
return result;
|
|
111
|
+
}
|
|
112
|
+
const configFile = ts.readConfigFile(tsconfigPath, ts.sys.readFile);
|
|
113
|
+
const parsedConfig = ts.parseJsonConfigFileContent(
|
|
114
|
+
configFile.config,
|
|
115
|
+
ts.sys,
|
|
116
|
+
path.dirname(tsconfigPath)
|
|
117
|
+
);
|
|
118
|
+
const componentsByFile = /* @__PURE__ */ new Map();
|
|
119
|
+
for (const fileName of parsedConfig.fileNames) {
|
|
120
|
+
const content = ts.sys.readFile(fileName);
|
|
121
|
+
if (!content) continue;
|
|
122
|
+
const components = detectComponents(ts, content, fileName);
|
|
123
|
+
if (components.length > 0) {
|
|
124
|
+
componentsByFile.set(fileName, components);
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
if (componentsByFile.size === 0) return result;
|
|
128
|
+
const modifiedSources = /* @__PURE__ */ new Map();
|
|
129
|
+
for (const [fileName, components] of componentsByFile) {
|
|
130
|
+
const supported = components.filter((c) => !c.propsType.includes("React."));
|
|
131
|
+
if (supported.length === 0) continue;
|
|
132
|
+
const original = ts.sys.readFile(fileName);
|
|
133
|
+
let modified = `import typia from "typia";
|
|
134
|
+
${original}`;
|
|
135
|
+
for (const comp of supported) {
|
|
136
|
+
modified += `
|
|
137
|
+
${comp.name}.__xydSchema = typia.json.schemas<[${comp.propsType}]>();`;
|
|
138
|
+
}
|
|
139
|
+
modifiedSources.set(fileName, modified);
|
|
140
|
+
}
|
|
141
|
+
const compilerHost = ts.createCompilerHost(parsedConfig.options);
|
|
142
|
+
const origGetSourceFile = compilerHost.getSourceFile;
|
|
143
|
+
const origFileExists = compilerHost.fileExists;
|
|
144
|
+
const origReadFile = compilerHost.readFile;
|
|
145
|
+
compilerHost.getSourceFile = (name, languageVersion, onError) => {
|
|
146
|
+
const resolved = path.resolve(name);
|
|
147
|
+
const modified = modifiedSources.get(resolved);
|
|
148
|
+
if (modified) {
|
|
149
|
+
return ts.createSourceFile(
|
|
150
|
+
name,
|
|
151
|
+
modified,
|
|
152
|
+
languageVersion,
|
|
153
|
+
true,
|
|
154
|
+
name.endsWith(".tsx") ? ts.ScriptKind.TSX : ts.ScriptKind.TS
|
|
155
|
+
);
|
|
156
|
+
}
|
|
157
|
+
return origGetSourceFile.call(compilerHost, name, languageVersion, onError);
|
|
158
|
+
};
|
|
159
|
+
compilerHost.fileExists = (name) => {
|
|
160
|
+
if (modifiedSources.has(path.resolve(name))) return true;
|
|
161
|
+
return origFileExists.call(compilerHost, name);
|
|
162
|
+
};
|
|
163
|
+
compilerHost.readFile = (name) => {
|
|
164
|
+
const modified = modifiedSources.get(path.resolve(name));
|
|
165
|
+
if (modified) return modified;
|
|
166
|
+
return origReadFile.call(compilerHost, name);
|
|
167
|
+
};
|
|
168
|
+
const program = ts.createProgram({
|
|
169
|
+
rootNames: parsedConfig.fileNames,
|
|
170
|
+
options: { ...parsedConfig.options, noEmit: false, declaration: false, sourceMap: false },
|
|
171
|
+
host: compilerHost
|
|
172
|
+
});
|
|
173
|
+
const factory = (typiaTransformModule.default || typiaTransformModule)(program);
|
|
174
|
+
for (const fileName of componentsByFile.keys()) {
|
|
175
|
+
const sourceFile = program.getSourceFile(fileName);
|
|
176
|
+
if (!sourceFile) continue;
|
|
177
|
+
try {
|
|
178
|
+
let output = "";
|
|
179
|
+
program.emit(
|
|
180
|
+
sourceFile,
|
|
181
|
+
(_name, text) => {
|
|
182
|
+
if (!_name.endsWith(".d.ts")) {
|
|
183
|
+
output = text;
|
|
184
|
+
}
|
|
185
|
+
},
|
|
186
|
+
void 0,
|
|
187
|
+
false,
|
|
188
|
+
{ before: [factory] }
|
|
189
|
+
);
|
|
190
|
+
if (output) {
|
|
191
|
+
result.set(path.resolve(fileName), output);
|
|
192
|
+
}
|
|
193
|
+
} catch (e) {
|
|
194
|
+
console.warn(`[xyd-source-react-runtime] typia transform failed for ${fileName}, skipping`);
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
return result;
|
|
198
|
+
}
|
|
199
|
+
function detectComponents(ts, code, fileName) {
|
|
200
|
+
const sourceFile = ts.createSourceFile(
|
|
201
|
+
fileName,
|
|
202
|
+
code,
|
|
203
|
+
ts.ScriptTarget.Latest,
|
|
204
|
+
true,
|
|
205
|
+
fileName.endsWith(".tsx") ? ts.ScriptKind.TSX : ts.ScriptKind.TS
|
|
206
|
+
);
|
|
207
|
+
const components = [];
|
|
208
|
+
ts.forEachChild(sourceFile, (node) => {
|
|
209
|
+
if (ts.isFunctionDeclaration(node) && node.name && isExported(ts, node)) {
|
|
210
|
+
const name = node.name.text;
|
|
211
|
+
if (!isPascalCase(name)) return;
|
|
212
|
+
const propsType = extractPropsType(ts, node, sourceFile);
|
|
213
|
+
if (propsType) {
|
|
214
|
+
components.push({ name, propsType, fileName });
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
if (ts.isVariableStatement(node) && isExported(ts, node)) {
|
|
218
|
+
for (const decl of node.declarationList.declarations) {
|
|
219
|
+
if (!ts.isIdentifier(decl.name)) continue;
|
|
220
|
+
const name = decl.name.text;
|
|
221
|
+
if (!isPascalCase(name)) continue;
|
|
222
|
+
if (!decl.initializer) continue;
|
|
223
|
+
if (ts.isArrowFunction(decl.initializer) || ts.isFunctionExpression(decl.initializer)) {
|
|
224
|
+
const propsType = extractPropsTypeFromParams(ts, decl.initializer.parameters, sourceFile);
|
|
225
|
+
if (propsType) {
|
|
226
|
+
components.push({ name, propsType, fileName });
|
|
227
|
+
}
|
|
228
|
+
continue;
|
|
229
|
+
}
|
|
230
|
+
const contextType = extractCreateContextType(ts, decl.initializer, sourceFile);
|
|
231
|
+
if (contextType) {
|
|
232
|
+
components.push({ name, propsType: contextType, fileName });
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
});
|
|
237
|
+
const foundNames = new Set(components.map((c) => c.name));
|
|
238
|
+
const reExportedNames = /* @__PURE__ */ new Set();
|
|
239
|
+
ts.forEachChild(sourceFile, (node) => {
|
|
240
|
+
if (ts.isExportDeclaration(node) && node.exportClause && ts.isNamedExports(node.exportClause)) {
|
|
241
|
+
for (const spec of node.exportClause.elements) {
|
|
242
|
+
reExportedNames.add(spec.name.text);
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
});
|
|
246
|
+
ts.forEachChild(sourceFile, (node) => {
|
|
247
|
+
if (ts.isFunctionDeclaration(node) && node.name && !isExported(ts, node)) {
|
|
248
|
+
const name = node.name.text;
|
|
249
|
+
if (!isPascalCase(name) || foundNames.has(name) || !reExportedNames.has(name)) return;
|
|
250
|
+
const propsType = extractPropsType(ts, node, sourceFile);
|
|
251
|
+
if (propsType) {
|
|
252
|
+
components.push({ name, propsType, fileName });
|
|
253
|
+
foundNames.add(name);
|
|
254
|
+
}
|
|
255
|
+
}
|
|
256
|
+
if (ts.isVariableStatement(node) && !isExported(ts, node)) {
|
|
257
|
+
for (const decl of node.declarationList.declarations) {
|
|
258
|
+
if (!ts.isIdentifier(decl.name)) continue;
|
|
259
|
+
const name = decl.name.text;
|
|
260
|
+
if (!isPascalCase(name) || foundNames.has(name) || !reExportedNames.has(name)) continue;
|
|
261
|
+
if (!decl.initializer) continue;
|
|
262
|
+
if (ts.isArrowFunction(decl.initializer) || ts.isFunctionExpression(decl.initializer)) {
|
|
263
|
+
const propsType = extractPropsTypeFromParams(ts, decl.initializer.parameters, sourceFile);
|
|
264
|
+
if (propsType) {
|
|
265
|
+
components.push({ name, propsType, fileName });
|
|
266
|
+
foundNames.add(name);
|
|
267
|
+
}
|
|
268
|
+
continue;
|
|
269
|
+
}
|
|
270
|
+
const contextType = extractCreateContextType(ts, decl.initializer, sourceFile);
|
|
271
|
+
if (contextType) {
|
|
272
|
+
components.push({ name, propsType: contextType, fileName });
|
|
273
|
+
foundNames.add(name);
|
|
274
|
+
}
|
|
275
|
+
}
|
|
276
|
+
}
|
|
277
|
+
});
|
|
278
|
+
return components;
|
|
279
|
+
}
|
|
280
|
+
function extractCreateContextType(ts, initializer, sourceFile) {
|
|
281
|
+
if (!ts.isCallExpression(initializer)) return null;
|
|
282
|
+
const callee = initializer.expression;
|
|
283
|
+
const isCreateContext = ts.isIdentifier(callee) && callee.text === "createContext" || ts.isPropertyAccessExpression(callee) && callee.name.text === "createContext";
|
|
284
|
+
if (!isCreateContext) return null;
|
|
285
|
+
const typeArgs = initializer.typeArguments;
|
|
286
|
+
if (!typeArgs || typeArgs.length === 0) return null;
|
|
287
|
+
const typeArg = typeArgs[0];
|
|
288
|
+
if (ts.isUnionTypeNode(typeArg)) {
|
|
289
|
+
const nonNullTypes = typeArg.types.filter(
|
|
290
|
+
(t) => !(ts.isLiteralTypeNode(t) && t.literal.kind === ts.SyntaxKind.NullKeyword) && !(t.kind === ts.SyntaxKind.UndefinedKeyword)
|
|
291
|
+
);
|
|
292
|
+
if (nonNullTypes.length === 1) {
|
|
293
|
+
return nonNullTypes[0].getText(sourceFile);
|
|
294
|
+
}
|
|
295
|
+
return nonNullTypes.map((t) => t.getText(sourceFile)).join(" | ");
|
|
296
|
+
}
|
|
297
|
+
return typeArg.getText(sourceFile);
|
|
298
|
+
}
|
|
299
|
+
function isExported(ts, node) {
|
|
300
|
+
var _a;
|
|
301
|
+
return ((_a = node.modifiers) == null ? void 0 : _a.some((m) => m.kind === ts.SyntaxKind.ExportKeyword)) ?? false;
|
|
302
|
+
}
|
|
303
|
+
function isPascalCase(name) {
|
|
304
|
+
return /^[A-Z]/.test(name);
|
|
305
|
+
}
|
|
306
|
+
function extractPropsType(ts, node, sourceFile) {
|
|
307
|
+
return extractPropsTypeFromParams(ts, node.parameters, sourceFile);
|
|
308
|
+
}
|
|
309
|
+
function extractPropsTypeFromParams(ts, parameters, sourceFile) {
|
|
310
|
+
if (parameters.length === 0) return null;
|
|
311
|
+
const firstParam = parameters[0];
|
|
312
|
+
if (firstParam.type && ts.isTypeReferenceNode(firstParam.type)) {
|
|
313
|
+
return firstParam.type.getText(sourceFile);
|
|
314
|
+
}
|
|
315
|
+
if (firstParam.type && ts.isTypeReferenceNode(firstParam.type) && ts.isObjectBindingPattern(firstParam.name)) {
|
|
316
|
+
return firstParam.type.getText(sourceFile);
|
|
317
|
+
}
|
|
318
|
+
if (ts.isObjectBindingPattern(firstParam.name) && firstParam.type) {
|
|
319
|
+
return firstParam.type.getText(sourceFile);
|
|
320
|
+
}
|
|
321
|
+
return null;
|
|
322
|
+
}
|
|
323
|
+
function convertSchemaToUniform(code, propertyName = "__xydUniform") {
|
|
324
|
+
const schemaRegex = /(\w+)\.__xydSchema\s*=\s*(\{[\s\S]*?\n\});/g;
|
|
325
|
+
let modified = code;
|
|
326
|
+
let hasChanges = false;
|
|
327
|
+
let match;
|
|
328
|
+
while ((match = schemaRegex.exec(code)) !== null) {
|
|
329
|
+
const componentName = match[1];
|
|
330
|
+
const schemaStr = match[2];
|
|
331
|
+
try {
|
|
332
|
+
const schema = new Function(`return ${schemaStr}`)();
|
|
333
|
+
const uniform = jsonSchemaToUniformReference(componentName, schema);
|
|
334
|
+
const jsonStr = JSON.stringify(uniform).replace(/\\/g, "\\\\").replace(/'/g, "\\'");
|
|
335
|
+
modified = modified.replace(
|
|
336
|
+
match[0],
|
|
337
|
+
`${componentName}.${propertyName} = JSON.parse('${jsonStr}');`
|
|
338
|
+
);
|
|
339
|
+
hasChanges = true;
|
|
340
|
+
} catch (e) {
|
|
341
|
+
console.warn(`[xyd-source-react-runtime] Failed to parse schema for ${componentName}:`, e);
|
|
342
|
+
}
|
|
343
|
+
}
|
|
344
|
+
if (!hasChanges) return null;
|
|
345
|
+
return { code: modified, map: null };
|
|
346
|
+
}
|
|
347
|
+
|
|
348
|
+
// src/esbuild.ts
|
|
349
|
+
function xydSourceReactRuntimeEsbuild(options) {
|
|
350
|
+
const vitePlugin = xydSourceReactRuntime(options);
|
|
351
|
+
return {
|
|
352
|
+
name: "xyd-source-react-runtime",
|
|
353
|
+
setup(build) {
|
|
354
|
+
build.onStart(async () => {
|
|
355
|
+
if (typeof vitePlugin.buildStart === "function") {
|
|
356
|
+
await vitePlugin.buildStart.call(vitePlugin);
|
|
357
|
+
}
|
|
358
|
+
});
|
|
359
|
+
build.onLoad({ filter: /\.[jt]sx?$/ }, async (args) => {
|
|
360
|
+
var _a, _b, _c, _d;
|
|
361
|
+
const code = fs.readFileSync(args.path, "utf-8");
|
|
362
|
+
const result = ((_b = (_a = vitePlugin.transform) == null ? void 0 : _a.call) == null ? void 0 : _b.call(_a, vitePlugin, code, args.path)) ?? ((_d = (_c = vitePlugin.load) == null ? void 0 : _c.call) == null ? void 0 : _d.call(_c, vitePlugin, args.path));
|
|
363
|
+
if (result) {
|
|
364
|
+
const contents = typeof result === "string" ? result : result.code;
|
|
365
|
+
return {
|
|
366
|
+
contents,
|
|
367
|
+
loader: args.path.endsWith(".tsx") ? "tsx" : args.path.endsWith(".ts") ? "ts" : "js"
|
|
368
|
+
};
|
|
369
|
+
}
|
|
370
|
+
return void 0;
|
|
371
|
+
});
|
|
372
|
+
}
|
|
373
|
+
};
|
|
374
|
+
}
|
|
375
|
+
export {
|
|
376
|
+
xydSourceReactRuntimeEsbuild
|
|
377
|
+
};
|
|
378
|
+
//# sourceMappingURL=esbuild.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/esbuild.ts","../src/index.ts","../src/json-schema-to-uniform.ts"],"sourcesContent":["import * as fs from 'node:fs';\nimport type {Plugin as EsbuildPlugin} from 'esbuild';\nimport {xydSourceReactRuntime, type XydSourceReactRuntimeOptions} from './index';\n\n/**\n * esbuild plugin adapter for xyd-source-react-runtime.\n *\n * ```js\n * import {xydSourceReactRuntimeEsbuild} from '@xyd-js/source-react-runtime/esbuild';\n *\n * await esbuild.build({\n * entryPoints: ['src/index.ts'],\n * plugins: [xydSourceReactRuntimeEsbuild({tsconfig: './tsconfig.json'})],\n * });\n * ```\n */\nexport function xydSourceReactRuntimeEsbuild(options?: XydSourceReactRuntimeOptions): EsbuildPlugin {\n const vitePlugin = xydSourceReactRuntime(options);\n\n return {\n name: 'xyd-source-react-runtime',\n setup(build) {\n build.onStart(async () => {\n if (typeof (vitePlugin as any).buildStart === 'function') {\n await (vitePlugin as any).buildStart.call(vitePlugin);\n }\n });\n\n build.onLoad({filter: /\\.[jt]sx?$/}, async (args) => {\n const code = fs.readFileSync(args.path, 'utf-8');\n const result = (vitePlugin as any).transform?.call?.(vitePlugin, code, args.path)\n ?? (vitePlugin as any).load?.call?.(vitePlugin, args.path);\n\n if (result) {\n const contents = typeof result === 'string' ? result : result.code;\n return {\n contents,\n loader: args.path.endsWith('.tsx') ? 'tsx' : args.path.endsWith('.ts') ? 'ts' : 'js',\n };\n }\n return undefined;\n });\n },\n };\n}\n","import * as path from 'node:path';\nimport * as fs from 'node:fs';\nimport type {Plugin} from 'vite';\nimport {jsonSchemaToUniformReference} from './json-schema-to-uniform';\n\nexport {jsonSchemaToUniformReference} from './json-schema-to-uniform';\n\nexport interface XydSourceReactRuntimeOptions {\n /** Path to tsconfig.json. Required for typia's TypeScript transform. */\n tsconfig?: string;\n /** Property name for the injected uniform data. Defaults to `__xydUniform`. */\n propertyName?: string;\n}\n\ninterface ComponentInfo {\n name: string;\n propsType: string;\n fileName: string;\n}\n\n/**\n * Vite plugin that auto-detects React components, uses typia to generate\n * JSON Schema from their props at build time, and injects `__xydUniform`.\n *\n * No manual annotations needed — the plugin:\n * 1. Scans source files for exported functions with typed props\n * 2. Injects `typia.json.schemas<[PropsType]>()` calls\n * 3. Runs typia's TS transform to resolve all types (cross-file, generics, etc.)\n * 4. Converts JSON Schema → xyd uniform format\n * 5. Injects `Component.__xydUniform = JSON.parse('...')`\n *\n * ```ts\n * import react from '@vitejs/plugin-react';\n * import { xydSourceReactRuntime } from '@xyd-js/source-react-runtime';\n *\n * export default defineConfig({\n * plugins: [\n * xydSourceReactRuntime({ tsconfig: './tsconfig.json' }),\n * react(),\n * ],\n * });\n * ```\n */\nexport function xydSourceReactRuntime(options?: XydSourceReactRuntimeOptions): Plugin {\n // Map of fileName → typia-transformed output with __xydSchema injected\n let transformedFiles: Map<string, string> = new Map();\n const propName = options?.propertyName || '__xydUniform';\n\n return {\n name: 'xyd-source-react-runtime',\n enforce: 'pre',\n\n async buildStart() {\n const tsconfigPath = options?.tsconfig || path.resolve(process.cwd(), 'tsconfig.json');\n transformedFiles = await buildTypiaSchemas(tsconfigPath);\n },\n\n // Vite path: transform hook receives the original code\n transform(code, id) {\n if (!id.match(/\\.[jt]sx?$/)) return null;\n\n const transformed = transformedFiles.get(path.resolve(id));\n if (!transformed) return null;\n\n return convertSchemaToUniform(transformed, propName);\n },\n\n // Rollup path: load hook returns our compiled JS before Rollup's parser\n load(id) {\n if (!id.match(/\\.[jt]sx?$/)) return null;\n\n const transformed = transformedFiles.get(path.resolve(id));\n if (!transformed) return null;\n\n return convertSchemaToUniform(transformed, propName);\n },\n };\n}\n\n/**\n * Scans all source files, detects React components, injects typia calls,\n * and runs typia transform to generate JSON schemas.\n */\nasync function buildTypiaSchemas(tsconfigPath: string): Promise<Map<string, string>> {\n const result = new Map<string, string>();\n\n let ts: typeof import('typescript');\n let typiaTransformModule: any;\n\n try {\n ts = await import('typescript');\n typiaTransformModule = await import('typia/lib/transform');\n } catch {\n console.warn('[xyd-source-react-runtime] typia or typescript not found');\n return result;\n }\n\n const configFile = ts.readConfigFile(tsconfigPath, ts.sys.readFile);\n const parsedConfig = ts.parseJsonConfigFileContent(\n configFile.config,\n ts.sys,\n path.dirname(tsconfigPath),\n );\n\n // Step 1: Scan source files for exported React components\n const componentsByFile = new Map<string, ComponentInfo[]>();\n\n for (const fileName of parsedConfig.fileNames) {\n const content = ts.sys.readFile(fileName);\n if (!content) continue;\n\n const components = detectComponents(ts, content, fileName);\n if (components.length > 0) {\n componentsByFile.set(fileName, components);\n }\n }\n\n if (componentsByFile.size === 0) return result;\n\n // Step 2: Create modified source files with typia calls injected\n const modifiedSources = new Map<string, string>();\n\n for (const [fileName, components] of componentsByFile) {\n // Filter out components whose propsType is an inline type literal with\n // React types (e.g. { children: React.ReactNode }) — typia can't resolve these\n const supported = components.filter(c => !c.propsType.includes('React.'));\n\n if (supported.length === 0) continue;\n\n const original = ts.sys.readFile(fileName)!;\n let modified = `import typia from \"typia\";\\n${original}`;\n\n for (const comp of supported) {\n modified += `\\n${comp.name}.__xydSchema = typia.json.schemas<[${comp.propsType}]>();`;\n }\n\n modifiedSources.set(fileName, modified);\n }\n\n // Step 3: Create a TS program with modified sources for typia transform\n const compilerHost = ts.createCompilerHost(parsedConfig.options);\n const origGetSourceFile = compilerHost.getSourceFile;\n const origFileExists = compilerHost.fileExists;\n const origReadFile = compilerHost.readFile;\n\n compilerHost.getSourceFile = (name, languageVersion, onError) => {\n const resolved = path.resolve(name);\n const modified = modifiedSources.get(resolved);\n if (modified) {\n return ts.createSourceFile(\n name, modified, languageVersion, true,\n name.endsWith('.tsx') ? ts.ScriptKind.TSX : ts.ScriptKind.TS,\n );\n }\n return origGetSourceFile.call(compilerHost, name, languageVersion, onError);\n };\n\n compilerHost.fileExists = (name) => {\n if (modifiedSources.has(path.resolve(name))) return true;\n return origFileExists.call(compilerHost, name);\n };\n\n compilerHost.readFile = (name) => {\n const modified = modifiedSources.get(path.resolve(name));\n if (modified) return modified;\n return origReadFile.call(compilerHost, name);\n };\n\n const program = ts.createProgram({\n rootNames: parsedConfig.fileNames,\n options: {...parsedConfig.options, noEmit: false, declaration: false, sourceMap: false},\n host: compilerHost,\n });\n\n const factory = (typiaTransformModule.default || typiaTransformModule)(program);\n\n // Step 4: Emit typia-transformed output for each file with components\n for (const fileName of componentsByFile.keys()) {\n const sourceFile = program.getSourceFile(fileName);\n if (!sourceFile) continue;\n\n try {\n let output = '';\n program.emit(\n sourceFile,\n (_name: string, text: string) => {\n if (!_name.endsWith('.d.ts')) {\n output = text;\n }\n },\n undefined,\n false,\n {before: [factory]},\n );\n\n if (output) {\n result.set(path.resolve(fileName), output);\n }\n } catch (e) {\n // typia transform can fail on files with unresolvable types (e.g. React.ReactNode)\n // Skip these files — their components won't get __xydUniform\n console.warn(`[xyd-source-react-runtime] typia transform failed for ${fileName}, skipping`);\n }\n }\n\n return result;\n}\n\n/**\n * Detects exported React components and their props type names using TS AST.\n */\nfunction detectComponents(\n ts: typeof import('typescript'),\n code: string,\n fileName: string,\n): ComponentInfo[] {\n const sourceFile = ts.createSourceFile(\n fileName, code, ts.ScriptTarget.Latest, true,\n fileName.endsWith('.tsx') ? ts.ScriptKind.TSX : ts.ScriptKind.TS,\n );\n\n const components: ComponentInfo[] = [];\n\n ts.forEachChild(sourceFile, (node) => {\n // export function ComponentName(props: PropsType) { ... }\n if (ts.isFunctionDeclaration(node) && node.name && isExported(ts, node)) {\n const name = node.name.text;\n if (!isPascalCase(name)) return;\n\n const propsType = extractPropsType(ts, node, sourceFile);\n if (propsType) {\n components.push({name, propsType, fileName});\n }\n }\n\n // export const ComponentName = (props: PropsType) => { ... }\n // export const SomeContext = createContext<ValueType>(...)\n if (ts.isVariableStatement(node) && isExported(ts, node)) {\n for (const decl of node.declarationList.declarations) {\n if (!ts.isIdentifier(decl.name)) continue;\n const name = decl.name.text;\n if (!isPascalCase(name)) continue;\n\n if (!decl.initializer) continue;\n\n // Arrow function / function expression → component\n if (ts.isArrowFunction(decl.initializer) || ts.isFunctionExpression(decl.initializer)) {\n const propsType = extractPropsTypeFromParams(ts, decl.initializer.parameters, sourceFile);\n if (propsType) {\n components.push({name, propsType, fileName});\n }\n continue;\n }\n\n // createContext<T>(...) → context\n const contextType = extractCreateContextType(ts, decl.initializer, sourceFile);\n if (contextType) {\n components.push({name, propsType: contextType, fileName});\n }\n }\n }\n });\n\n // Also detect non-inline exports: declarations + export { Name }\n // Collect all PascalCase declarations that weren't already found\n const foundNames = new Set(components.map(c => c.name));\n const reExportedNames = new Set<string>();\n\n // Find all names in export { ... } blocks\n ts.forEachChild(sourceFile, (node) => {\n if (ts.isExportDeclaration(node) && node.exportClause && ts.isNamedExports(node.exportClause)) {\n for (const spec of node.exportClause.elements) {\n reExportedNames.add(spec.name.text);\n }\n }\n });\n\n // Find non-exported declarations that are re-exported\n ts.forEachChild(sourceFile, (node) => {\n // function Name(...) { ... } (not exported inline)\n if (ts.isFunctionDeclaration(node) && node.name && !isExported(ts, node)) {\n const name = node.name.text;\n if (!isPascalCase(name) || foundNames.has(name) || !reExportedNames.has(name)) return;\n\n const propsType = extractPropsType(ts, node, sourceFile);\n if (propsType) {\n components.push({name, propsType, fileName});\n foundNames.add(name);\n }\n }\n\n // const Name = createContext<T>(...) or const Name = (...) => { ... }\n if (ts.isVariableStatement(node) && !isExported(ts, node)) {\n for (const decl of node.declarationList.declarations) {\n if (!ts.isIdentifier(decl.name)) continue;\n const name = decl.name.text;\n if (!isPascalCase(name) || foundNames.has(name) || !reExportedNames.has(name)) continue;\n if (!decl.initializer) continue;\n\n // Arrow/function expression\n if (ts.isArrowFunction(decl.initializer) || ts.isFunctionExpression(decl.initializer)) {\n const propsType = extractPropsTypeFromParams(ts, decl.initializer.parameters, sourceFile);\n if (propsType) {\n components.push({name, propsType, fileName});\n foundNames.add(name);\n }\n continue;\n }\n\n // createContext<T>(...)\n const contextType = extractCreateContextType(ts, decl.initializer, sourceFile);\n if (contextType) {\n components.push({name, propsType: contextType, fileName});\n foundNames.add(name);\n }\n }\n }\n });\n\n return components;\n}\n\n/**\n * Extracts the type argument from createContext<T>() calls.\n * Handles: createContext<T | null>() → strips null from union, returns T.\n */\nfunction extractCreateContextType(\n ts: typeof import('typescript'),\n initializer: import('typescript').Expression,\n sourceFile: import('typescript').SourceFile,\n): string | null {\n if (!ts.isCallExpression(initializer)) return null;\n\n // Match createContext(...) or React.createContext(...)\n const callee = initializer.expression;\n const isCreateContext =\n (ts.isIdentifier(callee) && callee.text === 'createContext') ||\n (ts.isPropertyAccessExpression(callee) && callee.name.text === 'createContext');\n\n if (!isCreateContext) return null;\n\n // Get type arguments: createContext<T>(...)\n const typeArgs = initializer.typeArguments;\n if (!typeArgs || typeArgs.length === 0) return null;\n\n const typeArg = typeArgs[0];\n\n // If it's a union like T | null, strip null/undefined and return T\n if (ts.isUnionTypeNode(typeArg)) {\n const nonNullTypes = typeArg.types.filter(\n (t) => !(ts.isLiteralTypeNode(t) && t.literal.kind === ts.SyntaxKind.NullKeyword) &&\n !(t.kind === ts.SyntaxKind.UndefinedKeyword),\n );\n if (nonNullTypes.length === 1) {\n return nonNullTypes[0].getText(sourceFile);\n }\n // Multiple non-null types — keep as union\n return nonNullTypes.map(t => t.getText(sourceFile)).join(' | ');\n }\n\n return typeArg.getText(sourceFile);\n}\n\nfunction isExported(ts: typeof import('typescript'), node: any): boolean {\n return node.modifiers?.some((m: any) => m.kind === ts.SyntaxKind.ExportKeyword) ?? false;\n}\n\nfunction isPascalCase(name: string): boolean {\n return /^[A-Z]/.test(name);\n}\n\nfunction extractPropsType(\n ts: typeof import('typescript'),\n node: import('typescript').FunctionDeclaration,\n sourceFile: import('typescript').SourceFile,\n): string | null {\n return extractPropsTypeFromParams(ts, node.parameters, sourceFile);\n}\n\nfunction extractPropsTypeFromParams(\n ts: typeof import('typescript'),\n parameters: import('typescript').NodeArray<import('typescript').ParameterDeclaration>,\n sourceFile: import('typescript').SourceFile,\n): string | null {\n if (parameters.length === 0) return null;\n\n const firstParam = parameters[0];\n\n // props: PropsType\n if (firstParam.type && ts.isTypeReferenceNode(firstParam.type)) {\n return firstParam.type.getText(sourceFile);\n }\n\n // { prop1, prop2 }: PropsType\n if (firstParam.type && ts.isTypeReferenceNode(firstParam.type) && ts.isObjectBindingPattern(firstParam.name)) {\n return firstParam.type.getText(sourceFile);\n }\n\n // Destructured with type annotation: ({ prop1, prop2 }: PropsType)\n if (ts.isObjectBindingPattern(firstParam.name) && firstParam.type) {\n return firstParam.type.getText(sourceFile);\n }\n\n return null;\n}\n\n/**\n * Finds __xydSchema assignments and converts JSON Schema → xyd uniform format.\n */\nfunction convertSchemaToUniform(code: string, propertyName: string = '__xydUniform'): {code: string; map: null} | null {\n const schemaRegex = /(\\w+)\\.__xydSchema\\s*=\\s*(\\{[\\s\\S]*?\\n\\});/g;\n let modified = code;\n let hasChanges = false;\n\n let match: RegExpExecArray | null;\n while ((match = schemaRegex.exec(code)) !== null) {\n const componentName = match[1];\n const schemaStr = match[2];\n\n try {\n const schema = new Function(`return ${schemaStr}`)();\n const uniform = jsonSchemaToUniformReference(componentName, schema);\n const jsonStr = JSON.stringify(uniform).replace(/\\\\/g, '\\\\\\\\').replace(/'/g, \"\\\\'\");\n\n modified = modified.replace(\n match[0],\n `${componentName}.${propertyName} = JSON.parse('${jsonStr}');`,\n );\n hasChanges = true;\n } catch (e) {\n console.warn(`[xyd-source-react-runtime] Failed to parse schema for ${componentName}:`, e);\n }\n }\n\n if (!hasChanges) return null;\n return {code: modified, map: null};\n}\n","import type {\n Reference,\n Definition,\n} from '@xyd-js/uniform';\n\nimport {\n schemaObjectToUniformDefinitionProperties,\n} from '@xyd-js/openapi';\n\n/**\n * JSON Schema structure as produced by typia.json.schemas<[T]>().\n */\ninterface JsonSchemaOutput {\n version?: string;\n components?: {\n schemas?: Record<string, any>;\n };\n schemas?: Array<{$ref?: string} | any>;\n}\n\n/**\n * Converts a typia JSON Schema output into an xyd uniform Reference,\n * reusing xyd-openapi's battle-tested schema → uniform converter.\n */\nexport function jsonSchemaToUniformReference(\n componentName: string,\n schema: JsonSchemaOutput,\n): Reference {\n const ref: Reference = {\n title: componentName,\n canonical: '',\n description: '',\n definitions: [],\n examples: {groups: []},\n };\n\n // Resolve the root schema (follows $ref to components.schemas)\n const rootSchema = resolveRootSchema(schema);\n if (!rootSchema) return ref;\n\n // Inline all $ref pointers so xyd-openapi doesn't encounter unresolved refs\n const schemas = schema.components?.schemas || {};\n const inlined = inlineRefs(rootSchema, schemas);\n\n // Use xyd-openapi's converter\n const result = schemaObjectToUniformDefinitionProperties(inlined as any);\n\n const propsDef: Definition = {\n title: 'Props',\n properties: [],\n meta: [{name: 'type' as any, value: 'parameters'}],\n };\n\n if (Array.isArray(result)) {\n propsDef.properties = result;\n } else if (result) {\n propsDef.rootProperty = result;\n }\n\n if (propsDef.properties.length > 0 || propsDef.rootProperty) {\n ref.definitions.push(propsDef);\n }\n\n return ref;\n}\n\nfunction resolveRootSchema(output: JsonSchemaOutput): any | null {\n const rootRef = output.schemas?.[0];\n if (!rootRef) return null;\n\n if ('$ref' in rootRef && rootRef.$ref) {\n const refPath = rootRef.$ref.replace('#/components/schemas/', '');\n return output.components?.schemas?.[refPath] || null;\n }\n\n return rootRef;\n}\n\n/**\n * Recursively inlines all $ref pointers so the schema is self-contained\n * for xyd-openapi's converter (which warns on unresolved $ref).\n */\nfunction inlineRefs(schema: any, schemas: Record<string, any>, visited = new Set<string>()): any {\n if (!schema || typeof schema !== 'object') return schema;\n\n if (schema.$ref) {\n const refPath = schema.$ref.replace('#/components/schemas/', '');\n if (visited.has(refPath)) {\n return {type: 'object', description: `(circular: ${refPath})`};\n }\n const resolved = schemas[refPath];\n if (!resolved) return schema;\n visited.add(refPath);\n const result = inlineRefs({...resolved}, schemas, visited);\n visited.delete(refPath);\n return result;\n }\n\n if (Array.isArray(schema)) {\n return schema.map((item) => inlineRefs(item, schemas, visited));\n }\n\n const result: any = {};\n for (const [key, value] of Object.entries(schema)) {\n result[key] = inlineRefs(value, schemas, visited);\n }\n return result;\n}\n"],"mappings":"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","names":["result"]}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { Plugin } from 'vite';
|
|
2
|
+
import { Reference } from '@xyd-js/uniform';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* JSON Schema structure as produced by typia.json.schemas<[T]>().
|
|
6
|
+
*/
|
|
7
|
+
interface JsonSchemaOutput {
|
|
8
|
+
version?: string;
|
|
9
|
+
components?: {
|
|
10
|
+
schemas?: Record<string, any>;
|
|
11
|
+
};
|
|
12
|
+
schemas?: Array<{
|
|
13
|
+
$ref?: string;
|
|
14
|
+
} | any>;
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Converts a typia JSON Schema output into an xyd uniform Reference,
|
|
18
|
+
* reusing xyd-openapi's battle-tested schema → uniform converter.
|
|
19
|
+
*/
|
|
20
|
+
declare function jsonSchemaToUniformReference(componentName: string, schema: JsonSchemaOutput): Reference;
|
|
21
|
+
|
|
22
|
+
interface XydSourceReactRuntimeOptions {
|
|
23
|
+
/** Path to tsconfig.json. Required for typia's TypeScript transform. */
|
|
24
|
+
tsconfig?: string;
|
|
25
|
+
/** Property name for the injected uniform data. Defaults to `__xydUniform`. */
|
|
26
|
+
propertyName?: string;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Vite plugin that auto-detects React components, uses typia to generate
|
|
30
|
+
* JSON Schema from their props at build time, and injects `__xydUniform`.
|
|
31
|
+
*
|
|
32
|
+
* No manual annotations needed — the plugin:
|
|
33
|
+
* 1. Scans source files for exported functions with typed props
|
|
34
|
+
* 2. Injects `typia.json.schemas<[PropsType]>()` calls
|
|
35
|
+
* 3. Runs typia's TS transform to resolve all types (cross-file, generics, etc.)
|
|
36
|
+
* 4. Converts JSON Schema → xyd uniform format
|
|
37
|
+
* 5. Injects `Component.__xydUniform = JSON.parse('...')`
|
|
38
|
+
*
|
|
39
|
+
* ```ts
|
|
40
|
+
* import react from '@vitejs/plugin-react';
|
|
41
|
+
* import { xydSourceReactRuntime } from '@xyd-js/source-react-runtime';
|
|
42
|
+
*
|
|
43
|
+
* export default defineConfig({
|
|
44
|
+
* plugins: [
|
|
45
|
+
* xydSourceReactRuntime({ tsconfig: './tsconfig.json' }),
|
|
46
|
+
* react(),
|
|
47
|
+
* ],
|
|
48
|
+
* });
|
|
49
|
+
* ```
|
|
50
|
+
*/
|
|
51
|
+
declare function xydSourceReactRuntime(options?: XydSourceReactRuntimeOptions): Plugin;
|
|
52
|
+
|
|
53
|
+
export { type XydSourceReactRuntimeOptions, jsonSchemaToUniformReference, xydSourceReactRuntime };
|