@netlify/edge-bundler 14.2.1 → 14.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/deno/lib/common.ts +1 -1
- package/dist/node/bridge.d.ts +11 -9
- package/dist/node/bridge.js +8 -7
- package/dist/node/bundle.d.ts +2 -1
- package/dist/node/bundle.js +1 -0
- package/dist/node/bundler.js +20 -4
- package/dist/node/bundler.test.js +75 -3
- package/dist/node/declaration.js +3 -1
- package/dist/node/feature_flags.d.ts +6 -2
- package/dist/node/feature_flags.js +3 -1
- package/dist/node/formats/tarball.d.ts +18 -0
- package/dist/node/formats/tarball.js +92 -0
- package/dist/node/import_map.d.ts +5 -0
- package/dist/node/import_map.js +36 -4
- package/dist/node/manifest.test.js +5 -5
- package/dist/node/npm_dependencies.js +1 -1
- package/dist/node/server/server.test.js +7 -2
- package/dist/node/utils/sha256.d.ts +3 -2
- package/dist/node/utils/sha256.js +30 -5
- package/dist/node/utils/typescript.d.ts +1 -0
- package/dist/node/utils/typescript.js +1 -0
- package/dist/test/util.d.ts +14 -6
- package/dist/test/util.js +56 -11
- package/package.json +4 -3
package/deno/lib/common.ts
CHANGED
|
@@ -42,7 +42,7 @@ const loadWithRetry = (specifier: string, delay = 1000, maxTry = 3) => {
|
|
|
42
42
|
maxTry,
|
|
43
43
|
});
|
|
44
44
|
} catch (error) {
|
|
45
|
-
if (
|
|
45
|
+
if (error instanceof Error && isTooManyTries(error)) {
|
|
46
46
|
console.error(`Loading ${specifier} failed after ${maxTry} tries.`);
|
|
47
47
|
}
|
|
48
48
|
throw error;
|
package/dist/node/bridge.d.ts
CHANGED
|
@@ -1,23 +1,26 @@
|
|
|
1
1
|
import { type WriteStream } from 'fs';
|
|
2
2
|
import { type ExecaChildProcess } from 'execa';
|
|
3
|
+
import { FeatureFlags } from './feature_flags.js';
|
|
3
4
|
import { Logger } from './logger.js';
|
|
4
|
-
declare const DENO_VERSION_RANGE = "1.39.0 - 2.2.4";
|
|
5
|
-
type OnBeforeDownloadHook = () => void | Promise<void>;
|
|
6
|
-
type OnAfterDownloadHook = (error?: Error) => void | Promise<void>;
|
|
7
|
-
interface DenoOptions {
|
|
5
|
+
export declare const DENO_VERSION_RANGE = "1.39.0 - 2.2.4";
|
|
6
|
+
export type OnBeforeDownloadHook = () => void | Promise<void>;
|
|
7
|
+
export type OnAfterDownloadHook = (error?: Error) => void | Promise<void>;
|
|
8
|
+
export interface DenoOptions {
|
|
8
9
|
cacheDirectory?: string;
|
|
9
10
|
debug?: boolean;
|
|
10
11
|
denoDir?: string;
|
|
12
|
+
featureFlags?: FeatureFlags;
|
|
11
13
|
logger?: Logger;
|
|
12
14
|
onAfterDownload?: OnAfterDownloadHook;
|
|
13
15
|
onBeforeDownload?: OnBeforeDownloadHook;
|
|
14
16
|
useGlobal?: boolean;
|
|
15
17
|
versionRange?: string;
|
|
16
18
|
}
|
|
17
|
-
interface ProcessRef {
|
|
19
|
+
export interface ProcessRef {
|
|
18
20
|
ps?: ExecaChildProcess<string>;
|
|
19
21
|
}
|
|
20
22
|
interface RunOptions {
|
|
23
|
+
cwd?: string;
|
|
21
24
|
env?: NodeJS.ProcessEnv;
|
|
22
25
|
extendEnv?: boolean;
|
|
23
26
|
pipeOutput?: boolean;
|
|
@@ -25,7 +28,7 @@ interface RunOptions {
|
|
|
25
28
|
stdout?: WriteStream;
|
|
26
29
|
rejectOnExitCode?: boolean;
|
|
27
30
|
}
|
|
28
|
-
declare class DenoBridge {
|
|
31
|
+
export declare class DenoBridge {
|
|
29
32
|
cacheDirectory: string;
|
|
30
33
|
currentDownload?: ReturnType<DenoBridge['downloadBinary']>;
|
|
31
34
|
debug: boolean;
|
|
@@ -51,8 +54,7 @@ declare class DenoBridge {
|
|
|
51
54
|
path: string;
|
|
52
55
|
}>;
|
|
53
56
|
getEnvironmentVariables(inputEnv?: NodeJS.ProcessEnv): NodeJS.ProcessEnv;
|
|
54
|
-
run(args: string[], { env: inputEnv, extendEnv, rejectOnExitCode, stderr, stdout }?: RunOptions): Promise<import("execa").ExecaReturnValue<string>>;
|
|
57
|
+
run(args: string[], { cwd, env: inputEnv, extendEnv, rejectOnExitCode, stderr, stdout }?: RunOptions): Promise<import("execa").ExecaReturnValue<string>>;
|
|
55
58
|
runInBackground(args: string[], ref?: ProcessRef, { env: inputEnv, extendEnv, pipeOutput, stderr, stdout }?: RunOptions): Promise<void>;
|
|
56
59
|
}
|
|
57
|
-
export {
|
|
58
|
-
export type { DenoOptions, OnAfterDownloadHook, OnBeforeDownloadHook, ProcessRef };
|
|
60
|
+
export {};
|
package/dist/node/bridge.js
CHANGED
|
@@ -12,10 +12,11 @@ const DENO_VERSION_FILE = 'version.txt';
|
|
|
12
12
|
// When updating DENO_VERSION_RANGE, ensure that the deno version
|
|
13
13
|
// on the netlify/buildbot build image satisfies this range!
|
|
14
14
|
// https://github.com/netlify/buildbot/blob/f9c03c9dcb091d6570e9d0778381560d469e78ad/build-image/noble/Dockerfile#L410
|
|
15
|
-
const DENO_VERSION_RANGE = '1.39.0 - 2.2.4';
|
|
16
|
-
|
|
15
|
+
export const DENO_VERSION_RANGE = '1.39.0 - 2.2.4';
|
|
16
|
+
const NEXT_DENO_VERSION_RANGE = '^2.4.2';
|
|
17
|
+
export class DenoBridge {
|
|
17
18
|
constructor(options) {
|
|
18
|
-
var _a, _b, _c, _d, _e;
|
|
19
|
+
var _a, _b, _c, _d, _e, _f;
|
|
19
20
|
this.cacheDirectory = (_a = options.cacheDirectory) !== null && _a !== void 0 ? _a : getPathInHome('deno-cli');
|
|
20
21
|
this.debug = (_b = options.debug) !== null && _b !== void 0 ? _b : false;
|
|
21
22
|
this.denoDir = options.denoDir;
|
|
@@ -23,7 +24,8 @@ class DenoBridge {
|
|
|
23
24
|
this.onAfterDownload = options.onAfterDownload;
|
|
24
25
|
this.onBeforeDownload = options.onBeforeDownload;
|
|
25
26
|
this.useGlobal = (_d = options.useGlobal) !== null && _d !== void 0 ? _d : true;
|
|
26
|
-
this.versionRange =
|
|
27
|
+
this.versionRange =
|
|
28
|
+
(_e = options.versionRange) !== null && _e !== void 0 ? _e : (((_f = options.featureFlags) === null || _f === void 0 ? void 0 : _f.edge_bundler_generate_tarball) ? NEXT_DENO_VERSION_RANGE : DENO_VERSION_RANGE);
|
|
27
29
|
}
|
|
28
30
|
async downloadBinary() {
|
|
29
31
|
var _a, _b, _c;
|
|
@@ -148,10 +150,10 @@ class DenoBridge {
|
|
|
148
150
|
}
|
|
149
151
|
// Runs the Deno CLI in the background and returns a reference to the child
|
|
150
152
|
// process, awaiting its execution.
|
|
151
|
-
async run(args, { env: inputEnv, extendEnv = true, rejectOnExitCode = true, stderr, stdout } = {}) {
|
|
153
|
+
async run(args, { cwd, env: inputEnv, extendEnv = true, rejectOnExitCode = true, stderr, stdout } = {}) {
|
|
152
154
|
const { path: binaryPath } = await this.getBinaryPath();
|
|
153
155
|
const env = this.getEnvironmentVariables(inputEnv);
|
|
154
|
-
const options = { env, extendEnv, reject: rejectOnExitCode };
|
|
156
|
+
const options = { cwd, env, extendEnv, reject: rejectOnExitCode };
|
|
155
157
|
return DenoBridge.runWithBinary(binaryPath, args, { options, stderr, stdout });
|
|
156
158
|
}
|
|
157
159
|
// Runs the Deno CLI in the background, assigning a reference of the child
|
|
@@ -166,4 +168,3 @@ class DenoBridge {
|
|
|
166
168
|
}
|
|
167
169
|
}
|
|
168
170
|
}
|
|
169
|
-
export { DENO_VERSION_RANGE, DenoBridge };
|
package/dist/node/bundle.d.ts
CHANGED
package/dist/node/bundle.js
CHANGED
package/dist/node/bundler.js
CHANGED
|
@@ -10,6 +10,7 @@ import { load as loadDeployConfig } from './deploy_config.js';
|
|
|
10
10
|
import { getFlags } from './feature_flags.js';
|
|
11
11
|
import { findFunctions } from './finder.js';
|
|
12
12
|
import { bundle as bundleESZIP } from './formats/eszip.js';
|
|
13
|
+
import { bundle as bundleTarball } from './formats/tarball.js';
|
|
13
14
|
import { ImportMap } from './import_map.js';
|
|
14
15
|
import { getLogger } from './logger.js';
|
|
15
16
|
import { writeManifest } from './manifest.js';
|
|
@@ -22,6 +23,7 @@ export const bundle = async (sourceDirectories, distDirectory, tomlDeclarations
|
|
|
22
23
|
const options = {
|
|
23
24
|
debug,
|
|
24
25
|
cacheDirectory,
|
|
26
|
+
featureFlags,
|
|
25
27
|
logger,
|
|
26
28
|
onAfterDownload,
|
|
27
29
|
onBeforeDownload,
|
|
@@ -58,10 +60,24 @@ export const bundle = async (sourceDirectories, distDirectory, tomlDeclarations
|
|
|
58
60
|
rootPath: rootPath !== null && rootPath !== void 0 ? rootPath : basePath,
|
|
59
61
|
vendorDirectory,
|
|
60
62
|
});
|
|
63
|
+
const bundles = [];
|
|
64
|
+
if (featureFlags.edge_bundler_generate_tarball) {
|
|
65
|
+
bundles.push(await bundleTarball({
|
|
66
|
+
basePath,
|
|
67
|
+
buildID,
|
|
68
|
+
debug,
|
|
69
|
+
deno,
|
|
70
|
+
distDirectory,
|
|
71
|
+
functions,
|
|
72
|
+
featureFlags,
|
|
73
|
+
importMap: importMap.clone(),
|
|
74
|
+
vendorDirectory: vendor === null || vendor === void 0 ? void 0 : vendor.directory,
|
|
75
|
+
}));
|
|
76
|
+
}
|
|
61
77
|
if (vendor) {
|
|
62
78
|
importMap.add(vendor.importMap);
|
|
63
79
|
}
|
|
64
|
-
|
|
80
|
+
bundles.push(await bundleESZIP({
|
|
65
81
|
basePath,
|
|
66
82
|
buildID,
|
|
67
83
|
debug,
|
|
@@ -72,11 +88,11 @@ export const bundle = async (sourceDirectories, distDirectory, tomlDeclarations
|
|
|
72
88
|
featureFlags,
|
|
73
89
|
importMap,
|
|
74
90
|
vendorDirectory: vendor === null || vendor === void 0 ? void 0 : vendor.directory,
|
|
75
|
-
});
|
|
91
|
+
}));
|
|
76
92
|
// The final file name of the bundles contains a SHA256 hash of the contents,
|
|
77
93
|
// which we can only compute now that the files have been generated. So let's
|
|
78
94
|
// rename the bundles to their permanent names.
|
|
79
|
-
await createFinalBundles(
|
|
95
|
+
await createFinalBundles(bundles, distDirectory, buildID);
|
|
80
96
|
// Retrieving a configuration object for each function.
|
|
81
97
|
// Run `getFunctionConfig` in parallel as it is a non-trivial operation and spins up deno
|
|
82
98
|
const internalConfigPromises = internalFunctions.map(async (func) => [func.name, await getFunctionConfig({ func, importMap, deno, log: logger })]);
|
|
@@ -92,7 +108,7 @@ export const bundle = async (sourceDirectories, distDirectory, tomlDeclarations
|
|
|
92
108
|
declarations,
|
|
93
109
|
});
|
|
94
110
|
const manifest = await writeManifest({
|
|
95
|
-
bundles
|
|
111
|
+
bundles,
|
|
96
112
|
declarations,
|
|
97
113
|
distDirectory,
|
|
98
114
|
featureFlags,
|
|
@@ -1,12 +1,14 @@
|
|
|
1
1
|
import { Buffer } from 'buffer';
|
|
2
|
+
import { execSync } from 'node:child_process';
|
|
2
3
|
import { access, readdir, readFile, rm, writeFile } from 'fs/promises';
|
|
3
4
|
import { join, resolve } from 'path';
|
|
4
5
|
import process from 'process';
|
|
5
6
|
import { pathToFileURL } from 'url';
|
|
7
|
+
import { lt } from 'semver';
|
|
6
8
|
import tmp from 'tmp-promise';
|
|
7
|
-
import { test, expect, vi } from 'vitest';
|
|
9
|
+
import { test, expect, vi, describe } from 'vitest';
|
|
8
10
|
import { importMapSpecifier } from '../shared/consts.js';
|
|
9
|
-
import { runESZIP, useFixture } from '../test/util.js';
|
|
11
|
+
import { runESZIP, runTarball, useFixture } from '../test/util.js';
|
|
10
12
|
import { BundleError } from './bundle_error.js';
|
|
11
13
|
import { bundle } from './bundler.js';
|
|
12
14
|
import { isFileNotFoundError } from './utils/error.js';
|
|
@@ -398,7 +400,7 @@ test('Loads npm modules from bare specifiers', async () => {
|
|
|
398
400
|
const manifest = JSON.parse(manifestFile);
|
|
399
401
|
const bundlePath = join(distPath, manifest.bundles[0].asset);
|
|
400
402
|
const { func1 } = await runESZIP(bundlePath, vendorDirectory.path);
|
|
401
|
-
expect(func1).toBe(`<parent-1><child-1>JavaScript</child-1></parent-1>, <parent-2><child-2><grandchild-1>APIs<cwd>${process.cwd()}</cwd></grandchild-1></child-2></parent-2>, <parent-3><child-2><grandchild-1>Markup<cwd>${process.cwd()}</cwd></grandchild-1></child-2></parent-3
|
|
403
|
+
expect(func1).toBe(`<parent-1><child-1>JavaScript</child-1></parent-1>, <parent-2><child-2><grandchild-1>APIs<cwd>${process.cwd()}</cwd></grandchild-1></child-2></parent-2>, <parent-3><child-2><grandchild-1>Markup<cwd>${process.cwd()}</cwd></grandchild-1></child-2></parent-3>, TmV0bGlmeQ==`);
|
|
402
404
|
await cleanup();
|
|
403
405
|
await rm(vendorDirectory.path, { force: true, recursive: true });
|
|
404
406
|
});
|
|
@@ -550,3 +552,73 @@ test('Loads edge functions from the Frameworks API', async () => {
|
|
|
550
552
|
});
|
|
551
553
|
await cleanup();
|
|
552
554
|
});
|
|
555
|
+
const denoVersion = execSync('deno eval --no-lock "console.log(Deno.version.deno)"').toString();
|
|
556
|
+
describe.skipIf(lt(denoVersion, '2.4.2'))('Produces a tarball bundle', () => {
|
|
557
|
+
test('With only local imports', async () => {
|
|
558
|
+
const systemLogger = vi.fn();
|
|
559
|
+
const { basePath, cleanup, distPath } = await useFixture('imports_node_builtin', { copyDirectory: true });
|
|
560
|
+
const declarations = [
|
|
561
|
+
{
|
|
562
|
+
function: 'func1',
|
|
563
|
+
path: '/func1',
|
|
564
|
+
},
|
|
565
|
+
];
|
|
566
|
+
const vendorDirectory = await tmp.dir();
|
|
567
|
+
await bundle([join(basePath, 'netlify/edge-functions')], distPath, declarations, {
|
|
568
|
+
basePath,
|
|
569
|
+
configPath: join(basePath, '.netlify/edge-functions/config.json'),
|
|
570
|
+
featureFlags: {
|
|
571
|
+
edge_bundler_generate_tarball: true,
|
|
572
|
+
},
|
|
573
|
+
systemLogger,
|
|
574
|
+
});
|
|
575
|
+
expect(systemLogger.mock.calls.find((call) => call[0] === 'Could not track dependencies in edge function:')).toBeUndefined();
|
|
576
|
+
const expectedOutput = {
|
|
577
|
+
func1: 'ok',
|
|
578
|
+
};
|
|
579
|
+
const manifestFile = await readFile(resolve(distPath, 'manifest.json'), 'utf8');
|
|
580
|
+
const manifest = JSON.parse(manifestFile);
|
|
581
|
+
const tarballPath = join(distPath, manifest.bundles[0].asset);
|
|
582
|
+
const tarballResult = await runTarball(tarballPath);
|
|
583
|
+
expect(tarballResult).toStrictEqual(expectedOutput);
|
|
584
|
+
const eszipPath = join(distPath, manifest.bundles[1].asset);
|
|
585
|
+
const eszipResult = await runESZIP(eszipPath);
|
|
586
|
+
expect(eszipResult).toStrictEqual(expectedOutput);
|
|
587
|
+
await cleanup();
|
|
588
|
+
await rm(vendorDirectory.path, { force: true, recursive: true });
|
|
589
|
+
});
|
|
590
|
+
// TODO: https://github.com/denoland/deno/issues/30187
|
|
591
|
+
test.todo('Using npm modules', async () => {
|
|
592
|
+
const systemLogger = vi.fn();
|
|
593
|
+
const { basePath, cleanup, distPath } = await useFixture('imports_npm_module', { copyDirectory: true });
|
|
594
|
+
const sourceDirectory = join(basePath, 'functions');
|
|
595
|
+
const declarations = [
|
|
596
|
+
{
|
|
597
|
+
function: 'func1',
|
|
598
|
+
path: '/func1',
|
|
599
|
+
},
|
|
600
|
+
];
|
|
601
|
+
const vendorDirectory = await tmp.dir();
|
|
602
|
+
await bundle([sourceDirectory], distPath, declarations, {
|
|
603
|
+
basePath,
|
|
604
|
+
featureFlags: {
|
|
605
|
+
edge_bundler_generate_tarball: true,
|
|
606
|
+
},
|
|
607
|
+
importMapPaths: [join(basePath, 'import_map.json')],
|
|
608
|
+
vendorDirectory: vendorDirectory.path,
|
|
609
|
+
systemLogger,
|
|
610
|
+
});
|
|
611
|
+
expect(systemLogger.mock.calls.find((call) => call[0] === 'Could not track dependencies in edge function:')).toBeUndefined();
|
|
612
|
+
const expectedOutput = `<parent-1><child-1>JavaScript</child-1></parent-1>, <parent-2><child-2><grandchild-1>APIs<cwd>${process.cwd()}</cwd></grandchild-1></child-2></parent-2>, <parent-3><child-2><grandchild-1>Markup<cwd>${process.cwd()}</cwd></grandchild-1></child-2></parent-3>, TmV0bGlmeQ==`;
|
|
613
|
+
const manifestFile = await readFile(resolve(distPath, 'manifest.json'), 'utf8');
|
|
614
|
+
const manifest = JSON.parse(manifestFile);
|
|
615
|
+
const tarballPath = join(distPath, manifest.bundles[0].asset);
|
|
616
|
+
const tarballResult = await runTarball(tarballPath);
|
|
617
|
+
expect(tarballResult.func1).toBe(expectedOutput);
|
|
618
|
+
const eszipPath = join(distPath, manifest.bundles[1].asset);
|
|
619
|
+
const eszipResult = await runESZIP(eszipPath, vendorDirectory.path);
|
|
620
|
+
expect(eszipResult.func1).toBe(expectedOutput);
|
|
621
|
+
await cleanup();
|
|
622
|
+
await rm(vendorDirectory.path, { force: true, recursive: true });
|
|
623
|
+
});
|
|
624
|
+
}, 10000);
|
package/dist/node/declaration.js
CHANGED
|
@@ -133,7 +133,9 @@ export const getHeaderMatchers = (headers) => {
|
|
|
133
133
|
matchers[header] = { matcher: headers[header] ? 'exists' : 'missing' };
|
|
134
134
|
}
|
|
135
135
|
else if (typeof headers[header] === 'string') {
|
|
136
|
-
|
|
136
|
+
// Strip leading and forward slashes.
|
|
137
|
+
const pattern = new RegExp(headers[header]).toString().slice(1, -1);
|
|
138
|
+
matchers[header] = { matcher: 'regex', pattern };
|
|
137
139
|
}
|
|
138
140
|
else {
|
|
139
141
|
throw new BundleError(new Error(headerConfigError));
|
|
@@ -1,6 +1,10 @@
|
|
|
1
|
-
declare const defaultFlags: {
|
|
1
|
+
declare const defaultFlags: {
|
|
2
|
+
edge_bundler_generate_tarball: boolean;
|
|
3
|
+
};
|
|
2
4
|
type FeatureFlag = keyof typeof defaultFlags;
|
|
3
5
|
type FeatureFlags = Partial<Record<FeatureFlag, boolean>>;
|
|
4
|
-
declare const getFlags: (input?: Record<string, boolean>, flags?: {
|
|
6
|
+
declare const getFlags: (input?: Record<string, boolean>, flags?: {
|
|
7
|
+
edge_bundler_generate_tarball: boolean;
|
|
8
|
+
}) => FeatureFlags;
|
|
5
9
|
export { defaultFlags, getFlags };
|
|
6
10
|
export type { FeatureFlag, FeatureFlags };
|
|
@@ -1,4 +1,6 @@
|
|
|
1
|
-
const defaultFlags = {
|
|
1
|
+
const defaultFlags = {
|
|
2
|
+
edge_bundler_generate_tarball: false,
|
|
3
|
+
};
|
|
2
4
|
const getFlags = (input = {}, flags = defaultFlags) => Object.entries(flags).reduce((result, [key, defaultValue]) => ({
|
|
3
5
|
...result,
|
|
4
6
|
[key]: input[key] === undefined ? defaultValue : input[key],
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { DenoBridge } from '../bridge.js';
|
|
2
|
+
import { Bundle } from '../bundle.js';
|
|
3
|
+
import { EdgeFunction } from '../edge_function.js';
|
|
4
|
+
import { FeatureFlags } from '../feature_flags.js';
|
|
5
|
+
import { ImportMap } from '../import_map.js';
|
|
6
|
+
interface BundleTarballOptions {
|
|
7
|
+
basePath: string;
|
|
8
|
+
buildID: string;
|
|
9
|
+
debug?: boolean;
|
|
10
|
+
deno: DenoBridge;
|
|
11
|
+
distDirectory: string;
|
|
12
|
+
featureFlags: FeatureFlags;
|
|
13
|
+
functions: EdgeFunction[];
|
|
14
|
+
importMap: ImportMap;
|
|
15
|
+
vendorDirectory?: string;
|
|
16
|
+
}
|
|
17
|
+
export declare const bundle: ({ basePath, buildID, deno, distDirectory, functions, importMap, vendorDirectory, }: BundleTarballOptions) => Promise<Bundle>;
|
|
18
|
+
export {};
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
import { promises as fs } from 'fs';
|
|
2
|
+
import path from 'path';
|
|
3
|
+
import commonPathPrefix from 'common-path-prefix';
|
|
4
|
+
import * as tar from 'tar';
|
|
5
|
+
import tmp from 'tmp-promise';
|
|
6
|
+
import { BundleFormat } from '../bundle.js';
|
|
7
|
+
import { getDirectoryHash, getStringHash } from '../utils/sha256.js';
|
|
8
|
+
const TARBALL_EXTENSION = '.tar';
|
|
9
|
+
const getUnixPath = (input) => input.split(path.sep).join('/');
|
|
10
|
+
export const bundle = async ({ basePath, buildID, deno, distDirectory, functions, importMap, vendorDirectory, }) => {
|
|
11
|
+
const sideFilesDir = await tmp.dir({ unsafeCleanup: true });
|
|
12
|
+
const cleanup = [sideFilesDir.cleanup];
|
|
13
|
+
let denoDir = vendorDirectory ? path.join(vendorDirectory, 'deno_dir') : undefined;
|
|
14
|
+
if (!denoDir) {
|
|
15
|
+
const tmpDir = await tmp.dir({ unsafeCleanup: true });
|
|
16
|
+
denoDir = tmpDir.path;
|
|
17
|
+
cleanup.push(tmpDir.cleanup);
|
|
18
|
+
}
|
|
19
|
+
const manifest = {
|
|
20
|
+
functions: {},
|
|
21
|
+
version: 1,
|
|
22
|
+
};
|
|
23
|
+
const entryPoints = functions.map((func) => func.path);
|
|
24
|
+
// `deno bundle` does not return the paths of the files it emits, so we have
|
|
25
|
+
// to infer them. When multiple entry points are supplied, it will find the
|
|
26
|
+
// common path prefix and use that as the base directory in `outdir`. When
|
|
27
|
+
// using a single entry point, `commonPathPrefix` returns an empty string,
|
|
28
|
+
// so we use the path of the first entry point's directory.
|
|
29
|
+
const commonPath = commonPathPrefix(entryPoints) || path.dirname(entryPoints[0]);
|
|
30
|
+
for (const func of functions) {
|
|
31
|
+
const relativePath = path.relative(commonPath, func.path);
|
|
32
|
+
const bundledPath = path.format({
|
|
33
|
+
...path.parse(relativePath),
|
|
34
|
+
base: undefined,
|
|
35
|
+
ext: '.js',
|
|
36
|
+
});
|
|
37
|
+
manifest.functions[func.name] = getUnixPath(bundledPath);
|
|
38
|
+
}
|
|
39
|
+
await deno.run([
|
|
40
|
+
'bundle',
|
|
41
|
+
'--import-map',
|
|
42
|
+
importMap.withNodeBuiltins().toDataURL(),
|
|
43
|
+
'--quiet',
|
|
44
|
+
'--code-splitting',
|
|
45
|
+
'--outdir',
|
|
46
|
+
distDirectory,
|
|
47
|
+
...functions.map((func) => func.path),
|
|
48
|
+
], {
|
|
49
|
+
cwd: basePath,
|
|
50
|
+
});
|
|
51
|
+
const manifestPath = path.join(sideFilesDir.path, 'manifest.json');
|
|
52
|
+
const manifestContents = JSON.stringify(manifest);
|
|
53
|
+
await fs.writeFile(manifestPath, manifestContents);
|
|
54
|
+
const denoConfigPath = path.join(sideFilesDir.path, 'deno.json');
|
|
55
|
+
const denoConfigContents = JSON.stringify(importMap.getContentsWithRelativePaths());
|
|
56
|
+
await fs.writeFile(denoConfigPath, denoConfigContents);
|
|
57
|
+
const rootLevel = await fs.readdir(distDirectory);
|
|
58
|
+
const hash = await getDirectoryHash(distDirectory);
|
|
59
|
+
const tarballPath = path.join(distDirectory, buildID + TARBALL_EXTENSION);
|
|
60
|
+
await fs.mkdir(path.dirname(tarballPath), { recursive: true });
|
|
61
|
+
// Adding all the bundled files.
|
|
62
|
+
await tar.create({
|
|
63
|
+
cwd: distDirectory,
|
|
64
|
+
file: tarballPath,
|
|
65
|
+
onWriteEntry(entry) {
|
|
66
|
+
entry.path = getUnixPath(`./${entry.path}`);
|
|
67
|
+
},
|
|
68
|
+
}, rootLevel);
|
|
69
|
+
// Adding `deno.json`.
|
|
70
|
+
await tar.update({
|
|
71
|
+
cwd: distDirectory,
|
|
72
|
+
file: tarballPath,
|
|
73
|
+
onWriteEntry(entry) {
|
|
74
|
+
entry.path = './deno.json';
|
|
75
|
+
},
|
|
76
|
+
}, [denoConfigPath]);
|
|
77
|
+
// Adding the manifest file.
|
|
78
|
+
await tar.update({
|
|
79
|
+
cwd: distDirectory,
|
|
80
|
+
file: tarballPath,
|
|
81
|
+
onWriteEntry(entry) {
|
|
82
|
+
entry.path = './___netlify-edge-functions.json';
|
|
83
|
+
},
|
|
84
|
+
}, [manifestPath]);
|
|
85
|
+
await Promise.all(cleanup);
|
|
86
|
+
const finalHash = [hash, getStringHash(manifestContents), getStringHash(denoConfigContents)].join('');
|
|
87
|
+
return {
|
|
88
|
+
extension: TARBALL_EXTENSION,
|
|
89
|
+
format: BundleFormat.TARBALL,
|
|
90
|
+
hash: finalHash,
|
|
91
|
+
};
|
|
92
|
+
};
|
|
@@ -24,6 +24,10 @@ export declare class ImportMap {
|
|
|
24
24
|
imports: Imports;
|
|
25
25
|
scopes: {};
|
|
26
26
|
};
|
|
27
|
+
getContentsWithRelativePaths(): {
|
|
28
|
+
imports: Imports;
|
|
29
|
+
scopes: Record<string, Imports>;
|
|
30
|
+
};
|
|
27
31
|
getContentsWithURLObjects(prefixes?: Record<string, string>): {
|
|
28
32
|
imports: Record<string, URL>;
|
|
29
33
|
scopes: Record<string, Record<string, URL>>;
|
|
@@ -34,6 +38,7 @@ export declare class ImportMap {
|
|
|
34
38
|
scopes: Record<string, Imports>;
|
|
35
39
|
};
|
|
36
40
|
toDataURL(): string;
|
|
41
|
+
withNodeBuiltins(): this;
|
|
37
42
|
writeToFile(path: string): Promise<void>;
|
|
38
43
|
}
|
|
39
44
|
export {};
|
package/dist/node/import_map.js
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
|
-
import { Buffer } from 'buffer';
|
|
2
|
-
import { promises as fs } from 'fs';
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
1
|
+
import { Buffer } from 'node:buffer';
|
|
2
|
+
import { promises as fs } from 'node:fs';
|
|
3
|
+
import { builtinModules } from 'node:module';
|
|
4
|
+
import { dirname, relative } from 'node:path';
|
|
5
|
+
import { fileURLToPath, pathToFileURL } from 'node:url';
|
|
5
6
|
import { parse } from '@import-maps/resolve';
|
|
6
7
|
import { isFileNotFoundError } from './utils/error.js';
|
|
7
8
|
const INTERNAL_IMPORTS = {
|
|
@@ -134,6 +135,24 @@ export class ImportMap {
|
|
|
134
135
|
scopes: transformedScopes,
|
|
135
136
|
};
|
|
136
137
|
}
|
|
138
|
+
getContentsWithRelativePaths() {
|
|
139
|
+
let imports = {};
|
|
140
|
+
let scopes = {};
|
|
141
|
+
this.sources.forEach((file) => {
|
|
142
|
+
imports = { ...imports, ...file.imports };
|
|
143
|
+
scopes = { ...scopes, ...file.scopes };
|
|
144
|
+
});
|
|
145
|
+
// Internal imports must come last, because we need to guarantee that
|
|
146
|
+
// `netlify:edge` isn't user-defined.
|
|
147
|
+
Object.entries(INTERNAL_IMPORTS).forEach((internalImport) => {
|
|
148
|
+
const [specifier, url] = internalImport;
|
|
149
|
+
imports[specifier] = url;
|
|
150
|
+
});
|
|
151
|
+
return {
|
|
152
|
+
imports,
|
|
153
|
+
scopes,
|
|
154
|
+
};
|
|
155
|
+
}
|
|
137
156
|
// The same as `getContents`, but the URLs are represented as URL objects
|
|
138
157
|
// instead of strings. This is compatible with the `ParsedImportMap` type
|
|
139
158
|
// from the `@import-maps/resolve` library.
|
|
@@ -182,6 +201,19 @@ export class ImportMap {
|
|
|
182
201
|
const encodedImportMap = Buffer.from(data).toString('base64');
|
|
183
202
|
return `data:application/json;base64,${encodedImportMap}`;
|
|
184
203
|
}
|
|
204
|
+
// Adds an import map source mapping Node.js built-in modules to their prefixed
|
|
205
|
+
// version (e.g. "path" => "node:path").
|
|
206
|
+
withNodeBuiltins() {
|
|
207
|
+
const imports = {};
|
|
208
|
+
for (const name of builtinModules) {
|
|
209
|
+
imports[name] = `node:${name}`;
|
|
210
|
+
}
|
|
211
|
+
this.sources.push({
|
|
212
|
+
baseURL: new URL(import.meta.url),
|
|
213
|
+
imports,
|
|
214
|
+
});
|
|
215
|
+
return this;
|
|
216
|
+
}
|
|
185
217
|
async writeToFile(path) {
|
|
186
218
|
const distDirectory = dirname(path);
|
|
187
219
|
await fs.mkdir(distDirectory, { recursive: true });
|
|
@@ -551,9 +551,9 @@ describe('Header matching', () => {
|
|
|
551
551
|
'x-present': true,
|
|
552
552
|
'x-also-present': true,
|
|
553
553
|
'x-absent': false,
|
|
554
|
-
'x-match-prefix': '^prefix
|
|
555
|
-
'x-match-exact': 'exact',
|
|
556
|
-
'x-match-suffix': '
|
|
554
|
+
'x-match-prefix': '^prefix',
|
|
555
|
+
'x-match-exact': '^exact$',
|
|
556
|
+
'x-match-suffix': 'suffix$',
|
|
557
557
|
},
|
|
558
558
|
},
|
|
559
559
|
];
|
|
@@ -580,11 +580,11 @@ describe('Header matching', () => {
|
|
|
580
580
|
matcher: 'regex',
|
|
581
581
|
},
|
|
582
582
|
'x-match-prefix': {
|
|
583
|
-
pattern: '^prefix
|
|
583
|
+
pattern: '^prefix',
|
|
584
584
|
matcher: 'regex',
|
|
585
585
|
},
|
|
586
586
|
'x-match-suffix': {
|
|
587
|
-
pattern: '
|
|
587
|
+
pattern: 'suffix$',
|
|
588
588
|
matcher: 'regex',
|
|
589
589
|
},
|
|
590
590
|
'x-present': {
|
|
@@ -8,7 +8,7 @@ import { findUp } from 'find-up';
|
|
|
8
8
|
import { parseImports } from 'parse-imports';
|
|
9
9
|
import tmp from 'tmp-promise';
|
|
10
10
|
import { pathsBetween } from './utils/fs.js';
|
|
11
|
-
|
|
11
|
+
import { TYPESCRIPT_EXTENSIONS } from './utils/typescript.js';
|
|
12
12
|
const slugifyFileName = (specifier) => {
|
|
13
13
|
return specifier.replace(/\//g, '_');
|
|
14
14
|
};
|
|
@@ -2,6 +2,11 @@ import { createWriteStream } from 'fs';
|
|
|
2
2
|
import { readFile } from 'fs/promises';
|
|
3
3
|
import { join } from 'path';
|
|
4
4
|
import process from 'process';
|
|
5
|
+
// @ts-expect-error TypeScript is complaining about the values for the `module`
|
|
6
|
+
// and `moduleResolution` configuration properties, but changing those to more
|
|
7
|
+
// modern values causes other packages to fail. Leaving this for now, but we
|
|
8
|
+
// should have a proper fix for this.
|
|
9
|
+
import { getURL as getBootstrapURL } from '@netlify/edge-functions-bootstrap/version';
|
|
5
10
|
import getPort from 'get-port';
|
|
6
11
|
import tmp from 'tmp-promise';
|
|
7
12
|
import { v4 as uuidv4 } from 'uuid';
|
|
@@ -19,7 +24,7 @@ test('Starts a server and serves requests for edge functions', async () => {
|
|
|
19
24
|
const servePath = join(basePath, '.netlify', 'edge-functions-serve');
|
|
20
25
|
const server = await serve({
|
|
21
26
|
basePath,
|
|
22
|
-
bootstrapURL:
|
|
27
|
+
bootstrapURL: await getBootstrapURL(),
|
|
23
28
|
port,
|
|
24
29
|
servePath,
|
|
25
30
|
});
|
|
@@ -99,7 +104,7 @@ test('Serves edge functions in a monorepo setup', async () => {
|
|
|
99
104
|
const servePath = join(basePath, '.netlify', 'edge-functions-serve');
|
|
100
105
|
const server = await serve({
|
|
101
106
|
basePath,
|
|
102
|
-
bootstrapURL:
|
|
107
|
+
bootstrapURL: await getBootstrapURL(),
|
|
103
108
|
port,
|
|
104
109
|
rootPath,
|
|
105
110
|
servePath,
|
|
@@ -1,2 +1,3 @@
|
|
|
1
|
-
declare const
|
|
2
|
-
export
|
|
1
|
+
export declare const getDirectoryHash: (dirPath: string) => Promise<string>;
|
|
2
|
+
export declare const getFileHash: (path: string) => Promise<string>;
|
|
3
|
+
export declare const getStringHash: (input: string) => string;
|
|
@@ -1,10 +1,30 @@
|
|
|
1
|
-
import crypto from 'crypto';
|
|
2
|
-
import fs from 'fs';
|
|
3
|
-
|
|
1
|
+
import crypto from 'node:crypto';
|
|
2
|
+
import { createReadStream, promises as fs } from 'node:fs';
|
|
3
|
+
import path from 'node:path';
|
|
4
|
+
export const getDirectoryHash = async (dirPath) => {
|
|
5
|
+
const entries = [];
|
|
6
|
+
async function walk(currentPath) {
|
|
7
|
+
const dirents = await fs.readdir(currentPath, { withFileTypes: true });
|
|
8
|
+
for (const dirent of dirents) {
|
|
9
|
+
const fullPath = path.join(currentPath, dirent.name);
|
|
10
|
+
const relativePath = path.relative(dirPath, fullPath);
|
|
11
|
+
if (dirent.isDirectory()) {
|
|
12
|
+
await walk(fullPath);
|
|
13
|
+
}
|
|
14
|
+
else if (dirent.isFile() || dirent.isSymbolicLink()) {
|
|
15
|
+
const fileHash = await getFileHash(fullPath);
|
|
16
|
+
entries.push(`${relativePath}:${fileHash}`);
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
await walk(dirPath);
|
|
21
|
+
return getStringHash(entries.sort((a, b) => a.localeCompare(b)).join('\n'));
|
|
22
|
+
};
|
|
23
|
+
export const getFileHash = (path) => {
|
|
4
24
|
const hash = crypto.createHash('sha256');
|
|
5
25
|
hash.setEncoding('hex');
|
|
6
26
|
return new Promise((resolve, reject) => {
|
|
7
|
-
const file =
|
|
27
|
+
const file = createReadStream(path);
|
|
8
28
|
file.on('end', () => {
|
|
9
29
|
hash.end();
|
|
10
30
|
resolve(hash.read());
|
|
@@ -13,4 +33,9 @@ const getFileHash = (path) => {
|
|
|
13
33
|
file.pipe(hash);
|
|
14
34
|
});
|
|
15
35
|
};
|
|
16
|
-
export
|
|
36
|
+
export const getStringHash = (input) => {
|
|
37
|
+
const hash = crypto.createHash('sha256');
|
|
38
|
+
hash.setEncoding('hex');
|
|
39
|
+
hash.update(input);
|
|
40
|
+
return hash.digest('hex');
|
|
41
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const TYPESCRIPT_EXTENSIONS: Set<string>;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export const TYPESCRIPT_EXTENSIONS = new Set(['.ts', '.tsx', '.cts', '.ctsx', '.mts', '.mtsx']);
|
package/dist/test/util.d.ts
CHANGED
|
@@ -1,11 +1,19 @@
|
|
|
1
1
|
import type { Manifest } from '../node/manifest.js';
|
|
2
|
-
declare const testLogger: import("../node/logger.js").Logger;
|
|
3
|
-
declare const fixturesDir: string;
|
|
4
|
-
|
|
2
|
+
export declare const testLogger: import("../node/logger.js").Logger;
|
|
3
|
+
export declare const fixturesDir: string;
|
|
4
|
+
interface UseFixtureOptions {
|
|
5
|
+
copyDirectory?: boolean;
|
|
6
|
+
}
|
|
7
|
+
export declare const useFixture: (fixtureName: string, { copyDirectory }?: UseFixtureOptions) => Promise<{
|
|
8
|
+
basePath: string;
|
|
9
|
+
cleanup: () => Promise<[PromiseSettledResult<() => Promise<void>>, PromiseSettledResult<() => Promise<void>>]>;
|
|
10
|
+
distPath: string;
|
|
11
|
+
} | {
|
|
5
12
|
basePath: string;
|
|
6
13
|
cleanup: () => Promise<void>;
|
|
7
14
|
distPath: string;
|
|
8
15
|
}>;
|
|
9
|
-
declare const getRouteMatcher: (manifest: Manifest) => (candidate: string) => import("../node/manifest.js").Route | undefined;
|
|
10
|
-
declare const runESZIP: (eszipPath: string, vendorDirectory?: string) => Promise<any>;
|
|
11
|
-
export
|
|
16
|
+
export declare const getRouteMatcher: (manifest: Manifest) => (candidate: string) => import("../node/manifest.js").Route | undefined;
|
|
17
|
+
export declare const runESZIP: (eszipPath: string, vendorDirectory?: string) => Promise<any>;
|
|
18
|
+
export declare const runTarball: (tarballPath: string) => Promise<any>;
|
|
19
|
+
export {};
|
package/dist/test/util.js
CHANGED
|
@@ -2,26 +2,38 @@ import { promises as fs } from 'fs';
|
|
|
2
2
|
import { join, resolve } from 'path';
|
|
3
3
|
import { stderr, stdout } from 'process';
|
|
4
4
|
import { fileURLToPath, pathToFileURL } from 'url';
|
|
5
|
+
import cpy from 'cpy';
|
|
5
6
|
import { execa } from 'execa';
|
|
7
|
+
import * as tar from 'tar';
|
|
6
8
|
import tmp from 'tmp-promise';
|
|
7
9
|
import { getLogger } from '../node/logger.js';
|
|
8
|
-
const testLogger = getLogger(() => {
|
|
10
|
+
export const testLogger = getLogger(() => {
|
|
9
11
|
// no-op
|
|
10
12
|
});
|
|
11
13
|
const url = new URL(import.meta.url);
|
|
12
14
|
const dirname = fileURLToPath(url);
|
|
13
|
-
const fixturesDir = resolve(dirname, '..', 'fixtures');
|
|
14
|
-
const useFixture = async (fixtureName) => {
|
|
15
|
-
const
|
|
15
|
+
export const fixturesDir = resolve(dirname, '..', 'fixtures');
|
|
16
|
+
export const useFixture = async (fixtureName, { copyDirectory } = {}) => {
|
|
17
|
+
const tmpDistDir = await tmp.dir({ unsafeCleanup: true });
|
|
16
18
|
const fixtureDir = resolve(fixturesDir, fixtureName);
|
|
17
|
-
const distPath = join(
|
|
19
|
+
const distPath = join(tmpDistDir.path, '.netlify', 'edge-functions-dist');
|
|
20
|
+
if (copyDirectory) {
|
|
21
|
+
const tmpFixtureDir = await tmp.dir({ unsafeCleanup: true });
|
|
22
|
+
// TODO: Replace with `fs.cp` once the Node.js version range allows.
|
|
23
|
+
await cpy(`${fixtureDir}/**`, tmpFixtureDir.path);
|
|
24
|
+
return {
|
|
25
|
+
basePath: tmpFixtureDir.path,
|
|
26
|
+
cleanup: () => Promise.allSettled([tmpDistDir.cleanup, tmpFixtureDir.cleanup]),
|
|
27
|
+
distPath,
|
|
28
|
+
};
|
|
29
|
+
}
|
|
18
30
|
return {
|
|
19
31
|
basePath: fixtureDir,
|
|
20
|
-
cleanup:
|
|
32
|
+
cleanup: tmpDistDir.cleanup,
|
|
21
33
|
distPath,
|
|
22
34
|
};
|
|
23
35
|
};
|
|
24
|
-
const
|
|
36
|
+
const inspectESZIPFunction = (path) => `
|
|
25
37
|
import { functions } from "${pathToFileURL(path)}.js";
|
|
26
38
|
|
|
27
39
|
const responses = {};
|
|
@@ -35,7 +47,25 @@ const inspectFunction = (path) => `
|
|
|
35
47
|
|
|
36
48
|
console.log(JSON.stringify(responses));
|
|
37
49
|
`;
|
|
38
|
-
const
|
|
50
|
+
const inspectTarballFunction = () => `
|
|
51
|
+
import path from "node:path";
|
|
52
|
+
import { pathToFileURL } from "node:url";
|
|
53
|
+
import manifest from "./___netlify-edge-functions.json" with { type: "json" };
|
|
54
|
+
|
|
55
|
+
const responses = {};
|
|
56
|
+
|
|
57
|
+
for (const functionName in manifest.functions) {
|
|
58
|
+
const req = new Request("https://test.netlify");
|
|
59
|
+
const entrypoint = path.resolve(manifest.functions[functionName]);
|
|
60
|
+
const func = await import(pathToFileURL(entrypoint))
|
|
61
|
+
const res = await func.default(req);
|
|
62
|
+
|
|
63
|
+
responses[functionName] = await res.text();
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
console.log(JSON.stringify(responses));
|
|
67
|
+
`;
|
|
68
|
+
export const getRouteMatcher = (manifest) => (candidate) => manifest.routes.find((route) => {
|
|
39
69
|
var _a, _b;
|
|
40
70
|
const regex = new RegExp(route.pattern);
|
|
41
71
|
if (!regex.test(candidate)) {
|
|
@@ -48,13 +78,14 @@ const getRouteMatcher = (manifest) => (candidate) => manifest.routes.find((route
|
|
|
48
78
|
const isExcluded = excludedPatterns.some((pattern) => new RegExp(pattern).test(candidate));
|
|
49
79
|
return !isExcluded;
|
|
50
80
|
});
|
|
51
|
-
const runESZIP = async (eszipPath, vendorDirectory) => {
|
|
81
|
+
export const runESZIP = async (eszipPath, vendorDirectory) => {
|
|
52
82
|
var _a, _b, _c;
|
|
53
83
|
const tmpDir = await tmp.dir({ unsafeCleanup: true });
|
|
54
84
|
// Extract ESZIP into temporary directory.
|
|
55
85
|
const extractCommand = execa('deno', [
|
|
56
86
|
'run',
|
|
57
87
|
'--allow-all',
|
|
88
|
+
'--no-lock',
|
|
58
89
|
'https://deno.land/x/eszip@v0.55.2/eszip.ts',
|
|
59
90
|
'x',
|
|
60
91
|
eszipPath,
|
|
@@ -76,10 +107,24 @@ const runESZIP = async (eszipPath, vendorDirectory) => {
|
|
|
76
107
|
}
|
|
77
108
|
await fs.rename(stage2Path, `${stage2Path}.js`);
|
|
78
109
|
// Run function that imports the extracted stage 2 and invokes each function.
|
|
79
|
-
const evalCommand = execa('deno', ['eval', '--import-map', importMapPath,
|
|
110
|
+
const evalCommand = execa('deno', ['eval', '--import-map', importMapPath, inspectESZIPFunction(stage2Path)]);
|
|
80
111
|
(_c = evalCommand.stderr) === null || _c === void 0 ? void 0 : _c.pipe(stderr);
|
|
81
112
|
const result = await evalCommand;
|
|
82
113
|
await tmpDir.cleanup();
|
|
83
114
|
return JSON.parse(result.stdout);
|
|
84
115
|
};
|
|
85
|
-
export
|
|
116
|
+
export const runTarball = async (tarballPath) => {
|
|
117
|
+
var _a;
|
|
118
|
+
const tmpDir = await tmp.dir({ unsafeCleanup: true });
|
|
119
|
+
await tar.extract({
|
|
120
|
+
cwd: tmpDir.path,
|
|
121
|
+
file: tarballPath,
|
|
122
|
+
});
|
|
123
|
+
const evalCommand = execa('deno', ['eval', inspectTarballFunction()], {
|
|
124
|
+
cwd: tmpDir.path,
|
|
125
|
+
});
|
|
126
|
+
(_a = evalCommand.stderr) === null || _a === void 0 ? void 0 : _a.pipe(stderr);
|
|
127
|
+
const result = await evalCommand;
|
|
128
|
+
await tmpDir.cleanup();
|
|
129
|
+
return JSON.parse(result.stdout);
|
|
130
|
+
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@netlify/edge-bundler",
|
|
3
|
-
"version": "14.
|
|
3
|
+
"version": "14.3.0",
|
|
4
4
|
"description": "Intelligently prepare Netlify Edge Functions for deployment",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/node/index.js",
|
|
@@ -42,6 +42,7 @@
|
|
|
42
42
|
"test": "test/node"
|
|
43
43
|
},
|
|
44
44
|
"devDependencies": {
|
|
45
|
+
"@netlify/edge-functions-bootstrap": "^2.14.0",
|
|
45
46
|
"@types/node": "^18.19.111",
|
|
46
47
|
"@types/semver": "^7.3.9",
|
|
47
48
|
"@types/uuid": "^10.0.0",
|
|
@@ -51,7 +52,6 @@
|
|
|
51
52
|
"cpy": "^11.1.0",
|
|
52
53
|
"nock": "^14.0.0",
|
|
53
54
|
"npm-run-all2": "^6.0.0",
|
|
54
|
-
"tar": "^7.0.0",
|
|
55
55
|
"typescript": "^5.0.0",
|
|
56
56
|
"vitest": "^3.0.0"
|
|
57
57
|
},
|
|
@@ -77,9 +77,10 @@
|
|
|
77
77
|
"parse-imports": "^2.2.1",
|
|
78
78
|
"path-key": "^4.0.0",
|
|
79
79
|
"semver": "^7.3.8",
|
|
80
|
+
"tar": "^7.4.3",
|
|
80
81
|
"tmp-promise": "^3.0.3",
|
|
81
82
|
"urlpattern-polyfill": "8.0.2",
|
|
82
83
|
"uuid": "^11.0.0"
|
|
83
84
|
},
|
|
84
|
-
"gitHead": "
|
|
85
|
+
"gitHead": "f65a08178a04db0ad274aa62f7d46319f2ef661a"
|
|
85
86
|
}
|