@effectify/prisma 0.1.2 → 1.0.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.
- 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/dist/src/templates/model.eta +8 -0
- 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/index-default.eta +0 -0
- /package/{src → dist/src}/templates/prisma-raw-sql.eta +0 -0
- /package/{src → dist/src}/templates/prisma-repository.eta +0 -0
- /package/{src → dist/src}/templates/prisma-schema.eta +0 -0
package/dist/src/cli.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
#!/usr/bin/env
|
|
1
|
+
#!/usr/bin/env -S pnpm dlx tsx
|
|
2
2
|
export {};
|
package/dist/src/cli.js
CHANGED
|
@@ -1,17 +1,17 @@
|
|
|
1
|
-
#!/usr/bin/env
|
|
1
|
+
#!/usr/bin/env -S pnpm dlx tsx
|
|
2
2
|
import * as Command from '@effect/cli/Command';
|
|
3
3
|
import * as NodeContext from '@effect/platform-node/NodeContext';
|
|
4
4
|
import * as NodeRuntime from '@effect/platform-node/NodeRuntime';
|
|
5
|
-
import * as Console from 'effect/Console';
|
|
6
5
|
import * as Effect from 'effect/Effect';
|
|
7
|
-
import
|
|
8
|
-
import { generateSqlSchemaCommand } from './commands/generate-sql-schema.js';
|
|
6
|
+
import * as Layer from 'effect/Layer';
|
|
9
7
|
import { initCommand } from './commands/init.js';
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
const cli = Command.run(
|
|
8
|
+
import { prismaCommand } from './commands/prisma.js';
|
|
9
|
+
import { GeneratorService } from './services/generator-service.js';
|
|
10
|
+
import { RenderService } from './services/render-service.js';
|
|
11
|
+
const cli = Command.run(prismaCommand.pipe(Command.withSubcommands([initCommand])), {
|
|
14
12
|
name: '@effectify/prisma CLI',
|
|
15
13
|
version: '0.1.0',
|
|
16
14
|
});
|
|
17
|
-
|
|
15
|
+
const GeneratorLayer = GeneratorService.Live.pipe(Layer.provide(RenderService.Live), Layer.provide(NodeContext.layer));
|
|
16
|
+
const MainLayer = Layer.mergeAll(GeneratorLayer, RenderService.Live, NodeContext.layer);
|
|
17
|
+
cli(process.argv).pipe(Effect.provide(MainLayer), NodeRuntime.runMain);
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
import * as Command from '@effect/cli/Command';
|
|
2
|
-
export declare const initCommand: Command.Command<"init", never,
|
|
2
|
+
export declare const initCommand: Command.Command<"init", never, import("@effect/platform/Error").PlatformError | Error, {
|
|
3
3
|
readonly output: string;
|
|
4
4
|
}>;
|
|
@@ -91,10 +91,8 @@ generator sqlSchema {
|
|
|
91
91
|
yield* Console.log(' 1. Set your DATABASE_URL environment variable');
|
|
92
92
|
yield* Console.log(' 2. Run: @effectify/prisma prisma generate-effect');
|
|
93
93
|
yield* Console.log(' 3. Run: @effectify/prisma prisma generate-sql-schema');
|
|
94
|
-
// Ensure the effect completes and exits
|
|
95
94
|
yield* Effect.sync(() => process.exit(0));
|
|
96
95
|
});
|
|
97
|
-
// Export the init command
|
|
98
96
|
export const initCommand = Command.make('init', {
|
|
99
97
|
output: outputOption,
|
|
100
98
|
}, ({ output }) => initializePrismaSchema({
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import * as Command from '@effect/cli/Command';
|
|
2
|
+
import type * as NodeContext from '@effect/platform-node/NodeContext';
|
|
3
|
+
import { GeneratorService } from '../services/generator-service.js';
|
|
4
|
+
import type { RenderService } from '../services/render-service.js';
|
|
5
|
+
export declare const prismaCommand: Command.Command<"prisma", RenderService | GeneratorService | NodeContext.NodeContext, never, {}>;
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import * as Command from '@effect/cli/Command';
|
|
2
|
+
import generatorHelper from '@prisma/generator-helper';
|
|
3
|
+
import * as Deferred from 'effect/Deferred';
|
|
4
|
+
import * as Effect from 'effect/Effect';
|
|
5
|
+
import * as Layer from 'effect/Layer';
|
|
6
|
+
import * as Runtime from 'effect/Runtime';
|
|
7
|
+
import * as Stream from 'effect/Stream';
|
|
8
|
+
import { GeneratorContext } from '../services/generator-context.js';
|
|
9
|
+
import { GeneratorService } from '../services/generator-service.js';
|
|
10
|
+
export const prismaCommand = Command.make('prisma', {}, () => Effect.gen(function* () {
|
|
11
|
+
const generator = yield* GeneratorService;
|
|
12
|
+
const runtime = yield* Effect.runtime();
|
|
13
|
+
const run = Runtime.runPromise(runtime);
|
|
14
|
+
const events = Stream.async((emit) => {
|
|
15
|
+
generatorHelper.generatorHandler({
|
|
16
|
+
onManifest() {
|
|
17
|
+
return {
|
|
18
|
+
defaultOutput: '../generated/effect',
|
|
19
|
+
prettyName: 'Prisma Effect Generator',
|
|
20
|
+
requiresEngines: [],
|
|
21
|
+
};
|
|
22
|
+
},
|
|
23
|
+
async onGenerate(options) {
|
|
24
|
+
await run(Effect.gen(function* () {
|
|
25
|
+
const deferred = yield* Deferred.make();
|
|
26
|
+
yield* Effect.promise(() => emit.single([options, deferred]));
|
|
27
|
+
yield* Deferred.await(deferred);
|
|
28
|
+
}));
|
|
29
|
+
// Cerrar el stream después de procesar la generación
|
|
30
|
+
emit.end();
|
|
31
|
+
},
|
|
32
|
+
});
|
|
33
|
+
});
|
|
34
|
+
yield* events.pipe(Stream.runForEach(([options, deferred]) => generator.generate.pipe(Effect.provide(Layer.succeed(GeneratorContext, options)), Effect.intoDeferred(deferred))));
|
|
35
|
+
}));
|
|
@@ -1,58 +1,50 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
// prettyName: 'SQL Schema Generator',
|
|
52
|
-
// requiresEngines: [],
|
|
53
|
-
// }
|
|
54
|
-
// },
|
|
55
|
-
// async onGenerate(options) {
|
|
56
|
-
// await generateSqlSchema(options)
|
|
57
|
-
// },
|
|
58
|
-
// })
|
|
1
|
+
#!/usr/bin/env tsx
|
|
2
|
+
// biome-ignore-all lint: Generated code
|
|
3
|
+
import { execSync } from 'node:child_process';
|
|
4
|
+
import fs from 'node:fs/promises';
|
|
5
|
+
import path from 'node:path';
|
|
6
|
+
import gh from '@prisma/generator-helper';
|
|
7
|
+
const header = `-- This file was generated by sql-schema-generator, do not edit manually.
|
|
8
|
+
-- Generated at: ${new Date().toISOString()}
|
|
9
|
+
|
|
10
|
+
`;
|
|
11
|
+
export async function generateSqlSchema(options) {
|
|
12
|
+
const outputDir = options.generator.output?.value || '../generated';
|
|
13
|
+
const datasourceUrl = 'prisma/dev.db';
|
|
14
|
+
if (!datasourceUrl) {
|
|
15
|
+
throw new Error('No datasource URL found');
|
|
16
|
+
}
|
|
17
|
+
await fs.mkdir(outputDir, { recursive: true });
|
|
18
|
+
try {
|
|
19
|
+
let dbPath = datasourceUrl;
|
|
20
|
+
if (dbPath.startsWith('file:')) {
|
|
21
|
+
dbPath = dbPath.replace('file:', '');
|
|
22
|
+
}
|
|
23
|
+
if (!path.isAbsolute(dbPath)) {
|
|
24
|
+
dbPath = path.resolve(process.cwd(), dbPath);
|
|
25
|
+
}
|
|
26
|
+
const schemaOutput = execSync(`sqlite3 "${dbPath}" ".schema"`, { encoding: 'utf8' });
|
|
27
|
+
const outputPath = path.join(outputDir, 'schema.sql');
|
|
28
|
+
await fs.writeFile(outputPath, header + schemaOutput);
|
|
29
|
+
}
|
|
30
|
+
catch (error) {
|
|
31
|
+
console.error('❌ Failed to generate schema dump:', error);
|
|
32
|
+
throw error;
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
gh.generatorHandler({
|
|
36
|
+
onManifest() {
|
|
37
|
+
return {
|
|
38
|
+
defaultOutput: '../generated',
|
|
39
|
+
prettyName: 'SQL Schema Generator',
|
|
40
|
+
requiresEngines: [],
|
|
41
|
+
};
|
|
42
|
+
},
|
|
43
|
+
async onGenerate(options) {
|
|
44
|
+
await generateSqlSchema({
|
|
45
|
+
generator: {
|
|
46
|
+
output: options?.generator?.output ? { value: options.generator.output.value || '' } : undefined,
|
|
47
|
+
},
|
|
48
|
+
});
|
|
49
|
+
},
|
|
50
|
+
});
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { GeneratorOptions } from '@prisma/generator-helper';
|
|
2
|
+
import * as Context from 'effect/Context';
|
|
3
|
+
declare const GeneratorContext_base: Context.TagClass<GeneratorContext, "GeneratorContext", GeneratorOptions>;
|
|
4
|
+
export declare class GeneratorContext extends GeneratorContext_base {
|
|
5
|
+
}
|
|
6
|
+
export {};
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import * as FileSystem from '@effect/platform/FileSystem';
|
|
2
|
+
import * as Path from '@effect/platform/Path';
|
|
3
|
+
import * as Context from 'effect/Context';
|
|
4
|
+
import * as Effect from 'effect/Effect';
|
|
5
|
+
import * as Layer from 'effect/Layer';
|
|
6
|
+
import { GeneratorContext } from './generator-context.js';
|
|
7
|
+
import { RenderService } from './render-service.js';
|
|
8
|
+
declare const GeneratorService_base: Context.TagClass<GeneratorService, "GeneratorService", {
|
|
9
|
+
readonly generate: Effect.Effect<void, Error, GeneratorContext>;
|
|
10
|
+
}>;
|
|
11
|
+
export declare class GeneratorService extends GeneratorService_base {
|
|
12
|
+
static Live: Layer.Layer<GeneratorService, never, FileSystem.FileSystem | Path.Path | RenderService>;
|
|
13
|
+
}
|
|
14
|
+
export {};
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
import * as FileSystem from '@effect/platform/FileSystem';
|
|
2
|
+
import * as Path from '@effect/platform/Path';
|
|
3
|
+
import * as Context from 'effect/Context';
|
|
4
|
+
import * as Effect from 'effect/Effect';
|
|
5
|
+
import * as Layer from 'effect/Layer';
|
|
6
|
+
import { GeneratorContext } from './generator-context.js';
|
|
7
|
+
import { RenderService } from './render-service.js';
|
|
8
|
+
export class GeneratorService extends Context.Tag('GeneratorService')() {
|
|
9
|
+
static Live = Layer.effect(GeneratorService, Effect.gen(function* () {
|
|
10
|
+
const fs = yield* FileSystem.FileSystem;
|
|
11
|
+
const path = yield* Path.Path;
|
|
12
|
+
const { render } = yield* RenderService;
|
|
13
|
+
const parseErrorImportPath = (errorImportPath) => {
|
|
14
|
+
if (!errorImportPath) {
|
|
15
|
+
return null;
|
|
16
|
+
}
|
|
17
|
+
const [modulePath, className] = errorImportPath.split('#');
|
|
18
|
+
if (!(modulePath && className)) {
|
|
19
|
+
throw new Error(`Invalid errorImportPath format: "${errorImportPath}". Expected "path/to/module#ErrorClassName"`);
|
|
20
|
+
}
|
|
21
|
+
return { path: modulePath, className };
|
|
22
|
+
};
|
|
23
|
+
const addExtension = (filePath, extension) => {
|
|
24
|
+
if (!extension) {
|
|
25
|
+
return filePath;
|
|
26
|
+
}
|
|
27
|
+
const ext = path.extname(filePath);
|
|
28
|
+
if (ext) {
|
|
29
|
+
return filePath;
|
|
30
|
+
}
|
|
31
|
+
return `${filePath}.${extension}`;
|
|
32
|
+
};
|
|
33
|
+
const fixSchemaImports = (outputDir) => Effect.gen(function* () {
|
|
34
|
+
const schemasDir = path.join(outputDir, 'schemas');
|
|
35
|
+
const indexFile = path.join(schemasDir, 'index.ts');
|
|
36
|
+
const exists = yield* fs.exists(indexFile);
|
|
37
|
+
if (!exists) {
|
|
38
|
+
return;
|
|
39
|
+
}
|
|
40
|
+
const content = yield* fs.readFileString(indexFile);
|
|
41
|
+
const fixedContent = content
|
|
42
|
+
.replace(/export \* from '\.\/enums'/g, "export * from './enums.js'")
|
|
43
|
+
.replace(/export \* from '\.\/types'/g, "export * from './types.js'");
|
|
44
|
+
if (content !== fixedContent) {
|
|
45
|
+
yield* fs.writeFileString(indexFile, fixedContent);
|
|
46
|
+
}
|
|
47
|
+
});
|
|
48
|
+
const getClientImportPath = (config) => Array.isArray(config.clientImportPath)
|
|
49
|
+
? config.clientImportPath[0]
|
|
50
|
+
: (config.clientImportPath ?? '@prisma/client');
|
|
51
|
+
const getErrorImportPath = (config) => Array.isArray(config.errorImportPath) ? config.errorImportPath[0] : config.errorImportPath;
|
|
52
|
+
const getImportFileExtension = (config) => Array.isArray(config.importFileExtension) ? config.importFileExtension[0] : (config.importFileExtension ?? '');
|
|
53
|
+
const getCustomError = (config, options, schemaDir) => {
|
|
54
|
+
const errorImportPathRaw = getErrorImportPath(config);
|
|
55
|
+
const importFileExtension = getImportFileExtension(config);
|
|
56
|
+
let customError = parseErrorImportPath(errorImportPathRaw);
|
|
57
|
+
if (customError?.path.startsWith('.')) {
|
|
58
|
+
const outputDir = options.generator.output?.value;
|
|
59
|
+
if (outputDir) {
|
|
60
|
+
const absoluteErrorPath = path.resolve(schemaDir, customError.path);
|
|
61
|
+
const relativeToOutput = path.relative(outputDir, absoluteErrorPath);
|
|
62
|
+
const normalizedPath = relativeToOutput.startsWith('.') ? relativeToOutput : `./${relativeToOutput}`;
|
|
63
|
+
const pathWithExtension = addExtension(normalizedPath, importFileExtension);
|
|
64
|
+
customError = { ...customError, path: pathWithExtension };
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
return customError;
|
|
68
|
+
};
|
|
69
|
+
const getGeneratorConfig = (options, schemaDir) => {
|
|
70
|
+
const { config } = options.generator;
|
|
71
|
+
const clientImportPath = getClientImportPath(config);
|
|
72
|
+
const customError = getCustomError(config, options, schemaDir);
|
|
73
|
+
return { clientImportPath, customError };
|
|
74
|
+
};
|
|
75
|
+
const generatePrismaSchema = (outputDir) => Effect.gen(function* () {
|
|
76
|
+
const content = yield* render('prisma-schema', {});
|
|
77
|
+
yield* fs.writeFileString(path.join(outputDir, 'prisma-schema.ts'), content);
|
|
78
|
+
});
|
|
79
|
+
const generatePrismaRepository = (outputDir, clientImportPath) => Effect.gen(function* () {
|
|
80
|
+
const content = yield* render('prisma-repository', { clientImportPath });
|
|
81
|
+
yield* fs.writeFileString(path.join(outputDir, 'prisma-repository.ts'), content);
|
|
82
|
+
});
|
|
83
|
+
const generateModels = (outputDir, models) => Effect.gen(function* () {
|
|
84
|
+
yield* fs.makeDirectory(path.join(outputDir, 'models'), { recursive: true });
|
|
85
|
+
for (const model of models) {
|
|
86
|
+
const content = yield* render('model', { model });
|
|
87
|
+
yield* fs.writeFileString(path.join(outputDir, 'models', `${model.name}.ts`), content);
|
|
88
|
+
}
|
|
89
|
+
});
|
|
90
|
+
const generateIndex = (outputDir, models, clientImportPath, customError) => Effect.gen(function* () {
|
|
91
|
+
const errorType = customError ? customError.className : 'PrismaError';
|
|
92
|
+
const rawSqlOperations = yield* render('prisma-raw-sql', { errorType });
|
|
93
|
+
const modelExports = models.map((m) => `export * from "./models/${m.name}.js"`).join('\n');
|
|
94
|
+
const templateName = customError ? 'index-custom-error' : 'index-default';
|
|
95
|
+
const content = yield* render(templateName, {
|
|
96
|
+
clientImportPath,
|
|
97
|
+
customError,
|
|
98
|
+
rawSqlOperations,
|
|
99
|
+
modelExports,
|
|
100
|
+
});
|
|
101
|
+
yield* fs.writeFileString(path.join(outputDir, 'index.ts'), content);
|
|
102
|
+
});
|
|
103
|
+
const generate = Effect.gen(function* () {
|
|
104
|
+
const options = yield* GeneratorContext;
|
|
105
|
+
const models = options.dmmf.datamodel.models;
|
|
106
|
+
const outputDir = options.generator.output?.value;
|
|
107
|
+
const schemaDir = path.dirname(options.schemaPath);
|
|
108
|
+
if (!outputDir) {
|
|
109
|
+
return yield* Effect.fail(new Error('No output directory specified'));
|
|
110
|
+
}
|
|
111
|
+
const { clientImportPath, customError } = getGeneratorConfig(options, schemaDir);
|
|
112
|
+
yield* fs.makeDirectory(outputDir, { recursive: true });
|
|
113
|
+
yield* generatePrismaSchema(outputDir);
|
|
114
|
+
yield* generatePrismaRepository(outputDir, clientImportPath);
|
|
115
|
+
yield* generateModels(outputDir, models);
|
|
116
|
+
yield* generateIndex(outputDir, models, clientImportPath, customError);
|
|
117
|
+
yield* fixSchemaImports(outputDir);
|
|
118
|
+
});
|
|
119
|
+
return { generate };
|
|
120
|
+
}));
|
|
121
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import * as Context from 'effect/Context';
|
|
2
|
+
import * as Effect from 'effect/Effect';
|
|
3
|
+
import * as Layer from 'effect/Layer';
|
|
4
|
+
declare const RenderService_base: Context.TagClass<RenderService, "RenderService", {
|
|
5
|
+
readonly render: (templateName: string, data: Record<string, unknown>) => Effect.Effect<string, Error>;
|
|
6
|
+
}>;
|
|
7
|
+
export declare class RenderService extends RenderService_base {
|
|
8
|
+
static Live: Layer.Layer<RenderService, never, never>;
|
|
9
|
+
}
|
|
10
|
+
export {};
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import * as path from 'node:path';
|
|
2
|
+
import { fileURLToPath } from 'node:url';
|
|
3
|
+
import * as Context from 'effect/Context';
|
|
4
|
+
import * as Effect from 'effect/Effect';
|
|
5
|
+
import * as Layer from 'effect/Layer';
|
|
6
|
+
import { Eta } from 'eta';
|
|
7
|
+
export class RenderService extends Context.Tag('RenderService')() {
|
|
8
|
+
static Live = Layer.sync(RenderService, () => {
|
|
9
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
10
|
+
const __dirname = path.dirname(__filename);
|
|
11
|
+
const templatesDir = path.resolve(__dirname, '../templates');
|
|
12
|
+
const eta = new Eta({
|
|
13
|
+
views: templatesDir,
|
|
14
|
+
autoEscape: false,
|
|
15
|
+
});
|
|
16
|
+
return {
|
|
17
|
+
render: (templateName, data) => Effect.try({
|
|
18
|
+
try: () => eta.render(templateName, data),
|
|
19
|
+
catch: (error) => new Error(`Failed to render template ${templateName}: ${error}`),
|
|
20
|
+
}),
|
|
21
|
+
};
|
|
22
|
+
});
|
|
23
|
+
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import * as Model from "../prisma-repository.js"
|
|
2
|
+
import { <%= it.model.name %>, <%= it.model.name %>Id } from "../schemas/index.js"
|
|
3
|
+
|
|
4
|
+
export class <%= it.model.name %>Model extends Model.Class<<%= it.model.name %>Model>("<%= it.model.name %>")({
|
|
5
|
+
...<%= it.model.name %>.fields
|
|
6
|
+
}) {}
|
|
7
|
+
|
|
8
|
+
export { <%= it.model.name %>, <%= it.model.name %>Id }
|
package/package.json
CHANGED
|
@@ -1,16 +1,20 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@effectify/prisma",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "1.0.0",
|
|
4
4
|
"description": "",
|
|
5
|
-
"main": "
|
|
5
|
+
"main": "./dist/src/cli.js",
|
|
6
6
|
"type": "module",
|
|
7
7
|
"license": "MIT",
|
|
8
8
|
"bin": {
|
|
9
|
-
"effect-prisma": "./src/cli.
|
|
9
|
+
"effect-prisma": "./dist/src/cli.js"
|
|
10
10
|
},
|
|
11
11
|
"exports": {
|
|
12
|
-
"
|
|
12
|
+
".": "./dist/src/cli.js",
|
|
13
|
+
"./prisma": "./dist/prisma/index.js"
|
|
13
14
|
},
|
|
15
|
+
"files": [
|
|
16
|
+
"dist"
|
|
17
|
+
],
|
|
14
18
|
"publishConfig": {
|
|
15
19
|
"access": "public"
|
|
16
20
|
},
|
|
@@ -18,9 +22,9 @@
|
|
|
18
22
|
"author": "",
|
|
19
23
|
"dependencies": {
|
|
20
24
|
"@effect/cli": "0.73.0",
|
|
21
|
-
"@prisma/adapter-better-sqlite3": "7.
|
|
22
|
-
"@prisma/generator": "
|
|
23
|
-
"@prisma/generator-helper": "7.
|
|
25
|
+
"@prisma/adapter-better-sqlite3": "7.3.0",
|
|
26
|
+
"@prisma/generator": "7.3.0",
|
|
27
|
+
"@prisma/generator-helper": "7.3.0",
|
|
24
28
|
"better-sqlite3": "12.4.6",
|
|
25
29
|
"eta": "^4.5.0",
|
|
26
30
|
"kysely": "0.28.8"
|
|
@@ -29,19 +33,19 @@
|
|
|
29
33
|
"@effect/platform": "0.94.0",
|
|
30
34
|
"@effect/platform-node": "0.104.0",
|
|
31
35
|
"effect": "3.19.13",
|
|
32
|
-
"@prisma/client": "7.
|
|
36
|
+
"@prisma/client": "7.3.0"
|
|
33
37
|
},
|
|
34
38
|
"devDependencies": {
|
|
35
|
-
"prisma-effect-kysely": "
|
|
39
|
+
"prisma-effect-kysely": "5.2.0",
|
|
36
40
|
"@effect/build-utils": "0.8.9",
|
|
37
41
|
"@effect/experimental": "0.58.0",
|
|
38
42
|
"@effect/language-service": "0.56.0",
|
|
39
43
|
"@effect/vitest": "0.27.0",
|
|
40
|
-
"@prisma/internals": "7.
|
|
44
|
+
"@prisma/internals": "7.3.0",
|
|
41
45
|
"@types/better-sqlite3": "7.6.13",
|
|
42
46
|
"@types/node": "20.19.25",
|
|
43
47
|
"bun": "1.3.0",
|
|
44
|
-
"prisma": "7.
|
|
48
|
+
"prisma": "7.3.0",
|
|
45
49
|
"tsx": "4.20.6",
|
|
46
50
|
"typescript": "5.9.3",
|
|
47
51
|
"vite-tsconfig-paths": "5.1.4",
|
|
@@ -1,73 +0,0 @@
|
|
|
1
|
-
import * as Command from '@effect/cli/Command';
|
|
2
|
-
import * as FileSystem from '@effect/platform/FileSystem';
|
|
3
|
-
import * as NodeFileSystem from '@effect/platform-node/NodeFileSystem';
|
|
4
|
-
import * as NodePath from '@effect/platform-node/NodePath';
|
|
5
|
-
import * as Console from 'effect/Console';
|
|
6
|
-
import * as Effect from 'effect/Effect';
|
|
7
|
-
import * as Match from 'effect/Match';
|
|
8
|
-
// import { generateEffectPrisma } from '../generators/prisma-effect-generator.js'
|
|
9
|
-
// Check if file exists
|
|
10
|
-
const fileExists = (path) => Effect.gen(function* () {
|
|
11
|
-
const fs = yield* FileSystem.FileSystem;
|
|
12
|
-
return yield* fs.exists(path);
|
|
13
|
-
});
|
|
14
|
-
// Detect package manager using pattern matching
|
|
15
|
-
const detectPackageManager = () => Effect.gen(function* () {
|
|
16
|
-
const pnpmExists = yield* fileExists('pnpm-lock.yaml');
|
|
17
|
-
const bunExists = yield* fileExists('bun.lockb');
|
|
18
|
-
const npmExists = yield* fileExists('package-lock.json');
|
|
19
|
-
// Create a tuple to match against
|
|
20
|
-
const lockFiles = [pnpmExists, bunExists, npmExists];
|
|
21
|
-
return Match.value(lockFiles).pipe(Match.when([true, false, false], () => 'pnpm'), Match.when([false, true, false], () => 'bun'), Match.when([false, false, true], () => 'npm'), Match.orElse(() => 'npm'));
|
|
22
|
-
});
|
|
23
|
-
// Check if Prisma schema exists
|
|
24
|
-
const checkPrismaSchema = () => Effect.gen(function* () {
|
|
25
|
-
const schemaExists = yield* fileExists('prisma/schema.prisma');
|
|
26
|
-
if (!schemaExists) {
|
|
27
|
-
yield* Console.log('❌ Prisma schema not found.');
|
|
28
|
-
yield* Console.log('');
|
|
29
|
-
yield* Console.log('Please run the following command first:');
|
|
30
|
-
const packageManager = yield* detectPackageManager();
|
|
31
|
-
const initCommand = Match.value(packageManager).pipe(Match.when('pnpm', () => 'pnpm dlx prisma init'), Match.when('bun', () => 'bunx prisma init'), Match.when('npm', () => 'npx prisma init'), Match.exhaustive);
|
|
32
|
-
yield* Console.log(` ${initCommand}`);
|
|
33
|
-
yield* Effect.fail(new Error('Prisma schema not found'));
|
|
34
|
-
}
|
|
35
|
-
});
|
|
36
|
-
// Execute the Effect generator
|
|
37
|
-
const generateEffectServices = () => Effect.gen(function* () {
|
|
38
|
-
// Check if we're being called by Prisma (no interactive output)
|
|
39
|
-
const isCalledByPrisma = process.env.PRISMA_GENERATOR_INVOCATION === 'true' ||
|
|
40
|
-
process.argv.includes('--generator') ||
|
|
41
|
-
!process.stdout.isTTY;
|
|
42
|
-
if (!isCalledByPrisma) {
|
|
43
|
-
yield* Console.log('🔧 Running Effect generator...');
|
|
44
|
-
}
|
|
45
|
-
// Check if Prisma schema exists
|
|
46
|
-
yield* checkPrismaSchema();
|
|
47
|
-
// Note: We don't need to check for local generator files
|
|
48
|
-
// since we're importing from our own package
|
|
49
|
-
if (!isCalledByPrisma) {
|
|
50
|
-
yield* Console.log('🚀 Executing Effect generator...');
|
|
51
|
-
}
|
|
52
|
-
// Execute the generator function
|
|
53
|
-
yield* Effect.tryPromise({
|
|
54
|
-
try: () => {
|
|
55
|
-
// Create mock options for the generator
|
|
56
|
-
// const mockOptions = {
|
|
57
|
-
// dmmf: { datamodel: { models: [] } }, // Empty models for now
|
|
58
|
-
// generator: { output: { value: 'src/generated/effect-prisma' } },
|
|
59
|
-
// }
|
|
60
|
-
return Promise.resolve();
|
|
61
|
-
// return generateEffectPrisma(mockOptions)
|
|
62
|
-
},
|
|
63
|
-
catch: (error) => new Error(`Generator execution failed: ${error}`),
|
|
64
|
-
});
|
|
65
|
-
if (!isCalledByPrisma) {
|
|
66
|
-
yield* Console.log('✅ Effect generator executed successfully!');
|
|
67
|
-
yield* Console.log('💡 Generated files are available in the configured output directory');
|
|
68
|
-
}
|
|
69
|
-
// Ensure the effect completes and exits
|
|
70
|
-
yield* Effect.sync(() => process.exit(0));
|
|
71
|
-
});
|
|
72
|
-
// Export the generate-effect command
|
|
73
|
-
export const generateEffectCommand = Command.make('generate-effect', {}, () => generateEffectServices().pipe(Effect.provide(NodeFileSystem.layer), Effect.provide(NodePath.layer)));
|
|
@@ -1,72 +0,0 @@
|
|
|
1
|
-
import * as Command from '@effect/cli/Command';
|
|
2
|
-
import * as FileSystem from '@effect/platform/FileSystem';
|
|
3
|
-
import * as NodeFileSystem from '@effect/platform-node/NodeFileSystem';
|
|
4
|
-
import * as NodePath from '@effect/platform-node/NodePath';
|
|
5
|
-
import * as Console from 'effect/Console';
|
|
6
|
-
import * as Effect from 'effect/Effect';
|
|
7
|
-
import * as Match from 'effect/Match';
|
|
8
|
-
// import { generateSqlSchema } from '../generators/sql-schema-generator.js'
|
|
9
|
-
// Check if file exists
|
|
10
|
-
const fileExists = (path) => Effect.gen(function* () {
|
|
11
|
-
const fs = yield* FileSystem.FileSystem;
|
|
12
|
-
return yield* fs.exists(path);
|
|
13
|
-
});
|
|
14
|
-
// Detect package manager using pattern matching
|
|
15
|
-
const detectPackageManager = () => Effect.gen(function* () {
|
|
16
|
-
const pnpmExists = yield* fileExists('pnpm-lock.yaml');
|
|
17
|
-
const bunExists = yield* fileExists('bun.lockb');
|
|
18
|
-
const npmExists = yield* fileExists('package-lock.json');
|
|
19
|
-
// Create a tuple to match against
|
|
20
|
-
const lockFiles = [pnpmExists, bunExists, npmExists];
|
|
21
|
-
return Match.value(lockFiles).pipe(Match.when([true, false, false], () => 'pnpm'), Match.when([false, true, false], () => 'bun'), Match.when([false, false, true], () => 'npm'), Match.orElse(() => 'npm'));
|
|
22
|
-
});
|
|
23
|
-
// Check if Prisma schema exists
|
|
24
|
-
const checkPrismaSchema = () => Effect.gen(function* () {
|
|
25
|
-
const schemaExists = yield* fileExists('prisma/schema.prisma');
|
|
26
|
-
if (!schemaExists) {
|
|
27
|
-
yield* Console.log('❌ Prisma schema not found.');
|
|
28
|
-
yield* Console.log('');
|
|
29
|
-
yield* Console.log('Please run the following command first:');
|
|
30
|
-
const packageManager = yield* detectPackageManager();
|
|
31
|
-
const initCommand = Match.value(packageManager).pipe(Match.when('pnpm', () => 'pnpm dlx prisma init'), Match.when('bun', () => 'bunx prisma init'), Match.when('npm', () => 'npx prisma init'), Match.exhaustive);
|
|
32
|
-
yield* Console.log(` ${initCommand}`);
|
|
33
|
-
yield* Effect.fail(new Error('Prisma schema not found'));
|
|
34
|
-
}
|
|
35
|
-
});
|
|
36
|
-
// Execute the SQL schema generator
|
|
37
|
-
const generateSqlSchemaServices = () => Effect.gen(function* () {
|
|
38
|
-
// Check if we're being called by Prisma (no interactive output)
|
|
39
|
-
const isCalledByPrisma = process.env.PRISMA_GENERATOR_INVOCATION === 'true' ||
|
|
40
|
-
process.argv.includes('--generator') ||
|
|
41
|
-
!process.stdout.isTTY;
|
|
42
|
-
if (!isCalledByPrisma) {
|
|
43
|
-
yield* Console.log('🔧 Running SQL schema generator...');
|
|
44
|
-
}
|
|
45
|
-
// Check if Prisma schema exists
|
|
46
|
-
yield* checkPrismaSchema();
|
|
47
|
-
// Note: We don't need to check for local generator files
|
|
48
|
-
// since we're importing from our own package
|
|
49
|
-
if (!isCalledByPrisma) {
|
|
50
|
-
yield* Console.log('🚀 Executing SQL schema generator...');
|
|
51
|
-
}
|
|
52
|
-
// Execute the generator function
|
|
53
|
-
yield* Effect.tryPromise({
|
|
54
|
-
try: () => {
|
|
55
|
-
// Create mock options for the generator
|
|
56
|
-
// const mockOptions = {
|
|
57
|
-
// generator: { output: { value: 'src/generated' } },
|
|
58
|
-
// }
|
|
59
|
-
// return generateSqlSchema(mockOptions)
|
|
60
|
-
return Promise.resolve();
|
|
61
|
-
},
|
|
62
|
-
catch: (error) => new Error(`Generator execution failed: ${error}`),
|
|
63
|
-
});
|
|
64
|
-
if (!isCalledByPrisma) {
|
|
65
|
-
yield* Console.log('✅ SQL schema generator executed successfully!');
|
|
66
|
-
yield* Console.log('💡 Generated files are available in the configured output directory');
|
|
67
|
-
}
|
|
68
|
-
// Ensure the effect completes and exits
|
|
69
|
-
yield* Effect.sync(() => process.exit(0));
|
|
70
|
-
});
|
|
71
|
-
// Export the generate-sql-schema command
|
|
72
|
-
export const generateSqlSchemaCommand = Command.make('generate-sql-schema', {}, () => generateSqlSchemaServices().pipe(Effect.provide(NodeFileSystem.layer), Effect.provide(NodePath.layer)));
|