@netlify/edge-bundler 8.12.1 → 8.12.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -25,8 +25,8 @@ export declare const addGeneratorFieldIfMissing: (declaration: Declaration, func
25
25
  cache?: string | undefined;
26
26
  function: string;
27
27
  name?: string | undefined;
28
- path: string;
29
- excludedPath?: string | undefined;
28
+ path: `/${string}`;
29
+ excludedPath?: `/${string}` | undefined;
30
30
  } | {
31
31
  generator: string | undefined;
32
32
  cache?: string | undefined;
@@ -7,12 +7,13 @@ export declare const enum Cache {
7
7
  Off = "off",
8
8
  Manual = "manual"
9
9
  }
10
+ export type Path = `/${string}`;
10
11
  export type OnError = 'fail' | 'bypass' | `/${string}`;
11
12
  export declare const isValidOnError: (value: unknown) => value is OnError;
12
13
  export interface FunctionConfig {
13
14
  cache?: Cache;
14
- path?: string | string[];
15
- excludedPath?: string | string[];
15
+ path?: Path | Path[];
16
+ excludedPath?: Path | Path[];
16
17
  onError?: OnError;
17
18
  }
18
19
  export declare const getFunctionConfig: (func: EdgeFunction, importMap: ImportMap, deno: DenoBridge, log: Logger, featureFlags: FeatureFlags) => Promise<FunctionConfig>;
@@ -1,4 +1,4 @@
1
- import { FunctionConfig } from './config.js';
1
+ import { FunctionConfig, Path } from './config.js';
2
2
  interface BaseDeclaration {
3
3
  cache?: string;
4
4
  function: string;
@@ -6,8 +6,8 @@ interface BaseDeclaration {
6
6
  generator?: string;
7
7
  }
8
8
  type DeclarationWithPath = BaseDeclaration & {
9
- path: string;
10
- excludedPath?: string;
9
+ path: Path;
10
+ excludedPath?: Path;
11
11
  };
12
12
  type DeclarationWithPattern = BaseDeclaration & {
13
13
  pattern: string;
@@ -1,12 +1,14 @@
1
1
  declare const defaultFlags: {
2
2
  edge_functions_fail_unsupported_regex: boolean;
3
3
  edge_functions_invalid_config_throw: boolean;
4
+ edge_functions_manifest_validate_slash: boolean;
4
5
  };
5
6
  type FeatureFlag = keyof typeof defaultFlags;
6
7
  type FeatureFlags = Partial<Record<FeatureFlag, boolean>>;
7
8
  declare const getFlags: (input?: Record<string, boolean>, flags?: {
8
9
  edge_functions_fail_unsupported_regex: boolean;
9
10
  edge_functions_invalid_config_throw: boolean;
11
+ edge_functions_manifest_validate_slash: boolean;
10
12
  }) => FeatureFlags;
11
13
  export { defaultFlags, getFlags };
12
14
  export type { FeatureFlag, FeatureFlags };
@@ -1,6 +1,7 @@
1
1
  const defaultFlags = {
2
2
  edge_functions_fail_unsupported_regex: false,
3
3
  edge_functions_invalid_config_throw: false,
4
+ edge_functions_manifest_validate_slash: false,
4
5
  };
5
6
  const getFlags = (input = {}, flags = defaultFlags) => Object.entries(flags).reduce((result, [key, defaultValue]) => ({
6
7
  ...result,
@@ -1,3 +1,4 @@
1
+ import { FeatureFlags } from '../../feature_flags.js';
1
2
  import ManifestValidationError from './error.js';
2
- export declare const validateManifest: (manifestData: unknown) => void;
3
+ export declare const validateManifest: (manifestData: unknown, featureFlags?: FeatureFlags) => void;
3
4
  export { ManifestValidationError };
@@ -4,13 +4,13 @@ import betterAjvErrors from 'better-ajv-errors';
4
4
  import ManifestValidationError from './error.js';
5
5
  import edgeManifestSchema from './schema.js';
6
6
  let manifestValidator;
7
- const initializeValidator = () => {
7
+ const initializeValidator = (featureFlags) => {
8
8
  if (manifestValidator === undefined) {
9
9
  const ajv = new Ajv({ allErrors: true });
10
10
  ajvErrors(ajv);
11
11
  // regex pattern for manifest route pattern
12
12
  // checks if the pattern string starts with ^ and ends with $
13
- const normalizedPatternRegex = /^\^.*\$$/;
13
+ const normalizedPatternRegex = featureFlags.edge_functions_manifest_validate_slash ? /^\^\/.*\$$/ : /^\^.*\$$/;
14
14
  ajv.addFormat('regexPattern', {
15
15
  validate: (data) => normalizedPatternRegex.test(data),
16
16
  });
@@ -19,8 +19,8 @@ const initializeValidator = () => {
19
19
  return manifestValidator;
20
20
  };
21
21
  // throws on validation error
22
- export const validateManifest = (manifestData) => {
23
- const validate = initializeValidator();
22
+ export const validateManifest = (manifestData, featureFlags = {}) => {
23
+ const validate = initializeValidator(featureFlags);
24
24
  const valid = validate(manifestData);
25
25
  if (!valid) {
26
26
  let errorOutput;
@@ -1,5 +1,5 @@
1
1
  import chalk from 'chalk';
2
- import { test, expect, describe } from 'vitest';
2
+ import { test, expect, describe, beforeEach, vi } from 'vitest';
3
3
  import { validateManifest, ManifestValidationError } from './index.js';
4
4
  // We need to disable all color outputs for the tests as they are different on different platforms, CI, etc.
5
5
  // This only works if this is the same instance of chalk that better-ajv-errors uses
@@ -79,25 +79,42 @@ describe('bundle', () => {
79
79
  });
80
80
  });
81
81
  describe('route', () => {
82
+ let freshValidateManifest;
83
+ beforeEach(async () => {
84
+ // reset all modules, to get a fresh AJV validator for FF changes
85
+ vi.resetModules();
86
+ const indexImport = await import('./index.js');
87
+ freshValidateManifest = indexImport.validateManifest;
88
+ });
82
89
  test('should throw on additional property', () => {
83
90
  const manifest = getBaseManifest();
84
91
  manifest.routes[0].foo = 'bar';
85
- expect(() => validateManifest(manifest)).toThrowErrorMatchingSnapshot();
92
+ expect(() => freshValidateManifest(manifest)).toThrowErrorMatchingSnapshot();
86
93
  });
87
94
  test('should throw on invalid pattern', () => {
88
95
  const manifest = getBaseManifest();
89
96
  manifest.routes[0].pattern = '/^/hello/?$/';
90
- expect(() => validateManifest(manifest)).toThrowErrorMatchingSnapshot();
97
+ expect(() => freshValidateManifest(manifest)).toThrowErrorMatchingSnapshot();
98
+ });
99
+ test('should not throw on missing beginning slash without FF', () => {
100
+ const manifest = getBaseManifest();
101
+ manifest.routes[0].pattern = '^hello/?$';
102
+ expect(() => freshValidateManifest(manifest, { edge_functions_manifest_validate_slash: false })).not.toThrowError();
103
+ });
104
+ test('should throw on missing beginning slash with FF', () => {
105
+ const manifest = getBaseManifest();
106
+ manifest.routes[0].pattern = '^hello/?$';
107
+ expect(() => freshValidateManifest(manifest, { edge_functions_manifest_validate_slash: true })).toThrowErrorMatchingSnapshot();
91
108
  });
92
109
  test('should throw on missing function', () => {
93
110
  const manifest = getBaseManifest();
94
111
  delete manifest.routes[0].function;
95
- expect(() => validateManifest(manifest)).toThrowErrorMatchingSnapshot();
112
+ expect(() => freshValidateManifest(manifest)).toThrowErrorMatchingSnapshot();
96
113
  });
97
114
  test('should throw on missing pattern', () => {
98
115
  const manifest = getBaseManifest();
99
116
  delete manifest.routes[0].pattern;
100
- expect(() => validateManifest(manifest)).toThrowErrorMatchingSnapshot();
117
+ expect(() => freshValidateManifest(manifest)).toThrowErrorMatchingSnapshot();
101
118
  });
102
119
  });
103
120
  // No tests for post_cache_routes as schema shared with routes
@@ -16,7 +16,7 @@ const routesSchema = {
16
16
  pattern: {
17
17
  type: 'string',
18
18
  format: 'regexPattern',
19
- errorMessage: 'pattern needs to be a regex that starts with ^ and ends with $ without any additional slashes before and afterwards',
19
+ errorMessage: 'pattern needs to be a regex that starts with ^ followed by / and ends with $ without any additional slashes before and afterwards',
20
20
  },
21
21
  generator: { type: 'string' },
22
22
  },
@@ -31,7 +31,7 @@ const functionConfigSchema = {
31
31
  items: {
32
32
  type: 'string',
33
33
  format: 'regexPattern',
34
- errorMessage: 'excluded_patterns needs to be an array of regex that starts with ^ and ends with $ without any additional slashes before and afterwards',
34
+ errorMessage: 'excluded_patterns needs to be an array of regex that starts with ^ followed by / and ends with $ without any additional slashes before and afterwards',
35
35
  },
36
36
  },
37
37
  on_error: { type: 'string' },
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@netlify/edge-bundler",
3
- "version": "8.12.1",
3
+ "version": "8.12.2",
4
4
  "description": "Intelligently prepare Netlify Edge Functions for deployment",
5
5
  "type": "module",
6
6
  "main": "./dist/node/index.js",
@@ -57,9 +57,8 @@
57
57
  "@types/glob-to-regexp": "^0.4.1",
58
58
  "@types/node": "^14.18.32",
59
59
  "@types/semver": "^7.3.9",
60
- "@types/sinon": "^10.0.8",
61
60
  "@types/uuid": "^9.0.0",
62
- "@vitest/coverage-c8": "^0.25.0",
61
+ "@vitest/coverage-c8": "^0.29.2",
63
62
  "archiver": "^5.3.1",
64
63
  "chalk": "^4.1.2",
65
64
  "cpy": "^9.0.1",
@@ -68,8 +67,7 @@
68
67
  "nock": "^13.2.4",
69
68
  "tar": "^6.1.11",
70
69
  "typescript": "^4.5.4",
71
- "vite": "^4.0.0",
72
- "vitest": "^0.25.0"
70
+ "vitest": "^0.29.2"
73
71
  },
74
72
  "engines": {
75
73
  "node": "^14.16.0 || >=16.0.0"