@kywi-software/cli 0.2.0 → 0.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.
package/README.md CHANGED
@@ -3,7 +3,7 @@
3
3
  The `kywi` command-line tool: applies the schema described by a project's
4
4
  `kywi.config.ts` to its database, and seeds default/demo content. Built on
5
5
  `@kywi-software/core`'s schema generator and Drizzle. See the
6
- [root README](https://github.com/kywi-software/kywi#readme) for how it fits
6
+ [root README](https://github.com/Kywi-Software/kywi-cms#readme) for how it fits
7
7
  into the rest of Kywi.
8
8
 
9
9
  ## Install
@@ -25,17 +25,78 @@ program
25
25
  mkdirSync(outDir, { recursive: true });
26
26
  mkdirSync(migrationsDir, { recursive: true });
27
27
  const { contentTypes, db } = config;
28
- if (contentTypes.length === 0) {
28
+ // ── Admin-created content types (#38) ────────────────────────────────────
29
+ // Types created through the admin Type Designer live in the DB, not in
30
+ // kywi.config.ts, but they get real `kywi_ct_*` tables. If schema generation
31
+ // reads only the config, drizzle-kit sees those tables as orphans and offers
32
+ // to DROP them (with their data). So when a database is reachable we read the
33
+ // admin-created types and generate their schema too — the generated schema
34
+ // then reflects the FULL content model and no admin table is ever an orphan.
35
+ let adminTypes = [];
36
+ let orphanTables = [];
37
+ let dbReadOk = false;
38
+ try {
39
+ // Imported at call time (mirrors migrate.ts): keeps schema generation
40
+ // dependency-light and lets a config-only build work even before core's
41
+ // DB helpers are present.
42
+ const { createDb, resolveDatabaseUrl, loadAdminContentTypes, listCustomContentTables } = await import('@kywi-software/core');
43
+ const dbUrl = resolveDatabaseUrl(db?.url, 'postgres://localhost:5432/kywi_dev').url;
44
+ const client = createDb(dbUrl, db?.provider);
45
+ try {
46
+ const admin = await loadAdminContentTypes(client);
47
+ // Only types that actually have a physical table (i.e. at least one
48
+ // custom field — matching where the runtime creates a `kywi_ct_*` table).
49
+ adminTypes = admin.filter(t => t.fields.length > 0);
50
+ // Any dynamic table present in the DB but backed by neither a config type
51
+ // nor a currently-registered admin type is an orphan (e.g. a type deleted
52
+ // via the admin, which intentionally leaves its table + rows in place).
53
+ // Excluding it from the drizzle-kit diff keeps that data safe.
54
+ const present = await listCustomContentTables(client);
55
+ const managed = new Set([
56
+ ...contentTypes.map((ct) => contentTypeToTableName(ct.name)),
57
+ ...adminTypes.map(ct => contentTypeToTableName(ct.name)),
58
+ ]);
59
+ orphanTables = present.filter(t => !managed.has(t));
60
+ dbReadOk = true;
61
+ }
62
+ finally {
63
+ // postgres.js keeps a live socket; close it so this process (a child of
64
+ // `kywi migrate`) can exit instead of hanging.
65
+ try {
66
+ await client
67
+ .$client?.end?.({ timeout: 5 });
68
+ }
69
+ catch {
70
+ /* best-effort close */
71
+ }
72
+ }
73
+ }
74
+ catch {
75
+ // No reachable database (offline `migrate:generate`, fresh DB, wrong
76
+ // DATABASE_URL). Fall back to config-only generation — the historical
77
+ // behaviour — and warn loudly, because in this mode drizzle-kit cannot be
78
+ // told about admin-created tables.
79
+ console.warn(' ⚠ Database not reachable — generating config-only schema. Run `kywi migrate` ' +
80
+ 'with DATABASE_URL set so admin-created content-type tables are included and protected.');
81
+ }
82
+ if (contentTypes.length === 0 && adminTypes.length === 0) {
29
83
  console.log('No custom content types found — only base schema will be used.');
30
84
  }
85
+ // The full content model drizzle-kit should manage: config-defined first
86
+ // (an app type wins a name clash), then admin-created.
87
+ const allTypes = [...contentTypes, ...adminTypes];
31
88
  // Write one file per content type
32
89
  for (const ct of contentTypes) {
33
90
  const tableName = contentTypeToTableName(ct.name);
34
- const fileName = `${tableName}.ts`;
35
- const filePath = join(outDir, fileName);
36
- const code = generateContentTypeSchema(ct);
37
- writeFileSync(filePath, code, 'utf-8');
38
- console.log(` ✓ ${fileName}`);
91
+ const filePath = join(outDir, `${tableName}.ts`);
92
+ writeFileSync(filePath, generateContentTypeSchema(ct), 'utf-8');
93
+ console.log(` ✓ ${tableName}.ts`);
94
+ }
95
+ for (const ct of adminTypes) {
96
+ const tableName = contentTypeToTableName(ct.name);
97
+ const filePath = join(outDir, `${tableName}.ts`);
98
+ writeFileSync(filePath, generateContentTypeSchema(ct), 'utf-8');
99
+ console.log(` ✓ ${tableName}.ts (admin-created)`);
39
100
  }
40
101
  // Write the self-contained base re-export that the barrel index references
41
102
  // as '../base.js'. Emitting it here means the generated output no longer
@@ -45,20 +106,30 @@ program
45
106
  console.log(` ✓ base.ts`);
46
107
  // Write the barrel index
47
108
  const indexPath = join(outDir, 'index.ts');
48
- writeFileSync(indexPath, generateSchemaIndex(contentTypes), 'utf-8');
109
+ writeFileSync(indexPath, generateSchemaIndex(allTypes), 'utf-8');
49
110
  console.log(` ✓ index.ts`);
50
- // Write the drizzle.config.ts at the project root
111
+ // Write the drizzle.config.ts at the project root. When we read the DB, scope
112
+ // drizzle-kit to Kywi-managed tables and exclude any orphaned dynamic tables
113
+ // so a `push`/`migrate` can never DROP admin-authored data (#38 safety net).
51
114
  const drizzleConfigPath = resolve(process.cwd(), 'drizzle.config.ts');
52
115
  const schemaRelative = `./${join('kywi-generated/schema', 'index.ts')}`;
53
116
  const migrationsRelative = './kywi-generated/migrations';
117
+ const tablesFilter = dbReadOk
118
+ ? ['kywi_*', ...orphanTables.map(t => `!${t}`)]
119
+ : undefined;
54
120
  const drizzleConfig = generateDrizzleConfig({
55
121
  dbProvider: db.provider,
56
122
  schemaRelativePath: schemaRelative,
57
123
  migrationsRelativePath: migrationsRelative,
124
+ ...(tablesFilter ? { tablesFilter } : {}),
58
125
  });
59
126
  writeFileSync(drizzleConfigPath, drizzleConfig, 'utf-8');
60
127
  console.log(` ✓ drizzle.config.ts (project root)`);
61
- console.log(`\nGenerated ${contentTypes.length} content type schema(s) to ${options.out}/`);
128
+ console.log(`\nGenerated ${allTypes.length} content type schema(s) to ${options.out}/` +
129
+ (adminTypes.length > 0 ? ` (${adminTypes.length} admin-created)` : ''));
130
+ if (orphanTables.length > 0) {
131
+ console.log(`Protected ${orphanTables.length} orphaned dynamic table(s) from drizzle-kit DROP: ${orphanTables.join(', ')}`);
132
+ }
62
133
  console.log(`Run 'kywi migrate' to apply the schema to your database.`);
63
134
  });
64
135
  //# sourceMappingURL=migrate-generate.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"migrate-generate.js","sourceRoot":"","sources":["../../src/commands/migrate-generate.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"migrate-generate.js","sourceRoot":"","sources":["../../src/commands/migrate-generate.ts"],"names":[],"mappings":"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"}
@@ -52,6 +52,23 @@ program
52
52
  }
53
53
  throw err;
54
54
  }
55
+ // Databases that predate the composite membership constraints (#40) can
56
+ // hold duplicate rows the new PKs would refuse to apply over. Dedupe
57
+ // before drizzle-kit runs; Postgres-only (the cleanup uses ctid/jsonb).
58
+ if ((config.db?.provider ?? 'postgresql') !== 'mysql') {
59
+ try {
60
+ const { dedupeMembershipRows } = await import('@kywi-software/core');
61
+ const deduped = await dedupeMembershipRows(db);
62
+ const total = deduped.userGroups + deduped.siteMemberships;
63
+ if (total > 0) {
64
+ console.log(`Removed ${total} duplicate membership row(s) (pre-0.2.2 bug #40) so the uniqueness constraints can apply.`);
65
+ }
66
+ }
67
+ catch (err) {
68
+ console.warn(`Warning: could not dedupe membership rows (${err.message}). ` +
69
+ 'If drizzle-kit fails adding a primary key on kywi_user_groups/kywi_site_memberships, deduplicate those tables and re-run.');
70
+ }
71
+ }
55
72
  }
56
73
  catch (err) {
57
74
  // Only connection problems are converted above; anything else is a real
@@ -67,6 +84,13 @@ program
67
84
  stdio: 'inherit',
68
85
  env: process.env,
69
86
  });
70
- process.exit(result.status ?? 0);
87
+ // A spawn failure (e.g. drizzle-kit not installed) leaves status null
88
+ // that must be a loud error, not a silent success exit.
89
+ if (result.error) {
90
+ console.error(`\n✖ Could not run drizzle-kit (${result.error.message}).`);
91
+ console.error(" Is 'drizzle-kit' installed? It is a devDependency of the generated app — run 'pnpm install'.");
92
+ process.exit(1);
93
+ }
94
+ process.exit(result.status ?? 1);
71
95
  });
72
96
  //# sourceMappingURL=migrate.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"migrate.js","sourceRoot":"","sources":["../../src/commands/migrate.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"migrate.js","sourceRoot":"","sources":["../../src/commands/migrate.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kywi-software/cli",
3
- "version": "0.2.0",
3
+ "version": "0.3.0",
4
4
  "description": "Kywi CMS command-line tool — migrate, seed, and generate schema from a kywi.config.ts project.",
5
5
  "type": "module",
6
6
  "license": "AGPL-3.0-only",
@@ -36,7 +36,7 @@
36
36
  "commander": "^12.0.0",
37
37
  "drizzle-orm": "^0.38.0",
38
38
  "tsx": "^4.7.0",
39
- "@kywi-software/core": "0.2.0"
39
+ "@kywi-software/core": "0.3.0"
40
40
  },
41
41
  "devDependencies": {
42
42
  "@types/node": "^20.0.0",