@jaaq/jaaq-sdk-js 0.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 +210 -0
- package/dist/index.cjs +134 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.ts +93 -0
- package/dist/index.mjs +130 -0
- package/dist/index.mjs.map +1 -0
- package/dist/jaaq-sdk.min.js +2 -0
- package/dist/jaaq-sdk.min.js.map +1 -0
- package/package.json +102 -0
package/README.md
ADDED
|
@@ -0,0 +1,210 @@
|
|
|
1
|
+
# JAAQ TypeScript SDK (`jaaq-sdk-js`)
|
|
2
|
+
|
|
3
|
+
A lightweight, type-safe SDK for interacting with the **JAAQ API (v1)**.
|
|
4
|
+
It provides a simple client with typed resources generated from the backend OpenAPI specification.
|
|
5
|
+
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
## Project Structure
|
|
9
|
+
|
|
10
|
+
- src/
|
|
11
|
+
- core/ # HTTP client
|
|
12
|
+
- gen/ # Generated OpenAPI types
|
|
13
|
+
- resources/ # API resources (e.g., videos)
|
|
14
|
+
- index.ts
|
|
15
|
+
- test/
|
|
16
|
+
- handlers/
|
|
17
|
+
- mocks/
|
|
18
|
+
- setup.ts
|
|
19
|
+
|
|
20
|
+
## Relative paths:
|
|
21
|
+
|
|
22
|
+
```bash
|
|
23
|
+
"@src/*": ["src/*"],
|
|
24
|
+
"@core/*": ["src/core/*"],
|
|
25
|
+
"@resources/*": ["src/resources/*"],
|
|
26
|
+
"@gen/*": ["src/gen/*"],
|
|
27
|
+
"@tests/*": ["tests/*"]
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
## Installation
|
|
31
|
+
|
|
32
|
+
```bash
|
|
33
|
+
pnpm install
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
## Build
|
|
37
|
+
|
|
38
|
+
```bash
|
|
39
|
+
pnpm build
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
## Run tests
|
|
43
|
+
|
|
44
|
+
```bash
|
|
45
|
+
pnpm test
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
or
|
|
49
|
+
|
|
50
|
+
```bash
|
|
51
|
+
pnpm test:watch
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
## Create types
|
|
55
|
+
|
|
56
|
+
Once we have the last openApi.json file from the Back-end
|
|
57
|
+
|
|
58
|
+
```bash
|
|
59
|
+
pnpm openapi:gen
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
And then:
|
|
63
|
+
|
|
64
|
+
```bash
|
|
65
|
+
import type { paths, components } from '@gen/openapi';
|
|
66
|
+
|
|
67
|
+
type GetVideosResponse = components['schemas']['GetVideosResponse'];
|
|
68
|
+
type GetVideosParams = paths['/videos']['get']['parameters']['query'];
|
|
69
|
+
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
## Configuration options:
|
|
73
|
+
|
|
74
|
+
- apiKey (required) – Provided by backend.
|
|
75
|
+
- clientId (required) – Provided by consuming company.
|
|
76
|
+
- baseUrl (optional) – Defaults to https://api.jaaq.app/v1.
|
|
77
|
+
- fetch (optional) – Custom fetch implementation (for Node < 18).
|
|
78
|
+
- timeoutMs (optional) – Request timeout in ms.
|
|
79
|
+
- headers (optional) – Extra headers for all requests.
|
|
80
|
+
- apiKeyHeaderName (optional) – Defaults to x-api-key.
|
|
81
|
+
|
|
82
|
+
## Linting
|
|
83
|
+
|
|
84
|
+
- ESLint (code rules) and Prettier (formatting).
|
|
85
|
+
- On save: use the Prettier editor extension (Format on Save).
|
|
86
|
+
- Pre-commit: lint-staged runs ESLint --fix on TS/JS and Prettier on staged files.
|
|
87
|
+
- Manual:
|
|
88
|
+
- `pnpm lint` / `pnpm lint:fix`
|
|
89
|
+
- `pnpm format` / `pnpm format:check`
|
|
90
|
+
- Commit messages: validated by commitlint (Husky commit-msg hook).
|
|
91
|
+
- PRs: CI runs `pnpm lint` and `pnpm format:check` on pull_request.
|
|
92
|
+
|
|
93
|
+
## Usage:
|
|
94
|
+
|
|
95
|
+
#### install module:
|
|
96
|
+
|
|
97
|
+

|
|
98
|
+
|
|
99
|
+
#### classic mode:
|
|
100
|
+
|
|
101
|
+
```bash
|
|
102
|
+
// Import module
|
|
103
|
+
import { JaaqClient } from "jaaq-sdk-js";
|
|
104
|
+
|
|
105
|
+
const client = JaaqClient.init({
|
|
106
|
+
apiKey: '<YOUR_API_KEY>',
|
|
107
|
+
clientId: '<YOUR_CLIENT_ID>',
|
|
108
|
+
});
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
#### JS mode:
|
|
112
|
+
|
|
113
|
+
```bash
|
|
114
|
+
// Import module
|
|
115
|
+
import { createJaaqClient } from "jaaq-sdk-js";
|
|
116
|
+
|
|
117
|
+
const client = createJaaqClient({
|
|
118
|
+
apiKey: '<YOUR_API_KEY>',
|
|
119
|
+
clientId: '<YOUR_CLIENT_ID>',
|
|
120
|
+
});
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
#### Access to the different resources:
|
|
124
|
+
|
|
125
|
+
```bash
|
|
126
|
+
client.videos.getById('xxxxxx')
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
or
|
|
130
|
+
|
|
131
|
+
```bash
|
|
132
|
+
client.collections.list()
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
#### Ex: Getting and displaying a video
|
|
136
|
+
|
|
137
|
+
```bash
|
|
138
|
+
import { useEffect, useRef } from "react";
|
|
139
|
+
import { createJaaqClient } from "jaaq-sdk-js";
|
|
140
|
+
|
|
141
|
+
const API_KEY = import.meta.env.VITE_JAAQ_API_KEY;
|
|
142
|
+
const CLIENT_ID = import.meta.env.VITE_JAAQ_CLIENT_ID;
|
|
143
|
+
|
|
144
|
+
export default function VideoExample({ id }: { id: string }) {
|
|
145
|
+
const videoRef = useRef<HTMLVideoElement | null>(null);
|
|
146
|
+
|
|
147
|
+
useEffect(() => {
|
|
148
|
+
(async () => {
|
|
149
|
+
const client = createJaaqClient({
|
|
150
|
+
apiKey: API_KEY,
|
|
151
|
+
clientId: CLIENT_ID
|
|
152
|
+
});
|
|
153
|
+
const resp = await client.videos.getById(id);
|
|
154
|
+
const url = resp.video.videoUrl;
|
|
155
|
+
videoRef.current.src = url;
|
|
156
|
+
})();
|
|
157
|
+
}, [id]);
|
|
158
|
+
|
|
159
|
+
return (
|
|
160
|
+
<video
|
|
161
|
+
ref={videoRef}
|
|
162
|
+
autoPlay
|
|
163
|
+
controls
|
|
164
|
+
/>;
|
|
165
|
+
)
|
|
166
|
+
}
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
#### If extension is .m3u8
|
|
170
|
+
|
|
171
|
+
```bash
|
|
172
|
+
import { useEffect, useRef } from "react";
|
|
173
|
+
import { createJaaqClient } from "jaaq-sdk-js";
|
|
174
|
+
import Hls from "hls.js";
|
|
175
|
+
|
|
176
|
+
const API_KEY = import.meta.env.VITE_JAAQ_API_KEY!;
|
|
177
|
+
const CLIENT_ID = import.meta.env.VITE_JAAQ_CLIENT_ID!;
|
|
178
|
+
|
|
179
|
+
export default function VideoExample({ id }: { id: string }) {
|
|
180
|
+
const videoRef = useRef<HTMLVideoElement | null>(null);
|
|
181
|
+
|
|
182
|
+
useEffect(() => {
|
|
183
|
+
let hls: Hls | undefined;
|
|
184
|
+
|
|
185
|
+
(async () => {
|
|
186
|
+
const client = createJaaqClient({ apiKey: API_KEY, clientId: CLIENT_ID });
|
|
187
|
+
const resp = await client.videos.getById(id);
|
|
188
|
+
const url = resp.video.videoUrl; // e.g. https://.../video.m3u8
|
|
189
|
+
const video = videoRef.current;
|
|
190
|
+
if (!video || !url) return;
|
|
191
|
+
|
|
192
|
+
if (Hls.isSupported()) {
|
|
193
|
+
hls = new Hls();
|
|
194
|
+
hls.loadSource(url);
|
|
195
|
+
hls.attachMedia(video);
|
|
196
|
+
}
|
|
197
|
+
})();
|
|
198
|
+
|
|
199
|
+
return () => hls?.destroy();
|
|
200
|
+
}, [id]);
|
|
201
|
+
|
|
202
|
+
return (
|
|
203
|
+
<video
|
|
204
|
+
ref={videoRef}
|
|
205
|
+
autoPlay
|
|
206
|
+
controls
|
|
207
|
+
/>;
|
|
208
|
+
)
|
|
209
|
+
}
|
|
210
|
+
```
|
package/dist/index.cjs
ADDED
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
async function parseJson(res) {
|
|
4
|
+
if (!res.ok) {
|
|
5
|
+
const text = await res.text().catch(() => '');
|
|
6
|
+
throw new Error(`HTTP ${res.status}: ${text || res.statusText}`);
|
|
7
|
+
}
|
|
8
|
+
if (res.status === 204)
|
|
9
|
+
return undefined;
|
|
10
|
+
return res.json();
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Join base URL and path avoiding duplicate slashes.
|
|
14
|
+
* - Preserves absolute paths (http/https) as-is.
|
|
15
|
+
* - Trims trailing slashes from base and leading slashes from path.
|
|
16
|
+
*/
|
|
17
|
+
function joinUrl(baseUrl, path) {
|
|
18
|
+
// return path if it is an absolute URL
|
|
19
|
+
if (/^https?:\/\//i.test(path))
|
|
20
|
+
return path;
|
|
21
|
+
const base = baseUrl.replace(/\/+$/, '');
|
|
22
|
+
const relative = path.replace(/^\/+/, '');
|
|
23
|
+
return `${base}/${relative}`;
|
|
24
|
+
}
|
|
25
|
+
function createHttpClient(config) {
|
|
26
|
+
const { baseUrl, apiKey, clientId, fetch: fetchImpl, headers, apiKeyHeaderName = 'x-api-key' } = config;
|
|
27
|
+
const f = fetchImpl ?? globalThis.fetch;
|
|
28
|
+
if (!f) {
|
|
29
|
+
throw new Error('No fetch implementation found. Provide one in SDKConfig.fetch for Node or custom environments.');
|
|
30
|
+
}
|
|
31
|
+
const baseHeaders = {
|
|
32
|
+
'Content-Type': 'application/json',
|
|
33
|
+
[apiKeyHeaderName]: apiKey,
|
|
34
|
+
'x-client-id': clientId,
|
|
35
|
+
...headers,
|
|
36
|
+
};
|
|
37
|
+
const fullUrl = (path) => joinUrl(baseUrl, path);
|
|
38
|
+
const request = async (method, path, init, body) => {
|
|
39
|
+
const reqInit = {
|
|
40
|
+
method,
|
|
41
|
+
headers: {
|
|
42
|
+
...baseHeaders,
|
|
43
|
+
...init?.headers,
|
|
44
|
+
},
|
|
45
|
+
...init,
|
|
46
|
+
};
|
|
47
|
+
if (body !== undefined)
|
|
48
|
+
reqInit.body = JSON.stringify(body);
|
|
49
|
+
const res = await f(fullUrl(path), reqInit);
|
|
50
|
+
return parseJson(res);
|
|
51
|
+
};
|
|
52
|
+
return {
|
|
53
|
+
get: (path, init) => request('GET', path, init),
|
|
54
|
+
post: (path, body, init) => request('POST', path, init, body),
|
|
55
|
+
put: (path, body, init) => request('PUT', path, init, body),
|
|
56
|
+
patch: (path, body, init) => request('PATCH', path, init, body),
|
|
57
|
+
delete: (path, init) => request('DELETE', path, init),
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
function createVideosResource(http) {
|
|
62
|
+
return {
|
|
63
|
+
async getById(id) {
|
|
64
|
+
const path = `b2b/videos/${encodeURIComponent(id)}`;
|
|
65
|
+
return http.get(path);
|
|
66
|
+
},
|
|
67
|
+
};
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
function createCollectionsResource(http) {
|
|
71
|
+
return {
|
|
72
|
+
async list() {
|
|
73
|
+
const path = 'b2b/collections';
|
|
74
|
+
return http.get(path);
|
|
75
|
+
},
|
|
76
|
+
async getById(id) {
|
|
77
|
+
const path = `b2b/collections/${encodeURIComponent(id)}`;
|
|
78
|
+
return http.get(path);
|
|
79
|
+
},
|
|
80
|
+
};
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
const BASE_URL = undefined;
|
|
84
|
+
class JaaqClient {
|
|
85
|
+
// Keep constructor private to enforce controlled instantiation.
|
|
86
|
+
constructor(http) {
|
|
87
|
+
this.videos = createVideosResource(http);
|
|
88
|
+
this.collections = createCollectionsResource(http);
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* Public "friend" constructor that remains inside the class boundary.
|
|
92
|
+
* This method is callable from the module-level build function
|
|
93
|
+
* without exposing `new JaaqClient(...)` to consumers.
|
|
94
|
+
*/
|
|
95
|
+
static fromHttp(http) {
|
|
96
|
+
return new JaaqClient(http);
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* OO-friendly static initializer.
|
|
100
|
+
* Delegates to the single source of truth: `buildClient`.
|
|
101
|
+
*/
|
|
102
|
+
static init(config) {
|
|
103
|
+
return buildClient(config);
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
/**
|
|
107
|
+
* Canonical factory (idiomatic for JS/TS).
|
|
108
|
+
* Delegates to the single source of truth: `buildClient`.
|
|
109
|
+
*/
|
|
110
|
+
function createJaaqClient(config) {
|
|
111
|
+
return buildClient(config);
|
|
112
|
+
}
|
|
113
|
+
/**
|
|
114
|
+
* Single source of truth for constructing the client.
|
|
115
|
+
* Both `createJaaqClient` and `JaaqClient.init` call this function.
|
|
116
|
+
* The constructor stays private; instantiation is funneled via `JaaqClient.fromHttp`.
|
|
117
|
+
*/
|
|
118
|
+
function buildClient(config) {
|
|
119
|
+
const { baseUrl = BASE_URL, apiKey, clientId, fetch: fetchImpl, headers, apiKeyHeaderName = 'x-api-key' } = config;
|
|
120
|
+
const http = createHttpClient({
|
|
121
|
+
baseUrl,
|
|
122
|
+
apiKey,
|
|
123
|
+
clientId,
|
|
124
|
+
apiKeyHeaderName,
|
|
125
|
+
fetch: fetchImpl ?? globalThis.fetch,
|
|
126
|
+
headers,
|
|
127
|
+
});
|
|
128
|
+
return JaaqClient.fromHttp(http);
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
exports.BASE_URL = BASE_URL;
|
|
132
|
+
exports.JaaqClient = JaaqClient;
|
|
133
|
+
exports.createJaaqClient = createJaaqClient;
|
|
134
|
+
//# sourceMappingURL=index.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.cjs","sources":["../src/core/httpClient.ts","../src/resources/videos.ts","../src/resources/collections.ts","../src/index.ts"],"sourcesContent":["export type FetchLike = typeof globalThis.fetch;\ntype RequestOptions = Parameters<typeof globalThis.fetch>[1];\ntype FetchResponse = Awaited<ReturnType<FetchLike>>;\n\nexport interface HttpClientConfig {\n baseUrl: string;\n apiKey: string;\n clientId: string;\n apiKeyHeaderName?: string;\n fetch?: FetchLike;\n timeoutMs?: number;\n headers?: Record<string, string>;\n}\n\nexport interface HttpClient {\n get<T>(_path: string, _init?: RequestOptions): Promise<T>;\n post<T>(_path: string, _body?: unknown, _init?: RequestOptions): Promise<T>;\n put<T>(_path: string, _body?: unknown, _init?: RequestOptions): Promise<T>;\n patch<T>(_path: string, _body?: unknown, _init?: RequestOptions): Promise<T>;\n delete<T>(_path: string, _init?: RequestOptions): Promise<T>;\n}\n\nasync function parseJson<T>(res: FetchResponse): Promise<T> {\n if (!res.ok) {\n const text = await res.text().catch(() => '');\n throw new Error(`HTTP ${res.status}: ${text || res.statusText}`);\n }\n if (res.status === 204) return undefined as unknown as T;\n return res.json() as Promise<T>;\n}\n\n/**\n * Join base URL and path avoiding duplicate slashes.\n * - Preserves absolute paths (http/https) as-is.\n * - Trims trailing slashes from base and leading slashes from path.\n */\nfunction joinUrl(baseUrl: string, path: string): string {\n // return path if it is an absolute URL\n if (/^https?:\\/\\//i.test(path)) return path;\n const base = baseUrl.replace(/\\/+$/, '');\n const relative = path.replace(/^\\/+/, '');\n return `${base}/${relative}`;\n}\n\nexport function createHttpClient(config: HttpClientConfig): HttpClient {\n const { baseUrl, apiKey, clientId, fetch: fetchImpl, headers, apiKeyHeaderName = 'x-api-key' } = config;\n\n const f: FetchLike | undefined = fetchImpl ?? (globalThis.fetch as FetchLike | undefined);\n if (!f) {\n throw new Error('No fetch implementation found. Provide one in SDKConfig.fetch for Node or custom environments.');\n }\n\n const baseHeaders: Record<string, string> = {\n 'Content-Type': 'application/json',\n [apiKeyHeaderName]: apiKey,\n 'x-client-id': clientId,\n ...headers,\n };\n\n const fullUrl = (path: string) => joinUrl(baseUrl, path);\n\n const request = async <T>(method: string, path: string, init?: RequestOptions, body?: unknown) => {\n const reqInit: RequestOptions = {\n method,\n headers: {\n ...baseHeaders,\n ...(init?.headers as Record<string, string> | undefined),\n },\n ...init,\n };\n if (body !== undefined) reqInit.body = JSON.stringify(body);\n const res = await f(fullUrl(path), reqInit);\n return parseJson<T>(res);\n };\n\n return {\n get: <T>(path: string, init?: RequestOptions) => request<T>('GET', path, init),\n post: <T>(path: string, body?: unknown, init?: RequestOptions) => request<T>('POST', path, init, body),\n put: <T>(path: string, body?: unknown, init?: RequestOptions) => request<T>('PUT', path, init, body),\n patch: <T>(path: string, body?: unknown, init?: RequestOptions) => request<T>('PATCH', path, init, body),\n delete: <T>(path: string, init?: RequestOptions) => request<T>('DELETE', path, init),\n };\n}\n","import type { HttpClient } from '@core/httpClient';\nimport type { Video } from '@src/types/videos';\n\nexport interface VideosResource {\n getById(_id: string): Promise<Video>;\n}\n\nexport function createVideosResource(http: HttpClient): VideosResource {\n return {\n async getById(id: string) {\n const path = `b2b/videos/${encodeURIComponent(id)}`;\n return http.get<Video>(path);\n },\n };\n}\n","import type { HttpClient } from '@core/httpClient';\nimport type { Collection } from '@src/types/collection';\n\nexport interface CollectionsResource {\n list(): Promise<Collection[]>;\n getById(_id: string): Promise<Collection>;\n}\n\nexport function createCollectionsResource(http: HttpClient): CollectionsResource {\n return {\n async list() {\n const path = 'b2b/collections';\n return http.get<Collection[]>(path);\n },\n async getById(id: string) {\n const path = `b2b/collections/${encodeURIComponent(id)}`;\n return http.get<Collection>(path);\n },\n };\n}\n","import { createHttpClient, type HttpClient, type FetchLike } from '@core/httpClient';\nimport { createVideosResource, type VideosResource } from '@resources/videos';\nimport { createCollectionsResource, type CollectionsResource } from '@resources/collections';\n\n// Public type exports for consumers (barrel)\nexport * from '@src/types';\n\nexport const BASE_URL = process.env.JAAQ_API_URL as string;\n\nexport interface SDKConfig {\n baseUrl?: string; // Pending to approve\n apiKey: string; // Provided by backend per client\n clientId: string; // Provided by each consuming company at init\n fetch?: FetchLike; // Optional fetch injection (Node/custom envs) // Pending to approve\n timeoutMs?: number;\n headers?: Record<string, string>; // Pending to approve\n apiKeyHeaderName?: string;\n}\n\nexport class JaaqClient {\n public readonly videos: VideosResource;\n public readonly collections: CollectionsResource;\n\n // Keep constructor private to enforce controlled instantiation.\n private constructor(http: HttpClient) {\n this.videos = createVideosResource(http);\n this.collections = createCollectionsResource(http);\n }\n\n /**\n * Public \"friend\" constructor that remains inside the class boundary.\n * This method is callable from the module-level build function\n * without exposing `new JaaqClient(...)` to consumers.\n */\n static fromHttp(http: HttpClient): JaaqClient {\n return new JaaqClient(http);\n }\n\n /**\n * OO-friendly static initializer.\n * Delegates to the single source of truth: `buildClient`.\n */\n static init(config: SDKConfig): JaaqClient {\n return buildClient(config);\n }\n}\n\n/**\n * Canonical factory (idiomatic for JS/TS).\n * Delegates to the single source of truth: `buildClient`.\n */\nexport function createJaaqClient(config: SDKConfig): JaaqClient {\n return buildClient(config);\n}\n\n/**\n * Single source of truth for constructing the client.\n * Both `createJaaqClient` and `JaaqClient.init` call this function.\n * The constructor stays private; instantiation is funneled via `JaaqClient.fromHttp`.\n */\nfunction buildClient(config: SDKConfig): JaaqClient {\n const { baseUrl = BASE_URL, apiKey, clientId, fetch: fetchImpl, headers, apiKeyHeaderName = 'x-api-key' } = config;\n\n const http = createHttpClient({\n baseUrl,\n apiKey,\n clientId,\n apiKeyHeaderName,\n fetch: fetchImpl ?? (globalThis.fetch as FetchLike | undefined),\n headers,\n });\n\n return JaaqClient.fromHttp(http);\n}\n"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
type FetchLike = typeof globalThis.fetch;
|
|
2
|
+
type RequestOptions = Parameters<typeof globalThis.fetch>[1];
|
|
3
|
+
interface HttpClient {
|
|
4
|
+
get<T>(_path: string, _init?: RequestOptions): Promise<T>;
|
|
5
|
+
post<T>(_path: string, _body?: unknown, _init?: RequestOptions): Promise<T>;
|
|
6
|
+
put<T>(_path: string, _body?: unknown, _init?: RequestOptions): Promise<T>;
|
|
7
|
+
patch<T>(_path: string, _body?: unknown, _init?: RequestOptions): Promise<T>;
|
|
8
|
+
delete<T>(_path: string, _init?: RequestOptions): Promise<T>;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
interface Video {
|
|
12
|
+
id: string;
|
|
13
|
+
videoId: string;
|
|
14
|
+
questionId: string;
|
|
15
|
+
question: string;
|
|
16
|
+
status: number | null;
|
|
17
|
+
transcription: string | null;
|
|
18
|
+
createdAt: string;
|
|
19
|
+
modifiedAt: string;
|
|
20
|
+
videoUrl: string;
|
|
21
|
+
published: boolean;
|
|
22
|
+
tags: string[];
|
|
23
|
+
severity: number | null;
|
|
24
|
+
duration: number;
|
|
25
|
+
subTopics: string[];
|
|
26
|
+
description: string;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
interface VideosResource {
|
|
30
|
+
getById(_id: string): Promise<Video>;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
interface Collection {
|
|
34
|
+
id: string;
|
|
35
|
+
name: string;
|
|
36
|
+
description: string;
|
|
37
|
+
imageUrl: string;
|
|
38
|
+
videos: Video[];
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
interface CollectionsResource {
|
|
42
|
+
list(): Promise<Collection[]>;
|
|
43
|
+
getById(_id: string): Promise<Collection>;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
type ISODateTimeString = string;
|
|
47
|
+
interface ApiError {
|
|
48
|
+
description: string;
|
|
49
|
+
error: string;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
interface Subtopic {
|
|
53
|
+
id: string;
|
|
54
|
+
name: string;
|
|
55
|
+
createdAt: ISODateTimeString;
|
|
56
|
+
modifiedAt: ISODateTimeString;
|
|
57
|
+
modifiedBy: ISODateTimeString;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
declare const BASE_URL: string;
|
|
61
|
+
interface SDKConfig {
|
|
62
|
+
baseUrl?: string;
|
|
63
|
+
apiKey: string;
|
|
64
|
+
clientId: string;
|
|
65
|
+
fetch?: FetchLike;
|
|
66
|
+
timeoutMs?: number;
|
|
67
|
+
headers?: Record<string, string>;
|
|
68
|
+
apiKeyHeaderName?: string;
|
|
69
|
+
}
|
|
70
|
+
declare class JaaqClient {
|
|
71
|
+
readonly videos: VideosResource;
|
|
72
|
+
readonly collections: CollectionsResource;
|
|
73
|
+
private constructor();
|
|
74
|
+
/**
|
|
75
|
+
* Public "friend" constructor that remains inside the class boundary.
|
|
76
|
+
* This method is callable from the module-level build function
|
|
77
|
+
* without exposing `new JaaqClient(...)` to consumers.
|
|
78
|
+
*/
|
|
79
|
+
static fromHttp(http: HttpClient): JaaqClient;
|
|
80
|
+
/**
|
|
81
|
+
* OO-friendly static initializer.
|
|
82
|
+
* Delegates to the single source of truth: `buildClient`.
|
|
83
|
+
*/
|
|
84
|
+
static init(config: SDKConfig): JaaqClient;
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* Canonical factory (idiomatic for JS/TS).
|
|
88
|
+
* Delegates to the single source of truth: `buildClient`.
|
|
89
|
+
*/
|
|
90
|
+
declare function createJaaqClient(config: SDKConfig): JaaqClient;
|
|
91
|
+
|
|
92
|
+
export { BASE_URL, JaaqClient, createJaaqClient };
|
|
93
|
+
export type { ApiError, Collection, ISODateTimeString, SDKConfig, Subtopic, Video };
|
package/dist/index.mjs
ADDED
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
async function parseJson(res) {
|
|
2
|
+
if (!res.ok) {
|
|
3
|
+
const text = await res.text().catch(() => '');
|
|
4
|
+
throw new Error(`HTTP ${res.status}: ${text || res.statusText}`);
|
|
5
|
+
}
|
|
6
|
+
if (res.status === 204)
|
|
7
|
+
return undefined;
|
|
8
|
+
return res.json();
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* Join base URL and path avoiding duplicate slashes.
|
|
12
|
+
* - Preserves absolute paths (http/https) as-is.
|
|
13
|
+
* - Trims trailing slashes from base and leading slashes from path.
|
|
14
|
+
*/
|
|
15
|
+
function joinUrl(baseUrl, path) {
|
|
16
|
+
// return path if it is an absolute URL
|
|
17
|
+
if (/^https?:\/\//i.test(path))
|
|
18
|
+
return path;
|
|
19
|
+
const base = baseUrl.replace(/\/+$/, '');
|
|
20
|
+
const relative = path.replace(/^\/+/, '');
|
|
21
|
+
return `${base}/${relative}`;
|
|
22
|
+
}
|
|
23
|
+
function createHttpClient(config) {
|
|
24
|
+
const { baseUrl, apiKey, clientId, fetch: fetchImpl, headers, apiKeyHeaderName = 'x-api-key' } = config;
|
|
25
|
+
const f = fetchImpl ?? globalThis.fetch;
|
|
26
|
+
if (!f) {
|
|
27
|
+
throw new Error('No fetch implementation found. Provide one in SDKConfig.fetch for Node or custom environments.');
|
|
28
|
+
}
|
|
29
|
+
const baseHeaders = {
|
|
30
|
+
'Content-Type': 'application/json',
|
|
31
|
+
[apiKeyHeaderName]: apiKey,
|
|
32
|
+
'x-client-id': clientId,
|
|
33
|
+
...headers,
|
|
34
|
+
};
|
|
35
|
+
const fullUrl = (path) => joinUrl(baseUrl, path);
|
|
36
|
+
const request = async (method, path, init, body) => {
|
|
37
|
+
const reqInit = {
|
|
38
|
+
method,
|
|
39
|
+
headers: {
|
|
40
|
+
...baseHeaders,
|
|
41
|
+
...init?.headers,
|
|
42
|
+
},
|
|
43
|
+
...init,
|
|
44
|
+
};
|
|
45
|
+
if (body !== undefined)
|
|
46
|
+
reqInit.body = JSON.stringify(body);
|
|
47
|
+
const res = await f(fullUrl(path), reqInit);
|
|
48
|
+
return parseJson(res);
|
|
49
|
+
};
|
|
50
|
+
return {
|
|
51
|
+
get: (path, init) => request('GET', path, init),
|
|
52
|
+
post: (path, body, init) => request('POST', path, init, body),
|
|
53
|
+
put: (path, body, init) => request('PUT', path, init, body),
|
|
54
|
+
patch: (path, body, init) => request('PATCH', path, init, body),
|
|
55
|
+
delete: (path, init) => request('DELETE', path, init),
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
function createVideosResource(http) {
|
|
60
|
+
return {
|
|
61
|
+
async getById(id) {
|
|
62
|
+
const path = `b2b/videos/${encodeURIComponent(id)}`;
|
|
63
|
+
return http.get(path);
|
|
64
|
+
},
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
function createCollectionsResource(http) {
|
|
69
|
+
return {
|
|
70
|
+
async list() {
|
|
71
|
+
const path = 'b2b/collections';
|
|
72
|
+
return http.get(path);
|
|
73
|
+
},
|
|
74
|
+
async getById(id) {
|
|
75
|
+
const path = `b2b/collections/${encodeURIComponent(id)}`;
|
|
76
|
+
return http.get(path);
|
|
77
|
+
},
|
|
78
|
+
};
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
const BASE_URL = undefined;
|
|
82
|
+
class JaaqClient {
|
|
83
|
+
// Keep constructor private to enforce controlled instantiation.
|
|
84
|
+
constructor(http) {
|
|
85
|
+
this.videos = createVideosResource(http);
|
|
86
|
+
this.collections = createCollectionsResource(http);
|
|
87
|
+
}
|
|
88
|
+
/**
|
|
89
|
+
* Public "friend" constructor that remains inside the class boundary.
|
|
90
|
+
* This method is callable from the module-level build function
|
|
91
|
+
* without exposing `new JaaqClient(...)` to consumers.
|
|
92
|
+
*/
|
|
93
|
+
static fromHttp(http) {
|
|
94
|
+
return new JaaqClient(http);
|
|
95
|
+
}
|
|
96
|
+
/**
|
|
97
|
+
* OO-friendly static initializer.
|
|
98
|
+
* Delegates to the single source of truth: `buildClient`.
|
|
99
|
+
*/
|
|
100
|
+
static init(config) {
|
|
101
|
+
return buildClient(config);
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
/**
|
|
105
|
+
* Canonical factory (idiomatic for JS/TS).
|
|
106
|
+
* Delegates to the single source of truth: `buildClient`.
|
|
107
|
+
*/
|
|
108
|
+
function createJaaqClient(config) {
|
|
109
|
+
return buildClient(config);
|
|
110
|
+
}
|
|
111
|
+
/**
|
|
112
|
+
* Single source of truth for constructing the client.
|
|
113
|
+
* Both `createJaaqClient` and `JaaqClient.init` call this function.
|
|
114
|
+
* The constructor stays private; instantiation is funneled via `JaaqClient.fromHttp`.
|
|
115
|
+
*/
|
|
116
|
+
function buildClient(config) {
|
|
117
|
+
const { baseUrl = BASE_URL, apiKey, clientId, fetch: fetchImpl, headers, apiKeyHeaderName = 'x-api-key' } = config;
|
|
118
|
+
const http = createHttpClient({
|
|
119
|
+
baseUrl,
|
|
120
|
+
apiKey,
|
|
121
|
+
clientId,
|
|
122
|
+
apiKeyHeaderName,
|
|
123
|
+
fetch: fetchImpl ?? globalThis.fetch,
|
|
124
|
+
headers,
|
|
125
|
+
});
|
|
126
|
+
return JaaqClient.fromHttp(http);
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
export { BASE_URL, JaaqClient, createJaaqClient };
|
|
130
|
+
//# sourceMappingURL=index.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.mjs","sources":["../src/core/httpClient.ts","../src/resources/videos.ts","../src/resources/collections.ts","../src/index.ts"],"sourcesContent":["export type FetchLike = typeof globalThis.fetch;\ntype RequestOptions = Parameters<typeof globalThis.fetch>[1];\ntype FetchResponse = Awaited<ReturnType<FetchLike>>;\n\nexport interface HttpClientConfig {\n baseUrl: string;\n apiKey: string;\n clientId: string;\n apiKeyHeaderName?: string;\n fetch?: FetchLike;\n timeoutMs?: number;\n headers?: Record<string, string>;\n}\n\nexport interface HttpClient {\n get<T>(_path: string, _init?: RequestOptions): Promise<T>;\n post<T>(_path: string, _body?: unknown, _init?: RequestOptions): Promise<T>;\n put<T>(_path: string, _body?: unknown, _init?: RequestOptions): Promise<T>;\n patch<T>(_path: string, _body?: unknown, _init?: RequestOptions): Promise<T>;\n delete<T>(_path: string, _init?: RequestOptions): Promise<T>;\n}\n\nasync function parseJson<T>(res: FetchResponse): Promise<T> {\n if (!res.ok) {\n const text = await res.text().catch(() => '');\n throw new Error(`HTTP ${res.status}: ${text || res.statusText}`);\n }\n if (res.status === 204) return undefined as unknown as T;\n return res.json() as Promise<T>;\n}\n\n/**\n * Join base URL and path avoiding duplicate slashes.\n * - Preserves absolute paths (http/https) as-is.\n * - Trims trailing slashes from base and leading slashes from path.\n */\nfunction joinUrl(baseUrl: string, path: string): string {\n // return path if it is an absolute URL\n if (/^https?:\\/\\//i.test(path)) return path;\n const base = baseUrl.replace(/\\/+$/, '');\n const relative = path.replace(/^\\/+/, '');\n return `${base}/${relative}`;\n}\n\nexport function createHttpClient(config: HttpClientConfig): HttpClient {\n const { baseUrl, apiKey, clientId, fetch: fetchImpl, headers, apiKeyHeaderName = 'x-api-key' } = config;\n\n const f: FetchLike | undefined = fetchImpl ?? (globalThis.fetch as FetchLike | undefined);\n if (!f) {\n throw new Error('No fetch implementation found. Provide one in SDKConfig.fetch for Node or custom environments.');\n }\n\n const baseHeaders: Record<string, string> = {\n 'Content-Type': 'application/json',\n [apiKeyHeaderName]: apiKey,\n 'x-client-id': clientId,\n ...headers,\n };\n\n const fullUrl = (path: string) => joinUrl(baseUrl, path);\n\n const request = async <T>(method: string, path: string, init?: RequestOptions, body?: unknown) => {\n const reqInit: RequestOptions = {\n method,\n headers: {\n ...baseHeaders,\n ...(init?.headers as Record<string, string> | undefined),\n },\n ...init,\n };\n if (body !== undefined) reqInit.body = JSON.stringify(body);\n const res = await f(fullUrl(path), reqInit);\n return parseJson<T>(res);\n };\n\n return {\n get: <T>(path: string, init?: RequestOptions) => request<T>('GET', path, init),\n post: <T>(path: string, body?: unknown, init?: RequestOptions) => request<T>('POST', path, init, body),\n put: <T>(path: string, body?: unknown, init?: RequestOptions) => request<T>('PUT', path, init, body),\n patch: <T>(path: string, body?: unknown, init?: RequestOptions) => request<T>('PATCH', path, init, body),\n delete: <T>(path: string, init?: RequestOptions) => request<T>('DELETE', path, init),\n };\n}\n","import type { HttpClient } from '@core/httpClient';\nimport type { Video } from '@src/types/videos';\n\nexport interface VideosResource {\n getById(_id: string): Promise<Video>;\n}\n\nexport function createVideosResource(http: HttpClient): VideosResource {\n return {\n async getById(id: string) {\n const path = `b2b/videos/${encodeURIComponent(id)}`;\n return http.get<Video>(path);\n },\n };\n}\n","import type { HttpClient } from '@core/httpClient';\nimport type { Collection } from '@src/types/collection';\n\nexport interface CollectionsResource {\n list(): Promise<Collection[]>;\n getById(_id: string): Promise<Collection>;\n}\n\nexport function createCollectionsResource(http: HttpClient): CollectionsResource {\n return {\n async list() {\n const path = 'b2b/collections';\n return http.get<Collection[]>(path);\n },\n async getById(id: string) {\n const path = `b2b/collections/${encodeURIComponent(id)}`;\n return http.get<Collection>(path);\n },\n };\n}\n","import { createHttpClient, type HttpClient, type FetchLike } from '@core/httpClient';\nimport { createVideosResource, type VideosResource } from '@resources/videos';\nimport { createCollectionsResource, type CollectionsResource } from '@resources/collections';\n\n// Public type exports for consumers (barrel)\nexport * from '@src/types';\n\nexport const BASE_URL = process.env.JAAQ_API_URL as string;\n\nexport interface SDKConfig {\n baseUrl?: string; // Pending to approve\n apiKey: string; // Provided by backend per client\n clientId: string; // Provided by each consuming company at init\n fetch?: FetchLike; // Optional fetch injection (Node/custom envs) // Pending to approve\n timeoutMs?: number;\n headers?: Record<string, string>; // Pending to approve\n apiKeyHeaderName?: string;\n}\n\nexport class JaaqClient {\n public readonly videos: VideosResource;\n public readonly collections: CollectionsResource;\n\n // Keep constructor private to enforce controlled instantiation.\n private constructor(http: HttpClient) {\n this.videos = createVideosResource(http);\n this.collections = createCollectionsResource(http);\n }\n\n /**\n * Public \"friend\" constructor that remains inside the class boundary.\n * This method is callable from the module-level build function\n * without exposing `new JaaqClient(...)` to consumers.\n */\n static fromHttp(http: HttpClient): JaaqClient {\n return new JaaqClient(http);\n }\n\n /**\n * OO-friendly static initializer.\n * Delegates to the single source of truth: `buildClient`.\n */\n static init(config: SDKConfig): JaaqClient {\n return buildClient(config);\n }\n}\n\n/**\n * Canonical factory (idiomatic for JS/TS).\n * Delegates to the single source of truth: `buildClient`.\n */\nexport function createJaaqClient(config: SDKConfig): JaaqClient {\n return buildClient(config);\n}\n\n/**\n * Single source of truth for constructing the client.\n * Both `createJaaqClient` and `JaaqClient.init` call this function.\n * The constructor stays private; instantiation is funneled via `JaaqClient.fromHttp`.\n */\nfunction buildClient(config: SDKConfig): JaaqClient {\n const { baseUrl = BASE_URL, apiKey, clientId, fetch: fetchImpl, headers, apiKeyHeaderName = 'x-api-key' } = config;\n\n const http = createHttpClient({\n baseUrl,\n apiKey,\n clientId,\n apiKeyHeaderName,\n fetch: fetchImpl ?? (globalThis.fetch as FetchLike | undefined),\n headers,\n });\n\n return JaaqClient.fromHttp(http);\n}\n"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?t(exports):"function"==typeof define&&define.amd?define(["exports"],t):t((e="undefined"!=typeof globalThis?globalThis:e||self).JaaqSDK={})}(this,function(e){"use strict";function t(e){const{baseUrl:t,apiKey:n,clientId:o,fetch:i,headers:s,apiKeyHeaderName:r="x-api-key"}=e,c=i??globalThis.fetch;if(!c)throw new Error("No fetch implementation found. Provide one in SDKConfig.fetch for Node or custom environments.");const a={"Content-Type":"application/json",[r]:n,"x-client-id":o,...s},f=async(e,n,o,i)=>{const s={method:e,headers:{...a,...o?.headers},...o};void 0!==i&&(s.body=JSON.stringify(i));const r=await c((e=>function(e,t){return/^https?:\/\//i.test(t)?t:`${e.replace(/\/+$/,"")}/${t.replace(/^\/+/,"")}`}(t,e))(n),s);return async function(e){if(!e.ok){const t=await e.text().catch(()=>"");throw new Error(`HTTP ${e.status}: ${t||e.statusText}`)}if(204!==e.status)return e.json()}(r)};return{get:(e,t)=>f("GET",e,t),post:(e,t,n)=>f("POST",e,n,t),put:(e,t,n)=>f("PUT",e,n,t),patch:(e,t,n)=>f("PATCH",e,n,t),delete:(e,t)=>f("DELETE",e,t)}}const n=void 0;class o{constructor(e){this.videos=function(e){return{async getById(t){const n=`b2b/videos/${encodeURIComponent(t)}`;return e.get(n)}}}(e),this.collections=function(e){return{list:async()=>e.get("b2b/collections"),async getById(t){const n=`b2b/collections/${encodeURIComponent(t)}`;return e.get(n)}}}(e)}static fromHttp(e){return new o(e)}static init(e){return i(e)}}function i(e){const{baseUrl:i=n,apiKey:s,clientId:r,fetch:c,headers:a,apiKeyHeaderName:f="x-api-key"}=e,d=t({baseUrl:i,apiKey:s,clientId:r,apiKeyHeaderName:f,fetch:c??globalThis.fetch,headers:a});return o.fromHttp(d)}e.BASE_URL=n,e.JaaqClient=o,e.createJaaqClient=function(e){return i(e)}});
|
|
2
|
+
//# sourceMappingURL=jaaq-sdk.min.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"jaaq-sdk.min.js","sources":["../src/core/httpClient.ts","../src/index.ts","../src/resources/videos.ts","../src/resources/collections.ts"],"sourcesContent":["export type FetchLike = typeof globalThis.fetch;\ntype RequestOptions = Parameters<typeof globalThis.fetch>[1];\ntype FetchResponse = Awaited<ReturnType<FetchLike>>;\n\nexport interface HttpClientConfig {\n baseUrl: string;\n apiKey: string;\n clientId: string;\n apiKeyHeaderName?: string;\n fetch?: FetchLike;\n timeoutMs?: number;\n headers?: Record<string, string>;\n}\n\nexport interface HttpClient {\n get<T>(_path: string, _init?: RequestOptions): Promise<T>;\n post<T>(_path: string, _body?: unknown, _init?: RequestOptions): Promise<T>;\n put<T>(_path: string, _body?: unknown, _init?: RequestOptions): Promise<T>;\n patch<T>(_path: string, _body?: unknown, _init?: RequestOptions): Promise<T>;\n delete<T>(_path: string, _init?: RequestOptions): Promise<T>;\n}\n\nasync function parseJson<T>(res: FetchResponse): Promise<T> {\n if (!res.ok) {\n const text = await res.text().catch(() => '');\n throw new Error(`HTTP ${res.status}: ${text || res.statusText}`);\n }\n if (res.status === 204) return undefined as unknown as T;\n return res.json() as Promise<T>;\n}\n\n/**\n * Join base URL and path avoiding duplicate slashes.\n * - Preserves absolute paths (http/https) as-is.\n * - Trims trailing slashes from base and leading slashes from path.\n */\nfunction joinUrl(baseUrl: string, path: string): string {\n // return path if it is an absolute URL\n if (/^https?:\\/\\//i.test(path)) return path;\n const base = baseUrl.replace(/\\/+$/, '');\n const relative = path.replace(/^\\/+/, '');\n return `${base}/${relative}`;\n}\n\nexport function createHttpClient(config: HttpClientConfig): HttpClient {\n const { baseUrl, apiKey, clientId, fetch: fetchImpl, headers, apiKeyHeaderName = 'x-api-key' } = config;\n\n const f: FetchLike | undefined = fetchImpl ?? (globalThis.fetch as FetchLike | undefined);\n if (!f) {\n throw new Error('No fetch implementation found. Provide one in SDKConfig.fetch for Node or custom environments.');\n }\n\n const baseHeaders: Record<string, string> = {\n 'Content-Type': 'application/json',\n [apiKeyHeaderName]: apiKey,\n 'x-client-id': clientId,\n ...headers,\n };\n\n const fullUrl = (path: string) => joinUrl(baseUrl, path);\n\n const request = async <T>(method: string, path: string, init?: RequestOptions, body?: unknown) => {\n const reqInit: RequestOptions = {\n method,\n headers: {\n ...baseHeaders,\n ...(init?.headers as Record<string, string> | undefined),\n },\n ...init,\n };\n if (body !== undefined) reqInit.body = JSON.stringify(body);\n const res = await f(fullUrl(path), reqInit);\n return parseJson<T>(res);\n };\n\n return {\n get: <T>(path: string, init?: RequestOptions) => request<T>('GET', path, init),\n post: <T>(path: string, body?: unknown, init?: RequestOptions) => request<T>('POST', path, init, body),\n put: <T>(path: string, body?: unknown, init?: RequestOptions) => request<T>('PUT', path, init, body),\n patch: <T>(path: string, body?: unknown, init?: RequestOptions) => request<T>('PATCH', path, init, body),\n delete: <T>(path: string, init?: RequestOptions) => request<T>('DELETE', path, init),\n };\n}\n","import { createHttpClient, type HttpClient, type FetchLike } from '@core/httpClient';\nimport { createVideosResource, type VideosResource } from '@resources/videos';\nimport { createCollectionsResource, type CollectionsResource } from '@resources/collections';\n\n// Public type exports for consumers (barrel)\nexport * from '@src/types';\n\nexport const BASE_URL = process.env.JAAQ_API_URL as string;\n\nexport interface SDKConfig {\n baseUrl?: string; // Pending to approve\n apiKey: string; // Provided by backend per client\n clientId: string; // Provided by each consuming company at init\n fetch?: FetchLike; // Optional fetch injection (Node/custom envs) // Pending to approve\n timeoutMs?: number;\n headers?: Record<string, string>; // Pending to approve\n apiKeyHeaderName?: string;\n}\n\nexport class JaaqClient {\n public readonly videos: VideosResource;\n public readonly collections: CollectionsResource;\n\n // Keep constructor private to enforce controlled instantiation.\n private constructor(http: HttpClient) {\n this.videos = createVideosResource(http);\n this.collections = createCollectionsResource(http);\n }\n\n /**\n * Public \"friend\" constructor that remains inside the class boundary.\n * This method is callable from the module-level build function\n * without exposing `new JaaqClient(...)` to consumers.\n */\n static fromHttp(http: HttpClient): JaaqClient {\n return new JaaqClient(http);\n }\n\n /**\n * OO-friendly static initializer.\n * Delegates to the single source of truth: `buildClient`.\n */\n static init(config: SDKConfig): JaaqClient {\n return buildClient(config);\n }\n}\n\n/**\n * Canonical factory (idiomatic for JS/TS).\n * Delegates to the single source of truth: `buildClient`.\n */\nexport function createJaaqClient(config: SDKConfig): JaaqClient {\n return buildClient(config);\n}\n\n/**\n * Single source of truth for constructing the client.\n * Both `createJaaqClient` and `JaaqClient.init` call this function.\n * The constructor stays private; instantiation is funneled via `JaaqClient.fromHttp`.\n */\nfunction buildClient(config: SDKConfig): JaaqClient {\n const { baseUrl = BASE_URL, apiKey, clientId, fetch: fetchImpl, headers, apiKeyHeaderName = 'x-api-key' } = config;\n\n const http = createHttpClient({\n baseUrl,\n apiKey,\n clientId,\n apiKeyHeaderName,\n fetch: fetchImpl ?? (globalThis.fetch as FetchLike | undefined),\n headers,\n });\n\n return JaaqClient.fromHttp(http);\n}\n","import type { HttpClient } from '@core/httpClient';\nimport type { Video } from '@src/types/videos';\n\nexport interface VideosResource {\n getById(_id: string): Promise<Video>;\n}\n\nexport function createVideosResource(http: HttpClient): VideosResource {\n return {\n async getById(id: string) {\n const path = `b2b/videos/${encodeURIComponent(id)}`;\n return http.get<Video>(path);\n },\n };\n}\n","import type { HttpClient } from '@core/httpClient';\nimport type { Collection } from '@src/types/collection';\n\nexport interface CollectionsResource {\n list(): Promise<Collection[]>;\n getById(_id: string): Promise<Collection>;\n}\n\nexport function createCollectionsResource(http: HttpClient): CollectionsResource {\n return {\n async list() {\n const path = 'b2b/collections';\n return http.get<Collection[]>(path);\n },\n async getById(id: string) {\n const path = `b2b/collections/${encodeURIComponent(id)}`;\n return http.get<Collection>(path);\n },\n };\n}\n"],"names":["createHttpClient","config","baseUrl","apiKey","clientId","fetch","fetchImpl","headers","apiKeyHeaderName","f","globalThis","Error","baseHeaders","request","async","method","path","init","body","reqInit","undefined","JSON","stringify","res","test","replace","joinUrl","fullUrl","ok","text","catch","status","statusText","json","parseJson","get","post","put","patch","delete","BASE_URL","JaaqClient","constructor","http","this","videos","getById","id","encodeURIComponent","createVideosResource","collections","createCollectionsResource","fromHttp","buildClient"],"mappings":"8OA4CM,SAAUA,EAAiBC,GAC/B,MAAMC,QAAEA,EAAOC,OAAEA,EAAMC,SAAEA,EAAUC,MAAOC,EAASC,QAAEA,EAAOC,iBAAEA,EAAmB,aAAgBP,EAE3FQ,EAA2BH,GAAcI,WAAWL,MAC1D,IAAKI,EACH,MAAM,IAAIE,MAAM,kGAGlB,MAAMC,EAAsC,CAC1C,eAAgB,mBAChBJ,CAACA,GAAmBL,EACpB,cAAeC,KACZG,GAKCM,EAAUC,MAAUC,EAAgBC,EAAcC,EAAuBC,KAC7E,MAAMC,EAA0B,CAC9BJ,SACAR,QAAS,IACJK,KACCK,GAAMV,YAETU,QAEQG,IAATF,IAAoBC,EAAQD,KAAOG,KAAKC,UAAUJ,IACtD,MAAMK,QAAYd,EAZJ,CAACO,GAvBnB,SAAiBd,EAAiBc,GAEhC,MAAI,gBAAgBQ,KAAKR,GAAcA,EAGhC,GAFMd,EAAQuB,QAAQ,OAAQ,OACpBT,EAAKS,QAAQ,OAAQ,KAExC,CAiBoCC,CAAQxB,EAASc,GAY7BW,CAAQX,GAAOG,GACnC,OAlDJL,eAA4BS,GAC1B,IAAKA,EAAIK,GAAI,CACX,MAAMC,QAAaN,EAAIM,OAAOC,MAAM,IAAM,IAC1C,MAAM,IAAInB,MAAM,QAAQY,EAAIQ,WAAWF,GAAQN,EAAIS,aACrD,CACA,GAAmB,MAAfT,EAAIQ,OACR,OAAOR,EAAIU,MACb,CA2CWC,CAAaX,IAGtB,MAAO,CACLY,IAAK,CAAInB,EAAcC,IAA0BJ,EAAW,MAAOG,EAAMC,GACzEmB,KAAM,CAAIpB,EAAcE,EAAgBD,IAA0BJ,EAAW,OAAQG,EAAMC,EAAMC,GACjGmB,IAAK,CAAIrB,EAAcE,EAAgBD,IAA0BJ,EAAW,MAAOG,EAAMC,EAAMC,GAC/FoB,MAAO,CAAItB,EAAcE,EAAgBD,IAA0BJ,EAAW,QAASG,EAAMC,EAAMC,GACnGqB,OAAQ,CAAIvB,EAAcC,IAA0BJ,EAAW,SAAUG,EAAMC,GAEnF,OC3EauB,OAAWpB,QAYXqB,EAKX,WAAAC,CAAoBC,GAClBC,KAAKC,OClBH,SAA+BF,GACnC,MAAO,CACL,aAAMG,CAAQC,GACZ,MAAM/B,EAAO,cAAcgC,mBAAmBD,KAC9C,OAAOJ,EAAKR,IAAWnB,EACzB,EAEJ,CDWkBiC,CAAqBN,GACnCC,KAAKM,YElBH,SAAoCP,GACxC,MAAO,CACL7B,KAAU,SAED6B,EAAKR,IADC,mBAGf,aAAMW,CAAQC,GACZ,MAAM/B,EAAO,mBAAmBgC,mBAAmBD,KACnD,OAAOJ,EAAKR,IAAgBnB,EAC9B,EAEJ,CFOuBmC,CAA0BR,EAC/C,CAOA,eAAOS,CAAST,GACd,OAAO,IAAIF,EAAWE,EACxB,CAMA,WAAO1B,CAAKhB,GACV,OAAOoD,EAAYpD,EACrB,EAgBF,SAASoD,EAAYpD,GACnB,MAAMC,QAAEA,EAAUsC,EAAQrC,OAAEA,EAAMC,SAAEA,EAAUC,MAAOC,EAASC,QAAEA,EAAOC,iBAAEA,EAAmB,aAAgBP,EAEtG0C,EAAO3C,EAAiB,CAC5BE,UACAC,SACAC,WACAI,mBACAH,MAAOC,GAAcI,WAAWL,MAChCE,YAGF,OAAOkC,EAAWW,SAAST,EAC7B,gDAtBM,SAA2B1C,GAC/B,OAAOoD,EAAYpD,EACrB"}
|
package/package.json
ADDED
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@jaaq/jaaq-sdk-js",
|
|
3
|
+
"version": "0.0.1",
|
|
4
|
+
"description": "Official JavaScript SDK for JAAQ API",
|
|
5
|
+
"main": "./dist/index.cjs",
|
|
6
|
+
"module": "./dist/index.mjs",
|
|
7
|
+
"types": "./dist/index.d.ts",
|
|
8
|
+
"scripts": {
|
|
9
|
+
"build": "rollup -c",
|
|
10
|
+
"dev": "dotenvx run -f .env.development -- rollup -c --watch",
|
|
11
|
+
"build:dev": "dotenvx run -f .env.development -- rollup -c",
|
|
12
|
+
"build:staging": "dotenvx run -f .env.staging -- rollup -c",
|
|
13
|
+
"build:prod": "dotenvx run -f .env.production -- rollup -c",
|
|
14
|
+
"test": "vitest run --exclude=tests/build",
|
|
15
|
+
"test:watch": "vitest --exclude=tests/build",
|
|
16
|
+
"test:coverage": "vitest run --coverage --exclude=tests/build",
|
|
17
|
+
"test:coverage:watch": "vitest --coverage --exclude=tests/build",
|
|
18
|
+
"test:smoke:dev": "dotenvx run -f .env.development -- vitest run tests/build",
|
|
19
|
+
"test:smoke:staging": "dotenvx run -f .env.staging -- vitest run tests/build",
|
|
20
|
+
"test:smoke:prod": "dotenvx run -f .env.production -- vitest run tests/build",
|
|
21
|
+
"test:smoke:ci": "vitest run tests/build",
|
|
22
|
+
"check-paths-in-bundle": "grep -R -nE --exclude='*.map' '@core/|@resources/' dist || echo 'OK no aliases found'",
|
|
23
|
+
"openapi:gen": "openapi-typescript ./openapi.json -o ./src/gen/openapi.ts",
|
|
24
|
+
"audit:moderate": "pnpm audit --audit-level=moderate",
|
|
25
|
+
"lint": "eslint .",
|
|
26
|
+
"lint:fix": "eslint . --fix",
|
|
27
|
+
"format": "prettier --write .",
|
|
28
|
+
"format:check": "prettier --check .",
|
|
29
|
+
"prepare": "husky"
|
|
30
|
+
},
|
|
31
|
+
"exports": {
|
|
32
|
+
".": {
|
|
33
|
+
"types": "./dist/index.d.ts",
|
|
34
|
+
"import": "./dist/index.mjs",
|
|
35
|
+
"require": "./dist/index.cjs",
|
|
36
|
+
"default": "./dist/index.mjs"
|
|
37
|
+
}
|
|
38
|
+
},
|
|
39
|
+
"keywords": [
|
|
40
|
+
"jaaq",
|
|
41
|
+
"sdk",
|
|
42
|
+
"api",
|
|
43
|
+
"video",
|
|
44
|
+
"collections"
|
|
45
|
+
],
|
|
46
|
+
"author": "JAAQ",
|
|
47
|
+
"license": "ISC",
|
|
48
|
+
"repository": {
|
|
49
|
+
"type": "git",
|
|
50
|
+
"url": "https://github.com/jaaq-eng/jaaq-sdk-js.git"
|
|
51
|
+
},
|
|
52
|
+
"bugs": {
|
|
53
|
+
"url": "https://github.com/jaaq-eng/jaaq-sdk-js/issues"
|
|
54
|
+
},
|
|
55
|
+
"homepage": "https://github.com/jaaq-eng/jaaq-sdk-js#readme",
|
|
56
|
+
"publishConfig": {
|
|
57
|
+
"access": "public"
|
|
58
|
+
},
|
|
59
|
+
"packageManager": "pnpm@10.17.1",
|
|
60
|
+
"lint-staged": {
|
|
61
|
+
"*.{ts,tsx,js}": [
|
|
62
|
+
"eslint --fix --max-warnings=0"
|
|
63
|
+
],
|
|
64
|
+
"*.{json,md,yml,yaml,ts,tsx,js}": [
|
|
65
|
+
"prettier --write"
|
|
66
|
+
]
|
|
67
|
+
},
|
|
68
|
+
"files": [
|
|
69
|
+
"dist",
|
|
70
|
+
"README.md",
|
|
71
|
+
"LICENSE"
|
|
72
|
+
],
|
|
73
|
+
"devDependencies": {
|
|
74
|
+
"@commitlint/cli": "^20.1.0",
|
|
75
|
+
"@commitlint/config-conventional": "^20.0.0",
|
|
76
|
+
"@dotenvx/dotenvx": "^1.51.1",
|
|
77
|
+
"@eslint/js": "^9.39.1",
|
|
78
|
+
"@rollup/plugin-commonjs": "^29.0.0",
|
|
79
|
+
"@rollup/plugin-node-resolve": "^16.0.3",
|
|
80
|
+
"@rollup/plugin-replace": "^6.0.3",
|
|
81
|
+
"@rollup/plugin-terser": "^0.4.4",
|
|
82
|
+
"@rollup/plugin-typescript": "^12.3.0",
|
|
83
|
+
"@types/node": "^24.10.0",
|
|
84
|
+
"@typescript-eslint/eslint-plugin": "^8.46.3",
|
|
85
|
+
"@typescript-eslint/parser": "^8.46.3",
|
|
86
|
+
"eslint": "^9.39.1",
|
|
87
|
+
"eslint-config-prettier": "^10.1.8",
|
|
88
|
+
"globals": "^16.5.0",
|
|
89
|
+
"husky": "^9.1.7",
|
|
90
|
+
"lint-staged": "^16.2.6",
|
|
91
|
+
"msw": "^2.12.1",
|
|
92
|
+
"openapi-typescript": "^7.10.1",
|
|
93
|
+
"prettier": "^3.6.2",
|
|
94
|
+
"rollup": "^4.53.2",
|
|
95
|
+
"rollup-plugin-dts": "^6.2.3",
|
|
96
|
+
"tslib": "^2.8.1",
|
|
97
|
+
"typescript": "^5.9.3",
|
|
98
|
+
"vitest": "^4.0.8",
|
|
99
|
+
"@vitest/coverage-v8": "^4.0.8",
|
|
100
|
+
"rollup-plugin-tsconfig-paths": "^1.5.2"
|
|
101
|
+
}
|
|
102
|
+
}
|