@kernlang/python 3.5.6-canary.195.1.72010f21 → 3.5.6
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/codegen-body-python.d.ts +37 -0
- package/dist/codegen-body-python.js +239 -0
- package/dist/codegen-body-python.js.map +1 -1
- package/dist/codegen-python.d.ts +1 -0
- package/dist/codegen-python.js +1 -1
- package/dist/codegen-python.js.map +1 -1
- package/dist/core/emit-imports.d.ts +11 -0
- package/dist/core/emit-imports.js +166 -0
- package/dist/core/emit-imports.js.map +1 -0
- package/dist/core/emit-models.d.ts +14 -0
- package/dist/core/emit-models.js +86 -0
- package/dist/core/emit-models.js.map +1 -0
- package/dist/core/fence-diagnostics.d.ts +17 -0
- package/dist/core/fence-diagnostics.js +86 -0
- package/dist/core/fence-diagnostics.js.map +1 -0
- package/dist/core/index.d.ts +3 -0
- package/dist/core/index.js +4 -0
- package/dist/core/index.js.map +1 -0
- package/dist/core/type-mapper.d.ts +4 -0
- package/dist/core/type-mapper.js +8 -0
- package/dist/core/type-mapper.js.map +1 -0
- package/dist/fastapi-portable.d.ts +7 -1
- package/dist/fastapi-portable.js +95 -73
- package/dist/fastapi-portable.js.map +1 -1
- package/dist/fastapi-response.d.ts +3 -1
- package/dist/fastapi-response.js +374 -26
- package/dist/fastapi-response.js.map +1 -1
- package/dist/generators/data.d.ts +3 -1
- package/dist/generators/data.js +28 -1
- package/dist/generators/data.js.map +1 -1
- package/dist/index.d.ts +2 -3
- package/dist/index.js +2 -3
- package/dist/index.js.map +1 -1
- package/dist/targets/python.d.ts +5 -0
- package/dist/targets/python.js +50 -0
- package/dist/targets/python.js.map +1 -0
- package/dist/transpiler-fastapi.js +23 -66
- package/dist/transpiler-fastapi.js.map +1 -1
- package/package.json +2 -2
package/dist/codegen-python.d.ts
CHANGED
|
@@ -12,6 +12,7 @@ export { generateAction, generateAssume, generateBranch, generateCollect, genera
|
|
|
12
12
|
export { generatePythonEmail, generatePythonJob, generatePythonStorage, } from './generators/infra.js';
|
|
13
13
|
export interface PythonCodegenOptions {
|
|
14
14
|
resolveKernModuleSpec?: (rawPath: string, node: IRNode) => string | undefined;
|
|
15
|
+
pythonModelBackend?: 'pydantic' | 'sqlmodel' | 'auto';
|
|
15
16
|
}
|
|
16
17
|
/** Generate Python for any core language node. Returns string lines. */
|
|
17
18
|
export declare function generatePythonCoreNode(node: IRNode, options?: PythonCodegenOptions): string[];
|
package/dist/codegen-python.js
CHANGED
|
@@ -54,7 +54,7 @@ export function generatePythonCoreNode(node, options = {}) {
|
|
|
54
54
|
return generateConst(node);
|
|
55
55
|
// Data layer
|
|
56
56
|
case 'model':
|
|
57
|
-
return generatePythonModel(node);
|
|
57
|
+
return generatePythonModel(node, options);
|
|
58
58
|
case 'repository':
|
|
59
59
|
return generatePythonRepository(node);
|
|
60
60
|
case 'cache':
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"codegen-python.js","sourceRoot":"","sources":["../src/codegen-python.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAIH,mGAAmG;AACnG,OAAO,EACL,cAAc,EACd,aAAa,EACb,aAAa,EACb,aAAa,EACb,cAAc,EACd,gBAAgB,EAChB,cAAc,EACd,iBAAiB,EACjB,eAAe,EACf,cAAc,EACd,aAAa,EACb,YAAY,EACZ,YAAY,EACZ,WAAW,GACZ,MAAM,sBAAsB,CAAC;AAC9B,+EAA+E;AAC/E,OAAO,EACL,mBAAmB,EACnB,wBAAwB,EACxB,mBAAmB,EACnB,wBAAwB,EACxB,qBAAqB,EACrB,mBAAmB,GACpB,MAAM,sBAAsB,CAAC;AAC9B,iIAAiI;AACjI,OAAO,EACL,cAAc,EACd,cAAc,EACd,cAAc,EACd,eAAe,EACf,cAAc,EACd,YAAY,EACZ,cAAc,EACd,aAAa,EACb,iBAAiB,EACjB,eAAe,EACf,eAAe,EACf,iBAAiB,EACjB,aAAa,GACd,MAAM,wBAAwB,CAAC;AAEhC,yCAAyC;AACzC,OAAO,EAAE,mBAAmB,EAAE,iBAAiB,EAAE,qBAAqB,EAAE,MAAM,uBAAuB,CAAC;AAEtG,mEAAmE;AACnE,OAAO,EAAE,uBAAuB,EAAE,uBAAuB,EAAE,UAAU,EAAE,IAAI,EAAE,CAAC,EAAE,MAAM,sBAAsB,CAAC;AAE7G,wEAAwE;AACxE,OAAO,EACL,cAAc,EACd,aAAa,EACb,aAAa,EACb,aAAa,EACb,gBAAgB,EAChB,cAAc,EACd,iBAAiB,EACjB,eAAe,EACf,cAAc,EACd,aAAa,EACb,YAAY,EACZ,YAAY,EACZ,WAAW,GACZ,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EACL,mBAAmB,EACnB,mBAAmB,EACnB,wBAAwB,EACxB,mBAAmB,EACnB,wBAAwB,EACxB,qBAAqB,EACrB,mBAAmB,EACnB,iBAAiB,GAClB,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EACL,cAAc,EACd,cAAc,EACd,cAAc,EACd,eAAe,EACf,cAAc,EACd,YAAY,EACZ,cAAc,EACd,aAAa,EACb,iBAAiB,EACjB,eAAe,EACf,eAAe,EACf,iBAAiB,GAClB,MAAM,wBAAwB,CAAC;AAEhC,OAAO,EACL,mBAAmB,EACnB,iBAAiB,EACjB,qBAAqB,GACtB,MAAM,uBAAuB,CAAC;
|
|
1
|
+
{"version":3,"file":"codegen-python.js","sourceRoot":"","sources":["../src/codegen-python.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { IRNode } from '@kernlang/core';
|
|
2
|
+
/**
|
|
3
|
+
* Perform a demand-driven AST traversal to collect necessary Python imports
|
|
4
|
+
* for the generated models and types, plus any Result/Option preamble imports.
|
|
5
|
+
*/
|
|
6
|
+
export declare function emitImports(root: IRNode, options?: {
|
|
7
|
+
pythonModelBackend?: 'pydantic' | 'sqlmodel' | 'auto';
|
|
8
|
+
}): {
|
|
9
|
+
lines: string[];
|
|
10
|
+
imports: Set<string>;
|
|
11
|
+
};
|
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
import { getChildren } from '@kernlang/core';
|
|
2
|
+
import { buildPythonStdlibPreamble } from '../python-stdlib-preamble.js';
|
|
3
|
+
import { mapTsTypeToPython } from '../type-map.js';
|
|
4
|
+
function findServerNode(root) {
|
|
5
|
+
if (root.type === 'server')
|
|
6
|
+
return root;
|
|
7
|
+
for (const child of root.children || []) {
|
|
8
|
+
const found = findServerNode(child);
|
|
9
|
+
if (found)
|
|
10
|
+
return found;
|
|
11
|
+
}
|
|
12
|
+
return undefined;
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Perform a demand-driven AST traversal to collect necessary Python imports
|
|
16
|
+
* for the generated models and types, plus any Result/Option preamble imports.
|
|
17
|
+
*/
|
|
18
|
+
export function emitImports(root, options) {
|
|
19
|
+
const imports = new Set();
|
|
20
|
+
// 1. Collect KERN standard library preamble imports and definition lines
|
|
21
|
+
const stdlib = buildPythonStdlibPreamble(root);
|
|
22
|
+
for (const imp of stdlib.imports) {
|
|
23
|
+
imports.add(imp);
|
|
24
|
+
}
|
|
25
|
+
// 2. Selection of the exact same core nodes as the original transpiler
|
|
26
|
+
const TOP_LEVEL_CORE = new Set([
|
|
27
|
+
'type',
|
|
28
|
+
'interface',
|
|
29
|
+
'fn',
|
|
30
|
+
'machine',
|
|
31
|
+
'error',
|
|
32
|
+
'module',
|
|
33
|
+
'config',
|
|
34
|
+
'store',
|
|
35
|
+
'test',
|
|
36
|
+
'event',
|
|
37
|
+
'import',
|
|
38
|
+
'extern',
|
|
39
|
+
'use',
|
|
40
|
+
'const',
|
|
41
|
+
'model',
|
|
42
|
+
'repository',
|
|
43
|
+
'cache',
|
|
44
|
+
'dependency',
|
|
45
|
+
'service',
|
|
46
|
+
'union',
|
|
47
|
+
'job',
|
|
48
|
+
'storage',
|
|
49
|
+
'email',
|
|
50
|
+
'derive',
|
|
51
|
+
'transform',
|
|
52
|
+
'action',
|
|
53
|
+
'guard',
|
|
54
|
+
'assume',
|
|
55
|
+
'invariant',
|
|
56
|
+
'each',
|
|
57
|
+
'collect',
|
|
58
|
+
'branch',
|
|
59
|
+
'resolve',
|
|
60
|
+
'expect',
|
|
61
|
+
'recover',
|
|
62
|
+
]);
|
|
63
|
+
const serverNode = findServerNode(root) || root;
|
|
64
|
+
const rootChildren = root.children || [];
|
|
65
|
+
const serverChildren = serverNode !== root ? serverNode.children || [] : [];
|
|
66
|
+
const coreNodes = [
|
|
67
|
+
...rootChildren.filter((c) => TOP_LEVEL_CORE.has(c.type)),
|
|
68
|
+
...serverChildren.filter((c) => TOP_LEVEL_CORE.has(c.type)),
|
|
69
|
+
];
|
|
70
|
+
if (TOP_LEVEL_CORE.has(root.type) && !coreNodes.includes(root)) {
|
|
71
|
+
coreNodes.unshift(root);
|
|
72
|
+
}
|
|
73
|
+
const coreTypes = new Set(coreNodes.map((n) => n.type));
|
|
74
|
+
const backend = options?.pythonModelBackend || 'auto';
|
|
75
|
+
// 3. BaseModel / SQLModel imports
|
|
76
|
+
if (coreTypes.has('interface') || coreTypes.has('union')) {
|
|
77
|
+
imports.add('from pydantic import BaseModel');
|
|
78
|
+
}
|
|
79
|
+
if (coreTypes.has('model')) {
|
|
80
|
+
if (backend === 'pydantic') {
|
|
81
|
+
imports.add('from pydantic import BaseModel');
|
|
82
|
+
}
|
|
83
|
+
else {
|
|
84
|
+
imports.add('from sqlmodel import SQLModel, Field, Relationship');
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
if (coreTypes.has('repository')) {
|
|
88
|
+
imports.add('from sqlalchemy.ext.asyncio import AsyncSession');
|
|
89
|
+
}
|
|
90
|
+
if (coreTypes.has('event')) {
|
|
91
|
+
imports.add('from typing import TypedDict');
|
|
92
|
+
imports.add('from typing import Literal');
|
|
93
|
+
imports.add('from typing import Any');
|
|
94
|
+
}
|
|
95
|
+
// 4. Examine all type strings in the AST to pull in typing / built-in imports
|
|
96
|
+
const typeProps = ['type', 'returns', 'constType', 'alias', 'values'];
|
|
97
|
+
function checkTypeString(tsType) {
|
|
98
|
+
const pyType = mapTsTypeToPython(tsType);
|
|
99
|
+
if (pyType.includes('Literal[')) {
|
|
100
|
+
imports.add('from typing import Literal');
|
|
101
|
+
}
|
|
102
|
+
if (pyType.includes('Union[')) {
|
|
103
|
+
imports.add('from typing import Union');
|
|
104
|
+
}
|
|
105
|
+
if (pyType.includes('Any')) {
|
|
106
|
+
imports.add('from typing import Any');
|
|
107
|
+
}
|
|
108
|
+
if (pyType.includes('Callable[')) {
|
|
109
|
+
imports.add('from typing import Callable');
|
|
110
|
+
}
|
|
111
|
+
if (tsType.includes('=>')) {
|
|
112
|
+
imports.add('from typing import Callable');
|
|
113
|
+
}
|
|
114
|
+
if (pyType.includes('UUID')) {
|
|
115
|
+
imports.add('from uuid import UUID');
|
|
116
|
+
}
|
|
117
|
+
if (pyType.includes('date') || pyType.includes('datetime')) {
|
|
118
|
+
imports.add('from datetime import date, datetime');
|
|
119
|
+
}
|
|
120
|
+
if (pyType.includes('Decimal')) {
|
|
121
|
+
imports.add('from decimal import Decimal');
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
function walkProps(node) {
|
|
125
|
+
if (node.type === 'type' && node.props?.values) {
|
|
126
|
+
imports.add('from typing import Literal');
|
|
127
|
+
}
|
|
128
|
+
if (node.props) {
|
|
129
|
+
for (const prop of typeProps) {
|
|
130
|
+
if (typeof node.props[prop] === 'string') {
|
|
131
|
+
checkTypeString(node.props[prop]);
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
if (node.type === 'model') {
|
|
136
|
+
for (const col of getChildren(node, 'column')) {
|
|
137
|
+
const colType = col.props?.type || '';
|
|
138
|
+
if (colType === 'uuid')
|
|
139
|
+
imports.add('from uuid import UUID');
|
|
140
|
+
if (['date', 'datetime', 'timestamp', 'Timestamp'].includes(colType)) {
|
|
141
|
+
imports.add('from datetime import date, datetime');
|
|
142
|
+
}
|
|
143
|
+
if (['decimal', 'Money'].includes(colType)) {
|
|
144
|
+
imports.add('from decimal import Decimal');
|
|
145
|
+
}
|
|
146
|
+
if (colType === 'json')
|
|
147
|
+
imports.add('from typing import Any');
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
for (const child of node.children || []) {
|
|
151
|
+
walkProps(child);
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
// Only walk type properties of the selected coreNodes and the root itself to remain strictly demand-driven for compiled components
|
|
155
|
+
for (const node of coreNodes) {
|
|
156
|
+
walkProps(node);
|
|
157
|
+
}
|
|
158
|
+
if (root !== serverNode) {
|
|
159
|
+
walkProps(root);
|
|
160
|
+
}
|
|
161
|
+
return {
|
|
162
|
+
lines: stdlib.lines,
|
|
163
|
+
imports,
|
|
164
|
+
};
|
|
165
|
+
}
|
|
166
|
+
//# sourceMappingURL=emit-imports.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"emit-imports.js","sourceRoot":"","sources":["../../src/core/emit-imports.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAC7C,OAAO,EAAE,yBAAyB,EAAE,MAAM,8BAA8B,CAAC;AACzE,OAAO,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AAEnD,SAAS,cAAc,CAAC,IAAY;IAClC,IAAI,IAAI,CAAC,IAAI,KAAK,QAAQ;QAAE,OAAO,IAAI,CAAC;IACxC,KAAK,MAAM,KAAK,IAAI,IAAI,CAAC,QAAQ,IAAI,EAAE,EAAE,CAAC;QACxC,MAAM,KAAK,GAAG,cAAc,CAAC,KAAK,CAAC,CAAC;QACpC,IAAI,KAAK;YAAE,OAAO,KAAK,CAAC;IAC1B,CAAC;IACD,OAAO,SAAS,CAAC;AACnB,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,WAAW,CACzB,IAAY,EACZ,OAAmE;IAEnE,MAAM,OAAO,GAAG,IAAI,GAAG,EAAU,CAAC;IAElC,yEAAyE;IACzE,MAAM,MAAM,GAAG,yBAAyB,CAAC,IAAI,CAAC,CAAC;IAC/C,KAAK,MAAM,GAAG,IAAI,MAAM,CAAC,OAAO,EAAE,CAAC;QACjC,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IACnB,CAAC;IAED,uEAAuE;IACvE,MAAM,cAAc,GAAG,IAAI,GAAG,CAAC;QAC7B,MAAM;QACN,WAAW;QACX,IAAI;QACJ,SAAS;QACT,OAAO;QACP,QAAQ;QACR,QAAQ;QACR,OAAO;QACP,MAAM;QACN,OAAO;QACP,QAAQ;QACR,QAAQ;QACR,KAAK;QACL,OAAO;QACP,OAAO;QACP,YAAY;QACZ,OAAO;QACP,YAAY;QACZ,SAAS;QACT,OAAO;QACP,KAAK;QACL,SAAS;QACT,OAAO;QACP,QAAQ;QACR,WAAW;QACX,QAAQ;QACR,OAAO;QACP,QAAQ;QACR,WAAW;QACX,MAAM;QACN,SAAS;QACT,QAAQ;QACR,SAAS;QACT,QAAQ;QACR,SAAS;KACV,CAAC,CAAC;IAEH,MAAM,UAAU,GAAG,cAAc,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC;IAChD,MAAM,YAAY,GAAG,IAAI,CAAC,QAAQ,IAAI,EAAE,CAAC;IACzC,MAAM,cAAc,GAAG,UAAU,KAAK,IAAI,CAAC,CAAC,CAAC,UAAU,CAAC,QAAQ,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;IAE5E,MAAM,SAAS,GAAa;QAC1B,GAAG,YAAY,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,cAAc,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;QACzD,GAAG,cAAc,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,cAAc,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;KAC5D,CAAC;IAEF,IAAI,cAAc,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;QAC/D,SAAS,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;IAC1B,CAAC;IAED,MAAM,SAAS,GAAG,IAAI,GAAG,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC;IACxD,MAAM,OAAO,GAAG,OAAO,EAAE,kBAAkB,IAAI,MAAM,CAAC;IAEtD,kCAAkC;IAClC,IAAI,SAAS,CAAC,GAAG,CAAC,WAAW,CAAC,IAAI,SAAS,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,CAAC;QACzD,OAAO,CAAC,GAAG,CAAC,gCAAgC,CAAC,CAAC;IAChD,CAAC;IAED,IAAI,SAAS,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,CAAC;QAC3B,IAAI,OAAO,KAAK,UAAU,EAAE,CAAC;YAC3B,OAAO,CAAC,GAAG,CAAC,gCAAgC,CAAC,CAAC;QAChD,CAAC;aAAM,CAAC;YACN,OAAO,CAAC,GAAG,CAAC,oDAAoD,CAAC,CAAC;QACpE,CAAC;IACH,CAAC;IAED,IAAI,SAAS,CAAC,GAAG,CAAC,YAAY,CAAC,EAAE,CAAC;QAChC,OAAO,CAAC,GAAG,CAAC,iDAAiD,CAAC,CAAC;IACjE,CAAC;IAED,IAAI,SAAS,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,CAAC;QAC3B,OAAO,CAAC,GAAG,CAAC,8BAA8B,CAAC,CAAC;QAC5C,OAAO,CAAC,GAAG,CAAC,4BAA4B,CAAC,CAAC;QAC1C,OAAO,CAAC,GAAG,CAAC,wBAAwB,CAAC,CAAC;IACxC,CAAC;IAED,8EAA8E;IAC9E,MAAM,SAAS,GAAG,CAAC,MAAM,EAAE,SAAS,EAAE,WAAW,EAAE,OAAO,EAAE,QAAQ,CAAC,CAAC;IAEtE,SAAS,eAAe,CAAC,MAAc;QACrC,MAAM,MAAM,GAAG,iBAAiB,CAAC,MAAM,CAAC,CAAC;QACzC,IAAI,MAAM,CAAC,QAAQ,CAAC,UAAU,CAAC,EAAE,CAAC;YAChC,OAAO,CAAC,GAAG,CAAC,4BAA4B,CAAC,CAAC;QAC5C,CAAC;QACD,IAAI,MAAM,CAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE,CAAC;YAC9B,OAAO,CAAC,GAAG,CAAC,0BAA0B,CAAC,CAAC;QAC1C,CAAC;QACD,IAAI,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC;YAC3B,OAAO,CAAC,GAAG,CAAC,wBAAwB,CAAC,CAAC;QACxC,CAAC;QACD,IAAI,MAAM,CAAC,QAAQ,CAAC,WAAW,CAAC,EAAE,CAAC;YACjC,OAAO,CAAC,GAAG,CAAC,6BAA6B,CAAC,CAAC;QAC7C,CAAC;QACD,IAAI,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;YAC1B,OAAO,CAAC,GAAG,CAAC,6BAA6B,CAAC,CAAC;QAC7C,CAAC;QACD,IAAI,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC;YAC5B,OAAO,CAAC,GAAG,CAAC,uBAAuB,CAAC,CAAC;QACvC,CAAC;QACD,IAAI,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,MAAM,CAAC,QAAQ,CAAC,UAAU,CAAC,EAAE,CAAC;YAC3D,OAAO,CAAC,GAAG,CAAC,qCAAqC,CAAC,CAAC;QACrD,CAAC;QACD,IAAI,MAAM,CAAC,QAAQ,CAAC,SAAS,CAAC,EAAE,CAAC;YAC/B,OAAO,CAAC,GAAG,CAAC,6BAA6B,CAAC,CAAC;QAC7C,CAAC;IACH,CAAC;IAED,SAAS,SAAS,CAAC,IAAY;QAC7B,IAAI,IAAI,CAAC,IAAI,KAAK,MAAM,IAAI,IAAI,CAAC,KAAK,EAAE,MAAM,EAAE,CAAC;YAC/C,OAAO,CAAC,GAAG,CAAC,4BAA4B,CAAC,CAAC;QAC5C,CAAC;QAED,IAAI,IAAI,CAAC,KAAK,EAAE,CAAC;YACf,KAAK,MAAM,IAAI,IAAI,SAAS,EAAE,CAAC;gBAC7B,IAAI,OAAO,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,QAAQ,EAAE,CAAC;oBACzC,eAAe,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAW,CAAC,CAAC;gBAC9C,CAAC;YACH,CAAC;QACH,CAAC;QAED,IAAI,IAAI,CAAC,IAAI,KAAK,OAAO,EAAE,CAAC;YAC1B,KAAK,MAAM,GAAG,IAAI,WAAW,CAAC,IAAI,EAAE,QAAQ,CAAC,EAAE,CAAC;gBAC9C,MAAM,OAAO,GAAI,GAAG,CAAC,KAAK,EAAE,IAAe,IAAI,EAAE,CAAC;gBAClD,IAAI,OAAO,KAAK,MAAM;oBAAE,OAAO,CAAC,GAAG,CAAC,uBAAuB,CAAC,CAAC;gBAC7D,IAAI,CAAC,MAAM,EAAE,UAAU,EAAE,WAAW,EAAE,WAAW,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC;oBACrE,OAAO,CAAC,GAAG,CAAC,qCAAqC,CAAC,CAAC;gBACrD,CAAC;gBACD,IAAI,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC;oBAC3C,OAAO,CAAC,GAAG,CAAC,6BAA6B,CAAC,CAAC;gBAC7C,CAAC;gBACD,IAAI,OAAO,KAAK,MAAM;oBAAE,OAAO,CAAC,GAAG,CAAC,wBAAwB,CAAC,CAAC;YAChE,CAAC;QACH,CAAC;QAED,KAAK,MAAM,KAAK,IAAI,IAAI,CAAC,QAAQ,IAAI,EAAE,EAAE,CAAC;YACxC,SAAS,CAAC,KAAK,CAAC,CAAC;QACnB,CAAC;IACH,CAAC;IAED,mIAAmI;IACnI,KAAK,MAAM,IAAI,IAAI,SAAS,EAAE,CAAC;QAC7B,SAAS,CAAC,IAAI,CAAC,CAAC;IAClB,CAAC;IACD,IAAI,IAAI,KAAK,UAAU,EAAE,CAAC;QACxB,SAAS,CAAC,IAAI,CAAC,CAAC;IAClB,CAAC;IAED,OAAO;QACL,KAAK,EAAE,MAAM,CAAC,KAAK;QACnB,OAAO;KACR,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { IRNode } from '@kernlang/core';
|
|
2
|
+
/**
|
|
3
|
+
* Filter the AST for core nodes / declarations and render their bodies using `generatePythonCoreNode`.
|
|
4
|
+
* In types-only projection (e.g. `--emit=models` or target `python`), functions are suppressed.
|
|
5
|
+
*/
|
|
6
|
+
export declare function emitModels(root: IRNode, options?: {
|
|
7
|
+
pythonModelBackend?: 'pydantic' | 'sqlmodel' | 'auto';
|
|
8
|
+
emit?: string;
|
|
9
|
+
target?: string;
|
|
10
|
+
resolveKernModuleSpec?: (rawPath: string, node: IRNode) => string | undefined;
|
|
11
|
+
}): {
|
|
12
|
+
code: string;
|
|
13
|
+
bodies: string[][];
|
|
14
|
+
};
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
import { generatePythonCoreNode } from '../codegen-python.js';
|
|
2
|
+
function findServerNode(root) {
|
|
3
|
+
if (root.type === 'server')
|
|
4
|
+
return root;
|
|
5
|
+
for (const child of root.children || []) {
|
|
6
|
+
const found = findServerNode(child);
|
|
7
|
+
if (found)
|
|
8
|
+
return found;
|
|
9
|
+
}
|
|
10
|
+
return undefined;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Filter the AST for core nodes / declarations and render their bodies using `generatePythonCoreNode`.
|
|
14
|
+
* In types-only projection (e.g. `--emit=models` or target `python`), functions are suppressed.
|
|
15
|
+
*/
|
|
16
|
+
export function emitModels(root, options) {
|
|
17
|
+
const isModelsOnly = options?.emit === 'models' || options?.target === 'python';
|
|
18
|
+
// Allowed core node types
|
|
19
|
+
const TOP_LEVEL_CORE = new Set([
|
|
20
|
+
'type',
|
|
21
|
+
'interface',
|
|
22
|
+
'fn',
|
|
23
|
+
'machine',
|
|
24
|
+
'error',
|
|
25
|
+
'module',
|
|
26
|
+
'config',
|
|
27
|
+
'store',
|
|
28
|
+
'test',
|
|
29
|
+
'event',
|
|
30
|
+
'import',
|
|
31
|
+
'extern',
|
|
32
|
+
'use',
|
|
33
|
+
'const',
|
|
34
|
+
'model',
|
|
35
|
+
'repository',
|
|
36
|
+
'cache',
|
|
37
|
+
'dependency',
|
|
38
|
+
'service',
|
|
39
|
+
'union',
|
|
40
|
+
'job',
|
|
41
|
+
'storage',
|
|
42
|
+
'email',
|
|
43
|
+
'derive',
|
|
44
|
+
'transform',
|
|
45
|
+
'action',
|
|
46
|
+
'guard',
|
|
47
|
+
'assume',
|
|
48
|
+
'invariant',
|
|
49
|
+
'each',
|
|
50
|
+
'collect',
|
|
51
|
+
'branch',
|
|
52
|
+
'resolve',
|
|
53
|
+
'expect',
|
|
54
|
+
'recover',
|
|
55
|
+
]);
|
|
56
|
+
const MODEL_ONLY_CORE = new Set(['type', 'interface', 'event', 'model', 'union']);
|
|
57
|
+
const allowedTypes = isModelsOnly ? MODEL_ONLY_CORE : TOP_LEVEL_CORE;
|
|
58
|
+
// Replicate original transpiler-fastapi core node selection
|
|
59
|
+
const serverNode = findServerNode(root) || root;
|
|
60
|
+
const rootChildren = root.children || [];
|
|
61
|
+
const serverChildren = serverNode !== root ? serverNode.children || [] : [];
|
|
62
|
+
const coreNodes = [
|
|
63
|
+
...rootChildren.filter((c) => allowedTypes.has(c.type)),
|
|
64
|
+
...serverChildren.filter((c) => allowedTypes.has(c.type)),
|
|
65
|
+
];
|
|
66
|
+
if (allowedTypes.has(root.type) && !coreNodes.includes(root)) {
|
|
67
|
+
coreNodes.unshift(root);
|
|
68
|
+
}
|
|
69
|
+
const codegenOpts = {
|
|
70
|
+
resolveKernModuleSpec: options?.resolveKernModuleSpec,
|
|
71
|
+
pythonModelBackend: options?.pythonModelBackend,
|
|
72
|
+
};
|
|
73
|
+
const bodies = coreNodes.map((node) => generatePythonCoreNode(node, codegenOpts));
|
|
74
|
+
const lines = [];
|
|
75
|
+
for (const coreLines of bodies) {
|
|
76
|
+
if (coreLines.length > 0) {
|
|
77
|
+
lines.push(...coreLines);
|
|
78
|
+
lines.push('');
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
return {
|
|
82
|
+
code: lines.join('\n'),
|
|
83
|
+
bodies,
|
|
84
|
+
};
|
|
85
|
+
}
|
|
86
|
+
//# sourceMappingURL=emit-models.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"emit-models.js","sourceRoot":"","sources":["../../src/core/emit-models.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,sBAAsB,EAAE,MAAM,sBAAsB,CAAC;AAE9D,SAAS,cAAc,CAAC,IAAY;IAClC,IAAI,IAAI,CAAC,IAAI,KAAK,QAAQ;QAAE,OAAO,IAAI,CAAC;IACxC,KAAK,MAAM,KAAK,IAAI,IAAI,CAAC,QAAQ,IAAI,EAAE,EAAE,CAAC;QACxC,MAAM,KAAK,GAAG,cAAc,CAAC,KAAK,CAAC,CAAC;QACpC,IAAI,KAAK;YAAE,OAAO,KAAK,CAAC;IAC1B,CAAC;IACD,OAAO,SAAS,CAAC;AACnB,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,UAAU,CACxB,IAAY,EACZ,OAKC;IAED,MAAM,YAAY,GAAG,OAAO,EAAE,IAAI,KAAK,QAAQ,IAAI,OAAO,EAAE,MAAM,KAAK,QAAQ,CAAC;IAEhF,0BAA0B;IAC1B,MAAM,cAAc,GAAG,IAAI,GAAG,CAAC;QAC7B,MAAM;QACN,WAAW;QACX,IAAI;QACJ,SAAS;QACT,OAAO;QACP,QAAQ;QACR,QAAQ;QACR,OAAO;QACP,MAAM;QACN,OAAO;QACP,QAAQ;QACR,QAAQ;QACR,KAAK;QACL,OAAO;QACP,OAAO;QACP,YAAY;QACZ,OAAO;QACP,YAAY;QACZ,SAAS;QACT,OAAO;QACP,KAAK;QACL,SAAS;QACT,OAAO;QACP,QAAQ;QACR,WAAW;QACX,QAAQ;QACR,OAAO;QACP,QAAQ;QACR,WAAW;QACX,MAAM;QACN,SAAS;QACT,QAAQ;QACR,SAAS;QACT,QAAQ;QACR,SAAS;KACV,CAAC,CAAC;IAEH,MAAM,eAAe,GAAG,IAAI,GAAG,CAAC,CAAC,MAAM,EAAE,WAAW,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC,CAAC;IAElF,MAAM,YAAY,GAAG,YAAY,CAAC,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,cAAc,CAAC;IAErE,4DAA4D;IAC5D,MAAM,UAAU,GAAG,cAAc,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC;IAChD,MAAM,YAAY,GAAG,IAAI,CAAC,QAAQ,IAAI,EAAE,CAAC;IACzC,MAAM,cAAc,GAAG,UAAU,KAAK,IAAI,CAAC,CAAC,CAAC,UAAU,CAAC,QAAQ,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;IAE5E,MAAM,SAAS,GAAa;QAC1B,GAAG,YAAY,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,YAAY,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;QACvD,GAAG,cAAc,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,YAAY,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;KAC1D,CAAC;IAEF,IAAI,YAAY,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;QAC7D,SAAS,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;IAC1B,CAAC;IAED,MAAM,WAAW,GAAG;QAClB,qBAAqB,EAAE,OAAO,EAAE,qBAAqB;QACrD,kBAAkB,EAAE,OAAO,EAAE,kBAAkB;KAChD,CAAC;IAEF,MAAM,MAAM,GAAG,SAAS,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,sBAAsB,CAAC,IAAI,EAAE,WAAW,CAAC,CAAC,CAAC;IAElF,MAAM,KAAK,GAAa,EAAE,CAAC;IAC3B,KAAK,MAAM,SAAS,IAAI,MAAM,EAAE,CAAC;QAC/B,IAAI,SAAS,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACzB,KAAK,CAAC,IAAI,CAAC,GAAG,SAAS,CAAC,CAAC;YACzB,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QACjB,CAAC;IACH,CAAC;IAED,OAAO;QACL,IAAI,EAAE,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC;QACtB,MAAM;KACP,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { IRNode, TranspileDiagnostic } from '@kernlang/core';
|
|
2
|
+
export type FenceSeverity = 'error' | 'warning' | 'info';
|
|
3
|
+
/**
|
|
4
|
+
* Walk every handler body and report what the (models-only) python target drops.
|
|
5
|
+
*
|
|
6
|
+
* The python target emits only models/types — every handler body is dropped. This
|
|
7
|
+
* surfaces at most one diagnostic per dropped handler so the drop is never silent:
|
|
8
|
+
* - raw unmarked TS fence → `rawFenceSeverity` (default warning) — the portability hazard
|
|
9
|
+
* - explicit lang="ts"/etc → info (foreign, intentional, but still dropped)
|
|
10
|
+
* - native kern / python → info ("not yet emitted") — prevents a false sense of portability
|
|
11
|
+
* - empty fence → skipped (nothing to port)
|
|
12
|
+
*
|
|
13
|
+
* Classifying a handler stops descent into its children (they are body content),
|
|
14
|
+
* so each handler yields a single diagnostic and there is no double-reporting; the
|
|
15
|
+
* python target runs no generic `buildDiagnostics` pass.
|
|
16
|
+
*/
|
|
17
|
+
export declare function collectFenceDiagnostics(root: IRNode, rawFenceSeverity?: FenceSeverity): TranspileDiagnostic[];
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
// Foreign fence languages that are explicitly NOT Python — declared on purpose,
|
|
2
|
+
// but still dropped by the (models-only) python target.
|
|
3
|
+
const FOREIGN_TS_LANGS = new Set(['ts', 'typescript', 'js', 'javascript', 'tsx', 'jsx']);
|
|
4
|
+
const PYTHON_LANGS = new Set(['python', 'py']);
|
|
5
|
+
const kernNotEmitted = (label) => `${label}: portable kern handler body is not yet emitted by the python target (dropped)`;
|
|
6
|
+
function ownerLabel(owner) {
|
|
7
|
+
if (!owner)
|
|
8
|
+
return 'handler';
|
|
9
|
+
const name = owner.props?.name;
|
|
10
|
+
if (typeof name === 'string' && name !== '')
|
|
11
|
+
return `${owner.type} "${name}"`;
|
|
12
|
+
return owner.type || 'handler';
|
|
13
|
+
}
|
|
14
|
+
function mk(node, severity, message) {
|
|
15
|
+
return {
|
|
16
|
+
nodeType: node.type,
|
|
17
|
+
outcome: 'unsupported',
|
|
18
|
+
target: 'python',
|
|
19
|
+
loc: node.loc ? { line: node.loc.line, col: node.loc.col } : undefined,
|
|
20
|
+
severity,
|
|
21
|
+
message,
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
function classify(handler, owner, rawFenceSeverity) {
|
|
25
|
+
const props = handler.props ?? {};
|
|
26
|
+
const lang = typeof props.lang === 'string' ? props.lang.trim().toLowerCase() : undefined;
|
|
27
|
+
const rawCode = typeof props.code === 'string' ? props.code : undefined;
|
|
28
|
+
const label = ownerLabel(owner);
|
|
29
|
+
// Raw / foreign fence — the body lives verbatim in props.code.
|
|
30
|
+
if (rawCode !== undefined) {
|
|
31
|
+
if (rawCode.trim() === '')
|
|
32
|
+
return null; // Empty fence — nothing to port.
|
|
33
|
+
if (lang === undefined || lang === '') {
|
|
34
|
+
// Unmarked raw fence — assumed TypeScript. The direct twin of the TS shadow analyzer.
|
|
35
|
+
return mk(handler, rawFenceSeverity, `${label}: raw TS fence is not portable to the python target (handler body dropped)`);
|
|
36
|
+
}
|
|
37
|
+
if (FOREIGN_TS_LANGS.has(lang)) {
|
|
38
|
+
return mk(handler, 'info', `${label}: lang="${lang}" foreign fence is dropped in the python target`);
|
|
39
|
+
}
|
|
40
|
+
if (PYTHON_LANGS.has(lang)) {
|
|
41
|
+
return mk(handler, 'info', `${label}: python-native fence is not yet emitted by the python target (dropped)`);
|
|
42
|
+
}
|
|
43
|
+
if (lang === 'kern') {
|
|
44
|
+
return mk(handler, 'info', kernNotEmitted(label));
|
|
45
|
+
}
|
|
46
|
+
// Unknown lang — treat as a raw, non-portable fence.
|
|
47
|
+
return mk(handler, rawFenceSeverity, `${label}: lang="${lang}" fence is not portable to the python target (handler body dropped)`);
|
|
48
|
+
}
|
|
49
|
+
// No raw code: a native body lives in statement children. Report it dropped so
|
|
50
|
+
// native handlers never look silently portable — independent of whether the
|
|
51
|
+
// parser tagged the body lang="kern".
|
|
52
|
+
if ((handler.children?.length ?? 0) > 0) {
|
|
53
|
+
return mk(handler, 'info', kernNotEmitted(label));
|
|
54
|
+
}
|
|
55
|
+
return null; // Bodiless handler — nothing dropped.
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Walk every handler body and report what the (models-only) python target drops.
|
|
59
|
+
*
|
|
60
|
+
* The python target emits only models/types — every handler body is dropped. This
|
|
61
|
+
* surfaces at most one diagnostic per dropped handler so the drop is never silent:
|
|
62
|
+
* - raw unmarked TS fence → `rawFenceSeverity` (default warning) — the portability hazard
|
|
63
|
+
* - explicit lang="ts"/etc → info (foreign, intentional, but still dropped)
|
|
64
|
+
* - native kern / python → info ("not yet emitted") — prevents a false sense of portability
|
|
65
|
+
* - empty fence → skipped (nothing to port)
|
|
66
|
+
*
|
|
67
|
+
* Classifying a handler stops descent into its children (they are body content),
|
|
68
|
+
* so each handler yields a single diagnostic and there is no double-reporting; the
|
|
69
|
+
* python target runs no generic `buildDiagnostics` pass.
|
|
70
|
+
*/
|
|
71
|
+
export function collectFenceDiagnostics(root, rawFenceSeverity = 'warning') {
|
|
72
|
+
const diagnostics = [];
|
|
73
|
+
function walk(node, parent) {
|
|
74
|
+
if (node.type === 'handler') {
|
|
75
|
+
const diag = classify(node, parent, rawFenceSeverity);
|
|
76
|
+
if (diag)
|
|
77
|
+
diagnostics.push(diag);
|
|
78
|
+
return; // Handler children are body content — don't descend.
|
|
79
|
+
}
|
|
80
|
+
for (const child of node.children ?? [])
|
|
81
|
+
walk(child, node);
|
|
82
|
+
}
|
|
83
|
+
walk(root, null);
|
|
84
|
+
return diagnostics;
|
|
85
|
+
}
|
|
86
|
+
//# sourceMappingURL=fence-diagnostics.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fence-diagnostics.js","sourceRoot":"","sources":["../../src/core/fence-diagnostics.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/core/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAChD,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAC9C,OAAO,EAAE,mBAAmB,EAAE,MAAM,kBAAkB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"type-mapper.js","sourceRoot":"","sources":["../../src/core/type-mapper.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AAEnD;;GAEG;AACH,MAAM,UAAU,mBAAmB,CAAC,MAAc;IAChD,OAAO,iBAAiB,CAAC,MAAM,CAAC,CAAC;AACnC,CAAC"}
|
|
@@ -29,7 +29,12 @@ export interface FastAPIStreamCtx {
|
|
|
29
29
|
n: number;
|
|
30
30
|
};
|
|
31
31
|
}
|
|
32
|
-
|
|
32
|
+
interface FastAPIClosureHoistCtx {
|
|
33
|
+
seq: {
|
|
34
|
+
n: number;
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
export declare function generatePortableChildFastAPI(child: IRNode, indent: string, pathParams: string[], imports: Set<string>, bodyFields?: Set<string>, authUser?: boolean, streamCtx?: FastAPIStreamCtx, closureHoistCtx?: FastAPIClosureHoistCtx): string[];
|
|
33
38
|
export declare function generatePortableHandlerFastAPI(routeNode: IRNode, indent: string, pathParams: string[], imports: Set<string>, bodyFields?: Set<string>, authUser?: boolean): string[];
|
|
34
39
|
export declare function hasPortableStreamBodyFastAPI(streamNode: IRNode): boolean;
|
|
35
40
|
/**
|
|
@@ -40,3 +45,4 @@ export declare function hasPortableStreamBodyFastAPI(streamNode: IRNode): boolea
|
|
|
40
45
|
* in a `StreamingResponse`.
|
|
41
46
|
*/
|
|
42
47
|
export declare function generatePortableStreamFastAPI(streamNode: IRNode, indent: string, pathParams: string[], imports: Set<string>, bodyFields?: Set<string>, authUser?: boolean): string[];
|
|
48
|
+
export {};
|