@portaidentity/sdk 0.1.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/README.md +224 -0
- package/dist/agent.d.ts +42 -0
- package/dist/agent.d.ts.map +1 -0
- package/dist/agent.js +146 -0
- package/dist/agent.js.map +1 -0
- package/dist/auth/cli-auth.d.ts +83 -0
- package/dist/auth/cli-auth.d.ts.map +1 -0
- package/dist/auth/cli-auth.js +188 -0
- package/dist/auth/cli-auth.js.map +1 -0
- package/dist/auth/client-credentials-auth.d.ts +54 -0
- package/dist/auth/client-credentials-auth.d.ts.map +1 -0
- package/dist/auth/client-credentials-auth.js +147 -0
- package/dist/auth/client-credentials-auth.js.map +1 -0
- package/dist/auth/index.d.ts +20 -0
- package/dist/auth/index.d.ts.map +1 -0
- package/dist/auth/index.js +16 -0
- package/dist/auth/index.js.map +1 -0
- package/dist/auth/token-auth.d.ts +40 -0
- package/dist/auth/token-auth.d.ts.map +1 -0
- package/dist/auth/token-auth.js +44 -0
- package/dist/auth/token-auth.js.map +1 -0
- package/dist/auth/types.d.ts +28 -0
- package/dist/auth/types.d.ts.map +1 -0
- package/dist/auth/types.js +11 -0
- package/dist/auth/types.js.map +1 -0
- package/dist/browser.d.ts +12 -0
- package/dist/browser.d.ts.map +1 -0
- package/dist/browser.js +12 -0
- package/dist/browser.js.map +1 -0
- package/dist/client.d.ts +52 -0
- package/dist/client.d.ts.map +1 -0
- package/dist/client.js +52 -0
- package/dist/client.js.map +1 -0
- package/dist/domains/applications.d.ts +23 -0
- package/dist/domains/applications.d.ts.map +1 -0
- package/dist/domains/applications.js +59 -0
- package/dist/domains/applications.js.map +1 -0
- package/dist/domains/audit.d.ts +13 -0
- package/dist/domains/audit.d.ts.map +1 -0
- package/dist/domains/audit.js +19 -0
- package/dist/domains/audit.js.map +1 -0
- package/dist/domains/branding.d.ts +16 -0
- package/dist/domains/branding.d.ts.map +1 -0
- package/dist/domains/branding.js +29 -0
- package/dist/domains/branding.js.map +1 -0
- package/dist/domains/bulk.d.ts +12 -0
- package/dist/domains/bulk.d.ts.map +1 -0
- package/dist/domains/bulk.js +14 -0
- package/dist/domains/bulk.js.map +1 -0
- package/dist/domains/clients.d.ts +22 -0
- package/dist/domains/clients.d.ts.map +1 -0
- package/dist/domains/clients.js +55 -0
- package/dist/domains/clients.js.map +1 -0
- package/dist/domains/config.d.ts +14 -0
- package/dist/domains/config.d.ts.map +1 -0
- package/dist/domains/config.js +23 -0
- package/dist/domains/config.js.map +1 -0
- package/dist/domains/custom-claims.d.ts +17 -0
- package/dist/domains/custom-claims.d.ts.map +1 -0
- package/dist/domains/custom-claims.js +35 -0
- package/dist/domains/custom-claims.js.map +1 -0
- package/dist/domains/exports.d.ts +12 -0
- package/dist/domains/exports.d.ts.map +1 -0
- package/dist/domains/exports.js +20 -0
- package/dist/domains/exports.js.map +1 -0
- package/dist/domains/helpers.d.ts +27 -0
- package/dist/domains/helpers.d.ts.map +1 -0
- package/dist/domains/helpers.js +46 -0
- package/dist/domains/helpers.js.map +1 -0
- package/dist/domains/imports.d.ts +12 -0
- package/dist/domains/imports.d.ts.map +1 -0
- package/dist/domains/imports.js +14 -0
- package/dist/domains/imports.js.map +1 -0
- package/dist/domains/index.d.ts +45 -0
- package/dist/domains/index.d.ts.map +1 -0
- package/dist/domains/index.js +46 -0
- package/dist/domains/index.js.map +1 -0
- package/dist/domains/keys.d.ts +14 -0
- package/dist/domains/keys.d.ts.map +1 -0
- package/dist/domains/keys.js +23 -0
- package/dist/domains/keys.js.map +1 -0
- package/dist/domains/organizations.d.ts +33 -0
- package/dist/domains/organizations.d.ts.map +1 -0
- package/dist/domains/organizations.js +69 -0
- package/dist/domains/organizations.js.map +1 -0
- package/dist/domains/permissions.d.ts +16 -0
- package/dist/domains/permissions.d.ts.map +1 -0
- package/dist/domains/permissions.js +31 -0
- package/dist/domains/permissions.js.map +1 -0
- package/dist/domains/roles.d.ts +19 -0
- package/dist/domains/roles.d.ts.map +1 -0
- package/dist/domains/roles.js +41 -0
- package/dist/domains/roles.js.map +1 -0
- package/dist/domains/sessions.d.ts +17 -0
- package/dist/domains/sessions.d.ts.map +1 -0
- package/dist/domains/sessions.js +28 -0
- package/dist/domains/sessions.js.map +1 -0
- package/dist/domains/stats.d.ts +12 -0
- package/dist/domains/stats.d.ts.map +1 -0
- package/dist/domains/stats.js +14 -0
- package/dist/domains/stats.js.map +1 -0
- package/dist/domains/two-factor.d.ts +14 -0
- package/dist/domains/two-factor.d.ts.map +1 -0
- package/dist/domains/two-factor.js +24 -0
- package/dist/domains/two-factor.js.map +1 -0
- package/dist/domains/user-claims.d.ts +14 -0
- package/dist/domains/user-claims.d.ts.map +1 -0
- package/dist/domains/user-claims.js +24 -0
- package/dist/domains/user-claims.js.map +1 -0
- package/dist/domains/user-roles.d.ts +14 -0
- package/dist/domains/user-roles.d.ts.map +1 -0
- package/dist/domains/user-roles.js +24 -0
- package/dist/domains/user-roles.js.map +1 -0
- package/dist/domains/users.d.ts +25 -0
- package/dist/domains/users.d.ts.map +1 -0
- package/dist/domains/users.js +67 -0
- package/dist/domains/users.js.map +1 -0
- package/dist/errors/index.d.ts +110 -0
- package/dist/errors/index.d.ts.map +1 -0
- package/dist/errors/index.js +206 -0
- package/dist/errors/index.js.map +1 -0
- package/dist/index.d.ts +24 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +22 -0
- package/dist/index.js.map +1 -0
- package/dist/node.d.ts +14 -0
- package/dist/node.d.ts.map +1 -0
- package/dist/node.js +12 -0
- package/dist/node.js.map +1 -0
- package/dist/pagination/index.d.ts +87 -0
- package/dist/pagination/index.d.ts.map +1 -0
- package/dist/pagination/index.js +67 -0
- package/dist/pagination/index.js.map +1 -0
- package/dist/transport/browser-transport.d.ts +64 -0
- package/dist/transport/browser-transport.d.ts.map +1 -0
- package/dist/transport/browser-transport.js +96 -0
- package/dist/transport/browser-transport.js.map +1 -0
- package/dist/transport/node-transport.d.ts +51 -0
- package/dist/transport/node-transport.d.ts.map +1 -0
- package/dist/transport/node-transport.js +108 -0
- package/dist/transport/node-transport.js.map +1 -0
- package/dist/transport/types.d.ts +84 -0
- package/dist/transport/types.d.ts.map +1 -0
- package/dist/transport/types.js +13 -0
- package/dist/transport/types.js.map +1 -0
- package/dist/transport/utils.d.ts +78 -0
- package/dist/transport/utils.d.ts.map +1 -0
- package/dist/transport/utils.js +126 -0
- package/dist/transport/utils.js.map +1 -0
- package/dist/types/applications.d.ts +48 -0
- package/dist/types/applications.d.ts.map +1 -0
- package/dist/types/applications.js +7 -0
- package/dist/types/applications.js.map +1 -0
- package/dist/types/audit.d.ts +31 -0
- package/dist/types/audit.d.ts.map +1 -0
- package/dist/types/audit.js +7 -0
- package/dist/types/audit.js.map +1 -0
- package/dist/types/branding.d.ts +13 -0
- package/dist/types/branding.d.ts.map +1 -0
- package/dist/types/branding.js +7 -0
- package/dist/types/branding.js.map +1 -0
- package/dist/types/bulk.d.ts +22 -0
- package/dist/types/bulk.d.ts.map +1 -0
- package/dist/types/bulk.js +7 -0
- package/dist/types/bulk.js.map +1 -0
- package/dist/types/clients.d.ts +70 -0
- package/dist/types/clients.d.ts.map +1 -0
- package/dist/types/clients.js +7 -0
- package/dist/types/clients.js.map +1 -0
- package/dist/types/common.d.ts +75 -0
- package/dist/types/common.d.ts.map +1 -0
- package/dist/types/common.js +7 -0
- package/dist/types/common.js.map +1 -0
- package/dist/types/config.d.ts +15 -0
- package/dist/types/config.d.ts.map +1 -0
- package/dist/types/config.js +7 -0
- package/dist/types/config.js.map +1 -0
- package/dist/types/custom-claims.d.ts +48 -0
- package/dist/types/custom-claims.d.ts.map +1 -0
- package/dist/types/custom-claims.js +7 -0
- package/dist/types/custom-claims.js.map +1 -0
- package/dist/types/exports.d.ts +14 -0
- package/dist/types/exports.d.ts.map +1 -0
- package/dist/types/exports.js +7 -0
- package/dist/types/exports.js.map +1 -0
- package/dist/types/imports.d.ts +31 -0
- package/dist/types/imports.d.ts.map +1 -0
- package/dist/types/imports.js +7 -0
- package/dist/types/imports.js.map +1 -0
- package/dist/types/index.d.ts +26 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +7 -0
- package/dist/types/index.js.map +1 -0
- package/dist/types/keys.d.ts +14 -0
- package/dist/types/keys.d.ts.map +1 -0
- package/dist/types/keys.js +7 -0
- package/dist/types/keys.js.map +1 -0
- package/dist/types/organizations.d.ts +47 -0
- package/dist/types/organizations.d.ts.map +1 -0
- package/dist/types/organizations.js +7 -0
- package/dist/types/organizations.js.map +1 -0
- package/dist/types/permissions.d.ts +23 -0
- package/dist/types/permissions.d.ts.map +1 -0
- package/dist/types/permissions.js +7 -0
- package/dist/types/permissions.js.map +1 -0
- package/dist/types/roles.d.ts +30 -0
- package/dist/types/roles.d.ts.map +1 -0
- package/dist/types/roles.js +7 -0
- package/dist/types/roles.js.map +1 -0
- package/dist/types/sessions.d.ts +25 -0
- package/dist/types/sessions.d.ts.map +1 -0
- package/dist/types/sessions.js +7 -0
- package/dist/types/sessions.js.map +1 -0
- package/dist/types/stats.d.ts +18 -0
- package/dist/types/stats.d.ts.map +1 -0
- package/dist/types/stats.js +7 -0
- package/dist/types/stats.js.map +1 -0
- package/dist/types/two-factor.d.ts +14 -0
- package/dist/types/two-factor.d.ts.map +1 -0
- package/dist/types/two-factor.js +7 -0
- package/dist/types/two-factor.js.map +1 -0
- package/dist/types/user-claims.d.ts +16 -0
- package/dist/types/user-claims.d.ts.map +1 -0
- package/dist/types/user-claims.js +7 -0
- package/dist/types/user-claims.js.map +1 -0
- package/dist/types/user-roles.d.ts +17 -0
- package/dist/types/user-roles.d.ts.map +1 -0
- package/dist/types/user-roles.js +7 -0
- package/dist/types/user-roles.js.map +1 -0
- package/dist/types/users.d.ts +53 -0
- package/dist/types/users.d.ts.map +1 -0
- package/dist/types/users.js +7 -0
- package/dist/types/users.js.map +1 -0
- package/dist/version.d.ts +9 -0
- package/dist/version.d.ts.map +1 -0
- package/dist/version.js +9 -0
- package/dist/version.js.map +1 -0
- package/package.json +51 -0
package/dist/node.js
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @portaidentity/sdk/node — Node.js entrypoint.
|
|
3
|
+
*
|
|
4
|
+
* Exports Node.js-specific transport and all auth providers.
|
|
5
|
+
*
|
|
6
|
+
* @module @portaidentity/sdk/node
|
|
7
|
+
*/
|
|
8
|
+
// Node transport
|
|
9
|
+
export { createNodeTransport } from './transport/node-transport.js';
|
|
10
|
+
// Auth providers
|
|
11
|
+
export { createTokenAuth, createClientCredentialsAuth, createCliAuth } from './auth/index.js';
|
|
12
|
+
//# sourceMappingURL=node.js.map
|
package/dist/node.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"node.js","sourceRoot":"","sources":["../src/node.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,iBAAiB;AACjB,OAAO,EAAE,mBAAmB,EAAE,MAAM,+BAA+B,CAAC;AAGpE,iBAAiB;AACjB,OAAO,EAAE,eAAe,EAAE,2BAA2B,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC"}
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pagination types and helpers for the Porta SDK.
|
|
3
|
+
*
|
|
4
|
+
* The server uses two pagination strategies:
|
|
5
|
+
* - **Offset-based**: `page`, `pageSize`, `totalPages` (legacy endpoints)
|
|
6
|
+
* - **Cursor-based**: `cursor`, `hasMore`, `limit` (newer endpoints)
|
|
7
|
+
*
|
|
8
|
+
* The `listAll` helper auto-detects the strategy from the first
|
|
9
|
+
* response and fetches all remaining pages sequentially.
|
|
10
|
+
*/
|
|
11
|
+
/**
|
|
12
|
+
* Paginated response from the server.
|
|
13
|
+
*
|
|
14
|
+
* The response shape varies by pagination strategy — offset-based
|
|
15
|
+
* endpoints include `page`/`totalPages`, cursor-based include
|
|
16
|
+
* `cursor`/`hasMore`. Both always include `data` and `total`.
|
|
17
|
+
*/
|
|
18
|
+
export interface PaginatedResult<T> {
|
|
19
|
+
/** Array of entities for the current page */
|
|
20
|
+
data: T[];
|
|
21
|
+
/** Total number of entities across all pages */
|
|
22
|
+
total: number;
|
|
23
|
+
/** Current page number (1-based). Present for offset-based pagination. */
|
|
24
|
+
page?: number;
|
|
25
|
+
/** Number of items per page. Present for offset-based pagination. */
|
|
26
|
+
pageSize?: number;
|
|
27
|
+
/** Total number of pages. Present for offset-based pagination. */
|
|
28
|
+
totalPages?: number;
|
|
29
|
+
/** Cursor for the next page. Null when on the last page. */
|
|
30
|
+
cursor?: string | null;
|
|
31
|
+
/** Whether more pages exist after this one. */
|
|
32
|
+
hasMore?: boolean;
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Parameters for paginated list endpoints.
|
|
36
|
+
*
|
|
37
|
+
* Domain methods accept these to control pagination, filtering,
|
|
38
|
+
* and sorting. Not all fields apply to all endpoints — the domain
|
|
39
|
+
* method passes only what the server supports.
|
|
40
|
+
*/
|
|
41
|
+
export interface PaginatedListParams {
|
|
42
|
+
/** Page number (1-based) for offset pagination */
|
|
43
|
+
page?: number;
|
|
44
|
+
/** Items per page for offset pagination */
|
|
45
|
+
pageSize?: number;
|
|
46
|
+
/** Cursor for cursor-based pagination */
|
|
47
|
+
cursor?: string;
|
|
48
|
+
/** Items per page for cursor-based pagination */
|
|
49
|
+
limit?: number;
|
|
50
|
+
/** Free-text search query */
|
|
51
|
+
search?: string;
|
|
52
|
+
/** Field to sort by */
|
|
53
|
+
sortBy?: string;
|
|
54
|
+
/** Sort direction */
|
|
55
|
+
sortOrder?: 'asc' | 'desc';
|
|
56
|
+
/** Additional domain-specific filter parameters */
|
|
57
|
+
[key: string]: string | number | boolean | undefined | null;
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* Fetches all pages of a paginated endpoint and returns the
|
|
61
|
+
* combined results as a flat array.
|
|
62
|
+
*
|
|
63
|
+
* Auto-detects the pagination strategy from the first response:
|
|
64
|
+
* - If `cursor`/`hasMore` fields are present → cursor-based iteration
|
|
65
|
+
* - If `totalPages` is present → offset-based iteration
|
|
66
|
+
* - Otherwise → returns just the first page's data
|
|
67
|
+
*
|
|
68
|
+
* @param fetchPage - Function that fetches a single page
|
|
69
|
+
* @param params - Base parameters (page/cursor excluded — managed internally)
|
|
70
|
+
* @param options - Optional AbortSignal for cancellation
|
|
71
|
+
* @returns Combined array of all entities across all pages
|
|
72
|
+
*
|
|
73
|
+
* @throws Immediately on any page fetch error (no partial results)
|
|
74
|
+
* @throws {DOMException} If the AbortSignal is triggered
|
|
75
|
+
*
|
|
76
|
+
* @example
|
|
77
|
+
* ```typescript
|
|
78
|
+
* const allOrgs = await listAll(
|
|
79
|
+
* (p) => client.organizations.list(p),
|
|
80
|
+
* { search: 'acme', sortBy: 'name' },
|
|
81
|
+
* );
|
|
82
|
+
* ```
|
|
83
|
+
*/
|
|
84
|
+
export declare function listAll<T>(fetchPage: (params: PaginatedListParams) => Promise<PaginatedResult<T>>, params?: Omit<PaginatedListParams, 'page' | 'cursor'>, options?: {
|
|
85
|
+
signal?: AbortSignal;
|
|
86
|
+
}): Promise<T[]>;
|
|
87
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/pagination/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH;;;;;;GAMG;AACH,MAAM,WAAW,eAAe,CAAC,CAAC;IAChC,6CAA6C;IAC7C,IAAI,EAAE,CAAC,EAAE,CAAC;IAEV,gDAAgD;IAChD,KAAK,EAAE,MAAM,CAAC;IAId,0EAA0E;IAC1E,IAAI,CAAC,EAAE,MAAM,CAAC;IAEd,qEAAqE;IACrE,QAAQ,CAAC,EAAE,MAAM,CAAC;IAElB,kEAAkE;IAClE,UAAU,CAAC,EAAE,MAAM,CAAC;IAIpB,4DAA4D;IAC5D,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAEvB,+CAA+C;IAC/C,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAED;;;;;;GAMG;AACH,MAAM,WAAW,mBAAmB;IAGlC,kDAAkD;IAClD,IAAI,CAAC,EAAE,MAAM,CAAC;IAEd,2CAA2C;IAC3C,QAAQ,CAAC,EAAE,MAAM,CAAC;IAIlB,yCAAyC;IACzC,MAAM,CAAC,EAAE,MAAM,CAAC;IAEhB,iDAAiD;IACjD,KAAK,CAAC,EAAE,MAAM,CAAC;IAIf,6BAA6B;IAC7B,MAAM,CAAC,EAAE,MAAM,CAAC;IAEhB,uBAAuB;IACvB,MAAM,CAAC,EAAE,MAAM,CAAC;IAEhB,qBAAqB;IACrB,SAAS,CAAC,EAAE,KAAK,GAAG,MAAM,CAAC;IAE3B,mDAAmD;IACnD,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,SAAS,GAAG,IAAI,CAAC;CAC7D;AAED;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,wBAAsB,OAAO,CAAC,CAAC,EAC7B,SAAS,EAAE,CAAC,MAAM,EAAE,mBAAmB,KAAK,OAAO,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC,EACvE,MAAM,CAAC,EAAE,IAAI,CAAC,mBAAmB,EAAE,MAAM,GAAG,QAAQ,CAAC,EACrD,OAAO,CAAC,EAAE;IAAE,MAAM,CAAC,EAAE,WAAW,CAAA;CAAE,GACjC,OAAO,CAAC,CAAC,EAAE,CAAC,CAqCd"}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pagination types and helpers for the Porta SDK.
|
|
3
|
+
*
|
|
4
|
+
* The server uses two pagination strategies:
|
|
5
|
+
* - **Offset-based**: `page`, `pageSize`, `totalPages` (legacy endpoints)
|
|
6
|
+
* - **Cursor-based**: `cursor`, `hasMore`, `limit` (newer endpoints)
|
|
7
|
+
*
|
|
8
|
+
* The `listAll` helper auto-detects the strategy from the first
|
|
9
|
+
* response and fetches all remaining pages sequentially.
|
|
10
|
+
*/
|
|
11
|
+
/**
|
|
12
|
+
* Fetches all pages of a paginated endpoint and returns the
|
|
13
|
+
* combined results as a flat array.
|
|
14
|
+
*
|
|
15
|
+
* Auto-detects the pagination strategy from the first response:
|
|
16
|
+
* - If `cursor`/`hasMore` fields are present → cursor-based iteration
|
|
17
|
+
* - If `totalPages` is present → offset-based iteration
|
|
18
|
+
* - Otherwise → returns just the first page's data
|
|
19
|
+
*
|
|
20
|
+
* @param fetchPage - Function that fetches a single page
|
|
21
|
+
* @param params - Base parameters (page/cursor excluded — managed internally)
|
|
22
|
+
* @param options - Optional AbortSignal for cancellation
|
|
23
|
+
* @returns Combined array of all entities across all pages
|
|
24
|
+
*
|
|
25
|
+
* @throws Immediately on any page fetch error (no partial results)
|
|
26
|
+
* @throws {DOMException} If the AbortSignal is triggered
|
|
27
|
+
*
|
|
28
|
+
* @example
|
|
29
|
+
* ```typescript
|
|
30
|
+
* const allOrgs = await listAll(
|
|
31
|
+
* (p) => client.organizations.list(p),
|
|
32
|
+
* { search: 'acme', sortBy: 'name' },
|
|
33
|
+
* );
|
|
34
|
+
* ```
|
|
35
|
+
*/
|
|
36
|
+
export async function listAll(fetchPage, params, options) {
|
|
37
|
+
const baseParams = { ...params };
|
|
38
|
+
const signal = options?.signal;
|
|
39
|
+
// Fetch the first page to detect pagination strategy
|
|
40
|
+
const firstPage = await fetchPage({ ...baseParams, page: 1 });
|
|
41
|
+
const allData = [...firstPage.data];
|
|
42
|
+
// Detect cursor-based pagination (hasMore field present)
|
|
43
|
+
if (typeof firstPage.hasMore === 'boolean') {
|
|
44
|
+
let nextCursor = firstPage.cursor;
|
|
45
|
+
let hasMore = firstPage.hasMore;
|
|
46
|
+
while (hasMore && nextCursor) {
|
|
47
|
+
signal?.throwIfAborted();
|
|
48
|
+
const nextPage = await fetchPage({ ...baseParams, cursor: nextCursor });
|
|
49
|
+
allData.push(...nextPage.data);
|
|
50
|
+
nextCursor = nextPage.cursor;
|
|
51
|
+
hasMore = nextPage.hasMore ?? false;
|
|
52
|
+
}
|
|
53
|
+
return allData;
|
|
54
|
+
}
|
|
55
|
+
// Detect offset-based pagination (totalPages field present)
|
|
56
|
+
if (typeof firstPage.totalPages === 'number' && firstPage.totalPages > 1) {
|
|
57
|
+
for (let page = 2; page <= firstPage.totalPages; page++) {
|
|
58
|
+
signal?.throwIfAborted();
|
|
59
|
+
const nextPage = await fetchPage({ ...baseParams, page });
|
|
60
|
+
allData.push(...nextPage.data);
|
|
61
|
+
}
|
|
62
|
+
return allData;
|
|
63
|
+
}
|
|
64
|
+
// Single page or unknown strategy — return what we have
|
|
65
|
+
return allData;
|
|
66
|
+
}
|
|
67
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/pagination/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AA2EH;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,MAAM,CAAC,KAAK,UAAU,OAAO,CAC3B,SAAuE,EACvE,MAAqD,EACrD,OAAkC;IAElC,MAAM,UAAU,GAAG,EAAE,GAAG,MAAM,EAAyB,CAAC;IACxD,MAAM,MAAM,GAAG,OAAO,EAAE,MAAM,CAAC;IAE/B,qDAAqD;IACrD,MAAM,SAAS,GAAG,MAAM,SAAS,CAAC,EAAE,GAAG,UAAU,EAAE,IAAI,EAAE,CAAC,EAAE,CAAC,CAAC;IAC9D,MAAM,OAAO,GAAG,CAAC,GAAG,SAAS,CAAC,IAAI,CAAC,CAAC;IAEpC,yDAAyD;IACzD,IAAI,OAAO,SAAS,CAAC,OAAO,KAAK,SAAS,EAAE,CAAC;QAC3C,IAAI,UAAU,GAAG,SAAS,CAAC,MAAM,CAAC;QAClC,IAAI,OAAO,GAAG,SAAS,CAAC,OAAO,CAAC;QAEhC,OAAO,OAAO,IAAI,UAAU,EAAE,CAAC;YAC7B,MAAM,EAAE,cAAc,EAAE,CAAC;YACzB,MAAM,QAAQ,GAAG,MAAM,SAAS,CAAC,EAAE,GAAG,UAAU,EAAE,MAAM,EAAE,UAAU,EAAE,CAAC,CAAC;YACxE,OAAO,CAAC,IAAI,CAAC,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAC;YAC/B,UAAU,GAAG,QAAQ,CAAC,MAAM,CAAC;YAC7B,OAAO,GAAG,QAAQ,CAAC,OAAO,IAAI,KAAK,CAAC;QACtC,CAAC;QAED,OAAO,OAAO,CAAC;IACjB,CAAC;IAED,4DAA4D;IAC5D,IAAI,OAAO,SAAS,CAAC,UAAU,KAAK,QAAQ,IAAI,SAAS,CAAC,UAAU,GAAG,CAAC,EAAE,CAAC;QACzE,KAAK,IAAI,IAAI,GAAG,CAAC,EAAE,IAAI,IAAI,SAAS,CAAC,UAAU,EAAE,IAAI,EAAE,EAAE,CAAC;YACxD,MAAM,EAAE,cAAc,EAAE,CAAC;YACzB,MAAM,QAAQ,GAAG,MAAM,SAAS,CAAC,EAAE,GAAG,UAAU,EAAE,IAAI,EAAE,CAAC,CAAC;YAC1D,OAAO,CAAC,IAAI,CAAC,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAC;QACjC,CAAC;QAED,OAAO,OAAO,CAAC;IACjB,CAAC;IAED,wDAAwD;IACxD,OAAO,OAAO,CAAC;AACjB,CAAC"}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Browser-oriented HTTP transport for the Porta SDK.
|
|
3
|
+
*
|
|
4
|
+
* Designed for SPAs communicating with a BFF (Backend-for-Frontend).
|
|
5
|
+
* Features:
|
|
6
|
+
* - Cookie-based sessions (`credentials: 'include'`)
|
|
7
|
+
* - CSRF token injection on state-changing requests (POST/PUT/PATCH/DELETE)
|
|
8
|
+
* - CSRF token update from response headers
|
|
9
|
+
* - 401 → configurable unauthorized handler (default: redirect to /auth/login)
|
|
10
|
+
* - Binary response support (`responseType: 'raw'`)
|
|
11
|
+
* - FormData upload support (`contentType: null`)
|
|
12
|
+
* - AbortSignal for request cancellation
|
|
13
|
+
*/
|
|
14
|
+
import type { HttpTransport } from './types.js';
|
|
15
|
+
/**
|
|
16
|
+
* Configuration options for the browser transport.
|
|
17
|
+
*/
|
|
18
|
+
export interface BrowserTransportOptions {
|
|
19
|
+
/**
|
|
20
|
+
* Base URL for API requests.
|
|
21
|
+
* Use `''` (empty string) for same-origin BFF requests.
|
|
22
|
+
* For cross-origin setups, provide the full origin (e.g., 'https://api.example.com').
|
|
23
|
+
*/
|
|
24
|
+
baseUrl: string;
|
|
25
|
+
/**
|
|
26
|
+
* Returns the current CSRF token for state-changing requests.
|
|
27
|
+
* Called on every POST, PUT, PATCH, and DELETE request.
|
|
28
|
+
* Typically reads from a cookie (e.g., `document.cookie`).
|
|
29
|
+
*/
|
|
30
|
+
getCsrfToken?: () => string | null;
|
|
31
|
+
/**
|
|
32
|
+
* Called when the server sends a new CSRF token in a response header.
|
|
33
|
+
* Allows the application to update its stored token for future requests.
|
|
34
|
+
* Triggered when the `X-CSRF-Token` response header is present.
|
|
35
|
+
*/
|
|
36
|
+
setCsrfToken?: (token: string | null) => void;
|
|
37
|
+
/**
|
|
38
|
+
* Called when a 401 Unauthorized response is received.
|
|
39
|
+
* Default behavior: redirects to `/auth/login` via `window.location.href`.
|
|
40
|
+
* Provide a custom handler to override (e.g., show a login modal).
|
|
41
|
+
*/
|
|
42
|
+
onUnauthorized?: () => void;
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Creates a browser-oriented HTTP transport.
|
|
46
|
+
*
|
|
47
|
+
* Uses the browser's native `fetch` with cookie-based sessions,
|
|
48
|
+
* CSRF token management, and configurable 401 handling. All requests
|
|
49
|
+
* include `credentials: 'include'` for cookie transmission.
|
|
50
|
+
*
|
|
51
|
+
* @param options - Transport configuration
|
|
52
|
+
* @returns An HttpTransport instance for browser environments
|
|
53
|
+
*
|
|
54
|
+
* @example
|
|
55
|
+
* ```typescript
|
|
56
|
+
* const transport = createBrowserTransport({
|
|
57
|
+
* baseUrl: '', // same-origin BFF
|
|
58
|
+
* getCsrfToken: () => getCookie('_csrf'),
|
|
59
|
+
* onUnauthorized: () => router.push('/login'),
|
|
60
|
+
* });
|
|
61
|
+
* ```
|
|
62
|
+
*/
|
|
63
|
+
export declare function createBrowserTransport(options: BrowserTransportOptions): HttpTransport;
|
|
64
|
+
//# sourceMappingURL=browser-transport.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"browser-transport.d.ts","sourceRoot":"","sources":["../../src/transport/browser-transport.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAuC,MAAM,YAAY,CAAC;AAUrF;;GAEG;AACH,MAAM,WAAW,uBAAuB;IACtC;;;;OAIG;IACH,OAAO,EAAE,MAAM,CAAC;IAEhB;;;;OAIG;IACH,YAAY,CAAC,EAAE,MAAM,MAAM,GAAG,IAAI,CAAC;IAEnC;;;;OAIG;IACH,YAAY,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,KAAK,IAAI,CAAC;IAE9C;;;;OAIG;IACH,cAAc,CAAC,EAAE,MAAM,IAAI,CAAC;CAC7B;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,sBAAsB,CAAC,OAAO,EAAE,uBAAuB,GAAG,aAAa,CAsEtF"}
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Browser-oriented HTTP transport for the Porta SDK.
|
|
3
|
+
*
|
|
4
|
+
* Designed for SPAs communicating with a BFF (Backend-for-Frontend).
|
|
5
|
+
* Features:
|
|
6
|
+
* - Cookie-based sessions (`credentials: 'include'`)
|
|
7
|
+
* - CSRF token injection on state-changing requests (POST/PUT/PATCH/DELETE)
|
|
8
|
+
* - CSRF token update from response headers
|
|
9
|
+
* - 401 → configurable unauthorized handler (default: redirect to /auth/login)
|
|
10
|
+
* - Binary response support (`responseType: 'raw'`)
|
|
11
|
+
* - FormData upload support (`contentType: null`)
|
|
12
|
+
* - AbortSignal for request cancellation
|
|
13
|
+
*/
|
|
14
|
+
import { mapResponseToError } from '../errors/index.js';
|
|
15
|
+
import { buildRequestUrl, extractResponseHeaders, buildCommonHeaders, serializeBody, safeParseJson, } from './utils.js';
|
|
16
|
+
/**
|
|
17
|
+
* Creates a browser-oriented HTTP transport.
|
|
18
|
+
*
|
|
19
|
+
* Uses the browser's native `fetch` with cookie-based sessions,
|
|
20
|
+
* CSRF token management, and configurable 401 handling. All requests
|
|
21
|
+
* include `credentials: 'include'` for cookie transmission.
|
|
22
|
+
*
|
|
23
|
+
* @param options - Transport configuration
|
|
24
|
+
* @returns An HttpTransport instance for browser environments
|
|
25
|
+
*
|
|
26
|
+
* @example
|
|
27
|
+
* ```typescript
|
|
28
|
+
* const transport = createBrowserTransport({
|
|
29
|
+
* baseUrl: '', // same-origin BFF
|
|
30
|
+
* getCsrfToken: () => getCookie('_csrf'),
|
|
31
|
+
* onUnauthorized: () => router.push('/login'),
|
|
32
|
+
* });
|
|
33
|
+
* ```
|
|
34
|
+
*/
|
|
35
|
+
export function createBrowserTransport(options) {
|
|
36
|
+
const { baseUrl, getCsrfToken, setCsrfToken, onUnauthorized } = options;
|
|
37
|
+
return {
|
|
38
|
+
async request(req) {
|
|
39
|
+
// Build full URL with /api/admin prefix and query params
|
|
40
|
+
const url = buildRequestUrl(baseUrl, req.path, req.params);
|
|
41
|
+
// Build common headers (Accept, Content-Type, SDK version)
|
|
42
|
+
const headers = buildCommonHeaders(req);
|
|
43
|
+
// Add CSRF token for state-changing methods
|
|
44
|
+
if (req.method !== 'GET' && getCsrfToken) {
|
|
45
|
+
const csrfToken = getCsrfToken();
|
|
46
|
+
if (csrfToken) {
|
|
47
|
+
headers['X-CSRF-Token'] = csrfToken;
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
// Execute fetch with cookie credentials
|
|
51
|
+
const response = await fetch(url, {
|
|
52
|
+
method: req.method,
|
|
53
|
+
headers,
|
|
54
|
+
body: serializeBody(req.body, req.contentType),
|
|
55
|
+
credentials: 'include',
|
|
56
|
+
signal: req.signal,
|
|
57
|
+
});
|
|
58
|
+
// Extract response headers (lowercased keys)
|
|
59
|
+
const responseHeaders = extractResponseHeaders(response);
|
|
60
|
+
// Update CSRF token if server sent a new one
|
|
61
|
+
const newCsrfToken = responseHeaders['x-csrf-token'];
|
|
62
|
+
if (setCsrfToken && newCsrfToken) {
|
|
63
|
+
setCsrfToken(newCsrfToken);
|
|
64
|
+
}
|
|
65
|
+
// 401 — notify caller and throw authentication error
|
|
66
|
+
if (response.status === 401) {
|
|
67
|
+
const body = await safeParseJson(response);
|
|
68
|
+
if (onUnauthorized) {
|
|
69
|
+
onUnauthorized();
|
|
70
|
+
}
|
|
71
|
+
else if (typeof window !== 'undefined') {
|
|
72
|
+
// Default: redirect to login page
|
|
73
|
+
window.location.href = '/auth/login';
|
|
74
|
+
}
|
|
75
|
+
throw mapResponseToError({ status: 401, headers: responseHeaders, body });
|
|
76
|
+
}
|
|
77
|
+
// 204 — no content
|
|
78
|
+
if (response.status === 204) {
|
|
79
|
+
return { status: 204, headers: responseHeaders, body: undefined };
|
|
80
|
+
}
|
|
81
|
+
// Non-2xx — parse error body and throw typed error
|
|
82
|
+
if (response.status < 200 || response.status >= 300) {
|
|
83
|
+
const body = await safeParseJson(response);
|
|
84
|
+
throw mapResponseToError({ status: response.status, headers: responseHeaders, body });
|
|
85
|
+
}
|
|
86
|
+
// 2xx + raw — return with native Response for binary streaming
|
|
87
|
+
if (req.responseType === 'raw') {
|
|
88
|
+
return { status: response.status, headers: responseHeaders, body: undefined, raw: response };
|
|
89
|
+
}
|
|
90
|
+
// 2xx + json — parse body and return
|
|
91
|
+
const body = await response.json();
|
|
92
|
+
return { status: response.status, headers: responseHeaders, body };
|
|
93
|
+
},
|
|
94
|
+
};
|
|
95
|
+
}
|
|
96
|
+
//# sourceMappingURL=browser-transport.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"browser-transport.js","sourceRoot":"","sources":["../../src/transport/browser-transport.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Node.js / server-side HTTP transport for the Porta SDK.
|
|
3
|
+
*
|
|
4
|
+
* Designed for CLI tools, automation scripts, and server-to-server
|
|
5
|
+
* communication. Features:
|
|
6
|
+
* - Bearer token authentication via AuthProvider
|
|
7
|
+
* - Automatic 401 retry with token refresh (when provider supports it)
|
|
8
|
+
* - Binary response support (`responseType: 'raw'`)
|
|
9
|
+
* - FormData upload support (`contentType: null`)
|
|
10
|
+
* - AbortSignal for request cancellation
|
|
11
|
+
*/
|
|
12
|
+
import type { HttpTransport } from './types.js';
|
|
13
|
+
import type { AuthProvider } from '../auth/types.js';
|
|
14
|
+
/**
|
|
15
|
+
* Configuration options for the Node.js transport.
|
|
16
|
+
*/
|
|
17
|
+
export interface NodeTransportOptions {
|
|
18
|
+
/**
|
|
19
|
+
* Base URL of the Porta instance.
|
|
20
|
+
* Must include the protocol and host (e.g., 'https://porta.example.com').
|
|
21
|
+
*/
|
|
22
|
+
baseUrl: string;
|
|
23
|
+
/**
|
|
24
|
+
* Authentication provider for Bearer token injection.
|
|
25
|
+
* Tokens are fetched via `auth.getToken()` for each request.
|
|
26
|
+
* If `auth.refreshToken()` is available, 401 responses trigger
|
|
27
|
+
* a token refresh and one automatic retry.
|
|
28
|
+
*/
|
|
29
|
+
auth: AuthProvider;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Creates a Node.js / server-side HTTP transport.
|
|
33
|
+
*
|
|
34
|
+
* Uses Bearer token authentication with optional automatic retry
|
|
35
|
+
* on 401 responses when the auth provider supports token refresh.
|
|
36
|
+
* Does NOT use `credentials: 'include'` — authentication is purely
|
|
37
|
+
* token-based (no cookies).
|
|
38
|
+
*
|
|
39
|
+
* @param options - Transport configuration
|
|
40
|
+
* @returns An HttpTransport instance for Node.js environments
|
|
41
|
+
*
|
|
42
|
+
* @example
|
|
43
|
+
* ```typescript
|
|
44
|
+
* const transport = createNodeTransport({
|
|
45
|
+
* baseUrl: 'https://porta.example.com',
|
|
46
|
+
* auth: createTokenAuth('my-access-token'),
|
|
47
|
+
* });
|
|
48
|
+
* ```
|
|
49
|
+
*/
|
|
50
|
+
export declare function createNodeTransport(options: NodeTransportOptions): HttpTransport;
|
|
51
|
+
//# sourceMappingURL=node-transport.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"node-transport.d.ts","sourceRoot":"","sources":["../../src/transport/node-transport.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAuC,MAAM,YAAY,CAAC;AACrF,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAUrD;;GAEG;AACH,MAAM,WAAW,oBAAoB;IACnC;;;OAGG;IACH,OAAO,EAAE,MAAM,CAAC;IAEhB;;;;;OAKG;IACH,IAAI,EAAE,YAAY,CAAC;CACpB;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,oBAAoB,GAAG,aAAa,CAqBhF"}
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Node.js / server-side HTTP transport for the Porta SDK.
|
|
3
|
+
*
|
|
4
|
+
* Designed for CLI tools, automation scripts, and server-to-server
|
|
5
|
+
* communication. Features:
|
|
6
|
+
* - Bearer token authentication via AuthProvider
|
|
7
|
+
* - Automatic 401 retry with token refresh (when provider supports it)
|
|
8
|
+
* - Binary response support (`responseType: 'raw'`)
|
|
9
|
+
* - FormData upload support (`contentType: null`)
|
|
10
|
+
* - AbortSignal for request cancellation
|
|
11
|
+
*/
|
|
12
|
+
import { mapResponseToError } from '../errors/index.js';
|
|
13
|
+
import { buildRequestUrl, extractResponseHeaders, buildCommonHeaders, serializeBody, safeParseJson, } from './utils.js';
|
|
14
|
+
/**
|
|
15
|
+
* Creates a Node.js / server-side HTTP transport.
|
|
16
|
+
*
|
|
17
|
+
* Uses Bearer token authentication with optional automatic retry
|
|
18
|
+
* on 401 responses when the auth provider supports token refresh.
|
|
19
|
+
* Does NOT use `credentials: 'include'` — authentication is purely
|
|
20
|
+
* token-based (no cookies).
|
|
21
|
+
*
|
|
22
|
+
* @param options - Transport configuration
|
|
23
|
+
* @returns An HttpTransport instance for Node.js environments
|
|
24
|
+
*
|
|
25
|
+
* @example
|
|
26
|
+
* ```typescript
|
|
27
|
+
* const transport = createNodeTransport({
|
|
28
|
+
* baseUrl: 'https://porta.example.com',
|
|
29
|
+
* auth: createTokenAuth('my-access-token'),
|
|
30
|
+
* });
|
|
31
|
+
* ```
|
|
32
|
+
*/
|
|
33
|
+
export function createNodeTransport(options) {
|
|
34
|
+
const { baseUrl, auth } = options;
|
|
35
|
+
return {
|
|
36
|
+
async request(req) {
|
|
37
|
+
// Get access token from auth provider
|
|
38
|
+
const token = await auth.getToken();
|
|
39
|
+
// Execute the initial request
|
|
40
|
+
const response = await executeRequest(baseUrl, req, token);
|
|
41
|
+
// 401 + refreshToken available → attempt token refresh and retry once
|
|
42
|
+
if (response.status === 401 && auth.refreshToken) {
|
|
43
|
+
const newToken = await auth.refreshToken();
|
|
44
|
+
const retryResponse = await executeRequest(baseUrl, req, newToken);
|
|
45
|
+
return processResponse(retryResponse, req);
|
|
46
|
+
}
|
|
47
|
+
return processResponse(response, req);
|
|
48
|
+
},
|
|
49
|
+
};
|
|
50
|
+
}
|
|
51
|
+
// ── Internal helpers ──────────────────────────────────────────────
|
|
52
|
+
/**
|
|
53
|
+
* Executes a single HTTP request with Bearer token authentication.
|
|
54
|
+
*
|
|
55
|
+
* Builds the full URL, sets common headers plus the Authorization
|
|
56
|
+
* header, serializes the body, and calls fetch().
|
|
57
|
+
*
|
|
58
|
+
* @param baseUrl - Base URL of the Porta instance
|
|
59
|
+
* @param req - The transport request to execute
|
|
60
|
+
* @param token - Bearer access token
|
|
61
|
+
* @returns The raw fetch Response
|
|
62
|
+
*/
|
|
63
|
+
async function executeRequest(baseUrl, req, token) {
|
|
64
|
+
// Build full URL with /api/admin prefix and query params
|
|
65
|
+
const url = buildRequestUrl(baseUrl, req.path, req.params);
|
|
66
|
+
// Build common headers (Accept, Content-Type, SDK version)
|
|
67
|
+
const headers = buildCommonHeaders(req);
|
|
68
|
+
// Add Bearer token authentication
|
|
69
|
+
headers['Authorization'] = `Bearer ${token}`;
|
|
70
|
+
// Execute fetch (no credentials: 'include' — server-side uses tokens only)
|
|
71
|
+
return fetch(url, {
|
|
72
|
+
method: req.method,
|
|
73
|
+
headers,
|
|
74
|
+
body: serializeBody(req.body, req.contentType),
|
|
75
|
+
signal: req.signal,
|
|
76
|
+
});
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* Processes a fetch Response into a TransportResponse.
|
|
80
|
+
*
|
|
81
|
+
* Handles 204 (no content), non-2xx errors (throws typed errors),
|
|
82
|
+
* raw responses (binary streaming), and JSON parsing.
|
|
83
|
+
*
|
|
84
|
+
* @param response - The raw fetch Response
|
|
85
|
+
* @param req - The original transport request (for responseType check)
|
|
86
|
+
* @returns A TransportResponse for successful requests
|
|
87
|
+
* @throws PortaHttpError subclass for non-2xx responses
|
|
88
|
+
*/
|
|
89
|
+
async function processResponse(response, req) {
|
|
90
|
+
const responseHeaders = extractResponseHeaders(response);
|
|
91
|
+
// 204 — no content
|
|
92
|
+
if (response.status === 204) {
|
|
93
|
+
return { status: 204, headers: responseHeaders, body: undefined };
|
|
94
|
+
}
|
|
95
|
+
// Non-2xx — parse error body and throw typed error
|
|
96
|
+
if (response.status < 200 || response.status >= 300) {
|
|
97
|
+
const body = await safeParseJson(response);
|
|
98
|
+
throw mapResponseToError({ status: response.status, headers: responseHeaders, body });
|
|
99
|
+
}
|
|
100
|
+
// 2xx + raw — return with native Response for binary streaming
|
|
101
|
+
if (req.responseType === 'raw') {
|
|
102
|
+
return { status: response.status, headers: responseHeaders, body: undefined, raw: response };
|
|
103
|
+
}
|
|
104
|
+
// 2xx + json — parse body and return
|
|
105
|
+
const body = await response.json();
|
|
106
|
+
return { status: response.status, headers: responseHeaders, body };
|
|
107
|
+
}
|
|
108
|
+
//# sourceMappingURL=node-transport.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"node-transport.js","sourceRoot":"","sources":["../../src/transport/node-transport.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Transport abstraction types for the Porta SDK.
|
|
3
|
+
*
|
|
4
|
+
* The transport layer handles environment-specific HTTP execution.
|
|
5
|
+
* Two implementations exist: BrowserTransport (for SPA/BFF) and
|
|
6
|
+
* NodeTransport (for server-side / CLI automation).
|
|
7
|
+
*
|
|
8
|
+
* Both transports prepend `/api/admin` to all request paths —
|
|
9
|
+
* domain methods only need to specify the resource path
|
|
10
|
+
* (e.g., `/organizations`).
|
|
11
|
+
*/
|
|
12
|
+
/** HTTP methods supported by the SDK */
|
|
13
|
+
export type HttpMethod = 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE';
|
|
14
|
+
/**
|
|
15
|
+
* Request passed to the transport.
|
|
16
|
+
*
|
|
17
|
+
* Domain methods construct these objects; the transport handles
|
|
18
|
+
* URL construction, authentication, headers, and serialization.
|
|
19
|
+
*/
|
|
20
|
+
export interface TransportRequest {
|
|
21
|
+
/** HTTP method */
|
|
22
|
+
method: HttpMethod;
|
|
23
|
+
/**
|
|
24
|
+
* Resource path (e.g., '/organizations', '/users/123').
|
|
25
|
+
* The transport prepends `baseUrl + '/api/admin'` to this path.
|
|
26
|
+
*/
|
|
27
|
+
path: string;
|
|
28
|
+
/** JSON request body (serialized by the transport) */
|
|
29
|
+
body?: unknown;
|
|
30
|
+
/** Additional headers to include in the request */
|
|
31
|
+
headers?: Record<string, string>;
|
|
32
|
+
/**
|
|
33
|
+
* Query parameters appended to the URL.
|
|
34
|
+
* Null/undefined values are skipped; all others are stringified.
|
|
35
|
+
*/
|
|
36
|
+
params?: Record<string, string | number | boolean | undefined | null>;
|
|
37
|
+
/** AbortSignal for request cancellation */
|
|
38
|
+
signal?: AbortSignal;
|
|
39
|
+
/**
|
|
40
|
+
* Response parsing mode:
|
|
41
|
+
* - 'json' (default): parses response body as JSON
|
|
42
|
+
* - 'raw': skips parsing, stores native Response in `raw` field
|
|
43
|
+
*
|
|
44
|
+
* Use 'raw' for binary downloads (exports, branding assets).
|
|
45
|
+
*/
|
|
46
|
+
responseType?: 'json' | 'raw';
|
|
47
|
+
/**
|
|
48
|
+
* Override the Content-Type header:
|
|
49
|
+
* - string: use this value as Content-Type
|
|
50
|
+
* - null: omit Content-Type entirely (lets runtime set it for FormData)
|
|
51
|
+
* - undefined (default): use 'application/json'
|
|
52
|
+
*/
|
|
53
|
+
contentType?: string | null;
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Response returned by the transport.
|
|
57
|
+
*
|
|
58
|
+
* Contains parsed response data and headers. For raw responses,
|
|
59
|
+
* the native Response object is available in the `raw` field.
|
|
60
|
+
*/
|
|
61
|
+
export interface TransportResponse {
|
|
62
|
+
/** HTTP status code */
|
|
63
|
+
status: number;
|
|
64
|
+
/** Response headers (lowercased keys) */
|
|
65
|
+
headers: Record<string, string>;
|
|
66
|
+
/** Parsed response body (undefined for 204 and raw responses) */
|
|
67
|
+
body: unknown;
|
|
68
|
+
/**
|
|
69
|
+
* Original Response object — available when `responseType` is 'raw'.
|
|
70
|
+
* Used for streaming binary data (exports, branding assets).
|
|
71
|
+
*/
|
|
72
|
+
raw?: Response;
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* Transport interface — environment-specific HTTP execution.
|
|
76
|
+
*
|
|
77
|
+
* Implementations handle URL construction, authentication,
|
|
78
|
+
* CSRF tokens, error mapping, and retry logic.
|
|
79
|
+
*/
|
|
80
|
+
export interface HttpTransport {
|
|
81
|
+
/** Execute an HTTP request and return the response */
|
|
82
|
+
request(req: TransportRequest): Promise<TransportResponse>;
|
|
83
|
+
}
|
|
84
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/transport/types.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,wCAAwC;AACxC,MAAM,MAAM,UAAU,GAAG,KAAK,GAAG,MAAM,GAAG,KAAK,GAAG,OAAO,GAAG,QAAQ,CAAC;AAErE;;;;;GAKG;AACH,MAAM,WAAW,gBAAgB;IAC/B,kBAAkB;IAClB,MAAM,EAAE,UAAU,CAAC;IAEnB;;;OAGG;IACH,IAAI,EAAE,MAAM,CAAC;IAEb,sDAAsD;IACtD,IAAI,CAAC,EAAE,OAAO,CAAC;IAEf,mDAAmD;IACnD,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAEjC;;;OAGG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,SAAS,GAAG,IAAI,CAAC,CAAC;IAEtE,2CAA2C;IAC3C,MAAM,CAAC,EAAE,WAAW,CAAC;IAErB;;;;;;OAMG;IACH,YAAY,CAAC,EAAE,MAAM,GAAG,KAAK,CAAC;IAE9B;;;;;OAKG;IACH,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAC7B;AAED;;;;;GAKG;AACH,MAAM,WAAW,iBAAiB;IAChC,uBAAuB;IACvB,MAAM,EAAE,MAAM,CAAC;IAEf,yCAAyC;IACzC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAEhC,iEAAiE;IACjE,IAAI,EAAE,OAAO,CAAC;IAEd;;;OAGG;IACH,GAAG,CAAC,EAAE,QAAQ,CAAC;CAChB;AAED;;;;;GAKG;AACH,MAAM,WAAW,aAAa;IAC5B,sDAAsD;IACtD,OAAO,CAAC,GAAG,EAAE,gBAAgB,GAAG,OAAO,CAAC,iBAAiB,CAAC,CAAC;CAC5D"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Transport abstraction types for the Porta SDK.
|
|
3
|
+
*
|
|
4
|
+
* The transport layer handles environment-specific HTTP execution.
|
|
5
|
+
* Two implementations exist: BrowserTransport (for SPA/BFF) and
|
|
6
|
+
* NodeTransport (for server-side / CLI automation).
|
|
7
|
+
*
|
|
8
|
+
* Both transports prepend `/api/admin` to all request paths —
|
|
9
|
+
* domain methods only need to specify the resource path
|
|
10
|
+
* (e.g., `/organizations`).
|
|
11
|
+
*/
|
|
12
|
+
export {};
|
|
13
|
+
//# sourceMappingURL=types.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/transport/types.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG"}
|