@nmakarov/cli-toolkit 0.16.0 → 0.18.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-runner.cjs +5006 -0
- package/dist/cli-runner.cjs.map +1 -0
- package/dist/cli-runner.js +4989 -0
- package/dist/cli-runner.js.map +1 -0
- 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 +1369 -9
- package/dist/http-client2.cjs.map +1 -1
- package/dist/http-client2.js +1359 -9
- package/dist/http-client2.js.map +1 -1
- package/dist/index.cjs +1244 -21
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +1224 -20
- package/dist/index.js.map +1 -1
- package/dist/init.cjs +9 -6
- package/dist/init.cjs.map +1 -1
- package/dist/init.js +9 -6
- 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/tasks.cjs +2295 -0
- package/dist/tasks.cjs.map +1 -0
- package/dist/tasks.js +2240 -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 +11 -3
package/dist/filedatabase.cjs
CHANGED
|
@@ -366,7 +366,7 @@ var FileDatabase = class _FileDatabase {
|
|
|
366
366
|
const versions = await this.getVersions();
|
|
367
367
|
while (versions.length > this.maxVersions) {
|
|
368
368
|
const versionToDelete = import_path3.default.resolve(this.getDestinationPath(), versions.shift());
|
|
369
|
-
this.logger.
|
|
369
|
+
this.logger.silly?.(`[FileDatabase] Deleting old version: ${versionToDelete}`);
|
|
370
370
|
await import_fs3.default.promises.rm(versionToDelete, { recursive: true, force: true });
|
|
371
371
|
}
|
|
372
372
|
return versionName;
|
|
@@ -644,7 +644,7 @@ var FileDatabase = class _FileDatabase {
|
|
|
644
644
|
};
|
|
645
645
|
this.metadata.files.push(fileEntry);
|
|
646
646
|
this.lastFileData = null;
|
|
647
|
-
this.logger.
|
|
647
|
+
this.logger.silly?.(`[FileDatabase] Created new file: ${fileEntry.fileName}, fileNumber: ${this.currentFileNumber}`);
|
|
648
648
|
}
|
|
649
649
|
/**
|
|
650
650
|
* Figure out what data to write and which file to use (for pagination)
|
|
@@ -677,7 +677,7 @@ var FileDatabase = class _FileDatabase {
|
|
|
677
677
|
const filesBeforeCreate = this.metadata.files.length;
|
|
678
678
|
this.makeNewFile();
|
|
679
679
|
newlyCreatedFileIndex = filesBeforeCreate;
|
|
680
|
-
this.logger.
|
|
680
|
+
this.logger.silly?.(`[FileDatabase] Creating new file for unique custom metadata combination, fileNumber: ${this.currentFileNumber}`);
|
|
681
681
|
} else if (this.metadata.files.length === 0) {
|
|
682
682
|
this.makeNewFile();
|
|
683
683
|
}
|
|
@@ -726,7 +726,7 @@ var FileDatabase = class _FileDatabase {
|
|
|
726
726
|
dataLeftOver = null;
|
|
727
727
|
}
|
|
728
728
|
const fileName = this.metadata.files[this.metadata.files.length - 1].fileName;
|
|
729
|
-
this.logger.
|
|
729
|
+
this.logger.silly?.(
|
|
730
730
|
`[FileDatabase] figureOutDataAndFileToWrite: filename=${fileName}, forceNewFile=${forceNewFile}, targetFileIndex=${targetFileIndex}, dataToWrite.length=${Array.isArray(dataToWrite) ? dataToWrite.length : "N/A"}, lastFileRecordsCount=${lastFileRecordsCount}`
|
|
731
731
|
);
|
|
732
732
|
return { dataToWrite, dataLeftOver, fileName };
|
|
@@ -781,7 +781,7 @@ var FileDatabase = class _FileDatabase {
|
|
|
781
781
|
this.metadata.modifiedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
782
782
|
this.metadata.dataType = detectDataType(dataToWrite);
|
|
783
783
|
this.metadata.totalRecords = this.metadata.files.reduce((sum, file) => sum + (file.recordsCount || 0), 0);
|
|
784
|
-
this.logger.
|
|
784
|
+
this.logger.silly?.(
|
|
785
785
|
`[FileDatabase] Updated metadata for file ${currentFile.fileName}: recordsCount=${recordsCount}, totalRecords=${this.metadata.totalRecords}`
|
|
786
786
|
);
|
|
787
787
|
}
|
|
@@ -805,7 +805,7 @@ var FileDatabase = class _FileDatabase {
|
|
|
805
805
|
}
|
|
806
806
|
try {
|
|
807
807
|
await import_fs3.default.promises.writeFile(filePath, serializedData, "utf8");
|
|
808
|
-
this.logger.
|
|
808
|
+
this.logger.silly?.(`[FileDatabase] Wrote ${bytesToHumanReadable(requiredBytes)} to ${filePath}`);
|
|
809
809
|
} catch (error) {
|
|
810
810
|
throw new FileDatabaseError(`Failed to write file ${filePath}: ${error.message}`);
|
|
811
811
|
}
|
|
@@ -887,7 +887,8 @@ var FileDatabase = class _FileDatabase {
|
|
|
887
887
|
this.useMetadata = format.hasMetadata;
|
|
888
888
|
}
|
|
889
889
|
if (this.useMetadata) {
|
|
890
|
-
const
|
|
890
|
+
const destPath = this.getDestinationPath();
|
|
891
|
+
const metadataPath = import_path3.default.join(destPath, "metadata.json");
|
|
891
892
|
if (import_fs3.default.existsSync(metadataPath)) {
|
|
892
893
|
try {
|
|
893
894
|
const rawData = await import_fs3.default.promises.readFile(metadataPath, "utf8");
|
|
@@ -901,7 +902,9 @@ var FileDatabase = class _FileDatabase {
|
|
|
901
902
|
throw new FileDatabaseError(`Failed to read metadata: ${e.message}`);
|
|
902
903
|
}
|
|
903
904
|
} else {
|
|
904
|
-
throw new FileDatabaseError(
|
|
905
|
+
throw new FileDatabaseError(
|
|
906
|
+
`[FileDatabase] No metadata found in non-versioned mode. Looked for: ${metadataPath} (table path: ${destPath})`
|
|
907
|
+
);
|
|
905
908
|
}
|
|
906
909
|
} else {
|
|
907
910
|
this.metadata = await this.figureMetadataFromVersionFiles("");
|
|
@@ -918,6 +921,13 @@ var FileDatabase = class _FileDatabase {
|
|
|
918
921
|
* Write data to the file database
|
|
919
922
|
*/
|
|
920
923
|
async write(data, options = {}) {
|
|
924
|
+
if (options.filename) {
|
|
925
|
+
const destPath2 = this.getDestinationPath();
|
|
926
|
+
await ensurePath(destPath2);
|
|
927
|
+
const filePath = import_path3.default.join(destPath2, options.filename);
|
|
928
|
+
await this.safeWrite(filePath, data);
|
|
929
|
+
return;
|
|
930
|
+
}
|
|
921
931
|
if (options.forceNewVersion && !this.versioned) {
|
|
922
932
|
throw new FileDatabaseError("Cannot use forceNewVersion in non-versioned mode");
|
|
923
933
|
}
|
|
@@ -941,17 +951,17 @@ var FileDatabase = class _FileDatabase {
|
|
|
941
951
|
});
|
|
942
952
|
if (matches) {
|
|
943
953
|
targetFileIndex = i;
|
|
944
|
-
this.logger.
|
|
954
|
+
this.logger.silly?.(`[FileDatabase] Found existing file with matching custom metadata: ${fileEntry.fileName}, metadata: ${JSON.stringify(options.customMetadata)}`);
|
|
945
955
|
break;
|
|
946
956
|
} else {
|
|
947
|
-
this.logger.
|
|
957
|
+
this.logger.silly?.(`[FileDatabase] File ${fileEntry.fileName} does not match custom metadata: ${JSON.stringify(options.customMetadata)}`);
|
|
948
958
|
}
|
|
949
959
|
}
|
|
950
960
|
if (targetFileIndex === null) {
|
|
951
|
-
this.logger.
|
|
961
|
+
this.logger.silly?.(`[FileDatabase] No existing file found with custom metadata: ${JSON.stringify(options.customMetadata)}, will create new file`);
|
|
952
962
|
}
|
|
953
963
|
} else {
|
|
954
|
-
this.logger.
|
|
964
|
+
this.logger.silly?.(`[FileDatabase] No custom metadata provided, will create new file`);
|
|
955
965
|
}
|
|
956
966
|
if (targetFileIndex !== null) {
|
|
957
967
|
const targetFile = this.metadata.files[targetFileIndex];
|
|
@@ -980,7 +990,17 @@ var FileDatabase = class _FileDatabase {
|
|
|
980
990
|
* Read data from the file database
|
|
981
991
|
*/
|
|
982
992
|
async read(options = {}) {
|
|
983
|
-
const { version, nextPage = false, pageSize } = options;
|
|
993
|
+
const { version, nextPage = false, pageSize, filename } = options;
|
|
994
|
+
if (filename) {
|
|
995
|
+
const destPath = this.getDestinationPath(version);
|
|
996
|
+
const filePath = import_path3.default.join(destPath, filename);
|
|
997
|
+
try {
|
|
998
|
+
const rawData = await import_fs3.default.promises.readFile(filePath, "utf8");
|
|
999
|
+
return JSON.parse(rawData);
|
|
1000
|
+
} catch (error) {
|
|
1001
|
+
throw new FileDatabaseError(`Failed to read file ${filename}: ${error.message}`);
|
|
1002
|
+
}
|
|
1003
|
+
}
|
|
984
1004
|
await this.prepare({ read: true, version });
|
|
985
1005
|
const isNonPaginatedData = this.metadata.dataType === "text" || this.metadata.dataType === "xml" || this.metadata.dataType === "json-object";
|
|
986
1006
|
if (isNonPaginatedData) {
|
|
@@ -1061,6 +1081,67 @@ var FileDatabase = class _FileDatabase {
|
|
|
1061
1081
|
this.currentRecord = 0;
|
|
1062
1082
|
this.hasReadFirstPage = false;
|
|
1063
1083
|
}
|
|
1084
|
+
/**
|
|
1085
|
+
* List filenames in the table directory.
|
|
1086
|
+
* For catalog/key-value usage (files written with { filename }).
|
|
1087
|
+
* Returns data file names (.json, .txt, .xml) excluding metadata.json.
|
|
1088
|
+
*/
|
|
1089
|
+
async listFilenames() {
|
|
1090
|
+
const destPath = this.versioned && this.currentVersion ? import_path3.default.join(this.getDestinationPath(), this.currentVersion) : this.getDestinationPath();
|
|
1091
|
+
try {
|
|
1092
|
+
const entries = await import_fs3.default.promises.readdir(destPath, { withFileTypes: true });
|
|
1093
|
+
return entries.filter((e) => e.isFile() && e.name !== "metadata.json" && /\.(json|txt|xml)$/i.test(e.name)).map((e) => e.name);
|
|
1094
|
+
} catch (err) {
|
|
1095
|
+
if (err?.code === "ENOENT") return [];
|
|
1096
|
+
throw new FileDatabaseError(`Failed to list files: ${err.message}`);
|
|
1097
|
+
}
|
|
1098
|
+
}
|
|
1099
|
+
/**
|
|
1100
|
+
* Remove a file from the table directory (catalog mode).
|
|
1101
|
+
* Use with listFilenames() to manage individual files.
|
|
1102
|
+
*/
|
|
1103
|
+
async removeFile(filename) {
|
|
1104
|
+
const destPath = this.versioned && this.currentVersion ? import_path3.default.join(this.getDestinationPath(), this.currentVersion) : this.getDestinationPath();
|
|
1105
|
+
const filePath = import_path3.default.join(destPath, filename);
|
|
1106
|
+
try {
|
|
1107
|
+
await import_fs3.default.promises.unlink(filePath);
|
|
1108
|
+
} catch (err) {
|
|
1109
|
+
if (err?.code === "ENOENT") return;
|
|
1110
|
+
throw new FileDatabaseError(`Failed to remove file ${filename}: ${err.message}`);
|
|
1111
|
+
}
|
|
1112
|
+
}
|
|
1113
|
+
/**
|
|
1114
|
+
* Remove a file and its metadata entry (non-versioned mode with useMetadata).
|
|
1115
|
+
* Use with findData() to get fileName, then call removeFileEntry to delete.
|
|
1116
|
+
*/
|
|
1117
|
+
async removeFileEntry(filename) {
|
|
1118
|
+
if (this.versioned) {
|
|
1119
|
+
throw new FileDatabaseError("removeFileEntry is only supported in non-versioned mode");
|
|
1120
|
+
}
|
|
1121
|
+
await this.prepare({ read: true });
|
|
1122
|
+
const idx = this.metadata.files.findIndex((f) => f.fileName === filename);
|
|
1123
|
+
if (idx === -1) {
|
|
1124
|
+
throw new FileDatabaseError(`File entry ${filename} not found in metadata`);
|
|
1125
|
+
}
|
|
1126
|
+
const entry = this.metadata.files[idx];
|
|
1127
|
+
const recordsCount = entry.recordsCount || 0;
|
|
1128
|
+
this.metadata.files.splice(idx, 1);
|
|
1129
|
+
this.metadata.totalRecords = Math.max(0, (this.metadata.totalRecords || 0) - recordsCount);
|
|
1130
|
+
const destPath = this.getDestinationPath();
|
|
1131
|
+
const filePath = import_path3.default.join(destPath, filename);
|
|
1132
|
+
try {
|
|
1133
|
+
await import_fs3.default.promises.unlink(filePath);
|
|
1134
|
+
} catch (err) {
|
|
1135
|
+
if (err?.code === "ENOENT") {
|
|
1136
|
+
this.logger.warn?.(`[FileDatabase] File ${filename} already missing on disk`);
|
|
1137
|
+
} else {
|
|
1138
|
+
throw new FileDatabaseError(`Failed to remove file ${filename}: ${err.message}`);
|
|
1139
|
+
}
|
|
1140
|
+
}
|
|
1141
|
+
if (this.useMetadata) {
|
|
1142
|
+
await this.saveVersionMetadata(this.metadata);
|
|
1143
|
+
}
|
|
1144
|
+
}
|
|
1064
1145
|
/**
|
|
1065
1146
|
* Set file-level synopsis calculation function
|
|
1066
1147
|
*/
|