lt-open-data-sdk 1.0.0 → 1.0.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 +21 -21
- package/README.md +366 -366
- package/dist/cli/generator.js +1 -1
- package/dist/cli/generator.js.map +1 -1
- package/dist/cli/index.js +27 -19
- package/dist/cli/index.js.map +1 -1
- package/dist/client/SpintaClient.d.ts +1 -1
- package/dist/client/SpintaClient.js +1 -1
- package/dist/index.d.ts +2 -2
- package/dist/index.js +2 -2
- package/package.json +1 -1
package/LICENSE
CHANGED
|
@@ -1,21 +1,21 @@
|
|
|
1
|
-
MIT License
|
|
2
|
-
|
|
3
|
-
Copyright (c) 2025 Giedrius Macevičius
|
|
4
|
-
|
|
5
|
-
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
-
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
-
in the Software without restriction, including without limitation the rights
|
|
8
|
-
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
-
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
-
furnished to do so, subject to the following conditions:
|
|
11
|
-
|
|
12
|
-
The above copyright notice and this permission notice shall be included in all
|
|
13
|
-
copies or substantial portions of the Software.
|
|
14
|
-
|
|
15
|
-
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
-
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
-
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
-
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
-
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
-
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
-
SOFTWARE.
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 Giedrius Macevičius
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
CHANGED
|
@@ -1,366 +1,366 @@
|
|
|
1
|
-
# lt-open-data-sdk
|
|
2
|
-
|
|
3
|
-
TypeScript SDK for the **Lithuanian Open Data platform** ([data.gov.lt](https://data.gov.lt)) powered by the Spinta engine.
|
|
4
|
-
|
|
5
|
-
## Features
|
|
6
|
-
|
|
7
|
-
- 🔍 **QueryBuilder** - Fluent API for constructing DSQL queries
|
|
8
|
-
- 🌐 **SpintaClient** - HTTP client with automatic pagination
|
|
9
|
-
- 🛠️ **CLI Type Generator** - Generate TypeScript interfaces from live API
|
|
10
|
-
- 🔐 **OAuth Support** - Client credentials authentication _(untested)_
|
|
11
|
-
|
|
12
|
-
## Installation
|
|
13
|
-
|
|
14
|
-
```bash
|
|
15
|
-
npm install lt-open-data-sdk
|
|
16
|
-
```
|
|
17
|
-
|
|
18
|
-
Requires Node.js ≥18 (uses native `fetch`).
|
|
19
|
-
|
|
20
|
-
## Quick Start
|
|
21
|
-
|
|
22
|
-
```typescript
|
|
23
|
-
import { SpintaClient, QueryBuilder } from "lt-open-data-sdk";
|
|
24
|
-
|
|
25
|
-
const client = new SpintaClient();
|
|
26
|
-
|
|
27
|
-
// Fetch data with a query
|
|
28
|
-
const query = new QueryBuilder()
|
|
29
|
-
.select("_id", "pavadinimas")
|
|
30
|
-
.filter((f) => f.field("sav_kodas").gt(10))
|
|
31
|
-
.sort("pavadinimas")
|
|
32
|
-
.limit(10);
|
|
33
|
-
|
|
34
|
-
const data = await client.getAll(
|
|
35
|
-
"datasets/gov/rc/ar/savivaldybe/Savivaldybe",
|
|
36
|
-
query
|
|
37
|
-
);
|
|
38
|
-
console.log(data);
|
|
39
|
-
```
|
|
40
|
-
|
|
41
|
-
---
|
|
42
|
-
|
|
43
|
-
## QueryBuilder
|
|
44
|
-
|
|
45
|
-
Build type-safe queries with a fluent API:
|
|
46
|
-
|
|
47
|
-
```typescript
|
|
48
|
-
const query = new QueryBuilder<MyType>()
|
|
49
|
-
.select("field1", "field2") // Select specific fields
|
|
50
|
-
.filter((f) => f.field("x").eq(1)) // Add filters
|
|
51
|
-
.sort("field1") // Sort ascending
|
|
52
|
-
.sortDesc("field2") // Sort descending
|
|
53
|
-
.limit(100); // Limit results
|
|
54
|
-
|
|
55
|
-
const queryString = query.toQueryString();
|
|
56
|
-
// Returns: ?select(field1,field2)&x=1&sort(field1,-field2)&limit(100)
|
|
57
|
-
```
|
|
58
|
-
|
|
59
|
-
### Filter Operators
|
|
60
|
-
|
|
61
|
-
| Method | Query | Description |
|
|
62
|
-
| ------------------ | ------------------------- | --------------------- |
|
|
63
|
-
| `.eq(value)` | `field=value` | Equals |
|
|
64
|
-
| `.ne(value)` | `field!=value` | Not equals |
|
|
65
|
-
| `.lt(value)` | `field<value` | Less than |
|
|
66
|
-
| `.le(value)` | `field<=value` | Less than or equal |
|
|
67
|
-
| `.gt(value)` | `field>value` | Greater than |
|
|
68
|
-
| `.ge(value)` | `field>=value` | Greater than or equal |
|
|
69
|
-
| `.contains(str)` | `field.contains("str")` | Contains substring |
|
|
70
|
-
| `.startswith(str)` | `field.startswith("str")` | Starts with |
|
|
71
|
-
|
|
72
|
-
### Combining Filters
|
|
73
|
-
|
|
74
|
-
```typescript
|
|
75
|
-
// AND
|
|
76
|
-
.filter(f => f.field('a').eq(1).and(f.field('b').eq(2)))
|
|
77
|
-
// Output: a=1&b=2
|
|
78
|
-
|
|
79
|
-
// OR
|
|
80
|
-
.filter(f => f.field('a').eq(1).or(f.field('b').eq(2)))
|
|
81
|
-
// Output: a=1|b=2
|
|
82
|
-
|
|
83
|
-
// Complex (OR inside AND - auto-wrapped in parentheses)
|
|
84
|
-
.filter(f => f.field('a').gt(10).and(
|
|
85
|
-
f.field('b').eq(1).or(f.field('b').eq(2))
|
|
86
|
-
))
|
|
87
|
-
// Output: a>10&(b=1|b=2)
|
|
88
|
-
```
|
|
89
|
-
|
|
90
|
-
---
|
|
91
|
-
|
|
92
|
-
## SpintaClient
|
|
93
|
-
|
|
94
|
-
### Basic Usage
|
|
95
|
-
|
|
96
|
-
```typescript
|
|
97
|
-
const client = new SpintaClient();
|
|
98
|
-
// Uses https://get.data.gov.lt by default
|
|
99
|
-
```
|
|
100
|
-
|
|
101
|
-
### Methods
|
|
102
|
-
|
|
103
|
-
#### `getAll(model, query?)` - Fetch one page
|
|
104
|
-
|
|
105
|
-
```typescript
|
|
106
|
-
const cities = await client.getAll("datasets/gov/example/City", query);
|
|
107
|
-
// Returns: Array of objects (unwrapped from _data)
|
|
108
|
-
```
|
|
109
|
-
|
|
110
|
-
> ⚠️ **Note**: Returns ONE page only. Use `stream()` for all records.
|
|
111
|
-
|
|
112
|
-
#### `getAllRaw(model, query?)` - Fetch with metadata
|
|
113
|
-
|
|
114
|
-
```typescript
|
|
115
|
-
const response = await client.getAllRaw("datasets/gov/example/City", query);
|
|
116
|
-
// Returns: { _type, _data: [...], _page: { next } }
|
|
117
|
-
```
|
|
118
|
-
|
|
119
|
-
#### `getOne(model, id)` - Fetch by UUID
|
|
120
|
-
|
|
121
|
-
```typescript
|
|
122
|
-
const city = await client.getOne("datasets/gov/example/City", "uuid-here");
|
|
123
|
-
```
|
|
124
|
-
|
|
125
|
-
#### `count(model, query?)` - Count records
|
|
126
|
-
|
|
127
|
-
```typescript
|
|
128
|
-
const total = await client.count("datasets/gov/example/City");
|
|
129
|
-
const filtered = await client.count(
|
|
130
|
-
"datasets/gov/example/City",
|
|
131
|
-
new QueryBuilder().filter((f) => f.field("population").gt(100000))
|
|
132
|
-
);
|
|
133
|
-
```
|
|
134
|
-
|
|
135
|
-
#### `stream(model, query?)` - Paginated iteration
|
|
136
|
-
|
|
137
|
-
```typescript
|
|
138
|
-
for await (const city of client.stream("datasets/gov/example/City")) {
|
|
139
|
-
console.log(city.pavadinimas);
|
|
140
|
-
}
|
|
141
|
-
```
|
|
142
|
-
|
|
143
|
-
#### `listNamespace(namespace)` - List namespace contents
|
|
144
|
-
|
|
145
|
-
```typescript
|
|
146
|
-
const items = await client.listNamespace("datasets/gov/rc");
|
|
147
|
-
// Returns: [{ _id: 'path', _type: 'ns' | 'model', title? }]
|
|
148
|
-
```
|
|
149
|
-
|
|
150
|
-
#### `discoverModels(namespace)` - Find all models recursively
|
|
151
|
-
|
|
152
|
-
```typescript
|
|
153
|
-
// Discover all available models in a namespace
|
|
154
|
-
const models = await client.discoverModels("datasets/gov/rc/ar");
|
|
155
|
-
console.log(`Found ${models.length} models`);
|
|
156
|
-
|
|
157
|
-
for (const model of models) {
|
|
158
|
-
console.log(`${model.path} - ${model.title}`);
|
|
159
|
-
}
|
|
160
|
-
|
|
161
|
-
// Then generate types for a specific model:
|
|
162
|
-
// npx lt-gen datasets/gov/rc/ar/savivaldybe -o ./types/savivaldybe.d.ts
|
|
163
|
-
```
|
|
164
|
-
|
|
165
|
-
Returns: `{ path, title?, namespace }[]`
|
|
166
|
-
|
|
167
|
-
---
|
|
168
|
-
|
|
169
|
-
## Type Safety & Autocomplete
|
|
170
|
-
|
|
171
|
-
The SDK provides full TypeScript support. The workflow is:
|
|
172
|
-
|
|
173
|
-
1. **Generate types** for your dataset:
|
|
174
|
-
|
|
175
|
-
```bash
|
|
176
|
-
npx lt-gen datasets/gov/rc/ar/savivaldybe -o ./types/savivaldybe.d.ts
|
|
177
|
-
```
|
|
178
|
-
|
|
179
|
-
2. **Import and use** in your code:
|
|
180
|
-
|
|
181
|
-
```typescript
|
|
182
|
-
import { SpintaClient } from "lt-open-data-sdk";
|
|
183
|
-
import type { GovRcArSavivaldybe_Savivaldybe } from "./types/savivaldybe";
|
|
184
|
-
|
|
185
|
-
const client = new SpintaClient();
|
|
186
|
-
|
|
187
|
-
// Pass the type to the method to get full autocomplete!
|
|
188
|
-
const data = await client.getAll<GovRcArSavivaldybe_Savivaldybe>(
|
|
189
|
-
"datasets/gov/rc/ar/savivaldybe/Savivaldybe"
|
|
190
|
-
);
|
|
191
|
-
|
|
192
|
-
// ✅ TypeScript knows these fields exist:
|
|
193
|
-
console.log(data[0].pavadinimas); // string
|
|
194
|
-
console.log(data[0].sav_kodas); // number
|
|
195
|
-
```
|
|
196
|
-
|
|
197
|
-
---
|
|
198
|
-
|
|
199
|
-
## Pagination
|
|
200
|
-
|
|
201
|
-
The API uses cursor-based pagination with `_page.next` tokens.
|
|
202
|
-
|
|
203
|
-
### Automatic Pagination with `stream()`
|
|
204
|
-
|
|
205
|
-
Use `stream()` to iterate through all records automatically:
|
|
206
|
-
|
|
207
|
-
```typescript
|
|
208
|
-
const query = new QueryBuilder().limit(100); // 100 items per page
|
|
209
|
-
|
|
210
|
-
for await (const item of client.stream("datasets/gov/example/City", query)) {
|
|
211
|
-
console.log(item.pavadinimas);
|
|
212
|
-
// Automatically fetches next page when current page is exhausted
|
|
213
|
-
}
|
|
214
|
-
```
|
|
215
|
-
|
|
216
|
-
**How it works:**
|
|
217
|
-
|
|
218
|
-
1. Fetches first page with your query
|
|
219
|
-
2. Yields items one by one
|
|
220
|
-
3. When page exhausted, uses `_page.next` token to fetch next page
|
|
221
|
-
4. Continues until no more pages
|
|
222
|
-
|
|
223
|
-
### Manual Pagination with `getAllRaw()`
|
|
224
|
-
|
|
225
|
-
For more control, handle pagination yourself:
|
|
226
|
-
|
|
227
|
-
```typescript
|
|
228
|
-
let pageToken: string | undefined;
|
|
229
|
-
|
|
230
|
-
do {
|
|
231
|
-
// Build query with page token
|
|
232
|
-
let query = new QueryBuilder().limit(100);
|
|
233
|
-
|
|
234
|
-
const response = await client.getAllRaw("datasets/gov/example/City", query);
|
|
235
|
-
|
|
236
|
-
// Process this page
|
|
237
|
-
for (const item of response._data) {
|
|
238
|
-
console.log(item);
|
|
239
|
-
}
|
|
240
|
-
|
|
241
|
-
// Get next page token
|
|
242
|
-
pageToken = response._page?.next;
|
|
243
|
-
|
|
244
|
-
// Note: You need to add page(token) to next request manually
|
|
245
|
-
// This is handled automatically by stream()
|
|
246
|
-
} while (pageToken);
|
|
247
|
-
```
|
|
248
|
-
|
|
249
|
-
> **Tip**: Use `stream()` for most cases. Use `getAllRaw()` when you need access to page metadata or custom page handling.
|
|
250
|
-
|
|
251
|
-
## CLI Type Generator
|
|
252
|
-
|
|
253
|
-
Generate TypeScript interfaces from live API metadata:
|
|
254
|
-
|
|
255
|
-
```bash
|
|
256
|
-
# Install globally or use npx
|
|
257
|
-
npx lt-gen datasets/gov/rc/ar/savivaldybe
|
|
258
|
-
|
|
259
|
-
# Save to file
|
|
260
|
-
npx lt-gen datasets/gov/rc/ar/savivaldybe -o ./types/savivaldybe.d.ts
|
|
261
|
-
|
|
262
|
-
# Custom API URL
|
|
263
|
-
npx lt-gen datasets/gov/rc/ar/savivaldybe --base-url https://get-test.data.gov.lt
|
|
264
|
-
```
|
|
265
|
-
|
|
266
|
-
### Generated Output
|
|
267
|
-
|
|
268
|
-
```typescript
|
|
269
|
-
export interface GovRcArSavivaldybe_Savivaldybe {
|
|
270
|
-
_id: string;
|
|
271
|
-
_type: string;
|
|
272
|
-
_revision?: string;
|
|
273
|
-
sav_kodas?: number;
|
|
274
|
-
pavadinimas?: string;
|
|
275
|
-
apskritis?: string | { _id: string }; // ref type
|
|
276
|
-
sav_nuo?: string; // date
|
|
277
|
-
}
|
|
278
|
-
|
|
279
|
-
export interface ModelMap {
|
|
280
|
-
"datasets/gov/rc/ar/savivaldybe/Savivaldybe": GovRcArSavivaldybe_Savivaldybe;
|
|
281
|
-
}
|
|
282
|
-
```
|
|
283
|
-
|
|
284
|
-
> **Note**: Types are inferred from data samples since schema endpoints require authentication.
|
|
285
|
-
|
|
286
|
-
---
|
|
287
|
-
|
|
288
|
-
## Authentication _(Untested)_
|
|
289
|
-
|
|
290
|
-
For write operations or private data, provide OAuth credentials:
|
|
291
|
-
|
|
292
|
-
```typescript
|
|
293
|
-
const client = new SpintaClient({
|
|
294
|
-
clientId: "your-client-id",
|
|
295
|
-
clientSecret: "your-client-secret",
|
|
296
|
-
authUrl: "https://put.data.gov.lt", // optional, default
|
|
297
|
-
scopes: ["spinta_getone", "spinta_getall"], // optional
|
|
298
|
-
});
|
|
299
|
-
```
|
|
300
|
-
|
|
301
|
-
The SDK handles:
|
|
302
|
-
|
|
303
|
-
- OAuth client credentials flow
|
|
304
|
-
- Automatic token caching
|
|
305
|
-
- Token refresh before expiry (5-minute buffer)
|
|
306
|
-
|
|
307
|
-
> ⚠️ **Note**: Authentication has been implemented but not tested against a live auth server.
|
|
308
|
-
|
|
309
|
-
---
|
|
310
|
-
|
|
311
|
-
## Error Handling
|
|
312
|
-
|
|
313
|
-
```typescript
|
|
314
|
-
import {
|
|
315
|
-
SpintaError,
|
|
316
|
-
NotFoundError,
|
|
317
|
-
AuthenticationError,
|
|
318
|
-
ValidationError,
|
|
319
|
-
} from "lt-open-data-sdk";
|
|
320
|
-
|
|
321
|
-
try {
|
|
322
|
-
const data = await client.getOne("datasets/example", "invalid-id");
|
|
323
|
-
} catch (error) {
|
|
324
|
-
if (error instanceof NotFoundError) {
|
|
325
|
-
console.log("Not found:", error.message);
|
|
326
|
-
} else if (error instanceof AuthenticationError) {
|
|
327
|
-
console.log("Auth failed:", error.status);
|
|
328
|
-
} else if (error instanceof ValidationError) {
|
|
329
|
-
console.log("Bad request:", error.body);
|
|
330
|
-
}
|
|
331
|
-
}
|
|
332
|
-
```
|
|
333
|
-
|
|
334
|
-
---
|
|
335
|
-
|
|
336
|
-
## API Reference
|
|
337
|
-
|
|
338
|
-
### Exports
|
|
339
|
-
|
|
340
|
-
```typescript
|
|
341
|
-
// Client
|
|
342
|
-
export { SpintaClient } from "./client/SpintaClient";
|
|
343
|
-
export {
|
|
344
|
-
SpintaError,
|
|
345
|
-
AuthenticationError,
|
|
346
|
-
NotFoundError,
|
|
347
|
-
ValidationError,
|
|
348
|
-
} from "./client/errors";
|
|
349
|
-
|
|
350
|
-
// Query Builder
|
|
351
|
-
export { QueryBuilder } from "./builder/QueryBuilder";
|
|
352
|
-
export { FilterBuilder } from "./builder/FilterBuilder";
|
|
353
|
-
|
|
354
|
-
// Types
|
|
355
|
-
export type {
|
|
356
|
-
ClientConfig,
|
|
357
|
-
SpintaResponse,
|
|
358
|
-
SpintaObject,
|
|
359
|
-
} from "./client/types";
|
|
360
|
-
```
|
|
361
|
-
|
|
362
|
-
---
|
|
363
|
-
|
|
364
|
-
## License
|
|
365
|
-
|
|
366
|
-
MIT
|
|
1
|
+
# lt-open-data-sdk
|
|
2
|
+
|
|
3
|
+
TypeScript SDK for the **Lithuanian Open Data platform** ([data.gov.lt](https://data.gov.lt)) powered by the Spinta engine.
|
|
4
|
+
|
|
5
|
+
## Features
|
|
6
|
+
|
|
7
|
+
- 🔍 **QueryBuilder** - Fluent API for constructing DSQL queries
|
|
8
|
+
- 🌐 **SpintaClient** - HTTP client with automatic pagination
|
|
9
|
+
- 🛠️ **CLI Type Generator** - Generate TypeScript interfaces from live API
|
|
10
|
+
- 🔐 **OAuth Support** - Client credentials authentication _(untested)_
|
|
11
|
+
|
|
12
|
+
## Installation
|
|
13
|
+
|
|
14
|
+
```bash
|
|
15
|
+
npm install lt-open-data-sdk
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
Requires Node.js ≥18 (uses native `fetch`).
|
|
19
|
+
|
|
20
|
+
## Quick Start
|
|
21
|
+
|
|
22
|
+
```typescript
|
|
23
|
+
import { SpintaClient, QueryBuilder } from "lt-open-data-sdk";
|
|
24
|
+
|
|
25
|
+
const client = new SpintaClient();
|
|
26
|
+
|
|
27
|
+
// Fetch data with a query
|
|
28
|
+
const query = new QueryBuilder()
|
|
29
|
+
.select("_id", "pavadinimas")
|
|
30
|
+
.filter((f) => f.field("sav_kodas").gt(10))
|
|
31
|
+
.sort("pavadinimas")
|
|
32
|
+
.limit(10);
|
|
33
|
+
|
|
34
|
+
const data = await client.getAll(
|
|
35
|
+
"datasets/gov/rc/ar/savivaldybe/Savivaldybe",
|
|
36
|
+
query
|
|
37
|
+
);
|
|
38
|
+
console.log(data);
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
---
|
|
42
|
+
|
|
43
|
+
## QueryBuilder
|
|
44
|
+
|
|
45
|
+
Build type-safe queries with a fluent API:
|
|
46
|
+
|
|
47
|
+
```typescript
|
|
48
|
+
const query = new QueryBuilder<MyType>()
|
|
49
|
+
.select("field1", "field2") // Select specific fields
|
|
50
|
+
.filter((f) => f.field("x").eq(1)) // Add filters
|
|
51
|
+
.sort("field1") // Sort ascending
|
|
52
|
+
.sortDesc("field2") // Sort descending
|
|
53
|
+
.limit(100); // Limit results
|
|
54
|
+
|
|
55
|
+
const queryString = query.toQueryString();
|
|
56
|
+
// Returns: ?select(field1,field2)&x=1&sort(field1,-field2)&limit(100)
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
### Filter Operators
|
|
60
|
+
|
|
61
|
+
| Method | Query | Description |
|
|
62
|
+
| ------------------ | ------------------------- | --------------------- |
|
|
63
|
+
| `.eq(value)` | `field=value` | Equals |
|
|
64
|
+
| `.ne(value)` | `field!=value` | Not equals |
|
|
65
|
+
| `.lt(value)` | `field<value` | Less than |
|
|
66
|
+
| `.le(value)` | `field<=value` | Less than or equal |
|
|
67
|
+
| `.gt(value)` | `field>value` | Greater than |
|
|
68
|
+
| `.ge(value)` | `field>=value` | Greater than or equal |
|
|
69
|
+
| `.contains(str)` | `field.contains("str")` | Contains substring |
|
|
70
|
+
| `.startswith(str)` | `field.startswith("str")` | Starts with |
|
|
71
|
+
|
|
72
|
+
### Combining Filters
|
|
73
|
+
|
|
74
|
+
```typescript
|
|
75
|
+
// AND
|
|
76
|
+
.filter(f => f.field('a').eq(1).and(f.field('b').eq(2)))
|
|
77
|
+
// Output: a=1&b=2
|
|
78
|
+
|
|
79
|
+
// OR
|
|
80
|
+
.filter(f => f.field('a').eq(1).or(f.field('b').eq(2)))
|
|
81
|
+
// Output: a=1|b=2
|
|
82
|
+
|
|
83
|
+
// Complex (OR inside AND - auto-wrapped in parentheses)
|
|
84
|
+
.filter(f => f.field('a').gt(10).and(
|
|
85
|
+
f.field('b').eq(1).or(f.field('b').eq(2))
|
|
86
|
+
))
|
|
87
|
+
// Output: a>10&(b=1|b=2)
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
---
|
|
91
|
+
|
|
92
|
+
## SpintaClient
|
|
93
|
+
|
|
94
|
+
### Basic Usage
|
|
95
|
+
|
|
96
|
+
```typescript
|
|
97
|
+
const client = new SpintaClient();
|
|
98
|
+
// Uses https://get.data.gov.lt by default
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
### Methods
|
|
102
|
+
|
|
103
|
+
#### `getAll(model, query?)` - Fetch one page
|
|
104
|
+
|
|
105
|
+
```typescript
|
|
106
|
+
const cities = await client.getAll("datasets/gov/example/City", query);
|
|
107
|
+
// Returns: Array of objects (unwrapped from _data)
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
> ⚠️ **Note**: Returns ONE page only. Use `stream()` for all records.
|
|
111
|
+
|
|
112
|
+
#### `getAllRaw(model, query?)` - Fetch with metadata
|
|
113
|
+
|
|
114
|
+
```typescript
|
|
115
|
+
const response = await client.getAllRaw("datasets/gov/example/City", query);
|
|
116
|
+
// Returns: { _type, _data: [...], _page: { next } }
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
#### `getOne(model, id)` - Fetch by UUID
|
|
120
|
+
|
|
121
|
+
```typescript
|
|
122
|
+
const city = await client.getOne("datasets/gov/example/City", "uuid-here");
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
#### `count(model, query?)` - Count records
|
|
126
|
+
|
|
127
|
+
```typescript
|
|
128
|
+
const total = await client.count("datasets/gov/example/City");
|
|
129
|
+
const filtered = await client.count(
|
|
130
|
+
"datasets/gov/example/City",
|
|
131
|
+
new QueryBuilder().filter((f) => f.field("population").gt(100000))
|
|
132
|
+
);
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
#### `stream(model, query?)` - Paginated iteration
|
|
136
|
+
|
|
137
|
+
```typescript
|
|
138
|
+
for await (const city of client.stream("datasets/gov/example/City")) {
|
|
139
|
+
console.log(city.pavadinimas);
|
|
140
|
+
}
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
#### `listNamespace(namespace)` - List namespace contents
|
|
144
|
+
|
|
145
|
+
```typescript
|
|
146
|
+
const items = await client.listNamespace("datasets/gov/rc");
|
|
147
|
+
// Returns: [{ _id: 'path', _type: 'ns' | 'model', title? }]
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
#### `discoverModels(namespace)` - Find all models recursively
|
|
151
|
+
|
|
152
|
+
```typescript
|
|
153
|
+
// Discover all available models in a namespace
|
|
154
|
+
const models = await client.discoverModels("datasets/gov/rc/ar");
|
|
155
|
+
console.log(`Found ${models.length} models`);
|
|
156
|
+
|
|
157
|
+
for (const model of models) {
|
|
158
|
+
console.log(`${model.path} - ${model.title}`);
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
// Then generate types for a specific model:
|
|
162
|
+
// npx lt-gen datasets/gov/rc/ar/savivaldybe -o ./types/savivaldybe.d.ts
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
Returns: `{ path, title?, namespace }[]`
|
|
166
|
+
|
|
167
|
+
---
|
|
168
|
+
|
|
169
|
+
## Type Safety & Autocomplete
|
|
170
|
+
|
|
171
|
+
The SDK provides full TypeScript support. The workflow is:
|
|
172
|
+
|
|
173
|
+
1. **Generate types** for your dataset:
|
|
174
|
+
|
|
175
|
+
```bash
|
|
176
|
+
npx lt-gen datasets/gov/rc/ar/savivaldybe -o ./types/savivaldybe.d.ts
|
|
177
|
+
```
|
|
178
|
+
|
|
179
|
+
2. **Import and use** in your code:
|
|
180
|
+
|
|
181
|
+
```typescript
|
|
182
|
+
import { SpintaClient } from "lt-open-data-sdk";
|
|
183
|
+
import type { GovRcArSavivaldybe_Savivaldybe } from "./types/savivaldybe";
|
|
184
|
+
|
|
185
|
+
const client = new SpintaClient();
|
|
186
|
+
|
|
187
|
+
// Pass the type to the method to get full autocomplete!
|
|
188
|
+
const data = await client.getAll<GovRcArSavivaldybe_Savivaldybe>(
|
|
189
|
+
"datasets/gov/rc/ar/savivaldybe/Savivaldybe"
|
|
190
|
+
);
|
|
191
|
+
|
|
192
|
+
// ✅ TypeScript knows these fields exist:
|
|
193
|
+
console.log(data[0].pavadinimas); // string
|
|
194
|
+
console.log(data[0].sav_kodas); // number
|
|
195
|
+
```
|
|
196
|
+
|
|
197
|
+
---
|
|
198
|
+
|
|
199
|
+
## Pagination
|
|
200
|
+
|
|
201
|
+
The API uses cursor-based pagination with `_page.next` tokens.
|
|
202
|
+
|
|
203
|
+
### Automatic Pagination with `stream()`
|
|
204
|
+
|
|
205
|
+
Use `stream()` to iterate through all records automatically:
|
|
206
|
+
|
|
207
|
+
```typescript
|
|
208
|
+
const query = new QueryBuilder().limit(100); // 100 items per page
|
|
209
|
+
|
|
210
|
+
for await (const item of client.stream("datasets/gov/example/City", query)) {
|
|
211
|
+
console.log(item.pavadinimas);
|
|
212
|
+
// Automatically fetches next page when current page is exhausted
|
|
213
|
+
}
|
|
214
|
+
```
|
|
215
|
+
|
|
216
|
+
**How it works:**
|
|
217
|
+
|
|
218
|
+
1. Fetches first page with your query
|
|
219
|
+
2. Yields items one by one
|
|
220
|
+
3. When page exhausted, uses `_page.next` token to fetch next page
|
|
221
|
+
4. Continues until no more pages
|
|
222
|
+
|
|
223
|
+
### Manual Pagination with `getAllRaw()`
|
|
224
|
+
|
|
225
|
+
For more control, handle pagination yourself:
|
|
226
|
+
|
|
227
|
+
```typescript
|
|
228
|
+
let pageToken: string | undefined;
|
|
229
|
+
|
|
230
|
+
do {
|
|
231
|
+
// Build query with page token
|
|
232
|
+
let query = new QueryBuilder().limit(100);
|
|
233
|
+
|
|
234
|
+
const response = await client.getAllRaw("datasets/gov/example/City", query);
|
|
235
|
+
|
|
236
|
+
// Process this page
|
|
237
|
+
for (const item of response._data) {
|
|
238
|
+
console.log(item);
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
// Get next page token
|
|
242
|
+
pageToken = response._page?.next;
|
|
243
|
+
|
|
244
|
+
// Note: You need to add page(token) to next request manually
|
|
245
|
+
// This is handled automatically by stream()
|
|
246
|
+
} while (pageToken);
|
|
247
|
+
```
|
|
248
|
+
|
|
249
|
+
> **Tip**: Use `stream()` for most cases. Use `getAllRaw()` when you need access to page metadata or custom page handling.
|
|
250
|
+
|
|
251
|
+
## CLI Type Generator
|
|
252
|
+
|
|
253
|
+
Generate TypeScript interfaces from live API metadata:
|
|
254
|
+
|
|
255
|
+
```bash
|
|
256
|
+
# Install globally or use npx
|
|
257
|
+
npx lt-gen datasets/gov/rc/ar/savivaldybe
|
|
258
|
+
|
|
259
|
+
# Save to file
|
|
260
|
+
npx lt-gen datasets/gov/rc/ar/savivaldybe -o ./types/savivaldybe.d.ts
|
|
261
|
+
|
|
262
|
+
# Custom API URL
|
|
263
|
+
npx lt-gen datasets/gov/rc/ar/savivaldybe --base-url https://get-test.data.gov.lt
|
|
264
|
+
```
|
|
265
|
+
|
|
266
|
+
### Generated Output
|
|
267
|
+
|
|
268
|
+
```typescript
|
|
269
|
+
export interface GovRcArSavivaldybe_Savivaldybe {
|
|
270
|
+
_id: string;
|
|
271
|
+
_type: string;
|
|
272
|
+
_revision?: string;
|
|
273
|
+
sav_kodas?: number;
|
|
274
|
+
pavadinimas?: string;
|
|
275
|
+
apskritis?: string | { _id: string }; // ref type
|
|
276
|
+
sav_nuo?: string; // date
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
export interface ModelMap {
|
|
280
|
+
"datasets/gov/rc/ar/savivaldybe/Savivaldybe": GovRcArSavivaldybe_Savivaldybe;
|
|
281
|
+
}
|
|
282
|
+
```
|
|
283
|
+
|
|
284
|
+
> **Note**: Types are inferred from data samples since schema endpoints require authentication.
|
|
285
|
+
|
|
286
|
+
---
|
|
287
|
+
|
|
288
|
+
## Authentication _(Untested)_
|
|
289
|
+
|
|
290
|
+
For write operations or private data, provide OAuth credentials:
|
|
291
|
+
|
|
292
|
+
```typescript
|
|
293
|
+
const client = new SpintaClient({
|
|
294
|
+
clientId: "your-client-id",
|
|
295
|
+
clientSecret: "your-client-secret",
|
|
296
|
+
authUrl: "https://put.data.gov.lt", // optional, default
|
|
297
|
+
scopes: ["spinta_getone", "spinta_getall"], // optional
|
|
298
|
+
});
|
|
299
|
+
```
|
|
300
|
+
|
|
301
|
+
The SDK handles:
|
|
302
|
+
|
|
303
|
+
- OAuth client credentials flow
|
|
304
|
+
- Automatic token caching
|
|
305
|
+
- Token refresh before expiry (5-minute buffer)
|
|
306
|
+
|
|
307
|
+
> ⚠️ **Note**: Authentication has been implemented but not tested against a live auth server.
|
|
308
|
+
|
|
309
|
+
---
|
|
310
|
+
|
|
311
|
+
## Error Handling
|
|
312
|
+
|
|
313
|
+
```typescript
|
|
314
|
+
import {
|
|
315
|
+
SpintaError,
|
|
316
|
+
NotFoundError,
|
|
317
|
+
AuthenticationError,
|
|
318
|
+
ValidationError,
|
|
319
|
+
} from "lt-open-data-sdk";
|
|
320
|
+
|
|
321
|
+
try {
|
|
322
|
+
const data = await client.getOne("datasets/example", "invalid-id");
|
|
323
|
+
} catch (error) {
|
|
324
|
+
if (error instanceof NotFoundError) {
|
|
325
|
+
console.log("Not found:", error.message);
|
|
326
|
+
} else if (error instanceof AuthenticationError) {
|
|
327
|
+
console.log("Auth failed:", error.status);
|
|
328
|
+
} else if (error instanceof ValidationError) {
|
|
329
|
+
console.log("Bad request:", error.body);
|
|
330
|
+
}
|
|
331
|
+
}
|
|
332
|
+
```
|
|
333
|
+
|
|
334
|
+
---
|
|
335
|
+
|
|
336
|
+
## API Reference
|
|
337
|
+
|
|
338
|
+
### Exports
|
|
339
|
+
|
|
340
|
+
```typescript
|
|
341
|
+
// Client
|
|
342
|
+
export { SpintaClient } from "./client/SpintaClient";
|
|
343
|
+
export {
|
|
344
|
+
SpintaError,
|
|
345
|
+
AuthenticationError,
|
|
346
|
+
NotFoundError,
|
|
347
|
+
ValidationError,
|
|
348
|
+
} from "./client/errors";
|
|
349
|
+
|
|
350
|
+
// Query Builder
|
|
351
|
+
export { QueryBuilder } from "./builder/QueryBuilder";
|
|
352
|
+
export { FilterBuilder } from "./builder/FilterBuilder";
|
|
353
|
+
|
|
354
|
+
// Types
|
|
355
|
+
export type {
|
|
356
|
+
ClientConfig,
|
|
357
|
+
SpintaResponse,
|
|
358
|
+
SpintaObject,
|
|
359
|
+
} from "./client/types";
|
|
360
|
+
```
|
|
361
|
+
|
|
362
|
+
---
|
|
363
|
+
|
|
364
|
+
## License
|
|
365
|
+
|
|
366
|
+
MIT
|
package/dist/cli/generator.js
CHANGED
|
@@ -52,7 +52,7 @@ export function generateDeclarationFile(models, namespace) {
|
|
|
52
52
|
lines.push('/**');
|
|
53
53
|
lines.push(` * TypeScript definitions for ${namespace}`);
|
|
54
54
|
lines.push(' * ');
|
|
55
|
-
lines.push(' * Generated by lt-data-sdk CLI');
|
|
55
|
+
lines.push(' * Generated by lt-open-data-sdk CLI');
|
|
56
56
|
lines.push(` * Generated at: ${new Date().toISOString()}`);
|
|
57
57
|
lines.push(' * ');
|
|
58
58
|
lines.push(' * @see https://get.data.gov.lt/' + namespace);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"generator.js","sourceRoot":"","sources":["../../src/cli/generator.ts"],"names":[],"mappings":"AAAA;;GAEG;AAGH,OAAO,EACL,aAAa,EACb,UAAU,EACV,wBAAwB,EACxB,oBAAoB,EACpB,aAAa,GACd,MAAM,iBAAiB,CAAC;AAEzB;;GAEG;AACH,SAAS,iBAAiB,CAAC,KAAoB;IAC7C,MAAM,aAAa,GAAG,wBAAwB,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IAC3D,MAAM,KAAK,GAAa,EAAE,CAAC;IAE3B,YAAY;IACZ,MAAM,KAAK,GAAG,aAAa,CAAC,KAAK,CAAC,KAAK,EAAE,KAAK,CAAC,WAAW,CAAC,CAAC;IAC5D,IAAI,KAAK,KAAK,EAAE,EAAE,CAAC;QACjB,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IACpB,CAAC;IAED,KAAK,CAAC,IAAI,CAAC,oBAAoB,aAAa,IAAI,CAAC,CAAC;IAElD,oCAAoC;IACpC,KAAK,CAAC,IAAI,CAAC,mCAAmC,CAAC,CAAC;IAChD,KAAK,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC;IAC7B,KAAK,CAAC,IAAI,CAAC,0BAA0B,CAAC,CAAC;IACvC,KAAK,CAAC,IAAI,CAAC,kBAAkB,CAAC,CAAC;IAC/B,KAAK,CAAC,IAAI,CAAC,mDAAmD,CAAC,CAAC;IAChE,KAAK,CAAC,IAAI,CAAC,uBAAuB,CAAC,CAAC;IACpC,KAAK,CAAC,IAAI,CAAC,yBAAyB,CAAC,CAAC;IACtC,KAAK,CAAC,IAAI,CAAC,kBAAkB,CAAC,CAAC;IAE/B,uBAAuB;IACvB,KAAK,MAAM,IAAI,IAAI,KAAK,CAAC,UAAU,EAAE,CAAC;QACpC,MAAM,QAAQ,GAAG,oBAAoB,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACjD,MAAM,MAAM,GAAG,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACxC,MAAM,QAAQ,GAAG,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACvC,MAAM,QAAQ,GAAG,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC;QAErC,qBAAqB;QACrB,MAAM,SAAS,GAAG,aAAa,CAAC,IAAI,CAAC,KAAK,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC;QAC9D,IAAI,SAAS,KAAK,EAAE,EAAE,CAAC;YACrB,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;YACf,KAAK,CAAC,IAAI,CACR,SAAS;iBACN,KAAK,CAAC,IAAI,CAAC;iBACX,GAAG,CAAC,CAAC,CAAS,EAAE,EAAE,CAAC,IAAI,GAAG,CAAC,CAAC;iBAC5B,IAAI,CAAC,IAAI,CAAC,CACd,CAAC;QACJ,CAAC;QAED,KAAK,CAAC,IAAI,CAAC,KAAK,QAAQ,GAAG,QAAQ,KAAK,MAAM,GAAG,CAAC,CAAC;IACrD,CAAC;IAED,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IAEhB,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAC1B,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,uBAAuB,CACrC,MAAgC,EAChC,SAAiB;IAEjB,MAAM,KAAK,GAAa,EAAE,CAAC;IAE3B,cAAc;IACd,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IAClB,KAAK,CAAC,IAAI,CAAC,iCAAiC,SAAS,EAAE,CAAC,CAAC;IACzD,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IAClB,KAAK,CAAC,IAAI,CAAC,
|
|
1
|
+
{"version":3,"file":"generator.js","sourceRoot":"","sources":["../../src/cli/generator.ts"],"names":[],"mappings":"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"}
|
package/dist/cli/index.js
CHANGED
|
@@ -15,7 +15,8 @@
|
|
|
15
15
|
* --base-url Base URL for the API (default: https://get.data.gov.lt)
|
|
16
16
|
* --help, -h Show help
|
|
17
17
|
*/
|
|
18
|
-
import { writeFileSync } from 'fs';
|
|
18
|
+
import { writeFileSync, mkdirSync } from 'fs';
|
|
19
|
+
import { dirname } from 'path';
|
|
19
20
|
import { SpintaClient } from '../client/SpintaClient.js';
|
|
20
21
|
import { crawlNamespace, fetchAllModelsMetadata } from './crawler.js';
|
|
21
22
|
import { generateDeclarationFile } from './generator.js';
|
|
@@ -57,24 +58,24 @@ function parseArgs(args) {
|
|
|
57
58
|
return options;
|
|
58
59
|
}
|
|
59
60
|
function showHelp() {
|
|
60
|
-
console.log(`
|
|
61
|
-
lt-gen - Generate TypeScript definitions from Spinta API metadata
|
|
62
|
-
|
|
63
|
-
Usage:
|
|
64
|
-
lt-gen <namespace> [options]
|
|
65
|
-
|
|
66
|
-
Arguments:
|
|
67
|
-
namespace Namespace path to generate types for (e.g., datasets/gov/ivpk/adk)
|
|
68
|
-
|
|
69
|
-
Options:
|
|
70
|
-
--output, -o Output file path (default: stdout)
|
|
71
|
-
--base-url Base URL for the API (default: https://get.data.gov.lt)
|
|
72
|
-
--help, -h Show this help message
|
|
73
|
-
|
|
74
|
-
Examples:
|
|
75
|
-
lt-gen datasets/gov/ivpk/adk
|
|
76
|
-
lt-gen datasets/gov/ivpk/adk -o ./types/adk.d.ts
|
|
77
|
-
lt-gen datasets/gov/ivpk/adk --base-url https://get-test.data.gov.lt
|
|
61
|
+
console.log(`
|
|
62
|
+
lt-gen - Generate TypeScript definitions from Spinta API metadata
|
|
63
|
+
|
|
64
|
+
Usage:
|
|
65
|
+
lt-gen <namespace> [options]
|
|
66
|
+
|
|
67
|
+
Arguments:
|
|
68
|
+
namespace Namespace path to generate types for (e.g., datasets/gov/ivpk/adk)
|
|
69
|
+
|
|
70
|
+
Options:
|
|
71
|
+
--output, -o Output file path (default: stdout)
|
|
72
|
+
--base-url Base URL for the API (default: https://get.data.gov.lt)
|
|
73
|
+
--help, -h Show this help message
|
|
74
|
+
|
|
75
|
+
Examples:
|
|
76
|
+
lt-gen datasets/gov/ivpk/adk
|
|
77
|
+
lt-gen datasets/gov/ivpk/adk -o ./types/adk.d.ts
|
|
78
|
+
lt-gen datasets/gov/ivpk/adk --base-url https://get-test.data.gov.lt
|
|
78
79
|
`);
|
|
79
80
|
}
|
|
80
81
|
async function main() {
|
|
@@ -85,6 +86,11 @@ async function main() {
|
|
|
85
86
|
process.exit(options.help ? 0 : 1);
|
|
86
87
|
}
|
|
87
88
|
console.error(`🔍 Discovering models in ${options.namespace}...`);
|
|
89
|
+
if (options.namespace.startsWith('http://') || options.namespace.startsWith('https://')) {
|
|
90
|
+
console.error(`\n❌ Error: Namespace should be a path (e.g. "datasets/gov/rc"), not a URL.`);
|
|
91
|
+
console.error(` Use --base-url to change the API endpoint if needed.`);
|
|
92
|
+
process.exit(1);
|
|
93
|
+
}
|
|
88
94
|
const client = new SpintaClient({ baseUrl: options.baseUrl });
|
|
89
95
|
try {
|
|
90
96
|
// Crawl namespace to find all models
|
|
@@ -105,6 +111,8 @@ async function main() {
|
|
|
105
111
|
const output = generateDeclarationFile(metadata, options.namespace);
|
|
106
112
|
// Write output
|
|
107
113
|
if (options.output !== undefined) {
|
|
114
|
+
// Ensure directory exists
|
|
115
|
+
mkdirSync(dirname(options.output), { recursive: true });
|
|
108
116
|
writeFileSync(options.output, output, 'utf-8');
|
|
109
117
|
console.error(`\n✅ Written to ${options.output}`);
|
|
110
118
|
}
|
package/dist/cli/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/cli/index.ts"],"names":[],"mappings":";AACA;;;;;;;;;;;;;;;GAeG;AAEH,OAAO,EAAE,aAAa,EAAE,MAAM,IAAI,CAAC;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/cli/index.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* lt-data-sdk - TypeScript SDK for the Lithuanian Open Data platform (data.gov.lt)
|
|
2
|
+
* lt-open-data-sdk - TypeScript SDK for the Lithuanian Open Data platform (data.gov.lt)
|
|
3
3
|
*
|
|
4
4
|
* @packageDocumentation
|
|
5
5
|
*
|
|
6
6
|
* @example
|
|
7
7
|
* ```typescript
|
|
8
|
-
* import { SpintaClient, QueryBuilder } from 'lt-data-sdk';
|
|
8
|
+
* import { SpintaClient, QueryBuilder } from 'lt-open-data-sdk';
|
|
9
9
|
*
|
|
10
10
|
* const client = new SpintaClient();
|
|
11
11
|
*
|
package/dist/index.js
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* lt-data-sdk - TypeScript SDK for the Lithuanian Open Data platform (data.gov.lt)
|
|
2
|
+
* lt-open-data-sdk - TypeScript SDK for the Lithuanian Open Data platform (data.gov.lt)
|
|
3
3
|
*
|
|
4
4
|
* @packageDocumentation
|
|
5
5
|
*
|
|
6
6
|
* @example
|
|
7
7
|
* ```typescript
|
|
8
|
-
* import { SpintaClient, QueryBuilder } from 'lt-data-sdk';
|
|
8
|
+
* import { SpintaClient, QueryBuilder } from 'lt-open-data-sdk';
|
|
9
9
|
*
|
|
10
10
|
* const client = new SpintaClient();
|
|
11
11
|
*
|