@stackframe/stack-shared 2.8.22 → 2.8.27

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 (164) hide show
  1. package/CHANGELOG.md +30 -0
  2. package/dist/config/format.d.mts +20 -5
  3. package/dist/config/format.d.ts +20 -5
  4. package/dist/config/format.js +39 -14
  5. package/dist/config/format.js.map +1 -1
  6. package/dist/config/schema.d.mts +816 -294
  7. package/dist/config/schema.d.ts +816 -294
  8. package/dist/config/schema.js +471 -82
  9. package/dist/config/schema.js.map +1 -1
  10. package/dist/crud.d.mts +1 -0
  11. package/dist/crud.d.ts +1 -0
  12. package/dist/esm/config/format.js +37 -14
  13. package/dist/esm/config/format.js.map +1 -1
  14. package/dist/esm/config/schema.js +460 -78
  15. package/dist/esm/config/schema.js.map +1 -1
  16. package/dist/esm/helpers/emails.js +185 -0
  17. package/dist/esm/helpers/emails.js.map +1 -0
  18. package/dist/esm/interface/admin-interface.js +58 -36
  19. package/dist/esm/interface/admin-interface.js.map +1 -1
  20. package/dist/esm/interface/client-interface.js +41 -0
  21. package/dist/esm/interface/client-interface.js.map +1 -1
  22. package/dist/esm/interface/crud/{oauth.js → connected-accounts.js} +2 -2
  23. package/dist/esm/interface/crud/connected-accounts.js.map +1 -0
  24. package/dist/esm/interface/crud/oauth-providers.js +87 -0
  25. package/dist/esm/interface/crud/oauth-providers.js.map +1 -0
  26. package/dist/esm/interface/crud/projects.js +7 -5
  27. package/dist/esm/interface/crud/projects.js.map +1 -1
  28. package/dist/esm/interface/server-interface.js +51 -0
  29. package/dist/esm/interface/server-interface.js.map +1 -1
  30. package/dist/esm/known-errors.js +34 -1
  31. package/dist/esm/known-errors.js.map +1 -1
  32. package/dist/esm/schema-fields.js +112 -24
  33. package/dist/esm/schema-fields.js.map +1 -1
  34. package/dist/esm/utils/currencies.js +52 -0
  35. package/dist/esm/utils/currencies.js.map +1 -0
  36. package/dist/esm/utils/dates.js +55 -1
  37. package/dist/esm/utils/dates.js.map +1 -1
  38. package/dist/esm/utils/errors.js.map +1 -1
  39. package/dist/esm/utils/esbuild.js +14 -4
  40. package/dist/esm/utils/esbuild.js.map +1 -1
  41. package/dist/esm/utils/oauth.js +1 -1
  42. package/dist/esm/utils/oauth.js.map +1 -1
  43. package/dist/esm/utils/objects.js +2 -0
  44. package/dist/esm/utils/objects.js.map +1 -1
  45. package/dist/esm/utils/strings.js +4 -0
  46. package/dist/esm/utils/strings.js.map +1 -1
  47. package/dist/esm/utils/types.js +45 -0
  48. package/dist/esm/utils/types.js.map +1 -1
  49. package/dist/helpers/emails.d.mts +50 -0
  50. package/dist/helpers/emails.d.ts +50 -0
  51. package/dist/helpers/emails.js +216 -0
  52. package/dist/helpers/emails.js.map +1 -0
  53. package/dist/helpers/password.d.mts +1 -0
  54. package/dist/helpers/password.d.ts +1 -0
  55. package/dist/helpers/production-mode.d.mts +1 -0
  56. package/dist/helpers/production-mode.d.ts +1 -0
  57. package/dist/index.d.mts +3 -3
  58. package/dist/index.d.ts +3 -3
  59. package/dist/interface/admin-interface.d.mts +24 -15
  60. package/dist/interface/admin-interface.d.ts +24 -15
  61. package/dist/interface/admin-interface.js +58 -36
  62. package/dist/interface/admin-interface.js.map +1 -1
  63. package/dist/interface/client-interface.d.mts +25 -1
  64. package/dist/interface/client-interface.d.ts +25 -1
  65. package/dist/interface/client-interface.js +41 -0
  66. package/dist/interface/client-interface.js.map +1 -1
  67. package/dist/interface/crud/{oauth.d.mts → connected-accounts.d.mts} +1 -0
  68. package/dist/interface/crud/{oauth.d.ts → connected-accounts.d.ts} +1 -0
  69. package/dist/interface/crud/{oauth.js → connected-accounts.js} +5 -5
  70. package/dist/interface/crud/connected-accounts.js.map +1 -0
  71. package/dist/interface/crud/contact-channels.d.mts +1 -0
  72. package/dist/interface/crud/contact-channels.d.ts +1 -0
  73. package/dist/interface/crud/current-user.d.mts +1 -0
  74. package/dist/interface/crud/current-user.d.ts +1 -0
  75. package/dist/interface/crud/email-templates.d.mts +1 -0
  76. package/dist/interface/crud/email-templates.d.ts +1 -0
  77. package/dist/interface/crud/emails.d.mts +1 -0
  78. package/dist/interface/crud/emails.d.ts +1 -0
  79. package/dist/interface/crud/internal-api-keys.d.mts +1 -0
  80. package/dist/interface/crud/internal-api-keys.d.ts +1 -0
  81. package/dist/interface/crud/notification-preferences.d.mts +1 -0
  82. package/dist/interface/crud/notification-preferences.d.ts +1 -0
  83. package/dist/interface/crud/oauth-providers.d.mts +173 -0
  84. package/dist/interface/crud/oauth-providers.d.ts +173 -0
  85. package/dist/interface/crud/oauth-providers.js +107 -0
  86. package/dist/interface/crud/oauth-providers.js.map +1 -0
  87. package/dist/interface/crud/project-api-keys.d.mts +1 -0
  88. package/dist/interface/crud/project-api-keys.d.ts +1 -0
  89. package/dist/interface/crud/project-permissions.d.mts +1 -0
  90. package/dist/interface/crud/project-permissions.d.ts +1 -0
  91. package/dist/interface/crud/projects.d.mts +16 -12
  92. package/dist/interface/crud/projects.d.ts +16 -12
  93. package/dist/interface/crud/projects.js +5 -3
  94. package/dist/interface/crud/projects.js.map +1 -1
  95. package/dist/interface/crud/sessions.d.mts +1 -0
  96. package/dist/interface/crud/sessions.d.ts +1 -0
  97. package/dist/interface/crud/svix-token.d.mts +1 -0
  98. package/dist/interface/crud/svix-token.d.ts +1 -0
  99. package/dist/interface/crud/team-invitation-details.d.mts +1 -0
  100. package/dist/interface/crud/team-invitation-details.d.ts +1 -0
  101. package/dist/interface/crud/team-invitation.d.mts +1 -0
  102. package/dist/interface/crud/team-invitation.d.ts +1 -0
  103. package/dist/interface/crud/team-member-profiles.d.mts +1 -0
  104. package/dist/interface/crud/team-member-profiles.d.ts +1 -0
  105. package/dist/interface/crud/team-memberships.d.mts +1 -0
  106. package/dist/interface/crud/team-memberships.d.ts +1 -0
  107. package/dist/interface/crud/team-permissions.d.mts +1 -0
  108. package/dist/interface/crud/team-permissions.d.ts +1 -0
  109. package/dist/interface/crud/teams.d.mts +1 -0
  110. package/dist/interface/crud/teams.d.ts +1 -0
  111. package/dist/interface/crud/users.d.mts +1 -0
  112. package/dist/interface/crud/users.d.ts +1 -0
  113. package/dist/interface/server-interface.d.mts +46 -1
  114. package/dist/interface/server-interface.d.ts +46 -1
  115. package/dist/interface/server-interface.js +51 -0
  116. package/dist/interface/server-interface.js.map +1 -1
  117. package/dist/known-errors.d.mts +9 -0
  118. package/dist/known-errors.d.ts +9 -0
  119. package/dist/known-errors.js +34 -1
  120. package/dist/known-errors.js.map +1 -1
  121. package/dist/schema-fields.d.mts +51 -7
  122. package/dist/schema-fields.d.ts +51 -7
  123. package/dist/schema-fields.js +128 -24
  124. package/dist/schema-fields.js.map +1 -1
  125. package/dist/utils/currencies.d.mts +39 -0
  126. package/dist/utils/currencies.d.ts +39 -0
  127. package/dist/utils/currencies.js +78 -0
  128. package/dist/utils/currencies.js.map +1 -0
  129. package/dist/utils/dates.d.mts +5 -1
  130. package/dist/utils/dates.d.ts +5 -1
  131. package/dist/utils/dates.js +58 -2
  132. package/dist/utils/dates.js.map +1 -1
  133. package/dist/utils/errors.d.mts +9 -0
  134. package/dist/utils/errors.d.ts +9 -0
  135. package/dist/utils/errors.js.map +1 -1
  136. package/dist/utils/esbuild.d.mts +3 -0
  137. package/dist/utils/esbuild.d.ts +3 -0
  138. package/dist/utils/esbuild.js +14 -4
  139. package/dist/utils/esbuild.js.map +1 -1
  140. package/dist/utils/oauth.d.mts +2 -2
  141. package/dist/utils/oauth.d.ts +2 -2
  142. package/dist/utils/oauth.js +1 -1
  143. package/dist/utils/oauth.js.map +1 -1
  144. package/dist/utils/objects.d.mts +23 -8
  145. package/dist/utils/objects.d.ts +23 -8
  146. package/dist/utils/objects.js +2 -0
  147. package/dist/utils/objects.js.map +1 -1
  148. package/dist/utils/strings.d.mts +3 -1
  149. package/dist/utils/strings.d.ts +3 -1
  150. package/dist/utils/strings.js +5 -0
  151. package/dist/utils/strings.js.map +1 -1
  152. package/dist/utils/types.d.mts +73 -2
  153. package/dist/utils/types.d.ts +73 -2
  154. package/dist/utils/types.js +54 -0
  155. package/dist/utils/types.js.map +1 -1
  156. package/package.json +1 -1
  157. package/dist/esm/helpers/email-themes.js +0 -45
  158. package/dist/esm/helpers/email-themes.js.map +0 -1
  159. package/dist/esm/interface/crud/oauth.js.map +0 -1
  160. package/dist/helpers/email-themes.d.mts +0 -13
  161. package/dist/helpers/email-themes.d.ts +0 -13
  162. package/dist/helpers/email-themes.js +0 -71
  163. package/dist/helpers/email-themes.js.map +0 -1
  164. package/dist/interface/crud/oauth.js.map +0 -1
package/CHANGELOG.md CHANGED
@@ -1,5 +1,35 @@
1
1
  # @stackframe/stack-shared
2
2
 
3
+ ## 2.8.27
4
+
5
+ ### Patch Changes
6
+
7
+ - Various changes
8
+
9
+ ## 2.8.26
10
+
11
+ ### Patch Changes
12
+
13
+ - Various changes
14
+
15
+ ## 2.8.25
16
+
17
+ ### Patch Changes
18
+
19
+ - Various changes
20
+
21
+ ## 2.8.24
22
+
23
+ ### Patch Changes
24
+
25
+ - Various changes
26
+
27
+ ## 2.8.23
28
+
29
+ ### Patch Changes
30
+
31
+ - Various changes
32
+
3
33
  ## 2.8.22
4
34
 
5
35
  ### Patch Changes
@@ -1,3 +1,6 @@
1
+ import { OptionalKeys, RequiredKeys } from '../utils/types.mjs';
2
+ import '../utils/strings.mjs';
3
+
1
4
  type ConfigValue = string | number | boolean | null | ConfigValue[] | Config;
2
5
  type Config = {
3
6
  [keyOrDotNotation: string]: ConfigValue | undefined;
@@ -7,7 +10,9 @@ type NormalizedConfig = {
7
10
  [key: string]: NormalizedConfigValue | undefined;
8
11
  };
9
12
  type _NormalizesTo<N> = N extends object ? (Config & {
10
- [K in keyof N]?: _NormalizesTo<N[K]> | null;
13
+ [K in OptionalKeys<N>]?: _NormalizesTo<N[K]> | null;
14
+ } & {
15
+ [K in RequiredKeys<N>]: undefined extends N[K] ? _NormalizesTo<N[K]> | null : _NormalizesTo<N[K]>;
11
16
  } & {
12
17
  [K in `${string}.${string}`]: ConfigValue;
13
18
  }) : N;
@@ -23,17 +28,27 @@ declare function assertValidConfig(c: unknown): void;
23
28
  declare function override(c1: Config, ...configs: Config[]): Config;
24
29
  type NormalizeOptions = {
25
30
  /**
26
- * What to do if a dot notation is used on null.
31
+ * What to do if a dot notation is used on a value that is not an object.
32
+ *
33
+ * - "throw" (default): Throw an error.
34
+ * - "ignore": Ignore the dot notation field.
35
+ */
36
+ onDotIntoNonObject?: "throw" | "ignore";
37
+ /**
38
+ * What to do if a dot notation is used on a value that is null.
27
39
  *
28
- * - "empty" (default): Replace the null with an empty object.
40
+ * - "like-non-object" (default): Treat it like a non-object. See `onDotIntoNonObject`.
29
41
  * - "throw": Throw an error.
30
42
  * - "ignore": Ignore the dot notation field.
43
+ * - "empty-object": Set the value to an empty object.
31
44
  */
32
- onDotIntoNull?: "empty" | "throw" | "ignore";
45
+ onDotIntoNull?: "like-non-object" | "throw" | "ignore" | "empty-object";
33
46
  };
34
47
  declare class NormalizationError extends Error {
35
48
  constructor(...args: ConstructorParameters<typeof Error>);
36
49
  }
50
+ declare function isNormalized(c: Config): c is NormalizedConfig;
51
+ declare function assertNormalized(c: Config): asserts c is NormalizedConfig;
37
52
  declare function normalize(c: Config, options?: NormalizeOptions): NormalizedConfig;
38
53
 
39
- export { type Config, type ConfigValue, NormalizationError, type NormalizedConfig, type NormalizedConfigValue, type NormalizesTo, type _NormalizesTo, assertValidConfig, getInvalidConfigReason, isValidConfig, normalize, override };
54
+ export { type Config, type ConfigValue, NormalizationError, type NormalizedConfig, type NormalizedConfigValue, type NormalizesTo, type _NormalizesTo, assertNormalized, assertValidConfig, getInvalidConfigReason, isNormalized, isValidConfig, normalize, override };
@@ -1,3 +1,6 @@
1
+ import { OptionalKeys, RequiredKeys } from '../utils/types.js';
2
+ import '../utils/strings.js';
3
+
1
4
  type ConfigValue = string | number | boolean | null | ConfigValue[] | Config;
2
5
  type Config = {
3
6
  [keyOrDotNotation: string]: ConfigValue | undefined;
@@ -7,7 +10,9 @@ type NormalizedConfig = {
7
10
  [key: string]: NormalizedConfigValue | undefined;
8
11
  };
9
12
  type _NormalizesTo<N> = N extends object ? (Config & {
10
- [K in keyof N]?: _NormalizesTo<N[K]> | null;
13
+ [K in OptionalKeys<N>]?: _NormalizesTo<N[K]> | null;
14
+ } & {
15
+ [K in RequiredKeys<N>]: undefined extends N[K] ? _NormalizesTo<N[K]> | null : _NormalizesTo<N[K]>;
11
16
  } & {
12
17
  [K in `${string}.${string}`]: ConfigValue;
13
18
  }) : N;
@@ -23,17 +28,27 @@ declare function assertValidConfig(c: unknown): void;
23
28
  declare function override(c1: Config, ...configs: Config[]): Config;
24
29
  type NormalizeOptions = {
25
30
  /**
26
- * What to do if a dot notation is used on null.
31
+ * What to do if a dot notation is used on a value that is not an object.
32
+ *
33
+ * - "throw" (default): Throw an error.
34
+ * - "ignore": Ignore the dot notation field.
35
+ */
36
+ onDotIntoNonObject?: "throw" | "ignore";
37
+ /**
38
+ * What to do if a dot notation is used on a value that is null.
27
39
  *
28
- * - "empty" (default): Replace the null with an empty object.
40
+ * - "like-non-object" (default): Treat it like a non-object. See `onDotIntoNonObject`.
29
41
  * - "throw": Throw an error.
30
42
  * - "ignore": Ignore the dot notation field.
43
+ * - "empty-object": Set the value to an empty object.
31
44
  */
32
- onDotIntoNull?: "empty" | "throw" | "ignore";
45
+ onDotIntoNull?: "like-non-object" | "throw" | "ignore" | "empty-object";
33
46
  };
34
47
  declare class NormalizationError extends Error {
35
48
  constructor(...args: ConstructorParameters<typeof Error>);
36
49
  }
50
+ declare function isNormalized(c: Config): c is NormalizedConfig;
51
+ declare function assertNormalized(c: Config): asserts c is NormalizedConfig;
37
52
  declare function normalize(c: Config, options?: NormalizeOptions): NormalizedConfig;
38
53
 
39
- export { type Config, type ConfigValue, NormalizationError, type NormalizedConfig, type NormalizedConfigValue, type NormalizesTo, type _NormalizesTo, assertValidConfig, getInvalidConfigReason, isValidConfig, normalize, override };
54
+ export { type Config, type ConfigValue, NormalizationError, type NormalizedConfig, type NormalizedConfigValue, type NormalizesTo, type _NormalizesTo, assertNormalized, assertValidConfig, getInvalidConfigReason, isNormalized, isValidConfig, normalize, override };
@@ -21,8 +21,10 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
21
21
  var format_exports = {};
22
22
  __export(format_exports, {
23
23
  NormalizationError: () => NormalizationError,
24
+ assertNormalized: () => assertNormalized,
24
25
  assertValidConfig: () => assertValidConfig,
25
26
  getInvalidConfigReason: () => getInvalidConfigReason,
27
+ isNormalized: () => isNormalized,
26
28
  isValidConfig: () => isValidConfig,
27
29
  normalize: () => normalize,
28
30
  override: () => override
@@ -101,9 +103,23 @@ var NormalizationError = class extends Error {
101
103
  }
102
104
  };
103
105
  NormalizationError.prototype.name = "NormalizationError";
106
+ function isNormalized(c) {
107
+ assertValidConfig(c);
108
+ for (const [key, value] of Object.entries(c)) {
109
+ if (value === void 0) continue;
110
+ if (key.includes(".")) return false;
111
+ if (value === null) return false;
112
+ }
113
+ return true;
114
+ }
115
+ function assertNormalized(c) {
116
+ assertValidConfig(c);
117
+ if (!isNormalized(c)) throw new import_errors.StackAssertionError(`Config is not normalized: ${JSON.stringify(c)}`);
118
+ }
104
119
  function normalize(c, options = {}) {
105
120
  assertValidConfig(c);
106
- const onDotIntoNull = options.onDotIntoNull ?? "empty";
121
+ const onDotIntoNonObject = options.onDotIntoNonObject ?? "throw";
122
+ const onDotIntoNull = options.onDotIntoNull ?? "like-non-object";
107
123
  const countDots = (s) => s.match(/\./g)?.length ?? 0;
108
124
  const result = {};
109
125
  const keysByDepth = Object.keys(c).sort((a, b) => countDots(a) - countDots(b));
@@ -115,49 +131,58 @@ function normalize(c, options = {}) {
115
131
  let current = result;
116
132
  for (const keySegment of keySegmentsWithoutLast) {
117
133
  if (!(0, import_objects.hasAndNotUndefined)(current, keySegment)) {
118
- switch (onDotIntoNull) {
119
- case "empty": {
120
- (0, import_objects.set)(current, keySegment, {});
121
- break;
122
- }
134
+ switch (onDotIntoNull === "like-non-object" ? onDotIntoNonObject : onDotIntoNull) {
123
135
  case "throw": {
124
- throw new NormalizationError(`Tried to use dot notation to access ${JSON.stringify(key)}, but ${JSON.stringify(keySegment)} doesn't exist on the object (or is null). Maybe this config is not normalizable?`);
136
+ throw new NormalizationError(`Tried to use dot notation to access ${JSON.stringify(key)}, but ${JSON.stringify(keySegment)} doesn't exist on the object (or is null).`);
125
137
  }
126
138
  case "ignore": {
127
139
  continue outer;
128
140
  }
141
+ case "empty-object": {
142
+ (0, import_objects.set)(current, keySegment, {});
143
+ break;
144
+ }
129
145
  }
130
146
  }
131
147
  const value2 = (0, import_objects.get)(current, keySegment);
132
148
  if (typeof value2 !== "object") {
133
- throw new NormalizationError(`Tried to use dot notation to access ${JSON.stringify(key)}, but ${JSON.stringify(keySegment)} is not an object. Maybe this config is not normalizable?`);
149
+ switch (onDotIntoNonObject) {
150
+ case "throw": {
151
+ throw new NormalizationError(`Tried to use dot notation to access ${JSON.stringify(key)}, but ${JSON.stringify(keySegment)} is not an object.`);
152
+ }
153
+ case "ignore": {
154
+ continue outer;
155
+ }
156
+ }
134
157
  }
135
158
  current = value2;
136
159
  }
137
- setNormalizedValue(current, last, value);
160
+ setNormalizedValue(current, last, value, options);
138
161
  }
139
162
  return result;
140
163
  }
141
- function normalizeValue(value) {
164
+ function normalizeValue(value, options) {
142
165
  if (value === null) throw new NormalizationError("Tried to normalize a null value");
143
- if (Array.isArray(value)) return value.map(normalizeValue);
144
- if (typeof value === "object") return normalize(value);
166
+ if (Array.isArray(value)) return value.map((v) => normalizeValue(v, options));
167
+ if (typeof value === "object") return normalize(value, options);
145
168
  return value;
146
169
  }
147
- function setNormalizedValue(result, key, value) {
170
+ function setNormalizedValue(result, key, value, options) {
148
171
  if (value === null) {
149
172
  if ((0, import_objects.hasAndNotUndefined)(result, key)) {
150
173
  (0, import_objects.deleteKey)(result, key);
151
174
  }
152
175
  } else {
153
- (0, import_objects.set)(result, key, normalizeValue(value));
176
+ (0, import_objects.set)(result, key, normalizeValue(value, options));
154
177
  }
155
178
  }
156
179
  // Annotate the CommonJS export names for ESM import in node:
157
180
  0 && (module.exports = {
158
181
  NormalizationError,
182
+ assertNormalized,
159
183
  assertValidConfig,
160
184
  getInvalidConfigReason,
185
+ isNormalized,
161
186
  isValidConfig,
162
187
  normalize,
163
188
  override
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/config/format.ts"],"sourcesContent":["// see https://github.com/stack-auth/info/blob/main/eng-handbook/random-thoughts/config-json-format.md\n\nimport { StackAssertionError, throwErr } from \"../utils/errors\";\nimport { deleteKey, filterUndefined, get, hasAndNotUndefined, set } from \"../utils/objects\";\n\n\nexport type ConfigValue = string | number | boolean | null | ConfigValue[] | Config;\nexport type Config = {\n [keyOrDotNotation: string]: ConfigValue | undefined, // must support undefined for optional values\n};\n\nexport type NormalizedConfigValue = string | number | boolean | NormalizedConfig | NormalizedConfigValue[];\nexport type NormalizedConfig = {\n [key: string]: NormalizedConfigValue | undefined, // must support undefined for optional values\n};\n\nexport type _NormalizesTo<N> = N extends object ? (\n & Config\n & { [K in keyof N]?: _NormalizesTo<N[K]> | null }\n & { [K in `${string}.${string}`]: ConfigValue }\n) : N;\nexport type NormalizesTo<N extends NormalizedConfig> = _NormalizesTo<N>;\n\n/**\n * Note that a config can both be valid and not normalizable.\n */\nexport function isValidConfig(c: unknown): c is Config {\n return getInvalidConfigReason(c) === undefined;\n}\n\nexport function getInvalidConfigReason(c: unknown, options: { configName?: string } = {}): string | undefined {\n const configName = options.configName ?? 'config';\n if (c === null || typeof c !== 'object') return `${configName} must be a non-null object`;\n for (const [key, value] of Object.entries(c)) {\n if (value === undefined) continue;\n if (typeof key !== 'string') return `${configName} must have only string keys (found: ${typeof key})`;\n if (!key.match(/^[a-zA-Z0-9_:$][a-zA-Z_:$0-9\\-]*(?:\\.[a-zA-Z0-9_:$][a-zA-Z_:$0-9\\-]*)*$/)) return `All keys of ${configName} must consist of only alphanumeric characters, dots, underscores, colons, dollar signs, or hyphens and start with a character other than a hyphen (found: ${key})`;\n\n const entryName = `${configName}.${key}`;\n const reason = getInvalidConfigValueReason(value, { valueName: entryName });\n if (reason) return reason;\n }\n return undefined;\n}\n\nfunction getInvalidConfigValueReason(value: unknown, options: { valueName?: string } = {}): string | undefined {\n const valueName = options.valueName ?? 'value';\n switch (typeof value) {\n case 'string':\n case 'number':\n case 'boolean': {\n break;\n }\n case 'object': {\n if (value === null) {\n break;\n } else if (Array.isArray(value)) {\n for (const [index, v] of value.entries()) {\n const reason = getInvalidConfigValueReason(v, { valueName: `${valueName}[${index}]` });\n if (reason) return reason;\n }\n } else {\n const reason = getInvalidConfigReason(value, { configName: valueName });\n if (reason) return reason;\n }\n break;\n }\n default: {\n return `${valueName} has an invalid value type ${typeof value} (value: ${value})`;\n }\n }\n return undefined;\n}\n\nexport function assertValidConfig(c: unknown) {\n const reason = getInvalidConfigReason(c);\n if (reason) throw new StackAssertionError(`Invalid config: ${reason}`, { c });\n}\n\nexport function override(c1: Config, ...configs: Config[]) {\n if (configs.length === 0) return c1;\n if (configs.length > 1) return override(override(c1, configs[0]), ...configs.slice(1));\n const c2 = configs[0];\n\n assertValidConfig(c1);\n assertValidConfig(c2);\n\n let result = c1;\n for (const key of Object.keys(filterUndefined(c2))) {\n result = Object.fromEntries(\n Object.entries(result).filter(([k]) => k !== key && !k.startsWith(key + '.'))\n );\n }\n\n return {\n ...result,\n ...filterUndefined(c2),\n };\n}\n\nundefined?.test(\"override(...)\", ({ expect }) => {\n expect(\n override(\n {\n a: 1,\n b: 2,\n \"c.d\": 3,\n \"c.e.f\": 4,\n \"c.g\": 5,\n h: [6, { i: 7 }, 8],\n k: 123,\n l: undefined,\n },\n {\n a: 9,\n \"c.d\": 10,\n \"c.e\": null,\n \"h.0\": 11,\n \"h.1\": {\n j: 12,\n },\n k: undefined,\n },\n )\n ).toEqual({\n a: 9,\n b: 2,\n \"c.d\": 10,\n \"c.e\": null,\n \"c.g\": 5,\n h: [6, { i: 7 }, 8],\n \"h.0\": 11,\n \"h.1\": {\n j: 12,\n },\n k: 123,\n l: undefined,\n });\n});\n\ntype NormalizeOptions = {\n /**\n * What to do if a dot notation is used on null.\n *\n * - \"empty\" (default): Replace the null with an empty object.\n * - \"throw\": Throw an error.\n * - \"ignore\": Ignore the dot notation field.\n */\n onDotIntoNull?: \"empty\" | \"throw\" | \"ignore\",\n}\n\nexport class NormalizationError extends Error {\n constructor(...args: ConstructorParameters<typeof Error>) {\n super(...args);\n }\n}\nNormalizationError.prototype.name = \"NormalizationError\";\n\nexport function normalize(c: Config, options: NormalizeOptions = {}): NormalizedConfig {\n assertValidConfig(c);\n const onDotIntoNull = options.onDotIntoNull ?? \"empty\";\n\n const countDots = (s: string) => s.match(/\\./g)?.length ?? 0;\n const result: NormalizedConfig = {};\n const keysByDepth = Object.keys(c).sort((a, b) => countDots(a) - countDots(b));\n\n outer: for (const key of keysByDepth) {\n const keySegmentsWithoutLast = key.split('.');\n const last = keySegmentsWithoutLast.pop() ?? throwErr('split returns empty array?');\n const value = get(c, key);\n if (value === undefined) continue;\n\n let current: NormalizedConfig = result;\n for (const keySegment of keySegmentsWithoutLast) {\n if (!hasAndNotUndefined(current, keySegment)) {\n switch (onDotIntoNull) {\n case \"empty\": {\n set(current, keySegment, {});\n break;\n }\n case \"throw\": {\n throw new NormalizationError(`Tried to use dot notation to access ${JSON.stringify(key)}, but ${JSON.stringify(keySegment)} doesn't exist on the object (or is null). Maybe this config is not normalizable?`);\n }\n case \"ignore\": {\n continue outer;\n }\n }\n }\n const value = get(current, keySegment);\n if (typeof value !== 'object') {\n throw new NormalizationError(`Tried to use dot notation to access ${JSON.stringify(key)}, but ${JSON.stringify(keySegment)} is not an object. Maybe this config is not normalizable?`);\n }\n current = value as NormalizedConfig;\n }\n setNormalizedValue(current, last, value);\n }\n return result;\n}\n\nfunction normalizeValue(value: ConfigValue): NormalizedConfigValue {\n if (value === null) throw new NormalizationError(\"Tried to normalize a null value\");\n if (Array.isArray(value)) return value.map(normalizeValue);\n if (typeof value === 'object') return normalize(value);\n return value;\n}\n\nfunction setNormalizedValue(result: NormalizedConfig, key: string, value: ConfigValue) {\n if (value === null) {\n if (hasAndNotUndefined(result, key)) {\n deleteKey(result, key);\n }\n } else {\n set(result, key, normalizeValue(value));\n }\n}\n\nundefined?.test(\"normalize(...)\", ({ expect }) => {\n expect(normalize({\n a: 9,\n b: 2,\n c: {},\n \"c.d\": 10,\n \"c.e\": null,\n \"c.g\": 5,\n h: [6, { i: 7 }, 8],\n \"h.0\": 11,\n \"h.1\": {\n j: 12,\n },\n k: { l: {} },\n \"k.l.m\": 13,\n n: undefined,\n })).toEqual({\n a: 9,\n b: 2,\n c: {\n d: 10,\n g: 5,\n },\n h: [11, { j: 12 }, 8],\n k: { l: { m: 13 } },\n });\n\n // dotting into null\n expect(normalize({\n \"b.c\": 2,\n })).toEqual({ b: { c: 2 } });\n expect(() => normalize({\n \"b.c\": 2,\n }, { onDotIntoNull: \"throw\" })).toThrow(`Tried to use dot notation to access \"b.c\", but \"b\" doesn't exist on the object (or is null). Maybe this config is not normalizable?`);\n expect(() => normalize({\n b: null,\n \"b.c\": 2,\n }, { onDotIntoNull: \"throw\" })).toThrow(`Tried to use dot notation to access \"b.c\", but \"b\" doesn't exist on the object (or is null). Maybe this config is not normalizable?`);\n expect(normalize({\n \"b.c\": 2,\n }, { onDotIntoNull: \"ignore\" })).toEqual({});\n\n // dotting into non-object\n expect(() => normalize({\n b: 1,\n \"b.c\": 2,\n })).toThrow(`Tried to use dot notation to access \"b.c\", but \"b\" is not an object. Maybe this config is not normalizable?`);\n});\n"],"mappings":"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","names":["value"]}
1
+ {"version":3,"sources":["../../src/config/format.ts"],"sourcesContent":["// see https://github.com/stack-auth/info/blob/main/eng-handbook/random-thoughts/config-json-format.md\n\nimport { StackAssertionError, throwErr } from \"../utils/errors\";\nimport { deleteKey, filterUndefined, get, hasAndNotUndefined, set } from \"../utils/objects\";\nimport { OptionalKeys, RequiredKeys } from \"../utils/types\";\n\n\nexport type ConfigValue = string | number | boolean | null | ConfigValue[] | Config;\nexport type Config = {\n [keyOrDotNotation: string]: ConfigValue | undefined, // must support undefined for optional values\n};\n\nexport type NormalizedConfigValue = string | number | boolean | NormalizedConfig | NormalizedConfigValue[];\nexport type NormalizedConfig = {\n [key: string]: NormalizedConfigValue | undefined, // must support undefined for optional values\n};\n\nexport type _NormalizesTo<N> = N extends object ? (\n & Config\n & { [K in OptionalKeys<N>]?: _NormalizesTo<N[K]> | null }\n & { [K in RequiredKeys<N>]: undefined extends N[K] ? _NormalizesTo<N[K]> | null : _NormalizesTo<N[K]> }\n & { [K in `${string}.${string}`]: ConfigValue }\n) : N;\nexport type NormalizesTo<N extends NormalizedConfig> = _NormalizesTo<N>;\n\n/**\n * Note that a config can both be valid and not normalizable.\n */\nexport function isValidConfig(c: unknown): c is Config {\n return getInvalidConfigReason(c) === undefined;\n}\n\nexport function getInvalidConfigReason(c: unknown, options: { configName?: string } = {}): string | undefined {\n const configName = options.configName ?? 'config';\n if (c === null || typeof c !== 'object') return `${configName} must be a non-null object`;\n for (const [key, value] of Object.entries(c)) {\n if (value === undefined) continue;\n if (typeof key !== 'string') return `${configName} must have only string keys (found: ${typeof key})`;\n if (!key.match(/^[a-zA-Z0-9_:$][a-zA-Z_:$0-9\\-]*(?:\\.[a-zA-Z0-9_:$][a-zA-Z_:$0-9\\-]*)*$/)) return `All keys of ${configName} must consist of only alphanumeric characters, dots, underscores, colons, dollar signs, or hyphens and start with a character other than a hyphen (found: ${key})`;\n\n const entryName = `${configName}.${key}`;\n const reason = getInvalidConfigValueReason(value, { valueName: entryName });\n if (reason) return reason;\n }\n return undefined;\n}\n\nfunction getInvalidConfigValueReason(value: unknown, options: { valueName?: string } = {}): string | undefined {\n const valueName = options.valueName ?? 'value';\n switch (typeof value) {\n case 'string':\n case 'number':\n case 'boolean': {\n break;\n }\n case 'object': {\n if (value === null) {\n break;\n } else if (Array.isArray(value)) {\n for (const [index, v] of value.entries()) {\n const reason = getInvalidConfigValueReason(v, { valueName: `${valueName}[${index}]` });\n if (reason) return reason;\n }\n } else {\n const reason = getInvalidConfigReason(value, { configName: valueName });\n if (reason) return reason;\n }\n break;\n }\n default: {\n return `${valueName} has an invalid value type ${typeof value} (value: ${value})`;\n }\n }\n return undefined;\n}\n\nexport function assertValidConfig(c: unknown) {\n const reason = getInvalidConfigReason(c);\n if (reason) throw new StackAssertionError(`Invalid config: ${reason}`, { c });\n}\n\nexport function override(c1: Config, ...configs: Config[]) {\n if (configs.length === 0) return c1;\n if (configs.length > 1) return override(override(c1, configs[0]), ...configs.slice(1));\n const c2 = configs[0];\n\n assertValidConfig(c1);\n assertValidConfig(c2);\n\n let result = c1;\n for (const key of Object.keys(filterUndefined(c2))) {\n result = Object.fromEntries(\n Object.entries(result).filter(([k]) => k !== key && !k.startsWith(key + '.'))\n );\n }\n\n return {\n ...result,\n ...filterUndefined(c2),\n };\n}\n\nundefined?.test(\"override(...)\", ({ expect }) => {\n expect(\n override(\n {\n a: 1,\n b: 2,\n \"c.d\": 3,\n \"c.e.f\": 4,\n \"c.g\": 5,\n h: [6, { i: 7 }, 8],\n k: 123,\n l: undefined,\n },\n {\n a: 9,\n \"c.d\": 10,\n \"c.e\": null,\n \"h.0\": 11,\n \"h.1\": {\n j: 12,\n },\n k: undefined,\n },\n )\n ).toEqual({\n a: 9,\n b: 2,\n \"c.d\": 10,\n \"c.e\": null,\n \"c.g\": 5,\n h: [6, { i: 7 }, 8],\n \"h.0\": 11,\n \"h.1\": {\n j: 12,\n },\n k: 123,\n l: undefined,\n });\n});\n\ntype NormalizeOptions = {\n /**\n * What to do if a dot notation is used on a value that is not an object.\n *\n * - \"throw\" (default): Throw an error.\n * - \"ignore\": Ignore the dot notation field.\n */\n onDotIntoNonObject?: \"throw\" | \"ignore\",\n /**\n * What to do if a dot notation is used on a value that is null.\n *\n * - \"like-non-object\" (default): Treat it like a non-object. See `onDotIntoNonObject`.\n * - \"throw\": Throw an error.\n * - \"ignore\": Ignore the dot notation field.\n * - \"empty-object\": Set the value to an empty object.\n */\n onDotIntoNull?: \"like-non-object\" | \"throw\" | \"ignore\" | \"empty-object\",\n}\n\nexport class NormalizationError extends Error {\n constructor(...args: ConstructorParameters<typeof Error>) {\n super(...args);\n }\n}\nNormalizationError.prototype.name = \"NormalizationError\";\n\nexport function isNormalized(c: Config): c is NormalizedConfig {\n assertValidConfig(c);\n for (const [key, value] of Object.entries(c)) {\n if (value === undefined) continue;\n if (key.includes('.')) return false;\n if (value === null) return false;\n }\n return true;\n}\n\nexport function assertNormalized(c: Config): asserts c is NormalizedConfig {\n assertValidConfig(c);\n if (!isNormalized(c)) throw new StackAssertionError(`Config is not normalized: ${JSON.stringify(c)}`);\n}\n\nexport function normalize(c: Config, options: NormalizeOptions = {}): NormalizedConfig {\n assertValidConfig(c);\n const onDotIntoNonObject = options.onDotIntoNonObject ?? \"throw\";\n const onDotIntoNull = options.onDotIntoNull ?? \"like-non-object\";\n\n const countDots = (s: string) => s.match(/\\./g)?.length ?? 0;\n const result: NormalizedConfig = {};\n const keysByDepth = Object.keys(c).sort((a, b) => countDots(a) - countDots(b));\n\n outer: for (const key of keysByDepth) {\n const keySegmentsWithoutLast = key.split('.');\n const last = keySegmentsWithoutLast.pop() ?? throwErr('split returns empty array?');\n const value = get(c, key);\n if (value === undefined) continue;\n\n let current: NormalizedConfig = result;\n for (const keySegment of keySegmentsWithoutLast) {\n if (!hasAndNotUndefined(current, keySegment)) {\n switch (onDotIntoNull === \"like-non-object\" ? onDotIntoNonObject : onDotIntoNull) {\n case \"throw\": {\n throw new NormalizationError(`Tried to use dot notation to access ${JSON.stringify(key)}, but ${JSON.stringify(keySegment)} doesn't exist on the object (or is null).`);\n }\n case \"ignore\": {\n continue outer;\n }\n case \"empty-object\": {\n set(current, keySegment, {});\n break;\n }\n }\n }\n const value = get(current, keySegment);\n if (typeof value !== 'object') {\n switch (onDotIntoNonObject) {\n case \"throw\": {\n throw new NormalizationError(`Tried to use dot notation to access ${JSON.stringify(key)}, but ${JSON.stringify(keySegment)} is not an object.`);\n }\n case \"ignore\": {\n continue outer;\n }\n }\n }\n current = value as NormalizedConfig;\n }\n setNormalizedValue(current, last, value, options);\n }\n return result;\n}\n\nfunction normalizeValue(value: ConfigValue, options: NormalizeOptions): NormalizedConfigValue {\n if (value === null) throw new NormalizationError(\"Tried to normalize a null value\");\n if (Array.isArray(value)) return value.map(v => normalizeValue(v, options));\n if (typeof value === 'object') return normalize(value, options);\n return value;\n}\n\nfunction setNormalizedValue(result: NormalizedConfig, key: string, value: ConfigValue, options: NormalizeOptions) {\n if (value === null) {\n if (hasAndNotUndefined(result, key)) {\n deleteKey(result, key);\n }\n } else {\n set(result, key, normalizeValue(value, options));\n }\n}\n\nundefined?.test(\"normalize(...)\", ({ expect }) => {\n expect(normalize({\n a: 9,\n b: 2,\n c: {},\n \"c.d\": 10,\n \"c.e\": null,\n \"c.g\": 5,\n h: [6, { i: 7 }, 8],\n \"h.0\": 11,\n \"h.1\": {\n j: 12,\n },\n k: { l: {} },\n \"k.l.m\": 13,\n n: undefined,\n }, { onDotIntoNonObject: \"ignore\" })).toEqual({\n a: 9,\n b: 2,\n c: {\n d: 10,\n g: 5,\n },\n h: [11, { j: 12 }, 8],\n k: { l: { m: 13 } },\n });\n\n // dotting into null\n expect(() => normalize({\n \"b.c\": 2,\n }, { onDotIntoNonObject: \"throw\" })).toThrow(`Tried to use dot notation to access \"b.c\", but \"b\" doesn't exist on the object (or is null)`);\n expect(() => normalize({\n b: null,\n \"b.c\": 2,\n }, { onDotIntoNonObject: \"throw\" })).toThrow(`Tried to use dot notation to access \"b.c\", but \"b\" doesn't exist on the object (or is null)`);\n expect(normalize({\n \"b.c\": 2,\n }, { onDotIntoNonObject: \"ignore\" })).toEqual({});\n\n // dotting into non-object\n expect(() => normalize({\n b: 1,\n \"b.c\": 2,\n }, { onDotIntoNonObject: \"throw\" })).toThrow(`Tried to use dot notation to access \"b.c\", but \"b\" is not an object`);\n expect(normalize({\n b: 1,\n \"b.c\": 2,\n }, { onDotIntoNonObject: \"ignore\" })).toEqual({ b: 1 });\n});\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAEA,oBAA8C;AAC9C,qBAAyE;AAyBlE,SAAS,cAAc,GAAyB;AACrD,SAAO,uBAAuB,CAAC,MAAM;AACvC;AAEO,SAAS,uBAAuB,GAAY,UAAmC,CAAC,GAAuB;AAC5G,QAAM,aAAa,QAAQ,cAAc;AACzC,MAAI,MAAM,QAAQ,OAAO,MAAM,SAAU,QAAO,GAAG,UAAU;AAC7D,aAAW,CAAC,KAAK,KAAK,KAAK,OAAO,QAAQ,CAAC,GAAG;AAC5C,QAAI,UAAU,OAAW;AACzB,QAAI,OAAO,QAAQ,SAAU,QAAO,GAAG,UAAU,uCAAuC,OAAO,GAAG;AAClG,QAAI,CAAC,IAAI,MAAM,yEAAyE,EAAG,QAAO,eAAe,UAAU,6JAA6J,GAAG;AAE3R,UAAM,YAAY,GAAG,UAAU,IAAI,GAAG;AACtC,UAAM,SAAS,4BAA4B,OAAO,EAAE,WAAW,UAAU,CAAC;AAC1E,QAAI,OAAQ,QAAO;AAAA,EACrB;AACA,SAAO;AACT;AAEA,SAAS,4BAA4B,OAAgB,UAAkC,CAAC,GAAuB;AAC7G,QAAM,YAAY,QAAQ,aAAa;AACvC,UAAQ,OAAO,OAAO;AAAA,IACpB,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK,WAAW;AACd;AAAA,IACF;AAAA,IACA,KAAK,UAAU;AACb,UAAI,UAAU,MAAM;AAClB;AAAA,MACF,WAAW,MAAM,QAAQ,KAAK,GAAG;AAC/B,mBAAW,CAAC,OAAO,CAAC,KAAK,MAAM,QAAQ,GAAG;AACxC,gBAAM,SAAS,4BAA4B,GAAG,EAAE,WAAW,GAAG,SAAS,IAAI,KAAK,IAAI,CAAC;AACrF,cAAI,OAAQ,QAAO;AAAA,QACrB;AAAA,MACF,OAAO;AACL,cAAM,SAAS,uBAAuB,OAAO,EAAE,YAAY,UAAU,CAAC;AACtE,YAAI,OAAQ,QAAO;AAAA,MACrB;AACA;AAAA,IACF;AAAA,IACA,SAAS;AACP,aAAO,GAAG,SAAS,8BAA8B,OAAO,KAAK,YAAY,KAAK;AAAA,IAChF;AAAA,EACF;AACA,SAAO;AACT;AAEO,SAAS,kBAAkB,GAAY;AAC5C,QAAM,SAAS,uBAAuB,CAAC;AACvC,MAAI,OAAQ,OAAM,IAAI,kCAAoB,mBAAmB,MAAM,IAAI,EAAE,EAAE,CAAC;AAC9E;AAEO,SAAS,SAAS,OAAe,SAAmB;AACzD,MAAI,QAAQ,WAAW,EAAG,QAAO;AACjC,MAAI,QAAQ,SAAS,EAAG,QAAO,SAAS,SAAS,IAAI,QAAQ,CAAC,CAAC,GAAG,GAAG,QAAQ,MAAM,CAAC,CAAC;AACrF,QAAM,KAAK,QAAQ,CAAC;AAEpB,oBAAkB,EAAE;AACpB,oBAAkB,EAAE;AAEpB,MAAI,SAAS;AACb,aAAW,OAAO,OAAO,SAAK,gCAAgB,EAAE,CAAC,GAAG;AAClD,aAAS,OAAO;AAAA,MACd,OAAO,QAAQ,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC,MAAM,MAAM,OAAO,CAAC,EAAE,WAAW,MAAM,GAAG,CAAC;AAAA,IAC9E;AAAA,EACF;AAEA,SAAO;AAAA,IACL,GAAG;AAAA,IACH,OAAG,gCAAgB,EAAE;AAAA,EACvB;AACF;AA6DO,IAAM,qBAAN,cAAiC,MAAM;AAAA,EAC5C,eAAe,MAA2C;AACxD,UAAM,GAAG,IAAI;AAAA,EACf;AACF;AACA,mBAAmB,UAAU,OAAO;AAE7B,SAAS,aAAa,GAAkC;AAC7D,oBAAkB,CAAC;AACnB,aAAW,CAAC,KAAK,KAAK,KAAK,OAAO,QAAQ,CAAC,GAAG;AAC5C,QAAI,UAAU,OAAW;AACzB,QAAI,IAAI,SAAS,GAAG,EAAG,QAAO;AAC9B,QAAI,UAAU,KAAM,QAAO;AAAA,EAC7B;AACA,SAAO;AACT;AAEO,SAAS,iBAAiB,GAA0C;AACzE,oBAAkB,CAAC;AACnB,MAAI,CAAC,aAAa,CAAC,EAAG,OAAM,IAAI,kCAAoB,6BAA6B,KAAK,UAAU,CAAC,CAAC,EAAE;AACtG;AAEO,SAAS,UAAU,GAAW,UAA4B,CAAC,GAAqB;AACrF,oBAAkB,CAAC;AACnB,QAAM,qBAAqB,QAAQ,sBAAsB;AACzD,QAAM,gBAAgB,QAAQ,iBAAiB;AAE/C,QAAM,YAAY,CAAC,MAAc,EAAE,MAAM,KAAK,GAAG,UAAU;AAC3D,QAAM,SAA2B,CAAC;AAClC,QAAM,cAAc,OAAO,KAAK,CAAC,EAAE,KAAK,CAAC,GAAG,MAAM,UAAU,CAAC,IAAI,UAAU,CAAC,CAAC;AAE7E,QAAO,YAAW,OAAO,aAAa;AACpC,UAAM,yBAAyB,IAAI,MAAM,GAAG;AAC5C,UAAM,OAAO,uBAAuB,IAAI,SAAK,wBAAS,4BAA4B;AAClF,UAAM,YAAQ,oBAAI,GAAG,GAAG;AACxB,QAAI,UAAU,OAAW;AAEzB,QAAI,UAA4B;AAChC,eAAW,cAAc,wBAAwB;AAC/C,UAAI,KAAC,mCAAmB,SAAS,UAAU,GAAG;AAC5C,gBAAQ,kBAAkB,oBAAoB,qBAAqB,eAAe;AAAA,UAChF,KAAK,SAAS;AACZ,kBAAM,IAAI,mBAAmB,uCAAuC,KAAK,UAAU,GAAG,CAAC,SAAS,KAAK,UAAU,UAAU,CAAC,4CAA4C;AAAA,UACxK;AAAA,UACA,KAAK,UAAU;AACb,qBAAS;AAAA,UACX;AAAA,UACA,KAAK,gBAAgB;AACnB,oCAAI,SAAS,YAAY,CAAC,CAAC;AAC3B;AAAA,UACF;AAAA,QACF;AAAA,MACF;AACA,YAAMA,aAAQ,oBAAI,SAAS,UAAU;AACrC,UAAI,OAAOA,WAAU,UAAU;AAC7B,gBAAQ,oBAAoB;AAAA,UAC1B,KAAK,SAAS;AACZ,kBAAM,IAAI,mBAAmB,uCAAuC,KAAK,UAAU,GAAG,CAAC,SAAS,KAAK,UAAU,UAAU,CAAC,oBAAoB;AAAA,UAChJ;AAAA,UACA,KAAK,UAAU;AACb,qBAAS;AAAA,UACX;AAAA,QACF;AAAA,MACF;AACA,gBAAUA;AAAA,IACZ;AACA,uBAAmB,SAAS,MAAM,OAAO,OAAO;AAAA,EAClD;AACA,SAAO;AACT;AAEA,SAAS,eAAe,OAAoB,SAAkD;AAC5F,MAAI,UAAU,KAAM,OAAM,IAAI,mBAAmB,iCAAiC;AAClF,MAAI,MAAM,QAAQ,KAAK,EAAG,QAAO,MAAM,IAAI,OAAK,eAAe,GAAG,OAAO,CAAC;AAC1E,MAAI,OAAO,UAAU,SAAU,QAAO,UAAU,OAAO,OAAO;AAC9D,SAAO;AACT;AAEA,SAAS,mBAAmB,QAA0B,KAAa,OAAoB,SAA2B;AAChH,MAAI,UAAU,MAAM;AAClB,YAAI,mCAAmB,QAAQ,GAAG,GAAG;AACnC,oCAAU,QAAQ,GAAG;AAAA,IACvB;AAAA,EACF,OAAO;AACL,4BAAI,QAAQ,KAAK,eAAe,OAAO,OAAO,CAAC;AAAA,EACjD;AACF;","names":["value"]}