@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 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.6.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.6.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",