@tonyclaw/llm-inspector 1.6.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.
Files changed (286) hide show
  1. package/.output/nitro.json +17 -0
  2. package/.output/public/assets/alibaba-TTwafVwX.svg +1 -0
  3. package/.output/public/assets/index-B3RwBPLW.css +1 -0
  4. package/.output/public/assets/index-s4lwsWvq.js +97 -0
  5. package/.output/public/assets/main-Cp8AM0Pa.js +17 -0
  6. package/.output/public/assets/minimax-BPMzvuL-.jpeg +0 -0
  7. package/.output/public/assets/qwen-CONDcHqt.png +0 -0
  8. package/.output/public/assets/zhipuai-BPNAnxo-.svg +219 -0
  9. package/.output/server/_chunks/ssr-renderer.mjs +17 -0
  10. package/.output/server/_libs/@radix-ui/react-accessible-icon+[...].mjs +1 -0
  11. package/.output/server/_libs/@radix-ui/react-dismissable-layer+[...].mjs +210 -0
  12. package/.output/server/_libs/@radix-ui/react-navigation-menu+[...].mjs +1 -0
  13. package/.output/server/_libs/@radix-ui/react-one-time-password-field+[...].mjs +1 -0
  14. package/.output/server/_libs/@radix-ui/react-password-toggle-field+[...].mjs +1 -0
  15. package/.output/server/_libs/@radix-ui/react-use-callback-ref+[...].mjs +11 -0
  16. package/.output/server/_libs/@radix-ui/react-use-controllable-state+[...].mjs +69 -0
  17. package/.output/server/_libs/@radix-ui/react-use-effect-event+[...].mjs +1 -0
  18. package/.output/server/_libs/@radix-ui/react-use-escape-keydown+[...].mjs +17 -0
  19. package/.output/server/_libs/@radix-ui/react-use-is-hydrated+[...].mjs +1 -0
  20. package/.output/server/_libs/@radix-ui/react-use-layout-effect+[...].mjs +6 -0
  21. package/.output/server/_libs/@radix-ui/react-visually-hidden+[...].mjs +34 -0
  22. package/.output/server/_libs/ajv-formats.mjs +330 -0
  23. package/.output/server/_libs/ajv.mjs +11444 -0
  24. package/.output/server/_libs/aria-hidden.mjs +122 -0
  25. package/.output/server/_libs/atomically.mjs +152 -0
  26. package/.output/server/_libs/bail.mjs +8 -0
  27. package/.output/server/_libs/character-entities.mjs +2130 -0
  28. package/.output/server/_libs/class-variance-authority.mjs +44 -0
  29. package/.output/server/_libs/clsx.mjs +16 -0
  30. package/.output/server/_libs/comma-separated-tokens.mjs +10 -0
  31. package/.output/server/_libs/conf.mjs +635 -0
  32. package/.output/server/_libs/cookie-es.mjs +58 -0
  33. package/.output/server/_libs/core-util-is.mjs +75 -0
  34. package/.output/server/_libs/croner.mjs +1 -0
  35. package/.output/server/_libs/crossws.mjs +1 -0
  36. package/.output/server/_libs/debounce-fn.mjs +69 -0
  37. package/.output/server/_libs/decode-named-character-reference+[...].mjs +8 -0
  38. package/.output/server/_libs/detect-node-es.mjs +1 -0
  39. package/.output/server/_libs/devlop.mjs +8 -0
  40. package/.output/server/_libs/dot-prop.mjs +265 -0
  41. package/.output/server/_libs/env-paths.mjs +57 -0
  42. package/.output/server/_libs/estree-util-is-identifier-name.mjs +11 -0
  43. package/.output/server/_libs/extend.mjs +97 -0
  44. package/.output/server/_libs/fast-deep-equal.mjs +38 -0
  45. package/.output/server/_libs/fast-uri.mjs +812 -0
  46. package/.output/server/_libs/floating-ui__core.mjs +725 -0
  47. package/.output/server/_libs/floating-ui__dom.mjs +622 -0
  48. package/.output/server/_libs/floating-ui__react-dom.mjs +292 -0
  49. package/.output/server/_libs/floating-ui__utils.mjs +320 -0
  50. package/.output/server/_libs/get-nonce.mjs +9 -0
  51. package/.output/server/_libs/h3-v2.mjs +276 -0
  52. package/.output/server/_libs/h3.mjs +400 -0
  53. package/.output/server/_libs/hast-util-to-jsx-runtime.mjs +388 -0
  54. package/.output/server/_libs/hast-util-whitespace.mjs +10 -0
  55. package/.output/server/_libs/hookable.mjs +1 -0
  56. package/.output/server/_libs/html-url-attributes.mjs +26 -0
  57. package/.output/server/_libs/immediate.mjs +74 -0
  58. package/.output/server/_libs/inherits.mjs +50 -0
  59. package/.output/server/_libs/inline-style-parser.mjs +142 -0
  60. package/.output/server/_libs/is-plain-obj.mjs +10 -0
  61. package/.output/server/_libs/isarray.mjs +14 -0
  62. package/.output/server/_libs/isbot.mjs +20 -0
  63. package/.output/server/_libs/json-schema-traverse.mjs +180 -0
  64. package/.output/server/_libs/jszip.mjs +3049 -0
  65. package/.output/server/_libs/lie.mjs +273 -0
  66. package/.output/server/_libs/lucide-react.mjs +368 -0
  67. package/.output/server/_libs/mdast-util-from-markdown.mjs +717 -0
  68. package/.output/server/_libs/mdast-util-to-hast.mjs +710 -0
  69. package/.output/server/_libs/mdast-util-to-string.mjs +38 -0
  70. package/.output/server/_libs/micromark-core-commonmark.mjs +2259 -0
  71. package/.output/server/_libs/micromark-factory-destination.mjs +94 -0
  72. package/.output/server/_libs/micromark-factory-label.mjs +63 -0
  73. package/.output/server/_libs/micromark-factory-space.mjs +24 -0
  74. package/.output/server/_libs/micromark-factory-title.mjs +65 -0
  75. package/.output/server/_libs/micromark-factory-whitespace.mjs +22 -0
  76. package/.output/server/_libs/micromark-util-character.mjs +44 -0
  77. package/.output/server/_libs/micromark-util-chunked.mjs +36 -0
  78. package/.output/server/_libs/micromark-util-classify-character+[...].mjs +12 -0
  79. package/.output/server/_libs/micromark-util-combine-extensions+[...].mjs +41 -0
  80. package/.output/server/_libs/micromark-util-decode-numeric-character-reference+[...].mjs +19 -0
  81. package/.output/server/_libs/micromark-util-decode-string.mjs +21 -0
  82. package/.output/server/_libs/micromark-util-encode.mjs +1 -0
  83. package/.output/server/_libs/micromark-util-html-tag-name.mjs +69 -0
  84. package/.output/server/_libs/micromark-util-normalize-identifier+[...].mjs +6 -0
  85. package/.output/server/_libs/micromark-util-resolve-all.mjs +15 -0
  86. package/.output/server/_libs/micromark-util-sanitize-uri.mjs +41 -0
  87. package/.output/server/_libs/micromark-util-subtokenize.mjs +346 -0
  88. package/.output/server/_libs/micromark.mjs +906 -0
  89. package/.output/server/_libs/mimic-function.mjs +47 -0
  90. package/.output/server/_libs/ohash.mjs +1 -0
  91. package/.output/server/_libs/pako.mjs +4223 -0
  92. package/.output/server/_libs/process-nextick-args.mjs +48 -0
  93. package/.output/server/_libs/property-information.mjs +1209 -0
  94. package/.output/server/_libs/radix-ui.mjs +1 -0
  95. package/.output/server/_libs/radix-ui__number.mjs +6 -0
  96. package/.output/server/_libs/radix-ui__primitive.mjs +11 -0
  97. package/.output/server/_libs/radix-ui__react-accordion.mjs +1 -0
  98. package/.output/server/_libs/radix-ui__react-alert-dialog.mjs +1 -0
  99. package/.output/server/_libs/radix-ui__react-arrow.mjs +23 -0
  100. package/.output/server/_libs/radix-ui__react-aspect-ratio.mjs +1 -0
  101. package/.output/server/_libs/radix-ui__react-avatar.mjs +1 -0
  102. package/.output/server/_libs/radix-ui__react-checkbox.mjs +1 -0
  103. package/.output/server/_libs/radix-ui__react-collapsible.mjs +144 -0
  104. package/.output/server/_libs/radix-ui__react-collection.mjs +69 -0
  105. package/.output/server/_libs/radix-ui__react-compose-refs.mjs +39 -0
  106. package/.output/server/_libs/radix-ui__react-context-menu.mjs +1 -0
  107. package/.output/server/_libs/radix-ui__react-context.mjs +78 -0
  108. package/.output/server/_libs/radix-ui__react-dialog.mjs +325 -0
  109. package/.output/server/_libs/radix-ui__react-direction.mjs +9 -0
  110. package/.output/server/_libs/radix-ui__react-dropdown-menu.mjs +1 -0
  111. package/.output/server/_libs/radix-ui__react-focus-guards.mjs +29 -0
  112. package/.output/server/_libs/radix-ui__react-focus-scope.mjs +206 -0
  113. package/.output/server/_libs/radix-ui__react-form.mjs +1 -0
  114. package/.output/server/_libs/radix-ui__react-hover-card.mjs +1 -0
  115. package/.output/server/_libs/radix-ui__react-id.mjs +14 -0
  116. package/.output/server/_libs/radix-ui__react-label.mjs +1 -0
  117. package/.output/server/_libs/radix-ui__react-menu.mjs +1 -0
  118. package/.output/server/_libs/radix-ui__react-menubar.mjs +1 -0
  119. package/.output/server/_libs/radix-ui__react-popover.mjs +1 -0
  120. package/.output/server/_libs/radix-ui__react-popper.mjs +286 -0
  121. package/.output/server/_libs/radix-ui__react-portal.mjs +16 -0
  122. package/.output/server/_libs/radix-ui__react-presence.mjs +128 -0
  123. package/.output/server/_libs/radix-ui__react-primitive.mjs +42 -0
  124. package/.output/server/_libs/radix-ui__react-progress.mjs +1 -0
  125. package/.output/server/_libs/radix-ui__react-radio-group.mjs +1 -0
  126. package/.output/server/_libs/radix-ui__react-roving-focus.mjs +224 -0
  127. package/.output/server/_libs/radix-ui__react-scroll-area.mjs +721 -0
  128. package/.output/server/_libs/radix-ui__react-select.mjs +1163 -0
  129. package/.output/server/_libs/radix-ui__react-separator.mjs +28 -0
  130. package/.output/server/_libs/radix-ui__react-slider.mjs +1 -0
  131. package/.output/server/_libs/radix-ui__react-slot.mjs +99 -0
  132. package/.output/server/_libs/radix-ui__react-switch.mjs +1 -0
  133. package/.output/server/_libs/radix-ui__react-tabs.mjs +189 -0
  134. package/.output/server/_libs/radix-ui__react-toast.mjs +1 -0
  135. package/.output/server/_libs/radix-ui__react-toggle-group.mjs +1 -0
  136. package/.output/server/_libs/radix-ui__react-toggle.mjs +1 -0
  137. package/.output/server/_libs/radix-ui__react-toolbar.mjs +1 -0
  138. package/.output/server/_libs/radix-ui__react-tooltip.mjs +495 -0
  139. package/.output/server/_libs/radix-ui__react-use-previous.mjs +14 -0
  140. package/.output/server/_libs/radix-ui__react-use-size.mjs +39 -0
  141. package/.output/server/_libs/react-dom.mjs +9935 -0
  142. package/.output/server/_libs/react-markdown.mjs +147 -0
  143. package/.output/server/_libs/react-remove-scroll-bar.mjs +82 -0
  144. package/.output/server/_libs/react-remove-scroll.mjs +328 -0
  145. package/.output/server/_libs/react-style-singleton.mjs +69 -0
  146. package/.output/server/_libs/react.mjs +515 -0
  147. package/.output/server/_libs/readable-stream.mjs +1518 -0
  148. package/.output/server/_libs/remark-parse.mjs +19 -0
  149. package/.output/server/_libs/remark-rehype.mjs +21 -0
  150. package/.output/server/_libs/rou3.mjs +8 -0
  151. package/.output/server/_libs/safe-buffer.mjs +64 -0
  152. package/.output/server/_libs/semver.mjs +1984 -0
  153. package/.output/server/_libs/seroval-plugins.mjs +58 -0
  154. package/.output/server/_libs/seroval.mjs +1765 -0
  155. package/.output/server/_libs/setimmediate.mjs +1 -0
  156. package/.output/server/_libs/space-separated-tokens.mjs +6 -0
  157. package/.output/server/_libs/srvx.mjs +334 -0
  158. package/.output/server/_libs/stubborn-fs.mjs +91 -0
  159. package/.output/server/_libs/stubborn-utils.mjs +66 -0
  160. package/.output/server/_libs/style-to-js.mjs +72 -0
  161. package/.output/server/_libs/style-to-object.mjs +38 -0
  162. package/.output/server/_libs/tailwind-merge.mjs +3010 -0
  163. package/.output/server/_libs/tanstack__history.mjs +217 -0
  164. package/.output/server/_libs/tanstack__react-router.mjs +1480 -0
  165. package/.output/server/_libs/tanstack__react-store.mjs +1 -0
  166. package/.output/server/_libs/tanstack__react-virtual.mjs +44 -0
  167. package/.output/server/_libs/tanstack__router-core.mjs +4827 -0
  168. package/.output/server/_libs/tanstack__store.mjs +1 -0
  169. package/.output/server/_libs/tanstack__virtual-core.mjs +1225 -0
  170. package/.output/server/_libs/tiny-invariant.mjs +12 -0
  171. package/.output/server/_libs/tiny-warning.mjs +5 -0
  172. package/.output/server/_libs/trim-lines.mjs +41 -0
  173. package/.output/server/_libs/trough.mjs +85 -0
  174. package/.output/server/_libs/tslib.mjs +576 -0
  175. package/.output/server/_libs/ufo.mjs +54 -0
  176. package/.output/server/_libs/uint8array-extras.mjs +69 -0
  177. package/.output/server/_libs/unctx.mjs +1 -0
  178. package/.output/server/_libs/ungap__structured-clone.mjs +212 -0
  179. package/.output/server/_libs/unified.mjs +661 -0
  180. package/.output/server/_libs/unist-util-is.mjs +100 -0
  181. package/.output/server/_libs/unist-util-position.mjs +27 -0
  182. package/.output/server/_libs/unist-util-stringify-position.mjs +27 -0
  183. package/.output/server/_libs/unist-util-visit-parents.mjs +82 -0
  184. package/.output/server/_libs/unist-util-visit.mjs +24 -0
  185. package/.output/server/_libs/unstorage.mjs +1 -0
  186. package/.output/server/_libs/use-callback-ref.mjs +66 -0
  187. package/.output/server/_libs/use-sidecar.mjs +106 -0
  188. package/.output/server/_libs/use-sync-external-store.mjs +1 -0
  189. package/.output/server/_libs/util-deprecate.mjs +12 -0
  190. package/.output/server/_libs/vfile-message.mjs +138 -0
  191. package/.output/server/_libs/vfile.mjs +467 -0
  192. package/.output/server/_libs/when-exit.mjs +53 -0
  193. package/.output/server/_libs/zod.mjs +4460 -0
  194. package/.output/server/_ssr/index-ByCLZu7J.mjs +3061 -0
  195. package/.output/server/_ssr/index.mjs +1176 -0
  196. package/.output/server/_ssr/router-Bq_mxeNz.mjs +2872 -0
  197. package/.output/server/_ssr/start-HYkvq4Ni.mjs +4 -0
  198. package/.output/server/_tanstack-start-manifest_v-C4E0e9my.mjs +4 -0
  199. package/.output/server/index.mjs +393 -0
  200. package/README.md +196 -0
  201. package/package.json +91 -0
  202. package/src/assets/logos/alibaba.svg +1 -0
  203. package/src/assets/logos/anthropic.svg +1 -0
  204. package/src/assets/logos/deepseek.svg +1 -0
  205. package/src/assets/logos/minimax.jpeg +0 -0
  206. package/src/assets/logos/openai.svg +1 -0
  207. package/src/assets/logos/qwen.png +0 -0
  208. package/src/assets/logos/zhipuai.svg +219 -0
  209. package/src/cli.ts +68 -0
  210. package/src/components/ProxyViewer.tsx +325 -0
  211. package/src/components/ProxyViewerContainer.tsx +211 -0
  212. package/src/components/providers/ProviderCard.tsx +186 -0
  213. package/src/components/providers/ProviderForm.tsx +259 -0
  214. package/src/components/providers/ProviderLogo.tsx +111 -0
  215. package/src/components/providers/ProvidersPanel.tsx +259 -0
  216. package/src/components/providers/SettingsDialog.tsx +39 -0
  217. package/src/components/proxy-viewer/ConversationGroup.tsx +68 -0
  218. package/src/components/proxy-viewer/ConversationHeader.tsx +141 -0
  219. package/src/components/proxy-viewer/LogEntry.tsx +225 -0
  220. package/src/components/proxy-viewer/LogEntryHeader.tsx +250 -0
  221. package/src/components/proxy-viewer/ReplayDialog.tsx +208 -0
  222. package/src/components/proxy-viewer/ResponseView.tsx +161 -0
  223. package/src/components/proxy-viewer/StreamingChunkSequence.tsx +171 -0
  224. package/src/components/proxy-viewer/formats/anthropic/ContentBlocks.tsx +139 -0
  225. package/src/components/proxy-viewer/formats/anthropic/ResponseView.tsx +64 -0
  226. package/src/components/proxy-viewer/formats/index.tsx +24 -0
  227. package/src/components/proxy-viewer/formats/openai/ResponseView.tsx +80 -0
  228. package/src/components/proxy-viewer/index.ts +8 -0
  229. package/src/components/ui/badge.tsx +47 -0
  230. package/src/components/ui/button.tsx +47 -0
  231. package/src/components/ui/collapsible.tsx +21 -0
  232. package/src/components/ui/dialog.tsx +129 -0
  233. package/src/components/ui/json-viewer.tsx +464 -0
  234. package/src/components/ui/scroll-area.tsx +54 -0
  235. package/src/components/ui/select.tsx +178 -0
  236. package/src/components/ui/separator.tsx +28 -0
  237. package/src/components/ui/tabs.tsx +88 -0
  238. package/src/components/ui/tooltip.tsx +51 -0
  239. package/src/index.css +11 -0
  240. package/src/lib/export-logs.ts +51 -0
  241. package/src/lib/utils.ts +22 -0
  242. package/src/proxy/chunkStorage.ts +118 -0
  243. package/src/proxy/constants.ts +36 -0
  244. package/src/proxy/formats/anthropic/anthropicProvider.ts +75 -0
  245. package/src/proxy/formats/anthropic/handler.ts +74 -0
  246. package/src/proxy/formats/anthropic/index.ts +14 -0
  247. package/src/proxy/formats/anthropic/register.ts +4 -0
  248. package/src/proxy/formats/anthropic/schemas.ts +217 -0
  249. package/src/proxy/formats/anthropic/stream.ts +167 -0
  250. package/src/proxy/formats/handler.ts +46 -0
  251. package/src/proxy/formats/index.ts +12 -0
  252. package/src/proxy/formats/jsonSchema.ts +24 -0
  253. package/src/proxy/formats/openai/alibabaProvider.ts +38 -0
  254. package/src/proxy/formats/openai/handler.ts +70 -0
  255. package/src/proxy/formats/openai/index.ts +25 -0
  256. package/src/proxy/formats/openai/provider.ts +50 -0
  257. package/src/proxy/formats/openai/register.ts +4 -0
  258. package/src/proxy/formats/openai/schemas.ts +150 -0
  259. package/src/proxy/formats/openai/stream.ts +153 -0
  260. package/src/proxy/formats/protocol.ts +50 -0
  261. package/src/proxy/formats/providerRegistry.ts +51 -0
  262. package/src/proxy/formats/providers/index.ts +3 -0
  263. package/src/proxy/formats/registry.ts +61 -0
  264. package/src/proxy/handler.ts +389 -0
  265. package/src/proxy/logIndex.ts +187 -0
  266. package/src/proxy/logger.ts +99 -0
  267. package/src/proxy/providers.ts +234 -0
  268. package/src/proxy/schemas.ts +160 -0
  269. package/src/proxy/socketTracker.ts +158 -0
  270. package/src/proxy/store.ts +386 -0
  271. package/src/router.tsx +16 -0
  272. package/src/routes/__root.tsx +38 -0
  273. package/src/routes/api/config.paths.ts +14 -0
  274. package/src/routes/api/health.ts +11 -0
  275. package/src/routes/api/logs.$id.chunks.ts +36 -0
  276. package/src/routes/api/logs.$id.replay.ts +262 -0
  277. package/src/routes/api/logs.$id.ts +22 -0
  278. package/src/routes/api/logs.stream.ts +64 -0
  279. package/src/routes/api/logs.ts +30 -0
  280. package/src/routes/api/models.ts +10 -0
  281. package/src/routes/api/providers.$providerId.ts +45 -0
  282. package/src/routes/api/providers.ts +37 -0
  283. package/src/routes/api/sessions.ts +10 -0
  284. package/src/routes/index.tsx +6 -0
  285. package/src/routes/proxy/$.ts +15 -0
  286. package/styles/globals.css +121 -0
@@ -0,0 +1,44 @@
1
+ import { c as clsx } from "./clsx.mjs";
2
+ const falsyToString = (value) => typeof value === "boolean" ? `${value}` : value === 0 ? "0" : value;
3
+ const cx = clsx;
4
+ const cva = (base, config) => (props) => {
5
+ var _config_compoundVariants;
6
+ if ((config === null || config === void 0 ? void 0 : config.variants) == null) return cx(base, props === null || props === void 0 ? void 0 : props.class, props === null || props === void 0 ? void 0 : props.className);
7
+ const { variants, defaultVariants } = config;
8
+ const getVariantClassNames = Object.keys(variants).map((variant) => {
9
+ const variantProp = props === null || props === void 0 ? void 0 : props[variant];
10
+ const defaultVariantProp = defaultVariants === null || defaultVariants === void 0 ? void 0 : defaultVariants[variant];
11
+ if (variantProp === null) return null;
12
+ const variantKey = falsyToString(variantProp) || falsyToString(defaultVariantProp);
13
+ return variants[variant][variantKey];
14
+ });
15
+ const propsWithoutUndefined = props && Object.entries(props).reduce((acc, param) => {
16
+ let [key, value] = param;
17
+ if (value === void 0) {
18
+ return acc;
19
+ }
20
+ acc[key] = value;
21
+ return acc;
22
+ }, {});
23
+ const getCompoundVariantClassNames = config === null || config === void 0 ? void 0 : (_config_compoundVariants = config.compoundVariants) === null || _config_compoundVariants === void 0 ? void 0 : _config_compoundVariants.reduce((acc, param) => {
24
+ let { class: cvClass, className: cvClassName, ...compoundVariantOptions } = param;
25
+ return Object.entries(compoundVariantOptions).every((param2) => {
26
+ let [key, value] = param2;
27
+ return Array.isArray(value) ? value.includes({
28
+ ...defaultVariants,
29
+ ...propsWithoutUndefined
30
+ }[key]) : {
31
+ ...defaultVariants,
32
+ ...propsWithoutUndefined
33
+ }[key] === value;
34
+ }) ? [
35
+ ...acc,
36
+ cvClass,
37
+ cvClassName
38
+ ] : acc;
39
+ }, []);
40
+ return cx(base, getVariantClassNames, getCompoundVariantClassNames, props === null || props === void 0 ? void 0 : props.class, props === null || props === void 0 ? void 0 : props.className);
41
+ };
42
+ export {
43
+ cva as c
44
+ };
@@ -0,0 +1,16 @@
1
+ function r(e) {
2
+ var t, f, n = "";
3
+ if ("string" == typeof e || "number" == typeof e) n += e;
4
+ else if ("object" == typeof e) if (Array.isArray(e)) {
5
+ var o = e.length;
6
+ for (t = 0; t < o; t++) e[t] && (f = r(e[t])) && (n && (n += " "), n += f);
7
+ } else for (f in e) e[f] && (n && (n += " "), n += f);
8
+ return n;
9
+ }
10
+ function clsx() {
11
+ for (var e, t, f = 0, n = "", o = arguments.length; f < o; f++) (e = arguments[f]) && (t = r(e)) && (n && (n += " "), n += t);
12
+ return n;
13
+ }
14
+ export {
15
+ clsx as c
16
+ };
@@ -0,0 +1,10 @@
1
+ function stringify(values, options) {
2
+ const settings = {};
3
+ const input = values[values.length - 1] === "" ? [...values, ""] : values;
4
+ return input.join(
5
+ (settings.padRight ? " " : "") + "," + (settings.padLeft === false ? "" : " ")
6
+ ).trim();
7
+ }
8
+ export {
9
+ stringify as s
10
+ };
@@ -0,0 +1,635 @@
1
+ import { isDeepStrictEqual } from "node:util";
2
+ import process from "node:process";
3
+ import fs from "node:fs";
4
+ import path from "node:path";
5
+ import crypto from "node:crypto";
6
+ import assert from "node:assert";
7
+ import { h as hasProperty, d as deleteProperty, s as setProperty, g as getProperty } from "./dot-prop.mjs";
8
+ import { e as envPaths } from "./env-paths.mjs";
9
+ import { w as writeFileSync } from "./atomically.mjs";
10
+ import { _ as _2020Exports } from "./ajv.mjs";
11
+ import { a as ajvFormatsModule } from "./ajv-formats.mjs";
12
+ import { d as debounceFunction } from "./debounce-fn.mjs";
13
+ import { s as semver } from "./semver.mjs";
14
+ import { u as uint8ArrayToString, s as stringToUint8Array, c as concatUint8Arrays } from "./uint8array-extras.mjs";
15
+ const defaultEncryptionAlgorithm = "aes-256-cbc";
16
+ const supportedEncryptionAlgorithms = /* @__PURE__ */ new Set([
17
+ "aes-256-cbc",
18
+ "aes-256-gcm",
19
+ "aes-256-ctr"
20
+ ]);
21
+ const isSupportedEncryptionAlgorithm = (value) => typeof value === "string" && supportedEncryptionAlgorithms.has(value);
22
+ const createPlainObject = () => /* @__PURE__ */ Object.create(null);
23
+ const isExist = (data) => data !== void 0;
24
+ const checkValueType = (key, value) => {
25
+ const nonJsonTypes = /* @__PURE__ */ new Set([
26
+ "undefined",
27
+ "symbol",
28
+ "function"
29
+ ]);
30
+ const type = typeof value;
31
+ if (nonJsonTypes.has(type)) {
32
+ throw new TypeError(`Setting a value of type \`${type}\` for key \`${key}\` is not allowed as it's not supported by JSON`);
33
+ }
34
+ };
35
+ const INTERNAL_KEY = "__internal__";
36
+ const MIGRATION_KEY = `${INTERNAL_KEY}.migrations.version`;
37
+ class Conf {
38
+ path;
39
+ events;
40
+ #validator;
41
+ #encryptionKey;
42
+ #encryptionAlgorithm;
43
+ #options;
44
+ #defaultValues = {};
45
+ #isInMigration = false;
46
+ #watcher;
47
+ #watchFile;
48
+ #debouncedChangeHandler;
49
+ constructor(partialOptions = {}) {
50
+ const options = this.#prepareOptions(partialOptions);
51
+ this.#options = options;
52
+ this.#setupValidator(options);
53
+ this.#applyDefaultValues(options);
54
+ this.#configureSerialization(options);
55
+ this.events = new EventTarget();
56
+ this.#encryptionKey = options.encryptionKey;
57
+ this.#encryptionAlgorithm = options.encryptionAlgorithm ?? defaultEncryptionAlgorithm;
58
+ this.path = this.#resolvePath(options);
59
+ this.#initializeStore(options);
60
+ if (options.watch) {
61
+ this._watch();
62
+ }
63
+ }
64
+ get(key, defaultValue) {
65
+ if (this.#options.accessPropertiesByDotNotation) {
66
+ return this._get(key, defaultValue);
67
+ }
68
+ const { store } = this;
69
+ return key in store ? store[key] : defaultValue;
70
+ }
71
+ set(key, value) {
72
+ if (typeof key !== "string" && typeof key !== "object") {
73
+ throw new TypeError(`Expected \`key\` to be of type \`string\` or \`object\`, got ${typeof key}`);
74
+ }
75
+ if (typeof key !== "object" && value === void 0) {
76
+ throw new TypeError("Use `delete()` to clear values");
77
+ }
78
+ if (this._containsReservedKey(key)) {
79
+ throw new TypeError(`Please don't use the ${INTERNAL_KEY} key, as it's used to manage this module internal operations.`);
80
+ }
81
+ const { store } = this;
82
+ const set = (key2, value2) => {
83
+ checkValueType(key2, value2);
84
+ if (this.#options.accessPropertiesByDotNotation) {
85
+ setProperty(store, key2, value2);
86
+ } else {
87
+ if (key2 === "__proto__" || key2 === "constructor" || key2 === "prototype") {
88
+ return;
89
+ }
90
+ store[key2] = value2;
91
+ }
92
+ };
93
+ if (typeof key === "object") {
94
+ const object = key;
95
+ for (const [key2, value2] of Object.entries(object)) {
96
+ set(key2, value2);
97
+ }
98
+ } else {
99
+ set(key, value);
100
+ }
101
+ this.store = store;
102
+ }
103
+ has(key) {
104
+ if (this.#options.accessPropertiesByDotNotation) {
105
+ return hasProperty(this.store, key);
106
+ }
107
+ return key in this.store;
108
+ }
109
+ appendToArray(key, value) {
110
+ checkValueType(key, value);
111
+ const array = this.#options.accessPropertiesByDotNotation ? this._get(key, []) : key in this.store ? this.store[key] : [];
112
+ if (!Array.isArray(array)) {
113
+ throw new TypeError(`The key \`${key}\` is already set to a non-array value`);
114
+ }
115
+ this.set(key, [...array, value]);
116
+ }
117
+ /**
118
+ Reset items to their default values, as defined by the `defaults` or `schema` option.
119
+
120
+ @see `clear()` to reset all items.
121
+
122
+ @param keys - The keys of the items to reset.
123
+ */
124
+ reset(...keys) {
125
+ for (const key of keys) {
126
+ if (isExist(this.#defaultValues[key])) {
127
+ this.set(key, this.#defaultValues[key]);
128
+ }
129
+ }
130
+ }
131
+ delete(key) {
132
+ const { store } = this;
133
+ if (this.#options.accessPropertiesByDotNotation) {
134
+ deleteProperty(store, key);
135
+ } else {
136
+ delete store[key];
137
+ }
138
+ this.store = store;
139
+ }
140
+ /**
141
+ Delete all items.
142
+
143
+ This resets known items to their default values, if defined by the `defaults` or `schema` option.
144
+ */
145
+ clear() {
146
+ const newStore = createPlainObject();
147
+ for (const key of Object.keys(this.#defaultValues)) {
148
+ if (isExist(this.#defaultValues[key])) {
149
+ checkValueType(key, this.#defaultValues[key]);
150
+ if (this.#options.accessPropertiesByDotNotation) {
151
+ setProperty(newStore, key, this.#defaultValues[key]);
152
+ } else {
153
+ newStore[key] = this.#defaultValues[key];
154
+ }
155
+ }
156
+ }
157
+ this.store = newStore;
158
+ }
159
+ onDidChange(key, callback) {
160
+ if (typeof key !== "string") {
161
+ throw new TypeError(`Expected \`key\` to be of type \`string\`, got ${typeof key}`);
162
+ }
163
+ if (typeof callback !== "function") {
164
+ throw new TypeError(`Expected \`callback\` to be of type \`function\`, got ${typeof callback}`);
165
+ }
166
+ return this._handleValueChange(() => this.get(key), callback);
167
+ }
168
+ /**
169
+ Watches the whole config object, calling `callback` on any changes.
170
+
171
+ @param callback - A callback function that is called on any changes. When a `key` is first set `oldValue` will be `undefined`, and when a key is deleted `newValue` will be `undefined`.
172
+ @returns A function, that when called, will unsubscribe.
173
+ */
174
+ onDidAnyChange(callback) {
175
+ if (typeof callback !== "function") {
176
+ throw new TypeError(`Expected \`callback\` to be of type \`function\`, got ${typeof callback}`);
177
+ }
178
+ return this._handleStoreChange(callback);
179
+ }
180
+ get size() {
181
+ const entries = Object.keys(this.store);
182
+ return entries.filter((key) => !this._isReservedKeyPath(key)).length;
183
+ }
184
+ /**
185
+ Get all the config as an object or replace the current config with an object.
186
+
187
+ @example
188
+ ```
189
+ console.log(config.store);
190
+ //=> {name: 'John', age: 30}
191
+ ```
192
+
193
+ @example
194
+ ```
195
+ config.store = {
196
+ hello: 'world'
197
+ };
198
+ ```
199
+ */
200
+ get store() {
201
+ try {
202
+ const data = fs.readFileSync(this.path, this.#encryptionKey ? null : "utf8");
203
+ const dataString = this._decryptData(data);
204
+ const parseStore = (value) => {
205
+ const deserializedData = this._deserialize(value);
206
+ if (!this.#isInMigration) {
207
+ this._validate(deserializedData);
208
+ }
209
+ return Object.assign(createPlainObject(), deserializedData);
210
+ };
211
+ return parseStore(dataString);
212
+ } catch (error) {
213
+ if (error?.code === "ENOENT") {
214
+ this._ensureDirectory();
215
+ return createPlainObject();
216
+ }
217
+ if (this.#options.clearInvalidConfig) {
218
+ const errorInstance = error;
219
+ if (errorInstance.name === "SyntaxError") {
220
+ return createPlainObject();
221
+ }
222
+ if (errorInstance.message?.startsWith("Config schema violation:")) {
223
+ return createPlainObject();
224
+ }
225
+ if (errorInstance.message === "Failed to decrypt config data.") {
226
+ return createPlainObject();
227
+ }
228
+ }
229
+ throw error;
230
+ }
231
+ }
232
+ set store(value) {
233
+ this._ensureDirectory();
234
+ if (!hasProperty(value, INTERNAL_KEY)) {
235
+ try {
236
+ const data = fs.readFileSync(this.path, this.#encryptionKey ? null : "utf8");
237
+ const dataString = this._decryptData(data);
238
+ const currentStore = this._deserialize(dataString);
239
+ if (hasProperty(currentStore, INTERNAL_KEY)) {
240
+ setProperty(value, INTERNAL_KEY, getProperty(currentStore, INTERNAL_KEY));
241
+ }
242
+ } catch {
243
+ }
244
+ }
245
+ if (!this.#isInMigration) {
246
+ this._validate(value);
247
+ }
248
+ this._write(value);
249
+ this.events.dispatchEvent(new Event("change"));
250
+ }
251
+ *[Symbol.iterator]() {
252
+ for (const [key, value] of Object.entries(this.store)) {
253
+ if (!this._isReservedKeyPath(key)) {
254
+ yield [key, value];
255
+ }
256
+ }
257
+ }
258
+ /**
259
+ Close the file watcher if one exists. This is useful in tests to prevent the process from hanging.
260
+ */
261
+ _closeWatcher() {
262
+ if (this.#watcher) {
263
+ this.#watcher.close();
264
+ this.#watcher = void 0;
265
+ }
266
+ if (this.#watchFile) {
267
+ fs.unwatchFile(this.path);
268
+ this.#watchFile = false;
269
+ }
270
+ this.#debouncedChangeHandler = void 0;
271
+ }
272
+ _decryptData(data) {
273
+ const encryptionKey = this.#encryptionKey;
274
+ if (!encryptionKey) {
275
+ return typeof data === "string" ? data : uint8ArrayToString(data);
276
+ }
277
+ const encryptionAlgorithm = this.#encryptionAlgorithm;
278
+ const authenticationTagLength = encryptionAlgorithm === "aes-256-gcm" ? 16 : 0;
279
+ const separatorCodePoint = ":".codePointAt(0);
280
+ const separatorByte = typeof data === "string" ? data.codePointAt(16) : data[16];
281
+ const hasSeparator = separatorCodePoint !== void 0 && separatorByte === separatorCodePoint;
282
+ if (!hasSeparator) {
283
+ if (encryptionAlgorithm === "aes-256-cbc") {
284
+ return typeof data === "string" ? data : uint8ArrayToString(data);
285
+ }
286
+ throw new Error("Failed to decrypt config data.");
287
+ }
288
+ const getEncryptedPayload = (dataUpdate2) => {
289
+ if (authenticationTagLength === 0) {
290
+ return { ciphertext: dataUpdate2 };
291
+ }
292
+ const authenticationTagStart = dataUpdate2.length - authenticationTagLength;
293
+ if (authenticationTagStart < 0) {
294
+ throw new Error("Invalid authentication tag length.");
295
+ }
296
+ return {
297
+ ciphertext: dataUpdate2.slice(0, authenticationTagStart),
298
+ authenticationTag: dataUpdate2.slice(authenticationTagStart)
299
+ };
300
+ };
301
+ const initializationVector = data.slice(0, 16);
302
+ const slice = data.slice(17);
303
+ const dataUpdate = typeof slice === "string" ? stringToUint8Array(slice) : slice;
304
+ const decrypt = (salt) => {
305
+ const { ciphertext, authenticationTag } = getEncryptedPayload(dataUpdate);
306
+ const password = crypto.pbkdf2Sync(encryptionKey, salt, 1e4, 32, "sha512");
307
+ const decipher = crypto.createDecipheriv(encryptionAlgorithm, password, initializationVector);
308
+ if (authenticationTag) {
309
+ decipher.setAuthTag(authenticationTag);
310
+ }
311
+ return uint8ArrayToString(concatUint8Arrays([decipher.update(ciphertext), decipher.final()]));
312
+ };
313
+ try {
314
+ return decrypt(initializationVector);
315
+ } catch {
316
+ try {
317
+ return decrypt(initializationVector.toString());
318
+ } catch {
319
+ }
320
+ }
321
+ if (encryptionAlgorithm === "aes-256-cbc") {
322
+ return typeof data === "string" ? data : uint8ArrayToString(data);
323
+ }
324
+ throw new Error("Failed to decrypt config data.");
325
+ }
326
+ _handleStoreChange(callback) {
327
+ let currentValue = this.store;
328
+ const onChange = () => {
329
+ const oldValue = currentValue;
330
+ const newValue = this.store;
331
+ if (isDeepStrictEqual(newValue, oldValue)) {
332
+ return;
333
+ }
334
+ currentValue = newValue;
335
+ callback.call(this, newValue, oldValue);
336
+ };
337
+ this.events.addEventListener("change", onChange);
338
+ return () => {
339
+ this.events.removeEventListener("change", onChange);
340
+ };
341
+ }
342
+ _handleValueChange(getter, callback) {
343
+ let currentValue = getter();
344
+ const onChange = () => {
345
+ const oldValue = currentValue;
346
+ const newValue = getter();
347
+ if (isDeepStrictEqual(newValue, oldValue)) {
348
+ return;
349
+ }
350
+ currentValue = newValue;
351
+ callback.call(this, newValue, oldValue);
352
+ };
353
+ this.events.addEventListener("change", onChange);
354
+ return () => {
355
+ this.events.removeEventListener("change", onChange);
356
+ };
357
+ }
358
+ _deserialize = (value) => JSON.parse(value);
359
+ _serialize = (value) => JSON.stringify(value, void 0, " ");
360
+ _validate(data) {
361
+ if (!this.#validator) {
362
+ return;
363
+ }
364
+ const valid = this.#validator(data);
365
+ if (valid || !this.#validator.errors) {
366
+ return;
367
+ }
368
+ const errors = this.#validator.errors.map(({ instancePath, message = "" }) => `\`${instancePath.slice(1)}\` ${message}`);
369
+ throw new Error("Config schema violation: " + errors.join("; "));
370
+ }
371
+ _ensureDirectory() {
372
+ fs.mkdirSync(path.dirname(this.path), { recursive: true });
373
+ }
374
+ _write(value) {
375
+ let data = this._serialize(value);
376
+ const encryptionKey = this.#encryptionKey;
377
+ if (encryptionKey) {
378
+ const initializationVector = crypto.randomBytes(16);
379
+ const password = crypto.pbkdf2Sync(encryptionKey, initializationVector, 1e4, 32, "sha512");
380
+ const cipher = crypto.createCipheriv(this.#encryptionAlgorithm, password, initializationVector);
381
+ const encryptedData = concatUint8Arrays([cipher.update(stringToUint8Array(data)), cipher.final()]);
382
+ const encryptedParts = [initializationVector, stringToUint8Array(":"), encryptedData];
383
+ if (this.#encryptionAlgorithm === "aes-256-gcm") {
384
+ encryptedParts.push(cipher.getAuthTag());
385
+ }
386
+ data = concatUint8Arrays(encryptedParts);
387
+ }
388
+ if (process.env.SNAP) {
389
+ fs.writeFileSync(this.path, data, { mode: this.#options.configFileMode });
390
+ } else {
391
+ try {
392
+ writeFileSync(this.path, data, { mode: this.#options.configFileMode });
393
+ } catch (error) {
394
+ if (error?.code === "EXDEV") {
395
+ fs.writeFileSync(this.path, data, { mode: this.#options.configFileMode });
396
+ return;
397
+ }
398
+ throw error;
399
+ }
400
+ }
401
+ }
402
+ _watch() {
403
+ this._ensureDirectory();
404
+ if (!fs.existsSync(this.path)) {
405
+ this._write(createPlainObject());
406
+ }
407
+ if (process.platform === "win32" || process.platform === "darwin") {
408
+ this.#debouncedChangeHandler ??= debounceFunction(() => {
409
+ this.events.dispatchEvent(new Event("change"));
410
+ }, { wait: 100 });
411
+ const directory = path.dirname(this.path);
412
+ const basename = path.basename(this.path);
413
+ this.#watcher = fs.watch(directory, { persistent: false, encoding: "utf8" }, (_eventType, filename) => {
414
+ if (filename && filename !== basename) {
415
+ return;
416
+ }
417
+ if (typeof this.#debouncedChangeHandler === "function") {
418
+ this.#debouncedChangeHandler();
419
+ }
420
+ });
421
+ } else {
422
+ this.#debouncedChangeHandler ??= debounceFunction(() => {
423
+ this.events.dispatchEvent(new Event("change"));
424
+ }, { wait: 1e3 });
425
+ fs.watchFile(this.path, { persistent: false }, (_current, _previous) => {
426
+ if (typeof this.#debouncedChangeHandler === "function") {
427
+ this.#debouncedChangeHandler();
428
+ }
429
+ });
430
+ this.#watchFile = true;
431
+ }
432
+ }
433
+ _migrate(migrations, versionToMigrate, beforeEachMigration) {
434
+ let previousMigratedVersion = this._get(MIGRATION_KEY, "0.0.0");
435
+ const newerVersions = Object.keys(migrations).filter((candidateVersion) => this._shouldPerformMigration(candidateVersion, previousMigratedVersion, versionToMigrate));
436
+ let storeBackup = structuredClone(this.store);
437
+ for (const version of newerVersions) {
438
+ try {
439
+ if (beforeEachMigration) {
440
+ beforeEachMigration(this, {
441
+ fromVersion: previousMigratedVersion,
442
+ toVersion: version,
443
+ finalVersion: versionToMigrate,
444
+ versions: newerVersions
445
+ });
446
+ }
447
+ const migration = migrations[version];
448
+ migration?.(this);
449
+ this._set(MIGRATION_KEY, version);
450
+ previousMigratedVersion = version;
451
+ storeBackup = structuredClone(this.store);
452
+ } catch (error) {
453
+ this.store = storeBackup;
454
+ const errorMessage = error instanceof Error ? error.message : String(error);
455
+ throw new Error(`Something went wrong during the migration! Changes applied to the store until this failed migration will be restored. ${errorMessage}`);
456
+ }
457
+ }
458
+ if (this._isVersionInRangeFormat(previousMigratedVersion) || !semver.eq(previousMigratedVersion, versionToMigrate)) {
459
+ this._set(MIGRATION_KEY, versionToMigrate);
460
+ }
461
+ }
462
+ _containsReservedKey(key) {
463
+ if (typeof key === "string") {
464
+ return this._isReservedKeyPath(key);
465
+ }
466
+ if (!key || typeof key !== "object") {
467
+ return false;
468
+ }
469
+ return this._objectContainsReservedKey(key);
470
+ }
471
+ _objectContainsReservedKey(value) {
472
+ if (!value || typeof value !== "object") {
473
+ return false;
474
+ }
475
+ for (const [candidateKey, candidateValue] of Object.entries(value)) {
476
+ if (this._isReservedKeyPath(candidateKey)) {
477
+ return true;
478
+ }
479
+ if (this._objectContainsReservedKey(candidateValue)) {
480
+ return true;
481
+ }
482
+ }
483
+ return false;
484
+ }
485
+ _isReservedKeyPath(candidate) {
486
+ return candidate === INTERNAL_KEY || candidate.startsWith(`${INTERNAL_KEY}.`);
487
+ }
488
+ _isVersionInRangeFormat(version) {
489
+ return semver.clean(version) === null;
490
+ }
491
+ _shouldPerformMigration(candidateVersion, previousMigratedVersion, versionToMigrate) {
492
+ if (this._isVersionInRangeFormat(candidateVersion)) {
493
+ if (previousMigratedVersion !== "0.0.0" && semver.satisfies(previousMigratedVersion, candidateVersion)) {
494
+ return false;
495
+ }
496
+ return semver.satisfies(versionToMigrate, candidateVersion);
497
+ }
498
+ if (semver.lte(candidateVersion, previousMigratedVersion)) {
499
+ return false;
500
+ }
501
+ if (semver.gt(candidateVersion, versionToMigrate)) {
502
+ return false;
503
+ }
504
+ return true;
505
+ }
506
+ _get(key, defaultValue) {
507
+ return getProperty(this.store, key, defaultValue);
508
+ }
509
+ _set(key, value) {
510
+ const { store } = this;
511
+ setProperty(store, key, value);
512
+ this.store = store;
513
+ }
514
+ #prepareOptions(partialOptions) {
515
+ const options = {
516
+ configName: "config",
517
+ fileExtension: "json",
518
+ projectSuffix: "nodejs",
519
+ clearInvalidConfig: false,
520
+ accessPropertiesByDotNotation: true,
521
+ configFileMode: 438,
522
+ ...partialOptions
523
+ };
524
+ options.encryptionAlgorithm ??= defaultEncryptionAlgorithm;
525
+ if (!isSupportedEncryptionAlgorithm(options.encryptionAlgorithm)) {
526
+ throw new TypeError(`The \`encryptionAlgorithm\` option must be one of: ${[...supportedEncryptionAlgorithms].join(", ")}`);
527
+ }
528
+ if (!options.cwd) {
529
+ if (!options.projectName) {
530
+ throw new Error("Please specify the `projectName` option.");
531
+ }
532
+ options.cwd = envPaths(options.projectName, { suffix: options.projectSuffix }).config;
533
+ }
534
+ if (typeof options.fileExtension === "string") {
535
+ options.fileExtension = options.fileExtension.replace(/^\.+/, "");
536
+ }
537
+ return options;
538
+ }
539
+ #setupValidator(options) {
540
+ if (!(options.schema ?? options.ajvOptions ?? options.rootSchema)) {
541
+ return;
542
+ }
543
+ if (options.schema && typeof options.schema !== "object") {
544
+ throw new TypeError("The `schema` option must be an object.");
545
+ }
546
+ const ajvFormats = ajvFormatsModule.default;
547
+ const ajv = new _2020Exports.Ajv2020({
548
+ allErrors: true,
549
+ useDefaults: true,
550
+ ...options.ajvOptions
551
+ });
552
+ ajvFormats(ajv);
553
+ const schema = {
554
+ ...options.rootSchema,
555
+ type: "object",
556
+ properties: options.schema
557
+ };
558
+ this.#validator = ajv.compile(schema);
559
+ this.#captureSchemaDefaults(options.schema);
560
+ }
561
+ #captureSchemaDefaults(schemaConfig) {
562
+ const schemaEntries = Object.entries(schemaConfig ?? {});
563
+ for (const [key, schemaDefinition] of schemaEntries) {
564
+ if (!schemaDefinition || typeof schemaDefinition !== "object") {
565
+ continue;
566
+ }
567
+ if (!Object.hasOwn(schemaDefinition, "default")) {
568
+ continue;
569
+ }
570
+ const { default: defaultValue } = schemaDefinition;
571
+ if (defaultValue === void 0) {
572
+ continue;
573
+ }
574
+ this.#defaultValues[key] = defaultValue;
575
+ }
576
+ }
577
+ #applyDefaultValues(options) {
578
+ if (options.defaults) {
579
+ Object.assign(this.#defaultValues, options.defaults);
580
+ }
581
+ }
582
+ #configureSerialization(options) {
583
+ if (options.serialize) {
584
+ this._serialize = options.serialize;
585
+ }
586
+ if (options.deserialize) {
587
+ this._deserialize = options.deserialize;
588
+ }
589
+ }
590
+ #resolvePath(options) {
591
+ const normalizedFileExtension = typeof options.fileExtension === "string" ? options.fileExtension : void 0;
592
+ const fileExtension = normalizedFileExtension ? `.${normalizedFileExtension}` : "";
593
+ return path.resolve(options.cwd, `${options.configName ?? "config"}${fileExtension}`);
594
+ }
595
+ #initializeStore(options) {
596
+ if (options.migrations) {
597
+ this.#runMigrations(options);
598
+ this._validate(this.store);
599
+ return;
600
+ }
601
+ const fileStore = this.store;
602
+ const storeWithDefaults = Object.assign(createPlainObject(), options.defaults ?? {}, fileStore);
603
+ this._validate(storeWithDefaults);
604
+ try {
605
+ assert.deepEqual(fileStore, storeWithDefaults);
606
+ } catch {
607
+ this.store = storeWithDefaults;
608
+ }
609
+ }
610
+ #runMigrations(options) {
611
+ const { migrations, projectVersion } = options;
612
+ if (!migrations) {
613
+ return;
614
+ }
615
+ if (!projectVersion) {
616
+ throw new Error("Please specify the `projectVersion` option.");
617
+ }
618
+ this.#isInMigration = true;
619
+ try {
620
+ const fileStore = this.store;
621
+ const storeWithDefaults = Object.assign(createPlainObject(), options.defaults ?? {}, fileStore);
622
+ try {
623
+ assert.deepEqual(fileStore, storeWithDefaults);
624
+ } catch {
625
+ this._write(storeWithDefaults);
626
+ }
627
+ this._migrate(migrations, projectVersion, options.beforeEachMigration);
628
+ } finally {
629
+ this.#isInMigration = false;
630
+ }
631
+ }
632
+ }
633
+ export {
634
+ Conf as C
635
+ };