dsh-connect 0.9.0 → 0.9.2
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/README.i18n.yaml +2 -2
- package/README.md +119 -18
- package/README.zh.md +87 -13
- package/client/client.js +18 -15
- package/client/client.js.map +2 -2
- package/client/settings-client.mjs +22 -13
- package/lib/channels/dingtalk/index.d.ts +49 -49
- package/lib/channels/dingtalk/index.d.ts.map +1 -1
- package/lib/channels/feishu/adapter.d.ts +8 -1
- package/lib/channels/feishu/adapter.d.ts.map +1 -1
- package/lib/channels/feishu/adapter.js +120 -39
- package/lib/channels/feishu/adapter.js.map +1 -1
- package/lib/channels/feishu/index.d.ts +27 -27
- package/lib/channels/feishu/index.d.ts.map +1 -1
- package/lib/channels/telegram/index.d.ts +13 -13
- package/lib/channels/telegram/index.d.ts.map +1 -1
- package/lib/channels/web/adapter.d.ts +3 -1
- package/lib/channels/web/adapter.d.ts.map +1 -1
- package/lib/channels/web/adapter.js +3 -1
- package/lib/channels/web/adapter.js.map +1 -1
- package/lib/channels/web/index.d.ts +5 -5
- package/lib/channels/web/index.d.ts.map +1 -1
- package/lib/index.d.ts +42 -58
- package/lib/index.d.ts.map +1 -1
- package/lib/index.js +162 -57
- package/lib/index.js.map +1 -1
- package/lib/interaction.d.ts +90 -50
- package/lib/interaction.d.ts.map +1 -1
- package/lib/interaction.js +233 -272
- package/lib/interaction.js.map +1 -1
- package/lib/retry.d.ts.map +1 -1
- package/lib/retry.js +7 -1
- package/lib/retry.js.map +1 -1
- package/lib/service.d.ts.map +1 -1
- package/lib/service.js +0 -2
- package/lib/service.js.map +1 -1
- package/lib/settings/legacy-import.d.ts +190 -0
- package/lib/settings/legacy-import.d.ts.map +1 -0
- package/lib/settings/legacy-import.js +373 -0
- package/lib/settings/legacy-import.js.map +1 -0
- package/lib/settings/namespace.d.ts +204 -116
- package/lib/settings/namespace.d.ts.map +1 -1
- package/lib/settings/namespace.js +235 -148
- package/lib/settings/namespace.js.map +1 -1
- package/lib/settings/settings-model.d.ts.map +1 -1
- package/lib/settings/settings-model.js +10 -1
- package/lib/settings/settings-model.js.map +1 -1
- package/lib/settings/settings-service.d.ts +13 -0
- package/lib/settings/settings-service.d.ts.map +1 -1
- package/lib/settings/settings-service.js +73 -4
- package/lib/settings/settings-service.js.map +1 -1
- package/lib/types.d.ts +14 -1
- package/lib/types.d.ts.map +1 -1
- package/package.json +12 -11
|
@@ -0,0 +1,373 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* One-shot migration of the pre-0.2 pane settings into the `connect` profile entry.
|
|
3
|
+
*
|
|
4
|
+
* Before 0.2 this plugin's pane settings lived in `$DSH_HOME/settings.yaml`
|
|
5
|
+
* under a `dsh-connect:` section, keyed by plugin *name*. The 0.2 host does not
|
|
6
|
+
* know that section and will not import it: `SettingsForms.importLegacyDocument()`
|
|
7
|
+
* renames the document to `settings.yaml.imported` and then calls
|
|
8
|
+
* `update(section, values)` for every top-level section, where the only renamed
|
|
9
|
+
* keys are the base-bundle ones (`ui-onboarding` → `ui-settings-general`, …).
|
|
10
|
+
* `dsh-connect` reaches `update("dsh-connect", …)` — an entry that does not
|
|
11
|
+
* exist — and is dropped with a warning. The user's channels keep working (their
|
|
12
|
+
* config is in the profile patch) but every pane-only choice silently reverts to
|
|
13
|
+
* its default the first time the pane is opened. This module recovers it.
|
|
14
|
+
*
|
|
15
|
+
* Three properties make the migration safe to run unattended:
|
|
16
|
+
*
|
|
17
|
+
* - **It merges, it does not replace.** `SettingsForms.replace()` resets every
|
|
18
|
+
* live field to its *inherited* layer and then applies the supplied ones, so a
|
|
19
|
+
* section carrying only the legacy keys would clear every pane field the
|
|
20
|
+
* legacy document happens not to mention — `channels` included, which is how a
|
|
21
|
+
* migration ends up disabling every adapter. The section handed to
|
|
22
|
+
* `replace()` is therefore always complete: what is in force now, with the
|
|
23
|
+
* legacy values layered on top.
|
|
24
|
+
* - **It is one-shot.** A marker beside the profile entry records that the
|
|
25
|
+
* import ran, including the benign "there was nothing to import" case, so the
|
|
26
|
+
* legacy document is never re-applied over later user edits. Nothing is marked
|
|
27
|
+
* unless the outcome is final: a document that is missing is marked, a document
|
|
28
|
+
* that is *there but unreadable* is not (see `LegacySkipReason`).
|
|
29
|
+
* - **It never blocks or breaks the load.** A missing parser, an unparseable
|
|
30
|
+
* document or a refused write degrades to one warning line and leaves both
|
|
31
|
+
* files untouched for a retry after the cause is fixed.
|
|
32
|
+
*
|
|
33
|
+
* Secrets cannot travel through it: the legacy section is projected by
|
|
34
|
+
* `sectionOf()`, which keeps declared non-secret keys only, and a parse failure
|
|
35
|
+
* is reported without quoting the document (a YAML error message contains the
|
|
36
|
+
* offending source lines, and the section it would quote holds an `appSecret`).
|
|
37
|
+
* Anything else in that file stays where it is.
|
|
38
|
+
* @module dsh-connect/settings/legacy-import
|
|
39
|
+
*/
|
|
40
|
+
import { mkdirSync, readFileSync, writeFileSync } from "node:fs";
|
|
41
|
+
import { homedir } from "node:os";
|
|
42
|
+
import { dirname, join } from "node:path";
|
|
43
|
+
import { LEGACY_CONNECT_SECTION, mergeSections, sectionOf } from "./namespace.js";
|
|
44
|
+
/**
|
|
45
|
+
* Name of the one-shot marker written beside the profile entry.
|
|
46
|
+
*
|
|
47
|
+
* Namespaced and dotted rather than a plain `${patchPath}.legacy-imported`
|
|
48
|
+
* because the profile directory is shared: every plugin's entry lives in that
|
|
49
|
+
* one `cordis.patch.yml`, so a bare suffix would be a file every plugin with a
|
|
50
|
+
* migration of its own would fight over — and the first one to write it would
|
|
51
|
+
* silently cancel the others.
|
|
52
|
+
*/
|
|
53
|
+
export const LEGACY_IMPORT_MARKER = ".dsh-connect-legacy-imported";
|
|
54
|
+
/**
|
|
55
|
+
* Resolve the Harness home with the same precedence as the host's own
|
|
56
|
+
* `resolveDshHome()`: an explicit path (the host hands us `profileContext.home`,
|
|
57
|
+
* which also covers a configured non-env home), then `$DSH_HOME` — whitespace
|
|
58
|
+
* only counts as unset, so a blank override never resolves the home to the
|
|
59
|
+
* filesystem root — then `~/.dsh`. A `~` in either of the first two is expanded.
|
|
60
|
+
*/
|
|
61
|
+
export function resolveHarnessHome(explicit) {
|
|
62
|
+
const usable = (value) => typeof value === "string" && value.trim().length > 0;
|
|
63
|
+
if (usable(explicit))
|
|
64
|
+
return expandHome(explicit);
|
|
65
|
+
if (usable(process.env.DSH_HOME))
|
|
66
|
+
return expandHome(process.env.DSH_HOME);
|
|
67
|
+
return join(homedir(), ".dsh");
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Trim, and expand a leading `~` the way a shell would.
|
|
71
|
+
*
|
|
72
|
+
* `DSH_HOME=~/.dsh` is a natural thing to write in a shell profile and a
|
|
73
|
+
* perfectly literal string to Node: left alone, the migration reads a directory
|
|
74
|
+
* named `~` under the process cwd, finds nothing there, and marks itself done —
|
|
75
|
+
* silently, permanently, against a home that does not exist. Only the two `~`
|
|
76
|
+
* forms are rewritten, so an absolute path is returned exactly as it was given
|
|
77
|
+
* (which is also what keeps `profileContext.home` whole).
|
|
78
|
+
*/
|
|
79
|
+
function expandHome(value) {
|
|
80
|
+
const trimmed = value.trim();
|
|
81
|
+
if (trimmed === "~")
|
|
82
|
+
return homedir();
|
|
83
|
+
if (trimmed.startsWith("~/") || trimmed.startsWith("~\\"))
|
|
84
|
+
return join(homedir(), trimmed.slice(2));
|
|
85
|
+
return trimmed;
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* The documents to try, in order.
|
|
89
|
+
*
|
|
90
|
+
* `settings.yaml` first: if the host has not run its own legacy import yet, the
|
|
91
|
+
* section is still there. Then `settings.yaml.imported`, which is where the host
|
|
92
|
+
* puts the document after renaming it — the read has to tolerate both because
|
|
93
|
+
* the host's import waits for the loader to settle and may run before or after
|
|
94
|
+
* ours. Finally the JSON state file this plugin used as its own fallback store:
|
|
95
|
+
* its values are unreachable once the live peer exists (`settings-service`
|
|
96
|
+
* prefers `live.read()` whenever it is present), so a user who only ever saved
|
|
97
|
+
* through the fallback path would otherwise lose them silently. That file is
|
|
98
|
+
* written flat — `persist()` stringifies the config itself, with no
|
|
99
|
+
* `dsh-connect` wrapper — so it is read as a section, not as a document.
|
|
100
|
+
*/
|
|
101
|
+
export function legacyCandidates(options) {
|
|
102
|
+
const home = resolveHarnessHome(options.home);
|
|
103
|
+
const candidates = [
|
|
104
|
+
{ path: join(home, "settings.yaml"), shape: "document" },
|
|
105
|
+
{ path: join(home, "settings.yaml.imported"), shape: "document" },
|
|
106
|
+
];
|
|
107
|
+
if (typeof options.statePath === "string" && options.statePath.trim().length > 0) {
|
|
108
|
+
candidates.push({ path: options.statePath, shape: "section" });
|
|
109
|
+
}
|
|
110
|
+
return candidates;
|
|
111
|
+
}
|
|
112
|
+
/**
|
|
113
|
+
* Where the one-shot marker goes: beside the profile entry this import writes to.
|
|
114
|
+
*
|
|
115
|
+
* The anchor matters more than it looks. The marker means "this *profile entry*
|
|
116
|
+
* has already consumed the home's legacy document", so it has to move exactly
|
|
117
|
+
* when that entry moves and not otherwise:
|
|
118
|
+
*
|
|
119
|
+
* - **Not the state file.** `${statePath}.legacy-imported` — what this did until
|
|
120
|
+
* 0.9.2 — hangs off a path the user controls (`stateDir`, the
|
|
121
|
+
* `DSH_CONNECT_STATE_DIR` override, `settingsStatePath`) and can delete. Move
|
|
122
|
+
* the state directory, or delete one JSON file, and the next boot believes no
|
|
123
|
+
* import ever ran, re-reads `settings.yaml.imported` (the host's rename keeps
|
|
124
|
+
* the `dsh-connect:` section intact) and layers the legacy values back over
|
|
125
|
+
* everything changed in the pane since. That is the one outcome the marker
|
|
126
|
+
* exists to prevent, reachable by tidying up a directory.
|
|
127
|
+
* - **Not the harness home.** `$DSH_HOME` is shared by every profile, so a
|
|
128
|
+
* marker there would let a second profile skip an import it never ran. The
|
|
129
|
+
* profile directory is per-profile; it only moves if the profile itself does,
|
|
130
|
+
* which is the one case where re-importing is right.
|
|
131
|
+
*
|
|
132
|
+
* The state-file suffix survives as a fallback for a caller with no entry path
|
|
133
|
+
* (a host too old to hand one over), where it is still better than no marker.
|
|
134
|
+
*/
|
|
135
|
+
export function legacyMarkerPath(options) {
|
|
136
|
+
if (typeof options.markerPath === "string" && options.markerPath.trim().length > 0)
|
|
137
|
+
return options.markerPath;
|
|
138
|
+
if (typeof options.entryPath === "string" && options.entryPath.trim().length > 0) {
|
|
139
|
+
return join(dirname(options.entryPath), LEGACY_IMPORT_MARKER);
|
|
140
|
+
}
|
|
141
|
+
if (typeof options.statePath === "string" && options.statePath.trim().length > 0) {
|
|
142
|
+
return `${options.statePath}.legacy-imported`;
|
|
143
|
+
}
|
|
144
|
+
return undefined;
|
|
145
|
+
}
|
|
146
|
+
/**
|
|
147
|
+
* Read a file, telling "not there" apart from "could not be read".
|
|
148
|
+
*
|
|
149
|
+
* Only `ENOENT` and `ENOTDIR` count as absence — `ENOTDIR` because pointing the
|
|
150
|
+
* home at a regular file makes every child path under it yield that code, which
|
|
151
|
+
* is an absence just as much as a missing directory is. Everything else
|
|
152
|
+
* (permissions, a path that is a directory, an I/O error) is a failure the
|
|
153
|
+
* caller must not mistake for an absence: see `LegacySkipReason`.
|
|
154
|
+
*/
|
|
155
|
+
function readFileOutcome(path) {
|
|
156
|
+
try {
|
|
157
|
+
return { kind: "text", text: readFileSync(path, "utf8") };
|
|
158
|
+
}
|
|
159
|
+
catch (error) {
|
|
160
|
+
const code = error?.code;
|
|
161
|
+
if (code === "ENOENT" || code === "ENOTDIR")
|
|
162
|
+
return { kind: "absent" };
|
|
163
|
+
return { kind: "unreadable", detail: message(error) };
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
/**
|
|
167
|
+
* A parse failure described without quoting the document.
|
|
168
|
+
*
|
|
169
|
+
* The `yaml` package's error message carries the offending source *lines*, and
|
|
170
|
+
* the document being parsed is the one holding `appSecret` — so reporting it
|
|
171
|
+
* verbatim would copy a credential into a boot warning. Its `code` and position
|
|
172
|
+
* are everything a user needs to find the fault in a file they already have
|
|
173
|
+
* open, so those are what is reported. Anything else keeps its first line only,
|
|
174
|
+
* for the same reason.
|
|
175
|
+
*/
|
|
176
|
+
function parseFailureDetail(error) {
|
|
177
|
+
if (typeof error === "object" && error !== null) {
|
|
178
|
+
const { code, linePos } = error;
|
|
179
|
+
if (typeof code === "string") {
|
|
180
|
+
const at = linePos?.[0];
|
|
181
|
+
return at === undefined ? code : `${code} at line ${at.line}, column ${at.col}`;
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
return message(error).split("\n", 1)[0] ?? "";
|
|
185
|
+
}
|
|
186
|
+
/** Parse YAML/JSON text, or throw a message fit for the warning line. */
|
|
187
|
+
async function parseDocument(source) {
|
|
188
|
+
let parser;
|
|
189
|
+
try {
|
|
190
|
+
parser = (await import("yaml"));
|
|
191
|
+
}
|
|
192
|
+
catch (error) {
|
|
193
|
+
throw new TaggedError("parser-missing", `the "yaml" package is unavailable (${message(error)})`);
|
|
194
|
+
}
|
|
195
|
+
try {
|
|
196
|
+
return parser.parse(source);
|
|
197
|
+
}
|
|
198
|
+
catch (error) {
|
|
199
|
+
throw new TaggedError("unparseable", parseFailureDetail(error));
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
/** An error carrying the outcome it should produce. */
|
|
203
|
+
class TaggedError extends Error {
|
|
204
|
+
tag;
|
|
205
|
+
constructor(tag, detail) {
|
|
206
|
+
super(detail);
|
|
207
|
+
this.tag = tag;
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
function message(error) {
|
|
211
|
+
return error instanceof Error ? error.message : String(error);
|
|
212
|
+
}
|
|
213
|
+
function isPlainObject(value) {
|
|
214
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
215
|
+
}
|
|
216
|
+
/**
|
|
217
|
+
* Project an object that *is* a pane section onto the declared keys, or
|
|
218
|
+
* `undefined` when nothing usable is left.
|
|
219
|
+
*
|
|
220
|
+
* `defaultChannels: false` because every caller here is reading a *source*, not
|
|
221
|
+
* writing: an absent `channels` key must stay absent so the in-force value keeps
|
|
222
|
+
* applying. The caller decides what to do about the omissions — which, given
|
|
223
|
+
* `mergeSections`, means the current list survives.
|
|
224
|
+
*/
|
|
225
|
+
function projectSection(raw) {
|
|
226
|
+
if (!isPlainObject(raw))
|
|
227
|
+
return undefined;
|
|
228
|
+
const section = sectionOf(raw, { defaultChannels: false });
|
|
229
|
+
return Object.keys(section).length > 0 ? section : undefined;
|
|
230
|
+
}
|
|
231
|
+
/**
|
|
232
|
+
* Extract the pane section from a parsed `settings.yaml`-style document: the
|
|
233
|
+
* `dsh-connect` mapping, projected onto declared keys, or `undefined` when the
|
|
234
|
+
* document has no such section (or carries nothing usable under it).
|
|
235
|
+
*/
|
|
236
|
+
export function sectionFromDocument(document) {
|
|
237
|
+
if (!isPlainObject(document))
|
|
238
|
+
return undefined;
|
|
239
|
+
return projectSection(document[LEGACY_CONNECT_SECTION]);
|
|
240
|
+
}
|
|
241
|
+
/**
|
|
242
|
+
* Extract the pane section from this plugin's own JSON state file, whose top
|
|
243
|
+
* level is already the section. A `dsh-connect` wrapper is tolerated as well,
|
|
244
|
+
* since pasting values across from the host document is a natural thing to have
|
|
245
|
+
* done — but the flat form is the one the file is actually written in.
|
|
246
|
+
*/
|
|
247
|
+
export function sectionOfStateDocument(document) {
|
|
248
|
+
if (!isPlainObject(document))
|
|
249
|
+
return undefined;
|
|
250
|
+
const nested = document[LEGACY_CONNECT_SECTION];
|
|
251
|
+
return projectSection(isPlainObject(nested) ? nested : document);
|
|
252
|
+
}
|
|
253
|
+
/**
|
|
254
|
+
* Record that the import ran.
|
|
255
|
+
*
|
|
256
|
+
* Best effort — a read-only home must not fail the boot — but not silent: the
|
|
257
|
+
* failure is not the harmless one it looks like. Without the marker the next
|
|
258
|
+
* start re-runs the whole migration, and a re-run layers the legacy values back
|
|
259
|
+
* over everything the user has changed in the pane since. The import it belongs
|
|
260
|
+
* to did its job; saying so is the difference between a user who can look at
|
|
261
|
+
* that warning and one whose settings revert on the next restart for no visible
|
|
262
|
+
* reason.
|
|
263
|
+
*/
|
|
264
|
+
function markAndReport(marker, body, warn) {
|
|
265
|
+
try {
|
|
266
|
+
mkdirSync(dirname(marker), { recursive: true });
|
|
267
|
+
writeFileSync(marker, body, "utf8");
|
|
268
|
+
}
|
|
269
|
+
catch (error) {
|
|
270
|
+
warn(`could not write the one-shot import marker at ${marker} (${message(error)}); ` +
|
|
271
|
+
`the migration will run again on the next start and may re-apply the legacy settings over newer pane changes`);
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
/**
|
|
275
|
+
* Import the pre-0.2 pane settings into the profile entry, once.
|
|
276
|
+
*
|
|
277
|
+
* Never rejects: every failure path is reported through the returned result and
|
|
278
|
+
* (for the ones a user can act on) a single warning line.
|
|
279
|
+
*/
|
|
280
|
+
export async function importLegacySection(options) {
|
|
281
|
+
const { write, current, logger } = options;
|
|
282
|
+
const warn = (text) => logger?.warn?.(`connect: ${text}`);
|
|
283
|
+
const marker = legacyMarkerPath(options);
|
|
284
|
+
if (marker !== undefined) {
|
|
285
|
+
const seen = readFileOutcome(marker);
|
|
286
|
+
if (seen.kind === "unreadable") {
|
|
287
|
+
// Treated as present rather than absent on purpose: re-running would layer
|
|
288
|
+
// the legacy values back over whatever the user has changed since, which is
|
|
289
|
+
// the one outcome the marker exists to prevent.
|
|
290
|
+
warn(`the import marker at ${marker} could not be read (${seen.detail}); treating the one-shot migration as already done rather than re-applying the legacy settings over newer changes`);
|
|
291
|
+
return { imported: false, skipped: "already-imported" };
|
|
292
|
+
}
|
|
293
|
+
if (seen.kind === "text")
|
|
294
|
+
return { imported: false, skipped: "already-imported" };
|
|
295
|
+
}
|
|
296
|
+
if (write === undefined) {
|
|
297
|
+
// No store to write to. Nothing is marked, so a host that gains a settings
|
|
298
|
+
// service later still gets the migration.
|
|
299
|
+
return { imported: false, skipped: "not-live" };
|
|
300
|
+
}
|
|
301
|
+
const reads = legacyCandidates(options).map((candidate) => ({ candidate, read: readFileOutcome(candidate.path) }));
|
|
302
|
+
const unreadable = reads.flatMap((entry) => entry.read.kind === "unreadable" ? [{ path: entry.candidate.path, detail: entry.read.detail }] : []);
|
|
303
|
+
if (unreadable.length > 0) {
|
|
304
|
+
// Deliberately not folded into `no-document`: this is the one branch where
|
|
305
|
+
// the user's settings may be sitting in a file we failed to open, so nothing
|
|
306
|
+
// is imported *and nothing is marked* — the next start tries again. Saying
|
|
307
|
+
// which file and why is the whole point of splitting the outcome; the usual
|
|
308
|
+
// causes are a permission, a path that is not what it looks like (a directory
|
|
309
|
+
// named `settings.yaml`), or a `~` nobody expanded.
|
|
310
|
+
for (const entry of unreadable) {
|
|
311
|
+
warn(`could not read the legacy settings candidate at ${entry.path} (${entry.detail}); nothing was imported and nothing was marked, so the migration retries on the next start`);
|
|
312
|
+
}
|
|
313
|
+
return { imported: false, skipped: "unreadable" };
|
|
314
|
+
}
|
|
315
|
+
if (reads.every((entry) => entry.read.kind === "absent")) {
|
|
316
|
+
if (marker !== undefined)
|
|
317
|
+
markAndReport(marker, `dsh-connect: no legacy settings document found\n`, warn);
|
|
318
|
+
return { imported: false, skipped: "no-document" };
|
|
319
|
+
}
|
|
320
|
+
let source;
|
|
321
|
+
let legacy;
|
|
322
|
+
for (const { candidate, read } of reads) {
|
|
323
|
+
if (read.kind !== "text")
|
|
324
|
+
continue;
|
|
325
|
+
let document;
|
|
326
|
+
try {
|
|
327
|
+
document = await parseDocument(read.text);
|
|
328
|
+
}
|
|
329
|
+
catch (error) {
|
|
330
|
+
// A malformed document stops the whole migration rather than falling
|
|
331
|
+
// through to the next candidate. The next *document* is the same file the
|
|
332
|
+
// host renamed, so it is a stale copy of the one that just failed, and the
|
|
333
|
+
// state file holds the same user's older settings — importing either in
|
|
334
|
+
// place of the section the user is looking at would be a silent
|
|
335
|
+
// substitution, and the one they would least expect. Nothing is marked, so
|
|
336
|
+
// fixing the file and restarting retries the whole thing.
|
|
337
|
+
const tag = error instanceof TaggedError ? error.tag : "unparseable";
|
|
338
|
+
warn(tag === "parser-missing"
|
|
339
|
+
? `the legacy settings at ${candidate.path} were not imported: ${message(error)}; reinstall dsh-connect to restore the migration`
|
|
340
|
+
: `the legacy settings at ${candidate.path} could not be parsed (${message(error)}); the ${LEGACY_CONNECT_SECTION} section was left in place — fix it and restart to import it`);
|
|
341
|
+
return { imported: false, skipped: tag };
|
|
342
|
+
}
|
|
343
|
+
const found = candidate.shape === "section" ? sectionOfStateDocument(document) : sectionFromDocument(document);
|
|
344
|
+
if (found !== undefined) {
|
|
345
|
+
source = candidate.path;
|
|
346
|
+
legacy = found;
|
|
347
|
+
break;
|
|
348
|
+
}
|
|
349
|
+
}
|
|
350
|
+
if (legacy === undefined || source === undefined) {
|
|
351
|
+
if (marker !== undefined) {
|
|
352
|
+
markAndReport(marker, `dsh-connect: no ${LEGACY_CONNECT_SECTION} section to import\n`, warn);
|
|
353
|
+
}
|
|
354
|
+
return { imported: false, skipped: "no-section" };
|
|
355
|
+
}
|
|
356
|
+
// Complete section: what is in force now, with the legacy values on top. See
|
|
357
|
+
// the module doc — a partial section would reset every field it omits.
|
|
358
|
+
const section = mergeSections(current, legacy);
|
|
359
|
+
try {
|
|
360
|
+
await write(section);
|
|
361
|
+
}
|
|
362
|
+
catch (error) {
|
|
363
|
+
warn(`could not import the legacy ${LEGACY_CONNECT_SECTION} settings from ${source} into this plugin's profile entry (${message(error)}); ` +
|
|
364
|
+
`the section was left in place — fix the cause and restart to import it`);
|
|
365
|
+
return { imported: false, source, skipped: "write-failed" };
|
|
366
|
+
}
|
|
367
|
+
if (marker !== undefined) {
|
|
368
|
+
markAndReport(marker, `dsh-connect: imported the ${LEGACY_CONNECT_SECTION} section from ${source}\n`, warn);
|
|
369
|
+
}
|
|
370
|
+
logger?.info?.(`connect: imported the legacy ${LEGACY_CONNECT_SECTION} settings from ${source}`);
|
|
371
|
+
return { imported: true, source, section };
|
|
372
|
+
}
|
|
373
|
+
//# sourceMappingURL=legacy-import.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"legacy-import.js","sourceRoot":"","sources":["../../src/settings/legacy-import.ts"],"names":[],"mappings":"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"}
|