anz-legislation 1.2.1
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/LICENSE +201 -0
- package/README.md +23 -0
- package/dist/cli.d.ts +6 -0
- package/dist/cli.js +198 -0
- package/dist/client.d.ts +84 -0
- package/dist/client.js +492 -0
- package/dist/commands/batch.d.ts +5 -0
- package/dist/commands/batch.js +121 -0
- package/dist/commands/cache.d.ts +5 -0
- package/dist/commands/cache.js +43 -0
- package/dist/commands/cite.d.ts +5 -0
- package/dist/commands/cite.js +68 -0
- package/dist/commands/config.d.ts +5 -0
- package/dist/commands/config.js +56 -0
- package/dist/commands/export.d.ts +8 -0
- package/dist/commands/export.js +169 -0
- package/dist/commands/generate.d.ts +10 -0
- package/dist/commands/generate.js +320 -0
- package/dist/commands/get.d.ts +5 -0
- package/dist/commands/get.js +99 -0
- package/dist/commands/help.d.ts +13 -0
- package/dist/commands/help.js +298 -0
- package/dist/commands/search.d.ts +5 -0
- package/dist/commands/search.js +96 -0
- package/dist/commands/stream.d.ts +5 -0
- package/dist/commands/stream.js +100 -0
- package/dist/config.d.ts +81 -0
- package/dist/config.js +209 -0
- package/dist/errors.d.ts +108 -0
- package/dist/errors.js +173 -0
- package/dist/mcp/server.d.ts +13 -0
- package/dist/mcp/server.js +428 -0
- package/dist/mcp-cli.d.ts +6 -0
- package/dist/mcp-cli.js +37 -0
- package/dist/models/canonical.d.ts +423 -0
- package/dist/models/canonical.js +92 -0
- package/dist/models/index.d.ts +892 -0
- package/dist/models/index.js +223 -0
- package/dist/output/index.d.ts +34 -0
- package/dist/output/index.js +195 -0
- package/dist/output/legal-metadata-publication.d.ts +18 -0
- package/dist/output/legal-metadata-publication.js +23 -0
- package/dist/providers/canonical-metadata.d.ts +3 -0
- package/dist/providers/canonical-metadata.js +202 -0
- package/dist/providers/commonwealth-provider.d.ts +27 -0
- package/dist/providers/commonwealth-provider.js +81 -0
- package/dist/providers/index.d.ts +20 -0
- package/dist/providers/index.js +27 -0
- package/dist/providers/legislation-provider.d.ts +227 -0
- package/dist/providers/legislation-provider.js +308 -0
- package/dist/providers/nz-provider.d.ts +36 -0
- package/dist/providers/nz-provider.js +130 -0
- package/dist/providers/output-adapters.d.ts +14 -0
- package/dist/providers/output-adapters.js +116 -0
- package/dist/providers/plugin-discovery.d.ts +39 -0
- package/dist/providers/plugin-discovery.js +91 -0
- package/dist/providers/plugin-loader.d.ts +86 -0
- package/dist/providers/plugin-loader.js +219 -0
- package/dist/providers/queensland-provider.d.ts +42 -0
- package/dist/providers/queensland-provider.js +105 -0
- package/dist/utils/api-optimization.d.ts +92 -0
- package/dist/utils/api-optimization.js +276 -0
- package/dist/utils/batch.d.ts +110 -0
- package/dist/utils/batch.js +269 -0
- package/dist/utils/branded-types.d.ts +0 -0
- package/dist/utils/branded-types.js +1 -0
- package/dist/utils/compatibility-matrix.d.ts +89 -0
- package/dist/utils/compatibility-matrix.js +214 -0
- package/dist/utils/config-validator.d.ts +39 -0
- package/dist/utils/config-validator.js +197 -0
- package/dist/utils/env-loader.d.ts +55 -0
- package/dist/utils/env-loader.js +77 -0
- package/dist/utils/health-monitor.d.ts +93 -0
- package/dist/utils/health-monitor.js +209 -0
- package/dist/utils/invocation.d.ts +4 -0
- package/dist/utils/invocation.js +33 -0
- package/dist/utils/logger.d.ts +94 -0
- package/dist/utils/logger.js +220 -0
- package/dist/utils/plugin-marketplace.d.ts +77 -0
- package/dist/utils/plugin-marketplace.js +191 -0
- package/dist/utils/presentation.d.ts +2 -0
- package/dist/utils/presentation.js +32 -0
- package/dist/utils/rate-limiter.d.ts +100 -0
- package/dist/utils/rate-limiter.js +256 -0
- package/dist/utils/scraper-cache.d.ts +115 -0
- package/dist/utils/scraper-cache.js +229 -0
- package/dist/utils/secure-config.d.ts +40 -0
- package/dist/utils/secure-config.js +195 -0
- package/dist/utils/streaming.d.ts +121 -0
- package/dist/utils/streaming.js +333 -0
- package/dist/utils/validation.d.ts +190 -0
- package/dist/utils/validation.js +209 -0
- package/dist/utils/version.d.ts +13 -0
- package/dist/utils/version.js +46 -0
- package/package.json +56 -0
|
@@ -0,0 +1,333 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Streaming Utilities
|
|
3
|
+
*
|
|
4
|
+
* Provides streaming support for large data exports to minimize memory usage.
|
|
5
|
+
* Allows exporting GBs of data without running out of memory.
|
|
6
|
+
*/
|
|
7
|
+
import { createWriteStream } from 'fs';
|
|
8
|
+
import { Readable } from 'stream';
|
|
9
|
+
import { pipeline } from 'stream/promises';
|
|
10
|
+
import { searchWorks, getWork } from '@client';
|
|
11
|
+
/**
|
|
12
|
+
* Stream exporter with progress tracking
|
|
13
|
+
*/
|
|
14
|
+
export class StreamExporter {
|
|
15
|
+
outputPath;
|
|
16
|
+
format;
|
|
17
|
+
includeMetadata;
|
|
18
|
+
batchSize;
|
|
19
|
+
maxResults;
|
|
20
|
+
concurrency;
|
|
21
|
+
writeStream;
|
|
22
|
+
bytesWritten = 0;
|
|
23
|
+
processed = 0;
|
|
24
|
+
aborted = false;
|
|
25
|
+
constructor(options) {
|
|
26
|
+
this.outputPath = options.outputPath;
|
|
27
|
+
this.format = options.format;
|
|
28
|
+
this.includeMetadata = options.includeMetadata ?? false;
|
|
29
|
+
this.batchSize = options.batchSize ?? 100;
|
|
30
|
+
this.maxResults = options.maxResults ?? Infinity;
|
|
31
|
+
this.concurrency = options.concurrency ?? 3;
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Export search results to file using streaming
|
|
35
|
+
*/
|
|
36
|
+
async export(params, onProgress) {
|
|
37
|
+
const startTime = Date.now();
|
|
38
|
+
// Create write stream
|
|
39
|
+
this.writeStream = createWriteStream(this.outputPath, {
|
|
40
|
+
encoding: 'utf-8',
|
|
41
|
+
highWaterMark: 64 * 1024, // 64KB chunks
|
|
42
|
+
});
|
|
43
|
+
try {
|
|
44
|
+
// Write header based on format
|
|
45
|
+
if (this.format === 'csv') {
|
|
46
|
+
this.writeCsvHeader();
|
|
47
|
+
}
|
|
48
|
+
else if (this.format === 'json') {
|
|
49
|
+
this.writeStream.write('[\n');
|
|
50
|
+
}
|
|
51
|
+
// NDJSON doesn't need a header
|
|
52
|
+
let offset = 0;
|
|
53
|
+
let totalFetched = 0;
|
|
54
|
+
let hasMore = true;
|
|
55
|
+
while (hasMore && !this.aborted) {
|
|
56
|
+
// Fetch batch
|
|
57
|
+
const results = await searchWorks({
|
|
58
|
+
...params,
|
|
59
|
+
limit: this.batchSize,
|
|
60
|
+
offset,
|
|
61
|
+
});
|
|
62
|
+
if (results.results.length === 0) {
|
|
63
|
+
hasMore = false;
|
|
64
|
+
break;
|
|
65
|
+
}
|
|
66
|
+
// Process and write each result
|
|
67
|
+
for (const work of results.results) {
|
|
68
|
+
if (this.aborted) {
|
|
69
|
+
break;
|
|
70
|
+
}
|
|
71
|
+
if (totalFetched >= this.maxResults) {
|
|
72
|
+
hasMore = false;
|
|
73
|
+
break;
|
|
74
|
+
}
|
|
75
|
+
this.writeWork(work, totalFetched === 0 && this.format === 'json');
|
|
76
|
+
this.processed++;
|
|
77
|
+
totalFetched++;
|
|
78
|
+
// Progress callback
|
|
79
|
+
if (onProgress) {
|
|
80
|
+
onProgress({
|
|
81
|
+
processed: this.processed,
|
|
82
|
+
total: results.total,
|
|
83
|
+
bytesWritten: this.bytesWritten,
|
|
84
|
+
percent: results.total > 0 ? Math.round((this.processed / results.total) * 100) : 0,
|
|
85
|
+
estimatedTimeRemaining: this.calculateETA(startTime, this.processed),
|
|
86
|
+
});
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
offset += this.batchSize;
|
|
90
|
+
}
|
|
91
|
+
// Write footer based on format
|
|
92
|
+
if (this.format === 'json') {
|
|
93
|
+
this.writeStream.write('\n]');
|
|
94
|
+
}
|
|
95
|
+
// Include metadata if requested
|
|
96
|
+
if (this.includeMetadata && this.format !== 'ndjson') {
|
|
97
|
+
this.writeMetadata(params, totalFetched);
|
|
98
|
+
}
|
|
99
|
+
// Close stream
|
|
100
|
+
await this.closeStream();
|
|
101
|
+
return {
|
|
102
|
+
processed: this.processed,
|
|
103
|
+
bytesWritten: this.bytesWritten,
|
|
104
|
+
};
|
|
105
|
+
}
|
|
106
|
+
catch (error) {
|
|
107
|
+
this.writeStream.destroy();
|
|
108
|
+
throw error;
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
/**
|
|
112
|
+
* Stream work details for multiple works
|
|
113
|
+
*/
|
|
114
|
+
async exportWorkDetails(workIds, outputPath, format = 'json', onProgress) {
|
|
115
|
+
const writeStream = createWriteStream(outputPath, {
|
|
116
|
+
encoding: 'utf-8',
|
|
117
|
+
highWaterMark: 64 * 1024,
|
|
118
|
+
});
|
|
119
|
+
const startTime = Date.now();
|
|
120
|
+
let processed = 0;
|
|
121
|
+
let bytesWritten = 0;
|
|
122
|
+
try {
|
|
123
|
+
if (format === 'json') {
|
|
124
|
+
writeStream.write('[\n');
|
|
125
|
+
}
|
|
126
|
+
for (let i = 0; i < workIds.length; i++) {
|
|
127
|
+
const workId = workIds[i];
|
|
128
|
+
try {
|
|
129
|
+
const work = await getWork(workId);
|
|
130
|
+
const line = format === 'json'
|
|
131
|
+
? (i > 0 ? ',\n' : '') + JSON.stringify(work, null, 2)
|
|
132
|
+
: JSON.stringify(work) + '\n';
|
|
133
|
+
writeStream.write(line);
|
|
134
|
+
bytesWritten += line.length;
|
|
135
|
+
processed++;
|
|
136
|
+
if (onProgress) {
|
|
137
|
+
onProgress({
|
|
138
|
+
processed,
|
|
139
|
+
total: workIds.length,
|
|
140
|
+
bytesWritten,
|
|
141
|
+
percent: Math.round((processed / workIds.length) * 100),
|
|
142
|
+
estimatedTimeRemaining: this.calculateETA(startTime, processed),
|
|
143
|
+
});
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
catch (error) {
|
|
147
|
+
// Log error but continue
|
|
148
|
+
console.error(`Failed to fetch work ${workId}:`, error.message);
|
|
149
|
+
}
|
|
150
|
+
// Rate limiting - small delay between requests
|
|
151
|
+
if (i < workIds.length - 1) {
|
|
152
|
+
await new Promise(resolve => setTimeout(resolve, 100));
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
if (format === 'json') {
|
|
156
|
+
writeStream.write('\n]');
|
|
157
|
+
}
|
|
158
|
+
await new Promise((resolve, reject) => {
|
|
159
|
+
writeStream.end(resolve);
|
|
160
|
+
writeStream.on('error', reject);
|
|
161
|
+
});
|
|
162
|
+
return { processed, bytesWritten };
|
|
163
|
+
}
|
|
164
|
+
catch (error) {
|
|
165
|
+
writeStream.destroy();
|
|
166
|
+
throw error;
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
/**
|
|
170
|
+
* Abort the streaming export
|
|
171
|
+
*/
|
|
172
|
+
abort() {
|
|
173
|
+
this.aborted = true;
|
|
174
|
+
}
|
|
175
|
+
/**
|
|
176
|
+
* Write CSV header
|
|
177
|
+
*/
|
|
178
|
+
writeCsvHeader() {
|
|
179
|
+
const header = 'id,title,shortTitle,type,status,date,url,versionCount\n';
|
|
180
|
+
this.writeStream.write(header);
|
|
181
|
+
this.bytesWritten += header.length;
|
|
182
|
+
}
|
|
183
|
+
/**
|
|
184
|
+
* Write work to stream
|
|
185
|
+
*/
|
|
186
|
+
writeWork(work, isFirst) {
|
|
187
|
+
let line = '';
|
|
188
|
+
switch (this.format) {
|
|
189
|
+
case 'csv':
|
|
190
|
+
line = this.formatCsvRow(work);
|
|
191
|
+
break;
|
|
192
|
+
case 'json':
|
|
193
|
+
line = (isFirst ? '' : ',\n') + JSON.stringify(work, null, 2);
|
|
194
|
+
break;
|
|
195
|
+
case 'ndjson':
|
|
196
|
+
line = JSON.stringify(work) + '\n';
|
|
197
|
+
break;
|
|
198
|
+
}
|
|
199
|
+
this.writeStream.write(line);
|
|
200
|
+
this.bytesWritten += line.length;
|
|
201
|
+
}
|
|
202
|
+
/**
|
|
203
|
+
* Format work as CSV row
|
|
204
|
+
*/
|
|
205
|
+
formatCsvRow(work) {
|
|
206
|
+
// Escape CSV fields
|
|
207
|
+
const escape = (str) => {
|
|
208
|
+
if (str.includes(',') || str.includes('"') || str.includes('\n')) {
|
|
209
|
+
return `"${str.replace(/"/g, '""')}"`;
|
|
210
|
+
}
|
|
211
|
+
return str;
|
|
212
|
+
};
|
|
213
|
+
return ([
|
|
214
|
+
work.id,
|
|
215
|
+
escape(work.title),
|
|
216
|
+
work.shortTitle ? escape(work.shortTitle) : '',
|
|
217
|
+
work.type,
|
|
218
|
+
work.status,
|
|
219
|
+
work.date,
|
|
220
|
+
work.url,
|
|
221
|
+
work.versionCount.toString(),
|
|
222
|
+
].join(',') + '\n');
|
|
223
|
+
}
|
|
224
|
+
/**
|
|
225
|
+
* Write metadata at end of file
|
|
226
|
+
*/
|
|
227
|
+
writeMetadata(params, totalResults) {
|
|
228
|
+
const metadata = {
|
|
229
|
+
_metadata: {
|
|
230
|
+
exportedAt: new Date().toISOString(),
|
|
231
|
+
query: params.query,
|
|
232
|
+
totalResults,
|
|
233
|
+
format: this.format,
|
|
234
|
+
},
|
|
235
|
+
};
|
|
236
|
+
if (this.format === 'csv') {
|
|
237
|
+
this.writeStream.write('\n# Metadata\n');
|
|
238
|
+
this.writeStream.write(`# Exported: ${metadata._metadata.exportedAt}\n`);
|
|
239
|
+
this.writeStream.write(`# Query: ${params.query}\n`);
|
|
240
|
+
this.writeStream.write(`# Total: ${totalResults}\n`);
|
|
241
|
+
}
|
|
242
|
+
else {
|
|
243
|
+
this.writeStream.write(',\n');
|
|
244
|
+
this.writeStream.write(JSON.stringify(metadata, null, 2));
|
|
245
|
+
}
|
|
246
|
+
this.bytesWritten += JSON.stringify(metadata).length;
|
|
247
|
+
}
|
|
248
|
+
/**
|
|
249
|
+
* Close write stream
|
|
250
|
+
*/
|
|
251
|
+
async closeStream() {
|
|
252
|
+
return new Promise((resolve, reject) => {
|
|
253
|
+
this.writeStream.end(() => {
|
|
254
|
+
resolve();
|
|
255
|
+
});
|
|
256
|
+
this.writeStream.on('error', reject);
|
|
257
|
+
});
|
|
258
|
+
}
|
|
259
|
+
/**
|
|
260
|
+
* Calculate estimated time remaining
|
|
261
|
+
*/
|
|
262
|
+
calculateETA(startTime, processed) {
|
|
263
|
+
if (processed === 0) {
|
|
264
|
+
return undefined;
|
|
265
|
+
}
|
|
266
|
+
const elapsed = Date.now() - startTime;
|
|
267
|
+
const avgTimePerItem = elapsed / processed;
|
|
268
|
+
const remaining = this.maxResults - processed;
|
|
269
|
+
return Math.round(avgTimePerItem * remaining);
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
/**
|
|
273
|
+
* Create a readable stream from paginated API results
|
|
274
|
+
*/
|
|
275
|
+
export function createPaginatedStream(params, options = {}) {
|
|
276
|
+
const batchSize = options.batchSize ?? 100;
|
|
277
|
+
let offset = 0;
|
|
278
|
+
let hasMore = true;
|
|
279
|
+
let pending = null;
|
|
280
|
+
return new Readable({
|
|
281
|
+
objectMode: true,
|
|
282
|
+
read() {
|
|
283
|
+
if (pending) {
|
|
284
|
+
return;
|
|
285
|
+
}
|
|
286
|
+
if (!hasMore) {
|
|
287
|
+
this.push(null);
|
|
288
|
+
return;
|
|
289
|
+
}
|
|
290
|
+
pending = (async () => {
|
|
291
|
+
try {
|
|
292
|
+
const results = await searchWorks({
|
|
293
|
+
...params,
|
|
294
|
+
limit: batchSize,
|
|
295
|
+
offset,
|
|
296
|
+
});
|
|
297
|
+
if (results.results.length === 0) {
|
|
298
|
+
hasMore = false;
|
|
299
|
+
this.push(null);
|
|
300
|
+
return;
|
|
301
|
+
}
|
|
302
|
+
for (const work of results.results) {
|
|
303
|
+
this.push(work);
|
|
304
|
+
}
|
|
305
|
+
offset += batchSize;
|
|
306
|
+
}
|
|
307
|
+
catch (error) {
|
|
308
|
+
this.destroy(error);
|
|
309
|
+
}
|
|
310
|
+
finally {
|
|
311
|
+
pending = null;
|
|
312
|
+
}
|
|
313
|
+
})();
|
|
314
|
+
},
|
|
315
|
+
});
|
|
316
|
+
}
|
|
317
|
+
/**
|
|
318
|
+
* Stream processing pipeline
|
|
319
|
+
*
|
|
320
|
+
* Example usage:
|
|
321
|
+
* ```typescript
|
|
322
|
+
* const stream = createPaginatedStream({ query: 'health' });
|
|
323
|
+
* const transformed = stream.pipe(new Transform({
|
|
324
|
+
* objectMode: true,
|
|
325
|
+
* transform(work, encoding, callback) {
|
|
326
|
+
* callback(null, { id: work.work_id, title: work.title });
|
|
327
|
+
* }
|
|
328
|
+
* }));
|
|
329
|
+
*
|
|
330
|
+
* await pipeline(stream, transformed, createWriteStream('output.json'));
|
|
331
|
+
* ```
|
|
332
|
+
*/
|
|
333
|
+
export { pipeline };
|
|
@@ -0,0 +1,190 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Input validation schemas using Zod
|
|
3
|
+
* Provides runtime validation for all user inputs
|
|
4
|
+
*/
|
|
5
|
+
import { z } from 'zod';
|
|
6
|
+
/**
|
|
7
|
+
* Date string in YYYY-MM-DD format
|
|
8
|
+
*/
|
|
9
|
+
export declare const DateStringSchema: z.ZodEffects<z.ZodString, string, string>;
|
|
10
|
+
/**
|
|
11
|
+
* Work ID validation for current API work IDs (e.g., act_public_1989_18)
|
|
12
|
+
*/
|
|
13
|
+
export declare const WorkIdSchema: z.ZodString;
|
|
14
|
+
/**
|
|
15
|
+
* Search query validation
|
|
16
|
+
*/
|
|
17
|
+
export declare const SearchQuerySchema: z.ZodString;
|
|
18
|
+
/**
|
|
19
|
+
* Legislation type validation
|
|
20
|
+
*/
|
|
21
|
+
export declare const LegislationTypeSchema: z.ZodOptional<z.ZodEnum<["act", "bill", "regulation", "instrument"]>>;
|
|
22
|
+
/**
|
|
23
|
+
* Legislation status validation
|
|
24
|
+
*/
|
|
25
|
+
export declare const LegislationStatusSchema: z.ZodOptional<z.ZodEnum<["in-force", "not-yet-in-force", "repealed", "partially-repealed", "withdrawn"]>>;
|
|
26
|
+
/**
|
|
27
|
+
* Output format validation
|
|
28
|
+
*/
|
|
29
|
+
export declare const OutputFormatSchema: z.ZodDefault<z.ZodEnum<["table", "json", "csv"]>>;
|
|
30
|
+
/**
|
|
31
|
+
* Pagination limit validation
|
|
32
|
+
*/
|
|
33
|
+
export declare const LimitSchema: z.ZodEffects<z.ZodDefault<z.ZodString>, number, string | undefined>;
|
|
34
|
+
/**
|
|
35
|
+
* Pagination offset validation
|
|
36
|
+
*/
|
|
37
|
+
export declare const OffsetSchema: z.ZodEffects<z.ZodDefault<z.ZodString>, number, string | undefined>;
|
|
38
|
+
/**
|
|
39
|
+
* Search parameters schema
|
|
40
|
+
*/
|
|
41
|
+
export declare const SearchParamsSchema: z.ZodObject<{
|
|
42
|
+
query: z.ZodString;
|
|
43
|
+
type: z.ZodOptional<z.ZodEnum<["act", "bill", "regulation", "instrument"]>>;
|
|
44
|
+
status: z.ZodOptional<z.ZodEnum<["in-force", "not-yet-in-force", "repealed", "partially-repealed", "withdrawn"]>>;
|
|
45
|
+
from: z.ZodOptional<z.ZodEffects<z.ZodString, string, string>>;
|
|
46
|
+
to: z.ZodOptional<z.ZodEffects<z.ZodString, string, string>>;
|
|
47
|
+
limit: z.ZodEffects<z.ZodDefault<z.ZodString>, number, string | undefined>;
|
|
48
|
+
offset: z.ZodEffects<z.ZodDefault<z.ZodString>, number, string | undefined>;
|
|
49
|
+
format: z.ZodDefault<z.ZodEnum<["table", "json", "csv"]>>;
|
|
50
|
+
}, "strip", z.ZodTypeAny, {
|
|
51
|
+
format: "json" | "table" | "csv";
|
|
52
|
+
offset: number;
|
|
53
|
+
limit: number;
|
|
54
|
+
query: string;
|
|
55
|
+
type?: "act" | "bill" | "regulation" | "instrument" | undefined;
|
|
56
|
+
status?: "not-yet-in-force" | "in-force" | "repealed" | "withdrawn" | "partially-repealed" | undefined;
|
|
57
|
+
from?: string | undefined;
|
|
58
|
+
to?: string | undefined;
|
|
59
|
+
}, {
|
|
60
|
+
query: string;
|
|
61
|
+
type?: "act" | "bill" | "regulation" | "instrument" | undefined;
|
|
62
|
+
status?: "not-yet-in-force" | "in-force" | "repealed" | "withdrawn" | "partially-repealed" | undefined;
|
|
63
|
+
format?: "json" | "table" | "csv" | undefined;
|
|
64
|
+
offset?: string | undefined;
|
|
65
|
+
limit?: string | undefined;
|
|
66
|
+
from?: string | undefined;
|
|
67
|
+
to?: string | undefined;
|
|
68
|
+
}>;
|
|
69
|
+
/**
|
|
70
|
+
* Get work parameters schema
|
|
71
|
+
*/
|
|
72
|
+
export declare const GetWorkParamsSchema: z.ZodObject<{
|
|
73
|
+
workId: z.ZodString;
|
|
74
|
+
versions: z.ZodDefault<z.ZodBoolean>;
|
|
75
|
+
format: z.ZodDefault<z.ZodEnum<["table", "json", "csv"]>>;
|
|
76
|
+
}, "strip", z.ZodTypeAny, {
|
|
77
|
+
format: "json" | "table" | "csv";
|
|
78
|
+
workId: string;
|
|
79
|
+
versions: boolean;
|
|
80
|
+
}, {
|
|
81
|
+
workId: string;
|
|
82
|
+
format?: "json" | "table" | "csv" | undefined;
|
|
83
|
+
versions?: boolean | undefined;
|
|
84
|
+
}>;
|
|
85
|
+
/**
|
|
86
|
+
* Citation style validation
|
|
87
|
+
*/
|
|
88
|
+
export declare const CitationStyleSchema: z.ZodDefault<z.ZodEnum<["nzmj", "bibtex", "ris", "enw", "apa"]>>;
|
|
89
|
+
/**
|
|
90
|
+
* Export parameters schema
|
|
91
|
+
*/
|
|
92
|
+
export declare const ExportParamsSchema: z.ZodObject<{
|
|
93
|
+
query: z.ZodString;
|
|
94
|
+
output: z.ZodString;
|
|
95
|
+
type: z.ZodOptional<z.ZodEnum<["act", "bill", "regulation", "instrument"]>>;
|
|
96
|
+
status: z.ZodOptional<z.ZodEnum<["in-force", "not-yet-in-force", "repealed", "partially-repealed", "withdrawn"]>>;
|
|
97
|
+
from: z.ZodOptional<z.ZodEffects<z.ZodString, string, string>>;
|
|
98
|
+
to: z.ZodOptional<z.ZodEffects<z.ZodString, string, string>>;
|
|
99
|
+
limit: z.ZodEffects<z.ZodDefault<z.ZodString>, number, string | undefined>;
|
|
100
|
+
}, "strip", z.ZodTypeAny, {
|
|
101
|
+
limit: number;
|
|
102
|
+
query: string;
|
|
103
|
+
output: string;
|
|
104
|
+
type?: "act" | "bill" | "regulation" | "instrument" | undefined;
|
|
105
|
+
status?: "not-yet-in-force" | "in-force" | "repealed" | "withdrawn" | "partially-repealed" | undefined;
|
|
106
|
+
from?: string | undefined;
|
|
107
|
+
to?: string | undefined;
|
|
108
|
+
}, {
|
|
109
|
+
query: string;
|
|
110
|
+
output: string;
|
|
111
|
+
type?: "act" | "bill" | "regulation" | "instrument" | undefined;
|
|
112
|
+
status?: "not-yet-in-force" | "in-force" | "repealed" | "withdrawn" | "partially-repealed" | undefined;
|
|
113
|
+
limit?: string | undefined;
|
|
114
|
+
from?: string | undefined;
|
|
115
|
+
to?: string | undefined;
|
|
116
|
+
}>;
|
|
117
|
+
/**
|
|
118
|
+
* Configuration key validation
|
|
119
|
+
*/
|
|
120
|
+
export declare const ConfigKeySchema: z.ZodEnum<["apiKey", "baseUrl", "timeout", "cacheEnabled", "cacheTTL", "rateLimitPerMinute", "outputFormat", "verbose"]>;
|
|
121
|
+
/**
|
|
122
|
+
* API URL validation
|
|
123
|
+
*/
|
|
124
|
+
export declare const ApiUrlSchema: z.ZodEffects<z.ZodString, string, string>;
|
|
125
|
+
/**
|
|
126
|
+
* Timeout validation (in milliseconds)
|
|
127
|
+
*/
|
|
128
|
+
export declare const TimeoutSchema: z.ZodEffects<z.ZodDefault<z.ZodString>, number, string | undefined>;
|
|
129
|
+
/**
|
|
130
|
+
* Validation error type
|
|
131
|
+
*/
|
|
132
|
+
export interface ValidationError {
|
|
133
|
+
field: string;
|
|
134
|
+
message: string;
|
|
135
|
+
value?: unknown;
|
|
136
|
+
}
|
|
137
|
+
/**
|
|
138
|
+
* Validate input against schema and return formatted errors
|
|
139
|
+
*/
|
|
140
|
+
export declare function validateInput<T>(schema: z.ZodSchema<T>, data: unknown): {
|
|
141
|
+
valid: boolean;
|
|
142
|
+
data?: T;
|
|
143
|
+
errors?: ValidationError[];
|
|
144
|
+
};
|
|
145
|
+
/**
|
|
146
|
+
* Sanitize string input to prevent injection attacks
|
|
147
|
+
*/
|
|
148
|
+
export declare function sanitizeInput(input: string): string;
|
|
149
|
+
/**
|
|
150
|
+
* Search parameters schema (output types for validated data)
|
|
151
|
+
*/
|
|
152
|
+
export interface ValidatedSearchParams {
|
|
153
|
+
query: string;
|
|
154
|
+
type?: 'act' | 'bill' | 'regulation' | 'instrument';
|
|
155
|
+
status?: 'in-force' | 'not-yet-in-force' | 'repealed' | 'partially-repealed' | 'withdrawn';
|
|
156
|
+
from?: string;
|
|
157
|
+
to?: string;
|
|
158
|
+
limit: number;
|
|
159
|
+
offset: number;
|
|
160
|
+
format: 'table' | 'json' | 'csv';
|
|
161
|
+
}
|
|
162
|
+
interface ValidationFailure {
|
|
163
|
+
valid: false;
|
|
164
|
+
errors: ValidationError[];
|
|
165
|
+
}
|
|
166
|
+
interface SearchValidationSuccess {
|
|
167
|
+
valid: true;
|
|
168
|
+
data: z.infer<typeof SearchParamsSchema>;
|
|
169
|
+
}
|
|
170
|
+
interface WorkIdValidationSuccess {
|
|
171
|
+
valid: true;
|
|
172
|
+
data: z.infer<typeof WorkIdSchema>;
|
|
173
|
+
}
|
|
174
|
+
interface ExportValidationSuccess {
|
|
175
|
+
valid: true;
|
|
176
|
+
data: z.infer<typeof ExportParamsSchema>;
|
|
177
|
+
}
|
|
178
|
+
/**
|
|
179
|
+
* Validate and sanitize search parameters
|
|
180
|
+
*/
|
|
181
|
+
export declare function validateSearchParams(params: unknown): ValidationFailure | SearchValidationSuccess;
|
|
182
|
+
/**
|
|
183
|
+
* Validate and sanitize work ID
|
|
184
|
+
*/
|
|
185
|
+
export declare function validateWorkId(workId: string): ValidationFailure | WorkIdValidationSuccess;
|
|
186
|
+
/**
|
|
187
|
+
* Validate and sanitize export parameters
|
|
188
|
+
*/
|
|
189
|
+
export declare function validateExportParams(params: unknown): ValidationFailure | ExportValidationSuccess;
|
|
190
|
+
export {};
|