@actuate-media/cli 0.7.0 → 0.10.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/.turbo/turbo-build.log +1 -1
- package/.turbo/turbo-test.log +32 -28
- package/CHANGELOG.md +28 -0
- package/README.md +30 -0
- package/dist/__tests__/db-sync.test.js +32 -1
- package/dist/__tests__/db-sync.test.js.map +1 -1
- package/dist/__tests__/deployment-diagnostics.test.js +42 -1
- package/dist/__tests__/deployment-diagnostics.test.js.map +1 -1
- package/dist/__tests__/form-seed.test.d.ts +2 -0
- package/dist/__tests__/form-seed.test.d.ts.map +1 -0
- package/dist/__tests__/form-seed.test.js +79 -0
- package/dist/__tests__/form-seed.test.js.map +1 -0
- package/dist/__tests__/seed.test.js +73 -0
- package/dist/__tests__/seed.test.js.map +1 -1
- package/dist/__tests__/vercel-env-matrix.test.d.ts +2 -0
- package/dist/__tests__/vercel-env-matrix.test.d.ts.map +1 -0
- package/dist/__tests__/vercel-env-matrix.test.js +48 -0
- package/dist/__tests__/vercel-env-matrix.test.js.map +1 -0
- package/dist/commands/db-sync.d.ts +22 -0
- package/dist/commands/db-sync.d.ts.map +1 -1
- package/dist/commands/db-sync.js +94 -0
- package/dist/commands/db-sync.js.map +1 -1
- package/dist/commands/doctor.d.ts.map +1 -1
- package/dist/commands/doctor.js +70 -3
- package/dist/commands/doctor.js.map +1 -1
- package/dist/commands/seed.d.ts +30 -1
- package/dist/commands/seed.d.ts.map +1 -1
- package/dist/commands/seed.js +146 -21
- package/dist/commands/seed.js.map +1 -1
- package/dist/commands/vercel-blob-link.d.ts +3 -0
- package/dist/commands/vercel-blob-link.d.ts.map +1 -0
- package/dist/commands/vercel-blob-link.js +82 -0
- package/dist/commands/vercel-blob-link.js.map +1 -0
- package/dist/deployment/diagnostics.d.ts +13 -0
- package/dist/deployment/diagnostics.d.ts.map +1 -1
- package/dist/deployment/diagnostics.js +55 -0
- package/dist/deployment/diagnostics.js.map +1 -1
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -1
- package/dist/utils/form-seed.d.ts +15 -0
- package/dist/utils/form-seed.d.ts.map +1 -0
- package/dist/utils/form-seed.js +97 -0
- package/dist/utils/form-seed.js.map +1 -0
- package/dist/vercel/client.d.ts +32 -0
- package/dist/vercel/client.d.ts.map +1 -0
- package/dist/vercel/client.js +74 -0
- package/dist/vercel/client.js.map +1 -0
- package/dist/vercel/env-matrix.d.ts +34 -0
- package/dist/vercel/env-matrix.d.ts.map +1 -0
- package/dist/vercel/env-matrix.js +57 -0
- package/dist/vercel/env-matrix.js.map +1 -0
- package/package.json +2 -2
- package/src/__tests__/db-sync.test.ts +55 -1
- package/src/__tests__/deployment-diagnostics.test.ts +51 -0
- package/src/__tests__/form-seed.test.ts +91 -0
- package/src/__tests__/seed.test.ts +97 -0
- package/src/__tests__/vercel-env-matrix.test.ts +56 -0
- package/src/commands/db-sync.ts +116 -0
- package/src/commands/doctor.ts +118 -10
- package/src/commands/seed.ts +167 -21
- package/src/commands/vercel-blob-link.ts +115 -0
- package/src/deployment/diagnostics.ts +70 -0
- package/src/index.ts +2 -0
- package/src/utils/form-seed.ts +137 -0
- package/src/vercel/client.ts +112 -0
- package/src/vercel/env-matrix.ts +101 -0
package/.turbo/turbo-build.log
CHANGED
package/.turbo/turbo-test.log
CHANGED
|
@@ -1,60 +1,64 @@
|
|
|
1
1
|
|
|
2
|
-
> @actuate-media/cli@0.
|
|
2
|
+
> @actuate-media/cli@0.10.0 test /home/runner/work/actuatecms/actuatecms/packages/cli
|
|
3
3
|
> vitest run
|
|
4
4
|
|
|
5
5
|
|
|
6
6
|
[1m[30m[46m RUN [49m[39m[22m [36mv4.1.8 [39m[90m/home/runner/work/actuatecms/actuatecms/packages/cli[39m
|
|
7
7
|
|
|
8
|
-
[32m✓[39m dist/__tests__/db-sync.test.js [2m([22m[
|
|
9
|
-
[32m✓[39m
|
|
8
|
+
[32m✓[39m dist/__tests__/db-sync.test.js [2m([22m[2m10 tests[22m[2m)[22m[33m 324[2mms[22m[39m
|
|
9
|
+
[32m✓[39m dist/__tests__/seed.test.js [2m([22m[2m10 tests[22m[2m)[22m[32m 241[2mms[22m[39m
|
|
10
|
+
[32m✓[39m src/__tests__/db-sync.test.ts [2m([22m[2m10 tests[22m[2m)[22m[32m 300[2mms[22m[39m
|
|
11
|
+
[32m✓[39m src/__tests__/seed.test.ts [2m([22m[2m10 tests[22m[2m)[22m[32m 141[2mms[22m[39m
|
|
12
|
+
[32m✓[39m dist/__tests__/deployment-diagnostics.test.js [2m([22m[2m8 tests[22m[2m)[22m[32m 68[2mms[22m[39m
|
|
13
|
+
[32m✓[39m src/__tests__/deployment-diagnostics.test.ts [2m([22m[2m8 tests[22m[2m)[22m[32m 58[2mms[22m[39m
|
|
10
14
|
- Reading canonical Actuate schema...
|
|
11
|
-
✔ Actuate CMS models added to schema.
|
|
12
|
-
- Running prisma generate...
|
|
13
15
|
[90mstdout[2m | dist/__tests__/db-init.test.js[2m > [22m[2mdb:init (WS-D D5 — canonical schema, no stale fragment)[2m > [22m[2mcommand[2m > [22m[2minjects canonical models with @@map and no duplicate datasource/generator
|
|
14
16
|
[22m[39m✔ Prisma client generated.
|
|
15
17
|
ℹ Run `npx prisma migrate dev --name actuate-cms` to create the migration.
|
|
16
18
|
|
|
17
|
-
|
|
18
|
-
|
|
19
|
+
✔ Actuate CMS models added to schema.
|
|
20
|
+
- Running prisma generate...
|
|
19
21
|
[90mstdout[2m | dist/__tests__/db-init.test.js[2m > [22m[2mdb:init (WS-D D5 — canonical schema, no stale fragment)[2m > [22m[2mcommand[2m > [22m[2mfails clearly when cms-core cannot be located
|
|
20
22
|
[22m[39mℹ Install it first: `npm install @actuate-media/cms-core`.
|
|
23
|
+
- Reading canonical Actuate schema...
|
|
21
24
|
|
|
25
|
+
✖ Could not locate @actuate-media/cms-core.
|
|
22
26
|
- Reading canonical Actuate schema...
|
|
23
|
-
✔ Actuate CMS models added to schema.
|
|
24
27
|
[90mstdout[2m | dist/__tests__/db-init.test.js[2m > [22m[2mdb:init (WS-D D5 — canonical schema, no stale fragment)[2m > [22m[2mcommand[2m > [22m[2mis idempotent without --force
|
|
25
28
|
[22m[39m✔ Prisma client generated.
|
|
26
29
|
ℹ Run `npx prisma migrate dev --name actuate-cms` to create the migration.
|
|
27
30
|
|
|
31
|
+
✔ Actuate CMS models added to schema.
|
|
28
32
|
- Running prisma generate...
|
|
29
33
|
- Reading canonical Actuate schema...
|
|
30
34
|
ℹ Actuate CMS models already present in schema. Use --force to overwrite.
|
|
31
|
-
[32m✓[39m dist/__tests__/db-init.test.js [2m([22m[2m4 tests[22m[2m)[22m[32m
|
|
35
|
+
[32m✓[39m dist/__tests__/db-init.test.js [2m([22m[2m4 tests[22m[2m)[22m[32m 285[2mms[22m[39m
|
|
32
36
|
- Reading canonical Actuate schema...
|
|
33
37
|
✔ Actuate CMS models added to schema.
|
|
34
|
-
[90mstdout[2m | src/__tests__/db-init.test.ts[2m > [22m[2mdb:init (WS-D D5 — canonical schema, no stale fragment)[2m > [22m[2mcommand[2m > [22m[2minjects canonical models with @@map and no duplicate datasource/generator
|
|
35
38
|
- Running prisma generate...
|
|
39
|
+
[90mstdout[2m | src/__tests__/db-init.test.ts[2m > [22m[2mdb:init (WS-D D5 — canonical schema, no stale fragment)[2m > [22m[2mcommand[2m > [22m[2minjects canonical models with @@map and no duplicate datasource/generator
|
|
36
40
|
[22m[39m✔ Prisma client generated.
|
|
37
41
|
ℹ Run `npx prisma migrate dev --name actuate-cms` to create the migration.
|
|
38
42
|
|
|
39
43
|
[90mstdout[2m | src/__tests__/db-init.test.ts[2m > [22m[2mdb:init (WS-D D5 — canonical schema, no stale fragment)[2m > [22m[2mcommand[2m > [22m[2mfails clearly when cms-core cannot be located
|
|
44
|
+
- Reading canonical Actuate schema...
|
|
40
45
|
[22m[39mℹ Install it first: `npm install @actuate-media/cms-core`.
|
|
41
46
|
|
|
42
|
-
- Reading canonical Actuate schema...
|
|
43
47
|
✖ Could not locate @actuate-media/cms-core.
|
|
44
48
|
- Reading canonical Actuate schema...
|
|
49
|
+
✔ Actuate CMS models added to schema.
|
|
50
|
+
- Running prisma generate...
|
|
45
51
|
[90mstdout[2m | src/__tests__/db-init.test.ts[2m > [22m[2mdb:init (WS-D D5 — canonical schema, no stale fragment)[2m > [22m[2mcommand[2m > [22m[2mis idempotent without --force
|
|
46
52
|
[22m[39m✔ Prisma client generated.
|
|
47
53
|
ℹ Run `npx prisma migrate dev --name actuate-cms` to create the migration.
|
|
48
54
|
|
|
49
|
-
✔ Actuate CMS models added to schema.
|
|
50
|
-
- Running prisma generate...
|
|
51
55
|
- Reading canonical Actuate schema...
|
|
52
56
|
ℹ Actuate CMS models already present in schema. Use --force to overwrite.
|
|
53
|
-
[32m✓[39m src/__tests__/db-init.test.ts [2m([22m[2m4 tests[22m[2m)[22m[32m
|
|
54
|
-
[32m✓[39m dist/__tests__/seed.test.js [2m([22m[
|
|
55
|
-
[32m✓[39m
|
|
56
|
-
[32m✓[39m
|
|
57
|
-
[32m✓[39m src/__tests__/
|
|
57
|
+
[32m✓[39m src/__tests__/db-init.test.ts [2m([22m[2m4 tests[22m[2m)[22m[32m 289[2mms[22m[39m
|
|
58
|
+
[32m✓[39m dist/__tests__/form-seed.test.js [2m([22m[2m10 tests[22m[2m)[22m[32m 57[2mms[22m[39m
|
|
59
|
+
[32m✓[39m src/__tests__/form-seed.test.ts [2m([22m[2m10 tests[22m[2m)[22m[32m 59[2mms[22m[39m
|
|
60
|
+
[32m✓[39m dist/__tests__/vercel-env-matrix.test.js [2m([22m[2m5 tests[22m[2m)[22m[32m 34[2mms[22m[39m
|
|
61
|
+
[32m✓[39m src/__tests__/vercel-env-matrix.test.ts [2m([22m[2m5 tests[22m[2m)[22m[32m 43[2mms[22m[39m
|
|
58
62
|
- Reading canonical Actuate schema...
|
|
59
63
|
✔ Actuate CMS models added to schema.
|
|
60
64
|
- Running prisma generate...
|
|
@@ -62,20 +66,20 @@
|
|
|
62
66
|
[22m[39m✔ Prisma client generated.
|
|
63
67
|
ℹ Run `npx prisma migrate dev --name actuate-cms` to create the migration.
|
|
64
68
|
|
|
65
|
-
[32m✓[39m dist/__tests__/schema-fragment.test.js [2m([22m[2m1 test[22m[2m)[22m[32m
|
|
69
|
+
[32m✓[39m dist/__tests__/schema-fragment.test.js [2m([22m[2m1 test[22m[2m)[22m[32m 96[2mms[22m[39m
|
|
66
70
|
- Reading canonical Actuate schema...
|
|
67
|
-
✔ Actuate CMS models added to schema.
|
|
68
71
|
[90mstdout[2m | src/__tests__/schema-fragment.test.ts[2m > [22m[2mdb:init schema fragment[2m > [22m[2minjects all deploy-critical Actuate models
|
|
72
|
+
✔ Actuate CMS models added to schema.
|
|
69
73
|
[22m[39m✔ Prisma client generated.
|
|
70
74
|
ℹ Run `npx prisma migrate dev --name actuate-cms` to create the migration.
|
|
71
|
-
- Running prisma generate...
|
|
72
75
|
|
|
73
|
-
|
|
74
|
-
[32m✓[39m
|
|
75
|
-
[32m✓[39m
|
|
76
|
+
- Running prisma generate...
|
|
77
|
+
[32m✓[39m src/__tests__/schema-fragment.test.ts [2m([22m[2m1 test[22m[2m)[22m[32m 116[2mms[22m[39m
|
|
78
|
+
[32m✓[39m dist/__tests__/init.test.js [2m([22m[2m2 tests[22m[2m)[22m[32m 54[2mms[22m[39m
|
|
79
|
+
[32m✓[39m src/__tests__/init.test.ts [2m([22m[2m2 tests[22m[2m)[22m[32m 32[2mms[22m[39m
|
|
76
80
|
|
|
77
|
-
[2m Test Files [22m [1m[
|
|
78
|
-
[2m Tests [22m [1m[
|
|
79
|
-
[2m Start at [22m
|
|
80
|
-
[2m Duration [22m
|
|
81
|
+
[2m Test Files [22m [1m[32m16 passed[39m[22m[90m (16)[39m
|
|
82
|
+
[2m Tests [22m [1m[32m100 passed[39m[22m[90m (100)[39m
|
|
83
|
+
[2m Start at [22m 15:53:52
|
|
84
|
+
[2m Duration [22m 23.79s[2m (transform 2.27s, setup 0ms, import 6.86s, tests 2.20s, environment 2ms)[22m
|
|
81
85
|
|
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,33 @@
|
|
|
1
1
|
# @actuate-media/cli
|
|
2
2
|
|
|
3
|
+
## 0.10.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- 232e251: New `actuate seed --upsert` (also on `populate`): documents are matched by collection + slug and updated in place instead of inserting duplicates, making seed files safe to re-run as content evolves. Every update records a version snapshot; `publishedAt` is only stamped on the transition into PUBLISHED; documents without a slug always insert. The summary line reports created vs updated counts.
|
|
8
|
+
|
|
9
|
+
## 0.9.0
|
|
10
|
+
|
|
11
|
+
### Minor Changes
|
|
12
|
+
|
|
13
|
+
- be9b5ff: `actuate seed` now validates `forms`-collection entries before writing anything, with actionable per-form errors. The most common mistake — putting the document envelope status (`PUBLISHED`) in `data.status` instead of the form's own lifecycle status (`active` / `draft` / `archived`, which gates the public endpoints) — gets a targeted explanation, as do fields using `name` instead of `key`/`label` and unknown field types. The `--demo` forms were rewritten to the canonical shape (they previously seeded fields without `key`/`label` and no `data.status`, so `/api/cms/public/forms/:slug` 404'd on them).
|
|
14
|
+
|
|
15
|
+
### Patch Changes
|
|
16
|
+
|
|
17
|
+
- 854152d: Developer experience improvements from external-consumer feedback:
|
|
18
|
+
- Every published package now ships its `CHANGELOG.md` in the npm tarball, and packages that were missing a `README.md` (cli, cms-admin, cms-core, import, platform-vercel, all plugins, sections-react) now have one — so release notes and usage docs are visible on npmjs.com and in `node_modules`.
|
|
19
|
+
- New client-safe form validation entry point: `@actuate-media/cms-core/forms/client` exports `validateFormFieldClient()`, `validateFormValuesClient()`, visibility/conditional helpers, and the exact `FORM_EMAIL_RE` / `FORM_PHONE_RE` regexes the server enforces — zero Node dependencies, so public-site forms can mirror server rules without reimplementing them. The server validator now imports the same primitives, so client and server can never drift.
|
|
20
|
+
|
|
21
|
+
## 0.8.0
|
|
22
|
+
|
|
23
|
+
### Minor Changes
|
|
24
|
+
|
|
25
|
+
- 74662c0: Add Vercel-backed deployment diagnostics and database drift detection.
|
|
26
|
+
- New `actuate vercel:blob-link` command validates the linked Vercel project's Blob connection via the Vercel API and fails when a store is connected but `BLOB_READ_WRITE_TOKEN` is missing for Production/Preview (warns for Development).
|
|
27
|
+
- `actuate deploy:check --vercel` prints a per-environment (Production/Preview/Development) matrix of required and optional variables, failing on any required var missing from Production or Preview. `CRON_SECRET` and the Blob vars are now part of the known set.
|
|
28
|
+
- `actuate doctor`/`deploy:check` now fail (rather than warn) on a partial Blob link detected offline.
|
|
29
|
+
- `actuate db:sync` runs a post-sync `prisma migrate diff` drift check and prints the exact reconciling commands when the database differs from the canonical schema (opt out with `--no-check-drift`).
|
|
30
|
+
|
|
3
31
|
## 0.7.0
|
|
4
32
|
|
|
5
33
|
### Minor Changes
|
package/README.md
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
# @actuate-media/cli
|
|
2
|
+
|
|
3
|
+
CLI for [Actuate CMS](https://github.com/actuate-media/actuatecms) —
|
|
4
|
+
migrations, codegen, seeding, imports/exports, verification, and upgrades.
|
|
5
|
+
|
|
6
|
+
```bash
|
|
7
|
+
npm install -D @actuate-media/cli
|
|
8
|
+
```
|
|
9
|
+
|
|
10
|
+
## Common commands
|
|
11
|
+
|
|
12
|
+
```bash
|
|
13
|
+
actuate migrate # apply Prisma migrations
|
|
14
|
+
actuate seed # seed content from seed scripts
|
|
15
|
+
actuate codegen # generate typed client from actuate.config.ts
|
|
16
|
+
actuate verify # check config, sections, and environment
|
|
17
|
+
actuate verify:cms-sections # editor ↔ frontend section contract check
|
|
18
|
+
actuate update # check for / apply CMS package updates
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
Run `actuate --help` for the full command list.
|
|
22
|
+
|
|
23
|
+
## Release notes
|
|
24
|
+
|
|
25
|
+
See [CHANGELOG.md](./CHANGELOG.md) (shipped with the package) or the
|
|
26
|
+
[GitHub releases](https://github.com/actuate-media/actuatecms/releases).
|
|
27
|
+
|
|
28
|
+
## License
|
|
29
|
+
|
|
30
|
+
MIT
|
|
@@ -2,7 +2,7 @@ import { mkdtemp, mkdir, readFile, readdir, rm, writeFile } from 'node:fs/promis
|
|
|
2
2
|
import { tmpdir } from 'node:os';
|
|
3
3
|
import path from 'node:path';
|
|
4
4
|
import { afterEach, describe, expect, it } from 'vitest';
|
|
5
|
-
import { buildConsumerSchema, syncPrismaAssets } from '../commands/db-sync.js';
|
|
5
|
+
import { buildConsumerSchema, checkSchemaDrift, driftGuidance, syncPrismaAssets, } from '../commands/db-sync.js';
|
|
6
6
|
const CORE_SCHEMA = `generator client {
|
|
7
7
|
provider = "prisma-client"
|
|
8
8
|
output = "../generated"
|
|
@@ -132,5 +132,36 @@ describe('db:sync (WS-D D2 — post-upgrade schema sync)', () => {
|
|
|
132
132
|
expect(second.migrationsAdded).toEqual([]);
|
|
133
133
|
});
|
|
134
134
|
});
|
|
135
|
+
describe('checkSchemaDrift', () => {
|
|
136
|
+
const okRunner = async () => ({ exitCode: 0, stdout: '', stderr: '' });
|
|
137
|
+
const driftRunner = async () => ({
|
|
138
|
+
exitCode: 2,
|
|
139
|
+
stdout: 'ALTER TABLE "actuate_media_usages" RENAME COLUMN "fieldName" TO "fieldPath";',
|
|
140
|
+
stderr: '',
|
|
141
|
+
});
|
|
142
|
+
it('skips when no database URL is configured', async () => {
|
|
143
|
+
const result = await checkSchemaDrift('prisma/schema.prisma', {}, okRunner);
|
|
144
|
+
expect(result.status).toBe('skipped');
|
|
145
|
+
});
|
|
146
|
+
it('reports no-drift on exit code 0', async () => {
|
|
147
|
+
const result = await checkSchemaDrift('prisma/schema.prisma', { DATABASE_URL: 'postgres://x' }, okRunner);
|
|
148
|
+
expect(result.status).toBe('no-drift');
|
|
149
|
+
});
|
|
150
|
+
it('reports drift (with reconciling SQL) on exit code 2', async () => {
|
|
151
|
+
const result = await checkSchemaDrift('prisma/schema.prisma', { DATABASE_URL: 'postgres://x' }, driftRunner);
|
|
152
|
+
expect(result.status).toBe('drift');
|
|
153
|
+
expect(result.detail).toContain('RENAME COLUMN');
|
|
154
|
+
expect(driftGuidance(result).join('\n')).toContain('prisma migrate dev --name');
|
|
155
|
+
});
|
|
156
|
+
it('prefers DIRECT_DATABASE_URL for the diff connection', async () => {
|
|
157
|
+
let usedUrl = '';
|
|
158
|
+
const spyRunner = async ({ url }) => {
|
|
159
|
+
usedUrl = url;
|
|
160
|
+
return { exitCode: 0, stdout: '', stderr: '' };
|
|
161
|
+
};
|
|
162
|
+
await checkSchemaDrift('prisma/schema.prisma', { DATABASE_URL: 'postgres://pooled', DIRECT_DATABASE_URL: 'postgres://direct' }, spyRunner);
|
|
163
|
+
expect(usedUrl).toBe('postgres://direct');
|
|
164
|
+
});
|
|
165
|
+
});
|
|
135
166
|
});
|
|
136
167
|
//# sourceMappingURL=db-sync.test.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"db-sync.test.js","sourceRoot":"","sources":["../../src/__tests__/db-sync.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,OAAO,EAAE,EAAE,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAA;AACnF,OAAO,EAAE,MAAM,EAAE,MAAM,SAAS,CAAA;AAChC,OAAO,IAAI,MAAM,WAAW,CAAA;AAC5B,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,QAAQ,CAAA;AAExD,OAAO,
|
|
1
|
+
{"version":3,"file":"db-sync.test.js","sourceRoot":"","sources":["../../src/__tests__/db-sync.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { describe, expect, it } from 'vitest';
|
|
2
|
-
import { buildDeploymentManifest, createDiagnosticReport, REQUIRED_CMS_MODELS, REQUIRED_ENV_VARS, } from '../deployment/diagnostics.js';
|
|
2
|
+
import { buildDeploymentManifest, createDiagnosticReport, detectBlobLinkState, REQUIRED_CMS_MODELS, REQUIRED_ENV_VARS, } from '../deployment/diagnostics.js';
|
|
3
3
|
describe('deployment diagnostics', () => {
|
|
4
4
|
it('tracks deploy-critical models used by first-run admin features', () => {
|
|
5
5
|
expect(REQUIRED_CMS_MODELS).toEqual(expect.arrayContaining([
|
|
@@ -105,6 +105,47 @@ describe('deployment diagnostics', () => {
|
|
|
105
105
|
}),
|
|
106
106
|
]));
|
|
107
107
|
});
|
|
108
|
+
it('fails (not warns) when a Blob store is linked but the read-write token is missing', () => {
|
|
109
|
+
const report = createDiagnosticReport({
|
|
110
|
+
schemaModels: new Set(REQUIRED_CMS_MODELS),
|
|
111
|
+
schemaContent: '',
|
|
112
|
+
env: {
|
|
113
|
+
DATABASE_URL: 'postgresql://example',
|
|
114
|
+
CMS_SECRET: 'secret',
|
|
115
|
+
CMS_ENCRYPTION_KEY: 'a'.repeat(64),
|
|
116
|
+
NEXT_PUBLIC_SITE_URL: 'https://example.com',
|
|
117
|
+
BLOB_STORE_ID: 'store_abc123',
|
|
118
|
+
BLOB_WEBHOOK_PUBLIC_KEY: 'pk_abc',
|
|
119
|
+
// BLOB_READ_WRITE_TOKEN deliberately absent — the partial-link failure.
|
|
120
|
+
},
|
|
121
|
+
packageManager: 'pnpm',
|
|
122
|
+
schemaPath: 'prisma/schema.prisma',
|
|
123
|
+
});
|
|
124
|
+
expect(report.status).toBe('fail');
|
|
125
|
+
expect(report.checks).toEqual(expect.arrayContaining([expect.objectContaining({ id: 'blob-storage', status: 'fail' })]));
|
|
126
|
+
});
|
|
127
|
+
it('passes the blob check when no Blob storage is configured', () => {
|
|
128
|
+
const report = createDiagnosticReport({
|
|
129
|
+
schemaModels: new Set(REQUIRED_CMS_MODELS),
|
|
130
|
+
schemaContent: '',
|
|
131
|
+
env: {
|
|
132
|
+
DATABASE_URL: 'postgresql://example',
|
|
133
|
+
CMS_SECRET: 'secret',
|
|
134
|
+
CMS_ENCRYPTION_KEY: 'a'.repeat(64),
|
|
135
|
+
NEXT_PUBLIC_SITE_URL: 'https://example.com',
|
|
136
|
+
},
|
|
137
|
+
packageManager: 'pnpm',
|
|
138
|
+
schemaPath: 'prisma/schema.prisma',
|
|
139
|
+
});
|
|
140
|
+
expect(report.checks).toEqual(expect.arrayContaining([expect.objectContaining({ id: 'blob-storage', status: 'pass' })]));
|
|
141
|
+
});
|
|
142
|
+
it('classifies blob link state from env and config signals', () => {
|
|
143
|
+
expect(detectBlobLinkState({ BLOB_READ_WRITE_TOKEN: 'vercel_blob_rw_x' })).toBe('ok');
|
|
144
|
+
expect(detectBlobLinkState({ BLOB_READ_WRITE_TOKEN: 'not-a-real-token' })).toBe('token-format');
|
|
145
|
+
expect(detectBlobLinkState({ BLOB_STORE_ID: 'store_x' })).toBe('partial');
|
|
146
|
+
expect(detectBlobLinkState({}, "storage: { provider: 'vercel-blob' }")).toBe('partial');
|
|
147
|
+
expect(detectBlobLinkState({})).toBe('none');
|
|
148
|
+
});
|
|
108
149
|
it('exposes machine-readable deployment metadata', () => {
|
|
109
150
|
const manifest = buildDeploymentManifest();
|
|
110
151
|
expect(manifest.requiredModels).toEqual(REQUIRED_CMS_MODELS);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"deployment-diagnostics.test.js","sourceRoot":"","sources":["../../src/__tests__/deployment-diagnostics.test.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"deployment-diagnostics.test.js","sourceRoot":"","sources":["../../src/__tests__/deployment-diagnostics.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"form-seed.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/form-seed.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
import { describe, expect, it, vi } from 'vitest';
|
|
2
|
+
// seed.js transitively imports cms-core helpers at module scope via mocks
|
|
3
|
+
// elsewhere; keep the same stub so importing DEMO_FORMS stays side-effect-free.
|
|
4
|
+
vi.mock('@actuate-media/cms-core', () => ({
|
|
5
|
+
extractPlainText: vi.fn(),
|
|
6
|
+
hashContent: vi.fn(),
|
|
7
|
+
sanitizeHtml: vi.fn(),
|
|
8
|
+
createInitialAdmin: vi.fn(),
|
|
9
|
+
}));
|
|
10
|
+
import { validateFormSeedData, validateFormSeeds } from '../utils/form-seed.js';
|
|
11
|
+
import { DEMO_FORMS } from '../commands/seed.js';
|
|
12
|
+
const validForm = () => ({
|
|
13
|
+
name: 'Contact',
|
|
14
|
+
slug: 'contact',
|
|
15
|
+
status: 'active',
|
|
16
|
+
fields: [{ id: 'f1', key: 'email', label: 'Email', type: 'email', required: true, sortOrder: 0 }],
|
|
17
|
+
});
|
|
18
|
+
describe('validateFormSeedData', () => {
|
|
19
|
+
it('accepts the canonical form shape', () => {
|
|
20
|
+
expect(validateFormSeedData(validForm())).toEqual([]);
|
|
21
|
+
});
|
|
22
|
+
it('every DEMO_FORMS entry passes its own validation', () => {
|
|
23
|
+
for (const form of DEMO_FORMS) {
|
|
24
|
+
expect(validateFormSeedData(form, form.slug)).toEqual([]);
|
|
25
|
+
}
|
|
26
|
+
});
|
|
27
|
+
it('explains the data.status vs document status split when status is missing', () => {
|
|
28
|
+
const { status: _status, ...form } = validForm();
|
|
29
|
+
const errors = validateFormSeedData(form);
|
|
30
|
+
expect(errors).toHaveLength(1);
|
|
31
|
+
expect(errors[0]).toContain('data.status to "active"');
|
|
32
|
+
expect(errors[0]).toContain('document envelope status');
|
|
33
|
+
});
|
|
34
|
+
it('catches a document-envelope status (PUBLISHED) used as the form status', () => {
|
|
35
|
+
const errors = validateFormSeedData({ ...validForm(), status: 'PUBLISHED' });
|
|
36
|
+
expect(errors).toHaveLength(1);
|
|
37
|
+
expect(errors[0]).toContain('looks like a document envelope status');
|
|
38
|
+
expect(errors[0]).toContain('"active" | "draft" | "archived"');
|
|
39
|
+
});
|
|
40
|
+
it('rejects unknown statuses with the allowed list', () => {
|
|
41
|
+
const errors = validateFormSeedData({ ...validForm(), status: 'live' });
|
|
42
|
+
expect(errors[0]).toContain('invalid data.status "live"');
|
|
43
|
+
});
|
|
44
|
+
it('requires slug, name, and a non-empty fields array', () => {
|
|
45
|
+
const errors = validateFormSeedData({ status: 'active' });
|
|
46
|
+
expect(errors.some((e) => e.includes('"slug"'))).toBe(true);
|
|
47
|
+
expect(errors.some((e) => e.includes('"name"'))).toBe(true);
|
|
48
|
+
expect(errors.some((e) => e.includes('"fields"'))).toBe(true);
|
|
49
|
+
});
|
|
50
|
+
it('points "name"-keyed fields (the old demo shape) at key/label', () => {
|
|
51
|
+
const errors = validateFormSeedData({
|
|
52
|
+
...validForm(),
|
|
53
|
+
fields: [{ name: 'email', type: 'email' }],
|
|
54
|
+
});
|
|
55
|
+
expect(errors.some((e) => e.includes('Rename name → key'))).toBe(true);
|
|
56
|
+
expect(errors.some((e) => e.includes('"label"'))).toBe(true);
|
|
57
|
+
});
|
|
58
|
+
it('rejects unknown field types', () => {
|
|
59
|
+
const errors = validateFormSeedData({
|
|
60
|
+
...validForm(),
|
|
61
|
+
fields: [{ key: 'x', label: 'X', type: 'dropdown' }],
|
|
62
|
+
});
|
|
63
|
+
expect(errors[0]).toContain('invalid type "dropdown"');
|
|
64
|
+
});
|
|
65
|
+
});
|
|
66
|
+
describe('validateFormSeeds', () => {
|
|
67
|
+
it('only validates forms-collection documents and labels errors by slug', () => {
|
|
68
|
+
const errors = validateFormSeeds([
|
|
69
|
+
{ collection: 'pages', data: { title: 'Home' } },
|
|
70
|
+
{ collection: 'forms', data: { ...validForm(), slug: 'contact', status: 'PUBLISHED' } },
|
|
71
|
+
]);
|
|
72
|
+
expect(errors).toHaveLength(1);
|
|
73
|
+
expect(errors[0]).toContain('forms "contact"');
|
|
74
|
+
});
|
|
75
|
+
it('returns no errors for a payload without forms', () => {
|
|
76
|
+
expect(validateFormSeeds([{ collection: 'pages', data: {} }])).toEqual([]);
|
|
77
|
+
});
|
|
78
|
+
});
|
|
79
|
+
//# sourceMappingURL=form-seed.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"form-seed.test.js","sourceRoot":"","sources":["../../src/__tests__/form-seed.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -112,6 +112,79 @@ describe('seed document creation', () => {
|
|
|
112
112
|
});
|
|
113
113
|
});
|
|
114
114
|
});
|
|
115
|
+
describe('seed document upsert', () => {
|
|
116
|
+
function makeDb(existing) {
|
|
117
|
+
const tx = {
|
|
118
|
+
document: {
|
|
119
|
+
create: vi.fn().mockResolvedValue({ id: 'doc-new' }),
|
|
120
|
+
update: vi.fn().mockResolvedValue({ id: existing?.id ?? 'doc-new' }),
|
|
121
|
+
},
|
|
122
|
+
version: { create: vi.fn() },
|
|
123
|
+
};
|
|
124
|
+
const db = {
|
|
125
|
+
document: { findFirst: vi.fn().mockResolvedValue(existing) },
|
|
126
|
+
$transaction: vi.fn(async (fn) => fn(tx)),
|
|
127
|
+
};
|
|
128
|
+
return { db, tx };
|
|
129
|
+
}
|
|
130
|
+
const doc = {
|
|
131
|
+
collection: 'pages',
|
|
132
|
+
status: 'PUBLISHED',
|
|
133
|
+
data: { title: 'Home v2', slug: 'home' },
|
|
134
|
+
};
|
|
135
|
+
it('updates an existing document matched by collection + slug', async () => {
|
|
136
|
+
const publishedAt = new Date('2026-01-01T00:00:00Z');
|
|
137
|
+
const { db, tx } = makeDb({ id: 'doc-1', status: 'PUBLISHED', publishedAt });
|
|
138
|
+
const result = await createSeedDocument(db, 'admin-1', doc, { upsert: true });
|
|
139
|
+
expect(result).toBe('updated');
|
|
140
|
+
expect(db.document.findFirst).toHaveBeenCalledWith({
|
|
141
|
+
where: { collection: 'pages', slug: 'home', deletedAt: null },
|
|
142
|
+
select: { id: true, status: true, publishedAt: true },
|
|
143
|
+
});
|
|
144
|
+
expect(tx.document.create).not.toHaveBeenCalled();
|
|
145
|
+
expect(tx.document.update).toHaveBeenCalledWith({
|
|
146
|
+
where: { id: 'doc-1' },
|
|
147
|
+
data: expect.objectContaining({
|
|
148
|
+
title: 'Home v2',
|
|
149
|
+
status: 'PUBLISHED',
|
|
150
|
+
// Re-publishing an already-published doc keeps the original timestamp.
|
|
151
|
+
publishedAt,
|
|
152
|
+
updatedById: 'admin-1',
|
|
153
|
+
}),
|
|
154
|
+
});
|
|
155
|
+
expect(tx.version.create).toHaveBeenCalledWith({
|
|
156
|
+
data: expect.objectContaining({ documentId: 'doc-1', changeType: 'UPDATE' }),
|
|
157
|
+
});
|
|
158
|
+
});
|
|
159
|
+
it('stamps publishedAt on the transition into PUBLISHED', async () => {
|
|
160
|
+
const { db, tx } = makeDb({ id: 'doc-1', status: 'DRAFT', publishedAt: null });
|
|
161
|
+
await createSeedDocument(db, 'admin-1', doc, { upsert: true });
|
|
162
|
+
expect(tx.document.update).toHaveBeenCalledWith(expect.objectContaining({
|
|
163
|
+
data: expect.objectContaining({ publishedAt: expect.any(Date) }),
|
|
164
|
+
}));
|
|
165
|
+
});
|
|
166
|
+
it('creates when no document matches', async () => {
|
|
167
|
+
const { db, tx } = makeDb(null);
|
|
168
|
+
const result = await createSeedDocument(db, 'admin-1', doc, { upsert: true });
|
|
169
|
+
expect(result).toBe('created');
|
|
170
|
+
expect(tx.document.create).toHaveBeenCalled();
|
|
171
|
+
expect(tx.document.update).not.toHaveBeenCalled();
|
|
172
|
+
});
|
|
173
|
+
it('always creates slugless documents (no upsert key)', async () => {
|
|
174
|
+
const { db, tx } = makeDb({ id: 'doc-1', status: 'DRAFT', publishedAt: null });
|
|
175
|
+
const result = await createSeedDocument(db, 'admin-1', { collection: 'pages', status: 'DRAFT', data: { title: 'No slug' } }, { upsert: true });
|
|
176
|
+
expect(result).toBe('created');
|
|
177
|
+
expect(db.document.findFirst).not.toHaveBeenCalled();
|
|
178
|
+
expect(tx.document.create).toHaveBeenCalled();
|
|
179
|
+
});
|
|
180
|
+
it('does not look up existing documents without the upsert flag', async () => {
|
|
181
|
+
const { db, tx } = makeDb({ id: 'doc-1', status: 'DRAFT', publishedAt: null });
|
|
182
|
+
const result = await createSeedDocument(db, 'admin-1', doc);
|
|
183
|
+
expect(result).toBe('created');
|
|
184
|
+
expect(db.document.findFirst).not.toHaveBeenCalled();
|
|
185
|
+
expect(tx.document.create).toHaveBeenCalled();
|
|
186
|
+
});
|
|
187
|
+
});
|
|
115
188
|
describe('demo navigations', () => {
|
|
116
189
|
// The scaffold site layout fetches menus by the `main` and `footer` slugs, so
|
|
117
190
|
// the demo seed must provide exactly those — guard against slug drift.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"seed.test.js","sourceRoot":"","sources":["../../src/__tests__/seed.test.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"seed.test.js","sourceRoot":"","sources":["../../src/__tests__/seed.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"vercel-env-matrix.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/vercel-env-matrix.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { describe, expect, it } from 'vitest';
|
|
2
|
+
import { buildEnvMatrix, evaluateBlobLink, presenceForKey } from '../vercel/env-matrix.js';
|
|
3
|
+
function env(key, target) {
|
|
4
|
+
return { key, target };
|
|
5
|
+
}
|
|
6
|
+
describe('presenceForKey', () => {
|
|
7
|
+
it('aggregates targets across multiple entries for the same key', () => {
|
|
8
|
+
const vars = [env('DATABASE_URL', ['production']), env('DATABASE_URL', ['preview'])];
|
|
9
|
+
expect(presenceForKey(vars, 'DATABASE_URL')).toEqual({
|
|
10
|
+
production: true,
|
|
11
|
+
preview: true,
|
|
12
|
+
development: false,
|
|
13
|
+
});
|
|
14
|
+
});
|
|
15
|
+
});
|
|
16
|
+
describe('buildEnvMatrix', () => {
|
|
17
|
+
it('flags required vars missing on production or preview as critical', () => {
|
|
18
|
+
const vars = [
|
|
19
|
+
env('DATABASE_URL', ['production', 'preview', 'development']),
|
|
20
|
+
env('CMS_SECRET', ['production']),
|
|
21
|
+
];
|
|
22
|
+
const matrix = buildEnvMatrix(vars, ['DATABASE_URL', 'CMS_SECRET'], ['CRON_SECRET']);
|
|
23
|
+
expect(matrix.missingCritical).toEqual([{ key: 'CMS_SECRET', targets: ['preview'] }]);
|
|
24
|
+
expect(matrix.rows.find((r) => r.key === 'CRON_SECRET')).toMatchObject({ required: false });
|
|
25
|
+
});
|
|
26
|
+
});
|
|
27
|
+
describe('evaluateBlobLink', () => {
|
|
28
|
+
it('reports none when no blob vars exist', () => {
|
|
29
|
+
expect(evaluateBlobLink([env('DATABASE_URL', ['production'])]).status).toBe('none');
|
|
30
|
+
});
|
|
31
|
+
it('reports partial when linked but token missing on production/preview', () => {
|
|
32
|
+
const report = evaluateBlobLink([
|
|
33
|
+
env('BLOB_STORE_ID', ['production', 'preview', 'development']),
|
|
34
|
+
]);
|
|
35
|
+
expect(report.linked).toBe(true);
|
|
36
|
+
expect(report.status).toBe('partial');
|
|
37
|
+
expect(report.missingTargets).toContain('production');
|
|
38
|
+
});
|
|
39
|
+
it('reports ok when token covers production and preview (dev optional)', () => {
|
|
40
|
+
const report = evaluateBlobLink([
|
|
41
|
+
env('BLOB_STORE_ID', ['production', 'preview']),
|
|
42
|
+
env('BLOB_READ_WRITE_TOKEN', ['production', 'preview']),
|
|
43
|
+
]);
|
|
44
|
+
expect(report.status).toBe('ok');
|
|
45
|
+
expect(report.missingTargets).toEqual(['development']);
|
|
46
|
+
});
|
|
47
|
+
});
|
|
48
|
+
//# sourceMappingURL=vercel-env-matrix.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"vercel-env-matrix.test.js","sourceRoot":"","sources":["../../src/__tests__/vercel-env-matrix.test.ts"],"names":[],"mappings":"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"}
|