alepha 0.19.2 → 0.19.3

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 (61) hide show
  1. package/dist/api/jobs/index.d.ts +24 -24
  2. package/dist/api/jobs/index.d.ts.map +1 -1
  3. package/dist/api/jobs/index.js +10 -4
  4. package/dist/api/jobs/index.js.map +1 -1
  5. package/dist/api/keys/index.d.ts +5 -5
  6. package/dist/api/users/index.d.ts +9 -19
  7. package/dist/api/users/index.d.ts.map +1 -1
  8. package/dist/api/verifications/index.d.ts +13 -13
  9. package/dist/cli/config/index.d.ts +6 -28
  10. package/dist/cli/config/index.d.ts.map +1 -1
  11. package/dist/cli/config/index.js +5 -10
  12. package/dist/cli/config/index.js.map +1 -1
  13. package/dist/cli/core/index.d.ts +11653 -208
  14. package/dist/cli/core/index.d.ts.map +1 -1
  15. package/dist/cli/core/index.js +48 -12
  16. package/dist/cli/core/index.js.map +1 -1
  17. package/dist/cli/devtools/index.d.ts +5 -0
  18. package/dist/cli/devtools/index.d.ts.map +1 -1
  19. package/dist/cli/devtools/index.js +4 -0
  20. package/dist/cli/devtools/index.js.map +1 -1
  21. package/dist/cli/platform/index.d.ts +69 -64
  22. package/dist/cli/platform/index.d.ts.map +1 -1
  23. package/dist/cli/platform/index.js +6 -2
  24. package/dist/cli/platform/index.js.map +1 -1
  25. package/dist/cli/vendor/index.d.ts +7 -2
  26. package/dist/cli/vendor/index.d.ts.map +1 -1
  27. package/dist/cli/vendor/index.js +6 -2
  28. package/dist/cli/vendor/index.js.map +1 -1
  29. package/dist/core/index.browser.js.map +1 -1
  30. package/dist/core/index.d.ts.map +1 -1
  31. package/dist/core/index.js +4 -0
  32. package/dist/core/index.js.map +1 -1
  33. package/dist/core/index.native.js +4 -0
  34. package/dist/core/index.native.js.map +1 -1
  35. package/dist/core/index.workerd.js +4 -0
  36. package/dist/core/index.workerd.js.map +1 -1
  37. package/dist/logger/index.d.ts.map +1 -1
  38. package/dist/logger/index.js +1 -1
  39. package/dist/logger/index.js.map +1 -1
  40. package/dist/orm/core/index.bun.js +25 -56
  41. package/dist/orm/core/index.bun.js.map +1 -1
  42. package/dist/orm/core/index.d.ts +9 -19
  43. package/dist/orm/core/index.d.ts.map +1 -1
  44. package/dist/orm/core/index.js +25 -56
  45. package/dist/orm/core/index.js.map +1 -1
  46. package/dist/orm/postgres/index.d.ts +2 -1
  47. package/dist/orm/postgres/index.d.ts.map +1 -1
  48. package/package.json +6 -6
  49. package/src/api/jobs/providers/JobProvider.ts +10 -6
  50. package/src/cli/config/defineConfig.ts +17 -46
  51. package/src/cli/core/providers/ViteDevServerProvider.ts +45 -3
  52. package/src/cli/core/services/PackageManagerUtils.ts +3 -1
  53. package/src/cli/core/services/ProjectScaffolder.ts +5 -5
  54. package/src/cli/core/templates/agentMd.ts +14 -5
  55. package/src/cli/devtools/index.ts +21 -1
  56. package/src/cli/platform/index.ts +23 -2
  57. package/src/cli/vendor/index.ts +20 -3
  58. package/src/core/Alepha.ts +10 -0
  59. package/src/logger/index.ts +6 -1
  60. package/src/orm/core/providers/DrizzleKitProvider.ts +56 -105
  61. package/tsconfig.base.json +0 -1
@@ -29,10 +29,13 @@ export class DrizzleKitProvider {
29
29
  }
30
30
 
31
31
  if (this.alepha.isTest()) {
32
- // In test mode, we want to generate migrations from scratch (no snapshots)
33
- // to ensure the generated SQL is correct and can be applied cleanly.
34
32
  const { statements } = await this.generateMigration(provider);
35
- await this.executeFallbackStatements(statements, provider);
33
+ await this.executeStatements(
34
+ statements.map((s) =>
35
+ s.replace(/^CREATE SCHEMA /i, "CREATE SCHEMA IF NOT EXISTS "),
36
+ ),
37
+ provider,
38
+ );
36
39
  return;
37
40
  }
38
41
 
@@ -52,14 +55,18 @@ export class DrizzleKitProvider {
52
55
  await this.pushPostgres(kit, models, provider);
53
56
  }
54
57
  } catch (error) {
55
- // Fallback: generate migrations from scratch (no snapshots)
56
- // Covers drivers that don't support introspection (e.g. PgLite, sqlite-proxy)
58
+ // Fallback: generate migrations from scratch (no snapshots).
59
+ // Covers drivers that don't support introspection (e.g. PgLite, sqlite-proxy).
60
+ //
61
+ // If push partially executed (e.g. interactive rename applied then errored),
62
+ // the fallback would re-create tables that already exist. Guard against this
63
+ // by attempting the statements individually and ignoring "already exists" errors.
57
64
  this.log.debug(
58
65
  "Push sync not available, falling back to migration generation",
59
66
  { error },
60
67
  );
61
68
  const { statements } = await this.generateMigration(provider);
62
- await this.executeFallbackStatements(statements, provider);
69
+ await this.executeStatementsLenient(statements, provider);
63
70
  }
64
71
 
65
72
  this.log.info(
@@ -127,7 +134,6 @@ export class DrizzleKitProvider {
127
134
  public getModels(provider: DatabaseProvider): Record<string, unknown> {
128
135
  const models: Record<string, unknown> = {};
129
136
 
130
- // Required for pushSchema with Postgres and POSTGRES_SCHEMA
131
137
  for (const [key, value] of provider.schemas.entries()) {
132
138
  models[`__schema_${key}`] = value;
133
139
  }
@@ -232,14 +238,10 @@ export class DrizzleKitProvider {
232
238
  };
233
239
 
234
240
  if (provider.dialect === "sqlite") {
235
- result = await this.muteSpinner(() =>
236
- kit.pushSQLiteSchema(models, provider.db as any),
237
- );
241
+ result = await kit.pushSQLiteSchema(models, provider.db as any);
238
242
  } else {
239
243
  const wrappedDb = this.wrapDbForDrizzleKit(provider.db);
240
- result = await this.muteSpinner(() =>
241
- kit.pushSchema(models, wrappedDb, [provider.schema]),
242
- );
244
+ result = await kit.pushSchema(models, wrappedDb, [provider.schema]);
243
245
  }
244
246
 
245
247
  return {
@@ -256,11 +258,11 @@ export class DrizzleKitProvider {
256
258
  models: Record<string, unknown>,
257
259
  provider: DatabaseProvider,
258
260
  ): Promise<void> {
259
- const result = await this.muteSpinner(() =>
260
- kit.pushSQLiteSchema(models, provider.db as any),
261
+ const { statementsToExecute } = await kit.pushSQLiteSchema(
262
+ models,
263
+ provider.db as any,
261
264
  );
262
-
263
- await this.runPushResult(result, provider);
265
+ await this.executeStatements(statementsToExecute, provider);
264
266
  }
265
267
 
266
268
  /**
@@ -275,78 +277,61 @@ export class DrizzleKitProvider {
275
277
  await this.createSchemaIfNotExists(provider, provider.schema);
276
278
  }
277
279
 
278
- // Drizzle Kit's pushSchema internally does:
279
- // const res = await drizzleInstance.execute(sql.raw(query));
280
- // return res.rows;
281
- //
282
- // This assumes node-postgres (pg) format where execute() returns { rows: [...] }.
283
- // But postgres.js (used by Alepha) returns a Result that extends Array — no .rows property.
284
- // We wrap the db instance so execute() returns { rows: [...] } as expected.
280
+ // Drizzle Kit's pushSchema expects execute() to return { rows: T[] }
281
+ // (node-postgres/pg format), but postgres.js returns a Result that
282
+ // extends Array directly — no .rows property.
285
283
  const wrappedDb = this.wrapDbForDrizzleKit(provider.db);
286
284
 
287
- const result = await this.muteSpinner(() =>
288
- kit.pushSchema(models, wrappedDb, [provider.schema]),
289
- );
290
-
291
- await this.runPushResult(result, provider);
285
+ const { statementsToExecute } = await kit.pushSchema(models, wrappedDb, [
286
+ provider.schema,
287
+ ]);
288
+ await this.executeStatements(statementsToExecute, provider);
292
289
  }
293
290
 
294
291
  /**
295
- * Run the statements returned by Drizzle Kit's pushSchema, with safety filters and logging.
292
+ * Execute a list of SQL statements against the provider.
296
293
  */
297
- protected async runPushResult(
298
- result: {
299
- statementsToExecute: string[];
300
- warnings: string[];
301
- hasDataLoss: boolean;
302
- },
294
+ protected async executeStatements(
295
+ statements: string[],
303
296
  provider: DatabaseProvider,
304
- ) {
305
- // Filter out destructive schema/table drops — never auto-apply those in dev.
306
- const safe = (result.statementsToExecute as string[]).filter((s) => {
307
- const upper = s.trimStart().toUpperCase();
308
- if (upper.startsWith("DROP SCHEMA") || upper.startsWith("DROP TABLE")) {
309
- this.log.warn("Skipping destructive statement", { statement: s });
310
- return false;
311
- }
312
- return true;
313
- });
314
-
315
- if (result.hasDataLoss) {
316
- this.log.warn("Push would cause data loss", {
317
- warnings: result.warnings,
318
- statements: result.statementsToExecute,
297
+ ): Promise<void> {
298
+ if (statements.length > 0) {
299
+ this.log.debug(`Executing ${statements.length} statements ...`, {
300
+ statements,
319
301
  });
320
302
  }
321
-
322
- if (safe.length > 0) {
323
- this.log.debug(`Pushing ${safe.length} statements ...`, {
324
- statements: safe,
325
- });
326
- for (const statement of safe) {
327
- await provider.execute(sql.raw(statement));
328
- }
303
+ for (const statement of statements) {
304
+ await provider.execute(sql.raw(statement));
329
305
  }
330
306
  }
331
307
 
332
308
  /**
333
- * Execute migration statements as a fallback when push sync is not available.
334
- * Used for drivers that don't support Drizzle Kit introspection (e.g. PgLite).
309
+ * Execute SQL statements, ignoring "already exists" errors.
310
+ *
311
+ * Used by the fallback migration path where push may have partially
312
+ * applied changes before erroring, leaving some objects already created.
335
313
  */
336
- protected async executeFallbackStatements(
314
+ protected async executeStatementsLenient(
337
315
  statements: string[],
338
316
  provider: DatabaseProvider,
339
317
  ): Promise<void> {
318
+ if (statements.length > 0) {
319
+ this.log.debug(
320
+ `Executing ${statements.length} statements (lenient) ...`,
321
+ { statements },
322
+ );
323
+ }
340
324
  for (const statement of statements) {
341
- const upper = statement.trimStart().toUpperCase();
342
- // Schema lifecycle is managed by createSchemaIfNotExists / generateTestSchema.
343
- if (
344
- upper.startsWith("DROP SCHEMA") ||
345
- upper.startsWith("CREATE SCHEMA")
346
- ) {
347
- continue;
325
+ try {
326
+ await provider.execute(sql.raw(statement));
327
+ } catch (error: any) {
328
+ const message = error?.message ?? "";
329
+ if (message.includes("already exists")) {
330
+ this.log.debug(`Skipped (already exists): ${statement.slice(0, 80)}`);
331
+ continue;
332
+ }
333
+ throw error;
348
334
  }
349
- await provider.execute(sql.raw(statement));
350
335
  }
351
336
  }
352
337
 
@@ -375,7 +360,7 @@ export class DrizzleKitProvider {
375
360
 
376
361
  // -------------------------------------------------------------------------------------------------------------------
377
362
 
378
- // TODO: remove both hacks when Drizzle Kit is updated !
363
+ // TODO: remove when Drizzle Kit fixes postgres.js compatibility
379
364
 
380
365
  /**
381
366
  * Wrap a Drizzle PgDatabase instance for compatibility with Drizzle Kit.
@@ -401,40 +386,6 @@ export class DrizzleKitProvider {
401
386
  });
402
387
  }
403
388
 
404
- /**
405
- * Suppress Drizzle Kit's spinner output during a callback.
406
- *
407
- * Drizzle Kit uses hanji's renderWithTask with a setInterval-based spinner.
408
- * If the wrapped task throws, the interval is never cleared and leaks
409
- * spinner frames to stdout. We keep the filter active until the next
410
- * tick after the promise settles to catch any straggling writes.
411
- */
412
- protected async muteSpinner<T>(fn: () => Promise<T>): Promise<T> {
413
- const originalWrite = process.stdout.write;
414
- const filter = (chunk: any, ...args: any[]) => {
415
- const str =
416
- typeof chunk === "string" ? chunk : (chunk?.toString?.() ?? "");
417
- if (str.includes("Pulling schema from database")) {
418
- return true;
419
- }
420
- if (str.includes("\x1B[1A")) {
421
- return true;
422
- }
423
- return (originalWrite as any).call(process.stdout, chunk, ...args);
424
- };
425
- process.stdout.write = filter as any;
426
- try {
427
- return await fn();
428
- } finally {
429
- // Delay restore to catch orphaned setInterval spinner writes
430
- // that fire after the promise rejects but before cleanup.
431
- await new Promise((r) => setTimeout(r, 200));
432
- process.stdout.write = originalWrite;
433
- }
434
- }
435
-
436
- // -------------------------------------------------------------------------------------------------------------------
437
-
438
389
  /**
439
390
  * Try to load the official Drizzle Kit API.
440
391
  */
@@ -1,6 +1,5 @@
1
1
  {
2
2
  "compilerOptions": {
3
- "types": ["node", "bun"],
4
3
  "module": "nodenext",
5
4
  "target": "esnext",
6
5
  "strict": true,