@mmapp/react-compiler 0.1.0-alpha.1 → 0.1.0-alpha.4
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/ATOM-PIPELINE.md +144 -0
- package/README.md +88 -40
- package/dist/auth-3UK75242.mjs +17 -0
- package/dist/babel/index.d.mts +2 -2
- package/dist/babel/index.d.ts +2 -2
- package/dist/babel/index.js +2816 -279
- package/dist/babel/index.mjs +2 -2
- package/dist/chunk-3USIFFE4.mjs +2190 -0
- package/dist/chunk-45YMGEVT.mjs +186 -0
- package/dist/chunk-4FN2AISW.mjs +148 -0
- package/dist/chunk-4OPI5L7G.mjs +2593 -0
- package/dist/chunk-4RYTKOOJ.mjs +186 -0
- package/dist/chunk-52XHYD2V.mjs +214 -0
- package/dist/chunk-5FTDWKHH.mjs +244 -0
- package/dist/chunk-5GUFFFGL.mjs +148 -0
- package/dist/chunk-5RKTOVR5.mjs +244 -0
- package/dist/chunk-5YDMOO4X.mjs +214 -0
- package/dist/chunk-64ZWEMLJ.mjs +148 -0
- package/dist/chunk-6XP4KSWQ.mjs +2190 -0
- package/dist/chunk-72QWL54I.mjs +175 -0
- package/dist/chunk-7B4TRI7C.mjs +4835 -0
- package/dist/chunk-7JRAEFRB.mjs +7510 -0
- package/dist/chunk-7T6Q5KAA.mjs +7506 -0
- package/dist/chunk-7ZKGHTNB.mjs +4952 -0
- package/dist/chunk-ABYPKRSB.mjs +215 -0
- package/dist/chunk-BZEXUPDH.mjs +175 -0
- package/dist/chunk-CIESM3BP.mjs +33 -0
- package/dist/chunk-DE3ZGQAC.mjs +148 -0
- package/dist/chunk-DMCY3BBG.mjs +1933 -0
- package/dist/chunk-DPIK3PJS.mjs +244 -0
- package/dist/chunk-E5IVH4RE.mjs +186 -0
- package/dist/chunk-E6FZNUR5.mjs +4953 -0
- package/dist/chunk-EJRBDQDP.mjs +2607 -0
- package/dist/chunk-ELO4TXJL.mjs +186 -0
- package/dist/chunk-EO6SYNCG.mjs +175 -0
- package/dist/chunk-FKRO52XH.mjs +3446 -0
- package/dist/chunk-FL4YAKU6.mjs +4941 -0
- package/dist/chunk-FYT47UBU.mjs +5076 -0
- package/dist/chunk-GCLGPOJZ.mjs +148 -0
- package/dist/chunk-GXB4JOP7.mjs +5072 -0
- package/dist/chunk-HFXOUMTD.mjs +175 -0
- package/dist/chunk-HRYR54PT.mjs +175 -0
- package/dist/chunk-HWIZ47US.mjs +214 -0
- package/dist/chunk-IB7MNPQL.mjs +4953 -0
- package/dist/chunk-ICSIHQCG.mjs +148 -0
- package/dist/chunk-J3M4GUS7.mjs +161 -0
- package/dist/chunk-J7JUAHS4.mjs +186 -0
- package/dist/chunk-JLA5VNQ3.mjs +186 -0
- package/dist/chunk-JQLWFCTM.mjs +214 -0
- package/dist/chunk-JRGFBWTN.mjs +2918 -0
- package/dist/chunk-KFJJCQAL.mjs +148 -0
- package/dist/chunk-KJUIIEQE.mjs +186 -0
- package/dist/chunk-KNWTHRVQ.mjs +175 -0
- package/dist/chunk-KSG4XSZF.mjs +175 -0
- package/dist/chunk-LF5N6DOU.mjs +175 -0
- package/dist/chunk-LJQCM2IM.mjs +214 -0
- package/dist/chunk-NTB7OEX2.mjs +2918 -0
- package/dist/chunk-NW6555WJ.mjs +186 -0
- package/dist/chunk-O4AUS7EU.mjs +148 -0
- package/dist/chunk-OMZE6VLQ.mjs +214 -0
- package/dist/chunk-OPJKP747.mjs +7506 -0
- package/dist/chunk-P4BR7WVO.mjs +2190 -0
- package/dist/chunk-QQHVYH2X.mjs +244 -0
- package/dist/chunk-R2DD5GTY.mjs +186 -0
- package/dist/chunk-S5QLWLLT.mjs +186 -0
- package/dist/chunk-SCWGT2FY.mjs +2190 -0
- package/dist/chunk-SMKJUSB3.mjs +2190 -0
- package/dist/chunk-THFYE5ZX.mjs +244 -0
- package/dist/chunk-UDDTWG5J.mjs +734 -0
- package/dist/chunk-VCAY2KGM.mjs +175 -0
- package/dist/chunk-VLTKQDJ3.mjs +244 -0
- package/dist/chunk-WBYMW4NQ.mjs +3450 -0
- package/dist/chunk-WECAV6QB.mjs +148 -0
- package/dist/chunk-WMKBXUCE.mjs +3228 -0
- package/dist/chunk-WVYY32LD.mjs +939 -0
- package/dist/chunk-XAJ5BKKL.mjs +4947 -0
- package/dist/chunk-XDVM4YHX.mjs +3450 -0
- package/dist/chunk-XG2X7AEA.mjs +175 -0
- package/dist/chunk-XG7Z23NQ.mjs +148 -0
- package/dist/chunk-XWZAOCQ7.mjs +2607 -0
- package/dist/chunk-Y6MA7ULW.mjs +148 -0
- package/dist/chunk-YMS7Q7LG.mjs +214 -0
- package/dist/chunk-Z2G5RZ4H.mjs +186 -0
- package/dist/chunk-ZA37XTGA.mjs +175 -0
- package/dist/chunk-ZE3KCHBM.mjs +2918 -0
- package/dist/cli/index.js +14720 -7199
- package/dist/cli/index.mjs +224 -183
- package/dist/codemod/cli.js +1 -1
- package/dist/codemod/cli.mjs +2 -2
- package/dist/codemod/index.d.mts +3 -3
- package/dist/codemod/index.d.ts +3 -3
- package/dist/codemod/index.js +1 -1
- package/dist/codemod/index.mjs +2 -2
- package/dist/config-PL24KEWL.mjs +219 -0
- package/dist/deploy-YAJGW6II.mjs +9 -0
- package/dist/dev-server-CrQ041KP.d.mts +79 -0
- package/dist/dev-server-CrQ041KP.d.ts +79 -0
- package/dist/dev-server-RmGHIntF.d.mts +113 -0
- package/dist/dev-server-RmGHIntF.d.ts +113 -0
- package/dist/dev-server.d.mts +2 -2
- package/dist/dev-server.d.ts +2 -2
- package/dist/dev-server.js +6424 -1597
- package/dist/dev-server.mjs +5 -5
- package/dist/envelope-ChEkuHij.d.mts +265 -0
- package/dist/envelope-ChEkuHij.d.ts +265 -0
- package/dist/envelope.d.mts +2 -2
- package/dist/envelope.d.ts +2 -2
- package/dist/envelope.js +2814 -277
- package/dist/envelope.mjs +3 -3
- package/dist/index-CEKyyazf.d.mts +104 -0
- package/dist/index-CEKyyazf.d.ts +104 -0
- package/dist/index.d.mts +168 -9
- package/dist/index.d.ts +168 -9
- package/dist/index.js +5606 -681
- package/dist/index.mjs +217 -9
- package/dist/init-7FJENUDK.mjs +407 -0
- package/{src/cli/init.ts → dist/init-7JQMAAXS.mjs} +70 -95
- package/dist/init-DQDX3QK6.mjs +369 -0
- package/dist/init-EHO4VQ22.mjs +369 -0
- package/dist/init-UC3FWPIW.mjs +367 -0
- package/dist/init-UNSMVKIK.mjs +366 -0
- package/dist/init-UNV5XIDE.mjs +367 -0
- package/dist/project-compiler-2P4N4DR7.mjs +10 -0
- package/dist/project-compiler-D2LCC27O.mjs +10 -0
- package/dist/project-compiler-EJ3GANJE.mjs +10 -0
- package/dist/project-compiler-LOQKVRZJ.mjs +10 -0
- package/dist/project-compiler-NNK32MPG.mjs +10 -0
- package/dist/project-compiler-OP2VVGJQ.mjs +10 -0
- package/dist/project-compiler-RQ6OQKRM.mjs +10 -0
- package/dist/project-compiler-VWNNCHGO.mjs +10 -0
- package/dist/project-compiler-XVAAU4C5.mjs +10 -0
- package/dist/project-compiler-YES5FGMD.mjs +10 -0
- package/dist/project-compiler-ZB4RUYVL.mjs +10 -0
- package/dist/project-compiler-ZKMQDLGU.mjs +10 -0
- package/dist/project-decompiler-FLXCEJHS.mjs +7 -0
- package/dist/project-decompiler-U55HQUHW.mjs +7 -0
- package/dist/project-decompiler-US7GAVIC.mjs +7 -0
- package/dist/project-decompiler-VLPR22QF.mjs +7 -0
- package/dist/pull-FUS5QYZS.mjs +109 -0
- package/dist/pull-KOL2QAYQ.mjs +109 -0
- package/dist/pull-LD5ENLGY.mjs +109 -0
- package/dist/pull-P44LDRWB.mjs +109 -0
- package/dist/seed-KOGEPGOJ.mjs +154 -0
- package/dist/server-VW6UPCHO.mjs +277 -0
- package/dist/testing/index.d.mts +8 -8
- package/dist/testing/index.d.ts +8 -8
- package/dist/testing/index.js +2824 -287
- package/dist/testing/index.mjs +2 -2
- package/dist/verify-BYHUKARQ.mjs +1833 -0
- package/dist/verify-OQDEQYMS.mjs +1833 -0
- package/dist/verify-SEIXUGN4.mjs +1833 -0
- package/dist/vite/index.d.mts +1 -1
- package/dist/vite/index.d.ts +1 -1
- package/dist/vite/index.js +2817 -280
- package/dist/vite/index.mjs +3 -3
- package/examples/authentication/main.workflow.tsx +1 -1
- package/examples/authentication/mm.config.ts +1 -1
- package/examples/authentication/pages/LoginPage.tsx +2 -2
- package/examples/authentication/pages/SignupPage.tsx +2 -2
- package/examples/counter.workflow.tsx +1 -1
- package/examples/dashboard.workflow.tsx +1 -1
- package/examples/invoice-approval/actions/invoice.server.ts +1 -1
- package/examples/invoice-approval/main.workflow.tsx +1 -1
- package/examples/invoice-approval/mm.config.ts +1 -1
- package/examples/invoice-approval/pages/InvoiceDetailPage.tsx +1 -1
- package/examples/invoice-approval/pages/InvoiceFormPage.tsx +1 -1
- package/examples/invoice-approval/pages/InvoiceListPage.tsx +1 -1
- package/examples/todo-app.workflow.tsx +1 -1
- package/examples/uber-app/actions/matching.server.ts +1 -1
- package/examples/uber-app/actions/notifications.server.ts +1 -1
- package/examples/uber-app/actions/payments.server.ts +1 -1
- package/examples/uber-app/actions/pricing.server.ts +1 -1
- package/examples/uber-app/app/admin/analytics.tsx +2 -2
- package/examples/uber-app/app/admin/fleet.tsx +21 -21
- package/examples/uber-app/app/admin/surge-pricing.tsx +2 -2
- package/examples/uber-app/app/driver/dashboard.tsx +2 -2
- package/examples/uber-app/app/driver/earnings.tsx +2 -2
- package/examples/uber-app/app/driver/navigation.tsx +2 -2
- package/examples/uber-app/app/driver/ride-acceptance.tsx +2 -2
- package/examples/uber-app/app/rider/home.tsx +2 -2
- package/examples/uber-app/app/rider/payment-methods.tsx +2 -2
- package/examples/uber-app/app/rider/ride-history.tsx +2 -2
- package/examples/uber-app/app/rider/ride-tracking.tsx +2 -2
- package/examples/uber-app/components/DriverCard.tsx +1 -1
- package/examples/uber-app/components/MapView.tsx +3 -3
- package/examples/uber-app/components/RatingStars.tsx +2 -2
- package/examples/uber-app/components/RideCard.tsx +1 -1
- package/examples/uber-app/mm.config.ts +1 -1
- package/examples/uber-app/workflows/dispute-resolution.workflow.tsx +2 -2
- package/examples/uber-app/workflows/driver-onboarding.workflow.tsx +2 -2
- package/examples/uber-app/workflows/payment-processing.workflow.tsx +2 -2
- package/examples/uber-app/workflows/ride-request.workflow.tsx +2 -2
- package/package.json +10 -4
- package/compile-blueprint-chat.mjs +0 -99
- package/compile-blueprint-glass-console.mjs +0 -98
- package/compile-chat-defs.mjs +0 -92
- package/examples/uber-app/tests/payment.test.tsx +0 -129
- package/examples/uber-app/tests/ride-flow.test.tsx +0 -123
- package/package.json.backup +0 -86
- package/scripts/decompile.ts +0 -226
- package/scripts/seed-auth.ts +0 -267
- package/scripts/seed-uber.ts +0 -248
- package/scripts/validate-uber.ts +0 -119
- package/seed-blueprint-chat.mjs +0 -444
- package/seed-blueprint-glass-console.mjs +0 -445
- package/seed-compiled.mjs +0 -318
- package/src/RoundTripValidator.ts +0 -400
- package/src/__tests__/atom-rendering-coverage.test.ts +0 -680
- package/src/__tests__/auth-module-compilation.test.ts +0 -247
- package/src/__tests__/auth-template-compilation.test.ts +0 -589
- package/src/__tests__/change-extractor.test.ts +0 -142
- package/src/__tests__/cli-pull.test.ts +0 -73
- package/src/__tests__/cli-test.test.ts +0 -72
- package/src/__tests__/component-extractor.test.ts +0 -331
- package/src/__tests__/context-extractor.test.ts +0 -145
- package/src/__tests__/decompiler.test.ts +0 -718
- package/src/__tests__/define-blueprint.test.ts +0 -133
- package/src/__tests__/definition-validator.test.ts +0 -519
- package/src/__tests__/during-extractor.test.ts +0 -152
- package/src/__tests__/effect-extractor.test.ts +0 -107
- package/src/__tests__/event-emission.test.ts +0 -127
- package/src/__tests__/examples.test.ts +0 -236
- package/src/__tests__/full-blueprint-coverage.test.ts +0 -1221
- package/src/__tests__/golden-suite.test.ts +0 -403
- package/src/__tests__/grammar-island-extractor.test.ts +0 -289
- package/src/__tests__/instance-key.test.ts +0 -82
- package/src/__tests__/ir-migration.test.ts +0 -255
- package/src/__tests__/lock-file.test.ts +0 -117
- package/src/__tests__/model-extractor.test.ts +0 -195
- package/src/__tests__/model-field-acl.test.ts +0 -237
- package/src/__tests__/model-hooks.test.ts +0 -130
- package/src/__tests__/model-ref-resolution.test.ts +0 -268
- package/src/__tests__/model-roundtrip.test.ts +0 -502
- package/src/__tests__/model-runtime.test.ts +0 -112
- package/src/__tests__/model-transitions.test.ts +0 -183
- package/src/__tests__/nrt-action-trace.test.ts +0 -391
- package/src/__tests__/pipeline-hardening.test.ts +0 -413
- package/src/__tests__/project-compiler.test.ts +0 -546
- package/src/__tests__/project-decompiler.test.ts +0 -343
- package/src/__tests__/query-compilation.test.ts +0 -145
- package/src/__tests__/round-trip/PLAN.md +0 -158
- package/src/__tests__/round-trip/README.md +0 -52
- package/src/__tests__/round-trip/RESULTS.md +0 -86
- package/src/__tests__/round-trip/fixtures/data-heavy/main.workflow.tsx +0 -55
- package/src/__tests__/round-trip/fixtures/data-heavy/mm.config.ts +0 -11
- package/src/__tests__/round-trip/fixtures/data-heavy/models/contact.ts +0 -54
- package/src/__tests__/round-trip/fixtures/full-workflow/main.workflow.tsx +0 -79
- package/src/__tests__/round-trip/fixtures/full-workflow/mm.config.ts +0 -12
- package/src/__tests__/round-trip/fixtures/full-workflow/models/order.ts +0 -50
- package/src/__tests__/round-trip/fixtures/simple-crud/main.workflow.tsx +0 -25
- package/src/__tests__/round-trip/fixtures/simple-crud/mm.config.ts +0 -11
- package/src/__tests__/round-trip/fixtures/simple-crud/models/task.ts +0 -32
- package/src/__tests__/round-trip/fixtures/view-heavy/main.workflow.tsx +0 -79
- package/src/__tests__/round-trip/fixtures/view-heavy/mm.config.ts +0 -10
- package/src/__tests__/round-trip/round-trip.test.ts +0 -2598
- package/src/__tests__/round-trip-ir.test.ts +0 -300
- package/src/__tests__/round-trip.test.ts +0 -1212
- package/src/__tests__/route-merging.test.ts +0 -372
- package/src/__tests__/router-composition.test.ts +0 -489
- package/src/__tests__/router-extractor.test.ts +0 -176
- package/src/__tests__/server-action-extractor.test.ts +0 -128
- package/src/__tests__/smart-type-inference.test.ts +0 -365
- package/src/__tests__/source-envelope.test.ts +0 -284
- package/src/__tests__/source-fidelity.test.ts +0 -516
- package/src/__tests__/state-extractor.test.ts +0 -115
- package/src/__tests__/strict-mode.test.ts +0 -227
- package/src/__tests__/transition-effect-extractor.test.ts +0 -119
- package/src/__tests__/transition-extractor.test.ts +0 -68
- package/src/__tests__/ts-to-expression.test.ts +0 -462
- package/src/__tests__/type-generator.test.ts +0 -201
- package/src/__tests__/uber-validation.test.ts +0 -502
- package/src/action-compiler.ts +0 -361
- package/src/babel/emitters/experience-transform.ts +0 -199
- package/src/babel/emitters/ir-to-tsx-emitter.ts +0 -110
- package/src/babel/emitters/pure-form-emitter.ts +0 -1023
- package/src/babel/emitters/runtime-glue-emitter.ts +0 -39
- package/src/babel/extractors/change-extractor.ts +0 -199
- package/src/babel/extractors/component-extractor.ts +0 -907
- package/src/babel/extractors/computed-extractor.ts +0 -262
- package/src/babel/extractors/context-extractor.ts +0 -277
- package/src/babel/extractors/during-extractor.ts +0 -295
- package/src/babel/extractors/effect-extractor.ts +0 -340
- package/src/babel/extractors/event-extractor.ts +0 -235
- package/src/babel/extractors/grammar-island-extractor.ts +0 -302
- package/src/babel/extractors/model-extractor.ts +0 -1018
- package/src/babel/extractors/router-extractor.ts +0 -303
- package/src/babel/extractors/server-action-extractor.ts +0 -173
- package/src/babel/extractors/server-action-hook-extractor.ts +0 -72
- package/src/babel/extractors/server-state-extractor.ts +0 -88
- package/src/babel/extractors/state-extractor.ts +0 -214
- package/src/babel/extractors/transition-effect-extractor.ts +0 -176
- package/src/babel/extractors/transition-extractor.ts +0 -143
- package/src/babel/index.ts +0 -24
- package/src/babel/transpilers/ts-to-expression.ts +0 -674
- package/src/babel/visitor.ts +0 -807
- package/src/cli/auth.ts +0 -255
- package/src/cli/build.ts +0 -288
- package/src/cli/deploy.ts +0 -206
- package/src/cli/index.ts +0 -328
- package/src/cli/installer.ts +0 -261
- package/src/cli/lock-file.ts +0 -94
- package/src/cli/mmrc.ts +0 -22
- package/src/cli/pull.ts +0 -172
- package/src/cli/registry-client.ts +0 -175
- package/src/cli/test.ts +0 -397
- package/src/cli/type-generator.ts +0 -243
- package/src/codemod/__tests__/forward.test.ts +0 -239
- package/src/codemod/__tests__/reverse.test.ts +0 -145
- package/src/codemod/__tests__/round-trip.test.ts +0 -137
- package/src/codemod/annotation.ts +0 -97
- package/src/codemod/classify.ts +0 -197
- package/src/codemod/cli.ts +0 -207
- package/src/codemod/control-flow.ts +0 -409
- package/src/codemod/forward.ts +0 -244
- package/src/codemod/import-manager.ts +0 -171
- package/src/codemod/index.ts +0 -120
- package/src/codemod/reverse.ts +0 -197
- package/src/codemod/rules.ts +0 -174
- package/src/codemod/state-transform.ts +0 -126
- package/src/decompiler/ast-builder.ts +0 -538
- package/src/decompiler/config-generator.ts +0 -151
- package/src/decompiler/index.ts +0 -315
- package/src/decompiler/project-decompiler.ts +0 -1776
- package/src/decompiler/project.ts +0 -862
- package/src/decompiler/split-strategy.ts +0 -140
- package/src/decompiler/state-emitter.ts +0 -1053
- package/src/decompiler/sx-emitter.ts +0 -318
- package/src/decompiler/workspace-hydrator.ts +0 -189
- package/src/dev-server.ts +0 -238
- package/src/envelope/fs-tree.ts +0 -217
- package/src/envelope/source-envelope.ts +0 -264
- package/src/envelope.ts +0 -315
- package/src/incremental-compiler.ts +0 -401
- package/src/index.ts +0 -99
- package/src/model-compiler.ts +0 -277
- package/src/project-compiler.ts +0 -1629
- package/src/route-extractor.ts +0 -333
- package/src/testing/index.ts +0 -32
- package/src/testing/snapshot.ts +0 -252
- package/src/testing/test-utils.ts +0 -226
- package/src/types.ts +0 -68
- package/src/vite/index.ts +0 -288
- package/test-compile.mjs +0 -142
- package/tsconfig.json +0 -25
- package/tsup.config.ts +0 -23
- package/vitest.config.ts +0 -9
package/dist/vite/index.js
CHANGED
|
@@ -38,7 +38,7 @@ var import_fs = require("fs");
|
|
|
38
38
|
var import_path = require("path");
|
|
39
39
|
|
|
40
40
|
// src/babel/visitor.ts
|
|
41
|
-
var
|
|
41
|
+
var t21 = __toESM(require("@babel/types"));
|
|
42
42
|
|
|
43
43
|
// src/babel/extractors/state-extractor.ts
|
|
44
44
|
var t = __toESM(require("@babel/types"));
|
|
@@ -444,25 +444,25 @@ function inferTransitionStates(transitions, states) {
|
|
|
444
444
|
const stateArray = Array.from(states.values());
|
|
445
445
|
const startStates = stateArray.filter((s) => s.type === "START");
|
|
446
446
|
const regularStates = stateArray.filter((s) => s.type === "REGULAR");
|
|
447
|
-
const needsInference = transitions.filter((
|
|
447
|
+
const needsInference = transitions.filter((t22) => t22.from.length === 0 || !t22.to);
|
|
448
448
|
if (needsInference.length === 0) return;
|
|
449
449
|
if (startStates.length === 1 && regularStates.length > 0) {
|
|
450
|
-
needsInference.forEach((
|
|
451
|
-
if (
|
|
452
|
-
|
|
450
|
+
needsInference.forEach((t22, idx) => {
|
|
451
|
+
if (t22.from.length === 0) {
|
|
452
|
+
t22.from = [startStates[0].name];
|
|
453
453
|
}
|
|
454
|
-
if (!
|
|
455
|
-
|
|
454
|
+
if (!t22.to) {
|
|
455
|
+
t22.to = regularStates[idx % regularStates.length]?.name || startStates[0].name;
|
|
456
456
|
}
|
|
457
457
|
});
|
|
458
458
|
} else {
|
|
459
459
|
const allStateNames = stateArray.map((s) => s.name);
|
|
460
|
-
needsInference.forEach((
|
|
461
|
-
if (
|
|
462
|
-
|
|
460
|
+
needsInference.forEach((t22, idx) => {
|
|
461
|
+
if (t22.from.length === 0 && allStateNames.length > 0) {
|
|
462
|
+
t22.from = [allStateNames[0]];
|
|
463
463
|
}
|
|
464
|
-
if (!
|
|
465
|
-
|
|
464
|
+
if (!t22.to && allStateNames.length > 1) {
|
|
465
|
+
t22.to = allStateNames[Math.min(idx + 1, allStateNames.length - 1)];
|
|
466
466
|
}
|
|
467
467
|
});
|
|
468
468
|
}
|
|
@@ -652,6 +652,8 @@ var TranspileContext = class {
|
|
|
652
652
|
this.localFieldMap = options.localFieldMap ?? /* @__PURE__ */ new Map();
|
|
653
653
|
this.derivedVarMap = options.derivedVarMap ?? /* @__PURE__ */ new Map();
|
|
654
654
|
this.setterToFieldMap = options.setterToFieldMap ?? /* @__PURE__ */ new Map();
|
|
655
|
+
this.parameterMap = options.parameterMap ?? /* @__PURE__ */ new Map();
|
|
656
|
+
this.allMutable = options.allMutable ?? false;
|
|
655
657
|
}
|
|
656
658
|
/**
|
|
657
659
|
* Emit an opaque JS fallback, marking the result as impure.
|
|
@@ -673,6 +675,8 @@ var TranspileContext = class {
|
|
|
673
675
|
if (snakeName) return `$local.${snakeName}`;
|
|
674
676
|
const derivedInit = this.derivedVarMap.get(node.name);
|
|
675
677
|
if (derivedInit) return `(${this.visit(derivedInit)})`;
|
|
678
|
+
const paramField = this.parameterMap.get(node.name);
|
|
679
|
+
if (paramField) return paramField;
|
|
676
680
|
if (node.name === "undefined") return "null";
|
|
677
681
|
if (node.name === "NaN") return "null";
|
|
678
682
|
if (node.name === "Infinity") return "null";
|
|
@@ -720,6 +724,9 @@ var TranspileContext = class {
|
|
|
720
724
|
if (t5.isNewExpression(node)) {
|
|
721
725
|
return this.visitNew(node);
|
|
722
726
|
}
|
|
727
|
+
if (t5.isAssignmentExpression(node) && node.operator === "=" && t5.isIdentifier(node.left)) {
|
|
728
|
+
return `${node.left.name} = ${this.visit(node.right)}`;
|
|
729
|
+
}
|
|
723
730
|
return this.opaque(fallbackGenerate(node));
|
|
724
731
|
}
|
|
725
732
|
// ---------------------------------------------------------------------------
|
|
@@ -920,6 +927,11 @@ var TranspileContext = class {
|
|
|
920
927
|
return this.visitArrayHigherOrder("some", obj, args);
|
|
921
928
|
case "every":
|
|
922
929
|
return this.visitArrayHigherOrder("every", obj, args);
|
|
930
|
+
// --- Array push: arr.push(item) → arr = push(arr, item) ---
|
|
931
|
+
case "push": {
|
|
932
|
+
const [item] = this.visitArgsList(args);
|
|
933
|
+
return `${obj} = push(${obj}, ${item})`;
|
|
934
|
+
}
|
|
923
935
|
// --- Array mutation-free methods ---
|
|
924
936
|
case "reverse":
|
|
925
937
|
return `reverse(${obj})`;
|
|
@@ -2755,6 +2767,71 @@ function modelStateTypeToIR(type) {
|
|
|
2755
2767
|
if (type === "final") return "END";
|
|
2756
2768
|
return "REGULAR";
|
|
2757
2769
|
}
|
|
2770
|
+
function parseActionArray(raw, actionCounter) {
|
|
2771
|
+
if (!Array.isArray(raw)) return [];
|
|
2772
|
+
const actions = [];
|
|
2773
|
+
for (const item of raw) {
|
|
2774
|
+
if (typeof item !== "object" || item === null) continue;
|
|
2775
|
+
const a = item;
|
|
2776
|
+
actions.push({
|
|
2777
|
+
id: a.id ? String(a.id) : `auto_${++actionCounter.value}`,
|
|
2778
|
+
type: String(a.type || a.action_type || "unknown"),
|
|
2779
|
+
mode: a.mode || "auto",
|
|
2780
|
+
config: a.config && typeof a.config === "object" ? a.config : {},
|
|
2781
|
+
...a.condition ? { condition: String(a.condition) } : {}
|
|
2782
|
+
});
|
|
2783
|
+
}
|
|
2784
|
+
return actions;
|
|
2785
|
+
}
|
|
2786
|
+
function parseDuringArray(raw, actionCounter) {
|
|
2787
|
+
if (!Array.isArray(raw)) return [];
|
|
2788
|
+
const result = [];
|
|
2789
|
+
for (const item of raw) {
|
|
2790
|
+
if (typeof item !== "object" || item === null) continue;
|
|
2791
|
+
const d = item;
|
|
2792
|
+
result.push({
|
|
2793
|
+
id: d.id ? String(d.id) : `during_${++actionCounter.value}`,
|
|
2794
|
+
type: d.type || "interval",
|
|
2795
|
+
...d.interval_ms != null ? { interval_ms: Number(d.interval_ms) } : {},
|
|
2796
|
+
...d.cron ? { cron: String(d.cron) } : {},
|
|
2797
|
+
...d.delay_ms != null ? { delay_ms: Number(d.delay_ms) } : {},
|
|
2798
|
+
...d.condition ? { condition: String(d.condition) } : {},
|
|
2799
|
+
actions: parseActionArray(d.actions, actionCounter)
|
|
2800
|
+
});
|
|
2801
|
+
}
|
|
2802
|
+
return result;
|
|
2803
|
+
}
|
|
2804
|
+
function parseOnEventArray(raw, actionCounter) {
|
|
2805
|
+
if (!Array.isArray(raw)) return [];
|
|
2806
|
+
const result = [];
|
|
2807
|
+
for (const item of raw) {
|
|
2808
|
+
if (typeof item !== "object" || item === null) continue;
|
|
2809
|
+
const e = item;
|
|
2810
|
+
const actions = [];
|
|
2811
|
+
if (Array.isArray(e.actions)) {
|
|
2812
|
+
for (const a of e.actions) {
|
|
2813
|
+
if (typeof a !== "object" || a === null) continue;
|
|
2814
|
+
const act = a;
|
|
2815
|
+
actions.push({
|
|
2816
|
+
type: act.type || "set_field",
|
|
2817
|
+
...act.field ? { field: String(act.field) } : {},
|
|
2818
|
+
...act.expression ? { expression: String(act.expression) } : {},
|
|
2819
|
+
...act.key ? { key: String(act.key) } : {},
|
|
2820
|
+
...act.message ? { message: String(act.message) } : {},
|
|
2821
|
+
...act.config && typeof act.config === "object" ? { config: act.config } : {},
|
|
2822
|
+
...act.conditions && Array.isArray(act.conditions) ? { conditions: act.conditions.map(String) } : {}
|
|
2823
|
+
});
|
|
2824
|
+
}
|
|
2825
|
+
}
|
|
2826
|
+
result.push({
|
|
2827
|
+
match: String(e.match || ""),
|
|
2828
|
+
...e.description ? { description: String(e.description) } : {},
|
|
2829
|
+
...e.conditions && Array.isArray(e.conditions) ? { conditions: e.conditions.map(String) } : {},
|
|
2830
|
+
actions
|
|
2831
|
+
});
|
|
2832
|
+
}
|
|
2833
|
+
return result;
|
|
2834
|
+
}
|
|
2758
2835
|
function extractDefineModelCall(programPath, compilerState, actionCounter) {
|
|
2759
2836
|
for (const node of programPath.node.body) {
|
|
2760
2837
|
if (!t11.isExportDefaultDeclaration(node)) continue;
|
|
@@ -2794,17 +2871,29 @@ function extractDefineModelCall(programPath, compilerState, actionCounter) {
|
|
|
2794
2871
|
const statesObj = config.states;
|
|
2795
2872
|
for (const [name, stateConfig] of Object.entries(statesObj)) {
|
|
2796
2873
|
const stateType = modelStateTypeToIR(stateConfig.type);
|
|
2874
|
+
const on_enter = parseActionArray(stateConfig.on_enter, actionCounter);
|
|
2875
|
+
const on_exit = parseActionArray(stateConfig.on_exit, actionCounter);
|
|
2876
|
+
const during = parseDuringArray(stateConfig.during, actionCounter);
|
|
2877
|
+
const on_event = parseOnEventArray(stateConfig.on_event, actionCounter);
|
|
2878
|
+
const stateRuntime = stateConfig.runtime;
|
|
2797
2879
|
if (!compilerState.states.has(name)) {
|
|
2798
2880
|
compilerState.states.set(name, {
|
|
2799
2881
|
name,
|
|
2800
2882
|
type: stateType,
|
|
2801
2883
|
description: stateConfig.description,
|
|
2802
|
-
on_enter
|
|
2803
|
-
during
|
|
2804
|
-
on_exit
|
|
2884
|
+
on_enter,
|
|
2885
|
+
during,
|
|
2886
|
+
on_exit,
|
|
2887
|
+
...on_event.length > 0 ? { on_event } : {},
|
|
2888
|
+
...stateRuntime ? { runtime: stateRuntime } : {}
|
|
2805
2889
|
});
|
|
2806
2890
|
} else {
|
|
2807
|
-
compilerState.states.get(name)
|
|
2891
|
+
const existing = compilerState.states.get(name);
|
|
2892
|
+
existing.type = stateType;
|
|
2893
|
+
if (on_enter.length > 0) existing.on_enter = on_enter;
|
|
2894
|
+
if (on_exit.length > 0) existing.on_exit = on_exit;
|
|
2895
|
+
if (during.length > 0) existing.during = during;
|
|
2896
|
+
if (on_event.length > 0) existing.on_event = on_event;
|
|
2808
2897
|
}
|
|
2809
2898
|
}
|
|
2810
2899
|
}
|
|
@@ -2842,16 +2931,26 @@ function extractDefineModelCall(programPath, compilerState, actionCounter) {
|
|
|
2842
2931
|
if (transConfig.guard) {
|
|
2843
2932
|
conditions.push(parseGuardExpression(String(transConfig.guard)));
|
|
2844
2933
|
}
|
|
2934
|
+
if (transConfig.conditions && Array.isArray(transConfig.conditions)) {
|
|
2935
|
+
for (const cond of transConfig.conditions) {
|
|
2936
|
+
if (typeof cond === "object" && cond !== null) {
|
|
2937
|
+
conditions.push(cond);
|
|
2938
|
+
}
|
|
2939
|
+
}
|
|
2940
|
+
}
|
|
2941
|
+
const actions = parseActionArray(transConfig.actions, actionCounter);
|
|
2942
|
+
const transRuntime = transConfig.runtime;
|
|
2845
2943
|
compilerState.transitions.push({
|
|
2846
2944
|
name,
|
|
2847
2945
|
from,
|
|
2848
2946
|
to,
|
|
2849
2947
|
description: transConfig.description,
|
|
2850
2948
|
conditions: conditions.length > 0 ? conditions : void 0,
|
|
2851
|
-
actions
|
|
2949
|
+
actions,
|
|
2852
2950
|
roles: transConfig.roles,
|
|
2853
2951
|
auto: transConfig.auto,
|
|
2854
|
-
required_fields: transConfig.required_fields
|
|
2952
|
+
required_fields: transConfig.required_fields,
|
|
2953
|
+
...transRuntime ? { runtime: transRuntime } : {}
|
|
2855
2954
|
});
|
|
2856
2955
|
}
|
|
2857
2956
|
}
|
|
@@ -2868,6 +2967,9 @@ function extractDefineModelCall(programPath, compilerState, actionCounter) {
|
|
|
2868
2967
|
if (config.metadata && typeof config.metadata === "object") {
|
|
2869
2968
|
compilerState.metadata.modelMetadata = config.metadata;
|
|
2870
2969
|
}
|
|
2970
|
+
if (config.orchestration && typeof config.orchestration === "object" && !Array.isArray(config.orchestration)) {
|
|
2971
|
+
compilerState.metadata.orchestration = config.orchestration;
|
|
2972
|
+
}
|
|
2871
2973
|
return true;
|
|
2872
2974
|
}
|
|
2873
2975
|
return false;
|
|
@@ -3042,165 +3144,2021 @@ function extractModelFile(path, state) {
|
|
|
3042
3144
|
}
|
|
3043
3145
|
}
|
|
3044
3146
|
|
|
3045
|
-
// src/babel/extractors/
|
|
3147
|
+
// src/babel/extractors/flow-extractor.ts
|
|
3046
3148
|
var t12 = __toESM(require("@babel/types"));
|
|
3047
|
-
|
|
3048
|
-
|
|
3049
|
-
|
|
3149
|
+
|
|
3150
|
+
// src/babel/extractors/workflow-shorthand.ts
|
|
3151
|
+
function makeState(name, type) {
|
|
3152
|
+
return {
|
|
3153
|
+
name,
|
|
3154
|
+
type,
|
|
3155
|
+
on_enter: [],
|
|
3156
|
+
during: [],
|
|
3157
|
+
on_exit: []
|
|
3158
|
+
};
|
|
3050
3159
|
}
|
|
3051
|
-
function
|
|
3052
|
-
|
|
3053
|
-
|
|
3054
|
-
|
|
3055
|
-
|
|
3056
|
-
|
|
3057
|
-
|
|
3058
|
-
|
|
3059
|
-
|
|
3060
|
-
|
|
3061
|
-
|
|
3062
|
-
|
|
3160
|
+
function makeTransition(name, from, to) {
|
|
3161
|
+
return {
|
|
3162
|
+
name,
|
|
3163
|
+
from: [from],
|
|
3164
|
+
to,
|
|
3165
|
+
actions: []
|
|
3166
|
+
};
|
|
3167
|
+
}
|
|
3168
|
+
function dedupeTransitions(ts) {
|
|
3169
|
+
const seen = /* @__PURE__ */ new Set();
|
|
3170
|
+
const out = [];
|
|
3171
|
+
for (const t22 of ts) {
|
|
3172
|
+
const key = `${t22.name}::${t22.from.join(",")}::${t22.to}`;
|
|
3173
|
+
if (!seen.has(key)) {
|
|
3174
|
+
seen.add(key);
|
|
3175
|
+
out.push(t22);
|
|
3176
|
+
}
|
|
3177
|
+
}
|
|
3178
|
+
return out;
|
|
3179
|
+
}
|
|
3180
|
+
var TOKEN_RE = /(<->)|<-(\w+)-|(<-)|(?:-(\w+)->)|(->)|(\|)|([a-zA-Z_]\w*)/g;
|
|
3181
|
+
function tokenize(line) {
|
|
3182
|
+
const tokens = [];
|
|
3183
|
+
let m;
|
|
3184
|
+
TOKEN_RE.lastIndex = 0;
|
|
3185
|
+
while ((m = TOKEN_RE.exec(line)) !== null) {
|
|
3186
|
+
if (m[1]) {
|
|
3187
|
+
tokens.push({ kind: "arrow", direction: "bidirectional" });
|
|
3188
|
+
} else if (m[2]) {
|
|
3189
|
+
tokens.push({ kind: "arrow", direction: "backward", name: m[2] });
|
|
3190
|
+
} else if (m[3]) {
|
|
3191
|
+
tokens.push({ kind: "arrow", direction: "backward" });
|
|
3192
|
+
} else if (m[4]) {
|
|
3193
|
+
tokens.push({ kind: "arrow", direction: "forward", name: m[4] });
|
|
3194
|
+
} else if (m[5]) {
|
|
3195
|
+
tokens.push({ kind: "arrow", direction: "forward" });
|
|
3196
|
+
} else if (m[6]) {
|
|
3197
|
+
tokens.push({ kind: "branch" });
|
|
3198
|
+
} else if (m[7]) {
|
|
3199
|
+
tokens.push({ kind: "state", name: m[7] });
|
|
3200
|
+
}
|
|
3201
|
+
}
|
|
3202
|
+
return tokens;
|
|
3203
|
+
}
|
|
3204
|
+
function parseTokens(tokens, stateMap, transitions, outgoingCounts) {
|
|
3205
|
+
let lastState = null;
|
|
3206
|
+
for (let i = 0; i < tokens.length; i++) {
|
|
3207
|
+
const tok = tokens[i];
|
|
3208
|
+
if (tok.kind === "state") {
|
|
3209
|
+
stateMap.set(tok.name, stateMap.has(tok.name) ? stateMap.get(tok.name) : true);
|
|
3210
|
+
lastState = tok.name;
|
|
3211
|
+
continue;
|
|
3212
|
+
}
|
|
3213
|
+
if (tok.kind === "branch") {
|
|
3214
|
+
continue;
|
|
3215
|
+
}
|
|
3216
|
+
if (tok.kind === "arrow") {
|
|
3217
|
+
let nextIdx = i + 1;
|
|
3218
|
+
const targets = [];
|
|
3219
|
+
while (nextIdx < tokens.length) {
|
|
3220
|
+
const next = tokens[nextIdx];
|
|
3221
|
+
if (next.kind === "state") {
|
|
3222
|
+
targets.push(next.name);
|
|
3223
|
+
stateMap.set(next.name, stateMap.has(next.name) ? stateMap.get(next.name) : true);
|
|
3224
|
+
nextIdx++;
|
|
3225
|
+
if (nextIdx < tokens.length && tokens[nextIdx].kind === "branch") {
|
|
3226
|
+
nextIdx++;
|
|
3227
|
+
continue;
|
|
3228
|
+
}
|
|
3229
|
+
break;
|
|
3230
|
+
} else {
|
|
3231
|
+
nextIdx++;
|
|
3063
3232
|
}
|
|
3064
3233
|
}
|
|
3065
|
-
if (
|
|
3066
|
-
for (const
|
|
3067
|
-
if (
|
|
3068
|
-
|
|
3069
|
-
|
|
3070
|
-
|
|
3071
|
-
|
|
3072
|
-
|
|
3073
|
-
|
|
3074
|
-
|
|
3075
|
-
|
|
3076
|
-
|
|
3077
|
-
|
|
3078
|
-
|
|
3079
|
-
|
|
3234
|
+
if (lastState && targets.length > 0) {
|
|
3235
|
+
for (const target of targets) {
|
|
3236
|
+
if (tok.direction === "forward" || tok.direction === "bidirectional") {
|
|
3237
|
+
const name = tok.name || `to_${target}`;
|
|
3238
|
+
transitions.push(makeTransition(name, lastState, target));
|
|
3239
|
+
outgoingCounts.set(lastState, (outgoingCounts.get(lastState) || 0) + 1);
|
|
3240
|
+
}
|
|
3241
|
+
if (tok.direction === "backward" || tok.direction === "bidirectional") {
|
|
3242
|
+
const name = tok.name || `to_${lastState}`;
|
|
3243
|
+
transitions.push(makeTransition(name, target, lastState));
|
|
3244
|
+
outgoingCounts.set(target, (outgoingCounts.get(target) || 0) + 1);
|
|
3245
|
+
}
|
|
3246
|
+
}
|
|
3247
|
+
lastState = targets[targets.length > 1 ? 0 : 0];
|
|
3248
|
+
if (targets.length === 1) {
|
|
3249
|
+
lastState = targets[0];
|
|
3250
|
+
}
|
|
3251
|
+
i = nextIdx - 1;
|
|
3252
|
+
}
|
|
3253
|
+
}
|
|
3254
|
+
}
|
|
3255
|
+
}
|
|
3256
|
+
function parseMultiLine(lines) {
|
|
3257
|
+
const allStateNames = [];
|
|
3258
|
+
const allTransitions = [];
|
|
3259
|
+
const stateMap = /* @__PURE__ */ new Map();
|
|
3260
|
+
const outgoingCounts = /* @__PURE__ */ new Map();
|
|
3261
|
+
for (const line of lines) {
|
|
3262
|
+
const trimmed = line.trim();
|
|
3263
|
+
if (!trimmed) continue;
|
|
3264
|
+
const tokens = tokenize(trimmed);
|
|
3265
|
+
const hasStates = tokens.some((t22) => t22.kind === "state");
|
|
3266
|
+
const hasForwardArrows = tokens.some(
|
|
3267
|
+
(t22) => t22.kind === "arrow" && (t22.direction === "forward" || t22.direction === "bidirectional")
|
|
3268
|
+
);
|
|
3269
|
+
if (hasStates && hasForwardArrows) {
|
|
3270
|
+
for (const tok of tokens) {
|
|
3271
|
+
if (tok.kind === "state" && !allStateNames.includes(tok.name)) {
|
|
3272
|
+
allStateNames.push(tok.name);
|
|
3273
|
+
}
|
|
3274
|
+
}
|
|
3275
|
+
parseTokens(tokens, stateMap, allTransitions, outgoingCounts);
|
|
3276
|
+
} else if (!hasStates && tokens.some((t22) => t22.kind === "arrow")) {
|
|
3277
|
+
let arrowIndex = 0;
|
|
3278
|
+
for (const tok of tokens) {
|
|
3279
|
+
if (tok.kind === "arrow") {
|
|
3280
|
+
if (arrowIndex < allStateNames.length - 1) {
|
|
3281
|
+
const left = allStateNames[arrowIndex];
|
|
3282
|
+
const right = allStateNames[arrowIndex + 1];
|
|
3283
|
+
if (tok.direction === "backward" || tok.direction === "bidirectional") {
|
|
3284
|
+
const name = tok.name || `to_${left}`;
|
|
3285
|
+
allTransitions.push(makeTransition(name, right, left));
|
|
3286
|
+
outgoingCounts.set(right, (outgoingCounts.get(right) || 0) + 1);
|
|
3287
|
+
}
|
|
3288
|
+
if (tok.direction === "forward" || tok.direction === "bidirectional") {
|
|
3289
|
+
const name = tok.name || `to_${right}`;
|
|
3290
|
+
allTransitions.push(makeTransition(name, left, right));
|
|
3291
|
+
outgoingCounts.set(left, (outgoingCounts.get(left) || 0) + 1);
|
|
3080
3292
|
}
|
|
3081
|
-
serverActions.push(action);
|
|
3082
3293
|
}
|
|
3294
|
+
arrowIndex++;
|
|
3295
|
+
}
|
|
3296
|
+
}
|
|
3297
|
+
} else if (hasStates) {
|
|
3298
|
+
parseTokens(tokens, stateMap, allTransitions, outgoingCounts);
|
|
3299
|
+
for (const tok of tokens) {
|
|
3300
|
+
if (tok.kind === "state" && !allStateNames.includes(tok.name)) {
|
|
3301
|
+
allStateNames.push(tok.name);
|
|
3083
3302
|
}
|
|
3084
3303
|
}
|
|
3085
3304
|
}
|
|
3086
3305
|
}
|
|
3087
|
-
|
|
3088
|
-
|
|
3089
|
-
|
|
3306
|
+
return { stateNames: allStateNames, transitions: dedupeTransitions(allTransitions) };
|
|
3307
|
+
}
|
|
3308
|
+
function parseArrowSyntax(arrow) {
|
|
3309
|
+
const lines = arrow.split("\n");
|
|
3310
|
+
const { stateNames, transitions } = parseMultiLine(lines);
|
|
3311
|
+
if (stateNames.length === 0) {
|
|
3312
|
+
return { states: [], transitions: [] };
|
|
3313
|
+
}
|
|
3314
|
+
const hasOutgoing = /* @__PURE__ */ new Set();
|
|
3315
|
+
for (const t22 of transitions) {
|
|
3316
|
+
for (const from of t22.from) {
|
|
3317
|
+
hasOutgoing.add(from);
|
|
3318
|
+
}
|
|
3319
|
+
}
|
|
3320
|
+
const states = stateNames.map((name, idx) => {
|
|
3321
|
+
let type = "REGULAR";
|
|
3322
|
+
if (idx === 0) {
|
|
3323
|
+
type = "START";
|
|
3324
|
+
} else if (!hasOutgoing.has(name)) {
|
|
3325
|
+
type = "END";
|
|
3326
|
+
}
|
|
3327
|
+
return makeState(name, type);
|
|
3328
|
+
});
|
|
3329
|
+
return { states, transitions };
|
|
3330
|
+
}
|
|
3331
|
+
function parseFieldRecord(fields) {
|
|
3332
|
+
return Object.entries(fields).map(([name, typeStr]) => {
|
|
3333
|
+
let required = false;
|
|
3334
|
+
let raw = typeStr.trim();
|
|
3335
|
+
if (raw.endsWith("!")) {
|
|
3336
|
+
required = true;
|
|
3337
|
+
raw = raw.slice(0, -1).trim();
|
|
3338
|
+
}
|
|
3339
|
+
let defaultValue;
|
|
3340
|
+
const eqIdx = raw.indexOf("=");
|
|
3341
|
+
let typePart = raw;
|
|
3342
|
+
if (eqIdx !== -1) {
|
|
3343
|
+
typePart = raw.slice(0, eqIdx).trim();
|
|
3344
|
+
const valStr = raw.slice(eqIdx + 1).trim();
|
|
3345
|
+
try {
|
|
3346
|
+
defaultValue = JSON.parse(valStr);
|
|
3347
|
+
} catch {
|
|
3348
|
+
defaultValue = valStr;
|
|
3349
|
+
}
|
|
3350
|
+
}
|
|
3351
|
+
const TYPE_MAP = {
|
|
3352
|
+
string: "text",
|
|
3353
|
+
str: "text",
|
|
3354
|
+
text: "text",
|
|
3355
|
+
number: "number",
|
|
3356
|
+
num: "number",
|
|
3357
|
+
int: "number",
|
|
3358
|
+
integer: "number",
|
|
3359
|
+
float: "number",
|
|
3360
|
+
bool: "boolean",
|
|
3361
|
+
boolean: "boolean",
|
|
3362
|
+
date: "date",
|
|
3363
|
+
datetime: "datetime",
|
|
3364
|
+
email: "email",
|
|
3365
|
+
url: "url",
|
|
3366
|
+
json: "json",
|
|
3367
|
+
object: "json",
|
|
3368
|
+
array: "json",
|
|
3369
|
+
select: "select",
|
|
3370
|
+
enum: "select",
|
|
3371
|
+
file: "file",
|
|
3372
|
+
image: "image",
|
|
3373
|
+
currency: "currency",
|
|
3374
|
+
phone: "phone",
|
|
3375
|
+
address: "address",
|
|
3376
|
+
rich_text: "rich_text",
|
|
3377
|
+
richtext: "rich_text",
|
|
3378
|
+
color: "color",
|
|
3379
|
+
rating: "rating"
|
|
3380
|
+
};
|
|
3381
|
+
const fieldType = TYPE_MAP[typePart.toLowerCase()] || typePart;
|
|
3382
|
+
const field = {
|
|
3383
|
+
name,
|
|
3384
|
+
type: fieldType
|
|
3385
|
+
};
|
|
3386
|
+
if (required) field.required = true;
|
|
3387
|
+
if (defaultValue !== void 0) field.default_value = defaultValue;
|
|
3388
|
+
return field;
|
|
3389
|
+
});
|
|
3390
|
+
}
|
|
3391
|
+
function parseWorkflowShorthand(slug, fieldsOrArrow, arrowString) {
|
|
3392
|
+
let fields = [];
|
|
3393
|
+
let arrow;
|
|
3394
|
+
if (typeof fieldsOrArrow === "string") {
|
|
3395
|
+
arrow = fieldsOrArrow;
|
|
3396
|
+
} else {
|
|
3397
|
+
fields = parseFieldRecord(fieldsOrArrow);
|
|
3398
|
+
arrow = arrowString || "";
|
|
3090
3399
|
}
|
|
3400
|
+
const { states, transitions } = parseArrowSyntax(arrow);
|
|
3401
|
+
return { slug, fields, states, transitions };
|
|
3091
3402
|
}
|
|
3092
|
-
|
|
3093
|
-
|
|
3094
|
-
|
|
3095
|
-
|
|
3096
|
-
|
|
3097
|
-
|
|
3098
|
-
|
|
3099
|
-
|
|
3100
|
-
|
|
3101
|
-
|
|
3102
|
-
|
|
3403
|
+
|
|
3404
|
+
// src/babel/extractors/flow-extractor.ts
|
|
3405
|
+
function isImperativeWorkflowFile(path, _filename) {
|
|
3406
|
+
for (const node of path.node.body) {
|
|
3407
|
+
if (t12.isExportDefaultDeclaration(node)) {
|
|
3408
|
+
const decl = node.declaration;
|
|
3409
|
+
if (t12.isFunctionDeclaration(decl) && decl.async && decl.params.length > 0) {
|
|
3410
|
+
const param = decl.params[0];
|
|
3411
|
+
if (t12.isIdentifier(param) && param.typeAnnotation) {
|
|
3412
|
+
return true;
|
|
3413
|
+
}
|
|
3414
|
+
}
|
|
3415
|
+
if (t12.isCallExpression(decl) && t12.isIdentifier(decl.callee) && decl.callee.name === "workflow") {
|
|
3416
|
+
return true;
|
|
3417
|
+
}
|
|
3103
3418
|
}
|
|
3104
3419
|
}
|
|
3105
|
-
return
|
|
3420
|
+
return false;
|
|
3106
3421
|
}
|
|
3107
|
-
|
|
3108
|
-
|
|
3109
|
-
|
|
3110
|
-
|
|
3111
|
-
|
|
3422
|
+
var VALIDATION_FNS = /* @__PURE__ */ new Set(["validate", "assert"]);
|
|
3423
|
+
function roleCondition(role) {
|
|
3424
|
+
return { type: "role", field: role, operator: "eq", value: true };
|
|
3425
|
+
}
|
|
3426
|
+
var TS_TYPE_MAP = {
|
|
3427
|
+
Date: "datetime",
|
|
3428
|
+
Record: "json",
|
|
3429
|
+
Map: "json",
|
|
3430
|
+
Set: "json",
|
|
3431
|
+
URL: "url"
|
|
3432
|
+
};
|
|
3433
|
+
var NAME_TYPE_MAP = {
|
|
3434
|
+
email: "email",
|
|
3435
|
+
url: "url",
|
|
3436
|
+
website: "url",
|
|
3437
|
+
phone: "phone"
|
|
3438
|
+
};
|
|
3439
|
+
function resolveType2(annotation) {
|
|
3440
|
+
if (t12.isTSStringKeyword(annotation)) return "text";
|
|
3441
|
+
if (t12.isTSNumberKeyword(annotation)) return "number";
|
|
3442
|
+
if (t12.isTSBooleanKeyword(annotation)) return "boolean";
|
|
3443
|
+
if (t12.isTSTypeReference(annotation) && t12.isIdentifier(annotation.typeName)) {
|
|
3444
|
+
const name = annotation.typeName.name;
|
|
3445
|
+
if (TS_TYPE_MAP[name]) return TS_TYPE_MAP[name];
|
|
3446
|
+
if (name === "Array") return "multi_select";
|
|
3447
|
+
return name.replace(/([A-Z])/g, "-$1").toLowerCase().replace(/^-/, "");
|
|
3448
|
+
}
|
|
3449
|
+
if (t12.isTSArrayType(annotation)) return "multi_select";
|
|
3450
|
+
if (t12.isTSUnionType(annotation)) {
|
|
3451
|
+
const allLiterals = annotation.types.every(
|
|
3452
|
+
(t22) => t12.isTSLiteralType(t22) && (t12.isStringLiteral(t22.literal) || t12.isNumericLiteral(t22.literal))
|
|
3453
|
+
);
|
|
3454
|
+
if (allLiterals) return "select";
|
|
3455
|
+
return "text";
|
|
3456
|
+
}
|
|
3457
|
+
if (t12.isTSLiteralType(annotation) && t12.isStringLiteral(annotation.literal)) return "text";
|
|
3458
|
+
if (t12.isTSLiteralType(annotation) && t12.isNumericLiteral(annotation.literal)) return "number";
|
|
3459
|
+
return "text";
|
|
3460
|
+
}
|
|
3461
|
+
function extractUnionOptions2(annotation) {
|
|
3462
|
+
if (!t12.isTSUnionType(annotation)) return void 0;
|
|
3463
|
+
const options = [];
|
|
3464
|
+
for (const member of annotation.types) {
|
|
3465
|
+
if (t12.isTSLiteralType(member) && t12.isStringLiteral(member.literal)) {
|
|
3466
|
+
options.push(member.literal.value);
|
|
3112
3467
|
}
|
|
3113
3468
|
}
|
|
3114
|
-
return void 0;
|
|
3469
|
+
return options.length > 0 ? options : void 0;
|
|
3115
3470
|
}
|
|
3116
|
-
function
|
|
3117
|
-
|
|
3118
|
-
|
|
3119
|
-
|
|
3120
|
-
|
|
3121
|
-
|
|
3122
|
-
|
|
3123
|
-
|
|
3471
|
+
function extractFieldsFromInterface2(declaration) {
|
|
3472
|
+
const fields = [];
|
|
3473
|
+
for (const member of declaration.body.body) {
|
|
3474
|
+
if (!t12.isTSPropertySignature(member)) continue;
|
|
3475
|
+
if (!t12.isIdentifier(member.key)) continue;
|
|
3476
|
+
const name = member.key.name;
|
|
3477
|
+
const required = !member.optional;
|
|
3478
|
+
const typeAnno = member.typeAnnotation;
|
|
3479
|
+
let fieldType = typeAnno ? resolveType2(typeAnno.typeAnnotation) : "text";
|
|
3480
|
+
if (NAME_TYPE_MAP[name]) fieldType = NAME_TYPE_MAP[name];
|
|
3481
|
+
const field = {
|
|
3482
|
+
name,
|
|
3483
|
+
type: fieldType,
|
|
3484
|
+
label: name.replace(/([A-Z])/g, " $1").replace(/^./, (c) => c.toUpperCase()),
|
|
3485
|
+
required,
|
|
3486
|
+
default_value: getDefaultForType(fieldType)
|
|
3487
|
+
};
|
|
3488
|
+
if (typeAnno) {
|
|
3489
|
+
const options = extractUnionOptions2(typeAnno.typeAnnotation);
|
|
3490
|
+
if (options) {
|
|
3491
|
+
field.validation = { options };
|
|
3124
3492
|
}
|
|
3125
3493
|
}
|
|
3494
|
+
fields.push(field);
|
|
3126
3495
|
}
|
|
3127
|
-
return
|
|
3496
|
+
return fields;
|
|
3128
3497
|
}
|
|
3129
|
-
|
|
3130
|
-
|
|
3131
|
-
|
|
3132
|
-
|
|
3133
|
-
|
|
3134
|
-
|
|
3135
|
-
|
|
3136
|
-
|
|
3137
|
-
|
|
3138
|
-
|
|
3139
|
-
|
|
3140
|
-
|
|
3141
|
-
|
|
3142
|
-
|
|
3143
|
-
|
|
3144
|
-
|
|
3145
|
-
|
|
3146
|
-
|
|
3498
|
+
function getDefaultForType(type) {
|
|
3499
|
+
switch (type) {
|
|
3500
|
+
case "text":
|
|
3501
|
+
case "email":
|
|
3502
|
+
case "url":
|
|
3503
|
+
case "phone":
|
|
3504
|
+
case "select":
|
|
3505
|
+
return "";
|
|
3506
|
+
case "number":
|
|
3507
|
+
case "currency":
|
|
3508
|
+
return 0;
|
|
3509
|
+
case "boolean":
|
|
3510
|
+
return false;
|
|
3511
|
+
case "multi_select":
|
|
3512
|
+
return [];
|
|
3513
|
+
case "json":
|
|
3514
|
+
return {};
|
|
3515
|
+
default:
|
|
3516
|
+
return null;
|
|
3517
|
+
}
|
|
3518
|
+
}
|
|
3519
|
+
function extractNodeValue2(node) {
|
|
3520
|
+
if (t12.isStringLiteral(node)) return node.value;
|
|
3521
|
+
if (t12.isNumericLiteral(node)) return node.value;
|
|
3522
|
+
if (t12.isBooleanLiteral(node)) return node.value;
|
|
3523
|
+
if (t12.isNullLiteral(node)) return null;
|
|
3524
|
+
if (t12.isArrayExpression(node)) {
|
|
3525
|
+
return node.elements.map((el) => {
|
|
3526
|
+
if (!el || t12.isSpreadElement(el)) return null;
|
|
3527
|
+
return extractNodeValue2(el);
|
|
3528
|
+
});
|
|
3529
|
+
}
|
|
3530
|
+
if (t12.isObjectExpression(node)) {
|
|
3531
|
+
const obj = {};
|
|
3532
|
+
for (const prop of node.properties) {
|
|
3533
|
+
if (!t12.isObjectProperty(prop)) continue;
|
|
3534
|
+
const key = t12.isIdentifier(prop.key) ? prop.key.name : t12.isStringLiteral(prop.key) ? prop.key.value : null;
|
|
3535
|
+
if (key) obj[key] = extractNodeValue2(prop.value);
|
|
3147
3536
|
}
|
|
3537
|
+
return obj;
|
|
3148
3538
|
}
|
|
3149
|
-
|
|
3150
|
-
|
|
3151
|
-
entry.variableName = parent.node.id.name;
|
|
3539
|
+
if (t12.isTemplateLiteral(node)) {
|
|
3540
|
+
return node.quasis.map((q) => q.value.raw).join("${}");
|
|
3152
3541
|
}
|
|
3153
|
-
if (
|
|
3154
|
-
|
|
3155
|
-
|
|
3156
|
-
|
|
3542
|
+
if (t12.isIdentifier(node)) {
|
|
3543
|
+
if (node.name === "undefined") return void 0;
|
|
3544
|
+
return node.name;
|
|
3545
|
+
}
|
|
3546
|
+
if (t12.isMemberExpression(node)) {
|
|
3547
|
+
return memberExprToString(node);
|
|
3548
|
+
}
|
|
3549
|
+
if (t12.isTSAsExpression(node)) return extractNodeValue2(node.expression);
|
|
3550
|
+
if (t12.isArrowFunctionExpression(node) || t12.isFunctionExpression(node)) {
|
|
3551
|
+
return "[Function]";
|
|
3552
|
+
}
|
|
3553
|
+
return "[Expression]";
|
|
3157
3554
|
}
|
|
3158
|
-
|
|
3159
|
-
|
|
3160
|
-
|
|
3161
|
-
|
|
3162
|
-
|
|
3163
|
-
|
|
3164
|
-
const
|
|
3165
|
-
const
|
|
3166
|
-
const
|
|
3167
|
-
|
|
3168
|
-
|
|
3555
|
+
function memberExprToString(node) {
|
|
3556
|
+
const obj = t12.isIdentifier(node.object) ? node.object.name : t12.isMemberExpression(node.object) ? memberExprToString(node.object) : "[object]";
|
|
3557
|
+
const prop = t12.isIdentifier(node.property) ? node.property.name : t12.isStringLiteral(node.property) ? node.property.value : "[property]";
|
|
3558
|
+
return `${obj}.${prop}`;
|
|
3559
|
+
}
|
|
3560
|
+
function analyzeStateFn(fn, paramName, actionCounter) {
|
|
3561
|
+
const onEnter = [];
|
|
3562
|
+
const validations = [];
|
|
3563
|
+
const conditions = [];
|
|
3564
|
+
const roles = [];
|
|
3565
|
+
const requiredFields = [];
|
|
3566
|
+
const during = [];
|
|
3567
|
+
const onEvent = [];
|
|
3568
|
+
let timeout;
|
|
3569
|
+
let runtime;
|
|
3570
|
+
if (!fn.body || !t12.isBlockStatement(fn.body)) {
|
|
3571
|
+
return { onEnter, validations, conditions, roles, requiredFields, during, onEvent, timeout, runtime };
|
|
3572
|
+
}
|
|
3573
|
+
for (const stmt of fn.body.body) {
|
|
3574
|
+
processStatement(stmt, paramName, actionCounter, {
|
|
3575
|
+
onEnter,
|
|
3576
|
+
validations,
|
|
3577
|
+
conditions,
|
|
3578
|
+
roles,
|
|
3579
|
+
requiredFields,
|
|
3580
|
+
during,
|
|
3581
|
+
onEvent,
|
|
3582
|
+
setTimeout: (t22) => {
|
|
3583
|
+
timeout = t22;
|
|
3584
|
+
},
|
|
3585
|
+
setRuntime: (r) => {
|
|
3586
|
+
runtime = r;
|
|
3587
|
+
}
|
|
3588
|
+
});
|
|
3169
3589
|
}
|
|
3170
|
-
|
|
3171
|
-
|
|
3172
|
-
|
|
3173
|
-
|
|
3174
|
-
|
|
3590
|
+
return { onEnter, validations, conditions, roles, requiredFields, during, onEvent, timeout, runtime };
|
|
3591
|
+
}
|
|
3592
|
+
function processStatement(stmt, paramName, actionCounter, ctx) {
|
|
3593
|
+
if (t12.isExpressionStatement(stmt)) {
|
|
3594
|
+
processExpression(stmt.expression, paramName, actionCounter, ctx);
|
|
3595
|
+
return;
|
|
3596
|
+
}
|
|
3597
|
+
if (t12.isIfStatement(stmt)) {
|
|
3598
|
+
const testStr = expressionToIR(stmt.test, paramName);
|
|
3599
|
+
if (t12.isBlockStatement(stmt.consequent)) {
|
|
3600
|
+
for (const inner of stmt.consequent.body) {
|
|
3601
|
+
processStatement(inner, paramName, actionCounter, {
|
|
3602
|
+
...ctx,
|
|
3603
|
+
ifCondition: testStr
|
|
3604
|
+
});
|
|
3175
3605
|
}
|
|
3176
3606
|
}
|
|
3607
|
+
return;
|
|
3177
3608
|
}
|
|
3178
|
-
|
|
3179
|
-
|
|
3180
|
-
|
|
3181
|
-
|
|
3182
|
-
} else if (t14.isObjectPattern(parent.node.id)) {
|
|
3183
|
-
const props = parent.node.id.properties.filter((p) => t14.isObjectProperty(p) && t14.isIdentifier(p.key)).map((p) => p.key.name);
|
|
3184
|
-
if (props.length > 0) {
|
|
3185
|
-
entry.variableName = props.join(", ");
|
|
3609
|
+
if (t12.isVariableDeclaration(stmt)) {
|
|
3610
|
+
for (const decl of stmt.declarations) {
|
|
3611
|
+
if (decl.init && t12.isAwaitExpression(decl.init)) {
|
|
3612
|
+
processExpression(decl.init, paramName, actionCounter, ctx);
|
|
3186
3613
|
}
|
|
3187
3614
|
}
|
|
3188
3615
|
}
|
|
3189
|
-
if (!compilerState.metadata) compilerState.metadata = {};
|
|
3190
|
-
const meta = compilerState.metadata;
|
|
3191
|
-
if (!meta.serverStateSubscriptions) meta.serverStateSubscriptions = [];
|
|
3192
|
-
meta.serverStateSubscriptions.push(entry);
|
|
3193
|
-
meta.requiresSSE = true;
|
|
3194
3616
|
}
|
|
3195
|
-
|
|
3196
|
-
|
|
3197
|
-
|
|
3198
|
-
|
|
3199
|
-
|
|
3200
|
-
|
|
3201
|
-
|
|
3202
|
-
|
|
3203
|
-
|
|
3617
|
+
function processExpression(expr, paramName, actionCounter, ctx) {
|
|
3618
|
+
if (t12.isAssignmentExpression(expr) && t12.isMemberExpression(expr.left)) {
|
|
3619
|
+
const left = memberExprToString(expr.left);
|
|
3620
|
+
if (left.startsWith(`${paramName}.`)) {
|
|
3621
|
+
const field = left.slice(paramName.length + 1);
|
|
3622
|
+
const valueExpr = expressionToIR(expr.right, paramName);
|
|
3623
|
+
const action = {
|
|
3624
|
+
id: `auto_${++actionCounter.value}`,
|
|
3625
|
+
type: "set_field",
|
|
3626
|
+
mode: "auto",
|
|
3627
|
+
config: { field, expression: valueExpr },
|
|
3628
|
+
...ctx.ifCondition ? { condition: ctx.ifCondition } : {}
|
|
3629
|
+
};
|
|
3630
|
+
ctx.onEnter.push(action);
|
|
3631
|
+
return;
|
|
3632
|
+
}
|
|
3633
|
+
}
|
|
3634
|
+
if (t12.isAssignmentExpression(expr) && expr.operator !== "=" && t12.isMemberExpression(expr.left)) {
|
|
3635
|
+
const left = memberExprToString(expr.left);
|
|
3636
|
+
if (left.startsWith(`${paramName}.`)) {
|
|
3637
|
+
const field = left.slice(paramName.length + 1);
|
|
3638
|
+
const op = expr.operator.replace("=", "");
|
|
3639
|
+
const valueExpr = expressionToIR(expr.right, paramName);
|
|
3640
|
+
const action = {
|
|
3641
|
+
id: `auto_${++actionCounter.value}`,
|
|
3642
|
+
type: "set_field",
|
|
3643
|
+
mode: "auto",
|
|
3644
|
+
config: { field, expression: `state_data.${field} ${op} ${valueExpr}` },
|
|
3645
|
+
...ctx.ifCondition ? { condition: ctx.ifCondition } : {}
|
|
3646
|
+
};
|
|
3647
|
+
ctx.onEnter.push(action);
|
|
3648
|
+
return;
|
|
3649
|
+
}
|
|
3650
|
+
}
|
|
3651
|
+
if (t12.isCallExpression(expr) || t12.isAwaitExpression(expr) && t12.isCallExpression(expr.argument)) {
|
|
3652
|
+
const call = t12.isAwaitExpression(expr) ? expr.argument : expr;
|
|
3653
|
+
const fnName = t12.isIdentifier(call.callee) ? call.callee.name : t12.isMemberExpression(call.callee) && t12.isIdentifier(call.callee.property) ? call.callee.property.name : null;
|
|
3654
|
+
if (!fnName) return;
|
|
3655
|
+
if (VALIDATION_FNS.has(fnName)) {
|
|
3656
|
+
extractValidation(call, paramName, ctx);
|
|
3657
|
+
return;
|
|
3658
|
+
}
|
|
3659
|
+
if (fnName === "log") {
|
|
3660
|
+
const event = call.arguments[0] ? extractNodeValue2(call.arguments[0]) : "";
|
|
3661
|
+
const data = call.arguments[1] ? extractNodeValue2(call.arguments[1]) : void 0;
|
|
3662
|
+
ctx.onEnter.push({
|
|
3663
|
+
id: `auto_${++actionCounter.value}`,
|
|
3664
|
+
type: "log_event",
|
|
3665
|
+
mode: "auto",
|
|
3666
|
+
config: { event: String(event), ...data ? { data } : {} },
|
|
3667
|
+
...ctx.ifCondition ? { condition: ctx.ifCondition } : {}
|
|
3668
|
+
});
|
|
3669
|
+
return;
|
|
3670
|
+
}
|
|
3671
|
+
if (fnName === "notify") {
|
|
3672
|
+
const to = call.arguments[0] ? expressionToIR(call.arguments[0], paramName) : "";
|
|
3673
|
+
const message = call.arguments[1] ? extractNodeValue2(call.arguments[1]) : "";
|
|
3674
|
+
const opts = call.arguments[2] ? extractNodeValue2(call.arguments[2]) : {};
|
|
3675
|
+
ctx.onEnter.push({
|
|
3676
|
+
id: `auto_${++actionCounter.value}`,
|
|
3677
|
+
type: "send_notification",
|
|
3678
|
+
mode: "auto",
|
|
3679
|
+
config: {
|
|
3680
|
+
to: String(to),
|
|
3681
|
+
message: String(message),
|
|
3682
|
+
...opts
|
|
3683
|
+
},
|
|
3684
|
+
...ctx.ifCondition ? { condition: ctx.ifCondition } : {}
|
|
3685
|
+
});
|
|
3686
|
+
return;
|
|
3687
|
+
}
|
|
3688
|
+
if (fnName === "emit") {
|
|
3689
|
+
const event = call.arguments[0] ? extractNodeValue2(call.arguments[0]) : "";
|
|
3690
|
+
const payload = call.arguments[1] ? extractNodeValue2(call.arguments[1]) : void 0;
|
|
3691
|
+
ctx.onEnter.push({
|
|
3692
|
+
id: `auto_${++actionCounter.value}`,
|
|
3693
|
+
type: "emit_event",
|
|
3694
|
+
mode: "auto",
|
|
3695
|
+
config: { event: String(event), ...payload ? { payload } : {} },
|
|
3696
|
+
...ctx.ifCondition ? { condition: ctx.ifCondition } : {}
|
|
3697
|
+
});
|
|
3698
|
+
return;
|
|
3699
|
+
}
|
|
3700
|
+
if (fnName === "requireRole") {
|
|
3701
|
+
for (const arg of call.arguments) {
|
|
3702
|
+
if (t12.isStringLiteral(arg)) ctx.roles.push(arg.value);
|
|
3703
|
+
}
|
|
3704
|
+
return;
|
|
3705
|
+
}
|
|
3706
|
+
if (fnName === "requireField") {
|
|
3707
|
+
for (const arg of call.arguments) {
|
|
3708
|
+
if (t12.isStringLiteral(arg)) ctx.requiredFields.push(arg.value);
|
|
3709
|
+
}
|
|
3710
|
+
return;
|
|
3711
|
+
}
|
|
3712
|
+
if (fnName === "runtime") {
|
|
3713
|
+
if (call.arguments[0] && t12.isStringLiteral(call.arguments[0])) {
|
|
3714
|
+
ctx.setRuntime(call.arguments[0].value);
|
|
3715
|
+
}
|
|
3716
|
+
return;
|
|
3717
|
+
}
|
|
3718
|
+
if (fnName === "guard") {
|
|
3719
|
+
if (call.arguments[0] && t12.isStringLiteral(call.arguments[0])) {
|
|
3720
|
+
ctx.conditions.push({ expression: call.arguments[0].value });
|
|
3721
|
+
}
|
|
3722
|
+
return;
|
|
3723
|
+
}
|
|
3724
|
+
if (fnName === "every") {
|
|
3725
|
+
const interval = call.arguments[0] && t12.isStringLiteral(call.arguments[0]) ? call.arguments[0].value : "1h";
|
|
3726
|
+
const intervalMs = parseDuration(interval);
|
|
3727
|
+
const opts = call.arguments[1] ? extractNodeValue2(call.arguments[1]) : {};
|
|
3728
|
+
const duringAction = {
|
|
3729
|
+
id: `during_${++actionCounter.value}`,
|
|
3730
|
+
type: "interval",
|
|
3731
|
+
interval_ms: intervalMs,
|
|
3732
|
+
...typeof opts === "object" && opts !== null && opts.when ? { condition: opts.when } : {},
|
|
3733
|
+
actions: []
|
|
3734
|
+
// Placeholder — body analysis would extract inner actions
|
|
3735
|
+
};
|
|
3736
|
+
ctx.during.push(duringAction);
|
|
3737
|
+
return;
|
|
3738
|
+
}
|
|
3739
|
+
if (fnName === "cron") {
|
|
3740
|
+
const cronExpr = call.arguments[0] && t12.isStringLiteral(call.arguments[0]) ? call.arguments[0].value : "* * * * *";
|
|
3741
|
+
ctx.during.push({
|
|
3742
|
+
id: `during_${++actionCounter.value}`,
|
|
3743
|
+
type: "cron",
|
|
3744
|
+
cron: cronExpr,
|
|
3745
|
+
actions: []
|
|
3746
|
+
});
|
|
3747
|
+
return;
|
|
3748
|
+
}
|
|
3749
|
+
if (fnName === "after") {
|
|
3750
|
+
const delay = call.arguments[0] && t12.isStringLiteral(call.arguments[0]) ? call.arguments[0].value : "1h";
|
|
3751
|
+
ctx.during.push({
|
|
3752
|
+
id: `during_${++actionCounter.value}`,
|
|
3753
|
+
type: "timeout",
|
|
3754
|
+
delay_ms: parseDuration(delay),
|
|
3755
|
+
actions: []
|
|
3756
|
+
});
|
|
3757
|
+
return;
|
|
3758
|
+
}
|
|
3759
|
+
if (fnName === "on" && !t12.isAwaitExpression(expr)) {
|
|
3760
|
+
const pattern = call.arguments[0] && t12.isStringLiteral(call.arguments[0]) ? call.arguments[0].value : "*";
|
|
3761
|
+
const opts = call.arguments[1] ? extractNodeValue2(call.arguments[1]) : {};
|
|
3762
|
+
const optsObj = typeof opts === "object" && opts !== null ? opts : {};
|
|
3763
|
+
ctx.onEvent.push({
|
|
3764
|
+
match: pattern,
|
|
3765
|
+
...optsObj.when ? { conditions: [String(optsObj.when)] } : {},
|
|
3766
|
+
actions: []
|
|
3767
|
+
});
|
|
3768
|
+
return;
|
|
3769
|
+
}
|
|
3770
|
+
if (fnName === "timeout") {
|
|
3771
|
+
const duration = call.arguments[0] && t12.isStringLiteral(call.arguments[0]) ? call.arguments[0].value : "1h";
|
|
3772
|
+
const opts = call.arguments[1] ? extractNodeValue2(call.arguments[1]) : {};
|
|
3773
|
+
const optsObj = typeof opts === "object" && opts !== null ? opts : {};
|
|
3774
|
+
ctx.setTimeout({
|
|
3775
|
+
duration,
|
|
3776
|
+
fallback: {
|
|
3777
|
+
...optsObj.transition ? { transition: String(optsObj.transition) } : {},
|
|
3778
|
+
...optsObj.action ? { action: String(optsObj.action) } : {}
|
|
3779
|
+
}
|
|
3780
|
+
});
|
|
3781
|
+
return;
|
|
3782
|
+
}
|
|
3783
|
+
if (fnName === "restrict") {
|
|
3784
|
+
return;
|
|
3785
|
+
}
|
|
3786
|
+
}
|
|
3787
|
+
}
|
|
3788
|
+
function extractValidation(call, paramName, ctx) {
|
|
3789
|
+
const condArg = call.arguments[0];
|
|
3790
|
+
const msgArg = call.arguments[1];
|
|
3791
|
+
const sevArg = call.arguments[2];
|
|
3792
|
+
const message = msgArg && t12.isStringLiteral(msgArg) ? msgArg.value : "Validation failed";
|
|
3793
|
+
const severity = sevArg && t12.isStringLiteral(sevArg) && sevArg.value === "warning" ? "warning" : "error";
|
|
3794
|
+
if (!condArg) return;
|
|
3795
|
+
const field = extractFieldFromCondition(condArg, paramName);
|
|
3796
|
+
const exprStr = expressionToIR(condArg, paramName);
|
|
3797
|
+
if (field) {
|
|
3798
|
+
const validation = {};
|
|
3799
|
+
if (t12.isBinaryExpression(condArg) && (condArg.operator === ">" || condArg.operator === ">=")) {
|
|
3800
|
+
if (isLengthAccess(condArg.left, paramName, field) && t12.isNumericLiteral(condArg.right)) {
|
|
3801
|
+
validation.minLength = condArg.right.value + (condArg.operator === ">" ? 1 : 0);
|
|
3802
|
+
} else if (isFieldAccess(condArg.left, paramName, field) && t12.isNumericLiteral(condArg.right)) {
|
|
3803
|
+
validation.min = condArg.right.value + (condArg.operator === ">" ? 1e-3 : 0);
|
|
3804
|
+
}
|
|
3805
|
+
}
|
|
3806
|
+
if (t12.isBinaryExpression(condArg) && (condArg.operator === "<" || condArg.operator === "<=")) {
|
|
3807
|
+
if (isFieldAccess(condArg.left, paramName, field) && t12.isNumericLiteral(condArg.right)) {
|
|
3808
|
+
validation.max = condArg.right.value;
|
|
3809
|
+
}
|
|
3810
|
+
}
|
|
3811
|
+
if (t12.isCallExpression(condArg) && t12.isMemberExpression(condArg.callee) && t12.isRegExpLiteral(condArg.callee.object) && t12.isIdentifier(condArg.callee.property) && condArg.callee.property.name === "test") {
|
|
3812
|
+
if (!validation.rules) validation.rules = [];
|
|
3813
|
+
validation.rules.push({
|
|
3814
|
+
expression: `MATCHES(value, "${condArg.callee.object.pattern}")`,
|
|
3815
|
+
message: "",
|
|
3816
|
+
// Will be set from the validate() message arg
|
|
3817
|
+
severity: "error"
|
|
3818
|
+
});
|
|
3819
|
+
}
|
|
3820
|
+
ctx.validations.push({ field, validation, message, severity });
|
|
3821
|
+
} else {
|
|
3822
|
+
ctx.validations.push({
|
|
3823
|
+
field: "__cross__",
|
|
3824
|
+
validation: { rules: [{ expression: exprStr, message, severity }] },
|
|
3825
|
+
message,
|
|
3826
|
+
severity
|
|
3827
|
+
});
|
|
3828
|
+
}
|
|
3829
|
+
}
|
|
3830
|
+
function extractFieldFromCondition(node, paramName) {
|
|
3831
|
+
if (t12.isMemberExpression(node)) {
|
|
3832
|
+
const str = memberExprToString(node);
|
|
3833
|
+
if (str.startsWith(`${paramName}.`)) {
|
|
3834
|
+
const parts = str.slice(paramName.length + 1).split(".");
|
|
3835
|
+
return parts[0];
|
|
3836
|
+
}
|
|
3837
|
+
}
|
|
3838
|
+
if (t12.isBinaryExpression(node)) {
|
|
3839
|
+
return extractFieldFromCondition(node.left, paramName) || extractFieldFromCondition(node.right, paramName);
|
|
3840
|
+
}
|
|
3841
|
+
if (t12.isCallExpression(node) && t12.isMemberExpression(node.callee)) {
|
|
3842
|
+
return extractFieldFromCondition(node.callee.object, paramName);
|
|
3843
|
+
}
|
|
3844
|
+
if (t12.isCallExpression(node) && t12.isMemberExpression(node.callee) && t12.isRegExpLiteral(node.callee.object) && node.arguments[0]) {
|
|
3845
|
+
return extractFieldFromCondition(node.arguments[0], paramName);
|
|
3846
|
+
}
|
|
3847
|
+
if (t12.isLogicalExpression(node)) {
|
|
3848
|
+
return extractFieldFromCondition(node.left, paramName) || extractFieldFromCondition(node.right, paramName);
|
|
3849
|
+
}
|
|
3850
|
+
if (t12.isUnaryExpression(node)) {
|
|
3851
|
+
return extractFieldFromCondition(node.argument, paramName);
|
|
3852
|
+
}
|
|
3853
|
+
return null;
|
|
3854
|
+
}
|
|
3855
|
+
function isLengthAccess(node, paramName, field) {
|
|
3856
|
+
if (!t12.isMemberExpression(node)) return false;
|
|
3857
|
+
const str = memberExprToString(node);
|
|
3858
|
+
return str === `${paramName}.${field}.length`;
|
|
3859
|
+
}
|
|
3860
|
+
function isFieldAccess(node, paramName, field) {
|
|
3861
|
+
if (!t12.isMemberExpression(node)) return false;
|
|
3862
|
+
const str = memberExprToString(node);
|
|
3863
|
+
return str === `${paramName}.${field}`;
|
|
3864
|
+
}
|
|
3865
|
+
function expressionToIR(node, paramName) {
|
|
3866
|
+
if (t12.isStringLiteral(node)) return `"${node.value}"`;
|
|
3867
|
+
if (t12.isNumericLiteral(node)) return String(node.value);
|
|
3868
|
+
if (t12.isBooleanLiteral(node)) return String(node.value);
|
|
3869
|
+
if (t12.isNullLiteral(node)) return "null";
|
|
3870
|
+
if (t12.isIdentifier(node)) {
|
|
3871
|
+
if (node.name === paramName) return "state_data";
|
|
3872
|
+
if (node.name === "actor") return "context";
|
|
3873
|
+
if (node.name === "instance") return "instance";
|
|
3874
|
+
return node.name;
|
|
3875
|
+
}
|
|
3876
|
+
if (t12.isMemberExpression(node)) {
|
|
3877
|
+
const str = memberExprToString(node);
|
|
3878
|
+
if (str.startsWith(`${paramName}.`)) return "state_data." + str.slice(paramName.length + 1);
|
|
3879
|
+
if (str.startsWith("actor.")) return "context." + str.slice(6);
|
|
3880
|
+
if (str.startsWith("Date.")) {
|
|
3881
|
+
if (str === "Date.now") return "NOW()";
|
|
3882
|
+
}
|
|
3883
|
+
return str;
|
|
3884
|
+
}
|
|
3885
|
+
if (t12.isCallExpression(node)) {
|
|
3886
|
+
if (t12.isMemberExpression(node.callee) && t12.isIdentifier(node.callee.property)) {
|
|
3887
|
+
const obj = expressionToIR(node.callee.object, paramName);
|
|
3888
|
+
const method = node.callee.property.name;
|
|
3889
|
+
if (method === "now" && obj === "Date") return "NOW()";
|
|
3890
|
+
if (method === "includes") {
|
|
3891
|
+
const arg = node.arguments[0] ? expressionToIR(node.arguments[0], paramName) : "";
|
|
3892
|
+
return `CONTAINS(${obj}, ${arg})`;
|
|
3893
|
+
}
|
|
3894
|
+
if (method === "length") return `LEN(${obj})`;
|
|
3895
|
+
}
|
|
3896
|
+
if (t12.isIdentifier(node.callee) && node.callee.name === "Date") {
|
|
3897
|
+
if (t12.isMemberExpression(node) && t12.isIdentifier(node.property) && node.property.name === "now") {
|
|
3898
|
+
return "NOW()";
|
|
3899
|
+
}
|
|
3900
|
+
}
|
|
3901
|
+
return "[call]";
|
|
3902
|
+
}
|
|
3903
|
+
if (t12.isBinaryExpression(node)) {
|
|
3904
|
+
const left = expressionToIR(node.left, paramName);
|
|
3905
|
+
const right = expressionToIR(node.right, paramName);
|
|
3906
|
+
return `${left} ${node.operator} ${right}`;
|
|
3907
|
+
}
|
|
3908
|
+
if (t12.isLogicalExpression(node)) {
|
|
3909
|
+
const left = expressionToIR(node.left, paramName);
|
|
3910
|
+
const right = expressionToIR(node.right, paramName);
|
|
3911
|
+
const op = node.operator === "&&" ? "AND" : node.operator === "||" ? "OR" : node.operator;
|
|
3912
|
+
return `${left} ${op} ${right}`;
|
|
3913
|
+
}
|
|
3914
|
+
if (t12.isUnaryExpression(node)) {
|
|
3915
|
+
if (node.operator === "!") return `NOT(${expressionToIR(node.argument, paramName)})`;
|
|
3916
|
+
return `${node.operator}${expressionToIR(node.argument, paramName)}`;
|
|
3917
|
+
}
|
|
3918
|
+
if (t12.isConditionalExpression(node)) {
|
|
3919
|
+
return `IF(${expressionToIR(node.test, paramName)}, ${expressionToIR(node.consequent, paramName)}, ${expressionToIR(node.alternate, paramName)})`;
|
|
3920
|
+
}
|
|
3921
|
+
if (t12.isTemplateLiteral(node)) {
|
|
3922
|
+
const parts = [];
|
|
3923
|
+
for (let i = 0; i < node.quasis.length; i++) {
|
|
3924
|
+
parts.push(node.quasis[i].value.raw);
|
|
3925
|
+
if (i < node.expressions.length) {
|
|
3926
|
+
parts.push(`{{ ${expressionToIR(node.expressions[i], paramName)} }}`);
|
|
3927
|
+
}
|
|
3928
|
+
}
|
|
3929
|
+
return `"${parts.join("")}"`;
|
|
3930
|
+
}
|
|
3931
|
+
if (t12.isRegExpLiteral(node)) return node.pattern;
|
|
3932
|
+
return "[expr]";
|
|
3933
|
+
}
|
|
3934
|
+
function extractCallSequence(body, paramName, localFnNames, importedFns) {
|
|
3935
|
+
const calls = [];
|
|
3936
|
+
for (const stmt of body.body) {
|
|
3937
|
+
extractCallsFromStatement(stmt, paramName, localFnNames, importedFns, calls);
|
|
3938
|
+
}
|
|
3939
|
+
return calls;
|
|
3940
|
+
}
|
|
3941
|
+
function extractCallsFromStatement(stmt, paramName, localFnNames, importedFns, calls, condition) {
|
|
3942
|
+
if (t12.isExpressionStatement(stmt)) {
|
|
3943
|
+
const expr = stmt.expression;
|
|
3944
|
+
if (t12.isAwaitExpression(expr)) {
|
|
3945
|
+
const call = extractWorkflowCall(expr.argument, paramName, localFnNames, importedFns);
|
|
3946
|
+
if (call) {
|
|
3947
|
+
if (condition) call.condition = condition;
|
|
3948
|
+
calls.push(call);
|
|
3949
|
+
}
|
|
3950
|
+
}
|
|
3951
|
+
if (t12.isCallExpression(expr) && t12.isIdentifier(expr.callee) && expr.callee.name === "allowTransition") {
|
|
3952
|
+
}
|
|
3953
|
+
}
|
|
3954
|
+
if (t12.isVariableDeclaration(stmt)) {
|
|
3955
|
+
for (const decl of stmt.declarations) {
|
|
3956
|
+
if (decl.init && t12.isAwaitExpression(decl.init)) {
|
|
3957
|
+
const call = extractWorkflowCall(decl.init.argument, paramName, localFnNames, importedFns);
|
|
3958
|
+
if (call) {
|
|
3959
|
+
if (condition) call.condition = condition;
|
|
3960
|
+
calls.push(call);
|
|
3961
|
+
}
|
|
3962
|
+
}
|
|
3963
|
+
}
|
|
3964
|
+
}
|
|
3965
|
+
if (t12.isIfStatement(stmt)) {
|
|
3966
|
+
const condStr = expressionToIR(stmt.test, paramName);
|
|
3967
|
+
if (t12.isBlockStatement(stmt.consequent)) {
|
|
3968
|
+
for (const inner of stmt.consequent.body) {
|
|
3969
|
+
extractCallsFromStatement(inner, paramName, localFnNames, importedFns, calls, condStr);
|
|
3970
|
+
}
|
|
3971
|
+
}
|
|
3972
|
+
if (stmt.alternate) {
|
|
3973
|
+
const negCond = `NOT(${condStr})`;
|
|
3974
|
+
if (t12.isBlockStatement(stmt.alternate)) {
|
|
3975
|
+
for (const inner of stmt.alternate.body) {
|
|
3976
|
+
extractCallsFromStatement(inner, paramName, localFnNames, importedFns, calls, negCond);
|
|
3977
|
+
}
|
|
3978
|
+
} else if (t12.isIfStatement(stmt.alternate)) {
|
|
3979
|
+
extractCallsFromStatement(stmt.alternate, paramName, localFnNames, importedFns, calls);
|
|
3980
|
+
}
|
|
3981
|
+
}
|
|
3982
|
+
}
|
|
3983
|
+
if (t12.isTryStatement(stmt)) {
|
|
3984
|
+
const tryBlockCalls = [];
|
|
3985
|
+
if (stmt.block) {
|
|
3986
|
+
for (const inner of stmt.block.body) {
|
|
3987
|
+
extractCallsFromStatement(inner, paramName, localFnNames, importedFns, tryBlockCalls, condition);
|
|
3988
|
+
}
|
|
3989
|
+
}
|
|
3990
|
+
calls.push(...tryBlockCalls);
|
|
3991
|
+
if (stmt.handler && stmt.handler.body) {
|
|
3992
|
+
const catchBody = stmt.handler.body;
|
|
3993
|
+
const compensationActions = [];
|
|
3994
|
+
const catchParamName = stmt.handler.param && t12.isIdentifier(stmt.handler.param) ? stmt.handler.param.name : "error";
|
|
3995
|
+
const hasReturn = catchBody.body.some((s) => t12.isReturnStatement(s));
|
|
3996
|
+
for (const inner of catchBody.body) {
|
|
3997
|
+
if (t12.isReturnStatement(inner)) continue;
|
|
3998
|
+
extractCallsFromStatement(inner, paramName, localFnNames, importedFns, compensationActions, condition);
|
|
3999
|
+
}
|
|
4000
|
+
calls.push({
|
|
4001
|
+
type: "stateCall",
|
|
4002
|
+
name: `__compensation_${calls.length}`,
|
|
4003
|
+
options: {
|
|
4004
|
+
__isCompensation: true,
|
|
4005
|
+
__tryBlockCallNames: tryBlockCalls.map((c) => c.name),
|
|
4006
|
+
__compensationCalls: compensationActions,
|
|
4007
|
+
__hasReturn: hasReturn,
|
|
4008
|
+
__catchParam: catchParamName,
|
|
4009
|
+
__catchBody: catchBody
|
|
4010
|
+
}
|
|
4011
|
+
});
|
|
4012
|
+
}
|
|
4013
|
+
}
|
|
4014
|
+
if (t12.isSwitchStatement(stmt)) {
|
|
4015
|
+
}
|
|
4016
|
+
}
|
|
4017
|
+
function extractWorkflowCall(node, paramName, localFnNames, importedFns) {
|
|
4018
|
+
if (t12.isCallExpression(node)) {
|
|
4019
|
+
const callee = node.callee;
|
|
4020
|
+
if (t12.isIdentifier(callee) && callee.name === "named" && node.arguments.length >= 2) {
|
|
4021
|
+
const name = t12.isStringLiteral(node.arguments[0]) ? node.arguments[0].value : "";
|
|
4022
|
+
const inner = node.arguments[1];
|
|
4023
|
+
if (t12.isCallExpression(inner) || t12.isAwaitExpression(inner)) {
|
|
4024
|
+
const innerNode = t12.isAwaitExpression(inner) ? inner.argument : inner;
|
|
4025
|
+
const innerCall = extractWorkflowCall(innerNode, paramName, localFnNames, importedFns);
|
|
4026
|
+
if (innerCall) {
|
|
4027
|
+
innerCall.transitionName = name;
|
|
4028
|
+
return innerCall;
|
|
4029
|
+
}
|
|
4030
|
+
}
|
|
4031
|
+
return null;
|
|
4032
|
+
}
|
|
4033
|
+
if (t12.isIdentifier(callee) && callee.name === "userAction") {
|
|
4034
|
+
const name = node.arguments[0] && t12.isStringLiteral(node.arguments[0]) ? node.arguments[0].value : "action";
|
|
4035
|
+
const opts = node.arguments[1] ? extractNodeValue2(node.arguments[1]) : {};
|
|
4036
|
+
return { type: "userAction", name, options: opts };
|
|
4037
|
+
}
|
|
4038
|
+
if (t12.isIdentifier(callee) && callee.name === "userChoice") {
|
|
4039
|
+
const choices = node.arguments[0] ? extractNodeValue2(node.arguments[0]) : {};
|
|
4040
|
+
return { type: "userChoice", name: "choice", choices };
|
|
4041
|
+
}
|
|
4042
|
+
if (t12.isIdentifier(callee) && callee.name === "delay") {
|
|
4043
|
+
const duration = node.arguments[0] && t12.isStringLiteral(node.arguments[0]) ? node.arguments[0].value : "0";
|
|
4044
|
+
return { type: "delay", name: `delay_${duration}` };
|
|
4045
|
+
}
|
|
4046
|
+
if (t12.isIdentifier(callee) && callee.name === "on") {
|
|
4047
|
+
const pattern = node.arguments[0] && t12.isStringLiteral(node.arguments[0]) ? node.arguments[0].value : "*";
|
|
4048
|
+
const opts = node.arguments[1] ? extractNodeValue2(node.arguments[1]) : {};
|
|
4049
|
+
opts.__eventPattern = pattern;
|
|
4050
|
+
return { type: "awaitOn", name: pattern.replace(/[^a-zA-Z0-9]/g, "_"), options: opts };
|
|
4051
|
+
}
|
|
4052
|
+
if (t12.isMemberExpression(callee) && t12.isIdentifier(callee.object) && callee.object.name === "Promise" && t12.isIdentifier(callee.property)) {
|
|
4053
|
+
if (callee.property.name === "all" && node.arguments[0] && t12.isArrayExpression(node.arguments[0])) {
|
|
4054
|
+
const parallelCalls = [];
|
|
4055
|
+
for (const el of node.arguments[0].elements) {
|
|
4056
|
+
if (!el || t12.isSpreadElement(el)) continue;
|
|
4057
|
+
const innerNode = t12.isAwaitExpression(el) ? el.argument : el;
|
|
4058
|
+
const c = extractWorkflowCall(innerNode, paramName, localFnNames, importedFns);
|
|
4059
|
+
if (c) parallelCalls.push(c);
|
|
4060
|
+
}
|
|
4061
|
+
return { type: "promiseAll", name: "parallel", parallelCalls };
|
|
4062
|
+
}
|
|
4063
|
+
if (callee.property.name === "race" && node.arguments[0] && t12.isArrayExpression(node.arguments[0])) {
|
|
4064
|
+
const parallelCalls = [];
|
|
4065
|
+
for (const el of node.arguments[0].elements) {
|
|
4066
|
+
if (!el || t12.isSpreadElement(el)) continue;
|
|
4067
|
+
const innerNode = t12.isAwaitExpression(el) ? el.argument : el;
|
|
4068
|
+
const c = extractWorkflowCall(innerNode, paramName, localFnNames, importedFns);
|
|
4069
|
+
if (c) parallelCalls.push(c);
|
|
4070
|
+
}
|
|
4071
|
+
return { type: "promiseRace", name: "race", parallelCalls };
|
|
4072
|
+
}
|
|
4073
|
+
}
|
|
4074
|
+
if (t12.isIdentifier(callee) && localFnNames.has(callee.name)) {
|
|
4075
|
+
return { type: "stateCall", name: callee.name };
|
|
4076
|
+
}
|
|
4077
|
+
if (t12.isIdentifier(callee) && importedFns.has(callee.name)) {
|
|
4078
|
+
return {
|
|
4079
|
+
type: "serviceCall",
|
|
4080
|
+
name: callee.name,
|
|
4081
|
+
importSource: importedFns.get(callee.name)
|
|
4082
|
+
};
|
|
4083
|
+
}
|
|
4084
|
+
}
|
|
4085
|
+
return null;
|
|
4086
|
+
}
|
|
4087
|
+
function extractAllowTransitions(body) {
|
|
4088
|
+
const result = [];
|
|
4089
|
+
for (const stmt of body.body) {
|
|
4090
|
+
if (!t12.isExpressionStatement(stmt)) continue;
|
|
4091
|
+
const expr = stmt.expression;
|
|
4092
|
+
if (!t12.isCallExpression(expr)) continue;
|
|
4093
|
+
if (!t12.isIdentifier(expr.callee) || expr.callee.name !== "allowTransition") continue;
|
|
4094
|
+
const nameArg = expr.arguments[0];
|
|
4095
|
+
const optsArg = expr.arguments[1];
|
|
4096
|
+
if (!t12.isStringLiteral(nameArg)) continue;
|
|
4097
|
+
const name = nameArg.value;
|
|
4098
|
+
const opts = optsArg && t12.isObjectExpression(optsArg) ? extractNodeValue2(optsArg) : {};
|
|
4099
|
+
let from = [];
|
|
4100
|
+
if (typeof opts.from === "string") from = [opts.from];
|
|
4101
|
+
else if (Array.isArray(opts.from)) from = opts.from.map(String);
|
|
4102
|
+
result.push({
|
|
4103
|
+
name,
|
|
4104
|
+
from,
|
|
4105
|
+
to: String(opts.to || ""),
|
|
4106
|
+
...opts.roles ? { roles: opts.roles } : {},
|
|
4107
|
+
...opts.require ? { require: opts.require } : {},
|
|
4108
|
+
...opts.when ? { when: String(opts.when) } : {}
|
|
4109
|
+
});
|
|
4110
|
+
}
|
|
4111
|
+
return result;
|
|
4112
|
+
}
|
|
4113
|
+
function parseDuration(str) {
|
|
4114
|
+
const match = str.match(/^(\d+(?:\.\d+)?)\s*(ms|s|m|h|d|w)$/);
|
|
4115
|
+
if (!match) return 0;
|
|
4116
|
+
const value = parseFloat(match[1]);
|
|
4117
|
+
switch (match[2]) {
|
|
4118
|
+
case "ms":
|
|
4119
|
+
return value;
|
|
4120
|
+
case "s":
|
|
4121
|
+
return value * 1e3;
|
|
4122
|
+
case "m":
|
|
4123
|
+
return value * 6e4;
|
|
4124
|
+
case "h":
|
|
4125
|
+
return value * 36e5;
|
|
4126
|
+
case "d":
|
|
4127
|
+
return value * 864e5;
|
|
4128
|
+
case "w":
|
|
4129
|
+
return value * 6048e5;
|
|
4130
|
+
default:
|
|
4131
|
+
return 0;
|
|
4132
|
+
}
|
|
4133
|
+
}
|
|
4134
|
+
function toSnakeCase2(name) {
|
|
4135
|
+
return name.replace(/([A-Z])/g, "_$1").toLowerCase().replace(/^_/, "");
|
|
4136
|
+
}
|
|
4137
|
+
function fnNameToSlug(name) {
|
|
4138
|
+
return name.replace(/([A-Z])/g, "-$1").toLowerCase().replace(/^-/, "");
|
|
4139
|
+
}
|
|
4140
|
+
function extractStateDataRefs(expression) {
|
|
4141
|
+
const refs = [];
|
|
4142
|
+
const regex = /state_data\.(\w+)/g;
|
|
4143
|
+
let match;
|
|
4144
|
+
while ((match = regex.exec(expression)) !== null) {
|
|
4145
|
+
refs.push(match[1]);
|
|
4146
|
+
}
|
|
4147
|
+
return [...new Set(refs)];
|
|
4148
|
+
}
|
|
4149
|
+
function detectComputedFieldsFromActions(compilerState, stateFnInfos) {
|
|
4150
|
+
for (const [, info] of stateFnInfos) {
|
|
4151
|
+
for (const action of info.onEnter) {
|
|
4152
|
+
if (action.type !== "set_field") continue;
|
|
4153
|
+
const config = action.config;
|
|
4154
|
+
if (!config?.field || !config?.expression) continue;
|
|
4155
|
+
const targetField = config.field;
|
|
4156
|
+
const expression = config.expression;
|
|
4157
|
+
const refs = extractStateDataRefs(expression);
|
|
4158
|
+
const deps = refs.filter((r) => r !== targetField);
|
|
4159
|
+
if (deps.length === 0) continue;
|
|
4160
|
+
const field = compilerState.fields.find((f) => f.name === targetField);
|
|
4161
|
+
if (field) {
|
|
4162
|
+
field.computed = expression;
|
|
4163
|
+
field.computed_deps = deps;
|
|
4164
|
+
}
|
|
4165
|
+
}
|
|
4166
|
+
}
|
|
4167
|
+
}
|
|
4168
|
+
function detectComputedFieldGetters(path, paramName, paramTypeName, compilerState) {
|
|
4169
|
+
for (const node of path.node.body) {
|
|
4170
|
+
if (!t12.isFunctionDeclaration(node)) continue;
|
|
4171
|
+
if (node.async) continue;
|
|
4172
|
+
if (!node.id) continue;
|
|
4173
|
+
if (node.params.length !== 1) continue;
|
|
4174
|
+
const fnParam = node.params[0];
|
|
4175
|
+
if (!t12.isIdentifier(fnParam)) continue;
|
|
4176
|
+
if (fnParam.typeAnnotation && t12.isTSTypeAnnotation(fnParam.typeAnnotation)) {
|
|
4177
|
+
const typeAnno = fnParam.typeAnnotation.typeAnnotation;
|
|
4178
|
+
if (t12.isTSTypeReference(typeAnno) && t12.isIdentifier(typeAnno.typeName)) {
|
|
4179
|
+
if (typeAnno.typeName.name !== paramTypeName) continue;
|
|
4180
|
+
} else {
|
|
4181
|
+
continue;
|
|
4182
|
+
}
|
|
4183
|
+
} else {
|
|
4184
|
+
continue;
|
|
4185
|
+
}
|
|
4186
|
+
const hasReturnType = node.returnType && t12.isTSTypeAnnotation(node.returnType);
|
|
4187
|
+
if (!node.body || !t12.isBlockStatement(node.body)) continue;
|
|
4188
|
+
const returnStmt = node.body.body.find(
|
|
4189
|
+
(s) => t12.isReturnStatement(s)
|
|
4190
|
+
);
|
|
4191
|
+
if (!returnStmt?.argument) continue;
|
|
4192
|
+
const getterParamName = fnParam.name;
|
|
4193
|
+
const expression = expressionToIR(returnStmt.argument, getterParamName);
|
|
4194
|
+
const deps = extractStateDataRefs(expression);
|
|
4195
|
+
if (deps.length === 0) continue;
|
|
4196
|
+
const fieldName = node.id.name;
|
|
4197
|
+
let field = compilerState.fields.find((f) => f.name === fieldName);
|
|
4198
|
+
if (field) {
|
|
4199
|
+
field.computed = expression;
|
|
4200
|
+
field.computed_deps = deps;
|
|
4201
|
+
} else {
|
|
4202
|
+
let fieldType = "text";
|
|
4203
|
+
if (hasReturnType) {
|
|
4204
|
+
const retType = node.returnType.typeAnnotation;
|
|
4205
|
+
fieldType = resolveType2(retType);
|
|
4206
|
+
}
|
|
4207
|
+
compilerState.fields.push({
|
|
4208
|
+
name: fieldName,
|
|
4209
|
+
type: fieldType,
|
|
4210
|
+
label: fieldName.replace(/([A-Z])/g, " $1").replace(/^./, (c) => c.toUpperCase()),
|
|
4211
|
+
required: false,
|
|
4212
|
+
computed: expression,
|
|
4213
|
+
computed_deps: deps
|
|
4214
|
+
});
|
|
4215
|
+
}
|
|
4216
|
+
}
|
|
4217
|
+
}
|
|
4218
|
+
function extractImperativeWorkflow(path, state) {
|
|
4219
|
+
const compilerState = state;
|
|
4220
|
+
if (!compilerState.actionCounter) compilerState.actionCounter = 0;
|
|
4221
|
+
const actionCounter = { value: compilerState.actionCounter };
|
|
4222
|
+
const importedFns = /* @__PURE__ */ new Map();
|
|
4223
|
+
const stdLibImports = /* @__PURE__ */ new Set();
|
|
4224
|
+
for (const node of path.node.body) {
|
|
4225
|
+
if (t12.isImportDeclaration(node)) {
|
|
4226
|
+
const source = node.source.value;
|
|
4227
|
+
for (const spec of node.specifiers) {
|
|
4228
|
+
const localName = spec.local.name;
|
|
4229
|
+
if (source.includes("@mmapp/react") || source.includes("@mmapp/react")) {
|
|
4230
|
+
stdLibImports.add(localName);
|
|
4231
|
+
} else {
|
|
4232
|
+
importedFns.set(localName, source);
|
|
4233
|
+
}
|
|
4234
|
+
}
|
|
4235
|
+
}
|
|
4236
|
+
}
|
|
4237
|
+
for (const node of path.node.body) {
|
|
4238
|
+
if (t12.isExportDefaultDeclaration(node) && t12.isCallExpression(node.declaration)) {
|
|
4239
|
+
const call = node.declaration;
|
|
4240
|
+
if (t12.isIdentifier(call.callee) && call.callee.name === "workflow") {
|
|
4241
|
+
const slugArg = call.arguments[0] && t12.isStringLiteral(call.arguments[0]) ? call.arguments[0].value : "workflow";
|
|
4242
|
+
let fieldsOrArrow = "";
|
|
4243
|
+
let arrowString;
|
|
4244
|
+
if (call.arguments.length === 2) {
|
|
4245
|
+
const arg1 = call.arguments[1];
|
|
4246
|
+
if (t12.isStringLiteral(arg1)) {
|
|
4247
|
+
fieldsOrArrow = arg1.value;
|
|
4248
|
+
} else if (t12.isTemplateLiteral(arg1)) {
|
|
4249
|
+
fieldsOrArrow = arg1.quasis.map((q) => q.value.raw).join("");
|
|
4250
|
+
} else if (t12.isObjectExpression(arg1)) {
|
|
4251
|
+
fieldsOrArrow = extractNodeValue2(arg1);
|
|
4252
|
+
}
|
|
4253
|
+
} else if (call.arguments.length >= 3) {
|
|
4254
|
+
const arg1 = call.arguments[1];
|
|
4255
|
+
const arg2 = call.arguments[2];
|
|
4256
|
+
if (t12.isObjectExpression(arg1)) {
|
|
4257
|
+
fieldsOrArrow = extractNodeValue2(arg1);
|
|
4258
|
+
}
|
|
4259
|
+
if (t12.isStringLiteral(arg2)) {
|
|
4260
|
+
arrowString = arg2.value;
|
|
4261
|
+
} else if (t12.isTemplateLiteral(arg2)) {
|
|
4262
|
+
arrowString = arg2.quasis.map((q) => q.value.raw).join("");
|
|
4263
|
+
}
|
|
4264
|
+
}
|
|
4265
|
+
const result = parseWorkflowShorthand(slugArg, fieldsOrArrow, arrowString);
|
|
4266
|
+
compilerState.metadata.slug = result.slug;
|
|
4267
|
+
compilerState.metadata.category = "workflow";
|
|
4268
|
+
compilerState.fields.push(...result.fields);
|
|
4269
|
+
for (const s of result.states) {
|
|
4270
|
+
compilerState.states.set(s.name, s);
|
|
4271
|
+
}
|
|
4272
|
+
compilerState.transitions.push(...result.transitions);
|
|
4273
|
+
compilerState.actionCounter = actionCounter.value;
|
|
4274
|
+
return;
|
|
4275
|
+
}
|
|
4276
|
+
}
|
|
4277
|
+
}
|
|
4278
|
+
let parentFn = null;
|
|
4279
|
+
let parentName = "";
|
|
4280
|
+
let paramName = "";
|
|
4281
|
+
let paramTypeName = "";
|
|
4282
|
+
for (const node of path.node.body) {
|
|
4283
|
+
if (t12.isExportDefaultDeclaration(node) && t12.isFunctionDeclaration(node.declaration)) {
|
|
4284
|
+
const fn = node.declaration;
|
|
4285
|
+
if (fn.async && fn.params.length > 0) {
|
|
4286
|
+
parentFn = fn;
|
|
4287
|
+
parentName = fn.id?.name || "workflow";
|
|
4288
|
+
const param = fn.params[0];
|
|
4289
|
+
if (t12.isIdentifier(param)) {
|
|
4290
|
+
paramName = param.name;
|
|
4291
|
+
if (param.typeAnnotation && t12.isTSTypeAnnotation(param.typeAnnotation)) {
|
|
4292
|
+
const typeAnno = param.typeAnnotation.typeAnnotation;
|
|
4293
|
+
if (t12.isTSTypeReference(typeAnno) && t12.isIdentifier(typeAnno.typeName)) {
|
|
4294
|
+
paramTypeName = typeAnno.typeName.name;
|
|
4295
|
+
}
|
|
4296
|
+
}
|
|
4297
|
+
}
|
|
4298
|
+
}
|
|
4299
|
+
}
|
|
4300
|
+
}
|
|
4301
|
+
if (!parentFn || !paramName) return;
|
|
4302
|
+
const slug = fnNameToSlug(parentName.replace(/Workflow$/, ""));
|
|
4303
|
+
compilerState.metadata.slug = slug;
|
|
4304
|
+
compilerState.metadata.category = "workflow";
|
|
4305
|
+
for (const node of path.node.body) {
|
|
4306
|
+
if (t12.isTSInterfaceDeclaration(node) && node.id.name === paramTypeName) {
|
|
4307
|
+
const fields = extractFieldsFromInterface2(node);
|
|
4308
|
+
compilerState.fields.push(...fields);
|
|
4309
|
+
compilerState.metadata.name = paramTypeName;
|
|
4310
|
+
}
|
|
4311
|
+
if (t12.isExportNamedDeclaration(node) && t12.isTSInterfaceDeclaration(node.declaration) && node.declaration.id.name === paramTypeName) {
|
|
4312
|
+
const fields = extractFieldsFromInterface2(node.declaration);
|
|
4313
|
+
compilerState.fields.push(...fields);
|
|
4314
|
+
compilerState.metadata.name = paramTypeName;
|
|
4315
|
+
}
|
|
4316
|
+
}
|
|
4317
|
+
const localFns = /* @__PURE__ */ new Map();
|
|
4318
|
+
const localFnNames = /* @__PURE__ */ new Set();
|
|
4319
|
+
for (const node of path.node.body) {
|
|
4320
|
+
if (t12.isFunctionDeclaration(node) && node.async && node.id) {
|
|
4321
|
+
if (node.id.name !== parentName) {
|
|
4322
|
+
localFns.set(node.id.name, node);
|
|
4323
|
+
localFnNames.add(node.id.name);
|
|
4324
|
+
}
|
|
4325
|
+
}
|
|
4326
|
+
if (t12.isExportNamedDeclaration(node) && t12.isFunctionDeclaration(node.declaration) && node.declaration.async && node.declaration.id) {
|
|
4327
|
+
if (node.declaration.id.name !== parentName) {
|
|
4328
|
+
localFns.set(node.declaration.id.name, node.declaration);
|
|
4329
|
+
localFnNames.add(node.declaration.id.name);
|
|
4330
|
+
}
|
|
4331
|
+
}
|
|
4332
|
+
}
|
|
4333
|
+
for (const node of path.node.body) {
|
|
4334
|
+
if (t12.isExportNamedDeclaration(node) && t12.isVariableDeclaration(node.declaration)) {
|
|
4335
|
+
for (const decl of node.declaration.declarations) {
|
|
4336
|
+
if (t12.isIdentifier(decl.id) && decl.id.name === "defaults" && t12.isObjectExpression(decl.init)) {
|
|
4337
|
+
const defaults = extractNodeValue2(decl.init);
|
|
4338
|
+
for (const [name, value] of Object.entries(defaults)) {
|
|
4339
|
+
const field = compilerState.fields.find((f) => f.name === name);
|
|
4340
|
+
if (field && value !== void 0) {
|
|
4341
|
+
field.default_value = value;
|
|
4342
|
+
}
|
|
4343
|
+
}
|
|
4344
|
+
}
|
|
4345
|
+
}
|
|
4346
|
+
}
|
|
4347
|
+
}
|
|
4348
|
+
const stateFnInfos = /* @__PURE__ */ new Map();
|
|
4349
|
+
for (const [name, fn] of localFns) {
|
|
4350
|
+
const fnParamName = fn.params[0] && t12.isIdentifier(fn.params[0]) ? fn.params[0].name : paramName;
|
|
4351
|
+
const analysis = analyzeStateFn(fn, fnParamName, actionCounter);
|
|
4352
|
+
stateFnInfos.set(name, {
|
|
4353
|
+
name,
|
|
4354
|
+
node: fn,
|
|
4355
|
+
params: fn.params.map((p) => t12.isIdentifier(p) ? p.name : ""),
|
|
4356
|
+
...analysis
|
|
4357
|
+
});
|
|
4358
|
+
}
|
|
4359
|
+
detectComputedFieldsFromActions(compilerState, stateFnInfos);
|
|
4360
|
+
detectComputedFieldGetters(path, paramName, paramTypeName, compilerState);
|
|
4361
|
+
const callSequence = extractCallSequence(
|
|
4362
|
+
parentFn.body,
|
|
4363
|
+
paramName,
|
|
4364
|
+
localFnNames,
|
|
4365
|
+
importedFns
|
|
4366
|
+
);
|
|
4367
|
+
const allowTransitions = extractAllowTransitions(parentFn.body);
|
|
4368
|
+
const referencedStates = /* @__PURE__ */ new Set();
|
|
4369
|
+
let firstStateName = "";
|
|
4370
|
+
let prevStateName = "";
|
|
4371
|
+
let transitionIndex = 0;
|
|
4372
|
+
for (const call of callSequence) {
|
|
4373
|
+
const stateName = toSnakeCase2(call.name);
|
|
4374
|
+
switch (call.type) {
|
|
4375
|
+
case "stateCall": {
|
|
4376
|
+
if (call.name.startsWith("__compensation_") && call.options?.__isCompensation) {
|
|
4377
|
+
const compOpts = call.options;
|
|
4378
|
+
const tryCallNames = compOpts.__tryBlockCallNames || [];
|
|
4379
|
+
const compensationCalls = compOpts.__compensationCalls || [];
|
|
4380
|
+
const hasReturn = compOpts.__hasReturn;
|
|
4381
|
+
const catchBody = compOpts.__catchBody;
|
|
4382
|
+
const compIndex = ++transitionIndex;
|
|
4383
|
+
const compStateName = `compensation_${compIndex}`;
|
|
4384
|
+
const compActions = [];
|
|
4385
|
+
if (catchBody) {
|
|
4386
|
+
for (const innerStmt of catchBody.body) {
|
|
4387
|
+
if (t12.isReturnStatement(innerStmt)) continue;
|
|
4388
|
+
if (t12.isExpressionStatement(innerStmt)) {
|
|
4389
|
+
const innerExpr = innerStmt.expression;
|
|
4390
|
+
if (t12.isAssignmentExpression(innerExpr) && t12.isMemberExpression(innerExpr.left)) {
|
|
4391
|
+
const left = memberExprToString(innerExpr.left);
|
|
4392
|
+
if (left.startsWith(`${paramName}.`)) {
|
|
4393
|
+
const field = left.slice(paramName.length + 1);
|
|
4394
|
+
const valueExpr = expressionToIR(innerExpr.right, paramName);
|
|
4395
|
+
compActions.push({
|
|
4396
|
+
id: `auto_${++actionCounter.value}`,
|
|
4397
|
+
type: "set_field",
|
|
4398
|
+
mode: "auto",
|
|
4399
|
+
config: { field, expression: valueExpr }
|
|
4400
|
+
});
|
|
4401
|
+
}
|
|
4402
|
+
}
|
|
4403
|
+
if (t12.isAwaitExpression(innerExpr) && t12.isCallExpression(innerExpr.argument)) {
|
|
4404
|
+
const innerCall = innerExpr.argument;
|
|
4405
|
+
const fnName = t12.isIdentifier(innerCall.callee) ? innerCall.callee.name : null;
|
|
4406
|
+
if (fnName && importedFns.has(fnName)) {
|
|
4407
|
+
compActions.push({
|
|
4408
|
+
id: `auto_${++actionCounter.value}`,
|
|
4409
|
+
type: "call_workflow",
|
|
4410
|
+
mode: "auto",
|
|
4411
|
+
config: { definition_slug: fnNameToSlug(fnName), blocking: true }
|
|
4412
|
+
});
|
|
4413
|
+
}
|
|
4414
|
+
if (fnName === "log") {
|
|
4415
|
+
const event = innerCall.arguments[0] ? extractNodeValue2(innerCall.arguments[0]) : "";
|
|
4416
|
+
compActions.push({
|
|
4417
|
+
id: `auto_${++actionCounter.value}`,
|
|
4418
|
+
type: "log_event",
|
|
4419
|
+
mode: "auto",
|
|
4420
|
+
config: { event: String(event) }
|
|
4421
|
+
});
|
|
4422
|
+
}
|
|
4423
|
+
if (fnName === "notify") {
|
|
4424
|
+
const to = innerCall.arguments[0] ? expressionToIR(innerCall.arguments[0], paramName) : "";
|
|
4425
|
+
const message = innerCall.arguments[1] ? extractNodeValue2(innerCall.arguments[1]) : "";
|
|
4426
|
+
compActions.push({
|
|
4427
|
+
id: `auto_${++actionCounter.value}`,
|
|
4428
|
+
type: "send_notification",
|
|
4429
|
+
mode: "auto",
|
|
4430
|
+
config: { to: String(to), message: String(message) }
|
|
4431
|
+
});
|
|
4432
|
+
}
|
|
4433
|
+
if (fnName === "emit") {
|
|
4434
|
+
const event = innerCall.arguments[0] ? extractNodeValue2(innerCall.arguments[0]) : "";
|
|
4435
|
+
compActions.push({
|
|
4436
|
+
id: `auto_${++actionCounter.value}`,
|
|
4437
|
+
type: "emit_event",
|
|
4438
|
+
mode: "auto",
|
|
4439
|
+
config: { event: String(event) }
|
|
4440
|
+
});
|
|
4441
|
+
}
|
|
4442
|
+
}
|
|
4443
|
+
if (t12.isCallExpression(innerExpr)) {
|
|
4444
|
+
const fnName = t12.isIdentifier(innerExpr.callee) ? innerExpr.callee.name : null;
|
|
4445
|
+
if (fnName === "log") {
|
|
4446
|
+
const event = innerExpr.arguments[0] ? extractNodeValue2(innerExpr.arguments[0]) : "";
|
|
4447
|
+
compActions.push({
|
|
4448
|
+
id: `auto_${++actionCounter.value}`,
|
|
4449
|
+
type: "log_event",
|
|
4450
|
+
mode: "auto",
|
|
4451
|
+
config: { event: String(event) }
|
|
4452
|
+
});
|
|
4453
|
+
}
|
|
4454
|
+
if (fnName === "notify") {
|
|
4455
|
+
const to = innerExpr.arguments[0] ? expressionToIR(innerExpr.arguments[0], paramName) : "";
|
|
4456
|
+
const message = innerExpr.arguments[1] ? extractNodeValue2(innerExpr.arguments[1]) : "";
|
|
4457
|
+
compActions.push({
|
|
4458
|
+
id: `auto_${++actionCounter.value}`,
|
|
4459
|
+
type: "send_notification",
|
|
4460
|
+
mode: "auto",
|
|
4461
|
+
config: { to: String(to), message: String(message) }
|
|
4462
|
+
});
|
|
4463
|
+
}
|
|
4464
|
+
if (fnName === "emit") {
|
|
4465
|
+
const event = innerExpr.arguments[0] ? extractNodeValue2(innerExpr.arguments[0]) : "";
|
|
4466
|
+
compActions.push({
|
|
4467
|
+
id: `auto_${++actionCounter.value}`,
|
|
4468
|
+
type: "emit_event",
|
|
4469
|
+
mode: "auto",
|
|
4470
|
+
config: { event: String(event) }
|
|
4471
|
+
});
|
|
4472
|
+
}
|
|
4473
|
+
}
|
|
4474
|
+
}
|
|
4475
|
+
if (t12.isIfStatement(innerStmt) && t12.isBlockStatement(innerStmt.consequent)) {
|
|
4476
|
+
const condStr = expressionToIR(innerStmt.test, paramName);
|
|
4477
|
+
for (const ifInner of innerStmt.consequent.body) {
|
|
4478
|
+
if (t12.isExpressionStatement(ifInner)) {
|
|
4479
|
+
const ifExpr = ifInner.expression;
|
|
4480
|
+
if (t12.isAssignmentExpression(ifExpr) && t12.isMemberExpression(ifExpr.left)) {
|
|
4481
|
+
const left = memberExprToString(ifExpr.left);
|
|
4482
|
+
if (left.startsWith(`${paramName}.`)) {
|
|
4483
|
+
const field = left.slice(paramName.length + 1);
|
|
4484
|
+
const valueExpr = expressionToIR(ifExpr.right, paramName);
|
|
4485
|
+
compActions.push({
|
|
4486
|
+
id: `auto_${++actionCounter.value}`,
|
|
4487
|
+
type: "set_field",
|
|
4488
|
+
mode: "auto",
|
|
4489
|
+
config: { field, expression: valueExpr },
|
|
4490
|
+
condition: condStr
|
|
4491
|
+
});
|
|
4492
|
+
}
|
|
4493
|
+
}
|
|
4494
|
+
if (t12.isAwaitExpression(ifExpr) && t12.isCallExpression(ifExpr.argument)) {
|
|
4495
|
+
const ifCall = ifExpr.argument;
|
|
4496
|
+
const fnName = t12.isIdentifier(ifCall.callee) ? ifCall.callee.name : null;
|
|
4497
|
+
if (fnName && importedFns.has(fnName)) {
|
|
4498
|
+
compActions.push({
|
|
4499
|
+
id: `auto_${++actionCounter.value}`,
|
|
4500
|
+
type: "call_workflow",
|
|
4501
|
+
mode: "auto",
|
|
4502
|
+
config: { definition_slug: fnNameToSlug(fnName), blocking: true },
|
|
4503
|
+
condition: condStr
|
|
4504
|
+
});
|
|
4505
|
+
}
|
|
4506
|
+
}
|
|
4507
|
+
}
|
|
4508
|
+
}
|
|
4509
|
+
}
|
|
4510
|
+
}
|
|
4511
|
+
}
|
|
4512
|
+
for (const cc of compensationCalls) {
|
|
4513
|
+
if (cc.type === "serviceCall") {
|
|
4514
|
+
compActions.push({
|
|
4515
|
+
id: `auto_${++actionCounter.value}`,
|
|
4516
|
+
type: "call_workflow",
|
|
4517
|
+
mode: "auto",
|
|
4518
|
+
config: { definition_slug: fnNameToSlug(cc.name), blocking: true }
|
|
4519
|
+
});
|
|
4520
|
+
}
|
|
4521
|
+
}
|
|
4522
|
+
compilerState.states.set(compStateName, {
|
|
4523
|
+
name: compStateName,
|
|
4524
|
+
type: hasReturn ? "END" : "REGULAR",
|
|
4525
|
+
on_enter: compActions,
|
|
4526
|
+
during: [],
|
|
4527
|
+
on_exit: []
|
|
4528
|
+
});
|
|
4529
|
+
for (const tryCallName of tryCallNames) {
|
|
4530
|
+
let tryStateName;
|
|
4531
|
+
if (localFnNames.has(tryCallName)) {
|
|
4532
|
+
tryStateName = toSnakeCase2(tryCallName);
|
|
4533
|
+
} else if (importedFns.has(tryCallName)) {
|
|
4534
|
+
tryStateName = `awaiting_${toSnakeCase2(tryCallName)}`;
|
|
4535
|
+
} else {
|
|
4536
|
+
tryStateName = toSnakeCase2(tryCallName);
|
|
4537
|
+
}
|
|
4538
|
+
if (compilerState.states.has(tryStateName)) {
|
|
4539
|
+
compilerState.transitions.push({
|
|
4540
|
+
name: `error_to_${compStateName}`,
|
|
4541
|
+
from: [tryStateName],
|
|
4542
|
+
to: compStateName,
|
|
4543
|
+
conditions: [{ expression: "error != null" }],
|
|
4544
|
+
actions: [],
|
|
4545
|
+
auto: true
|
|
4546
|
+
});
|
|
4547
|
+
}
|
|
4548
|
+
}
|
|
4549
|
+
if (!hasReturn) {
|
|
4550
|
+
prevStateName = compStateName;
|
|
4551
|
+
}
|
|
4552
|
+
break;
|
|
4553
|
+
}
|
|
4554
|
+
referencedStates.add(call.name);
|
|
4555
|
+
if (!firstStateName) firstStateName = stateName;
|
|
4556
|
+
const info = stateFnInfos.get(call.name);
|
|
4557
|
+
if (info && !compilerState.states.has(stateName)) {
|
|
4558
|
+
compilerState.states.set(stateName, {
|
|
4559
|
+
name: stateName,
|
|
4560
|
+
type: !firstStateName || stateName === toSnakeCase2(callSequence[0]?.name || "") ? "START" : "REGULAR",
|
|
4561
|
+
on_enter: info.onEnter,
|
|
4562
|
+
during: info.during,
|
|
4563
|
+
on_exit: [],
|
|
4564
|
+
...info.onEvent.length > 0 ? { on_event: info.onEvent } : {},
|
|
4565
|
+
...info.timeout ? { timeout: info.timeout } : {},
|
|
4566
|
+
...info.runtime ? { runtime: info.runtime } : {}
|
|
4567
|
+
});
|
|
4568
|
+
} else if (!compilerState.states.has(stateName)) {
|
|
4569
|
+
compilerState.states.set(stateName, {
|
|
4570
|
+
name: stateName,
|
|
4571
|
+
type: "REGULAR",
|
|
4572
|
+
on_enter: [],
|
|
4573
|
+
during: [],
|
|
4574
|
+
on_exit: []
|
|
4575
|
+
});
|
|
4576
|
+
}
|
|
4577
|
+
if (prevStateName && prevStateName !== stateName) {
|
|
4578
|
+
const transName = call.transitionName || `to_${stateName}`;
|
|
4579
|
+
const conditions = [];
|
|
4580
|
+
if (call.condition) {
|
|
4581
|
+
conditions.push({ expression: call.condition });
|
|
4582
|
+
}
|
|
4583
|
+
if (info?.roles.length) {
|
|
4584
|
+
for (const role of info.roles) {
|
|
4585
|
+
conditions.push(roleCondition(role));
|
|
4586
|
+
}
|
|
4587
|
+
}
|
|
4588
|
+
compilerState.transitions.push({
|
|
4589
|
+
name: transName,
|
|
4590
|
+
from: [prevStateName],
|
|
4591
|
+
to: stateName,
|
|
4592
|
+
conditions: conditions.length > 0 ? conditions : void 0,
|
|
4593
|
+
actions: [],
|
|
4594
|
+
...info?.requiredFields.length ? { required_fields: info.requiredFields } : {},
|
|
4595
|
+
auto: true
|
|
4596
|
+
});
|
|
4597
|
+
}
|
|
4598
|
+
prevStateName = stateName;
|
|
4599
|
+
break;
|
|
4600
|
+
}
|
|
4601
|
+
case "userAction": {
|
|
4602
|
+
const awaitState = `awaiting_${call.name}`;
|
|
4603
|
+
if (!compilerState.states.has(awaitState)) {
|
|
4604
|
+
compilerState.states.set(awaitState, {
|
|
4605
|
+
name: awaitState,
|
|
4606
|
+
type: "REGULAR",
|
|
4607
|
+
on_enter: [],
|
|
4608
|
+
during: [],
|
|
4609
|
+
on_exit: []
|
|
4610
|
+
});
|
|
4611
|
+
}
|
|
4612
|
+
if (prevStateName) {
|
|
4613
|
+
compilerState.transitions.push({
|
|
4614
|
+
name: `to_${awaitState}`,
|
|
4615
|
+
from: [prevStateName],
|
|
4616
|
+
to: awaitState,
|
|
4617
|
+
actions: [],
|
|
4618
|
+
auto: true,
|
|
4619
|
+
...call.condition ? { conditions: [{ expression: call.condition }] } : {}
|
|
4620
|
+
});
|
|
4621
|
+
}
|
|
4622
|
+
const opts = call.options || {};
|
|
4623
|
+
const conditions = [];
|
|
4624
|
+
if (opts.roles && Array.isArray(opts.roles)) {
|
|
4625
|
+
for (const role of opts.roles) {
|
|
4626
|
+
conditions.push(roleCondition(role));
|
|
4627
|
+
}
|
|
4628
|
+
}
|
|
4629
|
+
if (opts.when && typeof opts.when === "string") {
|
|
4630
|
+
conditions.push({ expression: opts.when });
|
|
4631
|
+
}
|
|
4632
|
+
compilerState.transitions.push({
|
|
4633
|
+
name: call.name,
|
|
4634
|
+
from: [awaitState],
|
|
4635
|
+
to: "",
|
|
4636
|
+
// Will be resolved later (next state in sequence)
|
|
4637
|
+
conditions: conditions.length > 0 ? conditions : void 0,
|
|
4638
|
+
actions: [],
|
|
4639
|
+
...opts.require ? { required_fields: opts.require } : {}
|
|
4640
|
+
});
|
|
4641
|
+
prevStateName = awaitState;
|
|
4642
|
+
break;
|
|
4643
|
+
}
|
|
4644
|
+
case "userChoice": {
|
|
4645
|
+
const choiceState = prevStateName || "choice";
|
|
4646
|
+
if (call.choices) {
|
|
4647
|
+
for (const [optionName, optionConfig] of Object.entries(call.choices)) {
|
|
4648
|
+
const config = optionConfig;
|
|
4649
|
+
const conditions = [];
|
|
4650
|
+
if (config.roles && Array.isArray(config.roles)) {
|
|
4651
|
+
for (const role of config.roles) {
|
|
4652
|
+
conditions.push(roleCondition(role));
|
|
4653
|
+
}
|
|
4654
|
+
}
|
|
4655
|
+
if (config.when && typeof config.when === "string") {
|
|
4656
|
+
conditions.push({ expression: config.when });
|
|
4657
|
+
}
|
|
4658
|
+
compilerState.transitions.push({
|
|
4659
|
+
name: optionName,
|
|
4660
|
+
from: [choiceState],
|
|
4661
|
+
to: "",
|
|
4662
|
+
// Resolved by switch/case handling
|
|
4663
|
+
conditions: conditions.length > 0 ? conditions : void 0,
|
|
4664
|
+
actions: [],
|
|
4665
|
+
...config.require ? { required_fields: config.require } : {}
|
|
4666
|
+
});
|
|
4667
|
+
}
|
|
4668
|
+
}
|
|
4669
|
+
break;
|
|
4670
|
+
}
|
|
4671
|
+
case "serviceCall": {
|
|
4672
|
+
const serviceSlug = fnNameToSlug(call.name);
|
|
4673
|
+
const serviceState = `awaiting_${toSnakeCase2(call.name)}`;
|
|
4674
|
+
compilerState.states.set(serviceState, {
|
|
4675
|
+
name: serviceState,
|
|
4676
|
+
type: "REGULAR",
|
|
4677
|
+
on_enter: [{
|
|
4678
|
+
id: `auto_${++actionCounter.value}`,
|
|
4679
|
+
type: "call_workflow",
|
|
4680
|
+
mode: "auto",
|
|
4681
|
+
config: {
|
|
4682
|
+
definition_slug: serviceSlug,
|
|
4683
|
+
blocking: true
|
|
4684
|
+
}
|
|
4685
|
+
}],
|
|
4686
|
+
during: [],
|
|
4687
|
+
on_exit: []
|
|
4688
|
+
});
|
|
4689
|
+
if (prevStateName) {
|
|
4690
|
+
compilerState.transitions.push({
|
|
4691
|
+
name: `call_${toSnakeCase2(call.name)}`,
|
|
4692
|
+
from: [prevStateName],
|
|
4693
|
+
to: serviceState,
|
|
4694
|
+
actions: [],
|
|
4695
|
+
auto: true,
|
|
4696
|
+
...call.condition ? { conditions: [{ expression: call.condition }] } : {}
|
|
4697
|
+
});
|
|
4698
|
+
}
|
|
4699
|
+
prevStateName = serviceState;
|
|
4700
|
+
break;
|
|
4701
|
+
}
|
|
4702
|
+
case "awaitOn": {
|
|
4703
|
+
const eventState = `awaiting_${call.name}`;
|
|
4704
|
+
const opts = call.options || {};
|
|
4705
|
+
const eventPattern = opts.__eventPattern ? String(opts.__eventPattern) : call.name.replace(/_/g, ":");
|
|
4706
|
+
const awaitOnMetadata = {
|
|
4707
|
+
event_pattern: eventPattern
|
|
4708
|
+
};
|
|
4709
|
+
if (opts.when && typeof opts.when === "string") {
|
|
4710
|
+
awaitOnMetadata.event_condition = String(opts.when);
|
|
4711
|
+
}
|
|
4712
|
+
if (opts.timeout) {
|
|
4713
|
+
awaitOnMetadata.event_timeout = String(opts.timeout);
|
|
4714
|
+
}
|
|
4715
|
+
const awaitState = {
|
|
4716
|
+
name: eventState,
|
|
4717
|
+
type: "REGULAR",
|
|
4718
|
+
on_enter: [],
|
|
4719
|
+
during: [],
|
|
4720
|
+
on_exit: [],
|
|
4721
|
+
...opts.timeout ? { timeout: { duration: String(opts.timeout) } } : {}
|
|
4722
|
+
};
|
|
4723
|
+
if (awaitOnMetadata) awaitState.metadata = awaitOnMetadata;
|
|
4724
|
+
compilerState.states.set(eventState, awaitState);
|
|
4725
|
+
if (prevStateName) {
|
|
4726
|
+
compilerState.transitions.push({
|
|
4727
|
+
name: `await_${call.name}`,
|
|
4728
|
+
from: [prevStateName],
|
|
4729
|
+
to: eventState,
|
|
4730
|
+
actions: [],
|
|
4731
|
+
auto: true,
|
|
4732
|
+
...call.condition ? { conditions: [{ expression: call.condition }] } : {}
|
|
4733
|
+
});
|
|
4734
|
+
}
|
|
4735
|
+
const eventConditions = [];
|
|
4736
|
+
if (opts.when && typeof opts.when === "string") {
|
|
4737
|
+
eventConditions.push({ expression: String(opts.when) });
|
|
4738
|
+
}
|
|
4739
|
+
compilerState.transitions.push({
|
|
4740
|
+
name: `${call.name}_matched`,
|
|
4741
|
+
from: [eventState],
|
|
4742
|
+
to: "",
|
|
4743
|
+
// Resolved to next state
|
|
4744
|
+
conditions: eventConditions.length > 0 ? eventConditions : void 0,
|
|
4745
|
+
actions: [],
|
|
4746
|
+
auto: true
|
|
4747
|
+
});
|
|
4748
|
+
prevStateName = eventState;
|
|
4749
|
+
break;
|
|
4750
|
+
}
|
|
4751
|
+
case "promiseAll": {
|
|
4752
|
+
const parallelState = `parallel_${++transitionIndex}`;
|
|
4753
|
+
const parallelActions = [];
|
|
4754
|
+
for (const pc of call.parallelCalls || []) {
|
|
4755
|
+
if (pc.type === "serviceCall") {
|
|
4756
|
+
parallelActions.push({
|
|
4757
|
+
id: `auto_${++actionCounter.value}`,
|
|
4758
|
+
type: "call_workflow",
|
|
4759
|
+
mode: "auto",
|
|
4760
|
+
config: {
|
|
4761
|
+
definition_slug: fnNameToSlug(pc.name),
|
|
4762
|
+
blocking: true
|
|
4763
|
+
}
|
|
4764
|
+
});
|
|
4765
|
+
}
|
|
4766
|
+
}
|
|
4767
|
+
compilerState.states.set(parallelState, {
|
|
4768
|
+
name: parallelState,
|
|
4769
|
+
type: "REGULAR",
|
|
4770
|
+
on_enter: parallelActions,
|
|
4771
|
+
during: [],
|
|
4772
|
+
on_exit: []
|
|
4773
|
+
});
|
|
4774
|
+
if (prevStateName) {
|
|
4775
|
+
compilerState.transitions.push({
|
|
4776
|
+
name: `to_${parallelState}`,
|
|
4777
|
+
from: [prevStateName],
|
|
4778
|
+
to: parallelState,
|
|
4779
|
+
actions: [],
|
|
4780
|
+
auto: true
|
|
4781
|
+
});
|
|
4782
|
+
}
|
|
4783
|
+
prevStateName = parallelState;
|
|
4784
|
+
break;
|
|
4785
|
+
}
|
|
4786
|
+
case "delay": {
|
|
4787
|
+
const delayState = `delay_${++transitionIndex}`;
|
|
4788
|
+
const durationMatch = call.name.match(/delay_(.+)/);
|
|
4789
|
+
const duration = durationMatch ? durationMatch[1] : "0";
|
|
4790
|
+
compilerState.states.set(delayState, {
|
|
4791
|
+
name: delayState,
|
|
4792
|
+
type: "REGULAR",
|
|
4793
|
+
on_enter: [],
|
|
4794
|
+
during: [],
|
|
4795
|
+
on_exit: [],
|
|
4796
|
+
timeout: { duration, fallback: {} }
|
|
4797
|
+
});
|
|
4798
|
+
if (prevStateName) {
|
|
4799
|
+
compilerState.transitions.push({
|
|
4800
|
+
name: `to_${delayState}`,
|
|
4801
|
+
from: [prevStateName],
|
|
4802
|
+
to: delayState,
|
|
4803
|
+
actions: [],
|
|
4804
|
+
auto: true
|
|
4805
|
+
});
|
|
4806
|
+
}
|
|
4807
|
+
prevStateName = delayState;
|
|
4808
|
+
break;
|
|
4809
|
+
}
|
|
4810
|
+
}
|
|
4811
|
+
}
|
|
4812
|
+
if (prevStateName && compilerState.states.has(prevStateName)) {
|
|
4813
|
+
const lastState = compilerState.states.get(prevStateName);
|
|
4814
|
+
const hasOutgoing = compilerState.transitions.some((t22) => t22.from.includes(prevStateName));
|
|
4815
|
+
if (!hasOutgoing) {
|
|
4816
|
+
lastState.type = "END";
|
|
4817
|
+
}
|
|
4818
|
+
}
|
|
4819
|
+
if (firstStateName && compilerState.states.has(firstStateName)) {
|
|
4820
|
+
compilerState.states.get(firstStateName).type = "START";
|
|
4821
|
+
}
|
|
4822
|
+
for (let i = 0; i < compilerState.transitions.length; i++) {
|
|
4823
|
+
const trans = compilerState.transitions[i];
|
|
4824
|
+
if (trans.to === "" && i + 1 < compilerState.transitions.length) {
|
|
4825
|
+
const nextTrans = compilerState.transitions[i + 1];
|
|
4826
|
+
if (nextTrans.to) {
|
|
4827
|
+
trans.to = nextTrans.to;
|
|
4828
|
+
} else if (nextTrans.from.length > 0) {
|
|
4829
|
+
}
|
|
4830
|
+
}
|
|
4831
|
+
}
|
|
4832
|
+
const stateSequence = callSequence.filter((c) => c.type === "stateCall" || c.type === "serviceCall" || c.type === "userAction" || c.type === "awaitOn").map((c) => {
|
|
4833
|
+
if (c.type === "stateCall") return toSnakeCase2(c.name);
|
|
4834
|
+
if (c.type === "userAction") return `awaiting_${c.name}`;
|
|
4835
|
+
if (c.type === "serviceCall") return `awaiting_${toSnakeCase2(c.name)}`;
|
|
4836
|
+
if (c.type === "awaitOn") return `awaiting_${c.name}`;
|
|
4837
|
+
return c.name;
|
|
4838
|
+
});
|
|
4839
|
+
for (const trans of compilerState.transitions) {
|
|
4840
|
+
if (trans.to === "") {
|
|
4841
|
+
const fromState = trans.from[0];
|
|
4842
|
+
const idx = stateSequence.indexOf(fromState);
|
|
4843
|
+
if (idx >= 0 && idx + 1 < stateSequence.length) {
|
|
4844
|
+
trans.to = stateSequence[idx + 1];
|
|
4845
|
+
}
|
|
4846
|
+
}
|
|
4847
|
+
}
|
|
4848
|
+
for (const at of allowTransitions) {
|
|
4849
|
+
const resolvedTo = at.to === "$self" ? "__self__" : toSnakeCase2(at.to);
|
|
4850
|
+
const resolvedFrom = at.from.map((f) => toSnakeCase2(f));
|
|
4851
|
+
const conditions = [];
|
|
4852
|
+
if (at.roles) {
|
|
4853
|
+
for (const role of at.roles) {
|
|
4854
|
+
conditions.push(roleCondition(role));
|
|
4855
|
+
}
|
|
4856
|
+
}
|
|
4857
|
+
if (at.when) {
|
|
4858
|
+
conditions.push({ expression: at.when });
|
|
4859
|
+
}
|
|
4860
|
+
if (resolvedTo !== "__self__" && !compilerState.states.has(resolvedTo)) {
|
|
4861
|
+
compilerState.states.set(resolvedTo, {
|
|
4862
|
+
name: resolvedTo,
|
|
4863
|
+
type: "REGULAR",
|
|
4864
|
+
on_enter: [],
|
|
4865
|
+
during: [],
|
|
4866
|
+
on_exit: []
|
|
4867
|
+
});
|
|
4868
|
+
}
|
|
4869
|
+
if (resolvedTo === "__self__") {
|
|
4870
|
+
for (const from of resolvedFrom) {
|
|
4871
|
+
compilerState.transitions.push({
|
|
4872
|
+
name: at.name,
|
|
4873
|
+
from: [from],
|
|
4874
|
+
to: from,
|
|
4875
|
+
conditions: conditions.length > 0 ? conditions : void 0,
|
|
4876
|
+
actions: [],
|
|
4877
|
+
...at.require ? { required_fields: at.require } : {}
|
|
4878
|
+
});
|
|
4879
|
+
}
|
|
4880
|
+
} else {
|
|
4881
|
+
compilerState.transitions.push({
|
|
4882
|
+
name: at.name,
|
|
4883
|
+
from: resolvedFrom,
|
|
4884
|
+
to: resolvedTo,
|
|
4885
|
+
conditions: conditions.length > 0 ? conditions : void 0,
|
|
4886
|
+
actions: [],
|
|
4887
|
+
...at.require ? { required_fields: at.require } : {}
|
|
4888
|
+
});
|
|
4889
|
+
}
|
|
4890
|
+
}
|
|
4891
|
+
for (const [, info] of stateFnInfos) {
|
|
4892
|
+
for (const v of info.validations) {
|
|
4893
|
+
if (v.field === "__cross__") continue;
|
|
4894
|
+
const field = compilerState.fields.find((f) => f.name === v.field);
|
|
4895
|
+
if (field) {
|
|
4896
|
+
if (!field.validation) field.validation = {};
|
|
4897
|
+
Object.assign(field.validation, v.validation);
|
|
4898
|
+
if (v.validation.rules) {
|
|
4899
|
+
if (!field.validation.rules) field.validation.rules = [];
|
|
4900
|
+
field.validation.rules.push(...v.validation.rules);
|
|
4901
|
+
}
|
|
4902
|
+
}
|
|
4903
|
+
}
|
|
4904
|
+
}
|
|
4905
|
+
for (const node of path.node.body) {
|
|
4906
|
+
if (t12.isExportNamedDeclaration(node) && t12.isVariableDeclaration(node.declaration)) {
|
|
4907
|
+
for (const decl of node.declaration.declarations) {
|
|
4908
|
+
if (t12.isIdentifier(decl.id) && decl.id.name === "roles" && decl.init) {
|
|
4909
|
+
let rolesObj = null;
|
|
4910
|
+
if (t12.isCallExpression(decl.init) && t12.isIdentifier(decl.init.callee) && decl.init.callee.name === "defineRoles" && t12.isObjectExpression(decl.init.arguments[0])) {
|
|
4911
|
+
rolesObj = decl.init.arguments[0];
|
|
4912
|
+
} else if (t12.isObjectExpression(decl.init)) {
|
|
4913
|
+
rolesObj = decl.init;
|
|
4914
|
+
}
|
|
4915
|
+
if (rolesObj) {
|
|
4916
|
+
const roles = extractNodeValue2(rolesObj);
|
|
4917
|
+
if (!compilerState.metadata.roles) compilerState.metadata.roles = {};
|
|
4918
|
+
for (const [roleName, roleConfig] of Object.entries(roles)) {
|
|
4919
|
+
compilerState.metadata.roles[roleName] = roleConfig;
|
|
4920
|
+
}
|
|
4921
|
+
}
|
|
4922
|
+
}
|
|
4923
|
+
if (t12.isIdentifier(decl.id) && decl.id.name === "fieldAccess" && t12.isObjectExpression(decl.init)) {
|
|
4924
|
+
const access = extractNodeValue2(decl.init);
|
|
4925
|
+
for (const [fieldName, config] of Object.entries(access)) {
|
|
4926
|
+
const field = compilerState.fields.find((f) => f.name === fieldName);
|
|
4927
|
+
if (field) {
|
|
4928
|
+
if (config.visibleTo) field.visible_to_roles = config.visibleTo;
|
|
4929
|
+
if (config.editableBy) field.editable_by_roles = config.editableBy;
|
|
4930
|
+
if (config.editableIn) field.editable_in_states = config.editableIn;
|
|
4931
|
+
}
|
|
4932
|
+
}
|
|
4933
|
+
}
|
|
4934
|
+
if (t12.isIdentifier(decl.id) && decl.id.name === "config" && decl.init) {
|
|
4935
|
+
if (t12.isCallExpression(decl.init) && t12.isIdentifier(decl.init.callee) && decl.init.callee.name === "orchestration" && t12.isObjectExpression(decl.init.arguments[0])) {
|
|
4936
|
+
compilerState.metadata.orchestration = extractNodeValue2(decl.init.arguments[0]);
|
|
4937
|
+
}
|
|
4938
|
+
}
|
|
4939
|
+
}
|
|
4940
|
+
}
|
|
4941
|
+
}
|
|
4942
|
+
for (const node of path.node.body) {
|
|
4943
|
+
if (t12.isExportNamedDeclaration(node) && t12.isVariableDeclaration(node.declaration)) {
|
|
4944
|
+
for (const decl of node.declaration.declarations) {
|
|
4945
|
+
if (t12.isIdentifier(decl.id) && decl.id.name === "fields" && t12.isObjectExpression(decl.init)) {
|
|
4946
|
+
const fieldsConfig = extractNodeValue2(decl.init);
|
|
4947
|
+
for (const [name, config] of Object.entries(fieldsConfig)) {
|
|
4948
|
+
const field = compilerState.fields.find((f) => f.name === name);
|
|
4949
|
+
if (!field) continue;
|
|
4950
|
+
if (typeof config === "string") {
|
|
4951
|
+
if (config.includes("!")) field.required = true;
|
|
4952
|
+
} else if (typeof config === "object" && config !== null) {
|
|
4953
|
+
const cfg = config;
|
|
4954
|
+
if (cfg.required) field.required = true;
|
|
4955
|
+
if (cfg.min !== void 0 || cfg.max !== void 0 || cfg.minLength !== void 0 || cfg.maxLength !== void 0 || cfg.pattern !== void 0) {
|
|
4956
|
+
if (!field.validation) field.validation = {};
|
|
4957
|
+
if (cfg.min !== void 0) field.validation.min = Number(cfg.min);
|
|
4958
|
+
if (cfg.max !== void 0) field.validation.max = Number(cfg.max);
|
|
4959
|
+
if (cfg.minLength !== void 0) field.validation.minLength = Number(cfg.minLength);
|
|
4960
|
+
if (cfg.maxLength !== void 0) field.validation.maxLength = Number(cfg.maxLength);
|
|
4961
|
+
if (cfg.pattern !== void 0) {
|
|
4962
|
+
if (!field.validation.rules) field.validation.rules = [];
|
|
4963
|
+
field.validation.rules.push({
|
|
4964
|
+
expression: `MATCHES(value, "${String(cfg.pattern)}")`,
|
|
4965
|
+
message: "Invalid format",
|
|
4966
|
+
severity: "error"
|
|
4967
|
+
});
|
|
4968
|
+
}
|
|
4969
|
+
}
|
|
4970
|
+
if (cfg.default !== void 0) field.default_value = cfg.default;
|
|
4971
|
+
}
|
|
4972
|
+
}
|
|
4973
|
+
}
|
|
4974
|
+
}
|
|
4975
|
+
}
|
|
4976
|
+
}
|
|
4977
|
+
compilerState.transitions = compilerState.transitions.filter((t22) => t22.to !== "");
|
|
4978
|
+
for (const trans of compilerState.transitions) {
|
|
4979
|
+
for (const from of trans.from) {
|
|
4980
|
+
if (!compilerState.states.has(from)) {
|
|
4981
|
+
compilerState.states.set(from, {
|
|
4982
|
+
name: from,
|
|
4983
|
+
type: "REGULAR",
|
|
4984
|
+
on_enter: [],
|
|
4985
|
+
during: [],
|
|
4986
|
+
on_exit: []
|
|
4987
|
+
});
|
|
4988
|
+
}
|
|
4989
|
+
}
|
|
4990
|
+
if (!compilerState.states.has(trans.to)) {
|
|
4991
|
+
compilerState.states.set(trans.to, {
|
|
4992
|
+
name: trans.to,
|
|
4993
|
+
type: "REGULAR",
|
|
4994
|
+
on_enter: [],
|
|
4995
|
+
during: [],
|
|
4996
|
+
on_exit: []
|
|
4997
|
+
});
|
|
4998
|
+
}
|
|
4999
|
+
}
|
|
5000
|
+
compilerState.actionCounter = actionCounter.value;
|
|
5001
|
+
}
|
|
5002
|
+
|
|
5003
|
+
// src/babel/extractors/server-action-extractor.ts
|
|
5004
|
+
var t13 = __toESM(require("@babel/types"));
|
|
5005
|
+
function isServerActionFile(filename) {
|
|
5006
|
+
if (!filename) return false;
|
|
5007
|
+
return /\.server\.(ts|tsx|js|jsx)$/.test(filename);
|
|
5008
|
+
}
|
|
5009
|
+
function extractServerActions(path, state) {
|
|
5010
|
+
const compilerState = state;
|
|
5011
|
+
const serverActions = [];
|
|
5012
|
+
for (const node of path.node.body) {
|
|
5013
|
+
if (t13.isExportNamedDeclaration(node)) {
|
|
5014
|
+
const decl = node.declaration;
|
|
5015
|
+
if (t13.isFunctionDeclaration(decl) && decl.id) {
|
|
5016
|
+
const action = extractFunctionAction(decl);
|
|
5017
|
+
if (action) {
|
|
5018
|
+
const comments = node.leadingComments || decl.leadingComments || [];
|
|
5019
|
+
action.description = extractDescription(comments);
|
|
5020
|
+
serverActions.push(action);
|
|
5021
|
+
}
|
|
5022
|
+
}
|
|
5023
|
+
if (t13.isVariableDeclaration(decl)) {
|
|
5024
|
+
for (const varDecl of decl.declarations) {
|
|
5025
|
+
if (!t13.isIdentifier(varDecl.id)) continue;
|
|
5026
|
+
const init = varDecl.init;
|
|
5027
|
+
if (t13.isArrowFunctionExpression(init) || t13.isFunctionExpression(init)) {
|
|
5028
|
+
const action = {
|
|
5029
|
+
name: varDecl.id.name,
|
|
5030
|
+
async: init.async || false,
|
|
5031
|
+
params: init.params.filter((p) => t13.isIdentifier(p)).map((p) => p.name)
|
|
5032
|
+
};
|
|
5033
|
+
if (init.params.length > 0) {
|
|
5034
|
+
const firstParam = init.params[0];
|
|
5035
|
+
if (t13.isIdentifier(firstParam) && firstParam.typeAnnotation) {
|
|
5036
|
+
action.contextType = extractTypeName(firstParam.typeAnnotation);
|
|
5037
|
+
}
|
|
5038
|
+
}
|
|
5039
|
+
serverActions.push(action);
|
|
5040
|
+
}
|
|
5041
|
+
}
|
|
5042
|
+
}
|
|
5043
|
+
}
|
|
5044
|
+
}
|
|
5045
|
+
if (serverActions.length > 0) {
|
|
5046
|
+
if (!compilerState.metadata) compilerState.metadata = {};
|
|
5047
|
+
compilerState.metadata.serverActions = serverActions;
|
|
5048
|
+
}
|
|
5049
|
+
}
|
|
5050
|
+
function extractFunctionAction(decl) {
|
|
5051
|
+
if (!decl.id) return null;
|
|
5052
|
+
const action = {
|
|
5053
|
+
name: decl.id.name,
|
|
5054
|
+
async: decl.async || false,
|
|
5055
|
+
params: decl.params.filter((p) => t13.isIdentifier(p)).map((p) => p.name)
|
|
5056
|
+
};
|
|
5057
|
+
if (decl.params.length > 0) {
|
|
5058
|
+
const firstParam = decl.params[0];
|
|
5059
|
+
if (t13.isIdentifier(firstParam) && firstParam.typeAnnotation) {
|
|
5060
|
+
action.contextType = extractTypeName(firstParam.typeAnnotation);
|
|
5061
|
+
}
|
|
5062
|
+
}
|
|
5063
|
+
return action;
|
|
5064
|
+
}
|
|
5065
|
+
function extractTypeName(annotation) {
|
|
5066
|
+
if (t13.isTSTypeAnnotation(annotation)) {
|
|
5067
|
+
const typeNode = annotation.typeAnnotation;
|
|
5068
|
+
if (t13.isTSTypeReference(typeNode) && t13.isIdentifier(typeNode.typeName)) {
|
|
5069
|
+
return typeNode.typeName.name;
|
|
5070
|
+
}
|
|
5071
|
+
}
|
|
5072
|
+
return void 0;
|
|
5073
|
+
}
|
|
5074
|
+
function extractDescription(comments) {
|
|
5075
|
+
for (const comment of comments) {
|
|
5076
|
+
if (comment.type !== "CommentBlock") continue;
|
|
5077
|
+
const lines = comment.value.split("\n");
|
|
5078
|
+
for (const line of lines) {
|
|
5079
|
+
const trimmed = line.replace(/^\s*\*\s?/, "").trim();
|
|
5080
|
+
if (trimmed && !trimmed.startsWith("@")) {
|
|
5081
|
+
return trimmed;
|
|
5082
|
+
}
|
|
5083
|
+
}
|
|
5084
|
+
}
|
|
5085
|
+
return void 0;
|
|
5086
|
+
}
|
|
5087
|
+
|
|
5088
|
+
// src/babel/extractors/server-action-hook-extractor.ts
|
|
5089
|
+
var t14 = __toESM(require("@babel/types"));
|
|
5090
|
+
function extractServerActionHook(path, state) {
|
|
5091
|
+
const args = path.node.arguments;
|
|
5092
|
+
if (args.length < 1) return;
|
|
5093
|
+
const nameArg = args[0];
|
|
5094
|
+
if (!t14.isStringLiteral(nameArg)) return;
|
|
5095
|
+
const compilerState = state;
|
|
5096
|
+
const entry = {
|
|
5097
|
+
name: nameArg.value
|
|
5098
|
+
};
|
|
5099
|
+
if (args.length > 1 && t14.isObjectExpression(args[1])) {
|
|
5100
|
+
for (const prop of args[1].properties) {
|
|
5101
|
+
if (!t14.isObjectProperty(prop) || !t14.isIdentifier(prop.key)) continue;
|
|
5102
|
+
if (prop.key.name === "instanceId" && t14.isStringLiteral(prop.value)) {
|
|
5103
|
+
entry.staticInstanceId = prop.value.value;
|
|
5104
|
+
}
|
|
5105
|
+
}
|
|
5106
|
+
}
|
|
5107
|
+
const parent = path.parentPath;
|
|
5108
|
+
if (parent?.isVariableDeclarator() && t14.isIdentifier(parent.node.id)) {
|
|
5109
|
+
entry.variableName = parent.node.id.name;
|
|
5110
|
+
}
|
|
5111
|
+
if (!compilerState.metadata) compilerState.metadata = {};
|
|
5112
|
+
const meta = compilerState.metadata;
|
|
5113
|
+
if (!meta.serverActionHooks) meta.serverActionHooks = [];
|
|
5114
|
+
meta.serverActionHooks.push(entry);
|
|
5115
|
+
}
|
|
5116
|
+
|
|
5117
|
+
// src/babel/extractors/server-state-extractor.ts
|
|
5118
|
+
var t15 = __toESM(require("@babel/types"));
|
|
5119
|
+
function extractServerState(path, state) {
|
|
5120
|
+
const args = path.node.arguments;
|
|
5121
|
+
if (args.length < 1) return;
|
|
5122
|
+
const compilerState = state;
|
|
5123
|
+
const entry = {};
|
|
5124
|
+
const instanceArg = args[0];
|
|
5125
|
+
if (t15.isStringLiteral(instanceArg)) {
|
|
5126
|
+
entry.staticInstanceId = instanceArg.value;
|
|
5127
|
+
}
|
|
5128
|
+
if (args.length > 1 && t15.isObjectExpression(args[1])) {
|
|
5129
|
+
for (const prop of args[1].properties) {
|
|
5130
|
+
if (!t15.isObjectProperty(prop) || !t15.isIdentifier(prop.key)) continue;
|
|
5131
|
+
if (prop.key.name === "enabled" && t15.isBooleanLiteral(prop.value)) {
|
|
5132
|
+
if (!prop.value.value) entry.disabled = true;
|
|
5133
|
+
}
|
|
5134
|
+
}
|
|
5135
|
+
}
|
|
5136
|
+
const parent = path.parentPath;
|
|
5137
|
+
if (parent?.isVariableDeclarator()) {
|
|
5138
|
+
if (t15.isIdentifier(parent.node.id)) {
|
|
5139
|
+
entry.variableName = parent.node.id.name;
|
|
5140
|
+
} else if (t15.isObjectPattern(parent.node.id)) {
|
|
5141
|
+
const props = parent.node.id.properties.filter((p) => t15.isObjectProperty(p) && t15.isIdentifier(p.key)).map((p) => p.key.name);
|
|
5142
|
+
if (props.length > 0) {
|
|
5143
|
+
entry.variableName = props.join(", ");
|
|
5144
|
+
}
|
|
5145
|
+
}
|
|
5146
|
+
}
|
|
5147
|
+
if (!compilerState.metadata) compilerState.metadata = {};
|
|
5148
|
+
const meta = compilerState.metadata;
|
|
5149
|
+
if (!meta.serverStateSubscriptions) meta.serverStateSubscriptions = [];
|
|
5150
|
+
meta.serverStateSubscriptions.push(entry);
|
|
5151
|
+
meta.requiresSSE = true;
|
|
5152
|
+
}
|
|
5153
|
+
|
|
5154
|
+
// src/babel/extractors/grammar-island-extractor.ts
|
|
5155
|
+
var t16 = __toESM(require("@babel/types"));
|
|
5156
|
+
var GRAMMAR_TAGS = /* @__PURE__ */ new Set(["cedar", "sql", "cron", "dmn", "graphql", "jsonpath"]);
|
|
5157
|
+
function parseCedar(source) {
|
|
5158
|
+
const policies = [];
|
|
5159
|
+
const policyRegex = /(permit|forbid)\s*\(([^)]*)\)(?:\s*when\s*\{([^}]*)\})?/g;
|
|
5160
|
+
let match;
|
|
5161
|
+
while ((match = policyRegex.exec(source)) !== null) {
|
|
3204
5162
|
const [, effect, scope, condition] = match;
|
|
3205
5163
|
const parts = scope.split(",").map((s) => s.trim());
|
|
3206
5164
|
const policy = {
|
|
@@ -3275,7 +5233,7 @@ function parseDmn(source) {
|
|
|
3275
5233
|
}
|
|
3276
5234
|
function extractGrammarIsland(path, state, slug) {
|
|
3277
5235
|
const tag = path.node.tag;
|
|
3278
|
-
if (!
|
|
5236
|
+
if (!t16.isIdentifier(tag)) return;
|
|
3279
5237
|
const tagName = tag.name;
|
|
3280
5238
|
if (!GRAMMAR_TAGS.has(tagName)) return;
|
|
3281
5239
|
const compilerState = state;
|
|
@@ -3285,7 +5243,7 @@ function extractGrammarIsland(path, state, slug) {
|
|
|
3285
5243
|
rawSource += quasi.quasis[i].value.raw;
|
|
3286
5244
|
if (i < quasi.expressions.length) {
|
|
3287
5245
|
const expr = quasi.expressions[i];
|
|
3288
|
-
if (
|
|
5246
|
+
if (t16.isIdentifier(expr)) {
|
|
3289
5247
|
rawSource += `\${${expr.name}}`;
|
|
3290
5248
|
} else {
|
|
3291
5249
|
rawSource += `\${expr_${i}}`;
|
|
@@ -3329,16 +5287,16 @@ function extractGrammarIslands(path, state) {
|
|
|
3329
5287
|
path.traverse({
|
|
3330
5288
|
TaggedTemplateExpression(templatePath) {
|
|
3331
5289
|
const tag = templatePath.node.tag;
|
|
3332
|
-
if (!
|
|
5290
|
+
if (!t16.isIdentifier(tag) || !GRAMMAR_TAGS.has(tag.name)) return;
|
|
3333
5291
|
let slug = "unnamed";
|
|
3334
5292
|
const parent = templatePath.parentPath;
|
|
3335
|
-
if (parent && parent.isVariableDeclarator() &&
|
|
5293
|
+
if (parent && parent.isVariableDeclarator() && t16.isIdentifier(parent.node.id)) {
|
|
3336
5294
|
slug = parent.node.id.name;
|
|
3337
5295
|
}
|
|
3338
|
-
if (parent && parent.isObjectProperty() &&
|
|
5296
|
+
if (parent && parent.isObjectProperty() && t16.isIdentifier(parent.node.key)) {
|
|
3339
5297
|
slug = parent.node.key.name;
|
|
3340
5298
|
}
|
|
3341
|
-
if (parent && parent.isObjectProperty() &&
|
|
5299
|
+
if (parent && parent.isObjectProperty() && t16.isStringLiteral(parent.node.key)) {
|
|
3342
5300
|
slug = parent.node.key.value;
|
|
3343
5301
|
}
|
|
3344
5302
|
extractGrammarIsland(templatePath, state, slug);
|
|
@@ -3347,12 +5305,12 @@ function extractGrammarIslands(path, state) {
|
|
|
3347
5305
|
}
|
|
3348
5306
|
|
|
3349
5307
|
// src/babel/extractors/context-extractor.ts
|
|
3350
|
-
var
|
|
5308
|
+
var t17 = __toESM(require("@babel/types"));
|
|
3351
5309
|
function hasContextCreation(path) {
|
|
3352
5310
|
let found = false;
|
|
3353
5311
|
path.traverse({
|
|
3354
5312
|
CallExpression(callPath) {
|
|
3355
|
-
if (
|
|
5313
|
+
if (t17.isIdentifier(callPath.node.callee, { name: "createContext" })) {
|
|
3356
5314
|
found = true;
|
|
3357
5315
|
callPath.stop();
|
|
3358
5316
|
}
|
|
@@ -3368,9 +5326,9 @@ function extractContextWorkflows(path, state) {
|
|
|
3368
5326
|
// Detect: const XContext = createContext(...)
|
|
3369
5327
|
VariableDeclarator(declPath) {
|
|
3370
5328
|
const init = declPath.node.init;
|
|
3371
|
-
if (!init || !
|
|
3372
|
-
if (!
|
|
3373
|
-
if (!
|
|
5329
|
+
if (!init || !t17.isCallExpression(init)) return;
|
|
5330
|
+
if (!t17.isIdentifier(init.callee, { name: "createContext" })) return;
|
|
5331
|
+
if (!t17.isIdentifier(declPath.node.id)) return;
|
|
3374
5332
|
const contextName = declPath.node.id.name;
|
|
3375
5333
|
contextNames.set(contextName, contextName);
|
|
3376
5334
|
const workflow = {
|
|
@@ -3379,25 +5337,25 @@ function extractContextWorkflows(path, state) {
|
|
|
3379
5337
|
reducerActions: []
|
|
3380
5338
|
};
|
|
3381
5339
|
const typeParams = init.typeParameters;
|
|
3382
|
-
if (typeParams &&
|
|
5340
|
+
if (typeParams && t17.isTSTypeParameterInstantiation(typeParams)) {
|
|
3383
5341
|
const typeArg = typeParams.params[0];
|
|
3384
|
-
if (
|
|
5342
|
+
if (t17.isTSTypeReference(typeArg) && t17.isIdentifier(typeArg.typeName)) {
|
|
3385
5343
|
const interfaceName = typeArg.typeName.name;
|
|
3386
|
-
|
|
5344
|
+
extractFieldsFromInterface3(path, interfaceName, workflow);
|
|
3387
5345
|
}
|
|
3388
5346
|
}
|
|
3389
|
-
if (init.arguments.length > 0 &&
|
|
5347
|
+
if (init.arguments.length > 0 && t17.isObjectExpression(init.arguments[0])) {
|
|
3390
5348
|
workflow.initialState = extractObjectLiteral2(init.arguments[0]);
|
|
3391
5349
|
}
|
|
3392
5350
|
contextWorkflows.push(workflow);
|
|
3393
5351
|
},
|
|
3394
5352
|
// Detect useReducer(reducer, initialState) and extract reducer cases
|
|
3395
5353
|
CallExpression(callPath) {
|
|
3396
|
-
if (!
|
|
5354
|
+
if (!t17.isIdentifier(callPath.node.callee, { name: "useReducer" })) return;
|
|
3397
5355
|
const args = callPath.node.arguments;
|
|
3398
5356
|
if (args.length < 1) return;
|
|
3399
5357
|
const reducerArg = args[0];
|
|
3400
|
-
if (!
|
|
5358
|
+
if (!t17.isIdentifier(reducerArg)) return;
|
|
3401
5359
|
const reducerName = reducerArg.name;
|
|
3402
5360
|
const actions = extractReducerActions(path, reducerName);
|
|
3403
5361
|
if (contextWorkflows.length > 0) {
|
|
@@ -3413,13 +5371,13 @@ function extractContextWorkflows(path, state) {
|
|
|
3413
5371
|
meta.contextWorkflows = contextWorkflows;
|
|
3414
5372
|
}
|
|
3415
5373
|
}
|
|
3416
|
-
function
|
|
5374
|
+
function extractFieldsFromInterface3(path, interfaceName, workflow) {
|
|
3417
5375
|
path.traverse({
|
|
3418
5376
|
TSInterfaceDeclaration(ifacePath) {
|
|
3419
|
-
if (!
|
|
5377
|
+
if (!t17.isIdentifier(ifacePath.node.id, { name: interfaceName })) return;
|
|
3420
5378
|
for (const prop of ifacePath.node.body.body) {
|
|
3421
|
-
if (!
|
|
3422
|
-
if (!
|
|
5379
|
+
if (!t17.isTSPropertySignature(prop)) continue;
|
|
5380
|
+
if (!t17.isIdentifier(prop.key)) continue;
|
|
3423
5381
|
const field = {
|
|
3424
5382
|
name: prop.key.name,
|
|
3425
5383
|
type: extractTSType(prop.typeAnnotation),
|
|
@@ -3431,20 +5389,20 @@ function extractFieldsFromInterface2(path, interfaceName, workflow) {
|
|
|
3431
5389
|
});
|
|
3432
5390
|
}
|
|
3433
5391
|
function extractTSType(annotation) {
|
|
3434
|
-
if (!annotation || !
|
|
5392
|
+
if (!annotation || !t17.isTSTypeAnnotation(annotation)) return "unknown";
|
|
3435
5393
|
const typeNode = annotation.typeAnnotation;
|
|
3436
|
-
if (
|
|
3437
|
-
if (
|
|
3438
|
-
if (
|
|
3439
|
-
if (
|
|
3440
|
-
if (
|
|
5394
|
+
if (t17.isTSStringKeyword(typeNode)) return "string";
|
|
5395
|
+
if (t17.isTSNumberKeyword(typeNode)) return "number";
|
|
5396
|
+
if (t17.isTSBooleanKeyword(typeNode)) return "boolean";
|
|
5397
|
+
if (t17.isTSArrayType(typeNode)) return `${extractTSTypeNode(typeNode.elementType)}[]`;
|
|
5398
|
+
if (t17.isTSTypeReference(typeNode) && t17.isIdentifier(typeNode.typeName)) return typeNode.typeName.name;
|
|
3441
5399
|
return "unknown";
|
|
3442
5400
|
}
|
|
3443
5401
|
function extractTSTypeNode(node) {
|
|
3444
|
-
if (
|
|
3445
|
-
if (
|
|
3446
|
-
if (
|
|
3447
|
-
if (
|
|
5402
|
+
if (t17.isTSStringKeyword(node)) return "string";
|
|
5403
|
+
if (t17.isTSNumberKeyword(node)) return "number";
|
|
5404
|
+
if (t17.isTSBooleanKeyword(node)) return "boolean";
|
|
5405
|
+
if (t17.isTSTypeReference(node) && t17.isIdentifier(node.typeName)) return node.typeName.name;
|
|
3448
5406
|
return "unknown";
|
|
3449
5407
|
}
|
|
3450
5408
|
function extractReducerActions(path, reducerName) {
|
|
@@ -3456,7 +5414,7 @@ function extractReducerActions(path, reducerName) {
|
|
|
3456
5414
|
SwitchStatement(switchPath) {
|
|
3457
5415
|
for (const switchCase of switchPath.node.cases) {
|
|
3458
5416
|
if (!switchCase.test) continue;
|
|
3459
|
-
if (
|
|
5417
|
+
if (t17.isStringLiteral(switchCase.test)) {
|
|
3460
5418
|
actions.push({
|
|
3461
5419
|
type: switchCase.test.value
|
|
3462
5420
|
});
|
|
@@ -3471,24 +5429,576 @@ function extractReducerActions(path, reducerName) {
|
|
|
3471
5429
|
function extractObjectLiteral2(obj) {
|
|
3472
5430
|
const result = {};
|
|
3473
5431
|
for (const prop of obj.properties) {
|
|
3474
|
-
if (!
|
|
3475
|
-
if (
|
|
3476
|
-
else if (
|
|
3477
|
-
else if (
|
|
3478
|
-
else if (
|
|
3479
|
-
else if (
|
|
3480
|
-
else if (
|
|
5432
|
+
if (!t17.isObjectProperty(prop) || !t17.isIdentifier(prop.key)) continue;
|
|
5433
|
+
if (t17.isStringLiteral(prop.value)) result[prop.key.name] = prop.value.value;
|
|
5434
|
+
else if (t17.isNumericLiteral(prop.value)) result[prop.key.name] = prop.value.value;
|
|
5435
|
+
else if (t17.isBooleanLiteral(prop.value)) result[prop.key.name] = prop.value.value;
|
|
5436
|
+
else if (t17.isNullLiteral(prop.value)) result[prop.key.name] = null;
|
|
5437
|
+
else if (t17.isArrayExpression(prop.value)) result[prop.key.name] = [];
|
|
5438
|
+
else if (t17.isObjectExpression(prop.value)) result[prop.key.name] = extractObjectLiteral2(prop.value);
|
|
5439
|
+
}
|
|
5440
|
+
return result;
|
|
5441
|
+
}
|
|
5442
|
+
|
|
5443
|
+
// src/babel/extractors/middleware-extractor.ts
|
|
5444
|
+
var t18 = __toESM(require("@babel/types"));
|
|
5445
|
+
var BUILTIN_FACTORIES = /* @__PURE__ */ new Set([
|
|
5446
|
+
"withAuth",
|
|
5447
|
+
"withAuditLog",
|
|
5448
|
+
"withRateLimit",
|
|
5449
|
+
"withValidation",
|
|
5450
|
+
"withMetrics"
|
|
5451
|
+
]);
|
|
5452
|
+
function hasMiddleware(path) {
|
|
5453
|
+
for (const node of path.node.body) {
|
|
5454
|
+
if (t18.isExportDefaultDeclaration(node)) {
|
|
5455
|
+
const decl = node.declaration;
|
|
5456
|
+
if (isDefineMiddlewareCall(decl) || isBuiltinFactoryCall(decl)) {
|
|
5457
|
+
return true;
|
|
5458
|
+
}
|
|
5459
|
+
}
|
|
5460
|
+
if (t18.isExportNamedDeclaration(node) && node.declaration) {
|
|
5461
|
+
if (t18.isVariableDeclaration(node.declaration)) {
|
|
5462
|
+
for (const declarator of node.declaration.declarations) {
|
|
5463
|
+
if (declarator.init && (isDefineMiddlewareCall(declarator.init) || isBuiltinFactoryCall(declarator.init))) {
|
|
5464
|
+
return true;
|
|
5465
|
+
}
|
|
5466
|
+
}
|
|
5467
|
+
}
|
|
5468
|
+
}
|
|
5469
|
+
if (t18.isVariableDeclaration(node)) {
|
|
5470
|
+
for (const declarator of node.declarations) {
|
|
5471
|
+
if (declarator.init && (isDefineMiddlewareCall(declarator.init) || isBuiltinFactoryCall(declarator.init))) {
|
|
5472
|
+
return true;
|
|
5473
|
+
}
|
|
5474
|
+
}
|
|
5475
|
+
}
|
|
5476
|
+
}
|
|
5477
|
+
return false;
|
|
5478
|
+
}
|
|
5479
|
+
function isDefineMiddlewareCall(node) {
|
|
5480
|
+
return t18.isCallExpression(node) && t18.isIdentifier(node.callee) && node.callee.name === "defineMiddleware";
|
|
5481
|
+
}
|
|
5482
|
+
function isBuiltinFactoryCall(node) {
|
|
5483
|
+
return t18.isCallExpression(node) && t18.isIdentifier(node.callee) && BUILTIN_FACTORIES.has(node.callee.name);
|
|
5484
|
+
}
|
|
5485
|
+
function extractMiddleware(path, state) {
|
|
5486
|
+
const compilerState = state;
|
|
5487
|
+
if (!compilerState.metadata) compilerState.metadata = {};
|
|
5488
|
+
const meta = compilerState.metadata;
|
|
5489
|
+
if (!meta.middleware) meta.middleware = [];
|
|
5490
|
+
const middlewareList = meta.middleware;
|
|
5491
|
+
path.traverse({
|
|
5492
|
+
CallExpression(callPath) {
|
|
5493
|
+
const callee = callPath.node.callee;
|
|
5494
|
+
if (!t18.isIdentifier(callee)) return;
|
|
5495
|
+
if (callee.name === "defineMiddleware") {
|
|
5496
|
+
const extracted = extractDefineMiddleware(callPath);
|
|
5497
|
+
if (extracted) middlewareList.push(extracted);
|
|
5498
|
+
} else if (BUILTIN_FACTORIES.has(callee.name)) {
|
|
5499
|
+
const extracted = extractBuiltinFactory(callee.name, callPath);
|
|
5500
|
+
if (extracted) middlewareList.push(extracted);
|
|
5501
|
+
}
|
|
5502
|
+
}
|
|
5503
|
+
});
|
|
5504
|
+
}
|
|
5505
|
+
function extractDefineMiddleware(callPath) {
|
|
5506
|
+
const args = callPath.node.arguments;
|
|
5507
|
+
if (args.length < 1 || !t18.isObjectExpression(args[0])) return null;
|
|
5508
|
+
const obj = args[0];
|
|
5509
|
+
let name = "unnamed";
|
|
5510
|
+
let match = [];
|
|
5511
|
+
let priority = 0;
|
|
5512
|
+
const before = [];
|
|
5513
|
+
const after = [];
|
|
5514
|
+
let hasAround = false;
|
|
5515
|
+
let config;
|
|
5516
|
+
for (const prop of obj.properties) {
|
|
5517
|
+
if (!t18.isObjectProperty(prop) && !t18.isObjectMethod(prop)) continue;
|
|
5518
|
+
const key = t18.isObjectProperty(prop) ? prop.key : prop.key;
|
|
5519
|
+
const keyName = t18.isIdentifier(key) ? key.name : t18.isStringLiteral(key) ? key.value : null;
|
|
5520
|
+
if (!keyName) continue;
|
|
5521
|
+
switch (keyName) {
|
|
5522
|
+
case "name":
|
|
5523
|
+
if (t18.isObjectProperty(prop) && t18.isStringLiteral(prop.value)) {
|
|
5524
|
+
name = prop.value.value;
|
|
5525
|
+
}
|
|
5526
|
+
break;
|
|
5527
|
+
case "match":
|
|
5528
|
+
if (t18.isObjectProperty(prop)) {
|
|
5529
|
+
if (t18.isStringLiteral(prop.value)) {
|
|
5530
|
+
match = [prop.value.value];
|
|
5531
|
+
} else if (t18.isArrayExpression(prop.value)) {
|
|
5532
|
+
match = prop.value.elements.filter((el) => t18.isStringLiteral(el)).map((el) => el.value);
|
|
5533
|
+
}
|
|
5534
|
+
}
|
|
5535
|
+
break;
|
|
5536
|
+
case "priority":
|
|
5537
|
+
if (t18.isObjectProperty(prop) && t18.isNumericLiteral(prop.value)) {
|
|
5538
|
+
priority = prop.value.value;
|
|
5539
|
+
}
|
|
5540
|
+
break;
|
|
5541
|
+
case "config":
|
|
5542
|
+
if (t18.isObjectProperty(prop) && t18.isObjectExpression(prop.value)) {
|
|
5543
|
+
config = extractConfigSchema(prop.value);
|
|
5544
|
+
}
|
|
5545
|
+
break;
|
|
5546
|
+
case "before":
|
|
5547
|
+
if (t18.isObjectMethod(prop)) {
|
|
5548
|
+
extractActionsFromBody(prop.body, before);
|
|
5549
|
+
} else if (t18.isObjectProperty(prop)) {
|
|
5550
|
+
const val = prop.value;
|
|
5551
|
+
if (t18.isFunctionExpression(val) || t18.isArrowFunctionExpression(val)) {
|
|
5552
|
+
const body = t18.isBlockStatement(val.body) ? val.body : null;
|
|
5553
|
+
if (body) extractActionsFromBody(body, before);
|
|
5554
|
+
}
|
|
5555
|
+
}
|
|
5556
|
+
break;
|
|
5557
|
+
case "after":
|
|
5558
|
+
if (t18.isObjectMethod(prop)) {
|
|
5559
|
+
extractActionsFromBody(prop.body, after);
|
|
5560
|
+
} else if (t18.isObjectProperty(prop)) {
|
|
5561
|
+
const val = prop.value;
|
|
5562
|
+
if (t18.isFunctionExpression(val) || t18.isArrowFunctionExpression(val)) {
|
|
5563
|
+
const body = t18.isBlockStatement(val.body) ? val.body : null;
|
|
5564
|
+
if (body) extractActionsFromBody(body, after);
|
|
5565
|
+
}
|
|
5566
|
+
}
|
|
5567
|
+
break;
|
|
5568
|
+
case "around":
|
|
5569
|
+
hasAround = true;
|
|
5570
|
+
break;
|
|
5571
|
+
}
|
|
5572
|
+
}
|
|
5573
|
+
return { name, match, priority, before, after, hasAround, config };
|
|
5574
|
+
}
|
|
5575
|
+
function extractBuiltinFactory(factoryName, callPath) {
|
|
5576
|
+
const args = callPath.node.arguments;
|
|
5577
|
+
const opts = args.length > 0 && t18.isObjectExpression(args[0]) ? args[0] : null;
|
|
5578
|
+
switch (factoryName) {
|
|
5579
|
+
case "withAuth": {
|
|
5580
|
+
let redirectTo;
|
|
5581
|
+
if (opts) {
|
|
5582
|
+
for (const prop of opts.properties) {
|
|
5583
|
+
if (t18.isObjectProperty(prop) && t18.isIdentifier(prop.key) && prop.key.name === "redirectTo" && t18.isStringLiteral(prop.value)) {
|
|
5584
|
+
redirectTo = prop.value.value;
|
|
5585
|
+
}
|
|
5586
|
+
}
|
|
5587
|
+
}
|
|
5588
|
+
return {
|
|
5589
|
+
name: "mm:auth",
|
|
5590
|
+
match: ["*:*:transition.execute"],
|
|
5591
|
+
priority: 90,
|
|
5592
|
+
before: [{ type: "block", args: { condition: "!ctx.actor.id", reason: redirectTo ? `redirect:${redirectTo}` : "Authentication required" } }],
|
|
5593
|
+
after: [],
|
|
5594
|
+
hasAround: false,
|
|
5595
|
+
factory: "withAuth"
|
|
5596
|
+
};
|
|
5597
|
+
}
|
|
5598
|
+
case "withAuditLog": {
|
|
5599
|
+
let level = "info";
|
|
5600
|
+
if (opts) {
|
|
5601
|
+
for (const prop of opts.properties) {
|
|
5602
|
+
if (t18.isObjectProperty(prop) && t18.isIdentifier(prop.key) && prop.key.name === "level" && t18.isStringLiteral(prop.value)) {
|
|
5603
|
+
level = prop.value.value;
|
|
5604
|
+
}
|
|
5605
|
+
}
|
|
5606
|
+
}
|
|
5607
|
+
return {
|
|
5608
|
+
name: "mm:audit-log",
|
|
5609
|
+
match: ["*:*:transition.execute"],
|
|
5610
|
+
priority: 0,
|
|
5611
|
+
before: [],
|
|
5612
|
+
after: [{ type: "modify", args: { __audit: { level } } }],
|
|
5613
|
+
hasAround: false,
|
|
5614
|
+
factory: "withAuditLog"
|
|
5615
|
+
};
|
|
5616
|
+
}
|
|
5617
|
+
case "withRateLimit": {
|
|
5618
|
+
let maxPerMinute = 60;
|
|
5619
|
+
if (opts) {
|
|
5620
|
+
for (const prop of opts.properties) {
|
|
5621
|
+
if (t18.isObjectProperty(prop) && t18.isIdentifier(prop.key) && prop.key.name === "maxPerMinute" && t18.isNumericLiteral(prop.value)) {
|
|
5622
|
+
maxPerMinute = prop.value.value;
|
|
5623
|
+
}
|
|
5624
|
+
}
|
|
5625
|
+
}
|
|
5626
|
+
return {
|
|
5627
|
+
name: "mm:rate-limit",
|
|
5628
|
+
match: ["*:*:transition.execute"],
|
|
5629
|
+
priority: 80,
|
|
5630
|
+
before: [{ type: "block", args: { condition: `counter >= ${maxPerMinute}`, reason: `Rate limit exceeded: ${maxPerMinute} per minute` } }],
|
|
5631
|
+
after: [],
|
|
5632
|
+
hasAround: false,
|
|
5633
|
+
config: { maxPerMinute: { type: "number", default: maxPerMinute } },
|
|
5634
|
+
factory: "withRateLimit"
|
|
5635
|
+
};
|
|
5636
|
+
}
|
|
5637
|
+
case "withValidation": {
|
|
5638
|
+
const rules = [];
|
|
5639
|
+
if (opts) {
|
|
5640
|
+
for (const prop of opts.properties) {
|
|
5641
|
+
if (t18.isObjectProperty(prop) && t18.isIdentifier(prop.key) && prop.key.name === "rules" && t18.isArrayExpression(prop.value)) {
|
|
5642
|
+
for (const el of prop.value.elements) {
|
|
5643
|
+
if (!t18.isObjectExpression(el)) continue;
|
|
5644
|
+
let fields = [];
|
|
5645
|
+
let check = "";
|
|
5646
|
+
let message = "";
|
|
5647
|
+
for (const rp of el.properties) {
|
|
5648
|
+
if (!t18.isObjectProperty(rp) || !t18.isIdentifier(rp.key)) continue;
|
|
5649
|
+
if (rp.key.name === "fields" && t18.isArrayExpression(rp.value)) {
|
|
5650
|
+
fields = rp.value.elements.filter((e) => t18.isStringLiteral(e)).map((e) => e.value);
|
|
5651
|
+
}
|
|
5652
|
+
if (rp.key.name === "check" && t18.isStringLiteral(rp.value)) {
|
|
5653
|
+
check = rp.value.value;
|
|
5654
|
+
}
|
|
5655
|
+
if (rp.key.name === "message" && t18.isStringLiteral(rp.value)) {
|
|
5656
|
+
message = rp.value.value;
|
|
5657
|
+
}
|
|
5658
|
+
}
|
|
5659
|
+
if (fields.length > 0) rules.push({ fields, check, message });
|
|
5660
|
+
}
|
|
5661
|
+
}
|
|
5662
|
+
}
|
|
5663
|
+
}
|
|
5664
|
+
return {
|
|
5665
|
+
name: "mm:validation",
|
|
5666
|
+
match: ["*:*:field.change"],
|
|
5667
|
+
priority: 70,
|
|
5668
|
+
before: rules.map((r) => ({ type: "validate", args: { fields: r.fields, check: r.check, message: r.message } })),
|
|
5669
|
+
after: [],
|
|
5670
|
+
hasAround: false,
|
|
5671
|
+
config: { rules: { type: "json", default: rules } },
|
|
5672
|
+
factory: "withValidation"
|
|
5673
|
+
};
|
|
5674
|
+
}
|
|
5675
|
+
case "withMetrics": {
|
|
5676
|
+
let endpoint;
|
|
5677
|
+
if (opts) {
|
|
5678
|
+
for (const prop of opts.properties) {
|
|
5679
|
+
if (t18.isObjectProperty(prop) && t18.isIdentifier(prop.key) && prop.key.name === "endpoint" && t18.isStringLiteral(prop.value)) {
|
|
5680
|
+
endpoint = prop.value.value;
|
|
5681
|
+
}
|
|
5682
|
+
}
|
|
5683
|
+
}
|
|
5684
|
+
return {
|
|
5685
|
+
name: "mm:metrics",
|
|
5686
|
+
match: ["*:*:*"],
|
|
5687
|
+
priority: 100,
|
|
5688
|
+
before: [],
|
|
5689
|
+
after: [],
|
|
5690
|
+
hasAround: true,
|
|
5691
|
+
config: { endpoint: { type: "string", default: endpoint } },
|
|
5692
|
+
factory: "withMetrics"
|
|
5693
|
+
};
|
|
5694
|
+
}
|
|
5695
|
+
default:
|
|
5696
|
+
return null;
|
|
5697
|
+
}
|
|
5698
|
+
}
|
|
5699
|
+
function extractActionsFromBody(body, actions) {
|
|
5700
|
+
for (const stmt of body.body) {
|
|
5701
|
+
if (t18.isExpressionStatement(stmt) && t18.isCallExpression(stmt.expression)) {
|
|
5702
|
+
const call = stmt.expression;
|
|
5703
|
+
if (t18.isMemberExpression(call.callee) && t18.isIdentifier(call.callee.property)) {
|
|
5704
|
+
const method = call.callee.property.name;
|
|
5705
|
+
if (method === "block" && call.arguments.length > 0) {
|
|
5706
|
+
const arg = call.arguments[0];
|
|
5707
|
+
actions.push({
|
|
5708
|
+
type: "block",
|
|
5709
|
+
args: { reason: t18.isStringLiteral(arg) ? arg.value : "<expression>" }
|
|
5710
|
+
});
|
|
5711
|
+
} else if (method === "modify" && call.arguments.length > 0) {
|
|
5712
|
+
const arg = call.arguments[0];
|
|
5713
|
+
actions.push({
|
|
5714
|
+
type: "modify",
|
|
5715
|
+
args: t18.isObjectExpression(arg) ? extractStaticObject(arg) : {}
|
|
5716
|
+
});
|
|
5717
|
+
} else if (method === "skip") {
|
|
5718
|
+
actions.push({ type: "skip" });
|
|
5719
|
+
}
|
|
5720
|
+
}
|
|
5721
|
+
}
|
|
5722
|
+
if (t18.isIfStatement(stmt)) {
|
|
5723
|
+
if (t18.isBlockStatement(stmt.consequent)) {
|
|
5724
|
+
extractActionsFromBody(stmt.consequent, actions);
|
|
5725
|
+
} else if (t18.isExpressionStatement(stmt.consequent)) {
|
|
5726
|
+
extractActionsFromBody(
|
|
5727
|
+
t18.blockStatement([stmt.consequent]),
|
|
5728
|
+
actions
|
|
5729
|
+
);
|
|
5730
|
+
}
|
|
5731
|
+
}
|
|
5732
|
+
}
|
|
5733
|
+
}
|
|
5734
|
+
function extractStaticObject(obj) {
|
|
5735
|
+
const result = {};
|
|
5736
|
+
for (const prop of obj.properties) {
|
|
5737
|
+
if (!t18.isObjectProperty(prop)) continue;
|
|
5738
|
+
const key = t18.isIdentifier(prop.key) ? prop.key.name : t18.isStringLiteral(prop.key) ? prop.key.value : null;
|
|
5739
|
+
if (!key) continue;
|
|
5740
|
+
const val = prop.value;
|
|
5741
|
+
if (t18.isStringLiteral(val)) result[key] = val.value;
|
|
5742
|
+
else if (t18.isNumericLiteral(val)) result[key] = val.value;
|
|
5743
|
+
else if (t18.isBooleanLiteral(val)) result[key] = val.value;
|
|
5744
|
+
else if (t18.isNullLiteral(val)) result[key] = null;
|
|
5745
|
+
else if (t18.isObjectExpression(val)) result[key] = extractStaticObject(val);
|
|
5746
|
+
else if (t18.isMemberExpression(val)) {
|
|
5747
|
+
result[key] = memberExprToString2(val);
|
|
5748
|
+
} else {
|
|
5749
|
+
result[key] = "<expression>";
|
|
5750
|
+
}
|
|
3481
5751
|
}
|
|
3482
5752
|
return result;
|
|
3483
5753
|
}
|
|
5754
|
+
function memberExprToString2(expr) {
|
|
5755
|
+
const parts = [];
|
|
5756
|
+
let current = expr;
|
|
5757
|
+
while (t18.isMemberExpression(current)) {
|
|
5758
|
+
if (t18.isIdentifier(current.property)) {
|
|
5759
|
+
parts.unshift(current.property.name);
|
|
5760
|
+
}
|
|
5761
|
+
current = current.object;
|
|
5762
|
+
}
|
|
5763
|
+
if (t18.isIdentifier(current)) {
|
|
5764
|
+
parts.unshift(current.name);
|
|
5765
|
+
}
|
|
5766
|
+
return "$" + parts.join(".");
|
|
5767
|
+
}
|
|
5768
|
+
function extractConfigSchema(obj) {
|
|
5769
|
+
const schema = {};
|
|
5770
|
+
for (const prop of obj.properties) {
|
|
5771
|
+
if (!t18.isObjectProperty(prop) || !t18.isIdentifier(prop.key)) continue;
|
|
5772
|
+
if (!t18.isObjectExpression(prop.value)) continue;
|
|
5773
|
+
const entry = { type: "string" };
|
|
5774
|
+
for (const inner of prop.value.properties) {
|
|
5775
|
+
if (!t18.isObjectProperty(inner) || !t18.isIdentifier(inner.key)) continue;
|
|
5776
|
+
if (inner.key.name === "type" && t18.isStringLiteral(inner.value)) {
|
|
5777
|
+
entry.type = inner.value.value;
|
|
5778
|
+
}
|
|
5779
|
+
if (inner.key.name === "default") {
|
|
5780
|
+
if (t18.isStringLiteral(inner.value)) entry.default = inner.value.value;
|
|
5781
|
+
else if (t18.isNumericLiteral(inner.value)) entry.default = inner.value.value;
|
|
5782
|
+
else if (t18.isBooleanLiteral(inner.value)) entry.default = inner.value.value;
|
|
5783
|
+
}
|
|
5784
|
+
}
|
|
5785
|
+
schema[prop.key.name] = entry;
|
|
5786
|
+
}
|
|
5787
|
+
return schema;
|
|
5788
|
+
}
|
|
5789
|
+
|
|
5790
|
+
// src/babel/extractors/constraint-extractor.ts
|
|
5791
|
+
var t19 = __toESM(require("@babel/types"));
|
|
5792
|
+
var BUILTIN_CONSTRAINTS = /* @__PURE__ */ new Set([
|
|
5793
|
+
"every state is reachable",
|
|
5794
|
+
"no deadlocks",
|
|
5795
|
+
"no unreachable states",
|
|
5796
|
+
"deterministic guards",
|
|
5797
|
+
"terminates",
|
|
5798
|
+
"no guard overlaps",
|
|
5799
|
+
"all roles defined",
|
|
5800
|
+
"all fields validated"
|
|
5801
|
+
]);
|
|
5802
|
+
function hasConstraints(path) {
|
|
5803
|
+
for (const node of path.node.body) {
|
|
5804
|
+
if (t19.isExportNamedDeclaration(node) && node.declaration) {
|
|
5805
|
+
if (t19.isVariableDeclaration(node.declaration)) {
|
|
5806
|
+
for (const declarator of node.declaration.declarations) {
|
|
5807
|
+
if (declarator.init && isConstraintsCall(declarator.init)) {
|
|
5808
|
+
return true;
|
|
5809
|
+
}
|
|
5810
|
+
}
|
|
5811
|
+
}
|
|
5812
|
+
}
|
|
5813
|
+
if (t19.isVariableDeclaration(node)) {
|
|
5814
|
+
for (const declarator of node.declarations) {
|
|
5815
|
+
if (declarator.init && isConstraintsCall(declarator.init)) {
|
|
5816
|
+
return true;
|
|
5817
|
+
}
|
|
5818
|
+
}
|
|
5819
|
+
}
|
|
5820
|
+
if (t19.isExpressionStatement(node) && isConstraintsCall(node.expression)) {
|
|
5821
|
+
return true;
|
|
5822
|
+
}
|
|
5823
|
+
}
|
|
5824
|
+
return false;
|
|
5825
|
+
}
|
|
5826
|
+
function isConstraintsCall(node) {
|
|
5827
|
+
return t19.isCallExpression(node) && t19.isIdentifier(node.callee) && node.callee.name === "constraints";
|
|
5828
|
+
}
|
|
5829
|
+
function extractConstraints(path, state) {
|
|
5830
|
+
const compilerState = state;
|
|
5831
|
+
if (!compilerState.metadata) compilerState.metadata = {};
|
|
5832
|
+
const meta = compilerState.metadata;
|
|
5833
|
+
if (!meta.constraints) meta.constraints = [];
|
|
5834
|
+
const constraintList = meta.constraints;
|
|
5835
|
+
path.traverse({
|
|
5836
|
+
CallExpression(callPath) {
|
|
5837
|
+
const callee = callPath.node.callee;
|
|
5838
|
+
if (!t19.isIdentifier(callee) || callee.name !== "constraints") return;
|
|
5839
|
+
const args = callPath.node.arguments;
|
|
5840
|
+
for (const arg of args) {
|
|
5841
|
+
if (t19.isStringLiteral(arg)) {
|
|
5842
|
+
constraintList.push({
|
|
5843
|
+
rule: arg.value,
|
|
5844
|
+
type: BUILTIN_CONSTRAINTS.has(arg.value) ? "builtin" : "custom"
|
|
5845
|
+
});
|
|
5846
|
+
}
|
|
5847
|
+
}
|
|
5848
|
+
}
|
|
5849
|
+
});
|
|
5850
|
+
}
|
|
3484
5851
|
|
|
3485
|
-
//
|
|
3486
|
-
|
|
3487
|
-
|
|
3488
|
-
|
|
3489
|
-
|
|
5852
|
+
// src/babel/extractors/actor-extractor.ts
|
|
5853
|
+
var t20 = __toESM(require("@babel/types"));
|
|
5854
|
+
function hasActorConfig(path) {
|
|
5855
|
+
for (const node of path.node.body) {
|
|
5856
|
+
if (t20.isExportNamedDeclaration(node) && node.declaration) {
|
|
5857
|
+
if (t20.isVariableDeclaration(node.declaration)) {
|
|
5858
|
+
for (const declarator of node.declaration.declarations) {
|
|
5859
|
+
if (declarator.init && isActorCall(declarator.init)) {
|
|
5860
|
+
return true;
|
|
5861
|
+
}
|
|
5862
|
+
}
|
|
5863
|
+
}
|
|
5864
|
+
}
|
|
5865
|
+
if (t20.isVariableDeclaration(node)) {
|
|
5866
|
+
for (const declarator of node.declarations) {
|
|
5867
|
+
if (declarator.init && isActorCall(declarator.init)) {
|
|
5868
|
+
return true;
|
|
5869
|
+
}
|
|
5870
|
+
}
|
|
5871
|
+
}
|
|
5872
|
+
if (t20.isExpressionStatement(node) && isActorCall(node.expression)) {
|
|
5873
|
+
return true;
|
|
5874
|
+
}
|
|
5875
|
+
}
|
|
5876
|
+
return false;
|
|
5877
|
+
}
|
|
5878
|
+
function isActorCall(node) {
|
|
5879
|
+
return t20.isCallExpression(node) && t20.isIdentifier(node.callee) && (node.callee.name === "configureActor" || node.callee.name === "spawnActor");
|
|
5880
|
+
}
|
|
5881
|
+
function extractActorConfig(path, state) {
|
|
5882
|
+
const compilerState = state;
|
|
5883
|
+
if (!compilerState.metadata) compilerState.metadata = {};
|
|
5884
|
+
const meta = compilerState.metadata;
|
|
5885
|
+
if (!meta.actor) {
|
|
5886
|
+
meta.actor = {
|
|
5887
|
+
supervision: { strategy: "escalate" },
|
|
5888
|
+
mailbox: {},
|
|
5889
|
+
hierarchy: {},
|
|
5890
|
+
spawns: []
|
|
5891
|
+
};
|
|
5892
|
+
}
|
|
5893
|
+
const actorConfig = meta.actor;
|
|
5894
|
+
path.traverse({
|
|
5895
|
+
CallExpression(callPath) {
|
|
5896
|
+
const callee = callPath.node.callee;
|
|
5897
|
+
if (!t20.isIdentifier(callee)) return;
|
|
5898
|
+
if (callee.name === "configureActor") {
|
|
5899
|
+
extractConfigureActor(callPath, actorConfig);
|
|
5900
|
+
} else if (callee.name === "spawnActor") {
|
|
5901
|
+
extractSpawnActor(callPath, actorConfig);
|
|
5902
|
+
}
|
|
5903
|
+
}
|
|
5904
|
+
});
|
|
5905
|
+
}
|
|
5906
|
+
function extractConfigureActor(callPath, actorConfig) {
|
|
5907
|
+
const args = callPath.node.arguments;
|
|
5908
|
+
if (args.length < 1 || !t20.isObjectExpression(args[0])) return;
|
|
5909
|
+
const obj = args[0];
|
|
5910
|
+
for (const prop of obj.properties) {
|
|
5911
|
+
if (!t20.isObjectProperty(prop) || !t20.isIdentifier(prop.key)) continue;
|
|
5912
|
+
switch (prop.key.name) {
|
|
5913
|
+
case "supervision":
|
|
5914
|
+
if (t20.isObjectExpression(prop.value)) {
|
|
5915
|
+
actorConfig.supervision = extractSupervision(prop.value);
|
|
5916
|
+
}
|
|
5917
|
+
break;
|
|
5918
|
+
case "mailbox":
|
|
5919
|
+
if (t20.isObjectExpression(prop.value)) {
|
|
5920
|
+
actorConfig.mailbox = extractMailbox(prop.value);
|
|
5921
|
+
}
|
|
5922
|
+
break;
|
|
5923
|
+
case "hierarchy":
|
|
5924
|
+
if (t20.isObjectExpression(prop.value)) {
|
|
5925
|
+
actorConfig.hierarchy = extractStaticObj(prop.value);
|
|
5926
|
+
}
|
|
5927
|
+
break;
|
|
5928
|
+
}
|
|
5929
|
+
}
|
|
5930
|
+
}
|
|
5931
|
+
function extractSpawnActor(callPath, actorConfig) {
|
|
5932
|
+
const args = callPath.node.arguments;
|
|
5933
|
+
if (args.length < 1 || !t20.isStringLiteral(args[0])) return;
|
|
5934
|
+
const spawn = { slug: args[0].value };
|
|
5935
|
+
if (args.length > 1 && t20.isObjectExpression(args[1])) {
|
|
5936
|
+
for (const prop of args[1].properties) {
|
|
5937
|
+
if (!t20.isObjectProperty(prop) || !t20.isIdentifier(prop.key)) continue;
|
|
5938
|
+
if (prop.key.name === "supervision" && t20.isObjectExpression(prop.value)) {
|
|
5939
|
+
spawn.supervision = extractSupervision(prop.value);
|
|
5940
|
+
} else if (prop.key.name === "blocking" && t20.isBooleanLiteral(prop.value)) {
|
|
5941
|
+
spawn.blocking = prop.value.value;
|
|
5942
|
+
}
|
|
5943
|
+
}
|
|
5944
|
+
}
|
|
5945
|
+
actorConfig.spawns.push(spawn);
|
|
5946
|
+
}
|
|
5947
|
+
function extractSupervision(obj) {
|
|
5948
|
+
const result = { strategy: "escalate" };
|
|
5949
|
+
for (const prop of obj.properties) {
|
|
5950
|
+
if (!t20.isObjectProperty(prop) || !t20.isIdentifier(prop.key)) continue;
|
|
5951
|
+
switch (prop.key.name) {
|
|
5952
|
+
case "strategy":
|
|
5953
|
+
if (t20.isStringLiteral(prop.value)) result.strategy = prop.value.value;
|
|
5954
|
+
break;
|
|
5955
|
+
case "maxRetries":
|
|
5956
|
+
if (t20.isNumericLiteral(prop.value)) result.maxRetries = prop.value.value;
|
|
5957
|
+
break;
|
|
5958
|
+
case "retryWindow":
|
|
5959
|
+
if (t20.isStringLiteral(prop.value)) result.retryWindow = prop.value.value;
|
|
5960
|
+
break;
|
|
5961
|
+
case "backoff":
|
|
5962
|
+
if (t20.isStringLiteral(prop.value)) result.backoff = prop.value.value;
|
|
5963
|
+
break;
|
|
5964
|
+
}
|
|
5965
|
+
}
|
|
5966
|
+
return result;
|
|
5967
|
+
}
|
|
5968
|
+
function extractMailbox(obj) {
|
|
5969
|
+
const result = {};
|
|
5970
|
+
for (const prop of obj.properties) {
|
|
5971
|
+
if (!t20.isObjectProperty(prop) || !t20.isIdentifier(prop.key)) continue;
|
|
5972
|
+
switch (prop.key.name) {
|
|
5973
|
+
case "capacity":
|
|
5974
|
+
if (t20.isNumericLiteral(prop.value)) result.capacity = prop.value.value;
|
|
5975
|
+
break;
|
|
5976
|
+
case "overflow":
|
|
5977
|
+
if (t20.isStringLiteral(prop.value)) result.overflow = prop.value.value;
|
|
5978
|
+
break;
|
|
5979
|
+
case "priority":
|
|
5980
|
+
if (t20.isStringLiteral(prop.value)) result.priority = prop.value.value;
|
|
5981
|
+
break;
|
|
5982
|
+
}
|
|
5983
|
+
}
|
|
5984
|
+
return result;
|
|
5985
|
+
}
|
|
5986
|
+
function extractStaticObj(obj) {
|
|
5987
|
+
const result = {};
|
|
5988
|
+
for (const prop of obj.properties) {
|
|
5989
|
+
if (!t20.isObjectProperty(prop) || !t20.isIdentifier(prop.key)) continue;
|
|
5990
|
+
const val = prop.value;
|
|
5991
|
+
if (t20.isStringLiteral(val)) result[prop.key.name] = val.value;
|
|
5992
|
+
else if (t20.isNumericLiteral(val)) result[prop.key.name] = val.value;
|
|
5993
|
+
else if (t20.isBooleanLiteral(val)) result[prop.key.name] = val.value;
|
|
5994
|
+
else if (t20.isNullLiteral(val)) result[prop.key.name] = null;
|
|
5995
|
+
}
|
|
5996
|
+
return result;
|
|
3490
5997
|
}
|
|
3491
5998
|
|
|
5999
|
+
// src/babel/emitters/pure-form-emitter.ts
|
|
6000
|
+
var import_player_core = require("@mmapp/player-core");
|
|
6001
|
+
|
|
3492
6002
|
// src/babel/emitters/experience-transform.ts
|
|
3493
6003
|
function transformToFrontend(node) {
|
|
3494
6004
|
const result = {
|
|
@@ -3706,7 +6216,7 @@ function normalizeViewNode(node, fieldNames) {
|
|
|
3706
6216
|
}
|
|
3707
6217
|
return node;
|
|
3708
6218
|
}
|
|
3709
|
-
function
|
|
6219
|
+
function toSnakeCase3(str) {
|
|
3710
6220
|
return str.replace(/([A-Z])/g, "_$1").toLowerCase().replace(/^_/, "");
|
|
3711
6221
|
}
|
|
3712
6222
|
function convertAction(action) {
|
|
@@ -3774,6 +6284,18 @@ function emitIR(extracted) {
|
|
|
3774
6284
|
});
|
|
3775
6285
|
stateNames.add(transition.to);
|
|
3776
6286
|
}
|
|
6287
|
+
for (const from of transition.from) {
|
|
6288
|
+
if (from && !stateNames.has(from)) {
|
|
6289
|
+
stateArray.push({
|
|
6290
|
+
name: from,
|
|
6291
|
+
type: "REGULAR",
|
|
6292
|
+
on_enter: [],
|
|
6293
|
+
during: [],
|
|
6294
|
+
on_exit: []
|
|
6295
|
+
});
|
|
6296
|
+
stateNames.add(from);
|
|
6297
|
+
}
|
|
6298
|
+
}
|
|
3777
6299
|
}
|
|
3778
6300
|
const fieldNames = new Set(fields.map((f) => f.name));
|
|
3779
6301
|
let normalizedView;
|
|
@@ -3789,7 +6311,7 @@ function emitIR(extracted) {
|
|
|
3789
6311
|
if (fields.length > 0) {
|
|
3790
6312
|
const localDefaults = {};
|
|
3791
6313
|
for (const f of fields) {
|
|
3792
|
-
localDefaults[
|
|
6314
|
+
localDefaults[toSnakeCase3(f.name)] = f.default_value ?? null;
|
|
3793
6315
|
}
|
|
3794
6316
|
if (!normalizedView.config) normalizedView.config = {};
|
|
3795
6317
|
normalizedView.config.localDefaults = localDefaults;
|
|
@@ -3868,7 +6390,7 @@ function liftAction(action) {
|
|
|
3868
6390
|
}
|
|
3869
6391
|
return {
|
|
3870
6392
|
slug: action.id,
|
|
3871
|
-
category: normalizeCategory("expression", "mutation", action.type),
|
|
6393
|
+
category: (0, import_player_core.normalizeCategory)("expression", "mutation", action.type),
|
|
3872
6394
|
parts: parts.length > 0 ? parts : void 0
|
|
3873
6395
|
};
|
|
3874
6396
|
}
|
|
@@ -3898,7 +6420,7 @@ function liftSchedule(during) {
|
|
|
3898
6420
|
for (const action of during.actions) {
|
|
3899
6421
|
parts.push({
|
|
3900
6422
|
slug: "do",
|
|
3901
|
-
category: normalizeCategory("expression", "mutation", action.type),
|
|
6423
|
+
category: (0, import_player_core.normalizeCategory)("expression", "mutation", action.type),
|
|
3902
6424
|
parts: Object.entries(action.config || {}).map(([key, value]) => ({
|
|
3903
6425
|
slug: key,
|
|
3904
6426
|
category: ["atom"],
|
|
@@ -3908,7 +6430,7 @@ function liftSchedule(during) {
|
|
|
3908
6430
|
}
|
|
3909
6431
|
return {
|
|
3910
6432
|
slug: during.id,
|
|
3911
|
-
category: normalizeCategory("schedule", during.type),
|
|
6433
|
+
category: (0, import_player_core.normalizeCategory)("schedule", during.type),
|
|
3912
6434
|
parts
|
|
3913
6435
|
};
|
|
3914
6436
|
}
|
|
@@ -3921,14 +6443,14 @@ function liftState(state) {
|
|
|
3921
6443
|
if (state.on_enter && state.on_enter.length > 0) {
|
|
3922
6444
|
parts.push({
|
|
3923
6445
|
slug: "on_enter",
|
|
3924
|
-
category: normalizeCategory("expression", "sequence"),
|
|
6446
|
+
category: (0, import_player_core.normalizeCategory)("expression", "sequence"),
|
|
3925
6447
|
parts: state.on_enter.map(liftAction)
|
|
3926
6448
|
});
|
|
3927
6449
|
}
|
|
3928
6450
|
if (state.on_exit && state.on_exit.length > 0) {
|
|
3929
6451
|
parts.push({
|
|
3930
6452
|
slug: "on_exit",
|
|
3931
|
-
category: normalizeCategory("expression", "sequence"),
|
|
6453
|
+
category: (0, import_player_core.normalizeCategory)("expression", "sequence"),
|
|
3932
6454
|
parts: state.on_exit.map(liftAction)
|
|
3933
6455
|
});
|
|
3934
6456
|
}
|
|
@@ -3939,7 +6461,7 @@ function liftState(state) {
|
|
|
3939
6461
|
}
|
|
3940
6462
|
return {
|
|
3941
6463
|
slug: state.name,
|
|
3942
|
-
category: normalizeCategory("state", ...tags),
|
|
6464
|
+
category: (0, import_player_core.normalizeCategory)("state", ...tags),
|
|
3943
6465
|
parts: parts.length > 0 ? parts : void 0
|
|
3944
6466
|
};
|
|
3945
6467
|
}
|
|
@@ -3962,17 +6484,17 @@ function liftTransition(transition) {
|
|
|
3962
6484
|
if (transition.actions && transition.actions.length > 0) {
|
|
3963
6485
|
parts.push({
|
|
3964
6486
|
slug: "actions",
|
|
3965
|
-
category: normalizeCategory("expression", "sequence"),
|
|
6487
|
+
category: (0, import_player_core.normalizeCategory)("expression", "sequence"),
|
|
3966
6488
|
parts: transition.actions.map(liftAction)
|
|
3967
6489
|
});
|
|
3968
6490
|
}
|
|
3969
6491
|
if (transition.conditions && transition.conditions.length > 0) {
|
|
3970
6492
|
parts.push({
|
|
3971
6493
|
slug: "conditions",
|
|
3972
|
-
category: normalizeCategory("expression", "guard"),
|
|
6494
|
+
category: (0, import_player_core.normalizeCategory)("expression", "guard"),
|
|
3973
6495
|
parts: transition.conditions.map((c, i) => ({
|
|
3974
6496
|
slug: `condition_${i}`,
|
|
3975
|
-
category: normalizeCategory("expression", c.type || "condition"),
|
|
6497
|
+
category: (0, import_player_core.normalizeCategory)("expression", c.type || "condition"),
|
|
3976
6498
|
parts: c.expression ? [{ slug: c.expression, category: ["binding"] }] : void 0
|
|
3977
6499
|
}))
|
|
3978
6500
|
});
|
|
@@ -4011,7 +6533,7 @@ function liftField(field) {
|
|
|
4011
6533
|
}
|
|
4012
6534
|
return {
|
|
4013
6535
|
slug: field.name,
|
|
4014
|
-
category: normalizeCategory("field", field.type),
|
|
6536
|
+
category: (0, import_player_core.normalizeCategory)("field", field.type),
|
|
4015
6537
|
parts: parts.length > 0 ? parts : void 0
|
|
4016
6538
|
};
|
|
4017
6539
|
}
|
|
@@ -4034,20 +6556,20 @@ function liftView(node) {
|
|
|
4034
6556
|
if (match) {
|
|
4035
6557
|
parts.push({
|
|
4036
6558
|
slug: key,
|
|
4037
|
-
category: normalizeCategory("expression", "effect", "transition"),
|
|
6559
|
+
category: (0, import_player_core.normalizeCategory)("expression", "effect", "transition"),
|
|
4038
6560
|
parts: [{ slug: match[1], category: ["ref"] }]
|
|
4039
6561
|
});
|
|
4040
6562
|
} else {
|
|
4041
6563
|
parts.push({
|
|
4042
6564
|
slug: key,
|
|
4043
|
-
category: normalizeCategory("expression", "binding"),
|
|
6565
|
+
category: (0, import_player_core.normalizeCategory)("expression", "binding"),
|
|
4044
6566
|
parts: [{ slug: String(expr), category: ["binding"] }]
|
|
4045
6567
|
});
|
|
4046
6568
|
}
|
|
4047
6569
|
} else {
|
|
4048
6570
|
parts.push({
|
|
4049
6571
|
slug: key,
|
|
4050
|
-
category: normalizeCategory("expression", "binding"),
|
|
6572
|
+
category: (0, import_player_core.normalizeCategory)("expression", "binding"),
|
|
4051
6573
|
parts: [{ slug: String(expr), category: ["binding"] }]
|
|
4052
6574
|
});
|
|
4053
6575
|
}
|
|
@@ -4058,20 +6580,20 @@ function liftView(node) {
|
|
|
4058
6580
|
if (eqMatch) {
|
|
4059
6581
|
parts.push({
|
|
4060
6582
|
slug: "visible_when",
|
|
4061
|
-
category: normalizeCategory("expression", "guard"),
|
|
6583
|
+
category: (0, import_player_core.normalizeCategory)("expression", "guard"),
|
|
4062
6584
|
parts: [{
|
|
4063
6585
|
slug: "body",
|
|
4064
|
-
category: normalizeCategory("expression", "eq"),
|
|
6586
|
+
category: (0, import_player_core.normalizeCategory)("expression", "eq"),
|
|
4065
6587
|
parts: [
|
|
4066
|
-
{ slug: "lhs", category: normalizeCategory("expression", "path"), parts: [{ slug: eqMatch[1], category: ["binding"] }] },
|
|
4067
|
-
{ slug: "rhs", category: normalizeCategory("expression", "literal"), parts: [{ slug: eqMatch[2], category: ["literal"] }] }
|
|
6588
|
+
{ slug: "lhs", category: (0, import_player_core.normalizeCategory)("expression", "path"), parts: [{ slug: eqMatch[1], category: ["binding"] }] },
|
|
6589
|
+
{ slug: "rhs", category: (0, import_player_core.normalizeCategory)("expression", "literal"), parts: [{ slug: eqMatch[2], category: ["literal"] }] }
|
|
4068
6590
|
]
|
|
4069
6591
|
}]
|
|
4070
6592
|
});
|
|
4071
6593
|
} else {
|
|
4072
6594
|
parts.push({
|
|
4073
6595
|
slug: "visible_when",
|
|
4074
|
-
category: normalizeCategory("expression", "guard"),
|
|
6596
|
+
category: (0, import_player_core.normalizeCategory)("expression", "guard"),
|
|
4075
6597
|
parts: [{ slug: node.visible_when, category: ["binding"] }]
|
|
4076
6598
|
});
|
|
4077
6599
|
}
|
|
@@ -4083,7 +6605,7 @@ function liftView(node) {
|
|
|
4083
6605
|
}
|
|
4084
6606
|
return {
|
|
4085
6607
|
slug: node.id,
|
|
4086
|
-
category: normalizeCategory("view", componentTag),
|
|
6608
|
+
category: (0, import_player_core.normalizeCategory)("view", componentTag),
|
|
4087
6609
|
parts: parts.length > 0 ? parts : void 0
|
|
4088
6610
|
};
|
|
4089
6611
|
}
|
|
@@ -4104,7 +6626,7 @@ function emitCanonical(extracted, sourceFilename) {
|
|
|
4104
6626
|
}
|
|
4105
6627
|
parts.push({
|
|
4106
6628
|
slug: "manifest",
|
|
4107
|
-
category: normalizeCategory("meta", "manifest"),
|
|
6629
|
+
category: (0, import_player_core.normalizeCategory)("meta", "manifest"),
|
|
4108
6630
|
parts: [
|
|
4109
6631
|
{
|
|
4110
6632
|
slug: "workflows",
|
|
@@ -4125,7 +6647,7 @@ function emitCanonical(extracted, sourceFilename) {
|
|
|
4125
6647
|
let categoryArray;
|
|
4126
6648
|
if (category.includes("/")) {
|
|
4127
6649
|
const [primary, ...tags] = category.split("/");
|
|
4128
|
-
categoryArray = normalizeCategory(primary, ...tags);
|
|
6650
|
+
categoryArray = (0, import_player_core.normalizeCategory)(primary, ...tags);
|
|
4129
6651
|
} else {
|
|
4130
6652
|
categoryArray = [category];
|
|
4131
6653
|
}
|
|
@@ -4187,7 +6709,7 @@ function emitWorkflowDefinition(extracted) {
|
|
|
4187
6709
|
on_event: (s.on_event || []).map(convertOnEvent)
|
|
4188
6710
|
}));
|
|
4189
6711
|
const fields = ir.fields.map((f) => ({
|
|
4190
|
-
name:
|
|
6712
|
+
name: toSnakeCase3(f.name),
|
|
4191
6713
|
field_type: f.type,
|
|
4192
6714
|
label: f.label || f.name.replace(/([A-Z])/g, " $1").replace(/^./, (c) => c.toUpperCase()),
|
|
4193
6715
|
required: f.required || false,
|
|
@@ -4203,16 +6725,16 @@ function emitWorkflowDefinition(extracted) {
|
|
|
4203
6725
|
...f.editable_when && { editable_when: f.editable_when },
|
|
4204
6726
|
...f.state_home && { state_home: f.state_home }
|
|
4205
6727
|
}));
|
|
4206
|
-
const transitions = ir.transitions.map((
|
|
4207
|
-
name:
|
|
4208
|
-
from:
|
|
4209
|
-
to:
|
|
4210
|
-
description:
|
|
4211
|
-
roles:
|
|
4212
|
-
auto:
|
|
4213
|
-
conditions:
|
|
4214
|
-
actions: (
|
|
4215
|
-
required_fields:
|
|
6728
|
+
const transitions = ir.transitions.map((t22) => ({
|
|
6729
|
+
name: t22.name,
|
|
6730
|
+
from: t22.from,
|
|
6731
|
+
to: t22.to,
|
|
6732
|
+
description: t22.description || "",
|
|
6733
|
+
roles: t22.roles || [],
|
|
6734
|
+
auto: t22.auto || false,
|
|
6735
|
+
conditions: t22.conditions || [],
|
|
6736
|
+
actions: (t22.actions || []).map(convertAction),
|
|
6737
|
+
required_fields: t22.required_fields || [],
|
|
4216
6738
|
priority: 0
|
|
4217
6739
|
}));
|
|
4218
6740
|
const state_data = {};
|
|
@@ -4230,7 +6752,7 @@ function emitWorkflowDefinition(extracted) {
|
|
|
4230
6752
|
if (extracted.fields.length > 0) {
|
|
4231
6753
|
const localDefaults = {};
|
|
4232
6754
|
for (const f of extracted.fields) {
|
|
4233
|
-
localDefaults[
|
|
6755
|
+
localDefaults[toSnakeCase3(f.name)] = f.default_value ?? null;
|
|
4234
6756
|
}
|
|
4235
6757
|
if (!viewRoot.config) viewRoot.config = {};
|
|
4236
6758
|
viewRoot.config.localDefaults = localDefaults;
|
|
@@ -4293,8 +6815,8 @@ function compilerStateToWorkflow(state, metadata) {
|
|
|
4293
6815
|
function resolveSlugArg(args, state) {
|
|
4294
6816
|
if (args.length < 1) return null;
|
|
4295
6817
|
const slugArg = args[0];
|
|
4296
|
-
if (
|
|
4297
|
-
if (
|
|
6818
|
+
if (t21.isStringLiteral(slugArg)) return slugArg.value;
|
|
6819
|
+
if (t21.isIdentifier(slugArg)) {
|
|
4298
6820
|
const compilerState = state;
|
|
4299
6821
|
const meta = compilerState.metadata;
|
|
4300
6822
|
const resolvedSlugs = meta.__modelImportSlugs;
|
|
@@ -4320,43 +6842,43 @@ function extractQueryDataSource(path, state) {
|
|
|
4320
6842
|
slug,
|
|
4321
6843
|
query: "list"
|
|
4322
6844
|
};
|
|
4323
|
-
if (args.length > 1 &&
|
|
6845
|
+
if (args.length > 1 && t21.isObjectExpression(args[1])) {
|
|
4324
6846
|
for (const prop of args[1].properties) {
|
|
4325
|
-
if (!
|
|
6847
|
+
if (!t21.isObjectProperty(prop) || !t21.isIdentifier(prop.key)) continue;
|
|
4326
6848
|
const key = prop.key.name;
|
|
4327
6849
|
const val = prop.value;
|
|
4328
6850
|
switch (key) {
|
|
4329
6851
|
case "limit":
|
|
4330
|
-
if (
|
|
6852
|
+
if (t21.isNumericLiteral(val)) {
|
|
4331
6853
|
dataSource.pageSize = val.value;
|
|
4332
6854
|
dataSource.paginated = true;
|
|
4333
6855
|
}
|
|
4334
6856
|
break;
|
|
4335
6857
|
case "orderBy":
|
|
4336
|
-
if (
|
|
6858
|
+
if (t21.isStringLiteral(val)) {
|
|
4337
6859
|
dataSource.sort = val.value;
|
|
4338
6860
|
}
|
|
4339
6861
|
break;
|
|
4340
6862
|
case "order":
|
|
4341
|
-
if (
|
|
6863
|
+
if (t21.isStringLiteral(val) && dataSource.sort) {
|
|
4342
6864
|
dataSource.sort = `${dataSource.sort}:${val.value}`;
|
|
4343
6865
|
}
|
|
4344
6866
|
break;
|
|
4345
6867
|
case "search":
|
|
4346
|
-
if (
|
|
6868
|
+
if (t21.isStringLiteral(val)) {
|
|
4347
6869
|
dataSource.search = val.value;
|
|
4348
6870
|
}
|
|
4349
6871
|
break;
|
|
4350
6872
|
case "searchFields":
|
|
4351
|
-
if (
|
|
4352
|
-
dataSource.searchFields = val.elements.filter((el) =>
|
|
6873
|
+
if (t21.isArrayExpression(val)) {
|
|
6874
|
+
dataSource.searchFields = val.elements.filter((el) => t21.isStringLiteral(el)).map((el) => el.value);
|
|
4353
6875
|
}
|
|
4354
6876
|
break;
|
|
4355
6877
|
case "filter":
|
|
4356
|
-
if (
|
|
6878
|
+
if (t21.isObjectExpression(val)) {
|
|
4357
6879
|
const filter = {};
|
|
4358
6880
|
for (const fp of val.properties) {
|
|
4359
|
-
if (
|
|
6881
|
+
if (t21.isObjectProperty(fp) && t21.isIdentifier(fp.key) && t21.isStringLiteral(fp.value)) {
|
|
4360
6882
|
filter[fp.key.name] = fp.value.value;
|
|
4361
6883
|
}
|
|
4362
6884
|
}
|
|
@@ -4366,19 +6888,19 @@ function extractQueryDataSource(path, state) {
|
|
|
4366
6888
|
}
|
|
4367
6889
|
break;
|
|
4368
6890
|
case "state":
|
|
4369
|
-
if (
|
|
6891
|
+
if (t21.isStringLiteral(val)) {
|
|
4370
6892
|
if (!dataSource.filter) dataSource.filter = {};
|
|
4371
6893
|
dataSource.filter.current_state = val.value;
|
|
4372
6894
|
}
|
|
4373
6895
|
break;
|
|
4374
6896
|
case "groupBy":
|
|
4375
|
-
if (
|
|
6897
|
+
if (t21.isStringLiteral(val)) {
|
|
4376
6898
|
dataSource.groupBy = val.value;
|
|
4377
6899
|
}
|
|
4378
6900
|
break;
|
|
4379
6901
|
case "facets":
|
|
4380
|
-
if (
|
|
4381
|
-
dataSource.facets = val.elements.filter((el) =>
|
|
6902
|
+
if (t21.isArrayExpression(val)) {
|
|
6903
|
+
dataSource.facets = val.elements.filter((el) => t21.isStringLiteral(el)).map((el) => el.value);
|
|
4382
6904
|
}
|
|
4383
6905
|
break;
|
|
4384
6906
|
}
|
|
@@ -4402,17 +6924,17 @@ function extractMutationDataSource(path, state) {
|
|
|
4402
6924
|
}
|
|
4403
6925
|
function extractDuringAction(path, state) {
|
|
4404
6926
|
const args = path.node.arguments;
|
|
4405
|
-
if (args.length < 1 || !
|
|
6927
|
+
if (args.length < 1 || !t21.isObjectExpression(args[0])) return;
|
|
4406
6928
|
const compilerState = state;
|
|
4407
6929
|
const config = args[0];
|
|
4408
6930
|
let stateName;
|
|
4409
6931
|
let intervalMs = 1e3;
|
|
4410
6932
|
for (const prop of config.properties) {
|
|
4411
|
-
if (!
|
|
4412
|
-
if (prop.key.name === "state" &&
|
|
6933
|
+
if (!t21.isObjectProperty(prop) || !t21.isIdentifier(prop.key)) continue;
|
|
6934
|
+
if (prop.key.name === "state" && t21.isStringLiteral(prop.value)) {
|
|
4413
6935
|
stateName = prop.value.value;
|
|
4414
6936
|
}
|
|
4415
|
-
if (prop.key.name === "intervalMs" &&
|
|
6937
|
+
if (prop.key.name === "intervalMs" && t21.isNumericLiteral(prop.value)) {
|
|
4416
6938
|
intervalMs = prop.value.value;
|
|
4417
6939
|
}
|
|
4418
6940
|
}
|
|
@@ -4438,7 +6960,7 @@ function extractDuringAction(path, state) {
|
|
|
4438
6960
|
}
|
|
4439
6961
|
function extractRoleDependency(path, state) {
|
|
4440
6962
|
const args = path.node.arguments;
|
|
4441
|
-
if (args.length < 1 || !
|
|
6963
|
+
if (args.length < 1 || !t21.isStringLiteral(args[0])) return;
|
|
4442
6964
|
const compilerState = state;
|
|
4443
6965
|
if (!compilerState.metadata) compilerState.metadata = {};
|
|
4444
6966
|
const meta = compilerState.metadata;
|
|
@@ -4449,7 +6971,7 @@ function extractRoleDependency(path, state) {
|
|
|
4449
6971
|
}
|
|
4450
6972
|
function extractViewDependency(path, state) {
|
|
4451
6973
|
const args = path.node.arguments;
|
|
4452
|
-
if (args.length < 1 || !
|
|
6974
|
+
if (args.length < 1 || !t21.isStringLiteral(args[0])) return;
|
|
4453
6975
|
const compilerState = state;
|
|
4454
6976
|
if (!compilerState.metadata) compilerState.metadata = {};
|
|
4455
6977
|
const meta = compilerState.metadata;
|
|
@@ -4466,7 +6988,7 @@ function extractParamsUsage(_path, state) {
|
|
|
4466
6988
|
}
|
|
4467
6989
|
function extractLibraryDependency(path, state) {
|
|
4468
6990
|
const args = path.node.arguments;
|
|
4469
|
-
if (args.length < 1 || !
|
|
6991
|
+
if (args.length < 1 || !t21.isStringLiteral(args[0])) return;
|
|
4470
6992
|
const compilerState = state;
|
|
4471
6993
|
if (!compilerState.metadata) compilerState.metadata = {};
|
|
4472
6994
|
const meta = compilerState.metadata;
|
|
@@ -4546,15 +7068,15 @@ function createVisitor(options = {}) {
|
|
|
4546
7068
|
}
|
|
4547
7069
|
}
|
|
4548
7070
|
const exportDeclaration = program.body.find(
|
|
4549
|
-
(node) =>
|
|
7071
|
+
(node) => t21.isExportNamedDeclaration(node) || t21.isExportDefaultDeclaration(node)
|
|
4550
7072
|
);
|
|
4551
7073
|
if (exportDeclaration) {
|
|
4552
7074
|
if (exportDeclaration.leadingComments) {
|
|
4553
7075
|
extractMetadataFromComments(exportDeclaration.leadingComments, compilerState.metadata);
|
|
4554
7076
|
}
|
|
4555
|
-
if (
|
|
7077
|
+
if (t21.isExportNamedDeclaration(exportDeclaration)) {
|
|
4556
7078
|
const declaration = exportDeclaration.declaration;
|
|
4557
|
-
if (
|
|
7079
|
+
if (t21.isFunctionDeclaration(declaration)) {
|
|
4558
7080
|
if (declaration.id) {
|
|
4559
7081
|
compilerState.metadata.name = declaration.id.name;
|
|
4560
7082
|
}
|
|
@@ -4562,16 +7084,16 @@ function createVisitor(options = {}) {
|
|
|
4562
7084
|
extractMetadataFromComments(declaration.leadingComments, compilerState.metadata);
|
|
4563
7085
|
}
|
|
4564
7086
|
}
|
|
4565
|
-
} else if (
|
|
7087
|
+
} else if (t21.isExportDefaultDeclaration(exportDeclaration)) {
|
|
4566
7088
|
const declaration = exportDeclaration.declaration;
|
|
4567
|
-
if (
|
|
7089
|
+
if (t21.isFunctionDeclaration(declaration)) {
|
|
4568
7090
|
if (declaration.id) {
|
|
4569
7091
|
compilerState.metadata.name = declaration.id.name;
|
|
4570
7092
|
}
|
|
4571
7093
|
if (declaration.leadingComments) {
|
|
4572
7094
|
extractMetadataFromComments(declaration.leadingComments, compilerState.metadata);
|
|
4573
7095
|
}
|
|
4574
|
-
} else if (
|
|
7096
|
+
} else if (t21.isIdentifier(declaration)) {
|
|
4575
7097
|
compilerState.metadata.name = declaration.name;
|
|
4576
7098
|
}
|
|
4577
7099
|
}
|
|
@@ -4582,7 +7104,13 @@ function createVisitor(options = {}) {
|
|
|
4582
7104
|
compilerState.metadata.__slugAutoFallback = true;
|
|
4583
7105
|
}
|
|
4584
7106
|
Object.assign(state, compilerState);
|
|
4585
|
-
if (
|
|
7107
|
+
if (isImperativeWorkflowFile(_path, state.filename)) {
|
|
7108
|
+
extractImperativeWorkflow(_path, state);
|
|
7109
|
+
state.__isModelFile = true;
|
|
7110
|
+
if (!compilerState.metadata.category) {
|
|
7111
|
+
compilerState.metadata.category = "workflow";
|
|
7112
|
+
}
|
|
7113
|
+
} else if (isModelFile(_path, state.filename)) {
|
|
4586
7114
|
extractModelFile(_path, state);
|
|
4587
7115
|
state.__isModelFile = true;
|
|
4588
7116
|
if (!compilerState.metadata.category) {
|
|
@@ -4593,6 +7121,15 @@ function createVisitor(options = {}) {
|
|
|
4593
7121
|
if (hasContextCreation(_path)) {
|
|
4594
7122
|
extractContextWorkflows(_path, state);
|
|
4595
7123
|
}
|
|
7124
|
+
if (hasMiddleware(_path)) {
|
|
7125
|
+
extractMiddleware(_path, state);
|
|
7126
|
+
}
|
|
7127
|
+
if (hasConstraints(_path)) {
|
|
7128
|
+
extractConstraints(_path, state);
|
|
7129
|
+
}
|
|
7130
|
+
if (hasActorConfig(_path)) {
|
|
7131
|
+
extractActorConfig(_path, state);
|
|
7132
|
+
}
|
|
4596
7133
|
if (isServerActionFile(state.filename)) {
|
|
4597
7134
|
extractServerActions(_path, state);
|
|
4598
7135
|
state.__isServerActionFile = true;
|
|
@@ -4628,13 +7165,13 @@ function createVisitor(options = {}) {
|
|
|
4628
7165
|
// Main hook extraction dispatcher
|
|
4629
7166
|
CallExpression(path, state) {
|
|
4630
7167
|
const callee = path.node.callee;
|
|
4631
|
-
if (!
|
|
7168
|
+
if (!t21.isIdentifier(callee)) return;
|
|
4632
7169
|
const compilerState = state;
|
|
4633
7170
|
const hookName = callee.name;
|
|
4634
7171
|
if (mode === "strict" && STRICT_BANNED_HOOKS[hookName]) {
|
|
4635
7172
|
const error = {
|
|
4636
7173
|
code: STRICT_BANNED_HOOKS[hookName],
|
|
4637
|
-
message: `${hookName}() is not allowed in strict mode. Use @
|
|
7174
|
+
message: `${hookName}() is not allowed in strict mode. Use @mmapp/react effect hooks instead.`,
|
|
4638
7175
|
line: path.node.loc?.start.line,
|
|
4639
7176
|
column: path.node.loc?.start.column,
|
|
4640
7177
|
severity: "error"
|
|
@@ -4720,18 +7257,18 @@ function createVisitor(options = {}) {
|
|
|
4720
7257
|
if (!meta.__modelImports) meta.__modelImports = {};
|
|
4721
7258
|
const imports = meta.__modelImports;
|
|
4722
7259
|
for (const specifier of path.node.specifiers) {
|
|
4723
|
-
if (
|
|
7260
|
+
if (t21.isImportDefaultSpecifier(specifier) || t21.isImportSpecifier(specifier)) {
|
|
4724
7261
|
imports[specifier.local.name] = source;
|
|
4725
7262
|
}
|
|
4726
7263
|
}
|
|
4727
7264
|
}
|
|
4728
7265
|
if (mode !== "strict") return;
|
|
4729
|
-
if (source.startsWith("@
|
|
7266
|
+
if (source.startsWith("@mmapp/") || source.startsWith("@mmapp/") || source === "react" || source.startsWith("react/") || source.startsWith(".") || source.startsWith("/")) {
|
|
4730
7267
|
return;
|
|
4731
7268
|
}
|
|
4732
7269
|
const error = {
|
|
4733
7270
|
code: "STRICT_FORBIDDEN_IMPORT",
|
|
4734
|
-
message: `Import from '${source}' is not allowed in strict mode. Only @
|
|
7271
|
+
message: `Import from '${source}' is not allowed in strict mode. Only @mmapp/* and relative imports are permitted.`,
|
|
4735
7272
|
line: path.node.loc?.start.line,
|
|
4736
7273
|
column: path.node.loc?.start.column,
|
|
4737
7274
|
severity: "error"
|
|
@@ -4753,8 +7290,8 @@ function createVisitor(options = {}) {
|
|
|
4753
7290
|
if (!compilerState.metadata) return;
|
|
4754
7291
|
const id = path.node.id;
|
|
4755
7292
|
const init = path.node.init;
|
|
4756
|
-
if (
|
|
4757
|
-
if (!
|
|
7293
|
+
if (t21.isArrayPattern(id)) return;
|
|
7294
|
+
if (!t21.isIdentifier(id) || !init || !t21.isExpression(init)) return;
|
|
4758
7295
|
const parentFn = path.getFunctionParent();
|
|
4759
7296
|
if (!parentFn) return;
|
|
4760
7297
|
const parentNode = parentFn.parentPath;
|
|
@@ -4762,17 +7299,17 @@ function createVisitor(options = {}) {
|
|
|
4762
7299
|
let isExportedByName = false;
|
|
4763
7300
|
if (!isExportedDirectly && parentNode?.isVariableDeclarator()) {
|
|
4764
7301
|
const varId = parentNode.node.id;
|
|
4765
|
-
if (
|
|
7302
|
+
if (t21.isIdentifier(varId)) {
|
|
4766
7303
|
isExportedByName = varId.name === compilerState.metadata?.name;
|
|
4767
7304
|
}
|
|
4768
7305
|
}
|
|
4769
7306
|
if (!isExportedDirectly && !isExportedByName) return;
|
|
4770
|
-
if (
|
|
7307
|
+
if (t21.isCallExpression(init) && t21.isIdentifier(init.callee)) {
|
|
4771
7308
|
const callee = init.callee.name;
|
|
4772
7309
|
if (callee === "useQuery") {
|
|
4773
|
-
registerDerivedVar(id.name,
|
|
4774
|
-
|
|
4775
|
-
|
|
7310
|
+
registerDerivedVar(id.name, t21.optionalMemberExpression(
|
|
7311
|
+
t21.identifier("$instance"),
|
|
7312
|
+
t21.identifier(id.name),
|
|
4776
7313
|
false,
|
|
4777
7314
|
// computed
|
|
4778
7315
|
true
|
|
@@ -4781,23 +7318,23 @@ function createVisitor(options = {}) {
|
|
|
4781
7318
|
return;
|
|
4782
7319
|
}
|
|
4783
7320
|
if (callee === "useMutation") {
|
|
4784
|
-
registerDerivedVar(id.name,
|
|
4785
|
-
|
|
4786
|
-
|
|
7321
|
+
registerDerivedVar(id.name, t21.memberExpression(
|
|
7322
|
+
t21.identifier("$action"),
|
|
7323
|
+
t21.identifier("transition")
|
|
4787
7324
|
));
|
|
4788
7325
|
return;
|
|
4789
7326
|
}
|
|
4790
7327
|
if (callee === "useServerAction") {
|
|
4791
|
-
registerDerivedVar(id.name,
|
|
4792
|
-
|
|
4793
|
-
|
|
7328
|
+
registerDerivedVar(id.name, t21.memberExpression(
|
|
7329
|
+
t21.identifier("$action"),
|
|
7330
|
+
t21.identifier("serverAction")
|
|
4794
7331
|
));
|
|
4795
7332
|
return;
|
|
4796
7333
|
}
|
|
4797
7334
|
if (callee === "useServerState") {
|
|
4798
|
-
registerDerivedVar(id.name,
|
|
4799
|
-
|
|
4800
|
-
|
|
7335
|
+
registerDerivedVar(id.name, t21.optionalMemberExpression(
|
|
7336
|
+
t21.identifier("$instance"),
|
|
7337
|
+
t21.identifier("serverState"),
|
|
4801
7338
|
false,
|
|
4802
7339
|
true
|
|
4803
7340
|
));
|
|
@@ -4805,12 +7342,12 @@ function createVisitor(options = {}) {
|
|
|
4805
7342
|
}
|
|
4806
7343
|
if (callee === "useMemo" && init.arguments.length >= 1) {
|
|
4807
7344
|
const callback = init.arguments[0];
|
|
4808
|
-
if (
|
|
4809
|
-
if (
|
|
7345
|
+
if (t21.isArrowFunctionExpression(callback)) {
|
|
7346
|
+
if (t21.isExpression(callback.body)) {
|
|
4810
7347
|
registerDerivedVar(id.name, callback.body);
|
|
4811
|
-
} else if (
|
|
4812
|
-
const retStmt = callback.body.body.find((s) =>
|
|
4813
|
-
if (retStmt?.argument &&
|
|
7348
|
+
} else if (t21.isBlockStatement(callback.body)) {
|
|
7349
|
+
const retStmt = callback.body.body.find((s) => t21.isReturnStatement(s));
|
|
7350
|
+
if (retStmt?.argument && t21.isExpression(retStmt.argument)) {
|
|
4814
7351
|
registerDerivedVar(id.name, retStmt.argument);
|
|
4815
7352
|
}
|
|
4816
7353
|
}
|
|
@@ -4825,7 +7362,7 @@ function createVisitor(options = {}) {
|
|
|
4825
7362
|
// Only extract from the exported component function's direct return,
|
|
4826
7363
|
// not from nested callbacks (Each render functions, helper components, etc.).
|
|
4827
7364
|
ReturnStatement(path, state) {
|
|
4828
|
-
if (!
|
|
7365
|
+
if (!t21.isJSXElement(path.node.argument) && !t21.isJSXFragment(path.node.argument)) return;
|
|
4829
7366
|
const parentFn = path.getFunctionParent();
|
|
4830
7367
|
if (!parentFn) return;
|
|
4831
7368
|
const parentNode = parentFn.parentPath;
|
|
@@ -4833,7 +7370,7 @@ function createVisitor(options = {}) {
|
|
|
4833
7370
|
let isExportedByName = false;
|
|
4834
7371
|
if (!isExportedDirectly && parentNode?.isVariableDeclarator()) {
|
|
4835
7372
|
const varId = parentNode.node.id;
|
|
4836
|
-
if (
|
|
7373
|
+
if (t21.isIdentifier(varId)) {
|
|
4837
7374
|
isExportedByName = varId.name === state.metadata?.name;
|
|
4838
7375
|
}
|
|
4839
7376
|
}
|