@mmapp/react-compiler 0.1.0-alpha.7 → 0.1.0-alpha.9
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/auth-3UK75242.mjs +17 -0
- package/dist/babel/index.d.mts +2 -2
- package/dist/babel/index.d.ts +2 -2
- package/dist/babel/index.js +27 -31
- package/dist/babel/index.mjs +1 -1
- package/dist/chunk-7T6Q5KAA.mjs +7506 -0
- package/dist/chunk-ABYPKRSB.mjs +215 -0
- package/dist/chunk-BZEXUPDH.mjs +175 -0
- package/dist/chunk-J3M4GUS7.mjs +161 -0
- package/dist/chunk-JRGFBWTN.mjs +2918 -0
- package/dist/chunk-R2DD5GTY.mjs +186 -0
- package/dist/chunk-UDDTWG5J.mjs +734 -0
- package/dist/chunk-VLTKQDJ3.mjs +244 -0
- package/dist/chunk-WVYY32LD.mjs +939 -0
- package/dist/chunk-XDVM4YHX.mjs +3450 -0
- package/dist/cli/index.js +4372 -3240
- package/dist/cli/index.mjs +77 -179
- package/dist/codemod/cli.js +1 -1
- package/dist/codemod/cli.mjs +1 -1
- package/dist/codemod/index.d.mts +3 -3
- package/dist/codemod/index.d.ts +3 -3
- package/dist/codemod/index.js +1 -1
- package/dist/codemod/index.mjs +1 -1
- package/dist/deploy-YAJGW6II.mjs +9 -0
- package/dist/dev-server-CrQ041KP.d.mts +79 -0
- package/dist/dev-server-CrQ041KP.d.ts +79 -0
- package/dist/dev-server.d.mts +2 -2
- package/dist/dev-server.d.ts +2 -2
- package/dist/dev-server.js +1240 -120
- package/dist/dev-server.mjs +4 -4
- package/dist/envelope-ChEkuHij.d.mts +265 -0
- package/dist/envelope-ChEkuHij.d.ts +265 -0
- package/dist/envelope.d.mts +2 -2
- package/dist/envelope.d.ts +2 -2
- package/dist/envelope.js +27 -31
- package/dist/envelope.mjs +2 -2
- package/dist/index-CEKyyazf.d.mts +104 -0
- package/dist/index-CEKyyazf.d.ts +104 -0
- package/dist/index.d.mts +8 -8
- package/dist/index.d.ts +8 -8
- package/dist/index.js +1512 -600
- package/dist/index.mjs +8 -8
- package/dist/init-7FJENUDK.mjs +407 -0
- package/dist/project-compiler-ZB4RUYVL.mjs +10 -0
- package/dist/project-decompiler-U55HQUHW.mjs +7 -0
- package/dist/pull-KOL2QAYQ.mjs +109 -0
- package/dist/seed-KOGEPGOJ.mjs +154 -0
- package/dist/server-VW6UPCHO.mjs +277 -0
- package/dist/testing/index.d.mts +8 -8
- package/dist/testing/index.d.ts +8 -8
- package/dist/testing/index.js +27 -31
- package/dist/testing/index.mjs +1 -1
- package/dist/verify-OQDEQYMS.mjs +1833 -0
- package/dist/vite/index.d.mts +1 -1
- package/dist/vite/index.d.ts +1 -1
- package/dist/vite/index.js +27 -31
- package/dist/vite/index.mjs +2 -2
- package/examples/authentication/main.workflow.tsx +1 -1
- package/examples/authentication/mm.config.ts +1 -1
- package/examples/authentication/pages/LoginPage.tsx +2 -2
- package/examples/authentication/pages/SignupPage.tsx +2 -2
- package/examples/counter.workflow.tsx +1 -1
- package/examples/dashboard.workflow.tsx +1 -1
- package/examples/invoice-approval/actions/invoice.server.ts +1 -1
- package/examples/invoice-approval/main.workflow.tsx +1 -1
- package/examples/invoice-approval/mm.config.ts +1 -1
- package/examples/invoice-approval/pages/InvoiceDetailPage.tsx +1 -1
- package/examples/invoice-approval/pages/InvoiceFormPage.tsx +1 -1
- package/examples/invoice-approval/pages/InvoiceListPage.tsx +1 -1
- package/examples/todo-app.workflow.tsx +1 -1
- package/examples/uber-app/actions/matching.server.ts +1 -1
- package/examples/uber-app/actions/notifications.server.ts +1 -1
- package/examples/uber-app/actions/payments.server.ts +1 -1
- package/examples/uber-app/actions/pricing.server.ts +1 -1
- package/examples/uber-app/app/admin/analytics.tsx +2 -2
- package/examples/uber-app/app/admin/fleet.tsx +2 -2
- package/examples/uber-app/app/admin/surge-pricing.tsx +2 -2
- package/examples/uber-app/app/driver/dashboard.tsx +2 -2
- package/examples/uber-app/app/driver/earnings.tsx +2 -2
- package/examples/uber-app/app/driver/navigation.tsx +2 -2
- package/examples/uber-app/app/driver/ride-acceptance.tsx +2 -2
- package/examples/uber-app/app/rider/home.tsx +2 -2
- package/examples/uber-app/app/rider/payment-methods.tsx +2 -2
- package/examples/uber-app/app/rider/ride-history.tsx +2 -2
- package/examples/uber-app/app/rider/ride-tracking.tsx +2 -2
- package/examples/uber-app/components/DriverCard.tsx +1 -1
- package/examples/uber-app/components/MapView.tsx +3 -3
- package/examples/uber-app/components/RatingStars.tsx +2 -2
- package/examples/uber-app/components/RideCard.tsx +1 -1
- package/examples/uber-app/mm.config.ts +1 -1
- package/examples/uber-app/workflows/dispute-resolution.workflow.tsx +2 -2
- package/examples/uber-app/workflows/driver-onboarding.workflow.tsx +2 -2
- package/examples/uber-app/workflows/payment-processing.workflow.tsx +2 -2
- package/examples/uber-app/workflows/ride-request.workflow.tsx +2 -2
- package/package.json +7 -14
package/dist/index.js
CHANGED
|
@@ -1874,18 +1874,6 @@ var init_component_extractor = __esm({
|
|
|
1874
1874
|
}
|
|
1875
1875
|
});
|
|
1876
1876
|
|
|
1877
|
-
// ../player-core/dist/index.mjs
|
|
1878
|
-
function normalizeCategory(primary, ...tags) {
|
|
1879
|
-
const uniqueTags = [...new Set(tags.filter((t27) => t27 !== primary))];
|
|
1880
|
-
uniqueTags.sort();
|
|
1881
|
-
return [primary, ...uniqueTags];
|
|
1882
|
-
}
|
|
1883
|
-
var init_dist = __esm({
|
|
1884
|
-
"../player-core/dist/index.mjs"() {
|
|
1885
|
-
"use strict";
|
|
1886
|
-
}
|
|
1887
|
-
});
|
|
1888
|
-
|
|
1889
1877
|
// src/babel/emitters/experience-transform.ts
|
|
1890
1878
|
function transformToFrontend(node) {
|
|
1891
1879
|
const result = {
|
|
@@ -2262,7 +2250,7 @@ function liftAction(action) {
|
|
|
2262
2250
|
}
|
|
2263
2251
|
return {
|
|
2264
2252
|
slug: action.id,
|
|
2265
|
-
category: normalizeCategory("expression", "mutation", action.type),
|
|
2253
|
+
category: (0, import_player_core.normalizeCategory)("expression", "mutation", action.type),
|
|
2266
2254
|
parts: parts.length > 0 ? parts : void 0
|
|
2267
2255
|
};
|
|
2268
2256
|
}
|
|
@@ -2292,7 +2280,7 @@ function liftSchedule(during) {
|
|
|
2292
2280
|
for (const action of during.actions) {
|
|
2293
2281
|
parts.push({
|
|
2294
2282
|
slug: "do",
|
|
2295
|
-
category: normalizeCategory("expression", "mutation", action.type),
|
|
2283
|
+
category: (0, import_player_core.normalizeCategory)("expression", "mutation", action.type),
|
|
2296
2284
|
parts: Object.entries(action.config || {}).map(([key, value]) => ({
|
|
2297
2285
|
slug: key,
|
|
2298
2286
|
category: ["atom"],
|
|
@@ -2302,7 +2290,7 @@ function liftSchedule(during) {
|
|
|
2302
2290
|
}
|
|
2303
2291
|
return {
|
|
2304
2292
|
slug: during.id,
|
|
2305
|
-
category: normalizeCategory("schedule", during.type),
|
|
2293
|
+
category: (0, import_player_core.normalizeCategory)("schedule", during.type),
|
|
2306
2294
|
parts
|
|
2307
2295
|
};
|
|
2308
2296
|
}
|
|
@@ -2315,14 +2303,14 @@ function liftState(state) {
|
|
|
2315
2303
|
if (state.on_enter && state.on_enter.length > 0) {
|
|
2316
2304
|
parts.push({
|
|
2317
2305
|
slug: "on_enter",
|
|
2318
|
-
category: normalizeCategory("expression", "sequence"),
|
|
2306
|
+
category: (0, import_player_core.normalizeCategory)("expression", "sequence"),
|
|
2319
2307
|
parts: state.on_enter.map(liftAction)
|
|
2320
2308
|
});
|
|
2321
2309
|
}
|
|
2322
2310
|
if (state.on_exit && state.on_exit.length > 0) {
|
|
2323
2311
|
parts.push({
|
|
2324
2312
|
slug: "on_exit",
|
|
2325
|
-
category: normalizeCategory("expression", "sequence"),
|
|
2313
|
+
category: (0, import_player_core.normalizeCategory)("expression", "sequence"),
|
|
2326
2314
|
parts: state.on_exit.map(liftAction)
|
|
2327
2315
|
});
|
|
2328
2316
|
}
|
|
@@ -2333,7 +2321,7 @@ function liftState(state) {
|
|
|
2333
2321
|
}
|
|
2334
2322
|
return {
|
|
2335
2323
|
slug: state.name,
|
|
2336
|
-
category: normalizeCategory("state", ...tags),
|
|
2324
|
+
category: (0, import_player_core.normalizeCategory)("state", ...tags),
|
|
2337
2325
|
parts: parts.length > 0 ? parts : void 0
|
|
2338
2326
|
};
|
|
2339
2327
|
}
|
|
@@ -2356,17 +2344,17 @@ function liftTransition(transition) {
|
|
|
2356
2344
|
if (transition.actions && transition.actions.length > 0) {
|
|
2357
2345
|
parts.push({
|
|
2358
2346
|
slug: "actions",
|
|
2359
|
-
category: normalizeCategory("expression", "sequence"),
|
|
2347
|
+
category: (0, import_player_core.normalizeCategory)("expression", "sequence"),
|
|
2360
2348
|
parts: transition.actions.map(liftAction)
|
|
2361
2349
|
});
|
|
2362
2350
|
}
|
|
2363
2351
|
if (transition.conditions && transition.conditions.length > 0) {
|
|
2364
2352
|
parts.push({
|
|
2365
2353
|
slug: "conditions",
|
|
2366
|
-
category: normalizeCategory("expression", "guard"),
|
|
2354
|
+
category: (0, import_player_core.normalizeCategory)("expression", "guard"),
|
|
2367
2355
|
parts: transition.conditions.map((c, i) => ({
|
|
2368
2356
|
slug: `condition_${i}`,
|
|
2369
|
-
category: normalizeCategory("expression", c.type || "condition"),
|
|
2357
|
+
category: (0, import_player_core.normalizeCategory)("expression", c.type || "condition"),
|
|
2370
2358
|
parts: c.expression ? [{ slug: c.expression, category: ["binding"] }] : void 0
|
|
2371
2359
|
}))
|
|
2372
2360
|
});
|
|
@@ -2405,7 +2393,7 @@ function liftField(field) {
|
|
|
2405
2393
|
}
|
|
2406
2394
|
return {
|
|
2407
2395
|
slug: field.name,
|
|
2408
|
-
category: normalizeCategory("field", field.type),
|
|
2396
|
+
category: (0, import_player_core.normalizeCategory)("field", field.type),
|
|
2409
2397
|
parts: parts.length > 0 ? parts : void 0
|
|
2410
2398
|
};
|
|
2411
2399
|
}
|
|
@@ -2428,20 +2416,20 @@ function liftView(node) {
|
|
|
2428
2416
|
if (match) {
|
|
2429
2417
|
parts.push({
|
|
2430
2418
|
slug: key,
|
|
2431
|
-
category: normalizeCategory("expression", "effect", "transition"),
|
|
2419
|
+
category: (0, import_player_core.normalizeCategory)("expression", "effect", "transition"),
|
|
2432
2420
|
parts: [{ slug: match[1], category: ["ref"] }]
|
|
2433
2421
|
});
|
|
2434
2422
|
} else {
|
|
2435
2423
|
parts.push({
|
|
2436
2424
|
slug: key,
|
|
2437
|
-
category: normalizeCategory("expression", "binding"),
|
|
2425
|
+
category: (0, import_player_core.normalizeCategory)("expression", "binding"),
|
|
2438
2426
|
parts: [{ slug: String(expr), category: ["binding"] }]
|
|
2439
2427
|
});
|
|
2440
2428
|
}
|
|
2441
2429
|
} else {
|
|
2442
2430
|
parts.push({
|
|
2443
2431
|
slug: key,
|
|
2444
|
-
category: normalizeCategory("expression", "binding"),
|
|
2432
|
+
category: (0, import_player_core.normalizeCategory)("expression", "binding"),
|
|
2445
2433
|
parts: [{ slug: String(expr), category: ["binding"] }]
|
|
2446
2434
|
});
|
|
2447
2435
|
}
|
|
@@ -2452,20 +2440,20 @@ function liftView(node) {
|
|
|
2452
2440
|
if (eqMatch) {
|
|
2453
2441
|
parts.push({
|
|
2454
2442
|
slug: "visible_when",
|
|
2455
|
-
category: normalizeCategory("expression", "guard"),
|
|
2443
|
+
category: (0, import_player_core.normalizeCategory)("expression", "guard"),
|
|
2456
2444
|
parts: [{
|
|
2457
2445
|
slug: "body",
|
|
2458
|
-
category: normalizeCategory("expression", "eq"),
|
|
2446
|
+
category: (0, import_player_core.normalizeCategory)("expression", "eq"),
|
|
2459
2447
|
parts: [
|
|
2460
|
-
{ slug: "lhs", category: normalizeCategory("expression", "path"), parts: [{ slug: eqMatch[1], category: ["binding"] }] },
|
|
2461
|
-
{ slug: "rhs", category: normalizeCategory("expression", "literal"), parts: [{ slug: eqMatch[2], category: ["literal"] }] }
|
|
2448
|
+
{ slug: "lhs", category: (0, import_player_core.normalizeCategory)("expression", "path"), parts: [{ slug: eqMatch[1], category: ["binding"] }] },
|
|
2449
|
+
{ slug: "rhs", category: (0, import_player_core.normalizeCategory)("expression", "literal"), parts: [{ slug: eqMatch[2], category: ["literal"] }] }
|
|
2462
2450
|
]
|
|
2463
2451
|
}]
|
|
2464
2452
|
});
|
|
2465
2453
|
} else {
|
|
2466
2454
|
parts.push({
|
|
2467
2455
|
slug: "visible_when",
|
|
2468
|
-
category: normalizeCategory("expression", "guard"),
|
|
2456
|
+
category: (0, import_player_core.normalizeCategory)("expression", "guard"),
|
|
2469
2457
|
parts: [{ slug: node.visible_when, category: ["binding"] }]
|
|
2470
2458
|
});
|
|
2471
2459
|
}
|
|
@@ -2477,7 +2465,7 @@ function liftView(node) {
|
|
|
2477
2465
|
}
|
|
2478
2466
|
return {
|
|
2479
2467
|
slug: node.id,
|
|
2480
|
-
category: normalizeCategory("view", componentTag),
|
|
2468
|
+
category: (0, import_player_core.normalizeCategory)("view", componentTag),
|
|
2481
2469
|
parts: parts.length > 0 ? parts : void 0
|
|
2482
2470
|
};
|
|
2483
2471
|
}
|
|
@@ -2498,7 +2486,7 @@ function emitCanonical(extracted, sourceFilename) {
|
|
|
2498
2486
|
}
|
|
2499
2487
|
parts.push({
|
|
2500
2488
|
slug: "manifest",
|
|
2501
|
-
category: normalizeCategory("meta", "manifest"),
|
|
2489
|
+
category: (0, import_player_core.normalizeCategory)("meta", "manifest"),
|
|
2502
2490
|
parts: [
|
|
2503
2491
|
{
|
|
2504
2492
|
slug: "workflows",
|
|
@@ -2519,7 +2507,7 @@ function emitCanonical(extracted, sourceFilename) {
|
|
|
2519
2507
|
let categoryArray;
|
|
2520
2508
|
if (category.includes("/")) {
|
|
2521
2509
|
const [primary, ...tags] = category.split("/");
|
|
2522
|
-
categoryArray = normalizeCategory(primary, ...tags);
|
|
2510
|
+
categoryArray = (0, import_player_core.normalizeCategory)(primary, ...tags);
|
|
2523
2511
|
} else {
|
|
2524
2512
|
categoryArray = [category];
|
|
2525
2513
|
}
|
|
@@ -2688,11 +2676,11 @@ function compilerStateToWorkflow(state, metadata) {
|
|
|
2688
2676
|
extraMetadata: Object.keys(extraMetadata).length > 0 ? extraMetadata : void 0
|
|
2689
2677
|
};
|
|
2690
2678
|
}
|
|
2691
|
-
var PROP_RULES, COMPONENT_RENAMES, RENAME_EXTRA_CONFIG, emitPureForm;
|
|
2679
|
+
var import_player_core, PROP_RULES, COMPONENT_RENAMES, RENAME_EXTRA_CONFIG, emitPureForm;
|
|
2692
2680
|
var init_pure_form_emitter = __esm({
|
|
2693
2681
|
"src/babel/emitters/pure-form-emitter.ts"() {
|
|
2694
2682
|
"use strict";
|
|
2695
|
-
|
|
2683
|
+
import_player_core = require("@mmapp/player-core");
|
|
2696
2684
|
init_transition_extractor();
|
|
2697
2685
|
init_experience_transform();
|
|
2698
2686
|
PROP_RULES = {
|
|
@@ -5232,7 +5220,7 @@ function extractImperativeWorkflow(path, state) {
|
|
|
5232
5220
|
const source = node.source.value;
|
|
5233
5221
|
for (const spec of node.specifiers) {
|
|
5234
5222
|
const localName = spec.local.name;
|
|
5235
|
-
if (source.includes("@mmapp/react") || source.includes("@
|
|
5223
|
+
if (source.includes("@mmapp/react") || source.includes("@mmapp/react")) {
|
|
5236
5224
|
stdLibImports.add(localName);
|
|
5237
5225
|
} else {
|
|
5238
5226
|
importedFns.set(localName, source);
|
|
@@ -7425,7 +7413,7 @@ function createVisitor(options = {}) {
|
|
|
7425
7413
|
if (mode === "strict" && STRICT_BANNED_HOOKS[hookName]) {
|
|
7426
7414
|
const error = {
|
|
7427
7415
|
code: STRICT_BANNED_HOOKS[hookName],
|
|
7428
|
-
message: `${hookName}() is not allowed in strict mode. Use @
|
|
7416
|
+
message: `${hookName}() is not allowed in strict mode. Use @mmapp/react effect hooks instead.`,
|
|
7429
7417
|
line: path.node.loc?.start.line,
|
|
7430
7418
|
column: path.node.loc?.start.column,
|
|
7431
7419
|
severity: "error"
|
|
@@ -7517,12 +7505,12 @@ function createVisitor(options = {}) {
|
|
|
7517
7505
|
}
|
|
7518
7506
|
}
|
|
7519
7507
|
if (mode !== "strict") return;
|
|
7520
|
-
if (source.startsWith("@
|
|
7508
|
+
if (source.startsWith("@mmapp/") || source.startsWith("@mmapp/") || source === "react" || source.startsWith("react/") || source.startsWith(".") || source.startsWith("/")) {
|
|
7521
7509
|
return;
|
|
7522
7510
|
}
|
|
7523
7511
|
const error = {
|
|
7524
7512
|
code: "STRICT_FORBIDDEN_IMPORT",
|
|
7525
|
-
message: `Import from '${source}' is not allowed in strict mode. Only @
|
|
7513
|
+
message: `Import from '${source}' is not allowed in strict mode. Only @mmapp/* and relative imports are permitted.`,
|
|
7526
7514
|
line: path.node.loc?.start.line,
|
|
7527
7515
|
column: path.node.loc?.start.column,
|
|
7528
7516
|
severity: "error"
|
|
@@ -10628,249 +10616,795 @@ var init_project_compiler = __esm({
|
|
|
10628
10616
|
}
|
|
10629
10617
|
});
|
|
10630
10618
|
|
|
10631
|
-
// src/
|
|
10632
|
-
var
|
|
10633
|
-
__export(
|
|
10634
|
-
|
|
10635
|
-
|
|
10636
|
-
|
|
10637
|
-
|
|
10638
|
-
|
|
10639
|
-
|
|
10640
|
-
buildDependencyGraph: () => buildDependencyGraph,
|
|
10641
|
-
buildEnvelope: () => buildEnvelope,
|
|
10642
|
-
compileActions: () => compileActions,
|
|
10643
|
-
compileModel: () => compileModel,
|
|
10644
|
-
compileModels: () => compileModels,
|
|
10645
|
-
compileProject: () => compileProject,
|
|
10646
|
-
compileSource: () => compileSource,
|
|
10647
|
-
compilerStateToWorkflow: () => compilerStateToWorkflow,
|
|
10648
|
-
computeEnvelopeId: () => computeEnvelopeId,
|
|
10649
|
-
computeTransitiveDirtySet: () => computeTransitiveDirtySet,
|
|
10650
|
-
createDevServer: () => createDevServer,
|
|
10651
|
-
createDiagnosticCollector: () => createDiagnosticCollector,
|
|
10652
|
-
createSourceEnvelope: () => createSourceEnvelope,
|
|
10653
|
-
createVisitor: () => createVisitor,
|
|
10654
|
-
decompile: () => decompile,
|
|
10655
|
-
decompileProject: () => decompileProject,
|
|
10656
|
-
decompileToTSX: () => decompileToTSX,
|
|
10657
|
-
deploy: () => deploy,
|
|
10658
|
-
detectFileRole: () => detectFileRole,
|
|
10659
|
-
diffEnvelopes: () => diffEnvelopes,
|
|
10660
|
-
diffFsTrees: () => diffFsTrees,
|
|
10661
|
-
emitCanonical: () => emitCanonical,
|
|
10662
|
-
emitCompiledOutput: () => emitCompiledOutput,
|
|
10663
|
-
emitIR: () => emitIR,
|
|
10664
|
-
emitPureForm: () => emitPureForm,
|
|
10665
|
-
envelopesEqual: () => envelopesEqual,
|
|
10666
|
-
extractComponents: () => extractComponents,
|
|
10667
|
-
extractComputed: () => extractComputed,
|
|
10668
|
-
extractEffects: () => extractEffects,
|
|
10669
|
-
extractEvents: () => extractEvents,
|
|
10670
|
-
extractImports: () => extractImports,
|
|
10671
|
-
extractRoutes: () => extractRoutes,
|
|
10672
|
-
extractStates: () => extractStates,
|
|
10673
|
-
extractTransitions: () => extractTransitions,
|
|
10674
|
-
filterByRole: () => filterByRole,
|
|
10675
|
-
generateFsTree: () => generateFsTree,
|
|
10676
|
-
hashContent: () => hashContent,
|
|
10677
|
-
normalizeDecompilerInput: () => normalizeDecompilerInput,
|
|
10678
|
-
resolveActionReferences: () => resolveActionReferences,
|
|
10679
|
-
resolveImport: () => resolveImport,
|
|
10680
|
-
shouldDecompileAsProject: () => shouldDecompileAsProject,
|
|
10681
|
-
topologicalSort: () => topologicalSort,
|
|
10682
|
-
transformToFrontend: () => transformToFrontend,
|
|
10683
|
-
validateRoundTrip: () => validateRoundTrip,
|
|
10684
|
-
validateSourceRoundTrip: () => validateSourceRoundTrip
|
|
10619
|
+
// src/cli/auth.ts
|
|
10620
|
+
var auth_exports = {};
|
|
10621
|
+
__export(auth_exports, {
|
|
10622
|
+
loadCredentials: () => loadCredentials,
|
|
10623
|
+
login: () => login,
|
|
10624
|
+
logout: () => logout,
|
|
10625
|
+
resolveToken: () => resolveToken,
|
|
10626
|
+
saveCredentials: () => saveCredentials,
|
|
10627
|
+
whoami: () => whoami
|
|
10685
10628
|
});
|
|
10686
|
-
|
|
10687
|
-
|
|
10688
|
-
|
|
10689
|
-
|
|
10690
|
-
|
|
10691
|
-
|
|
10692
|
-
init_pure_form_emitter();
|
|
10693
|
-
init_experience_transform();
|
|
10694
|
-
|
|
10695
|
-
// src/decompiler/index.ts
|
|
10696
|
-
var t10 = __toESM(require("@babel/types"));
|
|
10697
|
-
var import_generator = __toESM(require("@babel/generator"));
|
|
10698
|
-
|
|
10699
|
-
// src/decompiler/ast-builder.ts
|
|
10700
|
-
var t8 = __toESM(require("@babel/types"));
|
|
10701
|
-
var import_parser = require("@babel/parser");
|
|
10702
|
-
|
|
10703
|
-
// src/decompiler/sx-emitter.ts
|
|
10704
|
-
var t7 = __toESM(require("@babel/types"));
|
|
10705
|
-
function isTRBL(v) {
|
|
10706
|
-
if (typeof v !== "object" || v === null) return false;
|
|
10707
|
-
const obj = v;
|
|
10708
|
-
return typeof obj.top === "number" && typeof obj.right === "number" && typeof obj.bottom === "number" && typeof obj.left === "number";
|
|
10709
|
-
}
|
|
10710
|
-
function isFourCorners(v) {
|
|
10711
|
-
if (typeof v !== "object" || v === null) return false;
|
|
10712
|
-
const obj = v;
|
|
10713
|
-
return typeof obj.topLeft === "number" && typeof obj.topRight === "number" && typeof obj.bottomRight === "number" && typeof obj.bottomLeft === "number";
|
|
10714
|
-
}
|
|
10715
|
-
function isTokenRef(v) {
|
|
10716
|
-
if (typeof v !== "object" || v === null) return false;
|
|
10717
|
-
return v.kind === "token-ref";
|
|
10718
|
-
}
|
|
10719
|
-
function emitSpacingShorthand(prefix, trbl) {
|
|
10720
|
-
const { top, right, bottom, left } = trbl;
|
|
10721
|
-
if (top === right && right === bottom && bottom === left) {
|
|
10722
|
-
return [prop(prefix, top)];
|
|
10723
|
-
}
|
|
10724
|
-
if (top === bottom && left === right) {
|
|
10725
|
-
return [
|
|
10726
|
-
prop(`${prefix}y`, top),
|
|
10727
|
-
prop(`${prefix}x`, left)
|
|
10728
|
-
];
|
|
10629
|
+
function loadCredentials() {
|
|
10630
|
+
if (!(0, import_fs4.existsSync)(CREDENTIALS_PATH)) return {};
|
|
10631
|
+
try {
|
|
10632
|
+
return JSON.parse((0, import_fs4.readFileSync)(CREDENTIALS_PATH, "utf-8"));
|
|
10633
|
+
} catch {
|
|
10634
|
+
return {};
|
|
10729
10635
|
}
|
|
10730
|
-
return [
|
|
10731
|
-
prop(`${prefix}t`, top),
|
|
10732
|
-
prop(`${prefix}r`, right),
|
|
10733
|
-
prop(`${prefix}b`, bottom),
|
|
10734
|
-
prop(`${prefix}l`, left)
|
|
10735
|
-
];
|
|
10736
10636
|
}
|
|
10737
|
-
function
|
|
10738
|
-
|
|
10739
|
-
|
|
10740
|
-
|
|
10637
|
+
function saveCredentials(apiUrl, token) {
|
|
10638
|
+
(0, import_fs4.mkdirSync)(MMRC_DIR, { recursive: true, mode: 448 });
|
|
10639
|
+
const creds = loadCredentials();
|
|
10640
|
+
creds[apiUrl] = { token, savedAt: (/* @__PURE__ */ new Date()).toISOString() };
|
|
10641
|
+
(0, import_fs4.writeFileSync)(CREDENTIALS_PATH, JSON.stringify(creds, null, 2), "utf-8");
|
|
10642
|
+
try {
|
|
10643
|
+
const { chmodSync } = require("fs");
|
|
10644
|
+
chmodSync(CREDENTIALS_PATH, 384);
|
|
10645
|
+
} catch {
|
|
10741
10646
|
}
|
|
10742
|
-
return [
|
|
10743
|
-
prop("roundedTL", topLeft),
|
|
10744
|
-
prop("roundedTR", topRight),
|
|
10745
|
-
prop("roundedBR", bottomRight),
|
|
10746
|
-
prop("roundedBL", bottomLeft)
|
|
10747
|
-
];
|
|
10748
10647
|
}
|
|
10749
|
-
function
|
|
10750
|
-
if (
|
|
10751
|
-
|
|
10752
|
-
|
|
10753
|
-
|
|
10754
|
-
return t7.stringLiteral(color);
|
|
10648
|
+
function removeCredentials(apiUrl) {
|
|
10649
|
+
if (!(0, import_fs4.existsSync)(CREDENTIALS_PATH)) return;
|
|
10650
|
+
if (!apiUrl) {
|
|
10651
|
+
(0, import_fs4.unlinkSync)(CREDENTIALS_PATH);
|
|
10652
|
+
return;
|
|
10755
10653
|
}
|
|
10756
|
-
|
|
10757
|
-
|
|
10758
|
-
|
|
10759
|
-
|
|
10760
|
-
|
|
10761
|
-
|
|
10762
|
-
return t7.stringLiteral(hex);
|
|
10763
|
-
}
|
|
10764
|
-
return t7.stringLiteral(`rgba(${c.r}, ${c.g}, ${c.b}, ${a})`);
|
|
10765
|
-
}
|
|
10654
|
+
const creds = loadCredentials();
|
|
10655
|
+
delete creds[apiUrl];
|
|
10656
|
+
if (Object.keys(creds).length === 0) {
|
|
10657
|
+
(0, import_fs4.unlinkSync)(CREDENTIALS_PATH);
|
|
10658
|
+
} else {
|
|
10659
|
+
(0, import_fs4.writeFileSync)(CREDENTIALS_PATH, JSON.stringify(creds, null, 2), "utf-8");
|
|
10766
10660
|
}
|
|
10767
|
-
return t7.stringLiteral("inherit");
|
|
10768
10661
|
}
|
|
10769
|
-
function
|
|
10770
|
-
|
|
10771
|
-
|
|
10772
|
-
|
|
10773
|
-
|
|
10662
|
+
function resolveToken(apiUrl, explicitToken) {
|
|
10663
|
+
if (explicitToken) return explicitToken;
|
|
10664
|
+
const envToken = process.env.MMRC_TOKEN;
|
|
10665
|
+
if (envToken) return envToken;
|
|
10666
|
+
const creds = loadCredentials();
|
|
10667
|
+
const entry = creds[apiUrl];
|
|
10668
|
+
if (entry?.token) return entry.token;
|
|
10669
|
+
return null;
|
|
10774
10670
|
}
|
|
10775
|
-
function
|
|
10776
|
-
|
|
10777
|
-
|
|
10778
|
-
|
|
10779
|
-
|
|
10780
|
-
|
|
10781
|
-
|
|
10782
|
-
|
|
10783
|
-
|
|
10784
|
-
|
|
10785
|
-
|
|
10786
|
-
|
|
10787
|
-
|
|
10788
|
-
|
|
10789
|
-
|
|
10790
|
-
|
|
10791
|
-
|
|
10792
|
-
|
|
10671
|
+
function prompt(question, hidden = false) {
|
|
10672
|
+
return new Promise((resolve3) => {
|
|
10673
|
+
const rl = (0, import_readline.createInterface)({
|
|
10674
|
+
input: process.stdin,
|
|
10675
|
+
output: process.stdout
|
|
10676
|
+
});
|
|
10677
|
+
if (hidden && process.stdin.isTTY) {
|
|
10678
|
+
const origWrite = process.stdout.write.bind(process.stdout);
|
|
10679
|
+
process.stdout.write = ((chunk, encodingOrCb, cb) => {
|
|
10680
|
+
if (typeof chunk === "string" && chunk.includes(question)) {
|
|
10681
|
+
return origWrite(chunk, encodingOrCb, cb);
|
|
10682
|
+
}
|
|
10683
|
+
if (typeof chunk === "string" && !chunk.includes("\n")) {
|
|
10684
|
+
return true;
|
|
10685
|
+
}
|
|
10686
|
+
return origWrite(chunk, encodingOrCb, cb);
|
|
10687
|
+
});
|
|
10688
|
+
rl.question(question, (answer) => {
|
|
10689
|
+
process.stdout.write = origWrite;
|
|
10690
|
+
console.log();
|
|
10691
|
+
rl.close();
|
|
10692
|
+
resolve3(answer.trim());
|
|
10693
|
+
});
|
|
10694
|
+
} else {
|
|
10695
|
+
rl.question(question, (answer) => {
|
|
10696
|
+
rl.close();
|
|
10697
|
+
resolve3(answer.trim());
|
|
10698
|
+
});
|
|
10699
|
+
}
|
|
10700
|
+
});
|
|
10793
10701
|
}
|
|
10794
|
-
|
|
10795
|
-
|
|
10796
|
-
|
|
10797
|
-
focused: "focus",
|
|
10798
|
-
selected: "selected",
|
|
10799
|
-
disabled: "disabled"
|
|
10800
|
-
};
|
|
10801
|
-
function emitSxProp(style) {
|
|
10802
|
-
if (!style || typeof style !== "object") return null;
|
|
10803
|
-
const props = [];
|
|
10804
|
-
if (style.padding && isTRBL(style.padding)) {
|
|
10805
|
-
props.push(...emitSpacingShorthand("p", style.padding));
|
|
10806
|
-
}
|
|
10807
|
-
if (style.margin && isTRBL(style.margin)) {
|
|
10808
|
-
props.push(...emitSpacingShorthand("m", style.margin));
|
|
10809
|
-
}
|
|
10810
|
-
if (style.backgroundColor) {
|
|
10811
|
-
props.push(t7.objectProperty(
|
|
10812
|
-
t7.identifier("bg"),
|
|
10813
|
-
emitColorValue(style.backgroundColor)
|
|
10814
|
-
));
|
|
10815
|
-
}
|
|
10816
|
-
if (style.borderRadius && isFourCorners(style.borderRadius)) {
|
|
10817
|
-
props.push(...emitRadiusShorthand(style.borderRadius));
|
|
10818
|
-
}
|
|
10819
|
-
if (typeof style.gap === "number") {
|
|
10820
|
-
props.push(prop("gap", style.gap));
|
|
10821
|
-
}
|
|
10822
|
-
if (typeof style.flexDirection === "string") {
|
|
10823
|
-
props.push(prop("direction", style.flexDirection));
|
|
10824
|
-
}
|
|
10825
|
-
if (typeof style.justifyContent === "string") {
|
|
10826
|
-
props.push(prop("justify", style.justifyContent));
|
|
10827
|
-
}
|
|
10828
|
-
if (typeof style.alignItems === "string") {
|
|
10829
|
-
props.push(prop("align", style.alignItems));
|
|
10702
|
+
async function login(apiUrl, email, password) {
|
|
10703
|
+
if (!email) {
|
|
10704
|
+
email = await prompt("Email: ");
|
|
10830
10705
|
}
|
|
10831
|
-
if (
|
|
10832
|
-
|
|
10833
|
-
if (style.minWidth !== void 0) props.push(prop("minW", style.minWidth));
|
|
10834
|
-
if (style.minHeight !== void 0) props.push(prop("minH", style.minHeight));
|
|
10835
|
-
if (style.maxWidth !== void 0) props.push(prop("maxW", style.maxWidth));
|
|
10836
|
-
if (style.maxHeight !== void 0) props.push(prop("maxH", style.maxHeight));
|
|
10837
|
-
if (typeof style.opacity === "number") {
|
|
10838
|
-
props.push(prop("opacity", style.opacity));
|
|
10706
|
+
if (!password) {
|
|
10707
|
+
password = await prompt("Password: ", true);
|
|
10839
10708
|
}
|
|
10840
|
-
if (
|
|
10841
|
-
|
|
10842
|
-
t7.identifier("color"),
|
|
10843
|
-
emitColorValue(style.color)
|
|
10844
|
-
));
|
|
10709
|
+
if (!email || !password) {
|
|
10710
|
+
throw new Error("Email and password are required");
|
|
10845
10711
|
}
|
|
10846
|
-
|
|
10847
|
-
|
|
10712
|
+
console.log(`[mmrc] Logging in to ${apiUrl}...`);
|
|
10713
|
+
const res = await fetch(`${apiUrl}/auth/login`, {
|
|
10714
|
+
method: "POST",
|
|
10715
|
+
headers: { "Content-Type": "application/json" },
|
|
10716
|
+
body: JSON.stringify({ email, password })
|
|
10717
|
+
});
|
|
10718
|
+
if (!res.ok) {
|
|
10719
|
+
const text = await res.text();
|
|
10720
|
+
throw new Error(`Login failed: ${res.status} ${text}`);
|
|
10721
|
+
}
|
|
10722
|
+
const data = await res.json();
|
|
10723
|
+
const token = data.token ?? data.access_token ?? data.accessToken;
|
|
10724
|
+
if (!token) {
|
|
10725
|
+
throw new Error("Login succeeded but no token in response");
|
|
10726
|
+
}
|
|
10727
|
+
saveCredentials(apiUrl, token);
|
|
10728
|
+
const userName = data.name ?? data.user?.name ?? data.user?.email ?? email;
|
|
10729
|
+
console.log(`[mmrc] Logged in as ${userName}`);
|
|
10730
|
+
console.log(`[mmrc] Token saved to ${CREDENTIALS_PATH}`);
|
|
10731
|
+
return token;
|
|
10732
|
+
}
|
|
10733
|
+
function logout(apiUrl) {
|
|
10734
|
+
if (apiUrl) {
|
|
10735
|
+
removeCredentials(apiUrl);
|
|
10736
|
+
console.log(`[mmrc] Credentials removed for ${apiUrl}`);
|
|
10737
|
+
} else {
|
|
10738
|
+
removeCredentials();
|
|
10739
|
+
console.log("[mmrc] All saved credentials removed");
|
|
10848
10740
|
}
|
|
10849
|
-
|
|
10850
|
-
|
|
10741
|
+
}
|
|
10742
|
+
async function whoami(apiUrl) {
|
|
10743
|
+
const token = resolveToken(apiUrl);
|
|
10744
|
+
if (!token) {
|
|
10745
|
+
console.log("[mmrc] Not logged in. Run `mmrc login` to authenticate.");
|
|
10746
|
+
return;
|
|
10851
10747
|
}
|
|
10852
|
-
|
|
10853
|
-
|
|
10854
|
-
|
|
10855
|
-
|
|
10856
|
-
|
|
10857
|
-
|
|
10858
|
-
|
|
10859
|
-
|
|
10860
|
-
subProp.value.expression
|
|
10861
|
-
));
|
|
10862
|
-
}
|
|
10748
|
+
try {
|
|
10749
|
+
const res = await fetch(`${apiUrl}/auth/me`, {
|
|
10750
|
+
headers: { Authorization: `Bearer ${token}` }
|
|
10751
|
+
});
|
|
10752
|
+
if (!res.ok) {
|
|
10753
|
+
if (res.status === 401) {
|
|
10754
|
+
console.log("[mmrc] Token is expired or invalid. Run `mmrc login` to re-authenticate.");
|
|
10755
|
+
return;
|
|
10863
10756
|
}
|
|
10757
|
+
console.log(`[mmrc] Failed to fetch user info: ${res.status}`);
|
|
10758
|
+
return;
|
|
10864
10759
|
}
|
|
10760
|
+
const user = await res.json();
|
|
10761
|
+
console.log(`[mmrc] Logged in to ${apiUrl}`);
|
|
10762
|
+
console.log(` Name: ${user.name ?? "(unknown)"}`);
|
|
10763
|
+
console.log(` Email: ${user.email ?? "(unknown)"}`);
|
|
10764
|
+
if (user.id) console.log(` ID: ${user.id}`);
|
|
10765
|
+
if (user.role) console.log(` Role: ${user.role}`);
|
|
10766
|
+
} catch (error) {
|
|
10767
|
+
console.log(`[mmrc] Could not connect to ${apiUrl}: ${error.message}`);
|
|
10865
10768
|
}
|
|
10866
|
-
if (props.length === 0) return null;
|
|
10867
|
-
return t7.jsxAttribute(
|
|
10868
|
-
t7.jsxIdentifier("sx"),
|
|
10869
|
-
t7.jsxExpressionContainer(t7.objectExpression(props))
|
|
10870
|
-
);
|
|
10871
10769
|
}
|
|
10872
|
-
|
|
10873
|
-
|
|
10770
|
+
var import_fs4, import_path3, import_os, import_readline, MMRC_DIR, CREDENTIALS_PATH;
|
|
10771
|
+
var init_auth = __esm({
|
|
10772
|
+
"src/cli/auth.ts"() {
|
|
10773
|
+
"use strict";
|
|
10774
|
+
import_fs4 = require("fs");
|
|
10775
|
+
import_path3 = require("path");
|
|
10776
|
+
import_os = require("os");
|
|
10777
|
+
import_readline = require("readline");
|
|
10778
|
+
MMRC_DIR = (0, import_path3.join)((0, import_os.homedir)(), ".mmrc");
|
|
10779
|
+
CREDENTIALS_PATH = (0, import_path3.join)(MMRC_DIR, "credentials.json");
|
|
10780
|
+
}
|
|
10781
|
+
});
|
|
10782
|
+
|
|
10783
|
+
// src/cli/deploy.ts
|
|
10784
|
+
var deploy_exports = {};
|
|
10785
|
+
__export(deploy_exports, {
|
|
10786
|
+
deploy: () => deploy,
|
|
10787
|
+
syncServices: () => syncServices
|
|
10788
|
+
});
|
|
10789
|
+
async function deploy(options) {
|
|
10790
|
+
const dir = options.dir ?? "dist/workflows";
|
|
10791
|
+
const targetLabel = options.targetName ? ` (target: ${options.targetName})` : "";
|
|
10792
|
+
console.log(`[mindmatrix-react] Deploying workflows from ${dir} to ${options.apiUrl}${targetLabel}...`);
|
|
10793
|
+
const files = await (0, import_glob2.glob)(`${dir}/**/*.workflow.json`);
|
|
10794
|
+
if (files.length === 0) {
|
|
10795
|
+
console.log(`[mindmatrix-react] No workflow files found in ${dir}`);
|
|
10796
|
+
return { created: [], updated: [], versioned: [], skipped: [], failed: [] };
|
|
10797
|
+
}
|
|
10798
|
+
const result = {
|
|
10799
|
+
created: [],
|
|
10800
|
+
updated: [],
|
|
10801
|
+
versioned: [],
|
|
10802
|
+
skipped: [],
|
|
10803
|
+
failed: []
|
|
10804
|
+
};
|
|
10805
|
+
const deployedIRs = [];
|
|
10806
|
+
for (const file2 of files) {
|
|
10807
|
+
try {
|
|
10808
|
+
const ir = JSON.parse((0, import_fs5.readFileSync)(file2, "utf-8"));
|
|
10809
|
+
const slug = ir.slug;
|
|
10810
|
+
if (options.dryRun) {
|
|
10811
|
+
console.log(` [dry-run] Would deploy ${slug} (${(0, import_path4.basename)(file2)})`);
|
|
10812
|
+
continue;
|
|
10813
|
+
}
|
|
10814
|
+
const existing = await fetchExistingDefinition(options.apiUrl, options.token, slug);
|
|
10815
|
+
if (!existing) {
|
|
10816
|
+
await createDefinition(options.apiUrl, options.token, ir);
|
|
10817
|
+
console.log(` \u2713 ${slug} (created)`);
|
|
10818
|
+
result.created.push(slug);
|
|
10819
|
+
} else if (existing.instanceCount === 0 || options.force) {
|
|
10820
|
+
await updateDefinition(options.apiUrl, options.token, existing.id, ir);
|
|
10821
|
+
console.log(` \u2713 ${slug} (updated)`);
|
|
10822
|
+
result.updated.push(slug);
|
|
10823
|
+
} else {
|
|
10824
|
+
const newVersion = bumpVersion(existing.version);
|
|
10825
|
+
ir.version = newVersion;
|
|
10826
|
+
await createDefinition(options.apiUrl, options.token, ir);
|
|
10827
|
+
console.log(` \u2713 ${slug} v${newVersion} (new version, ${existing.instanceCount} instances on v${existing.version})`);
|
|
10828
|
+
result.versioned.push(slug);
|
|
10829
|
+
}
|
|
10830
|
+
deployedIRs.push(ir);
|
|
10831
|
+
} catch (error) {
|
|
10832
|
+
const slug = (0, import_path4.basename)(file2).replace(".workflow.json", "");
|
|
10833
|
+
const msg = error.message;
|
|
10834
|
+
console.error(` \u2717 ${slug}: ${msg}`);
|
|
10835
|
+
result.failed.push({ slug, error: msg });
|
|
10836
|
+
}
|
|
10837
|
+
}
|
|
10838
|
+
if (!options.dryRun) {
|
|
10839
|
+
for (const ir of deployedIRs) {
|
|
10840
|
+
const serviceResult = await syncServices(options.apiUrl, options.token, ir);
|
|
10841
|
+
if (serviceResult) {
|
|
10842
|
+
if (!result.services) {
|
|
10843
|
+
result.services = { registered: [], updated: [], failed: [] };
|
|
10844
|
+
}
|
|
10845
|
+
result.services.registered.push(...serviceResult.registered);
|
|
10846
|
+
result.services.updated.push(...serviceResult.updated);
|
|
10847
|
+
result.services.failed.push(...serviceResult.failed);
|
|
10848
|
+
}
|
|
10849
|
+
}
|
|
10850
|
+
}
|
|
10851
|
+
if (options.reportFile) {
|
|
10852
|
+
(0, import_fs5.writeFileSync)(options.reportFile, JSON.stringify(result, null, 2), "utf-8");
|
|
10853
|
+
console.log(`
|
|
10854
|
+
Report written to ${options.reportFile}`);
|
|
10855
|
+
}
|
|
10856
|
+
const total = result.created.length + result.updated.length + result.versioned.length;
|
|
10857
|
+
console.log(
|
|
10858
|
+
`
|
|
10859
|
+
[mindmatrix-react] Deployed ${total} workflows (${result.created.length} created, ${result.updated.length} updated, ${result.versioned.length} versioned, ${result.failed.length} failed)`
|
|
10860
|
+
);
|
|
10861
|
+
if (result.services) {
|
|
10862
|
+
const svcTotal = result.services.registered.length + result.services.updated.length;
|
|
10863
|
+
if (svcTotal > 0 || result.services.failed.length > 0) {
|
|
10864
|
+
console.log(
|
|
10865
|
+
`[mindmatrix-react] Synced ${svcTotal} services (${result.services.registered.length} registered, ${result.services.updated.length} updated, ${result.services.failed.length} failed)`
|
|
10866
|
+
);
|
|
10867
|
+
}
|
|
10868
|
+
}
|
|
10869
|
+
return result;
|
|
10870
|
+
}
|
|
10871
|
+
async function fetchExistingDefinition(apiUrl, token, slug) {
|
|
10872
|
+
try {
|
|
10873
|
+
const res = await fetch(`${apiUrl}/workflow/definitions?slug=${encodeURIComponent(slug)}`, {
|
|
10874
|
+
headers: { Authorization: `Bearer ${token}` }
|
|
10875
|
+
});
|
|
10876
|
+
if (!res.ok) return null;
|
|
10877
|
+
const data = await res.json();
|
|
10878
|
+
const definitions = Array.isArray(data) ? data : data.items ?? data.data;
|
|
10879
|
+
if (!definitions || definitions.length === 0) return null;
|
|
10880
|
+
const def = definitions[0];
|
|
10881
|
+
return {
|
|
10882
|
+
id: def.id,
|
|
10883
|
+
slug: def.slug,
|
|
10884
|
+
version: def.version || "0.1.0",
|
|
10885
|
+
instanceCount: def.instanceCount ?? def.instance_count ?? 0
|
|
10886
|
+
};
|
|
10887
|
+
} catch {
|
|
10888
|
+
return null;
|
|
10889
|
+
}
|
|
10890
|
+
}
|
|
10891
|
+
async function createDefinition(apiUrl, token, ir) {
|
|
10892
|
+
const res = await fetch(`${apiUrl}/workflow/definitions`, {
|
|
10893
|
+
method: "POST",
|
|
10894
|
+
headers: {
|
|
10895
|
+
"Content-Type": "application/json",
|
|
10896
|
+
Authorization: `Bearer ${token}`
|
|
10897
|
+
},
|
|
10898
|
+
body: JSON.stringify(ir)
|
|
10899
|
+
});
|
|
10900
|
+
if (!res.ok) {
|
|
10901
|
+
const errorText = await res.text();
|
|
10902
|
+
throw new Error(`Create failed: ${res.status} ${errorText}`);
|
|
10903
|
+
}
|
|
10904
|
+
}
|
|
10905
|
+
async function updateDefinition(apiUrl, token, id, ir) {
|
|
10906
|
+
const { slug: _slug, ...updatePayload } = ir;
|
|
10907
|
+
const res = await fetch(`${apiUrl}/workflow/definitions/${id}`, {
|
|
10908
|
+
method: "PATCH",
|
|
10909
|
+
headers: {
|
|
10910
|
+
"Content-Type": "application/json",
|
|
10911
|
+
Authorization: `Bearer ${token}`
|
|
10912
|
+
},
|
|
10913
|
+
body: JSON.stringify(updatePayload)
|
|
10914
|
+
});
|
|
10915
|
+
if (!res.ok) {
|
|
10916
|
+
const errorText = await res.text();
|
|
10917
|
+
throw new Error(`Update failed: ${res.status} ${errorText}`);
|
|
10918
|
+
}
|
|
10919
|
+
}
|
|
10920
|
+
function bumpVersion(version) {
|
|
10921
|
+
const parts = version.split(".");
|
|
10922
|
+
if (parts.length !== 3) return `${version}.1`;
|
|
10923
|
+
const patch = parseInt(parts[2], 10) || 0;
|
|
10924
|
+
return `${parts[0]}.${parts[1]}.${patch + 1}`;
|
|
10925
|
+
}
|
|
10926
|
+
async function syncServices(apiUrl, token, ir) {
|
|
10927
|
+
const metadata = ir.metadata;
|
|
10928
|
+
const orchestration = metadata?.orchestration;
|
|
10929
|
+
const services = orchestration?.services;
|
|
10930
|
+
if (!services || Object.keys(services).length === 0) return null;
|
|
10931
|
+
const result = { registered: [], updated: [], failed: [] };
|
|
10932
|
+
for (const [name, config] of Object.entries(services)) {
|
|
10933
|
+
try {
|
|
10934
|
+
const registration = {
|
|
10935
|
+
name,
|
|
10936
|
+
connection: {
|
|
10937
|
+
type: config.type || "webhook",
|
|
10938
|
+
url: config.url,
|
|
10939
|
+
queue: config.queue
|
|
10940
|
+
},
|
|
10941
|
+
actions: config.actions || [],
|
|
10942
|
+
labels: config.labels || {}
|
|
10943
|
+
};
|
|
10944
|
+
const existing = await fetchExistingService(apiUrl, token, name);
|
|
10945
|
+
if (existing) {
|
|
10946
|
+
await fetch(`${apiUrl}/services/${existing.id}`, {
|
|
10947
|
+
method: "PATCH",
|
|
10948
|
+
headers: {
|
|
10949
|
+
"Content-Type": "application/json",
|
|
10950
|
+
Authorization: `Bearer ${token}`
|
|
10951
|
+
},
|
|
10952
|
+
body: JSON.stringify(registration)
|
|
10953
|
+
});
|
|
10954
|
+
console.log(` \u2713 service: ${name} (updated)`);
|
|
10955
|
+
result.updated.push(name);
|
|
10956
|
+
} else {
|
|
10957
|
+
const res = await fetch(`${apiUrl}/services`, {
|
|
10958
|
+
method: "POST",
|
|
10959
|
+
headers: {
|
|
10960
|
+
"Content-Type": "application/json",
|
|
10961
|
+
Authorization: `Bearer ${token}`
|
|
10962
|
+
},
|
|
10963
|
+
body: JSON.stringify(registration)
|
|
10964
|
+
});
|
|
10965
|
+
if (!res.ok) {
|
|
10966
|
+
const errorText = await res.text();
|
|
10967
|
+
throw new Error(`Register failed: ${res.status} ${errorText}`);
|
|
10968
|
+
}
|
|
10969
|
+
console.log(` \u2713 service: ${name} (registered)`);
|
|
10970
|
+
result.registered.push(name);
|
|
10971
|
+
}
|
|
10972
|
+
} catch (error) {
|
|
10973
|
+
const msg = error.message;
|
|
10974
|
+
console.error(` \u2717 service: ${name}: ${msg}`);
|
|
10975
|
+
result.failed.push(name);
|
|
10976
|
+
}
|
|
10977
|
+
}
|
|
10978
|
+
return result;
|
|
10979
|
+
}
|
|
10980
|
+
async function fetchExistingService(apiUrl, token, name) {
|
|
10981
|
+
try {
|
|
10982
|
+
const res = await fetch(`${apiUrl}/services?name=${encodeURIComponent(name)}`, {
|
|
10983
|
+
headers: { Authorization: `Bearer ${token}` }
|
|
10984
|
+
});
|
|
10985
|
+
if (!res.ok) return null;
|
|
10986
|
+
const data = await res.json();
|
|
10987
|
+
const servicesList = Array.isArray(data) ? data : data.services ?? data.items ?? data.data;
|
|
10988
|
+
if (!servicesList || servicesList.length === 0) return null;
|
|
10989
|
+
const found = servicesList.find((s) => s.name === name);
|
|
10990
|
+
return found ? { id: found.id, name: found.name } : null;
|
|
10991
|
+
} catch {
|
|
10992
|
+
return null;
|
|
10993
|
+
}
|
|
10994
|
+
}
|
|
10995
|
+
var import_glob2, import_fs5, import_path4;
|
|
10996
|
+
var init_deploy = __esm({
|
|
10997
|
+
"src/cli/deploy.ts"() {
|
|
10998
|
+
"use strict";
|
|
10999
|
+
import_glob2 = require("glob");
|
|
11000
|
+
import_fs5 = require("fs");
|
|
11001
|
+
import_path4 = require("path");
|
|
11002
|
+
}
|
|
11003
|
+
});
|
|
11004
|
+
|
|
11005
|
+
// src/cli/seed.ts
|
|
11006
|
+
var seed_exports = {};
|
|
11007
|
+
__export(seed_exports, {
|
|
11008
|
+
generateFieldValue: () => generateFieldValue,
|
|
11009
|
+
generateInstanceData: () => generateInstanceData,
|
|
11010
|
+
seedInstances: () => seedInstances
|
|
11011
|
+
});
|
|
11012
|
+
function randomInt(min, max) {
|
|
11013
|
+
return Math.floor(Math.random() * (max - min + 1)) + min;
|
|
11014
|
+
}
|
|
11015
|
+
function randomPick(arr) {
|
|
11016
|
+
return arr[Math.floor(Math.random() * arr.length)];
|
|
11017
|
+
}
|
|
11018
|
+
function loremSentence(words = 5) {
|
|
11019
|
+
const result = [];
|
|
11020
|
+
for (let i = 0; i < words; i++) result.push(randomPick(LOREM_WORDS));
|
|
11021
|
+
const s = result.join(" ");
|
|
11022
|
+
return s.charAt(0).toUpperCase() + s.slice(1);
|
|
11023
|
+
}
|
|
11024
|
+
function generateFieldValue(field, index) {
|
|
11025
|
+
if (field.default_value !== void 0 && field.default_value !== null) {
|
|
11026
|
+
return field.default_value;
|
|
11027
|
+
}
|
|
11028
|
+
if (field.options && field.options.length > 0) {
|
|
11029
|
+
return field.options[index % field.options.length].value;
|
|
11030
|
+
}
|
|
11031
|
+
const ft = (field.field_type ?? field.type ?? "text").toLowerCase();
|
|
11032
|
+
switch (ft) {
|
|
11033
|
+
case "text":
|
|
11034
|
+
case "string":
|
|
11035
|
+
case "textarea":
|
|
11036
|
+
case "rich_text": {
|
|
11037
|
+
const name = field.name.toLowerCase();
|
|
11038
|
+
if (name.includes("email")) return `${randomPick(FIRST_NAMES).toLowerCase()}${++_counter}@${randomPick(DOMAINS)}`;
|
|
11039
|
+
if (name.includes("name") && name.includes("first")) return randomPick(FIRST_NAMES);
|
|
11040
|
+
if (name.includes("name") && name.includes("last")) return randomPick(LAST_NAMES);
|
|
11041
|
+
if (name.includes("name") || name === "title") return `${randomPick(FIRST_NAMES)} ${randomPick(LAST_NAMES)}`;
|
|
11042
|
+
if (name.includes("company") || name.includes("org")) return randomPick(COMPANIES);
|
|
11043
|
+
if (name.includes("phone")) return `+1-555-${randomInt(100, 999)}-${randomInt(1e3, 9999)}`;
|
|
11044
|
+
if (name.includes("url") || name.includes("website")) return `https://${randomPick(DOMAINS)}/${field.name}`;
|
|
11045
|
+
if (name.includes("description") || name.includes("note") || name.includes("comment")) return loremSentence(randomInt(8, 15));
|
|
11046
|
+
if (name.includes("address")) return `${randomInt(100, 9999)} ${loremSentence(2)} St`;
|
|
11047
|
+
return loremSentence(randomInt(2, 5));
|
|
11048
|
+
}
|
|
11049
|
+
case "number":
|
|
11050
|
+
case "numeric":
|
|
11051
|
+
case "integer":
|
|
11052
|
+
case "int": {
|
|
11053
|
+
const name = field.name.toLowerCase();
|
|
11054
|
+
if (name.includes("price") || name.includes("amount") || name.includes("cost") || name.includes("salary"))
|
|
11055
|
+
return randomInt(1e3, 99999) / 100;
|
|
11056
|
+
if (name.includes("age")) return randomInt(18, 65);
|
|
11057
|
+
if (name.includes("quantity") || name.includes("count") || name.includes("qty")) return randomInt(1, 100);
|
|
11058
|
+
if (name.includes("percent") || name.includes("rate")) return randomInt(1, 100);
|
|
11059
|
+
return randomInt(1, 1e3);
|
|
11060
|
+
}
|
|
11061
|
+
case "currency":
|
|
11062
|
+
case "decimal":
|
|
11063
|
+
return randomInt(100, 999999) / 100;
|
|
11064
|
+
case "boolean":
|
|
11065
|
+
case "bool":
|
|
11066
|
+
case "checkbox":
|
|
11067
|
+
case "toggle":
|
|
11068
|
+
return index % 2 === 0;
|
|
11069
|
+
case "date":
|
|
11070
|
+
case "datetime":
|
|
11071
|
+
case "timestamptz": {
|
|
11072
|
+
const d = /* @__PURE__ */ new Date();
|
|
11073
|
+
d.setDate(d.getDate() - randomInt(0, 365));
|
|
11074
|
+
return d.toISOString().split("T")[0];
|
|
11075
|
+
}
|
|
11076
|
+
case "select":
|
|
11077
|
+
case "enum":
|
|
11078
|
+
case "multi_select":
|
|
11079
|
+
return field.options?.[index % (field.options?.length || 1)]?.value ?? "option_1";
|
|
11080
|
+
case "email":
|
|
11081
|
+
return `${randomPick(FIRST_NAMES).toLowerCase()}${++_counter}@${randomPick(DOMAINS)}`;
|
|
11082
|
+
case "url":
|
|
11083
|
+
return `https://${randomPick(DOMAINS)}/${field.name}`;
|
|
11084
|
+
case "json":
|
|
11085
|
+
case "object":
|
|
11086
|
+
return {};
|
|
11087
|
+
case "array":
|
|
11088
|
+
return [];
|
|
11089
|
+
default:
|
|
11090
|
+
return loremSentence(3);
|
|
11091
|
+
}
|
|
11092
|
+
}
|
|
11093
|
+
function generateInstanceData(fields, index) {
|
|
11094
|
+
const data = {};
|
|
11095
|
+
for (const field of fields) {
|
|
11096
|
+
if (field.name === "id" || field.name === "created_at" || field.name === "updated_at") continue;
|
|
11097
|
+
data[field.name] = generateFieldValue(field, index);
|
|
11098
|
+
}
|
|
11099
|
+
return data;
|
|
11100
|
+
}
|
|
11101
|
+
async function seedInstances(options) {
|
|
11102
|
+
const dir = options.dir ?? "dist/workflows";
|
|
11103
|
+
const count = options.count ?? 7;
|
|
11104
|
+
const result = { created: 0, definitions: 0, errors: [] };
|
|
11105
|
+
const files = await (0, import_glob3.glob)(`${dir}/**/*.workflow.json`);
|
|
11106
|
+
if (files.length === 0) return result;
|
|
11107
|
+
for (const file2 of files) {
|
|
11108
|
+
let def;
|
|
11109
|
+
try {
|
|
11110
|
+
def = JSON.parse((0, import_fs6.readFileSync)(file2, "utf-8"));
|
|
11111
|
+
} catch {
|
|
11112
|
+
continue;
|
|
11113
|
+
}
|
|
11114
|
+
if (!def.slug || !def.fields || def.fields.length === 0) continue;
|
|
11115
|
+
const startState = def.states?.find((s) => s.state_type === "START")?.name ?? def.states?.[0]?.name ?? "initial";
|
|
11116
|
+
let defCreated = 0;
|
|
11117
|
+
for (let i = 0; i < count; i++) {
|
|
11118
|
+
const stateData = generateInstanceData(def.fields, i);
|
|
11119
|
+
try {
|
|
11120
|
+
const resp = await fetch(`${options.apiUrl}/workflow/instances`, {
|
|
11121
|
+
method: "POST",
|
|
11122
|
+
headers: {
|
|
11123
|
+
"Content-Type": "application/json",
|
|
11124
|
+
"Authorization": `Bearer ${options.token}`
|
|
11125
|
+
},
|
|
11126
|
+
body: JSON.stringify({
|
|
11127
|
+
definition_slug: def.slug,
|
|
11128
|
+
initial_state: startState,
|
|
11129
|
+
state_data: stateData
|
|
11130
|
+
})
|
|
11131
|
+
});
|
|
11132
|
+
if (resp.ok) {
|
|
11133
|
+
defCreated++;
|
|
11134
|
+
} else {
|
|
11135
|
+
const errText = await resp.text().catch(() => resp.statusText);
|
|
11136
|
+
result.errors.push(`${def.slug}[${i}]: ${resp.status} ${errText}`);
|
|
11137
|
+
}
|
|
11138
|
+
} catch (e) {
|
|
11139
|
+
result.errors.push(`${def.slug}[${i}]: ${e instanceof Error ? e.message : String(e)}`);
|
|
11140
|
+
}
|
|
11141
|
+
}
|
|
11142
|
+
if (defCreated > 0) {
|
|
11143
|
+
result.definitions++;
|
|
11144
|
+
result.created += defCreated;
|
|
11145
|
+
console.log(` [seed] ${def.slug}: ${defCreated} instances created`);
|
|
11146
|
+
}
|
|
11147
|
+
}
|
|
11148
|
+
return result;
|
|
11149
|
+
}
|
|
11150
|
+
var import_fs6, import_glob3, FIRST_NAMES, LAST_NAMES, COMPANIES, LOREM_WORDS, DOMAINS, _counter;
|
|
11151
|
+
var init_seed = __esm({
|
|
11152
|
+
"src/cli/seed.ts"() {
|
|
11153
|
+
"use strict";
|
|
11154
|
+
import_fs6 = require("fs");
|
|
11155
|
+
import_glob3 = require("glob");
|
|
11156
|
+
FIRST_NAMES = ["Alice", "Bob", "Charlie", "Diana", "Eve", "Frank", "Grace", "Henry"];
|
|
11157
|
+
LAST_NAMES = ["Smith", "Johnson", "Williams", "Brown", "Jones", "Garcia", "Miller", "Davis"];
|
|
11158
|
+
COMPANIES = ["Acme Corp", "TechStart Inc", "GlobalTrade Ltd", "DataFlow Systems", "CloudPeak"];
|
|
11159
|
+
LOREM_WORDS = ["lorem", "ipsum", "dolor", "sit", "amet", "consectetur", "adipiscing", "elit", "sed", "do", "eiusmod", "tempor"];
|
|
11160
|
+
DOMAINS = ["example.com", "test.org", "demo.io", "sample.net"];
|
|
11161
|
+
_counter = 0;
|
|
11162
|
+
}
|
|
11163
|
+
});
|
|
11164
|
+
|
|
11165
|
+
// src/index.ts
|
|
11166
|
+
var index_exports = {};
|
|
11167
|
+
__export(index_exports, {
|
|
11168
|
+
DIAGNOSTIC_CODES: () => DIAGNOSTIC_CODES,
|
|
11169
|
+
DiagnosticCollector: () => DiagnosticCollector,
|
|
11170
|
+
IncrementalCache: () => IncrementalCache,
|
|
11171
|
+
IncrementalProjectCompiler: () => IncrementalProjectCompiler,
|
|
11172
|
+
babelPlugin: () => babelPlugin,
|
|
11173
|
+
build: () => build,
|
|
11174
|
+
buildDependencyGraph: () => buildDependencyGraph,
|
|
11175
|
+
buildEnvelope: () => buildEnvelope,
|
|
11176
|
+
compileActions: () => compileActions,
|
|
11177
|
+
compileModel: () => compileModel,
|
|
11178
|
+
compileModels: () => compileModels,
|
|
11179
|
+
compileProject: () => compileProject,
|
|
11180
|
+
compileSource: () => compileSource,
|
|
11181
|
+
compilerStateToWorkflow: () => compilerStateToWorkflow,
|
|
11182
|
+
computeEnvelopeId: () => computeEnvelopeId,
|
|
11183
|
+
computeTransitiveDirtySet: () => computeTransitiveDirtySet,
|
|
11184
|
+
createDevServer: () => createDevServer,
|
|
11185
|
+
createDiagnosticCollector: () => createDiagnosticCollector,
|
|
11186
|
+
createSourceEnvelope: () => createSourceEnvelope,
|
|
11187
|
+
createVisitor: () => createVisitor,
|
|
11188
|
+
decompile: () => decompile,
|
|
11189
|
+
decompileProject: () => decompileProject,
|
|
11190
|
+
decompileToTSX: () => decompileToTSX,
|
|
11191
|
+
deploy: () => deploy,
|
|
11192
|
+
detectFileRole: () => detectFileRole,
|
|
11193
|
+
diffEnvelopes: () => diffEnvelopes,
|
|
11194
|
+
diffFsTrees: () => diffFsTrees,
|
|
11195
|
+
emitCanonical: () => emitCanonical,
|
|
11196
|
+
emitCompiledOutput: () => emitCompiledOutput,
|
|
11197
|
+
emitIR: () => emitIR,
|
|
11198
|
+
emitPureForm: () => emitPureForm,
|
|
11199
|
+
envelopesEqual: () => envelopesEqual,
|
|
11200
|
+
extractComponents: () => extractComponents,
|
|
11201
|
+
extractComputed: () => extractComputed,
|
|
11202
|
+
extractEffects: () => extractEffects,
|
|
11203
|
+
extractEvents: () => extractEvents,
|
|
11204
|
+
extractImports: () => extractImports,
|
|
11205
|
+
extractRoutes: () => extractRoutes,
|
|
11206
|
+
extractStates: () => extractStates,
|
|
11207
|
+
extractTransitions: () => extractTransitions,
|
|
11208
|
+
filterByRole: () => filterByRole,
|
|
11209
|
+
generateFsTree: () => generateFsTree,
|
|
11210
|
+
hashContent: () => hashContent,
|
|
11211
|
+
normalizeDecompilerInput: () => normalizeDecompilerInput,
|
|
11212
|
+
resolveActionReferences: () => resolveActionReferences,
|
|
11213
|
+
resolveImport: () => resolveImport,
|
|
11214
|
+
shouldDecompileAsProject: () => shouldDecompileAsProject,
|
|
11215
|
+
topologicalSort: () => topologicalSort,
|
|
11216
|
+
transformToFrontend: () => transformToFrontend,
|
|
11217
|
+
validateRoundTrip: () => validateRoundTrip,
|
|
11218
|
+
validateSourceRoundTrip: () => validateSourceRoundTrip
|
|
11219
|
+
});
|
|
11220
|
+
module.exports = __toCommonJS(index_exports);
|
|
11221
|
+
init_state_extractor();
|
|
11222
|
+
init_effect_extractor();
|
|
11223
|
+
init_transition_extractor();
|
|
11224
|
+
init_event_extractor();
|
|
11225
|
+
init_component_extractor();
|
|
11226
|
+
init_pure_form_emitter();
|
|
11227
|
+
init_experience_transform();
|
|
11228
|
+
|
|
11229
|
+
// src/decompiler/index.ts
|
|
11230
|
+
var t10 = __toESM(require("@babel/types"));
|
|
11231
|
+
var import_generator = __toESM(require("@babel/generator"));
|
|
11232
|
+
|
|
11233
|
+
// src/decompiler/ast-builder.ts
|
|
11234
|
+
var t8 = __toESM(require("@babel/types"));
|
|
11235
|
+
var import_parser = require("@babel/parser");
|
|
11236
|
+
|
|
11237
|
+
// src/decompiler/sx-emitter.ts
|
|
11238
|
+
var t7 = __toESM(require("@babel/types"));
|
|
11239
|
+
function isTRBL(v) {
|
|
11240
|
+
if (typeof v !== "object" || v === null) return false;
|
|
11241
|
+
const obj = v;
|
|
11242
|
+
return typeof obj.top === "number" && typeof obj.right === "number" && typeof obj.bottom === "number" && typeof obj.left === "number";
|
|
11243
|
+
}
|
|
11244
|
+
function isFourCorners(v) {
|
|
11245
|
+
if (typeof v !== "object" || v === null) return false;
|
|
11246
|
+
const obj = v;
|
|
11247
|
+
return typeof obj.topLeft === "number" && typeof obj.topRight === "number" && typeof obj.bottomRight === "number" && typeof obj.bottomLeft === "number";
|
|
11248
|
+
}
|
|
11249
|
+
function isTokenRef(v) {
|
|
11250
|
+
if (typeof v !== "object" || v === null) return false;
|
|
11251
|
+
return v.kind === "token-ref";
|
|
11252
|
+
}
|
|
11253
|
+
function emitSpacingShorthand(prefix, trbl) {
|
|
11254
|
+
const { top, right, bottom, left } = trbl;
|
|
11255
|
+
if (top === right && right === bottom && bottom === left) {
|
|
11256
|
+
return [prop(prefix, top)];
|
|
11257
|
+
}
|
|
11258
|
+
if (top === bottom && left === right) {
|
|
11259
|
+
return [
|
|
11260
|
+
prop(`${prefix}y`, top),
|
|
11261
|
+
prop(`${prefix}x`, left)
|
|
11262
|
+
];
|
|
11263
|
+
}
|
|
11264
|
+
return [
|
|
11265
|
+
prop(`${prefix}t`, top),
|
|
11266
|
+
prop(`${prefix}r`, right),
|
|
11267
|
+
prop(`${prefix}b`, bottom),
|
|
11268
|
+
prop(`${prefix}l`, left)
|
|
11269
|
+
];
|
|
11270
|
+
}
|
|
11271
|
+
function emitRadiusShorthand(corners) {
|
|
11272
|
+
const { topLeft, topRight, bottomRight, bottomLeft } = corners;
|
|
11273
|
+
if (topLeft === topRight && topRight === bottomRight && bottomRight === bottomLeft) {
|
|
11274
|
+
return [prop("rounded", topLeft)];
|
|
11275
|
+
}
|
|
11276
|
+
return [
|
|
11277
|
+
prop("roundedTL", topLeft),
|
|
11278
|
+
prop("roundedTR", topRight),
|
|
11279
|
+
prop("roundedBR", bottomRight),
|
|
11280
|
+
prop("roundedBL", bottomLeft)
|
|
11281
|
+
];
|
|
11282
|
+
}
|
|
11283
|
+
function emitColorValue(color) {
|
|
11284
|
+
if (isTokenRef(color)) {
|
|
11285
|
+
return t7.stringLiteral(`token:${color.name}`);
|
|
11286
|
+
}
|
|
11287
|
+
if (typeof color === "string") {
|
|
11288
|
+
return t7.stringLiteral(color);
|
|
11289
|
+
}
|
|
11290
|
+
if (typeof color === "object" && color !== null) {
|
|
11291
|
+
const c = color;
|
|
11292
|
+
if (typeof c.r === "number" && typeof c.g === "number" && typeof c.b === "number") {
|
|
11293
|
+
const a = typeof c.a === "number" ? c.a : 1;
|
|
11294
|
+
if (a === 1) {
|
|
11295
|
+
const hex = `#${hexByte(c.r)}${hexByte(c.g)}${hexByte(c.b)}`;
|
|
11296
|
+
return t7.stringLiteral(hex);
|
|
11297
|
+
}
|
|
11298
|
+
return t7.stringLiteral(`rgba(${c.r}, ${c.g}, ${c.b}, ${a})`);
|
|
11299
|
+
}
|
|
11300
|
+
}
|
|
11301
|
+
return t7.stringLiteral("inherit");
|
|
11302
|
+
}
|
|
11303
|
+
function hexByte(n) {
|
|
11304
|
+
return Math.round(n).toString(16).padStart(2, "0");
|
|
11305
|
+
}
|
|
11306
|
+
function prop(key, value) {
|
|
11307
|
+
return t7.objectProperty(t7.identifier(key), valueToExpression(value));
|
|
11308
|
+
}
|
|
11309
|
+
function valueToExpression(value) {
|
|
11310
|
+
if (typeof value === "string") return t7.stringLiteral(value);
|
|
11311
|
+
if (typeof value === "number") return t7.numericLiteral(value);
|
|
11312
|
+
if (typeof value === "boolean") return t7.booleanLiteral(value);
|
|
11313
|
+
if (value === null) return t7.nullLiteral();
|
|
11314
|
+
if (value === void 0) return t7.identifier("undefined");
|
|
11315
|
+
if (Array.isArray(value)) {
|
|
11316
|
+
return t7.arrayExpression(value.map((v) => valueToExpression(v)));
|
|
11317
|
+
}
|
|
11318
|
+
if (typeof value === "object") {
|
|
11319
|
+
const entries = Object.entries(value);
|
|
11320
|
+
return t7.objectExpression(
|
|
11321
|
+
entries.map(
|
|
11322
|
+
([k, v]) => t7.objectProperty(t7.identifier(k), valueToExpression(v))
|
|
11323
|
+
)
|
|
11324
|
+
);
|
|
11325
|
+
}
|
|
11326
|
+
return t7.identifier("undefined");
|
|
11327
|
+
}
|
|
11328
|
+
var STATE_TO_SX_KEY = {
|
|
11329
|
+
hovered: "hover",
|
|
11330
|
+
pressed: "pressed",
|
|
11331
|
+
focused: "focus",
|
|
11332
|
+
selected: "selected",
|
|
11333
|
+
disabled: "disabled"
|
|
11334
|
+
};
|
|
11335
|
+
function emitSxProp(style) {
|
|
11336
|
+
if (!style || typeof style !== "object") return null;
|
|
11337
|
+
const props = [];
|
|
11338
|
+
if (style.padding && isTRBL(style.padding)) {
|
|
11339
|
+
props.push(...emitSpacingShorthand("p", style.padding));
|
|
11340
|
+
}
|
|
11341
|
+
if (style.margin && isTRBL(style.margin)) {
|
|
11342
|
+
props.push(...emitSpacingShorthand("m", style.margin));
|
|
11343
|
+
}
|
|
11344
|
+
if (style.backgroundColor) {
|
|
11345
|
+
props.push(t7.objectProperty(
|
|
11346
|
+
t7.identifier("bg"),
|
|
11347
|
+
emitColorValue(style.backgroundColor)
|
|
11348
|
+
));
|
|
11349
|
+
}
|
|
11350
|
+
if (style.borderRadius && isFourCorners(style.borderRadius)) {
|
|
11351
|
+
props.push(...emitRadiusShorthand(style.borderRadius));
|
|
11352
|
+
}
|
|
11353
|
+
if (typeof style.gap === "number") {
|
|
11354
|
+
props.push(prop("gap", style.gap));
|
|
11355
|
+
}
|
|
11356
|
+
if (typeof style.flexDirection === "string") {
|
|
11357
|
+
props.push(prop("direction", style.flexDirection));
|
|
11358
|
+
}
|
|
11359
|
+
if (typeof style.justifyContent === "string") {
|
|
11360
|
+
props.push(prop("justify", style.justifyContent));
|
|
11361
|
+
}
|
|
11362
|
+
if (typeof style.alignItems === "string") {
|
|
11363
|
+
props.push(prop("align", style.alignItems));
|
|
11364
|
+
}
|
|
11365
|
+
if (style.width !== void 0) props.push(prop("w", style.width));
|
|
11366
|
+
if (style.height !== void 0) props.push(prop("h", style.height));
|
|
11367
|
+
if (style.minWidth !== void 0) props.push(prop("minW", style.minWidth));
|
|
11368
|
+
if (style.minHeight !== void 0) props.push(prop("minH", style.minHeight));
|
|
11369
|
+
if (style.maxWidth !== void 0) props.push(prop("maxW", style.maxWidth));
|
|
11370
|
+
if (style.maxHeight !== void 0) props.push(prop("maxH", style.maxHeight));
|
|
11371
|
+
if (typeof style.opacity === "number") {
|
|
11372
|
+
props.push(prop("opacity", style.opacity));
|
|
11373
|
+
}
|
|
11374
|
+
if (style.color) {
|
|
11375
|
+
props.push(t7.objectProperty(
|
|
11376
|
+
t7.identifier("color"),
|
|
11377
|
+
emitColorValue(style.color)
|
|
11378
|
+
));
|
|
11379
|
+
}
|
|
11380
|
+
if (typeof style.overflow === "string") {
|
|
11381
|
+
props.push(prop("overflow", style.overflow));
|
|
11382
|
+
}
|
|
11383
|
+
if (typeof style.position === "string") {
|
|
11384
|
+
props.push(prop("position", style.position));
|
|
11385
|
+
}
|
|
11386
|
+
if (typeof style.states === "object" && style.states !== null) {
|
|
11387
|
+
for (const [state, override] of Object.entries(style.states)) {
|
|
11388
|
+
const sxKey = STATE_TO_SX_KEY[state] || state;
|
|
11389
|
+
if (typeof override === "object" && override !== null) {
|
|
11390
|
+
const subProp = emitSxProp(override);
|
|
11391
|
+
if (subProp && t7.isJSXExpressionContainer(subProp.value) && t7.isObjectExpression(subProp.value.expression)) {
|
|
11392
|
+
props.push(t7.objectProperty(
|
|
11393
|
+
t7.identifier(sxKey),
|
|
11394
|
+
subProp.value.expression
|
|
11395
|
+
));
|
|
11396
|
+
}
|
|
11397
|
+
}
|
|
11398
|
+
}
|
|
11399
|
+
}
|
|
11400
|
+
if (props.length === 0) return null;
|
|
11401
|
+
return t7.jsxAttribute(
|
|
11402
|
+
t7.jsxIdentifier("sx"),
|
|
11403
|
+
t7.jsxExpressionContainer(t7.objectExpression(props))
|
|
11404
|
+
);
|
|
11405
|
+
}
|
|
11406
|
+
|
|
11407
|
+
// src/decompiler/ast-builder.ts
|
|
10874
11408
|
function buildSymbolTable(fields, metadata, transitions, experience) {
|
|
10875
11409
|
const locals = /* @__PURE__ */ new Map();
|
|
10876
11410
|
const setters = /* @__PURE__ */ new Map();
|
|
@@ -11128,7 +11662,7 @@ function buildJSXTree(node, imports, symbols) {
|
|
|
11128
11662
|
}
|
|
11129
11663
|
const componentName = node.component;
|
|
11130
11664
|
if (REACT_ATOMS.has(componentName)) {
|
|
11131
|
-
addImport(imports, "@
|
|
11665
|
+
addImport(imports, "@mmapp/react", componentName);
|
|
11132
11666
|
}
|
|
11133
11667
|
const attributes = [];
|
|
11134
11668
|
if (node.config) {
|
|
@@ -11173,7 +11707,7 @@ function buildJSXTree(node, imports, symbols) {
|
|
|
11173
11707
|
isSelfClosing
|
|
11174
11708
|
);
|
|
11175
11709
|
if (node.visible_when) {
|
|
11176
|
-
addImport(imports, "@
|
|
11710
|
+
addImport(imports, "@mmapp/react", "Show");
|
|
11177
11711
|
return t8.jsxElement(
|
|
11178
11712
|
t8.jsxOpeningElement(
|
|
11179
11713
|
t8.jsxIdentifier("Show"),
|
|
@@ -11254,7 +11788,7 @@ function fieldTypeAnnotation(field) {
|
|
|
11254
11788
|
}
|
|
11255
11789
|
function emitFieldDeclarations(fields, imports) {
|
|
11256
11790
|
if (fields.length === 0) return [];
|
|
11257
|
-
addImport2(imports, "@
|
|
11791
|
+
addImport2(imports, "@mmapp/react", "useState");
|
|
11258
11792
|
const statements = [];
|
|
11259
11793
|
for (const field of fields) {
|
|
11260
11794
|
if (field.computed) continue;
|
|
@@ -11318,7 +11852,7 @@ function emitStateEffects(states, imports) {
|
|
|
11318
11852
|
const statements = [];
|
|
11319
11853
|
for (const state of states) {
|
|
11320
11854
|
if (state.on_enter.length > 0) {
|
|
11321
|
-
addImport2(imports, "@
|
|
11855
|
+
addImport2(imports, "@mmapp/react", "useOnEnter");
|
|
11322
11856
|
statements.push(
|
|
11323
11857
|
t9.expressionStatement(
|
|
11324
11858
|
t9.callExpression(t9.identifier("useOnEnter"), [
|
|
@@ -11329,7 +11863,7 @@ function emitStateEffects(states, imports) {
|
|
|
11329
11863
|
);
|
|
11330
11864
|
}
|
|
11331
11865
|
if (state.on_exit.length > 0) {
|
|
11332
|
-
addImport2(imports, "@
|
|
11866
|
+
addImport2(imports, "@mmapp/react", "useOnExit");
|
|
11333
11867
|
statements.push(
|
|
11334
11868
|
t9.expressionStatement(
|
|
11335
11869
|
t9.callExpression(t9.identifier("useOnExit"), [
|
|
@@ -11340,7 +11874,7 @@ function emitStateEffects(states, imports) {
|
|
|
11340
11874
|
);
|
|
11341
11875
|
}
|
|
11342
11876
|
if (state.during.length > 0) {
|
|
11343
|
-
addImport2(imports, "@
|
|
11877
|
+
addImport2(imports, "@mmapp/react", "useWhileIn");
|
|
11344
11878
|
for (const during of state.during) {
|
|
11345
11879
|
const args = [
|
|
11346
11880
|
t9.stringLiteral(state.name)
|
|
@@ -11361,7 +11895,7 @@ function emitStateEffects(states, imports) {
|
|
|
11361
11895
|
}
|
|
11362
11896
|
function emitTransitionDeclarations(transitions, imports) {
|
|
11363
11897
|
if (transitions.length === 0) return [];
|
|
11364
|
-
addImport2(imports, "@
|
|
11898
|
+
addImport2(imports, "@mmapp/react", "useTransition");
|
|
11365
11899
|
const correctedTransitions = correctFromFields(transitions);
|
|
11366
11900
|
const statements = [];
|
|
11367
11901
|
for (const transition of correctedTransitions) {
|
|
@@ -11596,7 +12130,7 @@ function emitSingleCondition(cond) {
|
|
|
11596
12130
|
function emitRoleDeclarations(metadata, imports) {
|
|
11597
12131
|
const roleDeps = metadata?.roleDependencies;
|
|
11598
12132
|
if (!roleDeps || roleDeps.length === 0) return [];
|
|
11599
|
-
addImport2(imports, "@
|
|
12133
|
+
addImport2(imports, "@mmapp/react", "useRole");
|
|
11600
12134
|
const statements = [];
|
|
11601
12135
|
for (const role of roleDeps) {
|
|
11602
12136
|
const varName = `is${toPascalCase(role)}`;
|
|
@@ -11617,7 +12151,7 @@ function emitQueryDeclarations(metadata, imports) {
|
|
|
11617
12151
|
const modelImports = metadata?.modelImports;
|
|
11618
12152
|
const addedModelImports = /* @__PURE__ */ new Set();
|
|
11619
12153
|
if (dataSources && dataSources.length > 0) {
|
|
11620
|
-
addImport2(imports, "@
|
|
12154
|
+
addImport2(imports, "@mmapp/react", "useQuery");
|
|
11621
12155
|
const usedVarNames = /* @__PURE__ */ new Set();
|
|
11622
12156
|
for (const ds of dataSources) {
|
|
11623
12157
|
if (ds.type !== "workflow") continue;
|
|
@@ -11684,7 +12218,7 @@ function emitQueryDeclarations(metadata, imports) {
|
|
|
11684
12218
|
}
|
|
11685
12219
|
const mutationTargets = metadata?.mutationTargets;
|
|
11686
12220
|
if (mutationTargets && mutationTargets.length > 0) {
|
|
11687
|
-
addImport2(imports, "@
|
|
12221
|
+
addImport2(imports, "@mmapp/react", "useMutation");
|
|
11688
12222
|
for (const slug of mutationTargets) {
|
|
11689
12223
|
const modelPath = modelImports?.[slug];
|
|
11690
12224
|
const modelVarName2 = modelPath ? `${toCamelCase2(slug.replace(/-/g, "_"))}Model` : void 0;
|
|
@@ -11709,7 +12243,7 @@ function emitQueryDeclarations(metadata, imports) {
|
|
|
11709
12243
|
function emitChangeWatchers(metadata, imports) {
|
|
11710
12244
|
const watchers = metadata?.fieldWatchers;
|
|
11711
12245
|
if (!watchers || watchers.length === 0) return [];
|
|
11712
|
-
addImport2(imports, "@
|
|
12246
|
+
addImport2(imports, "@mmapp/react", "useOnChange");
|
|
11713
12247
|
const statements = [];
|
|
11714
12248
|
for (const watcher of watchers) {
|
|
11715
12249
|
statements.push(
|
|
@@ -11725,7 +12259,7 @@ function emitChangeWatchers(metadata, imports) {
|
|
|
11725
12259
|
}
|
|
11726
12260
|
function emitEventSubscriptions(onEvent, imports) {
|
|
11727
12261
|
if (!onEvent || onEvent.length === 0) return [];
|
|
11728
|
-
addImport2(imports, "@
|
|
12262
|
+
addImport2(imports, "@mmapp/react", "useOnEvent");
|
|
11729
12263
|
const statements = [];
|
|
11730
12264
|
for (const sub of onEvent) {
|
|
11731
12265
|
const actions = sub.actions.map((a, i) => ({
|
|
@@ -11752,7 +12286,7 @@ function emitEventSubscriptions(onEvent, imports) {
|
|
|
11752
12286
|
function emitTransitionEffects(metadata, imports) {
|
|
11753
12287
|
const effects = metadata?.transitionEffects;
|
|
11754
12288
|
if (!effects || effects.length === 0) return [];
|
|
11755
|
-
addImport2(imports, "@
|
|
12289
|
+
addImport2(imports, "@mmapp/react", "useOnTransition");
|
|
11756
12290
|
const statements = [];
|
|
11757
12291
|
for (const effect of effects) {
|
|
11758
12292
|
statements.push(
|
|
@@ -11783,7 +12317,7 @@ function emitLocalDefaultDeclarations(experience, existingFields, imports) {
|
|
|
11783
12317
|
const camelName = toCamelCase2(key);
|
|
11784
12318
|
if (emittedCamelNames.has(camelName)) continue;
|
|
11785
12319
|
emittedCamelNames.add(camelName);
|
|
11786
|
-
addImport2(imports, "@
|
|
12320
|
+
addImport2(imports, "@mmapp/react", "useState");
|
|
11787
12321
|
const setter = `set${toPascalCase(key)}`;
|
|
11788
12322
|
let defaultExpr;
|
|
11789
12323
|
if (value === void 0 || value === null) {
|
|
@@ -11996,7 +12530,7 @@ function generateServerActionFile(actions) {
|
|
|
11996
12530
|
` * Each receives a TransitionContext with instance data and utilities.`,
|
|
11997
12531
|
` */`,
|
|
11998
12532
|
``,
|
|
11999
|
-
`import type { TransitionContext } from '@
|
|
12533
|
+
`import type { TransitionContext } from '@mmapp/react';`,
|
|
12000
12534
|
``
|
|
12001
12535
|
];
|
|
12002
12536
|
for (const action of actions) {
|
|
@@ -12069,7 +12603,7 @@ function generateConfigFile(def) {
|
|
|
12069
12603
|
` * Blueprint configuration for "${def.name || pascalCase(def.slug)}".`,
|
|
12070
12604
|
` */`,
|
|
12071
12605
|
``,
|
|
12072
|
-
`import { defineBlueprint } from '@
|
|
12606
|
+
`import { defineBlueprint } from '@mmapp/react';`,
|
|
12073
12607
|
``,
|
|
12074
12608
|
`export default defineBlueprint({`,
|
|
12075
12609
|
` slug: '${def.slug}',`,
|
|
@@ -12164,7 +12698,7 @@ function generateMainFile(def, pages, hasModel, serverActionNames, options) {
|
|
|
12164
12698
|
reactImports.add("Stack");
|
|
12165
12699
|
if (reactImports.size > 0) {
|
|
12166
12700
|
const sorted = [...reactImports].sort();
|
|
12167
|
-
importLines.push(`import { ${sorted.join(", ")} } from '@
|
|
12701
|
+
importLines.push(`import { ${sorted.join(", ")} } from '@mmapp/react';`);
|
|
12168
12702
|
}
|
|
12169
12703
|
if (hasModel) {
|
|
12170
12704
|
const typeName = pascalCase(slug);
|
|
@@ -13361,27 +13895,580 @@ async function startWatchMode(options) {
|
|
|
13361
13895
|
console.log(`
|
|
13362
13896
|
[mindmatrix-react] Watching ${srcDir} for changes... (Ctrl+C to stop)
|
|
13363
13897
|
`);
|
|
13364
|
-
fsWatch(srcDir, { recursive: true }, (_event, filename) => {
|
|
13365
|
-
if (!filename) return;
|
|
13366
|
-
if (!filename.match(/\.(tsx?|jsx?)$/)) return;
|
|
13367
|
-
if (filename.includes("node_modules") || filename.includes("dist")) return;
|
|
13368
|
-
if (debounce) clearTimeout(debounce);
|
|
13369
|
-
debounce = setTimeout(async () => {
|
|
13370
|
-
const ts = (/* @__PURE__ */ new Date()).toLocaleTimeString();
|
|
13371
|
-
console.log(`
|
|
13372
|
-
[${ts}] Change detected: ${filename} \u2014 recompiling...`);
|
|
13373
|
-
try {
|
|
13374
|
-
await build({ ...options, watch: false, skipTypeCheck: true });
|
|
13375
|
-
} catch (e) {
|
|
13376
|
-
console.error(`[mindmatrix-react] Rebuild failed:`, e.message);
|
|
13377
|
-
}
|
|
13378
|
-
}, 300);
|
|
13379
|
-
});
|
|
13380
|
-
return new Promise(() => {
|
|
13381
|
-
});
|
|
13898
|
+
fsWatch(srcDir, { recursive: true }, (_event, filename) => {
|
|
13899
|
+
if (!filename) return;
|
|
13900
|
+
if (!filename.match(/\.(tsx?|jsx?)$/)) return;
|
|
13901
|
+
if (filename.includes("node_modules") || filename.includes("dist")) return;
|
|
13902
|
+
if (debounce) clearTimeout(debounce);
|
|
13903
|
+
debounce = setTimeout(async () => {
|
|
13904
|
+
const ts = (/* @__PURE__ */ new Date()).toLocaleTimeString();
|
|
13905
|
+
console.log(`
|
|
13906
|
+
[${ts}] Change detected: ${filename} \u2014 recompiling...`);
|
|
13907
|
+
try {
|
|
13908
|
+
await build({ ...options, watch: false, skipTypeCheck: true });
|
|
13909
|
+
} catch (e) {
|
|
13910
|
+
console.error(`[mindmatrix-react] Rebuild failed:`, e.message);
|
|
13911
|
+
}
|
|
13912
|
+
}, 300);
|
|
13913
|
+
});
|
|
13914
|
+
return new Promise(() => {
|
|
13915
|
+
});
|
|
13916
|
+
}
|
|
13917
|
+
|
|
13918
|
+
// src/cli/local-server.ts
|
|
13919
|
+
var http = __toESM(require("http"));
|
|
13920
|
+
var import_node_crypto = require("crypto");
|
|
13921
|
+
var MemoryStore = class {
|
|
13922
|
+
constructor() {
|
|
13923
|
+
this.definitions = /* @__PURE__ */ new Map();
|
|
13924
|
+
this.instances = /* @__PURE__ */ new Map();
|
|
13925
|
+
this.slugIndex = /* @__PURE__ */ new Map();
|
|
13926
|
+
}
|
|
13927
|
+
// slug → id
|
|
13928
|
+
// ── Definitions ──────────────────────────────────────────────────────
|
|
13929
|
+
createDefinition(input) {
|
|
13930
|
+
if (this.slugIndex.has(input.slug)) {
|
|
13931
|
+
const existing = this.definitions.get(this.slugIndex.get(input.slug));
|
|
13932
|
+
if (existing) return existing;
|
|
13933
|
+
}
|
|
13934
|
+
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
13935
|
+
const def = {
|
|
13936
|
+
id: input.id ?? (0, import_node_crypto.randomUUID)(),
|
|
13937
|
+
slug: input.slug,
|
|
13938
|
+
name: input.name,
|
|
13939
|
+
version: input.version ?? "1.0.0",
|
|
13940
|
+
description: input.description ?? null,
|
|
13941
|
+
category: input.category ?? "workflow",
|
|
13942
|
+
fields: input.fields ?? [],
|
|
13943
|
+
states: input.states ?? [],
|
|
13944
|
+
transitions: input.transitions ?? [],
|
|
13945
|
+
roles: input.roles ?? [],
|
|
13946
|
+
experience: input.experience ?? null,
|
|
13947
|
+
metadata: input.metadata ?? {},
|
|
13948
|
+
child_definitions: input.child_definitions ?? [],
|
|
13949
|
+
is_immutable: input.is_immutable ?? false,
|
|
13950
|
+
tags: input.tags ?? [],
|
|
13951
|
+
inline_tags: input.inline_tags ?? [],
|
|
13952
|
+
created_at: now,
|
|
13953
|
+
updated_at: now
|
|
13954
|
+
};
|
|
13955
|
+
this.definitions.set(def.id, def);
|
|
13956
|
+
this.slugIndex.set(def.slug, def.id);
|
|
13957
|
+
return def;
|
|
13958
|
+
}
|
|
13959
|
+
getDefinition(idOrSlug) {
|
|
13960
|
+
const byId = this.definitions.get(idOrSlug);
|
|
13961
|
+
if (byId) return byId;
|
|
13962
|
+
const id = this.slugIndex.get(idOrSlug);
|
|
13963
|
+
if (id) return this.definitions.get(id);
|
|
13964
|
+
return void 0;
|
|
13965
|
+
}
|
|
13966
|
+
listDefinitions(opts) {
|
|
13967
|
+
let items = Array.from(this.definitions.values());
|
|
13968
|
+
if (opts?.category) {
|
|
13969
|
+
items = items.filter((d) => d.category === opts.category);
|
|
13970
|
+
}
|
|
13971
|
+
const total = items.length;
|
|
13972
|
+
const offset = opts?.offset ?? 0;
|
|
13973
|
+
const limit = opts?.limit ?? 50;
|
|
13974
|
+
items = items.slice(offset, offset + limit);
|
|
13975
|
+
return { items, total };
|
|
13976
|
+
}
|
|
13977
|
+
patchDefinition(id, patch) {
|
|
13978
|
+
const def = this.definitions.get(id);
|
|
13979
|
+
if (!def) return void 0;
|
|
13980
|
+
Object.assign(def, patch, { updated_at: (/* @__PURE__ */ new Date()).toISOString() });
|
|
13981
|
+
return def;
|
|
13982
|
+
}
|
|
13983
|
+
deleteDefinition(id) {
|
|
13984
|
+
const def = this.definitions.get(id);
|
|
13985
|
+
if (!def) return false;
|
|
13986
|
+
this.slugIndex.delete(def.slug);
|
|
13987
|
+
this.definitions.delete(id);
|
|
13988
|
+
return true;
|
|
13989
|
+
}
|
|
13990
|
+
// ── Instances ────────────────────────────────────────────────────────
|
|
13991
|
+
createInstance(input) {
|
|
13992
|
+
const def = this.getDefinition(input.definition_id) ?? this.getDefinition(input.definition_slug);
|
|
13993
|
+
if (!def) return null;
|
|
13994
|
+
const initialState = def.states.find((s) => s.type === "START" || s.type === "initial");
|
|
13995
|
+
const stateName = initialState?.name ?? "initial";
|
|
13996
|
+
const stateData = {};
|
|
13997
|
+
for (const field of def.fields) {
|
|
13998
|
+
if (field.default_value !== void 0) {
|
|
13999
|
+
stateData[field.name] = field.default_value;
|
|
14000
|
+
}
|
|
14001
|
+
}
|
|
14002
|
+
Object.assign(stateData, input.state_data ?? {});
|
|
14003
|
+
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
14004
|
+
const inst = {
|
|
14005
|
+
id: (0, import_node_crypto.randomUUID)(),
|
|
14006
|
+
definition_id: def.id,
|
|
14007
|
+
definition_slug: def.slug,
|
|
14008
|
+
current_state: stateName,
|
|
14009
|
+
state_data: stateData,
|
|
14010
|
+
execution_lock_version: 0,
|
|
14011
|
+
event_log: [{
|
|
14012
|
+
event_type: "transition",
|
|
14013
|
+
message: `Instance created in state '${stateName}'`,
|
|
14014
|
+
timestamp: now
|
|
14015
|
+
}],
|
|
14016
|
+
created_at: now,
|
|
14017
|
+
updated_at: now
|
|
14018
|
+
};
|
|
14019
|
+
this.instances.set(inst.id, inst);
|
|
14020
|
+
return inst;
|
|
14021
|
+
}
|
|
14022
|
+
getInstance(id) {
|
|
14023
|
+
return this.instances.get(id);
|
|
14024
|
+
}
|
|
14025
|
+
listInstances(opts) {
|
|
14026
|
+
let items = Array.from(this.instances.values());
|
|
14027
|
+
if (opts?.definition_id) {
|
|
14028
|
+
items = items.filter((i) => i.definition_id === opts.definition_id);
|
|
14029
|
+
}
|
|
14030
|
+
const total = items.length;
|
|
14031
|
+
const offset = opts?.offset ?? 0;
|
|
14032
|
+
const limit = opts?.limit ?? 50;
|
|
14033
|
+
items = items.slice(offset, offset + limit);
|
|
14034
|
+
return { items, total };
|
|
14035
|
+
}
|
|
14036
|
+
// ── Execute Action (Transition) ──────────────────────────────────────
|
|
14037
|
+
executeAction(input) {
|
|
14038
|
+
const def = this.getDefinition(input.definition_id);
|
|
14039
|
+
if (!def) return { success: false, error: "Definition not found" };
|
|
14040
|
+
let inst;
|
|
14041
|
+
if (input.instance_id) {
|
|
14042
|
+
const existing = this.instances.get(input.instance_id);
|
|
14043
|
+
if (!existing) return { success: false, error: "Instance not found" };
|
|
14044
|
+
inst = existing;
|
|
14045
|
+
} else {
|
|
14046
|
+
const created = this.createInstance({
|
|
14047
|
+
definition_id: def.id,
|
|
14048
|
+
definition_slug: def.slug,
|
|
14049
|
+
state_data: input.payload
|
|
14050
|
+
});
|
|
14051
|
+
if (!created) return { success: false, error: "Failed to create instance" };
|
|
14052
|
+
inst = created;
|
|
14053
|
+
}
|
|
14054
|
+
if (input.payload && input.instance_id) {
|
|
14055
|
+
Object.assign(inst.state_data, input.payload);
|
|
14056
|
+
}
|
|
14057
|
+
const transition = def.transitions.find((t27) => t27.name === input.action_name && t27.from.includes(inst.current_state));
|
|
14058
|
+
if (!transition) {
|
|
14059
|
+
return {
|
|
14060
|
+
success: false,
|
|
14061
|
+
instance_id: inst.id,
|
|
14062
|
+
from_state: inst.current_state,
|
|
14063
|
+
to_state: null,
|
|
14064
|
+
state_data: inst.state_data,
|
|
14065
|
+
error: `No transition '${input.action_name}' from state '${inst.current_state}'`
|
|
14066
|
+
};
|
|
14067
|
+
}
|
|
14068
|
+
const fromState = inst.current_state;
|
|
14069
|
+
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
14070
|
+
const events = [];
|
|
14071
|
+
let lastEvalResult = null;
|
|
14072
|
+
events.push({ event_type: "transition", message: `Transition '${transition.name}' started: ${fromState} \u2192 ${transition.to}`, timestamp: now });
|
|
14073
|
+
for (const action of transition.actions ?? []) {
|
|
14074
|
+
try {
|
|
14075
|
+
if (action.type === "set_field") {
|
|
14076
|
+
const field = action.config?.field;
|
|
14077
|
+
if (action.config?.expression) {
|
|
14078
|
+
const expr = action.config.expression;
|
|
14079
|
+
const result = this.evaluateSimpleExpression(expr, inst.state_data);
|
|
14080
|
+
inst.state_data[field] = result;
|
|
14081
|
+
} else if (action.config?.value !== void 0) {
|
|
14082
|
+
inst.state_data[field] = action.config.value;
|
|
14083
|
+
}
|
|
14084
|
+
events.push({ event_type: "action_executed", message: `transition action 'set_field' succeeded`, timestamp: now });
|
|
14085
|
+
} else if (action.type === "eval") {
|
|
14086
|
+
const expr = action.config?.expression;
|
|
14087
|
+
lastEvalResult = this.evaluateSimpleExpression(expr, inst.state_data);
|
|
14088
|
+
events.push({ event_type: "action_executed", message: `transition action 'eval' succeeded`, timestamp: now });
|
|
14089
|
+
} else {
|
|
14090
|
+
events.push({ event_type: "action_executed", message: `transition action '${action.type}' succeeded (no-op in local mode)`, timestamp: now });
|
|
14091
|
+
}
|
|
14092
|
+
} catch (err) {
|
|
14093
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
14094
|
+
events.push({ event_type: "action_failed", message: `transition action '${action.type}' failed: ${msg}`, timestamp: now });
|
|
14095
|
+
return {
|
|
14096
|
+
success: false,
|
|
14097
|
+
instance_id: inst.id,
|
|
14098
|
+
from_state: fromState,
|
|
14099
|
+
to_state: null,
|
|
14100
|
+
state_data: inst.state_data,
|
|
14101
|
+
event_log: events,
|
|
14102
|
+
error: `transition action failed: ${msg}`
|
|
14103
|
+
};
|
|
14104
|
+
}
|
|
14105
|
+
}
|
|
14106
|
+
inst.current_state = transition.to;
|
|
14107
|
+
inst.execution_lock_version++;
|
|
14108
|
+
inst.updated_at = now;
|
|
14109
|
+
events.push({ event_type: "transition", message: `State changed: ${fromState} \u2192 ${transition.to}`, timestamp: now });
|
|
14110
|
+
inst.event_log.push(...events);
|
|
14111
|
+
return {
|
|
14112
|
+
success: true,
|
|
14113
|
+
instance_id: inst.id,
|
|
14114
|
+
from_state: fromState,
|
|
14115
|
+
to_state: transition.to,
|
|
14116
|
+
state_data: inst.state_data,
|
|
14117
|
+
result: lastEvalResult,
|
|
14118
|
+
event_log: events
|
|
14119
|
+
};
|
|
14120
|
+
}
|
|
14121
|
+
/**
|
|
14122
|
+
* Minimal expression evaluator for local dev mode.
|
|
14123
|
+
* Handles: field references, arithmetic, string literals, simple comparisons.
|
|
14124
|
+
* Does NOT handle: while loops, if/else, function calls, multi-statement blocks.
|
|
14125
|
+
* For full evaluation, use mm-napi when available.
|
|
14126
|
+
*/
|
|
14127
|
+
evaluateSimpleExpression(expr, context) {
|
|
14128
|
+
if (context[expr] !== void 0) return context[expr];
|
|
14129
|
+
const arithMatch = expr.match(/^(\w+)\s*([+\-*/])\s*(\d+(?:\.\d+)?)$/);
|
|
14130
|
+
if (arithMatch) {
|
|
14131
|
+
const [, field, op, numStr] = arithMatch;
|
|
14132
|
+
const left = Number(context[field] ?? 0);
|
|
14133
|
+
const right = Number(numStr);
|
|
14134
|
+
switch (op) {
|
|
14135
|
+
case "+":
|
|
14136
|
+
return left + right;
|
|
14137
|
+
case "-":
|
|
14138
|
+
return left - right;
|
|
14139
|
+
case "*":
|
|
14140
|
+
return left * right;
|
|
14141
|
+
case "/":
|
|
14142
|
+
return right !== 0 ? left / right : 0;
|
|
14143
|
+
}
|
|
14144
|
+
}
|
|
14145
|
+
if (/^\d+(\.\d+)?$/.test(expr.trim())) {
|
|
14146
|
+
return Number(expr.trim());
|
|
14147
|
+
}
|
|
14148
|
+
const strMatch = expr.match(/^["'](.*)["']$/);
|
|
14149
|
+
if (strMatch) return strMatch[1];
|
|
14150
|
+
try {
|
|
14151
|
+
const keys = Object.keys(context);
|
|
14152
|
+
const values = Object.values(context);
|
|
14153
|
+
const fn = new Function(...keys, `"use strict"; return (${expr});`);
|
|
14154
|
+
return fn(...values);
|
|
14155
|
+
} catch {
|
|
14156
|
+
return null;
|
|
14157
|
+
}
|
|
14158
|
+
}
|
|
14159
|
+
};
|
|
14160
|
+
async function startLocalServer(options = {}) {
|
|
14161
|
+
const { port = 4200, noAuth = true } = options;
|
|
14162
|
+
const store = new MemoryStore();
|
|
14163
|
+
const startedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
14164
|
+
function json(res, status, body) {
|
|
14165
|
+
const data = JSON.stringify(body);
|
|
14166
|
+
res.writeHead(status, {
|
|
14167
|
+
"Content-Type": "application/json",
|
|
14168
|
+
"Access-Control-Allow-Origin": "*",
|
|
14169
|
+
"Access-Control-Allow-Methods": "GET, POST, PATCH, PUT, DELETE, OPTIONS",
|
|
14170
|
+
"Access-Control-Allow-Headers": "Content-Type, Authorization",
|
|
14171
|
+
"Content-Length": Buffer.byteLength(data)
|
|
14172
|
+
});
|
|
14173
|
+
res.end(data);
|
|
14174
|
+
}
|
|
14175
|
+
function readBody(req) {
|
|
14176
|
+
return new Promise((resolve3, reject) => {
|
|
14177
|
+
const chunks = [];
|
|
14178
|
+
req.on("data", (chunk) => chunks.push(chunk));
|
|
14179
|
+
req.on("end", () => resolve3(Buffer.concat(chunks).toString()));
|
|
14180
|
+
req.on("error", reject);
|
|
14181
|
+
});
|
|
14182
|
+
}
|
|
14183
|
+
function parseQuery(url) {
|
|
14184
|
+
const idx = url.indexOf("?");
|
|
14185
|
+
if (idx === -1) return {};
|
|
14186
|
+
const params = {};
|
|
14187
|
+
const qs = url.slice(idx + 1);
|
|
14188
|
+
for (const pair of qs.split("&")) {
|
|
14189
|
+
const [k, v] = pair.split("=");
|
|
14190
|
+
if (k) params[decodeURIComponent(k)] = decodeURIComponent(v ?? "");
|
|
14191
|
+
}
|
|
14192
|
+
return params;
|
|
14193
|
+
}
|
|
14194
|
+
const server = http.createServer(async (req, res) => {
|
|
14195
|
+
const method = req.method?.toUpperCase() ?? "GET";
|
|
14196
|
+
const rawUrl = req.url ?? "/";
|
|
14197
|
+
const queryStart = rawUrl.indexOf("?");
|
|
14198
|
+
const path = queryStart >= 0 ? rawUrl.slice(0, queryStart) : rawUrl;
|
|
14199
|
+
const query = parseQuery(rawUrl);
|
|
14200
|
+
if (method === "OPTIONS") {
|
|
14201
|
+
res.writeHead(204, {
|
|
14202
|
+
"Access-Control-Allow-Origin": "*",
|
|
14203
|
+
"Access-Control-Allow-Methods": "GET, POST, PATCH, PUT, DELETE, OPTIONS",
|
|
14204
|
+
"Access-Control-Allow-Headers": "Content-Type, Authorization",
|
|
14205
|
+
"Access-Control-Max-Age": "86400"
|
|
14206
|
+
});
|
|
14207
|
+
res.end();
|
|
14208
|
+
return;
|
|
14209
|
+
}
|
|
14210
|
+
try {
|
|
14211
|
+
if (path === "/health" && method === "GET") {
|
|
14212
|
+
return json(res, 200, {
|
|
14213
|
+
status: "ok",
|
|
14214
|
+
service: "mm-local-dev",
|
|
14215
|
+
mode: "in-memory",
|
|
14216
|
+
started_at: startedAt,
|
|
14217
|
+
definitions: store.definitions.size,
|
|
14218
|
+
instances: store.instances.size
|
|
14219
|
+
});
|
|
14220
|
+
}
|
|
14221
|
+
if (path === "/api/v1/auth/login" && (method === "POST" || method === "GET")) {
|
|
14222
|
+
return json(res, 200, {
|
|
14223
|
+
token: "dev-token-local",
|
|
14224
|
+
user: {
|
|
14225
|
+
id: "dev-user-001",
|
|
14226
|
+
email: "dev@localhost",
|
|
14227
|
+
role: "admin",
|
|
14228
|
+
name: "Local Developer"
|
|
14229
|
+
}
|
|
14230
|
+
});
|
|
14231
|
+
}
|
|
14232
|
+
if (path === "/api/v1/workflow/definitions" && method === "GET") {
|
|
14233
|
+
const result = store.listDefinitions({
|
|
14234
|
+
category: query.category,
|
|
14235
|
+
limit: query.limit ? parseInt(query.limit, 10) : void 0,
|
|
14236
|
+
offset: query.offset ? parseInt(query.offset, 10) : void 0
|
|
14237
|
+
});
|
|
14238
|
+
if (query.slug) {
|
|
14239
|
+
const def = store.getDefinition(query.slug);
|
|
14240
|
+
return json(res, 200, { items: def ? [def] : [], total: def ? 1 : 0 });
|
|
14241
|
+
}
|
|
14242
|
+
return json(res, 200, result);
|
|
14243
|
+
}
|
|
14244
|
+
const defMatch = path.match(/^\/api\/v1\/workflow\/definitions\/([^/]+)$/);
|
|
14245
|
+
if (defMatch && method === "GET") {
|
|
14246
|
+
const def = store.getDefinition(defMatch[1]);
|
|
14247
|
+
if (!def) return json(res, 404, { error: "Not found" });
|
|
14248
|
+
return json(res, 200, def);
|
|
14249
|
+
}
|
|
14250
|
+
if (path === "/api/v1/workflow/definitions" && method === "POST") {
|
|
14251
|
+
const body = JSON.parse(await readBody(req));
|
|
14252
|
+
const def = store.createDefinition(body);
|
|
14253
|
+
return json(res, 201, def);
|
|
14254
|
+
}
|
|
14255
|
+
if (defMatch && method === "PATCH") {
|
|
14256
|
+
const body = JSON.parse(await readBody(req));
|
|
14257
|
+
const updated = store.patchDefinition(defMatch[1], body);
|
|
14258
|
+
if (!updated) return json(res, 404, { error: "Not found" });
|
|
14259
|
+
return json(res, 200, updated);
|
|
14260
|
+
}
|
|
14261
|
+
if (defMatch && method === "DELETE") {
|
|
14262
|
+
const deleted = store.deleteDefinition(defMatch[1]);
|
|
14263
|
+
if (!deleted) return json(res, 404, { error: "Not found" });
|
|
14264
|
+
return json(res, 204, null);
|
|
14265
|
+
}
|
|
14266
|
+
if (path === "/api/v1/workflow/instances" && method === "GET") {
|
|
14267
|
+
const result = store.listInstances({
|
|
14268
|
+
definition_id: query.definition_id,
|
|
14269
|
+
limit: query.limit ? parseInt(query.limit, 10) : void 0,
|
|
14270
|
+
offset: query.offset ? parseInt(query.offset, 10) : void 0
|
|
14271
|
+
});
|
|
14272
|
+
return json(res, 200, result);
|
|
14273
|
+
}
|
|
14274
|
+
if (path === "/api/v1/workflow/instances" && method === "POST") {
|
|
14275
|
+
const body = JSON.parse(await readBody(req));
|
|
14276
|
+
const inst = store.createInstance(body);
|
|
14277
|
+
if (!inst) return json(res, 404, { error: "Definition not found" });
|
|
14278
|
+
return json(res, 201, inst);
|
|
14279
|
+
}
|
|
14280
|
+
const instMatch = path.match(/^\/api\/v1\/workflow\/instances\/([^/]+)$/);
|
|
14281
|
+
if (instMatch && method === "GET") {
|
|
14282
|
+
const inst = store.getInstance(instMatch[1]);
|
|
14283
|
+
if (!inst) return json(res, 404, { error: "Not found" });
|
|
14284
|
+
return json(res, 200, inst);
|
|
14285
|
+
}
|
|
14286
|
+
if (path === "/api/v1/workflow/execute-action" && method === "POST") {
|
|
14287
|
+
const body = JSON.parse(await readBody(req));
|
|
14288
|
+
const result = store.executeAction(body);
|
|
14289
|
+
return json(res, 200, result);
|
|
14290
|
+
}
|
|
14291
|
+
const dataMatch = path.match(/^\/api\/v1\/data\/([^/]+)$/);
|
|
14292
|
+
if (dataMatch && method === "GET") {
|
|
14293
|
+
const def = store.getDefinition(dataMatch[1]);
|
|
14294
|
+
if (!def) return json(res, 404, { error: "Not found" });
|
|
14295
|
+
const instances = store.listInstances({ definition_id: def.id });
|
|
14296
|
+
return json(res, 200, instances);
|
|
14297
|
+
}
|
|
14298
|
+
if (path.startsWith("/api/v1/")) {
|
|
14299
|
+
return json(res, 501, { error: "Not implemented in local dev mode", path, method });
|
|
14300
|
+
}
|
|
14301
|
+
return json(res, 404, { error: "Not found", path });
|
|
14302
|
+
} catch (err) {
|
|
14303
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
14304
|
+
console.error(`[mm-local] ${method} ${path} \u2014 Error: ${message}`);
|
|
14305
|
+
return json(res, 500, { error: message });
|
|
14306
|
+
}
|
|
14307
|
+
});
|
|
14308
|
+
return new Promise((resolve3, reject) => {
|
|
14309
|
+
server.on("error", (err) => {
|
|
14310
|
+
if (err.code === "EADDRINUSE") {
|
|
14311
|
+
reject(new Error(`Port ${port} is already in use. Is another server running?`));
|
|
14312
|
+
} else {
|
|
14313
|
+
reject(err);
|
|
14314
|
+
}
|
|
14315
|
+
});
|
|
14316
|
+
server.listen(port, () => {
|
|
14317
|
+
console.log(`[mm-local] Local API server running at http://localhost:${port}`);
|
|
14318
|
+
console.log(`[mm-local] Mode: in-memory (data lost on restart)`);
|
|
14319
|
+
console.log(`[mm-local] Auth: disabled (all requests accepted)`);
|
|
14320
|
+
resolve3({
|
|
14321
|
+
server,
|
|
14322
|
+
port,
|
|
14323
|
+
store,
|
|
14324
|
+
async close() {
|
|
14325
|
+
return new Promise((res) => {
|
|
14326
|
+
server.close(() => {
|
|
14327
|
+
console.log("[mm-local] Local API server stopped");
|
|
14328
|
+
res();
|
|
14329
|
+
});
|
|
14330
|
+
});
|
|
14331
|
+
}
|
|
14332
|
+
});
|
|
14333
|
+
});
|
|
14334
|
+
});
|
|
14335
|
+
}
|
|
14336
|
+
|
|
14337
|
+
// src/dev-server.ts
|
|
14338
|
+
var currentErrors = null;
|
|
14339
|
+
function escapeHtml(s) {
|
|
14340
|
+
return s.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """);
|
|
14341
|
+
}
|
|
14342
|
+
function renderErrorOverlay(errors) {
|
|
14343
|
+
const cards = errors.map((err) => {
|
|
14344
|
+
const loc = err.line ? `${err.file}:${err.line}${err.column ? ":" + err.column : ""}` : err.file;
|
|
14345
|
+
const snippet = err.snippet ? `<pre style="background:#1a1a2e;color:#e0e0e0;padding:12px 16px;border-radius:6px;overflow-x:auto;margin-top:8px;font-size:13px;line-height:1.5">${escapeHtml(err.snippet)}</pre>` : "";
|
|
14346
|
+
return `<div style="background:#2d1b1b;border:1px solid #5c2020;border-radius:8px;padding:16px 20px;margin-bottom:12px">
|
|
14347
|
+
<div style="color:#ff6b6b;font-family:monospace;font-size:13px;margin-bottom:6px">${escapeHtml(loc)}</div>
|
|
14348
|
+
<div style="color:#ffa0a0;font-size:15px;font-weight:500">${escapeHtml(err.message)}</div>${snippet}</div>`;
|
|
14349
|
+
}).join("\n");
|
|
14350
|
+
return `<!DOCTYPE html><html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1">
|
|
14351
|
+
<title>Compile Error - MindMatrix Dev</title>
|
|
14352
|
+
<style>*{box-sizing:border-box;margin:0;padding:0}body{background:#1a1a2e;color:#e0e0e0;font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,sans-serif;padding:40px 20px;min-height:100vh}</style></head>
|
|
14353
|
+
<body><div style="max-width:800px;margin:0 auto">
|
|
14354
|
+
<div style="display:flex;align-items:center;gap:12px;margin-bottom:24px">
|
|
14355
|
+
<div style="background:#5c2020;color:#ff6b6b;font-size:14px;font-weight:600;padding:4px 10px;border-radius:4px">COMPILE ERROR</div>
|
|
14356
|
+
<div style="color:#888;font-size:13px">${errors.length} error${errors.length !== 1 ? "s" : ""}</div></div>
|
|
14357
|
+
${cards}
|
|
14358
|
+
<div style="color:#666;font-size:12px;margin-top:24px;text-align:center">Fix the error and save -- the page will reload automatically.</div></div>
|
|
14359
|
+
<script>const ws=new WebSocket('ws://'+location.host+'/__mm_dev');ws.onmessage=e=>{const m=JSON.parse(e.data);if(m.type==='workflow:compiled'||m.type==='workflow:rebuild')location.reload()};ws.onclose=()=>setTimeout(()=>location.reload(),2000)</script>
|
|
14360
|
+
</body></html>`;
|
|
14361
|
+
}
|
|
14362
|
+
function errorOverlayMiddleware() {
|
|
14363
|
+
return (req, res, next) => {
|
|
14364
|
+
if (!currentErrors || !req.url) return next();
|
|
14365
|
+
const url = req.url;
|
|
14366
|
+
if (url.startsWith("/api") || url.startsWith("/health") || url.startsWith("/ws") || url.startsWith("/__mm_dev") || url.startsWith("/@") || url.startsWith("/node_modules")) return next();
|
|
14367
|
+
const accept = req.headers?.accept ?? "";
|
|
14368
|
+
if (!accept.includes("text/html")) return next();
|
|
14369
|
+
res.writeHead(500, { "Content-Type": "text/html; charset=utf-8" });
|
|
14370
|
+
res.end(renderErrorOverlay(currentErrors));
|
|
14371
|
+
};
|
|
14372
|
+
}
|
|
14373
|
+
async function resolveDevToken(apiUrl, explicit) {
|
|
14374
|
+
if (explicit) return explicit;
|
|
14375
|
+
try {
|
|
14376
|
+
const { resolveToken: resolveToken2 } = await Promise.resolve().then(() => (init_auth(), auth_exports));
|
|
14377
|
+
const s = resolveToken2(apiUrl);
|
|
14378
|
+
if (s) return s;
|
|
14379
|
+
} catch {
|
|
14380
|
+
}
|
|
14381
|
+
try {
|
|
14382
|
+
const resp = await fetch(`${apiUrl}/auth/login`, {
|
|
14383
|
+
method: "POST",
|
|
14384
|
+
headers: { "Content-Type": "application/json" },
|
|
14385
|
+
body: JSON.stringify({ email: "admin@mindmatrix.com", password: "Admin123!" })
|
|
14386
|
+
});
|
|
14387
|
+
if (resp.ok) {
|
|
14388
|
+
const data = await resp.json();
|
|
14389
|
+
const token = data.token ?? data.access_token;
|
|
14390
|
+
if (token) {
|
|
14391
|
+
try {
|
|
14392
|
+
const { saveCredentials: saveCredentials2 } = await Promise.resolve().then(() => (init_auth(), auth_exports));
|
|
14393
|
+
saveCredentials2(apiUrl, token);
|
|
14394
|
+
} catch {
|
|
14395
|
+
}
|
|
14396
|
+
return token;
|
|
14397
|
+
}
|
|
14398
|
+
}
|
|
14399
|
+
} catch {
|
|
14400
|
+
}
|
|
14401
|
+
return process.env.MINDMATRIX_TOKEN;
|
|
14402
|
+
}
|
|
14403
|
+
async function checkBackendHealth(apiUrl) {
|
|
14404
|
+
try {
|
|
14405
|
+
const base = apiUrl.replace(/\/api\/v1\/?$/, "");
|
|
14406
|
+
const resp = await fetch(`${base}/health`, { signal: AbortSignal.timeout(5e3) });
|
|
14407
|
+
if (resp.ok) {
|
|
14408
|
+
const d = await resp.json();
|
|
14409
|
+
return { ok: true, version: d.version, db: d.database };
|
|
14410
|
+
}
|
|
14411
|
+
return { ok: resp.status < 500 };
|
|
14412
|
+
} catch {
|
|
14413
|
+
return { ok: false };
|
|
14414
|
+
}
|
|
14415
|
+
}
|
|
14416
|
+
async function initialBuildDeploy(src, outDir, mode, apiUrl, token) {
|
|
14417
|
+
console.log("[mm-dev] Compiling project...");
|
|
14418
|
+
const buildResult = await build({ src, outDir, mode, skipTypeCheck: true });
|
|
14419
|
+
if (buildResult.errors > 0) {
|
|
14420
|
+
currentErrors = buildResult.errorDetails.map((e) => ({ file: e.file, message: e.message, line: e.line }));
|
|
14421
|
+
console.error(`[mm-dev] Build failed with ${buildResult.errors} error(s) -- error overlay active`);
|
|
14422
|
+
return { buildResult, deployed: false, slug: void 0 };
|
|
14423
|
+
}
|
|
14424
|
+
currentErrors = null;
|
|
14425
|
+
if (buildResult.compiled === 0) return { buildResult, deployed: false, slug: void 0 };
|
|
14426
|
+
console.log(`[mm-dev] Compiled ${buildResult.compiled} definition(s)`);
|
|
14427
|
+
try {
|
|
14428
|
+
const { deploy: deploy2 } = await Promise.resolve().then(() => (init_deploy(), deploy_exports));
|
|
14429
|
+
const result = await deploy2({ apiUrl, token, dir: outDir });
|
|
14430
|
+
const total = result.created.length + result.updated.length + result.versioned.length;
|
|
14431
|
+
if (total > 0) console.log(`[mm-dev] Deployed: ${result.created.length} created, ${result.updated.length} updated`);
|
|
14432
|
+
return { buildResult, deployed: true, slug: buildResult.definitions?.[0]?.slug };
|
|
14433
|
+
} catch (e) {
|
|
14434
|
+
console.warn(`[mm-dev] Deploy failed: ${e instanceof Error ? e.message : e}`);
|
|
14435
|
+
return { buildResult, deployed: false, slug: void 0 };
|
|
14436
|
+
}
|
|
14437
|
+
}
|
|
14438
|
+
function printBanner(o) {
|
|
14439
|
+
const l = "-".repeat(58);
|
|
14440
|
+
console.log(`
|
|
14441
|
+
${l}
|
|
14442
|
+
MindMatrix Dev Server
|
|
14443
|
+
${l}
|
|
14444
|
+
`);
|
|
14445
|
+
console.log(` Preview: http://localhost:${o.port}`);
|
|
14446
|
+
console.log(` API Proxy: /api/* -> ${o.apiUrl}`);
|
|
14447
|
+
console.log(` WebSocket: ws://localhost:${o.port}/__mm_dev`);
|
|
14448
|
+
console.log(` Watching: ${o.src} (${o.include.join(", ")})
|
|
14449
|
+
`);
|
|
14450
|
+
console.log(` Backend: ${o.health.ok ? "connected" : "unreachable"}${o.health.version ? ` (v${o.health.version})` : ""}`);
|
|
14451
|
+
if (o.health.db) console.log(` Database: ${o.health.db}`);
|
|
14452
|
+
console.log(` Auth: ${o.token ? "authenticated" : "no token"}`);
|
|
14453
|
+
if (o.compiled > 0) {
|
|
14454
|
+
console.log(` Blueprint: ${o.slug ?? "unknown"} (${o.compiled} defs)`);
|
|
14455
|
+
console.log(` Deploy: ${o.deployed ? "synced" : "pending"}`);
|
|
14456
|
+
}
|
|
14457
|
+
if (o.errors > 0) console.log(` Errors: ${o.errors} compile error(s) -- overlay active`);
|
|
14458
|
+
console.log(`
|
|
14459
|
+
${l}
|
|
14460
|
+
`);
|
|
14461
|
+
}
|
|
14462
|
+
function broadcast(clients, data) {
|
|
14463
|
+
const msg = JSON.stringify(data);
|
|
14464
|
+
for (const c of clients) {
|
|
14465
|
+
try {
|
|
14466
|
+
if (c.readyState === 1) c.send(msg);
|
|
14467
|
+
} catch {
|
|
14468
|
+
clients.delete(c);
|
|
14469
|
+
}
|
|
14470
|
+
}
|
|
13382
14471
|
}
|
|
13383
|
-
|
|
13384
|
-
// src/dev-server.ts
|
|
13385
14472
|
async function createDevServer(options = {}) {
|
|
13386
14473
|
const {
|
|
13387
14474
|
port = 5199,
|
|
@@ -13390,44 +14477,87 @@ async function createDevServer(options = {}) {
|
|
|
13390
14477
|
include = ["**/*.workflow.tsx"],
|
|
13391
14478
|
outDir = "dist/workflows",
|
|
13392
14479
|
seed = false,
|
|
13393
|
-
apiUrl = "
|
|
13394
|
-
authToken
|
|
14480
|
+
apiUrl: rawApiUrl = "auto",
|
|
14481
|
+
authToken: explicitToken,
|
|
13395
14482
|
ws: enableWs = true,
|
|
13396
14483
|
open = false
|
|
13397
14484
|
} = options;
|
|
13398
14485
|
const clients = /* @__PURE__ */ new Set();
|
|
13399
|
-
|
|
13400
|
-
|
|
13401
|
-
|
|
13402
|
-
|
|
13403
|
-
|
|
13404
|
-
apiUrl
|
|
13405
|
-
|
|
13406
|
-
}
|
|
13407
|
-
|
|
13408
|
-
|
|
14486
|
+
let localServer = null;
|
|
14487
|
+
let apiUrl;
|
|
14488
|
+
let isLocalMode = false;
|
|
14489
|
+
if (rawApiUrl === "local") {
|
|
14490
|
+
localServer = await startLocalServer({ port: 4200 });
|
|
14491
|
+
apiUrl = "http://localhost:4200/api/v1";
|
|
14492
|
+
isLocalMode = true;
|
|
14493
|
+
} else if (rawApiUrl === "auto") {
|
|
14494
|
+
const defaultRemote = "https://dev.mindmatrix.club/api/v1";
|
|
14495
|
+
const remoteHealth = await checkBackendHealth(defaultRemote);
|
|
14496
|
+
if (remoteHealth.ok) {
|
|
14497
|
+
apiUrl = defaultRemote;
|
|
14498
|
+
} else {
|
|
14499
|
+
const localHealth = await checkBackendHealth("http://localhost:4200/api/v1");
|
|
14500
|
+
if (localHealth.ok) {
|
|
14501
|
+
apiUrl = "http://localhost:4200/api/v1";
|
|
14502
|
+
} else {
|
|
14503
|
+
console.log("[mm-dev] No backend detected \u2014 starting local in-memory API server...");
|
|
14504
|
+
localServer = await startLocalServer({ port: 4200 });
|
|
14505
|
+
apiUrl = "http://localhost:4200/api/v1";
|
|
14506
|
+
isLocalMode = true;
|
|
14507
|
+
}
|
|
14508
|
+
}
|
|
14509
|
+
} else {
|
|
14510
|
+
apiUrl = rawApiUrl;
|
|
14511
|
+
}
|
|
14512
|
+
const token = isLocalMode ? "dev-token-local" : await resolveDevToken(apiUrl, explicitToken);
|
|
14513
|
+
const health = isLocalMode ? { ok: true, version: "local", db: "in-memory" } : await checkBackendHealth(apiUrl);
|
|
14514
|
+
let initialSlug, initialCompiled = 0, initialDeployed = false, initialErrors = 0;
|
|
14515
|
+
if (token && health.ok) {
|
|
14516
|
+
const r = await initialBuildDeploy(src, outDir, mode, apiUrl, token);
|
|
14517
|
+
initialCompiled = r.buildResult.compiled;
|
|
14518
|
+
initialDeployed = r.deployed;
|
|
14519
|
+
initialSlug = r.slug;
|
|
14520
|
+
initialErrors = r.buildResult.errors;
|
|
14521
|
+
}
|
|
14522
|
+
if (seed && token && initialDeployed) {
|
|
14523
|
+
try {
|
|
14524
|
+
const { seedInstances: seedInstances2 } = await Promise.resolve().then(() => (init_seed(), seed_exports));
|
|
14525
|
+
console.log("[mm-dev] Seeding sample instances...");
|
|
14526
|
+
const sr = await seedInstances2({ apiUrl, token, dir: outDir });
|
|
14527
|
+
console.log(`[mm-dev] Seeded ${sr.created} instance(s) across ${sr.definitions} definition(s)`);
|
|
14528
|
+
} catch (e) {
|
|
14529
|
+
console.warn(`[mm-dev] Seed failed: ${e instanceof Error ? e.message : e}`);
|
|
14530
|
+
}
|
|
14531
|
+
}
|
|
14532
|
+
const pluginOpts = { mode, include, outDir, seedOnCompile: seed, apiUrl, authToken: token };
|
|
14533
|
+
const proxyTarget = apiUrl.replace(/\/api\/v1\/?$/, "") || apiUrl;
|
|
14534
|
+
let deployInFlight = false;
|
|
14535
|
+
const compileDeployPlugin = {
|
|
14536
|
+
name: "mindmatrix-dev-compile-deploy",
|
|
13409
14537
|
enforce: "post",
|
|
13410
|
-
handleHotUpdate(ctx) {
|
|
13411
|
-
const
|
|
13412
|
-
|
|
13413
|
-
|
|
13414
|
-
});
|
|
13415
|
-
|
|
13416
|
-
|
|
13417
|
-
|
|
13418
|
-
|
|
13419
|
-
|
|
13420
|
-
}
|
|
13421
|
-
|
|
14538
|
+
async handleHotUpdate(ctx) {
|
|
14539
|
+
const isWf = include.some((p) => new RegExp(p.replace(/[.+^${}()|[\]\\]/g, "\\$&").replace(/\*\*/g, "<<G>>").replace(/\*/g, "[^/]*").replace(/<<G>>/g, ".*").replace(/\?/g, ".")).test(ctx.file));
|
|
14540
|
+
if (!isWf) return;
|
|
14541
|
+
const fn = ctx.file.split("/").pop() ?? ctx.file;
|
|
14542
|
+
console.log(`[mm-dev] Recompiling ${fn}...`);
|
|
14543
|
+
const br = await build({ src, outDir, mode, skipTypeCheck: true });
|
|
14544
|
+
if (br.errors > 0) {
|
|
14545
|
+
currentErrors = br.errorDetails.map((e) => ({ file: e.file, message: e.message, line: e.line }));
|
|
14546
|
+
broadcast(clients, { type: "workflow:error", errors: br.errors, timestamp: ctx.timestamp });
|
|
14547
|
+
return;
|
|
14548
|
+
}
|
|
14549
|
+
currentErrors = null;
|
|
14550
|
+
if (token && !deployInFlight) {
|
|
14551
|
+
deployInFlight = true;
|
|
13422
14552
|
try {
|
|
13423
|
-
|
|
13424
|
-
|
|
13425
|
-
}
|
|
14553
|
+
const { deploy: d } = await Promise.resolve().then(() => (init_deploy(), deploy_exports));
|
|
14554
|
+
await d({ apiUrl, token, dir: outDir });
|
|
13426
14555
|
} catch {
|
|
13427
|
-
|
|
14556
|
+
} finally {
|
|
14557
|
+
deployInFlight = false;
|
|
13428
14558
|
}
|
|
13429
14559
|
}
|
|
13430
|
-
|
|
14560
|
+
broadcast(clients, { type: "workflow:compiled", file: ctx.file, compiled: br.compiled, timestamp: ctx.timestamp });
|
|
13431
14561
|
}
|
|
13432
14562
|
};
|
|
13433
14563
|
const viteConfig = {
|
|
@@ -13435,311 +14565,93 @@ async function createDevServer(options = {}) {
|
|
|
13435
14565
|
server: {
|
|
13436
14566
|
port,
|
|
13437
14567
|
open,
|
|
13438
|
-
host: true
|
|
14568
|
+
host: true,
|
|
14569
|
+
proxy: {
|
|
14570
|
+
"/api": { target: proxyTarget, changeOrigin: true, secure: true, ws: true },
|
|
14571
|
+
"/health": { target: proxyTarget, changeOrigin: true, secure: true },
|
|
14572
|
+
"/ws": { target: proxyTarget.replace(/^http/, "ws"), changeOrigin: true, ws: true }
|
|
14573
|
+
}
|
|
13439
14574
|
},
|
|
13440
14575
|
plugins: [
|
|
13441
|
-
mindmatrixReact(
|
|
13442
|
-
|
|
14576
|
+
mindmatrixReact(pluginOpts),
|
|
14577
|
+
compileDeployPlugin,
|
|
14578
|
+
{ name: "mindmatrix-error-overlay", configureServer(server) {
|
|
14579
|
+
server.middlewares.use(errorOverlayMiddleware());
|
|
14580
|
+
} }
|
|
13443
14581
|
],
|
|
13444
|
-
logLevel: "
|
|
14582
|
+
logLevel: "warn"
|
|
13445
14583
|
};
|
|
13446
|
-
const { createServer } = await import("vite");
|
|
13447
|
-
const vite = await
|
|
14584
|
+
const { createServer: createServer2 } = await import("vite");
|
|
14585
|
+
const vite = await createServer2(viteConfig);
|
|
13448
14586
|
await vite.listen();
|
|
13449
14587
|
const resolvedPort = vite.config.server.port ?? port;
|
|
13450
14588
|
if (enableWs && vite.httpServer) {
|
|
13451
14589
|
try {
|
|
13452
|
-
const
|
|
13453
|
-
const
|
|
13454
|
-
if (
|
|
13455
|
-
const wss = new
|
|
13456
|
-
|
|
13457
|
-
|
|
13458
|
-
|
|
13459
|
-
|
|
13460
|
-
clients.add(socket);
|
|
13461
|
-
console.log(`[mm-dev] Editor connected (${clients.size} total)`);
|
|
13462
|
-
socket.on("close", () => {
|
|
13463
|
-
clients.delete(socket);
|
|
13464
|
-
console.log(`[mm-dev] Editor disconnected (${clients.size} total)`);
|
|
13465
|
-
});
|
|
13466
|
-
socket.send(JSON.stringify({
|
|
13467
|
-
type: "mm:connected",
|
|
13468
|
-
version: "0.1.0",
|
|
13469
|
-
capabilities: ["compile", "seed", "notify"]
|
|
13470
|
-
}));
|
|
14590
|
+
const wsM = await Function('return import("ws")')();
|
|
14591
|
+
const WSS = wsM.WebSocketServer ?? wsM.default?.WebSocketServer;
|
|
14592
|
+
if (WSS) {
|
|
14593
|
+
const wss = new WSS({ server: vite.httpServer, path: "/__mm_dev" });
|
|
14594
|
+
wss.on("connection", (s) => {
|
|
14595
|
+
clients.add(s);
|
|
14596
|
+
s.on("close", () => clients.delete(s));
|
|
14597
|
+
s.send(JSON.stringify({ type: "mm:connected", version: "0.1.0", capabilities: ["compile", "deploy", "proxy", "notify", "error-overlay"] }));
|
|
13471
14598
|
});
|
|
13472
14599
|
}
|
|
13473
14600
|
} catch {
|
|
13474
|
-
console.warn("[mm-dev] ws package not available \u2014 WebSocket notifications disabled");
|
|
13475
14601
|
}
|
|
13476
14602
|
}
|
|
13477
|
-
|
|
13478
|
-
[mm-dev] MindMatrix Dev Server running`);
|
|
13479
|
-
console.log(` Local: http://localhost:${resolvedPort}`);
|
|
13480
|
-
console.log(` WebSocket: ws://localhost:${resolvedPort}/__mm_dev`);
|
|
13481
|
-
console.log(` Watching: ${src} (${include.join(", ")})`);
|
|
13482
|
-
if (seed) {
|
|
13483
|
-
console.log(` Seeding: ${apiUrl}`);
|
|
13484
|
-
}
|
|
13485
|
-
console.log();
|
|
14603
|
+
printBanner({ port: resolvedPort, apiUrl: isLocalMode ? `${apiUrl} (local in-memory)` : apiUrl, src, include, health, token: !!token, compiled: initialCompiled, deployed: initialDeployed, slug: initialSlug, errors: initialErrors });
|
|
13486
14604
|
return {
|
|
13487
14605
|
vite,
|
|
13488
14606
|
port: resolvedPort,
|
|
13489
14607
|
clients,
|
|
13490
14608
|
async rebuild() {
|
|
13491
|
-
|
|
13492
|
-
|
|
13493
|
-
|
|
13494
|
-
|
|
13495
|
-
|
|
13496
|
-
|
|
13497
|
-
|
|
13498
|
-
|
|
13499
|
-
|
|
13500
|
-
|
|
13501
|
-
|
|
13502
|
-
} catch {
|
|
13503
|
-
clients.delete(client);
|
|
14609
|
+
const r = await build({ src, outDir, mode });
|
|
14610
|
+
if (r.errors > 0) {
|
|
14611
|
+
currentErrors = r.errorDetails.map((e) => ({ file: e.file, message: e.message, line: e.line }));
|
|
14612
|
+
} else {
|
|
14613
|
+
currentErrors = null;
|
|
14614
|
+
if (token) {
|
|
14615
|
+
try {
|
|
14616
|
+
const { deploy: d } = await Promise.resolve().then(() => (init_deploy(), deploy_exports));
|
|
14617
|
+
await d({ apiUrl, token, dir: outDir });
|
|
14618
|
+
} catch {
|
|
14619
|
+
}
|
|
13504
14620
|
}
|
|
13505
14621
|
}
|
|
13506
|
-
|
|
14622
|
+
broadcast(clients, { type: "workflow:rebuild", compiled: r.compiled, errors: r.errors, timestamp: Date.now() });
|
|
14623
|
+
return r;
|
|
13507
14624
|
},
|
|
13508
14625
|
async close() {
|
|
13509
|
-
for (const
|
|
14626
|
+
for (const c of clients) {
|
|
13510
14627
|
try {
|
|
13511
|
-
|
|
14628
|
+
c.close();
|
|
13512
14629
|
} catch {
|
|
13513
14630
|
}
|
|
13514
14631
|
}
|
|
13515
14632
|
clients.clear();
|
|
14633
|
+
currentErrors = null;
|
|
13516
14634
|
await vite.close();
|
|
13517
|
-
|
|
14635
|
+
if (localServer) {
|
|
14636
|
+
await localServer.close();
|
|
14637
|
+
}
|
|
13518
14638
|
}
|
|
13519
14639
|
};
|
|
13520
14640
|
}
|
|
13521
14641
|
|
|
13522
|
-
// src/
|
|
13523
|
-
|
|
13524
|
-
var import_fs4 = require("fs");
|
|
13525
|
-
var import_path3 = require("path");
|
|
13526
|
-
async function deploy(options) {
|
|
13527
|
-
const dir = options.dir ?? "dist/workflows";
|
|
13528
|
-
const targetLabel = options.targetName ? ` (target: ${options.targetName})` : "";
|
|
13529
|
-
console.log(`[mindmatrix-react] Deploying workflows from ${dir} to ${options.apiUrl}${targetLabel}...`);
|
|
13530
|
-
const files = await (0, import_glob2.glob)(`${dir}/**/*.workflow.json`);
|
|
13531
|
-
if (files.length === 0) {
|
|
13532
|
-
console.log(`[mindmatrix-react] No workflow files found in ${dir}`);
|
|
13533
|
-
return { created: [], updated: [], versioned: [], skipped: [], failed: [] };
|
|
13534
|
-
}
|
|
13535
|
-
const result = {
|
|
13536
|
-
created: [],
|
|
13537
|
-
updated: [],
|
|
13538
|
-
versioned: [],
|
|
13539
|
-
skipped: [],
|
|
13540
|
-
failed: []
|
|
13541
|
-
};
|
|
13542
|
-
const deployedIRs = [];
|
|
13543
|
-
for (const file2 of files) {
|
|
13544
|
-
try {
|
|
13545
|
-
const ir = JSON.parse((0, import_fs4.readFileSync)(file2, "utf-8"));
|
|
13546
|
-
const slug = ir.slug;
|
|
13547
|
-
if (options.dryRun) {
|
|
13548
|
-
console.log(` [dry-run] Would deploy ${slug} (${(0, import_path3.basename)(file2)})`);
|
|
13549
|
-
continue;
|
|
13550
|
-
}
|
|
13551
|
-
const existing = await fetchExistingDefinition(options.apiUrl, options.token, slug);
|
|
13552
|
-
if (!existing) {
|
|
13553
|
-
await createDefinition(options.apiUrl, options.token, ir);
|
|
13554
|
-
console.log(` \u2713 ${slug} (created)`);
|
|
13555
|
-
result.created.push(slug);
|
|
13556
|
-
} else if (existing.instanceCount === 0 || options.force) {
|
|
13557
|
-
await updateDefinition(options.apiUrl, options.token, existing.id, ir);
|
|
13558
|
-
console.log(` \u2713 ${slug} (updated)`);
|
|
13559
|
-
result.updated.push(slug);
|
|
13560
|
-
} else {
|
|
13561
|
-
const newVersion = bumpVersion(existing.version);
|
|
13562
|
-
ir.version = newVersion;
|
|
13563
|
-
await createDefinition(options.apiUrl, options.token, ir);
|
|
13564
|
-
console.log(` \u2713 ${slug} v${newVersion} (new version, ${existing.instanceCount} instances on v${existing.version})`);
|
|
13565
|
-
result.versioned.push(slug);
|
|
13566
|
-
}
|
|
13567
|
-
deployedIRs.push(ir);
|
|
13568
|
-
} catch (error) {
|
|
13569
|
-
const slug = (0, import_path3.basename)(file2).replace(".workflow.json", "");
|
|
13570
|
-
const msg = error.message;
|
|
13571
|
-
console.error(` \u2717 ${slug}: ${msg}`);
|
|
13572
|
-
result.failed.push({ slug, error: msg });
|
|
13573
|
-
}
|
|
13574
|
-
}
|
|
13575
|
-
if (!options.dryRun) {
|
|
13576
|
-
for (const ir of deployedIRs) {
|
|
13577
|
-
const serviceResult = await syncServices(options.apiUrl, options.token, ir);
|
|
13578
|
-
if (serviceResult) {
|
|
13579
|
-
if (!result.services) {
|
|
13580
|
-
result.services = { registered: [], updated: [], failed: [] };
|
|
13581
|
-
}
|
|
13582
|
-
result.services.registered.push(...serviceResult.registered);
|
|
13583
|
-
result.services.updated.push(...serviceResult.updated);
|
|
13584
|
-
result.services.failed.push(...serviceResult.failed);
|
|
13585
|
-
}
|
|
13586
|
-
}
|
|
13587
|
-
}
|
|
13588
|
-
if (options.reportFile) {
|
|
13589
|
-
(0, import_fs4.writeFileSync)(options.reportFile, JSON.stringify(result, null, 2), "utf-8");
|
|
13590
|
-
console.log(`
|
|
13591
|
-
Report written to ${options.reportFile}`);
|
|
13592
|
-
}
|
|
13593
|
-
const total = result.created.length + result.updated.length + result.versioned.length;
|
|
13594
|
-
console.log(
|
|
13595
|
-
`
|
|
13596
|
-
[mindmatrix-react] Deployed ${total} workflows (${result.created.length} created, ${result.updated.length} updated, ${result.versioned.length} versioned, ${result.failed.length} failed)`
|
|
13597
|
-
);
|
|
13598
|
-
if (result.services) {
|
|
13599
|
-
const svcTotal = result.services.registered.length + result.services.updated.length;
|
|
13600
|
-
if (svcTotal > 0 || result.services.failed.length > 0) {
|
|
13601
|
-
console.log(
|
|
13602
|
-
`[mindmatrix-react] Synced ${svcTotal} services (${result.services.registered.length} registered, ${result.services.updated.length} updated, ${result.services.failed.length} failed)`
|
|
13603
|
-
);
|
|
13604
|
-
}
|
|
13605
|
-
}
|
|
13606
|
-
return result;
|
|
13607
|
-
}
|
|
13608
|
-
async function fetchExistingDefinition(apiUrl, token, slug) {
|
|
13609
|
-
try {
|
|
13610
|
-
const res = await fetch(`${apiUrl}/workflow/definitions?slug=${encodeURIComponent(slug)}`, {
|
|
13611
|
-
headers: { Authorization: `Bearer ${token}` }
|
|
13612
|
-
});
|
|
13613
|
-
if (!res.ok) return null;
|
|
13614
|
-
const data = await res.json();
|
|
13615
|
-
const definitions = Array.isArray(data) ? data : data.items ?? data.data;
|
|
13616
|
-
if (!definitions || definitions.length === 0) return null;
|
|
13617
|
-
const def = definitions[0];
|
|
13618
|
-
return {
|
|
13619
|
-
id: def.id,
|
|
13620
|
-
slug: def.slug,
|
|
13621
|
-
version: def.version || "0.1.0",
|
|
13622
|
-
instanceCount: def.instanceCount ?? def.instance_count ?? 0
|
|
13623
|
-
};
|
|
13624
|
-
} catch {
|
|
13625
|
-
return null;
|
|
13626
|
-
}
|
|
13627
|
-
}
|
|
13628
|
-
async function createDefinition(apiUrl, token, ir) {
|
|
13629
|
-
const res = await fetch(`${apiUrl}/workflow/definitions`, {
|
|
13630
|
-
method: "POST",
|
|
13631
|
-
headers: {
|
|
13632
|
-
"Content-Type": "application/json",
|
|
13633
|
-
Authorization: `Bearer ${token}`
|
|
13634
|
-
},
|
|
13635
|
-
body: JSON.stringify(ir)
|
|
13636
|
-
});
|
|
13637
|
-
if (!res.ok) {
|
|
13638
|
-
const errorText = await res.text();
|
|
13639
|
-
throw new Error(`Create failed: ${res.status} ${errorText}`);
|
|
13640
|
-
}
|
|
13641
|
-
}
|
|
13642
|
-
async function updateDefinition(apiUrl, token, id, ir) {
|
|
13643
|
-
const { slug: _slug, ...updatePayload } = ir;
|
|
13644
|
-
const res = await fetch(`${apiUrl}/workflow/definitions/${id}`, {
|
|
13645
|
-
method: "PATCH",
|
|
13646
|
-
headers: {
|
|
13647
|
-
"Content-Type": "application/json",
|
|
13648
|
-
Authorization: `Bearer ${token}`
|
|
13649
|
-
},
|
|
13650
|
-
body: JSON.stringify(updatePayload)
|
|
13651
|
-
});
|
|
13652
|
-
if (!res.ok) {
|
|
13653
|
-
const errorText = await res.text();
|
|
13654
|
-
throw new Error(`Update failed: ${res.status} ${errorText}`);
|
|
13655
|
-
}
|
|
13656
|
-
}
|
|
13657
|
-
function bumpVersion(version) {
|
|
13658
|
-
const parts = version.split(".");
|
|
13659
|
-
if (parts.length !== 3) return `${version}.1`;
|
|
13660
|
-
const patch = parseInt(parts[2], 10) || 0;
|
|
13661
|
-
return `${parts[0]}.${parts[1]}.${patch + 1}`;
|
|
13662
|
-
}
|
|
13663
|
-
async function syncServices(apiUrl, token, ir) {
|
|
13664
|
-
const metadata = ir.metadata;
|
|
13665
|
-
const orchestration = metadata?.orchestration;
|
|
13666
|
-
const services = orchestration?.services;
|
|
13667
|
-
if (!services || Object.keys(services).length === 0) return null;
|
|
13668
|
-
const result = { registered: [], updated: [], failed: [] };
|
|
13669
|
-
for (const [name, config] of Object.entries(services)) {
|
|
13670
|
-
try {
|
|
13671
|
-
const registration = {
|
|
13672
|
-
name,
|
|
13673
|
-
connection: {
|
|
13674
|
-
type: config.type || "webhook",
|
|
13675
|
-
url: config.url,
|
|
13676
|
-
queue: config.queue
|
|
13677
|
-
},
|
|
13678
|
-
actions: config.actions || [],
|
|
13679
|
-
labels: config.labels || {}
|
|
13680
|
-
};
|
|
13681
|
-
const existing = await fetchExistingService(apiUrl, token, name);
|
|
13682
|
-
if (existing) {
|
|
13683
|
-
await fetch(`${apiUrl}/services/${existing.id}`, {
|
|
13684
|
-
method: "PATCH",
|
|
13685
|
-
headers: {
|
|
13686
|
-
"Content-Type": "application/json",
|
|
13687
|
-
Authorization: `Bearer ${token}`
|
|
13688
|
-
},
|
|
13689
|
-
body: JSON.stringify(registration)
|
|
13690
|
-
});
|
|
13691
|
-
console.log(` \u2713 service: ${name} (updated)`);
|
|
13692
|
-
result.updated.push(name);
|
|
13693
|
-
} else {
|
|
13694
|
-
const res = await fetch(`${apiUrl}/services`, {
|
|
13695
|
-
method: "POST",
|
|
13696
|
-
headers: {
|
|
13697
|
-
"Content-Type": "application/json",
|
|
13698
|
-
Authorization: `Bearer ${token}`
|
|
13699
|
-
},
|
|
13700
|
-
body: JSON.stringify(registration)
|
|
13701
|
-
});
|
|
13702
|
-
if (!res.ok) {
|
|
13703
|
-
const errorText = await res.text();
|
|
13704
|
-
throw new Error(`Register failed: ${res.status} ${errorText}`);
|
|
13705
|
-
}
|
|
13706
|
-
console.log(` \u2713 service: ${name} (registered)`);
|
|
13707
|
-
result.registered.push(name);
|
|
13708
|
-
}
|
|
13709
|
-
} catch (error) {
|
|
13710
|
-
const msg = error.message;
|
|
13711
|
-
console.error(` \u2717 service: ${name}: ${msg}`);
|
|
13712
|
-
result.failed.push(name);
|
|
13713
|
-
}
|
|
13714
|
-
}
|
|
13715
|
-
return result;
|
|
13716
|
-
}
|
|
13717
|
-
async function fetchExistingService(apiUrl, token, name) {
|
|
13718
|
-
try {
|
|
13719
|
-
const res = await fetch(`${apiUrl}/services?name=${encodeURIComponent(name)}`, {
|
|
13720
|
-
headers: { Authorization: `Bearer ${token}` }
|
|
13721
|
-
});
|
|
13722
|
-
if (!res.ok) return null;
|
|
13723
|
-
const data = await res.json();
|
|
13724
|
-
const servicesList = Array.isArray(data) ? data : data.services ?? data.items ?? data.data;
|
|
13725
|
-
if (!servicesList || servicesList.length === 0) return null;
|
|
13726
|
-
const found = servicesList.find((s) => s.name === name);
|
|
13727
|
-
return found ? { id: found.id, name: found.name } : null;
|
|
13728
|
-
} catch {
|
|
13729
|
-
return null;
|
|
13730
|
-
}
|
|
13731
|
-
}
|
|
14642
|
+
// src/index.ts
|
|
14643
|
+
init_deploy();
|
|
13732
14644
|
|
|
13733
14645
|
// src/envelope.ts
|
|
13734
14646
|
var import_crypto3 = require("crypto");
|
|
13735
|
-
var
|
|
13736
|
-
var
|
|
13737
|
-
var
|
|
14647
|
+
var import_fs7 = require("fs");
|
|
14648
|
+
var import_path5 = require("path");
|
|
14649
|
+
var import_glob4 = require("glob");
|
|
13738
14650
|
var import_core7 = require("@babel/core");
|
|
13739
14651
|
init_babel();
|
|
13740
14652
|
async function buildEnvelope(projectDir, options = {}) {
|
|
13741
|
-
const root = (0,
|
|
13742
|
-
const slug = options.slug ?? (0,
|
|
14653
|
+
const root = (0, import_path5.resolve)(projectDir);
|
|
14654
|
+
const slug = options.slug ?? (0, import_path5.basename)(root);
|
|
13743
14655
|
const version = options.version ?? "0.1.0";
|
|
13744
14656
|
const mode = options.mode ?? "infer";
|
|
13745
14657
|
const patterns = options.include ?? [
|
|
@@ -13749,11 +14661,11 @@ async function buildEnvelope(projectDir, options = {}) {
|
|
|
13749
14661
|
];
|
|
13750
14662
|
const discoveredFiles = [];
|
|
13751
14663
|
for (const pattern of patterns) {
|
|
13752
|
-
const matches = await (0,
|
|
14664
|
+
const matches = await (0, import_glob4.glob)(pattern, { absolute: true });
|
|
13753
14665
|
discoveredFiles.push(...matches);
|
|
13754
14666
|
}
|
|
13755
14667
|
const uniqueFiles = [...new Set(discoveredFiles)];
|
|
13756
|
-
const allSourceFiles = await (0,
|
|
14668
|
+
const allSourceFiles = await (0, import_glob4.glob)(`${root}/**/*.{ts,tsx,js,jsx,css,json}`, {
|
|
13757
14669
|
absolute: true,
|
|
13758
14670
|
ignore: ["**/node_modules/**", "**/dist/**", "**/.git/**"]
|
|
13759
14671
|
});
|
|
@@ -13763,10 +14675,10 @@ async function buildEnvelope(projectDir, options = {}) {
|
|
|
13763
14675
|
const errors = [];
|
|
13764
14676
|
const sourceBindings = [];
|
|
13765
14677
|
for (const file2 of uniqueFiles) {
|
|
13766
|
-
const relativePath = (0,
|
|
14678
|
+
const relativePath = (0, import_path5.relative)(root, file2);
|
|
13767
14679
|
let fileContent;
|
|
13768
14680
|
try {
|
|
13769
|
-
fileContent = (0,
|
|
14681
|
+
fileContent = (0, import_fs7.readFileSync)(file2);
|
|
13770
14682
|
} catch {
|
|
13771
14683
|
errors.push({ file: relativePath, message: "Could not read file" });
|
|
13772
14684
|
continue;
|