@createcms/core 0.1.1

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 (83) hide show
  1. package/README.md +169 -0
  2. package/dist/ab-edge/index.cjs +214 -0
  3. package/dist/ab-edge/index.d.cts +121 -0
  4. package/dist/ab-edge/index.d.ts +121 -0
  5. package/dist/ab-edge/index.js +205 -0
  6. package/dist/bin/createcms.js +3082 -0
  7. package/dist/db.cjs +496 -0
  8. package/dist/db.d.cts +128 -0
  9. package/dist/db.d.ts +128 -0
  10. package/dist/db.js +488 -0
  11. package/dist/index.cjs +13789 -0
  12. package/dist/index.d.cts +10277 -0
  13. package/dist/index.d.ts +10277 -0
  14. package/dist/index.js +13737 -0
  15. package/dist/nanoid.cjs +50 -0
  16. package/dist/nanoid.d.cts +29 -0
  17. package/dist/nanoid.d.ts +29 -0
  18. package/dist/nanoid.js +47 -0
  19. package/dist/next/index.cjs +60 -0
  20. package/dist/next/index.d.cts +141 -0
  21. package/dist/next/index.d.ts +141 -0
  22. package/dist/next/index.js +58 -0
  23. package/dist/next/middleware.cjs +113 -0
  24. package/dist/next/middleware.d.cts +77 -0
  25. package/dist/next/middleware.d.ts +77 -0
  26. package/dist/next/middleware.js +111 -0
  27. package/dist/plugins/ab-test/analytics/upstash.cjs +345 -0
  28. package/dist/plugins/ab-test/analytics/upstash.d.cts +193 -0
  29. package/dist/plugins/ab-test/analytics/upstash.d.ts +193 -0
  30. package/dist/plugins/ab-test/analytics/upstash.js +343 -0
  31. package/dist/plugins/ab-test/client.cjs +686 -0
  32. package/dist/plugins/ab-test/client.d.cts +233 -0
  33. package/dist/plugins/ab-test/client.d.ts +233 -0
  34. package/dist/plugins/ab-test/client.js +684 -0
  35. package/dist/plugins/ab-test/index.cjs +3400 -0
  36. package/dist/plugins/ab-test/index.d.cts +1131 -0
  37. package/dist/plugins/ab-test/index.d.ts +1131 -0
  38. package/dist/plugins/ab-test/index.js +3367 -0
  39. package/dist/plugins/client.cjs +20 -0
  40. package/dist/plugins/client.d.cts +3 -0
  41. package/dist/plugins/client.d.ts +3 -0
  42. package/dist/plugins/client.js +3 -0
  43. package/dist/plugins/consent/client.cjs +315 -0
  44. package/dist/plugins/consent/client.d.cts +145 -0
  45. package/dist/plugins/consent/client.d.ts +145 -0
  46. package/dist/plugins/consent/client.js +313 -0
  47. package/dist/plugins/consent/index.cjs +267 -0
  48. package/dist/plugins/consent/index.d.cts +618 -0
  49. package/dist/plugins/consent/index.d.ts +618 -0
  50. package/dist/plugins/consent/index.js +258 -0
  51. package/dist/plugins/i18n/index.cjs +2177 -0
  52. package/dist/plugins/i18n/index.d.cts +562 -0
  53. package/dist/plugins/i18n/index.d.ts +562 -0
  54. package/dist/plugins/i18n/index.js +2150 -0
  55. package/dist/plugins/media-optimize/index.cjs +315 -0
  56. package/dist/plugins/media-optimize/index.d.cts +144 -0
  57. package/dist/plugins/media-optimize/index.d.ts +144 -0
  58. package/dist/plugins/media-optimize/index.js +311 -0
  59. package/dist/plugins/multi-tenant/index.cjs +210 -0
  60. package/dist/plugins/multi-tenant/index.d.cts +431 -0
  61. package/dist/plugins/multi-tenant/index.d.ts +431 -0
  62. package/dist/plugins/multi-tenant/index.js +207 -0
  63. package/dist/plugins/server.cjs +24 -0
  64. package/dist/plugins/server.d.cts +3 -0
  65. package/dist/plugins/server.d.ts +3 -0
  66. package/dist/plugins/server.js +3 -0
  67. package/dist/react/blocks.cjs +233 -0
  68. package/dist/react/blocks.d.cts +320 -0
  69. package/dist/react/blocks.d.ts +320 -0
  70. package/dist/react/blocks.js +226 -0
  71. package/dist/react/index.cjs +901 -0
  72. package/dist/react/index.d.cts +992 -0
  73. package/dist/react/index.d.ts +992 -0
  74. package/dist/react/index.js +872 -0
  75. package/dist/react/tracking.cjs +243 -0
  76. package/dist/react/tracking.d.cts +364 -0
  77. package/dist/react/tracking.d.ts +364 -0
  78. package/dist/react/tracking.js +216 -0
  79. package/dist/react/variant.cjs +59 -0
  80. package/dist/react/variant.d.cts +26 -0
  81. package/dist/react/variant.d.ts +26 -0
  82. package/dist/react/variant.js +57 -0
  83. package/package.json +303 -0
@@ -0,0 +1,26 @@
1
+ type BlockTreeNode = {
2
+ blockId: string;
3
+ type: string;
4
+ properties: Record<string, unknown>;
5
+ children: BlockTreeNode[];
6
+ };
7
+
8
+ type PageVariant = {
9
+ branchId: string;
10
+ tree: BlockTreeNode;
11
+ };
12
+ /**
13
+ * Pick the tree to render for a variant-coded request.
14
+ *
15
+ * - `branchId` matches a published PAGE variant → that page branch (page-level
16
+ * test). - else `branchId` is an EMBEDDED block's branch → the control page
17
+ * tree with that one embedded block swapped to the branch. - `branchId=null`
18
+ * or no match anywhere → control (fail-closed). `abTest` is always stripped.
19
+ *
20
+ * `controlBranchId` designates the control page variant (page-level tests); when
21
+ * omitted the first variant is used (correct for embedded-only pages + the
22
+ * deterministic default).
23
+ */
24
+ declare function pickVariant(variants: readonly PageVariant[], branchId: string | null, controlBranchId?: string): BlockTreeNode | null;
25
+
26
+ export { pickVariant };
@@ -0,0 +1,57 @@
1
+ import { isResolvedReference } from './blocks.js';
2
+
3
+ /**
4
+ * Walk a tree and, at the (XOR ≤1) embedded A/B reference, swap in the variant
5
+ * whose branch matches `branchId` — then strip `abTest` everywhere so the
6
+ * renderer only ever sees a fully-picked tree. With `branchId=null` (control
7
+ * render) it just strips, leaving every embed on its control branch. Mutates in
8
+ * place (the caller passes a clone).
9
+ */ function resolveVariantTree(tree, branchId) {
10
+ for (const value of Object.values(tree.properties)){
11
+ if (!isResolvedReference(value)) continue;
12
+ // `value` is narrowed to ResolvedReference — its `abTest.variants` are
13
+ // PublishedBranchSnapshot (branchId + isControl + properties + tree).
14
+ const ref = value;
15
+ if (ref.abTest) {
16
+ if (branchId) {
17
+ const picked = ref.abTest.variants.find((v)=>v.branchId === branchId);
18
+ if (picked) {
19
+ ref.tree = picked.tree;
20
+ ref.properties = picked.properties;
21
+ }
22
+ }
23
+ // The picked tree intentionally carries NO A/B metadata downstream:
24
+ // attribution is owned by the edge/URL (the FA4 impression beacon), not
25
+ // the rendered tree. Non-matching branch / control → leave control.
26
+ delete ref.abTest;
27
+ }
28
+ resolveVariantTree(ref.tree, branchId); // descend into the inlined subtree
29
+ }
30
+ for (const child of tree.children){
31
+ resolveVariantTree(child, branchId);
32
+ }
33
+ }
34
+ /**
35
+ * Pick the tree to render for a variant-coded request.
36
+ *
37
+ * - `branchId` matches a published PAGE variant → that page branch (page-level
38
+ * test). - else `branchId` is an EMBEDDED block's branch → the control page
39
+ * tree with that one embedded block swapped to the branch. - `branchId=null`
40
+ * or no match anywhere → control (fail-closed). `abTest` is always stripped.
41
+ *
42
+ * `controlBranchId` designates the control page variant (page-level tests); when
43
+ * omitted the first variant is used (correct for embedded-only pages + the
44
+ * deterministic default).
45
+ */ function pickVariant(variants, branchId, controlBranchId) {
46
+ if (variants.length === 0) return null;
47
+ const pageVariant = branchId ? variants.find((v)=>v.branchId === branchId) : undefined;
48
+ const control = (controlBranchId ? variants.find((v)=>v.branchId === controlBranchId) : undefined) ?? variants[0];
49
+ const base = pageVariant ?? control;
50
+ const tree = structuredClone(base.tree);
51
+ // Page-level pick already chose the right page branch; only an embedded pick
52
+ // (branch not a page variant) needs the in-tree swap. Either way, strip abTest.
53
+ resolveVariantTree(tree, pageVariant ? null : branchId);
54
+ return tree;
55
+ }
56
+
57
+ export { pickVariant };
package/package.json ADDED
@@ -0,0 +1,303 @@
1
+ {
2
+ "name": "@createcms/core",
3
+ "version": "0.1.1",
4
+ "description": "[Work in progress · pre-1.0 · not production-ready] Composable, block-based headless CMS powered by better-call and Drizzle ORM (Postgres). Database-native versioning with Git-like branches, copy-on-write drafts, visual diffs, merges, reusable blocks, nested pages, and a fully type-safe API.",
5
+ "license": "MIT",
6
+ "homepage": "https://github.com/weepaho3/createCMS#readme",
7
+ "bugs": {
8
+ "url": "https://github.com/weepaho3/createCMS/issues"
9
+ },
10
+ "author": {
11
+ "name": "weepaho3",
12
+ "url": "https://github.com/weepaho3"
13
+ },
14
+ "repository": {
15
+ "type": "git",
16
+ "url": "git+https://github.com/weepaho3/createCMS.git",
17
+ "directory": "packages/cms"
18
+ },
19
+ "keywords": [
20
+ "cms",
21
+ "headless-cms",
22
+ "drizzle",
23
+ "postgres",
24
+ "composable",
25
+ "blocks",
26
+ "git-like",
27
+ "versioning",
28
+ "typescript"
29
+ ],
30
+ "engines": {
31
+ "node": ">=18"
32
+ },
33
+ "bin": {
34
+ "createcms": "dist/bin/createcms.js"
35
+ },
36
+ "files": [
37
+ "dist",
38
+ "README.md"
39
+ ],
40
+ "type": "module",
41
+ "main": "./dist/index.cjs",
42
+ "module": "./dist/index.js",
43
+ "types": "./dist/index.d.ts",
44
+ "exports": {
45
+ ".": {
46
+ "import": {
47
+ "types": "./dist/index.d.ts",
48
+ "default": "./dist/index.js"
49
+ },
50
+ "require": {
51
+ "types": "./dist/index.d.cts",
52
+ "default": "./dist/index.cjs"
53
+ }
54
+ },
55
+ "./react": {
56
+ "import": {
57
+ "types": "./dist/react/index.d.ts",
58
+ "default": "./dist/react/index.js"
59
+ },
60
+ "require": {
61
+ "types": "./dist/react/index.d.cts",
62
+ "default": "./dist/react/index.cjs"
63
+ }
64
+ },
65
+ "./react/blocks": {
66
+ "import": {
67
+ "types": "./dist/react/blocks.d.ts",
68
+ "default": "./dist/react/blocks.js"
69
+ },
70
+ "require": {
71
+ "types": "./dist/react/blocks.d.cts",
72
+ "default": "./dist/react/blocks.cjs"
73
+ }
74
+ },
75
+ "./react/variant": {
76
+ "import": {
77
+ "types": "./dist/react/variant.d.ts",
78
+ "default": "./dist/react/variant.js"
79
+ },
80
+ "require": {
81
+ "types": "./dist/react/variant.d.cts",
82
+ "default": "./dist/react/variant.cjs"
83
+ }
84
+ },
85
+ "./react/tracking": {
86
+ "import": {
87
+ "types": "./dist/react/tracking.d.ts",
88
+ "default": "./dist/react/tracking.js"
89
+ },
90
+ "require": {
91
+ "types": "./dist/react/tracking.d.cts",
92
+ "default": "./dist/react/tracking.cjs"
93
+ }
94
+ },
95
+ "./db": {
96
+ "import": {
97
+ "types": "./dist/db.d.ts",
98
+ "default": "./dist/db.js"
99
+ },
100
+ "require": {
101
+ "types": "./dist/db.d.cts",
102
+ "default": "./dist/db.cjs"
103
+ }
104
+ },
105
+ "./nanoid": {
106
+ "import": {
107
+ "types": "./dist/nanoid.d.ts",
108
+ "default": "./dist/nanoid.js"
109
+ },
110
+ "require": {
111
+ "types": "./dist/nanoid.d.cts",
112
+ "default": "./dist/nanoid.cjs"
113
+ }
114
+ },
115
+ "./plugins/server": {
116
+ "import": {
117
+ "types": "./dist/plugins/server.d.ts",
118
+ "default": "./dist/plugins/server.js"
119
+ },
120
+ "require": {
121
+ "types": "./dist/plugins/server.d.cts",
122
+ "default": "./dist/plugins/server.cjs"
123
+ }
124
+ },
125
+ "./plugins/client": {
126
+ "import": {
127
+ "types": "./dist/plugins/client.d.ts",
128
+ "default": "./dist/plugins/client.js"
129
+ },
130
+ "require": {
131
+ "types": "./dist/plugins/client.d.cts",
132
+ "default": "./dist/plugins/client.cjs"
133
+ }
134
+ },
135
+ "./plugins/multi-tenant": {
136
+ "import": {
137
+ "types": "./dist/plugins/multi-tenant/index.d.ts",
138
+ "default": "./dist/plugins/multi-tenant/index.js"
139
+ },
140
+ "require": {
141
+ "types": "./dist/plugins/multi-tenant/index.d.cts",
142
+ "default": "./dist/plugins/multi-tenant/index.cjs"
143
+ }
144
+ },
145
+ "./plugins/i18n": {
146
+ "import": {
147
+ "types": "./dist/plugins/i18n/index.d.ts",
148
+ "default": "./dist/plugins/i18n/index.js"
149
+ },
150
+ "require": {
151
+ "types": "./dist/plugins/i18n/index.d.cts",
152
+ "default": "./dist/plugins/i18n/index.cjs"
153
+ }
154
+ },
155
+ "./plugins/ab-test": {
156
+ "import": {
157
+ "types": "./dist/plugins/ab-test/index.d.ts",
158
+ "default": "./dist/plugins/ab-test/index.js"
159
+ },
160
+ "require": {
161
+ "types": "./dist/plugins/ab-test/index.d.cts",
162
+ "default": "./dist/plugins/ab-test/index.cjs"
163
+ }
164
+ },
165
+ "./plugins/ab-test/client": {
166
+ "import": {
167
+ "types": "./dist/plugins/ab-test/client.d.ts",
168
+ "default": "./dist/plugins/ab-test/client.js"
169
+ },
170
+ "require": {
171
+ "types": "./dist/plugins/ab-test/client.d.cts",
172
+ "default": "./dist/plugins/ab-test/client.cjs"
173
+ }
174
+ },
175
+ "./plugins/ab-test/analytics/upstash": {
176
+ "import": {
177
+ "types": "./dist/plugins/ab-test/analytics/upstash.d.ts",
178
+ "default": "./dist/plugins/ab-test/analytics/upstash.js"
179
+ },
180
+ "require": {
181
+ "types": "./dist/plugins/ab-test/analytics/upstash.d.cts",
182
+ "default": "./dist/plugins/ab-test/analytics/upstash.cjs"
183
+ }
184
+ },
185
+ "./plugins/media-optimize": {
186
+ "import": {
187
+ "types": "./dist/plugins/media-optimize/index.d.ts",
188
+ "default": "./dist/plugins/media-optimize/index.js"
189
+ },
190
+ "require": {
191
+ "types": "./dist/plugins/media-optimize/index.d.cts",
192
+ "default": "./dist/plugins/media-optimize/index.cjs"
193
+ }
194
+ },
195
+ "./plugins/consent": {
196
+ "import": {
197
+ "types": "./dist/plugins/consent/index.d.ts",
198
+ "default": "./dist/plugins/consent/index.js"
199
+ },
200
+ "require": {
201
+ "types": "./dist/plugins/consent/index.d.cts",
202
+ "default": "./dist/plugins/consent/index.cjs"
203
+ }
204
+ },
205
+ "./plugins/consent/client": {
206
+ "import": {
207
+ "types": "./dist/plugins/consent/client.d.ts",
208
+ "default": "./dist/plugins/consent/client.js"
209
+ },
210
+ "require": {
211
+ "types": "./dist/plugins/consent/client.d.cts",
212
+ "default": "./dist/plugins/consent/client.cjs"
213
+ }
214
+ },
215
+ "./next": {
216
+ "import": {
217
+ "types": "./dist/next/index.d.ts",
218
+ "default": "./dist/next/index.js"
219
+ },
220
+ "require": {
221
+ "types": "./dist/next/index.d.cts",
222
+ "default": "./dist/next/index.cjs"
223
+ }
224
+ },
225
+ "./next/middleware": {
226
+ "import": {
227
+ "types": "./dist/next/middleware.d.ts",
228
+ "default": "./dist/next/middleware.js"
229
+ },
230
+ "require": {
231
+ "types": "./dist/next/middleware.d.cts",
232
+ "default": "./dist/next/middleware.cjs"
233
+ }
234
+ },
235
+ "./ab-edge": {
236
+ "import": {
237
+ "types": "./dist/ab-edge/index.d.ts",
238
+ "default": "./dist/ab-edge/index.js"
239
+ },
240
+ "require": {
241
+ "types": "./dist/ab-edge/index.d.cts",
242
+ "default": "./dist/ab-edge/index.cjs"
243
+ }
244
+ }
245
+ },
246
+ "publishConfig": {
247
+ "access": "public"
248
+ },
249
+ "scripts": {
250
+ "build": "bunchee && bun scripts/inject-endpoint-docs.mjs",
251
+ "clean": "rm -rf dist .turbo",
252
+ "generate:schema": "bun run scripts/generate-schema.ts",
253
+ "lint": "oxlint",
254
+ "test": "vitest",
255
+ "check-types": "tsc --noEmit"
256
+ },
257
+ "dependencies": {
258
+ "aws4fetch": "^1.0.20",
259
+ "better-call": "^2.0.2",
260
+ "cac": "^7.0.0",
261
+ "fast-xml-parser": "^5.4.2",
262
+ "jiti": "^2.6.1",
263
+ "kleur": "^4.1.5",
264
+ "nanoid": "^5.1.6",
265
+ "nanostores": "^1.1.0",
266
+ "ora": "^9.3.0",
267
+ "prompts": "^2.4.2",
268
+ "slugify": "^1.6.8",
269
+ "zod": "^4.3.6"
270
+ },
271
+ "devDependencies": {
272
+ "@electric-sql/pglite": "^0.3.15",
273
+ "@jsquash/webp": "^1.5.0",
274
+ "@types/node": "^22.10.2",
275
+ "@types/prompts": "^2.4.9",
276
+ "@types/react": "^19.2.2",
277
+ "@types/react-dom": "^19.2.2",
278
+ "@types/s3rver": "^3.7.4",
279
+ "bunchee": "^6.9.3",
280
+ "drizzle-kit": "^0.31.9",
281
+ "drizzle-orm": "^0.45.0",
282
+ "next": "^16.2.0",
283
+ "react": "^19.2.4",
284
+ "react-dom": "^19.2.4",
285
+ "s3rver": "^3.7.1",
286
+ "typescript": "^5.7.2",
287
+ "vitest": "^4.0.18"
288
+ },
289
+ "peerDependencies": {
290
+ "@jsquash/webp": "^1.5.0",
291
+ "drizzle-orm": "^0.45.0",
292
+ "next": ">=16",
293
+ "react": ">=18"
294
+ },
295
+ "peerDependenciesMeta": {
296
+ "@jsquash/webp": {
297
+ "optional": true
298
+ },
299
+ "next": {
300
+ "optional": true
301
+ }
302
+ }
303
+ }