mfeflow 0.6.0 → 0.7.0
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/assets/features/deploy-cloudflare/feature.json +85 -0
- package/assets/features/deploy-cloudflare/files/cloudflare.json.eta +13 -0
- package/assets/features/deploy-cloudflare/files/cloudflare.md.eta +104 -0
- package/assets/features/deploy-cloudflare/files/deploy-cloudflare.ts +318 -0
- package/assets/features/deploy-cloudflare/files/deploy-cloudflare.yml +111 -0
- package/assets/features/deploy-cloudflare/files/headers.remote +14 -0
- package/assets/features/deploy-cloudflare/files/headers.shell.eta +18 -0
- package/assets/features/deploy-cloudflare/files/r2-cors.json +10 -0
- package/assets/features/deploy-cloudflare/files/registry-proxy.ts +80 -0
- package/assets/features/deploy-cloudflare/files/wrangler.remote.jsonc.eta +21 -0
- package/assets/features/deploy-cloudflare/files/wrangler.shell.jsonc.eta +40 -0
- package/assets/features/deploy-docker/feature.json +22 -0
- package/assets/features/deploy-docker/files/40-mfe-config.sh +76 -0
- package/assets/features/deploy-docker/files/Dockerfile +48 -0
- package/assets/features/deploy-docker/files/compose-registry.json.eta +19 -0
- package/assets/features/deploy-docker/files/compose.yaml.eta +50 -0
- package/assets/features/deploy-docker/files/docker.md +52 -0
- package/assets/features/deploy-docker/files/dockerignore +17 -0
- package/assets/features/deploy-docker/files/k8s.yaml +114 -0
- package/assets/features/deploy-docker/files/nginx.remote.conf +73 -0
- package/assets/features/deploy-docker/files/nginx.shell.conf +84 -0
- package/assets/templates/monorepo/feature.json +1 -1
- package/assets/templates/monorepo/files/root/pnpm-workspace.yaml.eta +3 -2
- package/dist/commands/doctor.d.ts +5 -0
- package/dist/index.js +80 -21
- package/dist/output.d.ts +1 -1
- package/dist/server-client.d.ts +8 -0
- package/package.json +5 -5
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
# The shell. Every response says how long it may be cached: revalidate by default, a year only for
|
|
2
|
+
# files whose name changes when their content does (/static/). nginx drops the headers of the
|
|
3
|
+
# level above as soon as a location sets its own, so each location repeats Cache-Control.
|
|
4
|
+
|
|
5
|
+
# The stock mime.types has no .mjs. This block sits at http level, where it adds to the stock
|
|
6
|
+
# list; inside a server block a types block would replace the whole list.
|
|
7
|
+
types {
|
|
8
|
+
text/javascript mjs;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
# add_header is not inherited by a location that sets its own, so every location repeats the
|
|
12
|
+
# security headers beside Cache-Control.
|
|
13
|
+
gzip on;
|
|
14
|
+
gzip_vary on;
|
|
15
|
+
gzip_min_length 256;
|
|
16
|
+
gzip_types text/css text/javascript application/javascript application/json image/svg+xml;
|
|
17
|
+
# This image has no brotli module. Let a CDN or ingress do brotli if you want it.
|
|
18
|
+
|
|
19
|
+
server {
|
|
20
|
+
listen 8080;
|
|
21
|
+
server_name _;
|
|
22
|
+
server_tokens off;
|
|
23
|
+
root /usr/share/nginx/html;
|
|
24
|
+
|
|
25
|
+
location = /healthz {
|
|
26
|
+
access_log off;
|
|
27
|
+
default_type text/plain;
|
|
28
|
+
return 200 "ok\n";
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
# Dotfiles (.env, .git) are never served. .well-known stays reachable.
|
|
32
|
+
location ~ /\.(?!well-known) { return 404; }
|
|
33
|
+
|
|
34
|
+
# Written by the start script (or mounted as a ConfigMap) so the image holds no environment.
|
|
35
|
+
location = /config/runtime-config.json {
|
|
36
|
+
alias /tmp/mfe-runtime/runtime-config.json;
|
|
37
|
+
default_type application/json;
|
|
38
|
+
add_header Cache-Control "no-cache" always;
|
|
39
|
+
add_header X-Content-Type-Options "nosniff" always;
|
|
40
|
+
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
|
|
41
|
+
add_header X-Frame-Options "SAMEORIGIN" always;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
# Mounted, never baked in: a ConfigMap in Kubernetes, a file in Docker, or leave it out and point
|
|
45
|
+
# registryUrls in the runtime config at a registry you host elsewhere.
|
|
46
|
+
location = /registry/index.json {
|
|
47
|
+
alias /tmp/mfe-registry/index.json;
|
|
48
|
+
default_type application/json;
|
|
49
|
+
add_header Cache-Control "no-cache" always;
|
|
50
|
+
add_header X-Content-Type-Options "nosniff" always;
|
|
51
|
+
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
|
|
52
|
+
add_header X-Frame-Options "SAMEORIGIN" always;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
location ^~ /config/ { return 404; }
|
|
56
|
+
location ^~ /registry/ { return 404; }
|
|
57
|
+
|
|
58
|
+
# Hashed build output.
|
|
59
|
+
location ^~ /static/ {
|
|
60
|
+
try_files $uri =404;
|
|
61
|
+
add_header Cache-Control "public, max-age=31536000, immutable";
|
|
62
|
+
add_header X-Content-Type-Options "nosniff" always;
|
|
63
|
+
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
|
|
64
|
+
add_header X-Frame-Options "SAMEORIGIN" always;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
# Any other file (favicon, mf-manifest.json): a missing one is a real 404, never index.html.
|
|
68
|
+
location ~ \.[A-Za-z0-9]+$ {
|
|
69
|
+
try_files $uri =404;
|
|
70
|
+
add_header Cache-Control "no-cache" always;
|
|
71
|
+
add_header X-Content-Type-Options "nosniff" always;
|
|
72
|
+
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
|
|
73
|
+
add_header X-Frame-Options "SAMEORIGIN" always;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
# Routes. The fallback to index.html lives here and nowhere else.
|
|
77
|
+
location / {
|
|
78
|
+
try_files $uri /index.html;
|
|
79
|
+
add_header Cache-Control "no-cache" always;
|
|
80
|
+
add_header X-Content-Type-Options "nosniff" always;
|
|
81
|
+
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
|
|
82
|
+
add_header X-Frame-Options "SAMEORIGIN" always;
|
|
83
|
+
}
|
|
84
|
+
}
|
|
@@ -2,8 +2,9 @@ packages:
|
|
|
2
2
|
- apps/*
|
|
3
3
|
- packages/*
|
|
4
4
|
|
|
5
|
-
# Dependencies allowed to run install scripts. esbuild (pulled in by Storybook)
|
|
6
|
-
# script; listing
|
|
5
|
+
# Dependencies allowed to run install scripts. esbuild (pulled in by Storybook) and workerd (pulled in
|
|
6
|
+
# by wrangler) work without their script; listing them as false keeps pnpm from stopping the install to ask.
|
|
7
7
|
allowBuilds:
|
|
8
8
|
lefthook: true
|
|
9
9
|
esbuild: false
|
|
10
|
+
workerd: false
|
|
@@ -43,6 +43,11 @@ export declare const DOCTOR_ARGS: {
|
|
|
43
43
|
readonly alias: 'h';
|
|
44
44
|
readonly description: 'Show this help';
|
|
45
45
|
};
|
|
46
|
+
readonly against: {
|
|
47
|
+
readonly type: 'string';
|
|
48
|
+
readonly description: 'Check against the shell a registry index or a deployed mf-manifest.json describes (file or https URL)';
|
|
49
|
+
readonly valueHint: 'url|file';
|
|
50
|
+
};
|
|
46
51
|
readonly fix: {
|
|
47
52
|
readonly type: 'boolean';
|
|
48
53
|
readonly description: 'Repair what is safe: missing workspace versions and registry entries';
|
package/dist/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { stripVTControlCharacters } from "node:util";
|
|
2
|
-
import { COST_MODEL, DOCS_URL, MFE_NAME, REGISTRY_NAMESPACE, ROUTE_OVERLAP, isLoopbackHttp, isRegistryProtocol, isSafeRelativePath, judgeCost, judgeRemoteInitial, primaryExpose, redactUrl, redactUrlsIn, registryIndexUrl, registryTemplateProblem, remoteDistFiles, round1, routesOverlap, validateMfeManifest, validateRegistryEntry, validateRegistryIndex } from "@mfeflow/contracts";
|
|
3
|
-
import { APP_FILE, LEGACY_APP_FILE, MfeflowError, PROJECT_FILE, PlanBuilder, TRUST_ENV, addTrusted, applyPlan, buildRegistry, checkIntegrity, configDirOf, detectFederation, dotenvKeys, fetchFeatureIndex, findDiverged, findProjectRoot, getHttps, hasErrno, inOrder, isMfeflowError, legacyAppFileNotice, loadFeature, loadProject, messageOf, parseFeature, parseTrustEnv, planAdoption, planUpgrade, readAppFile, readCappedText, readTrusted, realFs, recordPlan, removeTrusted, renderDiff, renderTemplate, resolveFeature, runtimeConfigFiles, saveProject, schemaKeys, serializeProject, summarize, symlinkedPrefix, trustedNamespaces, writeFileAtomic } from "@mfeflow/core";
|
|
2
|
+
import { COST_MODEL, DOCS_URL, ENV_KEY_NAME, MFE_NAME, REGISTRY_NAMESPACE, ROUTE_OVERLAP, isLoopbackHttp, isRegistryProtocol, isSafeRelativePath, judgeCost, judgeRemoteInitial, primaryExpose, redactUrl, redactUrlsIn, registryIndexUrl, registryTemplateProblem, remoteDistFiles, round1, routesOverlap, validateMfeManifest, validateRegistryEntry, validateRegistryIndex } from "@mfeflow/contracts";
|
|
3
|
+
import { APP_FILE, LEGACY_APP_FILE, MfeflowError, PROJECT_FILE, PlanBuilder, TRUST_ENV, addTrusted, applyPlan, buildRegistry, checkIntegrity, configDirOf, detectFederation, dotenvKeys, fetchFeatureIndex, findDiverged, findProjectRoot, getHttps, hasErrno, inOrder, isMfeflowError, legacyAppFileNotice, loadFeature, loadProject, messageOf, parseFeature, parseTrustEnv, planAdoption, planUpgrade, readAppFile, readCappedText, readTrusted, realFs, recordEnvKey, recordPlan, removeTrusted, renderDiff, renderTemplate, resolveFeature, runtimeConfigFiles, saveProject, schemaKeys, serializeProject, summarize, symlinkedPrefix, trustedNamespaces, writeFileAtomic } from "@mfeflow/core";
|
|
4
4
|
import { defineCommand, runCommand } from "citty";
|
|
5
5
|
import node_path from "node:path";
|
|
6
6
|
import promises from "node:fs/promises";
|
|
@@ -242,6 +242,16 @@ const FIRST_PARTY = [
|
|
|
242
242
|
name: 'registry-server',
|
|
243
243
|
always: false,
|
|
244
244
|
default: false
|
|
245
|
+
},
|
|
246
|
+
{
|
|
247
|
+
name: 'deploy-cloudflare',
|
|
248
|
+
always: false,
|
|
249
|
+
default: false
|
|
250
|
+
},
|
|
251
|
+
{
|
|
252
|
+
name: 'deploy-docker',
|
|
253
|
+
always: false,
|
|
254
|
+
default: false
|
|
245
255
|
}
|
|
246
256
|
];
|
|
247
257
|
function isFirstParty(name) {
|
|
@@ -1379,7 +1389,6 @@ async function writePlan(request) {
|
|
|
1379
1389
|
installed: installing
|
|
1380
1390
|
};
|
|
1381
1391
|
}
|
|
1382
|
-
const KEY = /^[A-Za-z_][A-Za-z0-9_]*$/;
|
|
1383
1392
|
const GROUPS = [
|
|
1384
1393
|
'root',
|
|
1385
1394
|
'shell',
|
|
@@ -1460,7 +1469,7 @@ function envKeyOp(input) {
|
|
|
1460
1469
|
async function addEnvKey(rt, globals, args, key) {
|
|
1461
1470
|
const scope = args_text(args, 'scope');
|
|
1462
1471
|
const schema = args_text(args, 'schema');
|
|
1463
|
-
if (void 0 === key || !
|
|
1472
|
+
if (void 0 === key || !ENV_KEY_NAME.test(key)) throw new MfeflowError('E107', 'add env-key needs a key like API_ORIGIN: mfeflow add env-key <KEY>');
|
|
1464
1473
|
if ('server' !== scope && 'runtime' !== scope) throw new MfeflowError('E107', '--scope must be server or runtime');
|
|
1465
1474
|
if (void 0 === schema) throw new MfeflowError('E107', '--schema is required, for example --schema "z.url()"');
|
|
1466
1475
|
const root = await findProjectRoot(globals.cwd);
|
|
@@ -1501,6 +1510,7 @@ async function addEnvKey(rt, globals, args, key) {
|
|
|
1501
1510
|
...builder.build(),
|
|
1502
1511
|
features: []
|
|
1503
1512
|
};
|
|
1513
|
+
const recorded = recordEnvKey(project, plan.changes.map((change)=>change.path), key);
|
|
1504
1514
|
const outcome = await writePlan({
|
|
1505
1515
|
rt,
|
|
1506
1516
|
globals: {
|
|
@@ -1509,7 +1519,7 @@ async function addEnvKey(rt, globals, args, key) {
|
|
|
1509
1519
|
},
|
|
1510
1520
|
root,
|
|
1511
1521
|
plan,
|
|
1512
|
-
project
|
|
1522
|
+
project: recorded
|
|
1513
1523
|
});
|
|
1514
1524
|
const result = {
|
|
1515
1525
|
ok: true,
|
|
@@ -3457,7 +3467,7 @@ const singletonVersions = {
|
|
|
3457
3467
|
}
|
|
3458
3468
|
};
|
|
3459
3469
|
const ABSENT_SHELL_WARNING = 'shell is not in this repo, pass --against <url|file>';
|
|
3460
|
-
const ABSENT_UNDER_DOCTOR = 'shell is not in this repo, run `mfeflow
|
|
3470
|
+
const ABSENT_UNDER_DOCTOR = 'shell is not in this repo, run `mfeflow doctor --against <url|file>`';
|
|
3461
3471
|
async function versionsOf(app, names, root) {
|
|
3462
3472
|
const found = await Promise.all(names.map(async (name)=>[
|
|
3463
3473
|
name,
|
|
@@ -4069,22 +4079,26 @@ const DOCTOR_CHECKS = [
|
|
|
4069
4079
|
runtimePlugins,
|
|
4070
4080
|
...envChecks
|
|
4071
4081
|
];
|
|
4082
|
+
const AGAINST_ARG = {
|
|
4083
|
+
against: {
|
|
4084
|
+
type: 'string',
|
|
4085
|
+
description: 'Check against the shell a registry index or a deployed mf-manifest.json describes (file or https URL)',
|
|
4086
|
+
valueHint: 'url|file'
|
|
4087
|
+
}
|
|
4088
|
+
};
|
|
4072
4089
|
const DOCTOR_ARGS = {
|
|
4073
4090
|
fix: {
|
|
4074
4091
|
type: 'boolean',
|
|
4075
4092
|
description: 'Repair what is safe: missing workspace versions and registry entries'
|
|
4076
4093
|
},
|
|
4094
|
+
...AGAINST_ARG,
|
|
4077
4095
|
...GLOBAL_ARGS
|
|
4078
4096
|
};
|
|
4079
4097
|
const VALIDATE_ARGS = {
|
|
4080
4098
|
...GLOBAL_ARGS
|
|
4081
4099
|
};
|
|
4082
4100
|
const COMPAT_ARGS = {
|
|
4083
|
-
|
|
4084
|
-
type: 'string',
|
|
4085
|
-
description: 'Check against the shell a registry index or a deployed mf-manifest.json describes (file or https URL)',
|
|
4086
|
-
valueHint: 'url|file'
|
|
4087
|
-
},
|
|
4101
|
+
...AGAINST_ARG,
|
|
4088
4102
|
...GLOBAL_ARGS
|
|
4089
4103
|
};
|
|
4090
4104
|
const DEFAULT_VERSION = '0.0.0';
|
|
@@ -4199,7 +4213,17 @@ async function runGroup(rt, args, raw, defs, command, checks, fix) {
|
|
|
4199
4213
|
};
|
|
4200
4214
|
}
|
|
4201
4215
|
function runDoctor(rt, args, raw) {
|
|
4202
|
-
|
|
4216
|
+
const against = 'string' == typeof args.against ? args.against : void 0;
|
|
4217
|
+
return runGroup(rt, args, raw, DOCTOR_ARGS, 'doctor', void 0 === against ? DOCTOR_CHECKS : async (globals)=>{
|
|
4218
|
+
const shell = await loadShell(against, {
|
|
4219
|
+
cwd: globals.cwd,
|
|
4220
|
+
fetch: rt.fetch
|
|
4221
|
+
});
|
|
4222
|
+
return DOCTOR_CHECKS.map((check)=>check.id === compat.id ? compatCheck(shell, 'doctor') : check);
|
|
4223
|
+
}, true === args.fix).then((result)=>void 0 === against ? result : {
|
|
4224
|
+
...result,
|
|
4225
|
+
against: redactUrl(against)
|
|
4226
|
+
});
|
|
4203
4227
|
}
|
|
4204
4228
|
function runValidate(rt, args, raw) {
|
|
4205
4229
|
return runGroup(rt, args, raw, VALIDATE_ARGS, 'validate', VALIDATE_CHECKS, false);
|
|
@@ -4893,6 +4917,40 @@ class ServerClient {
|
|
|
4893
4917
|
scrubAll(value) {
|
|
4894
4918
|
return JSON.parse(this.scrub(JSON.stringify(value)));
|
|
4895
4919
|
}
|
|
4920
|
+
scrubError(error, seen = new WeakSet()) {
|
|
4921
|
+
if ('string' == typeof error) return this.scrub(error);
|
|
4922
|
+
if ('object' != typeof error || null === error) return error;
|
|
4923
|
+
if (seen.has(error)) return error;
|
|
4924
|
+
seen.add(error);
|
|
4925
|
+
if (!(error instanceof Error)) try {
|
|
4926
|
+
return this.scrubAll(error);
|
|
4927
|
+
} catch {
|
|
4928
|
+
return this.scrub(Object.prototype.toString.call(error));
|
|
4929
|
+
}
|
|
4930
|
+
error.message = this.scrub(error.message);
|
|
4931
|
+
if (void 0 !== error.stack) error.stack = this.scrub(error.stack);
|
|
4932
|
+
if (error instanceof MfeflowError) error.fix = this.scrub(error.fix);
|
|
4933
|
+
if (void 0 !== error.cause) error.cause = this.scrubError(error.cause, seen);
|
|
4934
|
+
if (error instanceof AggregateError) error.errors = error.errors.map((inner)=>this.scrubError(inner, seen));
|
|
4935
|
+
return error;
|
|
4936
|
+
}
|
|
4937
|
+
async guarded(rt, work) {
|
|
4938
|
+
const prompter = {
|
|
4939
|
+
...rt.prompter,
|
|
4940
|
+
confirm: (options)=>rt.prompter.confirm({
|
|
4941
|
+
...options,
|
|
4942
|
+
message: this.scrub(options.message)
|
|
4943
|
+
})
|
|
4944
|
+
};
|
|
4945
|
+
try {
|
|
4946
|
+
return this.scrubAll(await work({
|
|
4947
|
+
...rt,
|
|
4948
|
+
prompter
|
|
4949
|
+
}));
|
|
4950
|
+
} catch (error) {
|
|
4951
|
+
throw this.scrubError(error);
|
|
4952
|
+
}
|
|
4953
|
+
}
|
|
4896
4954
|
get hasToken() {
|
|
4897
4955
|
return void 0 !== this.token;
|
|
4898
4956
|
}
|
|
@@ -5651,24 +5709,24 @@ async function killInner(rt, args, raw, restore, client) {
|
|
|
5651
5709
|
}
|
|
5652
5710
|
const rate = (c)=>`${String(c.loads)} loads, ${String(c.errors)} errors`;
|
|
5653
5711
|
async function deployViaServer(rt, args, raw, defs, client) {
|
|
5654
|
-
return client.
|
|
5712
|
+
return client.guarded(rt, (guarded)=>deployInner(guarded, args, raw, defs, client));
|
|
5655
5713
|
}
|
|
5656
5714
|
async function promoteViaServer(rt, args, raw, defs, client) {
|
|
5657
|
-
return client.
|
|
5715
|
+
return client.guarded(rt, (guarded)=>promoteInner(guarded, args, raw, defs, client));
|
|
5658
5716
|
}
|
|
5659
5717
|
async function rollbackViaServer(rt, args, raw, defs, client) {
|
|
5660
|
-
return client.
|
|
5718
|
+
return client.guarded(rt, (guarded)=>rollbackInner(guarded, args, raw, defs, client));
|
|
5661
5719
|
}
|
|
5662
5720
|
async function statusViaServer(rt, args, raw, defs, client) {
|
|
5663
|
-
return client.
|
|
5721
|
+
return client.guarded(rt, (guarded)=>statusInner(guarded, args, raw, defs, client));
|
|
5664
5722
|
}
|
|
5665
5723
|
async function runRolloutCommand(rt, args, raw, client) {
|
|
5666
|
-
|
|
5667
|
-
return
|
|
5724
|
+
if (void 0 === client) return rolloutInner(rt, args, raw, client);
|
|
5725
|
+
return client.guarded(rt, (guarded)=>rolloutInner(guarded, args, raw, client));
|
|
5668
5726
|
}
|
|
5669
5727
|
async function runKillCommand(rt, args, raw, restore, client) {
|
|
5670
|
-
|
|
5671
|
-
return
|
|
5728
|
+
if (void 0 === client) return killInner(rt, args, raw, restore, client);
|
|
5729
|
+
return client.guarded(rt, (guarded)=>killInner(guarded, args, raw, restore, client));
|
|
5672
5730
|
}
|
|
5673
5731
|
function formatServerAction(result) {
|
|
5674
5732
|
if ('rollout' === result.command) {
|
|
@@ -8108,7 +8166,8 @@ const COMMANDS = [
|
|
|
8108
8166
|
'mfeflow doctor',
|
|
8109
8167
|
'mfeflow doctor --fix',
|
|
8110
8168
|
'mfeflow doctor --json',
|
|
8111
|
-
'mfeflow doctor --fix --dry-run'
|
|
8169
|
+
'mfeflow doctor --fix --dry-run',
|
|
8170
|
+
'mfeflow doctor --against https://cdn.example.com/envs/prod/index.json'
|
|
8112
8171
|
],
|
|
8113
8172
|
run: runDoctor
|
|
8114
8173
|
},
|
package/dist/output.d.ts
CHANGED
|
@@ -195,7 +195,7 @@ export interface ReportResult {
|
|
|
195
195
|
summary: Summary;
|
|
196
196
|
checks: CheckReport[];
|
|
197
197
|
findings: Finding[];
|
|
198
|
-
/** `check-compat --against`: where the shell's versions came from. */
|
|
198
|
+
/** `doctor` and `check-compat --against`: where the shell's versions came from. */
|
|
199
199
|
against?: string;
|
|
200
200
|
}
|
|
201
201
|
export interface ShellBudget {
|
package/dist/server-client.d.ts
CHANGED
|
@@ -43,6 +43,14 @@ export declare class ServerClient {
|
|
|
43
43
|
scrub(words: string): string;
|
|
44
44
|
/** A result document with every string scrubbed. The server's words reach the output through it. */
|
|
45
45
|
scrubAll<T>(value: T): T;
|
|
46
|
+
/**
|
|
47
|
+
* Whatever was thrown, with the token taken out for errors raised outside `run`: message, stack,
|
|
48
|
+
* `fix`, the `cause` chain and the errors of an AggregateError. Strings and plain objects are
|
|
49
|
+
* scrubbed too.
|
|
50
|
+
*/
|
|
51
|
+
scrubError(error: unknown, seen?: WeakSet<object>): unknown;
|
|
52
|
+
/** Runs a whole server-mode command: whatever it prints, prompts or throws is scrubbed. */
|
|
53
|
+
guarded<T>(rt: Runtime, work: (rt: Runtime) => Promise<T>): Promise<T>;
|
|
46
54
|
get hasToken(): boolean;
|
|
47
55
|
/** Throws the catalogue error for anything that is not a 2xx reply; `gates_failed` is thrown as a ServerError. */
|
|
48
56
|
get(route: string, needsToken?: boolean): Promise<unknown>;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "mfeflow",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.7.0",
|
|
4
4
|
"description": "Create and grow a React micro-frontend platform: mfeflow init, add remote, add <feature>.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"micro-frontend",
|
|
@@ -49,15 +49,15 @@
|
|
|
49
49
|
},
|
|
50
50
|
"dependencies": {
|
|
51
51
|
"@clack/prompts": "1.8.1",
|
|
52
|
-
"@mfeflow/contracts": "0.
|
|
53
|
-
"@mfeflow/core": "0.
|
|
54
|
-
"@mfeflow/registry": "0.
|
|
52
|
+
"@mfeflow/contracts": "0.7.0",
|
|
53
|
+
"@mfeflow/core": "0.7.0",
|
|
54
|
+
"@mfeflow/registry": "0.7.0",
|
|
55
55
|
"citty": "0.2.2",
|
|
56
56
|
"semver": "7.8.5",
|
|
57
57
|
"yaml": "2.9.1"
|
|
58
58
|
},
|
|
59
59
|
"devDependencies": {
|
|
60
|
-
"@mfeflow/rsbuild": "0.
|
|
60
|
+
"@mfeflow/rsbuild": "0.7.0",
|
|
61
61
|
"@rslib/core": "1.0.5",
|
|
62
62
|
"@types/node": "26.6.6",
|
|
63
63
|
"@types/semver": "7.8.0",
|