@cisco_open/linting-orchestrator 1.0.0-rc.4

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.
Files changed (197) hide show
  1. package/LICENSE +201 -0
  2. package/NOTICE +5 -0
  3. package/README.md +43 -0
  4. package/build/cli/api-client.d.ts +170 -0
  5. package/build/cli/api-client.d.ts.map +1 -0
  6. package/build/cli/api-client.js +284 -0
  7. package/build/cli/api-client.js.map +1 -0
  8. package/build/cli/commands/agents.d.ts +7 -0
  9. package/build/cli/commands/agents.d.ts.map +1 -0
  10. package/build/cli/commands/agents.js +694 -0
  11. package/build/cli/commands/agents.js.map +1 -0
  12. package/build/cli/commands/completion.d.ts +9 -0
  13. package/build/cli/commands/completion.d.ts.map +1 -0
  14. package/build/cli/commands/completion.js +177 -0
  15. package/build/cli/commands/completion.js.map +1 -0
  16. package/build/cli/commands/config.d.ts +10 -0
  17. package/build/cli/commands/config.d.ts.map +1 -0
  18. package/build/cli/commands/config.js +284 -0
  19. package/build/cli/commands/config.js.map +1 -0
  20. package/build/cli/commands/health.d.ts +11 -0
  21. package/build/cli/commands/health.d.ts.map +1 -0
  22. package/build/cli/commands/health.js +38 -0
  23. package/build/cli/commands/health.js.map +1 -0
  24. package/build/cli/commands/help.d.ts +6 -0
  25. package/build/cli/commands/help.d.ts.map +1 -0
  26. package/build/cli/commands/help.js +20 -0
  27. package/build/cli/commands/help.js.map +1 -0
  28. package/build/cli/commands/history.d.ts +11 -0
  29. package/build/cli/commands/history.d.ts.map +1 -0
  30. package/build/cli/commands/history.js +50 -0
  31. package/build/cli/commands/history.js.map +1 -0
  32. package/build/cli/commands/jobs.d.ts +12 -0
  33. package/build/cli/commands/jobs.d.ts.map +1 -0
  34. package/build/cli/commands/jobs.js +84 -0
  35. package/build/cli/commands/jobs.js.map +1 -0
  36. package/build/cli/commands/lint.d.ts +15 -0
  37. package/build/cli/commands/lint.d.ts.map +1 -0
  38. package/build/cli/commands/lint.js +384 -0
  39. package/build/cli/commands/lint.js.map +1 -0
  40. package/build/cli/commands/ps.d.ts +8 -0
  41. package/build/cli/commands/ps.d.ts.map +1 -0
  42. package/build/cli/commands/ps.js +74 -0
  43. package/build/cli/commands/ps.js.map +1 -0
  44. package/build/cli/commands/reproduce.d.ts +9 -0
  45. package/build/cli/commands/reproduce.d.ts.map +1 -0
  46. package/build/cli/commands/reproduce.js +31 -0
  47. package/build/cli/commands/reproduce.js.map +1 -0
  48. package/build/cli/commands/reset.d.ts +5 -0
  49. package/build/cli/commands/reset.d.ts.map +1 -0
  50. package/build/cli/commands/reset.js +13 -0
  51. package/build/cli/commands/reset.js.map +1 -0
  52. package/build/cli/commands/results.d.ts +13 -0
  53. package/build/cli/commands/results.d.ts.map +1 -0
  54. package/build/cli/commands/results.js +129 -0
  55. package/build/cli/commands/results.js.map +1 -0
  56. package/build/cli/commands/rulesets/check.d.ts +12 -0
  57. package/build/cli/commands/rulesets/check.d.ts.map +1 -0
  58. package/build/cli/commands/rulesets/check.js +226 -0
  59. package/build/cli/commands/rulesets/check.js.map +1 -0
  60. package/build/cli/commands/rulesets/index.d.ts +5 -0
  61. package/build/cli/commands/rulesets/index.d.ts.map +1 -0
  62. package/build/cli/commands/rulesets/index.js +6 -0
  63. package/build/cli/commands/rulesets/index.js.map +1 -0
  64. package/build/cli/commands/rulesets/view.d.ts +16 -0
  65. package/build/cli/commands/rulesets/view.d.ts.map +1 -0
  66. package/build/cli/commands/rulesets/view.js +100 -0
  67. package/build/cli/commands/rulesets/view.js.map +1 -0
  68. package/build/cli/commands/start.d.ts +16 -0
  69. package/build/cli/commands/start.d.ts.map +1 -0
  70. package/build/cli/commands/start.js +167 -0
  71. package/build/cli/commands/start.js.map +1 -0
  72. package/build/cli/commands/status.d.ts +9 -0
  73. package/build/cli/commands/status.d.ts.map +1 -0
  74. package/build/cli/commands/status.js +46 -0
  75. package/build/cli/commands/status.js.map +1 -0
  76. package/build/cli/commands/stop.d.ts +11 -0
  77. package/build/cli/commands/stop.d.ts.map +1 -0
  78. package/build/cli/commands/stop.js +78 -0
  79. package/build/cli/commands/stop.js.map +1 -0
  80. package/build/cli/config-manager.d.ts +134 -0
  81. package/build/cli/config-manager.d.ts.map +1 -0
  82. package/build/cli/config-manager.js +288 -0
  83. package/build/cli/config-manager.js.map +1 -0
  84. package/build/cli/formatters.d.ts +62 -0
  85. package/build/cli/formatters.d.ts.map +1 -0
  86. package/build/cli/formatters.js +715 -0
  87. package/build/cli/formatters.js.map +1 -0
  88. package/build/cli/history-manager.d.ts +97 -0
  89. package/build/cli/history-manager.d.ts.map +1 -0
  90. package/build/cli/history-manager.js +201 -0
  91. package/build/cli/history-manager.js.map +1 -0
  92. package/build/cli/index.d.ts +16 -0
  93. package/build/cli/index.d.ts.map +1 -0
  94. package/build/cli/index.js +335 -0
  95. package/build/cli/index.js.map +1 -0
  96. package/build/cli/list-rulesets.d.ts +15 -0
  97. package/build/cli/list-rulesets.d.ts.map +1 -0
  98. package/build/cli/list-rulesets.js +193 -0
  99. package/build/cli/list-rulesets.js.map +1 -0
  100. package/build/cli/utils/connection-error.d.ts +9 -0
  101. package/build/cli/utils/connection-error.d.ts.map +1 -0
  102. package/build/cli/utils/connection-error.js +30 -0
  103. package/build/cli/utils/connection-error.js.map +1 -0
  104. package/build/cli/utils/embedded-server.d.ts +21 -0
  105. package/build/cli/utils/embedded-server.d.ts.map +1 -0
  106. package/build/cli/utils/embedded-server.js +61 -0
  107. package/build/cli/utils/embedded-server.js.map +1 -0
  108. package/build/cli/utils/mode-validator.d.ts +13 -0
  109. package/build/cli/utils/mode-validator.d.ts.map +1 -0
  110. package/build/cli/utils/mode-validator.js +31 -0
  111. package/build/cli/utils/mode-validator.js.map +1 -0
  112. package/build/cli/utils/port-checker.d.ts +20 -0
  113. package/build/cli/utils/port-checker.d.ts.map +1 -0
  114. package/build/cli/utils/port-checker.js +49 -0
  115. package/build/cli/utils/port-checker.js.map +1 -0
  116. package/build/config.d.ts +57 -0
  117. package/build/config.d.ts.map +1 -0
  118. package/build/config.js +527 -0
  119. package/build/config.js.map +1 -0
  120. package/build/document-accessor.d.ts +79 -0
  121. package/build/document-accessor.d.ts.map +1 -0
  122. package/build/document-accessor.js +148 -0
  123. package/build/document-accessor.js.map +1 -0
  124. package/build/formatters/reproduce-markdown.d.ts +14 -0
  125. package/build/formatters/reproduce-markdown.d.ts.map +1 -0
  126. package/build/formatters/reproduce-markdown.js +182 -0
  127. package/build/formatters/reproduce-markdown.js.map +1 -0
  128. package/build/formatters/sarif-builder.d.ts +86 -0
  129. package/build/formatters/sarif-builder.d.ts.map +1 -0
  130. package/build/formatters/sarif-builder.js +276 -0
  131. package/build/formatters/sarif-builder.js.map +1 -0
  132. package/build/index.d.ts +3 -0
  133. package/build/index.d.ts.map +1 -0
  134. package/build/index.js +174 -0
  135. package/build/index.js.map +1 -0
  136. package/build/logger.d.ts +38 -0
  137. package/build/logger.d.ts.map +1 -0
  138. package/build/logger.js +105 -0
  139. package/build/logger.js.map +1 -0
  140. package/build/mock-server.d.ts +2 -0
  141. package/build/mock-server.d.ts.map +1 -0
  142. package/build/mock-server.js +290 -0
  143. package/build/mock-server.js.map +1 -0
  144. package/build/orchestrator.d.ts +149 -0
  145. package/build/orchestrator.d.ts.map +1 -0
  146. package/build/orchestrator.js +874 -0
  147. package/build/orchestrator.js.map +1 -0
  148. package/build/ruleset-loader.d.ts +79 -0
  149. package/build/ruleset-loader.d.ts.map +1 -0
  150. package/build/ruleset-loader.js +514 -0
  151. package/build/ruleset-loader.js.map +1 -0
  152. package/build/schemas.d.ts +2568 -0
  153. package/build/schemas.d.ts.map +1 -0
  154. package/build/schemas.js +674 -0
  155. package/build/schemas.js.map +1 -0
  156. package/build/server.d.ts +39 -0
  157. package/build/server.d.ts.map +1 -0
  158. package/build/server.js +834 -0
  159. package/build/server.js.map +1 -0
  160. package/build/storage/memory-storage.d.ts +190 -0
  161. package/build/storage/memory-storage.d.ts.map +1 -0
  162. package/build/storage/memory-storage.js +629 -0
  163. package/build/storage/memory-storage.js.map +1 -0
  164. package/build/storage/redis-storage.d.ts +134 -0
  165. package/build/storage/redis-storage.d.ts.map +1 -0
  166. package/build/storage/redis-storage.js +236 -0
  167. package/build/storage/redis-storage.js.map +1 -0
  168. package/build/storage/storage-adapter.d.ts +189 -0
  169. package/build/storage/storage-adapter.d.ts.map +1 -0
  170. package/build/storage/storage-adapter.js +36 -0
  171. package/build/storage/storage-adapter.js.map +1 -0
  172. package/build/types.d.ts +981 -0
  173. package/build/types.d.ts.map +1 -0
  174. package/build/types.js +5 -0
  175. package/build/types.js.map +1 -0
  176. package/build/utils/version.d.ts +40 -0
  177. package/build/utils/version.d.ts.map +1 -0
  178. package/build/utils/version.js +94 -0
  179. package/build/utils/version.js.map +1 -0
  180. package/build/validation.d.ts +95 -0
  181. package/build/validation.d.ts.map +1 -0
  182. package/build/validation.js +150 -0
  183. package/build/validation.js.map +1 -0
  184. package/build/worker-pool.d.ts +137 -0
  185. package/build/worker-pool.d.ts.map +1 -0
  186. package/build/worker-pool.js +549 -0
  187. package/build/worker-pool.js.map +1 -0
  188. package/build/worker.d.ts +2 -0
  189. package/build/worker.d.ts.map +1 -0
  190. package/build/worker.js +427 -0
  191. package/build/worker.js.map +1 -0
  192. package/package.json +110 -0
  193. package/rulesets/CHANGELOG.md +25 -0
  194. package/rulesets/config/rulesets.yaml +96 -0
  195. package/rulesets/sources/README.md +47 -0
  196. package/rulesets/sources/example/oas-recommended/v1.0.0/ruleset.yaml +6 -0
  197. package/rulesets/sources/example/oas-recommended/v2.0.0/ruleset.yaml +14 -0
@@ -0,0 +1,134 @@
1
+ /**
2
+ * Redis Storage Implementation for OpenAPI Lint Orchestrator
3
+ *
4
+ * TODO: Future enhancement for distributed deployments.
5
+ *
6
+ * This storage adapter is designed but not yet implemented.
7
+ * It will provide shared storage across multiple orchestrator instances
8
+ * using Redis as the backend.
9
+ *
10
+ * Use cases:
11
+ * - Multi-instance deployments behind load balancer
12
+ * - Shared result cache across worker nodes
13
+ * - Persistent storage with Redis persistence
14
+ * - Pub/sub for cache invalidation notifications
15
+ *
16
+ * @module storage/redis-storage
17
+ */
18
+ import type { LintJobResult } from '../types.js';
19
+ import type { LintResultStorage, StorageOptions, StorageStats } from './storage-adapter.js';
20
+ /**
21
+ * Redis-specific storage options
22
+ */
23
+ export interface RedisStorageOptions extends StorageOptions {
24
+ /**
25
+ * Redis connection URL
26
+ * Example: redis://localhost:6379
27
+ */
28
+ url?: string;
29
+ /**
30
+ * Redis connection options
31
+ */
32
+ host?: string;
33
+ port?: number;
34
+ password?: string;
35
+ db?: number;
36
+ /**
37
+ * Key prefix for all storage keys
38
+ * Default: 'spectify:lint:'
39
+ */
40
+ keyPrefix?: string;
41
+ /**
42
+ * Enable pub/sub for distributed cache invalidation
43
+ * Default: false
44
+ */
45
+ enablePubSub?: boolean;
46
+ }
47
+ /**
48
+ * Redis storage implementation
49
+ *
50
+ * TODO: Implement using ioredis package
51
+ *
52
+ * Implementation plan:
53
+ * 1. Add ioredis dependency: npm install ioredis @types/ioredis
54
+ * 2. Implement connection management
55
+ * 3. Implement key-value storage with TTL
56
+ * 4. Implement indexing using Redis Sets
57
+ * 5. Implement pub/sub for invalidation (optional)
58
+ * 6. Add error handling and retry logic
59
+ * 7. Add comprehensive tests
60
+ *
61
+ * Example usage:
62
+ * ```typescript
63
+ * const storage = new RedisLintStorage();
64
+ * await storage.initialize({
65
+ * url: 'redis://localhost:6379',
66
+ * ttl: 3600, // 1 hour
67
+ * keyPrefix: 'spectify:lint:'
68
+ * });
69
+ * ```
70
+ */
71
+ export declare class RedisLintStorage implements LintResultStorage {
72
+ /**
73
+ * Initialize Redis storage
74
+ *
75
+ * TODO: Implement Redis connection
76
+ */
77
+ initialize(_options?: RedisStorageOptions): Promise<void>;
78
+ /**
79
+ * Store job result in Redis
80
+ *
81
+ * TODO: Implement Redis storage
82
+ *
83
+ * Storage strategy:
84
+ * - Key: spectify:lint:job:{jobId}
85
+ * - Value: JSON.stringify(result)
86
+ * - TTL: options.ttl (if set)
87
+ * - Index: spectify:lint:doc:{documentId} -> Set of jobIds
88
+ * - Index: spectify:lint:composite:{compositeKey} -> jobId
89
+ */
90
+ storeJob(_result: LintJobResult): Promise<void>;
91
+ /**
92
+ * Retrieve job by ID from Redis
93
+ *
94
+ * TODO: Implement retrieval
95
+ */
96
+ retrieveJobById(_jobId: string): Promise<LintJobResult | null>;
97
+ /**
98
+ * Retrieve job by document + ruleset
99
+ *
100
+ * TODO: Implement composite retrieval
101
+ */
102
+ retrieveJob(_documentId: string, _rulesetName: string, _rulesetVersion: string): Promise<LintJobResult | null>;
103
+ /**
104
+ * Check if results exist
105
+ *
106
+ * TODO: Implement existence check
107
+ */
108
+ exists(_documentId: string, _rulesetName: string, _rulesetVersion: string): Promise<boolean>;
109
+ /**
110
+ * Invalidate all results for a document
111
+ *
112
+ * TODO: Implement invalidation with pub/sub
113
+ */
114
+ invalidate(_documentId: string): Promise<number>;
115
+ /**
116
+ * Get storage statistics
117
+ *
118
+ * TODO: Implement stats collection
119
+ */
120
+ getStats(): Promise<StorageStats>;
121
+ /**
122
+ * Clear all data
123
+ *
124
+ * TODO: Implement clear
125
+ */
126
+ clear(): Promise<number>;
127
+ /**
128
+ * Close Redis connection
129
+ *
130
+ * TODO: Implement cleanup
131
+ */
132
+ close(): Promise<void>;
133
+ }
134
+ //# sourceMappingURL=redis-storage.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"redis-storage.d.ts","sourceRoot":"","sources":["../../src/storage/redis-storage.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AACjD,OAAO,KAAK,EACV,iBAAiB,EACjB,cAAc,EACd,YAAY,EACb,MAAM,sBAAsB,CAAC;AAE9B;;GAEG;AACH,MAAM,WAAW,mBAAoB,SAAQ,cAAc;IACzD;;;OAGG;IACH,GAAG,CAAC,EAAE,MAAM,CAAC;IAEb;;OAEG;IACH,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,EAAE,CAAC,EAAE,MAAM,CAAC;IAEZ;;;OAGG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;IAEnB;;;OAGG;IACH,YAAY,CAAC,EAAE,OAAO,CAAC;CACxB;AAED;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,qBAAa,gBAAiB,YAAW,iBAAiB;IAIxD;;;;OAIG;IACG,UAAU,CAAC,QAAQ,CAAC,EAAE,mBAAmB,GAAG,OAAO,CAAC,IAAI,CAAC;IAsB/D;;;;;;;;;;;OAWG;IACG,QAAQ,CAAC,OAAO,EAAE,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC;IA+BrD;;;;OAIG;IACG,eAAe,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,GAAG,IAAI,CAAC;IAcpE;;;;OAIG;IACG,WAAW,CACf,WAAW,EAAE,MAAM,EACnB,YAAY,EAAE,MAAM,EACpB,eAAe,EAAE,MAAM,GACtB,OAAO,CAAC,aAAa,GAAG,IAAI,CAAC;IAehC;;;;OAIG;IACG,MAAM,CACV,WAAW,EAAE,MAAM,EACnB,YAAY,EAAE,MAAM,EACpB,eAAe,EAAE,MAAM,GACtB,OAAO,CAAC,OAAO,CAAC;IAUnB;;;;OAIG;IACG,UAAU,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IA6BtD;;;;OAIG;IACG,QAAQ,IAAI,OAAO,CAAC,YAAY,CAAC;IAcvC;;;;OAIG;IACG,KAAK,IAAI,OAAO,CAAC,MAAM,CAAC;IAc9B;;;;OAIG;IACG,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;CAsB7B"}
@@ -0,0 +1,236 @@
1
+ /**
2
+ * Redis Storage Implementation for OpenAPI Lint Orchestrator
3
+ *
4
+ * TODO: Future enhancement for distributed deployments.
5
+ *
6
+ * This storage adapter is designed but not yet implemented.
7
+ * It will provide shared storage across multiple orchestrator instances
8
+ * using Redis as the backend.
9
+ *
10
+ * Use cases:
11
+ * - Multi-instance deployments behind load balancer
12
+ * - Shared result cache across worker nodes
13
+ * - Persistent storage with Redis persistence
14
+ * - Pub/sub for cache invalidation notifications
15
+ *
16
+ * @module storage/redis-storage
17
+ */
18
+ /**
19
+ * Redis storage implementation
20
+ *
21
+ * TODO: Implement using ioredis package
22
+ *
23
+ * Implementation plan:
24
+ * 1. Add ioredis dependency: npm install ioredis @types/ioredis
25
+ * 2. Implement connection management
26
+ * 3. Implement key-value storage with TTL
27
+ * 4. Implement indexing using Redis Sets
28
+ * 5. Implement pub/sub for invalidation (optional)
29
+ * 6. Add error handling and retry logic
30
+ * 7. Add comprehensive tests
31
+ *
32
+ * Example usage:
33
+ * ```typescript
34
+ * const storage = new RedisLintStorage();
35
+ * await storage.initialize({
36
+ * url: 'redis://localhost:6379',
37
+ * ttl: 3600, // 1 hour
38
+ * keyPrefix: 'spectify:lint:'
39
+ * });
40
+ * ```
41
+ */
42
+ export class RedisLintStorage {
43
+ // TODO: Add Redis client instance
44
+ // private redis?: Redis;
45
+ /**
46
+ * Initialize Redis storage
47
+ *
48
+ * TODO: Implement Redis connection
49
+ */
50
+ async initialize(_options) {
51
+ // TODO: Create Redis connection
52
+ // this.redis = new Redis(options?.url || {
53
+ // host: options?.host || 'localhost',
54
+ // port: options?.port || 6379,
55
+ // password: options?.password,
56
+ // db: options?.db || 0
57
+ // });
58
+ throw new Error('RedisLintStorage: TODO - Redis storage is not yet implemented.\n' +
59
+ 'This is a future enhancement for distributed deployments.\n' +
60
+ 'For local development, use MemoryLintStorage instead.\n\n' +
61
+ 'To implement:\n' +
62
+ '1. Install: npm install ioredis @types/ioredis\n' +
63
+ '2. Uncomment Redis client initialization\n' +
64
+ '3. Implement all interface methods\n' +
65
+ '4. Add tests in tests/unit/redis-storage.test.ts');
66
+ }
67
+ /**
68
+ * Store job result in Redis
69
+ *
70
+ * TODO: Implement Redis storage
71
+ *
72
+ * Storage strategy:
73
+ * - Key: spectify:lint:job:{jobId}
74
+ * - Value: JSON.stringify(result)
75
+ * - TTL: options.ttl (if set)
76
+ * - Index: spectify:lint:doc:{documentId} -> Set of jobIds
77
+ * - Index: spectify:lint:composite:{compositeKey} -> jobId
78
+ */
79
+ async storeJob(_result) {
80
+ throw new Error('RedisLintStorage.storeJob: TODO - Not implemented');
81
+ // TODO: Implementation
82
+ // const key = this.makeJobKey(result.jobId);
83
+ // const value = JSON.stringify(result);
84
+ //
85
+ // if (this.options?.ttl) {
86
+ // await this.redis.setex(key, this.options.ttl, value);
87
+ // } else {
88
+ // await this.redis.set(key, value);
89
+ // }
90
+ //
91
+ // // Add to document index
92
+ // await this.redis.sadd(
93
+ // this.makeDocumentIndexKey(result.documentId),
94
+ // result.jobId
95
+ // );
96
+ //
97
+ // // Add to composite index
98
+ // const compositeKey = makeCompositeKey(
99
+ // result.documentId,
100
+ // result.rulesetName,
101
+ // result.rulesetVersion
102
+ // );
103
+ // await this.redis.set(
104
+ // this.makeCompositeIndexKey(compositeKey),
105
+ // result.jobId
106
+ // );
107
+ }
108
+ /**
109
+ * Retrieve job by ID from Redis
110
+ *
111
+ * TODO: Implement retrieval
112
+ */
113
+ async retrieveJobById(_jobId) {
114
+ throw new Error('RedisLintStorage.retrieveJobById: TODO - Not implemented');
115
+ // TODO: Implementation
116
+ // const key = this.makeJobKey(jobId);
117
+ // const value = await this.redis.get(key);
118
+ //
119
+ // if (!value) {
120
+ // return null;
121
+ // }
122
+ //
123
+ // return JSON.parse(value) as LintJobResult;
124
+ }
125
+ /**
126
+ * Retrieve job by document + ruleset
127
+ *
128
+ * TODO: Implement composite retrieval
129
+ */
130
+ async retrieveJob(_documentId, _rulesetName, _rulesetVersion) {
131
+ throw new Error('RedisLintStorage.retrieveJob: TODO - Not implemented');
132
+ // TODO: Implementation
133
+ // const compositeKey = makeCompositeKey(documentId, rulesetName, rulesetVersion);
134
+ // const indexKey = this.makeCompositeIndexKey(compositeKey);
135
+ // const jobId = await this.redis.get(indexKey);
136
+ //
137
+ // if (!jobId) {
138
+ // return null;
139
+ // }
140
+ //
141
+ // return this.retrieveJobById(jobId);
142
+ }
143
+ /**
144
+ * Check if results exist
145
+ *
146
+ * TODO: Implement existence check
147
+ */
148
+ async exists(_documentId, _rulesetName, _rulesetVersion) {
149
+ throw new Error('RedisLintStorage.exists: TODO - Not implemented');
150
+ // TODO: Implementation
151
+ // const compositeKey = makeCompositeKey(documentId, rulesetName, rulesetVersion);
152
+ // const indexKey = this.makeCompositeIndexKey(compositeKey);
153
+ // const exists = await this.redis.exists(indexKey);
154
+ // return exists === 1;
155
+ }
156
+ /**
157
+ * Invalidate all results for a document
158
+ *
159
+ * TODO: Implement invalidation with pub/sub
160
+ */
161
+ async invalidate(_documentId) {
162
+ throw new Error('RedisLintStorage.invalidate: TODO - Not implemented');
163
+ // TODO: Implementation
164
+ // const indexKey = this.makeDocumentIndexKey(documentId);
165
+ // const jobIds = await this.redis.smembers(indexKey);
166
+ //
167
+ // if (jobIds.length === 0) {
168
+ // return 0;
169
+ // }
170
+ //
171
+ // // Delete all job keys
172
+ // const jobKeys = jobIds.map(id => this.makeJobKey(id));
173
+ // await this.redis.del(...jobKeys);
174
+ //
175
+ // // Delete index
176
+ // await this.redis.del(indexKey);
177
+ //
178
+ // // TODO: Publish invalidation event if pub/sub enabled
179
+ // if (this.options?.enablePubSub) {
180
+ // await this.redis.publish(
181
+ // 'spectify:invalidate',
182
+ // JSON.stringify({ documentId, jobIds })
183
+ // );
184
+ // }
185
+ //
186
+ // return jobIds.length;
187
+ }
188
+ /**
189
+ * Get storage statistics
190
+ *
191
+ * TODO: Implement stats collection
192
+ */
193
+ async getStats() {
194
+ throw new Error('RedisLintStorage.getStats: TODO - Not implemented');
195
+ // TODO: Implementation
196
+ // const pattern = `${this.options?.keyPrefix || 'spectify:lint:'}job:*`;
197
+ // const keys = await this.redis.keys(pattern);
198
+ //
199
+ // return {
200
+ // totalJobs: keys.length,
201
+ // totalResults: 0, // Would need to scan all jobs
202
+ // storageSize: await this.redis.dbsize()
203
+ // };
204
+ }
205
+ /**
206
+ * Clear all data
207
+ *
208
+ * TODO: Implement clear
209
+ */
210
+ async clear() {
211
+ throw new Error('RedisLintStorage.clear: TODO - Not implemented');
212
+ // TODO: Implementation
213
+ // const pattern = `${this.options?.keyPrefix || 'spectify:lint:'}*`;
214
+ // const keys = await this.redis.keys(pattern);
215
+ //
216
+ // if (keys.length > 0) {
217
+ // await this.redis.del(...keys);
218
+ // }
219
+ //
220
+ // return keys.length;
221
+ }
222
+ /**
223
+ * Close Redis connection
224
+ *
225
+ * TODO: Implement cleanup
226
+ */
227
+ async close() {
228
+ throw new Error('RedisLintStorage.close: TODO - Not implemented');
229
+ // TODO: Implementation
230
+ // if (this.redis) {
231
+ // await this.redis.quit();
232
+ // this.redis = undefined;
233
+ // }
234
+ }
235
+ }
236
+ //# sourceMappingURL=redis-storage.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"redis-storage.js","sourceRoot":"","sources":["../../src/storage/redis-storage.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,189 @@
1
+ /**
2
+ * Storage Adapter Interface for OpenAPI Lint Orchestrator
3
+ *
4
+ * Defines the contract for storing and retrieving lint job results.
5
+ * Implementations can use different backends (memory, Redis, database, etc.)
6
+ *
7
+ * @module storage/storage-adapter
8
+ */
9
+ import type { LintJobResult, ListJobsOptions, JobSummary, DocumentLintActivity, LintResultQueryOptions, PaginatedLintResult, LintResultStats } from '../types.js';
10
+ /**
11
+ * Storage configuration options
12
+ */
13
+ export interface StorageOptions {
14
+ /**
15
+ * Time-to-live for cached results in seconds
16
+ * If undefined, results never expire
17
+ */
18
+ ttl?: number;
19
+ /**
20
+ * Additional backend-specific options
21
+ */
22
+ [key: string]: any;
23
+ }
24
+ /**
25
+ * Storage statistics
26
+ */
27
+ export interface StorageStats {
28
+ /**
29
+ * Total number of jobs stored
30
+ */
31
+ totalJobs: number;
32
+ /**
33
+ * Total number of results across all jobs
34
+ */
35
+ totalResults: number;
36
+ /**
37
+ * Approximate storage size in bytes (if available)
38
+ */
39
+ storageSize?: number;
40
+ /**
41
+ * Number of expired entries (if TTL enabled)
42
+ */
43
+ expiredEntries?: number;
44
+ /**
45
+ * Failure statistics
46
+ */
47
+ failureStats?: {
48
+ totalFailed: number;
49
+ totalTimeout: number;
50
+ totalCompleted: number;
51
+ failureRate: number;
52
+ };
53
+ /**
54
+ * Backend-specific metrics
55
+ */
56
+ [key: string]: any;
57
+ }
58
+ /**
59
+ * Abstract storage adapter interface
60
+ *
61
+ * All storage implementations must implement this interface.
62
+ * Provides methods for storing, retrieving, and managing lint job results.
63
+ */
64
+ export interface LintResultStorage {
65
+ /**
66
+ * Initialize the storage backend
67
+ *
68
+ * @param options - Storage configuration options
69
+ */
70
+ initialize?(options?: StorageOptions): Promise<void>;
71
+ /**
72
+ * Store complete job result
73
+ *
74
+ * @param result - The complete lint job result
75
+ * @throws {Error} If storage operation fails
76
+ */
77
+ storeJob(result: LintJobResult): Promise<void>;
78
+ /**
79
+ * Retrieve job result by job ID
80
+ *
81
+ * @param jobId - The unique job identifier
82
+ * @returns The job result, or null if not found or expired
83
+ */
84
+ retrieveJobById(jobId: string): Promise<LintJobResult | null>;
85
+ /**
86
+ * Retrieve job result by document + ruleset combination
87
+ *
88
+ * Useful for checking if results already exist for a specific
89
+ * document and ruleset combination (caching).
90
+ *
91
+ * @param documentId - The document identifier
92
+ * @param rulesetName - The ruleset name
93
+ * @param rulesetVersion - The ruleset version
94
+ * @returns The most recent job result, or null if not found or expired
95
+ */
96
+ retrieveJob(documentId: string, rulesetName: string, rulesetVersion: string): Promise<LintJobResult | null>;
97
+ /**
98
+ * Check if cached results exist for a document + ruleset
99
+ *
100
+ * More efficient than retrieveJob when you only need existence check.
101
+ *
102
+ * @param documentId - The document identifier
103
+ * @param rulesetName - The ruleset name
104
+ * @param rulesetVersion - The ruleset version
105
+ * @returns True if results exist and haven't expired
106
+ */
107
+ exists(documentId: string, rulesetName: string, rulesetVersion: string): Promise<boolean>;
108
+ /**
109
+ * Invalidate all results for a specific document
110
+ *
111
+ * Useful when a document is updated and all cached results
112
+ * should be discarded.
113
+ *
114
+ * @param documentId - The document identifier
115
+ * @returns Number of invalidated jobs
116
+ */
117
+ invalidate(documentId: string): Promise<number>;
118
+ /**
119
+ * Get storage statistics
120
+ *
121
+ * @returns Storage statistics including total jobs, results, and size
122
+ */
123
+ getStats(): Promise<StorageStats>;
124
+ /**
125
+ * List jobs with filtering and pagination
126
+ *
127
+ * @param options - Filter and pagination options
128
+ * @returns Array of job summaries (lightweight, documentId only)
129
+ */
130
+ listJobs?(options?: ListJobsOptions): Promise<JobSummary[]>;
131
+ /**
132
+ * Retrieve job results with pagination and filtering
133
+ *
134
+ * @param jobId - The unique job identifier
135
+ * @param options - Pagination and filter options
136
+ * @returns Paginated result set with metadata
137
+ */
138
+ queryJobResults?(jobId: string, options: LintResultQueryOptions): Promise<PaginatedLintResult | null>;
139
+ /**
140
+ * Get aggregated statistics for a job's lint results
141
+ *
142
+ * @param jobId - The unique job identifier
143
+ * @returns Aggregated stats including rule breakdown and top paths
144
+ */
145
+ getJobStats?(jobId: string): Promise<LintResultStats | null>;
146
+ /**
147
+ * Get lint activity for a specific document
148
+ *
149
+ * @param documentId - The document identifier
150
+ * @returns Document lint activity summary
151
+ */
152
+ getDocumentLintActivity?(documentId: string): Promise<DocumentLintActivity | null>;
153
+ /**
154
+ * Clear all stored data
155
+ *
156
+ * USE WITH CAUTION: This removes all job results.
157
+ *
158
+ * @returns Number of jobs cleared
159
+ */
160
+ clear?(): Promise<number>;
161
+ /**
162
+ * Close/cleanup storage connection
163
+ *
164
+ * Called during graceful shutdown. Implementations should
165
+ * close connections, flush buffers, etc.
166
+ */
167
+ close?(): Promise<void>;
168
+ }
169
+ /**
170
+ * Create composite key for document + ruleset lookups
171
+ *
172
+ * @param documentId - The document identifier
173
+ * @param rulesetName - The ruleset name
174
+ * @param rulesetVersion - The ruleset version
175
+ * @returns Composite key string
176
+ */
177
+ export declare function makeCompositeKey(documentId: string, rulesetName: string, rulesetVersion: string): string;
178
+ /**
179
+ * Parse composite key back into components
180
+ *
181
+ * @param key - Composite key string
182
+ * @returns Parsed components or null if invalid
183
+ */
184
+ export declare function parseCompositeKey(key: string): {
185
+ documentId: string;
186
+ rulesetName: string;
187
+ rulesetVersion: string;
188
+ } | null;
189
+ //# sourceMappingURL=storage-adapter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"storage-adapter.d.ts","sourceRoot":"","sources":["../../src/storage/storage-adapter.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,36 @@
1
+ /**
2
+ * Storage Adapter Interface for OpenAPI Lint Orchestrator
3
+ *
4
+ * Defines the contract for storing and retrieving lint job results.
5
+ * Implementations can use different backends (memory, Redis, database, etc.)
6
+ *
7
+ * @module storage/storage-adapter
8
+ */
9
+ /**
10
+ * Create composite key for document + ruleset lookups
11
+ *
12
+ * @param documentId - The document identifier
13
+ * @param rulesetName - The ruleset name
14
+ * @param rulesetVersion - The ruleset version
15
+ * @returns Composite key string
16
+ */
17
+ export function makeCompositeKey(documentId, rulesetName, rulesetVersion) {
18
+ return `${documentId}:${rulesetName}:${rulesetVersion}`;
19
+ }
20
+ /**
21
+ * Parse composite key back into components
22
+ *
23
+ * @param key - Composite key string
24
+ * @returns Parsed components or null if invalid
25
+ */
26
+ export function parseCompositeKey(key) {
27
+ const parts = key.split(':');
28
+ if (parts.length !== 3)
29
+ return null;
30
+ return {
31
+ documentId: parts[0],
32
+ rulesetName: parts[1],
33
+ rulesetVersion: parts[2]
34
+ };
35
+ }
36
+ //# sourceMappingURL=storage-adapter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"storage-adapter.js","sourceRoot":"","sources":["../../src/storage/storage-adapter.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAgMH;;;;;;;GAOG;AACH,MAAM,UAAU,gBAAgB,CAC9B,UAAkB,EAClB,WAAmB,EACnB,cAAsB;IAEtB,OAAO,GAAG,UAAU,IAAI,WAAW,IAAI,cAAc,EAAE,CAAC;AAC1D,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,iBAAiB,CAAC,GAAW;IAK3C,MAAM,KAAK,GAAG,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IAC7B,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,IAAI,CAAC;IAEpC,OAAO;QACL,UAAU,EAAE,KAAK,CAAC,CAAC,CAAC;QACpB,WAAW,EAAE,KAAK,CAAC,CAAC,CAAC;QACrB,cAAc,EAAE,KAAK,CAAC,CAAC,CAAC;KACzB,CAAC;AACJ,CAAC"}