@zodal/dials-ui 0.1.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.cjs ADDED
@@ -0,0 +1,597 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // src/index.ts
21
+ var index_exports = {};
22
+ __export(index_exports, {
23
+ PRIORITY: () => import_ui.PRIORITY,
24
+ alwaysMatch: () => alwaysMatch,
25
+ and: () => import_ui.and,
26
+ applyLayerPatch: () => applyLayerPatch,
27
+ applyScopedFilters: () => applyScopedFilters,
28
+ createLocalStorageProfileStorage: () => createLocalStorageProfileStorage,
29
+ createMemoryProfileStorage: () => createMemoryProfileStorage,
30
+ createProfileStore: () => createProfileStore,
31
+ createRendererRegistry: () => import_ui.createRendererRegistry,
32
+ createSettingsRendererRegistry: () => createSettingsRendererRegistry,
33
+ createSettingsStore: () => createSettingsStore,
34
+ createSubstringSearchProvider: () => createSubstringSearchProvider,
35
+ describeSettings: () => describeSettings,
36
+ dirtyKeys: () => dirtyKeys,
37
+ editWidgetIs: () => import_ui.editWidgetIs,
38
+ fieldNameMatches: () => import_ui.fieldNameMatches,
39
+ hasRefinement: () => import_ui.hasRefinement,
40
+ isBoolean: () => isBoolean,
41
+ isDirty: () => isDirty,
42
+ isEnum: () => isEnum,
43
+ isNumber: () => isNumber,
44
+ isString: () => isString,
45
+ isStructuredValue: () => isStructuredValue,
46
+ metaMatches: () => import_ui.metaMatches,
47
+ or: () => import_ui.or,
48
+ parseScopedQuery: () => parseScopedQuery,
49
+ recordLayerChange: () => recordLayerChange,
50
+ resetToDefault: () => resetToDefault,
51
+ searchSettings: () => searchSettings,
52
+ secretRoleIs: () => secretRoleIs,
53
+ toFieldStates: () => toFieldStates,
54
+ toGroups: () => toGroups,
55
+ toIndexableSettings: () => toIndexableSettings,
56
+ toSettingsForm: () => toSettingsForm,
57
+ unsetKey: () => unsetKey,
58
+ widgetKindFor: () => widgetKindFor,
59
+ zodTypeIs: () => import_ui.zodTypeIs
60
+ });
61
+ module.exports = __toCommonJS(index_exports);
62
+
63
+ // src/widgets.ts
64
+ var KNOWN_WIDGETS = /* @__PURE__ */ new Set([
65
+ "switch",
66
+ "select",
67
+ "radio",
68
+ "slider",
69
+ "number",
70
+ "text",
71
+ "textarea",
72
+ "secret",
73
+ "color",
74
+ "date",
75
+ "path",
76
+ "object",
77
+ "array",
78
+ "rawJson"
79
+ ]);
80
+ function widgetKindFor(input) {
81
+ if (typeof input.metaWidget === "string" && KNOWN_WIDGETS.has(input.metaWidget)) {
82
+ return input.metaWidget;
83
+ }
84
+ if (input.sensitivity === "secret") return "secret";
85
+ switch (input.zodType) {
86
+ case "boolean":
87
+ return "switch";
88
+ case "enum":
89
+ return input.enumValues && input.enumValues.length > 0 && input.enumValues.length <= 4 ? "radio" : "select";
90
+ case "number":
91
+ return input.bounds && input.bounds.min !== void 0 && input.bounds.max !== void 0 ? "slider" : "number";
92
+ case "string":
93
+ return "text";
94
+ case "object":
95
+ return "object";
96
+ case "array":
97
+ return "array";
98
+ default:
99
+ return "rawJson";
100
+ }
101
+ }
102
+
103
+ // src/registry.ts
104
+ var import_ui = require("@zodal/ui");
105
+ function secretRoleIs() {
106
+ return (_field, ctx) => ctx.sensitivity === "secret" ? import_ui.PRIORITY.OVERRIDE : -1;
107
+ }
108
+ function isStructuredValue() {
109
+ return (field, ctx) => ctx.structured === true || field.zodType === "object" || field.zodType === "array" ? import_ui.PRIORITY.LIBRARY : -1;
110
+ }
111
+ function isBoolean() {
112
+ return (0, import_ui.zodTypeIs)("boolean");
113
+ }
114
+ function isEnum() {
115
+ return (0, import_ui.zodTypeIs)("enum");
116
+ }
117
+ function isNumber() {
118
+ return (0, import_ui.zodTypeIs)("number");
119
+ }
120
+ function isString() {
121
+ return (0, import_ui.zodTypeIs)("string");
122
+ }
123
+ function alwaysMatch(priority = import_ui.PRIORITY.FALLBACK) {
124
+ return () => priority;
125
+ }
126
+ function createSettingsRendererRegistry() {
127
+ return (0, import_ui.createRendererRegistry)();
128
+ }
129
+
130
+ // src/introspect.ts
131
+ var import_dials_core = require("@zodal/dials-core");
132
+ var import_core = require("@zodal/core");
133
+ function safe(fn) {
134
+ try {
135
+ return fn();
136
+ } catch {
137
+ return void 0;
138
+ }
139
+ }
140
+ function uniqueStrings(values) {
141
+ return [...new Set(values)];
142
+ }
143
+ function describeSettings(dials, options = {}) {
144
+ const shape = (0, import_dials_core.getObjectShape)(dials.schema);
145
+ return dials.keys.map((key) => {
146
+ const field = shape[key];
147
+ const meta = field ? (0, import_dials_core.readMeta)(field) : {};
148
+ const zodType = field ? (0, import_dials_core.baseType)(field) : "unknown";
149
+ const sensitivity = dials.sensitivityFor(key);
150
+ const enumValues = field ? safe(() => (0, import_core.getEnumValues)(field)) : void 0;
151
+ const rawBounds = field ? safe(() => (0, import_core.getNumericBounds)(field)) : void 0;
152
+ const min = rawBounds != null && Number.isFinite(rawBounds.min) ? rawBounds.min : void 0;
153
+ const max = rawBounds != null && Number.isFinite(rawBounds.max) ? rawBounds.max : void 0;
154
+ const bounds = min !== void 0 || max !== void 0 ? { ...min !== void 0 ? { min } : {}, ...max !== void 0 ? { max } : {} } : void 0;
155
+ const metaFacets = Array.isArray(meta.facets) ? meta.facets.map((f) => String(f)) : [];
156
+ const facets = uniqueStrings([...metaFacets, ...options.facets?.[key] ?? []]);
157
+ const advanced = facets.includes("advanced") || meta.advanced === true;
158
+ const required = field ? !field.safeParse(void 0).success && dials.defaults[key] === void 0 : false;
159
+ return {
160
+ key,
161
+ label: typeof meta.title === "string" ? meta.title : (0, import_core.humanizeFieldName)(key),
162
+ description: typeof meta.description === "string" ? meta.description : void 0,
163
+ widget: widgetKindFor({ zodType, sensitivity, bounds, enumValues, metaWidget: meta.editWidget }),
164
+ zodType,
165
+ required,
166
+ readOnly: meta.readOnly === true || meta.editable === false,
167
+ hidden: meta.hidden === true,
168
+ sensitivity,
169
+ mergeStrategy: dials.mergeStrategyFor(key),
170
+ // Never put a secret's plaintext default into the headless config — a renderer that prefills
171
+ // from `defaultValue` would expose it. Secrets carry no default here (the secret backend owns it).
172
+ defaultValue: sensitivity === "secret" ? void 0 : dials.defaults[key],
173
+ enumValues: enumValues && enumValues.length > 0 ? enumValues : void 0,
174
+ bounds,
175
+ facets,
176
+ advanced,
177
+ order: typeof meta.order === "number" ? meta.order : void 0,
178
+ isStructured: zodType === "object" || zodType === "array"
179
+ };
180
+ });
181
+ }
182
+
183
+ // src/facets.ts
184
+ function humanize(id) {
185
+ return id.replace(/^@/, "").replace(/[._-]+/g, " ").replace(/\b\w/g, (c) => c.toUpperCase());
186
+ }
187
+ function computedGroups(fields, result) {
188
+ const out = [];
189
+ const add = (id, title, keys, order) => {
190
+ if (keys.length > 0) out.push({ id, title, order, settingKeys: keys, computed: true });
191
+ };
192
+ const fieldKeys = new Set(fields.map((f) => f.key));
193
+ add("@secret", "Secrets", fields.filter((f) => f.sensitivity === "secret").map((f) => f.key), 2e3);
194
+ add("@advanced", "Advanced", fields.filter((f) => f.advanced).map((f) => f.key), 2001);
195
+ if (result) {
196
+ const modified = Object.keys(result.provenance).filter((k) => fieldKeys.has(k) && result.provenance[k].winningScope !== "default");
197
+ const managed = Object.keys(result.provenance).filter((k) => fieldKeys.has(k) && result.provenance[k].managed);
198
+ add("@modified", "Modified", modified, 2002);
199
+ add("@managed", "Managed by policy", managed, 2003);
200
+ }
201
+ return out;
202
+ }
203
+ function toGroups(fields, result, options = {}) {
204
+ const declared = new Map((options.facetDefs ?? []).map((f) => [f.id, f]));
205
+ const forward = /* @__PURE__ */ new Map();
206
+ for (const field of fields) {
207
+ for (const facet of field.facets) {
208
+ const list = forward.get(facet);
209
+ if (list) list.push(field.key);
210
+ else forward.set(facet, [field.key]);
211
+ }
212
+ }
213
+ const groups = [];
214
+ for (const [facet, keys] of forward) {
215
+ const def = declared.get(facet);
216
+ groups.push({ id: facet, title: def?.title ?? humanize(facet), order: def?.order ?? 100, settingKeys: keys, computed: false });
217
+ }
218
+ const seenIds = new Set(groups.map((g) => g.id));
219
+ const ungrouped = fields.filter((f) => f.facets.length === 0).map((f) => f.key);
220
+ if (ungrouped.length > 0 && !seenIds.has("_ungrouped")) {
221
+ groups.push({ id: "_ungrouped", title: options.ungroupedTitle ?? "Other", order: 1e3, settingKeys: ungrouped, computed: false });
222
+ seenIds.add("_ungrouped");
223
+ }
224
+ if (options.computedGroups !== false) {
225
+ for (const group of computedGroups(fields, result)) {
226
+ if (!seenIds.has(group.id)) {
227
+ groups.push(group);
228
+ seenIds.add(group.id);
229
+ }
230
+ }
231
+ }
232
+ return groups.sort((a, b) => a.order - b.order || a.title.localeCompare(b.title));
233
+ }
234
+
235
+ // src/search.ts
236
+ function toIndexableSettings(fields) {
237
+ return fields.map((f) => ({
238
+ key: f.key,
239
+ title: f.label,
240
+ description: f.description ?? "",
241
+ enumLabels: f.enumValues ?? [],
242
+ facets: f.facets,
243
+ keywords: [f.key, ...f.key.split(/[._\-/]/).filter(Boolean)]
244
+ }));
245
+ }
246
+ function createSubstringSearchProvider(settings, options = {}) {
247
+ const fields = options.fields ?? ["title", "description", "enumLabels", "facets", "keywords"];
248
+ const haystacks = settings.map((s) => ({
249
+ key: s.key,
250
+ parts: {
251
+ title: s.title.toLowerCase(),
252
+ description: s.description.toLowerCase(),
253
+ enumLabels: s.enumLabels.join(" ").toLowerCase(),
254
+ facets: s.facets.join(" ").toLowerCase(),
255
+ keywords: s.keywords.join(" ").toLowerCase()
256
+ }
257
+ }));
258
+ return {
259
+ search(query) {
260
+ const q = query.trim().toLowerCase();
261
+ if (!q) return settings.map((s) => s.key);
262
+ const scored = [];
263
+ for (const h of haystacks) {
264
+ let score = 0;
265
+ for (const f of fields) {
266
+ if (h.parts[f].includes(q)) score += f === "title" || f === "keywords" ? 3 : 1;
267
+ }
268
+ if (score > 0) scored.push({ key: h.key, score });
269
+ }
270
+ scored.sort((a, b) => b.score - a.score);
271
+ return scored.map((s) => s.key);
272
+ }
273
+ };
274
+ }
275
+ function parseScopedQuery(query) {
276
+ const tokens = query.split(/\s+/).filter(Boolean);
277
+ const filters = [];
278
+ const text = [];
279
+ for (const tok of tokens) {
280
+ const m = /^@([a-z]+)(?::(.+))?$/i.exec(tok);
281
+ if (!m) {
282
+ text.push(tok);
283
+ continue;
284
+ }
285
+ const name = m[1].toLowerCase();
286
+ const value = m[2];
287
+ if (name === "modified") filters.push({ type: "modified" });
288
+ else if (name === "managed") filters.push({ type: "managed" });
289
+ else if (name === "secret") filters.push({ type: "secret" });
290
+ else if (name === "advanced") filters.push({ type: "advanced" });
291
+ else if (name === "facet" && value) filters.push({ type: "facet", value });
292
+ else if (name === "scope" && value) filters.push({ type: "scope", value });
293
+ else text.push(tok);
294
+ }
295
+ return { filters, text: text.join(" ") };
296
+ }
297
+ function applyScopedFilters(keys, filters, context) {
298
+ if (filters.length === 0) return keys;
299
+ const byKey = new Map(context.fields.map((f) => [f.key, f]));
300
+ const prov = context.result?.provenance ?? {};
301
+ return keys.filter(
302
+ (key) => filters.every((filter) => {
303
+ const f = byKey.get(key);
304
+ switch (filter.type) {
305
+ case "secret":
306
+ return f?.sensitivity === "secret";
307
+ case "advanced":
308
+ return f?.advanced === true;
309
+ case "facet":
310
+ return f?.facets.includes(filter.value) ?? false;
311
+ case "modified":
312
+ return prov[key] ? prov[key].winningScope !== "default" : false;
313
+ case "managed":
314
+ return prov[key]?.managed === true;
315
+ case "scope":
316
+ return prov[key]?.winningScope === filter.value;
317
+ default:
318
+ return true;
319
+ }
320
+ })
321
+ );
322
+ }
323
+ function searchSettings(query, provider, context) {
324
+ const { filters, text } = parseScopedQuery(query);
325
+ const allKeys = context.fields.map((f) => f.key);
326
+ const filtered = new Set(applyScopedFilters(allKeys, filters, context));
327
+ const ranked = text ? provider.search(text) : allKeys;
328
+ return ranked.filter((k) => filtered.has(k));
329
+ }
330
+
331
+ // src/lifecycle.ts
332
+ var import_dials_core2 = require("@zodal/dials-core");
333
+ function normalize(value) {
334
+ if (value === import_dials_core2.UNSET) return "\0unset";
335
+ if (value === void 0) return "\0undefined";
336
+ return JSON.stringify(value);
337
+ }
338
+ function dirtyKeys(current, baseline) {
339
+ const keys = /* @__PURE__ */ new Set([...Object.keys(current), ...Object.keys(baseline)]);
340
+ const out = [];
341
+ for (const key of keys) {
342
+ const inCurrent = Object.prototype.hasOwnProperty.call(current, key);
343
+ const inBaseline = Object.prototype.hasOwnProperty.call(baseline, key);
344
+ if (inCurrent !== inBaseline || normalize(current[key]) !== normalize(baseline[key])) out.push(key);
345
+ }
346
+ return out;
347
+ }
348
+ function isDirty(current, baseline) {
349
+ return dirtyKeys(current, baseline).length > 0;
350
+ }
351
+ function resetToDefault(layer, key) {
352
+ const out = { ...layer };
353
+ delete out[key];
354
+ return out;
355
+ }
356
+ function unsetKey(layer, key) {
357
+ return { ...layer, [key]: import_dials_core2.UNSET };
358
+ }
359
+ function recordLayerChange(before, after) {
360
+ const b = (0, import_dials_core2.serializeLayer)(before);
361
+ const a = (0, import_dials_core2.serializeLayer)(after);
362
+ const forward = (0, import_dials_core2.diffJsonPatch)(b, a);
363
+ return { forward, inverse: (0, import_dials_core2.invertJsonPatch)(forward, b) };
364
+ }
365
+ function applyLayerPatch(layer, ops) {
366
+ const serialized = (0, import_dials_core2.applyJsonPatch)((0, import_dials_core2.serializeLayer)(layer), ops);
367
+ return (0, import_dials_core2.deserializeLayer)(serialized);
368
+ }
369
+
370
+ // src/form.ts
371
+ var import_dials_core3 = require("@zodal/dials-core");
372
+ function toSettingsForm(dials, options = {}) {
373
+ const all = describeSettings(dials, { facets: options.facets });
374
+ const visible = options.includeHidden ? all : all.filter((f) => !f.hidden);
375
+ const fields = [...visible].sort((a, b) => (a.order ?? 1e3) - (b.order ?? 1e3) || a.label.localeCompare(b.label));
376
+ const groups = toGroups(fields, options.result, {
377
+ facetDefs: options.facetDefs,
378
+ computedGroups: options.computedGroups,
379
+ ungroupedTitle: options.ungroupedTitle
380
+ });
381
+ return { fields, groups };
382
+ }
383
+ function toFieldStates(fields, result, dirty = []) {
384
+ const dirtySet = new Set(dirty);
385
+ const states = {};
386
+ for (const field of fields) {
387
+ const prov = result.provenance[field.key];
388
+ const raw = result.effective[field.key];
389
+ const value = field.sensitivity === "secret" && !(0, import_dials_core3.isSecretRef)(raw) ? (0, import_dials_core3.makeSecretRef)(field.key, raw !== void 0 && raw !== null && raw !== "") : raw;
390
+ states[field.key] = {
391
+ value,
392
+ source: prov?.winningScope,
393
+ managed: prov?.managed ?? false,
394
+ shadowed: (prov?.shadowed.length ?? 0) > 0,
395
+ dirty: dirtySet.has(field.key)
396
+ };
397
+ }
398
+ return states;
399
+ }
400
+
401
+ // src/store.ts
402
+ var import_dials_core4 = require("@zodal/dials-core");
403
+ function createSettingsStore(dials, options = {}) {
404
+ const scopeId = options.scope ?? "user";
405
+ const maskSecrets = options.maskSecrets !== false;
406
+ const listeners = /* @__PURE__ */ new Set();
407
+ let scopes = [...options.scopes ?? []];
408
+ let layer = { ...options.layer ?? {} };
409
+ let baseline = { ...layer };
410
+ let state;
411
+ const recompute = () => {
412
+ const raw = dials.resolve([...scopes, { scope: scopeId, layer }]);
413
+ const validation = dials.validate(raw.effective);
414
+ const shown = maskSecrets ? (0, import_dials_core4.maskEffectiveResult)(raw, dials.sensitivityFor) : raw;
415
+ state = {
416
+ effective: shown.effective,
417
+ provenance: shown.provenance,
418
+ conflicts: shown.conflicts,
419
+ layer: { ...layer },
420
+ scopes: [...scopes],
421
+ dirty: dirtyKeys(layer, baseline),
422
+ validation
423
+ };
424
+ for (const listener of [...listeners]) {
425
+ try {
426
+ listener();
427
+ } catch (error) {
428
+ options.onListenerError?.(error);
429
+ }
430
+ }
431
+ };
432
+ recompute();
433
+ const mutate = (next) => {
434
+ layer = next;
435
+ recompute();
436
+ };
437
+ return {
438
+ getState: () => state,
439
+ subscribe(listener) {
440
+ listeners.add(listener);
441
+ return () => listeners.delete(listener);
442
+ },
443
+ set: (key, value) => {
444
+ if (Object.prototype.hasOwnProperty.call(layer, key) && Object.is(layer[key], value)) return;
445
+ mutate({ ...layer, [key]: value });
446
+ },
447
+ unset: (key) => mutate({ ...layer, [key]: import_dials_core4.UNSET }),
448
+ reset: (key) => {
449
+ const next = { ...layer };
450
+ delete next[key];
451
+ mutate(next);
452
+ },
453
+ setLayer: (next) => mutate({ ...next }),
454
+ setScopes: (next) => {
455
+ scopes = [...next];
456
+ recompute();
457
+ },
458
+ markSaved: () => {
459
+ baseline = { ...layer };
460
+ recompute();
461
+ },
462
+ get: (key) => state.effective[key],
463
+ explain: (key) => state.provenance[key]
464
+ };
465
+ }
466
+
467
+ // src/profiles.ts
468
+ var import_dials_core5 = require("@zodal/dials-core");
469
+ function createMemoryProfileStorage(initial = []) {
470
+ let profiles = initial.map((p) => ({ ...p }));
471
+ return {
472
+ read: () => Promise.resolve(profiles.map((p) => ({ ...p }))),
473
+ write: (next) => {
474
+ profiles = next.map((p) => ({ ...p }));
475
+ return Promise.resolve();
476
+ }
477
+ };
478
+ }
479
+ function createLocalStorageProfileStorage(storageKey = "zodal-dials.profiles") {
480
+ const ls = globalThis.localStorage;
481
+ if (!ls) throw new Error("createLocalStorageProfileStorage: localStorage is not available");
482
+ return {
483
+ read: () => {
484
+ const raw = ls.getItem(storageKey);
485
+ if (!raw) return Promise.resolve([]);
486
+ try {
487
+ const parsed = JSON.parse(raw);
488
+ return Promise.resolve(Array.isArray(parsed) ? parsed : []);
489
+ } catch {
490
+ return Promise.resolve([]);
491
+ }
492
+ },
493
+ write: (profiles) => {
494
+ ls.setItem(storageKey, JSON.stringify(profiles));
495
+ return Promise.resolve();
496
+ }
497
+ };
498
+ }
499
+ function createProfileStore(storage, options = {}) {
500
+ const findIndex = (profiles, name) => profiles.findIndex((p) => p.name === name);
501
+ let queue = Promise.resolve();
502
+ const enqueue = (run) => {
503
+ const result = queue.then(run, run);
504
+ queue = result.then(
505
+ () => void 0,
506
+ () => void 0
507
+ );
508
+ return result;
509
+ };
510
+ return {
511
+ async list() {
512
+ const profiles = await storage.read();
513
+ return profiles.map(({ name, meta }) => ({ name, ...meta ? { meta } : {} }));
514
+ },
515
+ save(name, layer, meta) {
516
+ const trimmed = name.trim();
517
+ if (!trimmed) return Promise.reject(new Error("profile name cannot be empty"));
518
+ return enqueue(async () => {
519
+ const profiles = await storage.read();
520
+ let serialized = (0, import_dials_core5.serializeLayer)(layer);
521
+ if (options.sensitivityFor) serialized = (0, import_dials_core5.redactSecretsFromLayer)(serialized, options.sensitivityFor);
522
+ const entry = { name: trimmed, layer: serialized, ...meta ? { meta } : {} };
523
+ const index = findIndex(profiles, trimmed);
524
+ if (index >= 0) profiles[index] = entry;
525
+ else profiles.push(entry);
526
+ await storage.write(profiles);
527
+ });
528
+ },
529
+ async load(name) {
530
+ const profiles = await storage.read();
531
+ const found = profiles[findIndex(profiles, name)];
532
+ return found ? (0, import_dials_core5.deserializeLayer)(found.layer) : void 0;
533
+ },
534
+ remove(name) {
535
+ return enqueue(async () => {
536
+ const profiles = await storage.read();
537
+ await storage.write(profiles.filter((p) => p.name !== name));
538
+ });
539
+ },
540
+ rename(from, to) {
541
+ if (from === to) return Promise.resolve();
542
+ return enqueue(async () => {
543
+ const profiles = await storage.read();
544
+ if (findIndex(profiles, to) >= 0) throw new Error(`profile "${to}" already exists`);
545
+ const index = findIndex(profiles, from);
546
+ if (index < 0) return;
547
+ profiles[index] = { ...profiles[index], name: to };
548
+ await storage.write(profiles);
549
+ });
550
+ },
551
+ async has(name) {
552
+ const profiles = await storage.read();
553
+ return findIndex(profiles, name) >= 0;
554
+ }
555
+ };
556
+ }
557
+ // Annotate the CommonJS export names for ESM import in node:
558
+ 0 && (module.exports = {
559
+ PRIORITY,
560
+ alwaysMatch,
561
+ and,
562
+ applyLayerPatch,
563
+ applyScopedFilters,
564
+ createLocalStorageProfileStorage,
565
+ createMemoryProfileStorage,
566
+ createProfileStore,
567
+ createRendererRegistry,
568
+ createSettingsRendererRegistry,
569
+ createSettingsStore,
570
+ createSubstringSearchProvider,
571
+ describeSettings,
572
+ dirtyKeys,
573
+ editWidgetIs,
574
+ fieldNameMatches,
575
+ hasRefinement,
576
+ isBoolean,
577
+ isDirty,
578
+ isEnum,
579
+ isNumber,
580
+ isString,
581
+ isStructuredValue,
582
+ metaMatches,
583
+ or,
584
+ parseScopedQuery,
585
+ recordLayerChange,
586
+ resetToDefault,
587
+ searchSettings,
588
+ secretRoleIs,
589
+ toFieldStates,
590
+ toGroups,
591
+ toIndexableSettings,
592
+ toSettingsForm,
593
+ unsetKey,
594
+ widgetKindFor,
595
+ zodTypeIs
596
+ });
597
+ //# sourceMappingURL=index.cjs.map