asma-core-helpers 0.10.0 → 0.12.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/lib/helpers/createTadaBrowserClient.d.ts +53 -0
- package/lib/helpers/createTadaBrowserClient.d.ts.map +1 -0
- package/lib/helpers/createTadaBrowserClient.js +76 -0
- package/lib/helpers/createTadaBrowserClient.js.map +1 -0
- package/lib/helpers/generateEnvConfigsBindings.d.ts +1 -1
- package/lib/helpers/generateEnvConfigsBindings.d.ts.map +1 -1
- package/lib/helpers/urql.d.ts +4 -0
- package/lib/helpers/urql.d.ts.map +1 -0
- package/lib/helpers/urql.js +3 -0
- package/lib/helpers/urql.js.map +1 -0
- package/lib/index.d.ts +2 -0
- package/lib/index.d.ts.map +1 -1
- package/lib/index.js +1 -0
- package/lib/index.js.map +1 -1
- package/package.json +8 -3
- package/src/helpers/createTadaBrowserClient.ts +127 -0
- package/src/helpers/generateEnvConfigsBindings.ts +1 -1
- package/src/helpers/urql.ts +3 -0
- package/src/index.ts +3 -0
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* createTadaBrowserClient — shared urql client factory for ASMA frontend apps.
|
|
3
|
+
*
|
|
4
|
+
* Wraps the urql core (fetchExchange + optional service-specific exchanges) with
|
|
5
|
+
* an authExchange that attaches a JWT Bearer token and refreshes on 401.
|
|
6
|
+
*
|
|
7
|
+
* URL resolution stays in the app (imports EnvConfigs from asma-helpers);
|
|
8
|
+
* this factory accepts the resolved URL so it has zero dependency on asma-helpers.
|
|
9
|
+
*
|
|
10
|
+
* @see asma-modules/_docs/frontend/operations/2026-07-11-23-00-runbook-graphql-schema-generation-secrets.md
|
|
11
|
+
*/
|
|
12
|
+
import { type Client, type ClientOptions, type Exchange } from '@urql/core';
|
|
13
|
+
/**
|
|
14
|
+
* Contributes service-specific exchanges (e.g. the Adopus per-tenant namespace
|
|
15
|
+
* rewrite) without baking that knowledge into the generic factory. Called once
|
|
16
|
+
* per client build with the resolved endpoint; returned exchanges are inserted
|
|
17
|
+
* just before `fetchExchange` (and after `authExchange`).
|
|
18
|
+
*/
|
|
19
|
+
export type ResolveExchanges = (ctx: {
|
|
20
|
+
/** The fully-resolved GraphQL endpoint URL. */
|
|
21
|
+
url: string;
|
|
22
|
+
/** Resolves the current JWT (may be stale — the auth exchange handles refresh). */
|
|
23
|
+
getJwt: () => Promise<string | undefined>;
|
|
24
|
+
}) => Exchange[] | Promise<Exchange[]>;
|
|
25
|
+
export interface CreateTadaBrowserClientOptions {
|
|
26
|
+
/** Fully-resolved GraphQL endpoint URL (caller resolves via EnvConfigs / srv_urls). */
|
|
27
|
+
url: string;
|
|
28
|
+
/** Resolves the current JWT. Typically `getCachedJwt` from asma-core-react. */
|
|
29
|
+
getJwt: () => Promise<string | undefined>;
|
|
30
|
+
/** Returns true when the cached JWT is still valid. Typically `isJwtValid` from asma-core-react. */
|
|
31
|
+
isJwtValid: () => boolean;
|
|
32
|
+
/** Optional service-specific exchanges injected before fetchExchange. */
|
|
33
|
+
resolveExchanges?: ResolveExchanges;
|
|
34
|
+
/** Passthrough to urql ClientOptions (url is overridden by the `url` param above). */
|
|
35
|
+
clientOptions?: Partial<ClientOptions>;
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Creates a configured, authenticated urql Client for an ASMA frontend app.
|
|
39
|
+
*
|
|
40
|
+
* Exchange order (first = outermost):
|
|
41
|
+
* 1. authExchange — attach Bearer token, refresh on 401
|
|
42
|
+
* 2. resolveExchanges — optional service-specific transforms (e.g. namespace)
|
|
43
|
+
* 3. fetchExchange — standard HTTP fetch
|
|
44
|
+
* 4. caller-provided — appended via clientOptions.exchanges (end of pipeline)
|
|
45
|
+
*/
|
|
46
|
+
export declare function createTadaBrowserClient({ url, getJwt, isJwtValid, resolveExchanges, clientOptions, }: CreateTadaBrowserClientOptions): {
|
|
47
|
+
getClient: () => Promise<Client>;
|
|
48
|
+
createClient: (opts?: {
|
|
49
|
+
clientOptions?: Partial<ClientOptions>;
|
|
50
|
+
anonymous?: boolean;
|
|
51
|
+
}) => Promise<Client>;
|
|
52
|
+
};
|
|
53
|
+
//# sourceMappingURL=createTadaBrowserClient.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"createTadaBrowserClient.d.ts","sourceRoot":"","sources":["../../src/helpers/createTadaBrowserClient.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AACH,OAAO,EACH,KAAK,MAAM,EACX,KAAK,aAAa,EAElB,KAAK,QAAQ,EAEhB,MAAM,YAAY,CAAA;AAGnB;;;;;GAKG;AACH,MAAM,MAAM,gBAAgB,GAAG,CAAC,GAAG,EAAE;IACjC,+CAA+C;IAC/C,GAAG,EAAE,MAAM,CAAA;IACX,mFAAmF;IACnF,MAAM,EAAE,MAAM,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAAA;CAC5C,KAAK,QAAQ,EAAE,GAAG,OAAO,CAAC,QAAQ,EAAE,CAAC,CAAA;AAEtC,MAAM,WAAW,8BAA8B;IAC3C,uFAAuF;IACvF,GAAG,EAAE,MAAM,CAAA;IACX,+EAA+E;IAC/E,MAAM,EAAE,MAAM,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAAA;IACzC,oGAAoG;IACpG,UAAU,EAAE,MAAM,OAAO,CAAA;IACzB,yEAAyE;IACzE,gBAAgB,CAAC,EAAE,gBAAgB,CAAA;IACnC,sFAAsF;IACtF,aAAa,CAAC,EAAE,OAAO,CAAC,aAAa,CAAC,CAAA;CACzC;AAED;;;;;;;;GAQG;AACH,wBAAgB,uBAAuB,CAAC,EACpC,GAAG,EACH,MAAM,EACN,UAAU,EACV,gBAAgB,EAChB,aAAa,GAChB,EAAE,8BAA8B,GAAG;IAAE,SAAS,EAAE,MAAM,OAAO,CAAC,MAAM,CAAC,CAAC;IAAC,YAAY,EAAE,CAAC,IAAI,CAAC,EAAE;QAAE,aAAa,CAAC,EAAE,OAAO,CAAC,aAAa,CAAC,CAAC;QAAC,SAAS,CAAC,EAAE,OAAO,CAAA;KAAE,KAAK,OAAO,CAAC,MAAM,CAAC,CAAA;CAAE,CAiElL"}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* createTadaBrowserClient — shared urql client factory for ASMA frontend apps.
|
|
3
|
+
*
|
|
4
|
+
* Wraps the urql core (fetchExchange + optional service-specific exchanges) with
|
|
5
|
+
* an authExchange that attaches a JWT Bearer token and refreshes on 401.
|
|
6
|
+
*
|
|
7
|
+
* URL resolution stays in the app (imports EnvConfigs from asma-helpers);
|
|
8
|
+
* this factory accepts the resolved URL so it has zero dependency on asma-helpers.
|
|
9
|
+
*
|
|
10
|
+
* @see asma-modules/_docs/frontend/operations/2026-07-11-23-00-runbook-graphql-schema-generation-secrets.md
|
|
11
|
+
*/
|
|
12
|
+
import { createClient, fetchExchange, } from '@urql/core';
|
|
13
|
+
import { authExchange } from '@urql/exchange-auth';
|
|
14
|
+
/**
|
|
15
|
+
* Creates a configured, authenticated urql Client for an ASMA frontend app.
|
|
16
|
+
*
|
|
17
|
+
* Exchange order (first = outermost):
|
|
18
|
+
* 1. authExchange — attach Bearer token, refresh on 401
|
|
19
|
+
* 2. resolveExchanges — optional service-specific transforms (e.g. namespace)
|
|
20
|
+
* 3. fetchExchange — standard HTTP fetch
|
|
21
|
+
* 4. caller-provided — appended via clientOptions.exchanges (end of pipeline)
|
|
22
|
+
*/
|
|
23
|
+
export function createTadaBrowserClient({ url, getJwt, isJwtValid, resolveExchanges, clientOptions, }) {
|
|
24
|
+
let tadaClient;
|
|
25
|
+
const getClient = async () => {
|
|
26
|
+
tadaClient = await buildClient({ clientOptions });
|
|
27
|
+
return tadaClient;
|
|
28
|
+
};
|
|
29
|
+
async function buildClient(opts) {
|
|
30
|
+
const _clientOptions = { ...(opts?.clientOptions ?? {}) };
|
|
31
|
+
const anonymous = opts?.anonymous;
|
|
32
|
+
_clientOptions.url = url;
|
|
33
|
+
_clientOptions.preferGetMethod = false;
|
|
34
|
+
_clientOptions.requestPolicy = 'cache-and-network';
|
|
35
|
+
// Start with fetchExchange + caller-provided exchanges
|
|
36
|
+
_clientOptions.exchanges = [
|
|
37
|
+
fetchExchange,
|
|
38
|
+
...(_clientOptions.exchanges || []),
|
|
39
|
+
];
|
|
40
|
+
// Inject service-specific exchanges before fetchExchange
|
|
41
|
+
if (resolveExchanges) {
|
|
42
|
+
const extra = await resolveExchanges({
|
|
43
|
+
getJwt,
|
|
44
|
+
url,
|
|
45
|
+
});
|
|
46
|
+
if (extra.length) {
|
|
47
|
+
_clientOptions.exchanges.unshift(...extra);
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
// authExchange is outermost (first to receive the operation)
|
|
51
|
+
if (!anonymous) {
|
|
52
|
+
_clientOptions.exchanges.unshift(authExchange(async (utils) => {
|
|
53
|
+
const token = await getJwt();
|
|
54
|
+
return {
|
|
55
|
+
addAuthToOperation(operation) {
|
|
56
|
+
return utils.appendHeaders(operation, {
|
|
57
|
+
Authorization: `Bearer ${token}`,
|
|
58
|
+
});
|
|
59
|
+
},
|
|
60
|
+
didAuthError(error) {
|
|
61
|
+
return error.response.status === 401;
|
|
62
|
+
},
|
|
63
|
+
async refreshAuth() {
|
|
64
|
+
tadaClient = await buildClient({ clientOptions: opts?.clientOptions });
|
|
65
|
+
},
|
|
66
|
+
willAuthError() {
|
|
67
|
+
return !isJwtValid();
|
|
68
|
+
},
|
|
69
|
+
};
|
|
70
|
+
}));
|
|
71
|
+
}
|
|
72
|
+
return createClient(_clientOptions);
|
|
73
|
+
}
|
|
74
|
+
return { getClient, createClient: buildClient };
|
|
75
|
+
}
|
|
76
|
+
//# sourceMappingURL=createTadaBrowserClient.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"createTadaBrowserClient.js","sourceRoot":"","sources":["../../src/helpers/createTadaBrowserClient.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AACH,OAAO,EAGH,YAAY,EAEZ,aAAa,GAChB,MAAM,YAAY,CAAA;AACnB,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAA;AA4BlD;;;;;;;;GAQG;AACH,MAAM,UAAU,uBAAuB,CAAC,EACpC,GAAG,EACH,MAAM,EACN,UAAU,EACV,gBAAgB,EAChB,aAAa,GACgB;IAC7B,IAAI,UAA8B,CAAA;IAElC,MAAM,SAAS,GAAG,KAAK,IAAI,EAAE;QACzB,UAAU,GAAG,MAAM,WAAW,CAAC,EAAE,aAAa,EAAE,CAAC,CAAA;QACjD,OAAO,UAAU,CAAA;IACrB,CAAC,CAAA;IAED,KAAK,UAAU,WAAW,CAAC,IAG1B;QACG,MAAM,cAAc,GAA2B,EAAE,GAAG,CAAC,IAAI,EAAE,aAAa,IAAI,EAAE,CAAC,EAAE,CAAA;QACjF,MAAM,SAAS,GAAG,IAAI,EAAE,SAAS,CAAA;QAEjC,cAAc,CAAC,GAAG,GAAG,GAAG,CAAA;QACxB,cAAc,CAAC,eAAe,GAAG,KAAK,CAAA;QACtC,cAAc,CAAC,aAAa,GAAG,mBAAmB,CAAA;QAElD,uDAAuD;QACvD,cAAc,CAAC,SAAS,GAAG;YACvB,aAAa;YACb,GAAG,CAAC,cAAc,CAAC,SAAS,IAAI,EAAE,CAAC;SACtC,CAAA;QAED,yDAAyD;QACzD,IAAI,gBAAgB,EAAE,CAAC;YACnB,MAAM,KAAK,GAAG,MAAM,gBAAgB,CAAC;gBACjC,MAAM;gBACN,GAAG;aACN,CAAC,CAAA;YACF,IAAI,KAAK,CAAC,MAAM,EAAE,CAAC;gBACf,cAAc,CAAC,SAAS,CAAC,OAAO,CAAC,GAAG,KAAK,CAAC,CAAA;YAC9C,CAAC;QACL,CAAC;QAED,6DAA6D;QAC7D,IAAI,CAAC,SAAS,EAAE,CAAC;YACb,cAAc,CAAC,SAAS,CAAC,OAAO,CAC5B,YAAY,CAAC,KAAK,EAAE,KAAK,EAAE,EAAE;gBACzB,MAAM,KAAK,GAAG,MAAM,MAAM,EAAE,CAAA;gBAC5B,OAAO;oBACH,kBAAkB,CAAC,SAAS;wBACxB,OAAO,KAAK,CAAC,aAAa,CAAC,SAAS,EAAE;4BAClC,aAAa,EAAE,UAAU,KAAK,EAAE;yBACnC,CAAC,CAAA;oBACN,CAAC;oBACD,YAAY,CAAC,KAAK;wBACd,OAAO,KAAK,CAAC,QAAQ,CAAC,MAAM,KAAK,GAAG,CAAA;oBACxC,CAAC;oBACD,KAAK,CAAC,WAAW;wBACb,UAAU,GAAG,MAAM,WAAW,CAAC,EAAE,aAAa,EAAE,IAAI,EAAE,aAAa,EAAE,CAAC,CAAA;oBAC1E,CAAC;oBACD,aAAa;wBACT,OAAO,CAAC,UAAU,EAAE,CAAA;oBACxB,CAAC;iBACJ,CAAA;YACL,CAAC,CAAC,CACL,CAAA;QACL,CAAC;QAED,OAAO,YAAY,CAAC,cAA+B,CAAC,CAAA;IACxD,CAAC;IAED,OAAO,EAAE,SAAS,EAAE,YAAY,EAAE,WAAW,EAAE,CAAA;AACnD,CAAC"}
|
|
@@ -15,7 +15,7 @@ type IEnvironmentUrls = ReturnType<typeof EnvironmentsUrls1>;
|
|
|
15
15
|
export type IKeyEnvironmentUrls = keyof IEnvironmentUrls;
|
|
16
16
|
type StartsWith<T, U extends string> = T extends `${U}${infer _}` ? T : never;
|
|
17
17
|
type SRVKeys<T> = {
|
|
18
|
-
[K in keyof T as StartsWith<K & string, 'SRV_'>]: T[K];
|
|
18
|
+
[K in keyof T as StartsWith<K & string, 'SRV_'> | StartsWith<K & string, 'HSR_'>]: T[K];
|
|
19
19
|
};
|
|
20
20
|
export type IEnvironmentUrlsGenQLOnly = SRVKeys<IEnvironmentUrls>;
|
|
21
21
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"generateEnvConfigsBindings.d.ts","sourceRoot":"","sources":["../../src/helpers/generateEnvConfigsBindings.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAA;AAGzD,UAAU,SAAS;IACf,WAAW,CAAC,EAAE,OAAO,CAAA;IACrB,sBAAsB,CAAC,EAAE,MAAM,CAAA;IAC/B,iBAAiB,CAAC,EAAE,MAAM,CAAA;IAE1B,iBAAiB,CAAC,EAAE,OAAO,CAAA;IAC3B,sBAAsB,CAAC,EAAE,MAAM,CAAA;IAE/B,2BAA2B,CAAC,EAAE,OAAO,CAAA;IACrC,uBAAuB,CAAC,EAAE,OAAO,CAAA;IACjC,0BAA0B,CAAC,EAAE,OAAO,CAAA;IACpC,sBAAsB,CAAC,EAAE,OAAO,CAAA;IAChC,4BAA4B,CAAC,EAAE,MAAM,EAAE,CAAA;CAC1C;AAED,KAAK,gBAAgB,GAAG,UAAU,CAAC,OAAO,iBAAiB,CAAC,CAAA;AAE5D,MAAM,MAAM,mBAAmB,GAAG,MAAM,gBAAgB,CAAA;AAExD,KAAK,UAAU,CAAC,CAAC,EAAE,CAAC,SAAS,MAAM,IAAI,CAAC,SAAS,GAAG,CAAC,GAAG,MAAM,CAAC,EAAE,GAAG,CAAC,GAAG,KAAK,CAAA;AAE7E,KAAK,OAAO,CAAC,CAAC,IAAI;KACb,CAAC,IAAI,MAAM,CAAC,IAAI,UAAU,CAAC,CAAC,GAAG,MAAM,EAAE,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"generateEnvConfigsBindings.d.ts","sourceRoot":"","sources":["../../src/helpers/generateEnvConfigsBindings.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAA;AAGzD,UAAU,SAAS;IACf,WAAW,CAAC,EAAE,OAAO,CAAA;IACrB,sBAAsB,CAAC,EAAE,MAAM,CAAA;IAC/B,iBAAiB,CAAC,EAAE,MAAM,CAAA;IAE1B,iBAAiB,CAAC,EAAE,OAAO,CAAA;IAC3B,sBAAsB,CAAC,EAAE,MAAM,CAAA;IAE/B,2BAA2B,CAAC,EAAE,OAAO,CAAA;IACrC,uBAAuB,CAAC,EAAE,OAAO,CAAA;IACjC,0BAA0B,CAAC,EAAE,OAAO,CAAA;IACpC,sBAAsB,CAAC,EAAE,OAAO,CAAA;IAChC,4BAA4B,CAAC,EAAE,MAAM,EAAE,CAAA;CAC1C;AAED,KAAK,gBAAgB,GAAG,UAAU,CAAC,OAAO,iBAAiB,CAAC,CAAA;AAE5D,MAAM,MAAM,mBAAmB,GAAG,MAAM,gBAAgB,CAAA;AAExD,KAAK,UAAU,CAAC,CAAC,EAAE,CAAC,SAAS,MAAM,IAAI,CAAC,SAAS,GAAG,CAAC,GAAG,MAAM,CAAC,EAAE,GAAG,CAAC,GAAG,KAAK,CAAA;AAE7E,KAAK,OAAO,CAAC,CAAC,IAAI;KACb,CAAC,IAAI,MAAM,CAAC,IAAI,UAAU,CAAC,CAAC,GAAG,MAAM,EAAE,MAAM,CAAC,GAAG,UAAU,CAAC,CAAC,GAAG,MAAM,EAAE,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;CAC1F,CAAA;AAED,MAAM,MAAM,yBAAyB,GAAG,OAAO,CAAC,gBAAgB,CAAC,CAAA;AAWjE;;;GAGG;AAEH,wBAAgB,oBAAoB,IAQP;IACrB,aAAa,EAAE,MAAM,CAAA;IACrB,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,iBAAiB,CAAC,EAAE,MAAM,CAAA;CAC7B,GAAG,gBAAgB,GAChB,SAAS,CAChB;AAED,wBAAgB,0BAA0B,CACtC,CAAC,SAAS,SAAS,EACnB,CAAC,SAAS,CACJ,MAAM,CAAC,GACP,OAAO,CAAC,mBAAmB,EAAE,gBAAgB,CAAC,CACnD,GACG,MAAM,EACV,CAAC,EACH,WAAW,EAAE;IAAE,IAAI,EAAE,CAAC,CAAA;CAAE,EAAE,aAAa,EAAE,CAAC,EAAE,EAAE,UAAU,EAAE,CAAC,EAAE,kBAAkB,CAAC,EAAE,MAAM,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAgE3F"}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
export { adopusNamespaceExchange, adopusSlugFromJwt, denamespaceData, namespaceDocument } from './adopusNamespaceExchange.js';
|
|
2
|
+
export { createTadaBrowserClient } from './createTadaBrowserClient.js';
|
|
3
|
+
export type { CreateTadaBrowserClientOptions, ResolveExchanges } from './createTadaBrowserClient.js';
|
|
4
|
+
//# sourceMappingURL=urql.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"urql.d.ts","sourceRoot":"","sources":["../../src/helpers/urql.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,uBAAuB,EAAE,iBAAiB,EAAE,eAAe,EAAE,iBAAiB,EAAE,MAAM,8BAA8B,CAAA;AAC7H,OAAO,EAAE,uBAAuB,EAAE,MAAM,8BAA8B,CAAA;AACtE,YAAY,EAAE,8BAA8B,EAAE,gBAAgB,EAAE,MAAM,8BAA8B,CAAA"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"urql.js","sourceRoot":"","sources":["../../src/helpers/urql.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,uBAAuB,EAAE,iBAAiB,EAAE,eAAe,EAAE,iBAAiB,EAAE,MAAM,8BAA8B,CAAA;AAC7H,OAAO,EAAE,uBAAuB,EAAE,MAAM,8BAA8B,CAAA"}
|
package/lib/index.d.ts
CHANGED
|
@@ -39,4 +39,6 @@ export * from './helpers/isUUID.js';
|
|
|
39
39
|
export * from './helpers/JSONToBase64EncodeDecode.js';
|
|
40
40
|
export * from './helpers/getActivityStatus.js';
|
|
41
41
|
export * from './helpers/stringToKeyValueMap.js';
|
|
42
|
+
export { createTadaBrowserClient } from './helpers/createTadaBrowserClient.js';
|
|
43
|
+
export type { CreateTadaBrowserClientOptions, ResolveExchanges } from './helpers/createTadaBrowserClient.js';
|
|
42
44
|
//# sourceMappingURL=index.d.ts.map
|
package/lib/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,kCAAkC,CAAA;AAChD,cAAc,oCAAoC,CAAA;AAClD,cAAc,mCAAmC,CAAA;AACjD,cAAc,mCAAmC,CAAA;AACjD,cAAc,wBAAwB,CAAA;AACtC,cAAc,uBAAuB,CAAA;AACrC,cAAc,yBAAyB,CAAA;AACvC,cAAc,qBAAqB,CAAA;AACnC,cAAc,mDAAmD,CAAA;AACjE,cAAc,iCAAiC,CAAA;AAE/C,cAAc,kCAAkC,CAAA;AAChD,cAAc,uBAAuB,CAAA;AACrC,cAAc,+BAA+B,CAAA;AAC7C,cAAc,wCAAwC,CAAA;AACtD,cAAc,sCAAsC,CAAA;AACpD,cAAc,4CAA4C,CAAA;AAC1D,cAAc,2BAA2B,CAAA;AACzC,cAAc,2CAA2C,CAAA;AACzD,cAAc,6BAA6B,CAAA;AAC3C,cAAc,yCAAyC,CAAA;AACvD,cAAc,+BAA+B,CAAA;AAC7C,cAAc,2BAA2B,CAAA;AACzC,cAAc,yBAAyB,CAAA;AACvC,cAAc,2CAA2C,CAAA;AACzD,cAAc,gCAAgC,CAAA;AAC9C,cAAc,iCAAiC,CAAA;AAC/C,cAAc,gCAAgC,CAAA;AAC9C,cAAc,+BAA+B,CAAA;AAE7C,cAAc,qBAAqB,CAAA;AACnC,cAAc,kCAAkC,CAAA;AAEhD,cAAc,oBAAoB,CAAA;AAElC,cAAc,sBAAsB,CAAA;AAEpC,cAAc,uBAAuB,CAAA;AAErC,cAAc,oBAAoB,CAAA;AAElC,cAAc,8CAA8C,CAAA;AAC5D,cAAc,+CAA+C,CAAA;AAC7D,cAAc,mCAAmC,CAAA;AACjD,cAAc,qBAAqB,CAAA;AACnC,cAAc,uCAAuC,CAAA;AACrD,cAAc,gCAAgC,CAAA;AAC9C,cAAc,kCAAkC,CAAA"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,kCAAkC,CAAA;AAChD,cAAc,oCAAoC,CAAA;AAClD,cAAc,mCAAmC,CAAA;AACjD,cAAc,mCAAmC,CAAA;AACjD,cAAc,wBAAwB,CAAA;AACtC,cAAc,uBAAuB,CAAA;AACrC,cAAc,yBAAyB,CAAA;AACvC,cAAc,qBAAqB,CAAA;AACnC,cAAc,mDAAmD,CAAA;AACjE,cAAc,iCAAiC,CAAA;AAE/C,cAAc,kCAAkC,CAAA;AAChD,cAAc,uBAAuB,CAAA;AACrC,cAAc,+BAA+B,CAAA;AAC7C,cAAc,wCAAwC,CAAA;AACtD,cAAc,sCAAsC,CAAA;AACpD,cAAc,4CAA4C,CAAA;AAC1D,cAAc,2BAA2B,CAAA;AACzC,cAAc,2CAA2C,CAAA;AACzD,cAAc,6BAA6B,CAAA;AAC3C,cAAc,yCAAyC,CAAA;AACvD,cAAc,+BAA+B,CAAA;AAC7C,cAAc,2BAA2B,CAAA;AACzC,cAAc,yBAAyB,CAAA;AACvC,cAAc,2CAA2C,CAAA;AACzD,cAAc,gCAAgC,CAAA;AAC9C,cAAc,iCAAiC,CAAA;AAC/C,cAAc,gCAAgC,CAAA;AAC9C,cAAc,+BAA+B,CAAA;AAE7C,cAAc,qBAAqB,CAAA;AACnC,cAAc,kCAAkC,CAAA;AAEhD,cAAc,oBAAoB,CAAA;AAElC,cAAc,sBAAsB,CAAA;AAEpC,cAAc,uBAAuB,CAAA;AAErC,cAAc,oBAAoB,CAAA;AAElC,cAAc,8CAA8C,CAAA;AAC5D,cAAc,+CAA+C,CAAA;AAC7D,cAAc,mCAAmC,CAAA;AACjD,cAAc,qBAAqB,CAAA;AACnC,cAAc,uCAAuC,CAAA;AACrD,cAAc,gCAAgC,CAAA;AAC9C,cAAc,kCAAkC,CAAA;AAEhD,OAAO,EAAE,uBAAuB,EAAE,MAAM,sCAAsC,CAAA;AAC9E,YAAY,EAAE,8BAA8B,EAAE,gBAAgB,EAAE,MAAM,sCAAsC,CAAA"}
|
package/lib/index.js
CHANGED
|
@@ -40,4 +40,5 @@ export * from './helpers/isUUID.js';
|
|
|
40
40
|
export * from './helpers/JSONToBase64EncodeDecode.js';
|
|
41
41
|
export * from './helpers/getActivityStatus.js';
|
|
42
42
|
export * from './helpers/stringToKeyValueMap.js';
|
|
43
|
+
export { createTadaBrowserClient } from './helpers/createTadaBrowserClient.js';
|
|
43
44
|
//# sourceMappingURL=index.js.map
|
package/lib/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,kCAAkC,CAAA;AAChD,cAAc,oCAAoC,CAAA;AAClD,cAAc,mCAAmC,CAAA;AACjD,cAAc,mCAAmC,CAAA;AACjD,cAAc,wBAAwB,CAAA;AACtC,cAAc,uBAAuB,CAAA;AACrC,cAAc,yBAAyB,CAAA;AACvC,cAAc,qBAAqB,CAAA;AACnC,cAAc,mDAAmD,CAAA;AACjE,cAAc,iCAAiC,CAAA;AAE/C,cAAc,kCAAkC,CAAA;AAChD,cAAc,uBAAuB,CAAA;AACrC,cAAc,+BAA+B,CAAA;AAC7C,cAAc,wCAAwC,CAAA;AACtD,cAAc,sCAAsC,CAAA;AACpD,cAAc,4CAA4C,CAAA;AAC1D,cAAc,2BAA2B,CAAA;AACzC,cAAc,2CAA2C,CAAA;AACzD,cAAc,6BAA6B,CAAA;AAC3C,cAAc,yCAAyC,CAAA;AACvD,cAAc,+BAA+B,CAAA;AAC7C,cAAc,2BAA2B,CAAA;AACzC,cAAc,yBAAyB,CAAA;AACvC,cAAc,2CAA2C,CAAA;AACzD,cAAc,gCAAgC,CAAA;AAC9C,cAAc,iCAAiC,CAAA;AAC/C,cAAc,gCAAgC,CAAA;AAC9C,cAAc,+BAA+B,CAAA;AAC7C,gDAAgD;AAChD,cAAc,qBAAqB,CAAA;AACnC,cAAc,kCAAkC,CAAA;AAEhD,cAAc,oBAAoB,CAAA;AAElC,cAAc,sBAAsB,CAAA;AAEpC,cAAc,uBAAuB,CAAA;AAErC,cAAc,oBAAoB,CAAA;AAElC,cAAc,8CAA8C,CAAA;AAC5D,cAAc,+CAA+C,CAAA;AAC7D,cAAc,mCAAmC,CAAA;AACjD,cAAc,qBAAqB,CAAA;AACnC,cAAc,uCAAuC,CAAA;AACrD,cAAc,gCAAgC,CAAA;AAC9C,cAAc,kCAAkC,CAAA"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,kCAAkC,CAAA;AAChD,cAAc,oCAAoC,CAAA;AAClD,cAAc,mCAAmC,CAAA;AACjD,cAAc,mCAAmC,CAAA;AACjD,cAAc,wBAAwB,CAAA;AACtC,cAAc,uBAAuB,CAAA;AACrC,cAAc,yBAAyB,CAAA;AACvC,cAAc,qBAAqB,CAAA;AACnC,cAAc,mDAAmD,CAAA;AACjE,cAAc,iCAAiC,CAAA;AAE/C,cAAc,kCAAkC,CAAA;AAChD,cAAc,uBAAuB,CAAA;AACrC,cAAc,+BAA+B,CAAA;AAC7C,cAAc,wCAAwC,CAAA;AACtD,cAAc,sCAAsC,CAAA;AACpD,cAAc,4CAA4C,CAAA;AAC1D,cAAc,2BAA2B,CAAA;AACzC,cAAc,2CAA2C,CAAA;AACzD,cAAc,6BAA6B,CAAA;AAC3C,cAAc,yCAAyC,CAAA;AACvD,cAAc,+BAA+B,CAAA;AAC7C,cAAc,2BAA2B,CAAA;AACzC,cAAc,yBAAyB,CAAA;AACvC,cAAc,2CAA2C,CAAA;AACzD,cAAc,gCAAgC,CAAA;AAC9C,cAAc,iCAAiC,CAAA;AAC/C,cAAc,gCAAgC,CAAA;AAC9C,cAAc,+BAA+B,CAAA;AAC7C,gDAAgD;AAChD,cAAc,qBAAqB,CAAA;AACnC,cAAc,kCAAkC,CAAA;AAEhD,cAAc,oBAAoB,CAAA;AAElC,cAAc,sBAAsB,CAAA;AAEpC,cAAc,uBAAuB,CAAA;AAErC,cAAc,oBAAoB,CAAA;AAElC,cAAc,8CAA8C,CAAA;AAC5D,cAAc,+CAA+C,CAAA;AAC7D,cAAc,mCAAmC,CAAA;AACjD,cAAc,qBAAqB,CAAA;AACnC,cAAc,uCAAuC,CAAA;AACrD,cAAc,gCAAgC,CAAA;AAC9C,cAAc,kCAAkC,CAAA;AAEhD,OAAO,EAAE,uBAAuB,EAAE,MAAM,sCAAsC,CAAA"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "asma-core-helpers",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.12.0",
|
|
4
4
|
"description": "Core helper utilities for ASMA applications",
|
|
5
5
|
"files": [
|
|
6
6
|
"lib/**/*",
|
|
@@ -12,8 +12,8 @@
|
|
|
12
12
|
".": "./lib/index.js",
|
|
13
13
|
"./lib": "./lib/index.js",
|
|
14
14
|
"./urql": {
|
|
15
|
-
"types": "./lib/helpers/
|
|
16
|
-
"default": "./lib/helpers/
|
|
15
|
+
"types": "./lib/helpers/urql.d.ts",
|
|
16
|
+
"default": "./lib/helpers/urql.js"
|
|
17
17
|
}
|
|
18
18
|
},
|
|
19
19
|
"scripts": {
|
|
@@ -29,12 +29,16 @@
|
|
|
29
29
|
"license": "MIT",
|
|
30
30
|
"peerDependencies": {
|
|
31
31
|
"@urql/core": ">=4",
|
|
32
|
+
"@urql/exchange-auth": ">=3",
|
|
32
33
|
"wonka": ">=6"
|
|
33
34
|
},
|
|
34
35
|
"peerDependenciesMeta": {
|
|
35
36
|
"@urql/core": {
|
|
36
37
|
"optional": true
|
|
37
38
|
},
|
|
39
|
+
"@urql/exchange-auth": {
|
|
40
|
+
"optional": true
|
|
41
|
+
},
|
|
38
42
|
"wonka": {
|
|
39
43
|
"optional": true
|
|
40
44
|
}
|
|
@@ -42,6 +46,7 @@
|
|
|
42
46
|
"devDependencies": {
|
|
43
47
|
"@openreplay/tracker": "^16.4.10",
|
|
44
48
|
"@urql/core": "^6.0.3",
|
|
49
|
+
"@urql/exchange-auth": "^3.0.0",
|
|
45
50
|
"asma-qiankun-react-loader": "^0.8.2",
|
|
46
51
|
"asma-types": "^2.8.0",
|
|
47
52
|
"history": "^5.3.0",
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* createTadaBrowserClient — shared urql client factory for ASMA frontend apps.
|
|
3
|
+
*
|
|
4
|
+
* Wraps the urql core (fetchExchange + optional service-specific exchanges) with
|
|
5
|
+
* an authExchange that attaches a JWT Bearer token and refreshes on 401.
|
|
6
|
+
*
|
|
7
|
+
* URL resolution stays in the app (imports EnvConfigs from asma-helpers);
|
|
8
|
+
* this factory accepts the resolved URL so it has zero dependency on asma-helpers.
|
|
9
|
+
*
|
|
10
|
+
* @see asma-modules/_docs/frontend/operations/2026-07-11-23-00-runbook-graphql-schema-generation-secrets.md
|
|
11
|
+
*/
|
|
12
|
+
import {
|
|
13
|
+
type Client,
|
|
14
|
+
type ClientOptions,
|
|
15
|
+
createClient,
|
|
16
|
+
type Exchange,
|
|
17
|
+
fetchExchange,
|
|
18
|
+
} from '@urql/core'
|
|
19
|
+
import { authExchange } from '@urql/exchange-auth'
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* Contributes service-specific exchanges (e.g. the Adopus per-tenant namespace
|
|
23
|
+
* rewrite) without baking that knowledge into the generic factory. Called once
|
|
24
|
+
* per client build with the resolved endpoint; returned exchanges are inserted
|
|
25
|
+
* just before `fetchExchange` (and after `authExchange`).
|
|
26
|
+
*/
|
|
27
|
+
export type ResolveExchanges = (ctx: {
|
|
28
|
+
/** The fully-resolved GraphQL endpoint URL. */
|
|
29
|
+
url: string
|
|
30
|
+
/** Resolves the current JWT (may be stale — the auth exchange handles refresh). */
|
|
31
|
+
getJwt: () => Promise<string | undefined>
|
|
32
|
+
}) => Exchange[] | Promise<Exchange[]>
|
|
33
|
+
|
|
34
|
+
export interface CreateTadaBrowserClientOptions {
|
|
35
|
+
/** Fully-resolved GraphQL endpoint URL (caller resolves via EnvConfigs / srv_urls). */
|
|
36
|
+
url: string
|
|
37
|
+
/** Resolves the current JWT. Typically `getCachedJwt` from asma-core-react. */
|
|
38
|
+
getJwt: () => Promise<string | undefined>
|
|
39
|
+
/** Returns true when the cached JWT is still valid. Typically `isJwtValid` from asma-core-react. */
|
|
40
|
+
isJwtValid: () => boolean
|
|
41
|
+
/** Optional service-specific exchanges injected before fetchExchange. */
|
|
42
|
+
resolveExchanges?: ResolveExchanges
|
|
43
|
+
/** Passthrough to urql ClientOptions (url is overridden by the `url` param above). */
|
|
44
|
+
clientOptions?: Partial<ClientOptions>
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* Creates a configured, authenticated urql Client for an ASMA frontend app.
|
|
49
|
+
*
|
|
50
|
+
* Exchange order (first = outermost):
|
|
51
|
+
* 1. authExchange — attach Bearer token, refresh on 401
|
|
52
|
+
* 2. resolveExchanges — optional service-specific transforms (e.g. namespace)
|
|
53
|
+
* 3. fetchExchange — standard HTTP fetch
|
|
54
|
+
* 4. caller-provided — appended via clientOptions.exchanges (end of pipeline)
|
|
55
|
+
*/
|
|
56
|
+
export function createTadaBrowserClient({
|
|
57
|
+
url,
|
|
58
|
+
getJwt,
|
|
59
|
+
isJwtValid,
|
|
60
|
+
resolveExchanges,
|
|
61
|
+
clientOptions,
|
|
62
|
+
}: CreateTadaBrowserClientOptions): { getClient: () => Promise<Client>; createClient: (opts?: { clientOptions?: Partial<ClientOptions>; anonymous?: boolean }) => Promise<Client> } {
|
|
63
|
+
let tadaClient: Client | undefined
|
|
64
|
+
|
|
65
|
+
const getClient = async () => {
|
|
66
|
+
tadaClient = await buildClient({ clientOptions })
|
|
67
|
+
return tadaClient
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
async function buildClient(opts?: {
|
|
71
|
+
clientOptions?: Partial<ClientOptions>
|
|
72
|
+
anonymous?: boolean
|
|
73
|
+
}) {
|
|
74
|
+
const _clientOptions: Partial<ClientOptions> = { ...(opts?.clientOptions ?? {}) }
|
|
75
|
+
const anonymous = opts?.anonymous
|
|
76
|
+
|
|
77
|
+
_clientOptions.url = url
|
|
78
|
+
_clientOptions.preferGetMethod = false
|
|
79
|
+
_clientOptions.requestPolicy = 'cache-and-network'
|
|
80
|
+
|
|
81
|
+
// Start with fetchExchange + caller-provided exchanges
|
|
82
|
+
_clientOptions.exchanges = [
|
|
83
|
+
fetchExchange,
|
|
84
|
+
...(_clientOptions.exchanges || []),
|
|
85
|
+
]
|
|
86
|
+
|
|
87
|
+
// Inject service-specific exchanges before fetchExchange
|
|
88
|
+
if (resolveExchanges) {
|
|
89
|
+
const extra = await resolveExchanges({
|
|
90
|
+
getJwt,
|
|
91
|
+
url,
|
|
92
|
+
})
|
|
93
|
+
if (extra.length) {
|
|
94
|
+
_clientOptions.exchanges.unshift(...extra)
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
// authExchange is outermost (first to receive the operation)
|
|
99
|
+
if (!anonymous) {
|
|
100
|
+
_clientOptions.exchanges.unshift(
|
|
101
|
+
authExchange(async (utils) => {
|
|
102
|
+
const token = await getJwt()
|
|
103
|
+
return {
|
|
104
|
+
addAuthToOperation(operation) {
|
|
105
|
+
return utils.appendHeaders(operation, {
|
|
106
|
+
Authorization: `Bearer ${token}`,
|
|
107
|
+
})
|
|
108
|
+
},
|
|
109
|
+
didAuthError(error) {
|
|
110
|
+
return error.response.status === 401
|
|
111
|
+
},
|
|
112
|
+
async refreshAuth() {
|
|
113
|
+
tadaClient = await buildClient({ clientOptions: opts?.clientOptions })
|
|
114
|
+
},
|
|
115
|
+
willAuthError() {
|
|
116
|
+
return !isJwtValid()
|
|
117
|
+
},
|
|
118
|
+
}
|
|
119
|
+
}),
|
|
120
|
+
)
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
return createClient(_clientOptions as ClientOptions)
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
return { getClient, createClient: buildClient }
|
|
127
|
+
}
|
|
@@ -25,7 +25,7 @@ export type IKeyEnvironmentUrls = keyof IEnvironmentUrls
|
|
|
25
25
|
type StartsWith<T, U extends string> = T extends `${U}${infer _}` ? T : never
|
|
26
26
|
|
|
27
27
|
type SRVKeys<T> = {
|
|
28
|
-
[K in keyof T as StartsWith<K & string, 'SRV_'>]: T[K]
|
|
28
|
+
[K in keyof T as StartsWith<K & string, 'SRV_'> | StartsWith<K & string, 'HSR_'>]: T[K]
|
|
29
29
|
}
|
|
30
30
|
|
|
31
31
|
export type IEnvironmentUrlsGenQLOnly = SRVKeys<IEnvironmentUrls> /* Omit<
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
export { adopusNamespaceExchange, adopusSlugFromJwt, denamespaceData, namespaceDocument } from './adopusNamespaceExchange.js'
|
|
2
|
+
export { createTadaBrowserClient } from './createTadaBrowserClient.js'
|
|
3
|
+
export type { CreateTadaBrowserClientOptions, ResolveExchanges } from './createTadaBrowserClient.js'
|
package/src/index.ts
CHANGED
|
@@ -46,3 +46,6 @@ export * from './helpers/isUUID.js'
|
|
|
46
46
|
export * from './helpers/JSONToBase64EncodeDecode.js'
|
|
47
47
|
export * from './helpers/getActivityStatus.js'
|
|
48
48
|
export * from './helpers/stringToKeyValueMap.js'
|
|
49
|
+
|
|
50
|
+
export { createTadaBrowserClient } from './helpers/createTadaBrowserClient.js'
|
|
51
|
+
export type { CreateTadaBrowserClientOptions, ResolveExchanges } from './helpers/createTadaBrowserClient.js'
|