@authup/server-core 1.0.0-beta.58 → 1.0.0-beta.59
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/adapters/http/controllers/index.mjs +2 -1
- package/dist/adapters/http/controllers/workflows/account/index.d.ts +2 -0
- package/dist/adapters/http/controllers/workflows/account/index.d.ts.map +1 -0
- package/dist/adapters/http/controllers/workflows/account/index.mjs +5 -0
- package/dist/adapters/http/controllers/workflows/account/module.d.ts +24 -0
- package/dist/adapters/http/controllers/workflows/account/module.d.ts.map +1 -0
- package/dist/adapters/http/controllers/workflows/account/module.mjs +63 -0
- package/dist/adapters/http/controllers/workflows/account/module.mjs.map +1 -0
- package/dist/adapters/http/controllers/workflows/activate/module.mjs +1 -1
- package/dist/adapters/http/controllers/workflows/authorize/module.mjs +2 -2
- package/dist/adapters/http/controllers/workflows/authorize/module.mjs.map +1 -1
- package/dist/adapters/http/controllers/workflows/index.d.ts +1 -0
- package/dist/adapters/http/controllers/workflows/index.d.ts.map +1 -1
- package/dist/adapters/http/controllers/workflows/index.mjs +3 -1
- package/dist/adapters/http/controllers/workflows/logout/module.mjs +2 -2
- package/dist/adapters/http/controllers/workflows/logout/module.mjs.map +1 -1
- package/dist/adapters/http/controllers/workflows/password-forgot/module.mjs +1 -1
- package/dist/adapters/http/controllers/workflows/password-reset/module.mjs +1 -1
- package/dist/adapters/http/controllers/workflows/register/module.mjs +1 -1
- package/dist/adapters/http/controllers/workflows/userinfo/module.d.ts.map +1 -1
- package/dist/adapters/http/controllers/workflows/userinfo/module.mjs +5 -1
- package/dist/adapters/http/controllers/workflows/userinfo/module.mjs.map +1 -1
- package/dist/adapters/http/index.mjs +3 -1
- package/dist/adapters/http/middleware/built-in/assets.d.ts +8 -1
- package/dist/adapters/http/middleware/built-in/assets.d.ts.map +1 -1
- package/dist/adapters/http/middleware/built-in/assets.mjs +48 -4
- package/dist/adapters/http/middleware/built-in/assets.mjs.map +1 -1
- package/dist/adapters/http/middleware/built-in/index.d.ts +2 -0
- package/dist/adapters/http/middleware/built-in/index.d.ts.map +1 -1
- package/dist/adapters/http/middleware/built-in/index.mjs +2 -1
- package/dist/adapters/http/middleware/built-in/theme.d.ts +15 -0
- package/dist/adapters/http/middleware/built-in/theme.d.ts.map +1 -0
- package/dist/adapters/http/middleware/built-in/theme.mjs +27 -0
- package/dist/adapters/http/middleware/built-in/theme.mjs.map +1 -0
- package/dist/adapters/http/middleware/built-in/types.d.ts +14 -0
- package/dist/adapters/http/middleware/built-in/types.d.ts.map +1 -0
- package/dist/adapters/http/middleware/built-in/ui-http-client.d.ts +1 -1
- package/dist/adapters/http/middleware/built-in/ui-http-client.mjs +1 -1
- package/dist/adapters/http/middleware/built-in/ui-http-client.mjs.map +1 -1
- package/dist/adapters/http/middleware/index.mjs +2 -1
- package/dist/adapters/http/ui/account-console/index.d.ts +4 -0
- package/dist/adapters/http/ui/account-console/index.d.ts.map +1 -0
- package/dist/adapters/http/ui/account-console/index.mjs +6 -0
- package/dist/adapters/http/ui/account-console/module.d.ts +28 -0
- package/dist/adapters/http/ui/account-console/module.d.ts.map +1 -0
- package/dist/adapters/http/ui/account-console/module.mjs +80 -0
- package/dist/adapters/http/ui/account-console/module.mjs.map +1 -0
- package/dist/adapters/http/ui/account-console/ref.d.ts +30 -0
- package/dist/adapters/http/ui/account-console/ref.d.ts.map +1 -0
- package/dist/adapters/http/ui/account-console/ref.mjs +50 -0
- package/dist/adapters/http/ui/account-console/ref.mjs.map +1 -0
- package/dist/adapters/http/ui/account-console/types.d.ts +11 -0
- package/dist/adapters/http/ui/account-console/types.d.ts.map +1 -0
- package/dist/adapters/http/ui/account-console/types.mjs +4 -0
- package/dist/adapters/http/ui/{internal-http-client.d.ts → auth-console/http-client.d.ts} +1 -1
- package/dist/adapters/http/ui/auth-console/http-client.d.ts.map +1 -0
- package/dist/adapters/http/ui/{internal-http-client.mjs → auth-console/http-client.mjs} +2 -2
- package/dist/adapters/http/ui/auth-console/http-client.mjs.map +1 -0
- package/dist/adapters/http/ui/auth-console/index.d.ts +6 -0
- package/dist/adapters/http/ui/auth-console/index.d.ts.map +1 -0
- package/dist/adapters/http/ui/auth-console/index.mjs +8 -0
- package/dist/adapters/http/ui/auth-console/module.d.ts +4 -0
- package/dist/adapters/http/ui/auth-console/module.d.ts.map +1 -0
- package/dist/adapters/http/ui/auth-console/module.mjs +73 -0
- package/dist/adapters/http/ui/auth-console/module.mjs.map +1 -0
- package/dist/adapters/http/ui/auth-console/resolve.d.ts +21 -0
- package/dist/adapters/http/ui/auth-console/resolve.d.ts.map +1 -0
- package/dist/adapters/http/ui/auth-console/resolve.mjs +53 -0
- package/dist/adapters/http/ui/auth-console/resolve.mjs.map +1 -0
- package/dist/adapters/http/ui/{serve.d.ts → auth-console/serve.d.ts} +1 -8
- package/dist/adapters/http/ui/auth-console/serve.d.ts.map +1 -0
- package/dist/adapters/http/ui/{serve.mjs → auth-console/serve.mjs} +5 -5
- package/dist/adapters/http/ui/auth-console/serve.mjs.map +1 -0
- package/dist/adapters/http/ui/auth-console/types.d.ts +26 -0
- package/dist/adapters/http/ui/auth-console/types.d.ts.map +1 -0
- package/dist/adapters/http/ui/auth-console/types.mjs +4 -0
- package/dist/adapters/http/ui/console-packages/index.d.ts +3 -0
- package/dist/adapters/http/ui/console-packages/index.d.ts.map +1 -0
- package/dist/adapters/http/ui/console-packages/index.mjs +5 -0
- package/dist/adapters/http/ui/console-packages/module.d.ts +33 -0
- package/dist/adapters/http/ui/console-packages/module.d.ts.map +1 -0
- package/dist/adapters/http/ui/console-packages/module.mjs +70 -0
- package/dist/adapters/http/ui/console-packages/module.mjs.map +1 -0
- package/dist/adapters/http/ui/console-packages/types.d.ts +12 -0
- package/dist/adapters/http/ui/console-packages/types.d.ts.map +1 -0
- package/dist/adapters/http/ui/console-packages/types.mjs +4 -0
- package/dist/adapters/http/ui/index.d.ts +5 -5
- package/dist/adapters/http/ui/index.d.ts.map +1 -1
- package/dist/adapters/http/ui/index.mjs +22 -5
- package/dist/adapters/http/ui/shared/html.d.ts +76 -0
- package/dist/adapters/http/ui/shared/html.d.ts.map +1 -0
- package/dist/adapters/http/ui/shared/html.mjs +103 -0
- package/dist/adapters/http/ui/shared/html.mjs.map +1 -0
- package/dist/adapters/http/ui/shared/index.d.ts +2 -0
- package/dist/adapters/http/ui/shared/index.d.ts.map +1 -0
- package/dist/adapters/http/ui/shared/index.mjs +5 -0
- package/dist/adapters/http/ui/theme/apply.d.ts +12 -0
- package/dist/adapters/http/ui/theme/apply.d.ts.map +1 -0
- package/dist/adapters/http/ui/theme/apply.mjs +29 -0
- package/dist/adapters/http/ui/theme/apply.mjs.map +1 -0
- package/dist/adapters/http/ui/theme/assets.d.ts +20 -0
- package/dist/adapters/http/ui/theme/assets.d.ts.map +1 -0
- package/dist/adapters/http/ui/theme/assets.mjs +86 -0
- package/dist/adapters/http/ui/theme/assets.mjs.map +1 -0
- package/dist/adapters/http/ui/theme/constants.d.ts +16 -0
- package/dist/adapters/http/ui/theme/constants.d.ts.map +1 -0
- package/dist/adapters/http/ui/theme/constants.mjs +20 -0
- package/dist/adapters/http/ui/theme/constants.mjs.map +1 -0
- package/dist/adapters/http/ui/theme/contract/constants.d.ts +120 -0
- package/dist/adapters/http/ui/theme/contract/constants.d.ts.map +1 -0
- package/dist/adapters/http/ui/theme/contract/constants.mjs +136 -0
- package/dist/adapters/http/ui/theme/contract/constants.mjs.map +1 -0
- package/dist/adapters/http/ui/theme/contract/head.d.ts +12 -0
- package/dist/adapters/http/ui/theme/contract/head.d.ts.map +1 -0
- package/dist/adapters/http/ui/theme/contract/head.mjs +61 -0
- package/dist/adapters/http/ui/theme/contract/head.mjs.map +1 -0
- package/dist/adapters/http/ui/theme/contract/index.d.ts +6 -0
- package/dist/adapters/http/ui/theme/contract/index.d.ts.map +1 -0
- package/dist/adapters/http/ui/theme/contract/index.mjs +8 -0
- package/dist/adapters/http/ui/theme/contract/manifest.d.ts +25 -0
- package/dist/adapters/http/ui/theme/contract/manifest.d.ts.map +1 -0
- package/dist/adapters/http/ui/theme/contract/manifest.mjs +77 -0
- package/dist/adapters/http/ui/theme/contract/manifest.mjs.map +1 -0
- package/dist/adapters/http/ui/theme/contract/types.d.ts +26 -0
- package/dist/adapters/http/ui/theme/contract/types.d.ts.map +1 -0
- package/dist/adapters/http/ui/theme/contract/types.mjs +4 -0
- package/dist/adapters/http/ui/theme/contract/utils.d.ts +11 -0
- package/dist/adapters/http/ui/theme/contract/utils.d.ts.map +1 -0
- package/dist/adapters/http/ui/theme/contract/utils.mjs +22 -0
- package/dist/adapters/http/ui/theme/contract/utils.mjs.map +1 -0
- package/dist/adapters/http/ui/theme/index.d.ts +7 -0
- package/dist/adapters/http/ui/theme/index.d.ts.map +1 -0
- package/dist/adapters/http/ui/theme/index.mjs +13 -0
- package/dist/adapters/http/ui/theme/module.d.ts +79 -0
- package/dist/adapters/http/ui/theme/module.d.ts.map +1 -0
- package/dist/adapters/http/ui/theme/module.mjs +206 -0
- package/dist/adapters/http/ui/theme/module.mjs.map +1 -0
- package/dist/adapters/http/ui/theme/types.d.ts +42 -0
- package/dist/adapters/http/ui/theme/types.d.ts.map +1 -0
- package/dist/adapters/http/ui/theme/types.mjs +4 -0
- package/dist/app/index.mjs +3 -1
- package/dist/app/modules/config/constants.d.ts +5 -0
- package/dist/app/modules/config/constants.d.ts.map +1 -1
- package/dist/app/modules/config/constants.mjs +5 -0
- package/dist/app/modules/config/constants.mjs.map +1 -1
- package/dist/app/modules/config/normalize.d.ts.map +1 -1
- package/dist/app/modules/config/normalize.mjs +8 -0
- package/dist/app/modules/config/normalize.mjs.map +1 -1
- package/dist/app/modules/config/origins.d.ts.map +1 -1
- package/dist/app/modules/config/origins.mjs +2 -0
- package/dist/app/modules/config/origins.mjs.map +1 -1
- package/dist/app/modules/config/read/env.d.ts.map +1 -1
- package/dist/app/modules/config/read/env.mjs +10 -0
- package/dist/app/modules/config/read/env.mjs.map +1 -1
- package/dist/app/modules/config/types.d.ts +63 -3
- package/dist/app/modules/config/types.d.ts.map +1 -1
- package/dist/app/modules/config/validator.d.ts.map +1 -1
- package/dist/app/modules/config/validator.mjs +5 -0
- package/dist/app/modules/config/validator.mjs.map +1 -1
- package/dist/app/modules/http/module.d.ts.map +1 -1
- package/dist/app/modules/http/module.mjs +7 -1
- package/dist/app/modules/http/module.mjs.map +1 -1
- package/dist/app/modules/http/modules/controller.d.ts +2 -1
- package/dist/app/modules/http/modules/controller.d.ts.map +1 -1
- package/dist/app/modules/http/modules/controller.mjs +20 -5
- package/dist/app/modules/http/modules/controller.mjs.map +1 -1
- package/dist/app/modules/http/modules/middleware.d.ts +9 -1
- package/dist/app/modules/http/modules/middleware.d.ts.map +1 -1
- package/dist/app/modules/http/modules/middleware.mjs +18 -3
- package/dist/app/modules/http/modules/middleware.mjs.map +1 -1
- package/dist/app/modules/index.mjs +3 -1
- package/dist/app/modules/provisioning/constants.d.ts +12 -0
- package/dist/app/modules/provisioning/constants.d.ts.map +1 -0
- package/dist/app/modules/provisioning/constants.mjs +16 -0
- package/dist/app/modules/provisioning/constants.mjs.map +1 -0
- package/dist/app/modules/provisioning/index.d.ts +2 -0
- package/dist/app/modules/provisioning/index.d.ts.map +1 -1
- package/dist/app/modules/provisioning/index.mjs +3 -1
- package/dist/app/modules/provisioning/lazy-wildcard.d.ts +15 -0
- package/dist/app/modules/provisioning/lazy-wildcard.d.ts.map +1 -0
- package/dist/app/modules/provisioning/lazy-wildcard.mjs +23 -0
- package/dist/app/modules/provisioning/lazy-wildcard.mjs.map +1 -0
- package/dist/app/modules/provisioning/module.d.ts.map +1 -1
- package/dist/app/modules/provisioning/module.mjs +21 -3
- package/dist/app/modules/provisioning/module.mjs.map +1 -1
- package/dist/app/modules/provisioning/sources/composite/module.d.ts +0 -19
- package/dist/app/modules/provisioning/sources/composite/module.d.ts.map +1 -1
- package/dist/app/modules/provisioning/sources/composite/module.mjs +7 -77
- package/dist/app/modules/provisioning/sources/composite/module.mjs.map +1 -1
- package/dist/core/entities/client/index.d.ts +1 -1
- package/dist/core/entities/client/index.d.ts.map +1 -1
- package/dist/core/entities/client/index.mjs +2 -2
- package/dist/core/entities/client/service.mjs.map +1 -1
- package/dist/core/entities/client/system-clients.d.ts +95 -0
- package/dist/core/entities/client/system-clients.d.ts.map +1 -0
- package/dist/core/entities/client/system-clients.mjs +158 -0
- package/dist/core/entities/client/system-clients.mjs.map +1 -0
- package/dist/core/entities/client/types.d.ts +17 -4
- package/dist/core/entities/client/types.d.ts.map +1 -1
- package/dist/core/entities/index.mjs +2 -2
- package/dist/core/entities/realm/service.d.ts +8 -6
- package/dist/core/entities/realm/service.d.ts.map +1 -1
- package/dist/core/entities/realm/service.mjs +5 -8
- package/dist/core/entities/realm/service.mjs.map +1 -1
- package/dist/core/index.mjs +6 -2
- package/dist/core/key/types.d.ts +2 -1
- package/dist/core/key/types.d.ts.map +1 -1
- package/dist/core/oauth2/authorization/code-request/verifier/module.d.ts.map +1 -1
- package/dist/core/oauth2/authorization/code-request/verifier/module.mjs +2 -2
- package/dist/core/oauth2/authorization/code-request/verifier/module.mjs.map +1 -1
- package/dist/core/oauth2/end-session/service.d.ts.map +1 -1
- package/dist/core/oauth2/end-session/service.mjs +2 -2
- package/dist/core/oauth2/end-session/service.mjs.map +1 -1
- package/dist/core/provisioning/constants.d.ts +8 -0
- package/dist/core/provisioning/constants.d.ts.map +1 -0
- package/dist/core/provisioning/constants.mjs +14 -0
- package/dist/core/provisioning/constants.mjs.map +1 -0
- package/dist/core/provisioning/entities/index.mjs +2 -1
- package/dist/core/provisioning/entities/realm/index.d.ts +1 -0
- package/dist/core/provisioning/entities/realm/index.d.ts.map +1 -1
- package/dist/core/provisioning/entities/realm/index.mjs +2 -1
- package/dist/core/provisioning/entities/realm/validator.d.ts +11 -0
- package/dist/core/provisioning/entities/realm/validator.d.ts.map +1 -1
- package/dist/core/provisioning/entities/realm/validator.mjs +14 -0
- package/dist/core/provisioning/entities/realm/validator.mjs.map +1 -1
- package/dist/core/provisioning/entities/realm/wildcard-validator.d.ts +19 -0
- package/dist/core/provisioning/entities/realm/wildcard-validator.d.ts.map +1 -0
- package/dist/core/provisioning/entities/realm/wildcard-validator.mjs +65 -0
- package/dist/core/provisioning/entities/realm/wildcard-validator.mjs.map +1 -0
- package/dist/core/provisioning/index.d.ts +3 -0
- package/dist/core/provisioning/index.d.ts.map +1 -1
- package/dist/core/provisioning/index.mjs +7 -1
- package/dist/core/provisioning/merge/index.d.ts +3 -0
- package/dist/core/provisioning/merge/index.d.ts.map +1 -0
- package/dist/core/provisioning/merge/index.mjs +5 -0
- package/dist/core/provisioning/merge/module.d.ts +18 -0
- package/dist/core/provisioning/merge/module.d.ts.map +1 -0
- package/dist/core/provisioning/merge/module.mjs +82 -0
- package/dist/core/provisioning/merge/module.mjs.map +1 -0
- package/dist/core/provisioning/merge/types.d.ts +34 -0
- package/dist/core/provisioning/merge/types.d.ts.map +1 -0
- package/dist/core/provisioning/merge/types.mjs +4 -0
- package/dist/core/provisioning/types.d.ts +10 -0
- package/dist/core/provisioning/types.d.ts.map +1 -1
- package/dist/core/provisioning/wildcard/index.d.ts +3 -0
- package/dist/core/provisioning/wildcard/index.d.ts.map +1 -0
- package/dist/core/provisioning/wildcard/index.mjs +5 -0
- package/dist/core/provisioning/wildcard/module.d.ts +53 -0
- package/dist/core/provisioning/wildcard/module.d.ts.map +1 -0
- package/dist/core/provisioning/wildcard/module.mjs +91 -0
- package/dist/core/provisioning/wildcard/module.mjs.map +1 -0
- package/dist/core/provisioning/wildcard/types.d.ts +19 -0
- package/dist/core/provisioning/wildcard/types.d.ts.map +1 -0
- package/dist/core/provisioning/wildcard/types.mjs +4 -0
- package/dist/index.mjs +5 -1
- package/dist/path.d.ts +0 -2
- package/dist/path.d.ts.map +1 -1
- package/dist/path.mjs +1 -3
- package/dist/path.mjs.map +1 -1
- package/dist/swagger.json +50 -6
- package/package.json +19 -57
- package/dist/adapters/http/ui/base-path.d.ts +0 -9
- package/dist/adapters/http/ui/base-path.d.ts.map +0 -1
- package/dist/adapters/http/ui/base-path.mjs +0 -18
- package/dist/adapters/http/ui/base-path.mjs.map +0 -1
- package/dist/adapters/http/ui/internal-http-client.d.ts.map +0 -1
- package/dist/adapters/http/ui/internal-http-client.mjs.map +0 -1
- package/dist/adapters/http/ui/render.d.ts +0 -4
- package/dist/adapters/http/ui/render.d.ts.map +0 -1
- package/dist/adapters/http/ui/render.mjs +0 -63
- package/dist/adapters/http/ui/render.mjs.map +0 -1
- package/dist/adapters/http/ui/serve.d.ts.map +0 -1
- package/dist/adapters/http/ui/serve.mjs.map +0 -1
- package/dist/adapters/http/ui/types.d.ts +0 -20
- package/dist/adapters/http/ui/types.d.ts.map +0 -1
- package/dist/core/entities/client/web-client.d.ts +0 -72
- package/dist/core/entities/client/web-client.d.ts.map +0 -1
- package/dist/core/entities/client/web-client.mjs +0 -123
- package/dist/core/entities/client/web-client.mjs.map +0 -1
- package/dist/ui/client/.vite/ssr-manifest.json +0 -54974
- package/dist/ui/client/assets/asap-latin-400-normal-Dc37g3Il.woff +0 -0
- package/dist/ui/client/assets/asap-latin-400-normal-DnZ1MOsG.woff2 +0 -0
- package/dist/ui/client/assets/asap-latin-700-normal-Dqcopq14.woff +0 -0
- package/dist/ui/client/assets/asap-latin-700-normal-l2Y8pi-F.woff2 +0 -0
- package/dist/ui/client/assets/asap-latin-ext-400-normal-C-fcRdtE.woff +0 -0
- package/dist/ui/client/assets/asap-latin-ext-400-normal-DwYtpHbV.woff2 +0 -0
- package/dist/ui/client/assets/asap-latin-ext-700-normal-D00OESsZ.woff +0 -0
- package/dist/ui/client/assets/asap-latin-ext-700-normal-y8bo5aW5.woff2 +0 -0
- package/dist/ui/client/assets/asap-vietnamese-400-normal-DGyJlJLT.woff2 +0 -0
- package/dist/ui/client/assets/asap-vietnamese-400-normal-lfLaoF2x.woff +0 -0
- package/dist/ui/client/assets/asap-vietnamese-700-normal-B-e19ug5.woff +0 -0
- package/dist/ui/client/assets/asap-vietnamese-700-normal-D-SxY94i.woff2 +0 -0
- package/dist/ui/client/assets/index-BTK3GPZZ.js +0 -106
- package/dist/ui/client/assets/index-Cx_pI7BS.css +0 -2
- package/dist/ui/client/assets/nunito-cyrillic-300-normal-BPQV259B.woff2 +0 -0
- package/dist/ui/client/assets/nunito-cyrillic-300-normal-g5qSsvc0.woff +0 -0
- package/dist/ui/client/assets/nunito-cyrillic-400-normal-D1j0u8EH.woff +0 -0
- package/dist/ui/client/assets/nunito-cyrillic-400-normal-xAOo5cBP.woff2 +0 -0
- package/dist/ui/client/assets/nunito-cyrillic-600-normal-BUjmtIuu.woff +0 -0
- package/dist/ui/client/assets/nunito-cyrillic-600-normal-DJGQ2h05.woff2 +0 -0
- package/dist/ui/client/assets/nunito-cyrillic-700-normal-DP36NgGt.woff2 +0 -0
- package/dist/ui/client/assets/nunito-cyrillic-700-normal-DfHRUDv-.woff +0 -0
- package/dist/ui/client/assets/nunito-cyrillic-ext-300-normal-BDHtqmCR.woff +0 -0
- package/dist/ui/client/assets/nunito-cyrillic-ext-300-normal-ChMQLIrm.woff2 +0 -0
- package/dist/ui/client/assets/nunito-cyrillic-ext-400-normal-CuPM9foi.woff2 +0 -0
- package/dist/ui/client/assets/nunito-cyrillic-ext-400-normal-xaE7D4Sw.woff +0 -0
- package/dist/ui/client/assets/nunito-cyrillic-ext-600-normal-CWPPjBOD.woff2 +0 -0
- package/dist/ui/client/assets/nunito-cyrillic-ext-600-normal-vnfu4DTE.woff +0 -0
- package/dist/ui/client/assets/nunito-cyrillic-ext-700-normal-BuR0mlCG.woff2 +0 -0
- package/dist/ui/client/assets/nunito-cyrillic-ext-700-normal-DfoqN4Gs.woff +0 -0
- package/dist/ui/client/assets/nunito-latin-300-normal-C3ZIKvzv.woff +0 -0
- package/dist/ui/client/assets/nunito-latin-300-normal-COoPE5VN.woff2 +0 -0
- package/dist/ui/client/assets/nunito-latin-400-normal-DKg4f3fz.woff +0 -0
- package/dist/ui/client/assets/nunito-latin-400-normal-r8SDr6Up.woff2 +0 -0
- package/dist/ui/client/assets/nunito-latin-600-normal-Br8yIETf.woff2 +0 -0
- package/dist/ui/client/assets/nunito-latin-600-normal-Cd0eNu1l.woff +0 -0
- package/dist/ui/client/assets/nunito-latin-700-normal-Dort48En.woff2 +0 -0
- package/dist/ui/client/assets/nunito-latin-700-normal-OcDqTBcA.woff +0 -0
- package/dist/ui/client/assets/nunito-latin-ext-300-normal-D1SyVuPt.woff2 +0 -0
- package/dist/ui/client/assets/nunito-latin-ext-300-normal-DfqbmdMl.woff +0 -0
- package/dist/ui/client/assets/nunito-latin-ext-400-normal-CjMJVfGn.woff +0 -0
- package/dist/ui/client/assets/nunito-latin-ext-400-normal-i-8OOpdj.woff2 +0 -0
- package/dist/ui/client/assets/nunito-latin-ext-600-normal-BKUpuB78.woff +0 -0
- package/dist/ui/client/assets/nunito-latin-ext-600-normal-Dd9Zuxh1.woff2 +0 -0
- package/dist/ui/client/assets/nunito-latin-ext-700-normal-BWeMsAzO.woff2 +0 -0
- package/dist/ui/client/assets/nunito-latin-ext-700-normal-D4woHhbd.woff +0 -0
- package/dist/ui/client/assets/nunito-vietnamese-300-normal-DATld5Vw.woff +0 -0
- package/dist/ui/client/assets/nunito-vietnamese-300-normal-mLneKULB.woff2 +0 -0
- package/dist/ui/client/assets/nunito-vietnamese-400-normal-BHkVbP3T.woff2 +0 -0
- package/dist/ui/client/assets/nunito-vietnamese-400-normal-DtOtW02z.woff +0 -0
- package/dist/ui/client/assets/nunito-vietnamese-600-normal-BY8O6Cug.woff2 +0 -0
- package/dist/ui/client/assets/nunito-vietnamese-600-normal-DO1RqFw5.woff +0 -0
- package/dist/ui/client/assets/nunito-vietnamese-700-normal-C9SQsXvj.woff +0 -0
- package/dist/ui/client/assets/nunito-vietnamese-700-normal-Ch8EUCfz.woff2 +0 -0
- package/dist/ui/client/index.html +0 -22
- package/dist/ui/server/assets/multipart-parser-BCMy8Xwv.js +0 -181
- package/dist/ui/server/assets/multipart-parser-BVY8pIV2.js +0 -176
- package/dist/ui/server/server.js +0 -155269
- /package/dist/adapters/http/{ui → middleware/built-in}/types.mjs +0 -0
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import "node:path";
|
|
2
|
+
import "node:url";
|
|
3
|
+
import.meta.url;
|
|
4
|
+
import { injectHeadContent, stampDocumentTitle } from "../shared/html.mjs";
|
|
5
|
+
import "../shared/index.mjs";
|
|
6
|
+
import { escapeHtml } from "./contract/head.mjs";
|
|
7
|
+
import "./contract/index.mjs";
|
|
8
|
+
//#region src/adapters/http/ui/theme/apply.ts
|
|
9
|
+
/**
|
|
10
|
+
* Apply the operator theme to a rendered console shell. A no-op when
|
|
11
|
+
* theming is off or the directory carries no manifest, so both console
|
|
12
|
+
* serve paths can call it unconditionally.
|
|
13
|
+
*
|
|
14
|
+
* Lives outside contract/ because it takes a provider (filesystem-backed)
|
|
15
|
+
* and splices into a served document: contract/ stays a pure description
|
|
16
|
+
* of what a theme IS.
|
|
17
|
+
*/ async function applyTheme(html, provider, basePath) {
|
|
18
|
+
if (!provider) return html;
|
|
19
|
+
let body = html;
|
|
20
|
+
const manifest = await provider.getManifest();
|
|
21
|
+
if (manifest?.title) body = stampDocumentTitle(body, escapeHtml(manifest.title));
|
|
22
|
+
const head = await provider.getHead(basePath);
|
|
23
|
+
if (head) body = injectHeadContent(body, head);
|
|
24
|
+
return body;
|
|
25
|
+
}
|
|
26
|
+
//#endregion
|
|
27
|
+
export { applyTheme };
|
|
28
|
+
|
|
29
|
+
//# sourceMappingURL=apply.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"apply.mjs","names":["injectHeadContent","stampDocumentTitle","escapeHtml","applyTheme","html","provider","basePath","body","manifest","getManifest","title","head","getHead"],"sources":["../../../../../src/adapters/http/ui/theme/apply.ts"],"sourcesContent":["/*\n * Copyright (c) 2026.\n * Author Peter Placzek (tada5hi)\n * For the full copyright and license information,\n * view the LICENSE file that was distributed with this source code.\n */\n\nimport { injectHeadContent, stampDocumentTitle } from '../shared/index.ts';\nimport { escapeHtml } from './contract/index.ts';\nimport type { IThemeProvider } from './types.ts';\n\n/**\n * Apply the operator theme to a rendered console shell. A no-op when\n * theming is off or the directory carries no manifest, so both console\n * serve paths can call it unconditionally.\n *\n * Lives outside contract/ because it takes a provider (filesystem-backed)\n * and splices into a served document: contract/ stays a pure description\n * of what a theme IS.\n */\nexport async function applyTheme(\n html: string,\n provider: IThemeProvider | undefined,\n basePath: string,\n) : Promise<string> {\n if (!provider) {\n return html;\n }\n\n let body = html;\n\n // A directory may carry only a fragment, or only a stylesheet, so the\n // manifest is not a precondition for applying the theme.\n const manifest = await provider.getManifest();\n if (manifest?.title) {\n body = stampDocumentTitle(body, escapeHtml(manifest.title));\n }\n\n const head = await provider.getHead(basePath);\n if (head) {\n body = injectHeadContent(body, head);\n }\n\n return body;\n}\n"],"mappings":";;;;;;;;;;;;;;;;GAoBA,eAAsBG,WAClBC,MACAC,UACAC,UAAgB;CAEhB,IAAI,CAACD,UACD,OAAOD;CAGX,IAAIG,OAAOH;CAIX,MAAMI,WAAW,MAAMH,SAASI,YAAW;CAC3C,IAAID,UAAUE,OACVH,OAAON,mBAAmBM,MAAML,WAAWM,SAASE,KAAK,CAAA;CAG7D,MAAMC,OAAO,MAAMN,SAASO,QAAQN,QAAAA;CACpC,IAAIK,MACAJ,OAAOP,kBAAkBO,MAAMI,IAAAA;CAGnC,OAAOJ;AACX"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import type { Handler } from 'routup';
|
|
2
|
+
import type { IThemeProvider } from './types.ts';
|
|
3
|
+
/**
|
|
4
|
+
* Serves the operator theme's `assets/` directory.
|
|
5
|
+
*
|
|
6
|
+
* Deliberately NOT `@routup/assets`' createHandler, for three reasons that
|
|
7
|
+
* matter for an operator-supplied root:
|
|
8
|
+
* - its lookup walks PATH SUFFIXES, so `/theme/anything/logo.svg` would
|
|
9
|
+
* serve `/logo.svg`; the same file becomes reachable at unbounded
|
|
10
|
+
* distinct URLs.
|
|
11
|
+
* - it probes `.html` / `index.html` by default, which would make a stray
|
|
12
|
+
* index.html a servable document on the IdP origin.
|
|
13
|
+
* - it performs no realpath containment check, so a symlink inside the
|
|
14
|
+
* mounted directory pointing outside it is served with a 200. A
|
|
15
|
+
* read-only mount does not prevent that, and refusing symlinks outright
|
|
16
|
+
* is not an option: a Kubernetes ConfigMap volume IS a symlink farm
|
|
17
|
+
* (`key -> ..data/key`).
|
|
18
|
+
*/
|
|
19
|
+
export declare function createThemeAssetsHandler(provider: IThemeProvider): Handler;
|
|
20
|
+
//# sourceMappingURL=assets.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"assets.d.ts","sourceRoot":"","sources":["../../../../../src/adapters/http/ui/theme/assets.ts"],"names":[],"mappings":"AAUA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,QAAQ,CAAC;AAQtC,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAIjD;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,wBAAwB,CAAC,QAAQ,EAAE,cAAc,GAAI,OAAO,CAqG3E"}
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
import "node:path";
|
|
2
|
+
import "node:url";
|
|
3
|
+
import.meta.url;
|
|
4
|
+
import { THEME_ASSET_CONTENT_TYPES, THEME_ASSET_EXTENSIONS } from "./contract/constants.mjs";
|
|
5
|
+
import { themeAssetExtension } from "./contract/utils.mjs";
|
|
6
|
+
import "./contract/index.mjs";
|
|
7
|
+
import { THEME_ASSET_CSP } from "./constants.mjs";
|
|
8
|
+
import path from "node:path";
|
|
9
|
+
import { HeaderName, defineCoreHandler, sendFile } from "routup";
|
|
10
|
+
import fs from "node:fs";
|
|
11
|
+
import { Readable } from "node:stream";
|
|
12
|
+
//#region src/adapters/http/ui/theme/assets.ts
|
|
13
|
+
const REQUEST_PATH_PATTERN = /^[a-z0-9][a-z0-9._/-]*$/i;
|
|
14
|
+
/**
|
|
15
|
+
* Serves the operator theme's `assets/` directory.
|
|
16
|
+
*
|
|
17
|
+
* Deliberately NOT `@routup/assets`' createHandler, for three reasons that
|
|
18
|
+
* matter for an operator-supplied root:
|
|
19
|
+
* - its lookup walks PATH SUFFIXES, so `/theme/anything/logo.svg` would
|
|
20
|
+
* serve `/logo.svg`; the same file becomes reachable at unbounded
|
|
21
|
+
* distinct URLs.
|
|
22
|
+
* - it probes `.html` / `index.html` by default, which would make a stray
|
|
23
|
+
* index.html a servable document on the IdP origin.
|
|
24
|
+
* - it performs no realpath containment check, so a symlink inside the
|
|
25
|
+
* mounted directory pointing outside it is served with a 200. A
|
|
26
|
+
* read-only mount does not prevent that, and refusing symlinks outright
|
|
27
|
+
* is not an option: a Kubernetes ConfigMap volume IS a symlink farm
|
|
28
|
+
* (`key -> ..data/key`).
|
|
29
|
+
*/ function createThemeAssetsHandler(provider) {
|
|
30
|
+
return defineCoreHandler(async (event) => {
|
|
31
|
+
const assetsPath = await provider.getAssetsPath();
|
|
32
|
+
if (!assetsPath) {
|
|
33
|
+
event.response.status = 404;
|
|
34
|
+
return null;
|
|
35
|
+
}
|
|
36
|
+
let requestPath = event.path;
|
|
37
|
+
const { mountPath } = event;
|
|
38
|
+
if (requestPath.startsWith(mountPath)) requestPath = requestPath.substring(mountPath.length);
|
|
39
|
+
if (requestPath.includes("%")) try {
|
|
40
|
+
requestPath = decodeURIComponent(requestPath);
|
|
41
|
+
} catch {
|
|
42
|
+
event.response.status = 404;
|
|
43
|
+
return null;
|
|
44
|
+
}
|
|
45
|
+
requestPath = requestPath.replace(/^\/+/, "");
|
|
46
|
+
const extension = themeAssetExtension(requestPath);
|
|
47
|
+
if (!requestPath || !REQUEST_PATH_PATTERN.test(requestPath) || requestPath.split("/").includes("..") || !THEME_ASSET_EXTENSIONS.includes(extension)) {
|
|
48
|
+
event.response.status = 404;
|
|
49
|
+
return null;
|
|
50
|
+
}
|
|
51
|
+
let root;
|
|
52
|
+
let filePath;
|
|
53
|
+
let stats;
|
|
54
|
+
try {
|
|
55
|
+
root = await fs.promises.realpath(assetsPath);
|
|
56
|
+
filePath = await fs.promises.realpath(path.join(assetsPath, requestPath));
|
|
57
|
+
stats = await fs.promises.stat(filePath);
|
|
58
|
+
} catch {
|
|
59
|
+
event.response.status = 404;
|
|
60
|
+
return null;
|
|
61
|
+
}
|
|
62
|
+
if (!stats.isFile() || filePath !== root && !filePath.startsWith(root + path.sep)) {
|
|
63
|
+
event.response.status = 404;
|
|
64
|
+
return null;
|
|
65
|
+
}
|
|
66
|
+
const etag = `W/"${stats.size}-${stats.mtime.getTime()}"`;
|
|
67
|
+
event.response.headers.set(HeaderName.CACHE_CONTROL, "public, max-age=0, must-revalidate");
|
|
68
|
+
if (event.headers.get(HeaderName.IF_NONE_MATCH) === etag) {
|
|
69
|
+
event.response.status = 304;
|
|
70
|
+
return null;
|
|
71
|
+
}
|
|
72
|
+
const response = await sendFile(event, {
|
|
73
|
+
content: (options) => Readable.toWeb(fs.createReadStream(filePath, options)),
|
|
74
|
+
stats: () => stats,
|
|
75
|
+
name: filePath
|
|
76
|
+
});
|
|
77
|
+
response.headers.set(HeaderName.CONTENT_TYPE, THEME_ASSET_CONTENT_TYPES[extension]);
|
|
78
|
+
response.headers.set("x-content-type-options", "nosniff");
|
|
79
|
+
response.headers.set("content-security-policy", THEME_ASSET_CSP);
|
|
80
|
+
return response;
|
|
81
|
+
});
|
|
82
|
+
}
|
|
83
|
+
//#endregion
|
|
84
|
+
export { createThemeAssetsHandler };
|
|
85
|
+
|
|
86
|
+
//# sourceMappingURL=assets.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"assets.mjs","names":["fs","path","Readable","HeaderName","defineCoreHandler","sendFile","THEME_ASSET_CSP","THEME_ASSET_CONTENT_TYPES","THEME_ASSET_EXTENSIONS","themeAssetExtension","REQUEST_PATH_PATTERN","createThemeAssetsHandler","provider","event","assetsPath","getAssetsPath","response","status","requestPath","mountPath","startsWith","substring","length","includes","decodeURIComponent","replace","extension","test","split","root","filePath","stats","promises","realpath","join","stat","isFile","sep","etag","size","mtime","getTime","headers","set","CACHE_CONTROL","get","IF_NONE_MATCH","content","options","toWeb","createReadStream","name","CONTENT_TYPE"],"sources":["../../../../../src/adapters/http/ui/theme/assets.ts"],"sourcesContent":["/*\n * Copyright (c) 2026.\n * Author Peter Placzek (tada5hi)\n * For the full copyright and license information,\n * view the LICENSE file that was distributed with this source code.\n */\n\nimport fs from 'node:fs';\nimport path from 'node:path';\nimport { Readable } from 'node:stream';\nimport type { Handler } from 'routup';\nimport { HeaderName, defineCoreHandler, sendFile } from 'routup';\nimport { THEME_ASSET_CSP } from './constants.ts';\nimport {\n THEME_ASSET_CONTENT_TYPES,\n THEME_ASSET_EXTENSIONS,\n themeAssetExtension,\n} from './contract/index.ts';\nimport type { IThemeProvider } from './types.ts';\n\nconst REQUEST_PATH_PATTERN = /^[a-z0-9][a-z0-9._/-]*$/i;\n\n/**\n * Serves the operator theme's `assets/` directory.\n *\n * Deliberately NOT `@routup/assets`' createHandler, for three reasons that\n * matter for an operator-supplied root:\n * - its lookup walks PATH SUFFIXES, so `/theme/anything/logo.svg` would\n * serve `/logo.svg`; the same file becomes reachable at unbounded\n * distinct URLs.\n * - it probes `.html` / `index.html` by default, which would make a stray\n * index.html a servable document on the IdP origin.\n * - it performs no realpath containment check, so a symlink inside the\n * mounted directory pointing outside it is served with a 200. A\n * read-only mount does not prevent that, and refusing symlinks outright\n * is not an option: a Kubernetes ConfigMap volume IS a symlink farm\n * (`key -> ..data/key`).\n */\nexport function createThemeAssetsHandler(provider: IThemeProvider) : Handler {\n return defineCoreHandler(async (event) => {\n const assetsPath = await provider.getAssetsPath();\n if (!assetsPath) {\n event.response.status = 404;\n\n return null;\n }\n\n let requestPath = event.path;\n const { mountPath } = event;\n if (requestPath.startsWith(mountPath)) {\n requestPath = requestPath.substring(mountPath.length);\n }\n\n if (requestPath.includes('%')) {\n try {\n requestPath = decodeURIComponent(requestPath);\n } catch {\n event.response.status = 404;\n\n return null;\n }\n }\n\n requestPath = requestPath.replace(/^\\/+/, '');\n\n // The contract's own parser, so the set the handler serves cannot\n // drift from the set the manifest validator accepts.\n const extension = themeAssetExtension(requestPath);\n\n if (\n !requestPath ||\n !REQUEST_PATH_PATTERN.test(requestPath) ||\n requestPath.split('/').includes('..') ||\n !THEME_ASSET_EXTENSIONS.includes(extension)\n ) {\n event.response.status = 404;\n\n return null;\n }\n\n // Both the root and the file are realpathed HERE, per request, and\n // never cached. A Kubernetes ConfigMap update swaps the `..data`\n // symlink to a new timestamped directory and deletes the old one,\n // so a root realpath captured at boot dangles after the first\n // update and every asset 404s until the pod restarts.\n //\n // The realpath is also the control that survives a symlink pointing\n // out of the mount; the pattern check above is only the cheap first\n // pass. Resolving both within the same request keeps the comparison\n // consistent: a swap landing between the two calls fails closed\n // (a transient 404), never open.\n let root : string;\n let filePath : string;\n let stats : fs.Stats;\n try {\n root = await fs.promises.realpath(assetsPath);\n filePath = await fs.promises.realpath(path.join(assetsPath, requestPath));\n stats = await fs.promises.stat(filePath);\n } catch {\n event.response.status = 404;\n\n return null;\n }\n\n if (\n !stats.isFile() ||\n (filePath !== root && !filePath.startsWith(root + path.sep))\n ) {\n event.response.status = 404;\n\n return null;\n }\n\n const etag = `W/\"${stats.size}-${stats.mtime.getTime()}\"`;\n event.response.headers.set(HeaderName.CACHE_CONTROL, 'public, max-age=0, must-revalidate');\n\n if (event.headers.get(HeaderName.IF_NONE_MATCH) === etag) {\n event.response.status = 304;\n\n return null;\n }\n\n const response = await sendFile(event, {\n content: (options) => Readable.toWeb(\n fs.createReadStream(filePath, options),\n ) as ReadableStream,\n stats: () => stats,\n name: filePath,\n });\n\n // Pin the content type from our own extension map rather than\n // letting it be sniffed or inferred, and neutralize SVG as active\n // content (an SVG navigated to directly executes inline script).\n response.headers.set(HeaderName.CONTENT_TYPE, THEME_ASSET_CONTENT_TYPES[extension]);\n response.headers.set('x-content-type-options', 'nosniff');\n response.headers.set('content-security-policy', THEME_ASSET_CSP);\n\n return response;\n });\n}\n"],"mappings":";;;;;;;;;;;;AAoBA,MAAMU,uBAAuB;;;;;;;;;;;;;;;;GAkB7B,SAAgBC,yBAAyBC,UAAwB;CAC7D,OAAOR,kBAAkB,OAAOS,UAAAA;EAC5B,MAAMC,aAAa,MAAMF,SAASG,cAAa;EAC/C,IAAI,CAACD,YAAY;GACbD,MAAMG,SAASC,SAAS;GAExB,OAAO;EACX;EAEA,IAAIC,cAAcL,MAAMZ;EACxB,MAAM,EAAEkB,cAAcN;EACtB,IAAIK,YAAYE,WAAWD,SAAAA,GACvBD,cAAcA,YAAYG,UAAUF,UAAUG,MAAM;EAGxD,IAAIJ,YAAYK,SAAS,GAAA,GACrB,IAAI;GACAL,cAAcM,mBAAmBN,WAAAA;EACrC,QAAQ;GACJL,MAAMG,SAASC,SAAS;GAExB,OAAO;EACX;EAGJC,cAAcA,YAAYO,QAAQ,QAAQ,EAAA;EAI1C,MAAMC,YAAYjB,oBAAoBS,WAAAA;EAEtC,IACI,CAACA,eACD,CAACR,qBAAqBiB,KAAKT,WAAAA,KAC3BA,YAAYU,MAAM,GAAA,CAAA,CAAKL,SAAS,IAAA,KAChC,CAACf,uBAAuBe,SAASG,SAAAA,GACnC;GACEb,MAAMG,SAASC,SAAS;GAExB,OAAO;EACX;EAaA,IAAIY;EACJ,IAAIC;EACJ,IAAIC;EACJ,IAAI;GACAF,OAAO,MAAM7B,GAAGgC,SAASC,SAASnB,UAAAA;GAClCgB,WAAW,MAAM9B,GAAGgC,SAASC,SAAShC,KAAKiC,KAAKpB,YAAYI,WAAAA,CAAAA;GAC5Da,QAAQ,MAAM/B,GAAGgC,SAASG,KAAKL,QAAAA;EACnC,QAAQ;GACJjB,MAAMG,SAASC,SAAS;GAExB,OAAO;EACX;EAEA,IACI,CAACc,MAAMK,OAAM,KACZN,aAAaD,QAAQ,CAACC,SAASV,WAAWS,OAAO5B,KAAKoC,GAAG,GAC5D;GACExB,MAAMG,SAASC,SAAS;GAExB,OAAO;EACX;EAEA,MAAMqB,OAAO,MAAMP,MAAMQ,KAAK,GAAGR,MAAMS,MAAMC,QAAO,EAAG;EACvD5B,MAAMG,SAAS0B,QAAQC,IAAIxC,WAAWyC,eAAe,oCAAA;EAErD,IAAI/B,MAAM6B,QAAQG,IAAI1C,WAAW2C,aAAa,MAAMR,MAAM;GACtDzB,MAAMG,SAASC,SAAS;GAExB,OAAO;EACX;EAEA,MAAMD,WAAW,MAAMX,SAASQ,OAAO;GACnCkC,UAAUC,YAAY9C,SAAS+C,MAC3BjD,GAAGkD,iBAAiBpB,UAAUkB,OAAAA,CAAAA;GAElCjB,aAAaA;GACboB,MAAMrB;EACV,CAAA;EAKAd,SAAS0B,QAAQC,IAAIxC,WAAWiD,cAAc7C,0BAA0BmB,UAAU;EAClFV,SAAS0B,QAAQC,IAAI,0BAA0B,SAAA;EAC/C3B,SAAS0B,QAAQC,IAAI,2BAA2BrC,eAAAA;EAEhD,OAAOU;CACX,CAAA;AACJ"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SERVING constants. The theme's own vocabulary (layout, manifest, tokens,
|
|
3
|
+
* asset kinds) lives in contract/, which stays portable.
|
|
4
|
+
*/
|
|
5
|
+
/**
|
|
6
|
+
* Debounce for the manifest mtime re-check. A burst of renders costs one
|
|
7
|
+
* stat; an edit takes effect on the next render after the window.
|
|
8
|
+
*/
|
|
9
|
+
export declare const THEME_MANIFEST_REVALIDATE_INTERVAL = 1000;
|
|
10
|
+
/**
|
|
11
|
+
* An SVG navigated to directly executes inline script, and a theme
|
|
12
|
+
* directory is exactly where operator SVGs land. This neutralizes that
|
|
13
|
+
* while leaving `<img>` and `background-image` rendering intact.
|
|
14
|
+
*/
|
|
15
|
+
export declare const THEME_ASSET_CSP = "default-src 'none'; style-src 'unsafe-inline'; img-src data:; sandbox";
|
|
16
|
+
//# sourceMappingURL=constants.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../../../../../src/adapters/http/ui/theme/constants.ts"],"names":[],"mappings":"AAOA;;;GAGG;AAEH;;;GAGG;AACH,eAAO,MAAM,kCAAkC,OAAQ,CAAC;AAExD;;;;GAIG;AACH,eAAO,MAAM,eAAe,0EAA0E,CAAC"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import "node:path";
|
|
2
|
+
import "node:url";
|
|
3
|
+
import.meta.url;
|
|
4
|
+
//#region src/adapters/http/ui/theme/constants.ts
|
|
5
|
+
/**
|
|
6
|
+
* SERVING constants. The theme's own vocabulary (layout, manifest, tokens,
|
|
7
|
+
* asset kinds) lives in contract/, which stays portable.
|
|
8
|
+
*/ /**
|
|
9
|
+
* Debounce for the manifest mtime re-check. A burst of renders costs one
|
|
10
|
+
* stat; an edit takes effect on the next render after the window.
|
|
11
|
+
*/ const THEME_MANIFEST_REVALIDATE_INTERVAL = 1e3;
|
|
12
|
+
/**
|
|
13
|
+
* An SVG navigated to directly executes inline script, and a theme
|
|
14
|
+
* directory is exactly where operator SVGs land. This neutralizes that
|
|
15
|
+
* while leaving `<img>` and `background-image` rendering intact.
|
|
16
|
+
*/ const THEME_ASSET_CSP = "default-src 'none'; style-src 'unsafe-inline'; img-src data:; sandbox";
|
|
17
|
+
//#endregion
|
|
18
|
+
export { THEME_ASSET_CSP, THEME_MANIFEST_REVALIDATE_INTERVAL };
|
|
19
|
+
|
|
20
|
+
//# sourceMappingURL=constants.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"constants.mjs","names":["THEME_MANIFEST_REVALIDATE_INTERVAL","THEME_ASSET_CSP"],"sources":["../../../../../src/adapters/http/ui/theme/constants.ts"],"sourcesContent":["/*\n * Copyright (c) 2026.\n * Author Peter Placzek (tada5hi)\n * For the full copyright and license information,\n * view the LICENSE file that was distributed with this source code.\n */\n\n/**\n * SERVING constants. The theme's own vocabulary (layout, manifest, tokens,\n * asset kinds) lives in contract/, which stays portable.\n */\n\n/**\n * Debounce for the manifest mtime re-check. A burst of renders costs one\n * stat; an edit takes effect on the next render after the window.\n */\nexport const THEME_MANIFEST_REVALIDATE_INTERVAL = 1_000;\n\n/**\n * An SVG navigated to directly executes inline script, and a theme\n * directory is exactly where operator SVGs land. This neutralizes that\n * while leaving `<img>` and `background-image` rendering intact.\n */\nexport const THEME_ASSET_CSP = \"default-src 'none'; style-src 'unsafe-inline'; img-src data:; sandbox\";\n"],"mappings":";;;;;;;;;;GAgBA,MAAaA,qCAAqC;;;;;GAOlD,MAAaC,kBAAkB"}
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The theme CONTRACT: the on-disk layout, the manifest vocabulary and the
|
|
3
|
+
* URL space a theme occupies. Everything here is portable — no node APIs,
|
|
4
|
+
* no HTTP — so a browser-side theme editor or a CLI validator can share it
|
|
5
|
+
* verbatim. Serving concerns (headers, caches, mounts) live one level up.
|
|
6
|
+
*/
|
|
7
|
+
export declare const THEME_MANIFEST_FILE_NAME = "theme.json";
|
|
8
|
+
/**
|
|
9
|
+
* The ONLY sub-directory reachable over HTTP. The mount root is
|
|
10
|
+
* `<themeDirectoryPath>/assets`, never the theme root, so `theme.json`
|
|
11
|
+
* (and any future non-public file) is unreachable by construction rather
|
|
12
|
+
* than by an extension filter a later edit could loosen.
|
|
13
|
+
*/
|
|
14
|
+
export declare const THEME_ASSETS_DIRECTORY_NAME = "assets";
|
|
15
|
+
export declare const THEME_FRAGMENTS_DIRECTORY_NAME = "fragments";
|
|
16
|
+
/**
|
|
17
|
+
* Raw markup spliced into `<head>`. Read only when the operator opts in
|
|
18
|
+
* via `themeFragmentsEnabled`: a fragment is unsanitized markup on the
|
|
19
|
+
* IdP origin, so it must be a deliberate decision and never a consequence
|
|
20
|
+
* of dropping a file into the mounted directory.
|
|
21
|
+
*
|
|
22
|
+
* Head-only by design. There is deliberately no in-`<body>` slot: a
|
|
23
|
+
* fragment rendered next to the consent buttons is a strictly better
|
|
24
|
+
* consent-forgery primitive than one in `<head>` (it could relabel or
|
|
25
|
+
* overlay Allow with no CSS at all).
|
|
26
|
+
*/
|
|
27
|
+
export declare const THEME_HEAD_FRAGMENT_FILE_NAME = "head.html";
|
|
28
|
+
export declare const THEME_HEAD_FRAGMENT_MAX_LENGTH: number;
|
|
29
|
+
/** The path segment the theme's `assets/` directory is served under. */
|
|
30
|
+
export declare const THEME_ASSET_MOUNT_PATH = "theme";
|
|
31
|
+
/**
|
|
32
|
+
* A manifest declares the contract version it was written against. An
|
|
33
|
+
* unknown version fails the boot instead of being partially understood.
|
|
34
|
+
*/
|
|
35
|
+
export declare const THEME_MANIFEST_VERSION = 1;
|
|
36
|
+
/**
|
|
37
|
+
* Token names are validated by GRAMMAR, not against a closed list of the
|
|
38
|
+
* `--authup-*` properties the theme packages happen to declare today.
|
|
39
|
+
*
|
|
40
|
+
* A closed list would have to live here, and this package cannot depend on
|
|
41
|
+
* `@authup/client-web-kit-theme`, so nothing could bind the two and it
|
|
42
|
+
* would rot in both directions: a newly added CSS token would fail
|
|
43
|
+
* validation for a legitimate override, and a removed one would stay
|
|
44
|
+
* accepted. The grammar cannot rot.
|
|
45
|
+
*
|
|
46
|
+
* It is NOT sufficient for an untrusted (per-realm) token source, and a
|
|
47
|
+
* later rung must not adopt it unchanged. Values are guarded by a denylist
|
|
48
|
+
* of CSS functions, and a denylist over a language that keeps gaining
|
|
49
|
+
* functions leaks by construction: `image-set()` and `src()` already had
|
|
50
|
+
* to be added after `url()`. Filesystem input is operator trust, equal to
|
|
51
|
+
* the process, so a denylist is proportionate here. Untrusted input needs
|
|
52
|
+
* an allowlist of accepted value SHAPES (a colour, a length, a keyword)
|
|
53
|
+
* per token, which is a different validator.
|
|
54
|
+
*/
|
|
55
|
+
export declare const THEME_TOKEN_NAME_PATTERN: RegExp;
|
|
56
|
+
export declare const THEME_TOKEN_VALUE_MAX_LENGTH = 256;
|
|
57
|
+
/**
|
|
58
|
+
* Keeps a token value from closing the declaration block, opening a tag,
|
|
59
|
+
* starting a new at-rule or comment, or turning the server-emitted token
|
|
60
|
+
* block into a request-emitting sink. Layer 2 (`theme.css`) may of course
|
|
61
|
+
* use `url()`; that asymmetry is deliberate and documented.
|
|
62
|
+
*
|
|
63
|
+
* `{` is forbidden alongside `}`: it opens a block inside the declaration,
|
|
64
|
+
* which swallows the rule that follows. One stray brace in a light token
|
|
65
|
+
* silently absorbs the whole `.dark` rule, so dark mode stops applying
|
|
66
|
+
* with no error anywhere.
|
|
67
|
+
*
|
|
68
|
+
* Vendor prefixes are covered (`-webkit-image-set(`), and so is whitespace
|
|
69
|
+
* before the paren; escapes cannot be used to smuggle a name past this
|
|
70
|
+
* because `\` is forbidden outright.
|
|
71
|
+
*/
|
|
72
|
+
export declare const THEME_TOKEN_VALUE_FORBIDDEN_PATTERN: RegExp;
|
|
73
|
+
/**
|
|
74
|
+
* Every asset kind a theme may contain, and the content type it is pinned
|
|
75
|
+
* to when served. Notably excludes `.html` and `.js`, so a stray document
|
|
76
|
+
* or script in the mounted directory can never be served from the IdP
|
|
77
|
+
* origin.
|
|
78
|
+
*/
|
|
79
|
+
export declare const THEME_ASSET_CONTENT_TYPES: Record<string, string>;
|
|
80
|
+
/**
|
|
81
|
+
* Derived, never hand-maintained: the allowlist and the content-type map
|
|
82
|
+
* must describe the same set, or a servable extension would be sent with
|
|
83
|
+
* an undefined content type.
|
|
84
|
+
*/
|
|
85
|
+
export declare const THEME_ASSET_EXTENSIONS: string[];
|
|
86
|
+
/**
|
|
87
|
+
* The subset a `logo` may use. Derived from the content-type map so a new
|
|
88
|
+
* image type is servable and usable as a logo in one edit.
|
|
89
|
+
*/
|
|
90
|
+
export declare const THEME_IMAGE_EXTENSIONS: string[];
|
|
91
|
+
/**
|
|
92
|
+
* Emitted by server-core from a manifest's `logo`, never authored as a raw
|
|
93
|
+
* token: the value carries a `url()`, which the token grammar forbids for
|
|
94
|
+
* operator-supplied values so the token block cannot become a
|
|
95
|
+
* request-emitting sink. The href is built from an already-validated asset
|
|
96
|
+
* path.
|
|
97
|
+
*/
|
|
98
|
+
export declare const THEME_LOGO_TOKENS: readonly [{
|
|
99
|
+
readonly image: "--authup-auth-logo-image";
|
|
100
|
+
readonly markVisibility: "--authup-auth-logo-mark-visibility";
|
|
101
|
+
}, {
|
|
102
|
+
readonly image: "--authup-account-logo-image";
|
|
103
|
+
readonly markVisibility: "--authup-account-logo-mark-visibility";
|
|
104
|
+
}];
|
|
105
|
+
/**
|
|
106
|
+
* The CSS layer the token block is emitted into.
|
|
107
|
+
*
|
|
108
|
+
* A layer name not present in the bundle's `@layer` statement is appended
|
|
109
|
+
* LAST in the layer order, so it beats `@layer authup` (the kit tokens)
|
|
110
|
+
* and `@layer base` (the app theme's brand rebinds and its `.dark` flips)
|
|
111
|
+
* without needing `!important`. Inside the block `.dark` beats `:root` by
|
|
112
|
+
* source order, so dark mode keeps working.
|
|
113
|
+
*
|
|
114
|
+
* Deliberately NOT an inline `style` attribute on `<html>`: that would win
|
|
115
|
+
* permanently, and the color-mode switcher flips the `.dark` class
|
|
116
|
+
* client-side with no reload, which would freeze the brand at whatever the
|
|
117
|
+
* cookie said at render time.
|
|
118
|
+
*/
|
|
119
|
+
export declare const THEME_CSS_LAYER_NAME = "authup-theme";
|
|
120
|
+
//# sourceMappingURL=constants.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../../../../../../src/adapters/http/ui/theme/contract/constants.ts"],"names":[],"mappings":"AAOA;;;;;GAKG;AAEH,eAAO,MAAM,wBAAwB,eAAe,CAAC;AAErD;;;;;GAKG;AACH,eAAO,MAAM,2BAA2B,WAAW,CAAC;AAEpD,eAAO,MAAM,8BAA8B,cAAc,CAAC;AAE1D;;;;;;;;;;GAUG;AACH,eAAO,MAAM,6BAA6B,cAAc,CAAC;AAEzD,eAAO,MAAM,8BAA8B,QAAY,CAAC;AAExD,wEAAwE;AACxE,eAAO,MAAM,sBAAsB,UAAU,CAAC;AAE9C;;;GAGG;AACH,eAAO,MAAM,sBAAsB,IAAI,CAAC;AAExC;;;;;;;;;;;;;;;;;;GAkBG;AACH,eAAO,MAAM,wBAAwB,QAAwB,CAAC;AAE9D,eAAO,MAAM,4BAA4B,MAAM,CAAC;AA8BhD;;;;;;;;;;;;;;GAcG;AACH,eAAO,MAAM,mCAAmC,QAG/C,CAAC;AAEF;;;;;GAKG;AACH,eAAO,MAAM,yBAAyB,EAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAY7D,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,sBAAsB,UAAyC,CAAC;AAE7E;;;GAGG;AACH,eAAO,MAAM,sBAAsB,UACkD,CAAC;AAEtF;;;;;;GAMG;AACH,eAAO,MAAM,iBAAiB;;;;;;EAGpB,CAAC;AAEX;;;;;;;;;;;;;GAaG;AACH,eAAO,MAAM,oBAAoB,iBAAiB,CAAC"}
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
import "node:path";
|
|
2
|
+
import "node:url";
|
|
3
|
+
import.meta.url;
|
|
4
|
+
//#region src/adapters/http/ui/theme/contract/constants.ts
|
|
5
|
+
/**
|
|
6
|
+
* The theme CONTRACT: the on-disk layout, the manifest vocabulary and the
|
|
7
|
+
* URL space a theme occupies. Everything here is portable — no node APIs,
|
|
8
|
+
* no HTTP — so a browser-side theme editor or a CLI validator can share it
|
|
9
|
+
* verbatim. Serving concerns (headers, caches, mounts) live one level up.
|
|
10
|
+
*/ const THEME_MANIFEST_FILE_NAME = "theme.json";
|
|
11
|
+
/**
|
|
12
|
+
* The ONLY sub-directory reachable over HTTP. The mount root is
|
|
13
|
+
* `<themeDirectoryPath>/assets`, never the theme root, so `theme.json`
|
|
14
|
+
* (and any future non-public file) is unreachable by construction rather
|
|
15
|
+
* than by an extension filter a later edit could loosen.
|
|
16
|
+
*/ const THEME_ASSETS_DIRECTORY_NAME = "assets";
|
|
17
|
+
const THEME_FRAGMENTS_DIRECTORY_NAME = "fragments";
|
|
18
|
+
/**
|
|
19
|
+
* Raw markup spliced into `<head>`. Read only when the operator opts in
|
|
20
|
+
* via `themeFragmentsEnabled`: a fragment is unsanitized markup on the
|
|
21
|
+
* IdP origin, so it must be a deliberate decision and never a consequence
|
|
22
|
+
* of dropping a file into the mounted directory.
|
|
23
|
+
*
|
|
24
|
+
* Head-only by design. There is deliberately no in-`<body>` slot: a
|
|
25
|
+
* fragment rendered next to the consent buttons is a strictly better
|
|
26
|
+
* consent-forgery primitive than one in `<head>` (it could relabel or
|
|
27
|
+
* overlay Allow with no CSS at all).
|
|
28
|
+
*/ const THEME_HEAD_FRAGMENT_FILE_NAME = "head.html";
|
|
29
|
+
const THEME_HEAD_FRAGMENT_MAX_LENGTH = 65536;
|
|
30
|
+
/** The path segment the theme's `assets/` directory is served under. */ const THEME_ASSET_MOUNT_PATH = "theme";
|
|
31
|
+
/**
|
|
32
|
+
* A manifest declares the contract version it was written against. An
|
|
33
|
+
* unknown version fails the boot instead of being partially understood.
|
|
34
|
+
*/ const THEME_MANIFEST_VERSION = 1;
|
|
35
|
+
/**
|
|
36
|
+
* Token names are validated by GRAMMAR, not against a closed list of the
|
|
37
|
+
* `--authup-*` properties the theme packages happen to declare today.
|
|
38
|
+
*
|
|
39
|
+
* A closed list would have to live here, and this package cannot depend on
|
|
40
|
+
* `@authup/client-web-kit-theme`, so nothing could bind the two and it
|
|
41
|
+
* would rot in both directions: a newly added CSS token would fail
|
|
42
|
+
* validation for a legitimate override, and a removed one would stay
|
|
43
|
+
* accepted. The grammar cannot rot.
|
|
44
|
+
*
|
|
45
|
+
* It is NOT sufficient for an untrusted (per-realm) token source, and a
|
|
46
|
+
* later rung must not adopt it unchanged. Values are guarded by a denylist
|
|
47
|
+
* of CSS functions, and a denylist over a language that keeps gaining
|
|
48
|
+
* functions leaks by construction: `image-set()` and `src()` already had
|
|
49
|
+
* to be added after `url()`. Filesystem input is operator trust, equal to
|
|
50
|
+
* the process, so a denylist is proportionate here. Untrusted input needs
|
|
51
|
+
* an allowlist of accepted value SHAPES (a colour, a length, a keyword)
|
|
52
|
+
* per token, which is a different validator.
|
|
53
|
+
*/ const THEME_TOKEN_NAME_PATTERN = /^--[a-z][a-z0-9-]*$/;
|
|
54
|
+
const THEME_TOKEN_VALUE_MAX_LENGTH = 256;
|
|
55
|
+
/**
|
|
56
|
+
* Keeps a token value from closing the declaration block, opening a tag,
|
|
57
|
+
* starting a new at-rule or comment, or turning the server-emitted token
|
|
58
|
+
* block into a request-emitting sink. Layer 2 (`theme.css`) may of course
|
|
59
|
+
* use `url()`; that asymmetry is deliberate and documented.
|
|
60
|
+
*
|
|
61
|
+
* `{` is forbidden alongside `}`: it opens a block inside the declaration,
|
|
62
|
+
* which swallows the rule that follows. One stray brace in a light token
|
|
63
|
+
* silently absorbs the whole `.dark` rule, so dark mode stops applying
|
|
64
|
+
* with no error anywhere.
|
|
65
|
+
*
|
|
66
|
+
* Vendor prefixes are covered (`-webkit-image-set(`), and so is whitespace
|
|
67
|
+
* before the paren; escapes cannot be used to smuggle a name past this
|
|
68
|
+
* because `\` is forbidden outright.
|
|
69
|
+
*/ const THEME_TOKEN_VALUE_FORBIDDEN_PATTERN = new RegExp(`[{}<>;@\\\\]|\\/\\*|(?:^|[^a-z0-9-])(?:-[a-z]+-)?(?:${[
|
|
70
|
+
"url",
|
|
71
|
+
"expression",
|
|
72
|
+
"image",
|
|
73
|
+
"image-set",
|
|
74
|
+
"src",
|
|
75
|
+
"cross-fade",
|
|
76
|
+
"element",
|
|
77
|
+
"paint"
|
|
78
|
+
].join("|")})\\s*\\(`, "i");
|
|
79
|
+
/**
|
|
80
|
+
* Every asset kind a theme may contain, and the content type it is pinned
|
|
81
|
+
* to when served. Notably excludes `.html` and `.js`, so a stray document
|
|
82
|
+
* or script in the mounted directory can never be served from the IdP
|
|
83
|
+
* origin.
|
|
84
|
+
*/ const THEME_ASSET_CONTENT_TYPES = {
|
|
85
|
+
".css": "text/css; charset=utf-8",
|
|
86
|
+
".svg": "image/svg+xml",
|
|
87
|
+
".png": "image/png",
|
|
88
|
+
".jpg": "image/jpeg",
|
|
89
|
+
".jpeg": "image/jpeg",
|
|
90
|
+
".gif": "image/gif",
|
|
91
|
+
".webp": "image/webp",
|
|
92
|
+
".avif": "image/avif",
|
|
93
|
+
".ico": "image/x-icon",
|
|
94
|
+
".woff": "font/woff",
|
|
95
|
+
".woff2": "font/woff2"
|
|
96
|
+
};
|
|
97
|
+
/**
|
|
98
|
+
* Derived, never hand-maintained: the allowlist and the content-type map
|
|
99
|
+
* must describe the same set, or a servable extension would be sent with
|
|
100
|
+
* an undefined content type.
|
|
101
|
+
*/ const THEME_ASSET_EXTENSIONS = Object.keys(THEME_ASSET_CONTENT_TYPES);
|
|
102
|
+
/**
|
|
103
|
+
* The subset a `logo` may use. Derived from the content-type map so a new
|
|
104
|
+
* image type is servable and usable as a logo in one edit.
|
|
105
|
+
*/ const THEME_IMAGE_EXTENSIONS = THEME_ASSET_EXTENSIONS.filter((extension) => THEME_ASSET_CONTENT_TYPES[extension].startsWith("image/"));
|
|
106
|
+
/**
|
|
107
|
+
* Emitted by server-core from a manifest's `logo`, never authored as a raw
|
|
108
|
+
* token: the value carries a `url()`, which the token grammar forbids for
|
|
109
|
+
* operator-supplied values so the token block cannot become a
|
|
110
|
+
* request-emitting sink. The href is built from an already-validated asset
|
|
111
|
+
* path.
|
|
112
|
+
*/ const THEME_LOGO_TOKENS = [{
|
|
113
|
+
image: "--authup-auth-logo-image",
|
|
114
|
+
markVisibility: "--authup-auth-logo-mark-visibility"
|
|
115
|
+
}, {
|
|
116
|
+
image: "--authup-account-logo-image",
|
|
117
|
+
markVisibility: "--authup-account-logo-mark-visibility"
|
|
118
|
+
}];
|
|
119
|
+
/**
|
|
120
|
+
* The CSS layer the token block is emitted into.
|
|
121
|
+
*
|
|
122
|
+
* A layer name not present in the bundle's `@layer` statement is appended
|
|
123
|
+
* LAST in the layer order, so it beats `@layer authup` (the kit tokens)
|
|
124
|
+
* and `@layer base` (the app theme's brand rebinds and its `.dark` flips)
|
|
125
|
+
* without needing `!important`. Inside the block `.dark` beats `:root` by
|
|
126
|
+
* source order, so dark mode keeps working.
|
|
127
|
+
*
|
|
128
|
+
* Deliberately NOT an inline `style` attribute on `<html>`: that would win
|
|
129
|
+
* permanently, and the color-mode switcher flips the `.dark` class
|
|
130
|
+
* client-side with no reload, which would freeze the brand at whatever the
|
|
131
|
+
* cookie said at render time.
|
|
132
|
+
*/ const THEME_CSS_LAYER_NAME = "authup-theme";
|
|
133
|
+
//#endregion
|
|
134
|
+
export { THEME_ASSETS_DIRECTORY_NAME, THEME_ASSET_CONTENT_TYPES, THEME_ASSET_EXTENSIONS, THEME_ASSET_MOUNT_PATH, THEME_CSS_LAYER_NAME, THEME_FRAGMENTS_DIRECTORY_NAME, THEME_HEAD_FRAGMENT_FILE_NAME, THEME_HEAD_FRAGMENT_MAX_LENGTH, THEME_IMAGE_EXTENSIONS, THEME_LOGO_TOKENS, THEME_MANIFEST_FILE_NAME, THEME_MANIFEST_VERSION, THEME_TOKEN_NAME_PATTERN, THEME_TOKEN_VALUE_FORBIDDEN_PATTERN, THEME_TOKEN_VALUE_MAX_LENGTH };
|
|
135
|
+
|
|
136
|
+
//# sourceMappingURL=constants.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"constants.mjs","names":["THEME_MANIFEST_FILE_NAME","THEME_ASSETS_DIRECTORY_NAME","THEME_FRAGMENTS_DIRECTORY_NAME","THEME_HEAD_FRAGMENT_FILE_NAME","THEME_HEAD_FRAGMENT_MAX_LENGTH","THEME_ASSET_MOUNT_PATH","THEME_MANIFEST_VERSION","THEME_TOKEN_NAME_PATTERN","THEME_TOKEN_VALUE_MAX_LENGTH","THEME_TOKEN_VALUE_FORBIDDEN_FUNCTIONS","THEME_TOKEN_VALUE_FORBIDDEN_PATTERN","RegExp","join","THEME_ASSET_CONTENT_TYPES","THEME_ASSET_EXTENSIONS","Object","keys","THEME_IMAGE_EXTENSIONS","filter","extension","startsWith","THEME_LOGO_TOKENS","image","markVisibility","THEME_CSS_LAYER_NAME"],"sources":["../../../../../../src/adapters/http/ui/theme/contract/constants.ts"],"sourcesContent":["/*\n * Copyright (c) 2026.\n * Author Peter Placzek (tada5hi)\n * For the full copyright and license information,\n * view the LICENSE file that was distributed with this source code.\n */\n\n/**\n * The theme CONTRACT: the on-disk layout, the manifest vocabulary and the\n * URL space a theme occupies. Everything here is portable — no node APIs,\n * no HTTP — so a browser-side theme editor or a CLI validator can share it\n * verbatim. Serving concerns (headers, caches, mounts) live one level up.\n */\n\nexport const THEME_MANIFEST_FILE_NAME = 'theme.json';\n\n/**\n * The ONLY sub-directory reachable over HTTP. The mount root is\n * `<themeDirectoryPath>/assets`, never the theme root, so `theme.json`\n * (and any future non-public file) is unreachable by construction rather\n * than by an extension filter a later edit could loosen.\n */\nexport const THEME_ASSETS_DIRECTORY_NAME = 'assets';\n\nexport const THEME_FRAGMENTS_DIRECTORY_NAME = 'fragments';\n\n/**\n * Raw markup spliced into `<head>`. Read only when the operator opts in\n * via `themeFragmentsEnabled`: a fragment is unsanitized markup on the\n * IdP origin, so it must be a deliberate decision and never a consequence\n * of dropping a file into the mounted directory.\n *\n * Head-only by design. There is deliberately no in-`<body>` slot: a\n * fragment rendered next to the consent buttons is a strictly better\n * consent-forgery primitive than one in `<head>` (it could relabel or\n * overlay Allow with no CSS at all).\n */\nexport const THEME_HEAD_FRAGMENT_FILE_NAME = 'head.html';\n\nexport const THEME_HEAD_FRAGMENT_MAX_LENGTH = 64 * 1024;\n\n/** The path segment the theme's `assets/` directory is served under. */\nexport const THEME_ASSET_MOUNT_PATH = 'theme';\n\n/**\n * A manifest declares the contract version it was written against. An\n * unknown version fails the boot instead of being partially understood.\n */\nexport const THEME_MANIFEST_VERSION = 1;\n\n/**\n * Token names are validated by GRAMMAR, not against a closed list of the\n * `--authup-*` properties the theme packages happen to declare today.\n *\n * A closed list would have to live here, and this package cannot depend on\n * `@authup/client-web-kit-theme`, so nothing could bind the two and it\n * would rot in both directions: a newly added CSS token would fail\n * validation for a legitimate override, and a removed one would stay\n * accepted. The grammar cannot rot.\n *\n * It is NOT sufficient for an untrusted (per-realm) token source, and a\n * later rung must not adopt it unchanged. Values are guarded by a denylist\n * of CSS functions, and a denylist over a language that keeps gaining\n * functions leaks by construction: `image-set()` and `src()` already had\n * to be added after `url()`. Filesystem input is operator trust, equal to\n * the process, so a denylist is proportionate here. Untrusted input needs\n * an allowlist of accepted value SHAPES (a colour, a length, a keyword)\n * per token, which is a different validator.\n */\nexport const THEME_TOKEN_NAME_PATTERN = /^--[a-z][a-z0-9-]*$/;\n\nexport const THEME_TOKEN_VALUE_MAX_LENGTH = 256;\n\n/**\n * Every CSS function that can load a remote resource.\n *\n * Blocking `url(` alone does not close the request-emitting-sink hole:\n * `image-set()`, `image()`, `src()` and `cross-fade()` all take a bare\n * string URL, and a token like `--authup-auth-logo-image` is substituted\n * straight into an image-accepting property. `element()` and `paint()`\n * cannot fetch, but they render document content into a paint sink and\n * have no business in an operator token either.\n *\n * A denylist over function names is still a denylist, so this list is the\n * floor rather than the argument: the values it guards are operator\n * authored, and an operator can already ship arbitrary CSS through\n * `theme.css`. It exists so a value cannot QUIETLY do something the\n * grammar advertises as impossible. A per-realm (untrusted) token source\n * must not reuse it as-is; see the note on the name pattern below.\n */\nconst THEME_TOKEN_VALUE_FORBIDDEN_FUNCTIONS = [\n 'url',\n 'expression',\n 'image',\n 'image-set',\n 'src',\n 'cross-fade',\n 'element',\n 'paint',\n];\n\n/**\n * Keeps a token value from closing the declaration block, opening a tag,\n * starting a new at-rule or comment, or turning the server-emitted token\n * block into a request-emitting sink. Layer 2 (`theme.css`) may of course\n * use `url()`; that asymmetry is deliberate and documented.\n *\n * `{` is forbidden alongside `}`: it opens a block inside the declaration,\n * which swallows the rule that follows. One stray brace in a light token\n * silently absorbs the whole `.dark` rule, so dark mode stops applying\n * with no error anywhere.\n *\n * Vendor prefixes are covered (`-webkit-image-set(`), and so is whitespace\n * before the paren; escapes cannot be used to smuggle a name past this\n * because `\\` is forbidden outright.\n */\nexport const THEME_TOKEN_VALUE_FORBIDDEN_PATTERN = new RegExp(\n `[{}<>;@\\\\\\\\]|\\\\/\\\\*|(?:^|[^a-z0-9-])(?:-[a-z]+-)?(?:${THEME_TOKEN_VALUE_FORBIDDEN_FUNCTIONS.join('|')})\\\\s*\\\\(`,\n 'i',\n);\n\n/**\n * Every asset kind a theme may contain, and the content type it is pinned\n * to when served. Notably excludes `.html` and `.js`, so a stray document\n * or script in the mounted directory can never be served from the IdP\n * origin.\n */\nexport const THEME_ASSET_CONTENT_TYPES : Record<string, string> = {\n '.css': 'text/css; charset=utf-8',\n '.svg': 'image/svg+xml',\n '.png': 'image/png',\n '.jpg': 'image/jpeg',\n '.jpeg': 'image/jpeg',\n '.gif': 'image/gif',\n '.webp': 'image/webp',\n '.avif': 'image/avif',\n '.ico': 'image/x-icon',\n '.woff': 'font/woff',\n '.woff2': 'font/woff2',\n};\n\n/**\n * Derived, never hand-maintained: the allowlist and the content-type map\n * must describe the same set, or a servable extension would be sent with\n * an undefined content type.\n */\nexport const THEME_ASSET_EXTENSIONS = Object.keys(THEME_ASSET_CONTENT_TYPES);\n\n/**\n * The subset a `logo` may use. Derived from the content-type map so a new\n * image type is servable and usable as a logo in one edit.\n */\nexport const THEME_IMAGE_EXTENSIONS = THEME_ASSET_EXTENSIONS\n .filter((extension) => THEME_ASSET_CONTENT_TYPES[extension].startsWith('image/'));\n\n/**\n * Emitted by server-core from a manifest's `logo`, never authored as a raw\n * token: the value carries a `url()`, which the token grammar forbids for\n * operator-supplied values so the token block cannot become a\n * request-emitting sink. The href is built from an already-validated asset\n * path.\n */\nexport const THEME_LOGO_TOKENS = [\n { image: '--authup-auth-logo-image', markVisibility: '--authup-auth-logo-mark-visibility' },\n { image: '--authup-account-logo-image', markVisibility: '--authup-account-logo-mark-visibility' },\n] as const;\n\n/**\n * The CSS layer the token block is emitted into.\n *\n * A layer name not present in the bundle's `@layer` statement is appended\n * LAST in the layer order, so it beats `@layer authup` (the kit tokens)\n * and `@layer base` (the app theme's brand rebinds and its `.dark` flips)\n * without needing `!important`. Inside the block `.dark` beats `:root` by\n * source order, so dark mode keeps working.\n *\n * Deliberately NOT an inline `style` attribute on `<html>`: that would win\n * permanently, and the color-mode switcher flips the `.dark` class\n * client-side with no reload, which would freeze the brand at whatever the\n * cookie said at render time.\n */\nexport const THEME_CSS_LAYER_NAME = 'authup-theme';\n"],"mappings":";;;;;;;;;GAcA,MAAaA,2BAA2B;;;;;;GAQxC,MAAaC,8BAA8B;AAE3C,MAAaC,iCAAiC;;;;;;;;;;;GAa9C,MAAaC,gCAAgC;AAE7C,MAAaC,iCAAiC;yEAG9C,MAAaC,yBAAyB;;;;GAMtC,MAAaC,yBAAyB;;;;;;;;;;;;;;;;;;;GAqBtC,MAAaC,2BAA2B;AAExC,MAAaC,+BAA+B;;;;;;;;;;;;;;;GA6C5C,MAAaE,sCAAsC,IAAIC,OACnD,uDAAuDF;CA1BvD;CACA;CACA;CACA;CACA;CACA;CACA;CACA;AAmBuDA,CAAAA,CAAsCG,KAAK,GAAA,EAAK,WACvG,GAAA;;;;;;GASJ,MAAaC,4BAAqD;CAC9D,QAAQ;CACR,QAAQ;CACR,QAAQ;CACR,QAAQ;CACR,SAAS;CACT,QAAQ;CACR,SAAS;CACT,SAAS;CACT,QAAQ;CACR,SAAS;CACT,UAAU;AACd;;;;;GAOA,MAAaC,yBAAyBC,OAAOC,KAAKH,yBAAAA;;;;GAMlD,MAAaI,yBAAyBH,uBACjCI,QAAQC,cAAcN,0BAA0BM,UAAU,CAACC,WAAW,QAAA,CAAA;;;;;;;GAS3E,MAAaC,oBAAoB,CAC7B;CAAEC,OAAO;CAA4BC,gBAAgB;AAAqC,GAC1F;CAAED,OAAO;CAA+BC,gBAAgB;AAAwC,CACnG;;;;;;;;;;;;;;GAgBD,MAAaC,uBAAuB"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { ThemeManifest } from './types.ts';
|
|
2
|
+
export declare function escapeHtml(value: string): string;
|
|
3
|
+
/**
|
|
4
|
+
* The `<style>`/`<link>` block injected before `</head>`.
|
|
5
|
+
*
|
|
6
|
+
* Every value here has already passed the manifest grammar (no `<`, `>`,
|
|
7
|
+
* `}`, `;` or `@` in a token value; asset paths are alphanumeric plus
|
|
8
|
+
* `._/-`), so the emitted CSS cannot be broken out of. The title is the
|
|
9
|
+
* one free-form field and is HTML-escaped.
|
|
10
|
+
*/
|
|
11
|
+
export declare function buildThemeHead(manifest: ThemeManifest, basePath: string, fragment?: string): string;
|
|
12
|
+
//# sourceMappingURL=head.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"head.d.ts","sourceRoot":"","sources":["../../../../../../src/adapters/http/ui/theme/contract/head.ts"],"names":[],"mappings":"AAaA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAEhD,wBAAgB,UAAU,CAAC,KAAK,EAAE,MAAM,GAAI,MAAM,CAMjD;AA2CD;;;;;;;GAOG;AACH,wBAAgB,cAAc,CAC1B,QAAQ,EAAE,aAAa,EACvB,QAAQ,EAAE,MAAM,EAChB,QAAQ,CAAC,EAAE,MAAM,GACjB,MAAM,CAuDT"}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import "node:path";
|
|
2
|
+
import "node:url";
|
|
3
|
+
import.meta.url;
|
|
4
|
+
import { THEME_ASSETS_DIRECTORY_NAME, THEME_ASSET_MOUNT_PATH, THEME_CSS_LAYER_NAME, THEME_LOGO_TOKENS } from "./constants.mjs";
|
|
5
|
+
//#region src/adapters/http/ui/theme/contract/head.ts
|
|
6
|
+
function escapeHtml(value) {
|
|
7
|
+
return value.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """);
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* Turn a manifest asset path (`assets/logo.svg`) into the href it is
|
|
11
|
+
* served under.
|
|
12
|
+
*
|
|
13
|
+
* Built with the base path up front rather than via rebaseAssetURLs, which
|
|
14
|
+
* only rewrites the fixed `/public/` and `/account/` vite bases.
|
|
15
|
+
*/ function buildAssetURL(assetPath, basePath) {
|
|
16
|
+
const name = assetPath.slice(`${THEME_ASSETS_DIRECTORY_NAME}/`.length);
|
|
17
|
+
return `${basePath}/${THEME_ASSET_MOUNT_PATH}/${name}`;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* The token pair that swaps the built-in mark for an operator image, for
|
|
21
|
+
* one color mode. Empty when that mode declares no logo, so the other
|
|
22
|
+
* mode's rule (or the built-in mark) stands.
|
|
23
|
+
*/ function buildLogoTokens(logo, basePath) {
|
|
24
|
+
const tokens = {};
|
|
25
|
+
if (!logo) return tokens;
|
|
26
|
+
const url = buildAssetURL(logo, basePath);
|
|
27
|
+
for (const pair of THEME_LOGO_TOKENS) {
|
|
28
|
+
tokens[pair.image] = `url("${url}")`;
|
|
29
|
+
tokens[pair.markVisibility] = "hidden";
|
|
30
|
+
}
|
|
31
|
+
return tokens;
|
|
32
|
+
}
|
|
33
|
+
function buildTokenRule(selector, tokens) {
|
|
34
|
+
return `${selector}{${Object.keys(tokens).map((name) => `${name}:${tokens[name]}`).join(";")}}`;
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* The `<style>`/`<link>` block injected before `</head>`.
|
|
38
|
+
*
|
|
39
|
+
* Every value here has already passed the manifest grammar (no `<`, `>`,
|
|
40
|
+
* `}`, `;` or `@` in a token value; asset paths are alphanumeric plus
|
|
41
|
+
* `._/-`), so the emitted CSS cannot be broken out of. The title is the
|
|
42
|
+
* one free-form field and is HTML-escaped.
|
|
43
|
+
*/ function buildThemeHead(manifest, basePath, fragment) {
|
|
44
|
+
const parts = [];
|
|
45
|
+
const rules = [];
|
|
46
|
+
const tokens = buildLogoTokens(manifest.logo, basePath);
|
|
47
|
+
Object.assign(tokens, manifest.tokens);
|
|
48
|
+
const tokensDark = buildLogoTokens(manifest.logoDark, basePath);
|
|
49
|
+
Object.assign(tokensDark, manifest.tokensDark);
|
|
50
|
+
if (Object.keys(tokens).length > 0) rules.push(buildTokenRule(":root", tokens));
|
|
51
|
+
if (Object.keys(tokensDark).length > 0) rules.push(buildTokenRule(".dark", tokensDark));
|
|
52
|
+
if (rules.length > 0) parts.push(`<style>@layer ${THEME_CSS_LAYER_NAME}{${rules.join("")}}</style>`);
|
|
53
|
+
if (manifest.favicon) parts.push(`<link rel="icon" href="${escapeHtml(buildAssetURL(manifest.favicon, basePath))}">`);
|
|
54
|
+
if (manifest.stylesheet) parts.push(`<link rel="stylesheet" href="${escapeHtml(buildAssetURL(manifest.stylesheet, basePath))}">`);
|
|
55
|
+
if (fragment) parts.push(fragment);
|
|
56
|
+
return parts.join("");
|
|
57
|
+
}
|
|
58
|
+
//#endregion
|
|
59
|
+
export { buildThemeHead, escapeHtml };
|
|
60
|
+
|
|
61
|
+
//# sourceMappingURL=head.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"head.mjs","names":["THEME_ASSETS_DIRECTORY_NAME","THEME_ASSET_MOUNT_PATH","THEME_CSS_LAYER_NAME","THEME_LOGO_TOKENS","escapeHtml","value","replace","buildAssetURL","assetPath","basePath","name","slice","length","buildLogoTokens","logo","tokens","url","pair","image","markVisibility","buildTokenRule","selector","declarations","Object","keys","map","join","buildThemeHead","manifest","fragment","parts","rules","assign","tokensDark","logoDark","push","favicon","stylesheet"],"sources":["../../../../../../src/adapters/http/ui/theme/contract/head.ts"],"sourcesContent":["/*\n * Copyright (c) 2026.\n * Author Peter Placzek (tada5hi)\n * For the full copyright and license information,\n * view the LICENSE file that was distributed with this source code.\n */\n\nimport {\n THEME_ASSETS_DIRECTORY_NAME,\n THEME_ASSET_MOUNT_PATH,\n THEME_CSS_LAYER_NAME,\n THEME_LOGO_TOKENS,\n} from './constants.ts';\nimport type { ThemeManifest } from './types.ts';\n\nexport function escapeHtml(value: string) : string {\n return value\n .replace(/&/g, '&')\n .replace(/</g, '<')\n .replace(/>/g, '>')\n .replace(/\"/g, '"');\n}\n\n/**\n * Turn a manifest asset path (`assets/logo.svg`) into the href it is\n * served under.\n *\n * Built with the base path up front rather than via rebaseAssetURLs, which\n * only rewrites the fixed `/public/` and `/account/` vite bases.\n */\nfunction buildAssetURL(assetPath: string, basePath: string) : string {\n const name = assetPath.slice(`${THEME_ASSETS_DIRECTORY_NAME}/`.length);\n\n return `${basePath}/${THEME_ASSET_MOUNT_PATH}/${name}`;\n}\n\n/**\n * The token pair that swaps the built-in mark for an operator image, for\n * one color mode. Empty when that mode declares no logo, so the other\n * mode's rule (or the built-in mark) stands.\n */\nfunction buildLogoTokens(logo: string | undefined, basePath: string) : Record<string, string> {\n const tokens : Record<string, string> = {};\n if (!logo) {\n return tokens;\n }\n\n const url = buildAssetURL(logo, basePath);\n for (const pair of THEME_LOGO_TOKENS) {\n tokens[pair.image] = `url(\"${url}\")`;\n tokens[pair.markVisibility] = 'hidden';\n }\n\n return tokens;\n}\n\nfunction buildTokenRule(selector: string, tokens: Record<string, string>) : string {\n const declarations = Object.keys(tokens)\n .map((name) => `${name}:${tokens[name]}`)\n .join(';');\n\n return `${selector}{${declarations}}`;\n}\n\n/**\n * The `<style>`/`<link>` block injected before `</head>`.\n *\n * Every value here has already passed the manifest grammar (no `<`, `>`,\n * `}`, `;` or `@` in a token value; asset paths are alphanumeric plus\n * `._/-`), so the emitted CSS cannot be broken out of. The title is the\n * one free-form field and is HTML-escaped.\n */\nexport function buildThemeHead(\n manifest: ThemeManifest,\n basePath: string,\n fragment?: string,\n) : string {\n const parts : string[] = [];\n\n const rules : string[] = [];\n\n // The logo is a manifest field rather than a raw token because its\n // value needs url(), which the token grammar forbids. Merged before\n // the authored tokens so an explicit token of the same name still wins.\n //\n // `logo` and `logoDark` are emitted into their own rule, so a brand\n // whose mark is dark-on-light can ship a light-on-dark variant instead\n // of disappearing against the dark card. Each mode carries the\n // mark-visibility flag alongside its image, which makes all three\n // combinations coherent:\n // logo only -> one image, inherited by dark mode\n // both -> a per-mode image\n // logoDark only -> the built-in mark in light, the operator's in dark\n const tokens = buildLogoTokens(manifest.logo, basePath);\n Object.assign(tokens, manifest.tokens);\n\n const tokensDark = buildLogoTokens(manifest.logoDark, basePath);\n Object.assign(tokensDark, manifest.tokensDark);\n\n if (Object.keys(tokens).length > 0) {\n rules.push(buildTokenRule(':root', tokens));\n }\n // After :root, so it wins inside the layer by source order and the\n // color-mode switcher keeps working.\n if (Object.keys(tokensDark).length > 0) {\n rules.push(buildTokenRule('.dark', tokensDark));\n }\n\n if (rules.length > 0) {\n parts.push(`<style>@layer ${THEME_CSS_LAYER_NAME}{${rules.join('')}}</style>`);\n }\n\n if (manifest.favicon) {\n parts.push(`<link rel=\"icon\" href=\"${escapeHtml(buildAssetURL(manifest.favicon, basePath))}\">`);\n }\n\n // Last, so the operator stylesheet wins over the token block above it.\n if (manifest.stylesheet) {\n parts.push(`<link rel=\"stylesheet\" href=\"${escapeHtml(buildAssetURL(manifest.stylesheet, basePath))}\">`);\n }\n\n // After the stylesheet, so a fragment can override everything the\n // manifest emitted. Passed through verbatim: it is operator-authored\n // markup, and a partial sanitizer would be worse than none because it\n // invites treating fragments as untrusted-safe. The controls are that\n // it is filesystem-only, off by default, and head-only.\n if (fragment) {\n parts.push(fragment);\n }\n\n return parts.join('');\n}\n"],"mappings":";;;;;AAeA,SAAgBI,WAAWC,OAAa;CACpC,OAAOA,MACFC,QAAQ,MAAM,OAAA,CAAA,CACdA,QAAQ,MAAM,MAAA,CAAA,CACdA,QAAQ,MAAM,MAAA,CAAA,CACdA,QAAQ,MAAM,QAAA;AACvB;;;;;;;GASA,SAASC,cAAcC,WAAmBC,UAAgB;CACtD,MAAMC,OAAOF,UAAUG,MAAM,GAAGX,4BAA4B,GAAGY,MAAM;CAErE,OAAO,GAAGH,SAAS,GAAGR,uBAAuB,GAAGS;AACpD;;;;;GAOA,SAASG,gBAAgBC,MAA0BL,UAAgB;CAC/D,MAAMM,SAAkC,CAAC;CACzC,IAAI,CAACD,MACD,OAAOC;CAGX,MAAMC,MAAMT,cAAcO,MAAML,QAAAA;CAChC,KAAK,MAAMQ,QAAQd,mBAAmB;EAClCY,OAAOE,KAAKC,SAAS,QAAQF,IAAI;EACjCD,OAAOE,KAAKE,kBAAkB;CAClC;CAEA,OAAOJ;AACX;AAEA,SAASK,eAAeC,UAAkBN,QAA8B;CAKpE,OAAO,GAAGM,SAAS,GAJEE,OAAOC,KAAKT,MAAAA,CAAAA,CAC5BU,KAAKf,SAAS,GAAGA,KAAK,GAAGK,OAAOL,OAAO,CAAA,CACvCgB,KAAK,GAEYJ,EAAa;AACvC;;;;;;;;GAUA,SAAgBK,eACZC,UACAnB,UACAoB,UAAiB;CAEjB,MAAMC,QAAmB,CAAA;CAEzB,MAAMC,QAAmB,CAAA;CAczB,MAAMhB,SAASF,gBAAgBe,SAASd,MAAML,QAAAA;CAC9Cc,OAAOS,OAAOjB,QAAQa,SAASb,MAAM;CAErC,MAAMkB,aAAapB,gBAAgBe,SAASM,UAAUzB,QAAAA;CACtDc,OAAOS,OAAOC,YAAYL,SAASK,UAAU;CAE7C,IAAIV,OAAOC,KAAKT,MAAAA,CAAAA,CAAQH,SAAS,GAC7BmB,MAAMI,KAAKf,eAAe,SAASL,MAAAA,CAAAA;CAIvC,IAAIQ,OAAOC,KAAKS,UAAAA,CAAAA,CAAYrB,SAAS,GACjCmB,MAAMI,KAAKf,eAAe,SAASa,UAAAA,CAAAA;CAGvC,IAAIF,MAAMnB,SAAS,GACfkB,MAAMK,KAAK,iBAAiBjC,qBAAqB,GAAG6B,MAAML,KAAK,EAAA,EAAI,UAAU;CAGjF,IAAIE,SAASQ,SACTN,MAAMK,KAAK,0BAA0B/B,WAAWG,cAAcqB,SAASQ,SAAS3B,QAAAA,CAAAA,EAAW,GAAG;CAIlG,IAAImB,SAASS,YACTP,MAAMK,KAAK,gCAAgC/B,WAAWG,cAAcqB,SAASS,YAAY5B,QAAAA,CAAAA,EAAW,GAAG;CAQ3G,IAAIoB,UACAC,MAAMK,KAAKN,QAAAA;CAGf,OAAOC,MAAMJ,KAAK,EAAA;AACtB"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../../src/adapters/http/ui/theme/contract/index.ts"],"names":[],"mappings":"AAOA,cAAc,gBAAgB,CAAC;AAC/B,cAAc,WAAW,CAAC;AAC1B,cAAc,eAAe,CAAC;AAC9B,cAAc,YAAY,CAAC;AAC3B,cAAc,YAAY,CAAC"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import "node:path";
|
|
2
|
+
import "node:url";
|
|
3
|
+
import.meta.url;
|
|
4
|
+
import { THEME_ASSETS_DIRECTORY_NAME, THEME_ASSET_CONTENT_TYPES, THEME_ASSET_EXTENSIONS, THEME_ASSET_MOUNT_PATH, THEME_CSS_LAYER_NAME, THEME_FRAGMENTS_DIRECTORY_NAME, THEME_HEAD_FRAGMENT_FILE_NAME, THEME_HEAD_FRAGMENT_MAX_LENGTH, THEME_IMAGE_EXTENSIONS, THEME_LOGO_TOKENS, THEME_MANIFEST_FILE_NAME, THEME_MANIFEST_VERSION, THEME_TOKEN_NAME_PATTERN, THEME_TOKEN_VALUE_FORBIDDEN_PATTERN, THEME_TOKEN_VALUE_MAX_LENGTH } from "./constants.mjs";
|
|
5
|
+
import { buildThemeHead, escapeHtml } from "./head.mjs";
|
|
6
|
+
import { themeAssetExtension } from "./utils.mjs";
|
|
7
|
+
import { ThemeManifestValidator, parseThemeManifest } from "./manifest.mjs";
|
|
8
|
+
export { THEME_ASSETS_DIRECTORY_NAME, THEME_ASSET_CONTENT_TYPES, THEME_ASSET_EXTENSIONS, THEME_ASSET_MOUNT_PATH, THEME_CSS_LAYER_NAME, THEME_FRAGMENTS_DIRECTORY_NAME, THEME_HEAD_FRAGMENT_FILE_NAME, THEME_HEAD_FRAGMENT_MAX_LENGTH, THEME_IMAGE_EXTENSIONS, THEME_LOGO_TOKENS, THEME_MANIFEST_FILE_NAME, THEME_MANIFEST_VERSION, THEME_TOKEN_NAME_PATTERN, THEME_TOKEN_VALUE_FORBIDDEN_PATTERN, THEME_TOKEN_VALUE_MAX_LENGTH, ThemeManifestValidator, buildThemeHead, escapeHtml, parseThemeManifest, themeAssetExtension };
|