create-absolutejs 0.5.0 → 0.5.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.
@@ -72,7 +72,7 @@ export const createPackageJson = ({ projectName, authProvider, plugins, database
72
72
  devDependencies['@tailwindcss/cli'] = resolveVersion('@tailwindcss/cli', '4.1.7');
73
73
  }
74
74
  if (flags.requiresReact) {
75
- dependencies['react'] = resolveVersion('react', '19.2.0');
75
+ dependencies['react'] = resolveVersion('react', '19.2.1');
76
76
  devDependencies['@types/react'] = resolveVersion('@types/react', '19.2.0');
77
77
  }
78
78
  if (flags.requiresReact && codeQualityTool === 'eslint+prettier') {
@@ -100,7 +100,7 @@ export const createPackageJson = ({ projectName, authProvider, plugins, database
100
100
  dependencies['@neondatabase/serverless'] = resolveVersion('@neondatabase/serverless', '1.0.0');
101
101
  break;
102
102
  case 'planetscale':
103
- dependencies['@planetscale/database'] = resolveVersion('@planetscale/database', '1.0.0');
103
+ dependencies['@planetscale/database'] = resolveVersion('@planetscale/database', '1.19.0');
104
104
  break;
105
105
  case 'turso':
106
106
  dependencies['@libsql/client'] = resolveVersion('@libsql/client', '0.15.9');
@@ -143,6 +143,10 @@ export const createPackageJson = ({ projectName, authProvider, plugins, database
143
143
  if (isLocal && databaseEngine === 'singlestore') {
144
144
  dependencies['mysql2'] = resolveVersion('mysql2', '3.14.2');
145
145
  }
146
+ if (databaseEngine === 'postgresql' && databaseHost === 'planetscale') {
147
+ dependencies['pg'] = resolveVersion('pg', '8.11.0');
148
+ devDependencies['@types/pg'] = resolveVersion('@types/pg', '8.6.1');
149
+ }
146
150
  if (isLocal && databaseEngine === 'mssql') {
147
151
  dependencies['mssql'] = resolveVersion('mssql', '12.1.0');
148
152
  devDependencies['@types/mssql'] = resolveVersion('@types/mssql', '9.1.8');
@@ -6,11 +6,16 @@ export const generateDatabaseTypes = ({ databaseEngine, databaseHost, authProvid
6
6
  dbImport = `import { NeonHttpDatabase } from 'drizzle-orm/neon-http';`;
7
7
  dbTypeLine = 'export type DatabaseType = NeonHttpDatabase<SchemaType>;';
8
8
  }
9
- else if (databaseHost === 'planetscale') {
9
+ else if (databaseHost === 'planetscale' && databaseEngine === 'mysql') {
10
10
  dbImport = `import { PlanetScaleDatabase } from 'drizzle-orm/planetscale-serverless';`;
11
11
  dbTypeLine =
12
12
  'export type DatabaseType = PlanetScaleDatabase<SchemaType>;';
13
13
  }
14
+ else if (databaseHost === 'planetscale' &&
15
+ databaseEngine === 'postgresql') {
16
+ dbImport = `import { NodePgDatabase } from 'drizzle-orm/node-postgres';`;
17
+ dbTypeLine = 'export type DatabaseType = NodePgDatabase<SchemaType>;';
18
+ }
14
19
  else if (databaseHost === 'turso') {
15
20
  dbImport = `import { LibSQLDatabase } from 'drizzle-orm/libsql';`;
16
21
  dbTypeLine = 'export type DatabaseType = LibSQLDatabase<SchemaType>;';
@@ -45,11 +45,21 @@ declare const driverConfigurations: {
45
45
  readonly importLines: "\nimport { eq } from 'drizzle-orm'\nimport { MySql2Database } from 'drizzle-orm/mysql2'\nimport { schema, type SchemaType } from '../../../db/schema'";
46
46
  readonly queries: QueryOperations;
47
47
  };
48
+ readonly 'mysql:drizzle:planetscale': {
49
+ readonly dbType: "PlanetScaleDatabase<SchemaType>";
50
+ readonly importLines: "\nimport { eq } from 'drizzle-orm'\nimport { PlanetScaleDatabase } from 'drizzle-orm/planetscale-serverless'\nimport { schema, type SchemaType } from '../../../db/schema'";
51
+ readonly queries: QueryOperations;
52
+ };
48
53
  readonly 'mysql:sql:local': {
49
54
  readonly dbType: "SQL";
50
55
  readonly importLines: "import { SQL } from 'bun'";
51
56
  readonly queries: QueryOperations;
52
57
  };
58
+ readonly 'mysql:sql:planetscale': {
59
+ readonly dbType: "Client";
60
+ readonly importLines: "import { Client } from '@planetscale/database'";
61
+ readonly queries: QueryOperations;
62
+ };
53
63
  readonly 'postgresql:drizzle:local': {
54
64
  readonly dbType: "BunSQLDatabase<SchemaType>";
55
65
  readonly importLines: "\nimport { eq } from 'drizzle-orm'\nimport { BunSQLDatabase } from 'drizzle-orm/bun-sql'\nimport { schema, type SchemaType } from '../../../db/schema'";
@@ -60,6 +70,11 @@ declare const driverConfigurations: {
60
70
  readonly importLines: "\nimport { eq } from 'drizzle-orm'\nimport { NeonDatabase } from 'drizzle-orm/neon-serverless'\nimport { schema, type SchemaType } from '../../../db/schema'";
61
71
  readonly queries: QueryOperations;
62
72
  };
73
+ readonly 'postgresql:drizzle:planetscale': {
74
+ readonly dbType: "NodePgDatabase<SchemaType>";
75
+ readonly importLines: "\nimport { eq } from 'drizzle-orm'\nimport { NodePgDatabase } from 'drizzle-orm/node-postgres'\nimport { schema, type SchemaType } from '../../../db/schema'";
76
+ readonly queries: QueryOperations;
77
+ };
63
78
  readonly 'postgresql:sql:local': {
64
79
  readonly dbType: "SQL";
65
80
  readonly importLines: "import { SQL } from 'bun'";
@@ -70,6 +85,11 @@ declare const driverConfigurations: {
70
85
  readonly importLines: "import { Pool } from '@neondatabase/serverless'";
71
86
  readonly queries: QueryOperations;
72
87
  };
88
+ readonly 'postgresql:sql:planetscale': {
89
+ readonly dbType: "Pool";
90
+ readonly importLines: "import { Pool } from 'pg'";
91
+ readonly queries: QueryOperations;
92
+ };
73
93
  readonly 'singlestore:sql:local': {
74
94
  readonly dbType: "Pool";
75
95
  readonly importLines: "import { Pool, RowDataPacket } from 'mysql2/promise'";
@@ -81,7 +81,7 @@ const bunSqliteQueryOperations = {
81
81
  const [user] = statement.all(authSub)
82
82
  return user ?? null`
83
83
  };
84
- const postgresNeonQueryOperations = {
84
+ const postgresQueryOperations = {
85
85
  insertHistory: `const { rows } = await db.query(
86
86
  'INSERT INTO count_history (count) VALUES ($1) RETURNING *',
87
87
  [count]
@@ -220,12 +220,10 @@ const mysqlSqlQueryOperations = {
220
220
  VALUES (\${authSub}, \${JSON.stringify(userIdentity)})
221
221
  \`;
222
222
 
223
- const insertId = result.lastInsertRowid;
224
-
225
223
  const [row] = await db\`
226
224
  SELECT *
227
225
  FROM users
228
- WHERE uid = \${insertId}
226
+ WHERE auth_sub = \${authSub}
229
227
  LIMIT 1
230
228
  \`;
231
229
 
@@ -270,22 +268,71 @@ const mysqlDrizzleQueryOperations = {
270
268
  return newHistory;`,
271
269
  insertUser: `const [row] = await db
272
270
  .insert(schema.users)
273
- .values({ auth_sub: authSub, metadata: userIdentity })
274
- .$returningId();
275
-
276
- if (!row) throw new Error('insert failed: no uid returned');
277
- const { uid } = row;
271
+ .values({ auth_sub: authSub, metadata: userIdentity });
278
272
 
279
273
  const [newUser] = await db
280
274
  .select()
281
275
  .from(schema.users)
282
- .where(eq(schema.users.uid, uid));
276
+ .where(eq(schema.users.auth_sub, authSub));
283
277
 
284
278
  if (!newUser) throw new Error('Failed to create user');
285
279
  return newUser;`,
286
280
  selectHistory: drizzleQueryOperations.selectHistory,
287
281
  selectUser: drizzleQueryOperations.selectUser
288
282
  };
283
+ const mysqlPlanetScaleQueryOperations = {
284
+ insertHistory: `
285
+ const result = await db.execute(
286
+ \`INSERT INTO count_history (count) VALUES (?)\`,
287
+ [count]
288
+ );
289
+
290
+ const insertId = result.insertId;
291
+ if (!insertId) throw new Error("Could not insert count history");
292
+
293
+ const { rows } = await db.execute(
294
+ \`SELECT * FROM count_history WHERE uid = ? LIMIT 1\`,
295
+ [insertId]
296
+ );
297
+
298
+ const row = rows[0] ?? null;
299
+ if (!row) throw new Error("Could not retrieve the newly-inserted history");
300
+
301
+ return row;
302
+ `,
303
+ insertUser: `
304
+ const result = await db.execute(
305
+ \`INSERT INTO users (auth_sub, metadata) VALUES (?, ?)\`,
306
+ [authSub, JSON.stringify(userIdentity)]
307
+ );
308
+
309
+ const { rows } = await db.execute(
310
+ \`SELECT * FROM users WHERE auth_sub = ? LIMIT 1\`,
311
+ [authSub]
312
+ );
313
+
314
+ const row = rows[0] ?? null;
315
+ if (!row) throw new Error("Failed to create user");
316
+
317
+ return row;
318
+ `,
319
+ selectHistory: `
320
+ const { rows } = await db.execute(
321
+ \`SELECT * FROM count_history WHERE uid = ? LIMIT 1\`,
322
+ [uid]
323
+ );
324
+
325
+ return rows[0] ?? null;
326
+ `,
327
+ selectUser: `
328
+ const { rows } = await db.execute(
329
+ \`SELECT * FROM users WHERE auth_sub = ? LIMIT 1\`,
330
+ [authSub]
331
+ );
332
+
333
+ return rows[0] ?? null;
334
+ `
335
+ };
289
336
  const driverConfigurations = {
290
337
  'cockroachdb:sql:local': {
291
338
  dbType: 'SQL',
@@ -334,6 +381,14 @@ import { schema, type SchemaType } from '../../../db/schema'`,
334
381
  importLines: `
335
382
  import { eq } from 'drizzle-orm'
336
383
  import { MySql2Database } from 'drizzle-orm/mysql2'
384
+ import { schema, type SchemaType } from '../../../db/schema'`,
385
+ queries: mysqlDrizzleQueryOperations
386
+ },
387
+ 'mysql:drizzle:planetscale': {
388
+ dbType: 'PlanetScaleDatabase<SchemaType>',
389
+ importLines: `
390
+ import { eq } from 'drizzle-orm'
391
+ import { PlanetScaleDatabase } from 'drizzle-orm/planetscale-serverless'
337
392
  import { schema, type SchemaType } from '../../../db/schema'`,
338
393
  queries: mysqlDrizzleQueryOperations
339
394
  },
@@ -342,6 +397,11 @@ import { schema, type SchemaType } from '../../../db/schema'`,
342
397
  importLines: `import { SQL } from 'bun'`,
343
398
  queries: mysqlSqlQueryOperations
344
399
  },
400
+ 'mysql:sql:planetscale': {
401
+ dbType: 'Client',
402
+ importLines: `import { Client } from '@planetscale/database'`,
403
+ queries: mysqlPlanetScaleQueryOperations
404
+ },
345
405
  'postgresql:drizzle:local': {
346
406
  dbType: 'BunSQLDatabase<SchemaType>',
347
407
  importLines: `
@@ -355,6 +415,14 @@ import { schema, type SchemaType } from '../../../db/schema'`,
355
415
  importLines: `
356
416
  import { eq } from 'drizzle-orm'
357
417
  import { NeonDatabase } from 'drizzle-orm/neon-serverless'
418
+ import { schema, type SchemaType } from '../../../db/schema'`,
419
+ queries: drizzleQueryOperations
420
+ },
421
+ 'postgresql:drizzle:planetscale': {
422
+ dbType: 'NodePgDatabase<SchemaType>',
423
+ importLines: `
424
+ import { eq } from 'drizzle-orm'
425
+ import { NodePgDatabase } from 'drizzle-orm/node-postgres'
358
426
  import { schema, type SchemaType } from '../../../db/schema'`,
359
427
  queries: drizzleQueryOperations
360
428
  },
@@ -366,7 +434,12 @@ import { schema, type SchemaType } from '../../../db/schema'`,
366
434
  'postgresql:sql:neon': {
367
435
  dbType: 'Pool',
368
436
  importLines: `import { Pool } from '@neondatabase/serverless'`,
369
- queries: postgresNeonQueryOperations
437
+ queries: postgresQueryOperations
438
+ },
439
+ 'postgresql:sql:planetscale': {
440
+ dbType: 'Pool',
441
+ importLines: `import { Pool } from 'pg'`,
442
+ queries: postgresQueryOperations
370
443
  },
371
444
  'singlestore:sql:local': {
372
445
  dbType: 'Pool',
@@ -17,13 +17,16 @@ const connectionMap = {
17
17
  },
18
18
  mysql: {
19
19
  none: { expr: 'new SQL(getEnv("DATABASE_URL"))' },
20
- planetscale: { expr: 'connect({ url: getEnv("DATABASE_URL") })' }
20
+ planetscale: { expr: 'new Client({ url: getEnv("DATABASE_URL") })' }
21
21
  },
22
22
  postgresql: {
23
23
  neon: {
24
24
  expr: 'new Pool({ connectionString: getEnv("DATABASE_URL") })'
25
25
  },
26
- none: { expr: 'new SQL(getEnv("DATABASE_URL"))' }
26
+ none: { expr: 'new SQL(getEnv("DATABASE_URL"))' },
27
+ planetscale: {
28
+ expr: 'new Pool({ connectionString: getEnv("DATABASE_URL") })'
29
+ }
27
30
  },
28
31
  singlestore: {
29
32
  none: { expr: 'createPool(getEnv("DATABASE_URL"))' }
@@ -35,7 +38,7 @@ const connectionMap = {
35
38
  };
36
39
  const remoteDrizzleInit = {
37
40
  neon: 'new Pool({ connectionString: getEnv("DATABASE_URL") })',
38
- planetscale: 'connect({ url: getEnv("DATABASE_URL") })',
41
+ planetscale: 'new Client({ url: getEnv("DATABASE_URL") })',
39
42
  turso: 'createClient({ url: getEnv("DATABASE_URL") })'
40
43
  };
41
44
  const drizzleDialectSet = new Set([...availableDrizzleDialects]);
@@ -56,13 +59,11 @@ export const generateDBBlock = ({ databaseEngine, orm, databaseHost }) => {
56
59
  const expr = engineGroup[hostKey]?.expr ?? remoteDrizzleInit[hostKey];
57
60
  if (!expr)
58
61
  return '';
59
- if (databaseEngine === 'mysql' || databaseEngine === 'mariadb') {
60
- const mode = databaseHost === 'planetscale' && databaseEngine === 'mysql'
61
- ? 'planetscale'
62
- : 'default';
62
+ if ((databaseEngine === 'mysql' || databaseEngine === 'mariadb') &&
63
+ databaseHost !== 'planetscale') {
63
64
  return `
64
65
  const pool = createPool(getEnv("DATABASE_URL"))
65
- const db = drizzle(pool, { schema, mode: '${mode}' })
66
+ const db = drizzle(pool, { schema, mode: 'default' })
66
67
  `;
67
68
  }
68
69
  return `
@@ -39,7 +39,7 @@ export const generateImportsBlock = ({ backendDirectory, deps, flags, orm, authP
39
39
  rawImports.push(`import VueExample from '${buildExamplePath(vueDir, 'VueExample.vue')}'`);
40
40
  const connectorImports = {
41
41
  neon: [`import { Pool } from '@neondatabase/serverless'`],
42
- planetscale: [`import { connect } from '@planetscale/database'`],
42
+ planetscale: [`import { Client } from '@planetscale/database'`],
43
43
  turso: [`import { createClient } from '@libsql/client'`]
44
44
  };
45
45
  const dialectImports = {
@@ -87,7 +87,12 @@ export const generateImportsBlock = ({ backendDirectory, deps, flags, orm, authP
87
87
  `import { SQL } from 'bun'`,
88
88
  `import { drizzle } from 'drizzle-orm/bun-sql'`
89
89
  ]
90
- : [],
90
+ : isRemoteHost && databaseHost === 'planetscale'
91
+ ? [
92
+ `import { drizzle } from 'drizzle-orm/node-postgres'`,
93
+ `import { Pool } from 'pg'`
94
+ ]
95
+ : [],
91
96
  singlestore: [
92
97
  `import { drizzle } from 'drizzle-orm/singlestore'`,
93
98
  `import { createPool } from 'mysql2/promise'`
@@ -127,15 +132,20 @@ export const generateImportsBlock = ({ backendDirectory, deps, flags, orm, authP
127
132
  `import { SQL } from 'bun'`,
128
133
  `import { getEnv } from '@absolutejs/absolute'`
129
134
  ],
130
- postgresql: isRemoteHost
135
+ postgresql: isRemoteHost && databaseHost === 'neon'
131
136
  ? [
132
137
  ...connectorImports[databaseHost],
133
138
  `import { getEnv } from '@absolutejs/absolute'`
134
139
  ]
135
- : [
136
- `import { SQL } from 'bun'`,
137
- `import { getEnv } from '@absolutejs/absolute'`
138
- ],
140
+ : isRemoteHost && databaseHost === 'planetscale'
141
+ ? [
142
+ `import { Pool } from 'pg'`,
143
+ `import { getEnv } from '@absolutejs/absolute'`
144
+ ]
145
+ : [
146
+ `import { SQL } from 'bun'`,
147
+ `import { getEnv } from '@absolutejs/absolute'`
148
+ ],
139
149
  singlestore: [
140
150
  `import { createPool } from 'mysql2/promise'`,
141
151
  `import { getEnv } from '@absolutejs/absolute'`
@@ -150,7 +160,9 @@ export const generateImportsBlock = ({ backendDirectory, deps, flags, orm, authP
150
160
  if (orm === 'drizzle') {
151
161
  rawImports.push(...ormImports[orm]);
152
162
  }
153
- if (orm === 'drizzle' && isRemoteHost) {
163
+ if (orm == 'drizzle' &&
164
+ isRemoteHost &&
165
+ !(databaseEngine === 'postgresql' && databaseHost === 'planetscale')) {
154
166
  rawImports.push(...connectorImports[databaseHost], ...dialectImports[databaseHost]);
155
167
  }
156
168
  if (orm === 'drizzle' && isDrizzleDialect(databaseEngine)) {
package/dist/messages.js CHANGED
@@ -34,7 +34,7 @@ Options:
34
34
  ${cyan('--plugin')} ${dim(cyan('<plugin>'))} Elysia plugin(s) to include (repeatable); 'none' skips plugin setup
35
35
  ${cyan('--react')} Include a React frontend
36
36
  ${cyan('--react-dir')} ${dim(cyan('<directory>'))} Specify the directory for and use the React frontend
37
- ${cyan('--skip')} Skip non-required prompts; uses 'none' for all optional configs
37
+ ${cyan('--skip')} Skip non-required prompts; use 'none' for all optional configs and "absolutejs-project" when no project name is provided.
38
38
  ${cyan('--svelte')} Include a Svelte frontend
39
39
  ${cyan('--svelte-dir')} ${dim(cyan('<directory>'))} Specify the directory for and use the Svelte frontend
40
40
  ${cyan('--tailwind')} Include Tailwind CSS setup
@@ -15,6 +15,18 @@ export const getDatabaseHost = async (databaseEngine) => {
15
15
  abort();
16
16
  return databaseHost === 'none' ? undefined : databaseHost;
17
17
  }
18
+ if (databaseEngine === 'mysql') {
19
+ const databaseHost = await select({
20
+ message: 'Select database host:',
21
+ options: [
22
+ { label: 'None', value: 'none' },
23
+ { label: cyan('PlanetScale'), value: 'planetscale' }
24
+ ]
25
+ });
26
+ if (isCancel(databaseHost))
27
+ abort();
28
+ return databaseHost === 'none' ? undefined : databaseHost;
29
+ }
18
30
  if (databaseEngine === 'sqlite') {
19
31
  const databaseHost = await select({
20
32
  message: 'Select database host:',
@@ -0,0 +1 @@
1
+ @import 'tailwindcss';
@@ -46,7 +46,7 @@ export const parseCommandLineOptions = () => {
46
46
  }
47
47
  });
48
48
  const errors = [];
49
- const projectName = positionals[0] ?? (values.skip ? undefined : 'absolutejs-project');
49
+ const projectName = positionals[0] ?? (values.skip ? 'absolutejs-project' : undefined);
50
50
  let authProvider;
51
51
  if (values.auth !== undefined && !isAuthProvider(values.auth)) {
52
52
  errors.push(`Invalid auth provider: "${values.auth}". Expected: [ ${availableAuthProviders.join(', ')} ]`);
package/package.json CHANGED
@@ -47,5 +47,5 @@
47
47
  "typecheck": "bun run tsc --noEmit"
48
48
  },
49
49
  "type": "module",
50
- "version": "0.5.0"
50
+ "version": "0.5.1"
51
51
  }