diff --git a/Dockerfile b/Dockerfile index 6dc1677..151ec72 100644 --- a/Dockerfile +++ b/Dockerfile @@ -27,7 +27,6 @@ ARG NUXT_PUBLIC_MATOMO_BASE_URL ARG NUXT_PUBLIC_MATOMO_ID ARG NUXT_PUBLIC_REDMINE_ID ARG NUXT_PUBLIC_API_BASE_URL -ARG NUXT_PUBLIC_API_SPEC_URL RUN pnpm install --frozen-lockfile --offline diff --git a/nuxt.config.ts b/nuxt.config.ts index b7224d7..63a6442 100644 --- a/nuxt.config.ts +++ b/nuxt.config.ts @@ -77,9 +77,8 @@ export default defineNuxtConfig({ runtimeConfig: { NODE_ENV: process.env.NODE_ENV, public: { - NUXT_PUBLIC_APP_BASE_URL: process.env.NUXT_PUBLIC_APP_BASE_URL, NUXT_PUBLIC_API_BASE_URL: process.env.NUXT_PUBLIC_API_BASE_URL, - NUXT_PUBLIC_API_SPEC_URL: process.env.NUXT_PUBLIC_API_SPEC_URL, + NUXT_PUBLIC_APP_BASE_URL: process.env.NUXT_PUBLIC_APP_BASE_URL, NUXT_PUBLIC_BOTS: process.env.NUXT_PUBLIC_BOTS, NUXT_PUBLIC_MATOMO_BASE_URL: process.env.NUXT_PUBLIC_MATOMO_BASE_URL, NUXT_PUBLIC_MATOMO_ID: process.env.NUXT_PUBLIC_MATOMO_ID, diff --git a/package.json b/package.json index 9f12c1f..11b51a9 100644 --- a/package.json +++ b/package.json @@ -32,7 +32,7 @@ "test:e2e:ui": "playwright test --ui", "types:check": "nuxt typecheck", "validate": "run-p format:check lint:check types:check test test:e2e", - "createclient": "npx tsx ./scripts/generate-api-client.ts" + "createclient": "dotenv -c -- tsx ./scripts/generate-api-client.ts" }, "dependencies": { "@acdh-oeaw/lib": "^0.1.7", @@ -55,10 +55,8 @@ "lodash": "^4.17.21", "lucide-vue-next": "^0.356.0", "maplibre-gl": "^4.1.3", - "mkdirp": "^3.0.1", "openapi-zod-client": "^1.16.2", "pino-http": "^9.0.0", - "rimraf": "^5.0.7", "satori": "^0.10.13", "vue": "^3.4.21", "vue-i18n": "^9.10.1", @@ -79,22 +77,20 @@ "@playwright/test": "^1.42.1", "@tailwindcss/typography": "^0.5.12", "@types/d3": "^7.4.3", - "@types/js-yaml": "^4.0.9", "@types/lodash": "^4.17.0", "@types/node": "^20.11.26", "axe-core": "^4.8.4", "axe-playwright": "^2.0.1", "ci-info": "^4.0.0", "dotenv": "^16.4.5", + "dotenv-cli": "^7.4.2", "dotenv-expand": "^11.0.6", "eslint": "^8.57.0", "eslint-plugin-tailwindcss": "^3.15.1", "is-ci": "^3.0.1", - "js-yaml": "^4.1.0", "lint-staged": "^15.2.2", "npm-run-all2": "^6.1.2", "nuxt": "^3.10.3", - "openapi-endpoint-trimmer": "^2.0.0", "openapi3-ts": "^4.3.3", "postcss": "^8.4.35", "prettier": "^3.2.5", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 85bbb2c..6df300b 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -65,18 +65,12 @@ dependencies: maplibre-gl: specifier: ^4.1.3 version: 4.1.3 - mkdirp: - specifier: ^3.0.1 - version: 3.0.1 openapi-zod-client: specifier: ^1.16.2 version: 1.16.2 pino-http: specifier: ^9.0.0 version: 9.0.0 - rimraf: - specifier: ^5.0.7 - version: 5.0.7 satori: specifier: ^0.10.13 version: 0.10.13 @@ -133,9 +127,6 @@ devDependencies: '@types/d3': specifier: ^7.4.3 version: 7.4.3 - '@types/js-yaml': - specifier: ^4.0.9 - version: 4.0.9 '@types/lodash': specifier: ^4.17.0 version: 4.17.0 @@ -154,6 +145,9 @@ devDependencies: dotenv: specifier: ^16.4.5 version: 16.4.5 + dotenv-cli: + specifier: ^7.4.2 + version: 7.4.2 dotenv-expand: specifier: ^11.0.6 version: 11.0.6 @@ -166,9 +160,6 @@ devDependencies: is-ci: specifier: ^3.0.1 version: 3.0.1 - js-yaml: - specifier: ^4.1.0 - version: 4.1.0 lint-staged: specifier: ^15.2.2 version: 15.2.2 @@ -178,9 +169,6 @@ devDependencies: nuxt: specifier: ^3.10.3 version: 3.10.3(@types/node@20.11.26)(eslint@8.57.0)(rollup@4.13.0)(stylelint@16.2.1)(typescript@5.4.2)(vite@5.1.6)(vue-tsc@2.0.6) - openapi-endpoint-trimmer: - specifier: ^2.0.0 - version: 2.0.0 openapi3-ts: specifier: ^4.3.3 version: 4.3.3 @@ -3010,10 +2998,6 @@ packages: dependencies: '@types/node': 20.11.26 - /@types/js-yaml@4.0.9: - resolution: {integrity: sha512-k4MGaQl5TGo/iipqb2UDG2UwjXziSWkh0uysQelTlJpX1qGlpUZYm8PnO4DxG1qBomtJUdYJ6qR6xdIah10JLg==} - dev: true - /@types/json-schema@7.0.15: resolution: {integrity: sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==} dev: true @@ -4252,11 +4236,6 @@ packages: resolution: {integrity: sha512-Fu4hJdvzeylCfQPp9SGWidpzrMs7tTrlu6Vb8XGaRGck8QSNZJJp538Wrb60Lax4fPwR64ViY468OIUTbRlGZg==} dev: false - /commander@10.0.1: - resolution: {integrity: sha512-y4Mg2tXshplEbSGzx7amzPwKKOCGuoSRP/CjEdwwk0FOGlUbq6lKuoyDZTNZkmxHdJtp54hdfY/JUrdL7Xfdug==} - engines: {node: '>=14'} - dev: true - /commander@11.1.0: resolution: {integrity: sha512-yPVavfyCcRhmorC7rWlkHn15b4wDVgVmBA7kV4QVBsF7kv/9TKJAbAXVTxvTnwP8HHKjRCJDClKbciiYS7p0DQ==} engines: {node: '>=16'} @@ -4977,6 +4956,21 @@ packages: dependencies: type-fest: 3.13.1 + /dotenv-cli@7.4.2: + resolution: {integrity: sha512-SbUj8l61zIbzyhIbg0FwPJq6+wjbzdn9oEtozQpZ6kW2ihCcapKVZj49oCT3oPM+mgQm+itgvUQcG5szxVrZTA==} + hasBin: true + dependencies: + cross-spawn: 7.0.3 + dotenv: 16.4.5 + dotenv-expand: 10.0.0 + minimist: 1.2.8 + dev: true + + /dotenv-expand@10.0.0: + resolution: {integrity: sha512-GopVGCpVS1UKH75VKHGuQFqS1Gusej0z4FyQkPdwjil2gNIv+LNsqBlboOzpJFZKVT95GkCyWJbBSdFEFUWI2A==} + engines: {node: '>=12'} + dev: true + /dotenv-expand@11.0.6: resolution: {integrity: sha512-8NHi73otpWsZGBSZwwknTXS5pqMOrk9+Ssrna8xCaxkzEpU9OTf9R5ArQGVw03//Zmk9MOwLPng9WwndvpAJ5g==} engines: {node: '>=12'} @@ -7414,7 +7408,6 @@ packages: /minimist@1.2.8: resolution: {integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==} requiresBuild: true - dev: false /minipass-collect@2.0.1: resolution: {integrity: sha512-D7V8PO9oaz7PWGLbCACuI1qEOsq7UKfLotx/C0Aet43fCUB/wfQ7DYeq2oR/svFJGYDHPr38SHATeaj/ZoKHKw==} @@ -7492,12 +7485,6 @@ packages: engines: {node: '>=10'} hasBin: true - /mkdirp@3.0.1: - resolution: {integrity: sha512-+NsyUUAZDmo6YVHzL/stxSu3t9YS1iljliy3BSDrXJ/dkn1KYdmtZODGGjLcc9XLgVVpH4KshHB8XmZgMhaBXg==} - engines: {node: '>=10'} - hasBin: true - dev: false - /mlly@1.6.1: resolution: {integrity: sha512-vLgaHvaeunuOXHSmEbZ9izxPx3USsk8KCQ8iC+aTlp5sKRSoZvwhHh5L9VbKSaVC6sJDqbyohIS76E2VmHIPAA==} dependencies: @@ -8068,17 +8055,6 @@ packages: is-docker: 2.2.1 is-wsl: 2.2.0 - /openapi-endpoint-trimmer@2.0.0: - resolution: {integrity: sha512-0eHcIbHkItgk9S8mHPMn8Zn+jsdBztc2KHEaUmJYdq70vzgDr6WF9k4npisb7LhUeH3GN2d6YmKy30Xzs7GXAQ==} - hasBin: true - dependencies: - chalk: 5.3.0 - commander: 10.0.1 - js-yaml: 4.1.0 - undici: 5.28.3 - zod: 3.22.4 - dev: true - /openapi-types@12.1.3: resolution: {integrity: sha512-N4YtSYJqghVu4iek2ZUvcN/0aqH1kRDuNqzcycDxhOUpg7GdvLa2F3DgS6yBNhInhv2r/6I0Flkn7CqL8+nIcw==} dev: false @@ -9187,14 +9163,6 @@ packages: dependencies: glob: 7.2.3 - /rimraf@5.0.7: - resolution: {integrity: sha512-nV6YcJo5wbLW77m+8KjH8aB/7/rxQy9SZ0HY5shnwULfS+9nmTtVXAJET5NdZmCzA4fPI/Hm1wo/Po/4mopOdg==} - engines: {node: '>=14.18'} - hasBin: true - dependencies: - glob: 10.3.10 - dev: false - /robust-predicates@3.0.2: resolution: {integrity: sha512-IXgzBWvWQwE6PrDI05OvmXUIruQTcoMDzRsOd5CDvHCVLcLHMTSYvOK5Cm46kWqlV3yAbuSpBZdJ5oP5OUoStg==} dev: false @@ -11120,6 +11088,7 @@ packages: /zod@3.22.4: resolution: {integrity: sha512-iC+8Io04lddc+mVqQ9AZ7OQ2MrUKGN+oIQyq1vemgt46jwCwLfhq7/pwnBnNXXXZb8VTVLKwp9EDkx+ryxIWmg==} + dev: false /zwitch@2.0.4: resolution: {integrity: sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A==} diff --git a/scripts/generate-api-client.ts b/scripts/generate-api-client.ts index cb80ef3..90168d5 100644 --- a/scripts/generate-api-client.ts +++ b/scripts/generate-api-client.ts @@ -1,58 +1,63 @@ -import { load } from "js-yaml"; +import { createUrl, createUrlSearchParams, log, request } from "@acdh-oeaw/lib"; import { generateZodClientFromOpenAPI } from "openapi-zod-client"; import type { OpenAPIObject, PathsObject } from "openapi3-ts/oas30"; +import { z } from "zod"; -console.log("Starting zod client generation"); -const options = { - url: "https://sicprod.acdh-dev.oeaw.ac.at/apis/swagger/schema/?format=json", - prefixes: [ - "/apis/api/apis_ontology.event", - "/apis/api/apis_ontology.function", - "/apis/api/apis_ontology.institution", - "/apis/api/apis_ontology.person", - "/apis/api/apis_ontology.place", - "/apis/api/apis_ontology.salary", - ], - dist: "./lib/api.ts", -}; +const outputPath = "./lib/api.ts"; +async function main() { + log.info("Starting zod client generation"); + + const apisBaseURL = z.string().url().parse(process.env.NUXT_PUBLIC_API_BASE_URL); + + const options = { + url: createUrl({ + baseUrl: apisBaseURL, + pathname: "/apis/swagger/schema", + searchParams: createUrlSearchParams({ format: "json" }), + }), + prefixes: [ + "/apis/api/apis_ontology.event", + "/apis/api/apis_ontology.function", + "/apis/api/apis_ontology.institution", + "/apis/api/apis_ontology.person", + "/apis/api/apis_ontology.place", + "/apis/api/apis_ontology.salary", + ], + dist: outputPath, + }; -let data: string; -if (options.url) { // download swagger file - const response = await fetch(options.url); - if (!response.ok) { - throw new Error( - `Received a non-200 response when downloading from ${options.url}. Received ${response.statusText}. Please double check your setup.`, - ); - } - data = await response.text(); -} else { - throw new Error(`Found neither an input URL or an input file!`); -} + const data = await request(options.url, { responseType: "json" }); -// trim swagger file to only contain the prefixes specified in options.prefixes -const prefixes = options.prefixes; -let openApiDoc: OpenAPIObject = load(data) as OpenAPIObject; -const paths: PathsObject = {}; -for (const path of Object.keys(openApiDoc.paths)) { - if (prefixes.some((retain) => path.startsWith(retain))) { - paths[path] = openApiDoc.paths[path] ?? {}; + // trim swagger file to only contain the prefixes specified in options.prefixes + const prefixes = options.prefixes; + let openApiDoc: OpenAPIObject = data as OpenAPIObject; + const paths: PathsObject = {}; + for (const [key, value] of Object.entries(openApiDoc.paths)) { + if (prefixes.some((retain) => key.startsWith(retain))) { + paths[key] = value; + } } -} -openApiDoc = { - ...openApiDoc, - paths, -}; + openApiDoc = { + ...openApiDoc, + paths, + }; -// use the trimmed openAPIDoc with openapi-zod-client -await generateZodClientFromOpenAPI({ - openApiDoc, - distPath: options.dist, - options: { - shouldExportAllTypes: true, - withAlias: true, - }, -}); + // use the trimmed openAPIDoc with openapi-zod-client + await generateZodClientFromOpenAPI({ + openApiDoc, + distPath: options.dist, + options: { + shouldExportAllTypes: true, + withAlias: true, + }, + }); +} -console.log("Client creation completed"); -console.log("Output was written to: ", options.dist); +main() + .then(() => { + log.success("Client creation completed. \nOutput was written to: ", outputPath); + }) + .catch((err) => { + log.error("Client creation failed", String(err)); + });