@mfeflow/core 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/dist/index.d.ts +1 -1
- package/dist/index.js +39 -3
- package/dist/upgrade.d.ts +7 -0
- package/package.json +2 -2
package/dist/index.d.ts
CHANGED
|
@@ -11,7 +11,7 @@ export { realFs, symlinkedPrefix, writeFileAtomic, type FsOps } from './fs.js';
|
|
|
11
11
|
export { findDiverged, findProjectRoot, loadProject, parseProject, PROJECT_FILE, recordPlan, saveProject, serializeProject, type DivergedFile, type MfeflowProject, } from './project.js';
|
|
12
12
|
export { emptyPlan, PlanBuilder, renderDiff, summarize, type ChangeAction, type DependencyAdd, type EnvKeyAdd, type FileChange, type Plan, type PlanBuilderOptions, type PlanFeature, type ReadFile, type ScriptAdd, } from './plan.js';
|
|
13
13
|
export { applyPlan, type ApplyOptions, type ApplyResult, type InstallContext, type InstallStep, } from './apply.js';
|
|
14
|
-
export { detectBaseline, planUpgrade, type DivergedUpgrade, type DivergeReason, type Migration, type UpgradeDecisions, type UpgradeInput, type UpgradePlan, } from './upgrade.js';
|
|
14
|
+
export { detectBaseline, isEnvKeyFile, planUpgrade, recordEnvKey, type DivergedUpgrade, type DivergeReason, type Migration, type UpgradeDecisions, type UpgradeInput, type UpgradePlan, } from './upgrade.js';
|
|
15
15
|
export { renderTemplate, substitute, type TemplateData } from './templates.js';
|
|
16
16
|
export { RUNTIME_CONFIG_FILE, runtimeConfigFiles } from './runtime-config.js';
|
|
17
17
|
export { applyTransform, dotenvKeys, schemaKeys, type SchemaKey } from './transforms/index.js';
|
package/dist/index.js
CHANGED
|
@@ -448,6 +448,10 @@ function serializeProject(project) {
|
|
|
448
448
|
const { $schema, ...rest } = project;
|
|
449
449
|
const files = rest.files && Object.fromEntries(Object.entries(rest.files).toSorted(byKey));
|
|
450
450
|
const kept = rest.kept && Object.fromEntries(Object.entries(rest.kept).toSorted(byKey));
|
|
451
|
+
const envKeys = rest.envKeys && Object.fromEntries(Object.entries(rest.envKeys).toSorted(byKey).map(([file, keys])=>[
|
|
452
|
+
file,
|
|
453
|
+
keys.toSorted((a, b)=>a < b ? -1 : a > b ? 1 : 0)
|
|
454
|
+
]));
|
|
451
455
|
const ordered = {
|
|
452
456
|
$schema: $schema ?? SCHEMA_URLS.project,
|
|
453
457
|
...rest,
|
|
@@ -456,6 +460,9 @@ function serializeProject(project) {
|
|
|
456
460
|
} : {},
|
|
457
461
|
...kept ? {
|
|
458
462
|
kept
|
|
463
|
+
} : {},
|
|
464
|
+
...envKeys ? {
|
|
465
|
+
envKeys
|
|
459
466
|
} : {}
|
|
460
467
|
};
|
|
461
468
|
return `${JSON.stringify(ordered, null, 2)}\n`;
|
|
@@ -2190,8 +2197,15 @@ async function resolveFeature(input) {
|
|
|
2190
2197
|
for (const needed of manifest.requires ?? [])if (!present.has(needed)) throw new MfeflowError('E206', `${manifest.name} needs ${needed}`);
|
|
2191
2198
|
const options = resolveOptions(manifest, input.options);
|
|
2192
2199
|
if ('tailwind' === manifest.name) assertUniqueTailwindPrefixes(Object.keys(project.apps));
|
|
2200
|
+
const apps = Object.entries(project.apps).map(([name, app])=>({
|
|
2201
|
+
name,
|
|
2202
|
+
kind: app.kind,
|
|
2203
|
+
path: app.path,
|
|
2204
|
+
port: app.port
|
|
2205
|
+
}));
|
|
2193
2206
|
const dataFor = (place)=>({
|
|
2194
2207
|
scope: project.scope,
|
|
2208
|
+
apps,
|
|
2195
2209
|
topology: project.topology,
|
|
2196
2210
|
packageManager: project.packageManager,
|
|
2197
2211
|
options,
|
|
@@ -2290,6 +2304,24 @@ const OWN_CLI = 'mfeflow';
|
|
|
2290
2304
|
const PLACEHOLDER_RANGE = 'latest';
|
|
2291
2305
|
const USER_DATA = /^registry\/envs\//;
|
|
2292
2306
|
const ENV_KEY_FILES = /(^|\/)(env\.ts|src\/config\/schema\.ts|runtime-config(\.[^/]+)?\.json|\.env[^/]*)$/;
|
|
2307
|
+
const isEnvKeyFile = (file)=>ENV_KEY_FILES.test(file);
|
|
2308
|
+
function recordEnvKey(project, files, key) {
|
|
2309
|
+
const touched = files.filter(isEnvKeyFile);
|
|
2310
|
+
if (0 === touched.length) return project;
|
|
2311
|
+
const envKeys = {
|
|
2312
|
+
...project.envKeys
|
|
2313
|
+
};
|
|
2314
|
+
for (const file of touched)envKeys[file] = [
|
|
2315
|
+
...new Set([
|
|
2316
|
+
...envKeys[file] ?? [],
|
|
2317
|
+
key
|
|
2318
|
+
])
|
|
2319
|
+
].toSorted(byCodePoint);
|
|
2320
|
+
return {
|
|
2321
|
+
...project,
|
|
2322
|
+
envKeys
|
|
2323
|
+
};
|
|
2324
|
+
}
|
|
2293
2325
|
const KEEP_RANGE = /^(workspace|link|file|portal):/;
|
|
2294
2326
|
const byCodePoint = (a, b)=>a < b ? -1 : a > b ? 1 : 0;
|
|
2295
2327
|
const isOwn = (name)=>name === OWN_CLI || name.startsWith(OWN_PREFIX);
|
|
@@ -2481,7 +2513,7 @@ function lostKeys(file, disk, incoming) {
|
|
|
2481
2513
|
}
|
|
2482
2514
|
const writes = (verdict)=>'create' === verdict || 'replace' === verdict || 'missing' !== verdict && 'matching' !== verdict && 'leave' !== verdict && 'symlink' !== verdict;
|
|
2483
2515
|
function judge(file, disk, incoming, state) {
|
|
2484
|
-
const { recorded, kept, anySkipped } = state;
|
|
2516
|
+
const { recorded, kept, anySkipped, envKeys = [] } = state;
|
|
2485
2517
|
if (void 0 === disk) {
|
|
2486
2518
|
if (void 0 !== recorded) return 'missing';
|
|
2487
2519
|
return USER_DATA.test(file) ? 'leave' : 'create';
|
|
@@ -2495,6 +2527,7 @@ function judge(file, disk, incoming, state) {
|
|
|
2495
2527
|
if (ENV_KEY_FILES.test(file)) {
|
|
2496
2528
|
const lost = lostKeys(file, disk, incoming);
|
|
2497
2529
|
if (void 0 === lost || lost.missing.length > 0) return 'edited-by-cli';
|
|
2530
|
+
if (lost.changed.some((key)=>envKeys.includes(key))) return 'edited-by-cli';
|
|
2498
2531
|
}
|
|
2499
2532
|
return anySkipped ? 'skipped-feature' : 'replace';
|
|
2500
2533
|
}
|
|
@@ -2519,7 +2552,10 @@ async function compareFiles(project, fresh, read, builder, options) {
|
|
|
2519
2552
|
...project.kept?.[file] === void 0 ? {} : {
|
|
2520
2553
|
kept: project.kept[file]
|
|
2521
2554
|
},
|
|
2522
|
-
anySkipped: options.anySkipped
|
|
2555
|
+
anySkipped: options.anySkipped,
|
|
2556
|
+
...project.envKeys?.[file] === void 0 ? {} : {
|
|
2557
|
+
envKeys: project.envKeys[file]
|
|
2558
|
+
}
|
|
2523
2559
|
});
|
|
2524
2560
|
if (writes(verdict) && await options.isSymlink?.(file)) verdict = 'symlink';
|
|
2525
2561
|
if ('missing' === verdict) out.missing.push(file);
|
|
@@ -4494,4 +4530,4 @@ function packageInfo() {
|
|
|
4494
4530
|
version
|
|
4495
4531
|
};
|
|
4496
4532
|
}
|
|
4497
|
-
export { APP_FILE, ERROR_CATALOGUE, LEGACY_APP_FILE, MfeflowError, PROJECT_FILE, PlanBuilder, RUNTIME_CONFIG_FILE, TRUST_ENV, addTrusted, applyPlan, applyTransform, buildRegistry, checkIntegrity, configDirOf, detectBaseline, detectFederation, dotenvKeys, emptyPlan, fetchFeatureIndex, fetchRemoteText, findDiverged, findProjectRoot, getHttps, hasErrno, hashContent, inOrder, indexedVersion, integrityOf, isMfeflowError, isProtectedPath, legacyAppFileNotice, listLocalFeatures, loadFeature, loadProject, messageOf, packageInfo, parseFeature, parseProject, parseTrustEnv, planAdoption, planUpgrade, readAppFile, readCappedText, readTrusted, realFs, recordPlan, registryUrl, removeTrusted, renderDiff, renderTemplate, resolveFeature, resolveOptions, runtimeConfigFiles, saveProject, schemaKeys, serializeProject, substitute, summarize, symlinkedPrefix, trustFileIn, trustedNamespaces, writeFileAtomic };
|
|
4533
|
+
export { APP_FILE, ERROR_CATALOGUE, LEGACY_APP_FILE, MfeflowError, PROJECT_FILE, PlanBuilder, RUNTIME_CONFIG_FILE, TRUST_ENV, addTrusted, applyPlan, applyTransform, buildRegistry, checkIntegrity, configDirOf, detectBaseline, detectFederation, dotenvKeys, emptyPlan, fetchFeatureIndex, fetchRemoteText, findDiverged, findProjectRoot, getHttps, hasErrno, hashContent, inOrder, indexedVersion, integrityOf, isEnvKeyFile, isMfeflowError, isProtectedPath, legacyAppFileNotice, listLocalFeatures, loadFeature, loadProject, messageOf, packageInfo, parseFeature, parseProject, parseTrustEnv, planAdoption, planUpgrade, readAppFile, readCappedText, readTrusted, realFs, recordEnvKey, recordPlan, registryUrl, removeTrusted, renderDiff, renderTemplate, resolveFeature, resolveOptions, runtimeConfigFiles, saveProject, schemaKeys, serializeProject, substitute, summarize, symlinkedPrefix, trustFileIn, trustedNamespaces, writeFileAtomic };
|
package/dist/upgrade.d.ts
CHANGED
|
@@ -87,6 +87,13 @@ export interface UpgradePlan {
|
|
|
87
87
|
/** Files the old version generated that you deleted. They are not brought back. */
|
|
88
88
|
missing: string[];
|
|
89
89
|
}
|
|
90
|
+
/** Whether `mfeflow add env-key` may have edited this file. */
|
|
91
|
+
export declare const isEnvKeyFile: (file: string) => boolean;
|
|
92
|
+
/**
|
|
93
|
+
* `project` with `key` recorded under each of `files` that `add env-key` edits, so `upgrade` can
|
|
94
|
+
* ask before a new template changes its value. Files that are not env files are ignored.
|
|
95
|
+
*/
|
|
96
|
+
export declare function recordEnvKey(project: MfeflowProject, files: readonly string[], key: string): MfeflowProject;
|
|
90
97
|
/**
|
|
91
98
|
* The version of the CLI that made the project: `cli` in `mfeflow.json`, else the lowest version
|
|
92
99
|
* the shell's `@mfeflow/runtime` range allows (0.1 projects have no `cli`). A `workspace:`,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mfeflow/core",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.7.0",
|
|
4
4
|
"description": "The engine behind the mfeflow CLI: project model, change plans with diffs, atomic apply with rollback, and feature resolution.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"micro-frontend",
|
|
@@ -45,7 +45,7 @@
|
|
|
45
45
|
"dependencies": {
|
|
46
46
|
"@babel/parser": "8.0.10",
|
|
47
47
|
"@babel/types": "8.0.10",
|
|
48
|
-
"@mfeflow/contracts": "0.
|
|
48
|
+
"@mfeflow/contracts": "0.7.0",
|
|
49
49
|
"diff": "9.0.0",
|
|
50
50
|
"eta": "4.6.0",
|
|
51
51
|
"semver": "7.8.5",
|