@jaaq/jaaq-sdk-js 0.0.1 → 1.0.0-dev-b6088e1-20251204

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 CHANGED
@@ -1,106 +1,27 @@
1
- # JAAQ TypeScript SDK (`jaaq-sdk-js`)
1
+ # JAAQ TypeScript SDK
2
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
- ```
3
+ A lightweight, type-safe SDK for interacting with the JAAQ API. Built with TypeScript and optimized for modern JavaScript frameworks.
29
4
 
30
5
  ## Installation
31
6
 
32
7
  ```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
8
+ npm install @jaaq/jaaq-sdk-js
52
9
  ```
53
10
 
54
- ## Create types
55
-
56
- Once we have the last openApi.json file from the Back-end
57
-
58
11
  ```bash
59
- pnpm openapi:gen
12
+ yarn add @jaaq/jaaq-sdk-js
60
13
  ```
61
14
 
62
- And then:
63
-
64
15
  ```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
-
16
+ pnpm add @jaaq/jaaq-sdk-js
70
17
  ```
71
18
 
72
- ## Configuration options:
19
+ ## Quick Start
73
20
 
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.
21
+ ### Using JaaqClient (Class-based)
81
22
 
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
- ![Install module screenshot](./docs/install-sdk.png)
98
-
99
- #### classic mode:
100
-
101
- ```bash
102
- // Import module
103
- import { JaaqClient } from "jaaq-sdk-js";
23
+ ```typescript
24
+ import { JaaqClient } from '@jaaq/jaaq-sdk-js';
104
25
 
105
26
  const client = JaaqClient.init({
106
27
  apiKey: '<YOUR_API_KEY>',
@@ -108,11 +29,10 @@ const client = JaaqClient.init({
108
29
  });
109
30
  ```
110
31
 
111
- #### JS mode:
32
+ ### Using createJaaqClient (Functional)
112
33
 
113
- ```bash
114
- // Import module
115
- import { createJaaqClient } from "jaaq-sdk-js";
34
+ ```typescript
35
+ import { createJaaqClient } from '@jaaq/jaaq-sdk-js';
116
36
 
117
37
  const client = createJaaqClient({
118
38
  apiKey: '<YOUR_API_KEY>',
@@ -120,23 +40,20 @@ const client = createJaaqClient({
120
40
  });
121
41
  ```
122
42
 
123
- #### Access to the different resources:
124
-
125
- ```bash
126
- client.videos.getById('xxxxxx')
127
- ```
43
+ ## Usage
128
44
 
129
- or
45
+ ### Accessing Resources
130
46
 
131
- ```bash
132
- client.collections.list()
47
+ ```typescript
48
+ const video = await client.videos.getById('video-id');
49
+ const collections = await client.collections.list();
133
50
  ```
134
51
 
135
- #### Ex: Getting and displaying a video
52
+ ### React Example: Basic Video
136
53
 
137
- ```bash
54
+ ```typescript
138
55
  import { useEffect, useRef } from "react";
139
- import { createJaaqClient } from "jaaq-sdk-js";
56
+ import { createJaaqClient } from "@jaaq/jaaq-sdk-js";
140
57
 
141
58
  const API_KEY = import.meta.env.VITE_JAAQ_API_KEY;
142
59
  const CLIENT_ID = import.meta.env.VITE_JAAQ_CLIENT_ID;
@@ -161,16 +78,16 @@ export default function VideoExample({ id }: { id: string }) {
161
78
  ref={videoRef}
162
79
  autoPlay
163
80
  controls
164
- />;
165
- )
81
+ />
82
+ );
166
83
  }
167
84
  ```
168
85
 
169
- #### If extension is .m3u8
86
+ ### React Example: HLS Streaming (.m3u8)
170
87
 
171
- ```bash
88
+ ```typescript
172
89
  import { useEffect, useRef } from "react";
173
- import { createJaaqClient } from "jaaq-sdk-js";
90
+ import { createJaaqClient } from "@jaaq/jaaq-sdk-js";
174
91
  import Hls from "hls.js";
175
92
 
176
93
  const API_KEY = import.meta.env.VITE_JAAQ_API_KEY!;
@@ -185,7 +102,7 @@ export default function VideoExample({ id }: { id: string }) {
185
102
  (async () => {
186
103
  const client = createJaaqClient({ apiKey: API_KEY, clientId: CLIENT_ID });
187
104
  const resp = await client.videos.getById(id);
188
- const url = resp.video.videoUrl; // e.g. https://.../video.m3u8
105
+ const url = resp.video.videoUrl;
189
106
  const video = videoRef.current;
190
107
  if (!video || !url) return;
191
108
 
@@ -204,7 +121,30 @@ export default function VideoExample({ id }: { id: string }) {
204
121
  ref={videoRef}
205
122
  autoPlay
206
123
  controls
207
- />;
208
- )
124
+ />
125
+ );
209
126
  }
210
127
  ```
128
+
129
+ ## Configuration
130
+
131
+ | Option | Type | Required | Default | Description |
132
+ | ----------- | ---------- | -------- | ---------------------- | ------------------------------- |
133
+ | `apiKey` | `string` | Yes | - | Your JAAQ API key |
134
+ | `clientId` | `string` | Yes | - | Your client identifier |
135
+ | `baseUrl` | `string` | No | `https://api.jaaq.app` | API base URL |
136
+ | `fetch` | `Function` | No | `globalThis.fetch` | Custom fetch implementation |
137
+ | `timeoutMs` | `number` | No | - | Request timeout in milliseconds |
138
+
139
+ ## Resources
140
+
141
+ - [Development Guide](./DEVELOPMENT.md) - For SDK contributors and developers
142
+ - [Release Notes](./RELEASE.md) - Version history and changelog
143
+
144
+ ## TypeScript Support
145
+
146
+ This SDK is written in TypeScript and includes complete type definitions. Types are automatically generated from the JAAQ OpenAPI specification.
147
+
148
+ ## License
149
+
150
+ MIT
package/dist/index.cjs CHANGED
@@ -9,32 +9,25 @@ async function parseJson(res) {
9
9
  return undefined;
10
10
  return res.json();
11
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) {
12
+ function joinUrl(baseUrl, clientId, path) {
18
13
  // return path if it is an absolute URL
19
14
  if (/^https?:\/\//i.test(path))
20
15
  return path;
21
16
  const base = baseUrl.replace(/\/+$/, '');
22
17
  const relative = path.replace(/^\/+/, '');
23
- return `${base}/${relative}`;
18
+ return `${base}/b2b/v1/subscription/${encodeURIComponent(clientId)}${relative.startsWith('/') ? relative : `/${relative}`}`;
24
19
  }
25
20
  function createHttpClient(config) {
26
- const { baseUrl, apiKey, clientId, fetch: fetchImpl, headers, apiKeyHeaderName = 'x-api-key' } = config;
21
+ const { baseUrl, apiKey, clientId, fetch: fetchImpl } = config;
27
22
  const f = fetchImpl ?? globalThis.fetch;
28
23
  if (!f) {
29
24
  throw new Error('No fetch implementation found. Provide one in SDKConfig.fetch for Node or custom environments.');
30
25
  }
31
26
  const baseHeaders = {
32
27
  'Content-Type': 'application/json',
33
- [apiKeyHeaderName]: apiKey,
34
- 'x-client-id': clientId,
35
- ...headers,
28
+ 'x-api-key': apiKey,
36
29
  };
37
- const fullUrl = (path) => joinUrl(baseUrl, path);
30
+ const fullUrl = (path) => joinUrl(baseUrl, clientId, path);
38
31
  const request = async (method, path, init, body) => {
39
32
  const reqInit = {
40
33
  method,
@@ -61,8 +54,9 @@ function createHttpClient(config) {
61
54
  function createVideosResource(http) {
62
55
  return {
63
56
  async getById(id) {
64
- const path = `b2b/videos/${encodeURIComponent(id)}`;
65
- return http.get(path);
57
+ const path = `/videos/${encodeURIComponent(id)}`;
58
+ const response = await http.get(path);
59
+ return response.video;
66
60
  },
67
61
  };
68
62
  }
@@ -70,17 +64,19 @@ function createVideosResource(http) {
70
64
  function createCollectionsResource(http) {
71
65
  return {
72
66
  async list() {
73
- const path = 'b2b/collections';
74
- return http.get(path);
67
+ const path = '/collections';
68
+ const response = await http.get(path);
69
+ return response.collections;
75
70
  },
76
71
  async getById(id) {
77
- const path = `b2b/collections/${encodeURIComponent(id)}`;
78
- return http.get(path);
72
+ const path = `/collections/${encodeURIComponent(id)}`;
73
+ const response = await http.get(path);
74
+ return response.collection;
79
75
  },
80
76
  };
81
77
  }
82
78
 
83
- const BASE_URL = undefined;
79
+ const BASE_URL = "https://api.jaaq.app";
84
80
  class JaaqClient {
85
81
  // Keep constructor private to enforce controlled instantiation.
86
82
  constructor(http) {
@@ -116,14 +112,12 @@ function createJaaqClient(config) {
116
112
  * The constructor stays private; instantiation is funneled via `JaaqClient.fromHttp`.
117
113
  */
118
114
  function buildClient(config) {
119
- const { baseUrl = BASE_URL, apiKey, clientId, fetch: fetchImpl, headers, apiKeyHeaderName = 'x-api-key' } = config;
115
+ const { baseUrl = BASE_URL, apiKey, clientId, fetch: fetchImpl } = config;
120
116
  const http = createHttpClient({
121
117
  baseUrl,
122
118
  apiKey,
123
119
  clientId,
124
- apiKeyHeaderName,
125
120
  fetch: fetchImpl ?? globalThis.fetch,
126
- headers,
127
121
  });
128
122
  return JaaqClient.fromHttp(http);
129
123
  }
@@ -1 +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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"}
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 fetch?: FetchLike;\n timeoutMs?: number;\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\nfunction joinUrl(baseUrl: string, clientId: 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}/b2b/v1/subscription/${encodeURIComponent(clientId)}${relative.startsWith('/') ? relative : `/${relative}`}`;\n}\n\nexport function createHttpClient(config: HttpClientConfig): HttpClient {\n const { baseUrl, apiKey, clientId, fetch: fetchImpl } = 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 'x-api-key': apiKey,\n };\n\n const fullUrl = (path: string) => joinUrl(baseUrl, clientId, 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 { VideoDTO } from '@src/types/videos';\n\nexport type VideosResource = {\n getById(_id: string): Promise<VideoDTO>;\n};\n\nexport function createVideosResource(http: HttpClient): VideosResource {\n return {\n async getById(id: string) {\n const path = `/videos/${encodeURIComponent(id)}`;\n const response = await http.get<{ video: VideoDTO }>(path);\n return response.video;\n },\n };\n}\n","import type { HttpClient } from '@core/httpClient';\nimport type { CollectionDTO } from '@src/types/collection';\n\nexport type CollectionsResource = {\n list(): Promise<CollectionDTO[]>;\n getById(_id: string): Promise<CollectionDTO>;\n};\n\nexport function createCollectionsResource(http: HttpClient): CollectionsResource {\n return {\n async list() {\n const path = '/collections';\n const response = await http.get<{ collections: CollectionDTO[] }>(path);\n return response.collections;\n },\n async getById(id: string) {\n const path = `/collections/${encodeURIComponent(id)}`;\n const response = await http.get<{ collection: CollectionDTO }>(path);\n return response.collection;\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}\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 } = config;\n\n const http = createHttpClient({\n baseUrl,\n apiKey,\n clientId,\n fetch: fetchImpl ?? (globalThis.fetch as FetchLike | undefined),\n });\n\n return JaaqClient.fromHttp(http);\n}\n"],"names":[],"mappings":"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"}
package/dist/index.d.ts CHANGED
@@ -8,40 +8,39 @@ interface HttpClient {
8
8
  delete<T>(_path: string, _init?: RequestOptions): Promise<T>;
9
9
  }
10
10
 
11
- interface Video {
11
+ type VideoDTO = {
12
12
  id: string;
13
13
  videoId: string;
14
- questionId: string;
15
14
  question: string;
16
- status: number | null;
17
- transcription: string | null;
15
+ status: number;
16
+ transcription: string;
17
+ subtitle: string;
18
18
  createdAt: string;
19
- modifiedAt: string;
20
19
  videoUrl: string;
21
20
  published: boolean;
22
21
  tags: string[];
23
22
  severity: number | null;
24
23
  duration: number;
25
- subTopics: string[];
26
24
  description: string;
27
- }
25
+ };
28
26
 
29
- interface VideosResource {
30
- getById(_id: string): Promise<Video>;
31
- }
27
+ type VideosResource = {
28
+ getById(_id: string): Promise<VideoDTO>;
29
+ };
32
30
 
33
- interface Collection {
31
+ type CollectionDTO = {
34
32
  id: string;
35
33
  name: string;
36
34
  description: string;
37
35
  imageUrl: string;
38
- videos: Video[];
39
- }
36
+ createdAt: string;
37
+ videos: VideoDTO[];
38
+ };
40
39
 
41
- interface CollectionsResource {
42
- list(): Promise<Collection[]>;
43
- getById(_id: string): Promise<Collection>;
44
- }
40
+ type CollectionsResource = {
41
+ list(): Promise<CollectionDTO[]>;
42
+ getById(_id: string): Promise<CollectionDTO>;
43
+ };
45
44
 
46
45
  type ISODateTimeString = string;
47
46
  interface ApiError {
@@ -64,8 +63,6 @@ interface SDKConfig {
64
63
  clientId: string;
65
64
  fetch?: FetchLike;
66
65
  timeoutMs?: number;
67
- headers?: Record<string, string>;
68
- apiKeyHeaderName?: string;
69
66
  }
70
67
  declare class JaaqClient {
71
68
  readonly videos: VideosResource;
@@ -90,4 +87,4 @@ declare class JaaqClient {
90
87
  declare function createJaaqClient(config: SDKConfig): JaaqClient;
91
88
 
92
89
  export { BASE_URL, JaaqClient, createJaaqClient };
93
- export type { ApiError, Collection, ISODateTimeString, SDKConfig, Subtopic, Video };
90
+ export type { ApiError, CollectionDTO, ISODateTimeString, SDKConfig, Subtopic, VideoDTO };
package/dist/index.mjs CHANGED
@@ -7,32 +7,25 @@ async function parseJson(res) {
7
7
  return undefined;
8
8
  return res.json();
9
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) {
10
+ function joinUrl(baseUrl, clientId, path) {
16
11
  // return path if it is an absolute URL
17
12
  if (/^https?:\/\//i.test(path))
18
13
  return path;
19
14
  const base = baseUrl.replace(/\/+$/, '');
20
15
  const relative = path.replace(/^\/+/, '');
21
- return `${base}/${relative}`;
16
+ return `${base}/b2b/v1/subscription/${encodeURIComponent(clientId)}${relative.startsWith('/') ? relative : `/${relative}`}`;
22
17
  }
23
18
  function createHttpClient(config) {
24
- const { baseUrl, apiKey, clientId, fetch: fetchImpl, headers, apiKeyHeaderName = 'x-api-key' } = config;
19
+ const { baseUrl, apiKey, clientId, fetch: fetchImpl } = config;
25
20
  const f = fetchImpl ?? globalThis.fetch;
26
21
  if (!f) {
27
22
  throw new Error('No fetch implementation found. Provide one in SDKConfig.fetch for Node or custom environments.');
28
23
  }
29
24
  const baseHeaders = {
30
25
  'Content-Type': 'application/json',
31
- [apiKeyHeaderName]: apiKey,
32
- 'x-client-id': clientId,
33
- ...headers,
26
+ 'x-api-key': apiKey,
34
27
  };
35
- const fullUrl = (path) => joinUrl(baseUrl, path);
28
+ const fullUrl = (path) => joinUrl(baseUrl, clientId, path);
36
29
  const request = async (method, path, init, body) => {
37
30
  const reqInit = {
38
31
  method,
@@ -59,8 +52,9 @@ function createHttpClient(config) {
59
52
  function createVideosResource(http) {
60
53
  return {
61
54
  async getById(id) {
62
- const path = `b2b/videos/${encodeURIComponent(id)}`;
63
- return http.get(path);
55
+ const path = `/videos/${encodeURIComponent(id)}`;
56
+ const response = await http.get(path);
57
+ return response.video;
64
58
  },
65
59
  };
66
60
  }
@@ -68,17 +62,19 @@ function createVideosResource(http) {
68
62
  function createCollectionsResource(http) {
69
63
  return {
70
64
  async list() {
71
- const path = 'b2b/collections';
72
- return http.get(path);
65
+ const path = '/collections';
66
+ const response = await http.get(path);
67
+ return response.collections;
73
68
  },
74
69
  async getById(id) {
75
- const path = `b2b/collections/${encodeURIComponent(id)}`;
76
- return http.get(path);
70
+ const path = `/collections/${encodeURIComponent(id)}`;
71
+ const response = await http.get(path);
72
+ return response.collection;
77
73
  },
78
74
  };
79
75
  }
80
76
 
81
- const BASE_URL = undefined;
77
+ const BASE_URL = "https://api.jaaq.app";
82
78
  class JaaqClient {
83
79
  // Keep constructor private to enforce controlled instantiation.
84
80
  constructor(http) {
@@ -114,14 +110,12 @@ function createJaaqClient(config) {
114
110
  * The constructor stays private; instantiation is funneled via `JaaqClient.fromHttp`.
115
111
  */
116
112
  function buildClient(config) {
117
- const { baseUrl = BASE_URL, apiKey, clientId, fetch: fetchImpl, headers, apiKeyHeaderName = 'x-api-key' } = config;
113
+ const { baseUrl = BASE_URL, apiKey, clientId, fetch: fetchImpl } = config;
118
114
  const http = createHttpClient({
119
115
  baseUrl,
120
116
  apiKey,
121
117
  clientId,
122
- apiKeyHeaderName,
123
118
  fetch: fetchImpl ?? globalThis.fetch,
124
- headers,
125
119
  });
126
120
  return JaaqClient.fromHttp(http);
127
121
  }
@@ -1 +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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"}
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 fetch?: FetchLike;\n timeoutMs?: number;\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\nfunction joinUrl(baseUrl: string, clientId: 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}/b2b/v1/subscription/${encodeURIComponent(clientId)}${relative.startsWith('/') ? relative : `/${relative}`}`;\n}\n\nexport function createHttpClient(config: HttpClientConfig): HttpClient {\n const { baseUrl, apiKey, clientId, fetch: fetchImpl } = 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 'x-api-key': apiKey,\n };\n\n const fullUrl = (path: string) => joinUrl(baseUrl, clientId, 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 { VideoDTO } from '@src/types/videos';\n\nexport type VideosResource = {\n getById(_id: string): Promise<VideoDTO>;\n};\n\nexport function createVideosResource(http: HttpClient): VideosResource {\n return {\n async getById(id: string) {\n const path = `/videos/${encodeURIComponent(id)}`;\n const response = await http.get<{ video: VideoDTO }>(path);\n return response.video;\n },\n };\n}\n","import type { HttpClient } from '@core/httpClient';\nimport type { CollectionDTO } from '@src/types/collection';\n\nexport type CollectionsResource = {\n list(): Promise<CollectionDTO[]>;\n getById(_id: string): Promise<CollectionDTO>;\n};\n\nexport function createCollectionsResource(http: HttpClient): CollectionsResource {\n return {\n async list() {\n const path = '/collections';\n const response = await http.get<{ collections: CollectionDTO[] }>(path);\n return response.collections;\n },\n async getById(id: string) {\n const path = `/collections/${encodeURIComponent(id)}`;\n const response = await http.get<{ collection: CollectionDTO }>(path);\n return response.collection;\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}\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 } = config;\n\n const http = createHttpClient({\n baseUrl,\n apiKey,\n clientId,\n fetch: fetchImpl ?? (globalThis.fetch as FetchLike | undefined),\n });\n\n return JaaqClient.fromHttp(http);\n}\n"],"names":[],"mappings":"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"}
@@ -1,2 +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)}});
1
+ !function(t,e){"object"==typeof exports&&"undefined"!=typeof module?e(exports):"function"==typeof define&&define.amd?define(["exports"],e):e((t="undefined"!=typeof globalThis?globalThis:t||self).JaaqSDK={})}(this,function(t){"use strict";function e(t){const{baseUrl:e,apiKey:n,clientId:o,fetch:i}=t,c=i??globalThis.fetch;if(!c)throw new Error("No fetch implementation found. Provide one in SDKConfig.fetch for Node or custom environments.");const s={"Content-Type":"application/json","x-api-key":n},r=t=>function(t,e,n){if(/^https?:\/\//i.test(n))return n;const o=t.replace(/\/+$/,""),i=n.replace(/^\/+/,"");return`${o}/b2b/v1/subscription/${encodeURIComponent(e)}${i.startsWith("/")?i:`/${i}`}`}(e,o,t),a=async(t,e,n,o)=>{const i={method:t,headers:{...s,...n?.headers},...n};void 0!==o&&(i.body=JSON.stringify(o));return async function(t){if(!t.ok){const e=await t.text().catch(()=>"");throw new Error(`HTTP ${t.status}: ${e||t.statusText}`)}if(204!==t.status)return t.json()}(await c(r(e),i))};return{get:(t,e)=>a("GET",t,e),post:(t,e,n)=>a("POST",t,n,e),put:(t,e,n)=>a("PUT",t,n,e),patch:(t,e,n)=>a("PATCH",t,n,e),delete:(t,e)=>a("DELETE",t,e)}}const n="https://api.jaaq.app";class o{constructor(t){this.videos=function(t){return{async getById(e){const n=`/videos/${encodeURIComponent(e)}`;return(await t.get(n)).video}}}(t),this.collections=function(t){return{list:async()=>(await t.get("/collections")).collections,async getById(e){const n=`/collections/${encodeURIComponent(e)}`;return(await t.get(n)).collection}}}(t)}static fromHttp(t){return new o(t)}static init(t){return i(t)}}function i(t){const{baseUrl:i=n,apiKey:c,clientId:s,fetch:r}=t,a=e({baseUrl:i,apiKey:c,clientId:s,fetch:r??globalThis.fetch});return o.fromHttp(a)}t.BASE_URL=n,t.JaaqClient=o,t.createJaaqClient=function(t){return i(t)}});
2
2
  //# sourceMappingURL=jaaq-sdk.min.js.map
@@ -1 +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"}
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 fetch?: FetchLike;\n timeoutMs?: number;\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\nfunction joinUrl(baseUrl: string, clientId: 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}/b2b/v1/subscription/${encodeURIComponent(clientId)}${relative.startsWith('/') ? relative : `/${relative}`}`;\n}\n\nexport function createHttpClient(config: HttpClientConfig): HttpClient {\n const { baseUrl, apiKey, clientId, fetch: fetchImpl } = 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 'x-api-key': apiKey,\n };\n\n const fullUrl = (path: string) => joinUrl(baseUrl, clientId, 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}\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 } = config;\n\n const http = createHttpClient({\n baseUrl,\n apiKey,\n clientId,\n fetch: fetchImpl ?? (globalThis.fetch as FetchLike | undefined),\n });\n\n return JaaqClient.fromHttp(http);\n}\n","import type { HttpClient } from '@core/httpClient';\nimport type { VideoDTO } from '@src/types/videos';\n\nexport type VideosResource = {\n getById(_id: string): Promise<VideoDTO>;\n};\n\nexport function createVideosResource(http: HttpClient): VideosResource {\n return {\n async getById(id: string) {\n const path = `/videos/${encodeURIComponent(id)}`;\n const response = await http.get<{ video: VideoDTO }>(path);\n return response.video;\n },\n };\n}\n","import type { HttpClient } from '@core/httpClient';\nimport type { CollectionDTO } from '@src/types/collection';\n\nexport type CollectionsResource = {\n list(): Promise<CollectionDTO[]>;\n getById(_id: string): Promise<CollectionDTO>;\n};\n\nexport function createCollectionsResource(http: HttpClient): CollectionsResource {\n return {\n async list() {\n const path = '/collections';\n const response = await http.get<{ collections: CollectionDTO[] }>(path);\n return response.collections;\n },\n async getById(id: string) {\n const path = `/collections/${encodeURIComponent(id)}`;\n const response = await http.get<{ collection: CollectionDTO }>(path);\n return response.collection;\n },\n };\n}\n"],"names":["createHttpClient","config","baseUrl","apiKey","clientId","fetch","fetchImpl","f","globalThis","Error","baseHeaders","fullUrl","path","test","base","replace","relative","encodeURIComponent","startsWith","joinUrl","request","async","method","init","body","reqInit","headers","undefined","JSON","stringify","res","ok","text","catch","status","statusText","json","parseJson","get","post","put","patch","delete","BASE_URL","JaaqClient","constructor","http","this","videos","getById","id","video","createVideosResource","collections","collection","createCollectionsResource","fromHttp","buildClient"],"mappings":"8OAqCM,SAAUA,EAAiBC,GAC/B,MAAMC,QAAEA,EAAOC,OAAEA,EAAMC,SAAEA,EAAUC,MAAOC,GAAcL,EAElDM,EAA2BD,GAAcE,WAAWH,MAC1D,IAAKE,EACH,MAAM,IAAIE,MAAM,kGAGlB,MAAMC,EAAsC,CAC1C,eAAgB,mBAChB,YAAaP,GAGTQ,EAAWC,GArBnB,SAAiBV,EAAiBE,EAAkBQ,GAElD,GAAI,gBAAgBC,KAAKD,GAAO,OAAOA,EACvC,MAAME,EAAOZ,EAAQa,QAAQ,OAAQ,IAC/BC,EAAWJ,EAAKG,QAAQ,OAAQ,IACtC,MAAO,GAAGD,yBAA4BG,mBAAmBb,KAAYY,EAASE,WAAW,KAAOF,EAAW,IAAIA,KACjH,CAeoCG,CAAQjB,EAASE,EAAUQ,GAEvDQ,EAAUC,MAAUC,EAAgBV,EAAcW,EAAuBC,KAC7E,MAAMC,EAA0B,CAC9BH,SACAI,QAAS,IACJhB,KACCa,GAAMG,YAETH,QAEQI,IAATH,IAAoBC,EAAQD,KAAOI,KAAKC,UAAUL,IAEtD,OA3CJH,eAA4BS,GAC1B,IAAKA,EAAIC,GAAI,CACX,MAAMC,QAAaF,EAAIE,OAAOC,MAAM,IAAM,IAC1C,MAAM,IAAIxB,MAAM,QAAQqB,EAAII,WAAWF,GAAQF,EAAIK,aACrD,CACA,GAAmB,MAAfL,EAAII,OACR,OAAOJ,EAAIM,MACb,CAoCWC,OADW9B,EAAEI,EAAQC,GAAOa,KAIrC,MAAO,CACLa,IAAK,CAAI1B,EAAcW,IAA0BH,EAAW,MAAOR,EAAMW,GACzEgB,KAAM,CAAI3B,EAAcY,EAAgBD,IAA0BH,EAAW,OAAQR,EAAMW,EAAMC,GACjGgB,IAAK,CAAI5B,EAAcY,EAAgBD,IAA0BH,EAAW,MAAOR,EAAMW,EAAMC,GAC/FiB,MAAO,CAAI7B,EAAcY,EAAgBD,IAA0BH,EAAW,QAASR,EAAMW,EAAMC,GACnGkB,OAAQ,CAAI9B,EAAcW,IAA0BH,EAAW,SAAUR,EAAMW,GAEnF,OClEaoB,EAAW,6BAUXC,EAKX,WAAAC,CAAoBC,GAClBC,KAAKC,OChBH,SAA+BF,GACnC,MAAO,CACL,aAAMG,CAAQC,GACZ,MAAMtC,EAAO,WAAWK,mBAAmBiC,KAE3C,aADuBJ,EAAKR,IAAyB1B,IACrCuC,KAClB,EAEJ,CDQkBC,CAAqBN,GACnCC,KAAKM,YEhBH,SAAoCP,GACxC,MAAO,CACLzB,KAAU,gBAEeyB,EAAKR,IADf,iBAEGe,YAElB,aAAMJ,CAAQC,GACZ,MAAMtC,EAAO,gBAAgBK,mBAAmBiC,KAEhD,aADuBJ,EAAKR,IAAmC1B,IAC/C0C,UAClB,EAEJ,CFGuBC,CAA0BT,EAC/C,CAOA,eAAOU,CAASV,GACd,OAAO,IAAIF,EAAWE,EACxB,CAMA,WAAOvB,CAAKtB,GACV,OAAOwD,EAAYxD,EACrB,EAgBF,SAASwD,EAAYxD,GACnB,MAAMC,QAAEA,EAAUyC,EAAQxC,OAAEA,EAAMC,SAAEA,EAAUC,MAAOC,GAAcL,EAE7D6C,EAAO9C,EAAiB,CAC5BE,UACAC,SACAC,WACAC,MAAOC,GAAcE,WAAWH,QAGlC,OAAOuC,EAAWY,SAASV,EAC7B,gDApBM,SAA2B7C,GAC/B,OAAOwD,EAAYxD,EACrB"}
package/package.json CHANGED
@@ -1,33 +1,10 @@
1
1
  {
2
2
  "name": "@jaaq/jaaq-sdk-js",
3
- "version": "0.0.1",
3
+ "version": "1.0.0-dev-b6088e1-20251204",
4
4
  "description": "Official JavaScript SDK for JAAQ API",
5
5
  "main": "./dist/index.cjs",
6
6
  "module": "./dist/index.mjs",
7
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
8
  "exports": {
32
9
  ".": {
33
10
  "types": "./dist/index.d.ts",
@@ -47,16 +24,15 @@
47
24
  "license": "ISC",
48
25
  "repository": {
49
26
  "type": "git",
50
- "url": "https://github.com/jaaq-eng/jaaq-sdk-js.git"
27
+ "url": "git+https://github.com/jaaq-eng/jaaq-sdk-js.git"
51
28
  },
52
29
  "bugs": {
53
30
  "url": "https://github.com/jaaq-eng/jaaq-sdk-js/issues"
54
31
  },
55
32
  "homepage": "https://github.com/jaaq-eng/jaaq-sdk-js#readme",
56
33
  "publishConfig": {
57
- "access": "public"
34
+ "access": "restricted"
58
35
  },
59
- "packageManager": "pnpm@10.17.1",
60
36
  "lint-staged": {
61
37
  "*.{ts,tsx,js}": [
62
38
  "eslint --fix --max-warnings=0"
@@ -83,6 +59,7 @@
83
59
  "@types/node": "^24.10.0",
84
60
  "@typescript-eslint/eslint-plugin": "^8.46.3",
85
61
  "@typescript-eslint/parser": "^8.46.3",
62
+ "@vitest/coverage-v8": "^4.0.8",
86
63
  "eslint": "^9.39.1",
87
64
  "eslint-config-prettier": "^10.1.8",
88
65
  "globals": "^16.5.0",
@@ -93,10 +70,31 @@
93
70
  "prettier": "^3.6.2",
94
71
  "rollup": "^4.53.2",
95
72
  "rollup-plugin-dts": "^6.2.3",
73
+ "rollup-plugin-tsconfig-paths": "^1.5.2",
96
74
  "tslib": "^2.8.1",
97
75
  "typescript": "^5.9.3",
98
- "vitest": "^4.0.8",
99
- "@vitest/coverage-v8": "^4.0.8",
100
- "rollup-plugin-tsconfig-paths": "^1.5.2"
76
+ "vitest": "^4.0.8"
77
+ },
78
+ "scripts": {
79
+ "build": "rollup -c",
80
+ "dev": "dotenvx run -f .env.development -- rollup -c --watch",
81
+ "build:dev": "dotenvx run -f .env.development -- rollup -c",
82
+ "build:staging": "dotenvx run -f .env.staging -- rollup -c",
83
+ "build:prod": "dotenvx run -f .env.production -- rollup -c",
84
+ "test": "vitest run --exclude=tests/build",
85
+ "test:watch": "vitest --exclude=tests/build",
86
+ "test:coverage": "vitest run --coverage --exclude=tests/build",
87
+ "test:coverage:watch": "vitest --coverage --exclude=tests/build",
88
+ "test:smoke:dev": "dotenvx run -f .env.development -- vitest run tests/build",
89
+ "test:smoke:staging": "dotenvx run -f .env.staging -- vitest run tests/build",
90
+ "test:smoke:prod": "dotenvx run -f .env.production -- vitest run tests/build",
91
+ "test:smoke:ci": "vitest run tests/build",
92
+ "check-paths-in-bundle": "grep -R -nE --exclude='*.map' '@core/|@resources/' dist || echo 'OK no aliases found'",
93
+ "openapi:gen": "openapi-typescript ./openapi.json -o ./src/gen/openapi.ts",
94
+ "audit:moderate": "pnpm audit --audit-level=moderate",
95
+ "lint": "eslint .",
96
+ "lint:fix": "eslint . --fix",
97
+ "format": "prettier --write .",
98
+ "format:check": "prettier --check ."
101
99
  }
102
- }
100
+ }