@scouterna/scoutnet 0.3.6
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/CHANGELOG.md +106 -0
- package/README.md +101 -0
- package/dist/client.d.ts +12 -0
- package/dist/client.js +23 -0
- package/dist/client.js.map +1 -0
- package/dist/generated/api-types.d.ts +410 -0
- package/dist/generated/api-types.js +6 -0
- package/dist/generated/api-types.js.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +3 -0
- package/dist/index.js.map +1 -0
- package/dummy +2 -0
- package/package.json +36 -0
- package/src/client.ts +43 -0
- package/src/generated/.gitkeep +0 -0
- package/src/index.ts +2 -0
- package/tsconfig.json +25 -0
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
## [0.3.6](https://github.com/Scouterna/scoutnet-api/compare/scoutnet-v0.3.5...scoutnet-v0.3.6) (2025-03-30)
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
### Bug Fixes
|
|
7
|
+
|
|
8
|
+
* dummy ([a29431c](https://github.com/Scouterna/scoutnet-api/commit/a29431ce4ca49c5120e0f6855877b43c601a8a38))
|
|
9
|
+
|
|
10
|
+
## [0.3.5](https://github.com/Scouterna/scoutnet-api/compare/scoutnet-v0.3.4...scoutnet-v0.3.5) (2025-03-30)
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
### Bug Fixes
|
|
14
|
+
|
|
15
|
+
* add metadata to packages ([e2a5728](https://github.com/Scouterna/scoutnet-api/commit/e2a5728ba5ec3604f46a4d70a9ac891b399073d9))
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
### Dependencies
|
|
19
|
+
|
|
20
|
+
* The following workspace dependencies were updated
|
|
21
|
+
* devDependencies
|
|
22
|
+
* @scouterna/scoutnet-openapi bumped to 0.1.5
|
|
23
|
+
|
|
24
|
+
## [0.3.4](https://github.com/Scouterna/scoutnet-api/compare/scoutnet-v0.3.3...scoutnet-v0.3.4) (2025-03-30)
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
### Bug Fixes
|
|
28
|
+
|
|
29
|
+
* dummy change ([60e78ee](https://github.com/Scouterna/scoutnet-api/commit/60e78eeaf9940e30564c0856d3a038da96e4efd1))
|
|
30
|
+
|
|
31
|
+
## [0.3.3](https://github.com/Scouterna/scoutnet-api/compare/scoutnet-v0.3.2...scoutnet-v0.3.3) (2025-03-30)
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
### Bug Fixes
|
|
35
|
+
|
|
36
|
+
* add author to public packages ([e963310](https://github.com/Scouterna/scoutnet-api/commit/e963310c54ece98eda03ea85a2bea8dd3fb98e08))
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
### Dependencies
|
|
40
|
+
|
|
41
|
+
* The following workspace dependencies were updated
|
|
42
|
+
* devDependencies
|
|
43
|
+
* @scouterna/scoutnet-openapi bumped to 0.1.4
|
|
44
|
+
|
|
45
|
+
## [0.3.2](https://github.com/Scouterna/scoutnet-api/compare/scoutnet-v0.3.1...scoutnet-v0.3.2) (2025-03-27)
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
### Dependencies
|
|
49
|
+
|
|
50
|
+
* The following workspace dependencies were updated
|
|
51
|
+
* devDependencies
|
|
52
|
+
* @scouterna/scoutnet-openapi bumped to 0.1.3
|
|
53
|
+
|
|
54
|
+
## [0.3.1](https://github.com/Scouterna/scoutnet-api/compare/scoutnet-v0.3.0...scoutnet-v0.3.1) (2025-03-27)
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
### Bug Fixes
|
|
58
|
+
|
|
59
|
+
* add jsdoc to createAuthorizationHeader ([9441e0d](https://github.com/Scouterna/scoutnet-api/commit/9441e0dd0b20fbadc7dd91d70c39539c9b3c0c87))
|
|
60
|
+
|
|
61
|
+
## [0.3.0](https://github.com/Scouterna/scoutnet-api/compare/scoutnet-v0.2.0...scoutnet-v0.3.0) (2025-03-27)
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
### Features
|
|
65
|
+
|
|
66
|
+
* initial commit ([b4f964b](https://github.com/Scouterna/scoutnet-api/commit/b4f964bf7ce908386feaed5171f0acc73f27942d))
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
### Bug Fixes
|
|
70
|
+
|
|
71
|
+
* remove unfinished sentence ([56e46c3](https://github.com/Scouterna/scoutnet-api/commit/56e46c31cc7abc9ce759802ea6eadee289aaed46))
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
### Dependencies
|
|
75
|
+
|
|
76
|
+
* The following workspace dependencies were updated
|
|
77
|
+
* devDependencies
|
|
78
|
+
* @scouterna/scoutnet-openapi bumped to 0.1.2
|
|
79
|
+
|
|
80
|
+
## [0.2.0](https://github.com/Scouterna/scoutnet-api/compare/@scoutnet/scoutnet-v0.1.0...@scoutnet/scoutnet-v0.2.0) (2025-03-27)
|
|
81
|
+
|
|
82
|
+
|
|
83
|
+
### Features
|
|
84
|
+
|
|
85
|
+
* initial commit ([b4f964b](https://github.com/Scouterna/scoutnet-api/commit/b4f964bf7ce908386feaed5171f0acc73f27942d))
|
|
86
|
+
|
|
87
|
+
|
|
88
|
+
### Dependencies
|
|
89
|
+
|
|
90
|
+
* The following workspace dependencies were updated
|
|
91
|
+
* devDependencies
|
|
92
|
+
* @scouterna/scoutnet-openapi bumped to 0.1.1
|
|
93
|
+
|
|
94
|
+
## 0.1.0 (2025-03-27)
|
|
95
|
+
|
|
96
|
+
|
|
97
|
+
### Features
|
|
98
|
+
|
|
99
|
+
* initial commit ([b4f964b](https://github.com/Scouterna/scoutnet-api/commit/b4f964bf7ce908386feaed5171f0acc73f27942d))
|
|
100
|
+
|
|
101
|
+
|
|
102
|
+
### Dependencies
|
|
103
|
+
|
|
104
|
+
* The following workspace dependencies were updated
|
|
105
|
+
* devDependencies
|
|
106
|
+
* @scouterna/scoutnet-openapi bumped to 0.1.0
|
package/README.md
ADDED
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
# Scoutnet Node.js API Client
|
|
2
|
+
|
|
3
|
+
This is an API client for the Scoutnet API developed and maintained by
|
|
4
|
+
[Scouternas e-tjänster](https://etjanster.scout.se/). It is automatically
|
|
5
|
+
generated from the
|
|
6
|
+
[Scoutnet OpenAPI Document](https://github.com/Scouterna/scoutnet-api/blob/main/packages/scoutnet-openapi/scoutnet.yaml).
|
|
7
|
+
|
|
8
|
+
The client uses [openapi-typescript](https://openapi-ts.dev/introduction) and
|
|
9
|
+
[openapi-fetch](https://openapi-ts.dev/openapi-fetch/) under the hood. This NPM
|
|
10
|
+
package exports all types generated by openapi-typescript as well as a modified
|
|
11
|
+
version of the `createClient` method from openapi-fetch. This means that you can
|
|
12
|
+
use just the types if you need to build something very custom. For complete
|
|
13
|
+
usage instructions, check out their documentation.
|
|
14
|
+
|
|
15
|
+
## Installation
|
|
16
|
+
|
|
17
|
+
The client is available on NPM:
|
|
18
|
+
|
|
19
|
+
```bash
|
|
20
|
+
npm i @scouterna/scoutnet
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
## Usage
|
|
24
|
+
|
|
25
|
+
### Creating the client
|
|
26
|
+
|
|
27
|
+
You must always start by creating an instance of the API client. This ensures
|
|
28
|
+
all requests will be fully type safe.
|
|
29
|
+
|
|
30
|
+
```ts
|
|
31
|
+
const client = createClient();
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
You can pass options when creating the client that will apply to all requests.
|
|
35
|
+
For example, you might want to use a different server during development.
|
|
36
|
+
|
|
37
|
+
```ts
|
|
38
|
+
const client = createClient({
|
|
39
|
+
baseUrl: 'https://s1.test.custard.no/api'
|
|
40
|
+
});
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
### Making requests
|
|
44
|
+
|
|
45
|
+
When making requests you provide the endpoint you want to call, and the types
|
|
46
|
+
are automatically inferred. Because all endpoints in the Scoutnet API have
|
|
47
|
+
unique access keys this is also where you set the Authorization header.
|
|
48
|
+
|
|
49
|
+
```ts
|
|
50
|
+
const result = await client.GET("/project/get/participants", {
|
|
51
|
+
headers: {
|
|
52
|
+
Authorization: createAuthorizationHeader({
|
|
53
|
+
resourceId: '12345',
|
|
54
|
+
key: '80vn4...n724',
|
|
55
|
+
}),
|
|
56
|
+
},
|
|
57
|
+
});
|
|
58
|
+
|
|
59
|
+
if ('error' in result) {
|
|
60
|
+
// Handle the error properly
|
|
61
|
+
throw new Error(`Request failed with status code ${result.response.status}`);
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
console.log(data.participants);
|
|
65
|
+
// ^ Access fully typed properties
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
There are two important notes to be made here.
|
|
69
|
+
|
|
70
|
+
First, make sure to use `if ('error' in result)` to check if there is an error
|
|
71
|
+
as in the example above and not just `if (result.error)`. Since Scoutnet returns
|
|
72
|
+
an empty body on errors such as 401 the latter will pass even though there is an
|
|
73
|
+
error.
|
|
74
|
+
|
|
75
|
+
Second, often times you will receive multiple levels of data. Consider the
|
|
76
|
+
following simplified example of a response:
|
|
77
|
+
```json
|
|
78
|
+
{
|
|
79
|
+
"first_name": "Janne",
|
|
80
|
+
"last_name": "Långben",
|
|
81
|
+
"contact_info": {
|
|
82
|
+
"1": "0701 23 45 67"
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
As you can see the `contact_info` property contains an object of arbitrary data.
|
|
88
|
+
If we instead imagine there was no contact info the response would look like
|
|
89
|
+
this:
|
|
90
|
+
```json
|
|
91
|
+
{
|
|
92
|
+
"first_name": "Janne",
|
|
93
|
+
"last_name": "Långben",
|
|
94
|
+
"contact_info": []
|
|
95
|
+
}
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
Notice how `contact_info` suddenly became an empty array. This is a quirk of the
|
|
99
|
+
Scoutnet API that happens every time there is an empty object and you will have
|
|
100
|
+
to handle it accordingly. The return type of the API methods should help you
|
|
101
|
+
catch these cases.
|
package/dist/client.d.ts
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { ClientOptions as OpenApiClientOptions } from "openapi-fetch";
|
|
2
|
+
import type { paths } from "./generated/api-types.js";
|
|
3
|
+
export type APICredentials = {
|
|
4
|
+
resourceId: number | string;
|
|
5
|
+
key: string;
|
|
6
|
+
};
|
|
7
|
+
export type ClientOptions = OpenApiClientOptions;
|
|
8
|
+
export declare const createClient: ({ baseUrl, ...clientOptions }: ClientOptions) => import("openapi-fetch").Client<paths, `${string}/${string}`>;
|
|
9
|
+
/**
|
|
10
|
+
* Creates an authorization header for the Scoutnet API.
|
|
11
|
+
*/
|
|
12
|
+
export declare const createAuthorizationHeader: ({ resourceId, key: token, }: APICredentials) => string;
|
package/dist/client.js
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import openApiCreateClient from "openapi-fetch";
|
|
2
|
+
export const createClient = ({ baseUrl = "https://scoutnet.se/api", ...clientOptions }) => {
|
|
3
|
+
const client = openApiCreateClient({
|
|
4
|
+
baseUrl,
|
|
5
|
+
...clientOptions,
|
|
6
|
+
});
|
|
7
|
+
return client;
|
|
8
|
+
};
|
|
9
|
+
const base64encode = (data) => {
|
|
10
|
+
if (typeof window === "undefined") {
|
|
11
|
+
return Buffer.from(data).toString("base64");
|
|
12
|
+
}
|
|
13
|
+
return window.btoa(data);
|
|
14
|
+
};
|
|
15
|
+
/**
|
|
16
|
+
* Creates an authorization header for the Scoutnet API.
|
|
17
|
+
*/
|
|
18
|
+
export const createAuthorizationHeader = ({ resourceId, key: token, }) => {
|
|
19
|
+
const authString = `${resourceId}:${token}`;
|
|
20
|
+
const encoded = base64encode(authString);
|
|
21
|
+
return `Basic ${encoded}`;
|
|
22
|
+
};
|
|
23
|
+
//# sourceMappingURL=client.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AACA,OAAO,mBAAmB,MAAM,eAAe,CAAC;AAWhD,MAAM,CAAC,MAAM,YAAY,GAAG,CAAC,EAC3B,OAAO,GAAG,yBAAyB,EACnC,GAAG,aAAa,EACF,EAAE,EAAE;IAClB,MAAM,MAAM,GAAG,mBAAmB,CAAQ;QACxC,OAAO;QACP,GAAG,aAAa;KACjB,CAAC,CAAC;IAEH,OAAO,MAAM,CAAC;AAChB,CAAC,CAAC;AAEF,MAAM,YAAY,GAAG,CAAC,IAAY,EAAE,EAAE;IACpC,IAAI,OAAO,MAAM,KAAK,WAAW,EAAE,CAAC;QAClC,OAAO,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;IAC9C,CAAC;IAED,OAAO,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAC3B,CAAC,CAAC;AAEF;;GAEG;AACH,MAAM,CAAC,MAAM,yBAAyB,GAAG,CAAC,EACxC,UAAU,EACV,GAAG,EAAE,KAAK,GACK,EAAE,EAAE;IACnB,MAAM,UAAU,GAAG,GAAG,UAAU,IAAI,KAAK,EAAE,CAAC;IAC5C,MAAM,OAAO,GAAG,YAAY,CAAC,UAAU,CAAC,CAAC;IACzC,OAAO,SAAS,OAAO,EAAE,CAAC;AAC5B,CAAC,CAAC"}
|
|
@@ -0,0 +1,410 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* This file was auto-generated by openapi-typescript.
|
|
3
|
+
* Do not make direct changes to the file.
|
|
4
|
+
*/
|
|
5
|
+
export interface paths {
|
|
6
|
+
"/body_key_list": {
|
|
7
|
+
parameters: {
|
|
8
|
+
query?: never;
|
|
9
|
+
header?: never;
|
|
10
|
+
path?: never;
|
|
11
|
+
cookie?: never;
|
|
12
|
+
};
|
|
13
|
+
/**
|
|
14
|
+
* Restricted endpoint. Get a list of all bodies and their relations to each other
|
|
15
|
+
* @description For security reasons this endpoint is not publicly available and can only be used by internally developed systems.
|
|
16
|
+
*/
|
|
17
|
+
get: operations["listBodyKeys"];
|
|
18
|
+
put?: never;
|
|
19
|
+
post?: never;
|
|
20
|
+
delete?: never;
|
|
21
|
+
options?: never;
|
|
22
|
+
head?: never;
|
|
23
|
+
patch?: never;
|
|
24
|
+
trace?: never;
|
|
25
|
+
};
|
|
26
|
+
"/project/get/groups": {
|
|
27
|
+
parameters: {
|
|
28
|
+
query?: never;
|
|
29
|
+
header?: never;
|
|
30
|
+
path?: never;
|
|
31
|
+
cookie?: never;
|
|
32
|
+
};
|
|
33
|
+
/** Get a list of groups with members attending a project */
|
|
34
|
+
get: operations["getProjectGroups"];
|
|
35
|
+
put?: never;
|
|
36
|
+
post?: never;
|
|
37
|
+
delete?: never;
|
|
38
|
+
options?: never;
|
|
39
|
+
head?: never;
|
|
40
|
+
patch?: never;
|
|
41
|
+
trace?: never;
|
|
42
|
+
};
|
|
43
|
+
"/project/get/participants": {
|
|
44
|
+
parameters: {
|
|
45
|
+
query?: never;
|
|
46
|
+
header?: never;
|
|
47
|
+
path?: never;
|
|
48
|
+
cookie?: never;
|
|
49
|
+
};
|
|
50
|
+
/** Get a list of members who are registered on the project */
|
|
51
|
+
get: operations["getProjectParticipants"];
|
|
52
|
+
put?: never;
|
|
53
|
+
post?: never;
|
|
54
|
+
delete?: never;
|
|
55
|
+
options?: never;
|
|
56
|
+
head?: never;
|
|
57
|
+
patch?: never;
|
|
58
|
+
trace?: never;
|
|
59
|
+
};
|
|
60
|
+
"/project/checkin": {
|
|
61
|
+
parameters: {
|
|
62
|
+
query?: never;
|
|
63
|
+
header?: never;
|
|
64
|
+
path?: never;
|
|
65
|
+
cookie?: never;
|
|
66
|
+
};
|
|
67
|
+
get?: never;
|
|
68
|
+
/** Update the check-in state of participant(s) on the project */
|
|
69
|
+
put: operations["updateCheckin"];
|
|
70
|
+
post?: never;
|
|
71
|
+
delete?: never;
|
|
72
|
+
options?: never;
|
|
73
|
+
head?: never;
|
|
74
|
+
patch?: never;
|
|
75
|
+
trace?: never;
|
|
76
|
+
};
|
|
77
|
+
}
|
|
78
|
+
export type webhooks = Record<string, never>;
|
|
79
|
+
export interface components {
|
|
80
|
+
schemas: {
|
|
81
|
+
body: {
|
|
82
|
+
/** @description Unique key for the body. Usually body type and body ID separated by an underscore. */
|
|
83
|
+
body_key?: string;
|
|
84
|
+
/** @description The name of the body. */
|
|
85
|
+
body_name?: string;
|
|
86
|
+
/** @enum {string} */
|
|
87
|
+
body_type?: "organisation" | "region" | "network" | "district" | "corps" | "group" | "troop" | "patrol";
|
|
88
|
+
/** @description ID of the body. */
|
|
89
|
+
body_id?: number;
|
|
90
|
+
/** @description ID of the organisation this body belongs to. If this body is an organisation, this is the same as body_id. */
|
|
91
|
+
organisation_id?: number;
|
|
92
|
+
};
|
|
93
|
+
address: {
|
|
94
|
+
care_of?: string;
|
|
95
|
+
location_name?: string;
|
|
96
|
+
line_1?: string;
|
|
97
|
+
line_2?: string;
|
|
98
|
+
line_3?: string;
|
|
99
|
+
post_code?: string;
|
|
100
|
+
post_town?: string;
|
|
101
|
+
latitude?: string;
|
|
102
|
+
longitude?: string;
|
|
103
|
+
info?: string;
|
|
104
|
+
country_code?: string;
|
|
105
|
+
section_name?: string;
|
|
106
|
+
section_priority?: boolean;
|
|
107
|
+
};
|
|
108
|
+
project_stats: {
|
|
109
|
+
project_id?: number;
|
|
110
|
+
group_participants?: number;
|
|
111
|
+
project_name?: string;
|
|
112
|
+
/** @description NOT YET DOCUMENTED */
|
|
113
|
+
questions?: Record<string, never>;
|
|
114
|
+
};
|
|
115
|
+
group: {
|
|
116
|
+
/** @description The name of the group. */
|
|
117
|
+
name?: string;
|
|
118
|
+
/** @description A description of the group. */
|
|
119
|
+
description?: string;
|
|
120
|
+
/** @description Group ID number. */
|
|
121
|
+
group_no?: number;
|
|
122
|
+
/** @description Corps or "samverkansorganisation". `null` means Scouterna. */
|
|
123
|
+
corps_id?: number;
|
|
124
|
+
/** @description 1: Scoutkår
|
|
125
|
+
* 2: Sjöscoutkår
|
|
126
|
+
* 3: Hub-Kår
|
|
127
|
+
* */
|
|
128
|
+
group_types?: number[];
|
|
129
|
+
/** @description 1: Bäverscouter
|
|
130
|
+
* 2: Spårarscouter
|
|
131
|
+
* 3: Upptäckarscouter
|
|
132
|
+
* 4: Äventyrarscouter
|
|
133
|
+
* 5: Utmanarscouter
|
|
134
|
+
* 6: Roverscouter
|
|
135
|
+
* 7: Annat
|
|
136
|
+
* 8: Familjescouter
|
|
137
|
+
* */
|
|
138
|
+
troop_types?: number[];
|
|
139
|
+
/** @description Municipality ID. Name can be found in the region object. */
|
|
140
|
+
municipality_id?: number;
|
|
141
|
+
/** @description County ID. Name can be found in the region object. */
|
|
142
|
+
county_id?: number;
|
|
143
|
+
/** @description Whether the group is open for new members or not. */
|
|
144
|
+
public_registration_enabled?: boolean;
|
|
145
|
+
/** @description Destination list for public registration.
|
|
146
|
+
* 1: Medlemskap som väntar på godkännande (Membership waiting for approval)
|
|
147
|
+
* 2: Flytta till väntelista (Move to waiting list)
|
|
148
|
+
* */
|
|
149
|
+
destination_list?: number;
|
|
150
|
+
/** @description NOT YET DOCUMENTED */
|
|
151
|
+
badges?: Record<string, never>;
|
|
152
|
+
addresses?: {
|
|
153
|
+
[key: string]: components["schemas"]["address"];
|
|
154
|
+
};
|
|
155
|
+
email?: {
|
|
156
|
+
[key: string]: string;
|
|
157
|
+
};
|
|
158
|
+
email_membership?: {
|
|
159
|
+
[key: string]: string;
|
|
160
|
+
};
|
|
161
|
+
project_stats?: {
|
|
162
|
+
[key: string]: components["schemas"]["project_stats"];
|
|
163
|
+
};
|
|
164
|
+
};
|
|
165
|
+
district: {
|
|
166
|
+
/** @description The name of the district. */
|
|
167
|
+
name?: string;
|
|
168
|
+
groups?: {
|
|
169
|
+
[key: string]: components["schemas"]["group"];
|
|
170
|
+
};
|
|
171
|
+
};
|
|
172
|
+
region: {
|
|
173
|
+
/** @description The name of the region. */
|
|
174
|
+
name?: string;
|
|
175
|
+
districts?: {
|
|
176
|
+
[key: string]: components["schemas"]["district"];
|
|
177
|
+
};
|
|
178
|
+
/** @description NOT YET DOCUMENTED */
|
|
179
|
+
corps?: Record<string, never>;
|
|
180
|
+
/** @description Key-value map of municipality IDs (used in the response) to their names. */
|
|
181
|
+
municipalities?: {
|
|
182
|
+
[key: string]: string;
|
|
183
|
+
};
|
|
184
|
+
/** @description Key-value map of country IDs (used in the response) to their names. */
|
|
185
|
+
conties?: {
|
|
186
|
+
[key: string]: string;
|
|
187
|
+
};
|
|
188
|
+
};
|
|
189
|
+
organisation: {
|
|
190
|
+
/** @description The name of the organisation. */
|
|
191
|
+
name?: string;
|
|
192
|
+
regions?: {
|
|
193
|
+
[key: string]: components["schemas"]["region"];
|
|
194
|
+
};
|
|
195
|
+
};
|
|
196
|
+
project_member: {
|
|
197
|
+
checked_in?: boolean | null;
|
|
198
|
+
attended?: boolean | null;
|
|
199
|
+
cancelled?: boolean | null;
|
|
200
|
+
member_status?: number | null;
|
|
201
|
+
member_no?: number | null;
|
|
202
|
+
group_registration?: boolean | null;
|
|
203
|
+
first_name?: string | null;
|
|
204
|
+
last_name?: string | null;
|
|
205
|
+
ssno?: string | null;
|
|
206
|
+
registration_date?: string | null;
|
|
207
|
+
cancelled_date?: string | null;
|
|
208
|
+
primary_email?: string | null;
|
|
209
|
+
fee_id?: number | null;
|
|
210
|
+
primary_membership_info?: {
|
|
211
|
+
patrol_id?: number | null;
|
|
212
|
+
patrol_name?: string | null;
|
|
213
|
+
troop_id?: number | null;
|
|
214
|
+
troop_name?: string | null;
|
|
215
|
+
group_id?: number | null;
|
|
216
|
+
group_name?: string | null;
|
|
217
|
+
district_id?: number | null;
|
|
218
|
+
district_name?: string | null;
|
|
219
|
+
region_id?: number | null;
|
|
220
|
+
region_name?: string | null;
|
|
221
|
+
organisation_id?: number | null;
|
|
222
|
+
organisation_name?: string | null;
|
|
223
|
+
} | unknown[] | null;
|
|
224
|
+
group_registration_info?: {
|
|
225
|
+
group_id?: number | null;
|
|
226
|
+
patrol_id?: number | null;
|
|
227
|
+
group_name?: string | null;
|
|
228
|
+
org_id?: number | null;
|
|
229
|
+
org_name?: string | null;
|
|
230
|
+
district_id?: number | null;
|
|
231
|
+
district_name?: string | null;
|
|
232
|
+
patrol_name?: string | null;
|
|
233
|
+
} | {
|
|
234
|
+
group_id?: number | null;
|
|
235
|
+
patrol_id?: number | null;
|
|
236
|
+
group_name?: string | null;
|
|
237
|
+
org_id?: number | null;
|
|
238
|
+
org_name?: string | null;
|
|
239
|
+
district_id?: number | null;
|
|
240
|
+
district_name?: string | null;
|
|
241
|
+
patrol_name?: string | null;
|
|
242
|
+
} | null;
|
|
243
|
+
/** @description NOT YET DOCUMENTED */
|
|
244
|
+
questions?: Record<string, never>;
|
|
245
|
+
contact_info?: {
|
|
246
|
+
[key: string]: string;
|
|
247
|
+
};
|
|
248
|
+
};
|
|
249
|
+
project_get_participants_labels: {
|
|
250
|
+
member_status?: {
|
|
251
|
+
[key: string]: string;
|
|
252
|
+
};
|
|
253
|
+
sex?: {
|
|
254
|
+
[key: string]: string;
|
|
255
|
+
};
|
|
256
|
+
project_fee?: {
|
|
257
|
+
[key: string]: string;
|
|
258
|
+
};
|
|
259
|
+
contact_type?: {
|
|
260
|
+
[key: string]: string;
|
|
261
|
+
};
|
|
262
|
+
};
|
|
263
|
+
checkin: {
|
|
264
|
+
/**
|
|
265
|
+
* @description Set to 1 to mark the participant as checked in, 0 to mark as checked out.
|
|
266
|
+
* @enum {number}
|
|
267
|
+
*/
|
|
268
|
+
checked_in?: 0 | 1;
|
|
269
|
+
/** @description A comment to be stored with the check-in. If checked_in is not provided a comment will be stored without changing the check-in state. */
|
|
270
|
+
comment?: string;
|
|
271
|
+
/**
|
|
272
|
+
* @description Only applicable when checking out. Set to 1 to mark the participant as attended, 0 to mark as not attended. Default is 1.
|
|
273
|
+
* @default 1
|
|
274
|
+
* @enum {number}
|
|
275
|
+
*/
|
|
276
|
+
attended: 0 | 1;
|
|
277
|
+
};
|
|
278
|
+
checkin_response: {
|
|
279
|
+
/** @description List of member IDs that were checked in. */
|
|
280
|
+
checked_in?: number[];
|
|
281
|
+
/** @description List of member IDs that were checked out and marked as attended. */
|
|
282
|
+
checked_out_attended?: number[];
|
|
283
|
+
/** @description List of member IDs that were checked out and marked as not attended. */
|
|
284
|
+
checked_out_not_attended?: number[];
|
|
285
|
+
/** @description List of member IDs that were not changed. If only a comment was added, the member is still in this list. */
|
|
286
|
+
unchanged?: number[];
|
|
287
|
+
/** @description List of member IDs that exist but are not participants on the project. */
|
|
288
|
+
not_found?: number[];
|
|
289
|
+
/** @description List of member IDs that do not exist in the system. */
|
|
290
|
+
no_member?: number[];
|
|
291
|
+
/** @description Total number of members that were processed. Unchanged members are counted as well. */
|
|
292
|
+
total?: number;
|
|
293
|
+
/** @description NOT YET DOCUMENTED */
|
|
294
|
+
updated_questions?: Record<string, never>;
|
|
295
|
+
};
|
|
296
|
+
};
|
|
297
|
+
responses: {
|
|
298
|
+
/** @description When unauthorized there will be no response body. */
|
|
299
|
+
NotAuthorized: {
|
|
300
|
+
headers: {
|
|
301
|
+
[name: string]: unknown;
|
|
302
|
+
};
|
|
303
|
+
content?: never;
|
|
304
|
+
};
|
|
305
|
+
};
|
|
306
|
+
parameters: never;
|
|
307
|
+
requestBodies: never;
|
|
308
|
+
headers: never;
|
|
309
|
+
pathItems: never;
|
|
310
|
+
}
|
|
311
|
+
export type $defs = Record<string, never>;
|
|
312
|
+
export interface operations {
|
|
313
|
+
listBodyKeys: {
|
|
314
|
+
parameters: {
|
|
315
|
+
query?: never;
|
|
316
|
+
header?: never;
|
|
317
|
+
path?: never;
|
|
318
|
+
cookie?: never;
|
|
319
|
+
};
|
|
320
|
+
requestBody?: never;
|
|
321
|
+
responses: {
|
|
322
|
+
200: {
|
|
323
|
+
headers: {
|
|
324
|
+
[name: string]: unknown;
|
|
325
|
+
};
|
|
326
|
+
content: {
|
|
327
|
+
"application/json": {
|
|
328
|
+
[key: string]: components["schemas"]["body"];
|
|
329
|
+
};
|
|
330
|
+
};
|
|
331
|
+
};
|
|
332
|
+
401: components["responses"]["NotAuthorized"];
|
|
333
|
+
};
|
|
334
|
+
};
|
|
335
|
+
getProjectGroups: {
|
|
336
|
+
parameters: {
|
|
337
|
+
query?: never;
|
|
338
|
+
header?: never;
|
|
339
|
+
path?: never;
|
|
340
|
+
cookie?: never;
|
|
341
|
+
};
|
|
342
|
+
requestBody?: never;
|
|
343
|
+
responses: {
|
|
344
|
+
/** @description Keys of the response object are group IDs and values are group objects. */
|
|
345
|
+
200: {
|
|
346
|
+
headers: {
|
|
347
|
+
[name: string]: unknown;
|
|
348
|
+
};
|
|
349
|
+
content: {
|
|
350
|
+
"application/json": {
|
|
351
|
+
[key: string]: components["schemas"]["organisation"];
|
|
352
|
+
};
|
|
353
|
+
};
|
|
354
|
+
};
|
|
355
|
+
401: components["responses"]["NotAuthorized"];
|
|
356
|
+
};
|
|
357
|
+
};
|
|
358
|
+
getProjectParticipants: {
|
|
359
|
+
parameters: {
|
|
360
|
+
query?: never;
|
|
361
|
+
header?: never;
|
|
362
|
+
path?: never;
|
|
363
|
+
cookie?: never;
|
|
364
|
+
};
|
|
365
|
+
requestBody?: never;
|
|
366
|
+
responses: {
|
|
367
|
+
200: {
|
|
368
|
+
headers: {
|
|
369
|
+
[name: string]: unknown;
|
|
370
|
+
};
|
|
371
|
+
content: {
|
|
372
|
+
"application/json": {
|
|
373
|
+
participants?: {
|
|
374
|
+
[key: string]: components["schemas"]["project_member"];
|
|
375
|
+
} | unknown[] | null;
|
|
376
|
+
labels?: components["schemas"]["project_get_participants_labels"];
|
|
377
|
+
};
|
|
378
|
+
};
|
|
379
|
+
};
|
|
380
|
+
401: components["responses"]["NotAuthorized"];
|
|
381
|
+
};
|
|
382
|
+
};
|
|
383
|
+
updateCheckin: {
|
|
384
|
+
parameters: {
|
|
385
|
+
query?: never;
|
|
386
|
+
header?: never;
|
|
387
|
+
path?: never;
|
|
388
|
+
cookie?: never;
|
|
389
|
+
};
|
|
390
|
+
/** @description An object where the keys are member IDs and the values are objects with check-in details. */
|
|
391
|
+
requestBody: {
|
|
392
|
+
content: {
|
|
393
|
+
"application/json": {
|
|
394
|
+
[key: string]: components["schemas"]["checkin"];
|
|
395
|
+
};
|
|
396
|
+
};
|
|
397
|
+
};
|
|
398
|
+
responses: {
|
|
399
|
+
200: {
|
|
400
|
+
headers: {
|
|
401
|
+
[name: string]: unknown;
|
|
402
|
+
};
|
|
403
|
+
content: {
|
|
404
|
+
"application/json": components["schemas"]["checkin_response"];
|
|
405
|
+
};
|
|
406
|
+
};
|
|
407
|
+
401: components["responses"]["NotAuthorized"];
|
|
408
|
+
};
|
|
409
|
+
};
|
|
410
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"api-types.js","sourceRoot":"","sources":["../../src/generated/api-types.ts"],"names":[],"mappings":"AAAA;;;GAGG"}
|
package/dist/index.d.ts
ADDED
package/dist/index.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,0BAA0B,CAAC;AACzC,cAAc,aAAa,CAAC"}
|
package/dummy
ADDED
package/package.json
ADDED
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@scouterna/scoutnet",
|
|
3
|
+
"version": "0.3.6",
|
|
4
|
+
"description": "API client for the Scoutnet API.",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"scouterna",
|
|
7
|
+
"scoutnet"
|
|
8
|
+
],
|
|
9
|
+
"author": "Malcolm Nihlén <malcolm.nihlen@scouterna.se>",
|
|
10
|
+
"license": "MIT",
|
|
11
|
+
"repository": {
|
|
12
|
+
"type": "git",
|
|
13
|
+
"url": "https://github.com/Scouterna/scoutnet-api.git",
|
|
14
|
+
"directory": "packages/scoutnet"
|
|
15
|
+
},
|
|
16
|
+
"type": "module",
|
|
17
|
+
"exports": {
|
|
18
|
+
".": "./dist/index.js"
|
|
19
|
+
},
|
|
20
|
+
"scripts": {
|
|
21
|
+
"build": "pnpm run build:types && pnpm run build:format && pnpm run build:typescript",
|
|
22
|
+
"build:types": "openapi-typescript ./node_modules/@scouterna/scoutnet-openapi/scoutnet.yaml -o ./src/generated/api-types.ts",
|
|
23
|
+
"build:format": "biome format --write ./src/generated/api-types.ts",
|
|
24
|
+
"build:typescript": "tsc",
|
|
25
|
+
"test": "echo \"Error: no test specified\" && exit 1"
|
|
26
|
+
},
|
|
27
|
+
"devDependencies": {
|
|
28
|
+
"@types/node": "^22.10.10",
|
|
29
|
+
"openapi-typescript": "^7.6.0",
|
|
30
|
+
"typescript": "~5.6.2",
|
|
31
|
+
"@scouterna/scoutnet-openapi": "workspace:^"
|
|
32
|
+
},
|
|
33
|
+
"dependencies": {
|
|
34
|
+
"openapi-fetch": "^0.13.4"
|
|
35
|
+
}
|
|
36
|
+
}
|
package/src/client.ts
ADDED
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import type { ClientOptions as OpenApiClientOptions } from "openapi-fetch";
|
|
2
|
+
import openApiCreateClient from "openapi-fetch";
|
|
3
|
+
|
|
4
|
+
import type { paths } from "./generated/api-types.js";
|
|
5
|
+
|
|
6
|
+
export type APICredentials = {
|
|
7
|
+
resourceId: number | string;
|
|
8
|
+
key: string;
|
|
9
|
+
};
|
|
10
|
+
|
|
11
|
+
export type ClientOptions = OpenApiClientOptions;
|
|
12
|
+
|
|
13
|
+
export const createClient = ({
|
|
14
|
+
baseUrl = "https://scoutnet.se/api",
|
|
15
|
+
...clientOptions
|
|
16
|
+
}: ClientOptions) => {
|
|
17
|
+
const client = openApiCreateClient<paths>({
|
|
18
|
+
baseUrl,
|
|
19
|
+
...clientOptions,
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
return client;
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
const base64encode = (data: string) => {
|
|
26
|
+
if (typeof window === "undefined") {
|
|
27
|
+
return Buffer.from(data).toString("base64");
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
return window.btoa(data);
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Creates an authorization header for the Scoutnet API.
|
|
35
|
+
*/
|
|
36
|
+
export const createAuthorizationHeader = ({
|
|
37
|
+
resourceId,
|
|
38
|
+
key: token,
|
|
39
|
+
}: APICredentials) => {
|
|
40
|
+
const authString = `${resourceId}:${token}`;
|
|
41
|
+
const encoded = base64encode(authString);
|
|
42
|
+
return `Basic ${encoded}`;
|
|
43
|
+
};
|
|
File without changes
|
package/src/index.ts
ADDED
package/tsconfig.json
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
{
|
|
2
|
+
"compilerOptions": {
|
|
3
|
+
/* Base Options: */
|
|
4
|
+
"esModuleInterop": true,
|
|
5
|
+
"skipLibCheck": true,
|
|
6
|
+
"target": "es2022",
|
|
7
|
+
"allowJs": true,
|
|
8
|
+
"resolveJsonModule": true,
|
|
9
|
+
"moduleDetection": "force",
|
|
10
|
+
"isolatedModules": true,
|
|
11
|
+
"verbatimModuleSyntax": true,
|
|
12
|
+
|
|
13
|
+
/* Strictness */
|
|
14
|
+
"strict": true,
|
|
15
|
+
"noUncheckedIndexedAccess": true,
|
|
16
|
+
"noImplicitOverride": true,
|
|
17
|
+
|
|
18
|
+
/* Transpilation */
|
|
19
|
+
"module": "NodeNext",
|
|
20
|
+
"outDir": "dist",
|
|
21
|
+
"sourceMap": true,
|
|
22
|
+
"declaration": true,
|
|
23
|
+
"lib": ["es2022", "dom"]
|
|
24
|
+
}
|
|
25
|
+
}
|