naro-cli 0.26.0 → 0.28.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/README.md +59 -9
- package/dist/args.d.ts +2 -0
- package/dist/artifact-types.d.ts +1 -1
- package/dist/{chunk-RQJTCRKY.js → chunk-UJGDKNDM.js} +721 -978
- package/dist/deploy.d.ts +11 -2
- package/dist/deploy.js +7 -1
- package/dist/index.js +134 -60
- package/dist/user-adapter.d.ts +32 -0
- package/dist/working-tree.d.ts +1 -1
- package/package.json +5 -6
|
@@ -5,10 +5,10 @@ import {
|
|
|
5
5
|
|
|
6
6
|
// src/deploy.ts
|
|
7
7
|
import { existsSync as existsSync10 } from "fs";
|
|
8
|
-
import { mkdtemp as mkdtemp2, readFile as
|
|
8
|
+
import { mkdtemp as mkdtemp2, readFile as readFile16, rm as rm6 } from "fs/promises";
|
|
9
9
|
import { tmpdir as tmpdir2 } from "os";
|
|
10
|
-
import { basename as
|
|
11
|
-
import { fileURLToPath as
|
|
10
|
+
import { basename as basename4, dirname as dirname9, join as join31, resolve as resolve15 } from "path";
|
|
11
|
+
import { fileURLToPath as fileURLToPath5 } from "url";
|
|
12
12
|
|
|
13
13
|
// ../../packages/build/src/artifact-upload.ts
|
|
14
14
|
function artifactUploadEntries(artifact) {
|
|
@@ -41,7 +41,7 @@ function parseArtifactPutUrls(payload) {
|
|
|
41
41
|
}
|
|
42
42
|
async function eachWithinBudget(items, limit, budget, weigh, work) {
|
|
43
43
|
if (items.length === 0) return;
|
|
44
|
-
await new Promise((
|
|
44
|
+
await new Promise((resolve16, reject) => {
|
|
45
45
|
let next = 0;
|
|
46
46
|
let running = 0;
|
|
47
47
|
let weight = 0;
|
|
@@ -58,7 +58,7 @@ async function eachWithinBudget(items, limit, budget, weigh, work) {
|
|
|
58
58
|
running -= 1;
|
|
59
59
|
weight -= itemWeight;
|
|
60
60
|
finished += 1;
|
|
61
|
-
if (finished === items.length)
|
|
61
|
+
if (finished === items.length) resolve16();
|
|
62
62
|
else pump();
|
|
63
63
|
}, reject);
|
|
64
64
|
}
|
|
@@ -287,9 +287,9 @@ function hashAsset(data, contentType2) {
|
|
|
287
287
|
}
|
|
288
288
|
|
|
289
289
|
// ../../packages/build/src/local-build-executor.ts
|
|
290
|
-
import { access as
|
|
290
|
+
import { access as access6, mkdtemp, readFile as readFile14, rm as rm4 } from "fs/promises";
|
|
291
291
|
import { tmpdir } from "os";
|
|
292
|
-
import { dirname as
|
|
292
|
+
import { dirname as dirname3, join as join17, resolve as resolve7 } from "path";
|
|
293
293
|
|
|
294
294
|
// ../../packages/core/src/route-patterns.ts
|
|
295
295
|
var ROUTE_PATTERN = /^\/[A-Za-z0-9\-._~%!$&()*+,;=:@/[\]]*$/;
|
|
@@ -527,11 +527,33 @@ var CAPABILITIES = [
|
|
|
527
527
|
id: "team-usage",
|
|
528
528
|
domain: "teams",
|
|
529
529
|
title: "\uD300 \uC0AC\uC6A9\uB7C9",
|
|
530
|
-
routes: [
|
|
530
|
+
routes: [
|
|
531
|
+
"GET teams/[teamSlug]/usage",
|
|
532
|
+
"GET teams/[teamSlug]/usage/hosting"
|
|
533
|
+
],
|
|
531
534
|
ui: { kind: "built" },
|
|
532
535
|
cli: { kind: "built", commands: ["naro usage"] },
|
|
533
536
|
mcp: { kind: "built", tools: ["get_team_usage"] }
|
|
534
537
|
},
|
|
538
|
+
{
|
|
539
|
+
id: "team-backend-usage",
|
|
540
|
+
domain: "teams",
|
|
541
|
+
title: "\uD300 \uBC31\uC5D4\uB4DC \uC0AC\uC6A9\uB7C9\xB7\uC77C\uBCC4 \uCC28\uD2B8(\uD568\uC218 CPU\xB7DB\xB7\uC2A4\uD1A0\uB9AC\uC9C0\xB7\uB9AC\uC5BC\uD0C0\uC784)",
|
|
542
|
+
routes: [
|
|
543
|
+
"GET teams/[teamSlug]/backend-usage",
|
|
544
|
+
"GET teams/[teamSlug]/usage/series"
|
|
545
|
+
],
|
|
546
|
+
dashboard: "/[teamSlug]/projects",
|
|
547
|
+
ui: { kind: "built" },
|
|
548
|
+
cli: {
|
|
549
|
+
kind: "planned",
|
|
550
|
+
note: "\uD300 \uAC1C\uC694 \uCE74\uB4DC\uB85C \uBA3C\uC800 \uB0C8\uB2E4. naro usage\uC5D0 \uBC31\uC5D4\uB4DC \uC904\uC744 \uB354\uD558\uB294 \uAC83\uC774 \uB2E4\uC74C\uC774\uB2E4."
|
|
551
|
+
},
|
|
552
|
+
mcp: {
|
|
553
|
+
kind: "planned",
|
|
554
|
+
note: "get_team_usage\uC5D0 \uBC31\uC5D4\uB4DC \uC0AC\uC6A9\uB7C9\uC744 \uB354\uD558\uB294 \uAC83\uC774 \uB2E4\uC74C\uC774\uB2E4."
|
|
555
|
+
}
|
|
556
|
+
},
|
|
535
557
|
{
|
|
536
558
|
id: "billing-view",
|
|
537
559
|
domain: "billing",
|
|
@@ -902,47 +924,6 @@ var CAPABILITIES = [
|
|
|
902
924
|
note: "\uBCF5\uD638\uD654\uD55C \uAC12\uC744 .env.local\uC5D0 \uC4F4\uB2E4. list_environment_variables\uB294 \uAC12\uC744 \uAC00\uB9B0\uB2E4. 2026-11-03 \uACB0\uC815."
|
|
903
925
|
}
|
|
904
926
|
},
|
|
905
|
-
{
|
|
906
|
-
id: "supabase-connect",
|
|
907
|
-
domain: "env",
|
|
908
|
-
title: "\uAE30\uC874 Supabase \uD504\uB85C\uC81D\uD2B8 \uC5F0\uACB0\xB7\uD0A4 \uB2E4\uC2DC \uBC1B\uAE30",
|
|
909
|
-
routes: [
|
|
910
|
-
"GET supabase/authorize",
|
|
911
|
-
"GET supabase/callback",
|
|
912
|
-
"GET projects/[projectId]/supabase/projects",
|
|
913
|
-
"PUT projects/[projectId]/supabase"
|
|
914
|
-
],
|
|
915
|
-
dashboard: "/[teamSlug]/projects/[projectSlug]/settings",
|
|
916
|
-
ui: { kind: "built" },
|
|
917
|
-
cli: {
|
|
918
|
-
kind: "excluded",
|
|
919
|
-
reason: "browser-required",
|
|
920
|
-
note: "Supabase OAuth \uB9AC\uB2E4\uC774\uB809\uD2B8\uB85C \uB05D\uB09C\uB2E4. \uD1A0\uD070\uC740 10\uBD84 \uCFE0\uD0A4\uC5D0\uB9CC \uC788\uB2E4(\uC124\uACC4 2026-11-04 \xA72.1)."
|
|
921
|
-
},
|
|
922
|
-
mcp: {
|
|
923
|
-
kind: "excluded",
|
|
924
|
-
reason: "browser-required",
|
|
925
|
-
note: "Supabase OAuth \uB9AC\uB2E4\uC774\uB809\uD2B8\uB85C \uB05D\uB09C\uB2E4. \uB300\uC2DC\uBCF4\uB4DC\uC758 \uD504\uB85C\uC81D\uD2B8 \uC124\uC815 \uD0ED\uC5D0\uC11C \uC5F0\uACB0\uD55C\uB2E4."
|
|
926
|
-
}
|
|
927
|
-
},
|
|
928
|
-
{
|
|
929
|
-
id: "supabase-link-list",
|
|
930
|
-
domain: "env",
|
|
931
|
-
title: "Supabase \uC5F0\uACB0 \uBCF4\uAE30",
|
|
932
|
-
routes: ["GET projects/[projectId]/supabase"],
|
|
933
|
-
ui: { kind: "built" },
|
|
934
|
-
cli: { kind: "built", commands: ["naro supabase"] },
|
|
935
|
-
mcp: { kind: "built", tools: ["list_supabase_links"] }
|
|
936
|
-
},
|
|
937
|
-
{
|
|
938
|
-
id: "supabase-disconnect",
|
|
939
|
-
domain: "env",
|
|
940
|
-
title: "Supabase \uC5F0\uACB0 \uD574\uC81C",
|
|
941
|
-
routes: ["DELETE projects/[projectId]/supabase"],
|
|
942
|
-
ui: { kind: "built" },
|
|
943
|
-
cli: { kind: "built", commands: ["naro supabase disconnect"] },
|
|
944
|
-
mcp: { kind: "built", tools: ["disconnect_supabase"] }
|
|
945
|
-
},
|
|
946
927
|
{
|
|
947
928
|
id: "environment-list",
|
|
948
929
|
domain: "environments",
|
|
@@ -1895,6 +1876,19 @@ var CAPABILITIES = [
|
|
|
1895
1876
|
cli: { kind: "built", commands: ["naro backend"] },
|
|
1896
1877
|
mcp: { kind: "built", tools: ["get_backend"] }
|
|
1897
1878
|
},
|
|
1879
|
+
{
|
|
1880
|
+
id: "backend-usage",
|
|
1881
|
+
domain: "backend",
|
|
1882
|
+
title: "Backend \uAC1C\uC694\uC758 \uC0AC\uC6A9\uB7C9(DB \uC4F0\uAE30\xB7\uD06C\uAE30, Storage \uC6A9\uB7C9\xB7\uC4F0\uAE30, \uD568\uC218 \uD638\uCD9C, Realtime \uBA54\uC2DC\uC9C0)",
|
|
1883
|
+
routes: ["GET projects/[projectId]/backend/usage"],
|
|
1884
|
+
ui: { kind: "built" },
|
|
1885
|
+
// 같은 숫자를 섹션마다 이미 돌려준다: naro db info(오늘 쓴 행·한도), naro
|
|
1886
|
+
// storage(용량·오늘 쓰기), naro functions(함수별 오늘 호출), naro realtime
|
|
1887
|
+
// (이번 달 메시지). 이 라우트는 개요가 한 번에 읽으려고 모은 것이다.
|
|
1888
|
+
cli: { kind: "built" },
|
|
1889
|
+
// get_database·get_storage·list_functions·get_realtime이 같은 숫자를 준다.
|
|
1890
|
+
mcp: { kind: "built" }
|
|
1891
|
+
},
|
|
1898
1892
|
{
|
|
1899
1893
|
id: "backend-enable",
|
|
1900
1894
|
domain: "backend",
|
|
@@ -2270,7 +2264,7 @@ function parseDotenvDetailed(text3) {
|
|
|
2270
2264
|
var STALL_WINDOW_MS = 10 * 6e4;
|
|
2271
2265
|
|
|
2272
2266
|
// ../../packages/core/src/deployment-strategy.ts
|
|
2273
|
-
var MIN_SUPPORTED_NEXT_MAJOR =
|
|
2267
|
+
var MIN_SUPPORTED_NEXT_MAJOR = 16;
|
|
2274
2268
|
|
|
2275
2269
|
// ../../packages/core/src/environment-guidance.ts
|
|
2276
2270
|
var DATA_COMMANDS = /* @__PURE__ */ new Set([
|
|
@@ -2553,12 +2547,8 @@ var DEPLOYMENT_ERROR_CODES = [
|
|
|
2553
2547
|
"ENVIRONMENT_DELETED",
|
|
2554
2548
|
/** The edge refused the environment's protection change; the database change is rolled back. */
|
|
2555
2549
|
"ENVIRONMENT_PROTECTION_PUBLISH_FAILED",
|
|
2556
|
-
/** The variable
|
|
2557
|
-
"ENV_MANAGED"
|
|
2558
|
-
/** The 10-minute Supabase sign-in cookie is gone or expired (spec 2026-11-04 §6.4). */
|
|
2559
|
-
"SUPABASE_SESSION_EXPIRED",
|
|
2560
|
-
/** The Supabase Management API refused or did not answer (spec 2026-11-04 §6.4). */
|
|
2561
|
-
"SUPABASE_API_FAILED"
|
|
2550
|
+
/** The variable is owned by the Resend connection; only it changes it (spec 2026-11-04 resend §6.4). */
|
|
2551
|
+
"ENV_MANAGED"
|
|
2562
2552
|
];
|
|
2563
2553
|
var DeploymentError = class extends Error {
|
|
2564
2554
|
code;
|
|
@@ -17636,6 +17626,130 @@ var BUILDS = {
|
|
|
17636
17626
|
}
|
|
17637
17627
|
};
|
|
17638
17628
|
|
|
17629
|
+
// ../../packages/next-adapter/src/index.ts
|
|
17630
|
+
import { fileURLToPath } from "url";
|
|
17631
|
+
|
|
17632
|
+
// ../../packages/next-adapter/src/supported.ts
|
|
17633
|
+
var SUPPORTED_NEXT = [
|
|
17634
|
+
{ minor: "16.2", next: "16.2.12", routing: "@next/routing-16.2" },
|
|
17635
|
+
{ minor: "16.3", next: "16.3.8", routing: "@next/routing-16.3" },
|
|
17636
|
+
{ minor: "16.4", next: "16.4.5", routing: "@next/routing-16.4" }
|
|
17637
|
+
];
|
|
17638
|
+
var VERSION = /^(\d+)\.(\d+)\.(\d+)/;
|
|
17639
|
+
function judgeNextVersion(version3) {
|
|
17640
|
+
const match = VERSION.exec(version3.trim());
|
|
17641
|
+
if (!match) return null;
|
|
17642
|
+
const major = Number(match[1]);
|
|
17643
|
+
const minor = Number(match[2]);
|
|
17644
|
+
if (major < 16 || major === 16 && minor < 2) return { kind: "too-old" };
|
|
17645
|
+
const entry = SUPPORTED_NEXT.find(
|
|
17646
|
+
(candidate) => candidate.minor === `${String(major)}.${String(minor)}`
|
|
17647
|
+
);
|
|
17648
|
+
if (entry) return { kind: "supported", entry };
|
|
17649
|
+
const newest = SUPPORTED_NEXT[SUPPORTED_NEXT.length - 1];
|
|
17650
|
+
if (!newest) throw new Error("SUPPORTED_NEXT is empty.");
|
|
17651
|
+
return { kind: "newer", entry: newest };
|
|
17652
|
+
}
|
|
17653
|
+
function testedRange() {
|
|
17654
|
+
const first = SUPPORTED_NEXT[0];
|
|
17655
|
+
const last = SUPPORTED_NEXT[SUPPORTED_NEXT.length - 1];
|
|
17656
|
+
if (!first || !last) throw new Error("SUPPORTED_NEXT is empty.");
|
|
17657
|
+
return `${first.minor}\u2013${last.minor}`;
|
|
17658
|
+
}
|
|
17659
|
+
|
|
17660
|
+
// ../../packages/next-adapter/src/paths.ts
|
|
17661
|
+
var OUTPUT_DIR = ".naro";
|
|
17662
|
+
var BUILD_RECORD = ".naro/build.json";
|
|
17663
|
+
var WORKER_DIR = ".naro/worker";
|
|
17664
|
+
var ASSETS_DIR = ".naro/assets";
|
|
17665
|
+
var WRANGLER_CONFIG = ".naro/worker/wrangler.jsonc";
|
|
17666
|
+
|
|
17667
|
+
// ../../packages/next-adapter/src/bundle/wrangler.ts
|
|
17668
|
+
import { posix } from "path";
|
|
17669
|
+
|
|
17670
|
+
// ../../packages/next-adapter/src/config-wrapper.ts
|
|
17671
|
+
import { access, readFile as readFile2, rename, writeFile as writeFile2 } from "fs/promises";
|
|
17672
|
+
import { join as join2 } from "path";
|
|
17673
|
+
var PROJECT_CONFIG_BASENAME = "next.config.naro-user";
|
|
17674
|
+
var WRAPPABLE = {
|
|
17675
|
+
"next.config.js": {
|
|
17676
|
+
wrapper: "next.config.mjs",
|
|
17677
|
+
specifier: `./${PROJECT_CONFIG_BASENAME}.js`,
|
|
17678
|
+
typescript: false
|
|
17679
|
+
},
|
|
17680
|
+
"next.config.mjs": {
|
|
17681
|
+
wrapper: "next.config.mjs",
|
|
17682
|
+
specifier: `./${PROJECT_CONFIG_BASENAME}.mjs`,
|
|
17683
|
+
typescript: false
|
|
17684
|
+
},
|
|
17685
|
+
"next.config.ts": {
|
|
17686
|
+
wrapper: "next.config.ts",
|
|
17687
|
+
specifier: `./${PROJECT_CONFIG_BASENAME}`,
|
|
17688
|
+
typescript: true
|
|
17689
|
+
},
|
|
17690
|
+
"next.config.mts": {
|
|
17691
|
+
wrapper: "next.config.mts",
|
|
17692
|
+
specifier: `./${PROJECT_CONFIG_BASENAME}.mts`,
|
|
17693
|
+
typescript: true
|
|
17694
|
+
}
|
|
17695
|
+
};
|
|
17696
|
+
function nextConfigWrapperSource(projectSpecifier, typescript) {
|
|
17697
|
+
return `${typescript ? "// @ts-nocheck\n" : ""}// Written by Naro for this build only. The project's own next.config is
|
|
17698
|
+
// ${projectSpecifier}, unchanged; this wrapper swaps its Next.js adapter for
|
|
17699
|
+
// the Naro adapter (project setting "replace").
|
|
17700
|
+
import projectConfig from ${JSON.stringify(projectSpecifier)};
|
|
17701
|
+
|
|
17702
|
+
export default async function naroNextConfig(phase, context) {
|
|
17703
|
+
const config =
|
|
17704
|
+
typeof projectConfig === "function"
|
|
17705
|
+
? await projectConfig(phase, context)
|
|
17706
|
+
: await projectConfig;
|
|
17707
|
+
const rest = { ...(config ?? {}) };
|
|
17708
|
+
delete rest.adapterPath;
|
|
17709
|
+
if (rest.experimental && typeof rest.experimental === "object") {
|
|
17710
|
+
rest.experimental = { ...rest.experimental };
|
|
17711
|
+
delete rest.experimental.adapterPath;
|
|
17712
|
+
}
|
|
17713
|
+
return { ...rest, adapterPath: process.env.NEXT_ADAPTER_PATH };
|
|
17714
|
+
}
|
|
17715
|
+
`;
|
|
17716
|
+
}
|
|
17717
|
+
async function exists(path) {
|
|
17718
|
+
try {
|
|
17719
|
+
await access(path);
|
|
17720
|
+
return true;
|
|
17721
|
+
} catch {
|
|
17722
|
+
return false;
|
|
17723
|
+
}
|
|
17724
|
+
}
|
|
17725
|
+
async function wrapNextConfig(appRoot, file2) {
|
|
17726
|
+
const plan = WRAPPABLE[file2];
|
|
17727
|
+
if (!plan) return null;
|
|
17728
|
+
const ext = file2.slice("next.config.".length);
|
|
17729
|
+
const project2 = `${PROJECT_CONFIG_BASENAME}.${ext}`;
|
|
17730
|
+
if (await exists(join2(appRoot, project2)))
|
|
17731
|
+
throw new Error(
|
|
17732
|
+
`${project2} already exists in the project; Naro needs that name to replace the project's Next.js adapter.`
|
|
17733
|
+
);
|
|
17734
|
+
await readFile2(join2(appRoot, file2));
|
|
17735
|
+
await rename(join2(appRoot, file2), join2(appRoot, project2));
|
|
17736
|
+
await writeFile2(
|
|
17737
|
+
join2(appRoot, plan.wrapper),
|
|
17738
|
+
nextConfigWrapperSource(plan.specifier, plan.typescript)
|
|
17739
|
+
);
|
|
17740
|
+
return { wrapper: plan.wrapper, project: project2 };
|
|
17741
|
+
}
|
|
17742
|
+
|
|
17743
|
+
// ../../packages/next-adapter/src/index.ts
|
|
17744
|
+
function nextAdapterPath(base2 = import.meta.url) {
|
|
17745
|
+
if (!base2) return void 0;
|
|
17746
|
+
try {
|
|
17747
|
+
return fileURLToPath(new URL("../dist/adapter.cjs", base2));
|
|
17748
|
+
} catch {
|
|
17749
|
+
return void 0;
|
|
17750
|
+
}
|
|
17751
|
+
}
|
|
17752
|
+
|
|
17639
17753
|
// ../../packages/build/src/next-version.ts
|
|
17640
17754
|
var NEXT_RELEASE_DATES = {
|
|
17641
17755
|
16: "2025-10-21",
|
|
@@ -17645,7 +17759,6 @@ var NEXT_RELEASE_DATES = {
|
|
|
17645
17759
|
12: "2021-10-26"
|
|
17646
17760
|
};
|
|
17647
17761
|
var SUPPORT_WINDOW_YEARS = 2;
|
|
17648
|
-
var VERIFIED_15_FLOOR = { major: 15, minor: 5, patch: 21 };
|
|
17649
17762
|
var VERIFIED_16_FLOOR = { major: 16, minor: 2, patch: 11 };
|
|
17650
17763
|
function parseNextVersion(raw) {
|
|
17651
17764
|
const match = /^\s*(\d+)\.(\d+)\.(\d+)/.exec(raw);
|
|
@@ -17673,7 +17786,6 @@ function compare(a, b) {
|
|
|
17673
17786
|
return a.major - b.major || a.minor - b.minor || a.patch - b.patch;
|
|
17674
17787
|
}
|
|
17675
17788
|
function withinVerifiedRange(version3) {
|
|
17676
|
-
if (version3.major === 15) return compare(version3, VERIFIED_15_FLOOR) >= 0;
|
|
17677
17789
|
if (version3.major === 16) return compare(version3, VERIFIED_16_FLOOR) >= 0;
|
|
17678
17790
|
return version3.major > 16;
|
|
17679
17791
|
}
|
|
@@ -17689,34 +17801,34 @@ function classifyNextVersion(raw, now) {
|
|
|
17689
17801
|
reason: `Could not read a Next.js version from "${raw}".`
|
|
17690
17802
|
};
|
|
17691
17803
|
}
|
|
17692
|
-
|
|
17693
|
-
if (!windowEnd || version3.major < VERIFIED_15_FLOOR.major) {
|
|
17804
|
+
if (version3.major < MIN_SUPPORTED_NEXT_MAJOR) {
|
|
17694
17805
|
return {
|
|
17695
17806
|
status: "too-old",
|
|
17696
17807
|
version: version3,
|
|
17697
|
-
reason: `Next.js ${raw} is too old to deploy. Naro deploys Next.js
|
|
17808
|
+
reason: `Next.js ${raw} is too old to deploy. Naro deploys Next.js ${String(MIN_SUPPORTED_NEXT_MAJOR)} or newer. Upgrade to Next.js 16.`
|
|
17698
17809
|
};
|
|
17699
17810
|
}
|
|
17700
|
-
|
|
17811
|
+
const windowEnd = supportEndsAt(version3.major);
|
|
17812
|
+
if (windowEnd && now > windowEnd) {
|
|
17701
17813
|
return {
|
|
17702
|
-
status: "
|
|
17814
|
+
status: "past-support-window",
|
|
17703
17815
|
version: version3,
|
|
17704
|
-
reason: `Next.js ${version3.major} left its support window on ${formatDate(windowEnd)}. The build continues, but unsupported releases stop receiving security patches \u2014 upgrade
|
|
17816
|
+
reason: `Next.js ${version3.major} left its support window on ${formatDate(windowEnd)}. The build continues, but unsupported releases stop receiving security patches \u2014 upgrade Next.js. See https://nextjs.org/support-policy`
|
|
17705
17817
|
};
|
|
17706
17818
|
}
|
|
17707
17819
|
if (!withinVerifiedRange(version3)) {
|
|
17708
17820
|
return {
|
|
17709
|
-
status: "outside-
|
|
17821
|
+
status: "outside-verified-range",
|
|
17710
17822
|
version: version3,
|
|
17711
|
-
reason: `Next.js ${raw} is outside the range Naro verifies deploys on (>=
|
|
17823
|
+
reason: `Next.js ${raw} is outside the range Naro verifies deploys on (>=16.2.11). The build may fail in ways Naro cannot explain.`
|
|
17712
17824
|
};
|
|
17713
17825
|
}
|
|
17714
17826
|
return { status: "supported", version: version3, reason: "" };
|
|
17715
17827
|
}
|
|
17716
17828
|
|
|
17717
17829
|
// ../../packages/build/src/package-manager.ts
|
|
17718
|
-
import { access, readFile as
|
|
17719
|
-
import { join as
|
|
17830
|
+
import { access as access2, readFile as readFile3 } from "fs/promises";
|
|
17831
|
+
import { join as join3 } from "path";
|
|
17720
17832
|
function cacheEnv(dir, manager) {
|
|
17721
17833
|
return {
|
|
17722
17834
|
...manager === "pnpm" ? { npm_config_store_dir: dir } : {},
|
|
@@ -17736,9 +17848,9 @@ function withSharedCache(spec, dir) {
|
|
|
17736
17848
|
addEnv: { ...spec.addEnv, ...cacheEnv(dir, spec.name) }
|
|
17737
17849
|
};
|
|
17738
17850
|
}
|
|
17739
|
-
async function
|
|
17851
|
+
async function exists2(path) {
|
|
17740
17852
|
try {
|
|
17741
|
-
await
|
|
17853
|
+
await access2(path);
|
|
17742
17854
|
return true;
|
|
17743
17855
|
} catch {
|
|
17744
17856
|
return false;
|
|
@@ -17746,7 +17858,7 @@ async function exists(path) {
|
|
|
17746
17858
|
}
|
|
17747
17859
|
async function usesModernYarn(root) {
|
|
17748
17860
|
try {
|
|
17749
|
-
const raw = await
|
|
17861
|
+
const raw = await readFile3(join3(root, "package.json"), "utf8");
|
|
17750
17862
|
const packageJson = JSON.parse(raw);
|
|
17751
17863
|
if (typeof packageJson.packageManager !== "string") return false;
|
|
17752
17864
|
const version3 = /^yarn@(\d+)/.exec(packageJson.packageManager)?.[1];
|
|
@@ -17756,7 +17868,7 @@ async function usesModernYarn(root) {
|
|
|
17756
17868
|
}
|
|
17757
17869
|
}
|
|
17758
17870
|
async function detectPackageManager(root) {
|
|
17759
|
-
if (await
|
|
17871
|
+
if (await exists2(join3(root, "pnpm-lock.yaml"))) {
|
|
17760
17872
|
return {
|
|
17761
17873
|
name: "pnpm",
|
|
17762
17874
|
install: ["pnpm", "install", "--frozen-lockfile"],
|
|
@@ -17767,7 +17879,7 @@ async function detectPackageManager(root) {
|
|
|
17767
17879
|
addArgs: (specs) => ["pnpm", "add", ...specs]
|
|
17768
17880
|
};
|
|
17769
17881
|
}
|
|
17770
|
-
if (await
|
|
17882
|
+
if (await exists2(join3(root, "package-lock.json"))) {
|
|
17771
17883
|
return {
|
|
17772
17884
|
name: "npm",
|
|
17773
17885
|
install: ["npm", "ci"],
|
|
@@ -17793,7 +17905,7 @@ async function detectPackageManager(root) {
|
|
|
17793
17905
|
sharedCacheAddArgs: ["--prefer-offline"]
|
|
17794
17906
|
};
|
|
17795
17907
|
}
|
|
17796
|
-
if (await
|
|
17908
|
+
if (await exists2(join3(root, "yarn.lock"))) {
|
|
17797
17909
|
const modern = await usesModernYarn(root);
|
|
17798
17910
|
return {
|
|
17799
17911
|
name: "yarn",
|
|
@@ -17814,114 +17926,13 @@ async function detectPackageManager(root) {
|
|
|
17814
17926
|
);
|
|
17815
17927
|
}
|
|
17816
17928
|
|
|
17817
|
-
// ../../packages/build/src/proxy-to-middleware.ts
|
|
17818
|
-
import { access as access2, readFile as readFile3, rename, writeFile as writeFile2 } from "fs/promises";
|
|
17819
|
-
import { join as join3 } from "path";
|
|
17820
|
-
var EXTENSIONS = ["ts", "tsx", "js", "jsx"];
|
|
17821
|
-
var DIRECTORIES = ["", "src"];
|
|
17822
|
-
async function exists2(path) {
|
|
17823
|
-
try {
|
|
17824
|
-
await access2(path);
|
|
17825
|
-
return true;
|
|
17826
|
-
} catch {
|
|
17827
|
-
return false;
|
|
17828
|
-
}
|
|
17829
|
-
}
|
|
17830
|
-
function renameExport(source) {
|
|
17831
|
-
return source.replace(
|
|
17832
|
-
/(export\s+(?:default\s+)?(?:async\s+)?function\s+)proxy\b/g,
|
|
17833
|
-
"$1middleware"
|
|
17834
|
-
).replace(/(export\s+const\s+)proxy\b/g, "$1middleware");
|
|
17835
|
-
}
|
|
17836
|
-
async function convertProxyToMiddleware(appRoot) {
|
|
17837
|
-
for (const dir of DIRECTORIES) {
|
|
17838
|
-
for (const ext of EXTENSIONS) {
|
|
17839
|
-
const rel = join3(dir, `proxy.${ext}`);
|
|
17840
|
-
const proxyPath = join3(appRoot, rel);
|
|
17841
|
-
if (!await exists2(proxyPath)) continue;
|
|
17842
|
-
const middlewarePath = join3(appRoot, dir, `middleware.${ext}`);
|
|
17843
|
-
if (await exists2(middlewarePath)) return { converted: false };
|
|
17844
|
-
const source = await readFile3(proxyPath, "utf8");
|
|
17845
|
-
await writeFile2(middlewarePath, renameExport(source));
|
|
17846
|
-
await rename(proxyPath, `${proxyPath}.converted`);
|
|
17847
|
-
return { converted: true, file: rel };
|
|
17848
|
-
}
|
|
17849
|
-
}
|
|
17850
|
-
return { converted: false };
|
|
17851
|
-
}
|
|
17852
|
-
|
|
17853
17929
|
// ../../packages/build/src/vinext.ts
|
|
17854
|
-
import { access as
|
|
17855
|
-
import { join as join6, resolve
|
|
17930
|
+
import { access as access3, readFile as readFile5, writeFile as writeFile4 } from "fs/promises";
|
|
17931
|
+
import { join as join6, resolve } from "path";
|
|
17856
17932
|
|
|
17857
|
-
// ../../packages/build/src/
|
|
17858
|
-
import {
|
|
17859
|
-
import {
|
|
17860
|
-
basename,
|
|
17861
|
-
dirname,
|
|
17862
|
-
extname,
|
|
17863
|
-
isAbsolute,
|
|
17864
|
-
join as join4,
|
|
17865
|
-
relative,
|
|
17866
|
-
resolve,
|
|
17867
|
-
sep
|
|
17868
|
-
} from "path";
|
|
17869
|
-
function parseJsonc(source) {
|
|
17870
|
-
let output = "";
|
|
17871
|
-
let index = 0;
|
|
17872
|
-
let inString = false;
|
|
17873
|
-
let escaped = false;
|
|
17874
|
-
while (index < source.length) {
|
|
17875
|
-
const current = source[index] ?? "";
|
|
17876
|
-
const next = source[index + 1] ?? "";
|
|
17877
|
-
if (inString) {
|
|
17878
|
-
output += current;
|
|
17879
|
-
if (escaped) escaped = false;
|
|
17880
|
-
else if (current === "\\") escaped = true;
|
|
17881
|
-
else if (current === '"') inString = false;
|
|
17882
|
-
index += 1;
|
|
17883
|
-
continue;
|
|
17884
|
-
}
|
|
17885
|
-
if (current === '"') {
|
|
17886
|
-
inString = true;
|
|
17887
|
-
output += current;
|
|
17888
|
-
index += 1;
|
|
17889
|
-
continue;
|
|
17890
|
-
}
|
|
17891
|
-
if (current === "/" && next === "/") {
|
|
17892
|
-
index += 2;
|
|
17893
|
-
while (index < source.length && source[index] !== "\n") index += 1;
|
|
17894
|
-
continue;
|
|
17895
|
-
}
|
|
17896
|
-
if (current === "/" && next === "*") {
|
|
17897
|
-
index += 2;
|
|
17898
|
-
while (index < source.length && !(source[index] === "*" && source[index + 1] === "/"))
|
|
17899
|
-
index += 1;
|
|
17900
|
-
index += 2;
|
|
17901
|
-
continue;
|
|
17902
|
-
}
|
|
17903
|
-
output += current;
|
|
17904
|
-
index += 1;
|
|
17905
|
-
}
|
|
17906
|
-
return JSON.parse(output.replace(/,\s*([}\]])/g, "$1"));
|
|
17907
|
-
}
|
|
17908
|
-
function confinedPath(root, configuredPath, label2, base2 = root) {
|
|
17909
|
-
if (isAbsolute(configuredPath)) {
|
|
17910
|
-
throw new DeploymentError(
|
|
17911
|
-
"ARTIFACT_INVALID",
|
|
17912
|
-
`${label2} must be relative to the application root.`
|
|
17913
|
-
);
|
|
17914
|
-
}
|
|
17915
|
-
const resolved = resolve(base2, configuredPath);
|
|
17916
|
-
const relation = relative(root, resolved);
|
|
17917
|
-
if (relation === ".." || relation.startsWith(`..${sep}`) || isAbsolute(relation)) {
|
|
17918
|
-
throw new DeploymentError(
|
|
17919
|
-
"ARTIFACT_INVALID",
|
|
17920
|
-
`${label2} escapes the application root.`
|
|
17921
|
-
);
|
|
17922
|
-
}
|
|
17923
|
-
return resolved;
|
|
17924
|
-
}
|
|
17933
|
+
// ../../packages/build/src/artifact-files.ts
|
|
17934
|
+
import { readdir, readFile as readFile4, realpath } from "fs/promises";
|
|
17935
|
+
import { extname, isAbsolute, join as join4, relative, sep } from "path";
|
|
17925
17936
|
function contentType(path) {
|
|
17926
17937
|
switch (extname(path).toLowerCase()) {
|
|
17927
17938
|
case ".html":
|
|
@@ -17996,7 +18007,7 @@ async function assertInsideOnDisk(appRoot, directory, label2) {
|
|
|
17996
18007
|
);
|
|
17997
18008
|
}
|
|
17998
18009
|
}
|
|
17999
|
-
async function listArtifactFiles(root, label2 = "
|
|
18010
|
+
async function listArtifactFiles(root, label2 = "Build", appRoot) {
|
|
18000
18011
|
if (appRoot !== void 0) await assertInsideOnDisk(appRoot, root, label2);
|
|
18001
18012
|
const files = [];
|
|
18002
18013
|
async function visit(directory) {
|
|
@@ -18024,131 +18035,12 @@ async function listArtifactFiles(root, label2 = "OpenNext", appRoot) {
|
|
|
18024
18035
|
await visit(root);
|
|
18025
18036
|
return files;
|
|
18026
18037
|
}
|
|
18027
|
-
|
|
18028
|
-
|
|
18029
|
-
const resolved = isAbsolute(configuredPath) ? configuredPath : resolve(root, configuredPath);
|
|
18030
|
-
const relation = relative(root, resolved);
|
|
18031
|
-
if (relation === ".." || relation.startsWith(`..${sep}`) || isAbsolute(relation)) {
|
|
18032
|
-
throw new DeploymentError(
|
|
18033
|
-
"ARTIFACT_INVALID",
|
|
18034
|
-
"Wrangler config escapes the application root."
|
|
18035
|
-
);
|
|
18036
|
-
}
|
|
18037
|
-
await access3(resolved);
|
|
18038
|
-
return resolved;
|
|
18039
|
-
}
|
|
18040
|
-
for (const name of ["wrangler.jsonc", "wrangler.json"]) {
|
|
18041
|
-
const path = join4(root, name);
|
|
18042
|
-
try {
|
|
18043
|
-
await access3(path);
|
|
18044
|
-
return path;
|
|
18045
|
-
} catch {
|
|
18046
|
-
}
|
|
18047
|
-
}
|
|
18048
|
-
throw new DeploymentError(
|
|
18049
|
-
"ARTIFACT_INVALID",
|
|
18050
|
-
"A wrangler.jsonc or wrangler.json file is required."
|
|
18051
|
-
);
|
|
18052
|
-
}
|
|
18053
|
-
var OPEN_NEXT_LAYOUT = {
|
|
18054
|
-
outputRoot: ".open-next",
|
|
18055
|
-
bundleDir: ".open-next/worker-bundle"
|
|
18056
|
-
};
|
|
18057
|
-
async function readOpenNextArtifact(appRoot, identity, wranglerConfigPath) {
|
|
18058
|
-
const configPath = await findWranglerConfig(appRoot, wranglerConfigPath);
|
|
18059
|
-
return readWorkerArtifact(appRoot, identity, {
|
|
18060
|
-
wranglerConfigPath: configPath,
|
|
18061
|
-
...OPEN_NEXT_LAYOUT
|
|
18062
|
-
});
|
|
18063
|
-
}
|
|
18064
|
-
async function readWorkerArtifact(appRoot, identity, layout) {
|
|
18065
|
-
const listFiles = (root) => listArtifactFiles(root, "OpenNext", appRoot);
|
|
18066
|
-
try {
|
|
18067
|
-
const configPath = await findWranglerConfig(
|
|
18068
|
-
appRoot,
|
|
18069
|
-
layout.wranglerConfigPath
|
|
18070
|
-
);
|
|
18071
|
-
const metadata = parseJsonc(
|
|
18072
|
-
await readFile4(configPath, "utf8")
|
|
18073
|
-
);
|
|
18074
|
-
if (typeof metadata.main !== "string" || typeof metadata.compatibility_date !== "string") {
|
|
18075
|
-
throw new DeploymentError(
|
|
18076
|
-
"ARTIFACT_INVALID",
|
|
18077
|
-
"Wrangler metadata must declare main and compatibility_date."
|
|
18078
|
-
);
|
|
18079
|
-
}
|
|
18080
|
-
const configDir = dirname(configPath);
|
|
18081
|
-
const outputRoot = confinedPath(appRoot, layout.outputRoot, "Output root");
|
|
18082
|
-
const entrypointPath = confinedPath(
|
|
18083
|
-
appRoot,
|
|
18084
|
-
metadata.main,
|
|
18085
|
-
"Worker entrypoint",
|
|
18086
|
-
configDir
|
|
18087
|
-
);
|
|
18088
|
-
const entryRelation = relative(outputRoot, entrypointPath);
|
|
18089
|
-
if (entryRelation === ".." || entryRelation.startsWith(`..${sep}`) || isAbsolute(entryRelation)) {
|
|
18090
|
-
throw new DeploymentError(
|
|
18091
|
-
"ARTIFACT_INVALID",
|
|
18092
|
-
`Worker entrypoint must be inside ${layout.outputRoot}.`
|
|
18093
|
-
);
|
|
18094
|
-
}
|
|
18095
|
-
await access3(entrypointPath);
|
|
18096
|
-
const configuredAssets = typeof metadata.assets?.directory === "string" ? confinedPath(
|
|
18097
|
-
appRoot,
|
|
18098
|
-
metadata.assets.directory,
|
|
18099
|
-
"Assets directory",
|
|
18100
|
-
configDir
|
|
18101
|
-
) : join4(outputRoot, "assets");
|
|
18102
|
-
const assetsRelation = relative(outputRoot, configuredAssets);
|
|
18103
|
-
if (assetsRelation === ".." || assetsRelation.startsWith(`..${sep}`) || isAbsolute(assetsRelation)) {
|
|
18104
|
-
throw new DeploymentError(
|
|
18105
|
-
"ARTIFACT_INVALID",
|
|
18106
|
-
`Assets directory must be inside ${layout.outputRoot}.`
|
|
18107
|
-
);
|
|
18108
|
-
}
|
|
18109
|
-
const bundleRoot = confinedPath(appRoot, layout.bundleDir, "Bundle dir");
|
|
18110
|
-
let bundleExists = true;
|
|
18111
|
-
try {
|
|
18112
|
-
await access3(bundleRoot);
|
|
18113
|
-
} catch {
|
|
18114
|
-
bundleExists = false;
|
|
18115
|
-
}
|
|
18116
|
-
const bundleFiles = bundleExists ? await listFiles(bundleRoot) : null;
|
|
18117
|
-
const outputFiles = bundleFiles ?? await listFiles(outputRoot);
|
|
18118
|
-
const entrypointName = bundleFiles ? basename(entrypointPath) : relative(outputRoot, entrypointPath).split(sep).join("/");
|
|
18119
|
-
const assetsPrefix = `${relative(outputRoot, configuredAssets).split(sep).join("/")}/`;
|
|
18120
|
-
const entrypoint = outputFiles.find((file2) => file2.name === entrypointName);
|
|
18121
|
-
if (!entrypoint)
|
|
18122
|
-
throw new DeploymentError(
|
|
18123
|
-
"ARTIFACT_INVALID",
|
|
18124
|
-
"Worker entrypoint is missing from the build output."
|
|
18125
|
-
);
|
|
18126
|
-
return {
|
|
18127
|
-
...identity,
|
|
18128
|
-
entrypoint,
|
|
18129
|
-
modules: outputFiles.filter(
|
|
18130
|
-
(file2) => file2.name !== entrypointName && !file2.name.endsWith(".map") && file2.name !== "README.md" && (bundleFiles !== null || !file2.name.startsWith(assetsPrefix))
|
|
18131
|
-
),
|
|
18132
|
-
assets: (await listFiles(configuredAssets)).map((file2) => ({ ...file2 })),
|
|
18133
|
-
compatibilityDate: metadata.compatibility_date,
|
|
18134
|
-
compatibilityFlags: Array.isArray(metadata.compatibility_flags) ? metadata.compatibility_flags.filter(
|
|
18135
|
-
(flag) => typeof flag === "string"
|
|
18136
|
-
) : [],
|
|
18137
|
-
assetsBinding: typeof metadata.assets?.binding === "string" ? metadata.assets.binding : "ASSETS"
|
|
18138
|
-
};
|
|
18139
|
-
} catch (error51) {
|
|
18140
|
-
if (error51 instanceof DeploymentError) throw error51;
|
|
18141
|
-
throw new DeploymentError(
|
|
18142
|
-
"ARTIFACT_INVALID",
|
|
18143
|
-
"Could not read the Worker build output.",
|
|
18144
|
-
{ cause: error51 }
|
|
18145
|
-
);
|
|
18146
|
-
}
|
|
18147
|
-
}
|
|
18038
|
+
|
|
18039
|
+
// ../../packages/build/src/isr-cache-source.generated.ts
|
|
18040
|
+
var NARO_ISR_CACHE_SOURCE = '// Written by naro: vinext\'s data cache, shared across isolates and colos\n// through the dispatcher (spec 2026-11-06-isr-shared-cache \xA75).\n//\n// Layer 1 is this isolate\'s memory, with vinext\'s MemoryCacheHandler\n// semantics. Layer 2 is the store the dispatcher hands this request as\n// `ctx.props.NARO_CACHE` (an RPC stub, valid for this request only \u2014 never\n// kept). With no store (a build-time prerender, `vinext dev`, an older\n// dispatcher) this is a memory cache, as before.\n\nconst MEMORY_MAX_BYTES = 52_428_800;\nconst TAG_MEMO_TTL_MS = 5_000;\nconst TAG_MEMO_MAX = 10_000;\nconst ENTRY_MAX_CHARS = 2_097_152;\nconst ENTRY_MAX_TAGS = 256;\nconst TAG_MAX_CHARS = 1_024;\nconst TAG_LOOKUP_CHUNK = 256;\nconst SERIAL_VERSION = 1;\nconst WARN_INTERVAL_MS = 60_000;\nconst CONTEXT = Symbol.for("__cloudflare-context__");\n\n/** The store for the current request, or null. */\nexport function currentNaroCacheStore() {\n const context = globalThis[CONTEXT];\n return context?.ctx?.props?.NARO_CACHE ?? null;\n}\n\nfunction currentWaitUntil() {\n const ctx = globalThis[CONTEXT]?.ctx;\n return typeof ctx?.waitUntil === "function"\n ? (promise) => ctx.waitUntil(promise)\n : null;\n}\n\nconst isString = (value) => typeof value === "string";\n\nfunction unique(values) {\n return [...new Set(values)];\n}\n\nfunction readStringArray(ctx, field) {\n const value = ctx?.[field];\n return Array.isArray(value) ? value.filter(isString) : [];\n}\n\nfunction readPositiveNumber(ctx, field) {\n const value = ctx?.[field];\n return typeof value === "number" && value > 0 ? value : undefined;\n}\n\nfunction cacheControlOf(ctx) {\n const value = ctx?.cacheControl;\n return value !== null && typeof value === "object" ? value : undefined;\n}\n\nfunction readCacheControlNumber(ctx, field) {\n const value = cacheControlOf(ctx)?.[field] ?? ctx?.[field];\n return typeof value === "number" ? value : undefined;\n}\n\nfunction readCacheControlRevalidate(ctx) {\n const value = cacheControlOf(ctx)?.revalidate ?? ctx?.revalidate;\n return typeof value === "number" || value === false ? value : undefined;\n}\n\nfunction stringMapSize(map) {\n if (!map) return 0;\n let size = 0;\n for (const [key, value] of Object.entries(map)) {\n size += key.length;\n if (Array.isArray(value)) for (const item of value) size += item.length;\n else size += String(value).length;\n }\n return size;\n}\n\n/** vinext\'s estimate (shims/cache-handler.js), so the 50 MiB means the same. */\nfunction valueSize(value) {\n if (value === null || value === undefined) return 25;\n switch (value.kind) {\n case "FETCH":\n return JSON.stringify(value.data ?? "").length;\n case "PAGES":\n return (\n value.html.length +\n JSON.stringify(value.pageData ?? {}).length +\n stringMapSize(value.headers)\n );\n case "APP_PAGE":\n return (\n value.html.length +\n (value.rscData?.byteLength ?? 0) +\n (value.postponed?.length ?? 0) +\n stringMapSize(value.headers)\n );\n case "APP_ROUTE":\n return value.body.byteLength + stringMapSize(value.headers);\n case "REDIRECT":\n return JSON.stringify(value.props ?? {}).length;\n case "IMAGE":\n return (\n value.buffer.byteLength + value.extension.length + value.etag.length\n );\n default:\n return JSON.stringify(value).length;\n }\n}\n\nfunction entrySize(entry) {\n return (\n valueSize(entry.value) +\n entry.tags.reduce((sum, tag) => sum + tag.length, 0) +\n 64\n );\n}\n\nfunction toBase64(bytes) {\n let binary = "";\n for (let i = 0; i < bytes.length; i += 0x8000)\n binary += String.fromCharCode.apply(null, bytes.subarray(i, i + 0x8000));\n return btoa(binary);\n}\n\nfunction fromBase64(text) {\n const binary = atob(text);\n const bytes = new Uint8Array(binary.length);\n for (let i = 0; i < binary.length; i++) bytes[i] = binary.charCodeAt(i);\n return bytes;\n}\n\n/** One entry as the text layer 2 keeps. ArrayBuffers go as base64. */\nexport function serializeEntry(entry) {\n return JSON.stringify({ v: SERIAL_VERSION, ...entry }, (_key, value) => {\n if (value instanceof ArrayBuffer)\n return { __naroBytes: toBase64(new Uint8Array(value)) };\n if (ArrayBuffer.isView(value))\n return {\n __naroU8: toBase64(\n new Uint8Array(value.buffer, value.byteOffset, value.byteLength),\n ),\n };\n return value;\n });\n}\n\n/** The entry back, or null for another serial version. Throws on bad JSON. */\nexport function deserializeEntry(text) {\n const parsed = JSON.parse(text, (_key, value) => {\n if (value !== null && typeof value === "object") {\n if (isString(value.__naroBytes))\n return fromBase64(value.__naroBytes).buffer;\n if (isString(value.__naroU8)) return fromBase64(value.__naroU8);\n }\n return value;\n });\n if (\n parsed === null ||\n typeof parsed !== "object" ||\n parsed.v !== SERIAL_VERSION ||\n typeof parsed.lastModified !== "number" ||\n !Array.isArray(parsed.tags)\n )\n return null;\n return {\n value: parsed.value ?? null,\n tags: parsed.tags.filter(isString),\n lastModified: parsed.lastModified,\n revalidateAt:\n typeof parsed.revalidateAt === "number" ? parsed.revalidateAt : null,\n expireAt: typeof parsed.expireAt === "number" ? parsed.expireAt : null,\n cacheControl: parsed.cacheControl,\n };\n}\n\nfunction errorMessage(error) {\n return error instanceof Error && error.message\n ? error.message\n : String(error);\n}\n\nexport class NaroIsrCacheHandler {\n constructor({\n storeFor = currentNaroCacheStore,\n now = Date.now,\n waitUntilFor = currentWaitUntil,\n warn = (message) => console.warn(message),\n maxMemoryBytes = MEMORY_MAX_BYTES,\n tagMemoTtlMs = TAG_MEMO_TTL_MS,\n } = {}) {\n this.storeFor = storeFor;\n this.now = now;\n this.waitUntilFor = waitUntilFor;\n this.warn = warn;\n this.maxMemoryBytes = maxMemoryBytes;\n this.tagMemoTtlMs = tagMemoTtlMs;\n this.entries = new Map();\n this.memoryBytes = 0;\n this.tagMemo = new Map();\n this.lastWarnAt = -Infinity;\n }\n\n warnOnce(error) {\n const now = this.now();\n if (now - this.lastWarnAt < WARN_INTERVAL_MS) return;\n this.lastWarnAt = now;\n this.warn(`[naro-isr] shared cache unavailable: ${errorMessage(error)}`);\n }\n\n forget(key) {\n const existing = this.entries.get(key);\n if (!existing) return;\n this.memoryBytes -= existing.size;\n this.entries.delete(key);\n }\n\n remember(key, entry) {\n const size = entrySize(entry);\n this.forget(key);\n if (this.maxMemoryBytes <= 0 || size > this.maxMemoryBytes) return;\n this.entries.set(key, { ...entry, size });\n this.memoryBytes += size;\n while (this.memoryBytes > this.maxMemoryBytes) {\n const oldest = this.entries.keys().next().value;\n if (oldest === undefined) break;\n this.forget(oldest);\n }\n }\n\n setMemo(tag, time, fetchedAt) {\n this.tagMemo.delete(tag);\n this.tagMemo.set(tag, { time, fetchedAt });\n while (this.tagMemo.size > TAG_MEMO_MAX) {\n const oldest = this.tagMemo.keys().next().value;\n if (oldest === undefined) break;\n this.tagMemo.delete(oldest);\n }\n }\n\n /** Each tag\'s last revalidation as far as this isolate knows (ms, 0 = never). */\n async tagTimes(tags, store) {\n const now = this.now();\n const times = new Map();\n const missing = [];\n for (const tag of tags) {\n const memo = this.tagMemo.get(tag);\n // A tag over the cap never reaches layer 2 (set() does not write such\n // entries, the store ignores such tags): this isolate\'s own word only.\n if (\n memo &&\n (!store ||\n tag.length > TAG_MAX_CHARS ||\n now - memo.fetchedAt < this.tagMemoTtlMs)\n )\n times.set(tag, memo.time);\n else if (!store || tag.length > TAG_MAX_CHARS) times.set(tag, 0);\n else missing.push(tag);\n }\n if (missing.length === 0) return times;\n const chunks = [];\n for (let i = 0; i < missing.length; i += TAG_LOOKUP_CHUNK)\n chunks.push(missing.slice(i, i + TAG_LOOKUP_CHUNK));\n await Promise.all(\n chunks.map(async (chunk) => {\n let remote = null;\n try {\n remote = (await store.tagTimes(chunk)) ?? {};\n } catch (error) {\n this.warnOnce(error);\n }\n for (const tag of chunk) {\n const known = this.tagMemo.get(tag)?.time ?? 0;\n // A tag the store did not answer (failed read, or cut off by its\n // cap) keeps its old memo and fetch time, so the next get asks again.\n if (!remote || typeof remote[tag] !== "number") {\n times.set(tag, known);\n continue;\n }\n // Never forget a revalidation this isolate made: KV can answer an\n // older value for up to a minute after the write.\n const time = Math.max(known, remote[tag]);\n this.setMemo(tag, time, now);\n times.set(tag, time);\n }\n }),\n );\n return times;\n }\n\n /**\n * "valid", "own" (one of the entry\'s own tags was revalidated) or "soft"\n * (only a tag of the path asking was). vinext\'s MemoryCacheHandler evicts\n * only for an own tag: fetch entries are shared by several pages.\n */\n async validity(entry, softTags, store) {\n const tags = unique([...entry.tags, ...softTags]);\n if (tags.length === 0) return "valid";\n const times = await this.tagTimes(tags, store);\n const revalidated = (tag) => (times.get(tag) ?? 0) >= entry.lastModified;\n if (entry.tags.some(revalidated)) return "own";\n return softTags.some(revalidated) ? "soft" : "valid";\n }\n\n timing(entry, ctx) {\n const now = this.now();\n if (entry.expireAt !== null && now > entry.expireAt) return "expired";\n const requested = readPositiveNumber(ctx, "revalidate");\n const requestedAt =\n requested === undefined ? null : entry.lastModified + requested * 1000;\n if (\n (entry.revalidateAt !== null && now > entry.revalidateAt) ||\n (requestedAt !== null && now > requestedAt)\n )\n return "stale";\n return undefined;\n }\n\n answer(key, entry, cacheState) {\n // Most recently used goes last.\n const kept = this.entries.get(key);\n if (kept) {\n this.entries.delete(key);\n this.entries.set(key, kept);\n }\n return {\n lastModified: entry.lastModified,\n value: entry.value,\n ...(cacheState === undefined ? {} : { cacheState }),\n cacheControl: entry.cacheControl,\n };\n }\n\n async readRemote(store, key) {\n try {\n const found = await store.getEntry(key);\n if (!found || !isString(found.body)) return null;\n return deserializeEntry(found.body);\n } catch (error) {\n this.warnOnce(error);\n return null;\n }\n }\n\n async get(key, ctx) {\n const store = this.storeFor();\n const softTags = readStringArray(ctx, "softTags");\n const local = this.entries.get(key) ?? null;\n if (local) {\n const localValidity = await this.validity(local, softTags, store);\n if (localValidity === "valid") {\n const cacheState = this.timing(local, ctx);\n if (cacheState === undefined || !store)\n return this.answer(key, local, cacheState);\n // Stale here: another isolate may already have rendered a newer one.\n const remote = await this.readRemote(store, key);\n if (\n remote &&\n remote.lastModified > local.lastModified &&\n (await this.validity(remote, softTags, store)) === "valid"\n ) {\n this.remember(key, remote);\n return this.answer(key, remote, this.timing(remote, ctx));\n }\n return this.answer(key, local, cacheState);\n }\n // Only its own tags evict; a soft tag just makes this get a miss.\n if (localValidity === "own") this.forget(key);\n }\n if (!store) return null;\n const remote = await this.readRemote(store, key);\n if (!remote || (await this.validity(remote, softTags, store)) !== "valid")\n return null;\n this.remember(key, remote);\n return this.answer(key, remote, this.timing(remote, ctx));\n }\n\n async set(key, data, ctx) {\n const tags = unique([\n ...(data && Array.isArray(data.tags) ? data.tags.filter(isString) : []),\n ...readStringArray(ctx, "tags"),\n ]);\n let revalidate = readCacheControlRevalidate(ctx);\n const expire = readCacheControlNumber(ctx, "expire");\n const stale = readCacheControlNumber(ctx, "stale");\n if (data && typeof data.revalidate === "number")\n revalidate = data.revalidate;\n else if (data && data.revalidate === false) revalidate ??= false;\n if (revalidate === 0) return;\n const now = this.now();\n const entry = {\n value: data,\n tags,\n lastModified: now,\n revalidateAt:\n typeof revalidate === "number" && revalidate > 0\n ? now + revalidate * 1000\n : null,\n expireAt:\n typeof expire === "number" && expire > 0 ? now + expire * 1000 : null,\n cacheControl:\n typeof revalidate === "number" || revalidate === false\n ? {\n revalidate,\n ...(expire === undefined ? {} : { expire }),\n ...(stale === undefined ? {} : { stale }),\n }\n : undefined,\n };\n this.remember(key, entry);\n const store = this.storeFor();\n if (!store) return;\n if (\n tags.length > ENTRY_MAX_TAGS ||\n tags.some((tag) => tag.length > TAG_MAX_CHARS)\n )\n return;\n // The serialized text is never shorter than the size estimate (base64 is\n // 4/3 of the bytes, and the field names come on top), so an entry over the\n // limit by estimate is dropped without being serialized, which for a big\n // body would cost several times its size in memory.\n if (entrySize(entry) > ENTRY_MAX_CHARS) return;\n const body = serializeEntry(entry);\n if (body.length > ENTRY_MAX_CHARS) return;\n const write = Promise.resolve()\n .then(() => store.putEntry(key, body, { lastModified: now, tags }))\n .catch((error) => this.warnOnce(error));\n const waitUntil = this.waitUntilFor();\n if (waitUntil) waitUntil(write);\n else await write;\n }\n\n async revalidateTag(tags) {\n const list = unique((Array.isArray(tags) ? tags : [tags]).filter(isString));\n if (list.length === 0) return;\n const now = this.now();\n for (const tag of list)\n this.setMemo(tag, Math.max(this.tagMemo.get(tag)?.time ?? 0, now), now);\n const store = this.storeFor();\n if (!store) return;\n try {\n const recorded = await store.revalidateTags(list);\n if (typeof recorded === "number") {\n const fetchedAt = this.now();\n for (const tag of list)\n this.setMemo(\n tag,\n Math.max(this.tagMemo.get(tag)?.time ?? 0, recorded),\n fetchedAt,\n );\n }\n } catch (error) {\n this.warnOnce(error);\n }\n }\n\n resetRequestCache() {}\n}\n\n/** vinext calls this once per isolate with `{ env, options }`. */\nexport default function createNaroIsrCache({ options } = {}) {\n const ttl = options?.tagMemoTtlMs;\n return new NaroIsrCacheHandler(\n Number.isInteger(ttl) && ttl >= 0 && ttl <= 60_000\n ? { tagMemoTtlMs: ttl }\n : {},\n );\n}\n';
|
|
18148
18041
|
|
|
18149
18042
|
// ../../packages/build/src/platform-config.ts
|
|
18150
|
-
import {
|
|
18151
|
-
import { createRequire } from "module";
|
|
18043
|
+
import { writeFile as writeFile3 } from "fs/promises";
|
|
18152
18044
|
import { join as join5 } from "path";
|
|
18153
18045
|
var COMPATIBILITY_DATE = "2026-08-19";
|
|
18154
18046
|
var NEXT_CONFIG_FILES = [
|
|
@@ -18157,14 +18049,6 @@ var NEXT_CONFIG_FILES = [
|
|
|
18157
18049
|
"next.config.cjs",
|
|
18158
18050
|
"next.config.ts"
|
|
18159
18051
|
];
|
|
18160
|
-
async function pathExists(path) {
|
|
18161
|
-
try {
|
|
18162
|
-
await access4(path);
|
|
18163
|
-
return true;
|
|
18164
|
-
} catch {
|
|
18165
|
-
return false;
|
|
18166
|
-
}
|
|
18167
|
-
}
|
|
18168
18052
|
var BUILD_NPMRC = [
|
|
18169
18053
|
"# Host package-manager credentials are intentionally unavailable.",
|
|
18170
18054
|
"audit=false",
|
|
@@ -18179,61 +18063,40 @@ async function createPackageManagerConfig(appRoot, writer = async (path, content
|
|
|
18179
18063
|
await writer(packageManagerConfigPath, BUILD_NPMRC);
|
|
18180
18064
|
return packageManagerConfigPath;
|
|
18181
18065
|
}
|
|
18182
|
-
|
|
18183
|
-
|
|
18184
|
-
|
|
18185
|
-
"
|
|
18186
|
-
|
|
18187
|
-
|
|
18188
|
-
|
|
18189
|
-
|
|
18190
|
-
|
|
18191
|
-
|
|
18192
|
-
if (
|
|
18193
|
-
|
|
18194
|
-
|
|
18066
|
+
|
|
18067
|
+
// ../../packages/build/src/wrangler-output.ts
|
|
18068
|
+
function globToRegExp(glob) {
|
|
18069
|
+
let source = "";
|
|
18070
|
+
for (let index = 0; index < glob.length; index += 1) {
|
|
18071
|
+
const char = glob[index];
|
|
18072
|
+
if (char !== "*") {
|
|
18073
|
+
source += char?.replace(/[.+?^${}()|[\]\\]/g, String.raw`\$&`) ?? "";
|
|
18074
|
+
continue;
|
|
18075
|
+
}
|
|
18076
|
+
if (glob[index + 1] !== "*") {
|
|
18077
|
+
source += "[^/]*";
|
|
18078
|
+
continue;
|
|
18079
|
+
}
|
|
18080
|
+
if (glob[index + 2] === "/") {
|
|
18081
|
+
source += "(?:[^/]*/)*";
|
|
18082
|
+
index += 2;
|
|
18083
|
+
} else {
|
|
18084
|
+
source += ".*";
|
|
18085
|
+
index += 1;
|
|
18195
18086
|
}
|
|
18196
18087
|
}
|
|
18197
|
-
|
|
18198
|
-
|
|
18199
|
-
|
|
18200
|
-
|
|
18201
|
-
|
|
18202
|
-
|
|
18203
|
-
|
|
18204
|
-
|
|
18205
|
-
|
|
18206
|
-
|
|
18207
|
-
|
|
18208
|
-
|
|
18209
|
-
);
|
|
18210
|
-
await writer(
|
|
18211
|
-
wranglerConfigPath,
|
|
18212
|
-
`${JSON.stringify(
|
|
18213
|
-
{
|
|
18214
|
-
name: `next-deploy-${safeDeploymentId}`,
|
|
18215
|
-
main: ".open-next/worker.js",
|
|
18216
|
-
compatibility_date: COMPATIBILITY_DATE,
|
|
18217
|
-
compatibility_flags: ["nodejs_compat"],
|
|
18218
|
-
assets: {
|
|
18219
|
-
directory: ".open-next/assets",
|
|
18220
|
-
binding: "ASSETS"
|
|
18221
|
-
}
|
|
18222
|
-
},
|
|
18223
|
-
null,
|
|
18224
|
-
2
|
|
18225
|
-
)}
|
|
18226
|
-
`
|
|
18227
|
-
);
|
|
18228
|
-
const packageManagerConfigPath = await createPackageManagerConfig(
|
|
18229
|
-
appRoot,
|
|
18230
|
-
writer
|
|
18231
|
-
);
|
|
18232
|
-
return {
|
|
18233
|
-
openNextConfigPath,
|
|
18234
|
-
wranglerConfigPath,
|
|
18235
|
-
packageManagerConfigPath
|
|
18236
|
-
};
|
|
18088
|
+
return new RegExp(`^${source}$`);
|
|
18089
|
+
}
|
|
18090
|
+
function moduleRules(rules) {
|
|
18091
|
+
if (!Array.isArray(rules)) return [];
|
|
18092
|
+
return rules.flatMap((rule) => {
|
|
18093
|
+
const { type, globs } = rule;
|
|
18094
|
+
if (!Array.isArray(globs)) return [];
|
|
18095
|
+
return globs.filter((glob) => typeof glob === "string").map((glob) => ({
|
|
18096
|
+
type: typeof type === "string" ? type : "",
|
|
18097
|
+
test: globToRegExp(glob)
|
|
18098
|
+
}));
|
|
18099
|
+
});
|
|
18237
18100
|
}
|
|
18238
18101
|
|
|
18239
18102
|
// ../../packages/build/src/vinext.ts
|
|
@@ -18256,6 +18119,8 @@ var VITE_CONFIG_NAMES = [
|
|
|
18256
18119
|
];
|
|
18257
18120
|
var GENERATED_VITE_CONFIG = "vite.config.js";
|
|
18258
18121
|
var GENERATED_WORKER_ENTRY = "naro-worker.js";
|
|
18122
|
+
var GENERATED_ISR_CACHE = "naro-isr-cache.js";
|
|
18123
|
+
var ISR_SHARED_CACHE_OFF_NOTE = "ISR shared cache is off: the project builds with its own vite.config.";
|
|
18259
18124
|
var VINEXT_WORKER_ENTRY_SOURCE = `// Written by naro: vinext's Worker, with getCloudflareContext() given its env.
|
|
18260
18125
|
import { AsyncLocalStorage } from "node:async_hooks";
|
|
18261
18126
|
import handler from "vinext/server/fetch-handler";
|
|
@@ -18290,7 +18155,7 @@ function vinextWranglerConfigPath(appRoot) {
|
|
|
18290
18155
|
}
|
|
18291
18156
|
async function exists3(path) {
|
|
18292
18157
|
try {
|
|
18293
|
-
await
|
|
18158
|
+
await access3(path);
|
|
18294
18159
|
return true;
|
|
18295
18160
|
} catch {
|
|
18296
18161
|
return false;
|
|
@@ -18314,6 +18179,13 @@ async function createVinextBuildConfig(appRoot, deploymentId, writer = async (pa
|
|
|
18314
18179
|
`The project already has a ${GENERATED_WORKER_ENTRY}. Naro writes its vinext Worker entry under that name and will not overwrite a file of the project's.`
|
|
18315
18180
|
);
|
|
18316
18181
|
}
|
|
18182
|
+
const isrCachePath = join6(appRoot, GENERATED_ISR_CACHE);
|
|
18183
|
+
if (await exists3(isrCachePath)) {
|
|
18184
|
+
throw new DeploymentError(
|
|
18185
|
+
"ARTIFACT_INVALID",
|
|
18186
|
+
`The project already has a ${GENERATED_ISR_CACHE}. Naro writes its ISR cache handler under that name and will not overwrite a file of the project's.`
|
|
18187
|
+
);
|
|
18188
|
+
}
|
|
18317
18189
|
const safeDeploymentId = deploymentId.replace(/[^a-z0-9-]/gi, "-");
|
|
18318
18190
|
const viteConfigPath = join6(appRoot, GENERATED_VITE_CONFIG);
|
|
18319
18191
|
const wranglerConfigPath = join6(appRoot, "wrangler.jsonc");
|
|
@@ -18326,7 +18198,7 @@ async function createVinextBuildConfig(appRoot, deploymentId, writer = async (pa
|
|
|
18326
18198
|
"",
|
|
18327
18199
|
"export default defineConfig({",
|
|
18328
18200
|
" plugins: [",
|
|
18329
|
-
|
|
18201
|
+
` vinext({ cache: { data: { adapter: ${JSON.stringify(isrCachePath)} } } }),`,
|
|
18330
18202
|
' cloudflare({ viteEnvironment: { name: "rsc", childEnvironments: ["ssr"] } }),',
|
|
18331
18203
|
" ],",
|
|
18332
18204
|
"});",
|
|
@@ -18334,6 +18206,7 @@ async function createVinextBuildConfig(appRoot, deploymentId, writer = async (pa
|
|
|
18334
18206
|
].join("\n")
|
|
18335
18207
|
);
|
|
18336
18208
|
await writer(workerEntryPath, VINEXT_WORKER_ENTRY_SOURCE);
|
|
18209
|
+
await writer(isrCachePath, NARO_ISR_CACHE_SOURCE);
|
|
18337
18210
|
await writer(
|
|
18338
18211
|
wranglerConfigPath,
|
|
18339
18212
|
`${JSON.stringify(
|
|
@@ -18386,8 +18259,8 @@ function parseVinextCheckReport(output) {
|
|
|
18386
18259
|
function vinextRouteFromCheck(report) {
|
|
18387
18260
|
if (!report)
|
|
18388
18261
|
return {
|
|
18389
|
-
eligible:
|
|
18390
|
-
reason: "vinext check output could not be read;
|
|
18262
|
+
eligible: true,
|
|
18263
|
+
reason: "vinext check output could not be read; trying the build anyway. Expected if vinext changed its report format."
|
|
18391
18264
|
};
|
|
18392
18265
|
const autoFixed = report.issueLines.filter(
|
|
18393
18266
|
(line) => AUTO_FIXED_ISSUES.some((pattern) => pattern.test(line))
|
|
@@ -18399,7 +18272,7 @@ function vinextRouteFromCheck(report) {
|
|
|
18399
18272
|
if (blocking > 0)
|
|
18400
18273
|
return {
|
|
18401
18274
|
eligible: false,
|
|
18402
|
-
reason: `vinext check reported ${blocking} unsupported item(s) (${report.percent}% compatible)
|
|
18275
|
+
reason: `vinext check reported ${blocking} unsupported item(s) (${report.percent}% compatible).`
|
|
18403
18276
|
};
|
|
18404
18277
|
if (autoFixed.length > 0)
|
|
18405
18278
|
return {
|
|
@@ -18411,38 +18284,12 @@ function vinextRouteFromCheck(report) {
|
|
|
18411
18284
|
reason: report.partial > 0 ? `vinext check found no blocking issues (${report.partial} partially supported); attempting a vinext build.` : "vinext check found no issues; attempting a vinext build."
|
|
18412
18285
|
};
|
|
18413
18286
|
}
|
|
18414
|
-
function globToRegExp(glob) {
|
|
18415
|
-
let source = "";
|
|
18416
|
-
for (let index = 0; index < glob.length; index += 1) {
|
|
18417
|
-
const char = glob[index];
|
|
18418
|
-
if (char !== "*") {
|
|
18419
|
-
source += char?.replace(/[.+?^${}()|[\]\\]/g, String.raw`\$&`) ?? "";
|
|
18420
|
-
continue;
|
|
18421
|
-
}
|
|
18422
|
-
if (glob[index + 1] !== "*") {
|
|
18423
|
-
source += "[^/]*";
|
|
18424
|
-
continue;
|
|
18425
|
-
}
|
|
18426
|
-
if (glob[index + 2] === "/") {
|
|
18427
|
-
source += "(?:[^/]*/)*";
|
|
18428
|
-
index += 2;
|
|
18429
|
-
} else {
|
|
18430
|
-
source += ".*";
|
|
18431
|
-
index += 1;
|
|
18432
|
-
}
|
|
18433
|
-
}
|
|
18434
|
-
return new RegExp(`^${source}$`);
|
|
18435
|
-
}
|
|
18436
18287
|
function moduleMatchers(rules) {
|
|
18437
|
-
|
|
18438
|
-
return rules.flatMap((rule) => {
|
|
18439
|
-
const globs = rule.globs;
|
|
18440
|
-
return Array.isArray(globs) ? globs : [];
|
|
18441
|
-
}).filter((glob) => typeof glob === "string").map(globToRegExp);
|
|
18288
|
+
return moduleRules(rules).map((rule) => rule.test);
|
|
18442
18289
|
}
|
|
18443
18290
|
async function readVinextArtifact(appRoot, identity) {
|
|
18444
18291
|
try {
|
|
18445
|
-
const outputRoot =
|
|
18292
|
+
const outputRoot = resolve(appRoot, VINEXT_OUTPUT_DIR);
|
|
18446
18293
|
const serverRoot = join6(outputRoot, SERVER_DIR);
|
|
18447
18294
|
const clientRoot = join6(outputRoot, CLIENT_DIR);
|
|
18448
18295
|
const configPath = join6(serverRoot, WRANGLER_OUTPUT_NAME);
|
|
@@ -18503,7 +18350,7 @@ var FRAMEWORK_PRESETS = {
|
|
|
18503
18350
|
id: "next",
|
|
18504
18351
|
detectDependency: "next",
|
|
18505
18352
|
defaultBuildScript: "build",
|
|
18506
|
-
defaultOutputDirectory: "
|
|
18353
|
+
defaultOutputDirectory: "dist",
|
|
18507
18354
|
needsServerRuntime: true,
|
|
18508
18355
|
spaFallback: false,
|
|
18509
18356
|
cachePath: ".next/cache"
|
|
@@ -18841,9 +18688,85 @@ async function detectFramework(root, overrides = {}) {
|
|
|
18841
18688
|
};
|
|
18842
18689
|
}
|
|
18843
18690
|
|
|
18691
|
+
// ../../packages/build/src/naro-adapter-artifact.ts
|
|
18692
|
+
import { readFile as readFile7 } from "fs/promises";
|
|
18693
|
+
import { join as join8 } from "path";
|
|
18694
|
+
var RULE_CONTENT_TYPES = {
|
|
18695
|
+
ESModule: "application/javascript+module",
|
|
18696
|
+
CommonJS: "application/javascript",
|
|
18697
|
+
Text: "text/plain",
|
|
18698
|
+
Data: "application/octet-stream",
|
|
18699
|
+
CompiledWasm: "application/wasm"
|
|
18700
|
+
};
|
|
18701
|
+
var CONFIG_NAME = "wrangler.jsonc";
|
|
18702
|
+
async function readNaroAdapterArtifact(appRoot, identity) {
|
|
18703
|
+
try {
|
|
18704
|
+
const workerRoot = join8(appRoot, WORKER_DIR);
|
|
18705
|
+
let metadata;
|
|
18706
|
+
try {
|
|
18707
|
+
metadata = JSON.parse(
|
|
18708
|
+
await readFile7(join8(workerRoot, CONFIG_NAME), "utf8")
|
|
18709
|
+
);
|
|
18710
|
+
} catch (error51) {
|
|
18711
|
+
throw new DeploymentError(
|
|
18712
|
+
"ARTIFACT_INVALID",
|
|
18713
|
+
`The Naro adapter produced no ${WORKER_DIR}/${CONFIG_NAME}.`,
|
|
18714
|
+
{ cause: error51 }
|
|
18715
|
+
);
|
|
18716
|
+
}
|
|
18717
|
+
if (typeof metadata.main !== "string" || typeof metadata.compatibility_date !== "string")
|
|
18718
|
+
throw new DeploymentError(
|
|
18719
|
+
"ARTIFACT_INVALID",
|
|
18720
|
+
"Naro adapter wrangler output must declare main and compatibility_date."
|
|
18721
|
+
);
|
|
18722
|
+
const rules = moduleRules(metadata.rules);
|
|
18723
|
+
const files = await listArtifactFiles(workerRoot, "naro-adapter", appRoot);
|
|
18724
|
+
const entry = files.find((file2) => file2.name === metadata.main);
|
|
18725
|
+
if (!entry)
|
|
18726
|
+
throw new DeploymentError(
|
|
18727
|
+
"ARTIFACT_INVALID",
|
|
18728
|
+
`Naro adapter worker entrypoint "${metadata.main}" is missing from the build output.`
|
|
18729
|
+
);
|
|
18730
|
+
const modules = files.filter(
|
|
18731
|
+
(file2) => file2.name !== metadata.main && file2.name !== CONFIG_NAME && !file2.name.endsWith(".map")
|
|
18732
|
+
).map((file2) => {
|
|
18733
|
+
const rule = rules.find((candidate) => candidate.test.test(file2.name));
|
|
18734
|
+
const contentType2 = rule ? RULE_CONTENT_TYPES[rule.type] : void 0;
|
|
18735
|
+
if (!contentType2)
|
|
18736
|
+
throw new DeploymentError(
|
|
18737
|
+
"ARTIFACT_INVALID",
|
|
18738
|
+
`Naro adapter output file "${file2.name}" matches no module rule.`
|
|
18739
|
+
);
|
|
18740
|
+
return { ...file2, contentType: contentType2 };
|
|
18741
|
+
});
|
|
18742
|
+
return {
|
|
18743
|
+
...identity,
|
|
18744
|
+
entrypoint: { ...entry, contentType: "application/javascript+module" },
|
|
18745
|
+
modules,
|
|
18746
|
+
assets: await listArtifactFiles(
|
|
18747
|
+
join8(appRoot, ASSETS_DIR),
|
|
18748
|
+
"naro-adapter",
|
|
18749
|
+
appRoot
|
|
18750
|
+
),
|
|
18751
|
+
compatibilityDate: metadata.compatibility_date,
|
|
18752
|
+
compatibilityFlags: Array.isArray(metadata.compatibility_flags) ? metadata.compatibility_flags.filter(
|
|
18753
|
+
(flag) => typeof flag === "string"
|
|
18754
|
+
) : [],
|
|
18755
|
+
assetsBinding: typeof metadata.assets?.binding === "string" ? metadata.assets.binding : "ASSETS"
|
|
18756
|
+
};
|
|
18757
|
+
} catch (error51) {
|
|
18758
|
+
if (error51 instanceof DeploymentError) throw error51;
|
|
18759
|
+
throw new DeploymentError(
|
|
18760
|
+
"ARTIFACT_INVALID",
|
|
18761
|
+
"Could not read the Naro adapter output.",
|
|
18762
|
+
{ cause: error51 }
|
|
18763
|
+
);
|
|
18764
|
+
}
|
|
18765
|
+
}
|
|
18766
|
+
|
|
18844
18767
|
// ../../packages/build/src/next-routes.ts
|
|
18845
18768
|
import { readdir as readdir2, stat as stat2 } from "fs/promises";
|
|
18846
|
-
import { join as
|
|
18769
|
+
import { join as join9 } from "path";
|
|
18847
18770
|
var APP_PAGE_FILE = /^page\.(?:js|jsx|ts|tsx|md|mdx)$/;
|
|
18848
18771
|
var PAGES_ROUTER_FILE = /^(.+)\.(?:js|jsx|ts|tsx)$/;
|
|
18849
18772
|
var DECLARATION_FILE = /\.d\.ts$/;
|
|
@@ -18857,7 +18780,7 @@ function errorCode(error51) {
|
|
|
18857
18780
|
}
|
|
18858
18781
|
async function firstDirectory(root, candidates) {
|
|
18859
18782
|
for (const candidate of candidates) {
|
|
18860
|
-
const path =
|
|
18783
|
+
const path = join9(root, candidate);
|
|
18861
18784
|
try {
|
|
18862
18785
|
if ((await stat2(path)).isDirectory()) return path;
|
|
18863
18786
|
} catch (error51) {
|
|
@@ -18887,7 +18810,7 @@ async function readAppRouter(dir, segments, routes) {
|
|
|
18887
18810
|
const name = entry.name;
|
|
18888
18811
|
if (name.startsWith("_") || INTERCEPTING.test(name)) continue;
|
|
18889
18812
|
const next = ROUTE_GROUP.test(name) || name.startsWith("@") ? segments : [...segments, urlSegment(name, "app")];
|
|
18890
|
-
await readAppRouter(
|
|
18813
|
+
await readAppRouter(join9(dir, name), next, routes);
|
|
18891
18814
|
}
|
|
18892
18815
|
}
|
|
18893
18816
|
async function readPagesRouter(dir, segments, routes) {
|
|
@@ -18896,7 +18819,7 @@ async function readPagesRouter(dir, segments, routes) {
|
|
|
18896
18819
|
if (entry.isDirectory()) {
|
|
18897
18820
|
if (segments.length === 0 && entry.name === "api") continue;
|
|
18898
18821
|
await readPagesRouter(
|
|
18899
|
-
|
|
18822
|
+
join9(dir, entry.name),
|
|
18900
18823
|
[...segments, urlSegment(entry.name, "pages")],
|
|
18901
18824
|
routes
|
|
18902
18825
|
);
|
|
@@ -18914,8 +18837,8 @@ async function readPagesRouter(dir, segments, routes) {
|
|
|
18914
18837
|
}
|
|
18915
18838
|
}
|
|
18916
18839
|
async function listNextRoutes(appRoot) {
|
|
18917
|
-
const app = await firstDirectory(appRoot, ["app",
|
|
18918
|
-
const pages = await firstDirectory(appRoot, ["pages",
|
|
18840
|
+
const app = await firstDirectory(appRoot, ["app", join9("src", "app")]);
|
|
18841
|
+
const pages = await firstDirectory(appRoot, ["pages", join9("src", "pages")]);
|
|
18919
18842
|
if (!app && !pages) return null;
|
|
18920
18843
|
const routes = /* @__PURE__ */ new Set();
|
|
18921
18844
|
if (app) await readAppRouter(app, [], routes);
|
|
@@ -19152,14 +19075,14 @@ async function runCommand(spec, observer) {
|
|
|
19152
19075
|
|
|
19153
19076
|
// ../../packages/build/src/repository.ts
|
|
19154
19077
|
import { realpath as realpath2 } from "fs/promises";
|
|
19155
|
-
import { isAbsolute as isAbsolute2, relative as relative2, resolve as
|
|
19078
|
+
import { isAbsolute as isAbsolute2, relative as relative2, resolve as resolve2, sep as sep2 } from "path";
|
|
19156
19079
|
function resolveAppRoot(checkout, configuredRoot) {
|
|
19157
|
-
const checkoutRoot =
|
|
19080
|
+
const checkoutRoot = resolve2(checkout);
|
|
19158
19081
|
if (!configuredRoot) return checkoutRoot;
|
|
19159
19082
|
if (isAbsolute2(configuredRoot)) {
|
|
19160
19083
|
throw new Error("Configured root directory escapes repository");
|
|
19161
19084
|
}
|
|
19162
|
-
const appRoot =
|
|
19085
|
+
const appRoot = resolve2(checkoutRoot, configuredRoot);
|
|
19163
19086
|
const relativeRoot = relative2(checkoutRoot, appRoot);
|
|
19164
19087
|
if (relativeRoot === ".." || relativeRoot.startsWith(`..${process.platform === "win32" ? "\\" : "/"}`) || isAbsolute2(relativeRoot)) {
|
|
19165
19088
|
throw new Error("Configured root directory escapes repository");
|
|
@@ -19190,8 +19113,8 @@ async function assertAppRootInsideCheckout(checkout, appRoot) {
|
|
|
19190
19113
|
}
|
|
19191
19114
|
|
|
19192
19115
|
// ../../packages/build/src/static-artifact.ts
|
|
19193
|
-
import { readdir as readdir3, readFile as
|
|
19194
|
-
import { isAbsolute as isAbsolute3, join as
|
|
19116
|
+
import { readdir as readdir3, readFile as readFile8 } from "fs/promises";
|
|
19117
|
+
import { isAbsolute as isAbsolute3, join as join10, relative as relative3, resolve as resolve3, sep as sep3 } from "path";
|
|
19195
19118
|
var SHIM_WORKER_SOURCE = "export default { fetch: (request, env) => env.ASSETS.fetch(request) };\n";
|
|
19196
19119
|
var EXCLUDED_DIRECTORIES = /* @__PURE__ */ new Set(["node_modules"]);
|
|
19197
19120
|
var ALLOWED_DOTFILE = ".well-known";
|
|
@@ -19205,7 +19128,7 @@ async function readStaticArtifact(appRoot, outputDirectory, identity, options, o
|
|
|
19205
19128
|
"ARTIFACT_INVALID",
|
|
19206
19129
|
"Output directory must be relative to the application root."
|
|
19207
19130
|
);
|
|
19208
|
-
const outputRoot =
|
|
19131
|
+
const outputRoot = resolve3(appRoot, outputDirectory);
|
|
19209
19132
|
const relation = relative3(appRoot, outputRoot);
|
|
19210
19133
|
if (relation === ".." || relation.startsWith(`..${sep3}`) || isAbsolute3(relation))
|
|
19211
19134
|
throw new DeploymentError(
|
|
@@ -19224,7 +19147,7 @@ async function readStaticArtifact(appRoot, outputDirectory, identity, options, o
|
|
|
19224
19147
|
(left, right) => left.name.localeCompare(right.name)
|
|
19225
19148
|
)) {
|
|
19226
19149
|
if (excluded(entry.name)) continue;
|
|
19227
|
-
const path =
|
|
19150
|
+
const path = join10(directory, entry.name);
|
|
19228
19151
|
if (entry.isSymbolicLink())
|
|
19229
19152
|
throw new DeploymentError(
|
|
19230
19153
|
"ARTIFACT_INVALID",
|
|
@@ -19234,7 +19157,7 @@ async function readStaticArtifact(appRoot, outputDirectory, identity, options, o
|
|
|
19234
19157
|
else if (entry.isFile()) {
|
|
19235
19158
|
assets.push({
|
|
19236
19159
|
name: relative3(outputRoot, path).split(sep3).join("/"),
|
|
19237
|
-
data: await
|
|
19160
|
+
data: await readFile8(path),
|
|
19238
19161
|
contentType: contentType(path)
|
|
19239
19162
|
});
|
|
19240
19163
|
}
|
|
@@ -19280,8 +19203,8 @@ async function readStaticArtifact(appRoot, outputDirectory, identity, options, o
|
|
|
19280
19203
|
|
|
19281
19204
|
// ../../packages/build/src/strategy/fingerprint.ts
|
|
19282
19205
|
import { createHash as createHash3 } from "crypto";
|
|
19283
|
-
import { readFile as
|
|
19284
|
-
import { join as
|
|
19206
|
+
import { readFile as readFile9 } from "fs/promises";
|
|
19207
|
+
import { join as join11, relative as relative4, sep as sep4 } from "path";
|
|
19285
19208
|
var APP_ROOT_FILES = [
|
|
19286
19209
|
"package.json",
|
|
19287
19210
|
"next.config.js",
|
|
@@ -19318,18 +19241,18 @@ function sha256(data) {
|
|
|
19318
19241
|
}
|
|
19319
19242
|
async function hashFile(path) {
|
|
19320
19243
|
try {
|
|
19321
|
-
return sha256(await
|
|
19244
|
+
return sha256(await readFile9(path));
|
|
19322
19245
|
} catch {
|
|
19323
19246
|
return null;
|
|
19324
19247
|
}
|
|
19325
19248
|
}
|
|
19326
19249
|
async function hashStrategyInputs(checkout, appRoot) {
|
|
19327
19250
|
const candidates = /* @__PURE__ */ new Set();
|
|
19328
|
-
for (const name of CHECKOUT_FILES) candidates.add(
|
|
19329
|
-
for (const name of APP_ROOT_FILES) candidates.add(
|
|
19251
|
+
for (const name of CHECKOUT_FILES) candidates.add(join11(checkout, name));
|
|
19252
|
+
for (const name of APP_ROOT_FILES) candidates.add(join11(appRoot, name));
|
|
19330
19253
|
for (const base2 of SOURCE_FILES) {
|
|
19331
19254
|
for (const ext of SOURCE_EXTENSIONS) {
|
|
19332
|
-
candidates.add(
|
|
19255
|
+
candidates.add(join11(appRoot, `${base2}.${ext}`));
|
|
19333
19256
|
}
|
|
19334
19257
|
}
|
|
19335
19258
|
const entries = [];
|
|
@@ -19357,12 +19280,12 @@ async function computeStrategyFingerprint(input) {
|
|
|
19357
19280
|
}
|
|
19358
19281
|
|
|
19359
19282
|
// ../../packages/build/src/strategy/project-facts.ts
|
|
19360
|
-
import { access as
|
|
19361
|
-
import { join as
|
|
19283
|
+
import { access as access4, readFile as readFile11 } from "fs/promises";
|
|
19284
|
+
import { join as join13 } from "path";
|
|
19362
19285
|
|
|
19363
19286
|
// ../../packages/build/src/strategy/user-adapter.ts
|
|
19364
|
-
import { readFile as
|
|
19365
|
-
import { join as
|
|
19287
|
+
import { readFile as readFile10 } from "fs/promises";
|
|
19288
|
+
import { join as join12 } from "path";
|
|
19366
19289
|
var ADAPTER_PATH = /\badapterPath\b/;
|
|
19367
19290
|
var EXPERIMENTAL_ADAPTER_PATH = /\bexperimental\s*:\s*\{[^{}]*\badapterPath\b/;
|
|
19368
19291
|
function adapterKeyFromConfigSource(source) {
|
|
@@ -19394,8 +19317,8 @@ async function adapterInBuildOutput(appRoot, nextVersion) {
|
|
|
19394
19317
|
let manifest2;
|
|
19395
19318
|
try {
|
|
19396
19319
|
const parsed = JSON.parse(
|
|
19397
|
-
await
|
|
19398
|
-
|
|
19320
|
+
await readFile10(
|
|
19321
|
+
join12(appRoot, ".next", "required-server-files.json"),
|
|
19399
19322
|
"utf8"
|
|
19400
19323
|
)
|
|
19401
19324
|
);
|
|
@@ -19406,10 +19329,14 @@ async function adapterInBuildOutput(appRoot, nextVersion) {
|
|
|
19406
19329
|
}
|
|
19407
19330
|
const topLevel = manifest2.config?.adapterPath;
|
|
19408
19331
|
if (keys.includes("adapterPath") && typeof topLevel === "string" && topLevel)
|
|
19409
|
-
return { source: "build-output", key: "adapterPath" };
|
|
19332
|
+
return { source: "build-output", key: "adapterPath", path: topLevel };
|
|
19410
19333
|
const experimental = manifest2.config?.experimental?.adapterPath;
|
|
19411
19334
|
if (keys.includes("experimental.adapterPath") && typeof experimental === "string" && experimental)
|
|
19412
|
-
return {
|
|
19335
|
+
return {
|
|
19336
|
+
source: "build-output",
|
|
19337
|
+
key: "experimental.adapterPath",
|
|
19338
|
+
path: experimental
|
|
19339
|
+
};
|
|
19413
19340
|
return null;
|
|
19414
19341
|
}
|
|
19415
19342
|
function describeUserAdapter(adapter) {
|
|
@@ -19422,9 +19349,6 @@ function describeUserAdapter(adapter) {
|
|
|
19422
19349
|
return `${adapter.key} in the Next.js build output`;
|
|
19423
19350
|
}
|
|
19424
19351
|
}
|
|
19425
|
-
function openNextAdapterWarning(adapter) {
|
|
19426
|
-
return `P2 opennext-cloudflare: The project sets its own Next.js adapter (${describeUserAdapter(adapter)}); its modifyConfig and onBuildComplete also run in the OpenNext build.`;
|
|
19427
|
-
}
|
|
19428
19352
|
|
|
19429
19353
|
// ../../packages/build/src/strategy/project-facts.ts
|
|
19430
19354
|
var SOURCE_EXTENSIONS2 = ["ts", "tsx", "js", "jsx", "mjs", "mts"];
|
|
@@ -19437,17 +19361,17 @@ var VITE_CONFIGS = [
|
|
|
19437
19361
|
];
|
|
19438
19362
|
async function exists4(path) {
|
|
19439
19363
|
try {
|
|
19440
|
-
await
|
|
19364
|
+
await access4(path);
|
|
19441
19365
|
return true;
|
|
19442
19366
|
} catch {
|
|
19443
19367
|
return false;
|
|
19444
19368
|
}
|
|
19445
19369
|
}
|
|
19446
|
-
async function findSourceFile(appRoot,
|
|
19370
|
+
async function findSourceFile(appRoot, basename5) {
|
|
19447
19371
|
for (const dir of SOURCE_DIRECTORIES) {
|
|
19448
19372
|
for (const ext of SOURCE_EXTENSIONS2) {
|
|
19449
|
-
const rel = dir ? `${dir}/${
|
|
19450
|
-
if (await exists4(
|
|
19373
|
+
const rel = dir ? `${dir}/${basename5}.${ext}` : `${basename5}.${ext}`;
|
|
19374
|
+
if (await exists4(join13(appRoot, rel))) return rel;
|
|
19451
19375
|
}
|
|
19452
19376
|
}
|
|
19453
19377
|
return null;
|
|
@@ -19467,14 +19391,15 @@ function matcherRoutesFromSource(source) {
|
|
|
19467
19391
|
}
|
|
19468
19392
|
async function readIfExists(path) {
|
|
19469
19393
|
try {
|
|
19470
|
-
return await
|
|
19394
|
+
return await readFile11(path, "utf8");
|
|
19471
19395
|
} catch {
|
|
19472
19396
|
return null;
|
|
19473
19397
|
}
|
|
19474
19398
|
}
|
|
19475
19399
|
async function findAdapterConfig(appRoot) {
|
|
19476
19400
|
for (const file2 of NEXT_CONFIG_FILES) {
|
|
19477
|
-
|
|
19401
|
+
if (file2 === "next.config.cjs") continue;
|
|
19402
|
+
const source = await readIfExists(join13(appRoot, file2));
|
|
19478
19403
|
if (source === null) continue;
|
|
19479
19404
|
const key = adapterKeyFromConfigSource(source);
|
|
19480
19405
|
return key ? { file: file2, key } : null;
|
|
@@ -19485,10 +19410,10 @@ async function collectProjectFacts(appRoot) {
|
|
|
19485
19410
|
const proxyFile = await findSourceFile(appRoot, "proxy");
|
|
19486
19411
|
const middlewareFile = await findSourceFile(appRoot, "middleware");
|
|
19487
19412
|
const routeSourceFile = middlewareFile ?? proxyFile;
|
|
19488
|
-
const routeSource = routeSourceFile ? await readIfExists(
|
|
19413
|
+
const routeSource = routeSourceFile ? await readIfExists(join13(appRoot, routeSourceFile)) : null;
|
|
19489
19414
|
let usesVinext = false;
|
|
19490
19415
|
let nextSpec = null;
|
|
19491
|
-
const packageJsonSource = await readIfExists(
|
|
19416
|
+
const packageJsonSource = await readIfExists(join13(appRoot, "package.json"));
|
|
19492
19417
|
if (packageJsonSource) {
|
|
19493
19418
|
try {
|
|
19494
19419
|
const packageJson = JSON.parse(packageJsonSource);
|
|
@@ -19499,7 +19424,7 @@ async function collectProjectFacts(appRoot) {
|
|
|
19499
19424
|
nextSpec = dependency("next");
|
|
19500
19425
|
if (dependency("vinext") !== null) {
|
|
19501
19426
|
for (const name of VITE_CONFIGS) {
|
|
19502
|
-
const config2 = await readIfExists(
|
|
19427
|
+
const config2 = await readIfExists(join13(appRoot, name));
|
|
19503
19428
|
if (config2 && /\bvinext\s*\(/.test(config2) && /@cloudflare\/vite-plugin/.test(config2)) {
|
|
19504
19429
|
usesVinext = true;
|
|
19505
19430
|
break;
|
|
@@ -19768,7 +19693,8 @@ async function fetchStatus(fetchImpl, url2, timeoutMs) {
|
|
|
19768
19693
|
clearTimeout(timer);
|
|
19769
19694
|
}
|
|
19770
19695
|
}
|
|
19771
|
-
function probeOk(status) {
|
|
19696
|
+
function probeOk(status, expect) {
|
|
19697
|
+
if (expect === "found" && status === 404) return false;
|
|
19772
19698
|
return status < 500;
|
|
19773
19699
|
}
|
|
19774
19700
|
function createSmokeTester(options = {}) {
|
|
@@ -19855,7 +19781,11 @@ function createSmokeTester(options = {}) {
|
|
|
19855
19781
|
`${origin}${probe.path}`,
|
|
19856
19782
|
probeTimeoutMs
|
|
19857
19783
|
);
|
|
19858
|
-
const result = "status" in answer ? {
|
|
19784
|
+
const result = "status" in answer ? {
|
|
19785
|
+
...probe,
|
|
19786
|
+
status: answer.status,
|
|
19787
|
+
ok: probeOk(answer.status, probe.expect)
|
|
19788
|
+
} : { ...probe, status: null, ok: false, detail: answer.error };
|
|
19859
19789
|
probes2.push(result);
|
|
19860
19790
|
await observer.onLog({
|
|
19861
19791
|
level: result.ok ? "INFO" : "ERROR",
|
|
@@ -19900,13 +19830,40 @@ function defaultSmokeProbes(matcherRoutes) {
|
|
|
19900
19830
|
return probes2;
|
|
19901
19831
|
}
|
|
19902
19832
|
|
|
19903
|
-
// ../../packages/build/src/strategy/strategies/
|
|
19904
|
-
|
|
19905
|
-
|
|
19833
|
+
// ../../packages/build/src/strategy/strategies/unavailable.ts
|
|
19834
|
+
function createUnavailableStrategy(options) {
|
|
19835
|
+
return {
|
|
19836
|
+
id: options.id,
|
|
19837
|
+
priority: options.priority,
|
|
19838
|
+
target: options.target,
|
|
19839
|
+
supports: () => ({ supported: false, reason: options.reason }),
|
|
19840
|
+
evaluate: async () => ({ status: "skipped", reason: options.reason })
|
|
19841
|
+
};
|
|
19842
|
+
}
|
|
19843
|
+
function createSplitCloudflareStrategy() {
|
|
19844
|
+
return createUnavailableStrategy({
|
|
19845
|
+
id: "split-cloudflare",
|
|
19846
|
+
priority: 3,
|
|
19847
|
+
target: "cloudflare-split",
|
|
19848
|
+
reason: "Split Cloudflare deployment needs the dispatcher to chain a middleware Worker in front of the app Worker; the runtime plane routes one Worker per hostname today."
|
|
19849
|
+
});
|
|
19850
|
+
}
|
|
19851
|
+
function createAwsMiddlewareCloudflareAppStrategy() {
|
|
19852
|
+
return createUnavailableStrategy({
|
|
19853
|
+
id: "aws-middleware-cloudflare-app",
|
|
19854
|
+
priority: 4,
|
|
19855
|
+
target: "aws-hybrid",
|
|
19856
|
+
reason: "Hybrid AWS middleware + Cloudflare app needs an AWS deploy target and cross-cloud request chaining; neither exists on this control plane."
|
|
19857
|
+
});
|
|
19858
|
+
}
|
|
19859
|
+
|
|
19860
|
+
// ../../packages/build/src/strategy/strategies/naro-adapter-cloudflare.ts
|
|
19861
|
+
import { readFile as readFile13, rm as rm2 } from "fs/promises";
|
|
19862
|
+
import { join as join15, resolve as resolve5 } from "path";
|
|
19906
19863
|
|
|
19907
19864
|
// ../../packages/build/src/strategy/strategies/shared.ts
|
|
19908
|
-
import { access as
|
|
19909
|
-
import { dirname
|
|
19865
|
+
import { access as access5, readFile as readFile12, rm, writeFile as writeFile5 } from "fs/promises";
|
|
19866
|
+
import { dirname, join as join14, resolve as resolve4 } from "path";
|
|
19910
19867
|
function capturingObserver(observer) {
|
|
19911
19868
|
const lines = [];
|
|
19912
19869
|
return {
|
|
@@ -19942,31 +19899,28 @@ function describeFailure(step) {
|
|
|
19942
19899
|
function failed(stage, reason) {
|
|
19943
19900
|
return { status: "failed", stage, reason };
|
|
19944
19901
|
}
|
|
19945
|
-
function appBuildFailed(reason) {
|
|
19946
|
-
return { status: "failed", stage: "build", reason, appBuild: true };
|
|
19947
|
-
}
|
|
19948
19902
|
async function info(observer, message) {
|
|
19949
19903
|
await observer.onLog({ level: "INFO", stage: "BUILDING", message });
|
|
19950
19904
|
}
|
|
19951
19905
|
async function warn(observer, message) {
|
|
19952
19906
|
await observer.onLog({ level: "WARN", stage: "BUILDING", message });
|
|
19953
19907
|
}
|
|
19954
|
-
async function
|
|
19908
|
+
async function pathExists(path) {
|
|
19955
19909
|
try {
|
|
19956
|
-
await
|
|
19910
|
+
await access5(path);
|
|
19957
19911
|
return true;
|
|
19958
19912
|
} catch {
|
|
19959
19913
|
return false;
|
|
19960
19914
|
}
|
|
19961
19915
|
}
|
|
19962
19916
|
async function findProjectBin(appRoot, checkout, name) {
|
|
19963
|
-
let dir =
|
|
19964
|
-
const stop =
|
|
19917
|
+
let dir = resolve4(appRoot);
|
|
19918
|
+
const stop = resolve4(checkout);
|
|
19965
19919
|
for (; ; ) {
|
|
19966
|
-
const candidate =
|
|
19967
|
-
if (await
|
|
19920
|
+
const candidate = join14(dir, "node_modules", ".bin", name);
|
|
19921
|
+
if (await pathExists(candidate)) return candidate;
|
|
19968
19922
|
if (dir === stop) return null;
|
|
19969
|
-
const parent =
|
|
19923
|
+
const parent = dirname(dir);
|
|
19970
19924
|
if (parent === dir) return null;
|
|
19971
19925
|
dir = parent;
|
|
19972
19926
|
}
|
|
@@ -19977,7 +19931,7 @@ function dotenvQuote(value) {
|
|
|
19977
19931
|
return `"${value.replace(/"/g, '\\"').replace(/\n/g, "\\n").replace(/\r/g, "\\r")}"`;
|
|
19978
19932
|
}
|
|
19979
19933
|
async function withDevVars(wranglerConfigPath, env, run) {
|
|
19980
|
-
const path =
|
|
19934
|
+
const path = join14(dirname(wranglerConfigPath), ".dev.vars");
|
|
19981
19935
|
const keys = Object.keys(env).filter(
|
|
19982
19936
|
(key) => /^[A-Za-z_][A-Za-z0-9_]*$/.test(key)
|
|
19983
19937
|
);
|
|
@@ -19994,36 +19948,7 @@ async function withDevVars(wranglerConfigPath, env, run) {
|
|
|
19994
19948
|
await rm(path, { force: true });
|
|
19995
19949
|
}
|
|
19996
19950
|
}
|
|
19997
|
-
async function
|
|
19998
|
-
return runStep(
|
|
19999
|
-
context,
|
|
20000
|
-
{
|
|
20001
|
-
command: context.toolchain.wrangler,
|
|
20002
|
-
args: [
|
|
20003
|
-
"deploy",
|
|
20004
|
-
"--dry-run",
|
|
20005
|
-
"--config",
|
|
20006
|
-
layout.wranglerConfigPath,
|
|
20007
|
-
"--outdir",
|
|
20008
|
-
layout.bundleDir
|
|
20009
|
-
],
|
|
20010
|
-
cwd: layout.appRoot,
|
|
20011
|
-
env: {
|
|
20012
|
-
CI: "1",
|
|
20013
|
-
WRANGLER_LOG_PATH: join13(
|
|
20014
|
-
layout.appRoot,
|
|
20015
|
-
layout.outputRoot,
|
|
20016
|
-
"wrangler.log"
|
|
20017
|
-
)
|
|
20018
|
-
},
|
|
20019
|
-
timeoutMs: 5 * 6e4,
|
|
20020
|
-
stage: "BUILDING",
|
|
20021
|
-
errorCode: errorCode2
|
|
20022
|
-
},
|
|
20023
|
-
observer
|
|
20024
|
-
);
|
|
20025
|
-
}
|
|
20026
|
-
async function smokeWorker(context, layout, observer) {
|
|
19951
|
+
async function smokeWorker(context, layout, observer, extraProbes = []) {
|
|
20027
19952
|
return withDevVars(
|
|
20028
19953
|
layout.wranglerConfigPath,
|
|
20029
19954
|
context.env,
|
|
@@ -20043,19 +19968,22 @@ async function smokeWorker(context, layout, observer) {
|
|
|
20043
19968
|
"--show-interactive-dev-session=false",
|
|
20044
19969
|
"--log-level=warn",
|
|
20045
19970
|
"--persist-to",
|
|
20046
|
-
|
|
19971
|
+
join14(layout.appRoot, layout.outputRoot, ".naro-smoke-state")
|
|
20047
19972
|
],
|
|
20048
19973
|
cwd: layout.appRoot,
|
|
20049
19974
|
env: {
|
|
20050
19975
|
CI: "1",
|
|
20051
|
-
WRANGLER_LOG_PATH:
|
|
19976
|
+
WRANGLER_LOG_PATH: join14(
|
|
20052
19977
|
layout.appRoot,
|
|
20053
19978
|
layout.outputRoot,
|
|
20054
19979
|
"wrangler-dev.log"
|
|
20055
19980
|
)
|
|
20056
19981
|
}
|
|
20057
19982
|
}),
|
|
20058
|
-
probes:
|
|
19983
|
+
probes: [
|
|
19984
|
+
...defaultSmokeProbes(context.facts.matcherRoutes),
|
|
19985
|
+
...extraProbes
|
|
19986
|
+
],
|
|
20059
19987
|
stage: "BUILDING",
|
|
20060
19988
|
errorCode: "BUILD_FAILED"
|
|
20061
19989
|
},
|
|
@@ -20064,10 +19992,10 @@ async function smokeWorker(context, layout, observer) {
|
|
|
20064
19992
|
);
|
|
20065
19993
|
}
|
|
20066
19994
|
async function approvePnpmBuilds(checkout, packages) {
|
|
20067
|
-
const path =
|
|
19995
|
+
const path = join14(checkout, "pnpm-workspace.yaml");
|
|
20068
19996
|
let source = "";
|
|
20069
19997
|
try {
|
|
20070
|
-
source = await
|
|
19998
|
+
source = await readFile12(path, "utf8");
|
|
20071
19999
|
} catch {
|
|
20072
20000
|
}
|
|
20073
20001
|
let next = source;
|
|
@@ -20114,412 +20042,191 @@ ${listEntries}
|
|
|
20114
20042
|
}
|
|
20115
20043
|
}
|
|
20116
20044
|
|
|
20117
|
-
// ../../packages/build/src/strategy/strategies/
|
|
20118
|
-
var
|
|
20119
|
-
|
|
20120
|
-
|
|
20121
|
-
|
|
20122
|
-
|
|
20123
|
-
|
|
20124
|
-
|
|
20125
|
-
|
|
20126
|
-
|
|
20127
|
-
|
|
20128
|
-
|
|
20129
|
-
|
|
20130
|
-
|
|
20131
|
-
|
|
20132
|
-
|
|
20045
|
+
// ../../packages/build/src/strategy/strategies/naro-adapter-cloudflare.ts
|
|
20046
|
+
var NARO_ADAPTER_REASONS = {
|
|
20047
|
+
notInstalled: "The Naro adapter is not installed in this build environment.",
|
|
20048
|
+
unknownVersion: "The installed Next.js version could not be read; the Naro adapter needs Next.js 16.2 or newer.",
|
|
20049
|
+
missingOutput: "next build finished without the Naro adapter's output; another Next.js adapter may have run instead.",
|
|
20050
|
+
userAdapterRan: (key) => `next build ran the project's own Next.js adapter (${key} in the Next.js build output) instead of the Naro adapter. Naro replaces an adapter only when next.config sets adapterPath itself; this one is set somewhere Naro does not read before the build, such as an imported file.`
|
|
20051
|
+
};
|
|
20052
|
+
var REPLACE_TAIL = "Your repository is unchanged, and your adapter's modifyConfig and onBuildComplete do not run. To keep your adapter (vinext only), change the project's Next.js adapter setting.";
|
|
20053
|
+
function replaceWarning(adapter) {
|
|
20054
|
+
return adapter.source === "next-config" ? `${adapter.file} sets its own Next.js adapter (${adapter.key}); this build replaces it with the Naro adapter in a temporary copy. ${REPLACE_TAIL}` : `NEXT_ADAPTER_PATH sets its own Next.js adapter; this build replaces it with the Naro adapter. ${REPLACE_TAIL}`;
|
|
20055
|
+
}
|
|
20056
|
+
async function readRecord(appRoot) {
|
|
20057
|
+
try {
|
|
20058
|
+
const parsed = JSON.parse(
|
|
20059
|
+
await readFile13(join15(appRoot, BUILD_RECORD), "utf8")
|
|
20060
|
+
);
|
|
20061
|
+
if (typeof parsed.buildId !== "string" || typeof parsed.distDir !== "string")
|
|
20062
|
+
return null;
|
|
20063
|
+
const staticFiles = Array.isArray(parsed.outputs?.staticFiles) ? parsed.outputs.staticFiles : [];
|
|
20064
|
+
return {
|
|
20065
|
+
buildId: parsed.buildId,
|
|
20066
|
+
distDir: parsed.distDir,
|
|
20067
|
+
basePath: typeof parsed.config?.basePath === "string" ? parsed.config.basePath : "",
|
|
20068
|
+
staticPathnames: staticFiles.flatMap((file2) => {
|
|
20069
|
+
const pathname = file2?.pathname;
|
|
20070
|
+
return typeof pathname === "string" ? [pathname] : [];
|
|
20071
|
+
})
|
|
20072
|
+
};
|
|
20073
|
+
} catch {
|
|
20074
|
+
return null;
|
|
20075
|
+
}
|
|
20076
|
+
}
|
|
20077
|
+
function naroAdapterSmokeProbes(record3, assetNames) {
|
|
20078
|
+
const { basePath } = record3;
|
|
20079
|
+
const probes2 = [];
|
|
20080
|
+
const assetPrefix = `${basePath}/_next/static/`;
|
|
20081
|
+
const script = assetNames.find(
|
|
20082
|
+
(name) => `/${name}`.startsWith(assetPrefix) && name.endsWith(".js")
|
|
20083
|
+
);
|
|
20084
|
+
if (script)
|
|
20085
|
+
probes2.push({ path: `/${script}`, label: "static asset", expect: "found" });
|
|
20086
|
+
const notPages = new Set(
|
|
20087
|
+
["/404", "/500", "/index"].map((path) => `${basePath}${path}`)
|
|
20088
|
+
);
|
|
20089
|
+
const page2 = record3.staticPathnames.find(
|
|
20090
|
+
(pathname) => !pathname.startsWith(assetPrefix) && !pathname.endsWith(".rsc") && !notPages.has(pathname)
|
|
20091
|
+
);
|
|
20092
|
+
if (page2) probes2.push({ path: page2, label: "static page", expect: "found" });
|
|
20093
|
+
return probes2;
|
|
20133
20094
|
}
|
|
20134
|
-
function
|
|
20095
|
+
async function readBuildId(distDir) {
|
|
20096
|
+
try {
|
|
20097
|
+
return (await readFile13(join15(distDir, "BUILD_ID"), "utf8")).trim();
|
|
20098
|
+
} catch {
|
|
20099
|
+
return null;
|
|
20100
|
+
}
|
|
20101
|
+
}
|
|
20102
|
+
function createNaroAdapterCloudflareStrategy(options) {
|
|
20135
20103
|
return {
|
|
20136
|
-
id: "
|
|
20137
|
-
priority:
|
|
20138
|
-
target: "
|
|
20104
|
+
id: "naro-adapter-cloudflare",
|
|
20105
|
+
priority: 2,
|
|
20106
|
+
target: "cloudflare",
|
|
20139
20107
|
supports(context) {
|
|
20140
|
-
if (!context.
|
|
20108
|
+
if (!context.toolchain.nextAdapter)
|
|
20109
|
+
return { supported: false, reason: NARO_ADAPTER_REASONS.notInstalled };
|
|
20110
|
+
const verdict = judgeNextVersion(context.nextVersion);
|
|
20111
|
+
if (!verdict)
|
|
20112
|
+
return {
|
|
20113
|
+
supported: false,
|
|
20114
|
+
reason: NARO_ADAPTER_REASONS.unknownVersion
|
|
20115
|
+
};
|
|
20116
|
+
if (verdict.kind === "too-old")
|
|
20141
20117
|
return {
|
|
20142
20118
|
supported: false,
|
|
20143
|
-
reason:
|
|
20119
|
+
reason: `The Naro adapter needs Next.js 16.2 or newer; this project runs Next.js ${context.nextVersion}.`
|
|
20144
20120
|
};
|
|
20145
|
-
|
|
20121
|
+
const adapter = userAdapterOf(context);
|
|
20122
|
+
if (adapter && context.userAdapter === "keep")
|
|
20146
20123
|
return {
|
|
20147
20124
|
supported: false,
|
|
20148
|
-
reason:
|
|
20125
|
+
reason: `The project keeps its own Next.js adapter (${describeUserAdapter(adapter)}) by its Next.js adapter setting, so the Naro adapter is skipped.`
|
|
20149
20126
|
};
|
|
20150
20127
|
return { supported: true };
|
|
20151
20128
|
},
|
|
20152
20129
|
async evaluate(context, observer) {
|
|
20153
|
-
|
|
20154
|
-
|
|
20155
|
-
|
|
20156
|
-
)
|
|
20130
|
+
const adapterPath = context.toolchain.nextAdapter;
|
|
20131
|
+
if (!adapterPath)
|
|
20132
|
+
return { status: "skipped", reason: NARO_ADAPTER_REASONS.notInstalled };
|
|
20133
|
+
if (judgeNextVersion(context.nextVersion)?.kind === "newer")
|
|
20134
|
+
await warn(
|
|
20135
|
+
observer,
|
|
20136
|
+
`Next.js ${context.nextVersion} is newer than the versions the Naro adapter is tested with (${testedRange()}); building anyway.`
|
|
20137
|
+
);
|
|
20157
20138
|
let fork;
|
|
20158
20139
|
try {
|
|
20159
|
-
fork = await context.workspace.fork("
|
|
20140
|
+
fork = await context.workspace.fork("naro-adapter");
|
|
20160
20141
|
} catch (error51) {
|
|
20161
20142
|
return failed("prepare", describeError(error51));
|
|
20162
20143
|
}
|
|
20163
|
-
|
|
20164
|
-
|
|
20165
|
-
|
|
20166
|
-
|
|
20167
|
-
|
|
20168
|
-
|
|
20169
|
-
|
|
20170
|
-
|
|
20171
|
-
|
|
20172
|
-
|
|
20173
|
-
|
|
20144
|
+
await rm2(join15(fork.appRoot, OUTPUT_DIR), {
|
|
20145
|
+
recursive: true,
|
|
20146
|
+
force: true
|
|
20147
|
+
});
|
|
20148
|
+
const userAdapter = userAdapterOf(context);
|
|
20149
|
+
if (userAdapter && userAdapter.source !== "build-output") {
|
|
20150
|
+
let replaced = true;
|
|
20151
|
+
if (userAdapter.source === "next-config") {
|
|
20152
|
+
try {
|
|
20153
|
+
replaced = await wrapNextConfig(fork.appRoot, userAdapter.file) !== null;
|
|
20154
|
+
} catch (error51) {
|
|
20155
|
+
return failed("prepare", describeError(error51));
|
|
20156
|
+
}
|
|
20157
|
+
}
|
|
20158
|
+
if (replaced) await warn(observer, replaceWarning(userAdapter));
|
|
20174
20159
|
}
|
|
20175
20160
|
const build = await runStep(
|
|
20176
20161
|
context,
|
|
20177
20162
|
{
|
|
20178
|
-
command: context.
|
|
20179
|
-
args: ["
|
|
20163
|
+
command: context.packageManager.name,
|
|
20164
|
+
args: ["run", context.buildScript],
|
|
20180
20165
|
cwd: fork.appRoot,
|
|
20181
20166
|
env: {
|
|
20182
20167
|
...context.env,
|
|
20183
|
-
|
|
20168
|
+
NEXT_ADAPTER_PATH: adapterPath,
|
|
20169
|
+
NPM_CONFIG_USERCONFIG: context.packageManagerConfigPath,
|
|
20170
|
+
CI: "1"
|
|
20184
20171
|
},
|
|
20185
|
-
timeoutMs:
|
|
20186
|
-
stage: "BUILDING",
|
|
20187
|
-
errorCode: "BUILD_FAILED"
|
|
20188
|
-
},
|
|
20189
|
-
observer
|
|
20190
|
-
);
|
|
20191
|
-
if (!build.ok) return failed("build", describeFailure(build));
|
|
20192
|
-
const serverFunction = join14(fork.appRoot, SERVER_FUNCTION);
|
|
20193
|
-
if (!await pathExists2(serverFunction))
|
|
20194
|
-
return failed("bundle", `OpenNext AWS produced no ${SERVER_FUNCTION}.`);
|
|
20195
|
-
const smoke = await context.ports.smoke.run(
|
|
20196
|
-
{
|
|
20197
|
-
boot: (port) => ({
|
|
20198
|
-
command: process.execPath,
|
|
20199
|
-
args: [serverFunction],
|
|
20200
|
-
cwd: fork.appRoot,
|
|
20201
|
-
env: { ...context.env, PORT: String(port), NODE_ENV: "production" }
|
|
20202
|
-
}),
|
|
20203
|
-
probes: defaultSmokeProbes(context.facts.matcherRoutes),
|
|
20172
|
+
timeoutMs: 15 * 6e4,
|
|
20204
20173
|
stage: "BUILDING",
|
|
20205
20174
|
errorCode: "BUILD_FAILED"
|
|
20206
20175
|
},
|
|
20207
20176
|
observer
|
|
20208
20177
|
);
|
|
20209
|
-
if (!
|
|
20210
|
-
|
|
20211
|
-
status: "success",
|
|
20212
|
-
artifact: {
|
|
20213
|
-
kind: "opennext-aws",
|
|
20214
|
-
outputRoot: join14(fork.appRoot, ".open-next"),
|
|
20215
|
-
serverFunction
|
|
20216
|
-
},
|
|
20217
|
-
notes: [
|
|
20218
|
-
"Verified with the Node wrapper; an AWS deploy needs a Lambda-wrapper build against provisioned resources."
|
|
20219
|
-
]
|
|
20220
|
-
};
|
|
20221
|
-
}
|
|
20222
|
-
};
|
|
20223
|
-
}
|
|
20224
|
-
|
|
20225
|
-
// ../../packages/build/src/strategy/strategies/opennext-cloudflare.ts
|
|
20226
|
-
import { readFile as readFile12 } from "fs/promises";
|
|
20227
|
-
import { join as join15 } from "path";
|
|
20228
|
-
var PROXY_TO_MIDDLEWARE_VARIANT = "proxy-to-middleware";
|
|
20229
|
-
var NODE_MIDDLEWARE_REFUSAL = /Node\.js middleware is not (?:currently )?supported/i;
|
|
20230
|
-
var NODE_MIDDLEWARE_EXPERIMENTAL = /Node\.js middleware support is experimental/i;
|
|
20231
|
-
var NODE_MIDDLEWARE_NOT_DEPLOYED = 'Node.js-runtime middleware (runtime: "nodejs") is only an experiment in OpenNext Cloudflare, and Naro does not deploy it. Remove runtime: "nodejs" to build it as Edge middleware';
|
|
20232
|
-
async function buildDeclaresNodeMiddleware(appRoot) {
|
|
20233
|
-
try {
|
|
20234
|
-
const manifest2 = JSON.parse(
|
|
20235
|
-
await readFile12(
|
|
20236
|
-
join15(appRoot, ".next", "server", "functions-config-manifest.json"),
|
|
20237
|
-
"utf8"
|
|
20238
|
-
)
|
|
20239
|
-
);
|
|
20240
|
-
return Boolean(manifest2.functions?.["/_middleware"]);
|
|
20241
|
-
} catch {
|
|
20242
|
-
return false;
|
|
20243
|
-
}
|
|
20244
|
-
}
|
|
20245
|
-
function createOpenNextCloudflareStrategy(options) {
|
|
20246
|
-
async function attempt(context, roots, observer, ownBuild, adapterNotice) {
|
|
20247
|
-
let platform;
|
|
20248
|
-
try {
|
|
20249
|
-
platform = await options.createPlatformBuildConfig(
|
|
20250
|
-
roots.appRoot,
|
|
20251
|
-
context.identity.deploymentId
|
|
20252
|
-
);
|
|
20253
|
-
} catch (error51) {
|
|
20254
|
-
return {
|
|
20255
|
-
ok: false,
|
|
20256
|
-
nodeMiddleware: null,
|
|
20257
|
-
outcome: failed("prepare", describeError(error51))
|
|
20258
|
-
};
|
|
20259
|
-
}
|
|
20260
|
-
const nextBuild = await runStep(
|
|
20261
|
-
context,
|
|
20262
|
-
{
|
|
20263
|
-
command: context.packageManager.name,
|
|
20264
|
-
args: ["run", context.buildScript],
|
|
20265
|
-
cwd: roots.appRoot,
|
|
20266
|
-
env: {
|
|
20267
|
-
...context.env,
|
|
20268
|
-
NEXT_PRIVATE_STANDALONE: "true",
|
|
20269
|
-
NPM_CONFIG_USERCONFIG: platform.packageManagerConfigPath
|
|
20270
|
-
},
|
|
20271
|
-
timeoutMs: 15 * 6e4,
|
|
20272
|
-
stage: "BUILDING",
|
|
20273
|
-
errorCode: "BUILD_FAILED"
|
|
20274
|
-
},
|
|
20275
|
-
observer
|
|
20276
|
-
);
|
|
20277
|
-
if (!nextBuild.ok) {
|
|
20278
|
-
return {
|
|
20279
|
-
ok: false,
|
|
20280
|
-
nodeMiddleware: null,
|
|
20281
|
-
outcome: ownBuild ? appBuildFailed(describeFailure(nextBuild)) : failed("build", describeFailure(nextBuild))
|
|
20282
|
-
};
|
|
20283
|
-
}
|
|
20284
|
-
if (!adapterNotice.warned) {
|
|
20285
|
-
const adapter = userAdapterOf(context) ?? await adapterInBuildOutput(roots.appRoot, context.nextVersion);
|
|
20286
|
-
if (adapter) {
|
|
20287
|
-
adapterNotice.warned = true;
|
|
20288
|
-
await warn(observer, openNextAdapterWarning(adapter));
|
|
20289
|
-
}
|
|
20290
|
-
}
|
|
20291
|
-
if (await buildDeclaresNodeMiddleware(roots.appRoot)) {
|
|
20292
|
-
return {
|
|
20293
|
-
ok: false,
|
|
20294
|
-
nodeMiddleware: "experimental",
|
|
20295
|
-
outcome: failed("build", NODE_MIDDLEWARE_NOT_DEPLOYED)
|
|
20296
|
-
};
|
|
20297
|
-
}
|
|
20298
|
-
const openNext = await runStep(
|
|
20299
|
-
context,
|
|
20300
|
-
{
|
|
20301
|
-
command: context.toolchain.openNextCloudflare,
|
|
20302
|
-
args: [
|
|
20303
|
-
"build",
|
|
20304
|
-
"--skip-next-build",
|
|
20305
|
-
"--openNextConfigPath",
|
|
20306
|
-
platform.openNextConfigPath,
|
|
20307
|
-
"--config",
|
|
20308
|
-
platform.wranglerConfigPath,
|
|
20309
|
-
...context.nextSupport.status === "needs-unsupported-flag" ? ["--dangerouslyUseUnsupportedNextVersion"] : []
|
|
20310
|
-
],
|
|
20311
|
-
cwd: roots.appRoot,
|
|
20312
|
-
timeoutMs: 15 * 6e4,
|
|
20313
|
-
stage: "BUILDING",
|
|
20314
|
-
errorCode: "OPENNEXT_FAILED"
|
|
20315
|
-
},
|
|
20316
|
-
observer
|
|
20317
|
-
);
|
|
20318
|
-
if (!openNext.ok) {
|
|
20319
|
-
const refused = openNext.output.some(
|
|
20320
|
-
(line) => NODE_MIDDLEWARE_REFUSAL.test(line)
|
|
20321
|
-
);
|
|
20322
|
-
return {
|
|
20323
|
-
ok: false,
|
|
20324
|
-
nodeMiddleware: refused ? "refused" : null,
|
|
20325
|
-
outcome: failed(
|
|
20326
|
-
"build",
|
|
20327
|
-
refused ? NODE_MIDDLEWARE_NOT_DEPLOYED : describeFailure(openNext)
|
|
20328
|
-
)
|
|
20329
|
-
};
|
|
20330
|
-
}
|
|
20331
|
-
if (openNext.output.some((line) => NODE_MIDDLEWARE_EXPERIMENTAL.test(line))) {
|
|
20332
|
-
return {
|
|
20333
|
-
ok: false,
|
|
20334
|
-
nodeMiddleware: "experimental",
|
|
20335
|
-
outcome: failed("build", NODE_MIDDLEWARE_NOT_DEPLOYED)
|
|
20336
|
-
};
|
|
20337
|
-
}
|
|
20338
|
-
const layout = {
|
|
20339
|
-
appRoot: roots.appRoot,
|
|
20340
|
-
wranglerConfigPath: platform.wranglerConfigPath,
|
|
20341
|
-
...OPEN_NEXT_LAYOUT
|
|
20342
|
-
};
|
|
20343
|
-
const bundle = await bundleWorker(
|
|
20344
|
-
context,
|
|
20345
|
-
layout,
|
|
20346
|
-
observer,
|
|
20347
|
-
"OPENNEXT_FAILED"
|
|
20348
|
-
);
|
|
20349
|
-
if (!bundle.ok) {
|
|
20350
|
-
return {
|
|
20351
|
-
ok: false,
|
|
20352
|
-
nodeMiddleware: null,
|
|
20353
|
-
outcome: failed("bundle", describeFailure(bundle))
|
|
20354
|
-
};
|
|
20355
|
-
}
|
|
20356
|
-
let artifact;
|
|
20357
|
-
try {
|
|
20358
|
-
artifact = await options.readOpenNextArtifact(
|
|
20359
|
-
roots.appRoot,
|
|
20360
|
-
context.identity,
|
|
20361
|
-
platform.wranglerConfigPath
|
|
20362
|
-
);
|
|
20363
|
-
} catch (error51) {
|
|
20364
|
-
return {
|
|
20365
|
-
ok: false,
|
|
20366
|
-
nodeMiddleware: null,
|
|
20367
|
-
outcome: failed("bundle", describeError(error51))
|
|
20368
|
-
};
|
|
20369
|
-
}
|
|
20370
|
-
const smoke = await smokeWorker(context, layout, observer);
|
|
20371
|
-
if (!smoke.ok) {
|
|
20372
|
-
return {
|
|
20373
|
-
ok: false,
|
|
20374
|
-
nodeMiddleware: null,
|
|
20375
|
-
outcome: failed("smoke", smoke.reason)
|
|
20376
|
-
};
|
|
20377
|
-
}
|
|
20378
|
-
return { ok: true, artifact };
|
|
20379
|
-
}
|
|
20380
|
-
return {
|
|
20381
|
-
id: "opennext-cloudflare",
|
|
20382
|
-
priority: 2,
|
|
20383
|
-
target: "cloudflare",
|
|
20384
|
-
supports: () => ({ supported: true }),
|
|
20385
|
-
async evaluate(context, observer) {
|
|
20386
|
-
const adapterNotice = { warned: false };
|
|
20387
|
-
const rememberedRewrite = context.pinnedVariant === PROXY_TO_MIDDLEWARE_VARIANT && context.facts.proxyFile !== null;
|
|
20388
|
-
if (rememberedRewrite) {
|
|
20389
|
-
await info(
|
|
20390
|
-
observer,
|
|
20391
|
-
`P2 opennext-cloudflare: the stored strategy already needed ${context.facts.proxyFile ?? "proxy"} rewritten to Edge middleware; building that way directly.`
|
|
20392
|
-
);
|
|
20393
|
-
} else {
|
|
20394
|
-
await info(
|
|
20395
|
-
observer,
|
|
20396
|
-
"P2 opennext-cloudflare: building the project as written."
|
|
20397
|
-
);
|
|
20398
|
-
const first = await attempt(
|
|
20399
|
-
context,
|
|
20400
|
-
context.workspace,
|
|
20401
|
-
observer,
|
|
20402
|
-
true,
|
|
20403
|
-
adapterNotice
|
|
20404
|
-
);
|
|
20405
|
-
if (first.ok) {
|
|
20178
|
+
if (!build.ok) {
|
|
20179
|
+
if (!await pathExists(join15(fork.appRoot, BUILD_RECORD)))
|
|
20406
20180
|
return {
|
|
20407
|
-
status: "
|
|
20408
|
-
|
|
20409
|
-
|
|
20181
|
+
status: "failed",
|
|
20182
|
+
stage: "build",
|
|
20183
|
+
reason: describeFailure(build),
|
|
20184
|
+
appBuild: true
|
|
20410
20185
|
};
|
|
20411
|
-
|
|
20412
|
-
|
|
20413
|
-
|
|
20414
|
-
|
|
20415
|
-
|
|
20416
|
-
|
|
20186
|
+
return failed("bundle", describeFailure(build));
|
|
20187
|
+
}
|
|
20188
|
+
const record3 = await readRecord(fork.appRoot);
|
|
20189
|
+
if (!record3 || await readBuildId(record3.distDir) !== record3.buildId) {
|
|
20190
|
+
const ran = await adapterInBuildOutput(
|
|
20191
|
+
fork.appRoot,
|
|
20192
|
+
context.nextVersion
|
|
20193
|
+
);
|
|
20194
|
+
return failed(
|
|
20195
|
+
"build",
|
|
20196
|
+
ran?.source === "build-output" && resolve5(fork.appRoot, ran.path) !== resolve5(adapterPath) ? NARO_ADAPTER_REASONS.userAdapterRan(ran.key) : NARO_ADAPTER_REASONS.missingOutput
|
|
20417
20197
|
);
|
|
20418
20198
|
}
|
|
20419
|
-
let
|
|
20199
|
+
let artifact;
|
|
20420
20200
|
try {
|
|
20421
|
-
|
|
20201
|
+
artifact = await options.readArtifact(fork.appRoot, context.identity);
|
|
20422
20202
|
} catch (error51) {
|
|
20423
|
-
return failed("
|
|
20424
|
-
}
|
|
20425
|
-
const conversion = await options.convertProxyToMiddleware(fork.appRoot);
|
|
20426
|
-
if (!conversion.converted) {
|
|
20427
|
-
return failed(
|
|
20428
|
-
"prepare",
|
|
20429
|
-
`Could not rewrite ${context.facts.proxyFile} to middleware (a middleware file already exists).`
|
|
20430
|
-
);
|
|
20203
|
+
return failed("bundle", describeError(error51));
|
|
20431
20204
|
}
|
|
20432
|
-
await
|
|
20433
|
-
observer,
|
|
20434
|
-
`Converted ${conversion.file ?? context.facts.proxyFile} to edge middleware for this build only. Next.js 16 proxy runs on the Node.js runtime, which Cloudflare does not support; middleware runs on the Edge runtime, so Node.js-only APIs are unavailable. Your repository is unchanged.`
|
|
20435
|
-
);
|
|
20436
|
-
const second = await attempt(
|
|
20205
|
+
const smoke = await smokeWorker(
|
|
20437
20206
|
context,
|
|
20438
|
-
|
|
20207
|
+
{
|
|
20208
|
+
appRoot: fork.appRoot,
|
|
20209
|
+
wranglerConfigPath: join15(fork.appRoot, WRANGLER_CONFIG),
|
|
20210
|
+
outputRoot: OUTPUT_DIR
|
|
20211
|
+
},
|
|
20439
20212
|
observer,
|
|
20440
|
-
|
|
20441
|
-
|
|
20213
|
+
naroAdapterSmokeProbes(
|
|
20214
|
+
record3,
|
|
20215
|
+
artifact.assets.map((asset) => asset.name)
|
|
20216
|
+
)
|
|
20442
20217
|
);
|
|
20443
|
-
if (!
|
|
20444
|
-
if (!rememberedRewrite || second.outcome.status !== "failed" || !second.outcome.appBuild)
|
|
20445
|
-
return second.outcome;
|
|
20446
|
-
await info(
|
|
20447
|
-
observer,
|
|
20448
|
-
`P2 opennext-cloudflare: the rewritten copy did not build; building the project as written once to tell the app's own error from the rewrite's.`
|
|
20449
|
-
);
|
|
20450
|
-
const asWritten = await attempt(
|
|
20451
|
-
context,
|
|
20452
|
-
context.workspace,
|
|
20453
|
-
observer,
|
|
20454
|
-
true,
|
|
20455
|
-
adapterNotice
|
|
20456
|
-
);
|
|
20457
|
-
if (asWritten.ok) {
|
|
20458
|
-
await info(
|
|
20459
|
-
observer,
|
|
20460
|
-
"P2 opennext-cloudflare: the project as written builds and ships as it is; the rewrite is no longer needed."
|
|
20461
|
-
);
|
|
20462
|
-
return {
|
|
20463
|
-
status: "success",
|
|
20464
|
-
artifact: {
|
|
20465
|
-
kind: "cloudflare-worker",
|
|
20466
|
-
artifact: asWritten.artifact
|
|
20467
|
-
},
|
|
20468
|
-
notes: []
|
|
20469
|
-
};
|
|
20470
|
-
}
|
|
20471
|
-
if (asWritten.outcome.status === "failed" && asWritten.outcome.appBuild) {
|
|
20472
|
-
await warn(
|
|
20473
|
-
observer,
|
|
20474
|
-
"P2 opennext-cloudflare: the project as written does not build either, so the error is the app's own."
|
|
20475
|
-
);
|
|
20476
|
-
return asWritten.outcome;
|
|
20477
|
-
}
|
|
20478
|
-
await warn(
|
|
20479
|
-
observer,
|
|
20480
|
-
"P2 opennext-cloudflare: the project as written builds, so the rewritten copy's error is the Edge rewrite's (a Node-only API reached from proxy.ts), not the app's code."
|
|
20481
|
-
);
|
|
20482
|
-
return failed("build", second.outcome.reason);
|
|
20483
|
-
}
|
|
20218
|
+
if (!smoke.ok) return failed("smoke", smoke.reason);
|
|
20484
20219
|
return {
|
|
20485
20220
|
status: "success",
|
|
20486
|
-
artifact: { kind: "cloudflare-worker", artifact
|
|
20487
|
-
variant: PROXY_TO_MIDDLEWARE_VARIANT,
|
|
20221
|
+
artifact: { kind: "cloudflare-worker", artifact },
|
|
20488
20222
|
notes: [
|
|
20489
|
-
|
|
20223
|
+
"Built with the Naro adapter (Next.js Adapter API) in a temporary workspace."
|
|
20490
20224
|
]
|
|
20491
20225
|
};
|
|
20492
20226
|
}
|
|
20493
20227
|
};
|
|
20494
20228
|
}
|
|
20495
20229
|
|
|
20496
|
-
// ../../packages/build/src/strategy/strategies/unavailable.ts
|
|
20497
|
-
function createUnavailableStrategy(options) {
|
|
20498
|
-
return {
|
|
20499
|
-
id: options.id,
|
|
20500
|
-
priority: options.priority,
|
|
20501
|
-
target: options.target,
|
|
20502
|
-
supports: () => ({ supported: false, reason: options.reason }),
|
|
20503
|
-
evaluate: async () => ({ status: "skipped", reason: options.reason })
|
|
20504
|
-
};
|
|
20505
|
-
}
|
|
20506
|
-
function createSplitCloudflareStrategy() {
|
|
20507
|
-
return createUnavailableStrategy({
|
|
20508
|
-
id: "split-cloudflare",
|
|
20509
|
-
priority: 3,
|
|
20510
|
-
target: "cloudflare-split",
|
|
20511
|
-
reason: "Split Cloudflare deployment needs the dispatcher to chain a middleware Worker in front of the app Worker; the runtime plane routes one Worker per hostname today."
|
|
20512
|
-
});
|
|
20513
|
-
}
|
|
20514
|
-
function createAwsMiddlewareCloudflareAppStrategy() {
|
|
20515
|
-
return createUnavailableStrategy({
|
|
20516
|
-
id: "aws-middleware-cloudflare-app",
|
|
20517
|
-
priority: 4,
|
|
20518
|
-
target: "aws-hybrid",
|
|
20519
|
-
reason: "Hybrid AWS middleware + Cloudflare app needs an AWS deploy target and cross-cloud request chaining; neither exists on this control plane."
|
|
20520
|
-
});
|
|
20521
|
-
}
|
|
20522
|
-
|
|
20523
20230
|
// ../../packages/build/src/strategy/strategies/vinext-cloudflare.ts
|
|
20524
20231
|
var VINEXT_MIN_NEXT_MAJOR = 16;
|
|
20525
20232
|
var VINEXT_BUILD_SCRIPTS = ["esbuild", "workerd"];
|
|
@@ -20594,6 +20301,7 @@ function createVinextCloudflareStrategy(options) {
|
|
|
20594
20301
|
observer,
|
|
20595
20302
|
"P1 vinext-cloudflare: the project already builds with vinext; using its own configuration."
|
|
20596
20303
|
);
|
|
20304
|
+
await info(observer, ISR_SHARED_CACHE_OFF_NOTE);
|
|
20597
20305
|
}
|
|
20598
20306
|
let fork;
|
|
20599
20307
|
try {
|
|
@@ -20691,13 +20399,13 @@ function createVinextCloudflareStrategy(options) {
|
|
|
20691
20399
|
|
|
20692
20400
|
// ../../packages/build/src/strategy/workspace.ts
|
|
20693
20401
|
import { execFile } from "child_process";
|
|
20694
|
-
import { cp, mkdir as mkdir2, readdir as readdir4, rm as
|
|
20695
|
-
import { basename
|
|
20402
|
+
import { cp, mkdir as mkdir2, readdir as readdir4, rm as rm3 } from "fs/promises";
|
|
20403
|
+
import { basename, dirname as dirname2, join as join16, relative as relative5, resolve as resolve6 } from "path";
|
|
20696
20404
|
import { promisify } from "util";
|
|
20697
20405
|
var execFileAsync = promisify(execFile);
|
|
20698
20406
|
var SKIPPED_ANYWHERE = /* @__PURE__ */ new Set(["node_modules"]);
|
|
20699
20407
|
function shouldCopy(path) {
|
|
20700
|
-
const name =
|
|
20408
|
+
const name = basename(path);
|
|
20701
20409
|
if (SKIPPED_ANYWHERE.has(name)) return false;
|
|
20702
20410
|
return !name.startsWith(".next-deploy-");
|
|
20703
20411
|
}
|
|
@@ -20725,13 +20433,13 @@ async function copyInstalledPackages(source, target2) {
|
|
|
20725
20433
|
await copyTree(install, join16(target2, relative5(origin, install)));
|
|
20726
20434
|
}
|
|
20727
20435
|
async function copyTree(from, to) {
|
|
20728
|
-
await mkdir2(
|
|
20436
|
+
await mkdir2(dirname2(to), { recursive: true });
|
|
20729
20437
|
if (process.platform !== "win32") {
|
|
20730
20438
|
try {
|
|
20731
20439
|
await execFileAsync("cp", ["-a", from, to]);
|
|
20732
20440
|
return;
|
|
20733
20441
|
} catch {
|
|
20734
|
-
await
|
|
20442
|
+
await rm3(to, { recursive: true, force: true });
|
|
20735
20443
|
}
|
|
20736
20444
|
}
|
|
20737
20445
|
await cp(from, to, { recursive: true, verbatimSymlinks: true });
|
|
@@ -20759,27 +20467,26 @@ async function withRouteList(artifact, list, appRoot, observer) {
|
|
|
20759
20467
|
return artifact;
|
|
20760
20468
|
}
|
|
20761
20469
|
}
|
|
20470
|
+
var NEXT_ADAPTER_PATH = nextAdapterPath();
|
|
20762
20471
|
var defaultLocalBuildDependencies = {
|
|
20763
20472
|
createWorkspace: () => mkdtemp(join17(tmpdir(), "next-deploy-build-")),
|
|
20764
|
-
removeWorkspace: (path) =>
|
|
20473
|
+
removeWorkspace: (path) => rm4(path, { recursive: true, force: true }),
|
|
20765
20474
|
runCommand,
|
|
20766
20475
|
detectPackageManager,
|
|
20767
20476
|
resolveAppRoot,
|
|
20768
20477
|
detectFramework,
|
|
20769
20478
|
readStaticArtifact,
|
|
20770
20479
|
createPackageManagerConfig,
|
|
20771
|
-
createPlatformBuildConfig,
|
|
20772
|
-
readOpenNextArtifact,
|
|
20773
|
-
openNextCommand: "opennextjs-cloudflare",
|
|
20774
20480
|
wranglerCommand: "wrangler",
|
|
20775
20481
|
cacheFetch: (input, init) => fetch(input, init),
|
|
20776
|
-
convertProxyToMiddleware,
|
|
20777
20482
|
commandAvailable: hasCommand,
|
|
20778
20483
|
readInstalledNextVersion,
|
|
20779
20484
|
now: () => /* @__PURE__ */ new Date(),
|
|
20780
20485
|
createVinextBuildConfig,
|
|
20781
20486
|
readVinextArtifact,
|
|
20782
20487
|
vinextCommand: "vinext",
|
|
20488
|
+
...NEXT_ADAPTER_PATH ? { nextAdapterPath: NEXT_ADAPTER_PATH } : {},
|
|
20489
|
+
readNaroAdapterArtifact,
|
|
20783
20490
|
forkWorkspace: copyCheckout,
|
|
20784
20491
|
copyInstalledPackages,
|
|
20785
20492
|
collectProjectFacts,
|
|
@@ -20794,7 +20501,7 @@ async function readInstalledNextVersion(appRoot, checkout) {
|
|
|
20794
20501
|
const stop = resolve7(checkout);
|
|
20795
20502
|
for (; ; ) {
|
|
20796
20503
|
try {
|
|
20797
|
-
const source = await
|
|
20504
|
+
const source = await readFile14(
|
|
20798
20505
|
join17(dir, "node_modules", "next", "package.json"),
|
|
20799
20506
|
"utf8"
|
|
20800
20507
|
);
|
|
@@ -20803,7 +20510,7 @@ async function readInstalledNextVersion(appRoot, checkout) {
|
|
|
20803
20510
|
} catch {
|
|
20804
20511
|
}
|
|
20805
20512
|
if (dir === stop) return null;
|
|
20806
|
-
const parent =
|
|
20513
|
+
const parent = dirname3(dir);
|
|
20807
20514
|
if (parent === dir) return null;
|
|
20808
20515
|
dir = parent;
|
|
20809
20516
|
}
|
|
@@ -20826,9 +20533,9 @@ async function hasCommand(command) {
|
|
|
20826
20533
|
return false;
|
|
20827
20534
|
}
|
|
20828
20535
|
}
|
|
20829
|
-
async function
|
|
20536
|
+
async function pathExists2(path) {
|
|
20830
20537
|
try {
|
|
20831
|
-
await
|
|
20538
|
+
await access6(path);
|
|
20832
20539
|
return true;
|
|
20833
20540
|
} catch {
|
|
20834
20541
|
return false;
|
|
@@ -20872,14 +20579,11 @@ function defaultStrategies(dependencies) {
|
|
|
20872
20579
|
createVinextBuildConfig: dependencies.createVinextBuildConfig ?? createVinextBuildConfig,
|
|
20873
20580
|
readVinextArtifact: dependencies.readVinextArtifact ?? readVinextArtifact
|
|
20874
20581
|
}),
|
|
20875
|
-
|
|
20876
|
-
|
|
20877
|
-
convertProxyToMiddleware: dependencies.convertProxyToMiddleware ?? convertProxyToMiddleware,
|
|
20878
|
-
readOpenNextArtifact: dependencies.readOpenNextArtifact
|
|
20582
|
+
createNaroAdapterCloudflareStrategy({
|
|
20583
|
+
readArtifact: dependencies.readNaroAdapterArtifact ?? readNaroAdapterArtifact
|
|
20879
20584
|
}),
|
|
20880
20585
|
createSplitCloudflareStrategy(),
|
|
20881
|
-
createAwsMiddlewareCloudflareAppStrategy()
|
|
20882
|
-
createOpenNextAwsStrategy()
|
|
20586
|
+
createAwsMiddlewareCloudflareAppStrategy()
|
|
20883
20587
|
];
|
|
20884
20588
|
}
|
|
20885
20589
|
var LocalBuildExecutor = class {
|
|
@@ -21158,7 +20862,7 @@ var LocalBuildExecutor = class {
|
|
|
21158
20862
|
"NEXT_VERSION_UNSUPPORTED",
|
|
21159
20863
|
nextSupport.reason
|
|
21160
20864
|
);
|
|
21161
|
-
if (nextSupport.status === "
|
|
20865
|
+
if (nextSupport.status === "past-support-window" || nextSupport.status === "outside-verified-range") {
|
|
21162
20866
|
await observer.onLog({
|
|
21163
20867
|
level: "WARN",
|
|
21164
20868
|
stage: "BUILDING",
|
|
@@ -21213,7 +20917,6 @@ var LocalBuildExecutor = class {
|
|
|
21213
20917
|
};
|
|
21214
20918
|
};
|
|
21215
20919
|
const vinextCommand = this.dependencies.vinextCommand;
|
|
21216
|
-
const openNextAwsCommand = this.dependencies.openNextAwsCommand;
|
|
21217
20920
|
const context = {
|
|
21218
20921
|
identity,
|
|
21219
20922
|
branch: input.branch,
|
|
@@ -21225,15 +20928,14 @@ var LocalBuildExecutor = class {
|
|
|
21225
20928
|
buildScript: resolved.buildScript,
|
|
21226
20929
|
nextVersion: nextVersion ? `${String(nextVersion.major)}.${String(nextVersion.minor)}.${String(nextVersion.patch)}` : "unknown",
|
|
21227
20930
|
nextMajor,
|
|
21228
|
-
nextSupport,
|
|
21229
20931
|
vinextEnabled: input.vinextEnabled !== false,
|
|
20932
|
+
userAdapter: input.userAdapter === "keep" ? "keep" : "replace",
|
|
21230
20933
|
facts,
|
|
21231
20934
|
workspace: { checkout, appRoot, fork: forkWorkspace },
|
|
21232
20935
|
toolchain: {
|
|
21233
|
-
openNextCloudflare: this.dependencies.openNextCommand,
|
|
21234
20936
|
wrangler: this.dependencies.wranglerCommand,
|
|
21235
20937
|
...vinextCommand && await commandAvailable(vinextCommand) ? { vinext: vinextCommand } : {},
|
|
21236
|
-
...
|
|
20938
|
+
...this.dependencies.nextAdapterPath && await pathExists2(this.dependencies.nextAdapterPath) ? { nextAdapter: this.dependencies.nextAdapterPath } : {}
|
|
21237
20939
|
},
|
|
21238
20940
|
targets: this.dependencies.targets ?? { cloudflare: true },
|
|
21239
20941
|
ports: {
|
|
@@ -21288,7 +20990,7 @@ var LocalBuildExecutor = class {
|
|
|
21288
20990
|
if (depsKey && !depsRestored) {
|
|
21289
20991
|
await trySave("deps", depsKey, pmCacheDir, cachePorts, observer);
|
|
21290
20992
|
}
|
|
21291
|
-
if (buildCacheDir && await
|
|
20993
|
+
if (buildCacheDir && await pathExists2(buildCacheDir)) {
|
|
21292
20994
|
await trySave(
|
|
21293
20995
|
"next",
|
|
21294
20996
|
buildCacheKey,
|
|
@@ -21688,8 +21390,8 @@ function sendPage(res, status, html) {
|
|
|
21688
21390
|
async function startCallbackServer() {
|
|
21689
21391
|
let resolveCode;
|
|
21690
21392
|
let rejectCode;
|
|
21691
|
-
const codePromise = new Promise((
|
|
21692
|
-
resolveCode =
|
|
21393
|
+
const codePromise = new Promise((resolve16, reject) => {
|
|
21394
|
+
resolveCode = resolve16;
|
|
21693
21395
|
rejectCode = reject;
|
|
21694
21396
|
});
|
|
21695
21397
|
const server = createServer2((req, res) => {
|
|
@@ -21718,7 +21420,7 @@ async function startCallbackServer() {
|
|
|
21718
21420
|
sendPage(res, 200, successPage());
|
|
21719
21421
|
resolveCode(code);
|
|
21720
21422
|
});
|
|
21721
|
-
await new Promise((
|
|
21423
|
+
await new Promise((resolve16) => server.listen(0, "127.0.0.1", resolve16));
|
|
21722
21424
|
const port = server.address().port;
|
|
21723
21425
|
return {
|
|
21724
21426
|
port,
|
|
@@ -22136,32 +21838,6 @@ var ObservabilityApi = class {
|
|
|
22136
21838
|
}
|
|
22137
21839
|
};
|
|
22138
21840
|
|
|
22139
|
-
// ../../packages/sdk/src/supabase-links.ts
|
|
22140
|
-
var SupabaseApi = class {
|
|
22141
|
-
constructor(client) {
|
|
22142
|
-
this.client = client;
|
|
22143
|
-
}
|
|
22144
|
-
async links(projectId) {
|
|
22145
|
-
const body = await this.client.request(
|
|
22146
|
-
`/api/projects/${encodeURIComponent(projectId)}/supabase`,
|
|
22147
|
-
{ context: "Read Supabase links" }
|
|
22148
|
-
);
|
|
22149
|
-
return body.links;
|
|
22150
|
-
}
|
|
22151
|
-
/**
|
|
22152
|
-
* Removes the link of one target (production, preview or an environment's
|
|
22153
|
-
* slug), or every link the role may write when `target` is left out, with
|
|
22154
|
-
* the env rows they hold. Answers how many went.
|
|
22155
|
-
*/
|
|
22156
|
-
async disconnect(projectId, options = {}) {
|
|
22157
|
-
const query = options.target === void 0 ? "" : `?target=${encodeURIComponent(options.target)}`;
|
|
22158
|
-
return this.client.request(
|
|
22159
|
-
`/api/projects/${encodeURIComponent(projectId)}/supabase${query}`,
|
|
22160
|
-
{ method: "DELETE", context: "Disconnect Supabase" }
|
|
22161
|
-
);
|
|
22162
|
-
}
|
|
22163
|
-
};
|
|
22164
|
-
|
|
22165
21841
|
// ../../packages/sdk/src/environments.ts
|
|
22166
21842
|
function isReservedEnvTarget(value) {
|
|
22167
21843
|
return RESERVED_ENVIRONMENT_SLUGS.includes(value);
|
|
@@ -22242,7 +21918,8 @@ function projectInfo(row) {
|
|
|
22242
21918
|
repositoryUrl: row.repository_url,
|
|
22243
21919
|
repositoryFullName: row.repository_full_name ?? null,
|
|
22244
21920
|
createdAt: row.created_at,
|
|
22245
|
-
updatedAt: row.updated_at
|
|
21921
|
+
updatedAt: row.updated_at,
|
|
21922
|
+
userAdapter: row.user_adapter ?? null
|
|
22246
21923
|
};
|
|
22247
21924
|
}
|
|
22248
21925
|
function deploymentInfo(row) {
|
|
@@ -22301,7 +21978,6 @@ var NaroClient = class _NaroClient {
|
|
|
22301
21978
|
flags;
|
|
22302
21979
|
billing;
|
|
22303
21980
|
observability;
|
|
22304
|
-
supabase;
|
|
22305
21981
|
logs;
|
|
22306
21982
|
db;
|
|
22307
21983
|
backend;
|
|
@@ -22330,7 +22006,6 @@ var NaroClient = class _NaroClient {
|
|
|
22330
22006
|
this.flags = new FlagsApi(this);
|
|
22331
22007
|
this.billing = new BillingApi(this);
|
|
22332
22008
|
this.observability = new ObservabilityApi(this);
|
|
22333
|
-
this.supabase = new SupabaseApi(this);
|
|
22334
22009
|
this.logs = new LogsApi(this);
|
|
22335
22010
|
this.db = new DbApi(this);
|
|
22336
22011
|
this.backend = new BackendApi(this);
|
|
@@ -22415,6 +22090,19 @@ var TeamsApi = class {
|
|
|
22415
22090
|
{ context: "Read team usage" }
|
|
22416
22091
|
);
|
|
22417
22092
|
}
|
|
22093
|
+
/**
|
|
22094
|
+
* The team's hosting compute (CPU) per project and environment for a UTC
|
|
22095
|
+
* month (spec 2026-11-06-hosting-cpu-usage §7). Observed, never billed.
|
|
22096
|
+
*/
|
|
22097
|
+
async usageHosting(teamSlug, query = {}) {
|
|
22098
|
+
const params = new URLSearchParams();
|
|
22099
|
+
if (query.month !== void 0) params.set("month", query.month);
|
|
22100
|
+
const text3 = params.toString();
|
|
22101
|
+
return this.client.request(
|
|
22102
|
+
`/api/teams/${encodeURIComponent(teamSlug)}/usage/hosting${text3 ? `?${text3}` : ""}`,
|
|
22103
|
+
{ context: "Read team hosting usage" }
|
|
22104
|
+
);
|
|
22105
|
+
}
|
|
22418
22106
|
path(teamSlug, suffix = "") {
|
|
22419
22107
|
return `/api/teams/${encodeURIComponent(teamSlug)}${suffix}`;
|
|
22420
22108
|
}
|
|
@@ -22790,7 +22478,7 @@ var DeploymentsApi = class {
|
|
|
22790
22478
|
async wait(deploymentId, options = {}) {
|
|
22791
22479
|
const intervalMs = options.intervalMs ?? 2500;
|
|
22792
22480
|
const timeoutMs = options.timeoutMs ?? 15 * 6e4;
|
|
22793
|
-
const sleep2 = options.sleep ?? ((ms) => new Promise((
|
|
22481
|
+
const sleep2 = options.sleep ?? ((ms) => new Promise((resolve16) => setTimeout(resolve16, ms)));
|
|
22794
22482
|
const startedAt = Date.now();
|
|
22795
22483
|
let lastStatus = null;
|
|
22796
22484
|
let lastSequence = -1;
|
|
@@ -23391,7 +23079,7 @@ var DbApi = class {
|
|
|
23391
23079
|
*/
|
|
23392
23080
|
async export(projectId, options = {}, wait = {}) {
|
|
23393
23081
|
const timeoutMs = wait.timeoutMs ?? EXPORT_TIMEOUT_MS;
|
|
23394
|
-
const sleep2 = wait.sleep ?? ((ms) => new Promise((
|
|
23082
|
+
const sleep2 = wait.sleep ?? ((ms) => new Promise((resolve16) => setTimeout(resolve16, ms)));
|
|
23395
23083
|
const given = wait.pollIntervalMs;
|
|
23396
23084
|
const firstPollMs = given !== void 0 && Number.isFinite(given) && given > 0 ? given : EXPORT_FIRST_POLL_MS;
|
|
23397
23085
|
const maxPollMs = Math.max(EXPORT_MAX_POLL_MS, firstPollMs);
|
|
@@ -26854,8 +26542,8 @@ function readAuth(state, start, allowBareJwt) {
|
|
|
26854
26542
|
stream.expectOperator("(");
|
|
26855
26543
|
stream.expectOperator(")");
|
|
26856
26544
|
if (fn !== "jwt") return { kind: "auth", fn };
|
|
26857
|
-
const
|
|
26858
|
-
if (
|
|
26545
|
+
const access7 = readJwtAccess(stream);
|
|
26546
|
+
if (access7) return access7;
|
|
26859
26547
|
if (allowBareJwt) return "jwt";
|
|
26860
26548
|
throw new PolicySyntaxError(
|
|
26861
26549
|
"auth.jwt() is read one claim at a time: auth.jwt() ->> 'email'",
|
|
@@ -26923,13 +26611,13 @@ function readPrimary(state) {
|
|
|
26923
26611
|
const inner2 = readAuth(state, auth, true);
|
|
26924
26612
|
stream.expectOperator(")");
|
|
26925
26613
|
if (inner2 !== "jwt") return inner2;
|
|
26926
|
-
const
|
|
26927
|
-
if (!
|
|
26614
|
+
const access7 = readJwtAccess(stream);
|
|
26615
|
+
if (!access7)
|
|
26928
26616
|
throw new PolicySyntaxError(
|
|
26929
26617
|
"auth.jwt() is read one claim at a time: (select auth.jwt()) ->> 'email'",
|
|
26930
26618
|
auth.position
|
|
26931
26619
|
);
|
|
26932
|
-
return
|
|
26620
|
+
return access7;
|
|
26933
26621
|
}
|
|
26934
26622
|
const inner = readOr(state);
|
|
26935
26623
|
stream.expectOperator(")");
|
|
@@ -34695,10 +34383,10 @@ var SUPPORTED_REMOTE = [
|
|
|
34695
34383
|
/^ssh:\/\/[^\s]+$/,
|
|
34696
34384
|
/^git@[A-Za-z0-9.-]+:[A-Za-z0-9._/-]+(\.git)?$/
|
|
34697
34385
|
];
|
|
34698
|
-
var defaultExec = (args, cwd) => new Promise((
|
|
34386
|
+
var defaultExec = (args, cwd) => new Promise((resolve16, reject) => {
|
|
34699
34387
|
execFile2("git", args, { cwd }, (error51, stdout) => {
|
|
34700
34388
|
if (error51) reject(error51);
|
|
34701
|
-
else
|
|
34389
|
+
else resolve16(stdout);
|
|
34702
34390
|
});
|
|
34703
34391
|
});
|
|
34704
34392
|
async function tryExec(exec, args, cwd) {
|
|
@@ -34847,15 +34535,52 @@ async function uploadArtifact(artifact, opts) {
|
|
|
34847
34535
|
};
|
|
34848
34536
|
}
|
|
34849
34537
|
|
|
34538
|
+
// src/user-adapter.ts
|
|
34539
|
+
import { resolve as resolve10 } from "path";
|
|
34540
|
+
async function detectUserAdapter(directory, rootDirectory) {
|
|
34541
|
+
return findAdapterConfig(
|
|
34542
|
+
rootDirectory ? resolve10(directory, rootDirectory) : directory
|
|
34543
|
+
);
|
|
34544
|
+
}
|
|
34545
|
+
function parseUserAdapter(value) {
|
|
34546
|
+
return value === "replace" || value === "keep" ? value : null;
|
|
34547
|
+
}
|
|
34548
|
+
var USER_ADAPTER_OPTIONS = [
|
|
34549
|
+
{
|
|
34550
|
+
value: "replace",
|
|
34551
|
+
label: "Replace it with the Naro adapter on Naro's builders (recommended) \u2014 your repository stays as it is"
|
|
34552
|
+
},
|
|
34553
|
+
{ value: "keep", label: "Keep my adapter \u2014 Naro builds with vinext only" }
|
|
34554
|
+
];
|
|
34555
|
+
function userAdapterQuestion(adapter) {
|
|
34556
|
+
return `${adapter.file} sets its own Next.js adapter (${adapter.key}). How should Naro build this project?`;
|
|
34557
|
+
}
|
|
34558
|
+
function userAdapterOutcome(choice) {
|
|
34559
|
+
return choice === "replace" ? "\u25B8 This local build uses vinext only; if vinext cannot build the app, build it on Naro with the Naro adapter: naro deployments create (needs a connected repository)." : "\u25B8 Naro keeps your adapter: builds use vinext only.";
|
|
34560
|
+
}
|
|
34561
|
+
function userAdapterStored(adapter, choice) {
|
|
34562
|
+
return choice === "replace" ? `\u25B8 ${adapter.file} sets its own Next.js adapter; this project replaces it with the Naro adapter on Naro's builders.` : `\u25B8 ${adapter.file} sets its own Next.js adapter; this project keeps it and builds with vinext only.`;
|
|
34563
|
+
}
|
|
34564
|
+
function userAdapterUnasked(adapter) {
|
|
34565
|
+
return `\u26A0 ${adapter.file} sets its own Next.js adapter (${adapter.key}). Naro's builders replace it with the Naro adapter unless you choose otherwise: naro deploy --user-adapter keep, or naro project set --user-adapter keep.`;
|
|
34566
|
+
}
|
|
34567
|
+
var CHOOSE_USER_ADAPTER = {
|
|
34568
|
+
cli: "naro project set --user-adapter replace|keep",
|
|
34569
|
+
mcp: "update_project with userAdapter replace|keep"
|
|
34570
|
+
};
|
|
34571
|
+
function userAdapterUnreadable(adapter, surface = "cli") {
|
|
34572
|
+
return `\u26A0 ${adapter.file} sets its own Next.js adapter (${adapter.key}), but the project's adapter setting could not be read, so nothing was asked. Choose with ${CHOOSE_USER_ADAPTER[surface]}.`;
|
|
34573
|
+
}
|
|
34574
|
+
|
|
34850
34575
|
// src/version.ts
|
|
34851
34576
|
import { readFileSync as readFileSync6 } from "fs";
|
|
34852
|
-
import { dirname as
|
|
34853
|
-
import { fileURLToPath } from "url";
|
|
34577
|
+
import { dirname as dirname4, join as join24 } from "path";
|
|
34578
|
+
import { fileURLToPath as fileURLToPath2 } from "url";
|
|
34854
34579
|
function version2() {
|
|
34855
34580
|
try {
|
|
34856
34581
|
const pkg = JSON.parse(
|
|
34857
34582
|
readFileSync6(
|
|
34858
|
-
join24(
|
|
34583
|
+
join24(dirname4(fileURLToPath2(import.meta.url)), "..", "package.json"),
|
|
34859
34584
|
"utf8"
|
|
34860
34585
|
)
|
|
34861
34586
|
);
|
|
@@ -34871,22 +34596,22 @@ import {
|
|
|
34871
34596
|
cp as cp2,
|
|
34872
34597
|
lstat,
|
|
34873
34598
|
mkdir as mkdir3,
|
|
34874
|
-
readFile as
|
|
34599
|
+
readFile as readFile15,
|
|
34875
34600
|
readlink,
|
|
34876
34601
|
realpath as realpath3,
|
|
34877
|
-
rm as
|
|
34602
|
+
rm as rm5,
|
|
34878
34603
|
stat as stat3,
|
|
34879
34604
|
symlink,
|
|
34880
34605
|
unlink,
|
|
34881
|
-
writeFile as
|
|
34606
|
+
writeFile as writeFile6
|
|
34882
34607
|
} from "fs/promises";
|
|
34883
34608
|
import {
|
|
34884
|
-
basename as
|
|
34885
|
-
dirname as
|
|
34609
|
+
basename as basename2,
|
|
34610
|
+
dirname as dirname5,
|
|
34886
34611
|
isAbsolute as isAbsolute4,
|
|
34887
34612
|
join as join25,
|
|
34888
34613
|
relative as relative6,
|
|
34889
|
-
resolve as
|
|
34614
|
+
resolve as resolve11,
|
|
34890
34615
|
sep as sep5
|
|
34891
34616
|
} from "path";
|
|
34892
34617
|
var COPY_SKIP = /(^|[\\/])(node_modules|\.next|\.open-next|\.git|\.wrangler|\.turbo|\.naro)([\\/]|$)/;
|
|
@@ -34916,7 +34641,7 @@ async function committedEnvFiles(sourceDir) {
|
|
|
34916
34641
|
if (tab < 0) return [];
|
|
34917
34642
|
const [mode] = entry.slice(0, tab).split(" ");
|
|
34918
34643
|
const path = entry.slice(tab + 1);
|
|
34919
|
-
if (!ENV_FILE.test(
|
|
34644
|
+
if (!ENV_FILE.test(basename2(path)) || COPY_SKIP.test(path)) return [];
|
|
34920
34645
|
if (mode === "100644" || mode === "100755")
|
|
34921
34646
|
return [{ path, symlink: false }];
|
|
34922
34647
|
if (mode === "120000") return [{ path, symlink: true }];
|
|
@@ -34948,14 +34673,14 @@ async function keptOnly(items, keep, remove) {
|
|
|
34948
34673
|
async function readLocal(path) {
|
|
34949
34674
|
const found = await stat3(path).catch(() => null);
|
|
34950
34675
|
if (!found?.isFile()) return null;
|
|
34951
|
-
return
|
|
34676
|
+
return readFile15(path).catch(() => null);
|
|
34952
34677
|
}
|
|
34953
34678
|
async function realAncestor(dir) {
|
|
34954
|
-
for (let current = dir; ; current =
|
|
34679
|
+
for (let current = dir; ; current = dirname5(current)) {
|
|
34955
34680
|
try {
|
|
34956
34681
|
return await realpath3(current);
|
|
34957
34682
|
} catch {
|
|
34958
|
-
if (
|
|
34683
|
+
if (dirname5(current) === current)
|
|
34959
34684
|
throw new Error(`No ancestor of ${dir}`);
|
|
34960
34685
|
}
|
|
34961
34686
|
}
|
|
@@ -34974,7 +34699,7 @@ async function copyWorkingTree(source, checkout) {
|
|
|
34974
34699
|
recursive: true,
|
|
34975
34700
|
// Relative symlinks must stay relative: resolved, they would point
|
|
34976
34701
|
// back into the developer's real tree, and a strategy's temporary
|
|
34977
|
-
// rewrite (
|
|
34702
|
+
// rewrite (the vinext toolchain install) would land there.
|
|
34978
34703
|
verbatimSymlinks: true,
|
|
34979
34704
|
filter: async (src) => {
|
|
34980
34705
|
if (COPY_SKIP.test(src)) return false;
|
|
@@ -34982,7 +34707,7 @@ async function copyWorkingTree(source, checkout) {
|
|
|
34982
34707
|
const entry = await lstat(src);
|
|
34983
34708
|
if (entry.isFIFO() || entry.isSocket() || entry.isCharacterDevice() || entry.isBlockDevice())
|
|
34984
34709
|
return false;
|
|
34985
|
-
if (ENV_FILE.test(
|
|
34710
|
+
if (ENV_FILE.test(basename2(src)) && !entry.isDirectory()) {
|
|
34986
34711
|
inWorkingTree.push(relative6(sourceDir, src).split(sep5).join("/"));
|
|
34987
34712
|
return false;
|
|
34988
34713
|
}
|
|
@@ -34993,7 +34718,7 @@ async function copyWorkingTree(source, checkout) {
|
|
|
34993
34718
|
absoluteLinks.push(path);
|
|
34994
34719
|
return false;
|
|
34995
34720
|
}
|
|
34996
|
-
if (!inside(
|
|
34721
|
+
if (!inside(resolve11(dirname5(src), target2), sourceDir)) {
|
|
34997
34722
|
linksOutside.push(path);
|
|
34998
34723
|
return false;
|
|
34999
34724
|
}
|
|
@@ -35031,21 +34756,21 @@ async function copyWorkingTree(source, checkout) {
|
|
|
35031
34756
|
continue;
|
|
35032
34757
|
}
|
|
35033
34758
|
const target2 = join25(checkout, path);
|
|
35034
|
-
if (!inside(await realAncestor(
|
|
34759
|
+
if (!inside(await realAncestor(dirname5(target2)), root)) {
|
|
35035
34760
|
outsideProject.push(path);
|
|
35036
34761
|
continue;
|
|
35037
34762
|
}
|
|
35038
34763
|
try {
|
|
35039
|
-
await mkdir3(
|
|
34764
|
+
await mkdir3(dirname5(target2), { recursive: true });
|
|
35040
34765
|
} catch {
|
|
35041
34766
|
outsideProject.push(path);
|
|
35042
34767
|
continue;
|
|
35043
34768
|
}
|
|
35044
|
-
await
|
|
34769
|
+
await rm5(target2, { recursive: true, force: true });
|
|
35045
34770
|
const content = await git(sourceDir, ["show", `HEAD:./${path}`]);
|
|
35046
34771
|
if (isLink) {
|
|
35047
34772
|
const linkTarget = content.toString("utf8");
|
|
35048
|
-
const pointsAt =
|
|
34773
|
+
const pointsAt = resolve11(dirname5(target2), linkTarget);
|
|
35049
34774
|
if (isAbsolute4(linkTarget) || !inside(pointsAt, checkout)) {
|
|
35050
34775
|
outsideProject.push(path);
|
|
35051
34776
|
continue;
|
|
@@ -35054,7 +34779,7 @@ async function copyWorkingTree(source, checkout) {
|
|
|
35054
34779
|
envLinks.push(path);
|
|
35055
34780
|
continue;
|
|
35056
34781
|
}
|
|
35057
|
-
await
|
|
34782
|
+
await writeFile6(target2, content, { flag: "wx" });
|
|
35058
34783
|
const local = await readLocal(join25(sourceDir, path));
|
|
35059
34784
|
if (!local || !sameText(local, content)) committedVersion.push(path);
|
|
35060
34785
|
}
|
|
@@ -35149,7 +34874,7 @@ var TtyPrompter = class {
|
|
|
35149
34874
|
});
|
|
35150
34875
|
try {
|
|
35151
34876
|
return await new Promise(
|
|
35152
|
-
(
|
|
34877
|
+
(resolve16) => rl.question(question, resolve16)
|
|
35153
34878
|
);
|
|
35154
34879
|
} finally {
|
|
35155
34880
|
rl.close();
|
|
@@ -35170,7 +34895,7 @@ var TtyPrompter = class {
|
|
|
35170
34895
|
});
|
|
35171
34896
|
try {
|
|
35172
34897
|
const answer = new Promise(
|
|
35173
|
-
(
|
|
34898
|
+
(resolve16) => rl.question(question, resolve16)
|
|
35174
34899
|
);
|
|
35175
34900
|
muted = true;
|
|
35176
34901
|
const value = await answer;
|
|
@@ -35506,7 +35231,7 @@ async function runDbLint(context) {
|
|
|
35506
35231
|
}
|
|
35507
35232
|
|
|
35508
35233
|
// src/functions/deploy.ts
|
|
35509
|
-
import { relative as relative11, resolve as
|
|
35234
|
+
import { relative as relative11, resolve as resolve14, sep as sep10 } from "path";
|
|
35510
35235
|
|
|
35511
35236
|
// ../../packages/functions-bundler/src/errors.ts
|
|
35512
35237
|
var FunctionBundleError = class extends Error {
|
|
@@ -35563,7 +35288,7 @@ var BUNDLE_MESSAGES = {
|
|
|
35563
35288
|
|
|
35564
35289
|
// ../../packages/functions-bundler/src/discover.ts
|
|
35565
35290
|
import { existsSync as existsSync7, readdirSync as readdirSync3, readFileSync as readFileSync8, statSync as statSync2 } from "fs";
|
|
35566
|
-
import { join as join27, relative as relative8, resolve as
|
|
35291
|
+
import { join as join27, relative as relative8, resolve as resolve12, sep as sep6 } from "path";
|
|
35567
35292
|
|
|
35568
35293
|
// ../../packages/functions-bundler/src/limits.ts
|
|
35569
35294
|
var FUNCTION_BUNDLE_MAX_BYTES = 67108864;
|
|
@@ -35585,9 +35310,9 @@ function isEntrypoint(value) {
|
|
|
35585
35310
|
);
|
|
35586
35311
|
}
|
|
35587
35312
|
function functionsFolder(options) {
|
|
35588
|
-
const root =
|
|
35313
|
+
const root = resolve12(options.cwd, options.root ?? ".");
|
|
35589
35314
|
const explicit = options.dir !== void 0;
|
|
35590
|
-
const dir = explicit ?
|
|
35315
|
+
const dir = explicit ? resolve12(options.cwd, options.dir) : join27(root, "naro", "functions");
|
|
35591
35316
|
const label2 = relative8(options.cwd, dir).split(sep6).join("/") || ".";
|
|
35592
35317
|
return { dir, label: label2, root, explicit };
|
|
35593
35318
|
}
|
|
@@ -35706,7 +35431,7 @@ function closesNext(text3, from) {
|
|
|
35706
35431
|
while (i < text3.length && /\s/.test(text3[i] ?? "")) i += 1;
|
|
35707
35432
|
return text3[i] === "}" || text3[i] === "]";
|
|
35708
35433
|
}
|
|
35709
|
-
function
|
|
35434
|
+
function parseJsonc(text3) {
|
|
35710
35435
|
const uncommented = stripComments2(text3);
|
|
35711
35436
|
let out = "";
|
|
35712
35437
|
let inString = false;
|
|
@@ -35767,11 +35492,11 @@ function stripComments2(text3) {
|
|
|
35767
35492
|
}
|
|
35768
35493
|
|
|
35769
35494
|
// ../../packages/functions-bundler/src/node-compat.ts
|
|
35770
|
-
import { createRequire
|
|
35771
|
-
import { dirname as
|
|
35772
|
-
import { fileURLToPath as
|
|
35773
|
-
var require2 =
|
|
35774
|
-
var MODULE_DIR =
|
|
35495
|
+
import { createRequire } from "module";
|
|
35496
|
+
import { dirname as dirname6, resolve as resolvePath } from "path";
|
|
35497
|
+
import { fileURLToPath as fileURLToPath3 } from "url";
|
|
35498
|
+
var require2 = createRequire(import.meta.url);
|
|
35499
|
+
var MODULE_DIR = dirname6(fileURLToPath3(import.meta.url));
|
|
35775
35500
|
var REQUIRED_NODE_BUILT_IN_NAMESPACE = "node-built-in-modules";
|
|
35776
35501
|
var REQUIRED_UNENV_ALIAS_NAMESPACE = "required-unenv-alias";
|
|
35777
35502
|
var SKIPPED_ALIASES = /* @__PURE__ */ new Set(["debug"]);
|
|
@@ -35901,12 +35626,12 @@ ${injects.map(
|
|
|
35901
35626
|
|
|
35902
35627
|
// ../../packages/functions-bundler/src/deno-imports.ts
|
|
35903
35628
|
import { existsSync as existsSync9, readFileSync as readFileSync10, realpathSync as realpathSync2 } from "fs";
|
|
35904
|
-
import { dirname as
|
|
35629
|
+
import { dirname as dirname8, isAbsolute as isAbsolute5, join as join29, relative as relative9, sep as sep8 } from "path";
|
|
35905
35630
|
|
|
35906
35631
|
// ../../packages/functions-bundler/src/import-map.ts
|
|
35907
35632
|
import { existsSync as existsSync8, readFileSync as readFileSync9, realpathSync } from "fs";
|
|
35908
|
-
import { basename as
|
|
35909
|
-
import { fileURLToPath as
|
|
35633
|
+
import { basename as basename3, dirname as dirname7, join as join28, resolve as resolve13, sep as sep7 } from "path";
|
|
35634
|
+
import { fileURLToPath as fileURLToPath4 } from "url";
|
|
35910
35635
|
|
|
35911
35636
|
// ../../packages/functions-bundler/src/printable.ts
|
|
35912
35637
|
var UNPRINTABLE2 = /[\p{Cc}\p{Cf}\p{Zl}\p{Zp}]/gu;
|
|
@@ -35939,7 +35664,7 @@ function expandBareKeys(imports) {
|
|
|
35939
35664
|
function load(file2, label2) {
|
|
35940
35665
|
let parsed;
|
|
35941
35666
|
try {
|
|
35942
|
-
parsed =
|
|
35667
|
+
parsed = parseJsonc(readFileSync9(file2, "utf8"));
|
|
35943
35668
|
} catch {
|
|
35944
35669
|
throw new FunctionBundleError(
|
|
35945
35670
|
"VALIDATION_FAILED",
|
|
@@ -35962,8 +35687,8 @@ function load(file2, label2) {
|
|
|
35962
35687
|
printable2(BUNDLE_MESSAGES.importMapPrefix(label2, key, value))
|
|
35963
35688
|
);
|
|
35964
35689
|
return {
|
|
35965
|
-
imports: DENO_CONFIGS.has(
|
|
35966
|
-
base:
|
|
35690
|
+
imports: DENO_CONFIGS.has(basename3(file2)) ? expandBareKeys(written) : written,
|
|
35691
|
+
base: dirname7(file2),
|
|
35967
35692
|
label: label2
|
|
35968
35693
|
};
|
|
35969
35694
|
}
|
|
@@ -35996,7 +35721,7 @@ var isPathLike = (text3) => text3.startsWith("./") || text3.startsWith("../") ||
|
|
|
35996
35721
|
function filePath(text3) {
|
|
35997
35722
|
if (!text3.startsWith("file:")) return null;
|
|
35998
35723
|
try {
|
|
35999
|
-
return
|
|
35724
|
+
return fileURLToPath4(text3);
|
|
36000
35725
|
} catch {
|
|
36001
35726
|
return null;
|
|
36002
35727
|
}
|
|
@@ -36014,7 +35739,7 @@ function keysOf(map2) {
|
|
|
36014
35739
|
for (const [key, target2] of Object.entries(map2.imports)) {
|
|
36015
35740
|
const trailing = key.endsWith("/");
|
|
36016
35741
|
const file2 = filePath(key);
|
|
36017
|
-
const name = file2 !== null ? realKey(file2, trailing) : isPathLike(key) ? realKey(
|
|
35742
|
+
const name = file2 !== null ? realKey(file2, trailing) : isPathLike(key) ? realKey(resolve13(base2, key), trailing) : key;
|
|
36018
35743
|
if (!keys.has(name)) keys.set(name, target2);
|
|
36019
35744
|
}
|
|
36020
35745
|
normalized.set(map2, keys);
|
|
@@ -36026,10 +35751,10 @@ function mapSpecifier(map2, specifier, importerDir) {
|
|
|
36026
35751
|
const file2 = filePath(specifier);
|
|
36027
35752
|
if (file2 !== null) lookup = realKey(file2, trailing);
|
|
36028
35753
|
else if (specifier.startsWith("/"))
|
|
36029
|
-
lookup = realKey(
|
|
35754
|
+
lookup = realKey(resolve13(specifier), trailing);
|
|
36030
35755
|
else if (isPathLike(specifier)) {
|
|
36031
35756
|
if (importerDir === void 0) return null;
|
|
36032
|
-
lookup = realKey(
|
|
35757
|
+
lookup = realKey(resolve13(importerDir, specifier), trailing);
|
|
36033
35758
|
}
|
|
36034
35759
|
const keys = keysOf(map2);
|
|
36035
35760
|
let target2 = keys.get(lookup);
|
|
@@ -36042,7 +35767,7 @@ function mapSpecifier(map2, specifier, importerDir) {
|
|
|
36042
35767
|
target2 = `${keys.get(prefix) ?? ""}${lookup.slice(prefix.length)}`;
|
|
36043
35768
|
}
|
|
36044
35769
|
if (target2.startsWith("./") || target2.startsWith("../"))
|
|
36045
|
-
return
|
|
35770
|
+
return resolve13(map2.base, target2);
|
|
36046
35771
|
return filePath(target2) ?? target2;
|
|
36047
35772
|
}
|
|
36048
35773
|
|
|
@@ -36122,7 +35847,7 @@ function packageDir(from, projectRoot) {
|
|
|
36122
35847
|
const inNodeModules = fromRoot(projectRoot, current).split("/").includes("node_modules");
|
|
36123
35848
|
if (!inNodeModules && existsSync9(join29(current, "package.json")))
|
|
36124
35849
|
return fromRoot(projectRoot, current) || ".";
|
|
36125
|
-
const up =
|
|
35850
|
+
const up = dirname8(current);
|
|
36126
35851
|
if (up === current) break;
|
|
36127
35852
|
current = up;
|
|
36128
35853
|
}
|
|
@@ -36133,14 +35858,14 @@ function isInstalled(from, pkg) {
|
|
|
36133
35858
|
let current = from;
|
|
36134
35859
|
for (; ; ) {
|
|
36135
35860
|
if (existsSync9(join29(current, "node_modules", pkg))) return true;
|
|
36136
|
-
const up =
|
|
35861
|
+
const up = dirname8(current);
|
|
36137
35862
|
if (up === current) return false;
|
|
36138
35863
|
current = up;
|
|
36139
35864
|
}
|
|
36140
35865
|
}
|
|
36141
35866
|
var NODE_MODULES = /[\\/]node_modules[\\/]/;
|
|
36142
35867
|
function installedVersion(resolved, pkg) {
|
|
36143
|
-
let current =
|
|
35868
|
+
let current = dirname8(resolved);
|
|
36144
35869
|
for (; ; ) {
|
|
36145
35870
|
const file2 = join29(current, "package.json");
|
|
36146
35871
|
if (existsSync9(file2)) {
|
|
@@ -36151,7 +35876,7 @@ function installedVersion(resolved, pkg) {
|
|
|
36151
35876
|
} catch {
|
|
36152
35877
|
}
|
|
36153
35878
|
}
|
|
36154
|
-
const up =
|
|
35879
|
+
const up = dirname8(current);
|
|
36155
35880
|
if (up === current) return null;
|
|
36156
35881
|
current = up;
|
|
36157
35882
|
}
|
|
@@ -36581,7 +36306,7 @@ var FUNCTION_BUSY_WAIT_MS = 5e3;
|
|
|
36581
36306
|
var FUNCTION_RATE_LIMIT_DEFAULT_SECONDS = 60;
|
|
36582
36307
|
var FUNCTION_RATE_LIMIT_MAX_SECONDS = 300;
|
|
36583
36308
|
function defaultSleep(ms) {
|
|
36584
|
-
return new Promise((
|
|
36309
|
+
return new Promise((resolve16) => setTimeout(resolve16, ms));
|
|
36585
36310
|
}
|
|
36586
36311
|
function retryAfterSeconds(error51) {
|
|
36587
36312
|
const value = error51.details?.retryAfter;
|
|
@@ -36778,7 +36503,7 @@ async function deployOne(options, folder, name, importMap, secretNames, io, budg
|
|
|
36778
36503
|
}
|
|
36779
36504
|
function readFlagImportMap(options, folder) {
|
|
36780
36505
|
if (options.importMap === void 0) return void 0;
|
|
36781
|
-
const file2 =
|
|
36506
|
+
const file2 = resolve14(options.cwd, options.importMap);
|
|
36782
36507
|
try {
|
|
36783
36508
|
return readImportMapFile(
|
|
36784
36509
|
file2,
|
|
@@ -36896,7 +36621,7 @@ function eventsObserver(cp3, deploymentId, token, fetchImpl = fetch, logIngestUr
|
|
|
36896
36621
|
} catch (error51) {
|
|
36897
36622
|
lastError = error51;
|
|
36898
36623
|
await new Promise(
|
|
36899
|
-
(
|
|
36624
|
+
(resolve16) => setTimeout(resolve16, 500 * (attempt + 1))
|
|
36900
36625
|
);
|
|
36901
36626
|
}
|
|
36902
36627
|
}
|
|
@@ -36972,19 +36697,19 @@ function slugify2(value) {
|
|
|
36972
36697
|
async function projectName(sourceDir) {
|
|
36973
36698
|
try {
|
|
36974
36699
|
const pkg = JSON.parse(
|
|
36975
|
-
await
|
|
36700
|
+
await readFile16(join31(sourceDir, "package.json"), "utf8")
|
|
36976
36701
|
);
|
|
36977
36702
|
if (pkg.name) return pkg.name;
|
|
36978
36703
|
} catch {
|
|
36979
36704
|
}
|
|
36980
|
-
return
|
|
36705
|
+
return basename4(sourceDir);
|
|
36981
36706
|
}
|
|
36982
36707
|
function resolveBin(name) {
|
|
36983
|
-
let dir =
|
|
36708
|
+
let dir = dirname9(fileURLToPath5(import.meta.url));
|
|
36984
36709
|
for (; ; ) {
|
|
36985
36710
|
const candidate = join31(dir, "node_modules", ".bin", name);
|
|
36986
36711
|
if (existsSync10(candidate)) return candidate;
|
|
36987
|
-
const parent =
|
|
36712
|
+
const parent = dirname9(dir);
|
|
36988
36713
|
if (parent === dir) return name;
|
|
36989
36714
|
dir = parent;
|
|
36990
36715
|
}
|
|
@@ -37050,7 +36775,7 @@ function workingTreeNotices(copy) {
|
|
|
37050
36775
|
function localDependencies(sourceDir, say = () => void 0) {
|
|
37051
36776
|
return {
|
|
37052
36777
|
createWorkspace: () => mkdtemp2(join31(tmpdir2(), "naro-build-")),
|
|
37053
|
-
removeWorkspace: (path) =>
|
|
36778
|
+
removeWorkspace: (path) => rm6(path, { recursive: true, force: true }),
|
|
37054
36779
|
async runCommand(spec, observer) {
|
|
37055
36780
|
if (spec.command === "git" && spec.args[0] === "clone") {
|
|
37056
36781
|
const checkout = spec.args.at(-1);
|
|
@@ -37075,9 +36800,6 @@ function localDependencies(sourceDir, say = () => void 0) {
|
|
|
37075
36800
|
detectFramework,
|
|
37076
36801
|
readStaticArtifact,
|
|
37077
36802
|
createPackageManagerConfig,
|
|
37078
|
-
createPlatformBuildConfig,
|
|
37079
|
-
readOpenNextArtifact,
|
|
37080
|
-
openNextCommand: resolveBin("opennextjs-cloudflare"),
|
|
37081
36803
|
wranglerCommand: resolveBin("wrangler"),
|
|
37082
36804
|
// `vinext check` runs on the bare checkout, before the toolchain is added
|
|
37083
36805
|
// to the user's tree, so this binary has to come from the CLI's own deps.
|
|
@@ -37099,7 +36821,7 @@ async function deployDirectory(sourceDir, options, log2) {
|
|
|
37099
36821
|
"Pass production: true for production; preview is the default."
|
|
37100
36822
|
);
|
|
37101
36823
|
const surface = production ? "production" : environment ?? "preview";
|
|
37102
|
-
const appRoot = options.rootDirectory ?
|
|
36824
|
+
const appRoot = options.rootDirectory ? resolve15(sourceDir, options.rootDirectory) : sourceDir;
|
|
37103
36825
|
const framework = detectFramework2(appRoot);
|
|
37104
36826
|
if (!framework.deployable && !options.force) {
|
|
37105
36827
|
throw new NaroError(
|
|
@@ -37187,6 +36909,19 @@ async function deployDirectory(sourceDir, options, log2) {
|
|
|
37187
36909
|
});
|
|
37188
36910
|
if (ctx.envSkipped?.length)
|
|
37189
36911
|
log2(`\u26A0 skipped env: ${ctx.envSkipped.join(", ")}`);
|
|
36912
|
+
const storedAdapter = ctx.userAdapter ?? null;
|
|
36913
|
+
if (options.userAdapter && options.userAdapter !== storedAdapter) {
|
|
36914
|
+
try {
|
|
36915
|
+
await client.projects.update(ctx.projectId, {
|
|
36916
|
+
userAdapter: options.userAdapter
|
|
36917
|
+
});
|
|
36918
|
+
} catch (error51) {
|
|
36919
|
+
log2(
|
|
36920
|
+
`\u26A0 Could not save the Next.js adapter choice: ${error51 instanceof Error ? error51.message : String(error51)}`
|
|
36921
|
+
);
|
|
36922
|
+
}
|
|
36923
|
+
}
|
|
36924
|
+
if (options.userAdapter) log2(userAdapterOutcome(options.userAdapter));
|
|
37190
36925
|
const executor = options.executor ?? new LocalBuildExecutor(localDependencies(sourceDir, log2));
|
|
37191
36926
|
const observer = eventsObserver(
|
|
37192
36927
|
cpUrl,
|
|
@@ -37215,7 +36950,8 @@ async function deployDirectory(sourceDir, options, log2) {
|
|
|
37215
36950
|
// one, as before.
|
|
37216
36951
|
env: ctx.environment ? { ...envToSend, ...ctx.env } : { ...ctx.env, ...envToSend },
|
|
37217
36952
|
strategy: ctx.strategy ?? null,
|
|
37218
|
-
...ctx.vinextEnabled === void 0 ? {} : { vinextEnabled: ctx.vinextEnabled }
|
|
36953
|
+
...ctx.vinextEnabled === void 0 ? {} : { vinextEnabled: ctx.vinextEnabled },
|
|
36954
|
+
...options.userAdapter ?? storedAdapter ? { userAdapter: options.userAdapter ?? storedAdapter } : {}
|
|
37219
36955
|
},
|
|
37220
36956
|
observer,
|
|
37221
36957
|
createCacheTransport({
|
|
@@ -37397,6 +37133,13 @@ export {
|
|
|
37397
37133
|
promptForMissingEnv,
|
|
37398
37134
|
pullEnv,
|
|
37399
37135
|
detectGitInfo,
|
|
37136
|
+
detectUserAdapter,
|
|
37137
|
+
parseUserAdapter,
|
|
37138
|
+
USER_ADAPTER_OPTIONS,
|
|
37139
|
+
userAdapterQuestion,
|
|
37140
|
+
userAdapterStored,
|
|
37141
|
+
userAdapterUnasked,
|
|
37142
|
+
userAdapterUnreadable,
|
|
37400
37143
|
version2 as version,
|
|
37401
37144
|
DATA_ENV_MESSAGES,
|
|
37402
37145
|
dataEnvironment,
|
|
@@ -37426,7 +37169,7 @@ export {
|
|
|
37426
37169
|
runDbLint,
|
|
37427
37170
|
BUNDLE_MESSAGES,
|
|
37428
37171
|
functionsFolder,
|
|
37429
|
-
|
|
37172
|
+
parseJsonc,
|
|
37430
37173
|
defaultSleep,
|
|
37431
37174
|
retryAfterSeconds,
|
|
37432
37175
|
withFunctionRetries,
|