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