@kernlang/express 3.1.6 → 3.1.8
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/express-middleware.d.ts +6 -0
- package/dist/express-middleware.js +77 -0
- package/dist/express-middleware.js.map +1 -0
- package/dist/express-portable.d.ts +5 -0
- package/dist/express-portable.js +161 -0
- package/dist/express-portable.js.map +1 -0
- package/dist/express-prisma.d.ts +17 -0
- package/dist/express-prisma.js +174 -0
- package/dist/express-prisma.js.map +1 -0
- package/dist/express-route.d.ts +3 -0
- package/dist/express-route.js +269 -0
- package/dist/express-route.js.map +1 -0
- package/dist/express-stream.d.ts +5 -0
- package/dist/express-stream.js +191 -0
- package/dist/express-stream.js.map +1 -0
- package/dist/express-types.d.ts +42 -0
- package/dist/express-types.js +22 -0
- package/dist/express-types.js.map +1 -0
- package/dist/express-utils.d.ts +18 -0
- package/dist/express-utils.js +166 -0
- package/dist/express-utils.js.map +1 -0
- package/dist/transpiler-express.d.ts +2 -2
- package/dist/transpiler-express.js +270 -968
- package/dist/transpiler-express.js.map +1 -1
- package/package.json +2 -2
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { GeneratedArtifact, IRNode } from '@kernlang/core';
|
|
2
|
+
import type { MiddlewareArtifactRef, MiddlewareUsage, SchemaShape } from './express-types.js';
|
|
3
|
+
export declare function buildSchema(node?: IRNode): SchemaShape;
|
|
4
|
+
export declare function buildMiddlewareArtifact(node: IRNode, exportName: string): GeneratedArtifact;
|
|
5
|
+
export declare function ensureCustomMiddlewareArtifact(node: IRNode, middlewareArtifacts: Map<string, MiddlewareArtifactRef>): MiddlewareArtifactRef;
|
|
6
|
+
export declare function resolveMiddlewareUsage(node: IRNode, middlewareArtifacts: Map<string, MiddlewareArtifactRef>, importPrefix: string, securityLevel?: 'strict' | 'relaxed'): MiddlewareUsage;
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import { getFirstChild, getProps } from '@kernlang/core';
|
|
2
|
+
import { indentBlock, middlewareExportName, slugify } from './express-utils.js';
|
|
3
|
+
export function buildSchema(node) {
|
|
4
|
+
if (!node)
|
|
5
|
+
return {};
|
|
6
|
+
const props = getProps(node);
|
|
7
|
+
const schema = {};
|
|
8
|
+
if (typeof props.body === 'string')
|
|
9
|
+
schema.body = props.body;
|
|
10
|
+
if (typeof props.params === 'string')
|
|
11
|
+
schema.params = props.params;
|
|
12
|
+
if (typeof props.query === 'string')
|
|
13
|
+
schema.query = props.query;
|
|
14
|
+
if (typeof props.response === 'string')
|
|
15
|
+
schema.response = props.response;
|
|
16
|
+
return schema;
|
|
17
|
+
}
|
|
18
|
+
export function buildMiddlewareArtifact(node, exportName) {
|
|
19
|
+
const handlerNode = getFirstChild(node, 'handler');
|
|
20
|
+
const handlerProps = handlerNode ? getProps(handlerNode) : {};
|
|
21
|
+
const handlerCode = typeof handlerProps.code === 'string' ? String(handlerProps.code) : '';
|
|
22
|
+
const lines = [];
|
|
23
|
+
lines.push(`import type { NextFunction, Request, Response } from 'express';`);
|
|
24
|
+
lines.push('');
|
|
25
|
+
lines.push(`export function ${exportName}(req: Request, res: Response, next: NextFunction): void {`);
|
|
26
|
+
if (handlerCode) {
|
|
27
|
+
lines.push(...indentBlock(handlerCode, ' '));
|
|
28
|
+
}
|
|
29
|
+
else {
|
|
30
|
+
lines.push(' next();');
|
|
31
|
+
}
|
|
32
|
+
lines.push('}');
|
|
33
|
+
const name = String(getProps(node).name || exportName);
|
|
34
|
+
return {
|
|
35
|
+
path: `middleware/${slugify(name)}.ts`,
|
|
36
|
+
content: lines.join('\n'),
|
|
37
|
+
type: 'middleware',
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
export function ensureCustomMiddlewareArtifact(node, middlewareArtifacts) {
|
|
41
|
+
const name = String(getProps(node).name || 'middleware');
|
|
42
|
+
const fileBase = slugify(name);
|
|
43
|
+
const existing = middlewareArtifacts.get(fileBase);
|
|
44
|
+
if (existing)
|
|
45
|
+
return existing;
|
|
46
|
+
const exportName = middlewareExportName(node);
|
|
47
|
+
const artifact = buildMiddlewareArtifact(node, exportName);
|
|
48
|
+
const created = { artifact, exportName, fileBase };
|
|
49
|
+
middlewareArtifacts.set(fileBase, created);
|
|
50
|
+
return created;
|
|
51
|
+
}
|
|
52
|
+
export function resolveMiddlewareUsage(node, middlewareArtifacts, importPrefix, securityLevel) {
|
|
53
|
+
const props = getProps(node);
|
|
54
|
+
const name = String(props.name || 'middleware');
|
|
55
|
+
if (name === 'cors') {
|
|
56
|
+
const invocation = securityLevel === 'strict'
|
|
57
|
+
? `cors({ origin: process.env.CORS_ORIGINS ? process.env.CORS_ORIGINS.split(',').map((origin: string) => origin.trim()).filter(Boolean) : false, credentials: true })`
|
|
58
|
+
: 'cors()';
|
|
59
|
+
return { importLine: `import cors from 'cors';`, invocation };
|
|
60
|
+
}
|
|
61
|
+
if (name === 'json') {
|
|
62
|
+
const invocation = securityLevel === 'relaxed' ? 'express.json()' : `express.json({ limit: '1mb' })`;
|
|
63
|
+
return { invocation };
|
|
64
|
+
}
|
|
65
|
+
if (name === 'rateLimit' || name === 'rate-limit' || name === 'rateLimiter') {
|
|
66
|
+
return {
|
|
67
|
+
importLine: `import rateLimit from 'express-rate-limit';`,
|
|
68
|
+
invocation: `rateLimit({ windowMs: 15 * 60 * 1000, max: 100 })`,
|
|
69
|
+
};
|
|
70
|
+
}
|
|
71
|
+
const artifact = ensureCustomMiddlewareArtifact(node, middlewareArtifacts);
|
|
72
|
+
return {
|
|
73
|
+
importLine: `import { ${artifact.exportName} } from '${importPrefix}middleware/${artifact.fileBase}.js';`,
|
|
74
|
+
invocation: artifact.exportName,
|
|
75
|
+
};
|
|
76
|
+
}
|
|
77
|
+
//# sourceMappingURL=express-middleware.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"express-middleware.js","sourceRoot":"","sources":["../src/express-middleware.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { IRNode } from '@kernlang/core';
|
|
2
|
+
export declare function rewriteExpressExpr(expr: string, path: string): string;
|
|
3
|
+
export declare function extractExprCode(prop: unknown): string;
|
|
4
|
+
export declare function generatePortableChildExpress(child: IRNode, indent: string, path: string): string[];
|
|
5
|
+
export declare function generatePortableHandlerExpress(routeNode: IRNode, indent: string, path: string): string[];
|
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
import { getChildren, getFirstChild, getProps } from '@kernlang/core';
|
|
2
|
+
import { derivePathParams, escapeSingleQuotes, generateRespondExpress, indentBlock } from './express-utils.js';
|
|
3
|
+
// ── Portable request reference rewriting ──────────────────────────────────
|
|
4
|
+
export function rewriteExpressExpr(expr, path) {
|
|
5
|
+
const _pathParams = derivePathParams(path);
|
|
6
|
+
let result = expr;
|
|
7
|
+
// params.X → req.params.X
|
|
8
|
+
result = result.replace(/\bparams\.([A-Za-z_]\w*)/g, 'req.params.$1');
|
|
9
|
+
// body.X → req.body.X
|
|
10
|
+
result = result.replace(/\bbody\.([A-Za-z_]\w*)/g, 'req.body.$1');
|
|
11
|
+
// query.X → req.query.X
|
|
12
|
+
result = result.replace(/\bquery\.([A-Za-z_]\w*)/g, 'req.query.$1');
|
|
13
|
+
// headers.X → req.headers['X']
|
|
14
|
+
result = result.replace(/\bheaders\.([A-Za-z_][\w-]*)/g, (_m, key) => `req.headers['${key}']`);
|
|
15
|
+
// effectName.result → effectName (effect variables hold the result directly)
|
|
16
|
+
result = result.replace(/\b([A-Za-z_]\w*)\.result\b/g, '$1');
|
|
17
|
+
return result;
|
|
18
|
+
}
|
|
19
|
+
// ── Portable handler generation (derive → guard → handler → respond) ─────
|
|
20
|
+
export function extractExprCode(prop) {
|
|
21
|
+
if (typeof prop === 'object' && prop !== null && prop.__expr)
|
|
22
|
+
return prop.code;
|
|
23
|
+
return typeof prop === 'string' ? prop : '';
|
|
24
|
+
}
|
|
25
|
+
export function generatePortableChildExpress(child, indent, path) {
|
|
26
|
+
const lines = [];
|
|
27
|
+
const p = getProps(child);
|
|
28
|
+
switch (child.type) {
|
|
29
|
+
case 'derive': {
|
|
30
|
+
const name = String(p.name || '');
|
|
31
|
+
const exprCode = extractExprCode(p.expr);
|
|
32
|
+
if (name && exprCode) {
|
|
33
|
+
lines.push(`${indent}const ${name} = ${rewriteExpressExpr(exprCode, path)};`);
|
|
34
|
+
}
|
|
35
|
+
break;
|
|
36
|
+
}
|
|
37
|
+
case 'guard': {
|
|
38
|
+
const name = String(p.name || '');
|
|
39
|
+
const exprCode = extractExprCode(p.expr);
|
|
40
|
+
const elseStatus = p.else ? parseInt(String(p.else), 10) : 404;
|
|
41
|
+
const elseMessage = typeof p.message === 'string' ? p.message : name ? `${name} guard failed` : 'Guard failed';
|
|
42
|
+
if (exprCode) {
|
|
43
|
+
lines.push(`${indent}if (!(${rewriteExpressExpr(exprCode, path)})) {`);
|
|
44
|
+
lines.push(`${indent} return res.status(${elseStatus}).json({ error: '${escapeSingleQuotes(elseMessage)}' });`);
|
|
45
|
+
lines.push(`${indent}}`);
|
|
46
|
+
}
|
|
47
|
+
break;
|
|
48
|
+
}
|
|
49
|
+
case 'handler': {
|
|
50
|
+
const code = String(p.code || '');
|
|
51
|
+
if (code)
|
|
52
|
+
lines.push(...indentBlock(code, indent));
|
|
53
|
+
break;
|
|
54
|
+
}
|
|
55
|
+
case 'respond': {
|
|
56
|
+
// Clone props to avoid mutating shared AST, then rewrite portable refs
|
|
57
|
+
const clonedRespond = { ...child, props: { ...child.props } };
|
|
58
|
+
if (clonedRespond.props.json)
|
|
59
|
+
clonedRespond.props.json = rewriteExpressExpr(String(clonedRespond.props.json), path);
|
|
60
|
+
if (clonedRespond.props.text)
|
|
61
|
+
clonedRespond.props.text = rewriteExpressExpr(String(clonedRespond.props.text), path);
|
|
62
|
+
lines.push(...generateRespondExpress(clonedRespond, indent));
|
|
63
|
+
break;
|
|
64
|
+
}
|
|
65
|
+
case 'branch': {
|
|
66
|
+
const on = rewriteExpressExpr(String(p.on || ''), path);
|
|
67
|
+
const paths = getChildren(child, 'path');
|
|
68
|
+
for (let i = 0; i < paths.length; i++) {
|
|
69
|
+
const pathNode = paths[i];
|
|
70
|
+
const pp = getProps(pathNode);
|
|
71
|
+
const value = String(pp.value || '');
|
|
72
|
+
const keyword = i === 0 ? 'if' : 'else if';
|
|
73
|
+
lines.push(`${indent}${keyword} (${on} === '${escapeSingleQuotes(value)}') {`);
|
|
74
|
+
// Recurse into path children
|
|
75
|
+
for (const pathChild of pathNode.children || []) {
|
|
76
|
+
lines.push(...generatePortableChildExpress(pathChild, `${indent} `, path));
|
|
77
|
+
}
|
|
78
|
+
lines.push(`${indent}}`);
|
|
79
|
+
}
|
|
80
|
+
break;
|
|
81
|
+
}
|
|
82
|
+
case 'each': {
|
|
83
|
+
const name = String(p.name || 'item');
|
|
84
|
+
const collection = rewriteExpressExpr(extractExprCode(p.in) || String(p.in || ''), path);
|
|
85
|
+
const index = p.index ? String(p.index) : undefined;
|
|
86
|
+
if (index) {
|
|
87
|
+
lines.push(`${indent}for (const [${index}, ${name}] of (${collection}).entries()) {`);
|
|
88
|
+
}
|
|
89
|
+
else {
|
|
90
|
+
lines.push(`${indent}for (const ${name} of ${collection}) {`);
|
|
91
|
+
}
|
|
92
|
+
for (const eachChild of child.children || []) {
|
|
93
|
+
lines.push(...generatePortableChildExpress(eachChild, `${indent} `, path));
|
|
94
|
+
}
|
|
95
|
+
lines.push(`${indent}}`);
|
|
96
|
+
break;
|
|
97
|
+
}
|
|
98
|
+
case 'collect': {
|
|
99
|
+
const name = String(p.name || '');
|
|
100
|
+
const from = rewriteExpressExpr(String(p.from || ''), path);
|
|
101
|
+
const where = p.where ? extractExprCode(p.where) : undefined;
|
|
102
|
+
const limit = p.limit ? String(p.limit) : undefined;
|
|
103
|
+
const order = p.order ? rewriteExpressExpr(extractExprCode(p.order) || String(p.order), path) : undefined;
|
|
104
|
+
let chain = from;
|
|
105
|
+
if (where)
|
|
106
|
+
chain += `.filter(item => ${rewriteExpressExpr(where, path)})`;
|
|
107
|
+
if (order)
|
|
108
|
+
chain += `.sort((a, b) => ${order})`;
|
|
109
|
+
if (limit)
|
|
110
|
+
chain += `.slice(0, ${limit})`;
|
|
111
|
+
if (name)
|
|
112
|
+
lines.push(`${indent}const ${name} = ${chain};`);
|
|
113
|
+
break;
|
|
114
|
+
}
|
|
115
|
+
case 'effect': {
|
|
116
|
+
const effectName = String(p.name || 'effect');
|
|
117
|
+
const triggerNode = getFirstChild(child, 'trigger');
|
|
118
|
+
const recoverNode = getFirstChild(child, 'recover');
|
|
119
|
+
const triggerProps = triggerNode ? getProps(triggerNode) : {};
|
|
120
|
+
const triggerExpr = extractExprCode(triggerProps.expr) || String(triggerProps.query || triggerProps.url || triggerProps.call || '');
|
|
121
|
+
const retryCount = recoverNode ? parseInt(String(getProps(recoverNode).retry || '0'), 10) : 0;
|
|
122
|
+
const fallback = recoverNode ? String(getProps(recoverNode).fallback || 'null') : 'null';
|
|
123
|
+
if (retryCount > 0) {
|
|
124
|
+
lines.push(`${indent}let ${effectName} = ${fallback};`);
|
|
125
|
+
lines.push(`${indent}for (let _attempt = 0; _attempt < ${retryCount}; _attempt++) {`);
|
|
126
|
+
lines.push(`${indent} try {`);
|
|
127
|
+
lines.push(`${indent} ${effectName} = ${rewriteExpressExpr(triggerExpr, path)};`);
|
|
128
|
+
lines.push(`${indent} break;`);
|
|
129
|
+
lines.push(`${indent} } catch (_err) {`);
|
|
130
|
+
lines.push(`${indent} if (_attempt === ${retryCount - 1}) ${effectName} = ${fallback};`);
|
|
131
|
+
lines.push(`${indent} }`);
|
|
132
|
+
lines.push(`${indent}}`);
|
|
133
|
+
}
|
|
134
|
+
else {
|
|
135
|
+
lines.push(`${indent}let ${effectName} = ${fallback};`);
|
|
136
|
+
lines.push(`${indent}try {`);
|
|
137
|
+
lines.push(`${indent} ${effectName} = ${rewriteExpressExpr(triggerExpr, path)};`);
|
|
138
|
+
lines.push(`${indent}} catch (_err) {`);
|
|
139
|
+
lines.push(`${indent} ${effectName} = ${fallback};`);
|
|
140
|
+
lines.push(`${indent}}`);
|
|
141
|
+
}
|
|
142
|
+
break;
|
|
143
|
+
}
|
|
144
|
+
default:
|
|
145
|
+
break;
|
|
146
|
+
}
|
|
147
|
+
return lines;
|
|
148
|
+
}
|
|
149
|
+
export function generatePortableHandlerExpress(routeNode, indent, path) {
|
|
150
|
+
const lines = [];
|
|
151
|
+
const children = routeNode.children || [];
|
|
152
|
+
// Walk all route children in document order — portable nodes are emitted inline
|
|
153
|
+
const PORTABLE_TYPES = new Set(['derive', 'guard', 'handler', 'respond', 'branch', 'each', 'collect', 'effect']);
|
|
154
|
+
for (const child of children) {
|
|
155
|
+
if (PORTABLE_TYPES.has(child.type)) {
|
|
156
|
+
lines.push(...generatePortableChildExpress(child, indent, path));
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
return lines;
|
|
160
|
+
}
|
|
161
|
+
//# sourceMappingURL=express-portable.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"express-portable.js","sourceRoot":"","sources":["../src/express-portable.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { GeneratedArtifact, IRNode, ResolvedKernConfig } from '@kernlang/core';
|
|
2
|
+
import type { CoreArtifactRef } from './express-types.js';
|
|
3
|
+
/** Map core node type → output directory + artifact type. */
|
|
4
|
+
export declare function coreNodeMeta(type: string): {
|
|
5
|
+
dir: string;
|
|
6
|
+
artifactType: GeneratedArtifact['type'];
|
|
7
|
+
};
|
|
8
|
+
export declare const TOP_LEVEL_CORE: Set<string>;
|
|
9
|
+
/** Map KERN column type to Prisma schema type. Strips @db.* decorators for non-PostgreSQL providers. */
|
|
10
|
+
export declare function mapColumnToPrisma(kernType: string, provider: string): string;
|
|
11
|
+
/**
|
|
12
|
+
* Build a complete schema.prisma file from model IR nodes.
|
|
13
|
+
* This runs ONLY in Express — not in the shared codegen path.
|
|
14
|
+
*/
|
|
15
|
+
export declare function formatPrismaDefault(value: string): string;
|
|
16
|
+
export declare function buildPrismaArtifact(modelNodes: IRNode[], config?: ResolvedKernConfig): GeneratedArtifact | null;
|
|
17
|
+
export declare function buildCoreArtifact(node: IRNode): CoreArtifactRef;
|
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
import { generateCoreNode, getChildren, mapSemanticType, propsOf } from '@kernlang/core';
|
|
2
|
+
import { slugify } from './express-utils.js';
|
|
3
|
+
// ── Core node artifact mapping ────────────────────────────────────────────
|
|
4
|
+
/** Map core node type → output directory + artifact type. */
|
|
5
|
+
export function coreNodeMeta(type) {
|
|
6
|
+
switch (type) {
|
|
7
|
+
case 'interface':
|
|
8
|
+
return { dir: 'models', artifactType: 'model' };
|
|
9
|
+
case 'model':
|
|
10
|
+
return { dir: 'models', artifactType: 'model' };
|
|
11
|
+
case 'repository':
|
|
12
|
+
return { dir: 'models', artifactType: 'repository' };
|
|
13
|
+
case 'cache':
|
|
14
|
+
return { dir: 'lib', artifactType: 'lib' };
|
|
15
|
+
case 'dependency':
|
|
16
|
+
return { dir: 'lib', artifactType: 'lib' };
|
|
17
|
+
case 'service':
|
|
18
|
+
return { dir: 'services', artifactType: 'service' };
|
|
19
|
+
case 'type':
|
|
20
|
+
return { dir: 'types', artifactType: 'types' };
|
|
21
|
+
case 'config':
|
|
22
|
+
return { dir: 'config', artifactType: 'config' };
|
|
23
|
+
case 'error':
|
|
24
|
+
return { dir: 'errors', artifactType: 'error' };
|
|
25
|
+
default:
|
|
26
|
+
return { dir: 'lib', artifactType: 'lib' };
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
export const TOP_LEVEL_CORE = new Set([
|
|
30
|
+
'type',
|
|
31
|
+
'interface',
|
|
32
|
+
'service',
|
|
33
|
+
'fn',
|
|
34
|
+
'machine',
|
|
35
|
+
'error',
|
|
36
|
+
'module',
|
|
37
|
+
'config',
|
|
38
|
+
'store',
|
|
39
|
+
'event',
|
|
40
|
+
'const',
|
|
41
|
+
// Data layer
|
|
42
|
+
'model',
|
|
43
|
+
'repository',
|
|
44
|
+
'cache',
|
|
45
|
+
'dependency',
|
|
46
|
+
// Backend infrastructure
|
|
47
|
+
'job',
|
|
48
|
+
'storage',
|
|
49
|
+
'email',
|
|
50
|
+
]);
|
|
51
|
+
// ── Prisma Schema Artifact ───────────────────────────────────────────────
|
|
52
|
+
/** Map KERN column type to Prisma schema type. Strips @db.* decorators for non-PostgreSQL providers. */
|
|
53
|
+
export function mapColumnToPrisma(kernType, provider) {
|
|
54
|
+
const mapped = mapSemanticType(kernType, 'prisma');
|
|
55
|
+
if (provider !== 'postgresql') {
|
|
56
|
+
return mapped.replace(/ @db\.\w+/g, '');
|
|
57
|
+
}
|
|
58
|
+
return mapped;
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Build a complete schema.prisma file from model IR nodes.
|
|
62
|
+
* This runs ONLY in Express — not in the shared codegen path.
|
|
63
|
+
*/
|
|
64
|
+
export function formatPrismaDefault(value) {
|
|
65
|
+
const trimmed = value.trim();
|
|
66
|
+
if (/^-?\d+(?:\.\d+)?$/.test(trimmed))
|
|
67
|
+
return trimmed;
|
|
68
|
+
if (trimmed === 'true' || trimmed === 'false')
|
|
69
|
+
return trimmed;
|
|
70
|
+
if (trimmed === 'uuid4()' || trimmed === 'uuid4')
|
|
71
|
+
return 'uuid()';
|
|
72
|
+
if (trimmed === 'now()' || trimmed === 'now')
|
|
73
|
+
return 'now()';
|
|
74
|
+
if (trimmed === 'autoincrement()' || trimmed === 'autoincrement')
|
|
75
|
+
return 'autoincrement()';
|
|
76
|
+
if (/^[A-Za-z_]\w*\([^)]*\)$/.test(trimmed))
|
|
77
|
+
return trimmed;
|
|
78
|
+
return `"${trimmed}"`;
|
|
79
|
+
}
|
|
80
|
+
export function buildPrismaArtifact(modelNodes, config) {
|
|
81
|
+
if (modelNodes.length === 0)
|
|
82
|
+
return null;
|
|
83
|
+
const provider = config?.express?.prisma?.provider ?? 'postgresql';
|
|
84
|
+
const lines = [
|
|
85
|
+
'// Generated by KERN. Run migrations:',
|
|
86
|
+
'// npx prisma generate',
|
|
87
|
+
'// npx prisma migrate dev --name init',
|
|
88
|
+
'// npx prisma db push (for prototyping)',
|
|
89
|
+
'',
|
|
90
|
+
'generator client {',
|
|
91
|
+
' provider = "prisma-client-js"',
|
|
92
|
+
'}',
|
|
93
|
+
'',
|
|
94
|
+
'datasource db {',
|
|
95
|
+
` provider = "${provider}"`,
|
|
96
|
+
' url = env("DATABASE_URL")',
|
|
97
|
+
'}',
|
|
98
|
+
'',
|
|
99
|
+
];
|
|
100
|
+
for (const node of modelNodes) {
|
|
101
|
+
const props = propsOf(node);
|
|
102
|
+
const name = props.name || 'UnknownModel';
|
|
103
|
+
const table = props.table;
|
|
104
|
+
const columns = getChildren(node, 'column');
|
|
105
|
+
const relations = getChildren(node, 'relation');
|
|
106
|
+
lines.push(`model ${name} {`);
|
|
107
|
+
for (const col of columns) {
|
|
108
|
+
const cp = propsOf(col);
|
|
109
|
+
const colName = cp.name || 'column';
|
|
110
|
+
const rawType = mapColumnToPrisma(cp.type || 'String', provider);
|
|
111
|
+
// Split off Prisma decorators embedded in the type (e.g., 'String @db.Uuid')
|
|
112
|
+
const [prismaType, ...typeDecorators] = rawType.split(' ');
|
|
113
|
+
const decorators = [...typeDecorators];
|
|
114
|
+
const isPrimary = cp.primary === 'true' || cp.primary === true;
|
|
115
|
+
const isUnique = cp.unique === 'true' || cp.unique === true;
|
|
116
|
+
const isNullable = cp.nullable === 'true' || cp.nullable === true;
|
|
117
|
+
const defaultVal = cp.default;
|
|
118
|
+
if (isPrimary)
|
|
119
|
+
decorators.push('@id');
|
|
120
|
+
if (isUnique)
|
|
121
|
+
decorators.push('@unique');
|
|
122
|
+
if (defaultVal !== undefined)
|
|
123
|
+
decorators.push(`@default(${formatPrismaDefault(defaultVal)})`);
|
|
124
|
+
const nullMark = isNullable ? '?' : '';
|
|
125
|
+
const decoStr = decorators.length > 0 ? ` ${decorators.join(' ')}` : '';
|
|
126
|
+
lines.push(` ${colName} ${prismaType}${nullMark}${decoStr}`);
|
|
127
|
+
}
|
|
128
|
+
for (const rel of relations) {
|
|
129
|
+
const rp = propsOf(rel);
|
|
130
|
+
const relName = rp.name || 'relation';
|
|
131
|
+
const target = rp.target || rp.model || 'Unknown';
|
|
132
|
+
const kind = rp.kind || 'one-to-many';
|
|
133
|
+
const fk = rp.foreignKey;
|
|
134
|
+
if (kind === 'one-to-many' || kind === 'many-to-many') {
|
|
135
|
+
lines.push(` ${relName} ${target}[]`);
|
|
136
|
+
}
|
|
137
|
+
else {
|
|
138
|
+
const relDeco = fk ? ` @relation(fields: [${fk}], references: [id])` : '';
|
|
139
|
+
lines.push(` ${relName} ${target}?${relDeco}`);
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
if (table) {
|
|
143
|
+
lines.push('');
|
|
144
|
+
lines.push(` @@map("${table}")`);
|
|
145
|
+
}
|
|
146
|
+
lines.push('}');
|
|
147
|
+
lines.push('');
|
|
148
|
+
}
|
|
149
|
+
return { path: 'prisma/schema.prisma', content: lines.join('\n'), type: 'prisma' };
|
|
150
|
+
}
|
|
151
|
+
export function buildCoreArtifact(node) {
|
|
152
|
+
const name = String(node.props?.name || node.type);
|
|
153
|
+
const fileBase = slugify(name);
|
|
154
|
+
const { dir, artifactType } = coreNodeMeta(node.type);
|
|
155
|
+
const tsLines = generateCoreNode(node);
|
|
156
|
+
const content = tsLines.join('\n');
|
|
157
|
+
// Extract export names for the import line
|
|
158
|
+
const exportNames = [];
|
|
159
|
+
for (const line of tsLines) {
|
|
160
|
+
const m = line.match(/^export (?:type |interface |function |const |class |enum |abstract class )(\w+)/);
|
|
161
|
+
if (m)
|
|
162
|
+
exportNames.push(m[1]);
|
|
163
|
+
}
|
|
164
|
+
return {
|
|
165
|
+
importPath: `./${dir}/${fileBase}.js`,
|
|
166
|
+
exportNames,
|
|
167
|
+
artifact: {
|
|
168
|
+
path: `${dir}/${fileBase}.ts`,
|
|
169
|
+
content,
|
|
170
|
+
type: artifactType,
|
|
171
|
+
},
|
|
172
|
+
};
|
|
173
|
+
}
|
|
174
|
+
//# sourceMappingURL=express-prisma.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"express-prisma.js","sourceRoot":"","sources":["../src/express-prisma.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import type { IRNode, SourceMapEntry } from '@kernlang/core';
|
|
2
|
+
import type { MiddlewareArtifactRef, RouteArtifactRef } from './express-types.js';
|
|
3
|
+
export declare function buildRouteArtifact(routeNode: IRNode, routeIndex: number, middlewareArtifacts: Map<string, MiddlewareArtifactRef>, sourceMap: SourceMapEntry[], securityLevel: 'strict' | 'relaxed'): RouteArtifactRef;
|