@tinyrack/dotweave 0.39.4

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 (246) hide show
  1. package/bin/index.js +5 -0
  2. package/dist/application.d.ts +5 -0
  3. package/dist/application.d.ts.map +1 -0
  4. package/dist/application.js +86 -0
  5. package/dist/application.js.map +1 -0
  6. package/dist/cli/autocomplete.d.ts +7 -0
  7. package/dist/cli/autocomplete.d.ts.map +1 -0
  8. package/dist/cli/autocomplete.js +62 -0
  9. package/dist/cli/autocomplete.js.map +1 -0
  10. package/dist/cli/cd.d.ts +4 -0
  11. package/dist/cli/cd.d.ts.map +1 -0
  12. package/dist/cli/cd.js +23 -0
  13. package/dist/cli/cd.js.map +1 -0
  14. package/dist/cli/doctor.d.ts +4 -0
  15. package/dist/cli/doctor.d.ts.map +1 -0
  16. package/dist/cli/doctor.js +92 -0
  17. package/dist/cli/doctor.js.map +1 -0
  18. package/dist/cli/index.d.ts +4 -0
  19. package/dist/cli/index.d.ts.map +1 -0
  20. package/dist/cli/index.js +22 -0
  21. package/dist/cli/index.js.map +1 -0
  22. package/dist/cli/init.d.ts +4 -0
  23. package/dist/cli/init.d.ts.map +1 -0
  24. package/dist/cli/init.js +110 -0
  25. package/dist/cli/init.js.map +1 -0
  26. package/dist/cli/profile/index.d.ts +3 -0
  27. package/dist/cli/profile/index.d.ts.map +1 -0
  28. package/dist/cli/profile/index.js +15 -0
  29. package/dist/cli/profile/index.js.map +1 -0
  30. package/dist/cli/profile/list.d.ts +4 -0
  31. package/dist/cli/profile/list.d.ts.map +1 -0
  32. package/dist/cli/profile/list.js +42 -0
  33. package/dist/cli/profile/list.js.map +1 -0
  34. package/dist/cli/profile/use.d.ts +4 -0
  35. package/dist/cli/profile/use.d.ts.map +1 -0
  36. package/dist/cli/profile/use.js +49 -0
  37. package/dist/cli/profile/use.js.map +1 -0
  38. package/dist/cli/pull.d.ts +4 -0
  39. package/dist/cli/pull.d.ts.map +1 -0
  40. package/dist/cli/pull.js +107 -0
  41. package/dist/cli/pull.js.map +1 -0
  42. package/dist/cli/push.d.ts +4 -0
  43. package/dist/cli/push.d.ts.map +1 -0
  44. package/dist/cli/push.js +49 -0
  45. package/dist/cli/push.js.map +1 -0
  46. package/dist/cli/root-commands.d.ts +13 -0
  47. package/dist/cli/root-commands.d.ts.map +1 -0
  48. package/dist/cli/root-commands.js +25 -0
  49. package/dist/cli/root-commands.js.map +1 -0
  50. package/dist/cli/status.d.ts +4 -0
  51. package/dist/cli/status.d.ts.map +1 -0
  52. package/dist/cli/status.js +132 -0
  53. package/dist/cli/status.js.map +1 -0
  54. package/dist/cli/track.d.ts +4 -0
  55. package/dist/cli/track.d.ts.map +1 -0
  56. package/dist/cli/track.js +133 -0
  57. package/dist/cli/track.js.map +1 -0
  58. package/dist/cli/untrack.d.ts +4 -0
  59. package/dist/cli/untrack.d.ts.map +1 -0
  60. package/dist/cli/untrack.js +40 -0
  61. package/dist/cli/untrack.js.map +1 -0
  62. package/dist/config/constants.d.ts +31 -0
  63. package/dist/config/constants.d.ts.map +1 -0
  64. package/dist/config/constants.js +33 -0
  65. package/dist/config/constants.js.map +1 -0
  66. package/dist/config/global-config.d.ts +21 -0
  67. package/dist/config/global-config.d.ts.map +1 -0
  68. package/dist/config/global-config.js +89 -0
  69. package/dist/config/global-config.js.map +1 -0
  70. package/dist/config/identity-file.d.ts +9 -0
  71. package/dist/config/identity-file.d.ts.map +1 -0
  72. package/dist/config/identity-file.js +48 -0
  73. package/dist/config/identity-file.js.map +1 -0
  74. package/dist/config/migration.d.ts +9 -0
  75. package/dist/config/migration.d.ts.map +1 -0
  76. package/dist/config/migration.js +61 -0
  77. package/dist/config/migration.js.map +1 -0
  78. package/dist/config/platform.d.ts +12 -0
  79. package/dist/config/platform.d.ts.map +1 -0
  80. package/dist/config/platform.js +25 -0
  81. package/dist/config/platform.js.map +1 -0
  82. package/dist/config/runtime-env.d.ts +7 -0
  83. package/dist/config/runtime-env.d.ts.map +1 -0
  84. package/dist/config/runtime-env.js +31 -0
  85. package/dist/config/runtime-env.js.map +1 -0
  86. package/dist/config/sync-entry.d.ts +14 -0
  87. package/dist/config/sync-entry.d.ts.map +1 -0
  88. package/dist/config/sync-entry.js +99 -0
  89. package/dist/config/sync-entry.js.map +1 -0
  90. package/dist/config/sync-schema.d.ts +146 -0
  91. package/dist/config/sync-schema.d.ts.map +1 -0
  92. package/dist/config/sync-schema.js +392 -0
  93. package/dist/config/sync-schema.js.map +1 -0
  94. package/dist/config/sync.d.ts +8 -0
  95. package/dist/config/sync.d.ts.map +1 -0
  96. package/dist/config/sync.js +53 -0
  97. package/dist/config/sync.js.map +1 -0
  98. package/dist/config/xdg.d.ts +10 -0
  99. package/dist/config/xdg.d.ts.map +1 -0
  100. package/dist/config/xdg.js +90 -0
  101. package/dist/config/xdg.js.map +1 -0
  102. package/dist/index.d.ts +3 -0
  103. package/dist/index.d.ts.map +1 -0
  104. package/dist/index.js +4 -0
  105. package/dist/index.js.map +1 -0
  106. package/dist/lib/content.d.ts +5 -0
  107. package/dist/lib/content.d.ts.map +1 -0
  108. package/dist/lib/content.js +29 -0
  109. package/dist/lib/content.js.map +1 -0
  110. package/dist/lib/crypto.d.ts +45 -0
  111. package/dist/lib/crypto.d.ts.map +1 -0
  112. package/dist/lib/crypto.js +130 -0
  113. package/dist/lib/crypto.js.map +1 -0
  114. package/dist/lib/env.d.ts +13 -0
  115. package/dist/lib/env.d.ts.map +1 -0
  116. package/dist/lib/env.js +50 -0
  117. package/dist/lib/env.js.map +1 -0
  118. package/dist/lib/error.d.ts +22 -0
  119. package/dist/lib/error.d.ts.map +1 -0
  120. package/dist/lib/error.js +50 -0
  121. package/dist/lib/error.js.map +1 -0
  122. package/dist/lib/file-mode.d.ts +36 -0
  123. package/dist/lib/file-mode.d.ts.map +1 -0
  124. package/dist/lib/file-mode.js +55 -0
  125. package/dist/lib/file-mode.js.map +1 -0
  126. package/dist/lib/filesystem.d.ts +60 -0
  127. package/dist/lib/filesystem.d.ts.map +1 -0
  128. package/dist/lib/filesystem.js +190 -0
  129. package/dist/lib/filesystem.js.map +1 -0
  130. package/dist/lib/git.d.ts +23 -0
  131. package/dist/lib/git.d.ts.map +1 -0
  132. package/dist/lib/git.js +162 -0
  133. package/dist/lib/git.js.map +1 -0
  134. package/dist/lib/jsonc.d.ts +8 -0
  135. package/dist/lib/jsonc.d.ts.map +1 -0
  136. package/dist/lib/jsonc.js +78 -0
  137. package/dist/lib/jsonc.js.map +1 -0
  138. package/dist/lib/path.d.ts +21 -0
  139. package/dist/lib/path.d.ts.map +1 -0
  140. package/dist/lib/path.js +44 -0
  141. package/dist/lib/path.js.map +1 -0
  142. package/dist/lib/promise.d.ts +10 -0
  143. package/dist/lib/promise.d.ts.map +1 -0
  144. package/dist/lib/promise.js +25 -0
  145. package/dist/lib/promise.js.map +1 -0
  146. package/dist/lib/string.d.ts +6 -0
  147. package/dist/lib/string.d.ts.map +1 -0
  148. package/dist/lib/string.js +8 -0
  149. package/dist/lib/string.js.map +1 -0
  150. package/dist/lib/validation.d.ts +7 -0
  151. package/dist/lib/validation.d.ts.map +1 -0
  152. package/dist/lib/validation.js +13 -0
  153. package/dist/lib/validation.js.map +1 -0
  154. package/dist/lib/version.d.ts +2 -0
  155. package/dist/lib/version.d.ts.map +1 -0
  156. package/dist/lib/version.js +4 -0
  157. package/dist/lib/version.js.map +1 -0
  158. package/dist/migrations/global-v3.d.ts +3 -0
  159. package/dist/migrations/global-v3.d.ts.map +1 -0
  160. package/dist/migrations/global-v3.js +5 -0
  161. package/dist/migrations/global-v3.js.map +1 -0
  162. package/dist/services/autocomplete.d.ts +5 -0
  163. package/dist/services/autocomplete.d.ts.map +1 -0
  164. package/dist/services/autocomplete.js +185 -0
  165. package/dist/services/autocomplete.js.map +1 -0
  166. package/dist/services/config-file.d.ts +73 -0
  167. package/dist/services/config-file.d.ts.map +1 -0
  168. package/dist/services/config-file.js +40 -0
  169. package/dist/services/config-file.js.map +1 -0
  170. package/dist/services/doctor.d.ts +16 -0
  171. package/dist/services/doctor.d.ts.map +1 -0
  172. package/dist/services/doctor.js +126 -0
  173. package/dist/services/doctor.js.map +1 -0
  174. package/dist/services/init.d.ts +24 -0
  175. package/dist/services/init.d.ts.map +1 -0
  176. package/dist/services/init.js +265 -0
  177. package/dist/services/init.js.map +1 -0
  178. package/dist/services/local-materialization.d.ts +30 -0
  179. package/dist/services/local-materialization.d.ts.map +1 -0
  180. package/dist/services/local-materialization.js +451 -0
  181. package/dist/services/local-materialization.js.map +1 -0
  182. package/dist/services/local-snapshot.d.ts +26 -0
  183. package/dist/services/local-snapshot.d.ts.map +1 -0
  184. package/dist/services/local-snapshot.js +119 -0
  185. package/dist/services/local-snapshot.js.map +1 -0
  186. package/dist/services/paths.d.ts +8 -0
  187. package/dist/services/paths.d.ts.map +1 -0
  188. package/dist/services/paths.js +71 -0
  189. package/dist/services/paths.js.map +1 -0
  190. package/dist/services/profile.d.ts +39 -0
  191. package/dist/services/profile.d.ts.map +1 -0
  192. package/dist/services/profile.js +124 -0
  193. package/dist/services/profile.js.map +1 -0
  194. package/dist/services/pull.d.ts +38 -0
  195. package/dist/services/pull.d.ts.map +1 -0
  196. package/dist/services/pull.js +148 -0
  197. package/dist/services/pull.js.map +1 -0
  198. package/dist/services/push.d.ts +38 -0
  199. package/dist/services/push.d.ts.map +1 -0
  200. package/dist/services/push.js +120 -0
  201. package/dist/services/push.js.map +1 -0
  202. package/dist/services/repo-artifacts.d.ts +52 -0
  203. package/dist/services/repo-artifacts.d.ts.map +1 -0
  204. package/dist/services/repo-artifacts.js +325 -0
  205. package/dist/services/repo-artifacts.js.map +1 -0
  206. package/dist/services/repo-snapshot.d.ts +7 -0
  207. package/dist/services/repo-snapshot.d.ts.map +1 -0
  208. package/dist/services/repo-snapshot.js +181 -0
  209. package/dist/services/repo-snapshot.js.map +1 -0
  210. package/dist/services/runtime.d.ts +30 -0
  211. package/dist/services/runtime.d.ts.map +1 -0
  212. package/dist/services/runtime.js +71 -0
  213. package/dist/services/runtime.js.map +1 -0
  214. package/dist/services/set.d.ts +41 -0
  215. package/dist/services/set.d.ts.map +1 -0
  216. package/dist/services/set.js +288 -0
  217. package/dist/services/set.js.map +1 -0
  218. package/dist/services/status.d.ts +41 -0
  219. package/dist/services/status.d.ts.map +1 -0
  220. package/dist/services/status.js +87 -0
  221. package/dist/services/status.js.map +1 -0
  222. package/dist/services/terminal/cli-runtime.d.ts +18 -0
  223. package/dist/services/terminal/cli-runtime.d.ts.map +1 -0
  224. package/dist/services/terminal/cli-runtime.js +19 -0
  225. package/dist/services/terminal/cli-runtime.js.map +1 -0
  226. package/dist/services/terminal/logger.d.ts +9 -0
  227. package/dist/services/terminal/logger.d.ts.map +1 -0
  228. package/dist/services/terminal/logger.js +15 -0
  229. package/dist/services/terminal/logger.js.map +1 -0
  230. package/dist/services/terminal/path-completion.d.ts +3 -0
  231. package/dist/services/terminal/path-completion.d.ts.map +1 -0
  232. package/dist/services/terminal/path-completion.js +108 -0
  233. package/dist/services/terminal/path-completion.js.map +1 -0
  234. package/dist/services/terminal/shell.d.ts +24 -0
  235. package/dist/services/terminal/shell.d.ts.map +1 -0
  236. package/dist/services/terminal/shell.js +227 -0
  237. package/dist/services/terminal/shell.js.map +1 -0
  238. package/dist/services/track.d.ts +20 -0
  239. package/dist/services/track.d.ts.map +1 -0
  240. package/dist/services/track.js +224 -0
  241. package/dist/services/track.js.map +1 -0
  242. package/dist/services/untrack.d.ts +13 -0
  243. package/dist/services/untrack.d.ts.map +1 -0
  244. package/dist/services/untrack.js +133 -0
  245. package/dist/services/untrack.js.map +1 -0
  246. package/package.json +84 -0
@@ -0,0 +1,52 @@
1
+ import type { ConsolaInstance } from "consola";
2
+ import { type ResolvedSyncConfigEntry } from "#app/config/sync.ts";
3
+ import type { SnapshotNode } from "./local-snapshot.ts";
4
+ import type { EffectiveSyncConfig } from "./runtime.ts";
5
+ type ArtifactConfig = EffectiveSyncConfig;
6
+ export declare const collectArtifactProfiles: (entries: readonly Pick<ResolvedSyncConfigEntry, "profiles">[]) => Set<string>;
7
+ export type RepoArtifact = Readonly<{
8
+ category: "plain";
9
+ kind: "directory";
10
+ profile: string;
11
+ repoPath: string;
12
+ }> | Readonly<{
13
+ category: "plain";
14
+ kind: "file";
15
+ repoPath: string;
16
+ profile: string;
17
+ contents: Uint8Array;
18
+ executable: boolean;
19
+ }> | Readonly<{
20
+ category: "plain";
21
+ kind: "symlink";
22
+ profile: string;
23
+ repoPath: string;
24
+ linkTarget: string;
25
+ }> | Readonly<{
26
+ category: "secret";
27
+ kind: "file";
28
+ profile: string;
29
+ repoPath: string;
30
+ contents: Uint8Array;
31
+ executable: boolean;
32
+ }>;
33
+ export declare const buildArtifactKey: (artifact: RepoArtifact) => string;
34
+ export declare const isSecretArtifactPath: (relativePath: string) => boolean;
35
+ export declare const stripSecretArtifactSuffix: (relativePath: string) => string | undefined;
36
+ export declare const assertStorageSafeRepoPath: (repoPath: string) => void;
37
+ export declare const resolveArtifactRelativePath: (artifact: Pick<RepoArtifact, "category" | "profile" | "repoPath">) => string;
38
+ export declare const parseArtifactRelativePath: (relativePath: string) => {
39
+ profile: string;
40
+ repoPath: string;
41
+ secret: boolean;
42
+ };
43
+ export declare const buildRepoArtifacts: (snapshot: ReadonlyMap<string, SnapshotNode>, config: ArtifactConfig, reporter?: ConsolaInstance) => Promise<RepoArtifact[]>;
44
+ export declare const collectExistingArtifactKeys: (syncDirectory: string, config: ArtifactConfig, reporter?: ConsolaInstance) => Promise<Set<string>>;
45
+ type AgeWriteConfig = Readonly<{
46
+ identityFile: string;
47
+ recipients: readonly string[];
48
+ }>;
49
+ export declare const isRepoArtifactCurrent: (rootDirectory: string, artifact: RepoArtifact, ageConfig?: Pick<AgeWriteConfig, "identityFile">) => Promise<boolean>;
50
+ export declare const writeArtifactsToDirectory: (rootDirectory: string, artifacts: readonly RepoArtifact[], ageConfig?: AgeWriteConfig, reporter?: ConsolaInstance) => Promise<void>;
51
+ export {};
52
+ //# sourceMappingURL=repo-artifacts.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"repo-artifacts.d.ts","sourceRoot":"","sources":["../../src/services/repo-artifacts.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AAE/C,OAAO,EAGL,KAAK,uBAAuB,EAE7B,MAAM,qBAAqB,CAAC;AAmB7B,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACxD,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,cAAc,CAAC;AAExD,KAAK,cAAc,GAAG,mBAAmB,CAAC;AAW1C,eAAO,MAAM,uBAAuB,GAClC,SAAS,SAAS,IAAI,CAAC,uBAAuB,EAAE,UAAU,CAAC,EAAE,gBAY9D,CAAC;AAEF,MAAM,MAAM,YAAY,GACpB,QAAQ,CAAC;IACP,QAAQ,EAAE,OAAO,CAAC;IAClB,IAAI,EAAE,WAAW,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;CAClB,CAAC,GACF,QAAQ,CAAC;IACP,QAAQ,EAAE,OAAO,CAAC;IAClB,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,UAAU,CAAC;IACrB,UAAU,EAAE,OAAO,CAAC;CACrB,CAAC,GACF,QAAQ,CAAC;IACP,QAAQ,EAAE,OAAO,CAAC;IAClB,IAAI,EAAE,SAAS,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;CACpB,CAAC,GACF,QAAQ,CAAC;IACP,QAAQ,EAAE,QAAQ,CAAC;IACnB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,UAAU,CAAC;IACrB,UAAU,EAAE,OAAO,CAAC;CACrB,CAAC,CAAC;AAEP,eAAO,MAAM,gBAAgB,GAAI,UAAU,YAAY,WAMtD,CAAC;AAEF,eAAO,MAAM,oBAAoB,GAAI,cAAc,MAAM,YAExD,CAAC;AAEF,eAAO,MAAM,yBAAyB,GAAI,cAAc,MAAM,uBAM7D,CAAC;AAEF,eAAO,MAAM,yBAAyB,GAAI,UAAU,MAAM,SAazD,CAAC;AAEF,eAAO,MAAM,2BAA2B,GACtC,UAAU,IAAI,CAAC,YAAY,EAAE,UAAU,GAAG,SAAS,GAAG,UAAU,CAAC,WAOlE,CAAC;AAEF,eAAO,MAAM,yBAAyB,GAAI,cAAc,MAAM;;;;CAqB7D,CAAC;AAEF,eAAO,MAAM,kBAAkB,GAC7B,UAAU,WAAW,CAAC,MAAM,EAAE,YAAY,CAAC,EAC3C,QAAQ,cAAc,EACtB,WAAW,eAAe,4BA+F3B,CAAC;AAyCF,eAAO,MAAM,2BAA2B,GACtC,eAAe,MAAM,EACrB,QAAQ,cAAc,EACtB,WAAW,eAAe,yBAuE3B,CAAC;AAEF,KAAK,cAAc,GAAG,QAAQ,CAAC;IAC7B,YAAY,EAAE,MAAM,CAAC;IACrB,UAAU,EAAE,SAAS,MAAM,EAAE,CAAC;CAC/B,CAAC,CAAC;AAyCH,eAAO,MAAM,qBAAqB,GAChC,eAAe,MAAM,EACrB,UAAU,YAAY,EACtB,YAAY,IAAI,CAAC,cAAc,EAAE,cAAc,CAAC,qBA8CjD,CAAC;AAEF,eAAO,MAAM,yBAAyB,GACpC,eAAe,MAAM,EACrB,WAAW,SAAS,YAAY,EAAE,EAClC,YAAY,cAAc,EAC1B,WAAW,eAAe,kBAyE3B,CAAC"}
@@ -0,0 +1,325 @@
1
+ import { lstat, mkdir, readFile, readlink } from "node:fs/promises";
2
+ import { join } from "node:path";
3
+ import { CONSTANTS } from "#app/config/constants.ts";
4
+ import { findOwningSyncEntry, hasReservedSyncArtifactSuffixSegment, resolveSyncRule, } from "#app/config/sync.ts";
5
+ import { fileContentsEqual, shouldNormalizeTextLineEndings, } from "#app/lib/content.ts";
6
+ import { decryptSecretFile, encryptSecretFile } from "#app/lib/crypto.ts";
7
+ import { DotweaveError } from "#app/lib/error.ts";
8
+ import { buildExecutableMode, supportsPosixFileModes, } from "#app/lib/file-mode.ts";
9
+ import { getPathStats, listDirectoryEntries, writeFileNode, writeSymlinkNode, } from "#app/lib/filesystem.ts";
10
+ import { buildDirectoryKey } from "#app/lib/path.ts";
11
+ import { limitConcurrency } from "#app/lib/promise.ts";
12
+ const isActiveArtifactRule = (rule, profile) => {
13
+ return (rule !== undefined && rule.mode !== "ignore" && rule.profile === profile);
14
+ };
15
+ export const collectArtifactProfiles = (entries) => {
16
+ const profiles = new Set();
17
+ profiles.add(CONSTANTS.SYNC.DEFAULT_PROFILE);
18
+ for (const entry of entries) {
19
+ for (const profile of entry.profiles) {
20
+ profiles.add(profile);
21
+ }
22
+ }
23
+ return profiles;
24
+ };
25
+ export const buildArtifactKey = (artifact) => {
26
+ const relativePath = resolveArtifactRelativePath(artifact);
27
+ return artifact.kind === "directory"
28
+ ? buildDirectoryKey(relativePath)
29
+ : relativePath;
30
+ };
31
+ export const isSecretArtifactPath = (relativePath) => {
32
+ return relativePath.endsWith(CONSTANTS.SYNC.SECRET_ARTIFACT_SUFFIX);
33
+ };
34
+ export const stripSecretArtifactSuffix = (relativePath) => {
35
+ if (!isSecretArtifactPath(relativePath)) {
36
+ return undefined;
37
+ }
38
+ return relativePath.slice(0, -CONSTANTS.SYNC.SECRET_ARTIFACT_SUFFIX.length);
39
+ };
40
+ export const assertStorageSafeRepoPath = (repoPath) => {
41
+ if (!hasReservedSyncArtifactSuffixSegment(repoPath)) {
42
+ return;
43
+ }
44
+ throw new DotweaveError(`Tracked sync paths must not use the reserved suffix ${CONSTANTS.SYNC.SECRET_ARTIFACT_SUFFIX}.`, {
45
+ code: "RESERVED_SECRET_SUFFIX",
46
+ details: [`Repository path: ${repoPath}`],
47
+ hint: "Rename the tracked path so no segment ends with the secret artifact suffix.",
48
+ });
49
+ };
50
+ export const resolveArtifactRelativePath = (artifact) => {
51
+ const profileRelativePath = `${artifact.profile}/${artifact.repoPath}`;
52
+ return artifact.category === "secret"
53
+ ? `${profileRelativePath}${CONSTANTS.SYNC.SECRET_ARTIFACT_SUFFIX}`
54
+ : profileRelativePath;
55
+ };
56
+ export const parseArtifactRelativePath = (relativePath) => {
57
+ const secret = relativePath.endsWith(CONSTANTS.SYNC.SECRET_ARTIFACT_SUFFIX);
58
+ const logicalPath = secret
59
+ ? relativePath.slice(0, -CONSTANTS.SYNC.SECRET_ARTIFACT_SUFFIX.length)
60
+ : relativePath;
61
+ const segments = logicalPath.split("/");
62
+ if (segments.length < 2 || segments[0] === undefined) {
63
+ throw new DotweaveError("Repository artifact path is invalid.", {
64
+ code: "INVALID_REPO_ENTRY",
65
+ details: [`Repository path: ${relativePath}`],
66
+ });
67
+ }
68
+ const [profile, ...repoPathSegments] = segments;
69
+ return {
70
+ profile,
71
+ repoPath: repoPathSegments.join("/"),
72
+ secret,
73
+ };
74
+ };
75
+ export const buildRepoArtifacts = async (snapshot, config, reporter) => {
76
+ const artifacts = [];
77
+ const seenArtifactKeys = new Set();
78
+ let preparedArtifactCount = 0;
79
+ const addArtifact = (artifact) => {
80
+ const key = buildArtifactKey(artifact);
81
+ if (seenArtifactKeys.has(key)) {
82
+ throw new DotweaveError("Duplicate repository artifact was generated.", {
83
+ code: "DUPLICATE_REPO_ARTIFACT",
84
+ details: [`Artifact key: ${key}`],
85
+ });
86
+ }
87
+ seenArtifactKeys.add(key);
88
+ artifacts.push(artifact);
89
+ preparedArtifactCount += 1;
90
+ const relativePath = resolveArtifactRelativePath(artifact);
91
+ if ((reporter?.level ?? 0) >= 4) {
92
+ reporter?.verbose(`prepared repository artifact ${relativePath}`);
93
+ }
94
+ else if (preparedArtifactCount % 100 === 0) {
95
+ reporter?.start(`Prepared ${preparedArtifactCount} repository artifacts...`);
96
+ }
97
+ };
98
+ for (const repoPath of [...snapshot.keys()].sort((left, right) => {
99
+ return left.localeCompare(right);
100
+ })) {
101
+ assertStorageSafeRepoPath(repoPath);
102
+ const node = snapshot.get(repoPath);
103
+ const owningEntry = findOwningSyncEntry(config, repoPath);
104
+ const resolvedRule = resolveSyncRule(config, repoPath, config.activeProfile);
105
+ if (node === undefined ||
106
+ owningEntry === undefined ||
107
+ resolvedRule === undefined) {
108
+ continue;
109
+ }
110
+ if (node.type === "directory") {
111
+ addArtifact({
112
+ category: "plain",
113
+ kind: "directory",
114
+ profile: resolvedRule.profile,
115
+ repoPath,
116
+ });
117
+ continue;
118
+ }
119
+ if (node.type === "symlink") {
120
+ addArtifact({
121
+ category: "plain",
122
+ kind: "symlink",
123
+ linkTarget: node.linkTarget,
124
+ profile: resolvedRule.profile,
125
+ repoPath,
126
+ });
127
+ continue;
128
+ }
129
+ if (!node.secret) {
130
+ addArtifact({
131
+ category: "plain",
132
+ contents: node.contents,
133
+ executable: node.executable,
134
+ kind: "file",
135
+ profile: resolvedRule.profile,
136
+ repoPath,
137
+ });
138
+ continue;
139
+ }
140
+ addArtifact({
141
+ category: "secret",
142
+ contents: node.contents,
143
+ executable: node.executable,
144
+ kind: "file",
145
+ profile: resolvedRule.profile,
146
+ repoPath,
147
+ });
148
+ }
149
+ return artifacts;
150
+ };
151
+ const collectArtifactLeafKeys = async (rootDirectory, keys, prefix, onKey) => {
152
+ const rootStats = await getPathStats(rootDirectory);
153
+ if (rootStats === undefined) {
154
+ return;
155
+ }
156
+ if (!rootStats.isDirectory()) {
157
+ if (prefix !== undefined) {
158
+ keys.add(prefix);
159
+ onKey?.(prefix);
160
+ }
161
+ return;
162
+ }
163
+ const entries = await listDirectoryEntries(rootDirectory);
164
+ for (const entry of entries) {
165
+ const absolutePath = join(rootDirectory, entry.name);
166
+ const relativePath = prefix === undefined ? entry.name : `${prefix}/${entry.name}`;
167
+ const stats = await lstat(absolutePath);
168
+ if (stats?.isDirectory()) {
169
+ await collectArtifactLeafKeys(absolutePath, keys, relativePath, onKey);
170
+ continue;
171
+ }
172
+ keys.add(relativePath);
173
+ onKey?.(relativePath);
174
+ }
175
+ };
176
+ export const collectExistingArtifactKeys = async (syncDirectory, config, reporter) => {
177
+ const keys = new Set();
178
+ const artifactsDirectory = syncDirectory;
179
+ const artifactProfiles = collectArtifactProfiles(config.entries);
180
+ let discoveredArtifactCount = 0;
181
+ const noteDiscoveredArtifact = (key) => {
182
+ discoveredArtifactCount += 1;
183
+ if ((reporter?.level ?? 0) >= 4) {
184
+ reporter?.verbose(`found repository artifact ${key}`);
185
+ }
186
+ else if (discoveredArtifactCount % 100 === 0) {
187
+ reporter?.start(`Scanned ${discoveredArtifactCount} repository artifacts...`);
188
+ }
189
+ };
190
+ await Promise.all([...artifactProfiles].map(async (profile) => {
191
+ await collectArtifactLeafKeys(join(artifactsDirectory, profile), keys, profile, noteDiscoveredArtifact);
192
+ }));
193
+ for (const key of [...keys]) {
194
+ if (key.startsWith("__dir__:")) {
195
+ continue;
196
+ }
197
+ const artifact = parseArtifactRelativePath(key);
198
+ const rule = resolveSyncRule(config, artifact.repoPath, config.activeProfile);
199
+ if (!isActiveArtifactRule(rule, artifact.profile)) {
200
+ keys.delete(key);
201
+ }
202
+ }
203
+ for (const entry of config.entries) {
204
+ if (entry.kind !== "directory") {
205
+ continue;
206
+ }
207
+ const rule = resolveSyncRule(config, entry.repoPath, config.activeProfile);
208
+ if (rule === undefined || rule.mode === "ignore") {
209
+ continue;
210
+ }
211
+ const relativePath = resolveArtifactRelativePath({
212
+ category: "plain",
213
+ profile: rule.profile,
214
+ repoPath: entry.repoPath,
215
+ });
216
+ const path = join(artifactsDirectory, ...relativePath.split("/"));
217
+ if ((await getPathStats(path))?.isDirectory()) {
218
+ keys.add(buildDirectoryKey(relativePath));
219
+ }
220
+ }
221
+ return keys;
222
+ };
223
+ const fileModeMatches = (actualMode, executable) => {
224
+ if (!supportsPosixFileModes()) {
225
+ return true;
226
+ }
227
+ return (actualMode & 0o777) === buildExecutableMode(executable);
228
+ };
229
+ const isSecretArtifactUnchanged = async (artifactPath, plaintext, identityFile) => {
230
+ let existingCiphertext;
231
+ try {
232
+ existingCiphertext = await readFile(artifactPath, "utf8");
233
+ }
234
+ catch {
235
+ return false;
236
+ }
237
+ try {
238
+ const existingPlaintext = await decryptSecretFile(existingCiphertext, identityFile);
239
+ return fileContentsEqual(existingPlaintext, plaintext, {
240
+ normalizeTextLineEndings: shouldNormalizeTextLineEndings(),
241
+ });
242
+ }
243
+ catch {
244
+ return false;
245
+ }
246
+ };
247
+ const normalizeLinkTargetForComparison = (target) => {
248
+ return process.platform === "win32" ? target.replaceAll("\\", "/") : target;
249
+ };
250
+ export const isRepoArtifactCurrent = async (rootDirectory, artifact, ageConfig) => {
251
+ const relativePath = resolveArtifactRelativePath(artifact);
252
+ const artifactPath = join(rootDirectory, ...relativePath.split("/"));
253
+ const stats = await getPathStats(artifactPath);
254
+ if (artifact.kind === "directory") {
255
+ return stats?.isDirectory() ?? false;
256
+ }
257
+ if (artifact.kind === "symlink") {
258
+ const linkTarget = stats?.isSymbolicLink() === true ? await readlink(artifactPath) : "";
259
+ return (stats?.isSymbolicLink() === true &&
260
+ normalizeLinkTargetForComparison(linkTarget) ===
261
+ normalizeLinkTargetForComparison(artifact.linkTarget));
262
+ }
263
+ if (stats?.isFile() !== true) {
264
+ return false;
265
+ }
266
+ if (!fileModeMatches(stats.mode, artifact.executable)) {
267
+ return false;
268
+ }
269
+ if (artifact.category === "secret") {
270
+ if (ageConfig === undefined) {
271
+ return false;
272
+ }
273
+ return isSecretArtifactUnchanged(artifactPath, artifact.contents, ageConfig.identityFile);
274
+ }
275
+ const existingContents = await readFile(artifactPath);
276
+ return fileContentsEqual(existingContents, artifact.contents, {
277
+ normalizeTextLineEndings: shouldNormalizeTextLineEndings(),
278
+ });
279
+ };
280
+ export const writeArtifactsToDirectory = async (rootDirectory, artifacts, ageConfig, reporter) => {
281
+ await mkdir(rootDirectory, { recursive: true });
282
+ let processedArtifactCount = 0;
283
+ const noteProcessedArtifact = (relativePath, action) => {
284
+ processedArtifactCount += 1;
285
+ if ((reporter?.level ?? 0) >= 4) {
286
+ reporter?.verbose(`${action} ${relativePath}`);
287
+ return;
288
+ }
289
+ if (processedArtifactCount % 100 === 0) {
290
+ reporter?.start(`Processed ${processedArtifactCount} repository artifacts...`);
291
+ }
292
+ };
293
+ await limitConcurrency(CONSTANTS.SYNC.DEFAULT_CONCURRENCY, artifacts, async (artifact) => {
294
+ const relativePath = resolveArtifactRelativePath(artifact);
295
+ const artifactPath = join(rootDirectory, ...relativePath.split("/"));
296
+ if (await isRepoArtifactCurrent(rootDirectory, artifact, ageConfig === undefined
297
+ ? undefined
298
+ : { identityFile: ageConfig.identityFile })) {
299
+ noteProcessedArtifact(relativePath, "skipped unchanged repository artifact");
300
+ return;
301
+ }
302
+ if (artifact.kind === "directory") {
303
+ await mkdir(artifactPath, { recursive: true });
304
+ noteProcessedArtifact(relativePath, "ensured repository directory");
305
+ return;
306
+ }
307
+ if (artifact.kind === "symlink") {
308
+ await writeSymlinkNode(artifactPath, artifact.linkTarget);
309
+ noteProcessedArtifact(relativePath, "wrote repository symlink");
310
+ return;
311
+ }
312
+ if (artifact.category === "secret" && ageConfig !== undefined) {
313
+ const encrypted = await encryptSecretFile(artifact.contents, ageConfig.recipients);
314
+ await writeFileNode(artifactPath, {
315
+ contents: encrypted,
316
+ executable: artifact.executable,
317
+ });
318
+ noteProcessedArtifact(relativePath, "wrote repository secret artifact");
319
+ return;
320
+ }
321
+ await writeFileNode(artifactPath, artifact);
322
+ noteProcessedArtifact(relativePath, "wrote repository file");
323
+ });
324
+ };
325
+ //# sourceMappingURL=repo-artifacts.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"repo-artifacts.js","sourceRoot":"","sources":["../../src/services/repo-artifacts.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,7 @@
1
+ import type { ConsolaInstance } from "consola";
2
+ import { type SnapshotNode } from "./local-snapshot.ts";
3
+ import type { EffectiveSyncConfig } from "./runtime.ts";
4
+ type RepositorySnapshotConfig = EffectiveSyncConfig;
5
+ export declare const buildRepositorySnapshot: (syncDirectory: string, config: RepositorySnapshotConfig, reporter?: ConsolaInstance) => Promise<Map<string, SnapshotNode>>;
6
+ export {};
7
+ //# sourceMappingURL=repo-snapshot.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"repo-snapshot.d.ts","sourceRoot":"","sources":["../../src/services/repo-snapshot.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AAM/C,OAAO,EAAmB,KAAK,YAAY,EAAE,MAAM,qBAAqB,CAAC;AAMzE,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,cAAc,CAAC;AAExD,KAAK,wBAAwB,GAAG,mBAAmB,CAAC;AAuOpD,eAAO,MAAM,uBAAuB,GAClC,eAAe,MAAM,EACrB,QAAQ,wBAAwB,EAChC,WAAW,eAAe,uCAkE3B,CAAC"}
@@ -0,0 +1,181 @@
1
+ import { lstat, readFile, readlink } from "node:fs/promises";
2
+ import { join } from "node:path";
3
+ import { resolveManagedSyncMode, resolveSyncRule } from "#app/config/sync.ts";
4
+ import { decryptSecretFile } from "#app/lib/crypto.ts";
5
+ import { DotweaveError, wrapUnknownError } from "#app/lib/error.ts";
6
+ import { isExecutableMode } from "#app/lib/file-mode.ts";
7
+ import { getPathStats, listDirectoryEntries } from "#app/lib/filesystem.ts";
8
+ import { addSnapshotNode } from "./local-snapshot.js";
9
+ import { assertStorageSafeRepoPath, collectArtifactProfiles, parseArtifactRelativePath, } from "./repo-artifacts.js";
10
+ const reportRepositoryScanProgress = (reporter, state, storagePath, kind) => {
11
+ state.scannedStorageEntryCount += 1;
12
+ if ((reporter?.level ?? 0) >= 4) {
13
+ reporter?.verbose(`scanned repository ${kind} ${storagePath}`);
14
+ return;
15
+ }
16
+ if (state.scannedStorageEntryCount % 100 === 0) {
17
+ reporter?.start(`Scanned ${state.scannedStorageEntryCount} repository entries...`);
18
+ }
19
+ };
20
+ const isActiveStorageProfile = (storageProfile, config, repoPath) => {
21
+ const rule = resolveSyncRule(config, repoPath, config.activeProfile);
22
+ if (rule === undefined || rule.mode === "ignore") {
23
+ return false;
24
+ }
25
+ return rule.profile === storageProfile;
26
+ };
27
+ const readArtifactLeaf = async (absolutePath, storagePath, config, snapshot) => {
28
+ const artifact = parseArtifactRelativePath(storagePath);
29
+ if (!isActiveStorageProfile(artifact.profile, config, artifact.repoPath)) {
30
+ return;
31
+ }
32
+ assertStorageSafeRepoPath(artifact.repoPath);
33
+ const rule = resolveSyncRule(config, artifact.repoPath, config.activeProfile);
34
+ if (rule === undefined) {
35
+ throw new DotweaveError("Repository path is not managed by the current sync configuration.", {
36
+ code: "UNMANAGED_SYNC_PATH",
37
+ details: [
38
+ `Repository path: ${artifact.repoPath}`,
39
+ `Context: ${storagePath}`,
40
+ ],
41
+ hint: "Add the parent path to dotweave, or remove stray artifacts from the sync directory.",
42
+ });
43
+ }
44
+ if (rule.profile !== artifact.profile) {
45
+ throw new DotweaveError("Repository artifact is stored under the wrong profile directory.", {
46
+ code: "REPO_PROFILE_MISMATCH",
47
+ details: [
48
+ `Repository path: ${artifact.repoPath}`,
49
+ `Stored profile: ${artifact.profile}`,
50
+ `Expected profile: ${rule.profile}`,
51
+ ],
52
+ });
53
+ }
54
+ if (rule.mode === "ignore") {
55
+ return;
56
+ }
57
+ if (artifact.secret) {
58
+ if (rule.mode !== "secret") {
59
+ throw new DotweaveError("Plain sync path is stored as a secret artifact in the repository.", {
60
+ code: "PLAIN_STORED_SECRET",
61
+ details: [`Repository path: ${storagePath}`],
62
+ });
63
+ }
64
+ const stats = await lstat(absolutePath);
65
+ if (!stats.isFile()) {
66
+ throw new DotweaveError("Secret repository artifacts must be regular files, not symlinks.", {
67
+ code: "SECRET_ARTIFACT_SYMLINK",
68
+ details: [`Repository path: ${storagePath}`],
69
+ });
70
+ }
71
+ let contents;
72
+ try {
73
+ contents = await decryptSecretFile(await readFile(absolutePath, "utf8"), config.age.identityFile);
74
+ }
75
+ catch (error) {
76
+ throw wrapUnknownError("Failed to decrypt a secret repository artifact.", error, {
77
+ code: "SECRET_ARTIFACT_DECRYPT_FAILED",
78
+ details: [
79
+ `Repository path: ${storagePath}`,
80
+ `Identity file: ${config.age.identityFile}`,
81
+ ],
82
+ });
83
+ }
84
+ addSnapshotNode(snapshot, artifact.repoPath, {
85
+ contents,
86
+ executable: isExecutableMode(stats.mode),
87
+ secret: true,
88
+ type: "file",
89
+ });
90
+ return;
91
+ }
92
+ const mode = resolveManagedSyncMode(config, artifact.repoPath, config.activeProfile, storagePath);
93
+ const stats = await lstat(absolutePath);
94
+ if (stats.isSymbolicLink()) {
95
+ if (mode === "secret") {
96
+ throw new DotweaveError("Secret sync path is stored as a plain artifact in the repository.", {
97
+ code: "SECRET_STORED_PLAIN",
98
+ details: [`Repository path: ${storagePath}`],
99
+ });
100
+ }
101
+ addSnapshotNode(snapshot, artifact.repoPath, {
102
+ linkTarget: await readlink(absolutePath),
103
+ type: "symlink",
104
+ });
105
+ return;
106
+ }
107
+ if (!stats.isFile()) {
108
+ throw new DotweaveError("Repository contains an unsupported plain artifact type.", {
109
+ code: "UNSUPPORTED_REPO_ENTRY",
110
+ details: [`Repository path: ${storagePath}`],
111
+ });
112
+ }
113
+ if (mode === "secret") {
114
+ throw new DotweaveError("Secret sync path is stored as a plain artifact in the repository.", {
115
+ code: "SECRET_STORED_PLAIN",
116
+ details: [`Repository path: ${storagePath}`],
117
+ });
118
+ }
119
+ addSnapshotNode(snapshot, artifact.repoPath, {
120
+ contents: await readFile(absolutePath),
121
+ executable: isExecutableMode(stats.mode),
122
+ secret: false,
123
+ type: "file",
124
+ });
125
+ };
126
+ const walkArtifactTree = async (rootDirectory, config, snapshot, prefix = "", reporter, progressState = {
127
+ scannedStorageEntryCount: 0,
128
+ }) => {
129
+ const entries = await listDirectoryEntries(rootDirectory);
130
+ for (const entry of entries) {
131
+ const absolutePath = join(rootDirectory, entry.name);
132
+ const storagePath = prefix === "" ? entry.name : `${prefix}/${entry.name}`;
133
+ const stats = await lstat(absolutePath);
134
+ reportRepositoryScanProgress(reporter, progressState, storagePath, stats.isDirectory() ? "directory" : "file");
135
+ if (stats.isDirectory()) {
136
+ await walkArtifactTree(absolutePath, config, snapshot, storagePath, reporter, progressState);
137
+ continue;
138
+ }
139
+ await readArtifactLeaf(absolutePath, storagePath, config, snapshot);
140
+ }
141
+ };
142
+ export const buildRepositorySnapshot = async (syncDirectory, config, reporter) => {
143
+ const snapshot = new Map();
144
+ const artifactsDirectory = syncDirectory;
145
+ const artifactProfiles = collectArtifactProfiles(config.entries);
146
+ const progressState = { scannedStorageEntryCount: 0 };
147
+ await Promise.all([...artifactProfiles].map(async (profile) => {
148
+ const profileDirectory = join(artifactsDirectory, profile);
149
+ const profileStats = await getPathStats(profileDirectory);
150
+ if (profileStats?.isDirectory()) {
151
+ reporter?.start(`Scanning repository profile ${profile}...`);
152
+ await walkArtifactTree(profileDirectory, config, snapshot, profile, reporter, progressState);
153
+ }
154
+ }));
155
+ for (const entry of config.entries) {
156
+ if (entry.kind !== "directory") {
157
+ continue;
158
+ }
159
+ const rule = resolveSyncRule(config, entry.repoPath, config.activeProfile);
160
+ if (rule === undefined) {
161
+ continue;
162
+ }
163
+ const hasTrackedChildren = [...snapshot.keys()].some((repoPath) => {
164
+ return repoPath.startsWith(`${entry.repoPath}/`);
165
+ });
166
+ const expectedPath = join(artifactsDirectory, rule.profile, ...entry.repoPath.split("/"));
167
+ const expectedStats = await getPathStats(expectedPath);
168
+ if (expectedStats !== undefined && !expectedStats.isDirectory()) {
169
+ throw new DotweaveError("Directory sync entry is not stored as a directory in the repository.", {
170
+ code: "DIRECTORY_ENTRY_NOT_DIRECTORY",
171
+ details: [`Repository path: ${entry.repoPath}`],
172
+ });
173
+ }
174
+ if ((expectedStats?.isDirectory() ?? false) &&
175
+ (rule.mode !== "ignore" || hasTrackedChildren)) {
176
+ addSnapshotNode(snapshot, entry.repoPath, { type: "directory" });
177
+ }
178
+ }
179
+ return snapshot;
180
+ };
181
+ //# sourceMappingURL=repo-snapshot.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"repo-snapshot.js","sourceRoot":"","sources":["../../src/services/repo-snapshot.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,30 @@
1
+ import { type ActiveProfileSelection, type GlobalDotweaveConfig } from "#app/config/global-config.ts";
2
+ import { type AgeConfig, type ResolvedSyncConfig, type SyncConfigResolutionContext } from "#app/config/sync.ts";
3
+ export type RuntimeAgeConfig = Readonly<{
4
+ identityFile: string;
5
+ recipients: readonly string[];
6
+ }>;
7
+ export type SyncPaths = Readonly<{
8
+ artifactsDirectory: string;
9
+ configPath: string;
10
+ globalConfigPath: string;
11
+ homeDirectory: string;
12
+ syncDirectory: string;
13
+ }>;
14
+ export type EffectiveSyncConfig = ResolvedSyncConfig & Readonly<{
15
+ activeProfile?: string;
16
+ age: RuntimeAgeConfig;
17
+ }>;
18
+ export type LoadedSyncConfig = Readonly<{
19
+ effectiveConfig: EffectiveSyncConfig;
20
+ fullConfig: ResolvedSyncConfig;
21
+ globalConfig?: GlobalDotweaveConfig;
22
+ }>;
23
+ export declare const resolveSyncConfigResolutionContext: () => SyncConfigResolutionContext;
24
+ export declare const resolveSyncPaths: () => SyncPaths;
25
+ export declare const resolveAgeFromSyncConfig: (age: AgeConfig) => RuntimeAgeConfig;
26
+ export declare const buildEffectiveSyncConfig: (fullConfig: ResolvedSyncConfig, selection: ActiveProfileSelection, age: RuntimeAgeConfig) => EffectiveSyncConfig;
27
+ export declare const loadSyncConfig: (syncDirectory: string, options?: Readonly<{
28
+ profile?: string;
29
+ }>) => Promise<LoadedSyncConfig>;
30
+ //# sourceMappingURL=runtime.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"runtime.d.ts","sourceRoot":"","sources":["../../src/services/runtime.ts"],"names":[],"mappings":"AACA,OAAO,EACL,KAAK,sBAAsB,EAC3B,KAAK,oBAAoB,EAG1B,MAAM,8BAA8B,CAAC;AAUtC,OAAO,EACL,KAAK,SAAS,EACd,KAAK,kBAAkB,EAGvB,KAAK,2BAA2B,EACjC,MAAM,qBAAqB,CAAC;AAG7B,MAAM,MAAM,gBAAgB,GAAG,QAAQ,CAAC;IACtC,YAAY,EAAE,MAAM,CAAC;IACrB,UAAU,EAAE,SAAS,MAAM,EAAE,CAAC;CAC/B,CAAC,CAAC;AAEH,MAAM,MAAM,SAAS,GAAG,QAAQ,CAAC;IAC/B,kBAAkB,EAAE,MAAM,CAAC;IAC3B,UAAU,EAAE,MAAM,CAAC;IACnB,gBAAgB,EAAE,MAAM,CAAC;IACzB,aAAa,EAAE,MAAM,CAAC;IACtB,aAAa,EAAE,MAAM,CAAC;CACvB,CAAC,CAAC;AAEH,MAAM,MAAM,mBAAmB,GAAG,kBAAkB,GAClD,QAAQ,CAAC;IACP,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,GAAG,EAAE,gBAAgB,CAAC;CACvB,CAAC,CAAC;AAEL,MAAM,MAAM,gBAAgB,GAAG,QAAQ,CAAC;IACtC,eAAe,EAAE,mBAAmB,CAAC;IACrC,UAAU,EAAE,kBAAkB,CAAC;IAC/B,YAAY,CAAC,EAAE,oBAAoB,CAAC;CACrC,CAAC,CAAC;AAEH,eAAO,MAAM,kCAAkC,QACzC,2BAOH,CAAC;AAEJ,eAAO,MAAM,gBAAgB,QAAO,SAUnC,CAAC;AAEF,eAAO,MAAM,wBAAwB,GAAI,KAAK,SAAS,KAAG,gBAQzD,CAAC;AAEF,eAAO,MAAM,wBAAwB,GACnC,YAAY,kBAAkB,EAC9B,WAAW,sBAAsB,EACjC,KAAK,gBAAgB,KACpB,mBAqBF,CAAC;AAEF,eAAO,MAAM,cAAc,GACzB,eAAe,MAAM,EACrB,UAAS,QAAQ,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB,CAAM,KACN,OAAO,CAAC,gBAAgB,CAmC1B,CAAC"}