@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.
Files changed (2) hide show
  1. package/dist/cli.js +96 -17
  2. 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 chalk3 from "chalk";
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(chalk3.bold.blue("\n AnrakLegal Sync \u2014 Setup\n"));
1305
+ console.log(chalk4.bold.blue("\n AnrakLegal Sync \u2014 Setup\n"));
1227
1306
  const apiUrl = await rl.question(
1228
- ` AnrakLegal URL ${chalk3.dim("(https://anrak.legal)")}: `
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 ${chalk3.dim(`(${defaultFolder})`)}: `
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
- chalk3.dim("\n Run `anrak-sync start` to begin syncing\n")
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(chalk3.bold.blue("\n AnrakLegal Sync\n"));
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(chalk3.bold.blue("\n AnrakLegal Sync \u2014 Push\n"));
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(chalk3.bold.blue("\n AnrakLegal Sync \u2014 Status\n"));
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: ${chalk3.green(stats.synced)}`);
1354
- console.log(` Pending: ${chalk3.yellow(stats.pending)}`);
1355
- console.log(` Errors: ${chalk3.red(stats.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: ${chalk3.green("valid")}`);
1440
+ console.log(` Auth: ${chalk4.green("valid")}`);
1362
1441
  } catch {
1363
1442
  console.log(`
1364
- Auth: ${chalk3.red("expired \u2014 run anrak-sync login")}`);
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(chalk3.bold.blue("\n AnrakLegal Sync \u2014 Mappings\n"));
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
- ` ${chalk3.cyan(folder)} -> ${mapping.caseNumber} (${chalk3.dim(mapping.caseName)})`
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(chalk3.dim("\n Unmapped server cases:"));
1466
+ console.log(chalk4.dim("\n Unmapped server cases:"));
1388
1467
  for (const c of unmapped) {
1389
- console.log(` ${chalk3.dim(c.caseNumber)} ${chalk3.dim(c.caseName)}`);
1468
+ console.log(` ${chalk4.dim(c.caseNumber)} ${chalk4.dim(c.caseName)}`);
1390
1469
  }
1391
1470
  }
1392
1471
  } catch {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@anraktech/sync",
3
- "version": "0.6.0",
3
+ "version": "0.7.0",
4
4
  "description": "AnrakLegal desktop file sync agent — watches local folders and syncs to case management",
5
5
  "type": "module",
6
6
  "bin": {