@lumy-pack/syncpoint 0.0.4 → 0.0.6

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,2 @@
1
+ import { Command } from 'commander';
2
+ export declare function registerMigrateCommand(program: Command): void;
@@ -0,0 +1,11 @@
1
+ import type { MigrateResult } from '../utils/types.js';
2
+ export interface DiffResult {
3
+ added: string[][];
4
+ removed: string[][];
5
+ existing: string[][];
6
+ }
7
+ export declare function diffConfigFields(userData: unknown): DiffResult;
8
+ export declare function buildMigratedDocument(templateText: string, userData: unknown, diff: DiffResult): string;
9
+ export declare function migrateConfig(options?: {
10
+ dryRun?: boolean;
11
+ }): Promise<MigrateResult>;
package/dist/index.cjs CHANGED
@@ -126,6 +126,76 @@ function getSubDir(sub) {
126
126
  return (0, import_node_path2.join)(getAppDir(), sub);
127
127
  }
128
128
 
129
+ // assets/schemas/config.schema.json
130
+ var config_schema_default = {
131
+ $schema: "http://json-schema.org/draft-07/schema#",
132
+ title: "Syncpoint Config",
133
+ description: "Configuration for syncpoint backup tool",
134
+ type: "object",
135
+ required: [
136
+ "backup"
137
+ ],
138
+ properties: {
139
+ backup: {
140
+ type: "object",
141
+ description: "Backup configuration",
142
+ required: [
143
+ "targets",
144
+ "exclude",
145
+ "filename"
146
+ ],
147
+ properties: {
148
+ targets: {
149
+ type: "array",
150
+ description: "List of files/directories to backup. Supports literal paths (e.g. ~/.zshrc), glob patterns (e.g. ~/.config/*.conf), and regex patterns (e.g. /\\.conf$/).",
151
+ items: {
152
+ type: "string",
153
+ validPattern: true
154
+ }
155
+ },
156
+ exclude: {
157
+ type: "array",
158
+ description: "List of patterns to exclude from backup. Supports glob (e.g. **/*.swp) and regex (e.g. /\\.bak$/) patterns.",
159
+ items: {
160
+ type: "string",
161
+ validPattern: true
162
+ }
163
+ },
164
+ filename: {
165
+ type: "string",
166
+ description: "Backup archive filename pattern. Available variables: {hostname}, {datetime}.",
167
+ minLength: 1
168
+ },
169
+ destination: {
170
+ type: "string",
171
+ description: "Backup archive destination path. Default: ~/.syncpoint/backups/"
172
+ },
173
+ includeSensitiveFiles: {
174
+ type: "boolean",
175
+ description: "Include sensitive files (SSH keys, certificates, etc.) in backup. When false (default), files matching sensitive patterns (id_rsa, id_ed25519, *.pem, *.key) are automatically excluded."
176
+ }
177
+ },
178
+ additionalProperties: false
179
+ },
180
+ scripts: {
181
+ type: "object",
182
+ description: "Scripts configuration",
183
+ properties: {
184
+ includeInBackup: {
185
+ type: "boolean",
186
+ description: "Whether to include scripts/ directory in backup. Default: true."
187
+ }
188
+ },
189
+ additionalProperties: false
190
+ },
191
+ "yaml-language-server": {
192
+ type: "string",
193
+ description: "Editor directive for schema association; ignored at runtime."
194
+ }
195
+ },
196
+ additionalProperties: false
197
+ };
198
+
129
199
  // src/schemas/ajv.ts
130
200
  var import_ajv = __toESM(require("ajv"), 1);
131
201
  var import_ajv_formats = __toESM(require("ajv-formats"), 1);
@@ -231,45 +301,7 @@ ajv.addKeyword({
231
301
  });
232
302
 
233
303
  // src/schemas/config.schema.ts
234
- var configSchema = {
235
- type: "object",
236
- required: ["backup"],
237
- properties: {
238
- backup: {
239
- type: "object",
240
- required: ["targets", "exclude", "filename"],
241
- properties: {
242
- targets: {
243
- type: "array",
244
- items: { type: "string", validPattern: true }
245
- },
246
- exclude: {
247
- type: "array",
248
- items: { type: "string", validPattern: true }
249
- },
250
- filename: {
251
- type: "string",
252
- minLength: 1
253
- },
254
- destination: {
255
- type: "string"
256
- }
257
- },
258
- additionalProperties: false
259
- },
260
- scripts: {
261
- type: "object",
262
- properties: {
263
- includeInBackup: {
264
- type: "boolean"
265
- }
266
- },
267
- additionalProperties: false
268
- }
269
- },
270
- additionalProperties: false
271
- };
272
- var validate2 = ajv.compile(configSchema);
304
+ var validate2 = ajv.compile(config_schema_default);
273
305
  function validateConfig(data) {
274
306
  const valid = validate2(data);
275
307
  if (valid) return { valid: true };
@@ -485,8 +517,11 @@ var logger = {
485
517
  var import_node_crypto = require("crypto");
486
518
  var import_promises4 = require("fs/promises");
487
519
 
488
- // src/schemas/metadata.schema.ts
489
- var metadataSchema = {
520
+ // assets/schemas/metadata.schema.json
521
+ var metadata_schema_default = {
522
+ $schema: "http://json-schema.org/draft-07/schema#",
523
+ title: "Syncpoint Backup Metadata",
524
+ description: "Metadata stored inside backup archives as _metadata.json",
490
525
  type: "object",
491
526
  required: [
492
527
  "version",
@@ -499,57 +534,114 @@ var metadataSchema = {
499
534
  "summary"
500
535
  ],
501
536
  properties: {
502
- version: { type: "string" },
503
- toolVersion: { type: "string" },
504
- createdAt: { type: "string" },
505
- hostname: { type: "string" },
537
+ version: {
538
+ type: "string",
539
+ description: "Metadata schema version."
540
+ },
541
+ toolVersion: {
542
+ type: "string",
543
+ description: "Syncpoint tool version used to create the backup."
544
+ },
545
+ createdAt: {
546
+ type: "string",
547
+ description: "ISO 8601 timestamp of backup creation."
548
+ },
549
+ hostname: {
550
+ type: "string",
551
+ description: "Hostname of the machine where the backup was created."
552
+ },
506
553
  system: {
507
554
  type: "object",
555
+ description: "System information at backup time.",
508
556
  required: ["platform", "release", "arch"],
509
557
  properties: {
510
- platform: { type: "string" },
511
- release: { type: "string" },
512
- arch: { type: "string" }
558
+ platform: {
559
+ type: "string",
560
+ description: "Operating system platform (e.g. darwin, linux)."
561
+ },
562
+ release: {
563
+ type: "string",
564
+ description: "OS kernel release version."
565
+ },
566
+ arch: {
567
+ type: "string",
568
+ description: "CPU architecture (e.g. arm64, x64)."
569
+ }
513
570
  },
514
571
  additionalProperties: false
515
572
  },
516
573
  config: {
517
574
  type: "object",
575
+ description: "Backup configuration snapshot.",
518
576
  required: ["filename"],
519
577
  properties: {
520
- filename: { type: "string" },
521
- destination: { type: "string" }
578
+ filename: {
579
+ type: "string",
580
+ description: "Filename pattern used for the backup."
581
+ },
582
+ destination: {
583
+ type: "string",
584
+ description: "Custom destination path, if configured."
585
+ }
522
586
  },
523
587
  additionalProperties: false
524
588
  },
525
589
  files: {
526
590
  type: "array",
591
+ description: "List of files included in the backup.",
527
592
  items: {
528
593
  type: "object",
529
594
  required: ["path", "absolutePath", "size", "hash"],
530
595
  properties: {
531
- path: { type: "string" },
532
- absolutePath: { type: "string" },
533
- size: { type: "number", minimum: 0 },
534
- hash: { type: "string" },
535
- type: { type: "string" }
596
+ path: {
597
+ type: "string",
598
+ description: "Display path (e.g. ~/.zshrc)."
599
+ },
600
+ absolutePath: {
601
+ type: "string",
602
+ description: "Full filesystem path."
603
+ },
604
+ size: {
605
+ type: "number",
606
+ description: "File size in bytes.",
607
+ minimum: 0
608
+ },
609
+ hash: {
610
+ type: "string",
611
+ description: "SHA-256 hash of file contents."
612
+ },
613
+ type: {
614
+ type: "string",
615
+ description: "File type (e.g. symlink, directory)."
616
+ }
536
617
  },
537
618
  additionalProperties: false
538
619
  }
539
620
  },
540
621
  summary: {
541
622
  type: "object",
623
+ description: "Backup summary statistics.",
542
624
  required: ["fileCount", "totalSize"],
543
625
  properties: {
544
- fileCount: { type: "integer", minimum: 0 },
545
- totalSize: { type: "number", minimum: 0 }
626
+ fileCount: {
627
+ type: "integer",
628
+ description: "Total number of files in the backup.",
629
+ minimum: 0
630
+ },
631
+ totalSize: {
632
+ type: "number",
633
+ description: "Total size of all files in bytes.",
634
+ minimum: 0
635
+ }
546
636
  },
547
637
  additionalProperties: false
548
638
  }
549
639
  },
550
640
  additionalProperties: false
551
641
  };
552
- var validate3 = ajv.compile(metadataSchema);
642
+
643
+ // src/schemas/metadata.schema.ts
644
+ var validate3 = ajv.compile(metadata_schema_default);
553
645
  function validateMetadata(data) {
554
646
  const valid = validate3(data);
555
647
  if (valid) return { valid: true };
@@ -560,7 +652,7 @@ function validateMetadata(data) {
560
652
  }
561
653
 
562
654
  // src/version.ts
563
- var VERSION = "0.0.4";
655
+ var VERSION = "0.0.6";
564
656
 
565
657
  // src/core/metadata.ts
566
658
  var METADATA_VERSION = "1.0.0";
@@ -745,6 +837,10 @@ async function scanTargets(config) {
745
837
  });
746
838
  for (const match of allFiles) {
747
839
  if (regex.test(match) && !isExcluded(match)) {
840
+ if (!config.backup.includeSensitiveFiles && isSensitiveFile(match)) {
841
+ logger.warn(`Sensitive file excluded: ${match}`);
842
+ continue;
843
+ }
748
844
  const entry = await collectFileInfo(match, match);
749
845
  found.push(entry);
750
846
  }
@@ -773,6 +869,10 @@ async function scanTargets(config) {
773
869
  });
774
870
  for (const match of matches) {
775
871
  if (!isExcluded(match)) {
872
+ if (!config.backup.includeSensitiveFiles && isSensitiveFile(match)) {
873
+ logger.warn(`Sensitive file excluded: ${match}`);
874
+ continue;
875
+ }
776
876
  const entry = await collectFileInfo(match, match);
777
877
  found.push(entry);
778
878
  }
@@ -806,6 +906,10 @@ async function scanTargets(config) {
806
906
  });
807
907
  for (const match of matches) {
808
908
  if (!isExcluded(match)) {
909
+ if (!config.backup.includeSensitiveFiles && isSensitiveFile(match)) {
910
+ logger.warn(`Sensitive file excluded: ${match}`);
911
+ continue;
912
+ }
809
913
  const entry = await collectFileInfo(match, match);
810
914
  found.push(entry);
811
915
  }
@@ -817,15 +921,16 @@ async function scanTargets(config) {
817
921
  if (isExcluded(absPath)) {
818
922
  continue;
819
923
  }
924
+ if (!config.backup.includeSensitiveFiles && isSensitiveFile(absPath)) {
925
+ logger.warn(`Sensitive file excluded: ${target}`);
926
+ continue;
927
+ }
820
928
  const entry = await collectFileInfo(absPath, absPath);
821
929
  if (entry.size > LARGE_FILE_THRESHOLD) {
822
930
  logger.warn(
823
931
  `Large file (>${Math.round(LARGE_FILE_THRESHOLD / 1024 / 1024)}MB): ${target}`
824
932
  );
825
933
  }
826
- if (isSensitiveFile(absPath)) {
827
- logger.warn(`Sensitive file detected: ${target}`);
828
- }
829
934
  found.push(entry);
830
935
  }
831
936
  }
@@ -1057,27 +1162,61 @@ var import_promises8 = require("fs/promises");
1057
1162
  var import_node_path9 = require("path");
1058
1163
  var import_yaml2 = __toESM(require("yaml"), 1);
1059
1164
 
1060
- // src/schemas/template.schema.ts
1061
- var templateSchema = {
1165
+ // assets/schemas/template.schema.json
1166
+ var template_schema_default = {
1167
+ $schema: "http://json-schema.org/draft-07/schema#",
1168
+ title: "Syncpoint Template",
1169
+ description: "Provisioning template for syncpoint",
1062
1170
  type: "object",
1063
1171
  required: ["name", "steps"],
1064
1172
  properties: {
1065
- name: { type: "string", minLength: 1 },
1066
- description: { type: "string" },
1067
- backup: { type: "string" },
1068
- sudo: { type: "boolean" },
1173
+ name: {
1174
+ type: "string",
1175
+ description: "Template name.",
1176
+ minLength: 1
1177
+ },
1178
+ description: {
1179
+ type: "string",
1180
+ description: "Template description."
1181
+ },
1182
+ backup: {
1183
+ type: "string",
1184
+ description: "Backup name to restore automatically after provisioning."
1185
+ },
1186
+ sudo: {
1187
+ type: "boolean",
1188
+ description: "Whether sudo privilege is required. If true, requests sudo authentication before execution."
1189
+ },
1069
1190
  steps: {
1070
1191
  type: "array",
1192
+ description: "List of provisioning steps. At least 1 step required.",
1071
1193
  minItems: 1,
1072
1194
  items: {
1073
1195
  type: "object",
1074
1196
  required: ["name", "command"],
1075
1197
  properties: {
1076
- name: { type: "string", minLength: 1 },
1077
- description: { type: "string" },
1078
- command: { type: "string", minLength: 1 },
1079
- skip_if: { type: "string" },
1080
- continue_on_error: { type: "boolean" }
1198
+ name: {
1199
+ type: "string",
1200
+ description: "Step name.",
1201
+ minLength: 1
1202
+ },
1203
+ description: {
1204
+ type: "string",
1205
+ description: "Step description."
1206
+ },
1207
+ command: {
1208
+ type: "string",
1209
+ description: "Shell command to execute.",
1210
+ minLength: 1
1211
+ },
1212
+ skip_if: {
1213
+ type: "string",
1214
+ description: "Skip this step if this command exits with code 0."
1215
+ },
1216
+ continue_on_error: {
1217
+ type: "boolean",
1218
+ description: "Continue to next step even if this fails. Default: false."
1219
+ }
1081
1220
  },
1082
1221
  additionalProperties: false
1083
1222
  }
@@ -1085,7 +1224,9 @@ var templateSchema = {
1085
1224
  },
1086
1225
  additionalProperties: false
1087
1226
  };
1088
- var validate4 = ajv.compile(templateSchema);
1227
+
1228
+ // src/schemas/template.schema.ts
1229
+ var validate4 = ajv.compile(template_schema_default);
1089
1230
  function validateTemplate(data) {
1090
1231
  const valid = validate4(data);
1091
1232
  if (valid) return { valid: true };