@mmapp/react-compiler 0.1.0-alpha.3 → 0.1.0-alpha.5
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/dist/babel/index.js +2733 -303
- package/dist/babel/index.mjs +1 -1
- package/dist/chunk-52XHYD2V.mjs +214 -0
- package/dist/chunk-5GUFFFGL.mjs +148 -0
- package/dist/chunk-EO6SYNCG.mjs +175 -0
- package/dist/chunk-J7JUAHS4.mjs +186 -0
- package/dist/chunk-NTB7OEX2.mjs +2918 -0
- package/dist/chunk-OPJKP747.mjs +7506 -0
- package/dist/chunk-THFYE5ZX.mjs +244 -0
- package/dist/chunk-WBYMW4NQ.mjs +3450 -0
- package/dist/cli/index.js +13001 -7900
- package/dist/cli/index.mjs +139 -21
- package/dist/config-PL24KEWL.mjs +219 -0
- package/dist/dev-server.js +3122 -356
- package/dist/dev-server.mjs +4 -4
- package/dist/envelope.js +2731 -301
- package/dist/envelope.mjs +2 -2
- package/dist/index.d.mts +156 -1
- package/dist/index.d.ts +156 -1
- package/dist/index.js +3643 -571
- package/dist/index.mjs +216 -8
- package/dist/init-DQDX3QK6.mjs +369 -0
- package/dist/project-compiler-OP2VVGJQ.mjs +10 -0
- package/dist/project-decompiler-US7GAVIC.mjs +7 -0
- package/dist/pull-P44LDRWB.mjs +109 -0
- package/dist/testing/index.js +2741 -311
- package/dist/testing/index.mjs +1 -1
- package/dist/verify-SEIXUGN4.mjs +1833 -0
- package/dist/vite/index.js +2732 -302
- package/dist/vite/index.mjs +2 -2
- package/package.json +14 -5
package/dist/dev-server.js
CHANGED
|
@@ -445,25 +445,25 @@ function inferTransitionStates(transitions, states) {
|
|
|
445
445
|
const stateArray = Array.from(states.values());
|
|
446
446
|
const startStates = stateArray.filter((s) => s.type === "START");
|
|
447
447
|
const regularStates = stateArray.filter((s) => s.type === "REGULAR");
|
|
448
|
-
const needsInference = transitions.filter((
|
|
448
|
+
const needsInference = transitions.filter((t23) => t23.from.length === 0 || !t23.to);
|
|
449
449
|
if (needsInference.length === 0) return;
|
|
450
450
|
if (startStates.length === 1 && regularStates.length > 0) {
|
|
451
|
-
needsInference.forEach((
|
|
452
|
-
if (
|
|
453
|
-
|
|
451
|
+
needsInference.forEach((t23, idx) => {
|
|
452
|
+
if (t23.from.length === 0) {
|
|
453
|
+
t23.from = [startStates[0].name];
|
|
454
454
|
}
|
|
455
|
-
if (!
|
|
456
|
-
|
|
455
|
+
if (!t23.to) {
|
|
456
|
+
t23.to = regularStates[idx % regularStates.length]?.name || startStates[0].name;
|
|
457
457
|
}
|
|
458
458
|
});
|
|
459
459
|
} else {
|
|
460
460
|
const allStateNames = stateArray.map((s) => s.name);
|
|
461
|
-
needsInference.forEach((
|
|
462
|
-
if (
|
|
463
|
-
|
|
461
|
+
needsInference.forEach((t23, idx) => {
|
|
462
|
+
if (t23.from.length === 0 && allStateNames.length > 0) {
|
|
463
|
+
t23.from = [allStateNames[0]];
|
|
464
464
|
}
|
|
465
|
-
if (!
|
|
466
|
-
|
|
465
|
+
if (!t23.to && allStateNames.length > 1) {
|
|
466
|
+
t23.to = allStateNames[Math.min(idx + 1, allStateNames.length - 1)];
|
|
467
467
|
}
|
|
468
468
|
});
|
|
469
469
|
}
|
|
@@ -2551,7 +2551,7 @@ function resolveType(annotation) {
|
|
|
2551
2551
|
}
|
|
2552
2552
|
if (t11.isTSUnionType(annotation)) {
|
|
2553
2553
|
const allLiterals = annotation.types.every(
|
|
2554
|
-
(
|
|
2554
|
+
(t23) => t11.isTSLiteralType(t23) && (t11.isStringLiteral(t23.literal) || t11.isNumericLiteral(t23.literal))
|
|
2555
2555
|
);
|
|
2556
2556
|
if (allLiterals) return "select";
|
|
2557
2557
|
return "text";
|
|
@@ -3033,6 +3033,7 @@ function extractDefineModelCall(programPath, compilerState, actionCounter) {
|
|
|
3033
3033
|
const on_exit = parseActionArray(stateConfig.on_exit, actionCounter);
|
|
3034
3034
|
const during = parseDuringArray(stateConfig.during, actionCounter);
|
|
3035
3035
|
const on_event = parseOnEventArray(stateConfig.on_event, actionCounter);
|
|
3036
|
+
const stateRuntime = stateConfig.runtime;
|
|
3036
3037
|
if (!compilerState.states.has(name)) {
|
|
3037
3038
|
compilerState.states.set(name, {
|
|
3038
3039
|
name,
|
|
@@ -3041,7 +3042,8 @@ function extractDefineModelCall(programPath, compilerState, actionCounter) {
|
|
|
3041
3042
|
on_enter,
|
|
3042
3043
|
during,
|
|
3043
3044
|
on_exit,
|
|
3044
|
-
...on_event.length > 0 ? { on_event } : {}
|
|
3045
|
+
...on_event.length > 0 ? { on_event } : {},
|
|
3046
|
+
...stateRuntime ? { runtime: stateRuntime } : {}
|
|
3045
3047
|
});
|
|
3046
3048
|
} else {
|
|
3047
3049
|
const existing = compilerState.states.get(name);
|
|
@@ -3095,6 +3097,7 @@ function extractDefineModelCall(programPath, compilerState, actionCounter) {
|
|
|
3095
3097
|
}
|
|
3096
3098
|
}
|
|
3097
3099
|
const actions = parseActionArray(transConfig.actions, actionCounter);
|
|
3100
|
+
const transRuntime = transConfig.runtime;
|
|
3098
3101
|
compilerState.transitions.push({
|
|
3099
3102
|
name,
|
|
3100
3103
|
from,
|
|
@@ -3104,7 +3107,8 @@ function extractDefineModelCall(programPath, compilerState, actionCounter) {
|
|
|
3104
3107
|
actions,
|
|
3105
3108
|
roles: transConfig.roles,
|
|
3106
3109
|
auto: transConfig.auto,
|
|
3107
|
-
required_fields: transConfig.required_fields
|
|
3110
|
+
required_fields: transConfig.required_fields,
|
|
3111
|
+
...transRuntime ? { runtime: transRuntime } : {}
|
|
3108
3112
|
});
|
|
3109
3113
|
}
|
|
3110
3114
|
}
|
|
@@ -3121,6 +3125,9 @@ function extractDefineModelCall(programPath, compilerState, actionCounter) {
|
|
|
3121
3125
|
if (config.metadata && typeof config.metadata === "object") {
|
|
3122
3126
|
compilerState.metadata.modelMetadata = config.metadata;
|
|
3123
3127
|
}
|
|
3128
|
+
if (config.orchestration && typeof config.orchestration === "object" && !Array.isArray(config.orchestration)) {
|
|
3129
|
+
compilerState.metadata.orchestration = config.orchestration;
|
|
3130
|
+
}
|
|
3124
3131
|
return true;
|
|
3125
3132
|
}
|
|
3126
3133
|
return false;
|
|
@@ -3309,6 +3316,1873 @@ var init_model_extractor = __esm({
|
|
|
3309
3316
|
}
|
|
3310
3317
|
});
|
|
3311
3318
|
|
|
3319
|
+
// src/babel/extractors/workflow-shorthand.ts
|
|
3320
|
+
function makeState(name, type) {
|
|
3321
|
+
return {
|
|
3322
|
+
name,
|
|
3323
|
+
type,
|
|
3324
|
+
on_enter: [],
|
|
3325
|
+
during: [],
|
|
3326
|
+
on_exit: []
|
|
3327
|
+
};
|
|
3328
|
+
}
|
|
3329
|
+
function makeTransition(name, from, to) {
|
|
3330
|
+
return {
|
|
3331
|
+
name,
|
|
3332
|
+
from: [from],
|
|
3333
|
+
to,
|
|
3334
|
+
actions: []
|
|
3335
|
+
};
|
|
3336
|
+
}
|
|
3337
|
+
function dedupeTransitions(ts) {
|
|
3338
|
+
const seen = /* @__PURE__ */ new Set();
|
|
3339
|
+
const out = [];
|
|
3340
|
+
for (const t23 of ts) {
|
|
3341
|
+
const key = `${t23.name}::${t23.from.join(",")}::${t23.to}`;
|
|
3342
|
+
if (!seen.has(key)) {
|
|
3343
|
+
seen.add(key);
|
|
3344
|
+
out.push(t23);
|
|
3345
|
+
}
|
|
3346
|
+
}
|
|
3347
|
+
return out;
|
|
3348
|
+
}
|
|
3349
|
+
function tokenize(line) {
|
|
3350
|
+
const tokens = [];
|
|
3351
|
+
let m;
|
|
3352
|
+
TOKEN_RE.lastIndex = 0;
|
|
3353
|
+
while ((m = TOKEN_RE.exec(line)) !== null) {
|
|
3354
|
+
if (m[1]) {
|
|
3355
|
+
tokens.push({ kind: "arrow", direction: "bidirectional" });
|
|
3356
|
+
} else if (m[2]) {
|
|
3357
|
+
tokens.push({ kind: "arrow", direction: "backward", name: m[2] });
|
|
3358
|
+
} else if (m[3]) {
|
|
3359
|
+
tokens.push({ kind: "arrow", direction: "backward" });
|
|
3360
|
+
} else if (m[4]) {
|
|
3361
|
+
tokens.push({ kind: "arrow", direction: "forward", name: m[4] });
|
|
3362
|
+
} else if (m[5]) {
|
|
3363
|
+
tokens.push({ kind: "arrow", direction: "forward" });
|
|
3364
|
+
} else if (m[6]) {
|
|
3365
|
+
tokens.push({ kind: "branch" });
|
|
3366
|
+
} else if (m[7]) {
|
|
3367
|
+
tokens.push({ kind: "state", name: m[7] });
|
|
3368
|
+
}
|
|
3369
|
+
}
|
|
3370
|
+
return tokens;
|
|
3371
|
+
}
|
|
3372
|
+
function parseTokens(tokens, stateMap, transitions, outgoingCounts) {
|
|
3373
|
+
let lastState = null;
|
|
3374
|
+
for (let i = 0; i < tokens.length; i++) {
|
|
3375
|
+
const tok = tokens[i];
|
|
3376
|
+
if (tok.kind === "state") {
|
|
3377
|
+
stateMap.set(tok.name, stateMap.has(tok.name) ? stateMap.get(tok.name) : true);
|
|
3378
|
+
lastState = tok.name;
|
|
3379
|
+
continue;
|
|
3380
|
+
}
|
|
3381
|
+
if (tok.kind === "branch") {
|
|
3382
|
+
continue;
|
|
3383
|
+
}
|
|
3384
|
+
if (tok.kind === "arrow") {
|
|
3385
|
+
let nextIdx = i + 1;
|
|
3386
|
+
const targets = [];
|
|
3387
|
+
while (nextIdx < tokens.length) {
|
|
3388
|
+
const next = tokens[nextIdx];
|
|
3389
|
+
if (next.kind === "state") {
|
|
3390
|
+
targets.push(next.name);
|
|
3391
|
+
stateMap.set(next.name, stateMap.has(next.name) ? stateMap.get(next.name) : true);
|
|
3392
|
+
nextIdx++;
|
|
3393
|
+
if (nextIdx < tokens.length && tokens[nextIdx].kind === "branch") {
|
|
3394
|
+
nextIdx++;
|
|
3395
|
+
continue;
|
|
3396
|
+
}
|
|
3397
|
+
break;
|
|
3398
|
+
} else {
|
|
3399
|
+
nextIdx++;
|
|
3400
|
+
}
|
|
3401
|
+
}
|
|
3402
|
+
if (lastState && targets.length > 0) {
|
|
3403
|
+
for (const target of targets) {
|
|
3404
|
+
if (tok.direction === "forward" || tok.direction === "bidirectional") {
|
|
3405
|
+
const name = tok.name || `to_${target}`;
|
|
3406
|
+
transitions.push(makeTransition(name, lastState, target));
|
|
3407
|
+
outgoingCounts.set(lastState, (outgoingCounts.get(lastState) || 0) + 1);
|
|
3408
|
+
}
|
|
3409
|
+
if (tok.direction === "backward" || tok.direction === "bidirectional") {
|
|
3410
|
+
const name = tok.name || `to_${lastState}`;
|
|
3411
|
+
transitions.push(makeTransition(name, target, lastState));
|
|
3412
|
+
outgoingCounts.set(target, (outgoingCounts.get(target) || 0) + 1);
|
|
3413
|
+
}
|
|
3414
|
+
}
|
|
3415
|
+
lastState = targets[targets.length > 1 ? 0 : 0];
|
|
3416
|
+
if (targets.length === 1) {
|
|
3417
|
+
lastState = targets[0];
|
|
3418
|
+
}
|
|
3419
|
+
i = nextIdx - 1;
|
|
3420
|
+
}
|
|
3421
|
+
}
|
|
3422
|
+
}
|
|
3423
|
+
}
|
|
3424
|
+
function parseMultiLine(lines) {
|
|
3425
|
+
const allStateNames = [];
|
|
3426
|
+
const allTransitions = [];
|
|
3427
|
+
const stateMap = /* @__PURE__ */ new Map();
|
|
3428
|
+
const outgoingCounts = /* @__PURE__ */ new Map();
|
|
3429
|
+
for (const line of lines) {
|
|
3430
|
+
const trimmed = line.trim();
|
|
3431
|
+
if (!trimmed) continue;
|
|
3432
|
+
const tokens = tokenize(trimmed);
|
|
3433
|
+
const hasStates = tokens.some((t23) => t23.kind === "state");
|
|
3434
|
+
const hasForwardArrows = tokens.some(
|
|
3435
|
+
(t23) => t23.kind === "arrow" && (t23.direction === "forward" || t23.direction === "bidirectional")
|
|
3436
|
+
);
|
|
3437
|
+
if (hasStates && hasForwardArrows) {
|
|
3438
|
+
for (const tok of tokens) {
|
|
3439
|
+
if (tok.kind === "state" && !allStateNames.includes(tok.name)) {
|
|
3440
|
+
allStateNames.push(tok.name);
|
|
3441
|
+
}
|
|
3442
|
+
}
|
|
3443
|
+
parseTokens(tokens, stateMap, allTransitions, outgoingCounts);
|
|
3444
|
+
} else if (!hasStates && tokens.some((t23) => t23.kind === "arrow")) {
|
|
3445
|
+
let arrowIndex = 0;
|
|
3446
|
+
for (const tok of tokens) {
|
|
3447
|
+
if (tok.kind === "arrow") {
|
|
3448
|
+
if (arrowIndex < allStateNames.length - 1) {
|
|
3449
|
+
const left = allStateNames[arrowIndex];
|
|
3450
|
+
const right = allStateNames[arrowIndex + 1];
|
|
3451
|
+
if (tok.direction === "backward" || tok.direction === "bidirectional") {
|
|
3452
|
+
const name = tok.name || `to_${left}`;
|
|
3453
|
+
allTransitions.push(makeTransition(name, right, left));
|
|
3454
|
+
outgoingCounts.set(right, (outgoingCounts.get(right) || 0) + 1);
|
|
3455
|
+
}
|
|
3456
|
+
if (tok.direction === "forward" || tok.direction === "bidirectional") {
|
|
3457
|
+
const name = tok.name || `to_${right}`;
|
|
3458
|
+
allTransitions.push(makeTransition(name, left, right));
|
|
3459
|
+
outgoingCounts.set(left, (outgoingCounts.get(left) || 0) + 1);
|
|
3460
|
+
}
|
|
3461
|
+
}
|
|
3462
|
+
arrowIndex++;
|
|
3463
|
+
}
|
|
3464
|
+
}
|
|
3465
|
+
} else if (hasStates) {
|
|
3466
|
+
parseTokens(tokens, stateMap, allTransitions, outgoingCounts);
|
|
3467
|
+
for (const tok of tokens) {
|
|
3468
|
+
if (tok.kind === "state" && !allStateNames.includes(tok.name)) {
|
|
3469
|
+
allStateNames.push(tok.name);
|
|
3470
|
+
}
|
|
3471
|
+
}
|
|
3472
|
+
}
|
|
3473
|
+
}
|
|
3474
|
+
return { stateNames: allStateNames, transitions: dedupeTransitions(allTransitions) };
|
|
3475
|
+
}
|
|
3476
|
+
function parseArrowSyntax(arrow) {
|
|
3477
|
+
const lines = arrow.split("\n");
|
|
3478
|
+
const { stateNames, transitions } = parseMultiLine(lines);
|
|
3479
|
+
if (stateNames.length === 0) {
|
|
3480
|
+
return { states: [], transitions: [] };
|
|
3481
|
+
}
|
|
3482
|
+
const hasOutgoing = /* @__PURE__ */ new Set();
|
|
3483
|
+
for (const t23 of transitions) {
|
|
3484
|
+
for (const from of t23.from) {
|
|
3485
|
+
hasOutgoing.add(from);
|
|
3486
|
+
}
|
|
3487
|
+
}
|
|
3488
|
+
const states = stateNames.map((name, idx) => {
|
|
3489
|
+
let type = "REGULAR";
|
|
3490
|
+
if (idx === 0) {
|
|
3491
|
+
type = "START";
|
|
3492
|
+
} else if (!hasOutgoing.has(name)) {
|
|
3493
|
+
type = "END";
|
|
3494
|
+
}
|
|
3495
|
+
return makeState(name, type);
|
|
3496
|
+
});
|
|
3497
|
+
return { states, transitions };
|
|
3498
|
+
}
|
|
3499
|
+
function parseFieldRecord(fields) {
|
|
3500
|
+
return Object.entries(fields).map(([name, typeStr]) => {
|
|
3501
|
+
let required = false;
|
|
3502
|
+
let raw = typeStr.trim();
|
|
3503
|
+
if (raw.endsWith("!")) {
|
|
3504
|
+
required = true;
|
|
3505
|
+
raw = raw.slice(0, -1).trim();
|
|
3506
|
+
}
|
|
3507
|
+
let defaultValue;
|
|
3508
|
+
const eqIdx = raw.indexOf("=");
|
|
3509
|
+
let typePart = raw;
|
|
3510
|
+
if (eqIdx !== -1) {
|
|
3511
|
+
typePart = raw.slice(0, eqIdx).trim();
|
|
3512
|
+
const valStr = raw.slice(eqIdx + 1).trim();
|
|
3513
|
+
try {
|
|
3514
|
+
defaultValue = JSON.parse(valStr);
|
|
3515
|
+
} catch {
|
|
3516
|
+
defaultValue = valStr;
|
|
3517
|
+
}
|
|
3518
|
+
}
|
|
3519
|
+
const TYPE_MAP = {
|
|
3520
|
+
string: "text",
|
|
3521
|
+
str: "text",
|
|
3522
|
+
text: "text",
|
|
3523
|
+
number: "number",
|
|
3524
|
+
num: "number",
|
|
3525
|
+
int: "number",
|
|
3526
|
+
integer: "number",
|
|
3527
|
+
float: "number",
|
|
3528
|
+
bool: "boolean",
|
|
3529
|
+
boolean: "boolean",
|
|
3530
|
+
date: "date",
|
|
3531
|
+
datetime: "datetime",
|
|
3532
|
+
email: "email",
|
|
3533
|
+
url: "url",
|
|
3534
|
+
json: "json",
|
|
3535
|
+
object: "json",
|
|
3536
|
+
array: "json",
|
|
3537
|
+
select: "select",
|
|
3538
|
+
enum: "select",
|
|
3539
|
+
file: "file",
|
|
3540
|
+
image: "image",
|
|
3541
|
+
currency: "currency",
|
|
3542
|
+
phone: "phone",
|
|
3543
|
+
address: "address",
|
|
3544
|
+
rich_text: "rich_text",
|
|
3545
|
+
richtext: "rich_text",
|
|
3546
|
+
color: "color",
|
|
3547
|
+
rating: "rating"
|
|
3548
|
+
};
|
|
3549
|
+
const fieldType = TYPE_MAP[typePart.toLowerCase()] || typePart;
|
|
3550
|
+
const field = {
|
|
3551
|
+
name,
|
|
3552
|
+
type: fieldType
|
|
3553
|
+
};
|
|
3554
|
+
if (required) field.required = true;
|
|
3555
|
+
if (defaultValue !== void 0) field.default_value = defaultValue;
|
|
3556
|
+
return field;
|
|
3557
|
+
});
|
|
3558
|
+
}
|
|
3559
|
+
function parseWorkflowShorthand(slug, fieldsOrArrow, arrowString) {
|
|
3560
|
+
let fields = [];
|
|
3561
|
+
let arrow;
|
|
3562
|
+
if (typeof fieldsOrArrow === "string") {
|
|
3563
|
+
arrow = fieldsOrArrow;
|
|
3564
|
+
} else {
|
|
3565
|
+
fields = parseFieldRecord(fieldsOrArrow);
|
|
3566
|
+
arrow = arrowString || "";
|
|
3567
|
+
}
|
|
3568
|
+
const { states, transitions } = parseArrowSyntax(arrow);
|
|
3569
|
+
return { slug, fields, states, transitions };
|
|
3570
|
+
}
|
|
3571
|
+
var TOKEN_RE;
|
|
3572
|
+
var init_workflow_shorthand = __esm({
|
|
3573
|
+
"src/babel/extractors/workflow-shorthand.ts"() {
|
|
3574
|
+
"use strict";
|
|
3575
|
+
TOKEN_RE = /(<->)|<-(\w+)-|(<-)|(?:-(\w+)->)|(->)|(\|)|([a-zA-Z_]\w*)/g;
|
|
3576
|
+
}
|
|
3577
|
+
});
|
|
3578
|
+
|
|
3579
|
+
// src/babel/extractors/flow-extractor.ts
|
|
3580
|
+
function isImperativeWorkflowFile(path, _filename) {
|
|
3581
|
+
for (const node of path.node.body) {
|
|
3582
|
+
if (t12.isExportDefaultDeclaration(node)) {
|
|
3583
|
+
const decl = node.declaration;
|
|
3584
|
+
if (t12.isFunctionDeclaration(decl) && decl.async && decl.params.length > 0) {
|
|
3585
|
+
const param = decl.params[0];
|
|
3586
|
+
if (t12.isIdentifier(param) && param.typeAnnotation) {
|
|
3587
|
+
return true;
|
|
3588
|
+
}
|
|
3589
|
+
}
|
|
3590
|
+
if (t12.isCallExpression(decl) && t12.isIdentifier(decl.callee) && decl.callee.name === "workflow") {
|
|
3591
|
+
return true;
|
|
3592
|
+
}
|
|
3593
|
+
}
|
|
3594
|
+
}
|
|
3595
|
+
return false;
|
|
3596
|
+
}
|
|
3597
|
+
function roleCondition(role) {
|
|
3598
|
+
return { type: "role", field: role, operator: "eq", value: true };
|
|
3599
|
+
}
|
|
3600
|
+
function resolveType2(annotation) {
|
|
3601
|
+
if (t12.isTSStringKeyword(annotation)) return "text";
|
|
3602
|
+
if (t12.isTSNumberKeyword(annotation)) return "number";
|
|
3603
|
+
if (t12.isTSBooleanKeyword(annotation)) return "boolean";
|
|
3604
|
+
if (t12.isTSTypeReference(annotation) && t12.isIdentifier(annotation.typeName)) {
|
|
3605
|
+
const name = annotation.typeName.name;
|
|
3606
|
+
if (TS_TYPE_MAP[name]) return TS_TYPE_MAP[name];
|
|
3607
|
+
if (name === "Array") return "multi_select";
|
|
3608
|
+
return name.replace(/([A-Z])/g, "-$1").toLowerCase().replace(/^-/, "");
|
|
3609
|
+
}
|
|
3610
|
+
if (t12.isTSArrayType(annotation)) return "multi_select";
|
|
3611
|
+
if (t12.isTSUnionType(annotation)) {
|
|
3612
|
+
const allLiterals = annotation.types.every(
|
|
3613
|
+
(t23) => t12.isTSLiteralType(t23) && (t12.isStringLiteral(t23.literal) || t12.isNumericLiteral(t23.literal))
|
|
3614
|
+
);
|
|
3615
|
+
if (allLiterals) return "select";
|
|
3616
|
+
return "text";
|
|
3617
|
+
}
|
|
3618
|
+
if (t12.isTSLiteralType(annotation) && t12.isStringLiteral(annotation.literal)) return "text";
|
|
3619
|
+
if (t12.isTSLiteralType(annotation) && t12.isNumericLiteral(annotation.literal)) return "number";
|
|
3620
|
+
return "text";
|
|
3621
|
+
}
|
|
3622
|
+
function extractUnionOptions2(annotation) {
|
|
3623
|
+
if (!t12.isTSUnionType(annotation)) return void 0;
|
|
3624
|
+
const options = [];
|
|
3625
|
+
for (const member of annotation.types) {
|
|
3626
|
+
if (t12.isTSLiteralType(member) && t12.isStringLiteral(member.literal)) {
|
|
3627
|
+
options.push(member.literal.value);
|
|
3628
|
+
}
|
|
3629
|
+
}
|
|
3630
|
+
return options.length > 0 ? options : void 0;
|
|
3631
|
+
}
|
|
3632
|
+
function extractFieldsFromInterface2(declaration) {
|
|
3633
|
+
const fields = [];
|
|
3634
|
+
for (const member of declaration.body.body) {
|
|
3635
|
+
if (!t12.isTSPropertySignature(member)) continue;
|
|
3636
|
+
if (!t12.isIdentifier(member.key)) continue;
|
|
3637
|
+
const name = member.key.name;
|
|
3638
|
+
const required = !member.optional;
|
|
3639
|
+
const typeAnno = member.typeAnnotation;
|
|
3640
|
+
let fieldType = typeAnno ? resolveType2(typeAnno.typeAnnotation) : "text";
|
|
3641
|
+
if (NAME_TYPE_MAP[name]) fieldType = NAME_TYPE_MAP[name];
|
|
3642
|
+
const field = {
|
|
3643
|
+
name,
|
|
3644
|
+
type: fieldType,
|
|
3645
|
+
label: name.replace(/([A-Z])/g, " $1").replace(/^./, (c) => c.toUpperCase()),
|
|
3646
|
+
required,
|
|
3647
|
+
default_value: getDefaultForType(fieldType)
|
|
3648
|
+
};
|
|
3649
|
+
if (typeAnno) {
|
|
3650
|
+
const options = extractUnionOptions2(typeAnno.typeAnnotation);
|
|
3651
|
+
if (options) {
|
|
3652
|
+
field.validation = { options };
|
|
3653
|
+
}
|
|
3654
|
+
}
|
|
3655
|
+
fields.push(field);
|
|
3656
|
+
}
|
|
3657
|
+
return fields;
|
|
3658
|
+
}
|
|
3659
|
+
function getDefaultForType(type) {
|
|
3660
|
+
switch (type) {
|
|
3661
|
+
case "text":
|
|
3662
|
+
case "email":
|
|
3663
|
+
case "url":
|
|
3664
|
+
case "phone":
|
|
3665
|
+
case "select":
|
|
3666
|
+
return "";
|
|
3667
|
+
case "number":
|
|
3668
|
+
case "currency":
|
|
3669
|
+
return 0;
|
|
3670
|
+
case "boolean":
|
|
3671
|
+
return false;
|
|
3672
|
+
case "multi_select":
|
|
3673
|
+
return [];
|
|
3674
|
+
case "json":
|
|
3675
|
+
return {};
|
|
3676
|
+
default:
|
|
3677
|
+
return null;
|
|
3678
|
+
}
|
|
3679
|
+
}
|
|
3680
|
+
function extractNodeValue2(node) {
|
|
3681
|
+
if (t12.isStringLiteral(node)) return node.value;
|
|
3682
|
+
if (t12.isNumericLiteral(node)) return node.value;
|
|
3683
|
+
if (t12.isBooleanLiteral(node)) return node.value;
|
|
3684
|
+
if (t12.isNullLiteral(node)) return null;
|
|
3685
|
+
if (t12.isArrayExpression(node)) {
|
|
3686
|
+
return node.elements.map((el) => {
|
|
3687
|
+
if (!el || t12.isSpreadElement(el)) return null;
|
|
3688
|
+
return extractNodeValue2(el);
|
|
3689
|
+
});
|
|
3690
|
+
}
|
|
3691
|
+
if (t12.isObjectExpression(node)) {
|
|
3692
|
+
const obj = {};
|
|
3693
|
+
for (const prop of node.properties) {
|
|
3694
|
+
if (!t12.isObjectProperty(prop)) continue;
|
|
3695
|
+
const key = t12.isIdentifier(prop.key) ? prop.key.name : t12.isStringLiteral(prop.key) ? prop.key.value : null;
|
|
3696
|
+
if (key) obj[key] = extractNodeValue2(prop.value);
|
|
3697
|
+
}
|
|
3698
|
+
return obj;
|
|
3699
|
+
}
|
|
3700
|
+
if (t12.isTemplateLiteral(node)) {
|
|
3701
|
+
return node.quasis.map((q) => q.value.raw).join("${}");
|
|
3702
|
+
}
|
|
3703
|
+
if (t12.isIdentifier(node)) {
|
|
3704
|
+
if (node.name === "undefined") return void 0;
|
|
3705
|
+
return node.name;
|
|
3706
|
+
}
|
|
3707
|
+
if (t12.isMemberExpression(node)) {
|
|
3708
|
+
return memberExprToString(node);
|
|
3709
|
+
}
|
|
3710
|
+
if (t12.isTSAsExpression(node)) return extractNodeValue2(node.expression);
|
|
3711
|
+
if (t12.isArrowFunctionExpression(node) || t12.isFunctionExpression(node)) {
|
|
3712
|
+
return "[Function]";
|
|
3713
|
+
}
|
|
3714
|
+
return "[Expression]";
|
|
3715
|
+
}
|
|
3716
|
+
function memberExprToString(node) {
|
|
3717
|
+
const obj = t12.isIdentifier(node.object) ? node.object.name : t12.isMemberExpression(node.object) ? memberExprToString(node.object) : "[object]";
|
|
3718
|
+
const prop = t12.isIdentifier(node.property) ? node.property.name : t12.isStringLiteral(node.property) ? node.property.value : "[property]";
|
|
3719
|
+
return `${obj}.${prop}`;
|
|
3720
|
+
}
|
|
3721
|
+
function analyzeStateFn(fn, paramName, actionCounter) {
|
|
3722
|
+
const onEnter = [];
|
|
3723
|
+
const validations = [];
|
|
3724
|
+
const conditions = [];
|
|
3725
|
+
const roles = [];
|
|
3726
|
+
const requiredFields = [];
|
|
3727
|
+
const during = [];
|
|
3728
|
+
const onEvent = [];
|
|
3729
|
+
let timeout;
|
|
3730
|
+
let runtime;
|
|
3731
|
+
if (!fn.body || !t12.isBlockStatement(fn.body)) {
|
|
3732
|
+
return { onEnter, validations, conditions, roles, requiredFields, during, onEvent, timeout, runtime };
|
|
3733
|
+
}
|
|
3734
|
+
for (const stmt of fn.body.body) {
|
|
3735
|
+
processStatement(stmt, paramName, actionCounter, {
|
|
3736
|
+
onEnter,
|
|
3737
|
+
validations,
|
|
3738
|
+
conditions,
|
|
3739
|
+
roles,
|
|
3740
|
+
requiredFields,
|
|
3741
|
+
during,
|
|
3742
|
+
onEvent,
|
|
3743
|
+
setTimeout: (t23) => {
|
|
3744
|
+
timeout = t23;
|
|
3745
|
+
},
|
|
3746
|
+
setRuntime: (r) => {
|
|
3747
|
+
runtime = r;
|
|
3748
|
+
}
|
|
3749
|
+
});
|
|
3750
|
+
}
|
|
3751
|
+
return { onEnter, validations, conditions, roles, requiredFields, during, onEvent, timeout, runtime };
|
|
3752
|
+
}
|
|
3753
|
+
function processStatement(stmt, paramName, actionCounter, ctx) {
|
|
3754
|
+
if (t12.isExpressionStatement(stmt)) {
|
|
3755
|
+
processExpression(stmt.expression, paramName, actionCounter, ctx);
|
|
3756
|
+
return;
|
|
3757
|
+
}
|
|
3758
|
+
if (t12.isIfStatement(stmt)) {
|
|
3759
|
+
const testStr = expressionToIR(stmt.test, paramName);
|
|
3760
|
+
if (t12.isBlockStatement(stmt.consequent)) {
|
|
3761
|
+
for (const inner of stmt.consequent.body) {
|
|
3762
|
+
processStatement(inner, paramName, actionCounter, {
|
|
3763
|
+
...ctx,
|
|
3764
|
+
ifCondition: testStr
|
|
3765
|
+
});
|
|
3766
|
+
}
|
|
3767
|
+
}
|
|
3768
|
+
return;
|
|
3769
|
+
}
|
|
3770
|
+
if (t12.isVariableDeclaration(stmt)) {
|
|
3771
|
+
for (const decl of stmt.declarations) {
|
|
3772
|
+
if (decl.init && t12.isAwaitExpression(decl.init)) {
|
|
3773
|
+
processExpression(decl.init, paramName, actionCounter, ctx);
|
|
3774
|
+
}
|
|
3775
|
+
}
|
|
3776
|
+
}
|
|
3777
|
+
}
|
|
3778
|
+
function processExpression(expr, paramName, actionCounter, ctx) {
|
|
3779
|
+
if (t12.isAssignmentExpression(expr) && t12.isMemberExpression(expr.left)) {
|
|
3780
|
+
const left = memberExprToString(expr.left);
|
|
3781
|
+
if (left.startsWith(`${paramName}.`)) {
|
|
3782
|
+
const field = left.slice(paramName.length + 1);
|
|
3783
|
+
const valueExpr = expressionToIR(expr.right, paramName);
|
|
3784
|
+
const action = {
|
|
3785
|
+
id: `auto_${++actionCounter.value}`,
|
|
3786
|
+
type: "set_field",
|
|
3787
|
+
mode: "auto",
|
|
3788
|
+
config: { field, expression: valueExpr },
|
|
3789
|
+
...ctx.ifCondition ? { condition: ctx.ifCondition } : {}
|
|
3790
|
+
};
|
|
3791
|
+
ctx.onEnter.push(action);
|
|
3792
|
+
return;
|
|
3793
|
+
}
|
|
3794
|
+
}
|
|
3795
|
+
if (t12.isAssignmentExpression(expr) && expr.operator !== "=" && t12.isMemberExpression(expr.left)) {
|
|
3796
|
+
const left = memberExprToString(expr.left);
|
|
3797
|
+
if (left.startsWith(`${paramName}.`)) {
|
|
3798
|
+
const field = left.slice(paramName.length + 1);
|
|
3799
|
+
const op = expr.operator.replace("=", "");
|
|
3800
|
+
const valueExpr = expressionToIR(expr.right, paramName);
|
|
3801
|
+
const action = {
|
|
3802
|
+
id: `auto_${++actionCounter.value}`,
|
|
3803
|
+
type: "set_field",
|
|
3804
|
+
mode: "auto",
|
|
3805
|
+
config: { field, expression: `state_data.${field} ${op} ${valueExpr}` },
|
|
3806
|
+
...ctx.ifCondition ? { condition: ctx.ifCondition } : {}
|
|
3807
|
+
};
|
|
3808
|
+
ctx.onEnter.push(action);
|
|
3809
|
+
return;
|
|
3810
|
+
}
|
|
3811
|
+
}
|
|
3812
|
+
if (t12.isCallExpression(expr) || t12.isAwaitExpression(expr) && t12.isCallExpression(expr.argument)) {
|
|
3813
|
+
const call = t12.isAwaitExpression(expr) ? expr.argument : expr;
|
|
3814
|
+
const fnName = t12.isIdentifier(call.callee) ? call.callee.name : t12.isMemberExpression(call.callee) && t12.isIdentifier(call.callee.property) ? call.callee.property.name : null;
|
|
3815
|
+
if (!fnName) return;
|
|
3816
|
+
if (VALIDATION_FNS.has(fnName)) {
|
|
3817
|
+
extractValidation(call, paramName, ctx);
|
|
3818
|
+
return;
|
|
3819
|
+
}
|
|
3820
|
+
if (fnName === "log") {
|
|
3821
|
+
const event = call.arguments[0] ? extractNodeValue2(call.arguments[0]) : "";
|
|
3822
|
+
const data = call.arguments[1] ? extractNodeValue2(call.arguments[1]) : void 0;
|
|
3823
|
+
ctx.onEnter.push({
|
|
3824
|
+
id: `auto_${++actionCounter.value}`,
|
|
3825
|
+
type: "log_event",
|
|
3826
|
+
mode: "auto",
|
|
3827
|
+
config: { event: String(event), ...data ? { data } : {} },
|
|
3828
|
+
...ctx.ifCondition ? { condition: ctx.ifCondition } : {}
|
|
3829
|
+
});
|
|
3830
|
+
return;
|
|
3831
|
+
}
|
|
3832
|
+
if (fnName === "notify") {
|
|
3833
|
+
const to = call.arguments[0] ? expressionToIR(call.arguments[0], paramName) : "";
|
|
3834
|
+
const message = call.arguments[1] ? extractNodeValue2(call.arguments[1]) : "";
|
|
3835
|
+
const opts = call.arguments[2] ? extractNodeValue2(call.arguments[2]) : {};
|
|
3836
|
+
ctx.onEnter.push({
|
|
3837
|
+
id: `auto_${++actionCounter.value}`,
|
|
3838
|
+
type: "send_notification",
|
|
3839
|
+
mode: "auto",
|
|
3840
|
+
config: {
|
|
3841
|
+
to: String(to),
|
|
3842
|
+
message: String(message),
|
|
3843
|
+
...opts
|
|
3844
|
+
},
|
|
3845
|
+
...ctx.ifCondition ? { condition: ctx.ifCondition } : {}
|
|
3846
|
+
});
|
|
3847
|
+
return;
|
|
3848
|
+
}
|
|
3849
|
+
if (fnName === "emit") {
|
|
3850
|
+
const event = call.arguments[0] ? extractNodeValue2(call.arguments[0]) : "";
|
|
3851
|
+
const payload = call.arguments[1] ? extractNodeValue2(call.arguments[1]) : void 0;
|
|
3852
|
+
ctx.onEnter.push({
|
|
3853
|
+
id: `auto_${++actionCounter.value}`,
|
|
3854
|
+
type: "emit_event",
|
|
3855
|
+
mode: "auto",
|
|
3856
|
+
config: { event: String(event), ...payload ? { payload } : {} },
|
|
3857
|
+
...ctx.ifCondition ? { condition: ctx.ifCondition } : {}
|
|
3858
|
+
});
|
|
3859
|
+
return;
|
|
3860
|
+
}
|
|
3861
|
+
if (fnName === "requireRole") {
|
|
3862
|
+
for (const arg of call.arguments) {
|
|
3863
|
+
if (t12.isStringLiteral(arg)) ctx.roles.push(arg.value);
|
|
3864
|
+
}
|
|
3865
|
+
return;
|
|
3866
|
+
}
|
|
3867
|
+
if (fnName === "requireField") {
|
|
3868
|
+
for (const arg of call.arguments) {
|
|
3869
|
+
if (t12.isStringLiteral(arg)) ctx.requiredFields.push(arg.value);
|
|
3870
|
+
}
|
|
3871
|
+
return;
|
|
3872
|
+
}
|
|
3873
|
+
if (fnName === "runtime") {
|
|
3874
|
+
if (call.arguments[0] && t12.isStringLiteral(call.arguments[0])) {
|
|
3875
|
+
ctx.setRuntime(call.arguments[0].value);
|
|
3876
|
+
}
|
|
3877
|
+
return;
|
|
3878
|
+
}
|
|
3879
|
+
if (fnName === "guard") {
|
|
3880
|
+
if (call.arguments[0] && t12.isStringLiteral(call.arguments[0])) {
|
|
3881
|
+
ctx.conditions.push({ expression: call.arguments[0].value });
|
|
3882
|
+
}
|
|
3883
|
+
return;
|
|
3884
|
+
}
|
|
3885
|
+
if (fnName === "every") {
|
|
3886
|
+
const interval = call.arguments[0] && t12.isStringLiteral(call.arguments[0]) ? call.arguments[0].value : "1h";
|
|
3887
|
+
const intervalMs = parseDuration(interval);
|
|
3888
|
+
const opts = call.arguments[1] ? extractNodeValue2(call.arguments[1]) : {};
|
|
3889
|
+
const duringAction = {
|
|
3890
|
+
id: `during_${++actionCounter.value}`,
|
|
3891
|
+
type: "interval",
|
|
3892
|
+
interval_ms: intervalMs,
|
|
3893
|
+
...typeof opts === "object" && opts !== null && opts.when ? { condition: opts.when } : {},
|
|
3894
|
+
actions: []
|
|
3895
|
+
// Placeholder — body analysis would extract inner actions
|
|
3896
|
+
};
|
|
3897
|
+
ctx.during.push(duringAction);
|
|
3898
|
+
return;
|
|
3899
|
+
}
|
|
3900
|
+
if (fnName === "cron") {
|
|
3901
|
+
const cronExpr = call.arguments[0] && t12.isStringLiteral(call.arguments[0]) ? call.arguments[0].value : "* * * * *";
|
|
3902
|
+
ctx.during.push({
|
|
3903
|
+
id: `during_${++actionCounter.value}`,
|
|
3904
|
+
type: "cron",
|
|
3905
|
+
cron: cronExpr,
|
|
3906
|
+
actions: []
|
|
3907
|
+
});
|
|
3908
|
+
return;
|
|
3909
|
+
}
|
|
3910
|
+
if (fnName === "after") {
|
|
3911
|
+
const delay = call.arguments[0] && t12.isStringLiteral(call.arguments[0]) ? call.arguments[0].value : "1h";
|
|
3912
|
+
ctx.during.push({
|
|
3913
|
+
id: `during_${++actionCounter.value}`,
|
|
3914
|
+
type: "timeout",
|
|
3915
|
+
delay_ms: parseDuration(delay),
|
|
3916
|
+
actions: []
|
|
3917
|
+
});
|
|
3918
|
+
return;
|
|
3919
|
+
}
|
|
3920
|
+
if (fnName === "on" && !t12.isAwaitExpression(expr)) {
|
|
3921
|
+
const pattern = call.arguments[0] && t12.isStringLiteral(call.arguments[0]) ? call.arguments[0].value : "*";
|
|
3922
|
+
const opts = call.arguments[1] ? extractNodeValue2(call.arguments[1]) : {};
|
|
3923
|
+
const optsObj = typeof opts === "object" && opts !== null ? opts : {};
|
|
3924
|
+
ctx.onEvent.push({
|
|
3925
|
+
match: pattern,
|
|
3926
|
+
...optsObj.when ? { conditions: [String(optsObj.when)] } : {},
|
|
3927
|
+
actions: []
|
|
3928
|
+
});
|
|
3929
|
+
return;
|
|
3930
|
+
}
|
|
3931
|
+
if (fnName === "timeout") {
|
|
3932
|
+
const duration = call.arguments[0] && t12.isStringLiteral(call.arguments[0]) ? call.arguments[0].value : "1h";
|
|
3933
|
+
const opts = call.arguments[1] ? extractNodeValue2(call.arguments[1]) : {};
|
|
3934
|
+
const optsObj = typeof opts === "object" && opts !== null ? opts : {};
|
|
3935
|
+
ctx.setTimeout({
|
|
3936
|
+
duration,
|
|
3937
|
+
fallback: {
|
|
3938
|
+
...optsObj.transition ? { transition: String(optsObj.transition) } : {},
|
|
3939
|
+
...optsObj.action ? { action: String(optsObj.action) } : {}
|
|
3940
|
+
}
|
|
3941
|
+
});
|
|
3942
|
+
return;
|
|
3943
|
+
}
|
|
3944
|
+
if (fnName === "restrict") {
|
|
3945
|
+
return;
|
|
3946
|
+
}
|
|
3947
|
+
}
|
|
3948
|
+
}
|
|
3949
|
+
function extractValidation(call, paramName, ctx) {
|
|
3950
|
+
const condArg = call.arguments[0];
|
|
3951
|
+
const msgArg = call.arguments[1];
|
|
3952
|
+
const sevArg = call.arguments[2];
|
|
3953
|
+
const message = msgArg && t12.isStringLiteral(msgArg) ? msgArg.value : "Validation failed";
|
|
3954
|
+
const severity = sevArg && t12.isStringLiteral(sevArg) && sevArg.value === "warning" ? "warning" : "error";
|
|
3955
|
+
if (!condArg) return;
|
|
3956
|
+
const field = extractFieldFromCondition(condArg, paramName);
|
|
3957
|
+
const exprStr = expressionToIR(condArg, paramName);
|
|
3958
|
+
if (field) {
|
|
3959
|
+
const validation = {};
|
|
3960
|
+
if (t12.isBinaryExpression(condArg) && (condArg.operator === ">" || condArg.operator === ">=")) {
|
|
3961
|
+
if (isLengthAccess(condArg.left, paramName, field) && t12.isNumericLiteral(condArg.right)) {
|
|
3962
|
+
validation.minLength = condArg.right.value + (condArg.operator === ">" ? 1 : 0);
|
|
3963
|
+
} else if (isFieldAccess(condArg.left, paramName, field) && t12.isNumericLiteral(condArg.right)) {
|
|
3964
|
+
validation.min = condArg.right.value + (condArg.operator === ">" ? 1e-3 : 0);
|
|
3965
|
+
}
|
|
3966
|
+
}
|
|
3967
|
+
if (t12.isBinaryExpression(condArg) && (condArg.operator === "<" || condArg.operator === "<=")) {
|
|
3968
|
+
if (isFieldAccess(condArg.left, paramName, field) && t12.isNumericLiteral(condArg.right)) {
|
|
3969
|
+
validation.max = condArg.right.value;
|
|
3970
|
+
}
|
|
3971
|
+
}
|
|
3972
|
+
if (t12.isCallExpression(condArg) && t12.isMemberExpression(condArg.callee) && t12.isRegExpLiteral(condArg.callee.object) && t12.isIdentifier(condArg.callee.property) && condArg.callee.property.name === "test") {
|
|
3973
|
+
if (!validation.rules) validation.rules = [];
|
|
3974
|
+
validation.rules.push({
|
|
3975
|
+
expression: `MATCHES(value, "${condArg.callee.object.pattern}")`,
|
|
3976
|
+
message: "",
|
|
3977
|
+
// Will be set from the validate() message arg
|
|
3978
|
+
severity: "error"
|
|
3979
|
+
});
|
|
3980
|
+
}
|
|
3981
|
+
ctx.validations.push({ field, validation, message, severity });
|
|
3982
|
+
} else {
|
|
3983
|
+
ctx.validations.push({
|
|
3984
|
+
field: "__cross__",
|
|
3985
|
+
validation: { rules: [{ expression: exprStr, message, severity }] },
|
|
3986
|
+
message,
|
|
3987
|
+
severity
|
|
3988
|
+
});
|
|
3989
|
+
}
|
|
3990
|
+
}
|
|
3991
|
+
function extractFieldFromCondition(node, paramName) {
|
|
3992
|
+
if (t12.isMemberExpression(node)) {
|
|
3993
|
+
const str = memberExprToString(node);
|
|
3994
|
+
if (str.startsWith(`${paramName}.`)) {
|
|
3995
|
+
const parts = str.slice(paramName.length + 1).split(".");
|
|
3996
|
+
return parts[0];
|
|
3997
|
+
}
|
|
3998
|
+
}
|
|
3999
|
+
if (t12.isBinaryExpression(node)) {
|
|
4000
|
+
return extractFieldFromCondition(node.left, paramName) || extractFieldFromCondition(node.right, paramName);
|
|
4001
|
+
}
|
|
4002
|
+
if (t12.isCallExpression(node) && t12.isMemberExpression(node.callee)) {
|
|
4003
|
+
return extractFieldFromCondition(node.callee.object, paramName);
|
|
4004
|
+
}
|
|
4005
|
+
if (t12.isCallExpression(node) && t12.isMemberExpression(node.callee) && t12.isRegExpLiteral(node.callee.object) && node.arguments[0]) {
|
|
4006
|
+
return extractFieldFromCondition(node.arguments[0], paramName);
|
|
4007
|
+
}
|
|
4008
|
+
if (t12.isLogicalExpression(node)) {
|
|
4009
|
+
return extractFieldFromCondition(node.left, paramName) || extractFieldFromCondition(node.right, paramName);
|
|
4010
|
+
}
|
|
4011
|
+
if (t12.isUnaryExpression(node)) {
|
|
4012
|
+
return extractFieldFromCondition(node.argument, paramName);
|
|
4013
|
+
}
|
|
4014
|
+
return null;
|
|
4015
|
+
}
|
|
4016
|
+
function isLengthAccess(node, paramName, field) {
|
|
4017
|
+
if (!t12.isMemberExpression(node)) return false;
|
|
4018
|
+
const str = memberExprToString(node);
|
|
4019
|
+
return str === `${paramName}.${field}.length`;
|
|
4020
|
+
}
|
|
4021
|
+
function isFieldAccess(node, paramName, field) {
|
|
4022
|
+
if (!t12.isMemberExpression(node)) return false;
|
|
4023
|
+
const str = memberExprToString(node);
|
|
4024
|
+
return str === `${paramName}.${field}`;
|
|
4025
|
+
}
|
|
4026
|
+
function expressionToIR(node, paramName) {
|
|
4027
|
+
if (t12.isStringLiteral(node)) return `"${node.value}"`;
|
|
4028
|
+
if (t12.isNumericLiteral(node)) return String(node.value);
|
|
4029
|
+
if (t12.isBooleanLiteral(node)) return String(node.value);
|
|
4030
|
+
if (t12.isNullLiteral(node)) return "null";
|
|
4031
|
+
if (t12.isIdentifier(node)) {
|
|
4032
|
+
if (node.name === paramName) return "state_data";
|
|
4033
|
+
if (node.name === "actor") return "context";
|
|
4034
|
+
if (node.name === "instance") return "instance";
|
|
4035
|
+
return node.name;
|
|
4036
|
+
}
|
|
4037
|
+
if (t12.isMemberExpression(node)) {
|
|
4038
|
+
const str = memberExprToString(node);
|
|
4039
|
+
if (str.startsWith(`${paramName}.`)) return "state_data." + str.slice(paramName.length + 1);
|
|
4040
|
+
if (str.startsWith("actor.")) return "context." + str.slice(6);
|
|
4041
|
+
if (str.startsWith("Date.")) {
|
|
4042
|
+
if (str === "Date.now") return "NOW()";
|
|
4043
|
+
}
|
|
4044
|
+
return str;
|
|
4045
|
+
}
|
|
4046
|
+
if (t12.isCallExpression(node)) {
|
|
4047
|
+
if (t12.isMemberExpression(node.callee) && t12.isIdentifier(node.callee.property)) {
|
|
4048
|
+
const obj = expressionToIR(node.callee.object, paramName);
|
|
4049
|
+
const method = node.callee.property.name;
|
|
4050
|
+
if (method === "now" && obj === "Date") return "NOW()";
|
|
4051
|
+
if (method === "includes") {
|
|
4052
|
+
const arg = node.arguments[0] ? expressionToIR(node.arguments[0], paramName) : "";
|
|
4053
|
+
return `CONTAINS(${obj}, ${arg})`;
|
|
4054
|
+
}
|
|
4055
|
+
if (method === "length") return `LEN(${obj})`;
|
|
4056
|
+
}
|
|
4057
|
+
if (t12.isIdentifier(node.callee) && node.callee.name === "Date") {
|
|
4058
|
+
if (t12.isMemberExpression(node) && t12.isIdentifier(node.property) && node.property.name === "now") {
|
|
4059
|
+
return "NOW()";
|
|
4060
|
+
}
|
|
4061
|
+
}
|
|
4062
|
+
return "[call]";
|
|
4063
|
+
}
|
|
4064
|
+
if (t12.isBinaryExpression(node)) {
|
|
4065
|
+
const left = expressionToIR(node.left, paramName);
|
|
4066
|
+
const right = expressionToIR(node.right, paramName);
|
|
4067
|
+
return `${left} ${node.operator} ${right}`;
|
|
4068
|
+
}
|
|
4069
|
+
if (t12.isLogicalExpression(node)) {
|
|
4070
|
+
const left = expressionToIR(node.left, paramName);
|
|
4071
|
+
const right = expressionToIR(node.right, paramName);
|
|
4072
|
+
const op = node.operator === "&&" ? "AND" : node.operator === "||" ? "OR" : node.operator;
|
|
4073
|
+
return `${left} ${op} ${right}`;
|
|
4074
|
+
}
|
|
4075
|
+
if (t12.isUnaryExpression(node)) {
|
|
4076
|
+
if (node.operator === "!") return `NOT(${expressionToIR(node.argument, paramName)})`;
|
|
4077
|
+
return `${node.operator}${expressionToIR(node.argument, paramName)}`;
|
|
4078
|
+
}
|
|
4079
|
+
if (t12.isConditionalExpression(node)) {
|
|
4080
|
+
return `IF(${expressionToIR(node.test, paramName)}, ${expressionToIR(node.consequent, paramName)}, ${expressionToIR(node.alternate, paramName)})`;
|
|
4081
|
+
}
|
|
4082
|
+
if (t12.isTemplateLiteral(node)) {
|
|
4083
|
+
const parts = [];
|
|
4084
|
+
for (let i = 0; i < node.quasis.length; i++) {
|
|
4085
|
+
parts.push(node.quasis[i].value.raw);
|
|
4086
|
+
if (i < node.expressions.length) {
|
|
4087
|
+
parts.push(`{{ ${expressionToIR(node.expressions[i], paramName)} }}`);
|
|
4088
|
+
}
|
|
4089
|
+
}
|
|
4090
|
+
return `"${parts.join("")}"`;
|
|
4091
|
+
}
|
|
4092
|
+
if (t12.isRegExpLiteral(node)) return node.pattern;
|
|
4093
|
+
return "[expr]";
|
|
4094
|
+
}
|
|
4095
|
+
function extractCallSequence(body, paramName, localFnNames, importedFns) {
|
|
4096
|
+
const calls = [];
|
|
4097
|
+
for (const stmt of body.body) {
|
|
4098
|
+
extractCallsFromStatement(stmt, paramName, localFnNames, importedFns, calls);
|
|
4099
|
+
}
|
|
4100
|
+
return calls;
|
|
4101
|
+
}
|
|
4102
|
+
function extractCallsFromStatement(stmt, paramName, localFnNames, importedFns, calls, condition) {
|
|
4103
|
+
if (t12.isExpressionStatement(stmt)) {
|
|
4104
|
+
const expr = stmt.expression;
|
|
4105
|
+
if (t12.isAwaitExpression(expr)) {
|
|
4106
|
+
const call = extractWorkflowCall(expr.argument, paramName, localFnNames, importedFns);
|
|
4107
|
+
if (call) {
|
|
4108
|
+
if (condition) call.condition = condition;
|
|
4109
|
+
calls.push(call);
|
|
4110
|
+
}
|
|
4111
|
+
}
|
|
4112
|
+
if (t12.isCallExpression(expr) && t12.isIdentifier(expr.callee) && expr.callee.name === "allowTransition") {
|
|
4113
|
+
}
|
|
4114
|
+
}
|
|
4115
|
+
if (t12.isVariableDeclaration(stmt)) {
|
|
4116
|
+
for (const decl of stmt.declarations) {
|
|
4117
|
+
if (decl.init && t12.isAwaitExpression(decl.init)) {
|
|
4118
|
+
const call = extractWorkflowCall(decl.init.argument, paramName, localFnNames, importedFns);
|
|
4119
|
+
if (call) {
|
|
4120
|
+
if (condition) call.condition = condition;
|
|
4121
|
+
calls.push(call);
|
|
4122
|
+
}
|
|
4123
|
+
}
|
|
4124
|
+
}
|
|
4125
|
+
}
|
|
4126
|
+
if (t12.isIfStatement(stmt)) {
|
|
4127
|
+
const condStr = expressionToIR(stmt.test, paramName);
|
|
4128
|
+
if (t12.isBlockStatement(stmt.consequent)) {
|
|
4129
|
+
for (const inner of stmt.consequent.body) {
|
|
4130
|
+
extractCallsFromStatement(inner, paramName, localFnNames, importedFns, calls, condStr);
|
|
4131
|
+
}
|
|
4132
|
+
}
|
|
4133
|
+
if (stmt.alternate) {
|
|
4134
|
+
const negCond = `NOT(${condStr})`;
|
|
4135
|
+
if (t12.isBlockStatement(stmt.alternate)) {
|
|
4136
|
+
for (const inner of stmt.alternate.body) {
|
|
4137
|
+
extractCallsFromStatement(inner, paramName, localFnNames, importedFns, calls, negCond);
|
|
4138
|
+
}
|
|
4139
|
+
} else if (t12.isIfStatement(stmt.alternate)) {
|
|
4140
|
+
extractCallsFromStatement(stmt.alternate, paramName, localFnNames, importedFns, calls);
|
|
4141
|
+
}
|
|
4142
|
+
}
|
|
4143
|
+
}
|
|
4144
|
+
if (t12.isTryStatement(stmt)) {
|
|
4145
|
+
const tryBlockCalls = [];
|
|
4146
|
+
if (stmt.block) {
|
|
4147
|
+
for (const inner of stmt.block.body) {
|
|
4148
|
+
extractCallsFromStatement(inner, paramName, localFnNames, importedFns, tryBlockCalls, condition);
|
|
4149
|
+
}
|
|
4150
|
+
}
|
|
4151
|
+
calls.push(...tryBlockCalls);
|
|
4152
|
+
if (stmt.handler && stmt.handler.body) {
|
|
4153
|
+
const catchBody = stmt.handler.body;
|
|
4154
|
+
const compensationActions = [];
|
|
4155
|
+
const catchParamName = stmt.handler.param && t12.isIdentifier(stmt.handler.param) ? stmt.handler.param.name : "error";
|
|
4156
|
+
const hasReturn = catchBody.body.some((s) => t12.isReturnStatement(s));
|
|
4157
|
+
for (const inner of catchBody.body) {
|
|
4158
|
+
if (t12.isReturnStatement(inner)) continue;
|
|
4159
|
+
extractCallsFromStatement(inner, paramName, localFnNames, importedFns, compensationActions, condition);
|
|
4160
|
+
}
|
|
4161
|
+
calls.push({
|
|
4162
|
+
type: "stateCall",
|
|
4163
|
+
name: `__compensation_${calls.length}`,
|
|
4164
|
+
options: {
|
|
4165
|
+
__isCompensation: true,
|
|
4166
|
+
__tryBlockCallNames: tryBlockCalls.map((c) => c.name),
|
|
4167
|
+
__compensationCalls: compensationActions,
|
|
4168
|
+
__hasReturn: hasReturn,
|
|
4169
|
+
__catchParam: catchParamName,
|
|
4170
|
+
__catchBody: catchBody
|
|
4171
|
+
}
|
|
4172
|
+
});
|
|
4173
|
+
}
|
|
4174
|
+
}
|
|
4175
|
+
if (t12.isSwitchStatement(stmt)) {
|
|
4176
|
+
}
|
|
4177
|
+
}
|
|
4178
|
+
function extractWorkflowCall(node, paramName, localFnNames, importedFns) {
|
|
4179
|
+
if (t12.isCallExpression(node)) {
|
|
4180
|
+
const callee = node.callee;
|
|
4181
|
+
if (t12.isIdentifier(callee) && callee.name === "named" && node.arguments.length >= 2) {
|
|
4182
|
+
const name = t12.isStringLiteral(node.arguments[0]) ? node.arguments[0].value : "";
|
|
4183
|
+
const inner = node.arguments[1];
|
|
4184
|
+
if (t12.isCallExpression(inner) || t12.isAwaitExpression(inner)) {
|
|
4185
|
+
const innerNode = t12.isAwaitExpression(inner) ? inner.argument : inner;
|
|
4186
|
+
const innerCall = extractWorkflowCall(innerNode, paramName, localFnNames, importedFns);
|
|
4187
|
+
if (innerCall) {
|
|
4188
|
+
innerCall.transitionName = name;
|
|
4189
|
+
return innerCall;
|
|
4190
|
+
}
|
|
4191
|
+
}
|
|
4192
|
+
return null;
|
|
4193
|
+
}
|
|
4194
|
+
if (t12.isIdentifier(callee) && callee.name === "userAction") {
|
|
4195
|
+
const name = node.arguments[0] && t12.isStringLiteral(node.arguments[0]) ? node.arguments[0].value : "action";
|
|
4196
|
+
const opts = node.arguments[1] ? extractNodeValue2(node.arguments[1]) : {};
|
|
4197
|
+
return { type: "userAction", name, options: opts };
|
|
4198
|
+
}
|
|
4199
|
+
if (t12.isIdentifier(callee) && callee.name === "userChoice") {
|
|
4200
|
+
const choices = node.arguments[0] ? extractNodeValue2(node.arguments[0]) : {};
|
|
4201
|
+
return { type: "userChoice", name: "choice", choices };
|
|
4202
|
+
}
|
|
4203
|
+
if (t12.isIdentifier(callee) && callee.name === "delay") {
|
|
4204
|
+
const duration = node.arguments[0] && t12.isStringLiteral(node.arguments[0]) ? node.arguments[0].value : "0";
|
|
4205
|
+
return { type: "delay", name: `delay_${duration}` };
|
|
4206
|
+
}
|
|
4207
|
+
if (t12.isIdentifier(callee) && callee.name === "on") {
|
|
4208
|
+
const pattern = node.arguments[0] && t12.isStringLiteral(node.arguments[0]) ? node.arguments[0].value : "*";
|
|
4209
|
+
const opts = node.arguments[1] ? extractNodeValue2(node.arguments[1]) : {};
|
|
4210
|
+
opts.__eventPattern = pattern;
|
|
4211
|
+
return { type: "awaitOn", name: pattern.replace(/[^a-zA-Z0-9]/g, "_"), options: opts };
|
|
4212
|
+
}
|
|
4213
|
+
if (t12.isMemberExpression(callee) && t12.isIdentifier(callee.object) && callee.object.name === "Promise" && t12.isIdentifier(callee.property)) {
|
|
4214
|
+
if (callee.property.name === "all" && node.arguments[0] && t12.isArrayExpression(node.arguments[0])) {
|
|
4215
|
+
const parallelCalls = [];
|
|
4216
|
+
for (const el of node.arguments[0].elements) {
|
|
4217
|
+
if (!el || t12.isSpreadElement(el)) continue;
|
|
4218
|
+
const innerNode = t12.isAwaitExpression(el) ? el.argument : el;
|
|
4219
|
+
const c = extractWorkflowCall(innerNode, paramName, localFnNames, importedFns);
|
|
4220
|
+
if (c) parallelCalls.push(c);
|
|
4221
|
+
}
|
|
4222
|
+
return { type: "promiseAll", name: "parallel", parallelCalls };
|
|
4223
|
+
}
|
|
4224
|
+
if (callee.property.name === "race" && node.arguments[0] && t12.isArrayExpression(node.arguments[0])) {
|
|
4225
|
+
const parallelCalls = [];
|
|
4226
|
+
for (const el of node.arguments[0].elements) {
|
|
4227
|
+
if (!el || t12.isSpreadElement(el)) continue;
|
|
4228
|
+
const innerNode = t12.isAwaitExpression(el) ? el.argument : el;
|
|
4229
|
+
const c = extractWorkflowCall(innerNode, paramName, localFnNames, importedFns);
|
|
4230
|
+
if (c) parallelCalls.push(c);
|
|
4231
|
+
}
|
|
4232
|
+
return { type: "promiseRace", name: "race", parallelCalls };
|
|
4233
|
+
}
|
|
4234
|
+
}
|
|
4235
|
+
if (t12.isIdentifier(callee) && localFnNames.has(callee.name)) {
|
|
4236
|
+
return { type: "stateCall", name: callee.name };
|
|
4237
|
+
}
|
|
4238
|
+
if (t12.isIdentifier(callee) && importedFns.has(callee.name)) {
|
|
4239
|
+
return {
|
|
4240
|
+
type: "serviceCall",
|
|
4241
|
+
name: callee.name,
|
|
4242
|
+
importSource: importedFns.get(callee.name)
|
|
4243
|
+
};
|
|
4244
|
+
}
|
|
4245
|
+
}
|
|
4246
|
+
return null;
|
|
4247
|
+
}
|
|
4248
|
+
function extractAllowTransitions(body) {
|
|
4249
|
+
const result = [];
|
|
4250
|
+
for (const stmt of body.body) {
|
|
4251
|
+
if (!t12.isExpressionStatement(stmt)) continue;
|
|
4252
|
+
const expr = stmt.expression;
|
|
4253
|
+
if (!t12.isCallExpression(expr)) continue;
|
|
4254
|
+
if (!t12.isIdentifier(expr.callee) || expr.callee.name !== "allowTransition") continue;
|
|
4255
|
+
const nameArg = expr.arguments[0];
|
|
4256
|
+
const optsArg = expr.arguments[1];
|
|
4257
|
+
if (!t12.isStringLiteral(nameArg)) continue;
|
|
4258
|
+
const name = nameArg.value;
|
|
4259
|
+
const opts = optsArg && t12.isObjectExpression(optsArg) ? extractNodeValue2(optsArg) : {};
|
|
4260
|
+
let from = [];
|
|
4261
|
+
if (typeof opts.from === "string") from = [opts.from];
|
|
4262
|
+
else if (Array.isArray(opts.from)) from = opts.from.map(String);
|
|
4263
|
+
result.push({
|
|
4264
|
+
name,
|
|
4265
|
+
from,
|
|
4266
|
+
to: String(opts.to || ""),
|
|
4267
|
+
...opts.roles ? { roles: opts.roles } : {},
|
|
4268
|
+
...opts.require ? { require: opts.require } : {},
|
|
4269
|
+
...opts.when ? { when: String(opts.when) } : {}
|
|
4270
|
+
});
|
|
4271
|
+
}
|
|
4272
|
+
return result;
|
|
4273
|
+
}
|
|
4274
|
+
function parseDuration(str) {
|
|
4275
|
+
const match = str.match(/^(\d+(?:\.\d+)?)\s*(ms|s|m|h|d|w)$/);
|
|
4276
|
+
if (!match) return 0;
|
|
4277
|
+
const value = parseFloat(match[1]);
|
|
4278
|
+
switch (match[2]) {
|
|
4279
|
+
case "ms":
|
|
4280
|
+
return value;
|
|
4281
|
+
case "s":
|
|
4282
|
+
return value * 1e3;
|
|
4283
|
+
case "m":
|
|
4284
|
+
return value * 6e4;
|
|
4285
|
+
case "h":
|
|
4286
|
+
return value * 36e5;
|
|
4287
|
+
case "d":
|
|
4288
|
+
return value * 864e5;
|
|
4289
|
+
case "w":
|
|
4290
|
+
return value * 6048e5;
|
|
4291
|
+
default:
|
|
4292
|
+
return 0;
|
|
4293
|
+
}
|
|
4294
|
+
}
|
|
4295
|
+
function toSnakeCase2(name) {
|
|
4296
|
+
return name.replace(/([A-Z])/g, "_$1").toLowerCase().replace(/^_/, "");
|
|
4297
|
+
}
|
|
4298
|
+
function fnNameToSlug(name) {
|
|
4299
|
+
return name.replace(/([A-Z])/g, "-$1").toLowerCase().replace(/^-/, "");
|
|
4300
|
+
}
|
|
4301
|
+
function extractStateDataRefs(expression) {
|
|
4302
|
+
const refs = [];
|
|
4303
|
+
const regex = /state_data\.(\w+)/g;
|
|
4304
|
+
let match;
|
|
4305
|
+
while ((match = regex.exec(expression)) !== null) {
|
|
4306
|
+
refs.push(match[1]);
|
|
4307
|
+
}
|
|
4308
|
+
return [...new Set(refs)];
|
|
4309
|
+
}
|
|
4310
|
+
function detectComputedFieldsFromActions(compilerState, stateFnInfos) {
|
|
4311
|
+
for (const [, info] of stateFnInfos) {
|
|
4312
|
+
for (const action of info.onEnter) {
|
|
4313
|
+
if (action.type !== "set_field") continue;
|
|
4314
|
+
const config = action.config;
|
|
4315
|
+
if (!config?.field || !config?.expression) continue;
|
|
4316
|
+
const targetField = config.field;
|
|
4317
|
+
const expression = config.expression;
|
|
4318
|
+
const refs = extractStateDataRefs(expression);
|
|
4319
|
+
const deps = refs.filter((r) => r !== targetField);
|
|
4320
|
+
if (deps.length === 0) continue;
|
|
4321
|
+
const field = compilerState.fields.find((f) => f.name === targetField);
|
|
4322
|
+
if (field) {
|
|
4323
|
+
field.computed = expression;
|
|
4324
|
+
field.computed_deps = deps;
|
|
4325
|
+
}
|
|
4326
|
+
}
|
|
4327
|
+
}
|
|
4328
|
+
}
|
|
4329
|
+
function detectComputedFieldGetters(path, paramName, paramTypeName, compilerState) {
|
|
4330
|
+
for (const node of path.node.body) {
|
|
4331
|
+
if (!t12.isFunctionDeclaration(node)) continue;
|
|
4332
|
+
if (node.async) continue;
|
|
4333
|
+
if (!node.id) continue;
|
|
4334
|
+
if (node.params.length !== 1) continue;
|
|
4335
|
+
const fnParam = node.params[0];
|
|
4336
|
+
if (!t12.isIdentifier(fnParam)) continue;
|
|
4337
|
+
if (fnParam.typeAnnotation && t12.isTSTypeAnnotation(fnParam.typeAnnotation)) {
|
|
4338
|
+
const typeAnno = fnParam.typeAnnotation.typeAnnotation;
|
|
4339
|
+
if (t12.isTSTypeReference(typeAnno) && t12.isIdentifier(typeAnno.typeName)) {
|
|
4340
|
+
if (typeAnno.typeName.name !== paramTypeName) continue;
|
|
4341
|
+
} else {
|
|
4342
|
+
continue;
|
|
4343
|
+
}
|
|
4344
|
+
} else {
|
|
4345
|
+
continue;
|
|
4346
|
+
}
|
|
4347
|
+
const hasReturnType = node.returnType && t12.isTSTypeAnnotation(node.returnType);
|
|
4348
|
+
if (!node.body || !t12.isBlockStatement(node.body)) continue;
|
|
4349
|
+
const returnStmt = node.body.body.find(
|
|
4350
|
+
(s) => t12.isReturnStatement(s)
|
|
4351
|
+
);
|
|
4352
|
+
if (!returnStmt?.argument) continue;
|
|
4353
|
+
const getterParamName = fnParam.name;
|
|
4354
|
+
const expression = expressionToIR(returnStmt.argument, getterParamName);
|
|
4355
|
+
const deps = extractStateDataRefs(expression);
|
|
4356
|
+
if (deps.length === 0) continue;
|
|
4357
|
+
const fieldName = node.id.name;
|
|
4358
|
+
let field = compilerState.fields.find((f) => f.name === fieldName);
|
|
4359
|
+
if (field) {
|
|
4360
|
+
field.computed = expression;
|
|
4361
|
+
field.computed_deps = deps;
|
|
4362
|
+
} else {
|
|
4363
|
+
let fieldType = "text";
|
|
4364
|
+
if (hasReturnType) {
|
|
4365
|
+
const retType = node.returnType.typeAnnotation;
|
|
4366
|
+
fieldType = resolveType2(retType);
|
|
4367
|
+
}
|
|
4368
|
+
compilerState.fields.push({
|
|
4369
|
+
name: fieldName,
|
|
4370
|
+
type: fieldType,
|
|
4371
|
+
label: fieldName.replace(/([A-Z])/g, " $1").replace(/^./, (c) => c.toUpperCase()),
|
|
4372
|
+
required: false,
|
|
4373
|
+
computed: expression,
|
|
4374
|
+
computed_deps: deps
|
|
4375
|
+
});
|
|
4376
|
+
}
|
|
4377
|
+
}
|
|
4378
|
+
}
|
|
4379
|
+
function extractImperativeWorkflow(path, state) {
|
|
4380
|
+
const compilerState = state;
|
|
4381
|
+
if (!compilerState.actionCounter) compilerState.actionCounter = 0;
|
|
4382
|
+
const actionCounter = { value: compilerState.actionCounter };
|
|
4383
|
+
const importedFns = /* @__PURE__ */ new Map();
|
|
4384
|
+
const stdLibImports = /* @__PURE__ */ new Set();
|
|
4385
|
+
for (const node of path.node.body) {
|
|
4386
|
+
if (t12.isImportDeclaration(node)) {
|
|
4387
|
+
const source = node.source.value;
|
|
4388
|
+
for (const spec of node.specifiers) {
|
|
4389
|
+
const localName = spec.local.name;
|
|
4390
|
+
if (source.includes("@mmapp/react") || source.includes("@mindmatrix/react")) {
|
|
4391
|
+
stdLibImports.add(localName);
|
|
4392
|
+
} else {
|
|
4393
|
+
importedFns.set(localName, source);
|
|
4394
|
+
}
|
|
4395
|
+
}
|
|
4396
|
+
}
|
|
4397
|
+
}
|
|
4398
|
+
for (const node of path.node.body) {
|
|
4399
|
+
if (t12.isExportDefaultDeclaration(node) && t12.isCallExpression(node.declaration)) {
|
|
4400
|
+
const call = node.declaration;
|
|
4401
|
+
if (t12.isIdentifier(call.callee) && call.callee.name === "workflow") {
|
|
4402
|
+
const slugArg = call.arguments[0] && t12.isStringLiteral(call.arguments[0]) ? call.arguments[0].value : "workflow";
|
|
4403
|
+
let fieldsOrArrow = "";
|
|
4404
|
+
let arrowString;
|
|
4405
|
+
if (call.arguments.length === 2) {
|
|
4406
|
+
const arg1 = call.arguments[1];
|
|
4407
|
+
if (t12.isStringLiteral(arg1)) {
|
|
4408
|
+
fieldsOrArrow = arg1.value;
|
|
4409
|
+
} else if (t12.isTemplateLiteral(arg1)) {
|
|
4410
|
+
fieldsOrArrow = arg1.quasis.map((q) => q.value.raw).join("");
|
|
4411
|
+
} else if (t12.isObjectExpression(arg1)) {
|
|
4412
|
+
fieldsOrArrow = extractNodeValue2(arg1);
|
|
4413
|
+
}
|
|
4414
|
+
} else if (call.arguments.length >= 3) {
|
|
4415
|
+
const arg1 = call.arguments[1];
|
|
4416
|
+
const arg2 = call.arguments[2];
|
|
4417
|
+
if (t12.isObjectExpression(arg1)) {
|
|
4418
|
+
fieldsOrArrow = extractNodeValue2(arg1);
|
|
4419
|
+
}
|
|
4420
|
+
if (t12.isStringLiteral(arg2)) {
|
|
4421
|
+
arrowString = arg2.value;
|
|
4422
|
+
} else if (t12.isTemplateLiteral(arg2)) {
|
|
4423
|
+
arrowString = arg2.quasis.map((q) => q.value.raw).join("");
|
|
4424
|
+
}
|
|
4425
|
+
}
|
|
4426
|
+
const result = parseWorkflowShorthand(slugArg, fieldsOrArrow, arrowString);
|
|
4427
|
+
compilerState.metadata.slug = result.slug;
|
|
4428
|
+
compilerState.metadata.category = "workflow";
|
|
4429
|
+
compilerState.fields.push(...result.fields);
|
|
4430
|
+
for (const s of result.states) {
|
|
4431
|
+
compilerState.states.set(s.name, s);
|
|
4432
|
+
}
|
|
4433
|
+
compilerState.transitions.push(...result.transitions);
|
|
4434
|
+
compilerState.actionCounter = actionCounter.value;
|
|
4435
|
+
return;
|
|
4436
|
+
}
|
|
4437
|
+
}
|
|
4438
|
+
}
|
|
4439
|
+
let parentFn = null;
|
|
4440
|
+
let parentName = "";
|
|
4441
|
+
let paramName = "";
|
|
4442
|
+
let paramTypeName = "";
|
|
4443
|
+
for (const node of path.node.body) {
|
|
4444
|
+
if (t12.isExportDefaultDeclaration(node) && t12.isFunctionDeclaration(node.declaration)) {
|
|
4445
|
+
const fn = node.declaration;
|
|
4446
|
+
if (fn.async && fn.params.length > 0) {
|
|
4447
|
+
parentFn = fn;
|
|
4448
|
+
parentName = fn.id?.name || "workflow";
|
|
4449
|
+
const param = fn.params[0];
|
|
4450
|
+
if (t12.isIdentifier(param)) {
|
|
4451
|
+
paramName = param.name;
|
|
4452
|
+
if (param.typeAnnotation && t12.isTSTypeAnnotation(param.typeAnnotation)) {
|
|
4453
|
+
const typeAnno = param.typeAnnotation.typeAnnotation;
|
|
4454
|
+
if (t12.isTSTypeReference(typeAnno) && t12.isIdentifier(typeAnno.typeName)) {
|
|
4455
|
+
paramTypeName = typeAnno.typeName.name;
|
|
4456
|
+
}
|
|
4457
|
+
}
|
|
4458
|
+
}
|
|
4459
|
+
}
|
|
4460
|
+
}
|
|
4461
|
+
}
|
|
4462
|
+
if (!parentFn || !paramName) return;
|
|
4463
|
+
const slug = fnNameToSlug(parentName.replace(/Workflow$/, ""));
|
|
4464
|
+
compilerState.metadata.slug = slug;
|
|
4465
|
+
compilerState.metadata.category = "workflow";
|
|
4466
|
+
for (const node of path.node.body) {
|
|
4467
|
+
if (t12.isTSInterfaceDeclaration(node) && node.id.name === paramTypeName) {
|
|
4468
|
+
const fields = extractFieldsFromInterface2(node);
|
|
4469
|
+
compilerState.fields.push(...fields);
|
|
4470
|
+
compilerState.metadata.name = paramTypeName;
|
|
4471
|
+
}
|
|
4472
|
+
if (t12.isExportNamedDeclaration(node) && t12.isTSInterfaceDeclaration(node.declaration) && node.declaration.id.name === paramTypeName) {
|
|
4473
|
+
const fields = extractFieldsFromInterface2(node.declaration);
|
|
4474
|
+
compilerState.fields.push(...fields);
|
|
4475
|
+
compilerState.metadata.name = paramTypeName;
|
|
4476
|
+
}
|
|
4477
|
+
}
|
|
4478
|
+
const localFns = /* @__PURE__ */ new Map();
|
|
4479
|
+
const localFnNames = /* @__PURE__ */ new Set();
|
|
4480
|
+
for (const node of path.node.body) {
|
|
4481
|
+
if (t12.isFunctionDeclaration(node) && node.async && node.id) {
|
|
4482
|
+
if (node.id.name !== parentName) {
|
|
4483
|
+
localFns.set(node.id.name, node);
|
|
4484
|
+
localFnNames.add(node.id.name);
|
|
4485
|
+
}
|
|
4486
|
+
}
|
|
4487
|
+
if (t12.isExportNamedDeclaration(node) && t12.isFunctionDeclaration(node.declaration) && node.declaration.async && node.declaration.id) {
|
|
4488
|
+
if (node.declaration.id.name !== parentName) {
|
|
4489
|
+
localFns.set(node.declaration.id.name, node.declaration);
|
|
4490
|
+
localFnNames.add(node.declaration.id.name);
|
|
4491
|
+
}
|
|
4492
|
+
}
|
|
4493
|
+
}
|
|
4494
|
+
for (const node of path.node.body) {
|
|
4495
|
+
if (t12.isExportNamedDeclaration(node) && t12.isVariableDeclaration(node.declaration)) {
|
|
4496
|
+
for (const decl of node.declaration.declarations) {
|
|
4497
|
+
if (t12.isIdentifier(decl.id) && decl.id.name === "defaults" && t12.isObjectExpression(decl.init)) {
|
|
4498
|
+
const defaults = extractNodeValue2(decl.init);
|
|
4499
|
+
for (const [name, value] of Object.entries(defaults)) {
|
|
4500
|
+
const field = compilerState.fields.find((f) => f.name === name);
|
|
4501
|
+
if (field && value !== void 0) {
|
|
4502
|
+
field.default_value = value;
|
|
4503
|
+
}
|
|
4504
|
+
}
|
|
4505
|
+
}
|
|
4506
|
+
}
|
|
4507
|
+
}
|
|
4508
|
+
}
|
|
4509
|
+
const stateFnInfos = /* @__PURE__ */ new Map();
|
|
4510
|
+
for (const [name, fn] of localFns) {
|
|
4511
|
+
const fnParamName = fn.params[0] && t12.isIdentifier(fn.params[0]) ? fn.params[0].name : paramName;
|
|
4512
|
+
const analysis = analyzeStateFn(fn, fnParamName, actionCounter);
|
|
4513
|
+
stateFnInfos.set(name, {
|
|
4514
|
+
name,
|
|
4515
|
+
node: fn,
|
|
4516
|
+
params: fn.params.map((p) => t12.isIdentifier(p) ? p.name : ""),
|
|
4517
|
+
...analysis
|
|
4518
|
+
});
|
|
4519
|
+
}
|
|
4520
|
+
detectComputedFieldsFromActions(compilerState, stateFnInfos);
|
|
4521
|
+
detectComputedFieldGetters(path, paramName, paramTypeName, compilerState);
|
|
4522
|
+
const callSequence = extractCallSequence(
|
|
4523
|
+
parentFn.body,
|
|
4524
|
+
paramName,
|
|
4525
|
+
localFnNames,
|
|
4526
|
+
importedFns
|
|
4527
|
+
);
|
|
4528
|
+
const allowTransitions = extractAllowTransitions(parentFn.body);
|
|
4529
|
+
const referencedStates = /* @__PURE__ */ new Set();
|
|
4530
|
+
let firstStateName = "";
|
|
4531
|
+
let prevStateName = "";
|
|
4532
|
+
let transitionIndex = 0;
|
|
4533
|
+
for (const call of callSequence) {
|
|
4534
|
+
const stateName = toSnakeCase2(call.name);
|
|
4535
|
+
switch (call.type) {
|
|
4536
|
+
case "stateCall": {
|
|
4537
|
+
if (call.name.startsWith("__compensation_") && call.options?.__isCompensation) {
|
|
4538
|
+
const compOpts = call.options;
|
|
4539
|
+
const tryCallNames = compOpts.__tryBlockCallNames || [];
|
|
4540
|
+
const compensationCalls = compOpts.__compensationCalls || [];
|
|
4541
|
+
const hasReturn = compOpts.__hasReturn;
|
|
4542
|
+
const catchBody = compOpts.__catchBody;
|
|
4543
|
+
const compIndex = ++transitionIndex;
|
|
4544
|
+
const compStateName = `compensation_${compIndex}`;
|
|
4545
|
+
const compActions = [];
|
|
4546
|
+
if (catchBody) {
|
|
4547
|
+
for (const innerStmt of catchBody.body) {
|
|
4548
|
+
if (t12.isReturnStatement(innerStmt)) continue;
|
|
4549
|
+
if (t12.isExpressionStatement(innerStmt)) {
|
|
4550
|
+
const innerExpr = innerStmt.expression;
|
|
4551
|
+
if (t12.isAssignmentExpression(innerExpr) && t12.isMemberExpression(innerExpr.left)) {
|
|
4552
|
+
const left = memberExprToString(innerExpr.left);
|
|
4553
|
+
if (left.startsWith(`${paramName}.`)) {
|
|
4554
|
+
const field = left.slice(paramName.length + 1);
|
|
4555
|
+
const valueExpr = expressionToIR(innerExpr.right, paramName);
|
|
4556
|
+
compActions.push({
|
|
4557
|
+
id: `auto_${++actionCounter.value}`,
|
|
4558
|
+
type: "set_field",
|
|
4559
|
+
mode: "auto",
|
|
4560
|
+
config: { field, expression: valueExpr }
|
|
4561
|
+
});
|
|
4562
|
+
}
|
|
4563
|
+
}
|
|
4564
|
+
if (t12.isAwaitExpression(innerExpr) && t12.isCallExpression(innerExpr.argument)) {
|
|
4565
|
+
const innerCall = innerExpr.argument;
|
|
4566
|
+
const fnName = t12.isIdentifier(innerCall.callee) ? innerCall.callee.name : null;
|
|
4567
|
+
if (fnName && importedFns.has(fnName)) {
|
|
4568
|
+
compActions.push({
|
|
4569
|
+
id: `auto_${++actionCounter.value}`,
|
|
4570
|
+
type: "call_workflow",
|
|
4571
|
+
mode: "auto",
|
|
4572
|
+
config: { definition_slug: fnNameToSlug(fnName), blocking: true }
|
|
4573
|
+
});
|
|
4574
|
+
}
|
|
4575
|
+
if (fnName === "log") {
|
|
4576
|
+
const event = innerCall.arguments[0] ? extractNodeValue2(innerCall.arguments[0]) : "";
|
|
4577
|
+
compActions.push({
|
|
4578
|
+
id: `auto_${++actionCounter.value}`,
|
|
4579
|
+
type: "log_event",
|
|
4580
|
+
mode: "auto",
|
|
4581
|
+
config: { event: String(event) }
|
|
4582
|
+
});
|
|
4583
|
+
}
|
|
4584
|
+
if (fnName === "notify") {
|
|
4585
|
+
const to = innerCall.arguments[0] ? expressionToIR(innerCall.arguments[0], paramName) : "";
|
|
4586
|
+
const message = innerCall.arguments[1] ? extractNodeValue2(innerCall.arguments[1]) : "";
|
|
4587
|
+
compActions.push({
|
|
4588
|
+
id: `auto_${++actionCounter.value}`,
|
|
4589
|
+
type: "send_notification",
|
|
4590
|
+
mode: "auto",
|
|
4591
|
+
config: { to: String(to), message: String(message) }
|
|
4592
|
+
});
|
|
4593
|
+
}
|
|
4594
|
+
if (fnName === "emit") {
|
|
4595
|
+
const event = innerCall.arguments[0] ? extractNodeValue2(innerCall.arguments[0]) : "";
|
|
4596
|
+
compActions.push({
|
|
4597
|
+
id: `auto_${++actionCounter.value}`,
|
|
4598
|
+
type: "emit_event",
|
|
4599
|
+
mode: "auto",
|
|
4600
|
+
config: { event: String(event) }
|
|
4601
|
+
});
|
|
4602
|
+
}
|
|
4603
|
+
}
|
|
4604
|
+
if (t12.isCallExpression(innerExpr)) {
|
|
4605
|
+
const fnName = t12.isIdentifier(innerExpr.callee) ? innerExpr.callee.name : null;
|
|
4606
|
+
if (fnName === "log") {
|
|
4607
|
+
const event = innerExpr.arguments[0] ? extractNodeValue2(innerExpr.arguments[0]) : "";
|
|
4608
|
+
compActions.push({
|
|
4609
|
+
id: `auto_${++actionCounter.value}`,
|
|
4610
|
+
type: "log_event",
|
|
4611
|
+
mode: "auto",
|
|
4612
|
+
config: { event: String(event) }
|
|
4613
|
+
});
|
|
4614
|
+
}
|
|
4615
|
+
if (fnName === "notify") {
|
|
4616
|
+
const to = innerExpr.arguments[0] ? expressionToIR(innerExpr.arguments[0], paramName) : "";
|
|
4617
|
+
const message = innerExpr.arguments[1] ? extractNodeValue2(innerExpr.arguments[1]) : "";
|
|
4618
|
+
compActions.push({
|
|
4619
|
+
id: `auto_${++actionCounter.value}`,
|
|
4620
|
+
type: "send_notification",
|
|
4621
|
+
mode: "auto",
|
|
4622
|
+
config: { to: String(to), message: String(message) }
|
|
4623
|
+
});
|
|
4624
|
+
}
|
|
4625
|
+
if (fnName === "emit") {
|
|
4626
|
+
const event = innerExpr.arguments[0] ? extractNodeValue2(innerExpr.arguments[0]) : "";
|
|
4627
|
+
compActions.push({
|
|
4628
|
+
id: `auto_${++actionCounter.value}`,
|
|
4629
|
+
type: "emit_event",
|
|
4630
|
+
mode: "auto",
|
|
4631
|
+
config: { event: String(event) }
|
|
4632
|
+
});
|
|
4633
|
+
}
|
|
4634
|
+
}
|
|
4635
|
+
}
|
|
4636
|
+
if (t12.isIfStatement(innerStmt) && t12.isBlockStatement(innerStmt.consequent)) {
|
|
4637
|
+
const condStr = expressionToIR(innerStmt.test, paramName);
|
|
4638
|
+
for (const ifInner of innerStmt.consequent.body) {
|
|
4639
|
+
if (t12.isExpressionStatement(ifInner)) {
|
|
4640
|
+
const ifExpr = ifInner.expression;
|
|
4641
|
+
if (t12.isAssignmentExpression(ifExpr) && t12.isMemberExpression(ifExpr.left)) {
|
|
4642
|
+
const left = memberExprToString(ifExpr.left);
|
|
4643
|
+
if (left.startsWith(`${paramName}.`)) {
|
|
4644
|
+
const field = left.slice(paramName.length + 1);
|
|
4645
|
+
const valueExpr = expressionToIR(ifExpr.right, paramName);
|
|
4646
|
+
compActions.push({
|
|
4647
|
+
id: `auto_${++actionCounter.value}`,
|
|
4648
|
+
type: "set_field",
|
|
4649
|
+
mode: "auto",
|
|
4650
|
+
config: { field, expression: valueExpr },
|
|
4651
|
+
condition: condStr
|
|
4652
|
+
});
|
|
4653
|
+
}
|
|
4654
|
+
}
|
|
4655
|
+
if (t12.isAwaitExpression(ifExpr) && t12.isCallExpression(ifExpr.argument)) {
|
|
4656
|
+
const ifCall = ifExpr.argument;
|
|
4657
|
+
const fnName = t12.isIdentifier(ifCall.callee) ? ifCall.callee.name : null;
|
|
4658
|
+
if (fnName && importedFns.has(fnName)) {
|
|
4659
|
+
compActions.push({
|
|
4660
|
+
id: `auto_${++actionCounter.value}`,
|
|
4661
|
+
type: "call_workflow",
|
|
4662
|
+
mode: "auto",
|
|
4663
|
+
config: { definition_slug: fnNameToSlug(fnName), blocking: true },
|
|
4664
|
+
condition: condStr
|
|
4665
|
+
});
|
|
4666
|
+
}
|
|
4667
|
+
}
|
|
4668
|
+
}
|
|
4669
|
+
}
|
|
4670
|
+
}
|
|
4671
|
+
}
|
|
4672
|
+
}
|
|
4673
|
+
for (const cc of compensationCalls) {
|
|
4674
|
+
if (cc.type === "serviceCall") {
|
|
4675
|
+
compActions.push({
|
|
4676
|
+
id: `auto_${++actionCounter.value}`,
|
|
4677
|
+
type: "call_workflow",
|
|
4678
|
+
mode: "auto",
|
|
4679
|
+
config: { definition_slug: fnNameToSlug(cc.name), blocking: true }
|
|
4680
|
+
});
|
|
4681
|
+
}
|
|
4682
|
+
}
|
|
4683
|
+
compilerState.states.set(compStateName, {
|
|
4684
|
+
name: compStateName,
|
|
4685
|
+
type: hasReturn ? "END" : "REGULAR",
|
|
4686
|
+
on_enter: compActions,
|
|
4687
|
+
during: [],
|
|
4688
|
+
on_exit: []
|
|
4689
|
+
});
|
|
4690
|
+
for (const tryCallName of tryCallNames) {
|
|
4691
|
+
let tryStateName;
|
|
4692
|
+
if (localFnNames.has(tryCallName)) {
|
|
4693
|
+
tryStateName = toSnakeCase2(tryCallName);
|
|
4694
|
+
} else if (importedFns.has(tryCallName)) {
|
|
4695
|
+
tryStateName = `awaiting_${toSnakeCase2(tryCallName)}`;
|
|
4696
|
+
} else {
|
|
4697
|
+
tryStateName = toSnakeCase2(tryCallName);
|
|
4698
|
+
}
|
|
4699
|
+
if (compilerState.states.has(tryStateName)) {
|
|
4700
|
+
compilerState.transitions.push({
|
|
4701
|
+
name: `error_to_${compStateName}`,
|
|
4702
|
+
from: [tryStateName],
|
|
4703
|
+
to: compStateName,
|
|
4704
|
+
conditions: [{ expression: "error != null" }],
|
|
4705
|
+
actions: [],
|
|
4706
|
+
auto: true
|
|
4707
|
+
});
|
|
4708
|
+
}
|
|
4709
|
+
}
|
|
4710
|
+
if (!hasReturn) {
|
|
4711
|
+
prevStateName = compStateName;
|
|
4712
|
+
}
|
|
4713
|
+
break;
|
|
4714
|
+
}
|
|
4715
|
+
referencedStates.add(call.name);
|
|
4716
|
+
if (!firstStateName) firstStateName = stateName;
|
|
4717
|
+
const info = stateFnInfos.get(call.name);
|
|
4718
|
+
if (info && !compilerState.states.has(stateName)) {
|
|
4719
|
+
compilerState.states.set(stateName, {
|
|
4720
|
+
name: stateName,
|
|
4721
|
+
type: !firstStateName || stateName === toSnakeCase2(callSequence[0]?.name || "") ? "START" : "REGULAR",
|
|
4722
|
+
on_enter: info.onEnter,
|
|
4723
|
+
during: info.during,
|
|
4724
|
+
on_exit: [],
|
|
4725
|
+
...info.onEvent.length > 0 ? { on_event: info.onEvent } : {},
|
|
4726
|
+
...info.timeout ? { timeout: info.timeout } : {},
|
|
4727
|
+
...info.runtime ? { runtime: info.runtime } : {}
|
|
4728
|
+
});
|
|
4729
|
+
} else if (!compilerState.states.has(stateName)) {
|
|
4730
|
+
compilerState.states.set(stateName, {
|
|
4731
|
+
name: stateName,
|
|
4732
|
+
type: "REGULAR",
|
|
4733
|
+
on_enter: [],
|
|
4734
|
+
during: [],
|
|
4735
|
+
on_exit: []
|
|
4736
|
+
});
|
|
4737
|
+
}
|
|
4738
|
+
if (prevStateName && prevStateName !== stateName) {
|
|
4739
|
+
const transName = call.transitionName || `to_${stateName}`;
|
|
4740
|
+
const conditions = [];
|
|
4741
|
+
if (call.condition) {
|
|
4742
|
+
conditions.push({ expression: call.condition });
|
|
4743
|
+
}
|
|
4744
|
+
if (info?.roles.length) {
|
|
4745
|
+
for (const role of info.roles) {
|
|
4746
|
+
conditions.push(roleCondition(role));
|
|
4747
|
+
}
|
|
4748
|
+
}
|
|
4749
|
+
compilerState.transitions.push({
|
|
4750
|
+
name: transName,
|
|
4751
|
+
from: [prevStateName],
|
|
4752
|
+
to: stateName,
|
|
4753
|
+
conditions: conditions.length > 0 ? conditions : void 0,
|
|
4754
|
+
actions: [],
|
|
4755
|
+
...info?.requiredFields.length ? { required_fields: info.requiredFields } : {},
|
|
4756
|
+
auto: true
|
|
4757
|
+
});
|
|
4758
|
+
}
|
|
4759
|
+
prevStateName = stateName;
|
|
4760
|
+
break;
|
|
4761
|
+
}
|
|
4762
|
+
case "userAction": {
|
|
4763
|
+
const awaitState = `awaiting_${call.name}`;
|
|
4764
|
+
if (!compilerState.states.has(awaitState)) {
|
|
4765
|
+
compilerState.states.set(awaitState, {
|
|
4766
|
+
name: awaitState,
|
|
4767
|
+
type: "REGULAR",
|
|
4768
|
+
on_enter: [],
|
|
4769
|
+
during: [],
|
|
4770
|
+
on_exit: []
|
|
4771
|
+
});
|
|
4772
|
+
}
|
|
4773
|
+
if (prevStateName) {
|
|
4774
|
+
compilerState.transitions.push({
|
|
4775
|
+
name: `to_${awaitState}`,
|
|
4776
|
+
from: [prevStateName],
|
|
4777
|
+
to: awaitState,
|
|
4778
|
+
actions: [],
|
|
4779
|
+
auto: true,
|
|
4780
|
+
...call.condition ? { conditions: [{ expression: call.condition }] } : {}
|
|
4781
|
+
});
|
|
4782
|
+
}
|
|
4783
|
+
const opts = call.options || {};
|
|
4784
|
+
const conditions = [];
|
|
4785
|
+
if (opts.roles && Array.isArray(opts.roles)) {
|
|
4786
|
+
for (const role of opts.roles) {
|
|
4787
|
+
conditions.push(roleCondition(role));
|
|
4788
|
+
}
|
|
4789
|
+
}
|
|
4790
|
+
if (opts.when && typeof opts.when === "string") {
|
|
4791
|
+
conditions.push({ expression: opts.when });
|
|
4792
|
+
}
|
|
4793
|
+
compilerState.transitions.push({
|
|
4794
|
+
name: call.name,
|
|
4795
|
+
from: [awaitState],
|
|
4796
|
+
to: "",
|
|
4797
|
+
// Will be resolved later (next state in sequence)
|
|
4798
|
+
conditions: conditions.length > 0 ? conditions : void 0,
|
|
4799
|
+
actions: [],
|
|
4800
|
+
...opts.require ? { required_fields: opts.require } : {}
|
|
4801
|
+
});
|
|
4802
|
+
prevStateName = awaitState;
|
|
4803
|
+
break;
|
|
4804
|
+
}
|
|
4805
|
+
case "userChoice": {
|
|
4806
|
+
const choiceState = prevStateName || "choice";
|
|
4807
|
+
if (call.choices) {
|
|
4808
|
+
for (const [optionName, optionConfig] of Object.entries(call.choices)) {
|
|
4809
|
+
const config = optionConfig;
|
|
4810
|
+
const conditions = [];
|
|
4811
|
+
if (config.roles && Array.isArray(config.roles)) {
|
|
4812
|
+
for (const role of config.roles) {
|
|
4813
|
+
conditions.push(roleCondition(role));
|
|
4814
|
+
}
|
|
4815
|
+
}
|
|
4816
|
+
if (config.when && typeof config.when === "string") {
|
|
4817
|
+
conditions.push({ expression: config.when });
|
|
4818
|
+
}
|
|
4819
|
+
compilerState.transitions.push({
|
|
4820
|
+
name: optionName,
|
|
4821
|
+
from: [choiceState],
|
|
4822
|
+
to: "",
|
|
4823
|
+
// Resolved by switch/case handling
|
|
4824
|
+
conditions: conditions.length > 0 ? conditions : void 0,
|
|
4825
|
+
actions: [],
|
|
4826
|
+
...config.require ? { required_fields: config.require } : {}
|
|
4827
|
+
});
|
|
4828
|
+
}
|
|
4829
|
+
}
|
|
4830
|
+
break;
|
|
4831
|
+
}
|
|
4832
|
+
case "serviceCall": {
|
|
4833
|
+
const serviceSlug = fnNameToSlug(call.name);
|
|
4834
|
+
const serviceState = `awaiting_${toSnakeCase2(call.name)}`;
|
|
4835
|
+
compilerState.states.set(serviceState, {
|
|
4836
|
+
name: serviceState,
|
|
4837
|
+
type: "REGULAR",
|
|
4838
|
+
on_enter: [{
|
|
4839
|
+
id: `auto_${++actionCounter.value}`,
|
|
4840
|
+
type: "call_workflow",
|
|
4841
|
+
mode: "auto",
|
|
4842
|
+
config: {
|
|
4843
|
+
definition_slug: serviceSlug,
|
|
4844
|
+
blocking: true
|
|
4845
|
+
}
|
|
4846
|
+
}],
|
|
4847
|
+
during: [],
|
|
4848
|
+
on_exit: []
|
|
4849
|
+
});
|
|
4850
|
+
if (prevStateName) {
|
|
4851
|
+
compilerState.transitions.push({
|
|
4852
|
+
name: `call_${toSnakeCase2(call.name)}`,
|
|
4853
|
+
from: [prevStateName],
|
|
4854
|
+
to: serviceState,
|
|
4855
|
+
actions: [],
|
|
4856
|
+
auto: true,
|
|
4857
|
+
...call.condition ? { conditions: [{ expression: call.condition }] } : {}
|
|
4858
|
+
});
|
|
4859
|
+
}
|
|
4860
|
+
prevStateName = serviceState;
|
|
4861
|
+
break;
|
|
4862
|
+
}
|
|
4863
|
+
case "awaitOn": {
|
|
4864
|
+
const eventState = `awaiting_${call.name}`;
|
|
4865
|
+
const opts = call.options || {};
|
|
4866
|
+
const eventPattern = opts.__eventPattern ? String(opts.__eventPattern) : call.name.replace(/_/g, ":");
|
|
4867
|
+
const awaitOnMetadata = {
|
|
4868
|
+
event_pattern: eventPattern
|
|
4869
|
+
};
|
|
4870
|
+
if (opts.when && typeof opts.when === "string") {
|
|
4871
|
+
awaitOnMetadata.event_condition = String(opts.when);
|
|
4872
|
+
}
|
|
4873
|
+
if (opts.timeout) {
|
|
4874
|
+
awaitOnMetadata.event_timeout = String(opts.timeout);
|
|
4875
|
+
}
|
|
4876
|
+
const awaitState = {
|
|
4877
|
+
name: eventState,
|
|
4878
|
+
type: "REGULAR",
|
|
4879
|
+
on_enter: [],
|
|
4880
|
+
during: [],
|
|
4881
|
+
on_exit: [],
|
|
4882
|
+
...opts.timeout ? { timeout: { duration: String(opts.timeout) } } : {}
|
|
4883
|
+
};
|
|
4884
|
+
if (awaitOnMetadata) awaitState.metadata = awaitOnMetadata;
|
|
4885
|
+
compilerState.states.set(eventState, awaitState);
|
|
4886
|
+
if (prevStateName) {
|
|
4887
|
+
compilerState.transitions.push({
|
|
4888
|
+
name: `await_${call.name}`,
|
|
4889
|
+
from: [prevStateName],
|
|
4890
|
+
to: eventState,
|
|
4891
|
+
actions: [],
|
|
4892
|
+
auto: true,
|
|
4893
|
+
...call.condition ? { conditions: [{ expression: call.condition }] } : {}
|
|
4894
|
+
});
|
|
4895
|
+
}
|
|
4896
|
+
const eventConditions = [];
|
|
4897
|
+
if (opts.when && typeof opts.when === "string") {
|
|
4898
|
+
eventConditions.push({ expression: String(opts.when) });
|
|
4899
|
+
}
|
|
4900
|
+
compilerState.transitions.push({
|
|
4901
|
+
name: `${call.name}_matched`,
|
|
4902
|
+
from: [eventState],
|
|
4903
|
+
to: "",
|
|
4904
|
+
// Resolved to next state
|
|
4905
|
+
conditions: eventConditions.length > 0 ? eventConditions : void 0,
|
|
4906
|
+
actions: [],
|
|
4907
|
+
auto: true
|
|
4908
|
+
});
|
|
4909
|
+
prevStateName = eventState;
|
|
4910
|
+
break;
|
|
4911
|
+
}
|
|
4912
|
+
case "promiseAll": {
|
|
4913
|
+
const parallelState = `parallel_${++transitionIndex}`;
|
|
4914
|
+
const parallelActions = [];
|
|
4915
|
+
for (const pc of call.parallelCalls || []) {
|
|
4916
|
+
if (pc.type === "serviceCall") {
|
|
4917
|
+
parallelActions.push({
|
|
4918
|
+
id: `auto_${++actionCounter.value}`,
|
|
4919
|
+
type: "call_workflow",
|
|
4920
|
+
mode: "auto",
|
|
4921
|
+
config: {
|
|
4922
|
+
definition_slug: fnNameToSlug(pc.name),
|
|
4923
|
+
blocking: true
|
|
4924
|
+
}
|
|
4925
|
+
});
|
|
4926
|
+
}
|
|
4927
|
+
}
|
|
4928
|
+
compilerState.states.set(parallelState, {
|
|
4929
|
+
name: parallelState,
|
|
4930
|
+
type: "REGULAR",
|
|
4931
|
+
on_enter: parallelActions,
|
|
4932
|
+
during: [],
|
|
4933
|
+
on_exit: []
|
|
4934
|
+
});
|
|
4935
|
+
if (prevStateName) {
|
|
4936
|
+
compilerState.transitions.push({
|
|
4937
|
+
name: `to_${parallelState}`,
|
|
4938
|
+
from: [prevStateName],
|
|
4939
|
+
to: parallelState,
|
|
4940
|
+
actions: [],
|
|
4941
|
+
auto: true
|
|
4942
|
+
});
|
|
4943
|
+
}
|
|
4944
|
+
prevStateName = parallelState;
|
|
4945
|
+
break;
|
|
4946
|
+
}
|
|
4947
|
+
case "delay": {
|
|
4948
|
+
const delayState = `delay_${++transitionIndex}`;
|
|
4949
|
+
const durationMatch = call.name.match(/delay_(.+)/);
|
|
4950
|
+
const duration = durationMatch ? durationMatch[1] : "0";
|
|
4951
|
+
compilerState.states.set(delayState, {
|
|
4952
|
+
name: delayState,
|
|
4953
|
+
type: "REGULAR",
|
|
4954
|
+
on_enter: [],
|
|
4955
|
+
during: [],
|
|
4956
|
+
on_exit: [],
|
|
4957
|
+
timeout: { duration, fallback: {} }
|
|
4958
|
+
});
|
|
4959
|
+
if (prevStateName) {
|
|
4960
|
+
compilerState.transitions.push({
|
|
4961
|
+
name: `to_${delayState}`,
|
|
4962
|
+
from: [prevStateName],
|
|
4963
|
+
to: delayState,
|
|
4964
|
+
actions: [],
|
|
4965
|
+
auto: true
|
|
4966
|
+
});
|
|
4967
|
+
}
|
|
4968
|
+
prevStateName = delayState;
|
|
4969
|
+
break;
|
|
4970
|
+
}
|
|
4971
|
+
}
|
|
4972
|
+
}
|
|
4973
|
+
if (prevStateName && compilerState.states.has(prevStateName)) {
|
|
4974
|
+
const lastState = compilerState.states.get(prevStateName);
|
|
4975
|
+
const hasOutgoing = compilerState.transitions.some((t23) => t23.from.includes(prevStateName));
|
|
4976
|
+
if (!hasOutgoing) {
|
|
4977
|
+
lastState.type = "END";
|
|
4978
|
+
}
|
|
4979
|
+
}
|
|
4980
|
+
if (firstStateName && compilerState.states.has(firstStateName)) {
|
|
4981
|
+
compilerState.states.get(firstStateName).type = "START";
|
|
4982
|
+
}
|
|
4983
|
+
for (let i = 0; i < compilerState.transitions.length; i++) {
|
|
4984
|
+
const trans = compilerState.transitions[i];
|
|
4985
|
+
if (trans.to === "" && i + 1 < compilerState.transitions.length) {
|
|
4986
|
+
const nextTrans = compilerState.transitions[i + 1];
|
|
4987
|
+
if (nextTrans.to) {
|
|
4988
|
+
trans.to = nextTrans.to;
|
|
4989
|
+
} else if (nextTrans.from.length > 0) {
|
|
4990
|
+
}
|
|
4991
|
+
}
|
|
4992
|
+
}
|
|
4993
|
+
const stateSequence = callSequence.filter((c) => c.type === "stateCall" || c.type === "serviceCall" || c.type === "userAction" || c.type === "awaitOn").map((c) => {
|
|
4994
|
+
if (c.type === "stateCall") return toSnakeCase2(c.name);
|
|
4995
|
+
if (c.type === "userAction") return `awaiting_${c.name}`;
|
|
4996
|
+
if (c.type === "serviceCall") return `awaiting_${toSnakeCase2(c.name)}`;
|
|
4997
|
+
if (c.type === "awaitOn") return `awaiting_${c.name}`;
|
|
4998
|
+
return c.name;
|
|
4999
|
+
});
|
|
5000
|
+
for (const trans of compilerState.transitions) {
|
|
5001
|
+
if (trans.to === "") {
|
|
5002
|
+
const fromState = trans.from[0];
|
|
5003
|
+
const idx = stateSequence.indexOf(fromState);
|
|
5004
|
+
if (idx >= 0 && idx + 1 < stateSequence.length) {
|
|
5005
|
+
trans.to = stateSequence[idx + 1];
|
|
5006
|
+
}
|
|
5007
|
+
}
|
|
5008
|
+
}
|
|
5009
|
+
for (const at of allowTransitions) {
|
|
5010
|
+
const resolvedTo = at.to === "$self" ? "__self__" : toSnakeCase2(at.to);
|
|
5011
|
+
const resolvedFrom = at.from.map((f) => toSnakeCase2(f));
|
|
5012
|
+
const conditions = [];
|
|
5013
|
+
if (at.roles) {
|
|
5014
|
+
for (const role of at.roles) {
|
|
5015
|
+
conditions.push(roleCondition(role));
|
|
5016
|
+
}
|
|
5017
|
+
}
|
|
5018
|
+
if (at.when) {
|
|
5019
|
+
conditions.push({ expression: at.when });
|
|
5020
|
+
}
|
|
5021
|
+
if (resolvedTo !== "__self__" && !compilerState.states.has(resolvedTo)) {
|
|
5022
|
+
compilerState.states.set(resolvedTo, {
|
|
5023
|
+
name: resolvedTo,
|
|
5024
|
+
type: "REGULAR",
|
|
5025
|
+
on_enter: [],
|
|
5026
|
+
during: [],
|
|
5027
|
+
on_exit: []
|
|
5028
|
+
});
|
|
5029
|
+
}
|
|
5030
|
+
if (resolvedTo === "__self__") {
|
|
5031
|
+
for (const from of resolvedFrom) {
|
|
5032
|
+
compilerState.transitions.push({
|
|
5033
|
+
name: at.name,
|
|
5034
|
+
from: [from],
|
|
5035
|
+
to: from,
|
|
5036
|
+
conditions: conditions.length > 0 ? conditions : void 0,
|
|
5037
|
+
actions: [],
|
|
5038
|
+
...at.require ? { required_fields: at.require } : {}
|
|
5039
|
+
});
|
|
5040
|
+
}
|
|
5041
|
+
} else {
|
|
5042
|
+
compilerState.transitions.push({
|
|
5043
|
+
name: at.name,
|
|
5044
|
+
from: resolvedFrom,
|
|
5045
|
+
to: resolvedTo,
|
|
5046
|
+
conditions: conditions.length > 0 ? conditions : void 0,
|
|
5047
|
+
actions: [],
|
|
5048
|
+
...at.require ? { required_fields: at.require } : {}
|
|
5049
|
+
});
|
|
5050
|
+
}
|
|
5051
|
+
}
|
|
5052
|
+
for (const [, info] of stateFnInfos) {
|
|
5053
|
+
for (const v of info.validations) {
|
|
5054
|
+
if (v.field === "__cross__") continue;
|
|
5055
|
+
const field = compilerState.fields.find((f) => f.name === v.field);
|
|
5056
|
+
if (field) {
|
|
5057
|
+
if (!field.validation) field.validation = {};
|
|
5058
|
+
Object.assign(field.validation, v.validation);
|
|
5059
|
+
if (v.validation.rules) {
|
|
5060
|
+
if (!field.validation.rules) field.validation.rules = [];
|
|
5061
|
+
field.validation.rules.push(...v.validation.rules);
|
|
5062
|
+
}
|
|
5063
|
+
}
|
|
5064
|
+
}
|
|
5065
|
+
}
|
|
5066
|
+
for (const node of path.node.body) {
|
|
5067
|
+
if (t12.isExportNamedDeclaration(node) && t12.isVariableDeclaration(node.declaration)) {
|
|
5068
|
+
for (const decl of node.declaration.declarations) {
|
|
5069
|
+
if (t12.isIdentifier(decl.id) && decl.id.name === "roles" && decl.init) {
|
|
5070
|
+
let rolesObj = null;
|
|
5071
|
+
if (t12.isCallExpression(decl.init) && t12.isIdentifier(decl.init.callee) && decl.init.callee.name === "defineRoles" && t12.isObjectExpression(decl.init.arguments[0])) {
|
|
5072
|
+
rolesObj = decl.init.arguments[0];
|
|
5073
|
+
} else if (t12.isObjectExpression(decl.init)) {
|
|
5074
|
+
rolesObj = decl.init;
|
|
5075
|
+
}
|
|
5076
|
+
if (rolesObj) {
|
|
5077
|
+
const roles = extractNodeValue2(rolesObj);
|
|
5078
|
+
if (!compilerState.metadata.roles) compilerState.metadata.roles = {};
|
|
5079
|
+
for (const [roleName, roleConfig] of Object.entries(roles)) {
|
|
5080
|
+
compilerState.metadata.roles[roleName] = roleConfig;
|
|
5081
|
+
}
|
|
5082
|
+
}
|
|
5083
|
+
}
|
|
5084
|
+
if (t12.isIdentifier(decl.id) && decl.id.name === "fieldAccess" && t12.isObjectExpression(decl.init)) {
|
|
5085
|
+
const access = extractNodeValue2(decl.init);
|
|
5086
|
+
for (const [fieldName, config] of Object.entries(access)) {
|
|
5087
|
+
const field = compilerState.fields.find((f) => f.name === fieldName);
|
|
5088
|
+
if (field) {
|
|
5089
|
+
if (config.visibleTo) field.visible_to_roles = config.visibleTo;
|
|
5090
|
+
if (config.editableBy) field.editable_by_roles = config.editableBy;
|
|
5091
|
+
if (config.editableIn) field.editable_in_states = config.editableIn;
|
|
5092
|
+
}
|
|
5093
|
+
}
|
|
5094
|
+
}
|
|
5095
|
+
if (t12.isIdentifier(decl.id) && decl.id.name === "config" && decl.init) {
|
|
5096
|
+
if (t12.isCallExpression(decl.init) && t12.isIdentifier(decl.init.callee) && decl.init.callee.name === "orchestration" && t12.isObjectExpression(decl.init.arguments[0])) {
|
|
5097
|
+
compilerState.metadata.orchestration = extractNodeValue2(decl.init.arguments[0]);
|
|
5098
|
+
}
|
|
5099
|
+
}
|
|
5100
|
+
}
|
|
5101
|
+
}
|
|
5102
|
+
}
|
|
5103
|
+
for (const node of path.node.body) {
|
|
5104
|
+
if (t12.isExportNamedDeclaration(node) && t12.isVariableDeclaration(node.declaration)) {
|
|
5105
|
+
for (const decl of node.declaration.declarations) {
|
|
5106
|
+
if (t12.isIdentifier(decl.id) && decl.id.name === "fields" && t12.isObjectExpression(decl.init)) {
|
|
5107
|
+
const fieldsConfig = extractNodeValue2(decl.init);
|
|
5108
|
+
for (const [name, config] of Object.entries(fieldsConfig)) {
|
|
5109
|
+
const field = compilerState.fields.find((f) => f.name === name);
|
|
5110
|
+
if (!field) continue;
|
|
5111
|
+
if (typeof config === "string") {
|
|
5112
|
+
if (config.includes("!")) field.required = true;
|
|
5113
|
+
} else if (typeof config === "object" && config !== null) {
|
|
5114
|
+
const cfg = config;
|
|
5115
|
+
if (cfg.required) field.required = true;
|
|
5116
|
+
if (cfg.min !== void 0 || cfg.max !== void 0 || cfg.minLength !== void 0 || cfg.maxLength !== void 0 || cfg.pattern !== void 0) {
|
|
5117
|
+
if (!field.validation) field.validation = {};
|
|
5118
|
+
if (cfg.min !== void 0) field.validation.min = Number(cfg.min);
|
|
5119
|
+
if (cfg.max !== void 0) field.validation.max = Number(cfg.max);
|
|
5120
|
+
if (cfg.minLength !== void 0) field.validation.minLength = Number(cfg.minLength);
|
|
5121
|
+
if (cfg.maxLength !== void 0) field.validation.maxLength = Number(cfg.maxLength);
|
|
5122
|
+
if (cfg.pattern !== void 0) {
|
|
5123
|
+
if (!field.validation.rules) field.validation.rules = [];
|
|
5124
|
+
field.validation.rules.push({
|
|
5125
|
+
expression: `MATCHES(value, "${String(cfg.pattern)}")`,
|
|
5126
|
+
message: "Invalid format",
|
|
5127
|
+
severity: "error"
|
|
5128
|
+
});
|
|
5129
|
+
}
|
|
5130
|
+
}
|
|
5131
|
+
if (cfg.default !== void 0) field.default_value = cfg.default;
|
|
5132
|
+
}
|
|
5133
|
+
}
|
|
5134
|
+
}
|
|
5135
|
+
}
|
|
5136
|
+
}
|
|
5137
|
+
}
|
|
5138
|
+
compilerState.transitions = compilerState.transitions.filter((t23) => t23.to !== "");
|
|
5139
|
+
for (const trans of compilerState.transitions) {
|
|
5140
|
+
for (const from of trans.from) {
|
|
5141
|
+
if (!compilerState.states.has(from)) {
|
|
5142
|
+
compilerState.states.set(from, {
|
|
5143
|
+
name: from,
|
|
5144
|
+
type: "REGULAR",
|
|
5145
|
+
on_enter: [],
|
|
5146
|
+
during: [],
|
|
5147
|
+
on_exit: []
|
|
5148
|
+
});
|
|
5149
|
+
}
|
|
5150
|
+
}
|
|
5151
|
+
if (!compilerState.states.has(trans.to)) {
|
|
5152
|
+
compilerState.states.set(trans.to, {
|
|
5153
|
+
name: trans.to,
|
|
5154
|
+
type: "REGULAR",
|
|
5155
|
+
on_enter: [],
|
|
5156
|
+
during: [],
|
|
5157
|
+
on_exit: []
|
|
5158
|
+
});
|
|
5159
|
+
}
|
|
5160
|
+
}
|
|
5161
|
+
compilerState.actionCounter = actionCounter.value;
|
|
5162
|
+
}
|
|
5163
|
+
var t12, VALIDATION_FNS, TS_TYPE_MAP, NAME_TYPE_MAP;
|
|
5164
|
+
var init_flow_extractor = __esm({
|
|
5165
|
+
"src/babel/extractors/flow-extractor.ts"() {
|
|
5166
|
+
"use strict";
|
|
5167
|
+
t12 = __toESM(require("@babel/types"));
|
|
5168
|
+
init_workflow_shorthand();
|
|
5169
|
+
VALIDATION_FNS = /* @__PURE__ */ new Set(["validate", "assert"]);
|
|
5170
|
+
TS_TYPE_MAP = {
|
|
5171
|
+
Date: "datetime",
|
|
5172
|
+
Record: "json",
|
|
5173
|
+
Map: "json",
|
|
5174
|
+
Set: "json",
|
|
5175
|
+
URL: "url"
|
|
5176
|
+
};
|
|
5177
|
+
NAME_TYPE_MAP = {
|
|
5178
|
+
email: "email",
|
|
5179
|
+
url: "url",
|
|
5180
|
+
website: "url",
|
|
5181
|
+
phone: "phone"
|
|
5182
|
+
};
|
|
5183
|
+
}
|
|
5184
|
+
});
|
|
5185
|
+
|
|
3312
5186
|
// src/babel/extractors/server-action-extractor.ts
|
|
3313
5187
|
function isServerActionFile(filename) {
|
|
3314
5188
|
if (!filename) return false;
|
|
@@ -3318,9 +5192,9 @@ function extractServerActions(path, state) {
|
|
|
3318
5192
|
const compilerState = state;
|
|
3319
5193
|
const serverActions = [];
|
|
3320
5194
|
for (const node of path.node.body) {
|
|
3321
|
-
if (
|
|
5195
|
+
if (t13.isExportNamedDeclaration(node)) {
|
|
3322
5196
|
const decl = node.declaration;
|
|
3323
|
-
if (
|
|
5197
|
+
if (t13.isFunctionDeclaration(decl) && decl.id) {
|
|
3324
5198
|
const action = extractFunctionAction(decl);
|
|
3325
5199
|
if (action) {
|
|
3326
5200
|
const comments = node.leadingComments || decl.leadingComments || [];
|
|
@@ -3328,19 +5202,19 @@ function extractServerActions(path, state) {
|
|
|
3328
5202
|
serverActions.push(action);
|
|
3329
5203
|
}
|
|
3330
5204
|
}
|
|
3331
|
-
if (
|
|
5205
|
+
if (t13.isVariableDeclaration(decl)) {
|
|
3332
5206
|
for (const varDecl of decl.declarations) {
|
|
3333
|
-
if (!
|
|
5207
|
+
if (!t13.isIdentifier(varDecl.id)) continue;
|
|
3334
5208
|
const init = varDecl.init;
|
|
3335
|
-
if (
|
|
5209
|
+
if (t13.isArrowFunctionExpression(init) || t13.isFunctionExpression(init)) {
|
|
3336
5210
|
const action = {
|
|
3337
5211
|
name: varDecl.id.name,
|
|
3338
5212
|
async: init.async || false,
|
|
3339
|
-
params: init.params.filter((p) =>
|
|
5213
|
+
params: init.params.filter((p) => t13.isIdentifier(p)).map((p) => p.name)
|
|
3340
5214
|
};
|
|
3341
5215
|
if (init.params.length > 0) {
|
|
3342
5216
|
const firstParam = init.params[0];
|
|
3343
|
-
if (
|
|
5217
|
+
if (t13.isIdentifier(firstParam) && firstParam.typeAnnotation) {
|
|
3344
5218
|
action.contextType = extractTypeName(firstParam.typeAnnotation);
|
|
3345
5219
|
}
|
|
3346
5220
|
}
|
|
@@ -3360,20 +5234,20 @@ function extractFunctionAction(decl) {
|
|
|
3360
5234
|
const action = {
|
|
3361
5235
|
name: decl.id.name,
|
|
3362
5236
|
async: decl.async || false,
|
|
3363
|
-
params: decl.params.filter((p) =>
|
|
5237
|
+
params: decl.params.filter((p) => t13.isIdentifier(p)).map((p) => p.name)
|
|
3364
5238
|
};
|
|
3365
5239
|
if (decl.params.length > 0) {
|
|
3366
5240
|
const firstParam = decl.params[0];
|
|
3367
|
-
if (
|
|
5241
|
+
if (t13.isIdentifier(firstParam) && firstParam.typeAnnotation) {
|
|
3368
5242
|
action.contextType = extractTypeName(firstParam.typeAnnotation);
|
|
3369
5243
|
}
|
|
3370
5244
|
}
|
|
3371
5245
|
return action;
|
|
3372
5246
|
}
|
|
3373
5247
|
function extractTypeName(annotation) {
|
|
3374
|
-
if (
|
|
5248
|
+
if (t13.isTSTypeAnnotation(annotation)) {
|
|
3375
5249
|
const typeNode = annotation.typeAnnotation;
|
|
3376
|
-
if (
|
|
5250
|
+
if (t13.isTSTypeReference(typeNode) && t13.isIdentifier(typeNode.typeName)) {
|
|
3377
5251
|
return typeNode.typeName.name;
|
|
3378
5252
|
}
|
|
3379
5253
|
}
|
|
@@ -3392,11 +5266,11 @@ function extractDescription(comments) {
|
|
|
3392
5266
|
}
|
|
3393
5267
|
return void 0;
|
|
3394
5268
|
}
|
|
3395
|
-
var
|
|
5269
|
+
var t13;
|
|
3396
5270
|
var init_server_action_extractor = __esm({
|
|
3397
5271
|
"src/babel/extractors/server-action-extractor.ts"() {
|
|
3398
5272
|
"use strict";
|
|
3399
|
-
|
|
5273
|
+
t13 = __toESM(require("@babel/types"));
|
|
3400
5274
|
}
|
|
3401
5275
|
});
|
|
3402
5276
|
|
|
@@ -3405,21 +5279,21 @@ function extractServerActionHook(path, state) {
|
|
|
3405
5279
|
const args = path.node.arguments;
|
|
3406
5280
|
if (args.length < 1) return;
|
|
3407
5281
|
const nameArg = args[0];
|
|
3408
|
-
if (!
|
|
5282
|
+
if (!t14.isStringLiteral(nameArg)) return;
|
|
3409
5283
|
const compilerState = state;
|
|
3410
5284
|
const entry = {
|
|
3411
5285
|
name: nameArg.value
|
|
3412
5286
|
};
|
|
3413
|
-
if (args.length > 1 &&
|
|
5287
|
+
if (args.length > 1 && t14.isObjectExpression(args[1])) {
|
|
3414
5288
|
for (const prop of args[1].properties) {
|
|
3415
|
-
if (!
|
|
3416
|
-
if (prop.key.name === "instanceId" &&
|
|
5289
|
+
if (!t14.isObjectProperty(prop) || !t14.isIdentifier(prop.key)) continue;
|
|
5290
|
+
if (prop.key.name === "instanceId" && t14.isStringLiteral(prop.value)) {
|
|
3417
5291
|
entry.staticInstanceId = prop.value.value;
|
|
3418
5292
|
}
|
|
3419
5293
|
}
|
|
3420
5294
|
}
|
|
3421
5295
|
const parent = path.parentPath;
|
|
3422
|
-
if (parent?.isVariableDeclarator() &&
|
|
5296
|
+
if (parent?.isVariableDeclarator() && t14.isIdentifier(parent.node.id)) {
|
|
3423
5297
|
entry.variableName = parent.node.id.name;
|
|
3424
5298
|
}
|
|
3425
5299
|
if (!compilerState.metadata) compilerState.metadata = {};
|
|
@@ -3427,11 +5301,11 @@ function extractServerActionHook(path, state) {
|
|
|
3427
5301
|
if (!meta.serverActionHooks) meta.serverActionHooks = [];
|
|
3428
5302
|
meta.serverActionHooks.push(entry);
|
|
3429
5303
|
}
|
|
3430
|
-
var
|
|
5304
|
+
var t14;
|
|
3431
5305
|
var init_server_action_hook_extractor = __esm({
|
|
3432
5306
|
"src/babel/extractors/server-action-hook-extractor.ts"() {
|
|
3433
5307
|
"use strict";
|
|
3434
|
-
|
|
5308
|
+
t14 = __toESM(require("@babel/types"));
|
|
3435
5309
|
}
|
|
3436
5310
|
});
|
|
3437
5311
|
|
|
@@ -3442,23 +5316,23 @@ function extractServerState(path, state) {
|
|
|
3442
5316
|
const compilerState = state;
|
|
3443
5317
|
const entry = {};
|
|
3444
5318
|
const instanceArg = args[0];
|
|
3445
|
-
if (
|
|
5319
|
+
if (t15.isStringLiteral(instanceArg)) {
|
|
3446
5320
|
entry.staticInstanceId = instanceArg.value;
|
|
3447
5321
|
}
|
|
3448
|
-
if (args.length > 1 &&
|
|
5322
|
+
if (args.length > 1 && t15.isObjectExpression(args[1])) {
|
|
3449
5323
|
for (const prop of args[1].properties) {
|
|
3450
|
-
if (!
|
|
3451
|
-
if (prop.key.name === "enabled" &&
|
|
5324
|
+
if (!t15.isObjectProperty(prop) || !t15.isIdentifier(prop.key)) continue;
|
|
5325
|
+
if (prop.key.name === "enabled" && t15.isBooleanLiteral(prop.value)) {
|
|
3452
5326
|
if (!prop.value.value) entry.disabled = true;
|
|
3453
5327
|
}
|
|
3454
5328
|
}
|
|
3455
5329
|
}
|
|
3456
5330
|
const parent = path.parentPath;
|
|
3457
5331
|
if (parent?.isVariableDeclarator()) {
|
|
3458
|
-
if (
|
|
5332
|
+
if (t15.isIdentifier(parent.node.id)) {
|
|
3459
5333
|
entry.variableName = parent.node.id.name;
|
|
3460
|
-
} else if (
|
|
3461
|
-
const props = parent.node.id.properties.filter((p) =>
|
|
5334
|
+
} else if (t15.isObjectPattern(parent.node.id)) {
|
|
5335
|
+
const props = parent.node.id.properties.filter((p) => t15.isObjectProperty(p) && t15.isIdentifier(p.key)).map((p) => p.key.name);
|
|
3462
5336
|
if (props.length > 0) {
|
|
3463
5337
|
entry.variableName = props.join(", ");
|
|
3464
5338
|
}
|
|
@@ -3470,11 +5344,11 @@ function extractServerState(path, state) {
|
|
|
3470
5344
|
meta.serverStateSubscriptions.push(entry);
|
|
3471
5345
|
meta.requiresSSE = true;
|
|
3472
5346
|
}
|
|
3473
|
-
var
|
|
5347
|
+
var t15;
|
|
3474
5348
|
var init_server_state_extractor = __esm({
|
|
3475
5349
|
"src/babel/extractors/server-state-extractor.ts"() {
|
|
3476
5350
|
"use strict";
|
|
3477
|
-
|
|
5351
|
+
t15 = __toESM(require("@babel/types"));
|
|
3478
5352
|
}
|
|
3479
5353
|
});
|
|
3480
5354
|
|
|
@@ -3558,7 +5432,7 @@ function parseDmn(source) {
|
|
|
3558
5432
|
}
|
|
3559
5433
|
function extractGrammarIsland(path, state, slug) {
|
|
3560
5434
|
const tag = path.node.tag;
|
|
3561
|
-
if (!
|
|
5435
|
+
if (!t16.isIdentifier(tag)) return;
|
|
3562
5436
|
const tagName = tag.name;
|
|
3563
5437
|
if (!GRAMMAR_TAGS.has(tagName)) return;
|
|
3564
5438
|
const compilerState = state;
|
|
@@ -3568,7 +5442,7 @@ function extractGrammarIsland(path, state, slug) {
|
|
|
3568
5442
|
rawSource += quasi.quasis[i].value.raw;
|
|
3569
5443
|
if (i < quasi.expressions.length) {
|
|
3570
5444
|
const expr = quasi.expressions[i];
|
|
3571
|
-
if (
|
|
5445
|
+
if (t16.isIdentifier(expr)) {
|
|
3572
5446
|
rawSource += `\${${expr.name}}`;
|
|
3573
5447
|
} else {
|
|
3574
5448
|
rawSource += `\${expr_${i}}`;
|
|
@@ -3608,186 +5482,748 @@ function extractGrammarIsland(path, state, slug) {
|
|
|
3608
5482
|
if (!meta.grammarIslands) meta.grammarIslands = [];
|
|
3609
5483
|
meta.grammarIslands.push(island);
|
|
3610
5484
|
}
|
|
3611
|
-
function extractGrammarIslands(path, state) {
|
|
3612
|
-
path.traverse({
|
|
3613
|
-
TaggedTemplateExpression(templatePath) {
|
|
3614
|
-
const tag = templatePath.node.tag;
|
|
3615
|
-
if (!
|
|
3616
|
-
let slug = "unnamed";
|
|
3617
|
-
const parent = templatePath.parentPath;
|
|
3618
|
-
if (parent && parent.isVariableDeclarator() &&
|
|
3619
|
-
slug = parent.node.id.name;
|
|
3620
|
-
}
|
|
3621
|
-
if (parent && parent.isObjectProperty() &&
|
|
3622
|
-
slug = parent.node.key.name;
|
|
5485
|
+
function extractGrammarIslands(path, state) {
|
|
5486
|
+
path.traverse({
|
|
5487
|
+
TaggedTemplateExpression(templatePath) {
|
|
5488
|
+
const tag = templatePath.node.tag;
|
|
5489
|
+
if (!t16.isIdentifier(tag) || !GRAMMAR_TAGS.has(tag.name)) return;
|
|
5490
|
+
let slug = "unnamed";
|
|
5491
|
+
const parent = templatePath.parentPath;
|
|
5492
|
+
if (parent && parent.isVariableDeclarator() && t16.isIdentifier(parent.node.id)) {
|
|
5493
|
+
slug = parent.node.id.name;
|
|
5494
|
+
}
|
|
5495
|
+
if (parent && parent.isObjectProperty() && t16.isIdentifier(parent.node.key)) {
|
|
5496
|
+
slug = parent.node.key.name;
|
|
5497
|
+
}
|
|
5498
|
+
if (parent && parent.isObjectProperty() && t16.isStringLiteral(parent.node.key)) {
|
|
5499
|
+
slug = parent.node.key.value;
|
|
5500
|
+
}
|
|
5501
|
+
extractGrammarIsland(templatePath, state, slug);
|
|
5502
|
+
}
|
|
5503
|
+
});
|
|
5504
|
+
}
|
|
5505
|
+
var t16, GRAMMAR_TAGS;
|
|
5506
|
+
var init_grammar_island_extractor = __esm({
|
|
5507
|
+
"src/babel/extractors/grammar-island-extractor.ts"() {
|
|
5508
|
+
"use strict";
|
|
5509
|
+
t16 = __toESM(require("@babel/types"));
|
|
5510
|
+
GRAMMAR_TAGS = /* @__PURE__ */ new Set(["cedar", "sql", "cron", "dmn", "graphql", "jsonpath"]);
|
|
5511
|
+
}
|
|
5512
|
+
});
|
|
5513
|
+
|
|
5514
|
+
// src/babel/extractors/context-extractor.ts
|
|
5515
|
+
function hasContextCreation(path) {
|
|
5516
|
+
let found = false;
|
|
5517
|
+
path.traverse({
|
|
5518
|
+
CallExpression(callPath) {
|
|
5519
|
+
if (t17.isIdentifier(callPath.node.callee, { name: "createContext" })) {
|
|
5520
|
+
found = true;
|
|
5521
|
+
callPath.stop();
|
|
5522
|
+
}
|
|
5523
|
+
}
|
|
5524
|
+
});
|
|
5525
|
+
return found;
|
|
5526
|
+
}
|
|
5527
|
+
function extractContextWorkflows(path, state) {
|
|
5528
|
+
const compilerState = state;
|
|
5529
|
+
const contextWorkflows = [];
|
|
5530
|
+
const contextNames = /* @__PURE__ */ new Map();
|
|
5531
|
+
path.traverse({
|
|
5532
|
+
// Detect: const XContext = createContext(...)
|
|
5533
|
+
VariableDeclarator(declPath) {
|
|
5534
|
+
const init = declPath.node.init;
|
|
5535
|
+
if (!init || !t17.isCallExpression(init)) return;
|
|
5536
|
+
if (!t17.isIdentifier(init.callee, { name: "createContext" })) return;
|
|
5537
|
+
if (!t17.isIdentifier(declPath.node.id)) return;
|
|
5538
|
+
const contextName = declPath.node.id.name;
|
|
5539
|
+
contextNames.set(contextName, contextName);
|
|
5540
|
+
const workflow = {
|
|
5541
|
+
name: contextName,
|
|
5542
|
+
fields: [],
|
|
5543
|
+
reducerActions: []
|
|
5544
|
+
};
|
|
5545
|
+
const typeParams = init.typeParameters;
|
|
5546
|
+
if (typeParams && t17.isTSTypeParameterInstantiation(typeParams)) {
|
|
5547
|
+
const typeArg = typeParams.params[0];
|
|
5548
|
+
if (t17.isTSTypeReference(typeArg) && t17.isIdentifier(typeArg.typeName)) {
|
|
5549
|
+
const interfaceName = typeArg.typeName.name;
|
|
5550
|
+
extractFieldsFromInterface3(path, interfaceName, workflow);
|
|
5551
|
+
}
|
|
5552
|
+
}
|
|
5553
|
+
if (init.arguments.length > 0 && t17.isObjectExpression(init.arguments[0])) {
|
|
5554
|
+
workflow.initialState = extractObjectLiteral2(init.arguments[0]);
|
|
5555
|
+
}
|
|
5556
|
+
contextWorkflows.push(workflow);
|
|
5557
|
+
},
|
|
5558
|
+
// Detect useReducer(reducer, initialState) and extract reducer cases
|
|
5559
|
+
CallExpression(callPath) {
|
|
5560
|
+
if (!t17.isIdentifier(callPath.node.callee, { name: "useReducer" })) return;
|
|
5561
|
+
const args = callPath.node.arguments;
|
|
5562
|
+
if (args.length < 1) return;
|
|
5563
|
+
const reducerArg = args[0];
|
|
5564
|
+
if (!t17.isIdentifier(reducerArg)) return;
|
|
5565
|
+
const reducerName = reducerArg.name;
|
|
5566
|
+
const actions = extractReducerActions(path, reducerName);
|
|
5567
|
+
if (contextWorkflows.length > 0) {
|
|
5568
|
+
const lastWorkflow = contextWorkflows[contextWorkflows.length - 1];
|
|
5569
|
+
lastWorkflow.reducerActions = actions;
|
|
5570
|
+
lastWorkflow.reducerName = reducerName;
|
|
5571
|
+
}
|
|
5572
|
+
}
|
|
5573
|
+
});
|
|
5574
|
+
if (contextWorkflows.length > 0) {
|
|
5575
|
+
if (!compilerState.metadata) compilerState.metadata = {};
|
|
5576
|
+
const meta = compilerState.metadata;
|
|
5577
|
+
meta.contextWorkflows = contextWorkflows;
|
|
5578
|
+
}
|
|
5579
|
+
}
|
|
5580
|
+
function extractFieldsFromInterface3(path, interfaceName, workflow) {
|
|
5581
|
+
path.traverse({
|
|
5582
|
+
TSInterfaceDeclaration(ifacePath) {
|
|
5583
|
+
if (!t17.isIdentifier(ifacePath.node.id, { name: interfaceName })) return;
|
|
5584
|
+
for (const prop of ifacePath.node.body.body) {
|
|
5585
|
+
if (!t17.isTSPropertySignature(prop)) continue;
|
|
5586
|
+
if (!t17.isIdentifier(prop.key)) continue;
|
|
5587
|
+
const field = {
|
|
5588
|
+
name: prop.key.name,
|
|
5589
|
+
type: extractTSType(prop.typeAnnotation),
|
|
5590
|
+
optional: prop.optional || false
|
|
5591
|
+
};
|
|
5592
|
+
workflow.fields.push(field);
|
|
5593
|
+
}
|
|
5594
|
+
}
|
|
5595
|
+
});
|
|
5596
|
+
}
|
|
5597
|
+
function extractTSType(annotation) {
|
|
5598
|
+
if (!annotation || !t17.isTSTypeAnnotation(annotation)) return "unknown";
|
|
5599
|
+
const typeNode = annotation.typeAnnotation;
|
|
5600
|
+
if (t17.isTSStringKeyword(typeNode)) return "string";
|
|
5601
|
+
if (t17.isTSNumberKeyword(typeNode)) return "number";
|
|
5602
|
+
if (t17.isTSBooleanKeyword(typeNode)) return "boolean";
|
|
5603
|
+
if (t17.isTSArrayType(typeNode)) return `${extractTSTypeNode(typeNode.elementType)}[]`;
|
|
5604
|
+
if (t17.isTSTypeReference(typeNode) && t17.isIdentifier(typeNode.typeName)) return typeNode.typeName.name;
|
|
5605
|
+
return "unknown";
|
|
5606
|
+
}
|
|
5607
|
+
function extractTSTypeNode(node) {
|
|
5608
|
+
if (t17.isTSStringKeyword(node)) return "string";
|
|
5609
|
+
if (t17.isTSNumberKeyword(node)) return "number";
|
|
5610
|
+
if (t17.isTSBooleanKeyword(node)) return "boolean";
|
|
5611
|
+
if (t17.isTSTypeReference(node) && t17.isIdentifier(node.typeName)) return node.typeName.name;
|
|
5612
|
+
return "unknown";
|
|
5613
|
+
}
|
|
5614
|
+
function extractReducerActions(path, reducerName) {
|
|
5615
|
+
const actions = [];
|
|
5616
|
+
path.traverse({
|
|
5617
|
+
FunctionDeclaration(funcPath) {
|
|
5618
|
+
if (!funcPath.node.id || funcPath.node.id.name !== reducerName) return;
|
|
5619
|
+
funcPath.traverse({
|
|
5620
|
+
SwitchStatement(switchPath) {
|
|
5621
|
+
for (const switchCase of switchPath.node.cases) {
|
|
5622
|
+
if (!switchCase.test) continue;
|
|
5623
|
+
if (t17.isStringLiteral(switchCase.test)) {
|
|
5624
|
+
actions.push({
|
|
5625
|
+
type: switchCase.test.value
|
|
5626
|
+
});
|
|
5627
|
+
}
|
|
5628
|
+
}
|
|
5629
|
+
}
|
|
5630
|
+
});
|
|
5631
|
+
}
|
|
5632
|
+
});
|
|
5633
|
+
return actions;
|
|
5634
|
+
}
|
|
5635
|
+
function extractObjectLiteral2(obj) {
|
|
5636
|
+
const result = {};
|
|
5637
|
+
for (const prop of obj.properties) {
|
|
5638
|
+
if (!t17.isObjectProperty(prop) || !t17.isIdentifier(prop.key)) continue;
|
|
5639
|
+
if (t17.isStringLiteral(prop.value)) result[prop.key.name] = prop.value.value;
|
|
5640
|
+
else if (t17.isNumericLiteral(prop.value)) result[prop.key.name] = prop.value.value;
|
|
5641
|
+
else if (t17.isBooleanLiteral(prop.value)) result[prop.key.name] = prop.value.value;
|
|
5642
|
+
else if (t17.isNullLiteral(prop.value)) result[prop.key.name] = null;
|
|
5643
|
+
else if (t17.isArrayExpression(prop.value)) result[prop.key.name] = [];
|
|
5644
|
+
else if (t17.isObjectExpression(prop.value)) result[prop.key.name] = extractObjectLiteral2(prop.value);
|
|
5645
|
+
}
|
|
5646
|
+
return result;
|
|
5647
|
+
}
|
|
5648
|
+
var t17;
|
|
5649
|
+
var init_context_extractor = __esm({
|
|
5650
|
+
"src/babel/extractors/context-extractor.ts"() {
|
|
5651
|
+
"use strict";
|
|
5652
|
+
t17 = __toESM(require("@babel/types"));
|
|
5653
|
+
}
|
|
5654
|
+
});
|
|
5655
|
+
|
|
5656
|
+
// src/babel/extractors/middleware-extractor.ts
|
|
5657
|
+
function hasMiddleware(path) {
|
|
5658
|
+
for (const node of path.node.body) {
|
|
5659
|
+
if (t18.isExportDefaultDeclaration(node)) {
|
|
5660
|
+
const decl = node.declaration;
|
|
5661
|
+
if (isDefineMiddlewareCall(decl) || isBuiltinFactoryCall(decl)) {
|
|
5662
|
+
return true;
|
|
5663
|
+
}
|
|
5664
|
+
}
|
|
5665
|
+
if (t18.isExportNamedDeclaration(node) && node.declaration) {
|
|
5666
|
+
if (t18.isVariableDeclaration(node.declaration)) {
|
|
5667
|
+
for (const declarator of node.declaration.declarations) {
|
|
5668
|
+
if (declarator.init && (isDefineMiddlewareCall(declarator.init) || isBuiltinFactoryCall(declarator.init))) {
|
|
5669
|
+
return true;
|
|
5670
|
+
}
|
|
5671
|
+
}
|
|
5672
|
+
}
|
|
5673
|
+
}
|
|
5674
|
+
if (t18.isVariableDeclaration(node)) {
|
|
5675
|
+
for (const declarator of node.declarations) {
|
|
5676
|
+
if (declarator.init && (isDefineMiddlewareCall(declarator.init) || isBuiltinFactoryCall(declarator.init))) {
|
|
5677
|
+
return true;
|
|
5678
|
+
}
|
|
5679
|
+
}
|
|
5680
|
+
}
|
|
5681
|
+
}
|
|
5682
|
+
return false;
|
|
5683
|
+
}
|
|
5684
|
+
function isDefineMiddlewareCall(node) {
|
|
5685
|
+
return t18.isCallExpression(node) && t18.isIdentifier(node.callee) && node.callee.name === "defineMiddleware";
|
|
5686
|
+
}
|
|
5687
|
+
function isBuiltinFactoryCall(node) {
|
|
5688
|
+
return t18.isCallExpression(node) && t18.isIdentifier(node.callee) && BUILTIN_FACTORIES.has(node.callee.name);
|
|
5689
|
+
}
|
|
5690
|
+
function extractMiddleware(path, state) {
|
|
5691
|
+
const compilerState = state;
|
|
5692
|
+
if (!compilerState.metadata) compilerState.metadata = {};
|
|
5693
|
+
const meta = compilerState.metadata;
|
|
5694
|
+
if (!meta.middleware) meta.middleware = [];
|
|
5695
|
+
const middlewareList = meta.middleware;
|
|
5696
|
+
path.traverse({
|
|
5697
|
+
CallExpression(callPath) {
|
|
5698
|
+
const callee = callPath.node.callee;
|
|
5699
|
+
if (!t18.isIdentifier(callee)) return;
|
|
5700
|
+
if (callee.name === "defineMiddleware") {
|
|
5701
|
+
const extracted = extractDefineMiddleware(callPath);
|
|
5702
|
+
if (extracted) middlewareList.push(extracted);
|
|
5703
|
+
} else if (BUILTIN_FACTORIES.has(callee.name)) {
|
|
5704
|
+
const extracted = extractBuiltinFactory(callee.name, callPath);
|
|
5705
|
+
if (extracted) middlewareList.push(extracted);
|
|
5706
|
+
}
|
|
5707
|
+
}
|
|
5708
|
+
});
|
|
5709
|
+
}
|
|
5710
|
+
function extractDefineMiddleware(callPath) {
|
|
5711
|
+
const args = callPath.node.arguments;
|
|
5712
|
+
if (args.length < 1 || !t18.isObjectExpression(args[0])) return null;
|
|
5713
|
+
const obj = args[0];
|
|
5714
|
+
let name = "unnamed";
|
|
5715
|
+
let match = [];
|
|
5716
|
+
let priority = 0;
|
|
5717
|
+
const before = [];
|
|
5718
|
+
const after = [];
|
|
5719
|
+
let hasAround = false;
|
|
5720
|
+
let config;
|
|
5721
|
+
for (const prop of obj.properties) {
|
|
5722
|
+
if (!t18.isObjectProperty(prop) && !t18.isObjectMethod(prop)) continue;
|
|
5723
|
+
const key = t18.isObjectProperty(prop) ? prop.key : prop.key;
|
|
5724
|
+
const keyName = t18.isIdentifier(key) ? key.name : t18.isStringLiteral(key) ? key.value : null;
|
|
5725
|
+
if (!keyName) continue;
|
|
5726
|
+
switch (keyName) {
|
|
5727
|
+
case "name":
|
|
5728
|
+
if (t18.isObjectProperty(prop) && t18.isStringLiteral(prop.value)) {
|
|
5729
|
+
name = prop.value.value;
|
|
5730
|
+
}
|
|
5731
|
+
break;
|
|
5732
|
+
case "match":
|
|
5733
|
+
if (t18.isObjectProperty(prop)) {
|
|
5734
|
+
if (t18.isStringLiteral(prop.value)) {
|
|
5735
|
+
match = [prop.value.value];
|
|
5736
|
+
} else if (t18.isArrayExpression(prop.value)) {
|
|
5737
|
+
match = prop.value.elements.filter((el) => t18.isStringLiteral(el)).map((el) => el.value);
|
|
5738
|
+
}
|
|
5739
|
+
}
|
|
5740
|
+
break;
|
|
5741
|
+
case "priority":
|
|
5742
|
+
if (t18.isObjectProperty(prop) && t18.isNumericLiteral(prop.value)) {
|
|
5743
|
+
priority = prop.value.value;
|
|
5744
|
+
}
|
|
5745
|
+
break;
|
|
5746
|
+
case "config":
|
|
5747
|
+
if (t18.isObjectProperty(prop) && t18.isObjectExpression(prop.value)) {
|
|
5748
|
+
config = extractConfigSchema(prop.value);
|
|
5749
|
+
}
|
|
5750
|
+
break;
|
|
5751
|
+
case "before":
|
|
5752
|
+
if (t18.isObjectMethod(prop)) {
|
|
5753
|
+
extractActionsFromBody(prop.body, before);
|
|
5754
|
+
} else if (t18.isObjectProperty(prop)) {
|
|
5755
|
+
const val = prop.value;
|
|
5756
|
+
if (t18.isFunctionExpression(val) || t18.isArrowFunctionExpression(val)) {
|
|
5757
|
+
const body = t18.isBlockStatement(val.body) ? val.body : null;
|
|
5758
|
+
if (body) extractActionsFromBody(body, before);
|
|
5759
|
+
}
|
|
5760
|
+
}
|
|
5761
|
+
break;
|
|
5762
|
+
case "after":
|
|
5763
|
+
if (t18.isObjectMethod(prop)) {
|
|
5764
|
+
extractActionsFromBody(prop.body, after);
|
|
5765
|
+
} else if (t18.isObjectProperty(prop)) {
|
|
5766
|
+
const val = prop.value;
|
|
5767
|
+
if (t18.isFunctionExpression(val) || t18.isArrowFunctionExpression(val)) {
|
|
5768
|
+
const body = t18.isBlockStatement(val.body) ? val.body : null;
|
|
5769
|
+
if (body) extractActionsFromBody(body, after);
|
|
5770
|
+
}
|
|
5771
|
+
}
|
|
5772
|
+
break;
|
|
5773
|
+
case "around":
|
|
5774
|
+
hasAround = true;
|
|
5775
|
+
break;
|
|
5776
|
+
}
|
|
5777
|
+
}
|
|
5778
|
+
return { name, match, priority, before, after, hasAround, config };
|
|
5779
|
+
}
|
|
5780
|
+
function extractBuiltinFactory(factoryName, callPath) {
|
|
5781
|
+
const args = callPath.node.arguments;
|
|
5782
|
+
const opts = args.length > 0 && t18.isObjectExpression(args[0]) ? args[0] : null;
|
|
5783
|
+
switch (factoryName) {
|
|
5784
|
+
case "withAuth": {
|
|
5785
|
+
let redirectTo;
|
|
5786
|
+
if (opts) {
|
|
5787
|
+
for (const prop of opts.properties) {
|
|
5788
|
+
if (t18.isObjectProperty(prop) && t18.isIdentifier(prop.key) && prop.key.name === "redirectTo" && t18.isStringLiteral(prop.value)) {
|
|
5789
|
+
redirectTo = prop.value.value;
|
|
5790
|
+
}
|
|
5791
|
+
}
|
|
5792
|
+
}
|
|
5793
|
+
return {
|
|
5794
|
+
name: "mm:auth",
|
|
5795
|
+
match: ["*:*:transition.execute"],
|
|
5796
|
+
priority: 90,
|
|
5797
|
+
before: [{ type: "block", args: { condition: "!ctx.actor.id", reason: redirectTo ? `redirect:${redirectTo}` : "Authentication required" } }],
|
|
5798
|
+
after: [],
|
|
5799
|
+
hasAround: false,
|
|
5800
|
+
factory: "withAuth"
|
|
5801
|
+
};
|
|
5802
|
+
}
|
|
5803
|
+
case "withAuditLog": {
|
|
5804
|
+
let level = "info";
|
|
5805
|
+
if (opts) {
|
|
5806
|
+
for (const prop of opts.properties) {
|
|
5807
|
+
if (t18.isObjectProperty(prop) && t18.isIdentifier(prop.key) && prop.key.name === "level" && t18.isStringLiteral(prop.value)) {
|
|
5808
|
+
level = prop.value.value;
|
|
5809
|
+
}
|
|
5810
|
+
}
|
|
5811
|
+
}
|
|
5812
|
+
return {
|
|
5813
|
+
name: "mm:audit-log",
|
|
5814
|
+
match: ["*:*:transition.execute"],
|
|
5815
|
+
priority: 0,
|
|
5816
|
+
before: [],
|
|
5817
|
+
after: [{ type: "modify", args: { __audit: { level } } }],
|
|
5818
|
+
hasAround: false,
|
|
5819
|
+
factory: "withAuditLog"
|
|
5820
|
+
};
|
|
5821
|
+
}
|
|
5822
|
+
case "withRateLimit": {
|
|
5823
|
+
let maxPerMinute = 60;
|
|
5824
|
+
if (opts) {
|
|
5825
|
+
for (const prop of opts.properties) {
|
|
5826
|
+
if (t18.isObjectProperty(prop) && t18.isIdentifier(prop.key) && prop.key.name === "maxPerMinute" && t18.isNumericLiteral(prop.value)) {
|
|
5827
|
+
maxPerMinute = prop.value.value;
|
|
5828
|
+
}
|
|
5829
|
+
}
|
|
5830
|
+
}
|
|
5831
|
+
return {
|
|
5832
|
+
name: "mm:rate-limit",
|
|
5833
|
+
match: ["*:*:transition.execute"],
|
|
5834
|
+
priority: 80,
|
|
5835
|
+
before: [{ type: "block", args: { condition: `counter >= ${maxPerMinute}`, reason: `Rate limit exceeded: ${maxPerMinute} per minute` } }],
|
|
5836
|
+
after: [],
|
|
5837
|
+
hasAround: false,
|
|
5838
|
+
config: { maxPerMinute: { type: "number", default: maxPerMinute } },
|
|
5839
|
+
factory: "withRateLimit"
|
|
5840
|
+
};
|
|
5841
|
+
}
|
|
5842
|
+
case "withValidation": {
|
|
5843
|
+
const rules = [];
|
|
5844
|
+
if (opts) {
|
|
5845
|
+
for (const prop of opts.properties) {
|
|
5846
|
+
if (t18.isObjectProperty(prop) && t18.isIdentifier(prop.key) && prop.key.name === "rules" && t18.isArrayExpression(prop.value)) {
|
|
5847
|
+
for (const el of prop.value.elements) {
|
|
5848
|
+
if (!t18.isObjectExpression(el)) continue;
|
|
5849
|
+
let fields = [];
|
|
5850
|
+
let check = "";
|
|
5851
|
+
let message = "";
|
|
5852
|
+
for (const rp of el.properties) {
|
|
5853
|
+
if (!t18.isObjectProperty(rp) || !t18.isIdentifier(rp.key)) continue;
|
|
5854
|
+
if (rp.key.name === "fields" && t18.isArrayExpression(rp.value)) {
|
|
5855
|
+
fields = rp.value.elements.filter((e) => t18.isStringLiteral(e)).map((e) => e.value);
|
|
5856
|
+
}
|
|
5857
|
+
if (rp.key.name === "check" && t18.isStringLiteral(rp.value)) {
|
|
5858
|
+
check = rp.value.value;
|
|
5859
|
+
}
|
|
5860
|
+
if (rp.key.name === "message" && t18.isStringLiteral(rp.value)) {
|
|
5861
|
+
message = rp.value.value;
|
|
5862
|
+
}
|
|
5863
|
+
}
|
|
5864
|
+
if (fields.length > 0) rules.push({ fields, check, message });
|
|
5865
|
+
}
|
|
5866
|
+
}
|
|
5867
|
+
}
|
|
5868
|
+
}
|
|
5869
|
+
return {
|
|
5870
|
+
name: "mm:validation",
|
|
5871
|
+
match: ["*:*:field.change"],
|
|
5872
|
+
priority: 70,
|
|
5873
|
+
before: rules.map((r) => ({ type: "validate", args: { fields: r.fields, check: r.check, message: r.message } })),
|
|
5874
|
+
after: [],
|
|
5875
|
+
hasAround: false,
|
|
5876
|
+
config: { rules: { type: "json", default: rules } },
|
|
5877
|
+
factory: "withValidation"
|
|
5878
|
+
};
|
|
5879
|
+
}
|
|
5880
|
+
case "withMetrics": {
|
|
5881
|
+
let endpoint;
|
|
5882
|
+
if (opts) {
|
|
5883
|
+
for (const prop of opts.properties) {
|
|
5884
|
+
if (t18.isObjectProperty(prop) && t18.isIdentifier(prop.key) && prop.key.name === "endpoint" && t18.isStringLiteral(prop.value)) {
|
|
5885
|
+
endpoint = prop.value.value;
|
|
5886
|
+
}
|
|
5887
|
+
}
|
|
5888
|
+
}
|
|
5889
|
+
return {
|
|
5890
|
+
name: "mm:metrics",
|
|
5891
|
+
match: ["*:*:*"],
|
|
5892
|
+
priority: 100,
|
|
5893
|
+
before: [],
|
|
5894
|
+
after: [],
|
|
5895
|
+
hasAround: true,
|
|
5896
|
+
config: { endpoint: { type: "string", default: endpoint } },
|
|
5897
|
+
factory: "withMetrics"
|
|
5898
|
+
};
|
|
5899
|
+
}
|
|
5900
|
+
default:
|
|
5901
|
+
return null;
|
|
5902
|
+
}
|
|
5903
|
+
}
|
|
5904
|
+
function extractActionsFromBody(body, actions) {
|
|
5905
|
+
for (const stmt of body.body) {
|
|
5906
|
+
if (t18.isExpressionStatement(stmt) && t18.isCallExpression(stmt.expression)) {
|
|
5907
|
+
const call = stmt.expression;
|
|
5908
|
+
if (t18.isMemberExpression(call.callee) && t18.isIdentifier(call.callee.property)) {
|
|
5909
|
+
const method = call.callee.property.name;
|
|
5910
|
+
if (method === "block" && call.arguments.length > 0) {
|
|
5911
|
+
const arg = call.arguments[0];
|
|
5912
|
+
actions.push({
|
|
5913
|
+
type: "block",
|
|
5914
|
+
args: { reason: t18.isStringLiteral(arg) ? arg.value : "<expression>" }
|
|
5915
|
+
});
|
|
5916
|
+
} else if (method === "modify" && call.arguments.length > 0) {
|
|
5917
|
+
const arg = call.arguments[0];
|
|
5918
|
+
actions.push({
|
|
5919
|
+
type: "modify",
|
|
5920
|
+
args: t18.isObjectExpression(arg) ? extractStaticObject(arg) : {}
|
|
5921
|
+
});
|
|
5922
|
+
} else if (method === "skip") {
|
|
5923
|
+
actions.push({ type: "skip" });
|
|
5924
|
+
}
|
|
5925
|
+
}
|
|
5926
|
+
}
|
|
5927
|
+
if (t18.isIfStatement(stmt)) {
|
|
5928
|
+
if (t18.isBlockStatement(stmt.consequent)) {
|
|
5929
|
+
extractActionsFromBody(stmt.consequent, actions);
|
|
5930
|
+
} else if (t18.isExpressionStatement(stmt.consequent)) {
|
|
5931
|
+
extractActionsFromBody(
|
|
5932
|
+
t18.blockStatement([stmt.consequent]),
|
|
5933
|
+
actions
|
|
5934
|
+
);
|
|
5935
|
+
}
|
|
5936
|
+
}
|
|
5937
|
+
}
|
|
5938
|
+
}
|
|
5939
|
+
function extractStaticObject(obj) {
|
|
5940
|
+
const result = {};
|
|
5941
|
+
for (const prop of obj.properties) {
|
|
5942
|
+
if (!t18.isObjectProperty(prop)) continue;
|
|
5943
|
+
const key = t18.isIdentifier(prop.key) ? prop.key.name : t18.isStringLiteral(prop.key) ? prop.key.value : null;
|
|
5944
|
+
if (!key) continue;
|
|
5945
|
+
const val = prop.value;
|
|
5946
|
+
if (t18.isStringLiteral(val)) result[key] = val.value;
|
|
5947
|
+
else if (t18.isNumericLiteral(val)) result[key] = val.value;
|
|
5948
|
+
else if (t18.isBooleanLiteral(val)) result[key] = val.value;
|
|
5949
|
+
else if (t18.isNullLiteral(val)) result[key] = null;
|
|
5950
|
+
else if (t18.isObjectExpression(val)) result[key] = extractStaticObject(val);
|
|
5951
|
+
else if (t18.isMemberExpression(val)) {
|
|
5952
|
+
result[key] = memberExprToString2(val);
|
|
5953
|
+
} else {
|
|
5954
|
+
result[key] = "<expression>";
|
|
5955
|
+
}
|
|
5956
|
+
}
|
|
5957
|
+
return result;
|
|
5958
|
+
}
|
|
5959
|
+
function memberExprToString2(expr) {
|
|
5960
|
+
const parts = [];
|
|
5961
|
+
let current = expr;
|
|
5962
|
+
while (t18.isMemberExpression(current)) {
|
|
5963
|
+
if (t18.isIdentifier(current.property)) {
|
|
5964
|
+
parts.unshift(current.property.name);
|
|
5965
|
+
}
|
|
5966
|
+
current = current.object;
|
|
5967
|
+
}
|
|
5968
|
+
if (t18.isIdentifier(current)) {
|
|
5969
|
+
parts.unshift(current.name);
|
|
5970
|
+
}
|
|
5971
|
+
return "$" + parts.join(".");
|
|
5972
|
+
}
|
|
5973
|
+
function extractConfigSchema(obj) {
|
|
5974
|
+
const schema = {};
|
|
5975
|
+
for (const prop of obj.properties) {
|
|
5976
|
+
if (!t18.isObjectProperty(prop) || !t18.isIdentifier(prop.key)) continue;
|
|
5977
|
+
if (!t18.isObjectExpression(prop.value)) continue;
|
|
5978
|
+
const entry = { type: "string" };
|
|
5979
|
+
for (const inner of prop.value.properties) {
|
|
5980
|
+
if (!t18.isObjectProperty(inner) || !t18.isIdentifier(inner.key)) continue;
|
|
5981
|
+
if (inner.key.name === "type" && t18.isStringLiteral(inner.value)) {
|
|
5982
|
+
entry.type = inner.value.value;
|
|
3623
5983
|
}
|
|
3624
|
-
if (
|
|
3625
|
-
|
|
5984
|
+
if (inner.key.name === "default") {
|
|
5985
|
+
if (t18.isStringLiteral(inner.value)) entry.default = inner.value.value;
|
|
5986
|
+
else if (t18.isNumericLiteral(inner.value)) entry.default = inner.value.value;
|
|
5987
|
+
else if (t18.isBooleanLiteral(inner.value)) entry.default = inner.value.value;
|
|
3626
5988
|
}
|
|
3627
|
-
extractGrammarIsland(templatePath, state, slug);
|
|
3628
5989
|
}
|
|
3629
|
-
|
|
5990
|
+
schema[prop.key.name] = entry;
|
|
5991
|
+
}
|
|
5992
|
+
return schema;
|
|
3630
5993
|
}
|
|
3631
|
-
var
|
|
3632
|
-
var
|
|
3633
|
-
"src/babel/extractors/
|
|
5994
|
+
var t18, BUILTIN_FACTORIES;
|
|
5995
|
+
var init_middleware_extractor = __esm({
|
|
5996
|
+
"src/babel/extractors/middleware-extractor.ts"() {
|
|
3634
5997
|
"use strict";
|
|
3635
|
-
|
|
3636
|
-
|
|
5998
|
+
t18 = __toESM(require("@babel/types"));
|
|
5999
|
+
BUILTIN_FACTORIES = /* @__PURE__ */ new Set([
|
|
6000
|
+
"withAuth",
|
|
6001
|
+
"withAuditLog",
|
|
6002
|
+
"withRateLimit",
|
|
6003
|
+
"withValidation",
|
|
6004
|
+
"withMetrics"
|
|
6005
|
+
]);
|
|
3637
6006
|
}
|
|
3638
6007
|
});
|
|
3639
6008
|
|
|
3640
|
-
// src/babel/extractors/
|
|
3641
|
-
function
|
|
3642
|
-
|
|
3643
|
-
|
|
3644
|
-
|
|
3645
|
-
|
|
3646
|
-
|
|
3647
|
-
|
|
6009
|
+
// src/babel/extractors/constraint-extractor.ts
|
|
6010
|
+
function hasConstraints(path) {
|
|
6011
|
+
for (const node of path.node.body) {
|
|
6012
|
+
if (t19.isExportNamedDeclaration(node) && node.declaration) {
|
|
6013
|
+
if (t19.isVariableDeclaration(node.declaration)) {
|
|
6014
|
+
for (const declarator of node.declaration.declarations) {
|
|
6015
|
+
if (declarator.init && isConstraintsCall(declarator.init)) {
|
|
6016
|
+
return true;
|
|
6017
|
+
}
|
|
6018
|
+
}
|
|
3648
6019
|
}
|
|
3649
6020
|
}
|
|
3650
|
-
|
|
3651
|
-
|
|
6021
|
+
if (t19.isVariableDeclaration(node)) {
|
|
6022
|
+
for (const declarator of node.declarations) {
|
|
6023
|
+
if (declarator.init && isConstraintsCall(declarator.init)) {
|
|
6024
|
+
return true;
|
|
6025
|
+
}
|
|
6026
|
+
}
|
|
6027
|
+
}
|
|
6028
|
+
if (t19.isExpressionStatement(node) && isConstraintsCall(node.expression)) {
|
|
6029
|
+
return true;
|
|
6030
|
+
}
|
|
6031
|
+
}
|
|
6032
|
+
return false;
|
|
3652
6033
|
}
|
|
3653
|
-
function
|
|
6034
|
+
function isConstraintsCall(node) {
|
|
6035
|
+
return t19.isCallExpression(node) && t19.isIdentifier(node.callee) && node.callee.name === "constraints";
|
|
6036
|
+
}
|
|
6037
|
+
function extractConstraints(path, state) {
|
|
3654
6038
|
const compilerState = state;
|
|
3655
|
-
|
|
3656
|
-
const
|
|
6039
|
+
if (!compilerState.metadata) compilerState.metadata = {};
|
|
6040
|
+
const meta = compilerState.metadata;
|
|
6041
|
+
if (!meta.constraints) meta.constraints = [];
|
|
6042
|
+
const constraintList = meta.constraints;
|
|
3657
6043
|
path.traverse({
|
|
3658
|
-
// Detect: const XContext = createContext(...)
|
|
3659
|
-
VariableDeclarator(declPath) {
|
|
3660
|
-
const init = declPath.node.init;
|
|
3661
|
-
if (!init || !t16.isCallExpression(init)) return;
|
|
3662
|
-
if (!t16.isIdentifier(init.callee, { name: "createContext" })) return;
|
|
3663
|
-
if (!t16.isIdentifier(declPath.node.id)) return;
|
|
3664
|
-
const contextName = declPath.node.id.name;
|
|
3665
|
-
contextNames.set(contextName, contextName);
|
|
3666
|
-
const workflow = {
|
|
3667
|
-
name: contextName,
|
|
3668
|
-
fields: [],
|
|
3669
|
-
reducerActions: []
|
|
3670
|
-
};
|
|
3671
|
-
const typeParams = init.typeParameters;
|
|
3672
|
-
if (typeParams && t16.isTSTypeParameterInstantiation(typeParams)) {
|
|
3673
|
-
const typeArg = typeParams.params[0];
|
|
3674
|
-
if (t16.isTSTypeReference(typeArg) && t16.isIdentifier(typeArg.typeName)) {
|
|
3675
|
-
const interfaceName = typeArg.typeName.name;
|
|
3676
|
-
extractFieldsFromInterface2(path, interfaceName, workflow);
|
|
3677
|
-
}
|
|
3678
|
-
}
|
|
3679
|
-
if (init.arguments.length > 0 && t16.isObjectExpression(init.arguments[0])) {
|
|
3680
|
-
workflow.initialState = extractObjectLiteral2(init.arguments[0]);
|
|
3681
|
-
}
|
|
3682
|
-
contextWorkflows.push(workflow);
|
|
3683
|
-
},
|
|
3684
|
-
// Detect useReducer(reducer, initialState) and extract reducer cases
|
|
3685
6044
|
CallExpression(callPath) {
|
|
3686
|
-
|
|
6045
|
+
const callee = callPath.node.callee;
|
|
6046
|
+
if (!t19.isIdentifier(callee) || callee.name !== "constraints") return;
|
|
3687
6047
|
const args = callPath.node.arguments;
|
|
3688
|
-
|
|
3689
|
-
|
|
3690
|
-
|
|
3691
|
-
|
|
3692
|
-
|
|
3693
|
-
|
|
3694
|
-
|
|
3695
|
-
lastWorkflow.reducerActions = actions;
|
|
3696
|
-
lastWorkflow.reducerName = reducerName;
|
|
6048
|
+
for (const arg of args) {
|
|
6049
|
+
if (t19.isStringLiteral(arg)) {
|
|
6050
|
+
constraintList.push({
|
|
6051
|
+
rule: arg.value,
|
|
6052
|
+
type: BUILTIN_CONSTRAINTS.has(arg.value) ? "builtin" : "custom"
|
|
6053
|
+
});
|
|
6054
|
+
}
|
|
3697
6055
|
}
|
|
3698
6056
|
}
|
|
3699
6057
|
});
|
|
3700
|
-
|
|
3701
|
-
|
|
3702
|
-
|
|
3703
|
-
|
|
6058
|
+
}
|
|
6059
|
+
var t19, BUILTIN_CONSTRAINTS;
|
|
6060
|
+
var init_constraint_extractor = __esm({
|
|
6061
|
+
"src/babel/extractors/constraint-extractor.ts"() {
|
|
6062
|
+
"use strict";
|
|
6063
|
+
t19 = __toESM(require("@babel/types"));
|
|
6064
|
+
BUILTIN_CONSTRAINTS = /* @__PURE__ */ new Set([
|
|
6065
|
+
"every state is reachable",
|
|
6066
|
+
"no deadlocks",
|
|
6067
|
+
"no unreachable states",
|
|
6068
|
+
"deterministic guards",
|
|
6069
|
+
"terminates",
|
|
6070
|
+
"no guard overlaps",
|
|
6071
|
+
"all roles defined",
|
|
6072
|
+
"all fields validated"
|
|
6073
|
+
]);
|
|
6074
|
+
}
|
|
6075
|
+
});
|
|
6076
|
+
|
|
6077
|
+
// src/babel/extractors/actor-extractor.ts
|
|
6078
|
+
function hasActorConfig(path) {
|
|
6079
|
+
for (const node of path.node.body) {
|
|
6080
|
+
if (t20.isExportNamedDeclaration(node) && node.declaration) {
|
|
6081
|
+
if (t20.isVariableDeclaration(node.declaration)) {
|
|
6082
|
+
for (const declarator of node.declaration.declarations) {
|
|
6083
|
+
if (declarator.init && isActorCall(declarator.init)) {
|
|
6084
|
+
return true;
|
|
6085
|
+
}
|
|
6086
|
+
}
|
|
6087
|
+
}
|
|
6088
|
+
}
|
|
6089
|
+
if (t20.isVariableDeclaration(node)) {
|
|
6090
|
+
for (const declarator of node.declarations) {
|
|
6091
|
+
if (declarator.init && isActorCall(declarator.init)) {
|
|
6092
|
+
return true;
|
|
6093
|
+
}
|
|
6094
|
+
}
|
|
6095
|
+
}
|
|
6096
|
+
if (t20.isExpressionStatement(node) && isActorCall(node.expression)) {
|
|
6097
|
+
return true;
|
|
6098
|
+
}
|
|
3704
6099
|
}
|
|
6100
|
+
return false;
|
|
6101
|
+
}
|
|
6102
|
+
function isActorCall(node) {
|
|
6103
|
+
return t20.isCallExpression(node) && t20.isIdentifier(node.callee) && (node.callee.name === "configureActor" || node.callee.name === "spawnActor");
|
|
3705
6104
|
}
|
|
3706
|
-
function
|
|
6105
|
+
function extractActorConfig(path, state) {
|
|
6106
|
+
const compilerState = state;
|
|
6107
|
+
if (!compilerState.metadata) compilerState.metadata = {};
|
|
6108
|
+
const meta = compilerState.metadata;
|
|
6109
|
+
if (!meta.actor) {
|
|
6110
|
+
meta.actor = {
|
|
6111
|
+
supervision: { strategy: "escalate" },
|
|
6112
|
+
mailbox: {},
|
|
6113
|
+
hierarchy: {},
|
|
6114
|
+
spawns: []
|
|
6115
|
+
};
|
|
6116
|
+
}
|
|
6117
|
+
const actorConfig = meta.actor;
|
|
3707
6118
|
path.traverse({
|
|
3708
|
-
|
|
3709
|
-
|
|
3710
|
-
|
|
3711
|
-
|
|
3712
|
-
|
|
3713
|
-
|
|
3714
|
-
|
|
3715
|
-
type: extractTSType(prop.typeAnnotation),
|
|
3716
|
-
optional: prop.optional || false
|
|
3717
|
-
};
|
|
3718
|
-
workflow.fields.push(field);
|
|
6119
|
+
CallExpression(callPath) {
|
|
6120
|
+
const callee = callPath.node.callee;
|
|
6121
|
+
if (!t20.isIdentifier(callee)) return;
|
|
6122
|
+
if (callee.name === "configureActor") {
|
|
6123
|
+
extractConfigureActor(callPath, actorConfig);
|
|
6124
|
+
} else if (callee.name === "spawnActor") {
|
|
6125
|
+
extractSpawnActor(callPath, actorConfig);
|
|
3719
6126
|
}
|
|
3720
6127
|
}
|
|
3721
6128
|
});
|
|
3722
6129
|
}
|
|
3723
|
-
function
|
|
3724
|
-
|
|
3725
|
-
|
|
3726
|
-
|
|
3727
|
-
|
|
3728
|
-
|
|
3729
|
-
|
|
3730
|
-
|
|
3731
|
-
|
|
6130
|
+
function extractConfigureActor(callPath, actorConfig) {
|
|
6131
|
+
const args = callPath.node.arguments;
|
|
6132
|
+
if (args.length < 1 || !t20.isObjectExpression(args[0])) return;
|
|
6133
|
+
const obj = args[0];
|
|
6134
|
+
for (const prop of obj.properties) {
|
|
6135
|
+
if (!t20.isObjectProperty(prop) || !t20.isIdentifier(prop.key)) continue;
|
|
6136
|
+
switch (prop.key.name) {
|
|
6137
|
+
case "supervision":
|
|
6138
|
+
if (t20.isObjectExpression(prop.value)) {
|
|
6139
|
+
actorConfig.supervision = extractSupervision(prop.value);
|
|
6140
|
+
}
|
|
6141
|
+
break;
|
|
6142
|
+
case "mailbox":
|
|
6143
|
+
if (t20.isObjectExpression(prop.value)) {
|
|
6144
|
+
actorConfig.mailbox = extractMailbox(prop.value);
|
|
6145
|
+
}
|
|
6146
|
+
break;
|
|
6147
|
+
case "hierarchy":
|
|
6148
|
+
if (t20.isObjectExpression(prop.value)) {
|
|
6149
|
+
actorConfig.hierarchy = extractStaticObj(prop.value);
|
|
6150
|
+
}
|
|
6151
|
+
break;
|
|
6152
|
+
}
|
|
6153
|
+
}
|
|
3732
6154
|
}
|
|
3733
|
-
function
|
|
3734
|
-
|
|
3735
|
-
if (
|
|
3736
|
-
|
|
3737
|
-
if (
|
|
3738
|
-
|
|
6155
|
+
function extractSpawnActor(callPath, actorConfig) {
|
|
6156
|
+
const args = callPath.node.arguments;
|
|
6157
|
+
if (args.length < 1 || !t20.isStringLiteral(args[0])) return;
|
|
6158
|
+
const spawn = { slug: args[0].value };
|
|
6159
|
+
if (args.length > 1 && t20.isObjectExpression(args[1])) {
|
|
6160
|
+
for (const prop of args[1].properties) {
|
|
6161
|
+
if (!t20.isObjectProperty(prop) || !t20.isIdentifier(prop.key)) continue;
|
|
6162
|
+
if (prop.key.name === "supervision" && t20.isObjectExpression(prop.value)) {
|
|
6163
|
+
spawn.supervision = extractSupervision(prop.value);
|
|
6164
|
+
} else if (prop.key.name === "blocking" && t20.isBooleanLiteral(prop.value)) {
|
|
6165
|
+
spawn.blocking = prop.value.value;
|
|
6166
|
+
}
|
|
6167
|
+
}
|
|
6168
|
+
}
|
|
6169
|
+
actorConfig.spawns.push(spawn);
|
|
3739
6170
|
}
|
|
3740
|
-
function
|
|
3741
|
-
const
|
|
3742
|
-
|
|
3743
|
-
|
|
3744
|
-
|
|
3745
|
-
|
|
3746
|
-
|
|
3747
|
-
|
|
3748
|
-
|
|
3749
|
-
|
|
3750
|
-
|
|
3751
|
-
|
|
3752
|
-
|
|
3753
|
-
|
|
3754
|
-
|
|
3755
|
-
|
|
3756
|
-
|
|
6171
|
+
function extractSupervision(obj) {
|
|
6172
|
+
const result = { strategy: "escalate" };
|
|
6173
|
+
for (const prop of obj.properties) {
|
|
6174
|
+
if (!t20.isObjectProperty(prop) || !t20.isIdentifier(prop.key)) continue;
|
|
6175
|
+
switch (prop.key.name) {
|
|
6176
|
+
case "strategy":
|
|
6177
|
+
if (t20.isStringLiteral(prop.value)) result.strategy = prop.value.value;
|
|
6178
|
+
break;
|
|
6179
|
+
case "maxRetries":
|
|
6180
|
+
if (t20.isNumericLiteral(prop.value)) result.maxRetries = prop.value.value;
|
|
6181
|
+
break;
|
|
6182
|
+
case "retryWindow":
|
|
6183
|
+
if (t20.isStringLiteral(prop.value)) result.retryWindow = prop.value.value;
|
|
6184
|
+
break;
|
|
6185
|
+
case "backoff":
|
|
6186
|
+
if (t20.isStringLiteral(prop.value)) result.backoff = prop.value.value;
|
|
6187
|
+
break;
|
|
3757
6188
|
}
|
|
3758
|
-
}
|
|
3759
|
-
return
|
|
6189
|
+
}
|
|
6190
|
+
return result;
|
|
3760
6191
|
}
|
|
3761
|
-
function
|
|
6192
|
+
function extractMailbox(obj) {
|
|
3762
6193
|
const result = {};
|
|
3763
6194
|
for (const prop of obj.properties) {
|
|
3764
|
-
if (!
|
|
3765
|
-
|
|
3766
|
-
|
|
3767
|
-
|
|
3768
|
-
|
|
3769
|
-
|
|
3770
|
-
|
|
6195
|
+
if (!t20.isObjectProperty(prop) || !t20.isIdentifier(prop.key)) continue;
|
|
6196
|
+
switch (prop.key.name) {
|
|
6197
|
+
case "capacity":
|
|
6198
|
+
if (t20.isNumericLiteral(prop.value)) result.capacity = prop.value.value;
|
|
6199
|
+
break;
|
|
6200
|
+
case "overflow":
|
|
6201
|
+
if (t20.isStringLiteral(prop.value)) result.overflow = prop.value.value;
|
|
6202
|
+
break;
|
|
6203
|
+
case "priority":
|
|
6204
|
+
if (t20.isStringLiteral(prop.value)) result.priority = prop.value.value;
|
|
6205
|
+
break;
|
|
6206
|
+
}
|
|
3771
6207
|
}
|
|
3772
6208
|
return result;
|
|
3773
6209
|
}
|
|
3774
|
-
|
|
3775
|
-
|
|
3776
|
-
|
|
3777
|
-
|
|
3778
|
-
|
|
6210
|
+
function extractStaticObj(obj) {
|
|
6211
|
+
const result = {};
|
|
6212
|
+
for (const prop of obj.properties) {
|
|
6213
|
+
if (!t20.isObjectProperty(prop) || !t20.isIdentifier(prop.key)) continue;
|
|
6214
|
+
const val = prop.value;
|
|
6215
|
+
if (t20.isStringLiteral(val)) result[prop.key.name] = val.value;
|
|
6216
|
+
else if (t20.isNumericLiteral(val)) result[prop.key.name] = val.value;
|
|
6217
|
+
else if (t20.isBooleanLiteral(val)) result[prop.key.name] = val.value;
|
|
6218
|
+
else if (t20.isNullLiteral(val)) result[prop.key.name] = null;
|
|
3779
6219
|
}
|
|
3780
|
-
|
|
3781
|
-
|
|
3782
|
-
|
|
3783
|
-
|
|
3784
|
-
|
|
3785
|
-
uniqueTags.sort();
|
|
3786
|
-
return [primary, ...uniqueTags];
|
|
3787
|
-
}
|
|
3788
|
-
var init_dist = __esm({
|
|
3789
|
-
"../player-core/dist/index.mjs"() {
|
|
6220
|
+
return result;
|
|
6221
|
+
}
|
|
6222
|
+
var t20;
|
|
6223
|
+
var init_actor_extractor = __esm({
|
|
6224
|
+
"src/babel/extractors/actor-extractor.ts"() {
|
|
3790
6225
|
"use strict";
|
|
6226
|
+
t20 = __toESM(require("@babel/types"));
|
|
3791
6227
|
}
|
|
3792
6228
|
});
|
|
3793
6229
|
|
|
@@ -3993,7 +6429,7 @@ function normalizeViewNode(node, fieldNames) {
|
|
|
3993
6429
|
}
|
|
3994
6430
|
return node;
|
|
3995
6431
|
}
|
|
3996
|
-
function
|
|
6432
|
+
function toSnakeCase3(str) {
|
|
3997
6433
|
return str.replace(/([A-Z])/g, "_$1").toLowerCase().replace(/^_/, "");
|
|
3998
6434
|
}
|
|
3999
6435
|
function convertAction(action) {
|
|
@@ -4088,7 +6524,7 @@ function emitIR(extracted) {
|
|
|
4088
6524
|
if (fields.length > 0) {
|
|
4089
6525
|
const localDefaults = {};
|
|
4090
6526
|
for (const f of fields) {
|
|
4091
|
-
localDefaults[
|
|
6527
|
+
localDefaults[toSnakeCase3(f.name)] = f.default_value ?? null;
|
|
4092
6528
|
}
|
|
4093
6529
|
if (!normalizedView.config) normalizedView.config = {};
|
|
4094
6530
|
normalizedView.config.localDefaults = localDefaults;
|
|
@@ -4167,7 +6603,7 @@ function liftAction(action) {
|
|
|
4167
6603
|
}
|
|
4168
6604
|
return {
|
|
4169
6605
|
slug: action.id,
|
|
4170
|
-
category: normalizeCategory("expression", "mutation", action.type),
|
|
6606
|
+
category: (0, import_player_core.normalizeCategory)("expression", "mutation", action.type),
|
|
4171
6607
|
parts: parts.length > 0 ? parts : void 0
|
|
4172
6608
|
};
|
|
4173
6609
|
}
|
|
@@ -4197,7 +6633,7 @@ function liftSchedule(during) {
|
|
|
4197
6633
|
for (const action of during.actions) {
|
|
4198
6634
|
parts.push({
|
|
4199
6635
|
slug: "do",
|
|
4200
|
-
category: normalizeCategory("expression", "mutation", action.type),
|
|
6636
|
+
category: (0, import_player_core.normalizeCategory)("expression", "mutation", action.type),
|
|
4201
6637
|
parts: Object.entries(action.config || {}).map(([key, value]) => ({
|
|
4202
6638
|
slug: key,
|
|
4203
6639
|
category: ["atom"],
|
|
@@ -4207,7 +6643,7 @@ function liftSchedule(during) {
|
|
|
4207
6643
|
}
|
|
4208
6644
|
return {
|
|
4209
6645
|
slug: during.id,
|
|
4210
|
-
category: normalizeCategory("schedule", during.type),
|
|
6646
|
+
category: (0, import_player_core.normalizeCategory)("schedule", during.type),
|
|
4211
6647
|
parts
|
|
4212
6648
|
};
|
|
4213
6649
|
}
|
|
@@ -4220,14 +6656,14 @@ function liftState(state) {
|
|
|
4220
6656
|
if (state.on_enter && state.on_enter.length > 0) {
|
|
4221
6657
|
parts.push({
|
|
4222
6658
|
slug: "on_enter",
|
|
4223
|
-
category: normalizeCategory("expression", "sequence"),
|
|
6659
|
+
category: (0, import_player_core.normalizeCategory)("expression", "sequence"),
|
|
4224
6660
|
parts: state.on_enter.map(liftAction)
|
|
4225
6661
|
});
|
|
4226
6662
|
}
|
|
4227
6663
|
if (state.on_exit && state.on_exit.length > 0) {
|
|
4228
6664
|
parts.push({
|
|
4229
6665
|
slug: "on_exit",
|
|
4230
|
-
category: normalizeCategory("expression", "sequence"),
|
|
6666
|
+
category: (0, import_player_core.normalizeCategory)("expression", "sequence"),
|
|
4231
6667
|
parts: state.on_exit.map(liftAction)
|
|
4232
6668
|
});
|
|
4233
6669
|
}
|
|
@@ -4238,7 +6674,7 @@ function liftState(state) {
|
|
|
4238
6674
|
}
|
|
4239
6675
|
return {
|
|
4240
6676
|
slug: state.name,
|
|
4241
|
-
category: normalizeCategory("state", ...tags),
|
|
6677
|
+
category: (0, import_player_core.normalizeCategory)("state", ...tags),
|
|
4242
6678
|
parts: parts.length > 0 ? parts : void 0
|
|
4243
6679
|
};
|
|
4244
6680
|
}
|
|
@@ -4261,17 +6697,17 @@ function liftTransition(transition) {
|
|
|
4261
6697
|
if (transition.actions && transition.actions.length > 0) {
|
|
4262
6698
|
parts.push({
|
|
4263
6699
|
slug: "actions",
|
|
4264
|
-
category: normalizeCategory("expression", "sequence"),
|
|
6700
|
+
category: (0, import_player_core.normalizeCategory)("expression", "sequence"),
|
|
4265
6701
|
parts: transition.actions.map(liftAction)
|
|
4266
6702
|
});
|
|
4267
6703
|
}
|
|
4268
6704
|
if (transition.conditions && transition.conditions.length > 0) {
|
|
4269
6705
|
parts.push({
|
|
4270
6706
|
slug: "conditions",
|
|
4271
|
-
category: normalizeCategory("expression", "guard"),
|
|
6707
|
+
category: (0, import_player_core.normalizeCategory)("expression", "guard"),
|
|
4272
6708
|
parts: transition.conditions.map((c, i) => ({
|
|
4273
6709
|
slug: `condition_${i}`,
|
|
4274
|
-
category: normalizeCategory("expression", c.type || "condition"),
|
|
6710
|
+
category: (0, import_player_core.normalizeCategory)("expression", c.type || "condition"),
|
|
4275
6711
|
parts: c.expression ? [{ slug: c.expression, category: ["binding"] }] : void 0
|
|
4276
6712
|
}))
|
|
4277
6713
|
});
|
|
@@ -4310,7 +6746,7 @@ function liftField(field) {
|
|
|
4310
6746
|
}
|
|
4311
6747
|
return {
|
|
4312
6748
|
slug: field.name,
|
|
4313
|
-
category: normalizeCategory("field", field.type),
|
|
6749
|
+
category: (0, import_player_core.normalizeCategory)("field", field.type),
|
|
4314
6750
|
parts: parts.length > 0 ? parts : void 0
|
|
4315
6751
|
};
|
|
4316
6752
|
}
|
|
@@ -4333,20 +6769,20 @@ function liftView(node) {
|
|
|
4333
6769
|
if (match) {
|
|
4334
6770
|
parts.push({
|
|
4335
6771
|
slug: key,
|
|
4336
|
-
category: normalizeCategory("expression", "effect", "transition"),
|
|
6772
|
+
category: (0, import_player_core.normalizeCategory)("expression", "effect", "transition"),
|
|
4337
6773
|
parts: [{ slug: match[1], category: ["ref"] }]
|
|
4338
6774
|
});
|
|
4339
6775
|
} else {
|
|
4340
6776
|
parts.push({
|
|
4341
6777
|
slug: key,
|
|
4342
|
-
category: normalizeCategory("expression", "binding"),
|
|
6778
|
+
category: (0, import_player_core.normalizeCategory)("expression", "binding"),
|
|
4343
6779
|
parts: [{ slug: String(expr), category: ["binding"] }]
|
|
4344
6780
|
});
|
|
4345
6781
|
}
|
|
4346
6782
|
} else {
|
|
4347
6783
|
parts.push({
|
|
4348
6784
|
slug: key,
|
|
4349
|
-
category: normalizeCategory("expression", "binding"),
|
|
6785
|
+
category: (0, import_player_core.normalizeCategory)("expression", "binding"),
|
|
4350
6786
|
parts: [{ slug: String(expr), category: ["binding"] }]
|
|
4351
6787
|
});
|
|
4352
6788
|
}
|
|
@@ -4357,20 +6793,20 @@ function liftView(node) {
|
|
|
4357
6793
|
if (eqMatch) {
|
|
4358
6794
|
parts.push({
|
|
4359
6795
|
slug: "visible_when",
|
|
4360
|
-
category: normalizeCategory("expression", "guard"),
|
|
6796
|
+
category: (0, import_player_core.normalizeCategory)("expression", "guard"),
|
|
4361
6797
|
parts: [{
|
|
4362
6798
|
slug: "body",
|
|
4363
|
-
category: normalizeCategory("expression", "eq"),
|
|
6799
|
+
category: (0, import_player_core.normalizeCategory)("expression", "eq"),
|
|
4364
6800
|
parts: [
|
|
4365
|
-
{ slug: "lhs", category: normalizeCategory("expression", "path"), parts: [{ slug: eqMatch[1], category: ["binding"] }] },
|
|
4366
|
-
{ slug: "rhs", category: normalizeCategory("expression", "literal"), parts: [{ slug: eqMatch[2], category: ["literal"] }] }
|
|
6801
|
+
{ slug: "lhs", category: (0, import_player_core.normalizeCategory)("expression", "path"), parts: [{ slug: eqMatch[1], category: ["binding"] }] },
|
|
6802
|
+
{ slug: "rhs", category: (0, import_player_core.normalizeCategory)("expression", "literal"), parts: [{ slug: eqMatch[2], category: ["literal"] }] }
|
|
4367
6803
|
]
|
|
4368
6804
|
}]
|
|
4369
6805
|
});
|
|
4370
6806
|
} else {
|
|
4371
6807
|
parts.push({
|
|
4372
6808
|
slug: "visible_when",
|
|
4373
|
-
category: normalizeCategory("expression", "guard"),
|
|
6809
|
+
category: (0, import_player_core.normalizeCategory)("expression", "guard"),
|
|
4374
6810
|
parts: [{ slug: node.visible_when, category: ["binding"] }]
|
|
4375
6811
|
});
|
|
4376
6812
|
}
|
|
@@ -4382,7 +6818,7 @@ function liftView(node) {
|
|
|
4382
6818
|
}
|
|
4383
6819
|
return {
|
|
4384
6820
|
slug: node.id,
|
|
4385
|
-
category: normalizeCategory("view", componentTag),
|
|
6821
|
+
category: (0, import_player_core.normalizeCategory)("view", componentTag),
|
|
4386
6822
|
parts: parts.length > 0 ? parts : void 0
|
|
4387
6823
|
};
|
|
4388
6824
|
}
|
|
@@ -4403,7 +6839,7 @@ function emitCanonical(extracted, sourceFilename) {
|
|
|
4403
6839
|
}
|
|
4404
6840
|
parts.push({
|
|
4405
6841
|
slug: "manifest",
|
|
4406
|
-
category: normalizeCategory("meta", "manifest"),
|
|
6842
|
+
category: (0, import_player_core.normalizeCategory)("meta", "manifest"),
|
|
4407
6843
|
parts: [
|
|
4408
6844
|
{
|
|
4409
6845
|
slug: "workflows",
|
|
@@ -4424,7 +6860,7 @@ function emitCanonical(extracted, sourceFilename) {
|
|
|
4424
6860
|
let categoryArray;
|
|
4425
6861
|
if (category.includes("/")) {
|
|
4426
6862
|
const [primary, ...tags] = category.split("/");
|
|
4427
|
-
categoryArray = normalizeCategory(primary, ...tags);
|
|
6863
|
+
categoryArray = (0, import_player_core.normalizeCategory)(primary, ...tags);
|
|
4428
6864
|
} else {
|
|
4429
6865
|
categoryArray = [category];
|
|
4430
6866
|
}
|
|
@@ -4486,7 +6922,7 @@ function emitWorkflowDefinition(extracted) {
|
|
|
4486
6922
|
on_event: (s.on_event || []).map(convertOnEvent)
|
|
4487
6923
|
}));
|
|
4488
6924
|
const fields = ir.fields.map((f) => ({
|
|
4489
|
-
name:
|
|
6925
|
+
name: toSnakeCase3(f.name),
|
|
4490
6926
|
field_type: f.type,
|
|
4491
6927
|
label: f.label || f.name.replace(/([A-Z])/g, " $1").replace(/^./, (c) => c.toUpperCase()),
|
|
4492
6928
|
required: f.required || false,
|
|
@@ -4502,16 +6938,16 @@ function emitWorkflowDefinition(extracted) {
|
|
|
4502
6938
|
...f.editable_when && { editable_when: f.editable_when },
|
|
4503
6939
|
...f.state_home && { state_home: f.state_home }
|
|
4504
6940
|
}));
|
|
4505
|
-
const transitions = ir.transitions.map((
|
|
4506
|
-
name:
|
|
4507
|
-
from:
|
|
4508
|
-
to:
|
|
4509
|
-
description:
|
|
4510
|
-
roles:
|
|
4511
|
-
auto:
|
|
4512
|
-
conditions:
|
|
4513
|
-
actions: (
|
|
4514
|
-
required_fields:
|
|
6941
|
+
const transitions = ir.transitions.map((t23) => ({
|
|
6942
|
+
name: t23.name,
|
|
6943
|
+
from: t23.from,
|
|
6944
|
+
to: t23.to,
|
|
6945
|
+
description: t23.description || "",
|
|
6946
|
+
roles: t23.roles || [],
|
|
6947
|
+
auto: t23.auto || false,
|
|
6948
|
+
conditions: t23.conditions || [],
|
|
6949
|
+
actions: (t23.actions || []).map(convertAction),
|
|
6950
|
+
required_fields: t23.required_fields || [],
|
|
4515
6951
|
priority: 0
|
|
4516
6952
|
}));
|
|
4517
6953
|
const state_data = {};
|
|
@@ -4529,7 +6965,7 @@ function emitWorkflowDefinition(extracted) {
|
|
|
4529
6965
|
if (extracted.fields.length > 0) {
|
|
4530
6966
|
const localDefaults = {};
|
|
4531
6967
|
for (const f of extracted.fields) {
|
|
4532
|
-
localDefaults[
|
|
6968
|
+
localDefaults[toSnakeCase3(f.name)] = f.default_value ?? null;
|
|
4533
6969
|
}
|
|
4534
6970
|
if (!viewRoot.config) viewRoot.config = {};
|
|
4535
6971
|
viewRoot.config.localDefaults = localDefaults;
|
|
@@ -4587,11 +7023,11 @@ function compilerStateToWorkflow(state, metadata) {
|
|
|
4587
7023
|
extraMetadata: Object.keys(extraMetadata).length > 0 ? extraMetadata : void 0
|
|
4588
7024
|
};
|
|
4589
7025
|
}
|
|
4590
|
-
var PROP_RULES, COMPONENT_RENAMES, RENAME_EXTRA_CONFIG;
|
|
7026
|
+
var import_player_core, PROP_RULES, COMPONENT_RENAMES, RENAME_EXTRA_CONFIG;
|
|
4591
7027
|
var init_pure_form_emitter = __esm({
|
|
4592
7028
|
"src/babel/emitters/pure-form-emitter.ts"() {
|
|
4593
7029
|
"use strict";
|
|
4594
|
-
|
|
7030
|
+
import_player_core = require("@mindmatrix/player-core");
|
|
4595
7031
|
init_transition_extractor();
|
|
4596
7032
|
init_experience_transform();
|
|
4597
7033
|
PROP_RULES = {
|
|
@@ -4621,8 +7057,8 @@ var init_pure_form_emitter = __esm({
|
|
|
4621
7057
|
function resolveSlugArg(args, state) {
|
|
4622
7058
|
if (args.length < 1) return null;
|
|
4623
7059
|
const slugArg = args[0];
|
|
4624
|
-
if (
|
|
4625
|
-
if (
|
|
7060
|
+
if (t21.isStringLiteral(slugArg)) return slugArg.value;
|
|
7061
|
+
if (t21.isIdentifier(slugArg)) {
|
|
4626
7062
|
const compilerState = state;
|
|
4627
7063
|
const meta = compilerState.metadata;
|
|
4628
7064
|
const resolvedSlugs = meta.__modelImportSlugs;
|
|
@@ -4648,43 +7084,43 @@ function extractQueryDataSource(path, state) {
|
|
|
4648
7084
|
slug,
|
|
4649
7085
|
query: "list"
|
|
4650
7086
|
};
|
|
4651
|
-
if (args.length > 1 &&
|
|
7087
|
+
if (args.length > 1 && t21.isObjectExpression(args[1])) {
|
|
4652
7088
|
for (const prop of args[1].properties) {
|
|
4653
|
-
if (!
|
|
7089
|
+
if (!t21.isObjectProperty(prop) || !t21.isIdentifier(prop.key)) continue;
|
|
4654
7090
|
const key = prop.key.name;
|
|
4655
7091
|
const val = prop.value;
|
|
4656
7092
|
switch (key) {
|
|
4657
7093
|
case "limit":
|
|
4658
|
-
if (
|
|
7094
|
+
if (t21.isNumericLiteral(val)) {
|
|
4659
7095
|
dataSource.pageSize = val.value;
|
|
4660
7096
|
dataSource.paginated = true;
|
|
4661
7097
|
}
|
|
4662
7098
|
break;
|
|
4663
7099
|
case "orderBy":
|
|
4664
|
-
if (
|
|
7100
|
+
if (t21.isStringLiteral(val)) {
|
|
4665
7101
|
dataSource.sort = val.value;
|
|
4666
7102
|
}
|
|
4667
7103
|
break;
|
|
4668
7104
|
case "order":
|
|
4669
|
-
if (
|
|
7105
|
+
if (t21.isStringLiteral(val) && dataSource.sort) {
|
|
4670
7106
|
dataSource.sort = `${dataSource.sort}:${val.value}`;
|
|
4671
7107
|
}
|
|
4672
7108
|
break;
|
|
4673
7109
|
case "search":
|
|
4674
|
-
if (
|
|
7110
|
+
if (t21.isStringLiteral(val)) {
|
|
4675
7111
|
dataSource.search = val.value;
|
|
4676
7112
|
}
|
|
4677
7113
|
break;
|
|
4678
7114
|
case "searchFields":
|
|
4679
|
-
if (
|
|
4680
|
-
dataSource.searchFields = val.elements.filter((el) =>
|
|
7115
|
+
if (t21.isArrayExpression(val)) {
|
|
7116
|
+
dataSource.searchFields = val.elements.filter((el) => t21.isStringLiteral(el)).map((el) => el.value);
|
|
4681
7117
|
}
|
|
4682
7118
|
break;
|
|
4683
7119
|
case "filter":
|
|
4684
|
-
if (
|
|
7120
|
+
if (t21.isObjectExpression(val)) {
|
|
4685
7121
|
const filter = {};
|
|
4686
7122
|
for (const fp of val.properties) {
|
|
4687
|
-
if (
|
|
7123
|
+
if (t21.isObjectProperty(fp) && t21.isIdentifier(fp.key) && t21.isStringLiteral(fp.value)) {
|
|
4688
7124
|
filter[fp.key.name] = fp.value.value;
|
|
4689
7125
|
}
|
|
4690
7126
|
}
|
|
@@ -4694,19 +7130,19 @@ function extractQueryDataSource(path, state) {
|
|
|
4694
7130
|
}
|
|
4695
7131
|
break;
|
|
4696
7132
|
case "state":
|
|
4697
|
-
if (
|
|
7133
|
+
if (t21.isStringLiteral(val)) {
|
|
4698
7134
|
if (!dataSource.filter) dataSource.filter = {};
|
|
4699
7135
|
dataSource.filter.current_state = val.value;
|
|
4700
7136
|
}
|
|
4701
7137
|
break;
|
|
4702
7138
|
case "groupBy":
|
|
4703
|
-
if (
|
|
7139
|
+
if (t21.isStringLiteral(val)) {
|
|
4704
7140
|
dataSource.groupBy = val.value;
|
|
4705
7141
|
}
|
|
4706
7142
|
break;
|
|
4707
7143
|
case "facets":
|
|
4708
|
-
if (
|
|
4709
|
-
dataSource.facets = val.elements.filter((el) =>
|
|
7144
|
+
if (t21.isArrayExpression(val)) {
|
|
7145
|
+
dataSource.facets = val.elements.filter((el) => t21.isStringLiteral(el)).map((el) => el.value);
|
|
4710
7146
|
}
|
|
4711
7147
|
break;
|
|
4712
7148
|
}
|
|
@@ -4730,17 +7166,17 @@ function extractMutationDataSource(path, state) {
|
|
|
4730
7166
|
}
|
|
4731
7167
|
function extractDuringAction(path, state) {
|
|
4732
7168
|
const args = path.node.arguments;
|
|
4733
|
-
if (args.length < 1 || !
|
|
7169
|
+
if (args.length < 1 || !t21.isObjectExpression(args[0])) return;
|
|
4734
7170
|
const compilerState = state;
|
|
4735
7171
|
const config = args[0];
|
|
4736
7172
|
let stateName;
|
|
4737
7173
|
let intervalMs = 1e3;
|
|
4738
7174
|
for (const prop of config.properties) {
|
|
4739
|
-
if (!
|
|
4740
|
-
if (prop.key.name === "state" &&
|
|
7175
|
+
if (!t21.isObjectProperty(prop) || !t21.isIdentifier(prop.key)) continue;
|
|
7176
|
+
if (prop.key.name === "state" && t21.isStringLiteral(prop.value)) {
|
|
4741
7177
|
stateName = prop.value.value;
|
|
4742
7178
|
}
|
|
4743
|
-
if (prop.key.name === "intervalMs" &&
|
|
7179
|
+
if (prop.key.name === "intervalMs" && t21.isNumericLiteral(prop.value)) {
|
|
4744
7180
|
intervalMs = prop.value.value;
|
|
4745
7181
|
}
|
|
4746
7182
|
}
|
|
@@ -4766,7 +7202,7 @@ function extractDuringAction(path, state) {
|
|
|
4766
7202
|
}
|
|
4767
7203
|
function extractRoleDependency(path, state) {
|
|
4768
7204
|
const args = path.node.arguments;
|
|
4769
|
-
if (args.length < 1 || !
|
|
7205
|
+
if (args.length < 1 || !t21.isStringLiteral(args[0])) return;
|
|
4770
7206
|
const compilerState = state;
|
|
4771
7207
|
if (!compilerState.metadata) compilerState.metadata = {};
|
|
4772
7208
|
const meta = compilerState.metadata;
|
|
@@ -4777,7 +7213,7 @@ function extractRoleDependency(path, state) {
|
|
|
4777
7213
|
}
|
|
4778
7214
|
function extractViewDependency(path, state) {
|
|
4779
7215
|
const args = path.node.arguments;
|
|
4780
|
-
if (args.length < 1 || !
|
|
7216
|
+
if (args.length < 1 || !t21.isStringLiteral(args[0])) return;
|
|
4781
7217
|
const compilerState = state;
|
|
4782
7218
|
if (!compilerState.metadata) compilerState.metadata = {};
|
|
4783
7219
|
const meta = compilerState.metadata;
|
|
@@ -4794,7 +7230,7 @@ function extractParamsUsage(_path, state) {
|
|
|
4794
7230
|
}
|
|
4795
7231
|
function extractLibraryDependency(path, state) {
|
|
4796
7232
|
const args = path.node.arguments;
|
|
4797
|
-
if (args.length < 1 || !
|
|
7233
|
+
if (args.length < 1 || !t21.isStringLiteral(args[0])) return;
|
|
4798
7234
|
const compilerState = state;
|
|
4799
7235
|
if (!compilerState.metadata) compilerState.metadata = {};
|
|
4800
7236
|
const meta = compilerState.metadata;
|
|
@@ -4867,15 +7303,15 @@ function createVisitor(options = {}) {
|
|
|
4867
7303
|
}
|
|
4868
7304
|
}
|
|
4869
7305
|
const exportDeclaration = program.body.find(
|
|
4870
|
-
(node) =>
|
|
7306
|
+
(node) => t21.isExportNamedDeclaration(node) || t21.isExportDefaultDeclaration(node)
|
|
4871
7307
|
);
|
|
4872
7308
|
if (exportDeclaration) {
|
|
4873
7309
|
if (exportDeclaration.leadingComments) {
|
|
4874
7310
|
extractMetadataFromComments(exportDeclaration.leadingComments, compilerState.metadata);
|
|
4875
7311
|
}
|
|
4876
|
-
if (
|
|
7312
|
+
if (t21.isExportNamedDeclaration(exportDeclaration)) {
|
|
4877
7313
|
const declaration = exportDeclaration.declaration;
|
|
4878
|
-
if (
|
|
7314
|
+
if (t21.isFunctionDeclaration(declaration)) {
|
|
4879
7315
|
if (declaration.id) {
|
|
4880
7316
|
compilerState.metadata.name = declaration.id.name;
|
|
4881
7317
|
}
|
|
@@ -4883,16 +7319,16 @@ function createVisitor(options = {}) {
|
|
|
4883
7319
|
extractMetadataFromComments(declaration.leadingComments, compilerState.metadata);
|
|
4884
7320
|
}
|
|
4885
7321
|
}
|
|
4886
|
-
} else if (
|
|
7322
|
+
} else if (t21.isExportDefaultDeclaration(exportDeclaration)) {
|
|
4887
7323
|
const declaration = exportDeclaration.declaration;
|
|
4888
|
-
if (
|
|
7324
|
+
if (t21.isFunctionDeclaration(declaration)) {
|
|
4889
7325
|
if (declaration.id) {
|
|
4890
7326
|
compilerState.metadata.name = declaration.id.name;
|
|
4891
7327
|
}
|
|
4892
7328
|
if (declaration.leadingComments) {
|
|
4893
7329
|
extractMetadataFromComments(declaration.leadingComments, compilerState.metadata);
|
|
4894
7330
|
}
|
|
4895
|
-
} else if (
|
|
7331
|
+
} else if (t21.isIdentifier(declaration)) {
|
|
4896
7332
|
compilerState.metadata.name = declaration.name;
|
|
4897
7333
|
}
|
|
4898
7334
|
}
|
|
@@ -4903,7 +7339,13 @@ function createVisitor(options = {}) {
|
|
|
4903
7339
|
compilerState.metadata.__slugAutoFallback = true;
|
|
4904
7340
|
}
|
|
4905
7341
|
Object.assign(state, compilerState);
|
|
4906
|
-
if (
|
|
7342
|
+
if (isImperativeWorkflowFile(_path, state.filename)) {
|
|
7343
|
+
extractImperativeWorkflow(_path, state);
|
|
7344
|
+
state.__isModelFile = true;
|
|
7345
|
+
if (!compilerState.metadata.category) {
|
|
7346
|
+
compilerState.metadata.category = "workflow";
|
|
7347
|
+
}
|
|
7348
|
+
} else if (isModelFile(_path, state.filename)) {
|
|
4907
7349
|
extractModelFile(_path, state);
|
|
4908
7350
|
state.__isModelFile = true;
|
|
4909
7351
|
if (!compilerState.metadata.category) {
|
|
@@ -4914,6 +7356,15 @@ function createVisitor(options = {}) {
|
|
|
4914
7356
|
if (hasContextCreation(_path)) {
|
|
4915
7357
|
extractContextWorkflows(_path, state);
|
|
4916
7358
|
}
|
|
7359
|
+
if (hasMiddleware(_path)) {
|
|
7360
|
+
extractMiddleware(_path, state);
|
|
7361
|
+
}
|
|
7362
|
+
if (hasConstraints(_path)) {
|
|
7363
|
+
extractConstraints(_path, state);
|
|
7364
|
+
}
|
|
7365
|
+
if (hasActorConfig(_path)) {
|
|
7366
|
+
extractActorConfig(_path, state);
|
|
7367
|
+
}
|
|
4917
7368
|
if (isServerActionFile(state.filename)) {
|
|
4918
7369
|
extractServerActions(_path, state);
|
|
4919
7370
|
state.__isServerActionFile = true;
|
|
@@ -4949,7 +7400,7 @@ function createVisitor(options = {}) {
|
|
|
4949
7400
|
// Main hook extraction dispatcher
|
|
4950
7401
|
CallExpression(path, state) {
|
|
4951
7402
|
const callee = path.node.callee;
|
|
4952
|
-
if (!
|
|
7403
|
+
if (!t21.isIdentifier(callee)) return;
|
|
4953
7404
|
const compilerState = state;
|
|
4954
7405
|
const hookName = callee.name;
|
|
4955
7406
|
if (mode === "strict" && STRICT_BANNED_HOOKS[hookName]) {
|
|
@@ -5041,7 +7492,7 @@ function createVisitor(options = {}) {
|
|
|
5041
7492
|
if (!meta.__modelImports) meta.__modelImports = {};
|
|
5042
7493
|
const imports = meta.__modelImports;
|
|
5043
7494
|
for (const specifier of path.node.specifiers) {
|
|
5044
|
-
if (
|
|
7495
|
+
if (t21.isImportDefaultSpecifier(specifier) || t21.isImportSpecifier(specifier)) {
|
|
5045
7496
|
imports[specifier.local.name] = source;
|
|
5046
7497
|
}
|
|
5047
7498
|
}
|
|
@@ -5074,8 +7525,8 @@ function createVisitor(options = {}) {
|
|
|
5074
7525
|
if (!compilerState.metadata) return;
|
|
5075
7526
|
const id = path.node.id;
|
|
5076
7527
|
const init = path.node.init;
|
|
5077
|
-
if (
|
|
5078
|
-
if (!
|
|
7528
|
+
if (t21.isArrayPattern(id)) return;
|
|
7529
|
+
if (!t21.isIdentifier(id) || !init || !t21.isExpression(init)) return;
|
|
5079
7530
|
const parentFn = path.getFunctionParent();
|
|
5080
7531
|
if (!parentFn) return;
|
|
5081
7532
|
const parentNode = parentFn.parentPath;
|
|
@@ -5083,17 +7534,17 @@ function createVisitor(options = {}) {
|
|
|
5083
7534
|
let isExportedByName = false;
|
|
5084
7535
|
if (!isExportedDirectly && parentNode?.isVariableDeclarator()) {
|
|
5085
7536
|
const varId = parentNode.node.id;
|
|
5086
|
-
if (
|
|
7537
|
+
if (t21.isIdentifier(varId)) {
|
|
5087
7538
|
isExportedByName = varId.name === compilerState.metadata?.name;
|
|
5088
7539
|
}
|
|
5089
7540
|
}
|
|
5090
7541
|
if (!isExportedDirectly && !isExportedByName) return;
|
|
5091
|
-
if (
|
|
7542
|
+
if (t21.isCallExpression(init) && t21.isIdentifier(init.callee)) {
|
|
5092
7543
|
const callee = init.callee.name;
|
|
5093
7544
|
if (callee === "useQuery") {
|
|
5094
|
-
registerDerivedVar(id.name,
|
|
5095
|
-
|
|
5096
|
-
|
|
7545
|
+
registerDerivedVar(id.name, t21.optionalMemberExpression(
|
|
7546
|
+
t21.identifier("$instance"),
|
|
7547
|
+
t21.identifier(id.name),
|
|
5097
7548
|
false,
|
|
5098
7549
|
// computed
|
|
5099
7550
|
true
|
|
@@ -5102,23 +7553,23 @@ function createVisitor(options = {}) {
|
|
|
5102
7553
|
return;
|
|
5103
7554
|
}
|
|
5104
7555
|
if (callee === "useMutation") {
|
|
5105
|
-
registerDerivedVar(id.name,
|
|
5106
|
-
|
|
5107
|
-
|
|
7556
|
+
registerDerivedVar(id.name, t21.memberExpression(
|
|
7557
|
+
t21.identifier("$action"),
|
|
7558
|
+
t21.identifier("transition")
|
|
5108
7559
|
));
|
|
5109
7560
|
return;
|
|
5110
7561
|
}
|
|
5111
7562
|
if (callee === "useServerAction") {
|
|
5112
|
-
registerDerivedVar(id.name,
|
|
5113
|
-
|
|
5114
|
-
|
|
7563
|
+
registerDerivedVar(id.name, t21.memberExpression(
|
|
7564
|
+
t21.identifier("$action"),
|
|
7565
|
+
t21.identifier("serverAction")
|
|
5115
7566
|
));
|
|
5116
7567
|
return;
|
|
5117
7568
|
}
|
|
5118
7569
|
if (callee === "useServerState") {
|
|
5119
|
-
registerDerivedVar(id.name,
|
|
5120
|
-
|
|
5121
|
-
|
|
7570
|
+
registerDerivedVar(id.name, t21.optionalMemberExpression(
|
|
7571
|
+
t21.identifier("$instance"),
|
|
7572
|
+
t21.identifier("serverState"),
|
|
5122
7573
|
false,
|
|
5123
7574
|
true
|
|
5124
7575
|
));
|
|
@@ -5126,12 +7577,12 @@ function createVisitor(options = {}) {
|
|
|
5126
7577
|
}
|
|
5127
7578
|
if (callee === "useMemo" && init.arguments.length >= 1) {
|
|
5128
7579
|
const callback = init.arguments[0];
|
|
5129
|
-
if (
|
|
5130
|
-
if (
|
|
7580
|
+
if (t21.isArrowFunctionExpression(callback)) {
|
|
7581
|
+
if (t21.isExpression(callback.body)) {
|
|
5131
7582
|
registerDerivedVar(id.name, callback.body);
|
|
5132
|
-
} else if (
|
|
5133
|
-
const retStmt = callback.body.body.find((s) =>
|
|
5134
|
-
if (retStmt?.argument &&
|
|
7583
|
+
} else if (t21.isBlockStatement(callback.body)) {
|
|
7584
|
+
const retStmt = callback.body.body.find((s) => t21.isReturnStatement(s));
|
|
7585
|
+
if (retStmt?.argument && t21.isExpression(retStmt.argument)) {
|
|
5135
7586
|
registerDerivedVar(id.name, retStmt.argument);
|
|
5136
7587
|
}
|
|
5137
7588
|
}
|
|
@@ -5146,7 +7597,7 @@ function createVisitor(options = {}) {
|
|
|
5146
7597
|
// Only extract from the exported component function's direct return,
|
|
5147
7598
|
// not from nested callbacks (Each render functions, helper components, etc.).
|
|
5148
7599
|
ReturnStatement(path, state) {
|
|
5149
|
-
if (!
|
|
7600
|
+
if (!t21.isJSXElement(path.node.argument) && !t21.isJSXFragment(path.node.argument)) return;
|
|
5150
7601
|
const parentFn = path.getFunctionParent();
|
|
5151
7602
|
if (!parentFn) return;
|
|
5152
7603
|
const parentNode = parentFn.parentPath;
|
|
@@ -5154,7 +7605,7 @@ function createVisitor(options = {}) {
|
|
|
5154
7605
|
let isExportedByName = false;
|
|
5155
7606
|
if (!isExportedDirectly && parentNode?.isVariableDeclarator()) {
|
|
5156
7607
|
const varId = parentNode.node.id;
|
|
5157
|
-
if (
|
|
7608
|
+
if (t21.isIdentifier(varId)) {
|
|
5158
7609
|
isExportedByName = varId.name === state.metadata?.name;
|
|
5159
7610
|
}
|
|
5160
7611
|
}
|
|
@@ -5164,11 +7615,11 @@ function createVisitor(options = {}) {
|
|
|
5164
7615
|
}
|
|
5165
7616
|
};
|
|
5166
7617
|
}
|
|
5167
|
-
var
|
|
7618
|
+
var t21, STRICT_BANNED_HOOKS;
|
|
5168
7619
|
var init_visitor = __esm({
|
|
5169
7620
|
"src/babel/visitor.ts"() {
|
|
5170
7621
|
"use strict";
|
|
5171
|
-
|
|
7622
|
+
t21 = __toESM(require("@babel/types"));
|
|
5172
7623
|
init_state_extractor();
|
|
5173
7624
|
init_effect_extractor();
|
|
5174
7625
|
init_transition_extractor();
|
|
@@ -5179,11 +7630,15 @@ var init_visitor = __esm({
|
|
|
5179
7630
|
init_computed_extractor();
|
|
5180
7631
|
init_transition_effect_extractor();
|
|
5181
7632
|
init_model_extractor();
|
|
7633
|
+
init_flow_extractor();
|
|
5182
7634
|
init_server_action_extractor();
|
|
5183
7635
|
init_server_action_hook_extractor();
|
|
5184
7636
|
init_server_state_extractor();
|
|
5185
7637
|
init_grammar_island_extractor();
|
|
5186
7638
|
init_context_extractor();
|
|
7639
|
+
init_middleware_extractor();
|
|
7640
|
+
init_constraint_extractor();
|
|
7641
|
+
init_actor_extractor();
|
|
5187
7642
|
init_pure_form_emitter();
|
|
5188
7643
|
STRICT_BANNED_HOOKS = {
|
|
5189
7644
|
useEffect: "STRICT_USE_EFFECT",
|
|
@@ -5461,7 +7916,7 @@ function compileModel(filename, source, options = {}) {
|
|
|
5461
7916
|
ir,
|
|
5462
7917
|
interfaceName,
|
|
5463
7918
|
fieldNames: ir.fields.map((f) => f.name),
|
|
5464
|
-
transitionNames: ir.transitions.map((
|
|
7919
|
+
transitionNames: ir.transitions.map((t23) => t23.name),
|
|
5465
7920
|
stateNames: ir.states.map((s) => s.name),
|
|
5466
7921
|
hasFieldOptions: Object.keys(rawFieldOptions).length > 0,
|
|
5467
7922
|
fieldOptions: rawFieldOptions
|
|
@@ -5881,7 +8336,7 @@ function extractAction(source, filename) {
|
|
|
5881
8336
|
const fields = params.map((p) => paramToField(p));
|
|
5882
8337
|
const parameterMap = /* @__PURE__ */ new Map();
|
|
5883
8338
|
for (const p of params) {
|
|
5884
|
-
const snakeName =
|
|
8339
|
+
const snakeName = toSnakeCase4(p.name);
|
|
5885
8340
|
if (snakeName !== p.name) {
|
|
5886
8341
|
parameterMap.set(p.name, snakeName);
|
|
5887
8342
|
}
|
|
@@ -5901,7 +8356,7 @@ function extractAction(source, filename) {
|
|
|
5901
8356
|
}
|
|
5902
8357
|
if (isAsync) {
|
|
5903
8358
|
const segments = splitAtAwaits(body.body);
|
|
5904
|
-
const hasAwaits = segments.some((s) => s.kind
|
|
8359
|
+
const hasAwaits = segments.some((s) => s.kind !== "sync");
|
|
5905
8360
|
if (hasAwaits) {
|
|
5906
8361
|
const rewritten = rewriteAwaitReferences(segments);
|
|
5907
8362
|
const { states: states2, transitions: transitions2, bodyIsPure } = generateMultiStateIR(rewritten, warnings, parameterMap);
|
|
@@ -5976,10 +8431,10 @@ function extractAction(source, filename) {
|
|
|
5976
8431
|
function findDefaultExportedFunction(ast) {
|
|
5977
8432
|
const topLevelVars = /* @__PURE__ */ new Map();
|
|
5978
8433
|
for (const node of ast.program.body) {
|
|
5979
|
-
if (
|
|
8434
|
+
if (t22.isVariableDeclaration(node)) {
|
|
5980
8435
|
for (const decl of node.declarations) {
|
|
5981
|
-
if (
|
|
5982
|
-
if (
|
|
8436
|
+
if (t22.isIdentifier(decl.id) && decl.init) {
|
|
8437
|
+
if (t22.isArrowFunctionExpression(decl.init) || t22.isFunctionExpression(decl.init)) {
|
|
5983
8438
|
topLevelVars.set(decl.id.name, decl.init);
|
|
5984
8439
|
}
|
|
5985
8440
|
}
|
|
@@ -5987,19 +8442,19 @@ function findDefaultExportedFunction(ast) {
|
|
|
5987
8442
|
}
|
|
5988
8443
|
}
|
|
5989
8444
|
for (const node of ast.program.body) {
|
|
5990
|
-
if (
|
|
8445
|
+
if (t22.isExportDefaultDeclaration(node)) {
|
|
5991
8446
|
const decl = node.declaration;
|
|
5992
|
-
if (
|
|
8447
|
+
if (t22.isFunctionDeclaration(decl) && decl.body) {
|
|
5993
8448
|
const name = decl.id?.name ?? inferNameFromFile(decl) ?? "action";
|
|
5994
8449
|
return extractFromFunction(name, decl.params, decl.body, decl.returnType, decl.async);
|
|
5995
8450
|
}
|
|
5996
|
-
if (
|
|
5997
|
-
const name =
|
|
8451
|
+
if (t22.isArrowFunctionExpression(decl) || t22.isFunctionExpression(decl)) {
|
|
8452
|
+
const name = t22.isFunctionExpression(decl) && decl.id ? decl.id.name : "action";
|
|
5998
8453
|
const body = ensureBlock(decl.body);
|
|
5999
8454
|
if (!body) return null;
|
|
6000
8455
|
return extractFromFunction(name, decl.params, body, decl.returnType, decl.async);
|
|
6001
8456
|
}
|
|
6002
|
-
if (
|
|
8457
|
+
if (t22.isIdentifier(decl)) {
|
|
6003
8458
|
const fn = topLevelVars.get(decl.name);
|
|
6004
8459
|
if (fn) {
|
|
6005
8460
|
const body = ensureBlock(fn.body);
|
|
@@ -6013,28 +8468,28 @@ function findDefaultExportedFunction(ast) {
|
|
|
6013
8468
|
}
|
|
6014
8469
|
function extractFromFunction(name, params, body, returnType, isAsync = false) {
|
|
6015
8470
|
const extracted = params.map((p) => extractParam(p));
|
|
6016
|
-
const returnTypeAnnotation = returnType &&
|
|
8471
|
+
const returnTypeAnnotation = returnType && t22.isTSTypeAnnotation(returnType) ? serializeTSType(returnType.typeAnnotation) : void 0;
|
|
6017
8472
|
return { name, params: extracted, body, returnTypeAnnotation, isAsync };
|
|
6018
8473
|
}
|
|
6019
8474
|
function ensureBlock(body) {
|
|
6020
|
-
if (
|
|
6021
|
-
const ret =
|
|
6022
|
-
return
|
|
8475
|
+
if (t22.isBlockStatement(body)) return body;
|
|
8476
|
+
const ret = t22.returnStatement(body);
|
|
8477
|
+
return t22.blockStatement([ret]);
|
|
6023
8478
|
}
|
|
6024
8479
|
function inferNameFromFile(_node) {
|
|
6025
8480
|
return null;
|
|
6026
8481
|
}
|
|
6027
8482
|
function extractParam(param) {
|
|
6028
|
-
if (
|
|
8483
|
+
if (t22.isIdentifier(param)) {
|
|
6029
8484
|
return {
|
|
6030
8485
|
name: param.name,
|
|
6031
8486
|
typeAnnotation: param.typeAnnotation ? param.typeAnnotation.typeAnnotation : null,
|
|
6032
8487
|
optional: param.optional ?? false
|
|
6033
8488
|
};
|
|
6034
8489
|
}
|
|
6035
|
-
if (
|
|
8490
|
+
if (t22.isAssignmentPattern(param)) {
|
|
6036
8491
|
const inner = param.left;
|
|
6037
|
-
if (
|
|
8492
|
+
if (t22.isIdentifier(inner)) {
|
|
6038
8493
|
return {
|
|
6039
8494
|
name: inner.name,
|
|
6040
8495
|
typeAnnotation: inner.typeAnnotation ? inner.typeAnnotation.typeAnnotation : null,
|
|
@@ -6043,10 +8498,10 @@ function extractParam(param) {
|
|
|
6043
8498
|
};
|
|
6044
8499
|
}
|
|
6045
8500
|
}
|
|
6046
|
-
if (
|
|
8501
|
+
if (t22.isRestElement(param)) {
|
|
6047
8502
|
const arg = param.argument;
|
|
6048
8503
|
return {
|
|
6049
|
-
name:
|
|
8504
|
+
name: t22.isIdentifier(arg) ? arg.name : "rest",
|
|
6050
8505
|
typeAnnotation: null,
|
|
6051
8506
|
optional: true
|
|
6052
8507
|
};
|
|
@@ -6056,7 +8511,7 @@ function extractParam(param) {
|
|
|
6056
8511
|
function paramToField(param) {
|
|
6057
8512
|
const fieldType = param.typeAnnotation ? tsTypeToFieldType2(param.typeAnnotation) : "text";
|
|
6058
8513
|
const field = {
|
|
6059
|
-
name:
|
|
8514
|
+
name: toSnakeCase4(param.name),
|
|
6060
8515
|
type: fieldType,
|
|
6061
8516
|
required: !param.optional
|
|
6062
8517
|
};
|
|
@@ -6067,34 +8522,34 @@ function paramToField(param) {
|
|
|
6067
8522
|
}
|
|
6068
8523
|
function extractLiteralDefault(expr) {
|
|
6069
8524
|
if (!expr) return void 0;
|
|
6070
|
-
if (
|
|
6071
|
-
if (
|
|
6072
|
-
if (
|
|
6073
|
-
if (
|
|
6074
|
-
if (
|
|
6075
|
-
if (
|
|
8525
|
+
if (t22.isStringLiteral(expr)) return expr.value;
|
|
8526
|
+
if (t22.isNumericLiteral(expr)) return expr.value;
|
|
8527
|
+
if (t22.isBooleanLiteral(expr)) return expr.value;
|
|
8528
|
+
if (t22.isNullLiteral(expr)) return null;
|
|
8529
|
+
if (t22.isArrayExpression(expr) && expr.elements.length === 0) return [];
|
|
8530
|
+
if (t22.isObjectExpression(expr) && expr.properties.length === 0) return {};
|
|
6076
8531
|
return void 0;
|
|
6077
8532
|
}
|
|
6078
8533
|
function tsTypeToFieldType2(tsType) {
|
|
6079
|
-
if (
|
|
6080
|
-
if (
|
|
6081
|
-
if (
|
|
6082
|
-
if (
|
|
6083
|
-
if (
|
|
6084
|
-
if (
|
|
6085
|
-
if (
|
|
8534
|
+
if (t22.isTSStringKeyword(tsType)) return "text";
|
|
8535
|
+
if (t22.isTSNumberKeyword(tsType)) return "number";
|
|
8536
|
+
if (t22.isTSBooleanKeyword(tsType)) return "boolean";
|
|
8537
|
+
if (t22.isTSObjectKeyword(tsType)) return "json";
|
|
8538
|
+
if (t22.isTSAnyKeyword(tsType) || t22.isTSUnknownKeyword(tsType)) return "json";
|
|
8539
|
+
if (t22.isTSArrayType(tsType)) return "json";
|
|
8540
|
+
if (t22.isTSUnionType(tsType)) {
|
|
6086
8541
|
const nonNullable = tsType.types.filter(
|
|
6087
|
-
(
|
|
8542
|
+
(t23) => !t22.isTSNullKeyword(t23) && !t22.isTSUndefinedKeyword(t23)
|
|
6088
8543
|
);
|
|
6089
8544
|
if (nonNullable.length === 1) {
|
|
6090
8545
|
return tsTypeToFieldType2(nonNullable[0]);
|
|
6091
8546
|
}
|
|
6092
|
-
if (nonNullable.every((
|
|
8547
|
+
if (nonNullable.every((t23) => t22.isTSLiteralType(t23) && t22.isStringLiteral(t23.literal))) {
|
|
6093
8548
|
return "select";
|
|
6094
8549
|
}
|
|
6095
8550
|
return "text";
|
|
6096
8551
|
}
|
|
6097
|
-
if (
|
|
8552
|
+
if (t22.isTSTypeReference(tsType) && t22.isIdentifier(tsType.typeName)) {
|
|
6098
8553
|
const name = tsType.typeName.name;
|
|
6099
8554
|
if (name === "Date") return "datetime";
|
|
6100
8555
|
if (name === "string") return "text";
|
|
@@ -6104,16 +8559,16 @@ function tsTypeToFieldType2(tsType) {
|
|
|
6104
8559
|
return "text";
|
|
6105
8560
|
}
|
|
6106
8561
|
function serializeTSType(tsType) {
|
|
6107
|
-
if (
|
|
6108
|
-
if (
|
|
6109
|
-
if (
|
|
6110
|
-
if (
|
|
6111
|
-
if (
|
|
6112
|
-
if (
|
|
8562
|
+
if (t22.isTSStringKeyword(tsType)) return "string";
|
|
8563
|
+
if (t22.isTSNumberKeyword(tsType)) return "number";
|
|
8564
|
+
if (t22.isTSBooleanKeyword(tsType)) return "boolean";
|
|
8565
|
+
if (t22.isTSVoidKeyword(tsType)) return "void";
|
|
8566
|
+
if (t22.isTSAnyKeyword(tsType)) return "any";
|
|
8567
|
+
if (t22.isTSTypeReference(tsType) && t22.isIdentifier(tsType.typeName)) {
|
|
6113
8568
|
return tsType.typeName.name;
|
|
6114
8569
|
}
|
|
6115
|
-
if (
|
|
6116
|
-
if (
|
|
8570
|
+
if (t22.isTSArrayType(tsType)) return `${serializeTSType(tsType.elementType)}[]`;
|
|
8571
|
+
if (t22.isTSPromiseType(tsType)) {
|
|
6117
8572
|
return `Promise<${tsType.typeParameter ? serializeTSType(tsType.typeParameter.params[0]) : "unknown"}>`;
|
|
6118
8573
|
}
|
|
6119
8574
|
return "unknown";
|
|
@@ -6123,6 +8578,56 @@ function splitAtAwaits(body) {
|
|
|
6123
8578
|
let current = [];
|
|
6124
8579
|
let index = 0;
|
|
6125
8580
|
for (const stmt of body) {
|
|
8581
|
+
if (t22.isTryStatement(stmt) && containsAwait(stmt.block)) {
|
|
8582
|
+
if (current.length > 0) {
|
|
8583
|
+
segments.push({ index: index++, kind: "sync", statements: current });
|
|
8584
|
+
current = [];
|
|
8585
|
+
}
|
|
8586
|
+
const trySegs = splitAtAwaits(stmt.block.body);
|
|
8587
|
+
const catchStmts = stmt.handler?.body.body ?? [];
|
|
8588
|
+
const catchParam = stmt.handler?.param && t22.isIdentifier(stmt.handler.param) ? stmt.handler.param.name : "error";
|
|
8589
|
+
segments.push({
|
|
8590
|
+
index: index++,
|
|
8591
|
+
kind: "try_catch",
|
|
8592
|
+
statements: [stmt],
|
|
8593
|
+
trySegments: trySegs,
|
|
8594
|
+
catchStatements: catchStmts,
|
|
8595
|
+
catchParam
|
|
8596
|
+
});
|
|
8597
|
+
continue;
|
|
8598
|
+
}
|
|
8599
|
+
if (t22.isForOfStatement(stmt) && containsAwait(stmt.body)) {
|
|
8600
|
+
if (current.length > 0) {
|
|
8601
|
+
segments.push({ index: index++, kind: "sync", statements: current });
|
|
8602
|
+
current = [];
|
|
8603
|
+
}
|
|
8604
|
+
const loopBody = t22.isBlockStatement(stmt.body) ? stmt.body.body : [stmt.body];
|
|
8605
|
+
const loopBinding = t22.isVariableDeclaration(stmt.left) && t22.isIdentifier(stmt.left.declarations[0]?.id) ? stmt.left.declarations[0].id.name : "item";
|
|
8606
|
+
segments.push({
|
|
8607
|
+
index: index++,
|
|
8608
|
+
kind: "loop",
|
|
8609
|
+
statements: [stmt],
|
|
8610
|
+
loopBinding,
|
|
8611
|
+
loopIterable: stmt.right,
|
|
8612
|
+
loopBodySegments: splitAtAwaits(loopBody)
|
|
8613
|
+
});
|
|
8614
|
+
continue;
|
|
8615
|
+
}
|
|
8616
|
+
const promiseInfo = extractPromiseAllOrRace(stmt);
|
|
8617
|
+
if (promiseInfo) {
|
|
8618
|
+
if (current.length > 0) {
|
|
8619
|
+
segments.push({ index: index++, kind: "sync", statements: current });
|
|
8620
|
+
current = [];
|
|
8621
|
+
}
|
|
8622
|
+
segments.push({
|
|
8623
|
+
index: index++,
|
|
8624
|
+
kind: promiseInfo.type === "all" ? "parallel" : "race",
|
|
8625
|
+
statements: [stmt],
|
|
8626
|
+
parallelCallees: promiseInfo.callees,
|
|
8627
|
+
resultBinding: promiseInfo.binding
|
|
8628
|
+
});
|
|
8629
|
+
continue;
|
|
8630
|
+
}
|
|
6126
8631
|
const awaitInfo = extractAwait(stmt);
|
|
6127
8632
|
if (!awaitInfo) {
|
|
6128
8633
|
current.push(stmt);
|
|
@@ -6147,22 +8652,22 @@ function splitAtAwaits(body) {
|
|
|
6147
8652
|
return segments;
|
|
6148
8653
|
}
|
|
6149
8654
|
function extractAwait(stmt) {
|
|
6150
|
-
if (
|
|
8655
|
+
if (t22.isVariableDeclaration(stmt)) {
|
|
6151
8656
|
const decl = stmt.declarations[0];
|
|
6152
|
-
if (decl?.init &&
|
|
8657
|
+
if (decl?.init && t22.isAwaitExpression(decl.init)) {
|
|
6153
8658
|
const arg = decl.init.argument;
|
|
6154
|
-
if (
|
|
8659
|
+
if (t22.isCallExpression(arg)) {
|
|
6155
8660
|
return {
|
|
6156
8661
|
callee: getCalleeName(arg.callee),
|
|
6157
8662
|
args: arg.arguments,
|
|
6158
|
-
binding:
|
|
8663
|
+
binding: t22.isIdentifier(decl.id) ? decl.id.name : void 0
|
|
6159
8664
|
};
|
|
6160
8665
|
}
|
|
6161
8666
|
}
|
|
6162
8667
|
}
|
|
6163
|
-
if (
|
|
8668
|
+
if (t22.isExpressionStatement(stmt) && t22.isAwaitExpression(stmt.expression)) {
|
|
6164
8669
|
const arg = stmt.expression.argument;
|
|
6165
|
-
if (
|
|
8670
|
+
if (t22.isCallExpression(arg)) {
|
|
6166
8671
|
return {
|
|
6167
8672
|
callee: getCalleeName(arg.callee),
|
|
6168
8673
|
args: arg.arguments,
|
|
@@ -6170,9 +8675,9 @@ function extractAwait(stmt) {
|
|
|
6170
8675
|
};
|
|
6171
8676
|
}
|
|
6172
8677
|
}
|
|
6173
|
-
if (
|
|
8678
|
+
if (t22.isReturnStatement(stmt) && stmt.argument && t22.isAwaitExpression(stmt.argument)) {
|
|
6174
8679
|
const arg = stmt.argument.argument;
|
|
6175
|
-
if (
|
|
8680
|
+
if (t22.isCallExpression(arg)) {
|
|
6176
8681
|
return {
|
|
6177
8682
|
callee: getCalleeName(arg.callee),
|
|
6178
8683
|
args: arg.arguments,
|
|
@@ -6182,9 +8687,89 @@ function extractAwait(stmt) {
|
|
|
6182
8687
|
}
|
|
6183
8688
|
return null;
|
|
6184
8689
|
}
|
|
8690
|
+
function containsAwait(node) {
|
|
8691
|
+
if (t22.isAwaitExpression(node)) return true;
|
|
8692
|
+
if (t22.isBlockStatement(node)) {
|
|
8693
|
+
return node.body.some((s) => containsAwait(s));
|
|
8694
|
+
}
|
|
8695
|
+
if (t22.isExpressionStatement(node)) {
|
|
8696
|
+
return containsAwait(node.expression);
|
|
8697
|
+
}
|
|
8698
|
+
if (t22.isVariableDeclaration(node)) {
|
|
8699
|
+
return node.declarations.some((d) => d.init ? containsAwait(d.init) : false);
|
|
8700
|
+
}
|
|
8701
|
+
if (t22.isReturnStatement(node) && node.argument) {
|
|
8702
|
+
return containsAwait(node.argument);
|
|
8703
|
+
}
|
|
8704
|
+
if (t22.isCallExpression(node)) {
|
|
8705
|
+
return node.arguments.some((a) => t22.isNode(a) && containsAwait(a));
|
|
8706
|
+
}
|
|
8707
|
+
if (t22.isForOfStatement(node)) {
|
|
8708
|
+
return containsAwait(node.body);
|
|
8709
|
+
}
|
|
8710
|
+
if (t22.isForStatement(node)) {
|
|
8711
|
+
return containsAwait(node.body);
|
|
8712
|
+
}
|
|
8713
|
+
if (t22.isIfStatement(node)) {
|
|
8714
|
+
return containsAwait(node.consequent) || (node.alternate ? containsAwait(node.alternate) : false);
|
|
8715
|
+
}
|
|
8716
|
+
if (t22.isTryStatement(node)) {
|
|
8717
|
+
return containsAwait(node.block) || (node.handler ? containsAwait(node.handler.body) : false);
|
|
8718
|
+
}
|
|
8719
|
+
if (t22.isArrayExpression(node)) {
|
|
8720
|
+
return node.elements.some((e) => e && !t22.isSpreadElement(e) && containsAwait(e));
|
|
8721
|
+
}
|
|
8722
|
+
return false;
|
|
8723
|
+
}
|
|
8724
|
+
function extractPromiseAllOrRace(stmt) {
|
|
8725
|
+
let awaitExpr = null;
|
|
8726
|
+
let binding;
|
|
8727
|
+
if (t22.isVariableDeclaration(stmt)) {
|
|
8728
|
+
const decl = stmt.declarations[0];
|
|
8729
|
+
if (decl?.init && t22.isAwaitExpression(decl.init)) {
|
|
8730
|
+
awaitExpr = decl.init;
|
|
8731
|
+
binding = t22.isIdentifier(decl.id) ? decl.id.name : t22.isArrayPattern(decl.id) ? "__destructured__" : void 0;
|
|
8732
|
+
}
|
|
8733
|
+
} else if (t22.isExpressionStatement(stmt) && t22.isAwaitExpression(stmt.expression)) {
|
|
8734
|
+
awaitExpr = stmt.expression;
|
|
8735
|
+
}
|
|
8736
|
+
if (!awaitExpr) return null;
|
|
8737
|
+
const arg = awaitExpr.argument;
|
|
8738
|
+
if (!t22.isCallExpression(arg)) return null;
|
|
8739
|
+
if (!t22.isMemberExpression(arg.callee)) return null;
|
|
8740
|
+
if (!t22.isIdentifier(arg.callee.object) || arg.callee.object.name !== "Promise") return null;
|
|
8741
|
+
if (!t22.isIdentifier(arg.callee.property)) return null;
|
|
8742
|
+
const method = arg.callee.property.name;
|
|
8743
|
+
if (method !== "all" && method !== "race") return null;
|
|
8744
|
+
const firstArg = arg.arguments[0];
|
|
8745
|
+
if (!t22.isArrayExpression(firstArg)) return null;
|
|
8746
|
+
const callees = [];
|
|
8747
|
+
for (const elem of firstArg.elements) {
|
|
8748
|
+
if (!elem || t22.isSpreadElement(elem)) continue;
|
|
8749
|
+
if (t22.isCallExpression(elem)) {
|
|
8750
|
+
callees.push({
|
|
8751
|
+
callee: getCalleeName(elem.callee),
|
|
8752
|
+
args: elem.arguments
|
|
8753
|
+
});
|
|
8754
|
+
}
|
|
8755
|
+
}
|
|
8756
|
+
if (callees.length === 0) return null;
|
|
8757
|
+
if (binding === "__destructured__" && t22.isVariableDeclaration(stmt)) {
|
|
8758
|
+
const decl = stmt.declarations[0];
|
|
8759
|
+
if (t22.isArrayPattern(decl.id)) {
|
|
8760
|
+
for (let i = 0; i < decl.id.elements.length && i < callees.length; i++) {
|
|
8761
|
+
const elem = decl.id.elements[i];
|
|
8762
|
+
if (t22.isIdentifier(elem)) {
|
|
8763
|
+
callees[i].binding = elem.name;
|
|
8764
|
+
}
|
|
8765
|
+
}
|
|
8766
|
+
}
|
|
8767
|
+
}
|
|
8768
|
+
return { type: method, callees, binding };
|
|
8769
|
+
}
|
|
6185
8770
|
function getCalleeName(callee) {
|
|
6186
|
-
if (
|
|
6187
|
-
if (
|
|
8771
|
+
if (t22.isIdentifier(callee)) return callee.name;
|
|
8772
|
+
if (t22.isMemberExpression(callee) && t22.isIdentifier(callee.object) && t22.isIdentifier(callee.property)) {
|
|
6188
8773
|
return `${callee.object.name}_${callee.property.name}`;
|
|
6189
8774
|
}
|
|
6190
8775
|
return "unknown_action";
|
|
@@ -6194,7 +8779,7 @@ function rewriteAwaitReferences(segments) {
|
|
|
6194
8779
|
const slugCounts = /* @__PURE__ */ new Map();
|
|
6195
8780
|
return segments.map((seg) => {
|
|
6196
8781
|
if (seg.kind === "await" && seg.resultBinding) {
|
|
6197
|
-
const slug =
|
|
8782
|
+
const slug = toSnakeCase4(seg.awaitTarget ?? "unknown");
|
|
6198
8783
|
const count = (slugCounts.get(slug) ?? 0) + 1;
|
|
6199
8784
|
slugCounts.set(slug, count);
|
|
6200
8785
|
const key = count > 1 ? `${slug}_${count}` : slug;
|
|
@@ -6222,7 +8807,7 @@ function generateMultiStateIR(segments, _warnings, parameterMap) {
|
|
|
6222
8807
|
const slugCounts = /* @__PURE__ */ new Map();
|
|
6223
8808
|
for (const seg of segments) {
|
|
6224
8809
|
if (seg.kind === "await" && seg.resultBinding) {
|
|
6225
|
-
const slug =
|
|
8810
|
+
const slug = toSnakeCase4(seg.awaitTarget ?? "unknown");
|
|
6226
8811
|
const count = (slugCounts.get(slug) ?? 0) + 1;
|
|
6227
8812
|
slugCounts.set(slug, count);
|
|
6228
8813
|
const key = count > 1 ? `${slug}_${count}` : slug;
|
|
@@ -6239,7 +8824,177 @@ function generateMultiStateIR(segments, _warnings, parameterMap) {
|
|
|
6239
8824
|
pendingSyncStmts.push(...seg.statements);
|
|
6240
8825
|
continue;
|
|
6241
8826
|
}
|
|
6242
|
-
|
|
8827
|
+
if (seg.kind === "try_catch" && seg.trySegments) {
|
|
8828
|
+
if (pendingSyncStmts.length > 0) {
|
|
8829
|
+
const block = t22.blockStatement(pendingSyncStmts);
|
|
8830
|
+
const transpiled = transpileBlock(block, { allMutable: true, derivedVarMap: buildDerivedVarMap(awaitBindings), parameterMap });
|
|
8831
|
+
if (!transpiled.pure) bodyIsPure = false;
|
|
8832
|
+
const preState = uniqueState("pre_try", usedStateNames);
|
|
8833
|
+
states.push({ name: preState, type: "REGULAR", on_enter: [], during: [], on_exit: [] });
|
|
8834
|
+
transitions.push({
|
|
8835
|
+
name: transitionCount === 0 ? "execute" : `on_${getStateSuffix(prevState)}_complete`,
|
|
8836
|
+
from: [prevState],
|
|
8837
|
+
to: preState,
|
|
8838
|
+
actions: [{ id: `pre_try_${transitionCount}`, type: "eval", mode: "auto", config: { expression: transpiled.expression } }]
|
|
8839
|
+
});
|
|
8840
|
+
prevState = preState;
|
|
8841
|
+
transitionCount++;
|
|
8842
|
+
pendingSyncStmts = [];
|
|
8843
|
+
}
|
|
8844
|
+
const tryResult = generateMultiStateIR(seg.trySegments, _warnings, parameterMap);
|
|
8845
|
+
if (!tryResult.bodyIsPure) bodyIsPure = false;
|
|
8846
|
+
const successState = uniqueState("try_success", usedStateNames);
|
|
8847
|
+
const errorState = uniqueState("try_error", usedStateNames);
|
|
8848
|
+
states.push({ name: errorState, type: "REGULAR", on_enter: [], during: [], on_exit: [] });
|
|
8849
|
+
states.push({ name: successState, type: "REGULAR", on_enter: [], during: [], on_exit: [] });
|
|
8850
|
+
for (const s of tryResult.states) {
|
|
8851
|
+
if (s.name === "ready" || s.name === "done") continue;
|
|
8852
|
+
states.push(s);
|
|
8853
|
+
}
|
|
8854
|
+
for (const tr of tryResult.transitions) {
|
|
8855
|
+
const remappedFrom = tr.from.map((f) => f === "ready" ? prevState : f);
|
|
8856
|
+
const remappedTo = tr.to === "done" ? successState : tr.to;
|
|
8857
|
+
transitions.push({ ...tr, from: remappedFrom, to: remappedTo });
|
|
8858
|
+
if (tr.actions.some((a) => a.type === "call_workflow")) {
|
|
8859
|
+
const awaitState = tr.to === successState ? successState : tr.to;
|
|
8860
|
+
if (awaitState !== successState) {
|
|
8861
|
+
transitions.push({
|
|
8862
|
+
name: `on_${getStateSuffix(awaitState)}_error`,
|
|
8863
|
+
from: [awaitState],
|
|
8864
|
+
to: errorState,
|
|
8865
|
+
actions: [],
|
|
8866
|
+
conditions: [{ expression: "action_error != null", type: "expression" }]
|
|
8867
|
+
});
|
|
8868
|
+
}
|
|
8869
|
+
}
|
|
8870
|
+
}
|
|
8871
|
+
if (tryResult.transitions.length > 0 && transitionCount === 0) {
|
|
8872
|
+
transitions[transitions.length - tryResult.transitions.length].name = "execute";
|
|
8873
|
+
}
|
|
8874
|
+
if (seg.catchStatements && seg.catchStatements.length > 0) {
|
|
8875
|
+
const catchBlock = t22.blockStatement(seg.catchStatements);
|
|
8876
|
+
const catchBindings = new Map(awaitBindings);
|
|
8877
|
+
if (seg.catchParam) {
|
|
8878
|
+
catchBindings.set(seg.catchParam, "action_error");
|
|
8879
|
+
}
|
|
8880
|
+
const catchTranspiled = transpileBlock(catchBlock, {
|
|
8881
|
+
allMutable: true,
|
|
8882
|
+
derivedVarMap: buildDerivedVarMap(catchBindings),
|
|
8883
|
+
parameterMap
|
|
8884
|
+
});
|
|
8885
|
+
if (!catchTranspiled.pure) bodyIsPure = false;
|
|
8886
|
+
const postCatch = uniqueState("post_catch", usedStateNames);
|
|
8887
|
+
states.push({ name: postCatch, type: "REGULAR", on_enter: [], during: [], on_exit: [] });
|
|
8888
|
+
transitions.push({
|
|
8889
|
+
name: `catch_${transitionCount}`,
|
|
8890
|
+
from: [errorState],
|
|
8891
|
+
to: postCatch,
|
|
8892
|
+
actions: [{ id: `catch_eval_${transitionCount}`, type: "eval", mode: "auto", config: { expression: catchTranspiled.expression } }]
|
|
8893
|
+
});
|
|
8894
|
+
prevState = postCatch;
|
|
8895
|
+
transitions.push({
|
|
8896
|
+
name: `try_success_${transitionCount}`,
|
|
8897
|
+
from: [successState],
|
|
8898
|
+
to: postCatch,
|
|
8899
|
+
actions: []
|
|
8900
|
+
});
|
|
8901
|
+
} else {
|
|
8902
|
+
prevState = successState;
|
|
8903
|
+
}
|
|
8904
|
+
transitionCount++;
|
|
8905
|
+
continue;
|
|
8906
|
+
}
|
|
8907
|
+
if ((seg.kind === "parallel" || seg.kind === "race") && seg.parallelCallees) {
|
|
8908
|
+
if (pendingSyncStmts.length > 0) {
|
|
8909
|
+
const block = t22.blockStatement(pendingSyncStmts);
|
|
8910
|
+
const transpiled = transpileBlock(block, { allMutable: true, derivedVarMap: buildDerivedVarMap(awaitBindings), parameterMap });
|
|
8911
|
+
if (!transpiled.pure) bodyIsPure = false;
|
|
8912
|
+
pendingSyncStmts = [];
|
|
8913
|
+
}
|
|
8914
|
+
const groupId = `p${transitionCount}`;
|
|
8915
|
+
const dispatchKind = seg.kind === "parallel" ? "parallel" : "race";
|
|
8916
|
+
const stateName2 = uniqueState(`awaiting_${dispatchKind}_${transitionCount}`, usedStateNames);
|
|
8917
|
+
states.push({ name: stateName2, type: "REGULAR", on_enter: [], during: [], on_exit: [] });
|
|
8918
|
+
const actions2 = [];
|
|
8919
|
+
for (let ci = 0; ci < seg.parallelCallees.length; ci++) {
|
|
8920
|
+
const callee = seg.parallelCallees[ci];
|
|
8921
|
+
const slug = toSnakeCase4(callee.callee);
|
|
8922
|
+
actions2.push({
|
|
8923
|
+
id: `call_${slug}_${ci}`,
|
|
8924
|
+
type: "call_workflow",
|
|
8925
|
+
mode: "auto",
|
|
8926
|
+
config: {
|
|
8927
|
+
definition_slug: callee.callee,
|
|
8928
|
+
result_key: slug,
|
|
8929
|
+
[`${dispatchKind}_group`]: groupId
|
|
8930
|
+
}
|
|
8931
|
+
});
|
|
8932
|
+
if (callee.binding) {
|
|
8933
|
+
awaitBindings.set(callee.binding, `action_results.${slug}`);
|
|
8934
|
+
}
|
|
8935
|
+
}
|
|
8936
|
+
const transName2 = transitionCount === 0 ? "execute" : `on_${getStateSuffix(prevState)}_complete`;
|
|
8937
|
+
transitions.push({ name: transName2, from: [prevState], to: stateName2, actions: actions2 });
|
|
8938
|
+
prevState = stateName2;
|
|
8939
|
+
transitionCount++;
|
|
8940
|
+
continue;
|
|
8941
|
+
}
|
|
8942
|
+
if (seg.kind === "loop" && seg.loopBodySegments) {
|
|
8943
|
+
if (pendingSyncStmts.length > 0) {
|
|
8944
|
+
const block = t22.blockStatement(pendingSyncStmts);
|
|
8945
|
+
const transpiled = transpileBlock(block, { allMutable: true, derivedVarMap: buildDerivedVarMap(awaitBindings), parameterMap });
|
|
8946
|
+
if (!transpiled.pure) bodyIsPure = false;
|
|
8947
|
+
pendingSyncStmts = [];
|
|
8948
|
+
}
|
|
8949
|
+
const loopState = uniqueState(`loop_${toSnakeCase4(seg.loopBinding ?? "item")}`, usedStateNames);
|
|
8950
|
+
const postLoop = uniqueState("post_loop", usedStateNames);
|
|
8951
|
+
states.push({ name: loopState, type: "REGULAR", on_enter: [], during: [], on_exit: [] });
|
|
8952
|
+
states.push({ name: postLoop, type: "REGULAR", on_enter: [], during: [], on_exit: [] });
|
|
8953
|
+
const initTransName = transitionCount === 0 ? "execute" : `on_${getStateSuffix(prevState)}_complete`;
|
|
8954
|
+
transitions.push({
|
|
8955
|
+
name: initTransName,
|
|
8956
|
+
from: [prevState],
|
|
8957
|
+
to: loopState,
|
|
8958
|
+
actions: [{
|
|
8959
|
+
id: `loop_init_${transitionCount}`,
|
|
8960
|
+
type: "eval",
|
|
8961
|
+
mode: "auto",
|
|
8962
|
+
config: { expression: `let __loop_idx = 0; let __loop_items = ${seg.loopIterable ? toSnakeCase4(seg.loopBinding ?? "items") : "[]"}` }
|
|
8963
|
+
}]
|
|
8964
|
+
});
|
|
8965
|
+
const awaitSegs = seg.loopBodySegments.filter((s) => s.kind === "await");
|
|
8966
|
+
if (awaitSegs.length > 0) {
|
|
8967
|
+
const firstAwait = awaitSegs[0];
|
|
8968
|
+
const slug = toSnakeCase4(firstAwait.awaitTarget ?? "action");
|
|
8969
|
+
transitions.push({
|
|
8970
|
+
name: `loop_body_${transitionCount}`,
|
|
8971
|
+
from: [loopState],
|
|
8972
|
+
to: loopState,
|
|
8973
|
+
actions: [{
|
|
8974
|
+
id: `loop_call_${slug}`,
|
|
8975
|
+
type: "call_workflow",
|
|
8976
|
+
mode: "auto",
|
|
8977
|
+
config: {
|
|
8978
|
+
definition_slug: firstAwait.awaitTarget,
|
|
8979
|
+
result_key: slug,
|
|
8980
|
+
loop_iteration: true
|
|
8981
|
+
}
|
|
8982
|
+
}],
|
|
8983
|
+
conditions: [{ expression: "__loop_idx < length(__loop_items)", type: "expression" }]
|
|
8984
|
+
});
|
|
8985
|
+
}
|
|
8986
|
+
transitions.push({
|
|
8987
|
+
name: `loop_done_${transitionCount}`,
|
|
8988
|
+
from: [loopState],
|
|
8989
|
+
to: postLoop,
|
|
8990
|
+
actions: [],
|
|
8991
|
+
conditions: [{ expression: "__loop_idx >= length(__loop_items)", type: "expression" }]
|
|
8992
|
+
});
|
|
8993
|
+
prevState = postLoop;
|
|
8994
|
+
transitionCount++;
|
|
8995
|
+
continue;
|
|
8996
|
+
}
|
|
8997
|
+
const targetSlug = toSnakeCase4(seg.awaitTarget ?? "unknown");
|
|
6243
8998
|
let stateName = `awaiting_${targetSlug}`;
|
|
6244
8999
|
if (usedStateNames.has(stateName)) {
|
|
6245
9000
|
let suffix = 2;
|
|
@@ -6250,7 +9005,7 @@ function generateMultiStateIR(segments, _warnings, parameterMap) {
|
|
|
6250
9005
|
states.push({ name: stateName, type: "REGULAR", on_enter: [], during: [], on_exit: [] });
|
|
6251
9006
|
const actions = [];
|
|
6252
9007
|
if (pendingSyncStmts.length > 0) {
|
|
6253
|
-
const block =
|
|
9008
|
+
const block = t22.blockStatement(pendingSyncStmts);
|
|
6254
9009
|
const transpiled = transpileBlock(block, {
|
|
6255
9010
|
allMutable: true,
|
|
6256
9011
|
derivedVarMap: buildDerivedVarMap(awaitBindings),
|
|
@@ -6273,9 +9028,9 @@ function generateMultiStateIR(segments, _warnings, parameterMap) {
|
|
|
6273
9028
|
const params = {};
|
|
6274
9029
|
for (let i = 0; i < seg.awaitArgs.length; i++) {
|
|
6275
9030
|
const arg = seg.awaitArgs[i];
|
|
6276
|
-
if (
|
|
9031
|
+
if (t22.isObjectExpression(arg)) {
|
|
6277
9032
|
for (const prop of arg.properties) {
|
|
6278
|
-
if (
|
|
9033
|
+
if (t22.isObjectProperty(prop) && t22.isIdentifier(prop.key)) {
|
|
6279
9034
|
const { expression: valExpr } = transpileArgExpression(prop.value, awaitBindings);
|
|
6280
9035
|
params[prop.key.name] = valExpr;
|
|
6281
9036
|
}
|
|
@@ -6308,7 +9063,7 @@ function generateMultiStateIR(segments, _warnings, parameterMap) {
|
|
|
6308
9063
|
states.push({ name: "done", type: "END", on_enter: [], during: [], on_exit: [] });
|
|
6309
9064
|
const finalActions = [];
|
|
6310
9065
|
if (pendingSyncStmts.length > 0) {
|
|
6311
|
-
const block =
|
|
9066
|
+
const block = t22.blockStatement(pendingSyncStmts);
|
|
6312
9067
|
const transpiled = transpileBlock(block, {
|
|
6313
9068
|
allMutable: true,
|
|
6314
9069
|
derivedVarMap: buildDerivedVarMap(awaitBindings),
|
|
@@ -6331,46 +9086,57 @@ function generateMultiStateIR(segments, _warnings, parameterMap) {
|
|
|
6331
9086
|
});
|
|
6332
9087
|
return { states, transitions, bodyIsPure };
|
|
6333
9088
|
}
|
|
9089
|
+
function uniqueState(base, used) {
|
|
9090
|
+
if (!used.has(base)) {
|
|
9091
|
+
used.add(base);
|
|
9092
|
+
return base;
|
|
9093
|
+
}
|
|
9094
|
+
let suffix = 2;
|
|
9095
|
+
while (used.has(`${base}_${suffix}`)) suffix++;
|
|
9096
|
+
const name = `${base}_${suffix}`;
|
|
9097
|
+
used.add(name);
|
|
9098
|
+
return name;
|
|
9099
|
+
}
|
|
6334
9100
|
function getStateSuffix(stateName) {
|
|
6335
9101
|
return stateName.replace(/^awaiting_/, "");
|
|
6336
9102
|
}
|
|
6337
9103
|
function transpileArgExpression(expr, bindings) {
|
|
6338
|
-
if (
|
|
9104
|
+
if (t22.isIdentifier(expr)) {
|
|
6339
9105
|
const replacement = bindings.get(expr.name);
|
|
6340
9106
|
if (replacement) return { expression: replacement };
|
|
6341
|
-
return { expression: `state_data.${
|
|
9107
|
+
return { expression: `state_data.${toSnakeCase4(expr.name)}` };
|
|
6342
9108
|
}
|
|
6343
|
-
if (
|
|
9109
|
+
if (t22.isMemberExpression(expr) && t22.isIdentifier(expr.object)) {
|
|
6344
9110
|
const replacement = bindings.get(expr.object.name);
|
|
6345
|
-
if (replacement &&
|
|
9111
|
+
if (replacement && t22.isIdentifier(expr.property)) {
|
|
6346
9112
|
return { expression: `${replacement}.${expr.property.name}` };
|
|
6347
9113
|
}
|
|
6348
9114
|
}
|
|
6349
|
-
if (
|
|
6350
|
-
if (
|
|
6351
|
-
if (
|
|
9115
|
+
if (t22.isStringLiteral(expr)) return { expression: `'${expr.value}'` };
|
|
9116
|
+
if (t22.isNumericLiteral(expr)) return { expression: String(expr.value) };
|
|
9117
|
+
if (t22.isBooleanLiteral(expr)) return { expression: String(expr.value) };
|
|
6352
9118
|
const { transpile: transpile2 } = (init_ts_to_expression(), __toCommonJS(ts_to_expression_exports));
|
|
6353
9119
|
return { expression: transpile2(expr, { derivedVarMap: buildDerivedVarMap(bindings) }) };
|
|
6354
9120
|
}
|
|
6355
9121
|
function buildDerivedVarMap(bindings) {
|
|
6356
9122
|
const map = /* @__PURE__ */ new Map();
|
|
6357
9123
|
for (const [varName, path] of bindings) {
|
|
6358
|
-
map.set(varName,
|
|
9124
|
+
map.set(varName, t22.identifier(path));
|
|
6359
9125
|
}
|
|
6360
9126
|
return map;
|
|
6361
9127
|
}
|
|
6362
9128
|
function toKebabCase(name) {
|
|
6363
9129
|
return name.replace(/([A-Z])/g, "-$1").toLowerCase().replace(/^-/, "");
|
|
6364
9130
|
}
|
|
6365
|
-
function
|
|
9131
|
+
function toSnakeCase4(name) {
|
|
6366
9132
|
return name.replace(/([A-Z])/g, "_$1").toLowerCase().replace(/^_/, "");
|
|
6367
9133
|
}
|
|
6368
|
-
var import_parser,
|
|
9134
|
+
var import_parser, t22;
|
|
6369
9135
|
var init_action_extractor = __esm({
|
|
6370
9136
|
"src/babel/extractors/action-extractor.ts"() {
|
|
6371
9137
|
"use strict";
|
|
6372
9138
|
import_parser = require("@babel/parser");
|
|
6373
|
-
|
|
9139
|
+
t22 = __toESM(require("@babel/types"));
|
|
6374
9140
|
init_ts_to_expression();
|
|
6375
9141
|
}
|
|
6376
9142
|
});
|