@tinyrack/devsync 1.1.0 → 1.3.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 (220) 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/platform.d.ts +11 -0
  55. package/dist/config/platform.d.ts.map +1 -0
  56. package/dist/config/platform.js +19 -0
  57. package/dist/config/platform.js.map +1 -0
  58. package/dist/config/sync.d.ts +107 -0
  59. package/dist/config/sync.d.ts.map +1 -0
  60. package/dist/config/sync.js +424 -0
  61. package/dist/config/sync.js.map +1 -0
  62. package/dist/config/xdg.d.ts +14 -0
  63. package/dist/config/xdg.d.ts.map +1 -0
  64. package/dist/config/xdg.js +102 -0
  65. package/dist/config/xdg.js.map +1 -0
  66. package/dist/index.d.ts +3 -0
  67. package/dist/index.d.ts.map +1 -0
  68. package/{src/index.ts → dist/index.js} +1 -1
  69. package/dist/index.js.map +1 -0
  70. package/dist/lib/file-mode.d.ts +3 -0
  71. package/dist/lib/file-mode.d.ts.map +1 -0
  72. package/dist/lib/file-mode.js +7 -0
  73. package/dist/lib/file-mode.js.map +1 -0
  74. package/dist/lib/output.d.ts +31 -0
  75. package/dist/lib/output.d.ts.map +1 -0
  76. package/dist/lib/output.js +198 -0
  77. package/dist/lib/output.js.map +1 -0
  78. package/dist/lib/path.d.ts +5 -0
  79. package/dist/lib/path.d.ts.map +1 -0
  80. package/dist/lib/path.js +25 -0
  81. package/dist/lib/path.js.map +1 -0
  82. package/dist/lib/string.d.ts +2 -0
  83. package/dist/lib/string.d.ts.map +1 -0
  84. package/dist/lib/string.js +4 -0
  85. package/dist/lib/string.js.map +1 -0
  86. package/dist/lib/validation.d.ts +3 -0
  87. package/dist/lib/validation.d.ts.map +1 -0
  88. package/dist/lib/validation.js +9 -0
  89. package/dist/lib/validation.js.map +1 -0
  90. package/dist/services/add.d.ts +20 -0
  91. package/dist/services/add.d.ts.map +1 -0
  92. package/dist/services/add.js +161 -0
  93. package/dist/services/add.js.map +1 -0
  94. package/dist/services/config-file.d.ts +45 -0
  95. package/dist/services/config-file.d.ts.map +1 -0
  96. package/dist/services/config-file.js +35 -0
  97. package/dist/services/config-file.js.map +1 -0
  98. package/dist/services/crypto.d.ts +9 -0
  99. package/dist/services/crypto.d.ts.map +1 -0
  100. package/dist/services/crypto.js +75 -0
  101. package/dist/services/crypto.js.map +1 -0
  102. package/dist/services/doctor.d.ts +16 -0
  103. package/dist/services/doctor.d.ts.map +1 -0
  104. package/dist/services/doctor.js +84 -0
  105. package/dist/services/doctor.js.map +1 -0
  106. package/dist/services/error.d.ts +14 -0
  107. package/dist/services/error.d.ts.map +1 -0
  108. package/dist/services/error.js +38 -0
  109. package/dist/services/error.js.map +1 -0
  110. package/dist/services/filesystem.d.ts +15 -0
  111. package/dist/services/filesystem.d.ts.map +1 -0
  112. package/dist/services/filesystem.js +113 -0
  113. package/dist/services/filesystem.js.map +1 -0
  114. package/dist/services/forget.d.ts +14 -0
  115. package/dist/services/forget.d.ts.map +1 -0
  116. package/dist/services/forget.js +124 -0
  117. package/dist/services/forget.js.map +1 -0
  118. package/dist/services/git.d.ts +10 -0
  119. package/dist/services/git.d.ts.map +1 -0
  120. package/dist/services/git.js +57 -0
  121. package/dist/services/git.js.map +1 -0
  122. package/dist/services/init.d.ts +19 -0
  123. package/dist/services/init.d.ts.map +1 -0
  124. package/dist/services/init.js +203 -0
  125. package/dist/services/init.js.map +1 -0
  126. package/dist/services/local-materialization.d.ts +28 -0
  127. package/dist/services/local-materialization.d.ts.map +1 -0
  128. package/dist/services/local-materialization.js +262 -0
  129. package/dist/services/local-materialization.js.map +1 -0
  130. package/dist/services/local-snapshot.d.ts +25 -0
  131. package/dist/services/local-snapshot.d.ts.map +1 -0
  132. package/dist/services/local-snapshot.js +93 -0
  133. package/dist/services/local-snapshot.js.map +1 -0
  134. package/dist/services/machine.d.ts +40 -0
  135. package/dist/services/machine.d.ts.map +1 -0
  136. package/dist/services/machine.js +113 -0
  137. package/dist/services/machine.js.map +1 -0
  138. package/dist/services/paths.d.ts +13 -0
  139. package/dist/services/paths.d.ts.map +1 -0
  140. package/dist/services/paths.js +71 -0
  141. package/dist/services/paths.js.map +1 -0
  142. package/dist/services/pull.d.ts +28 -0
  143. package/dist/services/pull.d.ts.map +1 -0
  144. package/dist/services/pull.js +67 -0
  145. package/dist/services/pull.js.map +1 -0
  146. package/dist/services/push.d.ts +35 -0
  147. package/dist/services/push.d.ts.map +1 -0
  148. package/dist/services/push.js +96 -0
  149. package/dist/services/push.js.map +1 -0
  150. package/dist/services/repo-artifacts.d.ts +52 -0
  151. package/dist/services/repo-artifacts.d.ts.map +1 -0
  152. package/dist/services/repo-artifacts.js +251 -0
  153. package/dist/services/repo-artifacts.js.map +1 -0
  154. package/dist/services/repo-snapshot.d.ts +6 -0
  155. package/dist/services/repo-snapshot.d.ts.map +1 -0
  156. package/dist/services/repo-snapshot.js +163 -0
  157. package/dist/services/repo-snapshot.js.map +1 -0
  158. package/dist/services/runtime.d.ts +40 -0
  159. package/dist/services/runtime.d.ts.map +1 -0
  160. package/dist/services/runtime.js +71 -0
  161. package/dist/services/runtime.js.map +1 -0
  162. package/dist/services/set.d.ts +38 -0
  163. package/dist/services/set.d.ts.map +1 -0
  164. package/dist/services/set.js +184 -0
  165. package/dist/services/set.js.map +1 -0
  166. package/dist/services/status.d.ts +30 -0
  167. package/dist/services/status.d.ts.map +1 -0
  168. package/dist/services/status.js +35 -0
  169. package/dist/services/status.js.map +1 -0
  170. package/package.json +15 -7
  171. package/src/cli/commands/add.ts +0 -40
  172. package/src/cli/commands/cd.ts +0 -80
  173. package/src/cli/commands/doctor.ts +0 -20
  174. package/src/cli/commands/forget.ts +0 -32
  175. package/src/cli/commands/index.ts +0 -23
  176. package/src/cli/commands/init.ts +0 -43
  177. package/src/cli/commands/list.ts +0 -17
  178. package/src/cli/commands/pull.ts +0 -31
  179. package/src/cli/commands/push.ts +0 -31
  180. package/src/cli/commands/set.ts +0 -47
  181. package/src/cli/commands/status.ts +0 -18
  182. package/src/cli/sync-output.test.ts +0 -173
  183. package/src/cli/sync-output.ts +0 -200
  184. package/src/config/sync.test.ts +0 -609
  185. package/src/config/sync.ts +0 -572
  186. package/src/config/xdg.ts +0 -138
  187. package/src/lib/string.test.ts +0 -13
  188. package/src/lib/string.ts +0 -3
  189. package/src/lib/validation.test.ts +0 -32
  190. package/src/lib/validation.ts +0 -11
  191. package/src/services/add.ts +0 -178
  192. package/src/services/config-file.test.ts +0 -161
  193. package/src/services/config-file.ts +0 -101
  194. package/src/services/crypto.test.ts +0 -132
  195. package/src/services/crypto.ts +0 -83
  196. package/src/services/doctor.ts +0 -142
  197. package/src/services/error.ts +0 -6
  198. package/src/services/filesystem.test.ts +0 -171
  199. package/src/services/filesystem.ts +0 -183
  200. package/src/services/forget.ts +0 -261
  201. package/src/services/git.test.ts +0 -83
  202. package/src/services/git.ts +0 -74
  203. package/src/services/init.test.ts +0 -109
  204. package/src/services/init.ts +0 -244
  205. package/src/services/list.ts +0 -63
  206. package/src/services/local-materialization.ts +0 -421
  207. package/src/services/local-snapshot.ts +0 -173
  208. package/src/services/paths.test.ts +0 -74
  209. package/src/services/paths.ts +0 -98
  210. package/src/services/pull.ts +0 -144
  211. package/src/services/push.ts +0 -168
  212. package/src/services/repo-artifacts.ts +0 -262
  213. package/src/services/repo-snapshot.ts +0 -197
  214. package/src/services/runtime.ts +0 -57
  215. package/src/services/set.ts +0 -383
  216. package/src/services/status.ts +0 -57
  217. package/src/services/sync.dry-run.test.ts +0 -179
  218. package/src/services/sync.runtime.test.ts +0 -756
  219. package/src/services/sync.service.test.ts +0 -1169
  220. package/src/test/helpers/sync-fixture.ts +0 -47
@@ -0,0 +1,113 @@
1
+ import { randomUUID } from "node:crypto";
2
+ import { access, chmod, lstat, mkdir, mkdtemp, readdir, readFile, readlink, rename, rm, symlink, writeFile, } from "node:fs/promises";
3
+ import { basename, dirname, join } from "node:path";
4
+ import { buildExecutableMode, isExecutableMode } from "#app/lib/file-mode.js";
5
+ export { buildExecutableMode, isExecutableMode } from "#app/lib/file-mode.js";
6
+ import { DevsyncError } from "./error.js";
7
+ export const pathExists = async (path) => {
8
+ try {
9
+ await access(path);
10
+ return true;
11
+ }
12
+ catch (error) {
13
+ if (error instanceof Error && "code" in error && error.code === "ENOENT") {
14
+ return false;
15
+ }
16
+ throw error;
17
+ }
18
+ };
19
+ export const getPathStats = async (path) => {
20
+ try {
21
+ return await lstat(path);
22
+ }
23
+ catch (error) {
24
+ if (error instanceof Error && "code" in error && error.code === "ENOENT") {
25
+ return undefined;
26
+ }
27
+ throw error;
28
+ }
29
+ };
30
+ export const listDirectoryEntries = async (path) => {
31
+ const entries = await readdir(path, { withFileTypes: true });
32
+ return entries.sort((left, right) => {
33
+ return left.name.localeCompare(right.name);
34
+ });
35
+ };
36
+ export const writeFileNode = async (path, node) => {
37
+ await mkdir(dirname(path), { recursive: true });
38
+ await writeFile(path, node.contents);
39
+ await chmod(path, buildExecutableMode(node.executable));
40
+ };
41
+ export const writeSymlinkNode = async (path, linkTarget) => {
42
+ await mkdir(dirname(path), { recursive: true });
43
+ await rm(path, { force: true, recursive: true });
44
+ await symlink(linkTarget, path);
45
+ };
46
+ export const copyFilesystemNode = async (sourcePath, targetPath, stats) => {
47
+ const sourceStats = stats ?? (await lstat(sourcePath));
48
+ if (sourceStats.isDirectory()) {
49
+ await mkdir(targetPath, { recursive: true });
50
+ const entries = await listDirectoryEntries(sourcePath);
51
+ for (const entry of entries) {
52
+ await copyFilesystemNode(join(sourcePath, entry.name), join(targetPath, entry.name));
53
+ }
54
+ return;
55
+ }
56
+ if (sourceStats.isSymbolicLink()) {
57
+ await writeSymlinkNode(targetPath, await readlink(sourcePath));
58
+ return;
59
+ }
60
+ if (!sourceStats.isFile()) {
61
+ throw new DevsyncError(`Unsupported filesystem entry: ${sourcePath}`);
62
+ }
63
+ await writeFileNode(targetPath, {
64
+ contents: await readFile(sourcePath),
65
+ executable: isExecutableMode(sourceStats.mode),
66
+ });
67
+ };
68
+ export const replacePathAtomically = async (targetPath, nextPath) => {
69
+ const backupPath = join(dirname(targetPath), `.${basename(targetPath)}.devsync-sync-backup-${randomUUID()}`);
70
+ const existingStats = await getPathStats(targetPath);
71
+ let targetMoved = false;
72
+ try {
73
+ if (existingStats !== undefined) {
74
+ await rename(targetPath, backupPath);
75
+ targetMoved = true;
76
+ }
77
+ await rename(nextPath, targetPath);
78
+ if (targetMoved) {
79
+ await rm(backupPath, { force: true, recursive: true });
80
+ }
81
+ }
82
+ catch (error) {
83
+ if (targetMoved && !(await pathExists(targetPath))) {
84
+ await rename(backupPath, targetPath).catch(() => { });
85
+ }
86
+ throw error;
87
+ }
88
+ finally {
89
+ await rm(backupPath, { force: true, recursive: true }).catch(() => { });
90
+ }
91
+ };
92
+ export const removePathAtomically = async (targetPath) => {
93
+ const stats = await getPathStats(targetPath);
94
+ if (stats === undefined) {
95
+ return;
96
+ }
97
+ const backupPath = join(dirname(targetPath), `.${basename(targetPath)}.devsync-sync-remove-${randomUUID()}`);
98
+ await rename(targetPath, backupPath);
99
+ await rm(backupPath, { force: true, recursive: true });
100
+ };
101
+ export const writeTextFileAtomically = async (targetPath, contents) => {
102
+ await mkdir(dirname(targetPath), { recursive: true });
103
+ const stagingDirectory = await mkdtemp(join(dirname(targetPath), `.${basename(targetPath)}.devsync-sync-`));
104
+ const stagedPath = join(stagingDirectory, basename(targetPath));
105
+ try {
106
+ await writeFile(stagedPath, contents, "utf8");
107
+ await replacePathAtomically(targetPath, stagedPath);
108
+ }
109
+ finally {
110
+ await rm(stagingDirectory, { force: true, recursive: true });
111
+ }
112
+ };
113
+ //# sourceMappingURL=filesystem.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"filesystem.js","sourceRoot":"","sources":["../../src/services/filesystem.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,14 @@
1
+ import { type SyncContext } from "./runtime.js";
2
+ export type SyncForgetRequest = Readonly<{
3
+ target: string;
4
+ }>;
5
+ export type SyncForgetResult = Readonly<{
6
+ configPath: string;
7
+ localPath: string;
8
+ plainArtifactCount: number;
9
+ repoPath: string;
10
+ secretArtifactCount: number;
11
+ syncDirectory: string;
12
+ }>;
13
+ export declare const forgetSyncTarget: (request: SyncForgetRequest, context: SyncContext) => Promise<SyncForgetResult>;
14
+ //# sourceMappingURL=forget.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"forget.d.ts","sourceRoot":"","sources":["../../src/services/forget.ts"],"names":[],"mappings":"AA0BA,OAAO,EAAwB,KAAK,WAAW,EAAE,MAAM,cAAc,CAAC;AAEtE,MAAM,MAAM,iBAAiB,GAAG,QAAQ,CAAC;IACvC,MAAM,EAAE,MAAM,CAAC;CAChB,CAAC,CAAC;AAEH,MAAM,MAAM,gBAAgB,GAAG,QAAQ,CAAC;IACtC,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,kBAAkB,EAAE,MAAM,CAAC;IAC3B,QAAQ,EAAE,MAAM,CAAC;IACjB,mBAAmB,EAAE,MAAM,CAAC;IAC5B,aAAa,EAAE,MAAM,CAAC;CACvB,CAAC,CAAC;AA+IH,eAAO,MAAM,gBAAgB,GAC3B,SAAS,iBAAiB,EAC1B,SAAS,WAAW,KACnB,OAAO,CAAC,gBAAgB,CA2C1B,CAAC"}
@@ -0,0 +1,124 @@
1
+ import { readdir, rm } from "node:fs/promises";
2
+ import { dirname, join, posix } from "node:path";
3
+ import { readSyncConfig, resolveSyncArtifactsDirectoryPath, } from "#app/config/sync.js";
4
+ import { createSyncConfigDocument, writeValidatedSyncConfig, } from "./config-file.js";
5
+ import { DevsyncError } from "./error.js";
6
+ import { getPathStats, listDirectoryEntries, removePathAtomically, } from "./filesystem.js";
7
+ import { isPathEqualOrNested, resolveTrackedEntry } from "./paths.js";
8
+ import { collectArtifactNamespaces, isSecretArtifactPath, resolveArtifactRelativePath, resolveEntryArtifactPath, } from "./repo-artifacts.js";
9
+ import { ensureSyncRepository } from "./runtime.js";
10
+ const collectRepoArtifactCounts = async (targetPath, counts, relativePath) => {
11
+ const stats = await getPathStats(targetPath);
12
+ if (stats === undefined) {
13
+ return;
14
+ }
15
+ if (stats.isDirectory()) {
16
+ counts.plain += 1;
17
+ const entries = await listDirectoryEntries(targetPath);
18
+ for (const entry of entries) {
19
+ await collectRepoArtifactCounts(join(targetPath, entry.name), counts, posix.join(relativePath, entry.name));
20
+ }
21
+ return;
22
+ }
23
+ if (isSecretArtifactPath(relativePath)) {
24
+ counts.secret += 1;
25
+ }
26
+ else {
27
+ counts.plain += 1;
28
+ }
29
+ };
30
+ const collectEntryArtifactCounts = async (syncDirectory, entry) => {
31
+ const artifactsRoot = resolveSyncArtifactsDirectoryPath(syncDirectory);
32
+ const counts = {
33
+ plain: 0,
34
+ secret: 0,
35
+ };
36
+ const namespaces = collectArtifactNamespaces([entry]);
37
+ for (const machine of namespaces) {
38
+ await collectRepoArtifactCounts(resolveEntryArtifactPath(artifactsRoot, entry, machine), counts, resolveArtifactRelativePath({
39
+ category: "plain",
40
+ machine,
41
+ repoPath: entry.repoPath,
42
+ }));
43
+ if (entry.kind !== "directory") {
44
+ const secretRelativePath = resolveArtifactRelativePath({
45
+ category: "secret",
46
+ machine,
47
+ repoPath: entry.repoPath,
48
+ });
49
+ await collectRepoArtifactCounts(join(artifactsRoot, ...secretRelativePath.split("/")), counts, secretRelativePath);
50
+ }
51
+ }
52
+ return {
53
+ plainArtifactCount: counts.plain,
54
+ secretArtifactCount: counts.secret,
55
+ };
56
+ };
57
+ const pruneEmptyParentDirectories = async (startPath, rootPath) => {
58
+ let currentPath = startPath;
59
+ while (isPathEqualOrNested(currentPath, rootPath) &&
60
+ currentPath !== rootPath) {
61
+ const stats = await getPathStats(currentPath);
62
+ if (stats === undefined) {
63
+ currentPath = dirname(currentPath);
64
+ continue;
65
+ }
66
+ if (!stats.isDirectory()) {
67
+ break;
68
+ }
69
+ const entries = await readdir(currentPath);
70
+ if (entries.length > 0) {
71
+ break;
72
+ }
73
+ await rm(currentPath, { force: true, recursive: true });
74
+ currentPath = dirname(currentPath);
75
+ }
76
+ };
77
+ const removeTrackedEntryArtifacts = async (syncDirectory, entry) => {
78
+ const artifactsRoot = resolveSyncArtifactsDirectoryPath(syncDirectory);
79
+ const namespaces = collectArtifactNamespaces([entry]);
80
+ for (const machine of namespaces) {
81
+ const plainPath = resolveEntryArtifactPath(artifactsRoot, entry, machine);
82
+ await removePathAtomically(plainPath);
83
+ await pruneEmptyParentDirectories(dirname(plainPath), artifactsRoot);
84
+ if (entry.kind !== "directory") {
85
+ const secretPath = join(artifactsRoot, ...resolveArtifactRelativePath({
86
+ category: "secret",
87
+ machine,
88
+ repoPath: entry.repoPath,
89
+ }).split("/"));
90
+ await removePathAtomically(secretPath);
91
+ await pruneEmptyParentDirectories(dirname(secretPath), artifactsRoot);
92
+ }
93
+ }
94
+ };
95
+ export const forgetSyncTarget = async (request, context) => {
96
+ const target = request.target.trim();
97
+ if (target.length === 0) {
98
+ throw new DevsyncError("Target path is required.");
99
+ }
100
+ await ensureSyncRepository(context);
101
+ const config = await readSyncConfig(context.paths.syncDirectory, context.environment);
102
+ const entry = resolveTrackedEntry(target, config.entries, context);
103
+ if (entry === undefined) {
104
+ throw new DevsyncError(`No tracked sync entry matches: ${target}`);
105
+ }
106
+ const { plainArtifactCount, secretArtifactCount } = await collectEntryArtifactCounts(context.paths.syncDirectory, entry);
107
+ const nextConfig = createSyncConfigDocument({
108
+ ...config,
109
+ entries: config.entries.filter((configEntry) => {
110
+ return configEntry.repoPath !== entry.repoPath;
111
+ }),
112
+ });
113
+ await writeValidatedSyncConfig(context.paths.syncDirectory, nextConfig, context.environment);
114
+ await removeTrackedEntryArtifacts(context.paths.syncDirectory, entry);
115
+ return {
116
+ configPath: context.paths.configPath,
117
+ localPath: entry.localPath,
118
+ plainArtifactCount,
119
+ repoPath: entry.repoPath,
120
+ secretArtifactCount,
121
+ syncDirectory: context.paths.syncDirectory,
122
+ };
123
+ };
124
+ //# sourceMappingURL=forget.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"forget.js","sourceRoot":"","sources":["../../src/services/forget.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,10 @@
1
+ export declare const ensureRepository: (directory: string) => Promise<void>;
2
+ export declare const initializeRepository: (directory: string, source?: string) => Promise<{
3
+ action: "initialized";
4
+ source?: undefined;
5
+ } | {
6
+ action: "cloned";
7
+ source: string;
8
+ }>;
9
+ export declare const ensureGitRepository: (syncDirectory: string) => Promise<void>;
10
+ //# sourceMappingURL=git.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"git.d.ts","sourceRoot":"","sources":["../../src/services/git.ts"],"names":[],"mappings":"AAuCA,eAAO,MAAM,gBAAgB,GAAU,WAAW,MAAM,kBAEvD,CAAC;AAEF,eAAO,MAAM,oBAAoB,GAC/B,WAAW,MAAM,EACjB,SAAS,MAAM;;;;;;EAgBhB,CAAC;AAEF,eAAO,MAAM,mBAAmB,GAAU,eAAe,MAAM,kBAU9D,CAAC"}
@@ -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"}