ts-runtime-validation 1.8.2 → 1.8.3
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/SchemaGenerator.js
CHANGED
|
@@ -43,10 +43,42 @@ class SchemaGenerator {
|
|
|
43
43
|
console.log(`Found ${files.length} schema file(s)`);
|
|
44
44
|
files.forEach(file => console.log(` - ${file.path}`));
|
|
45
45
|
}
|
|
46
|
+
// Separate changed and unchanged files when caching is enabled
|
|
47
|
+
const cacheEnabled = this.options.cache || false;
|
|
48
|
+
let filesToProcess;
|
|
49
|
+
const cachedSchemas = new Map();
|
|
50
|
+
if (cacheEnabled) {
|
|
51
|
+
filesToProcess = files.filter(f => f.changed !== false);
|
|
52
|
+
const unchangedFiles = files.filter(f => f.changed === false);
|
|
53
|
+
for (const file of unchangedFiles) {
|
|
54
|
+
const cached = this.fileDiscovery.getCachedSchema(file.path);
|
|
55
|
+
if (cached) {
|
|
56
|
+
cachedSchemas.set(file.path, cached);
|
|
57
|
+
}
|
|
58
|
+
else {
|
|
59
|
+
// No cached schema available, must reprocess
|
|
60
|
+
filesToProcess.push(file);
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
if (this.options.verbose) {
|
|
64
|
+
console.log(`Cache: ${cachedSchemas.size} unchanged, ${filesToProcess.length} to process`);
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
else {
|
|
68
|
+
filesToProcess = files;
|
|
69
|
+
}
|
|
46
70
|
// Process schemas
|
|
47
71
|
this.progressReporter.update(1, "Processing TypeScript files...");
|
|
48
|
-
this.progressReporter.options.total =
|
|
49
|
-
const
|
|
72
|
+
this.progressReporter.options.total = filesToProcess.length + 4; // files + 4 generation steps
|
|
73
|
+
const processedSchemas = filesToProcess.length > 0
|
|
74
|
+
? yield this.schemaProcessor.processFiles(filesToProcess)
|
|
75
|
+
: new Map();
|
|
76
|
+
// Merge processed and cached schemas
|
|
77
|
+
const schemaMap = new Map([...cachedSchemas, ...processedSchemas]);
|
|
78
|
+
// Save all schemas to cache for next run
|
|
79
|
+
if (cacheEnabled) {
|
|
80
|
+
yield this.fileDiscovery.saveSchemasToCache(schemaMap);
|
|
81
|
+
}
|
|
50
82
|
if (schemaMap.size === 0) {
|
|
51
83
|
console.log("No types found to generate schemas for");
|
|
52
84
|
return;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SchemaGenerator.js","sourceRoot":"","sources":["../src/SchemaGenerator.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;AACA,gDAAwB;AACxB,
|
|
1
|
+
{"version":3,"file":"SchemaGenerator.js","sourceRoot":"","sources":["../src/SchemaGenerator.ts"],"names":[],"mappings":"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"}
|
|
@@ -23,7 +23,10 @@ class FileDiscovery {
|
|
|
23
23
|
constructor(options) {
|
|
24
24
|
this.options = options;
|
|
25
25
|
this.fileCache = new Map();
|
|
26
|
-
this.
|
|
26
|
+
this.schemaCache = new Map();
|
|
27
|
+
const cacheDir = options.cachePath || ".ts-runtime-validation-cache";
|
|
28
|
+
this.cacheFile = path_1.default.join(cacheDir, "file-hashes.json");
|
|
29
|
+
this.schemaCacheFile = path_1.default.join(cacheDir, "schema-cache.json");
|
|
27
30
|
if (options.cacheEnabled) {
|
|
28
31
|
this.loadCache();
|
|
29
32
|
}
|
|
@@ -64,10 +67,12 @@ class FileDiscovery {
|
|
|
64
67
|
const enrichedFiles = yield Promise.all(files.map((filePath) => __awaiter(this, void 0, void 0, function* () {
|
|
65
68
|
const stats = yield fs_1.default.promises.stat(filePath);
|
|
66
69
|
const hash = yield this.getFileHash(filePath);
|
|
70
|
+
const cachedHash = this.fileCache.get(filePath);
|
|
67
71
|
return {
|
|
68
72
|
path: filePath,
|
|
69
73
|
hash,
|
|
70
|
-
lastModified: stats.mtime
|
|
74
|
+
lastModified: stats.mtime,
|
|
75
|
+
changed: cachedHash !== hash
|
|
71
76
|
};
|
|
72
77
|
})));
|
|
73
78
|
yield this.saveCache(enrichedFiles);
|
|
@@ -84,16 +89,38 @@ class FileDiscovery {
|
|
|
84
89
|
const cachedHash = this.fileCache.get(filePath);
|
|
85
90
|
return cachedHash !== currentHash;
|
|
86
91
|
}
|
|
92
|
+
getCachedSchema(filePath) {
|
|
93
|
+
return this.schemaCache.get(filePath);
|
|
94
|
+
}
|
|
95
|
+
saveSchemasToCache(schemas) {
|
|
96
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
97
|
+
const cacheDir = path_1.default.dirname(this.schemaCacheFile);
|
|
98
|
+
if (!fs_1.default.existsSync(cacheDir)) {
|
|
99
|
+
yield fs_1.default.promises.mkdir(cacheDir, { recursive: true });
|
|
100
|
+
}
|
|
101
|
+
const data = {};
|
|
102
|
+
for (const [key, value] of schemas) {
|
|
103
|
+
data[key] = value;
|
|
104
|
+
this.schemaCache.set(key, value);
|
|
105
|
+
}
|
|
106
|
+
yield fs_1.default.promises.writeFile(this.schemaCacheFile, JSON.stringify(data));
|
|
107
|
+
});
|
|
108
|
+
}
|
|
87
109
|
loadCache() {
|
|
88
110
|
try {
|
|
89
111
|
if (fs_1.default.existsSync(this.cacheFile)) {
|
|
90
112
|
const cacheData = JSON.parse(fs_1.default.readFileSync(this.cacheFile, 'utf-8'));
|
|
91
113
|
this.fileCache = new Map(Object.entries(cacheData));
|
|
92
114
|
}
|
|
115
|
+
if (fs_1.default.existsSync(this.schemaCacheFile)) {
|
|
116
|
+
const schemaData = JSON.parse(fs_1.default.readFileSync(this.schemaCacheFile, 'utf-8'));
|
|
117
|
+
this.schemaCache = new Map(Object.entries(schemaData));
|
|
118
|
+
}
|
|
93
119
|
}
|
|
94
120
|
catch (error) {
|
|
95
121
|
console.warn('Failed to load cache, starting fresh');
|
|
96
122
|
this.fileCache.clear();
|
|
123
|
+
this.schemaCache.clear();
|
|
97
124
|
}
|
|
98
125
|
}
|
|
99
126
|
saveCache(files) {
|
|
@@ -114,9 +141,13 @@ class FileDiscovery {
|
|
|
114
141
|
}
|
|
115
142
|
clearCache() {
|
|
116
143
|
this.fileCache.clear();
|
|
144
|
+
this.schemaCache.clear();
|
|
117
145
|
if (fs_1.default.existsSync(this.cacheFile)) {
|
|
118
146
|
fs_1.default.unlinkSync(this.cacheFile);
|
|
119
147
|
}
|
|
148
|
+
if (fs_1.default.existsSync(this.schemaCacheFile)) {
|
|
149
|
+
fs_1.default.unlinkSync(this.schemaCacheFile);
|
|
150
|
+
}
|
|
120
151
|
}
|
|
121
152
|
}
|
|
122
153
|
exports.FileDiscovery = FileDiscovery;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"FileDiscovery.js","sourceRoot":"","sources":["../../src/services/FileDiscovery.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;AAAA,+BAA4B;AAC5B,0DAAkC;AAClC,gDAAwB;AACxB,4CAAoB;AACpB,oDAA4B;AAC5B,sCAA+C;
|
|
1
|
+
{"version":3,"file":"FileDiscovery.js","sourceRoot":"","sources":["../../src/services/FileDiscovery.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;AAAA,+BAA4B;AAC5B,0DAAkC;AAClC,gDAAwB;AACxB,4CAAoB;AACpB,oDAA4B;AAC5B,sCAA+C;AAgB/C,MAAa,aAAa;IAMtB,YAAoB,OAA6B;QAA7B,YAAO,GAAP,OAAO,CAAsB;QAHzC,cAAS,GAAwB,IAAI,GAAG,EAAE,CAAC;QAC3C,gBAAW,GAAwB,IAAI,GAAG,EAAE,CAAC;QAGjD,MAAM,QAAQ,GAAG,OAAO,CAAC,SAAS,IAAI,8BAA8B,CAAC;QACrE,IAAI,CAAC,SAAS,GAAG,cAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,kBAAkB,CAAC,CAAC;QACzD,IAAI,CAAC,eAAe,GAAG,cAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,mBAAmB,CAAC,CAAC;QAChE,IAAI,OAAO,CAAC,YAAY,EAAE,CAAC;YACvB,IAAI,CAAC,SAAS,EAAE,CAAC;QACrB,CAAC;IACL,CAAC;IAEY,aAAa;;YACtB,MAAM,EAAE,IAAI,EAAE,QAAQ,EAAE,GAAG,IAAI,CAAC,OAAO,CAAC;YAExC,IAAI,CAAC;gBACD,MAAM,GAAG,GAAG,IAAI,WAAI,CAAC;oBACjB,eAAe,EAAE,IAAI;oBACrB,WAAW,EAAE,KAAK;oBAClB,OAAO,EAAE;wBACL,CAAC,QAAQ,EAAE,EAAE;4BACT,OAAO,mBAAS,CAAC,OAAO,CAAC,QAAQ,EAAE,IAAI,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC;wBACjE,CAAC;qBACJ;iBACJ,CAAC,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;gBAEnB,MAAM,KAAK,GAAG,MAAM,GAAG,CAAC,WAAW,EAAE,CAAC;gBAEtC,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;oBACrB,MAAM,IAAI,2BAAkB,CACxB,oCAAoC,IAAI,OAAO,QAAQ,EAAE,CAC5D,CAAC;gBACN,CAAC;gBAED,0DAA0D;gBAC1D,MAAM,WAAW,GAAG,CAAC,GAAG,KAAK,CAAC,CAAC,IAAI,EAAE,CAAC;gBAEtC,OAAO,IAAI,CAAC,OAAO,CAAC,YAAY;oBAC5B,CAAC,CAAC,MAAM,IAAI,CAAC,mBAAmB,CAAC,WAAW,CAAC;oBAC7C,CAAC,CAAC,WAAW,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC;YAC9C,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACb,IAAI,KAAK,YAAY,2BAAkB,EAAE,CAAC;oBACtC,MAAM,KAAK,CAAC;gBAChB,CAAC;gBACD,MAAM,IAAI,2BAAkB,CACxB,6BAA6B,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CACxF,CAAC;YACN,CAAC;QACL,CAAC;KAAA;IAEa,mBAAmB,CAAC,KAAe;;YAC7C,MAAM,aAAa,GAAG,MAAM,OAAO,CAAC,GAAG,CACnC,KAAK,CAAC,GAAG,CAAC,CAAO,QAAQ,EAAE,EAAE;gBACzB,MAAM,KAAK,GAAG,MAAM,YAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;gBAC/C,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,WAAW,CAAC,QAAQ,CAAC,CAAC;gBAC9C,MAAM,UAAU,GAAG,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;gBAChD,OAAO;oBACH,IAAI,EAAE,QAAQ;oBACd,IAAI;oBACJ,YAAY,EAAE,KAAK,CAAC,KAAK;oBACzB,OAAO,EAAE,UAAU,KAAK,IAAI;iBAC/B,CAAC;YACN,CAAC,CAAA,CAAC,CACL,CAAC;YAEF,MAAM,IAAI,CAAC,SAAS,CAAC,aAAa,CAAC,CAAC;YACpC,OAAO,aAAa,CAAC;QACzB,CAAC;KAAA;IAEa,WAAW,CAAC,QAAgB;;YACtC,MAAM,OAAO,GAAG,MAAM,YAAE,CAAC,QAAQ,CAAC,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;YAC9D,OAAO,gBAAM,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QAClE,CAAC;KAAA;IAEM,cAAc,CAAC,QAAgB,EAAE,WAAmB;QACvD,MAAM,UAAU,GAAG,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;QAChD,OAAO,UAAU,KAAK,WAAW,CAAC;IACtC,CAAC;IAEM,eAAe,CAAC,QAAgB;QACnC,OAAO,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;IAC1C,CAAC;IAEY,kBAAkB,CAAC,OAA4B;;YACxD,MAAM,QAAQ,GAAG,cAAI,CAAC,OAAO,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC;YACpD,IAAI,CAAC,YAAE,CAAC,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC;gBAC3B,MAAM,YAAE,CAAC,QAAQ,CAAC,KAAK,CAAC,QAAQ,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;YAC3D,CAAC;YACD,MAAM,IAAI,GAA2B,EAAE,CAAC;YACxC,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,OAAO,EAAE,CAAC;gBACjC,IAAI,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC;gBAClB,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;YACrC,CAAC;YACD,MAAM,YAAE,CAAC,QAAQ,CAAC,SAAS,CAAC,IAAI,CAAC,eAAe,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC;QAC5E,CAAC;KAAA;IAEO,SAAS;QACb,IAAI,CAAC;YACD,IAAI,YAAE,CAAC,UAAU,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,CAAC;gBAChC,MAAM,SAAS,GAAG,IAAI,CAAC,KAAK,CACxB,YAAE,CAAC,YAAY,CAAC,IAAI,CAAC,SAAS,EAAE,OAAO,CAAC,CAC3C,CAAC;gBACF,IAAI,CAAC,SAAS,GAAG,IAAI,GAAG,CAAC,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC,CAAC;YACxD,CAAC;YACD,IAAI,YAAE,CAAC,UAAU,CAAC,IAAI,CAAC,eAAe,CAAC,EAAE,CAAC;gBACtC,MAAM,UAAU,GAAG,IAAI,CAAC,KAAK,CACzB,YAAE,CAAC,YAAY,CAAC,IAAI,CAAC,eAAe,EAAE,OAAO,CAAC,CACjD,CAAC;gBACF,IAAI,CAAC,WAAW,GAAG,IAAI,GAAG,CAAC,MAAM,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC,CAAC;YAC3D,CAAC;QACL,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACb,OAAO,CAAC,IAAI,CAAC,sCAAsC,CAAC,CAAC;YACrD,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,CAAC;YACvB,IAAI,CAAC,WAAW,CAAC,KAAK,EAAE,CAAC;QAC7B,CAAC;IACL,CAAC;IAEa,SAAS,CAAC,KAAiB;;YACrC,MAAM,QAAQ,GAAG,cAAI,CAAC,OAAO,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;YAC9C,IAAI,CAAC,YAAE,CAAC,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC;gBAC3B,MAAM,YAAE,CAAC,QAAQ,CAAC,KAAK,CAAC,QAAQ,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;YAC3D,CAAC;YAED,MAAM,SAAS,GAA2B,EAAE,CAAC;YAC7C,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE;gBACjB,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC;oBACZ,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC,IAAI,CAAC;oBACjC,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC;gBAC7C,CAAC;YACL,CAAC,CAAC,CAAC;YAEH,MAAM,YAAE,CAAC,QAAQ,CAAC,SAAS,CACvB,IAAI,CAAC,SAAS,EACd,IAAI,CAAC,SAAS,CAAC,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC,CACrC,CAAC;QACN,CAAC;KAAA;IAEM,UAAU;QACb,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,CAAC;QACvB,IAAI,CAAC,WAAW,CAAC,KAAK,EAAE,CAAC;QACzB,IAAI,YAAE,CAAC,UAAU,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,CAAC;YAChC,YAAE,CAAC,UAAU,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;QAClC,CAAC;QACD,IAAI,YAAE,CAAC,UAAU,CAAC,IAAI,CAAC,eAAe,CAAC,EAAE,CAAC;YACtC,YAAE,CAAC,UAAU,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC;QACxC,CAAC;IACL,CAAC;CACJ;AAtJD,sCAsJC"}
|
package/package.json
CHANGED
package/src/SchemaGenerator.ts
CHANGED
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
import { ICommandOptions } from "./ICommandOptions";
|
|
2
2
|
import path from "path";
|
|
3
|
-
import { FileDiscovery } from "./services/FileDiscovery";
|
|
3
|
+
import { FileDiscovery, FileInfo } from "./services/FileDiscovery";
|
|
4
4
|
import { SchemaProcessor } from "./services/SchemaProcessor";
|
|
5
5
|
import { CodeGenerator } from "./services/CodeGenerator";
|
|
6
6
|
import { SchemaWriter } from "./services/SchemaWriter";
|
|
7
7
|
import { ProgressReporter } from "./utils/ProgressReporter";
|
|
8
8
|
import { formatError, isKnownError } from "./errors";
|
|
9
|
+
import { Schema } from "ts-json-schema-generator";
|
|
9
10
|
|
|
10
11
|
const validationSchemaFileName = "validation.schema.json";
|
|
11
12
|
const schemaDefinitionFileName = "SchemaDefinition.ts";
|
|
@@ -69,17 +70,51 @@ export class SchemaGenerator {
|
|
|
69
70
|
// Discover files
|
|
70
71
|
this.progressReporter.update(0, "Discovering files...");
|
|
71
72
|
const files = await this.fileDiscovery.discoverFiles();
|
|
72
|
-
|
|
73
|
+
|
|
73
74
|
if (this.options.verbose) {
|
|
74
75
|
console.log(`Found ${files.length} schema file(s)`);
|
|
75
76
|
files.forEach(file => console.log(` - ${file.path}`));
|
|
76
77
|
}
|
|
77
|
-
|
|
78
|
+
|
|
79
|
+
// Separate changed and unchanged files when caching is enabled
|
|
80
|
+
const cacheEnabled = this.options.cache || false;
|
|
81
|
+
let filesToProcess: FileInfo[];
|
|
82
|
+
const cachedSchemas = new Map<string, Schema>();
|
|
83
|
+
|
|
84
|
+
if (cacheEnabled) {
|
|
85
|
+
filesToProcess = files.filter(f => f.changed !== false);
|
|
86
|
+
const unchangedFiles = files.filter(f => f.changed === false);
|
|
87
|
+
for (const file of unchangedFiles) {
|
|
88
|
+
const cached = this.fileDiscovery.getCachedSchema(file.path);
|
|
89
|
+
if (cached) {
|
|
90
|
+
cachedSchemas.set(file.path, cached as Schema);
|
|
91
|
+
} else {
|
|
92
|
+
// No cached schema available, must reprocess
|
|
93
|
+
filesToProcess.push(file);
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
if (this.options.verbose) {
|
|
97
|
+
console.log(`Cache: ${cachedSchemas.size} unchanged, ${filesToProcess.length} to process`);
|
|
98
|
+
}
|
|
99
|
+
} else {
|
|
100
|
+
filesToProcess = files;
|
|
101
|
+
}
|
|
102
|
+
|
|
78
103
|
// Process schemas
|
|
79
104
|
this.progressReporter.update(1, "Processing TypeScript files...");
|
|
80
|
-
this.progressReporter.options.total =
|
|
81
|
-
|
|
82
|
-
const
|
|
105
|
+
this.progressReporter.options.total = filesToProcess.length + 4; // files + 4 generation steps
|
|
106
|
+
|
|
107
|
+
const processedSchemas = filesToProcess.length > 0
|
|
108
|
+
? await this.schemaProcessor.processFiles(filesToProcess)
|
|
109
|
+
: new Map<string, Schema>();
|
|
110
|
+
|
|
111
|
+
// Merge processed and cached schemas
|
|
112
|
+
const schemaMap = new Map<string, Schema>([...cachedSchemas, ...processedSchemas]);
|
|
113
|
+
|
|
114
|
+
// Save all schemas to cache for next run
|
|
115
|
+
if (cacheEnabled) {
|
|
116
|
+
await this.fileDiscovery.saveSchemasToCache(schemaMap);
|
|
117
|
+
}
|
|
83
118
|
|
|
84
119
|
if (schemaMap.size === 0) {
|
|
85
120
|
console.log("No types found to generate schemas for");
|
|
@@ -16,17 +16,19 @@ export interface FileInfo {
|
|
|
16
16
|
path: string;
|
|
17
17
|
hash?: string;
|
|
18
18
|
lastModified?: Date;
|
|
19
|
+
changed?: boolean;
|
|
19
20
|
}
|
|
20
21
|
|
|
21
22
|
export class FileDiscovery {
|
|
22
23
|
private cacheFile: string;
|
|
24
|
+
private schemaCacheFile: string;
|
|
23
25
|
private fileCache: Map<string, string> = new Map();
|
|
26
|
+
private schemaCache: Map<string, object> = new Map();
|
|
24
27
|
|
|
25
28
|
constructor(private options: FileDiscoveryOptions) {
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
);
|
|
29
|
+
const cacheDir = options.cachePath || ".ts-runtime-validation-cache";
|
|
30
|
+
this.cacheFile = path.join(cacheDir, "file-hashes.json");
|
|
31
|
+
this.schemaCacheFile = path.join(cacheDir, "schema-cache.json");
|
|
30
32
|
if (options.cacheEnabled) {
|
|
31
33
|
this.loadCache();
|
|
32
34
|
}
|
|
@@ -75,14 +77,16 @@ export class FileDiscovery {
|
|
|
75
77
|
files.map(async (filePath) => {
|
|
76
78
|
const stats = await fs.promises.stat(filePath);
|
|
77
79
|
const hash = await this.getFileHash(filePath);
|
|
80
|
+
const cachedHash = this.fileCache.get(filePath);
|
|
78
81
|
return {
|
|
79
82
|
path: filePath,
|
|
80
83
|
hash,
|
|
81
|
-
lastModified: stats.mtime
|
|
84
|
+
lastModified: stats.mtime,
|
|
85
|
+
changed: cachedHash !== hash
|
|
82
86
|
};
|
|
83
87
|
})
|
|
84
88
|
);
|
|
85
|
-
|
|
89
|
+
|
|
86
90
|
await this.saveCache(enrichedFiles);
|
|
87
91
|
return enrichedFiles;
|
|
88
92
|
}
|
|
@@ -97,6 +101,23 @@ export class FileDiscovery {
|
|
|
97
101
|
return cachedHash !== currentHash;
|
|
98
102
|
}
|
|
99
103
|
|
|
104
|
+
public getCachedSchema(filePath: string): object | undefined {
|
|
105
|
+
return this.schemaCache.get(filePath);
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
public async saveSchemasToCache(schemas: Map<string, object>): Promise<void> {
|
|
109
|
+
const cacheDir = path.dirname(this.schemaCacheFile);
|
|
110
|
+
if (!fs.existsSync(cacheDir)) {
|
|
111
|
+
await fs.promises.mkdir(cacheDir, { recursive: true });
|
|
112
|
+
}
|
|
113
|
+
const data: Record<string, object> = {};
|
|
114
|
+
for (const [key, value] of schemas) {
|
|
115
|
+
data[key] = value;
|
|
116
|
+
this.schemaCache.set(key, value);
|
|
117
|
+
}
|
|
118
|
+
await fs.promises.writeFile(this.schemaCacheFile, JSON.stringify(data));
|
|
119
|
+
}
|
|
120
|
+
|
|
100
121
|
private loadCache(): void {
|
|
101
122
|
try {
|
|
102
123
|
if (fs.existsSync(this.cacheFile)) {
|
|
@@ -105,9 +126,16 @@ export class FileDiscovery {
|
|
|
105
126
|
);
|
|
106
127
|
this.fileCache = new Map(Object.entries(cacheData));
|
|
107
128
|
}
|
|
129
|
+
if (fs.existsSync(this.schemaCacheFile)) {
|
|
130
|
+
const schemaData = JSON.parse(
|
|
131
|
+
fs.readFileSync(this.schemaCacheFile, 'utf-8')
|
|
132
|
+
);
|
|
133
|
+
this.schemaCache = new Map(Object.entries(schemaData));
|
|
134
|
+
}
|
|
108
135
|
} catch (error) {
|
|
109
136
|
console.warn('Failed to load cache, starting fresh');
|
|
110
137
|
this.fileCache.clear();
|
|
138
|
+
this.schemaCache.clear();
|
|
111
139
|
}
|
|
112
140
|
}
|
|
113
141
|
|
|
@@ -133,8 +161,12 @@ export class FileDiscovery {
|
|
|
133
161
|
|
|
134
162
|
public clearCache(): void {
|
|
135
163
|
this.fileCache.clear();
|
|
164
|
+
this.schemaCache.clear();
|
|
136
165
|
if (fs.existsSync(this.cacheFile)) {
|
|
137
166
|
fs.unlinkSync(this.cacheFile);
|
|
138
167
|
}
|
|
168
|
+
if (fs.existsSync(this.schemaCacheFile)) {
|
|
169
|
+
fs.unlinkSync(this.schemaCacheFile);
|
|
170
|
+
}
|
|
139
171
|
}
|
|
140
172
|
}
|