@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.
Files changed (63) hide show
  1. package/LICENSE +678 -0
  2. package/README.md +26 -0
  3. package/dist/codegen-body-python.d.ts +152 -0
  4. package/dist/codegen-body-python.js +1648 -0
  5. package/dist/codegen-body-python.js.map +1 -0
  6. package/dist/codegen-helpers.d.ts +21 -0
  7. package/dist/codegen-helpers.js +352 -0
  8. package/dist/codegen-helpers.js.map +1 -0
  9. package/dist/codegen-python.d.ts +17 -0
  10. package/dist/codegen-python.js +106 -0
  11. package/dist/codegen-python.js.map +1 -0
  12. package/dist/fastapi-middleware.d.ts +8 -0
  13. package/dist/fastapi-middleware.js +87 -0
  14. package/dist/fastapi-middleware.js.map +1 -0
  15. package/dist/fastapi-portable.d.ts +9 -0
  16. package/dist/fastapi-portable.js +295 -0
  17. package/dist/fastapi-portable.js.map +1 -0
  18. package/dist/fastapi-raw-handler.d.ts +28 -0
  19. package/dist/fastapi-raw-handler.js +282 -0
  20. package/dist/fastapi-raw-handler.js.map +1 -0
  21. package/dist/fastapi-response.d.ts +13 -0
  22. package/dist/fastapi-response.js +150 -0
  23. package/dist/fastapi-response.js.map +1 -0
  24. package/dist/fastapi-route.d.ts +12 -0
  25. package/dist/fastapi-route.js +629 -0
  26. package/dist/fastapi-route.js.map +1 -0
  27. package/dist/fastapi-types.d.ts +39 -0
  28. package/dist/fastapi-types.js +5 -0
  29. package/dist/fastapi-types.js.map +1 -0
  30. package/dist/fastapi-utils.d.ts +16 -0
  31. package/dist/fastapi-utils.js +99 -0
  32. package/dist/fastapi-utils.js.map +1 -0
  33. package/dist/fastapi-websocket.d.ts +6 -0
  34. package/dist/fastapi-websocket.js +77 -0
  35. package/dist/fastapi-websocket.js.map +1 -0
  36. package/dist/generators/core.d.ts +23 -0
  37. package/dist/generators/core.js +906 -0
  38. package/dist/generators/core.js.map +1 -0
  39. package/dist/generators/data.d.ts +15 -0
  40. package/dist/generators/data.js +443 -0
  41. package/dist/generators/data.js.map +1 -0
  42. package/dist/generators/ground.d.ts +20 -0
  43. package/dist/generators/ground.js +333 -0
  44. package/dist/generators/ground.js.map +1 -0
  45. package/dist/generators/infra.d.ts +8 -0
  46. package/dist/generators/infra.js +109 -0
  47. package/dist/generators/infra.js.map +1 -0
  48. package/dist/index.d.ts +6 -0
  49. package/dist/index.js +7 -0
  50. package/dist/index.js.map +1 -0
  51. package/dist/ir-semantics/python-leg.d.ts +45 -0
  52. package/dist/ir-semantics/python-leg.js +291 -0
  53. package/dist/ir-semantics/python-leg.js.map +1 -0
  54. package/dist/python-stdlib-preamble.d.ts +32 -0
  55. package/dist/python-stdlib-preamble.js +86 -0
  56. package/dist/python-stdlib-preamble.js.map +1 -0
  57. package/dist/transpiler-fastapi.d.ts +8 -0
  58. package/dist/transpiler-fastapi.js +593 -0
  59. package/dist/transpiler-fastapi.js.map +1 -0
  60. package/dist/type-map.d.ts +14 -0
  61. package/dist/type-map.js +288 -0
  62. package/dist/type-map.js.map +1 -0
  63. 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;