@anraktech/sync 0.6.0 → 0.7.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.
- package/dist/cli.js +96 -17
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -6,7 +6,7 @@ import { createInterface as createInterface2 } from "readline/promises";
|
|
|
6
6
|
import { stdin as stdin2, stdout as stdout2 } from "process";
|
|
7
7
|
import { existsSync as existsSync4, statSync as statSync3 } from "fs";
|
|
8
8
|
import { resolve as resolve3 } from "path";
|
|
9
|
-
import
|
|
9
|
+
import chalk4 from "chalk";
|
|
10
10
|
|
|
11
11
|
// src/config.ts
|
|
12
12
|
import { existsSync, mkdirSync, readFileSync, writeFileSync } from "fs";
|
|
@@ -1211,6 +1211,84 @@ async function startWatching(config) {
|
|
|
1211
1211
|
process.on("SIGTERM", shutdown);
|
|
1212
1212
|
}
|
|
1213
1213
|
|
|
1214
|
+
// src/updater.ts
|
|
1215
|
+
import { execFileSync } from "child_process";
|
|
1216
|
+
import chalk3 from "chalk";
|
|
1217
|
+
var PACKAGE_NAME = "@anraktech/sync";
|
|
1218
|
+
var CHECK_INTERVAL_MS = 4 * 60 * 60 * 1e3;
|
|
1219
|
+
var updateCache = { lastCheck: 0, latestVersion: null };
|
|
1220
|
+
function compareVersions(current, latest) {
|
|
1221
|
+
const a = current.split(".").map(Number);
|
|
1222
|
+
const b = latest.split(".").map(Number);
|
|
1223
|
+
for (let i = 0; i < 3; i++) {
|
|
1224
|
+
if ((b[i] ?? 0) > (a[i] ?? 0)) return 1;
|
|
1225
|
+
if ((b[i] ?? 0) < (a[i] ?? 0)) return -1;
|
|
1226
|
+
}
|
|
1227
|
+
return 0;
|
|
1228
|
+
}
|
|
1229
|
+
async function fetchLatestVersion() {
|
|
1230
|
+
try {
|
|
1231
|
+
const res = await fetch(`https://registry.npmjs.org/${PACKAGE_NAME}/latest`, {
|
|
1232
|
+
signal: AbortSignal.timeout(5e3)
|
|
1233
|
+
});
|
|
1234
|
+
if (!res.ok) return null;
|
|
1235
|
+
const data = await res.json();
|
|
1236
|
+
return data.version ?? null;
|
|
1237
|
+
} catch {
|
|
1238
|
+
return null;
|
|
1239
|
+
}
|
|
1240
|
+
}
|
|
1241
|
+
function performUpdate(currentVersion, latestVersion) {
|
|
1242
|
+
console.log("");
|
|
1243
|
+
console.log(
|
|
1244
|
+
chalk3.dim(` Update available: ${currentVersion} \u2192 `) + chalk3.green(latestVersion)
|
|
1245
|
+
);
|
|
1246
|
+
console.log(chalk3.dim(" Updating..."));
|
|
1247
|
+
try {
|
|
1248
|
+
execFileSync("npm", ["install", "-g", `${PACKAGE_NAME}@${latestVersion}`], {
|
|
1249
|
+
stdio: "pipe",
|
|
1250
|
+
timeout: 6e4
|
|
1251
|
+
});
|
|
1252
|
+
console.log(chalk3.green(" Updated successfully. Restart to use the new version."));
|
|
1253
|
+
console.log("");
|
|
1254
|
+
return true;
|
|
1255
|
+
} catch {
|
|
1256
|
+
try {
|
|
1257
|
+
execFileSync("npm", ["install", "-g", `${PACKAGE_NAME}@${latestVersion}`, "--prefix", process.env.HOME + "/.npm-global"], {
|
|
1258
|
+
stdio: "pipe",
|
|
1259
|
+
timeout: 6e4
|
|
1260
|
+
});
|
|
1261
|
+
console.log(chalk3.green(" Updated successfully. Restart to use the new version."));
|
|
1262
|
+
console.log("");
|
|
1263
|
+
return true;
|
|
1264
|
+
} catch {
|
|
1265
|
+
console.log(
|
|
1266
|
+
chalk3.dim(" Auto-update failed. Run manually: ") + chalk3.cyan(`npm install -g ${PACKAGE_NAME}`)
|
|
1267
|
+
);
|
|
1268
|
+
console.log("");
|
|
1269
|
+
return false;
|
|
1270
|
+
}
|
|
1271
|
+
}
|
|
1272
|
+
}
|
|
1273
|
+
async function checkForUpdates(currentVersion) {
|
|
1274
|
+
try {
|
|
1275
|
+
const now = Date.now();
|
|
1276
|
+
if (now - updateCache.lastCheck < CHECK_INTERVAL_MS && updateCache.latestVersion) {
|
|
1277
|
+
if (compareVersions(currentVersion, updateCache.latestVersion) > 0) {
|
|
1278
|
+
performUpdate(currentVersion, updateCache.latestVersion);
|
|
1279
|
+
}
|
|
1280
|
+
return;
|
|
1281
|
+
}
|
|
1282
|
+
const latestVersion = await fetchLatestVersion();
|
|
1283
|
+
updateCache = { lastCheck: now, latestVersion };
|
|
1284
|
+
if (!latestVersion) return;
|
|
1285
|
+
if (compareVersions(currentVersion, latestVersion) > 0) {
|
|
1286
|
+
performUpdate(currentVersion, latestVersion);
|
|
1287
|
+
}
|
|
1288
|
+
} catch {
|
|
1289
|
+
}
|
|
1290
|
+
}
|
|
1291
|
+
|
|
1214
1292
|
// src/cli.ts
|
|
1215
1293
|
import { readFileSync as readFileSync2 } from "fs";
|
|
1216
1294
|
import { fileURLToPath } from "url";
|
|
@@ -1218,14 +1296,15 @@ import { dirname as dirname2, join as join4 } from "path";
|
|
|
1218
1296
|
var __filename2 = fileURLToPath(import.meta.url);
|
|
1219
1297
|
var __dirname2 = dirname2(__filename2);
|
|
1220
1298
|
var pkg = JSON.parse(readFileSync2(join4(__dirname2, "..", "package.json"), "utf-8"));
|
|
1299
|
+
await checkForUpdates(pkg.version);
|
|
1221
1300
|
var program = new Command();
|
|
1222
1301
|
program.name("anrak-sync").description("AnrakLegal desktop file sync \u2014 watches local folders, syncs to case management").version(pkg.version);
|
|
1223
1302
|
program.command("init").description("Set up AnrakLegal Sync (first-time configuration)").option("--password", "Use email/password login instead of browser").action(async (opts) => {
|
|
1224
1303
|
const rl = createInterface2({ input: stdin2, output: stdout2 });
|
|
1225
1304
|
try {
|
|
1226
|
-
console.log(
|
|
1305
|
+
console.log(chalk4.bold.blue("\n AnrakLegal Sync \u2014 Setup\n"));
|
|
1227
1306
|
const apiUrl = await rl.question(
|
|
1228
|
-
` AnrakLegal URL ${
|
|
1307
|
+
` AnrakLegal URL ${chalk4.dim("(https://anrak.legal)")}: `
|
|
1229
1308
|
) || "https://anrak.legal";
|
|
1230
1309
|
log.info("Connecting to server...");
|
|
1231
1310
|
const serverConfig = await fetchServerConfig(apiUrl);
|
|
@@ -1256,7 +1335,7 @@ program.command("init").description("Set up AnrakLegal Sync (first-time configur
|
|
|
1256
1335
|
const rl2 = createInterface2({ input: stdin2, output: stdout2 });
|
|
1257
1336
|
const defaultFolder = process.platform === "win32" ? "C:\\Cases" : `${process.env.HOME}/Cases`;
|
|
1258
1337
|
const watchInput = await rl2.question(
|
|
1259
|
-
` Watch folder ${
|
|
1338
|
+
` Watch folder ${chalk4.dim(`(${defaultFolder})`)}: `
|
|
1260
1339
|
);
|
|
1261
1340
|
const watchFolder = resolve3(watchInput || defaultFolder);
|
|
1262
1341
|
rl2.close();
|
|
@@ -1282,7 +1361,7 @@ program.command("init").description("Set up AnrakLegal Sync (first-time configur
|
|
|
1282
1361
|
log.info(`Config saved to ${getConfigDir()}`);
|
|
1283
1362
|
log.info(`Watching: ${watchFolder}`);
|
|
1284
1363
|
console.log(
|
|
1285
|
-
|
|
1364
|
+
chalk4.dim("\n Run `anrak-sync start` to begin syncing\n")
|
|
1286
1365
|
);
|
|
1287
1366
|
} catch (err) {
|
|
1288
1367
|
log.error(err instanceof Error ? err.message : String(err));
|
|
@@ -1317,7 +1396,7 @@ program.command("login").description("Re-authenticate with AnrakLegal").option("
|
|
|
1317
1396
|
});
|
|
1318
1397
|
program.command("start").description("Start watching for file changes and syncing").action(async () => {
|
|
1319
1398
|
const config = requireConfig();
|
|
1320
|
-
console.log(
|
|
1399
|
+
console.log(chalk4.bold.blue("\n AnrakLegal Sync\n"));
|
|
1321
1400
|
log.info(`Watching: ${config.watchFolder}`);
|
|
1322
1401
|
log.info(`Server: ${config.apiUrl}`);
|
|
1323
1402
|
console.log("");
|
|
@@ -1330,7 +1409,7 @@ program.command("start").description("Start watching for file changes and syncin
|
|
|
1330
1409
|
});
|
|
1331
1410
|
program.command("push").description("One-time sync \u2014 upload all new/changed files, then exit").action(async () => {
|
|
1332
1411
|
const config = requireConfig();
|
|
1333
|
-
console.log(
|
|
1412
|
+
console.log(chalk4.bold.blue("\n AnrakLegal Sync \u2014 Push\n"));
|
|
1334
1413
|
log.info(`Folder: ${config.watchFolder}`);
|
|
1335
1414
|
log.info(`Server: ${config.apiUrl}`);
|
|
1336
1415
|
console.log("");
|
|
@@ -1344,24 +1423,24 @@ program.command("push").description("One-time sync \u2014 upload all new/changed
|
|
|
1344
1423
|
program.command("status").description("Show sync status").action(async () => {
|
|
1345
1424
|
const config = requireConfig();
|
|
1346
1425
|
const stats = getStats();
|
|
1347
|
-
console.log(
|
|
1426
|
+
console.log(chalk4.bold.blue("\n AnrakLegal Sync \u2014 Status\n"));
|
|
1348
1427
|
console.log(` Server: ${config.apiUrl}`);
|
|
1349
1428
|
console.log(` Watch folder: ${config.watchFolder}`);
|
|
1350
1429
|
console.log(` Config: ${getConfigDir()}`);
|
|
1351
1430
|
console.log("");
|
|
1352
1431
|
console.log(` Files tracked: ${stats.totalFiles}`);
|
|
1353
|
-
console.log(` Synced: ${
|
|
1354
|
-
console.log(` Pending: ${
|
|
1355
|
-
console.log(` Errors: ${
|
|
1432
|
+
console.log(` Synced: ${chalk4.green(stats.synced)}`);
|
|
1433
|
+
console.log(` Pending: ${chalk4.yellow(stats.pending)}`);
|
|
1434
|
+
console.log(` Errors: ${chalk4.red(stats.errors)}`);
|
|
1356
1435
|
console.log(` Mapped folders: ${stats.mappedFolders}`);
|
|
1357
1436
|
try {
|
|
1358
1437
|
const cases = await listCases(config);
|
|
1359
1438
|
console.log(`
|
|
1360
1439
|
Server cases: ${cases.length}`);
|
|
1361
|
-
console.log(` Auth: ${
|
|
1440
|
+
console.log(` Auth: ${chalk4.green("valid")}`);
|
|
1362
1441
|
} catch {
|
|
1363
1442
|
console.log(`
|
|
1364
|
-
Auth: ${
|
|
1443
|
+
Auth: ${chalk4.red("expired \u2014 run anrak-sync login")}`);
|
|
1365
1444
|
}
|
|
1366
1445
|
console.log("");
|
|
1367
1446
|
});
|
|
@@ -1369,13 +1448,13 @@ program.command("map").description("Show folder-to-case mappings").action(async
|
|
|
1369
1448
|
const config = requireConfig();
|
|
1370
1449
|
const mappings = getAllMappings();
|
|
1371
1450
|
const entries = Object.entries(mappings);
|
|
1372
|
-
console.log(
|
|
1451
|
+
console.log(chalk4.bold.blue("\n AnrakLegal Sync \u2014 Mappings\n"));
|
|
1373
1452
|
if (entries.length === 0) {
|
|
1374
1453
|
log.info("No mappings yet. Run `anrak-sync push` or `anrak-sync start` to create them.");
|
|
1375
1454
|
} else {
|
|
1376
1455
|
for (const [folder, mapping] of entries) {
|
|
1377
1456
|
console.log(
|
|
1378
|
-
` ${
|
|
1457
|
+
` ${chalk4.cyan(folder)} -> ${mapping.caseNumber} (${chalk4.dim(mapping.caseName)})`
|
|
1379
1458
|
);
|
|
1380
1459
|
}
|
|
1381
1460
|
}
|
|
@@ -1384,9 +1463,9 @@ program.command("map").description("Show folder-to-case mappings").action(async
|
|
|
1384
1463
|
const mappedIds = new Set(entries.map(([, m]) => m.caseId));
|
|
1385
1464
|
const unmapped = cases.filter((c) => !mappedIds.has(c.id));
|
|
1386
1465
|
if (unmapped.length > 0) {
|
|
1387
|
-
console.log(
|
|
1466
|
+
console.log(chalk4.dim("\n Unmapped server cases:"));
|
|
1388
1467
|
for (const c of unmapped) {
|
|
1389
|
-
console.log(` ${
|
|
1468
|
+
console.log(` ${chalk4.dim(c.caseNumber)} ${chalk4.dim(c.caseName)}`);
|
|
1390
1469
|
}
|
|
1391
1470
|
}
|
|
1392
1471
|
} catch {
|