@tempoxyz/id 0.0.0-pr-187.sha-eed04d3
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/README.md +81 -0
- package/dist/App.d.ts +20 -0
- package/dist/App.d.ts.map +1 -0
- package/dist/App.js +26 -0
- package/dist/App.js.map +1 -0
- package/dist/app/client/.assetsignore +2 -0
- package/dist/app/client/assets/BRLA-CZvVDNYr.png +0 -0
- package/dist/app/client/assets/CHFAU-DCedc4aH.png +0 -0
- package/dist/app/client/assets/DLUSD-BnRXm3EI.png +0 -0
- package/dist/app/client/assets/PRIME-CiFp2-3e.svg +14 -0
- package/dist/app/client/assets/Pilat-Bold-C1t1eIrF.woff2 +0 -0
- package/dist/app/client/assets/Pilat-Book-CbS8ofT8.woff2 +0 -0
- package/dist/app/client/assets/Pilat-Demi-CADSbPAt.woff2 +0 -0
- package/dist/app/client/assets/Pilat-Regular-Bx8vzE7q.woff2 +0 -0
- package/dist/app/client/assets/USD1-COVcO_PB.svg +30 -0
- package/dist/app/client/assets/YLDS-CRh8Zw0g.svg +3 -0
- package/dist/app/client/assets/ccip-Cq1mMiVl.js +1 -0
- package/dist/app/client/assets/frxUSD-n9pTpinR.svg +1 -0
- package/dist/app/client/assets/geist-mono-latin-wght-normal-XN7g48iV.woff2 +0 -0
- package/dist/app/client/assets/index-B7YJVP00.css +1 -0
- package/dist/app/client/assets/index-UXTxXCLk.js +55 -0
- package/dist/app/client/assets/pathUSD-BvaO6ooS.svg +25 -0
- package/dist/app/client/assets/reset-co-CHrff.css +1 -0
- package/dist/app/client/assets/wYLDS-CaCKDrO-.svg +10 -0
- package/dist/app/db/auth.d.ts +3207 -0
- package/dist/app/db/auth.d.ts.map +1 -0
- package/dist/app/db/auth.js +330 -0
- package/dist/app/db/auth.js.map +1 -0
- package/dist/app/db/schema.d.ts +932 -0
- package/dist/app/db/schema.d.ts.map +1 -0
- package/dist/app/db/schema.js +171 -0
- package/dist/app/db/schema.js.map +1 -0
- package/dist/app/server/.vite/manifest.json +489 -0
- package/dist/app/server/assets/BRLA-CZvVDNYr.png +0 -0
- package/dist/app/server/assets/CHFAU-DCedc4aH.png +0 -0
- package/dist/app/server/assets/DLUSD-BnRXm3EI.png +0 -0
- package/dist/app/server/assets/PRIME-CiFp2-3e.svg +14 -0
- package/dist/app/server/assets/Pilat-Bold-C1t1eIrF.woff2 +0 -0
- package/dist/app/server/assets/Pilat-Book-CbS8ofT8.woff2 +0 -0
- package/dist/app/server/assets/Pilat-Demi-CADSbPAt.woff2 +0 -0
- package/dist/app/server/assets/Pilat-Regular-Bx8vzE7q.woff2 +0 -0
- package/dist/app/server/assets/USD1-COVcO_PB.svg +30 -0
- package/dist/app/server/assets/YLDS-CRh8Zw0g.svg +3 -0
- package/dist/app/server/assets/_tanstack-start-manifest_v-DjQNeRZp.js +1 -0
- package/dist/app/server/assets/arktype-aI7TBD0R-D1R3Byo5.js +2 -0
- package/dist/app/server/assets/arktype-aI7TBD0R-D1R3Byo5.js.map +1 -0
- package/dist/app/server/assets/authorize-C95F-9E1-CbESJKGU.js +31 -0
- package/dist/app/server/assets/authorize-C95F-9E1-CbESJKGU.js.map +1 -0
- package/dist/app/server/assets/bun-sqlite-dialect-DoOVo4ja-CtyBkVMb.js +2 -0
- package/dist/app/server/assets/bun-sqlite-dialect-DoOVo4ja-CtyBkVMb.js.map +1 -0
- package/dist/app/server/assets/call-UQamaCKN.js +32 -0
- package/dist/app/server/assets/call-UQamaCKN.js.map +1 -0
- package/dist/app/server/assets/ccip-CbNKFO4n.js +2 -0
- package/dist/app/server/assets/ccip-CbNKFO4n.js.map +1 -0
- package/dist/app/server/assets/compiled-query-Ds2NVcFT.js +2 -0
- package/dist/app/server/assets/compiled-query-Ds2NVcFT.js.map +1 -0
- package/dist/app/server/assets/convert-BIC8n32x.js +2 -0
- package/dist/app/server/assets/convert-BIC8n32x.js.map +1 -0
- package/dist/app/server/assets/cookie-CS900nSP.css +1 -0
- package/dist/app/server/assets/cookie-Cce9CrIP.js +10 -0
- package/dist/app/server/assets/cookie-Cce9CrIP.js.map +1 -0
- package/dist/app/server/assets/core-B1HCXUmx.js +56 -0
- package/dist/app/server/assets/core-B1HCXUmx.js.map +1 -0
- package/dist/app/server/assets/d1-sqlite-dialect-m0f01-4z-Cv-csE1u.js +2 -0
- package/dist/app/server/assets/d1-sqlite-dialect-m0f01-4z-Cv-csE1u.js.map +1 -0
- package/dist/app/server/assets/default-u_dwuiYb-BJJ9PwCi.js +2 -0
- package/dist/app/server/assets/default-u_dwuiYb-BJJ9PwCi.js.map +1 -0
- package/dist/app/server/assets/dist-BxSwugSY.js +1 -0
- package/dist/app/server/assets/dist-CZGFhmQd.js +2 -0
- package/dist/app/server/assets/dist-CZGFhmQd.js.map +1 -0
- package/dist/app/server/assets/dist-Dg3PQqiW.js +15 -0
- package/dist/app/server/assets/dist-Dg3PQqiW.js.map +1 -0
- package/dist/app/server/assets/effect-QlVUlMFu-2tSPDT2b.js +2 -0
- package/dist/app/server/assets/effect-QlVUlMFu-2tSPDT2b.js.map +1 -0
- package/dist/app/server/assets/empty-plugin-adapters-BaGcmrjC.js +2 -0
- package/dist/app/server/assets/empty-plugin-adapters-BaGcmrjC.js.map +1 -0
- package/dist/app/server/assets/factory-ipHlJXZY.js +5 -0
- package/dist/app/server/assets/factory-ipHlJXZY.js.map +1 -0
- package/dist/app/server/assets/frxUSD-n9pTpinR.svg +1 -0
- package/dist/app/server/assets/geist-mono-latin-wght-normal-XN7g48iV.woff2 +0 -0
- package/dist/app/server/assets/get-id-field-B0x109VU.js +6 -0
- package/dist/app/server/assets/get-id-field-B0x109VU.js.map +1 -0
- package/dist/app/server/assets/index-CLddUTqr-xpSuLpBt.js +2 -0
- package/dist/app/server/assets/index-CLddUTqr-xpSuLpBt.js.map +1 -0
- package/dist/app/server/assets/index-DZEfthgZ-8Uq5s5Pt.js +2 -0
- package/dist/app/server/assets/index-DZEfthgZ-8Uq5s5Pt.js.map +1 -0
- package/dist/app/server/assets/kysely-adapter-MkHAI9Jk.js +1 -0
- package/dist/app/server/assets/node-sqlite-dialect-BowWLXvK.js +2 -0
- package/dist/app/server/assets/node-sqlite-dialect-BowWLXvK.js.map +1 -0
- package/dist/app/server/assets/pathUSD-BvaO6ooS.svg +25 -0
- package/dist/app/server/assets/reset-co-CHrff.css +1 -0
- package/dist/app/server/assets/rolldown-runtime-B0Z9INg1.js +1 -0
- package/dist/app/server/assets/router-CcbyBCI4.css +1 -0
- package/dist/app/server/assets/router-xjZtEeaI.js +7 -0
- package/dist/app/server/assets/router-xjZtEeaI.js.map +1 -0
- package/dist/app/server/assets/schema-check-Cf7QOZZD.js +9 -0
- package/dist/app/server/assets/schema-check-Cf7QOZZD.js.map +1 -0
- package/dist/app/server/assets/schemas-C2lCYmR5.js +2 -0
- package/dist/app/server/assets/schemas-C2lCYmR5.js.map +1 -0
- package/dist/app/server/assets/secp256k1-buM5g4AL.js +2 -0
- package/dist/app/server/assets/secp256k1-buM5g4AL.js.map +1 -0
- package/dist/app/server/assets/sqlite-adapter-C_LAV4e3.js +2 -0
- package/dist/app/server/assets/sqlite-adapter-C_LAV4e3.js.map +1 -0
- package/dist/app/server/assets/sqlite-introspector-DSCAP82F-Crx7Ny14.js +6 -0
- package/dist/app/server/assets/sqlite-introspector-DSCAP82F-Crx7Ny14.js.map +1 -0
- package/dist/app/server/assets/standard-json-Cg1N07hM.js +2 -0
- package/dist/app/server/assets/standard-json-Cg1N07hM.js.map +1 -0
- package/dist/app/server/assets/standard-json-DY77efq0.js +2 -0
- package/dist/app/server/assets/standard-json-DY77efq0.js.map +1 -0
- package/dist/app/server/assets/standard-json-ig2t0wRt.js +2 -0
- package/dist/app/server/assets/standard-json-ig2t0wRt.js.map +1 -0
- package/dist/app/server/assets/standard-json-t-LNckA6.js +2 -0
- package/dist/app/server/assets/standard-json-t-LNckA6.js.map +1 -0
- package/dist/app/server/assets/standard-openapi-CONmVRl8.js +2 -0
- package/dist/app/server/assets/standard-openapi-CONmVRl8.js.map +1 -0
- package/dist/app/server/assets/start-C63VetBp.js +2 -0
- package/dist/app/server/assets/start-C63VetBp.js.map +1 -0
- package/dist/app/server/assets/sury-CWZTCd75-xt1mWc9f.js +2 -0
- package/dist/app/server/assets/sury-CWZTCd75-xt1mWc9f.js.map +1 -0
- package/dist/app/server/assets/typebox-Dei93FPO-D_lCVdAz.js +2 -0
- package/dist/app/server/assets/typebox-Dei93FPO-D_lCVdAz.js.map +1 -0
- package/dist/app/server/assets/utils-C4ZXZIZW.js +2 -0
- package/dist/app/server/assets/utils-C4ZXZIZW.js.map +1 -0
- package/dist/app/server/assets/valibot--1zFm7rT-NSoY2xTp.js +2 -0
- package/dist/app/server/assets/valibot--1zFm7rT-NSoY2xTp.js.map +1 -0
- package/dist/app/server/assets/valibot-D_HTw1Gn-CJwWeOUE.js +2 -0
- package/dist/app/server/assets/valibot-D_HTw1Gn-CJwWeOUE.js.map +1 -0
- package/dist/app/server/assets/wYLDS-CaCKDrO-.svg +10 -0
- package/dist/app/server/assets/zod-Bwrt9trS-CV38yPnQ.js +2 -0
- package/dist/app/server/assets/zod-Bwrt9trS-CV38yPnQ.js.map +1 -0
- package/dist/app/server/assets/zod-DSgpEGAE-BvlnBE2L.js +2 -0
- package/dist/app/server/assets/zod-DSgpEGAE-BvlnBE2L.js.map +1 -0
- package/dist/app/server/index.js +574 -0
- package/dist/app/server/index.js.map +1 -0
- package/dist/app/server/wrangler.json +1 -0
- package/dist/cli/Admin.d.ts +38 -0
- package/dist/cli/Admin.d.ts.map +1 -0
- package/dist/cli/Admin.js +62 -0
- package/dist/cli/Admin.js.map +1 -0
- package/dist/cli/Apps.d.ts +9 -0
- package/dist/cli/Apps.d.ts.map +1 -0
- package/dist/cli/Apps.js +36 -0
- package/dist/cli/Apps.js.map +1 -0
- package/dist/cli/Cli.d.ts +14 -0
- package/dist/cli/Cli.d.ts.map +1 -0
- package/dist/cli/Cli.js +27 -0
- package/dist/cli/Cli.js.map +1 -0
- package/dist/cli/Project.d.ts +20 -0
- package/dist/cli/Project.d.ts.map +1 -0
- package/dist/cli/Project.js +88 -0
- package/dist/cli/Project.js.map +1 -0
- package/dist/cli/Realms.d.ts +24 -0
- package/dist/cli/Realms.d.ts.map +1 -0
- package/dist/cli/Realms.js +49 -0
- package/dist/cli/Realms.js.map +1 -0
- package/dist/cli/Session.d.ts +85 -0
- package/dist/cli/Session.d.ts.map +1 -0
- package/dist/cli/Session.js +178 -0
- package/dist/cli/Session.js.map +1 -0
- package/dist/cli/User.d.ts +29 -0
- package/dist/cli/User.d.ts.map +1 -0
- package/dist/cli/User.js +39 -0
- package/dist/cli/User.js.map +1 -0
- package/dist/cli/V1.d.ts +35 -0
- package/dist/cli/V1.d.ts.map +1 -0
- package/dist/cli/V1.js +41 -0
- package/dist/cli/V1.js.map +1 -0
- package/dist/cli/bin.d.ts +3 -0
- package/dist/cli/bin.d.ts.map +1 -0
- package/dist/cli/bin.js +46 -0
- package/dist/cli/bin.js.map +1 -0
- package/dist/cli/commands/admin/apps/create.d.ts +23 -0
- package/dist/cli/commands/admin/apps/create.d.ts.map +1 -0
- package/dist/cli/commands/admin/apps/create.js +89 -0
- package/dist/cli/commands/admin/apps/create.js.map +1 -0
- package/dist/cli/commands/admin/apps/delete.d.ts +14 -0
- package/dist/cli/commands/admin/apps/delete.d.ts.map +1 -0
- package/dist/cli/commands/admin/apps/delete.js +41 -0
- package/dist/cli/commands/admin/apps/delete.js.map +1 -0
- package/dist/cli/commands/admin/apps/index.d.ts +5 -0
- package/dist/cli/commands/admin/apps/index.d.ts.map +1 -0
- package/dist/cli/commands/admin/apps/index.js +14 -0
- package/dist/cli/commands/admin/apps/index.js.map +1 -0
- package/dist/cli/commands/admin/apps/list.d.ts +9 -0
- package/dist/cli/commands/admin/apps/list.d.ts.map +1 -0
- package/dist/cli/commands/admin/apps/list.js +26 -0
- package/dist/cli/commands/admin/apps/list.js.map +1 -0
- package/dist/cli/commands/admin/apps/rotate-secret.d.ts +16 -0
- package/dist/cli/commands/admin/apps/rotate-secret.d.ts.map +1 -0
- package/dist/cli/commands/admin/apps/rotate-secret.js +47 -0
- package/dist/cli/commands/admin/apps/rotate-secret.js.map +1 -0
- package/dist/cli/commands/admin/apps/update.d.ts +20 -0
- package/dist/cli/commands/admin/apps/update.d.ts.map +1 -0
- package/dist/cli/commands/admin/apps/update.js +76 -0
- package/dist/cli/commands/admin/apps/update.js.map +1 -0
- package/dist/cli/commands/admin/index.d.ts +5 -0
- package/dist/cli/commands/admin/index.d.ts.map +1 -0
- package/dist/cli/commands/admin/index.js +13 -0
- package/dist/cli/commands/admin/index.js.map +1 -0
- package/dist/cli/commands/admin/migrate.d.ts +9 -0
- package/dist/cli/commands/admin/migrate.d.ts.map +1 -0
- package/dist/cli/commands/admin/migrate.js +17 -0
- package/dist/cli/commands/admin/migrate.js.map +1 -0
- package/dist/cli/commands/admin/realms/add.d.ts +12 -0
- package/dist/cli/commands/admin/realms/add.d.ts.map +1 -0
- package/dist/cli/commands/admin/realms/add.js +42 -0
- package/dist/cli/commands/admin/realms/add.js.map +1 -0
- package/dist/cli/commands/admin/realms/index.d.ts +5 -0
- package/dist/cli/commands/admin/realms/index.d.ts.map +1 -0
- package/dist/cli/commands/admin/realms/index.js +13 -0
- package/dist/cli/commands/admin/realms/index.js.map +1 -0
- package/dist/cli/commands/admin/realms/list.d.ts +13 -0
- package/dist/cli/commands/admin/realms/list.d.ts.map +1 -0
- package/dist/cli/commands/admin/realms/list.js +36 -0
- package/dist/cli/commands/admin/realms/list.js.map +1 -0
- package/dist/cli/commands/admin/realms/passkeys/index.d.ts +5 -0
- package/dist/cli/commands/admin/realms/passkeys/index.d.ts.map +1 -0
- package/dist/cli/commands/admin/realms/passkeys/index.js +13 -0
- package/dist/cli/commands/admin/realms/passkeys/index.js.map +1 -0
- package/dist/cli/commands/admin/realms/passkeys/set.d.ts +16 -0
- package/dist/cli/commands/admin/realms/passkeys/set.d.ts.map +1 -0
- package/dist/cli/commands/admin/realms/passkeys/set.js +46 -0
- package/dist/cli/commands/admin/realms/passkeys/set.js.map +1 -0
- package/dist/cli/commands/admin/realms/privy/index.d.ts +5 -0
- package/dist/cli/commands/admin/realms/privy/index.d.ts.map +1 -0
- package/dist/cli/commands/admin/realms/privy/index.js +13 -0
- package/dist/cli/commands/admin/realms/privy/index.js.map +1 -0
- package/dist/cli/commands/admin/realms/privy/set.d.ts +18 -0
- package/dist/cli/commands/admin/realms/privy/set.d.ts.map +1 -0
- package/dist/cli/commands/admin/realms/privy/set.js +66 -0
- package/dist/cli/commands/admin/realms/privy/set.js.map +1 -0
- package/dist/cli/commands/admin/realms/remove.d.ts +11 -0
- package/dist/cli/commands/admin/realms/remove.d.ts.map +1 -0
- package/dist/cli/commands/admin/realms/remove.js +35 -0
- package/dist/cli/commands/admin/realms/remove.js.map +1 -0
- package/dist/cli/commands/admin/realms/secp256k1/disable.d.ts +15 -0
- package/dist/cli/commands/admin/realms/secp256k1/disable.d.ts.map +1 -0
- package/dist/cli/commands/admin/realms/secp256k1/disable.js +42 -0
- package/dist/cli/commands/admin/realms/secp256k1/disable.js.map +1 -0
- package/dist/cli/commands/admin/realms/secp256k1/enable.d.ts +15 -0
- package/dist/cli/commands/admin/realms/secp256k1/enable.d.ts.map +1 -0
- package/dist/cli/commands/admin/realms/secp256k1/enable.js +42 -0
- package/dist/cli/commands/admin/realms/secp256k1/enable.js.map +1 -0
- package/dist/cli/commands/admin/realms/secp256k1/index.d.ts +9 -0
- package/dist/cli/commands/admin/realms/secp256k1/index.d.ts.map +1 -0
- package/dist/cli/commands/admin/realms/secp256k1/index.js +17 -0
- package/dist/cli/commands/admin/realms/secp256k1/index.js.map +1 -0
- package/dist/cli/commands/admin/realms/set.d.ts +16 -0
- package/dist/cli/commands/admin/realms/set.d.ts.map +1 -0
- package/dist/cli/commands/admin/realms/set.js +46 -0
- package/dist/cli/commands/admin/realms/set.js.map +1 -0
- package/dist/cli/commands/admin/rotate-key.d.ts +15 -0
- package/dist/cli/commands/admin/rotate-key.d.ts.map +1 -0
- package/dist/cli/commands/admin/rotate-key.js +46 -0
- package/dist/cli/commands/admin/rotate-key.js.map +1 -0
- package/dist/cli/commands/init.d.ts +11 -0
- package/dist/cli/commands/init.d.ts.map +1 -0
- package/dist/cli/commands/init.js +34 -0
- package/dist/cli/commands/init.js.map +1 -0
- package/dist/cli/commands/login.d.ts +12 -0
- package/dist/cli/commands/login.d.ts.map +1 -0
- package/dist/cli/commands/login.js +29 -0
- package/dist/cli/commands/login.js.map +1 -0
- package/dist/cli/commands/logout.d.ts +8 -0
- package/dist/cli/commands/logout.d.ts.map +1 -0
- package/dist/cli/commands/logout.js +19 -0
- package/dist/cli/commands/logout.js.map +1 -0
- package/dist/cli/commands/whoami.d.ts +12 -0
- package/dist/cli/commands/whoami.d.ts.map +1 -0
- package/dist/cli/commands/whoami.js +24 -0
- package/dist/cli/commands/whoami.js.map +1 -0
- package/dist/client/Actions.d.ts +101 -0
- package/dist/client/Actions.d.ts.map +1 -0
- package/dist/client/Actions.js +90 -0
- package/dist/client/Actions.js.map +1 -0
- package/dist/client/Auth.d.ts +161 -0
- package/dist/client/Auth.d.ts.map +1 -0
- package/dist/client/Auth.js +113 -0
- package/dist/client/Auth.js.map +1 -0
- package/dist/client/Authorization.d.ts +29 -0
- package/dist/client/Authorization.d.ts.map +1 -0
- package/dist/client/Authorization.js +12 -0
- package/dist/client/Authorization.js.map +1 -0
- package/dist/client/Decorator.d.ts +170 -0
- package/dist/client/Decorator.d.ts.map +1 -0
- package/dist/client/Decorator.js +227 -0
- package/dist/client/Decorator.js.map +1 -0
- package/dist/client/Key.d.ts +85 -0
- package/dist/client/Key.d.ts.map +1 -0
- package/dist/client/Key.js +83 -0
- package/dist/client/Key.js.map +1 -0
- package/dist/client/Pending.d.ts +39 -0
- package/dist/client/Pending.d.ts.map +1 -0
- package/dist/client/Pending.js +12 -0
- package/dist/client/Pending.js.map +1 -0
- package/dist/client/Permissions.d.ts +34 -0
- package/dist/client/Permissions.d.ts.map +1 -0
- package/dist/client/Permissions.js +16 -0
- package/dist/client/Permissions.js.map +1 -0
- package/dist/client/Provider.d.ts +16 -0
- package/dist/client/Provider.d.ts.map +1 -0
- package/dist/client/Provider.js +12 -0
- package/dist/client/Provider.js.map +1 -0
- package/dist/client/Step.d.ts +21 -0
- package/dist/client/Step.d.ts.map +1 -0
- package/dist/client/Step.js +16 -0
- package/dist/client/Step.js.map +1 -0
- package/dist/client/Storage.d.ts +27 -0
- package/dist/client/Storage.d.ts.map +1 -0
- package/dist/client/Storage.js +16 -0
- package/dist/client/Storage.js.map +1 -0
- package/dist/client/TempoAccount.d.ts +40 -0
- package/dist/client/TempoAccount.d.ts.map +1 -0
- package/dist/client/TempoAccount.js +16 -0
- package/dist/client/TempoAccount.js.map +1 -0
- package/dist/client/Tokens.d.ts +25 -0
- package/dist/client/Tokens.d.ts.map +1 -0
- package/dist/client/Tokens.js +12 -0
- package/dist/client/Tokens.js.map +1 -0
- package/dist/client/User.d.ts +21 -0
- package/dist/client/User.d.ts.map +1 -0
- package/dist/client/User.js +12 -0
- package/dist/client/User.js.map +1 -0
- package/dist/client/actions/account.d.ts +25 -0
- package/dist/client/actions/account.d.ts.map +1 -0
- package/dist/client/actions/account.js +34 -0
- package/dist/client/actions/account.js.map +1 -0
- package/dist/client/actions/device.d.ts +53 -0
- package/dist/client/actions/device.d.ts.map +1 -0
- package/dist/client/actions/device.js +79 -0
- package/dist/client/actions/device.js.map +1 -0
- package/dist/client/actions/email.d.ts +84 -0
- package/dist/client/actions/email.d.ts.map +1 -0
- package/dist/client/actions/email.js +63 -0
- package/dist/client/actions/email.js.map +1 -0
- package/dist/client/actions/oauth.d.ts +115 -0
- package/dist/client/actions/oauth.d.ts.map +1 -0
- package/dist/client/actions/oauth.js +105 -0
- package/dist/client/actions/oauth.js.map +1 -0
- package/dist/client/actions/passkey.d.ts +88 -0
- package/dist/client/actions/passkey.d.ts.map +1 -0
- package/dist/client/actions/passkey.js +60 -0
- package/dist/client/actions/passkey.js.map +1 -0
- package/dist/client/actions/provider.d.ts +49 -0
- package/dist/client/actions/provider.d.ts.map +1 -0
- package/dist/client/actions/provider.js +34 -0
- package/dist/client/actions/provider.js.map +1 -0
- package/dist/client/actions/realm.d.ts +24 -0
- package/dist/client/actions/realm.d.ts.map +1 -0
- package/dist/client/actions/realm.js +15 -0
- package/dist/client/actions/realm.js.map +1 -0
- package/dist/client/actions/redirect.d.ts +153 -0
- package/dist/client/actions/redirect.d.ts.map +1 -0
- package/dist/client/actions/redirect.js +236 -0
- package/dist/client/actions/redirect.js.map +1 -0
- package/dist/client/internal/accessKey.d.ts +21 -0
- package/dist/client/internal/accessKey.d.ts.map +1 -0
- package/dist/client/internal/accessKey.js +38 -0
- package/dist/client/internal/accessKey.js.map +1 -0
- package/dist/client/internal/account.d.ts +14 -0
- package/dist/client/internal/account.d.ts.map +1 -0
- package/dist/client/internal/account.js +3 -0
- package/dist/client/internal/account.js.map +1 -0
- package/dist/client/internal/api.d.ts +106 -0
- package/dist/client/internal/api.d.ts.map +1 -0
- package/dist/client/internal/api.js +129 -0
- package/dist/client/internal/api.js.map +1 -0
- package/dist/client/internal/headless.d.ts +33 -0
- package/dist/client/internal/headless.d.ts.map +1 -0
- package/dist/client/internal/headless.js +46 -0
- package/dist/client/internal/headless.js.map +1 -0
- package/dist/client/internal/indexedDb.d.ts +9 -0
- package/dist/client/internal/indexedDb.d.ts.map +1 -0
- package/dist/client/internal/indexedDb.js +32 -0
- package/dist/client/internal/indexedDb.js.map +1 -0
- package/dist/client/internal/request.d.ts +58 -0
- package/dist/client/internal/request.d.ts.map +1 -0
- package/dist/client/internal/request.js +45 -0
- package/dist/client/internal/request.js.map +1 -0
- package/dist/client/internal/store.d.ts +12 -0
- package/dist/client/internal/store.d.ts.map +1 -0
- package/dist/client/internal/store.js +15 -0
- package/dist/client/internal/store.js.map +1 -0
- package/dist/client.d.ts +20 -0
- package/dist/client.d.ts.map +1 -0
- package/dist/client.js +20 -0
- package/dist/client.js.map +1 -0
- package/dist/index.d.ts +7 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +7 -0
- package/dist/index.js.map +1 -0
- package/dist/internal/Apps.d.ts +3051 -0
- package/dist/internal/Apps.d.ts.map +1 -0
- package/dist/internal/Apps.js +472 -0
- package/dist/internal/Apps.js.map +1 -0
- package/dist/internal/Auth.d.ts +4058 -0
- package/dist/internal/Auth.d.ts.map +1 -0
- package/dist/internal/Auth.js +137 -0
- package/dist/internal/Auth.js.map +1 -0
- package/dist/internal/Authorize.d.ts +532 -0
- package/dist/internal/Authorize.d.ts.map +1 -0
- package/dist/internal/Authorize.js +326 -0
- package/dist/internal/Authorize.js.map +1 -0
- package/dist/internal/Device.d.ts +371 -0
- package/dist/internal/Device.d.ts.map +1 -0
- package/dist/internal/Device.js +271 -0
- package/dist/internal/Device.js.map +1 -0
- package/dist/internal/Env.d.ts +57 -0
- package/dist/internal/Env.d.ts.map +1 -0
- package/dist/internal/Env.js +2 -0
- package/dist/internal/Env.js.map +1 -0
- package/dist/internal/ErrorResponse.d.ts +609 -0
- package/dist/internal/ErrorResponse.d.ts.map +1 -0
- package/dist/internal/ErrorResponse.js +679 -0
- package/dist/internal/ErrorResponse.js.map +1 -0
- package/dist/internal/Id.d.ts +10 -0
- package/dist/internal/Id.d.ts.map +1 -0
- package/dist/internal/Id.js +34 -0
- package/dist/internal/Id.js.map +1 -0
- package/dist/internal/KeyAuthorization.d.ts +1456 -0
- package/dist/internal/KeyAuthorization.d.ts.map +1 -0
- package/dist/internal/KeyAuthorization.js +1030 -0
- package/dist/internal/KeyAuthorization.js.map +1 -0
- package/dist/internal/Limits.d.ts +65 -0
- package/dist/internal/Limits.d.ts.map +1 -0
- package/dist/internal/Limits.js +35 -0
- package/dist/internal/Limits.js.map +1 -0
- package/dist/internal/Log.d.ts +49 -0
- package/dist/internal/Log.d.ts.map +1 -0
- package/dist/internal/Log.js +101 -0
- package/dist/internal/Log.js.map +1 -0
- package/dist/internal/LogLine.d.ts +33 -0
- package/dist/internal/LogLine.d.ts.map +1 -0
- package/dist/internal/LogLine.js +56 -0
- package/dist/internal/LogLine.js.map +1 -0
- package/dist/internal/Migrations.d.ts +19 -0
- package/dist/internal/Migrations.d.ts.map +1 -0
- package/dist/internal/Migrations.js +57 -0
- package/dist/internal/Migrations.js.map +1 -0
- package/dist/internal/Owner.d.ts +146 -0
- package/dist/internal/Owner.d.ts.map +1 -0
- package/dist/internal/Owner.js +65 -0
- package/dist/internal/Owner.js.map +1 -0
- package/dist/internal/Passkey.d.ts +528 -0
- package/dist/internal/Passkey.d.ts.map +1 -0
- package/dist/internal/Passkey.js +658 -0
- package/dist/internal/Passkey.js.map +1 -0
- package/dist/internal/PendingKey.d.ts +49 -0
- package/dist/internal/PendingKey.d.ts.map +1 -0
- package/dist/internal/PendingKey.js +58 -0
- package/dist/internal/PendingKey.js.map +1 -0
- package/dist/internal/Privy.d.ts +105 -0
- package/dist/internal/Privy.d.ts.map +1 -0
- package/dist/internal/Privy.js +224 -0
- package/dist/internal/Privy.js.map +1 -0
- package/dist/internal/RateLimit.d.ts +190 -0
- package/dist/internal/RateLimit.d.ts.map +1 -0
- package/dist/internal/RateLimit.js +148 -0
- package/dist/internal/RateLimit.js.map +1 -0
- package/dist/internal/Realm.d.ts +281 -0
- package/dist/internal/Realm.d.ts.map +1 -0
- package/dist/internal/Realm.js +477 -0
- package/dist/internal/Realm.js.map +1 -0
- package/dist/internal/RequestId.d.ts +16 -0
- package/dist/internal/RequestId.d.ts.map +1 -0
- package/dist/internal/RequestId.js +78 -0
- package/dist/internal/RequestId.js.map +1 -0
- package/dist/internal/SigningKey.d.ts +115 -0
- package/dist/internal/SigningKey.d.ts.map +1 -0
- package/dist/internal/SigningKey.js +197 -0
- package/dist/internal/SigningKey.js.map +1 -0
- package/dist/internal/TestInbox.d.ts +42 -0
- package/dist/internal/TestInbox.d.ts.map +1 -0
- package/dist/internal/TestInbox.js +20 -0
- package/dist/internal/TestInbox.js.map +1 -0
- package/dist/internal/Timing.d.ts +51 -0
- package/dist/internal/Timing.d.ts.map +1 -0
- package/dist/internal/Timing.js +103 -0
- package/dist/internal/Timing.js.map +1 -0
- package/dist/internal/Validation.d.ts +52 -0
- package/dist/internal/Validation.d.ts.map +1 -0
- package/dist/internal/Validation.js +22 -0
- package/dist/internal/Validation.js.map +1 -0
- package/dist/internal/Wallet.d.ts +37 -0
- package/dist/internal/Wallet.d.ts.map +1 -0
- package/dist/internal/Wallet.js +43 -0
- package/dist/internal/Wallet.js.map +1 -0
- package/dist/worker.d.ts +12 -0
- package/dist/worker.d.ts.map +1 -0
- package/dist/worker.js +12 -0
- package/dist/worker.js.map +1 -0
- package/package.json +82 -0
- package/src/Api.ts +151 -0
- package/src/App.ts +56 -0
- package/src/api/account.ts +311 -0
- package/src/api/authenticate.ts +1290 -0
- package/src/api/authorize.ts +1030 -0
- package/src/api/device.ts +874 -0
- package/src/api/health.ts +72 -0
- package/src/api/lib/AccountStep.ts +335 -0
- package/src/api/lib/Auth.ts +134 -0
- package/src/api/lib/Consent.ts +339 -0
- package/src/api/lib/Cors.ts +107 -0
- package/src/api/lib/Database.ts +10 -0
- package/src/api/lib/DeviceRequest.ts +265 -0
- package/src/api/lib/FirstAccount.ts +90 -0
- package/src/api/lib/KeySigner.ts +393 -0
- package/src/api/lib/PasskeyLink.ts +162 -0
- package/src/api/lib/Session.ts +34 -0
- package/src/api/lib/SignInConsent.ts +316 -0
- package/src/api/oauth.ts +1282 -0
- package/src/api/provider.ts +441 -0
- package/src/app/components/Button.tsx +128 -0
- package/src/app/components/CodeInput.tsx +186 -0
- package/src/app/components/ErrorMessage.tsx +66 -0
- package/src/app/components/Grant.tsx +323 -0
- package/src/app/components/Input.tsx +48 -0
- package/src/app/components/Tooltip.tsx +45 -0
- package/src/app/components/icons/BRLA.png +0 -0
- package/src/app/components/icons/BRZ.svg +1 -0
- package/src/app/components/icons/CHFAU.png +0 -0
- package/src/app/components/icons/DLUSD.png +0 -0
- package/src/app/components/icons/EURAU.svg +1 -0
- package/src/app/components/icons/EURC.e.svg +1 -0
- package/src/app/components/icons/GBPA.svg +4 -0
- package/src/app/components/icons/GUSD.svg +1 -0
- package/src/app/components/icons/MACH.svg +4 -0
- package/src/app/components/icons/OUSD.svg +5 -0
- package/src/app/components/icons/PRIME.svg +14 -0
- package/src/app/components/icons/SBC.svg +1 -0
- package/src/app/components/icons/SEKAU.svg +5 -0
- package/src/app/components/icons/USD1.svg +30 -0
- package/src/app/components/icons/USDB.svg +11 -0
- package/src/app/components/icons/USDC.e.svg +1 -0
- package/src/app/components/icons/USDT0.svg +1 -0
- package/src/app/components/icons/USDY.svg +16 -0
- package/src/app/components/icons/USDe.svg +1 -0
- package/src/app/components/icons/YLDS.svg +3 -0
- package/src/app/components/icons/alphaUSD.svg +1 -0
- package/src/app/components/icons/betaUSD.svg +1 -0
- package/src/app/components/icons/cUSD.svg +1 -0
- package/src/app/components/icons/cbBTC.svg +1 -0
- package/src/app/components/icons/frxUSD.svg +1 -0
- package/src/app/components/icons/goUSD.svg +5 -0
- package/src/app/components/icons/iUSD.svg +1 -0
- package/src/app/components/icons/pathUSD.svg +25 -0
- package/src/app/components/icons/rUSD.svg +1 -0
- package/src/app/components/icons/reUSD.svg +1 -0
- package/src/app/components/icons/sUSDe.svg +1 -0
- package/src/app/components/icons/siUSD.svg +1 -0
- package/src/app/components/icons/stcUSD.svg +1 -0
- package/src/app/components/icons/syrupUSDC.svg +5 -0
- package/src/app/components/icons/thetaUSD.svg +1 -0
- package/src/app/components/icons/wYLDS.svg +10 -0
- package/src/app/components/icons/wsrUSD.svg +1 -0
- package/src/app/components/logos/OUSD.dark.svg +17 -0
- package/src/app/components/logos/OUSD.light.svg +17 -0
- package/src/app/crons/cleanup.ts +42 -0
- package/src/app/db/auth.ts +416 -0
- package/src/app/db/migrations/0000_better_auth.sql +53 -0
- package/src/app/db/migrations/0001_oauth_provider.sql +162 -0
- package/src/app/db/migrations/0002_device_code.sql +17 -0
- package/src/app/db/migrations/0003_realms.sql +27 -0
- package/src/app/db/migrations/0004_default_realm.sql +2 -0
- package/src/app/db/migrations/0005_passkeys.sql +30 -0
- package/src/app/db/migrations/0006_first_accounts.sql +9 -0
- package/src/app/db/migrations/0007_pending_keys.sql +13 -0
- package/src/app/db/migrations/0008_secp256k1_owners.sql +18 -0
- package/src/app/db/migrations/0009_device_requests.sql +8 -0
- package/src/app/db/migrations/0010_device_keys.sql +4 -0
- package/src/app/db/migrations/meta/0000_snapshot.json +362 -0
- package/src/app/db/migrations/meta/0001_snapshot.json +1487 -0
- package/src/app/db/migrations/meta/0002_snapshot.json +1603 -0
- package/src/app/db/migrations/meta/0003_snapshot.json +1760 -0
- package/src/app/db/migrations/meta/0004_snapshot.json +1760 -0
- package/src/app/db/migrations/meta/0005_snapshot.json +1911 -0
- package/src/app/db/migrations/meta/0006_snapshot.json +1967 -0
- package/src/app/db/migrations/meta/0007_snapshot.json +2047 -0
- package/src/app/db/migrations/meta/0008_snapshot.json +2157 -0
- package/src/app/db/migrations/meta/0009_snapshot.json +2207 -0
- package/src/app/db/migrations/meta/0010_snapshot.json +2231 -0
- package/src/app/db/migrations/meta/_journal.json +83 -0
- package/src/app/db/schema.ts +218 -0
- package/src/app/env.ts +49 -0
- package/src/app/lib/Client.ts +82 -0
- package/src/app/lib/Loader.ts +24 -0
- package/src/app/package.json +8 -0
- package/src/app/routeTree.gen.ts +198 -0
- package/src/app/router.tsx +48 -0
- package/src/app/routes/[_].flows.tsx +3001 -0
- package/src/app/routes/__root.tsx +91 -0
- package/src/app/routes/authorize.tsx +197 -0
- package/src/app/routes/choose-account.tsx +111 -0
- package/src/app/routes/deposit.tsx +105 -0
- package/src/app/routes/device.tsx +227 -0
- package/src/app/routes/index.tsx +115 -0
- package/src/app/routes/login.tsx +506 -0
- package/src/app/screens/Account.tsx +347 -0
- package/src/app/screens/Approval.tsx +276 -0
- package/src/app/screens/ChooseAccount.tsx +240 -0
- package/src/app/screens/Deposit.tsx +762 -0
- package/src/app/screens/DeviceApproval.tsx +480 -0
- package/src/app/screens/SignIn.tsx +362 -0
- package/src/app/screens/chains/base.svg +3 -0
- package/src/app/screens/chains/ethereum.svg +11 -0
- package/src/app/screens/chains/solana.svg +4 -0
- package/src/app/screens/chains/tempo.svg +4 -0
- package/src/app/server.ts +204 -0
- package/src/app/vite.config.ts +95 -0
- package/src/app/void.config.ts +29 -0
- package/src/app/zyzz.config.ts +274 -0
- package/src/cli/Admin.ts +73 -0
- package/src/cli/Apps.ts +29 -0
- package/src/cli/Cli.ts +42 -0
- package/src/cli/Project.ts +117 -0
- package/src/cli/Realms.ts +50 -0
- package/src/cli/Session.ts +239 -0
- package/src/cli/User.ts +45 -0
- package/src/cli/V1.ts +57 -0
- package/src/cli/bin.ts +44 -0
- package/src/cli/commands/admin/apps/create.ts +101 -0
- package/src/cli/commands/admin/apps/delete.ts +38 -0
- package/src/cli/commands/admin/apps/index.ts +15 -0
- package/src/cli/commands/admin/apps/list.ts +25 -0
- package/src/cli/commands/admin/apps/rotate-secret.ts +47 -0
- package/src/cli/commands/admin/apps/update.ts +86 -0
- package/src/cli/commands/admin/index.ts +14 -0
- package/src/cli/commands/admin/migrate.ts +16 -0
- package/src/cli/commands/admin/realms/add.ts +40 -0
- package/src/cli/commands/admin/realms/index.ts +14 -0
- package/src/cli/commands/admin/realms/list.ts +38 -0
- package/src/cli/commands/admin/realms/passkeys/index.ts +15 -0
- package/src/cli/commands/admin/realms/passkeys/set.ts +44 -0
- package/src/cli/commands/admin/realms/privy/index.ts +14 -0
- package/src/cli/commands/admin/realms/privy/set.ts +69 -0
- package/src/cli/commands/admin/realms/remove.ts +33 -0
- package/src/cli/commands/admin/realms/secp256k1/disable.ts +40 -0
- package/src/cli/commands/admin/realms/secp256k1/enable.ts +40 -0
- package/src/cli/commands/admin/realms/secp256k1/index.ts +19 -0
- package/src/cli/commands/admin/realms/set.ts +46 -0
- package/src/cli/commands/admin/rotate-key.ts +47 -0
- package/src/cli/commands/init.ts +42 -0
- package/src/cli/commands/login.ts +32 -0
- package/src/cli/commands/logout.ts +19 -0
- package/src/cli/commands/whoami.ts +23 -0
- package/src/client/Actions.ts +168 -0
- package/src/client/Auth.ts +285 -0
- package/src/client/Authorization.ts +34 -0
- package/src/client/Decorator.ts +410 -0
- package/src/client/Key.ts +140 -0
- package/src/client/Pending.ts +46 -0
- package/src/client/Permissions.ts +39 -0
- package/src/client/Provider.ts +18 -0
- package/src/client/Step.ts +24 -0
- package/src/client/Storage.ts +29 -0
- package/src/client/TempoAccount.ts +42 -0
- package/src/client/Tokens.ts +27 -0
- package/src/client/User.ts +23 -0
- package/src/client/actions/account.ts +57 -0
- package/src/client/actions/device.ts +151 -0
- package/src/client/actions/email.ts +141 -0
- package/src/client/actions/oauth.ts +182 -0
- package/src/client/actions/passkey.ts +141 -0
- package/src/client/actions/provider.ts +70 -0
- package/src/client/actions/realm.ts +36 -0
- package/src/client/actions/redirect.ts +408 -0
- package/src/client/internal/accessKey.ts +54 -0
- package/src/client/internal/account.ts +15 -0
- package/src/client/internal/api.ts +224 -0
- package/src/client/internal/headless.ts +77 -0
- package/src/client/internal/indexedDb.ts +44 -0
- package/src/client/internal/request.ts +71 -0
- package/src/client/internal/store.ts +20 -0
- package/src/client.ts +19 -0
- package/src/index.ts +6 -0
- package/src/internal/Apps.ts +718 -0
- package/src/internal/Auth.ts +203 -0
- package/src/internal/Authorize.ts +424 -0
- package/src/internal/Balance.ts +168 -0
- package/src/internal/BodyLimit.ts +36 -0
- package/src/internal/Chain.ts +16 -0
- package/src/internal/Device.ts +469 -0
- package/src/internal/Env.ts +58 -0
- package/src/internal/ErrorResponse.ts +854 -0
- package/src/internal/Id.ts +41 -0
- package/src/internal/KeyAuthorization.ts +1339 -0
- package/src/internal/Limits.ts +39 -0
- package/src/internal/Log.ts +178 -0
- package/src/internal/LogLine.ts +87 -0
- package/src/internal/Logout.ts +336 -0
- package/src/internal/Migrations.ts +86 -0
- package/src/internal/OpenApi.ts +300 -0
- package/src/internal/Owner.ts +211 -0
- package/src/internal/Passkey.ts +1052 -0
- package/src/internal/PendingKey.ts +104 -0
- package/src/internal/Privy.ts +402 -0
- package/src/internal/Provider.ts +125 -0
- package/src/internal/RateLimit.ts +259 -0
- package/src/internal/Realm.ts +768 -0
- package/src/internal/RequestId.ts +118 -0
- package/src/internal/SignInGrant.ts +168 -0
- package/src/internal/SigningKey.ts +286 -0
- package/src/internal/TempoAccount.ts +342 -0
- package/src/internal/TestInbox.ts +51 -0
- package/src/internal/Timing.ts +158 -0
- package/src/internal/Validation.ts +52 -0
- package/src/internal/Wallet.ts +62 -0
- package/src/internal/owners/Passkey.ts +72 -0
- package/src/internal/owners/Privy.ts +81 -0
- package/src/internal/owners/Secp256k1.ts +143 -0
- package/src/types/app.d.ts +19 -0
- package/src/worker.ts +11 -0
|
@@ -0,0 +1,362 @@
|
|
|
1
|
+
/** The sign-in screen: an email address and the code sent to it, Google, or a passkey. @module */
|
|
2
|
+
import { type FormEvent, type ReactNode, useId } from 'react'
|
|
3
|
+
import Google from '~icons/logos/google-icon'
|
|
4
|
+
import BadgeCheck from '~icons/lucide/badge-check'
|
|
5
|
+
import Fingerprint from '~icons/lucide/fingerprint'
|
|
6
|
+
import { Button } from '../components/Button.js'
|
|
7
|
+
import { CodeInput } from '../components/CodeInput.js'
|
|
8
|
+
import { ErrorMessage } from '../components/ErrorMessage.js'
|
|
9
|
+
import { Grant } from '../components/Grant.js'
|
|
10
|
+
import { Input } from '../components/Input.js'
|
|
11
|
+
import { Tooltip } from '../components/Tooltip.js'
|
|
12
|
+
import { style } from '../zyzz.config.js'
|
|
13
|
+
import type { Approval } from './Approval.js'
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* The sign-in screen. Without `email` it asks for one, for Google, or for a passkey. With `email` it
|
|
17
|
+
* asks for the code sent there.
|
|
18
|
+
*/
|
|
19
|
+
export function SignIn(props: SignIn.Props): ReactNode {
|
|
20
|
+
const Title = props.heading ?? 'h1'
|
|
21
|
+
const { email } = props
|
|
22
|
+
// Several screens can share a document, such as on the flows canvas, so each derives its own IDs.
|
|
23
|
+
const id = useId()
|
|
24
|
+
|
|
25
|
+
return (
|
|
26
|
+
<div {...styles.column()}>
|
|
27
|
+
<header {...styles.header()}>
|
|
28
|
+
<Title {...styles.title()}>
|
|
29
|
+
{(() => {
|
|
30
|
+
if (email) return 'Check your email'
|
|
31
|
+
if (props.linking) return 'Verify your email'
|
|
32
|
+
return 'Sign in to Tempo'
|
|
33
|
+
})()}
|
|
34
|
+
</Title>
|
|
35
|
+
{(() => {
|
|
36
|
+
if (email)
|
|
37
|
+
return (
|
|
38
|
+
<p {...styles.description()}>
|
|
39
|
+
Enter the 6-digit code sent to <strong>{email}</strong>.
|
|
40
|
+
{props.linking
|
|
41
|
+
? ' Your passkey then confirms the sign-in.'
|
|
42
|
+
: null}
|
|
43
|
+
</p>
|
|
44
|
+
)
|
|
45
|
+
if (props.linking)
|
|
46
|
+
return (
|
|
47
|
+
<p {...styles.description()}>
|
|
48
|
+
Enter your email to finish signing in with your passkey.
|
|
49
|
+
</p>
|
|
50
|
+
)
|
|
51
|
+
if (props.request)
|
|
52
|
+
return (
|
|
53
|
+
<p {...styles.description()}>
|
|
54
|
+
Continue to let{' '}
|
|
55
|
+
<span {...styles.app()}>
|
|
56
|
+
<strong>{props.request.app}</strong>{' '}
|
|
57
|
+
<Tooltip label="Verified app">
|
|
58
|
+
<BadgeCheck
|
|
59
|
+
{...styles.badge()}
|
|
60
|
+
aria-label="Verified"
|
|
61
|
+
role="img"
|
|
62
|
+
tabIndex={0}
|
|
63
|
+
/>
|
|
64
|
+
</Tooltip>
|
|
65
|
+
</span>{' '}
|
|
66
|
+
use your Tempo Account.
|
|
67
|
+
</p>
|
|
68
|
+
)
|
|
69
|
+
return null
|
|
70
|
+
})()}
|
|
71
|
+
</header>
|
|
72
|
+
{/* The code step only proves the email, so the key shows once, before it. Signing in grants it. */}
|
|
73
|
+
{props.request && !email && !props.linking ? (
|
|
74
|
+
<Grant
|
|
75
|
+
heading={props.heading === 'h4' ? 'h5' : 'h2'}
|
|
76
|
+
keyAuthorization={props.request.key}
|
|
77
|
+
/>
|
|
78
|
+
) : null}
|
|
79
|
+
|
|
80
|
+
{email ? (
|
|
81
|
+
// A form submitted before the page hydrates posts, so the address and code stay out of the URL.
|
|
82
|
+
<form {...styles.code()} method="post" onSubmit={props.onSubmitCode}>
|
|
83
|
+
<CodeInput
|
|
84
|
+
aria-describedby={`${id}-error`}
|
|
85
|
+
aria-invalid={props.invalid}
|
|
86
|
+
aria-label="Code"
|
|
87
|
+
// The step replaces the email form, so focus moves to the field it asks for.
|
|
88
|
+
autoFocus={props.autoFocus}
|
|
89
|
+
inputMode="numeric"
|
|
90
|
+
// `CodeInput` cuts the cleaned value to `length`. A native `maxLength` would cut a pasted
|
|
91
|
+
// code before the space or dash around it is removed.
|
|
92
|
+
length={6}
|
|
93
|
+
name="code"
|
|
94
|
+
// A complete code submits itself.
|
|
95
|
+
onChange={(event) => {
|
|
96
|
+
if (event.currentTarget.value.length === 6)
|
|
97
|
+
event.currentTarget.form?.requestSubmit()
|
|
98
|
+
}}
|
|
99
|
+
pattern="\d{6}"
|
|
100
|
+
readOnly={props.verifying || props.verified}
|
|
101
|
+
required
|
|
102
|
+
verified={props.verified}
|
|
103
|
+
/>
|
|
104
|
+
<ErrorMessage align="center" id={`${id}-error`}>
|
|
105
|
+
{props.error}
|
|
106
|
+
</ErrorMessage>
|
|
107
|
+
<div {...styles.links()}>
|
|
108
|
+
<button
|
|
109
|
+
{...styles.link()}
|
|
110
|
+
disabled={
|
|
111
|
+
props.resend === 'pending' || props.verifying || props.verified
|
|
112
|
+
}
|
|
113
|
+
onClick={props.onResend}
|
|
114
|
+
type="button"
|
|
115
|
+
>
|
|
116
|
+
{(() => {
|
|
117
|
+
if (props.resend === 'pending') return 'Sending…'
|
|
118
|
+
if (props.resend === 'sent') return 'Code sent'
|
|
119
|
+
return 'Resend code'
|
|
120
|
+
})()}
|
|
121
|
+
</button>
|
|
122
|
+
<button
|
|
123
|
+
{...styles.link()}
|
|
124
|
+
// The address stays until the code's result returns, so the result applies to it.
|
|
125
|
+
disabled={props.verifying || props.verified}
|
|
126
|
+
onClick={props.onChangeEmail}
|
|
127
|
+
type="button"
|
|
128
|
+
>
|
|
129
|
+
Use a different email
|
|
130
|
+
</button>
|
|
131
|
+
<p {...styles.status()} aria-live="polite" role="status">
|
|
132
|
+
{(() => {
|
|
133
|
+
if (props.resend === 'pending') return 'Sending a new code.'
|
|
134
|
+
if (props.resend === 'sent')
|
|
135
|
+
return `A new code was sent to ${email}.`
|
|
136
|
+
return undefined
|
|
137
|
+
})()}
|
|
138
|
+
</p>
|
|
139
|
+
</div>
|
|
140
|
+
</form>
|
|
141
|
+
) : (
|
|
142
|
+
<div {...styles.stack()}>
|
|
143
|
+
<form
|
|
144
|
+
{...styles.stack()}
|
|
145
|
+
method="post"
|
|
146
|
+
onSubmit={props.onSubmitEmail}
|
|
147
|
+
>
|
|
148
|
+
<Input
|
|
149
|
+
aria-describedby={`${id}-error`}
|
|
150
|
+
aria-invalid={props.invalid}
|
|
151
|
+
aria-label="Email"
|
|
152
|
+
// `webauthn` lets the browser offer passkeys in the field's autofill.
|
|
153
|
+
autoComplete={props.onPasskey ? 'email webauthn' : 'email'}
|
|
154
|
+
// 1Password's inline menu takes focus from the field when it is clicked.
|
|
155
|
+
data-1p-ignore
|
|
156
|
+
id={`${id}-email`}
|
|
157
|
+
name="email"
|
|
158
|
+
placeholder="Email address"
|
|
159
|
+
required
|
|
160
|
+
type="email"
|
|
161
|
+
/>
|
|
162
|
+
<ErrorMessage id={`${id}-error`}>{props.error}</ErrorMessage>
|
|
163
|
+
<Button
|
|
164
|
+
// One sign-in runs at a time, since each one sets the session.
|
|
165
|
+
disabled={props.passkeyPending}
|
|
166
|
+
loading={props.sending}
|
|
167
|
+
type="submit"
|
|
168
|
+
>
|
|
169
|
+
Continue with email
|
|
170
|
+
</Button>
|
|
171
|
+
</form>
|
|
172
|
+
{/* A passkey that waits for its email links only through the code, so the other methods hide. */}
|
|
173
|
+
{!props.linking && (props.onGoogle || props.onPasskey) ? (
|
|
174
|
+
<hr {...styles.rule()} />
|
|
175
|
+
) : null}
|
|
176
|
+
{props.onGoogle && !props.linking ? (
|
|
177
|
+
<Button
|
|
178
|
+
disabled={props.sending || props.passkeyPending}
|
|
179
|
+
onClick={props.onGoogle}
|
|
180
|
+
prefix={<Google aria-hidden />}
|
|
181
|
+
variant="secondary"
|
|
182
|
+
>
|
|
183
|
+
Continue with Google
|
|
184
|
+
</Button>
|
|
185
|
+
) : null}
|
|
186
|
+
{props.onPasskey && !props.linking ? (
|
|
187
|
+
<Button
|
|
188
|
+
disabled={props.sending}
|
|
189
|
+
loading={props.passkeyPending}
|
|
190
|
+
onClick={props.onPasskey}
|
|
191
|
+
prefix={<Fingerprint aria-hidden />}
|
|
192
|
+
variant="secondary"
|
|
193
|
+
>
|
|
194
|
+
Continue with passkey
|
|
195
|
+
</Button>
|
|
196
|
+
) : null}
|
|
197
|
+
{props.linking && props.onStartOver ? (
|
|
198
|
+
<button
|
|
199
|
+
{...styles.link()}
|
|
200
|
+
onClick={props.onStartOver}
|
|
201
|
+
type="button"
|
|
202
|
+
>
|
|
203
|
+
Start over
|
|
204
|
+
</button>
|
|
205
|
+
) : null}
|
|
206
|
+
</div>
|
|
207
|
+
)}
|
|
208
|
+
</div>
|
|
209
|
+
)
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
export declare namespace SignIn {
|
|
213
|
+
type Props = {
|
|
214
|
+
/** Whether the code field takes focus when it appears. */
|
|
215
|
+
autoFocus?: boolean | undefined
|
|
216
|
+
/** The address a code was sent to, which shows the code step. */
|
|
217
|
+
email?: string | undefined
|
|
218
|
+
/** Why the current step failed. */
|
|
219
|
+
error?: string | undefined
|
|
220
|
+
/** The level of the screen's title: `h1` by default, or `h4` on the flows canvas, below the canvas's own headings. */
|
|
221
|
+
heading?: 'h1' | 'h4' | undefined
|
|
222
|
+
/** Whether the current step's own request failed, which marks its field invalid. */
|
|
223
|
+
invalid: boolean
|
|
224
|
+
/** Whether a passkey waits for the emailed code that links it, which the email and code steps explain. */
|
|
225
|
+
linking?: boolean | undefined
|
|
226
|
+
/** Returns to the email step. */
|
|
227
|
+
onChangeEmail: () => void
|
|
228
|
+
/** Signs in with Google. Absent, the screen offers no Google sign-in. */
|
|
229
|
+
onGoogle?: (() => void) | undefined
|
|
230
|
+
/** Signs in with a passkey. Absent, the screen offers no passkey sign-in. */
|
|
231
|
+
onPasskey?: (() => void) | undefined
|
|
232
|
+
/** Sends a new code to `email`. */
|
|
233
|
+
onResend: () => void
|
|
234
|
+
/**
|
|
235
|
+
* Drops the passkey that waits for a code, and returns to the first sign-in step. Absent, the
|
|
236
|
+
* linking step offers no way back.
|
|
237
|
+
*/
|
|
238
|
+
onStartOver?: (() => void) | undefined
|
|
239
|
+
/** Submits the code form. */
|
|
240
|
+
onSubmitCode: (event: FormEvent<HTMLFormElement>) => void
|
|
241
|
+
/** Submits the email form, which sends a code. */
|
|
242
|
+
onSubmitEmail: (event: FormEvent<HTMLFormElement>) => void
|
|
243
|
+
/** Whether a passkey sign-in runs, which holds its button and the email form. */
|
|
244
|
+
passkeyPending?: boolean | undefined
|
|
245
|
+
/**
|
|
246
|
+
* The app's authorization request that the sign-in continues, with the key that the sign-in
|
|
247
|
+
* grants. Absent for a sign-in without one, or for a request whose key the approval page shows.
|
|
248
|
+
*/
|
|
249
|
+
request?:
|
|
250
|
+
| {
|
|
251
|
+
/** The app's display name. */
|
|
252
|
+
app: string
|
|
253
|
+
/** What the key that the app requests may do. */
|
|
254
|
+
key: Approval.Key
|
|
255
|
+
}
|
|
256
|
+
| undefined
|
|
257
|
+
/** The progress of a resent code. */
|
|
258
|
+
resend: 'idle' | 'pending' | 'sent'
|
|
259
|
+
/** Whether the first code is being sent. */
|
|
260
|
+
sending: boolean
|
|
261
|
+
/** Whether the code was accepted, which tints the code field green before the sign-in continues. */
|
|
262
|
+
verified?: boolean | undefined
|
|
263
|
+
/** Whether the code is being verified, which holds the code field. */
|
|
264
|
+
verifying: boolean
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
namespace styles {
|
|
269
|
+
// The app's name and badge wrap as one word, so a hyphenated name never splits.
|
|
270
|
+
export const app = style({ whiteSpace: 'nowrap' })
|
|
271
|
+
|
|
272
|
+
export const badge = style({
|
|
273
|
+
display: 'inline',
|
|
274
|
+
height: 4,
|
|
275
|
+
outline: 'none',
|
|
276
|
+
verticalAlign: 'middle',
|
|
277
|
+
width: 4,
|
|
278
|
+
':focus-visible': {
|
|
279
|
+
outline: '2px solid',
|
|
280
|
+
outlineColor: 'blue.700',
|
|
281
|
+
outlineOffset: '2px',
|
|
282
|
+
},
|
|
283
|
+
})
|
|
284
|
+
|
|
285
|
+
export const code = style({ display: 'grid', gap: 6 })
|
|
286
|
+
|
|
287
|
+
export const column = style({
|
|
288
|
+
display: 'grid',
|
|
289
|
+
gap: 8,
|
|
290
|
+
maxWidth: 'sm',
|
|
291
|
+
width: 'full',
|
|
292
|
+
})
|
|
293
|
+
|
|
294
|
+
export const description = style({
|
|
295
|
+
color: 'gray.900',
|
|
296
|
+
textWrap: 'balance',
|
|
297
|
+
typography: 'copy.16',
|
|
298
|
+
'& strong': { color: 'foreground', fontWeight: 'medium' },
|
|
299
|
+
})
|
|
300
|
+
|
|
301
|
+
export const header = style({
|
|
302
|
+
display: 'grid',
|
|
303
|
+
gap: 2,
|
|
304
|
+
textAlign: 'center',
|
|
305
|
+
})
|
|
306
|
+
|
|
307
|
+
// A quiet pill, filled while hovered.
|
|
308
|
+
export const link = style({
|
|
309
|
+
backgroundColor: 'transparent',
|
|
310
|
+
border: 'none',
|
|
311
|
+
borderRadius: 'full',
|
|
312
|
+
color: 'foreground',
|
|
313
|
+
cursor: 'pointer',
|
|
314
|
+
height: 9,
|
|
315
|
+
justifySelf: 'center',
|
|
316
|
+
outline: 'none',
|
|
317
|
+
paddingInline: 4,
|
|
318
|
+
transitionDuration: '150ms',
|
|
319
|
+
transitionProperty: 'background-color, color',
|
|
320
|
+
transitionTimingFunction: 'in-out',
|
|
321
|
+
typography: 'button.14',
|
|
322
|
+
':disabled': { color: 'gray.700', cursor: 'not-allowed' },
|
|
323
|
+
':hover:not(:disabled)': { backgroundColor: 'gray.100' },
|
|
324
|
+
':focus-visible': {
|
|
325
|
+
outline: '2px solid',
|
|
326
|
+
outlineColor: 'blue.700',
|
|
327
|
+
outlineOffset: '2px',
|
|
328
|
+
},
|
|
329
|
+
})
|
|
330
|
+
|
|
331
|
+
export const links = style({
|
|
332
|
+
display: 'grid',
|
|
333
|
+
gap: 1,
|
|
334
|
+
justifyItems: 'center',
|
|
335
|
+
})
|
|
336
|
+
|
|
337
|
+
// The rule between the emailed code and the other sign-in methods.
|
|
338
|
+
export const rule = style({
|
|
339
|
+
border: 'none',
|
|
340
|
+
borderTop: '1px solid',
|
|
341
|
+
borderTopColor: 'gray.400',
|
|
342
|
+
marginBlock: 1,
|
|
343
|
+
width: 'full',
|
|
344
|
+
})
|
|
345
|
+
|
|
346
|
+
export const stack = style({ display: 'grid', gap: 3 })
|
|
347
|
+
|
|
348
|
+
// Screen readers announce the resend's progress, which the button label shows visually.
|
|
349
|
+
export const status = style({
|
|
350
|
+
clipPath: 'inset(50%)',
|
|
351
|
+
height: 'px',
|
|
352
|
+
overflow: 'hidden',
|
|
353
|
+
position: 'absolute',
|
|
354
|
+
whiteSpace: 'nowrap',
|
|
355
|
+
width: 'px',
|
|
356
|
+
})
|
|
357
|
+
|
|
358
|
+
export const title = style({
|
|
359
|
+
textWrap: 'balance',
|
|
360
|
+
typography: 'heading.24',
|
|
361
|
+
})
|
|
362
|
+
}
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
<svg width="64" height="64" viewBox="0 0 64 64" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
2
|
+
<path d="M8 12.5493C8 10.9893 8 10.2107 8.29333 9.61333C8.576 9.04 9.04 8.57333 9.616 8.29333C10.2133 8 10.992 8 12.5493 8H51.4507C53.0107 8 53.7867 8 54.3867 8.29333C54.96 8.57333 55.424 9.04 55.704 9.61333C56 10.2133 56 10.992 56 12.5493V51.4507C56 53.0107 56 53.7867 55.7067 54.3867C55.424 54.96 54.96 55.424 54.3867 55.704C53.7867 56 53.008 56 51.4507 56H12.5493C10.9893 56 10.2133 56 9.61333 55.7067C9.03998 55.4249 8.57656 54.9606 8.296 54.3867C8 53.7867 8 53.008 8 51.4507V12.5493Z" fill="#0000FF" />
|
|
3
|
+
</svg>
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
<svg width="64" height="64" viewBox="0 0 64 64" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
2
|
+
<rect width="64" height="64" fill="#627EEA" />
|
|
3
|
+
<g transform="translate(18 8)">
|
|
4
|
+
<path d="M14.996 0V17.74L29.99 24.44L14.996 0Z" fill="white" fill-opacity="0.602" />
|
|
5
|
+
<path d="M14.996 0L0 24.44L14.996 17.74V0Z" fill="white" />
|
|
6
|
+
<path d="M14.996 35.936V47.99L30 27.232L14.996 35.936Z" fill="white" fill-opacity="0.602" />
|
|
7
|
+
<path d="M14.996 47.99V35.934L0 27.232L14.996 47.99Z" fill="white" />
|
|
8
|
+
<path d="M14.996 33.146L29.99 24.44L14.996 17.744V33.146Z" fill="white" fill-opacity="0.2" />
|
|
9
|
+
<path d="M0 24.44L14.996 33.146V17.744L0 24.44Z" fill="white" fill-opacity="0.602" />
|
|
10
|
+
</g>
|
|
11
|
+
</svg>
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
<svg width="64" height="64" viewBox="0 0 64 64" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
2
|
+
<rect width="64" height="64" fill="black" />
|
|
3
|
+
<path d="M46.964 22.4753C46.7023 22.7154 46.3609 22.8511 46.005 22.8563H12.3524C11.1577 22.8563 10.5556 21.497 11.3817 20.7L16.9072 15.3927C17.1641 15.1449 17.5064 15.0044 17.8639 15H51.6496C52.8559 15 53.4463 16.371 52.6063 17.1703L46.964 22.4753ZM46.964 48.6328C46.7026 48.8718 46.3599 49.003 46.005 48.9999H12.3524C11.1577 48.9999 10.5556 47.6522 11.3817 46.8552L16.9072 41.5363C17.1662 41.2936 17.5083 41.1582 17.8639 41.1576H51.6496C52.8559 41.1576 53.4463 42.5169 52.6063 43.3139L46.964 48.6328ZM46.964 28.4517C46.7023 28.2136 46.3595 28.0832 46.005 28.0869H12.3524C11.1577 28.0869 10.5556 29.4346 11.3817 30.2293L16.9072 35.5505C17.1687 35.7893 17.5092 35.9241 17.8639 35.9293H51.6496C52.8559 35.9293 53.4463 34.57 52.6063 33.7729L46.964 28.4517Z" fill="white" />
|
|
4
|
+
</svg>
|
|
@@ -0,0 +1,204 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The app's server entry. The root Hono app in `src/Api.ts` serves every request, and renders each
|
|
3
|
+
* path that no route serves through TanStack Start. Server rendering reaches the API in process
|
|
4
|
+
* through the request context, so loaders call the same routes as the browser. The cron trigger
|
|
5
|
+
* runs `crons/cleanup.ts`. Void's Worker entry imports this module in place of TanStack Start's
|
|
6
|
+
* default entry, as `vite.config.ts` aliases it.
|
|
7
|
+
* @module
|
|
8
|
+
*/
|
|
9
|
+
import {
|
|
10
|
+
createStartHandler,
|
|
11
|
+
defaultStreamHandler,
|
|
12
|
+
} from '@tanstack/react-start/server'
|
|
13
|
+
import type { Context, ExecutionContext } from 'hono'
|
|
14
|
+
import { withRuntimeEnv } from 'void/_env'
|
|
15
|
+
import { api } from '../Api.js'
|
|
16
|
+
import type { Env } from '../internal/Env.js'
|
|
17
|
+
import * as Log from '../internal/Log.js'
|
|
18
|
+
import * as Timing from '../internal/Timing.js'
|
|
19
|
+
import cleanup from './crons/cleanup.js'
|
|
20
|
+
|
|
21
|
+
/** What server rendering receives for each page request. */
|
|
22
|
+
export type RequestContext = {
|
|
23
|
+
/** Calls the API in process with the page request's cookies and client headers. */
|
|
24
|
+
fetch: (input: RequestInfo | URL, init?: RequestInit) => Promise<Response>
|
|
25
|
+
/** The page's origin, which the API client's requests name. */
|
|
26
|
+
origin: string
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
declare module '@tanstack/react-start' {
|
|
30
|
+
interface Register {
|
|
31
|
+
server: { requestContext: RequestContext }
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/** The headers of a rate limit's refusal, which a page whose loader met the limit carries. */
|
|
36
|
+
const limit = ['ratelimit', 'ratelimit-policy', 'retry-after'] as const
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* The page request's headers that each in-process call carries, as the browser's own call would: the
|
|
40
|
+
* client's address and Ray ID, which rate limits and the request ID read, and its user agent, which
|
|
41
|
+
* Better Auth records.
|
|
42
|
+
*/
|
|
43
|
+
const forwarded = [
|
|
44
|
+
'cf-connecting-ip',
|
|
45
|
+
'cf-ray',
|
|
46
|
+
'cf-worker',
|
|
47
|
+
'user-agent',
|
|
48
|
+
] as const
|
|
49
|
+
|
|
50
|
+
const start = createStartHandler(defaultStreamHandler)
|
|
51
|
+
|
|
52
|
+
export default {
|
|
53
|
+
fetch: (
|
|
54
|
+
request: Request,
|
|
55
|
+
env: Record<string, unknown>,
|
|
56
|
+
ctx: ExecutionContext,
|
|
57
|
+
) =>
|
|
58
|
+
api.fetch(
|
|
59
|
+
request,
|
|
60
|
+
{ ...env, pages: (c: Context<Env>) => render(c, { env, ctx }) },
|
|
61
|
+
ctx,
|
|
62
|
+
),
|
|
63
|
+
// Void's Worker entry runs only `fetch` in its runtime scope, so the cron trigger enters it here.
|
|
64
|
+
scheduled: (...args: Parameters<typeof cleanup>) =>
|
|
65
|
+
withRuntimeEnv(args[1], () => cleanup(...args)),
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
* Renders the page of the request `c` through TanStack Start. A session refresh rotates its refresh
|
|
70
|
+
* token, and a call while rendering may refresh it. Later calls and the page carry the newest cookie,
|
|
71
|
+
* so no refresh reuses a spent token. A page whose loader met a rate limit responds with status 429
|
|
72
|
+
* and the limit's headers, and shows the refusal's message.
|
|
73
|
+
*/
|
|
74
|
+
async function render(c: Context<Env>, options: render.Options) {
|
|
75
|
+
const { ctx, env } = options
|
|
76
|
+
const cookies = parse(c.req.header('cookie'))
|
|
77
|
+
const origin = new URL(c.req.url).origin
|
|
78
|
+
let first: Promise<Response> | undefined
|
|
79
|
+
let limited: Response | undefined
|
|
80
|
+
let sent = false
|
|
81
|
+
|
|
82
|
+
const call = async (input: RequestInfo | URL, init?: RequestInit) => {
|
|
83
|
+
const request = new Request(input, init)
|
|
84
|
+
// Loaders read only the JSON API on the page's origin, so a value from a page's query that
|
|
85
|
+
// resolves to another path never reaches another route with the session.
|
|
86
|
+
const url = new URL(request.url)
|
|
87
|
+
if (url.origin !== origin || !url.pathname.startsWith('/v1/'))
|
|
88
|
+
throw new Error('A page called a path outside the JSON API.')
|
|
89
|
+
if (cookies.size > 0) request.headers.set('cookie', serialize(cookies))
|
|
90
|
+
for (const name of forwarded) {
|
|
91
|
+
const value = c.req.header(name)
|
|
92
|
+
if (value) request.headers.set(name, value)
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
// Each call logs its own spans, and the page's header shows the call's total.
|
|
96
|
+
const response = await Timing.measure(
|
|
97
|
+
c,
|
|
98
|
+
Promise.resolve(
|
|
99
|
+
api.fetch(request, { ...env, pages: () => notFound() }, ctx),
|
|
100
|
+
),
|
|
101
|
+
'api',
|
|
102
|
+
`${request.method} ${new URL(request.url).pathname}`,
|
|
103
|
+
)
|
|
104
|
+
for (const setCookie of response.headers.getSetCookie()) {
|
|
105
|
+
apply(cookies, { setCookie })
|
|
106
|
+
// The page's headers go out when the page starts to stream, before its body ends.
|
|
107
|
+
if (sent)
|
|
108
|
+
Log.warn(c, {
|
|
109
|
+
message: 'A page set a cookie after its headers were sent.',
|
|
110
|
+
})
|
|
111
|
+
else c.header('set-cookie', setCookie, { append: true })
|
|
112
|
+
}
|
|
113
|
+
if (response.status === 429) limited ??= response
|
|
114
|
+
return response
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
const response = await start(c.req.raw, {
|
|
118
|
+
context: {
|
|
119
|
+
fetch: async (input, init) => {
|
|
120
|
+
// Later calls wait for the first one's cookies, so concurrent reads refresh a session once.
|
|
121
|
+
if (first)
|
|
122
|
+
await Timing.measure(
|
|
123
|
+
c,
|
|
124
|
+
first.catch(() => undefined),
|
|
125
|
+
'api.wait',
|
|
126
|
+
)
|
|
127
|
+
const response = call(input, init)
|
|
128
|
+
first ??= response
|
|
129
|
+
return response
|
|
130
|
+
},
|
|
131
|
+
origin,
|
|
132
|
+
},
|
|
133
|
+
})
|
|
134
|
+
sent = true
|
|
135
|
+
// Pages show the signed-in user's data and an app's signed request, so no cache keeps them.
|
|
136
|
+
c.header('cache-control', 'private, no-store')
|
|
137
|
+
|
|
138
|
+
if (limited && response.status === 200) {
|
|
139
|
+
for (const name of limit) {
|
|
140
|
+
const value = limited.headers.get(name)
|
|
141
|
+
if (value) c.header(name, value)
|
|
142
|
+
}
|
|
143
|
+
return c.newResponse(response.body, {
|
|
144
|
+
headers: response.headers,
|
|
145
|
+
status: 429,
|
|
146
|
+
})
|
|
147
|
+
}
|
|
148
|
+
return c.newResponse(response.body, response)
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
declare namespace render {
|
|
152
|
+
type Options = {
|
|
153
|
+
/** The Worker's execution context. */
|
|
154
|
+
ctx: ExecutionContext
|
|
155
|
+
/** The Worker's bindings. */
|
|
156
|
+
env: Record<string, unknown>
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
/** Applies a `Set-Cookie` header to `cookies`, and removes a cookie that it expires. */
|
|
161
|
+
function apply(cookies: Map<string, string>, options: apply.Options) {
|
|
162
|
+
// `split` returns at least one element.
|
|
163
|
+
const [pair, ...attributes] = options.setCookie.split(';') as [
|
|
164
|
+
string,
|
|
165
|
+
...string[],
|
|
166
|
+
]
|
|
167
|
+
const index = pair.indexOf('=')
|
|
168
|
+
const name = pair.slice(0, index).trim()
|
|
169
|
+
const value = pair.slice(index + 1).trim()
|
|
170
|
+
// `deleteCookie` sets an empty value with `Max-Age=0`.
|
|
171
|
+
const expired = attributes.some((attribute) =>
|
|
172
|
+
/^max-age=0$/i.test(attribute.trim()),
|
|
173
|
+
)
|
|
174
|
+
if (expired || !value) cookies.delete(name)
|
|
175
|
+
else cookies.set(name, value)
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
declare namespace apply {
|
|
179
|
+
type Options = {
|
|
180
|
+
/** One `Set-Cookie` header value. */
|
|
181
|
+
setCookie: string
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
/** Responds to an in-process call to a path that no route serves, which renders no page. */
|
|
186
|
+
function notFound() {
|
|
187
|
+
return Promise.resolve(new Response(null, { status: 404 }))
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
/** Parses a `Cookie` header into raw values by name, still encoded as the browser sent them. */
|
|
191
|
+
function parse(header: string | undefined) {
|
|
192
|
+
const cookies = new Map<string, string>()
|
|
193
|
+
for (const pair of header?.split(';') ?? []) {
|
|
194
|
+
const index = pair.indexOf('=')
|
|
195
|
+
if (index > 0)
|
|
196
|
+
cookies.set(pair.slice(0, index).trim(), pair.slice(index + 1).trim())
|
|
197
|
+
}
|
|
198
|
+
return cookies
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
/** Serializes `cookies` as a `Cookie` header. */
|
|
202
|
+
function serialize(cookies: Map<string, string>) {
|
|
203
|
+
return [...cookies].map(([name, value]) => `${name}=${value}`).join('; ')
|
|
204
|
+
}
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Builds and serves the Tempo ID app with Void and TanStack Start, zyzz styles, and icon components.
|
|
3
|
+
* @module
|
|
4
|
+
*/
|
|
5
|
+
import { type ConfigPlugin, transform } from '@svgr/core'
|
|
6
|
+
import jsx from '@svgr/plugin-jsx'
|
|
7
|
+
import { tanstackStart } from '@tanstack/react-start/plugin/vite'
|
|
8
|
+
import react from '@vitejs/plugin-react'
|
|
9
|
+
import * as Url from 'node:url'
|
|
10
|
+
import icons from 'unplugin-icons/vite'
|
|
11
|
+
import { defineConfig } from 'vite'
|
|
12
|
+
import { voidPlugin } from 'void'
|
|
13
|
+
import { zyzz } from 'zyzz/vite'
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* svgr's JSX plugin. The package is CommonJS without an ES module flag, so Node's loader returns its
|
|
17
|
+
* exports object, whose `default` is the plugin, and the build's bundler returns the plugin itself.
|
|
18
|
+
*/
|
|
19
|
+
const svgJsx: ConfigPlugin =
|
|
20
|
+
typeof jsx === 'function' ? jsx : (jsx as { default: ConfigPlugin }).default
|
|
21
|
+
|
|
22
|
+
export default defineConfig({
|
|
23
|
+
environments: {
|
|
24
|
+
// The Worker bundles every dependency. TanStack Start lists its own packages, which would leave
|
|
25
|
+
// the rest external, and zyzz then cannot read the default tokens that `zyzz.config.ts` extends.
|
|
26
|
+
ssr: { resolve: { noExternal: true } },
|
|
27
|
+
},
|
|
28
|
+
// Plugins run in order: Void comes before TanStack Start, zyzz compiles styles before the route and
|
|
29
|
+
// React transforms, and TanStack Start comes before React's plugin.
|
|
30
|
+
plugins: [
|
|
31
|
+
voidPlugin(),
|
|
32
|
+
// Void targets browsers with native `light-dark()`, which zyzz needs, and Cloudflare's plugin adds
|
|
33
|
+
// `es2024` to its Worker environment, which zyzz cannot check. Vite concatenates the two lists, so
|
|
34
|
+
// the resolved list drops the addition before zyzz reads it.
|
|
35
|
+
{
|
|
36
|
+
configResolved: (config) => {
|
|
37
|
+
const builds = [
|
|
38
|
+
config.build,
|
|
39
|
+
...Object.values(config.environments).map((entry) => entry.build),
|
|
40
|
+
]
|
|
41
|
+
for (const build of builds)
|
|
42
|
+
if (Array.isArray(build.cssTarget))
|
|
43
|
+
build.cssTarget = build.cssTarget.filter(
|
|
44
|
+
(target) => target !== 'es2024',
|
|
45
|
+
)
|
|
46
|
+
},
|
|
47
|
+
enforce: 'pre',
|
|
48
|
+
name: 'tempo-id:css-target',
|
|
49
|
+
},
|
|
50
|
+
// Styles live in routes, screens, and components. The extractor cannot load server-only modules.
|
|
51
|
+
zyzz({
|
|
52
|
+
exclude: [
|
|
53
|
+
'crons/**',
|
|
54
|
+
'db/**',
|
|
55
|
+
'env.ts',
|
|
56
|
+
'routeTree.gen.ts',
|
|
57
|
+
'server.ts',
|
|
58
|
+
'void.config.ts',
|
|
59
|
+
],
|
|
60
|
+
}),
|
|
61
|
+
// The app's root is `src/app`, which holds the router, the routes, and the server entry.
|
|
62
|
+
tanstackStart({ srcDirectory: '.' }),
|
|
63
|
+
react(),
|
|
64
|
+
// Icons compile to React components, imported from `~icons/<collection>/<name>`. The compiler
|
|
65
|
+
// imports svgr here, since the icons plugin's own lookup of it fails under `vp dev`.
|
|
66
|
+
icons({
|
|
67
|
+
compiler: {
|
|
68
|
+
compiler: (svg, collection, icon) =>
|
|
69
|
+
transform(
|
|
70
|
+
svg,
|
|
71
|
+
{ plugins: [svgJsx], ref: true, titleProp: true },
|
|
72
|
+
{
|
|
73
|
+
componentName: `${collection}-${icon}`.replace(
|
|
74
|
+
/-(\w)/g,
|
|
75
|
+
(_, letter: string) => letter.toUpperCase(),
|
|
76
|
+
),
|
|
77
|
+
},
|
|
78
|
+
),
|
|
79
|
+
extension: 'jsx',
|
|
80
|
+
},
|
|
81
|
+
jsx: 'react',
|
|
82
|
+
scale: 1,
|
|
83
|
+
}),
|
|
84
|
+
],
|
|
85
|
+
// Void's Worker entry imports TanStack Start's default server entry, so the alias points it at
|
|
86
|
+
// `server.ts`, which serves every request through the root Hono app and runs the cron trigger.
|
|
87
|
+
resolve: {
|
|
88
|
+
alias: [
|
|
89
|
+
{
|
|
90
|
+
find: /^@tanstack\/react-start\/server-entry$/,
|
|
91
|
+
replacement: Url.fileURLToPath(new URL('server.ts', import.meta.url)),
|
|
92
|
+
},
|
|
93
|
+
],
|
|
94
|
+
},
|
|
95
|
+
})
|