@nmakarov/cli-toolkit 0.16.0 → 0.21.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/README.md +9 -0
- package/dist/cli-runner.cjs +5335 -0
- package/dist/cli-runner.cjs.map +1 -0
- package/dist/cli-runner.js +5318 -0
- package/dist/cli-runner.js.map +1 -0
- package/dist/db.cjs +1 -1
- package/dist/db.cjs.map +1 -1
- package/dist/db.js +1 -1
- package/dist/db.js.map +1 -1
- package/dist/filedatabase.cjs +94 -13
- package/dist/filedatabase.cjs.map +1 -1
- package/dist/filedatabase.js +94 -13
- package/dist/filedatabase.js.map +1 -1
- package/dist/http-client2.cjs +1375 -11
- package/dist/http-client2.cjs.map +1 -1
- package/dist/http-client2.js +1365 -11
- package/dist/http-client2.js.map +1 -1
- package/dist/index.cjs +1639 -30
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +1608 -29
- package/dist/index.js.map +1 -1
- package/dist/init.cjs +25 -7
- package/dist/init.cjs.map +1 -1
- package/dist/init.js +25 -7
- package/dist/init.js.map +1 -1
- package/dist/logger.cjs +9 -6
- package/dist/logger.cjs.map +1 -1
- package/dist/logger.js +9 -6
- package/dist/logger.js.map +1 -1
- package/dist/mock-server.cjs +192 -343
- package/dist/mock-server.cjs.map +1 -1
- package/dist/mock-server.js +190 -343
- package/dist/mock-server.js.map +1 -1
- package/dist/params.cjs +16 -1
- package/dist/params.cjs.map +1 -1
- package/dist/params.js +16 -1
- package/dist/params.js.map +1 -1
- package/dist/tasks.cjs +2666 -0
- package/dist/tasks.cjs.map +1 -0
- package/dist/tasks.js +2600 -0
- package/dist/tasks.js.map +1 -0
- package/dist/utils.cjs +15 -2
- package/dist/utils.cjs.map +1 -1
- package/dist/utils.js +12 -1
- package/dist/utils.js.map +1 -1
- package/package.json +20 -5
- package/scripts/ssm/parse-cli.ts +35 -0
- package/scripts/ssm/ssm-admin.ts +151 -0
- package/scripts/ssm/ssm-pull.ts +150 -0
package/dist/filedatabase.js
CHANGED
|
@@ -325,7 +325,7 @@ var FileDatabase = class _FileDatabase {
|
|
|
325
325
|
const versions = await this.getVersions();
|
|
326
326
|
while (versions.length > this.maxVersions) {
|
|
327
327
|
const versionToDelete = path3.resolve(this.getDestinationPath(), versions.shift());
|
|
328
|
-
this.logger.
|
|
328
|
+
this.logger.silly?.(`[FileDatabase] Deleting old version: ${versionToDelete}`);
|
|
329
329
|
await fs3.promises.rm(versionToDelete, { recursive: true, force: true });
|
|
330
330
|
}
|
|
331
331
|
return versionName;
|
|
@@ -603,7 +603,7 @@ var FileDatabase = class _FileDatabase {
|
|
|
603
603
|
};
|
|
604
604
|
this.metadata.files.push(fileEntry);
|
|
605
605
|
this.lastFileData = null;
|
|
606
|
-
this.logger.
|
|
606
|
+
this.logger.silly?.(`[FileDatabase] Created new file: ${fileEntry.fileName}, fileNumber: ${this.currentFileNumber}`);
|
|
607
607
|
}
|
|
608
608
|
/**
|
|
609
609
|
* Figure out what data to write and which file to use (for pagination)
|
|
@@ -636,7 +636,7 @@ var FileDatabase = class _FileDatabase {
|
|
|
636
636
|
const filesBeforeCreate = this.metadata.files.length;
|
|
637
637
|
this.makeNewFile();
|
|
638
638
|
newlyCreatedFileIndex = filesBeforeCreate;
|
|
639
|
-
this.logger.
|
|
639
|
+
this.logger.silly?.(`[FileDatabase] Creating new file for unique custom metadata combination, fileNumber: ${this.currentFileNumber}`);
|
|
640
640
|
} else if (this.metadata.files.length === 0) {
|
|
641
641
|
this.makeNewFile();
|
|
642
642
|
}
|
|
@@ -685,7 +685,7 @@ var FileDatabase = class _FileDatabase {
|
|
|
685
685
|
dataLeftOver = null;
|
|
686
686
|
}
|
|
687
687
|
const fileName = this.metadata.files[this.metadata.files.length - 1].fileName;
|
|
688
|
-
this.logger.
|
|
688
|
+
this.logger.silly?.(
|
|
689
689
|
`[FileDatabase] figureOutDataAndFileToWrite: filename=${fileName}, forceNewFile=${forceNewFile}, targetFileIndex=${targetFileIndex}, dataToWrite.length=${Array.isArray(dataToWrite) ? dataToWrite.length : "N/A"}, lastFileRecordsCount=${lastFileRecordsCount}`
|
|
690
690
|
);
|
|
691
691
|
return { dataToWrite, dataLeftOver, fileName };
|
|
@@ -740,7 +740,7 @@ var FileDatabase = class _FileDatabase {
|
|
|
740
740
|
this.metadata.modifiedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
741
741
|
this.metadata.dataType = detectDataType(dataToWrite);
|
|
742
742
|
this.metadata.totalRecords = this.metadata.files.reduce((sum, file) => sum + (file.recordsCount || 0), 0);
|
|
743
|
-
this.logger.
|
|
743
|
+
this.logger.silly?.(
|
|
744
744
|
`[FileDatabase] Updated metadata for file ${currentFile.fileName}: recordsCount=${recordsCount}, totalRecords=${this.metadata.totalRecords}`
|
|
745
745
|
);
|
|
746
746
|
}
|
|
@@ -764,7 +764,7 @@ var FileDatabase = class _FileDatabase {
|
|
|
764
764
|
}
|
|
765
765
|
try {
|
|
766
766
|
await fs3.promises.writeFile(filePath, serializedData, "utf8");
|
|
767
|
-
this.logger.
|
|
767
|
+
this.logger.silly?.(`[FileDatabase] Wrote ${bytesToHumanReadable(requiredBytes)} to ${filePath}`);
|
|
768
768
|
} catch (error) {
|
|
769
769
|
throw new FileDatabaseError(`Failed to write file ${filePath}: ${error.message}`);
|
|
770
770
|
}
|
|
@@ -846,7 +846,8 @@ var FileDatabase = class _FileDatabase {
|
|
|
846
846
|
this.useMetadata = format.hasMetadata;
|
|
847
847
|
}
|
|
848
848
|
if (this.useMetadata) {
|
|
849
|
-
const
|
|
849
|
+
const destPath = this.getDestinationPath();
|
|
850
|
+
const metadataPath = path3.join(destPath, "metadata.json");
|
|
850
851
|
if (fs3.existsSync(metadataPath)) {
|
|
851
852
|
try {
|
|
852
853
|
const rawData = await fs3.promises.readFile(metadataPath, "utf8");
|
|
@@ -860,7 +861,9 @@ var FileDatabase = class _FileDatabase {
|
|
|
860
861
|
throw new FileDatabaseError(`Failed to read metadata: ${e.message}`);
|
|
861
862
|
}
|
|
862
863
|
} else {
|
|
863
|
-
throw new FileDatabaseError(
|
|
864
|
+
throw new FileDatabaseError(
|
|
865
|
+
`[FileDatabase] No metadata found in non-versioned mode. Looked for: ${metadataPath} (table path: ${destPath})`
|
|
866
|
+
);
|
|
864
867
|
}
|
|
865
868
|
} else {
|
|
866
869
|
this.metadata = await this.figureMetadataFromVersionFiles("");
|
|
@@ -877,6 +880,13 @@ var FileDatabase = class _FileDatabase {
|
|
|
877
880
|
* Write data to the file database
|
|
878
881
|
*/
|
|
879
882
|
async write(data, options = {}) {
|
|
883
|
+
if (options.filename) {
|
|
884
|
+
const destPath2 = this.getDestinationPath();
|
|
885
|
+
await ensurePath(destPath2);
|
|
886
|
+
const filePath = path3.join(destPath2, options.filename);
|
|
887
|
+
await this.safeWrite(filePath, data);
|
|
888
|
+
return;
|
|
889
|
+
}
|
|
880
890
|
if (options.forceNewVersion && !this.versioned) {
|
|
881
891
|
throw new FileDatabaseError("Cannot use forceNewVersion in non-versioned mode");
|
|
882
892
|
}
|
|
@@ -900,17 +910,17 @@ var FileDatabase = class _FileDatabase {
|
|
|
900
910
|
});
|
|
901
911
|
if (matches) {
|
|
902
912
|
targetFileIndex = i;
|
|
903
|
-
this.logger.
|
|
913
|
+
this.logger.silly?.(`[FileDatabase] Found existing file with matching custom metadata: ${fileEntry.fileName}, metadata: ${JSON.stringify(options.customMetadata)}`);
|
|
904
914
|
break;
|
|
905
915
|
} else {
|
|
906
|
-
this.logger.
|
|
916
|
+
this.logger.silly?.(`[FileDatabase] File ${fileEntry.fileName} does not match custom metadata: ${JSON.stringify(options.customMetadata)}`);
|
|
907
917
|
}
|
|
908
918
|
}
|
|
909
919
|
if (targetFileIndex === null) {
|
|
910
|
-
this.logger.
|
|
920
|
+
this.logger.silly?.(`[FileDatabase] No existing file found with custom metadata: ${JSON.stringify(options.customMetadata)}, will create new file`);
|
|
911
921
|
}
|
|
912
922
|
} else {
|
|
913
|
-
this.logger.
|
|
923
|
+
this.logger.silly?.(`[FileDatabase] No custom metadata provided, will create new file`);
|
|
914
924
|
}
|
|
915
925
|
if (targetFileIndex !== null) {
|
|
916
926
|
const targetFile = this.metadata.files[targetFileIndex];
|
|
@@ -939,7 +949,17 @@ var FileDatabase = class _FileDatabase {
|
|
|
939
949
|
* Read data from the file database
|
|
940
950
|
*/
|
|
941
951
|
async read(options = {}) {
|
|
942
|
-
const { version, nextPage = false, pageSize } = options;
|
|
952
|
+
const { version, nextPage = false, pageSize, filename } = options;
|
|
953
|
+
if (filename) {
|
|
954
|
+
const destPath = this.getDestinationPath(version);
|
|
955
|
+
const filePath = path3.join(destPath, filename);
|
|
956
|
+
try {
|
|
957
|
+
const rawData = await fs3.promises.readFile(filePath, "utf8");
|
|
958
|
+
return JSON.parse(rawData);
|
|
959
|
+
} catch (error) {
|
|
960
|
+
throw new FileDatabaseError(`Failed to read file ${filename}: ${error.message}`);
|
|
961
|
+
}
|
|
962
|
+
}
|
|
943
963
|
await this.prepare({ read: true, version });
|
|
944
964
|
const isNonPaginatedData = this.metadata.dataType === "text" || this.metadata.dataType === "xml" || this.metadata.dataType === "json-object";
|
|
945
965
|
if (isNonPaginatedData) {
|
|
@@ -1020,6 +1040,67 @@ var FileDatabase = class _FileDatabase {
|
|
|
1020
1040
|
this.currentRecord = 0;
|
|
1021
1041
|
this.hasReadFirstPage = false;
|
|
1022
1042
|
}
|
|
1043
|
+
/**
|
|
1044
|
+
* List filenames in the table directory.
|
|
1045
|
+
* For catalog/key-value usage (files written with { filename }).
|
|
1046
|
+
* Returns data file names (.json, .txt, .xml) excluding metadata.json.
|
|
1047
|
+
*/
|
|
1048
|
+
async listFilenames() {
|
|
1049
|
+
const destPath = this.versioned && this.currentVersion ? path3.join(this.getDestinationPath(), this.currentVersion) : this.getDestinationPath();
|
|
1050
|
+
try {
|
|
1051
|
+
const entries = await fs3.promises.readdir(destPath, { withFileTypes: true });
|
|
1052
|
+
return entries.filter((e) => e.isFile() && e.name !== "metadata.json" && /\.(json|txt|xml)$/i.test(e.name)).map((e) => e.name);
|
|
1053
|
+
} catch (err) {
|
|
1054
|
+
if (err?.code === "ENOENT") return [];
|
|
1055
|
+
throw new FileDatabaseError(`Failed to list files: ${err.message}`);
|
|
1056
|
+
}
|
|
1057
|
+
}
|
|
1058
|
+
/**
|
|
1059
|
+
* Remove a file from the table directory (catalog mode).
|
|
1060
|
+
* Use with listFilenames() to manage individual files.
|
|
1061
|
+
*/
|
|
1062
|
+
async removeFile(filename) {
|
|
1063
|
+
const destPath = this.versioned && this.currentVersion ? path3.join(this.getDestinationPath(), this.currentVersion) : this.getDestinationPath();
|
|
1064
|
+
const filePath = path3.join(destPath, filename);
|
|
1065
|
+
try {
|
|
1066
|
+
await fs3.promises.unlink(filePath);
|
|
1067
|
+
} catch (err) {
|
|
1068
|
+
if (err?.code === "ENOENT") return;
|
|
1069
|
+
throw new FileDatabaseError(`Failed to remove file ${filename}: ${err.message}`);
|
|
1070
|
+
}
|
|
1071
|
+
}
|
|
1072
|
+
/**
|
|
1073
|
+
* Remove a file and its metadata entry (non-versioned mode with useMetadata).
|
|
1074
|
+
* Use with findData() to get fileName, then call removeFileEntry to delete.
|
|
1075
|
+
*/
|
|
1076
|
+
async removeFileEntry(filename) {
|
|
1077
|
+
if (this.versioned) {
|
|
1078
|
+
throw new FileDatabaseError("removeFileEntry is only supported in non-versioned mode");
|
|
1079
|
+
}
|
|
1080
|
+
await this.prepare({ read: true });
|
|
1081
|
+
const idx = this.metadata.files.findIndex((f) => f.fileName === filename);
|
|
1082
|
+
if (idx === -1) {
|
|
1083
|
+
throw new FileDatabaseError(`File entry ${filename} not found in metadata`);
|
|
1084
|
+
}
|
|
1085
|
+
const entry = this.metadata.files[idx];
|
|
1086
|
+
const recordsCount = entry.recordsCount || 0;
|
|
1087
|
+
this.metadata.files.splice(idx, 1);
|
|
1088
|
+
this.metadata.totalRecords = Math.max(0, (this.metadata.totalRecords || 0) - recordsCount);
|
|
1089
|
+
const destPath = this.getDestinationPath();
|
|
1090
|
+
const filePath = path3.join(destPath, filename);
|
|
1091
|
+
try {
|
|
1092
|
+
await fs3.promises.unlink(filePath);
|
|
1093
|
+
} catch (err) {
|
|
1094
|
+
if (err?.code === "ENOENT") {
|
|
1095
|
+
this.logger.warn?.(`[FileDatabase] File ${filename} already missing on disk`);
|
|
1096
|
+
} else {
|
|
1097
|
+
throw new FileDatabaseError(`Failed to remove file ${filename}: ${err.message}`);
|
|
1098
|
+
}
|
|
1099
|
+
}
|
|
1100
|
+
if (this.useMetadata) {
|
|
1101
|
+
await this.saveVersionMetadata(this.metadata);
|
|
1102
|
+
}
|
|
1103
|
+
}
|
|
1023
1104
|
/**
|
|
1024
1105
|
* Set file-level synopsis calculation function
|
|
1025
1106
|
*/
|