create-absolutejs 0.19.0 → 0.20.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.
Files changed (52) hide show
  1. package/CHANGELOG.md +6 -0
  2. package/README.md +9 -2
  3. package/changelog.json +10 -0
  4. package/dist/generators/configurations/generateEslintConfig.js +1 -1
  5. package/dist/generators/configurations/generatePackageJson.d.ts +2 -1
  6. package/dist/generators/configurations/generatePackageJson.js +10 -1
  7. package/dist/generators/db/scaffoldDatabase.js +14 -4
  8. package/dist/generators/prisma/generatePrismaCode.d.ts +6 -0
  9. package/dist/generators/prisma/generatePrismaCode.js +148 -0
  10. package/dist/generators/prisma/generatePrismaConfig.d.ts +8 -0
  11. package/dist/generators/prisma/generatePrismaConfig.js +68 -0
  12. package/dist/generators/prisma/generatePrismaSchema.d.ts +9 -0
  13. package/dist/generators/prisma/generatePrismaSchema.js +80 -0
  14. package/dist/generators/prisma/prismaPackageJson.d.ts +8 -0
  15. package/dist/generators/prisma/prismaPackageJson.js +46 -0
  16. package/dist/generators/prisma/prismaTargets.d.ts +22 -0
  17. package/dist/generators/prisma/prismaTargets.js +91 -0
  18. package/dist/generators/prisma/scaffoldPrismaDatabase.d.ts +16 -0
  19. package/dist/generators/prisma/scaffoldPrismaDatabase.js +136 -0
  20. package/dist/generators/project/generateDBBlock.js +5 -0
  21. package/dist/generators/project/generateImportsBlock.js +6 -1
  22. package/dist/questions/orm.js +5 -2
  23. package/dist/scaffold.js +4 -4
  24. package/dist/templates/configurations/.prettierignore +2 -1
  25. package/dist/templates/configurations/eslint.config.example.mjs +2 -1
  26. package/dist/templates/db/migrations/prisma-cockroachdb-count-history/20260926000000_init/migration.sql +12 -0
  27. package/dist/templates/db/migrations/prisma-cockroachdb-count-history/migration_lock.toml +3 -0
  28. package/dist/templates/db/migrations/prisma-cockroachdb-users/20260926000000_init/migration.sql +12 -0
  29. package/dist/templates/db/migrations/prisma-cockroachdb-users/migration_lock.toml +3 -0
  30. package/dist/templates/db/migrations/prisma-mysql-count-history/20260926000000_init/migration.sql +9 -0
  31. package/dist/templates/db/migrations/prisma-mysql-count-history/migration_lock.toml +3 -0
  32. package/dist/templates/db/migrations/prisma-mysql-users/20260926000000_init/migration.sql +9 -0
  33. package/dist/templates/db/migrations/prisma-mysql-users/migration_lock.toml +3 -0
  34. package/dist/templates/db/migrations/prisma-postgresql-count-history/20260926000000_init/migration.sql +12 -0
  35. package/dist/templates/db/migrations/prisma-postgresql-count-history/migration_lock.toml +3 -0
  36. package/dist/templates/db/migrations/prisma-postgresql-users/20260926000000_init/migration.sql +12 -0
  37. package/dist/templates/db/migrations/prisma-postgresql-users/migration_lock.toml +3 -0
  38. package/dist/templates/db/migrations/prisma-sqlite-count-history/20260926000000_init/migration.sql +7 -0
  39. package/dist/templates/db/migrations/prisma-sqlite-count-history/migration_lock.toml +3 -0
  40. package/dist/templates/db/migrations/prisma-sqlite-users/20260926000000_init/migration.sql +7 -0
  41. package/dist/templates/db/migrations/prisma-sqlite-users/migration_lock.toml +3 -0
  42. package/dist/templates/db/migrations/prisma-sqlserver-count-history/20260926000000_init/migration.sql +28 -0
  43. package/dist/templates/db/migrations/prisma-sqlserver-count-history/migration_lock.toml +3 -0
  44. package/dist/templates/db/migrations/prisma-sqlserver-users/20260926000000_init/migration.sql +28 -0
  45. package/dist/templates/db/migrations/prisma-sqlserver-users/migration_lock.toml +3 -0
  46. package/dist/templates/git/gitignore +5 -0
  47. package/dist/typeGuards.d.ts +2 -2
  48. package/dist/utils/parseCommandLineOptions.js +2 -8
  49. package/dist/utils/validateDatabaseSelection.js +5 -2
  50. package/dist/versions.d.ts +9 -0
  51. package/dist/versions.js +13 -0
  52. package/package.json +2 -1
@@ -0,0 +1,16 @@
1
+ import type { AuthOption, DatabaseEngine, DatabaseHost } from '../../types';
2
+ import { type PrismaTarget } from './prismaTargets';
3
+ type ScaffoldPrismaDatabaseProps = {
4
+ authOption: AuthOption;
5
+ backendDirectory: string;
6
+ databaseDirectory: string;
7
+ databaseEngine: DatabaseEngine;
8
+ databaseHost: DatabaseHost;
9
+ projectName: string;
10
+ typesDirectory: string;
11
+ verifyLocalDatabase: boolean;
12
+ };
13
+ export declare const prismaMongoDBCompose = "services:\n db:\n image: mongo:7.0\n restart: always\n command: [\"--replSet\", \"rs0\", \"--bind_ip_all\"]\n ports:\n - \"27017:27017\"\n healthcheck:\n test: [\"CMD-SHELL\", \"mongosh --quiet --eval \\\"try { if (rs.status().myState !== 1) quit(1) } catch (error) { rs.initiate({ _id: 'rs0', members: [{ _id: 0, host: 'localhost:27017' }] }); quit(1) }\\\"\"]\n interval: 2s\n timeout: 5s\n retries: 30\n start_period: 5s\n volumes:\n - db_data:/data/db\n\nvolumes:\n db_data:\n";
14
+ export declare const getPrismaLocalDatabaseUrl: (target: PrismaTarget, databaseDirectory: string, databaseHost: DatabaseHost) => string | undefined;
15
+ export declare const scaffoldPrismaDatabase: ({ authOption, backendDirectory, databaseDirectory, databaseEngine, databaseHost, projectName, typesDirectory, verifyLocalDatabase }: ScaffoldPrismaDatabaseProps) => Promise<boolean>;
16
+ export {};
@@ -0,0 +1,136 @@
1
+ import { cpSync, existsSync, readFileSync, writeFileSync } from 'fs';
2
+ import { dirname, join } from 'path';
3
+ import { fileURLToPath } from 'url';
4
+ import { spinner } from '@clack/prompts';
5
+ import { $ } from 'bun';
6
+ import { green, red } from 'picocolors';
7
+ import { isPrismaDialect } from '../../typeGuards';
8
+ import { checkDockerInstalled, ensureDockerDaemonRunning, resolveDockerExe, shutdownDockerDaemon } from '../../utils/checkDockerInstalled';
9
+ import { scaffoldDocker } from '../db/scaffoldDocker';
10
+ import { generatePrismaDatabaseTypes, generatePrismaHandlers } from './generatePrismaCode';
11
+ import { generateLibsqlMigrateScript, generatePrismaConfig } from './generatePrismaConfig';
12
+ import { generatePrismaSchema } from './generatePrismaSchema';
13
+ import { getPrismaMigrationTemplateName, getPrismaTarget } from './prismaTargets';
14
+ /* Prisma requires MongoDB to run as a replica set (it writes through
15
+ transactions). A single-node set is initiated by the healthcheck itself,
16
+ which only passes once the node is PRIMARY — so `db:up --wait` is followed
17
+ safely by `db:migrate`. */
18
+ export const prismaMongoDBCompose = `services:
19
+ db:
20
+ image: mongo:7.0
21
+ restart: always
22
+ command: ["--replSet", "rs0", "--bind_ip_all"]
23
+ ports:
24
+ - "27017:27017"
25
+ healthcheck:
26
+ test: ["CMD-SHELL", "mongosh --quiet --eval \\"try { if (rs.status().myState !== 1) quit(1) } catch (error) { rs.initiate({ _id: 'rs0', members: [{ _id: 0, host: 'localhost:27017' }] }); quit(1) }\\""]
27
+ interval: 2s
28
+ timeout: 5s
29
+ retries: 30
30
+ start_period: 5s
31
+ volumes:
32
+ - db_data:/data/db
33
+
34
+ volumes:
35
+ db_data:
36
+ `;
37
+ /* The local DATABASE_URL a Prisma project starts with, where it differs from
38
+ the no-ORM default generateEnv writes: SQLite needs a URL at all (the libSQL
39
+ adapter and Prisma Migrate both take one), MongoDB is the unauthenticated
40
+ replica set above, SQL Server uses Prisma's `sqlserver://` format and
41
+ MariaDB the `mysql://` scheme. */
42
+ export const getPrismaLocalDatabaseUrl = (target, databaseDirectory, databaseHost) => {
43
+ const isLocal = databaseHost === undefined || databaseHost === 'none';
44
+ if (!isLocal)
45
+ return undefined;
46
+ switch (target.provider) {
47
+ case 'mongodb':
48
+ return 'mongodb://localhost:27017/database?replicaSet=rs0&directConnection=true';
49
+ /* MariaDB too: Prisma Migrate only accepts the mysql:// scheme, and the
50
+ mariadb driver adapter takes it as well. */
51
+ case 'mysql':
52
+ return 'mysql://user:userpassword@localhost:3306/database';
53
+ case 'sqlite':
54
+ return `file:./${databaseDirectory}/database.sqlite`;
55
+ case 'sqlserver':
56
+ return 'sqlserver://localhost:1433;database=master;user=sa;password=SApassword1;encrypt=true;trustServerCertificate=true';
57
+ default:
58
+ return undefined;
59
+ }
60
+ };
61
+ /* Sets DATABASE_URL in the project's own .env, keeping every other line. */
62
+ const setProjectDatabaseUrl = (projectName, url) => {
63
+ const envPath = join(projectName, '.env');
64
+ const lines = existsSync(envPath)
65
+ ? readFileSync(envPath, 'utf8')
66
+ .split('\n')
67
+ .filter((line) => !line.startsWith('DATABASE_URL='))
68
+ : [];
69
+ writeFileSync(envPath, [...lines, `DATABASE_URL=${url}`].join('\n'));
70
+ };
71
+ const verifyMongoDBContainer = async (projectName, databaseDirectory) => {
72
+ const { freshInstall } = await checkDockerInstalled('mongodb');
73
+ const { daemonWasStarted } = await ensureDockerDaemonRunning();
74
+ const docker = resolveDockerExe();
75
+ const compose = [
76
+ 'compose',
77
+ '-p',
78
+ 'mongodb',
79
+ '-f',
80
+ `${databaseDirectory}/docker-compose.db.yml`
81
+ ];
82
+ const spin = spinner();
83
+ spin.start('Starting mongodb replica set');
84
+ try {
85
+ await $ `${docker} ${compose} up -d --wait db`.cwd(projectName).quiet();
86
+ await $ `${docker} ${compose} down`.cwd(projectName).quiet();
87
+ spin.stop(green('Docker container verified'));
88
+ }
89
+ catch (error) {
90
+ spin.cancel(red('Docker setup failed'));
91
+ throw error;
92
+ }
93
+ if (daemonWasStarted)
94
+ await shutdownDockerDaemon();
95
+ return freshInstall;
96
+ };
97
+ const templatesDirectory = () => join(dirname(fileURLToPath(import.meta.url)), '..', '..', 'templates');
98
+ /* Scaffolds a Prisma project's database layer: schema, prisma.config.ts, the
99
+ committed initial migration, typed handlers and types, local .env URL and
100
+ the Docker database. Everything is written under `projectName`. */
101
+ export const scaffoldPrismaDatabase = async ({ authOption, backendDirectory, databaseDirectory, databaseEngine, databaseHost, projectName, typesDirectory, verifyLocalDatabase }) => {
102
+ if (!isPrismaDialect(databaseEngine))
103
+ throw new Error(`Internal type error: "${databaseEngine}" is not a Prisma database`);
104
+ const target = getPrismaTarget(databaseEngine, databaseHost);
105
+ const projectDatabaseDirectory = join(projectName, databaseDirectory);
106
+ const usesAuth = authOption === 'abs';
107
+ writeFileSync(join(projectDatabaseDirectory, 'schema.prisma'), generatePrismaSchema({ authOption, databaseDirectory, target }));
108
+ writeFileSync(join(projectName, 'prisma.config.ts'), generatePrismaConfig({ databaseDirectory, target }));
109
+ if (target.provider !== 'mongodb')
110
+ cpSync(join(templatesDirectory(), 'db', 'migrations', getPrismaMigrationTemplateName(target.provider, usesAuth)), join(projectDatabaseDirectory, 'migrations'), { recursive: true });
111
+ if (target.migration === 'libsql')
112
+ writeFileSync(join(projectDatabaseDirectory, 'migrate.ts'), generateLibsqlMigrateScript());
113
+ writeFileSync(join(backendDirectory, 'handlers', usesAuth ? 'userHandlers.ts' : 'countHistoryHandlers.ts'), generatePrismaHandlers(authOption, target));
114
+ writeFileSync(join(typesDirectory, 'databaseTypes.ts'), generatePrismaDatabaseTypes(authOption, target));
115
+ const localUrl = getPrismaLocalDatabaseUrl(target, databaseDirectory, databaseHost);
116
+ if (localUrl)
117
+ setProjectDatabaseUrl(projectName, localUrl);
118
+ const isLocal = databaseHost === undefined || databaseHost === 'none';
119
+ if (!isLocal || target.provider === 'sqlite')
120
+ return false;
121
+ if (target.provider === 'mongodb') {
122
+ writeFileSync(join(projectDatabaseDirectory, 'docker-compose.db.yml'), prismaMongoDBCompose);
123
+ return (verifyLocalDatabase &&
124
+ verifyMongoDBContainer(projectName, databaseDirectory));
125
+ }
126
+ /* Migrations own the schema, so the container is only verified. */
127
+ const { dockerFreshInstall } = await scaffoldDocker({
128
+ authOption,
129
+ databaseEngine,
130
+ initializeSchema: false,
131
+ projectDatabaseDirectory,
132
+ projectName,
133
+ verifyLocalDatabase
134
+ });
135
+ return dockerFreshInstall;
136
+ };
@@ -1,4 +1,7 @@
1
1
  import { availableDrizzleDialects } from '../../data';
2
+ import { isPrismaDialect } from '../../typeGuards';
3
+ import { generatePrismaDBBlock } from '../prisma/generatePrismaCode';
4
+ import { getPrismaTarget } from '../prisma/prismaTargets';
2
5
  /* A Turso database needs its auth token; a local libSQL `file:` URL has none,
3
6
  so the token stays optional. */
4
7
  const tursoClient = 'createClient({ authToken: env.DATABASE_AUTH_TOKEN, url: getEnv("DATABASE_URL") })';
@@ -52,6 +55,8 @@ export const generateDBBlock = ({ databaseEngine, orm, databaseHost }) => {
52
55
  if (!databaseEngine || databaseEngine === 'none') {
53
56
  throw new Error('Internal type error: Expected a valid database engine');
54
57
  }
58
+ if (orm === 'prisma' && isPrismaDialect(databaseEngine))
59
+ return generatePrismaDBBlock(getPrismaTarget(databaseEngine, databaseHost));
55
60
  const hostKey = databaseHost ?? 'none';
56
61
  const engineGroup = connectionMap[databaseEngine];
57
62
  if (!engineGroup)
@@ -1,4 +1,6 @@
1
- import { isDrizzleDialect } from '../../typeGuards';
1
+ import { isDrizzleDialect, isPrismaDialect } from '../../typeGuards';
2
+ import { getPrismaServerImports } from '../prisma/generatePrismaCode';
3
+ import { getPrismaTarget } from '../prisma/prismaTargets';
2
4
  export const generateImportsBlock = ({ deps, flags, orm, authOption, databaseEngine, databaseHost, frontendDirectories }) => {
3
5
  const rawImports = [];
4
6
  const pushHandler = (cond, name, pkg = '@absolutejs/absolute') => cond && rawImports.push(`import { ${name} } from '${pkg}'`);
@@ -185,6 +187,9 @@ export const generateImportsBlock = ({ deps, flags, orm, authOption, databaseEng
185
187
  if (orm === 'drizzle' && isDrizzleDialect(databaseEngine)) {
186
188
  rawImports.push(...ormDatabaseImports[orm][databaseEngine]);
187
189
  }
190
+ if (orm === 'prisma' && isPrismaDialect(databaseEngine)) {
191
+ rawImports.push(...getPrismaServerImports(getPrismaTarget(databaseEngine, databaseHost)));
192
+ }
188
193
  if (noOrm && hasDatabase && noOrmImports[databaseEngine]) {
189
194
  rawImports.push(...noOrmImports[databaseEngine]);
190
195
  }
@@ -1,6 +1,6 @@
1
1
  import { select, isCancel } from '@clack/prompts';
2
- import { cyan } from 'picocolors';
3
- import { isDrizzleDialect } from '../typeGuards';
2
+ import { cyan, magenta } from 'picocolors';
3
+ import { isDrizzleDialect, isPrismaDialect } from '../typeGuards';
4
4
  import { abort } from '../utils/abort';
5
5
  export const getORM = async (databaseEngine) => {
6
6
  const options = [
@@ -9,6 +9,9 @@ export const getORM = async (databaseEngine) => {
9
9
  if (isDrizzleDialect(databaseEngine)) {
10
10
  options.push({ label: cyan('Drizzle'), value: 'drizzle' });
11
11
  }
12
+ if (isPrismaDialect(databaseEngine)) {
13
+ options.push({ label: magenta('Prisma'), value: 'prisma' });
14
+ }
12
15
  const orm = await select({
13
16
  message: 'Choose an ORM for your database:',
14
17
  options
package/dist/scaffold.js CHANGED
@@ -21,8 +21,6 @@ export const scaffold = async ({ response: { agentic, projectName, codeQualityTo
21
21
  });
22
22
  if (databaseErrors.length > 0)
23
23
  throw new Error(databaseErrors.join('\n'));
24
- if (orm === 'prisma')
25
- throw new Error('Prisma scaffolding is not implemented. Choose Drizzle or no ORM.');
26
24
  if (authOption === 'abs' && (!databaseEngine || databaseEngine === 'none'))
27
25
  throw new Error('Authentication requires a database for persistent users. Select a database or omit --auth.');
28
26
  if (authOption === 'abs' &&
@@ -48,6 +46,7 @@ export const scaffold = async ({ response: { agentic, projectName, codeQualityTo
48
46
  agentic,
49
47
  authOption,
50
48
  codeQualityTool,
49
+ databaseDirectory,
51
50
  databaseEngine,
52
51
  databaseHost,
53
52
  frontendDirectories,
@@ -121,7 +120,8 @@ export const server = treaty<Api>(serverUrl)
121
120
  if (installDependenciesNow) {
122
121
  await installDependencies(packageManager, projectName);
123
122
  }
124
- const databaseMigrated = orm === 'drizzle' &&
123
+ const usesMigrations = orm === 'drizzle' || orm === 'prisma';
124
+ const databaseMigrated = usesMigrations &&
125
125
  installDependenciesNow &&
126
126
  (await migrateDatabase({
127
127
  databaseEngine,
@@ -143,7 +143,7 @@ export const server = treaty<Api>(serverUrl)
143
143
  });
144
144
  }
145
145
  return {
146
- databaseMigrationPending: orm === 'drizzle' && !databaseMigrated,
146
+ databaseMigrationPending: usesMigrations && !databaseMigrated,
147
147
  dockerFreshInstall
148
148
  };
149
149
  };
@@ -1,4 +1,5 @@
1
1
  node_modules
2
2
  dist
3
3
  build
4
- *.min.js
4
+ *.min.js
5
+ src/generated
@@ -12,7 +12,8 @@ export default defineConfig([
12
12
  '.absolutejs/**',
13
13
  '.data/**',
14
14
  '**/.absolutejs-hmr-*',
15
- 'drizzle/**'
15
+ 'drizzle/**',
16
+ 'src/generated/**'
16
17
  ]
17
18
  },
18
19
  {
@@ -0,0 +1,12 @@
1
+ -- CreateSchema
2
+ CREATE SCHEMA IF NOT EXISTS "public";
3
+
4
+ -- CreateTable
5
+ CREATE TABLE "count_history" (
6
+ "uid" INT4 NOT NULL GENERATED BY DEFAULT AS IDENTITY (MAXVALUE 2147483647),
7
+ "count" INT4 NOT NULL,
8
+ "created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
9
+
10
+ CONSTRAINT "count_history_pkey" PRIMARY KEY ("uid")
11
+ );
12
+
@@ -0,0 +1,3 @@
1
+ # Please do not edit this file manually
2
+ # It should be added in your version-control system (e.g., Git)
3
+ provider = "cockroachdb"
@@ -0,0 +1,12 @@
1
+ -- CreateSchema
2
+ CREATE SCHEMA IF NOT EXISTS "public";
3
+
4
+ -- CreateTable
5
+ CREATE TABLE "users" (
6
+ "auth_sub" STRING(255) NOT NULL,
7
+ "created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
8
+ "metadata" JSONB NOT NULL,
9
+
10
+ CONSTRAINT "users_pkey" PRIMARY KEY ("auth_sub")
11
+ );
12
+
@@ -0,0 +1,3 @@
1
+ # Please do not edit this file manually
2
+ # It should be added in your version-control system (e.g., Git)
3
+ provider = "cockroachdb"
@@ -0,0 +1,9 @@
1
+ -- CreateTable
2
+ CREATE TABLE `count_history` (
3
+ `uid` INTEGER NOT NULL AUTO_INCREMENT,
4
+ `count` INTEGER NOT NULL,
5
+ `created_at` DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3),
6
+
7
+ PRIMARY KEY (`uid`)
8
+ ) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
9
+
@@ -0,0 +1,3 @@
1
+ # Please do not edit this file manually
2
+ # It should be added in your version-control system (e.g., Git)
3
+ provider = "mysql"
@@ -0,0 +1,9 @@
1
+ -- CreateTable
2
+ CREATE TABLE `users` (
3
+ `auth_sub` VARCHAR(255) NOT NULL,
4
+ `created_at` DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3),
5
+ `metadata` JSON NOT NULL,
6
+
7
+ PRIMARY KEY (`auth_sub`)
8
+ ) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
9
+
@@ -0,0 +1,3 @@
1
+ # Please do not edit this file manually
2
+ # It should be added in your version-control system (e.g., Git)
3
+ provider = "mysql"
@@ -0,0 +1,12 @@
1
+ -- CreateSchema
2
+ CREATE SCHEMA IF NOT EXISTS "public";
3
+
4
+ -- CreateTable
5
+ CREATE TABLE "count_history" (
6
+ "uid" SERIAL NOT NULL,
7
+ "count" INTEGER NOT NULL,
8
+ "created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
9
+
10
+ CONSTRAINT "count_history_pkey" PRIMARY KEY ("uid")
11
+ );
12
+
@@ -0,0 +1,3 @@
1
+ # Please do not edit this file manually
2
+ # It should be added in your version-control system (e.g., Git)
3
+ provider = "postgresql"
@@ -0,0 +1,12 @@
1
+ -- CreateSchema
2
+ CREATE SCHEMA IF NOT EXISTS "public";
3
+
4
+ -- CreateTable
5
+ CREATE TABLE "users" (
6
+ "auth_sub" VARCHAR(255) NOT NULL,
7
+ "created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
8
+ "metadata" JSONB NOT NULL,
9
+
10
+ CONSTRAINT "users_pkey" PRIMARY KEY ("auth_sub")
11
+ );
12
+
@@ -0,0 +1,3 @@
1
+ # Please do not edit this file manually
2
+ # It should be added in your version-control system (e.g., Git)
3
+ provider = "postgresql"
@@ -0,0 +1,7 @@
1
+ -- CreateTable
2
+ CREATE TABLE "count_history" (
3
+ "uid" INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
4
+ "count" INTEGER NOT NULL,
5
+ "created_at" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP
6
+ );
7
+
@@ -0,0 +1,3 @@
1
+ # Please do not edit this file manually
2
+ # It should be added in your version-control system (e.g., Git)
3
+ provider = "sqlite"
@@ -0,0 +1,7 @@
1
+ -- CreateTable
2
+ CREATE TABLE "users" (
3
+ "auth_sub" TEXT NOT NULL PRIMARY KEY,
4
+ "created_at" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
5
+ "metadata" JSONB NOT NULL
6
+ );
7
+
@@ -0,0 +1,3 @@
1
+ # Please do not edit this file manually
2
+ # It should be added in your version-control system (e.g., Git)
3
+ provider = "sqlite"
@@ -0,0 +1,28 @@
1
+ BEGIN TRY
2
+
3
+ BEGIN TRAN;
4
+
5
+ -- CreateSchema
6
+ IF NOT EXISTS (SELECT * FROM sys.schemas WHERE name = N'dbo') EXEC sp_executesql N'CREATE SCHEMA [dbo];';
7
+
8
+ -- CreateTable
9
+ CREATE TABLE [dbo].[count_history] (
10
+ [uid] INT NOT NULL IDENTITY(1,1),
11
+ [count] INT NOT NULL,
12
+ [created_at] DATETIME2 NOT NULL CONSTRAINT [count_history_created_at_df] DEFAULT CURRENT_TIMESTAMP,
13
+ CONSTRAINT [count_history_pkey] PRIMARY KEY CLUSTERED ([uid])
14
+ );
15
+
16
+ COMMIT TRAN;
17
+
18
+ END TRY
19
+ BEGIN CATCH
20
+
21
+ IF @@TRANCOUNT > 0
22
+ BEGIN
23
+ ROLLBACK TRAN;
24
+ END;
25
+ THROW
26
+
27
+ END CATCH
28
+
@@ -0,0 +1,3 @@
1
+ # Please do not edit this file manually
2
+ # It should be added in your version-control system (e.g., Git)
3
+ provider = "mssql"
@@ -0,0 +1,28 @@
1
+ BEGIN TRY
2
+
3
+ BEGIN TRAN;
4
+
5
+ -- CreateSchema
6
+ IF NOT EXISTS (SELECT * FROM sys.schemas WHERE name = N'dbo') EXEC sp_executesql N'CREATE SCHEMA [dbo];';
7
+
8
+ -- CreateTable
9
+ CREATE TABLE [dbo].[users] (
10
+ [auth_sub] NVARCHAR(255) NOT NULL,
11
+ [created_at] DATETIME2 NOT NULL CONSTRAINT [users_created_at_df] DEFAULT CURRENT_TIMESTAMP,
12
+ [metadata] NVARCHAR(max) NOT NULL,
13
+ CONSTRAINT [users_pkey] PRIMARY KEY CLUSTERED ([auth_sub])
14
+ );
15
+
16
+ COMMIT TRAN;
17
+
18
+ END TRY
19
+ BEGIN CATCH
20
+
21
+ IF @@TRANCOUNT > 0
22
+ BEGIN
23
+ ROLLBACK TRAN;
24
+ END;
25
+ THROW
26
+
27
+ END CATCH
28
+
@@ -0,0 +1,3 @@
1
+ # Please do not edit this file manually
2
+ # It should be added in your version-control system (e.g., Git)
3
+ provider = "mssql"
@@ -42,6 +42,11 @@ package-lock.json
42
42
  /build
43
43
  /drizzle
44
44
 
45
+ # generated Prisma client (rebuilt by postinstall / db:generate)
46
+ /src/generated
47
+ # scratch database Prisma Migrate authors libSQL migrations against
48
+ /db/prisma-migrate-dev.db
49
+
45
50
  # index files
46
51
  **/indexes/*
47
52
 
@@ -1,4 +1,4 @@
1
- import type { AuthOption, AvailableDrizzleDialect, CodeQualityTool, DatabaseEngine, DatabaseHost, Frontend, GithubLinkOption, ORM } from './types';
1
+ import type { AuthOption, AvailableDrizzleDialect, AvailablePrismaDialect, CodeQualityTool, DatabaseEngine, DatabaseHost, Frontend, GithubLinkOption, ORM } from './types';
2
2
  export declare const isCodeQualityTool: (value: string | undefined) => value is CodeQualityTool;
3
3
  export declare const isDatabaseEngine: (value: string | undefined) => value is DatabaseEngine;
4
4
  export declare const isDatabaseHost: (value: string | undefined) => value is DatabaseHost;
@@ -7,5 +7,5 @@ export declare const isDrizzleDialect: (value: string | undefined) => value is A
7
7
  export declare const isFrontend: (value: string | undefined) => value is Frontend;
8
8
  export declare const isGithubLinkOption: (value: string | undefined) => value is GithubLinkOption;
9
9
  export declare const isORM: (value: string | undefined) => value is ORM;
10
- export declare const isPrismaDialect: (value: string | undefined) => value is string;
10
+ export declare const isPrismaDialect: (value: string | undefined) => value is AvailablePrismaDialect;
11
11
  export declare const isValidAuthOption: (value: string | undefined) => value is AuthOption;
@@ -2,8 +2,8 @@ import { argv, exit } from 'process';
2
2
  import { parseArgs } from 'util';
3
3
  import { isValidProviderOption, providers } from '@absolutejs/auth';
4
4
  import { DEFAULT_ARG_LENGTH } from '../constants';
5
- import { availableAuthProviders, availableDatabaseEngines, availableDatabaseHosts, availableDirectoryConfigurations, availableORMs, availablePrismaDialects } from '../data';
6
- import { isValidAuthOption, isDatabaseEngine, isDatabaseHost, isDirectoryConfig, isGithubLinkOption, isORM, isPrismaDialect } from '../typeGuards';
5
+ import { availableAuthProviders, availableDatabaseEngines, availableDatabaseHosts, availableDirectoryConfigurations, availableORMs } from '../data';
6
+ import { isValidAuthOption, isDatabaseEngine, isDatabaseHost, isDirectoryConfig, isGithubLinkOption, isORM } from '../typeGuards';
7
7
  import { normalizeRepoInput } from './github';
8
8
  import { validateDatabaseSelection } from './validateDatabaseSelection';
9
9
  export const parseCommandLineOptions = () => {
@@ -143,12 +143,6 @@ export const parseCommandLineOptions = () => {
143
143
  });
144
144
  ({ databaseEngine } = databaseSelection);
145
145
  errors.push(...databaseSelection.errors);
146
- if (values.orm === 'prisma' &&
147
- databaseEngine !== undefined &&
148
- databaseEngine !== 'none' &&
149
- !isPrismaDialect(databaseEngine)) {
150
- errors.push(`Invalid database engine for Prisma ORM: "${databaseEngine}". Expected: [ ${availablePrismaDialects.join(', ')} ]`);
151
- }
152
146
  if (errors.length > 0) {
153
147
  console.error(errors.join('\n'));
154
148
  exit(1);
@@ -1,5 +1,5 @@
1
- import { availableDrizzleDialects } from '../data';
2
- import { isDrizzleDialect } from '../typeGuards';
1
+ import { availableDrizzleDialects, availablePrismaDialects } from '../data';
2
+ import { isDrizzleDialect, isPrismaDialect } from '../typeGuards';
3
3
  const hostEngines = {
4
4
  neon: { engines: ['postgresql'], label: 'Neon' },
5
5
  none: undefined,
@@ -22,6 +22,9 @@ export const validateDatabaseSelection = ({ databaseEngine, databaseHost, orm })
22
22
  !isDrizzleDialect(databaseEngine)) {
23
23
  errors.push(`Invalid database engine for Drizzle ORM: "${databaseEngine}". Expected: [ ${availableDrizzleDialects.join(', ')} ]`);
24
24
  }
25
+ if (orm === 'prisma' && hasEngine && !isPrismaDialect(databaseEngine)) {
26
+ errors.push(`Invalid database engine for Prisma ORM: "${databaseEngine}". Prisma supports [ ${availablePrismaDialects.join(', ')} ]; use "--orm none" with "--db ${databaseEngine}".`);
27
+ }
25
28
  const host = databaseHost === undefined ? undefined : hostEngines[databaseHost];
26
29
  const acceptsEngine = host?.engines.some((engine) => engine === resolvedEngine);
27
30
  if (host !== undefined && !acceptsEngine) {
@@ -1,3 +1,4 @@
1
+ export declare const prismaMongoDBVersion = "6.19.3";
1
2
  /**
2
3
  * Single source of truth for all scaffolded dependency versions.
3
4
  * Every package version used in project generation lives here.
@@ -42,6 +43,13 @@ export declare const versions: {
42
43
  readonly '@libsql/client': "0.18.0";
43
44
  readonly '@neondatabase/serverless': "1.1.0";
44
45
  readonly '@planetscale/database': "1.20.2";
46
+ readonly '@prisma/adapter-libsql': "7.10.0";
47
+ readonly '@prisma/adapter-mariadb': "7.10.0";
48
+ readonly '@prisma/adapter-mssql': "7.10.0";
49
+ readonly '@prisma/adapter-neon': "7.10.0";
50
+ readonly '@prisma/adapter-pg': "7.10.0";
51
+ readonly '@prisma/adapter-planetscale': "7.10.0";
52
+ readonly '@prisma/client': "7.10.0";
45
53
  readonly '@stylistic/eslint-plugin': "5.10.0";
46
54
  readonly '@tailwindcss/cli': "4.3.3";
47
55
  readonly '@types/bun': "1.4.2";
@@ -73,6 +81,7 @@ export declare const versions: {
73
81
  readonly postcss: "8.5.28";
74
82
  readonly prettier: "3.9.9";
75
83
  readonly 'prettier-plugin-svelte': "4.1.1";
84
+ readonly prisma: "7.10.0";
76
85
  readonly react: "19.3.0";
77
86
  readonly 'react-dom': "19.3.0";
78
87
  readonly 'react-refresh': "0.19.0";
package/dist/versions.js CHANGED
@@ -1,3 +1,7 @@
1
+ /* Prisma 7 does not support MongoDB (https://pris.ly/d/mongodb: "use Prisma
2
+ ORM v6.19"), so MongoDB projects pin the latest Prisma 6 line for both the
3
+ CLI and the client. */
4
+ export const prismaMongoDBVersion = '6.19.3';
1
5
  /**
2
6
  * Single source of truth for all scaffolded dependency versions.
3
7
  * Every package version used in project generation lives here.
@@ -47,6 +51,14 @@ export const versions = {
47
51
  '@libsql/client': '0.18.0',
48
52
  '@neondatabase/serverless': '1.1.0',
49
53
  '@planetscale/database': '1.20.2',
54
+ /* ── Prisma (7.x: query compiler + driver adapters) ──── */
55
+ '@prisma/adapter-libsql': '7.10.0',
56
+ '@prisma/adapter-mariadb': '7.10.0',
57
+ '@prisma/adapter-mssql': '7.10.0',
58
+ '@prisma/adapter-neon': '7.10.0',
59
+ '@prisma/adapter-pg': '7.10.0',
60
+ '@prisma/adapter-planetscale': '7.10.0',
61
+ '@prisma/client': '7.10.0',
50
62
  '@stylistic/eslint-plugin': '5.10.0',
51
63
  /* ── Tailwind CSS ─────────────────────────────────────── */
52
64
  '@tailwindcss/cli': '4.3.3',
@@ -85,6 +97,7 @@ export const versions = {
85
97
  prettier: '3.9.9',
86
98
  /* ── Svelte ───────────────────────────────────────────── */
87
99
  'prettier-plugin-svelte': '4.1.1',
100
+ prisma: '7.10.0',
88
101
  react: '19.3.0',
89
102
  'react-dom': '19.3.0',
90
103
  'react-refresh': '0.19.0',
package/package.json CHANGED
@@ -30,6 +30,7 @@
30
30
  "globals": "17.12.0",
31
31
  "prettier": "3.9.9",
32
32
  "prettier-plugin-svelte": "4.1.1",
33
+ "prisma": "7.10.0",
33
34
  "svelte": "5.57.1",
34
35
  "tailwindcss": "4.3.3",
35
36
  "typescript-eslint": "8.70.1",
@@ -63,5 +64,5 @@
63
64
  "typecheck": "bun run tsc --noEmit"
64
65
  },
65
66
  "type": "module",
66
- "version": "0.19.0"
67
+ "version": "0.20.0"
67
68
  }