@kernlang/python 3.5.2
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/LICENSE +678 -0
- package/README.md +26 -0
- package/dist/codegen-body-python.d.ts +152 -0
- package/dist/codegen-body-python.js +1648 -0
- package/dist/codegen-body-python.js.map +1 -0
- package/dist/codegen-helpers.d.ts +21 -0
- package/dist/codegen-helpers.js +352 -0
- package/dist/codegen-helpers.js.map +1 -0
- package/dist/codegen-python.d.ts +17 -0
- package/dist/codegen-python.js +106 -0
- package/dist/codegen-python.js.map +1 -0
- package/dist/fastapi-middleware.d.ts +8 -0
- package/dist/fastapi-middleware.js +87 -0
- package/dist/fastapi-middleware.js.map +1 -0
- package/dist/fastapi-portable.d.ts +9 -0
- package/dist/fastapi-portable.js +295 -0
- package/dist/fastapi-portable.js.map +1 -0
- package/dist/fastapi-raw-handler.d.ts +28 -0
- package/dist/fastapi-raw-handler.js +282 -0
- package/dist/fastapi-raw-handler.js.map +1 -0
- package/dist/fastapi-response.d.ts +13 -0
- package/dist/fastapi-response.js +150 -0
- package/dist/fastapi-response.js.map +1 -0
- package/dist/fastapi-route.d.ts +12 -0
- package/dist/fastapi-route.js +629 -0
- package/dist/fastapi-route.js.map +1 -0
- package/dist/fastapi-types.d.ts +39 -0
- package/dist/fastapi-types.js +5 -0
- package/dist/fastapi-types.js.map +1 -0
- package/dist/fastapi-utils.d.ts +16 -0
- package/dist/fastapi-utils.js +99 -0
- package/dist/fastapi-utils.js.map +1 -0
- package/dist/fastapi-websocket.d.ts +6 -0
- package/dist/fastapi-websocket.js +77 -0
- package/dist/fastapi-websocket.js.map +1 -0
- package/dist/generators/core.d.ts +23 -0
- package/dist/generators/core.js +906 -0
- package/dist/generators/core.js.map +1 -0
- package/dist/generators/data.d.ts +15 -0
- package/dist/generators/data.js +443 -0
- package/dist/generators/data.js.map +1 -0
- package/dist/generators/ground.d.ts +20 -0
- package/dist/generators/ground.js +333 -0
- package/dist/generators/ground.js.map +1 -0
- package/dist/generators/infra.d.ts +8 -0
- package/dist/generators/infra.js +109 -0
- package/dist/generators/infra.js.map +1 -0
- package/dist/index.d.ts +6 -0
- package/dist/index.js +7 -0
- package/dist/index.js.map +1 -0
- package/dist/ir-semantics/python-leg.d.ts +45 -0
- package/dist/ir-semantics/python-leg.js +291 -0
- package/dist/ir-semantics/python-leg.js.map +1 -0
- package/dist/python-stdlib-preamble.d.ts +32 -0
- package/dist/python-stdlib-preamble.js +86 -0
- package/dist/python-stdlib-preamble.js.map +1 -0
- package/dist/transpiler-fastapi.d.ts +8 -0
- package/dist/transpiler-fastapi.js +593 -0
- package/dist/transpiler-fastapi.js.map +1 -0
- package/dist/type-map.d.ts +14 -0
- package/dist/type-map.js +288 -0
- package/dist/type-map.js.map +1 -0
- package/package.json +37 -0
|
@@ -0,0 +1,282 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Detection + emission helpers for raw `<<<...>>>` handler bodies when the
|
|
3
|
+
* target is FastAPI/Python.
|
|
4
|
+
*
|
|
5
|
+
* Raw handler bodies are usually JavaScript/TypeScript — the legacy authoring
|
|
6
|
+
* form before native KERN body-stmts existed. The TS codegen path can emit
|
|
7
|
+
* them verbatim (it's already TypeScript), but the Python codegen must either
|
|
8
|
+
* lower them or refuse them; emitting raw JS inside a Python `def` produces
|
|
9
|
+
* invalid Python that breaks `ast.parse` on the generated module.
|
|
10
|
+
*
|
|
11
|
+
* Two helpers exposed:
|
|
12
|
+
* - `isUnsupportedJsHandlerBody`: returns true if the body uses
|
|
13
|
+
* JS-specific idioms that Python cannot accept verbatim (`res.X`,
|
|
14
|
+
* backtick template literals, optional chaining `?.`, nullish
|
|
15
|
+
* coalescing `??`, arrow functions `=>`, object shorthand inside
|
|
16
|
+
* literals).
|
|
17
|
+
* - `unsupportedRawHandlerBody`: returns the boilerplate Python that
|
|
18
|
+
* replaces an unsupported body with a `NotImplementedError` raise,
|
|
19
|
+
* so the route file still parses + imports cleanly.
|
|
20
|
+
*
|
|
21
|
+
* Co-locating these here (instead of inside fastapi-route.ts) lets the
|
|
22
|
+
* portable-handler path in fastapi-portable.ts apply the same guard without
|
|
23
|
+
* introducing an import cycle between portable and route.
|
|
24
|
+
*/
|
|
25
|
+
// Sticky-flag (`y`) regex that finds a candidate JS private-field-start
|
|
26
|
+
// at the `lastIndex` position. Either:
|
|
27
|
+
// - A JS identifier-start codepoint directly: ASCII letters/`_`/`$`
|
|
28
|
+
// plus the full Unicode `ID_Start` category (matches whole
|
|
29
|
+
// codepoints via `u` flag, so non-BMP surrogate pairs work).
|
|
30
|
+
// - A `\uXXXX` (4 hex digits) or `\u{...}` Unicode-escape sequence —
|
|
31
|
+
// the FORM JS uses for escaped identifier characters. Note: the
|
|
32
|
+
// escape's decoded codepoint must still be `ID_Start`-valid; that
|
|
33
|
+
// check happens in `isPrivateFieldStartAt` below per Codex fix-up
|
|
34
|
+
// 17 review (`#0` decodes to `0` which is NOT ID_Start).
|
|
35
|
+
// Sticky `y` (not anchored `^` on a slice) avoids O(N²) string allocation
|
|
36
|
+
// per `#` encounter (Gemini fix-up 15 perf review).
|
|
37
|
+
const PRIVATE_FIELD_START_AT_RE = /[$_\p{ID_Start}]|\\u(?:[0-9A-Fa-f]{4}|\{[0-9A-Fa-f]+\})/uy;
|
|
38
|
+
const ID_START_RE = /[$_\p{ID_Start}]/u;
|
|
39
|
+
// Tests whether `code[pos]` begins a JS private-field-name (i.e., the
|
|
40
|
+
// character/sequence after a `#`). Returns true only when the matched
|
|
41
|
+
// thing is a real JS identifier-start: either a literal ID_Start
|
|
42
|
+
// codepoint, OR a `\u`-escape whose decoded codepoint IS ID_Start.
|
|
43
|
+
function isPrivateFieldStartAt(code, pos) {
|
|
44
|
+
PRIVATE_FIELD_START_AT_RE.lastIndex = pos;
|
|
45
|
+
const matched = code.match(PRIVATE_FIELD_START_AT_RE);
|
|
46
|
+
if (!matched || matched.index !== pos)
|
|
47
|
+
return false;
|
|
48
|
+
const matchedText = matched[0];
|
|
49
|
+
if (!matchedText.startsWith('\\u'))
|
|
50
|
+
return true; // direct ID_Start codepoint
|
|
51
|
+
// `\uXXXX` or `\u{...}` — decode the hex and re-validate the resulting
|
|
52
|
+
// codepoint against `ID_Start`. Without this, `#0` (decodes to
|
|
53
|
+
// `0`, not an identifier-start) would be preserved as code.
|
|
54
|
+
const hex = matchedText.startsWith('\\u{') ? matchedText.slice(3, -1) : matchedText.slice(2);
|
|
55
|
+
const codepoint = Number.parseInt(hex, 16);
|
|
56
|
+
if (!Number.isFinite(codepoint) || codepoint > 0x10ffff)
|
|
57
|
+
return false;
|
|
58
|
+
return ID_START_RE.test(String.fromCodePoint(codepoint));
|
|
59
|
+
}
|
|
60
|
+
// Replace contents of every string literal AND comment with `_` so
|
|
61
|
+
// JS-keyword detection regexes don't false-positive on tokens that
|
|
62
|
+
// appear only inside strings or comments. Preserves quote delimiters,
|
|
63
|
+
// newlines, and code outside strings. Honors backslash escapes so
|
|
64
|
+
// `"\""` doesn't terminate the string early.
|
|
65
|
+
//
|
|
66
|
+
// Comment forms recognized:
|
|
67
|
+
// - Python line comments: `# ...` to end of line
|
|
68
|
+
// - JS line comments: `// ...` to end of line
|
|
69
|
+
// - JS block comments: `/* ... */`
|
|
70
|
+
//
|
|
71
|
+
// Review fix: Codex flagged on commit 68565826 that the original
|
|
72
|
+
// version stripped strings but NOT comments — a `lang="python"` body
|
|
73
|
+
// containing `# const x = 1` (a comment mentioning JS syntax) would
|
|
74
|
+
// still trip the `\bconst\s+\w+\s*=` regex and emit a NotImplementedError
|
|
75
|
+
// for valid Python.
|
|
76
|
+
export function stripStringsForJsCheck(code) {
|
|
77
|
+
let result = '';
|
|
78
|
+
let i = 0;
|
|
79
|
+
// null | quote-char | '//' (JS line) | '#' (Python line) | '/*' (JS block)
|
|
80
|
+
let mode = null;
|
|
81
|
+
let escaped = false;
|
|
82
|
+
while (i < code.length) {
|
|
83
|
+
const ch = code[i];
|
|
84
|
+
const next = code[i + 1];
|
|
85
|
+
if (mode === '"' || mode === "'" || mode === '`') {
|
|
86
|
+
if (escaped) {
|
|
87
|
+
escaped = false;
|
|
88
|
+
result += '_';
|
|
89
|
+
}
|
|
90
|
+
else if (ch === '\\') {
|
|
91
|
+
escaped = true;
|
|
92
|
+
result += '_';
|
|
93
|
+
}
|
|
94
|
+
else if (ch === mode) {
|
|
95
|
+
mode = null;
|
|
96
|
+
result += ch;
|
|
97
|
+
}
|
|
98
|
+
else {
|
|
99
|
+
result += ch === '\n' ? '\n' : '_';
|
|
100
|
+
}
|
|
101
|
+
i += 1;
|
|
102
|
+
continue;
|
|
103
|
+
}
|
|
104
|
+
if (mode === '//' || mode === '#') {
|
|
105
|
+
if (ch === '\n') {
|
|
106
|
+
mode = null;
|
|
107
|
+
result += '\n';
|
|
108
|
+
}
|
|
109
|
+
else {
|
|
110
|
+
result += '_';
|
|
111
|
+
}
|
|
112
|
+
i += 1;
|
|
113
|
+
continue;
|
|
114
|
+
}
|
|
115
|
+
if (mode === '/*') {
|
|
116
|
+
if (ch === '*' && next === '/') {
|
|
117
|
+
mode = null;
|
|
118
|
+
result += '__';
|
|
119
|
+
i += 2;
|
|
120
|
+
continue;
|
|
121
|
+
}
|
|
122
|
+
result += ch === '\n' ? '\n' : '_';
|
|
123
|
+
i += 1;
|
|
124
|
+
continue;
|
|
125
|
+
}
|
|
126
|
+
// mode is null — code mode
|
|
127
|
+
if (ch === '"' || ch === "'" || ch === '`') {
|
|
128
|
+
mode = ch;
|
|
129
|
+
result += ch;
|
|
130
|
+
i += 1;
|
|
131
|
+
continue;
|
|
132
|
+
}
|
|
133
|
+
if (ch === '/' && next === '/') {
|
|
134
|
+
mode = '//';
|
|
135
|
+
result += '__';
|
|
136
|
+
i += 2;
|
|
137
|
+
continue;
|
|
138
|
+
}
|
|
139
|
+
if (ch === '/' && next === '*') {
|
|
140
|
+
mode = '/*';
|
|
141
|
+
result += '__';
|
|
142
|
+
i += 2;
|
|
143
|
+
continue;
|
|
144
|
+
}
|
|
145
|
+
if (ch === '#') {
|
|
146
|
+
// `#` is a Python line comment ONLY when not directly followed by
|
|
147
|
+
// a JS identifier-start character (or a valid Unicode-escape
|
|
148
|
+
// identifier-escape sequence). Modern JS uses `#x` for private
|
|
149
|
+
// class fields; treating those as comments would hide real JS.
|
|
150
|
+
//
|
|
151
|
+
// The sticky regex tests at exactly position `i + 1` without
|
|
152
|
+
// creating a slice — O(1) per `#` (Gemini fix-up 15 perf review).
|
|
153
|
+
const isPrivateFieldStart = next !== undefined && isPrivateFieldStartAt(code, i + 1);
|
|
154
|
+
if (isPrivateFieldStart) {
|
|
155
|
+
result += ch;
|
|
156
|
+
i += 1;
|
|
157
|
+
continue;
|
|
158
|
+
}
|
|
159
|
+
mode = '#';
|
|
160
|
+
result += '_';
|
|
161
|
+
i += 1;
|
|
162
|
+
continue;
|
|
163
|
+
}
|
|
164
|
+
result += ch;
|
|
165
|
+
i += 1;
|
|
166
|
+
}
|
|
167
|
+
return result;
|
|
168
|
+
}
|
|
169
|
+
export function hasObjectShorthandOutsideStrings(expr) {
|
|
170
|
+
let index = 0;
|
|
171
|
+
let quote = null;
|
|
172
|
+
let escaped = false;
|
|
173
|
+
while (index < expr.length) {
|
|
174
|
+
const char = expr[index];
|
|
175
|
+
if (quote) {
|
|
176
|
+
if (escaped) {
|
|
177
|
+
escaped = false;
|
|
178
|
+
}
|
|
179
|
+
else if (char === '\\') {
|
|
180
|
+
escaped = true;
|
|
181
|
+
}
|
|
182
|
+
else if (char === quote) {
|
|
183
|
+
quote = null;
|
|
184
|
+
}
|
|
185
|
+
index += 1;
|
|
186
|
+
continue;
|
|
187
|
+
}
|
|
188
|
+
if (char === '"' || char === "'" || char === '`') {
|
|
189
|
+
quote = char;
|
|
190
|
+
index += 1;
|
|
191
|
+
continue;
|
|
192
|
+
}
|
|
193
|
+
if (char !== '{' && char !== ',') {
|
|
194
|
+
index += 1;
|
|
195
|
+
continue;
|
|
196
|
+
}
|
|
197
|
+
index += 1;
|
|
198
|
+
while (index < expr.length && /\s/.test(expr[index]))
|
|
199
|
+
index += 1;
|
|
200
|
+
if (index >= expr.length || !/[A-Za-z_$]/.test(expr[index]))
|
|
201
|
+
continue;
|
|
202
|
+
index += 1;
|
|
203
|
+
while (index < expr.length && /[\w$]/.test(expr[index]))
|
|
204
|
+
index += 1;
|
|
205
|
+
while (index < expr.length && /\s/.test(expr[index]))
|
|
206
|
+
index += 1;
|
|
207
|
+
if (expr[index] === ',' || expr[index] === '}')
|
|
208
|
+
return true;
|
|
209
|
+
}
|
|
210
|
+
return false;
|
|
211
|
+
}
|
|
212
|
+
// NOTE on cross-file asymmetry: `isUnsupportedJsHandlerBody` (this
|
|
213
|
+
// function) inspects FULL HANDLER BODIES which contain multiple
|
|
214
|
+
// statements — Python like `return new\nDate()` is two statements
|
|
215
|
+
// and must NOT false-positive. Hence the `new` regexes here use
|
|
216
|
+
// horizontal-whitespace-only `[^\S\r\n]+`.
|
|
217
|
+
//
|
|
218
|
+
// The sister guard `isLowerableJsValueExpression` in fastapi-route.ts
|
|
219
|
+
// inspects EXPRESSION CONTENT (e.g., the X in `res.json(X)`) — a single
|
|
220
|
+
// syntactic unit with no statement boundaries, so it can safely use
|
|
221
|
+
// `\s+` (newlines OK) to catch `new\nDate()` etc. The asymmetry is
|
|
222
|
+
// principled per Codex fix-up 16 review.
|
|
223
|
+
export function isUnsupportedJsHandlerBody(code) {
|
|
224
|
+
// Run JS-keyword detection on a string-stripped view so a Python body
|
|
225
|
+
// like `text = "uses res.send pattern"` or `msg = "const x = ..."`
|
|
226
|
+
// doesn't false-positive. Backticks INSIDE strings are stripped to `_`,
|
|
227
|
+
// but unmatched backticks outside strings (i.e., JS template literals)
|
|
228
|
+
// still trip the check.
|
|
229
|
+
//
|
|
230
|
+
// M1 (Codex+Gemini on ae9663cf): the const/let/var detection used to
|
|
231
|
+
// only match `\bKEYWORD\s+\w+\s*=` — missed destructuring forms
|
|
232
|
+
// (`const {x} = obj`, `const [a] = arr`) and for-loop variants
|
|
233
|
+
// (`for (var x of list)`, `for (let x in obj)`). Both are common JS
|
|
234
|
+
// and produce invalid Python. Adding two more alternatives below.
|
|
235
|
+
// The `var x;` no-init form is intentionally NOT detected: broadening
|
|
236
|
+
// there would false-positive on Python `for var in items:` where `var`
|
|
237
|
+
// is a Python loop variable name (not a keyword).
|
|
238
|
+
//
|
|
239
|
+
// M2 (Gemini+Codex on 85593a3f): drop the `[A-Z]` PascalCase constraint
|
|
240
|
+
// on the `new` check and broaden to dotted callables — `new foo()`,
|
|
241
|
+
// `new globalThis.Date()`, etc. all produce SyntaxError in Python.
|
|
242
|
+
const stripped = stripStringsForJsCheck(code);
|
|
243
|
+
return (/\bres\./.test(stripped) ||
|
|
244
|
+
/`/.test(stripped) ||
|
|
245
|
+
/\?\./.test(stripped) ||
|
|
246
|
+
/\?\?/.test(stripped) ||
|
|
247
|
+
/=>/.test(stripped) ||
|
|
248
|
+
/\b(?:const|let|var)\s+[A-Za-z_$][\w$]*\s*=/.test(stripped) || // assignment form ($-identifiers; JS identifiers don't start with digits)
|
|
249
|
+
/\b(?:const|let|var)\s+[{[]/.test(stripped) || // destructuring form
|
|
250
|
+
/\bfor(?:\s+await)?\s*\(\s*(?:var|let|const)\s+/.test(stripped) || // for / for-await loop variant
|
|
251
|
+
// Parens form `new X(...)`. Horizontal-whitespace-only `[^\S\r\n]+`
|
|
252
|
+
// between `new` and the identifier — even though JS allows `new\n
|
|
253
|
+
// Date()`, Python `return new\nDate()` IS valid (two statements:
|
|
254
|
+
// `return new`, then `Date()`). Codex's fix-up 14 review correctly
|
|
255
|
+
// pointed out that the cross-newline match false-flags the Python
|
|
256
|
+
// case. The trade-off: a prettier-formatted JS source with
|
|
257
|
+
// `new\nLongConstructor()` slips the leak guard. Acceptable because:
|
|
258
|
+
// 1. Most JS authoring keeps `new Foo()` on one line.
|
|
259
|
+
// 2. The slipped JS still produces invalid Python downstream
|
|
260
|
+
// (Python's `new` keyword doesn't exist), so the failure mode
|
|
261
|
+
// is "generated module fails to import" — visible, not silent.
|
|
262
|
+
// 3. Python correctness > JS-edge-detection per the cross-target
|
|
263
|
+
// safety doctrine of this arc.
|
|
264
|
+
/\bnew[^\S\r\n]+[A-Za-z_$][\w$]*(?:\.[A-Za-z_$][\w$]*)*\s*\(/.test(stripped) || // ctor with parens
|
|
265
|
+
// `new Foo` without parens is also valid JS (e.g., `return new Date`)
|
|
266
|
+
// and produces SyntaxError in Python. Two false-positive guards
|
|
267
|
+
// address review on fix-up 8 (Codex+Gemini, gemini-blocking):
|
|
268
|
+
// 1. Variable-width lookbehind `(?<!\bfor\s+)` — handles
|
|
269
|
+
// `for new in items:` with any whitespace between `for` and
|
|
270
|
+
// `new` (was single-space only).
|
|
271
|
+
// 2. Negative lookahead for Python keywords after `new` — excludes
|
|
272
|
+
// `new is None`, `new in items`, `new for x in seq`,
|
|
273
|
+
// `new if cond else other`, `new and other`, `new or other`,
|
|
274
|
+
// `new not other`. These are all valid Python where `new` is
|
|
275
|
+
// a local variable name, not a JS construction.
|
|
276
|
+
/(?<!\bfor[^\S\r\n]+)\bnew[^\S\r\n]+(?!(?:is|in|for|if|else|and|or|not)\b)[A-Za-z_$][\w$]*(?:\.[A-Za-z_$][\w$]*)*\b/.test(stripped) ||
|
|
277
|
+
hasObjectShorthandOutsideStrings(code));
|
|
278
|
+
}
|
|
279
|
+
export function unsupportedRawHandlerBody(indent) {
|
|
280
|
+
return [`${indent}raise NotImplementedError("Unsupported raw JavaScript handler syntax for FastAPI target")`];
|
|
281
|
+
}
|
|
282
|
+
//# sourceMappingURL=fastapi-raw-handler.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fastapi-raw-handler.js","sourceRoot":"","sources":["../src/fastapi-raw-handler.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Response helpers for the FastAPI transpiler.
|
|
3
|
+
*
|
|
4
|
+
* generateRespondFastAPI — IR respond node → Python return/raise statements
|
|
5
|
+
* rewriteFastAPIExpr — rewrite portable request references to FastAPI equivalents
|
|
6
|
+
* extractExprCode — extract expression code from IR prop
|
|
7
|
+
* addRespondImports — add necessary imports for respond node
|
|
8
|
+
*/
|
|
9
|
+
import type { IRNode } from '@kernlang/core';
|
|
10
|
+
export declare function generateRespondFastAPI(respondNode: IRNode, indent: string): string[];
|
|
11
|
+
export declare function rewriteFastAPIExpr(expr: string, pathParams: string[]): string;
|
|
12
|
+
export declare function extractExprCode(prop: unknown): string;
|
|
13
|
+
export declare function addRespondImports(respondNode: IRNode, imports: Set<string>): void;
|
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Response helpers for the FastAPI transpiler.
|
|
3
|
+
*
|
|
4
|
+
* generateRespondFastAPI — IR respond node → Python return/raise statements
|
|
5
|
+
* rewriteFastAPIExpr — rewrite portable request references to FastAPI equivalents
|
|
6
|
+
* extractExprCode — extract expression code from IR prop
|
|
7
|
+
* addRespondImports — add necessary imports for respond node
|
|
8
|
+
*/
|
|
9
|
+
import { getProps } from '@kernlang/core';
|
|
10
|
+
import { escapePyStr } from './fastapi-utils.js';
|
|
11
|
+
import { toSnakeCase } from './type-map.js';
|
|
12
|
+
export function generateRespondFastAPI(respondNode, indent) {
|
|
13
|
+
const p = getProps(respondNode);
|
|
14
|
+
const status = typeof p.status === 'number' ? p.status : undefined;
|
|
15
|
+
const json = p.json;
|
|
16
|
+
const error = p.error;
|
|
17
|
+
const text = p.text;
|
|
18
|
+
const redirect = p.redirect;
|
|
19
|
+
if (redirect) {
|
|
20
|
+
return [`${indent}return RedirectResponse(url="${escapePyStr(String(redirect))}")`];
|
|
21
|
+
}
|
|
22
|
+
if (error) {
|
|
23
|
+
return [`${indent}raise HTTPException(status_code=${status || 500}, detail="${escapePyStr(String(error))}")`];
|
|
24
|
+
}
|
|
25
|
+
if (json) {
|
|
26
|
+
if (!status || status === 200) {
|
|
27
|
+
return [`${indent}return ${json}`];
|
|
28
|
+
}
|
|
29
|
+
return [`${indent}return JSONResponse(content=${json}, status_code=${status})`];
|
|
30
|
+
}
|
|
31
|
+
if (text) {
|
|
32
|
+
if (!status || status === 200) {
|
|
33
|
+
return [`${indent}return PlainTextResponse(content=${text})`];
|
|
34
|
+
}
|
|
35
|
+
return [`${indent}return PlainTextResponse(content=${text}, status_code=${status})`];
|
|
36
|
+
}
|
|
37
|
+
if (status === 204) {
|
|
38
|
+
return [`${indent}return Response(status_code=204)`];
|
|
39
|
+
}
|
|
40
|
+
if (status) {
|
|
41
|
+
return [`${indent}return Response(status_code=${status})`];
|
|
42
|
+
}
|
|
43
|
+
return [`${indent}return Response(status_code=200)`];
|
|
44
|
+
}
|
|
45
|
+
// One level of nested parens inside the arrow body: matches `(u.age > 18)`,
|
|
46
|
+
// `Math.max(a, b)`, etc. Two-or-more levels still fall through (acceptable
|
|
47
|
+
// fallback per the lift-rate metric).
|
|
48
|
+
const ARROW_BODY = '((?:[^()]|\\([^()]*\\))+)';
|
|
49
|
+
// Receiver allows brackets + spaces so chained calls work after the inner
|
|
50
|
+
// call has already been rewritten to a list-comprehension (which contains
|
|
51
|
+
// brackets). The outer iteration re-runs the regex on the rewritten form.
|
|
52
|
+
const ARROW_RECEIVER = '([\\w.\\[\\] ]+?)';
|
|
53
|
+
const FILTER_RE = new RegExp(`${ARROW_RECEIVER}\\.filter\\(\\((\\w+)\\)\\s*=>\\s*${ARROW_BODY}\\)`, 'g');
|
|
54
|
+
const MAP_RE = new RegExp(`${ARROW_RECEIVER}\\.map\\(\\((\\w+)\\)\\s*=>\\s*${ARROW_BODY}\\)`, 'g');
|
|
55
|
+
const FIND_RE = new RegExp(`${ARROW_RECEIVER}\\.find\\(\\((\\w+)\\)\\s*=>\\s*${ARROW_BODY}\\)`, 'g');
|
|
56
|
+
// Quoted strings absorbed by the alternation; only literal `===`/`!==`
|
|
57
|
+
// outside strings get rewritten. Both single and double quotes AND
|
|
58
|
+
// backtick template literals are covered so a message like
|
|
59
|
+
// `` `use ===` `` is preserved (review fix — Codex+Gemini on 0ddfcc3d
|
|
60
|
+
// flagged backticks as missing). Escape sequences are honored so
|
|
61
|
+
// `"\""` / `` `\`` `` etc. don't terminate the string early.
|
|
62
|
+
const STRING_LITERAL_ALT = '"(?:[^"\\\\]|\\\\.)*"|\'(?:[^\'\\\\]|\\\\.)*\'|`(?:[^`\\\\]|\\\\.)*`';
|
|
63
|
+
const STRICT_EQ_RE = new RegExp(`${STRING_LITERAL_ALT}|===|!==`, 'g');
|
|
64
|
+
// Same trick for JS-literal lowering: any literal text inside a quoted
|
|
65
|
+
// string OR after a `.` (property accessor — `obj.true` must NOT become
|
|
66
|
+
// `obj.True`, which is a Python SyntaxError) is preserved untouched.
|
|
67
|
+
// Variable-width lookbehind `(?<!\.\s*)` handles both tight (`obj.true`)
|
|
68
|
+
// and loose (`obj . true`) forms; the latter caught by Codex review on
|
|
69
|
+
// commit 68565826.
|
|
70
|
+
const JS_LITERAL_RE = new RegExp(`${STRING_LITERAL_ALT}|(?<!\\.\\s*)\\b(?:undefined|null|true|false)\\b`, 'g');
|
|
71
|
+
function lowerJsArrayMethods(expr) {
|
|
72
|
+
// Iterate so chained calls (`.filter(...).map(...)`) collapse fully.
|
|
73
|
+
// Each pass rewrites the innermost matchable call; the broadened
|
|
74
|
+
// receiver picks up the list-comprehension produced by the prior pass.
|
|
75
|
+
// Bounded at 8 iterations to prevent any accidental infinite-loop bug;
|
|
76
|
+
// realistic chains rarely exceed 3-4 calls.
|
|
77
|
+
let prev = '';
|
|
78
|
+
let next = expr;
|
|
79
|
+
let i = 0;
|
|
80
|
+
while (prev !== next && i < 8) {
|
|
81
|
+
prev = next;
|
|
82
|
+
next = next
|
|
83
|
+
.replace(FILTER_RE, (_m, arr, varName, pred) => `[${varName} for ${varName} in ${arr} if ${pred}]`)
|
|
84
|
+
.replace(MAP_RE, (_m, arr, varName, body) => `[${body} for ${varName} in ${arr}]`)
|
|
85
|
+
.replace(FIND_RE, (_m, arr, varName, pred) => `next((${varName} for ${varName} in ${arr} if ${pred}), None)`);
|
|
86
|
+
i += 1;
|
|
87
|
+
}
|
|
88
|
+
return next;
|
|
89
|
+
}
|
|
90
|
+
export function rewriteFastAPIExpr(expr, pathParams) {
|
|
91
|
+
let result = expr;
|
|
92
|
+
// params.X → X (function param) for path params
|
|
93
|
+
for (const param of pathParams) {
|
|
94
|
+
result = result.replace(new RegExp(`\\bparams\\.${param}\\b`, 'g'), param);
|
|
95
|
+
}
|
|
96
|
+
// Fallback: any remaining params.X → X (for query params not in pathParams)
|
|
97
|
+
result = result.replace(/\bparams\.([A-Za-z_]\w*)/g, '$1');
|
|
98
|
+
// body.X → body.X (Pydantic model — already correct)
|
|
99
|
+
// query.X → X (function param)
|
|
100
|
+
result = result.replace(/\bquery\.([A-Za-z_]\w*)/g, '$1');
|
|
101
|
+
// headers.X → request.headers.get("X")
|
|
102
|
+
result = result.replace(/\bheaders\.([A-Za-z_][\w-]*)/g, (_m, key) => `request.headers.get("${key}")`);
|
|
103
|
+
// effectName.result → effect_name (effect variables hold the result directly, snake_cased)
|
|
104
|
+
result = result.replace(/\b([A-Za-z_]\w*)\.result\b/g, (_m, name) => toSnakeCase(name));
|
|
105
|
+
// ── JS-to-Python expression lowerings ─────────────────────────────────
|
|
106
|
+
// Array methods first (so any `===` inside an arrow body is hoisted into
|
|
107
|
+
// a list-comprehension predicate that the strict-equality pass below
|
|
108
|
+
// then catches).
|
|
109
|
+
result = lowerJsArrayMethods(result);
|
|
110
|
+
// Strict equality: skip text inside quoted strings so a user message
|
|
111
|
+
// like `"use === for strict equality"` doesn't get mangled to `==`.
|
|
112
|
+
result = result.replace(STRICT_EQ_RE, (match) => {
|
|
113
|
+
if (match === '===')
|
|
114
|
+
return '==';
|
|
115
|
+
if (match === '!==')
|
|
116
|
+
return '!=';
|
|
117
|
+
return match; // quoted string — return unchanged
|
|
118
|
+
});
|
|
119
|
+
// JS literals → Python equivalents. Same string-skip trick — a message
|
|
120
|
+
// like `"undefined behavior"` must not be rewritten to `"None behavior"`.
|
|
121
|
+
result = result.replace(JS_LITERAL_RE, (match) => {
|
|
122
|
+
if (match === 'undefined' || match === 'null')
|
|
123
|
+
return 'None';
|
|
124
|
+
if (match === 'true')
|
|
125
|
+
return 'True';
|
|
126
|
+
if (match === 'false')
|
|
127
|
+
return 'False';
|
|
128
|
+
return match; // quoted string
|
|
129
|
+
});
|
|
130
|
+
return result;
|
|
131
|
+
}
|
|
132
|
+
export function extractExprCode(prop) {
|
|
133
|
+
if (typeof prop === 'object' && prop !== null && prop.__expr)
|
|
134
|
+
return prop.code;
|
|
135
|
+
return typeof prop === 'string' ? prop : '';
|
|
136
|
+
}
|
|
137
|
+
export function addRespondImports(respondNode, imports) {
|
|
138
|
+
const rp = getProps(respondNode);
|
|
139
|
+
if (rp.redirect)
|
|
140
|
+
imports.add('from fastapi.responses import RedirectResponse');
|
|
141
|
+
if (rp.text)
|
|
142
|
+
imports.add('from fastapi.responses import PlainTextResponse');
|
|
143
|
+
if (typeof rp.status === 'number' && rp.status !== 200 && rp.json)
|
|
144
|
+
imports.add('from fastapi.responses import JSONResponse');
|
|
145
|
+
if (typeof rp.status === 'number' && !rp.json && !rp.text && !rp.redirect && !rp.error)
|
|
146
|
+
imports.add('from fastapi.responses import Response');
|
|
147
|
+
if (rp.error)
|
|
148
|
+
imports.add('from fastapi import HTTPException');
|
|
149
|
+
}
|
|
150
|
+
//# sourceMappingURL=fastapi-response.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fastapi-response.js","sourceRoot":"","sources":["../src/fastapi-response.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Route artifact builders for the FastAPI transpiler.
|
|
3
|
+
*
|
|
4
|
+
* generateStreamRoute — SSE streaming route
|
|
5
|
+
* generateTimerRoute — timeout-wrapped route
|
|
6
|
+
* buildRouteArtifact — main route artifact builder
|
|
7
|
+
*/
|
|
8
|
+
import type { IRNode, SourceMapEntry } from '@kernlang/core';
|
|
9
|
+
import type { RouteArtifactRef, RouteCapabilities } from './fastapi-types.js';
|
|
10
|
+
export declare function generateStreamRoute(_routeNode: IRNode, caps: RouteCapabilities, method: string, fastapiPath: string, pathParams: string[]): string[];
|
|
11
|
+
export declare function generateTimerRoute(_routeNode: IRNode, caps: RouteCapabilities, method: string, fastapiPath: string, pathParams: string[], handlerCode: string): string[];
|
|
12
|
+
export declare function buildRouteArtifact(routeNode: IRNode, routeIndex: number, sourceMap: SourceMapEntry[]): RouteArtifactRef;
|