@toa.io/origin 0.0.1 → 0.0.3

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,3 +1,51 @@
1
1
  # Toa Origin
2
2
 
3
3
  [Exposition](https://github.com/toa-io/toa/tree/dev/extensions/exposition) Client
4
+
5
+ ## `new Resource<T>(path: string, options?: RequestInit)`
6
+
7
+ ### Parameters
8
+
9
+ - `path` — Base API path (e.g. '/favorites/').
10
+ - `options` — Options passed to `fetch`.
11
+ - `T` — Type of the resource representation.
12
+
13
+ Each HTTP verb (get, post, patch, put, delete) provides the following response handling modes:
14
+
15
+ - `.value()`: Expects a single JSON object response `T`.
16
+ - `.array()`: Expects a JSON array response `T[]`.
17
+ - `.none()`: Expects no response body `void`.
18
+
19
+ ```typescript
20
+ (resource.<method>).<mode>(
21
+ segments?: string[], // Optional URL path segments, relative to the base path
22
+ options?: RequestInit // fetch-compatible request options
23
+ ): Promise<...>
24
+ ```
25
+
26
+ ## Usage
27
+
28
+ ```typescript
29
+ import { Resource } from '$origin'
30
+ import type { Favorite } from './Favorite'
31
+
32
+ // Initialize a resource client
33
+ const favorites = new Resource<Favorite>('/favorites/', { credentials: 'include' })
34
+
35
+ // GET /favorites/:identity/
36
+ export async function get(identity: string): Promise<Favorite[] | Error> {
37
+ return favorites.get.array([identity])
38
+ }
39
+
40
+ // POST /favorites/:identity/ with typed body
41
+ type Post = Omit<Favorite, 'id'>
42
+
43
+ export async function post(identity: string, body: Post): Promise<Favorite | Error> {
44
+ return favorites.post.value([identity], { body })
45
+ }
46
+
47
+ // DELETE /favorites/:identity/:id/
48
+ export async function del(identity: string, id: string): Promise<Favorite | Error> {
49
+ return favorites.delete.value([identity, id])
50
+ }
51
+ ```
package/eslint.config.js CHANGED
@@ -15,19 +15,24 @@ module.exports = [
15
15
  },
16
16
  {
17
17
  rules: {
18
+ 'no-void': ['error', { allowAsStatement: true }],
18
19
  curly: ['error', 'multi'],
19
- '@stylistic/space-before-function-paren': ['error', 'never'],
20
- 'padding-line-between-statements': [
20
+ '@stylistic/space-before-function-paren': ['error', {
21
+ asyncArrow: 'always',
22
+ named: 'never',
23
+ anonymous: 'never'
24
+ }],
25
+ '@stylistic/padding-line-between-statements': [
21
26
  'error',
22
27
  {
23
28
  blankLine: 'always',
24
- prev: ['block-like', 'if'],
29
+ prev: ['block-like', 'if', 'multiline-expression'],
25
30
  next: '*'
26
31
  },
27
32
  {
28
33
  blankLine: 'always',
29
34
  prev: '*',
30
- next: ['block-like', 'if']
35
+ next: ['block-like', 'if', 'multiline-expression']
31
36
  },
32
37
  {
33
38
  blankLine: 'always',
@@ -56,7 +61,7 @@ module.exports = [
56
61
  }
57
62
  ],
58
63
  'import/order': ['error', {
59
- groups: ['builtin', 'external', 'internal', 'parent', 'sibling', 'index', 'type'],
64
+ groups: ['builtin', 'external', 'internal', 'unknown', 'parent', 'sibling', 'index', 'type'],
60
65
  alphabetize: {
61
66
  order: 'asc'
62
67
  }
@@ -66,7 +71,6 @@ module.exports = [
66
71
  {
67
72
  files: ['**/*.ts'],
68
73
  rules: {
69
- 'no-void': ['error', { allowAsStatement: true }],
70
74
  '@typescript-eslint/consistent-type-imports': 'error'
71
75
  }
72
76
  },
package/package.json CHANGED
@@ -1,18 +1,15 @@
1
1
  {
2
2
  "name": "@toa.io/origin",
3
- "version": "0.0.1",
3
+ "version": "0.0.3",
4
4
  "publishConfig": {
5
5
  "access": "public"
6
6
  },
7
7
  "description": "Toa Origin",
8
- "homepage": "git@github.com:toa-io/origin.git#readme",
9
8
  "repository": {
10
9
  "type": "git",
11
- "url": "git@github.com:toa-io/origin.git"
12
- },
13
- "bugs": {
14
- "url": "git@github.com:toa-io/origin.git/issues"
10
+ "url": "git+ssh://git@github.com/toa-io/origin.git"
15
11
  },
12
+ "homepage": "https://github.com/toa-io/origin#readme",
16
13
  "main": "transpiled/index.js",
17
14
  "types": "transpiled/index.d.ts",
18
15
  "peerDependencies": {
@@ -20,14 +17,15 @@
20
17
  },
21
18
  "devDependencies": {
22
19
  "@types/node": "^22.15.17",
23
- "eslint": "^9.26.0",
20
+ "eslint": "^9.27.0",
24
21
  "eslint-plugin-import": "^2.31.0",
25
22
  "husky": "^9.1.7",
26
23
  "neostandard": "^0.12.1"
27
24
  },
28
25
  "scripts": {
29
26
  "prepare": "husky",
30
- "prepublishOnly": "rm -rf transpiled && tsc",
27
+ "prepublishOnly": "npm run transpile",
28
+ "transpile": "rm -rf transpiled tsconfig.tsbuildinfo && tsc",
31
29
  "lint": "eslint .",
32
30
  "format": "eslint . --fix",
33
31
  "test": "node --test && npm run lint"
package/source/Method.ts CHANGED
@@ -60,7 +60,7 @@ export class Method<Entity = never> {
60
60
  const entry = chunk.value as OctetsEntry
61
61
  const emitter = mitt<Events>()
62
62
 
63
- void (async() => {
63
+ void (async () => {
64
64
  for await (const part of generator) {
65
65
  const workflow = part as WorkflowStep
66
66
 
package/source/events.ts CHANGED
@@ -14,7 +14,7 @@ export interface Events extends Record<string | symbol, unknown> {
14
14
 
15
15
  response: {
16
16
  id: string
17
- status: number
17
+ response: Response
18
18
  duration: number
19
19
  }
20
20
  }
package/source/request.ts CHANGED
@@ -55,12 +55,13 @@ export async function request<T = unknown>(
55
55
  const id =
56
56
  typeof window !== 'undefined' && (window.crypto.randomUUID?.() ?? Math.random().toString())
57
57
 
58
- if (id) events.emit('request', { id, path, options })
58
+ if (id)
59
+ events.emit('request', { id, path, options })
59
60
 
60
61
  const response = await _fetch(settings.origin + path, options)
61
62
 
62
63
  if (id)
63
- events.emit('response', { id, status: response.status, duration: performance.now() - start })
64
+ events.emit('response', { id, response, duration: performance.now() - start })
64
65
 
65
66
  if (!response.ok) return await fail(response)
66
67
  else return await ok<T>(response)
@@ -0,0 +1,3 @@
1
+ import { Err } from 'error-value';
2
+ export declare class Failure extends Err<number> {
3
+ }
@@ -0,0 +1,8 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.Failure = void 0;
4
+ const error_value_1 = require("error-value");
5
+ class Failure extends error_value_1.Err {
6
+ }
7
+ exports.Failure = Failure;
8
+ //# sourceMappingURL=Failure.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Failure.js","sourceRoot":"","sources":["../source/Failure.ts"],"names":[],"mappings":";;;AAAA,6CAAiC;AAEjC,MAAa,OAAQ,SAAQ,iBAAW;CAAG;AAA3C,0BAA2C"}
@@ -0,0 +1,15 @@
1
+ import { type Emitter } from 'mitt';
2
+ import { type Options } from './request';
3
+ import type { Failure } from './Failure';
4
+ import type { OctetsEntry } from './Octets';
5
+ export declare class Method<Entity = never> {
6
+ private readonly base;
7
+ private readonly options?;
8
+ constructor(base: string, options?: Options);
9
+ none(segments?: string[] | string, options?: Options): Promise<void | Failure>;
10
+ value<T = Entity>(segments?: string[] | string, options?: Options): Promise<T | Failure>;
11
+ array<T = Entity[]>(segments?: string[] | string, options?: Options): Promise<T[] | Failure>;
12
+ multipart<T = Entity>(segments?: string[] | string, options?: Options): Promise<AsyncGenerator<T, void, undefined> | Failure>;
13
+ octets<Events extends Record<string, unknown>>(segments?: string[], options?: Options): Promise<[OctetsEntry, Emitter<Events>] | Failure>;
14
+ private request;
15
+ }
@@ -0,0 +1,78 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.Method = void 0;
7
+ const error_value_1 = require("error-value");
8
+ const mitt_1 = __importDefault(require("mitt"));
9
+ const request_1 = require("./request");
10
+ class Method {
11
+ base;
12
+ options;
13
+ constructor(base, options) {
14
+ this.base = base;
15
+ this.options = options;
16
+ }
17
+ async none(segments, options) {
18
+ return await this.request(segments, options);
19
+ }
20
+ async value(segments, options) {
21
+ return await this.request(segments, options);
22
+ }
23
+ async array(segments, options) {
24
+ return await this.request(segments, options);
25
+ }
26
+ async multipart(segments, options) {
27
+ const generator = await this.request(segments, options);
28
+ if (generator instanceof Error)
29
+ return generator;
30
+ const ack = await generator.next();
31
+ if (JSON.parse(ack.value.body) !== 'ACK')
32
+ throw new Error('No ACK');
33
+ return (async function* () {
34
+ for await (const chunk of generator) {
35
+ const value = JSON.parse(chunk.body);
36
+ if (value === 'FIN')
37
+ return;
38
+ yield value;
39
+ }
40
+ })();
41
+ }
42
+ async octets(segments, options) {
43
+ const generator = await this.multipart(segments, options);
44
+ if (generator instanceof Error)
45
+ return generator;
46
+ const chunk = await generator.next();
47
+ const entry = chunk.value;
48
+ const emitter = (0, mitt_1.default)();
49
+ void (async () => {
50
+ for await (const part of generator) {
51
+ const workflow = part;
52
+ console.debug('octets chunk:', workflow);
53
+ const payload = workflow.error === undefined
54
+ ? workflow.output
55
+ : new error_value_1.Err(workflow.error.code, workflow.error.message);
56
+ emitter.emit(workflow.step, payload);
57
+ }
58
+ emitter.off('*');
59
+ })();
60
+ return [entry, emitter];
61
+ }
62
+ async request(segments, options) {
63
+ const path = toPath(segments);
64
+ return await (0, request_1.request)(`${this.base}${path}`, {
65
+ ...this.options,
66
+ ...options
67
+ });
68
+ }
69
+ }
70
+ exports.Method = Method;
71
+ function toPath(segments) {
72
+ if (segments === undefined)
73
+ return '';
74
+ if (typeof segments === 'string')
75
+ return segments;
76
+ return segments.filter((s) => s !== undefined).join('/') + '/';
77
+ }
78
+ //# sourceMappingURL=Method.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Method.js","sourceRoot":"","sources":["../source/Method.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,14 @@
1
+ export interface OctetsEntry {
2
+ id: string;
3
+ }
4
+ export interface WorkflowStep<K = string, T = unknown> {
5
+ step: K;
6
+ status: 'completed' | 'exception';
7
+ output?: T;
8
+ error: WorkflowError;
9
+ }
10
+ interface WorkflowError {
11
+ code: string;
12
+ message?: string;
13
+ }
14
+ export {};
@@ -0,0 +1,3 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ //# sourceMappingURL=Octets.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Octets.js","sourceRoot":"","sources":["../source/Octets.ts"],"names":[],"mappings":""}
@@ -0,0 +1,10 @@
1
+ import { Method } from './Method';
2
+ import type { Options } from './request';
3
+ export declare class Resource<T> {
4
+ get: Method<T>;
5
+ post: Method<T>;
6
+ patch: Method<T>;
7
+ put: Method<T>;
8
+ delete: Method<never>;
9
+ constructor(base: string, options?: Omit<Options, 'method'>);
10
+ }
@@ -0,0 +1,20 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.Resource = void 0;
4
+ const Method_1 = require("./Method");
5
+ class Resource {
6
+ get;
7
+ post;
8
+ patch;
9
+ put;
10
+ delete;
11
+ constructor(base, options) {
12
+ this.get = new Method_1.Method(base, { method: 'GET', ...options });
13
+ this.post = new Method_1.Method(base, { method: 'POST', ...options });
14
+ this.patch = new Method_1.Method(base, { method: 'PATCH', ...options });
15
+ this.put = new Method_1.Method(base, { method: 'PUT', ...options });
16
+ this.delete = new Method_1.Method(base, { method: 'DELETE', ...options });
17
+ }
18
+ }
19
+ exports.Resource = Resource;
20
+ //# sourceMappingURL=Resource.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Resource.js","sourceRoot":"","sources":["../source/Resource.ts"],"names":[],"mappings":";;;AAAA,qCAAiC;AAGjC,MAAa,QAAQ;IACZ,GAAG,CAAW;IACd,IAAI,CAAW;IACf,KAAK,CAAW;IAChB,GAAG,CAAW;IACd,MAAM,CAAe;IAE5B,YAAmB,IAAY,EAAE,OAAiC;QAChE,IAAI,CAAC,GAAG,GAAG,IAAI,eAAM,CAAI,IAAI,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,GAAG,OAAO,EAAE,CAAC,CAAA;QAC7D,IAAI,CAAC,IAAI,GAAG,IAAI,eAAM,CAAI,IAAI,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,GAAG,OAAO,EAAE,CAAC,CAAA;QAC/D,IAAI,CAAC,KAAK,GAAG,IAAI,eAAM,CAAI,IAAI,EAAE,EAAE,MAAM,EAAE,OAAO,EAAE,GAAG,OAAO,EAAE,CAAC,CAAA;QACjE,IAAI,CAAC,GAAG,GAAG,IAAI,eAAM,CAAI,IAAI,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,GAAG,OAAO,EAAE,CAAC,CAAA;QAC7D,IAAI,CAAC,MAAM,GAAG,IAAI,eAAM,CAAC,IAAI,EAAE,EAAE,MAAM,EAAE,QAAQ,EAAE,GAAG,OAAO,EAAE,CAAC,CAAA;IAClE,CAAC;CACF;AAdD,4BAcC"}
@@ -0,0 +1,15 @@
1
+ import type { Options } from './request';
2
+ export declare const events: import("mitt").Emitter<Events>;
3
+ export interface Events extends Record<string | symbol, unknown> {
4
+ challenge: string;
5
+ request: {
6
+ id: string;
7
+ path: string;
8
+ options: Options;
9
+ };
10
+ response: {
11
+ id: string;
12
+ response: Response;
13
+ duration: number;
14
+ };
15
+ }
@@ -0,0 +1,9 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.events = void 0;
7
+ const mitt_1 = __importDefault(require("mitt"));
8
+ exports.events = (0, mitt_1.default)();
9
+ //# sourceMappingURL=events.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"events.js","sourceRoot":"","sources":["../source/events.ts"],"names":[],"mappings":";;;;;;AAAA,gDAAuB;AAGV,QAAA,MAAM,GAAG,IAAA,cAAI,GAAU,CAAA"}
@@ -0,0 +1,2 @@
1
+ import { Failure } from './Failure';
2
+ export declare function fail(response: Response): Promise<Failure>;
@@ -0,0 +1,13 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.fail = fail;
4
+ const Failure_1 = require("./Failure");
5
+ const events_1 = require("./events");
6
+ async function fail(response) {
7
+ const payload = response.headers.get('content-type') === 'application/json'
8
+ ? await response.json()
9
+ : await response.text();
10
+ events_1.events.emit(response.status, payload);
11
+ return new Failure_1.Failure(response.status);
12
+ }
13
+ //# sourceMappingURL=fail.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fail.js","sourceRoot":"","sources":["../source/fail.ts"],"names":[],"mappings":";;AAGA,oBASC;AAZD,uCAAmC;AACnC,qCAAiC;AAE1B,KAAK,UAAU,IAAI,CAAC,QAAkB;IAC3C,MAAM,OAAO,GACX,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,cAAc,CAAC,KAAK,kBAAkB;QACzD,CAAC,CAAC,MAAM,QAAQ,CAAC,IAAI,EAAE;QACvB,CAAC,CAAC,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAA;IAE3B,eAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;IAErC,OAAO,IAAI,iBAAO,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAA;AACrC,CAAC"}
@@ -0,0 +1,7 @@
1
+ export { Resource } from './Resource';
2
+ export { Method } from './Method';
3
+ export { Failure } from './Failure';
4
+ export { authenticate, request, use, type Options } from './request';
5
+ export { events } from './events';
6
+ export { connect } from './settings';
7
+ export type * from './Octets';
@@ -0,0 +1,18 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.connect = exports.events = exports.use = exports.request = exports.authenticate = exports.Failure = exports.Method = exports.Resource = void 0;
4
+ var Resource_1 = require("./Resource");
5
+ Object.defineProperty(exports, "Resource", { enumerable: true, get: function () { return Resource_1.Resource; } });
6
+ var Method_1 = require("./Method");
7
+ Object.defineProperty(exports, "Method", { enumerable: true, get: function () { return Method_1.Method; } });
8
+ var Failure_1 = require("./Failure");
9
+ Object.defineProperty(exports, "Failure", { enumerable: true, get: function () { return Failure_1.Failure; } });
10
+ var request_1 = require("./request");
11
+ Object.defineProperty(exports, "authenticate", { enumerable: true, get: function () { return request_1.authenticate; } });
12
+ Object.defineProperty(exports, "request", { enumerable: true, get: function () { return request_1.request; } });
13
+ Object.defineProperty(exports, "use", { enumerable: true, get: function () { return request_1.use; } });
14
+ var events_1 = require("./events");
15
+ Object.defineProperty(exports, "events", { enumerable: true, get: function () { return events_1.events; } });
16
+ var settings_1 = require("./settings");
17
+ Object.defineProperty(exports, "connect", { enumerable: true, get: function () { return settings_1.connect; } });
18
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../source/index.ts"],"names":[],"mappings":";;;AAAA,uCAAqC;AAA5B,oGAAA,QAAQ,OAAA;AACjB,mCAAiC;AAAxB,gGAAA,MAAM,OAAA;AACf,qCAAmC;AAA1B,kGAAA,OAAO,OAAA;AAChB,qCAAoE;AAA3D,uGAAA,YAAY,OAAA;AAAE,kGAAA,OAAO,OAAA;AAAE,8FAAA,GAAG,OAAA;AACnC,mCAAiC;AAAxB,gGAAA,MAAM,OAAA;AACf,uCAAoC;AAA3B,mGAAA,OAAO,OAAA"}
@@ -0,0 +1 @@
1
+ export declare function ok<T>(response: Response): Promise<T>;
@@ -0,0 +1,20 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ok = ok;
4
+ const browser_1 = require("meros/browser");
5
+ const events_1 = require("./events");
6
+ async function ok(response) {
7
+ const challenge = response.headers.get('authorization');
8
+ if (challenge !== null)
9
+ events_1.events.emit('challenge', challenge);
10
+ const type = response.headers.get('content-type');
11
+ if (type?.startsWith('multipart/'))
12
+ return (await (0, browser_1.meros)(response));
13
+ else if (type === 'application/json')
14
+ return (await response.json());
15
+ else if (type?.startsWith('text/'))
16
+ return (await response.text());
17
+ else
18
+ return (await response.blob());
19
+ }
20
+ //# sourceMappingURL=ok.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ok.js","sourceRoot":"","sources":["../source/ok.ts"],"names":[],"mappings":";;AAGA,gBAWC;AAdD,2CAAqC;AACrC,qCAAiC;AAE1B,KAAK,UAAU,EAAE,CAAI,QAAkB;IAC5C,MAAM,SAAS,GAAG,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,eAAe,CAAC,CAAA;IAEvD,IAAI,SAAS,KAAK,IAAI;QAAE,eAAM,CAAC,IAAI,CAAC,WAAW,EAAE,SAAS,CAAC,CAAA;IAE3D,MAAM,IAAI,GAAG,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,cAAc,CAAC,CAAA;IAEjD,IAAI,IAAI,EAAE,UAAU,CAAC,YAAY,CAAC;QAAE,OAAO,CAAC,MAAM,IAAA,eAAK,EAAC,QAAQ,CAAC,CAAM,CAAA;SAClE,IAAI,IAAI,KAAK,kBAAkB;QAAE,OAAO,CAAC,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAM,CAAA;SACpE,IAAI,IAAI,EAAE,UAAU,CAAC,OAAO,CAAC;QAAE,OAAO,CAAC,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAM,CAAA;;QAClE,OAAO,CAAC,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAM,CAAA;AAC1C,CAAC"}
@@ -0,0 +1,9 @@
1
+ import type { Failure } from './Failure';
2
+ export declare function authenticate(value: string | null): void;
3
+ export declare function use(fetcher: typeof fetch): void;
4
+ export declare function request<T = unknown>(path: string, options?: Options): Promise<T | Failure>;
5
+ export interface Options extends Omit<RequestInit, 'headers'> {
6
+ duplex?: 'half';
7
+ body?: any;
8
+ headers?: Record<string, string>;
9
+ }
@@ -0,0 +1,55 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.authenticate = authenticate;
4
+ exports.use = use;
5
+ exports.request = request;
6
+ const events_1 = require("./events");
7
+ const fail_1 = require("./fail");
8
+ const ok_1 = require("./ok");
9
+ const settings_1 = require("./settings");
10
+ const delay = settings_1.settings.delay;
11
+ if (delay)
12
+ console.warn(`API delay is enabled (${delay}ms)`);
13
+ let challenge = null;
14
+ function authenticate(value) {
15
+ challenge = value;
16
+ }
17
+ let _fetch = fetch;
18
+ function use(fetcher) {
19
+ _fetch = fetcher;
20
+ }
21
+ async function request(path, options = {}) {
22
+ options.headers ??= {};
23
+ options.headers['accept'] ??= 'application/json';
24
+ if (delay)
25
+ options.headers['sleep'] = Math.round((Math.random() * delay) / 2 + delay / 2).toString();
26
+ const authentication = options.credentials === 'include';
27
+ if (options.body !== undefined)
28
+ if (options.body instanceof File || options.body instanceof ReadableStream) {
29
+ options.method ??= 'POST';
30
+ options.duplex = 'half';
31
+ options.headers['content-type'] ??= 'application/octet-stream';
32
+ }
33
+ else {
34
+ options.body = JSON.stringify(options.body);
35
+ options.headers['content-type'] ??= 'application/json';
36
+ }
37
+ if (authentication && options.headers['authorization'] === undefined) {
38
+ if (challenge === null)
39
+ throw new Error(`Credentials must be set before sending authenticated request ${options.method ?? 'GET'} ${path}`);
40
+ options.headers['authorization'] = challenge;
41
+ delete options.credentials; // no cookies
42
+ }
43
+ const start = performance.now();
44
+ const id = typeof window !== 'undefined' && (window.crypto.randomUUID?.() ?? Math.random().toString());
45
+ if (id)
46
+ events_1.events.emit('request', { id, path, options });
47
+ const response = await _fetch(settings_1.settings.origin + path, options);
48
+ if (id)
49
+ events_1.events.emit('response', { id, response, duration: performance.now() - start });
50
+ if (!response.ok)
51
+ return await (0, fail_1.fail)(response);
52
+ else
53
+ return await (0, ok_1.ok)(response);
54
+ }
55
+ //# sourceMappingURL=request.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"request.js","sourceRoot":"","sources":["../source/request.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,7 @@
1
+ declare const settings: Partial<Settings>;
2
+ export declare function connect(set: Settings): void;
3
+ interface Settings {
4
+ origin: string;
5
+ delay: number;
6
+ }
7
+ export { settings };
@@ -0,0 +1,10 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.settings = void 0;
4
+ exports.connect = connect;
5
+ const settings = {};
6
+ exports.settings = settings;
7
+ function connect(set) {
8
+ Object.assign(settings, set);
9
+ }
10
+ //# sourceMappingURL=settings.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"settings.js","sourceRoot":"","sources":["../source/settings.ts"],"names":[],"mappings":";;;AAEA,0BAEC;AAJD,MAAM,QAAQ,GAAsB,EAAW,CAAA;AAWtC,4BAAQ;AATjB,SAAgB,OAAO,CAAC,GAAa;IACnC,MAAM,CAAC,MAAM,CAAC,QAAQ,EAAE,GAAG,CAAC,CAAA;AAC9B,CAAC"}