@timo9378/flow2code 0.1.9 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (50) hide show
  1. package/CHANGELOG.md +21 -0
  2. package/README.md +15 -2
  3. package/dist/cli.js +101978 -830
  4. package/dist/compiler.cjs +32 -2
  5. package/dist/compiler.d.cts +6 -0
  6. package/dist/compiler.d.ts +6 -0
  7. package/dist/compiler.js +32 -2
  8. package/dist/server.d.ts +1 -1
  9. package/dist/server.js +102677 -1379
  10. package/out/404.html +1 -1
  11. package/out/__next.__PAGE__.txt +4 -4
  12. package/out/__next._full.txt +13 -13
  13. package/out/__next._head.txt +4 -4
  14. package/out/__next._index.txt +6 -6
  15. package/out/__next._tree.txt +2 -2
  16. package/out/_next/static/chunks/05328cd26bdc795c.js +176 -0
  17. package/out/_next/static/chunks/06e01c846ae01892.js +1 -0
  18. package/out/_next/static/chunks/1011f174944c0ca2.js +70 -0
  19. package/out/_next/static/chunks/1570e9ba5f1b44ed.js +5 -0
  20. package/out/_next/static/chunks/6167fccccde2e675.css +1 -0
  21. package/out/_next/static/chunks/{b112c2f519e4b429.js → 7cd04052abfadac1.js} +1 -1
  22. package/out/_next/static/chunks/8091c1216a95d294.js +1 -0
  23. package/out/_next/static/chunks/98d53aae29c36c6b.js +1 -0
  24. package/out/_next/static/chunks/a6dad97d9634a72d.js.map +1 -1
  25. package/out/_next/static/chunks/{b163b5d7cccbcf42.js → b05daf00cdc6058f.js} +1 -1
  26. package/out/_next/static/chunks/b3419ee3e3a616d9.js +1 -0
  27. package/out/_next/static/chunks/{acf223168ac429f7.js → be40d79540010a0d.js} +1 -1
  28. package/out/_next/static/chunks/{turbopack-576234c945ffdc44.js → turbopack-9da9810f42c97265.js} +1 -1
  29. package/out/_not-found/__next._full.txt +11 -11
  30. package/out/_not-found/__next._head.txt +4 -4
  31. package/out/_not-found/__next._index.txt +6 -6
  32. package/out/_not-found/__next._not-found/__PAGE__.txt +2 -2
  33. package/out/_not-found/__next._not-found.txt +3 -3
  34. package/out/_not-found/__next._tree.txt +2 -2
  35. package/out/_not-found.html +1 -1
  36. package/out/_not-found.txt +11 -11
  37. package/out/index.html +2 -2
  38. package/out/index.txt +13 -13
  39. package/package.json +130 -124
  40. package/out/_next/static/chunks/0bc0a50347ee5f3c.js +0 -51
  41. package/out/_next/static/chunks/58bf94a9d7047ec0.js +0 -125
  42. package/out/_next/static/chunks/6b84376656bd9887.js +0 -1
  43. package/out/_next/static/chunks/83ab8820627f8bfe.css +0 -1
  44. package/out/_next/static/chunks/ab8888d4b78b94be.js +0 -5
  45. package/out/_next/static/chunks/b6e8711267bccbbd.js +0 -1
  46. package/out/_next/static/chunks/fbca595129527827.js +0 -1
  47. package/scripts/publish-all.sh +0 -56
  48. /package/out/_next/static/{Ma0MmC8j1mxpQbtLwNajF → hNOHolNViTvQRpVwfaIx-}/_buildManifest.js +0 -0
  49. /package/out/_next/static/{Ma0MmC8j1mxpQbtLwNajF → hNOHolNViTvQRpVwfaIx-}/_clientMiddlewareManifest.json +0 -0
  50. /package/out/_next/static/{Ma0MmC8j1mxpQbtLwNajF → hNOHolNViTvQRpVwfaIx-}/_ssgManifest.js +0 -0
package/dist/compiler.cjs CHANGED
@@ -281,14 +281,38 @@ function validateFlowIR(ir) {
281
281
  });
282
282
  }
283
283
  }
284
+ for (const edge of workingIR.edges) {
285
+ const sourceNode = workingNodeMap.get(edge.sourceNodeId);
286
+ const targetNode = workingNodeMap.get(edge.targetNodeId);
287
+ if (!sourceNode || !targetNode) continue;
288
+ const sourcePort = sourceNode.outputs?.find((p) => p.id === edge.sourcePortId);
289
+ const targetPort = targetNode.inputs?.find((p) => p.id === edge.targetPortId);
290
+ if (!sourcePort || !targetPort) continue;
291
+ if (!isTypeCompatible(sourcePort.dataType, targetPort.dataType)) {
292
+ errors.push({
293
+ code: "TYPE_MISMATCH",
294
+ message: `Type mismatch on edge "${edge.id}": output "${sourcePort.label}" (${sourcePort.dataType}) \u2192 input "${targetPort.label}" (${targetPort.dataType})`,
295
+ edgeId: edge.id,
296
+ severity: "warning"
297
+ });
298
+ }
299
+ }
284
300
  return {
285
- valid: errors.length === 0,
301
+ valid: errors.filter((e) => e.severity !== "warning" && e.severity !== "info").length === 0,
286
302
  errors,
287
303
  migrated,
288
304
  migratedIR: migrated ? workingIR : void 0,
289
305
  migrationLog
290
306
  };
291
307
  }
308
+ function isTypeCompatible(source, target) {
309
+ if (source === target) return true;
310
+ if (source === "any" || target === "any") return true;
311
+ if (target === "object" && source === "array") return true;
312
+ if (target === "string" && source === "number") return true;
313
+ if (target === "number" && source === "string") return true;
314
+ return false;
315
+ }
292
316
  function detectCycles(nodes, edges) {
293
317
  const errors = [];
294
318
  const adjacency = /* @__PURE__ */ new Map();
@@ -1848,6 +1872,9 @@ var RESERVED_WORDS = /* @__PURE__ */ new Set([
1848
1872
  ]);
1849
1873
 
1850
1874
  // src/lib/compiler/compiler.ts
1875
+ registerPlatform("nextjs", () => new NextjsPlatform());
1876
+ registerPlatform("express", () => new ExpressPlatform());
1877
+ registerPlatform("cloudflare", () => new CloudflarePlatform());
1851
1878
  function compile(ir, options) {
1852
1879
  const pluginRegistry = createPluginRegistry();
1853
1880
  pluginRegistry.registerAll(builtinPlugins);
@@ -1925,7 +1952,7 @@ function compile(ir, options) {
1925
1952
  indentSize: 2,
1926
1953
  convertTabsToSpaces: true
1927
1954
  });
1928
- const code = sourceFile.getFullText();
1955
+ let code = sourceFile.getFullText();
1929
1956
  const filePath = platform.getOutputFilePath(trigger);
1930
1957
  collectRequiredPackages(workingIR, context);
1931
1958
  const sourceMap = buildSourceMap(code, workingIR, filePath);
@@ -3375,6 +3402,7 @@ function withFlowTrace(handler, options) {
3375
3402
  formatTraceResults(err, traces, sourceMap.generatedFile)
3376
3403
  );
3377
3404
  }
3405
+ options.onTrace?.(traces, err);
3378
3406
  }
3379
3407
  throw err;
3380
3408
  }
@@ -3383,6 +3411,7 @@ function withFlowTrace(handler, options) {
3383
3411
  }
3384
3412
  function installFlowTracer(options) {
3385
3413
  const { sourceMap, ir, editorUrl = "http://localhost:3001", log = true } = options;
3414
+ const { onTrace } = options;
3386
3415
  const handleError = (err) => {
3387
3416
  if (!(err instanceof Error)) return;
3388
3417
  const traces = traceError(err, sourceMap, ir, editorUrl);
@@ -3391,6 +3420,7 @@ function installFlowTracer(options) {
3391
3420
  formatTraceResults(err, traces, sourceMap.generatedFile)
3392
3421
  );
3393
3422
  }
3423
+ onTrace?.(traces, err);
3394
3424
  };
3395
3425
  process.on("uncaughtException", handleError);
3396
3426
  process.on("unhandledRejection", handleError);
@@ -548,6 +548,8 @@ interface CompileOptions {
548
548
  platform?: PlatformName;
549
549
  /** Additional Node Plugins */
550
550
  plugins?: NodePlugin[];
551
+ /** Format output with Prettier (default: true) */
552
+ prettier?: boolean;
551
553
  }
552
554
  /**
553
555
  * Compiles FlowIR into TypeScript source code.
@@ -598,6 +600,8 @@ interface ValidationError {
598
600
  message: string;
599
601
  nodeId?: NodeId;
600
602
  edgeId?: string;
603
+ /** Severity level (default: "error") */
604
+ severity?: "error" | "warning" | "info";
601
605
  }
602
606
  interface ValidationResult {
603
607
  valid: boolean;
@@ -909,6 +913,8 @@ interface TracerOptions {
909
913
  ir?: FlowIR;
910
914
  /** Whether to print a readable error message to console (default: true) */
911
915
  log?: boolean;
916
+ /** Callback invoked when trace results are available (push to UI store for live badges) */
917
+ onTrace?: (results: TraceResult[], error: Error) => void;
912
918
  }
913
919
  /**
914
920
  * Extract all matching line numbers from an Error object's stack trace
@@ -548,6 +548,8 @@ interface CompileOptions {
548
548
  platform?: PlatformName;
549
549
  /** Additional Node Plugins */
550
550
  plugins?: NodePlugin[];
551
+ /** Format output with Prettier (default: true) */
552
+ prettier?: boolean;
551
553
  }
552
554
  /**
553
555
  * Compiles FlowIR into TypeScript source code.
@@ -598,6 +600,8 @@ interface ValidationError {
598
600
  message: string;
599
601
  nodeId?: NodeId;
600
602
  edgeId?: string;
603
+ /** Severity level (default: "error") */
604
+ severity?: "error" | "warning" | "info";
601
605
  }
602
606
  interface ValidationResult {
603
607
  valid: boolean;
@@ -909,6 +913,8 @@ interface TracerOptions {
909
913
  ir?: FlowIR;
910
914
  /** Whether to print a readable error message to console (default: true) */
911
915
  log?: boolean;
916
+ /** Callback invoked when trace results are available (push to UI store for live badges) */
917
+ onTrace?: (results: TraceResult[], error: Error) => void;
912
918
  }
913
919
  /**
914
920
  * Extract all matching line numbers from an Error object's stack trace
package/dist/compiler.js CHANGED
@@ -214,14 +214,38 @@ function validateFlowIR(ir) {
214
214
  });
215
215
  }
216
216
  }
217
+ for (const edge of workingIR.edges) {
218
+ const sourceNode = workingNodeMap.get(edge.sourceNodeId);
219
+ const targetNode = workingNodeMap.get(edge.targetNodeId);
220
+ if (!sourceNode || !targetNode) continue;
221
+ const sourcePort = sourceNode.outputs?.find((p) => p.id === edge.sourcePortId);
222
+ const targetPort = targetNode.inputs?.find((p) => p.id === edge.targetPortId);
223
+ if (!sourcePort || !targetPort) continue;
224
+ if (!isTypeCompatible(sourcePort.dataType, targetPort.dataType)) {
225
+ errors.push({
226
+ code: "TYPE_MISMATCH",
227
+ message: `Type mismatch on edge "${edge.id}": output "${sourcePort.label}" (${sourcePort.dataType}) \u2192 input "${targetPort.label}" (${targetPort.dataType})`,
228
+ edgeId: edge.id,
229
+ severity: "warning"
230
+ });
231
+ }
232
+ }
217
233
  return {
218
- valid: errors.length === 0,
234
+ valid: errors.filter((e) => e.severity !== "warning" && e.severity !== "info").length === 0,
219
235
  errors,
220
236
  migrated,
221
237
  migratedIR: migrated ? workingIR : void 0,
222
238
  migrationLog
223
239
  };
224
240
  }
241
+ function isTypeCompatible(source, target) {
242
+ if (source === target) return true;
243
+ if (source === "any" || target === "any") return true;
244
+ if (target === "object" && source === "array") return true;
245
+ if (target === "string" && source === "number") return true;
246
+ if (target === "number" && source === "string") return true;
247
+ return false;
248
+ }
225
249
  function detectCycles(nodes, edges) {
226
250
  const errors = [];
227
251
  const adjacency = /* @__PURE__ */ new Map();
@@ -1781,6 +1805,9 @@ var RESERVED_WORDS = /* @__PURE__ */ new Set([
1781
1805
  ]);
1782
1806
 
1783
1807
  // src/lib/compiler/compiler.ts
1808
+ registerPlatform("nextjs", () => new NextjsPlatform());
1809
+ registerPlatform("express", () => new ExpressPlatform());
1810
+ registerPlatform("cloudflare", () => new CloudflarePlatform());
1784
1811
  function compile(ir, options) {
1785
1812
  const pluginRegistry = createPluginRegistry();
1786
1813
  pluginRegistry.registerAll(builtinPlugins);
@@ -1858,7 +1885,7 @@ function compile(ir, options) {
1858
1885
  indentSize: 2,
1859
1886
  convertTabsToSpaces: true
1860
1887
  });
1861
- const code = sourceFile.getFullText();
1888
+ let code = sourceFile.getFullText();
1862
1889
  const filePath = platform.getOutputFilePath(trigger);
1863
1890
  collectRequiredPackages(workingIR, context);
1864
1891
  const sourceMap = buildSourceMap(code, workingIR, filePath);
@@ -3311,6 +3338,7 @@ function withFlowTrace(handler, options) {
3311
3338
  formatTraceResults(err, traces, sourceMap.generatedFile)
3312
3339
  );
3313
3340
  }
3341
+ options.onTrace?.(traces, err);
3314
3342
  }
3315
3343
  throw err;
3316
3344
  }
@@ -3319,6 +3347,7 @@ function withFlowTrace(handler, options) {
3319
3347
  }
3320
3348
  function installFlowTracer(options) {
3321
3349
  const { sourceMap, ir, editorUrl = "http://localhost:3001", log = true } = options;
3350
+ const { onTrace } = options;
3322
3351
  const handleError = (err) => {
3323
3352
  if (!(err instanceof Error)) return;
3324
3353
  const traces = traceError(err, sourceMap, ir, editorUrl);
@@ -3327,6 +3356,7 @@ function installFlowTracer(options) {
3327
3356
  formatTraceResults(err, traces, sourceMap.generatedFile)
3328
3357
  );
3329
3358
  }
3359
+ onTrace?.(traces, err);
3330
3360
  };
3331
3361
  process.on("uncaughtException", handleError);
3332
3362
  process.on("unhandledRejection", handleError);
package/dist/server.d.ts CHANGED
@@ -21,7 +21,7 @@ export interface ServerOptions {
21
21
  onReady?: (url: string) => void;
22
22
  }
23
23
 
24
- export declare function handleCompile(body: CompileRequest, projectRoot: string): ApiResponse;
24
+ export declare function handleCompile(body: CompileRequest, projectRoot: string): Promise<ApiResponse>;
25
25
  export declare function handleGenerate(body: { prompt?: string }): Promise<ApiResponse>;
26
26
  export declare function handleImportOpenAPI(body: { spec?: unknown; filter?: { tags?: string[]; paths?: string[] } }): ApiResponse;
27
27
  export declare function startServer(options?: ServerOptions): Server;