koguma 0.4.1 → 0.4.2

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/cli/index.ts CHANGED
@@ -863,8 +863,49 @@ async function cmdMigrate() {
863
863
  const { detectDrift } = await import('../src/db/migrate.ts');
864
864
  const result = detectDrift(config.contentTypes as any, existingColumns);
865
865
 
866
+ // Also ensure _assets table exists
867
+ try {
868
+ const output = runCapture(
869
+ `npx wrangler d1 execute ${dbName} ${target} --command "SELECT name FROM pragma_table_info('_assets')" --json`,
870
+ root
871
+ );
872
+ const parsed = JSON.parse(output);
873
+ const results = parsed?.[0]?.results ?? [];
874
+ if (results.length === 0) {
875
+ result.sql.unshift(
876
+ `CREATE TABLE IF NOT EXISTS _assets (\n` +
877
+ ` id TEXT PRIMARY KEY,\n` +
878
+ ` title TEXT NOT NULL DEFAULT '',\n` +
879
+ ` description TEXT DEFAULT '',\n` +
880
+ ` url TEXT NOT NULL,\n` +
881
+ ` content_type TEXT DEFAULT '',\n` +
882
+ ` width INTEGER,\n` +
883
+ ` height INTEGER,\n` +
884
+ ` file_size INTEGER,\n` +
885
+ ` created_at TEXT DEFAULT (datetime('now')),\n` +
886
+ ` updated_at TEXT DEFAULT (datetime('now'))\n` +
887
+ `);`
888
+ );
889
+ }
890
+ } catch {
891
+ result.sql.unshift(
892
+ `CREATE TABLE IF NOT EXISTS _assets (\n` +
893
+ ` id TEXT PRIMARY KEY,\n` +
894
+ ` title TEXT NOT NULL DEFAULT '',\n` +
895
+ ` description TEXT DEFAULT '',\n` +
896
+ ` url TEXT NOT NULL,\n` +
897
+ ` content_type TEXT DEFAULT '',\n` +
898
+ ` width INTEGER,\n` +
899
+ ` height INTEGER,\n` +
900
+ ` file_size INTEGER,\n` +
901
+ ` created_at TEXT DEFAULT (datetime('now')),\n` +
902
+ ` updated_at TEXT DEFAULT (datetime('now'))\n` +
903
+ `);`
904
+ );
905
+ }
906
+
866
907
  // Display results
867
- if (result.drift.length === 0 && result.warnings.length === 0) {
908
+ if (result.sql.length === 0 && result.warnings.length === 0) {
868
909
  ok('Schema is up to date — no changes needed!');
869
910
  return;
870
911
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "koguma",
3
- "version": "0.4.1",
3
+ "version": "0.4.2",
4
4
  "description": "🐻 A little CMS with big heart — schema-driven, runs on Cloudflare's free tier",
5
5
  "type": "module",
6
6
  "license": "MIT",
package/src/db/migrate.ts CHANGED
@@ -77,9 +77,39 @@ export function detectDrift(
77
77
  for (const ct of contentTypes) {
78
78
  const tableCols = existingColumns[ct.id];
79
79
  if (!tableCols) {
80
- // Table doesn't exist at all schema.ts will create it
81
- warnings.push(
82
- `Table '${ct.id}' does not exist yet — run 'koguma seed' to create it.`
80
+ // Table doesn't exist — generate CREATE TABLE
81
+ const columns: string[] = [
82
+ 'id TEXT PRIMARY KEY',
83
+ "created_at TEXT DEFAULT (datetime('now'))",
84
+ "updated_at TEXT DEFAULT (datetime('now'))",
85
+ "status TEXT NOT NULL DEFAULT 'published'",
86
+ 'publishAt TEXT'
87
+ ];
88
+
89
+ for (const [fieldId, meta] of Object.entries(ct.fieldMeta)) {
90
+ const st = sqlType(meta.fieldType);
91
+ if (st === '__JOIN__') {
92
+ // Create join table for `references` fields
93
+ const joinTable = `${ct.id}__${fieldId}`;
94
+ sql.push(
95
+ `CREATE TABLE IF NOT EXISTS ${joinTable} (\n` +
96
+ ` source_id TEXT NOT NULL,\n` +
97
+ ` target_id TEXT NOT NULL,\n` +
98
+ ` sort_order INTEGER NOT NULL DEFAULT 0,\n` +
99
+ ` PRIMARY KEY (source_id, target_id)\n` +
100
+ `);`
101
+ );
102
+ sql.push(
103
+ `CREATE INDEX IF NOT EXISTS idx_${joinTable}_source ON ${joinTable} (source_id);`
104
+ );
105
+ continue;
106
+ }
107
+ const notNull = meta.required ? ' NOT NULL' : '';
108
+ columns.push(`${fieldId} ${st}${notNull}`);
109
+ }
110
+
111
+ sql.push(
112
+ `CREATE TABLE IF NOT EXISTS ${ct.id} (\n ${columns.join(',\n ')}\n);`
83
113
  );
84
114
  continue;
85
115
  }