@netlify/edge-bundler 14.8.3 → 14.8.4
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/dist/node/bridge.d.ts +1 -1
- package/dist/node/bridge.js +3 -3
- package/dist/node/bundler.js +41 -46
- package/dist/node/config.js +6 -1
- package/dist/node/formats/eszip.d.ts +0 -4
- package/dist/node/formats/eszip.js +0 -11
- package/package.json +4 -3
- package/deno/extract.ts +0 -7
- package/dist/node/bridge.test.js +0 -141
- package/dist/node/bundler.test.js +0 -717
- package/dist/node/config.test.js +0 -408
- package/dist/node/declaration.test.js +0 -131
- package/dist/node/deploy_config.test.js +0 -48
- package/dist/node/downloader.test.js +0 -124
- package/dist/node/finder.test.js +0 -17
- package/dist/node/import_map.test.js +0 -212
- package/dist/node/logger.test.js +0 -51
- package/dist/node/main.test.js +0 -46
- package/dist/node/manifest.test.js +0 -597
- package/dist/node/package_json.test.js +0 -7
- package/dist/node/server/server.test.js +0 -144
- package/dist/node/stage_2.test.js +0 -53
- package/dist/node/types.test.js +0 -63
- package/dist/node/validation/manifest/index.test.js +0 -237
package/dist/node/bridge.d.ts
CHANGED
|
@@ -2,7 +2,7 @@ import { type WriteStream } from 'fs';
|
|
|
2
2
|
import { type ExecaChildProcess } from 'execa';
|
|
3
3
|
import { FeatureFlags } from './feature_flags.js';
|
|
4
4
|
import { Logger } from './logger.js';
|
|
5
|
-
export declare const
|
|
5
|
+
export declare const LEGACY_DENO_VERSION_RANGE = "1.39.0 - 2.2.4";
|
|
6
6
|
export type OnBeforeDownloadHook = () => void | Promise<void>;
|
|
7
7
|
export type OnAfterDownloadHook = (error?: Error) => void | Promise<void>;
|
|
8
8
|
export interface DenoOptions {
|
package/dist/node/bridge.js
CHANGED
|
@@ -9,11 +9,11 @@ import { getPathInHome } from './home_path.js';
|
|
|
9
9
|
import { getLogger } from './logger.js';
|
|
10
10
|
import { getBinaryExtension } from './platform.js';
|
|
11
11
|
const DENO_VERSION_FILE = 'version.txt';
|
|
12
|
+
export const LEGACY_DENO_VERSION_RANGE = '1.39.0 - 2.2.4';
|
|
12
13
|
// When updating DENO_VERSION_RANGE, ensure that the deno version
|
|
13
14
|
// on the netlify/buildbot build image satisfies this range!
|
|
14
15
|
// https://github.com/netlify/buildbot/blob/f9c03c9dcb091d6570e9d0778381560d469e78ad/build-image/noble/Dockerfile#L410
|
|
15
|
-
|
|
16
|
-
const NEXT_DENO_VERSION_RANGE = '^2.4.2';
|
|
16
|
+
const DENO_VERSION_RANGE = '^2.4.2';
|
|
17
17
|
export class DenoBridge {
|
|
18
18
|
cacheDirectory;
|
|
19
19
|
currentDownload;
|
|
@@ -35,7 +35,7 @@ export class DenoBridge {
|
|
|
35
35
|
const useNextDeno = options.featureFlags?.edge_bundler_dry_run_generate_tarball ||
|
|
36
36
|
options.featureFlags?.edge_bundler_generate_tarball ||
|
|
37
37
|
options.featureFlags?.edge_bundler_deno_v2;
|
|
38
|
-
this.versionRange = options.versionRange ?? (useNextDeno ?
|
|
38
|
+
this.versionRange = options.versionRange ?? (useNextDeno ? DENO_VERSION_RANGE : LEGACY_DENO_VERSION_RANGE);
|
|
39
39
|
}
|
|
40
40
|
async downloadBinary() {
|
|
41
41
|
await this.onBeforeDownload?.();
|
package/dist/node/bundler.js
CHANGED
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
import { promises as fs } from 'fs';
|
|
2
|
-
import { join
|
|
2
|
+
import { join } from 'path';
|
|
3
3
|
import commonPathPrefix from 'common-path-prefix';
|
|
4
4
|
import { v4 as uuidv4 } from 'uuid';
|
|
5
5
|
import { importMapSpecifier } from '../shared/consts.js';
|
|
6
|
-
import { DenoBridge } from './bridge.js';
|
|
6
|
+
import { DenoBridge, LEGACY_DENO_VERSION_RANGE, } from './bridge.js';
|
|
7
7
|
import { getFunctionConfig } from './config.js';
|
|
8
8
|
import { mergeDeclarations } from './declaration.js';
|
|
9
9
|
import { load as loadDeployConfig } from './deploy_config.js';
|
|
10
10
|
import { getFlags } from './feature_flags.js';
|
|
11
11
|
import { findFunctions } from './finder.js';
|
|
12
|
-
import { bundle as bundleESZIP
|
|
12
|
+
import { bundle as bundleESZIP } from './formats/eszip.js';
|
|
13
13
|
import { bundle as bundleTarball } from './formats/tarball.js';
|
|
14
14
|
import { ImportMap } from './import_map.js';
|
|
15
15
|
import { getLogger } from './logger.js';
|
|
@@ -17,7 +17,7 @@ import { writeManifest } from './manifest.js';
|
|
|
17
17
|
import { vendorNPMSpecifiers } from './npm_dependencies.js';
|
|
18
18
|
import { ensureLatestTypes } from './types.js';
|
|
19
19
|
import { nonNullable } from './utils/non_nullable.js';
|
|
20
|
-
import {
|
|
20
|
+
import { getPathInHome } from './home_path.js';
|
|
21
21
|
export const bundle = async (sourceDirectories, distDirectory, tomlDeclarations = [], { basePath: inputBasePath, cacheDirectory, configPath, debug, distImportMapPath, featureFlags: inputFeatureFlags, importMapPaths = [], internalSrcFolder, onAfterDownload, onBeforeDownload, rootPath, userLogger, systemLogger, vendorDirectory, } = {}) => {
|
|
22
22
|
const logger = getLogger(systemLogger, userLogger, debug);
|
|
23
23
|
const featureFlags = getFlags(inputFeatureFlags);
|
|
@@ -110,13 +110,9 @@ export const bundle = async (sourceDirectories, distDirectory, tomlDeclarations
|
|
|
110
110
|
// The final file name of the bundles contains a SHA256 hash of the contents,
|
|
111
111
|
// which we can only compute now that the files have been generated. So let's
|
|
112
112
|
// rename the bundles to their permanent names.
|
|
113
|
-
|
|
114
|
-
const eszipPath = bundlePaths.find((path) => path.endsWith(eszipExtension));
|
|
113
|
+
await createFinalBundles(bundles, distDirectory, buildID);
|
|
115
114
|
const { internalFunctions: internalFunctionsWithConfig, userFunctions: userFunctionsWithConfig } = await getFunctionConfigs({
|
|
116
|
-
basePath,
|
|
117
115
|
deno,
|
|
118
|
-
eszipPath,
|
|
119
|
-
featureFlags,
|
|
120
116
|
importMap,
|
|
121
117
|
internalFunctions,
|
|
122
118
|
log: logger,
|
|
@@ -146,45 +142,44 @@ export const bundle = async (sourceDirectories, distDirectory, tomlDeclarations
|
|
|
146
142
|
}
|
|
147
143
|
return { functions, manifest };
|
|
148
144
|
};
|
|
149
|
-
const getFunctionConfigs = async ({
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
return [func.name, await getFunctionConfig({ functionPath, importMap, deno, log })];
|
|
177
|
-
}));
|
|
178
|
-
await extractedESZIP.cleanup();
|
|
179
|
-
return {
|
|
180
|
-
internalFunctions: Object.fromEntries(configs.slice(0, internalFunctions.length)),
|
|
181
|
-
userFunctions: Object.fromEntries(configs.slice(internalFunctions.length)),
|
|
182
|
-
};
|
|
183
|
-
}
|
|
184
|
-
catch (err) {
|
|
185
|
-
throw new BundleError(new Error('An error occurred while building an edge function that uses an import assertion. Refer to https://ntl.fyi/import-assert for more information.'), { cause: err });
|
|
145
|
+
const getFunctionConfigs = async ({ deno, importMap, log, internalFunctions, userFunctions, }) => {
|
|
146
|
+
const functions = [...internalFunctions, ...userFunctions];
|
|
147
|
+
const results = await Promise.allSettled(functions.map(async (func) => {
|
|
148
|
+
return [func.name, await getFunctionConfig({ functionPath: func.path, importMap, deno, log })];
|
|
149
|
+
}));
|
|
150
|
+
const legacyDeno = new DenoBridge({
|
|
151
|
+
cacheDirectory: getPathInHome('deno-cli-v1'),
|
|
152
|
+
useGlobal: false,
|
|
153
|
+
versionRange: LEGACY_DENO_VERSION_RANGE,
|
|
154
|
+
});
|
|
155
|
+
for (let i = 0; i < results.length; i++) {
|
|
156
|
+
const result = results[i];
|
|
157
|
+
const func = functions[i];
|
|
158
|
+
// We offer support for some features of Deno 1.x that have been removed
|
|
159
|
+
// from 2.x, such as import assertions and the `window` global. When we
|
|
160
|
+
// see that we failed to extract a config due to those edge cases, re-run
|
|
161
|
+
// the script with Deno 1.x so we can extract the config.
|
|
162
|
+
if (result.status === 'rejected' &&
|
|
163
|
+
result.reason instanceof Error &&
|
|
164
|
+
(result.reason.cause === 'IMPORT_ASSERT' || result.reason.cause === 'WINDOW_GLOBAL')) {
|
|
165
|
+
try {
|
|
166
|
+
const fallbackConfig = await getFunctionConfig({ functionPath: func.path, importMap, deno: legacyDeno, log });
|
|
167
|
+
results[i] = { status: 'fulfilled', value: [func.name, fallbackConfig] };
|
|
168
|
+
}
|
|
169
|
+
catch {
|
|
170
|
+
throw result.reason;
|
|
171
|
+
}
|
|
186
172
|
}
|
|
187
173
|
}
|
|
174
|
+
const failure = results.find((result) => result.status === 'rejected');
|
|
175
|
+
if (failure) {
|
|
176
|
+
throw failure.reason;
|
|
177
|
+
}
|
|
178
|
+
const configs = results.map((config) => config.value);
|
|
179
|
+
return {
|
|
180
|
+
internalFunctions: Object.fromEntries(configs.slice(0, internalFunctions.length)),
|
|
181
|
+
userFunctions: Object.fromEntries(configs.slice(internalFunctions.length)),
|
|
182
|
+
};
|
|
188
183
|
};
|
|
189
184
|
const createFinalBundles = async (bundles, distDirectory, buildID) => {
|
|
190
185
|
const renamingOps = bundles.map(async ({ extension, hash }) => {
|
package/dist/node/config.js
CHANGED
|
@@ -84,10 +84,15 @@ export const getFunctionConfig = async ({ deno, functionPath, importMap, log, })
|
|
|
84
84
|
};
|
|
85
85
|
const handleConfigError = (functionPath, exitCode, stderr, log) => {
|
|
86
86
|
let cause;
|
|
87
|
-
if (stderr.includes('Import assertions are deprecated')
|
|
87
|
+
if (stderr.includes('Import assertions are deprecated') ||
|
|
88
|
+
stderr.includes(`SyntaxError: Unexpected identifier 'assert'`)) {
|
|
88
89
|
log.system(`Edge function uses import assertions: ${functionPath}`);
|
|
89
90
|
cause = 'IMPORT_ASSERT';
|
|
90
91
|
}
|
|
92
|
+
if (stderr.includes('ReferenceError: window is not defined')) {
|
|
93
|
+
log.system(`Edge function uses the window global: ${functionPath}`);
|
|
94
|
+
cause = 'WINDOW_GLOBAL';
|
|
95
|
+
}
|
|
91
96
|
switch (exitCode) {
|
|
92
97
|
case ConfigExitCode.ImportError:
|
|
93
98
|
log.user(stderr);
|
|
@@ -17,8 +17,4 @@ interface BundleESZIPOptions {
|
|
|
17
17
|
vendorDirectory?: string;
|
|
18
18
|
}
|
|
19
19
|
export declare const bundle: ({ basePath, buildID, debug, deno, distDirectory, externals, functions, importMap, vendorDirectory, }: BundleESZIPOptions) => Promise<Bundle>;
|
|
20
|
-
export declare const extract: (deno: DenoBridge, functionPath: string) => Promise<{
|
|
21
|
-
cleanup: () => Promise<void>;
|
|
22
|
-
path: string;
|
|
23
|
-
}>;
|
|
24
20
|
export {};
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { join } from 'path';
|
|
2
2
|
import { pathToFileURL } from 'url';
|
|
3
|
-
import tmp from 'tmp-promise';
|
|
4
3
|
import { virtualRoot, virtualVendorRoot } from '../../shared/consts.js';
|
|
5
4
|
import { BundleFormat } from '../bundle.js';
|
|
6
5
|
import { wrapBundleError } from '../bundle_error.js';
|
|
@@ -49,13 +48,3 @@ const getESZIPPaths = () => {
|
|
|
49
48
|
importMap: join(denoPath, 'vendor', 'import_map.json'),
|
|
50
49
|
};
|
|
51
50
|
};
|
|
52
|
-
export const extract = async (deno, functionPath) => {
|
|
53
|
-
const tmpDir = await tmp.dir({ unsafeCleanup: true });
|
|
54
|
-
const { extractor, importMap } = getESZIPPaths();
|
|
55
|
-
const flags = ['--allow-all', '--no-config', '--no-lock', `--import-map=${importMap}`, '--quiet'];
|
|
56
|
-
await deno.run(['run', ...flags, extractor, functionPath, tmpDir.path], { pipeOutput: true });
|
|
57
|
-
return {
|
|
58
|
-
cleanup: tmpDir.cleanup,
|
|
59
|
-
path: join(tmpDir.path, 'source', 'root'),
|
|
60
|
-
};
|
|
61
|
-
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@netlify/edge-bundler",
|
|
3
|
-
"version": "14.8.
|
|
3
|
+
"version": "14.8.4",
|
|
4
4
|
"description": "Intelligently prepare Netlify Edge Functions for deployment",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/node/index.js",
|
|
@@ -9,6 +9,7 @@
|
|
|
9
9
|
"deno/**",
|
|
10
10
|
"!deno/**/*.test.ts",
|
|
11
11
|
"dist/**/*.js",
|
|
12
|
+
"!dist/**/*.test.js",
|
|
12
13
|
"dist/**/*.d.ts",
|
|
13
14
|
"shared/**"
|
|
14
15
|
],
|
|
@@ -64,7 +65,7 @@
|
|
|
64
65
|
"better-ajv-errors": "^1.2.0",
|
|
65
66
|
"common-path-prefix": "^3.0.0",
|
|
66
67
|
"env-paths": "^3.0.0",
|
|
67
|
-
"esbuild": "0.25.
|
|
68
|
+
"esbuild": "0.25.11",
|
|
68
69
|
"execa": "^8.0.0",
|
|
69
70
|
"find-up": "^7.0.0",
|
|
70
71
|
"get-port": "^7.0.0",
|
|
@@ -79,5 +80,5 @@
|
|
|
79
80
|
"urlpattern-polyfill": "8.0.2",
|
|
80
81
|
"uuid": "^11.0.0"
|
|
81
82
|
},
|
|
82
|
-
"gitHead": "
|
|
83
|
+
"gitHead": "eae1c7c9d0d7ab598aa676f72d298160a5fee92a"
|
|
83
84
|
}
|
package/deno/extract.ts
DELETED
package/dist/node/bridge.test.js
DELETED
|
@@ -1,141 +0,0 @@
|
|
|
1
|
-
import { Buffer } from 'buffer';
|
|
2
|
-
import { rm } from 'fs/promises';
|
|
3
|
-
import { createRequire } from 'module';
|
|
4
|
-
import { platform, env } from 'process';
|
|
5
|
-
import { PassThrough } from 'stream';
|
|
6
|
-
import nock from 'nock';
|
|
7
|
-
import semver from 'semver';
|
|
8
|
-
import tmp from 'tmp-promise';
|
|
9
|
-
import { test, expect } from 'vitest';
|
|
10
|
-
import { DenoBridge, DENO_VERSION_RANGE } from './bridge.js';
|
|
11
|
-
import { getPlatformTarget } from './platform.js';
|
|
12
|
-
const require = createRequire(import.meta.url);
|
|
13
|
-
const archiver = require('archiver');
|
|
14
|
-
const getMockDenoBridge = function (tmpDir, mockBinaryOutput) {
|
|
15
|
-
const latestVersion = semver.minVersion(DENO_VERSION_RANGE)?.version ?? '';
|
|
16
|
-
const data = new PassThrough();
|
|
17
|
-
const archive = archiver('zip', { zlib: { level: 9 } });
|
|
18
|
-
archive.pipe(data);
|
|
19
|
-
archive.append(Buffer.from(mockBinaryOutput.replace(/@@@latestVersion@@@/g, latestVersion)), {
|
|
20
|
-
name: platform === 'win32' ? 'deno.exe' : 'deno',
|
|
21
|
-
});
|
|
22
|
-
archive.finalize();
|
|
23
|
-
const target = getPlatformTarget();
|
|
24
|
-
nock('https://dl.deno.land').get('/release-latest.txt').reply(200, `v${latestVersion}`);
|
|
25
|
-
nock('https://dl.deno.land')
|
|
26
|
-
.get(`/release/v${latestVersion}/deno-${target}.zip`)
|
|
27
|
-
.reply(200, () => data);
|
|
28
|
-
return new DenoBridge({
|
|
29
|
-
cacheDirectory: tmpDir.path,
|
|
30
|
-
useGlobal: false,
|
|
31
|
-
});
|
|
32
|
-
};
|
|
33
|
-
test('Does not inherit environment variables if `extendEnv` is false', async () => {
|
|
34
|
-
const tmpDir = await tmp.dir();
|
|
35
|
-
const deno = getMockDenoBridge(tmpDir, `#!/usr/bin/env sh
|
|
36
|
-
|
|
37
|
-
if [ "$1" = "test" ]
|
|
38
|
-
then
|
|
39
|
-
env
|
|
40
|
-
else
|
|
41
|
-
echo "deno @@@latestVersion@@@"
|
|
42
|
-
fi`);
|
|
43
|
-
// The environment sets some variables so let us see what they are and remove them from the result
|
|
44
|
-
const referenceOutput = await deno.run(['test'], { env: {}, extendEnv: false });
|
|
45
|
-
env.TADA = 'TUDU';
|
|
46
|
-
const result = await deno.run(['test'], { env: { LULU: 'LALA' }, extendEnv: false });
|
|
47
|
-
let output = result?.stdout ?? '';
|
|
48
|
-
delete env.TADA;
|
|
49
|
-
referenceOutput?.stdout.split('\n').forEach((line) => {
|
|
50
|
-
output = output.replace(line.trim(), '');
|
|
51
|
-
});
|
|
52
|
-
output = output.trim().replace(/\n+/g, '\n');
|
|
53
|
-
expect(output).toBe('LULU=LALA');
|
|
54
|
-
await rm(tmpDir.path, { force: true, recursive: true, maxRetries: 10 });
|
|
55
|
-
});
|
|
56
|
-
test('Does inherit environment variables if `extendEnv` is true', async () => {
|
|
57
|
-
const tmpDir = await tmp.dir();
|
|
58
|
-
const deno = getMockDenoBridge(tmpDir, `#!/usr/bin/env sh
|
|
59
|
-
|
|
60
|
-
if [ "$1" = "test" ]
|
|
61
|
-
then
|
|
62
|
-
env
|
|
63
|
-
else
|
|
64
|
-
echo "deno @@@latestVersion@@@"
|
|
65
|
-
fi`);
|
|
66
|
-
// The environment sets some variables so let us see what they are and remove them from the result
|
|
67
|
-
const referenceOutput = await deno.run(['test'], { env: {}, extendEnv: true });
|
|
68
|
-
env.TADA = 'TUDU';
|
|
69
|
-
const result = await deno.run(['test'], { env: { LULU: 'LALA' }, extendEnv: true });
|
|
70
|
-
let output = result?.stdout ?? '';
|
|
71
|
-
delete env.TADA;
|
|
72
|
-
referenceOutput?.stdout.split('\n').forEach((line) => {
|
|
73
|
-
output = output.replace(line.trim(), '');
|
|
74
|
-
});
|
|
75
|
-
// lets remove holes, split lines and sort lines by name, as different OSes might order them different
|
|
76
|
-
const environmentVariables = output.trim().replace(/\n+/g, '\n').split('\n').sort();
|
|
77
|
-
expect(environmentVariables).toEqual(['LULU=LALA', 'TADA=TUDU']);
|
|
78
|
-
await rm(tmpDir.path, { force: true, recursive: true, maxRetries: 10 });
|
|
79
|
-
});
|
|
80
|
-
test('Does inherit environment variables if `extendEnv` is not set', async () => {
|
|
81
|
-
const tmpDir = await tmp.dir();
|
|
82
|
-
const deno = getMockDenoBridge(tmpDir, `#!/usr/bin/env sh
|
|
83
|
-
|
|
84
|
-
if [ "$1" = "test" ]
|
|
85
|
-
then
|
|
86
|
-
env
|
|
87
|
-
else
|
|
88
|
-
echo "deno @@@latestVersion@@@"
|
|
89
|
-
fi`);
|
|
90
|
-
// The environment sets some variables so let us see what they are and remove them from the result
|
|
91
|
-
const referenceOutput = await deno.run(['test'], { env: {}, extendEnv: true });
|
|
92
|
-
env.TADA = 'TUDU';
|
|
93
|
-
const result = await deno.run(['test'], { env: { LULU: 'LALA' } });
|
|
94
|
-
let output = result?.stdout ?? '';
|
|
95
|
-
delete env.TADA;
|
|
96
|
-
referenceOutput?.stdout.split('\n').forEach((line) => {
|
|
97
|
-
output = output.replace(line.trim(), '');
|
|
98
|
-
});
|
|
99
|
-
// lets remove holes, split lines and sort lines by name, as different OSes might order them different
|
|
100
|
-
const environmentVariables = output.trim().replace(/\n+/g, '\n').split('\n').sort();
|
|
101
|
-
expect(environmentVariables).toEqual(['LULU=LALA', 'TADA=TUDU']);
|
|
102
|
-
await rm(tmpDir.path, { force: true, recursive: true, maxRetries: 10 });
|
|
103
|
-
});
|
|
104
|
-
test('Provides actionable error message when downloaded binary cannot be executed', async () => {
|
|
105
|
-
const tmpDir = await tmp.dir();
|
|
106
|
-
const latestVersion = semver.minVersion(DENO_VERSION_RANGE)?.version ?? '';
|
|
107
|
-
const data = new PassThrough();
|
|
108
|
-
const archive = archiver('zip', { zlib: { level: 9 } });
|
|
109
|
-
archive.pipe(data);
|
|
110
|
-
// Create a binary that will fail to execute (invalid content)
|
|
111
|
-
archive.append(Buffer.from('invalid binary content'), {
|
|
112
|
-
name: platform === 'win32' ? 'deno.exe' : 'deno',
|
|
113
|
-
});
|
|
114
|
-
archive.finalize();
|
|
115
|
-
const target = getPlatformTarget();
|
|
116
|
-
nock('https://dl.deno.land').get('/release-latest.txt').reply(200, `v${latestVersion}`);
|
|
117
|
-
nock('https://dl.deno.land')
|
|
118
|
-
.get(`/release/v${latestVersion}/deno-${target}.zip`)
|
|
119
|
-
.reply(200, () => data);
|
|
120
|
-
const deno = new DenoBridge({
|
|
121
|
-
cacheDirectory: tmpDir.path,
|
|
122
|
-
useGlobal: false,
|
|
123
|
-
});
|
|
124
|
-
try {
|
|
125
|
-
await deno.getBinaryPath();
|
|
126
|
-
expect.fail('Should have thrown an error');
|
|
127
|
-
}
|
|
128
|
-
catch (error) {
|
|
129
|
-
expect(error).toBeInstanceOf(Error);
|
|
130
|
-
const errorMessage = error.message;
|
|
131
|
-
expect(errorMessage).toContain('Failed to set up Deno for Edge Functions');
|
|
132
|
-
expect(errorMessage).toMatch(/Error:/);
|
|
133
|
-
expect(errorMessage).toMatch(/Downloaded to: .+deno(\.exe)?/);
|
|
134
|
-
expect(errorMessage).toContain(tmpDir.path);
|
|
135
|
-
expect(errorMessage).toMatch(/Platform: (darwin|linux|win32)\/(x64|arm64|ia32)/);
|
|
136
|
-
expect(errorMessage).toContain('This may be caused by permissions, antivirus software, or platform incompatibility');
|
|
137
|
-
expect(errorMessage).toContain('Try clearing the Deno cache directory and retrying');
|
|
138
|
-
expect(errorMessage).toContain('https://ntl.fyi/install-deno');
|
|
139
|
-
}
|
|
140
|
-
await rm(tmpDir.path, { force: true, recursive: true, maxRetries: 10 });
|
|
141
|
-
});
|