@portaidentity/sdk 1.12.0 → 1.13.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/CHANGELOG.md +10 -0
- package/README.md +69 -4
- package/dist/client.d.ts +1 -1
- package/dist/client.js +1 -1
- package/dist/transport/browser-transport.d.ts +7 -0
- package/dist/transport/browser-transport.d.ts.map +1 -1
- package/dist/transport/browser-transport.js +9 -4
- package/dist/transport/browser-transport.js.map +1 -1
- package/dist/transport/node-transport.d.ts +7 -0
- package/dist/transport/node-transport.d.ts.map +1 -1
- package/dist/transport/node-transport.js +7 -6
- package/dist/transport/node-transport.js.map +1 -1
- package/dist/transport/types.d.ts +1 -1
- package/dist/transport/utils.d.ts +2 -1
- package/dist/transport/utils.d.ts.map +1 -1
- package/dist/transport/utils.js +5 -3
- package/dist/transport/utils.js.map +1 -1
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,16 @@ All notable changes to this project will be documented in this file.
|
|
|
5
5
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
|
|
6
6
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
7
|
|
|
8
|
+
## [1.13.0] - 2026-10-24
|
|
9
|
+
|
|
10
|
+
Changed: Updated README.md to reflect recent changes in usage and examples.
|
|
11
|
+
Changed: Refactored client.ts for improved performance and enhanced API consistency.
|
|
12
|
+
Changed: Optimized browser-transport.ts for better handling of network requests.
|
|
13
|
+
Changed: Enhanced node-transport.ts to support additional transport methods.
|
|
14
|
+
Changed: Improved type definitions in types.ts for better type safety.
|
|
15
|
+
Changed: Streamlined utility functions in utils.ts for cleaner code.
|
|
16
|
+
Changed: Updated tests in browser-transport.test.ts and node-transport.test.ts for better coverage.
|
|
17
|
+
|
|
8
18
|
## [1.12.0] - 2026-10-23
|
|
9
19
|
|
|
10
20
|
Added
|
package/README.md
CHANGED
|
@@ -33,7 +33,7 @@ import { createBrowserTransport } from '@portaidentity/sdk/browser';
|
|
|
33
33
|
let csrfToken: string | null = null;
|
|
34
34
|
|
|
35
35
|
const transport = createBrowserTransport({
|
|
36
|
-
baseUrl: '
|
|
36
|
+
baseUrl: '', // same-origin BFF; the SDK adds the API prefix
|
|
37
37
|
getCsrfToken: () => csrfToken,
|
|
38
38
|
setCsrfToken: (token) => {
|
|
39
39
|
csrfToken = token;
|
|
@@ -64,7 +64,7 @@ import { createPortaClient } from '@portaidentity/sdk';
|
|
|
64
64
|
import { createNodeTransport, createTokenAuth } from '@portaidentity/sdk/node';
|
|
65
65
|
|
|
66
66
|
const transport = createNodeTransport({
|
|
67
|
-
baseUrl: 'https://porta.local:3443
|
|
67
|
+
baseUrl: 'https://porta.local:3443',
|
|
68
68
|
auth: createTokenAuth({ token: 'opaque-access-token' }),
|
|
69
69
|
});
|
|
70
70
|
|
|
@@ -96,7 +96,7 @@ import { createNodeTransport, createTokenAuth } from '@portaidentity/sdk/node';
|
|
|
96
96
|
|
|
97
97
|
const client = createPortaClient({
|
|
98
98
|
transport: createNodeTransport({
|
|
99
|
-
baseUrl: 'https://porta.example.com
|
|
99
|
+
baseUrl: 'https://porta.example.com',
|
|
100
100
|
auth: createTokenAuth({ token: process.env.PORTA_ACCESS_TOKEN! }),
|
|
101
101
|
}),
|
|
102
102
|
});
|
|
@@ -106,6 +106,71 @@ Client-credentials tokens carry no account identity and are rejected by `/api/ad
|
|
|
106
106
|
Do not use `createClientCredentialsAuth` for Admin API automation until service
|
|
107
107
|
accounts are supported.
|
|
108
108
|
|
|
109
|
+
### Tenant-scoped invitations from a BFF
|
|
110
|
+
|
|
111
|
+
Tenant applications can invite users without a control-plane service account.
|
|
112
|
+
The tenant route accepts either a confidential client using `client_credentials`
|
|
113
|
+
with the `org:user:invite` scope, or a tenant user's access token with the
|
|
114
|
+
`org:user:invite` permission in the token client's application.
|
|
115
|
+
|
|
116
|
+
Use `apiPrefix: '/api'` for the tenant route:
|
|
117
|
+
|
|
118
|
+
```typescript
|
|
119
|
+
import { createPortaClient } from '@portaidentity/sdk';
|
|
120
|
+
import {
|
|
121
|
+
createClientCredentialsAuth,
|
|
122
|
+
createNodeTransport,
|
|
123
|
+
createTokenAuth,
|
|
124
|
+
} from '@portaidentity/sdk/node';
|
|
125
|
+
|
|
126
|
+
// Background jobs: one tenant client, no refresh token or local credentials file.
|
|
127
|
+
const serviceClient = createPortaClient({
|
|
128
|
+
transport: createNodeTransport({
|
|
129
|
+
baseUrl: 'https://porta.example.com',
|
|
130
|
+
apiPrefix: '/api',
|
|
131
|
+
auth: createClientCredentialsAuth({
|
|
132
|
+
tokenEndpoint: 'https://porta.example.com/acme/token',
|
|
133
|
+
clientId: process.env.PORTA_TENANT_CLIENT_ID!,
|
|
134
|
+
clientSecret: process.env.PORTA_TENANT_CLIENT_SECRET!,
|
|
135
|
+
scope: 'org:user:invite',
|
|
136
|
+
}),
|
|
137
|
+
}),
|
|
138
|
+
});
|
|
139
|
+
|
|
140
|
+
// Interactive requests: forward the caller's Porta access token.
|
|
141
|
+
const userClient = createPortaClient({
|
|
142
|
+
transport: createNodeTransport({
|
|
143
|
+
baseUrl: 'https://porta.example.com',
|
|
144
|
+
apiPrefix: '/api',
|
|
145
|
+
auth: createTokenAuth({ token: userPortaAccessToken }),
|
|
146
|
+
}),
|
|
147
|
+
});
|
|
148
|
+
|
|
149
|
+
await (interactive ? userClient : serviceClient).users.invite({
|
|
150
|
+
organizationId: process.env.PORTA_TENANT_ORG_ID!,
|
|
151
|
+
email: 'new.user@example.com',
|
|
152
|
+
roles: [{ applicationId: process.env.PORTA_APP_ID!, roleId: roleId }],
|
|
153
|
+
});
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
The tenant route only allows roles owned by the token client's application.
|
|
157
|
+
Custom claim pre-assignment remains a control-plane capability in this
|
|
158
|
+
iteration. A tenant user cannot grant a role that exceeds their own live
|
|
159
|
+
permissions.
|
|
160
|
+
|
|
161
|
+
The service client must be configured with:
|
|
162
|
+
|
|
163
|
+
| Field | Value |
|
|
164
|
+
| ------------------------- | ------------------------ |
|
|
165
|
+
| `clientType` | `confidential` |
|
|
166
|
+
| `applicationType` | `web` |
|
|
167
|
+
| `grantTypes` | `['client_credentials']` |
|
|
168
|
+
| `scope` | `org:user:invite` |
|
|
169
|
+
| `tokenEndpointAuthMethod` | `client_secret_post` |
|
|
170
|
+
|
|
171
|
+
`createClientCredentialsAuth` sends the client secret in the form body, so the
|
|
172
|
+
client must allow `client_secret_post`.
|
|
173
|
+
|
|
109
174
|
### AI Agent Integration
|
|
110
175
|
|
|
111
176
|
```typescript
|
|
@@ -120,7 +185,7 @@ const tools = getToolDefinitions();
|
|
|
120
185
|
// Execute a tool call from an AI agent
|
|
121
186
|
const client = createPortaClient({
|
|
122
187
|
transport: createNodeTransport({
|
|
123
|
-
baseUrl: 'https://porta.example.com
|
|
188
|
+
baseUrl: 'https://porta.example.com',
|
|
124
189
|
auth: createTokenAuth({ token: process.env.PORTA_ACCESS_TOKEN! }),
|
|
125
190
|
}),
|
|
126
191
|
});
|
package/dist/client.d.ts
CHANGED
|
@@ -41,7 +41,7 @@ export interface PortaClient {
|
|
|
41
41
|
* import { createTokenAuth } from '@portaidentity/sdk/node';
|
|
42
42
|
*
|
|
43
43
|
* const transport = createNodeTransport({
|
|
44
|
-
* baseUrl: 'https://porta.local:3443
|
|
44
|
+
* baseUrl: 'https://porta.local:3443',
|
|
45
45
|
* auth: createTokenAuth({ token: 'my-bearer-token' }),
|
|
46
46
|
* });
|
|
47
47
|
*
|
package/dist/client.js
CHANGED
|
@@ -17,7 +17,7 @@ import { createOrganizationsDomain, createApplicationsDomain, createClientsDomai
|
|
|
17
17
|
* import { createTokenAuth } from '@portaidentity/sdk/node';
|
|
18
18
|
*
|
|
19
19
|
* const transport = createNodeTransport({
|
|
20
|
-
* baseUrl: 'https://porta.local:3443
|
|
20
|
+
* baseUrl: 'https://porta.local:3443',
|
|
21
21
|
* auth: createTokenAuth({ token: 'my-bearer-token' }),
|
|
22
22
|
* });
|
|
23
23
|
*
|
|
@@ -40,6 +40,13 @@ export interface BrowserTransportOptions {
|
|
|
40
40
|
* Provide a custom handler to override (e.g., show a login modal).
|
|
41
41
|
*/
|
|
42
42
|
onUnauthorized?: () => void;
|
|
43
|
+
/**
|
|
44
|
+
* API mount prefix.
|
|
45
|
+
*
|
|
46
|
+
* Defaults to `/api/admin` for the control-plane Admin API. Tenant-scoped
|
|
47
|
+
* calls use `/api`.
|
|
48
|
+
*/
|
|
49
|
+
apiPrefix?: string;
|
|
43
50
|
}
|
|
44
51
|
/**
|
|
45
52
|
* Creates a browser-oriented HTTP transport.
|
|
@@ -1 +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;
|
|
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;IAE5B;;;;;OAKG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,sBAAsB,CAAC,OAAO,EAAE,uBAAuB,GAAG,aAAa,CA2EtF"}
|
|
@@ -33,11 +33,11 @@ import { buildRequestUrl, extractResponseHeaders, buildCommonHeaders, serializeB
|
|
|
33
33
|
* ```
|
|
34
34
|
*/
|
|
35
35
|
export function createBrowserTransport(options) {
|
|
36
|
-
const { baseUrl, getCsrfToken, setCsrfToken, onUnauthorized } = options;
|
|
36
|
+
const { baseUrl, getCsrfToken, setCsrfToken, onUnauthorized, apiPrefix } = options;
|
|
37
37
|
return {
|
|
38
38
|
async request(req) {
|
|
39
|
-
// Build full URL with
|
|
40
|
-
const url = buildRequestUrl(baseUrl, req.path, req.params);
|
|
39
|
+
// Build full URL with the configured API prefix and query params
|
|
40
|
+
const url = buildRequestUrl(baseUrl, req.path, req.params, apiPrefix);
|
|
41
41
|
// Build common headers (Accept, Content-Type, SDK version)
|
|
42
42
|
const headers = buildCommonHeaders(req);
|
|
43
43
|
// Add CSRF token for state-changing methods
|
|
@@ -85,7 +85,12 @@ export function createBrowserTransport(options) {
|
|
|
85
85
|
}
|
|
86
86
|
// 2xx + raw — return with native Response for binary streaming
|
|
87
87
|
if (req.responseType === 'raw') {
|
|
88
|
-
return {
|
|
88
|
+
return {
|
|
89
|
+
status: response.status,
|
|
90
|
+
headers: responseHeaders,
|
|
91
|
+
body: undefined,
|
|
92
|
+
raw: response,
|
|
93
|
+
};
|
|
89
94
|
}
|
|
90
95
|
// 2xx + json — parse body and return
|
|
91
96
|
const body = await response.json();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"browser-transport.js","sourceRoot":"","sources":["../../src/transport/browser-transport.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAGH,OAAO,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;AACxD,OAAO,EACL,eAAe,EACf,sBAAsB,EACtB,kBAAkB,EAClB,aAAa,EACb,aAAa,GACd,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"browser-transport.js","sourceRoot":"","sources":["../../src/transport/browser-transport.ts"],"names":[],"mappings":"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"}
|
|
@@ -27,6 +27,13 @@ export interface NodeTransportOptions {
|
|
|
27
27
|
* a token refresh and one automatic retry.
|
|
28
28
|
*/
|
|
29
29
|
auth: AuthProvider;
|
|
30
|
+
/**
|
|
31
|
+
* API mount prefix.
|
|
32
|
+
*
|
|
33
|
+
* Defaults to `/api/admin` for the control-plane Admin API. Tenant-scoped
|
|
34
|
+
* BFF calls use `/api`.
|
|
35
|
+
*/
|
|
36
|
+
apiPrefix?: string;
|
|
30
37
|
}
|
|
31
38
|
/**
|
|
32
39
|
* Creates a Node.js / server-side HTTP transport.
|
|
@@ -1 +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"}
|
|
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;IAEnB;;;;;OAKG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,oBAAoB,GAAG,aAAa,CAqBhF"}
|
|
@@ -31,17 +31,17 @@ import { buildRequestUrl, extractResponseHeaders, buildCommonHeaders, serializeB
|
|
|
31
31
|
* ```
|
|
32
32
|
*/
|
|
33
33
|
export function createNodeTransport(options) {
|
|
34
|
-
const { baseUrl, auth } = options;
|
|
34
|
+
const { baseUrl, auth, apiPrefix } = options;
|
|
35
35
|
return {
|
|
36
36
|
async request(req) {
|
|
37
37
|
// Get access token from auth provider
|
|
38
38
|
const token = await auth.getToken();
|
|
39
39
|
// Execute the initial request
|
|
40
|
-
const response = await executeRequest(baseUrl, req, token);
|
|
40
|
+
const response = await executeRequest(baseUrl, req, token, apiPrefix);
|
|
41
41
|
// 401 + refreshToken available → attempt token refresh and retry once
|
|
42
42
|
if (response.status === 401 && auth.refreshToken) {
|
|
43
43
|
const newToken = await auth.refreshToken();
|
|
44
|
-
const retryResponse = await executeRequest(baseUrl, req, newToken);
|
|
44
|
+
const retryResponse = await executeRequest(baseUrl, req, newToken, apiPrefix);
|
|
45
45
|
return processResponse(retryResponse, req);
|
|
46
46
|
}
|
|
47
47
|
return processResponse(response, req);
|
|
@@ -58,11 +58,12 @@ export function createNodeTransport(options) {
|
|
|
58
58
|
* @param baseUrl - Base URL of the Porta instance
|
|
59
59
|
* @param req - The transport request to execute
|
|
60
60
|
* @param token - Bearer access token
|
|
61
|
+
* @param apiPrefix - API mount prefix
|
|
61
62
|
* @returns The raw fetch Response
|
|
62
63
|
*/
|
|
63
|
-
async function executeRequest(baseUrl, req, token) {
|
|
64
|
-
// Build full URL with
|
|
65
|
-
const url = buildRequestUrl(baseUrl, req.path, req.params);
|
|
64
|
+
async function executeRequest(baseUrl, req, token, apiPrefix) {
|
|
65
|
+
// Build full URL with the configured API prefix and query params
|
|
66
|
+
const url = buildRequestUrl(baseUrl, req.path, req.params, apiPrefix);
|
|
66
67
|
// Build common headers (Accept, Content-Type, SDK version)
|
|
67
68
|
const headers = buildCommonHeaders(req);
|
|
68
69
|
// Add Bearer token authentication
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"node-transport.js","sourceRoot":"","sources":["../../src/transport/node-transport.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAIH,OAAO,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;AACxD,OAAO,EACL,eAAe,EACf,sBAAsB,EACtB,kBAAkB,EAClB,aAAa,EACb,aAAa,GACd,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"node-transport.js","sourceRoot":"","sources":["../../src/transport/node-transport.ts"],"names":[],"mappings":"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"}
|
|
@@ -22,7 +22,7 @@ export interface TransportRequest {
|
|
|
22
22
|
method: HttpMethod;
|
|
23
23
|
/**
|
|
24
24
|
* Resource path (e.g., '/organizations', '/users/123').
|
|
25
|
-
* The transport prepends
|
|
25
|
+
* The transport prepends the configured API prefix (default `/api/admin`).
|
|
26
26
|
*/
|
|
27
27
|
path: string;
|
|
28
28
|
/** JSON request body (serialized by the transport) */
|
|
@@ -17,9 +17,10 @@
|
|
|
17
17
|
* @param baseUrl - Base URL (e.g., 'https://porta.example.com' or '' for same-origin)
|
|
18
18
|
* @param path - Resource path (e.g., '/organizations', '/users/123')
|
|
19
19
|
* @param params - Optional query parameters (null/undefined values are skipped)
|
|
20
|
+
* @param apiPrefix - API mount prefix; defaults to '/api/admin'
|
|
20
21
|
* @returns Complete URL string with query parameters
|
|
21
22
|
*/
|
|
22
|
-
export declare function buildRequestUrl(baseUrl: string, path: string, params?: Record<string, string | number | boolean | undefined | null
|
|
23
|
+
export declare function buildRequestUrl(baseUrl: string, path: string, params?: Record<string, string | number | boolean | undefined | null>, apiPrefix?: string): string;
|
|
23
24
|
/**
|
|
24
25
|
* Extracts response headers as a lowercased-key record.
|
|
25
26
|
*
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../src/transport/utils.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAIH
|
|
1
|
+
{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../src/transport/utils.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAIH;;;;;;;;;;;GAWG;AACH,wBAAgB,eAAe,CAC7B,OAAO,EAAE,MAAM,EACf,IAAI,EAAE,MAAM,EACZ,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,SAAS,GAAG,IAAI,CAAC,EACrE,SAAS,SAAe,GACvB,MAAM,CAcR;AAED;;;;;;;;;GASG;AACH,wBAAgB,sBAAsB,CAAC,QAAQ,EAAE,QAAQ,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAMjF;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,kBAAkB,CAAC,GAAG,EAAE;IACtC,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAClC,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAqBzB;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,OAAO,EAAE,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,GAAG,QAAQ,GAAG,SAAS,CAK9F;AAED;;;;;;;;;GASG;AACH,wBAAsB,aAAa,CAAC,QAAQ,EAAE,QAAQ,GAAG,OAAO,CAAC,OAAO,CAAC,CAMxE"}
|
package/dist/transport/utils.js
CHANGED
|
@@ -18,10 +18,12 @@ import { SDK_VERSION } from '../version.js';
|
|
|
18
18
|
* @param baseUrl - Base URL (e.g., 'https://porta.example.com' or '' for same-origin)
|
|
19
19
|
* @param path - Resource path (e.g., '/organizations', '/users/123')
|
|
20
20
|
* @param params - Optional query parameters (null/undefined values are skipped)
|
|
21
|
+
* @param apiPrefix - API mount prefix; defaults to '/api/admin'
|
|
21
22
|
* @returns Complete URL string with query parameters
|
|
22
23
|
*/
|
|
23
|
-
export function buildRequestUrl(baseUrl, path, params) {
|
|
24
|
-
const
|
|
24
|
+
export function buildRequestUrl(baseUrl, path, params, apiPrefix = '/api/admin') {
|
|
25
|
+
const prefix = apiPrefix.replace(/\/+$/, '');
|
|
26
|
+
const url = `${baseUrl}${prefix}${path}`;
|
|
25
27
|
if (!params)
|
|
26
28
|
return url;
|
|
27
29
|
const parts = [];
|
|
@@ -67,7 +69,7 @@ export function extractResponseHeaders(response) {
|
|
|
67
69
|
*/
|
|
68
70
|
export function buildCommonHeaders(req) {
|
|
69
71
|
const headers = {
|
|
70
|
-
|
|
72
|
+
Accept: 'application/json',
|
|
71
73
|
'X-Porta-SDK-Version': SDK_VERSION,
|
|
72
74
|
};
|
|
73
75
|
// Content-Type: null → omit (FormData), string → use it, undefined → json if body
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"utils.js","sourceRoot":"","sources":["../../src/transport/utils.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAE5C
|
|
1
|
+
{"version":3,"file":"utils.js","sourceRoot":"","sources":["../../src/transport/utils.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAE5C;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,eAAe,CAC7B,OAAe,EACf,IAAY,EACZ,MAAqE,EACrE,SAAS,GAAG,YAAY;IAExB,MAAM,MAAM,GAAG,SAAS,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;IAC7C,MAAM,GAAG,GAAG,GAAG,OAAO,GAAG,MAAM,GAAG,IAAI,EAAE,CAAC;IAEzC,IAAI,CAAC,MAAM;QAAE,OAAO,GAAG,CAAC;IAExB,MAAM,KAAK,GAAa,EAAE,CAAC;IAC3B,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC;QAClD,IAAI,KAAK,KAAK,IAAI,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;YAC1C,KAAK,CAAC,IAAI,CAAC,GAAG,kBAAkB,CAAC,GAAG,CAAC,IAAI,kBAAkB,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC;QAChF,CAAC;IACH,CAAC;IAED,OAAO,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,GAAG,IAAI,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC;AAC9D,CAAC;AAED;;;;;;;;;GASG;AACH,MAAM,UAAU,sBAAsB,CAAC,QAAkB;IACvD,MAAM,OAAO,GAA2B,EAAE,CAAC;IAC3C,QAAQ,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,KAAK,EAAE,GAAG,EAAE,EAAE;QACtC,OAAO,CAAC,GAAG,CAAC,WAAW,EAAE,CAAC,GAAG,KAAK,CAAC;IACrC,CAAC,CAAC,CAAC;IACH,OAAO,OAAO,CAAC;AACjB,CAAC;AAED;;;;;;;;;;;;;;;GAeG;AACH,MAAM,UAAU,kBAAkB,CAAC,GAIlC;IACC,MAAM,OAAO,GAA2B;QACtC,MAAM,EAAE,kBAAkB;QAC1B,qBAAqB,EAAE,WAAW;KACnC,CAAC;IAEF,kFAAkF;IAClF,IAAI,GAAG,CAAC,WAAW,KAAK,IAAI,EAAE,CAAC;QAC7B,6DAA6D;IAC/D,CAAC;SAAM,IAAI,GAAG,CAAC,WAAW,EAAE,CAAC;QAC3B,OAAO,CAAC,cAAc,CAAC,GAAG,GAAG,CAAC,WAAW,CAAC;IAC5C,CAAC;SAAM,IAAI,GAAG,CAAC,IAAI,KAAK,SAAS,EAAE,CAAC;QAClC,OAAO,CAAC,cAAc,CAAC,GAAG,kBAAkB,CAAC;IAC/C,CAAC;IAED,oDAAoD;IACpD,IAAI,GAAG,CAAC,OAAO,EAAE,CAAC;QAChB,MAAM,CAAC,MAAM,CAAC,OAAO,EAAE,GAAG,CAAC,OAAO,CAAC,CAAC;IACtC,CAAC;IAED,OAAO,OAAO,CAAC;AACjB,CAAC;AAED;;;;;;;;;;GAUG;AACH,MAAM,UAAU,aAAa,CAAC,IAAa,EAAE,WAA2B;IACtE,IAAI,IAAI,KAAK,SAAS;QAAE,OAAO,SAAS,CAAC;IACzC,kDAAkD;IAClD,IAAI,WAAW,KAAK,IAAI;QAAE,OAAO,IAAgB,CAAC;IAClD,OAAO,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;AAC9B,CAAC;AAED;;;;;;;;;GASG;AACH,MAAM,CAAC,KAAK,UAAU,aAAa,CAAC,QAAkB;IACpD,IAAI,CAAC;QACH,OAAO,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC;IAC/B,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,SAAS,CAAC;IACnB,CAAC;AACH,CAAC"}
|
package/dist/version.d.ts
CHANGED
package/dist/version.js
CHANGED