@notionx/create-notionx-app 1.0.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/README.md +139 -0
- package/dist/answers.js +332 -0
- package/dist/answers.js.map +1 -0
- package/dist/cli-notionx.js +388 -0
- package/dist/cli-notionx.js.map +1 -0
- package/dist/cli-notionx.test.js +277 -0
- package/dist/cli-notionx.test.js.map +1 -0
- package/dist/diff.js +40 -0
- package/dist/diff.js.map +1 -0
- package/dist/diff.test.js +90 -0
- package/dist/diff.test.js.map +1 -0
- package/dist/index.js +99 -0
- package/dist/index.js.map +1 -0
- package/dist/locale-add/apply.js +39 -0
- package/dist/locale-add/apply.js.map +1 -0
- package/dist/locale-add/format.js +38 -0
- package/dist/locale-add/format.js.map +1 -0
- package/dist/locale-add/list.js +44 -0
- package/dist/locale-add/list.js.map +1 -0
- package/dist/locale-add/list.test.js +45 -0
- package/dist/locale-add/list.test.js.map +1 -0
- package/dist/locale-add/plan.js +128 -0
- package/dist/locale-add/plan.js.map +1 -0
- package/dist/locale-add/validate.js +46 -0
- package/dist/locale-add/validate.js.map +1 -0
- package/dist/metadata.js +41 -0
- package/dist/metadata.js.map +1 -0
- package/dist/notion-translation-sources/apply.js +61 -0
- package/dist/notion-translation-sources/apply.js.map +1 -0
- package/dist/notion-translation-sources/index.js +3 -0
- package/dist/notion-translation-sources/index.js.map +1 -0
- package/dist/notion-translation-sources/plan.js +33 -0
- package/dist/notion-translation-sources/plan.js.map +1 -0
- package/dist/notionx-source.js +142 -0
- package/dist/notionx-source.js.map +1 -0
- package/dist/notionx-source.test.js +144 -0
- package/dist/notionx-source.test.js.map +1 -0
- package/dist/password.js +18 -0
- package/dist/password.js.map +1 -0
- package/dist/presets.js +83 -0
- package/dist/presets.js.map +1 -0
- package/dist/presets.test.js +50 -0
- package/dist/presets.test.js.map +1 -0
- package/dist/prompt.js +218 -0
- package/dist/prompt.js.map +1 -0
- package/dist/provision/cloudflare.js +236 -0
- package/dist/provision/cloudflare.js.map +1 -0
- package/dist/provision/dependencies.js +219 -0
- package/dist/provision/dependencies.js.map +1 -0
- package/dist/provision/index.js +681 -0
- package/dist/provision/index.js.map +1 -0
- package/dist/provision/index.test.js +54 -0
- package/dist/provision/index.test.js.map +1 -0
- package/dist/provision/inspect.js +109 -0
- package/dist/provision/inspect.js.map +1 -0
- package/dist/provision/inspect.test.js +75 -0
- package/dist/provision/inspect.test.js.map +1 -0
- package/dist/provision/notion.js +1981 -0
- package/dist/provision/notion.js.map +1 -0
- package/dist/provision/notion.test.js +542 -0
- package/dist/provision/notion.test.js.map +1 -0
- package/dist/provision/ntn-credentials.js +198 -0
- package/dist/provision/ntn-credentials.js.map +1 -0
- package/dist/provision/options.js +15 -0
- package/dist/provision/options.js.map +1 -0
- package/dist/provision/password-hash.js +78 -0
- package/dist/provision/password-hash.js.map +1 -0
- package/dist/provision/prompts.js +115 -0
- package/dist/provision/prompts.js.map +1 -0
- package/dist/provision/repair.js +48 -0
- package/dist/provision/repair.js.map +1 -0
- package/dist/provision/repair.test.js +141 -0
- package/dist/provision/repair.test.js.map +1 -0
- package/dist/provision/shell.js +84 -0
- package/dist/provision/shell.js.map +1 -0
- package/dist/provision/wire.js +78 -0
- package/dist/provision/wire.js.map +1 -0
- package/dist/registry/doctor.js +181 -0
- package/dist/registry/doctor.js.map +1 -0
- package/dist/registry/doctor.test.js +180 -0
- package/dist/registry/doctor.test.js.map +1 -0
- package/dist/registry/install.js +217 -0
- package/dist/registry/install.js.map +1 -0
- package/dist/registry/install.test.js +168 -0
- package/dist/registry/install.test.js.map +1 -0
- package/dist/registry/load-registry.js +24 -0
- package/dist/registry/load-registry.js.map +1 -0
- package/dist/registry/load-registry.test.js +59 -0
- package/dist/registry/load-registry.test.js.map +1 -0
- package/dist/registry/migration-planner.js +204 -0
- package/dist/registry/migration-planner.js.map +1 -0
- package/dist/registry/migration-planner.test.js +340 -0
- package/dist/registry/migration-planner.test.js.map +1 -0
- package/dist/registry/migrations-store.js +125 -0
- package/dist/registry/migrations-store.js.map +1 -0
- package/dist/registry/migrations-store.test.js +163 -0
- package/dist/registry/migrations-store.test.js.map +1 -0
- package/dist/registry/migrations-types.js +25 -0
- package/dist/registry/migrations-types.js.map +1 -0
- package/dist/registry/project-meta.js +84 -0
- package/dist/registry/project-meta.js.map +1 -0
- package/dist/registry/registry-items.js +354 -0
- package/dist/registry/registry-items.js.map +1 -0
- package/dist/registry/registry-items.test.js +99 -0
- package/dist/registry/registry-items.test.js.map +1 -0
- package/dist/registry/registry-store.js +232 -0
- package/dist/registry/registry-store.js.map +1 -0
- package/dist/registry/registry-store.test.js +136 -0
- package/dist/registry/registry-store.test.js.map +1 -0
- package/dist/registry/registry-types.js +18 -0
- package/dist/registry/registry-types.js.map +1 -0
- package/dist/registry/registry-types.test.js +146 -0
- package/dist/registry/registry-types.test.js.map +1 -0
- package/dist/registry/render-content-source-files.js +158 -0
- package/dist/registry/render-content-source-files.js.map +1 -0
- package/dist/registry/render-multi-source.js +296 -0
- package/dist/registry/render-multi-source.js.map +1 -0
- package/dist/registry/render-multi-source.test.js +110 -0
- package/dist/registry/render-multi-source.test.js.map +1 -0
- package/dist/registry/text-utils.js +42 -0
- package/dist/registry/text-utils.js.map +1 -0
- package/dist/registry/uninstall.js +250 -0
- package/dist/registry/uninstall.js.map +1 -0
- package/dist/registry/uninstall.test.js +264 -0
- package/dist/registry/uninstall.test.js.map +1 -0
- package/dist/registry/update.js +280 -0
- package/dist/registry/update.js.map +1 -0
- package/dist/registry/update.test.js +229 -0
- package/dist/registry/update.test.js.map +1 -0
- package/dist/render.js +549 -0
- package/dist/render.js.map +1 -0
- package/dist/render.test.js +414 -0
- package/dist/render.test.js.map +1 -0
- package/dist/templates/.dev.vars.example.tmpl +32 -0
- package/dist/templates/.gitignore.tmpl +58 -0
- package/dist/templates/README.md.tmpl +417 -0
- package/dist/templates/app/[slug]/page.tsx.tmpl +55 -0
- package/dist/templates/app/admin/account/page.tsx.tmpl +18 -0
- package/dist/templates/app/admin/content-models/page.tsx.tmpl +6 -0
- package/dist/templates/app/admin/layout.tsx.tmpl +90 -0
- package/dist/templates/app/admin/loading.tsx.tmpl +6 -0
- package/dist/templates/app/admin/page.tsx.tmpl +17 -0
- package/dist/templates/app/api/auth/google/callback/route.ts.tmpl +3 -0
- package/dist/templates/app/api/auth/google/route.ts.tmpl +3 -0
- package/dist/templates/app/api/auth/verify-email/route.ts.tmpl +3 -0
- package/dist/templates/app/api/auth/viewer/route.ts.tmpl +3 -0
- package/dist/templates/app/api/health/route.ts.tmpl +3 -0
- package/dist/templates/app/api/{{contentSourceId}}/[slug]/route.ts.tmpl +27 -0
- package/dist/templates/app/api/{{contentSourceId}}/route.ts.tmpl +18 -0
- package/dist/templates/app/globals.css.tmpl +109 -0
- package/dist/templates/app/layout.tsx.tmpl +56 -0
- package/dist/templates/app/login/page.tsx.tmpl +154 -0
- package/dist/templates/app/page.fallback.tsx.tmpl +31 -0
- package/dist/templates/app/page.tsx.tmpl +42 -0
- package/dist/templates/app/register/page.tsx.tmpl +138 -0
- package/dist/templates/app/{{contentSourceListPath}}/[slug]/page.tsx.tmpl +113 -0
- package/dist/templates/app/{{contentSourceListPath}}/page.tsx.tmpl +74 -0
- package/dist/templates/components/content/post-card.tsx.tmpl +80 -0
- package/dist/templates/components/notion-blocks.tsx.tmpl +668 -0
- package/dist/templates/components/page-blocks/feature-grid-block.tsx.tmpl +68 -0
- package/dist/templates/components/page-blocks/hero-block.tsx.tmpl +73 -0
- package/dist/templates/components/page-blocks/latest-posts-block.tsx.tmpl +59 -0
- package/dist/templates/components/page-blocks/story-block.tsx.tmpl +70 -0
- package/dist/templates/components/page-blocks.fallback.tsx.tmpl +17 -0
- package/dist/templates/components/page-blocks.tsx.tmpl +32 -0
- package/dist/templates/components/search/search-dialog.tsx.tmpl +171 -0
- package/dist/templates/components/site/locale-switcher.tsx.tmpl +65 -0
- package/dist/templates/components/site/site-footer.tsx.tmpl +106 -0
- package/dist/templates/components/site/site-header.tsx.tmpl +80 -0
- package/dist/templates/components/site/site-shell.tsx.tmpl +20 -0
- package/dist/templates/components/site/theme-bootstrap.tsx.tmpl +51 -0
- package/dist/templates/components/theme-provider.tsx.tmpl +14 -0
- package/dist/templates/components/theme-toggle.tsx.tmpl +38 -0
- package/dist/templates/components/ui/accordion.tsx.tmpl +56 -0
- package/dist/templates/components/ui/alert.tsx.tmpl +59 -0
- package/dist/templates/components/ui/aspect-ratio.tsx.tmpl +8 -0
- package/dist/templates/components/ui/avatar.tsx.tmpl +44 -0
- package/dist/templates/components/ui/badge.tsx.tmpl +33 -0
- package/dist/templates/components/ui/button.tsx.tmpl +56 -0
- package/dist/templates/components/ui/card.tsx.tmpl +61 -0
- package/dist/templates/components/ui/checkbox.tsx.tmpl +28 -0
- package/dist/templates/components/ui/dialog.tsx.tmpl +104 -0
- package/dist/templates/components/ui/dropdown-menu.tsx.tmpl +183 -0
- package/dist/templates/components/ui/input.tsx.tmpl +21 -0
- package/dist/templates/components/ui/label.tsx.tmpl +25 -0
- package/dist/templates/components/ui/popover.tsx.tmpl +30 -0
- package/dist/templates/components/ui/radio-group.tsx.tmpl +44 -0
- package/dist/templates/components/ui/select.tsx.tmpl +150 -0
- package/dist/templates/components/ui/separator.tsx.tmpl +30 -0
- package/dist/templates/components/ui/sheet.tsx.tmpl +125 -0
- package/dist/templates/components/ui/skeleton.tsx.tmpl +15 -0
- package/dist/templates/components/ui/sonner.tsx.tmpl +30 -0
- package/dist/templates/components/ui/switch.tsx.tmpl +29 -0
- package/dist/templates/components/ui/table.tsx.tmpl +107 -0
- package/dist/templates/components/ui/tabs.tsx.tmpl +55 -0
- package/dist/templates/components/ui/textarea.tsx.tmpl +24 -0
- package/dist/templates/components/ui/tooltip.tsx.tmpl +30 -0
- package/dist/templates/components.json.tmpl +21 -0
- package/dist/templates/env.d.ts.tmpl +32 -0
- package/dist/templates/lib/admin/actions.ts.tmpl +43 -0
- package/dist/templates/lib/admin/context.tsx.tmpl +209 -0
- package/dist/templates/lib/admin/nav.ts.tmpl +23 -0
- package/dist/templates/lib/auth.config.fallback.ts.tmpl +10 -0
- package/dist/templates/lib/auth.config.ts.tmpl +45 -0
- package/dist/templates/lib/blocks/translations.ts.tmpl +44 -0
- package/dist/templates/lib/blog/translations.ts.tmpl +52 -0
- package/dist/templates/lib/content/models.ts.tmpl +53 -0
- package/dist/templates/lib/i18n/config.ts.tmpl +18 -0
- package/dist/templates/lib/i18n/index.ts.tmpl +1 -0
- package/dist/templates/lib/locale-contract/built-in.ts.tmpl +19 -0
- package/dist/templates/lib/locale-contract/index.ts.tmpl +3 -0
- package/dist/templates/lib/locale-contract/paths.ts.tmpl +29 -0
- package/dist/templates/lib/pages/model.ts.tmpl +16 -0
- package/dist/templates/lib/pages/source.ts.tmpl +566 -0
- package/dist/templates/lib/pages/translations.ts.tmpl +34 -0
- package/dist/templates/lib/search/config.fallback.ts.tmpl +11 -0
- package/dist/templates/lib/search/config.ts.tmpl +25 -0
- package/dist/templates/lib/site/config.ts.tmpl +120 -0
- package/dist/templates/lib/site/request-env.ts.tmpl +71 -0
- package/dist/templates/lib/site/settings.fallback.ts.tmpl +21 -0
- package/dist/templates/lib/site/settings.ts.tmpl +320 -0
- package/dist/templates/lib/site/translations.ts.tmpl +30 -0
- package/dist/templates/lib/utils.ts.tmpl +9 -0
- package/dist/templates/migrations/0001_init.sql.tmpl +57 -0
- package/dist/templates/migrations/0002_admin_seed.sql.tmpl +30 -0
- package/dist/templates/migrations/0003_search_index.sql.tmpl +29 -0
- package/dist/templates/next.config.ts.tmpl +18 -0
- package/dist/templates/package.json.tmpl +40 -0
- package/dist/templates/shims/cloudflare-workers-empty.mjs +4 -0
- package/dist/templates/shims/next-headers-empty.mjs +4 -0
- package/dist/templates/tests/smoke.test.ts.tmpl +83 -0
- package/dist/templates/tsconfig.json.tmpl +31 -0
- package/dist/templates/vite.config.ts.tmpl +53 -0
- package/dist/templates/vitest.config.ts.tmpl +13 -0
- package/dist/templates/worker/index.ts.tmpl +52 -0
- package/dist/templates/wrangler.jsonc.tmpl +44 -0
- package/dist/ui-presets.js +60 -0
- package/dist/ui-presets.js.map +1 -0
- package/package.json +60 -0
|
@@ -0,0 +1,280 @@
|
|
|
1
|
+
// packages/create-notionx-app/src/registry/update.ts
|
|
2
|
+
//
|
|
3
|
+
// `notionx update` entry point. v2 protocol.
|
|
4
|
+
//
|
|
5
|
+
// What this does:
|
|
6
|
+
// 1. Read `.notionx/registry.json`.
|
|
7
|
+
// 2. Walk the installed manifest, compare versions to the
|
|
8
|
+
// catalog.
|
|
9
|
+
// 3. For each upgradable item, build a `UpdatePlan` (pure) and
|
|
10
|
+
// write **one set of payload files** per chain hop:
|
|
11
|
+
// - `.notionx/migrations/NNNN_<item>_<from>_<to>.notion-diff.json`
|
|
12
|
+
// - `.notionx/migrations/NNNN_<item>_<from>_<to>.d1.sql`
|
|
13
|
+
// - `.notionx/migrations/_meta.json` (always rewritten)
|
|
14
|
+
// 4. **Never** touch Notion or D1 directly. The user runs the
|
|
15
|
+
// migration by hand (or via the future `notionx migrate`
|
|
16
|
+
// command).
|
|
17
|
+
// 5. Re-render `lib/content/models.ts` so the registry stays
|
|
18
|
+
// in sync with the new catalog shape.
|
|
19
|
+
//
|
|
20
|
+
// Codemods (TS transformations) and `user`-owned file re-renders
|
|
21
|
+
// are scaffolded in PR 4 but not yet active; the planner already
|
|
22
|
+
// classifies them and `applyUpdate` records them in the
|
|
23
|
+
// `UpdatePlan` so the CLI can report them.
|
|
24
|
+
import { mkdir, writeFile } from "node:fs/promises";
|
|
25
|
+
import path from "node:path";
|
|
26
|
+
import { loadRegistry } from "./load-registry.js";
|
|
27
|
+
import { buildUpdatePlan } from "./migration-planner.js";
|
|
28
|
+
import { appendMigration, emptyMeta, MIGRATIONS_META, readMigrationsMeta, writeMigrationPayload, } from "./migrations-store.js";
|
|
29
|
+
import { renderContentSourceFiles } from "./render-content-source-files.js";
|
|
30
|
+
import { readProjectMeta } from "./project-meta.js";
|
|
31
|
+
export async function applyUpdate(input) {
|
|
32
|
+
const { projectDir, templatesDir, catalogItems } = input;
|
|
33
|
+
const loaded = await loadRegistry(projectDir);
|
|
34
|
+
const manifest = loaded.manifest;
|
|
35
|
+
const applied = (await readMigrationsMeta(projectDir)) ?? emptyMeta();
|
|
36
|
+
// Resolve scope before the planner sees anything: filtering
|
|
37
|
+
// here keeps the planner pure (it still takes plain arrays)
|
|
38
|
+
// and lets us surface a friendly error for unknown item ids.
|
|
39
|
+
const scope = input.scope ?? { kind: "all" };
|
|
40
|
+
const installed = filterInstalledByScope(manifest.installed, scope);
|
|
41
|
+
const catalogItemsScoped = filterCatalogByScope(catalogItems, scope, manifest);
|
|
42
|
+
// Project meta for token rendering. We reuse the same helper
|
|
43
|
+
// install.ts uses — read package.json to get the project name.
|
|
44
|
+
const project = await readProjectMeta(projectDir, manifest);
|
|
45
|
+
const plan = buildUpdatePlan({
|
|
46
|
+
installed,
|
|
47
|
+
catalogItems: catalogItemsScoped,
|
|
48
|
+
appliedMigrations: applied.history,
|
|
49
|
+
});
|
|
50
|
+
// Group steps by (itemId, fromV, toV) hop. We assume the
|
|
51
|
+
// planner emits at most one hop per item (single-hop rule).
|
|
52
|
+
// PR 4 keeps that constraint explicit; multi-hop will be a
|
|
53
|
+
// small extension.
|
|
54
|
+
const hops = new Map();
|
|
55
|
+
for (const step of [...plan.additive, ...plan.destructive]) {
|
|
56
|
+
const key = `${step.itemId}@${itemVersionById(manifest.installed, step.itemId)}`;
|
|
57
|
+
let hop = hops.get(key);
|
|
58
|
+
if (!hop) {
|
|
59
|
+
const fromV = itemVersionById(manifest.installed, step.itemId);
|
|
60
|
+
const toV = itemTargetVersion(catalogItems, step.itemId);
|
|
61
|
+
hop = { itemId: step.itemId, fromV, toV, additive: [], destructive: [] };
|
|
62
|
+
hops.set(key, hop);
|
|
63
|
+
}
|
|
64
|
+
if (plan.additive.includes(step))
|
|
65
|
+
hop.additive.push(step);
|
|
66
|
+
else
|
|
67
|
+
hop.destructive.push(step);
|
|
68
|
+
}
|
|
69
|
+
const wroteFiles = [];
|
|
70
|
+
let sequence;
|
|
71
|
+
const followup = [];
|
|
72
|
+
const rerenderedFiles = [];
|
|
73
|
+
if (input.dryRun) {
|
|
74
|
+
return {
|
|
75
|
+
plans: plan,
|
|
76
|
+
wroteFiles,
|
|
77
|
+
wroteManifest: false,
|
|
78
|
+
rerenderedFiles,
|
|
79
|
+
followup,
|
|
80
|
+
};
|
|
81
|
+
}
|
|
82
|
+
// Write the per-hop payload files. We always do additive
|
|
83
|
+
// + destructive in the same migration (one seq, multiple
|
|
84
|
+
// payload files) so the user's bookkeeping is "one
|
|
85
|
+
// migration per item version".
|
|
86
|
+
for (const hop of hops.values()) {
|
|
87
|
+
if (hop.additive.length === 0 && hop.destructive.length === 0)
|
|
88
|
+
continue;
|
|
89
|
+
const slug = `${hop.itemId}_${hop.fromV}_to_${hop.toV}`;
|
|
90
|
+
// Notion diff (if any notion-* steps).
|
|
91
|
+
const notionSteps = [...hop.additive, ...hop.destructive].filter((s) => s.kind === "notion-field-add" ||
|
|
92
|
+
s.kind === "notion-field-rename" ||
|
|
93
|
+
s.kind === "notion-field-deprecate");
|
|
94
|
+
if (notionSteps.length > 0) {
|
|
95
|
+
const filename = `${slug}.notion-diff.json`;
|
|
96
|
+
const payload = JSON.stringify({ itemId: hop.itemId, fromV: hop.fromV, toV: hop.toV, steps: notionSteps }, null, 2);
|
|
97
|
+
await writeMigrationPayload(projectDir, filename, `${payload}\n`);
|
|
98
|
+
wroteFiles.push(filename);
|
|
99
|
+
followup.push(`Apply Notion diff by running the steps in ${filename} (manually or via Notion API).`);
|
|
100
|
+
}
|
|
101
|
+
// D1 SQL (if any d1-* steps, including d1-migration-file refs).
|
|
102
|
+
const d1Steps = [...hop.additive, ...hop.destructive].filter((s) => s.kind === "d1-table-create" ||
|
|
103
|
+
s.kind === "d1-table-alter" ||
|
|
104
|
+
s.kind === "d1-migration-file");
|
|
105
|
+
if (d1Steps.length > 0) {
|
|
106
|
+
const filename = `${slug}.d1.sql`;
|
|
107
|
+
const sql = d1Steps
|
|
108
|
+
.map((s) => {
|
|
109
|
+
if (s.kind === "d1-table-create" || s.kind === "d1-table-alter") {
|
|
110
|
+
return `-- ${s.itemId}: ${s.kind} ${s.tableName}\n${s.sql}`;
|
|
111
|
+
}
|
|
112
|
+
if (s.kind === "d1-migration-file") {
|
|
113
|
+
return `-- ${s.itemId}: d1-migration-file (apply the SQL in ${s.file})`;
|
|
114
|
+
}
|
|
115
|
+
return "";
|
|
116
|
+
})
|
|
117
|
+
.filter(Boolean)
|
|
118
|
+
.join("\n\n");
|
|
119
|
+
await writeMigrationPayload(projectDir, filename, `${sql}\n`);
|
|
120
|
+
wroteFiles.push(filename);
|
|
121
|
+
followup.push(`Apply D1 SQL with: wrangler d1 migrations apply <DB_NAME> --remote`);
|
|
122
|
+
}
|
|
123
|
+
// Env vars (if any env-add steps).
|
|
124
|
+
const envSteps = [...hop.additive, ...hop.destructive].filter((s) => s.kind === "env-add");
|
|
125
|
+
if (envSteps.length > 0) {
|
|
126
|
+
const filename = `${slug}.env.json`;
|
|
127
|
+
const payload = JSON.stringify({
|
|
128
|
+
itemId: hop.itemId,
|
|
129
|
+
fromV: hop.fromV,
|
|
130
|
+
toV: hop.toV,
|
|
131
|
+
vars: envSteps.map((s) => s.kind === "env-add"
|
|
132
|
+
? {
|
|
133
|
+
name: s.name,
|
|
134
|
+
...(s.default !== undefined ? { default: s.default } : {}),
|
|
135
|
+
...(s.secret !== undefined ? { secret: s.secret } : {}),
|
|
136
|
+
}
|
|
137
|
+
: null),
|
|
138
|
+
}, null, 2);
|
|
139
|
+
await writeMigrationPayload(projectDir, filename, `${payload}\n`);
|
|
140
|
+
wroteFiles.push(filename);
|
|
141
|
+
for (const s of envSteps) {
|
|
142
|
+
if (s.kind !== "env-add")
|
|
143
|
+
continue;
|
|
144
|
+
const hint = s.secret
|
|
145
|
+
? `Set secret ${s.name} with: wrangler secret put ${s.name}`
|
|
146
|
+
: `Add ${s.name} to your .dev.vars and wrangler.jsonc vars`;
|
|
147
|
+
followup.push(hint);
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
// Config merge (if any config-merge steps).
|
|
151
|
+
const configSteps = [...hop.additive, ...hop.destructive].filter((s) => s.kind === "config-merge");
|
|
152
|
+
if (configSteps.length > 0) {
|
|
153
|
+
const filename = `${slug}.config-merge.json`;
|
|
154
|
+
const payload = JSON.stringify({
|
|
155
|
+
itemId: hop.itemId,
|
|
156
|
+
fromV: hop.fromV,
|
|
157
|
+
toV: hop.toV,
|
|
158
|
+
merges: configSteps.map((s) => s.kind === "config-merge"
|
|
159
|
+
? { file: s.file, json: s.json }
|
|
160
|
+
: null),
|
|
161
|
+
}, null, 2);
|
|
162
|
+
await writeMigrationPayload(projectDir, filename, `${payload}\n`);
|
|
163
|
+
wroteFiles.push(filename);
|
|
164
|
+
followup.push(`Merge config changes from ${filename} into the referenced files (deep-merge each entry's json into the target file).`);
|
|
165
|
+
}
|
|
166
|
+
// Append the migration entry to _meta.json. **The sequence
|
|
167
|
+
// number is whatever `appendMigration` assigns** (the
|
|
168
|
+
// canonical nextSequence from the directory). The payload
|
|
169
|
+
// filenames use the **un-padded** version pair as a slug, so
|
|
170
|
+
// they're stable across replays of the same hop.
|
|
171
|
+
const fileRef = pickMigrationFileRef(slug, {
|
|
172
|
+
notion: notionSteps.length > 0,
|
|
173
|
+
d1: d1Steps.length > 0,
|
|
174
|
+
env: envSteps.length > 0,
|
|
175
|
+
config: configSteps.length > 0,
|
|
176
|
+
});
|
|
177
|
+
const entry = await appendMigration(projectDir, {
|
|
178
|
+
itemId: hop.itemId,
|
|
179
|
+
itemKind: "content-source", // refined in PR 4.5 from the catalog
|
|
180
|
+
label: `${hop.itemId} ${hop.fromV}->${hop.toV}`,
|
|
181
|
+
file: fileRef,
|
|
182
|
+
applied: false,
|
|
183
|
+
});
|
|
184
|
+
sequence = entry.sequence;
|
|
185
|
+
wroteFiles.push(MIGRATIONS_META);
|
|
186
|
+
}
|
|
187
|
+
// Re-render every declared file for any installed item whose
|
|
188
|
+
// version moved (so bridges, pages, and API routes all stay in
|
|
189
|
+
// sync with the catalog version bump). We *don't* re-render
|
|
190
|
+
// when no hops were generated — the user hasn't moved versions,
|
|
191
|
+
// so nothing changed.
|
|
192
|
+
if (hops.size > 0) {
|
|
193
|
+
for (const item of installed) {
|
|
194
|
+
const catalog = catalogItems.find((c) => c.id === item.id);
|
|
195
|
+
if (!catalog)
|
|
196
|
+
continue;
|
|
197
|
+
// Skip items that didn't move versions.
|
|
198
|
+
if (catalog.version === item.version)
|
|
199
|
+
continue;
|
|
200
|
+
const rendered = await renderContentSourceFiles({
|
|
201
|
+
projectDir,
|
|
202
|
+
templatesDir,
|
|
203
|
+
item: catalog,
|
|
204
|
+
installed: manifest.installed,
|
|
205
|
+
project,
|
|
206
|
+
});
|
|
207
|
+
for (const f of rendered) {
|
|
208
|
+
await mkdir(path.dirname(f.absolutePath), { recursive: true });
|
|
209
|
+
await writeFile(f.absolutePath, f.content, "utf8");
|
|
210
|
+
rerenderedFiles.push(f.projectRelativePath);
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
// The registry's `installed[].version` field is **never** bumped
|
|
215
|
+
// by `applyUpdate`. The bump only happens after the user
|
|
216
|
+
// confirms they applied the migration by running
|
|
217
|
+
// `notionx migrate --mark-applied <seq>`. This is what
|
|
218
|
+
// guarantees the migration is safe to retry: if the user
|
|
219
|
+
// aborts mid-way, the next `notionx update` will detect
|
|
220
|
+
// they're still on the old version and re-emit the same plan.
|
|
221
|
+
//
|
|
222
|
+
// We still re-render the bridge files (worker/index.ts,
|
|
223
|
+
// models.ts, etc.) so the *source code* is in sync with what
|
|
224
|
+
// the *next applied* migration will produce. The user can
|
|
225
|
+
// ship that code immediately; the migration itself is what
|
|
226
|
+
// backfills their data.
|
|
227
|
+
return {
|
|
228
|
+
plans: plan,
|
|
229
|
+
...(sequence !== undefined ? { sequence } : {}),
|
|
230
|
+
wroteFiles,
|
|
231
|
+
wroteManifest: false,
|
|
232
|
+
rerenderedFiles,
|
|
233
|
+
followup,
|
|
234
|
+
};
|
|
235
|
+
}
|
|
236
|
+
// ---- internals ----
|
|
237
|
+
function itemVersionById(installed, id) {
|
|
238
|
+
return installed.find((i) => i.id === id)?.version ?? 0;
|
|
239
|
+
}
|
|
240
|
+
function itemTargetVersion(catalog, id) {
|
|
241
|
+
return catalog.find((c) => c.id === id)?.version ?? 0;
|
|
242
|
+
}
|
|
243
|
+
/**
|
|
244
|
+
* Pick the `MigrationFileRef` for the migration entry. Priority
|
|
245
|
+
* order matches the payload-writing blocks above. Falls back to
|
|
246
|
+
* `d1-sql` when no payload file was written (e.g. ts-codemod-only
|
|
247
|
+
* hops) so the entry always has a valid `file` field — the
|
|
248
|
+
* pre-existing behaviour.
|
|
249
|
+
*/
|
|
250
|
+
function pickMigrationFileRef(slug, present) {
|
|
251
|
+
if (present.notion)
|
|
252
|
+
return { kind: "notion-diff", filename: `${slug}.notion-diff.json` };
|
|
253
|
+
if (present.d1)
|
|
254
|
+
return { kind: "d1-sql", filename: `${slug}.d1.sql` };
|
|
255
|
+
if (present.env)
|
|
256
|
+
return { kind: "env", filename: `${slug}.env.json` };
|
|
257
|
+
if (present.config)
|
|
258
|
+
return { kind: "config-merge", filename: `${slug}.config-merge.json` };
|
|
259
|
+
return { kind: "d1-sql", filename: `${slug}.d1.sql` };
|
|
260
|
+
}
|
|
261
|
+
// ---- scope helpers ----
|
|
262
|
+
function filterInstalledByScope(installed, scope) {
|
|
263
|
+
if (scope.kind === "all")
|
|
264
|
+
return installed.slice();
|
|
265
|
+
const match = installed.find((i) => i.id === scope.itemId);
|
|
266
|
+
if (!match) {
|
|
267
|
+
throw new Error(`Cannot update "${scope.itemId}": not installed. Run \`notionx diff\` to see installed items.`);
|
|
268
|
+
}
|
|
269
|
+
return [match];
|
|
270
|
+
}
|
|
271
|
+
function filterCatalogByScope(catalog, scope, _manifest) {
|
|
272
|
+
if (scope.kind === "all")
|
|
273
|
+
return catalog.slice();
|
|
274
|
+
const match = catalog.find((c) => c.id === scope.itemId);
|
|
275
|
+
if (!match) {
|
|
276
|
+
throw new Error(`Cannot update "${scope.itemId}": not present in the official catalog.`);
|
|
277
|
+
}
|
|
278
|
+
return [match];
|
|
279
|
+
}
|
|
280
|
+
//# sourceMappingURL=update.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"update.js","sourceRoot":"","sources":["../../src/registry/update.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,229 @@
|
|
|
1
|
+
// packages/create-notionx-app/src/registry/update.test.ts
|
|
2
|
+
import { mkdir, mkdtemp, readFile, rm, writeFile } from "node:fs/promises";
|
|
3
|
+
import os from "node:os";
|
|
4
|
+
import path from "node:path";
|
|
5
|
+
import { afterEach, beforeEach, describe, expect, it } from "vitest";
|
|
6
|
+
import { resolveTemplatesDir } from "../render.js";
|
|
7
|
+
import { REGISTRY_SCHEMA_V2 } from "./registry-types.js";
|
|
8
|
+
import { applyUpdate } from "./update.js";
|
|
9
|
+
const blogV2 = {
|
|
10
|
+
id: "blog",
|
|
11
|
+
kind: "content-source",
|
|
12
|
+
version: 2,
|
|
13
|
+
source: { kind: "official", name: "@notionx/official" },
|
|
14
|
+
publishedAt: "2026-06-15T00:00:00.000Z",
|
|
15
|
+
params: { contentSourceId: "blog" },
|
|
16
|
+
files: [
|
|
17
|
+
{ path: "app/blog/page.tsx", ownership: "user" },
|
|
18
|
+
],
|
|
19
|
+
capabilities: {
|
|
20
|
+
envVars: ["NOTION_BLOG_DATA_SOURCE_ID"],
|
|
21
|
+
},
|
|
22
|
+
migrations: [
|
|
23
|
+
{
|
|
24
|
+
from: "blog@1",
|
|
25
|
+
to: "blog@2",
|
|
26
|
+
steps: [
|
|
27
|
+
{
|
|
28
|
+
kind: "notion-field-add",
|
|
29
|
+
source: "NOTION_BLOG_DATA_SOURCE_ID",
|
|
30
|
+
property: "Author",
|
|
31
|
+
type: "people",
|
|
32
|
+
},
|
|
33
|
+
{
|
|
34
|
+
kind: "d1-table-create",
|
|
35
|
+
name: "blog_authors",
|
|
36
|
+
sql: "CREATE TABLE blog_authors (id INTEGER PRIMARY KEY, name TEXT NOT NULL);",
|
|
37
|
+
},
|
|
38
|
+
],
|
|
39
|
+
},
|
|
40
|
+
],
|
|
41
|
+
};
|
|
42
|
+
const blogV1 = {
|
|
43
|
+
...blogV2,
|
|
44
|
+
version: 1,
|
|
45
|
+
migrations: [],
|
|
46
|
+
};
|
|
47
|
+
async function seedProject(projectDir, catalogItems, installed) {
|
|
48
|
+
await writeFile(path.join(projectDir, "package.json"), JSON.stringify({
|
|
49
|
+
name: "demo",
|
|
50
|
+
version: "0.0.0",
|
|
51
|
+
private: true,
|
|
52
|
+
dependencies: { "@notionx/core": "^2.0.0" },
|
|
53
|
+
}), "utf8");
|
|
54
|
+
await mkdir(path.join(projectDir, ".notionx"), { recursive: true });
|
|
55
|
+
await writeFile(path.join(projectDir, ".notionx/registry.json"), JSON.stringify({
|
|
56
|
+
$schema: REGISTRY_SCHEMA_V2,
|
|
57
|
+
projectKind: "notionx",
|
|
58
|
+
scaffoldVersion: "2.0.0",
|
|
59
|
+
notionxCore: "^2.0.0",
|
|
60
|
+
compat: { mode: "v2-native" },
|
|
61
|
+
registries: {},
|
|
62
|
+
installed,
|
|
63
|
+
managedFiles: { platform: ["package.json"], bridge: [], user: [] },
|
|
64
|
+
}), "utf8");
|
|
65
|
+
// Inject a fake catalog by writing a tiny catalog module that
|
|
66
|
+
// applyUpdate reads via the `catalog` param.
|
|
67
|
+
return { catalog: catalogItems };
|
|
68
|
+
}
|
|
69
|
+
describe("applyUpdate", () => {
|
|
70
|
+
let dir;
|
|
71
|
+
let templatesDir;
|
|
72
|
+
beforeEach(async () => {
|
|
73
|
+
dir = await mkdtemp(path.join(os.tmpdir(), "notionx-update-"));
|
|
74
|
+
await mkdir(path.join(dir, ".notionx"), { recursive: true });
|
|
75
|
+
templatesDir = await resolveTemplatesDir();
|
|
76
|
+
});
|
|
77
|
+
afterEach(async () => {
|
|
78
|
+
await rm(dir, { recursive: true, force: true });
|
|
79
|
+
});
|
|
80
|
+
it("generates a migration file + _meta entry, without modifying the data source", async () => {
|
|
81
|
+
const { catalog } = await seedProject(dir, [blogV2], [
|
|
82
|
+
{
|
|
83
|
+
id: "blog",
|
|
84
|
+
kind: "content-source",
|
|
85
|
+
version: 1,
|
|
86
|
+
source: { kind: "official", name: "@notionx/official" },
|
|
87
|
+
params: { contentSourceId: "blog" },
|
|
88
|
+
installedAt: "2026-06-10T00:00:00.000Z",
|
|
89
|
+
},
|
|
90
|
+
]);
|
|
91
|
+
const summary = await applyUpdate({
|
|
92
|
+
projectDir: dir,
|
|
93
|
+
templatesDir,
|
|
94
|
+
catalogItems: catalog,
|
|
95
|
+
});
|
|
96
|
+
expect(summary.plans.additive.length).toBeGreaterThan(0);
|
|
97
|
+
expect(summary.wroteFiles).toContain("blog_1_to_2.notion-diff.json");
|
|
98
|
+
expect(summary.wroteFiles).toContain("blog_1_to_2.d1.sql");
|
|
99
|
+
expect(summary.wroteFiles).toContain("_meta.json");
|
|
100
|
+
// The Notion diff was written but the Notion data source was
|
|
101
|
+
// not touched (we don't have a network call here).
|
|
102
|
+
const notionDiffPath = path.join(dir, ".notionx/migrations/blog_1_to_2.notion-diff.json");
|
|
103
|
+
const diff = JSON.parse(await readFile(notionDiffPath, "utf8"));
|
|
104
|
+
expect(diff.steps).toEqual(expect.arrayContaining([
|
|
105
|
+
expect.objectContaining({ kind: "notion-field-add", property: "Author" }),
|
|
106
|
+
]));
|
|
107
|
+
// The D1 SQL file was written
|
|
108
|
+
const sql = await readFile(path.join(dir, ".notionx/migrations/blog_1_to_2.d1.sql"), "utf8");
|
|
109
|
+
expect(sql).toContain("CREATE TABLE blog_authors");
|
|
110
|
+
// _meta.json is updated
|
|
111
|
+
const meta = JSON.parse(await readFile(path.join(dir, ".notionx/migrations/_meta.json"), "utf8"));
|
|
112
|
+
expect(meta.nextSequence).toBe(2);
|
|
113
|
+
expect(meta.history).toHaveLength(1);
|
|
114
|
+
expect(meta.history[0]?.label).toBe("blog 1->2");
|
|
115
|
+
});
|
|
116
|
+
it("is idempotent: a second call with the same catalog produces no new files", async () => {
|
|
117
|
+
const { catalog } = await seedProject(dir, [blogV2], [
|
|
118
|
+
{
|
|
119
|
+
id: "blog",
|
|
120
|
+
kind: "content-source",
|
|
121
|
+
version: 1,
|
|
122
|
+
source: { kind: "official", name: "@notionx/official" },
|
|
123
|
+
params: { contentSourceId: "blog" },
|
|
124
|
+
installedAt: "2026-06-10T00:00:00.000Z",
|
|
125
|
+
},
|
|
126
|
+
]);
|
|
127
|
+
const first = await applyUpdate({
|
|
128
|
+
projectDir: dir,
|
|
129
|
+
templatesDir,
|
|
130
|
+
catalogItems: catalog,
|
|
131
|
+
});
|
|
132
|
+
expect(first.wroteFiles.length).toBeGreaterThan(0);
|
|
133
|
+
const second = await applyUpdate({
|
|
134
|
+
projectDir: dir,
|
|
135
|
+
templatesDir,
|
|
136
|
+
catalogItems: catalog,
|
|
137
|
+
});
|
|
138
|
+
// Second run: no new payloads written, but _meta.json still
|
|
139
|
+
// gets re-written (the planner sees the same set).
|
|
140
|
+
expect(second.plans.additive).toEqual([]);
|
|
141
|
+
expect(second.plans.destructive).toEqual([]);
|
|
142
|
+
expect(second.plans.noop.length).toBeGreaterThan(0);
|
|
143
|
+
});
|
|
144
|
+
it("skips items already at the catalog version", async () => {
|
|
145
|
+
const { catalog } = await seedProject(dir, [blogV2], [
|
|
146
|
+
{
|
|
147
|
+
id: "blog",
|
|
148
|
+
kind: "content-source",
|
|
149
|
+
version: 2,
|
|
150
|
+
source: { kind: "official", name: "@notionx/official" },
|
|
151
|
+
params: { contentSourceId: "blog" },
|
|
152
|
+
installedAt: "2026-06-10T00:00:00.000Z",
|
|
153
|
+
},
|
|
154
|
+
]);
|
|
155
|
+
const summary = await applyUpdate({
|
|
156
|
+
projectDir: dir,
|
|
157
|
+
templatesDir,
|
|
158
|
+
catalogItems: catalog,
|
|
159
|
+
});
|
|
160
|
+
expect(summary.wroteFiles).toEqual([]);
|
|
161
|
+
expect(summary.plans.additive).toEqual([]);
|
|
162
|
+
expect(summary.plans.destructive).toEqual([]);
|
|
163
|
+
});
|
|
164
|
+
it("blocks downgrades: installed v2 + catalog v1 produces no plan", async () => {
|
|
165
|
+
const { catalog } = await seedProject(dir, [blogV1], [
|
|
166
|
+
{
|
|
167
|
+
id: "blog",
|
|
168
|
+
kind: "content-source",
|
|
169
|
+
version: 2,
|
|
170
|
+
source: { kind: "official", name: "@notionx/official" },
|
|
171
|
+
params: { contentSourceId: "blog" },
|
|
172
|
+
installedAt: "2026-06-10T00:00:00.000Z",
|
|
173
|
+
},
|
|
174
|
+
]);
|
|
175
|
+
const summary = await applyUpdate({
|
|
176
|
+
projectDir: dir,
|
|
177
|
+
templatesDir,
|
|
178
|
+
catalogItems: catalog,
|
|
179
|
+
});
|
|
180
|
+
expect(summary.plans.additive).toEqual([]);
|
|
181
|
+
expect(summary.plans.destructive).toEqual([]);
|
|
182
|
+
});
|
|
183
|
+
it("batches additive + destructive into the same migration file (one seq, multiple payloads)", async () => {
|
|
184
|
+
const blogV3 = {
|
|
185
|
+
...blogV2,
|
|
186
|
+
version: 3,
|
|
187
|
+
migrations: [
|
|
188
|
+
{
|
|
189
|
+
from: "blog@1",
|
|
190
|
+
to: "blog@3",
|
|
191
|
+
steps: [
|
|
192
|
+
{
|
|
193
|
+
kind: "notion-field-add",
|
|
194
|
+
source: "NOTION_BLOG_DATA_SOURCE_ID",
|
|
195
|
+
property: "Author",
|
|
196
|
+
type: "people",
|
|
197
|
+
},
|
|
198
|
+
{
|
|
199
|
+
kind: "notion-field-rename",
|
|
200
|
+
source: "NOTION_BLOG_DATA_SOURCE_ID",
|
|
201
|
+
from: "Eyebrow",
|
|
202
|
+
to: "Subheadline",
|
|
203
|
+
},
|
|
204
|
+
],
|
|
205
|
+
},
|
|
206
|
+
],
|
|
207
|
+
};
|
|
208
|
+
const { catalog } = await seedProject(dir, [blogV3], [
|
|
209
|
+
{
|
|
210
|
+
id: "blog",
|
|
211
|
+
kind: "content-source",
|
|
212
|
+
version: 1,
|
|
213
|
+
source: { kind: "official", name: "@notionx/official" },
|
|
214
|
+
params: { contentSourceId: "blog" },
|
|
215
|
+
installedAt: "2026-06-10T00:00:00.000Z",
|
|
216
|
+
},
|
|
217
|
+
]);
|
|
218
|
+
const summary = await applyUpdate({
|
|
219
|
+
projectDir: dir,
|
|
220
|
+
templatesDir,
|
|
221
|
+
catalogItems: catalog,
|
|
222
|
+
});
|
|
223
|
+
// One additive, one destructive, one seq, two payload files
|
|
224
|
+
expect(summary.plans.additive).toHaveLength(1);
|
|
225
|
+
expect(summary.plans.destructive).toHaveLength(1);
|
|
226
|
+
expect(summary.wroteFiles).toContain("blog_1_to_3.notion-diff.json");
|
|
227
|
+
});
|
|
228
|
+
});
|
|
229
|
+
//# sourceMappingURL=update.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"update.test.js","sourceRoot":"","sources":["../../src/registry/update.test.ts"],"names":[],"mappings":"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"}
|