@docker-harpoon/prisma 0.1.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/index.d.ts +82 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +103 -0
- package/dist/patchers/prisma-v7-libsql.d.ts +17 -0
- package/dist/patchers/prisma-v7-libsql.d.ts.map +1 -0
- package/dist/patchers/prisma-v7-libsql.js +103 -0
- package/dist/transformers/prisma.d.ts +26 -0
- package/dist/transformers/prisma.d.ts.map +1 -0
- package/dist/transformers/prisma.js +87 -0
- package/package.json +27 -0
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @harpoon/prisma
|
|
3
|
+
*
|
|
4
|
+
* Prisma binding for Harpoon.
|
|
5
|
+
*
|
|
6
|
+
* Provides:
|
|
7
|
+
* - PrismaBinding: Attaches to database containers for connection strings and migrations
|
|
8
|
+
* - Config patchers for Prisma v7 LibSQL support
|
|
9
|
+
* - Dockerfile transformers for prisma commands in monorepos
|
|
10
|
+
*/
|
|
11
|
+
import { Effect } from 'effect';
|
|
12
|
+
import type { Binding, PatchContext, PatchResult, DockerfileInstruction, TransformContext } from '@harpoon/core';
|
|
13
|
+
export { prismaV7LibSqlPatcher } from './patchers/prisma-v7-libsql';
|
|
14
|
+
export { prismaTransformers, prismaPackageManagerTransformer, prismaConditionalSeedTransformer, } from './transformers/prisma';
|
|
15
|
+
export interface PrismaBindingOptions {
|
|
16
|
+
/** Run prisma migrate deploy on container start */
|
|
17
|
+
migrate?: boolean;
|
|
18
|
+
/** Run prisma db push on container start */
|
|
19
|
+
push?: boolean;
|
|
20
|
+
/** Run prisma generate on container start */
|
|
21
|
+
generate?: boolean;
|
|
22
|
+
/** Path to prisma schema (default: ./prisma/schema.prisma) */
|
|
23
|
+
schema?: string;
|
|
24
|
+
/** Custom database URL override */
|
|
25
|
+
databaseUrl?: string;
|
|
26
|
+
}
|
|
27
|
+
export interface DatabaseLike {
|
|
28
|
+
connectionString: string;
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Creates a Prisma binding that attaches to a database container.
|
|
32
|
+
*
|
|
33
|
+
* Provides:
|
|
34
|
+
* - DATABASE_URL environment variable
|
|
35
|
+
* - Optional migration/generation on container start
|
|
36
|
+
* - Dockerfile transformations for Prisma commands
|
|
37
|
+
*
|
|
38
|
+
* @example
|
|
39
|
+
* ```typescript
|
|
40
|
+
* import { database, Container } from '@harpoon/core';
|
|
41
|
+
* import { PrismaBinding } from '@harpoon/prisma';
|
|
42
|
+
*
|
|
43
|
+
* const db = await database("postgres", {
|
|
44
|
+
* image: "postgres:15",
|
|
45
|
+
* env: { POSTGRES_PASSWORD: "secret" },
|
|
46
|
+
* });
|
|
47
|
+
*
|
|
48
|
+
* const app = await Container("app", {
|
|
49
|
+
* image: appImage,
|
|
50
|
+
* bindings: {
|
|
51
|
+
* DB: PrismaBinding(db, { migrate: true }),
|
|
52
|
+
* },
|
|
53
|
+
* });
|
|
54
|
+
* ```
|
|
55
|
+
*/
|
|
56
|
+
/**
|
|
57
|
+
* Extended binding interface that includes build-time capabilities.
|
|
58
|
+
* Unlike BuildBinding, this allows a resource to be attached.
|
|
59
|
+
*/
|
|
60
|
+
interface PrismaBindingResult<TDb> extends Binding<TDb, {
|
|
61
|
+
DATABASE_URL: string;
|
|
62
|
+
}> {
|
|
63
|
+
transformDockerfile(instructions: readonly DockerfileInstruction[], ctx: TransformContext): readonly DockerfileInstruction[];
|
|
64
|
+
patchConfig(ctx: PatchContext): Effect.Effect<PatchResult, Error>;
|
|
65
|
+
}
|
|
66
|
+
export declare function PrismaBinding<TDb extends DatabaseLike>(db: TDb, options?: PrismaBindingOptions): PrismaBindingResult<TDb>;
|
|
67
|
+
/**
|
|
68
|
+
* Register all Prisma patchers and transformers with Harpoon's registries.
|
|
69
|
+
*
|
|
70
|
+
* Call this once at application startup if you want the patchers and
|
|
71
|
+
* transformers to be available globally.
|
|
72
|
+
*
|
|
73
|
+
* @example
|
|
74
|
+
* ```typescript
|
|
75
|
+
* import { registerPrismaPlugins } from '@harpoon/prisma';
|
|
76
|
+
*
|
|
77
|
+
* registerPrismaPlugins();
|
|
78
|
+
* ```
|
|
79
|
+
*/
|
|
80
|
+
export declare function registerPrismaPlugins(): void;
|
|
81
|
+
export default PrismaBinding;
|
|
82
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAChC,OAAO,KAAK,EACV,OAAO,EACP,YAAY,EACZ,WAAW,EACX,qBAAqB,EACrB,gBAAgB,EAGjB,MAAM,eAAe,CAAC;AAGvB,OAAO,EAAE,qBAAqB,EAAE,MAAM,6BAA6B,CAAC;AACpE,OAAO,EACL,kBAAkB,EAClB,+BAA+B,EAC/B,gCAAgC,GACjC,MAAM,uBAAuB,CAAC;AAI/B,MAAM,WAAW,oBAAoB;IACnC,mDAAmD;IACnD,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,4CAA4C;IAC5C,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,6CAA6C;IAC7C,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,8DAA8D;IAC9D,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,mCAAmC;IACnC,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,YAAY;IAC3B,gBAAgB,EAAE,MAAM,CAAC;CAC1B;AAID;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH;;;GAGG;AACH,UAAU,mBAAmB,CAAC,GAAG,CAAE,SAAQ,OAAO,CAAC,GAAG,EAAE;IAAE,YAAY,EAAE,MAAM,CAAA;CAAE,CAAC;IAC/E,mBAAmB,CACjB,YAAY,EAAE,SAAS,qBAAqB,EAAE,EAC9C,GAAG,EAAE,gBAAgB,GACpB,SAAS,qBAAqB,EAAE,CAAC;IACpC,WAAW,CAAC,GAAG,EAAE,YAAY,GAAG,MAAM,CAAC,MAAM,CAAC,WAAW,EAAE,KAAK,CAAC,CAAC;CACnE;AAED,wBAAgB,aAAa,CAAC,GAAG,SAAS,YAAY,EACpD,EAAE,EAAE,GAAG,EACP,OAAO,GAAE,oBAAyB,GACjC,mBAAmB,CAAC,GAAG,CAAC,CA6E1B;AAID;;;;;;;;;;;;GAYG;AACH,wBAAgB,qBAAqB,IAAI,IAAI,CAiB5C;AAED,eAAe,aAAa,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @harpoon/prisma
|
|
3
|
+
*
|
|
4
|
+
* Prisma binding for Harpoon.
|
|
5
|
+
*
|
|
6
|
+
* Provides:
|
|
7
|
+
* - PrismaBinding: Attaches to database containers for connection strings and migrations
|
|
8
|
+
* - Config patchers for Prisma v7 LibSQL support
|
|
9
|
+
* - Dockerfile transformers for prisma commands in monorepos
|
|
10
|
+
*/
|
|
11
|
+
import { Effect } from 'effect';
|
|
12
|
+
// Re-export patchers and transformers
|
|
13
|
+
export { prismaV7LibSqlPatcher } from './patchers/prisma-v7-libsql';
|
|
14
|
+
export { prismaTransformers, prismaPackageManagerTransformer, prismaConditionalSeedTransformer, } from './transformers/prisma';
|
|
15
|
+
export function PrismaBinding(db, options = {}) {
|
|
16
|
+
const databaseUrl = options.databaseUrl ?? db.connectionString;
|
|
17
|
+
return {
|
|
18
|
+
type: 'prisma',
|
|
19
|
+
resource: db,
|
|
20
|
+
getEnv() {
|
|
21
|
+
return {
|
|
22
|
+
DATABASE_URL: databaseUrl,
|
|
23
|
+
};
|
|
24
|
+
},
|
|
25
|
+
onStart(_container) {
|
|
26
|
+
return Effect.gen(function* () {
|
|
27
|
+
if (options.generate) {
|
|
28
|
+
console.log(`[PrismaBinding] Running prisma generate...`);
|
|
29
|
+
// In a real implementation, this would exec into the container
|
|
30
|
+
// For now, this is a placeholder for the hook
|
|
31
|
+
}
|
|
32
|
+
if (options.migrate) {
|
|
33
|
+
console.log(`[PrismaBinding] Running prisma migrate deploy...`);
|
|
34
|
+
// In a real implementation, this would exec into the container
|
|
35
|
+
}
|
|
36
|
+
if (options.push) {
|
|
37
|
+
console.log(`[PrismaBinding] Running prisma db push...`);
|
|
38
|
+
// In a real implementation, this would exec into the container
|
|
39
|
+
}
|
|
40
|
+
});
|
|
41
|
+
},
|
|
42
|
+
// Build-time transformations (for when building images with Prisma)
|
|
43
|
+
transformDockerfile(instructions, ctx) {
|
|
44
|
+
// Import and apply prisma transformers
|
|
45
|
+
const { prismaTransformers } = require('./transformers/prisma');
|
|
46
|
+
let result = [...instructions];
|
|
47
|
+
for (const transformer of prismaTransformers) {
|
|
48
|
+
result = result.flatMap((inst) => {
|
|
49
|
+
if (!transformer.handlesTypes.includes(inst.type)) {
|
|
50
|
+
return [inst];
|
|
51
|
+
}
|
|
52
|
+
if (!transformer.matches(inst, ctx)) {
|
|
53
|
+
return [inst];
|
|
54
|
+
}
|
|
55
|
+
const transformed = transformer.transform(inst, ctx);
|
|
56
|
+
return Array.isArray(transformed) ? [...transformed] : [transformed];
|
|
57
|
+
});
|
|
58
|
+
}
|
|
59
|
+
return result;
|
|
60
|
+
},
|
|
61
|
+
patchConfig(ctx) {
|
|
62
|
+
const { prismaV7LibSqlPatcher } = require('./patchers/prisma-v7-libsql');
|
|
63
|
+
return Effect.gen(function* () {
|
|
64
|
+
const shouldApply = yield* prismaV7LibSqlPatcher.shouldApply(ctx);
|
|
65
|
+
if (!shouldApply) {
|
|
66
|
+
return {
|
|
67
|
+
applied: false,
|
|
68
|
+
modifiedFiles: [],
|
|
69
|
+
description: 'Prisma v7 not detected',
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
return yield* prismaV7LibSqlPatcher.apply(ctx);
|
|
73
|
+
});
|
|
74
|
+
},
|
|
75
|
+
};
|
|
76
|
+
}
|
|
77
|
+
// ============ Registration Helpers ============
|
|
78
|
+
/**
|
|
79
|
+
* Register all Prisma patchers and transformers with Harpoon's registries.
|
|
80
|
+
*
|
|
81
|
+
* Call this once at application startup if you want the patchers and
|
|
82
|
+
* transformers to be available globally.
|
|
83
|
+
*
|
|
84
|
+
* @example
|
|
85
|
+
* ```typescript
|
|
86
|
+
* import { registerPrismaPlugins } from '@harpoon/prisma';
|
|
87
|
+
*
|
|
88
|
+
* registerPrismaPlugins();
|
|
89
|
+
* ```
|
|
90
|
+
*/
|
|
91
|
+
export function registerPrismaPlugins() {
|
|
92
|
+
// Dynamic imports to avoid circular dependencies
|
|
93
|
+
const core = require('@harpoon/core');
|
|
94
|
+
const { prismaV7LibSqlPatcher } = require('./patchers/prisma-v7-libsql');
|
|
95
|
+
const { prismaTransformers } = require('./transformers/prisma');
|
|
96
|
+
// Register config patcher
|
|
97
|
+
core.registerConfigPatcher(prismaV7LibSqlPatcher);
|
|
98
|
+
// Register transformers
|
|
99
|
+
for (const transformer of prismaTransformers) {
|
|
100
|
+
core.registerTransformer(transformer);
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
export default PrismaBinding;
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Prisma V7 LibSQL Config Patcher
|
|
3
|
+
*
|
|
4
|
+
* Patches Prisma v7 libsql-config.ts to include authToken support.
|
|
5
|
+
* Also patches prisma.config.ts for LibSQL configuration.
|
|
6
|
+
*/
|
|
7
|
+
import type { ConfigPatcher } from '@harpoon/core';
|
|
8
|
+
/**
|
|
9
|
+
* Prisma V7 LibSQL patcher.
|
|
10
|
+
*
|
|
11
|
+
* Patches:
|
|
12
|
+
* - prisma/libsql-config.ts: Adds SQL_TOKEN/authToken support
|
|
13
|
+
* - prisma.config.ts: Ensures LibSQL configuration is correct
|
|
14
|
+
*/
|
|
15
|
+
export declare const prismaV7LibSqlPatcher: ConfigPatcher;
|
|
16
|
+
export default prismaV7LibSqlPatcher;
|
|
17
|
+
//# sourceMappingURL=prisma-v7-libsql.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"prisma-v7-libsql.d.ts","sourceRoot":"","sources":["../../src/patchers/prisma-v7-libsql.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAKH,OAAO,KAAK,EAAE,aAAa,EAA6B,MAAM,eAAe,CAAC;AAsE9E;;;;;;GAMG;AACH,eAAO,MAAM,qBAAqB,EAAE,aA0DnC,CAAC;AAEF,eAAe,qBAAqB,CAAC"}
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Prisma V7 LibSQL Config Patcher
|
|
3
|
+
*
|
|
4
|
+
* Patches Prisma v7 libsql-config.ts to include authToken support.
|
|
5
|
+
* Also patches prisma.config.ts for LibSQL configuration.
|
|
6
|
+
*/
|
|
7
|
+
import { Effect } from 'effect';
|
|
8
|
+
import * as fs from 'fs/promises';
|
|
9
|
+
import * as path from 'path';
|
|
10
|
+
import { ConfigPatchError } from '@harpoon/core';
|
|
11
|
+
// ============ Helper Functions ============
|
|
12
|
+
/**
|
|
13
|
+
* Check if the project uses Prisma v7.
|
|
14
|
+
*/
|
|
15
|
+
async function isPrismaV7(packageJsonPath) {
|
|
16
|
+
try {
|
|
17
|
+
const appPackageJson = JSON.parse(await fs.readFile(packageJsonPath, 'utf-8'));
|
|
18
|
+
const prismaVersion = appPackageJson.dependencies?.['prisma'] ||
|
|
19
|
+
appPackageJson.devDependencies?.['prisma'];
|
|
20
|
+
return !!(prismaVersion && prismaVersion.startsWith('^7.'));
|
|
21
|
+
}
|
|
22
|
+
catch {
|
|
23
|
+
return false;
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Patch the libsql-config.ts file to include authToken support.
|
|
28
|
+
*/
|
|
29
|
+
async function patchLibSqlConfig(libsqlConfigPath, appName) {
|
|
30
|
+
try {
|
|
31
|
+
const libsqlConfig = await fs.readFile(libsqlConfigPath, 'utf-8');
|
|
32
|
+
const patched = libsqlConfig.replace(/^(\s+)return \{\s*url: env\.DATABASE_URL,\s*\};$/m, (match, indent) => {
|
|
33
|
+
return `${indent}return {
|
|
34
|
+
${indent} url: env.DATABASE_URL,
|
|
35
|
+
${indent} ...(env.SQL_TOKEN ? { authToken: env.SQL_TOKEN } : {}),
|
|
36
|
+
${indent}};`;
|
|
37
|
+
});
|
|
38
|
+
if (patched !== libsqlConfig) {
|
|
39
|
+
await fs.writeFile(libsqlConfigPath, patched);
|
|
40
|
+
console.log(`[ConfigPatcher] Patched Prisma v7 libsql-config.ts for ${appName}`);
|
|
41
|
+
return { patched: true, path: libsqlConfigPath };
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
catch {
|
|
45
|
+
// File doesn't exist or error, skip silently
|
|
46
|
+
}
|
|
47
|
+
return { patched: false, path: libsqlConfigPath };
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Check if prisma.config.ts needs patching.
|
|
51
|
+
*/
|
|
52
|
+
async function checkPrismaConfig(prismaConfigPath) {
|
|
53
|
+
try {
|
|
54
|
+
const prismaConfig = await fs.readFile(prismaConfigPath, 'utf-8');
|
|
55
|
+
// Check if it's already using LibSQL properly
|
|
56
|
+
return !prismaConfig.includes('new PrismaLibSql(createLibSqlConfig())');
|
|
57
|
+
}
|
|
58
|
+
catch {
|
|
59
|
+
return false;
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
// ============ Patcher Implementation ============
|
|
63
|
+
/**
|
|
64
|
+
* Prisma V7 LibSQL patcher.
|
|
65
|
+
*
|
|
66
|
+
* Patches:
|
|
67
|
+
* - prisma/libsql-config.ts: Adds SQL_TOKEN/authToken support
|
|
68
|
+
* - prisma.config.ts: Ensures LibSQL configuration is correct
|
|
69
|
+
*/
|
|
70
|
+
export const prismaV7LibSqlPatcher = {
|
|
71
|
+
name: 'prisma-v7-libsql',
|
|
72
|
+
description: 'Patches Prisma v7 LibSQL configuration for authToken support',
|
|
73
|
+
shouldApply: (ctx) => Effect.tryPromise({
|
|
74
|
+
try: () => isPrismaV7(ctx.packageJsonPath),
|
|
75
|
+
catch: (error) => new ConfigPatchError('prisma-v7-libsql', `Failed to check Prisma version: ${error}`, error instanceof Error ? error : undefined),
|
|
76
|
+
}),
|
|
77
|
+
apply: (ctx) => Effect.tryPromise({
|
|
78
|
+
try: async () => {
|
|
79
|
+
const modifiedFiles = [];
|
|
80
|
+
// Patch libsql-config.ts
|
|
81
|
+
const libsqlConfigPath = path.join(ctx.appDir, 'prisma', 'libsql-config.ts');
|
|
82
|
+
const libsqlResult = await patchLibSqlConfig(libsqlConfigPath, ctx.appName);
|
|
83
|
+
if (libsqlResult.patched) {
|
|
84
|
+
modifiedFiles.push(libsqlResult.path);
|
|
85
|
+
}
|
|
86
|
+
// Check prisma.config.ts (only report, don't modify)
|
|
87
|
+
const prismaConfigPath = path.join(ctx.appDir, 'prisma.config.ts');
|
|
88
|
+
const needsPrismaPatch = await checkPrismaConfig(prismaConfigPath);
|
|
89
|
+
if (needsPrismaPatch) {
|
|
90
|
+
console.log(`[ConfigPatcher] prisma.config.ts may need manual review for ${ctx.appName}`);
|
|
91
|
+
}
|
|
92
|
+
return {
|
|
93
|
+
applied: modifiedFiles.length > 0,
|
|
94
|
+
modifiedFiles: Object.freeze(modifiedFiles),
|
|
95
|
+
description: modifiedFiles.length > 0
|
|
96
|
+
? `Patched ${modifiedFiles.length} file(s) for Prisma v7 LibSQL support`
|
|
97
|
+
: 'No files needed patching',
|
|
98
|
+
};
|
|
99
|
+
},
|
|
100
|
+
catch: (error) => new ConfigPatchError('prisma-v7-libsql', `Failed to apply Prisma v7 LibSQL patches: ${error}`, error instanceof Error ? error : undefined),
|
|
101
|
+
}),
|
|
102
|
+
};
|
|
103
|
+
export default prismaV7LibSqlPatcher;
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Prisma Dockerfile Transformers
|
|
3
|
+
*
|
|
4
|
+
* Transforms for Prisma-related RUN commands in Dockerfiles.
|
|
5
|
+
* Handles prisma:generate, prisma:seed, and exec prisma commands.
|
|
6
|
+
*
|
|
7
|
+
* Package-manager agnostic: supports npm, yarn, pnpm, and bun.
|
|
8
|
+
*/
|
|
9
|
+
import type { InstructionTransformer } from '@harpoon/core';
|
|
10
|
+
/**
|
|
11
|
+
* Transforms package manager prisma commands to include cd to app directory.
|
|
12
|
+
* Handles: prisma:generate, prisma:seed, exec prisma, run build
|
|
13
|
+
* Supports: npm, yarn, pnpm, bun
|
|
14
|
+
*/
|
|
15
|
+
export declare const prismaPackageManagerTransformer: InstructionTransformer;
|
|
16
|
+
/**
|
|
17
|
+
* Transforms conditional prisma:seed commands.
|
|
18
|
+
* Handles: if [ "$ENV" = "..." ]; then {npm|yarn|pnpm|bun} prisma:seed; fi
|
|
19
|
+
*/
|
|
20
|
+
export declare const prismaConditionalSeedTransformer: InstructionTransformer;
|
|
21
|
+
/**
|
|
22
|
+
* All Prisma transformers for easy registration.
|
|
23
|
+
*/
|
|
24
|
+
export declare const prismaTransformers: readonly InstructionTransformer[];
|
|
25
|
+
export default prismaTransformers;
|
|
26
|
+
//# sourceMappingURL=prisma.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"prisma.d.ts","sourceRoot":"","sources":["../../src/transformers/prisma.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,sBAAsB,EAA2C,MAAM,eAAe,CAAC;AA4BrG;;;;GAIG;AACH,eAAO,MAAM,+BAA+B,EAAE,sBA0B7C,CAAC;AAOF;;;GAGG;AACH,eAAO,MAAM,gCAAgC,EAAE,sBA0B9C,CAAC;AAIF;;GAEG;AACH,eAAO,MAAM,kBAAkB,EAAE,SAAS,sBAAsB,EAG9D,CAAC;AAEH,eAAe,kBAAkB,CAAC"}
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Prisma Dockerfile Transformers
|
|
3
|
+
*
|
|
4
|
+
* Transforms for Prisma-related RUN commands in Dockerfiles.
|
|
5
|
+
* Handles prisma:generate, prisma:seed, and exec prisma commands.
|
|
6
|
+
*
|
|
7
|
+
* Package-manager agnostic: supports npm, yarn, pnpm, and bun.
|
|
8
|
+
*/
|
|
9
|
+
import { replaceInstruction } from '@harpoon/core';
|
|
10
|
+
// ============ Helper Functions ============
|
|
11
|
+
/**
|
|
12
|
+
* Package manager prefixes we recognize.
|
|
13
|
+
*/
|
|
14
|
+
const PACKAGE_MANAGERS = ['npm', 'yarn', 'pnpm', 'bun'];
|
|
15
|
+
/**
|
|
16
|
+
* Check if instruction uses a known package manager.
|
|
17
|
+
*/
|
|
18
|
+
function isPackageManagerCommand(inst) {
|
|
19
|
+
const firstArg = inst.args[0] || '';
|
|
20
|
+
return PACKAGE_MANAGERS.some(pm => firstArg.startsWith(pm));
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Check if command already has cd to app directory.
|
|
24
|
+
*/
|
|
25
|
+
function alreadyHasCd(inst, appName) {
|
|
26
|
+
const originalCmd = inst.original.replace(/^RUN\s+/, '');
|
|
27
|
+
return originalCmd.includes(`cd apps/${appName}`);
|
|
28
|
+
}
|
|
29
|
+
// ============ Transformers ============
|
|
30
|
+
/**
|
|
31
|
+
* Transforms package manager prisma commands to include cd to app directory.
|
|
32
|
+
* Handles: prisma:generate, prisma:seed, exec prisma, run build
|
|
33
|
+
* Supports: npm, yarn, pnpm, bun
|
|
34
|
+
*/
|
|
35
|
+
export const prismaPackageManagerTransformer = {
|
|
36
|
+
name: 'prisma-package-manager',
|
|
37
|
+
description: 'Transforms package manager prisma commands for monorepo structure',
|
|
38
|
+
handlesTypes: ['RUN'],
|
|
39
|
+
matches: (inst, ctx) => {
|
|
40
|
+
if (!isPackageManagerCommand(inst))
|
|
41
|
+
return false;
|
|
42
|
+
if (alreadyHasCd(inst, ctx.appName))
|
|
43
|
+
return false;
|
|
44
|
+
const runCmd = inst.args.join(' ');
|
|
45
|
+
return (runCmd.includes('prisma:generate') ||
|
|
46
|
+
runCmd.includes('prisma:seed') ||
|
|
47
|
+
runCmd.includes('exec prisma') ||
|
|
48
|
+
runCmd.includes('run build'));
|
|
49
|
+
},
|
|
50
|
+
transform: (inst, ctx) => {
|
|
51
|
+
const originalCmd = inst.original.replace(/^RUN\s+/, '');
|
|
52
|
+
return replaceInstruction(inst, `RUN cd apps/${ctx.appName} && ${originalCmd}`, Object.freeze([`cd apps/${ctx.appName} && ${originalCmd}`]));
|
|
53
|
+
},
|
|
54
|
+
};
|
|
55
|
+
/**
|
|
56
|
+
* Pattern to match any package manager with prisma:seed.
|
|
57
|
+
*/
|
|
58
|
+
const PRISMA_SEED_PATTERN = /(npm|yarn|pnpm|bun)\s+(run\s+)?prisma:seed/;
|
|
59
|
+
/**
|
|
60
|
+
* Transforms conditional prisma:seed commands.
|
|
61
|
+
* Handles: if [ "$ENV" = "..." ]; then {npm|yarn|pnpm|bun} prisma:seed; fi
|
|
62
|
+
*/
|
|
63
|
+
export const prismaConditionalSeedTransformer = {
|
|
64
|
+
name: 'prisma-conditional-seed',
|
|
65
|
+
description: 'Transforms conditional prisma:seed commands for monorepo structure',
|
|
66
|
+
handlesTypes: ['RUN'],
|
|
67
|
+
matches: (inst, ctx) => {
|
|
68
|
+
const originalCmd = inst.original.replace(/^RUN\s+/, '');
|
|
69
|
+
return (PRISMA_SEED_PATTERN.test(originalCmd) &&
|
|
70
|
+
!originalCmd.includes(`cd apps/${ctx.appName}`));
|
|
71
|
+
},
|
|
72
|
+
transform: (inst, ctx) => {
|
|
73
|
+
const originalCmd = inst.original.replace(/^RUN\s+/, '');
|
|
74
|
+
// Replace any package manager prisma:seed with cd + command
|
|
75
|
+
const transformedCmd = originalCmd.replace(new RegExp(PRISMA_SEED_PATTERN.source, 'g'), `cd apps/${ctx.appName} && $&`);
|
|
76
|
+
return replaceInstruction(inst, `RUN ${transformedCmd}`, Object.freeze([transformedCmd]));
|
|
77
|
+
},
|
|
78
|
+
};
|
|
79
|
+
// ============ Exports ============
|
|
80
|
+
/**
|
|
81
|
+
* All Prisma transformers for easy registration.
|
|
82
|
+
*/
|
|
83
|
+
export const prismaTransformers = Object.freeze([
|
|
84
|
+
prismaPackageManagerTransformer,
|
|
85
|
+
prismaConditionalSeedTransformer,
|
|
86
|
+
]);
|
|
87
|
+
export default prismaTransformers;
|
package/package.json
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@docker-harpoon/prisma",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"license": "MIT",
|
|
5
|
+
"description": "Prisma binding for Harpoon - database migrations and Dockerfile transformations",
|
|
6
|
+
"type": "module",
|
|
7
|
+
"main": "./dist/index.js",
|
|
8
|
+
"types": "./dist/index.d.ts",
|
|
9
|
+
"exports": {
|
|
10
|
+
".": {
|
|
11
|
+
"types": "./dist/index.d.ts",
|
|
12
|
+
"import": "./dist/index.js"
|
|
13
|
+
}
|
|
14
|
+
},
|
|
15
|
+
"files": ["dist"],
|
|
16
|
+
"scripts": {
|
|
17
|
+
"build": "tsc",
|
|
18
|
+
"typecheck": "tsc --noEmit"
|
|
19
|
+
},
|
|
20
|
+
"dependencies": {
|
|
21
|
+
"effect": "^3.19.14"
|
|
22
|
+
},
|
|
23
|
+
"peerDependencies": {
|
|
24
|
+
"@docker-harpoon/core": ">=0.1.0",
|
|
25
|
+
"bun": ">=1.0.0"
|
|
26
|
+
}
|
|
27
|
+
}
|