experimental-ash 0.24.0 → 0.24.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +19 -0
- package/dist/src/chunks/authored-module-loader-DcCfCiBm.js +4 -0
- package/dist/src/chunks/client-DLHAGI2g.js +4 -0
- package/dist/src/chunks/dev-authored-source-watcher-CBID_Dwh.js +1 -0
- package/dist/src/chunks/{errors-DsO9xmQL.js → errors-HYWjHxV6.js} +1 -1
- package/dist/src/chunks/{gray-matter-BxS7ZG-J.js → gray-matter-D-9jHwOT.js} +4 -4
- package/dist/src/chunks/host-zBy9FyyX.js +70 -0
- package/dist/src/chunks/{jsdist-M7JFZoA4.js → jsdist-BkeWZ7EZ.js} +61 -61
- package/dist/src/chunks/package-HUaeub_D.js +1 -0
- package/dist/src/chunks/paths-CebY5GCi.js +89 -0
- package/dist/src/chunks/{picocolors-Bq-tZK9u.js → picocolors-aAkqW4On.js} +1 -1
- package/dist/src/chunks/token-D98SQdvs.js +1 -0
- package/dist/src/chunks/{url-BVRhVE2O.js → url-JdCGA634.js} +1 -1
- package/dist/src/cli/commands/info.js +1 -1
- package/dist/src/cli/dev/environment.d.ts +16 -2
- package/dist/src/cli/dev/environment.js +1 -1
- package/dist/src/cli/dev/input-requests.js +1 -1
- package/dist/src/cli/dev/repl.js +3 -3
- package/dist/src/cli/dev/url.js +1 -1
- package/dist/src/cli/run.js +1 -1
- package/dist/src/cli/ui/output.js +1 -1
- package/dist/src/client/index.d.ts +1 -0
- package/dist/src/client/index.js +1 -0
- package/dist/src/compiled/.vendor-stamp.json +7 -6
- package/dist/src/compiled/@ai-sdk/anthropic/index.js +1 -1
- package/dist/src/compiled/@ai-sdk/google/index.js +1 -1
- package/dist/src/compiled/@ai-sdk/mcp/index.js +1 -1
- package/dist/src/compiled/@ai-sdk/openai/index.js +1 -1
- package/dist/src/compiled/@ai-sdk/otel/index.js +1 -1
- package/dist/src/compiled/@chat-adapter/slack/_slack-web-api.d.ts +7 -0
- package/dist/src/compiled/@chat-adapter/slack/index.d.ts +418 -109
- package/dist/src/compiled/@chat-adapter/slack/index.js +31 -27
- package/dist/src/compiled/@chat-adapter/slack/package.json +1 -1
- package/dist/src/compiled/@chat-adapter/state-memory/index.d.ts +8 -2
- package/dist/src/compiled/@chat-adapter/state-memory/index.js +1 -1
- package/dist/src/compiled/@chat-adapter/state-memory/package.json +1 -1
- package/dist/src/compiled/@opentelemetry/api/index.js +1 -1
- package/dist/src/compiled/@vercel/sandbox/index.js +19 -17
- package/dist/src/compiled/@vercel/sandbox/package.json +1 -1
- package/dist/src/compiled/@workflow/core/index.js +2 -2
- package/dist/src/compiled/@workflow/core/runtime.js +22 -22
- package/dist/src/compiled/@workflow/core/workflow.js +1 -1
- package/dist/src/compiled/@workflow/errors/index.js +1 -1
- package/dist/src/compiled/_chunks/node/auth-ZhCJAHxl.js +2 -0
- package/dist/src/compiled/_chunks/node/{dist-BdWHjlRQ.js → dist-BQYUcBqu.js} +31 -31
- package/dist/src/compiled/_chunks/node/{chunk-Dd2tEFlW.js → dist-BdTs18CF.js} +1 -1
- package/dist/src/compiled/_chunks/node/retry-DkR2H1Y0.js +1 -0
- package/dist/src/compiled/_chunks/node/token-CoIbMZkq.js +1 -0
- package/dist/src/compiled/_chunks/node/{version-BMyZn3Y2.js → version-D4IYmfaS.js} +1 -1
- package/dist/src/compiled/_chunks/workflow/coerce-BhzIW-Hm.js +1 -0
- package/dist/src/compiled/_chunks/workflow/{compat-CIROS3w4.js → compat-DcEvieoj.js} +1 -1
- package/dist/src/compiled/_chunks/workflow/{core-DOVmxHH8.js → core-XWIi7wKc.js} +3 -3
- package/dist/src/compiled/_chunks/workflow/{dist-C7wPwOI9.js → dist-DO14ZaQj.js} +1 -1
- package/dist/src/compiled/_chunks/workflow/{dist-CpUQh3NH.js → dist-DZZY3Zyp.js} +1 -1
- package/dist/src/compiled/_chunks/workflow/resume-hook-DOMbNs-S.js +51 -0
- package/dist/src/compiled/_chunks/workflow/{schemas-DFZoEyCn.js → schemas-DmgDnhW3.js} +1 -1
- package/dist/src/compiled/_chunks/workflow/sleep-CRjce49s.js +1 -0
- package/dist/src/compiled/_chunks/workflow/{src-ClRYdO4-.js → src-B54rYDvB.js} +1 -1
- package/dist/src/compiled/_chunks/workflow/symbols-D8paKc8P.js +9 -0
- package/dist/src/compiled/_chunks/workflow/{token-CsNmv7KW.js → token-D9z1dMB6.js} +1 -1
- package/dist/src/compiled/_chunks/workflow/{token-j5Cl4rrs.js → token-DV7rQw_t.js} +1 -1
- package/dist/src/compiled/chat/index.d.ts +6 -3143
- package/dist/src/compiled/chat/index.js +1 -1
- package/dist/src/compiled/chat/{jsx-runtime-DxGwoLu2.d.ts → jsx-runtime-CFq1K_Ve.d.ts} +1 -1
- package/dist/src/compiled/chat/package.json +1 -1
- package/dist/src/compiled/jose/index.js +2 -2
- package/dist/src/compiled/jsonc-parser/LICENSE.md +21 -0
- package/dist/src/compiled/jsonc-parser/index.d.ts +13 -0
- package/dist/src/compiled/jsonc-parser/index.js +15 -0
- package/dist/src/compiled/jsonc-parser/package.json +7 -0
- package/dist/src/compiled/just-bash/index.js +773 -773
- package/dist/src/compiled/just-bash/package.json +1 -1
- package/dist/src/compiled/turndown/index.js +1 -1
- package/dist/src/compiled/zod/index.js +1 -1
- package/dist/src/compiled/zod-validation-error/index.js +1 -1
- package/dist/src/compiler/manifest.d.ts +36 -3
- package/dist/src/compiler/manifest.js +5 -1
- package/dist/src/compiler/module-map.js +8 -0
- package/dist/src/compiler/normalize-manifest.js +1 -0
- package/dist/src/compiler/normalize-subagent.d.ts +3 -2
- package/dist/src/compiler/normalize-subagent.js +112 -3
- package/dist/src/compiler/remote-agent-node.d.ts +20 -0
- package/dist/src/compiler/remote-agent-node.js +19 -0
- package/dist/src/discover/discover-subagent.js +35 -2
- package/dist/src/discover/grammar.d.ts +1 -0
- package/dist/src/discover/grammar.js +5 -0
- package/dist/src/evals/cli/eval.js +1 -1
- package/dist/src/evals/loaders/yaml.js +1 -1
- package/dist/src/evals/runner/discover.js +1 -1
- package/dist/src/evals/runner/execute-suite.js +1 -1
- package/dist/src/evals/runner/reporters/console.js +1 -1
- package/dist/src/evals/scorers/autoevals-client.js +1 -1
- package/dist/src/evals/scorers/autoevals.js +1 -1
- package/dist/src/evals/scorers/json.js +1 -1
- package/dist/src/evals/scorers/run.js +1 -1
- package/dist/src/evals/scorers/sql.js +1 -1
- package/dist/src/evals/scorers/text.js +1 -1
- package/dist/src/execution/connection-auth-steps.js +2 -0
- package/dist/src/internal/application/package.js +1 -1
- package/dist/src/internal/authored-asset-import-plugin.d.ts +5 -0
- package/dist/src/internal/authored-asset-import-plugin.js +141 -0
- package/dist/src/internal/authored-module-bundle.d.ts +4 -0
- package/dist/src/internal/authored-module-bundle.js +19 -0
- package/dist/src/internal/authored-module-loader.d.ts +6 -0
- package/dist/src/internal/authored-module-loader.js +114 -125
- package/dist/src/internal/authored-package-tsconfig-paths.d.ts +9 -0
- package/dist/src/internal/authored-package-tsconfig-paths.js +209 -0
- package/dist/src/internal/nitro/host/channel-routes.d.ts +9 -2
- package/dist/src/internal/nitro/host/dev-authored-source-watcher.d.ts +12 -1
- package/dist/src/internal/nitro/host/dev-authored-source-watcher.js +19 -3
- package/dist/src/internal/nitro/host/schedule-task-routes.d.ts +7 -3
- package/dist/src/internal/nitro/host/start-development-server.js +2 -0
- package/dist/src/internal/workflow-bundle/builder-support.js +1 -33
- package/dist/src/public/agents/auth.d.ts +30 -0
- package/dist/src/public/agents/auth.js +37 -0
- package/dist/src/public/definitions/remote-agent.d.ts +25 -0
- package/dist/src/public/definitions/remote-agent.js +11 -0
- package/dist/src/public/index.d.ts +1 -0
- package/dist/src/public/index.js +1 -0
- package/dist/src/public/next/index.d.ts +4 -4
- package/dist/src/public/next/index.js +16 -25
- package/dist/src/runtime/connections/mcp-client.js +3 -2
- package/dist/src/runtime/connections/types.d.ts +24 -0
- package/dist/src/runtime/resolve-agent-graph.js +57 -0
- package/dist/src/runtime/sessions/turn.d.ts +17 -5
- package/dist/src/runtime/subagents/registry.d.ts +6 -6
- package/dist/src/runtime/subagents/registry.js +1 -1
- package/dist/src/runtime/types.d.ts +20 -0
- package/package.json +22 -17
- package/dist/src/chunks/authored-module-loader-XcFLnl49.js +0 -2
- package/dist/src/chunks/client-nshDsWNF.js +0 -4
- package/dist/src/chunks/dev-authored-source-watcher-B4PaZGUr.js +0 -7
- package/dist/src/chunks/host-DsW72Q-w.js +0 -65
- package/dist/src/chunks/package-DmsQgn4v.js +0 -1
- package/dist/src/chunks/paths-OknjaYR8.js +0 -89
- package/dist/src/chunks/prewarm-B4YblQ5m.js +0 -6
- package/dist/src/chunks/token-DtoyQZy2.js +0 -1
- package/dist/src/chunks/token-util-CHjOk3A7.js +0 -1
- package/dist/src/compiled/_chunks/node/auth-vbe4XEEK.js +0 -2
- package/dist/src/compiled/_chunks/node/dist-DMSq2ehP.js +0 -1
- package/dist/src/compiled/_chunks/node/retry-BOcy5BbJ.js +0 -1
- package/dist/src/compiled/_chunks/node/token-D-BTJHoU.js +0 -1
- package/dist/src/compiled/_chunks/workflow/coerce-Dh0wa7P9.js +0 -1
- package/dist/src/compiled/_chunks/workflow/context-errors-Bbvvp-li.js +0 -6
- package/dist/src/compiled/_chunks/workflow/dist-C_oiE-l7.js +0 -40
- package/dist/src/compiled/_chunks/workflow/resume-hook-C3VWUPii.js +0 -12
- package/dist/src/compiled/_chunks/workflow/sleep-QTkC1VFe.js +0 -1
- package/dist/src/compiled/_chunks/workflow/symbols-QezhMuLg.js +0 -4
- package/dist/src/compiled/chat/_workflow-serde.d.ts +0 -5
- /package/dist/src/chunks/{chunk-8L7ocgPr.js → chunk-DSjMdhoD.js} +0 -0
- /package/dist/src/chunks/{guards-CjJ3lmju.js → guards-26p6sOw3.js} +0 -0
- /package/dist/src/chunks/{input-requests-BsBi7_5K.js → input-requests-DJiy6dG9.js} +0 -0
- /package/dist/src/chunks/{runtime-model-BWu6M_hq.js → runtime-model-Dh0Nz64z.js} +0 -0
- /package/dist/src/chunks/{types-MZUhN0Zy.js → types-DDA2QUED.js} +0 -0
- /package/dist/src/compiled/_chunks/workflow/{chunk-DHhdAPOb.js → chunk-DSjMdhoD.js} +0 -0
|
@@ -0,0 +1,209 @@
|
|
|
1
|
+
import { readFile, stat } from "node:fs/promises";
|
|
2
|
+
import { dirname, join, resolve, sep } from "node:path";
|
|
3
|
+
import { parse as parseJsonc } from "#compiled/jsonc-parser/index.js";
|
|
4
|
+
const packageTsConfigPathsCache = new Map();
|
|
5
|
+
const nearestPackageRootCache = new Map();
|
|
6
|
+
/**
|
|
7
|
+
* Resolves tsconfig `paths` for authored source imported from linked
|
|
8
|
+
* workspace packages. Rolldown handles the root app tsconfig; this only
|
|
9
|
+
* fills the package-local config gap for sources outside the app root.
|
|
10
|
+
*/
|
|
11
|
+
export function createAuthoredPackageTsConfigPathsPlugin(input) {
|
|
12
|
+
return {
|
|
13
|
+
name: "ash-package-tsconfig-paths",
|
|
14
|
+
async resolveId(source, importer, options) {
|
|
15
|
+
if (importer === undefined || !isPackageImport(source)) {
|
|
16
|
+
return undefined;
|
|
17
|
+
}
|
|
18
|
+
const importerPath = resolve(importer);
|
|
19
|
+
if (isPathInsideOrEqual(importerPath, input.appPackageRoot)) {
|
|
20
|
+
return undefined;
|
|
21
|
+
}
|
|
22
|
+
const packageRoot = await resolveNearestPackageRoot(importerPath);
|
|
23
|
+
if (packageRoot === undefined || isPathInsideOrEqual(packageRoot, input.appPackageRoot)) {
|
|
24
|
+
return undefined;
|
|
25
|
+
}
|
|
26
|
+
const config = await loadPackageTsConfigPaths(packageRoot);
|
|
27
|
+
if (config === undefined) {
|
|
28
|
+
return undefined;
|
|
29
|
+
}
|
|
30
|
+
for (const candidate of createTsConfigPathCandidates(source, config)) {
|
|
31
|
+
const resolved = await this.resolve(candidate, importer, {
|
|
32
|
+
kind: options.kind,
|
|
33
|
+
skipSelf: true,
|
|
34
|
+
});
|
|
35
|
+
if (resolved !== null) {
|
|
36
|
+
return resolved;
|
|
37
|
+
}
|
|
38
|
+
const existingPath = await resolveExistingPath(candidate, input.extensions);
|
|
39
|
+
if (existingPath !== undefined) {
|
|
40
|
+
return { id: existingPath };
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
return undefined;
|
|
44
|
+
},
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
function loadPackageTsConfigPaths(packageRoot) {
|
|
48
|
+
const cached = packageTsConfigPathsCache.get(packageRoot);
|
|
49
|
+
if (cached !== undefined) {
|
|
50
|
+
return cached;
|
|
51
|
+
}
|
|
52
|
+
const promise = readPackageTsConfigPaths(packageRoot);
|
|
53
|
+
packageTsConfigPathsCache.set(packageRoot, promise);
|
|
54
|
+
return promise;
|
|
55
|
+
}
|
|
56
|
+
async function readPackageTsConfigPaths(packageRoot) {
|
|
57
|
+
const configFile = await readPackageConfig(packageRoot);
|
|
58
|
+
if (configFile === undefined) {
|
|
59
|
+
return undefined;
|
|
60
|
+
}
|
|
61
|
+
const errors = [];
|
|
62
|
+
const parsed = parseJsonc(configFile.source, errors, {
|
|
63
|
+
allowTrailingComma: true,
|
|
64
|
+
});
|
|
65
|
+
if (errors.length > 0 || !isObjectRecord(parsed)) {
|
|
66
|
+
return undefined;
|
|
67
|
+
}
|
|
68
|
+
const compilerOptions = parsed.compilerOptions;
|
|
69
|
+
if (!isObjectRecord(compilerOptions) || !isObjectRecord(compilerOptions.paths)) {
|
|
70
|
+
return undefined;
|
|
71
|
+
}
|
|
72
|
+
const configDirectory = dirname(configFile.path);
|
|
73
|
+
const baseDirectory = typeof compilerOptions.baseUrl === "string"
|
|
74
|
+
? resolve(configDirectory, compilerOptions.baseUrl)
|
|
75
|
+
: configDirectory;
|
|
76
|
+
const entries = Object.entries(compilerOptions.paths)
|
|
77
|
+
.flatMap(([pattern, targets]) => {
|
|
78
|
+
if (!Array.isArray(targets) || !targets.every((target) => typeof target === "string")) {
|
|
79
|
+
return [];
|
|
80
|
+
}
|
|
81
|
+
return [{ pattern, targets }];
|
|
82
|
+
})
|
|
83
|
+
.sort((left, right) => right.pattern.length - left.pattern.length);
|
|
84
|
+
if (entries.length === 0) {
|
|
85
|
+
return undefined;
|
|
86
|
+
}
|
|
87
|
+
return { baseDirectory, entries };
|
|
88
|
+
}
|
|
89
|
+
async function readPackageConfig(packageRoot) {
|
|
90
|
+
for (const fileName of ["tsconfig.json", "jsconfig.json"]) {
|
|
91
|
+
const configPath = join(packageRoot, fileName);
|
|
92
|
+
try {
|
|
93
|
+
return {
|
|
94
|
+
path: configPath,
|
|
95
|
+
source: await readFile(configPath, "utf8"),
|
|
96
|
+
};
|
|
97
|
+
}
|
|
98
|
+
catch (error) {
|
|
99
|
+
if (!isPathNotFoundError(error)) {
|
|
100
|
+
throw error;
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
return undefined;
|
|
105
|
+
}
|
|
106
|
+
function createTsConfigPathCandidates(source, config) {
|
|
107
|
+
const candidates = [];
|
|
108
|
+
for (const entry of config.entries) {
|
|
109
|
+
const match = matchTsConfigPathPattern(source, entry.pattern);
|
|
110
|
+
if (match === undefined) {
|
|
111
|
+
continue;
|
|
112
|
+
}
|
|
113
|
+
for (const target of entry.targets) {
|
|
114
|
+
const targetPath = target.includes("*") ? target.replaceAll("*", match) : target;
|
|
115
|
+
candidates.push(resolve(config.baseDirectory, targetPath));
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
return candidates;
|
|
119
|
+
}
|
|
120
|
+
function matchTsConfigPathPattern(source, pattern) {
|
|
121
|
+
const wildcardIndex = pattern.indexOf("*");
|
|
122
|
+
if (wildcardIndex === -1) {
|
|
123
|
+
return source === pattern ? "" : undefined;
|
|
124
|
+
}
|
|
125
|
+
const prefix = pattern.slice(0, wildcardIndex);
|
|
126
|
+
const suffix = pattern.slice(wildcardIndex + 1);
|
|
127
|
+
if (!source.startsWith(prefix) || !source.endsWith(suffix)) {
|
|
128
|
+
return undefined;
|
|
129
|
+
}
|
|
130
|
+
return source.slice(prefix.length, source.length - suffix.length);
|
|
131
|
+
}
|
|
132
|
+
async function resolveExistingPath(path, extensions) {
|
|
133
|
+
if (await existsAsFile(path)) {
|
|
134
|
+
return path;
|
|
135
|
+
}
|
|
136
|
+
for (const extension of extensions) {
|
|
137
|
+
const candidate = `${path}${extension}`;
|
|
138
|
+
if (await existsAsFile(candidate)) {
|
|
139
|
+
return candidate;
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
for (const extension of extensions) {
|
|
143
|
+
const candidate = join(path, `index${extension}`);
|
|
144
|
+
if (await existsAsFile(candidate)) {
|
|
145
|
+
return candidate;
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
return undefined;
|
|
149
|
+
}
|
|
150
|
+
async function existsAsFile(path) {
|
|
151
|
+
try {
|
|
152
|
+
return (await stat(path)).isFile();
|
|
153
|
+
}
|
|
154
|
+
catch {
|
|
155
|
+
return false;
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
function resolveNearestPackageRoot(path) {
|
|
159
|
+
const startDirectory = dirname(path);
|
|
160
|
+
const cached = nearestPackageRootCache.get(startDirectory);
|
|
161
|
+
if (cached !== undefined) {
|
|
162
|
+
return cached;
|
|
163
|
+
}
|
|
164
|
+
const promise = findNearestPackageRoot(startDirectory);
|
|
165
|
+
nearestPackageRootCache.set(startDirectory, promise);
|
|
166
|
+
return promise;
|
|
167
|
+
}
|
|
168
|
+
async function findNearestPackageRoot(startDirectory) {
|
|
169
|
+
let currentDirectory = startDirectory;
|
|
170
|
+
while (true) {
|
|
171
|
+
if (await pathExists(join(currentDirectory, "package.json"))) {
|
|
172
|
+
return currentDirectory;
|
|
173
|
+
}
|
|
174
|
+
const parentDirectory = dirname(currentDirectory);
|
|
175
|
+
if (parentDirectory === currentDirectory) {
|
|
176
|
+
return undefined;
|
|
177
|
+
}
|
|
178
|
+
currentDirectory = parentDirectory;
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
async function pathExists(path) {
|
|
182
|
+
try {
|
|
183
|
+
await stat(path);
|
|
184
|
+
return true;
|
|
185
|
+
}
|
|
186
|
+
catch {
|
|
187
|
+
return false;
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
function isPathNotFoundError(error) {
|
|
191
|
+
return (typeof error === "object" &&
|
|
192
|
+
error !== null &&
|
|
193
|
+
"code" in error &&
|
|
194
|
+
(error.code === "ENOENT" || error.code === "ENOTDIR"));
|
|
195
|
+
}
|
|
196
|
+
function isPackageImport(source) {
|
|
197
|
+
if (source.startsWith(".") || source.startsWith("/") || /^[A-Za-z]:[\\/]/.test(source)) {
|
|
198
|
+
return false;
|
|
199
|
+
}
|
|
200
|
+
return !/^(?:node|data|file):/.test(source);
|
|
201
|
+
}
|
|
202
|
+
function isObjectRecord(value) {
|
|
203
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
204
|
+
}
|
|
205
|
+
function isPathInsideOrEqual(path, directory) {
|
|
206
|
+
const resolvedPath = resolve(path);
|
|
207
|
+
const resolvedDirectory = resolve(directory);
|
|
208
|
+
return (resolvedPath === resolvedDirectory || resolvedPath.startsWith(`${resolvedDirectory}${sep}`));
|
|
209
|
+
}
|
|
@@ -2,6 +2,12 @@ import type { Nitro } from "nitro/types";
|
|
|
2
2
|
import type { ChannelMethod } from "#public/definitions/channel.js";
|
|
3
3
|
import type { NitroArtifactsConfigInput } from "#internal/nitro/host/artifacts-config.js";
|
|
4
4
|
import type { PreparedApplicationHost } from "#internal/nitro/host/types.js";
|
|
5
|
+
interface ChannelRouteNitro {
|
|
6
|
+
options: Pick<Nitro["options"], "handlers" | "virtual">;
|
|
7
|
+
routing: {
|
|
8
|
+
sync(): void;
|
|
9
|
+
};
|
|
10
|
+
}
|
|
5
11
|
/**
|
|
6
12
|
* One Nitro route registration for an Ash channel.
|
|
7
13
|
*/
|
|
@@ -16,7 +22,7 @@ export declare function computeChannelRouteRegistrations(preparedHost: PreparedA
|
|
|
16
22
|
/**
|
|
17
23
|
* Registers virtual Nitro handlers for the provided Ash channel routes.
|
|
18
24
|
*/
|
|
19
|
-
export declare function registerChannelVirtualHandlers(nitro:
|
|
25
|
+
export declare function registerChannelVirtualHandlers(nitro: Pick<ChannelRouteNitro, "options">, input: {
|
|
20
26
|
readonly artifactsConfig: NitroArtifactsConfigInput;
|
|
21
27
|
readonly registrations: readonly NitroChannelRouteRegistration[];
|
|
22
28
|
}): void;
|
|
@@ -24,8 +30,9 @@ export declare function registerChannelVirtualHandlers(nitro: Nitro, input: {
|
|
|
24
30
|
* Replaces the currently-mounted Ash channel virtual handlers when the route
|
|
25
31
|
* set changes.
|
|
26
32
|
*/
|
|
27
|
-
export declare function syncChannelVirtualHandlers(nitro:
|
|
33
|
+
export declare function syncChannelVirtualHandlers(nitro: ChannelRouteNitro, input: {
|
|
28
34
|
readonly artifactsConfig: NitroArtifactsConfigInput;
|
|
29
35
|
readonly next: readonly NitroChannelRouteRegistration[];
|
|
30
36
|
readonly previous: readonly NitroChannelRouteRegistration[];
|
|
31
37
|
}): boolean;
|
|
38
|
+
export {};
|
|
@@ -1,5 +1,15 @@
|
|
|
1
1
|
import type { Nitro } from "nitro/types";
|
|
2
2
|
import type { PreparedApplicationHost } from "#internal/nitro/host/types.js";
|
|
3
|
+
type DevelopmentWatcherNitroOptions = Pick<Nitro["options"], "experimental" | "handlers" | "scheduledTasks" | "tasks" | "virtual"> & Partial<Pick<Nitro["options"], "dev" | "preset">>;
|
|
4
|
+
interface DevelopmentWatcherNitro {
|
|
5
|
+
hooks: {
|
|
6
|
+
callHook: Nitro["hooks"]["callHook"];
|
|
7
|
+
};
|
|
8
|
+
options: DevelopmentWatcherNitroOptions;
|
|
9
|
+
routing: {
|
|
10
|
+
sync(): void;
|
|
11
|
+
};
|
|
12
|
+
}
|
|
3
13
|
/**
|
|
4
14
|
* Handle for the authored-source development watcher.
|
|
5
15
|
*/
|
|
@@ -13,7 +23,8 @@ export interface AuthoredSourceWatcherHandle {
|
|
|
13
23
|
* triggers Nitro rebuild reloads only when structural runtime wiring changes.
|
|
14
24
|
*/
|
|
15
25
|
export declare function startAuthoredSourceWatcher(input: {
|
|
16
|
-
nitro:
|
|
26
|
+
nitro: DevelopmentWatcherNitro;
|
|
17
27
|
preparedHost: PreparedApplicationHost;
|
|
18
28
|
schedulesEnabled?: boolean;
|
|
19
29
|
}): Promise<AuthoredSourceWatcherHandle>;
|
|
30
|
+
export {};
|
|
@@ -3,7 +3,7 @@ import { readdir, readFile } from "node:fs/promises";
|
|
|
3
3
|
import { createRequire } from "node:module";
|
|
4
4
|
import { dirname, isAbsolute, join, resolve } from "node:path";
|
|
5
5
|
import { watch } from "chokidar";
|
|
6
|
-
import { parse as parseJsonc } from "jsonc-parser";
|
|
6
|
+
import { parse as parseJsonc } from "#compiled/jsonc-parser/index.js";
|
|
7
7
|
import { clearCompiledRuntimeAgentBundleCache } from "#runtime/sessions/compiled-agent-cache.js";
|
|
8
8
|
import { toErrorMessage } from "#shared/errors.js";
|
|
9
9
|
import { resolvePackageSourceFilePath } from "#internal/application/package.js";
|
|
@@ -12,6 +12,7 @@ import { computeChannelRouteRegistrations, syncChannelVirtualHandlers, } from "#
|
|
|
12
12
|
import { prepareApplicationHost } from "#internal/nitro/host/prepare-application-host.js";
|
|
13
13
|
import { prewarmAppSandboxes } from "#execution/sandbox/prewarm.js";
|
|
14
14
|
import { syncScheduleTaskHandlers } from "#internal/nitro/host/schedule-task-routes.js";
|
|
15
|
+
import { getDevelopmentEnvironmentFilePaths, reloadDevelopmentEnvironmentFiles, } from "#cli/dev/environment.js";
|
|
15
16
|
const DEBOUNCE_MS = 120;
|
|
16
17
|
const WATCHED_LOCKFILE_NAMES = [
|
|
17
18
|
"pnpm-lock.yaml",
|
|
@@ -44,6 +45,7 @@ export async function startAuthoredSourceWatcher(input) {
|
|
|
44
45
|
let queue = Promise.resolve();
|
|
45
46
|
let debounceTimer;
|
|
46
47
|
const pendingEvents = new Set();
|
|
48
|
+
const pendingChangedPaths = new Set();
|
|
47
49
|
const initialWatchPaths = await resolveAuthoredWatchPaths(currentHost);
|
|
48
50
|
let currentWatchPathsByKey = createWatchPathMap(initialWatchPaths);
|
|
49
51
|
const watcher = watch(initialWatchPaths, {
|
|
@@ -66,10 +68,16 @@ export async function startAuthoredSourceWatcher(input) {
|
|
|
66
68
|
return;
|
|
67
69
|
}
|
|
68
70
|
const eventSummary = pendingEvents.size;
|
|
71
|
+
const changedPaths = [...pendingChangedPaths];
|
|
69
72
|
pendingEvents.clear();
|
|
73
|
+
pendingChangedPaths.clear();
|
|
70
74
|
const previousHost = currentHost;
|
|
75
|
+
const hasEnvironmentChange = hasDevelopmentEnvironmentFileChange(previousHost.appRoot, changedPaths);
|
|
71
76
|
console.log(`[ash:dev] change detected (${eventSummary} event${eventSummary === 1 ? "" : "s"}), rebuilding authored artifacts...`);
|
|
72
77
|
try {
|
|
78
|
+
if (hasEnvironmentChange) {
|
|
79
|
+
reloadDevelopmentEnvironmentFiles(previousHost.appRoot);
|
|
80
|
+
}
|
|
73
81
|
const nextHost = await prepareApplicationHost(previousHost.appRoot);
|
|
74
82
|
await prewarmAppSandboxes({
|
|
75
83
|
appRoot: nextHost.appRoot,
|
|
@@ -77,7 +85,7 @@ export async function startAuthoredSourceWatcher(input) {
|
|
|
77
85
|
});
|
|
78
86
|
const artifactsConfig = createNitroArtifactsConfig({
|
|
79
87
|
appRoot: nextHost.appRoot,
|
|
80
|
-
dev: input.nitro.options.dev,
|
|
88
|
+
dev: input.nitro.options.dev === true,
|
|
81
89
|
});
|
|
82
90
|
const hasChannelRouteChanged = syncChannelVirtualHandlers(input.nitro, {
|
|
83
91
|
artifactsConfig,
|
|
@@ -92,7 +100,7 @@ export async function startAuthoredSourceWatcher(input) {
|
|
|
92
100
|
});
|
|
93
101
|
clearCompiledRuntimeAgentBundleCache();
|
|
94
102
|
currentHost = nextHost;
|
|
95
|
-
const hasStructuralChange = hasChannelRouteChanged || hasScheduleRegistrationsChanged;
|
|
103
|
+
const hasStructuralChange = hasChannelRouteChanged || hasScheduleRegistrationsChanged || hasEnvironmentChange;
|
|
96
104
|
if (hasStructuralChange) {
|
|
97
105
|
console.log("[ash:dev] structural change detected, reloading Nitro worker...");
|
|
98
106
|
await input.nitro.hooks.callHook("rollup:reload");
|
|
@@ -120,6 +128,7 @@ export async function startAuthoredSourceWatcher(input) {
|
|
|
120
128
|
return;
|
|
121
129
|
}
|
|
122
130
|
pendingEvents.add(`${event}:${changedPath}`);
|
|
131
|
+
pendingChangedPaths.add(changedPath);
|
|
123
132
|
if (debounceTimer !== undefined) {
|
|
124
133
|
clearTimeout(debounceTimer);
|
|
125
134
|
}
|
|
@@ -160,6 +169,9 @@ async function resolveAuthoredWatchPaths(host) {
|
|
|
160
169
|
join(host.appRoot, TS_CONFIG_GLOB_NAME),
|
|
161
170
|
]);
|
|
162
171
|
const tsconfigPaths = await resolveTsConfigWatchPaths(host.appRoot);
|
|
172
|
+
for (const envFilePath of getDevelopmentEnvironmentFilePaths(host.appRoot)) {
|
|
173
|
+
watchPaths.add(envFilePath);
|
|
174
|
+
}
|
|
163
175
|
for (const path of tsconfigPaths) {
|
|
164
176
|
watchPaths.add(path);
|
|
165
177
|
}
|
|
@@ -202,6 +214,10 @@ function syncWatcherPaths(input) {
|
|
|
202
214
|
function toWatchPathKey(path) {
|
|
203
215
|
return path.replaceAll("\\", "/");
|
|
204
216
|
}
|
|
217
|
+
function hasDevelopmentEnvironmentFileChange(appRoot, changedPaths) {
|
|
218
|
+
const environmentFilePathKeys = new Set(getDevelopmentEnvironmentFilePaths(appRoot).map((path) => toWatchPathKey(resolve(path))));
|
|
219
|
+
return changedPaths.some((path) => environmentFilePathKeys.has(toWatchPathKey(resolve(path))));
|
|
220
|
+
}
|
|
205
221
|
function resolveLockfileSearchDirectories(appRoot) {
|
|
206
222
|
const directories = [];
|
|
207
223
|
let currentDirectory = resolve(appRoot);
|
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
import type { Nitro } from "nitro/types";
|
|
2
2
|
import { type ScheduleRegistration } from "#runtime/schedules/register.js";
|
|
3
3
|
import type { NitroArtifactsConfigInput } from "#internal/nitro/host/artifacts-config.js";
|
|
4
|
+
interface ScheduleTaskNitro {
|
|
5
|
+
options: Pick<Nitro["options"], "experimental" | "scheduledTasks" | "tasks" | "virtual">;
|
|
6
|
+
}
|
|
4
7
|
/**
|
|
5
8
|
* Inputs needed to wire one set of compiled authored schedules into Nitro's
|
|
6
9
|
* task and cron surfaces.
|
|
@@ -39,7 +42,7 @@ export interface SyncScheduleTaskHandlersInput {
|
|
|
39
42
|
* adapts it to Nitro's task contract while baking in the artifacts config so
|
|
40
43
|
* the handler does not depend on a global runtime configuration store.
|
|
41
44
|
*/
|
|
42
|
-
export declare function registerScheduleTaskHandlers(nitro:
|
|
45
|
+
export declare function registerScheduleTaskHandlers(nitro: ScheduleTaskNitro, input: RegisterScheduleTaskHandlersInput): void;
|
|
43
46
|
/**
|
|
44
47
|
* Replaces the currently-registered Ash schedule task handlers when the
|
|
45
48
|
* compiled authored schedule set changes.
|
|
@@ -47,10 +50,11 @@ export declare function registerScheduleTaskHandlers(nitro: Nitro, input: Regist
|
|
|
47
50
|
* Returns `true` when the registration set changed (and the caller should
|
|
48
51
|
* trigger a Nitro rebuild reload), `false` when it was a structural no-op.
|
|
49
52
|
*/
|
|
50
|
-
export declare function syncScheduleTaskHandlers(nitro:
|
|
53
|
+
export declare function syncScheduleTaskHandlers(nitro: ScheduleTaskNitro, input: SyncScheduleTaskHandlersInput): boolean;
|
|
51
54
|
/**
|
|
52
55
|
* Removes every Ash-owned schedule task entry, virtual handler module, and
|
|
53
56
|
* cron entry from the Nitro options. Used by the dev watcher before
|
|
54
57
|
* re-registering the latest compiled set.
|
|
55
58
|
*/
|
|
56
|
-
export declare function removeScheduleTaskHandlers(nitro:
|
|
59
|
+
export declare function removeScheduleTaskHandlers(nitro: ScheduleTaskNitro): void;
|
|
60
|
+
export {};
|
|
@@ -2,6 +2,7 @@ import { build as buildNitro, createDevServer, prepare } from "nitro/builder";
|
|
|
2
2
|
import { createApplicationNitro } from "#internal/nitro/host/create-application-nitro.js";
|
|
3
3
|
import { prepareApplicationHost } from "#internal/nitro/host/prepare-application-host.js";
|
|
4
4
|
import { prewarmAppSandboxes } from "#execution/sandbox/prewarm.js";
|
|
5
|
+
import { loadDevelopmentEnvironmentFiles } from "#cli/dev/environment.js";
|
|
5
6
|
const DEFAULT_DEVELOPMENT_SERVER_PORT = 3000;
|
|
6
7
|
const MAX_ALLOWED_DEVELOPMENT_SERVER_PORT = 65_535;
|
|
7
8
|
const MAX_DEVELOPMENT_SERVER_PORT_ATTEMPTS = 10;
|
|
@@ -160,6 +161,7 @@ async function listenForDevelopmentServer(input) {
|
|
|
160
161
|
*/
|
|
161
162
|
export async function startDevelopmentServer(rootDir, options = {}) {
|
|
162
163
|
const schedulesEnabled = options.schedules === true;
|
|
164
|
+
loadDevelopmentEnvironmentFiles(rootDir);
|
|
163
165
|
const preparedHost = await prepareApplicationHost(rootDir);
|
|
164
166
|
await prewarmAppSandboxes({
|
|
165
167
|
appRoot: preparedHost.appRoot,
|
|
@@ -372,37 +372,5 @@ function isJavaScriptLikePath(path) {
|
|
|
372
372
|
export async function atomicWriteFile(targetPath, contents) {
|
|
373
373
|
const tmpPath = `${targetPath}.tmp-${process.pid}-${Date.now().toString(36)}`;
|
|
374
374
|
await writeFile(tmpPath, contents);
|
|
375
|
-
await
|
|
376
|
-
}
|
|
377
|
-
/*
|
|
378
|
-
* POSIX `rename` always succeeds when the target is open, but Windows
|
|
379
|
-
* `MoveFileEx` rejects the call with EPERM/EACCES if any handle to the
|
|
380
|
-
* target lacks FILE_SHARE_DELETE. Node's `fs.readFile` does not request
|
|
381
|
-
* that share mode, so a concurrent reader (e.g. Nitro's Rolldown bundler
|
|
382
|
-
* during `ash dev`) racing with this rename will trip the error even
|
|
383
|
-
* though its open-read-close cycle releases the handle moments later.
|
|
384
|
-
* Retrying with backoff lands the rename in one of those gaps and keeps
|
|
385
|
-
* the atomic guarantee intact on Windows. POSIX skips the loop.
|
|
386
|
-
*/
|
|
387
|
-
async function renameWithWindowsRetry(source, target) {
|
|
388
|
-
if (process.platform !== "win32") {
|
|
389
|
-
await rename(source, target);
|
|
390
|
-
return;
|
|
391
|
-
}
|
|
392
|
-
const maxAttempts = 10;
|
|
393
|
-
for (let attempt = 0; attempt < maxAttempts; attempt += 1) {
|
|
394
|
-
try {
|
|
395
|
-
await rename(source, target);
|
|
396
|
-
return;
|
|
397
|
-
}
|
|
398
|
-
catch (error) {
|
|
399
|
-
const isContended = error instanceof Error &&
|
|
400
|
-
"code" in error &&
|
|
401
|
-
(error.code === "EPERM" || error.code === "EACCES" || error.code === "EBUSY");
|
|
402
|
-
if (!isContended || attempt === maxAttempts - 1) {
|
|
403
|
-
throw error;
|
|
404
|
-
}
|
|
405
|
-
await new Promise((resolve) => setTimeout(resolve, 10 * (attempt + 1)));
|
|
406
|
-
}
|
|
407
|
-
}
|
|
375
|
+
await rename(tmpPath, targetPath);
|
|
408
376
|
}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import type { TokenValue } from "#client/types.js";
|
|
2
|
+
/**
|
|
3
|
+
* Outbound request auth hook used by remote agent dispatch.
|
|
4
|
+
*/
|
|
5
|
+
export type OutboundAuthFn = () => Promise<{
|
|
6
|
+
readonly headers: Readonly<Record<string, string>>;
|
|
7
|
+
}>;
|
|
8
|
+
/**
|
|
9
|
+
* Ash-owned subset of `@vercel/oidc` token lookup options.
|
|
10
|
+
*/
|
|
11
|
+
export interface VercelOidcOptions {
|
|
12
|
+
readonly expirationBufferMs?: number;
|
|
13
|
+
readonly project?: string;
|
|
14
|
+
readonly team?: string;
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Returns a Vercel OIDC bearer token for an outbound remote-agent request.
|
|
18
|
+
*/
|
|
19
|
+
export declare function vercelOidc(options?: VercelOidcOptions): OutboundAuthFn;
|
|
20
|
+
/**
|
|
21
|
+
* Returns a static or lazily resolved bearer token auth hook.
|
|
22
|
+
*/
|
|
23
|
+
export declare function bearer(token: TokenValue): OutboundAuthFn;
|
|
24
|
+
/**
|
|
25
|
+
* Returns an HTTP Basic auth hook.
|
|
26
|
+
*/
|
|
27
|
+
export declare function basic(input: {
|
|
28
|
+
readonly password: TokenValue;
|
|
29
|
+
readonly username: string;
|
|
30
|
+
}): OutboundAuthFn;
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { getVercelOidcToken } from "@vercel/oidc";
|
|
2
|
+
/**
|
|
3
|
+
* Returns a Vercel OIDC bearer token for an outbound remote-agent request.
|
|
4
|
+
*/
|
|
5
|
+
export function vercelOidc(options = {}) {
|
|
6
|
+
return async () => ({
|
|
7
|
+
headers: {
|
|
8
|
+
authorization: `Bearer ${await getVercelOidcToken(options)}`,
|
|
9
|
+
},
|
|
10
|
+
});
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Returns a static or lazily resolved bearer token auth hook.
|
|
14
|
+
*/
|
|
15
|
+
export function bearer(token) {
|
|
16
|
+
return async () => ({
|
|
17
|
+
headers: {
|
|
18
|
+
authorization: `Bearer ${await resolveTokenValue(token)}`,
|
|
19
|
+
},
|
|
20
|
+
});
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Returns an HTTP Basic auth hook.
|
|
24
|
+
*/
|
|
25
|
+
export function basic(input) {
|
|
26
|
+
return async () => {
|
|
27
|
+
const encodedCredentials = btoa(`${input.username}:${await resolveTokenValue(input.password)}`);
|
|
28
|
+
return {
|
|
29
|
+
headers: {
|
|
30
|
+
authorization: `Basic ${encodedCredentials}`,
|
|
31
|
+
},
|
|
32
|
+
};
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
async function resolveTokenValue(value) {
|
|
36
|
+
return typeof value === "function" ? await value() : value;
|
|
37
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import type { HeadersValue } from "#client/types.js";
|
|
2
|
+
import type { OutboundAuthFn } from "#public/agents/auth.js";
|
|
3
|
+
/**
|
|
4
|
+
* Public definition for a remote Ash agent lowered as a subagent tool.
|
|
5
|
+
*/
|
|
6
|
+
export interface RemoteAgentDefinition {
|
|
7
|
+
readonly auth?: OutboundAuthFn;
|
|
8
|
+
readonly description: string;
|
|
9
|
+
readonly headers?: HeadersValue;
|
|
10
|
+
readonly kind: "remote";
|
|
11
|
+
readonly path: string;
|
|
12
|
+
readonly url: string;
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Authored input accepted by {@link defineRemoteAgent}. Identity is derived
|
|
16
|
+
* from the file path under `agent/subagents/`; authored definitions do not
|
|
17
|
+
* carry a `name` field.
|
|
18
|
+
*/
|
|
19
|
+
export type RemoteAgentDefinitionInput = Omit<RemoteAgentDefinition, "kind" | "path"> & {
|
|
20
|
+
readonly path?: string;
|
|
21
|
+
};
|
|
22
|
+
/**
|
|
23
|
+
* Defines a remote Ash agent that the parent can call as a subagent tool.
|
|
24
|
+
*/
|
|
25
|
+
export declare function defineRemoteAgent(input: RemoteAgentDefinitionInput): RemoteAgentDefinition;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { ASH_CREATE_SESSION_ROUTE_PATH } from "#protocol/routes.js";
|
|
2
|
+
/**
|
|
3
|
+
* Defines a remote Ash agent that the parent can call as a subagent tool.
|
|
4
|
+
*/
|
|
5
|
+
export function defineRemoteAgent(input) {
|
|
6
|
+
return {
|
|
7
|
+
...input,
|
|
8
|
+
kind: "remote",
|
|
9
|
+
path: input.path ?? ASH_CREATE_SESSION_ROUTE_PATH,
|
|
10
|
+
};
|
|
11
|
+
}
|
|
@@ -2,3 +2,4 @@
|
|
|
2
2
|
* Core agent authoring helpers for `agent/agent.ts`.
|
|
3
3
|
*/
|
|
4
4
|
export { type AgentCompactionDefinition, type AgentDefinition, type AgentModelDefinition, type AgentModelOptionsDefinition, defineAgent, } from "#public/definitions/agent.js";
|
|
5
|
+
export { type RemoteAgentDefinition, type RemoteAgentDefinitionInput, defineRemoteAgent, } from "#public/definitions/remote-agent.js";
|
package/dist/src/public/index.js
CHANGED
|
@@ -72,10 +72,10 @@ export interface WithAshOptions {
|
|
|
72
72
|
* In development, `withAsh` starts `ash dev --no-repl --port 0` for the Ash
|
|
73
73
|
* app and rewrites Ash protocol endpoints to that local URL. In production on
|
|
74
74
|
* Vercel, it rewrites to the private Ash service prefix configured in
|
|
75
|
-
* `vercel.json
|
|
76
|
-
*
|
|
77
|
-
*
|
|
78
|
-
*
|
|
75
|
+
* `vercel.json`. Outside Vercel production, it serves an existing
|
|
76
|
+
* `.output/server/index.mjs` Ash build on a stable local port when present;
|
|
77
|
+
* otherwise set `ASH_NEXT_PRODUCTION_ORIGIN` to the origin that serves the Ash
|
|
78
|
+
* service namespace.
|
|
79
79
|
*/
|
|
80
80
|
export declare function withAsh<TConfig extends AshNextConfig>(configOrFunction: AshNextConfigInput<TConfig>, options?: WithAshOptions): AshNextConfigFunction<TConfig>;
|
|
81
81
|
export {};
|
|
@@ -32,16 +32,6 @@ function joinRoutePrefix(prefix, path) {
|
|
|
32
32
|
function normalizeOrigin(origin) {
|
|
33
33
|
return new URL(origin.trim()).origin;
|
|
34
34
|
}
|
|
35
|
-
function hasUrlScheme(value) {
|
|
36
|
-
return /^[a-z][a-z\d+.-]*:/i.test(value);
|
|
37
|
-
}
|
|
38
|
-
function resolveVercelDeploymentOrigin() {
|
|
39
|
-
const deploymentUrl = process.env.VERCEL_URL;
|
|
40
|
-
if (deploymentUrl === undefined || deploymentUrl.trim().length === 0) {
|
|
41
|
-
return undefined;
|
|
42
|
-
}
|
|
43
|
-
return normalizeOrigin(hasUrlScheme(deploymentUrl) ? deploymentUrl : `https://${deploymentUrl}`);
|
|
44
|
-
}
|
|
45
35
|
function readLocalProductionPort() {
|
|
46
36
|
const configuredPort = process.env[ASH_NEXT_PRODUCTION_PORT_ENV];
|
|
47
37
|
if (configuredPort === undefined || configuredPort.trim().length === 0) {
|
|
@@ -54,16 +44,15 @@ function readLocalProductionPort() {
|
|
|
54
44
|
return port;
|
|
55
45
|
}
|
|
56
46
|
function resolveProductionDestination(servicePrefix) {
|
|
57
|
-
|
|
58
|
-
if (configuredOrigin !== undefined && configuredOrigin.trim().length > 0) {
|
|
47
|
+
if (process.env.VERCEL) {
|
|
59
48
|
return {
|
|
60
|
-
destinationPrefix:
|
|
49
|
+
destinationPrefix: servicePrefix,
|
|
61
50
|
};
|
|
62
51
|
}
|
|
63
|
-
const
|
|
64
|
-
if (
|
|
52
|
+
const configuredOrigin = process.env[ASH_NEXT_PRODUCTION_ORIGIN_ENV];
|
|
53
|
+
if (configuredOrigin !== undefined && configuredOrigin.trim().length > 0) {
|
|
65
54
|
return {
|
|
66
|
-
destinationPrefix: joinRoutePrefix(
|
|
55
|
+
destinationPrefix: joinRoutePrefix(normalizeOrigin(configuredOrigin), servicePrefix),
|
|
67
56
|
};
|
|
68
57
|
}
|
|
69
58
|
const localServerOrigin = `http://127.0.0.1:${String(readLocalProductionPort())}`;
|
|
@@ -73,11 +62,13 @@ function resolveProductionDestination(servicePrefix) {
|
|
|
73
62
|
};
|
|
74
63
|
}
|
|
75
64
|
function createAshRewriteRules(destinationPrefix) {
|
|
76
|
-
return ASH_PROXY_REWRITE_SOURCES.map((source) =>
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
65
|
+
return ASH_PROXY_REWRITE_SOURCES.map((source) => {
|
|
66
|
+
const rule = {
|
|
67
|
+
destination: joinRoutePrefix(destinationPrefix, source),
|
|
68
|
+
source,
|
|
69
|
+
};
|
|
70
|
+
return rule;
|
|
71
|
+
});
|
|
81
72
|
}
|
|
82
73
|
async function resolveExistingRewrites(rewrites) {
|
|
83
74
|
return await rewrites?.();
|
|
@@ -114,10 +105,10 @@ async function resolveNextConfig(configOrFunction, phase, context) {
|
|
|
114
105
|
* In development, `withAsh` starts `ash dev --no-repl --port 0` for the Ash
|
|
115
106
|
* app and rewrites Ash protocol endpoints to that local URL. In production on
|
|
116
107
|
* Vercel, it rewrites to the private Ash service prefix configured in
|
|
117
|
-
* `vercel.json
|
|
118
|
-
*
|
|
119
|
-
*
|
|
120
|
-
*
|
|
108
|
+
* `vercel.json`. Outside Vercel production, it serves an existing
|
|
109
|
+
* `.output/server/index.mjs` Ash build on a stable local port when present;
|
|
110
|
+
* otherwise set `ASH_NEXT_PRODUCTION_ORIGIN` to the origin that serves the Ash
|
|
111
|
+
* service namespace.
|
|
121
112
|
*/
|
|
122
113
|
export function withAsh(configOrFunction, options = {}) {
|
|
123
114
|
const nextRoot = process.cwd();
|