@classytic/arc-next 0.15.0 → 0.15.1
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/api.d.ts +26 -2
- package/dist/api.js +31 -4
- package/dist/client.d.ts +27 -1
- package/dist/client.js +12 -1
- package/package.json +1 -1
package/dist/api.d.ts
CHANGED
|
@@ -114,9 +114,33 @@ interface BaseApiConfig {
|
|
|
114
114
|
}
|
|
115
115
|
declare class BaseApi<TDoc = Record<string, unknown>, TCreate = Partial<TDoc>, TUpdate = Partial<TDoc>> {
|
|
116
116
|
readonly entity: string;
|
|
117
|
-
|
|
118
|
-
|
|
117
|
+
/**
|
|
118
|
+
* `basePath` stays OPTIONAL here — it holds the explicit per-instance
|
|
119
|
+
* override and nothing else. The resolved value is {@link basePath}, which is
|
|
120
|
+
* computed per read; baking it in would defeat the whole point (see below).
|
|
121
|
+
*/
|
|
122
|
+
readonly config: Required<Omit<BaseApiConfig, "client" | "basePath">> & Pick<BaseApiConfig, "basePath">;
|
|
119
123
|
private readonly requestFn;
|
|
124
|
+
/**
|
|
125
|
+
* Per-instance override → the deployment's declared prefix → `/api/v1`.
|
|
126
|
+
*
|
|
127
|
+
* The middle step is what lets a package construct its own API internally and
|
|
128
|
+
* still land on a host mounted elsewhere. Without it the only options were
|
|
129
|
+
* "every consumer passes `basePath`" — impossible for an instance a package
|
|
130
|
+
* owns — or "every host mounts at `/api/v1`".
|
|
131
|
+
*
|
|
132
|
+
* ## Why this is a GETTER and not resolved in the constructor
|
|
133
|
+
*
|
|
134
|
+
* `configureClient()` runs inside a `"use client"` provider, which is LATER
|
|
135
|
+
* than module evaluation. A package's API instance is created at import time,
|
|
136
|
+
* so a constructor-time read would capture `/api/v1` before the deployment
|
|
137
|
+
* ever declared `/api`, and the fallback would win permanently — producing a
|
|
138
|
+
* 404 that renders as an empty list, which is the failure this was meant to
|
|
139
|
+
* fix. An explicit `basePath` is unaffected either way.
|
|
140
|
+
*/
|
|
141
|
+
get basePath(): string;
|
|
142
|
+
/** `{basePath}/{entity}` — the resource root every request is built from. */
|
|
143
|
+
get baseUrl(): string;
|
|
120
144
|
constructor(entity: string, config?: BaseApiConfig);
|
|
121
145
|
/** Merge per-instance headers into request options */
|
|
122
146
|
private withHeaders;
|
package/dist/api.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { createQueryString, handleApiRequest } from "./client.js";
|
|
1
|
+
import { createQueryString, getBasePath, handleApiRequest } from "./client.js";
|
|
2
2
|
import { STANDARD_RESERVED_PARAMS } from "@classytic/repo-core/query-parser";
|
|
3
3
|
|
|
4
4
|
//#region src/api.ts
|
|
@@ -9,15 +9,43 @@ for (const verb of [
|
|
|
9
9
|
]) if (!STANDARD_RESERVED_PARAMS.has(verb)) throw new Error(`[arc-next] dispatch verb '${verb}' is not in repo-core STANDARD_RESERVED_PARAMS`);
|
|
10
10
|
var BaseApi = class {
|
|
11
11
|
entity;
|
|
12
|
+
/**
|
|
13
|
+
* `basePath` stays OPTIONAL here — it holds the explicit per-instance
|
|
14
|
+
* override and nothing else. The resolved value is {@link basePath}, which is
|
|
15
|
+
* computed per read; baking it in would defeat the whole point (see below).
|
|
16
|
+
*/
|
|
12
17
|
config;
|
|
13
|
-
baseUrl;
|
|
14
18
|
requestFn;
|
|
19
|
+
/**
|
|
20
|
+
* Per-instance override → the deployment's declared prefix → `/api/v1`.
|
|
21
|
+
*
|
|
22
|
+
* The middle step is what lets a package construct its own API internally and
|
|
23
|
+
* still land on a host mounted elsewhere. Without it the only options were
|
|
24
|
+
* "every consumer passes `basePath`" — impossible for an instance a package
|
|
25
|
+
* owns — or "every host mounts at `/api/v1`".
|
|
26
|
+
*
|
|
27
|
+
* ## Why this is a GETTER and not resolved in the constructor
|
|
28
|
+
*
|
|
29
|
+
* `configureClient()` runs inside a `"use client"` provider, which is LATER
|
|
30
|
+
* than module evaluation. A package's API instance is created at import time,
|
|
31
|
+
* so a constructor-time read would capture `/api/v1` before the deployment
|
|
32
|
+
* ever declared `/api`, and the fallback would win permanently — producing a
|
|
33
|
+
* 404 that renders as an empty list, which is the failure this was meant to
|
|
34
|
+
* fix. An explicit `basePath` is unaffected either way.
|
|
35
|
+
*/
|
|
36
|
+
get basePath() {
|
|
37
|
+
return this.config.basePath ?? getBasePath() ?? "/api/v1";
|
|
38
|
+
}
|
|
39
|
+
/** `{basePath}/{entity}` — the resource root every request is built from. */
|
|
40
|
+
get baseUrl() {
|
|
41
|
+
return `${this.basePath}/${this.entity}`;
|
|
42
|
+
}
|
|
15
43
|
constructor(entity, config = {}) {
|
|
16
44
|
this.entity = entity;
|
|
17
45
|
const client = config.client;
|
|
18
46
|
this.requestFn = typeof client === "function" ? (method, endpoint, options) => client().request(method, endpoint, options) : client?.request ?? handleApiRequest;
|
|
19
47
|
this.config = {
|
|
20
|
-
basePath: config.basePath
|
|
48
|
+
...config.basePath !== void 0 ? { basePath: config.basePath } : {},
|
|
21
49
|
defaultParams: {
|
|
22
50
|
limit: 10,
|
|
23
51
|
page: 1,
|
|
@@ -26,7 +54,6 @@ var BaseApi = class {
|
|
|
26
54
|
cache: config.cache ?? "no-store",
|
|
27
55
|
headers: { ...config.headers || {} }
|
|
28
56
|
};
|
|
29
|
-
this.baseUrl = `${this.config.basePath}/${this.entity}`;
|
|
30
57
|
}
|
|
31
58
|
/** Merge per-instance headers into request options */
|
|
32
59
|
withHeaders(options) {
|
package/dist/client.d.ts
CHANGED
|
@@ -278,6 +278,23 @@ interface ClientEncryptionConfig {
|
|
|
278
278
|
}
|
|
279
279
|
interface ClientConfig {
|
|
280
280
|
baseUrl: string;
|
|
281
|
+
/**
|
|
282
|
+
* Route prefix every API is mounted under, when it is not `/api/v1`.
|
|
283
|
+
*
|
|
284
|
+
* `BaseApi` defaults each instance to `/api/v1` and takes a per-instance
|
|
285
|
+
* `basePath` override. That covers an app's OWN api classes and nothing else:
|
|
286
|
+
* a package that constructs its own API internally — erp-shell's permission
|
|
287
|
+
* `platformApi`, an SDK preset — has no seam to be told, so on a host mounted
|
|
288
|
+
* anywhere but `/api/v1` it silently requests a URL that does not exist and
|
|
289
|
+
* the feature reads as "no data" rather than as a misconfiguration.
|
|
290
|
+
*
|
|
291
|
+
* Setting it here makes the mount point a property of the DEPLOYMENT, stated
|
|
292
|
+
* once, which is what it actually is. A per-instance `basePath` still wins,
|
|
293
|
+
* so nothing that already passes one changes.
|
|
294
|
+
*
|
|
295
|
+
* @example configureClient({ baseUrl, basePath: '/api' }) // host mounts at /api
|
|
296
|
+
*/
|
|
297
|
+
basePath?: string;
|
|
281
298
|
internalApiKey?: string;
|
|
282
299
|
defaultHeaders?: Record<string, string>;
|
|
283
300
|
/**
|
|
@@ -457,6 +474,15 @@ declare function configureClient(config: ClientConfig): void;
|
|
|
457
474
|
declare function getAuthMode(): "bearer" | "cookie" | "header";
|
|
458
475
|
/** Get the configured base URL. Returns empty string if not configured. */
|
|
459
476
|
declare function getBaseUrl(): string;
|
|
477
|
+
/**
|
|
478
|
+
* The deployment's route prefix, or `null` when it has not declared one.
|
|
479
|
+
*
|
|
480
|
+
* `null` rather than the `/api/v1` default on purpose: the default belongs to
|
|
481
|
+
* `BaseApi`, which is the one place that should own it. Returning it here would
|
|
482
|
+
* put the same literal in two files, and the next person to change one would
|
|
483
|
+
* have no way to know about the other.
|
|
484
|
+
*/
|
|
485
|
+
declare function getBasePath(): string | null;
|
|
460
486
|
/** Whether auto-idempotency is enabled on the global client. */
|
|
461
487
|
declare function isAutoIdempotency(): boolean;
|
|
462
488
|
/**
|
|
@@ -1016,4 +1042,4 @@ declare const arc: {
|
|
|
1016
1042
|
delete: <T = unknown>(path: string, opts?: ArcFetchOptions) => Promise<T>;
|
|
1017
1043
|
};
|
|
1018
1044
|
//#endregion
|
|
1019
|
-
export { AfterResponseContext, AfterResponseInterceptor, ApiRequestOptions, ArcApiError, ArcApiErrorOptions, ArcClient, ArcClientConfig, ArcErrorCode, ArcFetchOptions, AuthConfig, AuthErrorContext, AuthErrorHandler, BeforeRequestContext, BeforeRequestInterceptor, BlobResponse, ClientConfig, ClientEncryptionConfig, HttpMethod, KNOWN_ARC_ERROR_CODES, NextFetchOptions, QuotaDetails, RetryConfig, ServerClientConfig, StreamUrlProtocol, TextResponse, TierRequirement, ToastHandler, UseRouterHook, _getAuthErrorHandler, _isAuthRecoverable, _resetArcFetchClient, _resetAuthRecovery, _resetAuthWarnings, _resolveRefreshedToken, _runAuthRecovery, arc, arcAuthHeaders, arcFetch, buildStreamUrl, configureAuth, configureClient, createAuthAwareClient, createAuthRefreshHandler, createClient, createQueryString, createServerClient, getAuthContext, getAuthMode, getBaseUrl, getClientAuthContext, getQuotaDetails, getTierRequirement, handleApiRequest, hasGlobalStaticAuth, isAbortError, isArcApiError, isArcErrorCode, isAutoIdempotency, isDuplicateKeyError, isOrgContextRequiredError, isQuotaExceeded, isTierRequiredError, isValidationError };
|
|
1045
|
+
export { AfterResponseContext, AfterResponseInterceptor, ApiRequestOptions, ArcApiError, ArcApiErrorOptions, ArcClient, ArcClientConfig, ArcErrorCode, ArcFetchOptions, AuthConfig, AuthErrorContext, AuthErrorHandler, BeforeRequestContext, BeforeRequestInterceptor, BlobResponse, ClientConfig, ClientEncryptionConfig, HttpMethod, KNOWN_ARC_ERROR_CODES, NextFetchOptions, QuotaDetails, RetryConfig, ServerClientConfig, StreamUrlProtocol, TextResponse, TierRequirement, ToastHandler, UseRouterHook, _getAuthErrorHandler, _isAuthRecoverable, _resetArcFetchClient, _resetAuthRecovery, _resetAuthWarnings, _resolveRefreshedToken, _runAuthRecovery, arc, arcAuthHeaders, arcFetch, buildStreamUrl, configureAuth, configureClient, createAuthAwareClient, createAuthRefreshHandler, createClient, createQueryString, createServerClient, getAuthContext, getAuthMode, getBasePath, getBaseUrl, getClientAuthContext, getQuotaDetails, getTierRequirement, handleApiRequest, hasGlobalStaticAuth, isAbortError, isArcApiError, isArcErrorCode, isAutoIdempotency, isDuplicateKeyError, isOrgContextRequiredError, isQuotaExceeded, isTierRequiredError, isValidationError };
|
package/dist/client.js
CHANGED
|
@@ -337,6 +337,17 @@ function getAuthMode() {
|
|
|
337
337
|
function getBaseUrl() {
|
|
338
338
|
return clientConfig?.baseUrl ?? "";
|
|
339
339
|
}
|
|
340
|
+
/**
|
|
341
|
+
* The deployment's route prefix, or `null` when it has not declared one.
|
|
342
|
+
*
|
|
343
|
+
* `null` rather than the `/api/v1` default on purpose: the default belongs to
|
|
344
|
+
* `BaseApi`, which is the one place that should own it. Returning it here would
|
|
345
|
+
* put the same literal in two files, and the next person to change one would
|
|
346
|
+
* have no way to know about the other.
|
|
347
|
+
*/
|
|
348
|
+
function getBasePath() {
|
|
349
|
+
return clientConfig?.basePath ?? null;
|
|
350
|
+
}
|
|
340
351
|
/** Whether auto-idempotency is enabled on the global client. */
|
|
341
352
|
function isAutoIdempotency() {
|
|
342
353
|
return clientConfig?.autoIdempotency ?? false;
|
|
@@ -1276,4 +1287,4 @@ const arc = {
|
|
|
1276
1287
|
};
|
|
1277
1288
|
|
|
1278
1289
|
//#endregion
|
|
1279
|
-
export { ArcApiError, KNOWN_ARC_ERROR_CODES, _getAuthErrorHandler, _isAuthRecoverable, _resetArcFetchClient, _resetAuthRecovery, _resetAuthWarnings, _resolveRefreshedToken, _runAuthRecovery, arc, arcAuthHeaders, arcFetch, buildStreamUrl, configureAuth, configureClient, createAuthAwareClient, createAuthRefreshHandler, createClient, createQueryString, createServerClient, getAuthContext, getAuthMode, getBaseUrl, getClientAuthContext, getQuotaDetails, getTierRequirement, handleApiRequest, hasGlobalStaticAuth, isAbortError, isArcApiError, isArcErrorCode, isAutoIdempotency, isDuplicateKeyError, isOrgContextRequiredError, isQuotaExceeded, isTierRequiredError, isValidationError };
|
|
1290
|
+
export { ArcApiError, KNOWN_ARC_ERROR_CODES, _getAuthErrorHandler, _isAuthRecoverable, _resetArcFetchClient, _resetAuthRecovery, _resetAuthWarnings, _resolveRefreshedToken, _runAuthRecovery, arc, arcAuthHeaders, arcFetch, buildStreamUrl, configureAuth, configureClient, createAuthAwareClient, createAuthRefreshHandler, createClient, createQueryString, createServerClient, getAuthContext, getAuthMode, getBasePath, getBaseUrl, getClientAuthContext, getQuotaDetails, getTierRequirement, handleApiRequest, hasGlobalStaticAuth, isAbortError, isArcApiError, isArcErrorCode, isAutoIdempotency, isDuplicateKeyError, isOrgContextRequiredError, isQuotaExceeded, isTierRequiredError, isValidationError };
|