@voltro/cli 0.33.0 → 0.35.0
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/CHANGELOG.md +1968 -0
- package/bin/nodeEnvironment.d.mts +30 -0
- package/bin/nodeEnvironment.mjs +158 -0
- package/bin/voltro.mjs +69 -5
- package/dist/addCommand-BNeoeSxe.js +124 -0
- package/dist/addCommand-aXSQveak.js +2 -0
- package/dist/agentsMd-BTchIZku.js +2 -0
- package/dist/agentsMd-mhQMF1bx.js +254 -0
- package/dist/apiBuild-B8aoJvuw.js +2 -0
- package/dist/{apiBuild-h9VHtnlw.js → apiBuild-DYD_ONLD.js} +46 -46
- package/dist/{appGraph-gQ_6GkQQ.js → appGraph-KGDPTuTy.js} +1 -1
- package/dist/appGraph-zuMGKVYX.js +2 -0
- package/dist/appPort-B_HpJ_ck.js +48 -0
- package/dist/baselineCommand-C2ClWZN3.js +2 -0
- package/dist/baselineCommand-DIttzO8A.js +227 -0
- package/dist/bin.js +71 -28
- package/dist/build-CD8K4XOr.js +711 -0
- package/dist/cacheCommand-DA4OH9xt.js +42 -0
- package/dist/capabilitiesCommand-nq_pz5xd.js +123 -0
- package/dist/checkCommand-Ct9xkTrS.js +232 -0
- package/dist/checkCommand-DKpDLlqu.js +2 -0
- package/dist/{cliArgs-qdZSElM3.js → cliArgs-D4p8n7EE.js} +12 -1
- package/dist/cliError-BmdYnghb.js +10 -0
- package/dist/cliOutput-D1tSBoRM.js +15 -0
- package/dist/{cliRuntime-Oh517vCV.js → cliRuntime-Dh7UDinH.js} +20 -20
- package/dist/cloudClient-DWL-Hw_T.js +67 -0
- package/dist/cloudCmd-Cvv5HGaZ.js +364 -0
- package/dist/clusterCmd-D5wsCmA_.js +54 -0
- package/dist/codegen-CYM3Zqrf.js +605 -0
- package/dist/codegen-ChBi_hVa.js +2 -0
- package/dist/codegenCommand-C4YoQIc2.js +30 -0
- package/dist/codemodRunner-BnFq3Fgu.js +5384 -0
- package/dist/commandRunner-BLAEFLjp.js +47 -0
- package/dist/commands-BE8E7zF3.js +816 -0
- package/dist/connectionConfig-UFlIEiys.js +66 -0
- package/dist/dashboardCommand-D7SgZGaN.js +25 -0
- package/dist/dataCommand-BhYwDgg-.js +537 -0
- package/dist/dataProfile-dW-PsfLB.js +15 -0
- package/dist/dbCommand-DS4b97Is.js +2 -0
- package/dist/{dbCommand-DTLKAfbA.js → dbCommand-O8HA63s2.js} +552 -402
- package/dist/{dev-C_P8FLSx.js → dev-C7sFZq3m.js} +3670 -3169
- package/dist/dev-D2BikO7a.js +3 -0
- package/dist/devActivity-Dx_3nnGv.js +100 -0
- package/dist/devActivity.js +1 -1
- package/dist/dialectDriver-CgXnDfec.js +39 -0
- package/dist/discover-C9XKJDco.js +25 -0
- package/dist/doctorCommand-CM4Ch9C7.js +2 -0
- package/dist/{checkCommand-xGhRFFg2.js → doctorCommand-DnimF5IM.js} +523 -1278
- package/dist/dormancyCommand-QewYug_s.js +69 -0
- package/dist/e2eCmd-BRabZww-.js +147 -0
- package/dist/embeddingsCommand-BfiLS_QI.js +73 -0
- package/dist/envCommand-CCGPRQY1.js +60 -0
- package/dist/evalCommand-6RUfPen4.js +118 -0
- package/dist/evolveCommand-CHsLCtDf.js +281 -0
- package/dist/fileTaxonomy-CJfgOllU.js +457 -0
- package/dist/frameworkTableAssembly-YyVe32Cb.js +2 -0
- package/dist/frameworkTableAssembly-oMPBKqlE.js +511 -0
- package/dist/generateCommand-DbgcUpGw.js +147 -0
- package/dist/index.d.ts +45 -0
- package/dist/index.js +4 -3
- package/dist/infoCommand-DwOgK1t6.js +60 -0
- package/dist/{inspect-BUUjt773.js → inspect-CjTYzAs_.js} +113 -41
- package/dist/inspect-P4pxoMaV.js +2 -0
- package/dist/inspectCmd-EHFZ9yYu.js +224 -0
- package/dist/inspectFetch-EMuhTG_9.js +151 -0
- package/dist/inspectMetrics-CfdKLh6t.js +72 -0
- package/dist/loadEnv-D9nEOClM.js +44 -0
- package/dist/logFileSink-C_D2wRN1.js +105 -0
- package/dist/logsCmd-D36xK7Zu.js +260 -0
- package/dist/manifestBuild-COkJoyAr.js +2 -0
- package/dist/{manifestBuild-BLrVuSlM.js → manifestBuild-hpPLaGxV.js} +1 -1
- package/dist/metaCommands-7MJfZ5cf.js +196 -0
- package/dist/migrate-BV7I-ZHZ.js +83 -0
- package/dist/mssqlClusterPatch-_4cE_nun.js +44 -0
- package/dist/newCommand-COWOJ1_E.js +156 -0
- package/dist/nodeEnvironment-cGFAj1J8.js +28 -0
- package/dist/packageCommand-Cug_3Ogl.js +271 -0
- package/dist/pageConvention-cEiRxdab.js +5 -0
- package/dist/privacyCommand-C-Df56U_.js +146 -0
- package/dist/probeCommand-CZfaaUOZ.js +122 -0
- package/dist/projectScaffold-DmzEKHib.js +2 -0
- package/dist/projectScaffold-LMMtaavR.js +814 -0
- package/dist/renderModeScan-D7J1B7Kw.js +105 -0
- package/dist/renderProfile-1OWWAAtx.js +81 -0
- package/dist/runtimeRegistry-DMeKfTHP.js +81 -0
- package/dist/runtimeTrace-CH3eUiMw.js +91 -0
- package/dist/scheduleCmd-DQRu6BZC.js +149 -0
- package/dist/scheduleManifestCmd-D2x0CTTY.js +249 -0
- package/dist/schemaIr-UJybUUZW.js +103 -0
- package/dist/{sdkgen-C81QIkiL.js → sdkgen-BLkvGRfX.js} +111 -209
- package/dist/seedRunner-ZmLSqNe2.js +333 -0
- package/dist/serveCommand-CbDHU6l-.js +2 -0
- package/dist/serveCommand-iwlUBNS1.js +1766 -0
- package/dist/serveEntry.js +5 -5
- package/dist/serverlessCommand-CfJZy6dS.js +482 -0
- package/dist/start-BgN62boB.js +3 -0
- package/dist/start-T4VesWiM.js +1087 -0
- package/dist/startEntry.js +2 -2
- package/dist/staticCommand-Dr2M6tpU.js +304 -0
- package/dist/storageCommand-Co6NfLqN.js +42 -0
- package/dist/templates-De8IR5-c.js +102 -0
- package/dist/test-CI6iDsYc.js +115 -0
- package/dist/tracesCmd-DStmCJPi.js +232 -0
- package/dist/tsconfigPaths-BWXBWgcl.js +107 -0
- package/dist/tsxLoader-EuXmSJ1K.js +51 -0
- package/dist/typecheckCommand-BlsWiCNq.js +61 -0
- package/dist/updateCommand-BlMZhWgO.js +2 -0
- package/dist/updateCommand-x0pI_x-B.js +585 -0
- package/dist/webDev-BcykISYQ2.js +2 -0
- package/dist/{inspectMetrics-1xzTKAFx.js → webDev-Dybxew86.js} +988 -1560
- package/dist/webhookDiscovery-CrGAfhIG.js +2 -0
- package/dist/webhookDiscovery-D7VaeMlz.js +51 -0
- package/dist/webhooksCommand-DlAgS2Iw.js +267 -0
- package/dist/workflowsCmd-BGF-mRZ5.js +608 -0
- package/package.json +209 -17
- package/templates/AGENTS.core.md +58 -3
- package/templates/AGENTS.md +64 -7
- package/templates/agent-docs/_index.md +6 -4
- package/templates/agent-docs/_manifest.json +23 -6
- package/templates/agent-docs/ai.md +370 -0
- package/templates/agent-docs/authentication.md +313 -31
- package/templates/agent-docs/caching.md +6 -0
- package/templates/agent-docs/cli.md +853 -50
- package/templates/agent-docs/data.md +608 -12
- package/templates/agent-docs/database/migrations.md +223 -25
- package/templates/agent-docs/database/misc.md +156 -40
- package/templates/agent-docs/database/querying.md +19 -1
- package/templates/agent-docs/database/scaling.md +60 -0
- package/templates/agent-docs/database/schema.md +1 -0
- package/templates/agent-docs/database/seedsdialects.md +208 -19
- package/templates/agent-docs/database/transactions.md +68 -0
- package/templates/agent-docs/deployment.md +284 -25
- package/templates/agent-docs/introduction.md +88 -17
- package/templates/agent-docs/local-first-mobile.md +79 -4
- package/templates/agent-docs/multi-tenancy.md +188 -42
- package/templates/agent-docs/observability.md +58 -3
- package/templates/agent-docs/plugins/ai-flows.md +247 -2
- package/templates/agent-docs/plugins/analytics-postgres.md +1 -1
- package/templates/agent-docs/plugins/audit.md +37 -1
- package/templates/agent-docs/plugins/auth-social.md +143 -0
- package/templates/agent-docs/plugins/auth-workos.md +4 -2
- package/templates/agent-docs/plugins/auth.md +131 -6
- package/templates/agent-docs/plugins/billing.md +132 -15
- package/templates/agent-docs/plugins/cdc-out.md +46 -7
- package/templates/agent-docs/plugins/clickhouse.md +32 -1
- package/templates/agent-docs/plugins/duckdb.md +1 -1
- package/templates/agent-docs/plugins/flags.md +132 -0
- package/templates/agent-docs/plugins/governance.md +105 -7
- package/templates/agent-docs/plugins/multitenancy.md +9 -4
- package/templates/agent-docs/plugins/presence.md +13 -2
- package/templates/agent-docs/plugins/ratelimit.md +9 -0
- package/templates/agent-docs/plugins/search.md +162 -8
- package/templates/agent-docs/plugins/sso-saml.md +47 -8
- package/templates/agent-docs/plugins/storage.md +11 -0
- package/templates/agent-docs/plugins/webhooks.md +105 -0
- package/templates/agent-docs/plugins.md +152 -18
- package/templates/agent-docs/reference.md +60 -3
- package/templates/agent-docs/releases.md +1117 -0
- package/templates/agent-docs/routing.md +43 -25
- package/templates/agent-docs/scheduling.md +27 -0
- package/templates/agent-docs/schema-driven-ui.md +92 -12
- package/templates/agent-docs/security.md +426 -0
- package/templates/agent-docs/templates/apibackends.md +87 -18
- package/templates/agent-docs/templates/appshells.md +32 -14
- package/templates/agent-docs/templates/overview.md +13 -8
- package/templates/agent-docs/testing.md +211 -14
- package/templates/agent-docs/whats-new.md +98 -136
- package/templates/agent-docs/workflows.md +231 -14
- package/templates/apps/api-ai/actions/summarize.action.ts +11 -0
- package/templates/apps/api-ai/package.json +8 -7
- package/templates/apps/api-auth/actions/me.action.ts +13 -0
- package/templates/apps/api-auth/package.json +9 -8
- package/templates/apps/api-backend/mutations/notes.create.mutation.ts +9 -0
- package/templates/apps/api-backend/package.json +12 -8
- package/templates/apps/api-backend/queries/notes.query.ts +30 -8
- package/templates/apps/api-backend-deactivation/actions/users.get.action.ts +14 -0
- package/templates/apps/api-backend-deactivation/mutations/users.create.mutation.ts +8 -0
- package/templates/apps/api-backend-deactivation/mutations/users.deactivate.mutation.ts +10 -0
- package/templates/apps/api-backend-deactivation/package.json +8 -7
- package/templates/apps/api-backend-mail/actions/sendWelcome.action.ts +17 -0
- package/templates/apps/api-backend-mail/mutations/notes.create.mutation.ts +9 -0
- package/templates/apps/api-backend-mail/package.json +9 -8
- package/templates/apps/api-backend-mail/queries/notes.query.ts +30 -8
- package/templates/apps/api-backend-mariadb/.env.example +14 -0
- package/templates/apps/api-backend-mariadb/mutations/notes.create.mutation.ts +9 -0
- package/templates/apps/api-backend-mariadb/package.json +10 -9
- package/templates/apps/api-backend-mariadb/queries/notes.query.ts +30 -8
- package/templates/apps/api-backend-sqlite/.env.example +14 -0
- package/templates/apps/api-backend-sqlite/mutations/notes.create.mutation.ts +9 -0
- package/templates/apps/api-backend-sqlite/package.json +9 -8
- package/templates/apps/api-backend-sqlite/queries/notes.query.ts +30 -8
- package/templates/apps/api-backend-storage/actions/uploadAvatar.action.ts +13 -0
- package/templates/apps/api-backend-storage/actions/uploadDocument.action.ts +12 -0
- package/templates/apps/api-backend-storage/mutations/notes.create.mutation.ts +9 -0
- package/templates/apps/api-backend-storage/package.json +9 -8
- package/templates/apps/api-backend-storage/queries/notes.query.ts +30 -8
- package/templates/apps/api-cms/actions/content.get.action.ts +7 -0
- package/templates/apps/api-cms/actions/content.types.action.ts +6 -0
- package/templates/apps/api-cms/actions/me.action.ts +13 -0
- package/templates/apps/api-cms/app.config.ts +19 -0
- package/templates/apps/api-cms/authz.ts +63 -0
- package/templates/apps/api-cms/mutations/content.publish.mutation.ts +10 -0
- package/templates/apps/api-cms/mutations/content.saveDraft.mutation.ts +10 -0
- package/templates/apps/api-cms/mutations/content.unpublish.mutation.ts +5 -0
- package/templates/apps/api-cms/package.json +11 -10
- package/templates/apps/api-cms/queries/content.list.query.ts +23 -7
- package/templates/apps/api-cms/tests/accessDecisions.test.ts +121 -0
- package/templates/apps/api-cms/tests/content.descriptors.test.ts +8 -4
- package/templates/apps/api-collab/mutations/documents.create.mutation.ts +8 -0
- package/templates/apps/api-collab/mutations/documents.setBody.mutation.ts +13 -0
- package/templates/apps/api-collab/package.json +9 -8
- package/templates/apps/api-collab/queries/documents.query.ts +19 -7
- package/templates/apps/api-data-advanced/package.json +9 -8
- package/templates/apps/api-data-advanced/queries/authors.withBooks.query.ts +12 -0
- package/templates/apps/api-data-advanced/queries/books.search.query.ts +9 -0
- package/templates/apps/api-durable/mutations/orders.approve.mutation.ts +17 -0
- package/templates/apps/api-durable/mutations/orders.place.mutation.ts +9 -0
- package/templates/apps/api-durable/package.json +9 -8
- package/templates/apps/api-feature-flags/actions/notes.export.action.ts +16 -0
- package/templates/apps/api-feature-flags/mutations/notes.create.mutation.ts +12 -0
- package/templates/apps/api-feature-flags/package.json +10 -9
- package/templates/apps/api-governance/README.md +30 -8
- package/templates/apps/api-governance/actions/profiles.get.action.server.ts +17 -1
- package/templates/apps/api-governance/actions/profiles.get.action.ts +29 -4
- package/templates/apps/api-governance/database/schema.ts +16 -4
- package/templates/apps/api-governance/mutations/profiles.create.mutation.ts +12 -0
- package/templates/apps/api-governance/package.json +9 -8
- package/templates/apps/api-kv/actions/sync.pull.action.ts +15 -0
- package/templates/apps/api-kv/actions/sync.reset.action.ts +13 -0
- package/templates/apps/api-kv/actions/sync.status.action.ts +7 -0
- package/templates/apps/api-kv/package.json +9 -8
- package/templates/apps/api-kv/queries/events.list.query.ts +19 -8
- package/templates/apps/api-moderation/mutations/comments.create.mutation.ts +11 -0
- package/templates/apps/api-moderation/mutations/posts.create.mutation.ts +13 -0
- package/templates/apps/api-moderation/package.json +9 -8
- package/templates/apps/api-observability/mutations/notes.create.mutation.ts +8 -0
- package/templates/apps/api-observability/package.json +9 -8
- package/templates/apps/api-observability/queries/notes.list.query.ts +13 -0
- package/templates/apps/api-ratelimit/mutations/notes.create.mutation.ts +14 -0
- package/templates/apps/api-ratelimit/package.json +9 -8
- package/templates/apps/api-rbac/package.json +9 -8
- package/templates/apps/api-rest/package.json +8 -7
- package/templates/apps/api-saas/mutations/projects.create.mutation.ts +13 -0
- package/templates/apps/api-saas/package.json +12 -11
- package/templates/apps/api-saas/queries/projects.list.query.ts +11 -0
- package/templates/apps/api-saas-starter/actions/me.action.ts +13 -0
- package/templates/apps/api-saas-starter/app.config.ts +19 -0
- package/templates/apps/api-saas-starter/authz.ts +75 -0
- package/templates/apps/api-saas-starter/mutations/invites.create.mutation.ts +10 -0
- package/templates/apps/api-saas-starter/mutations/projects.create.mutation.ts +9 -0
- package/templates/apps/api-saas-starter/package.json +15 -11
- package/templates/apps/api-saas-starter/queries/invites.list.query.ts +19 -8
- package/templates/apps/api-saas-starter/queries/projects.list.query.ts +18 -7
- package/templates/apps/api-saas-starter/tests/accessDecisions.test.ts +135 -0
- package/templates/apps/api-search/mutations/articles.create.mutation.ts +14 -0
- package/templates/apps/api-search/package.json +9 -8
- package/templates/apps/api-search/queries/articles.list.query.ts +21 -8
- package/templates/apps/api-status/README.md +10 -3
- package/templates/apps/api-status/app.config.ts +8 -3
- package/templates/apps/api-status/authz.ts +5 -3
- package/templates/apps/api-status/package.json +9 -8
- package/templates/apps/api-status/queries/components.list.query.ts +14 -6
- package/templates/apps/api-status/queries/incidents.live.query.ts +23 -10
- package/templates/apps/api-status/queries/updates.list.query.ts +16 -9
- package/templates/apps/api-status/tests/status.test.ts +9 -1
- package/templates/apps/api-versioning/actions/documents.asOf.action.ts +12 -0
- package/templates/apps/api-versioning/actions/documents.history.action.ts +13 -0
- package/templates/apps/api-versioning/mutations/documents.create.mutation.ts +9 -0
- package/templates/apps/api-versioning/mutations/documents.update.mutation.ts +12 -0
- package/templates/apps/api-versioning/package.json +9 -8
- package/templates/apps/api-webhooks/mutations/orders.fulfill.mutation.ts +16 -0
- package/templates/apps/api-webhooks/package.json +10 -9
- package/templates/apps/api-webhooks/queries/orders.list.query.ts +10 -0
- package/templates/apps/changelog/package.json +8 -6
- package/templates/apps/edge-functions/package.json +2 -2
- package/templates/apps/frontend-admin/package.json +10 -8
- package/templates/apps/frontend-admin/src/lib/admin.ts +20 -9
- package/templates/apps/frontend-admin/src/locales/de.ts +11 -1
- package/templates/apps/frontend-admin/src/locales/en.ts +13 -1
- package/templates/apps/frontend-admin/src/pages/admin/[entity]/page.tsx +65 -22
- package/templates/apps/frontend-admin/src/pages/admin/entity.test.tsx +130 -23
- package/templates/apps/frontend-admin/src/pages/admin/layout.tsx +3 -2
- package/templates/apps/frontend-admin/src/pages/admin/page.test.tsx +19 -2
- package/templates/apps/frontend-admin/src/pages/admin/page.tsx +9 -4
- package/templates/apps/frontend-app/app.config.ts +4 -3
- package/templates/apps/frontend-app/package.json +11 -8
- package/templates/apps/frontend-app/src/lib/api.ts +25 -0
- package/templates/apps/frontend-app/src/pages/page.test.tsx +130 -82
- package/templates/apps/frontend-app/src/pages/page.tsx +14 -18
- package/templates/apps/frontend-auth/package.json +10 -8
- package/templates/apps/frontend-blank/package.json +9 -7
- package/templates/apps/frontend-cms/package.json +11 -9
- package/templates/apps/frontend-collab/package.json +12 -9
- package/templates/apps/frontend-collab/src/pages/page.test.tsx +122 -78
- package/templates/apps/frontend-contact/package.json +9 -7
- package/templates/apps/frontend-dashboard/package.json +9 -7
- package/templates/apps/frontend-docs/package.json +9 -7
- package/templates/apps/frontend-i18n/package.json +8 -6
- package/templates/apps/frontend-landing/package.json +9 -7
- package/templates/apps/frontend-portal/package.json +10 -8
- package/templates/apps/frontend-saas/app.config.ts +10 -6
- package/templates/apps/frontend-saas/package.json +10 -8
- package/templates/apps/frontend-saas/src/lib/api.ts +27 -32
- package/templates/apps/frontend-saas/src/pages/dashboard/billing/page.tsx +7 -8
- package/templates/apps/frontend-saas/src/pages/dashboard/page.test.tsx +27 -3
- package/templates/apps/frontend-saas/src/pages/dashboard/page.tsx +4 -4
- package/templates/apps/frontend-saas/src/pages/dashboard/team/page.tsx +3 -4
- package/templates/apps/frontend-spa/package.json +9 -7
- package/templates/apps/frontend-ssr/package.json +9 -7
- package/templates/apps/frontend-ssr-api/package.json +10 -8
- package/templates/apps/frontend-static-blog/package.json +8 -6
- package/templates/apps/frontend-status/package.json +10 -8
- package/templates/apps/mobile-app/README.md +1 -0
- package/templates/apps/mobile-app/package.json +4 -2
- package/templates/apps/mobile-app/src/app/index.tsx +22 -12
- package/templates/apps/mobile-app/src/app/orders/[id].tsx +1 -1
- package/templates/apps/mobile-app/src/lib/api.ts +34 -0
- package/templates/apps/mobile-app/voltro.mobile.ts +4 -2
- package/templates/baselines/bare/.env.example +14 -0
- package/templates/baselines/bare/baseline.json +4 -4
- package/templates/baselines/compose/.env.example +14 -0
- package/templates/baselines/compose/README.md +1 -1
- package/templates/baselines/compose/baseline.json +5 -5
- package/templates/baselines/compose-mariadb/.env.example +14 -0
- package/templates/baselines/compose-mariadb/README.md +1 -1
- package/templates/baselines/compose-mariadb/baseline.json +5 -5
- package/templates/baselines/helm/.env.example +14 -0
- package/templates/baselines/helm/baseline.json +4 -4
- package/dist/apiBuild-C-x9YacA.js +0 -2
- package/dist/appGraph-CvQCte0z.js +0 -2
- package/dist/checkCommand-DRovTKza.js +0 -2
- package/dist/commands-CJfepbm4.js +0 -11541
- package/dist/dbCommand-b1gum4td.js +0 -2
- package/dist/dev-iiMtlkfs.js +0 -3
- package/dist/devActivity-BhIu6ncs.js +0 -159
- package/dist/frameworkTableAssembly-BwIrO5nv.js +0 -638
- package/dist/frameworkTableAssembly-D-EebUQX.js +0 -2
- package/dist/inspect-mmBuRXmy.js +0 -2
- package/dist/manifestBuild-Dj8Jjoto.js +0 -2
- package/dist/seedRunner-Bqxgp7HZ.js +0 -230
- package/dist/serveCommand-DdaM4Hup.js +0 -1608
- package/dist/start-C0koT0UO.js +0 -1084
- /package/templates/apps/api-ai/actions/{summarize.action.server.tsx → summarize.action.server.ts} +0 -0
|
@@ -1,11 +1,15 @@
|
|
|
1
1
|
// `/` — the notes page. Auto-mapped from src/pages/index.tsx by the
|
|
2
2
|
// framework's file-convention page discovery.
|
|
3
3
|
//
|
|
4
|
-
// THIS is the reactive end-to-end loop. `useSubscription('
|
|
5
|
-
//
|
|
6
|
-
// `
|
|
7
|
-
//
|
|
8
|
-
//
|
|
4
|
+
// THIS is the reactive end-to-end loop. `useSubscription('notes.list')`
|
|
5
|
+
// opens a live WebSocket subscription to the api's `notes.list` query;
|
|
6
|
+
// `useMutation('notes.create')` invokes the `notes.create` mutation. When the
|
|
7
|
+
// mutation commits, the server pushes a delta and this list re-renders — no
|
|
8
|
+
// refetch, no polling.
|
|
9
|
+
//
|
|
10
|
+
// Both come from `src/lib/api.ts`, which binds them ONCE to this api's
|
|
11
|
+
// generated procedure map — so the tag autocompletes, a typo is a compile
|
|
12
|
+
// error, and the row type is inferred rather than declared here.
|
|
9
13
|
//
|
|
10
14
|
// Auto-optimistic: `notes.create` declares `target: { table: 'notes', op:
|
|
11
15
|
// 'insert' }` server-side, so the framework prepends an optimistic row to
|
|
@@ -13,11 +17,11 @@
|
|
|
13
17
|
// row (or reverts it) when the rpc resolves. There is no `.withOptimistic`,
|
|
14
18
|
// no `useOptimistic`, no `startTransition` — just `create.mutate(input)`.
|
|
15
19
|
|
|
16
|
-
import { useMutation, useSubscription } from '@voltro/client'
|
|
17
20
|
import { useState, type FormEvent, type ReactNode } from 'react'
|
|
18
21
|
import type { PageMeta } from '@voltro/web'
|
|
19
22
|
import { T, useTFn } from '@voltro/i18n'
|
|
20
23
|
import { getCatalog } from '../locales'
|
|
24
|
+
import { useMutation, useSubscription } from '../lib/api'
|
|
21
25
|
|
|
22
26
|
// Locale-aware tab title: @voltro/web resolves meta({ locale }) from the
|
|
23
27
|
// active locale (the `voltro:locale` cookie in this cookie-i18n app).
|
|
@@ -31,21 +35,13 @@ export const meta = ({ locale }: { readonly locale: string }): PageMeta => ({
|
|
|
31
35
|
// submitted tenantId matches the caller's (a typed TenantMismatch otherwise).
|
|
32
36
|
const TENANT = 'acme'
|
|
33
37
|
|
|
34
|
-
interface Note {
|
|
35
|
-
readonly id: string
|
|
36
|
-
readonly title: string
|
|
37
|
-
readonly body: string
|
|
38
|
-
readonly done: boolean
|
|
39
|
-
readonly tenantId: string
|
|
40
|
-
readonly createdAt: Date
|
|
41
|
-
readonly optimistic?: boolean
|
|
42
|
-
}
|
|
43
|
-
|
|
44
38
|
const IndexPage = (): ReactNode => {
|
|
39
|
+
// No row `interface` and no `<T>`: the shape comes from `notes.list`'s own
|
|
40
|
+
// output schema, including the client's `optimistic` marker.
|
|
45
41
|
const { data, revision, emittedAt, error, pendingPatches } =
|
|
46
|
-
useSubscription
|
|
42
|
+
useSubscription('notes.list')
|
|
47
43
|
|
|
48
|
-
const create = useMutation
|
|
44
|
+
const create = useMutation('notes.create')
|
|
49
45
|
const t = useTFn()
|
|
50
46
|
|
|
51
47
|
const notes = data ?? []
|
|
@@ -12,21 +12,23 @@
|
|
|
12
12
|
"test": "voltro test"
|
|
13
13
|
},
|
|
14
14
|
"dependencies": {
|
|
15
|
-
"@{{projectName}}/api": "0.
|
|
16
|
-
"@voltro/cli": "0.
|
|
17
|
-
"@voltro/client": "0.
|
|
18
|
-
"@voltro/env": "0.
|
|
19
|
-
"@voltro/i18n": "0.
|
|
20
|
-
"@voltro/ui-shadcn": "0.
|
|
21
|
-
"@voltro/web": "0.
|
|
15
|
+
"@{{projectName}}/api": "0.35.0",
|
|
16
|
+
"@voltro/cli": "0.35.0",
|
|
17
|
+
"@voltro/client": "0.35.0",
|
|
18
|
+
"@voltro/env": "0.35.0",
|
|
19
|
+
"@voltro/i18n": "0.35.0",
|
|
20
|
+
"@voltro/ui-shadcn": "0.35.0",
|
|
21
|
+
"@voltro/web": "0.35.0",
|
|
22
22
|
"react": "^19.0.0",
|
|
23
23
|
"react-dom": "^19.0.0"
|
|
24
24
|
},
|
|
25
25
|
"devDependencies": {
|
|
26
|
-
"@voltro/devtools": "0.
|
|
26
|
+
"@voltro/devtools": "0.35.0",
|
|
27
27
|
"@types/react": "^19.0.0",
|
|
28
28
|
"@types/react-dom": "^19.0.0",
|
|
29
|
+
"jsdom": "^30.0.0",
|
|
29
30
|
"typescript": "^6.0.3",
|
|
31
|
+
"@vitest/coverage-v8": "^4.1.10",
|
|
30
32
|
"vitest": "^4.1.10"
|
|
31
33
|
}
|
|
32
34
|
}
|
|
@@ -12,20 +12,22 @@
|
|
|
12
12
|
"typecheck": "tsc --noEmit"
|
|
13
13
|
},
|
|
14
14
|
"dependencies": {
|
|
15
|
-
"@voltro/cli": "0.
|
|
16
|
-
"@voltro/client": "0.
|
|
17
|
-
"@voltro/env": "0.
|
|
18
|
-
"@voltro/i18n": "0.
|
|
19
|
-
"@voltro/ui-shadcn": "0.
|
|
20
|
-
"@voltro/web": "0.
|
|
15
|
+
"@voltro/cli": "0.35.0",
|
|
16
|
+
"@voltro/client": "0.35.0",
|
|
17
|
+
"@voltro/env": "0.35.0",
|
|
18
|
+
"@voltro/i18n": "0.35.0",
|
|
19
|
+
"@voltro/ui-shadcn": "0.35.0",
|
|
20
|
+
"@voltro/web": "0.35.0",
|
|
21
21
|
"react": "^19.0.0",
|
|
22
22
|
"react-dom": "^19.0.0"
|
|
23
23
|
},
|
|
24
24
|
"devDependencies": {
|
|
25
|
-
"@voltro/devtools": "0.
|
|
25
|
+
"@voltro/devtools": "0.35.0",
|
|
26
26
|
"@types/react": "^19.0.0",
|
|
27
27
|
"@types/react-dom": "^19.0.0",
|
|
28
|
+
"jsdom": "^30.0.0",
|
|
28
29
|
"typescript": "^6.0.3",
|
|
30
|
+
"@vitest/coverage-v8": "^4.1.10",
|
|
29
31
|
"vitest": "^4.1.10"
|
|
30
32
|
}
|
|
31
33
|
}
|
|
@@ -12,22 +12,24 @@
|
|
|
12
12
|
"test": "voltro test"
|
|
13
13
|
},
|
|
14
14
|
"dependencies": {
|
|
15
|
-
"@{{projectName}}/api": "0.
|
|
16
|
-
"@voltro/cli": "0.
|
|
17
|
-
"@voltro/client": "0.
|
|
18
|
-
"@voltro/cms": "0.
|
|
19
|
-
"@voltro/env": "0.
|
|
20
|
-
"@voltro/i18n": "0.
|
|
21
|
-
"@voltro/ui-shadcn": "0.
|
|
22
|
-
"@voltro/web": "0.
|
|
15
|
+
"@{{projectName}}/api": "0.35.0",
|
|
16
|
+
"@voltro/cli": "0.35.0",
|
|
17
|
+
"@voltro/client": "0.35.0",
|
|
18
|
+
"@voltro/cms": "0.35.0",
|
|
19
|
+
"@voltro/env": "0.35.0",
|
|
20
|
+
"@voltro/i18n": "0.35.0",
|
|
21
|
+
"@voltro/ui-shadcn": "0.35.0",
|
|
22
|
+
"@voltro/web": "0.35.0",
|
|
23
23
|
"react": "^19.0.0",
|
|
24
24
|
"react-dom": "^19.0.0"
|
|
25
25
|
},
|
|
26
26
|
"devDependencies": {
|
|
27
|
-
"@voltro/devtools": "0.
|
|
27
|
+
"@voltro/devtools": "0.35.0",
|
|
28
28
|
"@types/react": "^19.0.0",
|
|
29
29
|
"@types/react-dom": "^19.0.0",
|
|
30
|
+
"jsdom": "^30.0.0",
|
|
30
31
|
"typescript": "^6.0.3",
|
|
32
|
+
"@vitest/coverage-v8": "^4.1.10",
|
|
31
33
|
"vitest": "^4.1.10"
|
|
32
34
|
}
|
|
33
35
|
}
|
|
@@ -12,22 +12,25 @@
|
|
|
12
12
|
"typecheck": "tsc --noEmit"
|
|
13
13
|
},
|
|
14
14
|
"dependencies": {
|
|
15
|
-
"@{{projectName}}/api": "0.
|
|
16
|
-
"@voltro/cli": "0.
|
|
17
|
-
"@voltro/client": "0.
|
|
18
|
-
"@voltro/env": "0.
|
|
19
|
-
"@voltro/i18n": "0.
|
|
20
|
-
"@voltro/local-first": "0.
|
|
21
|
-
"@voltro/ui-shadcn": "0.
|
|
22
|
-
"@voltro/web": "0.
|
|
15
|
+
"@{{projectName}}/api": "0.35.0",
|
|
16
|
+
"@voltro/cli": "0.35.0",
|
|
17
|
+
"@voltro/client": "0.35.0",
|
|
18
|
+
"@voltro/env": "0.35.0",
|
|
19
|
+
"@voltro/i18n": "0.35.0",
|
|
20
|
+
"@voltro/local-first": "0.35.0",
|
|
21
|
+
"@voltro/ui-shadcn": "0.35.0",
|
|
22
|
+
"@voltro/web": "0.35.0",
|
|
23
23
|
"react": "^19.0.0",
|
|
24
24
|
"react-dom": "^19.0.0"
|
|
25
25
|
},
|
|
26
26
|
"devDependencies": {
|
|
27
|
-
"@voltro/devtools": "0.
|
|
27
|
+
"@voltro/devtools": "0.35.0",
|
|
28
|
+
"@voltro/testing": "0.35.0",
|
|
28
29
|
"@types/react": "^19.0.0",
|
|
29
30
|
"@types/react-dom": "^19.0.0",
|
|
31
|
+
"jsdom": "^30.0.0",
|
|
30
32
|
"typescript": "^6.0.3",
|
|
33
|
+
"@vitest/coverage-v8": "^4.1.10",
|
|
31
34
|
"vitest": "^4.1.10"
|
|
32
35
|
}
|
|
33
36
|
}
|
|
@@ -1,55 +1,69 @@
|
|
|
1
1
|
// @vitest-environment jsdom
|
|
2
2
|
//
|
|
3
|
-
// `/` — the collaborative editor
|
|
4
|
-
//
|
|
5
|
-
//
|
|
6
|
-
//
|
|
7
|
-
//
|
|
8
|
-
//
|
|
9
|
-
|
|
10
|
-
|
|
3
|
+
// `/` — the collaborative editor, driven through `makeVoltroTestClient`
|
|
4
|
+
// (`@voltro/testing/client`) rather than a hand-rolled `vi.mock('@voltro/client')`.
|
|
5
|
+
//
|
|
6
|
+
// WHY THE HARNESS HERE and not a mock. This page is stateful: a local CRDT
|
|
7
|
+
// handle in a ref, seeded from the server body, folding every INCOMING body
|
|
8
|
+
// back in. A `vi.mock` can return one snapshot per mount, so the fold —
|
|
9
|
+
// the whole point of the page — was untestable, and the suite that replaced
|
|
10
|
+
// this one never pushed a second value into a mounted tree. `setSubscription`
|
|
11
|
+
// is a real server delta, so the last case below asserts convergence.
|
|
12
|
+
//
|
|
13
|
+
// Two other things fall out of it: the real `@voltro/client` hooks run (so a
|
|
14
|
+
// change in their loading/error semantics is caught here instead of being
|
|
15
|
+
// re-implemented by the mock), and the page can be imported statically —
|
|
16
|
+
// `await import('./page')` only existed to sequence around `vi.mock`'s hoist.
|
|
17
|
+
//
|
|
18
|
+
// `@voltro/local-first` is NOT faked either: the editor's real CRDT handle
|
|
19
|
+
// decodes the seeded body and turns keystrokes into encoded updates, which is
|
|
20
|
+
// the behaviour worth asserting.
|
|
21
|
+
|
|
22
|
+
import { afterEach, beforeEach, describe, expect, test } from 'vitest'
|
|
11
23
|
import { act, createElement, type ReactNode } from 'react'
|
|
12
24
|
import { createRoot, type Root } from 'react-dom/client'
|
|
13
25
|
import { I18nProvider } from '@voltro/i18n'
|
|
14
|
-
import { crdtText } from '@voltro/local-first'
|
|
26
|
+
import { crdtText, type CrdtState } from '@voltro/local-first'
|
|
27
|
+
import { makeVoltroTestClient, type VoltroTestClient } from '@voltro/testing/client'
|
|
15
28
|
import enCatalog from '../locales/en'
|
|
29
|
+
import IndexPage from './page'
|
|
16
30
|
|
|
17
|
-
|
|
18
|
-
data: unknown
|
|
19
|
-
revision?: number
|
|
20
|
-
error?: unknown
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
const useSubscription = vi.fn<() => SubState>()
|
|
24
|
-
const createMutate = vi.fn<(input: unknown) => Promise<unknown>>()
|
|
25
|
-
const setBodyMutate = vi.fn<(input: unknown) => Promise<unknown>>()
|
|
31
|
+
;(globalThis as { IS_REACT_ACT_ENVIRONMENT?: boolean }).IS_REACT_ACT_ENVIRONMENT = true
|
|
26
32
|
|
|
27
|
-
|
|
28
|
-
const useMutation = vi.fn((_api: unknown, tag: unknown) =>
|
|
29
|
-
tag === 'documents.create'
|
|
30
|
-
? { mutate: createMutate, pending: false, error: undefined, data: undefined }
|
|
31
|
-
: { mutate: setBodyMutate, pending: false, error: undefined, data: undefined },
|
|
32
|
-
)
|
|
33
|
+
const LIST = 'documents.list'
|
|
33
34
|
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
}))
|
|
35
|
+
let container: HTMLDivElement
|
|
36
|
+
let root: Root
|
|
37
|
+
let client: VoltroTestClient
|
|
38
38
|
|
|
39
|
-
|
|
39
|
+
/** A CRDT state holding `text`, from a fresh document. */
|
|
40
|
+
const bodyWith = (text: string): CrdtState => crdtText().insert(0, text).encode()
|
|
40
41
|
|
|
41
|
-
|
|
42
|
+
/** A REMOTE edit derived from `base`, so merging it back converges instead of
|
|
43
|
+
* interleaving two independently-created runs of the same characters. */
|
|
44
|
+
const remoteEditOf = (base: CrdtState, at: number, insert: string): CrdtState =>
|
|
45
|
+
crdtText().merge(base).insert(at, insert).encode()
|
|
42
46
|
|
|
43
|
-
|
|
44
|
-
|
|
47
|
+
const docRow = (over: Partial<{ id: string; title: string; body: CrdtState | null }> = {}) => ({
|
|
48
|
+
id: over.id ?? 'doc_1',
|
|
49
|
+
title: over.title ?? 'Shared document',
|
|
50
|
+
body: over.body ?? null,
|
|
51
|
+
tenantId: 'acme',
|
|
52
|
+
createdAt: new Date(0),
|
|
53
|
+
})
|
|
45
54
|
|
|
46
|
-
const render = (
|
|
55
|
+
const render = (): void => {
|
|
47
56
|
container = document.createElement('div')
|
|
48
57
|
document.body.appendChild(container)
|
|
49
58
|
act(() => {
|
|
50
59
|
root = createRoot(container)
|
|
51
60
|
root.render(
|
|
52
|
-
createElement(I18nProvider, {
|
|
61
|
+
createElement(I18nProvider, {
|
|
62
|
+
locale: 'en',
|
|
63
|
+
messages: enCatalog,
|
|
64
|
+
defaultLocale: 'en',
|
|
65
|
+
children: createElement(client.Provider, null, createElement(IndexPage) as ReactNode),
|
|
66
|
+
}),
|
|
53
67
|
)
|
|
54
68
|
})
|
|
55
69
|
}
|
|
@@ -62,26 +76,20 @@ const setTextarea = (el: HTMLTextAreaElement, value: string): void => {
|
|
|
62
76
|
})
|
|
63
77
|
}
|
|
64
78
|
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
const
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
}
|
|
79
|
+
const textarea = (): HTMLTextAreaElement => container.querySelector('textarea') as HTMLTextAreaElement
|
|
80
|
+
|
|
81
|
+
/** The harness with both writes wired. Handlers return void; the assertions
|
|
82
|
+
* read `client.calls`, which records tag + input in order. */
|
|
83
|
+
const harness = (subscriptions: Readonly<Record<string, unknown>> = {}): VoltroTestClient =>
|
|
84
|
+
makeVoltroTestClient({
|
|
85
|
+
subscriptions,
|
|
86
|
+
mutations: {
|
|
87
|
+
'documents.create': () => undefined,
|
|
88
|
+
'documents.setBody': () => undefined,
|
|
89
|
+
},
|
|
90
|
+
})
|
|
76
91
|
|
|
77
|
-
beforeEach(() => {
|
|
78
|
-
useSubscription.mockReset()
|
|
79
|
-
createMutate.mockReset()
|
|
80
|
-
createMutate.mockResolvedValue(undefined)
|
|
81
|
-
setBodyMutate.mockReset()
|
|
82
|
-
setBodyMutate.mockResolvedValue(undefined)
|
|
83
|
-
useMutation.mockClear()
|
|
84
|
-
})
|
|
92
|
+
beforeEach(() => { client = harness() })
|
|
85
93
|
|
|
86
94
|
afterEach(() => {
|
|
87
95
|
if (root) act(() => root.unmount())
|
|
@@ -90,24 +98,25 @@ afterEach(() => {
|
|
|
90
98
|
})
|
|
91
99
|
|
|
92
100
|
describe('collab editor — subscription states', () => {
|
|
93
|
-
test('shows the loading hint before the first snapshot
|
|
94
|
-
|
|
95
|
-
|
|
101
|
+
test('shows the loading hint before the first snapshot', () => {
|
|
102
|
+
// A tag with NO fixture is the harness's cold state — the real thing a
|
|
103
|
+
// component sees before the first delta arrives.
|
|
104
|
+
render()
|
|
96
105
|
expect(container.textContent).toContain('loading…')
|
|
97
106
|
expect(container.querySelector('textarea')).toBeNull()
|
|
98
107
|
})
|
|
99
108
|
|
|
100
109
|
test('shows the empty state + create button once a snapshot arrives with no documents', () => {
|
|
101
|
-
|
|
102
|
-
render(
|
|
110
|
+
client = harness({ [LIST]: [] })
|
|
111
|
+
render()
|
|
103
112
|
expect(container.textContent).toContain('No document yet')
|
|
104
113
|
expect(container.querySelector('button')).not.toBeNull()
|
|
105
114
|
expect(container.querySelector('textarea')).toBeNull()
|
|
106
115
|
})
|
|
107
116
|
|
|
108
117
|
test('renders the error banner when the subscription errors', () => {
|
|
109
|
-
|
|
110
|
-
|
|
118
|
+
render()
|
|
119
|
+
act(() => { client.failSubscription(LIST, 'boom') })
|
|
111
120
|
expect(container.textContent).toContain('subscription error')
|
|
112
121
|
expect(container.textContent).toContain('boom')
|
|
113
122
|
})
|
|
@@ -115,36 +124,71 @@ describe('collab editor — subscription states', () => {
|
|
|
115
124
|
|
|
116
125
|
describe('collab editor — create', () => {
|
|
117
126
|
test('clicking Create document calls documents.create with the tenant + a title', async () => {
|
|
118
|
-
|
|
119
|
-
render(
|
|
127
|
+
client = harness({ [LIST]: [] })
|
|
128
|
+
render()
|
|
120
129
|
const button = container.querySelector('button') as HTMLButtonElement
|
|
121
130
|
await act(async () => {
|
|
122
131
|
button.dispatchEvent(new MouseEvent('click', { bubbles: true }))
|
|
123
132
|
})
|
|
124
|
-
expect(
|
|
125
|
-
|
|
133
|
+
expect(client.calls).toEqual([
|
|
134
|
+
{ kind: 'mutation', tag: 'documents.create', input: { tenantId: 'acme', title: 'Shared document' } },
|
|
135
|
+
])
|
|
126
136
|
})
|
|
127
137
|
})
|
|
128
138
|
|
|
129
139
|
describe('collab editor — editing a document', () => {
|
|
130
140
|
test('binds the textarea to the decoded CRDT body', () => {
|
|
131
|
-
|
|
132
|
-
render(
|
|
133
|
-
|
|
134
|
-
expect(textarea).
|
|
135
|
-
expect(textarea.value).toBe('Hello')
|
|
141
|
+
client = harness({ [LIST]: [docRow({ body: bodyWith('Hello') })] })
|
|
142
|
+
render()
|
|
143
|
+
expect(textarea()).not.toBeNull()
|
|
144
|
+
expect(textarea().value).toBe('Hello')
|
|
136
145
|
expect(container.textContent).toContain('Shared document')
|
|
137
146
|
})
|
|
138
147
|
|
|
139
148
|
test('typing sends an encoded CRDT update via documents.setBody', () => {
|
|
140
|
-
|
|
141
|
-
render(
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
expect(
|
|
149
|
+
client = harness({ [LIST]: [docRow({ body: bodyWith('Hello') })] })
|
|
150
|
+
render()
|
|
151
|
+
setTextarea(textarea(), 'Hello!')
|
|
152
|
+
|
|
153
|
+
expect(client.calls).toHaveLength(1)
|
|
154
|
+
const call = client.calls[0]!
|
|
155
|
+
expect(call.tag).toBe('documents.setBody')
|
|
156
|
+
const input = call.input as { id: string; update: unknown }
|
|
157
|
+
expect(input.id).toBe('doc_1')
|
|
158
|
+
expect(input.update).toBeInstanceOf(Uint8Array)
|
|
159
|
+
})
|
|
160
|
+
|
|
161
|
+
// The case the hand-rolled mock could not express, and the page's whole
|
|
162
|
+
// reason to exist: a body edited in ANOTHER tab arrives as a delta, and the
|
|
163
|
+
// local handle folds it in without remounting the editor.
|
|
164
|
+
test('a remote edit pushed by the server converges into the open editor', () => {
|
|
165
|
+
const base = bodyWith('Hello')
|
|
166
|
+
client = harness({ [LIST]: [docRow({ body: base })] })
|
|
167
|
+
render()
|
|
168
|
+
expect(textarea().value).toBe('Hello')
|
|
169
|
+
|
|
170
|
+
act(() => {
|
|
171
|
+
client.setSubscription(LIST, [docRow({ body: remoteEditOf(base, 5, ' world') })])
|
|
172
|
+
})
|
|
173
|
+
|
|
174
|
+
expect(textarea().value).toBe('Hello world')
|
|
175
|
+
// A fold is not a write — nothing is echoed back to the server.
|
|
176
|
+
expect(client.calls).toEqual([])
|
|
177
|
+
})
|
|
178
|
+
|
|
179
|
+
test('a local edit survives a concurrent remote edit — both are in the merged text', () => {
|
|
180
|
+
const base = bodyWith('Hello')
|
|
181
|
+
client = harness({ [LIST]: [docRow({ body: base })] })
|
|
182
|
+
render()
|
|
183
|
+
setTextarea(textarea(), 'Hello!')
|
|
184
|
+
expect(textarea().value).toBe('Hello!')
|
|
185
|
+
|
|
186
|
+
// The other tab branched from the SAME base and appended elsewhere.
|
|
187
|
+
act(() => {
|
|
188
|
+
client.setSubscription(LIST, [docRow({ body: remoteEditOf(base, 0, 'Oh, ') })])
|
|
189
|
+
})
|
|
190
|
+
|
|
191
|
+
expect(textarea().value).toContain('Oh, ')
|
|
192
|
+
expect(textarea().value).toContain('!')
|
|
149
193
|
})
|
|
150
194
|
})
|
|
@@ -15,21 +15,23 @@
|
|
|
15
15
|
},
|
|
16
16
|
"dependencies": {
|
|
17
17
|
"@effect/platform": "^0.97.0",
|
|
18
|
-
"@voltro/cli": "0.
|
|
19
|
-
"@voltro/client": "0.
|
|
20
|
-
"@voltro/env": "0.
|
|
21
|
-
"@voltro/i18n": "0.
|
|
22
|
-
"@voltro/serverless": "0.
|
|
23
|
-
"@voltro/web": "0.
|
|
18
|
+
"@voltro/cli": "0.35.0",
|
|
19
|
+
"@voltro/client": "0.35.0",
|
|
20
|
+
"@voltro/env": "0.35.0",
|
|
21
|
+
"@voltro/i18n": "0.35.0",
|
|
22
|
+
"@voltro/serverless": "0.35.0",
|
|
23
|
+
"@voltro/web": "0.35.0",
|
|
24
24
|
"effect": "^3.22.0",
|
|
25
25
|
"react": "^19.0.0",
|
|
26
26
|
"react-dom": "^19.0.0"
|
|
27
27
|
},
|
|
28
28
|
"devDependencies": {
|
|
29
|
-
"@voltro/devtools": "0.
|
|
29
|
+
"@voltro/devtools": "0.35.0",
|
|
30
30
|
"@types/react": "^19.0.0",
|
|
31
31
|
"@types/react-dom": "^19.0.0",
|
|
32
|
+
"jsdom": "^30.0.0",
|
|
32
33
|
"typescript": "^6.0.3",
|
|
34
|
+
"@vitest/coverage-v8": "^4.1.10",
|
|
33
35
|
"vitest": "^4.1.10"
|
|
34
36
|
}
|
|
35
37
|
}
|
|
@@ -12,20 +12,22 @@
|
|
|
12
12
|
"test": "voltro test"
|
|
13
13
|
},
|
|
14
14
|
"dependencies": {
|
|
15
|
-
"@voltro/cli": "0.
|
|
16
|
-
"@voltro/client": "0.
|
|
17
|
-
"@voltro/env": "0.
|
|
18
|
-
"@voltro/i18n": "0.
|
|
19
|
-
"@voltro/ui-shadcn": "0.
|
|
20
|
-
"@voltro/web": "0.
|
|
15
|
+
"@voltro/cli": "0.35.0",
|
|
16
|
+
"@voltro/client": "0.35.0",
|
|
17
|
+
"@voltro/env": "0.35.0",
|
|
18
|
+
"@voltro/i18n": "0.35.0",
|
|
19
|
+
"@voltro/ui-shadcn": "0.35.0",
|
|
20
|
+
"@voltro/web": "0.35.0",
|
|
21
21
|
"react": "^19.0.0",
|
|
22
22
|
"react-dom": "^19.0.0"
|
|
23
23
|
},
|
|
24
24
|
"devDependencies": {
|
|
25
|
-
"@voltro/devtools": "0.
|
|
25
|
+
"@voltro/devtools": "0.35.0",
|
|
26
26
|
"@types/react": "^19.0.0",
|
|
27
27
|
"@types/react-dom": "^19.0.0",
|
|
28
|
+
"jsdom": "^30.0.0",
|
|
28
29
|
"typescript": "^6.0.3",
|
|
30
|
+
"@vitest/coverage-v8": "^4.1.10",
|
|
29
31
|
"vitest": "^4.1.10"
|
|
30
32
|
}
|
|
31
33
|
}
|
|
@@ -12,20 +12,22 @@
|
|
|
12
12
|
"test": "voltro test"
|
|
13
13
|
},
|
|
14
14
|
"dependencies": {
|
|
15
|
-
"@voltro/cli": "0.
|
|
16
|
-
"@voltro/client": "0.
|
|
17
|
-
"@voltro/env": "0.
|
|
18
|
-
"@voltro/i18n": "0.
|
|
19
|
-
"@voltro/ui-shadcn": "0.
|
|
20
|
-
"@voltro/web": "0.
|
|
15
|
+
"@voltro/cli": "0.35.0",
|
|
16
|
+
"@voltro/client": "0.35.0",
|
|
17
|
+
"@voltro/env": "0.35.0",
|
|
18
|
+
"@voltro/i18n": "0.35.0",
|
|
19
|
+
"@voltro/ui-shadcn": "0.35.0",
|
|
20
|
+
"@voltro/web": "0.35.0",
|
|
21
21
|
"react": "^19.0.0",
|
|
22
22
|
"react-dom": "^19.0.0"
|
|
23
23
|
},
|
|
24
24
|
"devDependencies": {
|
|
25
|
-
"@voltro/devtools": "0.
|
|
25
|
+
"@voltro/devtools": "0.35.0",
|
|
26
26
|
"@types/react": "^19.0.0",
|
|
27
27
|
"@types/react-dom": "^19.0.0",
|
|
28
|
+
"jsdom": "^30.0.0",
|
|
28
29
|
"typescript": "^6.0.3",
|
|
30
|
+
"@vitest/coverage-v8": "^4.1.10",
|
|
29
31
|
"vitest": "^4.1.10"
|
|
30
32
|
}
|
|
31
33
|
}
|
|
@@ -12,19 +12,21 @@
|
|
|
12
12
|
"test": "voltro test"
|
|
13
13
|
},
|
|
14
14
|
"dependencies": {
|
|
15
|
-
"@voltro/cli": "0.
|
|
16
|
-
"@voltro/client": "0.
|
|
17
|
-
"@voltro/env": "0.
|
|
18
|
-
"@voltro/i18n": "0.
|
|
19
|
-
"@voltro/web": "0.
|
|
15
|
+
"@voltro/cli": "0.35.0",
|
|
16
|
+
"@voltro/client": "0.35.0",
|
|
17
|
+
"@voltro/env": "0.35.0",
|
|
18
|
+
"@voltro/i18n": "0.35.0",
|
|
19
|
+
"@voltro/web": "0.35.0",
|
|
20
20
|
"react": "^19.0.0",
|
|
21
21
|
"react-dom": "^19.0.0"
|
|
22
22
|
},
|
|
23
23
|
"devDependencies": {
|
|
24
|
-
"@voltro/devtools": "0.
|
|
24
|
+
"@voltro/devtools": "0.35.0",
|
|
25
25
|
"@types/react": "^19.0.0",
|
|
26
26
|
"@types/react-dom": "^19.0.0",
|
|
27
|
+
"jsdom": "^30.0.0",
|
|
27
28
|
"typescript": "^6.0.3",
|
|
29
|
+
"@vitest/coverage-v8": "^4.1.10",
|
|
28
30
|
"vitest": "^4.1.10"
|
|
29
31
|
}
|
|
30
32
|
}
|
|
@@ -12,20 +12,22 @@
|
|
|
12
12
|
"typecheck": "tsc --noEmit"
|
|
13
13
|
},
|
|
14
14
|
"dependencies": {
|
|
15
|
-
"@voltro/cli": "0.
|
|
16
|
-
"@voltro/client": "0.
|
|
17
|
-
"@voltro/env": "0.
|
|
18
|
-
"@voltro/i18n": "0.
|
|
19
|
-
"@voltro/ui-shadcn": "0.
|
|
20
|
-
"@voltro/web": "0.
|
|
15
|
+
"@voltro/cli": "0.35.0",
|
|
16
|
+
"@voltro/client": "0.35.0",
|
|
17
|
+
"@voltro/env": "0.35.0",
|
|
18
|
+
"@voltro/i18n": "0.35.0",
|
|
19
|
+
"@voltro/ui-shadcn": "0.35.0",
|
|
20
|
+
"@voltro/web": "0.35.0",
|
|
21
21
|
"react": "^19.0.0",
|
|
22
22
|
"react-dom": "^19.0.0"
|
|
23
23
|
},
|
|
24
24
|
"devDependencies": {
|
|
25
|
-
"@voltro/devtools": "0.
|
|
25
|
+
"@voltro/devtools": "0.35.0",
|
|
26
26
|
"@types/react": "^19.0.0",
|
|
27
27
|
"@types/react-dom": "^19.0.0",
|
|
28
|
+
"jsdom": "^30.0.0",
|
|
28
29
|
"typescript": "^6.0.3",
|
|
30
|
+
"@vitest/coverage-v8": "^4.1.10",
|
|
29
31
|
"vitest": "^4.1.10"
|
|
30
32
|
}
|
|
31
33
|
}
|
|
@@ -12,21 +12,23 @@
|
|
|
12
12
|
"test": "voltro test"
|
|
13
13
|
},
|
|
14
14
|
"dependencies": {
|
|
15
|
-
"@{{projectName}}/api": "0.
|
|
16
|
-
"@voltro/cli": "0.
|
|
17
|
-
"@voltro/client": "0.
|
|
18
|
-
"@voltro/env": "0.
|
|
19
|
-
"@voltro/i18n": "0.
|
|
20
|
-
"@voltro/ui-shadcn": "0.
|
|
21
|
-
"@voltro/web": "0.
|
|
15
|
+
"@{{projectName}}/api": "0.35.0",
|
|
16
|
+
"@voltro/cli": "0.35.0",
|
|
17
|
+
"@voltro/client": "0.35.0",
|
|
18
|
+
"@voltro/env": "0.35.0",
|
|
19
|
+
"@voltro/i18n": "0.35.0",
|
|
20
|
+
"@voltro/ui-shadcn": "0.35.0",
|
|
21
|
+
"@voltro/web": "0.35.0",
|
|
22
22
|
"react": "^19.0.0",
|
|
23
23
|
"react-dom": "^19.0.0"
|
|
24
24
|
},
|
|
25
25
|
"devDependencies": {
|
|
26
|
-
"@voltro/devtools": "0.
|
|
26
|
+
"@voltro/devtools": "0.35.0",
|
|
27
27
|
"@types/react": "^19.0.0",
|
|
28
28
|
"@types/react-dom": "^19.0.0",
|
|
29
|
+
"jsdom": "^30.0.0",
|
|
29
30
|
"typescript": "^6.0.3",
|
|
31
|
+
"@vitest/coverage-v8": "^4.1.10",
|
|
30
32
|
"vitest": "^4.1.10"
|
|
31
33
|
}
|
|
32
34
|
}
|