@kithinji/pod 1.0.10 → 1.0.13
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/main.js +159 -125
- package/dist/main.js.map +3 -3
- package/dist/types/dev/server.d.ts.map +1 -1
- package/dist/types/plugins/analyzers/graph.d.ts.map +1 -1
- package/dist/types/plugins/css/index.d.ts.map +1 -1
- package/dist/types/plugins/generators/tsx_server_stub.d.ts +2 -0
- package/dist/types/plugins/generators/tsx_server_stub.d.ts.map +1 -1
- package/dist/types/plugins/my.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/dev/server.ts +1 -0
- package/src/main.ts +1 -1
- package/src/plugins/analyzers/graph.ts +103 -115
- package/src/plugins/css/index.ts +1 -16
- package/src/plugins/generators/tsx_server_stub.ts +30 -10
- package/src/plugins/my.ts +12 -4
package/dist/main.js
CHANGED
|
@@ -1215,6 +1215,7 @@ function extractClassStub(classDecl) {
|
|
|
1215
1215
|
if (!className) return null;
|
|
1216
1216
|
let propsType = "{}";
|
|
1217
1217
|
const decorators = [];
|
|
1218
|
+
const constructorParams = [];
|
|
1218
1219
|
if (classDecl.decorators) {
|
|
1219
1220
|
for (const dec of classDecl.decorators) {
|
|
1220
1221
|
const str = stringifyDecorator(dec);
|
|
@@ -1226,23 +1227,35 @@ function extractClassStub(classDecl) {
|
|
|
1226
1227
|
if (member.key.type === "Identifier" && member.key.value === "props") {
|
|
1227
1228
|
propsType = extractPropsType(member);
|
|
1228
1229
|
}
|
|
1230
|
+
} else if (member.type === "Constructor") {
|
|
1231
|
+
for (const param of member.params) {
|
|
1232
|
+
const paramStr = stringifyParam(param);
|
|
1233
|
+
if (paramStr) constructorParams.push(paramStr);
|
|
1234
|
+
}
|
|
1229
1235
|
}
|
|
1230
1236
|
}
|
|
1231
1237
|
return {
|
|
1232
1238
|
name: className,
|
|
1233
1239
|
propsType,
|
|
1234
|
-
decorators
|
|
1240
|
+
decorators,
|
|
1241
|
+
constructorParams
|
|
1235
1242
|
};
|
|
1236
1243
|
}
|
|
1237
1244
|
function stringifyDecorator(decorator) {
|
|
1238
|
-
const
|
|
1239
|
-
|
|
1240
|
-
|
|
1241
|
-
|
|
1242
|
-
|
|
1243
|
-
|
|
1244
|
-
|
|
1245
|
-
|
|
1245
|
+
const exprCode = printSync({
|
|
1246
|
+
type: "Module",
|
|
1247
|
+
span: { start: 0, end: 0, ctxt: 0 },
|
|
1248
|
+
body: [
|
|
1249
|
+
{
|
|
1250
|
+
type: "ExpressionStatement",
|
|
1251
|
+
expression: decorator.expression,
|
|
1252
|
+
span: { start: 0, end: 0, ctxt: 0 }
|
|
1253
|
+
}
|
|
1254
|
+
],
|
|
1255
|
+
interpreter: ""
|
|
1256
|
+
}).code;
|
|
1257
|
+
const cleanCode = exprCode.replace(/^#!.*\n/, "").trim();
|
|
1258
|
+
return `@${cleanCode.replace(/;$/, "")}`;
|
|
1246
1259
|
}
|
|
1247
1260
|
function extractPropsType(member) {
|
|
1248
1261
|
const typeAnn = member.typeAnnotation?.typeAnnotation;
|
|
@@ -1260,6 +1273,46 @@ function extractPropsType(member) {
|
|
|
1260
1273
|
}
|
|
1261
1274
|
return stringifyType2(typeAnn);
|
|
1262
1275
|
}
|
|
1276
|
+
function stringifyParam(param) {
|
|
1277
|
+
let decorators = [];
|
|
1278
|
+
if (param.decorators) {
|
|
1279
|
+
for (const d of param.decorators) {
|
|
1280
|
+
const str = stringifyDecorator(d);
|
|
1281
|
+
if (str) decorators.push(str);
|
|
1282
|
+
}
|
|
1283
|
+
}
|
|
1284
|
+
const decoratorPrefix = decorators.length ? decorators.join(" ") + " " : "";
|
|
1285
|
+
let typeName = "any";
|
|
1286
|
+
let paramName = "";
|
|
1287
|
+
let accessibility = "";
|
|
1288
|
+
if (param.type === "TsParameterProperty") {
|
|
1289
|
+
accessibility = param.accessibility || "";
|
|
1290
|
+
const inner = param.param;
|
|
1291
|
+
if (inner.type !== "Identifier") return "";
|
|
1292
|
+
paramName = inner.value;
|
|
1293
|
+
if (inner.typeAnnotation?.typeAnnotation) {
|
|
1294
|
+
typeName = extractTypeName(inner.typeAnnotation.typeAnnotation);
|
|
1295
|
+
}
|
|
1296
|
+
} else if (param.type === "Parameter") {
|
|
1297
|
+
const pat = param.pat;
|
|
1298
|
+
if (pat.type !== "Identifier") return "";
|
|
1299
|
+
paramName = pat.value;
|
|
1300
|
+
if (pat.typeAnnotation?.typeAnnotation) {
|
|
1301
|
+
typeName = extractTypeName(pat.typeAnnotation.typeAnnotation);
|
|
1302
|
+
}
|
|
1303
|
+
} else {
|
|
1304
|
+
return "";
|
|
1305
|
+
}
|
|
1306
|
+
const accessPrefix = accessibility ? `${accessibility} ` : "";
|
|
1307
|
+
const result = `${decoratorPrefix}${accessPrefix}${paramName}: ${typeName}`;
|
|
1308
|
+
return result;
|
|
1309
|
+
}
|
|
1310
|
+
function extractTypeName(typeNode) {
|
|
1311
|
+
if (typeNode.type === "TsTypeReference" && typeNode.typeName.type === "Identifier") {
|
|
1312
|
+
return typeNode.typeName.value;
|
|
1313
|
+
}
|
|
1314
|
+
return stringifyType2(typeNode);
|
|
1315
|
+
}
|
|
1263
1316
|
function stringifyType2(typeNode) {
|
|
1264
1317
|
if (!typeNode) return "any";
|
|
1265
1318
|
switch (typeNode.type) {
|
|
@@ -1293,10 +1346,11 @@ function generateClassCode(stub, hash, fileName) {
|
|
|
1293
1346
|
const clientId = `${stub.name}_${hash}`;
|
|
1294
1347
|
const clientPath = `/${fileName}.js`;
|
|
1295
1348
|
const decoratorsStr = stub.decorators.length > 0 ? stub.decorators.join("\n") + "\n" : "";
|
|
1349
|
+
const constructorStr = stub.constructorParams.length ? `constructor(${stub.constructorParams.join(", ")}) {}` : "constructor() {}";
|
|
1296
1350
|
return `
|
|
1297
1351
|
${decoratorsStr}export class ${stub.name} {
|
|
1298
1352
|
props!: ${stub.propsType};
|
|
1299
|
-
|
|
1353
|
+
${constructorStr}
|
|
1300
1354
|
build() {
|
|
1301
1355
|
const inputProps = { ...this.props };
|
|
1302
1356
|
return {
|
|
@@ -2561,7 +2615,10 @@ ${controllerCode}
|
|
|
2561
2615
|
if (isTsx) {
|
|
2562
2616
|
if (isInteractiveFile) {
|
|
2563
2617
|
onClientFound(path14);
|
|
2564
|
-
|
|
2618
|
+
const clientCode = await this.transformInteractiveTsxStub(source, path14);
|
|
2619
|
+
const store = Store.getInstance();
|
|
2620
|
+
store.set(path14, clientCode.contents);
|
|
2621
|
+
return clientCode;
|
|
2565
2622
|
}
|
|
2566
2623
|
return this.transformServerTsx(source, path14);
|
|
2567
2624
|
}
|
|
@@ -2651,9 +2708,8 @@ function useMyPlugin(options) {
|
|
|
2651
2708
|
}
|
|
2652
2709
|
const node = options.graph[args.path];
|
|
2653
2710
|
if (!node) {
|
|
2654
|
-
|
|
2655
|
-
|
|
2656
|
-
);
|
|
2711
|
+
console.log(`File node not found in depend graph: ${args.path}`);
|
|
2712
|
+
throw new Error("900");
|
|
2657
2713
|
}
|
|
2658
2714
|
return clientTransformer.process(node, metadata);
|
|
2659
2715
|
}
|
|
@@ -2667,54 +2723,55 @@ import { parseSync as parseSync5 } from "@swc/core";
|
|
|
2667
2723
|
import * as fs3 from "fs";
|
|
2668
2724
|
import * as path7 from "path";
|
|
2669
2725
|
function resolveFilePath(fromFile, importPath) {
|
|
2670
|
-
if (!importPath.startsWith("."))
|
|
2671
|
-
return null;
|
|
2672
|
-
}
|
|
2726
|
+
if (!importPath.startsWith(".")) return null;
|
|
2673
2727
|
const dir = path7.dirname(fromFile);
|
|
2674
2728
|
const basePath = path7.resolve(dir, importPath);
|
|
2675
2729
|
const extensions = ["", ".ts", ".tsx", ".js", ".jsx"];
|
|
2676
2730
|
for (const ext of extensions) {
|
|
2677
2731
|
const fullPath = basePath + ext;
|
|
2678
|
-
if (fs3.existsSync(fullPath) && fs3.statSync(fullPath).isFile())
|
|
2732
|
+
if (fs3.existsSync(fullPath) && fs3.statSync(fullPath).isFile())
|
|
2679
2733
|
return fullPath;
|
|
2680
|
-
}
|
|
2681
2734
|
}
|
|
2682
2735
|
const indexFiles = ["/index.ts", "/index.tsx", "/index.js", "/index.jsx"];
|
|
2683
2736
|
for (const indexFile of indexFiles) {
|
|
2684
2737
|
const fullPath = basePath + indexFile;
|
|
2685
|
-
if (fs3.existsSync(fullPath))
|
|
2738
|
+
if (fs3.existsSync(fullPath) && fs3.statSync(fullPath).isFile())
|
|
2686
2739
|
return fullPath;
|
|
2687
|
-
}
|
|
2688
2740
|
}
|
|
2689
2741
|
return null;
|
|
2690
2742
|
}
|
|
2691
2743
|
function extractDecorators(decorators) {
|
|
2692
|
-
if (!decorators
|
|
2693
|
-
return decorators.map((
|
|
2694
|
-
|
|
2695
|
-
|
|
2696
|
-
|
|
2697
|
-
|
|
2698
|
-
} else if (decorator.expression.type === "Identifier") {
|
|
2699
|
-
return decorator.expression.value;
|
|
2700
|
-
}
|
|
2744
|
+
if (!decorators) return [];
|
|
2745
|
+
return decorators.map((d) => {
|
|
2746
|
+
const exp = d.expression;
|
|
2747
|
+
if (exp.type === "CallExpression" && exp.callee.type === "Identifier")
|
|
2748
|
+
return exp.callee.value;
|
|
2749
|
+
if (exp.type === "Identifier") return exp.value;
|
|
2701
2750
|
return "unknown";
|
|
2702
|
-
}).filter((
|
|
2751
|
+
}).filter((n) => n !== "unknown");
|
|
2703
2752
|
}
|
|
2704
2753
|
function extractDirective(ast) {
|
|
2705
2754
|
for (const item of ast.body) {
|
|
2706
2755
|
if (item.type === "ExpressionStatement" && item.expression.type === "StringLiteral") {
|
|
2707
|
-
const
|
|
2708
|
-
if (
|
|
2709
|
-
if (
|
|
2710
|
-
}
|
|
2711
|
-
if (item.type !== "ExpressionStatement" || item.expression.type !== "StringLiteral") {
|
|
2756
|
+
const val = item.expression.value;
|
|
2757
|
+
if (val === "use public") return "public";
|
|
2758
|
+
if (val === "use interactive") return "interactive";
|
|
2759
|
+
} else {
|
|
2712
2760
|
break;
|
|
2713
2761
|
}
|
|
2714
2762
|
}
|
|
2715
2763
|
return null;
|
|
2716
2764
|
}
|
|
2717
|
-
function
|
|
2765
|
+
function extractImports(ast) {
|
|
2766
|
+
const imports = [];
|
|
2767
|
+
for (const item of ast.body) {
|
|
2768
|
+
if (item.type === "ImportDeclaration") {
|
|
2769
|
+
imports.push({ path: item.source.value, specifiers: item.specifiers });
|
|
2770
|
+
}
|
|
2771
|
+
}
|
|
2772
|
+
return imports;
|
|
2773
|
+
}
|
|
2774
|
+
function extractExports(ast, currentFile, graph, processFile) {
|
|
2718
2775
|
const exports = [];
|
|
2719
2776
|
for (const item of ast.body) {
|
|
2720
2777
|
if (item.type === "ExportDeclaration" && item.declaration) {
|
|
@@ -2742,10 +2799,30 @@ function extractExports(ast) {
|
|
|
2742
2799
|
exports.push({ name: decl.id.value, kind: "enum" });
|
|
2743
2800
|
}
|
|
2744
2801
|
}
|
|
2745
|
-
if (item.type === "ExportNamedDeclaration") {
|
|
2746
|
-
|
|
2747
|
-
|
|
2748
|
-
|
|
2802
|
+
if (item.type === "ExportNamedDeclaration" && item.source) {
|
|
2803
|
+
const resolved = resolveFilePath(currentFile, item.source.value);
|
|
2804
|
+
if (resolved) {
|
|
2805
|
+
processFile(resolved);
|
|
2806
|
+
const sourceExports = graph[resolved]?.exports || [];
|
|
2807
|
+
for (const spec of item.specifiers) {
|
|
2808
|
+
if (spec.type === "ExportSpecifier") {
|
|
2809
|
+
const exp = sourceExports.find((e) => e.name === spec.orig.value);
|
|
2810
|
+
exports.push({
|
|
2811
|
+
name: spec.exported?.value || spec.orig.value,
|
|
2812
|
+
kind: exp?.kind || "unknown",
|
|
2813
|
+
decorators: exp?.decorators
|
|
2814
|
+
});
|
|
2815
|
+
}
|
|
2816
|
+
}
|
|
2817
|
+
}
|
|
2818
|
+
}
|
|
2819
|
+
if (item.type === "ExportAllDeclaration") {
|
|
2820
|
+
const resolved = resolveFilePath(currentFile, item.source.value);
|
|
2821
|
+
if (resolved) {
|
|
2822
|
+
processFile(resolved);
|
|
2823
|
+
const sourceExports = graph[resolved]?.exports || [];
|
|
2824
|
+
for (const exp of sourceExports) {
|
|
2825
|
+
exports.push({ ...exp });
|
|
2749
2826
|
}
|
|
2750
2827
|
}
|
|
2751
2828
|
}
|
|
@@ -2765,7 +2842,7 @@ function extractExports(ast) {
|
|
|
2765
2842
|
name: "default",
|
|
2766
2843
|
kind,
|
|
2767
2844
|
isDefault: true,
|
|
2768
|
-
decorators: decorators
|
|
2845
|
+
decorators: decorators?.length ? decorators : void 0
|
|
2769
2846
|
});
|
|
2770
2847
|
}
|
|
2771
2848
|
if (item.type === "ExportDefaultExpression") {
|
|
@@ -2774,95 +2851,66 @@ function extractExports(ast) {
|
|
|
2774
2851
|
}
|
|
2775
2852
|
return exports;
|
|
2776
2853
|
}
|
|
2777
|
-
function extractImports(ast) {
|
|
2778
|
-
const imports = [];
|
|
2779
|
-
for (const item of ast.body) {
|
|
2780
|
-
if (item.type === "ImportDeclaration") {
|
|
2781
|
-
imports.push({
|
|
2782
|
-
path: item.source.value,
|
|
2783
|
-
specifiers: item.specifiers
|
|
2784
|
-
});
|
|
2785
|
-
}
|
|
2786
|
-
}
|
|
2787
|
-
return imports;
|
|
2788
|
-
}
|
|
2789
2854
|
function buildGraph(entryPoints) {
|
|
2790
2855
|
const graph = {};
|
|
2791
2856
|
const visited = /* @__PURE__ */ new Set();
|
|
2792
2857
|
function processFile(filePath) {
|
|
2793
|
-
const
|
|
2794
|
-
if (!
|
|
2858
|
+
const allowedExt = [".ts", ".tsx", ".js", ".jsx"];
|
|
2859
|
+
if (!allowedExt.includes(path7.extname(filePath))) return;
|
|
2795
2860
|
if (visited.has(filePath)) return;
|
|
2796
2861
|
visited.add(filePath);
|
|
2797
2862
|
if (!fs3.existsSync(filePath)) {
|
|
2798
2863
|
console.warn(`File not found: ${filePath}`);
|
|
2799
2864
|
return;
|
|
2800
2865
|
}
|
|
2801
|
-
const isTsx =
|
|
2802
|
-
const
|
|
2866
|
+
const isTsx = [".tsx", ".jsx"].includes(path7.extname(filePath));
|
|
2867
|
+
const store = Store.getInstance();
|
|
2868
|
+
const newCode = store.get(filePath);
|
|
2869
|
+
const content = newCode ? newCode[0] : fs3.readFileSync(filePath, "utf-8");
|
|
2803
2870
|
const ast = parseSync5(content, {
|
|
2804
2871
|
syntax: "typescript",
|
|
2805
2872
|
tsx: isTsx,
|
|
2806
2873
|
decorators: true
|
|
2807
2874
|
});
|
|
2808
2875
|
const directive = extractDirective(ast);
|
|
2809
|
-
const exports = extractExports(ast);
|
|
2810
2876
|
const rawImports = extractImports(ast);
|
|
2877
|
+
const exports = extractExports(ast, filePath, graph, processFile);
|
|
2811
2878
|
for (const { path: importPath } of rawImports) {
|
|
2812
2879
|
const resolved = resolveFilePath(filePath, importPath);
|
|
2813
|
-
if (resolved)
|
|
2814
|
-
|
|
2815
|
-
|
|
2816
|
-
|
|
2817
|
-
|
|
2818
|
-
|
|
2819
|
-
|
|
2820
|
-
|
|
2821
|
-
|
|
2822
|
-
|
|
2823
|
-
|
|
2824
|
-
|
|
2825
|
-
|
|
2826
|
-
|
|
2827
|
-
|
|
2828
|
-
|
|
2829
|
-
|
|
2830
|
-
|
|
2831
|
-
|
|
2832
|
-
|
|
2833
|
-
|
|
2834
|
-
|
|
2835
|
-
|
|
2836
|
-
|
|
2837
|
-
|
|
2838
|
-
|
|
2839
|
-
|
|
2840
|
-
);
|
|
2841
|
-
symbols.push({
|
|
2842
|
-
name: importedName,
|
|
2843
|
-
kind: exportedSymbol?.kind || "unknown",
|
|
2844
|
-
decorators: exportedSymbol?.decorators
|
|
2845
|
-
});
|
|
2880
|
+
if (resolved) processFile(resolved);
|
|
2881
|
+
}
|
|
2882
|
+
const imports = rawImports.map(
|
|
2883
|
+
({ path: importPath, specifiers }) => {
|
|
2884
|
+
const resolvedPath = resolveFilePath(filePath, importPath);
|
|
2885
|
+
const sourceExports = resolvedPath && graph[resolvedPath] ? graph[resolvedPath].exports : [];
|
|
2886
|
+
const symbols = [];
|
|
2887
|
+
for (const spec of specifiers) {
|
|
2888
|
+
if (spec.type === "ImportDefaultSpecifier") {
|
|
2889
|
+
const def = sourceExports.find((e) => e.isDefault);
|
|
2890
|
+
symbols.push({
|
|
2891
|
+
name: spec.local.value,
|
|
2892
|
+
kind: def?.kind || "unknown",
|
|
2893
|
+
decorators: def?.decorators,
|
|
2894
|
+
isDefault: true
|
|
2895
|
+
});
|
|
2896
|
+
} else if (spec.type === "ImportNamespaceSpecifier") {
|
|
2897
|
+
symbols.push({ name: spec.local.value, kind: "namespace" });
|
|
2898
|
+
} else if (spec.type === "ImportSpecifier") {
|
|
2899
|
+
const importedName = spec.imported ? spec.imported.value : spec.local.value;
|
|
2900
|
+
const exp = sourceExports.find((e) => e.name === importedName);
|
|
2901
|
+
symbols.push({
|
|
2902
|
+
name: importedName,
|
|
2903
|
+
kind: exp?.kind || "unknown",
|
|
2904
|
+
decorators: exp?.decorators
|
|
2905
|
+
});
|
|
2906
|
+
}
|
|
2846
2907
|
}
|
|
2908
|
+
return { sourcePath: importPath, resolvedPath, symbols };
|
|
2847
2909
|
}
|
|
2848
|
-
|
|
2849
|
-
|
|
2850
|
-
resolvedPath,
|
|
2851
|
-
symbols
|
|
2852
|
-
});
|
|
2853
|
-
}
|
|
2854
|
-
graph[filePath] = {
|
|
2855
|
-
filePath,
|
|
2856
|
-
isTsx,
|
|
2857
|
-
directive,
|
|
2858
|
-
imports,
|
|
2859
|
-
exports
|
|
2860
|
-
};
|
|
2861
|
-
}
|
|
2862
|
-
for (const entry of entryPoints) {
|
|
2863
|
-
const resolved = path7.resolve(entry);
|
|
2864
|
-
processFile(resolved);
|
|
2910
|
+
);
|
|
2911
|
+
graph[filePath] = { filePath, isTsx, directive, imports, exports };
|
|
2865
2912
|
}
|
|
2913
|
+
for (const entry of entryPoints) processFile(path7.resolve(entry));
|
|
2866
2914
|
return graph;
|
|
2867
2915
|
}
|
|
2868
2916
|
|
|
@@ -2881,21 +2929,7 @@ function stylePlugin(store) {
|
|
|
2881
2929
|
const allRules = styleRules.flat();
|
|
2882
2930
|
const uniqueRules = [...new Set(allRules)];
|
|
2883
2931
|
const cssOutput = uniqueRules.join("\n");
|
|
2884
|
-
|
|
2885
|
-
box-sizing: border-box;
|
|
2886
|
-
}
|
|
2887
|
-
|
|
2888
|
-
*, *::before, *::after {
|
|
2889
|
-
box-sizing: inherit;
|
|
2890
|
-
}
|
|
2891
|
-
|
|
2892
|
-
body {
|
|
2893
|
-
margin: 0;
|
|
2894
|
-
padding: 0;
|
|
2895
|
-
}
|
|
2896
|
-
|
|
2897
|
-
${cssOutput}`;
|
|
2898
|
-
fs4.writeFileSync("public/index.css", output);
|
|
2932
|
+
fs4.writeFileSync("public/index.css", cssOutput);
|
|
2899
2933
|
});
|
|
2900
2934
|
}
|
|
2901
2935
|
};
|
|
@@ -4505,7 +4539,7 @@ function printNextSteps(projectName, env, services) {
|
|
|
4505
4539
|
|
|
4506
4540
|
// src/main.ts
|
|
4507
4541
|
var program = new Command();
|
|
4508
|
-
program.name("pod").description("Pod cli tool").version("1.0.
|
|
4542
|
+
program.name("pod").description("Pod cli tool").version("1.0.13");
|
|
4509
4543
|
program.command("new <name>").description("Start a new Pod Project").action(async (name) => {
|
|
4510
4544
|
await addNew(name);
|
|
4511
4545
|
const appDir = path13.resolve(process.cwd(), name);
|