From 5936162b840f272cb780514c34bc00880fe2166d Mon Sep 17 00:00:00 2001 From: Daniel Tschinder <231804+danez@users.noreply.github.com> Date: Fri, 18 Nov 2022 17:08:37 +0100 Subject: [PATCH] feat: move EF validation logic to edge-bundler --- package-lock.json | 190 ++++++++++++++++-- packages/build/package.json | 4 +- .../validate_edge_functions_manifest.js | 110 ---------- .../validate_edge_functions_manifest.ts | 32 +++ .../edge_functions/snapshots/tests.js.snap | Bin 2031 -> 2031 bytes .../snapshots/tests.js.md | 85 ++------ .../snapshots/tests.js.snap | Bin 548 -> 407 bytes .../unit/validate_edge_manifest/tests.js | 19 +- .../empty_manifest/manifest.json | 1 + .../invalid_manifest/manifest.json | 1 + .../manifest.json | 24 --- .../manifest.json | 22 -- .../manifest.json | 23 --- 13 files changed, 223 insertions(+), 288 deletions(-) delete mode 100644 packages/build/src/plugins_core/edge_functions/validate_manifest/validate_edge_functions_manifest.js create mode 100644 packages/build/src/plugins_core/edge_functions/validate_manifest/validate_edge_functions_manifest.ts create mode 100644 packages/build/tests/unit/validate_edge_manifest/unit_fixtures/empty_manifest/manifest.json create mode 100644 packages/build/tests/unit/validate_edge_manifest/unit_fixtures/invalid_manifest/manifest.json delete mode 100644 packages/build/tests/unit/validate_edge_manifest/unit_fixtures/invalid_manifest_extra_property/manifest.json delete mode 100644 packages/build/tests/unit/validate_edge_manifest/unit_fixtures/invalid_manifest_missing_property/manifest.json delete mode 100644 packages/build/tests/unit/validate_edge_manifest/unit_fixtures/invalid_manifest_wrong_route_pattern/manifest.json diff --git a/package-lock.json b/package-lock.json index b43cb3d03c..2401d851ba 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1043,6 +1043,14 @@ "url": "https://github.com/sponsors/nzakas" } }, + "node_modules/@humanwhocodes/momoa": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@humanwhocodes/momoa/-/momoa-2.0.4.tgz", + "integrity": "sha512-RE815I4arJFtt+FVeU1Tgp9/Xvecacji8w/V6XtXsWWH/wz/eNkNbhb+ny/+PlVZjV0rxQpRSQKNKE3lcktHEA==", + "engines": { + "node": ">=10.10.0" + } + }, "node_modules/@humanwhocodes/object-schema": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz", @@ -6553,11 +6561,14 @@ "link": true }, "node_modules/@netlify/edge-bundler": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/@netlify/edge-bundler/-/edge-bundler-4.3.2.tgz", - "integrity": "sha512-wHAeLe6IAxf0DB3eqW3YWcjJoIGsOT5j/GlnIGtWCSEwl0TkwUTolThcY2FWLZyPJNv0jD+4XeLy/05Yw8FNCg==", + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/@netlify/edge-bundler/-/edge-bundler-4.4.0.tgz", + "integrity": "sha512-jJvoMA4UUB8wGzEH43z6uiE4/K/D/auO7CH3f8cgNlT8V885agT21nnXapIpSfugGemfghvP6ld/Ul+nI8GIxQ==", "dependencies": { "@import-maps/resolve": "^1.0.1", + "ajv": "^8.11.2", + "ajv-errors": "^3.0.0", + "better-ajv-errors": "^1.2.0", "common-path-prefix": "^3.0.0", "del": "^7.0.0", "env-paths": "^3.0.0", @@ -9166,9 +9177,9 @@ } }, "node_modules/ajv": { - "version": "8.11.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.11.0.tgz", - "integrity": "sha512-wGgprdCvMalC0BztXvitD2hC04YffAvtsUn93JbGXYLAtCUO4xd17mCCZQxUOItiBwZvJScWo8NIvQMQ71rdpg==", + "version": "8.11.2", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.11.2.tgz", + "integrity": "sha512-E4bfmKAhGiSTvMfL1Myyycaub+cUEU2/IvpylXkUu7CHBkBj1f/ikdzbD7YQ6FKUbixDxeYvB/xY4fvyroDlQg==", "dependencies": { "fast-deep-equal": "^3.1.1", "json-schema-traverse": "^1.0.0", @@ -9833,6 +9844,80 @@ "integrity": "sha512-NzUnlZexiaH/46WDhANlyR2bXRopNg4F/zuSA3OpZnllCUgRaOF2znDioDWrmbNVsuZk6l9pMquQB38cfBZwkQ==", "dev": true }, + "node_modules/better-ajv-errors": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/better-ajv-errors/-/better-ajv-errors-1.2.0.tgz", + "integrity": "sha512-UW+IsFycygIo7bclP9h5ugkNH8EjCSgqyFB/yQ4Hqqa1OEYDtb0uFIkYE0b6+CjkgJYVM5UKI/pJPxjYe9EZlA==", + "dependencies": { + "@babel/code-frame": "^7.16.0", + "@humanwhocodes/momoa": "^2.0.2", + "chalk": "^4.1.2", + "jsonpointer": "^5.0.0", + "leven": "^3.1.0 < 4" + }, + "engines": { + "node": ">= 12.13.0" + }, + "peerDependencies": { + "ajv": "4.11.8 - 8" + } + }, + "node_modules/better-ajv-errors/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/better-ajv-errors/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/better-ajv-errors/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/better-ajv-errors/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" + }, + "node_modules/better-ajv-errors/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/bin-links": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/bin-links/-/bin-links-3.0.3.tgz", @@ -17352,6 +17437,14 @@ "node >= 0.2.0" ] }, + "node_modules/jsonpointer": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/jsonpointer/-/jsonpointer-5.0.1.tgz", + "integrity": "sha512-p/nXbhSEcu3pZRdkW1OfJhpsVtW1gd4Wa1fnQc9YLiTfAjn0312eMKimbdIQzuZl9aa9xUGaRlP9T/CJE/ditQ==", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/JSONStream": { "version": "1.3.5", "resolved": "https://registry.npmjs.org/JSONStream/-/JSONStream-1.3.5.tgz", @@ -25632,15 +25725,13 @@ "@bugsnag/js": "^7.0.0", "@netlify/cache-utils": "^5.0.2", "@netlify/config": "^20.0.1", - "@netlify/edge-bundler": "4.3.2", + "@netlify/edge-bundler": "4.4.0", "@netlify/functions-utils": "^5.0.4", "@netlify/git-utils": "^5.0.2", "@netlify/plugins-list": "^6.54.0", "@netlify/run-utils": "^5.0.2", "@netlify/zip-it-and-ship-it": "^7.1.2", "@sindresorhus/slugify": "^2.0.0", - "ajv": "^8.11.0", - "ajv-errors": "^3.0.0", "ansi-escapes": "^5.0.0", "chalk": "^5.0.0", "clean-stack": "^4.0.0", @@ -26898,6 +26989,11 @@ "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", "dev": true }, + "@humanwhocodes/momoa": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@humanwhocodes/momoa/-/momoa-2.0.4.tgz", + "integrity": "sha512-RE815I4arJFtt+FVeU1Tgp9/Xvecacji8w/V6XtXsWWH/wz/eNkNbhb+ny/+PlVZjV0rxQpRSQKNKE3lcktHEA==" + }, "@humanwhocodes/object-schema": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz", @@ -31227,7 +31323,7 @@ "@bugsnag/js": "^7.0.0", "@netlify/cache-utils": "^5.0.2", "@netlify/config": "^20.0.1", - "@netlify/edge-bundler": "4.3.2", + "@netlify/edge-bundler": "4.4.0", "@netlify/functions-utils": "^5.0.4", "@netlify/git-utils": "^5.0.2", "@netlify/nock-udp": "^3.0.1", @@ -31237,8 +31333,6 @@ "@sindresorhus/slugify": "^2.0.0", "@types/node": "^14.18.31", "@types/statsd-client": "^0.4.3", - "ajv": "^8.11.0", - "ajv-errors": "^3.0.0", "ansi-escapes": "^5.0.0", "atob": "^2.1.2", "ava": "^4.0.0", @@ -31449,11 +31543,14 @@ } }, "@netlify/edge-bundler": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/@netlify/edge-bundler/-/edge-bundler-4.3.2.tgz", - "integrity": "sha512-wHAeLe6IAxf0DB3eqW3YWcjJoIGsOT5j/GlnIGtWCSEwl0TkwUTolThcY2FWLZyPJNv0jD+4XeLy/05Yw8FNCg==", + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/@netlify/edge-bundler/-/edge-bundler-4.4.0.tgz", + "integrity": "sha512-jJvoMA4UUB8wGzEH43z6uiE4/K/D/auO7CH3f8cgNlT8V885agT21nnXapIpSfugGemfghvP6ld/Ul+nI8GIxQ==", "requires": { "@import-maps/resolve": "^1.0.1", + "ajv": "^8.11.2", + "ajv-errors": "^3.0.0", + "better-ajv-errors": "^1.2.0", "common-path-prefix": "^3.0.0", "del": "^7.0.0", "env-paths": "^3.0.0", @@ -33388,9 +33485,9 @@ } }, "ajv": { - "version": "8.11.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.11.0.tgz", - "integrity": "sha512-wGgprdCvMalC0BztXvitD2hC04YffAvtsUn93JbGXYLAtCUO4xd17mCCZQxUOItiBwZvJScWo8NIvQMQ71rdpg==", + "version": "8.11.2", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.11.2.tgz", + "integrity": "sha512-E4bfmKAhGiSTvMfL1Myyycaub+cUEU2/IvpylXkUu7CHBkBj1f/ikdzbD7YQ6FKUbixDxeYvB/xY4fvyroDlQg==", "requires": { "fast-deep-equal": "^3.1.1", "json-schema-traverse": "^1.0.0", @@ -33889,6 +33986,58 @@ "integrity": "sha512-NzUnlZexiaH/46WDhANlyR2bXRopNg4F/zuSA3OpZnllCUgRaOF2znDioDWrmbNVsuZk6l9pMquQB38cfBZwkQ==", "dev": true }, + "better-ajv-errors": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/better-ajv-errors/-/better-ajv-errors-1.2.0.tgz", + "integrity": "sha512-UW+IsFycygIo7bclP9h5ugkNH8EjCSgqyFB/yQ4Hqqa1OEYDtb0uFIkYE0b6+CjkgJYVM5UKI/pJPxjYe9EZlA==", + "requires": { + "@babel/code-frame": "^7.16.0", + "@humanwhocodes/momoa": "^2.0.2", + "chalk": "^4.1.2", + "jsonpointer": "^5.0.0", + "leven": "^3.1.0 < 4" + }, + "dependencies": { + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "requires": { + "color-convert": "^2.0.1" + } + }, + "chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "requires": { + "has-flag": "^4.0.0" + } + } + } + }, "bin-links": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/bin-links/-/bin-links-3.0.3.tgz", @@ -39406,6 +39555,11 @@ "integrity": "sha1-P02uSpH6wxX3EGL4UhzCOfE2YoA=", "dev": true }, + "jsonpointer": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/jsonpointer/-/jsonpointer-5.0.1.tgz", + "integrity": "sha512-p/nXbhSEcu3pZRdkW1OfJhpsVtW1gd4Wa1fnQc9YLiTfAjn0312eMKimbdIQzuZl9aa9xUGaRlP9T/CJE/ditQ==" + }, "JSONStream": { "version": "1.3.5", "resolved": "https://registry.npmjs.org/JSONStream/-/JSONStream-1.3.5.tgz", diff --git a/packages/build/package.json b/packages/build/package.json index 309e606374..53df9afe6d 100644 --- a/packages/build/package.json +++ b/packages/build/package.json @@ -66,15 +66,13 @@ "@bugsnag/js": "^7.0.0", "@netlify/cache-utils": "^5.0.2", "@netlify/config": "^20.0.1", - "@netlify/edge-bundler": "4.3.2", + "@netlify/edge-bundler": "4.4.0", "@netlify/functions-utils": "^5.0.4", "@netlify/git-utils": "^5.0.2", "@netlify/plugins-list": "^6.54.0", "@netlify/run-utils": "^5.0.2", "@netlify/zip-it-and-ship-it": "^7.1.2", "@sindresorhus/slugify": "^2.0.0", - "ajv": "^8.11.0", - "ajv-errors": "^3.0.0", "ansi-escapes": "^5.0.0", "chalk": "^5.0.0", "clean-stack": "^4.0.0", diff --git a/packages/build/src/plugins_core/edge_functions/validate_manifest/validate_edge_functions_manifest.js b/packages/build/src/plugins_core/edge_functions/validate_manifest/validate_edge_functions_manifest.js deleted file mode 100644 index 197af433f7..0000000000 --- a/packages/build/src/plugins_core/edge_functions/validate_manifest/validate_edge_functions_manifest.js +++ /dev/null @@ -1,110 +0,0 @@ -import { promises as fs } from 'fs' -import { join, resolve } from 'path' - -import Ajv from 'ajv' -import ajvErrors from 'ajv-errors' - -import { addErrorInfo } from '../../../error/info.js' - -const ajv = new Ajv({ allErrors: true }) -ajvErrors(ajv) - -// regex pattern for manifest route pattern -// checks if the pattern string starts with ^ and ends with $ -// we define this format in edge-bundler: -// https://github.com/netlify/edge-bundler/blob/main/src/manifest.ts#L66 -const normalizedPatternRegex = /^\^.*\$$/ -ajv.addFormat('regexPattern', { - async: true, - validate: (data) => normalizedPatternRegex.test(data), -}) - -const bundlesSchema = { - $async: true, - type: 'object', - required: ['asset', 'format'], - properties: { - asset: { type: 'string' }, - format: { type: 'string' }, - }, - additionalProperties: false, -} - -const routesSchema = { - $async: true, - type: 'object', - required: ['function', 'pattern'], - properties: { - name: { type: 'string' }, - function: { type: 'string' }, - pattern: { type: 'string', format: 'regexPattern', errorMessage: `must match format ${normalizedPatternRegex}` }, - }, - additionalProperties: false, -} - -const layersSchema = { - $async: true, - type: 'object', - required: ['flag', 'name'], - properties: { - flag: { type: 'string' }, - name: { type: 'string' }, - local: { type: 'string' }, - }, - additionalProperties: false, -} - -const edgeManifestSchema = { - $async: true, - type: 'object', - required: ['bundles', 'routes', 'bundler_version'], - properties: { - bundles: { - type: 'array', - items: bundlesSchema, - }, - routes: { - type: 'array', - items: routesSchema, - }, - post_cache_routes: { - type: 'array', - items: routesSchema, - }, - layers: { - type: 'array', - items: layersSchema, - }, - bundler_version: { type: 'string' }, - }, - additionalProperties: false, - errorMessage: "Couldn't validate Edge Functions manifest.json", -} - -const validateManifest = async (manifestData) => { - const validate = ajv.compile(edgeManifestSchema) - - await validate(manifestData) -} - -export const validateEdgeFunctionsManifest = async function ({ - buildDir, - constants: { EDGE_FUNCTIONS_DIST: distDirectory }, -}) { - try { - const edgeFunctionsDistPath = resolve(buildDir, distDirectory) - const manifestPath = join(edgeFunctionsDistPath, 'manifest.json') - const data = await fs.readFile(manifestPath) - const manifestData = JSON.parse(data) - - await validateManifest(manifestData) - } catch (error) { - const isValidationErr = error instanceof Ajv.ValidationError - const parsedErr = isValidationErr ? error.errors : error - - addErrorInfo(parsedErr, { type: 'coreStep' }) - throw new Error(isValidationErr ? JSON.stringify(parsedErr, null, 2) : parsedErr) - } - - return {} -} diff --git a/packages/build/src/plugins_core/edge_functions/validate_manifest/validate_edge_functions_manifest.ts b/packages/build/src/plugins_core/edge_functions/validate_manifest/validate_edge_functions_manifest.ts new file mode 100644 index 0000000000..eb155fcaa5 --- /dev/null +++ b/packages/build/src/plugins_core/edge_functions/validate_manifest/validate_edge_functions_manifest.ts @@ -0,0 +1,32 @@ +import { promises as fs } from 'fs' +import { join, resolve } from 'path' + +import { ManifestValidationError, validateManifest } from '@netlify/edge-bundler' + +import { addErrorInfo } from '../../../error/info.js' + +export const validateEdgeFunctionsManifest = async function ({ + buildDir, + constants: { EDGE_FUNCTIONS_DIST: distDirectory }, +}: { + buildDir: string + constants: { EDGE_FUNCTIONS_DIST: string } +}) { + const edgeFunctionsDistPath = resolve(buildDir, distDirectory) + const manifestPath = join(edgeFunctionsDistPath, 'manifest.json') + const data = await fs.readFile(manifestPath) + // @ts-expect-error TypeScript is not aware that parse can handle Buffer + const manifestData = JSON.parse(data) + + try { + validateManifest(manifestData) + } catch (error) { + if (error instanceof ManifestValidationError) { + addErrorInfo(error, { type: 'coreStep' }) + } + + throw error + } + + return {} +} diff --git a/packages/build/tests/edge_functions/snapshots/tests.js.snap b/packages/build/tests/edge_functions/snapshots/tests.js.snap index 73585d7837fbd525bbd32a17d6a166d4e8cf8ac7..29b869e9e7123c8c969752f8ccbf6fa8ce5d90b9 100644 GIT binary patch delta 915 zcmV;E18n^75AP2$K~_N^Q*L2!b7*gLAa*kf0|5S#lWU4DO6$ar2fz#;IA;H)X<{~u zn}lsOG3S76(SxxvYy^KqW?pUs<2nRjg{cD$5FNCMcZ`lSYBF{zTSyV`+j^(6Jb>qv z5HR(CIjJ?ZY;fG3P6%sK9-l;oV$qp*X>v^5N)W(oq&nW|V8{Suh`*bE3xEk4oHLGG zA_O=Q_zv>GRdHu*fCCBvDLJGPSkoeC#Q-1YvFOnus8XS>&$xfAxY)mOYjvmb{!bjuDr^(MoPA=&p%j#aKig2RuAuakg;jc#I?n>}<*r!Kfz{vQIJMfmdgo>`3B^j+HW!9!5%YUD8R9 zJh-KCG*?(0!X$c7DqW9CGkM^;^%+u0w(S!zGf=c*Nl)RQf{#{gI_)tTe017l#I(n? z15UvMA<%u)R*UpZ5n{s=q1u0 zA&Vm9Lcm}|^t{IuJ#peQL6vLTW=y`cz6==^A#o%maW`3O9Vpd6A3%|6;f^n3ArQa# zy$NFd9(RoJY#k};m!TXwL-1XmqI%ZK7ulJ)zh&ATf|S` z5q)F@Jj^&4ePPvIJr|FWmU~0wUN%MsS4t$}>Og;q7&0+(SWARDF~!XN^`c%mkw+As zlIb#?c6n(CYdxaVE)&2<^YDmimm85+jKfr9VlSjuKX5SED~8!Fc$;e4Lm|vL&R9ip z;g=Mj{;cyac|g-C;nN7EO*fD@-kx|$+}hpnbk_Gn99NVj{%W3k%vJvLZ-G+c7owb3 z9L-lKg!qKZBUDZUuN=L0jLbInTHuKxXt|G`g#QZ5Knv;Z0v47#><#BaToS88^b6=I pdQd&FrGPSj?spX^{Qs4i#tY5eP}0g!E5r0C{|DJ~Wg*0g002NnzJ34z delta 915 zcmV;E18n^75AP2$K~_N^Q*L2!b7*gLAa*kf0|3wc7~%_mL2re_?dbV6>m8}FP}l8a zi@hdt*7vz0AaAiUYy^MQtzg^0xDEkWVd{VbL8%}ww62}CU$~OTea#B|{@P)Wf8eguiHR>Cmt!_3q)_hK?kHjmyA>6IBv%6aV z6zy)W)*Hu`b(o1|#2#O?RczGpIw`=Z3fn|5XP;PcC{E<*;MEx?JCgXKW2KCwhmq1;mvqu2 z4{m83%@r1hFo_2+c(o^`S;G-3rPJ2uSAD#9XG3{~f zfK%{52y`E{)gnDpc@$3yBpDLYVu4iq3Oo$G=fiL_0jPi3oBnv7qT*k5`Xdh@dWrN$ z$f5|j5HJ`KJ?}9^Pn`HnQ01Do8Iv!qFGEH}NE``C+)dV62TC>22T-J1xZ}%M2*fXb zZ-Q9A#~mX)8=eqQ!IPWd`3Q$UcR4d5{2}wo|F0r!IC0I(Kyma#cym8;txzlUrO=LpkDyFl^>i%37V#5! zL?2lJ4>Jx%Us!cl&&6Y;<=zmvmyMCZl@f`#I#7QihD?kc))JvkOfhqRy{K1CAInAwJ>q2$j>oD@U&#BeRXY7I Snapshot 1 - `[␊ - {␊ - "instancePath": "/routes/2/pattern",␊ - "schemaPath": "#/properties/routes/items/properties/pattern/errorMessage",␊ - "keyword": "errorMessage",␊ - "params": {␊ - "errors": [␊ - {␊ - "instancePath": "/routes/2/pattern",␊ - "schemaPath": "#/properties/routes/items/properties/pattern/format",␊ - "keyword": "format",␊ - "params": {␊ - "format": "regexPattern"␊ - },␊ - "message": "must match format \\"regexPattern\\"",␊ - "emUsed": true␊ - }␊ - ]␊ - },␊ - "message": "must match format /^\\\\^.*\\\\$$/"␊ - }␊ - ]` + `Validation of Edge Functions manifest failed␊ + TYPE must be object␊ + ␊ + > 1 | "json"␊ +   | ^^^^^^ 👈🏽 type must be object` -## should detect missing property in manifest +## should print error on empty manifest > Snapshot 1 - `[␊ - {␊ - "instancePath": "",␊ - "schemaPath": "#/errorMessage",␊ - "keyword": "errorMessage",␊ - "params": {␊ - "errors": [␊ - {␊ - "instancePath": "/bundles/0",␊ - "schemaPath": "#/properties/bundles/items/required",␊ - "keyword": "required",␊ - "params": {␊ - "missingProperty": "format"␊ - },␊ - "message": "must have required property 'format'",␊ - "emUsed": true␊ - }␊ - ]␊ - },␊ - "message": "Couldn't validate Edge Functions manifest.json"␊ - }␊ - ]` - -## should detect extra property in manifest - -> Snapshot 1 - - `[␊ - {␊ - "instancePath": "",␊ - "schemaPath": "#/errorMessage",␊ - "keyword": "errorMessage",␊ - "params": {␊ - "errors": [␊ - {␊ - "instancePath": "/routes/0",␊ - "schemaPath": "#/properties/routes/items/additionalProperties",␊ - "keyword": "additionalProperties",␊ - "params": {␊ - "additionalProperty": "extra"␊ - },␊ - "message": "must NOT have additional properties",␊ - "emUsed": true␊ - }␊ - ]␊ - },␊ - "message": "Couldn't validate Edge Functions manifest.json"␊ - }␊ - ]` + `Validation of Edge Functions manifest failed␊ + REQUIRED must have required property 'bundler_version'␊ + ␊ + > 1 | {}␊ +   | ^ ☹️ bundler_version is missing here!` diff --git a/packages/build/tests/unit/validate_edge_manifest/snapshots/tests.js.snap b/packages/build/tests/unit/validate_edge_manifest/snapshots/tests.js.snap index f8c49b2a532de42ae1b7d2b2957c904771b56c1e..493c5159d10a9f28bccf253867f404a130fe975d 100644 GIT binary patch literal 407 zcmV;I0cid~RzV7l z{>OebbRUZd00000000BEQM*b5K@?3C5z<+wxdt)qZh}P`D_5}7ph5^Jvzfce#GRRS zW;PhqLMyvqXBXmEXyMQJ1LhN)-Nd{ILIkH6xQ}!0x%UhLKa`Ct{rHN8nGkPwbxXz} zg-9`B0F{yoqyQ#5BxDpg5iCG$m=+|mtwui#C?$r}vhjLmGn2gRMrLa*$et$vVwgqC z06f}6IE+OjN$3d=1cZf1bNPDN<@vhHPix0szFsQXpj_c;8hC6QeFW*Zv0>6e&LSK> zLG8~%Dh>x1?$QYCU*d(fmZC5&J3Ph0s1arwM_d;RCnmgxO;g7CWy_2(}s&}x|xfbalD7=oD!bG5qP+3t$KNd7Z zb=g6sEq!q{V{h+QvT~aIe0l$R>y3}Rpkbt%*-e?&Of;c|3b*Gk{tfG>aU?SX004`L ByNCb) literal 548 zcmV+<0^9vTRzV0qx$#g$>`ZQ86Qpn zez*@H63P-&877SK=m4U4yK(OjqcPgN zLu=U_Tf0*{|E>+My*8ywW|*`t+q4N@RYwke1lGCV8pO*VFwRUH$tbkzjI$|yYaAc< zT32Ooj*G;1+7T@SAL+N`3S?!;-8p4BG%k<^CTSG5fbx^Yxy?YQoAIXP-k-3d{Z!dju`;CFa_52afHrO)r8v=7REL)uBDc;NuqABvJ4_DdDraX1?Ws5SH*I{Te}t^pH7aUKuzJs!d(7VO zIl|jYWhAt+YgG2WTCIK|?L|l$F37N { ) }) -test('should detect invalid route pattern in manifest', async (t) => { +test('should print error on invalid manifest', async (t) => { const error = await t.throwsAsync( validateEdgeFunctionsManifest({ buildDir: FIXTURES_DIR, - constants: { EDGE_FUNCTIONS_DIST: 'invalid_manifest_wrong_route_pattern' }, + constants: { EDGE_FUNCTIONS_DIST: 'invalid_manifest' }, }), ) t.snapshot(error.message) }) -test('should detect missing property in manifest', async (t) => { +test('should print error on empty manifest', async (t) => { const error = await t.throwsAsync( validateEdgeFunctionsManifest({ buildDir: FIXTURES_DIR, - constants: { EDGE_FUNCTIONS_DIST: 'invalid_manifest_missing_property' }, - }), - ) - - t.snapshot(error.message) -}) - -test('should detect extra property in manifest', async (t) => { - const error = await t.throwsAsync( - validateEdgeFunctionsManifest({ - buildDir: FIXTURES_DIR, - constants: { EDGE_FUNCTIONS_DIST: 'invalid_manifest_extra_property' }, + constants: { EDGE_FUNCTIONS_DIST: 'empty_manifest' }, }), ) diff --git a/packages/build/tests/unit/validate_edge_manifest/unit_fixtures/empty_manifest/manifest.json b/packages/build/tests/unit/validate_edge_manifest/unit_fixtures/empty_manifest/manifest.json new file mode 100644 index 0000000000..0967ef424b --- /dev/null +++ b/packages/build/tests/unit/validate_edge_manifest/unit_fixtures/empty_manifest/manifest.json @@ -0,0 +1 @@ +{} diff --git a/packages/build/tests/unit/validate_edge_manifest/unit_fixtures/invalid_manifest/manifest.json b/packages/build/tests/unit/validate_edge_manifest/unit_fixtures/invalid_manifest/manifest.json new file mode 100644 index 0000000000..90817d4296 --- /dev/null +++ b/packages/build/tests/unit/validate_edge_manifest/unit_fixtures/invalid_manifest/manifest.json @@ -0,0 +1 @@ +"json" diff --git a/packages/build/tests/unit/validate_edge_manifest/unit_fixtures/invalid_manifest_extra_property/manifest.json b/packages/build/tests/unit/validate_edge_manifest/unit_fixtures/invalid_manifest_extra_property/manifest.json deleted file mode 100644 index bde758c772..0000000000 --- a/packages/build/tests/unit/validate_edge_manifest/unit_fixtures/invalid_manifest_extra_property/manifest.json +++ /dev/null @@ -1,24 +0,0 @@ -{ - "bundles": [ - { - "asset": "f35baff44129a8f6be7db68590b2efd86ed4ba29000e2edbcaddc5d620d7d043.js", - "format": "js" - } - ], - "routes": [ - { - "function": "hello", - "pattern": "^/hello/?$", - "extra": "I'm extra!" - }, - { - "function": "geolocation", - "pattern": "^/geolocation/?$" - }, - { - "function": "json", - "pattern": "^/json/?$" - } - ], - "bundler_version": "1.6.0" -} diff --git a/packages/build/tests/unit/validate_edge_manifest/unit_fixtures/invalid_manifest_missing_property/manifest.json b/packages/build/tests/unit/validate_edge_manifest/unit_fixtures/invalid_manifest_missing_property/manifest.json deleted file mode 100644 index 2fbf3814d5..0000000000 --- a/packages/build/tests/unit/validate_edge_manifest/unit_fixtures/invalid_manifest_missing_property/manifest.json +++ /dev/null @@ -1,22 +0,0 @@ -{ - "bundles": [ - { - "asset": "f35baff44129a8f6be7db68590b2efd86ed4ba29000e2edbcaddc5d620d7d043.js" - } - ], - "routes": [ - { - "function": "hello", - "pattern": "^/hello/?$" - }, - { - "function": "geolocation", - "pattern": "^/geolocation/?$" - }, - { - "function": "json", - "pattern": "^/json/?$" - } - ], - "bundler_version": "1.6.0" -} diff --git a/packages/build/tests/unit/validate_edge_manifest/unit_fixtures/invalid_manifest_wrong_route_pattern/manifest.json b/packages/build/tests/unit/validate_edge_manifest/unit_fixtures/invalid_manifest_wrong_route_pattern/manifest.json deleted file mode 100644 index 6d8ba8ae1c..0000000000 --- a/packages/build/tests/unit/validate_edge_manifest/unit_fixtures/invalid_manifest_wrong_route_pattern/manifest.json +++ /dev/null @@ -1,23 +0,0 @@ -{ - "bundles": [ - { - "asset": "f35baff44129a8f6be7db68590b2efd86ed4ba29000e2edbcaddc5d620d7d043.js", - "format": "js" - } - ], - "routes": [ - { - "function": "hello", - "pattern": "^/hello/?$" - }, - { - "function": "geolocation", - "pattern": "^/geolocation/?$" - }, - { - "function": "json", - "pattern": "^/json/?" - } - ], - "bundler_version": "1.6.0" -}