diff --git a/.editorconfig b/.editorconfig index 5205652..014dec4 100644 --- a/.editorconfig +++ b/.editorconfig @@ -11,7 +11,7 @@ indent_style = tab indent_size = 4 # Markdown -[*.{md,markdown}] +[*.{md,markdown,mdoc}] trim_trailing_whitespace = false indent_style = space indent_size = 2 diff --git a/.vscode/extensions.json b/.vscode/extensions.json index 2d7e893..c4b91c9 100644 --- a/.vscode/extensions.json +++ b/.vscode/extensions.json @@ -1,6 +1,7 @@ { "recommendations": [ - "astro-build.astro-vscode" + "astro-build.astro-vscode", + "stripe.markdoc-language-support" ], "unwantedRecommendations": [] } diff --git a/app/Dockerfile b/app/Dockerfile index b161b76..feb4afc 100644 --- a/app/Dockerfile +++ b/app/Dockerfile @@ -134,6 +134,7 @@ FROM test_base AS test_unit ARG UID # Copy source code +RUN chown "${UID}:0" . COPY --link --chown="${UID}:0" ./app/ ./ # Run as non-root user @@ -156,6 +157,7 @@ COPY --from=deps_dev --link --chown="${UID}:0" /app/package.json /app/pnpm-lock. RUN pnpm exec playwright install --with-deps # Copy source code +RUN chown "${UID}:0" . COPY --link --chown="${UID}:0" ./app/ ./ # Build application @@ -183,20 +185,21 @@ COPY --from=deps_dev --link --chown="${UID}:0" /app/.astro/ ./.astro/ COPY --from=deps_dev --link --chown="${UID}:0" /app/node_modules/ ./node_modules/ # Copy source code +RUN chown "${UID}:0" . COPY --link --chown="${UID}:0" ./app/ ./ # Create user 'user' in group 'root' # (hadolint: Ignore unchecked pipe failures) # hadolint ignore=DL4006 -RUN USERNAME="$(getent passwd "${UID}" 2>/dev/null | cut -d: -f1)"; \ +RUN USERNAME="$(getent passwd "${UID}" 2>/dev/null | cut -d: -f1 || true)"; \ if [ -z "${USERNAME}" ]; then \ useradd -lm -u "${UID}" -U -G 0 user; \ else \ usermod -a -G 0 "${USERNAME}"; \ fi -# Run as non-root user -USER ${UID}:0 +# Run as created non-root user +USER ${UID} # Set exposed port ARG PORT=8080 diff --git a/app/app/astro.config.mjs b/app/app/astro.config.mjs index 9e0f476..4acfd26 100644 --- a/app/app/astro.config.mjs +++ b/app/app/astro.config.mjs @@ -1,4 +1,5 @@ import { defineConfig, envField } from 'astro/config' +import markdoc from '@astrojs/markdoc' import tailwindcss from '@tailwindcss/vite' import { i18n } from '/src/config' @@ -10,7 +11,12 @@ export default defineConfig({ build: { assetsPrefix: process.env.ASTRO_ASSETS_PREFIX || undefined, }, - integrations: [], + integrations: [ + markdoc({ + allowHTML: true, + ignoreIndentation: true, + }), + ], vite: { plugins: [ tailwindcss(), diff --git a/app/app/markdoc.config.mjs b/app/app/markdoc.config.mjs new file mode 100644 index 0000000..e442726 --- /dev/null +++ b/app/app/markdoc.config.mjs @@ -0,0 +1,10 @@ +import { defineMarkdocConfig, nodes } from '@astrojs/markdoc/config' + +export default defineMarkdocConfig({ + nodes: { + document: { + ...nodes.document, + render: null, + }, + }, +}) diff --git a/app/app/package.json b/app/app/package.json index 4755ce2..de0413d 100644 --- a/app/app/package.json +++ b/app/app/package.json @@ -28,6 +28,7 @@ "homepage": "https://github.com/FluffEvent/files-website#readme", "dependencies": { "@astrojs/check": "^0.9.4", + "@astrojs/markdoc": "^0.15.8", "@fontsource-variable/noto-serif": "^5.2.9", "@iconify-json/mdi": "^1.2.3", "@iconify-json/twemoji": "^1.2.4", diff --git a/app/app/pnpm-lock.yaml b/app/app/pnpm-lock.yaml index f6b32f1..d52ed7d 100644 --- a/app/app/pnpm-lock.yaml +++ b/app/app/pnpm-lock.yaml @@ -11,6 +11,9 @@ importers: '@astrojs/check': specifier: ^0.9.4 version: 0.9.4(typescript@5.9.3) + '@astrojs/markdoc': + specifier: ^0.15.8 + version: 0.15.8(astro@5.14.1(@types/node@22.18.8)(jiti@2.6.1)(lightningcss@1.30.1)(rollup@4.46.3)(sass@1.93.2)(typescript@5.9.3)(yaml@2.7.1)) '@fontsource-variable/noto-serif': specifier: ^5.2.9 version: 5.2.9 @@ -69,6 +72,9 @@ packages: '@astrojs/internal-helpers@0.7.3': resolution: {integrity: sha512-6Pl0bQEIChuW5wqN7jdKrzWfCscW2rG/Cz+fzt4PhSQX2ivBpnhXgFUCs0M3DCYvjYHnPVG2W36X5rmFjZ62sw==} + '@astrojs/internal-helpers@0.7.4': + resolution: {integrity: sha512-lDA9MqE8WGi7T/t2BMi+EAXhs4Vcvr94Gqx3q15cFEz8oFZMO4/SFBqYr/UcmNlvW+35alowkVj+w9VhLvs5Cw==} + '@astrojs/language-server@2.15.4': resolution: {integrity: sha512-JivzASqTPR2bao9BWsSc/woPHH7OGSGc9aMxXL4U6egVTqBycB3ZHdBJPuOCVtcGLrzdWTosAqVPz1BVoxE0+A==} hasBin: true @@ -81,9 +87,18 @@ packages: prettier-plugin-astro: optional: true + '@astrojs/markdoc@0.15.8': + resolution: {integrity: sha512-FOYrIUvv4bvOOfOgTlL84Sp4O4rrhYSRkee17atybn12/KyG70s1DA4HCjS56ZustIxh86TMJxe0wt3J9PLddQ==} + engines: {node: 18.20.8 || ^20.3.0 || >=22.0.0} + peerDependencies: + astro: ^5.0.0 + '@astrojs/markdown-remark@6.3.7': resolution: {integrity: sha512-KXGdq6/BC18doBCYXp08alHlWChH0hdD2B1qv9wIyOHbvwI5K6I7FhSta8dq1hBQNdun8YkKPR013D/Hm8xd0g==} + '@astrojs/markdown-remark@6.3.8': + resolution: {integrity: sha512-uFNyFWadnULWK2cOw4n0hLKeu+xaVWeuECdP10cQ3K2fkybtTlhb7J7TcScdjmS8Yps7oje9S/ehYMfZrhrgCg==} + '@astrojs/prism@3.3.0': resolution: {integrity: sha512-q8VwfU/fDZNoDOf+r7jUnMC2//H2l0TuQ6FkGJL8vD8nw/q5KiL3DS1KKBI3QhI9UQhpJ5dc7AtqfbXWuOgLCQ==} engines: {node: 18.20.8 || ^20.3.0 || >=22.0.0} @@ -464,6 +479,18 @@ packages: '@jridgewell/trace-mapping@0.3.29': resolution: {integrity: sha512-uw6guiW/gcAGPDhLmd77/6lW8QLeiV5RUTsAX46Db6oLhGaVj4lhnPwb184s1bkc8kdVg/+h988dro8GRDpmYQ==} + '@markdoc/markdoc@0.5.4': + resolution: {integrity: sha512-36YFNlqFk//gVNGm5xZaTWVwbAVF2AOmVjf1tiUrS6tCoD/YSkVy2E3CkAfhc5MlKcjparL/QFHCopxL4zRyaQ==} + engines: {node: '>=14.7.0'} + peerDependencies: + '@types/react': '*' + react: '*' + peerDependenciesMeta: + '@types/react': + optional: true + react: + optional: true + '@nodelib/fs.scandir@2.1.5': resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==} engines: {node: '>= 8'} @@ -807,9 +834,18 @@ packages: '@types/hast@3.0.4': resolution: {integrity: sha512-WPs+bbQw5aCj+x6laNGWLH3wviHtoCv/P3+otBhbOhJgG8qtpdAMlTCxLtsTWA7LH1Oh/bFCHsBn0TPS5m30EQ==} + '@types/linkify-it@3.0.5': + resolution: {integrity: sha512-yg6E+u0/+Zjva+buc3EIb+29XEg4wltq7cSmd4Uc2EE/1nUVmxyzpX6gUXD0V8jIrG0r7YeOGVIbYRkxeooCtw==} + + '@types/markdown-it@12.2.3': + resolution: {integrity: sha512-GKMHFfv3458yYy+v/N8gjufHO6MSZKCOXpZc5GXIWWy8uldwfmPn98vp81gZ5f9SVw8YYBctgfJ22a2d7AOMeQ==} + '@types/mdast@4.0.4': resolution: {integrity: sha512-kGaNbPh1k7AFzgpud/gMdvIm5xuECykRR+JnWKQno9TAXVa6WIVCGTPvYGekIDL4uwCZQSYbUxNBSb1aUo79oA==} + '@types/mdurl@2.0.0': + resolution: {integrity: sha512-RGdgjQUZba5p6QEFAVx2OGb8rQDL/cPRG7GiedRzMcJ1tYnUANBncjbSB1NRGwbvjcPeikRABz2nshyPk1bhWg==} + '@types/ms@2.1.0': resolution: {integrity: sha512-GsCCIZDE/p3i96vtEqx+7dBUGXrc7zeSK3wwPHIaRThS+9OhWIXRqzs4d6k1SVU8g91DrNRWxWUGhp5KXQb2VA==} @@ -1113,6 +1149,19 @@ packages: dlv@1.1.3: resolution: {integrity: sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA==} + dom-serializer@2.0.0: + resolution: {integrity: sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==} + + domelementtype@2.3.0: + resolution: {integrity: sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==} + + domhandler@5.0.3: + resolution: {integrity: sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==} + engines: {node: '>= 4'} + + domutils@3.2.2: + resolution: {integrity: sha512-6kZKyUajlDuqlHKVX1w7gyslj9MPIXzIFiz/rGu35uC1wMi+kMhQwGhl4lt9unC9Vb9INnY9Z3/ZA3+FhASLaw==} + dset@3.1.4: resolution: {integrity: sha512-2QF/g9/zTaPDc3BjNcVTGoBbXBgYfMTTceLaYcFJ/W9kggFUkhxD/hMEeuLKbugyef9SqAx8cpgwlIP/jinUTA==} engines: {node: '>=4'} @@ -1130,6 +1179,10 @@ packages: resolution: {integrity: sha512-d4lC8xfavMeBjzGr2vECC3fsGXziXZQyJxD868h2M/mBI3PwAuODxAkLkq5HYuvrPYcUtiLzsTo8U3PgX3Ocww==} engines: {node: '>=10.13.0'} + entities@4.5.0: + resolution: {integrity: sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==} + engines: {node: '>=0.12'} + entities@6.0.1: resolution: {integrity: sha512-aN97NXWF6AWBTahfVOIrB/NShkzi5H7F9r1s9mD3cDj4Ko5f2qhhVoYMibXF7GlLveb/D2ioWay8lxI97Ven3g==} engines: {node: '>=0.12'} @@ -1276,6 +1329,9 @@ packages: html-void-elements@3.0.0: resolution: {integrity: sha512-bEqo66MRXsUGxWHV5IP0PUiAWwoEjba4VCzg0LjFJBpchPaTfyfCKTG6bc5F8ucKec3q5y6qOdGyYTSBEvhCrg==} + htmlparser2@10.0.0: + resolution: {integrity: sha512-TwAZM+zE5Tq3lrEHvOlvwgj1XLWQCtaaibSN11Q+gGBAS7Y1uZSWwXXRe4iF6OXnaq1riyQAPFOBtYc77Mxq0g==} + http-cache-semantics@4.2.0: resolution: {integrity: sha512-dTxcvPXqPvXBQpq5dUr6mEMJX4oIEFv6bwom3FDwKRDsuIjjJGANqhBuoAn9c1RQJIdAKav33ED65E2ys+87QQ==} @@ -2430,6 +2486,8 @@ snapshots: '@astrojs/internal-helpers@0.7.3': {} + '@astrojs/internal-helpers@0.7.4': {} + '@astrojs/language-server@2.15.4(typescript@5.9.3)': dependencies: '@astrojs/compiler': 2.12.2 @@ -2453,6 +2511,21 @@ snapshots: transitivePeerDependencies: - typescript + '@astrojs/markdoc@0.15.8(astro@5.14.1(@types/node@22.18.8)(jiti@2.6.1)(lightningcss@1.30.1)(rollup@4.46.3)(sass@1.93.2)(typescript@5.9.3)(yaml@2.7.1))': + dependencies: + '@astrojs/internal-helpers': 0.7.4 + '@astrojs/markdown-remark': 6.3.8 + '@astrojs/prism': 3.3.0 + '@markdoc/markdoc': 0.5.4 + astro: 5.14.1(@types/node@22.18.8)(jiti@2.6.1)(lightningcss@1.30.1)(rollup@4.46.3)(sass@1.93.2)(typescript@5.9.3)(yaml@2.7.1) + esbuild: 0.25.9 + github-slugger: 2.0.0 + htmlparser2: 10.0.0 + transitivePeerDependencies: + - '@types/react' + - react + - supports-color + '@astrojs/markdown-remark@6.3.7': dependencies: '@astrojs/internal-helpers': 0.7.3 @@ -2479,6 +2552,32 @@ snapshots: transitivePeerDependencies: - supports-color + '@astrojs/markdown-remark@6.3.8': + dependencies: + '@astrojs/internal-helpers': 0.7.4 + '@astrojs/prism': 3.3.0 + github-slugger: 2.0.0 + hast-util-from-html: 2.0.3 + hast-util-to-text: 4.0.2 + import-meta-resolve: 4.2.0 + js-yaml: 4.1.0 + mdast-util-definitions: 6.0.0 + rehype-raw: 7.0.0 + rehype-stringify: 10.0.1 + remark-gfm: 4.0.1 + remark-parse: 11.0.0 + remark-rehype: 11.1.2 + remark-smartypants: 3.0.2 + shiki: 3.13.0 + smol-toml: 1.4.2 + unified: 11.0.5 + unist-util-remove-position: 5.0.0 + unist-util-visit: 5.0.0 + unist-util-visit-parents: 6.0.1 + vfile: 6.0.3 + transitivePeerDependencies: + - supports-color + '@astrojs/prism@3.3.0': dependencies: prismjs: 1.30.0 @@ -2773,6 +2872,11 @@ snapshots: '@jridgewell/resolve-uri': 3.1.2 '@jridgewell/sourcemap-codec': 1.5.5 + '@markdoc/markdoc@0.5.4': + optionalDependencies: + '@types/linkify-it': 3.0.5 + '@types/markdown-it': 12.2.3 + '@nodelib/fs.scandir@2.1.5': dependencies: '@nodelib/fs.stat': 2.0.5 @@ -3048,10 +3152,22 @@ snapshots: dependencies: '@types/unist': 3.0.3 + '@types/linkify-it@3.0.5': + optional: true + + '@types/markdown-it@12.2.3': + dependencies: + '@types/linkify-it': 3.0.5 + '@types/mdurl': 2.0.0 + optional: true + '@types/mdast@4.0.4': dependencies: '@types/unist': 3.0.3 + '@types/mdurl@2.0.0': + optional: true + '@types/ms@2.1.0': {} '@types/nlcst@2.0.3': @@ -3441,6 +3557,24 @@ snapshots: dlv@1.1.3: {} + dom-serializer@2.0.0: + dependencies: + domelementtype: 2.3.0 + domhandler: 5.0.3 + entities: 4.5.0 + + domelementtype@2.3.0: {} + + domhandler@5.0.3: + dependencies: + domelementtype: 2.3.0 + + domutils@3.2.2: + dependencies: + dom-serializer: 2.0.0 + domelementtype: 2.3.0 + domhandler: 5.0.3 + dset@3.1.4: {} emmet@2.4.11: @@ -3457,6 +3591,8 @@ snapshots: graceful-fs: 4.2.11 tapable: 2.2.1 + entities@4.5.0: {} + entities@6.0.1: {} es-module-lexer@1.7.0: {} @@ -3674,6 +3810,13 @@ snapshots: html-void-elements@3.0.0: {} + htmlparser2@10.0.0: + dependencies: + domelementtype: 2.3.0 + domhandler: 5.0.3 + domutils: 3.2.2 + entities: 6.0.1 + http-cache-semantics@4.2.0: {} immutable@5.1.1: {} diff --git a/app/app/src/components/RenderDocument.astro b/app/app/src/components/RenderDocument.astro index f4e567a..dd1ffff 100644 --- a/app/app/src/components/RenderDocument.astro +++ b/app/app/src/components/RenderDocument.astro @@ -1,4 +1,6 @@ --- +import LocalesPicker from '~/components/LocalesPicker/LocalesPicker.astro' + import logosrc from '~/assets/logo.png?url' function splitHash(hash: string) @@ -23,36 +25,38 @@ const version = data.version || import.meta.env.GITHUB_SHA || 'dev' const footerText = data.footer || null --- -
- -
+
- +
+ +
+
@@ -110,17 +114,16 @@ const footerText = data.footer || null