From e3c64547d300d22c961a04a7d3e342fc3ae396ea Mon Sep 17 00:00:00 2001 From: CJ Yetman Date: Tue, 27 May 2025 20:33:49 +0200 Subject: [PATCH 01/17] add minimal JSON schema --- frontend/pbtar_schema.json | 85 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 85 insertions(+) create mode 100644 frontend/pbtar_schema.json diff --git a/frontend/pbtar_schema.json b/frontend/pbtar_schema.json new file mode 100644 index 00000000..58cc42ab --- /dev/null +++ b/frontend/pbtar_schema.json @@ -0,0 +1,85 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "$id": "pbtar_schema.json", + "title": "PBTAR Scenarios metadata Schema", + "description": "A schema for the scenarios metadata dataset in PBTAR", + "type": "array", + "items": { + "type": "object", + "properties": { + "id": { + "description": "The unique identifier for a scenario", + "type": "string" + }, + "name": { + "description": "Name of the scenario", + "type": "string" + }, + "description": { + "description": "Description of the scenario", + "type": "string" + }, + "category": { + "description": "Category of the scenario", + "type": "string" + }, + "target_year": { + "description": "Target year of the scenario", + "type": "string" + }, + "target_temperature": { + "description": "Target temperature of the scenario", + "type": "string" + }, + "regions": { + "description": "Regions that the scenario covers", + "type": "array", + "uniqueItems": true, + "items": { + "type": "string" + } + }, + "sectors": { + "description": "Sectors that the scenario covers", + "type": "array", + "items": { + "enum": [ + "Agriculture", + "Buildings", + "Coal", + "Industrial", + "Oil & Gas", + "Power", + "Renewables", + "Transport" + ] + } + }, + "publisher": { + "description": "Publisher of the scenario", + "type": "string" + }, + "published_date": { + "description": "Date that the scenario was published", + "type": "string" + }, + "overview": { + "description": "Overview of the scenario", + "type": "string" + }, + "expertRecommendation": { + "description": "Expert recommendation for the scenario", + "type": "string" + }, + "dataSource": { + "description": "Data source for the scenario", + "type": "object", + "properties": { + "description": { "type": "string" }, + "url": { "type": "string" }, + "downloadAvailable": { "type": "boolean" } + } + } + } + } +} From ec4172a180772fb732af65f198efed22ae8b4c1a Mon Sep 17 00:00:00 2001 From: CJ Yetman Date: Tue, 27 May 2025 20:39:37 +0200 Subject: [PATCH 02/17] formatting --- frontend/pbtar_schema.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frontend/pbtar_schema.json b/frontend/pbtar_schema.json index 58cc42ab..f37f392f 100644 --- a/frontend/pbtar_schema.json +++ b/frontend/pbtar_schema.json @@ -36,7 +36,7 @@ "type": "array", "uniqueItems": true, "items": { - "type": "string" + "type": "string" } }, "sectors": { From d5d062b39bc8cd60bc1cdebc5435ffae2eb74dba Mon Sep 17 00:00:00 2001 From: CJ Yetman Date: Wed, 28 May 2025 09:49:50 +0200 Subject: [PATCH 03/17] add npm script function to run ajv JSON validation --- frontend/package-lock.json | 263 +++++++++++++++++++++++++++++++++++++ frontend/package.json | 4 +- 2 files changed, 266 insertions(+), 1 deletion(-) diff --git a/frontend/package-lock.json b/frontend/package-lock.json index c4021b1f..384b7faa 100644 --- a/frontend/package-lock.json +++ b/frontend/package-lock.json @@ -22,6 +22,7 @@ "@types/react": "^19.1.5", "@types/react-dom": "^19.1.5", "@vitejs/plugin-react": "^4.5.0", + "ajv-cli": "^5.0.0", "autoprefixer": "^10.4.21", "eslint": "^9.27.0", "globals": "^16.2.0", @@ -2329,6 +2330,81 @@ "url": "https://github.com/sponsors/epoberezkin" } }, + "node_modules/ajv-cli": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/ajv-cli/-/ajv-cli-5.0.0.tgz", + "integrity": "sha512-LY4m6dUv44HTyhV+u2z5uX4EhPYTM38Iv1jdgDJJJCyOOuqB8KtZEGjPZ2T+sh5ZIJrXUfgErYx/j3gLd3+PlQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ajv": "^8.0.0", + "fast-json-patch": "^2.0.0", + "glob": "^7.1.0", + "js-yaml": "^3.14.0", + "json-schema-migrate": "^2.0.0", + "json5": "^2.1.3", + "minimist": "^1.2.0" + }, + "bin": { + "ajv": "dist/index.js" + }, + "peerDependencies": { + "ts-node": ">=9.0.0" + }, + "peerDependenciesMeta": { + "ts-node": { + "optional": true + } + } + }, + "node_modules/ajv-cli/node_modules/ajv": { + "version": "8.17.1", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz", + "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==", + "dev": true, + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.3", + "fast-uri": "^3.0.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/ajv-cli/node_modules/argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "dev": true, + "license": "MIT", + "dependencies": { + "sprintf-js": "~1.0.2" + } + }, + "node_modules/ajv-cli/node_modules/js-yaml": { + "version": "3.14.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", + "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", + "dev": true, + "license": "MIT", + "dependencies": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/ajv-cli/node_modules/json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", + "dev": true, + "license": "MIT" + }, "node_modules/ansi-regex": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", @@ -2924,6 +3000,20 @@ "url": "https://opencollective.com/eslint" } }, + "node_modules/esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "dev": true, + "license": "BSD-2-Clause", + "bin": { + "esparse": "bin/esparse.js", + "esvalidate": "bin/esvalidate.js" + }, + "engines": { + "node": ">=4" + } + }, "node_modules/esquery": { "version": "1.6.0", "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.6.0.tgz", @@ -3018,6 +3108,26 @@ "node": ">= 6" } }, + "node_modules/fast-json-patch": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/fast-json-patch/-/fast-json-patch-2.2.1.tgz", + "integrity": "sha512-4j5uBaTnsYAV5ebkidvxiLUYOwjQ+JSFljeqfTxCrH9bDmlCQaOJFS84oDJ2rAXZq2yskmk3ORfoP9DCwqFNig==", + "dev": true, + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^2.0.1" + }, + "engines": { + "node": ">= 0.4.0" + } + }, + "node_modules/fast-json-patch/node_modules/fast-deep-equal": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz", + "integrity": "sha512-bCK/2Z4zLidyB4ReuIsvALH6w31YfAQDmXMqMx6FyfHqvBxtjC0eRumeSu4Bs3XtXwpyIywtSTrVT99BxY1f9w==", + "dev": true, + "license": "MIT" + }, "node_modules/fast-json-stable-stringify": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", @@ -3030,6 +3140,23 @@ "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", "dev": true }, + "node_modules/fast-uri": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.0.6.tgz", + "integrity": "sha512-Atfo14OibSv5wAp4VWNsFYE1AchQRTv9cBGWET4pZWHzYshFSS9NQI6I57rdKn9croWVMbYFbLhJ+yJvmZIIHw==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fastify" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/fastify" + } + ], + "license": "BSD-3-Clause" + }, "node_modules/fastq": { "version": "1.19.1", "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.19.1.tgz", @@ -3112,6 +3239,13 @@ "url": "https://github.com/sponsors/rawify" } }, + "node_modules/fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", + "dev": true, + "license": "ISC" + }, "node_modules/fsevents": { "version": "2.3.3", "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", @@ -3135,6 +3269,28 @@ "node": ">=6.9.0" } }, + "node_modules/glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "deprecated": "Glob versions prior to v9 are no longer supported", + "dev": true, + "license": "ISC", + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "node_modules/glob-parent": { "version": "6.0.2", "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", @@ -3275,6 +3431,25 @@ "node": ">=8" } }, + "node_modules/inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", + "deprecated": "This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.", + "dev": true, + "license": "ISC", + "dependencies": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "dev": true, + "license": "ISC" + }, "node_modules/is-extglob": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", @@ -3401,6 +3576,40 @@ "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", "dev": true }, + "node_modules/json-schema-migrate": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/json-schema-migrate/-/json-schema-migrate-2.0.0.tgz", + "integrity": "sha512-r38SVTtojDRp4eD6WsCqiE0eNDt4v1WalBXb9cyZYw9ai5cGtBwzRNWjHzJl38w6TxFkXAIA7h+fyX3tnrAFhQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ajv": "^8.0.0" + } + }, + "node_modules/json-schema-migrate/node_modules/ajv": { + "version": "8.17.1", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz", + "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==", + "dev": true, + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.3", + "fast-uri": "^3.0.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/json-schema-migrate/node_modules/json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", + "dev": true, + "license": "MIT" + }, "node_modules/json-schema-traverse": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", @@ -3796,6 +4005,16 @@ "node": "*" } }, + "node_modules/minimist": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", + "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/minipass": { "version": "7.1.2", "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz", @@ -3887,6 +4106,16 @@ "integrity": "sha512-/ieB+mDe4MrrKMT8z+mQL8klXydZWGR5Dowt4RAGKbJ3kIGEx3X4ljUo+6V73IXtUPWgfOlU5B9MlGxFO5T+cA==", "dev": true }, + "node_modules/once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "dev": true, + "license": "ISC", + "dependencies": { + "wrappy": "1" + } + }, "node_modules/optionator": { "version": "0.9.4", "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz", @@ -3967,6 +4196,16 @@ "node": ">=8" } }, + "node_modules/path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/path-key": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", @@ -4212,6 +4451,16 @@ "node": ">=8" } }, + "node_modules/require-from-string": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", + "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/resolve-from": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", @@ -4373,6 +4622,13 @@ "node": ">=0.10.0" } }, + "node_modules/sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==", + "dev": true, + "license": "BSD-3-Clause" + }, "node_modules/stackback": { "version": "0.0.2", "resolved": "https://registry.npmjs.org/stackback/-/stackback-0.0.2.tgz", @@ -4992,6 +5248,13 @@ "node": ">=0.10.0" } }, + "node_modules/wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", + "dev": true, + "license": "ISC" + }, "node_modules/ws": { "version": "8.18.2", "resolved": "https://registry.npmjs.org/ws/-/ws-8.18.2.tgz", diff --git a/frontend/package.json b/frontend/package.json index 5089b9c0..850977e4 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -13,7 +13,8 @@ "lint": "eslint .", "lint:fix": "eslint . --fix", "format": "prettier --write .", - "format:check": "prettier --check ." + "format:check": "prettier --check .", + "json": "ajv -s pbtar_schema.json -d src/data/scenarios_metadata.json" }, "author": "RMI", "license": "MIT", @@ -31,6 +32,7 @@ "@types/react": "^19.1.5", "@types/react-dom": "^19.1.5", "@vitejs/plugin-react": "^4.5.0", + "ajv-cli": "^5.0.0", "autoprefixer": "^10.4.21", "eslint": "^9.27.0", "globals": "^16.2.0", From 8de36828b74b53afde71d8e84ba68627eff29ef0 Mon Sep 17 00:00:00 2001 From: CJ Yetman Date: Wed, 28 May 2025 09:58:10 +0200 Subject: [PATCH 04/17] add JSON validator GitHub action (and invalid data to trigger an error) --- .github/workflows/frontend-json.yml | 42 +++++++++++++++++++++++ frontend/src/data/scenarios_metadata.json | 2 +- 2 files changed, 43 insertions(+), 1 deletion(-) create mode 100644 .github/workflows/frontend-json.yml diff --git a/.github/workflows/frontend-json.yml b/.github/workflows/frontend-json.yml new file mode 100644 index 00000000..f402b2a3 --- /dev/null +++ b/.github/workflows/frontend-json.yml @@ -0,0 +1,42 @@ +name: JSON validate Frontend service + +on: + push: + branches: + - main + paths: + - 'frontend/pbtar_schema.json' + - 'frontend/src/data/scenarios_metadata.json' + - '.github/workflows/frontend-json.yml' + pull_request: + branches: + - main + paths: + - 'frontend/pbtar_schema.json' + - 'frontend/src/data/scenarios_metadata.json' + - '.github/workflows/frontend-json.yml' + workflow_dispatch: + +jobs: + lint: + name: "Run ajv JSON validator" + runs-on: ubuntu-latest + + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Setup Node.js + uses: actions/setup-node@v4 + with: + node-version: '20' + cache: 'npm' + cache-dependency-path: frontend/package-lock.json + + - name: Install dependencies + working-directory: ./frontend + run: npm ci + + - name: Run ajv JSON validator + working-directory: ./frontend + run: npm run json diff --git a/frontend/src/data/scenarios_metadata.json b/frontend/src/data/scenarios_metadata.json index 1e020390..177c2a9f 100644 --- a/frontend/src/data/scenarios_metadata.json +++ b/frontend/src/data/scenarios_metadata.json @@ -37,7 +37,7 @@ "sectors": [ "Power", "Oil & Gas", - "Coal", + "Coalx", "Renewables", "Industrial", "Transport" From 3c5f2f14763f71f052d4ea40c02b631eb90ec60c Mon Sep 17 00:00:00 2001 From: CJ Yetman Date: Wed, 28 May 2025 09:59:32 +0200 Subject: [PATCH 05/17] fix data error --- frontend/src/data/scenarios_metadata.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frontend/src/data/scenarios_metadata.json b/frontend/src/data/scenarios_metadata.json index 177c2a9f..1e020390 100644 --- a/frontend/src/data/scenarios_metadata.json +++ b/frontend/src/data/scenarios_metadata.json @@ -37,7 +37,7 @@ "sectors": [ "Power", "Oil & Gas", - "Coalx", + "Coal", "Renewables", "Industrial", "Transport" From 18b22b615748602712dfa5dc32d881c58f937cf7 Mon Sep 17 00:00:00 2001 From: CJ Yetman Date: Wed, 28 May 2025 11:19:17 +0200 Subject: [PATCH 06/17] change `json` script to `json:check` --- .github/workflows/frontend-json.yml | 2 +- frontend/package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/frontend-json.yml b/.github/workflows/frontend-json.yml index f402b2a3..4046a817 100644 --- a/.github/workflows/frontend-json.yml +++ b/.github/workflows/frontend-json.yml @@ -39,4 +39,4 @@ jobs: - name: Run ajv JSON validator working-directory: ./frontend - run: npm run json + run: npm run json:check diff --git a/frontend/package.json b/frontend/package.json index 850977e4..69e9741b 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -14,7 +14,7 @@ "lint:fix": "eslint . --fix", "format": "prettier --write .", "format:check": "prettier --check .", - "json": "ajv -s pbtar_schema.json -d src/data/scenarios_metadata.json" + "json:check": "ajv -s pbtar_schema.json -d src/data/scenarios_metadata.json" }, "author": "RMI", "license": "MIT", From c1ae9ac6570a7e2fdbc8521d78d126e55ab40092 Mon Sep 17 00:00:00 2001 From: CJ Yetman Date: Wed, 28 May 2025 11:38:54 +0200 Subject: [PATCH 07/17] use `@jirutka/ajv-cli` instead of `ajv-cli` --- frontend/package-lock.json | 362 +++++++++++++------------------------ frontend/package.json | 2 +- 2 files changed, 127 insertions(+), 237 deletions(-) diff --git a/frontend/package-lock.json b/frontend/package-lock.json index 384b7faa..e64d47c2 100644 --- a/frontend/package-lock.json +++ b/frontend/package-lock.json @@ -16,13 +16,13 @@ }, "devDependencies": { "@eslint/js": "^9.27.0", + "@jirutka/ajv-cli": "^6.0.0", "@tailwindcss/postcss": "^4.1.7", "@testing-library/jest-dom": "^6.6.3", "@testing-library/react": "^16.3.0", "@types/react": "^19.1.5", "@types/react-dom": "^19.1.5", "@vitejs/plugin-react": "^4.5.0", - "ajv-cli": "^5.0.0", "autoprefixer": "^10.4.21", "eslint": "^9.27.0", "globals": "^16.2.0", @@ -1064,6 +1064,16 @@ "url": "https://github.com/sponsors/nzakas" } }, + "node_modules/@humanwhocodes/momoa": { + "version": "3.3.8", + "resolved": "https://registry.npmjs.org/@humanwhocodes/momoa/-/momoa-3.3.8.tgz", + "integrity": "sha512-/3PZzor2imi/RLLcnHztkwA79txiVvW145Ve2cp5dxRcH5qOUNJPToasqLFHniTfw4B4lT7jGDdBOPXbXYlIMQ==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=18" + } + }, "node_modules/@humanwhocodes/retry": { "version": "0.4.3", "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.4.3.tgz", @@ -1090,6 +1100,84 @@ "node": ">=18.0.0" } }, + "node_modules/@jirutka/ajv-cli": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/@jirutka/ajv-cli/-/ajv-cli-6.0.0.tgz", + "integrity": "sha512-qQbBwIUltRLJow/E+H/ipga0pc4qcY31PDNM1RhkS+dn/hFDS+HuuEKEBBmACRj+uV8N07+ybskSgKBDujkmeg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@humanwhocodes/momoa": "^3.0.2", + "@json-schema-tools/traverse": "^1.10.4", + "ajv": "^8.13.0", + "chalk": "^5.3.0", + "damerau-levenshtein": "^1.0.8", + "fast-json-patch": "^3.1.0", + "picomatch": "^4.0.2", + "type-flag": "^3.0.0", + "yaml": "^2.4.5" + }, + "bin": { + "ajv": "lib/main.js" + } + }, + "node_modules/@jirutka/ajv-cli/node_modules/ajv": { + "version": "8.17.1", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz", + "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==", + "dev": true, + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.3", + "fast-uri": "^3.0.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/@jirutka/ajv-cli/node_modules/chalk": { + "version": "5.4.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.4.1.tgz", + "integrity": "sha512-zgVZuo2WcZgfUEmsn6eO3kINexW8RAE4maiQ8QNs8CtpPCSyMiYsULR3HQYkm3w8FIA3SberyMJMSldGsW+U3w==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^12.17.0 || ^14.13 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/@jirutka/ajv-cli/node_modules/fast-json-patch": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/fast-json-patch/-/fast-json-patch-3.1.1.tgz", + "integrity": "sha512-vf6IHUX2SBcA+5/+4883dsIjpBTqmfBjmYiWK1savxQmFk4JfBMLa7ynTYOs1Rolp/T1betJxHiGD3g1Mn8lUQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/@jirutka/ajv-cli/node_modules/json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", + "dev": true, + "license": "MIT" + }, + "node_modules/@jirutka/ajv-cli/node_modules/picomatch": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.2.tgz", + "integrity": "sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, "node_modules/@jridgewell/gen-mapping": { "version": "0.3.8", "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.8.tgz", @@ -1138,6 +1226,13 @@ "@jridgewell/sourcemap-codec": "^1.4.14" } }, + "node_modules/@json-schema-tools/traverse": { + "version": "1.10.4", + "resolved": "https://registry.npmjs.org/@json-schema-tools/traverse/-/traverse-1.10.4.tgz", + "integrity": "sha512-9e42zjhLIxzBONroNC4SGsTqdB877tzwH2S6lqgTav9K24kWJR9vNieeMVSuyqnY8FlclH21D8wsm/tuD9WA9Q==", + "dev": true, + "license": "Apache-2.0" + }, "node_modules/@nodelib/fs.scandir": { "version": "2.1.5", "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", @@ -2330,81 +2425,6 @@ "url": "https://github.com/sponsors/epoberezkin" } }, - "node_modules/ajv-cli": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/ajv-cli/-/ajv-cli-5.0.0.tgz", - "integrity": "sha512-LY4m6dUv44HTyhV+u2z5uX4EhPYTM38Iv1jdgDJJJCyOOuqB8KtZEGjPZ2T+sh5ZIJrXUfgErYx/j3gLd3+PlQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "ajv": "^8.0.0", - "fast-json-patch": "^2.0.0", - "glob": "^7.1.0", - "js-yaml": "^3.14.0", - "json-schema-migrate": "^2.0.0", - "json5": "^2.1.3", - "minimist": "^1.2.0" - }, - "bin": { - "ajv": "dist/index.js" - }, - "peerDependencies": { - "ts-node": ">=9.0.0" - }, - "peerDependenciesMeta": { - "ts-node": { - "optional": true - } - } - }, - "node_modules/ajv-cli/node_modules/ajv": { - "version": "8.17.1", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz", - "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==", - "dev": true, - "license": "MIT", - "dependencies": { - "fast-deep-equal": "^3.1.3", - "fast-uri": "^3.0.1", - "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" - } - }, - "node_modules/ajv-cli/node_modules/argparse": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", - "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", - "dev": true, - "license": "MIT", - "dependencies": { - "sprintf-js": "~1.0.2" - } - }, - "node_modules/ajv-cli/node_modules/js-yaml": { - "version": "3.14.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", - "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", - "dev": true, - "license": "MIT", - "dependencies": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" - }, - "bin": { - "js-yaml": "bin/js-yaml.js" - } - }, - "node_modules/ajv-cli/node_modules/json-schema-traverse": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", - "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", - "dev": true, - "license": "MIT" - }, "node_modules/ansi-regex": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", @@ -2719,6 +2739,13 @@ "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==", "dev": true }, + "node_modules/damerau-levenshtein": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/damerau-levenshtein/-/damerau-levenshtein-1.0.8.tgz", + "integrity": "sha512-sdQSFB7+llfUcQHUQO3+B8ERRj0Oa4w9POWMI/puGtuf7gFywGmkaLCElnudfTiKZV+NvHqL0ifzdrI8Ro7ESA==", + "dev": true, + "license": "BSD-2-Clause" + }, "node_modules/data-urls": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-5.0.0.tgz", @@ -3000,20 +3027,6 @@ "url": "https://opencollective.com/eslint" } }, - "node_modules/esprima": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", - "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", - "dev": true, - "license": "BSD-2-Clause", - "bin": { - "esparse": "bin/esparse.js", - "esvalidate": "bin/esvalidate.js" - }, - "engines": { - "node": ">=4" - } - }, "node_modules/esquery": { "version": "1.6.0", "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.6.0.tgz", @@ -3108,26 +3121,6 @@ "node": ">= 6" } }, - "node_modules/fast-json-patch": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/fast-json-patch/-/fast-json-patch-2.2.1.tgz", - "integrity": "sha512-4j5uBaTnsYAV5ebkidvxiLUYOwjQ+JSFljeqfTxCrH9bDmlCQaOJFS84oDJ2rAXZq2yskmk3ORfoP9DCwqFNig==", - "dev": true, - "license": "MIT", - "dependencies": { - "fast-deep-equal": "^2.0.1" - }, - "engines": { - "node": ">= 0.4.0" - } - }, - "node_modules/fast-json-patch/node_modules/fast-deep-equal": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz", - "integrity": "sha512-bCK/2Z4zLidyB4ReuIsvALH6w31YfAQDmXMqMx6FyfHqvBxtjC0eRumeSu4Bs3XtXwpyIywtSTrVT99BxY1f9w==", - "dev": true, - "license": "MIT" - }, "node_modules/fast-json-stable-stringify": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", @@ -3239,13 +3232,6 @@ "url": "https://github.com/sponsors/rawify" } }, - "node_modules/fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", - "dev": true, - "license": "ISC" - }, "node_modules/fsevents": { "version": "2.3.3", "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", @@ -3269,28 +3255,6 @@ "node": ">=6.9.0" } }, - "node_modules/glob": { - "version": "7.2.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", - "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", - "deprecated": "Glob versions prior to v9 are no longer supported", - "dev": true, - "license": "ISC", - "dependencies": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.1.1", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - }, - "engines": { - "node": "*" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, "node_modules/glob-parent": { "version": "6.0.2", "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", @@ -3431,25 +3395,6 @@ "node": ">=8" } }, - "node_modules/inflight": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", - "deprecated": "This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.", - "dev": true, - "license": "ISC", - "dependencies": { - "once": "^1.3.0", - "wrappy": "1" - } - }, - "node_modules/inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", - "dev": true, - "license": "ISC" - }, "node_modules/is-extglob": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", @@ -3576,40 +3521,6 @@ "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", "dev": true }, - "node_modules/json-schema-migrate": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/json-schema-migrate/-/json-schema-migrate-2.0.0.tgz", - "integrity": "sha512-r38SVTtojDRp4eD6WsCqiE0eNDt4v1WalBXb9cyZYw9ai5cGtBwzRNWjHzJl38w6TxFkXAIA7h+fyX3tnrAFhQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "ajv": "^8.0.0" - } - }, - "node_modules/json-schema-migrate/node_modules/ajv": { - "version": "8.17.1", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz", - "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==", - "dev": true, - "license": "MIT", - "dependencies": { - "fast-deep-equal": "^3.1.3", - "fast-uri": "^3.0.1", - "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" - } - }, - "node_modules/json-schema-migrate/node_modules/json-schema-traverse": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", - "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", - "dev": true, - "license": "MIT" - }, "node_modules/json-schema-traverse": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", @@ -4005,16 +3916,6 @@ "node": "*" } }, - "node_modules/minimist": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", - "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", - "dev": true, - "license": "MIT", - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/minipass": { "version": "7.1.2", "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz", @@ -4106,16 +4007,6 @@ "integrity": "sha512-/ieB+mDe4MrrKMT8z+mQL8klXydZWGR5Dowt4RAGKbJ3kIGEx3X4ljUo+6V73IXtUPWgfOlU5B9MlGxFO5T+cA==", "dev": true }, - "node_modules/once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", - "dev": true, - "license": "ISC", - "dependencies": { - "wrappy": "1" - } - }, "node_modules/optionator": { "version": "0.9.4", "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz", @@ -4196,16 +4087,6 @@ "node": ">=8" } }, - "node_modules/path-is-absolute": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/path-key": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", @@ -4622,13 +4503,6 @@ "node": ">=0.10.0" } }, - "node_modules/sprintf-js": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", - "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==", - "dev": true, - "license": "BSD-3-Clause" - }, "node_modules/stackback": { "version": "0.0.2", "resolved": "https://registry.npmjs.org/stackback/-/stackback-0.0.2.tgz", @@ -4887,6 +4761,16 @@ "node": ">= 0.8.0" } }, + "node_modules/type-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/type-flag/-/type-flag-3.0.0.tgz", + "integrity": "sha512-3YaYwMseXCAhBB14RXW5cRQfJQlEknS6i4C8fCfeUdS3ihG9EdccdR9kt3vP73ZdeTGmPb4bZtkDn5XMIn1DLA==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/privatenumber/type-flag?sponsor=1" + } + }, "node_modules/typescript": { "version": "5.8.3", "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.8.3.tgz", @@ -5248,13 +5132,6 @@ "node": ">=0.10.0" } }, - "node_modules/wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", - "dev": true, - "license": "ISC" - }, "node_modules/ws": { "version": "8.18.2", "resolved": "https://registry.npmjs.org/ws/-/ws-8.18.2.tgz", @@ -5297,6 +5174,19 @@ "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", "dev": true }, + "node_modules/yaml": { + "version": "2.8.0", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.8.0.tgz", + "integrity": "sha512-4lLa/EcQCB0cJkyts+FpIRx5G/llPxfP6VQU5KByHEhLxY3IJCH0f0Hy1MHI8sClTvsIb8qwRJ6R/ZdlDJ/leQ==", + "dev": true, + "license": "ISC", + "bin": { + "yaml": "bin.mjs" + }, + "engines": { + "node": ">= 14.6" + } + }, "node_modules/yocto-queue": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", diff --git a/frontend/package.json b/frontend/package.json index 69e9741b..92afe0db 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -26,13 +26,13 @@ }, "devDependencies": { "@eslint/js": "^9.27.0", + "@jirutka/ajv-cli": "^6.0.0", "@tailwindcss/postcss": "^4.1.7", "@testing-library/jest-dom": "^6.6.3", "@testing-library/react": "^16.3.0", "@types/react": "^19.1.5", "@types/react-dom": "^19.1.5", "@vitejs/plugin-react": "^4.5.0", - "ajv-cli": "^5.0.0", "autoprefixer": "^10.4.21", "eslint": "^9.27.0", "globals": "^16.2.0", From 63e17d95febe616d92462fdd20b9edf0848f8279 Mon Sep 17 00:00:00 2001 From: CJ Yetman Date: Wed, 28 May 2025 11:40:52 +0200 Subject: [PATCH 08/17] update JSON validation commmand for `@jirutka/ajv-cli` --- frontend/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frontend/package.json b/frontend/package.json index 92afe0db..db4b04fb 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -14,7 +14,7 @@ "lint:fix": "eslint . --fix", "format": "prettier --write .", "format:check": "prettier --check .", - "json:check": "ajv -s pbtar_schema.json -d src/data/scenarios_metadata.json" + "json:check": "ajv validate -s pbtar_schema.json src/data/scenarios_metadata.json"" }, "author": "RMI", "license": "MIT", From 4e5080e90e8628c87ed49db0fdaee5e3c84db15c Mon Sep 17 00:00:00 2001 From: CJ Yetman Date: Wed, 28 May 2025 11:43:34 +0200 Subject: [PATCH 09/17] remove stray double quote --- frontend/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frontend/package.json b/frontend/package.json index db4b04fb..d96246d5 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -14,7 +14,7 @@ "lint:fix": "eslint . --fix", "format": "prettier --write .", "format:check": "prettier --check .", - "json:check": "ajv validate -s pbtar_schema.json src/data/scenarios_metadata.json"" + "json:check": "ajv validate -s pbtar_schema.json src/data/scenarios_metadata.json" }, "author": "RMI", "license": "MIT", From 0344e50ae4857fa89463e4d684dbb637e59ee9c3 Mon Sep 17 00:00:00 2001 From: CJ Yetman Date: Wed, 28 May 2025 11:49:20 +0200 Subject: [PATCH 10/17] fail on additional properties (with intentional error) --- frontend/pbtar_schema.json | 3 ++- frontend/src/data/scenarios_metadata.json | 1 + 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/frontend/pbtar_schema.json b/frontend/pbtar_schema.json index f37f392f..9c50d0f7 100644 --- a/frontend/pbtar_schema.json +++ b/frontend/pbtar_schema.json @@ -80,6 +80,7 @@ "downloadAvailable": { "type": "boolean" } } } - } + }, + "additionalProperties": false } } diff --git a/frontend/src/data/scenarios_metadata.json b/frontend/src/data/scenarios_metadata.json index 1e020390..07de8310 100644 --- a/frontend/src/data/scenarios_metadata.json +++ b/frontend/src/data/scenarios_metadata.json @@ -1,5 +1,6 @@ [ { + "foo": "bar", "id": "scenario-001", "name": "ZETI Net Zero Pathway", "description": "A comprehensive pathway for the global energy sector to reach net zero by 2050", From fb0cbfee7906ddd85bc6c19aa7f706ab25faf569 Mon Sep 17 00:00:00 2001 From: CJ Yetman Date: Wed, 28 May 2025 11:50:39 +0200 Subject: [PATCH 11/17] fix intentional error --- frontend/src/data/scenarios_metadata.json | 1 - 1 file changed, 1 deletion(-) diff --git a/frontend/src/data/scenarios_metadata.json b/frontend/src/data/scenarios_metadata.json index 07de8310..1e020390 100644 --- a/frontend/src/data/scenarios_metadata.json +++ b/frontend/src/data/scenarios_metadata.json @@ -1,6 +1,5 @@ [ { - "foo": "bar", "id": "scenario-001", "name": "ZETI Net Zero Pathway", "description": "A comprehensive pathway for the global energy sector to reach net zero by 2050", From 359a6c1280dfeeae3fdc73af2e33ea06ba136c3f Mon Sep 17 00:00:00 2001 From: CJ Yetman Date: Wed, 28 May 2025 11:56:50 +0200 Subject: [PATCH 12/17] make all fields required (with intentional failure) --- frontend/pbtar_schema.json | 3 ++- frontend/src/data/scenarios_metadata.json | 1 - 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/frontend/pbtar_schema.json b/frontend/pbtar_schema.json index 9c50d0f7..273aa4af 100644 --- a/frontend/pbtar_schema.json +++ b/frontend/pbtar_schema.json @@ -81,6 +81,7 @@ } } }, - "additionalProperties": false + "additionalProperties": false, + "required": ["id", "name", "description", "category", "target_year", "target_temperature", "regions", "sectors", "publisher", "published_date", "overview", "expertRecommendation", "dataSource"] } } diff --git a/frontend/src/data/scenarios_metadata.json b/frontend/src/data/scenarios_metadata.json index 1e020390..124201ef 100644 --- a/frontend/src/data/scenarios_metadata.json +++ b/frontend/src/data/scenarios_metadata.json @@ -1,7 +1,6 @@ [ { "id": "scenario-001", - "name": "ZETI Net Zero Pathway", "description": "A comprehensive pathway for the global energy sector to reach net zero by 2050", "category": "IAM", "target_year": "2050", From e75d9f2ad5fd9776f21973c04ef99f021917b1d4 Mon Sep 17 00:00:00 2001 From: CJ Yetman Date: Wed, 28 May 2025 11:57:46 +0200 Subject: [PATCH 13/17] fix intentional error --- frontend/src/data/scenarios_metadata.json | 1 + 1 file changed, 1 insertion(+) diff --git a/frontend/src/data/scenarios_metadata.json b/frontend/src/data/scenarios_metadata.json index 124201ef..1e020390 100644 --- a/frontend/src/data/scenarios_metadata.json +++ b/frontend/src/data/scenarios_metadata.json @@ -1,6 +1,7 @@ [ { "id": "scenario-001", + "name": "ZETI Net Zero Pathway", "description": "A comprehensive pathway for the global energy sector to reach net zero by 2050", "category": "IAM", "target_year": "2050", From 8d45d63b86236b080fe81073baae557420417bad Mon Sep 17 00:00:00 2001 From: CJ Yetman Date: Wed, 28 May 2025 11:59:34 +0200 Subject: [PATCH 14/17] fix linting --- frontend/pbtar_schema.json | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/frontend/pbtar_schema.json b/frontend/pbtar_schema.json index 273aa4af..f02242cb 100644 --- a/frontend/pbtar_schema.json +++ b/frontend/pbtar_schema.json @@ -82,6 +82,20 @@ } }, "additionalProperties": false, - "required": ["id", "name", "description", "category", "target_year", "target_temperature", "regions", "sectors", "publisher", "published_date", "overview", "expertRecommendation", "dataSource"] + "required": [ + "id", + "name", + "description", + "category", + "target_year", + "target_temperature", + "regions", + "sectors", + "publisher", + "published_date", + "overview", + "expertRecommendation", + "dataSource" + ] } } From ae6d64b41c1437c468e39a5cd7ddfc67fe151d32 Mon Sep 17 00:00:00 2001 From: CJ Yetman Date: Wed, 28 May 2025 12:01:54 +0200 Subject: [PATCH 15/17] require all and only schema keys in `dataSource` object (with intentional error) --- frontend/pbtar_schema.json | 8 +++++++- frontend/src/data/scenarios_metadata.json | 1 - 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/frontend/pbtar_schema.json b/frontend/pbtar_schema.json index f02242cb..d745d0aa 100644 --- a/frontend/pbtar_schema.json +++ b/frontend/pbtar_schema.json @@ -78,7 +78,13 @@ "description": { "type": "string" }, "url": { "type": "string" }, "downloadAvailable": { "type": "boolean" } - } + }, + "additionalProperties": false, + "required": [ + "description", + "url", + "downloadAvailable" + ] } }, "additionalProperties": false, diff --git a/frontend/src/data/scenarios_metadata.json b/frontend/src/data/scenarios_metadata.json index 1e020390..9fe55e97 100644 --- a/frontend/src/data/scenarios_metadata.json +++ b/frontend/src/data/scenarios_metadata.json @@ -133,7 +133,6 @@ "expertRecommendation": "This scenario is recommended as a scientific reference point for Paris-aligned transition pathways. It has comprehensive global coverage across all major sectors and is backed by the scientific authority of the GEC. However, it may lack specific regional and sectoral detail needed for company-level assessments. We recommend using this scenario to establish the scientific basis for 1.5°C alignment, complemented by more detailed sectoral or regional scenarios.", "dataSource": { "description": "The GEC SSP database is publicly available and contains the full dataset for this scenario.", - "url": "https://sspdata.gec.org/", "downloadAvailable": true } }, From 57273f51dfc3be1170ffb58b930bee7f1fa11823 Mon Sep 17 00:00:00 2001 From: CJ Yetman Date: Wed, 28 May 2025 12:03:02 +0200 Subject: [PATCH 16/17] fix intentional error --- frontend/src/data/scenarios_metadata.json | 1 + 1 file changed, 1 insertion(+) diff --git a/frontend/src/data/scenarios_metadata.json b/frontend/src/data/scenarios_metadata.json index 9fe55e97..1e020390 100644 --- a/frontend/src/data/scenarios_metadata.json +++ b/frontend/src/data/scenarios_metadata.json @@ -133,6 +133,7 @@ "expertRecommendation": "This scenario is recommended as a scientific reference point for Paris-aligned transition pathways. It has comprehensive global coverage across all major sectors and is backed by the scientific authority of the GEC. However, it may lack specific regional and sectoral detail needed for company-level assessments. We recommend using this scenario to establish the scientific basis for 1.5°C alignment, complemented by more detailed sectoral or regional scenarios.", "dataSource": { "description": "The GEC SSP database is publicly available and contains the full dataset for this scenario.", + "url": "https://sspdata.gec.org/", "downloadAvailable": true } }, From 2fbbcf6b8063f8ca22b20aaeff872dbea92a26d5 Mon Sep 17 00:00:00 2001 From: CJ Yetman Date: Wed, 28 May 2025 12:24:43 +0200 Subject: [PATCH 17/17] fix formatting --- frontend/pbtar_schema.json | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/frontend/pbtar_schema.json b/frontend/pbtar_schema.json index d745d0aa..b2666c08 100644 --- a/frontend/pbtar_schema.json +++ b/frontend/pbtar_schema.json @@ -80,11 +80,7 @@ "downloadAvailable": { "type": "boolean" } }, "additionalProperties": false, - "required": [ - "description", - "url", - "downloadAvailable" - ] + "required": ["description", "url", "downloadAvailable"] } }, "additionalProperties": false,