dsh-connect 0.8.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.
Files changed (117) hide show
  1. package/README.i18n.yaml +2 -2
  2. package/README.md +236 -18
  3. package/README.zh.md +185 -18
  4. package/client/client.js +517 -84
  5. package/client/client.js.map +4 -4
  6. package/client/locale.mjs +227 -0
  7. package/client/panel-state.mjs +54 -0
  8. package/client/settings-client.mjs +282 -61
  9. package/docs/images/settings-advanced-en.png +0 -0
  10. package/docs/images/settings-advanced-zh.png +0 -0
  11. package/docs/images/settings-defaults-en.png +0 -0
  12. package/docs/images/settings-defaults-zh.png +0 -0
  13. package/docs/images/settings-overview-en.png +0 -0
  14. package/docs/images/settings-overview-zh.png +0 -0
  15. package/lib/binding.d.ts.map +1 -1
  16. package/lib/binding.js +2 -2
  17. package/lib/binding.js.map +1 -1
  18. package/lib/channels/dingtalk/index.d.ts +49 -49
  19. package/lib/channels/dingtalk/index.d.ts.map +1 -1
  20. package/lib/channels/dingtalk/message.d.ts.map +1 -1
  21. package/lib/channels/dingtalk/message.js +7 -0
  22. package/lib/channels/dingtalk/message.js.map +1 -1
  23. package/lib/channels/feishu/adapter.d.ts +14 -13
  24. package/lib/channels/feishu/adapter.d.ts.map +1 -1
  25. package/lib/channels/feishu/adapter.js +122 -56
  26. package/lib/channels/feishu/adapter.js.map +1 -1
  27. package/lib/channels/feishu/i18n.d.ts +2 -0
  28. package/lib/channels/feishu/i18n.d.ts.map +1 -1
  29. package/lib/channels/feishu/i18n.js +2 -0
  30. package/lib/channels/feishu/i18n.js.map +1 -1
  31. package/lib/channels/feishu/index.d.ts +48 -27
  32. package/lib/channels/feishu/index.d.ts.map +1 -1
  33. package/lib/channels/feishu/index.js +32 -6
  34. package/lib/channels/feishu/index.js.map +1 -1
  35. package/lib/channels/telegram/adapter.d.ts.map +1 -1
  36. package/lib/channels/telegram/adapter.js +7 -1
  37. package/lib/channels/telegram/adapter.js.map +1 -1
  38. package/lib/channels/telegram/index.d.ts +13 -13
  39. package/lib/channels/telegram/index.d.ts.map +1 -1
  40. package/lib/channels/web/adapter.d.ts +3 -1
  41. package/lib/channels/web/adapter.d.ts.map +1 -1
  42. package/lib/channels/web/adapter.js +3 -1
  43. package/lib/channels/web/adapter.js.map +1 -1
  44. package/lib/channels/web/index.d.ts +5 -5
  45. package/lib/channels/web/index.d.ts.map +1 -1
  46. package/lib/chat-key.d.ts +29 -0
  47. package/lib/chat-key.d.ts.map +1 -0
  48. package/lib/chat-key.js +38 -0
  49. package/lib/chat-key.js.map +1 -0
  50. package/lib/index.d.ts +57 -63
  51. package/lib/index.d.ts.map +1 -1
  52. package/lib/index.js +330 -55
  53. package/lib/index.js.map +1 -1
  54. package/lib/interaction.d.ts +90 -50
  55. package/lib/interaction.d.ts.map +1 -1
  56. package/lib/interaction.js +233 -272
  57. package/lib/interaction.js.map +1 -1
  58. package/lib/retry.d.ts.map +1 -1
  59. package/lib/retry.js +7 -1
  60. package/lib/retry.js.map +1 -1
  61. package/lib/runner.d.ts +54 -0
  62. package/lib/runner.d.ts.map +1 -1
  63. package/lib/runner.js +158 -23
  64. package/lib/runner.js.map +1 -1
  65. package/lib/scheduler.d.ts.map +1 -1
  66. package/lib/scheduler.js +2 -2
  67. package/lib/scheduler.js.map +1 -1
  68. package/lib/service.d.ts +16 -0
  69. package/lib/service.d.ts.map +1 -1
  70. package/lib/service.js +46 -4
  71. package/lib/service.js.map +1 -1
  72. package/lib/settings/channel-runtime.d.ts +75 -0
  73. package/lib/settings/channel-runtime.d.ts.map +1 -0
  74. package/lib/settings/channel-runtime.js +165 -0
  75. package/lib/settings/channel-runtime.js.map +1 -0
  76. package/lib/settings/channels.d.ts +11 -0
  77. package/lib/settings/channels.d.ts.map +1 -1
  78. package/lib/settings/channels.js +31 -0
  79. package/lib/settings/channels.js.map +1 -1
  80. package/lib/settings/credential-store.d.ts +52 -6
  81. package/lib/settings/credential-store.d.ts.map +1 -1
  82. package/lib/settings/credential-store.js +92 -18
  83. package/lib/settings/credential-store.js.map +1 -1
  84. package/lib/settings/legacy-import.d.ts +190 -0
  85. package/lib/settings/legacy-import.d.ts.map +1 -0
  86. package/lib/settings/legacy-import.js +373 -0
  87. package/lib/settings/legacy-import.js.map +1 -0
  88. package/lib/settings/namespace.d.ts +263 -0
  89. package/lib/settings/namespace.d.ts.map +1 -0
  90. package/lib/settings/namespace.js +287 -0
  91. package/lib/settings/namespace.js.map +1 -0
  92. package/lib/settings/secret-disclosure.d.ts +50 -0
  93. package/lib/settings/secret-disclosure.d.ts.map +1 -0
  94. package/lib/settings/secret-disclosure.js +132 -0
  95. package/lib/settings/secret-disclosure.js.map +1 -0
  96. package/lib/settings/settings-model.d.ts +17 -0
  97. package/lib/settings/settings-model.d.ts.map +1 -1
  98. package/lib/settings/settings-model.js +18 -1
  99. package/lib/settings/settings-model.js.map +1 -1
  100. package/lib/settings/settings-rpc.d.ts +71 -3
  101. package/lib/settings/settings-rpc.d.ts.map +1 -1
  102. package/lib/settings/settings-rpc.js +167 -24
  103. package/lib/settings/settings-rpc.js.map +1 -1
  104. package/lib/settings/settings-service.d.ts +22 -1
  105. package/lib/settings/settings-service.d.ts.map +1 -1
  106. package/lib/settings/settings-service.js +145 -8
  107. package/lib/settings/settings-service.js.map +1 -1
  108. package/lib/state-dir.d.ts +28 -0
  109. package/lib/state-dir.d.ts.map +1 -0
  110. package/lib/state-dir.js +33 -0
  111. package/lib/state-dir.js.map +1 -0
  112. package/lib/stream.d.ts.map +1 -1
  113. package/lib/stream.js +3 -2
  114. package/lib/stream.js.map +1 -1
  115. package/lib/types.d.ts +14 -1
  116. package/lib/types.d.ts.map +1 -1
  117. package/package.json +13 -10
@@ -0,0 +1,132 @@
1
+ /**
2
+ * How much of a stored secret the settings pane is allowed to show.
3
+ *
4
+ * The user has to be able to *confirm* what they configured — a pane that only
5
+ * ever says 「已配置」 cannot tell a correct appId from a typo — but a browser
6
+ * tab (or a screenshot of one) must never hold a usable credential. The two are
7
+ * reconciled here: the host masks the value **before it crosses the wire**, so
8
+ * what the pane receives is already unusable, and `maskSecret` is the only
9
+ * place that decides how much survives.
10
+ *
11
+ * Deliberately pure and dependency-free: the host (`settings-service`) masks
12
+ * with it and the client bundle imports the same compiled module for the input
13
+ * `type`, so the two can never drift into disagreeing about which keys are
14
+ * confidential.
15
+ *
16
+ * @module dsh-connect/settings/secret-disclosure
17
+ */
18
+ /**
19
+ * Per-config-key policy, keyed by the channel config key (`CREDENTIAL`-style
20
+ * keys are unique across channels: no channel has two fields that share a name
21
+ * but want different treatment).
22
+ *
23
+ * `appId` / `clientId` are `full` on purpose. They are **identifiers**: they
24
+ * appear in the URL or body of every outbound API call, are readable in the
25
+ * vendor's own console, and grant nothing without the paired secret. Masking
26
+ * them would cost the user the one thing this pane is for — checking that the
27
+ * id they pasted is the one they meant — and buy no secrecy at all.
28
+ */
29
+ export const SECRET_DISCLOSURE = Object.freeze({
30
+ appId: "full",
31
+ clientId: "full",
32
+ appSecret: "mask",
33
+ clientSecret: "mask",
34
+ botToken: "mask",
35
+ secret: "mask",
36
+ webhookUrl: "url",
37
+ });
38
+ /** Query parameters whose *value* is a credential and must not be echoed. */
39
+ const SECRET_QUERY_PARAM = /(secret|token|key|sign)/i;
40
+ /** Characters kept visible on each end of a masked value. */
41
+ const EDGE = 4;
42
+ /**
43
+ * Below this length there is no middle to hide — showing 4+4 of a 10-character
44
+ * value would print it in full — so short values collapse to a fixed-width
45
+ * mask, which also avoids leaking the length.
46
+ */
47
+ const MIN_MASKABLE = 12;
48
+ /** The width of the all-bullets mask used for values too short to split. */
49
+ const BULLETS = "••••••";
50
+ /** Policy for a config key; unknown keys are treated as confidential. */
51
+ export function disclosureOf(configKey) {
52
+ return SECRET_DISCLOSURE[configKey] ?? "mask";
53
+ }
54
+ /** True when the pane should render this key as a password input. */
55
+ export function isMaskedSecret(configKey) {
56
+ return disclosureOf(configKey) !== "full";
57
+ }
58
+ /** `head…tail`, or the bullets mask when the value is too short to split. */
59
+ function maskMiddle(value) {
60
+ if (value.length < MIN_MASKABLE)
61
+ return BULLETS;
62
+ return value.slice(0, EDGE) + "…" + value.slice(-EDGE);
63
+ }
64
+ /** Escape a query-parameter name for use inside a `RegExp`. */
65
+ function escapeForRegExp(text) {
66
+ return text.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
67
+ }
68
+ /**
69
+ * Mask the credential-bearing query parameters of a URL, keeping the origin,
70
+ * path and the innocent parameters readable.
71
+ *
72
+ * Masking such a URL end-to-end would defeat the purpose: DingTalk's webhook is
73
+ * `https://oapi.dingtalk.com/robot/send?access_token=…`, so `https…bcde` tells
74
+ * the user nothing about whether they pasted the right robot. Falls back to the
75
+ * plain mask when the value isn't a parseable URL (a bare token, a typo, an
76
+ * empty-ish string).
77
+ *
78
+ * The masking is a surgical replace on the original text rather than a
79
+ * re-serialize through `URLSearchParams`, which would percent-encode the `…`
80
+ * into `%E2%80%A6` and render the preview unreadable.
81
+ */
82
+ function maskUrl(value) {
83
+ let url;
84
+ try {
85
+ url = new URL(value);
86
+ }
87
+ catch {
88
+ return maskMiddle(value);
89
+ }
90
+ let masked = value;
91
+ for (const key of new Set(url.searchParams.keys())) {
92
+ if (!SECRET_QUERY_PARAM.test(key))
93
+ continue;
94
+ const pattern = new RegExp(`([?&]${escapeForRegExp(key)}=)([^&#]*)`, "g");
95
+ masked = masked.replace(pattern, (whole, prefix, held) => {
96
+ // Tolerate a percent-encoded token: decode to measure it, mask the
97
+ // decoded form, and splice the readable result back into the raw text.
98
+ let decoded = held;
99
+ try {
100
+ decoded = decodeURIComponent(held);
101
+ }
102
+ catch {
103
+ /* not encoded — use as-is */
104
+ }
105
+ return decoded.length === 0 ? whole : prefix + maskMiddle(decoded);
106
+ });
107
+ }
108
+ return masked;
109
+ }
110
+ /**
111
+ * The display preview for one stored secret. Never returns the input: for
112
+ * `mask` and `url` the returned string is lossy by construction, so a caller
113
+ * that echoes it to a browser cannot leak a usable credential.
114
+ *
115
+ * Surrounding whitespace is trimmed first — a pasted value commonly carries a
116
+ * trailing newline, and the mask should describe the stored value, not the
117
+ * paste.
118
+ */
119
+ export function maskSecret(configKey, value) {
120
+ const trimmed = value.trim();
121
+ if (trimmed.length === 0)
122
+ return "";
123
+ switch (disclosureOf(configKey)) {
124
+ case "full":
125
+ return trimmed;
126
+ case "url":
127
+ return maskUrl(trimmed);
128
+ default:
129
+ return maskMiddle(trimmed);
130
+ }
131
+ }
132
+ //# sourceMappingURL=secret-disclosure.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"secret-disclosure.js","sourceRoot":"","sources":["../../src/settings/secret-disclosure.ts"],"names":[],"mappings":"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"}
@@ -92,8 +92,25 @@ export interface SettingsForm {
92
92
  channels: ChannelName[];
93
93
  channelDefaults: Record<string, unknown>;
94
94
  channelConfigs: Record<string, Record<string, unknown>>;
95
+ /** Secret inputs the user is *typing*: written on save, never seeded by a read. */
95
96
  secrets: Record<string, Record<string, string>>;
97
+ /**
98
+ * Whether a value is already stored for a secret key, for the placeholder.
99
+ * Separate from `secrets` because the two have opposite lifetimes: presence
100
+ * comes from the snapshot and the typed values start empty and are cleared
101
+ * after a save — a read must never be able to populate an input.
102
+ */
103
+ secretPresence: Record<string, Record<string, boolean>>;
104
+ /**
105
+ * Host-masked previews of the stored secrets, so the user can confirm what
106
+ * they configured. Rendered as read-only text and **never** fed into
107
+ * `secrets`: a masked value is not a credential, and treating one as a value
108
+ * to save would overwrite a working secret with its own mask.
109
+ */
110
+ secretPreviews: Record<string, Record<string, string>>;
96
111
  settingsStatePath?: string;
112
+ /** True when the section lives in the settings namespace: a save is immediate and durable. */
113
+ live: boolean;
97
114
  }
98
115
  /** Build the initial form from a snapshot. */
99
116
  export declare function snapshotToForm(snapshot: SettingsSnapshot): SettingsForm;
@@ -1 +1 @@
1
- {"version":3,"file":"settings-model.d.ts","sourceRoot":"","sources":["../../src/settings/settings-model.ts"],"names":[],"mappings":"AAUA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AACjD,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AAE1D,mEAAmE;AACnE,eAAO,MAAM,qBAAqB,EAE7B,MAAM,CAAC,WAAW,EAAE,MAAM,EAAE,CAAC,CAAC;AAEnC;;;;;GAKG;AACH,MAAM,WAAW,WAAW;IAC1B,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,MAAM,GAAG,QAAQ,GAAG,SAAS,GAAG,QAAQ,CAAC;IAC/C,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;IACnB,kDAAkD;IAClD,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED;;;;GAIG;AACH,eAAO,MAAM,qBAAqB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAsB8B,CAAC;AAEjE,+EAA+E;AAC/E,eAAO,MAAM,sBAAsB,EAAE,SAAS,WAAW,EAGxD,CAAC;AAEF,qFAAqF;AACrF,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,WAAW,CAAC,MAAM,CAAC,EAAE,GAAG,EAAE,OAAO,GAAG,OAAO,CAclF;AAED,uCAAuC;AACvC,MAAM,WAAW,YAAY;IAC3B,QAAQ,EAAE,WAAW,EAAE,CAAC;IACxB,eAAe,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACzC,cAAc,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;IACxD,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;IAChD,iBAAiB,CAAC,EAAE,MAAM,CAAC;CAC5B;AAED,8CAA8C;AAC9C,wBAAgB,cAAc,CAAC,QAAQ,EAAE,gBAAgB,GAAG,YAAY,CAYvE;AASD,kEAAkE;AAClE,wBAAgB,eAAe,CAAC,IAAI,EAAE,YAAY,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAU3E;AAED,kFAAkF;AAClF,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,YAAY,GAAG;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;CAAE,EAAE,CAM9G"}
1
+ {"version":3,"file":"settings-model.d.ts","sourceRoot":"","sources":["../../src/settings/settings-model.ts"],"names":[],"mappings":"AAUA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AACjD,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AAE1D,mEAAmE;AACnE,eAAO,MAAM,qBAAqB,EAE7B,MAAM,CAAC,WAAW,EAAE,MAAM,EAAE,CAAC,CAAC;AAEnC;;;;;GAKG;AACH,MAAM,WAAW,WAAW;IAC1B,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,MAAM,GAAG,QAAQ,GAAG,SAAS,GAAG,QAAQ,CAAC;IAC/C,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;IACnB,kDAAkD;IAClD,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED;;;;GAIG;AACH,eAAO,MAAM,qBAAqB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAsB8B,CAAC;AAEjE,+EAA+E;AAC/E,eAAO,MAAM,sBAAsB,EAAE,SAAS,WAAW,EAGxD,CAAC;AAEF,qFAAqF;AACrF,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,WAAW,CAAC,MAAM,CAAC,EAAE,GAAG,EAAE,OAAO,GAAG,OAAO,CAclF;AAED,uCAAuC;AACvC,MAAM,WAAW,YAAY;IAC3B,QAAQ,EAAE,WAAW,EAAE,CAAC;IACxB,eAAe,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACzC,cAAc,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;IACxD,mFAAmF;IACnF,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;IAChD;;;;;OAKG;IACH,cAAc,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;IACxD;;;;;OAKG;IACH,cAAc,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;IACvD,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,8FAA8F;IAC9F,IAAI,EAAE,OAAO,CAAC;CACf;AAED,8CAA8C;AAC9C,wBAAgB,cAAc,CAAC,QAAQ,EAAE,gBAAgB,GAAG,YAAY,CA8BvE;AASD,kEAAkE;AAClE,wBAAgB,eAAe,CAAC,IAAI,EAAE,YAAY,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAU3E;AAED,kFAAkF;AAClF,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,YAAY,GAAG;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;CAAE,EAAE,CAM9G"}
@@ -64,15 +64,32 @@ export function coerceConfigValue(kind, raw) {
64
64
  export function snapshotToForm(snapshot) {
65
65
  const config = snapshot.config ?? {};
66
66
  const channels = (snapshot.enabled ?? []);
67
+ // Seeded for *every* channel the pane knows, not only the enabled ones. A
68
+ // save is a whole-section replace: a declared channel block the payload omits
69
+ // is reset to its inherited value (see `namespace.ts`). Seeding from
70
+ // `enabled` alone therefore meant that switching a channel off and saving —
71
+ // for any reason, even one unrelated to that channel — silently reset every
72
+ // declared field of it (`transport`, `dmMode`, `webhookPort`, …), with
73
+ // nothing in the UI to suggest it. Rendering a switched-off channel's stored
74
+ // values is also simply more honest than showing it blank.
67
75
  const channelConfigs = {};
68
- for (const ch of channels)
76
+ for (const ch of Object.keys(CHANNEL_CONFIG_FIELDS)) {
69
77
  channelConfigs[ch] = (config[ch] ?? {});
78
+ }
70
79
  return {
71
80
  channels,
72
81
  channelDefaults: (config.channelDefaults ?? {}),
73
82
  channelConfigs,
83
+ // Deliberately empty even though `secretPreviews` carries something: an
84
+ // input is a place to *type a new* secret, and prefilling it with the mask
85
+ // would either overwrite the stored secret with its own preview on save, or
86
+ // train the user to think a masked value is the real one. The preview is
87
+ // rendered beside the input instead.
74
88
  secrets: {},
89
+ secretPresence: (snapshot.secrets ?? {}),
90
+ secretPreviews: (snapshot.secretPreviews ?? {}),
75
91
  settingsStatePath: config.settingsStatePath,
92
+ live: snapshot.live === true,
76
93
  };
77
94
  }
78
95
  /** Drop keys whose value is `undefined`/`null` so cleared inputs aren't persisted. */
@@ -1 +1 @@
1
- {"version":3,"file":"settings-model.js","sourceRoot":"","sources":["../../src/settings/settings-model.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"settings-model.js","sourceRoot":"","sources":["../../src/settings/settings-model.ts"],"names":[],"mappings":"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"}
@@ -15,6 +15,7 @@
15
15
  *
16
16
  * @module dsh-connect/settings/settings-rpc
17
17
  */
18
+ import type { IncomingMessage, ServerResponse } from "node:http";
18
19
  /** RPC channel the settings pane calls. */
19
20
  export declare const SETTINGS_RPC_CHANNEL = "/dsh-connect";
20
21
  /** Endpoints the settings pane can invoke on the channel. */
@@ -27,6 +28,41 @@ export interface SettingsSnapshot {
27
28
  enabled: string[];
28
29
  /** Per-channel credential presence (true = stored & set). */
29
30
  credentials: Record<string, boolean>;
31
+ /**
32
+ * Per-channel, per-config-key secret **presence** (true = a value is stored
33
+ * for that key) — never the values themselves. The pane uses it to tell an
34
+ * untouched input («已配置») from an empty one.
35
+ *
36
+ * This used to echo the values, which put an `appSecret` into browser state
37
+ * and every screenshot of the settings page. What leaves the host now is
38
+ * either this boolean or the masked {@link secretPreviews} below — a usable
39
+ * secret still leaves exactly once, when the adapter consumes it
40
+ * (`injectSecrets`).
41
+ */
42
+ secrets?: Record<string, Record<string, boolean>>;
43
+ /**
44
+ * Per-channel, per-config-key **display preview**, for the user to confirm
45
+ * what they configured without being able to copy it back out.
46
+ *
47
+ * Already masked on the host by `maskSecret` (`./secret-disclosure.js`), so
48
+ * it is lossy by construction: identifiers such as an `appId` come through
49
+ * whole, an `appSecret` keeps only its first and last four characters, and a
50
+ * `webhookUrl` keeps its origin and path with the `access_token` in the query
51
+ * masked. A key is present here only when a value is stored for it, which
52
+ * makes an empty entry the same statement as `secrets[key] === false`.
53
+ *
54
+ * **Display-only.** The pane renders it as text; it must never be written
55
+ * back as a credential, and `buildCredentialSaves` ignores it — the secret
56
+ * inputs are still write-only and still start blank.
57
+ */
58
+ secretPreviews?: Record<string, Record<string, string>>;
59
+ /**
60
+ * True when the `dsh-connect` settings namespace is live, i.e. this config is
61
+ * stored in `$DSH_HOME/settings.yaml` and a save takes effect immediately.
62
+ * False means the legacy JSON state file is behind this pane: the settings
63
+ * path control still applies, and a save needs a restart.
64
+ */
65
+ live?: boolean;
30
66
  }
31
67
  /** The service backing the RPC; supplied by the web-settings integration. */
32
68
  export interface SettingsService {
@@ -51,12 +87,44 @@ export declare function createSettingsRpcHandler(service: SettingsService): (end
51
87
  };
52
88
  value?: undefined;
53
89
  }>;
90
+ /** The Host/Origin + browser-auth fence exposed by the host `connection` service. */
91
+ interface ConnectionFence {
92
+ /** HTTP status to reject with, or `undefined` to allow the request through. */
93
+ requestRejection?(request: IncomingMessage): number | undefined;
94
+ }
95
+ /**
96
+ * Build the raw HTTP handler for {@link SETTINGS_RPC_CHANNEL}. Mirrors the
97
+ * host's own Connection RPC adapter (method/content-type/envelope checks plus
98
+ * the Host/Origin and browser-auth fence) so the pane sees the same protocol
99
+ * and the same failure codes as a first-party channel.
100
+ */
101
+ export declare function createSettingsHttpHandler(service: SettingsService, connection?: ConnectionFence): (req: IncomingMessage, res: ServerResponse) => Promise<void>;
54
102
  /**
55
- * Register the settings RPC channel, mirroring dsh-im's `installUpdateRpc`.
56
- * No-ops (returns a no-op disposer) when the host connection is unavailable,
57
- * so the plugin stays safe to load in any context.
103
+ * Mount the settings RPC channel on the host webserver.
104
+ *
105
+ * Mounts a `prefix` route for {@link SETTINGS_RPC_CHANNEL} directly on the
106
+ * `webServer` host service — the same thing the host's own
107
+ * `connection.rpc.handle()` does internally (`owner.webServer.register(route)`
108
+ * with the `/api` fence), and the same thing `dsh-api-gateway` does for its
109
+ * WebSocket route.
110
+ *
111
+ * Why not `connection.rpc.handle()`: the host's `HostConnectionService` is
112
+ * context-tracked, so its `get rpc()` captures `this.ctx`. cordis resolves that
113
+ * read to a *shadow* of the service's construction context, and service
114
+ * resolution then walks **that** fiber chain — which never contains the
115
+ * `webServer` provider (a sibling fiber). The call therefore dies with
116
+ * `cannot get property "webServer" without inject`, the route is never mounted,
117
+ * and every `settings.*` call falls through to the static fallback (HTTP 405),
118
+ * leaving the pane stuck on "加载中". Injecting `webServer` into the calling
119
+ * scope — or declaring it in the plugin's `inject` — does not help, because the
120
+ * shadow overrides the caller's fiber.
121
+ *
122
+ * @param ctx - an injection scope holding `connection` and `webServer`.
123
+ * @param options - the settings service backing the channel.
124
+ * @returns a disposer removing the route (no-op if the host has no webserver).
58
125
  */
59
126
  export declare function installSettingsRpc(ctx: unknown, options: {
60
127
  service: SettingsService;
61
128
  }): () => void;
129
+ export {};
62
130
  //# sourceMappingURL=settings-rpc.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"settings-rpc.d.ts","sourceRoot":"","sources":["../../src/settings/settings-rpc.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,2CAA2C;AAC3C,eAAO,MAAM,oBAAoB,iBAAiB,CAAC;AAEnD,6DAA6D;AAC7D,eAAO,MAAM,kBAAkB,mBAA0F,CAAC;AAU1H,sDAAsD;AACtD,MAAM,WAAW,gBAAgB;IAC/B,qDAAqD;IACrD,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAChC,2CAA2C;IAC3C,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,6DAA6D;IAC7D,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACtC;AAED,6EAA6E;AAC7E,MAAM,WAAW,eAAe;IAC9B,GAAG,IAAI,OAAO,CAAC,gBAAgB,CAAC,CAAC;IACjC,IAAI,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,CAAC,gBAAgB,CAAC,CAAC;IACjE,6EAA6E;IAC7E,eAAe,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,OAAO,CAAC,gBAAgB,CAAC,CAAC;IAC7F,MAAM,IAAI,OAAO,CAAC,gBAAgB,CAAC,CAAC;CACrC;AAeD,wDAAwD;AACxD,wBAAgB,wBAAwB,CAAC,OAAO,EAAE,eAAe,IACjD,UAAU,MAAM,EAAE,SAAS,OAAO,EAAE,SAAS;IAAE,OAAO,CAAC,EAAE,OAAO,CAAA;CAAE;;;;;;;;;;;GAoBjF;AAaD;;;;GAIG;AACH,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,OAAO,EAAE,OAAO,EAAE;IAAE,OAAO,EAAE,eAAe,CAAA;CAAE,cAKrF"}
1
+ {"version":3,"file":"settings-rpc.d.ts","sourceRoot":"","sources":["../../src/settings/settings-rpc.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AACH,OAAO,KAAK,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AAEjE,2CAA2C;AAC3C,eAAO,MAAM,oBAAoB,iBAAiB,CAAC;AAEnD,6DAA6D;AAC7D,eAAO,MAAM,kBAAkB,mBAA0F,CAAC;AAU1H,sDAAsD;AACtD,MAAM,WAAW,gBAAgB;IAC/B,qDAAqD;IACrD,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAChC,2CAA2C;IAC3C,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,6DAA6D;IAC7D,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACrC;;;;;;;;;;OAUG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;IAClD;;;;;;;;;;;;;;OAcG;IACH,cAAc,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;IACxD;;;;;OAKG;IACH,IAAI,CAAC,EAAE,OAAO,CAAC;CAChB;AAED,6EAA6E;AAC7E,MAAM,WAAW,eAAe;IAC9B,GAAG,IAAI,OAAO,CAAC,gBAAgB,CAAC,CAAC;IACjC,IAAI,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,CAAC,gBAAgB,CAAC,CAAC;IACjE,6EAA6E;IAC7E,eAAe,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,OAAO,CAAC,gBAAgB,CAAC,CAAC;IAC7F,MAAM,IAAI,OAAO,CAAC,gBAAgB,CAAC,CAAC;CACrC;AAeD,wDAAwD;AACxD,wBAAgB,wBAAwB,CAAC,OAAO,EAAE,eAAe,IACjD,UAAU,MAAM,EAAE,SAAS,OAAO,EAAE,SAAS;IAAE,OAAO,CAAC,EAAE,OAAO,CAAA;CAAE;;;;;;;;;;;GAoBjF;AAmBD,qFAAqF;AACrF,UAAU,eAAe;IACvB,+EAA+E;IAC/E,gBAAgB,CAAC,CAAC,OAAO,EAAE,eAAe,GAAG,MAAM,GAAG,SAAS,CAAC;CACjE;AA+ED;;;;;GAKG;AACH,wBAAgB,yBAAyB,CAAC,OAAO,EAAE,eAAe,EAAE,UAAU,CAAC,EAAE,eAAe,IAGpD,KAAK,eAAe,EAAE,KAAK,cAAc,KAAG,OAAO,CAAC,IAAI,CAAC,CAgEpG;AAED;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,OAAO,EAAE,OAAO,EAAE;IAAE,OAAO,EAAE,eAAe,CAAA;CAAE,GAAG,MAAM,IAAI,CAiBlG"}
@@ -1,20 +1,3 @@
1
- /**
2
- * Host-side RPC facade for the dsh-connect web settings pane.
3
- *
4
- * Mirrors dsh-im's host RPC pattern: a plugin registers a single channel on
5
- * `ctx.connection.rpc.handle(...)` and a handler dispatches dotted endpoints,
6
- * returning `{ ok: true, value }` on success or `{ ok: false, error }` on
7
- * failure (see dsh-im `plugin-src/host/update-rpc.mjs`).
8
- *
9
- * Endpoints:
10
- * - `settings.get` — current non-secret config + enabled channels + credential presence.
11
- * - `settings.save` — persist non-secret config (payload must be non-empty).
12
- * - `credentials.save` — persist secrets to the DSH credential store (payload
13
- * `{ channel, values }`, values are {configKey: secret}).
14
- * - `settings.status` — fresh status snapshot.
15
- *
16
- * @module dsh-connect/settings/settings-rpc
17
- */
18
1
  /** RPC channel the settings pane calls. */
19
2
  export const SETTINGS_RPC_CHANNEL = "/dsh-connect";
20
3
  /** Endpoints the settings pane can invoke on the channel. */
@@ -75,16 +58,176 @@ async function saveCredentialsP(service, record) {
75
58
  const values = (record.values ?? {});
76
59
  return service.saveCredentials(channel, values);
77
60
  }
61
+ /** Endpoint segment accepted by a Connection RPC path (host-compatible). */
62
+ const ENDPOINT_SEGMENT_PATTERN = /^[A-Za-z0-9_$.-]+$/;
63
+ /** Upper bound on an accepted settings request body; settings payloads are tiny. */
64
+ const MAX_BODY_BYTES = 1024 * 1024;
65
+ /**
66
+ * Derive the endpoint from a request path, exactly like the host's own
67
+ * Connection router: the remainder of `channel/` must be non-empty segments
68
+ * matching {@link ENDPOINT_SEGMENT_PATTERN}.
69
+ */
70
+ function endpointFromPath(channel, pathname) {
71
+ if (!pathname.startsWith(`${channel}/`))
72
+ return undefined;
73
+ const endpoint = pathname.slice(channel.length + 1);
74
+ const segments = endpoint.split("/");
75
+ if (segments.some((segment) => segment === "" || segment === "." || segment === ".." || !ENDPOINT_SEGMENT_PATTERN.test(segment)))
76
+ return undefined;
77
+ return endpoint;
78
+ }
79
+ /** Read a request body as UTF-8 text, rejecting past {@link MAX_BODY_BYTES}. */
80
+ function readBody(req, limit = MAX_BODY_BYTES) {
81
+ return new Promise((resolve, reject) => {
82
+ const chunks = [];
83
+ let size = 0;
84
+ let overLimit = false;
85
+ req.on("data", (chunk) => {
86
+ if (overLimit)
87
+ return;
88
+ size += chunk.length;
89
+ if (size > limit) {
90
+ overLimit = true;
91
+ chunks.length = 0;
92
+ reject(new Error("body exceeds limit"));
93
+ return;
94
+ }
95
+ chunks.push(chunk);
96
+ });
97
+ req.on("end", () => resolve(Buffer.concat(chunks).toString("utf8")));
98
+ req.on("error", reject);
99
+ });
100
+ }
101
+ /** Write a JSON response with an accurate content length. */
102
+ function sendJson(res, status, body) {
103
+ const text = JSON.stringify(body);
104
+ res.writeHead(status, { "content-type": "application/json", "content-length": String(Buffer.byteLength(text)) });
105
+ res.end(text);
106
+ }
107
+ /**
108
+ * Coerce a handler result into the Connection response envelope the browser
109
+ * client validates. `error.details` must always be an object — the client's
110
+ * `parseConnectionResponse` throws on a missing one.
111
+ */
112
+ function responseEnvelope(rpcId, result) {
113
+ if (result?.ok === true)
114
+ return { type: "server-response", rpcId, result: { ok: true, value: result.value } };
115
+ const error = (result?.error ?? {});
116
+ const details = error.details !== null && typeof error.details === "object" ? error.details : {};
117
+ return {
118
+ type: "server-response",
119
+ rpcId,
120
+ result: { ok: false, error: { code: String(error.code ?? "settings-failed"), message: String(error.message ?? ""), details } },
121
+ };
122
+ }
123
+ /**
124
+ * Build the raw HTTP handler for {@link SETTINGS_RPC_CHANNEL}. Mirrors the
125
+ * host's own Connection RPC adapter (method/content-type/envelope checks plus
126
+ * the Host/Origin and browser-auth fence) so the pane sees the same protocol
127
+ * and the same failure codes as a first-party channel.
128
+ */
129
+ export function createSettingsHttpHandler(service, connection) {
130
+ const handle = createSettingsRpcHandler(service);
131
+ return async function settingsHttpHandler(req, res) {
132
+ // Same fence the host applies to `/api`: trusted Host/Origin, then browser auth.
133
+ const rejection = connection?.requestRejection?.(req);
134
+ if (rejection !== undefined) {
135
+ res.writeHead(rejection, { "content-type": "text/plain" });
136
+ res.end(rejection === 401 ? "unauthorized" : "forbidden");
137
+ return;
138
+ }
139
+ const endpoint = endpointFromPath(SETTINGS_RPC_CHANNEL, new URL(req.url ?? "/", "http://dsh.internal").pathname);
140
+ if (req.method !== "POST" || endpoint === undefined) {
141
+ res.writeHead(404);
142
+ res.end();
143
+ return;
144
+ }
145
+ const contentType = String(req.headers["content-type"] ?? "").split(";", 1)[0]?.trim().toLowerCase();
146
+ if (contentType !== "application/json") {
147
+ res.writeHead(415);
148
+ res.end("content type must be application/json");
149
+ return;
150
+ }
151
+ let raw;
152
+ try {
153
+ raw = await readBody(req);
154
+ }
155
+ catch {
156
+ res.writeHead(400);
157
+ res.end("body is not JSON");
158
+ return;
159
+ }
160
+ let body;
161
+ try {
162
+ body = JSON.parse(raw);
163
+ }
164
+ catch {
165
+ res.writeHead(400);
166
+ res.end("body is not JSON");
167
+ return;
168
+ }
169
+ const envelope = (body ?? {});
170
+ const rpcId = typeof envelope.rpcId === "string" ? envelope.rpcId : "invalid-request";
171
+ if (envelope.type !== "client-request" || typeof envelope.rpcId !== "string" || typeof envelope.method !== "string") {
172
+ sendJson(res, 200, responseEnvelope(rpcId, { ok: false, error: { code: "bad-request", message: "invalid client-request message" } }));
173
+ return;
174
+ }
175
+ if (envelope.method !== endpoint) {
176
+ sendJson(res, 200, responseEnvelope(rpcId, {
177
+ ok: false,
178
+ error: { code: "bad-request", message: `method ${JSON.stringify(envelope.method)} does not match endpoint ${JSON.stringify(endpoint)}` },
179
+ }));
180
+ return;
181
+ }
182
+ // Abort the caller's signal when the browser goes away before we answer.
183
+ const aborter = new AbortController();
184
+ res.on("close", () => {
185
+ if (!res.writableEnded)
186
+ aborter.abort();
187
+ });
188
+ const result = await handle(endpoint, envelope.payload, aborter.signal);
189
+ sendJson(res, 200, responseEnvelope(rpcId, result));
190
+ };
191
+ }
78
192
  /**
79
- * Register the settings RPC channel, mirroring dsh-im's `installUpdateRpc`.
80
- * No-ops (returns a no-op disposer) when the host connection is unavailable,
81
- * so the plugin stays safe to load in any context.
193
+ * Mount the settings RPC channel on the host webserver.
194
+ *
195
+ * Mounts a `prefix` route for {@link SETTINGS_RPC_CHANNEL} directly on the
196
+ * `webServer` host service — the same thing the host's own
197
+ * `connection.rpc.handle()` does internally (`owner.webServer.register(route)`
198
+ * with the `/api` fence), and the same thing `dsh-api-gateway` does for its
199
+ * WebSocket route.
200
+ *
201
+ * Why not `connection.rpc.handle()`: the host's `HostConnectionService` is
202
+ * context-tracked, so its `get rpc()` captures `this.ctx`. cordis resolves that
203
+ * read to a *shadow* of the service's construction context, and service
204
+ * resolution then walks **that** fiber chain — which never contains the
205
+ * `webServer` provider (a sibling fiber). The call therefore dies with
206
+ * `cannot get property "webServer" without inject`, the route is never mounted,
207
+ * and every `settings.*` call falls through to the static fallback (HTTP 405),
208
+ * leaving the pane stuck on "加载中". Injecting `webServer` into the calling
209
+ * scope — or declaring it in the plugin's `inject` — does not help, because the
210
+ * shadow overrides the caller's fiber.
211
+ *
212
+ * @param ctx - an injection scope holding `connection` and `webServer`.
213
+ * @param options - the settings service backing the channel.
214
+ * @returns a disposer removing the route (no-op if the host has no webserver).
82
215
  */
83
216
  export function installSettingsRpc(ctx, options) {
84
- const conn = ctx?.connection;
85
- const handle = conn?.rpc?.handle;
86
- if (typeof handle !== "function")
217
+ const scope = (ctx ?? {});
218
+ const register = scope.webServer?.register;
219
+ if (typeof register !== "function")
87
220
  return () => { };
88
- return handle(SETTINGS_RPC_CHANNEL, createSettingsRpcHandler(options.service), { authority: "loopback" });
221
+ const route = {
222
+ kind: "prefix",
223
+ path: SETTINGS_RPC_CHANNEL,
224
+ handler: createSettingsHttpHandler(options.service, scope.connection),
225
+ };
226
+ // Register through the scope's effect so the route is torn down with the fiber.
227
+ if (typeof scope.effect === "function") {
228
+ const disposed = scope.effect(() => register.call(scope.webServer, route), `dsh-connect: ${SETTINGS_RPC_CHANNEL} settings rpc`);
229
+ return typeof disposed === "function" ? disposed : () => { };
230
+ }
231
+ return register.call(scope.webServer, route);
89
232
  }
90
233
  //# sourceMappingURL=settings-rpc.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"settings-rpc.js","sourceRoot":"","sources":["../../src/settings/settings-rpc.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"settings-rpc.js","sourceRoot":"","sources":["../../src/settings/settings-rpc.ts"],"names":[],"mappings":"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"}
@@ -1,8 +1,9 @@
1
1
  import { type ChannelName } from "./channels.js";
2
2
  import type { SettingsService } from "./settings-rpc.js";
3
3
  import { type CredentialStore } from "./credential-store.js";
4
+ import type { LiveConnectSection } from "./namespace.js";
4
5
  export interface SettingsServiceOptions {
5
- /** JSON file to persist non-secret settings (omit = in-memory only). */
6
+ /** JSON file to persist non-secret settings when no namespace is live (omit = in-memory only). */
6
7
  statePath?: string;
7
8
  /** Known channel names (default: built-in channels). */
8
9
  channelNames?: readonly ChannelName[];
@@ -17,6 +18,26 @@ export interface SettingsServiceOptions {
17
18
  * per-channel) that the pane edits.
18
19
  */
19
20
  initialConfig?: Record<string, unknown>;
21
+ /**
22
+ * The live settings namespace, if one is installed. A **getter**, not a value:
23
+ * this service is built during the plugin's `apply`, while the namespace is
24
+ * registered later (the `settings` service is a `dsh-base` row that loads
25
+ * after a user plugin), so the handle does not exist yet at construction time.
26
+ */
27
+ live?: () => LiveConnectSection | undefined;
28
+ /**
29
+ * Called after a credential write lands in the store, so the running adapters
30
+ * pick the new secret up.
31
+ *
32
+ * Writing the store is not enough on its own: an adapter holds the secret it
33
+ * was started with, and the only thing that re-applies one is the plugin's
34
+ * `reconcile` — which the settings namespace fires on a *config* write. The
35
+ * pane saves config and credentials as two separate calls, so without this
36
+ * hook a rotated `appSecret` stayed inert until the next host restart while
37
+ * the pane reported 「已保存」 — the user's fix for a broken bot would appear
38
+ * to have done nothing.
39
+ */
40
+ onCredentialsSaved?: () => void;
20
41
  }
21
42
  /**
22
43
  * Build a settings service backed by a JSON state file. `get`/`status` read the
@@ -1 +1 @@
1
- {"version":3,"file":"settings-service.d.ts","sourceRoot":"","sources":["../../src/settings/settings-service.ts"],"names":[],"mappings":"AAaA,OAAO,EAAY,KAAK,WAAW,EAAE,MAAM,eAAe,CAAC;AAC3D,OAAO,KAAK,EAAE,eAAe,EAAoB,MAAM,mBAAmB,CAAC;AAC3E,OAAO,EAAuB,KAAK,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAElF,MAAM,WAAW,sBAAsB;IACrC,wEAAwE;IACxE,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,wDAAwD;IACxD,YAAY,CAAC,EAAE,SAAS,WAAW,EAAE,CAAC;IACtC,6EAA6E;IAC7E,eAAe,CAAC,EAAE,eAAe,CAAC;IAClC,2CAA2C;IAC3C,GAAG,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,CAAC;IAC5B;;;;;OAKG;IACH,aAAa,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACzC;AAMD;;;;GAIG;AACH,wBAAgB,qBAAqB,CAAC,OAAO,GAAE,sBAA2B,GAAG,eAAe,CAsE3F"}
1
+ {"version":3,"file":"settings-service.d.ts","sourceRoot":"","sources":["../../src/settings/settings-service.ts"],"names":[],"mappings":"AAsBA,OAAO,EAAY,KAAK,WAAW,EAAE,MAAM,eAAe,CAAC;AAC3D,OAAO,KAAK,EAAE,eAAe,EAAoB,MAAM,mBAAmB,CAAC;AAC3E,OAAO,EAAuB,KAAK,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAElF,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,gBAAgB,CAAC;AAEzD,MAAM,WAAW,sBAAsB;IACrC,kGAAkG;IAClG,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,wDAAwD;IACxD,YAAY,CAAC,EAAE,SAAS,WAAW,EAAE,CAAC;IACtC,6EAA6E;IAC7E,eAAe,CAAC,EAAE,eAAe,CAAC;IAClC,2CAA2C;IAC3C,GAAG,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,CAAC;IAC5B;;;;;OAKG;IACH,aAAa,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACxC;;;;;OAKG;IACH,IAAI,CAAC,EAAE,MAAM,kBAAkB,GAAG,SAAS,CAAC;IAC5C;;;;;;;;;;;OAWG;IACH,kBAAkB,CAAC,EAAE,MAAM,IAAI,CAAC;CACjC;AA6CD;;;;GAIG;AACH,wBAAgB,qBAAqB,CAAC,OAAO,GAAE,sBAA2B,GAAG,eAAe,CA6J3F"}