Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
44 commits
Select commit Hold shift + click to select a range
112edf1
correcting broken validate-compat.ts
jrs239 Oct 27, 2025
a38bd18
correcting compat.json
jrs239 Oct 27, 2025
87c4421
deleted 2 files, removed script from package.json
jrs239 Oct 27, 2025
f27e90b
tests: replace compat validator with bun:test suite using src/data.ts
jrs239 Oct 28, 2025
cc8ffa0
set up modular test structure for frontend backend db and auth, clean…
jrs239 Oct 28, 2025
59bf0b0
Replace the circular test with table-driven explicit cases
jrs239 Oct 28, 2025
d262a2c
fix: make db tests better and fix eslint errors
jrs239 Oct 28, 2025
ec14a8e
refactor: extract shared host-engine validation logic
jrs239 Oct 28, 2025
88542a7
fixed ESlint error: Explicit return types are disallowed; rely on Ty…
jrs239 Oct 28, 2025
9fc2984
harness task 2 files
santimuri08 Oct 28, 2025
ea0449a
Delete tests/harness/checks.ts
santimuri08 Oct 28, 2025
f630c4b
Delete tests/harness/constants.ts
santimuri08 Oct 28, 2025
1f4942b
Delete tests/harness/exec.ts
santimuri08 Oct 28, 2025
77d9c39
Refactor run-harness.ts for improved structure
santimuri08 Oct 28, 2025
07340b1
Update ORM from Prisma to Drizzle
santimuri08 Oct 28, 2025
8b22369
Refactor logging functions in run-harness.ts
santimuri08 Oct 28, 2025
abc394c
Database Host Scaffolding Tests files
santimuri08 Oct 29, 2025
624d6e6
Merge pull request #2 from absolutejs/compat-matrix
jrs239 Oct 29, 2025
bceecec
Merge pull request #3 from absolutejs/harness-test
jrs239 Oct 29, 2025
0551be1
cleaned eslint errors
jrs239 Oct 29, 2025
8649a7c
fixed syntax errors
jrs239 Nov 2, 2025
564af5b
removed /test-scaffold/
jrs239 Nov 2, 2025
0b3abe4
Add support for MSSQL in Prisma schema generator
santimuri08 Nov 11, 2025
2660054
Add Prisma support to scaffoldDatabase
santimuri08 Nov 11, 2025
8e62dc0
Add Prisma dependencies and scripts to package.json
santimuri08 Nov 11, 2025
922b055
Fix missing newline at end of scaffoldDatabase.ts
santimuri08 Nov 12, 2025
db2fb86
Update isPrismaDialect type guard to use AvailablePrismaDialect
santimuri08 Nov 12, 2025
597ff4f
Add missing newline at the end of generatePackageJson.ts
santimuri08 Nov 12, 2025
2b8dbb8
Add generatePrismaClient function
santimuri08 Nov 12, 2025
6ba1c72
Add support for Prisma dialects in generateDBBlock
santimuri08 Nov 12, 2025
b79480e
Add Prisma imports handling in generateImportsBlock
santimuri08 Nov 12, 2025
b658506
Enhance ORM key determination logic
santimuri08 Nov 12, 2025
b69a71e
Add Prisma query operations for various databases
santimuri08 Nov 12, 2025
955e5a6
Minor Improvments + Schema Generation Fixes
eugenegraves Nov 12, 2025
3644f96
feat: add Prisma lifecycle cleanup and db aliasing
jrs239 Nov 13, 2025
66aa1ef
cleaned lint errors
jrs239 Nov 13, 2025
6ba9bc6
Prisma Complete
eugenegraves Nov 18, 2025
518804b
Removed Test Folder
eugenegraves Nov 18, 2025
4c90a1f
Merged from Main
eugenegraves Feb 9, 2026
cacdb53
Additional Prisma Context Additions
eugenegraves Feb 9, 2026
f28a527
Root User Docker Approach
eugenegraves Feb 9, 2026
f7b97d3
Merge from Main
eugenegraves Feb 12, 2026
974e691
Run Prisma in Docker Env + Match Root Credentials
eugenegraves Feb 12, 2026
fdd882d
Merge from Main
eugenegraves Feb 26, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion eslint.config.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,10 @@ export default defineConfig([
'scripts/**',
'**/*/htmx.*.min.js',
'src/templates/types/**',
'src/templates/svelte/**'
'src/templates/svelte/**',
'test-scaffold/**/*.json',
'test-scaffold/**/*.config.*',
'test-scaffold/.prettierrc.*'
]
},

Expand Down
26 changes: 18 additions & 8 deletions src/commands/formatProject.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import { exit } from 'process';
import { exit } from 'node:process';
import { spinner } from '@clack/prompts';
import { $ } from 'bun';
import { green, red } from 'picocolors';
import { PackageManager } from '../types';
import { formatCommands, formatNoInstallCommands } from '../utils/commandMaps';
Expand All @@ -17,15 +16,26 @@ export const formatProject = async ({
installDependenciesNow
}: FormatProjectProps) => {
const spin = spinner();
const fmt = installDependenciesNow
? formatCommands[packageManager]
: formatNoInstallCommands[packageManager];
const parts = fmt.split(/\s+/);
const bin = parts[0];
if (bin === undefined) throw new Error('Empty format command');
const args = parts.slice(1);

try {
const fmt = installDependenciesNow
? formatCommands[packageManager]
: formatNoInstallCommands[packageManager];

spin.start('Formatting files…');
const [bin, ...args] = fmt.split(' ');
await $`${bin} ${args}`.cwd(projectName).quiet();
const proc = Bun.spawnSync([bin, ...args], {
cwd: projectName,
stderr: 'pipe',
stdout: 'ignore'
});
if (!proc.success) {
const errMsg =
proc.stderr?.toString().trim() ?? `Exit code ${proc.exitCode}`;
throw new Error(errMsg);
}
spin.stop(green('Files formatted'));
} catch (err) {
spin.cancel(red('Failed to format files'));
Expand Down
32 changes: 26 additions & 6 deletions src/commands/initializeGit.ts
Original file line number Diff line number Diff line change
@@ -1,18 +1,38 @@
import { spinner } from '@clack/prompts';
import { $ } from 'bun';
import { green, red } from 'picocolors';
import { abort } from '../utils/abort';
import { checkGitInstalled } from '../utils/checkGitInstalled';

const initializeRepository = async (
projectName: string,
spin: ReturnType<typeof spinner>
) => {
spin.stop();
spin.start('Initializing git repository…');

await $`git init -b main`.cwd(projectName).quiet();
await $`git add -A`.cwd(projectName).quiet();
await $`git commit -m "Initial commit"`.cwd(projectName).quiet();

spin.stop(green('Git repo initialized'));
};

export const initializeGit = async (projectName: string) => {
const spin = spinner();

try {
spin.start('Initializing git repository…');
spin.start('Checking git availability...');
const isGitInstalled = await checkGitInstalled();

await $`git init -b main`.cwd(projectName).quiet();
await $`git add -A`.cwd(projectName).quiet();
await $`git commit -m "Initial commit"`.cwd(projectName).quiet();
if (!isGitInstalled) {
spin.stop(
red('Git is not installed. Please install git before proceeding.')
);
abort();
}

spin.stop(green('Git repo initialized'));
try {
await initializeRepository(projectName, spin);
} catch (err) {
spin.cancel(red('Failed to initialize git'));
throw err;
Expand Down
17 changes: 14 additions & 3 deletions src/commands/installDependencies.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import { exit } from 'process';
import { spinner } from '@clack/prompts';
import { $ } from 'bun';
import { green, red } from 'picocolors';
import { PackageManager } from '../types';
import { installCommands } from '../utils/commandMaps';
Expand All @@ -11,11 +10,23 @@ export const installDependencies = async (
) => {
const spin = spinner();
const cmd = installCommands[packageManager];
const parts = cmd.split(/\s+/);
const bin = parts[0];
if (bin === undefined) throw new Error('Empty install command');
const args = parts.slice(1);

try {
spin.start('Installing dependencies');
const [bin, ...args] = cmd.split(' ');
await $`${bin} ${args}`.cwd(projectName).quiet();
const proc = Bun.spawnSync([bin, ...args], {
cwd: projectName,
stderr: 'pipe',
stdout: 'ignore'
});
if (!proc.success) {
const errMsg =
proc.stderr?.toString().trim() ?? `Exit code ${proc.exitCode}`;
throw new Error(errMsg);
}
spin.stop(green('Dependencies installed'));
} catch (err) {
spin.cancel(red('Installation failed'));
Expand Down
18 changes: 18 additions & 0 deletions src/data.ts
Original file line number Diff line number Diff line change
Expand Up @@ -187,6 +187,24 @@ export const eslintReactDependencies: AvailableDependency[] = [
value: 'zod-validation-error'
}
];

export const prismaRuntimeDependencies: AvailableDependency[] = [
{
latestVersion: '6.2.0',
value: '@prisma/client'
}
];

export const prismaDevDependencies: AvailableDependency[] = [
{
latestVersion: '6.2.0',
value: 'prisma'
},
{
latestVersion: '1.2.1',
value: '@prisma/extension-accelerate'
}
];
export const frontendLabels: FrontendLabels = {
html: 'HTML',
htmx: 'HTMX',
Expand Down
24 changes: 16 additions & 8 deletions src/generators/configurations/generateEnv.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,33 +4,41 @@ import { CreateConfiguration } from '../../types';

type GenerateEnvProps = Pick<
CreateConfiguration,
'databaseEngine' | 'databaseHost' | 'projectName'
'databaseEngine' | 'databaseHost' | 'projectName' | 'databaseDirectory'
> & {
envVariables?: string[];
};

const databaseURLS = {
cockroachdb: 'postgresql://root@localhost:26257/database',
gel: 'gel://admin@localhost:5656/main?tls_security=insecure',
mariadb: 'mariadb://user:userpassword@localhost:3306/database',
mongodb: 'mongodb://user:password@localhost:27017/database',
mssql: 'Server=localhost,1433;Database=master;User Id=sa;Password=SApassword1;Encrypt=true;TrustServerCertificate=true',
mysql: 'mysql://user:userpassword@localhost:3306/database',
postgresql: 'postgresql://user:password@localhost:5432/database',
singlestore: 'mysql://root:password@localhost:3306/database'
mariadb: 'mysql://root:rootpassword@localhost:3306/database',
mongodb:
'mongodb://root:rootpassword@127.0.0.1:27017/database?authSource=admin&directConnection=true',
mssql:
'Server=localhost,1433;Database=master;User Id=sa;Password=SApassword1;Encrypt=true;TrustServerCertificate=true',
mysql: 'mysql://root:rootpassword@localhost:3306/database',
postgresql: 'postgresql://postgres:rootpassword@localhost:5432/database',
singlestore: 'mysql://root:rootpassword@localhost:3306/database'
} as const;

export const generateEnv = ({
databaseEngine,
databaseHost,
databaseDirectory = 'db',
envVariables = [],
projectName
}: GenerateEnvProps) => {
const vars = [...envVariables];

if (
databaseEngine !== 'sqlite' &&
databaseEngine === 'sqlite' &&
(databaseHost === 'none' || databaseHost === undefined)
) {
vars.push(`DATABASE_URL=file:./${databaseDirectory}/database.sqlite`);
} else if (
databaseEngine !== 'none' &&
databaseEngine !== 'sqlite' &&
databaseEngine !== undefined &&
(databaseHost === 'none' || databaseHost === undefined)
) {
Expand Down
106 changes: 77 additions & 29 deletions src/generators/configurations/generatePackageJson.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,13 @@ import {
defaultDependencies,
defaultPlugins,
eslintAndPrettierDependencies,
eslintReactDependencies
eslintReactDependencies,
prismaDevDependencies,
prismaRuntimeDependencies
} from '../../data';
import type { CreateConfiguration, PackageJson } from '../../types';
import { getPackageVersions } from '../../utils/getPackageVersion';
import { toDockerProjectName } from '../../utils/toDockerProjectName';
import { versions } from '../../versions';
import { computeFlags } from '../project/computeFlags';

Expand All @@ -25,6 +28,7 @@ type CreatePackageJsonProps = Pick<
| 'orm'
| 'frontendDirectories'
| 'codeQualityTool'
| 'databaseDirectory'
> & {
projectName: string;
latest: boolean;
Expand All @@ -33,13 +37,13 @@ type CreatePackageJsonProps = Pick<
const dbClientCommands = {
cockroachdb: 'cockroach sql --insecure --database=database',
gel: 'gel -H localhost -P 5656 -u admin --tls-security insecure -b main',
mariadb: 'MYSQL_PWD=userpassword mariadb -h127.0.0.1 -u user database',
mariadb: 'MYSQL_PWD=rootpassword mariadb -h127.0.0.1 -u root database',
mongodb:
'mongosh -u user -p password --authenticationDatabase admin database',
'mongosh -u root -p rootpassword --authenticationDatabase admin database',
mssql: '/opt/mssql-tools18/bin/sqlcmd -C -S localhost -U sa -P SApassword1',
mysql: 'MYSQL_PWD=userpassword mysql -h127.0.0.1 -u user database',
postgresql: 'psql -h localhost -U user -d database',
singlestore: 'singlestore -u root -ppassword -D database'
mysql: 'MYSQL_PWD=rootpassword mysql -h127.0.0.1 -u root database',
postgresql: 'psql -h localhost -U postgres -d database',
singlestore: 'singlestore -u root -prootpassword -D database'
} as const;

export const createPackageJson = async ({
Expand All @@ -52,7 +56,8 @@ export const createPackageJson = async ({
useTailwind,
latest,
frontendDirectories,
codeQualityTool
codeQualityTool,
databaseDirectory
}: CreatePackageJsonProps) => {
const flags = computeFlags(frontendDirectories);
const isLocal = !databaseHost || databaseHost === 'none';
Expand Down Expand Up @@ -248,33 +253,58 @@ export const createPackageJson = async ({
versions['elysia-scoped-state']
);
}

if (orm === 'drizzle') {
dependencies['drizzle-orm'] = resolveVersion(
'drizzle-orm',
versions['drizzle-orm']
);
devDependencies['drizzle-kit'] = resolveVersion(
'drizzle-kit',
versions['drizzle-kit']
);
}
const usesAccelerate =
orm === 'prisma' &&
(databaseHost === 'neon' || databaseHost === 'planetscale');

switch (databaseHost) {
case 'neon':
dependencies['@neondatabase/serverless'] = resolveVersion(
'@neondatabase/serverless',
versions['@neondatabase/serverless']
);
break;
case 'planetscale':
dependencies['@planetscale/database'] = resolveVersion(
'@planetscale/database',
versions['@planetscale/database']
if (orm === 'prisma') {
prismaRuntimeDependencies.forEach((dep) => {
dependencies[dep.value] = resolveVersion(
dep.value,
dep.latestVersion
);
break;
case 'turso':
dependencies['@libsql/client'] = resolveVersion(
'@libsql/client',
versions['@libsql/client']
});

prismaDevDependencies.forEach((dep) => {
if (dep.value === '@prisma/extension-accelerate' && !usesAccelerate)
return;
devDependencies[dep.value] = resolveVersion(
dep.value,
dep.latestVersion
);
break;
});
}
Comment on lines +266 to +286
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

🧩 Analysis chain

🌐 Web query:

@prisma/extension-accelerate runtime dependency vs dev dependency documentation

💡 Result:

@prisma/extension-accelerate should be a runtime dependency (put it in dependencies), because it’s imported and used by your application code at runtime (e.g., import { withAccelerate } from "@prisma/extension-accelerate";). Prisma’s guides install it without --save-dev, while installing the Prisma CLI (prisma) with --save-dev. (prismagraphql.com)

Citations:


🏁 Script executed:

# Find and inspect src/data.ts to check where `@prisma/extension-accelerate` is defined
find . -name "data.ts" -type f | head -20

Repository: absolutejs/create-absolutejs

Length of output: 85


🏁 Script executed:

# Search for `@prisma/extension-accelerate` in the codebase
rg "@prisma/extension-accelerate" -n

Repository: absolutejs/create-absolutejs

Length of output: 383


🏁 Script executed:

# Check src/data.ts around line 186 to see which dependency array it's in
sed -n '170,200p' src/data.ts

Repository: absolutejs/create-absolutejs

Length of output: 645


🏁 Script executed:

# Check the import in generatePrismaClient.ts to see how it's used
sed -n '15,25p' src/generators/configurations/generatePrismaClient.ts

Repository: absolutejs/create-absolutejs

Length of output: 425


@prisma/extension-accelerate must be a runtime dependency, not a dev dependency.

According to Prisma's official documentation, @prisma/extension-accelerate is imported and used at runtime in the generated Prisma client code (see src/generators/configurations/generatePrismaClient.ts line 18). Placing it in devDependencies (currently in src/data.ts line 186) means it will not be installed in production environments when using npm install --production or equivalent flags, causing runtime failures when Accelerate is enabled.

Move @prisma/extension-accelerate from prismaDevDependencies to prismaRuntimeDependencies in src/data.ts.

🤖 Prompt for AI Agents
In `@src/generators/configurations/generatePackageJson.ts` around lines 208 - 228,
The `@prisma/extension-accelerate` package is currently being added from
prismaDevDependencies but is required at runtime by the generated Prisma client;
move the entry for "@prisma/extension-accelerate" from prismaDevDependencies
into prismaRuntimeDependencies in the data source so that when the code checks
usesAccelerate and populates dependencies (the block using
prismaRuntimeDependencies, prismaDevDependencies, resolveVersion and the
usesAccelerate flag) the package is added to dependencies rather than
devDependencies; update the arrays accordingly and ensure the existing
conditional that skips adding the dev dependency for accelerate (the check for
dep.value === '@prisma/extension-accelerate' && !usesAccelerate) is removed or
adjusted since accelerate should now be handled as a runtime dependency.

if (orm === 'drizzle') {
switch (databaseHost) {
case 'neon':
dependencies['@neondatabase/serverless'] = resolveVersion(
'@neondatabase/serverless',
versions['@neondatabase/serverless']
);
break;
case 'planetscale':
dependencies['@planetscale/database'] = resolveVersion(
'@planetscale/database',
versions['@planetscale/database']
);
break;
case 'turso':
dependencies['@libsql/client'] = resolveVersion(
'@libsql/client',
versions['@libsql/client']
);
break;
}
}

if (latest) s.stop(green('Package versions resolved'));
Expand All @@ -296,7 +326,8 @@ export const createPackageJson = async ({
databaseEngine !== 'sqlite'
) {
const clientCmd = dbClientCommands[databaseEngine];
const dockerPrefix = `docker compose -p ${databaseEngine} -f db/docker-compose.db.yml`;
const composeFile = `${databaseDirectory ?? 'db'}/docker-compose.db.yml`;
const dockerPrefix = `docker compose -p ${toDockerProjectName(projectName)} -f ${composeFile}`;

scripts['db:up'] = `${dockerPrefix} up -d --wait db`;
scripts['db:down'] = `${dockerPrefix} down`;
Expand Down Expand Up @@ -347,16 +378,33 @@ export const createPackageJson = async ({
);
}

if (isLocalDb && databaseEngine === 'sqlite') {
scripts['db:sqlite'] = 'sqlite3 db/database.sqlite';
scripts['db:init'] = 'sqlite3 db/database.sqlite < db/init.sql';
if (isLocal && databaseEngine === 'sqlite') {
const dbDir = databaseDirectory ?? 'db';
scripts['db:sqlite'] = `sqlite3 ${dbDir}/database.sqlite`;
scripts['db:init'] =
`sqlite3 ${dbDir}/database.sqlite < ${dbDir}/init.sql`;
}
Comment on lines 381 to 386
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Search for both init.sql and schema.sql references in TypeScript files
rg -n "init\.sql|schema\.sql" --type=ts -C2

Repository: absolutejs/create-absolutejs

Length of output: 1132


🏁 Script executed:

#!/bin/bash
# Search for all references to init.sql in the entire codebase
rg "init\.sql" -n

Repository: absolutejs/create-absolutejs

Length of output: 187


Change db:init script to reference schema.sql instead of init.sql.

The generated db:init script references init.sql, but src/generators/db/scaffoldDatabase.ts line 68 writes the schema file as schema.sql. This causes the db:init script to fail at runtime because the referenced file doesn't exist.

Proposed fix
 	scripts['db:init'] =
-		`sqlite3 ${dbDir}/database.sqlite < ${dbDir}/init.sql`;
+		`sqlite3 ${dbDir}/database.sqlite < ${dbDir}/schema.sql`;
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
if (isLocal && databaseEngine === 'sqlite') {
scripts['db:sqlite'] = 'sqlite3 db/database.sqlite';
scripts['db:init'] = 'sqlite3 db/database.sqlite < db/init.sql';
const dbDir = databaseDirectory ?? 'db';
scripts['db:sqlite'] = `sqlite3 ${dbDir}/database.sqlite`;
scripts['db:init'] =
`sqlite3 ${dbDir}/database.sqlite < ${dbDir}/init.sql`;
}
if (isLocal && databaseEngine === 'sqlite') {
const dbDir = databaseDirectory ?? 'db';
scripts['db:sqlite'] = `sqlite3 ${dbDir}/database.sqlite`;
scripts['db:init'] =
`sqlite3 ${dbDir}/database.sqlite < ${dbDir}/schema.sql`;
}
🤖 Prompt for AI Agents
In `@src/generators/configurations/generatePackageJson.ts` around lines 296 - 301,
The generated package.json script scripts['db:init'] references init.sql which
doesn't exist; update the scripts['db:init'] assignment in generatePackageJson
(the block using isLocal, databaseEngine, databaseDirectory and dbDir) to
reference schema.sql instead of init.sql so it matches the file written by your
DB scaffold (schema.sql).


if (orm === 'drizzle') {
scripts['db:studio'] = 'drizzle-kit studio';
scripts['db:push'] = 'drizzle-kit push';
}

if (orm === 'prisma') {
const schemaPath = databaseDirectory
? `${databaseDirectory}/schema.prisma`
: 'db/schema.prisma';
scripts['postinstall'] = `prisma generate --schema ${schemaPath}`;
scripts['db:generate'] = `prisma generate --schema ${schemaPath}`;
scripts['db:push'] = `prisma db push --schema ${schemaPath}`;
scripts['db:studio'] = `prisma studio --schema ${schemaPath}`;
scripts['db:migrate'] = `prisma migrate dev --schema ${schemaPath}`;
scripts['db:migrate:deploy'] =
`prisma migrate deploy --schema ${schemaPath}`;
scripts['db:migrate:reset'] =
`prisma migrate reset --schema ${schemaPath}`;
}

const packageJson: PackageJson = {
dependencies,
devDependencies,
Expand Down
Loading