@tinyrack/devsync 1.1.0 → 1.2.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (216) hide show
  1. package/README.md +230 -62
  2. package/dist/cli/base-command.d.ts +14 -0
  3. package/dist/cli/base-command.d.ts.map +1 -0
  4. package/dist/cli/base-command.js +22 -0
  5. package/dist/cli/base-command.js.map +1 -0
  6. package/dist/cli/commands/dir.d.ts +8 -0
  7. package/dist/cli/commands/dir.d.ts.map +1 -0
  8. package/dist/cli/commands/dir.js +16 -0
  9. package/dist/cli/commands/dir.js.map +1 -0
  10. package/dist/cli/commands/doctor.d.ts +8 -0
  11. package/dist/cli/commands/doctor.d.ts.map +1 -0
  12. package/dist/cli/commands/doctor.js +18 -0
  13. package/dist/cli/commands/doctor.js.map +1 -0
  14. package/dist/cli/commands/index.d.ts +23 -0
  15. package/dist/cli/commands/index.d.ts.map +1 -0
  16. package/dist/cli/commands/index.js +23 -0
  17. package/dist/cli/commands/index.js.map +1 -0
  18. package/dist/cli/commands/init.d.ts +15 -0
  19. package/dist/cli/commands/init.d.ts.map +1 -0
  20. package/dist/cli/commands/init.js +43 -0
  21. package/dist/cli/commands/init.js.map +1 -0
  22. package/dist/cli/commands/machine/list.d.ts +7 -0
  23. package/dist/cli/commands/machine/list.d.ts.map +1 -0
  24. package/dist/cli/commands/machine/list.js +12 -0
  25. package/dist/cli/commands/machine/list.js.map +1 -0
  26. package/dist/cli/commands/machine/use.d.ts +11 -0
  27. package/dist/cli/commands/machine/use.d.ts.map +1 -0
  28. package/dist/cli/commands/machine/use.js +28 -0
  29. package/dist/cli/commands/machine/use.js.map +1 -0
  30. package/dist/cli/commands/pull.d.ts +12 -0
  31. package/dist/cli/commands/pull.d.ts.map +1 -0
  32. package/dist/cli/commands/pull.js +34 -0
  33. package/dist/cli/commands/pull.js.map +1 -0
  34. package/dist/cli/commands/push.d.ts +12 -0
  35. package/dist/cli/commands/push.d.ts.map +1 -0
  36. package/dist/cli/commands/push.js +34 -0
  37. package/dist/cli/commands/push.js.map +1 -0
  38. package/dist/cli/commands/status.d.ts +11 -0
  39. package/dist/cli/commands/status.d.ts.map +1 -0
  40. package/dist/cli/commands/status.js +27 -0
  41. package/dist/cli/commands/status.js.map +1 -0
  42. package/dist/cli/commands/track.d.ts +16 -0
  43. package/dist/cli/commands/track.d.ts.map +1 -0
  44. package/dist/cli/commands/track.js +82 -0
  45. package/dist/cli/commands/track.js.map +1 -0
  46. package/dist/cli/commands/untrack.d.ts +11 -0
  47. package/dist/cli/commands/untrack.d.ts.map +1 -0
  48. package/dist/cli/commands/untrack.js +28 -0
  49. package/dist/cli/commands/untrack.js.map +1 -0
  50. package/dist/config/global-config.d.ts +21 -0
  51. package/dist/config/global-config.d.ts.map +1 -0
  52. package/dist/config/global-config.js +106 -0
  53. package/dist/config/global-config.js.map +1 -0
  54. package/dist/config/sync.d.ts +96 -0
  55. package/dist/config/sync.d.ts.map +1 -0
  56. package/dist/config/sync.js +412 -0
  57. package/dist/config/sync.js.map +1 -0
  58. package/dist/config/xdg.d.ts +11 -0
  59. package/dist/config/xdg.d.ts.map +1 -0
  60. package/dist/config/xdg.js +79 -0
  61. package/dist/config/xdg.js.map +1 -0
  62. package/dist/index.d.ts +3 -0
  63. package/dist/index.d.ts.map +1 -0
  64. package/{src/index.ts → dist/index.js} +1 -1
  65. package/dist/index.js.map +1 -0
  66. package/dist/lib/file-mode.d.ts +3 -0
  67. package/dist/lib/file-mode.d.ts.map +1 -0
  68. package/dist/lib/file-mode.js +7 -0
  69. package/dist/lib/file-mode.js.map +1 -0
  70. package/dist/lib/output.d.ts +31 -0
  71. package/dist/lib/output.d.ts.map +1 -0
  72. package/dist/lib/output.js +198 -0
  73. package/dist/lib/output.js.map +1 -0
  74. package/dist/lib/path.d.ts +5 -0
  75. package/dist/lib/path.d.ts.map +1 -0
  76. package/dist/lib/path.js +25 -0
  77. package/dist/lib/path.js.map +1 -0
  78. package/dist/lib/string.d.ts +2 -0
  79. package/dist/lib/string.d.ts.map +1 -0
  80. package/dist/lib/string.js +4 -0
  81. package/dist/lib/string.js.map +1 -0
  82. package/dist/lib/validation.d.ts +3 -0
  83. package/dist/lib/validation.d.ts.map +1 -0
  84. package/dist/lib/validation.js +9 -0
  85. package/dist/lib/validation.js.map +1 -0
  86. package/dist/services/add.d.ts +20 -0
  87. package/dist/services/add.d.ts.map +1 -0
  88. package/dist/services/add.js +161 -0
  89. package/dist/services/add.js.map +1 -0
  90. package/dist/services/config-file.d.ts +30 -0
  91. package/dist/services/config-file.d.ts.map +1 -0
  92. package/dist/services/config-file.js +34 -0
  93. package/dist/services/config-file.js.map +1 -0
  94. package/dist/services/crypto.d.ts +9 -0
  95. package/dist/services/crypto.d.ts.map +1 -0
  96. package/dist/services/crypto.js +75 -0
  97. package/dist/services/crypto.js.map +1 -0
  98. package/dist/services/doctor.d.ts +16 -0
  99. package/dist/services/doctor.d.ts.map +1 -0
  100. package/dist/services/doctor.js +84 -0
  101. package/dist/services/doctor.js.map +1 -0
  102. package/dist/services/error.d.ts +14 -0
  103. package/dist/services/error.d.ts.map +1 -0
  104. package/dist/services/error.js +38 -0
  105. package/dist/services/error.js.map +1 -0
  106. package/dist/services/filesystem.d.ts +15 -0
  107. package/dist/services/filesystem.d.ts.map +1 -0
  108. package/dist/services/filesystem.js +113 -0
  109. package/dist/services/filesystem.js.map +1 -0
  110. package/dist/services/forget.d.ts +14 -0
  111. package/dist/services/forget.d.ts.map +1 -0
  112. package/dist/services/forget.js +124 -0
  113. package/dist/services/forget.js.map +1 -0
  114. package/dist/services/git.d.ts +10 -0
  115. package/dist/services/git.d.ts.map +1 -0
  116. package/dist/services/git.js +57 -0
  117. package/dist/services/git.js.map +1 -0
  118. package/dist/services/init.d.ts +19 -0
  119. package/dist/services/init.d.ts.map +1 -0
  120. package/dist/services/init.js +203 -0
  121. package/dist/services/init.js.map +1 -0
  122. package/dist/services/local-materialization.d.ts +28 -0
  123. package/dist/services/local-materialization.d.ts.map +1 -0
  124. package/dist/services/local-materialization.js +262 -0
  125. package/dist/services/local-materialization.js.map +1 -0
  126. package/dist/services/local-snapshot.d.ts +25 -0
  127. package/dist/services/local-snapshot.d.ts.map +1 -0
  128. package/dist/services/local-snapshot.js +93 -0
  129. package/dist/services/local-snapshot.js.map +1 -0
  130. package/dist/services/machine.d.ts +40 -0
  131. package/dist/services/machine.d.ts.map +1 -0
  132. package/dist/services/machine.js +113 -0
  133. package/dist/services/machine.js.map +1 -0
  134. package/dist/services/paths.d.ts +12 -0
  135. package/dist/services/paths.d.ts.map +1 -0
  136. package/dist/services/paths.js +71 -0
  137. package/dist/services/paths.js.map +1 -0
  138. package/dist/services/pull.d.ts +28 -0
  139. package/dist/services/pull.d.ts.map +1 -0
  140. package/dist/services/pull.js +67 -0
  141. package/dist/services/pull.js.map +1 -0
  142. package/dist/services/push.d.ts +35 -0
  143. package/dist/services/push.d.ts.map +1 -0
  144. package/dist/services/push.js +96 -0
  145. package/dist/services/push.js.map +1 -0
  146. package/dist/services/repo-artifacts.d.ts +52 -0
  147. package/dist/services/repo-artifacts.d.ts.map +1 -0
  148. package/dist/services/repo-artifacts.js +251 -0
  149. package/dist/services/repo-artifacts.js.map +1 -0
  150. package/dist/services/repo-snapshot.d.ts +6 -0
  151. package/dist/services/repo-snapshot.d.ts.map +1 -0
  152. package/dist/services/repo-snapshot.js +163 -0
  153. package/dist/services/repo-snapshot.js.map +1 -0
  154. package/dist/services/runtime.d.ts +40 -0
  155. package/dist/services/runtime.d.ts.map +1 -0
  156. package/dist/services/runtime.js +71 -0
  157. package/dist/services/runtime.js.map +1 -0
  158. package/dist/services/set.d.ts +38 -0
  159. package/dist/services/set.d.ts.map +1 -0
  160. package/dist/services/set.js +184 -0
  161. package/dist/services/set.js.map +1 -0
  162. package/dist/services/status.d.ts +30 -0
  163. package/dist/services/status.d.ts.map +1 -0
  164. package/dist/services/status.js +35 -0
  165. package/dist/services/status.js.map +1 -0
  166. package/package.json +15 -7
  167. package/src/cli/commands/add.ts +0 -40
  168. package/src/cli/commands/cd.ts +0 -80
  169. package/src/cli/commands/doctor.ts +0 -20
  170. package/src/cli/commands/forget.ts +0 -32
  171. package/src/cli/commands/index.ts +0 -23
  172. package/src/cli/commands/init.ts +0 -43
  173. package/src/cli/commands/list.ts +0 -17
  174. package/src/cli/commands/pull.ts +0 -31
  175. package/src/cli/commands/push.ts +0 -31
  176. package/src/cli/commands/set.ts +0 -47
  177. package/src/cli/commands/status.ts +0 -18
  178. package/src/cli/sync-output.test.ts +0 -173
  179. package/src/cli/sync-output.ts +0 -200
  180. package/src/config/sync.test.ts +0 -609
  181. package/src/config/sync.ts +0 -572
  182. package/src/config/xdg.ts +0 -138
  183. package/src/lib/string.test.ts +0 -13
  184. package/src/lib/string.ts +0 -3
  185. package/src/lib/validation.test.ts +0 -32
  186. package/src/lib/validation.ts +0 -11
  187. package/src/services/add.ts +0 -178
  188. package/src/services/config-file.test.ts +0 -161
  189. package/src/services/config-file.ts +0 -101
  190. package/src/services/crypto.test.ts +0 -132
  191. package/src/services/crypto.ts +0 -83
  192. package/src/services/doctor.ts +0 -142
  193. package/src/services/error.ts +0 -6
  194. package/src/services/filesystem.test.ts +0 -171
  195. package/src/services/filesystem.ts +0 -183
  196. package/src/services/forget.ts +0 -261
  197. package/src/services/git.test.ts +0 -83
  198. package/src/services/git.ts +0 -74
  199. package/src/services/init.test.ts +0 -109
  200. package/src/services/init.ts +0 -244
  201. package/src/services/list.ts +0 -63
  202. package/src/services/local-materialization.ts +0 -421
  203. package/src/services/local-snapshot.ts +0 -173
  204. package/src/services/paths.test.ts +0 -74
  205. package/src/services/paths.ts +0 -98
  206. package/src/services/pull.ts +0 -144
  207. package/src/services/push.ts +0 -168
  208. package/src/services/repo-artifacts.ts +0 -262
  209. package/src/services/repo-snapshot.ts +0 -197
  210. package/src/services/runtime.ts +0 -57
  211. package/src/services/set.ts +0 -383
  212. package/src/services/status.ts +0 -57
  213. package/src/services/sync.dry-run.test.ts +0 -179
  214. package/src/services/sync.runtime.test.ts +0 -756
  215. package/src/services/sync.service.test.ts +0 -1169
  216. package/src/test/helpers/sync-fixture.ts +0 -47
@@ -0,0 +1,57 @@
1
+ import { execFile } from "node:child_process";
2
+ import { promisify } from "node:util";
3
+ import { wrapUnknownError } from "./error.js";
4
+ const execFileAsync = promisify(execFile);
5
+ const runGitCommand = async (args, options) => {
6
+ try {
7
+ const result = await execFileAsync("git", [...args], {
8
+ cwd: options?.cwd,
9
+ encoding: "utf8",
10
+ maxBuffer: 10_000_000,
11
+ });
12
+ return {
13
+ stderr: result.stderr,
14
+ stdout: result.stdout,
15
+ };
16
+ }
17
+ catch (error) {
18
+ if (error instanceof Error && "stderr" in error) {
19
+ const stderr = typeof error.stderr === "string" ? error.stderr.trim() : undefined;
20
+ const stdout = "stdout" in error && typeof error.stdout === "string"
21
+ ? error.stdout.trim()
22
+ : undefined;
23
+ const message = stderr || stdout || error.message;
24
+ throw new Error(message);
25
+ }
26
+ throw new Error(error instanceof Error ? error.message : "git failed.");
27
+ }
28
+ };
29
+ export const ensureRepository = async (directory) => {
30
+ await runGitCommand(["-C", directory, "rev-parse", "--is-inside-work-tree"]);
31
+ };
32
+ export const initializeRepository = async (directory, source) => {
33
+ if (source === undefined) {
34
+ await runGitCommand(["init", "-b", "main", directory]);
35
+ return {
36
+ action: "initialized",
37
+ };
38
+ }
39
+ await runGitCommand(["clone", source, directory]);
40
+ return {
41
+ action: "cloned",
42
+ source,
43
+ };
44
+ };
45
+ export const ensureGitRepository = async (syncDirectory) => {
46
+ try {
47
+ await ensureRepository(syncDirectory);
48
+ }
49
+ catch (error) {
50
+ throw wrapUnknownError("Sync repository is not initialized.", error, {
51
+ code: "SYNC_REPO_INVALID",
52
+ details: [`Sync directory: ${syncDirectory}`],
53
+ hint: "Run 'devsync init' to create or clone the sync repository.",
54
+ });
55
+ }
56
+ };
57
+ //# sourceMappingURL=git.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"git.js","sourceRoot":"","sources":["../../src/services/git.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAC9C,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AAEtC,OAAO,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAE9C,MAAM,aAAa,GAAG,SAAS,CAAC,QAAQ,CAAC,CAAC;AAE1C,MAAM,aAAa,GAAG,KAAK,EACzB,IAAuB,EACvB,OAAoC,EACpC,EAAE;IACF,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,MAAM,aAAa,CAAC,KAAK,EAAE,CAAC,GAAG,IAAI,CAAC,EAAE;YACnD,GAAG,EAAE,OAAO,EAAE,GAAG;YACjB,QAAQ,EAAE,MAAM;YAChB,SAAS,EAAE,UAAU;SACtB,CAAC,CAAC;QAEH,OAAO;YACL,MAAM,EAAE,MAAM,CAAC,MAAM;YACrB,MAAM,EAAE,MAAM,CAAC,MAAM;SACtB,CAAC;IACJ,CAAC;IAAC,OAAO,KAAc,EAAE,CAAC;QACxB,IAAI,KAAK,YAAY,KAAK,IAAI,QAAQ,IAAI,KAAK,EAAE,CAAC;YAChD,MAAM,MAAM,GACV,OAAO,KAAK,CAAC,MAAM,KAAK,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC;YACrE,MAAM,MAAM,GACV,QAAQ,IAAI,KAAK,IAAI,OAAO,KAAK,CAAC,MAAM,KAAK,QAAQ;gBACnD,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,IAAI,EAAE;gBACrB,CAAC,CAAC,SAAS,CAAC;YAChB,MAAM,OAAO,GAAG,MAAM,IAAI,MAAM,IAAI,KAAK,CAAC,OAAO,CAAC;YAElD,MAAM,IAAI,KAAK,CAAC,OAAO,CAAC,CAAC;QAC3B,CAAC;QAED,MAAM,IAAI,KAAK,CAAC,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC;IAC1E,CAAC;AACH,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,gBAAgB,GAAG,KAAK,EAAE,SAAiB,EAAE,EAAE;IAC1D,MAAM,aAAa,CAAC,CAAC,IAAI,EAAE,SAAS,EAAE,WAAW,EAAE,uBAAuB,CAAC,CAAC,CAAC;AAC/E,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,oBAAoB,GAAG,KAAK,EACvC,SAAiB,EACjB,MAAe,EACf,EAAE;IACF,IAAI,MAAM,KAAK,SAAS,EAAE,CAAC;QACzB,MAAM,aAAa,CAAC,CAAC,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,SAAS,CAAC,CAAC,CAAC;QAEvD,OAAO;YACL,MAAM,EAAE,aAAsB;SAC/B,CAAC;IACJ,CAAC;IAED,MAAM,aAAa,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,SAAS,CAAC,CAAC,CAAC;IAElD,OAAO;QACL,MAAM,EAAE,QAAiB;QACzB,MAAM;KACP,CAAC;AACJ,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,mBAAmB,GAAG,KAAK,EAAE,aAAqB,EAAE,EAAE;IACjE,IAAI,CAAC;QACH,MAAM,gBAAgB,CAAC,aAAa,CAAC,CAAC;IACxC,CAAC;IAAC,OAAO,KAAc,EAAE,CAAC;QACxB,MAAM,gBAAgB,CAAC,qCAAqC,EAAE,KAAK,EAAE;YACnE,IAAI,EAAE,mBAAmB;YACzB,OAAO,EAAE,CAAC,mBAAmB,aAAa,EAAE,CAAC;YAC7C,IAAI,EAAE,4DAA4D;SACnE,CAAC,CAAC;IACL,CAAC;AACH,CAAC,CAAC"}
@@ -0,0 +1,19 @@
1
+ import { type SyncContext } from "./runtime.js";
2
+ export type SyncInitRequest = Readonly<{
3
+ identityFile?: string;
4
+ recipients: readonly string[];
5
+ repository?: string;
6
+ }>;
7
+ export type SyncInitResult = Readonly<{
8
+ alreadyInitialized: boolean;
9
+ configPath: string;
10
+ entryCount: number;
11
+ gitAction: "cloned" | "existing" | "initialized";
12
+ gitSource?: string;
13
+ identityFile: string;
14
+ generatedIdentity: boolean;
15
+ recipientCount: number;
16
+ syncDirectory: string;
17
+ }>;
18
+ export declare const initializeSync: (request: SyncInitRequest, context: SyncContext) => Promise<SyncInitResult>;
19
+ //# sourceMappingURL=init.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"init.d.ts","sourceRoot":"","sources":["../../src/services/init.ts"],"names":[],"mappings":"AA0BA,OAAO,EAGL,KAAK,WAAW,EACjB,MAAM,cAAc,CAAC;AAEtB,MAAM,MAAM,eAAe,GAAG,QAAQ,CAAC;IACrC,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,UAAU,EAAE,SAAS,MAAM,EAAE,CAAC;IAC9B,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB,CAAC,CAAC;AAEH,MAAM,MAAM,cAAc,GAAG,QAAQ,CAAC;IACpC,kBAAkB,EAAE,OAAO,CAAC;IAC5B,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,QAAQ,GAAG,UAAU,GAAG,aAAa,CAAC;IACjD,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,YAAY,EAAE,MAAM,CAAC;IACrB,iBAAiB,EAAE,OAAO,CAAC;IAC3B,cAAc,EAAE,MAAM,CAAC;IACvB,aAAa,EAAE,MAAM,CAAC;CACvB,CAAC,CAAC;AAqJH,eAAO,MAAM,cAAc,GACzB,SAAS,eAAe,EACxB,SAAS,WAAW,KACnB,OAAO,CAAC,cAAc,CAsIxB,CAAC"}
@@ -0,0 +1,203 @@
1
+ import { mkdir, readdir, writeFile } from "node:fs/promises";
2
+ import { dirname } from "node:path";
3
+ import { formatGlobalDevsyncConfig, readGlobalDevsyncConfig, resolveConfiguredIdentityFile, } from "#app/config/global-config.js";
4
+ import { createInitialSyncConfig, formatSyncConfig, parseSyncConfig, readSyncConfig, resolveSyncArtifactsDirectoryPath, } from "#app/config/sync.js";
5
+ import { resolveConfiguredAbsolutePath } from "#app/config/xdg.js";
6
+ import { createAgeIdentityFile, readAgeRecipientsFromIdentityFile, } from "./crypto.js";
7
+ import { DevsyncError, wrapUnknownError } from "./error.js";
8
+ import { pathExists, writeTextFileAtomically } from "./filesystem.js";
9
+ import { ensureRepository, initializeRepository } from "./git.js";
10
+ import { ensureSyncRepository, resolveAgeFromSyncConfig, } from "./runtime.js";
11
+ const defaultSyncIdentityFile = "$XDG_CONFIG_HOME/devsync/age/keys.txt";
12
+ const normalizeRecipients = (recipients) => {
13
+ return [
14
+ ...new Set(recipients.map((recipient) => recipient.trim()).filter(Boolean)),
15
+ ].sort((left, right) => {
16
+ return left.localeCompare(right);
17
+ });
18
+ };
19
+ const resolveInitAgeBootstrap = async (request, context) => {
20
+ const configuredIdentityFile = request.identityFile?.trim() || defaultSyncIdentityFile;
21
+ const identityFile = resolveConfiguredAbsolutePath(configuredIdentityFile, context.environment);
22
+ const explicitRecipients = normalizeRecipients(request.recipients);
23
+ if (explicitRecipients.length === 0) {
24
+ if (await pathExists(identityFile)) {
25
+ return {
26
+ configuredIdentityFile,
27
+ generatedIdentity: false,
28
+ recipients: normalizeRecipients(await readAgeRecipientsFromIdentityFile(identityFile)),
29
+ };
30
+ }
31
+ const { recipient } = await createAgeIdentityFile(identityFile);
32
+ return {
33
+ configuredIdentityFile,
34
+ generatedIdentity: true,
35
+ recipients: [recipient],
36
+ };
37
+ }
38
+ if (await pathExists(identityFile)) {
39
+ return {
40
+ configuredIdentityFile,
41
+ generatedIdentity: false,
42
+ recipients: explicitRecipients,
43
+ };
44
+ }
45
+ const { recipient } = await createAgeIdentityFile(identityFile);
46
+ return {
47
+ configuredIdentityFile,
48
+ generatedIdentity: true,
49
+ recipients: normalizeRecipients([...explicitRecipients, recipient]),
50
+ };
51
+ };
52
+ const assertInitRequestMatchesConfig = (age, request, environment) => {
53
+ if (age === undefined) {
54
+ return;
55
+ }
56
+ const recipients = normalizeRecipients(request.recipients);
57
+ if (recipients.length > 0 &&
58
+ JSON.stringify(recipients) !==
59
+ JSON.stringify(normalizeRecipients([...age.recipients]))) {
60
+ throw new DevsyncError("Sync configuration already exists with different age recipients.", {
61
+ code: "INIT_RECIPIENT_MISMATCH",
62
+ details: [
63
+ `Requested recipients: ${recipients.join(", ") || "(none)"}`,
64
+ `Configured recipients: ${normalizeRecipients([...age.recipients]).join(", ")}`,
65
+ ],
66
+ hint: "Use the existing recipients, or update manifest.json manually if you intend to rotate recipients.",
67
+ });
68
+ }
69
+ if (request.identityFile === undefined ||
70
+ request.identityFile.trim() === "") {
71
+ return;
72
+ }
73
+ const resolvedIdentity = resolveConfiguredIdentityFile(request.identityFile, environment);
74
+ const configuredIdentity = resolveConfiguredIdentityFile(age.identityFile, environment);
75
+ if (resolvedIdentity !== configuredIdentity) {
76
+ throw new DevsyncError("Sync configuration already exists with a different age identity file.", {
77
+ code: "INIT_IDENTITY_MISMATCH",
78
+ details: [
79
+ `Requested identity file: ${resolvedIdentity}`,
80
+ `Configured identity file: ${configuredIdentity}`,
81
+ ],
82
+ hint: "Reuse the configured identity file, or update manifest.json before re-running init.",
83
+ });
84
+ }
85
+ };
86
+ const buildAlreadyInitializedResult = (config, environment, base) => {
87
+ const age = config.age !== undefined
88
+ ? resolveAgeFromSyncConfig(config.age, environment)
89
+ : undefined;
90
+ return {
91
+ alreadyInitialized: true,
92
+ configPath: base.configPath,
93
+ entryCount: config.entries.length,
94
+ gitAction: base.gitAction,
95
+ ...(base.gitSource === undefined ? {} : { gitSource: base.gitSource }),
96
+ generatedIdentity: false,
97
+ identityFile: age?.identityFile ?? "",
98
+ recipientCount: age?.recipients.length ?? 0,
99
+ syncDirectory: base.syncDirectory,
100
+ };
101
+ };
102
+ export const initializeSync = async (request, context) => {
103
+ const syncDirectory = context.paths.syncDirectory;
104
+ const configPath = context.paths.configPath;
105
+ const configExists = await pathExists(configPath);
106
+ if (configExists) {
107
+ await ensureSyncRepository(context);
108
+ const config = await readSyncConfig(syncDirectory, context.environment);
109
+ assertInitRequestMatchesConfig(config.age, request, context.environment);
110
+ return buildAlreadyInitializedResult(config, context.environment, {
111
+ configPath,
112
+ gitAction: "existing",
113
+ syncDirectory,
114
+ });
115
+ }
116
+ await mkdir(dirname(syncDirectory), {
117
+ recursive: true,
118
+ });
119
+ let gitAction = "existing";
120
+ let gitSource;
121
+ try {
122
+ await ensureRepository(syncDirectory);
123
+ }
124
+ catch {
125
+ const syncDirectoryExists = await pathExists(syncDirectory);
126
+ if (syncDirectoryExists) {
127
+ const entries = await readdir(syncDirectory);
128
+ if (entries.length > 0) {
129
+ throw new DevsyncError("Sync directory already exists and is not empty.", {
130
+ code: "SYNC_DIR_NOT_EMPTY",
131
+ details: [`Sync directory: ${syncDirectory}`],
132
+ hint: "Empty the directory, remove it, or point init at a different repository source.",
133
+ });
134
+ }
135
+ }
136
+ const gitSourceInput = request.repository?.trim() || undefined;
137
+ let gitResult;
138
+ try {
139
+ gitResult = await initializeRepository(syncDirectory, gitSourceInput);
140
+ }
141
+ catch (error) {
142
+ throw wrapUnknownError(gitSourceInput === undefined
143
+ ? "Failed to initialize the sync repository."
144
+ : "Failed to clone the sync repository.", error, {
145
+ code: gitSourceInput === undefined
146
+ ? "SYNC_INIT_GIT_FAILED"
147
+ : "SYNC_CLONE_FAILED",
148
+ details: [
149
+ `Sync directory: ${syncDirectory}`,
150
+ ...(gitSourceInput === undefined
151
+ ? []
152
+ : [`Repository source: ${gitSourceInput}`]),
153
+ ],
154
+ hint: gitSourceInput === undefined
155
+ ? "Check that git is installed and the sync directory is writable."
156
+ : "Check that the repository source is reachable and you have access to it.",
157
+ });
158
+ }
159
+ gitAction = gitResult.action;
160
+ gitSource = gitResult.source;
161
+ }
162
+ await mkdir(resolveSyncArtifactsDirectoryPath(syncDirectory), {
163
+ recursive: true,
164
+ });
165
+ if (await pathExists(configPath)) {
166
+ const config = await readSyncConfig(syncDirectory, context.environment);
167
+ assertInitRequestMatchesConfig(config.age, request, context.environment);
168
+ return buildAlreadyInitializedResult(config, context.environment, {
169
+ configPath,
170
+ gitAction,
171
+ gitSource,
172
+ syncDirectory,
173
+ });
174
+ }
175
+ const ageBootstrap = await resolveInitAgeBootstrap(request, context);
176
+ // Write global settings.json (without age)
177
+ const existingGlobalConfig = await readGlobalDevsyncConfig(context.environment);
178
+ const globalConfigToWrite = {
179
+ activeMachine: existingGlobalConfig?.activeMachine ?? "default",
180
+ version: 3,
181
+ };
182
+ await mkdir(dirname(context.paths.globalConfigPath), { recursive: true });
183
+ await writeTextFileAtomically(context.paths.globalConfigPath, formatGlobalDevsyncConfig(globalConfigToWrite));
184
+ // Write sync manifest with age
185
+ const initialConfig = createInitialSyncConfig({
186
+ identityFile: ageBootstrap.configuredIdentityFile,
187
+ recipients: [...new Set(ageBootstrap.recipients.map((r) => r.trim()))],
188
+ });
189
+ parseSyncConfig(initialConfig, context.environment);
190
+ await writeFile(configPath, formatSyncConfig(initialConfig), "utf8");
191
+ return {
192
+ alreadyInitialized: false,
193
+ configPath,
194
+ entryCount: 0,
195
+ gitAction,
196
+ ...(gitSource === undefined ? {} : { gitSource }),
197
+ generatedIdentity: ageBootstrap.generatedIdentity,
198
+ identityFile: resolveConfiguredAbsolutePath(ageBootstrap.configuredIdentityFile, context.environment),
199
+ recipientCount: ageBootstrap.recipients.length,
200
+ syncDirectory,
201
+ };
202
+ };
203
+ //# sourceMappingURL=init.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"init.js","sourceRoot":"","sources":["../../src/services/init.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,28 @@
1
+ import { type ResolvedSyncConfig, type ResolvedSyncConfigEntry } from "#app/config/sync.js";
2
+ import type { FileLikeSnapshotNode, SnapshotNode } from "./local-snapshot.js";
3
+ type MaterializationConfig = ResolvedSyncConfig & Readonly<{
4
+ activeMachine?: string;
5
+ }>;
6
+ type EntryMaterialization = Readonly<{
7
+ desiredKeys: ReadonlySet<string>;
8
+ type: "absent";
9
+ }> | Readonly<{
10
+ desiredKeys: ReadonlySet<string>;
11
+ node: FileLikeSnapshotNode;
12
+ type: "file";
13
+ }> | Readonly<{
14
+ desiredKeys: ReadonlySet<string>;
15
+ nodes: ReadonlyMap<string, FileLikeSnapshotNode>;
16
+ type: "directory";
17
+ }>;
18
+ export declare const buildEntryMaterialization: (entry: ResolvedSyncConfigEntry, snapshot: ReadonlyMap<string, SnapshotNode>) => EntryMaterialization;
19
+ export declare const countDeletedLocalNodes: (entry: ResolvedSyncConfigEntry, desiredKeys: ReadonlySet<string>, config: MaterializationConfig, existingKeys?: Set<string>) => Promise<number>;
20
+ export declare const applyEntryMaterialization: (entry: ResolvedSyncConfigEntry, materialization: EntryMaterialization, config: MaterializationConfig) => Promise<void>;
21
+ export declare const buildPullCounts: (materializations: readonly EntryMaterialization[]) => {
22
+ decryptedFileCount: number;
23
+ directoryCount: number;
24
+ plainFileCount: number;
25
+ symlinkCount: number;
26
+ };
27
+ export {};
28
+ //# sourceMappingURL=local-materialization.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"local-materialization.d.ts","sourceRoot":"","sources":["../../src/services/local-materialization.ts"],"names":[],"mappings":"AAGA,OAAO,EACL,KAAK,kBAAkB,EACvB,KAAK,uBAAuB,EAE7B,MAAM,qBAAqB,CAAC;AAY7B,OAAO,KAAK,EAAE,oBAAoB,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AAE9E,KAAK,qBAAqB,GAAG,kBAAkB,GAC7C,QAAQ,CAAC;IACP,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB,CAAC,CAAC;AAEL,KAAK,oBAAoB,GACrB,QAAQ,CAAC;IACP,WAAW,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;IACjC,IAAI,EAAE,QAAQ,CAAC;CAChB,CAAC,GACF,QAAQ,CAAC;IACP,WAAW,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;IACjC,IAAI,EAAE,oBAAoB,CAAC;IAC3B,IAAI,EAAE,MAAM,CAAC;CACd,CAAC,GACF,QAAQ,CAAC;IACP,WAAW,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;IACjC,KAAK,EAAE,WAAW,CAAC,MAAM,EAAE,oBAAoB,CAAC,CAAC;IACjD,IAAI,EAAE,WAAW,CAAC;CACnB,CAAC,CAAC;AAoIP,eAAO,MAAM,yBAAyB,GACpC,OAAO,uBAAuB,EAC9B,UAAU,WAAW,CAAC,MAAM,EAAE,YAAY,CAAC,KAC1C,oBA0EF,CAAC;AAuFF,eAAO,MAAM,sBAAsB,GACjC,OAAO,uBAAuB,EAC9B,aAAa,WAAW,CAAC,MAAM,CAAC,EAChC,QAAQ,qBAAqB,EAC7B,eAAc,GAAG,CAAC,MAAM,CAAqB,oBAe9C,CAAC;AAEF,eAAO,MAAM,yBAAyB,GACpC,OAAO,uBAAuB,EAC9B,iBAAiB,oBAAoB,EACrC,QAAQ,qBAAqB,kBAiC9B,CAAC;AAEF,eAAO,MAAM,eAAe,GAC1B,kBAAkB,SAAS,oBAAoB,EAAE;;;;;CA+ClD,CAAC"}
@@ -0,0 +1,262 @@
1
+ import { lstat, mkdir, mkdtemp, rm, symlink } from "node:fs/promises";
2
+ import { basename, dirname, join, posix } from "node:path";
3
+ import { resolveManagedSyncMode, } from "#app/config/sync.js";
4
+ import { buildDirectoryKey } from "#app/lib/path.js";
5
+ import { DevsyncError } from "./error.js";
6
+ import { copyFilesystemNode, getPathStats, listDirectoryEntries, removePathAtomically, replacePathAtomically, writeFileNode, writeSymlinkNode, } from "./filesystem.js";
7
+ const copyIgnoredLocalNodesToDirectory = async (sourceDirectory, targetDirectory, config, repoPathPrefix) => {
8
+ const stats = await getPathStats(sourceDirectory);
9
+ if (stats === undefined || !stats.isDirectory()) {
10
+ return 0;
11
+ }
12
+ let copiedNodeCount = 0;
13
+ const entries = await listDirectoryEntries(sourceDirectory);
14
+ const directoryMode = resolveManagedSyncMode(config, repoPathPrefix, config.activeMachine);
15
+ if (directoryMode === "ignore") {
16
+ await mkdir(targetDirectory, { recursive: true });
17
+ copiedNodeCount += 1;
18
+ }
19
+ for (const entry of entries) {
20
+ const sourcePath = join(sourceDirectory, entry.name);
21
+ const targetPath = join(targetDirectory, entry.name);
22
+ const repoPath = posix.join(repoPathPrefix, entry.name);
23
+ const entryStats = await lstat(sourcePath);
24
+ if (entryStats.isDirectory()) {
25
+ copiedNodeCount += await copyIgnoredLocalNodesToDirectory(sourcePath, targetPath, config, repoPath);
26
+ continue;
27
+ }
28
+ if (resolveManagedSyncMode(config, repoPath, config.activeMachine) !==
29
+ "ignore") {
30
+ continue;
31
+ }
32
+ await mkdir(dirname(targetPath), { recursive: true });
33
+ await copyFilesystemNode(sourcePath, targetPath, entryStats);
34
+ copiedNodeCount += 1;
35
+ }
36
+ return copiedNodeCount;
37
+ };
38
+ const stageAndReplaceFilePath = async (targetPath, node) => {
39
+ await mkdir(dirname(targetPath), { recursive: true });
40
+ const stagingDirectory = await mkdtemp(join(dirname(targetPath), `.${basename(targetPath)}.devsync-sync-`));
41
+ const stagedPath = join(stagingDirectory, basename(targetPath));
42
+ try {
43
+ if (node.type === "symlink") {
44
+ await symlink(node.linkTarget, stagedPath);
45
+ }
46
+ else {
47
+ await writeFileNode(stagedPath, node);
48
+ }
49
+ await replacePathAtomically(targetPath, stagedPath);
50
+ }
51
+ finally {
52
+ await rm(stagingDirectory, { force: true, recursive: true });
53
+ }
54
+ };
55
+ const stageAndReplaceMergedDirectoryPath = async (entry, config, desiredNodes) => {
56
+ await mkdir(dirname(entry.localPath), { recursive: true });
57
+ const stagingDirectory = await mkdtemp(join(dirname(entry.localPath), `.${basename(entry.localPath)}.devsync-sync-`));
58
+ try {
59
+ const preservedIgnoredNodeCount = await copyIgnoredLocalNodesToDirectory(entry.localPath, stagingDirectory, config, entry.repoPath);
60
+ for (const relativePath of [...desiredNodes.keys()].sort((left, right) => {
61
+ return left.localeCompare(right);
62
+ })) {
63
+ const node = desiredNodes.get(relativePath);
64
+ if (node === undefined) {
65
+ continue;
66
+ }
67
+ const targetNodePath = join(stagingDirectory, ...relativePath.split("/"));
68
+ if (node.type === "symlink") {
69
+ await writeSymlinkNode(targetNodePath, node.linkTarget);
70
+ }
71
+ else {
72
+ await writeFileNode(targetNodePath, node);
73
+ }
74
+ }
75
+ if (preservedIgnoredNodeCount === 0 && desiredNodes.size === 0) {
76
+ await removePathAtomically(entry.localPath);
77
+ return;
78
+ }
79
+ await replacePathAtomically(entry.localPath, stagingDirectory);
80
+ }
81
+ finally {
82
+ await rm(stagingDirectory, { force: true, recursive: true });
83
+ }
84
+ };
85
+ export const buildEntryMaterialization = (entry, snapshot) => {
86
+ if (entry.kind === "file") {
87
+ const node = snapshot.get(entry.repoPath);
88
+ if (node === undefined) {
89
+ return {
90
+ desiredKeys: new Set(),
91
+ type: "absent",
92
+ };
93
+ }
94
+ if (node.type === "directory") {
95
+ throw new DevsyncError("File sync entry resolves to a directory in the repository.", {
96
+ code: "FILE_ENTRY_RESOLVES_DIRECTORY",
97
+ details: [`Repository path: ${entry.repoPath}`],
98
+ hint: "Run 'devsync push' or fix the repository so this path is stored as a file.",
99
+ });
100
+ }
101
+ return {
102
+ desiredKeys: new Set([entry.repoPath]),
103
+ node,
104
+ type: "file",
105
+ };
106
+ }
107
+ const rootNode = snapshot.get(entry.repoPath);
108
+ if (rootNode !== undefined && rootNode.type !== "directory") {
109
+ throw new DevsyncError("Directory sync entry resolves to a file in the repository.", {
110
+ code: "DIRECTORY_ENTRY_RESOLVES_FILE",
111
+ details: [`Repository path: ${entry.repoPath}`],
112
+ hint: "Run 'devsync push' or fix the repository so this path is stored as a directory.",
113
+ });
114
+ }
115
+ const nodes = new Map();
116
+ const desiredKeys = new Set();
117
+ for (const [repoPath, node] of snapshot.entries()) {
118
+ if (!repoPath.startsWith(`${entry.repoPath}/`)) {
119
+ continue;
120
+ }
121
+ if (node.type === "directory") {
122
+ continue;
123
+ }
124
+ const relativePath = repoPath.slice(entry.repoPath.length + 1);
125
+ nodes.set(relativePath, node);
126
+ desiredKeys.add(repoPath);
127
+ }
128
+ if (rootNode === undefined && nodes.size === 0) {
129
+ return {
130
+ desiredKeys,
131
+ type: "absent",
132
+ };
133
+ }
134
+ desiredKeys.add(buildDirectoryKey(entry.repoPath));
135
+ return {
136
+ desiredKeys,
137
+ nodes,
138
+ type: "directory",
139
+ };
140
+ };
141
+ const collectLocalLeafKeys = async (targetPath, repoPathPrefix, keys, prefix) => {
142
+ const stats = await getPathStats(targetPath);
143
+ if (stats === undefined) {
144
+ return;
145
+ }
146
+ if (!stats.isDirectory()) {
147
+ keys.add(repoPathPrefix);
148
+ return;
149
+ }
150
+ keys.add(buildDirectoryKey(repoPathPrefix));
151
+ const entries = await listDirectoryEntries(targetPath);
152
+ for (const entry of entries) {
153
+ const absolutePath = join(targetPath, entry.name);
154
+ const relativePath = prefix === undefined ? entry.name : `${prefix}/${entry.name}`;
155
+ const childStats = await lstat(absolutePath);
156
+ if (childStats?.isDirectory()) {
157
+ await collectLocalLeafKeys(absolutePath, repoPathPrefix, keys, relativePath);
158
+ continue;
159
+ }
160
+ keys.add(posix.join(repoPathPrefix, relativePath));
161
+ }
162
+ };
163
+ const collectIgnoredLocalKeys = async (targetPath, repoPath, config, keys) => {
164
+ const stats = await getPathStats(targetPath);
165
+ if (stats === undefined) {
166
+ return false;
167
+ }
168
+ const mode = resolveManagedSyncMode(config, repoPath, config.activeMachine);
169
+ if (!stats.isDirectory()) {
170
+ if (mode !== "ignore") {
171
+ return false;
172
+ }
173
+ keys.add(repoPath);
174
+ return true;
175
+ }
176
+ let preservedIgnoredChildren = mode === "ignore";
177
+ const entries = await listDirectoryEntries(targetPath);
178
+ for (const entry of entries) {
179
+ const childPath = join(targetPath, entry.name);
180
+ const childRepoPath = posix.join(repoPath, entry.name);
181
+ preservedIgnoredChildren =
182
+ (await collectIgnoredLocalKeys(childPath, childRepoPath, config, keys)) ||
183
+ preservedIgnoredChildren;
184
+ }
185
+ if (mode === "ignore" || preservedIgnoredChildren) {
186
+ keys.add(buildDirectoryKey(repoPath));
187
+ }
188
+ return mode === "ignore" || preservedIgnoredChildren;
189
+ };
190
+ export const countDeletedLocalNodes = async (entry, desiredKeys, config, existingKeys = new Set()) => {
191
+ const preservedIgnoredKeys = new Set();
192
+ await collectLocalLeafKeys(entry.localPath, entry.repoPath, existingKeys);
193
+ await collectIgnoredLocalKeys(entry.localPath, entry.repoPath, config, preservedIgnoredKeys);
194
+ return [...existingKeys].filter((key) => {
195
+ return !desiredKeys.has(key) && !preservedIgnoredKeys.has(key);
196
+ }).length;
197
+ };
198
+ export const applyEntryMaterialization = async (entry, materialization, config) => {
199
+ if (entry.kind === "file" &&
200
+ resolveManagedSyncMode(config, entry.repoPath, config.activeMachine) ===
201
+ "ignore") {
202
+ return;
203
+ }
204
+ if (materialization.type === "absent") {
205
+ if (entry.kind === "directory") {
206
+ await stageAndReplaceMergedDirectoryPath(entry, config, new Map());
207
+ return;
208
+ }
209
+ await removePathAtomically(entry.localPath);
210
+ return;
211
+ }
212
+ if (materialization.type === "file") {
213
+ await stageAndReplaceFilePath(entry.localPath, materialization.node);
214
+ return;
215
+ }
216
+ await stageAndReplaceMergedDirectoryPath(entry, config, materialization.nodes);
217
+ };
218
+ export const buildPullCounts = (materializations) => {
219
+ let decryptedFileCount = 0;
220
+ let directoryCount = 0;
221
+ let plainFileCount = 0;
222
+ let symlinkCount = 0;
223
+ for (const materialization of materializations) {
224
+ if (materialization === undefined) {
225
+ continue;
226
+ }
227
+ if (materialization.type === "file") {
228
+ if (materialization.node.type === "symlink") {
229
+ symlinkCount += 1;
230
+ }
231
+ else if (materialization.node.secret) {
232
+ decryptedFileCount += 1;
233
+ }
234
+ else {
235
+ plainFileCount += 1;
236
+ }
237
+ continue;
238
+ }
239
+ if (materialization.type !== "directory") {
240
+ continue;
241
+ }
242
+ directoryCount += 1;
243
+ for (const node of materialization.nodes.values()) {
244
+ if (node.type === "symlink") {
245
+ symlinkCount += 1;
246
+ }
247
+ else if (node.secret) {
248
+ decryptedFileCount += 1;
249
+ }
250
+ else {
251
+ plainFileCount += 1;
252
+ }
253
+ }
254
+ }
255
+ return {
256
+ decryptedFileCount,
257
+ directoryCount,
258
+ plainFileCount,
259
+ symlinkCount,
260
+ };
261
+ };
262
+ //# sourceMappingURL=local-materialization.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"local-materialization.js","sourceRoot":"","sources":["../../src/services/local-materialization.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,25 @@
1
+ import { type ResolvedSyncConfig } from "#app/config/sync.js";
2
+ type SnapshotConfig = ResolvedSyncConfig & Readonly<{
3
+ activeMachine?: string;
4
+ }>;
5
+ export type SnapshotNode = Readonly<{
6
+ type: "directory";
7
+ }> | Readonly<{
8
+ executable: boolean;
9
+ secret: boolean;
10
+ type: "file";
11
+ contents: Uint8Array;
12
+ }> | Readonly<{
13
+ linkTarget: string;
14
+ type: "symlink";
15
+ }>;
16
+ export type FileSnapshotNode = Extract<SnapshotNode, Readonly<{
17
+ type: "file";
18
+ }>>;
19
+ export type FileLikeSnapshotNode = Extract<SnapshotNode, Readonly<{
20
+ type: "file" | "symlink";
21
+ }>>;
22
+ export declare const addSnapshotNode: (snapshot: Map<string, SnapshotNode>, repoPath: string, node: SnapshotNode) => void;
23
+ export declare const buildLocalSnapshot: (config: SnapshotConfig) => Promise<Map<string, SnapshotNode>>;
24
+ export {};
25
+ //# sourceMappingURL=local-snapshot.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"local-snapshot.d.ts","sourceRoot":"","sources":["../../src/services/local-snapshot.ts"],"names":[],"mappings":"AAGA,OAAO,EACL,KAAK,kBAAkB,EAExB,MAAM,qBAAqB,CAAC;AAM7B,KAAK,cAAc,GAAG,kBAAkB,GACtC,QAAQ,CAAC;IACP,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB,CAAC,CAAC;AAEL,MAAM,MAAM,YAAY,GACpB,QAAQ,CAAC;IACP,IAAI,EAAE,WAAW,CAAC;CACnB,CAAC,GACF,QAAQ,CAAC;IACP,UAAU,EAAE,OAAO,CAAC;IACpB,MAAM,EAAE,OAAO,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,UAAU,CAAC;CACtB,CAAC,GACF,QAAQ,CAAC;IACP,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,EAAE,SAAS,CAAC;CACjB,CAAC,CAAC;AAEP,MAAM,MAAM,gBAAgB,GAAG,OAAO,CACpC,YAAY,EACZ,QAAQ,CAAC;IAAE,IAAI,EAAE,MAAM,CAAA;CAAE,CAAC,CAC3B,CAAC;AAEF,MAAM,MAAM,oBAAoB,GAAG,OAAO,CACxC,YAAY,EACZ,QAAQ,CAAC;IAAE,IAAI,EAAE,MAAM,GAAG,SAAS,CAAA;CAAE,CAAC,CACvC,CAAC;AAEF,eAAO,MAAM,eAAe,GAC1B,UAAU,GAAG,CAAC,MAAM,EAAE,YAAY,CAAC,EACnC,UAAU,MAAM,EAChB,MAAM,YAAY,SAOnB,CAAC;AAoFF,eAAO,MAAM,kBAAkB,GAAU,QAAQ,cAAc,uCAmE9D,CAAC"}