stadata-js 1.1.0 → 2.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/README.md +122 -240
- package/dist/index.d.mts +287 -619
- package/dist/index.d.ts +287 -619
- package/dist/index.global.js +2 -2
- package/dist/index.js +2 -2
- package/dist/index.mjs +2 -2
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -2,317 +2,199 @@
|
|
|
2
2
|
|
|
3
3
|
[](https://www.npmjs.com/package/stadata-js)
|
|
4
4
|
[](https://opensource.org/licenses/MIT)
|
|
5
|
+
[](https://ipds-59.github.io/stadata_js/)
|
|
5
6
|
|
|
6
|
-
Official TypeScript/JavaScript SDK for BPS (Badan Pusat Statistik) WebAPI
|
|
7
|
+
Official TypeScript/JavaScript SDK for BPS (Badan Pusat Statistik) WebAPI — Seamlessly access Indonesia's Central Bureau of Statistics data through a comprehensive, type-safe client library.
|
|
7
8
|
|
|
8
9
|
## Overview
|
|
9
10
|
|
|
10
11
|
The STADATA JS SDK provides TypeScript/JavaScript developers with streamlined access to Indonesia's statistical data through the official BPS WebAPI. Create data-driven applications featuring demographic, economic, and socio-economic information from Indonesia's most authoritative statistical source.
|
|
11
12
|
|
|
12
|
-
This toolkit facilitates seamless integration with BPS data sources, eliminating the need for manual downloads from the BPS website. Access publications, press releases, static/dynamic tables, infographics, census datasets, and much more through a clean, modern API.
|
|
13
|
-
|
|
14
13
|
## Features
|
|
15
14
|
|
|
16
|
-
- **
|
|
17
|
-
- **
|
|
18
|
-
- **Result Pattern**
|
|
19
|
-
- **
|
|
20
|
-
- **
|
|
21
|
-
- **
|
|
22
|
-
- **
|
|
23
|
-
- **Immutable Entities** - All domain entities are immutable for predictable behavior
|
|
24
|
-
- **Pagination Support** - Built-in pagination handling for all list endpoints
|
|
25
|
-
- **Modern JavaScript** - Built for modern ES6+ environments with CommonJS and ESM support
|
|
15
|
+
- **Functional Composable API** — `initStadata()` + `use*()` composables by default, with optional explicit clients for advanced use cases
|
|
16
|
+
- **Full TypeScript Support** — Complete type definitions with IntelliSense support
|
|
17
|
+
- **Result Pattern** — Uses `neverthrow` for elegant, type-safe error handling
|
|
18
|
+
- **Tree-shakeable** — Only bundle what you use
|
|
19
|
+
- **Pagination Support** — Built-in pagination handling for all list endpoints
|
|
20
|
+
- **Request Cancellation** — Cancel ongoing requests to optimize performance
|
|
21
|
+
- **Immutable Entities** — Predictable, safe domain entities
|
|
26
22
|
|
|
27
23
|
## Requirements
|
|
28
24
|
|
|
29
25
|
- Node.js >= 16.0.0
|
|
30
|
-
- Valid API key from BPS WebAPI platform
|
|
26
|
+
- Valid API key from [BPS WebAPI platform](https://webapi.bps.go.id/)
|
|
31
27
|
|
|
32
28
|
## Installation
|
|
33
29
|
|
|
34
30
|
```bash
|
|
31
|
+
# npm
|
|
35
32
|
npm install stadata-js
|
|
36
|
-
```
|
|
37
33
|
|
|
38
|
-
|
|
34
|
+
# pnpm
|
|
35
|
+
pnpm add stadata-js
|
|
39
36
|
|
|
40
|
-
|
|
37
|
+
# yarn
|
|
41
38
|
yarn add stadata-js
|
|
42
39
|
```
|
|
43
40
|
|
|
44
|
-
or using pnpm:
|
|
45
|
-
|
|
46
|
-
```bash
|
|
47
|
-
pnpm add stadata-js
|
|
48
|
-
```
|
|
49
|
-
|
|
50
41
|
## Quick Start
|
|
51
42
|
|
|
52
43
|
```typescript
|
|
53
|
-
import {
|
|
44
|
+
import { initStadata, usePublications, useDomains, DataLanguage, DomainType } from 'stadata-js'
|
|
54
45
|
|
|
55
|
-
// Initialize
|
|
56
|
-
|
|
57
|
-
apiKey: 'your-api-key-here',
|
|
58
|
-
debug: false, // Enable debug logging if needed
|
|
59
|
-
});
|
|
46
|
+
// 1. Initialize once at app entry point
|
|
47
|
+
initStadata({ apiKey: 'your-api-key-here' })
|
|
60
48
|
|
|
61
|
-
//
|
|
62
|
-
const
|
|
49
|
+
// 2. Use composables anywhere — no client reference needed
|
|
50
|
+
const { fetchPublicationList, fetchPublicationDetail } = usePublications()
|
|
51
|
+
const { fetchDomainList } = useDomains()
|
|
63
52
|
|
|
64
|
-
// Fetch
|
|
65
|
-
const
|
|
66
|
-
|
|
53
|
+
// 3. Fetch data
|
|
54
|
+
const result = await fetchPublicationList({
|
|
55
|
+
domain: '7200',
|
|
56
|
+
lang: DataLanguage.ID,
|
|
67
57
|
page: 1,
|
|
68
58
|
perPage: 10,
|
|
69
|
-
})
|
|
70
|
-
|
|
71
|
-
// Handle the result using pattern matching
|
|
72
|
-
domainsResult.match(
|
|
73
|
-
(listResult) => {
|
|
74
|
-
console.log('Domains:', listResult.data);
|
|
75
|
-
console.log('Total:', listResult.pagination.total);
|
|
76
|
-
console.log('Current Page:', listResult.pagination.page);
|
|
77
|
-
},
|
|
78
|
-
(error) => {
|
|
79
|
-
console.error('Error:', error.message);
|
|
80
|
-
}
|
|
81
|
-
);
|
|
82
|
-
|
|
83
|
-
// Fetch a specific domain by ID
|
|
84
|
-
const domainResult = await stadata.view.domain({
|
|
85
|
-
id: '7315',
|
|
86
|
-
lang: DataLanguage.ID,
|
|
87
|
-
});
|
|
59
|
+
})
|
|
88
60
|
|
|
89
|
-
|
|
90
|
-
(
|
|
91
|
-
console.log(
|
|
92
|
-
|
|
61
|
+
result.match(
|
|
62
|
+
({ data, pagination }) => {
|
|
63
|
+
console.log(`Total: ${pagination.total}`)
|
|
64
|
+
data.forEach(pub => console.log(pub.title))
|
|
93
65
|
},
|
|
94
|
-
(error) =>
|
|
95
|
-
|
|
96
|
-
}
|
|
97
|
-
);
|
|
66
|
+
(error) => console.error('Error:', error.message)
|
|
67
|
+
)
|
|
98
68
|
```
|
|
99
69
|
|
|
100
|
-
##
|
|
70
|
+
## API Reference
|
|
101
71
|
|
|
102
|
-
|
|
72
|
+
Full documentation: **[ipds-59.github.io/stadata_js](https://ipds-59.github.io/stadata_js/)**
|
|
73
|
+
|
|
74
|
+
### Available Composables
|
|
75
|
+
|
|
76
|
+
| Composable | Functions |
|
|
77
|
+
|-----------|-----------|
|
|
78
|
+
| `useDomains()` | `fetchDomainList` |
|
|
79
|
+
| `usePublications()` | `fetchPublicationList`, `fetchPublicationDetail` |
|
|
80
|
+
| `usePressReleases()` | `fetchPressReleaseList`, `fetchPressReleaseDetail` |
|
|
81
|
+
| `useStaticTables()` | `fetchStaticTableList`, `fetchStaticTableDetail` |
|
|
82
|
+
| `useDynamicTables()` | `fetchDynamicTableList` |
|
|
83
|
+
| `useInfographics()` | `fetchInfographicList` |
|
|
84
|
+
| `useNews()` | `fetchNewsList`, `fetchNewsDetail` |
|
|
85
|
+
| `useNewsCategories()` | `fetchNewsCategoryList` |
|
|
86
|
+
| `useVariables()` | `fetchVariableList`, `fetchVariableDetail` |
|
|
87
|
+
| `useVerticalVariables()` | `fetchVerticalVariableList` |
|
|
88
|
+
| `useDerivedVariables()` | `fetchDerivedVariableList` |
|
|
89
|
+
| `useSubjects()` | `fetchSubjectList`, `fetchSubjectDetail` |
|
|
90
|
+
| `useSubjectCategories()` | `fetchSubjectCategoryList` |
|
|
91
|
+
| `useUnits()` | `fetchUnitList`, `fetchUnitDetail` |
|
|
92
|
+
| `usePeriods()` | `fetchPeriodList` |
|
|
93
|
+
| `useDerivedPeriods()` | `fetchDerivedPeriodList` |
|
|
94
|
+
| `useStrategicIndicators()` | `fetchStrategicIndicatorList`, `fetchStrategicIndicatorDetail` |
|
|
95
|
+
| `useStatisticClassifications()` | `fetchStatisticClassificationList`, `fetchStatisticClassificationDetail` |
|
|
96
|
+
| `useCensus()` | `fetchCensusList` |
|
|
97
|
+
| `useTrade()` | `fetchTradeData` |
|
|
103
98
|
|
|
104
|
-
|
|
99
|
+
### Error Handling
|
|
105
100
|
|
|
106
|
-
|
|
107
|
-
2. **Publications** - Statistical publications and reports
|
|
108
|
-
3. **Infographics** - Visual statistical representations
|
|
109
|
-
4. **News** - Latest statistical news
|
|
110
|
-
5. **News Categories** - News categorization
|
|
111
|
-
6. **Press Releases** - Official press releases
|
|
112
|
-
7. **Static Tables** - Pre-formatted statistical tables
|
|
113
|
-
8. **Subjects** - Statistical subjects
|
|
114
|
-
9. **Subject Categories** - Subject categorization
|
|
115
|
-
10. **Strategic Indicators** - Key economic indicators
|
|
116
|
-
11. **Variables** - Statistical variables
|
|
117
|
-
12. **Units** - Measurement units
|
|
118
|
-
13. **Periods** - Time periods
|
|
119
|
-
14. **Derived Variables** - Calculated statistical variables
|
|
120
|
-
15. **Derived Periods** - Calculated time periods
|
|
121
|
-
16. **Statistic Classifications** - Statistical classification systems
|
|
122
|
-
17. **Census** - Census data
|
|
123
|
-
18. **Dynamic Tables** - Interactive statistical tables
|
|
124
|
-
19. **Foreign Trade** - International trade statistics
|
|
101
|
+
All functions return `Result<T, ApiFailure>` from [neverthrow](https://github.com/supermacro/neverthrow):
|
|
125
102
|
|
|
126
|
-
|
|
103
|
+
```typescript
|
|
104
|
+
const result = await fetchPublicationList({ domain: '7200', lang: DataLanguage.ID })
|
|
127
105
|
|
|
128
|
-
|
|
106
|
+
// Option 1: match
|
|
107
|
+
result.match(
|
|
108
|
+
({ data, pagination }) => console.log(data),
|
|
109
|
+
(error) => console.error(error.message)
|
|
110
|
+
)
|
|
129
111
|
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
112
|
+
// Option 2: guard check
|
|
113
|
+
if (result.isOk()) {
|
|
114
|
+
const { data, pagination } = result.value
|
|
115
|
+
}
|
|
134
116
|
|
|
135
|
-
|
|
117
|
+
if (result.isErr()) {
|
|
118
|
+
console.error(result.error.message)
|
|
119
|
+
}
|
|
120
|
+
```
|
|
136
121
|
|
|
137
|
-
|
|
122
|
+
## Configuration
|
|
138
123
|
|
|
139
124
|
```typescript
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
});
|
|
147
|
-
|
|
148
|
-
publicationsResult.match(
|
|
149
|
-
(result) => {
|
|
150
|
-
result.data.forEach((publication) => {
|
|
151
|
-
console.log(publication.title);
|
|
152
|
-
console.log(publication.issn);
|
|
153
|
-
console.log(publication.cover);
|
|
154
|
-
});
|
|
155
|
-
},
|
|
156
|
-
(error) => console.error(error.message)
|
|
157
|
-
);
|
|
125
|
+
const stadata = createStadataClient({
|
|
126
|
+
apiKey: 'your-api-key', // required
|
|
127
|
+
timeout: 15000, // optional, ms (default: 30000)
|
|
128
|
+
debug: true, // optional, enable debug logging
|
|
129
|
+
baseURL: 'https://...', // optional, custom base URL
|
|
130
|
+
})
|
|
158
131
|
```
|
|
159
132
|
|
|
160
|
-
|
|
133
|
+
## Migration from v1
|
|
161
134
|
|
|
162
|
-
|
|
163
|
-
// Get static tables with filters
|
|
164
|
-
const tablesResult = await stadata.list.staticTables({
|
|
165
|
-
lang: DataLanguage.EN,
|
|
166
|
-
domain: '7315',
|
|
167
|
-
page: 1,
|
|
168
|
-
perPage: 15,
|
|
169
|
-
});
|
|
170
|
-
|
|
171
|
-
tablesResult.match(
|
|
172
|
-
(result) => {
|
|
173
|
-
result.data.forEach((table) => {
|
|
174
|
-
console.log(table.title);
|
|
175
|
-
console.log(table.subjectId);
|
|
176
|
-
console.log(table.table);
|
|
177
|
-
});
|
|
178
|
-
},
|
|
179
|
-
(error) => console.error(error.message)
|
|
180
|
-
);
|
|
181
|
-
```
|
|
135
|
+
Version 2 introduces a **breaking change** from the class-based API to the composable API.
|
|
182
136
|
|
|
183
|
-
###
|
|
137
|
+
### v1 (deprecated)
|
|
184
138
|
|
|
185
139
|
```typescript
|
|
186
|
-
|
|
187
|
-
const
|
|
140
|
+
await StadataJS.init({ apiKey: 'key' })
|
|
141
|
+
const stadata = StadataJS.instance
|
|
142
|
+
|
|
143
|
+
const publications = await stadata.list.publications({
|
|
144
|
+
domain: '7200',
|
|
188
145
|
lang: DataLanguage.ID,
|
|
189
|
-
|
|
190
|
-
perPage: 10,
|
|
191
|
-
});
|
|
192
|
-
|
|
193
|
-
tradeResult.match(
|
|
194
|
-
(result) => {
|
|
195
|
-
result.data.forEach((trade) => {
|
|
196
|
-
console.log(trade.title);
|
|
197
|
-
console.log(trade.period);
|
|
198
|
-
console.log(trade.hsLevel);
|
|
199
|
-
});
|
|
200
|
-
},
|
|
201
|
-
(error) => console.error(error.message)
|
|
202
|
-
);
|
|
146
|
+
})
|
|
203
147
|
```
|
|
204
148
|
|
|
205
|
-
###
|
|
206
|
-
|
|
207
|
-
The SDK uses the Result pattern from the `neverthrow` library for elegant error handling:
|
|
149
|
+
### v2 (recommended)
|
|
208
150
|
|
|
209
151
|
```typescript
|
|
210
|
-
|
|
211
|
-
lang: DataLanguage.EN,
|
|
212
|
-
});
|
|
213
|
-
|
|
214
|
-
// Pattern matching approach
|
|
215
|
-
result.match(
|
|
216
|
-
(success) => {
|
|
217
|
-
// Handle success case
|
|
218
|
-
console.log('Data:', success.data);
|
|
219
|
-
},
|
|
220
|
-
(error) => {
|
|
221
|
-
// Handle error case
|
|
222
|
-
console.error('Error occurred:', error.message);
|
|
223
|
-
}
|
|
224
|
-
);
|
|
152
|
+
import { initStadata, usePublications, DataLanguage } from 'stadata-js'
|
|
225
153
|
|
|
226
|
-
//
|
|
227
|
-
|
|
228
|
-
const data = result.value;
|
|
229
|
-
console.log('Success:', data);
|
|
230
|
-
} else {
|
|
231
|
-
const error = result.error;
|
|
232
|
-
console.error('Failed:', error);
|
|
233
|
-
}
|
|
234
|
-
```
|
|
154
|
+
// initialize once at app entry point
|
|
155
|
+
initStadata({ apiKey: 'key' })
|
|
235
156
|
|
|
236
|
-
|
|
157
|
+
// use composables anywhere in your app
|
|
158
|
+
const { fetchPublicationList, fetchPublicationDetail } = usePublications()
|
|
237
159
|
|
|
238
|
-
|
|
160
|
+
const publications = await fetchPublicationList({
|
|
161
|
+
domain: '7200',
|
|
162
|
+
lang: DataLanguage.ID,
|
|
163
|
+
})
|
|
164
|
+
```
|
|
239
165
|
|
|
240
|
-
|
|
166
|
+
### What changed
|
|
241
167
|
|
|
242
|
-
|
|
168
|
+
- `StadataJS.init()` → `initStadata()`
|
|
169
|
+
- `StadataJS.instance.list.publications()` → `usePublications().fetchPublicationList()`
|
|
170
|
+
- `StadataJS.instance.view.publication()` → `usePublications().fetchPublicationDetail()`
|
|
171
|
+
- list/view methods are now grouped by composable (`useDomains`, `useNews`, `useDynamicTables`, etc.)
|
|
172
|
+
- global initialization is the default pattern, so you no longer need to carry a singleton instance around your app
|
|
243
173
|
|
|
244
|
-
|
|
245
|
-
- `StadataJS.instance: StadataJS` - Get the singleton SDK instance
|
|
174
|
+
### Advanced migration path
|
|
246
175
|
|
|
247
|
-
|
|
176
|
+
If you need multiple clients (for example different API keys), you can still use an explicit client:
|
|
248
177
|
|
|
249
178
|
```typescript
|
|
250
|
-
|
|
251
|
-
apiKey: string; // Your BPS WebAPI key (required)
|
|
252
|
-
debug?: boolean; // Enable debug logging (default: false)
|
|
253
|
-
baseUrl?: string; // Custom API base URL (optional)
|
|
254
|
-
}
|
|
255
|
-
```
|
|
179
|
+
import { createStadataClient, usePublications } from 'stadata-js'
|
|
256
180
|
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
```typescript
|
|
260
|
-
enum DataLanguage {
|
|
261
|
-
ID = 'ind', // Indonesian
|
|
262
|
-
EN = 'eng', // English
|
|
263
|
-
}
|
|
181
|
+
const client = createStadataClient({ apiKey: 'other-key' })
|
|
182
|
+
const { fetchPublicationList } = usePublications(client)
|
|
264
183
|
```
|
|
265
184
|
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
The SDK follows Clean Architecture principles with clear separation between:
|
|
269
|
-
|
|
270
|
-
- **Domain Layer** - Business entities and use cases
|
|
271
|
-
- **Data Layer** - Repository implementations and data sources
|
|
272
|
-
- **Core Layer** - Base classes, utilities, and infrastructure
|
|
273
|
-
- **API Layer** - Public-facing SDK interface
|
|
274
|
-
|
|
275
|
-
This architecture ensures:
|
|
276
|
-
- High testability
|
|
277
|
-
- Loose coupling between components
|
|
278
|
-
- Easy maintenance and extensibility
|
|
279
|
-
- Clear separation of concerns
|
|
280
|
-
|
|
281
|
-
## Contributing
|
|
282
|
-
|
|
283
|
-
We welcome contributions! Whether you're fixing bugs, improving documentation, adding tests, or implementing new features, your help is appreciated.
|
|
185
|
+
> `StadataJS` class is kept as `@deprecated` in v2 for transition purposes and will be removed in v3.
|
|
284
186
|
|
|
285
|
-
|
|
187
|
+
## Advanced: Multiple Clients
|
|
286
188
|
|
|
287
|
-
|
|
288
|
-
2. Create a feature branch (`git checkout -b feature/amazing-feature`)
|
|
289
|
-
3. Commit your changes using conventional commits (`git commit -m 'feat: add amazing feature'`)
|
|
290
|
-
4. Push to the branch (`git push origin feature/amazing-feature`)
|
|
291
|
-
5. Open a Pull Request to the `develop` branch
|
|
189
|
+
If you need multiple clients (e.g. different API keys), use `createStadataClient` directly:
|
|
292
190
|
|
|
293
|
-
|
|
191
|
+
```typescript
|
|
192
|
+
import { createStadataClient, usePublications } from 'stadata-js'
|
|
294
193
|
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
- **Testing** - Add or improve test coverage
|
|
299
|
-
- **Code** - Implement new features or fix bugs
|
|
194
|
+
const client = createStadataClient({ apiKey: 'other-key' })
|
|
195
|
+
const { fetchPublicationList } = usePublications(client) // explicit client
|
|
196
|
+
```
|
|
300
197
|
|
|
301
198
|
## License
|
|
302
199
|
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
## Links
|
|
306
|
-
|
|
307
|
-
- [npm Package](https://www.npmjs.com/package/stadata-js)
|
|
308
|
-
- [GitHub Repository](https://github.com/IPDS-59/stadata_js)
|
|
309
|
-
- [Issue Tracker](https://github.com/IPDS-59/stadata_js/issues)
|
|
310
|
-
- [BPS Website](https://www.bps.go.id)
|
|
311
|
-
|
|
312
|
-
## Acknowledgments
|
|
313
|
-
|
|
314
|
-
This SDK is an unofficial community project and is not affiliated with or endorsed by BPS (Badan Pusat Statistik). All data accessed through this SDK is provided by BPS through their official WebAPI.
|
|
315
|
-
|
|
316
|
-
---
|
|
317
|
-
|
|
318
|
-
Made with ❤️ for the Indonesian developer community
|
|
200
|
+
MIT © [IPDS-59](https://github.com/IPDS-59)
|