@agent-native/core 0.189.0-nightly-20260925200527 → 0.189.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/corpus/README.md +1 -1
- package/corpus/templates/content/CHANGELOG.md +6 -0
- package/corpus/templates/content/vite.config.ts +2 -38
- package/corpus/templates/design/CHANGELOG.md +4 -0
- package/corpus/templates/mail/app/components/layout/AppLayout.tsx +36 -11
- package/corpus/templates/mail/app/hooks/use-inbox-threads.ts +82 -0
- package/corpus/templates/mail/app/pages/InboxPage.tsx +18 -19
- package/corpus/templates/mail/changelog/2026-09-25-keep-inbox-tab-counts-consistent-when-switching-tabs.md +6 -0
- package/corpus/templates/slides/CHANGELOG.md +4 -0
- package/dist/cli/index.js +1 -2
- package/dist/collab/awareness.d.ts +2 -2
- package/dist/deploy/build.d.ts +1 -1
- package/dist/deploy/build.js +9 -348
- package/dist/deploy/workspace-deploy.d.ts +2 -2
- package/dist/deploy/workspace-deploy.js +9 -130
- package/dist/file-upload/actions/upload-image.d.ts +1 -1
- package/dist/notifications/routes.d.ts +3 -3
- package/dist/observability/routes.d.ts +6 -6
- package/dist/org/handlers.d.ts +1 -1
- package/dist/progress/routes.d.ts +1 -1
- package/dist/resources/handlers.d.ts +1 -1
- package/dist/secrets/routes.d.ts +3 -3
- package/dist/server/agent-engine-ollama-models-route.d.ts +1 -1
- package/dist/vite/client.d.ts +1 -1
- package/docs/content/a2a-protocol.mdx +2 -2
- package/docs/content/cloudflare.mdx +2 -10
- package/docs/content/deploy-an-app.mdx +0 -1
- package/docs/content/deployment.mdx +2 -8
- package/docs/content/environment-variables.mdx +1 -1
- package/docs/content/multi-app-workspace.mdx +1 -1
- package/docs/content/netlify.mdx +1 -1
- package/docs/content/real-time-collaboration.mdx +6 -6
- package/docs/content/workspace-deployment.mdx +4 -15
- package/package.json +4 -4
package/dist/deploy/build.js
CHANGED
|
@@ -8,7 +8,6 @@
|
|
|
8
8
|
* 3. Bundles everything with esbuild into the target format
|
|
9
9
|
*
|
|
10
10
|
* Supported presets:
|
|
11
|
-
* - cloudflare_pages: Outputs dist/ with _worker.js for Cloudflare Pages
|
|
12
11
|
* - cloudflare_module: Outputs a native Cloudflare Worker under .output/server
|
|
13
12
|
* - aws_amplify: Uses Nitro's .amplify-hosting deployment specification
|
|
14
13
|
*
|
|
@@ -42,7 +41,7 @@ import { createAgentNativeConfigContext, loadResolvedAgentNativeConfig, readAgen
|
|
|
42
41
|
import { cloneServerBundleForFunction, copyDir, pruneSsrIslandFromRewritingClone, readPackageManifest, SERVERLESS_BROWSER_RUNTIME_PACKAGES, } from "./function-bundle.js";
|
|
43
42
|
import { collectImmutableAssetPaths, IMMUTABLE_ASSET_CACHE_CONTROL, IMMUTABLE_ASSET_CACHE_HEADERS, prefixAssetPath, } from "./immutable-assets.js";
|
|
44
43
|
import { writeNetlifyStaticHeaders } from "./netlify-static-headers.js";
|
|
45
|
-
import {
|
|
44
|
+
import { discoverPlugins, DEFAULT_PLUGIN_REGISTRY, } from "./route-discovery.js";
|
|
46
45
|
import { getWorkspaceCoreExports, } from "./workspace-core.js";
|
|
47
46
|
const cwd = process.cwd();
|
|
48
47
|
const preset = process.env.NITRO_PRESET || "node";
|
|
@@ -2345,295 +2344,6 @@ export function generateCloudflarePagesStaticShellFromManifest(manifest, basePat
|
|
|
2345
2344
|
: EMPTY_REACT_ROUTER_TURBO_STREAM;
|
|
2346
2345
|
return `<!DOCTYPE html><html lang="en"><head><meta charSet="utf-8"/><meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no"/><link rel="icon" type="image/svg+xml" href="/favicon.svg"/>${modulePreloads}${stylesheets}</head><body>${STATIC_SHELL_LOADING_MARKUP}<script>window.__reactRouterContext = ${JSON.stringify(context)};window.__reactRouterContext.stream = new ReadableStream({start(controller){window.__reactRouterContext.streamController = controller;}}).pipeThrough(new TextEncoderStream());</script><script type="module" async="">${routeModuleScript}</script><!--$--><script>window.__reactRouterContext.streamController.enqueue(${JSON.stringify(encodedInitialState)});</script><!--$--><script>window.__reactRouterContext.streamController.close();</script><!--/$--><!--/$--></body></html>`;
|
|
2347
2346
|
}
|
|
2348
|
-
function writeCloudflarePagesStaticShell({ serverDir, distDir, tmpDir, }) {
|
|
2349
|
-
const serverEntry = path.join(serverDir, "index.js");
|
|
2350
|
-
if (!fs.existsSync(serverEntry)) {
|
|
2351
|
-
throw new Error(`React Router server build not found at ${serverEntry}`);
|
|
2352
|
-
}
|
|
2353
|
-
const outFile = path.join(distDir, "index.html");
|
|
2354
|
-
const renderScript = path.join(tmpDir, "render-cloudflare-static-shell.mjs");
|
|
2355
|
-
const basePath = normalizeConfiguredAppBasePath();
|
|
2356
|
-
fs.writeFileSync(renderScript, `
|
|
2357
|
-
import fs from "node:fs";
|
|
2358
|
-
import { createRequire } from "node:module";
|
|
2359
|
-
import { pathToFileURL } from "node:url";
|
|
2360
|
-
|
|
2361
|
-
const cwd = ${JSON.stringify(cwd)};
|
|
2362
|
-
const serverEntry = ${JSON.stringify(serverEntry)};
|
|
2363
|
-
const outFile = ${JSON.stringify(outFile)};
|
|
2364
|
-
const basePath = ${JSON.stringify(basePath)};
|
|
2365
|
-
|
|
2366
|
-
const requireFromApp = createRequire(cwd + "/package.json");
|
|
2367
|
-
const reactRouterEntry = requireFromApp.resolve("react-router");
|
|
2368
|
-
const { createRequestHandler } = await import(pathToFileURL(reactRouterEntry).href);
|
|
2369
|
-
const serverBuild = await import(pathToFileURL(serverEntry).href);
|
|
2370
|
-
const handler = createRequestHandler(serverBuild, "production");
|
|
2371
|
-
const pathname = basePath ? basePath + "/" : "/";
|
|
2372
|
-
const response = await handler(
|
|
2373
|
-
new Request(new URL(pathname, "https://agent-native.local"), {
|
|
2374
|
-
headers: { "X-React-Router-SPA-Mode": "yes" },
|
|
2375
|
-
}),
|
|
2376
|
-
);
|
|
2377
|
-
const html = await response.text();
|
|
2378
|
-
|
|
2379
|
-
if (!html || !html.includes("__reactRouterContext") || !html.includes("entry.client")) {
|
|
2380
|
-
throw new Error("React Router did not render a usable Cloudflare Pages static shell");
|
|
2381
|
-
}
|
|
2382
|
-
|
|
2383
|
-
fs.writeFileSync(outFile, html);
|
|
2384
|
-
process.exit(0);
|
|
2385
|
-
`);
|
|
2386
|
-
try {
|
|
2387
|
-
execFileSync(process.execPath, [renderScript], {
|
|
2388
|
-
cwd,
|
|
2389
|
-
env: {
|
|
2390
|
-
...process.env,
|
|
2391
|
-
NODE_ENV: process.env.NODE_ENV || "production",
|
|
2392
|
-
IS_RR_BUILD_REQUEST: "yes",
|
|
2393
|
-
},
|
|
2394
|
-
stdio: "inherit",
|
|
2395
|
-
});
|
|
2396
|
-
console.log("[deploy] Wrote Cloudflare Pages static app shell.");
|
|
2397
|
-
}
|
|
2398
|
-
catch (error) {
|
|
2399
|
-
const message = error instanceof Error ? error.message : String(error);
|
|
2400
|
-
console.warn(`[deploy] React Router static shell render failed; using manifest fallback. ${message}`);
|
|
2401
|
-
fs.writeFileSync(outFile, generateCloudflarePagesStaticShellFromManifest(findReactRouterManifest(distDir), basePath));
|
|
2402
|
-
console.log("[deploy] Wrote Cloudflare Pages static app shell fallback.");
|
|
2403
|
-
}
|
|
2404
|
-
}
|
|
2405
|
-
/**
|
|
2406
|
-
* Build for Cloudflare Pages.
|
|
2407
|
-
* Output structure:
|
|
2408
|
-
* dist/
|
|
2409
|
-
* _worker.js (bundled worker entry)
|
|
2410
|
-
* assets/ (static client assets)
|
|
2411
|
-
*/
|
|
2412
|
-
async function buildCloudflarePages() {
|
|
2413
|
-
generateActionRegistryForProject(cwd);
|
|
2414
|
-
const buildDir = path.join(cwd, "build");
|
|
2415
|
-
const clientDir = path.join(buildDir, "client");
|
|
2416
|
-
const serverDir = path.join(buildDir, "server");
|
|
2417
|
-
const distDir = path.join(cwd, "dist");
|
|
2418
|
-
// Verify build output exists
|
|
2419
|
-
if (!fs.existsSync(clientDir) || !fs.existsSync(serverDir)) {
|
|
2420
|
-
console.error("Build output not found at build/client/ and build/server/. Run react-router build first.");
|
|
2421
|
-
process.exit(1);
|
|
2422
|
-
}
|
|
2423
|
-
// Clean dist
|
|
2424
|
-
if (fs.existsSync(distDir)) {
|
|
2425
|
-
fs.rmSync(distDir, { recursive: true });
|
|
2426
|
-
}
|
|
2427
|
-
fs.mkdirSync(distDir, { recursive: true });
|
|
2428
|
-
// Copy client assets to dist/
|
|
2429
|
-
copyDir(clientDir, distDir);
|
|
2430
|
-
const tmpDir = path.join(cwd, ".deploy-tmp");
|
|
2431
|
-
fs.mkdirSync(tmpDir, { recursive: true });
|
|
2432
|
-
writeCloudflarePagesStaticShell({ serverDir, distDir, tmpDir });
|
|
2433
|
-
// Exclude _worker.js from being served as a public asset
|
|
2434
|
-
fs.writeFileSync(path.join(distDir, ".assetsignore"), "_worker.js\n");
|
|
2435
|
-
// Write package metadata inside _worker.js/ for the ES module worker that
|
|
2436
|
-
// Wrangler compiles and uploads for Cloudflare Pages.
|
|
2437
|
-
fs.mkdirSync(path.join(distDir, "_worker.js"), { recursive: true });
|
|
2438
|
-
fs.writeFileSync(path.join(distDir, "_worker.js", "package.json"), JSON.stringify({ main: "index.js", type: "module" }));
|
|
2439
|
-
// Create empty stub for native modules that wrangler's bundler needs to resolve
|
|
2440
|
-
const stubsDir = path.join(distDir, "_worker.js", "stubs");
|
|
2441
|
-
fs.mkdirSync(stubsDir, { recursive: true });
|
|
2442
|
-
fs.writeFileSync(path.join(stubsDir, "empty.js"), "export default {}; export const watch = () => ({ close() {} }); export const Database = class {};\n");
|
|
2443
|
-
// Discover routes, plugins, actions, and the workspace core (if any).
|
|
2444
|
-
const routes = await discoverApiRoutes(cwd);
|
|
2445
|
-
const plugins = await discoverPlugins(cwd);
|
|
2446
|
-
const actions = await discoverActionFiles(cwd);
|
|
2447
|
-
const missingDefaults = await getMissingDefaultPlugins(cwd);
|
|
2448
|
-
const workspaceCore = await getWorkspaceCoreExports(cwd);
|
|
2449
|
-
const includeReactRouterSsr = false;
|
|
2450
|
-
const workspaceSlotCount = workspaceCore
|
|
2451
|
-
? Object.keys(workspaceCore.plugins).length
|
|
2452
|
-
: 0;
|
|
2453
|
-
console.log(`[deploy] ${routes.length} API routes, ${actions.length} actions, ${plugins.length} plugins (${plugins.filter((p) => isNodeOnlyPlugin(p)).length} skipped as Node-only), ${missingDefaults.length} auto-mounted defaults${workspaceCore ? `, workspace-core ${workspaceCore.packageName} (${workspaceSlotCount} plugin slots)` : ""}`);
|
|
2454
|
-
// Generate the worker entry
|
|
2455
|
-
const immutableAssetPaths = collectImmutableAssetPaths(clientDir);
|
|
2456
|
-
const entrySource = generateWorkerEntry(routes, plugins, missingDefaults, actions, workspaceCore, immutableAssetPaths, normalizeConfiguredAppBasePath(), { includeReactRouterSsr });
|
|
2457
|
-
// Create _worker.js output directory
|
|
2458
|
-
const workerOutDir = path.join(distDir, "_worker.js");
|
|
2459
|
-
fs.mkdirSync(workerOutDir, { recursive: true });
|
|
2460
|
-
// Write the worker entry
|
|
2461
|
-
const entryFile = path.join(workerOutDir, "index.js");
|
|
2462
|
-
// Rewrite the server-build import to point at the copied files when this
|
|
2463
|
-
// worker intentionally includes React Router SSR.
|
|
2464
|
-
const adjustedEntry = includeReactRouterSsr
|
|
2465
|
-
? entrySource.replace(`import * as serverBuild from "./server-build.js";`, `import * as serverBuild from "./server/index.js";`)
|
|
2466
|
-
: entrySource;
|
|
2467
|
-
// Write a temp file for esbuild to bundle everything into a single worker entry.
|
|
2468
|
-
// When React Router SSR is enabled, the server build is copied to tmp so
|
|
2469
|
-
// esbuild can resolve it. Cloudflare Pages currently uses a static app shell
|
|
2470
|
-
// instead so the worker stays under the platform bundle size limit.
|
|
2471
|
-
// Name the entry "index.js" so esbuild outputs index.js in the outdir,
|
|
2472
|
-
// matching the _worker.js/index.js entry point that Cloudflare Pages expects.
|
|
2473
|
-
const tmpEntry = path.join(tmpDir, "index.js");
|
|
2474
|
-
fs.writeFileSync(tmpEntry, adjustedEntry);
|
|
2475
|
-
if (includeReactRouterSsr) {
|
|
2476
|
-
copyDir(serverDir, path.join(tmpDir, "server"));
|
|
2477
|
-
}
|
|
2478
|
-
// Create a require shim so CJS require("fs") calls resolve via ESM imports.
|
|
2479
|
-
// This is injected via esbuild --inject to replace its broken __require shim.
|
|
2480
|
-
fs.writeFileSync(path.join(tmpDir, "_require-shim.js"), generateRequireShim());
|
|
2481
|
-
const nitroServerAssetsStub = path.join(tmpDir, "_nitro-server-assets-stub.js");
|
|
2482
|
-
fs.writeFileSync(nitroServerAssetsStub, [
|
|
2483
|
-
"const empty = async () => undefined;",
|
|
2484
|
-
"export const assets = {",
|
|
2485
|
-
" getItem: empty,",
|
|
2486
|
-
" getItemRaw: empty,",
|
|
2487
|
-
" getKeys: async () => [],",
|
|
2488
|
-
" getMeta: async () => undefined,",
|
|
2489
|
-
" hasItem: async () => false,",
|
|
2490
|
-
"};",
|
|
2491
|
-
"export default assets;",
|
|
2492
|
-
"",
|
|
2493
|
-
].join("\n"));
|
|
2494
|
-
// Create stub modules for native/Node-only deps that can't run on Workers.
|
|
2495
|
-
// These get resolved by esbuild instead of the real modules, avoiding bundling
|
|
2496
|
-
// native code that would fail on the Workers runtime.
|
|
2497
|
-
const stubDir = path.join(tmpDir, "node_modules");
|
|
2498
|
-
for (const [mod, source] of Object.entries(CLOUDFLARE_WORKER_STUB_MODULES)) {
|
|
2499
|
-
const modDir = path.join(stubDir, mod);
|
|
2500
|
-
fs.mkdirSync(modDir, { recursive: true });
|
|
2501
|
-
fs.writeFileSync(path.join(modDir, "index.js"), source);
|
|
2502
|
-
fs.writeFileSync(path.join(modDir, "package.json"), JSON.stringify({ name: mod, main: "index.js", type: "module" }));
|
|
2503
|
-
}
|
|
2504
|
-
for (const [mod, source] of Object.entries(CLOUDFLARE_WORKER_STUB_SUBPATH_MODULES)) {
|
|
2505
|
-
fs.writeFileSync(path.join(stubDir, `${mod.replace(/\//g, "__")}.js`), source);
|
|
2506
|
-
}
|
|
2507
|
-
const stubAliases = cloudflareWorkerStubAliasArgs(stubDir);
|
|
2508
|
-
const nodeBuiltinStubDir = path.join(tmpDir, "node-builtin-stubs");
|
|
2509
|
-
fs.mkdirSync(nodeBuiltinStubDir, { recursive: true });
|
|
2510
|
-
const nodeBuiltinStubAliases = [];
|
|
2511
|
-
for (const [mod, source] of Object.entries(CLOUDFLARE_WORKER_NODE_BUILTIN_STUB_MODULES).sort(([a], [b]) => b.length - a.length)) {
|
|
2512
|
-
const stubFile = path.join(nodeBuiltinStubDir, `${mod.replace(/\W+/g, "_")}.js`);
|
|
2513
|
-
fs.writeFileSync(stubFile, source);
|
|
2514
|
-
nodeBuiltinStubAliases.push(`--alias:${mod}=${stubFile}`, `--alias:node:${mod}=${stubFile}`);
|
|
2515
|
-
}
|
|
2516
|
-
const esbuildBin = findEsbuild();
|
|
2517
|
-
// Externalize node builtins (both bare and node: prefixed) — the require
|
|
2518
|
-
// shim handles bare ones. Also alias every `node:*` specifier to its bare
|
|
2519
|
-
// name so esbuild emits `import from "fs"` everywhere, never
|
|
2520
|
-
// `import from "node:fs"`. CF Pages Functions (wrangler 3.x, nodejs_compat
|
|
2521
|
-
// v1) rejects the `node:` prefix in chunks with:
|
|
2522
|
-
// No such module "node:fs" imported from chunks/...
|
|
2523
|
-
// The alias is the authoritative fix; the post-build strip stays as belt
|
|
2524
|
-
// & suspenders in case esbuild emits a node: string via some other path.
|
|
2525
|
-
const builtinNames = getNodeBuiltinNames();
|
|
2526
|
-
// Only externalize bare names. node:* externals would otherwise pin
|
|
2527
|
-
// the prefix in output; instead we alias node:* → bare so anything that
|
|
2528
|
-
// resolves past alias land as bare externals.
|
|
2529
|
-
const nodeBuiltinStubs = new Set(Object.keys(CLOUDFLARE_WORKER_NODE_BUILTIN_STUB_MODULES));
|
|
2530
|
-
const nodeExternals = builtinNames
|
|
2531
|
-
.filter((n) => !nodeBuiltinStubs.has(n))
|
|
2532
|
-
.sort((a, b) => b.length - a.length)
|
|
2533
|
-
.map((n) => `--external:${n}`);
|
|
2534
|
-
const nodeAliases = builtinNames
|
|
2535
|
-
.filter((n) => !nodeBuiltinStubs.has(n))
|
|
2536
|
-
.sort((a, b) => b.length - a.length)
|
|
2537
|
-
.map((n) => `--alias:node:${n}=${n}`);
|
|
2538
|
-
// Hard externalize large client-only / node-only libraries so they don't
|
|
2539
|
-
// bloat the edge worker. These are never executed in the CF Pages runtime
|
|
2540
|
-
// — mermaid/excalidraw render in the browser, pdf-parse and @google/genai
|
|
2541
|
-
// run from node-only action scripts. Without this, slides' bundle hits
|
|
2542
|
-
// the 25 MiB Pages Functions limit.
|
|
2543
|
-
//
|
|
2544
|
-
// @anthropic-ai/tokenizer (tiktoken .wasm) and @resvg/resvg-js (native
|
|
2545
|
-
// .node binding) can't be bundled by esbuild at all — no loader for those
|
|
2546
|
-
// files. Both import sites degrade gracefully when the runtime import
|
|
2547
|
-
// fails: context-xray token counts fall back to char/4 estimates and the
|
|
2548
|
-
// OG image route falls back to SVG.
|
|
2549
|
-
const heavyClientExternals = CLOUDFLARE_WORKER_ESBUILD_EXTERNALS.filter((p) => !Object.prototype.hasOwnProperty.call(CLOUDFLARE_WORKER_STUB_MODULES, p)).map((p) => `--external:${p}`);
|
|
2550
|
-
execFileSync(esbuildBin, [
|
|
2551
|
-
tmpEntry,
|
|
2552
|
-
"--bundle",
|
|
2553
|
-
"--format=esm",
|
|
2554
|
-
"--target=es2022",
|
|
2555
|
-
// browser platform for npm resolution; node builtins externalized separately
|
|
2556
|
-
"--platform=browser",
|
|
2557
|
-
"--minify",
|
|
2558
|
-
// Single-file bundle (no --splitting). CF Pages Functions' deploy
|
|
2559
|
-
// validator fails to load chunked _worker.js/ bundles even when the
|
|
2560
|
-
// chunks contain only bare node-builtin imports (wrangler 3.101.0
|
|
2561
|
-
// + nodejs_compat v2). Matches main's working config.
|
|
2562
|
-
`--outdir=${workerOutDir}`,
|
|
2563
|
-
"--conditions=workerd,worker,import",
|
|
2564
|
-
// The ssr-handler imports a virtual module that only exists at dev time
|
|
2565
|
-
"--external:virtual:react-router/server-build",
|
|
2566
|
-
`--alias:#nitro/virtual/server-assets=${nitroServerAssetsStub}`,
|
|
2567
|
-
// Banner: override the __require shim that esbuild generates for CJS modules.
|
|
2568
|
-
// This provides a real require() backed by ESM imports of node builtins.
|
|
2569
|
-
// Without this, CF Workers rejects the bundle because esbuild's default
|
|
2570
|
-
// __require shim throws "Dynamic require of X is not supported".
|
|
2571
|
-
`--banner:js=${generateRequireShim()}`,
|
|
2572
|
-
// Externalize node: builtins — CF Workers runtime provides them
|
|
2573
|
-
...nodeExternals,
|
|
2574
|
-
...heavyClientExternals,
|
|
2575
|
-
...stubAliases,
|
|
2576
|
-
...nodeBuiltinStubAliases,
|
|
2577
|
-
// Rewrite node:* -> bare names so chunks never contain node: imports
|
|
2578
|
-
...nodeAliases,
|
|
2579
|
-
], { stdio: "inherit", cwd });
|
|
2580
|
-
// Clean up tmp
|
|
2581
|
-
fs.rmSync(tmpDir, { recursive: true });
|
|
2582
|
-
// Rewrite the external virtual import to a local stub.
|
|
2583
|
-
// esbuild externalizes "virtual:react-router/server-build" (used by ssr-handler),
|
|
2584
|
-
// but wrangler re-bundles and chokes on it. Replace the import with a no-op stub.
|
|
2585
|
-
const virtualStub = path.join(workerOutDir, "chunks", "_virtual-stub.js");
|
|
2586
|
-
fs.mkdirSync(path.dirname(virtualStub), { recursive: true });
|
|
2587
|
-
fs.writeFileSync(virtualStub, "export default {};\n");
|
|
2588
|
-
// Post-build patches — apply to ALL .js files in the worker output directory
|
|
2589
|
-
// (entry + chunks) since code can land in any chunk after splitting.
|
|
2590
|
-
const allJsFiles = getAllJsFiles(workerOutDir);
|
|
2591
|
-
for (const jsFile of allJsFiles) {
|
|
2592
|
-
let code = fs.readFileSync(jsFile, "utf-8");
|
|
2593
|
-
// Strip "node:" prefix from all imports/requires. Cloudflare Pages
|
|
2594
|
-
// Functions runs under nodejs_compat v1, which exposes builtins as
|
|
2595
|
-
// bare names ("fs") and rejects "node:fs" at worker init:
|
|
2596
|
-
// No such module "node:fs" imported from chunks/...
|
|
2597
|
-
// (Workers-on-the-edge use v2 and require the prefix; Pages lags.)
|
|
2598
|
-
// Preserve the original quote char (single vs double) when rewriting —
|
|
2599
|
-
// esbuild's minifier sometimes places `import('node:buffer')` inside a
|
|
2600
|
-
// double-quoted string literal; swapping to double quotes breaks the
|
|
2601
|
-
// outer literal and produces `Unexpected identifier 'buffer'`.
|
|
2602
|
-
code = code.replace(/\bfrom(\s*)(["'])node:([^"']+)\2/g, (_, ws, q, mod) => `from${ws}${q}${mod}${q}`);
|
|
2603
|
-
code = code.replace(/\bimport(\s*)(["'])node:([^"']+)\2/g, (_, ws, q, mod) => `import${ws}${q}${mod}${q}`);
|
|
2604
|
-
// Strip `node:` prefix from any string literal that names a node
|
|
2605
|
-
// builtin. Covers dynamic imports, require(), getBuiltinModule(),
|
|
2606
|
-
// and minified wrappers like `Ut("node:fs")` that Nitro/h3 emit.
|
|
2607
|
-
// Pages' loader scans chunks for `"node:*"` literals and fails with
|
|
2608
|
-
// 'No such module "node:fs"' whether or not the string is reached
|
|
2609
|
-
// at runtime. Scoping to known builtins avoids touching user data.
|
|
2610
|
-
// Sorted longest-first so `fs/promises` matches before `fs`.
|
|
2611
|
-
const builtinsPattern = [...NODE_BUILTINS]
|
|
2612
|
-
.sort((a, b) => b.length - a.length)
|
|
2613
|
-
.join("|");
|
|
2614
|
-
const builtinRe = new RegExp(`(["'])node:(${builtinsPattern})\\1`, "g");
|
|
2615
|
-
code = code.replace(builtinRe, (_, q, mod) => `${q}${mod}${q}`);
|
|
2616
|
-
// Rewrite virtual:react-router/server-build imports to the local stub.
|
|
2617
|
-
// The generated entry handles SSR directly; this import is dead code from ssr-handler.
|
|
2618
|
-
const relStub = path
|
|
2619
|
-
.relative(path.dirname(jsFile), virtualStub)
|
|
2620
|
-
.replace(/\\/g, "/");
|
|
2621
|
-
code = code.replace(/["']virtual:react-router\/server-build["']/g, `"./${relStub}"`);
|
|
2622
|
-
// Patch createRequire(import.meta.url) — import.meta.url is undefined in CF Workers.
|
|
2623
|
-
// Matches both `from "module"` and `from "node:module"` — with the node:
|
|
2624
|
-
// prefix preserved (for nodejs_compat_v2), the latter is what esbuild now emits.
|
|
2625
|
-
code = code.replace(/\bimport\s*\{\s*createRequire\s+as\s+([\w$]+)\s*\}\s*from\s*["'](?:node:)?module["']\s*;/g, "var $1 = function() { return typeof require !== 'undefined' ? require : function(m) { throw new Error('require not supported: ' + m); }; };");
|
|
2626
|
-
// Patch setInterval/setTimeout at module scope — CF Workers disallows timers in global scope.
|
|
2627
|
-
code = shimCloudflarePagesModuleTimers(code);
|
|
2628
|
-
assertNoCloudflareWorkerStubDynamicImports(code, jsFile);
|
|
2629
|
-
fs.writeFileSync(jsFile, code);
|
|
2630
|
-
}
|
|
2631
|
-
// Report size
|
|
2632
|
-
const entrySize = fs.statSync(entryFile).size;
|
|
2633
|
-
const totalSize = getDirSize(workerOutDir);
|
|
2634
|
-
const chunkCount = allJsFiles.length - 1; // exclude entry
|
|
2635
|
-
console.log(`[deploy] Cloudflare Pages output written to dist/ (entry: ${(entrySize / 1024).toFixed(0)}KB, ${chunkCount} chunks, total: ${(totalSize / 1024 / 1024).toFixed(1)}MB)`);
|
|
2636
|
-
}
|
|
2637
2347
|
const NODE_BUILTINS = [
|
|
2638
2348
|
"assert",
|
|
2639
2349
|
"async_hooks",
|
|
@@ -2685,41 +2395,6 @@ const NODE_BUILTINS = [
|
|
|
2685
2395
|
export function getNodeBuiltinNames() {
|
|
2686
2396
|
return NODE_BUILTINS;
|
|
2687
2397
|
}
|
|
2688
|
-
/**
|
|
2689
|
-
* Generate a require() shim that bridges CJS require("fs") calls to ESM imports.
|
|
2690
|
-
* Injected via esbuild --inject so CJS deps work on Workers runtime.
|
|
2691
|
-
*/
|
|
2692
|
-
function generateRequireShim() {
|
|
2693
|
-
// Shim Node builtins that Cloudflare Pages can import, and return lazy
|
|
2694
|
-
// unavailable proxies for builtins that Pages Functions reject at upload
|
|
2695
|
-
// time (child_process, fs, net, etc.). This lets optional Node-only code stay
|
|
2696
|
-
// present in the shared bundle without making worker initialization fail.
|
|
2697
|
-
const stubbed = new Set(Object.keys(CLOUDFLARE_WORKER_NODE_BUILTIN_STUB_MODULES));
|
|
2698
|
-
const shimmed = NODE_BUILTINS.filter((name) => !stubbed.has(name));
|
|
2699
|
-
// Bare module names — CF Pages Functions runs under nodejs_compat v1,
|
|
2700
|
-
// which rejects "node:fs" and only accepts "fs". The post-build pass in
|
|
2701
|
-
// buildCloudflarePages() also strips any `node:` prefix that esbuild or
|
|
2702
|
-
// dependencies emit elsewhere.
|
|
2703
|
-
const imports = shimmed
|
|
2704
|
-
.map((m) => `import __${m.replace("/", "_")} from "${m}";`)
|
|
2705
|
-
.join("");
|
|
2706
|
-
// Only bare-name keys. Pages' Functions loader appears to scan chunks
|
|
2707
|
-
// for "node:*" string literals and pre-resolves them as module specs —
|
|
2708
|
-
// so keeping "node:fs" as an object key caused deploy to fail with
|
|
2709
|
-
// 'No such module "node:fs"' even though nothing imported it. The
|
|
2710
|
-
// post-build strip turns every runtime `require("node:fs")` into
|
|
2711
|
-
// `require("fs")` so bare keys are sufficient.
|
|
2712
|
-
const entries = shimmed
|
|
2713
|
-
.map((m) => `"${m}":__${m.replace("/", "_")}`)
|
|
2714
|
-
.join(",");
|
|
2715
|
-
const stubEntries = Array.from(stubbed)
|
|
2716
|
-
.sort()
|
|
2717
|
-
.map((m) => `"${m}":__unavailable("${m}")`)
|
|
2718
|
-
.join(",");
|
|
2719
|
-
const allEntries = [entries, stubEntries].filter(Boolean).join(",");
|
|
2720
|
-
const messageChannelPolyfill = `if(typeof MessageChannel==="undefined"){globalThis.MessageChannel=class{constructor(){const a={onmessage:null},b={onmessage:null};a.postMessage=d=>{if(b.onmessage)setTimeout(()=>b.onmessage({data:d}),0)};b.postMessage=d=>{if(a.onmessage)setTimeout(()=>a.onmessage({data:d}),0)};this.port1=a;this.port2=b}}}`;
|
|
2721
|
-
return `${imports}\n${messageChannelPolyfill}\nconst __unavailable=(m)=>new Proxy({}, { get(_target, prop) { return (..._args) => { throw new Error(m + "." + String(prop) + " is unavailable in Cloudflare Pages workers"); }; } });\nconst __mods={${allEntries}};export var require=globalThis.require||function(m){const r=__mods[m];if(r!==undefined)return r;throw new Error("Cannot require: "+m)};\n`;
|
|
2722
|
-
}
|
|
2723
2398
|
function findEsbuild() {
|
|
2724
2399
|
// Try to resolve esbuild's binary via Node module resolution
|
|
2725
2400
|
// This works regardless of hoisting or .bin symlink creation
|
|
@@ -2754,21 +2429,6 @@ function findWorkspaceRoot(dir) {
|
|
|
2754
2429
|
}
|
|
2755
2430
|
return null;
|
|
2756
2431
|
}
|
|
2757
|
-
/** Recursively collect all .js files in a directory. */
|
|
2758
|
-
function getAllJsFiles(dir) {
|
|
2759
|
-
const results = [];
|
|
2760
|
-
const entries = fs.readdirSync(dir, { withFileTypes: true });
|
|
2761
|
-
for (const entry of entries) {
|
|
2762
|
-
const fullPath = path.join(dir, entry.name);
|
|
2763
|
-
if (entry.isDirectory()) {
|
|
2764
|
-
results.push(...getAllJsFiles(fullPath));
|
|
2765
|
-
}
|
|
2766
|
-
else if (entry.name.endsWith(".js")) {
|
|
2767
|
-
results.push(fullPath);
|
|
2768
|
-
}
|
|
2769
|
-
}
|
|
2770
|
-
return results;
|
|
2771
|
-
}
|
|
2772
2432
|
function getDirSize(dir) {
|
|
2773
2433
|
let size = 0;
|
|
2774
2434
|
const entries = fs.readdirSync(dir, { withFileTypes: true });
|
|
@@ -5453,17 +5113,18 @@ export default bundle;
|
|
|
5453
5113
|
await nitro.close();
|
|
5454
5114
|
console.log(`[deploy] Nitro build complete for preset "${preset}".`);
|
|
5455
5115
|
}
|
|
5116
|
+
export function assertCloudflarePagesPresetRemoved(targetPreset) {
|
|
5117
|
+
if (targetPreset === "cloudflare_pages" ||
|
|
5118
|
+
targetPreset === "cloudflare-pages") {
|
|
5119
|
+
console.error(`[deploy] Unsupported preset "${targetPreset}". Cloudflare Pages was removed. Use cloudflare_module for Cloudflare Workers.`);
|
|
5120
|
+
process.exit(1);
|
|
5121
|
+
}
|
|
5122
|
+
}
|
|
5456
5123
|
async function main() {
|
|
5457
5124
|
console.log(`[deploy] Building for ${preset}...`);
|
|
5125
|
+
assertCloudflarePagesPresetRemoved(preset);
|
|
5458
5126
|
await resolveDeployFrameworkRoutePrefix();
|
|
5459
5127
|
switch (preset) {
|
|
5460
|
-
case "cloudflare_pages":
|
|
5461
|
-
case "cloudflare-pages":
|
|
5462
|
-
// Cloudflare Workers require a single-file bundle that wrangler can deploy.
|
|
5463
|
-
// Nitro's native presets produce split chunks that wrangler can't upload
|
|
5464
|
-
// as multi-module Workers. Use the custom esbuild-based bundler.
|
|
5465
|
-
await buildCloudflarePages();
|
|
5466
|
-
break;
|
|
5467
5128
|
case "cloudflare_module":
|
|
5468
5129
|
case "cloudflare-module":
|
|
5469
5130
|
await buildWithNitro();
|
|
@@ -15,14 +15,14 @@
|
|
|
15
15
|
* want the whole workspace behind one domain.
|
|
16
16
|
*/
|
|
17
17
|
import { execFileSync } from "child_process";
|
|
18
|
-
export type WorkspaceDeployPreset = "
|
|
18
|
+
export type WorkspaceDeployPreset = "netlify" | "vercel";
|
|
19
19
|
export interface WorkspaceDeployOptions {
|
|
20
20
|
args?: string[];
|
|
21
21
|
/** Override the workspace root (defaults to walking up from cwd). */
|
|
22
22
|
workspaceRoot?: string;
|
|
23
23
|
/** Only build — don't invoke the deploy platform CLI. */
|
|
24
24
|
buildOnly?: boolean;
|
|
25
|
-
/** Target preset. Defaults to `
|
|
25
|
+
/** Target preset. Defaults to `netlify`. */
|
|
26
26
|
preset?: WorkspaceDeployPreset;
|
|
27
27
|
/** @internal Override process execution in tests. */
|
|
28
28
|
execFile?: typeof execFileSync;
|
|
@@ -130,7 +130,7 @@ export async function runWorkspaceDeploy(opts = {}) {
|
|
|
130
130
|
buildOneApp(workspaceRoot, appsDir, app, preset, execFile, workspaceApps, workspaceAuthMode);
|
|
131
131
|
moveAppBuildIntoWorkspaceOutput(workspaceRoot, appsDir, app, preset, distDir, vercelOutputDir, workspaceApps, workspaceAuthMode);
|
|
132
132
|
}
|
|
133
|
-
writeWorkspaceAppManifests(workspaceRoot,
|
|
133
|
+
writeWorkspaceAppManifests(workspaceRoot, apps, workspaceApps, preset);
|
|
134
134
|
if (workspaceRootPage === "directory") {
|
|
135
135
|
writeWorkspaceDirectoryPage(preset === "vercel" ? path.join(vercelOutputDir, "static") : distDir, workspaceApps);
|
|
136
136
|
}
|
|
@@ -138,11 +138,8 @@ export async function runWorkspaceDeploy(opts = {}) {
|
|
|
138
138
|
writeNetlifyRedirects(distDir, apps, workspaceRootPage);
|
|
139
139
|
writeNetlifyHeaders(distDir, apps);
|
|
140
140
|
}
|
|
141
|
-
else if (preset === "vercel") {
|
|
142
|
-
writeVercelBuildConfig(vercelOutputDir, apps, workspaceRootPage);
|
|
143
|
-
}
|
|
144
141
|
else {
|
|
145
|
-
|
|
142
|
+
writeVercelBuildConfig(vercelOutputDir, apps, workspaceRootPage);
|
|
146
143
|
}
|
|
147
144
|
if (buildOnly) {
|
|
148
145
|
const outputDir = preset === "vercel" ? vercelOutputDir : distDir;
|
|
@@ -154,11 +151,8 @@ export async function runWorkspaceDeploy(opts = {}) {
|
|
|
154
151
|
if (preset === "netlify") {
|
|
155
152
|
console.log(` netlify deploy --prod --dir=dist --functions=.netlify/functions-internal\n`);
|
|
156
153
|
}
|
|
157
|
-
else if (preset === "vercel") {
|
|
158
|
-
console.log(` vercel deploy --prebuilt\n`);
|
|
159
|
-
}
|
|
160
154
|
else {
|
|
161
|
-
console.log(`
|
|
155
|
+
console.log(` vercel deploy --prebuilt\n`);
|
|
162
156
|
}
|
|
163
157
|
console.log(`All apps live at https://<origin>/<app-name>/*. Log in once on any app\nand the session is shared across the workspace.`);
|
|
164
158
|
}
|
|
@@ -230,8 +224,7 @@ function moveAppBuildIntoWorkspaceOutput(workspaceRoot, appsDir, app, preset, di
|
|
|
230
224
|
return;
|
|
231
225
|
}
|
|
232
226
|
// Resolve the per-app build output: prefer dist/ (standard), fall back to
|
|
233
|
-
// .output/ (Nitro's default).
|
|
234
|
-
// containing the worker + assets.
|
|
227
|
+
// .output/ (Nitro's default).
|
|
235
228
|
const candidates = ["dist", ".output"];
|
|
236
229
|
const src = candidates
|
|
237
230
|
.map((c) => path.join(appDir, c))
|
|
@@ -251,11 +244,6 @@ function moveAppBuildIntoWorkspaceOutput(workspaceRoot, appsDir, app, preset, di
|
|
|
251
244
|
fs.rmSync(path.join(target, app), { recursive: true, force: true });
|
|
252
245
|
copyNetlifyFunctionIntoWorkspace(workspaceRoot, appsDir, app, workspaceApps, target, workspaceAuthMode);
|
|
253
246
|
}
|
|
254
|
-
else {
|
|
255
|
-
const target = path.join(distDir, app);
|
|
256
|
-
fs.mkdirSync(target, { recursive: true });
|
|
257
|
-
copyDir(src, target);
|
|
258
|
-
}
|
|
259
247
|
}
|
|
260
248
|
function copyVercelAppBuildIntoWorkspace(appsDir, app, vercelOutputDir, workspaceApps, workspaceAuthMode) {
|
|
261
249
|
const appDir = path.join(appsDir, app);
|
|
@@ -288,107 +276,6 @@ function copyVercelAppBuildIntoWorkspace(appsDir, app, vercelOutputDir, workspac
|
|
|
288
276
|
cloneServerBundleForFunction(functionSrc, functionDest);
|
|
289
277
|
patchVercelFunctionEntry(functionDest, app, workspaceApps, workspaceAuthMode);
|
|
290
278
|
}
|
|
291
|
-
/**
|
|
292
|
-
* Write the Cloudflare Pages `_routes.json` and a dispatcher `_worker.js` at
|
|
293
|
-
* the workspace dist root so each app is reachable under /<app>/*.
|
|
294
|
-
*/
|
|
295
|
-
function writeCloudflareRoutingManifest(distDir, apps, rootPage) {
|
|
296
|
-
const dispatchFaviconAsset = apps.includes("dispatch")
|
|
297
|
-
? dispatchRootFaviconAsset(distDir)
|
|
298
|
-
: null;
|
|
299
|
-
// _routes.json tells Cloudflare which paths are dynamic (Functions) vs
|
|
300
|
-
// static. Mark both /<app> and /<app>/* as include so every app's worker
|
|
301
|
-
// handles its root and subtree.
|
|
302
|
-
const include = [
|
|
303
|
-
...apps.flatMap((a) => [`/${a}`, `/${a}/*`]),
|
|
304
|
-
...apps.flatMap((app) => workspaceOAuthDiscoveryRoutes(app).flatMap(({ path, descendants }) => [
|
|
305
|
-
path,
|
|
306
|
-
...(descendants ? [`${path}/*`] : []),
|
|
307
|
-
])),
|
|
308
|
-
];
|
|
309
|
-
if (rootPage !== "directory")
|
|
310
|
-
include.push("/");
|
|
311
|
-
if (apps.includes("dispatch")) {
|
|
312
|
-
include.push(`${workspaceFrameworkRoutePrefix()}/*`);
|
|
313
|
-
include.push("/.well-known/*");
|
|
314
|
-
include.push(...DISPATCH_WORKSPACE_ROOT_REDIRECTS.map(([from]) => `/${from}`));
|
|
315
|
-
include.push("/apps/*");
|
|
316
|
-
if (dispatchFaviconAsset)
|
|
317
|
-
include.push("/favicon.ico");
|
|
318
|
-
}
|
|
319
|
-
const routes = {
|
|
320
|
-
version: 1,
|
|
321
|
-
include,
|
|
322
|
-
exclude: [],
|
|
323
|
-
};
|
|
324
|
-
fs.writeFileSync(path.join(distDir, "_routes.json"), JSON.stringify(routes, null, 2) + "\n");
|
|
325
|
-
// Dispatcher worker: inspects the path and forwards to the matching
|
|
326
|
-
// per-app worker.
|
|
327
|
-
const imports = apps
|
|
328
|
-
.map((a) => `import ${moduleIdent(a)} from "./${a}/_worker.js";`)
|
|
329
|
-
.join("\n");
|
|
330
|
-
const dispatch = apps
|
|
331
|
-
.map((a) => ` if (pathname === "/${a}" || pathname === "/${a}.data" || pathname.startsWith("/${a}/")) return ${moduleIdent(a)}.fetch(requestForMountedApp(request, "/${a}"), env, ctx);`)
|
|
332
|
-
.join("\n");
|
|
333
|
-
const workspaceOAuthRoutes = apps
|
|
334
|
-
.flatMap((app) => workspaceOAuthDiscoveryRoutes(app).map(({ path, descendants }) => {
|
|
335
|
-
const matches = descendants
|
|
336
|
-
? `pathname === ${JSON.stringify(path)} || pathname.startsWith(${JSON.stringify(`${path}/`)})`
|
|
337
|
-
: `pathname === ${JSON.stringify(path)}`;
|
|
338
|
-
return ` if (${matches}) return ${moduleIdent(app)}.fetch(request, env, ctx);`;
|
|
339
|
-
}))
|
|
340
|
-
.join("\n");
|
|
341
|
-
const dispatchRootFrameworkRoutes = apps.includes("dispatch")
|
|
342
|
-
? ` if (pathname === ${JSON.stringify(workspaceFrameworkRoutePrefix())} || pathname.startsWith(${JSON.stringify(`${workspaceFrameworkRoutePrefix()}/`)}) || pathname === "/.well-known" || pathname.startsWith("/.well-known/")) return ${moduleIdent("dispatch")}.fetch(request, env, ctx);
|
|
343
|
-
`
|
|
344
|
-
: "";
|
|
345
|
-
const dispatchRootFaviconRoute = dispatchFaviconAsset
|
|
346
|
-
? ` if (pathname === "/favicon.ico") return Response.redirect(new URL("/dispatch/${dispatchFaviconAsset}", request.url).toString(), 302);
|
|
347
|
-
`
|
|
348
|
-
: "";
|
|
349
|
-
const dispatchRootAliasRoutes = apps.includes("dispatch")
|
|
350
|
-
? DISPATCH_WORKSPACE_ROOT_REDIRECTS.map(([from, to]) => ` if (pathname === "/${from}") return Response.redirect(new URL("/dispatch/${to}" + search, request.url).toString(), 302);`).join("\n") + "\n"
|
|
351
|
-
: "";
|
|
352
|
-
const dispatchRootDynamicAliasRoutes = apps.includes("dispatch")
|
|
353
|
-
? ` if (pathname.startsWith("/apps/")) return Response.redirect(new URL("/dispatch" + pathname + search, request.url).toString(), 302);
|
|
354
|
-
`
|
|
355
|
-
: "";
|
|
356
|
-
const dispatchMountedRootRedirect = apps.includes("dispatch")
|
|
357
|
-
? ` if (pathname === "/dispatch" || pathname === "/dispatch/") return Response.redirect(new URL("/dispatch/overview" + search, request.url).toString(), 302);
|
|
358
|
-
`
|
|
359
|
-
: "";
|
|
360
|
-
const rootRedirect = rootPage === "directory"
|
|
361
|
-
? ""
|
|
362
|
-
: ` if (pathname === "/") {
|
|
363
|
-
return Response.redirect(new URL("${cloudflareRootRedirectPath(apps)}", request.url).toString(), 302);
|
|
364
|
-
}
|
|
365
|
-
`;
|
|
366
|
-
const worker = `${imports}
|
|
367
|
-
|
|
368
|
-
function requestForMountedApp(request, basePath) {
|
|
369
|
-
const url = new URL(request.url);
|
|
370
|
-
if (url.pathname !== basePath && url.pathname !== \`\${basePath}/\`) {
|
|
371
|
-
return request;
|
|
372
|
-
}
|
|
373
|
-
url.pathname = \`\${basePath}//\`;
|
|
374
|
-
return new Request(url, request);
|
|
375
|
-
}
|
|
376
|
-
|
|
377
|
-
export default {
|
|
378
|
-
async fetch(request, env, ctx) {
|
|
379
|
-
const { pathname, search } = new URL(request.url);
|
|
380
|
-
${workspaceOAuthRoutes}
|
|
381
|
-
${dispatchRootFrameworkRoutes}${dispatchRootFaviconRoute}${dispatchRootAliasRoutes}${dispatchRootDynamicAliasRoutes}${dispatchMountedRootRedirect}${dispatch}
|
|
382
|
-
${rootRedirect}
|
|
383
|
-
return new Response("Not found", { status: 404 });
|
|
384
|
-
},
|
|
385
|
-
};
|
|
386
|
-
`;
|
|
387
|
-
fs.writeFileSync(path.join(distDir, "_worker.js"), worker);
|
|
388
|
-
}
|
|
389
|
-
function cloudflareRootRedirectPath(apps) {
|
|
390
|
-
return apps.includes("dispatch") ? "/dispatch/overview" : `/${apps[0]}/`;
|
|
391
|
-
}
|
|
392
279
|
function workspaceOAuthDiscoveryRoutes(app) {
|
|
393
280
|
return [
|
|
394
281
|
{
|
|
@@ -1212,16 +1099,14 @@ function appUsesNetlifyUnpooledDatabaseUrl(appDir) {
|
|
|
1212
1099
|
return false;
|
|
1213
1100
|
}
|
|
1214
1101
|
}
|
|
1215
|
-
function writeWorkspaceAppManifests(workspaceRoot,
|
|
1102
|
+
function writeWorkspaceAppManifests(workspaceRoot, apps, workspaceApps, preset) {
|
|
1216
1103
|
const manifest = JSON.stringify({
|
|
1217
1104
|
version: 1,
|
|
1218
1105
|
apps: workspaceApps,
|
|
1219
1106
|
}, null, 2);
|
|
1220
1107
|
const targets = preset === "netlify"
|
|
1221
1108
|
? apps.map((app) => path.join(netlifyFunctionsDir(workspaceRoot), `${app}-server`, WORKSPACE_APPS_MANIFEST_DIR, WORKSPACE_APPS_MANIFEST_FILE))
|
|
1222
|
-
:
|
|
1223
|
-
? apps.map((app) => path.join(workspaceRoot, VERCEL_OUTPUT_DIR, "functions", `${app}-server.func`, WORKSPACE_APPS_MANIFEST_DIR, WORKSPACE_APPS_MANIFEST_FILE))
|
|
1224
|
-
: apps.map((app) => path.join(distDir, app, WORKSPACE_APPS_MANIFEST_DIR, WORKSPACE_APPS_MANIFEST_FILE));
|
|
1109
|
+
: apps.map((app) => path.join(workspaceRoot, VERCEL_OUTPUT_DIR, "functions", `${app}-server.func`, WORKSPACE_APPS_MANIFEST_DIR, WORKSPACE_APPS_MANIFEST_FILE));
|
|
1225
1110
|
for (const target of targets) {
|
|
1226
1111
|
fs.mkdirSync(path.dirname(target), { recursive: true });
|
|
1227
1112
|
fs.writeFileSync(target, `${manifest}\n`);
|
|
@@ -1525,7 +1410,7 @@ function resolvePreset(optionPreset, args) {
|
|
|
1525
1410
|
return (optionPreset ??
|
|
1526
1411
|
parsePresetArg(args) ??
|
|
1527
1412
|
normalizePreset(process.env.NITRO_PRESET) ??
|
|
1528
|
-
"
|
|
1413
|
+
"netlify");
|
|
1529
1414
|
}
|
|
1530
1415
|
function assertWorkspaceDeployProductionEnv(opts) {
|
|
1531
1416
|
if (!isProductionWorkspaceDeploy(opts))
|
|
@@ -1550,9 +1435,6 @@ function isProductionWorkspaceDeploy(opts) {
|
|
|
1550
1435
|
process.env.NETLIFY_LOCAL !== "true") {
|
|
1551
1436
|
return true;
|
|
1552
1437
|
}
|
|
1553
|
-
if (opts.preset === "cloudflare_pages" && process.env.CF_PAGES === "1") {
|
|
1554
|
-
return true;
|
|
1555
|
-
}
|
|
1556
1438
|
if (opts.preset === "vercel" && process.env.VERCEL === "1") {
|
|
1557
1439
|
return true;
|
|
1558
1440
|
}
|
|
@@ -1562,16 +1444,13 @@ function normalizePreset(value) {
|
|
|
1562
1444
|
if (!value)
|
|
1563
1445
|
return null;
|
|
1564
1446
|
if (value === "cloudflare_pages" || value === "cloudflare-pages") {
|
|
1565
|
-
|
|
1447
|
+
throw new Error(`Unsupported workspace deploy preset "${value}". Cloudflare Pages was removed. Supported presets: netlify, vercel. For standalone Cloudflare Workers use NITRO_PRESET=cloudflare_module.`);
|
|
1566
1448
|
}
|
|
1567
1449
|
if (value === "netlify")
|
|
1568
1450
|
return "netlify";
|
|
1569
1451
|
if (value === "vercel")
|
|
1570
1452
|
return "vercel";
|
|
1571
|
-
throw new Error(`Unsupported workspace deploy preset "${value}". Supported presets:
|
|
1572
|
-
}
|
|
1573
|
-
function moduleIdent(app) {
|
|
1574
|
-
return "app_" + app.replace(/[^a-zA-Z0-9_]/g, "_");
|
|
1453
|
+
throw new Error(`Unsupported workspace deploy preset "${value}". Supported presets: netlify, vercel.`);
|
|
1575
1454
|
}
|
|
1576
1455
|
function workspaceAppAudienceForApp(workspaceApps, app) {
|
|
1577
1456
|
return (workspaceApps.find((entry) => entry.id === app)?.audience ??
|
|
@@ -44,9 +44,9 @@ declare const _default: import("../../action.js").ActionDefinition<{
|
|
|
44
44
|
url: string;
|
|
45
45
|
id: string;
|
|
46
46
|
provider: string;
|
|
47
|
-
error?: undefined;
|
|
48
47
|
configured?: undefined;
|
|
49
48
|
connectPath?: undefined;
|
|
49
|
+
error?: undefined;
|
|
50
50
|
} | {
|
|
51
51
|
url?: undefined;
|
|
52
52
|
id?: undefined;
|