create-prenta 1.3.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.
Files changed (49) hide show
  1. package/CHANGELOG.md +964 -0
  2. package/LICENSE +21 -0
  3. package/assets/prisma/migrations/0001_init/migration.sql +941 -0
  4. package/assets/prisma/migrations/0002_media_usage_field_path/migration.sql +11 -0
  5. package/assets/prisma/migrations/0003_ai_crawler_hits/migration.sql +21 -0
  6. package/assets/prisma/migrations/0004_drop_search_vector/migration.sql +4 -0
  7. package/assets/prisma/migrations/0005_script_tag_delivery_controls/migration.sql +8 -0
  8. package/assets/prisma/migrations/0006_totp_last_step/migration.sql +4 -0
  9. package/assets/prisma/migrations/0007_workflow_fk_drop_dead_enums/migration.sql +27 -0
  10. package/assets/prisma/migrations/0008_form_delivery_attempts/migration.sql +29 -0
  11. package/assets/prisma/migrations/0009_webhook_secret_rotation/migration.sql +6 -0
  12. package/assets/prisma/migrations/0010_media_is_decorative/migration.sql +3 -0
  13. package/assets/prisma/migrations/0011_media_content_hash/migration.sql +4 -0
  14. package/assets/prisma/migrations/0012_rename_to_prenta/migration.sql +89 -0
  15. package/assets/prisma/migrations/migration_lock.toml +3 -0
  16. package/assets/prisma/schema.prisma +989 -0
  17. package/dist/index.d.ts +3 -0
  18. package/dist/index.d.ts.map +1 -0
  19. package/dist/index.js +182 -0
  20. package/dist/index.js.map +1 -0
  21. package/dist/options.d.ts +160 -0
  22. package/dist/options.d.ts.map +1 -0
  23. package/dist/options.js +206 -0
  24. package/dist/options.js.map +1 -0
  25. package/dist/scaffold.d.ts +45 -0
  26. package/dist/scaffold.d.ts.map +1 -0
  27. package/dist/scaffold.js +2163 -0
  28. package/dist/scaffold.js.map +1 -0
  29. package/dist/templates/admin-page.ts.template.d.ts +24 -0
  30. package/dist/templates/admin-page.ts.template.d.ts.map +1 -0
  31. package/dist/templates/admin-page.ts.template.js +145 -0
  32. package/dist/templates/admin-page.ts.template.js.map +1 -0
  33. package/dist/templates/astro-site.d.ts +36 -0
  34. package/dist/templates/astro-site.d.ts.map +1 -0
  35. package/dist/templates/astro-site.js +918 -0
  36. package/dist/templates/astro-site.js.map +1 -0
  37. package/dist/templates/login-page.ts.template.d.ts +14 -0
  38. package/dist/templates/login-page.ts.template.d.ts.map +1 -0
  39. package/dist/templates/login-page.ts.template.js +143 -0
  40. package/dist/templates/login-page.ts.template.js.map +1 -0
  41. package/dist/templates/marketing-custom.d.ts +56 -0
  42. package/dist/templates/marketing-custom.d.ts.map +1 -0
  43. package/dist/templates/marketing-custom.js +814 -0
  44. package/dist/templates/marketing-custom.js.map +1 -0
  45. package/dist/templates/prenta.config.ts.template.d.ts +3 -0
  46. package/dist/templates/prenta.config.ts.template.d.ts.map +1 -0
  47. package/dist/templates/prenta.config.ts.template.js +253 -0
  48. package/dist/templates/prenta.config.ts.template.js.map +1 -0
  49. package/package.json +58 -0
@@ -0,0 +1,11 @@
1
+ -- Rename MediaUsage.fieldName -> fieldPath so the column matches cms-core's API
2
+ -- layer, server actions, and `actuate doctor` schema expectations. The original
3
+ -- 0001_init created the column as "fieldName"; this brings existing databases in
4
+ -- line without data loss.
5
+ ALTER TABLE "actuate_media_usages" RENAME COLUMN "fieldName" TO "fieldPath";
6
+
7
+ -- Prisma derives the unique-index name from its columns, so recreate it under
8
+ -- the fieldPath name (a bare column rename leaves the old index name in place).
9
+ DROP INDEX "actuate_media_usages_mediaId_documentId_fieldName_key";
10
+
11
+ CREATE UNIQUE INDEX "actuate_media_usages_mediaId_documentId_fieldPath_key" ON "actuate_media_usages"("mediaId", "documentId", "fieldPath");
@@ -0,0 +1,21 @@
1
+ -- AI crawler activity panel: aggregated per-(bot, surface) hit counters for the
2
+ -- llms.txt / llms-full.txt / per-page .md surfaces (plus an optional honeypot).
3
+ -- Stored aggregated (one row per bot+surface, upserted on hit) so the table
4
+ -- stays bounded and needs no periodic pruning.
5
+ CREATE TABLE "actuate_ai_crawler_hits" (
6
+ "id" TEXT NOT NULL,
7
+ "bot" TEXT NOT NULL,
8
+ "surface" TEXT NOT NULL,
9
+ "category" TEXT NOT NULL DEFAULT 'other',
10
+ "hits" INTEGER NOT NULL DEFAULT 1,
11
+ "firstSeenAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
12
+ "lastSeenAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
13
+
14
+ CONSTRAINT "actuate_ai_crawler_hits_pkey" PRIMARY KEY ("id")
15
+ );
16
+
17
+ -- One aggregate row per bot token + surface.
18
+ CREATE UNIQUE INDEX "actuate_ai_crawler_hits_bot_surface_key" ON "actuate_ai_crawler_hits"("bot", "surface");
19
+
20
+ -- Supports "recently active" ordering in the admin panel.
21
+ CREATE INDEX "actuate_ai_crawler_hits_lastSeenAt_idx" ON "actuate_ai_crawler_hits"("lastSeenAt");
@@ -0,0 +1,4 @@
1
+ -- searchVector was never written by the application. Full-text search uses
2
+ -- plainText + title via to_tsvector() and idx_actuate_documents_fts (see
3
+ -- packages/cms-core/src/search/index.ts).
4
+ ALTER TABLE "actuate_documents" DROP COLUMN IF EXISTS "searchVector";
@@ -0,0 +1,8 @@
1
+ -- Design-parity delivery controls for script tags:
2
+ -- loadAsync — inject `async` into external <script src> tags at resolve time
3
+ -- disableInPreview — skip the tag when rendering inside CMS preview mode
4
+ -- consentCategory — cookie-consent gate (none | analytics | marketing | functional | preferences)
5
+ ALTER TABLE "actuate_script_tags"
6
+ ADD COLUMN "loadAsync" BOOLEAN NOT NULL DEFAULT false,
7
+ ADD COLUMN "disableInPreview" BOOLEAN NOT NULL DEFAULT true,
8
+ ADD COLUMN "consentCategory" TEXT NOT NULL DEFAULT 'none';
@@ -0,0 +1,4 @@
1
+ -- Single-use TOTP: track the last consumed time-step so a still-valid code
2
+ -- can't be replayed within its ~90s window (#565). Nullable with no default —
3
+ -- additive and safe on existing rows (null = no TOTP step consumed yet).
4
+ ALTER TABLE "actuate_users" ADD COLUMN "lastTotpStep" INTEGER;
@@ -0,0 +1,27 @@
1
+ -- Schema hygiene.
2
+ --
3
+ -- #559 — WorkflowState.documentId gains a real foreign key to Document (it was
4
+ -- @unique with no relation, so orphan rows and no cascade were possible).
5
+ -- Purge any orphans first — the workflow feature is unbuilt, so the table
6
+ -- is empty in practice — then add the cascade FK.
7
+ --
8
+ -- #558 — drop six enums that were materialized into every consumer database via
9
+ -- CREATE TYPE but referenced by no model (pure schema/DB drift). IF EXISTS
10
+ -- keeps re-runs safe; NO CASCADE means if a downstream consumer somehow
11
+ -- reused one of these conveniently-named types, the DROP fails loudly
12
+ -- rather than silently removing their dependent columns.
13
+
14
+ DELETE FROM "actuate_workflow_states"
15
+ WHERE "documentId" NOT IN (SELECT "id" FROM "actuate_documents");
16
+
17
+ ALTER TABLE "actuate_workflow_states"
18
+ ADD CONSTRAINT "actuate_workflow_states_documentId_fkey"
19
+ FOREIGN KEY ("documentId") REFERENCES "actuate_documents"("id")
20
+ ON DELETE CASCADE ON UPDATE CASCADE;
21
+
22
+ DROP TYPE IF EXISTS "AuditEvent";
23
+ DROP TYPE IF EXISTS "NotificationType";
24
+ DROP TYPE IF EXISTS "OrderStatus";
25
+ DROP TYPE IF EXISTS "PaymentStatus";
26
+ DROP TYPE IF EXISTS "DiscountType";
27
+ DROP TYPE IF EXISTS "ProductType";
@@ -0,0 +1,29 @@
1
+ -- Per-submission form notify/webhook/email delivery attempts (#675).
2
+ CREATE TABLE "actuate_form_delivery_attempts" (
3
+ "id" TEXT NOT NULL,
4
+ "submissionId" TEXT NOT NULL,
5
+ "formId" TEXT NOT NULL,
6
+ "channel" TEXT NOT NULL,
7
+ "destination" TEXT NOT NULL,
8
+ "webhookId" TEXT,
9
+ "status" TEXT NOT NULL DEFAULT 'pending',
10
+ "attempts" INTEGER NOT NULL DEFAULT 0,
11
+ "maxAttempts" INTEGER NOT NULL DEFAULT 3,
12
+ "lastAttemptAt" TIMESTAMP(3),
13
+ "nextRetryAt" TIMESTAMP(3),
14
+ "error" TEXT,
15
+ "responseStatus" INTEGER,
16
+ "skippedReason" TEXT,
17
+ "payload" JSONB,
18
+ "alertedAt" TIMESTAMP(3),
19
+ "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
20
+ "updatedAt" TIMESTAMP(3) NOT NULL,
21
+
22
+ CONSTRAINT "actuate_form_delivery_attempts_pkey" PRIMARY KEY ("id")
23
+ );
24
+
25
+ CREATE INDEX "actuate_form_delivery_attempts_formId_status_idx" ON "actuate_form_delivery_attempts"("formId", "status");
26
+ CREATE INDEX "actuate_form_delivery_attempts_submissionId_idx" ON "actuate_form_delivery_attempts"("submissionId");
27
+ CREATE INDEX "actuate_form_delivery_attempts_status_nextRetryAt_idx" ON "actuate_form_delivery_attempts"("status", "nextRetryAt");
28
+
29
+ ALTER TABLE "actuate_form_delivery_attempts" ADD CONSTRAINT "actuate_form_delivery_attempts_submissionId_fkey" FOREIGN KEY ("submissionId") REFERENCES "actuate_form_submissions"("id") ON DELETE CASCADE ON UPDATE CASCADE;
@@ -0,0 +1,6 @@
1
+ -- AlterTable: grace-window previous secrets for webhook rotation (#679)
2
+ ALTER TABLE "actuate_form_webhooks" ADD COLUMN IF NOT EXISTS "previousSecret" TEXT;
3
+ ALTER TABLE "actuate_form_webhooks" ADD COLUMN IF NOT EXISTS "previousSecretValidUntil" TIMESTAMP(3);
4
+
5
+ ALTER TABLE "actuate_webhook_endpoints" ADD COLUMN IF NOT EXISTS "previousSecret" TEXT;
6
+ ALTER TABLE "actuate_webhook_endpoints" ADD COLUMN IF NOT EXISTS "previousSecretValidUntil" TIMESTAMP(3);
@@ -0,0 +1,3 @@
1
+ -- Persist the decorative-image verdict so empty alt is scored as intentional
2
+ -- WCAG treatment rather than missing-alt (#714).
3
+ ALTER TABLE "actuate_media" ADD COLUMN "isDecorative" BOOLEAN NOT NULL DEFAULT false;
@@ -0,0 +1,4 @@
1
+ -- SHA-256 of final stored bytes for upload dedupe (#718).
2
+ ALTER TABLE "actuate_media" ADD COLUMN "contentHash" TEXT;
3
+
4
+ CREATE INDEX "actuate_media_contentHash_idx" ON "actuate_media"("contentHash");
@@ -0,0 +1,89 @@
1
+ -- Product rename: ActuateCMS -> Prenta.
2
+ -- Renames every actuate_* table to prenta_*, then renames all actuate-prefixed
3
+ -- constraints, indexes, and sequences so physical names keep matching what
4
+ -- Prisma derives from the new @@map names (drift checks compare index names).
5
+ -- Fresh installs run 0001-0011 (which create actuate_* tables) and then this
6
+ -- rename; existing databases rename in place with no data movement.
7
+
8
+ ALTER TABLE "actuate_users" RENAME TO "prenta_users";
9
+ ALTER TABLE "actuate_oauth_accounts" RENAME TO "prenta_oauth_accounts";
10
+ ALTER TABLE "actuate_sessions" RENAME TO "prenta_sessions";
11
+ ALTER TABLE "actuate_api_keys" RENAME TO "prenta_api_keys";
12
+ ALTER TABLE "actuate_audit_logs" RENAME TO "prenta_audit_logs";
13
+ ALTER TABLE "actuate_folders" RENAME TO "prenta_folders";
14
+ ALTER TABLE "actuate_documents" RENAME TO "prenta_documents";
15
+ ALTER TABLE "actuate_versions" RENAME TO "prenta_versions";
16
+ ALTER TABLE "actuate_media" RENAME TO "prenta_media";
17
+ ALTER TABLE "actuate_media_usages" RENAME TO "prenta_media_usages";
18
+ ALTER TABLE "actuate_content_locks" RENAME TO "prenta_content_locks";
19
+ ALTER TABLE "actuate_notifications" RENAME TO "prenta_notifications";
20
+ ALTER TABLE "actuate_content_templates" RENAME TO "prenta_content_templates";
21
+ ALTER TABLE "actuate_sites" RENAME TO "prenta_sites";
22
+ ALTER TABLE "actuate_workflow_states" RENAME TO "prenta_workflow_states";
23
+ ALTER TABLE "actuate_redirects" RENAME TO "prenta_redirects";
24
+ ALTER TABLE "actuate_seo_audit_runs" RENAME TO "prenta_seo_audit_runs";
25
+ ALTER TABLE "actuate_seo_issues" RENAME TO "prenta_seo_issues";
26
+ ALTER TABLE "actuate_redirect_404_hits" RENAME TO "prenta_redirect_404_hits";
27
+ ALTER TABLE "actuate_ai_crawler_hits" RENAME TO "prenta_ai_crawler_hits";
28
+ ALTER TABLE "actuate_redirect_suggestions" RENAME TO "prenta_redirect_suggestions";
29
+ ALTER TABLE "actuate_form_schema_versions" RENAME TO "prenta_form_schema_versions";
30
+ ALTER TABLE "actuate_form_submissions" RENAME TO "prenta_form_submissions";
31
+ ALTER TABLE "actuate_form_submission_files" RENAME TO "prenta_form_submission_files";
32
+ ALTER TABLE "actuate_form_webhooks" RENAME TO "prenta_form_webhooks";
33
+ ALTER TABLE "actuate_form_delivery_attempts" RENAME TO "prenta_form_delivery_attempts";
34
+ ALTER TABLE "actuate_backup_records" RENAME TO "prenta_backup_records";
35
+ ALTER TABLE "actuate_webhook_endpoints" RENAME TO "prenta_webhook_endpoints";
36
+ ALTER TABLE "actuate_webhook_deliveries" RENAME TO "prenta_webhook_deliveries";
37
+ ALTER TABLE "actuate_password_reset_tokens" RENAME TO "prenta_password_reset_tokens";
38
+ ALTER TABLE "actuate_invites" RENAME TO "prenta_invites";
39
+ ALTER TABLE "actuate_script_tags" RENAME TO "prenta_script_tags";
40
+ ALTER TABLE "actuate_page_templates" RENAME TO "prenta_page_templates";
41
+ ALTER TABLE "actuate_saved_sections" RENAME TO "prenta_saved_sections";
42
+ ALTER TABLE "actuate_api_request_metrics" RENAME TO "prenta_api_request_metrics";
43
+ ALTER TABLE "actuate_content_issues" RENAME TO "prenta_content_issues";
44
+
45
+ -- Table renames keep the old constraint/index/sequence names. Prisma compares
46
+ -- physical names when diffing, so rename everything that carries the prefix.
47
+ DO $$
48
+ DECLARE r RECORD;
49
+ BEGIN
50
+ -- Constraints first: renaming a constraint also renames its backing index
51
+ -- (primary keys, unique constraints, foreign keys).
52
+ FOR r IN
53
+ SELECT con.conname, con.conrelid::regclass AS tbl
54
+ FROM pg_constraint con
55
+ JOIN pg_class c ON c.oid = con.conrelid
56
+ JOIN pg_namespace n ON n.oid = c.relnamespace
57
+ WHERE n.nspname = 'public' AND con.conname LIKE '%actuate\_%'
58
+ LOOP
59
+ EXECUTE format(
60
+ 'ALTER TABLE %s RENAME CONSTRAINT %I TO %I',
61
+ r.tbl, r.conname, replace(r.conname, 'actuate_', 'prenta_')
62
+ );
63
+ END LOOP;
64
+
65
+ -- Remaining indexes: plain @@index indexes and the raw-SQL FTS index
66
+ -- (idx_actuate_documents_fts -> idx_prenta_documents_fts).
67
+ FOR r IN
68
+ SELECT indexname FROM pg_indexes
69
+ WHERE schemaname = 'public' AND indexname LIKE '%actuate\_%'
70
+ LOOP
71
+ EXECUTE format(
72
+ 'ALTER INDEX %I RENAME TO %I',
73
+ r.indexname, replace(r.indexname, 'actuate_', 'prenta_')
74
+ );
75
+ END LOOP;
76
+
77
+ -- Sequences behind autoincrement columns.
78
+ FOR r IN
79
+ SELECT c.relname
80
+ FROM pg_class c
81
+ JOIN pg_namespace n ON n.oid = c.relnamespace
82
+ WHERE n.nspname = 'public' AND c.relkind = 'S' AND c.relname LIKE '%actuate\_%'
83
+ LOOP
84
+ EXECUTE format(
85
+ 'ALTER SEQUENCE %I RENAME TO %I',
86
+ r.relname, replace(r.relname, 'actuate_', 'prenta_')
87
+ );
88
+ END LOOP;
89
+ END $$;
@@ -0,0 +1,3 @@
1
+ # Please do not edit this file manually
2
+ # It should be added in your version-control system (e.g., Git)
3
+ provider = "postgresql"