@faapi/faapi 0.0.0-canary.9a79cdf → 0.0.0-canary.b2b338c

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/cli/index.js CHANGED
@@ -89,8 +89,8 @@ function isInsideDir(filePath, dir) {
89
89
  const rel = path2.relative(dir, filePath);
90
90
  return rel !== "" && !rel.startsWith("..") && !path2.isAbsolute(rel);
91
91
  }
92
- function toStrippedProdImportPath(sourceFile, rootDir, appDir) {
93
- const appDirAbs = toRealPath(path2.resolve(rootDir, appDir));
92
+ function toStrippedProdImportPath(sourceFile, rootDir) {
93
+ const appDirAbs = toRealPath(path2.resolve(rootDir, APP_DIR));
94
94
  const sourceReal = toRealPath(sourceFile);
95
95
  let rel = path2.relative(appDirAbs, sourceReal);
96
96
  rel = rel.split(path2.sep).join("/");
@@ -118,7 +118,7 @@ function resolveRelativeSpecifier(importer, specifier) {
118
118
  }
119
119
  function createAliasPlugin(config, options) {
120
120
  const SPEC_RE2 = /(\bfrom\s*|import\s*\(\s*)(['"])([^'"]+)\2/g;
121
- const appDirAbs = options?.rootDir && options?.appDir ? toRealPath(path2.resolve(options.rootDir, options.appDir)) : null;
121
+ const appDirAbs = options?.rootDir ? toRealPath(path2.resolve(options.rootDir, APP_DIR)) : null;
122
122
  return {
123
123
  name: "faapi-alias",
124
124
  setup(build) {
@@ -146,8 +146,7 @@ function createAliasPlugin(config, options) {
146
146
  modified = true;
147
147
  return `${prefix}${quote}${toStrippedProdImportPath(
148
148
  resolved,
149
- options.rootDir,
150
- options.appDir
149
+ options.rootDir
151
150
  )}${quote}`;
152
151
  }
153
152
  modified = true;
@@ -164,8 +163,7 @@ function createAliasPlugin(config, options) {
164
163
  if (appDirAbs && importerOutsideAppDir && isInsideDir(file, appDirAbs)) {
165
164
  return `${prefix}${quote}${toStrippedProdImportPath(
166
165
  file,
167
- options.rootDir,
168
- options.appDir
166
+ options.rootDir
169
167
  )}${quote}`;
170
168
  }
171
169
  return `${prefix}${quote}${toProdImportPath(file, importer)}${quote}`;
@@ -178,8 +176,7 @@ function createAliasPlugin(config, options) {
178
176
  if (appDirAbs && importerOutsideAppDir && isInsideDir(file, appDirAbs)) {
179
177
  return `${prefix}${quote}${toStrippedProdImportPath(
180
178
  file,
181
- options.rootDir,
182
- options.appDir
179
+ options.rootDir
183
180
  )}${quote}`;
184
181
  }
185
182
  return `${prefix}${quote}${toProdImportPath(file, importer)}${quote}`;
@@ -194,21 +191,17 @@ function createAliasPlugin(config, options) {
194
191
  }
195
192
  };
196
193
  }
197
- function buildAliasPlugins(rootDir, appDir) {
194
+ function buildAliasPlugins(rootDir) {
198
195
  const tsconfig = readTsconfig(rootDir);
199
- return [
200
- createAliasPlugin(
201
- tsconfig ?? { baseUrl: ".", paths: {} },
202
- appDir ? { rootDir, appDir } : void 0
203
- )
204
- ];
196
+ return [createAliasPlugin(tsconfig ?? { baseUrl: ".", paths: {} }, { rootDir })];
205
197
  }
206
- var PROD_EXTS, SOURCE_EXTS, INDEX_EXTS;
198
+ var APP_DIR, PROD_EXTS, SOURCE_EXTS, INDEX_EXTS;
207
199
  var init_aliasPlugin = __esm({
208
200
  "src/cli/aliasPlugin.ts"() {
209
201
  "use strict";
210
202
  init_resolveAlias();
211
203
  init_readTsconfig();
204
+ APP_DIR = "src";
212
205
  PROD_EXTS = [".js", ".mjs", ".cjs"];
213
206
  SOURCE_EXTS = [".ts", ".tsx", ".js", ".jsx", ".mjs", ".cjs"];
214
207
  INDEX_EXTS = [
@@ -227,8 +220,8 @@ import path3 from "path";
227
220
  import fs3 from "fs";
228
221
  import fg from "fast-glob";
229
222
  async function compileDevRoutes(options) {
230
- const { rootDir, appDir, outDir, files, logLevel = "silent" } = options;
231
- const entryPoints = files ?? await fg([`${appDir}/**/*.ts`], {
223
+ const { rootDir, dist, files, logLevel = "silent" } = options;
224
+ const entryPoints = files ?? await fg([`${APP_DIR2}/**/*.ts`], {
232
225
  cwd: rootDir,
233
226
  onlyFiles: true,
234
227
  absolute: true,
@@ -237,14 +230,14 @@ async function compileDevRoutes(options) {
237
230
  if (entryPoints.length === 0) {
238
231
  return { compiledFiles: [] };
239
232
  }
240
- const absOutDir = path3.resolve(rootDir, outDir);
241
- await fs3.promises.mkdir(absOutDir, { recursive: true });
233
+ const absDist = path3.resolve(rootDir, dist);
234
+ await fs3.promises.mkdir(absDist, { recursive: true });
242
235
  const plugins = buildAliasPlugins(rootDir);
243
236
  const esbuild = await import("esbuild");
244
- const outbase = appDir === "." ? rootDir : path3.resolve(rootDir, appDir);
237
+ const outbase = path3.resolve(rootDir, APP_DIR2);
245
238
  await esbuild.build({
246
239
  entryPoints,
247
- outdir: absOutDir,
240
+ outdir: absDist,
248
241
  outbase,
249
242
  bundle: false,
250
243
  platform: "node",
@@ -256,10 +249,12 @@ async function compileDevRoutes(options) {
256
249
  });
257
250
  return { compiledFiles: entryPoints };
258
251
  }
252
+ var APP_DIR2;
259
253
  var init_compileDevRoutes = __esm({
260
254
  "src/cli/compileDevRoutes.ts"() {
261
255
  "use strict";
262
256
  init_aliasPlugin();
257
+ APP_DIR2 = "src";
263
258
  }
264
259
  });
265
260
 
@@ -347,8 +342,8 @@ function extractRelativeSpecifiers(source) {
347
342
  }
348
343
  return specifiers;
349
344
  }
350
- async function collectRelativeImports(entryFiles, rootDir, appDir) {
351
- const appDirAbs = toRealPath2(path4.resolve(rootDir, appDir));
345
+ async function collectRelativeImports(entryFiles, rootDir) {
346
+ const appDirAbs = toRealPath2(path4.resolve(rootDir, "src"));
352
347
  const visited = /* @__PURE__ */ new Set();
353
348
  const appDirFiles = /* @__PURE__ */ new Set();
354
349
  const nonAppDirFiles = /* @__PURE__ */ new Set();
@@ -394,30 +389,26 @@ function createExternalRelativePlugin() {
394
389
  };
395
390
  }
396
391
  async function compileConfig(options) {
397
- const { rootDir, outDir, appDir = "src" } = options;
392
+ const { rootDir, dist } = options;
398
393
  const baseConfigName = findBaseConfig(rootDir);
399
394
  if (!baseConfigName) {
400
395
  return { generated: false, outputFile: "" };
401
396
  }
402
397
  const env = getEnv();
403
398
  const envConfigName = findEnvConfig(rootDir, env);
404
- const absOutDir = path4.resolve(rootDir, outDir);
405
- await fs4.promises.mkdir(absOutDir, { recursive: true });
399
+ const absDist = path4.resolve(rootDir, dist);
400
+ await fs4.promises.mkdir(absDist, { recursive: true });
406
401
  const configEntryPoints = [path4.resolve(rootDir, baseConfigName)];
407
402
  if (envConfigName) {
408
403
  configEntryPoints.push(path4.resolve(rootDir, envConfigName));
409
404
  }
410
- const { appDirFiles, nonAppDirFiles } = await collectRelativeImports(
411
- configEntryPoints,
412
- rootDir,
413
- appDir
414
- );
405
+ const { appDirFiles, nonAppDirFiles } = await collectRelativeImports(configEntryPoints, rootDir);
415
406
  const esbuild = await import("esbuild");
416
- const aliasPlugins = buildAliasPlugins(rootDir, appDir);
407
+ const aliasPlugins = buildAliasPlugins(rootDir);
417
408
  const step1aEntries = [...configEntryPoints, ...nonAppDirFiles];
418
409
  await esbuild.build({
419
410
  entryPoints: step1aEntries,
420
- outdir: absOutDir,
411
+ outdir: absDist,
421
412
  outbase: rootDir,
422
413
  bundle: false,
423
414
  platform: "node",
@@ -428,10 +419,10 @@ async function compileConfig(options) {
428
419
  logLevel: "silent"
429
420
  });
430
421
  if (appDirFiles.length > 0) {
431
- const appOutbase = appDir === "." ? rootDir : path4.resolve(rootDir, appDir);
422
+ const appOutbase = path4.resolve(rootDir, "src");
432
423
  await esbuild.build({
433
424
  entryPoints: appDirFiles,
434
- outdir: absOutDir,
425
+ outdir: absDist,
435
426
  outbase: appOutbase,
436
427
  bundle: false,
437
428
  platform: "node",
@@ -453,9 +444,9 @@ async function compileConfig(options) {
453
444
  exportDefault = "export default base;";
454
445
  }
455
446
  const entryCode = [...imports, DEEP_MERGE_SOURCE, exportDefault].join("\n");
456
- const outputFile = path4.resolve(absOutDir, "faapi-config.js");
447
+ const outputFile = path4.resolve(absDist, "faapi-config.js");
457
448
  await esbuild.build({
458
- stdin: { contents: entryCode, resolveDir: absOutDir, loader: "ts" },
449
+ stdin: { contents: entryCode, resolveDir: absDist, loader: "ts" },
459
450
  outfile: outputFile,
460
451
  bundle: true,
461
452
  format: "esm",
@@ -1684,25 +1675,25 @@ var init_generateZodSchema = __esm({
1684
1675
  // src/cli/generateSchemaFiles.ts
1685
1676
  import path6 from "path";
1686
1677
  import fs5 from "fs/promises";
1687
- function getSchemaOutputPath(sourceFile, appDir, outDir, rootDir) {
1678
+ function getSchemaOutputPath(sourceFile, dist, rootDir) {
1688
1679
  let rel = sourceFile.replace(/\\/g, "/");
1689
- if (appDir !== "." && rel.startsWith(`${appDir}/`)) {
1690
- rel = rel.slice(appDir.length + 1);
1680
+ if (rel.startsWith("src/")) {
1681
+ rel = rel.slice(4);
1691
1682
  }
1692
1683
  const idx = rel.lastIndexOf("/");
1693
1684
  const relDir = idx >= 0 ? rel.slice(0, idx) : "";
1694
- return path6.resolve(rootDir, outDir, relDir, "zod.js");
1685
+ return path6.resolve(rootDir, dist, relDir, "zod.js");
1695
1686
  }
1696
- function getRuntimeSchemaPath(filePath, appDir, outDir, rootDir) {
1687
+ function getRuntimeSchemaPath(filePath, dist, rootDir) {
1697
1688
  let rel = filePath.replace(/\\/g, "/");
1698
- if (appDir !== "." && rel.startsWith(`${appDir}/`)) {
1699
- rel = rel.slice(appDir.length + 1);
1700
- } else if (rel.startsWith(`${outDir}/`)) {
1701
- rel = rel.slice(outDir.length + 1);
1689
+ if (rel.startsWith("src/")) {
1690
+ rel = rel.slice(4);
1691
+ } else if (rel.startsWith(`${dist}/`)) {
1692
+ rel = rel.slice(dist.length + 1);
1702
1693
  }
1703
1694
  const idx = rel.lastIndexOf("/");
1704
1695
  const relDir = idx >= 0 ? rel.slice(0, idx) : "";
1705
- return path6.resolve(rootDir, outDir, relDir, "zod.js");
1696
+ return path6.resolve(rootDir, dist, relDir, "zod.js");
1706
1697
  }
1707
1698
  function getHelpersImportPath(relDir) {
1708
1699
  if (!relDir) return `./${HELPERS_FILENAME}`;
@@ -1738,7 +1729,7 @@ function generateSchemaFileSource(sources, allTypes, helpersImportPath) {
1738
1729
  lines.push(...schemaBlocks);
1739
1730
  return lines.join("\n").replace(/\n+$/, "\n");
1740
1731
  }
1741
- async function generateSchemaFiles(routes, rootDir, appDir, outDir) {
1732
+ async function generateSchemaFiles(routes, rootDir, dist) {
1742
1733
  if (routes.length === 0) return;
1743
1734
  const { sources, allTypesByFile } = collectRouteSchemaSources(routes, rootDir);
1744
1735
  const sourcesByFile = /* @__PURE__ */ new Map();
@@ -1753,11 +1744,11 @@ async function generateSchemaFiles(routes, rootDir, appDir, outDir) {
1753
1744
  const fileEntries = [];
1754
1745
  for (const [filePath, fileSources] of sourcesByFile) {
1755
1746
  const relFile = path6.relative(rootDir, filePath).replace(/\\/g, "/");
1756
- const outputPath = getSchemaOutputPath(relFile, appDir, outDir, rootDir);
1747
+ const outputPath = getSchemaOutputPath(relFile, dist, rootDir);
1757
1748
  const allTypes = allTypesByFile.get(filePath) ?? /* @__PURE__ */ new Map();
1758
1749
  let relForDir = relFile;
1759
- if (appDir !== "." && relForDir.startsWith(`${appDir}/`)) {
1760
- relForDir = relForDir.slice(appDir.length + 1);
1750
+ if (relForDir.startsWith("src/")) {
1751
+ relForDir = relForDir.slice(4);
1761
1752
  }
1762
1753
  const dirIdx = relForDir.lastIndexOf("/");
1763
1754
  const zodRelDir = dirIdx >= 0 ? relForDir.slice(0, dirIdx) : "";
@@ -1767,7 +1758,7 @@ async function generateSchemaFiles(routes, rootDir, appDir, outDir) {
1767
1758
  }
1768
1759
  const allSourceCode = fileEntries.map((e) => e.source).join("\n");
1769
1760
  if (usesCoerceHelpers(allSourceCode)) {
1770
- const helpersPath = path6.resolve(rootDir, outDir, HELPERS_FILENAME);
1761
+ const helpersPath = path6.resolve(rootDir, dist, HELPERS_FILENAME);
1771
1762
  await writeSchemaFile(helpersPath, generateHelpersFileSource());
1772
1763
  }
1773
1764
  await Promise.all(
@@ -1860,20 +1851,20 @@ var init_loadMiddlewares = __esm({
1860
1851
  // src/cli/generateRoutes.ts
1861
1852
  import fs6 from "fs";
1862
1853
  import path7 from "path";
1863
- function toProdFilePath(filePath, appDir, prodDir) {
1854
+ function toProdFilePath(filePath, dist) {
1864
1855
  let rel = filePath.replace(/\\/g, "/");
1865
- if (appDir !== "." && rel.startsWith(`${appDir}/`)) {
1866
- rel = rel.slice(appDir.length + 1);
1856
+ if (rel.startsWith("src/")) {
1857
+ rel = rel.slice(4);
1867
1858
  }
1868
1859
  const jsPath = rel.replace(/\.ts$/, ".js");
1869
- return jsPath.startsWith(`${prodDir}/`) ? jsPath : `${prodDir}/${jsPath}`;
1860
+ return jsPath.startsWith(`${dist}/`) ? jsPath : `${dist}/${jsPath}`;
1870
1861
  }
1871
- function serializeRoutes(routes, wsRoutes, rootDir, appDir = "src", prodDir = "dist") {
1862
+ function serializeRoutes(routes, wsRoutes, rootDir, dist = "dist") {
1872
1863
  const serialize = (route) => {
1873
- const middlewarePaths = extractMiddlewarePaths(route.filePath, rootDir, appDir, prodDir);
1864
+ const middlewarePaths = extractMiddlewarePaths(route.filePath, rootDir, dist);
1874
1865
  const serialized = {
1875
1866
  urlPath: route.urlPath,
1876
- filePath: toProdFilePath(route.filePath, appDir, prodDir),
1867
+ filePath: toProdFilePath(route.filePath, dist),
1877
1868
  paramNames: route.paramNames,
1878
1869
  isDynamic: route.isDynamic,
1879
1870
  isCatchAll: route.isCatchAll,
@@ -1889,7 +1880,7 @@ function serializeRoutes(routes, wsRoutes, rootDir, appDir = "src", prodDir = "d
1889
1880
  wsRoutes: wsRoutes.map(serialize)
1890
1881
  };
1891
1882
  }
1892
- function extractMiddlewarePaths(routeFilePath, rootDir, appDir, prodDir) {
1883
+ function extractMiddlewarePaths(routeFilePath, rootDir, dist) {
1893
1884
  const routeDir = path7.dirname(routeFilePath);
1894
1885
  const resolvedRoot = path7.resolve(rootDir);
1895
1886
  const paths = [];
@@ -1902,7 +1893,7 @@ function extractMiddlewarePaths(routeFilePath, rootDir, appDir, prodDir) {
1902
1893
  const absMwPath = fs6.existsSync(absTsPath) ? absTsPath : fs6.existsSync(absJsPath) ? absJsPath : null;
1903
1894
  if (absMwPath) {
1904
1895
  const relMwPath = path7.relative(rootDir, absMwPath);
1905
- const prodAbsPath = path7.resolve(rootDir, toProdFilePath(relMwPath, appDir, prodDir));
1896
+ const prodAbsPath = path7.resolve(rootDir, toProdFilePath(relMwPath, dist));
1906
1897
  paths.push(prodAbsPath);
1907
1898
  }
1908
1899
  if (currentDir === resolvedRoot) break;
@@ -2032,8 +2023,8 @@ function isCatchAllSegment(segment) {
2032
2023
  function isRouteGroup(segment) {
2033
2024
  return /^\(.+\)$/.test(segment);
2034
2025
  }
2035
- function filePathToUrlPath(filePath, appDir = ".") {
2036
- const withoutPrefix = filePath.startsWith(appDir + "/") ? filePath.slice(appDir.length + 1) : filePath;
2026
+ function filePathToUrlPath(filePath) {
2027
+ const withoutPrefix = filePath.startsWith("src/") ? filePath.slice(4) : filePath;
2037
2028
  const lastSlashIndex = withoutPrefix.lastIndexOf("/");
2038
2029
  const dirPath = lastSlashIndex === -1 ? "" : withoutPrefix.slice(0, lastSlashIndex);
2039
2030
  if (!dirPath) {
@@ -2053,24 +2044,24 @@ var init_parseRouteFile = __esm({
2053
2044
  import fg2 from "fast-glob";
2054
2045
  import path8 from "path";
2055
2046
  import fs7 from "fs";
2056
- function toProdAbsPath(sourceAbsPath, rootDir, appDir, prodDir) {
2047
+ function toProdAbsPath(sourceAbsPath, rootDir, dist) {
2057
2048
  let rel = path8.relative(rootDir, sourceAbsPath).replace(/\\/g, "/");
2058
- if (appDir !== "." && rel.startsWith(`${appDir}/`)) {
2059
- rel = rel.slice(appDir.length + 1);
2049
+ if (rel.startsWith(`${APP_DIR3}/`)) {
2050
+ rel = rel.slice(APP_DIR3.length + 1);
2060
2051
  }
2061
- const prodRel = `${prodDir}/${rel.replace(/\.ts$/, ".js")}`;
2052
+ const prodRel = `${dist}/${rel.replace(/\.ts$/, ".js")}`;
2062
2053
  return path8.resolve(rootDir, prodRel);
2063
2054
  }
2064
- async function findMergedMiddlewares(routeFilePath, rootDir, appDir, prodDir) {
2055
+ async function findMergedMiddlewares(routeFilePath, rootDir, dist) {
2065
2056
  const routeDir = path8.dirname(routeFilePath);
2066
2057
  const resolvedRoot = path8.resolve(rootDir);
2067
2058
  const mwPaths = [];
2068
2059
  let currentDir = path8.resolve(rootDir, routeDir);
2069
2060
  while (true) {
2070
- if (prodDir) {
2061
+ if (dist) {
2071
2062
  const mwPath = path8.join(currentDir, "middlewares.js");
2072
2063
  const absMwPath = path8.resolve(rootDir, mwPath);
2073
- const prodAbsMwPath = toProdAbsPath(absMwPath, rootDir, appDir, prodDir);
2064
+ const prodAbsMwPath = toProdAbsPath(absMwPath, rootDir, dist);
2074
2065
  if (fs7.existsSync(prodAbsMwPath)) {
2075
2066
  mwPaths.push(prodAbsMwPath);
2076
2067
  }
@@ -2135,8 +2126,7 @@ async function hasWsExport(absPath) {
2135
2126
  return false;
2136
2127
  }
2137
2128
  }
2138
- async function scanRoutes(rootDir, patterns, appDir, prodDir) {
2139
- const dir = appDir ?? ".";
2129
+ async function scanRoutes(rootDir, patterns, dist) {
2140
2130
  const files = await fg2(patterns, {
2141
2131
  cwd: rootDir,
2142
2132
  onlyFiles: true,
@@ -2149,12 +2139,12 @@ async function scanRoutes(rootDir, patterns, appDir, prodDir) {
2149
2139
  const fileName = normalizedFile.split("/").pop();
2150
2140
  if (fileName === "handler.ts" || fileName === "handler.js") {
2151
2141
  const absPath = path8.resolve(rootDir, normalizedFile);
2152
- const importPath = prodDir ? toProdAbsPath(absPath, rootDir, dir, prodDir) : absPath;
2153
- const urlPath = filePathToUrlPath(normalizedFile, dir);
2142
+ const importPath = dist ? toProdAbsPath(absPath, rootDir, dist) : absPath;
2143
+ const urlPath = filePathToUrlPath(normalizedFile);
2154
2144
  const paramNames = extractParamNames(urlPath);
2155
2145
  const isDynamic = paramNames.length > 0;
2156
2146
  const isCatchAll = normalizedFile.split("/").some(isCatchAllSegment);
2157
- const middlewareBundle = await findMergedMiddlewares(normalizedFile, rootDir, dir, prodDir);
2147
+ const middlewareBundle = await findMergedMiddlewares(normalizedFile, rootDir, dist);
2158
2148
  const methods = await extractMethodsFromHandler(importPath);
2159
2149
  for (const method of methods) {
2160
2150
  routes.push({
@@ -2185,6 +2175,7 @@ async function scanRoutes(rootDir, patterns, appDir, prodDir) {
2185
2175
  }
2186
2176
  return { routes, wsRoutes };
2187
2177
  }
2178
+ var APP_DIR3;
2188
2179
  var init_scanRoutes = __esm({
2189
2180
  "src/router/scanRoutes.ts"() {
2190
2181
  "use strict";
@@ -2192,6 +2183,7 @@ var init_scanRoutes = __esm({
2192
2183
  init_parseRouteFile();
2193
2184
  init_loadMiddlewares();
2194
2185
  init_importWithCacheBust();
2186
+ APP_DIR3 = "src";
2195
2187
  }
2196
2188
  });
2197
2189
 
@@ -2221,8 +2213,8 @@ var init_sortRoutes = __esm({
2221
2213
  // src/config/loadConfig.ts
2222
2214
  import path9 from "path";
2223
2215
  import fs8 from "fs";
2224
- async function loadConfig(rootDir, outDir) {
2225
- const configProductPath = path9.resolve(rootDir, outDir, CONFIG_PRODUCT_FILE);
2216
+ async function loadConfig(rootDir, dist) {
2217
+ const configProductPath = path9.resolve(rootDir, dist, CONFIG_PRODUCT_FILE);
2226
2218
  if (fs8.existsSync(configProductPath)) {
2227
2219
  const module = await importWithCacheBust(configProductPath);
2228
2220
  return module.default ?? {};
@@ -2230,7 +2222,7 @@ async function loadConfig(rootDir, outDir) {
2230
2222
  const hasSourceConfig = fs8.existsSync(path9.join(rootDir, "faapi.config.ts")) || fs8.existsSync(path9.join(rootDir, "faapi.config.js"));
2231
2223
  if (hasSourceConfig) {
2232
2224
  throw new Error(
2233
- `[faapi] ${outDir}/${CONFIG_PRODUCT_FILE} \u4E0D\u5B58\u5728\uFF0C\u8BF7\u5148\u6267\u884C \`faapi build\`\uFF08\u6216 \`faapi dev\`\uFF09\u751F\u6210\u4EA7\u7269\u3002`
2225
+ `[faapi] ${dist}/${CONFIG_PRODUCT_FILE} \u4E0D\u5B58\u5728\uFF0C\u8BF7\u5148\u6267\u884C \`faapi build\`\uFF08\u6216 \`faapi dev\`\uFF09\u751F\u6210\u4EA7\u7269\u3002`
2234
2226
  );
2235
2227
  }
2236
2228
  return null;
@@ -3956,7 +3948,7 @@ var init_esm2 = __esm({
3956
3948
  // src/cli/watcher.ts
3957
3949
  import path10 from "path";
3958
3950
  function startWatcher(options) {
3959
- const { rootDir, appDir, app } = options;
3951
+ const { rootDir, app, devDist } = options;
3960
3952
  let rebuildTimer = null;
3961
3953
  let pendingFiles = /* @__PURE__ */ new Set();
3962
3954
  async function rebuildRoutes() {
@@ -3966,12 +3958,11 @@ function startWatcher(options) {
3966
3958
  if (filesToCompile.length > 0) {
3967
3959
  await compileDevRoutes({
3968
3960
  rootDir,
3969
- appDir,
3970
- outDir: DEV_OUT_DIR,
3961
+ dist: devDist,
3971
3962
  files: filesToCompile
3972
3963
  });
3973
3964
  }
3974
- await compileConfig({ rootDir, outDir: DEV_OUT_DIR });
3965
+ await compileConfig({ rootDir, dist: devDist });
3975
3966
  await app.reloadRoutes();
3976
3967
  const recompiledCount = filesToCompile.length;
3977
3968
  console.log(
@@ -3994,12 +3985,12 @@ function startWatcher(options) {
3994
3985
  "faapi.config.production.ts",
3995
3986
  "faapi.config.production.js"
3996
3987
  ];
3997
- const watchPaths = [appDir, ...CONFIG_FILES];
3988
+ const watchPaths = ["src", ...CONFIG_FILES];
3998
3989
  const watcher = esm_default.watch(watchPaths, {
3999
3990
  cwd: rootDir,
4000
3991
  ignoreInitial: true,
4001
3992
  ignored: (filePath, stats) => {
4002
- if (filePath.includes("node_modules") || filePath.includes(".faapi") || filePath.includes("dist") || filePath.includes(".git")) {
3993
+ if (filePath.includes("node_modules") || filePath.includes(".faapi") || filePath.includes(devDist) || filePath.includes(".git")) {
4003
3994
  return true;
4004
3995
  }
4005
3996
  if (!stats) return false;
@@ -4029,14 +4020,12 @@ function startWatcher(options) {
4029
4020
  });
4030
4021
  console.log("- Watch mode enabled");
4031
4022
  }
4032
- var DEV_OUT_DIR;
4033
4023
  var init_watcher = __esm({
4034
4024
  "src/cli/watcher.ts"() {
4035
4025
  "use strict";
4036
4026
  init_esm2();
4037
4027
  init_compileDevRoutes();
4038
4028
  init_compileConfig();
4039
- DEV_OUT_DIR = ".faapi/dev";
4040
4029
  }
4041
4030
  });
4042
4031
 
@@ -5508,8 +5497,7 @@ function createServer(options) {
5508
5497
  const {
5509
5498
  routes,
5510
5499
  rootDir,
5511
- appDir,
5512
- outDir,
5500
+ dist,
5513
5501
  cors: corsOption,
5514
5502
  onError,
5515
5503
  config,
@@ -5547,8 +5535,7 @@ function createServer(options) {
5547
5535
  handleRequest(
5548
5536
  currentRoutes,
5549
5537
  rootDir,
5550
- appDir,
5551
- outDir,
5538
+ dist,
5552
5539
  req,
5553
5540
  res,
5554
5541
  configMiddlewares,
@@ -5567,7 +5554,7 @@ function createServer(options) {
5567
5554
  }
5568
5555
  return { server, routesRef };
5569
5556
  }
5570
- async function handleRequest(routes, rootDir, appDir, outDir, req, res, configMiddlewares, onError, config, globalMiddlewares, globalInjectors, bodyLimit) {
5557
+ async function handleRequest(routes, rootDir, dist, req, res, configMiddlewares, onError, config, globalMiddlewares, globalInjectors, bodyLimit) {
5571
5558
  const request = toWebRequest(req, bodyLimit);
5572
5559
  const method = request.method.toUpperCase();
5573
5560
  const urlPath = new URL(request.url).pathname;
@@ -5588,7 +5575,7 @@ async function handleRequest(routes, rootDir, appDir, outDir, req, res, configMi
5588
5575
  const routeModule = await loadRouteModule(absoluteFilePath, route.method);
5589
5576
  const input = await resolveInput(route.method, request);
5590
5577
  const inputType = getInputTypeForMethod(route.method);
5591
- const schemaPath = getRuntimeSchemaPath(route.filePath, appDir, outDir, rootDir);
5578
+ const schemaPath = getRuntimeSchemaPath(route.filePath, dist, rootDir);
5592
5579
  const result = await validateInput(schemaPath, route.method, inputType, input);
5593
5580
  if (!result.valid) {
5594
5581
  throw new ValidationError("\u53C2\u6570\u6821\u9A8C\u5931\u8D25", result.issues);
@@ -5758,16 +5745,14 @@ function isFaapiConfigKey(key) {
5758
5745
  }
5759
5746
  async function createAppBase(options) {
5760
5747
  const rootDir = options?.rootDir ?? process.cwd();
5761
- const outDir = options?.outDir ?? process.env.FAAPI_OUT_DIR ?? DEFAULT_OUT_DIR;
5762
- const routesPath = path13.resolve(rootDir, outDir, ROUTES_FILE);
5748
+ const dist = options?.dist ?? process.env.FAAPI_DIST ?? DEFAULT_DIST;
5749
+ const routesPath = path13.resolve(rootDir, dist, ROUTES_FILE);
5763
5750
  if (!fs9.existsSync(routesPath)) {
5764
5751
  throw new Error(
5765
- `[faapi] ${outDir}/${ROUTES_FILE} \u4E0D\u5B58\u5728\uFF0C\u8BF7\u5148\u6267\u884C \`faapi build\`\uFF08\u6216 \`faapi dev\`\uFF09\u751F\u6210\u4EA7\u7269\u3002`
5752
+ `[faapi] ${dist}/${ROUTES_FILE} \u4E0D\u5B58\u5728\uFF0C\u8BF7\u5148\u6267\u884C \`faapi build\`\uFF08\u6216 \`faapi dev\`\uFF09\u751F\u6210\u4EA7\u7269\u3002`
5766
5753
  );
5767
5754
  }
5768
- const config = await loadConfig(rootDir, outDir);
5769
- const appDir = options?.appDir ?? process.env.FAAPI_APP_DIR ?? DEFAULT_APP_DIR;
5770
- const patterns = appDir === "." ? ["api/**/*.ts"] : [`${appDir}/api/**/*.ts`];
5755
+ const config = await loadConfig(rootDir, dist);
5771
5756
  const serialized = await importWithCacheBust(routesPath);
5772
5757
  const hydrated = await hydrateRoutes(serialized);
5773
5758
  let sorted = sortRoutes(hydrated.routes);
@@ -5785,8 +5770,7 @@ async function createAppBase(options) {
5785
5770
  const { server, routesRef } = createServer({
5786
5771
  routes: sorted,
5787
5772
  rootDir,
5788
- appDir,
5789
- outDir,
5773
+ dist,
5790
5774
  cors: config?.cors ?? true,
5791
5775
  onError: config?.lifecycle?.onError,
5792
5776
  config: config ?? void 0,
@@ -5947,9 +5931,8 @@ async function createAppBase(options) {
5947
5931
  };
5948
5932
  const ctx = {
5949
5933
  rootDir,
5950
- appDir,
5951
- outDir,
5952
- patterns,
5934
+ dist,
5935
+ patterns: PATTERNS,
5953
5936
  server,
5954
5937
  routesRef,
5955
5938
  config,
@@ -5964,7 +5947,7 @@ async function createAppBase(options) {
5964
5947
  };
5965
5948
  return { app, ctx };
5966
5949
  }
5967
- var DEFAULT_OUT_DIR, DEFAULT_APP_DIR, DEFAULT_PORT, ROUTES_FILE, FAAPI_CONFIG_KEYS;
5950
+ var DEFAULT_DIST, DEFAULT_PORT, ROUTES_FILE, PATTERNS, FAAPI_CONFIG_KEYS;
5968
5951
  var init_createAppCore = __esm({
5969
5952
  "src/cli/createAppCore.ts"() {
5970
5953
  "use strict";
@@ -5976,10 +5959,10 @@ var init_createAppCore = __esm({
5976
5959
  init_generateRoutes();
5977
5960
  init_loadPlugins();
5978
5961
  init_importWithCacheBust();
5979
- DEFAULT_OUT_DIR = "dist";
5980
- DEFAULT_APP_DIR = "src";
5962
+ DEFAULT_DIST = "dist";
5981
5963
  DEFAULT_PORT = 3e3;
5982
5964
  ROUTES_FILE = "faapi-routes.js";
5965
+ PATTERNS = ["src/api/**/*.ts"];
5983
5966
  FAAPI_CONFIG_KEYS = /* @__PURE__ */ new Set([
5984
5967
  "cors",
5985
5968
  "lifecycle",
@@ -6004,9 +5987,9 @@ async function createDevApp(options) {
6004
5987
  invalidateMiddlewareCache();
6005
5988
  invalidateProgramCache();
6006
5989
  invalidateSchemaCache();
6007
- const reScanned = await scanRoutes(ctx.rootDir, ctx.patterns, ctx.appDir, ctx.outDir);
5990
+ const reScanned = await scanRoutes(ctx.rootDir, ctx.patterns, ctx.dist);
6008
5991
  const sorted = sortRoutes(reScanned.routes);
6009
- await generateSchemaFiles(sorted, ctx.rootDir, ctx.appDir, ctx.outDir);
5992
+ await generateSchemaFiles(sorted, ctx.rootDir, ctx.dist);
6010
5993
  ctx.updateRoutes(sorted, reScanned.wsRoutes);
6011
5994
  };
6012
5995
  return devApp;
@@ -6034,32 +6017,31 @@ __export(devCommand_exports, {
6034
6017
  import path14 from "path";
6035
6018
  async function devCommand(options) {
6036
6019
  const rootDir = process.cwd();
6037
- process.env.FAAPI_OUT_DIR = DEV_OUT_DIR2;
6020
+ const devDist = DEV_DIST;
6021
+ process.env.FAAPI_DIST = devDist;
6038
6022
  if (!process.env.NODE_ENV) process.env.NODE_ENV = "development";
6039
6023
  console.log("- Development mode");
6040
6024
  console.log("- Compiling config...");
6041
- await compileConfig({ rootDir, outDir: DEV_OUT_DIR2 });
6042
- const _config = await loadConfig(rootDir, DEV_OUT_DIR2);
6043
- const appDir = options?.appDir ?? process.env.FAAPI_APP_DIR ?? "src";
6044
- const patterns = appDir === "." ? ["api/**/*.ts"] : [`${appDir}/api/**/*.ts`];
6025
+ await compileConfig({ rootDir, dist: devDist });
6026
+ const _config = await loadConfig(rootDir, devDist);
6045
6027
  console.log("- Compiling TypeScript...");
6046
- await compileDevRoutes({ rootDir, appDir, outDir: DEV_OUT_DIR2 });
6028
+ await compileDevRoutes({ rootDir, dist: devDist });
6047
6029
  console.log("- Generating route manifest and schema...");
6048
- await generateRouteArtifacts(rootDir, appDir, patterns);
6030
+ await generateRouteArtifacts(rootDir, PATTERNS2, devDist);
6049
6031
  console.log("- Starting dev app...");
6050
6032
  const app = await createDevApp({ rootDir, port: options?.port });
6051
6033
  await app.listen();
6052
- startWatcher({ rootDir, appDir, app });
6034
+ startWatcher({ rootDir, app, devDist });
6053
6035
  }
6054
- async function generateRouteArtifacts(rootDir, appDir, patterns) {
6055
- const { routes, wsRoutes } = await scanRoutes(rootDir, patterns, appDir, DEV_OUT_DIR2);
6036
+ async function generateRouteArtifacts(rootDir, patterns, dist) {
6037
+ const { routes, wsRoutes } = await scanRoutes(rootDir, patterns, dist);
6056
6038
  const sorted = sortRoutes(routes);
6057
- const routesPath = path14.resolve(rootDir, DEV_OUT_DIR2, ROUTES_FILE2);
6058
- const serialized = serializeRoutes(sorted, wsRoutes, rootDir, appDir, DEV_OUT_DIR2);
6039
+ const routesPath = path14.resolve(rootDir, dist, ROUTES_FILE2);
6040
+ const serialized = serializeRoutes(sorted, wsRoutes, rootDir, dist);
6059
6041
  await writeRoutesModule(serialized, routesPath);
6060
- await generateSchemaFiles(sorted, rootDir, appDir, DEV_OUT_DIR2);
6042
+ await generateSchemaFiles(sorted, rootDir, dist);
6061
6043
  }
6062
- var DEV_OUT_DIR2, ROUTES_FILE2;
6044
+ var DEV_DIST, ROUTES_FILE2, PATTERNS2;
6063
6045
  var init_devCommand = __esm({
6064
6046
  "src/cli/devCommand.ts"() {
6065
6047
  "use strict";
@@ -6072,8 +6054,9 @@ var init_devCommand = __esm({
6072
6054
  init_loadConfig();
6073
6055
  init_watcher();
6074
6056
  init_createDevApp();
6075
- DEV_OUT_DIR2 = ".faapi/dev";
6057
+ DEV_DIST = ".faapi";
6076
6058
  ROUTES_FILE2 = "faapi-routes.js";
6059
+ PATTERNS2 = ["src/api/**/*.ts"];
6077
6060
  }
6078
6061
  });
6079
6062
 
@@ -6082,8 +6065,8 @@ import path15 from "path";
6082
6065
  import fs10 from "fs";
6083
6066
  import fg3 from "fast-glob";
6084
6067
  async function compileBuildRoutes(options) {
6085
- const { rootDir, appDir, outDir, files, logLevel = "silent" } = options;
6086
- const entryPoints = files ?? await fg3([`${appDir}/**/*.ts`], {
6068
+ const { rootDir, dist, files, logLevel = "silent" } = options;
6069
+ const entryPoints = files ?? await fg3([`${APP_DIR4}/**/*.ts`], {
6087
6070
  cwd: rootDir,
6088
6071
  onlyFiles: true,
6089
6072
  absolute: true,
@@ -6092,14 +6075,14 @@ async function compileBuildRoutes(options) {
6092
6075
  if (entryPoints.length === 0) {
6093
6076
  return { compiledFiles: [] };
6094
6077
  }
6095
- const absOutDir = path15.resolve(rootDir, outDir);
6096
- await fs10.promises.mkdir(absOutDir, { recursive: true });
6078
+ const absDist = path15.resolve(rootDir, dist);
6079
+ await fs10.promises.mkdir(absDist, { recursive: true });
6097
6080
  const plugins = buildAliasPlugins(rootDir);
6098
6081
  const esbuild = await import("esbuild");
6099
- const outbase = appDir === "." ? rootDir : path15.resolve(rootDir, appDir);
6082
+ const outbase = path15.resolve(rootDir, APP_DIR4);
6100
6083
  await esbuild.build({
6101
6084
  entryPoints,
6102
- outdir: absOutDir,
6085
+ outdir: absDist,
6103
6086
  outbase,
6104
6087
  bundle: false,
6105
6088
  platform: "node",
@@ -6113,10 +6096,12 @@ async function compileBuildRoutes(options) {
6113
6096
  });
6114
6097
  return { compiledFiles: entryPoints };
6115
6098
  }
6099
+ var APP_DIR4;
6116
6100
  var init_compileBuildRoutes = __esm({
6117
6101
  "src/cli/compileBuildRoutes.ts"() {
6118
6102
  "use strict";
6119
6103
  init_aliasPlugin();
6104
+ APP_DIR4 = "src";
6120
6105
  }
6121
6106
  });
6122
6107
 
@@ -6129,20 +6114,17 @@ import path16 from "path";
6129
6114
  import fs11 from "fs";
6130
6115
  async function buildCommand(options) {
6131
6116
  const rootDir = options?.rootDir ?? process.cwd();
6132
- const outdir = options?.outDir ?? DEFAULT_PROD_OUT_DIR;
6133
- await compileConfig({ rootDir, outDir: outdir });
6117
+ const outdir = options?.dist ?? DEFAULT_DIST2;
6118
+ await compileConfig({ rootDir, dist: outdir });
6134
6119
  const _config = await loadConfig(rootDir, outdir);
6135
- const appDir = options?.appDir ?? process.env.FAAPI_APP_DIR ?? "src";
6136
- const patterns = appDir === "." ? ["api/**/*.ts"] : [`${appDir}/api/**/*.ts`];
6137
6120
  console.log("faapi build started");
6138
6121
  console.log(`- Root: ${rootDir}`);
6139
- console.log(`- AppDir: ${appDir}`);
6122
+ console.log(`- Source: src/`);
6140
6123
  console.log(`- Output: ${outdir}`);
6141
6124
  console.log("\n[1/6] Compiling TypeScript (bundle: false)...");
6142
6125
  const result = await compileBuildRoutes({
6143
6126
  rootDir,
6144
- appDir,
6145
- outDir: outdir,
6127
+ dist: outdir,
6146
6128
  logLevel: "silent"
6147
6129
  });
6148
6130
  console.log(` Compiled ${result.compiledFiles.length} file(s)`);
@@ -6151,14 +6133,14 @@ async function buildCommand(options) {
6151
6133
  return;
6152
6134
  }
6153
6135
  console.log("\n[2/6] Compiling config...");
6154
- const configResult = await compileConfig({ rootDir, outDir: outdir });
6136
+ const configResult = await compileConfig({ rootDir, dist: outdir });
6155
6137
  if (configResult.generated) {
6156
6138
  console.log(` Written to ${configResult.outputFile}`);
6157
6139
  } else {
6158
6140
  console.log(" No config file found, skipped");
6159
6141
  }
6160
6142
  console.log("\n[3/6] Scanning routes...");
6161
- const { routes, wsRoutes } = await scanRoutes(rootDir, patterns, appDir, outdir);
6143
+ const { routes, wsRoutes } = await scanRoutes(rootDir, PATTERNS3, outdir);
6162
6144
  const sorted = sortRoutes(routes);
6163
6145
  console.log(` Found ${sorted.length} routes, ${wsRoutes.length} WS routes`);
6164
6146
  const conflicts = detectRouteConflicts(sorted);
@@ -6172,28 +6154,27 @@ async function buildCommand(options) {
6172
6154
  }
6173
6155
  }
6174
6156
  console.log("\n[4/6] Generating schema...");
6175
- await generateSchemaFiles(sorted, rootDir, appDir, outdir);
6157
+ await generateSchemaFiles(sorted, rootDir, outdir);
6176
6158
  console.log(` Schema: zod.js files under ${path16.resolve(rootDir, outdir)}`);
6177
6159
  console.log("\n[5/6] Generating routes manifest...");
6178
6160
  const routesPath = path16.resolve(rootDir, outdir, "faapi-routes.js");
6179
- const serialized = serializeRoutes(sorted, wsRoutes, rootDir, appDir, outdir);
6161
+ const serialized = serializeRoutes(sorted, wsRoutes, rootDir, outdir);
6180
6162
  await writeRoutesModule(serialized, routesPath);
6181
6163
  console.log(` Written to ${routesPath}`);
6182
6164
  console.log("\n[6/6] Generating entry file...");
6183
6165
  const mainPath = path16.resolve(rootDir, outdir, "main.js");
6184
- const createProdAppArgs = options?.outDir && options.outDir !== DEFAULT_PROD_OUT_DIR ? `{ outDir: '${options.outDir}' }` : "";
6185
- const listenArgs = options?.port ? String(options.port) : "";
6166
+ const createProdAppArgs = options?.dist && options.dist !== DEFAULT_DIST2 ? `{ dist: '${outdir}' }` : "";
6186
6167
  const mainContent = `// \u7531 faapi build \u81EA\u52A8\u751F\u6210\uFF0C\u8BF7\u52FF\u624B\u52A8\u7F16\u8F91
6187
6168
  import { createProdApp } from '@faapi/faapi';
6188
6169
 
6189
6170
  const app = await createProdApp(${createProdAppArgs});
6190
- await app.listen(${listenArgs});
6171
+ await app.listen();
6191
6172
  `;
6192
6173
  await fs11.promises.writeFile(mainPath, mainContent, "utf-8");
6193
6174
  console.log(` Written to ${mainPath}`);
6194
6175
  console.log("\nfaapi build completed");
6195
6176
  }
6196
- var DEFAULT_PROD_OUT_DIR;
6177
+ var DEFAULT_DIST2, PATTERNS3;
6197
6178
  var init_buildCommand = __esm({
6198
6179
  "src/cli/buildCommand.ts"() {
6199
6180
  "use strict";
@@ -6205,7 +6186,8 @@ var init_buildCommand = __esm({
6205
6186
  init_compileBuildRoutes();
6206
6187
  init_compileConfig();
6207
6188
  init_loadConfig();
6208
- DEFAULT_PROD_OUT_DIR = "dist";
6189
+ DEFAULT_DIST2 = "dist";
6190
+ PATTERNS3 = ["src/api/**/*.ts"];
6209
6191
  }
6210
6192
  });
6211
6193
 
@@ -6796,11 +6778,11 @@ var cac = (name = "") => new CAC(name);
6796
6778
 
6797
6779
  // src/cli/index.ts
6798
6780
  var cli = cac("faapi");
6799
- cli.command("").alias("dev").option("--port <number>", "\u670D\u52A1\u7AEF\u53E3\uFF08\u9ED8\u8BA4 3000\uFF09").option("--appDir <dir>", "\u6E90\u7801\u76EE\u5F55\u524D\u7F00\uFF08\u9ED8\u8BA4 src\uFF09").action(async (options) => {
6781
+ cli.command("").alias("dev").option("--port <number>", "\u670D\u52A1\u7AEF\u53E3\uFF08\u9ED8\u8BA4 3000\uFF09").action(async (options) => {
6800
6782
  const { devCommand: devCommand2 } = await Promise.resolve().then(() => (init_devCommand(), devCommand_exports));
6801
6783
  await devCommand2(options);
6802
6784
  });
6803
- cli.command("build", "Build for production").option("--port <number>", "prod \u670D\u52A1\u7AEF\u53E3\uFF0C\u5199\u5165 dist/main.js").option("--appDir <dir>", "\u6E90\u7801\u76EE\u5F55\u524D\u7F00\uFF08\u9ED8\u8BA4 src\uFF09").option("--outDir <dir>", "\u4EA7\u7269\u8F93\u51FA\u76EE\u5F55\uFF08\u9ED8\u8BA4 dist\uFF09").action(async (options) => {
6785
+ cli.command("build", "Build for production").option("--dist <dir>", "\u4EA7\u7269\u8F93\u51FA\u76EE\u5F55\uFF0C\u9ED8\u8BA4 dist").action(async (options) => {
6804
6786
  const { buildCommand: buildCommand2 } = await Promise.resolve().then(() => (init_buildCommand(), buildCommand_exports));
6805
6787
  await buildCommand2(options);
6806
6788
  });