@ysk-kit/create-app 1.0.0

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/dist/thin.js ADDED
@@ -0,0 +1,423 @@
1
+ import { existsSync, readdirSync, readFileSync, rmSync, statSync, writeFileSync } from 'node:fs';
2
+ import { join } from 'node:path';
3
+ const dropImportsMentioning = (src, needles) => {
4
+ const lines = src.split('\n');
5
+ const out = [];
6
+ let i = 0;
7
+ while (i < lines.length) {
8
+ const line = lines[i] ?? '';
9
+ if (line.startsWith('import ')) {
10
+ let block = line;
11
+ let j = i;
12
+ while (!block.includes(' from ') && j + 1 < lines.length) {
13
+ j += 1;
14
+ block += `\n${lines[j]}`;
15
+ }
16
+ if (needles.some((needle) => block.includes(needle))) {
17
+ i = j + 1;
18
+ continue;
19
+ }
20
+ out.push(...block.split('\n'));
21
+ i = j + 1;
22
+ continue;
23
+ }
24
+ out.push(line);
25
+ i += 1;
26
+ }
27
+ return out.join('\n');
28
+ };
29
+ const dropLinesContaining = (src, needles) => src
30
+ .split('\n')
31
+ .filter((line) => !needles.some((needle) => line.includes(needle)))
32
+ .join('\n');
33
+ const dropBalancedFrom = (src, startNeedle) => {
34
+ const start = src.indexOf(startNeedle);
35
+ if (start < 0)
36
+ return src;
37
+ const brace = src.indexOf('{', start);
38
+ if (brace < 0)
39
+ return src;
40
+ let depth = 0;
41
+ for (let i = brace; i < src.length; i += 1) {
42
+ const ch = src[i];
43
+ if (ch === '{')
44
+ depth += 1;
45
+ if (ch === '}') {
46
+ depth -= 1;
47
+ if (depth === 0) {
48
+ const from = src.lastIndexOf('\n', start - 1) + 1;
49
+ let end = i + 1;
50
+ const trailing = src.slice(end).match(/^[ \t]*[,)]*[ \t]*;?[ \t]*\n(?:[ \t]*[),;]+\n)?/);
51
+ if (trailing)
52
+ end += trailing[0].length;
53
+ else if (src[end] === ';') {
54
+ end += 1;
55
+ if (src[end] === '\n')
56
+ end += 1;
57
+ }
58
+ return `${src.slice(0, from)}${src.slice(end)}`;
59
+ }
60
+ }
61
+ }
62
+ return src;
63
+ };
64
+ const dropPrismaBlock = (schema, kind, name) => {
65
+ const startNeedle = `${kind} ${name} {`;
66
+ const start = schema.indexOf(startNeedle);
67
+ if (start < 0)
68
+ return schema;
69
+ let depth = 0;
70
+ for (let i = start + startNeedle.length - 1; i < schema.length; i += 1) {
71
+ if (schema[i] === '{')
72
+ depth += 1;
73
+ if (schema[i] === '}') {
74
+ depth -= 1;
75
+ if (depth === 0) {
76
+ let end = i + 1;
77
+ while (schema[end] === '\n')
78
+ end += 1;
79
+ const from = schema.lastIndexOf('\n', start - 1) + 1;
80
+ return `${schema.slice(0, from)}${schema.slice(end)}`;
81
+ }
82
+ }
83
+ }
84
+ return schema;
85
+ };
86
+ const rmIfExists = (path) => {
87
+ rmSync(path, { recursive: true, force: true });
88
+ };
89
+ const patchIfExists = (path, transform) => {
90
+ if (!existsSync(path) || statSync(path).isDirectory())
91
+ return;
92
+ const before = readFileSync(path, 'utf8');
93
+ const after = transform(before).replace(/\n{3,}/g, '\n\n');
94
+ if (after !== before)
95
+ writeFileSync(path, after.endsWith('\n') ? after : `${after}\n`);
96
+ };
97
+ const dropCallFrom = (src, callStart, containing) => {
98
+ const at = src.indexOf(containing);
99
+ if (at < 0)
100
+ return src;
101
+ const start = src.lastIndexOf(callStart, at);
102
+ if (start < 0)
103
+ return src;
104
+ const open = src.indexOf('(', start);
105
+ if (open < 0)
106
+ return src;
107
+ let depth = 0;
108
+ for (let i = open; i < src.length; i += 1) {
109
+ if (src[i] === '(')
110
+ depth += 1;
111
+ if (src[i] === ')') {
112
+ depth -= 1;
113
+ if (depth === 0) {
114
+ const from = src.lastIndexOf('\n', start - 1) + 1;
115
+ let end = i + 1;
116
+ if (src[end] === ';')
117
+ end += 1;
118
+ if (src[end] === '\n')
119
+ end += 1;
120
+ return `${src.slice(0, from)}${src.slice(end)}`;
121
+ }
122
+ }
123
+ }
124
+ return src;
125
+ };
126
+ const dropJsxFrom = (src, startNeedle, endTag) => {
127
+ const start = src.indexOf(startNeedle);
128
+ if (start < 0)
129
+ return src;
130
+ const from = src.lastIndexOf('\n', start - 1) + 1;
131
+ const end = src.indexOf(endTag, start);
132
+ if (end < 0)
133
+ return src;
134
+ let stop = end + endTag.length;
135
+ if (src[stop] === '\n')
136
+ stop += 1;
137
+ return `${src.slice(0, from)}${src.slice(stop)}`;
138
+ };
139
+ const collapseEmptyDirs = (dir) => {
140
+ if (!existsSync(dir) || !statSync(dir).isDirectory())
141
+ return;
142
+ for (const entry of readdirSync(dir))
143
+ collapseEmptyDirs(join(dir, entry));
144
+ if (readdirSync(dir).length === 0)
145
+ rmSync(dir);
146
+ };
147
+ const apiImportNeedles = [
148
+ 'modules/llm',
149
+ 'modules/billing',
150
+ 'modules/organizations',
151
+ 'modules/devices',
152
+ '@ysk-kit/llm',
153
+ '@ysk-kit/push',
154
+ ];
155
+ const dropNamedSpecifiers = (src, names) => src.replace(/import(\s+type)?\s*\{([^}]+)\}\s*from\s*(['"][^'"]+['"])/g, (full, typeKw, list, from) => {
156
+ const kept = list
157
+ .split(',')
158
+ .map((item) => item.trim())
159
+ .filter(Boolean)
160
+ .filter((item) => {
161
+ const ident = item
162
+ .replace(/^type\s+/, '')
163
+ .split(/\s+as\s+/)
164
+ .pop()
165
+ ?.trim();
166
+ return ident ? !names.includes(ident) : true;
167
+ });
168
+ if (kept.length ===
169
+ list
170
+ .split(',')
171
+ .map((item) => item.trim())
172
+ .filter(Boolean).length) {
173
+ return full;
174
+ }
175
+ if (kept.length === 0)
176
+ return '';
177
+ return `import${typeKw ?? ''} { ${kept.join(', ')} } from ${from}`;
178
+ });
179
+ const apiLineNeedles = [
180
+ 'registerLlmRoutes',
181
+ 'registerDeviceRoutes',
182
+ 'registerOrganizationRoutes',
183
+ 'registerBillingRoutes',
184
+ 'llmHandlers',
185
+ 'deviceHandlers',
186
+ 'organizationHandlers',
187
+ 'billingHandlers',
188
+ 'appContract.llm',
189
+ 'appContract.devices',
190
+ 'appContract.organizations',
191
+ 'appContract.billing',
192
+ 'llmService',
193
+ 'deviceService',
194
+ 'organizationService',
195
+ 'billingService',
196
+ 'LlmService',
197
+ 'DeviceService',
198
+ 'OrganizationService',
199
+ 'BillingService',
200
+ 'ILlmPort',
201
+ 'IPushPort',
202
+ 'IDeviceRepository',
203
+ 'createLlmFromEnv',
204
+ 'createLlmService',
205
+ 'createPrismaLlmUsageRepository',
206
+ 'createPushFromEnv',
207
+ 'createDeviceService',
208
+ 'createPrismaDeviceRepository',
209
+ 'createOrganizationService',
210
+ 'createPrismaOrganizationRepository',
211
+ 'createBillingService',
212
+ 'createBillingFromEnv',
213
+ 'createLogBilling',
214
+ 'createPrismaSubscriptionRepository',
215
+ 'createFakeLlm',
216
+ 'createLogPush',
217
+ 'createMemoryLlmUsageRepository',
218
+ 'createMemoryDeviceRepository',
219
+ 'createMemoryOrganizationRepository',
220
+ 'createMemorySubscriptionRepository',
221
+ 'composition.llmService',
222
+ 'composition.deviceService',
223
+ 'composition.organizationService',
224
+ 'composition.billingService',
225
+ 'composition.devices',
226
+ 'composition.push',
227
+ 'composition.llm',
228
+ ' llm,',
229
+ ' devices,',
230
+ ' push,',
231
+ ];
232
+ export const applyThinPreset = (dest) => {
233
+ for (const rel of [
234
+ 'apps/api/src/modules/llm',
235
+ 'apps/api/src/modules/billing',
236
+ 'apps/api/src/modules/organizations',
237
+ 'apps/api/src/modules/devices',
238
+ 'packages/contracts/src/api/llm.ts',
239
+ 'packages/contracts/src/api/billing.ts',
240
+ 'packages/contracts/src/api/organizations.ts',
241
+ 'packages/contracts/src/api/devices.ts',
242
+ 'packages/sdk/src/resources/llm.ts',
243
+ 'packages/sdk/src/resources/billing.ts',
244
+ 'packages/sdk/src/resources/organizations.ts',
245
+ 'packages/sdk/src/resources/devices.ts',
246
+ 'packages/sdk/src/optional-resources.test.ts',
247
+ 'packages/web-sdk/src/llm-hooks.ts',
248
+ 'packages/web-sdk/src/billing-hooks.ts',
249
+ 'packages/web-sdk/src/organizations-hooks.ts',
250
+ 'apps/web/src/features/llm',
251
+ 'apps/web/src/features/orgs',
252
+ ]) {
253
+ rmIfExists(join(dest, rel));
254
+ }
255
+ patchIfExists(join(dest, 'apps/api/prisma/schema.prisma'), (src) => {
256
+ let next = src;
257
+ next = dropPrismaBlock(next, 'enum', 'OrgRole');
258
+ for (const name of [
259
+ 'Device',
260
+ 'LlmUsage',
261
+ 'Organization',
262
+ 'Membership',
263
+ 'Subscription',
264
+ 'OrgInvite',
265
+ ]) {
266
+ next = dropPrismaBlock(next, 'model', name);
267
+ }
268
+ return dropLinesContaining(next, ['llmUsages', 'devices Device[]', 'memberships']);
269
+ });
270
+ const stripApiFile = (src) => {
271
+ let next = dropImportsMentioning(src, apiImportNeedles);
272
+ next = dropBalancedFrom(next, 'if (input.stripeWebhookSecret)');
273
+ next = dropCallFrom(next, 'app.get', "'/v1/billing/invoices/:id/pdf'");
274
+ next = dropBalancedFrom(next, "'/v1/billing/invoices/:id/pdf'");
275
+ next = dropBalancedFrom(next, "app.post('/v1/llm/stream'");
276
+ next = dropBalancedFrom(next, 'const llmService = createLlmService');
277
+ next = dropBalancedFrom(next, 'llmService: createLlmService');
278
+ next = dropBalancedFrom(next, 'organizationService: createOrganizationService');
279
+ next = dropBalancedFrom(next, 'billingService: createBillingService');
280
+ next = dropBalancedFrom(next, 'llm: llmResource');
281
+ next = dropLinesContaining(next, apiLineNeedles);
282
+ next = dropNamedSpecifiers(next, [
283
+ 'requireAuth',
284
+ 'requirePermission',
285
+ 'claimsHasPermission',
286
+ 'LlmCompleteCommandSchema',
287
+ ]);
288
+ next = next.replace(/^\s*stripeWebhookSecret\?: string;\n/m, '');
289
+ next = next.replace(/\n\s*\.\.\.\(composition\.env\.STRIPE_WEBHOOK_SECRET\n\s*\? \{ stripeWebhookSecret: composition\.env\.STRIPE_WEBHOOK_SECRET \}\n\s*: \{\}\),/, '');
290
+ return next;
291
+ };
292
+ for (const rel of [
293
+ 'apps/api/src/app.ts',
294
+ 'apps/api/src/app-fastify.ts',
295
+ 'apps/api/src/composition.ts',
296
+ 'apps/api/src/main.ts',
297
+ 'apps/api/src/worker.ts',
298
+ ]) {
299
+ patchIfExists(join(dest, rel), stripApiFile);
300
+ }
301
+ patchIfExists(join(dest, 'apps/api/src/create-memory-input.ts'), (src) => {
302
+ let next = stripApiFile(src);
303
+ next = next.replace('return { input, otpSink, mail, jobs, realtime, usage, push, users, sessions, orgs };', 'return { input, otpSink, mail, jobs, realtime, users, sessions };');
304
+ return next;
305
+ });
306
+ // apiKeyService block is required — stripApiFile may have dropped it via createApiKeyService
307
+ // in apiLineNeedles. Do not include createApiKeyService in needles.
308
+ patchIfExists(join(dest, 'packages/contracts/src/api/index.ts'), (src) => {
309
+ let next = dropImportsMentioning(src, ['./llm', './billing', './devices', './organizations']);
310
+ next = dropLinesContaining(next, [
311
+ 'llmContract',
312
+ 'billingContract',
313
+ 'devicesContract',
314
+ 'organizationsContract',
315
+ "from './llm'",
316
+ "from './billing'",
317
+ "from './devices'",
318
+ "from './organizations'",
319
+ ]);
320
+ return next;
321
+ });
322
+ patchIfExists(join(dest, 'packages/sdk/src/index.ts'), (src) => {
323
+ let next = dropImportsMentioning(src, [
324
+ './resources/llm',
325
+ './resources/billing',
326
+ './resources/devices',
327
+ './resources/organizations',
328
+ ]);
329
+ next = dropBalancedFrom(next, 'llm: llmResource');
330
+ return dropLinesContaining(next, [
331
+ 'billingResource',
332
+ 'devicesResource',
333
+ 'llmResource',
334
+ 'organizationsResource',
335
+ 'billing:',
336
+ 'devices:',
337
+ 'organizations:',
338
+ 'llm:',
339
+ ]);
340
+ });
341
+ patchIfExists(join(dest, 'packages/web-sdk/src/index.ts'), (src) => {
342
+ let next = dropLinesContaining(src, [
343
+ './billing-hooks',
344
+ './llm-hooks',
345
+ './organizations-hooks',
346
+ 'createBillingHooks',
347
+ 'createLlmHooks',
348
+ 'createOrganizationHooks',
349
+ 'billingQueryKey',
350
+ 'organizationQueryKey',
351
+ 'organizationsQueryKey',
352
+ ]);
353
+ next = next.replace(/export \{\s*\n+/g, '');
354
+ return next;
355
+ });
356
+ patchIfExists(join(dest, 'apps/web/src/router.tsx'), (src) => {
357
+ let next = dropImportsMentioning(src, [
358
+ './features/llm/llm-page',
359
+ './features/orgs/billing-page',
360
+ './features/orgs/invite-page',
361
+ './features/orgs/org-detail-page',
362
+ './features/orgs/orgs-page',
363
+ ]);
364
+ next = dropBalancedFrom(next, 'const llmRoute = createRoute');
365
+ next = dropBalancedFrom(next, 'const orgsRoute = createRoute');
366
+ next = dropBalancedFrom(next, 'const orgDetailRoute = createRoute');
367
+ next = dropBalancedFrom(next, 'const orgBillingRoute = createRoute');
368
+ next = dropBalancedFrom(next, 'const inviteRoute = createRoute');
369
+ next = dropJsxFrom(next, '<Link to="/llm"', '</Link>');
370
+ next = dropJsxFrom(next, '<Link to="/orgs"', '</Link>');
371
+ next = dropLinesContaining(next, [
372
+ 'to="/llm"',
373
+ 'to="/orgs"',
374
+ 'llmRoute',
375
+ 'orgsRoute',
376
+ 'orgDetailRoute',
377
+ 'orgBillingRoute',
378
+ 'inviteRoute',
379
+ 'LlmPage',
380
+ 'OrgsPage',
381
+ 'OrgDetailPage',
382
+ 'BillingPage',
383
+ 'InvitePage',
384
+ ]);
385
+ return next;
386
+ });
387
+ patchIfExists(join(dest, 'apps/mobile/src/adapters/push.ts'), (src) => src.replace('await opts.api.devices.register({ token, platform: opts.platform });', '// ysk add push restores client.devices'));
388
+ for (const rel of [
389
+ 'apps/mobile/src/screens/orgs-screen.tsx',
390
+ 'apps/mobile/src/screens/org-detail-screen.tsx',
391
+ 'apps/mobile/src/screens/invite-screen.tsx',
392
+ ]) {
393
+ rmIfExists(join(dest, rel));
394
+ }
395
+ patchIfExists(join(dest, 'apps/mobile/src/app.tsx'), (src) => {
396
+ let next = dropImportsMentioning(src, [
397
+ './screens/orgs-screen',
398
+ './screens/org-detail-screen',
399
+ './screens/invite-screen',
400
+ ]);
401
+ next = next.replace("type Screen = 'login' | 'home' | 'inbox' | 'orgs' | 'org-detail' | 'invite';", "type Screen = 'login' | 'home' | 'inbox';");
402
+ next = dropJsxFrom(next, "{screen === 'orgs' ?", ') : null}');
403
+ next = dropJsxFrom(next, "{screen === 'org-detail'", ') : null}');
404
+ next = dropJsxFrom(next, "{screen === 'invite' ?", ') : null}');
405
+ next = dropLinesContaining(next, ['InviteScreen', "screen === 'invite'"]);
406
+ next = next.replace(`{screen === 'login' ? (
407
+ <LoginScreen
408
+ onSignedIn={() => setScreen('home')}
409
+ onAcceptInvite={() => setScreen('invite')}
410
+ />
411
+ ) : null}`, `{screen === 'login' ? <LoginScreen onSignedIn={() => setScreen('home')} /> : null}`);
412
+ next = next.replace(`<HomeScreen
413
+ onInbox={() => setScreen('inbox')}
414
+ onOrgs={() => setScreen('orgs')}
415
+ onLogout={() => setScreen('login')}
416
+ />`, `<HomeScreen onInbox={() => setScreen('inbox')} onLogout={() => setScreen('login')} />`);
417
+ return dropLinesContaining(next, ['organizationId']);
418
+ });
419
+ patchIfExists(join(dest, 'apps/mobile/src/screens/home-screen.tsx'), (src) => dropLinesContaining(src, ['onOrgs', 'Organizations']));
420
+ patchIfExists(join(dest, 'apps/mobile/src/screens/login-screen.tsx'), (src) => dropLinesContaining(src, ['onAcceptInvite', 'Accept invite']));
421
+ collapseEmptyDirs(join(dest, 'apps/web/src/features'));
422
+ };
423
+ //# sourceMappingURL=thin.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"thin.js","sourceRoot":"","sources":["../src/thin.ts"],"names":[],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,36 @@
1
+ {
2
+ "name": "@ysk-kit/create-app",
3
+ "version": "1.0.0",
4
+ "type": "module",
5
+ "bin": {
6
+ "create-ysk-app": "./dist/index.js"
7
+ },
8
+ "devDependencies": {
9
+ "@types/node": "^24.5.2",
10
+ "tsx": "^4.19.3",
11
+ "typescript": "^6.0.3",
12
+ "vitest": "^5.0.2"
13
+ },
14
+ "files": [
15
+ "dist",
16
+ "templates"
17
+ ],
18
+ "publishConfig": {
19
+ "registry": "https://registry.npmjs.org",
20
+ "access": "public"
21
+ },
22
+ "scripts": {
23
+ "start": "tsx src/index.ts",
24
+ "typecheck": "tsc --noEmit -p tsconfig.json",
25
+ "test": "vitest run --passWithNoTests",
26
+ "build": "tsc -p tsconfig.build.json"
27
+ },
28
+ "main": "./dist/index.js",
29
+ "types": "./dist/index.d.ts",
30
+ "exports": {
31
+ ".": {
32
+ "types": "./dist/index.d.ts",
33
+ "import": "./dist/index.js"
34
+ }
35
+ }
36
+ }
@@ -0,0 +1,15 @@
1
+ {
2
+ "name": "ysk/__NAME__",
3
+ "description": "YSK Kit PHP bridge client",
4
+ "type": "library",
5
+ "require": {
6
+ "php": ">=8.2",
7
+ "ext-curl": "*",
8
+ "ext-json": "*"
9
+ },
10
+ "autoload": {
11
+ "psr-4": {
12
+ "Ysk\\": "src/"
13
+ }
14
+ }
15
+ }
@@ -0,0 +1,79 @@
1
+ <?php
2
+
3
+ declare(strict_types=1);
4
+
5
+ namespace Ysk;
6
+
7
+ final class YskApiError extends \RuntimeException
8
+ {
9
+ public function __construct(public readonly string $errorCode, string $message)
10
+ {
11
+ parent::__construct($message);
12
+ }
13
+ }
14
+
15
+ final class YskClient
16
+ {
17
+ public function __construct(
18
+ private readonly string $baseUrl,
19
+ private readonly ?string $token = null,
20
+ private readonly string $platform = 'web',
21
+ ) {
22
+ }
23
+
24
+ public function health(): mixed
25
+ {
26
+ return $this->request('GET', '/health');
27
+ }
28
+
29
+ public function login(string $email, string $password): mixed
30
+ {
31
+ return $this->request('POST', '/v1/auth/login', [
32
+ 'email' => $email,
33
+ 'password' => $password,
34
+ ]);
35
+ }
36
+
37
+ public function request(string $method, string $path, mixed $body = null, ?string $token = null): mixed
38
+ {
39
+ $ch = curl_init(rtrim($this->baseUrl, '/') . $path);
40
+ if ($ch === false) {
41
+ throw new \RuntimeException('curl_init failed');
42
+ }
43
+ $headers = [
44
+ 'Accept: application/json',
45
+ 'x-ysk-platform: ' . $this->platform,
46
+ ];
47
+ $bearer = $token ?? $this->token;
48
+ if (is_string($bearer) && $bearer !== '') {
49
+ $headers[] = 'Authorization: Bearer ' . $bearer;
50
+ }
51
+ $opts = [
52
+ CURLOPT_RETURNTRANSFER => true,
53
+ CURLOPT_CUSTOMREQUEST => $method,
54
+ CURLOPT_HTTPHEADER => $headers,
55
+ ];
56
+ if ($body !== null) {
57
+ $headers[] = 'Content-Type: application/json';
58
+ $opts[CURLOPT_HTTPHEADER] = $headers;
59
+ $opts[CURLOPT_POSTFIELDS] = json_encode($body, JSON_THROW_ON_ERROR);
60
+ }
61
+ curl_setopt_array($ch, $opts);
62
+ $raw = curl_exec($ch);
63
+ curl_close($ch);
64
+ if (!is_string($raw)) {
65
+ throw new \RuntimeException('empty response');
66
+ }
67
+ $json = json_decode($raw, true, 512, JSON_THROW_ON_ERROR);
68
+ if (!is_array($json)) {
69
+ throw new \RuntimeException('invalid json');
70
+ }
71
+ if (($json['ok'] ?? false) === true) {
72
+ return $json['data'] ?? null;
73
+ }
74
+ $error = is_array($json['error'] ?? null) ? $json['error'] : [];
75
+ $code = is_string($error['code'] ?? null) ? $error['code'] : 'INTERNAL';
76
+ $message = is_string($error['message'] ?? null) ? $error['message'] : 'error';
77
+ throw new YskApiError($code, $message);
78
+ }
79
+ }
@@ -0,0 +1,9 @@
1
+ {
2
+ "name": "__NAME__-ts-client",
3
+ "version": "0.1.0",
4
+ "type": "module",
5
+ "main": "./src/client.ts",
6
+ "scripts": {
7
+ "typecheck": "tsc --noEmit --esModuleInterop --module nodenext --target es2022 src/client.ts"
8
+ }
9
+ }
@@ -0,0 +1,60 @@
1
+ export type EnvelopeOk<T> = { ok: true; data: T };
2
+ export type EnvelopeErr = { ok: false; error: { code: string; message: string } };
3
+ export type Envelope<T> = EnvelopeOk<T> | EnvelopeErr;
4
+
5
+ export class YskApiError extends Error {
6
+ readonly code: string;
7
+ constructor(code: string, message: string) {
8
+ super(message);
9
+ this.code = code;
10
+ this.name = 'YskApiError';
11
+ }
12
+ }
13
+
14
+ export const unwrapEnvelope = <T>(json: Envelope<T>): T => {
15
+ if (json.ok) return json.data;
16
+ throw new YskApiError(json.error.code, json.error.message);
17
+ };
18
+
19
+ export const createClient = (opts: {
20
+ baseUrl: string;
21
+ getToken?: () => string | undefined;
22
+ platform?: string;
23
+ fetchImpl?: typeof fetch;
24
+ }) => {
25
+ const baseUrl = opts.baseUrl.replace(/\/$/, '');
26
+ const fetchImpl = opts.fetchImpl ?? fetch;
27
+ const platform = opts.platform ?? 'web';
28
+
29
+ const request = async <T>(
30
+ method: string,
31
+ path: string,
32
+ body?: unknown,
33
+ token?: string,
34
+ ): Promise<T> => {
35
+ const headers: Record<string, string> = {
36
+ accept: 'application/json',
37
+ 'x-ysk-platform': platform,
38
+ };
39
+ const bearer = token ?? opts.getToken?.();
40
+ if (bearer) headers.authorization = `Bearer ${bearer}`;
41
+ const init: RequestInit = { method, headers };
42
+ if (body !== undefined) {
43
+ headers['content-type'] = 'application/json';
44
+ init.body = JSON.stringify(body);
45
+ }
46
+ const res = await fetchImpl(`${baseUrl}${path}`, init);
47
+ const json = (await res.json()) as Envelope<T>;
48
+ return unwrapEnvelope(json);
49
+ };
50
+
51
+ return {
52
+ request,
53
+ health: () => request<{ status: string }>('GET', '/health'),
54
+ login: (email: string, password: string) =>
55
+ request<{ accessToken: string; refreshToken: string }>('POST', '/v1/auth/login', {
56
+ email,
57
+ password,
58
+ }),
59
+ };
60
+ };