@metaobjectsdev/codegen-ts 0.23.2 → 0.24.1
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 +7 -4
- package/dist/projection/build-projection-views.js.map +1 -1
- package/dist/projection/extract-view-spec.d.ts.map +1 -1
- package/dist/projection/extract-view-spec.js +70 -4
- package/dist/projection/extract-view-spec.js.map +1 -1
- package/dist/projection/view-ddl-emit.d.ts.map +1 -1
- package/dist/projection/view-ddl-emit.js +52 -0
- package/dist/projection/view-ddl-emit.js.map +1 -1
- package/dist/projection/view-spec.d.ts +15 -0
- package/dist/projection/view-spec.d.ts.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/inferred-types.d.ts.map +1 -1
- package/dist/templates/inferred-types.js +8 -4
- package/dist/templates/inferred-types.js.map +1 -1
- 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 +9 -8
- 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 +15 -4
- package/src/projection/extract-view-spec.ts +62 -3
- package/src/projection/view-ddl-emit.ts +54 -0
- package/src/projection/view-spec.ts +25 -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/inferred-types.ts +8 -4
- 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
|
@@ -154,30 +154,21 @@ export interface MetaobjectsGenConfig extends Omit<ResolvedGenConfig, "dbImport"
|
|
|
154
154
|
* loader. Composed AFTER the default core+forge bundle.
|
|
155
155
|
*/
|
|
156
156
|
providers?: readonly MetaDataTypeProvider[];
|
|
157
|
-
/** `meta verify` settings. Nothing here affects codegen. */
|
|
158
|
-
verify?: VerifyConfig;
|
|
159
|
-
}
|
|
160
|
-
|
|
161
|
-
/** `meta verify` settings. */
|
|
162
|
-
export interface VerifyConfig {
|
|
163
157
|
/**
|
|
164
|
-
*
|
|
165
|
-
*
|
|
166
|
-
* **What counts as a test file is the project's call.** The built-in patterns cover
|
|
167
|
-
* the conventions this repo ports to (jest/vitest/bun, JUnit, Maven Failsafe `*IT`,
|
|
168
|
-
* xUnit/NUnit, pytest, Kotlin) and are a CONVENIENCE, not an authority — a list of
|
|
169
|
-
* guesses about someone else's repository will always be incomplete, and when it is,
|
|
170
|
-
* a requirement naming a real test reads as a broken claim. Anything declared here is
|
|
171
|
-
* added to the built-ins.
|
|
158
|
+
* MetaObjects-shipped library packages this project loads alongside its own metadata —
|
|
159
|
+
* `["ai"]` makes `extends: "metaobjects::ai::LlmCallBase"` resolve.
|
|
172
160
|
*
|
|
173
|
-
*
|
|
174
|
-
*
|
|
161
|
+
* Sits beside `providers` because it answers the same shape of question: what does this
|
|
162
|
+
* project's model need in scope beyond the files it declares. Opt-in, because a library
|
|
163
|
+
* registers real top-level nodes and a project that never references one should not find
|
|
164
|
+
* them in its model, its generated output or its docs.
|
|
175
165
|
*
|
|
176
|
-
*
|
|
177
|
-
*
|
|
178
|
-
*
|
|
166
|
+
* Threaded to `loadMemory` by every CLI command that loads metadata. Before it existed,
|
|
167
|
+
* `librarySources` was reachable only from `MetaDataLoader.fromDirectory` — which the
|
|
168
|
+
* CLI does not use — so a generator that consumes a library was registered FOR the CLI
|
|
169
|
+
* while its input was unreachable THROUGH it (#333).
|
|
179
170
|
*/
|
|
180
|
-
|
|
171
|
+
libraries?: readonly string[];
|
|
181
172
|
}
|
|
182
173
|
|
|
183
174
|
/** MetaobjectsGenConfig after applying defaults. All fields required.
|
|
@@ -201,7 +192,7 @@ export interface NormalizedMetaobjectsGenConfig
|
|
|
201
192
|
targets: Record<string, ResolvedTarget>;
|
|
202
193
|
}
|
|
203
194
|
|
|
204
|
-
export type DocsSurface = "model" | "api";
|
|
195
|
+
export type DocsSurface = "model" | "api" | "requirements";
|
|
205
196
|
|
|
206
197
|
export interface ApiSurface {
|
|
207
198
|
lang: string;
|
|
@@ -240,7 +231,11 @@ export function resolveDocsConfig(
|
|
|
240
231
|
outDir: cli.outDir ?? block?.outDir ?? "./docs",
|
|
241
232
|
layout: cli.layout ?? block?.layout ?? fallbackLayout,
|
|
242
233
|
baseUrl: cli.baseUrl ?? block?.baseUrl ?? "",
|
|
243
|
-
|
|
234
|
+
// `requirements` defaults ON. Safe ONLY because requirementsFile() emits ZERO
|
|
235
|
+
// files for a project declaring no `requirement.*` node — not an empty page. A
|
|
236
|
+
// project without a ledger sees byte-identical output to before the surface
|
|
237
|
+
// existed; see requirements-file.ts.
|
|
238
|
+
surfaces: cli.surfaces ?? block?.surfaces ?? ["model", "api", "requirements"],
|
|
244
239
|
apiSurfaces: cli.apiSurfaces ?? block?.apiSurfaces ?? [{ lang: "ts", subDir: "api" }],
|
|
245
240
|
};
|
|
246
241
|
}
|
|
@@ -0,0 +1,178 @@
|
|
|
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
|
+
|
|
23
|
+
import { existsSync, readFileSync, rmSync } from "node:fs";
|
|
24
|
+
import { isAbsolute, relative, resolve, sep } from "node:path";
|
|
25
|
+
import {
|
|
26
|
+
listGeneratedPaths,
|
|
27
|
+
isPristineGenerated,
|
|
28
|
+
forgetGeneratedPaths,
|
|
29
|
+
} from "./overwrite-policy.js";
|
|
30
|
+
import { reconcileOrphans, type OrphanPolicy } from "./reconcile-orphans.js";
|
|
31
|
+
|
|
32
|
+
/** One opt-in generator's stake in the sweep. */
|
|
33
|
+
export interface OrphanJob {
|
|
34
|
+
/** For diagnostics — which generator's namespace this is. */
|
|
35
|
+
readonly generatorName: string;
|
|
36
|
+
/** Absolute directory this generator wrote to, i.e. the base its policy's
|
|
37
|
+
* relative paths are measured from. */
|
|
38
|
+
readonly writeOutDir: string;
|
|
39
|
+
readonly policy: OrphanPolicy;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
export interface SweepOrphansArgs {
|
|
43
|
+
readonly genStateDir: string;
|
|
44
|
+
/** Absolute project root — the base gen-state keys are relative to. */
|
|
45
|
+
readonly projectRoot: string;
|
|
46
|
+
/** Project-relative paths written on THIS run, by ANY generator. A path some
|
|
47
|
+
* other generator now produces is not an orphan, so the whole run's output is
|
|
48
|
+
* the right exclusion set, not just the opting-in generator's. */
|
|
49
|
+
readonly emittedRelPaths: readonly string[];
|
|
50
|
+
readonly jobs: readonly OrphanJob[];
|
|
51
|
+
/** Decide and report, touch nothing. */
|
|
52
|
+
readonly dryRun: boolean;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
export interface SweepOrphansResult {
|
|
56
|
+
/** Untouched orphans deleted (or, under dryRun, that would be). */
|
|
57
|
+
readonly removed: string[];
|
|
58
|
+
/** Hand-edited orphans left alone and reported. */
|
|
59
|
+
readonly refused: string[];
|
|
60
|
+
/** Which generator's namespace each refusal came from, so the caller can name it
|
|
61
|
+
* instead of assuming one. `orphanPolicy` is a generic `Generator` field and an app
|
|
62
|
+
* is encouraged to compose its own generator, so a message hardcoding one
|
|
63
|
+
* generator's name would be wrong for exactly the users the seam exists for. */
|
|
64
|
+
readonly refusedBy: ReadonlyMap<string, string>;
|
|
65
|
+
/** Hand-edited orphans deleted because their policy set `force`. Separate from
|
|
66
|
+
* `removed` so the caller can say the louder thing about them. */
|
|
67
|
+
readonly forced: string[];
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
/** gen-state keys carry the platform separator; an `owns` predicate is written
|
|
71
|
+
* against generated output, which is always `/`-separated. Normalize once so a
|
|
72
|
+
* predicate authored the obvious way is not silently wrong off Linux. */
|
|
73
|
+
function toPosix(p: string): string {
|
|
74
|
+
return sep === "/" ? p : p.split(sep).join("/");
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
export function sweepOrphans(args: SweepOrphansArgs): SweepOrphansResult {
|
|
78
|
+
if (args.jobs.length === 0) {
|
|
79
|
+
return { removed: [], refused: [], forced: [], refusedBy: new Map() };
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
const previouslyGenerated = listGeneratedPaths(args.genStateDir);
|
|
83
|
+
if (previouslyGenerated.length === 0) {
|
|
84
|
+
return { removed: [], refused: [], forced: [], refusedBy: new Map() };
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
// NOT normalized: both sides of this comparison are produced by
|
|
88
|
+
// `relative(projectRoot, …)` — gen-state's keys and the runner's emitted paths
|
|
89
|
+
// alike — so they already share whatever separator the platform uses.
|
|
90
|
+
// Normalizing one side is what would break them apart. `toPosix` is used only
|
|
91
|
+
// where a HUMAN-authored string is involved (the `owns` predicate below).
|
|
92
|
+
const emitted = args.emittedRelPaths;
|
|
93
|
+
// A path can fall inside two jobs' namespaces (an app may register several
|
|
94
|
+
// requirementTests() instances). Sets keep the second visit from re-reporting
|
|
95
|
+
// a file the first already dealt with.
|
|
96
|
+
const removed = new Set<string>();
|
|
97
|
+
const refused = new Set<string>();
|
|
98
|
+
const forced = new Set<string>();
|
|
99
|
+
const forget = new Set<string>();
|
|
100
|
+
const refusedBy = new Map<string, string>();
|
|
101
|
+
|
|
102
|
+
for (const job of args.jobs) {
|
|
103
|
+
const decision = reconcileOrphans({
|
|
104
|
+
previouslyGenerated,
|
|
105
|
+
emitted,
|
|
106
|
+
owns: (relPath) => {
|
|
107
|
+
const inTarget = relative(job.writeOutDir, resolve(args.projectRoot, relPath));
|
|
108
|
+
// "" is the directory itself; a `..` prefix or an absolute result means
|
|
109
|
+
// the path is outside this generator's output entirely. Neither is
|
|
110
|
+
// something the predicate should get a say in.
|
|
111
|
+
if (inTarget === "" || inTarget.startsWith("..") || isAbsolute(inTarget)) {
|
|
112
|
+
return false;
|
|
113
|
+
}
|
|
114
|
+
return job.policy.owns(toPosix(inTarget));
|
|
115
|
+
},
|
|
116
|
+
exists: (relPath) => existsSync(resolve(args.projectRoot, relPath)),
|
|
117
|
+
// The committed hash manifest, NOT the snapshot body — the bodies are
|
|
118
|
+
// gitignored, so on a fresh clone a body-based check could never prove a
|
|
119
|
+
// file untouched and orphan cleanup would refuse everything forever.
|
|
120
|
+
isUntouched: (relPath) => {
|
|
121
|
+
const full = resolve(args.projectRoot, relPath);
|
|
122
|
+
if (!existsSync(full)) return false;
|
|
123
|
+
return isPristineGenerated(
|
|
124
|
+
args.genStateDir,
|
|
125
|
+
relPath,
|
|
126
|
+
readFileSync(full, "utf-8"),
|
|
127
|
+
);
|
|
128
|
+
},
|
|
129
|
+
});
|
|
130
|
+
|
|
131
|
+
for (const relPath of decision.remove) {
|
|
132
|
+
if (refused.has(relPath) || forced.has(relPath)) continue;
|
|
133
|
+
removed.add(relPath);
|
|
134
|
+
forget.add(relPath);
|
|
135
|
+
}
|
|
136
|
+
for (const relPath of decision.refused) {
|
|
137
|
+
// `refused` belongs in this guard too. Without it, a path already refused by a
|
|
138
|
+
// non-forcing job could be picked up by a later FORCING job whose namespace
|
|
139
|
+
// overlaps (the file anticipates several requirementTests() instances), landing
|
|
140
|
+
// in `refused` and `forced` at once — deleted from disk, while
|
|
141
|
+
// `refusedOrphanMessage` tells the user it "was NOT deleted".
|
|
142
|
+
//
|
|
143
|
+
// First decision wins: a refusal is the conservative answer, and letting a
|
|
144
|
+
// later job escalate it to a deletion would make the outcome depend on job
|
|
145
|
+
// ORDER, which is exactly the ambiguity the runner's duplicate-path guard
|
|
146
|
+
// exists to reject elsewhere.
|
|
147
|
+
if (removed.has(relPath) || forced.has(relPath) || refused.has(relPath)) continue;
|
|
148
|
+
if (job.policy.force === true) {
|
|
149
|
+
forced.add(relPath);
|
|
150
|
+
forget.add(relPath);
|
|
151
|
+
} else {
|
|
152
|
+
// Deliberately NOT forgotten: the record is what makes the refusal
|
|
153
|
+
// repeat until someone resolves it.
|
|
154
|
+
refused.add(relPath);
|
|
155
|
+
refusedBy.set(relPath, job.generatorName);
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
// Nothing on disk to report — the file is already gone. Clear the stale
|
|
159
|
+
// record so this stops being reconsidered on every future run.
|
|
160
|
+
for (const relPath of decision.vanished) forget.add(relPath);
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
if (!args.dryRun) {
|
|
164
|
+
for (const relPath of [...removed, ...forced]) {
|
|
165
|
+
rmSync(resolve(args.projectRoot, relPath), { force: true });
|
|
166
|
+
}
|
|
167
|
+
// Batched: the per-path form rewrites the whole manifest each call, so clearing
|
|
168
|
+
// k orphans rewrote it k times for an identical result.
|
|
169
|
+
forgetGeneratedPaths(args.genStateDir, forget);
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
return {
|
|
173
|
+
removed: [...removed].sort(),
|
|
174
|
+
refused: [...refused].sort(),
|
|
175
|
+
forced: [...forced].sort(),
|
|
176
|
+
refusedBy,
|
|
177
|
+
};
|
|
178
|
+
}
|