@metaobjectsdev/codegen-ts 0.23.2 → 0.24.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/generator.d.ts +9 -0
- package/dist/generator.d.ts.map +1 -1
- package/dist/generator.js.map +1 -1
- package/dist/generators/api-field-shape.js +1 -1
- package/dist/generators/api-field-shape.js.map +1 -1
- package/dist/generators/api-model.d.ts.map +1 -1
- package/dist/generators/api-model.js +71 -42
- package/dist/generators/api-model.js.map +1 -1
- package/dist/generators/docs-data-builder.d.ts.map +1 -1
- package/dist/generators/docs-data-builder.js +36 -1
- package/dist/generators/docs-data-builder.js.map +1 -1
- package/dist/generators/docs-data.d.ts +14 -0
- package/dist/generators/docs-data.d.ts.map +1 -1
- package/dist/generators/docs-file.d.ts.map +1 -1
- package/dist/generators/docs-file.js +13 -4
- package/dist/generators/docs-file.js.map +1 -1
- package/dist/generators/extractor-file.d.ts.map +1 -1
- package/dist/generators/extractor-file.js +7 -11
- package/dist/generators/extractor-file.js.map +1 -1
- package/dist/generators/index.d.ts +4 -0
- package/dist/generators/index.d.ts.map +1 -1
- package/dist/generators/index.js +5 -0
- package/dist/generators/index.js.map +1 -1
- package/dist/generators/output-parser-file.d.ts.map +1 -1
- package/dist/generators/output-parser-file.js +12 -7
- package/dist/generators/output-parser-file.js.map +1 -1
- package/dist/generators/output-prompt-file.d.ts.map +1 -1
- package/dist/generators/output-prompt-file.js +14 -24
- package/dist/generators/output-prompt-file.js.map +1 -1
- package/dist/generators/requirement-tests.d.ts +44 -0
- package/dist/generators/requirement-tests.d.ts.map +1 -0
- package/dist/generators/requirement-tests.js +127 -0
- package/dist/generators/requirement-tests.js.map +1 -0
- package/dist/generators/requirements-file.d.ts +9 -0
- package/dist/generators/requirements-file.d.ts.map +1 -0
- package/dist/generators/requirements-file.js +53 -0
- package/dist/generators/requirements-file.js.map +1 -0
- package/dist/generators/requirements-markdown.d.ts +10 -0
- package/dist/generators/requirements-markdown.d.ts.map +1 -0
- package/dist/generators/requirements-markdown.js +71 -0
- package/dist/generators/requirements-markdown.js.map +1 -0
- package/dist/generators/requirements-toon.d.ts +3 -0
- package/dist/generators/requirements-toon.d.ts.map +1 -0
- package/dist/generators/requirements-toon.js +47 -0
- package/dist/generators/requirements-toon.js.map +1 -0
- package/dist/generators/requirements-view.d.ts +32 -0
- package/dist/generators/requirements-view.d.ts.map +1 -0
- package/dist/generators/requirements-view.js +64 -0
- package/dist/generators/requirements-view.js.map +1 -0
- package/dist/generators/trace-helper-file.d.ts.map +1 -1
- package/dist/generators/trace-helper-file.js +19 -11
- package/dist/generators/trace-helper-file.js.map +1 -1
- package/dist/index.d.ts +13 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +18 -0
- package/dist/index.js.map +1 -1
- package/dist/metaobjects-config.d.ts +12 -20
- package/dist/metaobjects-config.d.ts.map +1 -1
- package/dist/metaobjects-config.js +5 -1
- package/dist/metaobjects-config.js.map +1 -1
- package/dist/orphan-sweep.d.ts +38 -0
- package/dist/orphan-sweep.d.ts.map +1 -0
- package/dist/orphan-sweep.js +129 -0
- package/dist/orphan-sweep.js.map +1 -0
- package/dist/overwrite-policy.d.ts +97 -3
- package/dist/overwrite-policy.d.ts.map +1 -1
- package/dist/overwrite-policy.js +293 -81
- package/dist/overwrite-policy.js.map +1 -1
- package/dist/projection/build-projection-views.d.ts +8 -0
- package/dist/projection/build-projection-views.d.ts.map +1 -1
- package/dist/projection/build-projection-views.js +2 -0
- package/dist/projection/build-projection-views.js.map +1 -1
- package/dist/reconcile-orphans.d.ts +80 -0
- package/dist/reconcile-orphans.d.ts.map +1 -0
- package/dist/reconcile-orphans.js +61 -0
- package/dist/reconcile-orphans.js.map +1 -0
- package/dist/render-engine/embedded-templates.generated.js +1 -1
- package/dist/render-engine/embedded-templates.generated.js.map +1 -1
- package/dist/requirement-walk.d.ts +57 -0
- package/dist/requirement-walk.d.ts.map +1 -0
- package/dist/requirement-walk.js +94 -0
- package/dist/requirement-walk.js.map +1 -0
- package/dist/runner.d.ts +35 -0
- package/dist/runner.d.ts.map +1 -1
- package/dist/runner.js +217 -21
- package/dist/runner.js.map +1 -1
- package/dist/templates/extractor.d.ts +4 -4
- package/dist/templates/extractor.d.ts.map +1 -1
- package/dist/templates/extractor.js +18 -22
- package/dist/templates/extractor.js.map +1 -1
- package/dist/templates/find-inbound.d.ts +44 -0
- package/dist/templates/find-inbound.d.ts.map +1 -0
- package/dist/templates/find-inbound.js +69 -0
- package/dist/templates/find-inbound.js.map +1 -0
- package/dist/templates/output-format-spec-emitter.d.ts.map +1 -1
- package/dist/templates/output-format-spec-emitter.js +7 -4
- package/dist/templates/output-format-spec-emitter.js.map +1 -1
- package/dist/templates/output-parser.d.ts +8 -3
- package/dist/templates/output-parser.d.ts.map +1 -1
- package/dist/templates/output-parser.js +71 -31
- package/dist/templates/output-parser.js.map +1 -1
- package/dist/templates/output-prompt.d.ts +6 -5
- package/dist/templates/output-prompt.d.ts.map +1 -1
- package/dist/templates/output-prompt.js +26 -37
- package/dist/templates/output-prompt.js.map +1 -1
- package/dist/templates/queries.js +1 -1
- package/dist/templates/queries.js.map +1 -1
- package/dist/templates/requirement-test.d.ts +12 -0
- package/dist/templates/requirement-test.d.ts.map +1 -0
- package/dist/templates/requirement-test.js +120 -0
- package/dist/templates/requirement-test.js.map +1 -0
- package/dist/templates/zod-validators.d.ts.map +1 -1
- package/dist/templates/zod-validators.js +32 -15
- package/dist/templates/zod-validators.js.map +1 -1
- package/package.json +7 -6
- package/src/generator.ts +9 -0
- package/src/generators/api-field-shape.ts +1 -1
- package/src/generators/api-model.ts +69 -44
- package/src/generators/docs-data-builder.ts +37 -0
- package/src/generators/docs-data.ts +15 -0
- package/src/generators/docs-file.ts +13 -4
- package/src/generators/extractor-file.ts +7 -11
- package/src/generators/index.ts +11 -0
- package/src/generators/output-parser-file.ts +12 -7
- package/src/generators/output-prompt-file.ts +14 -27
- package/src/generators/requirement-tests.ts +203 -0
- package/src/generators/requirements-file.ts +71 -0
- package/src/generators/requirements-markdown.ts +72 -0
- package/src/generators/requirements-toon.ts +64 -0
- package/src/generators/requirements-view.ts +93 -0
- package/src/generators/trace-helper-file.ts +20 -10
- package/src/index.ts +47 -1
- package/src/metaobjects-config.ts +17 -22
- package/src/orphan-sweep.ts +178 -0
- package/src/overwrite-policy.ts +362 -89
- package/src/projection/build-projection-views.ts +10 -0
- package/src/reconcile-orphans.ts +136 -0
- package/src/reference/barrel.ts +4 -0
- package/src/reference/entity.ts +4 -0
- package/src/reference/queries.ts +4 -0
- package/src/reference/routes.ts +4 -0
- package/src/render-engine/embedded-templates.generated.ts +1 -1
- package/src/requirement-walk.ts +124 -0
- package/src/runner.ts +266 -27
- package/src/templates/extractor.ts +19 -24
- package/src/templates/find-inbound.ts +96 -0
- package/src/templates/output-format-spec-emitter.ts +7 -4
- package/src/templates/output-parser.ts +76 -34
- package/src/templates/output-prompt.ts +29 -42
- package/src/templates/queries.ts +1 -1
- package/src/templates/requirement-test.ts +140 -0
- package/src/templates/zod-validators.ts +32 -15
- package/templates/docs/entity-page.md.mustache +8 -0
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
// FR-038 §8 — bind the orphan decision to the filesystem.
|
|
2
|
+
//
|
|
3
|
+
// reconcile-orphans.ts is deliberately pure: it answers "remove, refuse, or
|
|
4
|
+
// already gone?" from readers the caller supplies. This module supplies those
|
|
5
|
+
// readers, applies the answer, and keeps `.gen-state` honest afterwards. Keeping
|
|
6
|
+
// the two apart is what lets the RULE be tested without a filesystem and the
|
|
7
|
+
// PLUMBING be tested against real files, rather than only through a full runGen.
|
|
8
|
+
//
|
|
9
|
+
// Three properties this file is responsible for, none of which the pure decision
|
|
10
|
+
// can enforce on its own:
|
|
11
|
+
//
|
|
12
|
+
// 1. NAMESPACE SCOPE. A generator's `owns` predicate speaks in paths relative
|
|
13
|
+
// to its own output directory; gen-state speaks in project-relative paths.
|
|
14
|
+
// Translating between them is where a boundary is won or lost, so a path
|
|
15
|
+
// that resolves outside the generator's directory is never even offered to
|
|
16
|
+
// the predicate.
|
|
17
|
+
// 2. RECORD HYGIENE. A removed or already-gone path must be forgotten, or the
|
|
18
|
+
// next run re-decides a settled orphan forever. A REFUSED path must be
|
|
19
|
+
// kept, or a refusal degrades into permanent silence on the run after.
|
|
20
|
+
// 3. DRY-RUN HONESTY. `--dry-run` must report a pending deletion and perform
|
|
21
|
+
// none, because a preview that hides a deletion is worse than no preview.
|
|
22
|
+
import { existsSync, readFileSync, rmSync } from "node:fs";
|
|
23
|
+
import { isAbsolute, relative, resolve, sep } from "node:path";
|
|
24
|
+
import { listGeneratedPaths, isPristineGenerated, forgetGeneratedPaths, } from "./overwrite-policy.js";
|
|
25
|
+
import { reconcileOrphans } from "./reconcile-orphans.js";
|
|
26
|
+
/** gen-state keys carry the platform separator; an `owns` predicate is written
|
|
27
|
+
* against generated output, which is always `/`-separated. Normalize once so a
|
|
28
|
+
* predicate authored the obvious way is not silently wrong off Linux. */
|
|
29
|
+
function toPosix(p) {
|
|
30
|
+
return sep === "/" ? p : p.split(sep).join("/");
|
|
31
|
+
}
|
|
32
|
+
export function sweepOrphans(args) {
|
|
33
|
+
if (args.jobs.length === 0) {
|
|
34
|
+
return { removed: [], refused: [], forced: [], refusedBy: new Map() };
|
|
35
|
+
}
|
|
36
|
+
const previouslyGenerated = listGeneratedPaths(args.genStateDir);
|
|
37
|
+
if (previouslyGenerated.length === 0) {
|
|
38
|
+
return { removed: [], refused: [], forced: [], refusedBy: new Map() };
|
|
39
|
+
}
|
|
40
|
+
// NOT normalized: both sides of this comparison are produced by
|
|
41
|
+
// `relative(projectRoot, …)` — gen-state's keys and the runner's emitted paths
|
|
42
|
+
// alike — so they already share whatever separator the platform uses.
|
|
43
|
+
// Normalizing one side is what would break them apart. `toPosix` is used only
|
|
44
|
+
// where a HUMAN-authored string is involved (the `owns` predicate below).
|
|
45
|
+
const emitted = args.emittedRelPaths;
|
|
46
|
+
// A path can fall inside two jobs' namespaces (an app may register several
|
|
47
|
+
// requirementTests() instances). Sets keep the second visit from re-reporting
|
|
48
|
+
// a file the first already dealt with.
|
|
49
|
+
const removed = new Set();
|
|
50
|
+
const refused = new Set();
|
|
51
|
+
const forced = new Set();
|
|
52
|
+
const forget = new Set();
|
|
53
|
+
const refusedBy = new Map();
|
|
54
|
+
for (const job of args.jobs) {
|
|
55
|
+
const decision = reconcileOrphans({
|
|
56
|
+
previouslyGenerated,
|
|
57
|
+
emitted,
|
|
58
|
+
owns: (relPath) => {
|
|
59
|
+
const inTarget = relative(job.writeOutDir, resolve(args.projectRoot, relPath));
|
|
60
|
+
// "" is the directory itself; a `..` prefix or an absolute result means
|
|
61
|
+
// the path is outside this generator's output entirely. Neither is
|
|
62
|
+
// something the predicate should get a say in.
|
|
63
|
+
if (inTarget === "" || inTarget.startsWith("..") || isAbsolute(inTarget)) {
|
|
64
|
+
return false;
|
|
65
|
+
}
|
|
66
|
+
return job.policy.owns(toPosix(inTarget));
|
|
67
|
+
},
|
|
68
|
+
exists: (relPath) => existsSync(resolve(args.projectRoot, relPath)),
|
|
69
|
+
// The committed hash manifest, NOT the snapshot body — the bodies are
|
|
70
|
+
// gitignored, so on a fresh clone a body-based check could never prove a
|
|
71
|
+
// file untouched and orphan cleanup would refuse everything forever.
|
|
72
|
+
isUntouched: (relPath) => {
|
|
73
|
+
const full = resolve(args.projectRoot, relPath);
|
|
74
|
+
if (!existsSync(full))
|
|
75
|
+
return false;
|
|
76
|
+
return isPristineGenerated(args.genStateDir, relPath, readFileSync(full, "utf-8"));
|
|
77
|
+
},
|
|
78
|
+
});
|
|
79
|
+
for (const relPath of decision.remove) {
|
|
80
|
+
if (refused.has(relPath) || forced.has(relPath))
|
|
81
|
+
continue;
|
|
82
|
+
removed.add(relPath);
|
|
83
|
+
forget.add(relPath);
|
|
84
|
+
}
|
|
85
|
+
for (const relPath of decision.refused) {
|
|
86
|
+
// `refused` belongs in this guard too. Without it, a path already refused by a
|
|
87
|
+
// non-forcing job could be picked up by a later FORCING job whose namespace
|
|
88
|
+
// overlaps (the file anticipates several requirementTests() instances), landing
|
|
89
|
+
// in `refused` and `forced` at once — deleted from disk, while
|
|
90
|
+
// `refusedOrphanMessage` tells the user it "was NOT deleted".
|
|
91
|
+
//
|
|
92
|
+
// First decision wins: a refusal is the conservative answer, and letting a
|
|
93
|
+
// later job escalate it to a deletion would make the outcome depend on job
|
|
94
|
+
// ORDER, which is exactly the ambiguity the runner's duplicate-path guard
|
|
95
|
+
// exists to reject elsewhere.
|
|
96
|
+
if (removed.has(relPath) || forced.has(relPath) || refused.has(relPath))
|
|
97
|
+
continue;
|
|
98
|
+
if (job.policy.force === true) {
|
|
99
|
+
forced.add(relPath);
|
|
100
|
+
forget.add(relPath);
|
|
101
|
+
}
|
|
102
|
+
else {
|
|
103
|
+
// Deliberately NOT forgotten: the record is what makes the refusal
|
|
104
|
+
// repeat until someone resolves it.
|
|
105
|
+
refused.add(relPath);
|
|
106
|
+
refusedBy.set(relPath, job.generatorName);
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
// Nothing on disk to report — the file is already gone. Clear the stale
|
|
110
|
+
// record so this stops being reconsidered on every future run.
|
|
111
|
+
for (const relPath of decision.vanished)
|
|
112
|
+
forget.add(relPath);
|
|
113
|
+
}
|
|
114
|
+
if (!args.dryRun) {
|
|
115
|
+
for (const relPath of [...removed, ...forced]) {
|
|
116
|
+
rmSync(resolve(args.projectRoot, relPath), { force: true });
|
|
117
|
+
}
|
|
118
|
+
// Batched: the per-path form rewrites the whole manifest each call, so clearing
|
|
119
|
+
// k orphans rewrote it k times for an identical result.
|
|
120
|
+
forgetGeneratedPaths(args.genStateDir, forget);
|
|
121
|
+
}
|
|
122
|
+
return {
|
|
123
|
+
removed: [...removed].sort(),
|
|
124
|
+
refused: [...refused].sort(),
|
|
125
|
+
forced: [...forced].sort(),
|
|
126
|
+
refusedBy,
|
|
127
|
+
};
|
|
128
|
+
}
|
|
129
|
+
//# sourceMappingURL=orphan-sweep.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"orphan-sweep.js","sourceRoot":"","sources":["../src/orphan-sweep.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,4 +1,10 @@
|
|
|
1
|
-
export type WriteStatus = "new" | "unchanged" | "overwrite" | "merged" | "conflict" | "refused" | "skipped"
|
|
1
|
+
export type WriteStatus = "new" | "unchanged" | "overwrite" | "merged" | "conflict" | "refused" | "skipped"
|
|
2
|
+
/** FR-038 §8 — deleted because it was generated by a previous run, is no longer
|
|
3
|
+
* generated, and was never edited by hand. Reported as a file outcome rather
|
|
4
|
+
* than a warning because a deletion is exactly as consequential as a write,
|
|
5
|
+
* and a run summary that lists writes but hides deletions is how a silent
|
|
6
|
+
* deletion happens. */
|
|
7
|
+
| "removed";
|
|
2
8
|
/**
|
|
3
9
|
* "overwrite" — default; three-way merge if .gen-state exists, else write-if-
|
|
4
10
|
* different / first-time-existing flow.
|
|
@@ -27,10 +33,74 @@ export interface DecideAndWriteOpts {
|
|
|
27
33
|
export interface WriteResult {
|
|
28
34
|
path: string;
|
|
29
35
|
status: WriteStatus;
|
|
30
|
-
/** Present when status is "conflict" — human-readable
|
|
31
|
-
*
|
|
36
|
+
/** Present when status is "conflict" or "refused" — human-readable reason,
|
|
37
|
+
* naming what the user must do. A refusal nobody can act on gets the file
|
|
38
|
+
* deleted by hand, which is the outcome refusing exists to prevent. */
|
|
32
39
|
conflictHint?: string;
|
|
33
40
|
}
|
|
41
|
+
/**
|
|
42
|
+
* Every snapshot key recorded under `genStateDir` — in a runner-driven project,
|
|
43
|
+
* the project-relative path of every file some previous `meta gen` wrote.
|
|
44
|
+
*
|
|
45
|
+
* Empty for a gen-state directory that does not exist yet, which is what makes a
|
|
46
|
+
* first run, an ephemeral test run and `verify --codegen`'s throwaway root all
|
|
47
|
+
* reconcile nothing.
|
|
48
|
+
*/
|
|
49
|
+
export declare function listGeneratedPaths(genStateDir: string): string[];
|
|
50
|
+
/**
|
|
51
|
+
* sha-256 of `content`, hex — the same function that produces `.hashes.json`.
|
|
52
|
+
*
|
|
53
|
+
* Exported so a caller can ask the one question the manifest exists to answer
|
|
54
|
+
* ("is this file byte-for-byte what we recorded writing?") without needing the
|
|
55
|
+
* snapshot body, which is what makes the answer available on a fresh clone.
|
|
56
|
+
*/
|
|
57
|
+
export declare function contentHash(content: string): string;
|
|
58
|
+
/**
|
|
59
|
+
* The hash we recorded when we last wrote `relPath`, or undefined if we have no
|
|
60
|
+
* record of ever writing it.
|
|
61
|
+
*
|
|
62
|
+
* This is the COMMITTED half of `.gen-state`. The snapshot bodies stay ignored —
|
|
63
|
+
* they are a second full copy of all generated output — but a hash per path is
|
|
64
|
+
* small enough to commit and review, and it is sufficient to distinguish "nobody
|
|
65
|
+
* touched this" from "somebody edited this", which is the only distinction the
|
|
66
|
+
* overwrite and delete decisions actually need.
|
|
67
|
+
*/
|
|
68
|
+
export declare function readGeneratedHash(genStateDir: string, relPath: string): string | undefined;
|
|
69
|
+
/**
|
|
70
|
+
* True when the file at `relPath` is byte-for-byte what we recorded writing.
|
|
71
|
+
*
|
|
72
|
+
* FAILS CLOSED: with no recorded hash we cannot prove anything, so the answer is
|
|
73
|
+
* false. Both the write path and the orphan-delete path ask this one question of
|
|
74
|
+
* this one piece of evidence — before this existed they answered the same
|
|
75
|
+
* uncertainty in opposite directions inside a single feature, refusing to DELETE
|
|
76
|
+
* a hand-edited file while silently OVERWRITING one.
|
|
77
|
+
*/
|
|
78
|
+
export declare function isPristineGenerated(genStateDir: string, relPath: string, current: string): boolean;
|
|
79
|
+
/**
|
|
80
|
+
* The snapshot of what we last wrote to `relPath`, or undefined when there is no
|
|
81
|
+
* trustworthy one.
|
|
82
|
+
*
|
|
83
|
+
* HASH-CHECKED on purpose. A caller comparing this against the file on disk is
|
|
84
|
+
* asking "is the output still exactly what I wrote?" — and a snapshot that fails
|
|
85
|
+
* its own hash cannot answer that. Returning the stale text would let a
|
|
86
|
+
* reconciling caller conclude "untouched" and delete a file it cannot vouch for,
|
|
87
|
+
* so a tampered snapshot reads as absent and the caller fails closed.
|
|
88
|
+
*/
|
|
89
|
+
export declare function readGeneratedSnapshot(genStateDir: string, relPath: string): string | undefined;
|
|
90
|
+
/**
|
|
91
|
+
* Drop both halves of the record for paths this run no longer generates — each
|
|
92
|
+
* snapshot file and its `.hashes.json` entry.
|
|
93
|
+
*
|
|
94
|
+
* BOTH halves, or the next run sees the path again in `listGeneratedPaths` and
|
|
95
|
+
* re-decides an orphan that has already been dealt with. A no-op for a path that was
|
|
96
|
+
* never generated.
|
|
97
|
+
*
|
|
98
|
+
* Batched deliberately: one manifest read and one write for the whole set. A per-path
|
|
99
|
+
* variant re-reads, re-sorts and rewrites the entire manifest every call, so clearing k
|
|
100
|
+
* orphans rewrote it k times — on a project with hundreds of generated files that makes
|
|
101
|
+
* bookkeeping the dominant cost of `meta gen`, for an identical result.
|
|
102
|
+
*/
|
|
103
|
+
export declare function forgetGeneratedPaths(genStateDir: string, relPaths: Iterable<string>): void;
|
|
34
104
|
/**
|
|
35
105
|
* The codegen engine version that last wrote this `.gen-state`, or undefined if it
|
|
36
106
|
* was never stamped (a pre-#232 snapshot, or a fresh project). Informational only —
|
|
@@ -45,6 +115,30 @@ export declare function saveEngineVersion(genStateDir: string, version: string):
|
|
|
45
115
|
export declare class GitMissingError extends Error {
|
|
46
116
|
constructor();
|
|
47
117
|
}
|
|
118
|
+
/** True when this project has a hash manifest at all — as opposed to a manifest
|
|
119
|
+
* that simply has no entry for some path.
|
|
120
|
+
*
|
|
121
|
+
* The distinction drives the upgrade message: a project with NO manifest predates
|
|
122
|
+
* the manifest being committed, so its refusals are one fixable configuration
|
|
123
|
+
* problem rather than N independent hand edits, and it deserves one instruction
|
|
124
|
+
* instead of a wall of per-file warnings. */
|
|
125
|
+
export declare function hasHashManifest(genStateDir: string): boolean;
|
|
126
|
+
/**
|
|
127
|
+
* What `decideAndWrite` WOULD do, touching nothing. Backs `meta gen --dry-run`.
|
|
128
|
+
*
|
|
129
|
+
* Exact for every outcome the hash manifest decides, because those are pure
|
|
130
|
+
* comparisons — `classifyWrite` above is the single source for which one applies.
|
|
131
|
+
* Deliberately COARSE in one place: with a snapshot body present the result depends
|
|
132
|
+
* on whether `git merge-file` comes back clean or conflicted, which cannot be known
|
|
133
|
+
* without performing the merge — so that case reports `overwrite`, meaning "this
|
|
134
|
+
* file will be rewritten", which is true either way.
|
|
135
|
+
*
|
|
136
|
+
* The reason this exists as its own function rather than a flag on
|
|
137
|
+
* `decideAndWrite`: a preview must be incapable of writing, and the cheapest way to
|
|
138
|
+
* guarantee that is to give it no write in its body at all — mapping a `WriteCase`
|
|
139
|
+
* to a status touches no file and no manifest.
|
|
140
|
+
*/
|
|
141
|
+
export declare function previewWriteStatus(path: string, content: string, optsOrStrategy?: DecideAndWriteOpts | MergeStrategy): WriteStatus;
|
|
48
142
|
/**
|
|
49
143
|
* The main entry point. Backward-compatible with the rc.11 signature: passing
|
|
50
144
|
* a `MergeStrategy` string as the third argument continues to work; passing
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"overwrite-policy.d.ts","sourceRoot":"","sources":["../src/overwrite-policy.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"overwrite-policy.d.ts","sourceRoot":"","sources":["../src/overwrite-policy.ts"],"names":[],"mappings":"AA+CA,MAAM,MAAM,WAAW,GACnB,KAAK,GACL,WAAW,GACX,WAAW,GACX,QAAQ,GACR,UAAU,GACV,SAAS,GACT,SAAS;AACX;;;;wBAIwB;GACtB,SAAS,CAAC;AAEd;;;;;GAKG;AACH,MAAM,MAAM,aAAa,GAAG,WAAW,GAAG,eAAe,CAAC;AAE1D;;;iDAGiD;AACjD,MAAM,MAAM,YAAY,GAAG,SAAS,GAAG,OAAO,CAAC;AAE/C,MAAM,WAAW,kBAAkB;IACjC,QAAQ,CAAC,EAAE,aAAa,CAAC;IACzB;;+DAE2D;IAC3D,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB;;qEAEiE;IACjE,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,yCAAyC;IACzC,QAAQ,CAAC,EAAE,YAAY,CAAC;CACzB;AAED,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,WAAW,CAAC;IACpB;;4EAEwE;IACxE,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AA8CD;;;;;;;GAOG;AACH,wBAAgB,kBAAkB,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,EAAE,CAEhE;AAED;;;;;;GAMG;AACH,wBAAgB,WAAW,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAEnD;AAED;;;;;;;;;GASG;AACH,wBAAgB,iBAAiB,CAC/B,WAAW,EAAE,MAAM,EACnB,OAAO,EAAE,MAAM,GACd,MAAM,GAAG,SAAS,CAEpB;AAED;;;;;;;;GAQG;AACH,wBAAgB,mBAAmB,CACjC,WAAW,EAAE,MAAM,EACnB,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,MAAM,GACd,OAAO,CAGT;AAED;;;;;;;;;GASG;AACH,wBAAgB,qBAAqB,CACnC,WAAW,EAAE,MAAM,EACnB,OAAO,EAAE,MAAM,GACd,MAAM,GAAG,SAAS,CAEpB;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,oBAAoB,CAClC,WAAW,EAAE,MAAM,EACnB,QAAQ,EAAE,QAAQ,CAAC,MAAM,CAAC,GACzB,IAAI,CAYN;AAID;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAazE;AAED,+EAA+E;AAC/E,wBAAgB,iBAAiB,CAAC,WAAW,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,IAAI,CAM5E;AAwCD;gDACgD;AAChD,qBAAa,eAAgB,SAAQ,KAAK;;CAQzC;AA+FD;;;;;;8CAM8C;AAC9C,wBAAgB,eAAe,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAE5D;AA+FD;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,kBAAkB,CAChC,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,MAAM,EACf,cAAc,GAAE,kBAAkB,GAAG,aAAkB,GACtD,WAAW,CAmBb;AAED;;;;GAIG;AACH,wBAAgB,cAAc,CAC5B,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,MAAM,EACf,cAAc,GAAE,kBAAkB,GAAG,aAAkB,GACtD,WAAW,CA8Eb"}
|