@effectify/prisma 0.1.2 → 1.0.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.
- package/dist/src/cli.d.ts +1 -1
- package/dist/src/cli.js +9 -9
- package/dist/src/commands/init.d.ts +1 -1
- package/dist/src/commands/init.js +0 -2
- package/dist/src/commands/prisma.d.ts +5 -0
- package/dist/src/commands/prisma.js +35 -0
- package/dist/src/generators/sql-schema-generator.d.ts +9 -0
- package/dist/src/generators/sql-schema-generator.js +50 -58
- package/dist/src/services/generator-context.d.ts +6 -0
- package/dist/src/services/generator-context.js +3 -0
- package/dist/src/services/generator-service.d.ts +14 -0
- package/dist/src/services/generator-service.js +121 -0
- package/dist/src/services/render-service.d.ts +10 -0
- package/dist/src/services/render-service.js +23 -0
- package/{src → dist/src}/templates/index-default.eta +1 -1
- package/dist/src/templates/model.eta +8 -0
- package/{src → dist/src}/templates/prisma-repository.eta +7 -7
- package/package.json +15 -11
- package/dist/src/commands/generate-effect.d.ts +0 -2
- package/dist/src/commands/generate-effect.js +0 -73
- package/dist/src/commands/generate-sql-schema.d.ts +0 -2
- package/dist/src/commands/generate-sql-schema.js +0 -72
- package/dist/src/effect-prisma.d.ts +0 -2
- package/dist/src/effect-prisma.js +0 -1771
- package/dist/src/generators/prisma-effect-generator.d.ts +0 -1
- package/dist/src/generators/prisma-effect-generator.js +0 -446
- package/prisma/dev.db +0 -0
- package/prisma/generated/client.d.ts +0 -1
- package/prisma/generated/client.js +0 -5
- package/prisma/generated/default.d.ts +0 -1
- package/prisma/generated/default.js +0 -5
- package/prisma/generated/edge.d.ts +0 -1
- package/prisma/generated/edge.js +0 -141
- package/prisma/generated/effect/index.ts +0 -392
- package/prisma/generated/effect/models/Todo.ts +0 -6
- package/prisma/generated/effect/prisma-repository.ts +0 -954
- package/prisma/generated/effect/prisma-schema.ts +0 -94
- package/prisma/generated/effect/schemas/enums.ts +0 -6
- package/prisma/generated/effect/schemas/index.ts +0 -2
- package/prisma/generated/effect/schemas/types.ts +0 -40
- package/prisma/generated/index-browser.js +0 -172
- package/prisma/generated/index.d.ts +0 -2376
- package/prisma/generated/index.js +0 -141
- package/prisma/generated/package.json +0 -144
- package/prisma/generated/query_compiler_bg.js +0 -2
- package/prisma/generated/query_compiler_bg.wasm +0 -0
- package/prisma/generated/query_compiler_bg.wasm-base64.js +0 -2
- package/prisma/generated/runtime/client.d.ts +0 -3180
- package/prisma/generated/runtime/client.js +0 -86
- package/prisma/generated/runtime/index-browser.d.ts +0 -87
- package/prisma/generated/runtime/index-browser.js +0 -6
- package/prisma/generated/runtime/wasm-compiler-edge.js +0 -76
- package/prisma/generated/schema.prisma +0 -31
- package/prisma/generated/wasm-edge-light-loader.mjs +0 -5
- package/prisma/generated/wasm-worker-loader.mjs +0 -5
- package/prisma/migrations/20250721164420_init/migration.sql +0 -9
- package/prisma/migrations/20250721191716_dumb/migration.sql +0 -49
- package/prisma/migrations/migration_lock.toml +0 -3
- package/prisma/schema.prisma +0 -31
- package/prisma.config.ts +0 -8
- package/project.json +0 -48
- package/scripts/cleanup-tests.ts +0 -26
- package/scripts/generate-test-files.ts +0 -93
- package/setup-tests.ts +0 -10
- package/src/cli.ts +0 -22
- package/src/commands/init.ts +0 -153
- package/src/commands/prisma.ts +0 -50
- package/src/generators/sql-schema-generator.ts +0 -66
- package/src/services/generator-context.ts +0 -4
- package/src/services/generator-service.ts +0 -178
- package/src/services/render-service.ts +0 -32
- package/src/templates/model.eta +0 -6
- package/test/prisma-model.test.ts +0 -340
- package/test/utils.ts +0 -10
- package/tsconfig.json +0 -20
- package/tsconfig.lib.json +0 -24
- package/tsconfig.spec.json +0 -15
- package/vitest.config.ts +0 -24
- /package/{src → dist/src}/templates/index-custom-error.eta +0 -0
- /package/{src → dist/src}/templates/prisma-raw-sql.eta +0 -0
- /package/{src → dist/src}/templates/prisma-schema.eta +0 -0
|
@@ -1,49 +0,0 @@
|
|
|
1
|
-
-- CreateTable
|
|
2
|
-
CREATE TABLE "users" (
|
|
3
|
-
"id" TEXT NOT NULL PRIMARY KEY,
|
|
4
|
-
"email" TEXT NOT NULL,
|
|
5
|
-
"name" TEXT,
|
|
6
|
-
"createdAt" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
7
|
-
"updatedAt" DATETIME NOT NULL
|
|
8
|
-
);
|
|
9
|
-
|
|
10
|
-
-- CreateTable
|
|
11
|
-
CREATE TABLE "tags" (
|
|
12
|
-
"id" TEXT NOT NULL PRIMARY KEY,
|
|
13
|
-
"name" TEXT NOT NULL
|
|
14
|
-
);
|
|
15
|
-
|
|
16
|
-
-- CreateTable
|
|
17
|
-
CREATE TABLE "todo_tags" (
|
|
18
|
-
"todoId" TEXT NOT NULL,
|
|
19
|
-
"tagId" TEXT NOT NULL,
|
|
20
|
-
|
|
21
|
-
PRIMARY KEY ("todoId", "tagId"),
|
|
22
|
-
CONSTRAINT "todo_tags_todoId_fkey" FOREIGN KEY ("todoId") REFERENCES "todos" ("id") ON DELETE RESTRICT ON UPDATE CASCADE,
|
|
23
|
-
CONSTRAINT "todo_tags_tagId_fkey" FOREIGN KEY ("tagId") REFERENCES "tags" ("id") ON DELETE RESTRICT ON UPDATE CASCADE
|
|
24
|
-
);
|
|
25
|
-
|
|
26
|
-
-- RedefineTables
|
|
27
|
-
PRAGMA defer_foreign_keys=ON;
|
|
28
|
-
PRAGMA foreign_keys=OFF;
|
|
29
|
-
CREATE TABLE "new_todos" (
|
|
30
|
-
"id" TEXT NOT NULL PRIMARY KEY,
|
|
31
|
-
"title" TEXT NOT NULL,
|
|
32
|
-
"description" TEXT,
|
|
33
|
-
"completed" BOOLEAN NOT NULL DEFAULT false,
|
|
34
|
-
"createdAt" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
35
|
-
"updatedAt" DATETIME NOT NULL,
|
|
36
|
-
"userId" TEXT,
|
|
37
|
-
CONSTRAINT "todos_userId_fkey" FOREIGN KEY ("userId") REFERENCES "users" ("id") ON DELETE SET NULL ON UPDATE CASCADE
|
|
38
|
-
);
|
|
39
|
-
INSERT INTO "new_todos" ("completed", "createdAt", "description", "id", "title", "updatedAt") SELECT "completed", "createdAt", "description", "id", "title", "updatedAt" FROM "todos";
|
|
40
|
-
DROP TABLE "todos";
|
|
41
|
-
ALTER TABLE "new_todos" RENAME TO "todos";
|
|
42
|
-
PRAGMA foreign_keys=ON;
|
|
43
|
-
PRAGMA defer_foreign_keys=OFF;
|
|
44
|
-
|
|
45
|
-
-- CreateIndex
|
|
46
|
-
CREATE UNIQUE INDEX "users_email_key" ON "users"("email");
|
|
47
|
-
|
|
48
|
-
-- CreateIndex
|
|
49
|
-
CREATE UNIQUE INDEX "tags_name_key" ON "tags"("name");
|
package/prisma/schema.prisma
DELETED
|
@@ -1,31 +0,0 @@
|
|
|
1
|
-
// This is your Prisma schema file,
|
|
2
|
-
// learn more about it in the docs: https://pris.ly/d/prisma-schema
|
|
3
|
-
|
|
4
|
-
generator client {
|
|
5
|
-
provider = "prisma-client-js"
|
|
6
|
-
output = "./generated"
|
|
7
|
-
}
|
|
8
|
-
|
|
9
|
-
generator effect_schemas {
|
|
10
|
-
provider = "prisma-effect-kysely"
|
|
11
|
-
output = "./generated/effect/schemas"
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
generator effect {
|
|
15
|
-
provider = "tsx ./src/cli.ts"
|
|
16
|
-
output = "./generated/effect"
|
|
17
|
-
clientImportPath = "@prisma/client"
|
|
18
|
-
importFileExtension = "js"
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
datasource db {
|
|
22
|
-
provider = "sqlite"
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
model Todo {
|
|
26
|
-
id Int @id @default(autoincrement())
|
|
27
|
-
title String
|
|
28
|
-
content String?
|
|
29
|
-
published Boolean @default(false)
|
|
30
|
-
authorId Int
|
|
31
|
-
}
|
package/prisma.config.ts
DELETED
package/project.json
DELETED
|
@@ -1,48 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "@effectify/prisma",
|
|
3
|
-
"$schema": "../../../node_modules/nx/schemas/project-schema.json",
|
|
4
|
-
"sourceRoot": "packages/prisma/src",
|
|
5
|
-
"projectType": "library",
|
|
6
|
-
"targets": {
|
|
7
|
-
"build": {
|
|
8
|
-
"executor": "@nx/js:tsc",
|
|
9
|
-
"outputs": ["{options.outputPath}"],
|
|
10
|
-
"defaultConfiguration": "production",
|
|
11
|
-
"options": {
|
|
12
|
-
"outputPath": "packages/prisma/dist",
|
|
13
|
-
"main": "packages/prisma/src/cli.tsx",
|
|
14
|
-
"tsConfig": "packages/prisma/tsconfig.lib.json",
|
|
15
|
-
"format": ["esm"],
|
|
16
|
-
"generatePackageJson": false,
|
|
17
|
-
"updateBuildableProjectDepsInPackageJson": false,
|
|
18
|
-
"additionalEntryPoints": []
|
|
19
|
-
},
|
|
20
|
-
"configurations": {
|
|
21
|
-
"development": {},
|
|
22
|
-
"production": {}
|
|
23
|
-
}
|
|
24
|
-
},
|
|
25
|
-
"prisma:generate": {
|
|
26
|
-
"executor": "nx:run-commands",
|
|
27
|
-
"options": {
|
|
28
|
-
"command": "pnpm dlx prisma generate",
|
|
29
|
-
"cwd": "packages/prisma"
|
|
30
|
-
}
|
|
31
|
-
},
|
|
32
|
-
"dev": {
|
|
33
|
-
"executor": "nx:run-commands",
|
|
34
|
-
"options": {
|
|
35
|
-
"command": "tsx src/messaround.ts",
|
|
36
|
-
"cwd": "packages/prisma"
|
|
37
|
-
}
|
|
38
|
-
},
|
|
39
|
-
"cli": {
|
|
40
|
-
"executor": "nx:run-commands",
|
|
41
|
-
"options": {
|
|
42
|
-
"command": "pnpm dlx tsx src/cli.tsx",
|
|
43
|
-
"cwd": "packages/prisma"
|
|
44
|
-
}
|
|
45
|
-
}
|
|
46
|
-
},
|
|
47
|
-
"tags": ["node", "react", "prisma"]
|
|
48
|
-
}
|
package/scripts/cleanup-tests.ts
DELETED
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
import { existsSync } from 'node:fs'
|
|
2
|
-
import { readdir, rmdir } from 'node:fs/promises'
|
|
3
|
-
import { resolve } from 'node:path'
|
|
4
|
-
|
|
5
|
-
async function cleanupTests() {
|
|
6
|
-
const testsDir = resolve('src/generated/tests')
|
|
7
|
-
const testDbsDir = resolve('src/generated/tests-dbs')
|
|
8
|
-
|
|
9
|
-
// Clean up test files
|
|
10
|
-
if (existsSync(testsDir)) {
|
|
11
|
-
await rmdir(testsDir, { recursive: true })
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
// Clean up test databases
|
|
15
|
-
if (existsSync(testDbsDir)) {
|
|
16
|
-
const files = await readdir(testDbsDir)
|
|
17
|
-
if (files.length > 0) {
|
|
18
|
-
await rmdir(testDbsDir, { recursive: true })
|
|
19
|
-
}
|
|
20
|
-
}
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
cleanupTests().catch((error) => {
|
|
24
|
-
console.error('❌ Cleanup failed:', error)
|
|
25
|
-
process.exit(1)
|
|
26
|
-
})
|
|
@@ -1,93 +0,0 @@
|
|
|
1
|
-
import { existsSync } from 'node:fs'
|
|
2
|
-
import { mkdir, writeFile } from 'node:fs/promises'
|
|
3
|
-
import { resolve } from 'node:path'
|
|
4
|
-
|
|
5
|
-
// Configuration
|
|
6
|
-
const testFileCount = Number.parseInt(process.argv[2], 10) || 5
|
|
7
|
-
const testsPerFileCount = Number.parseInt(process.argv[3], 10) || 3
|
|
8
|
-
|
|
9
|
-
const generateTestFile = (fileIndex: number, testsCount: number): string => {
|
|
10
|
-
const testCases = Array.from({ length: testsCount }, (_, testIndex) => {
|
|
11
|
-
const testName = `should handle test case ${testIndex + 1}`
|
|
12
|
-
const todoTitle = `Generated Todo ${fileIndex}-${testIndex + 1}`
|
|
13
|
-
const todoDescription = `Description for test ${fileIndex}-${testIndex + 1}`
|
|
14
|
-
|
|
15
|
-
return `
|
|
16
|
-
const test${testIndex + 1}Effect = Effect.gen(function* () {
|
|
17
|
-
const prisma = yield* PrismaService
|
|
18
|
-
const user = yield* prisma.user.create({
|
|
19
|
-
data: {
|
|
20
|
-
email: "user${fileIndex}-${testIndex + 1}@test.com"
|
|
21
|
-
}
|
|
22
|
-
})
|
|
23
|
-
|
|
24
|
-
const created = yield* createTodo({
|
|
25
|
-
title: "${todoTitle}",
|
|
26
|
-
completed: ${Math.random() > 0.5},
|
|
27
|
-
description: "${todoDescription}",
|
|
28
|
-
userId: user.id
|
|
29
|
-
})
|
|
30
|
-
|
|
31
|
-
const allTodos = yield* getAllTodosForUser(user)
|
|
32
|
-
|
|
33
|
-
expect(allTodos).toHaveLength(1)
|
|
34
|
-
expect(allTodos[0]?.title).toBe("${todoTitle}")
|
|
35
|
-
expect(allTodos[0]?.userId).toBe(user.id)
|
|
36
|
-
}).pipe(Effect.provide(PrismaService.Default)).pipe(Effect.provide(TestPrismaLayer))
|
|
37
|
-
|
|
38
|
-
it.scoped("${testName}", () => test${testIndex + 1}Effect)`
|
|
39
|
-
}).join('\n\n')
|
|
40
|
-
|
|
41
|
-
return `import { expect, it } from "@effect/vitest"
|
|
42
|
-
import { Effect } from "effect"
|
|
43
|
-
import type { Todo, User } from "../../generated/prisma/index.js"
|
|
44
|
-
import { PrismaService } from "../../generated/effect-prisma/index.js"
|
|
45
|
-
import { TestPrismaLayer } from "../../services/prisma.service.js"
|
|
46
|
-
|
|
47
|
-
const createTodo = (input: Omit<Todo, "id" | "createdAt" | "updatedAt">) =>
|
|
48
|
-
Effect.gen(function* () {
|
|
49
|
-
const prisma = yield* PrismaService
|
|
50
|
-
return yield* prisma.todo.create({
|
|
51
|
-
data: input
|
|
52
|
-
})
|
|
53
|
-
})
|
|
54
|
-
|
|
55
|
-
const getAllTodosForUser = (user: Pick<User, "id">) =>
|
|
56
|
-
Effect.gen(function* () {
|
|
57
|
-
const prisma = yield* PrismaService
|
|
58
|
-
return yield* prisma.todo.findMany({
|
|
59
|
-
where: {
|
|
60
|
-
userId: user.id
|
|
61
|
-
}
|
|
62
|
-
})
|
|
63
|
-
})
|
|
64
|
-
|
|
65
|
-
${testCases}
|
|
66
|
-
`
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
async function generateTestFiles() {
|
|
70
|
-
const testsDir = resolve('src/generated/tests')
|
|
71
|
-
|
|
72
|
-
// Create the tests directory if it doesn't exist
|
|
73
|
-
if (!existsSync(testsDir)) {
|
|
74
|
-
await mkdir(testsDir, { recursive: true })
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
// Generate test files
|
|
78
|
-
const filePromises: Promise<void>[] = []
|
|
79
|
-
for (let i = 1; i <= testFileCount; i++) {
|
|
80
|
-
const fileName = `stress-test-${i.toString().padStart(3, '0')}.test.ts`
|
|
81
|
-
const filePath = resolve(testsDir, fileName)
|
|
82
|
-
const fileContent = generateTestFile(i, testsPerFileCount)
|
|
83
|
-
|
|
84
|
-
filePromises.push(writeFile(filePath, fileContent, 'utf-8'))
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
await Promise.all(filePromises)
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
generateTestFiles().catch((error) => {
|
|
91
|
-
console.error('Failed to generate test files:', error)
|
|
92
|
-
process.exit(1)
|
|
93
|
-
})
|
package/setup-tests.ts
DELETED
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
import path from 'node:path'
|
|
2
|
-
import { fileURLToPath } from 'node:url'
|
|
3
|
-
import * as it from '@effect/vitest'
|
|
4
|
-
|
|
5
|
-
it.addEqualityTesters()
|
|
6
|
-
|
|
7
|
-
if (typeof __dirname === 'undefined') {
|
|
8
|
-
/** biome-ignore lint/suspicious/noExplicitAny: polyfill */
|
|
9
|
-
;(globalThis as any).__dirname = path.dirname(fileURLToPath(import.meta.url))
|
|
10
|
-
}
|
package/src/cli.ts
DELETED
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env -S pnpm dlx tsx
|
|
2
|
-
|
|
3
|
-
import * as Command from '@effect/cli/Command'
|
|
4
|
-
import * as NodeContext from '@effect/platform-node/NodeContext'
|
|
5
|
-
import * as NodeRuntime from '@effect/platform-node/NodeRuntime'
|
|
6
|
-
import * as Effect from 'effect/Effect'
|
|
7
|
-
import * as Layer from 'effect/Layer'
|
|
8
|
-
import { initCommand } from './commands/init.js'
|
|
9
|
-
import { prismaCommand } from './commands/prisma.js'
|
|
10
|
-
import { GeneratorService } from './services/generator-service.js'
|
|
11
|
-
import { RenderService } from './services/render-service.js'
|
|
12
|
-
|
|
13
|
-
const cli = Command.run(prismaCommand.pipe(Command.withSubcommands([initCommand])), {
|
|
14
|
-
name: '@effectify/prisma CLI',
|
|
15
|
-
version: '0.1.0',
|
|
16
|
-
})
|
|
17
|
-
|
|
18
|
-
const GeneratorLayer = GeneratorService.Live.pipe(Layer.provide(RenderService.Live), Layer.provide(NodeContext.layer))
|
|
19
|
-
|
|
20
|
-
const MainLayer = Layer.mergeAll(GeneratorLayer, RenderService.Live, NodeContext.layer)
|
|
21
|
-
|
|
22
|
-
cli(process.argv).pipe(Effect.provide(MainLayer), NodeRuntime.runMain)
|
package/src/commands/init.ts
DELETED
|
@@ -1,153 +0,0 @@
|
|
|
1
|
-
import * as Command from '@effect/cli/Command'
|
|
2
|
-
import * as Options from '@effect/cli/Options'
|
|
3
|
-
import * as FileSystem from '@effect/platform/FileSystem'
|
|
4
|
-
import * as NodeFileSystem from '@effect/platform-node/NodeFileSystem'
|
|
5
|
-
import * as NodePath from '@effect/platform-node/NodePath'
|
|
6
|
-
import * as Console from 'effect/Console'
|
|
7
|
-
import * as Effect from 'effect/Effect'
|
|
8
|
-
import * as Match from 'effect/Match'
|
|
9
|
-
|
|
10
|
-
// Options for the init command
|
|
11
|
-
const outputOption = Options.text('output').pipe(
|
|
12
|
-
Options.withAlias('o'),
|
|
13
|
-
Options.withDescription('Output directory path for generated files'),
|
|
14
|
-
Options.withDefault('src'),
|
|
15
|
-
)
|
|
16
|
-
|
|
17
|
-
// Check if file exists
|
|
18
|
-
const fileExists = (path: string) =>
|
|
19
|
-
Effect.gen(function* () {
|
|
20
|
-
const fs = yield* FileSystem.FileSystem
|
|
21
|
-
return yield* fs.exists(path)
|
|
22
|
-
})
|
|
23
|
-
|
|
24
|
-
// Read file content
|
|
25
|
-
const readFileContent = (path: string) =>
|
|
26
|
-
Effect.gen(function* () {
|
|
27
|
-
const fs = yield* FileSystem.FileSystem
|
|
28
|
-
const content = yield* fs.readFileString(path)
|
|
29
|
-
return content
|
|
30
|
-
})
|
|
31
|
-
|
|
32
|
-
// Write file content
|
|
33
|
-
const writeFileContent = (path: string, content: string) =>
|
|
34
|
-
Effect.gen(function* () {
|
|
35
|
-
const fs = yield* FileSystem.FileSystem
|
|
36
|
-
yield* fs.writeFileString(path, content)
|
|
37
|
-
})
|
|
38
|
-
|
|
39
|
-
// Detect package manager using pattern matching
|
|
40
|
-
const detectPackageManager = () =>
|
|
41
|
-
Effect.gen(function* () {
|
|
42
|
-
const pnpmExists = yield* fileExists('pnpm-lock.yaml')
|
|
43
|
-
const bunExists = yield* fileExists('bun.lockb')
|
|
44
|
-
const npmExists = yield* fileExists('package-lock.json')
|
|
45
|
-
|
|
46
|
-
// Create a tuple to match against
|
|
47
|
-
const lockFiles = [pnpmExists, bunExists, npmExists] as const
|
|
48
|
-
|
|
49
|
-
return Match.value(lockFiles).pipe(
|
|
50
|
-
Match.when([true, false, false], () => 'pnpm' as const),
|
|
51
|
-
Match.when([false, true, false], () => 'bun' as const),
|
|
52
|
-
Match.when([false, false, true], () => 'npm' as const),
|
|
53
|
-
Match.orElse(() => 'npm' as const), // default fallback
|
|
54
|
-
)
|
|
55
|
-
})
|
|
56
|
-
|
|
57
|
-
// Check if Prisma is already initialized
|
|
58
|
-
const checkPrismaSetup = () =>
|
|
59
|
-
Effect.gen(function* () {
|
|
60
|
-
const schemaExists = yield* fileExists('prisma/schema.prisma')
|
|
61
|
-
|
|
62
|
-
if (!schemaExists) {
|
|
63
|
-
const packageManager = yield* detectPackageManager()
|
|
64
|
-
|
|
65
|
-
yield* Console.log('❌ Prisma is not initialized in this project.')
|
|
66
|
-
yield* Console.log('')
|
|
67
|
-
yield* Console.log('Please run the following command first:')
|
|
68
|
-
|
|
69
|
-
const initCommand = Match.value(packageManager).pipe(
|
|
70
|
-
Match.when('pnpm', () => 'pnpm dlx prisma init'),
|
|
71
|
-
Match.when('bun', () => 'bunx prisma init'),
|
|
72
|
-
Match.when('npm', () => 'npx prisma init'),
|
|
73
|
-
Match.exhaustive,
|
|
74
|
-
)
|
|
75
|
-
|
|
76
|
-
yield* Console.log(` ${initCommand}`)
|
|
77
|
-
|
|
78
|
-
yield* Console.log('')
|
|
79
|
-
yield* Console.log('For more information, visit:')
|
|
80
|
-
yield* Console.log(
|
|
81
|
-
' https://www.prisma.io/docs/getting-started/setup-prisma/start-from-scratch/relational-databases-typescript-prismaPostgres',
|
|
82
|
-
)
|
|
83
|
-
yield* Effect.fail(new Error('Prisma not initialized'))
|
|
84
|
-
}
|
|
85
|
-
})
|
|
86
|
-
|
|
87
|
-
// Initialize Prisma schema logic
|
|
88
|
-
const initializePrismaSchema = (options: { output: string }) =>
|
|
89
|
-
Effect.gen(function* () {
|
|
90
|
-
yield* Console.log('🔧 Configuring Prisma schema with Effect generators...')
|
|
91
|
-
yield* Console.log(`📁 Output path: ${options.output}`)
|
|
92
|
-
|
|
93
|
-
// Check if Prisma is already set up
|
|
94
|
-
yield* checkPrismaSetup()
|
|
95
|
-
|
|
96
|
-
const schemaPath = 'prisma/schema.prisma'
|
|
97
|
-
|
|
98
|
-
yield* Console.log('📄 Schema file already exists.')
|
|
99
|
-
|
|
100
|
-
// Read existing content and check if it has our generators
|
|
101
|
-
const existingContent = yield* readFileContent(schemaPath)
|
|
102
|
-
|
|
103
|
-
if (existingContent.includes('@effectify/prisma prisma generate-effect')) {
|
|
104
|
-
yield* Console.log('✅ Effect generators already configured!')
|
|
105
|
-
return
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
// Add our generators to existing schema
|
|
109
|
-
yield* Console.log('🔧 Adding Effect generators to existing schema...')
|
|
110
|
-
|
|
111
|
-
const updatedContent =
|
|
112
|
-
existingContent +
|
|
113
|
-
`
|
|
114
|
-
|
|
115
|
-
// Effect generators added by @effectify/prisma
|
|
116
|
-
generator effectServices {
|
|
117
|
-
provider = "@effectify/prisma generate-effect"
|
|
118
|
-
output = "../${options.output}/generated/effect-prisma"
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
generator effect {
|
|
122
|
-
provider = "prisma-effect-kysely"
|
|
123
|
-
output = "../${options.output}/generated/effect-prisma"
|
|
124
|
-
}
|
|
125
|
-
|
|
126
|
-
generator sqlSchema {
|
|
127
|
-
provider = "@effectify/prisma generate-sql-schema"
|
|
128
|
-
output = "../${options.output}/generated"
|
|
129
|
-
}
|
|
130
|
-
`
|
|
131
|
-
|
|
132
|
-
yield* writeFileContent(schemaPath, updatedContent)
|
|
133
|
-
yield* Console.log('✅ Effect generators added to existing schema!')
|
|
134
|
-
|
|
135
|
-
yield* Console.log('🎉 Prisma schema initialization completed!')
|
|
136
|
-
yield* Console.log('💡 Next steps:')
|
|
137
|
-
yield* Console.log(' 1. Set your DATABASE_URL environment variable')
|
|
138
|
-
yield* Console.log(' 2. Run: @effectify/prisma prisma generate-effect')
|
|
139
|
-
yield* Console.log(' 3. Run: @effectify/prisma prisma generate-sql-schema')
|
|
140
|
-
|
|
141
|
-
yield* Effect.sync(() => process.exit(0))
|
|
142
|
-
})
|
|
143
|
-
|
|
144
|
-
export const initCommand = Command.make(
|
|
145
|
-
'init',
|
|
146
|
-
{
|
|
147
|
-
output: outputOption,
|
|
148
|
-
},
|
|
149
|
-
({ output }) =>
|
|
150
|
-
initializePrismaSchema({
|
|
151
|
-
output,
|
|
152
|
-
}).pipe(Effect.provide(NodeFileSystem.layer), Effect.provide(NodePath.layer)),
|
|
153
|
-
)
|
package/src/commands/prisma.ts
DELETED
|
@@ -1,50 +0,0 @@
|
|
|
1
|
-
import * as Command from '@effect/cli/Command'
|
|
2
|
-
import type * as NodeContext from '@effect/platform-node/NodeContext'
|
|
3
|
-
import type { GeneratorOptions } from '@prisma/generator-helper'
|
|
4
|
-
import generatorHelper from '@prisma/generator-helper'
|
|
5
|
-
import * as Deferred from 'effect/Deferred'
|
|
6
|
-
import * as Effect from 'effect/Effect'
|
|
7
|
-
import * as Layer from 'effect/Layer'
|
|
8
|
-
import * as Runtime from 'effect/Runtime'
|
|
9
|
-
import * as Stream from 'effect/Stream'
|
|
10
|
-
import { GeneratorContext } from '../services/generator-context.js'
|
|
11
|
-
import { GeneratorService } from '../services/generator-service.js'
|
|
12
|
-
import type { RenderService } from '../services/render-service.js'
|
|
13
|
-
|
|
14
|
-
export const prismaCommand = Command.make('prisma', {}, () =>
|
|
15
|
-
Effect.gen(function* () {
|
|
16
|
-
const generator = yield* GeneratorService
|
|
17
|
-
const runtime = yield* Effect.runtime<GeneratorService | RenderService | NodeContext.NodeContext>()
|
|
18
|
-
const run = Runtime.runPromise(runtime)
|
|
19
|
-
|
|
20
|
-
const events = Stream.async<[GeneratorOptions, Deferred.Deferred<void, unknown>]>((emit) => {
|
|
21
|
-
generatorHelper.generatorHandler({
|
|
22
|
-
onManifest() {
|
|
23
|
-
return {
|
|
24
|
-
defaultOutput: '../generated/effect',
|
|
25
|
-
prettyName: 'Prisma Effect Generator',
|
|
26
|
-
requiresEngines: [],
|
|
27
|
-
}
|
|
28
|
-
},
|
|
29
|
-
async onGenerate(options) {
|
|
30
|
-
await run(
|
|
31
|
-
Effect.gen(function* () {
|
|
32
|
-
const deferred = yield* Deferred.make<void, unknown>()
|
|
33
|
-
yield* Effect.promise(() => emit.single([options, deferred]))
|
|
34
|
-
yield* Deferred.await(deferred)
|
|
35
|
-
}),
|
|
36
|
-
)
|
|
37
|
-
},
|
|
38
|
-
})
|
|
39
|
-
})
|
|
40
|
-
|
|
41
|
-
yield* events.pipe(
|
|
42
|
-
Stream.runForEach(([options, deferred]) =>
|
|
43
|
-
generator.generate.pipe(
|
|
44
|
-
Effect.provide(Layer.succeed(GeneratorContext, options)),
|
|
45
|
-
Effect.intoDeferred(deferred),
|
|
46
|
-
),
|
|
47
|
-
),
|
|
48
|
-
)
|
|
49
|
-
}),
|
|
50
|
-
)
|
|
@@ -1,66 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env tsx
|
|
2
|
-
// biome-ignore-all lint: Generated code
|
|
3
|
-
|
|
4
|
-
import { execSync } from 'node:child_process'
|
|
5
|
-
import fs from 'node:fs/promises'
|
|
6
|
-
import path from 'node:path'
|
|
7
|
-
import gh from '@prisma/generator-helper'
|
|
8
|
-
|
|
9
|
-
const header = `-- This file was generated by sql-schema-generator, do not edit manually.
|
|
10
|
-
-- Generated at: ${new Date().toISOString()}
|
|
11
|
-
|
|
12
|
-
`
|
|
13
|
-
type SqlGeneratorOptions = {
|
|
14
|
-
generator: {
|
|
15
|
-
output?: {
|
|
16
|
-
value: string
|
|
17
|
-
}
|
|
18
|
-
}
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
export async function generateSqlSchema(options: SqlGeneratorOptions) {
|
|
22
|
-
const outputDir = options.generator.output?.value || '../generated'
|
|
23
|
-
const datasourceUrl = 'prisma/dev.db'
|
|
24
|
-
|
|
25
|
-
if (!datasourceUrl) {
|
|
26
|
-
throw new Error('No datasource URL found')
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
await fs.mkdir(outputDir, { recursive: true })
|
|
30
|
-
|
|
31
|
-
try {
|
|
32
|
-
let dbPath = datasourceUrl
|
|
33
|
-
if (dbPath.startsWith('file:')) {
|
|
34
|
-
dbPath = dbPath.replace('file:', '')
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
if (!path.isAbsolute(dbPath)) {
|
|
38
|
-
dbPath = path.resolve(process.cwd(), dbPath)
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
const schemaOutput = execSync(`sqlite3 "${dbPath}" ".schema"`, { encoding: 'utf8' })
|
|
42
|
-
const outputPath = path.join(outputDir, 'schema.sql')
|
|
43
|
-
await fs.writeFile(outputPath, header + schemaOutput)
|
|
44
|
-
} catch (error) {
|
|
45
|
-
console.error('❌ Failed to generate schema dump:', error)
|
|
46
|
-
throw error
|
|
47
|
-
}
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
gh.generatorHandler({
|
|
51
|
-
onManifest() {
|
|
52
|
-
return {
|
|
53
|
-
defaultOutput: '../generated',
|
|
54
|
-
prettyName: 'SQL Schema Generator',
|
|
55
|
-
requiresEngines: [],
|
|
56
|
-
}
|
|
57
|
-
},
|
|
58
|
-
|
|
59
|
-
async onGenerate(options) {
|
|
60
|
-
await generateSqlSchema({
|
|
61
|
-
generator: {
|
|
62
|
-
output: options?.generator?.output ? { value: options.generator.output.value || '' } : undefined,
|
|
63
|
-
},
|
|
64
|
-
})
|
|
65
|
-
},
|
|
66
|
-
})
|