@pulse-compute/provider-fastly 0.0.0 → 1.0.0-beta.1
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 +52 -1
- package/dist/config-schema.json +73 -0
- package/dist/index.d.ts +61 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +59 -0
- package/dist/index.js.map +1 -0
- package/package.json +87 -5
- package/src/build/canonical-target.js +436 -0
- package/src/build/entities-native.js +564 -0
- package/src/build/fixed-memory-runtime.as.ts +148 -0
- package/src/build/native-http-effects.js +871 -0
- package/src/build/native-http-shell.js +703 -0
- package/src/build/native-platform-capabilities.js +2109 -0
- package/src/compiler/assets-package-out-parity-proof.js +338 -0
- package/src/compiler/assets-provider-proof.js +499 -0
- package/src/compiler/config-provider-resolution.js +573 -0
- package/src/compiler/fastly-adapter.js +564 -0
- package/src/compiler/fastly-command-entry.js +390 -0
- package/src/compiler/fastly-config-secret-serve.js +323 -0
- package/src/compiler/fastly-hostcall-binding.js +598 -0
- package/src/compiler/fastly-readiness.js +477 -0
- package/src/compiler/index.js +40 -0
- package/src/compiler/lifecycle-parity-contract.js +70 -0
- package/src/compiler/lifecycle-parity-proof.js +260 -0
- package/src/compiler/route-handler-effect-proof.js +255 -0
- package/src/compiler/runtime-provider-kv.js +237 -0
- package/src/compiler/runtime-provider-shape.js +109 -0
- package/src/config-api.js +63 -0
- package/src/config-schema.d.ts +13 -0
- package/src/config-schema.js +27 -0
- package/src/config-schema.json +73 -0
- package/src/index.js +3 -0
- package/src/index.ts +118 -0
- package/src/javascript/assets-adapter.js +122 -0
- package/src/javascript/bindings-adapter.js +237 -0
- package/src/javascript/errors.js +26 -0
- package/src/javascript/fetch-adapter.js +93 -0
- package/src/javascript/grip-broadcast.js +261 -0
- package/src/javascript/jwt-verifier.js +137 -0
- package/src/javascript/lifecycle.js +55 -0
- package/src/javascript/local-loader.js +138 -0
- package/src/javascript/logging.js +26 -0
- package/src/javascript/package-effects.js +68 -0
- package/src/javascript/runtime-host.js +108 -0
- package/src/javascript/sha256.js +128 -0
- package/src/javascript/source-package.js +776 -0
- package/src/javascript/support.js +142 -0
- package/src/javascript/target-support-policy.js +260 -0
- package/src/javascript/target.js +73 -0
- package/src/javascript/test-runtime.js +407 -0
- package/src/provider-contract.js +72 -0
- package/src/runtime/assets-provider.js +464 -0
- package/src/runtime/canonical-api-runtime.js +597 -0
- package/src/runtime/index.js +28 -0
- package/src/runtime/provider-primitives-contract.js +272 -0
- package/src/runtime/provider-primitives.js +82 -0
- package/src/runtime/route-handler-effects.js +507 -0
- package/src/testing/fastly-cli.js +538 -0
- package/src/testing/native-http-effects-host.js +390 -0
- package/src/testing/native-http-shell-host.js +190 -0
- package/src/testing/native-platform-capabilities-host.js +599 -0
- package/src/toolchain/config.js +128 -0
- package/src/toolchain/index.js +343 -0
|
@@ -0,0 +1,776 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const crypto = require('node:crypto');
|
|
4
|
+
const fs = require('node:fs');
|
|
5
|
+
const path = require('node:path');
|
|
6
|
+
const { reportingDescriptor } = require('@pulse-compute/wasm-contracts/logging');
|
|
7
|
+
const { FASTLY_JAVASCRIPT_TARGET_DESCRIPTOR } = require('./target.js');
|
|
8
|
+
|
|
9
|
+
const FASTLY_JAVASCRIPT_SOURCE_PACKAGE_VERSION = 'pulse.fastly-javascript-source-package.v1';
|
|
10
|
+
const FASTLY_JAVASCRIPT_SOURCE_PACKAGE_MANIFEST = 'pulse-fastly-javascript-source-package.json';
|
|
11
|
+
const FASTLY_JAVASCRIPT_DEPLOYMENT_MANIFEST = 'pulse-fastly-javascript-deployment.json';
|
|
12
|
+
const FASTLY_JAVASCRIPT_DEPLOYMENT_CANDIDATE_VERSION = 'pulse.fastly-javascript-deployment-candidate.v1';
|
|
13
|
+
const FASTLY_JAVASCRIPT_DEPLOYMENT_CANDIDATE = 'pulse-fastly-javascript-candidate.json';
|
|
14
|
+
const FASTLY_JS_COMPUTE_VERSION = '3.43.1';
|
|
15
|
+
const ESBUILD_VERSION = '0.28.1';
|
|
16
|
+
|
|
17
|
+
class PulseFastlyJavascriptSourcePackageError extends Error {
|
|
18
|
+
constructor(code, message, detail = {}) {
|
|
19
|
+
super(message);
|
|
20
|
+
this.name = 'PulseFastlyJavascriptSourcePackageError';
|
|
21
|
+
this.code = code;
|
|
22
|
+
this.detail = Object.freeze({ ...detail });
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
function slash(value) {
|
|
27
|
+
return String(value).replace(/\\/g, '/');
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
function stableJson(value) {
|
|
31
|
+
return `${JSON.stringify(value, null, 2)}\n`;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
function sha256(value) {
|
|
35
|
+
return crypto.createHash('sha256').update(value).digest('hex');
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
function assertInside(root, candidate, label) {
|
|
39
|
+
const relative = path.relative(path.resolve(root), path.resolve(candidate));
|
|
40
|
+
if (relative === '' || (!relative.startsWith('..') && !path.isAbsolute(relative))) return;
|
|
41
|
+
throw new PulseFastlyJavascriptSourcePackageError(
|
|
42
|
+
'PULSE_FASTLY_JAVASCRIPT_PACKAGE_PATH_UNSAFE',
|
|
43
|
+
`${label} escapes the Pulse project root.`,
|
|
44
|
+
{ root: path.resolve(root), candidate: path.resolve(candidate) }
|
|
45
|
+
);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
function writeFile(root, relativeFile, content) {
|
|
49
|
+
const file = path.join(root, relativeFile);
|
|
50
|
+
assertInside(root, file, `Output file ${relativeFile}`);
|
|
51
|
+
fs.mkdirSync(path.dirname(file), { recursive: true });
|
|
52
|
+
fs.writeFileSync(file, content);
|
|
53
|
+
const bytes = fs.readFileSync(file);
|
|
54
|
+
return Object.freeze({
|
|
55
|
+
file: slash(relativeFile),
|
|
56
|
+
bytes: bytes.byteLength,
|
|
57
|
+
sha256: sha256(bytes)
|
|
58
|
+
});
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
function packageName(input) {
|
|
62
|
+
const normalized = String(input || 'pulse-app')
|
|
63
|
+
.toLowerCase()
|
|
64
|
+
.replace(/^@/, '')
|
|
65
|
+
.replace(/[^a-z0-9._-]+/g, '-')
|
|
66
|
+
.replace(/^-+|-+$/g, '') || 'pulse-app';
|
|
67
|
+
return `pulse-fastly-${normalized}`;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
function tomlString(value) {
|
|
71
|
+
return JSON.stringify(String(value));
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
function fastlyToml(providerConfig = {}) {
|
|
75
|
+
const build = providerConfig.build || {};
|
|
76
|
+
const authors = Array.isArray(build.authors) ? build.authors.map(String) : [];
|
|
77
|
+
return [
|
|
78
|
+
'manifest_version = 3',
|
|
79
|
+
`name = ${tomlString(build.name || 'pulse-app')}`,
|
|
80
|
+
`description = ${tomlString(build.description || 'Pulse application')}`,
|
|
81
|
+
`authors = [${authors.map(tomlString).join(', ')}]`,
|
|
82
|
+
'language = "javascript"',
|
|
83
|
+
'',
|
|
84
|
+
'[scripts]',
|
|
85
|
+
'build = "npm run build"',
|
|
86
|
+
''
|
|
87
|
+
].join('\n');
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
function downstreamEsbuildConfig() {
|
|
91
|
+
return [
|
|
92
|
+
"import { build } from 'esbuild';",
|
|
93
|
+
'',
|
|
94
|
+
'await build({',
|
|
95
|
+
" entryPoints: ['src/index.js'],",
|
|
96
|
+
" outfile: 'dist/index.js',",
|
|
97
|
+
' bundle: true,',
|
|
98
|
+
" format: 'esm',",
|
|
99
|
+
" platform: 'neutral',",
|
|
100
|
+
" target: ['es2022'],",
|
|
101
|
+
" conditions: ['fastly', 'module', 'import', 'default'],",
|
|
102
|
+
" external: ['fastly:*'],",
|
|
103
|
+
" legalComments: 'none',",
|
|
104
|
+
' sourcemap: false,',
|
|
105
|
+
" logLevel: 'info'",
|
|
106
|
+
'});',
|
|
107
|
+
''
|
|
108
|
+
].join('\n');
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
function abortControllerCompatibilitySource() {
|
|
112
|
+
return [
|
|
113
|
+
"if (typeof globalThis.AbortController !== 'function') {",
|
|
114
|
+
' class PulseFastlyAbortSignal {',
|
|
115
|
+
' constructor() {',
|
|
116
|
+
' this.aborted = false;',
|
|
117
|
+
' this.reason = undefined;',
|
|
118
|
+
' this.onabort = null;',
|
|
119
|
+
' this.listeners = [];',
|
|
120
|
+
' }',
|
|
121
|
+
' addEventListener(type, listener, options = undefined) {',
|
|
122
|
+
" if (type !== 'abort' || (typeof listener !== 'function' && !(listener && typeof listener.handleEvent === 'function'))) return;",
|
|
123
|
+
' if (this.listeners.some((entry) => entry.listener === listener)) return;',
|
|
124
|
+
' this.listeners.push({ listener, once: Boolean(options && options.once) });',
|
|
125
|
+
' }',
|
|
126
|
+
' removeEventListener(type, listener) {',
|
|
127
|
+
" if (type !== 'abort') return;",
|
|
128
|
+
' this.listeners = this.listeners.filter((entry) => entry.listener !== listener);',
|
|
129
|
+
' }',
|
|
130
|
+
' dispatchAbort(reason) {',
|
|
131
|
+
' if (this.aborted) return;',
|
|
132
|
+
' this.aborted = true;',
|
|
133
|
+
' this.reason = reason;',
|
|
134
|
+
" const event = Object.freeze({ type: 'abort', target: this, currentTarget: this });",
|
|
135
|
+
' const snapshot = [...this.listeners];',
|
|
136
|
+
' for (const entry of snapshot) {',
|
|
137
|
+
' if (entry.once) this.removeEventListener(\'abort\', entry.listener);',
|
|
138
|
+
' if (typeof entry.listener === \'function\') entry.listener.call(this, event);',
|
|
139
|
+
' else entry.listener.handleEvent(event);',
|
|
140
|
+
' }',
|
|
141
|
+
" if (typeof this.onabort === 'function') this.onabort.call(this, event);",
|
|
142
|
+
' }',
|
|
143
|
+
' }',
|
|
144
|
+
' class PulseFastlyAbortController {',
|
|
145
|
+
' constructor() { this.signal = new PulseFastlyAbortSignal(); }',
|
|
146
|
+
" abort(reason = new Error('This operation was aborted')) { this.signal.dispatchAbort(reason); }",
|
|
147
|
+
' }',
|
|
148
|
+
" Object.defineProperty(globalThis, 'AbortController', { configurable: true, writable: true, value: PulseFastlyAbortController });",
|
|
149
|
+
'}',
|
|
150
|
+
].join('\n');
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
function bootstrapSource(deployment, runtimeConfig) {
|
|
154
|
+
return [
|
|
155
|
+
"import { enforceExplicitBackends } from 'fastly:backend';",
|
|
156
|
+
"import { ConfigStore } from 'fastly:config-store';",
|
|
157
|
+
"import { KVStore } from 'fastly:kv-store';",
|
|
158
|
+
"import { SecretStore } from 'fastly:secret-store';",
|
|
159
|
+
"import application, { createFastlyJavascriptHandler, schemaCodecs } from './application.js';",
|
|
160
|
+
'',
|
|
161
|
+
abortControllerCompatibilitySource(),
|
|
162
|
+
'',
|
|
163
|
+
`export const pulseDeployment = Object.freeze(${JSON.stringify(deployment)});`,
|
|
164
|
+
`export const pulseRuntimeConfig = Object.freeze(${JSON.stringify(runtimeConfig)});`,
|
|
165
|
+
'if (pulseRuntimeConfig.bindings.dynamicBackends !== true) enforceExplicitBackends();',
|
|
166
|
+
'export const handler = createFastlyJavascriptHandler(application, {',
|
|
167
|
+
' ...pulseRuntimeConfig,',
|
|
168
|
+
' apis: { ConfigStore, SecretStore, KVStore },',
|
|
169
|
+
' fetchImplementation: globalThis.fetch.bind(globalThis),',
|
|
170
|
+
' console: globalThis.console,',
|
|
171
|
+
' schemaCodecs',
|
|
172
|
+
'});',
|
|
173
|
+
"addEventListener('fetch', (event) => event.respondWith(handler(event)));",
|
|
174
|
+
'export { application, schemaCodecs };',
|
|
175
|
+
'export default handler;',
|
|
176
|
+
''
|
|
177
|
+
].join('\n');
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
function normalizedInputPath(input, projectRoot) {
|
|
181
|
+
const absolute = path.isAbsolute(input) ? input : path.resolve(projectRoot, input);
|
|
182
|
+
const relative = path.relative(projectRoot, absolute);
|
|
183
|
+
return slash(relative || '.');
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
function workspacePatterns(manifest) {
|
|
187
|
+
if (!manifest) return [];
|
|
188
|
+
if (Array.isArray(manifest.workspaces)) return manifest.workspaces;
|
|
189
|
+
if (manifest.workspaces && Array.isArray(manifest.workspaces.packages)) return manifest.workspaces.packages;
|
|
190
|
+
return [];
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
function expandWorkspacePattern(root, pattern) {
|
|
194
|
+
const segments = slash(pattern).split('/').filter(Boolean);
|
|
195
|
+
let candidates = [root];
|
|
196
|
+
for (const segment of segments) {
|
|
197
|
+
const next = [];
|
|
198
|
+
for (const candidate of candidates) {
|
|
199
|
+
if (segment === '*') {
|
|
200
|
+
if (!fs.existsSync(candidate) || !fs.statSync(candidate).isDirectory()) continue;
|
|
201
|
+
for (const entry of fs.readdirSync(candidate, { withFileTypes: true })) {
|
|
202
|
+
if (entry.isDirectory() && entry.name !== 'node_modules' && !entry.name.startsWith('.')) {
|
|
203
|
+
next.push(path.join(candidate, entry.name));
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
} else if (!segment.includes('*')) {
|
|
207
|
+
next.push(path.join(candidate, segment));
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
candidates = next;
|
|
211
|
+
}
|
|
212
|
+
return candidates;
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
function workspacePackages(projectRoot) {
|
|
216
|
+
let current = path.resolve(projectRoot);
|
|
217
|
+
const filesystemRoot = path.parse(current).root;
|
|
218
|
+
while (true) {
|
|
219
|
+
const manifestFile = path.join(current, 'package.json');
|
|
220
|
+
if (fs.existsSync(manifestFile)) {
|
|
221
|
+
let manifest;
|
|
222
|
+
try { manifest = JSON.parse(fs.readFileSync(manifestFile, 'utf8')); }
|
|
223
|
+
catch (_) { manifest = null; }
|
|
224
|
+
const patterns = workspacePatterns(manifest);
|
|
225
|
+
if (patterns.length > 0) {
|
|
226
|
+
const packages = new Map();
|
|
227
|
+
for (const pattern of patterns) {
|
|
228
|
+
for (const root of expandWorkspacePattern(current, pattern)) {
|
|
229
|
+
const packageFile = path.join(root, 'package.json');
|
|
230
|
+
if (!fs.existsSync(packageFile)) continue;
|
|
231
|
+
try {
|
|
232
|
+
const packageManifest = JSON.parse(fs.readFileSync(packageFile, 'utf8'));
|
|
233
|
+
if (packageManifest && typeof packageManifest.name === 'string') {
|
|
234
|
+
packages.set(packageManifest.name, Object.freeze({ root, manifest: packageManifest }));
|
|
235
|
+
}
|
|
236
|
+
} catch (_) {
|
|
237
|
+
// Invalid package manifests are owned by workspace validation.
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
return packages;
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
if (current === filesystemRoot) break;
|
|
245
|
+
current = path.dirname(current);
|
|
246
|
+
}
|
|
247
|
+
return new Map();
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
function conditionalExportTarget(value) {
|
|
251
|
+
if (typeof value === 'string') return value;
|
|
252
|
+
if (!value || typeof value !== 'object' || Array.isArray(value)) return null;
|
|
253
|
+
for (const condition of ['fastly', 'import', 'module', 'require', 'default']) {
|
|
254
|
+
const target = conditionalExportTarget(value[condition]);
|
|
255
|
+
if (target) return target;
|
|
256
|
+
}
|
|
257
|
+
return null;
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
function workspacePackageAliases(projectRoot) {
|
|
261
|
+
const packages = workspacePackages(projectRoot);
|
|
262
|
+
const aliases = {};
|
|
263
|
+
for (const [name, entry] of packages) {
|
|
264
|
+
const exports = entry.manifest.exports;
|
|
265
|
+
if (exports && typeof exports === 'object' && !Array.isArray(exports)) {
|
|
266
|
+
for (const [subpath, value] of Object.entries(exports)) {
|
|
267
|
+
if (subpath !== '.' && !subpath.startsWith('./')) continue;
|
|
268
|
+
const target = conditionalExportTarget(value);
|
|
269
|
+
if (!target) continue;
|
|
270
|
+
const specifier = subpath === '.' ? name : `${name}/${subpath.slice(2)}`;
|
|
271
|
+
aliases[specifier] = path.resolve(entry.root, target);
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
if (!aliases[name]) {
|
|
275
|
+
const target = entry.manifest.module || entry.manifest.main;
|
|
276
|
+
if (target) aliases[name] = path.resolve(entry.root, target);
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
return Object.freeze(aliases);
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
function relativeImport(projectRoot, file) {
|
|
283
|
+
const relative = slash(path.relative(projectRoot, file));
|
|
284
|
+
return relative.startsWith('.') ? relative : `./${relative}`;
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
function bundleFastlyJavascriptApplication(plan, projectRoot, schemaBundle, options = {}) {
|
|
288
|
+
const format = options.format === 'cjs' ? 'cjs' : 'esm';
|
|
289
|
+
const external = [
|
|
290
|
+
'fastly:*',
|
|
291
|
+
...(options.externalRuntime === true
|
|
292
|
+
? ['@pulse-compute/runtime', '@pulse-compute/runtime/*']
|
|
293
|
+
: [])
|
|
294
|
+
];
|
|
295
|
+
let esbuild;
|
|
296
|
+
try { esbuild = require('esbuild'); }
|
|
297
|
+
catch (error) {
|
|
298
|
+
throw new PulseFastlyJavascriptSourcePackageError(
|
|
299
|
+
'PULSE_FASTLY_JAVASCRIPT_ESBUILD_MISSING',
|
|
300
|
+
`Fastly JavaScript source packaging requires exact esbuild ${ESBUILD_VERSION}.`,
|
|
301
|
+
{ package: 'esbuild', version: ESBUILD_VERSION, cause: error && error.message }
|
|
302
|
+
);
|
|
303
|
+
}
|
|
304
|
+
if (esbuild.version !== ESBUILD_VERSION) {
|
|
305
|
+
throw new PulseFastlyJavascriptSourcePackageError(
|
|
306
|
+
'PULSE_FASTLY_JAVASCRIPT_ESBUILD_VERSION_MISMATCH',
|
|
307
|
+
`Fastly JavaScript source packaging requires exact esbuild ${ESBUILD_VERSION}; received ${String(esbuild.version)}.`,
|
|
308
|
+
{ expected: ESBUILD_VERSION, actual: esbuild.version }
|
|
309
|
+
);
|
|
310
|
+
}
|
|
311
|
+
const entryFile = path.resolve(projectRoot, plan.workspace.entry);
|
|
312
|
+
assertInside(projectRoot, entryFile, 'Fastly JavaScript application entry');
|
|
313
|
+
if (!fs.existsSync(entryFile) || !fs.statSync(entryFile).isFile()) {
|
|
314
|
+
throw new PulseFastlyJavascriptSourcePackageError(
|
|
315
|
+
'PULSE_FASTLY_JAVASCRIPT_ENTRY_MISSING',
|
|
316
|
+
`Fastly JavaScript application entry is missing: ${plan.workspace.entry}.`,
|
|
317
|
+
{ entryFile, entry: plan.workspace.entry }
|
|
318
|
+
);
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
const runtimeFile = path.join(__dirname, 'lifecycle.js');
|
|
322
|
+
const entrySource = [
|
|
323
|
+
`import application from ${JSON.stringify(relativeImport(projectRoot, entryFile))};`,
|
|
324
|
+
`import fastlyRuntime from ${JSON.stringify(relativeImport(projectRoot, runtimeFile))};`,
|
|
325
|
+
...(schemaBundle && schemaBundle.active
|
|
326
|
+
? [
|
|
327
|
+
'const schemaCodecs = (() => {',
|
|
328
|
+
' const module = { exports: {} };',
|
|
329
|
+
schemaBundle.moduleSource,
|
|
330
|
+
' return module.exports;',
|
|
331
|
+
'})();'
|
|
332
|
+
]
|
|
333
|
+
: ['const schemaCodecs = null;']),
|
|
334
|
+
'const { createFastlyJavascriptHandler } = fastlyRuntime;',
|
|
335
|
+
'export { application, createFastlyJavascriptHandler, schemaCodecs };',
|
|
336
|
+
'export default application;',
|
|
337
|
+
''
|
|
338
|
+
].join('\n');
|
|
339
|
+
const workspaceAliases = workspacePackageAliases(projectRoot);
|
|
340
|
+
const aliases = {
|
|
341
|
+
...Object.fromEntries(Object.entries(workspaceAliases).filter(([specifier]) =>
|
|
342
|
+
options.externalRuntime !== true
|
|
343
|
+
|| (specifier !== '@pulse-compute/runtime' && !specifier.startsWith('@pulse-compute/runtime/'))
|
|
344
|
+
)),
|
|
345
|
+
...(schemaBundle && schemaBundle.active
|
|
346
|
+
? { 'node:crypto': path.join(__dirname, 'sha256.js') }
|
|
347
|
+
: {})
|
|
348
|
+
};
|
|
349
|
+
|
|
350
|
+
let result;
|
|
351
|
+
try {
|
|
352
|
+
result = esbuild.buildSync({
|
|
353
|
+
absWorkingDir: projectRoot,
|
|
354
|
+
stdin: {
|
|
355
|
+
contents: entrySource,
|
|
356
|
+
resolveDir: projectRoot,
|
|
357
|
+
sourcefile: 'pulse-fastly-application-entry.js',
|
|
358
|
+
loader: 'js'
|
|
359
|
+
},
|
|
360
|
+
outfile: 'application.js',
|
|
361
|
+
bundle: true,
|
|
362
|
+
write: false,
|
|
363
|
+
metafile: true,
|
|
364
|
+
format,
|
|
365
|
+
platform: 'neutral',
|
|
366
|
+
target: ['es2022'],
|
|
367
|
+
conditions: ['fastly', 'module', 'import', 'default'],
|
|
368
|
+
mainFields: ['module', 'main'],
|
|
369
|
+
packages: 'bundle',
|
|
370
|
+
external,
|
|
371
|
+
legalComments: 'none',
|
|
372
|
+
sourcemap: false,
|
|
373
|
+
charset: 'utf8',
|
|
374
|
+
treeShaking: true,
|
|
375
|
+
logLevel: 'silent',
|
|
376
|
+
alias: aliases
|
|
377
|
+
});
|
|
378
|
+
} catch (error) {
|
|
379
|
+
throw new PulseFastlyJavascriptSourcePackageError(
|
|
380
|
+
'PULSE_FASTLY_JAVASCRIPT_BUNDLE_FAILED',
|
|
381
|
+
'Fastly JavaScript source packaging could not bundle the application closure.',
|
|
382
|
+
{
|
|
383
|
+
entry: plan.workspace.entry,
|
|
384
|
+
errors: Array.isArray(error && error.errors)
|
|
385
|
+
? error.errors.map((entry) => Object.freeze({ text: entry.text, location: entry.location }))
|
|
386
|
+
: [],
|
|
387
|
+
cause: error && error.message
|
|
388
|
+
}
|
|
389
|
+
);
|
|
390
|
+
}
|
|
391
|
+
const output = result.outputFiles && result.outputFiles.find((entry) => entry.path.endsWith('application.js'));
|
|
392
|
+
if (!output) {
|
|
393
|
+
throw new PulseFastlyJavascriptSourcePackageError(
|
|
394
|
+
'PULSE_FASTLY_JAVASCRIPT_BUNDLE_OUTPUT_MISSING',
|
|
395
|
+
'Fastly JavaScript bundling did not produce application.js.'
|
|
396
|
+
);
|
|
397
|
+
}
|
|
398
|
+
const text = output.text;
|
|
399
|
+
const nodeImports = [...text.matchAll(/(?:from\s+|import\s*\()\s*["'](node:[^"']+|(?:fs|path|crypto|module|stream|buffer|util|events))["']/g)]
|
|
400
|
+
.map((match) => match[1]);
|
|
401
|
+
if (nodeImports.length > 0) {
|
|
402
|
+
throw new PulseFastlyJavascriptSourcePackageError(
|
|
403
|
+
'PULSE_FASTLY_JAVASCRIPT_NODE_BUILTIN',
|
|
404
|
+
'Fastly JavaScript source closure contains a Node-only builtin import.',
|
|
405
|
+
{ imports: Object.freeze([...new Set(nodeImports)].sort()) }
|
|
406
|
+
);
|
|
407
|
+
}
|
|
408
|
+
const inputs = Object.freeze(Object.entries(result.metafile.inputs || {})
|
|
409
|
+
.map(([file, metadata]) => Object.freeze({
|
|
410
|
+
file: normalizedInputPath(file, projectRoot),
|
|
411
|
+
bytes: Number(metadata.bytes || 0),
|
|
412
|
+
imports: Object.freeze((metadata.imports || []).map((entry) => Object.freeze({
|
|
413
|
+
path: slash(entry.path),
|
|
414
|
+
kind: entry.kind,
|
|
415
|
+
external: entry.external === true
|
|
416
|
+
})).sort((left, right) => left.path.localeCompare(right.path) || left.kind.localeCompare(right.kind)))
|
|
417
|
+
}))
|
|
418
|
+
.sort((left, right) => left.file.localeCompare(right.file)));
|
|
419
|
+
return Object.freeze({
|
|
420
|
+
format,
|
|
421
|
+
source: text,
|
|
422
|
+
sourceHash: sha256(Buffer.from(text)),
|
|
423
|
+
inputs
|
|
424
|
+
});
|
|
425
|
+
}
|
|
426
|
+
|
|
427
|
+
function assertDeploymentCandidateAgreement(input) {
|
|
428
|
+
const {
|
|
429
|
+
candidate,
|
|
430
|
+
candidateRecord,
|
|
431
|
+
deployment,
|
|
432
|
+
deploymentRecord,
|
|
433
|
+
manifest,
|
|
434
|
+
plan,
|
|
435
|
+
applicationRecord,
|
|
436
|
+
bootstrapRecord,
|
|
437
|
+
packageRecord,
|
|
438
|
+
fastlyRecord
|
|
439
|
+
} = input;
|
|
440
|
+
const mismatches = [];
|
|
441
|
+
const matches = (label, actual, expected) => {
|
|
442
|
+
if (actual !== expected) mismatches.push(Object.freeze({ label, actual, expected }));
|
|
443
|
+
};
|
|
444
|
+
matches('candidate.provider', candidate.provider, manifest.provider);
|
|
445
|
+
matches('candidate.target', candidate.target, manifest.target);
|
|
446
|
+
matches('candidate.targetId', candidate.targetId, manifest.targetId);
|
|
447
|
+
matches('candidate.identity.applicationPlanHash', candidate.identity.applicationPlanHash, plan.planHash);
|
|
448
|
+
matches('candidate.identity.graphHash', candidate.identity.graphHash, plan.graph.graphHash);
|
|
449
|
+
matches('candidate.identity.bundleSha256', candidate.identity.bundleSha256, applicationRecord.sha256);
|
|
450
|
+
matches('candidate.deployment.version', candidate.deployment.version, deployment.version);
|
|
451
|
+
matches('candidate.deployment.manifest', candidate.deployment.manifest, deploymentRecord.file);
|
|
452
|
+
matches('candidate.deployment.sha256', candidate.deployment.sha256, deploymentRecord.sha256);
|
|
453
|
+
matches('candidate.entrypoints.bootstrap', candidate.entrypoints.bootstrap, bootstrapRecord.file);
|
|
454
|
+
matches('candidate.entrypoints.bundledApplication', candidate.entrypoints.bundledApplication, applicationRecord.file);
|
|
455
|
+
matches('candidate.entrypoints.fastlyManifest', candidate.entrypoints.fastlyManifest, fastlyRecord.file);
|
|
456
|
+
matches('candidate.entrypoints.packageManifest', candidate.entrypoints.packageManifest, packageRecord.file);
|
|
457
|
+
matches('manifest.deploymentCandidate.version', manifest.deploymentCandidate.version, candidate.version);
|
|
458
|
+
matches('manifest.deploymentCandidate.status', manifest.deploymentCandidate.status, candidate.status);
|
|
459
|
+
matches('manifest.deploymentCandidate.file', manifest.deploymentCandidate.file, candidateRecord.file);
|
|
460
|
+
matches('manifest.deploymentCandidate.sha256', manifest.deploymentCandidate.sha256, candidateRecord.sha256);
|
|
461
|
+
matches('deployment.candidate.version', deployment.candidate.version, candidate.version);
|
|
462
|
+
matches('deployment.candidate.file', deployment.candidate.file, candidateRecord.file);
|
|
463
|
+
matches('deployment.candidate.status', deployment.candidate.status, candidate.status);
|
|
464
|
+
if (stableJson(manifest.deploymentCandidate.identity) !== stableJson(candidate.identity)) {
|
|
465
|
+
mismatches.push(Object.freeze({ label: 'manifest.deploymentCandidate.identity' }));
|
|
466
|
+
}
|
|
467
|
+
if (stableJson(manifest.deploymentCandidate.commands) !== stableJson(candidate.commands)) {
|
|
468
|
+
mismatches.push(Object.freeze({ label: 'manifest.deploymentCandidate.commands' }));
|
|
469
|
+
}
|
|
470
|
+
if (mismatches.length > 0) {
|
|
471
|
+
throw new PulseFastlyJavascriptSourcePackageError(
|
|
472
|
+
'PULSE_FASTLY_JAVASCRIPT_DEPLOYMENT_CANDIDATE_MISMATCH',
|
|
473
|
+
'Fastly JavaScript deployment candidate and source-package manifests disagree.',
|
|
474
|
+
{ mismatches: Object.freeze(mismatches) }
|
|
475
|
+
);
|
|
476
|
+
}
|
|
477
|
+
}
|
|
478
|
+
|
|
479
|
+
function writeFastlyJavascriptSourcePackage(options = {}) {
|
|
480
|
+
const plan = options.plan;
|
|
481
|
+
if (!plan || !plan.graph || plan.provider !== 'fastly' || plan.target !== 'javascript' || plan.loadable !== true) {
|
|
482
|
+
throw new PulseFastlyJavascriptSourcePackageError(
|
|
483
|
+
'PULSE_FASTLY_JAVASCRIPT_PACKAGE_PLAN_UNAVAILABLE',
|
|
484
|
+
'Fastly JavaScript source packaging requires a loadable Fastly JavaScript application plan.',
|
|
485
|
+
{
|
|
486
|
+
provider: plan && plan.provider,
|
|
487
|
+
target: plan && plan.target,
|
|
488
|
+
blockers: plan && plan.blockers || []
|
|
489
|
+
}
|
|
490
|
+
);
|
|
491
|
+
}
|
|
492
|
+
const projectRoot = path.resolve(options.projectRoot || '.');
|
|
493
|
+
const outDir = path.resolve(options.outDir || path.join(projectRoot, 'dist'));
|
|
494
|
+
assertInside(projectRoot, outDir, 'Fastly JavaScript build output');
|
|
495
|
+
fs.mkdirSync(outDir, { recursive: true });
|
|
496
|
+
|
|
497
|
+
const reporting = reportingDescriptor(options.reporting);
|
|
498
|
+
const descriptor = Object.freeze({
|
|
499
|
+
...FASTLY_JAVASCRIPT_TARGET_DESCRIPTOR,
|
|
500
|
+
resolvedReporting: reporting
|
|
501
|
+
});
|
|
502
|
+
const schemaBundle = options.schemaBundle;
|
|
503
|
+
const schemaActive = Boolean(schemaBundle && schemaBundle.active);
|
|
504
|
+
const bundle = bundleFastlyJavascriptApplication(plan, projectRoot, schemaBundle);
|
|
505
|
+
const providerConfig = options.providerConfig || {};
|
|
506
|
+
const providerBindings = providerConfig.bindings && typeof providerConfig.bindings === 'object'
|
|
507
|
+
? providerConfig.bindings
|
|
508
|
+
: {};
|
|
509
|
+
const targetSupport = options.targetSupport || null;
|
|
510
|
+
const deployment = Object.freeze({
|
|
511
|
+
version: 'pulse.fastly-javascript-deployment.v1',
|
|
512
|
+
provider: 'fastly',
|
|
513
|
+
target: 'javascript',
|
|
514
|
+
targetId: descriptor.targetId,
|
|
515
|
+
runtimeClass: 'javascript',
|
|
516
|
+
automaticFallback: false,
|
|
517
|
+
nativeArtifact: false,
|
|
518
|
+
sourcePackage: true,
|
|
519
|
+
executionReady: true,
|
|
520
|
+
providerExecutionReady: true,
|
|
521
|
+
generalAvailable: Boolean(targetSupport?.availability?.generalAvailable),
|
|
522
|
+
deferredTo: Object.freeze([]),
|
|
523
|
+
reporting,
|
|
524
|
+
targetDescriptor: descriptor,
|
|
525
|
+
targetSupport,
|
|
526
|
+
candidate: Object.freeze({
|
|
527
|
+
version: FASTLY_JAVASCRIPT_DEPLOYMENT_CANDIDATE_VERSION,
|
|
528
|
+
file: FASTLY_JAVASCRIPT_DEPLOYMENT_CANDIDATE,
|
|
529
|
+
status: 'structurally-deployable',
|
|
530
|
+
providerRealityValidated: false,
|
|
531
|
+
deployed: false
|
|
532
|
+
}),
|
|
533
|
+
downstreamBuild: Object.freeze({
|
|
534
|
+
owner: '@fastly/js-compute',
|
|
535
|
+
classification: 'javascript-runtime-deployment',
|
|
536
|
+
input: 'dist/index.js',
|
|
537
|
+
output: 'bin/main.wasm',
|
|
538
|
+
pulseNativeLowering: false
|
|
539
|
+
})
|
|
540
|
+
});
|
|
541
|
+
const runtimeConfig = Object.freeze({
|
|
542
|
+
bindings: providerBindings,
|
|
543
|
+
reporting: reporting.name,
|
|
544
|
+
strict: options.strict === true,
|
|
545
|
+
maxStructuredBodyBytes: Number(options.maxStructuredBodyBytes || 65536)
|
|
546
|
+
});
|
|
547
|
+
const packageJson = Object.freeze({
|
|
548
|
+
name: packageName(providerConfig.build && providerConfig.build.name),
|
|
549
|
+
version: '0.0.0',
|
|
550
|
+
private: true,
|
|
551
|
+
type: 'module',
|
|
552
|
+
scripts: Object.freeze({
|
|
553
|
+
prebuild: 'node pulse-esbuild.config.js',
|
|
554
|
+
build: 'js-compute-runtime ./dist/index.js ./bin/main.wasm'
|
|
555
|
+
}),
|
|
556
|
+
dependencies: Object.freeze({
|
|
557
|
+
'@fastly/js-compute': FASTLY_JS_COMPUTE_VERSION
|
|
558
|
+
}),
|
|
559
|
+
devDependencies: Object.freeze({
|
|
560
|
+
esbuild: ESBUILD_VERSION
|
|
561
|
+
})
|
|
562
|
+
});
|
|
563
|
+
|
|
564
|
+
const records = [];
|
|
565
|
+
const record = (relativeFile, content) => {
|
|
566
|
+
const value = writeFile(outDir, relativeFile, content);
|
|
567
|
+
records.push(value);
|
|
568
|
+
return value;
|
|
569
|
+
};
|
|
570
|
+
const applicationRecord = record('src/application.js', bundle.source);
|
|
571
|
+
const bootstrapRecord = record('src/index.js', bootstrapSource(deployment, runtimeConfig));
|
|
572
|
+
const packageRecord = record('package.json', stableJson(packageJson));
|
|
573
|
+
const configRecord = record('pulse-esbuild.config.js', downstreamEsbuildConfig());
|
|
574
|
+
const fastlyRecord = record('fastly.toml', fastlyToml(providerConfig));
|
|
575
|
+
const planRecord = record('pulse-javascript-application-plan.json', stableJson(plan));
|
|
576
|
+
const deploymentRecord = record(FASTLY_JAVASCRIPT_DEPLOYMENT_MANIFEST, stableJson(deployment));
|
|
577
|
+
const schemaRegistryRecord = schemaActive
|
|
578
|
+
? record('schema-json-registry.json', stableJson(schemaBundle.registry))
|
|
579
|
+
: undefined;
|
|
580
|
+
const schemaCodecsRecord = schemaActive
|
|
581
|
+
? record('schema-json-codecs.cjs', schemaBundle.moduleSource)
|
|
582
|
+
: undefined;
|
|
583
|
+
const candidate = Object.freeze({
|
|
584
|
+
version: FASTLY_JAVASCRIPT_DEPLOYMENT_CANDIDATE_VERSION,
|
|
585
|
+
status: 'structurally-deployable',
|
|
586
|
+
provider: 'fastly',
|
|
587
|
+
target: 'javascript',
|
|
588
|
+
targetId: descriptor.targetId,
|
|
589
|
+
runtimeClass: 'javascript',
|
|
590
|
+
automaticFallback: false,
|
|
591
|
+
nativeArtifact: false,
|
|
592
|
+
providerRealityValidated: false,
|
|
593
|
+
deployed: false,
|
|
594
|
+
identity: Object.freeze({
|
|
595
|
+
applicationPlanHash: plan.planHash,
|
|
596
|
+
graphHash: plan.graph.graphHash,
|
|
597
|
+
bundleSha256: applicationRecord.sha256,
|
|
598
|
+
targetSupportEvidenceHash: targetSupport && targetSupport.evidenceHash || null,
|
|
599
|
+
schemaSourceHash: schemaActive ? schemaBundle.sourceHash : null
|
|
600
|
+
}),
|
|
601
|
+
sourcePackage: Object.freeze({
|
|
602
|
+
version: FASTLY_JAVASCRIPT_SOURCE_PACKAGE_VERSION,
|
|
603
|
+
manifest: FASTLY_JAVASCRIPT_SOURCE_PACKAGE_MANIFEST
|
|
604
|
+
}),
|
|
605
|
+
deployment: Object.freeze({
|
|
606
|
+
version: deployment.version,
|
|
607
|
+
manifest: deploymentRecord.file,
|
|
608
|
+
sha256: deploymentRecord.sha256
|
|
609
|
+
}),
|
|
610
|
+
entrypoints: Object.freeze({
|
|
611
|
+
bootstrap: bootstrapRecord.file,
|
|
612
|
+
bundledApplication: applicationRecord.file,
|
|
613
|
+
fastlyManifest: fastlyRecord.file,
|
|
614
|
+
packageManifest: packageRecord.file
|
|
615
|
+
}),
|
|
616
|
+
toolchain: Object.freeze({
|
|
617
|
+
'@fastly/js-compute': FASTLY_JS_COMPUTE_VERSION,
|
|
618
|
+
esbuild: ESBUILD_VERSION
|
|
619
|
+
}),
|
|
620
|
+
commands: Object.freeze({
|
|
621
|
+
install: 'npm install',
|
|
622
|
+
build: 'npm run build',
|
|
623
|
+
localReality: 'fastly compute serve'
|
|
624
|
+
}),
|
|
625
|
+
validation: Object.freeze({
|
|
626
|
+
packageClosure: 'bundled',
|
|
627
|
+
loader: 'generated',
|
|
628
|
+
manifestAgreement: 'verified-at-package-write',
|
|
629
|
+
providerEmulation: 'pulse test and pulse dev',
|
|
630
|
+
providerReality: 'not-executed',
|
|
631
|
+
deployment: 'not-executed'
|
|
632
|
+
}),
|
|
633
|
+
files: Object.freeze(records.map((entry) => Object.freeze({
|
|
634
|
+
file: entry.file,
|
|
635
|
+
bytes: entry.bytes,
|
|
636
|
+
sha256: entry.sha256
|
|
637
|
+
})))
|
|
638
|
+
});
|
|
639
|
+
const candidateRecord = record(FASTLY_JAVASCRIPT_DEPLOYMENT_CANDIDATE, stableJson(candidate));
|
|
640
|
+
|
|
641
|
+
const manifest = Object.freeze({
|
|
642
|
+
version: FASTLY_JAVASCRIPT_SOURCE_PACKAGE_VERSION,
|
|
643
|
+
status: 'packaged',
|
|
644
|
+
provider: 'fastly',
|
|
645
|
+
target: 'javascript',
|
|
646
|
+
targetId: descriptor.targetId,
|
|
647
|
+
runtimeClass: 'javascript',
|
|
648
|
+
automaticFallback: false,
|
|
649
|
+
nativeArtifact: false,
|
|
650
|
+
nativeEligibility: plan.nativeEligibility,
|
|
651
|
+
reporting,
|
|
652
|
+
targetDescriptor: descriptor,
|
|
653
|
+
targetSupport,
|
|
654
|
+
capabilityEnvelope: plan.capabilityEnvelope,
|
|
655
|
+
eligibility: Object.freeze({
|
|
656
|
+
applicationPlanLoadable: plan.loadable,
|
|
657
|
+
blockers: plan.blockers,
|
|
658
|
+
providerExecutionReady: true,
|
|
659
|
+
projectStatus: targetSupport && targetSupport.project && targetSupport.project.status || 'eligible',
|
|
660
|
+
restrictions: descriptor.capabilities.restrictions,
|
|
661
|
+
availability: 'evidence-controlled'
|
|
662
|
+
}),
|
|
663
|
+
project: Object.freeze({
|
|
664
|
+
root: '.',
|
|
665
|
+
entry: slash(plan.workspace.entry),
|
|
666
|
+
bundledEntry: applicationRecord.file,
|
|
667
|
+
bootstrap: bootstrapRecord.file
|
|
668
|
+
}),
|
|
669
|
+
plan: Object.freeze({
|
|
670
|
+
version: plan.version,
|
|
671
|
+
planHash: plan.planHash,
|
|
672
|
+
graphVersion: plan.graph.version,
|
|
673
|
+
graphHash: plan.graph.graphHash,
|
|
674
|
+
resolverHash: plan.graph.resolverHash
|
|
675
|
+
}),
|
|
676
|
+
closure: Object.freeze({
|
|
677
|
+
kind: 'esbuild-bundled-source-closure',
|
|
678
|
+
bundle: applicationRecord.file,
|
|
679
|
+
bundleSha256: applicationRecord.sha256,
|
|
680
|
+
inputs: bundle.inputs,
|
|
681
|
+
reachablePackages: plan.packages,
|
|
682
|
+
toolchain: Object.freeze({
|
|
683
|
+
'@fastly/js-compute': FASTLY_JS_COMPUTE_VERSION,
|
|
684
|
+
esbuild: ESBUILD_VERSION
|
|
685
|
+
}),
|
|
686
|
+
workspaceLinks: false
|
|
687
|
+
}),
|
|
688
|
+
package: Object.freeze({
|
|
689
|
+
manifest: packageRecord.file,
|
|
690
|
+
entry: bootstrapRecord.file,
|
|
691
|
+
applicationPlan: planRecord.file,
|
|
692
|
+
deployment: deploymentRecord.file,
|
|
693
|
+
candidate: candidateRecord.file,
|
|
694
|
+
fastlyToml: fastlyRecord.file,
|
|
695
|
+
buildConfig: configRecord.file,
|
|
696
|
+
schemaRegistry: schemaRegistryRecord && schemaRegistryRecord.file,
|
|
697
|
+
schemaCodecs: schemaCodecsRecord && schemaCodecsRecord.file,
|
|
698
|
+
dependencies: packageJson.dependencies,
|
|
699
|
+
devDependencies: packageJson.devDependencies
|
|
700
|
+
}),
|
|
701
|
+
schemas: Object.freeze({
|
|
702
|
+
active: schemaActive,
|
|
703
|
+
registry: schemaRegistryRecord && schemaRegistryRecord.file,
|
|
704
|
+
codecs: schemaCodecsRecord && schemaCodecsRecord.file,
|
|
705
|
+
ids: Object.freeze(schemaActive ? [...schemaBundle.schemaIds] : []),
|
|
706
|
+
responseCaseIds: Object.freeze(schemaActive ? [...schemaBundle.responseCaseIds] : []),
|
|
707
|
+
registryHash: schemaActive ? schemaBundle.registry.registryHash : null,
|
|
708
|
+
codecTableHash: schemaActive ? schemaBundle.codecTableHash : null,
|
|
709
|
+
sourceHash: schemaActive ? schemaBundle.sourceHash : null,
|
|
710
|
+
fullCodecRealization: schemaActive ? schemaBundle.fullCodecRealization === true : false
|
|
711
|
+
}),
|
|
712
|
+
deploymentCandidate: Object.freeze({
|
|
713
|
+
version: candidate.version,
|
|
714
|
+
status: candidate.status,
|
|
715
|
+
file: candidateRecord.file,
|
|
716
|
+
sha256: candidateRecord.sha256,
|
|
717
|
+
providerRealityValidated: false,
|
|
718
|
+
deployed: false,
|
|
719
|
+
identity: candidate.identity,
|
|
720
|
+
commands: candidate.commands
|
|
721
|
+
}),
|
|
722
|
+
downstreamBuild: deployment.downstreamBuild,
|
|
723
|
+
files: Object.freeze([...records]),
|
|
724
|
+
summary: Object.freeze({
|
|
725
|
+
bundledInputs: bundle.inputs.length,
|
|
726
|
+
bundledBytes: applicationRecord.bytes,
|
|
727
|
+
sourcePackageBytes: records.reduce((sum, entry) => sum + entry.bytes, 0),
|
|
728
|
+
wasmFiles: 0,
|
|
729
|
+
nativeFiles: 0
|
|
730
|
+
})
|
|
731
|
+
});
|
|
732
|
+
assertDeploymentCandidateAgreement({
|
|
733
|
+
candidate,
|
|
734
|
+
candidateRecord,
|
|
735
|
+
deployment,
|
|
736
|
+
deploymentRecord,
|
|
737
|
+
manifest,
|
|
738
|
+
plan,
|
|
739
|
+
applicationRecord,
|
|
740
|
+
bootstrapRecord,
|
|
741
|
+
packageRecord,
|
|
742
|
+
fastlyRecord
|
|
743
|
+
});
|
|
744
|
+
const manifestRecord = writeFile(outDir, FASTLY_JAVASCRIPT_SOURCE_PACKAGE_MANIFEST, stableJson(manifest));
|
|
745
|
+
|
|
746
|
+
return Object.freeze({
|
|
747
|
+
version: FASTLY_JAVASCRIPT_SOURCE_PACKAGE_VERSION,
|
|
748
|
+
outDir,
|
|
749
|
+
entryFile: path.join(outDir, bootstrapRecord.file),
|
|
750
|
+
bundledApplicationFile: path.join(outDir, applicationRecord.file),
|
|
751
|
+
packageFile: path.join(outDir, packageRecord.file),
|
|
752
|
+
applicationPlanFile: path.join(outDir, planRecord.file),
|
|
753
|
+
deploymentFile: path.join(outDir, deploymentRecord.file),
|
|
754
|
+
deploymentCandidateFile: path.join(outDir, candidateRecord.file),
|
|
755
|
+
buildConfigFile: path.join(outDir, configRecord.file),
|
|
756
|
+
fastlyTomlFile: path.join(outDir, fastlyRecord.file),
|
|
757
|
+
schemaRegistryFile: schemaRegistryRecord ? path.join(outDir, schemaRegistryRecord.file) : undefined,
|
|
758
|
+
schemaCodecsFile: schemaCodecsRecord ? path.join(outDir, schemaCodecsRecord.file) : undefined,
|
|
759
|
+
manifestFile: path.join(outDir, manifestRecord.file),
|
|
760
|
+
manifest,
|
|
761
|
+
files: Object.freeze([...records, manifestRecord])
|
|
762
|
+
});
|
|
763
|
+
}
|
|
764
|
+
|
|
765
|
+
module.exports = Object.freeze({
|
|
766
|
+
FASTLY_JAVASCRIPT_SOURCE_PACKAGE_VERSION,
|
|
767
|
+
FASTLY_JAVASCRIPT_SOURCE_PACKAGE_MANIFEST,
|
|
768
|
+
FASTLY_JAVASCRIPT_DEPLOYMENT_MANIFEST,
|
|
769
|
+
FASTLY_JAVASCRIPT_DEPLOYMENT_CANDIDATE_VERSION,
|
|
770
|
+
FASTLY_JAVASCRIPT_DEPLOYMENT_CANDIDATE,
|
|
771
|
+
FASTLY_JS_COMPUTE_VERSION,
|
|
772
|
+
ESBUILD_VERSION,
|
|
773
|
+
PulseFastlyJavascriptSourcePackageError,
|
|
774
|
+
bundleFastlyJavascriptApplication,
|
|
775
|
+
writeFastlyJavascriptSourcePackage
|
|
776
|
+
});
|