jumbo-cli 3.12.0 → 3.12.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/infrastructure/settings/FsSettingsInitializer.d.ts +9 -3
- package/dist/infrastructure/settings/FsSettingsInitializer.d.ts.map +1 -1
- package/dist/infrastructure/settings/FsSettingsInitializer.js +19 -4
- package/dist/infrastructure/settings/FsSettingsInitializer.js.map +1 -1
- package/dist/infrastructure/settings/FsSettingsReader.d.ts +6 -0
- package/dist/infrastructure/settings/FsSettingsReader.d.ts.map +1 -1
- package/dist/infrastructure/settings/FsSettingsReader.js +43 -2
- package/dist/infrastructure/settings/FsSettingsReader.js.map +1 -1
- package/dist/infrastructure/settings/JsoncSettingsEditor.d.ts +40 -0
- package/dist/infrastructure/settings/JsoncSettingsEditor.d.ts.map +1 -0
- package/dist/infrastructure/settings/JsoncSettingsEditor.js +73 -0
- package/dist/infrastructure/settings/JsoncSettingsEditor.js.map +1 -0
- package/package.json +1 -1
|
@@ -1,15 +1,21 @@
|
|
|
1
1
|
import { ISettingsInitializer } from "../../application/settings/ISettingsInitializer.js";
|
|
2
2
|
import { PlannedFileChange } from "../../application/context/project/init/PlannedFileChange.js";
|
|
3
3
|
/**
|
|
4
|
-
* FsSettingsInitializer - Creates settings file with defaults if it doesn't exist
|
|
4
|
+
* FsSettingsInitializer - Creates settings file with defaults if it doesn't exist,
|
|
5
|
+
* and additively fills in any missing default sections or fields if it does.
|
|
5
6
|
*
|
|
6
|
-
* Called during bootstrap to ensure settings infrastructure is
|
|
7
|
-
*
|
|
7
|
+
* Called during bootstrap and evolve to ensure settings infrastructure is current.
|
|
8
|
+
* Existing explicit values and unknown entries are always preserved.
|
|
8
9
|
*/
|
|
9
10
|
export declare class FsSettingsInitializer implements ISettingsInitializer {
|
|
10
11
|
private readonly settingsFilePath;
|
|
11
12
|
constructor(rootDir: string);
|
|
12
13
|
ensureSettingsFileExists(): Promise<void>;
|
|
14
|
+
/**
|
|
15
|
+
* Fill in any missing default sections or fields on an existing settings
|
|
16
|
+
* file, leaving explicit values and unknown entries untouched.
|
|
17
|
+
*/
|
|
18
|
+
private applyMissingDefaults;
|
|
13
19
|
getPlannedFileChange(): Promise<PlannedFileChange | null>;
|
|
14
20
|
}
|
|
15
21
|
//# sourceMappingURL=FsSettingsInitializer.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"FsSettingsInitializer.d.ts","sourceRoot":"","sources":["../../../src/infrastructure/settings/FsSettingsInitializer.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,oBAAoB,EAAE,MAAM,oDAAoD,CAAC;AAC1F,OAAO,EAAE,iBAAiB,EAAE,MAAM,6DAA6D,CAAC;
|
|
1
|
+
{"version":3,"file":"FsSettingsInitializer.d.ts","sourceRoot":"","sources":["../../../src/infrastructure/settings/FsSettingsInitializer.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,oBAAoB,EAAE,MAAM,oDAAoD,CAAC;AAC1F,OAAO,EAAE,iBAAiB,EAAE,MAAM,6DAA6D,CAAC;AAIhG;;;;;;GAMG;AACH,qBAAa,qBAAsB,YAAW,oBAAoB;IAChE,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAS;gBAE9B,OAAO,EAAE,MAAM;IAIrB,wBAAwB,IAAI,OAAO,CAAC,IAAI,CAAC;IAsD/C;;;OAGG;YACW,oBAAoB;IAU5B,oBAAoB,IAAI,OAAO,CAAC,iBAAiB,GAAG,IAAI,CAAC;CAUhE"}
|
|
@@ -1,18 +1,21 @@
|
|
|
1
1
|
import fs from "fs-extra";
|
|
2
2
|
import path from "path";
|
|
3
|
+
import { DEFAULT_SETTINGS } from "./DefaultSettings.js";
|
|
4
|
+
import { applyMissingDefaults, assertValidJsonc } from "./JsoncSettingsEditor.js";
|
|
3
5
|
/**
|
|
4
|
-
* FsSettingsInitializer - Creates settings file with defaults if it doesn't exist
|
|
6
|
+
* FsSettingsInitializer - Creates settings file with defaults if it doesn't exist,
|
|
7
|
+
* and additively fills in any missing default sections or fields if it does.
|
|
5
8
|
*
|
|
6
|
-
* Called during bootstrap to ensure settings infrastructure is
|
|
7
|
-
*
|
|
9
|
+
* Called during bootstrap and evolve to ensure settings infrastructure is current.
|
|
10
|
+
* Existing explicit values and unknown entries are always preserved.
|
|
8
11
|
*/
|
|
9
12
|
export class FsSettingsInitializer {
|
|
10
13
|
constructor(rootDir) {
|
|
11
14
|
this.settingsFilePath = path.join(rootDir, "settings.jsonc");
|
|
12
15
|
}
|
|
13
16
|
async ensureSettingsFileExists() {
|
|
14
|
-
// Only create if it doesn't exist
|
|
15
17
|
if (await fs.pathExists(this.settingsFilePath)) {
|
|
18
|
+
await this.applyMissingDefaults();
|
|
16
19
|
return;
|
|
17
20
|
}
|
|
18
21
|
const content = `{
|
|
@@ -61,6 +64,18 @@ export class FsSettingsInitializer {
|
|
|
61
64
|
`;
|
|
62
65
|
await fs.writeFile(this.settingsFilePath, content, "utf-8");
|
|
63
66
|
}
|
|
67
|
+
/**
|
|
68
|
+
* Fill in any missing default sections or fields on an existing settings
|
|
69
|
+
* file, leaving explicit values and unknown entries untouched.
|
|
70
|
+
*/
|
|
71
|
+
async applyMissingDefaults() {
|
|
72
|
+
const content = await fs.readFile(this.settingsFilePath, "utf-8");
|
|
73
|
+
assertValidJsonc(content, this.settingsFilePath);
|
|
74
|
+
const updated = applyMissingDefaults(content, DEFAULT_SETTINGS);
|
|
75
|
+
if (updated !== content) {
|
|
76
|
+
await fs.writeFile(this.settingsFilePath, updated, "utf-8");
|
|
77
|
+
}
|
|
78
|
+
}
|
|
64
79
|
async getPlannedFileChange() {
|
|
65
80
|
if (await fs.pathExists(this.settingsFilePath)) {
|
|
66
81
|
return null; // No change needed
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"FsSettingsInitializer.js","sourceRoot":"","sources":["../../../src/infrastructure/settings/FsSettingsInitializer.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,UAAU,CAAC;AAC1B,OAAO,IAAI,MAAM,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"FsSettingsInitializer.js","sourceRoot":"","sources":["../../../src/infrastructure/settings/FsSettingsInitializer.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,UAAU,CAAC;AAC1B,OAAO,IAAI,MAAM,MAAM,CAAC;AAGxB,OAAO,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AACxD,OAAO,EAAc,oBAAoB,EAAE,gBAAgB,EAAE,MAAM,0BAA0B,CAAC;AAE9F;;;;;;GAMG;AACH,MAAM,OAAO,qBAAqB;IAGhC,YAAY,OAAe;QACzB,IAAI,CAAC,gBAAgB,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,gBAAgB,CAAC,CAAC;IAC/D,CAAC;IAED,KAAK,CAAC,wBAAwB;QAC5B,IAAI,MAAM,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC,gBAAgB,CAAC,EAAE,CAAC;YAC/C,MAAM,IAAI,CAAC,oBAAoB,EAAE,CAAC;YAClC,OAAO;QACT,CAAC;QAED,MAAM,OAAO,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA2CnB,CAAC;QAEE,MAAM,EAAE,CAAC,SAAS,CAAC,IAAI,CAAC,gBAAgB,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC;IAC9D,CAAC;IAED;;;OAGG;IACK,KAAK,CAAC,oBAAoB;QAChC,MAAM,OAAO,GAAG,MAAM,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,gBAAgB,EAAE,OAAO,CAAC,CAAC;QAClE,gBAAgB,CAAC,OAAO,EAAE,IAAI,CAAC,gBAAgB,CAAC,CAAC;QAEjD,MAAM,OAAO,GAAG,oBAAoB,CAAC,OAAO,EAAE,gBAAyC,CAAC,CAAC;QACzF,IAAI,OAAO,KAAK,OAAO,EAAE,CAAC;YACxB,MAAM,EAAE,CAAC,SAAS,CAAC,IAAI,CAAC,gBAAgB,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC;QAC9D,CAAC;IACH,CAAC;IAED,KAAK,CAAC,oBAAoB;QACxB,IAAI,MAAM,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC,gBAAgB,CAAC,EAAE,CAAC;YAC/C,OAAO,IAAI,CAAC,CAAC,mBAAmB;QAClC,CAAC;QACD,OAAO;YACL,IAAI,EAAE,uBAAuB;YAC7B,MAAM,EAAE,QAAQ;YAChB,WAAW,EAAE,8BAA8B;SAC5C,CAAC;IACJ,CAAC;CACF"}
|
|
@@ -12,6 +12,12 @@ export declare class FsSettingsReader implements ISettingsReader {
|
|
|
12
12
|
constructor(rootDir: string);
|
|
13
13
|
read(): Promise<Settings>;
|
|
14
14
|
write(settings: Settings): Promise<void>;
|
|
15
|
+
/**
|
|
16
|
+
* Known settings leaf paths and their values, used to persist changes onto
|
|
17
|
+
* an existing settings file without disturbing unknown entries elsewhere
|
|
18
|
+
* in the document.
|
|
19
|
+
*/
|
|
20
|
+
private knownValueEntries;
|
|
15
21
|
hasTelemetryConfiguration(): Promise<boolean>;
|
|
16
22
|
/**
|
|
17
23
|
* Create settings file with default values and helpful comments
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"FsSettingsReader.d.ts","sourceRoot":"","sources":["../../../src/infrastructure/settings/FsSettingsReader.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,eAAe,EAAE,MAAM,+CAA+C,CAAC;AAChF,OAAO,EAAE,QAAQ,EAAE,MAAM,wCAAwC,CAAC;
|
|
1
|
+
{"version":3,"file":"FsSettingsReader.d.ts","sourceRoot":"","sources":["../../../src/infrastructure/settings/FsSettingsReader.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,eAAe,EAAE,MAAM,+CAA+C,CAAC;AAChF,OAAO,EAAE,QAAQ,EAAE,MAAM,wCAAwC,CAAC;AAIlE;;;;;;GAMG;AACH,qBAAa,gBAAiB,YAAW,eAAe;IACtD,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAS;gBAE9B,OAAO,EAAE,MAAM;IAIrB,IAAI,IAAI,OAAO,CAAC,QAAQ,CAAC;IAkCzB,KAAK,CAAC,QAAQ,EAAE,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC;IAyB9C;;;;OAIG;IACH,OAAO,CAAC,iBAAiB;IAwBnB,yBAAyB,IAAI,OAAO,CAAC,OAAO,CAAC;IAenD;;OAEG;YACW,yBAAyB;IAIvC;;OAEG;IACH,OAAO,CAAC,iBAAiB;IAmCzB,OAAO,CAAC,wBAAwB;YAsDlB,eAAe;IAgB7B;;OAEG;IACH,OAAO,CAAC,iBAAiB;CAQ1B"}
|
|
@@ -2,6 +2,7 @@ import fs from "fs-extra";
|
|
|
2
2
|
import path from "path";
|
|
3
3
|
import * as jsonc from "jsonc-parser";
|
|
4
4
|
import { DEFAULT_SETTINGS } from "./DefaultSettings.js";
|
|
5
|
+
import { setJsoncValue } from "./JsoncSettingsEditor.js";
|
|
5
6
|
/**
|
|
6
7
|
* JsoncSettingsReader - File system implementation for reading settings.
|
|
7
8
|
*
|
|
@@ -42,8 +43,48 @@ export class FsSettingsReader {
|
|
|
42
43
|
}
|
|
43
44
|
async write(settings) {
|
|
44
45
|
const normalizedSettings = this.mergeWithDefaults(settings);
|
|
45
|
-
|
|
46
|
-
|
|
46
|
+
if (!(await fs.pathExists(this.settingsFilePath))) {
|
|
47
|
+
const content = this.buildSettingsFileContent(normalizedSettings);
|
|
48
|
+
await fs.writeFile(this.settingsFilePath, content, "utf-8");
|
|
49
|
+
return;
|
|
50
|
+
}
|
|
51
|
+
const existingContent = await fs.readFile(this.settingsFilePath, "utf-8");
|
|
52
|
+
const errors = [];
|
|
53
|
+
jsonc.parse(existingContent, errors, { allowTrailingComma: true });
|
|
54
|
+
if (errors.length > 0) {
|
|
55
|
+
throw new Error(`Invalid JSON in settings file: ${this.formatParseErrors(errors)}`);
|
|
56
|
+
}
|
|
57
|
+
let updated = existingContent;
|
|
58
|
+
for (const { path: fieldPath, value } of this.knownValueEntries(normalizedSettings)) {
|
|
59
|
+
updated = setJsoncValue(updated, fieldPath, value);
|
|
60
|
+
}
|
|
61
|
+
await fs.writeFile(this.settingsFilePath, updated, "utf-8");
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Known settings leaf paths and their values, used to persist changes onto
|
|
65
|
+
* an existing settings file without disturbing unknown entries elsewhere
|
|
66
|
+
* in the document.
|
|
67
|
+
*/
|
|
68
|
+
knownValueEntries(settings) {
|
|
69
|
+
return [
|
|
70
|
+
{ path: ["project", "id"], value: settings.project.id },
|
|
71
|
+
{ path: ["qa", "defaultTurnLimit"], value: settings.qa.defaultTurnLimit },
|
|
72
|
+
{
|
|
73
|
+
path: ["claims", "claimDurationMinutes"],
|
|
74
|
+
value: settings.claims.claimDurationMinutes,
|
|
75
|
+
},
|
|
76
|
+
{ path: ["telemetry", "enabled"], value: settings.telemetry.enabled },
|
|
77
|
+
{ path: ["telemetry", "anonymousId"], value: settings.telemetry.anonymousId },
|
|
78
|
+
{ path: ["telemetry", "consentGiven"], value: settings.telemetry.consentGiven },
|
|
79
|
+
{
|
|
80
|
+
path: ["tui", "showLaunchpadWelcome"],
|
|
81
|
+
value: settings.tui.showLaunchpadWelcome,
|
|
82
|
+
},
|
|
83
|
+
{
|
|
84
|
+
path: ["session", "backlogPreviewSize"],
|
|
85
|
+
value: settings.session.backlogPreviewSize,
|
|
86
|
+
},
|
|
87
|
+
];
|
|
47
88
|
}
|
|
48
89
|
async hasTelemetryConfiguration() {
|
|
49
90
|
if (!(await fs.pathExists(this.settingsFilePath))) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"FsSettingsReader.js","sourceRoot":"","sources":["../../../src/infrastructure/settings/FsSettingsReader.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,UAAU,CAAC;AAC1B,OAAO,IAAI,MAAM,MAAM,CAAC;AACxB,OAAO,KAAK,KAAK,MAAM,cAAc,CAAC;AAGtC,OAAO,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;
|
|
1
|
+
{"version":3,"file":"FsSettingsReader.js","sourceRoot":"","sources":["../../../src/infrastructure/settings/FsSettingsReader.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import * as jsonc from "jsonc-parser";
|
|
2
|
+
/**
|
|
3
|
+
* Recursive JSON value shape used to walk settings documents and defaults
|
|
4
|
+
* without resorting to `any` at the JSONC editing boundary.
|
|
5
|
+
*/
|
|
6
|
+
export type JsonValue = string | number | boolean | null | JsonValue[] | {
|
|
7
|
+
[key: string]: JsonValue;
|
|
8
|
+
};
|
|
9
|
+
export type JsonObject = {
|
|
10
|
+
[key: string]: JsonValue;
|
|
11
|
+
};
|
|
12
|
+
/**
|
|
13
|
+
* Parse settings JSONC content, throwing a descriptive error if it is invalid.
|
|
14
|
+
* Used at every write path so malformed files fail loudly instead of being
|
|
15
|
+
* partially rewritten.
|
|
16
|
+
*/
|
|
17
|
+
export declare function assertValidJsonc(content: string, filePath: string): void;
|
|
18
|
+
/**
|
|
19
|
+
* Set a single value at `path` within JSONC `content`, preserving comments,
|
|
20
|
+
* formatting, and every other entry in the document.
|
|
21
|
+
*/
|
|
22
|
+
export declare function setJsoncValue(content: string, path: jsonc.JSONPath, value: JsonValue): string;
|
|
23
|
+
export interface MissingEntry {
|
|
24
|
+
path: jsonc.JSONPath;
|
|
25
|
+
value: JsonValue;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Walk `defaults` against existing JSONC `content` and collect entries that
|
|
29
|
+
* are absent. Whole subtrees are reported as a single entry when their parent
|
|
30
|
+
* is entirely missing; otherwise only the missing nested fields are reported.
|
|
31
|
+
* Collected entries never nest one inside another, so they can be applied to
|
|
32
|
+
* `content` in any order without conflicting.
|
|
33
|
+
*/
|
|
34
|
+
export declare function collectMissingDefaults(content: string, defaults: JsonObject, basePath?: jsonc.JSONPath): MissingEntry[];
|
|
35
|
+
/**
|
|
36
|
+
* Apply every missing default entry to `content`, returning the updated
|
|
37
|
+
* document. Returns `content` unchanged if there is nothing to add.
|
|
38
|
+
*/
|
|
39
|
+
export declare function applyMissingDefaults(content: string, defaults: JsonObject): string;
|
|
40
|
+
//# sourceMappingURL=JsoncSettingsEditor.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"JsoncSettingsEditor.d.ts","sourceRoot":"","sources":["../../../src/infrastructure/settings/JsoncSettingsEditor.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,cAAc,CAAC;AAEtC;;;GAGG;AACH,MAAM,MAAM,SAAS,GACjB,MAAM,GACN,MAAM,GACN,OAAO,GACP,IAAI,GACJ,SAAS,EAAE,GACX;IAAE,CAAC,GAAG,EAAE,MAAM,GAAG,SAAS,CAAA;CAAE,CAAC;AAEjC,MAAM,MAAM,UAAU,GAAG;IAAE,CAAC,GAAG,EAAE,MAAM,GAAG,SAAS,CAAA;CAAE,CAAC;AAYtD;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,IAAI,CASxE;AAED;;;GAGG;AACH,wBAAgB,aAAa,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,KAAK,CAAC,QAAQ,EAAE,KAAK,EAAE,SAAS,GAAG,MAAM,CAG7F;AAUD,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,KAAK,CAAC,QAAQ,CAAC;IACrB,KAAK,EAAE,SAAS,CAAC;CAClB;AAED;;;;;;GAMG;AACH,wBAAgB,sBAAsB,CACpC,OAAO,EAAE,MAAM,EACf,QAAQ,EAAE,UAAU,EACpB,QAAQ,GAAE,KAAK,CAAC,QAAa,GAC5B,YAAY,EAAE,CAYhB;AAED;;;GAGG;AACH,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,UAAU,GAAG,MAAM,CAOlF"}
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import * as jsonc from "jsonc-parser";
|
|
2
|
+
const FORMATTING_OPTIONS = {
|
|
3
|
+
insertSpaces: true,
|
|
4
|
+
tabSize: 2,
|
|
5
|
+
eol: "\n",
|
|
6
|
+
};
|
|
7
|
+
function isPlainObject(value) {
|
|
8
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* Parse settings JSONC content, throwing a descriptive error if it is invalid.
|
|
12
|
+
* Used at every write path so malformed files fail loudly instead of being
|
|
13
|
+
* partially rewritten.
|
|
14
|
+
*/
|
|
15
|
+
export function assertValidJsonc(content, filePath) {
|
|
16
|
+
const errors = [];
|
|
17
|
+
jsonc.parse(content, errors, { allowTrailingComma: true });
|
|
18
|
+
if (errors.length > 0) {
|
|
19
|
+
const formatted = errors
|
|
20
|
+
.map((err) => `Error at offset ${err.offset}: ${jsonc.printParseErrorCode(err.error)}`)
|
|
21
|
+
.join(", ");
|
|
22
|
+
throw new Error(`Invalid JSON in settings file at ${filePath}: ${formatted}`);
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Set a single value at `path` within JSONC `content`, preserving comments,
|
|
27
|
+
* formatting, and every other entry in the document.
|
|
28
|
+
*/
|
|
29
|
+
export function setJsoncValue(content, path, value) {
|
|
30
|
+
const edits = jsonc.modify(content, path, value, { formattingOptions: FORMATTING_OPTIONS });
|
|
31
|
+
return jsonc.applyEdits(content, edits);
|
|
32
|
+
}
|
|
33
|
+
function isMissing(content, path) {
|
|
34
|
+
const tree = jsonc.parseTree(content);
|
|
35
|
+
if (!tree) {
|
|
36
|
+
return true;
|
|
37
|
+
}
|
|
38
|
+
return jsonc.findNodeAtLocation(tree, path) === undefined;
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Walk `defaults` against existing JSONC `content` and collect entries that
|
|
42
|
+
* are absent. Whole subtrees are reported as a single entry when their parent
|
|
43
|
+
* is entirely missing; otherwise only the missing nested fields are reported.
|
|
44
|
+
* Collected entries never nest one inside another, so they can be applied to
|
|
45
|
+
* `content` in any order without conflicting.
|
|
46
|
+
*/
|
|
47
|
+
export function collectMissingDefaults(content, defaults, basePath = []) {
|
|
48
|
+
const entries = [];
|
|
49
|
+
for (const key of Object.keys(defaults)) {
|
|
50
|
+
const path = [...basePath, key];
|
|
51
|
+
const value = defaults[key];
|
|
52
|
+
if (isMissing(content, path)) {
|
|
53
|
+
entries.push({ path, value });
|
|
54
|
+
}
|
|
55
|
+
else if (isPlainObject(value)) {
|
|
56
|
+
entries.push(...collectMissingDefaults(content, value, path));
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
return entries;
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Apply every missing default entry to `content`, returning the updated
|
|
63
|
+
* document. Returns `content` unchanged if there is nothing to add.
|
|
64
|
+
*/
|
|
65
|
+
export function applyMissingDefaults(content, defaults) {
|
|
66
|
+
const entries = collectMissingDefaults(content, defaults);
|
|
67
|
+
let updated = content;
|
|
68
|
+
for (const entry of entries) {
|
|
69
|
+
updated = setJsoncValue(updated, entry.path, entry.value);
|
|
70
|
+
}
|
|
71
|
+
return updated;
|
|
72
|
+
}
|
|
73
|
+
//# sourceMappingURL=JsoncSettingsEditor.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"JsoncSettingsEditor.js","sourceRoot":"","sources":["../../../src/infrastructure/settings/JsoncSettingsEditor.ts"],"names":[],"mappings":"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"}
|