@pracht/cli 1.2.1 → 1.3.0

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 CHANGED
@@ -1,5 +1,90 @@
1
1
  # @pracht/cli
2
2
 
3
+ ## 1.3.0
4
+
5
+ ### Minor Changes
6
+
7
+ - [#133](https://github.com/JoviDeCroock/pracht/pull/133) [`f8c5c1f`](https://github.com/JoviDeCroock/pracht/commit/f8c5c1fe1a7c7b5d7accd8028e8c12929a218081) Thanks [@JoviDeCroock](https://github.com/JoviDeCroock)! - API routes now support catch-all segments (e.g. `src/api/files/[...path].ts` → `/api/files/*`), matching the existing page-routing convention. The matched rest-path is exposed on the route params as `"*"`. Previously `[...param]` was silently turned into a `:...param` dynamic segment with a broken name.
8
+
9
+ ### Patch Changes
10
+
11
+ - Updated dependencies [[`f8c5c1f`](https://github.com/JoviDeCroock/pracht/commit/f8c5c1fe1a7c7b5d7accd8028e8c12929a218081)]:
12
+ - @pracht/core@0.4.0
13
+
14
+ ## 1.2.2
15
+
16
+ ### Patch Changes
17
+
18
+ - [#124](https://github.com/JoviDeCroock/pracht/pull/124) [`8f662c0`](https://github.com/JoviDeCroock/pracht/commit/8f662c0b78b1911a7534ffd7aa4e919cf22a3a42) Thanks [@JoviDeCroock](https://github.com/JoviDeCroock)! - Internal refactor: split several large modules into smaller, focused files to improve maintainability. Public APIs are unchanged.
19
+
20
+ - [#132](https://github.com/JoviDeCroock/pracht/pull/132) [`30d867f`](https://github.com/JoviDeCroock/pracht/commit/30d867f4a4cd41107a1ed60c607afe0d51848c3b) Thanks [@JoviDeCroock](https://github.com/JoviDeCroock)! - Follow-up security hardening after the main audit fixes.
21
+
22
+ - `@pracht/adapter-node` now supports `canonicalOrigin` so apps can pin
23
+ `request.url` to a known public origin instead of depending on untrusted
24
+ `Host` values. The adapter also treats both `x-pracht-route-state-request`
25
+ and `?_data=1` as route-state transports before any static/ISG HTML serving,
26
+ and ISG regeneration now uses a clean HTML request instead of replaying the
27
+ triggering user's cookies or authorization headers.
28
+ - `@pracht/adapter-cloudflare` now bypasses static asset serving for both
29
+ route-state transports (`x-pracht-route-state-request` and `?_data=1`).
30
+ - `@pracht/cli` now emits a Vercel Build Output rule that sends `?_data=1`
31
+ requests to the render function before static rewrites can serve prerendered
32
+ HTML.
33
+
34
+ - [#131](https://github.com/JoviDeCroock/pracht/pull/131) [`015e987`](https://github.com/JoviDeCroock/pracht/commit/015e987a2de471980fab557e3dbf3d52937ad0ac) Thanks [@JoviDeCroock](https://github.com/JoviDeCroock)! - Security hardening across request handling, redirects, and build output.
35
+
36
+ **Framework (`@pracht/core`)**
37
+
38
+ - **Middleware/loader redirects are now validated.** `javascript:`, `data:`,
39
+ `vbscript:`, `blob:`, and `file:` targets are refused server-side (they
40
+ were already refused on the client) and CR/LF in the `Location` value
41
+ throws instead of producing a split response. Non-safe-method redirects
42
+ now default to **303 See Other** rather than 302 so browsers don't
43
+ resend the POST body to the redirect target. `MiddlewareResult`'s
44
+ `redirect` form now accepts an optional `status` override.
45
+ - **CSRF protection for mutating API routes.** Non-GET API requests are
46
+ rejected with 403 unless the browser signals a same-origin/same-site
47
+ fetch (`Sec-Fetch-Site`) or the `Origin` header matches the request
48
+ URL's origin. Opt out per-app via `defineApp({ api: { requireSameOrigin: false } })`.
49
+ - **`_data=1` route-state bypass is now gated.** The query-param form of
50
+ the route-state endpoint now requires `Sec-Fetch-Site: same-origin`/
51
+ `same-site` (or a matching `Origin`). The explicit
52
+ `x-pracht-route-state-request` header is still accepted unconditionally
53
+ (CORS-protected).
54
+ - **Catch-all path traversal at build time is closed.**
55
+ `buildPathFromSegments` now percent-encodes catch-all components
56
+ individually and explicitly neutralises `.` / `..` segments, so a
57
+ `getStaticPaths` returning `{ "*": "../../etc/passwd" }` can no longer
58
+ escape `dist/client/` at SSG/ISG write time.
59
+ - **`headers()` values are validated for CR/LF.** `applyHeaders` now
60
+ throws a consistent framework error on response-splitting attempts,
61
+ regardless of adapter-specific Headers implementation behaviour.
62
+ - **`debugErrors` is ignored in production.** When `NODE_ENV=production`,
63
+ `debugErrors: true` is refused (with a one-shot console warning) so a
64
+ misconfigured deploy cannot leak stack traces and module paths.
65
+
66
+ **Adapter (`@pracht/adapter-node`)**
67
+
68
+ - **Symlinks are no longer followed by the static server.** `resolveStaticFile`
69
+ now uses `lstat` and rejects files whose inode is a symlink, preventing
70
+ a malicious build artifact from exposing files outside `dist/client/`.
71
+ - **ISG cache is path-contained.** The on-disk write path is now
72
+ `resolve()`-checked against the static root, rejecting any URL path
73
+ that would escape via `..`, encoded separators, or NUL bytes.
74
+ - **ISG skips the on-disk cache when the response is user-specific.**
75
+ Responses that set `Cache-Control: no-store`/`private`, `Set-Cookie`,
76
+ or a `Vary` covering `cookie`/`authorization`/`*` are served through
77
+ but not written to disk, closing a per-user cache-poisoning window.
78
+
79
+ **Packaging**
80
+
81
+ - `@pracht/cli` now has an explicit `files` allowlist so future
82
+ workdir additions can't accidentally ship in the npm tarball.
83
+ - `create-pracht`'s bin entry is now executable in the repository.
84
+
85
+ - Updated dependencies [[`caae3cb`](https://github.com/JoviDeCroock/pracht/commit/caae3cb53e0b6136ef78c3ac189a0d0ab82e4df7), [`8f662c0`](https://github.com/JoviDeCroock/pracht/commit/8f662c0b78b1911a7534ffd7aa4e919cf22a3a42), [`901ef5b`](https://github.com/JoviDeCroock/pracht/commit/901ef5b7958e4066d5382f836d098bded8bfe320), [`015e987`](https://github.com/JoviDeCroock/pracht/commit/015e987a2de471980fab557e3dbf3d52937ad0ac)]:
86
+ - @pracht/core@0.3.0
87
+
3
88
  ## 1.2.1
4
89
 
5
90
  ### Patch Changes
@@ -36,6 +36,14 @@ function createVercelOutputConfig({ functionName, headersManifest, staticRoutes,
36
36
  value: "1"
37
37
  }],
38
38
  src: "/(.*)"
39
+ }, {
40
+ dest: target,
41
+ has: [{
42
+ type: "query",
43
+ key: "_data",
44
+ value: "1"
45
+ }],
46
+ src: "/(.*)"
39
47
  }];
40
48
  for (const route of sortStaticRoutes(staticRoutes)) routes.push({
41
49
  dest: routeToStaticHtmlPath(route),
@@ -1,4 +1,4 @@
1
- import { t as runDoctor } from "./verification-CId4crSF.mjs";
1
+ import { t as runDoctor } from "./verification-WP-KTb41.mjs";
2
2
  import { defineCommand } from "citty";
3
3
  //#region src/commands/doctor.ts
4
4
  var doctor_default = defineCommand({
@@ -1,7 +1,146 @@
1
- import { a as toManifestModulePath, i as insertArrayItem, n as extractRegistryEntries, o as upsertObjectEntry, t as ensureCoreNamedImport } from "./manifest-DGq1n5LT.mjs";
2
- import { _ as requireEnum, a as readProjectConfig, c as resolveProjectPath, d as writeGeneratedFile, f as ensureTrailingNewline, g as quote, h as parseCommaList, l as resolveRouteModulePath, m as parseApiMethods, n as displayPath, o as resolveApiModulePath, s as resolvePagesRouteModulePath, t as assertFileExists, u as resolveScopedFile, v as requirePositiveInteger } from "./project-DUyH_7eJ.mjs";
1
+ import { _ as requireEnum, a as readProjectConfig, c as resolveProjectPath, d as writeGeneratedFile, f as ensureTrailingNewline, g as quote, h as parseCommaList, l as resolveRouteModulePath, m as parseApiMethods, n as displayPath, o as resolveApiModulePath, s as resolvePagesRouteModulePath, t as assertFileExists, u as resolveScopedFile, v as requirePositiveInteger } from "./project-BdMiN3s7.mjs";
2
+ import { a as toManifestModulePath, i as insertArrayItem, n as extractRegistryEntries, o as upsertObjectEntry, t as ensureCoreNamedImport } from "./manifest-Bs5hp3gA.mjs";
3
3
  import { defineCommand } from "citty";
4
4
  import { readFileSync, writeFileSync } from "node:fs";
5
+ //#region src/commands/generate-paths.ts
6
+ function normalizeRoutePathString(value) {
7
+ if (!value || value === "/") return "/";
8
+ const normalized = `/${value}`.replace(/\/+/g, "/");
9
+ return normalized !== "/" && normalized.endsWith("/") ? normalized.slice(0, -1) : normalized;
10
+ }
11
+ function normalizeApiPath(value) {
12
+ return normalizeRoutePathString(value).replace(/^\/api(?=\/|$)/, "") || "/";
13
+ }
14
+ function hasDynamicSegments(routePath) {
15
+ return routePath.split("/").some((segment) => segment.startsWith(":") || segment === "*");
16
+ }
17
+ function dynamicParamNames(routePath) {
18
+ return routePath.split("/").filter(Boolean).map((segment) => {
19
+ if (segment.startsWith(":")) return segment.slice(1);
20
+ if (segment === "*") return "slug";
21
+ return null;
22
+ }).filter((s) => s !== null);
23
+ }
24
+ function routeIdFromPath(routePath) {
25
+ if (routePath === "/") return "index";
26
+ return routePath.split("/").filter(Boolean).map((segment) => segment.replace(/^:/, "").replace(/\*/g, "splat")).join("-");
27
+ }
28
+ function titleFromPath(routePath) {
29
+ if (routePath === "/") return "Home";
30
+ return titleCase((routePath.split("/").filter(Boolean).at(-1) ?? "Page").replace(/^:/, "").replace(/\*/g, "slug"));
31
+ }
32
+ function titleCase(value) {
33
+ return value.split(/[-_/]/).filter(Boolean).map((segment) => segment.charAt(0).toUpperCase() + segment.slice(1)).join(" ");
34
+ }
35
+ //#endregion
36
+ //#region src/commands/generate-source.ts
37
+ function buildManifestRouteModuleSource(opts) {
38
+ const sections = buildRouteModuleSections(opts);
39
+ const componentIdx = sections.findIndex((s) => s.startsWith("export function Component"));
40
+ const insertAt = componentIdx === -1 ? sections.length : componentIdx;
41
+ sections.splice(insertAt, 0, "export function head() {", ` return { title: ${quote(opts.title)} };`, "}", "");
42
+ return `${sections.join("\n")}\n`;
43
+ }
44
+ function buildPagesRouteModuleSource(opts) {
45
+ const sections = buildRouteModuleSections(opts);
46
+ const firstExportIdx = sections.findIndex((s) => s.startsWith("export"));
47
+ const insertAt = firstExportIdx === -1 ? sections.length : firstExportIdx;
48
+ sections.splice(insertAt, 0, `export const RENDER_MODE = ${quote(opts.render)};`, "");
49
+ return `${sections.join("\n")}\n`;
50
+ }
51
+ function buildShellModuleSource(name) {
52
+ const title = titleCase(name);
53
+ return [
54
+ "import type { ShellProps } from \"@pracht/core\";",
55
+ "",
56
+ "export function Shell({ children }: ShellProps) {",
57
+ " return (",
58
+ ` <div class=${quote(`${name}-shell`)}>`,
59
+ " <main>{children}</main>",
60
+ " </div>",
61
+ " );",
62
+ "}",
63
+ "",
64
+ "export function head() {",
65
+ ` return { title: ${quote(title)} };`,
66
+ "}",
67
+ ""
68
+ ].join("\n");
69
+ }
70
+ function buildMiddlewareModuleSource() {
71
+ return [
72
+ "import type { MiddlewareFn } from \"@pracht/core\";",
73
+ "",
74
+ "export const middleware: MiddlewareFn = async (_args) => {",
75
+ " return;",
76
+ "};",
77
+ ""
78
+ ].join("\n");
79
+ }
80
+ function buildApiRouteSource({ endpointPath, methods }) {
81
+ return [
82
+ "import type { BaseRouteArgs } from \"@pracht/core\";",
83
+ "",
84
+ ...methods.flatMap((method, index) => {
85
+ const lines = buildApiMethodSource(method, methods, endpointPath);
86
+ if (index === methods.length - 1) return lines;
87
+ return [...lines, ""];
88
+ }),
89
+ ""
90
+ ].join("\n");
91
+ }
92
+ function buildRouteModuleSections(opts) {
93
+ const { includeErrorBoundary, includeLoader, includeStaticPaths, routePath, title } = opts;
94
+ const params = dynamicParamNames(routePath);
95
+ const imports = [];
96
+ const sections = [];
97
+ if (includeLoader) imports.push("LoaderArgs", "RouteComponentProps");
98
+ if (includeErrorBoundary) imports.push("ErrorBoundaryProps");
99
+ if (imports.length > 0) {
100
+ sections.push(`import type { ${imports.join(", ")} } from "@pracht/core";`);
101
+ sections.push("");
102
+ }
103
+ if (includeLoader) sections.push("export async function loader(_args: LoaderArgs) {", ` return { message: ${quote(`Welcome to ${title}.`)} };`, "}", "");
104
+ if (includeStaticPaths) sections.push("export function getStaticPaths() {", ` return [${buildStaticPathsStub(params)}];`, "}", "");
105
+ if (includeLoader) sections.push("export function Component({ data }: RouteComponentProps<typeof loader>) {", " return (", " <section>", ` <h1>${escapeJsxText(title)}</h1>`, " <p>{data.message}</p>", " </section>", " );", "}");
106
+ else sections.push("export function Component() {", " return (", " <section>", ` <h1>${escapeJsxText(title)}</h1>`, " </section>", " );", "}");
107
+ if (includeErrorBoundary) sections.push("", "export function ErrorBoundary({ error }: ErrorBoundaryProps) {", " return <p>{error.message}</p>;", "}");
108
+ return sections;
109
+ }
110
+ function buildApiMethodSource(method, methods, endpointPath) {
111
+ if (method === "DELETE" || method === "HEAD") return [
112
+ `export function ${method}(_args: BaseRouteArgs) {`,
113
+ " return new Response(null, { status: 204 });",
114
+ "}"
115
+ ];
116
+ if (method === "OPTIONS") return [
117
+ `export function ${method}(_args: BaseRouteArgs) {`,
118
+ " return new Response(null, {",
119
+ ` headers: { allow: ${quote(methods.join(", "))} },`,
120
+ " status: 204,",
121
+ " });",
122
+ "}"
123
+ ];
124
+ if (method === "GET") return [
125
+ `export function ${method}(_args: BaseRouteArgs) {`,
126
+ ` return Response.json({ endpoint: ${quote(`/api${endpointPath}`)}, ok: true });`,
127
+ "}"
128
+ ];
129
+ const status = method === "POST" ? 201 : 200;
130
+ return [
131
+ `export async function ${method}({ request }: BaseRouteArgs) {`,
132
+ " const body = await request.json();",
133
+ ` return Response.json({ body, ok: true }, { status: ${status} });`,
134
+ "}"
135
+ ];
136
+ }
137
+ function buildStaticPathsStub(params) {
138
+ if (params.length === 0) return "{}";
139
+ return `{ ${params.map((name) => `${name}: ${quote(`example-${name}`)}`).join(", ")} }`;
140
+ }
141
+ function escapeJsxText(value) {
142
+ return value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;");
143
+ }
5
144
  var generate_default = defineCommand({
6
145
  meta: {
7
146
  name: "generate",
@@ -260,141 +399,5 @@ function generateApi(args, project) {
260
399
  updated: []
261
400
  };
262
401
  }
263
- function buildRouteModuleSections(opts) {
264
- const { includeErrorBoundary, includeLoader, includeStaticPaths, routePath, title } = opts;
265
- const params = dynamicParamNames(routePath);
266
- const imports = [];
267
- const sections = [];
268
- if (includeLoader) imports.push("LoaderArgs", "RouteComponentProps");
269
- if (includeErrorBoundary) imports.push("ErrorBoundaryProps");
270
- if (imports.length > 0) {
271
- sections.push(`import type { ${imports.join(", ")} } from "@pracht/core";`);
272
- sections.push("");
273
- }
274
- if (includeLoader) sections.push("export async function loader(_args: LoaderArgs) {", ` return { message: ${quote(`Welcome to ${title}.`)} };`, "}", "");
275
- if (includeStaticPaths) sections.push("export function getStaticPaths() {", ` return [${buildStaticPathsStub(params)}];`, "}", "");
276
- if (includeLoader) sections.push("export function Component({ data }: RouteComponentProps<typeof loader>) {", " return (", " <section>", ` <h1>${escapeJsxText(title)}</h1>`, " <p>{data.message}</p>", " </section>", " );", "}");
277
- else sections.push("export function Component() {", " return (", " <section>", ` <h1>${escapeJsxText(title)}</h1>`, " </section>", " );", "}");
278
- if (includeErrorBoundary) sections.push("", "export function ErrorBoundary({ error }: ErrorBoundaryProps) {", " return <p>{error.message}</p>;", "}");
279
- return sections;
280
- }
281
- function buildManifestRouteModuleSource(opts) {
282
- const sections = buildRouteModuleSections(opts);
283
- const componentIdx = sections.findIndex((s) => s.startsWith("export function Component"));
284
- const insertAt = componentIdx === -1 ? sections.length : componentIdx;
285
- sections.splice(insertAt, 0, "export function head() {", ` return { title: ${quote(opts.title)} };`, "}", "");
286
- return `${sections.join("\n")}\n`;
287
- }
288
- function buildPagesRouteModuleSource(opts) {
289
- const sections = buildRouteModuleSections(opts);
290
- const firstExportIdx = sections.findIndex((s) => s.startsWith("export"));
291
- const insertAt = firstExportIdx === -1 ? sections.length : firstExportIdx;
292
- sections.splice(insertAt, 0, `export const RENDER_MODE = ${quote(opts.render)};`, "");
293
- return `${sections.join("\n")}\n`;
294
- }
295
- function buildShellModuleSource(name) {
296
- const title = titleCase(name);
297
- return [
298
- "import type { ShellProps } from \"@pracht/core\";",
299
- "",
300
- "export function Shell({ children }: ShellProps) {",
301
- " return (",
302
- ` <div class=${quote(`${name}-shell`)}>`,
303
- " <main>{children}</main>",
304
- " </div>",
305
- " );",
306
- "}",
307
- "",
308
- "export function head() {",
309
- ` return { title: ${quote(title)} };`,
310
- "}",
311
- ""
312
- ].join("\n");
313
- }
314
- function buildMiddlewareModuleSource() {
315
- return [
316
- "import type { MiddlewareFn } from \"@pracht/core\";",
317
- "",
318
- "export const middleware: MiddlewareFn = async (_args) => {",
319
- " return;",
320
- "};",
321
- ""
322
- ].join("\n");
323
- }
324
- function buildApiRouteSource({ endpointPath, methods }) {
325
- return [
326
- "import type { BaseRouteArgs } from \"@pracht/core\";",
327
- "",
328
- ...methods.flatMap((method, index) => {
329
- const lines = buildApiMethodSource(method, methods, endpointPath);
330
- if (index === methods.length - 1) return lines;
331
- return [...lines, ""];
332
- }),
333
- ""
334
- ].join("\n");
335
- }
336
- function buildApiMethodSource(method, methods, endpointPath) {
337
- if (method === "DELETE" || method === "HEAD") return [
338
- `export function ${method}(_args: BaseRouteArgs) {`,
339
- " return new Response(null, { status: 204 });",
340
- "}"
341
- ];
342
- if (method === "OPTIONS") return [
343
- `export function ${method}(_args: BaseRouteArgs) {`,
344
- " return new Response(null, {",
345
- ` headers: { allow: ${quote(methods.join(", "))} },`,
346
- " status: 204,",
347
- " });",
348
- "}"
349
- ];
350
- if (method === "GET") return [
351
- `export function ${method}(_args: BaseRouteArgs) {`,
352
- ` return Response.json({ endpoint: ${quote(`/api${endpointPath}`)}, ok: true });`,
353
- "}"
354
- ];
355
- const status = method === "POST" ? 201 : 200;
356
- return [
357
- `export async function ${method}({ request }: BaseRouteArgs) {`,
358
- " const body = await request.json();",
359
- ` return Response.json({ body, ok: true }, { status: ${status} });`,
360
- "}"
361
- ];
362
- }
363
- function normalizeRoutePathString(value) {
364
- if (!value || value === "/") return "/";
365
- const normalized = `/${value}`.replace(/\/+/g, "/");
366
- return normalized !== "/" && normalized.endsWith("/") ? normalized.slice(0, -1) : normalized;
367
- }
368
- function normalizeApiPath(value) {
369
- return normalizeRoutePathString(value).replace(/^\/api(?=\/|$)/, "") || "/";
370
- }
371
- function hasDynamicSegments(routePath) {
372
- return routePath.split("/").some((segment) => segment.startsWith(":") || segment === "*");
373
- }
374
- function dynamicParamNames(routePath) {
375
- return routePath.split("/").filter(Boolean).map((segment) => {
376
- if (segment.startsWith(":")) return segment.slice(1);
377
- if (segment === "*") return "slug";
378
- return null;
379
- }).filter((s) => s !== null);
380
- }
381
- function routeIdFromPath(routePath) {
382
- if (routePath === "/") return "index";
383
- return routePath.split("/").filter(Boolean).map((segment) => segment.replace(/^:/, "").replace(/\*/g, "splat")).join("-");
384
- }
385
- function titleFromPath(routePath) {
386
- if (routePath === "/") return "Home";
387
- return titleCase((routePath.split("/").filter(Boolean).at(-1) ?? "Page").replace(/^:/, "").replace(/\*/g, "slug"));
388
- }
389
- function titleCase(value) {
390
- return value.split(/[-_/]/).filter(Boolean).map((segment) => segment.charAt(0).toUpperCase() + segment.slice(1)).join(" ");
391
- }
392
- function buildStaticPathsStub(params) {
393
- if (params.length === 0) return "{}";
394
- return `{ ${params.map((name) => `${name}: ${quote(`example-${name}`)}`).join(", ")} }`;
395
- }
396
- function escapeJsxText(value) {
397
- return value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;");
398
- }
399
402
  //#endregion
400
403
  export { generate_default as default };
package/dist/index.mjs CHANGED
@@ -29,12 +29,12 @@ runMain(defineCommand({
29
29
  description: "The pracht CLI"
30
30
  },
31
31
  subCommands: {
32
- build: () => import("./build-DlABFPbG.mjs").then((m) => m.default),
32
+ build: () => import("./build-DkP2ffu9.mjs").then((m) => m.default),
33
33
  dev: () => import("./dev-BCFe3g38.mjs").then((m) => m.default),
34
- doctor: () => import("./doctor-CQq64tfW.mjs").then((m) => m.default),
35
- generate: () => import("./generate-sHtRHRAH.mjs").then((m) => m.default),
36
- inspect: () => import("./inspect-DP-h3vLw.mjs").then((m) => m.default),
37
- verify: () => import("./verify-D7Bg1Su6.mjs").then((m) => m.default)
34
+ doctor: () => import("./doctor-B5qYLJF8.mjs").then((m) => m.default),
35
+ generate: () => import("./generate-C9AMSGsv.mjs").then((m) => m.default),
36
+ inspect: () => import("./inspect-MseHPU9s.mjs").then((m) => m.default),
37
+ verify: () => import("./verify-Do8bG-fq.mjs").then((m) => m.default)
38
38
  }
39
39
  }));
40
40
  //#endregion
@@ -1,6 +1,6 @@
1
1
  import { t as HTTP_METHODS } from "./index.mjs";
2
2
  import { t as readClientBuildAssets } from "./build-metadata-BOChHO8g.mjs";
3
- import { a as readProjectConfig, c as resolveProjectPath, p as handleCliError } from "./project-DUyH_7eJ.mjs";
3
+ import { a as readProjectConfig, c as resolveProjectPath, p as handleCliError } from "./project-BdMiN3s7.mjs";
4
4
  import { defineCommand } from "citty";
5
5
  import { existsSync, readFileSync } from "node:fs";
6
6
  import { resolve } from "node:path";