+59
-48
index.ts
+59
-48
index.ts
···
6
6
import { Command, createArgument } from 'commander';
7
7
import ora from 'ora';
8
8
import path from 'path';
9
-
import { mkdir, readdir, stat, copyFile, readFile } from 'fs/promises';
9
+
import { mkdir, readdir, stat, copyFile, readFile, writeFile } from 'fs/promises';
10
10
import { cosmiconfig } from 'cosmiconfig';
11
11
import ignore, { Ignore } from 'ignore';
12
12
import type { Stats } from 'fs';
13
+
13
14
14
15
const repo = new Repo({
15
16
network: [
···
131
132
return folderHandle
132
133
}
133
134
135
+
async function downloadAutomergeDocuments(
136
+
rootUrl: AutomergeUrl,
137
+
outputPath: string
138
+
) {
139
+
console.log(rootUrl)
140
+
const rootHandle = repo.find<Folder | ImportedFile>(rootUrl)
141
+
const rootDoc = await rootHandle.doc()
142
+
console.log(rootHandle.state)
143
+
console.log(rootDoc)
144
+
145
+
async function downloadItem(doc: Folder | ImportedFile, currentPath: string) {
146
+
// TODO:
147
+
// We need to check mimetypes
148
+
if ('contents' in doc && Array.isArray(doc.contents)) {
149
+
// This is a folder
150
+
const folderPath = path.join(currentPath, doc.name)
151
+
console.log(folderPath)
152
+
await mkdir(folderPath, { recursive: true })
153
+
154
+
// Recursively process all items in the folder
155
+
for (const item of doc.contents) {
156
+
const itemHandle = repo.find(item.automergeUrl)
157
+
const itemDoc = await itemHandle.doc()
158
+
await downloadItem(itemDoc, folderPath)
159
+
}
160
+
} else {
161
+
// This is a file
162
+
const filePath = path.join(currentPath, doc.name)
163
+
164
+
if (typeof doc.contents === 'string') {
165
+
await writeFile(filePath, doc.contents, 'utf-8')
166
+
} else if (doc.contents instanceof Uint8Array) {
167
+
await writeFile(filePath, doc.contents)
168
+
}
169
+
170
+
//if (doc.executable) {
171
+
// await chmod(filePath, 0o755)
172
+
//}
173
+
}
174
+
}
175
+
176
+
await downloadItem(rootDoc, outputPath)
177
+
}
178
+
179
+
134
180
async function* walk(dir: string, root = dir): AsyncGenerator<FileInfo> {
135
181
const files = await readdir(dir);
136
182
···
165
211
return destPath;
166
212
};
167
213
168
-
const push = async (source: string, options: CommandOptions): Promise<void> => {
169
-
const spinner = ora('Pushing files...').start();
170
-
const config = await loadConfig();
171
-
const destination = options.dest ?? config.defaultDestination ?? './dest';
172
-
let fileCount = 0;
173
214
174
-
try {
175
-
await mkdir(destination, { recursive: true });
176
-
177
-
for await (const fileInfo of walk(source)) {
178
-
spinner.text = `Processing: ${fileInfo.relativePath}`;
179
-
await processFile(fileInfo, destination);
180
-
fileCount++;
181
-
}
182
-
183
-
spinner.succeed(`Successfully pushed ${fileCount} files to ${destination}`);
184
-
} catch (err) {
185
-
spinner.fail(`Push failed: ${err instanceof Error ? err.message : String(err)}`);
186
-
process.exit(1);
187
-
}
188
-
};
189
-
190
-
const pull = async (source: string, options: CommandOptions): Promise<void> => {
191
-
const spinner = ora('Pulling files...').start();
192
-
const config = await loadConfig();
193
-
const destination = options.dest ?? config.defaultSource ?? './src';
194
-
let fileCount = 0;
215
+
const pull = async (source: string, path: string): Promise<void> => {
216
+
console.log(`Listing all files in ${source}:`);
217
+
const s = <AutomergeUrl>(source)
195
218
196
219
try {
197
-
await mkdir(destination, { recursive: true });
198
-
199
-
for await (const fileInfo of walk(source)) {
200
-
spinner.text = `Processing: ${fileInfo.relativePath}`;
201
-
await processFile(fileInfo, destination);
202
-
fileCount++;
203
-
}
204
-
205
-
spinner.succeed(`Successfully pulled ${fileCount} files to ${destination}`);
220
+
const folderHandle = await downloadAutomergeDocuments(s, path.dest)
221
+
repo.shutdown()
206
222
} catch (err) {
207
-
spinner.fail(`Pull failed: ${err instanceof Error ? err.message : String(err)}`);
223
+
console.error('List failed:', err instanceof Error ? err.message : err);
208
224
process.exit(1);
209
225
}
210
226
};
211
227
212
-
const list = async (source: string): Promise<void> => {
228
+
const push = async (source: string): Promise<void> => {
213
229
console.log(`Listing all files in ${source}:`);
214
230
215
231
try {
···
221
237
process.exit(1);
222
238
}
223
239
};
240
+
224
241
225
242
const program = new Command();
226
243
···
236
253
await initIgnorePatterns(program.opts().ignore);
237
254
});
238
255
239
-
program.command('push')
240
-
.description('Push files to destination')
241
-
.argument('<source>', 'Source directory')
242
-
.option('-d, --dest <path>', 'Destination directory')
243
-
.action(push);
244
-
245
256
program.command('pull')
246
257
.description('Pull files from source')
247
-
.argument('<source>', 'Source directory')
258
+
.argument('<source>', 'Source Automerge URL')
248
259
.option('-d, --dest <path>', 'Destination directory')
249
260
.action(pull);
250
261
251
-
program.command('list')
252
-
.description('List all files in directory')
262
+
program.command('push')
263
+
.description('Push all files in directory into Automerge')
253
264
.argument('<source>', 'Source directory')
254
-
.action(list);
265
+
.action(push);
255
266
256
267
program.parse();