@async/db 0.2.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 +167 -0
- package/README.md +431 -0
- package/SPEC.md +1429 -0
- package/db.config.example.mjs +128 -0
- package/dist/cli/args.d.ts +8 -0
- package/dist/cli/args.js +16 -0
- package/dist/cli/commands/create.d.ts +3 -0
- package/dist/cli/commands/create.js +13 -0
- package/dist/cli/commands/doctor.d.ts +3 -0
- package/dist/cli/commands/doctor.js +31 -0
- package/dist/cli/commands/generate.d.ts +6 -0
- package/dist/cli/commands/generate.js +24 -0
- package/dist/cli/commands/operations.d.ts +12 -0
- package/dist/cli/commands/operations.js +61 -0
- package/dist/cli/commands/schema.d.ts +11 -0
- package/dist/cli/commands/schema.js +1086 -0
- package/dist/cli/commands/serve.d.ts +9 -0
- package/dist/cli/commands/serve.js +18 -0
- package/dist/cli/commands/sync.d.ts +3 -0
- package/dist/cli/commands/sync.js +11 -0
- package/dist/cli/commands/types.d.ts +7 -0
- package/dist/cli/commands/types.js +37 -0
- package/dist/cli/commands/viewer.d.ts +6 -0
- package/dist/cli/commands/viewer.js +29 -0
- package/dist/cli/index.d.ts +2 -0
- package/dist/cli/index.js +108 -0
- package/dist/cli/output.d.ts +25 -0
- package/dist/cli/output.js +149 -0
- package/dist/cli/schema-prompt.d.ts +20 -0
- package/dist/cli/schema-prompt.js +66 -0
- package/dist/cli.d.ts +2 -0
- package/dist/cli.js +3 -0
- package/dist/client-cache.d.ts +105 -0
- package/dist/client-cache.js +916 -0
- package/dist/client.d.ts +64 -0
- package/dist/client.js +405 -0
- package/dist/config-public.d.ts +1 -0
- package/dist/config-public.js +1 -0
- package/dist/config.d.ts +54 -0
- package/dist/config.js +2 -0
- package/dist/csv.d.ts +1 -0
- package/dist/csv.js +1 -0
- package/dist/db.d.ts +3 -0
- package/dist/db.js +3 -0
- package/dist/doctor.d.ts +1 -0
- package/dist/doctor.js +1 -0
- package/dist/errors.d.ts +1 -0
- package/dist/errors.js +1 -0
- package/dist/features/config/defaults.d.ts +98 -0
- package/dist/features/config/defaults.js +95 -0
- package/dist/features/config/load.d.ts +11 -0
- package/dist/features/config/load.js +265 -0
- package/dist/features/config/public.d.ts +17 -0
- package/dist/features/config/public.js +75 -0
- package/dist/features/doctor/duplicate-ids.d.ts +18 -0
- package/dist/features/doctor/duplicate-ids.js +79 -0
- package/dist/features/doctor/field-consistency.d.ts +17 -0
- package/dist/features/doctor/field-consistency.js +48 -0
- package/dist/features/doctor/index.d.ts +39 -0
- package/dist/features/doctor/index.js +177 -0
- package/dist/features/doctor/relations.d.ts +22 -0
- package/dist/features/doctor/relations.js +90 -0
- package/dist/features/doctor/schema-guidance.d.ts +35 -0
- package/dist/features/doctor/schema-guidance.js +184 -0
- package/dist/features/generate/registry.d.ts +14 -0
- package/dist/features/generate/registry.js +37 -0
- package/dist/features/http/registry.d.ts +46 -0
- package/dist/features/http/registry.js +86 -0
- package/dist/features/operations/index.d.ts +49 -0
- package/dist/features/operations/index.js +199 -0
- package/dist/features/operations/maps.d.ts +1 -0
- package/dist/features/operations/maps.js +10 -0
- package/dist/features/operations/readiness.d.ts +30 -0
- package/dist/features/operations/readiness.js +228 -0
- package/dist/features/operations/runtime.d.ts +57 -0
- package/dist/features/operations/runtime.js +288 -0
- package/dist/features/runtime/collection.d.ts +51 -0
- package/dist/features/runtime/collection.js +198 -0
- package/dist/features/runtime/db.d.ts +152 -0
- package/dist/features/runtime/db.js +824 -0
- package/dist/features/runtime/document.d.ts +43 -0
- package/dist/features/runtime/document.js +111 -0
- package/dist/features/runtime/fanout.d.ts +24 -0
- package/dist/features/runtime/fanout.js +77 -0
- package/dist/features/runtime/json-pointer.d.ts +5 -0
- package/dist/features/runtime/json-pointer.js +49 -0
- package/dist/features/runtime/scope-state.d.ts +44 -0
- package/dist/features/runtime/scope-state.js +185 -0
- package/dist/features/runtime/state.d.ts +1 -0
- package/dist/features/runtime/state.js +1 -0
- package/dist/features/schema/api.d.ts +107 -0
- package/dist/features/schema/api.js +460 -0
- package/dist/features/schema/builders.d.ts +86 -0
- package/dist/features/schema/builders.js +110 -0
- package/dist/features/schema/fields.d.ts +38 -0
- package/dist/features/schema/fields.js +296 -0
- package/dist/features/schema/generated.d.ts +29 -0
- package/dist/features/schema/generated.js +32 -0
- package/dist/features/schema/locator.d.ts +16 -0
- package/dist/features/schema/locator.js +135 -0
- package/dist/features/schema/manifest.d.ts +91 -0
- package/dist/features/schema/manifest.js +384 -0
- package/dist/features/schema/metadata.d.ts +30 -0
- package/dist/features/schema/metadata.js +75 -0
- package/dist/features/schema/project.d.ts +46 -0
- package/dist/features/schema/project.js +442 -0
- package/dist/features/schema/relations.d.ts +38 -0
- package/dist/features/schema/relations.js +109 -0
- package/dist/features/schema/resolvers.d.ts +36 -0
- package/dist/features/schema/resolvers.js +111 -0
- package/dist/features/schema/resource.d.ts +75 -0
- package/dist/features/schema/resource.js +253 -0
- package/dist/features/schema/source-definitions.d.ts +21 -0
- package/dist/features/schema/source-definitions.js +29 -0
- package/dist/features/schema/sources.d.ts +83 -0
- package/dist/features/schema/sources.js +689 -0
- package/dist/features/schema/standard-schema.d.ts +57 -0
- package/dist/features/schema/standard-schema.js +232 -0
- package/dist/features/schema/validation.d.ts +69 -0
- package/dist/features/schema/validation.js +434 -0
- package/dist/features/storage/events.d.ts +12 -0
- package/dist/features/storage/events.js +30 -0
- package/dist/features/storage/json.d.ts +112 -0
- package/dist/features/storage/json.js +239 -0
- package/dist/features/storage/memory.d.ts +30 -0
- package/dist/features/storage/memory.js +44 -0
- package/dist/features/storage/resource-json.d.ts +31 -0
- package/dist/features/storage/resource-json.js +76 -0
- package/dist/features/storage/runtime.d.ts +37 -0
- package/dist/features/storage/runtime.js +184 -0
- package/dist/features/storage/source-metadata.d.ts +20 -0
- package/dist/features/storage/source-metadata.js +25 -0
- package/dist/features/storage/source.d.ts +37 -0
- package/dist/features/storage/source.js +60 -0
- package/dist/features/storage/static.d.ts +29 -0
- package/dist/features/storage/static.js +42 -0
- package/dist/features/sync/defaults.d.ts +21 -0
- package/dist/features/sync/defaults.js +21 -0
- package/dist/features/sync/index.d.ts +35 -0
- package/dist/features/sync/index.js +85 -0
- package/dist/features/sync/mirror-state.d.ts +14 -0
- package/dist/features/sync/mirror-state.js +4 -0
- package/dist/features/sync/runtime-dirs.d.ts +5 -0
- package/dist/features/sync/runtime-dirs.js +9 -0
- package/dist/features/sync/source-writes.d.ts +15 -0
- package/dist/features/sync/source-writes.js +27 -0
- package/dist/features/sync/synthetic-seed.d.ts +26 -0
- package/dist/features/sync/synthetic-seed.js +83 -0
- package/dist/features/viewer/manifest.d.ts +148 -0
- package/dist/features/viewer/manifest.js +165 -0
- package/dist/fs-utils.d.ts +1 -0
- package/dist/fs-utils.js +1 -0
- package/dist/generate/hono/app.d.ts +6 -0
- package/dist/generate/hono/app.js +51 -0
- package/dist/generate/hono/graphql.d.ts +7 -0
- package/dist/generate/hono/graphql.js +53 -0
- package/dist/generate/hono/index.d.ts +55 -0
- package/dist/generate/hono/index.js +140 -0
- package/dist/generate/hono/package.d.ts +6 -0
- package/dist/generate/hono/package.js +44 -0
- package/dist/generate/hono/readme.d.ts +13 -0
- package/dist/generate/hono/readme.js +28 -0
- package/dist/generate/hono/repository.d.ts +1 -0
- package/dist/generate/hono/repository.js +27 -0
- package/dist/generate/hono/rest.d.ts +1 -0
- package/dist/generate/hono/rest.js +38 -0
- package/dist/generate/hono/schema.d.ts +13 -0
- package/dist/generate/hono/schema.js +18 -0
- package/dist/generate/hono/sqlite.d.ts +20 -0
- package/dist/generate/hono/sqlite.js +266 -0
- package/dist/generate/hono/validators.d.ts +1 -0
- package/dist/generate/hono/validators.js +141 -0
- package/dist/generate/hono.d.ts +1 -0
- package/dist/generate/hono.js +1 -0
- package/dist/graphql/execute.d.ts +14 -0
- package/dist/graphql/execute.js +719 -0
- package/dist/graphql/http.d.ts +15 -0
- package/dist/graphql/http.js +29 -0
- package/dist/graphql/index.d.ts +3 -0
- package/dist/graphql/index.js +3 -0
- package/dist/graphql/parser.d.ts +54 -0
- package/dist/graphql/parser.js +433 -0
- package/dist/hono.d.ts +77 -0
- package/dist/hono.js +1 -0
- package/dist/index.d.ts +1065 -0
- package/dist/index.js +14 -0
- package/dist/integrations/hono.d.ts +136 -0
- package/dist/integrations/hono.js +508 -0
- package/dist/integrations/kv.d.ts +69 -0
- package/dist/integrations/kv.js +69 -0
- package/dist/integrations/postgres.d.ts +52 -0
- package/dist/integrations/postgres.js +113 -0
- package/dist/integrations/sqlite.d.ts +112 -0
- package/dist/integrations/sqlite.js +489 -0
- package/dist/integrations/vite.d.ts +45 -0
- package/dist/integrations/vite.js +111 -0
- package/dist/json.d.ts +48 -0
- package/dist/json.js +1 -0
- package/dist/jsonc.d.ts +1 -0
- package/dist/jsonc.js +1 -0
- package/dist/kv.d.ts +24 -0
- package/dist/kv.js +1 -0
- package/dist/mock.d.ts +1 -0
- package/dist/mock.js +1 -0
- package/dist/names.d.ts +1 -0
- package/dist/names.js +1 -0
- package/dist/operations.d.ts +3 -0
- package/dist/operations.js +3 -0
- package/dist/postgres.d.ts +24 -0
- package/dist/postgres.js +1 -0
- package/dist/redis.d.ts +14 -0
- package/dist/redis.js +1 -0
- package/dist/rest/formats.d.ts +80 -0
- package/dist/rest/formats.js +318 -0
- package/dist/rest/handler.d.ts +111 -0
- package/dist/rest/handler.js +833 -0
- package/dist/rest/shape.d.ts +33 -0
- package/dist/rest/shape.js +218 -0
- package/dist/schema-builders.d.ts +1 -0
- package/dist/schema-builders.js +1 -0
- package/dist/schema-manifest.d.ts +1 -0
- package/dist/schema-manifest.js +1 -0
- package/dist/schema.d.ts +193 -0
- package/dist/schema.js +6 -0
- package/dist/server.d.ts +116 -0
- package/dist/server.js +601 -0
- package/dist/shared/csv.d.ts +8 -0
- package/dist/shared/csv.js +149 -0
- package/dist/shared/errors.d.ts +40 -0
- package/dist/shared/errors.js +55 -0
- package/dist/shared/fs-utils.d.ts +4 -0
- package/dist/shared/fs-utils.js +30 -0
- package/dist/shared/jsonc.d.ts +2 -0
- package/dist/shared/jsonc.js +99 -0
- package/dist/shared/mock.d.ts +40 -0
- package/dist/shared/mock.js +83 -0
- package/dist/shared/names.d.ts +28 -0
- package/dist/shared/names.js +127 -0
- package/dist/shared/operations.d.ts +32 -0
- package/dist/shared/operations.js +302 -0
- package/dist/sqlite.d.ts +24 -0
- package/dist/sqlite.js +1 -0
- package/dist/state.d.ts +1 -0
- package/dist/state.js +1 -0
- package/dist/sync.d.ts +1 -0
- package/dist/sync.js +1 -0
- package/dist/tracing.d.ts +95 -0
- package/dist/tracing.js +260 -0
- package/dist/types.d.ts +51 -0
- package/dist/types.js +285 -0
- package/dist/viewer-manifest.d.ts +1 -0
- package/dist/viewer-manifest.js +1 -0
- package/dist/vite.d.ts +59 -0
- package/dist/vite.js +1 -0
- package/dist/web/json-viewer.d.ts +5 -0
- package/dist/web/json-viewer.js +176 -0
- package/dist/web/viewer.d.ts +12 -0
- package/dist/web/viewer.js +1015 -0
- package/docs/README.md +42 -0
- package/docs/architecture.md +112 -0
- package/docs/ci-and-release.md +177 -0
- package/docs/cms-storage-patterns.md +108 -0
- package/docs/concepts.md +141 -0
- package/docs/configuration.md +552 -0
- package/docs/fixtures-and-schemas.md +527 -0
- package/docs/fork-branch-workflows.md +108 -0
- package/docs/generated-files.md +174 -0
- package/docs/getting-started.md +165 -0
- package/docs/integrations.md +206 -0
- package/docs/json-production.md +120 -0
- package/docs/package-api.md +418 -0
- package/docs/prototype-to-production.md +378 -0
- package/docs/server-and-viewer.md +466 -0
- package/docs/store-graduation.md +120 -0
- package/docs/typescript-schema-sources.md +79 -0
- package/examples/advanced/README.md +55 -0
- package/examples/advanced/db/projects.schema.jsonc +44 -0
- package/examples/advanced/db/settings.jsonc +9 -0
- package/examples/advanced/db/users.json +23 -0
- package/examples/advanced/db/users.schema.mjs +31 -0
- package/examples/advanced/db.config.mjs +18 -0
- package/examples/advanced/example.json +5 -0
- package/examples/advanced/src/generated/db.types.d.ts +64 -0
- package/examples/basic/README.md +95 -0
- package/examples/basic/db/operations/get-user.jsonc +8 -0
- package/examples/basic/db/settings.json +7 -0
- package/examples/basic/db/users.schema.jsonc +36 -0
- package/examples/basic/db.config.mjs +68 -0
- package/examples/basic/example.json +5 -0
- package/examples/basic/src/generated/db.types.d.ts +39 -0
- package/examples/cms-json-publish/README.md +21 -0
- package/examples/cms-json-publish/db/navigation.json +7 -0
- package/examples/cms-json-publish/db/pages.json +18 -0
- package/examples/cms-json-publish/example.json +5 -0
- package/examples/cms-json-publish/src/cms.mjs +104 -0
- package/examples/computed-fields/README.md +93 -0
- package/examples/computed-fields/db/orders.schema.mjs +62 -0
- package/examples/computed-fields/db/posts.schema.mjs +59 -0
- package/examples/computed-fields/db/products.schema.mjs +39 -0
- package/examples/computed-fields/db/users.schema.mjs +43 -0
- package/examples/computed-fields/db.config.mjs +15 -0
- package/examples/computed-fields/example.json +5 -0
- package/examples/computed-fields/src/generated/db.types.d.ts +81 -0
- package/examples/content-collections/README.md +91 -0
- package/examples/content-collections/db/authors.json +12 -0
- package/examples/content-collections/db/authors.schema.mjs +20 -0
- package/examples/content-collections/db/blog/draft-roadmap.mdx +12 -0
- package/examples/content-collections/db/blog/index.schema.mjs +61 -0
- package/examples/content-collections/db/blog/launch-notes.mdx +15 -0
- package/examples/content-collections/db/docs/index.schema.mjs +32 -0
- package/examples/content-collections/db/docs/intro.mdx +11 -0
- package/examples/content-collections/db/docs/schema-workflow.mdx +10 -0
- package/examples/content-collections/db/site.schema.jsonc +21 -0
- package/examples/content-collections/db.config.mjs +26 -0
- package/examples/content-collections/example.json +5 -0
- package/examples/content-collections/src/content-preview.mjs +66 -0
- package/examples/content-collections/src/generated/db.types.d.ts +81 -0
- package/examples/csv/README.md +52 -0
- package/examples/csv/db/customers.csv +4 -0
- package/examples/csv/db.config.mjs +13 -0
- package/examples/csv/example.json +5 -0
- package/examples/data-first/README.md +54 -0
- package/examples/data-first/db/posts.json +16 -0
- package/examples/data-first/db/settings.json +8 -0
- package/examples/data-first/db/users.json +14 -0
- package/examples/data-first/db.config.mjs +13 -0
- package/examples/data-first/example.json +5 -0
- package/examples/diagnostics/README.md +55 -0
- package/examples/diagnostics/db/projects.schema.jsonc +27 -0
- package/examples/diagnostics/db/users.json +9 -0
- package/examples/diagnostics/db/users.schema.jsonc +23 -0
- package/examples/diagnostics/db.config.mjs +16 -0
- package/examples/diagnostics/example.json +5 -0
- package/examples/free-plan-upgrade/README.md +22 -0
- package/examples/free-plan-upgrade/db/appSettings.json +4 -0
- package/examples/free-plan-upgrade/db/projects.json +7 -0
- package/examples/free-plan-upgrade/example.json +5 -0
- package/examples/free-plan-upgrade/src/upgrade-tenant-to-paid.mjs +105 -0
- package/examples/hono-auth/README.md +74 -0
- package/examples/hono-auth/db/pages.schema.jsonc +44 -0
- package/examples/hono-auth/db/users.schema.jsonc +42 -0
- package/examples/hono-auth/db.config.mjs +17 -0
- package/examples/hono-auth/example.json +5 -0
- package/examples/hono-auth/package.json +14 -0
- package/examples/hono-auth/src/app.mjs +79 -0
- package/examples/hono-auth/src/server.mjs +13 -0
- package/examples/production-json/README.md +102 -0
- package/examples/production-json/db/appSettings.schema.jsonc +41 -0
- package/examples/production-json/db/featureFlags.schema.jsonc +84 -0
- package/examples/production-json/db/operations/get-control-plane.jsonc +6 -0
- package/examples/production-json/db/operations/get-feature-flag.jsonc +9 -0
- package/examples/production-json/db/operations/list-feature-flags.jsonc +8 -0
- package/examples/production-json/db/operations/read-public-settings.jsonc +8 -0
- package/examples/production-json/db.config.mjs +33 -0
- package/examples/production-json/example.json +5 -0
- package/examples/production-json/src/client-demo.mjs +28 -0
- package/examples/production-json/src/generated/db.types.d.ts +60 -0
- package/examples/relations/README.md +56 -0
- package/examples/relations/db/posts.schema.jsonc +46 -0
- package/examples/relations/db/users.schema.jsonc +34 -0
- package/examples/relations/db.config.mjs +13 -0
- package/examples/relations/example.json +5 -0
- package/examples/rest-client/README.md +54 -0
- package/examples/rest-client/db/settings.json +5 -0
- package/examples/rest-client/db/users.schema.jsonc +42 -0
- package/examples/rest-client/db.config.mjs +13 -0
- package/examples/rest-client/example.json +5 -0
- package/examples/rest-client/src/client-demo.mjs +24 -0
- package/examples/schema-first/README.md +55 -0
- package/examples/schema-first/db/auditEvents.schema.jsonc +24 -0
- package/examples/schema-first/db/settings.schema.jsonc +29 -0
- package/examples/schema-first/db/users.schema.jsonc +36 -0
- package/examples/schema-first/db.config.mjs +15 -0
- package/examples/schema-first/example.json +5 -0
- package/examples/schema-first/src/generated/db.types.d.ts +47 -0
- package/examples/schema-manifest/README.md +50 -0
- package/examples/schema-manifest/db/projects.schema.jsonc +48 -0
- package/examples/schema-manifest/db/users.schema.jsonc +35 -0
- package/examples/schema-manifest/db.config.mjs +41 -0
- package/examples/schema-manifest/example.json +5 -0
- package/examples/schema-manifest/src/generated/db.schema.json +130 -0
- package/examples/schema-manifest/src/generated/db.types.d.ts +50 -0
- package/examples/schema-ui/README.md +103 -0
- package/examples/schema-ui/db/pages.schema.jsonc +53 -0
- package/examples/schema-ui/db/users.schema.jsonc +30 -0
- package/examples/schema-ui/db.config.mjs +55 -0
- package/examples/schema-ui/example.json +5 -0
- package/examples/schema-ui/src/cms-ssr.mjs +276 -0
- package/examples/schema-ui/src/generated/db.schema.json +133 -0
- package/examples/schema-ui/src/generated/db.types.d.ts +46 -0
- package/examples/schema-ui/src/render-admin.mjs +175 -0
- package/examples/schema-ui/src/schema-ui-ssr-handler.mjs +149 -0
- package/examples/schema-ui/src/start-schema-ui-server.mjs +140 -0
- package/examples/standard-schema/README.md +55 -0
- package/examples/standard-schema/db/settings.schema.mjs +22 -0
- package/examples/standard-schema/db/users.schema.mjs +72 -0
- package/examples/standard-schema/example.json +5 -0
- package/package.json +108 -0
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
# Advanced Example
|
|
2
|
+
|
|
3
|
+
## What This Teaches
|
|
4
|
+
|
|
5
|
+
Use this after the basics when you want to see several features working together: mixed-mode fixtures, `.schema.mjs`, defaults, nested objects, and committed generated types.
|
|
6
|
+
|
|
7
|
+
## Files To Inspect
|
|
8
|
+
|
|
9
|
+
- [db/users.schema.mjs](./db/users.schema.mjs): schema helper API from `@async/db/schema`.
|
|
10
|
+
- [db/users.json](./db/users.json): data seed for the schema-backed `users` collection.
|
|
11
|
+
- [db/projects.schema.jsonc](./db/projects.schema.jsonc): nested object defaults.
|
|
12
|
+
- [src/generated/db.types.d.ts](./src/generated/db.types.d.ts): committed generated types.
|
|
13
|
+
|
|
14
|
+
## Run It
|
|
15
|
+
|
|
16
|
+
From the repository root, use the repo-internal CLI path:
|
|
17
|
+
|
|
18
|
+
```bash
|
|
19
|
+
npm run db -- sync --cwd ./examples/advanced
|
|
20
|
+
npm run db -- serve --cwd ./examples/advanced
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
Open the viewer:
|
|
24
|
+
|
|
25
|
+
```txt
|
|
26
|
+
http://127.0.0.1:7331/__db
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
## Expected Result
|
|
30
|
+
|
|
31
|
+
`sync` loads mixed data and schema sources, applies defaults in the selected runtime store, and writes committed generated types.
|
|
32
|
+
|
|
33
|
+
## REST Request To Try
|
|
34
|
+
|
|
35
|
+
Leave `serve` running and run this from another terminal:
|
|
36
|
+
|
|
37
|
+
```bash
|
|
38
|
+
curl 'http://127.0.0.1:7331/db/projects.json?select=id,name,status,metadata'
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
## Features To Notice
|
|
42
|
+
|
|
43
|
+
- [JavaScript schema sources](../../docs/fixtures-and-schemas.md#javascript-schema-sources)
|
|
44
|
+
- [Schema defaults](../../docs/configuration.md#schema-defaults)
|
|
45
|
+
- [Fixture-like `.json` REST routes](../../docs/server-and-viewer.md#fixture-like-json-routes)
|
|
46
|
+
- [Generated types](../../docs/generated-files.md#generated-types)
|
|
47
|
+
|
|
48
|
+
## Cleanup
|
|
49
|
+
|
|
50
|
+
Generated `.db/` output is ignored by git and can be removed whenever you want fresh runtime state.
|
|
51
|
+
|
|
52
|
+
## More Docs
|
|
53
|
+
|
|
54
|
+
- [Fixtures And Schemas](../../docs/fixtures-and-schemas.md)
|
|
55
|
+
- [Package API](../../docs/package-api.md)
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
{
|
|
2
|
+
"kind": "collection",
|
|
3
|
+
"idField": "id",
|
|
4
|
+
"fields": {
|
|
5
|
+
"id": {
|
|
6
|
+
"type": "string",
|
|
7
|
+
"required": true
|
|
8
|
+
},
|
|
9
|
+
"name": {
|
|
10
|
+
"type": "string",
|
|
11
|
+
"required": true
|
|
12
|
+
},
|
|
13
|
+
"ownerId": {
|
|
14
|
+
"type": "string",
|
|
15
|
+
"required": true
|
|
16
|
+
},
|
|
17
|
+
"status": {
|
|
18
|
+
"type": "enum",
|
|
19
|
+
"values": ["planned", "active", "paused", "done"],
|
|
20
|
+
"default": "planned"
|
|
21
|
+
},
|
|
22
|
+
"metadata": {
|
|
23
|
+
"type": "object",
|
|
24
|
+
"default": {},
|
|
25
|
+
"fields": {
|
|
26
|
+
"priority": {
|
|
27
|
+
"type": "string",
|
|
28
|
+
"default": "normal"
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
},
|
|
33
|
+
"seed": [
|
|
34
|
+
{
|
|
35
|
+
"id": "proj_1",
|
|
36
|
+
"name": "Local checkout",
|
|
37
|
+
"ownerId": "u_1",
|
|
38
|
+
"status": "active",
|
|
39
|
+
"metadata": {
|
|
40
|
+
"priority": "high"
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
]
|
|
44
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
[
|
|
2
|
+
{
|
|
3
|
+
"id": "u_1",
|
|
4
|
+
"name": "Ada Lovelace",
|
|
5
|
+
"email": "ada@example.com",
|
|
6
|
+
"role": "admin",
|
|
7
|
+
"profile": {
|
|
8
|
+
"title": "Mathematician",
|
|
9
|
+
"location": "London"
|
|
10
|
+
},
|
|
11
|
+
"twitterHandle": "@ada"
|
|
12
|
+
},
|
|
13
|
+
{
|
|
14
|
+
"id": "u_2",
|
|
15
|
+
"name": "Katherine Johnson",
|
|
16
|
+
"email": "katherine@example.com",
|
|
17
|
+
"role": "editor",
|
|
18
|
+
"profile": {
|
|
19
|
+
"title": "Research mathematician",
|
|
20
|
+
"location": "Virginia"
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
]
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { collection, field } from '@async/db/schema';
|
|
2
|
+
|
|
3
|
+
export default collection({
|
|
4
|
+
description: 'Users who can sign into the local test app.',
|
|
5
|
+
idField: 'id',
|
|
6
|
+
fields: {
|
|
7
|
+
id: field.string({
|
|
8
|
+
required: true,
|
|
9
|
+
description: 'Stable user id.',
|
|
10
|
+
}),
|
|
11
|
+
name: field.string({
|
|
12
|
+
required: true,
|
|
13
|
+
description: 'Display name shown in the UI.',
|
|
14
|
+
}),
|
|
15
|
+
email: field.string({
|
|
16
|
+
required: true,
|
|
17
|
+
description: 'Unique email address.',
|
|
18
|
+
}),
|
|
19
|
+
role: field.enum(['admin', 'editor', 'user'], {
|
|
20
|
+
default: 'user',
|
|
21
|
+
description: 'Local authorization role.',
|
|
22
|
+
}),
|
|
23
|
+
twitterHandle: field.string({
|
|
24
|
+
description: 'Optional social handle used by local profile demos.',
|
|
25
|
+
}),
|
|
26
|
+
profile: field.object({
|
|
27
|
+
title: field.string({ default: 'Contributor' }),
|
|
28
|
+
location: field.string({ default: 'Remote' }),
|
|
29
|
+
}),
|
|
30
|
+
},
|
|
31
|
+
});
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
// @ts-check
|
|
2
|
+
import { defineConfig } from '@async/db/config';
|
|
3
|
+
|
|
4
|
+
export default defineConfig({
|
|
5
|
+
dbDir: './db',
|
|
6
|
+
outputs: {
|
|
7
|
+
stateDir: './.db',
|
|
8
|
+
types: './.db/types/index.d.ts',
|
|
9
|
+
committedTypes: './src/generated/db.types.d.ts',
|
|
10
|
+
},
|
|
11
|
+
types: {
|
|
12
|
+
enabled: true,
|
|
13
|
+
emitComments: true,
|
|
14
|
+
},
|
|
15
|
+
schema: {
|
|
16
|
+
unknownFields: 'warn',
|
|
17
|
+
},
|
|
18
|
+
});
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
/* eslint-disable */
|
|
2
|
+
// This file is generated by db. Do not edit by hand.
|
|
3
|
+
|
|
4
|
+
export type ProjectStatus =
|
|
5
|
+
| "planned"
|
|
6
|
+
| "active"
|
|
7
|
+
| "paused"
|
|
8
|
+
| "done";
|
|
9
|
+
|
|
10
|
+
export type UserRole = "admin" | "editor" | "user";
|
|
11
|
+
|
|
12
|
+
export type Project = {
|
|
13
|
+
id: string;
|
|
14
|
+
name: string;
|
|
15
|
+
ownerId: string;
|
|
16
|
+
status?: ProjectStatus;
|
|
17
|
+
metadata?: {
|
|
18
|
+
priority?: string;
|
|
19
|
+
};
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
export type Settings = {
|
|
23
|
+
features?: {
|
|
24
|
+
billing?: boolean;
|
|
25
|
+
graphql?: boolean;
|
|
26
|
+
};
|
|
27
|
+
locale?: string;
|
|
28
|
+
theme?: string;
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
/** Users who can sign into the local test app. */
|
|
32
|
+
export type User = {
|
|
33
|
+
/** Stable user id. */
|
|
34
|
+
id: string;
|
|
35
|
+
/** Display name shown in the UI. */
|
|
36
|
+
name: string;
|
|
37
|
+
/** Unique email address. */
|
|
38
|
+
email: string;
|
|
39
|
+
/** Local authorization role. */
|
|
40
|
+
role?: UserRole;
|
|
41
|
+
/** Optional social handle used by local profile demos. */
|
|
42
|
+
twitterHandle?: string;
|
|
43
|
+
profile?: {
|
|
44
|
+
title?: string;
|
|
45
|
+
location?: string;
|
|
46
|
+
};
|
|
47
|
+
};
|
|
48
|
+
|
|
49
|
+
export type DbCollections = {
|
|
50
|
+
projects: Project;
|
|
51
|
+
users: User;
|
|
52
|
+
};
|
|
53
|
+
|
|
54
|
+
export type DbDocuments = {
|
|
55
|
+
settings: Settings;
|
|
56
|
+
};
|
|
57
|
+
|
|
58
|
+
export type DbTypes = {
|
|
59
|
+
collections: DbCollections;
|
|
60
|
+
documents: DbDocuments;
|
|
61
|
+
};
|
|
62
|
+
|
|
63
|
+
export type DbCollectionName = keyof DbCollections;
|
|
64
|
+
export type DbDocumentName = keyof DbDocuments;
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
# Basic Example
|
|
2
|
+
|
|
3
|
+
## What This Teaches
|
|
4
|
+
|
|
5
|
+
Start here when you want the smallest schema-backed db workflow. It demonstrates sync, committed generated types, the viewer, fixture-like `.json` REST reads, and creating a record.
|
|
6
|
+
|
|
7
|
+
## Files To Inspect
|
|
8
|
+
|
|
9
|
+
- [db/users.schema.jsonc](./db/users.schema.jsonc): schema-backed collection with seed data.
|
|
10
|
+
- [db/settings.json](./db/settings.json): singleton document inferred from data.
|
|
11
|
+
- [db/operations/get-user.jsonc](./db/operations/get-user.jsonc): optional registered REST operation template.
|
|
12
|
+
- [src/generated/db.types.d.ts](./src/generated/db.types.d.ts): committed generated types.
|
|
13
|
+
|
|
14
|
+
## Run It
|
|
15
|
+
|
|
16
|
+
From the repository root, use the repo-internal CLI path:
|
|
17
|
+
|
|
18
|
+
```bash
|
|
19
|
+
npm run db -- sync --cwd ./examples/basic
|
|
20
|
+
npm run db -- operations build --cwd ./examples/basic
|
|
21
|
+
npm run db -- serve --cwd ./examples/basic
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
Open the viewer:
|
|
25
|
+
|
|
26
|
+
```txt
|
|
27
|
+
http://127.0.0.1:7331/__db
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
## Expected Result
|
|
31
|
+
|
|
32
|
+
`sync` writes generated schema, types, and runtime state under `examples/basic/.db/`, plus the committed type copy in `src/generated/`.
|
|
33
|
+
|
|
34
|
+
`operations build` writes a full server registry and client-safe refs under
|
|
35
|
+
`examples/basic/src/generated/`.
|
|
36
|
+
|
|
37
|
+
To review the browser-facing operation contract without volatile timestamps:
|
|
38
|
+
|
|
39
|
+
```bash
|
|
40
|
+
npm run db -- operations contract --cwd ./examples/basic
|
|
41
|
+
npm run db -- operations contract --cwd ./examples/basic --check
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
## REST Request To Try
|
|
45
|
+
|
|
46
|
+
Leave `serve` running and run this from another terminal:
|
|
47
|
+
|
|
48
|
+
```bash
|
|
49
|
+
curl http://127.0.0.1:7331/db/users.json
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
The `.json` route is intentional: a source fixture such as `db/users.json`
|
|
53
|
+
maps naturally to `GET /db/users.json`, while the server still reads from the
|
|
54
|
+
synced runtime resource under `.db/state`.
|
|
55
|
+
|
|
56
|
+
Create a local runtime record:
|
|
57
|
+
|
|
58
|
+
```bash
|
|
59
|
+
curl -X POST http://127.0.0.1:7331/db/users \
|
|
60
|
+
-H 'content-type: application/json' \
|
|
61
|
+
-d '{"id":"u_2","name":"Grace Hopper","email":"grace@example.com"}'
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
The equivalent CLI smoke command is:
|
|
65
|
+
|
|
66
|
+
```bash
|
|
67
|
+
npm run db -- create users '{"id":"u_2","name":"Grace Hopper","email":"grace@example.com"}' --cwd ./examples/basic
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
## Registered Operation To Try
|
|
71
|
+
|
|
72
|
+
Build operations, then use the generated ref from
|
|
73
|
+
`examples/basic/src/generated/db.operation-refs.json`:
|
|
74
|
+
|
|
75
|
+
```bash
|
|
76
|
+
curl -X POST http://127.0.0.1:7331/__db/operations/REF \
|
|
77
|
+
-H 'content-type: application/json' \
|
|
78
|
+
-d '{"variables":{"id":"u_1"}}'
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
## Features To Notice
|
|
82
|
+
|
|
83
|
+
- [Fixture-like `.json` REST routes](../../docs/server-and-viewer.md#fixture-like-json-routes)
|
|
84
|
+
- [Schema-backed fixtures](../../docs/fixtures-and-schemas.md#schema-files)
|
|
85
|
+
- [Generated types](../../docs/generated-files.md#generated-types)
|
|
86
|
+
- [Registered REST operations](../../docs/server-and-viewer.md#registered-rest-operations)
|
|
87
|
+
|
|
88
|
+
## Cleanup
|
|
89
|
+
|
|
90
|
+
Generated `.db/` output is ignored by git and can be removed whenever you want a fresh mirror.
|
|
91
|
+
|
|
92
|
+
## More Docs
|
|
93
|
+
|
|
94
|
+
- [Getting Started](../../docs/getting-started.md)
|
|
95
|
+
- [Generated Files](../../docs/generated-files.md)
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
{
|
|
2
|
+
// Users who can sign into the local test app.
|
|
3
|
+
"kind": "collection",
|
|
4
|
+
"idField": "id",
|
|
5
|
+
"fields": {
|
|
6
|
+
"id": {
|
|
7
|
+
"type": "string",
|
|
8
|
+
"required": true,
|
|
9
|
+
"description": "Stable user id."
|
|
10
|
+
},
|
|
11
|
+
"name": {
|
|
12
|
+
"type": "string",
|
|
13
|
+
"required": true,
|
|
14
|
+
"description": "Display name shown in the UI."
|
|
15
|
+
},
|
|
16
|
+
"email": {
|
|
17
|
+
"type": "string",
|
|
18
|
+
"required": true,
|
|
19
|
+
"description": "Unique email address."
|
|
20
|
+
},
|
|
21
|
+
"role": {
|
|
22
|
+
"type": "enum",
|
|
23
|
+
"values": ["admin", "user"],
|
|
24
|
+
"default": "user",
|
|
25
|
+
"description": "Local authorization role."
|
|
26
|
+
}
|
|
27
|
+
},
|
|
28
|
+
"seed": [
|
|
29
|
+
{
|
|
30
|
+
"id": "u_1",
|
|
31
|
+
"name": "Ada Lovelace",
|
|
32
|
+
"email": "ada@example.com",
|
|
33
|
+
"role": "admin"
|
|
34
|
+
}
|
|
35
|
+
]
|
|
36
|
+
}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
// @ts-check
|
|
2
|
+
import { defineConfig } from '@async/db/config';
|
|
3
|
+
|
|
4
|
+
export default defineConfig({
|
|
5
|
+
dbDir: './db',
|
|
6
|
+
outputs: {
|
|
7
|
+
stateDir: './.db',
|
|
8
|
+
types: './.db/types/index.d.ts',
|
|
9
|
+
committedTypes: './src/generated/db.types.d.ts',
|
|
10
|
+
operationRegistry: './src/generated/db.operations.json',
|
|
11
|
+
operationRefs: './src/generated/db.operation-refs.json',
|
|
12
|
+
},
|
|
13
|
+
types: {
|
|
14
|
+
enabled: true,
|
|
15
|
+
emitComments: true,
|
|
16
|
+
},
|
|
17
|
+
schema: {
|
|
18
|
+
unknownFields: 'warn',
|
|
19
|
+
},
|
|
20
|
+
operations: {
|
|
21
|
+
enabled: false,
|
|
22
|
+
sourceDir: './db/operations',
|
|
23
|
+
},
|
|
24
|
+
rest: {
|
|
25
|
+
formats: {
|
|
26
|
+
yaml: {
|
|
27
|
+
mediaTypes: ['application/yaml', 'text/yaml'],
|
|
28
|
+
contentType: 'application/yaml; charset=utf-8',
|
|
29
|
+
render({ data }) {
|
|
30
|
+
return `${toYaml(data)}\n`;
|
|
31
|
+
},
|
|
32
|
+
},
|
|
33
|
+
},
|
|
34
|
+
},
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
function toYaml(value, indent = 0) {
|
|
38
|
+
const pad = ' '.repeat(indent);
|
|
39
|
+
if (Array.isArray(value)) {
|
|
40
|
+
return value.map((item) => {
|
|
41
|
+
if (item && typeof item === 'object') {
|
|
42
|
+
return `${pad}-\n${toYaml(item, indent + 2)}`;
|
|
43
|
+
}
|
|
44
|
+
return `${pad}- ${formatYamlScalar(item)}`;
|
|
45
|
+
}).join('\n');
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
if (value && typeof value === 'object') {
|
|
49
|
+
return Object.entries(value).map(([key, item]) => {
|
|
50
|
+
if (item && typeof item === 'object') {
|
|
51
|
+
return `${pad}${key}:\n${toYaml(item, indent + 2)}`;
|
|
52
|
+
}
|
|
53
|
+
return `${pad}${key}: ${formatYamlScalar(item)}`;
|
|
54
|
+
}).join('\n');
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
return `${pad}${formatYamlScalar(value)}`;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
function formatYamlScalar(value) {
|
|
61
|
+
if (typeof value === 'string') {
|
|
62
|
+
return JSON.stringify(value);
|
|
63
|
+
}
|
|
64
|
+
if (value === null) {
|
|
65
|
+
return 'null';
|
|
66
|
+
}
|
|
67
|
+
return String(value);
|
|
68
|
+
}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
/* eslint-disable */
|
|
2
|
+
// This file is generated by db. Do not edit by hand.
|
|
3
|
+
|
|
4
|
+
export type UserRole = "admin" | "user";
|
|
5
|
+
|
|
6
|
+
export type Settings = {
|
|
7
|
+
features?: {
|
|
8
|
+
billing?: boolean;
|
|
9
|
+
};
|
|
10
|
+
locale?: string;
|
|
11
|
+
theme?: string;
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
export type User = {
|
|
15
|
+
/** Stable user id. */
|
|
16
|
+
id: string;
|
|
17
|
+
/** Display name shown in the UI. */
|
|
18
|
+
name: string;
|
|
19
|
+
/** Unique email address. */
|
|
20
|
+
email: string;
|
|
21
|
+
/** Local authorization role. */
|
|
22
|
+
role?: UserRole;
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
export type DbCollections = {
|
|
26
|
+
users: User;
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
export type DbDocuments = {
|
|
30
|
+
settings: Settings;
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
export type DbTypes = {
|
|
34
|
+
collections: DbCollections;
|
|
35
|
+
documents: DbDocuments;
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
export type DbCollectionName = keyof DbCollections;
|
|
39
|
+
export type DbDocumentName = keyof DbDocuments;
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
# CMS JSON Publish Example
|
|
2
|
+
|
|
3
|
+
This example shows how an app can build CMS behavior on top of generic `@async/db` primitives. The CMS helper is app code, not package API.
|
|
4
|
+
|
|
5
|
+
Run it from the repository root:
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm run db -- sync --cwd ./examples/cms-json-publish
|
|
9
|
+
node ./examples/cms-json-publish/src/cms.mjs
|
|
10
|
+
```
|
|
11
|
+
|
|
12
|
+
The script:
|
|
13
|
+
|
|
14
|
+
- creates a tenant fork
|
|
15
|
+
- creates `draft` and `published` branches
|
|
16
|
+
- saves draft content in `draft`
|
|
17
|
+
- filters public records in app code
|
|
18
|
+
- writes only published records into `published`
|
|
19
|
+
- serves public JSON from the `published` branch
|
|
20
|
+
|
|
21
|
+
`@async/db/json` stores the branch files; the app decides what `published` means.
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
[
|
|
2
|
+
{
|
|
3
|
+
"id": "home",
|
|
4
|
+
"slug": "home",
|
|
5
|
+
"title": "Home",
|
|
6
|
+
"status": "published",
|
|
7
|
+
"summary": "Public home page",
|
|
8
|
+
"bodyMarkdown": "# Home"
|
|
9
|
+
},
|
|
10
|
+
{
|
|
11
|
+
"id": "roadmap",
|
|
12
|
+
"slug": "roadmap",
|
|
13
|
+
"title": "Roadmap",
|
|
14
|
+
"status": "draft",
|
|
15
|
+
"summary": "Draft roadmap",
|
|
16
|
+
"bodyMarkdown": "# Roadmap"
|
|
17
|
+
}
|
|
18
|
+
]
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
import assert from 'node:assert/strict';
|
|
2
|
+
import { fileURLToPath } from 'node:url';
|
|
3
|
+
import { openDb } from '@async/db';
|
|
4
|
+
|
|
5
|
+
export function createCms(db, { tenantId }) {
|
|
6
|
+
return {
|
|
7
|
+
async setup() {
|
|
8
|
+
const tenant = await db.forks.ensure(tenantId, {
|
|
9
|
+
from: 'main',
|
|
10
|
+
metadata: {
|
|
11
|
+
purpose: 'tenant',
|
|
12
|
+
app: 'cms-json-publish',
|
|
13
|
+
},
|
|
14
|
+
});
|
|
15
|
+
await tenant.branches.ensure('draft', { from: 'main', metadata: { purpose: 'draft' } });
|
|
16
|
+
await tenant.branches.ensure('published', { from: 'main', metadata: { purpose: 'published' } });
|
|
17
|
+
},
|
|
18
|
+
|
|
19
|
+
async saveDraft(pageId, changes) {
|
|
20
|
+
const tenant = await db.forks.open(tenantId);
|
|
21
|
+
const draft = await tenant.branches.open('draft');
|
|
22
|
+
return draft.collection('pages').patch(pageId, {
|
|
23
|
+
...changes,
|
|
24
|
+
status: 'draft',
|
|
25
|
+
updatedAt: new Date().toISOString(),
|
|
26
|
+
});
|
|
27
|
+
},
|
|
28
|
+
|
|
29
|
+
async createPreview(previewId) {
|
|
30
|
+
const tenant = await db.forks.open(tenantId);
|
|
31
|
+
return tenant.branches.create(previewId, {
|
|
32
|
+
from: 'draft',
|
|
33
|
+
metadata: { purpose: 'preview' },
|
|
34
|
+
});
|
|
35
|
+
},
|
|
36
|
+
|
|
37
|
+
async publish({ label = 'publish' } = {}) {
|
|
38
|
+
const tenant = await db.forks.open(tenantId);
|
|
39
|
+
const draft = await tenant.branches.open('draft');
|
|
40
|
+
const published = await tenant.branches.open('published');
|
|
41
|
+
const snapshot = await draft.snapshots.create({
|
|
42
|
+
label,
|
|
43
|
+
resources: ['pages', 'navigation'],
|
|
44
|
+
});
|
|
45
|
+
const pages = await draft.collection('pages').all();
|
|
46
|
+
const publicPages = pages
|
|
47
|
+
.filter((page) => page.status === 'published')
|
|
48
|
+
.map(({ id, slug, title, status, summary, bodyMarkdown }) => ({
|
|
49
|
+
id,
|
|
50
|
+
slug,
|
|
51
|
+
title,
|
|
52
|
+
status,
|
|
53
|
+
summary,
|
|
54
|
+
bodyMarkdown,
|
|
55
|
+
}));
|
|
56
|
+
|
|
57
|
+
await published.collection('pages').replaceAll(publicPages);
|
|
58
|
+
await published.collection('navigation').replaceAll(await draft.collection('navigation').all());
|
|
59
|
+
|
|
60
|
+
return {
|
|
61
|
+
snapshot,
|
|
62
|
+
publicPages,
|
|
63
|
+
};
|
|
64
|
+
},
|
|
65
|
+
|
|
66
|
+
async listPublishedPages() {
|
|
67
|
+
const tenant = await db.forks.open(tenantId);
|
|
68
|
+
const published = await tenant.branches.open('published');
|
|
69
|
+
return published.collection('pages').all();
|
|
70
|
+
},
|
|
71
|
+
};
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
async function main() {
|
|
75
|
+
const db = await openDb({
|
|
76
|
+
cwd: new URL('../', import.meta.url).pathname,
|
|
77
|
+
});
|
|
78
|
+
const cms = createCms(db, { tenantId: 'tenant_acme' });
|
|
79
|
+
|
|
80
|
+
await cms.setup();
|
|
81
|
+
await cms.saveDraft('roadmap', {
|
|
82
|
+
title: 'Private roadmap',
|
|
83
|
+
});
|
|
84
|
+
await cms.createPreview('preview_homepage');
|
|
85
|
+
const { publicPages } = await cms.publish({ label: 'initial-public-json' });
|
|
86
|
+
|
|
87
|
+
assert.deepEqual(publicPages.map((page) => page.slug), ['home']);
|
|
88
|
+
assert.deepEqual(await cms.listPublishedPages(), [
|
|
89
|
+
{
|
|
90
|
+
id: 'home',
|
|
91
|
+
slug: 'home',
|
|
92
|
+
title: 'Home',
|
|
93
|
+
status: 'published',
|
|
94
|
+
summary: 'Public home page',
|
|
95
|
+
bodyMarkdown: '# Home',
|
|
96
|
+
},
|
|
97
|
+
]);
|
|
98
|
+
|
|
99
|
+
await db.close();
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
if (process.argv[1] === fileURLToPath(import.meta.url)) {
|
|
103
|
+
await main();
|
|
104
|
+
}
|