From 10399309ca97efc9f783878545fac93f725dd0a4 Mon Sep 17 00:00:00 2001 From: ismailbennani Date: Thu, 24 Apr 2025 13:51:23 +0200 Subject: [PATCH 1/4] use static env instead of placeholders to avoid breaking local builds --- docs/.vitepress/config.mts | 76 +++++++++++++++++++++++++++++--- docs/.vitepress/theme/custom.css | 9 ++++ docs/src/env.data.ts | 21 +++++++++ docs/src/env.json | 10 +++++ docs/src/index.md | 4 +- 5 files changed, 112 insertions(+), 8 deletions(-) create mode 100644 docs/src/env.data.ts create mode 100644 docs/src/env.json diff --git a/docs/.vitepress/config.mts b/docs/.vitepress/config.mts index 79ffeab5..7cbb2883 100644 --- a/docs/.vitepress/config.mts +++ b/docs/.vitepress/config.mts @@ -1,6 +1,7 @@ import {defineConfigWithTheme} from "vitepress"; // https://vitepress.dev/reference/site-config import {useSidebar} from "vitepress-openapi"; import {getSidebar} from "vitepress-plugin-auto-sidebar"; +import env from "../src/env.json" with {type: "json"}; import spec from "../src/assets/facturxdotnet.openapi.json" with {type: "json"}; const specSidebar = useSidebar({ @@ -71,11 +72,11 @@ export default defineConfigWithTheme({ items: [ { text: "Try the Editor", - link: "{EDITOR-URL}", + link: env.editor.url, }, { text: "Try the API", - link: "{API-URL}", + link: env.api.url, }, ], }, @@ -152,7 +153,10 @@ export default defineConfigWithTheme({ link: "/guides/about", }, { - text: "v{VERSION}", + text: `${env.buildName}`, + }, + { + text: `${env.version}`, }, ], "/openapi-specification/": [ @@ -162,20 +166,29 @@ export default defineConfigWithTheme({ }, ...specSidebar.generateSidebarGroups(), { - text: "v{VERSION}", + text: `${env.buildName}`, + }, + { + text: `${env.version}`, }, ], "/cli/": [ ...cliItems, { - text: "v{VERSION}", + text: `${env.buildName}`, + }, + { + text: `${env.version}`, }, ], "/api-reference/": [ { text: "Index", link: "/api-reference/index" }, ...apiReferenceItems, { - text: "v{VERSION}", + text: `${env.buildName}`, + }, + { + text: `${env.version}`, }, ], }, @@ -209,4 +222,55 @@ export default defineConfigWithTheme({ noExternal: ["vitepress-plugin-nprogress"], }, }, + + transformPageData: pageData => { + const result = { ...pageData }; + result.frontmatter = expandEnvInRecord(pageData.frontmatter); + return result; + }, }); + +function expandEnv(value: unknown): unknown { + if (typeof value === "string" || value instanceof String) { + return expandEnvInString(value); + } else if (value.constructor.name == "Array") { + return expandEnvInArray(value); + } else { + return expandEnvInRecord(value); + } +} + +function expandEnvInArray(array: unknown[]): unknown[] { + return array.map(expandEnv); +} + +function expandEnvInRecord( + record: Record, +): Record { + const result = {}; + + for (const key of Object.keys(record)) { + result[key] = expandEnv(record[key]); + } + + return result; +} + +function expandEnvInString(value: string): string { + return value.replace(/\$env\.([^ ]*)/g, (_, varName) => getEnvValue(varName)); +} + +function getEnvValue(varName: string): string { + const fragments = varName.split("."); + let result = env; + + for (const fragment of fragments) { + if (!Object.keys(result).includes(fragment)) { + return ""; + } + + result = result[fragment]; + } + + return result; +} diff --git a/docs/.vitepress/theme/custom.css b/docs/.vitepress/theme/custom.css index f4c7db15..a3496ecc 100644 --- a/docs/.vitepress/theme/custom.css +++ b/docs/.vitepress/theme/custom.css @@ -10,6 +10,15 @@ --vp-c-brand-3: #512bd4; } +p:has(.sidebar-footer) { + padding: 0 !important; + line-height: unset !important; +} + +p:has(.sidebar-footer-first) { + margin-top: 24px; +} + .sidebar-footer { font-size: 0.75rem; color: var(--vp-c-text-3); diff --git a/docs/src/env.data.ts b/docs/src/env.data.ts new file mode 100644 index 00000000..9cdb8d59 --- /dev/null +++ b/docs/src/env.data.ts @@ -0,0 +1,21 @@ +import fs from "node:fs"; + +export default { + watch: ["./env.json"], + load(watchedFile) { + const file = watchedFile[0]; + const fileContent = fs.readFileSync(file, "utf-8"); + return JSON.parse(fileContent) as Env; + }, +}; + +interface Env { + buildName: string; + version: string; + editor: { + url: string; + }; + api: { + url: string; + }; +} diff --git a/docs/src/env.json b/docs/src/env.json new file mode 100644 index 00000000..bc44b21f --- /dev/null +++ b/docs/src/env.json @@ -0,0 +1,10 @@ +{ + "buildName": "dev", + "version": "~dev", + "editor": { + "url": "http://localhost:4200" + }, + "api": { + "url": "http://localhost:5295" + } +} diff --git a/docs/src/index.md b/docs/src/index.md index ed7c2d92..f2387ff4 100644 --- a/docs/src/index.md +++ b/docs/src/index.md @@ -28,7 +28,7 @@ features: alt: 'WebSite' } details: Create, view, and edit Factur-X documents directly in your browser with our user-friendly editor. - link: {EDITOR-URL} + link: $env.editor.url linkText: Try it live - title: API icon: { @@ -37,7 +37,7 @@ features: alt: 'API' } details: Programmatically generate, read, and validate Factur-X documents through our powerful API. - link: {API-URL} + link: $env.api.url linkText: Try it live - title: .NET library and tool icon: { From 41fc7d00af2853474b7024bd678e7064c71b4abc Mon Sep 17 00:00:00 2001 From: ismailbennani Date: Thu, 24 Apr 2025 13:54:11 +0200 Subject: [PATCH 2/4] update build script --- .../reusable-build-deploy-api-editor-docs.yml | 1 + .../reusable-build-docs-application.yml | 21 ++++++++++++++++--- 2 files changed, 19 insertions(+), 3 deletions(-) diff --git a/.github/workflows/reusable-build-deploy-api-editor-docs.yml b/.github/workflows/reusable-build-deploy-api-editor-docs.yml index 0ee2b9a0..19fd5e5a 100644 --- a/.github/workflows/reusable-build-deploy-api-editor-docs.yml +++ b/.github/workflows/reusable-build-deploy-api-editor-docs.yml @@ -51,6 +51,7 @@ jobs: uses: ./.github/workflows/reusable-build-docs-application.yml with: artifact-name: docs + build-name: ${{ inputs.build-name }} api-url: https://${{ inputs.build-name }}.facturxdotnet.org/api editor-url: https://${{ inputs.build-name }}.facturxdotnet.org/editor version: ${{ needs.compute-version.outputs.version }} diff --git a/.github/workflows/reusable-build-docs-application.yml b/.github/workflows/reusable-build-docs-application.yml index 237fb916..cbaed96d 100644 --- a/.github/workflows/reusable-build-docs-application.yml +++ b/.github/workflows/reusable-build-docs-application.yml @@ -8,6 +8,11 @@ on: type: string required: true + build-name: + description: The name of the build, defaults to 'build' + type: string + required: true + api-url: description: The URL at which the FacturX.NET API will be served type: string @@ -198,10 +203,20 @@ jobs: echo echo - - name: Set version number + - name: Write env.json run: | - sed -i -e 's|{VERSION}|${{ inputs.version }}|g' -e 's|{API-URL}|${{ inputs.api-url }}|g' -e 's|{EDITOR-URL}|${{ inputs.editor-url }}|g' docs/.vitepress/config.mts - sed -i -e 's|{VERSION}|${{ inputs.version }}|g' -e 's|{API-URL}|${{ inputs.api-url }}|g' -e 's|{EDITOR-URL}|${{ inputs.editor-url }}|g' docs/src/index.md + echo '{' > docs/src/env.json + echo ' "buildName": "${{ inputs.build-name }}",' >> docs/src/env.json + echo ' "version": "${{ inputs.version }}",' >> docs/src/env.json + echo ' "editor": {' >> docs/src/env.json + echo ' "url": "${{ inputs.editor-url }}' >> docs/src/env.json + echo ' },' >> docs/src/env.json + echo ' "api": {' >> docs/src/env.json + echo ' "url": "${{ inputs.api-url }}"' >> docs/src/env.json + echo ' }' >> docs/src/env.json + echo '}' >> docs/src/env.json + + cat docs/src/env.json - name: Build run: cd docs; npm run build -- --base /docs/ --outDir dist/ From 50b57b8b9d92df689103041715b5cfcbdaf49d78 Mon Sep 17 00:00:00 2001 From: ismailbennani Date: Thu, 24 Apr 2025 14:01:19 +0200 Subject: [PATCH 3/4] fix build script --- .github/workflows/reusable-build-docs-application.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/reusable-build-docs-application.yml b/.github/workflows/reusable-build-docs-application.yml index cbaed96d..af841d0f 100644 --- a/.github/workflows/reusable-build-docs-application.yml +++ b/.github/workflows/reusable-build-docs-application.yml @@ -209,7 +209,7 @@ jobs: echo ' "buildName": "${{ inputs.build-name }}",' >> docs/src/env.json echo ' "version": "${{ inputs.version }}",' >> docs/src/env.json echo ' "editor": {' >> docs/src/env.json - echo ' "url": "${{ inputs.editor-url }}' >> docs/src/env.json + echo ' "url": "${{ inputs.editor-url }}"' >> docs/src/env.json echo ' },' >> docs/src/env.json echo ' "api": {' >> docs/src/env.json echo ' "url": "${{ inputs.api-url }}"' >> docs/src/env.json From 915192a509d1ffb69c0316c8daa602842caa3a7f Mon Sep 17 00:00:00 2001 From: ismailbennani Date: Thu, 24 Apr 2025 14:31:21 +0200 Subject: [PATCH 4/4] improve sidebar footer --- docs/.vitepress/config.mts | 71 +++++++++++++++----------------- docs/.vitepress/theme/custom.css | 9 ++-- docs/package-lock.json | 2 +- docs/package.json | 1 + 4 files changed, 40 insertions(+), 43 deletions(-) diff --git a/docs/.vitepress/config.mts b/docs/.vitepress/config.mts index 7cbb2883..d4505fd4 100644 --- a/docs/.vitepress/config.mts +++ b/docs/.vitepress/config.mts @@ -1,8 +1,9 @@ -import {defineConfigWithTheme} from "vitepress"; // https://vitepress.dev/reference/site-config -import {useSidebar} from "vitepress-openapi"; -import {getSidebar} from "vitepress-plugin-auto-sidebar"; -import env from "../src/env.json" with {type: "json"}; -import spec from "../src/assets/facturxdotnet.openapi.json" with {type: "json"}; +import { defineConfigWithTheme } from "vitepress"; // https://vitepress.dev/reference/site-config +import { useSidebar } from "vitepress-openapi"; +import { getSidebar } from "vitepress-plugin-auto-sidebar"; +import semver from "semver"; +import env from "../src/env.json" with { type: "json" }; +import spec from "../src/assets/facturxdotnet.openapi.json" with { type: "json" }; const specSidebar = useSidebar({ spec, @@ -24,7 +25,7 @@ let cliItems = collapsed: false, collapsible: false, })[0]?.items ?? []; -cliItems = cliItems.map(item => ({ +cliItems = cliItems.map((item) => ({ ...item, text: item.text.toLowerCase() === "subcommands" ? "Sub Commands" : item.text, })); @@ -38,9 +39,26 @@ let apiReferenceItems = collapsible: true, })[0]?.items ?? []; apiReferenceItems = apiReferenceItems.filter( - i => i.items !== undefined && i.items.length > 0, + (i) => i.items !== undefined && i.items.length > 0, ); +const semVersion = semver.valid(env.version) + ? semver.parse(env.version) + : { version: env.version, build: [] }; + +const footerText = [`${env.buildName} ยท v${semVersion.version}`]; +if (semVersion.build.length) { + footerText.push(`ID: ${semVersion.build.join(".")}`); +} + +const sidebarFooter = [ + { + text: ` + ${footerText.join("
")} +
`, + }, +]; + // https://vitepress.dev/reference/site-config export default defineConfigWithTheme({ srcDir: "./src", @@ -111,7 +129,7 @@ export default defineConfigWithTheme({ text: "Use cases", items: [ { - text: "Generation", + text: `Generation`, items: [ { text: "Generate a Factur-X document", @@ -124,7 +142,7 @@ export default defineConfigWithTheme({ ], }, { - text: "Validation", + text: `Validation`, items: [ { text: "Validate a Factur-X document", @@ -137,7 +155,7 @@ export default defineConfigWithTheme({ ], }, { - text: "Extraction", + text: `Extraction`, items: [ { text: "Extract Cross-Industry Invoice data", @@ -152,12 +170,7 @@ export default defineConfigWithTheme({ text: "About", link: "/guides/about", }, - { - text: `${env.buildName}`, - }, - { - text: `${env.version}`, - }, + ...sidebarFooter, ], "/openapi-specification/": [ { @@ -165,31 +178,13 @@ export default defineConfigWithTheme({ link: "/openapi-specification/introduction", }, ...specSidebar.generateSidebarGroups(), - { - text: `${env.buildName}`, - }, - { - text: `${env.version}`, - }, - ], - "/cli/": [ - ...cliItems, - { - text: `${env.buildName}`, - }, - { - text: `${env.version}`, - }, + ...sidebarFooter, ], + "/cli/": [...cliItems, ...sidebarFooter], "/api-reference/": [ { text: "Index", link: "/api-reference/index" }, ...apiReferenceItems, - { - text: `${env.buildName}`, - }, - { - text: `${env.version}`, - }, + ...sidebarFooter, ], }, @@ -223,7 +218,7 @@ export default defineConfigWithTheme({ }, }, - transformPageData: pageData => { + transformPageData: (pageData) => { const result = { ...pageData }; result.frontmatter = expandEnvInRecord(pageData.frontmatter); return result; diff --git a/docs/.vitepress/theme/custom.css b/docs/.vitepress/theme/custom.css index a3496ecc..110b3b18 100644 --- a/docs/.vitepress/theme/custom.css +++ b/docs/.vitepress/theme/custom.css @@ -10,13 +10,14 @@ --vp-c-brand-3: #512bd4; } -p:has(.sidebar-footer) { - padding: 0 !important; - line-height: unset !important; +.VPSidebarItem .item { + cursor: unset; } -p:has(.sidebar-footer-first) { +p:has(.sidebar-footer) { margin-top: 24px; + padding: 0 !important; + line-height: unset !important; } .sidebar-footer { diff --git a/docs/package-lock.json b/docs/package-lock.json index 23635727..cf529657 100644 --- a/docs/package-lock.json +++ b/docs/package-lock.json @@ -5,6 +5,7 @@ "packages": { "": { "dependencies": { + "semver": "^7.7.1", "vitepress-openapi": "^0.0.3-alpha.76", "vitepress-plugin-auto-sidebar": "^1.3.5", "vitepress-plugin-image-viewer": "^1.1.6" @@ -2715,7 +2716,6 @@ "version": "7.7.1", "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.1.tgz", "integrity": "sha512-hlq8tAfn0m/61p4BVRcPzIGr6LKiMwo4VM6dGi6pt4qcRkmNzTcWq6eCEjEh+qXjkMDvPlOFFSGwQjoEa6gyMA==", - "dev": true, "license": "ISC", "bin": { "semver": "bin/semver.js" diff --git a/docs/package.json b/docs/package.json index 67975c29..d26ecc87 100644 --- a/docs/package.json +++ b/docs/package.json @@ -11,6 +11,7 @@ "vitepress-plugin-nprogress": "^0.0.4" }, "dependencies": { + "semver": "^7.7.1", "vitepress-openapi": "^0.0.3-alpha.76", "vitepress-plugin-auto-sidebar": "^1.3.5", "vitepress-plugin-image-viewer": "^1.1.6"