@lumy-pack/syncpoint 0.0.10 → 0.0.12

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.
@@ -0,0 +1,9 @@
1
+ import { Command } from 'commander';
2
+ import React from 'react';
3
+ interface LinkViewProps {
4
+ refPath?: string;
5
+ yes: boolean;
6
+ }
7
+ export declare const LinkView: React.FC<LinkViewProps>;
8
+ export declare function registerLinkCommand(program: Command): void;
9
+ export {};
@@ -0,0 +1,2 @@
1
+ import { Command } from 'commander';
2
+ export declare function registerUnlinkCommand(program: Command): void;
@@ -0,0 +1,19 @@
1
+ import type { LinkOptions, LinkResult, UnlinkOptions, UnlinkResult } from '../utils/types.js';
2
+ /**
3
+ * Move ~/.syncpoint to {destination}/.syncpoint/ and create a symlink.
4
+ * If ~/.syncpoint is already a symlink, unlink and restore before re-linking.
5
+ */
6
+ export declare function linkSyncpoint(destination: string, _options?: LinkOptions): Promise<LinkResult>;
7
+ /**
8
+ * Create a symlink ~/.syncpoint → <refPath>/.syncpoint.
9
+ * For backwards compatibility, if refPath already points to a .syncpoint directory,
10
+ * it is used as-is.
11
+ * If ~/.syncpoint already exists, the caller must handle confirmation before invoking this.
12
+ */
13
+ export declare function linkSyncpointByRef(refPath: string): Promise<LinkResult>;
14
+ /**
15
+ * Remove the symlink at ~/.syncpoint and restore its contents by copying
16
+ * from the symlink target back to ~/.syncpoint.
17
+ * With options.clean=true, also removes the destination copy.
18
+ */
19
+ export declare function unlinkSyncpoint(options?: UnlinkOptions): Promise<UnlinkResult>;
package/dist/errors.d.ts CHANGED
@@ -7,6 +7,8 @@ export declare const SyncpointErrorCode: {
7
7
  readonly PROVISION_FAILED: "PROVISION_FAILED";
8
8
  readonly MISSING_ARGUMENT: "MISSING_ARGUMENT";
9
9
  readonly INVALID_ARGUMENT: "INVALID_ARGUMENT";
10
+ readonly LINK_FAILED: "LINK_FAILED";
11
+ readonly UNLINK_FAILED: "UNLINK_FAILED";
10
12
  readonly UNKNOWN: "UNKNOWN";
11
13
  };
12
14
  export type SyncpointErrorCode = (typeof SyncpointErrorCode)[keyof typeof SyncpointErrorCode];
package/dist/index.cjs CHANGED
@@ -51,6 +51,7 @@ var importMetaUrl = /* @__PURE__ */ getImportMetaUrl();
51
51
  // src/core/config.ts
52
52
  var import_promises2 = require("fs/promises");
53
53
  var import_node_path4 = require("path");
54
+ var import_common_utils2 = require("@winglet/common-utils");
54
55
  var import_yaml = __toESM(require("yaml"), 1);
55
56
 
56
57
  // src/constants.ts
@@ -126,6 +127,9 @@ function getSubDir(sub) {
126
127
  return (0, import_node_path2.join)(getAppDir(), sub);
127
128
  }
128
129
 
130
+ // src/schemas/config.schema.ts
131
+ var import_common_utils = require("@winglet/common-utils");
132
+
129
133
  // assets/schemas/config.schema.json
130
134
  var config_schema_default = {
131
135
  $schema: "http://json-schema.org/draft-07/schema#",
@@ -299,9 +303,10 @@ var validate2 = ajv.compile(config_schema_default);
299
303
  function validateConfig(data) {
300
304
  const valid = validate2(data);
301
305
  if (valid) return { valid: true };
302
- const errors = validate2.errors?.map(
306
+ const errors = validate2.errors ? (0, import_common_utils.map)(
307
+ validate2.errors,
303
308
  (e) => `${e.instancePath || "/"} ${e.message ?? "unknown error"}`
304
- );
309
+ ) : void 0;
305
310
  return { valid: false, errors };
306
311
  }
307
312
 
@@ -327,7 +332,7 @@ function readAsset(filename) {
327
332
  // src/core/config.ts
328
333
  function stripDangerousKeys(obj) {
329
334
  if (obj === null || typeof obj !== "object") return obj;
330
- if (Array.isArray(obj)) return obj.map(stripDangerousKeys);
335
+ if ((0, import_common_utils2.isArray)(obj)) return (0, import_common_utils2.map)(obj, stripDangerousKeys);
331
336
  const cleaned = {};
332
337
  for (const [key, value] of Object.entries(obj)) {
333
338
  if (["__proto__", "constructor", "prototype"].includes(key)) continue;
@@ -401,6 +406,7 @@ async function initDefaultConfig() {
401
406
  // src/core/backup.ts
402
407
  var import_promises6 = require("fs/promises");
403
408
  var import_node_path7 = require("path");
409
+ var import_common_utils5 = require("@winglet/common-utils");
404
410
  var import_fast_glob = __toESM(require("fast-glob"), 1);
405
411
 
406
412
  // src/utils/system.ts
@@ -510,6 +516,10 @@ var logger = {
510
516
  // src/core/metadata.ts
511
517
  var import_node_crypto = require("crypto");
512
518
  var import_promises4 = require("fs/promises");
519
+ var import_common_utils4 = require("@winglet/common-utils");
520
+
521
+ // src/schemas/metadata.schema.ts
522
+ var import_common_utils3 = require("@winglet/common-utils");
513
523
 
514
524
  // assets/schemas/metadata.schema.json
515
525
  var metadata_schema_default = {
@@ -639,14 +649,15 @@ var validate3 = ajv.compile(metadata_schema_default);
639
649
  function validateMetadata(data) {
640
650
  const valid = validate3(data);
641
651
  if (valid) return { valid: true };
642
- const errors = validate3.errors?.map(
652
+ const errors = validate3.errors ? (0, import_common_utils3.map)(
653
+ validate3.errors,
643
654
  (e) => `${e.instancePath || "/"} ${e.message ?? "unknown error"}`
644
- );
655
+ ) : void 0;
645
656
  return { valid: false, errors };
646
657
  }
647
658
 
648
659
  // src/version.ts
649
- var VERSION = "0.0.10";
660
+ var VERSION = "0.0.12";
650
661
 
651
662
  // src/core/metadata.ts
652
663
  var METADATA_VERSION = "1.0.0";
@@ -670,7 +681,7 @@ function createMetadata(files, config) {
670
681
  };
671
682
  }
672
683
  function parseMetadata(data) {
673
- const str = typeof data === "string" ? data : data.toString("utf-8");
684
+ const str = (0, import_common_utils4.isString)(data) ? data : data.toString("utf-8");
674
685
  const parsed = JSON.parse(str);
675
686
  const result = validateMetadata(parsed);
676
687
  if (!result.valid) {
@@ -824,7 +835,8 @@ async function scanTargets(config) {
824
835
  "**/Library/**",
825
836
  "**/.cache/**",
826
837
  "**/node_modules/**",
827
- ...config.backup.exclude.filter(
838
+ ...(0, import_common_utils5.filter)(
839
+ config.backup.exclude,
828
840
  (p) => detectPatternType(p) === "glob"
829
841
  )
830
842
  ]
@@ -995,6 +1007,7 @@ async function createBackup(config, options = {}) {
995
1007
  // src/core/restore.ts
996
1008
  var import_promises7 = require("fs/promises");
997
1009
  var import_node_path8 = require("path");
1010
+ var import_common_utils6 = require("@winglet/common-utils");
998
1011
  async function getBackupList(config) {
999
1012
  const backupDir = config?.backup.destination ? resolveTargetPath(config.backup.destination) : getSubDir(BACKUPS_DIR);
1000
1013
  const exists = await fileExists(backupDir);
@@ -1099,15 +1112,26 @@ async function restoreBackup(archivePath, options = {}) {
1099
1112
  const plan = await getRestorePlan(archivePath);
1100
1113
  const restoredFiles = [];
1101
1114
  const skippedFiles = [];
1102
- const overwritePaths = plan.actions.filter((a) => a.action === "overwrite").map((a) => a.path);
1115
+ const overwritePaths = [];
1116
+ (0, import_common_utils6.forEach)(plan.actions, (a) => {
1117
+ if (a.action === "overwrite") overwritePaths.push(a.path);
1118
+ });
1103
1119
  let safetyBackupPath;
1104
1120
  if (overwritePaths.length > 0 && !options.dryRun) {
1105
1121
  safetyBackupPath = await createSafetyBackup(overwritePaths);
1106
1122
  }
1107
1123
  if (options.dryRun) {
1124
+ const restoredFiles2 = [];
1125
+ (0, import_common_utils6.forEach)(plan.actions, (a) => {
1126
+ if (a.action !== "skip") restoredFiles2.push(a.path);
1127
+ });
1128
+ const skippedFiles2 = [];
1129
+ (0, import_common_utils6.forEach)(plan.actions, (a) => {
1130
+ if (a.action === "skip") skippedFiles2.push(a.path);
1131
+ });
1108
1132
  return {
1109
- restoredFiles: plan.actions.filter((a) => a.action !== "skip").map((a) => a.path),
1110
- skippedFiles: plan.actions.filter((a) => a.action === "skip").map((a) => a.path),
1133
+ restoredFiles: restoredFiles2,
1134
+ skippedFiles: skippedFiles2,
1111
1135
  safetyBackupPath
1112
1136
  };
1113
1137
  }
@@ -1154,8 +1178,12 @@ async function restoreBackup(archivePath, options = {}) {
1154
1178
  var import_node_child_process = require("child_process");
1155
1179
  var import_promises8 = require("fs/promises");
1156
1180
  var import_node_path9 = require("path");
1181
+ var import_common_utils8 = require("@winglet/common-utils");
1157
1182
  var import_yaml2 = __toESM(require("yaml"), 1);
1158
1183
 
1184
+ // src/schemas/template.schema.ts
1185
+ var import_common_utils7 = require("@winglet/common-utils");
1186
+
1159
1187
  // assets/schemas/template.schema.json
1160
1188
  var template_schema_default = {
1161
1189
  $schema: "http://json-schema.org/draft-07/schema#",
@@ -1224,9 +1252,10 @@ var validate4 = ajv.compile(template_schema_default);
1224
1252
  function validateTemplate(data) {
1225
1253
  const valid = validate4(data);
1226
1254
  if (valid) return { valid: true };
1227
- const errors = validate4.errors?.map(
1255
+ const errors = validate4.errors ? (0, import_common_utils7.map)(
1256
+ validate4.errors,
1228
1257
  (e) => `${e.instancePath || "/"} ${e.message ?? "unknown error"}`
1229
- );
1258
+ ) : void 0;
1230
1259
  return { valid: false, errors };
1231
1260
  }
1232
1261
 
@@ -1338,7 +1367,7 @@ async function executeStep(step) {
1338
1367
  }
1339
1368
  try {
1340
1369
  const { stdout, stderr } = await execAsync(step.command);
1341
- const output = [stdout, stderr].filter(Boolean).join("\n").trim();
1370
+ const output = (0, import_common_utils8.filter)([stdout, stderr], import_common_utils8.isTruthy).join("\n").trim();
1342
1371
  return {
1343
1372
  name: step.name,
1344
1373
  status: "success",
@@ -1349,7 +1378,7 @@ async function executeStep(step) {
1349
1378
  const error = err instanceof Error ? err : new Error(String(err));
1350
1379
  const stdout = err?.stdout ?? "";
1351
1380
  const stderr = err?.stderr ?? "";
1352
- const errorOutput = [stdout, stderr, error.message].filter(Boolean).join("\n").trim();
1381
+ const errorOutput = (0, import_common_utils8.filter)([stdout, stderr, error.message], import_common_utils8.isTruthy).join("\n").trim();
1353
1382
  return {
1354
1383
  name: step.name,
1355
1384
  status: "failed",
package/dist/index.mjs CHANGED
@@ -1,6 +1,7 @@
1
1
  // src/core/config.ts
2
2
  import { readFile, writeFile } from "fs/promises";
3
3
  import { join as join4 } from "path";
4
+ import { isArray, map as map2 } from "@winglet/common-utils";
4
5
  import YAML from "yaml";
5
6
 
6
7
  // src/constants.ts
@@ -76,6 +77,9 @@ function getSubDir(sub) {
76
77
  return join2(getAppDir(), sub);
77
78
  }
78
79
 
80
+ // src/schemas/config.schema.ts
81
+ import { map } from "@winglet/common-utils";
82
+
79
83
  // assets/schemas/config.schema.json
80
84
  var config_schema_default = {
81
85
  $schema: "http://json-schema.org/draft-07/schema#",
@@ -249,9 +253,10 @@ var validate2 = ajv.compile(config_schema_default);
249
253
  function validateConfig(data) {
250
254
  const valid = validate2(data);
251
255
  if (valid) return { valid: true };
252
- const errors = validate2.errors?.map(
256
+ const errors = validate2.errors ? map(
257
+ validate2.errors,
253
258
  (e) => `${e.instancePath || "/"} ${e.message ?? "unknown error"}`
254
- );
259
+ ) : void 0;
255
260
  return { valid: false, errors };
256
261
  }
257
262
 
@@ -277,7 +282,7 @@ function readAsset(filename) {
277
282
  // src/core/config.ts
278
283
  function stripDangerousKeys(obj) {
279
284
  if (obj === null || typeof obj !== "object") return obj;
280
- if (Array.isArray(obj)) return obj.map(stripDangerousKeys);
285
+ if (isArray(obj)) return map2(obj, stripDangerousKeys);
281
286
  const cleaned = {};
282
287
  for (const [key, value] of Object.entries(obj)) {
283
288
  if (["__proto__", "constructor", "prototype"].includes(key)) continue;
@@ -351,6 +356,7 @@ async function initDefaultConfig() {
351
356
  // src/core/backup.ts
352
357
  import { readdir } from "fs/promises";
353
358
  import { basename, join as join7 } from "path";
359
+ import { filter } from "@winglet/common-utils";
354
360
  import fg from "fast-glob";
355
361
 
356
362
  // src/utils/system.ts
@@ -460,6 +466,10 @@ var logger = {
460
466
  // src/core/metadata.ts
461
467
  import { createHash } from "crypto";
462
468
  import { lstat, readFile as readFile2, readlink } from "fs/promises";
469
+ import { isString } from "@winglet/common-utils";
470
+
471
+ // src/schemas/metadata.schema.ts
472
+ import { map as map3 } from "@winglet/common-utils";
463
473
 
464
474
  // assets/schemas/metadata.schema.json
465
475
  var metadata_schema_default = {
@@ -589,14 +599,15 @@ var validate3 = ajv.compile(metadata_schema_default);
589
599
  function validateMetadata(data) {
590
600
  const valid = validate3(data);
591
601
  if (valid) return { valid: true };
592
- const errors = validate3.errors?.map(
602
+ const errors = validate3.errors ? map3(
603
+ validate3.errors,
593
604
  (e) => `${e.instancePath || "/"} ${e.message ?? "unknown error"}`
594
- );
605
+ ) : void 0;
595
606
  return { valid: false, errors };
596
607
  }
597
608
 
598
609
  // src/version.ts
599
- var VERSION = "0.0.10";
610
+ var VERSION = "0.0.12";
600
611
 
601
612
  // src/core/metadata.ts
602
613
  var METADATA_VERSION = "1.0.0";
@@ -620,7 +631,7 @@ function createMetadata(files, config) {
620
631
  };
621
632
  }
622
633
  function parseMetadata(data) {
623
- const str = typeof data === "string" ? data : data.toString("utf-8");
634
+ const str = isString(data) ? data : data.toString("utf-8");
624
635
  const parsed = JSON.parse(str);
625
636
  const result = validateMetadata(parsed);
626
637
  if (!result.valid) {
@@ -774,7 +785,8 @@ async function scanTargets(config) {
774
785
  "**/Library/**",
775
786
  "**/.cache/**",
776
787
  "**/node_modules/**",
777
- ...config.backup.exclude.filter(
788
+ ...filter(
789
+ config.backup.exclude,
778
790
  (p) => detectPatternType(p) === "glob"
779
791
  )
780
792
  ]
@@ -945,6 +957,7 @@ async function createBackup(config, options = {}) {
945
957
  // src/core/restore.ts
946
958
  import { copyFile, lstat as lstat2, readdir as readdir2, stat as stat2 } from "fs/promises";
947
959
  import { dirname as dirname2, join as join8 } from "path";
960
+ import { forEach } from "@winglet/common-utils";
948
961
  async function getBackupList(config) {
949
962
  const backupDir = config?.backup.destination ? resolveTargetPath(config.backup.destination) : getSubDir(BACKUPS_DIR);
950
963
  const exists = await fileExists(backupDir);
@@ -1049,15 +1062,26 @@ async function restoreBackup(archivePath, options = {}) {
1049
1062
  const plan = await getRestorePlan(archivePath);
1050
1063
  const restoredFiles = [];
1051
1064
  const skippedFiles = [];
1052
- const overwritePaths = plan.actions.filter((a) => a.action === "overwrite").map((a) => a.path);
1065
+ const overwritePaths = [];
1066
+ forEach(plan.actions, (a) => {
1067
+ if (a.action === "overwrite") overwritePaths.push(a.path);
1068
+ });
1053
1069
  let safetyBackupPath;
1054
1070
  if (overwritePaths.length > 0 && !options.dryRun) {
1055
1071
  safetyBackupPath = await createSafetyBackup(overwritePaths);
1056
1072
  }
1057
1073
  if (options.dryRun) {
1074
+ const restoredFiles2 = [];
1075
+ forEach(plan.actions, (a) => {
1076
+ if (a.action !== "skip") restoredFiles2.push(a.path);
1077
+ });
1078
+ const skippedFiles2 = [];
1079
+ forEach(plan.actions, (a) => {
1080
+ if (a.action === "skip") skippedFiles2.push(a.path);
1081
+ });
1058
1082
  return {
1059
- restoredFiles: plan.actions.filter((a) => a.action !== "skip").map((a) => a.path),
1060
- skippedFiles: plan.actions.filter((a) => a.action === "skip").map((a) => a.path),
1083
+ restoredFiles: restoredFiles2,
1084
+ skippedFiles: skippedFiles2,
1061
1085
  safetyBackupPath
1062
1086
  };
1063
1087
  }
@@ -1104,8 +1128,12 @@ async function restoreBackup(archivePath, options = {}) {
1104
1128
  import { exec } from "child_process";
1105
1129
  import { readFile as readFile4, readdir as readdir3 } from "fs/promises";
1106
1130
  import { join as join9 } from "path";
1131
+ import { filter as filter2, isTruthy } from "@winglet/common-utils";
1107
1132
  import YAML2 from "yaml";
1108
1133
 
1134
+ // src/schemas/template.schema.ts
1135
+ import { map as map4 } from "@winglet/common-utils";
1136
+
1109
1137
  // assets/schemas/template.schema.json
1110
1138
  var template_schema_default = {
1111
1139
  $schema: "http://json-schema.org/draft-07/schema#",
@@ -1174,9 +1202,10 @@ var validate4 = ajv.compile(template_schema_default);
1174
1202
  function validateTemplate(data) {
1175
1203
  const valid = validate4(data);
1176
1204
  if (valid) return { valid: true };
1177
- const errors = validate4.errors?.map(
1205
+ const errors = validate4.errors ? map4(
1206
+ validate4.errors,
1178
1207
  (e) => `${e.instancePath || "/"} ${e.message ?? "unknown error"}`
1179
- );
1208
+ ) : void 0;
1180
1209
  return { valid: false, errors };
1181
1210
  }
1182
1211
 
@@ -1288,7 +1317,7 @@ async function executeStep(step) {
1288
1317
  }
1289
1318
  try {
1290
1319
  const { stdout, stderr } = await execAsync(step.command);
1291
- const output = [stdout, stderr].filter(Boolean).join("\n").trim();
1320
+ const output = filter2([stdout, stderr], isTruthy).join("\n").trim();
1292
1321
  return {
1293
1322
  name: step.name,
1294
1323
  status: "success",
@@ -1299,7 +1328,7 @@ async function executeStep(step) {
1299
1328
  const error = err instanceof Error ? err : new Error(String(err));
1300
1329
  const stdout = err?.stdout ?? "";
1301
1330
  const stderr = err?.stderr ?? "";
1302
- const errorOutput = [stdout, stderr, error.message].filter(Boolean).join("\n").trim();
1331
+ const errorOutput = filter2([stdout, stderr, error.message], isTruthy).join("\n").trim();
1303
1332
  return {
1304
1333
  name: step.name,
1305
1334
  status: "failed",
@@ -144,3 +144,18 @@ export interface InitOptions {
144
144
  export interface CliOptions {
145
145
  verbose?: boolean;
146
146
  }
147
+ export interface LinkOptions {
148
+ }
149
+ export interface UnlinkOptions {
150
+ clean?: boolean;
151
+ }
152
+ export interface LinkResult {
153
+ appDir: string;
154
+ targetDir: string;
155
+ wasAlreadyLinked: boolean;
156
+ }
157
+ export interface UnlinkResult {
158
+ appDir: string;
159
+ targetDir: string;
160
+ cleaned: boolean;
161
+ }
package/dist/version.d.ts CHANGED
@@ -2,4 +2,4 @@
2
2
  * Current package version from package.json
3
3
  * Automatically synchronized during build process
4
4
  */
5
- export declare const VERSION = "0.0.10";
5
+ export declare const VERSION = "0.0.12";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lumy-pack/syncpoint",
3
- "version": "0.0.10",
3
+ "version": "0.0.12",
4
4
  "description": "CLI tool for project synchronization and scaffolding",
5
5
  "keywords": [
6
6
  "cli",
@@ -56,6 +56,8 @@
56
56
  "version:patch": "yarn version patch"
57
57
  },
58
58
  "dependencies": {
59
+ "@winglet/common-utils": "^0.11.2",
60
+ "@winglet/react-utils": "^0.11.2",
59
61
  "ajv": "^8.0.0",
60
62
  "ajv-formats": "^3.0.0",
61
63
  "commander": "^12.1.0",