@luckystack/devkit 0.8.4 → 0.8.6
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 +12 -0
- package/CLAUDE.md +6 -2
- package/dist/index.d.ts +74 -1
- package/dist/index.js +306 -218
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -1943,8 +1943,8 @@ var getSyncClientOutputTypeDetailsFromFile = (filePath) => {
|
|
|
1943
1943
|
|
|
1944
1944
|
// src/typeMap/functionsMeta.ts
|
|
1945
1945
|
import * as ts7 from "typescript";
|
|
1946
|
-
import
|
|
1947
|
-
import
|
|
1946
|
+
import fs5 from "fs";
|
|
1947
|
+
import path8 from "path";
|
|
1948
1948
|
|
|
1949
1949
|
// src/typeMap/typeContext.ts
|
|
1950
1950
|
import * as ts6 from "typescript";
|
|
@@ -2038,7 +2038,143 @@ var sanitizeTypeAndCollectImports = ({
|
|
|
2038
2038
|
};
|
|
2039
2039
|
|
|
2040
2040
|
// src/typeMap/functionsMeta.ts
|
|
2041
|
-
import { getGeneratedSocketTypesPath as getGeneratedSocketTypesPath5,
|
|
2041
|
+
import { getGeneratedSocketTypesPath as getGeneratedSocketTypesPath5, ROOT_DIR as ROOT_DIR4 } from "@luckystack/core";
|
|
2042
|
+
|
|
2043
|
+
// src/functionRegistry.ts
|
|
2044
|
+
import fs4 from "fs";
|
|
2045
|
+
import path7 from "path";
|
|
2046
|
+
import { ROOT_DIR as ROOT_DIR3, getServerFunctionDirs, isTestFile, isTestDirectory } from "@luckystack/core";
|
|
2047
|
+
var normalizePath = (value) => value.replaceAll("\\", "/");
|
|
2048
|
+
var toWorkspaceRelative = (absolutePath) => normalizePath(path7.relative(ROOT_DIR3, absolutePath));
|
|
2049
|
+
var formatFunctionKeyPath = (keyPath) => keyPath.join(".");
|
|
2050
|
+
var functionModuleFileName = (keyPath) => {
|
|
2051
|
+
const fileName = keyPath.at(-1);
|
|
2052
|
+
if (fileName === void 0) {
|
|
2053
|
+
throw new Error("[function-injection] Internal error: encountered an empty function key path.");
|
|
2054
|
+
}
|
|
2055
|
+
return fileName;
|
|
2056
|
+
};
|
|
2057
|
+
var formatFunctionKeyConflict = (keyPath, firstSourcePath, secondSourcePath) => `[function-injection] Conflict at \`functions.${formatFunctionKeyPath(keyPath)}\`: defined in both \`${firstSourcePath}\` and \`${secondSourcePath}\`. Delete one \u2014 \`shared/\` is the canonical location for framework re-exports.`;
|
|
2058
|
+
var formatFunctionNamespaceConflict = (moduleKeyPath, moduleSourcePath, nestedKeyPath, nestedSourcePath) => `[function-injection] Conflict at \`functions.${formatFunctionKeyPath(moduleKeyPath)}\`: \`${moduleSourcePath}\` defines it as a module, but \`${nestedSourcePath}\` nests \`functions.${formatFunctionKeyPath(nestedKeyPath)}\` underneath it. Rename one \u2014 a key cannot be both a module and a namespace.`;
|
|
2059
|
+
var walkFunctionRoot = (dir, rootDir, basePath, collected) => {
|
|
2060
|
+
const entries = fs4.readdirSync(dir).toSorted();
|
|
2061
|
+
for (const entry of entries) {
|
|
2062
|
+
if (entry === "node_modules") continue;
|
|
2063
|
+
const fullPath = path7.join(dir, entry);
|
|
2064
|
+
if (getRoutingRules().ignore(toWorkspaceRelative(fullPath))) continue;
|
|
2065
|
+
if (fs4.statSync(fullPath).isDirectory()) {
|
|
2066
|
+
if (isTestDirectory(entry)) continue;
|
|
2067
|
+
walkFunctionRoot(fullPath, rootDir, [...basePath, entry], collected);
|
|
2068
|
+
continue;
|
|
2069
|
+
}
|
|
2070
|
+
if (!entry.endsWith(".ts")) continue;
|
|
2071
|
+
if (isTestFile(entry)) continue;
|
|
2072
|
+
collected.push({
|
|
2073
|
+
keyPath: [...basePath, entry.slice(0, -".ts".length)],
|
|
2074
|
+
sourcePath: toWorkspaceRelative(fullPath),
|
|
2075
|
+
rootPath: toWorkspaceRelative(rootDir)
|
|
2076
|
+
});
|
|
2077
|
+
}
|
|
2078
|
+
};
|
|
2079
|
+
var resolveNamespaceConflicts = (modules, reportConflict) => {
|
|
2080
|
+
const byDottedKey = /* @__PURE__ */ new Map();
|
|
2081
|
+
for (const module of modules) {
|
|
2082
|
+
byDottedKey.set(formatFunctionKeyPath(module.keyPath), module);
|
|
2083
|
+
}
|
|
2084
|
+
return modules.filter((module) => {
|
|
2085
|
+
for (let depth = 1; depth < module.keyPath.length; depth++) {
|
|
2086
|
+
const ancestor = byDottedKey.get(formatFunctionKeyPath(module.keyPath.slice(0, depth)));
|
|
2087
|
+
if (!ancestor) continue;
|
|
2088
|
+
reportConflict(formatFunctionNamespaceConflict(
|
|
2089
|
+
ancestor.keyPath,
|
|
2090
|
+
ancestor.sourcePath,
|
|
2091
|
+
module.keyPath,
|
|
2092
|
+
module.sourcePath
|
|
2093
|
+
));
|
|
2094
|
+
return false;
|
|
2095
|
+
}
|
|
2096
|
+
return true;
|
|
2097
|
+
});
|
|
2098
|
+
};
|
|
2099
|
+
var collectFunctionModules = (options = {}) => {
|
|
2100
|
+
const { roots, onConflict } = options;
|
|
2101
|
+
const functionRoots = roots ?? getServerFunctionDirs();
|
|
2102
|
+
const claimedByDottedKey = /* @__PURE__ */ new Map();
|
|
2103
|
+
const reportConflict = (message) => {
|
|
2104
|
+
if (!onConflict) throw new Error(message);
|
|
2105
|
+
onConflict(message);
|
|
2106
|
+
};
|
|
2107
|
+
for (const root of functionRoots) {
|
|
2108
|
+
if (!fs4.existsSync(root)) continue;
|
|
2109
|
+
const fromThisRoot = [];
|
|
2110
|
+
walkFunctionRoot(root, root, [], fromThisRoot);
|
|
2111
|
+
for (const module of fromThisRoot) {
|
|
2112
|
+
const dottedKey = formatFunctionKeyPath(module.keyPath);
|
|
2113
|
+
const claimed = claimedByDottedKey.get(dottedKey);
|
|
2114
|
+
if (claimed) {
|
|
2115
|
+
reportConflict(formatFunctionKeyConflict(
|
|
2116
|
+
module.keyPath,
|
|
2117
|
+
claimed.sourcePath,
|
|
2118
|
+
module.sourcePath
|
|
2119
|
+
));
|
|
2120
|
+
continue;
|
|
2121
|
+
}
|
|
2122
|
+
claimedByDottedKey.set(dottedKey, module);
|
|
2123
|
+
}
|
|
2124
|
+
}
|
|
2125
|
+
const modules = [...claimedByDottedKey.values()].toSorted((left, right) => formatFunctionKeyPath(left.keyPath).localeCompare(formatFunctionKeyPath(right.keyPath)));
|
|
2126
|
+
return resolveNamespaceConflicts(modules, reportConflict);
|
|
2127
|
+
};
|
|
2128
|
+
var createRenderNode = () => ({ children: /* @__PURE__ */ new Map(), module: null });
|
|
2129
|
+
var renderModuleEntry = (varName, fileName, indent) => `(() => {
|
|
2130
|
+
${indent} const { default: _default, ...named } = ${varName} as Record<string, unknown>;
|
|
2131
|
+
${indent} const cleaned = Object.fromEntries(Object.entries(named).filter(([key]) => key !== '__esModule'));
|
|
2132
|
+
${indent} if (Object.keys(cleaned).length > 0) return cleaned;
|
|
2133
|
+
${indent} return _default !== undefined ? { ${JSON.stringify(fileName)}: _default } : {};
|
|
2134
|
+
${indent}})()`;
|
|
2135
|
+
var renderNode = (node, indent) => {
|
|
2136
|
+
let output = "";
|
|
2137
|
+
for (const [name, child] of node.children) {
|
|
2138
|
+
if (child.module) {
|
|
2139
|
+
output += `${indent}${JSON.stringify(name)}: ${renderModuleEntry(child.module.varName, child.module.fileName, indent)},
|
|
2140
|
+
`;
|
|
2141
|
+
continue;
|
|
2142
|
+
}
|
|
2143
|
+
output += `${indent}${JSON.stringify(name)}: {
|
|
2144
|
+
${renderNode(child, `${indent} `)}${indent}},
|
|
2145
|
+
`;
|
|
2146
|
+
}
|
|
2147
|
+
return output;
|
|
2148
|
+
};
|
|
2149
|
+
var renderFunctionsMap = ({
|
|
2150
|
+
modules,
|
|
2151
|
+
importPrefix,
|
|
2152
|
+
varPrefix = "fn"
|
|
2153
|
+
}) => {
|
|
2154
|
+
const imports = [];
|
|
2155
|
+
const root = createRenderNode();
|
|
2156
|
+
for (const [index, module] of modules.entries()) {
|
|
2157
|
+
const varName = `${varPrefix}${index}`;
|
|
2158
|
+
imports.push(`import * as ${varName} from '${importPrefix}${module.sourcePath.replace(/\.ts$/, "")}';`);
|
|
2159
|
+
let target = root;
|
|
2160
|
+
for (const segment of module.keyPath.slice(0, -1)) {
|
|
2161
|
+
let child = target.children.get(segment);
|
|
2162
|
+
if (!child) {
|
|
2163
|
+
child = createRenderNode();
|
|
2164
|
+
target.children.set(segment, child);
|
|
2165
|
+
}
|
|
2166
|
+
target = child;
|
|
2167
|
+
}
|
|
2168
|
+
const fileName = functionModuleFileName(module.keyPath);
|
|
2169
|
+
const leaf = createRenderNode();
|
|
2170
|
+
leaf.module = { varName, fileName };
|
|
2171
|
+
target.children.set(fileName, leaf);
|
|
2172
|
+
}
|
|
2173
|
+
const source = "export const functions: Record<string, Record<string, unknown>> = {\n" + renderNode(root, " ") + "};";
|
|
2174
|
+
return { imports, source };
|
|
2175
|
+
};
|
|
2176
|
+
|
|
2177
|
+
// src/typeMap/functionsMeta.ts
|
|
2042
2178
|
var stripDefaultValues = (params) => {
|
|
2043
2179
|
return params.replaceAll(/\s*=(?!>)[^,)]+/g, "");
|
|
2044
2180
|
};
|
|
@@ -2066,9 +2202,9 @@ var simplifyInferredType = (value) => {
|
|
|
2066
2202
|
if (/\bRedis\b/.test(value)) return "Redis";
|
|
2067
2203
|
return value;
|
|
2068
2204
|
};
|
|
2069
|
-
var getGeneratedFileDir = () =>
|
|
2205
|
+
var getGeneratedFileDir = () => path8.dirname(getGeneratedSocketTypesPath5());
|
|
2070
2206
|
var sourceModuleSpecifier = (sourceFilePath) => {
|
|
2071
|
-
const relative =
|
|
2207
|
+
const relative = path8.relative(getGeneratedFileDir(), sourceFilePath).replaceAll("\\", "/").replace(/\.tsx?$/i, "");
|
|
2072
2208
|
return relative.startsWith(".") ? relative : `./${relative}`;
|
|
2073
2209
|
};
|
|
2074
2210
|
var portableInferredValueType = (inferred, sourceFilePath, exportName) => {
|
|
@@ -2079,9 +2215,9 @@ var relativizeModuleSpecifier = (specifier, sourceFilePath) => {
|
|
|
2079
2215
|
if (!specifier.startsWith("./") && !specifier.startsWith("../")) {
|
|
2080
2216
|
return specifier;
|
|
2081
2217
|
}
|
|
2082
|
-
const absolute =
|
|
2083
|
-
const rel =
|
|
2084
|
-
const normalized = rel.split(
|
|
2218
|
+
const absolute = path8.resolve(path8.dirname(sourceFilePath), specifier);
|
|
2219
|
+
const rel = path8.relative(getGeneratedFileDir(), absolute);
|
|
2220
|
+
const normalized = rel.split(path8.sep).join("/");
|
|
2085
2221
|
return normalized.startsWith(".") ? normalized : `./${normalized}`;
|
|
2086
2222
|
};
|
|
2087
2223
|
var findProgramVariableDeclaration = (sourceFile, exportName) => {
|
|
@@ -2255,7 +2391,7 @@ var findSignatureForExport = (name, sourceFile, rawContent, filePath, availableE
|
|
|
2255
2391
|
};
|
|
2256
2392
|
var parseFunctionFile = (fullPath, collectors) => {
|
|
2257
2393
|
try {
|
|
2258
|
-
const rawContent =
|
|
2394
|
+
const rawContent = fs5.readFileSync(fullPath, "utf8");
|
|
2259
2395
|
const sourceFile = ts7.createSourceFile(fullPath, rawContent, ts7.ScriptTarget.Latest, true);
|
|
2260
2396
|
const { availableExports, fileImports } = parseFileTypeContext(rawContent);
|
|
2261
2397
|
const program = getServerProgram();
|
|
@@ -2337,48 +2473,19 @@ var parseFunctionFile = (fullPath, collectors) => {
|
|
|
2337
2473
|
return null;
|
|
2338
2474
|
}
|
|
2339
2475
|
};
|
|
2340
|
-
var
|
|
2341
|
-
|
|
2342
|
-
const
|
|
2343
|
-
|
|
2344
|
-
|
|
2345
|
-
|
|
2346
|
-
if (entry.isDirectory()) {
|
|
2347
|
-
const subDir = walkDirToIR(fullPath, collectors);
|
|
2348
|
-
if (subDir && subDir.children.size > 0) {
|
|
2349
|
-
children.set(entry.name, subDir);
|
|
2350
|
-
}
|
|
2476
|
+
var insertFileNode = (root, keyPath, file) => {
|
|
2477
|
+
let target = root;
|
|
2478
|
+
for (const segment of keyPath.slice(0, -1)) {
|
|
2479
|
+
const existing = target.children.get(segment);
|
|
2480
|
+
if (existing?.kind === "dir") {
|
|
2481
|
+
target = existing;
|
|
2351
2482
|
continue;
|
|
2352
2483
|
}
|
|
2353
|
-
|
|
2354
|
-
|
|
2355
|
-
|
|
2356
|
-
if (parsed && (parsed.exports.size > 0 || parsed.defaultExportName !== null || parsed.wildcardReExport !== null)) {
|
|
2357
|
-
children.set(fileName, parsed);
|
|
2358
|
-
}
|
|
2359
|
-
}
|
|
2360
|
-
return { kind: "dir", children, sourcePath: dir };
|
|
2361
|
-
};
|
|
2362
|
-
var formatConflict = (keyPath, a, b) => {
|
|
2363
|
-
const dottedKey = keyPath.join(".");
|
|
2364
|
-
return `[function-injection] Conflict at \`functions.${dottedKey}\`: defined in both \`${a.sourcePath}\` and \`${b.sourcePath}\`. Delete one \u2014 \`shared/\` is the canonical location for framework re-exports.`;
|
|
2365
|
-
};
|
|
2366
|
-
var mergeIR = (target, source, prefix = []) => {
|
|
2367
|
-
for (const [name, sourceChild] of source.children) {
|
|
2368
|
-
const targetChild = target.children.get(name);
|
|
2369
|
-
if (!targetChild) {
|
|
2370
|
-
target.children.set(name, sourceChild);
|
|
2371
|
-
continue;
|
|
2372
|
-
}
|
|
2373
|
-
const keyPath = [...prefix, name];
|
|
2374
|
-
if (targetChild.kind !== sourceChild.kind) {
|
|
2375
|
-
throw new Error(formatConflict(keyPath, targetChild, sourceChild));
|
|
2376
|
-
}
|
|
2377
|
-
if (targetChild.kind === "file" || sourceChild.kind === "file") {
|
|
2378
|
-
throw new Error(formatConflict(keyPath, targetChild, sourceChild));
|
|
2379
|
-
}
|
|
2380
|
-
mergeIR(targetChild, sourceChild, keyPath);
|
|
2484
|
+
const created = { kind: "dir", children: /* @__PURE__ */ new Map(), sourcePath: segment };
|
|
2485
|
+
target.children.set(segment, created);
|
|
2486
|
+
target = created;
|
|
2381
2487
|
}
|
|
2488
|
+
target.children.set(functionModuleFileName(keyPath), file);
|
|
2382
2489
|
};
|
|
2383
2490
|
var serializeIRDir = (dir, indent) => {
|
|
2384
2491
|
let output = "";
|
|
@@ -2426,13 +2533,17 @@ ${fileOutput}${indent}};
|
|
|
2426
2533
|
return output;
|
|
2427
2534
|
};
|
|
2428
2535
|
var generateServerFunctions = (collectors) => {
|
|
2429
|
-
const
|
|
2430
|
-
if (
|
|
2536
|
+
const modules = collectFunctionModules();
|
|
2537
|
+
if (modules.length === 0) return "";
|
|
2431
2538
|
const merged = { kind: "dir", children: /* @__PURE__ */ new Map(), sourcePath: "<merged>" };
|
|
2432
|
-
for (const
|
|
2433
|
-
const
|
|
2434
|
-
|
|
2435
|
-
|
|
2539
|
+
for (const module of modules) {
|
|
2540
|
+
const absolutePath = path8.resolve(ROOT_DIR4, module.sourcePath);
|
|
2541
|
+
const parsed = parseFunctionFile(absolutePath, collectors);
|
|
2542
|
+
if (!parsed) continue;
|
|
2543
|
+
if (parsed.exports.size === 0 && parsed.defaultExportName === null && parsed.wildcardReExport === null) {
|
|
2544
|
+
continue;
|
|
2545
|
+
}
|
|
2546
|
+
insertFileNode(merged, module.keyPath, parsed);
|
|
2436
2547
|
}
|
|
2437
2548
|
return serializeIRDir(merged, " ");
|
|
2438
2549
|
};
|
|
@@ -2441,28 +2552,28 @@ var generateServerFunctions = (collectors) => {
|
|
|
2441
2552
|
import { getSrcDir as getSrcDir2 } from "@luckystack/core";
|
|
2442
2553
|
|
|
2443
2554
|
// src/routeNamingValidation.ts
|
|
2444
|
-
import
|
|
2445
|
-
import
|
|
2446
|
-
import { ROOT_DIR as
|
|
2447
|
-
var
|
|
2555
|
+
import fs6 from "fs";
|
|
2556
|
+
import path9 from "path";
|
|
2557
|
+
import { ROOT_DIR as ROOT_DIR5 } from "@luckystack/core";
|
|
2558
|
+
var normalizePath2 = (value) => {
|
|
2448
2559
|
return value.replaceAll("\\", "/");
|
|
2449
2560
|
};
|
|
2450
|
-
var toRel = (absolute) =>
|
|
2561
|
+
var toRel = (absolute) => path9.relative(ROOT_DIR5, absolute).replaceAll("\\", "/");
|
|
2451
2562
|
var isInsidePrivateRouteSubfolder = (fullPath) => {
|
|
2452
2563
|
const { privateFolderPrefix, apiMarker, syncMarker } = getRoutingRules();
|
|
2453
|
-
const segments =
|
|
2564
|
+
const segments = normalizePath2(fullPath).split("/");
|
|
2454
2565
|
const markerIndex = segments.findIndex((segment) => segment === apiMarker || segment === syncMarker);
|
|
2455
2566
|
if (markerIndex === -1) return false;
|
|
2456
2567
|
return segments.slice(markerIndex + 1).some((segment) => segment.startsWith(privateFolderPrefix));
|
|
2457
2568
|
};
|
|
2458
2569
|
var walkRouteFiles = (dir, results = []) => {
|
|
2459
|
-
const entries =
|
|
2570
|
+
const entries = fs6.readdirSync(dir, { withFileTypes: true });
|
|
2460
2571
|
const apiSeg = apiMarkerSegment();
|
|
2461
2572
|
const syncSeg = syncMarkerSegment();
|
|
2462
2573
|
const { ignore } = getRoutingRules();
|
|
2463
2574
|
for (const entry of entries) {
|
|
2464
|
-
const fullPath =
|
|
2465
|
-
const normalizedFullPath =
|
|
2575
|
+
const fullPath = path9.join(dir, entry.name);
|
|
2576
|
+
const normalizedFullPath = normalizePath2(fullPath);
|
|
2466
2577
|
if (ignore(toRel(fullPath))) continue;
|
|
2467
2578
|
if (isInsidePrivateRouteSubfolder(fullPath)) continue;
|
|
2468
2579
|
if (entry.isDirectory()) {
|
|
@@ -2497,8 +2608,8 @@ var getFileRouteToken = ({
|
|
|
2497
2608
|
};
|
|
2498
2609
|
var validateRouteFilePath = (filePath) => {
|
|
2499
2610
|
const issues = [];
|
|
2500
|
-
const normalizedFilePath =
|
|
2501
|
-
const fileName =
|
|
2611
|
+
const normalizedFilePath = normalizePath2(path9.resolve(filePath));
|
|
2612
|
+
const fileName = path9.basename(filePath);
|
|
2502
2613
|
const apiSeg = apiMarkerSegment();
|
|
2503
2614
|
const syncSeg = syncMarkerSegment();
|
|
2504
2615
|
if (normalizedFilePath.includes(apiSeg)) {
|
|
@@ -2546,7 +2657,7 @@ var resolveApiRouteKey = ({
|
|
|
2546
2657
|
filePath
|
|
2547
2658
|
}) => {
|
|
2548
2659
|
const rules2 = getRoutingRules();
|
|
2549
|
-
const relativePath =
|
|
2660
|
+
const relativePath = normalizePath2(path9.relative(srcDir, filePath));
|
|
2550
2661
|
const segments = relativePath.split("/");
|
|
2551
2662
|
const apiIndex = segments.indexOf(rules2.apiMarker);
|
|
2552
2663
|
if (apiIndex === -1 || apiIndex === segments.length - 1) {
|
|
@@ -2569,7 +2680,7 @@ var resolveSyncRouteKey = ({
|
|
|
2569
2680
|
filePath
|
|
2570
2681
|
}) => {
|
|
2571
2682
|
const rules2 = getRoutingRules();
|
|
2572
|
-
const relativePath =
|
|
2683
|
+
const relativePath = normalizePath2(path9.relative(srcDir, filePath));
|
|
2573
2684
|
const segments = relativePath.split("/");
|
|
2574
2685
|
const syncIndex = segments.indexOf(rules2.syncMarker);
|
|
2575
2686
|
if (syncIndex === -1 || syncIndex === segments.length - 1) {
|
|
@@ -2603,7 +2714,7 @@ var collectDuplicateNormalizedRouteKeyIssues = (srcDir) => {
|
|
|
2603
2714
|
const apiSeg = apiMarkerSegment();
|
|
2604
2715
|
const syncSeg = syncMarkerSegment();
|
|
2605
2716
|
for (const filePath of allRouteFiles) {
|
|
2606
|
-
const normalizedFilePath =
|
|
2717
|
+
const normalizedFilePath = normalizePath2(path9.resolve(filePath));
|
|
2607
2718
|
if (normalizedFilePath.includes(apiSeg)) {
|
|
2608
2719
|
const routeKey = resolveApiRouteKey({ srcDir, filePath });
|
|
2609
2720
|
if (!routeKey) {
|
|
@@ -2687,12 +2798,12 @@ var assertNoDuplicateNormalizedRouteKeys = ({
|
|
|
2687
2798
|
var walkPageFiles = (dir, results = []) => {
|
|
2688
2799
|
let entries;
|
|
2689
2800
|
try {
|
|
2690
|
-
entries =
|
|
2801
|
+
entries = fs6.readdirSync(dir, { withFileTypes: true });
|
|
2691
2802
|
} catch {
|
|
2692
2803
|
return results;
|
|
2693
2804
|
}
|
|
2694
2805
|
for (const entry of entries) {
|
|
2695
|
-
const fullPath =
|
|
2806
|
+
const fullPath = path9.join(dir, entry.name);
|
|
2696
2807
|
if (entry.isDirectory()) {
|
|
2697
2808
|
if (entry.name.startsWith(".") || entry.name === "node_modules") continue;
|
|
2698
2809
|
walkPageFiles(fullPath, results);
|
|
@@ -2709,11 +2820,11 @@ var collectDuplicatePageRoutes = (srcDir) => {
|
|
|
2709
2820
|
const pageFiles = walkPageFiles(srcDir);
|
|
2710
2821
|
const routeToFiles = /* @__PURE__ */ new Map();
|
|
2711
2822
|
for (const absoluteFilePath of pageFiles) {
|
|
2712
|
-
const relative =
|
|
2823
|
+
const relative = normalizePath2(path9.relative(srcDir, absoluteFilePath));
|
|
2713
2824
|
const result = validatePagePath(relative);
|
|
2714
2825
|
if (!result.valid || !result.route) continue;
|
|
2715
2826
|
const list = routeToFiles.get(result.route) ?? [];
|
|
2716
|
-
list.push(
|
|
2827
|
+
list.push(normalizePath2(path9.relative(ROOT_DIR5, absoluteFilePath)));
|
|
2717
2828
|
routeToFiles.set(result.route, list);
|
|
2718
2829
|
}
|
|
2719
2830
|
const issues = [];
|
|
@@ -2971,10 +3082,10 @@ var registerDefaultTemplateRules = () => {
|
|
|
2971
3082
|
registerDefaultTemplateRules();
|
|
2972
3083
|
|
|
2973
3084
|
// src/loader.ts
|
|
2974
|
-
import
|
|
2975
|
-
import
|
|
3085
|
+
import fs7 from "fs";
|
|
3086
|
+
import path10 from "path";
|
|
2976
3087
|
import { pathToFileURL } from "url";
|
|
2977
|
-
import { tryCatch,
|
|
3088
|
+
import { tryCatch, getSrcDir as getSrcDir3, ROOT_DIR as ROOT_DIR6 } from "@luckystack/core";
|
|
2978
3089
|
|
|
2979
3090
|
// src/runtimeTypeResolver.ts
|
|
2980
3091
|
import * as ts8 from "typescript";
|
|
@@ -3352,9 +3463,9 @@ var resolveRuntimeTypeText = ({
|
|
|
3352
3463
|
var devApis = {};
|
|
3353
3464
|
var devSyncs = {};
|
|
3354
3465
|
var devFunctions = {};
|
|
3355
|
-
var
|
|
3466
|
+
var normalizePath3 = (value) => value.replaceAll("\\", "/");
|
|
3356
3467
|
var isIgnoredPath = (absolutePath) => {
|
|
3357
|
-
const relativeFromRoot =
|
|
3468
|
+
const relativeFromRoot = normalizePath3(path10.relative(ROOT_DIR6, absolutePath));
|
|
3358
3469
|
return getRoutingRules().ignore(relativeFromRoot);
|
|
3359
3470
|
};
|
|
3360
3471
|
var mapApiPageLocation = (pageLocation) => {
|
|
@@ -3364,14 +3475,14 @@ var mapSyncPageLocation = (pageLocation) => {
|
|
|
3364
3475
|
return pageLocation || "system";
|
|
3365
3476
|
};
|
|
3366
3477
|
var resolveApiRouteMetaFromPath = (filePath) => {
|
|
3367
|
-
const absolutePath =
|
|
3368
|
-
const normalizedAbsolutePath =
|
|
3369
|
-
const normalizedSrcDir =
|
|
3478
|
+
const absolutePath = path10.resolve(filePath);
|
|
3479
|
+
const normalizedAbsolutePath = normalizePath3(absolutePath);
|
|
3480
|
+
const normalizedSrcDir = normalizePath3(getSrcDir3());
|
|
3370
3481
|
if (!normalizedAbsolutePath.startsWith(normalizedSrcDir) || !normalizedAbsolutePath.endsWith(".ts")) {
|
|
3371
3482
|
return null;
|
|
3372
3483
|
}
|
|
3373
3484
|
const rules2 = getRoutingRules();
|
|
3374
|
-
const relativePath =
|
|
3485
|
+
const relativePath = normalizePath3(path10.relative(getSrcDir3(), absolutePath));
|
|
3375
3486
|
const segments = relativePath.split("/");
|
|
3376
3487
|
const apiIndex = segments.indexOf(rules2.apiMarker);
|
|
3377
3488
|
if (apiIndex === -1 || apiIndex === segments.length - 1) {
|
|
@@ -3391,14 +3502,14 @@ var resolveApiRouteMetaFromPath = (filePath) => {
|
|
|
3391
3502
|
return { routeKey, absolutePath };
|
|
3392
3503
|
};
|
|
3393
3504
|
var resolveSyncRouteMetaFromPath = (filePath) => {
|
|
3394
|
-
const absolutePath =
|
|
3395
|
-
const normalizedAbsolutePath =
|
|
3396
|
-
const normalizedSrcDir =
|
|
3505
|
+
const absolutePath = path10.resolve(filePath);
|
|
3506
|
+
const normalizedAbsolutePath = normalizePath3(absolutePath);
|
|
3507
|
+
const normalizedSrcDir = normalizePath3(getSrcDir3());
|
|
3397
3508
|
if (!normalizedAbsolutePath.startsWith(normalizedSrcDir) || !normalizedAbsolutePath.endsWith(".ts")) {
|
|
3398
3509
|
return null;
|
|
3399
3510
|
}
|
|
3400
3511
|
const rules2 = getRoutingRules();
|
|
3401
|
-
const relativePath =
|
|
3512
|
+
const relativePath = normalizePath3(path10.relative(getSrcDir3(), absolutePath));
|
|
3402
3513
|
const segments = relativePath.split("/");
|
|
3403
3514
|
const syncIndex = segments.indexOf(rules2.syncMarker);
|
|
3404
3515
|
if (syncIndex === -1 || syncIndex === segments.length - 1) {
|
|
@@ -3442,13 +3553,13 @@ var importFile = async (absolutePath) => {
|
|
|
3442
3553
|
};
|
|
3443
3554
|
var collectTsFiles = (dir, relativeTo = "") => {
|
|
3444
3555
|
const results = [];
|
|
3445
|
-
const entries =
|
|
3556
|
+
const entries = fs7.readdirSync(dir);
|
|
3446
3557
|
for (const entry of entries) {
|
|
3447
3558
|
if (entry === "node_modules") continue;
|
|
3448
|
-
const entryPath =
|
|
3559
|
+
const entryPath = path10.join(dir, entry);
|
|
3449
3560
|
if (isIgnoredPath(entryPath)) continue;
|
|
3450
3561
|
const relPath = relativeTo ? `${relativeTo}/${entry}` : entry;
|
|
3451
|
-
if (
|
|
3562
|
+
if (fs7.statSync(entryPath).isDirectory()) {
|
|
3452
3563
|
results.push(...collectTsFiles(entryPath, relPath));
|
|
3453
3564
|
} else if (entry.endsWith(".ts") && !isRouteTestFile(entry)) {
|
|
3454
3565
|
results.push(relPath);
|
|
@@ -3479,16 +3590,16 @@ var resolveFunctionModule = (loadedModule, fileName) => {
|
|
|
3479
3590
|
var initializeApis = async () => {
|
|
3480
3591
|
for (const key of Object.keys(devApis)) delete devApis[key];
|
|
3481
3592
|
clearRuntimeTypeResolverCache();
|
|
3482
|
-
const srcFolder =
|
|
3593
|
+
const srcFolder = fs7.readdirSync(getSrcDir3());
|
|
3483
3594
|
for (const file of srcFolder) {
|
|
3484
3595
|
await scanApiFolder(file);
|
|
3485
3596
|
}
|
|
3486
3597
|
};
|
|
3487
3598
|
var upsertApiFromFile = async (filePath) => {
|
|
3488
|
-
if (isIgnoredPath(
|
|
3599
|
+
if (isIgnoredPath(path10.resolve(filePath))) return;
|
|
3489
3600
|
const routeMeta = resolveApiRouteMetaFromPath(filePath);
|
|
3490
3601
|
if (!routeMeta) {
|
|
3491
|
-
const normalized =
|
|
3602
|
+
const normalized = normalizePath3(path10.resolve(filePath));
|
|
3492
3603
|
if (normalized.includes("/_api/") && normalized.endsWith(".ts") && !isRouteTestFile(normalized)) {
|
|
3493
3604
|
console.log(
|
|
3494
3605
|
`[loader][api] invalid filename: ${normalized}. Expected <name>_v<number>.ts. File will not be loaded.`,
|
|
@@ -3536,13 +3647,13 @@ var removeApiFromFile = (filePath) => {
|
|
|
3536
3647
|
delete devApis[routeMeta.routeKey];
|
|
3537
3648
|
};
|
|
3538
3649
|
var scanApiFolder = async (file, basePath = "") => {
|
|
3539
|
-
const fullPath =
|
|
3650
|
+
const fullPath = path10.join(getSrcDir3(), basePath, file);
|
|
3540
3651
|
if (isIgnoredPath(fullPath)) return;
|
|
3541
|
-
if (!
|
|
3652
|
+
if (!fs7.statSync(fullPath).isDirectory()) return;
|
|
3542
3653
|
if (!file.toLowerCase().endsWith("api")) {
|
|
3543
|
-
const subFolders =
|
|
3654
|
+
const subFolders = fs7.readdirSync(fullPath);
|
|
3544
3655
|
for (const sub of subFolders) {
|
|
3545
|
-
await scanApiFolder(sub,
|
|
3656
|
+
await scanApiFolder(sub, path10.join(basePath, file));
|
|
3546
3657
|
}
|
|
3547
3658
|
return;
|
|
3548
3659
|
}
|
|
@@ -3555,7 +3666,7 @@ var scanApiFolder = async (file, basePath = "") => {
|
|
|
3555
3666
|
const versionMatch = rawApiName.match(apiRules.apiVersionRegex);
|
|
3556
3667
|
if (!versionMatch) {
|
|
3557
3668
|
console.log(
|
|
3558
|
-
`[loader][api] invalid filename: ${
|
|
3669
|
+
`[loader][api] invalid filename: ${path10.join(fullPath, relFile)}. Expected <name>_v<number>.ts. File will not be loaded.`,
|
|
3559
3670
|
"red"
|
|
3560
3671
|
);
|
|
3561
3672
|
continue;
|
|
@@ -3563,7 +3674,7 @@ var scanApiFolder = async (file, basePath = "") => {
|
|
|
3563
3674
|
const version = `v${versionMatch[1]}`;
|
|
3564
3675
|
const apiName = rawApiName.replace(apiRules.apiVersionRegex, "");
|
|
3565
3676
|
const routeKey = `api/${mappedPageLocation}/${apiName}/${version}`;
|
|
3566
|
-
const modulePath =
|
|
3677
|
+
const modulePath = path10.resolve(path10.join(fullPath, relFile));
|
|
3567
3678
|
const [err, module] = await tryCatch(async () => importFile(modulePath));
|
|
3568
3679
|
if (err) {
|
|
3569
3680
|
console.log(`[loader][api] failed to import ${routeKey} from ${modulePath}:`, err, "red");
|
|
@@ -3592,16 +3703,16 @@ var scanApiFolder = async (file, basePath = "") => {
|
|
|
3592
3703
|
var initializeSyncs = async () => {
|
|
3593
3704
|
for (const key of Object.keys(devSyncs)) delete devSyncs[key];
|
|
3594
3705
|
clearRuntimeTypeResolverCache();
|
|
3595
|
-
const srcFolder =
|
|
3706
|
+
const srcFolder = fs7.readdirSync(getSrcDir3());
|
|
3596
3707
|
for (const file of srcFolder) {
|
|
3597
3708
|
await scanSyncFolder(file);
|
|
3598
3709
|
}
|
|
3599
3710
|
};
|
|
3600
3711
|
var upsertSyncFromFile = async (filePath) => {
|
|
3601
|
-
if (isIgnoredPath(
|
|
3712
|
+
if (isIgnoredPath(path10.resolve(filePath))) return;
|
|
3602
3713
|
const routeMeta = resolveSyncRouteMetaFromPath(filePath);
|
|
3603
3714
|
if (!routeMeta) {
|
|
3604
|
-
const normalized =
|
|
3715
|
+
const normalized = normalizePath3(path10.resolve(filePath));
|
|
3605
3716
|
if (normalized.includes(`/${getRoutingRules().syncMarker}/`) && normalized.endsWith(".ts") && !isRouteTestFile(normalized)) {
|
|
3606
3717
|
console.log(
|
|
3607
3718
|
`[loader][sync] invalid filename: ${normalized}. Expected <name>_server_v<number>.ts or <name>_client_v<number>.ts. File will not be loaded.`,
|
|
@@ -3654,13 +3765,13 @@ var removeSyncFromFile = (filePath) => {
|
|
|
3654
3765
|
delete devSyncs[routeMeta.routeKey];
|
|
3655
3766
|
};
|
|
3656
3767
|
var scanSyncFolder = async (file, basePath = "") => {
|
|
3657
|
-
const fullPath =
|
|
3768
|
+
const fullPath = path10.join(getSrcDir3(), basePath, file);
|
|
3658
3769
|
if (isIgnoredPath(fullPath)) return;
|
|
3659
|
-
if (!
|
|
3770
|
+
if (!fs7.statSync(fullPath).isDirectory()) return;
|
|
3660
3771
|
if (!file.toLowerCase().endsWith("sync")) {
|
|
3661
|
-
const subFolders =
|
|
3772
|
+
const subFolders = fs7.readdirSync(fullPath);
|
|
3662
3773
|
for (const sub of subFolders) {
|
|
3663
|
-
await scanSyncFolder(sub,
|
|
3774
|
+
await scanSyncFolder(sub, path10.join(basePath, file));
|
|
3664
3775
|
}
|
|
3665
3776
|
return;
|
|
3666
3777
|
}
|
|
@@ -3672,7 +3783,7 @@ var scanSyncFolder = async (file, basePath = "") => {
|
|
|
3672
3783
|
const syncMatch = rawSyncFileName.match(syncRules.syncVersionRegex);
|
|
3673
3784
|
if (!syncMatch) {
|
|
3674
3785
|
console.log(
|
|
3675
|
-
`[loader][sync] invalid filename: ${
|
|
3786
|
+
`[loader][sync] invalid filename: ${path10.join(fullPath, relFile)}. Expected <name>_server_v<number>.ts or <name>_client_v<number>.ts. File will not be loaded.`,
|
|
3676
3787
|
"red"
|
|
3677
3788
|
);
|
|
3678
3789
|
continue;
|
|
@@ -3682,7 +3793,7 @@ var scanSyncFolder = async (file, basePath = "") => {
|
|
|
3682
3793
|
const syncName = rawSyncFileName.replace(syncRules.syncVersionRegex, "");
|
|
3683
3794
|
const mappedPageLocation = mapSyncPageLocation(pageLocation);
|
|
3684
3795
|
const routeBaseKey = `sync/${mappedPageLocation}/${syncName}/${version}`;
|
|
3685
|
-
const filePath =
|
|
3796
|
+
const filePath = path10.resolve(path10.join(fullPath, relFile));
|
|
3686
3797
|
const [fileError, fileResult] = await tryCatch(async () => importFile(filePath));
|
|
3687
3798
|
if (fileError) {
|
|
3688
3799
|
console.log(`[loader][sync] failed to import ${filePath}:`, fileError, "red");
|
|
@@ -3706,79 +3817,50 @@ var scanSyncFolder = async (file, basePath = "") => {
|
|
|
3706
3817
|
}
|
|
3707
3818
|
}
|
|
3708
3819
|
};
|
|
3709
|
-
var functionClaimMap = /* @__PURE__ */ new Map();
|
|
3710
3820
|
var initializeFunctions = async () => {
|
|
3711
3821
|
for (const key of Object.keys(devFunctions)) delete devFunctions[key];
|
|
3712
|
-
|
|
3713
|
-
|
|
3714
|
-
|
|
3715
|
-
if (fs6.existsSync(dir)) {
|
|
3716
|
-
await scanFunctionsFolder(dir, dir);
|
|
3717
|
-
}
|
|
3718
|
-
}
|
|
3719
|
-
};
|
|
3720
|
-
var scanFunctionsFolder = async (dir, rootDir, basePath = []) => {
|
|
3721
|
-
const entries = fs6.readdirSync(dir);
|
|
3722
|
-
for (const entry of entries) {
|
|
3723
|
-
const fullPath = path9.join(dir, entry);
|
|
3724
|
-
if (isIgnoredPath(fullPath)) continue;
|
|
3725
|
-
const stat = fs6.statSync(fullPath);
|
|
3726
|
-
if (stat.isDirectory()) {
|
|
3727
|
-
await scanFunctionsFolder(fullPath, rootDir, [...basePath, entry]);
|
|
3728
|
-
continue;
|
|
3729
|
-
}
|
|
3730
|
-
if (!entry.endsWith(".ts")) {
|
|
3731
|
-
continue;
|
|
3822
|
+
const modules = collectFunctionModules({
|
|
3823
|
+
onConflict: (message) => {
|
|
3824
|
+
console.log(`[loader][function] ${message} Skipping the second copy.`, "red");
|
|
3732
3825
|
}
|
|
3733
|
-
|
|
3826
|
+
});
|
|
3827
|
+
for (const functionModule of modules) {
|
|
3828
|
+
const absolutePath = path10.resolve(ROOT_DIR6, functionModule.sourcePath);
|
|
3829
|
+
const [err, module] = await tryCatch(async () => importFile(absolutePath));
|
|
3734
3830
|
if (err) {
|
|
3735
|
-
console.log(`[loader][function] failed to import ${
|
|
3831
|
+
console.log(`[loader][function] failed to import ${absolutePath}:`, err, "red");
|
|
3736
3832
|
continue;
|
|
3737
3833
|
}
|
|
3738
|
-
const fileName =
|
|
3834
|
+
const fileName = functionModuleFileName(functionModule.keyPath);
|
|
3739
3835
|
const resolvedFunctionModule = resolveFunctionModule(module, fileName);
|
|
3740
3836
|
if (!isMergeable(resolvedFunctionModule)) continue;
|
|
3741
|
-
const keyPath = [...basePath, fileName].join(".");
|
|
3742
|
-
const previousRoot = functionClaimMap.get(keyPath);
|
|
3743
|
-
if (previousRoot !== void 0 && previousRoot !== rootDir) {
|
|
3744
|
-
console.log(
|
|
3745
|
-
`[loader][function] Conflict at \`functions.${keyPath}\`: defined in both \`${previousRoot}\` and \`${rootDir}\`. Skipping the second copy; fix the duplicate (delete one \u2014 \`shared/\` is the canonical location for framework re-exports).`,
|
|
3746
|
-
"red"
|
|
3747
|
-
);
|
|
3748
|
-
continue;
|
|
3749
|
-
}
|
|
3750
|
-
functionClaimMap.set(keyPath, rootDir);
|
|
3751
3837
|
let target = devFunctions;
|
|
3752
|
-
for (const part of
|
|
3838
|
+
for (const part of functionModule.keyPath.slice(0, -1)) {
|
|
3753
3839
|
const existing = target[part];
|
|
3754
3840
|
if (!existing || typeof existing !== "object") {
|
|
3755
3841
|
target[part] = {};
|
|
3756
3842
|
}
|
|
3757
3843
|
target = target[part];
|
|
3758
3844
|
}
|
|
3759
|
-
const existingAtFileName = target[fileName];
|
|
3760
|
-
if (existingAtFileName !== void 0 && isMergeable(resolvedFunctionModule) && isMergeable(existingAtFileName)) {
|
|
3761
|
-
Object.assign(resolvedFunctionModule, existingAtFileName);
|
|
3762
|
-
}
|
|
3763
3845
|
target[fileName] = resolvedFunctionModule;
|
|
3764
3846
|
}
|
|
3765
3847
|
};
|
|
3766
3848
|
|
|
3767
3849
|
// src/hotReload.ts
|
|
3768
3850
|
import { watch } from "chokidar";
|
|
3769
|
-
import
|
|
3770
|
-
import
|
|
3851
|
+
import fs11 from "fs";
|
|
3852
|
+
import path14 from "path";
|
|
3771
3853
|
|
|
3772
3854
|
// src/templateInjector.ts
|
|
3773
|
-
import
|
|
3774
|
-
import
|
|
3855
|
+
import fs8 from "fs";
|
|
3856
|
+
import path11 from "path";
|
|
3775
3857
|
import { fileURLToPath, pathToFileURL as pathToFileURL2 } from "url";
|
|
3776
3858
|
import * as ts9 from "typescript";
|
|
3777
|
-
import { ROOT_DIR as
|
|
3859
|
+
import { ROOT_DIR as ROOT_DIR7, getGeneratedSocketTypesPath as getGeneratedSocketTypesPath6, getSrcDir as getSrcDir4 } from "@luckystack/core";
|
|
3778
3860
|
var __filename = fileURLToPath(import.meta.url);
|
|
3779
|
-
var __dirname =
|
|
3780
|
-
var templatesDir =
|
|
3781
|
-
var getConsumerTemplatesDir = () =>
|
|
3861
|
+
var __dirname = path11.dirname(__filename);
|
|
3862
|
+
var templatesDir = path11.join(__dirname, "templates");
|
|
3863
|
+
var getConsumerTemplatesDir = () => path11.join(ROOT_DIR7, ".luckystack", "templates");
|
|
3782
3864
|
var templateContentFilenames = (kind) => {
|
|
3783
3865
|
const builtIn = BUILT_IN_TEMPLATE_FILENAMES[kind];
|
|
3784
3866
|
if (builtIn) return [builtIn];
|
|
@@ -3787,10 +3869,10 @@ var templateContentFilenames = (kind) => {
|
|
|
3787
3869
|
var resolveTemplateContent = (kind) => {
|
|
3788
3870
|
const consumerDir = getConsumerTemplatesDir();
|
|
3789
3871
|
for (const fileName of templateContentFilenames(kind)) {
|
|
3790
|
-
const consumerFile =
|
|
3791
|
-
if (
|
|
3872
|
+
const consumerFile = path11.join(consumerDir, fileName);
|
|
3873
|
+
if (fs8.existsSync(consumerFile)) {
|
|
3792
3874
|
try {
|
|
3793
|
-
return
|
|
3875
|
+
return fs8.readFileSync(consumerFile, "utf8");
|
|
3794
3876
|
} catch (error) {
|
|
3795
3877
|
console.error(`[TemplateInjector] Could not read consumer template: ${consumerFile}`, error);
|
|
3796
3878
|
}
|
|
@@ -3800,9 +3882,9 @@ var resolveTemplateContent = (kind) => {
|
|
|
3800
3882
|
if (override !== null) return override;
|
|
3801
3883
|
const builtInName = BUILT_IN_TEMPLATE_FILENAMES[kind];
|
|
3802
3884
|
if (builtInName) {
|
|
3803
|
-
const bundled =
|
|
3885
|
+
const bundled = path11.join(templatesDir, builtInName);
|
|
3804
3886
|
try {
|
|
3805
|
-
return
|
|
3887
|
+
return fs8.readFileSync(bundled, "utf8");
|
|
3806
3888
|
} catch (error) {
|
|
3807
3889
|
console.error(`[TemplateInjector] Could not read bundled template: ${bundled}`, error);
|
|
3808
3890
|
return null;
|
|
@@ -3816,11 +3898,11 @@ var ensureConsumerTemplateConfigLoaded = () => {
|
|
|
3816
3898
|
consumerTemplateConfig ??= (async () => {
|
|
3817
3899
|
const dir = getConsumerTemplatesDir();
|
|
3818
3900
|
for (const fileName of ["templateRules.ts", "templateRules.mjs", "templateRules.js"]) {
|
|
3819
|
-
const rulesFile =
|
|
3820
|
-
if (!
|
|
3821
|
-
const resolvedRulesFile =
|
|
3822
|
-
const resolvedRoot =
|
|
3823
|
-
if (!resolvedRulesFile.startsWith(resolvedRoot +
|
|
3901
|
+
const rulesFile = path11.join(dir, fileName);
|
|
3902
|
+
if (!fs8.existsSync(rulesFile)) continue;
|
|
3903
|
+
const resolvedRulesFile = path11.resolve(rulesFile);
|
|
3904
|
+
const resolvedRoot = path11.resolve(ROOT_DIR7);
|
|
3905
|
+
if (!resolvedRulesFile.startsWith(resolvedRoot + path11.sep) && resolvedRulesFile !== resolvedRoot) {
|
|
3824
3906
|
console.warn(
|
|
3825
3907
|
`[TemplateInjector] Template rules file resolves outside project root \u2014 skipping: ${rulesFile}`
|
|
3826
3908
|
);
|
|
@@ -3838,7 +3920,7 @@ var ensureConsumerTemplateConfigLoaded = () => {
|
|
|
3838
3920
|
};
|
|
3839
3921
|
var isEmptyFile = (filePath) => {
|
|
3840
3922
|
try {
|
|
3841
|
-
const content =
|
|
3923
|
+
const content = fs8.readFileSync(filePath, "utf8");
|
|
3842
3924
|
return content.trim().length === 0;
|
|
3843
3925
|
} catch {
|
|
3844
3926
|
return false;
|
|
@@ -3846,7 +3928,7 @@ var isEmptyFile = (filePath) => {
|
|
|
3846
3928
|
};
|
|
3847
3929
|
var isCommentOnlyFile = (filePath) => {
|
|
3848
3930
|
try {
|
|
3849
|
-
const content =
|
|
3931
|
+
const content = fs8.readFileSync(filePath, "utf8");
|
|
3850
3932
|
const withoutBlockComments = content.replaceAll(/\/\*[\s\S]*?\*\//g, "");
|
|
3851
3933
|
const withoutLineComments = withoutBlockComments.replaceAll(/(^|\s)\/\/.*$/gm, "$1");
|
|
3852
3934
|
return withoutLineComments.trim().length === 0;
|
|
@@ -3880,7 +3962,7 @@ var isVersionedSyncFile = (filePath) => {
|
|
|
3880
3962
|
return isVersionedSyncFileName(filePath);
|
|
3881
3963
|
};
|
|
3882
3964
|
var getFileName = (filePath) => {
|
|
3883
|
-
return
|
|
3965
|
+
return path11.basename(filePath.replaceAll("\\", "/"));
|
|
3884
3966
|
};
|
|
3885
3967
|
var stripTsExtension = (fileName) => {
|
|
3886
3968
|
return fileName.replace(/\.ts$/, "");
|
|
@@ -3956,7 +4038,7 @@ var getInvalidVersionMessage = (filePath) => {
|
|
|
3956
4038
|
var computeSrcRelativePath = (filePath) => {
|
|
3957
4039
|
try {
|
|
3958
4040
|
const srcDir = getSrcDir4();
|
|
3959
|
-
const absolute =
|
|
4041
|
+
const absolute = path11.resolve(filePath);
|
|
3960
4042
|
const normalizedSrc = srcDir.replaceAll("\\", "/");
|
|
3961
4043
|
const normalizedAbs = absolute.replaceAll("\\", "/");
|
|
3962
4044
|
if (!normalizedAbs.startsWith(`${normalizedSrc}/`)) return null;
|
|
@@ -4004,7 +4086,7 @@ var getPairedSyncFile = (filePath) => {
|
|
|
4004
4086
|
var hasPairedFile = (filePath) => {
|
|
4005
4087
|
const pairedPath = getPairedSyncFile(filePath);
|
|
4006
4088
|
if (!pairedPath) return false;
|
|
4007
|
-
return
|
|
4089
|
+
return fs8.existsSync(pairedPath);
|
|
4008
4090
|
};
|
|
4009
4091
|
var extractSyncPagePath2 = (filePath) => {
|
|
4010
4092
|
const normalized = filePath.replaceAll("\\", "/");
|
|
@@ -4017,14 +4099,14 @@ var extractSyncName2 = (filePath) => {
|
|
|
4017
4099
|
const normalized = filePath.replaceAll("\\", "/");
|
|
4018
4100
|
const match = /_sync\/(.+)\.ts$/.exec(normalized);
|
|
4019
4101
|
if (!match) {
|
|
4020
|
-
const basename =
|
|
4102
|
+
const basename = path11.basename(filePath, ".ts");
|
|
4021
4103
|
return basename.replace(/_server_v\d+$/, "").replace(/_client_v\d+$/, "");
|
|
4022
4104
|
}
|
|
4023
4105
|
return (match[1] ?? "").replace(/_server_v\d+$/, "").replace(/_client_v\d+$/, "");
|
|
4024
4106
|
};
|
|
4025
4107
|
var extractClientInputFromFile = (filePath) => {
|
|
4026
4108
|
try {
|
|
4027
|
-
const content =
|
|
4109
|
+
const content = fs8.readFileSync(filePath, "utf8");
|
|
4028
4110
|
const syncParamsMatch = /interface\s+SyncParams\s*\{/.exec(content);
|
|
4029
4111
|
if (!syncParamsMatch) return null;
|
|
4030
4112
|
const searchRegion = content.slice(syncParamsMatch.index + syncParamsMatch[0].length);
|
|
@@ -4055,7 +4137,7 @@ var extractClientInputFromFile = (filePath) => {
|
|
|
4055
4137
|
var extractClientInputFromGeneratedTypes = (pagePath, syncName) => {
|
|
4056
4138
|
try {
|
|
4057
4139
|
const generatedTypesPath = getGeneratedSocketTypesPath6();
|
|
4058
|
-
const content =
|
|
4140
|
+
const content = fs8.readFileSync(generatedTypesPath, "utf8");
|
|
4059
4141
|
const escapeRegex = (value) => value.replaceAll(/[.*+?^${}()|[\]\\]/g, String.raw`\$&`);
|
|
4060
4142
|
const escapedPagePath = escapeRegex(pagePath);
|
|
4061
4143
|
const escapedSyncName = escapeRegex(syncName);
|
|
@@ -4101,7 +4183,7 @@ var calculateRelativePath = (filePath) => {
|
|
|
4101
4183
|
const srcRelative = computeSrcRelativePath(filePath);
|
|
4102
4184
|
if (srcRelative !== null) {
|
|
4103
4185
|
try {
|
|
4104
|
-
const srcDepthFromRoot =
|
|
4186
|
+
const srcDepthFromRoot = path11.relative(ROOT_DIR7, getSrcDir4()).replaceAll("\\", "/").split("/").filter((segment) => segment.length > 0).length;
|
|
4105
4187
|
const dirSegmentsAfterSrc = Math.max(
|
|
4106
4188
|
0,
|
|
4107
4189
|
srcRelative.split("/").filter((segment) => segment.length > 0).length - 1
|
|
@@ -4180,7 +4262,7 @@ var getTemplate = (filePath) => {
|
|
|
4180
4262
|
var injectTemplate = async (filePath) => {
|
|
4181
4263
|
await ensureConsumerTemplateConfigLoaded();
|
|
4182
4264
|
if (getRouteFilenameValidationMessage(filePath)) {
|
|
4183
|
-
|
|
4265
|
+
fs8.writeFileSync(filePath, getInvalidVersionMessage(filePath), "utf8");
|
|
4184
4266
|
console.log(`[TemplateInjector] Invalid route filename, injected guidance: ${filePath}`);
|
|
4185
4267
|
return true;
|
|
4186
4268
|
}
|
|
@@ -4189,7 +4271,7 @@ var injectTemplate = async (filePath) => {
|
|
|
4189
4271
|
return false;
|
|
4190
4272
|
}
|
|
4191
4273
|
try {
|
|
4192
|
-
|
|
4274
|
+
fs8.writeFileSync(filePath, template, "utf8");
|
|
4193
4275
|
console.log(`[TemplateInjector] Injected template into: ${filePath}`);
|
|
4194
4276
|
return true;
|
|
4195
4277
|
} catch (error) {
|
|
@@ -4317,10 +4399,10 @@ var updateClientFileForPairedServer = async (clientFilePath) => {
|
|
|
4317
4399
|
try {
|
|
4318
4400
|
const pagePath = extractSyncPagePath2(clientFilePath);
|
|
4319
4401
|
const syncName = extractSyncName2(clientFilePath);
|
|
4320
|
-
let content =
|
|
4402
|
+
let content = fs8.readFileSync(clientFilePath, "utf8");
|
|
4321
4403
|
content = ensureImportedTypes(content, clientFilePath);
|
|
4322
4404
|
content = insertTypeAliases(content, pagePath, syncName);
|
|
4323
|
-
const astResult = rewriteClientInputTypeAst(content,
|
|
4405
|
+
const astResult = rewriteClientInputTypeAst(content, path11.basename(clientFilePath));
|
|
4324
4406
|
if (astResult === null) {
|
|
4325
4407
|
console.log(
|
|
4326
4408
|
`[TemplateInjector] AST clientInput rewrite unavailable for ${clientFilePath} \u2014 using regex fallback`,
|
|
@@ -4332,7 +4414,7 @@ var updateClientFileForPairedServer = async (clientFilePath) => {
|
|
|
4332
4414
|
}
|
|
4333
4415
|
content = addServerOutputToParams(content);
|
|
4334
4416
|
content = addServerOutputToDestructuring(content);
|
|
4335
|
-
|
|
4417
|
+
fs8.writeFileSync(clientFilePath, content, "utf8");
|
|
4336
4418
|
console.log(`[TemplateInjector] Updated client file to use paired types (preserved code): ${clientFilePath}`);
|
|
4337
4419
|
return true;
|
|
4338
4420
|
} catch (error) {
|
|
@@ -4373,7 +4455,7 @@ var splitAtMainBody = (content) => {
|
|
|
4373
4455
|
};
|
|
4374
4456
|
var updateClientFileForDeletedServer = async (clientFilePath, clientInputTypes) => {
|
|
4375
4457
|
try {
|
|
4376
|
-
let content =
|
|
4458
|
+
let content = fs8.readFileSync(clientFilePath, "utf8");
|
|
4377
4459
|
content = inlineClientInputType(content, clientInputTypes);
|
|
4378
4460
|
const [header, body] = splitAtMainBody(content);
|
|
4379
4461
|
const cleanedHeader = removeServerOutputFromDestructuring(removeServerOutputFromParams(header));
|
|
@@ -4381,7 +4463,7 @@ var updateClientFileForDeletedServer = async (clientFilePath, clientInputTypes)
|
|
|
4381
4463
|
content = removeGeneratedTypeImports(content);
|
|
4382
4464
|
content = removeTypeAliases(content);
|
|
4383
4465
|
content = content.replaceAll(/\n{3,}/g, "\n\n");
|
|
4384
|
-
|
|
4466
|
+
fs8.writeFileSync(clientFilePath, content, "utf8");
|
|
4385
4467
|
console.log(`[TemplateInjector] Updated client file for deleted server (preserved code): ${clientFilePath}`);
|
|
4386
4468
|
return true;
|
|
4387
4469
|
} catch (error) {
|
|
@@ -4407,7 +4489,7 @@ var injectServerTemplateWithClientInput = async (serverFilePath, clientInputType
|
|
|
4407
4489
|
/clientInput:\s*\{[^}]*\}/s,
|
|
4408
4490
|
(_match) => `clientInput: ${clientInputTypes}`
|
|
4409
4491
|
);
|
|
4410
|
-
|
|
4492
|
+
fs8.writeFileSync(serverFilePath, content, "utf8");
|
|
4411
4493
|
console.log(`[TemplateInjector] Injected server template with clientInput: ${serverFilePath}`);
|
|
4412
4494
|
return true;
|
|
4413
4495
|
} catch (error) {
|
|
@@ -4417,24 +4499,24 @@ var injectServerTemplateWithClientInput = async (serverFilePath, clientInputType
|
|
|
4417
4499
|
};
|
|
4418
4500
|
|
|
4419
4501
|
// src/importDependencyGraph.ts
|
|
4420
|
-
import
|
|
4421
|
-
import
|
|
4422
|
-
import { ROOT_DIR as
|
|
4502
|
+
import fs9 from "fs";
|
|
4503
|
+
import path12 from "path";
|
|
4504
|
+
import { ROOT_DIR as ROOT_DIR8, getServerFunctionDirs as getServerFunctionDirs2, getSharedDir, getSrcDir as getSrcDir5 } from "@luckystack/core";
|
|
4423
4505
|
var SUPPORTED_EXTENSIONS = [".ts", ".tsx", ".js", ".jsx", ".mts", ".cts"];
|
|
4424
|
-
var
|
|
4506
|
+
var normalizePath4 = (value) => path12.resolve(value).replaceAll("\\", "/");
|
|
4425
4507
|
var isSupportedScriptFile = (value) => {
|
|
4426
4508
|
return SUPPORTED_EXTENSIONS.some((extension) => value.endsWith(extension));
|
|
4427
4509
|
};
|
|
4428
4510
|
var existsFile = (value) => {
|
|
4429
4511
|
try {
|
|
4430
|
-
return
|
|
4512
|
+
return fs9.existsSync(value) && fs9.statSync(value).isFile();
|
|
4431
4513
|
} catch {
|
|
4432
4514
|
return false;
|
|
4433
4515
|
}
|
|
4434
4516
|
};
|
|
4435
4517
|
var existsDirectory = (value) => {
|
|
4436
4518
|
try {
|
|
4437
|
-
return
|
|
4519
|
+
return fs9.existsSync(value) && fs9.statSync(value).isDirectory();
|
|
4438
4520
|
} catch {
|
|
4439
4521
|
return false;
|
|
4440
4522
|
}
|
|
@@ -4445,23 +4527,23 @@ var collectScriptFiles = (dir, output, visited = /* @__PURE__ */ new Set()) => {
|
|
|
4445
4527
|
}
|
|
4446
4528
|
let realDir;
|
|
4447
4529
|
try {
|
|
4448
|
-
realDir =
|
|
4530
|
+
realDir = fs9.realpathSync(dir);
|
|
4449
4531
|
} catch {
|
|
4450
4532
|
return;
|
|
4451
4533
|
}
|
|
4452
4534
|
if (visited.has(realDir)) return;
|
|
4453
4535
|
visited.add(realDir);
|
|
4454
|
-
const entries =
|
|
4536
|
+
const entries = fs9.readdirSync(dir, { withFileTypes: true });
|
|
4455
4537
|
for (const entry of entries) {
|
|
4456
4538
|
if (entry.name === "node_modules") continue;
|
|
4457
|
-
const fullPath =
|
|
4539
|
+
const fullPath = path12.join(dir, entry.name);
|
|
4458
4540
|
if (entry.isDirectory() || entry.isSymbolicLink()) {
|
|
4459
4541
|
if (existsDirectory(fullPath)) {
|
|
4460
4542
|
collectScriptFiles(fullPath, output, visited);
|
|
4461
4543
|
}
|
|
4462
4544
|
continue;
|
|
4463
4545
|
}
|
|
4464
|
-
const normalizedPath =
|
|
4546
|
+
const normalizedPath = normalizePath4(fullPath);
|
|
4465
4547
|
if (isSupportedScriptFile(normalizedPath)) {
|
|
4466
4548
|
output.add(normalizedPath);
|
|
4467
4549
|
}
|
|
@@ -4473,7 +4555,7 @@ var SCOPED_FILES_TTL_MS = 1e3;
|
|
|
4473
4555
|
var extractImportSpecifiers = (filePath) => {
|
|
4474
4556
|
let mtimeMs = 0;
|
|
4475
4557
|
try {
|
|
4476
|
-
mtimeMs =
|
|
4558
|
+
mtimeMs = fs9.statSync(filePath).mtimeMs;
|
|
4477
4559
|
} catch {
|
|
4478
4560
|
specifiersCache.delete(filePath);
|
|
4479
4561
|
return [];
|
|
@@ -4483,7 +4565,7 @@ var extractImportSpecifiers = (filePath) => {
|
|
|
4483
4565
|
return cached.specifiers;
|
|
4484
4566
|
}
|
|
4485
4567
|
try {
|
|
4486
|
-
const source =
|
|
4568
|
+
const source = fs9.readFileSync(filePath, "utf8");
|
|
4487
4569
|
const specifiers = /* @__PURE__ */ new Set();
|
|
4488
4570
|
const importExportRegex = /(?:import|export)\s+(?:[\s\S]*?\s+from\s+)?['"]([^'"]+)['"]/g;
|
|
4489
4571
|
const dynamicImportRegex = /import\(\s*['"]([^'"]+)['"]\s*\)/g;
|
|
@@ -4503,24 +4585,24 @@ var extractImportSpecifiers = (filePath) => {
|
|
|
4503
4585
|
}
|
|
4504
4586
|
};
|
|
4505
4587
|
var invalidateGraphForFile = (absolutePath) => {
|
|
4506
|
-
specifiersCache.delete(
|
|
4588
|
+
specifiersCache.delete(normalizePath4(absolutePath));
|
|
4507
4589
|
scopedFilesCache = null;
|
|
4508
4590
|
};
|
|
4509
4591
|
var tryResolveWithExtensions = (basePath) => {
|
|
4510
4592
|
if (existsFile(basePath)) {
|
|
4511
|
-
return
|
|
4593
|
+
return normalizePath4(basePath);
|
|
4512
4594
|
}
|
|
4513
4595
|
for (const extension of SUPPORTED_EXTENSIONS) {
|
|
4514
4596
|
const withExtension = `${basePath}${extension}`;
|
|
4515
4597
|
if (existsFile(withExtension)) {
|
|
4516
|
-
return
|
|
4598
|
+
return normalizePath4(withExtension);
|
|
4517
4599
|
}
|
|
4518
4600
|
}
|
|
4519
4601
|
if (existsDirectory(basePath)) {
|
|
4520
4602
|
for (const extension of SUPPORTED_EXTENSIONS) {
|
|
4521
|
-
const indexFile =
|
|
4603
|
+
const indexFile = path12.join(basePath, `index${extension}`);
|
|
4522
4604
|
if (existsFile(indexFile)) {
|
|
4523
|
-
return
|
|
4605
|
+
return normalizePath4(indexFile);
|
|
4524
4606
|
}
|
|
4525
4607
|
}
|
|
4526
4608
|
}
|
|
@@ -4531,18 +4613,18 @@ var resolveImportToFile = (importerPath, specifier) => {
|
|
|
4531
4613
|
return null;
|
|
4532
4614
|
}
|
|
4533
4615
|
if (specifier === "config") {
|
|
4534
|
-
return tryResolveWithExtensions(
|
|
4616
|
+
return tryResolveWithExtensions(path12.join(ROOT_DIR8, "config"));
|
|
4535
4617
|
}
|
|
4536
4618
|
if (specifier.startsWith("./") || specifier.startsWith("../")) {
|
|
4537
|
-
const relativeBase =
|
|
4619
|
+
const relativeBase = path12.resolve(path12.dirname(importerPath), specifier);
|
|
4538
4620
|
return tryResolveWithExtensions(relativeBase);
|
|
4539
4621
|
}
|
|
4540
4622
|
if (specifier.startsWith("src/") || specifier.startsWith("@/")) {
|
|
4541
4623
|
const sourcePath = specifier.startsWith("@/") ? specifier.slice(2) : specifier.slice(4);
|
|
4542
|
-
return tryResolveWithExtensions(
|
|
4624
|
+
return tryResolveWithExtensions(path12.join(getSrcDir5(), sourcePath));
|
|
4543
4625
|
}
|
|
4544
4626
|
if (specifier.startsWith("shared/")) {
|
|
4545
|
-
return tryResolveWithExtensions(
|
|
4627
|
+
return tryResolveWithExtensions(path12.join(getSharedDir(), specifier.slice(7)));
|
|
4546
4628
|
}
|
|
4547
4629
|
return null;
|
|
4548
4630
|
};
|
|
@@ -4557,10 +4639,10 @@ var collectScopedFiles = () => {
|
|
|
4557
4639
|
const files = /* @__PURE__ */ new Set();
|
|
4558
4640
|
collectScriptFiles(getSrcDir5(), files);
|
|
4559
4641
|
collectScriptFiles(getSharedDir(), files);
|
|
4560
|
-
for (const dir of
|
|
4642
|
+
for (const dir of getServerFunctionDirs2()) {
|
|
4561
4643
|
collectScriptFiles(dir, files);
|
|
4562
4644
|
}
|
|
4563
|
-
const configFile = tryResolveWithExtensions(
|
|
4645
|
+
const configFile = tryResolveWithExtensions(path12.join(ROOT_DIR8, "config"));
|
|
4564
4646
|
if (configFile) {
|
|
4565
4647
|
files.add(configFile);
|
|
4566
4648
|
}
|
|
@@ -4569,7 +4651,7 @@ var collectScopedFiles = () => {
|
|
|
4569
4651
|
};
|
|
4570
4652
|
var findDependentRouteFiles = (changedFilePath) => {
|
|
4571
4653
|
const scopedFiles = collectScopedFiles();
|
|
4572
|
-
const changedAbsolutePath =
|
|
4654
|
+
const changedAbsolutePath = normalizePath4(changedFilePath);
|
|
4573
4655
|
const reverseDependencies = /* @__PURE__ */ new Map();
|
|
4574
4656
|
for (const filePath of scopedFiles) {
|
|
4575
4657
|
const specifiers = extractImportSpecifiers(filePath);
|
|
@@ -4608,27 +4690,27 @@ var findDependentRouteFiles = (changedFilePath) => {
|
|
|
4608
4690
|
};
|
|
4609
4691
|
|
|
4610
4692
|
// src/prismaClientCheck.ts
|
|
4611
|
-
import
|
|
4612
|
-
import
|
|
4693
|
+
import fs10 from "fs";
|
|
4694
|
+
import path13 from "path";
|
|
4613
4695
|
import { spawn } from "child_process";
|
|
4614
|
-
import { ROOT_DIR as
|
|
4615
|
-
var GENERATED_CLIENT_DIR =
|
|
4616
|
-
var GENERATED_CLIENT_MARKER =
|
|
4617
|
-
var DEFAULT_SCHEMA_PATH =
|
|
4618
|
-
var isPrismaClientMissing = () =>
|
|
4696
|
+
import { ROOT_DIR as ROOT_DIR9, tryCatch as tryCatch2 } from "@luckystack/core";
|
|
4697
|
+
var GENERATED_CLIENT_DIR = path13.join(ROOT_DIR9, "node_modules", ".prisma", "client");
|
|
4698
|
+
var GENERATED_CLIENT_MARKER = path13.join(GENERATED_CLIENT_DIR, "schema.prisma");
|
|
4699
|
+
var DEFAULT_SCHEMA_PATH = path13.join(ROOT_DIR9, "prisma", "schema.prisma");
|
|
4700
|
+
var isPrismaClientMissing = () => fs10.existsSync(DEFAULT_SCHEMA_PATH) && !fs10.existsSync(GENERATED_CLIENT_MARKER);
|
|
4619
4701
|
var runPrismaGenerate = async () => tryCatch2(
|
|
4620
4702
|
() => new Promise((resolve, reject) => {
|
|
4621
4703
|
const localBinName = process.platform === "win32" ? "prisma.cmd" : "prisma";
|
|
4622
|
-
const localBin =
|
|
4623
|
-
const useLocal =
|
|
4704
|
+
const localBin = path13.join(ROOT_DIR9, "node_modules", ".bin", localBinName);
|
|
4705
|
+
const useLocal = fs10.existsSync(localBin);
|
|
4624
4706
|
const [cmd, args] = useLocal ? [localBin, ["generate"]] : [process.platform === "win32" ? "npx.cmd" : "npx", ["prisma", "generate"]];
|
|
4625
4707
|
const isWinShim = process.platform === "win32" && /\.(cmd|bat)$/i.test(cmd);
|
|
4626
4708
|
const child = isWinShim ? spawn(
|
|
4627
4709
|
process.env.ComSpec ?? "cmd.exe",
|
|
4628
4710
|
["/d", "/s", "/c", `""${cmd}" ${args.join(" ")}"`],
|
|
4629
|
-
{ cwd:
|
|
4711
|
+
{ cwd: ROOT_DIR9, stdio: "inherit", windowsVerbatimArguments: true }
|
|
4630
4712
|
) : spawn(cmd, args, {
|
|
4631
|
-
cwd:
|
|
4713
|
+
cwd: ROOT_DIR9,
|
|
4632
4714
|
stdio: "inherit",
|
|
4633
4715
|
shell: false
|
|
4634
4716
|
});
|
|
@@ -4641,7 +4723,7 @@ var runPrismaGenerate = async () => tryCatch2(
|
|
|
4641
4723
|
|
|
4642
4724
|
// src/hotReload.ts
|
|
4643
4725
|
import { tryCatch as tryCatch3, getProjectConfig, getLocaleReloader, isProductionRuntime } from "@luckystack/core";
|
|
4644
|
-
var normalizeFsPath = (value) =>
|
|
4726
|
+
var normalizeFsPath = (value) => path14.resolve(value).replaceAll("\\", "/");
|
|
4645
4727
|
var isGeneratedPath = (normalizedPath) => {
|
|
4646
4728
|
return normalizedPath.includes("apiTypes.generated.ts") || normalizedPath.includes("apiDocs.generated.json");
|
|
4647
4729
|
};
|
|
@@ -4849,7 +4931,7 @@ var setupWatchers = () => {
|
|
|
4849
4931
|
if (shouldInjectTemplate(filePath, { isNewFile: true })) {
|
|
4850
4932
|
if (isSyncServerFile(normalizedPath)) {
|
|
4851
4933
|
const clientPath = getPairedSyncFile(normalizedPath);
|
|
4852
|
-
if (clientPath &&
|
|
4934
|
+
if (clientPath && fs11.existsSync(clientPath) && !isEmptyFile(clientPath)) {
|
|
4853
4935
|
const clientInputTypes = extractClientInputFromFile(clientPath);
|
|
4854
4936
|
if (clientInputTypes) {
|
|
4855
4937
|
await injectServerTemplateWithClientInput(filePath, clientInputTypes);
|
|
@@ -5012,7 +5094,7 @@ var setupWatchers = () => {
|
|
|
5012
5094
|
scheduleReload("sync", async () => {
|
|
5013
5095
|
if (isSyncServerFile(normalizedPath)) {
|
|
5014
5096
|
const clientPath = getPairedSyncFile(normalizedPath);
|
|
5015
|
-
if (clientPath &&
|
|
5097
|
+
if (clientPath && fs11.existsSync(clientPath)) {
|
|
5016
5098
|
const pagePath = extractSyncPagePath2(normalizedPath);
|
|
5017
5099
|
const syncName = extractSyncName2(normalizedPath);
|
|
5018
5100
|
const clientInputTypes = extractClientInputFromGeneratedTypes(pagePath, syncName);
|
|
@@ -5075,9 +5157,14 @@ export {
|
|
|
5075
5157
|
clearRuntimeTypeResolverCache,
|
|
5076
5158
|
clearTemplateOverrides,
|
|
5077
5159
|
clearTemplateRules,
|
|
5160
|
+
collectFunctionModules,
|
|
5078
5161
|
devApis,
|
|
5079
5162
|
devFunctions,
|
|
5080
5163
|
devSyncs,
|
|
5164
|
+
formatFunctionKeyConflict,
|
|
5165
|
+
formatFunctionKeyPath,
|
|
5166
|
+
formatFunctionNamespaceConflict,
|
|
5167
|
+
functionModuleFileName,
|
|
5081
5168
|
generateTypeMapFile,
|
|
5082
5169
|
getInputTypeFromFile,
|
|
5083
5170
|
getRegisteredTemplate,
|
|
@@ -5100,6 +5187,7 @@ export {
|
|
|
5100
5187
|
registerTemplateRule,
|
|
5101
5188
|
removeApiFromFile,
|
|
5102
5189
|
removeSyncFromFile,
|
|
5190
|
+
renderFunctionsMap,
|
|
5103
5191
|
resolveRuntimeTypeText,
|
|
5104
5192
|
resolveTemplateKind,
|
|
5105
5193
|
setupWatchers,
|