@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/testing/index.js
CHANGED
|
@@ -49,7 +49,7 @@ module.exports = __toCommonJS(testing_exports);
|
|
|
49
49
|
var import_core = require("@babel/core");
|
|
50
50
|
|
|
51
51
|
// src/babel/visitor.ts
|
|
52
|
-
var
|
|
52
|
+
var t21 = __toESM(require("@babel/types"));
|
|
53
53
|
|
|
54
54
|
// src/babel/extractors/state-extractor.ts
|
|
55
55
|
var t = __toESM(require("@babel/types"));
|
|
@@ -455,25 +455,25 @@ function inferTransitionStates(transitions, states) {
|
|
|
455
455
|
const stateArray = Array.from(states.values());
|
|
456
456
|
const startStates = stateArray.filter((s) => s.type === "START");
|
|
457
457
|
const regularStates = stateArray.filter((s) => s.type === "REGULAR");
|
|
458
|
-
const needsInference = transitions.filter((
|
|
458
|
+
const needsInference = transitions.filter((t22) => t22.from.length === 0 || !t22.to);
|
|
459
459
|
if (needsInference.length === 0) return;
|
|
460
460
|
if (startStates.length === 1 && regularStates.length > 0) {
|
|
461
|
-
needsInference.forEach((
|
|
462
|
-
if (
|
|
463
|
-
|
|
461
|
+
needsInference.forEach((t22, idx) => {
|
|
462
|
+
if (t22.from.length === 0) {
|
|
463
|
+
t22.from = [startStates[0].name];
|
|
464
464
|
}
|
|
465
|
-
if (!
|
|
466
|
-
|
|
465
|
+
if (!t22.to) {
|
|
466
|
+
t22.to = regularStates[idx % regularStates.length]?.name || startStates[0].name;
|
|
467
467
|
}
|
|
468
468
|
});
|
|
469
469
|
} else {
|
|
470
470
|
const allStateNames = stateArray.map((s) => s.name);
|
|
471
|
-
needsInference.forEach((
|
|
472
|
-
if (
|
|
473
|
-
|
|
471
|
+
needsInference.forEach((t22, idx) => {
|
|
472
|
+
if (t22.from.length === 0 && allStateNames.length > 0) {
|
|
473
|
+
t22.from = [allStateNames[0]];
|
|
474
474
|
}
|
|
475
|
-
if (!
|
|
476
|
-
|
|
475
|
+
if (!t22.to && allStateNames.length > 1) {
|
|
476
|
+
t22.to = allStateNames[Math.min(idx + 1, allStateNames.length - 1)];
|
|
477
477
|
}
|
|
478
478
|
});
|
|
479
479
|
}
|
|
@@ -663,6 +663,8 @@ var TranspileContext = class {
|
|
|
663
663
|
this.localFieldMap = options.localFieldMap ?? /* @__PURE__ */ new Map();
|
|
664
664
|
this.derivedVarMap = options.derivedVarMap ?? /* @__PURE__ */ new Map();
|
|
665
665
|
this.setterToFieldMap = options.setterToFieldMap ?? /* @__PURE__ */ new Map();
|
|
666
|
+
this.parameterMap = options.parameterMap ?? /* @__PURE__ */ new Map();
|
|
667
|
+
this.allMutable = options.allMutable ?? false;
|
|
666
668
|
}
|
|
667
669
|
/**
|
|
668
670
|
* Emit an opaque JS fallback, marking the result as impure.
|
|
@@ -684,6 +686,8 @@ var TranspileContext = class {
|
|
|
684
686
|
if (snakeName) return `$local.${snakeName}`;
|
|
685
687
|
const derivedInit = this.derivedVarMap.get(node.name);
|
|
686
688
|
if (derivedInit) return `(${this.visit(derivedInit)})`;
|
|
689
|
+
const paramField = this.parameterMap.get(node.name);
|
|
690
|
+
if (paramField) return paramField;
|
|
687
691
|
if (node.name === "undefined") return "null";
|
|
688
692
|
if (node.name === "NaN") return "null";
|
|
689
693
|
if (node.name === "Infinity") return "null";
|
|
@@ -731,6 +735,9 @@ var TranspileContext = class {
|
|
|
731
735
|
if (t5.isNewExpression(node)) {
|
|
732
736
|
return this.visitNew(node);
|
|
733
737
|
}
|
|
738
|
+
if (t5.isAssignmentExpression(node) && node.operator === "=" && t5.isIdentifier(node.left)) {
|
|
739
|
+
return `${node.left.name} = ${this.visit(node.right)}`;
|
|
740
|
+
}
|
|
734
741
|
return this.opaque(fallbackGenerate(node));
|
|
735
742
|
}
|
|
736
743
|
// ---------------------------------------------------------------------------
|
|
@@ -931,6 +938,11 @@ var TranspileContext = class {
|
|
|
931
938
|
return this.visitArrayHigherOrder("some", obj, args);
|
|
932
939
|
case "every":
|
|
933
940
|
return this.visitArrayHigherOrder("every", obj, args);
|
|
941
|
+
// --- Array push: arr.push(item) → arr = push(arr, item) ---
|
|
942
|
+
case "push": {
|
|
943
|
+
const [item] = this.visitArgsList(args);
|
|
944
|
+
return `${obj} = push(${obj}, ${item})`;
|
|
945
|
+
}
|
|
934
946
|
// --- Array mutation-free methods ---
|
|
935
947
|
case "reverse":
|
|
936
948
|
return `reverse(${obj})`;
|
|
@@ -2766,6 +2778,71 @@ function modelStateTypeToIR(type) {
|
|
|
2766
2778
|
if (type === "final") return "END";
|
|
2767
2779
|
return "REGULAR";
|
|
2768
2780
|
}
|
|
2781
|
+
function parseActionArray(raw, actionCounter) {
|
|
2782
|
+
if (!Array.isArray(raw)) return [];
|
|
2783
|
+
const actions = [];
|
|
2784
|
+
for (const item of raw) {
|
|
2785
|
+
if (typeof item !== "object" || item === null) continue;
|
|
2786
|
+
const a = item;
|
|
2787
|
+
actions.push({
|
|
2788
|
+
id: a.id ? String(a.id) : `auto_${++actionCounter.value}`,
|
|
2789
|
+
type: String(a.type || a.action_type || "unknown"),
|
|
2790
|
+
mode: a.mode || "auto",
|
|
2791
|
+
config: a.config && typeof a.config === "object" ? a.config : {},
|
|
2792
|
+
...a.condition ? { condition: String(a.condition) } : {}
|
|
2793
|
+
});
|
|
2794
|
+
}
|
|
2795
|
+
return actions;
|
|
2796
|
+
}
|
|
2797
|
+
function parseDuringArray(raw, actionCounter) {
|
|
2798
|
+
if (!Array.isArray(raw)) return [];
|
|
2799
|
+
const result = [];
|
|
2800
|
+
for (const item of raw) {
|
|
2801
|
+
if (typeof item !== "object" || item === null) continue;
|
|
2802
|
+
const d = item;
|
|
2803
|
+
result.push({
|
|
2804
|
+
id: d.id ? String(d.id) : `during_${++actionCounter.value}`,
|
|
2805
|
+
type: d.type || "interval",
|
|
2806
|
+
...d.interval_ms != null ? { interval_ms: Number(d.interval_ms) } : {},
|
|
2807
|
+
...d.cron ? { cron: String(d.cron) } : {},
|
|
2808
|
+
...d.delay_ms != null ? { delay_ms: Number(d.delay_ms) } : {},
|
|
2809
|
+
...d.condition ? { condition: String(d.condition) } : {},
|
|
2810
|
+
actions: parseActionArray(d.actions, actionCounter)
|
|
2811
|
+
});
|
|
2812
|
+
}
|
|
2813
|
+
return result;
|
|
2814
|
+
}
|
|
2815
|
+
function parseOnEventArray(raw, actionCounter) {
|
|
2816
|
+
if (!Array.isArray(raw)) return [];
|
|
2817
|
+
const result = [];
|
|
2818
|
+
for (const item of raw) {
|
|
2819
|
+
if (typeof item !== "object" || item === null) continue;
|
|
2820
|
+
const e = item;
|
|
2821
|
+
const actions = [];
|
|
2822
|
+
if (Array.isArray(e.actions)) {
|
|
2823
|
+
for (const a of e.actions) {
|
|
2824
|
+
if (typeof a !== "object" || a === null) continue;
|
|
2825
|
+
const act = a;
|
|
2826
|
+
actions.push({
|
|
2827
|
+
type: act.type || "set_field",
|
|
2828
|
+
...act.field ? { field: String(act.field) } : {},
|
|
2829
|
+
...act.expression ? { expression: String(act.expression) } : {},
|
|
2830
|
+
...act.key ? { key: String(act.key) } : {},
|
|
2831
|
+
...act.message ? { message: String(act.message) } : {},
|
|
2832
|
+
...act.config && typeof act.config === "object" ? { config: act.config } : {},
|
|
2833
|
+
...act.conditions && Array.isArray(act.conditions) ? { conditions: act.conditions.map(String) } : {}
|
|
2834
|
+
});
|
|
2835
|
+
}
|
|
2836
|
+
}
|
|
2837
|
+
result.push({
|
|
2838
|
+
match: String(e.match || ""),
|
|
2839
|
+
...e.description ? { description: String(e.description) } : {},
|
|
2840
|
+
...e.conditions && Array.isArray(e.conditions) ? { conditions: e.conditions.map(String) } : {},
|
|
2841
|
+
actions
|
|
2842
|
+
});
|
|
2843
|
+
}
|
|
2844
|
+
return result;
|
|
2845
|
+
}
|
|
2769
2846
|
function extractDefineModelCall(programPath, compilerState, actionCounter) {
|
|
2770
2847
|
for (const node of programPath.node.body) {
|
|
2771
2848
|
if (!t11.isExportDefaultDeclaration(node)) continue;
|
|
@@ -2805,17 +2882,29 @@ function extractDefineModelCall(programPath, compilerState, actionCounter) {
|
|
|
2805
2882
|
const statesObj = config.states;
|
|
2806
2883
|
for (const [name, stateConfig] of Object.entries(statesObj)) {
|
|
2807
2884
|
const stateType = modelStateTypeToIR(stateConfig.type);
|
|
2885
|
+
const on_enter = parseActionArray(stateConfig.on_enter, actionCounter);
|
|
2886
|
+
const on_exit = parseActionArray(stateConfig.on_exit, actionCounter);
|
|
2887
|
+
const during = parseDuringArray(stateConfig.during, actionCounter);
|
|
2888
|
+
const on_event = parseOnEventArray(stateConfig.on_event, actionCounter);
|
|
2889
|
+
const stateRuntime = stateConfig.runtime;
|
|
2808
2890
|
if (!compilerState.states.has(name)) {
|
|
2809
2891
|
compilerState.states.set(name, {
|
|
2810
2892
|
name,
|
|
2811
2893
|
type: stateType,
|
|
2812
2894
|
description: stateConfig.description,
|
|
2813
|
-
on_enter
|
|
2814
|
-
during
|
|
2815
|
-
on_exit
|
|
2895
|
+
on_enter,
|
|
2896
|
+
during,
|
|
2897
|
+
on_exit,
|
|
2898
|
+
...on_event.length > 0 ? { on_event } : {},
|
|
2899
|
+
...stateRuntime ? { runtime: stateRuntime } : {}
|
|
2816
2900
|
});
|
|
2817
2901
|
} else {
|
|
2818
|
-
compilerState.states.get(name)
|
|
2902
|
+
const existing = compilerState.states.get(name);
|
|
2903
|
+
existing.type = stateType;
|
|
2904
|
+
if (on_enter.length > 0) existing.on_enter = on_enter;
|
|
2905
|
+
if (on_exit.length > 0) existing.on_exit = on_exit;
|
|
2906
|
+
if (during.length > 0) existing.during = during;
|
|
2907
|
+
if (on_event.length > 0) existing.on_event = on_event;
|
|
2819
2908
|
}
|
|
2820
2909
|
}
|
|
2821
2910
|
}
|
|
@@ -2853,16 +2942,26 @@ function extractDefineModelCall(programPath, compilerState, actionCounter) {
|
|
|
2853
2942
|
if (transConfig.guard) {
|
|
2854
2943
|
conditions.push(parseGuardExpression(String(transConfig.guard)));
|
|
2855
2944
|
}
|
|
2945
|
+
if (transConfig.conditions && Array.isArray(transConfig.conditions)) {
|
|
2946
|
+
for (const cond of transConfig.conditions) {
|
|
2947
|
+
if (typeof cond === "object" && cond !== null) {
|
|
2948
|
+
conditions.push(cond);
|
|
2949
|
+
}
|
|
2950
|
+
}
|
|
2951
|
+
}
|
|
2952
|
+
const actions = parseActionArray(transConfig.actions, actionCounter);
|
|
2953
|
+
const transRuntime = transConfig.runtime;
|
|
2856
2954
|
compilerState.transitions.push({
|
|
2857
2955
|
name,
|
|
2858
2956
|
from,
|
|
2859
2957
|
to,
|
|
2860
2958
|
description: transConfig.description,
|
|
2861
2959
|
conditions: conditions.length > 0 ? conditions : void 0,
|
|
2862
|
-
actions
|
|
2960
|
+
actions,
|
|
2863
2961
|
roles: transConfig.roles,
|
|
2864
2962
|
auto: transConfig.auto,
|
|
2865
|
-
required_fields: transConfig.required_fields
|
|
2963
|
+
required_fields: transConfig.required_fields,
|
|
2964
|
+
...transRuntime ? { runtime: transRuntime } : {}
|
|
2866
2965
|
});
|
|
2867
2966
|
}
|
|
2868
2967
|
}
|
|
@@ -2879,6 +2978,9 @@ function extractDefineModelCall(programPath, compilerState, actionCounter) {
|
|
|
2879
2978
|
if (config.metadata && typeof config.metadata === "object") {
|
|
2880
2979
|
compilerState.metadata.modelMetadata = config.metadata;
|
|
2881
2980
|
}
|
|
2981
|
+
if (config.orchestration && typeof config.orchestration === "object" && !Array.isArray(config.orchestration)) {
|
|
2982
|
+
compilerState.metadata.orchestration = config.orchestration;
|
|
2983
|
+
}
|
|
2882
2984
|
return true;
|
|
2883
2985
|
}
|
|
2884
2986
|
return false;
|
|
@@ -3053,166 +3155,2022 @@ function extractModelFile(path, state) {
|
|
|
3053
3155
|
}
|
|
3054
3156
|
}
|
|
3055
3157
|
|
|
3056
|
-
// src/babel/extractors/
|
|
3158
|
+
// src/babel/extractors/flow-extractor.ts
|
|
3057
3159
|
var t12 = __toESM(require("@babel/types"));
|
|
3058
|
-
|
|
3059
|
-
|
|
3060
|
-
|
|
3160
|
+
|
|
3161
|
+
// src/babel/extractors/workflow-shorthand.ts
|
|
3162
|
+
function makeState(name, type) {
|
|
3163
|
+
return {
|
|
3164
|
+
name,
|
|
3165
|
+
type,
|
|
3166
|
+
on_enter: [],
|
|
3167
|
+
during: [],
|
|
3168
|
+
on_exit: []
|
|
3169
|
+
};
|
|
3061
3170
|
}
|
|
3062
|
-
function
|
|
3063
|
-
|
|
3064
|
-
|
|
3065
|
-
|
|
3066
|
-
|
|
3067
|
-
|
|
3068
|
-
|
|
3069
|
-
|
|
3070
|
-
|
|
3071
|
-
|
|
3072
|
-
|
|
3073
|
-
|
|
3171
|
+
function makeTransition(name, from, to) {
|
|
3172
|
+
return {
|
|
3173
|
+
name,
|
|
3174
|
+
from: [from],
|
|
3175
|
+
to,
|
|
3176
|
+
actions: []
|
|
3177
|
+
};
|
|
3178
|
+
}
|
|
3179
|
+
function dedupeTransitions(ts) {
|
|
3180
|
+
const seen = /* @__PURE__ */ new Set();
|
|
3181
|
+
const out = [];
|
|
3182
|
+
for (const t22 of ts) {
|
|
3183
|
+
const key = `${t22.name}::${t22.from.join(",")}::${t22.to}`;
|
|
3184
|
+
if (!seen.has(key)) {
|
|
3185
|
+
seen.add(key);
|
|
3186
|
+
out.push(t22);
|
|
3187
|
+
}
|
|
3188
|
+
}
|
|
3189
|
+
return out;
|
|
3190
|
+
}
|
|
3191
|
+
var TOKEN_RE = /(<->)|<-(\w+)-|(<-)|(?:-(\w+)->)|(->)|(\|)|([a-zA-Z_]\w*)/g;
|
|
3192
|
+
function tokenize(line) {
|
|
3193
|
+
const tokens = [];
|
|
3194
|
+
let m;
|
|
3195
|
+
TOKEN_RE.lastIndex = 0;
|
|
3196
|
+
while ((m = TOKEN_RE.exec(line)) !== null) {
|
|
3197
|
+
if (m[1]) {
|
|
3198
|
+
tokens.push({ kind: "arrow", direction: "bidirectional" });
|
|
3199
|
+
} else if (m[2]) {
|
|
3200
|
+
tokens.push({ kind: "arrow", direction: "backward", name: m[2] });
|
|
3201
|
+
} else if (m[3]) {
|
|
3202
|
+
tokens.push({ kind: "arrow", direction: "backward" });
|
|
3203
|
+
} else if (m[4]) {
|
|
3204
|
+
tokens.push({ kind: "arrow", direction: "forward", name: m[4] });
|
|
3205
|
+
} else if (m[5]) {
|
|
3206
|
+
tokens.push({ kind: "arrow", direction: "forward" });
|
|
3207
|
+
} else if (m[6]) {
|
|
3208
|
+
tokens.push({ kind: "branch" });
|
|
3209
|
+
} else if (m[7]) {
|
|
3210
|
+
tokens.push({ kind: "state", name: m[7] });
|
|
3211
|
+
}
|
|
3212
|
+
}
|
|
3213
|
+
return tokens;
|
|
3214
|
+
}
|
|
3215
|
+
function parseTokens(tokens, stateMap, transitions, outgoingCounts) {
|
|
3216
|
+
let lastState = null;
|
|
3217
|
+
for (let i = 0; i < tokens.length; i++) {
|
|
3218
|
+
const tok = tokens[i];
|
|
3219
|
+
if (tok.kind === "state") {
|
|
3220
|
+
stateMap.set(tok.name, stateMap.has(tok.name) ? stateMap.get(tok.name) : true);
|
|
3221
|
+
lastState = tok.name;
|
|
3222
|
+
continue;
|
|
3223
|
+
}
|
|
3224
|
+
if (tok.kind === "branch") {
|
|
3225
|
+
continue;
|
|
3226
|
+
}
|
|
3227
|
+
if (tok.kind === "arrow") {
|
|
3228
|
+
let nextIdx = i + 1;
|
|
3229
|
+
const targets = [];
|
|
3230
|
+
while (nextIdx < tokens.length) {
|
|
3231
|
+
const next = tokens[nextIdx];
|
|
3232
|
+
if (next.kind === "state") {
|
|
3233
|
+
targets.push(next.name);
|
|
3234
|
+
stateMap.set(next.name, stateMap.has(next.name) ? stateMap.get(next.name) : true);
|
|
3235
|
+
nextIdx++;
|
|
3236
|
+
if (nextIdx < tokens.length && tokens[nextIdx].kind === "branch") {
|
|
3237
|
+
nextIdx++;
|
|
3238
|
+
continue;
|
|
3239
|
+
}
|
|
3240
|
+
break;
|
|
3241
|
+
} else {
|
|
3242
|
+
nextIdx++;
|
|
3074
3243
|
}
|
|
3075
3244
|
}
|
|
3076
|
-
if (
|
|
3077
|
-
for (const
|
|
3078
|
-
if (
|
|
3079
|
-
|
|
3080
|
-
|
|
3081
|
-
|
|
3082
|
-
|
|
3083
|
-
|
|
3084
|
-
|
|
3085
|
-
|
|
3086
|
-
|
|
3087
|
-
|
|
3088
|
-
|
|
3089
|
-
|
|
3090
|
-
|
|
3245
|
+
if (lastState && targets.length > 0) {
|
|
3246
|
+
for (const target of targets) {
|
|
3247
|
+
if (tok.direction === "forward" || tok.direction === "bidirectional") {
|
|
3248
|
+
const name = tok.name || `to_${target}`;
|
|
3249
|
+
transitions.push(makeTransition(name, lastState, target));
|
|
3250
|
+
outgoingCounts.set(lastState, (outgoingCounts.get(lastState) || 0) + 1);
|
|
3251
|
+
}
|
|
3252
|
+
if (tok.direction === "backward" || tok.direction === "bidirectional") {
|
|
3253
|
+
const name = tok.name || `to_${lastState}`;
|
|
3254
|
+
transitions.push(makeTransition(name, target, lastState));
|
|
3255
|
+
outgoingCounts.set(target, (outgoingCounts.get(target) || 0) + 1);
|
|
3256
|
+
}
|
|
3257
|
+
}
|
|
3258
|
+
lastState = targets[targets.length > 1 ? 0 : 0];
|
|
3259
|
+
if (targets.length === 1) {
|
|
3260
|
+
lastState = targets[0];
|
|
3261
|
+
}
|
|
3262
|
+
i = nextIdx - 1;
|
|
3263
|
+
}
|
|
3264
|
+
}
|
|
3265
|
+
}
|
|
3266
|
+
}
|
|
3267
|
+
function parseMultiLine(lines) {
|
|
3268
|
+
const allStateNames = [];
|
|
3269
|
+
const allTransitions = [];
|
|
3270
|
+
const stateMap = /* @__PURE__ */ new Map();
|
|
3271
|
+
const outgoingCounts = /* @__PURE__ */ new Map();
|
|
3272
|
+
for (const line of lines) {
|
|
3273
|
+
const trimmed = line.trim();
|
|
3274
|
+
if (!trimmed) continue;
|
|
3275
|
+
const tokens = tokenize(trimmed);
|
|
3276
|
+
const hasStates = tokens.some((t22) => t22.kind === "state");
|
|
3277
|
+
const hasForwardArrows = tokens.some(
|
|
3278
|
+
(t22) => t22.kind === "arrow" && (t22.direction === "forward" || t22.direction === "bidirectional")
|
|
3279
|
+
);
|
|
3280
|
+
if (hasStates && hasForwardArrows) {
|
|
3281
|
+
for (const tok of tokens) {
|
|
3282
|
+
if (tok.kind === "state" && !allStateNames.includes(tok.name)) {
|
|
3283
|
+
allStateNames.push(tok.name);
|
|
3284
|
+
}
|
|
3285
|
+
}
|
|
3286
|
+
parseTokens(tokens, stateMap, allTransitions, outgoingCounts);
|
|
3287
|
+
} else if (!hasStates && tokens.some((t22) => t22.kind === "arrow")) {
|
|
3288
|
+
let arrowIndex = 0;
|
|
3289
|
+
for (const tok of tokens) {
|
|
3290
|
+
if (tok.kind === "arrow") {
|
|
3291
|
+
if (arrowIndex < allStateNames.length - 1) {
|
|
3292
|
+
const left = allStateNames[arrowIndex];
|
|
3293
|
+
const right = allStateNames[arrowIndex + 1];
|
|
3294
|
+
if (tok.direction === "backward" || tok.direction === "bidirectional") {
|
|
3295
|
+
const name = tok.name || `to_${left}`;
|
|
3296
|
+
allTransitions.push(makeTransition(name, right, left));
|
|
3297
|
+
outgoingCounts.set(right, (outgoingCounts.get(right) || 0) + 1);
|
|
3298
|
+
}
|
|
3299
|
+
if (tok.direction === "forward" || tok.direction === "bidirectional") {
|
|
3300
|
+
const name = tok.name || `to_${right}`;
|
|
3301
|
+
allTransitions.push(makeTransition(name, left, right));
|
|
3302
|
+
outgoingCounts.set(left, (outgoingCounts.get(left) || 0) + 1);
|
|
3091
3303
|
}
|
|
3092
|
-
serverActions.push(action);
|
|
3093
3304
|
}
|
|
3305
|
+
arrowIndex++;
|
|
3306
|
+
}
|
|
3307
|
+
}
|
|
3308
|
+
} else if (hasStates) {
|
|
3309
|
+
parseTokens(tokens, stateMap, allTransitions, outgoingCounts);
|
|
3310
|
+
for (const tok of tokens) {
|
|
3311
|
+
if (tok.kind === "state" && !allStateNames.includes(tok.name)) {
|
|
3312
|
+
allStateNames.push(tok.name);
|
|
3094
3313
|
}
|
|
3095
3314
|
}
|
|
3096
3315
|
}
|
|
3097
3316
|
}
|
|
3098
|
-
|
|
3099
|
-
|
|
3100
|
-
|
|
3317
|
+
return { stateNames: allStateNames, transitions: dedupeTransitions(allTransitions) };
|
|
3318
|
+
}
|
|
3319
|
+
function parseArrowSyntax(arrow) {
|
|
3320
|
+
const lines = arrow.split("\n");
|
|
3321
|
+
const { stateNames, transitions } = parseMultiLine(lines);
|
|
3322
|
+
if (stateNames.length === 0) {
|
|
3323
|
+
return { states: [], transitions: [] };
|
|
3324
|
+
}
|
|
3325
|
+
const hasOutgoing = /* @__PURE__ */ new Set();
|
|
3326
|
+
for (const t22 of transitions) {
|
|
3327
|
+
for (const from of t22.from) {
|
|
3328
|
+
hasOutgoing.add(from);
|
|
3329
|
+
}
|
|
3330
|
+
}
|
|
3331
|
+
const states = stateNames.map((name, idx) => {
|
|
3332
|
+
let type = "REGULAR";
|
|
3333
|
+
if (idx === 0) {
|
|
3334
|
+
type = "START";
|
|
3335
|
+
} else if (!hasOutgoing.has(name)) {
|
|
3336
|
+
type = "END";
|
|
3337
|
+
}
|
|
3338
|
+
return makeState(name, type);
|
|
3339
|
+
});
|
|
3340
|
+
return { states, transitions };
|
|
3341
|
+
}
|
|
3342
|
+
function parseFieldRecord(fields) {
|
|
3343
|
+
return Object.entries(fields).map(([name, typeStr]) => {
|
|
3344
|
+
let required = false;
|
|
3345
|
+
let raw = typeStr.trim();
|
|
3346
|
+
if (raw.endsWith("!")) {
|
|
3347
|
+
required = true;
|
|
3348
|
+
raw = raw.slice(0, -1).trim();
|
|
3349
|
+
}
|
|
3350
|
+
let defaultValue;
|
|
3351
|
+
const eqIdx = raw.indexOf("=");
|
|
3352
|
+
let typePart = raw;
|
|
3353
|
+
if (eqIdx !== -1) {
|
|
3354
|
+
typePart = raw.slice(0, eqIdx).trim();
|
|
3355
|
+
const valStr = raw.slice(eqIdx + 1).trim();
|
|
3356
|
+
try {
|
|
3357
|
+
defaultValue = JSON.parse(valStr);
|
|
3358
|
+
} catch {
|
|
3359
|
+
defaultValue = valStr;
|
|
3360
|
+
}
|
|
3361
|
+
}
|
|
3362
|
+
const TYPE_MAP = {
|
|
3363
|
+
string: "text",
|
|
3364
|
+
str: "text",
|
|
3365
|
+
text: "text",
|
|
3366
|
+
number: "number",
|
|
3367
|
+
num: "number",
|
|
3368
|
+
int: "number",
|
|
3369
|
+
integer: "number",
|
|
3370
|
+
float: "number",
|
|
3371
|
+
bool: "boolean",
|
|
3372
|
+
boolean: "boolean",
|
|
3373
|
+
date: "date",
|
|
3374
|
+
datetime: "datetime",
|
|
3375
|
+
email: "email",
|
|
3376
|
+
url: "url",
|
|
3377
|
+
json: "json",
|
|
3378
|
+
object: "json",
|
|
3379
|
+
array: "json",
|
|
3380
|
+
select: "select",
|
|
3381
|
+
enum: "select",
|
|
3382
|
+
file: "file",
|
|
3383
|
+
image: "image",
|
|
3384
|
+
currency: "currency",
|
|
3385
|
+
phone: "phone",
|
|
3386
|
+
address: "address",
|
|
3387
|
+
rich_text: "rich_text",
|
|
3388
|
+
richtext: "rich_text",
|
|
3389
|
+
color: "color",
|
|
3390
|
+
rating: "rating"
|
|
3391
|
+
};
|
|
3392
|
+
const fieldType = TYPE_MAP[typePart.toLowerCase()] || typePart;
|
|
3393
|
+
const field = {
|
|
3394
|
+
name,
|
|
3395
|
+
type: fieldType
|
|
3396
|
+
};
|
|
3397
|
+
if (required) field.required = true;
|
|
3398
|
+
if (defaultValue !== void 0) field.default_value = defaultValue;
|
|
3399
|
+
return field;
|
|
3400
|
+
});
|
|
3401
|
+
}
|
|
3402
|
+
function parseWorkflowShorthand(slug, fieldsOrArrow, arrowString) {
|
|
3403
|
+
let fields = [];
|
|
3404
|
+
let arrow;
|
|
3405
|
+
if (typeof fieldsOrArrow === "string") {
|
|
3406
|
+
arrow = fieldsOrArrow;
|
|
3407
|
+
} else {
|
|
3408
|
+
fields = parseFieldRecord(fieldsOrArrow);
|
|
3409
|
+
arrow = arrowString || "";
|
|
3101
3410
|
}
|
|
3411
|
+
const { states, transitions } = parseArrowSyntax(arrow);
|
|
3412
|
+
return { slug, fields, states, transitions };
|
|
3102
3413
|
}
|
|
3103
|
-
|
|
3104
|
-
|
|
3105
|
-
|
|
3106
|
-
|
|
3107
|
-
|
|
3108
|
-
|
|
3109
|
-
|
|
3110
|
-
|
|
3111
|
-
|
|
3112
|
-
|
|
3113
|
-
|
|
3414
|
+
|
|
3415
|
+
// src/babel/extractors/flow-extractor.ts
|
|
3416
|
+
function isImperativeWorkflowFile(path, _filename) {
|
|
3417
|
+
for (const node of path.node.body) {
|
|
3418
|
+
if (t12.isExportDefaultDeclaration(node)) {
|
|
3419
|
+
const decl = node.declaration;
|
|
3420
|
+
if (t12.isFunctionDeclaration(decl) && decl.async && decl.params.length > 0) {
|
|
3421
|
+
const param = decl.params[0];
|
|
3422
|
+
if (t12.isIdentifier(param) && param.typeAnnotation) {
|
|
3423
|
+
return true;
|
|
3424
|
+
}
|
|
3425
|
+
}
|
|
3426
|
+
if (t12.isCallExpression(decl) && t12.isIdentifier(decl.callee) && decl.callee.name === "workflow") {
|
|
3427
|
+
return true;
|
|
3428
|
+
}
|
|
3114
3429
|
}
|
|
3115
3430
|
}
|
|
3116
|
-
return
|
|
3431
|
+
return false;
|
|
3117
3432
|
}
|
|
3118
|
-
|
|
3119
|
-
|
|
3120
|
-
|
|
3121
|
-
|
|
3122
|
-
|
|
3433
|
+
var VALIDATION_FNS = /* @__PURE__ */ new Set(["validate", "assert"]);
|
|
3434
|
+
function roleCondition(role) {
|
|
3435
|
+
return { type: "role", field: role, operator: "eq", value: true };
|
|
3436
|
+
}
|
|
3437
|
+
var TS_TYPE_MAP = {
|
|
3438
|
+
Date: "datetime",
|
|
3439
|
+
Record: "json",
|
|
3440
|
+
Map: "json",
|
|
3441
|
+
Set: "json",
|
|
3442
|
+
URL: "url"
|
|
3443
|
+
};
|
|
3444
|
+
var NAME_TYPE_MAP = {
|
|
3445
|
+
email: "email",
|
|
3446
|
+
url: "url",
|
|
3447
|
+
website: "url",
|
|
3448
|
+
phone: "phone"
|
|
3449
|
+
};
|
|
3450
|
+
function resolveType2(annotation) {
|
|
3451
|
+
if (t12.isTSStringKeyword(annotation)) return "text";
|
|
3452
|
+
if (t12.isTSNumberKeyword(annotation)) return "number";
|
|
3453
|
+
if (t12.isTSBooleanKeyword(annotation)) return "boolean";
|
|
3454
|
+
if (t12.isTSTypeReference(annotation) && t12.isIdentifier(annotation.typeName)) {
|
|
3455
|
+
const name = annotation.typeName.name;
|
|
3456
|
+
if (TS_TYPE_MAP[name]) return TS_TYPE_MAP[name];
|
|
3457
|
+
if (name === "Array") return "multi_select";
|
|
3458
|
+
return name.replace(/([A-Z])/g, "-$1").toLowerCase().replace(/^-/, "");
|
|
3459
|
+
}
|
|
3460
|
+
if (t12.isTSArrayType(annotation)) return "multi_select";
|
|
3461
|
+
if (t12.isTSUnionType(annotation)) {
|
|
3462
|
+
const allLiterals = annotation.types.every(
|
|
3463
|
+
(t22) => t12.isTSLiteralType(t22) && (t12.isStringLiteral(t22.literal) || t12.isNumericLiteral(t22.literal))
|
|
3464
|
+
);
|
|
3465
|
+
if (allLiterals) return "select";
|
|
3466
|
+
return "text";
|
|
3467
|
+
}
|
|
3468
|
+
if (t12.isTSLiteralType(annotation) && t12.isStringLiteral(annotation.literal)) return "text";
|
|
3469
|
+
if (t12.isTSLiteralType(annotation) && t12.isNumericLiteral(annotation.literal)) return "number";
|
|
3470
|
+
return "text";
|
|
3471
|
+
}
|
|
3472
|
+
function extractUnionOptions2(annotation) {
|
|
3473
|
+
if (!t12.isTSUnionType(annotation)) return void 0;
|
|
3474
|
+
const options = [];
|
|
3475
|
+
for (const member of annotation.types) {
|
|
3476
|
+
if (t12.isTSLiteralType(member) && t12.isStringLiteral(member.literal)) {
|
|
3477
|
+
options.push(member.literal.value);
|
|
3123
3478
|
}
|
|
3124
3479
|
}
|
|
3125
|
-
return void 0;
|
|
3480
|
+
return options.length > 0 ? options : void 0;
|
|
3126
3481
|
}
|
|
3127
|
-
function
|
|
3128
|
-
|
|
3129
|
-
|
|
3130
|
-
|
|
3131
|
-
|
|
3132
|
-
|
|
3133
|
-
|
|
3134
|
-
|
|
3482
|
+
function extractFieldsFromInterface2(declaration) {
|
|
3483
|
+
const fields = [];
|
|
3484
|
+
for (const member of declaration.body.body) {
|
|
3485
|
+
if (!t12.isTSPropertySignature(member)) continue;
|
|
3486
|
+
if (!t12.isIdentifier(member.key)) continue;
|
|
3487
|
+
const name = member.key.name;
|
|
3488
|
+
const required = !member.optional;
|
|
3489
|
+
const typeAnno = member.typeAnnotation;
|
|
3490
|
+
let fieldType = typeAnno ? resolveType2(typeAnno.typeAnnotation) : "text";
|
|
3491
|
+
if (NAME_TYPE_MAP[name]) fieldType = NAME_TYPE_MAP[name];
|
|
3492
|
+
const field = {
|
|
3493
|
+
name,
|
|
3494
|
+
type: fieldType,
|
|
3495
|
+
label: name.replace(/([A-Z])/g, " $1").replace(/^./, (c) => c.toUpperCase()),
|
|
3496
|
+
required,
|
|
3497
|
+
default_value: getDefaultForType(fieldType)
|
|
3498
|
+
};
|
|
3499
|
+
if (typeAnno) {
|
|
3500
|
+
const options = extractUnionOptions2(typeAnno.typeAnnotation);
|
|
3501
|
+
if (options) {
|
|
3502
|
+
field.validation = { options };
|
|
3135
3503
|
}
|
|
3136
3504
|
}
|
|
3505
|
+
fields.push(field);
|
|
3137
3506
|
}
|
|
3138
|
-
return
|
|
3507
|
+
return fields;
|
|
3139
3508
|
}
|
|
3140
|
-
|
|
3141
|
-
|
|
3142
|
-
|
|
3143
|
-
|
|
3144
|
-
|
|
3145
|
-
|
|
3146
|
-
|
|
3147
|
-
|
|
3148
|
-
|
|
3149
|
-
|
|
3150
|
-
|
|
3151
|
-
|
|
3152
|
-
|
|
3153
|
-
|
|
3154
|
-
|
|
3155
|
-
|
|
3156
|
-
|
|
3157
|
-
|
|
3509
|
+
function getDefaultForType(type) {
|
|
3510
|
+
switch (type) {
|
|
3511
|
+
case "text":
|
|
3512
|
+
case "email":
|
|
3513
|
+
case "url":
|
|
3514
|
+
case "phone":
|
|
3515
|
+
case "select":
|
|
3516
|
+
return "";
|
|
3517
|
+
case "number":
|
|
3518
|
+
case "currency":
|
|
3519
|
+
return 0;
|
|
3520
|
+
case "boolean":
|
|
3521
|
+
return false;
|
|
3522
|
+
case "multi_select":
|
|
3523
|
+
return [];
|
|
3524
|
+
case "json":
|
|
3525
|
+
return {};
|
|
3526
|
+
default:
|
|
3527
|
+
return null;
|
|
3528
|
+
}
|
|
3529
|
+
}
|
|
3530
|
+
function extractNodeValue2(node) {
|
|
3531
|
+
if (t12.isStringLiteral(node)) return node.value;
|
|
3532
|
+
if (t12.isNumericLiteral(node)) return node.value;
|
|
3533
|
+
if (t12.isBooleanLiteral(node)) return node.value;
|
|
3534
|
+
if (t12.isNullLiteral(node)) return null;
|
|
3535
|
+
if (t12.isArrayExpression(node)) {
|
|
3536
|
+
return node.elements.map((el) => {
|
|
3537
|
+
if (!el || t12.isSpreadElement(el)) return null;
|
|
3538
|
+
return extractNodeValue2(el);
|
|
3539
|
+
});
|
|
3540
|
+
}
|
|
3541
|
+
if (t12.isObjectExpression(node)) {
|
|
3542
|
+
const obj = {};
|
|
3543
|
+
for (const prop of node.properties) {
|
|
3544
|
+
if (!t12.isObjectProperty(prop)) continue;
|
|
3545
|
+
const key = t12.isIdentifier(prop.key) ? prop.key.name : t12.isStringLiteral(prop.key) ? prop.key.value : null;
|
|
3546
|
+
if (key) obj[key] = extractNodeValue2(prop.value);
|
|
3158
3547
|
}
|
|
3548
|
+
return obj;
|
|
3159
3549
|
}
|
|
3160
|
-
|
|
3161
|
-
|
|
3162
|
-
entry.variableName = parent.node.id.name;
|
|
3550
|
+
if (t12.isTemplateLiteral(node)) {
|
|
3551
|
+
return node.quasis.map((q) => q.value.raw).join("${}");
|
|
3163
3552
|
}
|
|
3164
|
-
if (
|
|
3165
|
-
|
|
3166
|
-
|
|
3167
|
-
|
|
3553
|
+
if (t12.isIdentifier(node)) {
|
|
3554
|
+
if (node.name === "undefined") return void 0;
|
|
3555
|
+
return node.name;
|
|
3556
|
+
}
|
|
3557
|
+
if (t12.isMemberExpression(node)) {
|
|
3558
|
+
return memberExprToString(node);
|
|
3559
|
+
}
|
|
3560
|
+
if (t12.isTSAsExpression(node)) return extractNodeValue2(node.expression);
|
|
3561
|
+
if (t12.isArrowFunctionExpression(node) || t12.isFunctionExpression(node)) {
|
|
3562
|
+
return "[Function]";
|
|
3563
|
+
}
|
|
3564
|
+
return "[Expression]";
|
|
3168
3565
|
}
|
|
3169
|
-
|
|
3170
|
-
|
|
3171
|
-
|
|
3172
|
-
|
|
3173
|
-
|
|
3174
|
-
|
|
3175
|
-
const
|
|
3176
|
-
const
|
|
3177
|
-
const
|
|
3178
|
-
|
|
3179
|
-
|
|
3566
|
+
function memberExprToString(node) {
|
|
3567
|
+
const obj = t12.isIdentifier(node.object) ? node.object.name : t12.isMemberExpression(node.object) ? memberExprToString(node.object) : "[object]";
|
|
3568
|
+
const prop = t12.isIdentifier(node.property) ? node.property.name : t12.isStringLiteral(node.property) ? node.property.value : "[property]";
|
|
3569
|
+
return `${obj}.${prop}`;
|
|
3570
|
+
}
|
|
3571
|
+
function analyzeStateFn(fn, paramName, actionCounter) {
|
|
3572
|
+
const onEnter = [];
|
|
3573
|
+
const validations = [];
|
|
3574
|
+
const conditions = [];
|
|
3575
|
+
const roles = [];
|
|
3576
|
+
const requiredFields = [];
|
|
3577
|
+
const during = [];
|
|
3578
|
+
const onEvent = [];
|
|
3579
|
+
let timeout;
|
|
3580
|
+
let runtime;
|
|
3581
|
+
if (!fn.body || !t12.isBlockStatement(fn.body)) {
|
|
3582
|
+
return { onEnter, validations, conditions, roles, requiredFields, during, onEvent, timeout, runtime };
|
|
3583
|
+
}
|
|
3584
|
+
for (const stmt of fn.body.body) {
|
|
3585
|
+
processStatement(stmt, paramName, actionCounter, {
|
|
3586
|
+
onEnter,
|
|
3587
|
+
validations,
|
|
3588
|
+
conditions,
|
|
3589
|
+
roles,
|
|
3590
|
+
requiredFields,
|
|
3591
|
+
during,
|
|
3592
|
+
onEvent,
|
|
3593
|
+
setTimeout: (t22) => {
|
|
3594
|
+
timeout = t22;
|
|
3595
|
+
},
|
|
3596
|
+
setRuntime: (r) => {
|
|
3597
|
+
runtime = r;
|
|
3598
|
+
}
|
|
3599
|
+
});
|
|
3180
3600
|
}
|
|
3181
|
-
|
|
3182
|
-
|
|
3183
|
-
|
|
3184
|
-
|
|
3185
|
-
|
|
3601
|
+
return { onEnter, validations, conditions, roles, requiredFields, during, onEvent, timeout, runtime };
|
|
3602
|
+
}
|
|
3603
|
+
function processStatement(stmt, paramName, actionCounter, ctx) {
|
|
3604
|
+
if (t12.isExpressionStatement(stmt)) {
|
|
3605
|
+
processExpression(stmt.expression, paramName, actionCounter, ctx);
|
|
3606
|
+
return;
|
|
3607
|
+
}
|
|
3608
|
+
if (t12.isIfStatement(stmt)) {
|
|
3609
|
+
const testStr = expressionToIR(stmt.test, paramName);
|
|
3610
|
+
if (t12.isBlockStatement(stmt.consequent)) {
|
|
3611
|
+
for (const inner of stmt.consequent.body) {
|
|
3612
|
+
processStatement(inner, paramName, actionCounter, {
|
|
3613
|
+
...ctx,
|
|
3614
|
+
ifCondition: testStr
|
|
3615
|
+
});
|
|
3186
3616
|
}
|
|
3187
3617
|
}
|
|
3618
|
+
return;
|
|
3188
3619
|
}
|
|
3189
|
-
|
|
3190
|
-
|
|
3191
|
-
|
|
3192
|
-
|
|
3193
|
-
} else if (t14.isObjectPattern(parent.node.id)) {
|
|
3194
|
-
const props = parent.node.id.properties.filter((p) => t14.isObjectProperty(p) && t14.isIdentifier(p.key)).map((p) => p.key.name);
|
|
3195
|
-
if (props.length > 0) {
|
|
3196
|
-
entry.variableName = props.join(", ");
|
|
3620
|
+
if (t12.isVariableDeclaration(stmt)) {
|
|
3621
|
+
for (const decl of stmt.declarations) {
|
|
3622
|
+
if (decl.init && t12.isAwaitExpression(decl.init)) {
|
|
3623
|
+
processExpression(decl.init, paramName, actionCounter, ctx);
|
|
3197
3624
|
}
|
|
3198
3625
|
}
|
|
3199
3626
|
}
|
|
3200
|
-
if (!compilerState.metadata) compilerState.metadata = {};
|
|
3201
|
-
const meta = compilerState.metadata;
|
|
3202
|
-
if (!meta.serverStateSubscriptions) meta.serverStateSubscriptions = [];
|
|
3203
|
-
meta.serverStateSubscriptions.push(entry);
|
|
3204
|
-
meta.requiresSSE = true;
|
|
3205
3627
|
}
|
|
3206
|
-
|
|
3207
|
-
|
|
3208
|
-
|
|
3209
|
-
|
|
3210
|
-
|
|
3211
|
-
|
|
3212
|
-
|
|
3213
|
-
|
|
3214
|
-
|
|
3215
|
-
|
|
3628
|
+
function processExpression(expr, paramName, actionCounter, ctx) {
|
|
3629
|
+
if (t12.isAssignmentExpression(expr) && t12.isMemberExpression(expr.left)) {
|
|
3630
|
+
const left = memberExprToString(expr.left);
|
|
3631
|
+
if (left.startsWith(`${paramName}.`)) {
|
|
3632
|
+
const field = left.slice(paramName.length + 1);
|
|
3633
|
+
const valueExpr = expressionToIR(expr.right, paramName);
|
|
3634
|
+
const action = {
|
|
3635
|
+
id: `auto_${++actionCounter.value}`,
|
|
3636
|
+
type: "set_field",
|
|
3637
|
+
mode: "auto",
|
|
3638
|
+
config: { field, expression: valueExpr },
|
|
3639
|
+
...ctx.ifCondition ? { condition: ctx.ifCondition } : {}
|
|
3640
|
+
};
|
|
3641
|
+
ctx.onEnter.push(action);
|
|
3642
|
+
return;
|
|
3643
|
+
}
|
|
3644
|
+
}
|
|
3645
|
+
if (t12.isAssignmentExpression(expr) && expr.operator !== "=" && t12.isMemberExpression(expr.left)) {
|
|
3646
|
+
const left = memberExprToString(expr.left);
|
|
3647
|
+
if (left.startsWith(`${paramName}.`)) {
|
|
3648
|
+
const field = left.slice(paramName.length + 1);
|
|
3649
|
+
const op = expr.operator.replace("=", "");
|
|
3650
|
+
const valueExpr = expressionToIR(expr.right, paramName);
|
|
3651
|
+
const action = {
|
|
3652
|
+
id: `auto_${++actionCounter.value}`,
|
|
3653
|
+
type: "set_field",
|
|
3654
|
+
mode: "auto",
|
|
3655
|
+
config: { field, expression: `state_data.${field} ${op} ${valueExpr}` },
|
|
3656
|
+
...ctx.ifCondition ? { condition: ctx.ifCondition } : {}
|
|
3657
|
+
};
|
|
3658
|
+
ctx.onEnter.push(action);
|
|
3659
|
+
return;
|
|
3660
|
+
}
|
|
3661
|
+
}
|
|
3662
|
+
if (t12.isCallExpression(expr) || t12.isAwaitExpression(expr) && t12.isCallExpression(expr.argument)) {
|
|
3663
|
+
const call = t12.isAwaitExpression(expr) ? expr.argument : expr;
|
|
3664
|
+
const fnName = t12.isIdentifier(call.callee) ? call.callee.name : t12.isMemberExpression(call.callee) && t12.isIdentifier(call.callee.property) ? call.callee.property.name : null;
|
|
3665
|
+
if (!fnName) return;
|
|
3666
|
+
if (VALIDATION_FNS.has(fnName)) {
|
|
3667
|
+
extractValidation(call, paramName, ctx);
|
|
3668
|
+
return;
|
|
3669
|
+
}
|
|
3670
|
+
if (fnName === "log") {
|
|
3671
|
+
const event = call.arguments[0] ? extractNodeValue2(call.arguments[0]) : "";
|
|
3672
|
+
const data = call.arguments[1] ? extractNodeValue2(call.arguments[1]) : void 0;
|
|
3673
|
+
ctx.onEnter.push({
|
|
3674
|
+
id: `auto_${++actionCounter.value}`,
|
|
3675
|
+
type: "log_event",
|
|
3676
|
+
mode: "auto",
|
|
3677
|
+
config: { event: String(event), ...data ? { data } : {} },
|
|
3678
|
+
...ctx.ifCondition ? { condition: ctx.ifCondition } : {}
|
|
3679
|
+
});
|
|
3680
|
+
return;
|
|
3681
|
+
}
|
|
3682
|
+
if (fnName === "notify") {
|
|
3683
|
+
const to = call.arguments[0] ? expressionToIR(call.arguments[0], paramName) : "";
|
|
3684
|
+
const message = call.arguments[1] ? extractNodeValue2(call.arguments[1]) : "";
|
|
3685
|
+
const opts = call.arguments[2] ? extractNodeValue2(call.arguments[2]) : {};
|
|
3686
|
+
ctx.onEnter.push({
|
|
3687
|
+
id: `auto_${++actionCounter.value}`,
|
|
3688
|
+
type: "send_notification",
|
|
3689
|
+
mode: "auto",
|
|
3690
|
+
config: {
|
|
3691
|
+
to: String(to),
|
|
3692
|
+
message: String(message),
|
|
3693
|
+
...opts
|
|
3694
|
+
},
|
|
3695
|
+
...ctx.ifCondition ? { condition: ctx.ifCondition } : {}
|
|
3696
|
+
});
|
|
3697
|
+
return;
|
|
3698
|
+
}
|
|
3699
|
+
if (fnName === "emit") {
|
|
3700
|
+
const event = call.arguments[0] ? extractNodeValue2(call.arguments[0]) : "";
|
|
3701
|
+
const payload = call.arguments[1] ? extractNodeValue2(call.arguments[1]) : void 0;
|
|
3702
|
+
ctx.onEnter.push({
|
|
3703
|
+
id: `auto_${++actionCounter.value}`,
|
|
3704
|
+
type: "emit_event",
|
|
3705
|
+
mode: "auto",
|
|
3706
|
+
config: { event: String(event), ...payload ? { payload } : {} },
|
|
3707
|
+
...ctx.ifCondition ? { condition: ctx.ifCondition } : {}
|
|
3708
|
+
});
|
|
3709
|
+
return;
|
|
3710
|
+
}
|
|
3711
|
+
if (fnName === "requireRole") {
|
|
3712
|
+
for (const arg of call.arguments) {
|
|
3713
|
+
if (t12.isStringLiteral(arg)) ctx.roles.push(arg.value);
|
|
3714
|
+
}
|
|
3715
|
+
return;
|
|
3716
|
+
}
|
|
3717
|
+
if (fnName === "requireField") {
|
|
3718
|
+
for (const arg of call.arguments) {
|
|
3719
|
+
if (t12.isStringLiteral(arg)) ctx.requiredFields.push(arg.value);
|
|
3720
|
+
}
|
|
3721
|
+
return;
|
|
3722
|
+
}
|
|
3723
|
+
if (fnName === "runtime") {
|
|
3724
|
+
if (call.arguments[0] && t12.isStringLiteral(call.arguments[0])) {
|
|
3725
|
+
ctx.setRuntime(call.arguments[0].value);
|
|
3726
|
+
}
|
|
3727
|
+
return;
|
|
3728
|
+
}
|
|
3729
|
+
if (fnName === "guard") {
|
|
3730
|
+
if (call.arguments[0] && t12.isStringLiteral(call.arguments[0])) {
|
|
3731
|
+
ctx.conditions.push({ expression: call.arguments[0].value });
|
|
3732
|
+
}
|
|
3733
|
+
return;
|
|
3734
|
+
}
|
|
3735
|
+
if (fnName === "every") {
|
|
3736
|
+
const interval = call.arguments[0] && t12.isStringLiteral(call.arguments[0]) ? call.arguments[0].value : "1h";
|
|
3737
|
+
const intervalMs = parseDuration(interval);
|
|
3738
|
+
const opts = call.arguments[1] ? extractNodeValue2(call.arguments[1]) : {};
|
|
3739
|
+
const duringAction = {
|
|
3740
|
+
id: `during_${++actionCounter.value}`,
|
|
3741
|
+
type: "interval",
|
|
3742
|
+
interval_ms: intervalMs,
|
|
3743
|
+
...typeof opts === "object" && opts !== null && opts.when ? { condition: opts.when } : {},
|
|
3744
|
+
actions: []
|
|
3745
|
+
// Placeholder — body analysis would extract inner actions
|
|
3746
|
+
};
|
|
3747
|
+
ctx.during.push(duringAction);
|
|
3748
|
+
return;
|
|
3749
|
+
}
|
|
3750
|
+
if (fnName === "cron") {
|
|
3751
|
+
const cronExpr = call.arguments[0] && t12.isStringLiteral(call.arguments[0]) ? call.arguments[0].value : "* * * * *";
|
|
3752
|
+
ctx.during.push({
|
|
3753
|
+
id: `during_${++actionCounter.value}`,
|
|
3754
|
+
type: "cron",
|
|
3755
|
+
cron: cronExpr,
|
|
3756
|
+
actions: []
|
|
3757
|
+
});
|
|
3758
|
+
return;
|
|
3759
|
+
}
|
|
3760
|
+
if (fnName === "after") {
|
|
3761
|
+
const delay = call.arguments[0] && t12.isStringLiteral(call.arguments[0]) ? call.arguments[0].value : "1h";
|
|
3762
|
+
ctx.during.push({
|
|
3763
|
+
id: `during_${++actionCounter.value}`,
|
|
3764
|
+
type: "timeout",
|
|
3765
|
+
delay_ms: parseDuration(delay),
|
|
3766
|
+
actions: []
|
|
3767
|
+
});
|
|
3768
|
+
return;
|
|
3769
|
+
}
|
|
3770
|
+
if (fnName === "on" && !t12.isAwaitExpression(expr)) {
|
|
3771
|
+
const pattern = call.arguments[0] && t12.isStringLiteral(call.arguments[0]) ? call.arguments[0].value : "*";
|
|
3772
|
+
const opts = call.arguments[1] ? extractNodeValue2(call.arguments[1]) : {};
|
|
3773
|
+
const optsObj = typeof opts === "object" && opts !== null ? opts : {};
|
|
3774
|
+
ctx.onEvent.push({
|
|
3775
|
+
match: pattern,
|
|
3776
|
+
...optsObj.when ? { conditions: [String(optsObj.when)] } : {},
|
|
3777
|
+
actions: []
|
|
3778
|
+
});
|
|
3779
|
+
return;
|
|
3780
|
+
}
|
|
3781
|
+
if (fnName === "timeout") {
|
|
3782
|
+
const duration = call.arguments[0] && t12.isStringLiteral(call.arguments[0]) ? call.arguments[0].value : "1h";
|
|
3783
|
+
const opts = call.arguments[1] ? extractNodeValue2(call.arguments[1]) : {};
|
|
3784
|
+
const optsObj = typeof opts === "object" && opts !== null ? opts : {};
|
|
3785
|
+
ctx.setTimeout({
|
|
3786
|
+
duration,
|
|
3787
|
+
fallback: {
|
|
3788
|
+
...optsObj.transition ? { transition: String(optsObj.transition) } : {},
|
|
3789
|
+
...optsObj.action ? { action: String(optsObj.action) } : {}
|
|
3790
|
+
}
|
|
3791
|
+
});
|
|
3792
|
+
return;
|
|
3793
|
+
}
|
|
3794
|
+
if (fnName === "restrict") {
|
|
3795
|
+
return;
|
|
3796
|
+
}
|
|
3797
|
+
}
|
|
3798
|
+
}
|
|
3799
|
+
function extractValidation(call, paramName, ctx) {
|
|
3800
|
+
const condArg = call.arguments[0];
|
|
3801
|
+
const msgArg = call.arguments[1];
|
|
3802
|
+
const sevArg = call.arguments[2];
|
|
3803
|
+
const message = msgArg && t12.isStringLiteral(msgArg) ? msgArg.value : "Validation failed";
|
|
3804
|
+
const severity = sevArg && t12.isStringLiteral(sevArg) && sevArg.value === "warning" ? "warning" : "error";
|
|
3805
|
+
if (!condArg) return;
|
|
3806
|
+
const field = extractFieldFromCondition(condArg, paramName);
|
|
3807
|
+
const exprStr = expressionToIR(condArg, paramName);
|
|
3808
|
+
if (field) {
|
|
3809
|
+
const validation = {};
|
|
3810
|
+
if (t12.isBinaryExpression(condArg) && (condArg.operator === ">" || condArg.operator === ">=")) {
|
|
3811
|
+
if (isLengthAccess(condArg.left, paramName, field) && t12.isNumericLiteral(condArg.right)) {
|
|
3812
|
+
validation.minLength = condArg.right.value + (condArg.operator === ">" ? 1 : 0);
|
|
3813
|
+
} else if (isFieldAccess(condArg.left, paramName, field) && t12.isNumericLiteral(condArg.right)) {
|
|
3814
|
+
validation.min = condArg.right.value + (condArg.operator === ">" ? 1e-3 : 0);
|
|
3815
|
+
}
|
|
3816
|
+
}
|
|
3817
|
+
if (t12.isBinaryExpression(condArg) && (condArg.operator === "<" || condArg.operator === "<=")) {
|
|
3818
|
+
if (isFieldAccess(condArg.left, paramName, field) && t12.isNumericLiteral(condArg.right)) {
|
|
3819
|
+
validation.max = condArg.right.value;
|
|
3820
|
+
}
|
|
3821
|
+
}
|
|
3822
|
+
if (t12.isCallExpression(condArg) && t12.isMemberExpression(condArg.callee) && t12.isRegExpLiteral(condArg.callee.object) && t12.isIdentifier(condArg.callee.property) && condArg.callee.property.name === "test") {
|
|
3823
|
+
if (!validation.rules) validation.rules = [];
|
|
3824
|
+
validation.rules.push({
|
|
3825
|
+
expression: `MATCHES(value, "${condArg.callee.object.pattern}")`,
|
|
3826
|
+
message: "",
|
|
3827
|
+
// Will be set from the validate() message arg
|
|
3828
|
+
severity: "error"
|
|
3829
|
+
});
|
|
3830
|
+
}
|
|
3831
|
+
ctx.validations.push({ field, validation, message, severity });
|
|
3832
|
+
} else {
|
|
3833
|
+
ctx.validations.push({
|
|
3834
|
+
field: "__cross__",
|
|
3835
|
+
validation: { rules: [{ expression: exprStr, message, severity }] },
|
|
3836
|
+
message,
|
|
3837
|
+
severity
|
|
3838
|
+
});
|
|
3839
|
+
}
|
|
3840
|
+
}
|
|
3841
|
+
function extractFieldFromCondition(node, paramName) {
|
|
3842
|
+
if (t12.isMemberExpression(node)) {
|
|
3843
|
+
const str = memberExprToString(node);
|
|
3844
|
+
if (str.startsWith(`${paramName}.`)) {
|
|
3845
|
+
const parts = str.slice(paramName.length + 1).split(".");
|
|
3846
|
+
return parts[0];
|
|
3847
|
+
}
|
|
3848
|
+
}
|
|
3849
|
+
if (t12.isBinaryExpression(node)) {
|
|
3850
|
+
return extractFieldFromCondition(node.left, paramName) || extractFieldFromCondition(node.right, paramName);
|
|
3851
|
+
}
|
|
3852
|
+
if (t12.isCallExpression(node) && t12.isMemberExpression(node.callee)) {
|
|
3853
|
+
return extractFieldFromCondition(node.callee.object, paramName);
|
|
3854
|
+
}
|
|
3855
|
+
if (t12.isCallExpression(node) && t12.isMemberExpression(node.callee) && t12.isRegExpLiteral(node.callee.object) && node.arguments[0]) {
|
|
3856
|
+
return extractFieldFromCondition(node.arguments[0], paramName);
|
|
3857
|
+
}
|
|
3858
|
+
if (t12.isLogicalExpression(node)) {
|
|
3859
|
+
return extractFieldFromCondition(node.left, paramName) || extractFieldFromCondition(node.right, paramName);
|
|
3860
|
+
}
|
|
3861
|
+
if (t12.isUnaryExpression(node)) {
|
|
3862
|
+
return extractFieldFromCondition(node.argument, paramName);
|
|
3863
|
+
}
|
|
3864
|
+
return null;
|
|
3865
|
+
}
|
|
3866
|
+
function isLengthAccess(node, paramName, field) {
|
|
3867
|
+
if (!t12.isMemberExpression(node)) return false;
|
|
3868
|
+
const str = memberExprToString(node);
|
|
3869
|
+
return str === `${paramName}.${field}.length`;
|
|
3870
|
+
}
|
|
3871
|
+
function isFieldAccess(node, paramName, field) {
|
|
3872
|
+
if (!t12.isMemberExpression(node)) return false;
|
|
3873
|
+
const str = memberExprToString(node);
|
|
3874
|
+
return str === `${paramName}.${field}`;
|
|
3875
|
+
}
|
|
3876
|
+
function expressionToIR(node, paramName) {
|
|
3877
|
+
if (t12.isStringLiteral(node)) return `"${node.value}"`;
|
|
3878
|
+
if (t12.isNumericLiteral(node)) return String(node.value);
|
|
3879
|
+
if (t12.isBooleanLiteral(node)) return String(node.value);
|
|
3880
|
+
if (t12.isNullLiteral(node)) return "null";
|
|
3881
|
+
if (t12.isIdentifier(node)) {
|
|
3882
|
+
if (node.name === paramName) return "state_data";
|
|
3883
|
+
if (node.name === "actor") return "context";
|
|
3884
|
+
if (node.name === "instance") return "instance";
|
|
3885
|
+
return node.name;
|
|
3886
|
+
}
|
|
3887
|
+
if (t12.isMemberExpression(node)) {
|
|
3888
|
+
const str = memberExprToString(node);
|
|
3889
|
+
if (str.startsWith(`${paramName}.`)) return "state_data." + str.slice(paramName.length + 1);
|
|
3890
|
+
if (str.startsWith("actor.")) return "context." + str.slice(6);
|
|
3891
|
+
if (str.startsWith("Date.")) {
|
|
3892
|
+
if (str === "Date.now") return "NOW()";
|
|
3893
|
+
}
|
|
3894
|
+
return str;
|
|
3895
|
+
}
|
|
3896
|
+
if (t12.isCallExpression(node)) {
|
|
3897
|
+
if (t12.isMemberExpression(node.callee) && t12.isIdentifier(node.callee.property)) {
|
|
3898
|
+
const obj = expressionToIR(node.callee.object, paramName);
|
|
3899
|
+
const method = node.callee.property.name;
|
|
3900
|
+
if (method === "now" && obj === "Date") return "NOW()";
|
|
3901
|
+
if (method === "includes") {
|
|
3902
|
+
const arg = node.arguments[0] ? expressionToIR(node.arguments[0], paramName) : "";
|
|
3903
|
+
return `CONTAINS(${obj}, ${arg})`;
|
|
3904
|
+
}
|
|
3905
|
+
if (method === "length") return `LEN(${obj})`;
|
|
3906
|
+
}
|
|
3907
|
+
if (t12.isIdentifier(node.callee) && node.callee.name === "Date") {
|
|
3908
|
+
if (t12.isMemberExpression(node) && t12.isIdentifier(node.property) && node.property.name === "now") {
|
|
3909
|
+
return "NOW()";
|
|
3910
|
+
}
|
|
3911
|
+
}
|
|
3912
|
+
return "[call]";
|
|
3913
|
+
}
|
|
3914
|
+
if (t12.isBinaryExpression(node)) {
|
|
3915
|
+
const left = expressionToIR(node.left, paramName);
|
|
3916
|
+
const right = expressionToIR(node.right, paramName);
|
|
3917
|
+
return `${left} ${node.operator} ${right}`;
|
|
3918
|
+
}
|
|
3919
|
+
if (t12.isLogicalExpression(node)) {
|
|
3920
|
+
const left = expressionToIR(node.left, paramName);
|
|
3921
|
+
const right = expressionToIR(node.right, paramName);
|
|
3922
|
+
const op = node.operator === "&&" ? "AND" : node.operator === "||" ? "OR" : node.operator;
|
|
3923
|
+
return `${left} ${op} ${right}`;
|
|
3924
|
+
}
|
|
3925
|
+
if (t12.isUnaryExpression(node)) {
|
|
3926
|
+
if (node.operator === "!") return `NOT(${expressionToIR(node.argument, paramName)})`;
|
|
3927
|
+
return `${node.operator}${expressionToIR(node.argument, paramName)}`;
|
|
3928
|
+
}
|
|
3929
|
+
if (t12.isConditionalExpression(node)) {
|
|
3930
|
+
return `IF(${expressionToIR(node.test, paramName)}, ${expressionToIR(node.consequent, paramName)}, ${expressionToIR(node.alternate, paramName)})`;
|
|
3931
|
+
}
|
|
3932
|
+
if (t12.isTemplateLiteral(node)) {
|
|
3933
|
+
const parts = [];
|
|
3934
|
+
for (let i = 0; i < node.quasis.length; i++) {
|
|
3935
|
+
parts.push(node.quasis[i].value.raw);
|
|
3936
|
+
if (i < node.expressions.length) {
|
|
3937
|
+
parts.push(`{{ ${expressionToIR(node.expressions[i], paramName)} }}`);
|
|
3938
|
+
}
|
|
3939
|
+
}
|
|
3940
|
+
return `"${parts.join("")}"`;
|
|
3941
|
+
}
|
|
3942
|
+
if (t12.isRegExpLiteral(node)) return node.pattern;
|
|
3943
|
+
return "[expr]";
|
|
3944
|
+
}
|
|
3945
|
+
function extractCallSequence(body, paramName, localFnNames, importedFns) {
|
|
3946
|
+
const calls = [];
|
|
3947
|
+
for (const stmt of body.body) {
|
|
3948
|
+
extractCallsFromStatement(stmt, paramName, localFnNames, importedFns, calls);
|
|
3949
|
+
}
|
|
3950
|
+
return calls;
|
|
3951
|
+
}
|
|
3952
|
+
function extractCallsFromStatement(stmt, paramName, localFnNames, importedFns, calls, condition) {
|
|
3953
|
+
if (t12.isExpressionStatement(stmt)) {
|
|
3954
|
+
const expr = stmt.expression;
|
|
3955
|
+
if (t12.isAwaitExpression(expr)) {
|
|
3956
|
+
const call = extractWorkflowCall(expr.argument, paramName, localFnNames, importedFns);
|
|
3957
|
+
if (call) {
|
|
3958
|
+
if (condition) call.condition = condition;
|
|
3959
|
+
calls.push(call);
|
|
3960
|
+
}
|
|
3961
|
+
}
|
|
3962
|
+
if (t12.isCallExpression(expr) && t12.isIdentifier(expr.callee) && expr.callee.name === "allowTransition") {
|
|
3963
|
+
}
|
|
3964
|
+
}
|
|
3965
|
+
if (t12.isVariableDeclaration(stmt)) {
|
|
3966
|
+
for (const decl of stmt.declarations) {
|
|
3967
|
+
if (decl.init && t12.isAwaitExpression(decl.init)) {
|
|
3968
|
+
const call = extractWorkflowCall(decl.init.argument, paramName, localFnNames, importedFns);
|
|
3969
|
+
if (call) {
|
|
3970
|
+
if (condition) call.condition = condition;
|
|
3971
|
+
calls.push(call);
|
|
3972
|
+
}
|
|
3973
|
+
}
|
|
3974
|
+
}
|
|
3975
|
+
}
|
|
3976
|
+
if (t12.isIfStatement(stmt)) {
|
|
3977
|
+
const condStr = expressionToIR(stmt.test, paramName);
|
|
3978
|
+
if (t12.isBlockStatement(stmt.consequent)) {
|
|
3979
|
+
for (const inner of stmt.consequent.body) {
|
|
3980
|
+
extractCallsFromStatement(inner, paramName, localFnNames, importedFns, calls, condStr);
|
|
3981
|
+
}
|
|
3982
|
+
}
|
|
3983
|
+
if (stmt.alternate) {
|
|
3984
|
+
const negCond = `NOT(${condStr})`;
|
|
3985
|
+
if (t12.isBlockStatement(stmt.alternate)) {
|
|
3986
|
+
for (const inner of stmt.alternate.body) {
|
|
3987
|
+
extractCallsFromStatement(inner, paramName, localFnNames, importedFns, calls, negCond);
|
|
3988
|
+
}
|
|
3989
|
+
} else if (t12.isIfStatement(stmt.alternate)) {
|
|
3990
|
+
extractCallsFromStatement(stmt.alternate, paramName, localFnNames, importedFns, calls);
|
|
3991
|
+
}
|
|
3992
|
+
}
|
|
3993
|
+
}
|
|
3994
|
+
if (t12.isTryStatement(stmt)) {
|
|
3995
|
+
const tryBlockCalls = [];
|
|
3996
|
+
if (stmt.block) {
|
|
3997
|
+
for (const inner of stmt.block.body) {
|
|
3998
|
+
extractCallsFromStatement(inner, paramName, localFnNames, importedFns, tryBlockCalls, condition);
|
|
3999
|
+
}
|
|
4000
|
+
}
|
|
4001
|
+
calls.push(...tryBlockCalls);
|
|
4002
|
+
if (stmt.handler && stmt.handler.body) {
|
|
4003
|
+
const catchBody = stmt.handler.body;
|
|
4004
|
+
const compensationActions = [];
|
|
4005
|
+
const catchParamName = stmt.handler.param && t12.isIdentifier(stmt.handler.param) ? stmt.handler.param.name : "error";
|
|
4006
|
+
const hasReturn = catchBody.body.some((s) => t12.isReturnStatement(s));
|
|
4007
|
+
for (const inner of catchBody.body) {
|
|
4008
|
+
if (t12.isReturnStatement(inner)) continue;
|
|
4009
|
+
extractCallsFromStatement(inner, paramName, localFnNames, importedFns, compensationActions, condition);
|
|
4010
|
+
}
|
|
4011
|
+
calls.push({
|
|
4012
|
+
type: "stateCall",
|
|
4013
|
+
name: `__compensation_${calls.length}`,
|
|
4014
|
+
options: {
|
|
4015
|
+
__isCompensation: true,
|
|
4016
|
+
__tryBlockCallNames: tryBlockCalls.map((c) => c.name),
|
|
4017
|
+
__compensationCalls: compensationActions,
|
|
4018
|
+
__hasReturn: hasReturn,
|
|
4019
|
+
__catchParam: catchParamName,
|
|
4020
|
+
__catchBody: catchBody
|
|
4021
|
+
}
|
|
4022
|
+
});
|
|
4023
|
+
}
|
|
4024
|
+
}
|
|
4025
|
+
if (t12.isSwitchStatement(stmt)) {
|
|
4026
|
+
}
|
|
4027
|
+
}
|
|
4028
|
+
function extractWorkflowCall(node, paramName, localFnNames, importedFns) {
|
|
4029
|
+
if (t12.isCallExpression(node)) {
|
|
4030
|
+
const callee = node.callee;
|
|
4031
|
+
if (t12.isIdentifier(callee) && callee.name === "named" && node.arguments.length >= 2) {
|
|
4032
|
+
const name = t12.isStringLiteral(node.arguments[0]) ? node.arguments[0].value : "";
|
|
4033
|
+
const inner = node.arguments[1];
|
|
4034
|
+
if (t12.isCallExpression(inner) || t12.isAwaitExpression(inner)) {
|
|
4035
|
+
const innerNode = t12.isAwaitExpression(inner) ? inner.argument : inner;
|
|
4036
|
+
const innerCall = extractWorkflowCall(innerNode, paramName, localFnNames, importedFns);
|
|
4037
|
+
if (innerCall) {
|
|
4038
|
+
innerCall.transitionName = name;
|
|
4039
|
+
return innerCall;
|
|
4040
|
+
}
|
|
4041
|
+
}
|
|
4042
|
+
return null;
|
|
4043
|
+
}
|
|
4044
|
+
if (t12.isIdentifier(callee) && callee.name === "userAction") {
|
|
4045
|
+
const name = node.arguments[0] && t12.isStringLiteral(node.arguments[0]) ? node.arguments[0].value : "action";
|
|
4046
|
+
const opts = node.arguments[1] ? extractNodeValue2(node.arguments[1]) : {};
|
|
4047
|
+
return { type: "userAction", name, options: opts };
|
|
4048
|
+
}
|
|
4049
|
+
if (t12.isIdentifier(callee) && callee.name === "userChoice") {
|
|
4050
|
+
const choices = node.arguments[0] ? extractNodeValue2(node.arguments[0]) : {};
|
|
4051
|
+
return { type: "userChoice", name: "choice", choices };
|
|
4052
|
+
}
|
|
4053
|
+
if (t12.isIdentifier(callee) && callee.name === "delay") {
|
|
4054
|
+
const duration = node.arguments[0] && t12.isStringLiteral(node.arguments[0]) ? node.arguments[0].value : "0";
|
|
4055
|
+
return { type: "delay", name: `delay_${duration}` };
|
|
4056
|
+
}
|
|
4057
|
+
if (t12.isIdentifier(callee) && callee.name === "on") {
|
|
4058
|
+
const pattern = node.arguments[0] && t12.isStringLiteral(node.arguments[0]) ? node.arguments[0].value : "*";
|
|
4059
|
+
const opts = node.arguments[1] ? extractNodeValue2(node.arguments[1]) : {};
|
|
4060
|
+
opts.__eventPattern = pattern;
|
|
4061
|
+
return { type: "awaitOn", name: pattern.replace(/[^a-zA-Z0-9]/g, "_"), options: opts };
|
|
4062
|
+
}
|
|
4063
|
+
if (t12.isMemberExpression(callee) && t12.isIdentifier(callee.object) && callee.object.name === "Promise" && t12.isIdentifier(callee.property)) {
|
|
4064
|
+
if (callee.property.name === "all" && node.arguments[0] && t12.isArrayExpression(node.arguments[0])) {
|
|
4065
|
+
const parallelCalls = [];
|
|
4066
|
+
for (const el of node.arguments[0].elements) {
|
|
4067
|
+
if (!el || t12.isSpreadElement(el)) continue;
|
|
4068
|
+
const innerNode = t12.isAwaitExpression(el) ? el.argument : el;
|
|
4069
|
+
const c = extractWorkflowCall(innerNode, paramName, localFnNames, importedFns);
|
|
4070
|
+
if (c) parallelCalls.push(c);
|
|
4071
|
+
}
|
|
4072
|
+
return { type: "promiseAll", name: "parallel", parallelCalls };
|
|
4073
|
+
}
|
|
4074
|
+
if (callee.property.name === "race" && node.arguments[0] && t12.isArrayExpression(node.arguments[0])) {
|
|
4075
|
+
const parallelCalls = [];
|
|
4076
|
+
for (const el of node.arguments[0].elements) {
|
|
4077
|
+
if (!el || t12.isSpreadElement(el)) continue;
|
|
4078
|
+
const innerNode = t12.isAwaitExpression(el) ? el.argument : el;
|
|
4079
|
+
const c = extractWorkflowCall(innerNode, paramName, localFnNames, importedFns);
|
|
4080
|
+
if (c) parallelCalls.push(c);
|
|
4081
|
+
}
|
|
4082
|
+
return { type: "promiseRace", name: "race", parallelCalls };
|
|
4083
|
+
}
|
|
4084
|
+
}
|
|
4085
|
+
if (t12.isIdentifier(callee) && localFnNames.has(callee.name)) {
|
|
4086
|
+
return { type: "stateCall", name: callee.name };
|
|
4087
|
+
}
|
|
4088
|
+
if (t12.isIdentifier(callee) && importedFns.has(callee.name)) {
|
|
4089
|
+
return {
|
|
4090
|
+
type: "serviceCall",
|
|
4091
|
+
name: callee.name,
|
|
4092
|
+
importSource: importedFns.get(callee.name)
|
|
4093
|
+
};
|
|
4094
|
+
}
|
|
4095
|
+
}
|
|
4096
|
+
return null;
|
|
4097
|
+
}
|
|
4098
|
+
function extractAllowTransitions(body) {
|
|
4099
|
+
const result = [];
|
|
4100
|
+
for (const stmt of body.body) {
|
|
4101
|
+
if (!t12.isExpressionStatement(stmt)) continue;
|
|
4102
|
+
const expr = stmt.expression;
|
|
4103
|
+
if (!t12.isCallExpression(expr)) continue;
|
|
4104
|
+
if (!t12.isIdentifier(expr.callee) || expr.callee.name !== "allowTransition") continue;
|
|
4105
|
+
const nameArg = expr.arguments[0];
|
|
4106
|
+
const optsArg = expr.arguments[1];
|
|
4107
|
+
if (!t12.isStringLiteral(nameArg)) continue;
|
|
4108
|
+
const name = nameArg.value;
|
|
4109
|
+
const opts = optsArg && t12.isObjectExpression(optsArg) ? extractNodeValue2(optsArg) : {};
|
|
4110
|
+
let from = [];
|
|
4111
|
+
if (typeof opts.from === "string") from = [opts.from];
|
|
4112
|
+
else if (Array.isArray(opts.from)) from = opts.from.map(String);
|
|
4113
|
+
result.push({
|
|
4114
|
+
name,
|
|
4115
|
+
from,
|
|
4116
|
+
to: String(opts.to || ""),
|
|
4117
|
+
...opts.roles ? { roles: opts.roles } : {},
|
|
4118
|
+
...opts.require ? { require: opts.require } : {},
|
|
4119
|
+
...opts.when ? { when: String(opts.when) } : {}
|
|
4120
|
+
});
|
|
4121
|
+
}
|
|
4122
|
+
return result;
|
|
4123
|
+
}
|
|
4124
|
+
function parseDuration(str) {
|
|
4125
|
+
const match = str.match(/^(\d+(?:\.\d+)?)\s*(ms|s|m|h|d|w)$/);
|
|
4126
|
+
if (!match) return 0;
|
|
4127
|
+
const value = parseFloat(match[1]);
|
|
4128
|
+
switch (match[2]) {
|
|
4129
|
+
case "ms":
|
|
4130
|
+
return value;
|
|
4131
|
+
case "s":
|
|
4132
|
+
return value * 1e3;
|
|
4133
|
+
case "m":
|
|
4134
|
+
return value * 6e4;
|
|
4135
|
+
case "h":
|
|
4136
|
+
return value * 36e5;
|
|
4137
|
+
case "d":
|
|
4138
|
+
return value * 864e5;
|
|
4139
|
+
case "w":
|
|
4140
|
+
return value * 6048e5;
|
|
4141
|
+
default:
|
|
4142
|
+
return 0;
|
|
4143
|
+
}
|
|
4144
|
+
}
|
|
4145
|
+
function toSnakeCase2(name) {
|
|
4146
|
+
return name.replace(/([A-Z])/g, "_$1").toLowerCase().replace(/^_/, "");
|
|
4147
|
+
}
|
|
4148
|
+
function fnNameToSlug(name) {
|
|
4149
|
+
return name.replace(/([A-Z])/g, "-$1").toLowerCase().replace(/^-/, "");
|
|
4150
|
+
}
|
|
4151
|
+
function extractStateDataRefs(expression) {
|
|
4152
|
+
const refs = [];
|
|
4153
|
+
const regex = /state_data\.(\w+)/g;
|
|
4154
|
+
let match;
|
|
4155
|
+
while ((match = regex.exec(expression)) !== null) {
|
|
4156
|
+
refs.push(match[1]);
|
|
4157
|
+
}
|
|
4158
|
+
return [...new Set(refs)];
|
|
4159
|
+
}
|
|
4160
|
+
function detectComputedFieldsFromActions(compilerState, stateFnInfos) {
|
|
4161
|
+
for (const [, info] of stateFnInfos) {
|
|
4162
|
+
for (const action of info.onEnter) {
|
|
4163
|
+
if (action.type !== "set_field") continue;
|
|
4164
|
+
const config = action.config;
|
|
4165
|
+
if (!config?.field || !config?.expression) continue;
|
|
4166
|
+
const targetField = config.field;
|
|
4167
|
+
const expression = config.expression;
|
|
4168
|
+
const refs = extractStateDataRefs(expression);
|
|
4169
|
+
const deps = refs.filter((r) => r !== targetField);
|
|
4170
|
+
if (deps.length === 0) continue;
|
|
4171
|
+
const field = compilerState.fields.find((f) => f.name === targetField);
|
|
4172
|
+
if (field) {
|
|
4173
|
+
field.computed = expression;
|
|
4174
|
+
field.computed_deps = deps;
|
|
4175
|
+
}
|
|
4176
|
+
}
|
|
4177
|
+
}
|
|
4178
|
+
}
|
|
4179
|
+
function detectComputedFieldGetters(path, paramName, paramTypeName, compilerState) {
|
|
4180
|
+
for (const node of path.node.body) {
|
|
4181
|
+
if (!t12.isFunctionDeclaration(node)) continue;
|
|
4182
|
+
if (node.async) continue;
|
|
4183
|
+
if (!node.id) continue;
|
|
4184
|
+
if (node.params.length !== 1) continue;
|
|
4185
|
+
const fnParam = node.params[0];
|
|
4186
|
+
if (!t12.isIdentifier(fnParam)) continue;
|
|
4187
|
+
if (fnParam.typeAnnotation && t12.isTSTypeAnnotation(fnParam.typeAnnotation)) {
|
|
4188
|
+
const typeAnno = fnParam.typeAnnotation.typeAnnotation;
|
|
4189
|
+
if (t12.isTSTypeReference(typeAnno) && t12.isIdentifier(typeAnno.typeName)) {
|
|
4190
|
+
if (typeAnno.typeName.name !== paramTypeName) continue;
|
|
4191
|
+
} else {
|
|
4192
|
+
continue;
|
|
4193
|
+
}
|
|
4194
|
+
} else {
|
|
4195
|
+
continue;
|
|
4196
|
+
}
|
|
4197
|
+
const hasReturnType = node.returnType && t12.isTSTypeAnnotation(node.returnType);
|
|
4198
|
+
if (!node.body || !t12.isBlockStatement(node.body)) continue;
|
|
4199
|
+
const returnStmt = node.body.body.find(
|
|
4200
|
+
(s) => t12.isReturnStatement(s)
|
|
4201
|
+
);
|
|
4202
|
+
if (!returnStmt?.argument) continue;
|
|
4203
|
+
const getterParamName = fnParam.name;
|
|
4204
|
+
const expression = expressionToIR(returnStmt.argument, getterParamName);
|
|
4205
|
+
const deps = extractStateDataRefs(expression);
|
|
4206
|
+
if (deps.length === 0) continue;
|
|
4207
|
+
const fieldName = node.id.name;
|
|
4208
|
+
let field = compilerState.fields.find((f) => f.name === fieldName);
|
|
4209
|
+
if (field) {
|
|
4210
|
+
field.computed = expression;
|
|
4211
|
+
field.computed_deps = deps;
|
|
4212
|
+
} else {
|
|
4213
|
+
let fieldType = "text";
|
|
4214
|
+
if (hasReturnType) {
|
|
4215
|
+
const retType = node.returnType.typeAnnotation;
|
|
4216
|
+
fieldType = resolveType2(retType);
|
|
4217
|
+
}
|
|
4218
|
+
compilerState.fields.push({
|
|
4219
|
+
name: fieldName,
|
|
4220
|
+
type: fieldType,
|
|
4221
|
+
label: fieldName.replace(/([A-Z])/g, " $1").replace(/^./, (c) => c.toUpperCase()),
|
|
4222
|
+
required: false,
|
|
4223
|
+
computed: expression,
|
|
4224
|
+
computed_deps: deps
|
|
4225
|
+
});
|
|
4226
|
+
}
|
|
4227
|
+
}
|
|
4228
|
+
}
|
|
4229
|
+
function extractImperativeWorkflow(path, state) {
|
|
4230
|
+
const compilerState = state;
|
|
4231
|
+
if (!compilerState.actionCounter) compilerState.actionCounter = 0;
|
|
4232
|
+
const actionCounter = { value: compilerState.actionCounter };
|
|
4233
|
+
const importedFns = /* @__PURE__ */ new Map();
|
|
4234
|
+
const stdLibImports = /* @__PURE__ */ new Set();
|
|
4235
|
+
for (const node of path.node.body) {
|
|
4236
|
+
if (t12.isImportDeclaration(node)) {
|
|
4237
|
+
const source = node.source.value;
|
|
4238
|
+
for (const spec of node.specifiers) {
|
|
4239
|
+
const localName = spec.local.name;
|
|
4240
|
+
if (source.includes("@mmapp/react") || source.includes("@mmapp/react")) {
|
|
4241
|
+
stdLibImports.add(localName);
|
|
4242
|
+
} else {
|
|
4243
|
+
importedFns.set(localName, source);
|
|
4244
|
+
}
|
|
4245
|
+
}
|
|
4246
|
+
}
|
|
4247
|
+
}
|
|
4248
|
+
for (const node of path.node.body) {
|
|
4249
|
+
if (t12.isExportDefaultDeclaration(node) && t12.isCallExpression(node.declaration)) {
|
|
4250
|
+
const call = node.declaration;
|
|
4251
|
+
if (t12.isIdentifier(call.callee) && call.callee.name === "workflow") {
|
|
4252
|
+
const slugArg = call.arguments[0] && t12.isStringLiteral(call.arguments[0]) ? call.arguments[0].value : "workflow";
|
|
4253
|
+
let fieldsOrArrow = "";
|
|
4254
|
+
let arrowString;
|
|
4255
|
+
if (call.arguments.length === 2) {
|
|
4256
|
+
const arg1 = call.arguments[1];
|
|
4257
|
+
if (t12.isStringLiteral(arg1)) {
|
|
4258
|
+
fieldsOrArrow = arg1.value;
|
|
4259
|
+
} else if (t12.isTemplateLiteral(arg1)) {
|
|
4260
|
+
fieldsOrArrow = arg1.quasis.map((q) => q.value.raw).join("");
|
|
4261
|
+
} else if (t12.isObjectExpression(arg1)) {
|
|
4262
|
+
fieldsOrArrow = extractNodeValue2(arg1);
|
|
4263
|
+
}
|
|
4264
|
+
} else if (call.arguments.length >= 3) {
|
|
4265
|
+
const arg1 = call.arguments[1];
|
|
4266
|
+
const arg2 = call.arguments[2];
|
|
4267
|
+
if (t12.isObjectExpression(arg1)) {
|
|
4268
|
+
fieldsOrArrow = extractNodeValue2(arg1);
|
|
4269
|
+
}
|
|
4270
|
+
if (t12.isStringLiteral(arg2)) {
|
|
4271
|
+
arrowString = arg2.value;
|
|
4272
|
+
} else if (t12.isTemplateLiteral(arg2)) {
|
|
4273
|
+
arrowString = arg2.quasis.map((q) => q.value.raw).join("");
|
|
4274
|
+
}
|
|
4275
|
+
}
|
|
4276
|
+
const result = parseWorkflowShorthand(slugArg, fieldsOrArrow, arrowString);
|
|
4277
|
+
compilerState.metadata.slug = result.slug;
|
|
4278
|
+
compilerState.metadata.category = "workflow";
|
|
4279
|
+
compilerState.fields.push(...result.fields);
|
|
4280
|
+
for (const s of result.states) {
|
|
4281
|
+
compilerState.states.set(s.name, s);
|
|
4282
|
+
}
|
|
4283
|
+
compilerState.transitions.push(...result.transitions);
|
|
4284
|
+
compilerState.actionCounter = actionCounter.value;
|
|
4285
|
+
return;
|
|
4286
|
+
}
|
|
4287
|
+
}
|
|
4288
|
+
}
|
|
4289
|
+
let parentFn = null;
|
|
4290
|
+
let parentName = "";
|
|
4291
|
+
let paramName = "";
|
|
4292
|
+
let paramTypeName = "";
|
|
4293
|
+
for (const node of path.node.body) {
|
|
4294
|
+
if (t12.isExportDefaultDeclaration(node) && t12.isFunctionDeclaration(node.declaration)) {
|
|
4295
|
+
const fn = node.declaration;
|
|
4296
|
+
if (fn.async && fn.params.length > 0) {
|
|
4297
|
+
parentFn = fn;
|
|
4298
|
+
parentName = fn.id?.name || "workflow";
|
|
4299
|
+
const param = fn.params[0];
|
|
4300
|
+
if (t12.isIdentifier(param)) {
|
|
4301
|
+
paramName = param.name;
|
|
4302
|
+
if (param.typeAnnotation && t12.isTSTypeAnnotation(param.typeAnnotation)) {
|
|
4303
|
+
const typeAnno = param.typeAnnotation.typeAnnotation;
|
|
4304
|
+
if (t12.isTSTypeReference(typeAnno) && t12.isIdentifier(typeAnno.typeName)) {
|
|
4305
|
+
paramTypeName = typeAnno.typeName.name;
|
|
4306
|
+
}
|
|
4307
|
+
}
|
|
4308
|
+
}
|
|
4309
|
+
}
|
|
4310
|
+
}
|
|
4311
|
+
}
|
|
4312
|
+
if (!parentFn || !paramName) return;
|
|
4313
|
+
const slug = fnNameToSlug(parentName.replace(/Workflow$/, ""));
|
|
4314
|
+
compilerState.metadata.slug = slug;
|
|
4315
|
+
compilerState.metadata.category = "workflow";
|
|
4316
|
+
for (const node of path.node.body) {
|
|
4317
|
+
if (t12.isTSInterfaceDeclaration(node) && node.id.name === paramTypeName) {
|
|
4318
|
+
const fields = extractFieldsFromInterface2(node);
|
|
4319
|
+
compilerState.fields.push(...fields);
|
|
4320
|
+
compilerState.metadata.name = paramTypeName;
|
|
4321
|
+
}
|
|
4322
|
+
if (t12.isExportNamedDeclaration(node) && t12.isTSInterfaceDeclaration(node.declaration) && node.declaration.id.name === paramTypeName) {
|
|
4323
|
+
const fields = extractFieldsFromInterface2(node.declaration);
|
|
4324
|
+
compilerState.fields.push(...fields);
|
|
4325
|
+
compilerState.metadata.name = paramTypeName;
|
|
4326
|
+
}
|
|
4327
|
+
}
|
|
4328
|
+
const localFns = /* @__PURE__ */ new Map();
|
|
4329
|
+
const localFnNames = /* @__PURE__ */ new Set();
|
|
4330
|
+
for (const node of path.node.body) {
|
|
4331
|
+
if (t12.isFunctionDeclaration(node) && node.async && node.id) {
|
|
4332
|
+
if (node.id.name !== parentName) {
|
|
4333
|
+
localFns.set(node.id.name, node);
|
|
4334
|
+
localFnNames.add(node.id.name);
|
|
4335
|
+
}
|
|
4336
|
+
}
|
|
4337
|
+
if (t12.isExportNamedDeclaration(node) && t12.isFunctionDeclaration(node.declaration) && node.declaration.async && node.declaration.id) {
|
|
4338
|
+
if (node.declaration.id.name !== parentName) {
|
|
4339
|
+
localFns.set(node.declaration.id.name, node.declaration);
|
|
4340
|
+
localFnNames.add(node.declaration.id.name);
|
|
4341
|
+
}
|
|
4342
|
+
}
|
|
4343
|
+
}
|
|
4344
|
+
for (const node of path.node.body) {
|
|
4345
|
+
if (t12.isExportNamedDeclaration(node) && t12.isVariableDeclaration(node.declaration)) {
|
|
4346
|
+
for (const decl of node.declaration.declarations) {
|
|
4347
|
+
if (t12.isIdentifier(decl.id) && decl.id.name === "defaults" && t12.isObjectExpression(decl.init)) {
|
|
4348
|
+
const defaults = extractNodeValue2(decl.init);
|
|
4349
|
+
for (const [name, value] of Object.entries(defaults)) {
|
|
4350
|
+
const field = compilerState.fields.find((f) => f.name === name);
|
|
4351
|
+
if (field && value !== void 0) {
|
|
4352
|
+
field.default_value = value;
|
|
4353
|
+
}
|
|
4354
|
+
}
|
|
4355
|
+
}
|
|
4356
|
+
}
|
|
4357
|
+
}
|
|
4358
|
+
}
|
|
4359
|
+
const stateFnInfos = /* @__PURE__ */ new Map();
|
|
4360
|
+
for (const [name, fn] of localFns) {
|
|
4361
|
+
const fnParamName = fn.params[0] && t12.isIdentifier(fn.params[0]) ? fn.params[0].name : paramName;
|
|
4362
|
+
const analysis = analyzeStateFn(fn, fnParamName, actionCounter);
|
|
4363
|
+
stateFnInfos.set(name, {
|
|
4364
|
+
name,
|
|
4365
|
+
node: fn,
|
|
4366
|
+
params: fn.params.map((p) => t12.isIdentifier(p) ? p.name : ""),
|
|
4367
|
+
...analysis
|
|
4368
|
+
});
|
|
4369
|
+
}
|
|
4370
|
+
detectComputedFieldsFromActions(compilerState, stateFnInfos);
|
|
4371
|
+
detectComputedFieldGetters(path, paramName, paramTypeName, compilerState);
|
|
4372
|
+
const callSequence = extractCallSequence(
|
|
4373
|
+
parentFn.body,
|
|
4374
|
+
paramName,
|
|
4375
|
+
localFnNames,
|
|
4376
|
+
importedFns
|
|
4377
|
+
);
|
|
4378
|
+
const allowTransitions = extractAllowTransitions(parentFn.body);
|
|
4379
|
+
const referencedStates = /* @__PURE__ */ new Set();
|
|
4380
|
+
let firstStateName = "";
|
|
4381
|
+
let prevStateName = "";
|
|
4382
|
+
let transitionIndex = 0;
|
|
4383
|
+
for (const call of callSequence) {
|
|
4384
|
+
const stateName = toSnakeCase2(call.name);
|
|
4385
|
+
switch (call.type) {
|
|
4386
|
+
case "stateCall": {
|
|
4387
|
+
if (call.name.startsWith("__compensation_") && call.options?.__isCompensation) {
|
|
4388
|
+
const compOpts = call.options;
|
|
4389
|
+
const tryCallNames = compOpts.__tryBlockCallNames || [];
|
|
4390
|
+
const compensationCalls = compOpts.__compensationCalls || [];
|
|
4391
|
+
const hasReturn = compOpts.__hasReturn;
|
|
4392
|
+
const catchBody = compOpts.__catchBody;
|
|
4393
|
+
const compIndex = ++transitionIndex;
|
|
4394
|
+
const compStateName = `compensation_${compIndex}`;
|
|
4395
|
+
const compActions = [];
|
|
4396
|
+
if (catchBody) {
|
|
4397
|
+
for (const innerStmt of catchBody.body) {
|
|
4398
|
+
if (t12.isReturnStatement(innerStmt)) continue;
|
|
4399
|
+
if (t12.isExpressionStatement(innerStmt)) {
|
|
4400
|
+
const innerExpr = innerStmt.expression;
|
|
4401
|
+
if (t12.isAssignmentExpression(innerExpr) && t12.isMemberExpression(innerExpr.left)) {
|
|
4402
|
+
const left = memberExprToString(innerExpr.left);
|
|
4403
|
+
if (left.startsWith(`${paramName}.`)) {
|
|
4404
|
+
const field = left.slice(paramName.length + 1);
|
|
4405
|
+
const valueExpr = expressionToIR(innerExpr.right, paramName);
|
|
4406
|
+
compActions.push({
|
|
4407
|
+
id: `auto_${++actionCounter.value}`,
|
|
4408
|
+
type: "set_field",
|
|
4409
|
+
mode: "auto",
|
|
4410
|
+
config: { field, expression: valueExpr }
|
|
4411
|
+
});
|
|
4412
|
+
}
|
|
4413
|
+
}
|
|
4414
|
+
if (t12.isAwaitExpression(innerExpr) && t12.isCallExpression(innerExpr.argument)) {
|
|
4415
|
+
const innerCall = innerExpr.argument;
|
|
4416
|
+
const fnName = t12.isIdentifier(innerCall.callee) ? innerCall.callee.name : null;
|
|
4417
|
+
if (fnName && importedFns.has(fnName)) {
|
|
4418
|
+
compActions.push({
|
|
4419
|
+
id: `auto_${++actionCounter.value}`,
|
|
4420
|
+
type: "call_workflow",
|
|
4421
|
+
mode: "auto",
|
|
4422
|
+
config: { definition_slug: fnNameToSlug(fnName), blocking: true }
|
|
4423
|
+
});
|
|
4424
|
+
}
|
|
4425
|
+
if (fnName === "log") {
|
|
4426
|
+
const event = innerCall.arguments[0] ? extractNodeValue2(innerCall.arguments[0]) : "";
|
|
4427
|
+
compActions.push({
|
|
4428
|
+
id: `auto_${++actionCounter.value}`,
|
|
4429
|
+
type: "log_event",
|
|
4430
|
+
mode: "auto",
|
|
4431
|
+
config: { event: String(event) }
|
|
4432
|
+
});
|
|
4433
|
+
}
|
|
4434
|
+
if (fnName === "notify") {
|
|
4435
|
+
const to = innerCall.arguments[0] ? expressionToIR(innerCall.arguments[0], paramName) : "";
|
|
4436
|
+
const message = innerCall.arguments[1] ? extractNodeValue2(innerCall.arguments[1]) : "";
|
|
4437
|
+
compActions.push({
|
|
4438
|
+
id: `auto_${++actionCounter.value}`,
|
|
4439
|
+
type: "send_notification",
|
|
4440
|
+
mode: "auto",
|
|
4441
|
+
config: { to: String(to), message: String(message) }
|
|
4442
|
+
});
|
|
4443
|
+
}
|
|
4444
|
+
if (fnName === "emit") {
|
|
4445
|
+
const event = innerCall.arguments[0] ? extractNodeValue2(innerCall.arguments[0]) : "";
|
|
4446
|
+
compActions.push({
|
|
4447
|
+
id: `auto_${++actionCounter.value}`,
|
|
4448
|
+
type: "emit_event",
|
|
4449
|
+
mode: "auto",
|
|
4450
|
+
config: { event: String(event) }
|
|
4451
|
+
});
|
|
4452
|
+
}
|
|
4453
|
+
}
|
|
4454
|
+
if (t12.isCallExpression(innerExpr)) {
|
|
4455
|
+
const fnName = t12.isIdentifier(innerExpr.callee) ? innerExpr.callee.name : null;
|
|
4456
|
+
if (fnName === "log") {
|
|
4457
|
+
const event = innerExpr.arguments[0] ? extractNodeValue2(innerExpr.arguments[0]) : "";
|
|
4458
|
+
compActions.push({
|
|
4459
|
+
id: `auto_${++actionCounter.value}`,
|
|
4460
|
+
type: "log_event",
|
|
4461
|
+
mode: "auto",
|
|
4462
|
+
config: { event: String(event) }
|
|
4463
|
+
});
|
|
4464
|
+
}
|
|
4465
|
+
if (fnName === "notify") {
|
|
4466
|
+
const to = innerExpr.arguments[0] ? expressionToIR(innerExpr.arguments[0], paramName) : "";
|
|
4467
|
+
const message = innerExpr.arguments[1] ? extractNodeValue2(innerExpr.arguments[1]) : "";
|
|
4468
|
+
compActions.push({
|
|
4469
|
+
id: `auto_${++actionCounter.value}`,
|
|
4470
|
+
type: "send_notification",
|
|
4471
|
+
mode: "auto",
|
|
4472
|
+
config: { to: String(to), message: String(message) }
|
|
4473
|
+
});
|
|
4474
|
+
}
|
|
4475
|
+
if (fnName === "emit") {
|
|
4476
|
+
const event = innerExpr.arguments[0] ? extractNodeValue2(innerExpr.arguments[0]) : "";
|
|
4477
|
+
compActions.push({
|
|
4478
|
+
id: `auto_${++actionCounter.value}`,
|
|
4479
|
+
type: "emit_event",
|
|
4480
|
+
mode: "auto",
|
|
4481
|
+
config: { event: String(event) }
|
|
4482
|
+
});
|
|
4483
|
+
}
|
|
4484
|
+
}
|
|
4485
|
+
}
|
|
4486
|
+
if (t12.isIfStatement(innerStmt) && t12.isBlockStatement(innerStmt.consequent)) {
|
|
4487
|
+
const condStr = expressionToIR(innerStmt.test, paramName);
|
|
4488
|
+
for (const ifInner of innerStmt.consequent.body) {
|
|
4489
|
+
if (t12.isExpressionStatement(ifInner)) {
|
|
4490
|
+
const ifExpr = ifInner.expression;
|
|
4491
|
+
if (t12.isAssignmentExpression(ifExpr) && t12.isMemberExpression(ifExpr.left)) {
|
|
4492
|
+
const left = memberExprToString(ifExpr.left);
|
|
4493
|
+
if (left.startsWith(`${paramName}.`)) {
|
|
4494
|
+
const field = left.slice(paramName.length + 1);
|
|
4495
|
+
const valueExpr = expressionToIR(ifExpr.right, paramName);
|
|
4496
|
+
compActions.push({
|
|
4497
|
+
id: `auto_${++actionCounter.value}`,
|
|
4498
|
+
type: "set_field",
|
|
4499
|
+
mode: "auto",
|
|
4500
|
+
config: { field, expression: valueExpr },
|
|
4501
|
+
condition: condStr
|
|
4502
|
+
});
|
|
4503
|
+
}
|
|
4504
|
+
}
|
|
4505
|
+
if (t12.isAwaitExpression(ifExpr) && t12.isCallExpression(ifExpr.argument)) {
|
|
4506
|
+
const ifCall = ifExpr.argument;
|
|
4507
|
+
const fnName = t12.isIdentifier(ifCall.callee) ? ifCall.callee.name : null;
|
|
4508
|
+
if (fnName && importedFns.has(fnName)) {
|
|
4509
|
+
compActions.push({
|
|
4510
|
+
id: `auto_${++actionCounter.value}`,
|
|
4511
|
+
type: "call_workflow",
|
|
4512
|
+
mode: "auto",
|
|
4513
|
+
config: { definition_slug: fnNameToSlug(fnName), blocking: true },
|
|
4514
|
+
condition: condStr
|
|
4515
|
+
});
|
|
4516
|
+
}
|
|
4517
|
+
}
|
|
4518
|
+
}
|
|
4519
|
+
}
|
|
4520
|
+
}
|
|
4521
|
+
}
|
|
4522
|
+
}
|
|
4523
|
+
for (const cc of compensationCalls) {
|
|
4524
|
+
if (cc.type === "serviceCall") {
|
|
4525
|
+
compActions.push({
|
|
4526
|
+
id: `auto_${++actionCounter.value}`,
|
|
4527
|
+
type: "call_workflow",
|
|
4528
|
+
mode: "auto",
|
|
4529
|
+
config: { definition_slug: fnNameToSlug(cc.name), blocking: true }
|
|
4530
|
+
});
|
|
4531
|
+
}
|
|
4532
|
+
}
|
|
4533
|
+
compilerState.states.set(compStateName, {
|
|
4534
|
+
name: compStateName,
|
|
4535
|
+
type: hasReturn ? "END" : "REGULAR",
|
|
4536
|
+
on_enter: compActions,
|
|
4537
|
+
during: [],
|
|
4538
|
+
on_exit: []
|
|
4539
|
+
});
|
|
4540
|
+
for (const tryCallName of tryCallNames) {
|
|
4541
|
+
let tryStateName;
|
|
4542
|
+
if (localFnNames.has(tryCallName)) {
|
|
4543
|
+
tryStateName = toSnakeCase2(tryCallName);
|
|
4544
|
+
} else if (importedFns.has(tryCallName)) {
|
|
4545
|
+
tryStateName = `awaiting_${toSnakeCase2(tryCallName)}`;
|
|
4546
|
+
} else {
|
|
4547
|
+
tryStateName = toSnakeCase2(tryCallName);
|
|
4548
|
+
}
|
|
4549
|
+
if (compilerState.states.has(tryStateName)) {
|
|
4550
|
+
compilerState.transitions.push({
|
|
4551
|
+
name: `error_to_${compStateName}`,
|
|
4552
|
+
from: [tryStateName],
|
|
4553
|
+
to: compStateName,
|
|
4554
|
+
conditions: [{ expression: "error != null" }],
|
|
4555
|
+
actions: [],
|
|
4556
|
+
auto: true
|
|
4557
|
+
});
|
|
4558
|
+
}
|
|
4559
|
+
}
|
|
4560
|
+
if (!hasReturn) {
|
|
4561
|
+
prevStateName = compStateName;
|
|
4562
|
+
}
|
|
4563
|
+
break;
|
|
4564
|
+
}
|
|
4565
|
+
referencedStates.add(call.name);
|
|
4566
|
+
if (!firstStateName) firstStateName = stateName;
|
|
4567
|
+
const info = stateFnInfos.get(call.name);
|
|
4568
|
+
if (info && !compilerState.states.has(stateName)) {
|
|
4569
|
+
compilerState.states.set(stateName, {
|
|
4570
|
+
name: stateName,
|
|
4571
|
+
type: !firstStateName || stateName === toSnakeCase2(callSequence[0]?.name || "") ? "START" : "REGULAR",
|
|
4572
|
+
on_enter: info.onEnter,
|
|
4573
|
+
during: info.during,
|
|
4574
|
+
on_exit: [],
|
|
4575
|
+
...info.onEvent.length > 0 ? { on_event: info.onEvent } : {},
|
|
4576
|
+
...info.timeout ? { timeout: info.timeout } : {},
|
|
4577
|
+
...info.runtime ? { runtime: info.runtime } : {}
|
|
4578
|
+
});
|
|
4579
|
+
} else if (!compilerState.states.has(stateName)) {
|
|
4580
|
+
compilerState.states.set(stateName, {
|
|
4581
|
+
name: stateName,
|
|
4582
|
+
type: "REGULAR",
|
|
4583
|
+
on_enter: [],
|
|
4584
|
+
during: [],
|
|
4585
|
+
on_exit: []
|
|
4586
|
+
});
|
|
4587
|
+
}
|
|
4588
|
+
if (prevStateName && prevStateName !== stateName) {
|
|
4589
|
+
const transName = call.transitionName || `to_${stateName}`;
|
|
4590
|
+
const conditions = [];
|
|
4591
|
+
if (call.condition) {
|
|
4592
|
+
conditions.push({ expression: call.condition });
|
|
4593
|
+
}
|
|
4594
|
+
if (info?.roles.length) {
|
|
4595
|
+
for (const role of info.roles) {
|
|
4596
|
+
conditions.push(roleCondition(role));
|
|
4597
|
+
}
|
|
4598
|
+
}
|
|
4599
|
+
compilerState.transitions.push({
|
|
4600
|
+
name: transName,
|
|
4601
|
+
from: [prevStateName],
|
|
4602
|
+
to: stateName,
|
|
4603
|
+
conditions: conditions.length > 0 ? conditions : void 0,
|
|
4604
|
+
actions: [],
|
|
4605
|
+
...info?.requiredFields.length ? { required_fields: info.requiredFields } : {},
|
|
4606
|
+
auto: true
|
|
4607
|
+
});
|
|
4608
|
+
}
|
|
4609
|
+
prevStateName = stateName;
|
|
4610
|
+
break;
|
|
4611
|
+
}
|
|
4612
|
+
case "userAction": {
|
|
4613
|
+
const awaitState = `awaiting_${call.name}`;
|
|
4614
|
+
if (!compilerState.states.has(awaitState)) {
|
|
4615
|
+
compilerState.states.set(awaitState, {
|
|
4616
|
+
name: awaitState,
|
|
4617
|
+
type: "REGULAR",
|
|
4618
|
+
on_enter: [],
|
|
4619
|
+
during: [],
|
|
4620
|
+
on_exit: []
|
|
4621
|
+
});
|
|
4622
|
+
}
|
|
4623
|
+
if (prevStateName) {
|
|
4624
|
+
compilerState.transitions.push({
|
|
4625
|
+
name: `to_${awaitState}`,
|
|
4626
|
+
from: [prevStateName],
|
|
4627
|
+
to: awaitState,
|
|
4628
|
+
actions: [],
|
|
4629
|
+
auto: true,
|
|
4630
|
+
...call.condition ? { conditions: [{ expression: call.condition }] } : {}
|
|
4631
|
+
});
|
|
4632
|
+
}
|
|
4633
|
+
const opts = call.options || {};
|
|
4634
|
+
const conditions = [];
|
|
4635
|
+
if (opts.roles && Array.isArray(opts.roles)) {
|
|
4636
|
+
for (const role of opts.roles) {
|
|
4637
|
+
conditions.push(roleCondition(role));
|
|
4638
|
+
}
|
|
4639
|
+
}
|
|
4640
|
+
if (opts.when && typeof opts.when === "string") {
|
|
4641
|
+
conditions.push({ expression: opts.when });
|
|
4642
|
+
}
|
|
4643
|
+
compilerState.transitions.push({
|
|
4644
|
+
name: call.name,
|
|
4645
|
+
from: [awaitState],
|
|
4646
|
+
to: "",
|
|
4647
|
+
// Will be resolved later (next state in sequence)
|
|
4648
|
+
conditions: conditions.length > 0 ? conditions : void 0,
|
|
4649
|
+
actions: [],
|
|
4650
|
+
...opts.require ? { required_fields: opts.require } : {}
|
|
4651
|
+
});
|
|
4652
|
+
prevStateName = awaitState;
|
|
4653
|
+
break;
|
|
4654
|
+
}
|
|
4655
|
+
case "userChoice": {
|
|
4656
|
+
const choiceState = prevStateName || "choice";
|
|
4657
|
+
if (call.choices) {
|
|
4658
|
+
for (const [optionName, optionConfig] of Object.entries(call.choices)) {
|
|
4659
|
+
const config = optionConfig;
|
|
4660
|
+
const conditions = [];
|
|
4661
|
+
if (config.roles && Array.isArray(config.roles)) {
|
|
4662
|
+
for (const role of config.roles) {
|
|
4663
|
+
conditions.push(roleCondition(role));
|
|
4664
|
+
}
|
|
4665
|
+
}
|
|
4666
|
+
if (config.when && typeof config.when === "string") {
|
|
4667
|
+
conditions.push({ expression: config.when });
|
|
4668
|
+
}
|
|
4669
|
+
compilerState.transitions.push({
|
|
4670
|
+
name: optionName,
|
|
4671
|
+
from: [choiceState],
|
|
4672
|
+
to: "",
|
|
4673
|
+
// Resolved by switch/case handling
|
|
4674
|
+
conditions: conditions.length > 0 ? conditions : void 0,
|
|
4675
|
+
actions: [],
|
|
4676
|
+
...config.require ? { required_fields: config.require } : {}
|
|
4677
|
+
});
|
|
4678
|
+
}
|
|
4679
|
+
}
|
|
4680
|
+
break;
|
|
4681
|
+
}
|
|
4682
|
+
case "serviceCall": {
|
|
4683
|
+
const serviceSlug = fnNameToSlug(call.name);
|
|
4684
|
+
const serviceState = `awaiting_${toSnakeCase2(call.name)}`;
|
|
4685
|
+
compilerState.states.set(serviceState, {
|
|
4686
|
+
name: serviceState,
|
|
4687
|
+
type: "REGULAR",
|
|
4688
|
+
on_enter: [{
|
|
4689
|
+
id: `auto_${++actionCounter.value}`,
|
|
4690
|
+
type: "call_workflow",
|
|
4691
|
+
mode: "auto",
|
|
4692
|
+
config: {
|
|
4693
|
+
definition_slug: serviceSlug,
|
|
4694
|
+
blocking: true
|
|
4695
|
+
}
|
|
4696
|
+
}],
|
|
4697
|
+
during: [],
|
|
4698
|
+
on_exit: []
|
|
4699
|
+
});
|
|
4700
|
+
if (prevStateName) {
|
|
4701
|
+
compilerState.transitions.push({
|
|
4702
|
+
name: `call_${toSnakeCase2(call.name)}`,
|
|
4703
|
+
from: [prevStateName],
|
|
4704
|
+
to: serviceState,
|
|
4705
|
+
actions: [],
|
|
4706
|
+
auto: true,
|
|
4707
|
+
...call.condition ? { conditions: [{ expression: call.condition }] } : {}
|
|
4708
|
+
});
|
|
4709
|
+
}
|
|
4710
|
+
prevStateName = serviceState;
|
|
4711
|
+
break;
|
|
4712
|
+
}
|
|
4713
|
+
case "awaitOn": {
|
|
4714
|
+
const eventState = `awaiting_${call.name}`;
|
|
4715
|
+
const opts = call.options || {};
|
|
4716
|
+
const eventPattern = opts.__eventPattern ? String(opts.__eventPattern) : call.name.replace(/_/g, ":");
|
|
4717
|
+
const awaitOnMetadata = {
|
|
4718
|
+
event_pattern: eventPattern
|
|
4719
|
+
};
|
|
4720
|
+
if (opts.when && typeof opts.when === "string") {
|
|
4721
|
+
awaitOnMetadata.event_condition = String(opts.when);
|
|
4722
|
+
}
|
|
4723
|
+
if (opts.timeout) {
|
|
4724
|
+
awaitOnMetadata.event_timeout = String(opts.timeout);
|
|
4725
|
+
}
|
|
4726
|
+
const awaitState = {
|
|
4727
|
+
name: eventState,
|
|
4728
|
+
type: "REGULAR",
|
|
4729
|
+
on_enter: [],
|
|
4730
|
+
during: [],
|
|
4731
|
+
on_exit: [],
|
|
4732
|
+
...opts.timeout ? { timeout: { duration: String(opts.timeout) } } : {}
|
|
4733
|
+
};
|
|
4734
|
+
if (awaitOnMetadata) awaitState.metadata = awaitOnMetadata;
|
|
4735
|
+
compilerState.states.set(eventState, awaitState);
|
|
4736
|
+
if (prevStateName) {
|
|
4737
|
+
compilerState.transitions.push({
|
|
4738
|
+
name: `await_${call.name}`,
|
|
4739
|
+
from: [prevStateName],
|
|
4740
|
+
to: eventState,
|
|
4741
|
+
actions: [],
|
|
4742
|
+
auto: true,
|
|
4743
|
+
...call.condition ? { conditions: [{ expression: call.condition }] } : {}
|
|
4744
|
+
});
|
|
4745
|
+
}
|
|
4746
|
+
const eventConditions = [];
|
|
4747
|
+
if (opts.when && typeof opts.when === "string") {
|
|
4748
|
+
eventConditions.push({ expression: String(opts.when) });
|
|
4749
|
+
}
|
|
4750
|
+
compilerState.transitions.push({
|
|
4751
|
+
name: `${call.name}_matched`,
|
|
4752
|
+
from: [eventState],
|
|
4753
|
+
to: "",
|
|
4754
|
+
// Resolved to next state
|
|
4755
|
+
conditions: eventConditions.length > 0 ? eventConditions : void 0,
|
|
4756
|
+
actions: [],
|
|
4757
|
+
auto: true
|
|
4758
|
+
});
|
|
4759
|
+
prevStateName = eventState;
|
|
4760
|
+
break;
|
|
4761
|
+
}
|
|
4762
|
+
case "promiseAll": {
|
|
4763
|
+
const parallelState = `parallel_${++transitionIndex}`;
|
|
4764
|
+
const parallelActions = [];
|
|
4765
|
+
for (const pc of call.parallelCalls || []) {
|
|
4766
|
+
if (pc.type === "serviceCall") {
|
|
4767
|
+
parallelActions.push({
|
|
4768
|
+
id: `auto_${++actionCounter.value}`,
|
|
4769
|
+
type: "call_workflow",
|
|
4770
|
+
mode: "auto",
|
|
4771
|
+
config: {
|
|
4772
|
+
definition_slug: fnNameToSlug(pc.name),
|
|
4773
|
+
blocking: true
|
|
4774
|
+
}
|
|
4775
|
+
});
|
|
4776
|
+
}
|
|
4777
|
+
}
|
|
4778
|
+
compilerState.states.set(parallelState, {
|
|
4779
|
+
name: parallelState,
|
|
4780
|
+
type: "REGULAR",
|
|
4781
|
+
on_enter: parallelActions,
|
|
4782
|
+
during: [],
|
|
4783
|
+
on_exit: []
|
|
4784
|
+
});
|
|
4785
|
+
if (prevStateName) {
|
|
4786
|
+
compilerState.transitions.push({
|
|
4787
|
+
name: `to_${parallelState}`,
|
|
4788
|
+
from: [prevStateName],
|
|
4789
|
+
to: parallelState,
|
|
4790
|
+
actions: [],
|
|
4791
|
+
auto: true
|
|
4792
|
+
});
|
|
4793
|
+
}
|
|
4794
|
+
prevStateName = parallelState;
|
|
4795
|
+
break;
|
|
4796
|
+
}
|
|
4797
|
+
case "delay": {
|
|
4798
|
+
const delayState = `delay_${++transitionIndex}`;
|
|
4799
|
+
const durationMatch = call.name.match(/delay_(.+)/);
|
|
4800
|
+
const duration = durationMatch ? durationMatch[1] : "0";
|
|
4801
|
+
compilerState.states.set(delayState, {
|
|
4802
|
+
name: delayState,
|
|
4803
|
+
type: "REGULAR",
|
|
4804
|
+
on_enter: [],
|
|
4805
|
+
during: [],
|
|
4806
|
+
on_exit: [],
|
|
4807
|
+
timeout: { duration, fallback: {} }
|
|
4808
|
+
});
|
|
4809
|
+
if (prevStateName) {
|
|
4810
|
+
compilerState.transitions.push({
|
|
4811
|
+
name: `to_${delayState}`,
|
|
4812
|
+
from: [prevStateName],
|
|
4813
|
+
to: delayState,
|
|
4814
|
+
actions: [],
|
|
4815
|
+
auto: true
|
|
4816
|
+
});
|
|
4817
|
+
}
|
|
4818
|
+
prevStateName = delayState;
|
|
4819
|
+
break;
|
|
4820
|
+
}
|
|
4821
|
+
}
|
|
4822
|
+
}
|
|
4823
|
+
if (prevStateName && compilerState.states.has(prevStateName)) {
|
|
4824
|
+
const lastState = compilerState.states.get(prevStateName);
|
|
4825
|
+
const hasOutgoing = compilerState.transitions.some((t22) => t22.from.includes(prevStateName));
|
|
4826
|
+
if (!hasOutgoing) {
|
|
4827
|
+
lastState.type = "END";
|
|
4828
|
+
}
|
|
4829
|
+
}
|
|
4830
|
+
if (firstStateName && compilerState.states.has(firstStateName)) {
|
|
4831
|
+
compilerState.states.get(firstStateName).type = "START";
|
|
4832
|
+
}
|
|
4833
|
+
for (let i = 0; i < compilerState.transitions.length; i++) {
|
|
4834
|
+
const trans = compilerState.transitions[i];
|
|
4835
|
+
if (trans.to === "" && i + 1 < compilerState.transitions.length) {
|
|
4836
|
+
const nextTrans = compilerState.transitions[i + 1];
|
|
4837
|
+
if (nextTrans.to) {
|
|
4838
|
+
trans.to = nextTrans.to;
|
|
4839
|
+
} else if (nextTrans.from.length > 0) {
|
|
4840
|
+
}
|
|
4841
|
+
}
|
|
4842
|
+
}
|
|
4843
|
+
const stateSequence = callSequence.filter((c) => c.type === "stateCall" || c.type === "serviceCall" || c.type === "userAction" || c.type === "awaitOn").map((c) => {
|
|
4844
|
+
if (c.type === "stateCall") return toSnakeCase2(c.name);
|
|
4845
|
+
if (c.type === "userAction") return `awaiting_${c.name}`;
|
|
4846
|
+
if (c.type === "serviceCall") return `awaiting_${toSnakeCase2(c.name)}`;
|
|
4847
|
+
if (c.type === "awaitOn") return `awaiting_${c.name}`;
|
|
4848
|
+
return c.name;
|
|
4849
|
+
});
|
|
4850
|
+
for (const trans of compilerState.transitions) {
|
|
4851
|
+
if (trans.to === "") {
|
|
4852
|
+
const fromState = trans.from[0];
|
|
4853
|
+
const idx = stateSequence.indexOf(fromState);
|
|
4854
|
+
if (idx >= 0 && idx + 1 < stateSequence.length) {
|
|
4855
|
+
trans.to = stateSequence[idx + 1];
|
|
4856
|
+
}
|
|
4857
|
+
}
|
|
4858
|
+
}
|
|
4859
|
+
for (const at of allowTransitions) {
|
|
4860
|
+
const resolvedTo = at.to === "$self" ? "__self__" : toSnakeCase2(at.to);
|
|
4861
|
+
const resolvedFrom = at.from.map((f) => toSnakeCase2(f));
|
|
4862
|
+
const conditions = [];
|
|
4863
|
+
if (at.roles) {
|
|
4864
|
+
for (const role of at.roles) {
|
|
4865
|
+
conditions.push(roleCondition(role));
|
|
4866
|
+
}
|
|
4867
|
+
}
|
|
4868
|
+
if (at.when) {
|
|
4869
|
+
conditions.push({ expression: at.when });
|
|
4870
|
+
}
|
|
4871
|
+
if (resolvedTo !== "__self__" && !compilerState.states.has(resolvedTo)) {
|
|
4872
|
+
compilerState.states.set(resolvedTo, {
|
|
4873
|
+
name: resolvedTo,
|
|
4874
|
+
type: "REGULAR",
|
|
4875
|
+
on_enter: [],
|
|
4876
|
+
during: [],
|
|
4877
|
+
on_exit: []
|
|
4878
|
+
});
|
|
4879
|
+
}
|
|
4880
|
+
if (resolvedTo === "__self__") {
|
|
4881
|
+
for (const from of resolvedFrom) {
|
|
4882
|
+
compilerState.transitions.push({
|
|
4883
|
+
name: at.name,
|
|
4884
|
+
from: [from],
|
|
4885
|
+
to: from,
|
|
4886
|
+
conditions: conditions.length > 0 ? conditions : void 0,
|
|
4887
|
+
actions: [],
|
|
4888
|
+
...at.require ? { required_fields: at.require } : {}
|
|
4889
|
+
});
|
|
4890
|
+
}
|
|
4891
|
+
} else {
|
|
4892
|
+
compilerState.transitions.push({
|
|
4893
|
+
name: at.name,
|
|
4894
|
+
from: resolvedFrom,
|
|
4895
|
+
to: resolvedTo,
|
|
4896
|
+
conditions: conditions.length > 0 ? conditions : void 0,
|
|
4897
|
+
actions: [],
|
|
4898
|
+
...at.require ? { required_fields: at.require } : {}
|
|
4899
|
+
});
|
|
4900
|
+
}
|
|
4901
|
+
}
|
|
4902
|
+
for (const [, info] of stateFnInfos) {
|
|
4903
|
+
for (const v of info.validations) {
|
|
4904
|
+
if (v.field === "__cross__") continue;
|
|
4905
|
+
const field = compilerState.fields.find((f) => f.name === v.field);
|
|
4906
|
+
if (field) {
|
|
4907
|
+
if (!field.validation) field.validation = {};
|
|
4908
|
+
Object.assign(field.validation, v.validation);
|
|
4909
|
+
if (v.validation.rules) {
|
|
4910
|
+
if (!field.validation.rules) field.validation.rules = [];
|
|
4911
|
+
field.validation.rules.push(...v.validation.rules);
|
|
4912
|
+
}
|
|
4913
|
+
}
|
|
4914
|
+
}
|
|
4915
|
+
}
|
|
4916
|
+
for (const node of path.node.body) {
|
|
4917
|
+
if (t12.isExportNamedDeclaration(node) && t12.isVariableDeclaration(node.declaration)) {
|
|
4918
|
+
for (const decl of node.declaration.declarations) {
|
|
4919
|
+
if (t12.isIdentifier(decl.id) && decl.id.name === "roles" && decl.init) {
|
|
4920
|
+
let rolesObj = null;
|
|
4921
|
+
if (t12.isCallExpression(decl.init) && t12.isIdentifier(decl.init.callee) && decl.init.callee.name === "defineRoles" && t12.isObjectExpression(decl.init.arguments[0])) {
|
|
4922
|
+
rolesObj = decl.init.arguments[0];
|
|
4923
|
+
} else if (t12.isObjectExpression(decl.init)) {
|
|
4924
|
+
rolesObj = decl.init;
|
|
4925
|
+
}
|
|
4926
|
+
if (rolesObj) {
|
|
4927
|
+
const roles = extractNodeValue2(rolesObj);
|
|
4928
|
+
if (!compilerState.metadata.roles) compilerState.metadata.roles = {};
|
|
4929
|
+
for (const [roleName, roleConfig] of Object.entries(roles)) {
|
|
4930
|
+
compilerState.metadata.roles[roleName] = roleConfig;
|
|
4931
|
+
}
|
|
4932
|
+
}
|
|
4933
|
+
}
|
|
4934
|
+
if (t12.isIdentifier(decl.id) && decl.id.name === "fieldAccess" && t12.isObjectExpression(decl.init)) {
|
|
4935
|
+
const access = extractNodeValue2(decl.init);
|
|
4936
|
+
for (const [fieldName, config] of Object.entries(access)) {
|
|
4937
|
+
const field = compilerState.fields.find((f) => f.name === fieldName);
|
|
4938
|
+
if (field) {
|
|
4939
|
+
if (config.visibleTo) field.visible_to_roles = config.visibleTo;
|
|
4940
|
+
if (config.editableBy) field.editable_by_roles = config.editableBy;
|
|
4941
|
+
if (config.editableIn) field.editable_in_states = config.editableIn;
|
|
4942
|
+
}
|
|
4943
|
+
}
|
|
4944
|
+
}
|
|
4945
|
+
if (t12.isIdentifier(decl.id) && decl.id.name === "config" && decl.init) {
|
|
4946
|
+
if (t12.isCallExpression(decl.init) && t12.isIdentifier(decl.init.callee) && decl.init.callee.name === "orchestration" && t12.isObjectExpression(decl.init.arguments[0])) {
|
|
4947
|
+
compilerState.metadata.orchestration = extractNodeValue2(decl.init.arguments[0]);
|
|
4948
|
+
}
|
|
4949
|
+
}
|
|
4950
|
+
}
|
|
4951
|
+
}
|
|
4952
|
+
}
|
|
4953
|
+
for (const node of path.node.body) {
|
|
4954
|
+
if (t12.isExportNamedDeclaration(node) && t12.isVariableDeclaration(node.declaration)) {
|
|
4955
|
+
for (const decl of node.declaration.declarations) {
|
|
4956
|
+
if (t12.isIdentifier(decl.id) && decl.id.name === "fields" && t12.isObjectExpression(decl.init)) {
|
|
4957
|
+
const fieldsConfig = extractNodeValue2(decl.init);
|
|
4958
|
+
for (const [name, config] of Object.entries(fieldsConfig)) {
|
|
4959
|
+
const field = compilerState.fields.find((f) => f.name === name);
|
|
4960
|
+
if (!field) continue;
|
|
4961
|
+
if (typeof config === "string") {
|
|
4962
|
+
if (config.includes("!")) field.required = true;
|
|
4963
|
+
} else if (typeof config === "object" && config !== null) {
|
|
4964
|
+
const cfg = config;
|
|
4965
|
+
if (cfg.required) field.required = true;
|
|
4966
|
+
if (cfg.min !== void 0 || cfg.max !== void 0 || cfg.minLength !== void 0 || cfg.maxLength !== void 0 || cfg.pattern !== void 0) {
|
|
4967
|
+
if (!field.validation) field.validation = {};
|
|
4968
|
+
if (cfg.min !== void 0) field.validation.min = Number(cfg.min);
|
|
4969
|
+
if (cfg.max !== void 0) field.validation.max = Number(cfg.max);
|
|
4970
|
+
if (cfg.minLength !== void 0) field.validation.minLength = Number(cfg.minLength);
|
|
4971
|
+
if (cfg.maxLength !== void 0) field.validation.maxLength = Number(cfg.maxLength);
|
|
4972
|
+
if (cfg.pattern !== void 0) {
|
|
4973
|
+
if (!field.validation.rules) field.validation.rules = [];
|
|
4974
|
+
field.validation.rules.push({
|
|
4975
|
+
expression: `MATCHES(value, "${String(cfg.pattern)}")`,
|
|
4976
|
+
message: "Invalid format",
|
|
4977
|
+
severity: "error"
|
|
4978
|
+
});
|
|
4979
|
+
}
|
|
4980
|
+
}
|
|
4981
|
+
if (cfg.default !== void 0) field.default_value = cfg.default;
|
|
4982
|
+
}
|
|
4983
|
+
}
|
|
4984
|
+
}
|
|
4985
|
+
}
|
|
4986
|
+
}
|
|
4987
|
+
}
|
|
4988
|
+
compilerState.transitions = compilerState.transitions.filter((t22) => t22.to !== "");
|
|
4989
|
+
for (const trans of compilerState.transitions) {
|
|
4990
|
+
for (const from of trans.from) {
|
|
4991
|
+
if (!compilerState.states.has(from)) {
|
|
4992
|
+
compilerState.states.set(from, {
|
|
4993
|
+
name: from,
|
|
4994
|
+
type: "REGULAR",
|
|
4995
|
+
on_enter: [],
|
|
4996
|
+
during: [],
|
|
4997
|
+
on_exit: []
|
|
4998
|
+
});
|
|
4999
|
+
}
|
|
5000
|
+
}
|
|
5001
|
+
if (!compilerState.states.has(trans.to)) {
|
|
5002
|
+
compilerState.states.set(trans.to, {
|
|
5003
|
+
name: trans.to,
|
|
5004
|
+
type: "REGULAR",
|
|
5005
|
+
on_enter: [],
|
|
5006
|
+
during: [],
|
|
5007
|
+
on_exit: []
|
|
5008
|
+
});
|
|
5009
|
+
}
|
|
5010
|
+
}
|
|
5011
|
+
compilerState.actionCounter = actionCounter.value;
|
|
5012
|
+
}
|
|
5013
|
+
|
|
5014
|
+
// src/babel/extractors/server-action-extractor.ts
|
|
5015
|
+
var t13 = __toESM(require("@babel/types"));
|
|
5016
|
+
function isServerActionFile(filename) {
|
|
5017
|
+
if (!filename) return false;
|
|
5018
|
+
return /\.server\.(ts|tsx|js|jsx)$/.test(filename);
|
|
5019
|
+
}
|
|
5020
|
+
function extractServerActions(path, state) {
|
|
5021
|
+
const compilerState = state;
|
|
5022
|
+
const serverActions = [];
|
|
5023
|
+
for (const node of path.node.body) {
|
|
5024
|
+
if (t13.isExportNamedDeclaration(node)) {
|
|
5025
|
+
const decl = node.declaration;
|
|
5026
|
+
if (t13.isFunctionDeclaration(decl) && decl.id) {
|
|
5027
|
+
const action = extractFunctionAction(decl);
|
|
5028
|
+
if (action) {
|
|
5029
|
+
const comments = node.leadingComments || decl.leadingComments || [];
|
|
5030
|
+
action.description = extractDescription(comments);
|
|
5031
|
+
serverActions.push(action);
|
|
5032
|
+
}
|
|
5033
|
+
}
|
|
5034
|
+
if (t13.isVariableDeclaration(decl)) {
|
|
5035
|
+
for (const varDecl of decl.declarations) {
|
|
5036
|
+
if (!t13.isIdentifier(varDecl.id)) continue;
|
|
5037
|
+
const init = varDecl.init;
|
|
5038
|
+
if (t13.isArrowFunctionExpression(init) || t13.isFunctionExpression(init)) {
|
|
5039
|
+
const action = {
|
|
5040
|
+
name: varDecl.id.name,
|
|
5041
|
+
async: init.async || false,
|
|
5042
|
+
params: init.params.filter((p) => t13.isIdentifier(p)).map((p) => p.name)
|
|
5043
|
+
};
|
|
5044
|
+
if (init.params.length > 0) {
|
|
5045
|
+
const firstParam = init.params[0];
|
|
5046
|
+
if (t13.isIdentifier(firstParam) && firstParam.typeAnnotation) {
|
|
5047
|
+
action.contextType = extractTypeName(firstParam.typeAnnotation);
|
|
5048
|
+
}
|
|
5049
|
+
}
|
|
5050
|
+
serverActions.push(action);
|
|
5051
|
+
}
|
|
5052
|
+
}
|
|
5053
|
+
}
|
|
5054
|
+
}
|
|
5055
|
+
}
|
|
5056
|
+
if (serverActions.length > 0) {
|
|
5057
|
+
if (!compilerState.metadata) compilerState.metadata = {};
|
|
5058
|
+
compilerState.metadata.serverActions = serverActions;
|
|
5059
|
+
}
|
|
5060
|
+
}
|
|
5061
|
+
function extractFunctionAction(decl) {
|
|
5062
|
+
if (!decl.id) return null;
|
|
5063
|
+
const action = {
|
|
5064
|
+
name: decl.id.name,
|
|
5065
|
+
async: decl.async || false,
|
|
5066
|
+
params: decl.params.filter((p) => t13.isIdentifier(p)).map((p) => p.name)
|
|
5067
|
+
};
|
|
5068
|
+
if (decl.params.length > 0) {
|
|
5069
|
+
const firstParam = decl.params[0];
|
|
5070
|
+
if (t13.isIdentifier(firstParam) && firstParam.typeAnnotation) {
|
|
5071
|
+
action.contextType = extractTypeName(firstParam.typeAnnotation);
|
|
5072
|
+
}
|
|
5073
|
+
}
|
|
5074
|
+
return action;
|
|
5075
|
+
}
|
|
5076
|
+
function extractTypeName(annotation) {
|
|
5077
|
+
if (t13.isTSTypeAnnotation(annotation)) {
|
|
5078
|
+
const typeNode = annotation.typeAnnotation;
|
|
5079
|
+
if (t13.isTSTypeReference(typeNode) && t13.isIdentifier(typeNode.typeName)) {
|
|
5080
|
+
return typeNode.typeName.name;
|
|
5081
|
+
}
|
|
5082
|
+
}
|
|
5083
|
+
return void 0;
|
|
5084
|
+
}
|
|
5085
|
+
function extractDescription(comments) {
|
|
5086
|
+
for (const comment of comments) {
|
|
5087
|
+
if (comment.type !== "CommentBlock") continue;
|
|
5088
|
+
const lines = comment.value.split("\n");
|
|
5089
|
+
for (const line of lines) {
|
|
5090
|
+
const trimmed = line.replace(/^\s*\*\s?/, "").trim();
|
|
5091
|
+
if (trimmed && !trimmed.startsWith("@")) {
|
|
5092
|
+
return trimmed;
|
|
5093
|
+
}
|
|
5094
|
+
}
|
|
5095
|
+
}
|
|
5096
|
+
return void 0;
|
|
5097
|
+
}
|
|
5098
|
+
|
|
5099
|
+
// src/babel/extractors/server-action-hook-extractor.ts
|
|
5100
|
+
var t14 = __toESM(require("@babel/types"));
|
|
5101
|
+
function extractServerActionHook(path, state) {
|
|
5102
|
+
const args = path.node.arguments;
|
|
5103
|
+
if (args.length < 1) return;
|
|
5104
|
+
const nameArg = args[0];
|
|
5105
|
+
if (!t14.isStringLiteral(nameArg)) return;
|
|
5106
|
+
const compilerState = state;
|
|
5107
|
+
const entry = {
|
|
5108
|
+
name: nameArg.value
|
|
5109
|
+
};
|
|
5110
|
+
if (args.length > 1 && t14.isObjectExpression(args[1])) {
|
|
5111
|
+
for (const prop of args[1].properties) {
|
|
5112
|
+
if (!t14.isObjectProperty(prop) || !t14.isIdentifier(prop.key)) continue;
|
|
5113
|
+
if (prop.key.name === "instanceId" && t14.isStringLiteral(prop.value)) {
|
|
5114
|
+
entry.staticInstanceId = prop.value.value;
|
|
5115
|
+
}
|
|
5116
|
+
}
|
|
5117
|
+
}
|
|
5118
|
+
const parent = path.parentPath;
|
|
5119
|
+
if (parent?.isVariableDeclarator() && t14.isIdentifier(parent.node.id)) {
|
|
5120
|
+
entry.variableName = parent.node.id.name;
|
|
5121
|
+
}
|
|
5122
|
+
if (!compilerState.metadata) compilerState.metadata = {};
|
|
5123
|
+
const meta = compilerState.metadata;
|
|
5124
|
+
if (!meta.serverActionHooks) meta.serverActionHooks = [];
|
|
5125
|
+
meta.serverActionHooks.push(entry);
|
|
5126
|
+
}
|
|
5127
|
+
|
|
5128
|
+
// src/babel/extractors/server-state-extractor.ts
|
|
5129
|
+
var t15 = __toESM(require("@babel/types"));
|
|
5130
|
+
function extractServerState(path, state) {
|
|
5131
|
+
const args = path.node.arguments;
|
|
5132
|
+
if (args.length < 1) return;
|
|
5133
|
+
const compilerState = state;
|
|
5134
|
+
const entry = {};
|
|
5135
|
+
const instanceArg = args[0];
|
|
5136
|
+
if (t15.isStringLiteral(instanceArg)) {
|
|
5137
|
+
entry.staticInstanceId = instanceArg.value;
|
|
5138
|
+
}
|
|
5139
|
+
if (args.length > 1 && t15.isObjectExpression(args[1])) {
|
|
5140
|
+
for (const prop of args[1].properties) {
|
|
5141
|
+
if (!t15.isObjectProperty(prop) || !t15.isIdentifier(prop.key)) continue;
|
|
5142
|
+
if (prop.key.name === "enabled" && t15.isBooleanLiteral(prop.value)) {
|
|
5143
|
+
if (!prop.value.value) entry.disabled = true;
|
|
5144
|
+
}
|
|
5145
|
+
}
|
|
5146
|
+
}
|
|
5147
|
+
const parent = path.parentPath;
|
|
5148
|
+
if (parent?.isVariableDeclarator()) {
|
|
5149
|
+
if (t15.isIdentifier(parent.node.id)) {
|
|
5150
|
+
entry.variableName = parent.node.id.name;
|
|
5151
|
+
} else if (t15.isObjectPattern(parent.node.id)) {
|
|
5152
|
+
const props = parent.node.id.properties.filter((p) => t15.isObjectProperty(p) && t15.isIdentifier(p.key)).map((p) => p.key.name);
|
|
5153
|
+
if (props.length > 0) {
|
|
5154
|
+
entry.variableName = props.join(", ");
|
|
5155
|
+
}
|
|
5156
|
+
}
|
|
5157
|
+
}
|
|
5158
|
+
if (!compilerState.metadata) compilerState.metadata = {};
|
|
5159
|
+
const meta = compilerState.metadata;
|
|
5160
|
+
if (!meta.serverStateSubscriptions) meta.serverStateSubscriptions = [];
|
|
5161
|
+
meta.serverStateSubscriptions.push(entry);
|
|
5162
|
+
meta.requiresSSE = true;
|
|
5163
|
+
}
|
|
5164
|
+
|
|
5165
|
+
// src/babel/extractors/grammar-island-extractor.ts
|
|
5166
|
+
var t16 = __toESM(require("@babel/types"));
|
|
5167
|
+
var GRAMMAR_TAGS = /* @__PURE__ */ new Set(["cedar", "sql", "cron", "dmn", "graphql", "jsonpath"]);
|
|
5168
|
+
function parseCedar(source) {
|
|
5169
|
+
const policies = [];
|
|
5170
|
+
const policyRegex = /(permit|forbid)\s*\(([^)]*)\)(?:\s*when\s*\{([^}]*)\})?/g;
|
|
5171
|
+
let match;
|
|
5172
|
+
while ((match = policyRegex.exec(source)) !== null) {
|
|
5173
|
+
const [, effect, scope, condition] = match;
|
|
3216
5174
|
const parts = scope.split(",").map((s) => s.trim());
|
|
3217
5175
|
const policy = {
|
|
3218
5176
|
effect,
|
|
@@ -3286,7 +5244,7 @@ function parseDmn(source) {
|
|
|
3286
5244
|
}
|
|
3287
5245
|
function extractGrammarIsland(path, state, slug) {
|
|
3288
5246
|
const tag = path.node.tag;
|
|
3289
|
-
if (!
|
|
5247
|
+
if (!t16.isIdentifier(tag)) return;
|
|
3290
5248
|
const tagName = tag.name;
|
|
3291
5249
|
if (!GRAMMAR_TAGS.has(tagName)) return;
|
|
3292
5250
|
const compilerState = state;
|
|
@@ -3296,7 +5254,7 @@ function extractGrammarIsland(path, state, slug) {
|
|
|
3296
5254
|
rawSource += quasi.quasis[i].value.raw;
|
|
3297
5255
|
if (i < quasi.expressions.length) {
|
|
3298
5256
|
const expr = quasi.expressions[i];
|
|
3299
|
-
if (
|
|
5257
|
+
if (t16.isIdentifier(expr)) {
|
|
3300
5258
|
rawSource += `\${${expr.name}}`;
|
|
3301
5259
|
} else {
|
|
3302
5260
|
rawSource += `\${expr_${i}}`;
|
|
@@ -3340,16 +5298,16 @@ function extractGrammarIslands(path, state) {
|
|
|
3340
5298
|
path.traverse({
|
|
3341
5299
|
TaggedTemplateExpression(templatePath) {
|
|
3342
5300
|
const tag = templatePath.node.tag;
|
|
3343
|
-
if (!
|
|
5301
|
+
if (!t16.isIdentifier(tag) || !GRAMMAR_TAGS.has(tag.name)) return;
|
|
3344
5302
|
let slug = "unnamed";
|
|
3345
5303
|
const parent = templatePath.parentPath;
|
|
3346
|
-
if (parent && parent.isVariableDeclarator() &&
|
|
5304
|
+
if (parent && parent.isVariableDeclarator() && t16.isIdentifier(parent.node.id)) {
|
|
3347
5305
|
slug = parent.node.id.name;
|
|
3348
5306
|
}
|
|
3349
|
-
if (parent && parent.isObjectProperty() &&
|
|
5307
|
+
if (parent && parent.isObjectProperty() && t16.isIdentifier(parent.node.key)) {
|
|
3350
5308
|
slug = parent.node.key.name;
|
|
3351
5309
|
}
|
|
3352
|
-
if (parent && parent.isObjectProperty() &&
|
|
5310
|
+
if (parent && parent.isObjectProperty() && t16.isStringLiteral(parent.node.key)) {
|
|
3353
5311
|
slug = parent.node.key.value;
|
|
3354
5312
|
}
|
|
3355
5313
|
extractGrammarIsland(templatePath, state, slug);
|
|
@@ -3358,12 +5316,12 @@ function extractGrammarIslands(path, state) {
|
|
|
3358
5316
|
}
|
|
3359
5317
|
|
|
3360
5318
|
// src/babel/extractors/context-extractor.ts
|
|
3361
|
-
var
|
|
5319
|
+
var t17 = __toESM(require("@babel/types"));
|
|
3362
5320
|
function hasContextCreation(path) {
|
|
3363
5321
|
let found = false;
|
|
3364
5322
|
path.traverse({
|
|
3365
5323
|
CallExpression(callPath) {
|
|
3366
|
-
if (
|
|
5324
|
+
if (t17.isIdentifier(callPath.node.callee, { name: "createContext" })) {
|
|
3367
5325
|
found = true;
|
|
3368
5326
|
callPath.stop();
|
|
3369
5327
|
}
|
|
@@ -3379,9 +5337,9 @@ function extractContextWorkflows(path, state) {
|
|
|
3379
5337
|
// Detect: const XContext = createContext(...)
|
|
3380
5338
|
VariableDeclarator(declPath) {
|
|
3381
5339
|
const init = declPath.node.init;
|
|
3382
|
-
if (!init || !
|
|
3383
|
-
if (!
|
|
3384
|
-
if (!
|
|
5340
|
+
if (!init || !t17.isCallExpression(init)) return;
|
|
5341
|
+
if (!t17.isIdentifier(init.callee, { name: "createContext" })) return;
|
|
5342
|
+
if (!t17.isIdentifier(declPath.node.id)) return;
|
|
3385
5343
|
const contextName = declPath.node.id.name;
|
|
3386
5344
|
contextNames.set(contextName, contextName);
|
|
3387
5345
|
const workflow = {
|
|
@@ -3390,25 +5348,25 @@ function extractContextWorkflows(path, state) {
|
|
|
3390
5348
|
reducerActions: []
|
|
3391
5349
|
};
|
|
3392
5350
|
const typeParams = init.typeParameters;
|
|
3393
|
-
if (typeParams &&
|
|
5351
|
+
if (typeParams && t17.isTSTypeParameterInstantiation(typeParams)) {
|
|
3394
5352
|
const typeArg = typeParams.params[0];
|
|
3395
|
-
if (
|
|
5353
|
+
if (t17.isTSTypeReference(typeArg) && t17.isIdentifier(typeArg.typeName)) {
|
|
3396
5354
|
const interfaceName = typeArg.typeName.name;
|
|
3397
|
-
|
|
5355
|
+
extractFieldsFromInterface3(path, interfaceName, workflow);
|
|
3398
5356
|
}
|
|
3399
5357
|
}
|
|
3400
|
-
if (init.arguments.length > 0 &&
|
|
5358
|
+
if (init.arguments.length > 0 && t17.isObjectExpression(init.arguments[0])) {
|
|
3401
5359
|
workflow.initialState = extractObjectLiteral2(init.arguments[0]);
|
|
3402
5360
|
}
|
|
3403
5361
|
contextWorkflows.push(workflow);
|
|
3404
5362
|
},
|
|
3405
5363
|
// Detect useReducer(reducer, initialState) and extract reducer cases
|
|
3406
5364
|
CallExpression(callPath) {
|
|
3407
|
-
if (!
|
|
5365
|
+
if (!t17.isIdentifier(callPath.node.callee, { name: "useReducer" })) return;
|
|
3408
5366
|
const args = callPath.node.arguments;
|
|
3409
5367
|
if (args.length < 1) return;
|
|
3410
5368
|
const reducerArg = args[0];
|
|
3411
|
-
if (!
|
|
5369
|
+
if (!t17.isIdentifier(reducerArg)) return;
|
|
3412
5370
|
const reducerName = reducerArg.name;
|
|
3413
5371
|
const actions = extractReducerActions(path, reducerName);
|
|
3414
5372
|
if (contextWorkflows.length > 0) {
|
|
@@ -3424,13 +5382,13 @@ function extractContextWorkflows(path, state) {
|
|
|
3424
5382
|
meta.contextWorkflows = contextWorkflows;
|
|
3425
5383
|
}
|
|
3426
5384
|
}
|
|
3427
|
-
function
|
|
5385
|
+
function extractFieldsFromInterface3(path, interfaceName, workflow) {
|
|
3428
5386
|
path.traverse({
|
|
3429
5387
|
TSInterfaceDeclaration(ifacePath) {
|
|
3430
|
-
if (!
|
|
5388
|
+
if (!t17.isIdentifier(ifacePath.node.id, { name: interfaceName })) return;
|
|
3431
5389
|
for (const prop of ifacePath.node.body.body) {
|
|
3432
|
-
if (!
|
|
3433
|
-
if (!
|
|
5390
|
+
if (!t17.isTSPropertySignature(prop)) continue;
|
|
5391
|
+
if (!t17.isIdentifier(prop.key)) continue;
|
|
3434
5392
|
const field = {
|
|
3435
5393
|
name: prop.key.name,
|
|
3436
5394
|
type: extractTSType(prop.typeAnnotation),
|
|
@@ -3442,20 +5400,20 @@ function extractFieldsFromInterface2(path, interfaceName, workflow) {
|
|
|
3442
5400
|
});
|
|
3443
5401
|
}
|
|
3444
5402
|
function extractTSType(annotation) {
|
|
3445
|
-
if (!annotation || !
|
|
5403
|
+
if (!annotation || !t17.isTSTypeAnnotation(annotation)) return "unknown";
|
|
3446
5404
|
const typeNode = annotation.typeAnnotation;
|
|
3447
|
-
if (
|
|
3448
|
-
if (
|
|
3449
|
-
if (
|
|
3450
|
-
if (
|
|
3451
|
-
if (
|
|
5405
|
+
if (t17.isTSStringKeyword(typeNode)) return "string";
|
|
5406
|
+
if (t17.isTSNumberKeyword(typeNode)) return "number";
|
|
5407
|
+
if (t17.isTSBooleanKeyword(typeNode)) return "boolean";
|
|
5408
|
+
if (t17.isTSArrayType(typeNode)) return `${extractTSTypeNode(typeNode.elementType)}[]`;
|
|
5409
|
+
if (t17.isTSTypeReference(typeNode) && t17.isIdentifier(typeNode.typeName)) return typeNode.typeName.name;
|
|
3452
5410
|
return "unknown";
|
|
3453
5411
|
}
|
|
3454
5412
|
function extractTSTypeNode(node) {
|
|
3455
|
-
if (
|
|
3456
|
-
if (
|
|
3457
|
-
if (
|
|
3458
|
-
if (
|
|
5413
|
+
if (t17.isTSStringKeyword(node)) return "string";
|
|
5414
|
+
if (t17.isTSNumberKeyword(node)) return "number";
|
|
5415
|
+
if (t17.isTSBooleanKeyword(node)) return "boolean";
|
|
5416
|
+
if (t17.isTSTypeReference(node) && t17.isIdentifier(node.typeName)) return node.typeName.name;
|
|
3459
5417
|
return "unknown";
|
|
3460
5418
|
}
|
|
3461
5419
|
function extractReducerActions(path, reducerName) {
|
|
@@ -3467,7 +5425,7 @@ function extractReducerActions(path, reducerName) {
|
|
|
3467
5425
|
SwitchStatement(switchPath) {
|
|
3468
5426
|
for (const switchCase of switchPath.node.cases) {
|
|
3469
5427
|
if (!switchCase.test) continue;
|
|
3470
|
-
if (
|
|
5428
|
+
if (t17.isStringLiteral(switchCase.test)) {
|
|
3471
5429
|
actions.push({
|
|
3472
5430
|
type: switchCase.test.value
|
|
3473
5431
|
});
|
|
@@ -3482,24 +5440,576 @@ function extractReducerActions(path, reducerName) {
|
|
|
3482
5440
|
function extractObjectLiteral2(obj) {
|
|
3483
5441
|
const result = {};
|
|
3484
5442
|
for (const prop of obj.properties) {
|
|
3485
|
-
if (!
|
|
3486
|
-
if (
|
|
3487
|
-
else if (
|
|
3488
|
-
else if (
|
|
3489
|
-
else if (
|
|
3490
|
-
else if (
|
|
3491
|
-
else if (
|
|
5443
|
+
if (!t17.isObjectProperty(prop) || !t17.isIdentifier(prop.key)) continue;
|
|
5444
|
+
if (t17.isStringLiteral(prop.value)) result[prop.key.name] = prop.value.value;
|
|
5445
|
+
else if (t17.isNumericLiteral(prop.value)) result[prop.key.name] = prop.value.value;
|
|
5446
|
+
else if (t17.isBooleanLiteral(prop.value)) result[prop.key.name] = prop.value.value;
|
|
5447
|
+
else if (t17.isNullLiteral(prop.value)) result[prop.key.name] = null;
|
|
5448
|
+
else if (t17.isArrayExpression(prop.value)) result[prop.key.name] = [];
|
|
5449
|
+
else if (t17.isObjectExpression(prop.value)) result[prop.key.name] = extractObjectLiteral2(prop.value);
|
|
5450
|
+
}
|
|
5451
|
+
return result;
|
|
5452
|
+
}
|
|
5453
|
+
|
|
5454
|
+
// src/babel/extractors/middleware-extractor.ts
|
|
5455
|
+
var t18 = __toESM(require("@babel/types"));
|
|
5456
|
+
var BUILTIN_FACTORIES = /* @__PURE__ */ new Set([
|
|
5457
|
+
"withAuth",
|
|
5458
|
+
"withAuditLog",
|
|
5459
|
+
"withRateLimit",
|
|
5460
|
+
"withValidation",
|
|
5461
|
+
"withMetrics"
|
|
5462
|
+
]);
|
|
5463
|
+
function hasMiddleware(path) {
|
|
5464
|
+
for (const node of path.node.body) {
|
|
5465
|
+
if (t18.isExportDefaultDeclaration(node)) {
|
|
5466
|
+
const decl = node.declaration;
|
|
5467
|
+
if (isDefineMiddlewareCall(decl) || isBuiltinFactoryCall(decl)) {
|
|
5468
|
+
return true;
|
|
5469
|
+
}
|
|
5470
|
+
}
|
|
5471
|
+
if (t18.isExportNamedDeclaration(node) && node.declaration) {
|
|
5472
|
+
if (t18.isVariableDeclaration(node.declaration)) {
|
|
5473
|
+
for (const declarator of node.declaration.declarations) {
|
|
5474
|
+
if (declarator.init && (isDefineMiddlewareCall(declarator.init) || isBuiltinFactoryCall(declarator.init))) {
|
|
5475
|
+
return true;
|
|
5476
|
+
}
|
|
5477
|
+
}
|
|
5478
|
+
}
|
|
5479
|
+
}
|
|
5480
|
+
if (t18.isVariableDeclaration(node)) {
|
|
5481
|
+
for (const declarator of node.declarations) {
|
|
5482
|
+
if (declarator.init && (isDefineMiddlewareCall(declarator.init) || isBuiltinFactoryCall(declarator.init))) {
|
|
5483
|
+
return true;
|
|
5484
|
+
}
|
|
5485
|
+
}
|
|
5486
|
+
}
|
|
5487
|
+
}
|
|
5488
|
+
return false;
|
|
5489
|
+
}
|
|
5490
|
+
function isDefineMiddlewareCall(node) {
|
|
5491
|
+
return t18.isCallExpression(node) && t18.isIdentifier(node.callee) && node.callee.name === "defineMiddleware";
|
|
5492
|
+
}
|
|
5493
|
+
function isBuiltinFactoryCall(node) {
|
|
5494
|
+
return t18.isCallExpression(node) && t18.isIdentifier(node.callee) && BUILTIN_FACTORIES.has(node.callee.name);
|
|
5495
|
+
}
|
|
5496
|
+
function extractMiddleware(path, state) {
|
|
5497
|
+
const compilerState = state;
|
|
5498
|
+
if (!compilerState.metadata) compilerState.metadata = {};
|
|
5499
|
+
const meta = compilerState.metadata;
|
|
5500
|
+
if (!meta.middleware) meta.middleware = [];
|
|
5501
|
+
const middlewareList = meta.middleware;
|
|
5502
|
+
path.traverse({
|
|
5503
|
+
CallExpression(callPath) {
|
|
5504
|
+
const callee = callPath.node.callee;
|
|
5505
|
+
if (!t18.isIdentifier(callee)) return;
|
|
5506
|
+
if (callee.name === "defineMiddleware") {
|
|
5507
|
+
const extracted = extractDefineMiddleware(callPath);
|
|
5508
|
+
if (extracted) middlewareList.push(extracted);
|
|
5509
|
+
} else if (BUILTIN_FACTORIES.has(callee.name)) {
|
|
5510
|
+
const extracted = extractBuiltinFactory(callee.name, callPath);
|
|
5511
|
+
if (extracted) middlewareList.push(extracted);
|
|
5512
|
+
}
|
|
5513
|
+
}
|
|
5514
|
+
});
|
|
5515
|
+
}
|
|
5516
|
+
function extractDefineMiddleware(callPath) {
|
|
5517
|
+
const args = callPath.node.arguments;
|
|
5518
|
+
if (args.length < 1 || !t18.isObjectExpression(args[0])) return null;
|
|
5519
|
+
const obj = args[0];
|
|
5520
|
+
let name = "unnamed";
|
|
5521
|
+
let match = [];
|
|
5522
|
+
let priority = 0;
|
|
5523
|
+
const before = [];
|
|
5524
|
+
const after = [];
|
|
5525
|
+
let hasAround = false;
|
|
5526
|
+
let config;
|
|
5527
|
+
for (const prop of obj.properties) {
|
|
5528
|
+
if (!t18.isObjectProperty(prop) && !t18.isObjectMethod(prop)) continue;
|
|
5529
|
+
const key = t18.isObjectProperty(prop) ? prop.key : prop.key;
|
|
5530
|
+
const keyName = t18.isIdentifier(key) ? key.name : t18.isStringLiteral(key) ? key.value : null;
|
|
5531
|
+
if (!keyName) continue;
|
|
5532
|
+
switch (keyName) {
|
|
5533
|
+
case "name":
|
|
5534
|
+
if (t18.isObjectProperty(prop) && t18.isStringLiteral(prop.value)) {
|
|
5535
|
+
name = prop.value.value;
|
|
5536
|
+
}
|
|
5537
|
+
break;
|
|
5538
|
+
case "match":
|
|
5539
|
+
if (t18.isObjectProperty(prop)) {
|
|
5540
|
+
if (t18.isStringLiteral(prop.value)) {
|
|
5541
|
+
match = [prop.value.value];
|
|
5542
|
+
} else if (t18.isArrayExpression(prop.value)) {
|
|
5543
|
+
match = prop.value.elements.filter((el) => t18.isStringLiteral(el)).map((el) => el.value);
|
|
5544
|
+
}
|
|
5545
|
+
}
|
|
5546
|
+
break;
|
|
5547
|
+
case "priority":
|
|
5548
|
+
if (t18.isObjectProperty(prop) && t18.isNumericLiteral(prop.value)) {
|
|
5549
|
+
priority = prop.value.value;
|
|
5550
|
+
}
|
|
5551
|
+
break;
|
|
5552
|
+
case "config":
|
|
5553
|
+
if (t18.isObjectProperty(prop) && t18.isObjectExpression(prop.value)) {
|
|
5554
|
+
config = extractConfigSchema(prop.value);
|
|
5555
|
+
}
|
|
5556
|
+
break;
|
|
5557
|
+
case "before":
|
|
5558
|
+
if (t18.isObjectMethod(prop)) {
|
|
5559
|
+
extractActionsFromBody(prop.body, before);
|
|
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, before);
|
|
5565
|
+
}
|
|
5566
|
+
}
|
|
5567
|
+
break;
|
|
5568
|
+
case "after":
|
|
5569
|
+
if (t18.isObjectMethod(prop)) {
|
|
5570
|
+
extractActionsFromBody(prop.body, after);
|
|
5571
|
+
} else if (t18.isObjectProperty(prop)) {
|
|
5572
|
+
const val = prop.value;
|
|
5573
|
+
if (t18.isFunctionExpression(val) || t18.isArrowFunctionExpression(val)) {
|
|
5574
|
+
const body = t18.isBlockStatement(val.body) ? val.body : null;
|
|
5575
|
+
if (body) extractActionsFromBody(body, after);
|
|
5576
|
+
}
|
|
5577
|
+
}
|
|
5578
|
+
break;
|
|
5579
|
+
case "around":
|
|
5580
|
+
hasAround = true;
|
|
5581
|
+
break;
|
|
5582
|
+
}
|
|
5583
|
+
}
|
|
5584
|
+
return { name, match, priority, before, after, hasAround, config };
|
|
5585
|
+
}
|
|
5586
|
+
function extractBuiltinFactory(factoryName, callPath) {
|
|
5587
|
+
const args = callPath.node.arguments;
|
|
5588
|
+
const opts = args.length > 0 && t18.isObjectExpression(args[0]) ? args[0] : null;
|
|
5589
|
+
switch (factoryName) {
|
|
5590
|
+
case "withAuth": {
|
|
5591
|
+
let redirectTo;
|
|
5592
|
+
if (opts) {
|
|
5593
|
+
for (const prop of opts.properties) {
|
|
5594
|
+
if (t18.isObjectProperty(prop) && t18.isIdentifier(prop.key) && prop.key.name === "redirectTo" && t18.isStringLiteral(prop.value)) {
|
|
5595
|
+
redirectTo = prop.value.value;
|
|
5596
|
+
}
|
|
5597
|
+
}
|
|
5598
|
+
}
|
|
5599
|
+
return {
|
|
5600
|
+
name: "mm:auth",
|
|
5601
|
+
match: ["*:*:transition.execute"],
|
|
5602
|
+
priority: 90,
|
|
5603
|
+
before: [{ type: "block", args: { condition: "!ctx.actor.id", reason: redirectTo ? `redirect:${redirectTo}` : "Authentication required" } }],
|
|
5604
|
+
after: [],
|
|
5605
|
+
hasAround: false,
|
|
5606
|
+
factory: "withAuth"
|
|
5607
|
+
};
|
|
5608
|
+
}
|
|
5609
|
+
case "withAuditLog": {
|
|
5610
|
+
let level = "info";
|
|
5611
|
+
if (opts) {
|
|
5612
|
+
for (const prop of opts.properties) {
|
|
5613
|
+
if (t18.isObjectProperty(prop) && t18.isIdentifier(prop.key) && prop.key.name === "level" && t18.isStringLiteral(prop.value)) {
|
|
5614
|
+
level = prop.value.value;
|
|
5615
|
+
}
|
|
5616
|
+
}
|
|
5617
|
+
}
|
|
5618
|
+
return {
|
|
5619
|
+
name: "mm:audit-log",
|
|
5620
|
+
match: ["*:*:transition.execute"],
|
|
5621
|
+
priority: 0,
|
|
5622
|
+
before: [],
|
|
5623
|
+
after: [{ type: "modify", args: { __audit: { level } } }],
|
|
5624
|
+
hasAround: false,
|
|
5625
|
+
factory: "withAuditLog"
|
|
5626
|
+
};
|
|
5627
|
+
}
|
|
5628
|
+
case "withRateLimit": {
|
|
5629
|
+
let maxPerMinute = 60;
|
|
5630
|
+
if (opts) {
|
|
5631
|
+
for (const prop of opts.properties) {
|
|
5632
|
+
if (t18.isObjectProperty(prop) && t18.isIdentifier(prop.key) && prop.key.name === "maxPerMinute" && t18.isNumericLiteral(prop.value)) {
|
|
5633
|
+
maxPerMinute = prop.value.value;
|
|
5634
|
+
}
|
|
5635
|
+
}
|
|
5636
|
+
}
|
|
5637
|
+
return {
|
|
5638
|
+
name: "mm:rate-limit",
|
|
5639
|
+
match: ["*:*:transition.execute"],
|
|
5640
|
+
priority: 80,
|
|
5641
|
+
before: [{ type: "block", args: { condition: `counter >= ${maxPerMinute}`, reason: `Rate limit exceeded: ${maxPerMinute} per minute` } }],
|
|
5642
|
+
after: [],
|
|
5643
|
+
hasAround: false,
|
|
5644
|
+
config: { maxPerMinute: { type: "number", default: maxPerMinute } },
|
|
5645
|
+
factory: "withRateLimit"
|
|
5646
|
+
};
|
|
5647
|
+
}
|
|
5648
|
+
case "withValidation": {
|
|
5649
|
+
const rules = [];
|
|
5650
|
+
if (opts) {
|
|
5651
|
+
for (const prop of opts.properties) {
|
|
5652
|
+
if (t18.isObjectProperty(prop) && t18.isIdentifier(prop.key) && prop.key.name === "rules" && t18.isArrayExpression(prop.value)) {
|
|
5653
|
+
for (const el of prop.value.elements) {
|
|
5654
|
+
if (!t18.isObjectExpression(el)) continue;
|
|
5655
|
+
let fields = [];
|
|
5656
|
+
let check = "";
|
|
5657
|
+
let message = "";
|
|
5658
|
+
for (const rp of el.properties) {
|
|
5659
|
+
if (!t18.isObjectProperty(rp) || !t18.isIdentifier(rp.key)) continue;
|
|
5660
|
+
if (rp.key.name === "fields" && t18.isArrayExpression(rp.value)) {
|
|
5661
|
+
fields = rp.value.elements.filter((e) => t18.isStringLiteral(e)).map((e) => e.value);
|
|
5662
|
+
}
|
|
5663
|
+
if (rp.key.name === "check" && t18.isStringLiteral(rp.value)) {
|
|
5664
|
+
check = rp.value.value;
|
|
5665
|
+
}
|
|
5666
|
+
if (rp.key.name === "message" && t18.isStringLiteral(rp.value)) {
|
|
5667
|
+
message = rp.value.value;
|
|
5668
|
+
}
|
|
5669
|
+
}
|
|
5670
|
+
if (fields.length > 0) rules.push({ fields, check, message });
|
|
5671
|
+
}
|
|
5672
|
+
}
|
|
5673
|
+
}
|
|
5674
|
+
}
|
|
5675
|
+
return {
|
|
5676
|
+
name: "mm:validation",
|
|
5677
|
+
match: ["*:*:field.change"],
|
|
5678
|
+
priority: 70,
|
|
5679
|
+
before: rules.map((r) => ({ type: "validate", args: { fields: r.fields, check: r.check, message: r.message } })),
|
|
5680
|
+
after: [],
|
|
5681
|
+
hasAround: false,
|
|
5682
|
+
config: { rules: { type: "json", default: rules } },
|
|
5683
|
+
factory: "withValidation"
|
|
5684
|
+
};
|
|
5685
|
+
}
|
|
5686
|
+
case "withMetrics": {
|
|
5687
|
+
let endpoint;
|
|
5688
|
+
if (opts) {
|
|
5689
|
+
for (const prop of opts.properties) {
|
|
5690
|
+
if (t18.isObjectProperty(prop) && t18.isIdentifier(prop.key) && prop.key.name === "endpoint" && t18.isStringLiteral(prop.value)) {
|
|
5691
|
+
endpoint = prop.value.value;
|
|
5692
|
+
}
|
|
5693
|
+
}
|
|
5694
|
+
}
|
|
5695
|
+
return {
|
|
5696
|
+
name: "mm:metrics",
|
|
5697
|
+
match: ["*:*:*"],
|
|
5698
|
+
priority: 100,
|
|
5699
|
+
before: [],
|
|
5700
|
+
after: [],
|
|
5701
|
+
hasAround: true,
|
|
5702
|
+
config: { endpoint: { type: "string", default: endpoint } },
|
|
5703
|
+
factory: "withMetrics"
|
|
5704
|
+
};
|
|
5705
|
+
}
|
|
5706
|
+
default:
|
|
5707
|
+
return null;
|
|
5708
|
+
}
|
|
5709
|
+
}
|
|
5710
|
+
function extractActionsFromBody(body, actions) {
|
|
5711
|
+
for (const stmt of body.body) {
|
|
5712
|
+
if (t18.isExpressionStatement(stmt) && t18.isCallExpression(stmt.expression)) {
|
|
5713
|
+
const call = stmt.expression;
|
|
5714
|
+
if (t18.isMemberExpression(call.callee) && t18.isIdentifier(call.callee.property)) {
|
|
5715
|
+
const method = call.callee.property.name;
|
|
5716
|
+
if (method === "block" && call.arguments.length > 0) {
|
|
5717
|
+
const arg = call.arguments[0];
|
|
5718
|
+
actions.push({
|
|
5719
|
+
type: "block",
|
|
5720
|
+
args: { reason: t18.isStringLiteral(arg) ? arg.value : "<expression>" }
|
|
5721
|
+
});
|
|
5722
|
+
} else if (method === "modify" && call.arguments.length > 0) {
|
|
5723
|
+
const arg = call.arguments[0];
|
|
5724
|
+
actions.push({
|
|
5725
|
+
type: "modify",
|
|
5726
|
+
args: t18.isObjectExpression(arg) ? extractStaticObject(arg) : {}
|
|
5727
|
+
});
|
|
5728
|
+
} else if (method === "skip") {
|
|
5729
|
+
actions.push({ type: "skip" });
|
|
5730
|
+
}
|
|
5731
|
+
}
|
|
5732
|
+
}
|
|
5733
|
+
if (t18.isIfStatement(stmt)) {
|
|
5734
|
+
if (t18.isBlockStatement(stmt.consequent)) {
|
|
5735
|
+
extractActionsFromBody(stmt.consequent, actions);
|
|
5736
|
+
} else if (t18.isExpressionStatement(stmt.consequent)) {
|
|
5737
|
+
extractActionsFromBody(
|
|
5738
|
+
t18.blockStatement([stmt.consequent]),
|
|
5739
|
+
actions
|
|
5740
|
+
);
|
|
5741
|
+
}
|
|
5742
|
+
}
|
|
5743
|
+
}
|
|
5744
|
+
}
|
|
5745
|
+
function extractStaticObject(obj) {
|
|
5746
|
+
const result = {};
|
|
5747
|
+
for (const prop of obj.properties) {
|
|
5748
|
+
if (!t18.isObjectProperty(prop)) continue;
|
|
5749
|
+
const key = t18.isIdentifier(prop.key) ? prop.key.name : t18.isStringLiteral(prop.key) ? prop.key.value : null;
|
|
5750
|
+
if (!key) continue;
|
|
5751
|
+
const val = prop.value;
|
|
5752
|
+
if (t18.isStringLiteral(val)) result[key] = val.value;
|
|
5753
|
+
else if (t18.isNumericLiteral(val)) result[key] = val.value;
|
|
5754
|
+
else if (t18.isBooleanLiteral(val)) result[key] = val.value;
|
|
5755
|
+
else if (t18.isNullLiteral(val)) result[key] = null;
|
|
5756
|
+
else if (t18.isObjectExpression(val)) result[key] = extractStaticObject(val);
|
|
5757
|
+
else if (t18.isMemberExpression(val)) {
|
|
5758
|
+
result[key] = memberExprToString2(val);
|
|
5759
|
+
} else {
|
|
5760
|
+
result[key] = "<expression>";
|
|
5761
|
+
}
|
|
3492
5762
|
}
|
|
3493
5763
|
return result;
|
|
3494
5764
|
}
|
|
5765
|
+
function memberExprToString2(expr) {
|
|
5766
|
+
const parts = [];
|
|
5767
|
+
let current = expr;
|
|
5768
|
+
while (t18.isMemberExpression(current)) {
|
|
5769
|
+
if (t18.isIdentifier(current.property)) {
|
|
5770
|
+
parts.unshift(current.property.name);
|
|
5771
|
+
}
|
|
5772
|
+
current = current.object;
|
|
5773
|
+
}
|
|
5774
|
+
if (t18.isIdentifier(current)) {
|
|
5775
|
+
parts.unshift(current.name);
|
|
5776
|
+
}
|
|
5777
|
+
return "$" + parts.join(".");
|
|
5778
|
+
}
|
|
5779
|
+
function extractConfigSchema(obj) {
|
|
5780
|
+
const schema = {};
|
|
5781
|
+
for (const prop of obj.properties) {
|
|
5782
|
+
if (!t18.isObjectProperty(prop) || !t18.isIdentifier(prop.key)) continue;
|
|
5783
|
+
if (!t18.isObjectExpression(prop.value)) continue;
|
|
5784
|
+
const entry = { type: "string" };
|
|
5785
|
+
for (const inner of prop.value.properties) {
|
|
5786
|
+
if (!t18.isObjectProperty(inner) || !t18.isIdentifier(inner.key)) continue;
|
|
5787
|
+
if (inner.key.name === "type" && t18.isStringLiteral(inner.value)) {
|
|
5788
|
+
entry.type = inner.value.value;
|
|
5789
|
+
}
|
|
5790
|
+
if (inner.key.name === "default") {
|
|
5791
|
+
if (t18.isStringLiteral(inner.value)) entry.default = inner.value.value;
|
|
5792
|
+
else if (t18.isNumericLiteral(inner.value)) entry.default = inner.value.value;
|
|
5793
|
+
else if (t18.isBooleanLiteral(inner.value)) entry.default = inner.value.value;
|
|
5794
|
+
}
|
|
5795
|
+
}
|
|
5796
|
+
schema[prop.key.name] = entry;
|
|
5797
|
+
}
|
|
5798
|
+
return schema;
|
|
5799
|
+
}
|
|
5800
|
+
|
|
5801
|
+
// src/babel/extractors/constraint-extractor.ts
|
|
5802
|
+
var t19 = __toESM(require("@babel/types"));
|
|
5803
|
+
var BUILTIN_CONSTRAINTS = /* @__PURE__ */ new Set([
|
|
5804
|
+
"every state is reachable",
|
|
5805
|
+
"no deadlocks",
|
|
5806
|
+
"no unreachable states",
|
|
5807
|
+
"deterministic guards",
|
|
5808
|
+
"terminates",
|
|
5809
|
+
"no guard overlaps",
|
|
5810
|
+
"all roles defined",
|
|
5811
|
+
"all fields validated"
|
|
5812
|
+
]);
|
|
5813
|
+
function hasConstraints(path) {
|
|
5814
|
+
for (const node of path.node.body) {
|
|
5815
|
+
if (t19.isExportNamedDeclaration(node) && node.declaration) {
|
|
5816
|
+
if (t19.isVariableDeclaration(node.declaration)) {
|
|
5817
|
+
for (const declarator of node.declaration.declarations) {
|
|
5818
|
+
if (declarator.init && isConstraintsCall(declarator.init)) {
|
|
5819
|
+
return true;
|
|
5820
|
+
}
|
|
5821
|
+
}
|
|
5822
|
+
}
|
|
5823
|
+
}
|
|
5824
|
+
if (t19.isVariableDeclaration(node)) {
|
|
5825
|
+
for (const declarator of node.declarations) {
|
|
5826
|
+
if (declarator.init && isConstraintsCall(declarator.init)) {
|
|
5827
|
+
return true;
|
|
5828
|
+
}
|
|
5829
|
+
}
|
|
5830
|
+
}
|
|
5831
|
+
if (t19.isExpressionStatement(node) && isConstraintsCall(node.expression)) {
|
|
5832
|
+
return true;
|
|
5833
|
+
}
|
|
5834
|
+
}
|
|
5835
|
+
return false;
|
|
5836
|
+
}
|
|
5837
|
+
function isConstraintsCall(node) {
|
|
5838
|
+
return t19.isCallExpression(node) && t19.isIdentifier(node.callee) && node.callee.name === "constraints";
|
|
5839
|
+
}
|
|
5840
|
+
function extractConstraints(path, state) {
|
|
5841
|
+
const compilerState = state;
|
|
5842
|
+
if (!compilerState.metadata) compilerState.metadata = {};
|
|
5843
|
+
const meta = compilerState.metadata;
|
|
5844
|
+
if (!meta.constraints) meta.constraints = [];
|
|
5845
|
+
const constraintList = meta.constraints;
|
|
5846
|
+
path.traverse({
|
|
5847
|
+
CallExpression(callPath) {
|
|
5848
|
+
const callee = callPath.node.callee;
|
|
5849
|
+
if (!t19.isIdentifier(callee) || callee.name !== "constraints") return;
|
|
5850
|
+
const args = callPath.node.arguments;
|
|
5851
|
+
for (const arg of args) {
|
|
5852
|
+
if (t19.isStringLiteral(arg)) {
|
|
5853
|
+
constraintList.push({
|
|
5854
|
+
rule: arg.value,
|
|
5855
|
+
type: BUILTIN_CONSTRAINTS.has(arg.value) ? "builtin" : "custom"
|
|
5856
|
+
});
|
|
5857
|
+
}
|
|
5858
|
+
}
|
|
5859
|
+
}
|
|
5860
|
+
});
|
|
5861
|
+
}
|
|
3495
5862
|
|
|
3496
|
-
//
|
|
3497
|
-
|
|
3498
|
-
|
|
3499
|
-
|
|
3500
|
-
|
|
5863
|
+
// src/babel/extractors/actor-extractor.ts
|
|
5864
|
+
var t20 = __toESM(require("@babel/types"));
|
|
5865
|
+
function hasActorConfig(path) {
|
|
5866
|
+
for (const node of path.node.body) {
|
|
5867
|
+
if (t20.isExportNamedDeclaration(node) && node.declaration) {
|
|
5868
|
+
if (t20.isVariableDeclaration(node.declaration)) {
|
|
5869
|
+
for (const declarator of node.declaration.declarations) {
|
|
5870
|
+
if (declarator.init && isActorCall(declarator.init)) {
|
|
5871
|
+
return true;
|
|
5872
|
+
}
|
|
5873
|
+
}
|
|
5874
|
+
}
|
|
5875
|
+
}
|
|
5876
|
+
if (t20.isVariableDeclaration(node)) {
|
|
5877
|
+
for (const declarator of node.declarations) {
|
|
5878
|
+
if (declarator.init && isActorCall(declarator.init)) {
|
|
5879
|
+
return true;
|
|
5880
|
+
}
|
|
5881
|
+
}
|
|
5882
|
+
}
|
|
5883
|
+
if (t20.isExpressionStatement(node) && isActorCall(node.expression)) {
|
|
5884
|
+
return true;
|
|
5885
|
+
}
|
|
5886
|
+
}
|
|
5887
|
+
return false;
|
|
5888
|
+
}
|
|
5889
|
+
function isActorCall(node) {
|
|
5890
|
+
return t20.isCallExpression(node) && t20.isIdentifier(node.callee) && (node.callee.name === "configureActor" || node.callee.name === "spawnActor");
|
|
5891
|
+
}
|
|
5892
|
+
function extractActorConfig(path, state) {
|
|
5893
|
+
const compilerState = state;
|
|
5894
|
+
if (!compilerState.metadata) compilerState.metadata = {};
|
|
5895
|
+
const meta = compilerState.metadata;
|
|
5896
|
+
if (!meta.actor) {
|
|
5897
|
+
meta.actor = {
|
|
5898
|
+
supervision: { strategy: "escalate" },
|
|
5899
|
+
mailbox: {},
|
|
5900
|
+
hierarchy: {},
|
|
5901
|
+
spawns: []
|
|
5902
|
+
};
|
|
5903
|
+
}
|
|
5904
|
+
const actorConfig = meta.actor;
|
|
5905
|
+
path.traverse({
|
|
5906
|
+
CallExpression(callPath) {
|
|
5907
|
+
const callee = callPath.node.callee;
|
|
5908
|
+
if (!t20.isIdentifier(callee)) return;
|
|
5909
|
+
if (callee.name === "configureActor") {
|
|
5910
|
+
extractConfigureActor(callPath, actorConfig);
|
|
5911
|
+
} else if (callee.name === "spawnActor") {
|
|
5912
|
+
extractSpawnActor(callPath, actorConfig);
|
|
5913
|
+
}
|
|
5914
|
+
}
|
|
5915
|
+
});
|
|
5916
|
+
}
|
|
5917
|
+
function extractConfigureActor(callPath, actorConfig) {
|
|
5918
|
+
const args = callPath.node.arguments;
|
|
5919
|
+
if (args.length < 1 || !t20.isObjectExpression(args[0])) return;
|
|
5920
|
+
const obj = args[0];
|
|
5921
|
+
for (const prop of obj.properties) {
|
|
5922
|
+
if (!t20.isObjectProperty(prop) || !t20.isIdentifier(prop.key)) continue;
|
|
5923
|
+
switch (prop.key.name) {
|
|
5924
|
+
case "supervision":
|
|
5925
|
+
if (t20.isObjectExpression(prop.value)) {
|
|
5926
|
+
actorConfig.supervision = extractSupervision(prop.value);
|
|
5927
|
+
}
|
|
5928
|
+
break;
|
|
5929
|
+
case "mailbox":
|
|
5930
|
+
if (t20.isObjectExpression(prop.value)) {
|
|
5931
|
+
actorConfig.mailbox = extractMailbox(prop.value);
|
|
5932
|
+
}
|
|
5933
|
+
break;
|
|
5934
|
+
case "hierarchy":
|
|
5935
|
+
if (t20.isObjectExpression(prop.value)) {
|
|
5936
|
+
actorConfig.hierarchy = extractStaticObj(prop.value);
|
|
5937
|
+
}
|
|
5938
|
+
break;
|
|
5939
|
+
}
|
|
5940
|
+
}
|
|
5941
|
+
}
|
|
5942
|
+
function extractSpawnActor(callPath, actorConfig) {
|
|
5943
|
+
const args = callPath.node.arguments;
|
|
5944
|
+
if (args.length < 1 || !t20.isStringLiteral(args[0])) return;
|
|
5945
|
+
const spawn = { slug: args[0].value };
|
|
5946
|
+
if (args.length > 1 && t20.isObjectExpression(args[1])) {
|
|
5947
|
+
for (const prop of args[1].properties) {
|
|
5948
|
+
if (!t20.isObjectProperty(prop) || !t20.isIdentifier(prop.key)) continue;
|
|
5949
|
+
if (prop.key.name === "supervision" && t20.isObjectExpression(prop.value)) {
|
|
5950
|
+
spawn.supervision = extractSupervision(prop.value);
|
|
5951
|
+
} else if (prop.key.name === "blocking" && t20.isBooleanLiteral(prop.value)) {
|
|
5952
|
+
spawn.blocking = prop.value.value;
|
|
5953
|
+
}
|
|
5954
|
+
}
|
|
5955
|
+
}
|
|
5956
|
+
actorConfig.spawns.push(spawn);
|
|
5957
|
+
}
|
|
5958
|
+
function extractSupervision(obj) {
|
|
5959
|
+
const result = { strategy: "escalate" };
|
|
5960
|
+
for (const prop of obj.properties) {
|
|
5961
|
+
if (!t20.isObjectProperty(prop) || !t20.isIdentifier(prop.key)) continue;
|
|
5962
|
+
switch (prop.key.name) {
|
|
5963
|
+
case "strategy":
|
|
5964
|
+
if (t20.isStringLiteral(prop.value)) result.strategy = prop.value.value;
|
|
5965
|
+
break;
|
|
5966
|
+
case "maxRetries":
|
|
5967
|
+
if (t20.isNumericLiteral(prop.value)) result.maxRetries = prop.value.value;
|
|
5968
|
+
break;
|
|
5969
|
+
case "retryWindow":
|
|
5970
|
+
if (t20.isStringLiteral(prop.value)) result.retryWindow = prop.value.value;
|
|
5971
|
+
break;
|
|
5972
|
+
case "backoff":
|
|
5973
|
+
if (t20.isStringLiteral(prop.value)) result.backoff = prop.value.value;
|
|
5974
|
+
break;
|
|
5975
|
+
}
|
|
5976
|
+
}
|
|
5977
|
+
return result;
|
|
5978
|
+
}
|
|
5979
|
+
function extractMailbox(obj) {
|
|
5980
|
+
const result = {};
|
|
5981
|
+
for (const prop of obj.properties) {
|
|
5982
|
+
if (!t20.isObjectProperty(prop) || !t20.isIdentifier(prop.key)) continue;
|
|
5983
|
+
switch (prop.key.name) {
|
|
5984
|
+
case "capacity":
|
|
5985
|
+
if (t20.isNumericLiteral(prop.value)) result.capacity = prop.value.value;
|
|
5986
|
+
break;
|
|
5987
|
+
case "overflow":
|
|
5988
|
+
if (t20.isStringLiteral(prop.value)) result.overflow = prop.value.value;
|
|
5989
|
+
break;
|
|
5990
|
+
case "priority":
|
|
5991
|
+
if (t20.isStringLiteral(prop.value)) result.priority = prop.value.value;
|
|
5992
|
+
break;
|
|
5993
|
+
}
|
|
5994
|
+
}
|
|
5995
|
+
return result;
|
|
5996
|
+
}
|
|
5997
|
+
function extractStaticObj(obj) {
|
|
5998
|
+
const result = {};
|
|
5999
|
+
for (const prop of obj.properties) {
|
|
6000
|
+
if (!t20.isObjectProperty(prop) || !t20.isIdentifier(prop.key)) continue;
|
|
6001
|
+
const val = prop.value;
|
|
6002
|
+
if (t20.isStringLiteral(val)) result[prop.key.name] = val.value;
|
|
6003
|
+
else if (t20.isNumericLiteral(val)) result[prop.key.name] = val.value;
|
|
6004
|
+
else if (t20.isBooleanLiteral(val)) result[prop.key.name] = val.value;
|
|
6005
|
+
else if (t20.isNullLiteral(val)) result[prop.key.name] = null;
|
|
6006
|
+
}
|
|
6007
|
+
return result;
|
|
3501
6008
|
}
|
|
3502
6009
|
|
|
6010
|
+
// src/babel/emitters/pure-form-emitter.ts
|
|
6011
|
+
var import_player_core = require("@mmapp/player-core");
|
|
6012
|
+
|
|
3503
6013
|
// src/babel/emitters/experience-transform.ts
|
|
3504
6014
|
function transformToFrontend(node) {
|
|
3505
6015
|
const result = {
|
|
@@ -3717,7 +6227,7 @@ function normalizeViewNode(node, fieldNames) {
|
|
|
3717
6227
|
}
|
|
3718
6228
|
return node;
|
|
3719
6229
|
}
|
|
3720
|
-
function
|
|
6230
|
+
function toSnakeCase3(str) {
|
|
3721
6231
|
return str.replace(/([A-Z])/g, "_$1").toLowerCase().replace(/^_/, "");
|
|
3722
6232
|
}
|
|
3723
6233
|
function convertAction(action) {
|
|
@@ -3785,6 +6295,18 @@ function emitIR(extracted) {
|
|
|
3785
6295
|
});
|
|
3786
6296
|
stateNames.add(transition.to);
|
|
3787
6297
|
}
|
|
6298
|
+
for (const from of transition.from) {
|
|
6299
|
+
if (from && !stateNames.has(from)) {
|
|
6300
|
+
stateArray.push({
|
|
6301
|
+
name: from,
|
|
6302
|
+
type: "REGULAR",
|
|
6303
|
+
on_enter: [],
|
|
6304
|
+
during: [],
|
|
6305
|
+
on_exit: []
|
|
6306
|
+
});
|
|
6307
|
+
stateNames.add(from);
|
|
6308
|
+
}
|
|
6309
|
+
}
|
|
3788
6310
|
}
|
|
3789
6311
|
const fieldNames = new Set(fields.map((f) => f.name));
|
|
3790
6312
|
let normalizedView;
|
|
@@ -3800,7 +6322,7 @@ function emitIR(extracted) {
|
|
|
3800
6322
|
if (fields.length > 0) {
|
|
3801
6323
|
const localDefaults = {};
|
|
3802
6324
|
for (const f of fields) {
|
|
3803
|
-
localDefaults[
|
|
6325
|
+
localDefaults[toSnakeCase3(f.name)] = f.default_value ?? null;
|
|
3804
6326
|
}
|
|
3805
6327
|
if (!normalizedView.config) normalizedView.config = {};
|
|
3806
6328
|
normalizedView.config.localDefaults = localDefaults;
|
|
@@ -3879,7 +6401,7 @@ function liftAction(action) {
|
|
|
3879
6401
|
}
|
|
3880
6402
|
return {
|
|
3881
6403
|
slug: action.id,
|
|
3882
|
-
category: normalizeCategory("expression", "mutation", action.type),
|
|
6404
|
+
category: (0, import_player_core.normalizeCategory)("expression", "mutation", action.type),
|
|
3883
6405
|
parts: parts.length > 0 ? parts : void 0
|
|
3884
6406
|
};
|
|
3885
6407
|
}
|
|
@@ -3909,7 +6431,7 @@ function liftSchedule(during) {
|
|
|
3909
6431
|
for (const action of during.actions) {
|
|
3910
6432
|
parts.push({
|
|
3911
6433
|
slug: "do",
|
|
3912
|
-
category: normalizeCategory("expression", "mutation", action.type),
|
|
6434
|
+
category: (0, import_player_core.normalizeCategory)("expression", "mutation", action.type),
|
|
3913
6435
|
parts: Object.entries(action.config || {}).map(([key, value]) => ({
|
|
3914
6436
|
slug: key,
|
|
3915
6437
|
category: ["atom"],
|
|
@@ -3919,7 +6441,7 @@ function liftSchedule(during) {
|
|
|
3919
6441
|
}
|
|
3920
6442
|
return {
|
|
3921
6443
|
slug: during.id,
|
|
3922
|
-
category: normalizeCategory("schedule", during.type),
|
|
6444
|
+
category: (0, import_player_core.normalizeCategory)("schedule", during.type),
|
|
3923
6445
|
parts
|
|
3924
6446
|
};
|
|
3925
6447
|
}
|
|
@@ -3932,14 +6454,14 @@ function liftState(state) {
|
|
|
3932
6454
|
if (state.on_enter && state.on_enter.length > 0) {
|
|
3933
6455
|
parts.push({
|
|
3934
6456
|
slug: "on_enter",
|
|
3935
|
-
category: normalizeCategory("expression", "sequence"),
|
|
6457
|
+
category: (0, import_player_core.normalizeCategory)("expression", "sequence"),
|
|
3936
6458
|
parts: state.on_enter.map(liftAction)
|
|
3937
6459
|
});
|
|
3938
6460
|
}
|
|
3939
6461
|
if (state.on_exit && state.on_exit.length > 0) {
|
|
3940
6462
|
parts.push({
|
|
3941
6463
|
slug: "on_exit",
|
|
3942
|
-
category: normalizeCategory("expression", "sequence"),
|
|
6464
|
+
category: (0, import_player_core.normalizeCategory)("expression", "sequence"),
|
|
3943
6465
|
parts: state.on_exit.map(liftAction)
|
|
3944
6466
|
});
|
|
3945
6467
|
}
|
|
@@ -3950,7 +6472,7 @@ function liftState(state) {
|
|
|
3950
6472
|
}
|
|
3951
6473
|
return {
|
|
3952
6474
|
slug: state.name,
|
|
3953
|
-
category: normalizeCategory("state", ...tags),
|
|
6475
|
+
category: (0, import_player_core.normalizeCategory)("state", ...tags),
|
|
3954
6476
|
parts: parts.length > 0 ? parts : void 0
|
|
3955
6477
|
};
|
|
3956
6478
|
}
|
|
@@ -3973,17 +6495,17 @@ function liftTransition(transition) {
|
|
|
3973
6495
|
if (transition.actions && transition.actions.length > 0) {
|
|
3974
6496
|
parts.push({
|
|
3975
6497
|
slug: "actions",
|
|
3976
|
-
category: normalizeCategory("expression", "sequence"),
|
|
6498
|
+
category: (0, import_player_core.normalizeCategory)("expression", "sequence"),
|
|
3977
6499
|
parts: transition.actions.map(liftAction)
|
|
3978
6500
|
});
|
|
3979
6501
|
}
|
|
3980
6502
|
if (transition.conditions && transition.conditions.length > 0) {
|
|
3981
6503
|
parts.push({
|
|
3982
6504
|
slug: "conditions",
|
|
3983
|
-
category: normalizeCategory("expression", "guard"),
|
|
6505
|
+
category: (0, import_player_core.normalizeCategory)("expression", "guard"),
|
|
3984
6506
|
parts: transition.conditions.map((c, i) => ({
|
|
3985
6507
|
slug: `condition_${i}`,
|
|
3986
|
-
category: normalizeCategory("expression", c.type || "condition"),
|
|
6508
|
+
category: (0, import_player_core.normalizeCategory)("expression", c.type || "condition"),
|
|
3987
6509
|
parts: c.expression ? [{ slug: c.expression, category: ["binding"] }] : void 0
|
|
3988
6510
|
}))
|
|
3989
6511
|
});
|
|
@@ -4022,7 +6544,7 @@ function liftField(field) {
|
|
|
4022
6544
|
}
|
|
4023
6545
|
return {
|
|
4024
6546
|
slug: field.name,
|
|
4025
|
-
category: normalizeCategory("field", field.type),
|
|
6547
|
+
category: (0, import_player_core.normalizeCategory)("field", field.type),
|
|
4026
6548
|
parts: parts.length > 0 ? parts : void 0
|
|
4027
6549
|
};
|
|
4028
6550
|
}
|
|
@@ -4045,20 +6567,20 @@ function liftView(node) {
|
|
|
4045
6567
|
if (match) {
|
|
4046
6568
|
parts.push({
|
|
4047
6569
|
slug: key,
|
|
4048
|
-
category: normalizeCategory("expression", "effect", "transition"),
|
|
6570
|
+
category: (0, import_player_core.normalizeCategory)("expression", "effect", "transition"),
|
|
4049
6571
|
parts: [{ slug: match[1], category: ["ref"] }]
|
|
4050
6572
|
});
|
|
4051
6573
|
} else {
|
|
4052
6574
|
parts.push({
|
|
4053
6575
|
slug: key,
|
|
4054
|
-
category: normalizeCategory("expression", "binding"),
|
|
6576
|
+
category: (0, import_player_core.normalizeCategory)("expression", "binding"),
|
|
4055
6577
|
parts: [{ slug: String(expr), category: ["binding"] }]
|
|
4056
6578
|
});
|
|
4057
6579
|
}
|
|
4058
6580
|
} else {
|
|
4059
6581
|
parts.push({
|
|
4060
6582
|
slug: key,
|
|
4061
|
-
category: normalizeCategory("expression", "binding"),
|
|
6583
|
+
category: (0, import_player_core.normalizeCategory)("expression", "binding"),
|
|
4062
6584
|
parts: [{ slug: String(expr), category: ["binding"] }]
|
|
4063
6585
|
});
|
|
4064
6586
|
}
|
|
@@ -4069,20 +6591,20 @@ function liftView(node) {
|
|
|
4069
6591
|
if (eqMatch) {
|
|
4070
6592
|
parts.push({
|
|
4071
6593
|
slug: "visible_when",
|
|
4072
|
-
category: normalizeCategory("expression", "guard"),
|
|
6594
|
+
category: (0, import_player_core.normalizeCategory)("expression", "guard"),
|
|
4073
6595
|
parts: [{
|
|
4074
6596
|
slug: "body",
|
|
4075
|
-
category: normalizeCategory("expression", "eq"),
|
|
6597
|
+
category: (0, import_player_core.normalizeCategory)("expression", "eq"),
|
|
4076
6598
|
parts: [
|
|
4077
|
-
{ slug: "lhs", category: normalizeCategory("expression", "path"), parts: [{ slug: eqMatch[1], category: ["binding"] }] },
|
|
4078
|
-
{ slug: "rhs", category: normalizeCategory("expression", "literal"), parts: [{ slug: eqMatch[2], category: ["literal"] }] }
|
|
6599
|
+
{ slug: "lhs", category: (0, import_player_core.normalizeCategory)("expression", "path"), parts: [{ slug: eqMatch[1], category: ["binding"] }] },
|
|
6600
|
+
{ slug: "rhs", category: (0, import_player_core.normalizeCategory)("expression", "literal"), parts: [{ slug: eqMatch[2], category: ["literal"] }] }
|
|
4079
6601
|
]
|
|
4080
6602
|
}]
|
|
4081
6603
|
});
|
|
4082
6604
|
} else {
|
|
4083
6605
|
parts.push({
|
|
4084
6606
|
slug: "visible_when",
|
|
4085
|
-
category: normalizeCategory("expression", "guard"),
|
|
6607
|
+
category: (0, import_player_core.normalizeCategory)("expression", "guard"),
|
|
4086
6608
|
parts: [{ slug: node.visible_when, category: ["binding"] }]
|
|
4087
6609
|
});
|
|
4088
6610
|
}
|
|
@@ -4094,7 +6616,7 @@ function liftView(node) {
|
|
|
4094
6616
|
}
|
|
4095
6617
|
return {
|
|
4096
6618
|
slug: node.id,
|
|
4097
|
-
category: normalizeCategory("view", componentTag),
|
|
6619
|
+
category: (0, import_player_core.normalizeCategory)("view", componentTag),
|
|
4098
6620
|
parts: parts.length > 0 ? parts : void 0
|
|
4099
6621
|
};
|
|
4100
6622
|
}
|
|
@@ -4115,7 +6637,7 @@ function emitCanonical(extracted, sourceFilename) {
|
|
|
4115
6637
|
}
|
|
4116
6638
|
parts.push({
|
|
4117
6639
|
slug: "manifest",
|
|
4118
|
-
category: normalizeCategory("meta", "manifest"),
|
|
6640
|
+
category: (0, import_player_core.normalizeCategory)("meta", "manifest"),
|
|
4119
6641
|
parts: [
|
|
4120
6642
|
{
|
|
4121
6643
|
slug: "workflows",
|
|
@@ -4136,7 +6658,7 @@ function emitCanonical(extracted, sourceFilename) {
|
|
|
4136
6658
|
let categoryArray;
|
|
4137
6659
|
if (category.includes("/")) {
|
|
4138
6660
|
const [primary, ...tags] = category.split("/");
|
|
4139
|
-
categoryArray = normalizeCategory(primary, ...tags);
|
|
6661
|
+
categoryArray = (0, import_player_core.normalizeCategory)(primary, ...tags);
|
|
4140
6662
|
} else {
|
|
4141
6663
|
categoryArray = [category];
|
|
4142
6664
|
}
|
|
@@ -4198,7 +6720,7 @@ function emitWorkflowDefinition(extracted) {
|
|
|
4198
6720
|
on_event: (s.on_event || []).map(convertOnEvent)
|
|
4199
6721
|
}));
|
|
4200
6722
|
const fields = ir.fields.map((f) => ({
|
|
4201
|
-
name:
|
|
6723
|
+
name: toSnakeCase3(f.name),
|
|
4202
6724
|
field_type: f.type,
|
|
4203
6725
|
label: f.label || f.name.replace(/([A-Z])/g, " $1").replace(/^./, (c) => c.toUpperCase()),
|
|
4204
6726
|
required: f.required || false,
|
|
@@ -4214,16 +6736,16 @@ function emitWorkflowDefinition(extracted) {
|
|
|
4214
6736
|
...f.editable_when && { editable_when: f.editable_when },
|
|
4215
6737
|
...f.state_home && { state_home: f.state_home }
|
|
4216
6738
|
}));
|
|
4217
|
-
const transitions = ir.transitions.map((
|
|
4218
|
-
name:
|
|
4219
|
-
from:
|
|
4220
|
-
to:
|
|
4221
|
-
description:
|
|
4222
|
-
roles:
|
|
4223
|
-
auto:
|
|
4224
|
-
conditions:
|
|
4225
|
-
actions: (
|
|
4226
|
-
required_fields:
|
|
6739
|
+
const transitions = ir.transitions.map((t22) => ({
|
|
6740
|
+
name: t22.name,
|
|
6741
|
+
from: t22.from,
|
|
6742
|
+
to: t22.to,
|
|
6743
|
+
description: t22.description || "",
|
|
6744
|
+
roles: t22.roles || [],
|
|
6745
|
+
auto: t22.auto || false,
|
|
6746
|
+
conditions: t22.conditions || [],
|
|
6747
|
+
actions: (t22.actions || []).map(convertAction),
|
|
6748
|
+
required_fields: t22.required_fields || [],
|
|
4227
6749
|
priority: 0
|
|
4228
6750
|
}));
|
|
4229
6751
|
const state_data = {};
|
|
@@ -4241,7 +6763,7 @@ function emitWorkflowDefinition(extracted) {
|
|
|
4241
6763
|
if (extracted.fields.length > 0) {
|
|
4242
6764
|
const localDefaults = {};
|
|
4243
6765
|
for (const f of extracted.fields) {
|
|
4244
|
-
localDefaults[
|
|
6766
|
+
localDefaults[toSnakeCase3(f.name)] = f.default_value ?? null;
|
|
4245
6767
|
}
|
|
4246
6768
|
if (!viewRoot.config) viewRoot.config = {};
|
|
4247
6769
|
viewRoot.config.localDefaults = localDefaults;
|
|
@@ -4304,8 +6826,8 @@ function compilerStateToWorkflow(state, metadata) {
|
|
|
4304
6826
|
function resolveSlugArg(args, state) {
|
|
4305
6827
|
if (args.length < 1) return null;
|
|
4306
6828
|
const slugArg = args[0];
|
|
4307
|
-
if (
|
|
4308
|
-
if (
|
|
6829
|
+
if (t21.isStringLiteral(slugArg)) return slugArg.value;
|
|
6830
|
+
if (t21.isIdentifier(slugArg)) {
|
|
4309
6831
|
const compilerState = state;
|
|
4310
6832
|
const meta = compilerState.metadata;
|
|
4311
6833
|
const resolvedSlugs = meta.__modelImportSlugs;
|
|
@@ -4331,43 +6853,43 @@ function extractQueryDataSource(path, state) {
|
|
|
4331
6853
|
slug,
|
|
4332
6854
|
query: "list"
|
|
4333
6855
|
};
|
|
4334
|
-
if (args.length > 1 &&
|
|
6856
|
+
if (args.length > 1 && t21.isObjectExpression(args[1])) {
|
|
4335
6857
|
for (const prop of args[1].properties) {
|
|
4336
|
-
if (!
|
|
6858
|
+
if (!t21.isObjectProperty(prop) || !t21.isIdentifier(prop.key)) continue;
|
|
4337
6859
|
const key = prop.key.name;
|
|
4338
6860
|
const val = prop.value;
|
|
4339
6861
|
switch (key) {
|
|
4340
6862
|
case "limit":
|
|
4341
|
-
if (
|
|
6863
|
+
if (t21.isNumericLiteral(val)) {
|
|
4342
6864
|
dataSource.pageSize = val.value;
|
|
4343
6865
|
dataSource.paginated = true;
|
|
4344
6866
|
}
|
|
4345
6867
|
break;
|
|
4346
6868
|
case "orderBy":
|
|
4347
|
-
if (
|
|
6869
|
+
if (t21.isStringLiteral(val)) {
|
|
4348
6870
|
dataSource.sort = val.value;
|
|
4349
6871
|
}
|
|
4350
6872
|
break;
|
|
4351
6873
|
case "order":
|
|
4352
|
-
if (
|
|
6874
|
+
if (t21.isStringLiteral(val) && dataSource.sort) {
|
|
4353
6875
|
dataSource.sort = `${dataSource.sort}:${val.value}`;
|
|
4354
6876
|
}
|
|
4355
6877
|
break;
|
|
4356
6878
|
case "search":
|
|
4357
|
-
if (
|
|
6879
|
+
if (t21.isStringLiteral(val)) {
|
|
4358
6880
|
dataSource.search = val.value;
|
|
4359
6881
|
}
|
|
4360
6882
|
break;
|
|
4361
6883
|
case "searchFields":
|
|
4362
|
-
if (
|
|
4363
|
-
dataSource.searchFields = val.elements.filter((el) =>
|
|
6884
|
+
if (t21.isArrayExpression(val)) {
|
|
6885
|
+
dataSource.searchFields = val.elements.filter((el) => t21.isStringLiteral(el)).map((el) => el.value);
|
|
4364
6886
|
}
|
|
4365
6887
|
break;
|
|
4366
6888
|
case "filter":
|
|
4367
|
-
if (
|
|
6889
|
+
if (t21.isObjectExpression(val)) {
|
|
4368
6890
|
const filter = {};
|
|
4369
6891
|
for (const fp of val.properties) {
|
|
4370
|
-
if (
|
|
6892
|
+
if (t21.isObjectProperty(fp) && t21.isIdentifier(fp.key) && t21.isStringLiteral(fp.value)) {
|
|
4371
6893
|
filter[fp.key.name] = fp.value.value;
|
|
4372
6894
|
}
|
|
4373
6895
|
}
|
|
@@ -4377,19 +6899,19 @@ function extractQueryDataSource(path, state) {
|
|
|
4377
6899
|
}
|
|
4378
6900
|
break;
|
|
4379
6901
|
case "state":
|
|
4380
|
-
if (
|
|
6902
|
+
if (t21.isStringLiteral(val)) {
|
|
4381
6903
|
if (!dataSource.filter) dataSource.filter = {};
|
|
4382
6904
|
dataSource.filter.current_state = val.value;
|
|
4383
6905
|
}
|
|
4384
6906
|
break;
|
|
4385
6907
|
case "groupBy":
|
|
4386
|
-
if (
|
|
6908
|
+
if (t21.isStringLiteral(val)) {
|
|
4387
6909
|
dataSource.groupBy = val.value;
|
|
4388
6910
|
}
|
|
4389
6911
|
break;
|
|
4390
6912
|
case "facets":
|
|
4391
|
-
if (
|
|
4392
|
-
dataSource.facets = val.elements.filter((el) =>
|
|
6913
|
+
if (t21.isArrayExpression(val)) {
|
|
6914
|
+
dataSource.facets = val.elements.filter((el) => t21.isStringLiteral(el)).map((el) => el.value);
|
|
4393
6915
|
}
|
|
4394
6916
|
break;
|
|
4395
6917
|
}
|
|
@@ -4413,17 +6935,17 @@ function extractMutationDataSource(path, state) {
|
|
|
4413
6935
|
}
|
|
4414
6936
|
function extractDuringAction(path, state) {
|
|
4415
6937
|
const args = path.node.arguments;
|
|
4416
|
-
if (args.length < 1 || !
|
|
6938
|
+
if (args.length < 1 || !t21.isObjectExpression(args[0])) return;
|
|
4417
6939
|
const compilerState = state;
|
|
4418
6940
|
const config = args[0];
|
|
4419
6941
|
let stateName;
|
|
4420
6942
|
let intervalMs = 1e3;
|
|
4421
6943
|
for (const prop of config.properties) {
|
|
4422
|
-
if (!
|
|
4423
|
-
if (prop.key.name === "state" &&
|
|
6944
|
+
if (!t21.isObjectProperty(prop) || !t21.isIdentifier(prop.key)) continue;
|
|
6945
|
+
if (prop.key.name === "state" && t21.isStringLiteral(prop.value)) {
|
|
4424
6946
|
stateName = prop.value.value;
|
|
4425
6947
|
}
|
|
4426
|
-
if (prop.key.name === "intervalMs" &&
|
|
6948
|
+
if (prop.key.name === "intervalMs" && t21.isNumericLiteral(prop.value)) {
|
|
4427
6949
|
intervalMs = prop.value.value;
|
|
4428
6950
|
}
|
|
4429
6951
|
}
|
|
@@ -4449,7 +6971,7 @@ function extractDuringAction(path, state) {
|
|
|
4449
6971
|
}
|
|
4450
6972
|
function extractRoleDependency(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;
|
|
@@ -4460,7 +6982,7 @@ function extractRoleDependency(path, state) {
|
|
|
4460
6982
|
}
|
|
4461
6983
|
function extractViewDependency(path, state) {
|
|
4462
6984
|
const args = path.node.arguments;
|
|
4463
|
-
if (args.length < 1 || !
|
|
6985
|
+
if (args.length < 1 || !t21.isStringLiteral(args[0])) return;
|
|
4464
6986
|
const compilerState = state;
|
|
4465
6987
|
if (!compilerState.metadata) compilerState.metadata = {};
|
|
4466
6988
|
const meta = compilerState.metadata;
|
|
@@ -4477,7 +6999,7 @@ function extractParamsUsage(_path, state) {
|
|
|
4477
6999
|
}
|
|
4478
7000
|
function extractLibraryDependency(path, state) {
|
|
4479
7001
|
const args = path.node.arguments;
|
|
4480
|
-
if (args.length < 1 || !
|
|
7002
|
+
if (args.length < 1 || !t21.isStringLiteral(args[0])) return;
|
|
4481
7003
|
const compilerState = state;
|
|
4482
7004
|
if (!compilerState.metadata) compilerState.metadata = {};
|
|
4483
7005
|
const meta = compilerState.metadata;
|
|
@@ -4557,15 +7079,15 @@ function createVisitor(options = {}) {
|
|
|
4557
7079
|
}
|
|
4558
7080
|
}
|
|
4559
7081
|
const exportDeclaration = program.body.find(
|
|
4560
|
-
(node) =>
|
|
7082
|
+
(node) => t21.isExportNamedDeclaration(node) || t21.isExportDefaultDeclaration(node)
|
|
4561
7083
|
);
|
|
4562
7084
|
if (exportDeclaration) {
|
|
4563
7085
|
if (exportDeclaration.leadingComments) {
|
|
4564
7086
|
extractMetadataFromComments(exportDeclaration.leadingComments, compilerState.metadata);
|
|
4565
7087
|
}
|
|
4566
|
-
if (
|
|
7088
|
+
if (t21.isExportNamedDeclaration(exportDeclaration)) {
|
|
4567
7089
|
const declaration = exportDeclaration.declaration;
|
|
4568
|
-
if (
|
|
7090
|
+
if (t21.isFunctionDeclaration(declaration)) {
|
|
4569
7091
|
if (declaration.id) {
|
|
4570
7092
|
compilerState.metadata.name = declaration.id.name;
|
|
4571
7093
|
}
|
|
@@ -4573,16 +7095,16 @@ function createVisitor(options = {}) {
|
|
|
4573
7095
|
extractMetadataFromComments(declaration.leadingComments, compilerState.metadata);
|
|
4574
7096
|
}
|
|
4575
7097
|
}
|
|
4576
|
-
} else if (
|
|
7098
|
+
} else if (t21.isExportDefaultDeclaration(exportDeclaration)) {
|
|
4577
7099
|
const declaration = exportDeclaration.declaration;
|
|
4578
|
-
if (
|
|
7100
|
+
if (t21.isFunctionDeclaration(declaration)) {
|
|
4579
7101
|
if (declaration.id) {
|
|
4580
7102
|
compilerState.metadata.name = declaration.id.name;
|
|
4581
7103
|
}
|
|
4582
7104
|
if (declaration.leadingComments) {
|
|
4583
7105
|
extractMetadataFromComments(declaration.leadingComments, compilerState.metadata);
|
|
4584
7106
|
}
|
|
4585
|
-
} else if (
|
|
7107
|
+
} else if (t21.isIdentifier(declaration)) {
|
|
4586
7108
|
compilerState.metadata.name = declaration.name;
|
|
4587
7109
|
}
|
|
4588
7110
|
}
|
|
@@ -4593,7 +7115,13 @@ function createVisitor(options = {}) {
|
|
|
4593
7115
|
compilerState.metadata.__slugAutoFallback = true;
|
|
4594
7116
|
}
|
|
4595
7117
|
Object.assign(state, compilerState);
|
|
4596
|
-
if (
|
|
7118
|
+
if (isImperativeWorkflowFile(_path, state.filename)) {
|
|
7119
|
+
extractImperativeWorkflow(_path, state);
|
|
7120
|
+
state.__isModelFile = true;
|
|
7121
|
+
if (!compilerState.metadata.category) {
|
|
7122
|
+
compilerState.metadata.category = "workflow";
|
|
7123
|
+
}
|
|
7124
|
+
} else if (isModelFile(_path, state.filename)) {
|
|
4597
7125
|
extractModelFile(_path, state);
|
|
4598
7126
|
state.__isModelFile = true;
|
|
4599
7127
|
if (!compilerState.metadata.category) {
|
|
@@ -4604,6 +7132,15 @@ function createVisitor(options = {}) {
|
|
|
4604
7132
|
if (hasContextCreation(_path)) {
|
|
4605
7133
|
extractContextWorkflows(_path, state);
|
|
4606
7134
|
}
|
|
7135
|
+
if (hasMiddleware(_path)) {
|
|
7136
|
+
extractMiddleware(_path, state);
|
|
7137
|
+
}
|
|
7138
|
+
if (hasConstraints(_path)) {
|
|
7139
|
+
extractConstraints(_path, state);
|
|
7140
|
+
}
|
|
7141
|
+
if (hasActorConfig(_path)) {
|
|
7142
|
+
extractActorConfig(_path, state);
|
|
7143
|
+
}
|
|
4607
7144
|
if (isServerActionFile(state.filename)) {
|
|
4608
7145
|
extractServerActions(_path, state);
|
|
4609
7146
|
state.__isServerActionFile = true;
|
|
@@ -4639,13 +7176,13 @@ function createVisitor(options = {}) {
|
|
|
4639
7176
|
// Main hook extraction dispatcher
|
|
4640
7177
|
CallExpression(path, state) {
|
|
4641
7178
|
const callee = path.node.callee;
|
|
4642
|
-
if (!
|
|
7179
|
+
if (!t21.isIdentifier(callee)) return;
|
|
4643
7180
|
const compilerState = state;
|
|
4644
7181
|
const hookName = callee.name;
|
|
4645
7182
|
if (mode === "strict" && STRICT_BANNED_HOOKS[hookName]) {
|
|
4646
7183
|
const error = {
|
|
4647
7184
|
code: STRICT_BANNED_HOOKS[hookName],
|
|
4648
|
-
message: `${hookName}() is not allowed in strict mode. Use @
|
|
7185
|
+
message: `${hookName}() is not allowed in strict mode. Use @mmapp/react effect hooks instead.`,
|
|
4649
7186
|
line: path.node.loc?.start.line,
|
|
4650
7187
|
column: path.node.loc?.start.column,
|
|
4651
7188
|
severity: "error"
|
|
@@ -4731,18 +7268,18 @@ function createVisitor(options = {}) {
|
|
|
4731
7268
|
if (!meta.__modelImports) meta.__modelImports = {};
|
|
4732
7269
|
const imports = meta.__modelImports;
|
|
4733
7270
|
for (const specifier of path.node.specifiers) {
|
|
4734
|
-
if (
|
|
7271
|
+
if (t21.isImportDefaultSpecifier(specifier) || t21.isImportSpecifier(specifier)) {
|
|
4735
7272
|
imports[specifier.local.name] = source;
|
|
4736
7273
|
}
|
|
4737
7274
|
}
|
|
4738
7275
|
}
|
|
4739
7276
|
if (mode !== "strict") return;
|
|
4740
|
-
if (source.startsWith("@
|
|
7277
|
+
if (source.startsWith("@mmapp/") || source.startsWith("@mmapp/") || source === "react" || source.startsWith("react/") || source.startsWith(".") || source.startsWith("/")) {
|
|
4741
7278
|
return;
|
|
4742
7279
|
}
|
|
4743
7280
|
const error = {
|
|
4744
7281
|
code: "STRICT_FORBIDDEN_IMPORT",
|
|
4745
|
-
message: `Import from '${source}' is not allowed in strict mode. Only @
|
|
7282
|
+
message: `Import from '${source}' is not allowed in strict mode. Only @mmapp/* and relative imports are permitted.`,
|
|
4746
7283
|
line: path.node.loc?.start.line,
|
|
4747
7284
|
column: path.node.loc?.start.column,
|
|
4748
7285
|
severity: "error"
|
|
@@ -4764,8 +7301,8 @@ function createVisitor(options = {}) {
|
|
|
4764
7301
|
if (!compilerState.metadata) return;
|
|
4765
7302
|
const id = path.node.id;
|
|
4766
7303
|
const init = path.node.init;
|
|
4767
|
-
if (
|
|
4768
|
-
if (!
|
|
7304
|
+
if (t21.isArrayPattern(id)) return;
|
|
7305
|
+
if (!t21.isIdentifier(id) || !init || !t21.isExpression(init)) return;
|
|
4769
7306
|
const parentFn = path.getFunctionParent();
|
|
4770
7307
|
if (!parentFn) return;
|
|
4771
7308
|
const parentNode = parentFn.parentPath;
|
|
@@ -4773,17 +7310,17 @@ function createVisitor(options = {}) {
|
|
|
4773
7310
|
let isExportedByName = false;
|
|
4774
7311
|
if (!isExportedDirectly && parentNode?.isVariableDeclarator()) {
|
|
4775
7312
|
const varId = parentNode.node.id;
|
|
4776
|
-
if (
|
|
7313
|
+
if (t21.isIdentifier(varId)) {
|
|
4777
7314
|
isExportedByName = varId.name === compilerState.metadata?.name;
|
|
4778
7315
|
}
|
|
4779
7316
|
}
|
|
4780
7317
|
if (!isExportedDirectly && !isExportedByName) return;
|
|
4781
|
-
if (
|
|
7318
|
+
if (t21.isCallExpression(init) && t21.isIdentifier(init.callee)) {
|
|
4782
7319
|
const callee = init.callee.name;
|
|
4783
7320
|
if (callee === "useQuery") {
|
|
4784
|
-
registerDerivedVar(id.name,
|
|
4785
|
-
|
|
4786
|
-
|
|
7321
|
+
registerDerivedVar(id.name, t21.optionalMemberExpression(
|
|
7322
|
+
t21.identifier("$instance"),
|
|
7323
|
+
t21.identifier(id.name),
|
|
4787
7324
|
false,
|
|
4788
7325
|
// computed
|
|
4789
7326
|
true
|
|
@@ -4792,23 +7329,23 @@ function createVisitor(options = {}) {
|
|
|
4792
7329
|
return;
|
|
4793
7330
|
}
|
|
4794
7331
|
if (callee === "useMutation") {
|
|
4795
|
-
registerDerivedVar(id.name,
|
|
4796
|
-
|
|
4797
|
-
|
|
7332
|
+
registerDerivedVar(id.name, t21.memberExpression(
|
|
7333
|
+
t21.identifier("$action"),
|
|
7334
|
+
t21.identifier("transition")
|
|
4798
7335
|
));
|
|
4799
7336
|
return;
|
|
4800
7337
|
}
|
|
4801
7338
|
if (callee === "useServerAction") {
|
|
4802
|
-
registerDerivedVar(id.name,
|
|
4803
|
-
|
|
4804
|
-
|
|
7339
|
+
registerDerivedVar(id.name, t21.memberExpression(
|
|
7340
|
+
t21.identifier("$action"),
|
|
7341
|
+
t21.identifier("serverAction")
|
|
4805
7342
|
));
|
|
4806
7343
|
return;
|
|
4807
7344
|
}
|
|
4808
7345
|
if (callee === "useServerState") {
|
|
4809
|
-
registerDerivedVar(id.name,
|
|
4810
|
-
|
|
4811
|
-
|
|
7346
|
+
registerDerivedVar(id.name, t21.optionalMemberExpression(
|
|
7347
|
+
t21.identifier("$instance"),
|
|
7348
|
+
t21.identifier("serverState"),
|
|
4812
7349
|
false,
|
|
4813
7350
|
true
|
|
4814
7351
|
));
|
|
@@ -4816,12 +7353,12 @@ function createVisitor(options = {}) {
|
|
|
4816
7353
|
}
|
|
4817
7354
|
if (callee === "useMemo" && init.arguments.length >= 1) {
|
|
4818
7355
|
const callback = init.arguments[0];
|
|
4819
|
-
if (
|
|
4820
|
-
if (
|
|
7356
|
+
if (t21.isArrowFunctionExpression(callback)) {
|
|
7357
|
+
if (t21.isExpression(callback.body)) {
|
|
4821
7358
|
registerDerivedVar(id.name, callback.body);
|
|
4822
|
-
} else if (
|
|
4823
|
-
const retStmt = callback.body.body.find((s) =>
|
|
4824
|
-
if (retStmt?.argument &&
|
|
7359
|
+
} else if (t21.isBlockStatement(callback.body)) {
|
|
7360
|
+
const retStmt = callback.body.body.find((s) => t21.isReturnStatement(s));
|
|
7361
|
+
if (retStmt?.argument && t21.isExpression(retStmt.argument)) {
|
|
4825
7362
|
registerDerivedVar(id.name, retStmt.argument);
|
|
4826
7363
|
}
|
|
4827
7364
|
}
|
|
@@ -4836,7 +7373,7 @@ function createVisitor(options = {}) {
|
|
|
4836
7373
|
// Only extract from the exported component function's direct return,
|
|
4837
7374
|
// not from nested callbacks (Each render functions, helper components, etc.).
|
|
4838
7375
|
ReturnStatement(path, state) {
|
|
4839
|
-
if (!
|
|
7376
|
+
if (!t21.isJSXElement(path.node.argument) && !t21.isJSXFragment(path.node.argument)) return;
|
|
4840
7377
|
const parentFn = path.getFunctionParent();
|
|
4841
7378
|
if (!parentFn) return;
|
|
4842
7379
|
const parentNode = parentFn.parentPath;
|
|
@@ -4844,7 +7381,7 @@ function createVisitor(options = {}) {
|
|
|
4844
7381
|
let isExportedByName = false;
|
|
4845
7382
|
if (!isExportedDirectly && parentNode?.isVariableDeclarator()) {
|
|
4846
7383
|
const varId = parentNode.node.id;
|
|
4847
|
-
if (
|
|
7384
|
+
if (t21.isIdentifier(varId)) {
|
|
4848
7385
|
isExportedByName = varId.name === state.metadata?.name;
|
|
4849
7386
|
}
|
|
4850
7387
|
}
|
|
@@ -4991,11 +7528,11 @@ function irToSnapshot(ir) {
|
|
|
4991
7528
|
enterActions: s.on_enter?.length ?? 0,
|
|
4992
7529
|
exitActions: s.on_exit?.length ?? 0
|
|
4993
7530
|
})),
|
|
4994
|
-
transitions: ir.transitions.map((
|
|
4995
|
-
name:
|
|
4996
|
-
from:
|
|
4997
|
-
to:
|
|
4998
|
-
conditions:
|
|
7531
|
+
transitions: ir.transitions.map((t22) => ({
|
|
7532
|
+
name: t22.name,
|
|
7533
|
+
from: t22.from,
|
|
7534
|
+
to: t22.to,
|
|
7535
|
+
conditions: t22.conditions?.length ?? 0
|
|
4999
7536
|
})),
|
|
5000
7537
|
hasExperience: !!meta.experience || !!ir.experience,
|
|
5001
7538
|
extensionTags: ir.extensions ? Object.keys(ir.extensions) : [],
|
|
@@ -5062,7 +7599,7 @@ function installIRMatchers() {
|
|
|
5062
7599
|
if (expected.transitions !== void 0 && Array.isArray(expected.transitions)) {
|
|
5063
7600
|
const expectedTransitions = expected.transitions;
|
|
5064
7601
|
for (const exp of expectedTransitions) {
|
|
5065
|
-
const match = received.transitions.find((
|
|
7602
|
+
const match = received.transitions.find((t22) => t22.name === exp.name);
|
|
5066
7603
|
if (!match) {
|
|
5067
7604
|
failures.push(`transitions: expected transition "${exp.name}" not found`);
|
|
5068
7605
|
} else {
|