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