From 99f198e3cc8fc7f8ee3963f9099efc5ea21f4884 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Gj=C3=B8s=C3=A6ter?= Date: Tue, 21 Apr 2026 11:16:53 +0200 Subject: [PATCH] Scripts --- components/station_history.yaml | 21 +- package-lock.json | 426 +++++++++++++++++++------------- package.json | 3 +- scripts/combine-yaml.ts | 6 + scripts/generate-examples.ts | 101 ++++++++ 5 files changed, 383 insertions(+), 174 deletions(-) create mode 100644 scripts/generate-examples.ts diff --git a/components/station_history.yaml b/components/station_history.yaml index 1b50380..7d48ea1 100644 --- a/components/station_history.yaml +++ b/components/station_history.yaml @@ -18,4 +18,23 @@ properties: used_capacity_percentage: type: object description: Percentage of total capacity utilized. - $ref: "#/components/schemas/simple_reading_float" \ No newline at end of file + $ref: "#/components/schemas/simple_reading_float" + generator_readings: + type: array + items: + type: object + properties: + generator_id: + type: string + x-faker: + helpers.replaceSymbols: "??#.??#.??#" + power_reading_mw: + type: number + format: float + x-faker: + datatype.float: + min: 0 + max: 50 + is_producing: + type: boolean + x-faker: datatype.boolean \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index 2f1df01..11f988f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,7 +9,8 @@ "version": "1.0.0", "hasInstallScript": true, "devDependencies": { - "@stoplight/prism-cli": "^5.0.0", + "@faker-js/faker": "^9.0.0", + "@stoplight/prism-cli": "^5.15.10", "@tanstack/react-query": "^4.0.0", "@types/js-yaml": "^4.0.5", "@types/node": "^20.0.0", @@ -519,14 +520,20 @@ "license": "MIT" }, "node_modules/@faker-js/faker": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/@faker-js/faker/-/faker-6.3.1.tgz", - "integrity": "sha512-8YXBE2ZcU/pImVOHX7MWrSR/X5up7t6rPWZlk34RwZEcdr3ua6X+32pSd6XuOQRN+vbuvYNfA6iey8NbrjuMFQ==", + "version": "9.9.0", + "resolved": "https://registry.npmjs.org/@faker-js/faker/-/faker-9.9.0.tgz", + "integrity": "sha512-OEl393iCOoo/z8bMezRlJu+GlRGlsKbUAN7jKB6LhnKoqKve5DXRpalbItIIcwnCjs1k/FOPjFzcA6Qn+H+YbA==", "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/fakerjs" + } + ], "license": "MIT", "engines": { - "node": ">=14.0.0", - "npm": ">=6.0.0" + "node": ">=18.0.0", + "npm": ">=9.0.0" } }, "node_modules/@ibm-cloud/openapi-ruleset": { @@ -607,6 +614,19 @@ "jsep": "^0.4.0||^1.0.0" } }, + "node_modules/@nodable/entities": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@nodable/entities/-/entities-2.1.0.tgz", + "integrity": "sha512-nyT7T3nbMyBI/lvr6L5TyWbFJAI9FTgVRakNoBqCD+PmID8DzFrrNdLLtHMwMszOtqZa8PAOV24ZqDnQrhQINA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/nodable" + } + ], + "license": "MIT" + }, "node_modules/@nodelib/fs.scandir": { "version": "2.1.5", "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", @@ -834,9 +854,9 @@ } }, "node_modules/@stoplight/http-spec/node_modules/yaml": { - "version": "1.10.2", - "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz", - "integrity": "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==", + "version": "1.10.3", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.3.tgz", + "integrity": "sha512-vIYeF1u3CjlhAFekPPAk2h/Kv4T3mAkMox5OymRiJQB0spDP10LHvt+K7G9Ny6NuuMAb25/6n1qyUjAcGNf/AA==", "dev": true, "license": "ISC", "engines": { @@ -934,9 +954,9 @@ } }, "node_modules/@stoplight/json-schema-ref-parser": { - "version": "9.2.7", - "resolved": "https://registry.npmjs.org/@stoplight/json-schema-ref-parser/-/json-schema-ref-parser-9.2.7.tgz", - "integrity": "sha512-1vNzJ7iSrFTAFNbZHPyhI6GiJJw74+WaV61bARUQEDR4Jm80f9s0Tq9uCvGoMYwIFmWDJAoTiyegnUs6SvVxDw==", + "version": "10.0.0", + "resolved": "https://registry.npmjs.org/@stoplight/json-schema-ref-parser/-/json-schema-ref-parser-10.0.0.tgz", + "integrity": "sha512-EibmayoGsMCIJOEKNvmsrAq37/M7A/rceY8ZAKX8rhwPThgkJ4QTPF0VhgGyfuq9P6i0EQQXM/x6nL7S2uPGsQ==", "dev": true, "license": "MIT", "dependencies": { @@ -944,9 +964,7 @@ "@stoplight/path": "^1.3.2", "@stoplight/yaml": "^4.0.2", "call-me-maybe": "^1.0.1", - "fastestsmallesttextencoderdecoder": "^1.0.22", - "isomorphic-fetch": "^3.0.0", - "node-abort-controller": "^3.0.1" + "url": "^0.11.3" } }, "node_modules/@stoplight/json-schema-sampler": { @@ -981,27 +999,28 @@ } }, "node_modules/@stoplight/prism-cli": { - "version": "5.12.0", - "resolved": "https://registry.npmjs.org/@stoplight/prism-cli/-/prism-cli-5.12.0.tgz", - "integrity": "sha512-icKw+XhKyocnjNuFJEtBxSY/+HLxvybwGvJ+QayCqROravBjQUXFC1Xg4v++Uz7MK1AkgkuvlSqcxtoQ02QsJg==", + "version": "5.15.10", + "resolved": "https://registry.npmjs.org/@stoplight/prism-cli/-/prism-cli-5.15.10.tgz", + "integrity": "sha512-fsIvRfpMwbVNnAbi7EbSj3vPMVgH+Vxb6o4MTS/F+OzoFKJixUcGviaR3+NKxf+5Bi+Gv7dbyn+xt1srBMEwVw==", "dev": true, "license": "Apache-2.0", "dependencies": { "@stoplight/json": "3.21.7", - "@stoplight/json-schema-ref-parser": "9.2.7", - "@stoplight/prism-core": "^5.8.0", - "@stoplight/prism-http": "5.12.0", - "@stoplight/prism-http-server": "^5.12.0", + "@stoplight/json-schema-ref-parser": "10.0.0", + "@stoplight/prism-core": "^5.15.10", + "@stoplight/prism-http": "^5.15.10", + "@stoplight/prism-http-server": "^5.15.10", "@stoplight/types": "^14.1.0", "chalk": "^4.1.2", "chokidar": "^3.5.2", "fp-ts": "^2.11.5", - "json-schema-faker": "0.5.8", - "lodash": "^4.17.21", + "json-schema-faker": "0.5.9", + "jsonrepair": "^3.12.0", + "lodash": "^4.17.23", "node-fetch": "^2.6.5", "pino": "^6.13.3", "signale": "^1.4.0", - "split2": "^3.2.2", + "split2": "^4.2.0", "tslib": "^2.3.1", "uri-template-lite": "^22.9.0", "urijs": "^1.19.11", @@ -1011,7 +1030,7 @@ "prism": "dist/index.js" }, "engines": { - "node": ">=18.20.1" + "node": ">=24.14.0" } }, "node_modules/@stoplight/prism-cli/node_modules/@stoplight/types": { @@ -1040,6 +1059,13 @@ "wrap-ansi": "^7.0.0" } }, + "node_modules/@stoplight/prism-cli/node_modules/lodash": { + "version": "4.18.1", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.18.1.tgz", + "integrity": "sha512-dMInicTPVE8d1e5otfwmmjlxkZoUpiVLwyeTdUsi/Caj/gfzzblBcCE5sRHV/AsjuCmxWrte2TNGSYuCeCq+0Q==", + "dev": true, + "license": "MIT" + }, "node_modules/@stoplight/prism-cli/node_modules/yargs": { "version": "16.2.0", "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", @@ -1070,9 +1096,9 @@ } }, "node_modules/@stoplight/prism-core": { - "version": "5.8.0", - "resolved": "https://registry.npmjs.org/@stoplight/prism-core/-/prism-core-5.8.0.tgz", - "integrity": "sha512-fmH7n6e0thzOGcD5uZBu/Xx1iFNfpc9ACTxPie+lFD54SJ214M2FIFXD7kV+NCFlC+w5OFw+lJRaYM859uMnAg==", + "version": "5.15.10", + "resolved": "https://registry.npmjs.org/@stoplight/prism-core/-/prism-core-5.15.10.tgz", + "integrity": "sha512-FJsxsgYzOeRanCgmRq+pUWcSFNnodcurNXHVmep8Faqg9dkgzFLrx0cc1MfjbNVF+/4/dzvViilyLImrhFO47g==", "dev": true, "license": "Apache-2.0", "dependencies": { @@ -1082,23 +1108,23 @@ "tslib": "^2.3.1" }, "engines": { - "node": ">=18.20.1" + "node": ">=24.14.0" } }, "node_modules/@stoplight/prism-http": { - "version": "5.12.0", - "resolved": "https://registry.npmjs.org/@stoplight/prism-http/-/prism-http-5.12.0.tgz", - "integrity": "sha512-H+B/SO4SgQ6DT3CHIDCMQFGOe48Yecj0Eu+6rXwrs5m1JFyA2nlDwz+r73QJLGQanN4Biod2s0V9pZRcs2JnPA==", + "version": "5.15.10", + "resolved": "https://registry.npmjs.org/@stoplight/prism-http/-/prism-http-5.15.10.tgz", + "integrity": "sha512-N+3BUwJF8iMG98eY7z7u1uNJDhco7mOut9b6vTGuecOV6mfg4hrLkrNJDZDR3L7WQi34MF6ZmsvE5oSnL5KCLQ==", "dev": true, "license": "Apache-2.0", "dependencies": { - "@faker-js/faker": "^6.0.0", - "@stoplight/http-spec": "^7.0.3", + "@faker-js/faker": "^10.4.0", + "@stoplight/http-spec": "^7.1.0", "@stoplight/json": "3.21.7", "@stoplight/json-schema-merge-allof": "0.7.8", - "@stoplight/json-schema-ref-parser": "9.2.7", + "@stoplight/json-schema-ref-parser": "10.0.0", "@stoplight/json-schema-sampler": "0.3.0", - "@stoplight/prism-core": "^5.8.0", + "@stoplight/prism-core": "^5.15.10", "@stoplight/types": "^14.1.0", "@stoplight/yaml": "^4.2.3", "abstract-logging": "^2.0.1", @@ -1112,7 +1138,7 @@ "http-proxy-agent": "^5.0.0", "https-proxy-agent": "^5.0.0", "json-schema-faker": "0.5.8", - "lodash": "^4.17.21", + "lodash": "^4.17.23", "node-fetch": "^2.6.5", "parse-multipart-data": "^1.5.0", "pino": "^6.13.3", @@ -1123,23 +1149,23 @@ "whatwg-mimetype": "^3.0.0" }, "engines": { - "node": ">=18.20.1" + "node": ">=24.14.0" } }, "node_modules/@stoplight/prism-http-server": { - "version": "5.12.0", - "resolved": "https://registry.npmjs.org/@stoplight/prism-http-server/-/prism-http-server-5.12.0.tgz", - "integrity": "sha512-rnACUB950kvgDGXk1MsVk1v8nAZNCRaxdrTlACoJpQA0qzF8eBszYikoDsVmx2BbGsOrCC/49+nQc+HyFFpMdQ==", + "version": "5.15.10", + "resolved": "https://registry.npmjs.org/@stoplight/prism-http-server/-/prism-http-server-5.15.10.tgz", + "integrity": "sha512-jiVWjlZ0oBCzX6qG82Mh1671oNru1+rQkPDUE0s+W+M62lD3IVTSi3nLDobboylFLw/yV8U3ZR1SPrWS4qq+tw==", "dev": true, "license": "Apache-2.0", "dependencies": { - "@stoplight/prism-core": "^5.8.0", - "@stoplight/prism-http": "^5.12.0", + "@stoplight/prism-core": "^5.15.10", + "@stoplight/prism-http": "^5.15.10", "@stoplight/types": "^14.1.0", - "fast-xml-parser": "^4.2.0", + "fast-xml-parser": "^5.5.7", "fp-ts": "^2.11.5", "io-ts": "^2.2.16", - "lodash": "^4.17.21", + "lodash": "^4.17.23", "micri": "^4.3.0", "node-fetch": "^2.6.5", "parse-prefer-header": "1.0.0", @@ -1147,7 +1173,7 @@ "type-is": "^1.6.18" }, "engines": { - "node": ">=18.20.1" + "node": ">=24.14.0" } }, "node_modules/@stoplight/prism-http-server/node_modules/@stoplight/types": { @@ -1164,6 +1190,30 @@ "node": "^12.20 || >=14.13" } }, + "node_modules/@stoplight/prism-http-server/node_modules/lodash": { + "version": "4.18.1", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.18.1.tgz", + "integrity": "sha512-dMInicTPVE8d1e5otfwmmjlxkZoUpiVLwyeTdUsi/Caj/gfzzblBcCE5sRHV/AsjuCmxWrte2TNGSYuCeCq+0Q==", + "dev": true, + "license": "MIT" + }, + "node_modules/@stoplight/prism-http/node_modules/@faker-js/faker": { + "version": "10.4.0", + "resolved": "https://registry.npmjs.org/@faker-js/faker/-/faker-10.4.0.tgz", + "integrity": "sha512-sDBWI3yLy8EcDzgobvJTWq1MJYzAkQdpjXuPukga9wXonhpMRvd1Izuo2Qgwey2OiEoRIBr35RMU9HJRoOHzpw==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/fakerjs" + } + ], + "license": "MIT", + "engines": { + "node": "^20.19.0 || ^22.13.0 || ^23.5.0 || >=24.0.0", + "npm": ">=10" + } + }, "node_modules/@stoplight/prism-http/node_modules/@stoplight/types": { "version": "14.1.1", "resolved": "https://registry.npmjs.org/@stoplight/types/-/types-14.1.1.tgz", @@ -1178,6 +1228,27 @@ "node": "^12.20 || >=14.13" } }, + "node_modules/@stoplight/prism-http/node_modules/json-schema-faker": { + "version": "0.5.8", + "resolved": "https://registry.npmjs.org/json-schema-faker/-/json-schema-faker-0.5.8.tgz", + "integrity": "sha512-sqzPEbEDlpiH8U1tfmJHScXHy52onvMxITPsHyhe/jhS83g8TX6ruvRqt/ot1bXUPRsh7Ps1sWqJiBxIXmW5Xw==", + "dev": true, + "license": "MIT", + "dependencies": { + "json-schema-ref-parser": "^6.1.0", + "jsonpath-plus": "^10.1.0" + }, + "bin": { + "jsf": "bin/gen.cjs" + } + }, + "node_modules/@stoplight/prism-http/node_modules/lodash": { + "version": "4.18.1", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.18.1.tgz", + "integrity": "sha512-dMInicTPVE8d1e5otfwmmjlxkZoUpiVLwyeTdUsi/Caj/gfzzblBcCE5sRHV/AsjuCmxWrte2TNGSYuCeCq+0Q==", + "dev": true, + "license": "MIT" + }, "node_modules/@stoplight/spectral-core": { "version": "1.19.4", "resolved": "https://registry.npmjs.org/@stoplight/spectral-core/-/spectral-core-1.19.4.tgz", @@ -1523,9 +1594,9 @@ "license": "MIT" }, "node_modules/@types/type-is": { - "version": "1.6.6", - "resolved": "https://registry.npmjs.org/@types/type-is/-/type-is-1.6.6.tgz", - "integrity": "sha512-fs1KHv/f9OvmTMsu4sBNaUu32oyda9Y9uK25naJG8gayxNrfqGIjPQsbLIYyfe7xFkppnPlJB+BuTldOaX9bXw==", + "version": "1.6.7", + "resolved": "https://registry.npmjs.org/@types/type-is/-/type-is-1.6.7.tgz", + "integrity": "sha512-gEsh7n8824nusZ2Sidh6POxNsIdTSvIAl5gXbeFj+TUaD1CO2r4i7MQYNMfEQkChU42s2bVWAda6x6BzIhtFbQ==", "dev": true, "license": "MIT", "dependencies": { @@ -2093,13 +2164,13 @@ } }, "node_modules/cross-fetch": { - "version": "3.1.8", - "resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-3.1.8.tgz", - "integrity": "sha512-cvA+JwZoU0Xq+h6WkMvAUqPEYy92Obet6UdKLfW60qn99ftItKjB5T+BkyWOFWe2pUyfQ+IJHmpOTznqk1M6Kg==", + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-3.2.0.tgz", + "integrity": "sha512-Q+xVJLoGOeIMXZmbUK4HYk+69cQH6LudR0Vu/pRm2YlU/hDV9CiS0gKUMaWY5f2NeUH9C1nV3bsTlCo0FsTV1Q==", "dev": true, "license": "MIT", "dependencies": { - "node-fetch": "^2.6.12" + "node-fetch": "^2.7.0" } }, "node_modules/cross-spawn": { @@ -2633,36 +2704,44 @@ "dev": true, "license": "BSD-3-Clause" }, - "node_modules/fast-xml-parser": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/fast-xml-parser/-/fast-xml-parser-4.5.0.tgz", - "integrity": "sha512-/PlTQCI96+fZMAOLMZK4CWG1ItCbfZ/0jx7UIJFChPNrx7tcEgerUgWbeieCM9MfHInUDyK8DWYZ+YrywDJuTg==", + "node_modules/fast-xml-builder": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/fast-xml-builder/-/fast-xml-builder-1.1.5.tgz", + "integrity": "sha512-4TJn/8FKLeslLAH3dnohXqE3QSoxkhvaMzepOIZytwJXZO69Bfz0HBdDHzOTOon6G59Zrk6VQ2bEiv1t61rfkA==", "dev": true, "funding": [ { "type": "github", "url": "https://github.com/sponsors/NaturalIntelligence" - }, + } + ], + "license": "MIT", + "dependencies": { + "path-expression-matcher": "^1.1.3" + } + }, + "node_modules/fast-xml-parser": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/fast-xml-parser/-/fast-xml-parser-5.7.1.tgz", + "integrity": "sha512-8Cc3f8GUGUULg34pBch/KGyPLglS+OFs05deyOlY7fL2MTagYPKrVQNmR1fLF/yJ9PH5ZSTd3YDF6pnmeZU+zA==", + "dev": true, + "funding": [ { - "type": "paypal", - "url": "https://paypal.me/naturalintelligence" + "type": "github", + "url": "https://github.com/sponsors/NaturalIntelligence" } ], "license": "MIT", "dependencies": { - "strnum": "^1.0.5" + "@nodable/entities": "^2.1.0", + "fast-xml-builder": "^1.1.5", + "path-expression-matcher": "^1.5.0", + "strnum": "^2.2.3" }, "bin": { "fxparser": "src/cli/cli.js" } }, - "node_modules/fastestsmallesttextencoderdecoder": { - "version": "1.0.22", - "resolved": "https://registry.npmjs.org/fastestsmallesttextencoderdecoder/-/fastestsmallesttextencoderdecoder-1.0.22.tgz", - "integrity": "sha512-Pb8d48e+oIuY4MaM64Cd7OW1gt4nxCHs7/ddPPZ/Ic3sg8yVGM7O9wDvZ7us6ScaUupzM+pfBolwtYhN1IxBIw==", - "dev": true, - "license": "CC0-1.0" - }, "node_modules/fastq": { "version": "1.17.1", "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.17.1.tgz", @@ -2801,9 +2880,9 @@ "license": "MIT" }, "node_modules/fp-ts": { - "version": "2.16.9", - "resolved": "https://registry.npmjs.org/fp-ts/-/fp-ts-2.16.9.tgz", - "integrity": "sha512-+I2+FnVB+tVaxcYyQkHUq7ZdKScaBlX53A41mxQtpIccsfyv8PzdzP7fzp2AY832T4aoK6UZ5WRX/ebGd8uZuQ==", + "version": "2.16.11", + "resolved": "https://registry.npmjs.org/fp-ts/-/fp-ts-2.16.11.tgz", + "integrity": "sha512-LaI+KaX2NFkfn1ZGHoKCmcfv7yrZsC3b8NtWsTVQeHkq4F27vI5igUuO53sxqDEa2gNQMHFPmpojDw/1zmUK7w==", "dev": true, "license": "MIT" }, @@ -3211,13 +3290,6 @@ "url": "https://opencollective.com/immer" } }, - "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/internal-slot": { "version": "1.0.7", "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.7.tgz", @@ -3663,17 +3735,6 @@ "dev": true, "license": "ISC" }, - "node_modules/isomorphic-fetch": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/isomorphic-fetch/-/isomorphic-fetch-3.0.0.tgz", - "integrity": "sha512-qvUtwJ3j6qwsF3jLxkZ72qCgjMysPzDfeV240JHiGZsANBYd+EEuu35v7dfrJ9Up0Ak07D7GGSkGhCHTqg/5wA==", - "dev": true, - "license": "MIT", - "dependencies": { - "node-fetch": "^2.6.1", - "whatwg-fetch": "^3.4.1" - } - }, "node_modules/js-tokens": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", @@ -3743,19 +3804,38 @@ } }, "node_modules/json-schema-faker": { - "version": "0.5.8", - "resolved": "https://registry.npmjs.org/json-schema-faker/-/json-schema-faker-0.5.8.tgz", - "integrity": "sha512-sqzPEbEDlpiH8U1tfmJHScXHy52onvMxITPsHyhe/jhS83g8TX6ruvRqt/ot1bXUPRsh7Ps1sWqJiBxIXmW5Xw==", + "version": "0.5.9", + "resolved": "https://registry.npmjs.org/json-schema-faker/-/json-schema-faker-0.5.9.tgz", + "integrity": "sha512-fNKLHgDvfGNNTX1zqIjqFMJjCLzJ2kvnJ831x4aqkAoeE4jE2TxvpJdhOnk3JU3s42vFzmXvkpbYzH5H3ncAzg==", "dev": true, "license": "MIT", "dependencies": { "json-schema-ref-parser": "^6.1.0", - "jsonpath-plus": "^10.1.0" + "jsonpath-plus": "^10.3.0" }, "bin": { "jsf": "bin/gen.cjs" } }, + "node_modules/json-schema-faker/node_modules/jsonpath-plus": { + "version": "10.4.0", + "resolved": "https://registry.npmjs.org/jsonpath-plus/-/jsonpath-plus-10.4.0.tgz", + "integrity": "sha512-T92WWatJXmhBbKsgH/0hl+jxjdXrifi5IKeMY02DWggRxX0UElcbVzPlmgLTbvsPeW1PasQ6xE2Q75stkhGbsA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jsep-plugin/assignment": "^1.3.0", + "@jsep-plugin/regex": "^1.0.4", + "jsep": "^1.4.0" + }, + "bin": { + "jsonpath": "bin/jsonpath-cli.js", + "jsonpath-plus": "bin/jsonpath-cli.js" + }, + "engines": { + "node": ">=18.0.0" + } + }, "node_modules/json-schema-ref-parser": { "version": "6.1.0", "resolved": "https://registry.npmjs.org/json-schema-ref-parser/-/json-schema-ref-parser-6.1.0.tgz", @@ -3780,9 +3860,9 @@ } }, "node_modules/json-schema-ref-parser/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==", + "version": "3.14.2", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.2.tgz", + "integrity": "sha512-PMSmkqxr106Xa156c2M265Z+FTrPl+oxd/rgOQy2tijQeK5TxQ43psO1ZCwhVOSdnn+RzkzlRz/eY4BgJBYVpg==", "dev": true, "license": "MIT", "dependencies": { @@ -3849,6 +3929,16 @@ "node": ">=0.10.0" } }, + "node_modules/jsonrepair": { + "version": "3.14.0", + "resolved": "https://registry.npmjs.org/jsonrepair/-/jsonrepair-3.14.0.tgz", + "integrity": "sha512-tWPGKMZf/8UPim+fcW2EfcQ/d/7aKUrP6IECz9G3Tu6Q5dX0orSleqJ9z6sSw7qrQkjF8/Edo4DvsWBZ8H+HNg==", + "dev": true, + "license": "ISC", + "bin": { + "jsonrepair": "bin/cli.js" + } + }, "node_modules/leven": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz", @@ -4186,13 +4276,6 @@ "lodash.topath": "^4.5.2" } }, - "node_modules/node-abort-controller": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/node-abort-controller/-/node-abort-controller-3.1.1.tgz", - "integrity": "sha512-AGK2yQKIjRuqnc6VkX2Xj5d+QW8xZ87pa1UK6yA6ouUyuxfHuMP6umE5QK7UmTeOAymo+Zx1Fxiuw9rVx8taHQ==", - "dev": true, - "license": "MIT" - }, "node_modules/node-fetch": { "version": "2.7.0", "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz", @@ -4568,6 +4651,22 @@ "node": ">=8" } }, + "node_modules/path-expression-matcher": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/path-expression-matcher/-/path-expression-matcher-1.5.0.tgz", + "integrity": "sha512-cbrerZV+6rvdQrrD+iGMcZFEiiSrbv9Tfdkvnusy6y0x0GKBXREFg/Y65GhIfm0tnLntThhzCnfKwp1WRjeCyQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/NaturalIntelligence" + } + ], + "license": "MIT", + "engines": { + "node": ">=14.0.0" + } + }, "node_modules/path-key": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", @@ -4828,6 +4927,22 @@ "node": ">=6" } }, + "node_modules/qs": { + "version": "6.15.1", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.15.1.tgz", + "integrity": "sha512-6YHEFRL9mfgcAvql/XhwTvf5jKcOiiupt2FiJxHkiX1z4j7WL8J/jRHYLluORvc1XxB5rV20KoeK00gVJamspg==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "side-channel": "^1.1.0" + }, + "engines": { + "node": ">=0.6" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/queue-microtask": { "version": "1.2.3", "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", @@ -4870,21 +4985,6 @@ "node": ">=0.10.0" } }, - "node_modules/readable-stream": { - "version": "3.6.2", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", - "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", - "dev": true, - "license": "MIT", - "dependencies": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - }, - "engines": { - "node": ">= 6" - } - }, "node_modules/readdirp": { "version": "3.6.0", "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", @@ -5035,27 +5135,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/safe-buffer": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", - "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "license": "MIT" - }, "node_modules/safe-regex-test": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.0.3.tgz", @@ -5426,13 +5505,13 @@ } }, "node_modules/split2": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/split2/-/split2-3.2.2.tgz", - "integrity": "sha512-9NThjpgZnifTkJpzTZ7Eue85S49QwpNhZTq6GRJwObb6jnLFNGB7Qm73V5HewTROPyxD0C29xqmaI68bQtV+hg==", + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/split2/-/split2-4.2.0.tgz", + "integrity": "sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg==", "dev": true, "license": "ISC", - "dependencies": { - "readable-stream": "^3.0.0" + "engines": { + "node": ">= 10.x" } }, "node_modules/sprintf-js": { @@ -5442,16 +5521,6 @@ "dev": true, "license": "BSD-3-Clause" }, - "node_modules/string_decoder": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", - "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", - "dev": true, - "license": "MIT", - "dependencies": { - "safe-buffer": "~5.2.0" - } - }, "node_modules/string-argv": { "version": "0.3.2", "resolved": "https://registry.npmjs.org/string-argv/-/string-argv-0.3.2.tgz", @@ -5570,10 +5639,16 @@ } }, "node_modules/strnum": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/strnum/-/strnum-1.0.5.tgz", - "integrity": "sha512-J8bbNyKKXl5qYcR36TIO8W3mVGVHrmmxsd5PAItGkmyzwJvybiw2IVq5nqd0i4LSNSkB/sx9VHllbfFdr9k1JA==", + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/strnum/-/strnum-2.2.3.tgz", + "integrity": "sha512-oKx6RUCuHfT3oyVjtnrmn19H1SiCqgJSg+54XqURKp5aCMbrXrhLjRN9TjuwMjiYstZ0MzDrHqkGZ5dFTKd+zg==", "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/NaturalIntelligence" + } + ], "license": "MIT" }, "node_modules/supports-color": { @@ -6279,6 +6354,27 @@ "dev": true, "license": "MIT" }, + "node_modules/url": { + "version": "0.11.4", + "resolved": "https://registry.npmjs.org/url/-/url-0.11.4.tgz", + "integrity": "sha512-oCwdVC7mTuWiPyjLUz/COz5TLk6wgp0RCsN+wHZ2Ekneac9w8uuV0njcbbie2ME+Vs+d6duwmYuR3HgQXs1fOg==", + "dev": true, + "license": "MIT", + "dependencies": { + "punycode": "^1.4.1", + "qs": "^6.12.3" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/url/node_modules/punycode": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", + "integrity": "sha512-jmYNElW7yvO7TV33CjSmvSiE2yco3bV2czu/OzDKdMNVZQWfxCblURLhf+47syQRBntjfLdd/H0egrzIG+oaFQ==", + "dev": true, + "license": "MIT" + }, "node_modules/use-sync-external-store": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/use-sync-external-store/-/use-sync-external-store-1.4.0.tgz", @@ -6289,13 +6385,6 @@ "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" } }, - "node_modules/util-deprecate": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", - "dev": true, - "license": "MIT" - }, "node_modules/utility-types": { "version": "3.11.0", "resolved": "https://registry.npmjs.org/utility-types/-/utility-types-3.11.0.tgz", @@ -6371,13 +6460,6 @@ "dev": true, "license": "BSD-2-Clause" }, - "node_modules/whatwg-fetch": { - "version": "3.6.20", - "resolved": "https://registry.npmjs.org/whatwg-fetch/-/whatwg-fetch-3.6.20.tgz", - "integrity": "sha512-EqhiFU6daOA8kpjOWTL0olhVOF3i7OrFzSYiGsEMB8GcXS+RrzauAERX65xMeNWVqxA6HXH2m69Z9LaKKdisfg==", - "dev": true, - "license": "MIT" - }, "node_modules/whatwg-mimetype": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-3.0.0.tgz", diff --git a/package.json b/package.json index c5eb2fa..3798e49 100644 --- a/package.json +++ b/package.json @@ -11,7 +11,8 @@ "buildstep": "npm run generate:api && npm run test:types" }, "devDependencies": { - "@stoplight/prism-cli": "^5.0.0", + "@faker-js/faker": "^9.0.0", + "@stoplight/prism-cli": "^5.15.10", "@tanstack/react-query": "^4.0.0", "@types/js-yaml": "^4.0.5", "@types/node": "^20.0.0", diff --git a/scripts/combine-yaml.ts b/scripts/combine-yaml.ts index 32be0d8..c499e26 100644 --- a/scripts/combine-yaml.ts +++ b/scripts/combine-yaml.ts @@ -1,6 +1,7 @@ import * as fs from 'fs'; import * as path from 'path'; import * as yaml from 'js-yaml'; +import { generateStationHistoryExamples } from './generate-examples.js'; const componentsDir = './components'; const outputFile = './openapi.combined.yaml'; @@ -58,6 +59,11 @@ componentFiles.forEach(file => { // Update all references in the main spec updateRefs(mainSpec); +// Inject fresh date-relative examples for station history +const stationHistoryResponse = + mainSpec.paths['/stations/{id}/history'].get.responses['200'].content['application/json']; +stationHistoryResponse.examples = generateStationHistoryExamples(); + // Write the combined spec fs.writeFileSync(outputFile, yaml.dump(mainSpec)); console.log('Combined OpenAPI specification written to', outputFile); diff --git a/scripts/generate-examples.ts b/scripts/generate-examples.ts new file mode 100644 index 0000000..aad76d4 --- /dev/null +++ b/scripts/generate-examples.ts @@ -0,0 +1,101 @@ +import { faker } from "@faker-js/faker"; + +const GENERATOR_IDS = ["GEN.A01.001", "GEN.A01.002"]; + +function mw(): number { + return Math.round(faker.number.float({ min: 5, max: 50 }) * 10) / 10; +} + +function cap(): number { + return Math.round(faker.number.float({ min: 20, max: 98 }) * 10) / 10; +} + +function dayStart(daysAgo: number): Date { + const d = new Date(); + d.setUTCHours(0, 0, 0, 0); + d.setUTCDate(d.getUTCDate() - daysAgo); + return d; +} + +function isoHour(base: Date, hour: number): string { + const d = new Date(base); + d.setUTCHours(hour, 0, 0, 0); + return d.toISOString(); +} + +type GeneratorReading = { + generator_id: string; + power_reading_mw: number; + is_producing: boolean; +}; + +type HistoryItem = { + timestamp: string; + power_reading_mw: { value: number }; + used_capacity_percentage: { value: number }; + generator_readings: GeneratorReading[]; +}; + +function generatorReadings(producing: boolean[]): GeneratorReading[] { + return GENERATOR_IDS.map((id, i) => ({ + generator_id: id, + power_reading_mw: producing[i] ? mw() : 0, + is_producing: producing[i], + })); +} + +function buildDaily28(): HistoryItem[] { + return Array.from({ length: 28 }, (_, i) => { + const ts = dayStart(27 - i); + ts.setUTCHours(0, 0, 0, 0); + return { + timestamp: ts.toISOString(), + power_reading_mw: { value: mw() }, + used_capacity_percentage: { value: cap() }, + generator_readings: [], + }; + }); +} + +function buildTodayHourly(): HistoryItem[] { + const today = dayStart(0); + return Array.from({ length: 24 }, (_, h) => ({ + timestamp: isoHour(today, h), + power_reading_mw: { value: mw() }, + used_capacity_percentage: { value: cap() }, + generator_readings: generatorReadings([ + faker.datatype.boolean({ probability: 0.85 }), + faker.datatype.boolean({ probability: 0.85 }), + ]), + })); +} + +function buildHourly28Days(): HistoryItem[] { + const items: HistoryItem[] = []; + for (let d = 27; d >= 0; d--) { + const base = dayStart(d); + for (let h = 0; h < 24; h++) { + items.push({ + timestamp: isoHour(base, h), + power_reading_mw: { value: mw() }, + used_capacity_percentage: { value: cap() }, + generator_readings: generatorReadings([ + faker.datatype.boolean({ probability: 0.85 }), + faker.datatype.boolean({ probability: 0.85 }), + ]), + }); + } + } + return items; +} + +export function generateStationHistoryExamples(): Record< + string, + { value: { history: HistoryItem[] } } +> { + return { + "daily-28": { value: { history: buildDaily28() } }, + "today-hourly": { value: { history: buildTodayHourly() } }, + "hourly-28-days": { value: { history: buildHourly28Days() } }, + }; +}