naro-cli 0.27.0 → 0.29.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 +61 -7
- package/dist/args.d.ts +2 -0
- package/dist/artifact-types.d.ts +1 -1
- package/dist/{chunk-UGJFIEH7.js → chunk-BAP7PHBF.js} +847 -910
- package/dist/deploy.d.ts +11 -2
- package/dist/deploy.js +7 -1
- package/dist/index.js +244 -33
- 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\-._~%!$&()*+,;=:@/[\]]*$/;
|
|
@@ -306,6 +306,9 @@ function sanitizeRoutes(value) {
|
|
|
306
306
|
return JSON.stringify(routes).length > MAX_ROUTE_LIST_BYTES ? void 0 : routes;
|
|
307
307
|
}
|
|
308
308
|
|
|
309
|
+
// ../../packages/core/src/static-assets.ts
|
|
310
|
+
var IMMUTABLE_CACHE_CONTROL = "public, max-age=31536000, immutable";
|
|
311
|
+
|
|
309
312
|
// ../../packages/core/src/artifact-manifest.ts
|
|
310
313
|
var MAX_FILE_BYTES = 25 * 1024 * 1024;
|
|
311
314
|
var MAX_ARTIFACT_BYTES = 64 * 1024 * 1024;
|
|
@@ -527,7 +530,10 @@ var CAPABILITIES = [
|
|
|
527
530
|
id: "team-usage",
|
|
528
531
|
domain: "teams",
|
|
529
532
|
title: "\uD300 \uC0AC\uC6A9\uB7C9",
|
|
530
|
-
routes: [
|
|
533
|
+
routes: [
|
|
534
|
+
"GET teams/[teamSlug]/usage",
|
|
535
|
+
"GET teams/[teamSlug]/usage/hosting"
|
|
536
|
+
],
|
|
531
537
|
ui: { kind: "built" },
|
|
532
538
|
cli: { kind: "built", commands: ["naro usage"] },
|
|
533
539
|
mcp: { kind: "built", tools: ["get_team_usage"] }
|
|
@@ -1873,6 +1879,19 @@ var CAPABILITIES = [
|
|
|
1873
1879
|
cli: { kind: "built", commands: ["naro backend"] },
|
|
1874
1880
|
mcp: { kind: "built", tools: ["get_backend"] }
|
|
1875
1881
|
},
|
|
1882
|
+
{
|
|
1883
|
+
id: "backend-usage",
|
|
1884
|
+
domain: "backend",
|
|
1885
|
+
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)",
|
|
1886
|
+
routes: ["GET projects/[projectId]/backend/usage"],
|
|
1887
|
+
ui: { kind: "built" },
|
|
1888
|
+
// 같은 숫자를 섹션마다 이미 돌려준다: naro db info(오늘 쓴 행·한도), naro
|
|
1889
|
+
// storage(용량·오늘 쓰기), naro functions(함수별 오늘 호출), naro realtime
|
|
1890
|
+
// (이번 달 메시지). 이 라우트는 개요가 한 번에 읽으려고 모은 것이다.
|
|
1891
|
+
cli: { kind: "built" },
|
|
1892
|
+
// get_database·get_storage·list_functions·get_realtime이 같은 숫자를 준다.
|
|
1893
|
+
mcp: { kind: "built" }
|
|
1894
|
+
},
|
|
1876
1895
|
{
|
|
1877
1896
|
id: "backend-enable",
|
|
1878
1897
|
domain: "backend",
|
|
@@ -2248,7 +2267,7 @@ function parseDotenvDetailed(text3) {
|
|
|
2248
2267
|
var STALL_WINDOW_MS = 10 * 6e4;
|
|
2249
2268
|
|
|
2250
2269
|
// ../../packages/core/src/deployment-strategy.ts
|
|
2251
|
-
var MIN_SUPPORTED_NEXT_MAJOR =
|
|
2270
|
+
var MIN_SUPPORTED_NEXT_MAJOR = 16;
|
|
2252
2271
|
|
|
2253
2272
|
// ../../packages/core/src/environment-guidance.ts
|
|
2254
2273
|
var DATA_COMMANDS = /* @__PURE__ */ new Set([
|
|
@@ -2495,12 +2514,20 @@ var DEPLOYMENT_ERROR_CODES = [
|
|
|
2495
2514
|
"DATABASE_FULL",
|
|
2496
2515
|
/** Usage limits spec 2026-10-18 §6: a hobby team created its 100 deployments this UTC month. */
|
|
2497
2516
|
"USAGE_LIMIT_REACHED",
|
|
2517
|
+
/** Hobby: another limit (requests, D1, Storage, Functions, Realtime) is reached, so new builds wait (spec 2026-11-07-hobby-any-limit-blocks-build). */
|
|
2518
|
+
"BUILDS_PAUSED",
|
|
2498
2519
|
/** A hobby team has its 3 projects; no project can be added. */
|
|
2499
2520
|
"PROJECT_LIMIT_REACHED",
|
|
2500
2521
|
/** A hobby team has its 1 member; no member or invite can be added. */
|
|
2501
2522
|
"MEMBER_LIMIT_REACHED",
|
|
2502
|
-
/**
|
|
2523
|
+
/**
|
|
2524
|
+
* Custom domains were not part of the Hobby plan. No longer answered since
|
|
2525
|
+
* 202611070030 (one domain per hobby project); kept so an older client
|
|
2526
|
+
* still names it.
|
|
2527
|
+
*/
|
|
2503
2528
|
"PLAN_DOMAINS_NOT_INCLUDED",
|
|
2529
|
+
/** A hobby project has its 1 custom domain (with its www form); no other can be added. */
|
|
2530
|
+
"PLAN_DOMAIN_LIMIT_REACHED",
|
|
2504
2531
|
/** Named environments (spec 2026-10-18-named-environments §15): the name is not lowercase letters, digits and single hyphens, or is over 20 characters. */
|
|
2505
2532
|
"ENVIRONMENT_NAME_INVALID",
|
|
2506
2533
|
/** `production` and `preview` are reserved names. */
|
|
@@ -17551,7 +17578,7 @@ var REQUESTS = {
|
|
|
17551
17578
|
subject100: (team) => `${team} has reached its monthly request limit`,
|
|
17552
17579
|
usage: (team, used, limit, month) => `${team} has used ${used} of the ${limit} requests the Hobby plan includes for ${month}.`,
|
|
17553
17580
|
warning: "When it reaches the limit, requests past it may be blocked until the month ends (UTC).",
|
|
17554
|
-
blocked: "Sites on this team
|
|
17581
|
+
blocked: "Sites on this team are blocked (HTTP 403 or 503) until the month ends (UTC).",
|
|
17555
17582
|
running: "Sites keep running for now.",
|
|
17556
17583
|
button: "View usage",
|
|
17557
17584
|
footer: (team) => `You're receiving this because you're an owner or billing member of ${team} on Naro.`
|
|
@@ -17561,7 +17588,7 @@ var REQUESTS = {
|
|
|
17561
17588
|
subject100: (team) => `${team} \uD300\uC774 \uC774\uBC88 \uB2EC \uC694\uCCAD \uD55C\uB3C4\uC5D0 \uB3C4\uB2EC\uD588\uC2B5\uB2C8\uB2E4`,
|
|
17562
17589
|
usage: (team, used, limit, month) => `${team} \uD300\uC774 ${month} Hobby \uD50C\uB79C\uC5D0 \uD3EC\uD568\uB41C \uC694\uCCAD ${limit}\uAC74 \uC911 ${used}\uAC74\uC744 \uC37C\uC2B5\uB2C8\uB2E4.`,
|
|
17563
17590
|
warning: "\uD55C\uB3C4\uC5D0 \uB3C4\uB2EC\uD558\uBA74 \uC774\uBC88 \uB2EC\uC774 \uB05D\uB0A0 \uB54C\uAE4C\uC9C0(UTC) \uADF8 \uB4A4 \uC694\uCCAD\uC774 \uB9C9\uD790 \uC218 \uC788\uC2B5\uB2C8\uB2E4.",
|
|
17564
|
-
blocked: "\uC774\uBC88 \uB2EC\uC774 \uB05D\uB0A0 \uB54C\uAE4C\uC9C0(UTC) \uC774 \uD300\uC758 \uC0AC\uC774\uD2B8\uB294
|
|
17591
|
+
blocked: "\uC774\uBC88 \uB2EC\uC774 \uB05D\uB0A0 \uB54C\uAE4C\uC9C0(UTC) \uC774 \uD300\uC758 \uC0AC\uC774\uD2B8\uB294 \uC694\uCCAD\uC744 \uB9C9\uC2B5\uB2C8\uB2E4(HTTP 403 \uB610\uB294 503).",
|
|
17565
17592
|
running: "\uC9C0\uAE08\uC740 \uC0AC\uC774\uD2B8\uAC00 \uACC4\uC18D \uB3D9\uC791\uD569\uB2C8\uB2E4.",
|
|
17566
17593
|
button: "\uC0AC\uC6A9\uB7C9 \uBCF4\uAE30",
|
|
17567
17594
|
footer: (team) => `Naro\uC5D0\uC11C ${team} \uD300\uC758 owner \uB610\uB294 billing \uC5ED\uD560\uC774\uB77C \uC774 \uBA54\uC77C\uC744 \uBC1B\uC558\uC2B5\uB2C8\uB2E4.`
|
|
@@ -17571,7 +17598,7 @@ var REQUESTS = {
|
|
|
17571
17598
|
subject100: (team) => `${team} \u30C1\u30FC\u30E0\u304C\u4ECA\u6708\u306E\u30EA\u30AF\u30A8\u30B9\u30C8\u4E0A\u9650\u306B\u9054\u3057\u307E\u3057\u305F`,
|
|
17572
17599
|
usage: (team, used, limit, month) => `${team} \u30C1\u30FC\u30E0\u306F ${month} \u306E Hobby \u30D7\u30E9\u30F3\u306B\u542B\u307E\u308C\u308B ${limit} \u30EA\u30AF\u30A8\u30B9\u30C8\u306E\u3046\u3061 ${used} \u3092\u4F7F\u7528\u3057\u307E\u3057\u305F\u3002`,
|
|
17573
17600
|
warning: "\u4E0A\u9650\u306B\u9054\u3059\u308B\u3068\u3001\u6708\u672B(UTC)\u307E\u3067\u4EE5\u964D\u306E\u30EA\u30AF\u30A8\u30B9\u30C8\u304C\u30D6\u30ED\u30C3\u30AF\u3055\u308C\u308B\u5834\u5408\u304C\u3042\u308A\u307E\u3059\u3002",
|
|
17574
|
-
blocked: "\u6708\u672B(UTC)\u307E\u3067\u3001\u3053\u306E\u30C1\u30FC\u30E0\u306E\u30B5\u30A4\u30C8\
|
|
17601
|
+
blocked: "\u6708\u672B(UTC)\u307E\u3067\u3001\u3053\u306E\u30C1\u30FC\u30E0\u306E\u30B5\u30A4\u30C8\u306F\u30EA\u30AF\u30A8\u30B9\u30C8\u3092\u62D2\u5426\u3057\u307E\u3059(HTTP 403 \u307E\u305F\u306F 503)\u3002",
|
|
17575
17602
|
running: "\u73FE\u5728\u3001\u30B5\u30A4\u30C8\u306F\u5F15\u304D\u7D9A\u304D\u52D5\u4F5C\u3057\u3066\u3044\u307E\u3059\u3002",
|
|
17576
17603
|
button: "\u4F7F\u7528\u91CF\u3092\u898B\u308B",
|
|
17577
17604
|
footer: (team) => `Naro \u3067 ${team} \u30C1\u30FC\u30E0\u306E owner \u307E\u305F\u306F billing \u30ED\u30FC\u30EB\u306E\u305F\u3081\u3001\u3053\u306E\u30E1\u30FC\u30EB\u3092\u304A\u9001\u308A\u3057\u3066\u3044\u307E\u3059\u3002`
|
|
@@ -17610,6 +17637,187 @@ var BUILDS = {
|
|
|
17610
17637
|
}
|
|
17611
17638
|
};
|
|
17612
17639
|
|
|
17640
|
+
// ../../packages/next-adapter/src/index.ts
|
|
17641
|
+
import { fileURLToPath } from "url";
|
|
17642
|
+
|
|
17643
|
+
// ../../packages/next-adapter/src/supported.ts
|
|
17644
|
+
var SUPPORTED_NEXT = [
|
|
17645
|
+
{ minor: "16.2", next: "16.2.12", routing: "@next/routing-16.2" },
|
|
17646
|
+
{ minor: "16.3", next: "16.3.8", routing: "@next/routing-16.3" },
|
|
17647
|
+
{ minor: "16.4", next: "16.4.5", routing: "@next/routing-16.4" }
|
|
17648
|
+
];
|
|
17649
|
+
var VERSION = /^(\d+)\.(\d+)\.(\d+)/;
|
|
17650
|
+
function judgeNextVersion(version3) {
|
|
17651
|
+
const match = VERSION.exec(version3.trim());
|
|
17652
|
+
if (!match) return null;
|
|
17653
|
+
const major = Number(match[1]);
|
|
17654
|
+
const minor = Number(match[2]);
|
|
17655
|
+
if (major < 16 || major === 16 && minor < 2) return { kind: "too-old" };
|
|
17656
|
+
const entry = SUPPORTED_NEXT.find(
|
|
17657
|
+
(candidate) => candidate.minor === `${String(major)}.${String(minor)}`
|
|
17658
|
+
);
|
|
17659
|
+
if (entry) return { kind: "supported", entry };
|
|
17660
|
+
const newest = SUPPORTED_NEXT[SUPPORTED_NEXT.length - 1];
|
|
17661
|
+
if (!newest) throw new Error("SUPPORTED_NEXT is empty.");
|
|
17662
|
+
return { kind: "newer", entry: newest };
|
|
17663
|
+
}
|
|
17664
|
+
function testedRange() {
|
|
17665
|
+
const first = SUPPORTED_NEXT[0];
|
|
17666
|
+
const last = SUPPORTED_NEXT[SUPPORTED_NEXT.length - 1];
|
|
17667
|
+
if (!first || !last) throw new Error("SUPPORTED_NEXT is empty.");
|
|
17668
|
+
return `${first.minor}\u2013${last.minor}`;
|
|
17669
|
+
}
|
|
17670
|
+
|
|
17671
|
+
// ../../packages/next-adapter/src/paths.ts
|
|
17672
|
+
var OUTPUT_DIR = ".naro";
|
|
17673
|
+
var BUILD_RECORD = ".naro/build.json";
|
|
17674
|
+
var WORKER_DIR = ".naro/worker";
|
|
17675
|
+
var ASSETS_DIR = ".naro/assets";
|
|
17676
|
+
var WRANGLER_CONFIG = ".naro/worker/wrangler.jsonc";
|
|
17677
|
+
|
|
17678
|
+
// ../../packages/next-adapter/src/bundle/wrangler.ts
|
|
17679
|
+
import { posix } from "path";
|
|
17680
|
+
|
|
17681
|
+
// ../../packages/next-adapter/src/config-wrapper.ts
|
|
17682
|
+
import { access, readFile as readFile2, rename, writeFile as writeFile2 } from "fs/promises";
|
|
17683
|
+
import { join as join2 } from "path";
|
|
17684
|
+
var PROJECT_CONFIG_BASENAME = "next.config.naro-user";
|
|
17685
|
+
var WRAPPABLE = {
|
|
17686
|
+
"next.config.js": {
|
|
17687
|
+
wrapper: "next.config.mjs",
|
|
17688
|
+
specifier: `./${PROJECT_CONFIG_BASENAME}.js`,
|
|
17689
|
+
typescript: false
|
|
17690
|
+
},
|
|
17691
|
+
"next.config.mjs": {
|
|
17692
|
+
wrapper: "next.config.mjs",
|
|
17693
|
+
specifier: `./${PROJECT_CONFIG_BASENAME}.mjs`,
|
|
17694
|
+
typescript: false
|
|
17695
|
+
},
|
|
17696
|
+
"next.config.ts": {
|
|
17697
|
+
wrapper: "next.config.ts",
|
|
17698
|
+
specifier: `./${PROJECT_CONFIG_BASENAME}`,
|
|
17699
|
+
typescript: true
|
|
17700
|
+
},
|
|
17701
|
+
"next.config.mts": {
|
|
17702
|
+
wrapper: "next.config.mts",
|
|
17703
|
+
specifier: `./${PROJECT_CONFIG_BASENAME}.mts`,
|
|
17704
|
+
typescript: true
|
|
17705
|
+
}
|
|
17706
|
+
};
|
|
17707
|
+
function nextConfigWrapperSource(projectSpecifier, typescript) {
|
|
17708
|
+
return `${typescript ? "// @ts-nocheck\n" : ""}// Written by Naro for this build only. The project's own next.config is
|
|
17709
|
+
// ${projectSpecifier}, unchanged; this wrapper swaps its Next.js adapter for
|
|
17710
|
+
// the Naro adapter (project setting "replace").
|
|
17711
|
+
import projectConfig from ${JSON.stringify(projectSpecifier)};
|
|
17712
|
+
|
|
17713
|
+
export default async function naroNextConfig(phase, context) {
|
|
17714
|
+
const config =
|
|
17715
|
+
typeof projectConfig === "function"
|
|
17716
|
+
? await projectConfig(phase, context)
|
|
17717
|
+
: await projectConfig;
|
|
17718
|
+
const rest = { ...(config ?? {}) };
|
|
17719
|
+
delete rest.adapterPath;
|
|
17720
|
+
if (rest.experimental && typeof rest.experimental === "object") {
|
|
17721
|
+
rest.experimental = { ...rest.experimental };
|
|
17722
|
+
delete rest.experimental.adapterPath;
|
|
17723
|
+
}
|
|
17724
|
+
return { ...rest, adapterPath: process.env.NEXT_ADAPTER_PATH };
|
|
17725
|
+
}
|
|
17726
|
+
`;
|
|
17727
|
+
}
|
|
17728
|
+
async function exists(path) {
|
|
17729
|
+
try {
|
|
17730
|
+
await access(path);
|
|
17731
|
+
return true;
|
|
17732
|
+
} catch {
|
|
17733
|
+
return false;
|
|
17734
|
+
}
|
|
17735
|
+
}
|
|
17736
|
+
async function wrapNextConfig(appRoot, file2) {
|
|
17737
|
+
const plan = WRAPPABLE[file2];
|
|
17738
|
+
if (!plan) return null;
|
|
17739
|
+
const ext = file2.slice("next.config.".length);
|
|
17740
|
+
const project2 = `${PROJECT_CONFIG_BASENAME}.${ext}`;
|
|
17741
|
+
if (await exists(join2(appRoot, project2)))
|
|
17742
|
+
throw new Error(
|
|
17743
|
+
`${project2} already exists in the project; Naro needs that name to replace the project's Next.js adapter.`
|
|
17744
|
+
);
|
|
17745
|
+
await readFile2(join2(appRoot, file2));
|
|
17746
|
+
await rename(join2(appRoot, file2), join2(appRoot, project2));
|
|
17747
|
+
await writeFile2(
|
|
17748
|
+
join2(appRoot, plan.wrapper),
|
|
17749
|
+
nextConfigWrapperSource(plan.specifier, plan.typescript)
|
|
17750
|
+
);
|
|
17751
|
+
return { wrapper: plan.wrapper, project: project2 };
|
|
17752
|
+
}
|
|
17753
|
+
function assetPrefixWrapperSource(projectSpecifier, typescript) {
|
|
17754
|
+
return `${typescript ? "// @ts-nocheck\n" : ""}// Written by Naro for this build only. The project's own next.config is
|
|
17755
|
+
// ${projectSpecifier}, unchanged; this wrapper serves _next/static from
|
|
17756
|
+
// Naro's CDN unless the project sets its own assetPrefix.
|
|
17757
|
+
import projectConfig from ${JSON.stringify(projectSpecifier)};
|
|
17758
|
+
|
|
17759
|
+
export default async function naroNextConfig(phase, context) {
|
|
17760
|
+
const config =
|
|
17761
|
+
typeof projectConfig === "function"
|
|
17762
|
+
? await projectConfig(phase, context)
|
|
17763
|
+
: await projectConfig;
|
|
17764
|
+
const rest = { ...(config ?? {}) };
|
|
17765
|
+
return {
|
|
17766
|
+
...rest,
|
|
17767
|
+
assetPrefix: rest.assetPrefix || process.env.NARO_STATIC_ASSET_PREFIX,
|
|
17768
|
+
};
|
|
17769
|
+
}
|
|
17770
|
+
`;
|
|
17771
|
+
}
|
|
17772
|
+
var ASSET_PREFIX_ONLY_CONFIG = `// Written by Naro for this build only: the project has no next.config.
|
|
17773
|
+
export default { assetPrefix: process.env.NARO_STATIC_ASSET_PREFIX };
|
|
17774
|
+
`;
|
|
17775
|
+
var CONFIG_LOOKUP = [
|
|
17776
|
+
"next.config.js",
|
|
17777
|
+
"next.config.mjs",
|
|
17778
|
+
"next.config.ts",
|
|
17779
|
+
"next.config.mts",
|
|
17780
|
+
"next.config.cjs"
|
|
17781
|
+
];
|
|
17782
|
+
async function wrapNextConfigForAssetPrefix(appRoot, prefix) {
|
|
17783
|
+
if (!prefix) return "skipped";
|
|
17784
|
+
let file2;
|
|
17785
|
+
for (const name of CONFIG_LOOKUP)
|
|
17786
|
+
if (await exists(join2(appRoot, name))) {
|
|
17787
|
+
file2 = name;
|
|
17788
|
+
break;
|
|
17789
|
+
}
|
|
17790
|
+
if (!file2) {
|
|
17791
|
+
await writeFile2(join2(appRoot, "next.config.mjs"), ASSET_PREFIX_ONLY_CONFIG);
|
|
17792
|
+
return "created";
|
|
17793
|
+
}
|
|
17794
|
+
const plan = WRAPPABLE[file2];
|
|
17795
|
+
if (!plan) return "skipped";
|
|
17796
|
+
const project2 = `${PROJECT_CONFIG_BASENAME}.${file2.slice("next.config.".length)}`;
|
|
17797
|
+
if (await exists(join2(appRoot, project2))) return "skipped";
|
|
17798
|
+
await rename(join2(appRoot, file2), join2(appRoot, project2));
|
|
17799
|
+
try {
|
|
17800
|
+
await writeFile2(
|
|
17801
|
+
join2(appRoot, plan.wrapper),
|
|
17802
|
+
assetPrefixWrapperSource(plan.specifier, plan.typescript)
|
|
17803
|
+
);
|
|
17804
|
+
} catch (error51) {
|
|
17805
|
+
await rename(join2(appRoot, project2), join2(appRoot, file2));
|
|
17806
|
+
throw error51;
|
|
17807
|
+
}
|
|
17808
|
+
return "wrapped";
|
|
17809
|
+
}
|
|
17810
|
+
|
|
17811
|
+
// ../../packages/next-adapter/src/index.ts
|
|
17812
|
+
function nextAdapterPath(base2 = import.meta.url) {
|
|
17813
|
+
if (!base2) return void 0;
|
|
17814
|
+
try {
|
|
17815
|
+
return fileURLToPath(new URL("../dist/adapter.cjs", base2));
|
|
17816
|
+
} catch {
|
|
17817
|
+
return void 0;
|
|
17818
|
+
}
|
|
17819
|
+
}
|
|
17820
|
+
|
|
17613
17821
|
// ../../packages/build/src/next-version.ts
|
|
17614
17822
|
var NEXT_RELEASE_DATES = {
|
|
17615
17823
|
16: "2025-10-21",
|
|
@@ -17619,7 +17827,6 @@ var NEXT_RELEASE_DATES = {
|
|
|
17619
17827
|
12: "2021-10-26"
|
|
17620
17828
|
};
|
|
17621
17829
|
var SUPPORT_WINDOW_YEARS = 2;
|
|
17622
|
-
var VERIFIED_15_FLOOR = { major: 15, minor: 5, patch: 21 };
|
|
17623
17830
|
var VERIFIED_16_FLOOR = { major: 16, minor: 2, patch: 11 };
|
|
17624
17831
|
function parseNextVersion(raw) {
|
|
17625
17832
|
const match = /^\s*(\d+)\.(\d+)\.(\d+)/.exec(raw);
|
|
@@ -17647,7 +17854,6 @@ function compare(a, b) {
|
|
|
17647
17854
|
return a.major - b.major || a.minor - b.minor || a.patch - b.patch;
|
|
17648
17855
|
}
|
|
17649
17856
|
function withinVerifiedRange(version3) {
|
|
17650
|
-
if (version3.major === 15) return compare(version3, VERIFIED_15_FLOOR) >= 0;
|
|
17651
17857
|
if (version3.major === 16) return compare(version3, VERIFIED_16_FLOOR) >= 0;
|
|
17652
17858
|
return version3.major > 16;
|
|
17653
17859
|
}
|
|
@@ -17663,34 +17869,34 @@ function classifyNextVersion(raw, now) {
|
|
|
17663
17869
|
reason: `Could not read a Next.js version from "${raw}".`
|
|
17664
17870
|
};
|
|
17665
17871
|
}
|
|
17666
|
-
|
|
17667
|
-
if (!windowEnd || version3.major < VERIFIED_15_FLOOR.major) {
|
|
17872
|
+
if (version3.major < MIN_SUPPORTED_NEXT_MAJOR) {
|
|
17668
17873
|
return {
|
|
17669
17874
|
status: "too-old",
|
|
17670
17875
|
version: version3,
|
|
17671
|
-
reason: `Next.js ${raw} is too old to deploy. Naro deploys Next.js
|
|
17876
|
+
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.`
|
|
17672
17877
|
};
|
|
17673
17878
|
}
|
|
17674
|
-
|
|
17879
|
+
const windowEnd = supportEndsAt(version3.major);
|
|
17880
|
+
if (windowEnd && now > windowEnd) {
|
|
17675
17881
|
return {
|
|
17676
|
-
status: "
|
|
17882
|
+
status: "past-support-window",
|
|
17677
17883
|
version: version3,
|
|
17678
|
-
reason: `Next.js ${version3.major} left its support window on ${formatDate(windowEnd)}. The build continues, but unsupported releases stop receiving security patches \u2014 upgrade
|
|
17884
|
+
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`
|
|
17679
17885
|
};
|
|
17680
17886
|
}
|
|
17681
17887
|
if (!withinVerifiedRange(version3)) {
|
|
17682
17888
|
return {
|
|
17683
|
-
status: "outside-
|
|
17889
|
+
status: "outside-verified-range",
|
|
17684
17890
|
version: version3,
|
|
17685
|
-
reason: `Next.js ${raw} is outside the range Naro verifies deploys on (>=
|
|
17891
|
+
reason: `Next.js ${raw} is outside the range Naro verifies deploys on (>=16.2.11). The build may fail in ways Naro cannot explain.`
|
|
17686
17892
|
};
|
|
17687
17893
|
}
|
|
17688
17894
|
return { status: "supported", version: version3, reason: "" };
|
|
17689
17895
|
}
|
|
17690
17896
|
|
|
17691
17897
|
// ../../packages/build/src/package-manager.ts
|
|
17692
|
-
import { access, readFile as
|
|
17693
|
-
import { join as
|
|
17898
|
+
import { access as access2, readFile as readFile3 } from "fs/promises";
|
|
17899
|
+
import { join as join3 } from "path";
|
|
17694
17900
|
function cacheEnv(dir, manager) {
|
|
17695
17901
|
return {
|
|
17696
17902
|
...manager === "pnpm" ? { npm_config_store_dir: dir } : {},
|
|
@@ -17710,9 +17916,9 @@ function withSharedCache(spec, dir) {
|
|
|
17710
17916
|
addEnv: { ...spec.addEnv, ...cacheEnv(dir, spec.name) }
|
|
17711
17917
|
};
|
|
17712
17918
|
}
|
|
17713
|
-
async function
|
|
17919
|
+
async function exists2(path) {
|
|
17714
17920
|
try {
|
|
17715
|
-
await
|
|
17921
|
+
await access2(path);
|
|
17716
17922
|
return true;
|
|
17717
17923
|
} catch {
|
|
17718
17924
|
return false;
|
|
@@ -17720,7 +17926,7 @@ async function exists(path) {
|
|
|
17720
17926
|
}
|
|
17721
17927
|
async function usesModernYarn(root) {
|
|
17722
17928
|
try {
|
|
17723
|
-
const raw = await
|
|
17929
|
+
const raw = await readFile3(join3(root, "package.json"), "utf8");
|
|
17724
17930
|
const packageJson = JSON.parse(raw);
|
|
17725
17931
|
if (typeof packageJson.packageManager !== "string") return false;
|
|
17726
17932
|
const version3 = /^yarn@(\d+)/.exec(packageJson.packageManager)?.[1];
|
|
@@ -17730,7 +17936,7 @@ async function usesModernYarn(root) {
|
|
|
17730
17936
|
}
|
|
17731
17937
|
}
|
|
17732
17938
|
async function detectPackageManager(root) {
|
|
17733
|
-
if (await
|
|
17939
|
+
if (await exists2(join3(root, "pnpm-lock.yaml"))) {
|
|
17734
17940
|
return {
|
|
17735
17941
|
name: "pnpm",
|
|
17736
17942
|
install: ["pnpm", "install", "--frozen-lockfile"],
|
|
@@ -17741,7 +17947,7 @@ async function detectPackageManager(root) {
|
|
|
17741
17947
|
addArgs: (specs) => ["pnpm", "add", ...specs]
|
|
17742
17948
|
};
|
|
17743
17949
|
}
|
|
17744
|
-
if (await
|
|
17950
|
+
if (await exists2(join3(root, "package-lock.json"))) {
|
|
17745
17951
|
return {
|
|
17746
17952
|
name: "npm",
|
|
17747
17953
|
install: ["npm", "ci"],
|
|
@@ -17767,7 +17973,7 @@ async function detectPackageManager(root) {
|
|
|
17767
17973
|
sharedCacheAddArgs: ["--prefer-offline"]
|
|
17768
17974
|
};
|
|
17769
17975
|
}
|
|
17770
|
-
if (await
|
|
17976
|
+
if (await exists2(join3(root, "yarn.lock"))) {
|
|
17771
17977
|
const modern = await usesModernYarn(root);
|
|
17772
17978
|
return {
|
|
17773
17979
|
name: "yarn",
|
|
@@ -17788,114 +17994,13 @@ async function detectPackageManager(root) {
|
|
|
17788
17994
|
);
|
|
17789
17995
|
}
|
|
17790
17996
|
|
|
17791
|
-
// ../../packages/build/src/proxy-to-middleware.ts
|
|
17792
|
-
import { access as access2, readFile as readFile3, rename, writeFile as writeFile2 } from "fs/promises";
|
|
17793
|
-
import { join as join3 } from "path";
|
|
17794
|
-
var EXTENSIONS = ["ts", "tsx", "js", "jsx"];
|
|
17795
|
-
var DIRECTORIES = ["", "src"];
|
|
17796
|
-
async function exists2(path) {
|
|
17797
|
-
try {
|
|
17798
|
-
await access2(path);
|
|
17799
|
-
return true;
|
|
17800
|
-
} catch {
|
|
17801
|
-
return false;
|
|
17802
|
-
}
|
|
17803
|
-
}
|
|
17804
|
-
function renameExport(source) {
|
|
17805
|
-
return source.replace(
|
|
17806
|
-
/(export\s+(?:default\s+)?(?:async\s+)?function\s+)proxy\b/g,
|
|
17807
|
-
"$1middleware"
|
|
17808
|
-
).replace(/(export\s+const\s+)proxy\b/g, "$1middleware");
|
|
17809
|
-
}
|
|
17810
|
-
async function convertProxyToMiddleware(appRoot) {
|
|
17811
|
-
for (const dir of DIRECTORIES) {
|
|
17812
|
-
for (const ext of EXTENSIONS) {
|
|
17813
|
-
const rel = join3(dir, `proxy.${ext}`);
|
|
17814
|
-
const proxyPath = join3(appRoot, rel);
|
|
17815
|
-
if (!await exists2(proxyPath)) continue;
|
|
17816
|
-
const middlewarePath = join3(appRoot, dir, `middleware.${ext}`);
|
|
17817
|
-
if (await exists2(middlewarePath)) return { converted: false };
|
|
17818
|
-
const source = await readFile3(proxyPath, "utf8");
|
|
17819
|
-
await writeFile2(middlewarePath, renameExport(source));
|
|
17820
|
-
await rename(proxyPath, `${proxyPath}.converted`);
|
|
17821
|
-
return { converted: true, file: rel };
|
|
17822
|
-
}
|
|
17823
|
-
}
|
|
17824
|
-
return { converted: false };
|
|
17825
|
-
}
|
|
17826
|
-
|
|
17827
17997
|
// ../../packages/build/src/vinext.ts
|
|
17828
|
-
import { access as
|
|
17829
|
-
import { join as join6, resolve
|
|
17998
|
+
import { access as access3, readFile as readFile5, writeFile as writeFile4 } from "fs/promises";
|
|
17999
|
+
import { join as join6, resolve } from "path";
|
|
17830
18000
|
|
|
17831
|
-
// ../../packages/build/src/
|
|
17832
|
-
import {
|
|
17833
|
-
import {
|
|
17834
|
-
basename,
|
|
17835
|
-
dirname,
|
|
17836
|
-
extname,
|
|
17837
|
-
isAbsolute,
|
|
17838
|
-
join as join4,
|
|
17839
|
-
relative,
|
|
17840
|
-
resolve,
|
|
17841
|
-
sep
|
|
17842
|
-
} from "path";
|
|
17843
|
-
function parseJsonc(source) {
|
|
17844
|
-
let output = "";
|
|
17845
|
-
let index = 0;
|
|
17846
|
-
let inString = false;
|
|
17847
|
-
let escaped = false;
|
|
17848
|
-
while (index < source.length) {
|
|
17849
|
-
const current = source[index] ?? "";
|
|
17850
|
-
const next = source[index + 1] ?? "";
|
|
17851
|
-
if (inString) {
|
|
17852
|
-
output += current;
|
|
17853
|
-
if (escaped) escaped = false;
|
|
17854
|
-
else if (current === "\\") escaped = true;
|
|
17855
|
-
else if (current === '"') inString = false;
|
|
17856
|
-
index += 1;
|
|
17857
|
-
continue;
|
|
17858
|
-
}
|
|
17859
|
-
if (current === '"') {
|
|
17860
|
-
inString = true;
|
|
17861
|
-
output += current;
|
|
17862
|
-
index += 1;
|
|
17863
|
-
continue;
|
|
17864
|
-
}
|
|
17865
|
-
if (current === "/" && next === "/") {
|
|
17866
|
-
index += 2;
|
|
17867
|
-
while (index < source.length && source[index] !== "\n") index += 1;
|
|
17868
|
-
continue;
|
|
17869
|
-
}
|
|
17870
|
-
if (current === "/" && next === "*") {
|
|
17871
|
-
index += 2;
|
|
17872
|
-
while (index < source.length && !(source[index] === "*" && source[index + 1] === "/"))
|
|
17873
|
-
index += 1;
|
|
17874
|
-
index += 2;
|
|
17875
|
-
continue;
|
|
17876
|
-
}
|
|
17877
|
-
output += current;
|
|
17878
|
-
index += 1;
|
|
17879
|
-
}
|
|
17880
|
-
return JSON.parse(output.replace(/,\s*([}\]])/g, "$1"));
|
|
17881
|
-
}
|
|
17882
|
-
function confinedPath(root, configuredPath, label2, base2 = root) {
|
|
17883
|
-
if (isAbsolute(configuredPath)) {
|
|
17884
|
-
throw new DeploymentError(
|
|
17885
|
-
"ARTIFACT_INVALID",
|
|
17886
|
-
`${label2} must be relative to the application root.`
|
|
17887
|
-
);
|
|
17888
|
-
}
|
|
17889
|
-
const resolved = resolve(base2, configuredPath);
|
|
17890
|
-
const relation = relative(root, resolved);
|
|
17891
|
-
if (relation === ".." || relation.startsWith(`..${sep}`) || isAbsolute(relation)) {
|
|
17892
|
-
throw new DeploymentError(
|
|
17893
|
-
"ARTIFACT_INVALID",
|
|
17894
|
-
`${label2} escapes the application root.`
|
|
17895
|
-
);
|
|
17896
|
-
}
|
|
17897
|
-
return resolved;
|
|
17898
|
-
}
|
|
18001
|
+
// ../../packages/build/src/artifact-files.ts
|
|
18002
|
+
import { readdir, readFile as readFile4, realpath } from "fs/promises";
|
|
18003
|
+
import { extname, isAbsolute, join as join4, relative, sep } from "path";
|
|
17899
18004
|
function contentType(path) {
|
|
17900
18005
|
switch (extname(path).toLowerCase()) {
|
|
17901
18006
|
case ".html":
|
|
@@ -17970,7 +18075,7 @@ async function assertInsideOnDisk(appRoot, directory, label2) {
|
|
|
17970
18075
|
);
|
|
17971
18076
|
}
|
|
17972
18077
|
}
|
|
17973
|
-
async function listArtifactFiles(root, label2 = "
|
|
18078
|
+
async function listArtifactFiles(root, label2 = "Build", appRoot) {
|
|
17974
18079
|
if (appRoot !== void 0) await assertInsideOnDisk(appRoot, root, label2);
|
|
17975
18080
|
const files = [];
|
|
17976
18081
|
async function visit(directory) {
|
|
@@ -17998,131 +18103,12 @@ async function listArtifactFiles(root, label2 = "OpenNext", appRoot) {
|
|
|
17998
18103
|
await visit(root);
|
|
17999
18104
|
return files;
|
|
18000
18105
|
}
|
|
18001
|
-
|
|
18002
|
-
|
|
18003
|
-
const resolved = isAbsolute(configuredPath) ? configuredPath : resolve(root, configuredPath);
|
|
18004
|
-
const relation = relative(root, resolved);
|
|
18005
|
-
if (relation === ".." || relation.startsWith(`..${sep}`) || isAbsolute(relation)) {
|
|
18006
|
-
throw new DeploymentError(
|
|
18007
|
-
"ARTIFACT_INVALID",
|
|
18008
|
-
"Wrangler config escapes the application root."
|
|
18009
|
-
);
|
|
18010
|
-
}
|
|
18011
|
-
await access3(resolved);
|
|
18012
|
-
return resolved;
|
|
18013
|
-
}
|
|
18014
|
-
for (const name of ["wrangler.jsonc", "wrangler.json"]) {
|
|
18015
|
-
const path = join4(root, name);
|
|
18016
|
-
try {
|
|
18017
|
-
await access3(path);
|
|
18018
|
-
return path;
|
|
18019
|
-
} catch {
|
|
18020
|
-
}
|
|
18021
|
-
}
|
|
18022
|
-
throw new DeploymentError(
|
|
18023
|
-
"ARTIFACT_INVALID",
|
|
18024
|
-
"A wrangler.jsonc or wrangler.json file is required."
|
|
18025
|
-
);
|
|
18026
|
-
}
|
|
18027
|
-
var OPEN_NEXT_LAYOUT = {
|
|
18028
|
-
outputRoot: ".open-next",
|
|
18029
|
-
bundleDir: ".open-next/worker-bundle"
|
|
18030
|
-
};
|
|
18031
|
-
async function readOpenNextArtifact(appRoot, identity, wranglerConfigPath) {
|
|
18032
|
-
const configPath = await findWranglerConfig(appRoot, wranglerConfigPath);
|
|
18033
|
-
return readWorkerArtifact(appRoot, identity, {
|
|
18034
|
-
wranglerConfigPath: configPath,
|
|
18035
|
-
...OPEN_NEXT_LAYOUT
|
|
18036
|
-
});
|
|
18037
|
-
}
|
|
18038
|
-
async function readWorkerArtifact(appRoot, identity, layout) {
|
|
18039
|
-
const listFiles = (root) => listArtifactFiles(root, "OpenNext", appRoot);
|
|
18040
|
-
try {
|
|
18041
|
-
const configPath = await findWranglerConfig(
|
|
18042
|
-
appRoot,
|
|
18043
|
-
layout.wranglerConfigPath
|
|
18044
|
-
);
|
|
18045
|
-
const metadata = parseJsonc(
|
|
18046
|
-
await readFile4(configPath, "utf8")
|
|
18047
|
-
);
|
|
18048
|
-
if (typeof metadata.main !== "string" || typeof metadata.compatibility_date !== "string") {
|
|
18049
|
-
throw new DeploymentError(
|
|
18050
|
-
"ARTIFACT_INVALID",
|
|
18051
|
-
"Wrangler metadata must declare main and compatibility_date."
|
|
18052
|
-
);
|
|
18053
|
-
}
|
|
18054
|
-
const configDir = dirname(configPath);
|
|
18055
|
-
const outputRoot = confinedPath(appRoot, layout.outputRoot, "Output root");
|
|
18056
|
-
const entrypointPath = confinedPath(
|
|
18057
|
-
appRoot,
|
|
18058
|
-
metadata.main,
|
|
18059
|
-
"Worker entrypoint",
|
|
18060
|
-
configDir
|
|
18061
|
-
);
|
|
18062
|
-
const entryRelation = relative(outputRoot, entrypointPath);
|
|
18063
|
-
if (entryRelation === ".." || entryRelation.startsWith(`..${sep}`) || isAbsolute(entryRelation)) {
|
|
18064
|
-
throw new DeploymentError(
|
|
18065
|
-
"ARTIFACT_INVALID",
|
|
18066
|
-
`Worker entrypoint must be inside ${layout.outputRoot}.`
|
|
18067
|
-
);
|
|
18068
|
-
}
|
|
18069
|
-
await access3(entrypointPath);
|
|
18070
|
-
const configuredAssets = typeof metadata.assets?.directory === "string" ? confinedPath(
|
|
18071
|
-
appRoot,
|
|
18072
|
-
metadata.assets.directory,
|
|
18073
|
-
"Assets directory",
|
|
18074
|
-
configDir
|
|
18075
|
-
) : join4(outputRoot, "assets");
|
|
18076
|
-
const assetsRelation = relative(outputRoot, configuredAssets);
|
|
18077
|
-
if (assetsRelation === ".." || assetsRelation.startsWith(`..${sep}`) || isAbsolute(assetsRelation)) {
|
|
18078
|
-
throw new DeploymentError(
|
|
18079
|
-
"ARTIFACT_INVALID",
|
|
18080
|
-
`Assets directory must be inside ${layout.outputRoot}.`
|
|
18081
|
-
);
|
|
18082
|
-
}
|
|
18083
|
-
const bundleRoot = confinedPath(appRoot, layout.bundleDir, "Bundle dir");
|
|
18084
|
-
let bundleExists = true;
|
|
18085
|
-
try {
|
|
18086
|
-
await access3(bundleRoot);
|
|
18087
|
-
} catch {
|
|
18088
|
-
bundleExists = false;
|
|
18089
|
-
}
|
|
18090
|
-
const bundleFiles = bundleExists ? await listFiles(bundleRoot) : null;
|
|
18091
|
-
const outputFiles = bundleFiles ?? await listFiles(outputRoot);
|
|
18092
|
-
const entrypointName = bundleFiles ? basename(entrypointPath) : relative(outputRoot, entrypointPath).split(sep).join("/");
|
|
18093
|
-
const assetsPrefix = `${relative(outputRoot, configuredAssets).split(sep).join("/")}/`;
|
|
18094
|
-
const entrypoint = outputFiles.find((file2) => file2.name === entrypointName);
|
|
18095
|
-
if (!entrypoint)
|
|
18096
|
-
throw new DeploymentError(
|
|
18097
|
-
"ARTIFACT_INVALID",
|
|
18098
|
-
"Worker entrypoint is missing from the build output."
|
|
18099
|
-
);
|
|
18100
|
-
return {
|
|
18101
|
-
...identity,
|
|
18102
|
-
entrypoint,
|
|
18103
|
-
modules: outputFiles.filter(
|
|
18104
|
-
(file2) => file2.name !== entrypointName && !file2.name.endsWith(".map") && file2.name !== "README.md" && (bundleFiles !== null || !file2.name.startsWith(assetsPrefix))
|
|
18105
|
-
),
|
|
18106
|
-
assets: (await listFiles(configuredAssets)).map((file2) => ({ ...file2 })),
|
|
18107
|
-
compatibilityDate: metadata.compatibility_date,
|
|
18108
|
-
compatibilityFlags: Array.isArray(metadata.compatibility_flags) ? metadata.compatibility_flags.filter(
|
|
18109
|
-
(flag) => typeof flag === "string"
|
|
18110
|
-
) : [],
|
|
18111
|
-
assetsBinding: typeof metadata.assets?.binding === "string" ? metadata.assets.binding : "ASSETS"
|
|
18112
|
-
};
|
|
18113
|
-
} catch (error51) {
|
|
18114
|
-
if (error51 instanceof DeploymentError) throw error51;
|
|
18115
|
-
throw new DeploymentError(
|
|
18116
|
-
"ARTIFACT_INVALID",
|
|
18117
|
-
"Could not read the Worker build output.",
|
|
18118
|
-
{ cause: error51 }
|
|
18119
|
-
);
|
|
18120
|
-
}
|
|
18121
|
-
}
|
|
18106
|
+
|
|
18107
|
+
// ../../packages/build/src/isr-cache-source.generated.ts
|
|
18108
|
+
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';
|
|
18122
18109
|
|
|
18123
18110
|
// ../../packages/build/src/platform-config.ts
|
|
18124
|
-
import {
|
|
18125
|
-
import { createRequire } from "module";
|
|
18111
|
+
import { writeFile as writeFile3 } from "fs/promises";
|
|
18126
18112
|
import { join as join5 } from "path";
|
|
18127
18113
|
var COMPATIBILITY_DATE = "2026-08-19";
|
|
18128
18114
|
var NEXT_CONFIG_FILES = [
|
|
@@ -18131,14 +18117,6 @@ var NEXT_CONFIG_FILES = [
|
|
|
18131
18117
|
"next.config.cjs",
|
|
18132
18118
|
"next.config.ts"
|
|
18133
18119
|
];
|
|
18134
|
-
async function pathExists(path) {
|
|
18135
|
-
try {
|
|
18136
|
-
await access4(path);
|
|
18137
|
-
return true;
|
|
18138
|
-
} catch {
|
|
18139
|
-
return false;
|
|
18140
|
-
}
|
|
18141
|
-
}
|
|
18142
18120
|
var BUILD_NPMRC = [
|
|
18143
18121
|
"# Host package-manager credentials are intentionally unavailable.",
|
|
18144
18122
|
"audit=false",
|
|
@@ -18153,61 +18131,40 @@ async function createPackageManagerConfig(appRoot, writer = async (path, content
|
|
|
18153
18131
|
await writer(packageManagerConfigPath, BUILD_NPMRC);
|
|
18154
18132
|
return packageManagerConfigPath;
|
|
18155
18133
|
}
|
|
18156
|
-
|
|
18157
|
-
|
|
18158
|
-
|
|
18159
|
-
"
|
|
18160
|
-
|
|
18161
|
-
|
|
18162
|
-
|
|
18163
|
-
|
|
18164
|
-
|
|
18165
|
-
|
|
18166
|
-
if (
|
|
18167
|
-
|
|
18168
|
-
|
|
18134
|
+
|
|
18135
|
+
// ../../packages/build/src/wrangler-output.ts
|
|
18136
|
+
function globToRegExp(glob) {
|
|
18137
|
+
let source = "";
|
|
18138
|
+
for (let index = 0; index < glob.length; index += 1) {
|
|
18139
|
+
const char = glob[index];
|
|
18140
|
+
if (char !== "*") {
|
|
18141
|
+
source += char?.replace(/[.+?^${}()|[\]\\]/g, String.raw`\$&`) ?? "";
|
|
18142
|
+
continue;
|
|
18143
|
+
}
|
|
18144
|
+
if (glob[index + 1] !== "*") {
|
|
18145
|
+
source += "[^/]*";
|
|
18146
|
+
continue;
|
|
18147
|
+
}
|
|
18148
|
+
if (glob[index + 2] === "/") {
|
|
18149
|
+
source += "(?:[^/]*/)*";
|
|
18150
|
+
index += 2;
|
|
18151
|
+
} else {
|
|
18152
|
+
source += ".*";
|
|
18153
|
+
index += 1;
|
|
18169
18154
|
}
|
|
18170
18155
|
}
|
|
18171
|
-
|
|
18172
|
-
|
|
18173
|
-
|
|
18174
|
-
|
|
18175
|
-
|
|
18176
|
-
|
|
18177
|
-
|
|
18178
|
-
|
|
18179
|
-
|
|
18180
|
-
|
|
18181
|
-
|
|
18182
|
-
|
|
18183
|
-
);
|
|
18184
|
-
await writer(
|
|
18185
|
-
wranglerConfigPath,
|
|
18186
|
-
`${JSON.stringify(
|
|
18187
|
-
{
|
|
18188
|
-
name: `next-deploy-${safeDeploymentId}`,
|
|
18189
|
-
main: ".open-next/worker.js",
|
|
18190
|
-
compatibility_date: COMPATIBILITY_DATE,
|
|
18191
|
-
compatibility_flags: ["nodejs_compat"],
|
|
18192
|
-
assets: {
|
|
18193
|
-
directory: ".open-next/assets",
|
|
18194
|
-
binding: "ASSETS"
|
|
18195
|
-
}
|
|
18196
|
-
},
|
|
18197
|
-
null,
|
|
18198
|
-
2
|
|
18199
|
-
)}
|
|
18200
|
-
`
|
|
18201
|
-
);
|
|
18202
|
-
const packageManagerConfigPath = await createPackageManagerConfig(
|
|
18203
|
-
appRoot,
|
|
18204
|
-
writer
|
|
18205
|
-
);
|
|
18206
|
-
return {
|
|
18207
|
-
openNextConfigPath,
|
|
18208
|
-
wranglerConfigPath,
|
|
18209
|
-
packageManagerConfigPath
|
|
18210
|
-
};
|
|
18156
|
+
return new RegExp(`^${source}$`);
|
|
18157
|
+
}
|
|
18158
|
+
function moduleRules(rules) {
|
|
18159
|
+
if (!Array.isArray(rules)) return [];
|
|
18160
|
+
return rules.flatMap((rule) => {
|
|
18161
|
+
const { type, globs } = rule;
|
|
18162
|
+
if (!Array.isArray(globs)) return [];
|
|
18163
|
+
return globs.filter((glob) => typeof glob === "string").map((glob) => ({
|
|
18164
|
+
type: typeof type === "string" ? type : "",
|
|
18165
|
+
test: globToRegExp(glob)
|
|
18166
|
+
}));
|
|
18167
|
+
});
|
|
18211
18168
|
}
|
|
18212
18169
|
|
|
18213
18170
|
// ../../packages/build/src/vinext.ts
|
|
@@ -18230,6 +18187,8 @@ var VITE_CONFIG_NAMES = [
|
|
|
18230
18187
|
];
|
|
18231
18188
|
var GENERATED_VITE_CONFIG = "vite.config.js";
|
|
18232
18189
|
var GENERATED_WORKER_ENTRY = "naro-worker.js";
|
|
18190
|
+
var GENERATED_ISR_CACHE = "naro-isr-cache.js";
|
|
18191
|
+
var ISR_SHARED_CACHE_OFF_NOTE = "ISR shared cache is off: the project builds with its own vite.config.";
|
|
18233
18192
|
var VINEXT_WORKER_ENTRY_SOURCE = `// Written by naro: vinext's Worker, with getCloudflareContext() given its env.
|
|
18234
18193
|
import { AsyncLocalStorage } from "node:async_hooks";
|
|
18235
18194
|
import handler from "vinext/server/fetch-handler";
|
|
@@ -18264,7 +18223,7 @@ function vinextWranglerConfigPath(appRoot) {
|
|
|
18264
18223
|
}
|
|
18265
18224
|
async function exists3(path) {
|
|
18266
18225
|
try {
|
|
18267
|
-
await
|
|
18226
|
+
await access3(path);
|
|
18268
18227
|
return true;
|
|
18269
18228
|
} catch {
|
|
18270
18229
|
return false;
|
|
@@ -18288,6 +18247,13 @@ async function createVinextBuildConfig(appRoot, deploymentId, writer = async (pa
|
|
|
18288
18247
|
`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.`
|
|
18289
18248
|
);
|
|
18290
18249
|
}
|
|
18250
|
+
const isrCachePath = join6(appRoot, GENERATED_ISR_CACHE);
|
|
18251
|
+
if (await exists3(isrCachePath)) {
|
|
18252
|
+
throw new DeploymentError(
|
|
18253
|
+
"ARTIFACT_INVALID",
|
|
18254
|
+
`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.`
|
|
18255
|
+
);
|
|
18256
|
+
}
|
|
18291
18257
|
const safeDeploymentId = deploymentId.replace(/[^a-z0-9-]/gi, "-");
|
|
18292
18258
|
const viteConfigPath = join6(appRoot, GENERATED_VITE_CONFIG);
|
|
18293
18259
|
const wranglerConfigPath = join6(appRoot, "wrangler.jsonc");
|
|
@@ -18300,7 +18266,7 @@ async function createVinextBuildConfig(appRoot, deploymentId, writer = async (pa
|
|
|
18300
18266
|
"",
|
|
18301
18267
|
"export default defineConfig({",
|
|
18302
18268
|
" plugins: [",
|
|
18303
|
-
|
|
18269
|
+
` vinext({ cache: { data: { adapter: ${JSON.stringify(isrCachePath)} } } }),`,
|
|
18304
18270
|
' cloudflare({ viteEnvironment: { name: "rsc", childEnvironments: ["ssr"] } }),',
|
|
18305
18271
|
" ],",
|
|
18306
18272
|
"});",
|
|
@@ -18308,6 +18274,7 @@ async function createVinextBuildConfig(appRoot, deploymentId, writer = async (pa
|
|
|
18308
18274
|
].join("\n")
|
|
18309
18275
|
);
|
|
18310
18276
|
await writer(workerEntryPath, VINEXT_WORKER_ENTRY_SOURCE);
|
|
18277
|
+
await writer(isrCachePath, NARO_ISR_CACHE_SOURCE);
|
|
18311
18278
|
await writer(
|
|
18312
18279
|
wranglerConfigPath,
|
|
18313
18280
|
`${JSON.stringify(
|
|
@@ -18360,8 +18327,8 @@ function parseVinextCheckReport(output) {
|
|
|
18360
18327
|
function vinextRouteFromCheck(report) {
|
|
18361
18328
|
if (!report)
|
|
18362
18329
|
return {
|
|
18363
|
-
eligible:
|
|
18364
|
-
reason: "vinext check output could not be read;
|
|
18330
|
+
eligible: true,
|
|
18331
|
+
reason: "vinext check output could not be read; trying the build anyway. Expected if vinext changed its report format."
|
|
18365
18332
|
};
|
|
18366
18333
|
const autoFixed = report.issueLines.filter(
|
|
18367
18334
|
(line) => AUTO_FIXED_ISSUES.some((pattern) => pattern.test(line))
|
|
@@ -18373,7 +18340,7 @@ function vinextRouteFromCheck(report) {
|
|
|
18373
18340
|
if (blocking > 0)
|
|
18374
18341
|
return {
|
|
18375
18342
|
eligible: false,
|
|
18376
|
-
reason: `vinext check reported ${blocking} unsupported item(s) (${report.percent}% compatible)
|
|
18343
|
+
reason: `vinext check reported ${blocking} unsupported item(s) (${report.percent}% compatible).`
|
|
18377
18344
|
};
|
|
18378
18345
|
if (autoFixed.length > 0)
|
|
18379
18346
|
return {
|
|
@@ -18385,38 +18352,12 @@ function vinextRouteFromCheck(report) {
|
|
|
18385
18352
|
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."
|
|
18386
18353
|
};
|
|
18387
18354
|
}
|
|
18388
|
-
function globToRegExp(glob) {
|
|
18389
|
-
let source = "";
|
|
18390
|
-
for (let index = 0; index < glob.length; index += 1) {
|
|
18391
|
-
const char = glob[index];
|
|
18392
|
-
if (char !== "*") {
|
|
18393
|
-
source += char?.replace(/[.+?^${}()|[\]\\]/g, String.raw`\$&`) ?? "";
|
|
18394
|
-
continue;
|
|
18395
|
-
}
|
|
18396
|
-
if (glob[index + 1] !== "*") {
|
|
18397
|
-
source += "[^/]*";
|
|
18398
|
-
continue;
|
|
18399
|
-
}
|
|
18400
|
-
if (glob[index + 2] === "/") {
|
|
18401
|
-
source += "(?:[^/]*/)*";
|
|
18402
|
-
index += 2;
|
|
18403
|
-
} else {
|
|
18404
|
-
source += ".*";
|
|
18405
|
-
index += 1;
|
|
18406
|
-
}
|
|
18407
|
-
}
|
|
18408
|
-
return new RegExp(`^${source}$`);
|
|
18409
|
-
}
|
|
18410
18355
|
function moduleMatchers(rules) {
|
|
18411
|
-
|
|
18412
|
-
return rules.flatMap((rule) => {
|
|
18413
|
-
const globs = rule.globs;
|
|
18414
|
-
return Array.isArray(globs) ? globs : [];
|
|
18415
|
-
}).filter((glob) => typeof glob === "string").map(globToRegExp);
|
|
18356
|
+
return moduleRules(rules).map((rule) => rule.test);
|
|
18416
18357
|
}
|
|
18417
18358
|
async function readVinextArtifact(appRoot, identity) {
|
|
18418
18359
|
try {
|
|
18419
|
-
const outputRoot =
|
|
18360
|
+
const outputRoot = resolve(appRoot, VINEXT_OUTPUT_DIR);
|
|
18420
18361
|
const serverRoot = join6(outputRoot, SERVER_DIR);
|
|
18421
18362
|
const clientRoot = join6(outputRoot, CLIENT_DIR);
|
|
18422
18363
|
const configPath = join6(serverRoot, WRANGLER_OUTPUT_NAME);
|
|
@@ -18477,7 +18418,7 @@ var FRAMEWORK_PRESETS = {
|
|
|
18477
18418
|
id: "next",
|
|
18478
18419
|
detectDependency: "next",
|
|
18479
18420
|
defaultBuildScript: "build",
|
|
18480
|
-
defaultOutputDirectory: "
|
|
18421
|
+
defaultOutputDirectory: "dist",
|
|
18481
18422
|
needsServerRuntime: true,
|
|
18482
18423
|
spaFallback: false,
|
|
18483
18424
|
cachePath: ".next/cache"
|
|
@@ -18815,9 +18756,85 @@ async function detectFramework(root, overrides = {}) {
|
|
|
18815
18756
|
};
|
|
18816
18757
|
}
|
|
18817
18758
|
|
|
18759
|
+
// ../../packages/build/src/naro-adapter-artifact.ts
|
|
18760
|
+
import { readFile as readFile7 } from "fs/promises";
|
|
18761
|
+
import { join as join8 } from "path";
|
|
18762
|
+
var RULE_CONTENT_TYPES = {
|
|
18763
|
+
ESModule: "application/javascript+module",
|
|
18764
|
+
CommonJS: "application/javascript",
|
|
18765
|
+
Text: "text/plain",
|
|
18766
|
+
Data: "application/octet-stream",
|
|
18767
|
+
CompiledWasm: "application/wasm"
|
|
18768
|
+
};
|
|
18769
|
+
var CONFIG_NAME = "wrangler.jsonc";
|
|
18770
|
+
async function readNaroAdapterArtifact(appRoot, identity) {
|
|
18771
|
+
try {
|
|
18772
|
+
const workerRoot = join8(appRoot, WORKER_DIR);
|
|
18773
|
+
let metadata;
|
|
18774
|
+
try {
|
|
18775
|
+
metadata = JSON.parse(
|
|
18776
|
+
await readFile7(join8(workerRoot, CONFIG_NAME), "utf8")
|
|
18777
|
+
);
|
|
18778
|
+
} catch (error51) {
|
|
18779
|
+
throw new DeploymentError(
|
|
18780
|
+
"ARTIFACT_INVALID",
|
|
18781
|
+
`The Naro adapter produced no ${WORKER_DIR}/${CONFIG_NAME}.`,
|
|
18782
|
+
{ cause: error51 }
|
|
18783
|
+
);
|
|
18784
|
+
}
|
|
18785
|
+
if (typeof metadata.main !== "string" || typeof metadata.compatibility_date !== "string")
|
|
18786
|
+
throw new DeploymentError(
|
|
18787
|
+
"ARTIFACT_INVALID",
|
|
18788
|
+
"Naro adapter wrangler output must declare main and compatibility_date."
|
|
18789
|
+
);
|
|
18790
|
+
const rules = moduleRules(metadata.rules);
|
|
18791
|
+
const files = await listArtifactFiles(workerRoot, "naro-adapter", appRoot);
|
|
18792
|
+
const entry = files.find((file2) => file2.name === metadata.main);
|
|
18793
|
+
if (!entry)
|
|
18794
|
+
throw new DeploymentError(
|
|
18795
|
+
"ARTIFACT_INVALID",
|
|
18796
|
+
`Naro adapter worker entrypoint "${metadata.main}" is missing from the build output.`
|
|
18797
|
+
);
|
|
18798
|
+
const modules = files.filter(
|
|
18799
|
+
(file2) => file2.name !== metadata.main && file2.name !== CONFIG_NAME && !file2.name.endsWith(".map")
|
|
18800
|
+
).map((file2) => {
|
|
18801
|
+
const rule = rules.find((candidate) => candidate.test.test(file2.name));
|
|
18802
|
+
const contentType2 = rule ? RULE_CONTENT_TYPES[rule.type] : void 0;
|
|
18803
|
+
if (!contentType2)
|
|
18804
|
+
throw new DeploymentError(
|
|
18805
|
+
"ARTIFACT_INVALID",
|
|
18806
|
+
`Naro adapter output file "${file2.name}" matches no module rule.`
|
|
18807
|
+
);
|
|
18808
|
+
return { ...file2, contentType: contentType2 };
|
|
18809
|
+
});
|
|
18810
|
+
return {
|
|
18811
|
+
...identity,
|
|
18812
|
+
entrypoint: { ...entry, contentType: "application/javascript+module" },
|
|
18813
|
+
modules,
|
|
18814
|
+
assets: await listArtifactFiles(
|
|
18815
|
+
join8(appRoot, ASSETS_DIR),
|
|
18816
|
+
"naro-adapter",
|
|
18817
|
+
appRoot
|
|
18818
|
+
),
|
|
18819
|
+
compatibilityDate: metadata.compatibility_date,
|
|
18820
|
+
compatibilityFlags: Array.isArray(metadata.compatibility_flags) ? metadata.compatibility_flags.filter(
|
|
18821
|
+
(flag) => typeof flag === "string"
|
|
18822
|
+
) : [],
|
|
18823
|
+
assetsBinding: typeof metadata.assets?.binding === "string" ? metadata.assets.binding : "ASSETS"
|
|
18824
|
+
};
|
|
18825
|
+
} catch (error51) {
|
|
18826
|
+
if (error51 instanceof DeploymentError) throw error51;
|
|
18827
|
+
throw new DeploymentError(
|
|
18828
|
+
"ARTIFACT_INVALID",
|
|
18829
|
+
"Could not read the Naro adapter output.",
|
|
18830
|
+
{ cause: error51 }
|
|
18831
|
+
);
|
|
18832
|
+
}
|
|
18833
|
+
}
|
|
18834
|
+
|
|
18818
18835
|
// ../../packages/build/src/next-routes.ts
|
|
18819
18836
|
import { readdir as readdir2, stat as stat2 } from "fs/promises";
|
|
18820
|
-
import { join as
|
|
18837
|
+
import { join as join9 } from "path";
|
|
18821
18838
|
var APP_PAGE_FILE = /^page\.(?:js|jsx|ts|tsx|md|mdx)$/;
|
|
18822
18839
|
var PAGES_ROUTER_FILE = /^(.+)\.(?:js|jsx|ts|tsx)$/;
|
|
18823
18840
|
var DECLARATION_FILE = /\.d\.ts$/;
|
|
@@ -18831,7 +18848,7 @@ function errorCode(error51) {
|
|
|
18831
18848
|
}
|
|
18832
18849
|
async function firstDirectory(root, candidates) {
|
|
18833
18850
|
for (const candidate of candidates) {
|
|
18834
|
-
const path =
|
|
18851
|
+
const path = join9(root, candidate);
|
|
18835
18852
|
try {
|
|
18836
18853
|
if ((await stat2(path)).isDirectory()) return path;
|
|
18837
18854
|
} catch (error51) {
|
|
@@ -18861,7 +18878,7 @@ async function readAppRouter(dir, segments, routes) {
|
|
|
18861
18878
|
const name = entry.name;
|
|
18862
18879
|
if (name.startsWith("_") || INTERCEPTING.test(name)) continue;
|
|
18863
18880
|
const next = ROUTE_GROUP.test(name) || name.startsWith("@") ? segments : [...segments, urlSegment(name, "app")];
|
|
18864
|
-
await readAppRouter(
|
|
18881
|
+
await readAppRouter(join9(dir, name), next, routes);
|
|
18865
18882
|
}
|
|
18866
18883
|
}
|
|
18867
18884
|
async function readPagesRouter(dir, segments, routes) {
|
|
@@ -18870,7 +18887,7 @@ async function readPagesRouter(dir, segments, routes) {
|
|
|
18870
18887
|
if (entry.isDirectory()) {
|
|
18871
18888
|
if (segments.length === 0 && entry.name === "api") continue;
|
|
18872
18889
|
await readPagesRouter(
|
|
18873
|
-
|
|
18890
|
+
join9(dir, entry.name),
|
|
18874
18891
|
[...segments, urlSegment(entry.name, "pages")],
|
|
18875
18892
|
routes
|
|
18876
18893
|
);
|
|
@@ -18888,8 +18905,8 @@ async function readPagesRouter(dir, segments, routes) {
|
|
|
18888
18905
|
}
|
|
18889
18906
|
}
|
|
18890
18907
|
async function listNextRoutes(appRoot) {
|
|
18891
|
-
const app = await firstDirectory(appRoot, ["app",
|
|
18892
|
-
const pages = await firstDirectory(appRoot, ["pages",
|
|
18908
|
+
const app = await firstDirectory(appRoot, ["app", join9("src", "app")]);
|
|
18909
|
+
const pages = await firstDirectory(appRoot, ["pages", join9("src", "pages")]);
|
|
18893
18910
|
if (!app && !pages) return null;
|
|
18894
18911
|
const routes = /* @__PURE__ */ new Set();
|
|
18895
18912
|
if (app) await readAppRouter(app, [], routes);
|
|
@@ -19126,14 +19143,14 @@ async function runCommand(spec, observer) {
|
|
|
19126
19143
|
|
|
19127
19144
|
// ../../packages/build/src/repository.ts
|
|
19128
19145
|
import { realpath as realpath2 } from "fs/promises";
|
|
19129
|
-
import { isAbsolute as isAbsolute2, relative as relative2, resolve as
|
|
19146
|
+
import { isAbsolute as isAbsolute2, relative as relative2, resolve as resolve2, sep as sep2 } from "path";
|
|
19130
19147
|
function resolveAppRoot(checkout, configuredRoot) {
|
|
19131
|
-
const checkoutRoot =
|
|
19148
|
+
const checkoutRoot = resolve2(checkout);
|
|
19132
19149
|
if (!configuredRoot) return checkoutRoot;
|
|
19133
19150
|
if (isAbsolute2(configuredRoot)) {
|
|
19134
19151
|
throw new Error("Configured root directory escapes repository");
|
|
19135
19152
|
}
|
|
19136
|
-
const appRoot =
|
|
19153
|
+
const appRoot = resolve2(checkoutRoot, configuredRoot);
|
|
19137
19154
|
const relativeRoot = relative2(checkoutRoot, appRoot);
|
|
19138
19155
|
if (relativeRoot === ".." || relativeRoot.startsWith(`..${process.platform === "win32" ? "\\" : "/"}`) || isAbsolute2(relativeRoot)) {
|
|
19139
19156
|
throw new Error("Configured root directory escapes repository");
|
|
@@ -19164,8 +19181,8 @@ async function assertAppRootInsideCheckout(checkout, appRoot) {
|
|
|
19164
19181
|
}
|
|
19165
19182
|
|
|
19166
19183
|
// ../../packages/build/src/static-artifact.ts
|
|
19167
|
-
import { readdir as readdir3, readFile as
|
|
19168
|
-
import { isAbsolute as isAbsolute3, join as
|
|
19184
|
+
import { readdir as readdir3, readFile as readFile8 } from "fs/promises";
|
|
19185
|
+
import { isAbsolute as isAbsolute3, join as join10, relative as relative3, resolve as resolve3, sep as sep3 } from "path";
|
|
19169
19186
|
var SHIM_WORKER_SOURCE = "export default { fetch: (request, env) => env.ASSETS.fetch(request) };\n";
|
|
19170
19187
|
var EXCLUDED_DIRECTORIES = /* @__PURE__ */ new Set(["node_modules"]);
|
|
19171
19188
|
var ALLOWED_DOTFILE = ".well-known";
|
|
@@ -19179,7 +19196,7 @@ async function readStaticArtifact(appRoot, outputDirectory, identity, options, o
|
|
|
19179
19196
|
"ARTIFACT_INVALID",
|
|
19180
19197
|
"Output directory must be relative to the application root."
|
|
19181
19198
|
);
|
|
19182
|
-
const outputRoot =
|
|
19199
|
+
const outputRoot = resolve3(appRoot, outputDirectory);
|
|
19183
19200
|
const relation = relative3(appRoot, outputRoot);
|
|
19184
19201
|
if (relation === ".." || relation.startsWith(`..${sep3}`) || isAbsolute3(relation))
|
|
19185
19202
|
throw new DeploymentError(
|
|
@@ -19198,7 +19215,7 @@ async function readStaticArtifact(appRoot, outputDirectory, identity, options, o
|
|
|
19198
19215
|
(left, right) => left.name.localeCompare(right.name)
|
|
19199
19216
|
)) {
|
|
19200
19217
|
if (excluded(entry.name)) continue;
|
|
19201
|
-
const path =
|
|
19218
|
+
const path = join10(directory, entry.name);
|
|
19202
19219
|
if (entry.isSymbolicLink())
|
|
19203
19220
|
throw new DeploymentError(
|
|
19204
19221
|
"ARTIFACT_INVALID",
|
|
@@ -19208,7 +19225,7 @@ async function readStaticArtifact(appRoot, outputDirectory, identity, options, o
|
|
|
19208
19225
|
else if (entry.isFile()) {
|
|
19209
19226
|
assets.push({
|
|
19210
19227
|
name: relative3(outputRoot, path).split(sep3).join("/"),
|
|
19211
|
-
data: await
|
|
19228
|
+
data: await readFile8(path),
|
|
19212
19229
|
contentType: contentType(path)
|
|
19213
19230
|
});
|
|
19214
19231
|
}
|
|
@@ -19252,10 +19269,58 @@ async function readStaticArtifact(appRoot, outputDirectory, identity, options, o
|
|
|
19252
19269
|
};
|
|
19253
19270
|
}
|
|
19254
19271
|
|
|
19272
|
+
// ../../packages/build/src/static-cdn.ts
|
|
19273
|
+
var STATIC_ASSET_PREFIX_ENV = "NARO_STATIC_ASSET_PREFIX";
|
|
19274
|
+
var STATIC_ASSETS_ON_CDN_NOTE = "Static assets (_next/static) are served from static.naro.sh.";
|
|
19275
|
+
var STATIC_ASSETS_ON_WORKER_NOTE = "Static assets stay on the Worker: the build did not use Naro's asset prefix (the project sets its own assetPrefix or a basePath, or it is not a Next.js build).";
|
|
19276
|
+
function buildEnvWithStaticPrefix(env, prefix) {
|
|
19277
|
+
const result = { ...env };
|
|
19278
|
+
delete result[STATIC_ASSET_PREFIX_ENV];
|
|
19279
|
+
if (prefix) result[STATIC_ASSET_PREFIX_ENV] = prefix;
|
|
19280
|
+
return result;
|
|
19281
|
+
}
|
|
19282
|
+
function contains(file2, needle) {
|
|
19283
|
+
return Buffer.from(
|
|
19284
|
+
file2.data.buffer,
|
|
19285
|
+
file2.data.byteOffset,
|
|
19286
|
+
file2.data.byteLength
|
|
19287
|
+
).includes(needle);
|
|
19288
|
+
}
|
|
19289
|
+
function withStaticAssetPrefix(artifact, prefix) {
|
|
19290
|
+
if (!prefix) return { artifact, note: null };
|
|
19291
|
+
const needle = Buffer.from(prefix, "utf8");
|
|
19292
|
+
const files = [artifact.entrypoint, ...artifact.modules, ...artifact.assets];
|
|
19293
|
+
if (!files.some((file2) => contains(file2, needle)))
|
|
19294
|
+
return { artifact, note: STATIC_ASSETS_ON_WORKER_NOTE };
|
|
19295
|
+
return {
|
|
19296
|
+
artifact: { ...artifact, staticAssetPrefix: prefix },
|
|
19297
|
+
note: STATIC_ASSETS_ON_CDN_NOTE
|
|
19298
|
+
};
|
|
19299
|
+
}
|
|
19300
|
+
var IMMUTABLE_HEADERS_FILE = "_headers";
|
|
19301
|
+
var IMMUTABLE_HEADERS = `/_next/static/*
|
|
19302
|
+
Cache-Control: ${IMMUTABLE_CACHE_CONTROL}
|
|
19303
|
+
`;
|
|
19304
|
+
function withImmutableHeaders(artifact) {
|
|
19305
|
+
if (artifact.assets.some((asset) => asset.name === IMMUTABLE_HEADERS_FILE))
|
|
19306
|
+
return artifact;
|
|
19307
|
+
return {
|
|
19308
|
+
...artifact,
|
|
19309
|
+
assets: [
|
|
19310
|
+
...artifact.assets,
|
|
19311
|
+
{
|
|
19312
|
+
name: IMMUTABLE_HEADERS_FILE,
|
|
19313
|
+
data: new TextEncoder().encode(IMMUTABLE_HEADERS),
|
|
19314
|
+
contentType: "text/plain"
|
|
19315
|
+
}
|
|
19316
|
+
]
|
|
19317
|
+
};
|
|
19318
|
+
}
|
|
19319
|
+
|
|
19255
19320
|
// ../../packages/build/src/strategy/fingerprint.ts
|
|
19256
19321
|
import { createHash as createHash3 } from "crypto";
|
|
19257
|
-
import { readFile as
|
|
19258
|
-
import { join as
|
|
19322
|
+
import { readFile as readFile9 } from "fs/promises";
|
|
19323
|
+
import { join as join11, relative as relative4, sep as sep4 } from "path";
|
|
19259
19324
|
var APP_ROOT_FILES = [
|
|
19260
19325
|
"package.json",
|
|
19261
19326
|
"next.config.js",
|
|
@@ -19292,18 +19357,18 @@ function sha256(data) {
|
|
|
19292
19357
|
}
|
|
19293
19358
|
async function hashFile(path) {
|
|
19294
19359
|
try {
|
|
19295
|
-
return sha256(await
|
|
19360
|
+
return sha256(await readFile9(path));
|
|
19296
19361
|
} catch {
|
|
19297
19362
|
return null;
|
|
19298
19363
|
}
|
|
19299
19364
|
}
|
|
19300
19365
|
async function hashStrategyInputs(checkout, appRoot) {
|
|
19301
19366
|
const candidates = /* @__PURE__ */ new Set();
|
|
19302
|
-
for (const name of CHECKOUT_FILES) candidates.add(
|
|
19303
|
-
for (const name of APP_ROOT_FILES) candidates.add(
|
|
19367
|
+
for (const name of CHECKOUT_FILES) candidates.add(join11(checkout, name));
|
|
19368
|
+
for (const name of APP_ROOT_FILES) candidates.add(join11(appRoot, name));
|
|
19304
19369
|
for (const base2 of SOURCE_FILES) {
|
|
19305
19370
|
for (const ext of SOURCE_EXTENSIONS) {
|
|
19306
|
-
candidates.add(
|
|
19371
|
+
candidates.add(join11(appRoot, `${base2}.${ext}`));
|
|
19307
19372
|
}
|
|
19308
19373
|
}
|
|
19309
19374
|
const entries = [];
|
|
@@ -19331,12 +19396,12 @@ async function computeStrategyFingerprint(input) {
|
|
|
19331
19396
|
}
|
|
19332
19397
|
|
|
19333
19398
|
// ../../packages/build/src/strategy/project-facts.ts
|
|
19334
|
-
import { access as
|
|
19335
|
-
import { join as
|
|
19399
|
+
import { access as access4, readFile as readFile11 } from "fs/promises";
|
|
19400
|
+
import { join as join13 } from "path";
|
|
19336
19401
|
|
|
19337
19402
|
// ../../packages/build/src/strategy/user-adapter.ts
|
|
19338
|
-
import { readFile as
|
|
19339
|
-
import { join as
|
|
19403
|
+
import { readFile as readFile10 } from "fs/promises";
|
|
19404
|
+
import { join as join12 } from "path";
|
|
19340
19405
|
var ADAPTER_PATH = /\badapterPath\b/;
|
|
19341
19406
|
var EXPERIMENTAL_ADAPTER_PATH = /\bexperimental\s*:\s*\{[^{}]*\badapterPath\b/;
|
|
19342
19407
|
function adapterKeyFromConfigSource(source) {
|
|
@@ -19368,8 +19433,8 @@ async function adapterInBuildOutput(appRoot, nextVersion) {
|
|
|
19368
19433
|
let manifest2;
|
|
19369
19434
|
try {
|
|
19370
19435
|
const parsed = JSON.parse(
|
|
19371
|
-
await
|
|
19372
|
-
|
|
19436
|
+
await readFile10(
|
|
19437
|
+
join12(appRoot, ".next", "required-server-files.json"),
|
|
19373
19438
|
"utf8"
|
|
19374
19439
|
)
|
|
19375
19440
|
);
|
|
@@ -19380,10 +19445,14 @@ async function adapterInBuildOutput(appRoot, nextVersion) {
|
|
|
19380
19445
|
}
|
|
19381
19446
|
const topLevel = manifest2.config?.adapterPath;
|
|
19382
19447
|
if (keys.includes("adapterPath") && typeof topLevel === "string" && topLevel)
|
|
19383
|
-
return { source: "build-output", key: "adapterPath" };
|
|
19448
|
+
return { source: "build-output", key: "adapterPath", path: topLevel };
|
|
19384
19449
|
const experimental = manifest2.config?.experimental?.adapterPath;
|
|
19385
19450
|
if (keys.includes("experimental.adapterPath") && typeof experimental === "string" && experimental)
|
|
19386
|
-
return {
|
|
19451
|
+
return {
|
|
19452
|
+
source: "build-output",
|
|
19453
|
+
key: "experimental.adapterPath",
|
|
19454
|
+
path: experimental
|
|
19455
|
+
};
|
|
19387
19456
|
return null;
|
|
19388
19457
|
}
|
|
19389
19458
|
function describeUserAdapter(adapter) {
|
|
@@ -19396,9 +19465,6 @@ function describeUserAdapter(adapter) {
|
|
|
19396
19465
|
return `${adapter.key} in the Next.js build output`;
|
|
19397
19466
|
}
|
|
19398
19467
|
}
|
|
19399
|
-
function openNextAdapterWarning(adapter) {
|
|
19400
|
-
return `P2 opennext-cloudflare: The project sets its own Next.js adapter (${describeUserAdapter(adapter)}); its modifyConfig and onBuildComplete also run in the OpenNext build.`;
|
|
19401
|
-
}
|
|
19402
19468
|
|
|
19403
19469
|
// ../../packages/build/src/strategy/project-facts.ts
|
|
19404
19470
|
var SOURCE_EXTENSIONS2 = ["ts", "tsx", "js", "jsx", "mjs", "mts"];
|
|
@@ -19411,17 +19477,17 @@ var VITE_CONFIGS = [
|
|
|
19411
19477
|
];
|
|
19412
19478
|
async function exists4(path) {
|
|
19413
19479
|
try {
|
|
19414
|
-
await
|
|
19480
|
+
await access4(path);
|
|
19415
19481
|
return true;
|
|
19416
19482
|
} catch {
|
|
19417
19483
|
return false;
|
|
19418
19484
|
}
|
|
19419
19485
|
}
|
|
19420
|
-
async function findSourceFile(appRoot,
|
|
19486
|
+
async function findSourceFile(appRoot, basename5) {
|
|
19421
19487
|
for (const dir of SOURCE_DIRECTORIES) {
|
|
19422
19488
|
for (const ext of SOURCE_EXTENSIONS2) {
|
|
19423
|
-
const rel = dir ? `${dir}/${
|
|
19424
|
-
if (await exists4(
|
|
19489
|
+
const rel = dir ? `${dir}/${basename5}.${ext}` : `${basename5}.${ext}`;
|
|
19490
|
+
if (await exists4(join13(appRoot, rel))) return rel;
|
|
19425
19491
|
}
|
|
19426
19492
|
}
|
|
19427
19493
|
return null;
|
|
@@ -19441,14 +19507,15 @@ function matcherRoutesFromSource(source) {
|
|
|
19441
19507
|
}
|
|
19442
19508
|
async function readIfExists(path) {
|
|
19443
19509
|
try {
|
|
19444
|
-
return await
|
|
19510
|
+
return await readFile11(path, "utf8");
|
|
19445
19511
|
} catch {
|
|
19446
19512
|
return null;
|
|
19447
19513
|
}
|
|
19448
19514
|
}
|
|
19449
19515
|
async function findAdapterConfig(appRoot) {
|
|
19450
19516
|
for (const file2 of NEXT_CONFIG_FILES) {
|
|
19451
|
-
|
|
19517
|
+
if (file2 === "next.config.cjs") continue;
|
|
19518
|
+
const source = await readIfExists(join13(appRoot, file2));
|
|
19452
19519
|
if (source === null) continue;
|
|
19453
19520
|
const key = adapterKeyFromConfigSource(source);
|
|
19454
19521
|
return key ? { file: file2, key } : null;
|
|
@@ -19459,10 +19526,10 @@ async function collectProjectFacts(appRoot) {
|
|
|
19459
19526
|
const proxyFile = await findSourceFile(appRoot, "proxy");
|
|
19460
19527
|
const middlewareFile = await findSourceFile(appRoot, "middleware");
|
|
19461
19528
|
const routeSourceFile = middlewareFile ?? proxyFile;
|
|
19462
|
-
const routeSource = routeSourceFile ? await readIfExists(
|
|
19529
|
+
const routeSource = routeSourceFile ? await readIfExists(join13(appRoot, routeSourceFile)) : null;
|
|
19463
19530
|
let usesVinext = false;
|
|
19464
19531
|
let nextSpec = null;
|
|
19465
|
-
const packageJsonSource = await readIfExists(
|
|
19532
|
+
const packageJsonSource = await readIfExists(join13(appRoot, "package.json"));
|
|
19466
19533
|
if (packageJsonSource) {
|
|
19467
19534
|
try {
|
|
19468
19535
|
const packageJson = JSON.parse(packageJsonSource);
|
|
@@ -19473,7 +19540,7 @@ async function collectProjectFacts(appRoot) {
|
|
|
19473
19540
|
nextSpec = dependency("next");
|
|
19474
19541
|
if (dependency("vinext") !== null) {
|
|
19475
19542
|
for (const name of VITE_CONFIGS) {
|
|
19476
|
-
const config2 = await readIfExists(
|
|
19543
|
+
const config2 = await readIfExists(join13(appRoot, name));
|
|
19477
19544
|
if (config2 && /\bvinext\s*\(/.test(config2) && /@cloudflare\/vite-plugin/.test(config2)) {
|
|
19478
19545
|
usesVinext = true;
|
|
19479
19546
|
break;
|
|
@@ -19742,7 +19809,8 @@ async function fetchStatus(fetchImpl, url2, timeoutMs) {
|
|
|
19742
19809
|
clearTimeout(timer);
|
|
19743
19810
|
}
|
|
19744
19811
|
}
|
|
19745
|
-
function probeOk(status) {
|
|
19812
|
+
function probeOk(status, expect) {
|
|
19813
|
+
if (expect === "found" && status === 404) return false;
|
|
19746
19814
|
return status < 500;
|
|
19747
19815
|
}
|
|
19748
19816
|
function createSmokeTester(options = {}) {
|
|
@@ -19829,7 +19897,11 @@ function createSmokeTester(options = {}) {
|
|
|
19829
19897
|
`${origin}${probe.path}`,
|
|
19830
19898
|
probeTimeoutMs
|
|
19831
19899
|
);
|
|
19832
|
-
const result = "status" in answer ? {
|
|
19900
|
+
const result = "status" in answer ? {
|
|
19901
|
+
...probe,
|
|
19902
|
+
status: answer.status,
|
|
19903
|
+
ok: probeOk(answer.status, probe.expect)
|
|
19904
|
+
} : { ...probe, status: null, ok: false, detail: answer.error };
|
|
19833
19905
|
probes2.push(result);
|
|
19834
19906
|
await observer.onLog({
|
|
19835
19907
|
level: result.ok ? "INFO" : "ERROR",
|
|
@@ -19874,13 +19946,40 @@ function defaultSmokeProbes(matcherRoutes) {
|
|
|
19874
19946
|
return probes2;
|
|
19875
19947
|
}
|
|
19876
19948
|
|
|
19877
|
-
// ../../packages/build/src/strategy/strategies/
|
|
19878
|
-
|
|
19879
|
-
|
|
19949
|
+
// ../../packages/build/src/strategy/strategies/unavailable.ts
|
|
19950
|
+
function createUnavailableStrategy(options) {
|
|
19951
|
+
return {
|
|
19952
|
+
id: options.id,
|
|
19953
|
+
priority: options.priority,
|
|
19954
|
+
target: options.target,
|
|
19955
|
+
supports: () => ({ supported: false, reason: options.reason }),
|
|
19956
|
+
evaluate: async () => ({ status: "skipped", reason: options.reason })
|
|
19957
|
+
};
|
|
19958
|
+
}
|
|
19959
|
+
function createSplitCloudflareStrategy() {
|
|
19960
|
+
return createUnavailableStrategy({
|
|
19961
|
+
id: "split-cloudflare",
|
|
19962
|
+
priority: 3,
|
|
19963
|
+
target: "cloudflare-split",
|
|
19964
|
+
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."
|
|
19965
|
+
});
|
|
19966
|
+
}
|
|
19967
|
+
function createAwsMiddlewareCloudflareAppStrategy() {
|
|
19968
|
+
return createUnavailableStrategy({
|
|
19969
|
+
id: "aws-middleware-cloudflare-app",
|
|
19970
|
+
priority: 4,
|
|
19971
|
+
target: "aws-hybrid",
|
|
19972
|
+
reason: "Hybrid AWS middleware + Cloudflare app needs an AWS deploy target and cross-cloud request chaining; neither exists on this control plane."
|
|
19973
|
+
});
|
|
19974
|
+
}
|
|
19975
|
+
|
|
19976
|
+
// ../../packages/build/src/strategy/strategies/naro-adapter-cloudflare.ts
|
|
19977
|
+
import { readFile as readFile13, rm as rm2 } from "fs/promises";
|
|
19978
|
+
import { join as join15, resolve as resolve5 } from "path";
|
|
19880
19979
|
|
|
19881
19980
|
// ../../packages/build/src/strategy/strategies/shared.ts
|
|
19882
|
-
import { access as
|
|
19883
|
-
import { dirname
|
|
19981
|
+
import { access as access5, readFile as readFile12, rm, writeFile as writeFile5 } from "fs/promises";
|
|
19982
|
+
import { dirname, join as join14, resolve as resolve4 } from "path";
|
|
19884
19983
|
function capturingObserver(observer) {
|
|
19885
19984
|
const lines = [];
|
|
19886
19985
|
return {
|
|
@@ -19916,31 +20015,28 @@ function describeFailure(step) {
|
|
|
19916
20015
|
function failed(stage, reason) {
|
|
19917
20016
|
return { status: "failed", stage, reason };
|
|
19918
20017
|
}
|
|
19919
|
-
function appBuildFailed(reason) {
|
|
19920
|
-
return { status: "failed", stage: "build", reason, appBuild: true };
|
|
19921
|
-
}
|
|
19922
20018
|
async function info(observer, message) {
|
|
19923
20019
|
await observer.onLog({ level: "INFO", stage: "BUILDING", message });
|
|
19924
20020
|
}
|
|
19925
20021
|
async function warn(observer, message) {
|
|
19926
20022
|
await observer.onLog({ level: "WARN", stage: "BUILDING", message });
|
|
19927
20023
|
}
|
|
19928
|
-
async function
|
|
20024
|
+
async function pathExists(path) {
|
|
19929
20025
|
try {
|
|
19930
|
-
await
|
|
20026
|
+
await access5(path);
|
|
19931
20027
|
return true;
|
|
19932
20028
|
} catch {
|
|
19933
20029
|
return false;
|
|
19934
20030
|
}
|
|
19935
20031
|
}
|
|
19936
20032
|
async function findProjectBin(appRoot, checkout, name) {
|
|
19937
|
-
let dir =
|
|
19938
|
-
const stop =
|
|
20033
|
+
let dir = resolve4(appRoot);
|
|
20034
|
+
const stop = resolve4(checkout);
|
|
19939
20035
|
for (; ; ) {
|
|
19940
|
-
const candidate =
|
|
19941
|
-
if (await
|
|
20036
|
+
const candidate = join14(dir, "node_modules", ".bin", name);
|
|
20037
|
+
if (await pathExists(candidate)) return candidate;
|
|
19942
20038
|
if (dir === stop) return null;
|
|
19943
|
-
const parent =
|
|
20039
|
+
const parent = dirname(dir);
|
|
19944
20040
|
if (parent === dir) return null;
|
|
19945
20041
|
dir = parent;
|
|
19946
20042
|
}
|
|
@@ -19951,7 +20047,7 @@ function dotenvQuote(value) {
|
|
|
19951
20047
|
return `"${value.replace(/"/g, '\\"').replace(/\n/g, "\\n").replace(/\r/g, "\\r")}"`;
|
|
19952
20048
|
}
|
|
19953
20049
|
async function withDevVars(wranglerConfigPath, env, run) {
|
|
19954
|
-
const path =
|
|
20050
|
+
const path = join14(dirname(wranglerConfigPath), ".dev.vars");
|
|
19955
20051
|
const keys = Object.keys(env).filter(
|
|
19956
20052
|
(key) => /^[A-Za-z_][A-Za-z0-9_]*$/.test(key)
|
|
19957
20053
|
);
|
|
@@ -19968,36 +20064,7 @@ async function withDevVars(wranglerConfigPath, env, run) {
|
|
|
19968
20064
|
await rm(path, { force: true });
|
|
19969
20065
|
}
|
|
19970
20066
|
}
|
|
19971
|
-
async function
|
|
19972
|
-
return runStep(
|
|
19973
|
-
context,
|
|
19974
|
-
{
|
|
19975
|
-
command: context.toolchain.wrangler,
|
|
19976
|
-
args: [
|
|
19977
|
-
"deploy",
|
|
19978
|
-
"--dry-run",
|
|
19979
|
-
"--config",
|
|
19980
|
-
layout.wranglerConfigPath,
|
|
19981
|
-
"--outdir",
|
|
19982
|
-
layout.bundleDir
|
|
19983
|
-
],
|
|
19984
|
-
cwd: layout.appRoot,
|
|
19985
|
-
env: {
|
|
19986
|
-
CI: "1",
|
|
19987
|
-
WRANGLER_LOG_PATH: join13(
|
|
19988
|
-
layout.appRoot,
|
|
19989
|
-
layout.outputRoot,
|
|
19990
|
-
"wrangler.log"
|
|
19991
|
-
)
|
|
19992
|
-
},
|
|
19993
|
-
timeoutMs: 5 * 6e4,
|
|
19994
|
-
stage: "BUILDING",
|
|
19995
|
-
errorCode: errorCode2
|
|
19996
|
-
},
|
|
19997
|
-
observer
|
|
19998
|
-
);
|
|
19999
|
-
}
|
|
20000
|
-
async function smokeWorker(context, layout, observer) {
|
|
20067
|
+
async function smokeWorker(context, layout, observer, extraProbes = []) {
|
|
20001
20068
|
return withDevVars(
|
|
20002
20069
|
layout.wranglerConfigPath,
|
|
20003
20070
|
context.env,
|
|
@@ -20017,19 +20084,22 @@ async function smokeWorker(context, layout, observer) {
|
|
|
20017
20084
|
"--show-interactive-dev-session=false",
|
|
20018
20085
|
"--log-level=warn",
|
|
20019
20086
|
"--persist-to",
|
|
20020
|
-
|
|
20087
|
+
join14(layout.appRoot, layout.outputRoot, ".naro-smoke-state")
|
|
20021
20088
|
],
|
|
20022
20089
|
cwd: layout.appRoot,
|
|
20023
20090
|
env: {
|
|
20024
20091
|
CI: "1",
|
|
20025
|
-
WRANGLER_LOG_PATH:
|
|
20092
|
+
WRANGLER_LOG_PATH: join14(
|
|
20026
20093
|
layout.appRoot,
|
|
20027
20094
|
layout.outputRoot,
|
|
20028
20095
|
"wrangler-dev.log"
|
|
20029
20096
|
)
|
|
20030
20097
|
}
|
|
20031
20098
|
}),
|
|
20032
|
-
probes:
|
|
20099
|
+
probes: [
|
|
20100
|
+
...defaultSmokeProbes(context.facts.matcherRoutes),
|
|
20101
|
+
...extraProbes
|
|
20102
|
+
],
|
|
20033
20103
|
stage: "BUILDING",
|
|
20034
20104
|
errorCode: "BUILD_FAILED"
|
|
20035
20105
|
},
|
|
@@ -20038,10 +20108,10 @@ async function smokeWorker(context, layout, observer) {
|
|
|
20038
20108
|
);
|
|
20039
20109
|
}
|
|
20040
20110
|
async function approvePnpmBuilds(checkout, packages) {
|
|
20041
|
-
const path =
|
|
20111
|
+
const path = join14(checkout, "pnpm-workspace.yaml");
|
|
20042
20112
|
let source = "";
|
|
20043
20113
|
try {
|
|
20044
|
-
source = await
|
|
20114
|
+
source = await readFile12(path, "utf8");
|
|
20045
20115
|
} catch {
|
|
20046
20116
|
}
|
|
20047
20117
|
let next = source;
|
|
@@ -20088,412 +20158,191 @@ ${listEntries}
|
|
|
20088
20158
|
}
|
|
20089
20159
|
}
|
|
20090
20160
|
|
|
20091
|
-
// ../../packages/build/src/strategy/strategies/
|
|
20092
|
-
var
|
|
20093
|
-
|
|
20094
|
-
|
|
20095
|
-
|
|
20096
|
-
|
|
20097
|
-
|
|
20098
|
-
|
|
20099
|
-
|
|
20100
|
-
|
|
20101
|
-
' imageOptimization: { loader: "dummy" },',
|
|
20102
|
-
" dangerous: { disableIncrementalCache: true, disableTagCache: true },",
|
|
20103
|
-
"};",
|
|
20104
|
-
"export default config;",
|
|
20105
|
-
""
|
|
20106
|
-
].join("\n");
|
|
20161
|
+
// ../../packages/build/src/strategy/strategies/naro-adapter-cloudflare.ts
|
|
20162
|
+
var NARO_ADAPTER_REASONS = {
|
|
20163
|
+
notInstalled: "The Naro adapter is not installed in this build environment.",
|
|
20164
|
+
unknownVersion: "The installed Next.js version could not be read; the Naro adapter needs Next.js 16.2 or newer.",
|
|
20165
|
+
missingOutput: "next build finished without the Naro adapter's output; another Next.js adapter may have run instead.",
|
|
20166
|
+
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.`
|
|
20167
|
+
};
|
|
20168
|
+
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.";
|
|
20169
|
+
function replaceWarning(adapter) {
|
|
20170
|
+
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}`;
|
|
20107
20171
|
}
|
|
20108
|
-
function
|
|
20172
|
+
async function readRecord(appRoot) {
|
|
20173
|
+
try {
|
|
20174
|
+
const parsed = JSON.parse(
|
|
20175
|
+
await readFile13(join15(appRoot, BUILD_RECORD), "utf8")
|
|
20176
|
+
);
|
|
20177
|
+
if (typeof parsed.buildId !== "string" || typeof parsed.distDir !== "string")
|
|
20178
|
+
return null;
|
|
20179
|
+
const staticFiles = Array.isArray(parsed.outputs?.staticFiles) ? parsed.outputs.staticFiles : [];
|
|
20180
|
+
return {
|
|
20181
|
+
buildId: parsed.buildId,
|
|
20182
|
+
distDir: parsed.distDir,
|
|
20183
|
+
basePath: typeof parsed.config?.basePath === "string" ? parsed.config.basePath : "",
|
|
20184
|
+
staticPathnames: staticFiles.flatMap((file2) => {
|
|
20185
|
+
const pathname = file2?.pathname;
|
|
20186
|
+
return typeof pathname === "string" ? [pathname] : [];
|
|
20187
|
+
})
|
|
20188
|
+
};
|
|
20189
|
+
} catch {
|
|
20190
|
+
return null;
|
|
20191
|
+
}
|
|
20192
|
+
}
|
|
20193
|
+
function naroAdapterSmokeProbes(record3, assetNames) {
|
|
20194
|
+
const { basePath } = record3;
|
|
20195
|
+
const probes2 = [];
|
|
20196
|
+
const assetPrefix = `${basePath}/_next/static/`;
|
|
20197
|
+
const script = assetNames.find(
|
|
20198
|
+
(name) => `/${name}`.startsWith(assetPrefix) && name.endsWith(".js")
|
|
20199
|
+
);
|
|
20200
|
+
if (script)
|
|
20201
|
+
probes2.push({ path: `/${script}`, label: "static asset", expect: "found" });
|
|
20202
|
+
const notPages = new Set(
|
|
20203
|
+
["/404", "/500", "/index"].map((path) => `${basePath}${path}`)
|
|
20204
|
+
);
|
|
20205
|
+
const page2 = record3.staticPathnames.find(
|
|
20206
|
+
(pathname) => !pathname.startsWith(assetPrefix) && !pathname.endsWith(".rsc") && !notPages.has(pathname)
|
|
20207
|
+
);
|
|
20208
|
+
if (page2) probes2.push({ path: page2, label: "static page", expect: "found" });
|
|
20209
|
+
return probes2;
|
|
20210
|
+
}
|
|
20211
|
+
async function readBuildId(distDir) {
|
|
20212
|
+
try {
|
|
20213
|
+
return (await readFile13(join15(distDir, "BUILD_ID"), "utf8")).trim();
|
|
20214
|
+
} catch {
|
|
20215
|
+
return null;
|
|
20216
|
+
}
|
|
20217
|
+
}
|
|
20218
|
+
function createNaroAdapterCloudflareStrategy(options) {
|
|
20109
20219
|
return {
|
|
20110
|
-
id: "
|
|
20111
|
-
priority:
|
|
20112
|
-
target: "
|
|
20220
|
+
id: "naro-adapter-cloudflare",
|
|
20221
|
+
priority: 2,
|
|
20222
|
+
target: "cloudflare",
|
|
20113
20223
|
supports(context) {
|
|
20114
|
-
if (!context.
|
|
20224
|
+
if (!context.toolchain.nextAdapter)
|
|
20225
|
+
return { supported: false, reason: NARO_ADAPTER_REASONS.notInstalled };
|
|
20226
|
+
const verdict = judgeNextVersion(context.nextVersion);
|
|
20227
|
+
if (!verdict)
|
|
20228
|
+
return {
|
|
20229
|
+
supported: false,
|
|
20230
|
+
reason: NARO_ADAPTER_REASONS.unknownVersion
|
|
20231
|
+
};
|
|
20232
|
+
if (verdict.kind === "too-old")
|
|
20115
20233
|
return {
|
|
20116
20234
|
supported: false,
|
|
20117
|
-
reason:
|
|
20235
|
+
reason: `The Naro adapter needs Next.js 16.2 or newer; this project runs Next.js ${context.nextVersion}.`
|
|
20118
20236
|
};
|
|
20119
|
-
|
|
20237
|
+
const adapter = userAdapterOf(context);
|
|
20238
|
+
if (adapter && context.userAdapter === "keep")
|
|
20120
20239
|
return {
|
|
20121
20240
|
supported: false,
|
|
20122
|
-
reason:
|
|
20241
|
+
reason: `The project keeps its own Next.js adapter (${describeUserAdapter(adapter)}) by its Next.js adapter setting, so the Naro adapter is skipped.`
|
|
20123
20242
|
};
|
|
20124
20243
|
return { supported: true };
|
|
20125
20244
|
},
|
|
20126
20245
|
async evaluate(context, observer) {
|
|
20127
|
-
|
|
20128
|
-
|
|
20129
|
-
|
|
20130
|
-
)
|
|
20246
|
+
const adapterPath = context.toolchain.nextAdapter;
|
|
20247
|
+
if (!adapterPath)
|
|
20248
|
+
return { status: "skipped", reason: NARO_ADAPTER_REASONS.notInstalled };
|
|
20249
|
+
if (judgeNextVersion(context.nextVersion)?.kind === "newer")
|
|
20250
|
+
await warn(
|
|
20251
|
+
observer,
|
|
20252
|
+
`Next.js ${context.nextVersion} is newer than the versions the Naro adapter is tested with (${testedRange()}); building anyway.`
|
|
20253
|
+
);
|
|
20131
20254
|
let fork;
|
|
20132
20255
|
try {
|
|
20133
|
-
fork = await context.workspace.fork("
|
|
20256
|
+
fork = await context.workspace.fork("naro-adapter");
|
|
20134
20257
|
} catch (error51) {
|
|
20135
20258
|
return failed("prepare", describeError(error51));
|
|
20136
20259
|
}
|
|
20137
|
-
|
|
20138
|
-
|
|
20139
|
-
|
|
20140
|
-
|
|
20141
|
-
|
|
20142
|
-
|
|
20143
|
-
|
|
20144
|
-
|
|
20145
|
-
|
|
20146
|
-
|
|
20147
|
-
|
|
20260
|
+
await rm2(join15(fork.appRoot, OUTPUT_DIR), {
|
|
20261
|
+
recursive: true,
|
|
20262
|
+
force: true
|
|
20263
|
+
});
|
|
20264
|
+
const userAdapter = userAdapterOf(context);
|
|
20265
|
+
if (userAdapter && userAdapter.source !== "build-output") {
|
|
20266
|
+
let replaced = true;
|
|
20267
|
+
if (userAdapter.source === "next-config") {
|
|
20268
|
+
try {
|
|
20269
|
+
replaced = await wrapNextConfig(fork.appRoot, userAdapter.file) !== null;
|
|
20270
|
+
} catch (error51) {
|
|
20271
|
+
return failed("prepare", describeError(error51));
|
|
20272
|
+
}
|
|
20273
|
+
}
|
|
20274
|
+
if (replaced) await warn(observer, replaceWarning(userAdapter));
|
|
20148
20275
|
}
|
|
20149
20276
|
const build = await runStep(
|
|
20150
20277
|
context,
|
|
20151
20278
|
{
|
|
20152
|
-
command: context.
|
|
20153
|
-
args: ["
|
|
20279
|
+
command: context.packageManager.name,
|
|
20280
|
+
args: ["run", context.buildScript],
|
|
20154
20281
|
cwd: fork.appRoot,
|
|
20155
20282
|
env: {
|
|
20156
20283
|
...context.env,
|
|
20157
|
-
|
|
20284
|
+
NEXT_ADAPTER_PATH: adapterPath,
|
|
20285
|
+
NPM_CONFIG_USERCONFIG: context.packageManagerConfigPath,
|
|
20286
|
+
CI: "1"
|
|
20158
20287
|
},
|
|
20159
|
-
timeoutMs:
|
|
20160
|
-
stage: "BUILDING",
|
|
20161
|
-
errorCode: "BUILD_FAILED"
|
|
20162
|
-
},
|
|
20163
|
-
observer
|
|
20164
|
-
);
|
|
20165
|
-
if (!build.ok) return failed("build", describeFailure(build));
|
|
20166
|
-
const serverFunction = join14(fork.appRoot, SERVER_FUNCTION);
|
|
20167
|
-
if (!await pathExists2(serverFunction))
|
|
20168
|
-
return failed("bundle", `OpenNext AWS produced no ${SERVER_FUNCTION}.`);
|
|
20169
|
-
const smoke = await context.ports.smoke.run(
|
|
20170
|
-
{
|
|
20171
|
-
boot: (port) => ({
|
|
20172
|
-
command: process.execPath,
|
|
20173
|
-
args: [serverFunction],
|
|
20174
|
-
cwd: fork.appRoot,
|
|
20175
|
-
env: { ...context.env, PORT: String(port), NODE_ENV: "production" }
|
|
20176
|
-
}),
|
|
20177
|
-
probes: defaultSmokeProbes(context.facts.matcherRoutes),
|
|
20288
|
+
timeoutMs: 15 * 6e4,
|
|
20178
20289
|
stage: "BUILDING",
|
|
20179
20290
|
errorCode: "BUILD_FAILED"
|
|
20180
20291
|
},
|
|
20181
20292
|
observer
|
|
20182
20293
|
);
|
|
20183
|
-
if (!
|
|
20184
|
-
|
|
20185
|
-
status: "success",
|
|
20186
|
-
artifact: {
|
|
20187
|
-
kind: "opennext-aws",
|
|
20188
|
-
outputRoot: join14(fork.appRoot, ".open-next"),
|
|
20189
|
-
serverFunction
|
|
20190
|
-
},
|
|
20191
|
-
notes: [
|
|
20192
|
-
"Verified with the Node wrapper; an AWS deploy needs a Lambda-wrapper build against provisioned resources."
|
|
20193
|
-
]
|
|
20194
|
-
};
|
|
20195
|
-
}
|
|
20196
|
-
};
|
|
20197
|
-
}
|
|
20198
|
-
|
|
20199
|
-
// ../../packages/build/src/strategy/strategies/opennext-cloudflare.ts
|
|
20200
|
-
import { readFile as readFile12 } from "fs/promises";
|
|
20201
|
-
import { join as join15 } from "path";
|
|
20202
|
-
var PROXY_TO_MIDDLEWARE_VARIANT = "proxy-to-middleware";
|
|
20203
|
-
var NODE_MIDDLEWARE_REFUSAL = /Node\.js middleware is not (?:currently )?supported/i;
|
|
20204
|
-
var NODE_MIDDLEWARE_EXPERIMENTAL = /Node\.js middleware support is experimental/i;
|
|
20205
|
-
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';
|
|
20206
|
-
async function buildDeclaresNodeMiddleware(appRoot) {
|
|
20207
|
-
try {
|
|
20208
|
-
const manifest2 = JSON.parse(
|
|
20209
|
-
await readFile12(
|
|
20210
|
-
join15(appRoot, ".next", "server", "functions-config-manifest.json"),
|
|
20211
|
-
"utf8"
|
|
20212
|
-
)
|
|
20213
|
-
);
|
|
20214
|
-
return Boolean(manifest2.functions?.["/_middleware"]);
|
|
20215
|
-
} catch {
|
|
20216
|
-
return false;
|
|
20217
|
-
}
|
|
20218
|
-
}
|
|
20219
|
-
function createOpenNextCloudflareStrategy(options) {
|
|
20220
|
-
async function attempt(context, roots, observer, ownBuild, adapterNotice) {
|
|
20221
|
-
let platform;
|
|
20222
|
-
try {
|
|
20223
|
-
platform = await options.createPlatformBuildConfig(
|
|
20224
|
-
roots.appRoot,
|
|
20225
|
-
context.identity.deploymentId
|
|
20226
|
-
);
|
|
20227
|
-
} catch (error51) {
|
|
20228
|
-
return {
|
|
20229
|
-
ok: false,
|
|
20230
|
-
nodeMiddleware: null,
|
|
20231
|
-
outcome: failed("prepare", describeError(error51))
|
|
20232
|
-
};
|
|
20233
|
-
}
|
|
20234
|
-
const nextBuild = await runStep(
|
|
20235
|
-
context,
|
|
20236
|
-
{
|
|
20237
|
-
command: context.packageManager.name,
|
|
20238
|
-
args: ["run", context.buildScript],
|
|
20239
|
-
cwd: roots.appRoot,
|
|
20240
|
-
env: {
|
|
20241
|
-
...context.env,
|
|
20242
|
-
NEXT_PRIVATE_STANDALONE: "true",
|
|
20243
|
-
NPM_CONFIG_USERCONFIG: platform.packageManagerConfigPath
|
|
20244
|
-
},
|
|
20245
|
-
timeoutMs: 15 * 6e4,
|
|
20246
|
-
stage: "BUILDING",
|
|
20247
|
-
errorCode: "BUILD_FAILED"
|
|
20248
|
-
},
|
|
20249
|
-
observer
|
|
20250
|
-
);
|
|
20251
|
-
if (!nextBuild.ok) {
|
|
20252
|
-
return {
|
|
20253
|
-
ok: false,
|
|
20254
|
-
nodeMiddleware: null,
|
|
20255
|
-
outcome: ownBuild ? appBuildFailed(describeFailure(nextBuild)) : failed("build", describeFailure(nextBuild))
|
|
20256
|
-
};
|
|
20257
|
-
}
|
|
20258
|
-
if (!adapterNotice.warned) {
|
|
20259
|
-
const adapter = userAdapterOf(context) ?? await adapterInBuildOutput(roots.appRoot, context.nextVersion);
|
|
20260
|
-
if (adapter) {
|
|
20261
|
-
adapterNotice.warned = true;
|
|
20262
|
-
await warn(observer, openNextAdapterWarning(adapter));
|
|
20263
|
-
}
|
|
20264
|
-
}
|
|
20265
|
-
if (await buildDeclaresNodeMiddleware(roots.appRoot)) {
|
|
20266
|
-
return {
|
|
20267
|
-
ok: false,
|
|
20268
|
-
nodeMiddleware: "experimental",
|
|
20269
|
-
outcome: failed("build", NODE_MIDDLEWARE_NOT_DEPLOYED)
|
|
20270
|
-
};
|
|
20271
|
-
}
|
|
20272
|
-
const openNext = await runStep(
|
|
20273
|
-
context,
|
|
20274
|
-
{
|
|
20275
|
-
command: context.toolchain.openNextCloudflare,
|
|
20276
|
-
args: [
|
|
20277
|
-
"build",
|
|
20278
|
-
"--skip-next-build",
|
|
20279
|
-
"--openNextConfigPath",
|
|
20280
|
-
platform.openNextConfigPath,
|
|
20281
|
-
"--config",
|
|
20282
|
-
platform.wranglerConfigPath,
|
|
20283
|
-
...context.nextSupport.status === "needs-unsupported-flag" ? ["--dangerouslyUseUnsupportedNextVersion"] : []
|
|
20284
|
-
],
|
|
20285
|
-
cwd: roots.appRoot,
|
|
20286
|
-
timeoutMs: 15 * 6e4,
|
|
20287
|
-
stage: "BUILDING",
|
|
20288
|
-
errorCode: "OPENNEXT_FAILED"
|
|
20289
|
-
},
|
|
20290
|
-
observer
|
|
20291
|
-
);
|
|
20292
|
-
if (!openNext.ok) {
|
|
20293
|
-
const refused = openNext.output.some(
|
|
20294
|
-
(line) => NODE_MIDDLEWARE_REFUSAL.test(line)
|
|
20295
|
-
);
|
|
20296
|
-
return {
|
|
20297
|
-
ok: false,
|
|
20298
|
-
nodeMiddleware: refused ? "refused" : null,
|
|
20299
|
-
outcome: failed(
|
|
20300
|
-
"build",
|
|
20301
|
-
refused ? NODE_MIDDLEWARE_NOT_DEPLOYED : describeFailure(openNext)
|
|
20302
|
-
)
|
|
20303
|
-
};
|
|
20304
|
-
}
|
|
20305
|
-
if (openNext.output.some((line) => NODE_MIDDLEWARE_EXPERIMENTAL.test(line))) {
|
|
20306
|
-
return {
|
|
20307
|
-
ok: false,
|
|
20308
|
-
nodeMiddleware: "experimental",
|
|
20309
|
-
outcome: failed("build", NODE_MIDDLEWARE_NOT_DEPLOYED)
|
|
20310
|
-
};
|
|
20311
|
-
}
|
|
20312
|
-
const layout = {
|
|
20313
|
-
appRoot: roots.appRoot,
|
|
20314
|
-
wranglerConfigPath: platform.wranglerConfigPath,
|
|
20315
|
-
...OPEN_NEXT_LAYOUT
|
|
20316
|
-
};
|
|
20317
|
-
const bundle = await bundleWorker(
|
|
20318
|
-
context,
|
|
20319
|
-
layout,
|
|
20320
|
-
observer,
|
|
20321
|
-
"OPENNEXT_FAILED"
|
|
20322
|
-
);
|
|
20323
|
-
if (!bundle.ok) {
|
|
20324
|
-
return {
|
|
20325
|
-
ok: false,
|
|
20326
|
-
nodeMiddleware: null,
|
|
20327
|
-
outcome: failed("bundle", describeFailure(bundle))
|
|
20328
|
-
};
|
|
20329
|
-
}
|
|
20330
|
-
let artifact;
|
|
20331
|
-
try {
|
|
20332
|
-
artifact = await options.readOpenNextArtifact(
|
|
20333
|
-
roots.appRoot,
|
|
20334
|
-
context.identity,
|
|
20335
|
-
platform.wranglerConfigPath
|
|
20336
|
-
);
|
|
20337
|
-
} catch (error51) {
|
|
20338
|
-
return {
|
|
20339
|
-
ok: false,
|
|
20340
|
-
nodeMiddleware: null,
|
|
20341
|
-
outcome: failed("bundle", describeError(error51))
|
|
20342
|
-
};
|
|
20343
|
-
}
|
|
20344
|
-
const smoke = await smokeWorker(context, layout, observer);
|
|
20345
|
-
if (!smoke.ok) {
|
|
20346
|
-
return {
|
|
20347
|
-
ok: false,
|
|
20348
|
-
nodeMiddleware: null,
|
|
20349
|
-
outcome: failed("smoke", smoke.reason)
|
|
20350
|
-
};
|
|
20351
|
-
}
|
|
20352
|
-
return { ok: true, artifact };
|
|
20353
|
-
}
|
|
20354
|
-
return {
|
|
20355
|
-
id: "opennext-cloudflare",
|
|
20356
|
-
priority: 2,
|
|
20357
|
-
target: "cloudflare",
|
|
20358
|
-
supports: () => ({ supported: true }),
|
|
20359
|
-
async evaluate(context, observer) {
|
|
20360
|
-
const adapterNotice = { warned: false };
|
|
20361
|
-
const rememberedRewrite = context.pinnedVariant === PROXY_TO_MIDDLEWARE_VARIANT && context.facts.proxyFile !== null;
|
|
20362
|
-
if (rememberedRewrite) {
|
|
20363
|
-
await info(
|
|
20364
|
-
observer,
|
|
20365
|
-
`P2 opennext-cloudflare: the stored strategy already needed ${context.facts.proxyFile ?? "proxy"} rewritten to Edge middleware; building that way directly.`
|
|
20366
|
-
);
|
|
20367
|
-
} else {
|
|
20368
|
-
await info(
|
|
20369
|
-
observer,
|
|
20370
|
-
"P2 opennext-cloudflare: building the project as written."
|
|
20371
|
-
);
|
|
20372
|
-
const first = await attempt(
|
|
20373
|
-
context,
|
|
20374
|
-
context.workspace,
|
|
20375
|
-
observer,
|
|
20376
|
-
true,
|
|
20377
|
-
adapterNotice
|
|
20378
|
-
);
|
|
20379
|
-
if (first.ok) {
|
|
20294
|
+
if (!build.ok) {
|
|
20295
|
+
if (!await pathExists(join15(fork.appRoot, BUILD_RECORD)))
|
|
20380
20296
|
return {
|
|
20381
|
-
status: "
|
|
20382
|
-
|
|
20383
|
-
|
|
20297
|
+
status: "failed",
|
|
20298
|
+
stage: "build",
|
|
20299
|
+
reason: describeFailure(build),
|
|
20300
|
+
appBuild: true
|
|
20384
20301
|
};
|
|
20385
|
-
|
|
20386
|
-
|
|
20387
|
-
|
|
20388
|
-
|
|
20389
|
-
|
|
20390
|
-
|
|
20302
|
+
return failed("bundle", describeFailure(build));
|
|
20303
|
+
}
|
|
20304
|
+
const record3 = await readRecord(fork.appRoot);
|
|
20305
|
+
if (!record3 || await readBuildId(record3.distDir) !== record3.buildId) {
|
|
20306
|
+
const ran = await adapterInBuildOutput(
|
|
20307
|
+
fork.appRoot,
|
|
20308
|
+
context.nextVersion
|
|
20309
|
+
);
|
|
20310
|
+
return failed(
|
|
20311
|
+
"build",
|
|
20312
|
+
ran?.source === "build-output" && resolve5(fork.appRoot, ran.path) !== resolve5(adapterPath) ? NARO_ADAPTER_REASONS.userAdapterRan(ran.key) : NARO_ADAPTER_REASONS.missingOutput
|
|
20391
20313
|
);
|
|
20392
20314
|
}
|
|
20393
|
-
let
|
|
20315
|
+
let artifact;
|
|
20394
20316
|
try {
|
|
20395
|
-
|
|
20317
|
+
artifact = await options.readArtifact(fork.appRoot, context.identity);
|
|
20396
20318
|
} catch (error51) {
|
|
20397
|
-
return failed("
|
|
20398
|
-
}
|
|
20399
|
-
const conversion = await options.convertProxyToMiddleware(fork.appRoot);
|
|
20400
|
-
if (!conversion.converted) {
|
|
20401
|
-
return failed(
|
|
20402
|
-
"prepare",
|
|
20403
|
-
`Could not rewrite ${context.facts.proxyFile} to middleware (a middleware file already exists).`
|
|
20404
|
-
);
|
|
20319
|
+
return failed("bundle", describeError(error51));
|
|
20405
20320
|
}
|
|
20406
|
-
await
|
|
20407
|
-
observer,
|
|
20408
|
-
`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.`
|
|
20409
|
-
);
|
|
20410
|
-
const second = await attempt(
|
|
20321
|
+
const smoke = await smokeWorker(
|
|
20411
20322
|
context,
|
|
20412
|
-
|
|
20323
|
+
{
|
|
20324
|
+
appRoot: fork.appRoot,
|
|
20325
|
+
wranglerConfigPath: join15(fork.appRoot, WRANGLER_CONFIG),
|
|
20326
|
+
outputRoot: OUTPUT_DIR
|
|
20327
|
+
},
|
|
20413
20328
|
observer,
|
|
20414
|
-
|
|
20415
|
-
|
|
20329
|
+
naroAdapterSmokeProbes(
|
|
20330
|
+
record3,
|
|
20331
|
+
artifact.assets.map((asset) => asset.name)
|
|
20332
|
+
)
|
|
20416
20333
|
);
|
|
20417
|
-
if (!
|
|
20418
|
-
if (!rememberedRewrite || second.outcome.status !== "failed" || !second.outcome.appBuild)
|
|
20419
|
-
return second.outcome;
|
|
20420
|
-
await info(
|
|
20421
|
-
observer,
|
|
20422
|
-
`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.`
|
|
20423
|
-
);
|
|
20424
|
-
const asWritten = await attempt(
|
|
20425
|
-
context,
|
|
20426
|
-
context.workspace,
|
|
20427
|
-
observer,
|
|
20428
|
-
true,
|
|
20429
|
-
adapterNotice
|
|
20430
|
-
);
|
|
20431
|
-
if (asWritten.ok) {
|
|
20432
|
-
await info(
|
|
20433
|
-
observer,
|
|
20434
|
-
"P2 opennext-cloudflare: the project as written builds and ships as it is; the rewrite is no longer needed."
|
|
20435
|
-
);
|
|
20436
|
-
return {
|
|
20437
|
-
status: "success",
|
|
20438
|
-
artifact: {
|
|
20439
|
-
kind: "cloudflare-worker",
|
|
20440
|
-
artifact: asWritten.artifact
|
|
20441
|
-
},
|
|
20442
|
-
notes: []
|
|
20443
|
-
};
|
|
20444
|
-
}
|
|
20445
|
-
if (asWritten.outcome.status === "failed" && asWritten.outcome.appBuild) {
|
|
20446
|
-
await warn(
|
|
20447
|
-
observer,
|
|
20448
|
-
"P2 opennext-cloudflare: the project as written does not build either, so the error is the app's own."
|
|
20449
|
-
);
|
|
20450
|
-
return asWritten.outcome;
|
|
20451
|
-
}
|
|
20452
|
-
await warn(
|
|
20453
|
-
observer,
|
|
20454
|
-
"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."
|
|
20455
|
-
);
|
|
20456
|
-
return failed("build", second.outcome.reason);
|
|
20457
|
-
}
|
|
20334
|
+
if (!smoke.ok) return failed("smoke", smoke.reason);
|
|
20458
20335
|
return {
|
|
20459
20336
|
status: "success",
|
|
20460
|
-
artifact: { kind: "cloudflare-worker", artifact
|
|
20461
|
-
variant: PROXY_TO_MIDDLEWARE_VARIANT,
|
|
20337
|
+
artifact: { kind: "cloudflare-worker", artifact },
|
|
20462
20338
|
notes: [
|
|
20463
|
-
|
|
20339
|
+
"Built with the Naro adapter (Next.js Adapter API) in a temporary workspace."
|
|
20464
20340
|
]
|
|
20465
20341
|
};
|
|
20466
20342
|
}
|
|
20467
20343
|
};
|
|
20468
20344
|
}
|
|
20469
20345
|
|
|
20470
|
-
// ../../packages/build/src/strategy/strategies/unavailable.ts
|
|
20471
|
-
function createUnavailableStrategy(options) {
|
|
20472
|
-
return {
|
|
20473
|
-
id: options.id,
|
|
20474
|
-
priority: options.priority,
|
|
20475
|
-
target: options.target,
|
|
20476
|
-
supports: () => ({ supported: false, reason: options.reason }),
|
|
20477
|
-
evaluate: async () => ({ status: "skipped", reason: options.reason })
|
|
20478
|
-
};
|
|
20479
|
-
}
|
|
20480
|
-
function createSplitCloudflareStrategy() {
|
|
20481
|
-
return createUnavailableStrategy({
|
|
20482
|
-
id: "split-cloudflare",
|
|
20483
|
-
priority: 3,
|
|
20484
|
-
target: "cloudflare-split",
|
|
20485
|
-
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."
|
|
20486
|
-
});
|
|
20487
|
-
}
|
|
20488
|
-
function createAwsMiddlewareCloudflareAppStrategy() {
|
|
20489
|
-
return createUnavailableStrategy({
|
|
20490
|
-
id: "aws-middleware-cloudflare-app",
|
|
20491
|
-
priority: 4,
|
|
20492
|
-
target: "aws-hybrid",
|
|
20493
|
-
reason: "Hybrid AWS middleware + Cloudflare app needs an AWS deploy target and cross-cloud request chaining; neither exists on this control plane."
|
|
20494
|
-
});
|
|
20495
|
-
}
|
|
20496
|
-
|
|
20497
20346
|
// ../../packages/build/src/strategy/strategies/vinext-cloudflare.ts
|
|
20498
20347
|
var VINEXT_MIN_NEXT_MAJOR = 16;
|
|
20499
20348
|
var VINEXT_BUILD_SCRIPTS = ["esbuild", "workerd"];
|
|
@@ -20568,6 +20417,7 @@ function createVinextCloudflareStrategy(options) {
|
|
|
20568
20417
|
observer,
|
|
20569
20418
|
"P1 vinext-cloudflare: the project already builds with vinext; using its own configuration."
|
|
20570
20419
|
);
|
|
20420
|
+
await info(observer, ISR_SHARED_CACHE_OFF_NOTE);
|
|
20571
20421
|
}
|
|
20572
20422
|
let fork;
|
|
20573
20423
|
try {
|
|
@@ -20618,6 +20468,17 @@ function createVinextCloudflareStrategy(options) {
|
|
|
20618
20468
|
);
|
|
20619
20469
|
if (!added.ok) return failed("prepare", describeFailure(added));
|
|
20620
20470
|
}
|
|
20471
|
+
try {
|
|
20472
|
+
await wrapNextConfigForAssetPrefix(
|
|
20473
|
+
fork.appRoot,
|
|
20474
|
+
context.env[STATIC_ASSET_PREFIX_ENV]
|
|
20475
|
+
);
|
|
20476
|
+
} catch (error51) {
|
|
20477
|
+
await warn(
|
|
20478
|
+
observer,
|
|
20479
|
+
`Could not point static assets at static.naro.sh: ${describeError(error51)}`
|
|
20480
|
+
);
|
|
20481
|
+
}
|
|
20621
20482
|
const projectBin = adopt ? null : await findProjectBin(fork.appRoot, fork.checkout, "vinext");
|
|
20622
20483
|
const build = await runStep(
|
|
20623
20484
|
context,
|
|
@@ -20665,13 +20526,13 @@ function createVinextCloudflareStrategy(options) {
|
|
|
20665
20526
|
|
|
20666
20527
|
// ../../packages/build/src/strategy/workspace.ts
|
|
20667
20528
|
import { execFile } from "child_process";
|
|
20668
|
-
import { cp, mkdir as mkdir2, readdir as readdir4, rm as
|
|
20669
|
-
import { basename
|
|
20529
|
+
import { cp, mkdir as mkdir2, readdir as readdir4, rm as rm3 } from "fs/promises";
|
|
20530
|
+
import { basename, dirname as dirname2, join as join16, relative as relative5, resolve as resolve6 } from "path";
|
|
20670
20531
|
import { promisify } from "util";
|
|
20671
20532
|
var execFileAsync = promisify(execFile);
|
|
20672
20533
|
var SKIPPED_ANYWHERE = /* @__PURE__ */ new Set(["node_modules"]);
|
|
20673
20534
|
function shouldCopy(path) {
|
|
20674
|
-
const name =
|
|
20535
|
+
const name = basename(path);
|
|
20675
20536
|
if (SKIPPED_ANYWHERE.has(name)) return false;
|
|
20676
20537
|
return !name.startsWith(".next-deploy-");
|
|
20677
20538
|
}
|
|
@@ -20699,13 +20560,13 @@ async function copyInstalledPackages(source, target2) {
|
|
|
20699
20560
|
await copyTree(install, join16(target2, relative5(origin, install)));
|
|
20700
20561
|
}
|
|
20701
20562
|
async function copyTree(from, to) {
|
|
20702
|
-
await mkdir2(
|
|
20563
|
+
await mkdir2(dirname2(to), { recursive: true });
|
|
20703
20564
|
if (process.platform !== "win32") {
|
|
20704
20565
|
try {
|
|
20705
20566
|
await execFileAsync("cp", ["-a", from, to]);
|
|
20706
20567
|
return;
|
|
20707
20568
|
} catch {
|
|
20708
|
-
await
|
|
20569
|
+
await rm3(to, { recursive: true, force: true });
|
|
20709
20570
|
}
|
|
20710
20571
|
}
|
|
20711
20572
|
await cp(from, to, { recursive: true, verbatimSymlinks: true });
|
|
@@ -20733,27 +20594,26 @@ async function withRouteList(artifact, list, appRoot, observer) {
|
|
|
20733
20594
|
return artifact;
|
|
20734
20595
|
}
|
|
20735
20596
|
}
|
|
20597
|
+
var NEXT_ADAPTER_PATH = nextAdapterPath();
|
|
20736
20598
|
var defaultLocalBuildDependencies = {
|
|
20737
20599
|
createWorkspace: () => mkdtemp(join17(tmpdir(), "next-deploy-build-")),
|
|
20738
|
-
removeWorkspace: (path) =>
|
|
20600
|
+
removeWorkspace: (path) => rm4(path, { recursive: true, force: true }),
|
|
20739
20601
|
runCommand,
|
|
20740
20602
|
detectPackageManager,
|
|
20741
20603
|
resolveAppRoot,
|
|
20742
20604
|
detectFramework,
|
|
20743
20605
|
readStaticArtifact,
|
|
20744
20606
|
createPackageManagerConfig,
|
|
20745
|
-
createPlatformBuildConfig,
|
|
20746
|
-
readOpenNextArtifact,
|
|
20747
|
-
openNextCommand: "opennextjs-cloudflare",
|
|
20748
20607
|
wranglerCommand: "wrangler",
|
|
20749
20608
|
cacheFetch: (input, init) => fetch(input, init),
|
|
20750
|
-
convertProxyToMiddleware,
|
|
20751
20609
|
commandAvailable: hasCommand,
|
|
20752
20610
|
readInstalledNextVersion,
|
|
20753
20611
|
now: () => /* @__PURE__ */ new Date(),
|
|
20754
20612
|
createVinextBuildConfig,
|
|
20755
20613
|
readVinextArtifact,
|
|
20756
20614
|
vinextCommand: "vinext",
|
|
20615
|
+
...NEXT_ADAPTER_PATH ? { nextAdapterPath: NEXT_ADAPTER_PATH } : {},
|
|
20616
|
+
readNaroAdapterArtifact,
|
|
20757
20617
|
forkWorkspace: copyCheckout,
|
|
20758
20618
|
copyInstalledPackages,
|
|
20759
20619
|
collectProjectFacts,
|
|
@@ -20768,7 +20628,7 @@ async function readInstalledNextVersion(appRoot, checkout) {
|
|
|
20768
20628
|
const stop = resolve7(checkout);
|
|
20769
20629
|
for (; ; ) {
|
|
20770
20630
|
try {
|
|
20771
|
-
const source = await
|
|
20631
|
+
const source = await readFile14(
|
|
20772
20632
|
join17(dir, "node_modules", "next", "package.json"),
|
|
20773
20633
|
"utf8"
|
|
20774
20634
|
);
|
|
@@ -20777,7 +20637,7 @@ async function readInstalledNextVersion(appRoot, checkout) {
|
|
|
20777
20637
|
} catch {
|
|
20778
20638
|
}
|
|
20779
20639
|
if (dir === stop) return null;
|
|
20780
|
-
const parent =
|
|
20640
|
+
const parent = dirname3(dir);
|
|
20781
20641
|
if (parent === dir) return null;
|
|
20782
20642
|
dir = parent;
|
|
20783
20643
|
}
|
|
@@ -20800,9 +20660,9 @@ async function hasCommand(command) {
|
|
|
20800
20660
|
return false;
|
|
20801
20661
|
}
|
|
20802
20662
|
}
|
|
20803
|
-
async function
|
|
20663
|
+
async function pathExists2(path) {
|
|
20804
20664
|
try {
|
|
20805
|
-
await
|
|
20665
|
+
await access6(path);
|
|
20806
20666
|
return true;
|
|
20807
20667
|
} catch {
|
|
20808
20668
|
return false;
|
|
@@ -20846,14 +20706,11 @@ function defaultStrategies(dependencies) {
|
|
|
20846
20706
|
createVinextBuildConfig: dependencies.createVinextBuildConfig ?? createVinextBuildConfig,
|
|
20847
20707
|
readVinextArtifact: dependencies.readVinextArtifact ?? readVinextArtifact
|
|
20848
20708
|
}),
|
|
20849
|
-
|
|
20850
|
-
|
|
20851
|
-
convertProxyToMiddleware: dependencies.convertProxyToMiddleware ?? convertProxyToMiddleware,
|
|
20852
|
-
readOpenNextArtifact: dependencies.readOpenNextArtifact
|
|
20709
|
+
createNaroAdapterCloudflareStrategy({
|
|
20710
|
+
readArtifact: dependencies.readNaroAdapterArtifact ?? readNaroAdapterArtifact
|
|
20853
20711
|
}),
|
|
20854
20712
|
createSplitCloudflareStrategy(),
|
|
20855
|
-
createAwsMiddlewareCloudflareAppStrategy()
|
|
20856
|
-
createOpenNextAwsStrategy()
|
|
20713
|
+
createAwsMiddlewareCloudflareAppStrategy()
|
|
20857
20714
|
];
|
|
20858
20715
|
}
|
|
20859
20716
|
var LocalBuildExecutor = class {
|
|
@@ -21132,7 +20989,7 @@ var LocalBuildExecutor = class {
|
|
|
21132
20989
|
"NEXT_VERSION_UNSUPPORTED",
|
|
21133
20990
|
nextSupport.reason
|
|
21134
20991
|
);
|
|
21135
|
-
if (nextSupport.status === "
|
|
20992
|
+
if (nextSupport.status === "past-support-window" || nextSupport.status === "outside-verified-range") {
|
|
21136
20993
|
await observer.onLog({
|
|
21137
20994
|
level: "WARN",
|
|
21138
20995
|
stage: "BUILDING",
|
|
@@ -21187,11 +21044,10 @@ var LocalBuildExecutor = class {
|
|
|
21187
21044
|
};
|
|
21188
21045
|
};
|
|
21189
21046
|
const vinextCommand = this.dependencies.vinextCommand;
|
|
21190
|
-
const openNextAwsCommand = this.dependencies.openNextAwsCommand;
|
|
21191
21047
|
const context = {
|
|
21192
21048
|
identity,
|
|
21193
21049
|
branch: input.branch,
|
|
21194
|
-
env: input.env
|
|
21050
|
+
env: buildEnvWithStaticPrefix(input.env, input.staticAssetPrefix),
|
|
21195
21051
|
// The toolchain add has to use the store the install linked
|
|
21196
21052
|
// node_modules from (withSharedCache).
|
|
21197
21053
|
packageManager: cachePorts ? withSharedCache(packageManager, pmCacheDir) : packageManager,
|
|
@@ -21199,15 +21055,14 @@ var LocalBuildExecutor = class {
|
|
|
21199
21055
|
buildScript: resolved.buildScript,
|
|
21200
21056
|
nextVersion: nextVersion ? `${String(nextVersion.major)}.${String(nextVersion.minor)}.${String(nextVersion.patch)}` : "unknown",
|
|
21201
21057
|
nextMajor,
|
|
21202
|
-
nextSupport,
|
|
21203
21058
|
vinextEnabled: input.vinextEnabled !== false,
|
|
21059
|
+
userAdapter: input.userAdapter === "keep" ? "keep" : "replace",
|
|
21204
21060
|
facts,
|
|
21205
21061
|
workspace: { checkout, appRoot, fork: forkWorkspace },
|
|
21206
21062
|
toolchain: {
|
|
21207
|
-
openNextCloudflare: this.dependencies.openNextCommand,
|
|
21208
21063
|
wrangler: this.dependencies.wranglerCommand,
|
|
21209
21064
|
...vinextCommand && await commandAvailable(vinextCommand) ? { vinext: vinextCommand } : {},
|
|
21210
|
-
...
|
|
21065
|
+
...this.dependencies.nextAdapterPath && await pathExists2(this.dependencies.nextAdapterPath) ? { nextAdapter: this.dependencies.nextAdapterPath } : {}
|
|
21211
21066
|
},
|
|
21212
21067
|
targets: this.dependencies.targets ?? { cloudflare: true },
|
|
21213
21068
|
ports: {
|
|
@@ -21248,7 +21103,10 @@ var LocalBuildExecutor = class {
|
|
|
21248
21103
|
args: ["run", resolved.buildScript],
|
|
21249
21104
|
cwd: appRoot,
|
|
21250
21105
|
env: {
|
|
21251
|
-
|
|
21106
|
+
// Static presets never get the asset prefix (spec
|
|
21107
|
+
// 2026-11-07-static-asset-cdn §3): a Vite base or CRA
|
|
21108
|
+
// PUBLIC_URL also moves the router and public/ files.
|
|
21109
|
+
...buildEnvWithStaticPrefix(input.env, void 0),
|
|
21252
21110
|
NPM_CONFIG_USERCONFIG: packageManagerConfigPath
|
|
21253
21111
|
},
|
|
21254
21112
|
timeoutMs: 15 * 6e4,
|
|
@@ -21262,7 +21120,7 @@ var LocalBuildExecutor = class {
|
|
|
21262
21120
|
if (depsKey && !depsRestored) {
|
|
21263
21121
|
await trySave("deps", depsKey, pmCacheDir, cachePorts, observer);
|
|
21264
21122
|
}
|
|
21265
|
-
if (buildCacheDir && await
|
|
21123
|
+
if (buildCacheDir && await pathExists2(buildCacheDir)) {
|
|
21266
21124
|
await trySave(
|
|
21267
21125
|
"next",
|
|
21268
21126
|
buildCacheKey,
|
|
@@ -21282,6 +21140,14 @@ var LocalBuildExecutor = class {
|
|
|
21282
21140
|
appRoot,
|
|
21283
21141
|
observer
|
|
21284
21142
|
);
|
|
21143
|
+
const cdn = withStaticAssetPrefix(artifact, input.staticAssetPrefix);
|
|
21144
|
+
if (cdn.note)
|
|
21145
|
+
await observer.onLog({
|
|
21146
|
+
level: "INFO",
|
|
21147
|
+
stage: "DEPLOYING",
|
|
21148
|
+
message: cdn.note
|
|
21149
|
+
});
|
|
21150
|
+
artifact = withImmutableHeaders(cdn.artifact);
|
|
21285
21151
|
return {
|
|
21286
21152
|
gitCommitSha,
|
|
21287
21153
|
artifact,
|
|
@@ -21662,8 +21528,8 @@ function sendPage(res, status, html) {
|
|
|
21662
21528
|
async function startCallbackServer() {
|
|
21663
21529
|
let resolveCode;
|
|
21664
21530
|
let rejectCode;
|
|
21665
|
-
const codePromise = new Promise((
|
|
21666
|
-
resolveCode =
|
|
21531
|
+
const codePromise = new Promise((resolve16, reject) => {
|
|
21532
|
+
resolveCode = resolve16;
|
|
21667
21533
|
rejectCode = reject;
|
|
21668
21534
|
});
|
|
21669
21535
|
const server = createServer2((req, res) => {
|
|
@@ -21692,7 +21558,7 @@ async function startCallbackServer() {
|
|
|
21692
21558
|
sendPage(res, 200, successPage());
|
|
21693
21559
|
resolveCode(code);
|
|
21694
21560
|
});
|
|
21695
|
-
await new Promise((
|
|
21561
|
+
await new Promise((resolve16) => server.listen(0, "127.0.0.1", resolve16));
|
|
21696
21562
|
const port = server.address().port;
|
|
21697
21563
|
return {
|
|
21698
21564
|
port,
|
|
@@ -22190,7 +22056,8 @@ function projectInfo(row) {
|
|
|
22190
22056
|
repositoryUrl: row.repository_url,
|
|
22191
22057
|
repositoryFullName: row.repository_full_name ?? null,
|
|
22192
22058
|
createdAt: row.created_at,
|
|
22193
|
-
updatedAt: row.updated_at
|
|
22059
|
+
updatedAt: row.updated_at,
|
|
22060
|
+
userAdapter: row.user_adapter ?? null
|
|
22194
22061
|
};
|
|
22195
22062
|
}
|
|
22196
22063
|
function deploymentInfo(row) {
|
|
@@ -22361,6 +22228,19 @@ var TeamsApi = class {
|
|
|
22361
22228
|
{ context: "Read team usage" }
|
|
22362
22229
|
);
|
|
22363
22230
|
}
|
|
22231
|
+
/**
|
|
22232
|
+
* The team's hosting compute (CPU) per project and environment for a UTC
|
|
22233
|
+
* month (spec 2026-11-06-hosting-cpu-usage §7). Observed, never billed.
|
|
22234
|
+
*/
|
|
22235
|
+
async usageHosting(teamSlug, query = {}) {
|
|
22236
|
+
const params = new URLSearchParams();
|
|
22237
|
+
if (query.month !== void 0) params.set("month", query.month);
|
|
22238
|
+
const text3 = params.toString();
|
|
22239
|
+
return this.client.request(
|
|
22240
|
+
`/api/teams/${encodeURIComponent(teamSlug)}/usage/hosting${text3 ? `?${text3}` : ""}`,
|
|
22241
|
+
{ context: "Read team hosting usage" }
|
|
22242
|
+
);
|
|
22243
|
+
}
|
|
22364
22244
|
path(teamSlug, suffix = "") {
|
|
22365
22245
|
return `/api/teams/${encodeURIComponent(teamSlug)}${suffix}`;
|
|
22366
22246
|
}
|
|
@@ -22736,7 +22616,7 @@ var DeploymentsApi = class {
|
|
|
22736
22616
|
async wait(deploymentId, options = {}) {
|
|
22737
22617
|
const intervalMs = options.intervalMs ?? 2500;
|
|
22738
22618
|
const timeoutMs = options.timeoutMs ?? 15 * 6e4;
|
|
22739
|
-
const sleep2 = options.sleep ?? ((ms) => new Promise((
|
|
22619
|
+
const sleep2 = options.sleep ?? ((ms) => new Promise((resolve16) => setTimeout(resolve16, ms)));
|
|
22740
22620
|
const startedAt = Date.now();
|
|
22741
22621
|
let lastStatus = null;
|
|
22742
22622
|
let lastSequence = -1;
|
|
@@ -23337,7 +23217,7 @@ var DbApi = class {
|
|
|
23337
23217
|
*/
|
|
23338
23218
|
async export(projectId, options = {}, wait = {}) {
|
|
23339
23219
|
const timeoutMs = wait.timeoutMs ?? EXPORT_TIMEOUT_MS;
|
|
23340
|
-
const sleep2 = wait.sleep ?? ((ms) => new Promise((
|
|
23220
|
+
const sleep2 = wait.sleep ?? ((ms) => new Promise((resolve16) => setTimeout(resolve16, ms)));
|
|
23341
23221
|
const given = wait.pollIntervalMs;
|
|
23342
23222
|
const firstPollMs = given !== void 0 && Number.isFinite(given) && given > 0 ? given : EXPORT_FIRST_POLL_MS;
|
|
23343
23223
|
const maxPollMs = Math.max(EXPORT_MAX_POLL_MS, firstPollMs);
|
|
@@ -26800,8 +26680,8 @@ function readAuth(state, start, allowBareJwt) {
|
|
|
26800
26680
|
stream.expectOperator("(");
|
|
26801
26681
|
stream.expectOperator(")");
|
|
26802
26682
|
if (fn !== "jwt") return { kind: "auth", fn };
|
|
26803
|
-
const
|
|
26804
|
-
if (
|
|
26683
|
+
const access7 = readJwtAccess(stream);
|
|
26684
|
+
if (access7) return access7;
|
|
26805
26685
|
if (allowBareJwt) return "jwt";
|
|
26806
26686
|
throw new PolicySyntaxError(
|
|
26807
26687
|
"auth.jwt() is read one claim at a time: auth.jwt() ->> 'email'",
|
|
@@ -26869,13 +26749,13 @@ function readPrimary(state) {
|
|
|
26869
26749
|
const inner2 = readAuth(state, auth, true);
|
|
26870
26750
|
stream.expectOperator(")");
|
|
26871
26751
|
if (inner2 !== "jwt") return inner2;
|
|
26872
|
-
const
|
|
26873
|
-
if (!
|
|
26752
|
+
const access7 = readJwtAccess(stream);
|
|
26753
|
+
if (!access7)
|
|
26874
26754
|
throw new PolicySyntaxError(
|
|
26875
26755
|
"auth.jwt() is read one claim at a time: (select auth.jwt()) ->> 'email'",
|
|
26876
26756
|
auth.position
|
|
26877
26757
|
);
|
|
26878
|
-
return
|
|
26758
|
+
return access7;
|
|
26879
26759
|
}
|
|
26880
26760
|
const inner = readOr(state);
|
|
26881
26761
|
stream.expectOperator(")");
|
|
@@ -34494,11 +34374,13 @@ function summarizeTeamUsage(report, currentMonth) {
|
|
|
34494
34374
|
};
|
|
34495
34375
|
const meters = USAGE_METRICS.map((metric) => {
|
|
34496
34376
|
const limit = report.limits?.[metric] ?? null;
|
|
34377
|
+
const perProject = metric === "domains" ? report.limits?.domainsPerProject ?? null : null;
|
|
34497
34378
|
return {
|
|
34498
34379
|
metric,
|
|
34499
34380
|
used: used[metric],
|
|
34500
34381
|
limit,
|
|
34501
|
-
percent: limit ? Math.floor(used[metric] * 100 / limit) : null
|
|
34382
|
+
percent: limit ? Math.floor(used[metric] * 100 / limit) : null,
|
|
34383
|
+
perProject
|
|
34502
34384
|
};
|
|
34503
34385
|
});
|
|
34504
34386
|
return {
|
|
@@ -34641,10 +34523,10 @@ var SUPPORTED_REMOTE = [
|
|
|
34641
34523
|
/^ssh:\/\/[^\s]+$/,
|
|
34642
34524
|
/^git@[A-Za-z0-9.-]+:[A-Za-z0-9._/-]+(\.git)?$/
|
|
34643
34525
|
];
|
|
34644
|
-
var defaultExec = (args, cwd) => new Promise((
|
|
34526
|
+
var defaultExec = (args, cwd) => new Promise((resolve16, reject) => {
|
|
34645
34527
|
execFile2("git", args, { cwd }, (error51, stdout) => {
|
|
34646
34528
|
if (error51) reject(error51);
|
|
34647
|
-
else
|
|
34529
|
+
else resolve16(stdout);
|
|
34648
34530
|
});
|
|
34649
34531
|
});
|
|
34650
34532
|
async function tryExec(exec, args, cwd) {
|
|
@@ -34793,15 +34675,52 @@ async function uploadArtifact(artifact, opts) {
|
|
|
34793
34675
|
};
|
|
34794
34676
|
}
|
|
34795
34677
|
|
|
34678
|
+
// src/user-adapter.ts
|
|
34679
|
+
import { resolve as resolve10 } from "path";
|
|
34680
|
+
async function detectUserAdapter(directory, rootDirectory) {
|
|
34681
|
+
return findAdapterConfig(
|
|
34682
|
+
rootDirectory ? resolve10(directory, rootDirectory) : directory
|
|
34683
|
+
);
|
|
34684
|
+
}
|
|
34685
|
+
function parseUserAdapter(value) {
|
|
34686
|
+
return value === "replace" || value === "keep" ? value : null;
|
|
34687
|
+
}
|
|
34688
|
+
var USER_ADAPTER_OPTIONS = [
|
|
34689
|
+
{
|
|
34690
|
+
value: "replace",
|
|
34691
|
+
label: "Replace it with the Naro adapter on Naro's builders (recommended) \u2014 your repository stays as it is"
|
|
34692
|
+
},
|
|
34693
|
+
{ value: "keep", label: "Keep my adapter \u2014 Naro builds with vinext only" }
|
|
34694
|
+
];
|
|
34695
|
+
function userAdapterQuestion(adapter) {
|
|
34696
|
+
return `${adapter.file} sets its own Next.js adapter (${adapter.key}). How should Naro build this project?`;
|
|
34697
|
+
}
|
|
34698
|
+
function userAdapterOutcome(choice) {
|
|
34699
|
+
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.";
|
|
34700
|
+
}
|
|
34701
|
+
function userAdapterStored(adapter, choice) {
|
|
34702
|
+
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.`;
|
|
34703
|
+
}
|
|
34704
|
+
function userAdapterUnasked(adapter) {
|
|
34705
|
+
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.`;
|
|
34706
|
+
}
|
|
34707
|
+
var CHOOSE_USER_ADAPTER = {
|
|
34708
|
+
cli: "naro project set --user-adapter replace|keep",
|
|
34709
|
+
mcp: "update_project with userAdapter replace|keep"
|
|
34710
|
+
};
|
|
34711
|
+
function userAdapterUnreadable(adapter, surface = "cli") {
|
|
34712
|
+
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]}.`;
|
|
34713
|
+
}
|
|
34714
|
+
|
|
34796
34715
|
// src/version.ts
|
|
34797
34716
|
import { readFileSync as readFileSync6 } from "fs";
|
|
34798
|
-
import { dirname as
|
|
34799
|
-
import { fileURLToPath } from "url";
|
|
34717
|
+
import { dirname as dirname4, join as join24 } from "path";
|
|
34718
|
+
import { fileURLToPath as fileURLToPath2 } from "url";
|
|
34800
34719
|
function version2() {
|
|
34801
34720
|
try {
|
|
34802
34721
|
const pkg = JSON.parse(
|
|
34803
34722
|
readFileSync6(
|
|
34804
|
-
join24(
|
|
34723
|
+
join24(dirname4(fileURLToPath2(import.meta.url)), "..", "package.json"),
|
|
34805
34724
|
"utf8"
|
|
34806
34725
|
)
|
|
34807
34726
|
);
|
|
@@ -34817,22 +34736,22 @@ import {
|
|
|
34817
34736
|
cp as cp2,
|
|
34818
34737
|
lstat,
|
|
34819
34738
|
mkdir as mkdir3,
|
|
34820
|
-
readFile as
|
|
34739
|
+
readFile as readFile15,
|
|
34821
34740
|
readlink,
|
|
34822
34741
|
realpath as realpath3,
|
|
34823
|
-
rm as
|
|
34742
|
+
rm as rm5,
|
|
34824
34743
|
stat as stat3,
|
|
34825
34744
|
symlink,
|
|
34826
34745
|
unlink,
|
|
34827
|
-
writeFile as
|
|
34746
|
+
writeFile as writeFile6
|
|
34828
34747
|
} from "fs/promises";
|
|
34829
34748
|
import {
|
|
34830
|
-
basename as
|
|
34831
|
-
dirname as
|
|
34749
|
+
basename as basename2,
|
|
34750
|
+
dirname as dirname5,
|
|
34832
34751
|
isAbsolute as isAbsolute4,
|
|
34833
34752
|
join as join25,
|
|
34834
34753
|
relative as relative6,
|
|
34835
|
-
resolve as
|
|
34754
|
+
resolve as resolve11,
|
|
34836
34755
|
sep as sep5
|
|
34837
34756
|
} from "path";
|
|
34838
34757
|
var COPY_SKIP = /(^|[\\/])(node_modules|\.next|\.open-next|\.git|\.wrangler|\.turbo|\.naro)([\\/]|$)/;
|
|
@@ -34862,7 +34781,7 @@ async function committedEnvFiles(sourceDir) {
|
|
|
34862
34781
|
if (tab < 0) return [];
|
|
34863
34782
|
const [mode] = entry.slice(0, tab).split(" ");
|
|
34864
34783
|
const path = entry.slice(tab + 1);
|
|
34865
|
-
if (!ENV_FILE.test(
|
|
34784
|
+
if (!ENV_FILE.test(basename2(path)) || COPY_SKIP.test(path)) return [];
|
|
34866
34785
|
if (mode === "100644" || mode === "100755")
|
|
34867
34786
|
return [{ path, symlink: false }];
|
|
34868
34787
|
if (mode === "120000") return [{ path, symlink: true }];
|
|
@@ -34894,14 +34813,14 @@ async function keptOnly(items, keep, remove) {
|
|
|
34894
34813
|
async function readLocal(path) {
|
|
34895
34814
|
const found = await stat3(path).catch(() => null);
|
|
34896
34815
|
if (!found?.isFile()) return null;
|
|
34897
|
-
return
|
|
34816
|
+
return readFile15(path).catch(() => null);
|
|
34898
34817
|
}
|
|
34899
34818
|
async function realAncestor(dir) {
|
|
34900
|
-
for (let current = dir; ; current =
|
|
34819
|
+
for (let current = dir; ; current = dirname5(current)) {
|
|
34901
34820
|
try {
|
|
34902
34821
|
return await realpath3(current);
|
|
34903
34822
|
} catch {
|
|
34904
|
-
if (
|
|
34823
|
+
if (dirname5(current) === current)
|
|
34905
34824
|
throw new Error(`No ancestor of ${dir}`);
|
|
34906
34825
|
}
|
|
34907
34826
|
}
|
|
@@ -34920,7 +34839,7 @@ async function copyWorkingTree(source, checkout) {
|
|
|
34920
34839
|
recursive: true,
|
|
34921
34840
|
// Relative symlinks must stay relative: resolved, they would point
|
|
34922
34841
|
// back into the developer's real tree, and a strategy's temporary
|
|
34923
|
-
// rewrite (
|
|
34842
|
+
// rewrite (the vinext toolchain install) would land there.
|
|
34924
34843
|
verbatimSymlinks: true,
|
|
34925
34844
|
filter: async (src) => {
|
|
34926
34845
|
if (COPY_SKIP.test(src)) return false;
|
|
@@ -34928,7 +34847,7 @@ async function copyWorkingTree(source, checkout) {
|
|
|
34928
34847
|
const entry = await lstat(src);
|
|
34929
34848
|
if (entry.isFIFO() || entry.isSocket() || entry.isCharacterDevice() || entry.isBlockDevice())
|
|
34930
34849
|
return false;
|
|
34931
|
-
if (ENV_FILE.test(
|
|
34850
|
+
if (ENV_FILE.test(basename2(src)) && !entry.isDirectory()) {
|
|
34932
34851
|
inWorkingTree.push(relative6(sourceDir, src).split(sep5).join("/"));
|
|
34933
34852
|
return false;
|
|
34934
34853
|
}
|
|
@@ -34939,7 +34858,7 @@ async function copyWorkingTree(source, checkout) {
|
|
|
34939
34858
|
absoluteLinks.push(path);
|
|
34940
34859
|
return false;
|
|
34941
34860
|
}
|
|
34942
|
-
if (!inside(
|
|
34861
|
+
if (!inside(resolve11(dirname5(src), target2), sourceDir)) {
|
|
34943
34862
|
linksOutside.push(path);
|
|
34944
34863
|
return false;
|
|
34945
34864
|
}
|
|
@@ -34977,21 +34896,21 @@ async function copyWorkingTree(source, checkout) {
|
|
|
34977
34896
|
continue;
|
|
34978
34897
|
}
|
|
34979
34898
|
const target2 = join25(checkout, path);
|
|
34980
|
-
if (!inside(await realAncestor(
|
|
34899
|
+
if (!inside(await realAncestor(dirname5(target2)), root)) {
|
|
34981
34900
|
outsideProject.push(path);
|
|
34982
34901
|
continue;
|
|
34983
34902
|
}
|
|
34984
34903
|
try {
|
|
34985
|
-
await mkdir3(
|
|
34904
|
+
await mkdir3(dirname5(target2), { recursive: true });
|
|
34986
34905
|
} catch {
|
|
34987
34906
|
outsideProject.push(path);
|
|
34988
34907
|
continue;
|
|
34989
34908
|
}
|
|
34990
|
-
await
|
|
34909
|
+
await rm5(target2, { recursive: true, force: true });
|
|
34991
34910
|
const content = await git(sourceDir, ["show", `HEAD:./${path}`]);
|
|
34992
34911
|
if (isLink) {
|
|
34993
34912
|
const linkTarget = content.toString("utf8");
|
|
34994
|
-
const pointsAt =
|
|
34913
|
+
const pointsAt = resolve11(dirname5(target2), linkTarget);
|
|
34995
34914
|
if (isAbsolute4(linkTarget) || !inside(pointsAt, checkout)) {
|
|
34996
34915
|
outsideProject.push(path);
|
|
34997
34916
|
continue;
|
|
@@ -35000,7 +34919,7 @@ async function copyWorkingTree(source, checkout) {
|
|
|
35000
34919
|
envLinks.push(path);
|
|
35001
34920
|
continue;
|
|
35002
34921
|
}
|
|
35003
|
-
await
|
|
34922
|
+
await writeFile6(target2, content, { flag: "wx" });
|
|
35004
34923
|
const local = await readLocal(join25(sourceDir, path));
|
|
35005
34924
|
if (!local || !sameText(local, content)) committedVersion.push(path);
|
|
35006
34925
|
}
|
|
@@ -35095,7 +35014,7 @@ var TtyPrompter = class {
|
|
|
35095
35014
|
});
|
|
35096
35015
|
try {
|
|
35097
35016
|
return await new Promise(
|
|
35098
|
-
(
|
|
35017
|
+
(resolve16) => rl.question(question, resolve16)
|
|
35099
35018
|
);
|
|
35100
35019
|
} finally {
|
|
35101
35020
|
rl.close();
|
|
@@ -35116,7 +35035,7 @@ var TtyPrompter = class {
|
|
|
35116
35035
|
});
|
|
35117
35036
|
try {
|
|
35118
35037
|
const answer = new Promise(
|
|
35119
|
-
(
|
|
35038
|
+
(resolve16) => rl.question(question, resolve16)
|
|
35120
35039
|
);
|
|
35121
35040
|
muted = true;
|
|
35122
35041
|
const value = await answer;
|
|
@@ -35452,7 +35371,7 @@ async function runDbLint(context) {
|
|
|
35452
35371
|
}
|
|
35453
35372
|
|
|
35454
35373
|
// src/functions/deploy.ts
|
|
35455
|
-
import { relative as relative11, resolve as
|
|
35374
|
+
import { relative as relative11, resolve as resolve14, sep as sep10 } from "path";
|
|
35456
35375
|
|
|
35457
35376
|
// ../../packages/functions-bundler/src/errors.ts
|
|
35458
35377
|
var FunctionBundleError = class extends Error {
|
|
@@ -35509,7 +35428,7 @@ var BUNDLE_MESSAGES = {
|
|
|
35509
35428
|
|
|
35510
35429
|
// ../../packages/functions-bundler/src/discover.ts
|
|
35511
35430
|
import { existsSync as existsSync7, readdirSync as readdirSync3, readFileSync as readFileSync8, statSync as statSync2 } from "fs";
|
|
35512
|
-
import { join as join27, relative as relative8, resolve as
|
|
35431
|
+
import { join as join27, relative as relative8, resolve as resolve12, sep as sep6 } from "path";
|
|
35513
35432
|
|
|
35514
35433
|
// ../../packages/functions-bundler/src/limits.ts
|
|
35515
35434
|
var FUNCTION_BUNDLE_MAX_BYTES = 67108864;
|
|
@@ -35531,9 +35450,9 @@ function isEntrypoint(value) {
|
|
|
35531
35450
|
);
|
|
35532
35451
|
}
|
|
35533
35452
|
function functionsFolder(options) {
|
|
35534
|
-
const root =
|
|
35453
|
+
const root = resolve12(options.cwd, options.root ?? ".");
|
|
35535
35454
|
const explicit = options.dir !== void 0;
|
|
35536
|
-
const dir = explicit ?
|
|
35455
|
+
const dir = explicit ? resolve12(options.cwd, options.dir) : join27(root, "naro", "functions");
|
|
35537
35456
|
const label2 = relative8(options.cwd, dir).split(sep6).join("/") || ".";
|
|
35538
35457
|
return { dir, label: label2, root, explicit };
|
|
35539
35458
|
}
|
|
@@ -35652,7 +35571,7 @@ function closesNext(text3, from) {
|
|
|
35652
35571
|
while (i < text3.length && /\s/.test(text3[i] ?? "")) i += 1;
|
|
35653
35572
|
return text3[i] === "}" || text3[i] === "]";
|
|
35654
35573
|
}
|
|
35655
|
-
function
|
|
35574
|
+
function parseJsonc(text3) {
|
|
35656
35575
|
const uncommented = stripComments2(text3);
|
|
35657
35576
|
let out = "";
|
|
35658
35577
|
let inString = false;
|
|
@@ -35713,11 +35632,11 @@ function stripComments2(text3) {
|
|
|
35713
35632
|
}
|
|
35714
35633
|
|
|
35715
35634
|
// ../../packages/functions-bundler/src/node-compat.ts
|
|
35716
|
-
import { createRequire
|
|
35717
|
-
import { dirname as
|
|
35718
|
-
import { fileURLToPath as
|
|
35719
|
-
var require2 =
|
|
35720
|
-
var MODULE_DIR =
|
|
35635
|
+
import { createRequire } from "module";
|
|
35636
|
+
import { dirname as dirname6, resolve as resolvePath } from "path";
|
|
35637
|
+
import { fileURLToPath as fileURLToPath3 } from "url";
|
|
35638
|
+
var require2 = createRequire(import.meta.url);
|
|
35639
|
+
var MODULE_DIR = dirname6(fileURLToPath3(import.meta.url));
|
|
35721
35640
|
var REQUIRED_NODE_BUILT_IN_NAMESPACE = "node-built-in-modules";
|
|
35722
35641
|
var REQUIRED_UNENV_ALIAS_NAMESPACE = "required-unenv-alias";
|
|
35723
35642
|
var SKIPPED_ALIASES = /* @__PURE__ */ new Set(["debug"]);
|
|
@@ -35847,12 +35766,12 @@ ${injects.map(
|
|
|
35847
35766
|
|
|
35848
35767
|
// ../../packages/functions-bundler/src/deno-imports.ts
|
|
35849
35768
|
import { existsSync as existsSync9, readFileSync as readFileSync10, realpathSync as realpathSync2 } from "fs";
|
|
35850
|
-
import { dirname as
|
|
35769
|
+
import { dirname as dirname8, isAbsolute as isAbsolute5, join as join29, relative as relative9, sep as sep8 } from "path";
|
|
35851
35770
|
|
|
35852
35771
|
// ../../packages/functions-bundler/src/import-map.ts
|
|
35853
35772
|
import { existsSync as existsSync8, readFileSync as readFileSync9, realpathSync } from "fs";
|
|
35854
|
-
import { basename as
|
|
35855
|
-
import { fileURLToPath as
|
|
35773
|
+
import { basename as basename3, dirname as dirname7, join as join28, resolve as resolve13, sep as sep7 } from "path";
|
|
35774
|
+
import { fileURLToPath as fileURLToPath4 } from "url";
|
|
35856
35775
|
|
|
35857
35776
|
// ../../packages/functions-bundler/src/printable.ts
|
|
35858
35777
|
var UNPRINTABLE2 = /[\p{Cc}\p{Cf}\p{Zl}\p{Zp}]/gu;
|
|
@@ -35885,7 +35804,7 @@ function expandBareKeys(imports) {
|
|
|
35885
35804
|
function load(file2, label2) {
|
|
35886
35805
|
let parsed;
|
|
35887
35806
|
try {
|
|
35888
|
-
parsed =
|
|
35807
|
+
parsed = parseJsonc(readFileSync9(file2, "utf8"));
|
|
35889
35808
|
} catch {
|
|
35890
35809
|
throw new FunctionBundleError(
|
|
35891
35810
|
"VALIDATION_FAILED",
|
|
@@ -35908,8 +35827,8 @@ function load(file2, label2) {
|
|
|
35908
35827
|
printable2(BUNDLE_MESSAGES.importMapPrefix(label2, key, value))
|
|
35909
35828
|
);
|
|
35910
35829
|
return {
|
|
35911
|
-
imports: DENO_CONFIGS.has(
|
|
35912
|
-
base:
|
|
35830
|
+
imports: DENO_CONFIGS.has(basename3(file2)) ? expandBareKeys(written) : written,
|
|
35831
|
+
base: dirname7(file2),
|
|
35913
35832
|
label: label2
|
|
35914
35833
|
};
|
|
35915
35834
|
}
|
|
@@ -35942,7 +35861,7 @@ var isPathLike = (text3) => text3.startsWith("./") || text3.startsWith("../") ||
|
|
|
35942
35861
|
function filePath(text3) {
|
|
35943
35862
|
if (!text3.startsWith("file:")) return null;
|
|
35944
35863
|
try {
|
|
35945
|
-
return
|
|
35864
|
+
return fileURLToPath4(text3);
|
|
35946
35865
|
} catch {
|
|
35947
35866
|
return null;
|
|
35948
35867
|
}
|
|
@@ -35960,7 +35879,7 @@ function keysOf(map2) {
|
|
|
35960
35879
|
for (const [key, target2] of Object.entries(map2.imports)) {
|
|
35961
35880
|
const trailing = key.endsWith("/");
|
|
35962
35881
|
const file2 = filePath(key);
|
|
35963
|
-
const name = file2 !== null ? realKey(file2, trailing) : isPathLike(key) ? realKey(
|
|
35882
|
+
const name = file2 !== null ? realKey(file2, trailing) : isPathLike(key) ? realKey(resolve13(base2, key), trailing) : key;
|
|
35964
35883
|
if (!keys.has(name)) keys.set(name, target2);
|
|
35965
35884
|
}
|
|
35966
35885
|
normalized.set(map2, keys);
|
|
@@ -35972,10 +35891,10 @@ function mapSpecifier(map2, specifier, importerDir) {
|
|
|
35972
35891
|
const file2 = filePath(specifier);
|
|
35973
35892
|
if (file2 !== null) lookup = realKey(file2, trailing);
|
|
35974
35893
|
else if (specifier.startsWith("/"))
|
|
35975
|
-
lookup = realKey(
|
|
35894
|
+
lookup = realKey(resolve13(specifier), trailing);
|
|
35976
35895
|
else if (isPathLike(specifier)) {
|
|
35977
35896
|
if (importerDir === void 0) return null;
|
|
35978
|
-
lookup = realKey(
|
|
35897
|
+
lookup = realKey(resolve13(importerDir, specifier), trailing);
|
|
35979
35898
|
}
|
|
35980
35899
|
const keys = keysOf(map2);
|
|
35981
35900
|
let target2 = keys.get(lookup);
|
|
@@ -35988,7 +35907,7 @@ function mapSpecifier(map2, specifier, importerDir) {
|
|
|
35988
35907
|
target2 = `${keys.get(prefix) ?? ""}${lookup.slice(prefix.length)}`;
|
|
35989
35908
|
}
|
|
35990
35909
|
if (target2.startsWith("./") || target2.startsWith("../"))
|
|
35991
|
-
return
|
|
35910
|
+
return resolve13(map2.base, target2);
|
|
35992
35911
|
return filePath(target2) ?? target2;
|
|
35993
35912
|
}
|
|
35994
35913
|
|
|
@@ -36068,7 +35987,7 @@ function packageDir(from, projectRoot) {
|
|
|
36068
35987
|
const inNodeModules = fromRoot(projectRoot, current).split("/").includes("node_modules");
|
|
36069
35988
|
if (!inNodeModules && existsSync9(join29(current, "package.json")))
|
|
36070
35989
|
return fromRoot(projectRoot, current) || ".";
|
|
36071
|
-
const up =
|
|
35990
|
+
const up = dirname8(current);
|
|
36072
35991
|
if (up === current) break;
|
|
36073
35992
|
current = up;
|
|
36074
35993
|
}
|
|
@@ -36079,14 +35998,14 @@ function isInstalled(from, pkg) {
|
|
|
36079
35998
|
let current = from;
|
|
36080
35999
|
for (; ; ) {
|
|
36081
36000
|
if (existsSync9(join29(current, "node_modules", pkg))) return true;
|
|
36082
|
-
const up =
|
|
36001
|
+
const up = dirname8(current);
|
|
36083
36002
|
if (up === current) return false;
|
|
36084
36003
|
current = up;
|
|
36085
36004
|
}
|
|
36086
36005
|
}
|
|
36087
36006
|
var NODE_MODULES = /[\\/]node_modules[\\/]/;
|
|
36088
36007
|
function installedVersion(resolved, pkg) {
|
|
36089
|
-
let current =
|
|
36008
|
+
let current = dirname8(resolved);
|
|
36090
36009
|
for (; ; ) {
|
|
36091
36010
|
const file2 = join29(current, "package.json");
|
|
36092
36011
|
if (existsSync9(file2)) {
|
|
@@ -36097,7 +36016,7 @@ function installedVersion(resolved, pkg) {
|
|
|
36097
36016
|
} catch {
|
|
36098
36017
|
}
|
|
36099
36018
|
}
|
|
36100
|
-
const up =
|
|
36019
|
+
const up = dirname8(current);
|
|
36101
36020
|
if (up === current) return null;
|
|
36102
36021
|
current = up;
|
|
36103
36022
|
}
|
|
@@ -36527,7 +36446,7 @@ var FUNCTION_BUSY_WAIT_MS = 5e3;
|
|
|
36527
36446
|
var FUNCTION_RATE_LIMIT_DEFAULT_SECONDS = 60;
|
|
36528
36447
|
var FUNCTION_RATE_LIMIT_MAX_SECONDS = 300;
|
|
36529
36448
|
function defaultSleep(ms) {
|
|
36530
|
-
return new Promise((
|
|
36449
|
+
return new Promise((resolve16) => setTimeout(resolve16, ms));
|
|
36531
36450
|
}
|
|
36532
36451
|
function retryAfterSeconds(error51) {
|
|
36533
36452
|
const value = error51.details?.retryAfter;
|
|
@@ -36724,7 +36643,7 @@ async function deployOne(options, folder, name, importMap, secretNames, io, budg
|
|
|
36724
36643
|
}
|
|
36725
36644
|
function readFlagImportMap(options, folder) {
|
|
36726
36645
|
if (options.importMap === void 0) return void 0;
|
|
36727
|
-
const file2 =
|
|
36646
|
+
const file2 = resolve14(options.cwd, options.importMap);
|
|
36728
36647
|
try {
|
|
36729
36648
|
return readImportMapFile(
|
|
36730
36649
|
file2,
|
|
@@ -36842,7 +36761,7 @@ function eventsObserver(cp3, deploymentId, token, fetchImpl = fetch, logIngestUr
|
|
|
36842
36761
|
} catch (error51) {
|
|
36843
36762
|
lastError = error51;
|
|
36844
36763
|
await new Promise(
|
|
36845
|
-
(
|
|
36764
|
+
(resolve16) => setTimeout(resolve16, 500 * (attempt + 1))
|
|
36846
36765
|
);
|
|
36847
36766
|
}
|
|
36848
36767
|
}
|
|
@@ -36918,19 +36837,19 @@ function slugify2(value) {
|
|
|
36918
36837
|
async function projectName(sourceDir) {
|
|
36919
36838
|
try {
|
|
36920
36839
|
const pkg = JSON.parse(
|
|
36921
|
-
await
|
|
36840
|
+
await readFile16(join31(sourceDir, "package.json"), "utf8")
|
|
36922
36841
|
);
|
|
36923
36842
|
if (pkg.name) return pkg.name;
|
|
36924
36843
|
} catch {
|
|
36925
36844
|
}
|
|
36926
|
-
return
|
|
36845
|
+
return basename4(sourceDir);
|
|
36927
36846
|
}
|
|
36928
36847
|
function resolveBin(name) {
|
|
36929
|
-
let dir =
|
|
36848
|
+
let dir = dirname9(fileURLToPath5(import.meta.url));
|
|
36930
36849
|
for (; ; ) {
|
|
36931
36850
|
const candidate = join31(dir, "node_modules", ".bin", name);
|
|
36932
36851
|
if (existsSync10(candidate)) return candidate;
|
|
36933
|
-
const parent =
|
|
36852
|
+
const parent = dirname9(dir);
|
|
36934
36853
|
if (parent === dir) return name;
|
|
36935
36854
|
dir = parent;
|
|
36936
36855
|
}
|
|
@@ -36996,7 +36915,7 @@ function workingTreeNotices(copy) {
|
|
|
36996
36915
|
function localDependencies(sourceDir, say = () => void 0) {
|
|
36997
36916
|
return {
|
|
36998
36917
|
createWorkspace: () => mkdtemp2(join31(tmpdir2(), "naro-build-")),
|
|
36999
|
-
removeWorkspace: (path) =>
|
|
36918
|
+
removeWorkspace: (path) => rm6(path, { recursive: true, force: true }),
|
|
37000
36919
|
async runCommand(spec, observer) {
|
|
37001
36920
|
if (spec.command === "git" && spec.args[0] === "clone") {
|
|
37002
36921
|
const checkout = spec.args.at(-1);
|
|
@@ -37021,9 +36940,6 @@ function localDependencies(sourceDir, say = () => void 0) {
|
|
|
37021
36940
|
detectFramework,
|
|
37022
36941
|
readStaticArtifact,
|
|
37023
36942
|
createPackageManagerConfig,
|
|
37024
|
-
createPlatformBuildConfig,
|
|
37025
|
-
readOpenNextArtifact,
|
|
37026
|
-
openNextCommand: resolveBin("opennextjs-cloudflare"),
|
|
37027
36943
|
wranglerCommand: resolveBin("wrangler"),
|
|
37028
36944
|
// `vinext check` runs on the bare checkout, before the toolchain is added
|
|
37029
36945
|
// to the user's tree, so this binary has to come from the CLI's own deps.
|
|
@@ -37045,7 +36961,7 @@ async function deployDirectory(sourceDir, options, log2) {
|
|
|
37045
36961
|
"Pass production: true for production; preview is the default."
|
|
37046
36962
|
);
|
|
37047
36963
|
const surface = production ? "production" : environment ?? "preview";
|
|
37048
|
-
const appRoot = options.rootDirectory ?
|
|
36964
|
+
const appRoot = options.rootDirectory ? resolve15(sourceDir, options.rootDirectory) : sourceDir;
|
|
37049
36965
|
const framework = detectFramework2(appRoot);
|
|
37050
36966
|
if (!framework.deployable && !options.force) {
|
|
37051
36967
|
throw new NaroError(
|
|
@@ -37133,6 +37049,19 @@ async function deployDirectory(sourceDir, options, log2) {
|
|
|
37133
37049
|
});
|
|
37134
37050
|
if (ctx.envSkipped?.length)
|
|
37135
37051
|
log2(`\u26A0 skipped env: ${ctx.envSkipped.join(", ")}`);
|
|
37052
|
+
const storedAdapter = ctx.userAdapter ?? null;
|
|
37053
|
+
if (options.userAdapter && options.userAdapter !== storedAdapter) {
|
|
37054
|
+
try {
|
|
37055
|
+
await client.projects.update(ctx.projectId, {
|
|
37056
|
+
userAdapter: options.userAdapter
|
|
37057
|
+
});
|
|
37058
|
+
} catch (error51) {
|
|
37059
|
+
log2(
|
|
37060
|
+
`\u26A0 Could not save the Next.js adapter choice: ${error51 instanceof Error ? error51.message : String(error51)}`
|
|
37061
|
+
);
|
|
37062
|
+
}
|
|
37063
|
+
}
|
|
37064
|
+
if (options.userAdapter) log2(userAdapterOutcome(options.userAdapter));
|
|
37136
37065
|
const executor = options.executor ?? new LocalBuildExecutor(localDependencies(sourceDir, log2));
|
|
37137
37066
|
const observer = eventsObserver(
|
|
37138
37067
|
cpUrl,
|
|
@@ -37161,7 +37090,8 @@ async function deployDirectory(sourceDir, options, log2) {
|
|
|
37161
37090
|
// one, as before.
|
|
37162
37091
|
env: ctx.environment ? { ...envToSend, ...ctx.env } : { ...ctx.env, ...envToSend },
|
|
37163
37092
|
strategy: ctx.strategy ?? null,
|
|
37164
|
-
...ctx.vinextEnabled === void 0 ? {} : { vinextEnabled: ctx.vinextEnabled }
|
|
37093
|
+
...ctx.vinextEnabled === void 0 ? {} : { vinextEnabled: ctx.vinextEnabled },
|
|
37094
|
+
...options.userAdapter ?? storedAdapter ? { userAdapter: options.userAdapter ?? storedAdapter } : {}
|
|
37165
37095
|
},
|
|
37166
37096
|
observer,
|
|
37167
37097
|
createCacheTransport({
|
|
@@ -37343,6 +37273,13 @@ export {
|
|
|
37343
37273
|
promptForMissingEnv,
|
|
37344
37274
|
pullEnv,
|
|
37345
37275
|
detectGitInfo,
|
|
37276
|
+
detectUserAdapter,
|
|
37277
|
+
parseUserAdapter,
|
|
37278
|
+
USER_ADAPTER_OPTIONS,
|
|
37279
|
+
userAdapterQuestion,
|
|
37280
|
+
userAdapterStored,
|
|
37281
|
+
userAdapterUnasked,
|
|
37282
|
+
userAdapterUnreadable,
|
|
37346
37283
|
version2 as version,
|
|
37347
37284
|
DATA_ENV_MESSAGES,
|
|
37348
37285
|
dataEnvironment,
|
|
@@ -37372,7 +37309,7 @@ export {
|
|
|
37372
37309
|
runDbLint,
|
|
37373
37310
|
BUNDLE_MESSAGES,
|
|
37374
37311
|
functionsFolder,
|
|
37375
|
-
|
|
37312
|
+
parseJsonc,
|
|
37376
37313
|
defaultSleep,
|
|
37377
37314
|
retryAfterSeconds,
|
|
37378
37315
|
withFunctionRetries,
|