asma-core-helpers 0.8.0 → 0.9.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/adopusNamespaceExchange.d.ts +44 -0
- package/lib/helpers/adopusNamespaceExchange.d.ts.map +1 -0
- package/lib/helpers/adopusNamespaceExchange.js +126 -0
- package/lib/helpers/adopusNamespaceExchange.js.map +1 -0
- package/lib/helpers/generateSrvAuthBindings.d.ts +8 -8
- package/lib/helpers/generateSrvAuthBindings.js +2 -2
- package/lib/index.d.ts +0 -1
- package/lib/index.d.ts.map +1 -1
- package/lib/index.js +0 -1
- package/lib/index.js.map +1 -1
- package/package.json +23 -4
- package/src/helpers/adopusNamespaceExchange.test.ts +117 -0
- package/src/helpers/adopusNamespaceExchange.ts +215 -0
- package/src/helpers/generateSrvAuthBindings.ts +2 -2
- package/src/index.ts +0 -1
- package/lib/helpers/generateGenqlClient.d.ts +0 -21
- package/lib/helpers/generateGenqlClient.d.ts.map +0 -1
- package/lib/helpers/generateGenqlClient.js +0 -98
- package/lib/helpers/generateGenqlClient.js.map +0 -1
- package/src/helpers/generateGenqlClient.ts +0 -145
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* adopusNamespaceExchange — urql exchange that maps unprefixed gql.tada operations onto the
|
|
3
|
+
* consolidated Adopus Hasura engine's per-tenant namespace, at the wire level only.
|
|
4
|
+
*
|
|
5
|
+
* Compile-time types stay the unprefixed avansas/AdOpusTest schema (DEC-004/DEC-011); this
|
|
6
|
+
* exchange rewrites the parsed document + JSON per request/response:
|
|
7
|
+
* 1. request: wrap each operation's selection set in the `<slug>` root field
|
|
8
|
+
* 2. request: prefix schema type names in variable definitions (`Actor_bool_exp` -> `<slug>_Actor_bool_exp`)
|
|
9
|
+
* 3. request: prefix fragment type conditions (inline + named)
|
|
10
|
+
* 4. response: unwrap `data[<slug>]` -> `data`
|
|
11
|
+
* 5. response: strip the `<slug>_` prefix from `__typename` values
|
|
12
|
+
*
|
|
13
|
+
* `prefixedTypes` is the exact set of names the engine prefixes for the tenant source —
|
|
14
|
+
* generated at codegen time by adopus-hsr-wrapper/scripts/unwrap_client_schema.mjs
|
|
15
|
+
* (adopus-prefixed-types.json) so the runtime never guesses which names carry the prefix.
|
|
16
|
+
*
|
|
17
|
+
* Install it only on the SRV_AO_WRAPPER client and only when the resolved endpoint is the
|
|
18
|
+
* consolidated engine (`/api/hsr-wrapper/`) — the per-tenant `srv_urls.ao_wrapper` flip then
|
|
19
|
+
* switches endpoint and namespace mode atomically.
|
|
20
|
+
*
|
|
21
|
+
* @see asma-modules/_docs/adopus-graphql/plans/2026-07-11-00-14-plan-adopus-hasura2-consolidation.md:184 — §2.4.3 (DEC-004/DEC-015)
|
|
22
|
+
*/
|
|
23
|
+
import type { DocumentNode } from '@0no-co/graphql.web';
|
|
24
|
+
import { type Exchange } from '@urql/core';
|
|
25
|
+
/**
|
|
26
|
+
* Derive the tenant namespace slug from the main ASMA JWT's `subdomain` claim (DEC-015),
|
|
27
|
+
* sanitized per plan §1.1 (lowercase, hyphens -> underscores). Returns undefined when the
|
|
28
|
+
* token is missing or the claim does not sanitize to a valid slug — callers skip the
|
|
29
|
+
* exchange in that case.
|
|
30
|
+
*/
|
|
31
|
+
export declare function adopusSlugFromJwt(jwt: string | undefined): string | undefined;
|
|
32
|
+
/** Transforms 1–3 on the parsed operation document. Pure; exported for tests. */
|
|
33
|
+
export declare function namespaceDocument(document: DocumentNode, slug: string, prefixed: ReadonlySet<string>): DocumentNode;
|
|
34
|
+
/** Transforms 4–5 on the response payload. Pure (returns new objects); exported for tests. */
|
|
35
|
+
export declare function denamespaceData<T>(data: T, slug: string): T;
|
|
36
|
+
/**
|
|
37
|
+
* @param slug tenant namespace — derive with `adopusSlugFromJwt(await getCachedJwt())`
|
|
38
|
+
* @param prefixedTypes contents of the codegen-emitted `adopus-prefixed-types.json`
|
|
39
|
+
*/
|
|
40
|
+
export declare function adopusNamespaceExchange({ slug, prefixedTypes, }: {
|
|
41
|
+
slug: string;
|
|
42
|
+
prefixedTypes: readonly string[];
|
|
43
|
+
}): Exchange;
|
|
44
|
+
//# sourceMappingURL=adopusNamespaceExchange.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"adopusNamespaceExchange.d.ts","sourceRoot":"","sources":["../../src/helpers/adopusNamespaceExchange.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAA;AACvD,OAAO,EAAiB,KAAK,QAAQ,EAAwC,MAAM,YAAY,CAAA;AAgE/F;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,GAAG,SAAS,CAS7E;AAED,iFAAiF;AACjF,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,YAAY,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,WAAW,CAAC,MAAM,CAAC,GAAG,YAAY,CAsDnH;AAED,8FAA8F;AAC9F,wBAAgB,eAAe,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,GAAG,CAAC,CAM3D;AAYD;;;GAGG;AACH,wBAAgB,uBAAuB,CAAC,EACpC,IAAI,EACJ,aAAa,GAChB,EAAE;IACC,IAAI,EAAE,MAAM,CAAA;IACZ,aAAa,EAAE,SAAS,MAAM,EAAE,CAAA;CACnC,GAAG,QAAQ,CAwBX"}
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
import { makeOperation } from '@urql/core';
|
|
2
|
+
import { map, pipe } from 'wonka';
|
|
3
|
+
const SLUG_PATTERN = /^[a-z][a-z0-9_]{1,30}$/;
|
|
4
|
+
// not parseJwt.js — that module touches `window` at import time; this subpath stays environment-neutral
|
|
5
|
+
function decodeJwtClaims(jwt) {
|
|
6
|
+
const payload = jwt.split('.')[1];
|
|
7
|
+
if (!payload)
|
|
8
|
+
return undefined;
|
|
9
|
+
try {
|
|
10
|
+
const base64 = payload.replace(/-/g, '+').replace(/_/g, '/');
|
|
11
|
+
return JSON.parse(new TextDecoder().decode(Uint8Array.from(atob(base64), (c) => c.charCodeAt(0))));
|
|
12
|
+
}
|
|
13
|
+
catch {
|
|
14
|
+
return undefined;
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Derive the tenant namespace slug from the main ASMA JWT's `subdomain` claim (DEC-015),
|
|
19
|
+
* sanitized per plan §1.1 (lowercase, hyphens -> underscores). Returns undefined when the
|
|
20
|
+
* token is missing or the claim does not sanitize to a valid slug — callers skip the
|
|
21
|
+
* exchange in that case.
|
|
22
|
+
*/
|
|
23
|
+
export function adopusSlugFromJwt(jwt) {
|
|
24
|
+
if (!jwt)
|
|
25
|
+
return undefined;
|
|
26
|
+
const claims = decodeJwtClaims(jwt);
|
|
27
|
+
const slug = claims?.subdomain?.toLowerCase().replace(/-/g, '_');
|
|
28
|
+
if (!slug || !SLUG_PATTERN.test(slug)) {
|
|
29
|
+
console.error(`adopusSlugFromJwt: subdomain claim '${claims?.subdomain}' is not a valid namespace slug`);
|
|
30
|
+
return undefined;
|
|
31
|
+
}
|
|
32
|
+
return slug;
|
|
33
|
+
}
|
|
34
|
+
/** Transforms 1–3 on the parsed operation document. Pure; exported for tests. */
|
|
35
|
+
export function namespaceDocument(document, slug, prefixed) {
|
|
36
|
+
const doc = document;
|
|
37
|
+
const prefixName = (name) => prefixed.has(name.value) ? { ...name, value: `${slug}_${name.value}` } : name;
|
|
38
|
+
const prefixType = (type) => type.kind === 'NamedType' ? { ...type, name: prefixName(type.name) } : { ...type, type: prefixType(type.type) };
|
|
39
|
+
const prefixFragmentConditions = (selectionSet) => ({
|
|
40
|
+
...selectionSet,
|
|
41
|
+
selections: selectionSet.selections.map((sel) => {
|
|
42
|
+
if (sel.kind === 'InlineFragment') {
|
|
43
|
+
return {
|
|
44
|
+
...sel,
|
|
45
|
+
typeCondition: sel.typeCondition && { ...sel.typeCondition, name: prefixName(sel.typeCondition.name) },
|
|
46
|
+
selectionSet: prefixFragmentConditions(sel.selectionSet),
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
if (sel.kind === 'Field' && sel.selectionSet) {
|
|
50
|
+
return { ...sel, selectionSet: prefixFragmentConditions(sel.selectionSet) };
|
|
51
|
+
}
|
|
52
|
+
return sel;
|
|
53
|
+
}),
|
|
54
|
+
});
|
|
55
|
+
const out = {
|
|
56
|
+
...doc,
|
|
57
|
+
definitions: doc.definitions.map((def) => {
|
|
58
|
+
if (def.kind === 'OperationDefinition') {
|
|
59
|
+
const op = def;
|
|
60
|
+
const namespaceField = {
|
|
61
|
+
kind: 'Field',
|
|
62
|
+
name: { kind: 'Name', value: slug },
|
|
63
|
+
selectionSet: prefixFragmentConditions(op.selectionSet),
|
|
64
|
+
};
|
|
65
|
+
return {
|
|
66
|
+
...op,
|
|
67
|
+
variableDefinitions: op.variableDefinitions?.map((v) => ({ ...v, type: prefixType(v.type) })),
|
|
68
|
+
selectionSet: { kind: 'SelectionSet', selections: [namespaceField] },
|
|
69
|
+
};
|
|
70
|
+
}
|
|
71
|
+
if (def.kind === 'FragmentDefinition') {
|
|
72
|
+
const frag = def;
|
|
73
|
+
return {
|
|
74
|
+
...frag,
|
|
75
|
+
typeCondition: { ...frag.typeCondition, name: prefixName(frag.typeCondition.name) },
|
|
76
|
+
selectionSet: prefixFragmentConditions(frag.selectionSet),
|
|
77
|
+
};
|
|
78
|
+
}
|
|
79
|
+
return def;
|
|
80
|
+
}),
|
|
81
|
+
};
|
|
82
|
+
return out;
|
|
83
|
+
}
|
|
84
|
+
/** Transforms 4–5 on the response payload. Pure (returns new objects); exported for tests. */
|
|
85
|
+
export function denamespaceData(data, slug) {
|
|
86
|
+
const unwrapped = data && typeof data === 'object' && !Array.isArray(data) && slug in data
|
|
87
|
+
? data[slug]
|
|
88
|
+
: data;
|
|
89
|
+
return stripTypenamePrefix(unwrapped, `${slug}_`);
|
|
90
|
+
}
|
|
91
|
+
function stripTypenamePrefix(value, prefix) {
|
|
92
|
+
if (Array.isArray(value))
|
|
93
|
+
return value.map((v) => stripTypenamePrefix(v, prefix));
|
|
94
|
+
if (!value || typeof value !== 'object')
|
|
95
|
+
return value;
|
|
96
|
+
const out = {};
|
|
97
|
+
for (const [key, v] of Object.entries(value)) {
|
|
98
|
+
out[key] = key === '__typename' && typeof v === 'string' && v.startsWith(prefix) ? v.slice(prefix.length) : stripTypenamePrefix(v, prefix);
|
|
99
|
+
}
|
|
100
|
+
return out;
|
|
101
|
+
}
|
|
102
|
+
/**
|
|
103
|
+
* @param slug tenant namespace — derive with `adopusSlugFromJwt(await getCachedJwt())`
|
|
104
|
+
* @param prefixedTypes contents of the codegen-emitted `adopus-prefixed-types.json`
|
|
105
|
+
*/
|
|
106
|
+
export function adopusNamespaceExchange({ slug, prefixedTypes, }) {
|
|
107
|
+
const prefixed = new Set(prefixedTypes);
|
|
108
|
+
// documents are module-level gql.tada constants — stable references, so WeakMap memoizes
|
|
109
|
+
// the rewrite once per document (NOT per operation.key, which varies with variables)
|
|
110
|
+
const rewritten = new WeakMap();
|
|
111
|
+
const rewriteOperation = (op) => {
|
|
112
|
+
if (op.kind === 'teardown')
|
|
113
|
+
return op;
|
|
114
|
+
let query = rewritten.get(op.query);
|
|
115
|
+
if (!query) {
|
|
116
|
+
query = namespaceDocument(op.query, slug, prefixed);
|
|
117
|
+
rewritten.set(op.query, query);
|
|
118
|
+
}
|
|
119
|
+
return makeOperation(op.kind, { ...op, query }, op.context);
|
|
120
|
+
};
|
|
121
|
+
const rewriteResult = (result) => result.operation.kind === 'teardown' || result.data == null
|
|
122
|
+
? result // ponytail: error paths keep the <slug> segment — cosmetic, fix if it ever confuses anyone
|
|
123
|
+
: { ...result, data: denamespaceData(result.data, slug) };
|
|
124
|
+
return ({ forward }) => (ops$) => pipe(forward(pipe(ops$, map(rewriteOperation))), map(rewriteResult));
|
|
125
|
+
}
|
|
126
|
+
//# sourceMappingURL=adopusNamespaceExchange.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"adopusNamespaceExchange.js","sourceRoot":"","sources":["../../src/helpers/adopusNamespaceExchange.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
import type { ICheckSigninOptions, ICheckSigninTransformedOptions } from './generateSrvAuthBindings.types.js';
|
|
2
2
|
import { type ActivityStatus, type IAuthBindings } from '../index.js';
|
|
3
3
|
import type { IUUID } from 'asma-types';
|
|
4
|
-
export declare const dispatchSrvAuthEvents: <Key extends "
|
|
4
|
+
export declare const dispatchSrvAuthEvents: <Key extends "jwt_changed" | "logout_event" | "customer_changed">(event: Key, arg: {
|
|
5
5
|
jwt_changed?: ICheckSigninOptions<any>;
|
|
6
6
|
logout_event: {
|
|
7
7
|
device?: "TRUSTED" | "UNTRUSTED";
|
|
8
8
|
};
|
|
9
9
|
customer_changed: {};
|
|
10
|
-
}[Key], shouldPersist?: boolean) => void, registerCallbackOnSrvAuthEvents: <Key extends "
|
|
10
|
+
}[Key], shouldPersist?: boolean) => void, registerCallbackOnSrvAuthEvents: <Key extends "jwt_changed" | "logout_event" | "customer_changed">(event: Key, callback: (val: {
|
|
11
11
|
jwt_changed?: ICheckSigninOptions<any>;
|
|
12
12
|
logout_event: {
|
|
13
13
|
device?: "TRUSTED" | "UNTRUSTED";
|
|
@@ -18,8 +18,8 @@ export declare const dispatchSrvAuthEvents: <Key extends "logout_event" | "jwt_c
|
|
|
18
18
|
};
|
|
19
19
|
declare function dispatchLogoutEvent(device?: 'TRUSTED' | 'UNTRUSTED'): void;
|
|
20
20
|
/**
|
|
21
|
-
* @generic FeatureEnums - feature_names_enums from
|
|
22
|
-
* @generic SrvUrlsEnums - srv_names_enums from
|
|
21
|
+
* @generic FeatureEnums - feature_names_enums from directory introspection
|
|
22
|
+
* @generic SrvUrlsEnums - srv_names_enums from directory introspection
|
|
23
23
|
*/
|
|
24
24
|
export declare function getCachedJwtInternal(): Promise<string | undefined>;
|
|
25
25
|
export declare function checkForRegisteredSubdomainInternal(): Promise<ICheckRegisteredSubdomainResponse<any> | undefined>;
|
|
@@ -89,7 +89,7 @@ export declare function generateSrvAuthBindings<FE extends string>(logout?: () =
|
|
|
89
89
|
/**
|
|
90
90
|
* @deprecated use registerCallbackOnSrvAuthEvents directly
|
|
91
91
|
*/
|
|
92
|
-
registerOnJwtChanges: <Key extends "
|
|
92
|
+
registerOnJwtChanges: <Key extends "jwt_changed" | "logout_event" | "customer_changed">(event: Key, callback: (val: {
|
|
93
93
|
jwt_changed?: ICheckSigninOptions<any>;
|
|
94
94
|
logout_event: {
|
|
95
95
|
device?: "TRUSTED" | "UNTRUSTED";
|
|
@@ -98,7 +98,7 @@ export declare function generateSrvAuthBindings<FE extends string>(logout?: () =
|
|
|
98
98
|
}[Key]) => void) => {
|
|
99
99
|
unregister: () => void;
|
|
100
100
|
};
|
|
101
|
-
registerCallbackOnSrvAuthEvents: <Key extends "
|
|
101
|
+
registerCallbackOnSrvAuthEvents: <Key extends "jwt_changed" | "logout_event" | "customer_changed">(event: Key, callback: (val: {
|
|
102
102
|
jwt_changed?: ICheckSigninOptions<any>;
|
|
103
103
|
logout_event: {
|
|
104
104
|
device?: "TRUSTED" | "UNTRUSTED";
|
|
@@ -177,7 +177,7 @@ export declare function generateSrvAuthBindingsMicroApp(logout?: () => void): IA
|
|
|
177
177
|
/**
|
|
178
178
|
* @deprecated use registerCallbackOnSrvAuthEvents directly
|
|
179
179
|
*/
|
|
180
|
-
registerOnJwtChanges: <Key extends "
|
|
180
|
+
registerOnJwtChanges: <Key extends "jwt_changed" | "logout_event" | "customer_changed">(event: Key, callback: (val: {
|
|
181
181
|
jwt_changed?: ICheckSigninOptions<any>;
|
|
182
182
|
logout_event: {
|
|
183
183
|
device?: "TRUSTED" | "UNTRUSTED";
|
|
@@ -186,7 +186,7 @@ export declare function generateSrvAuthBindingsMicroApp(logout?: () => void): IA
|
|
|
186
186
|
}[Key]) => void) => {
|
|
187
187
|
unregister: () => void;
|
|
188
188
|
};
|
|
189
|
-
registerCallbackOnSrvAuthEvents: <Key extends "
|
|
189
|
+
registerCallbackOnSrvAuthEvents: <Key extends "jwt_changed" | "logout_event" | "customer_changed">(event: Key, callback: (val: {
|
|
190
190
|
jwt_changed?: ICheckSigninOptions<any>;
|
|
191
191
|
logout_event: {
|
|
192
192
|
device?: "TRUSTED" | "UNTRUSTED";
|
|
@@ -14,8 +14,8 @@ function dispatchJwtChangedEvent(jwt) {
|
|
|
14
14
|
dispatchSrvAuthEvents('jwt_changed', jwt, false);
|
|
15
15
|
}
|
|
16
16
|
/**
|
|
17
|
-
* @generic FeatureEnums - feature_names_enums from
|
|
18
|
-
* @generic SrvUrlsEnums - srv_names_enums from
|
|
17
|
+
* @generic FeatureEnums - feature_names_enums from directory introspection
|
|
18
|
+
* @generic SrvUrlsEnums - srv_names_enums from directory introspection
|
|
19
19
|
*/
|
|
20
20
|
//type EnvConfigsFn = () => { SRV_AUTH: string; DEVELOPMENT: boolean; ENVIRONMENT_TO_OPERATE: string }
|
|
21
21
|
export async function getCachedJwtInternal() {
|
package/lib/index.d.ts
CHANGED
|
@@ -17,7 +17,6 @@ export * from './helpers/generateSrvAuthBindings.types.js';
|
|
|
17
17
|
export * from './helpers/getSubdomain.js';
|
|
18
18
|
export * from './helpers/checkForRegisteredSubdomains.js';
|
|
19
19
|
export * from './helpers/clearCacheData.js';
|
|
20
|
-
export * from './helpers/generateGenqlClient.js';
|
|
21
20
|
export * from './helpers/generateEnvConfigsBindings.js';
|
|
22
21
|
export * from './helpers/userTypingSignal.js';
|
|
23
22
|
export * from './helpers/base64ToFile.js';
|
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,
|
|
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"}
|
package/lib/index.js
CHANGED
|
@@ -17,7 +17,6 @@ export * from './helpers/generateSrvAuthBindings.types.js';
|
|
|
17
17
|
export * from './helpers/getSubdomain.js';
|
|
18
18
|
export * from './helpers/checkForRegisteredSubdomains.js';
|
|
19
19
|
export * from './helpers/clearCacheData.js';
|
|
20
|
-
export * from './helpers/generateGenqlClient.js';
|
|
21
20
|
export * from './helpers/generateEnvConfigsBindings.js';
|
|
22
21
|
export * from './helpers/userTypingSignal.js';
|
|
23
22
|
export * from './helpers/base64ToFile.js';
|
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,
|
|
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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "asma-core-helpers",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.9.0",
|
|
4
4
|
"description": "Core helper utilities for ASMA applications",
|
|
5
5
|
"files": [
|
|
6
6
|
"lib/**/*",
|
|
@@ -10,7 +10,11 @@
|
|
|
10
10
|
"type": "module",
|
|
11
11
|
"exports": {
|
|
12
12
|
".": "./lib/index.js",
|
|
13
|
-
"./lib": "./lib/index.js"
|
|
13
|
+
"./lib": "./lib/index.js",
|
|
14
|
+
"./urql": {
|
|
15
|
+
"types": "./lib/helpers/adopusNamespaceExchange.d.ts",
|
|
16
|
+
"default": "./lib/helpers/adopusNamespaceExchange.js"
|
|
17
|
+
}
|
|
14
18
|
},
|
|
15
19
|
"scripts": {
|
|
16
20
|
"build": "npx tsc && npx tsc -p .",
|
|
@@ -23,16 +27,31 @@
|
|
|
23
27
|
"keywords": [],
|
|
24
28
|
"author": "",
|
|
25
29
|
"license": "MIT",
|
|
30
|
+
"peerDependencies": {
|
|
31
|
+
"@urql/core": ">=4",
|
|
32
|
+
"wonka": ">=6"
|
|
33
|
+
},
|
|
34
|
+
"peerDependenciesMeta": {
|
|
35
|
+
"@urql/core": {
|
|
36
|
+
"optional": true
|
|
37
|
+
},
|
|
38
|
+
"wonka": {
|
|
39
|
+
"optional": true
|
|
40
|
+
}
|
|
41
|
+
},
|
|
26
42
|
"devDependencies": {
|
|
27
|
-
"@genql/runtime": "^2.10.0",
|
|
28
43
|
"@openreplay/tracker": "^16.4.10",
|
|
44
|
+
"@urql/core": "^6.0.3",
|
|
29
45
|
"asma-qiankun-react-loader": "^0.8.2",
|
|
30
46
|
"asma-types": "^2.8.0",
|
|
31
47
|
"history": "^5.3.0",
|
|
32
48
|
"lefthook": "^2.1.1",
|
|
33
|
-
"
|
|
49
|
+
"tsx": "^4.23.0",
|
|
50
|
+
"typescript": "^5.6.3",
|
|
51
|
+
"wonka": "^6.3.4"
|
|
34
52
|
},
|
|
35
53
|
"dependencies": {
|
|
54
|
+
"@0no-co/graphql.web": "^1.0.9",
|
|
36
55
|
"asma-event-bus": "^0.7.27",
|
|
37
56
|
"buffer": "^6.0.3",
|
|
38
57
|
"idb-keyval": "^6.2.1",
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
import assert from 'node:assert/strict'
|
|
2
|
+
import { describe, it } from 'node:test'
|
|
3
|
+
|
|
4
|
+
import { parse, print } from '@0no-co/graphql.web'
|
|
5
|
+
|
|
6
|
+
import { adopusSlugFromJwt, denamespaceData, namespaceDocument } from './adopusNamespaceExchange.js'
|
|
7
|
+
|
|
8
|
+
const PREFIXED = new Set(['Actor', 'Actor_bool_exp', 'Int_comparison_exp', 'uniqueidentifier'])
|
|
9
|
+
|
|
10
|
+
const normalize = (sdl: string) => print(parse(sdl))
|
|
11
|
+
|
|
12
|
+
describe('namespaceDocument (transforms 1-3)', () => {
|
|
13
|
+
it('wraps the operation, prefixes variable definition types, leaves builtins alone', () => {
|
|
14
|
+
const doc = parse(`
|
|
15
|
+
query fetchActors($where: Actor_bool_exp, $limit: Int, $id: uniqueidentifier) {
|
|
16
|
+
Actor(where: $where, limit: $limit) { ActorNo Navn }
|
|
17
|
+
}
|
|
18
|
+
`)
|
|
19
|
+
const out = print(namespaceDocument(doc, 'avansas', PREFIXED))
|
|
20
|
+
assert.equal(
|
|
21
|
+
out,
|
|
22
|
+
normalize(`
|
|
23
|
+
query fetchActors($where: avansas_Actor_bool_exp, $limit: Int, $id: avansas_uniqueidentifier) {
|
|
24
|
+
avansas {
|
|
25
|
+
Actor(where: $where, limit: $limit) { ActorNo Navn }
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
`),
|
|
29
|
+
)
|
|
30
|
+
})
|
|
31
|
+
|
|
32
|
+
it('prefixes wrapped list/non-null variable types', () => {
|
|
33
|
+
const doc = parse(`query q($ids: [Int_comparison_exp!]!) { Actor { ActorNo } }`)
|
|
34
|
+
const out = print(namespaceDocument(doc, 'avansas', PREFIXED))
|
|
35
|
+
assert.match(out, /\$ids: \[avansas_Int_comparison_exp!\]!/)
|
|
36
|
+
})
|
|
37
|
+
|
|
38
|
+
it('prefixes inline and named fragment type conditions, at any depth', () => {
|
|
39
|
+
const doc = parse(`
|
|
40
|
+
query q {
|
|
41
|
+
Actor {
|
|
42
|
+
... on Actor { ActorNo }
|
|
43
|
+
ActorActor_Overordnet { ... on Actor { Navn } }
|
|
44
|
+
...actorFields
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
fragment actorFields on Actor { Navn }
|
|
48
|
+
`)
|
|
49
|
+
const out = print(namespaceDocument(doc, 'avansas', PREFIXED))
|
|
50
|
+
assert.equal((out.match(/on avansas_Actor/g) ?? []).length, 3)
|
|
51
|
+
assert.doesNotMatch(out, /on Actor\b/)
|
|
52
|
+
})
|
|
53
|
+
|
|
54
|
+
it('wraps mutations too', () => {
|
|
55
|
+
const doc = parse(`mutation m($w: Actor_bool_exp!) { update_Actor(where: $w) { affected_rows } }`)
|
|
56
|
+
const out = print(namespaceDocument(doc, 'genesisdev', PREFIXED))
|
|
57
|
+
assert.equal(
|
|
58
|
+
out,
|
|
59
|
+
normalize(`
|
|
60
|
+
mutation m($w: genesisdev_Actor_bool_exp!) {
|
|
61
|
+
genesisdev { update_Actor(where: $w) { affected_rows } }
|
|
62
|
+
}
|
|
63
|
+
`),
|
|
64
|
+
)
|
|
65
|
+
})
|
|
66
|
+
})
|
|
67
|
+
|
|
68
|
+
describe('denamespaceData (transforms 4-5)', () => {
|
|
69
|
+
it('unwraps the namespace and strips __typename prefixes deeply', () => {
|
|
70
|
+
const wire = {
|
|
71
|
+
avansas: {
|
|
72
|
+
Actor: [
|
|
73
|
+
{
|
|
74
|
+
__typename: 'avansas_Actor',
|
|
75
|
+
ActorNo: 1,
|
|
76
|
+
ActorActor_Overordnet: [{ __typename: 'avansas_Actor', ActorNo: 2 }],
|
|
77
|
+
},
|
|
78
|
+
],
|
|
79
|
+
},
|
|
80
|
+
}
|
|
81
|
+
assert.deepEqual(denamespaceData(wire, 'avansas'), {
|
|
82
|
+
Actor: [
|
|
83
|
+
{
|
|
84
|
+
__typename: 'Actor',
|
|
85
|
+
ActorNo: 1,
|
|
86
|
+
ActorActor_Overordnet: [{ __typename: 'Actor', ActorNo: 2 }],
|
|
87
|
+
},
|
|
88
|
+
],
|
|
89
|
+
})
|
|
90
|
+
})
|
|
91
|
+
|
|
92
|
+
it('leaves unprefixed __typename values and non-typename fields untouched', () => {
|
|
93
|
+
const wire = { avansas: { Actor: [{ __typename: 'Actor', Navn: 'avansas_not_a_typename' }] } }
|
|
94
|
+
assert.deepEqual(denamespaceData(wire, 'avansas'), {
|
|
95
|
+
Actor: [{ __typename: 'Actor', Navn: 'avansas_not_a_typename' }],
|
|
96
|
+
})
|
|
97
|
+
})
|
|
98
|
+
|
|
99
|
+
it('passes data through when the namespace key is absent', () => {
|
|
100
|
+
assert.deepEqual(denamespaceData({ Actor: [] }, 'avansas'), { Actor: [] })
|
|
101
|
+
})
|
|
102
|
+
})
|
|
103
|
+
|
|
104
|
+
describe('adopusSlugFromJwt', () => {
|
|
105
|
+
const jwtWith = (claims: object) =>
|
|
106
|
+
`x.${Buffer.from(JSON.stringify(claims)).toString('base64url')}.y`
|
|
107
|
+
|
|
108
|
+
it('reads and sanitizes the subdomain claim', () => {
|
|
109
|
+
assert.equal(adopusSlugFromJwt(jwtWith({ subdomain: 'Fretex-Dev' })), 'fretex_dev')
|
|
110
|
+
})
|
|
111
|
+
|
|
112
|
+
it('returns undefined for missing token, missing claim, or unsanitizable subdomain', () => {
|
|
113
|
+
assert.equal(adopusSlugFromJwt(undefined), undefined)
|
|
114
|
+
assert.equal(adopusSlugFromJwt(jwtWith({})), undefined)
|
|
115
|
+
assert.equal(adopusSlugFromJwt(jwtWith({ subdomain: '1-bad!' })), undefined)
|
|
116
|
+
})
|
|
117
|
+
})
|
|
@@ -0,0 +1,215 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* adopusNamespaceExchange — urql exchange that maps unprefixed gql.tada operations onto the
|
|
3
|
+
* consolidated Adopus Hasura engine's per-tenant namespace, at the wire level only.
|
|
4
|
+
*
|
|
5
|
+
* Compile-time types stay the unprefixed avansas/AdOpusTest schema (DEC-004/DEC-011); this
|
|
6
|
+
* exchange rewrites the parsed document + JSON per request/response:
|
|
7
|
+
* 1. request: wrap each operation's selection set in the `<slug>` root field
|
|
8
|
+
* 2. request: prefix schema type names in variable definitions (`Actor_bool_exp` -> `<slug>_Actor_bool_exp`)
|
|
9
|
+
* 3. request: prefix fragment type conditions (inline + named)
|
|
10
|
+
* 4. response: unwrap `data[<slug>]` -> `data`
|
|
11
|
+
* 5. response: strip the `<slug>_` prefix from `__typename` values
|
|
12
|
+
*
|
|
13
|
+
* `prefixedTypes` is the exact set of names the engine prefixes for the tenant source —
|
|
14
|
+
* generated at codegen time by adopus-hsr-wrapper/scripts/unwrap_client_schema.mjs
|
|
15
|
+
* (adopus-prefixed-types.json) so the runtime never guesses which names carry the prefix.
|
|
16
|
+
*
|
|
17
|
+
* Install it only on the SRV_AO_WRAPPER client and only when the resolved endpoint is the
|
|
18
|
+
* consolidated engine (`/api/hsr-wrapper/`) — the per-tenant `srv_urls.ao_wrapper` flip then
|
|
19
|
+
* switches endpoint and namespace mode atomically.
|
|
20
|
+
*
|
|
21
|
+
* @see asma-modules/_docs/adopus-graphql/plans/2026-07-11-00-14-plan-adopus-hasura2-consolidation.md:184 — §2.4.3 (DEC-004/DEC-015)
|
|
22
|
+
*/
|
|
23
|
+
import type { DocumentNode } from '@0no-co/graphql.web'
|
|
24
|
+
import { makeOperation, type Exchange, type Operation, type OperationResult } from '@urql/core'
|
|
25
|
+
import { map, pipe } from 'wonka'
|
|
26
|
+
|
|
27
|
+
// Minimal structural AST model for exactly the nodes the transforms touch — graphql.web's
|
|
28
|
+
// published types carry `kind: any`, which defeats discriminant narrowing; these mirror the
|
|
29
|
+
// spec shape and the public API still speaks graphql.web's DocumentNode.
|
|
30
|
+
interface NameNode {
|
|
31
|
+
kind: 'Name'
|
|
32
|
+
value: string
|
|
33
|
+
}
|
|
34
|
+
interface NamedTypeNode {
|
|
35
|
+
kind: 'NamedType'
|
|
36
|
+
name: NameNode
|
|
37
|
+
}
|
|
38
|
+
type AstTypeNode = NamedTypeNode | { kind: 'ListType' | 'NonNullType'; type: AstTypeNode }
|
|
39
|
+
interface AstFieldNode {
|
|
40
|
+
kind: 'Field'
|
|
41
|
+
name: NameNode
|
|
42
|
+
selectionSet?: AstSelectionSetNode
|
|
43
|
+
}
|
|
44
|
+
interface AstInlineFragmentNode {
|
|
45
|
+
kind: 'InlineFragment'
|
|
46
|
+
typeCondition?: NamedTypeNode
|
|
47
|
+
selectionSet: AstSelectionSetNode
|
|
48
|
+
}
|
|
49
|
+
type AstSelectionNode = AstFieldNode | AstInlineFragmentNode | { kind: 'FragmentSpread'; name: NameNode }
|
|
50
|
+
interface AstSelectionSetNode {
|
|
51
|
+
kind: 'SelectionSet'
|
|
52
|
+
selections: readonly AstSelectionNode[]
|
|
53
|
+
}
|
|
54
|
+
interface AstVariableDefinitionNode {
|
|
55
|
+
kind: 'VariableDefinition'
|
|
56
|
+
type: AstTypeNode
|
|
57
|
+
}
|
|
58
|
+
interface AstOperationDefinitionNode {
|
|
59
|
+
kind: 'OperationDefinition'
|
|
60
|
+
variableDefinitions?: readonly AstVariableDefinitionNode[]
|
|
61
|
+
selectionSet: AstSelectionSetNode
|
|
62
|
+
}
|
|
63
|
+
interface AstFragmentDefinitionNode {
|
|
64
|
+
kind: 'FragmentDefinition'
|
|
65
|
+
typeCondition: NamedTypeNode
|
|
66
|
+
selectionSet: AstSelectionSetNode
|
|
67
|
+
}
|
|
68
|
+
type AstDefinitionNode = AstOperationDefinitionNode | AstFragmentDefinitionNode | { kind: string }
|
|
69
|
+
interface AstDocumentNode {
|
|
70
|
+
kind: 'Document'
|
|
71
|
+
definitions: readonly AstDefinitionNode[]
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
const SLUG_PATTERN = /^[a-z][a-z0-9_]{1,30}$/
|
|
75
|
+
|
|
76
|
+
// not parseJwt.js — that module touches `window` at import time; this subpath stays environment-neutral
|
|
77
|
+
function decodeJwtClaims(jwt: string): { subdomain?: string } | undefined {
|
|
78
|
+
const payload = jwt.split('.')[1]
|
|
79
|
+
if (!payload) return undefined
|
|
80
|
+
try {
|
|
81
|
+
const base64 = payload.replace(/-/g, '+').replace(/_/g, '/')
|
|
82
|
+
return JSON.parse(new TextDecoder().decode(Uint8Array.from(atob(base64), (c) => c.charCodeAt(0))))
|
|
83
|
+
} catch {
|
|
84
|
+
return undefined
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
/**
|
|
89
|
+
* Derive the tenant namespace slug from the main ASMA JWT's `subdomain` claim (DEC-015),
|
|
90
|
+
* sanitized per plan §1.1 (lowercase, hyphens -> underscores). Returns undefined when the
|
|
91
|
+
* token is missing or the claim does not sanitize to a valid slug — callers skip the
|
|
92
|
+
* exchange in that case.
|
|
93
|
+
*/
|
|
94
|
+
export function adopusSlugFromJwt(jwt: string | undefined): string | undefined {
|
|
95
|
+
if (!jwt) return undefined
|
|
96
|
+
const claims = decodeJwtClaims(jwt)
|
|
97
|
+
const slug = claims?.subdomain?.toLowerCase().replace(/-/g, '_')
|
|
98
|
+
if (!slug || !SLUG_PATTERN.test(slug)) {
|
|
99
|
+
console.error(`adopusSlugFromJwt: subdomain claim '${claims?.subdomain}' is not a valid namespace slug`)
|
|
100
|
+
return undefined
|
|
101
|
+
}
|
|
102
|
+
return slug
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
/** Transforms 1–3 on the parsed operation document. Pure; exported for tests. */
|
|
106
|
+
export function namespaceDocument(document: DocumentNode, slug: string, prefixed: ReadonlySet<string>): DocumentNode {
|
|
107
|
+
const doc = document as unknown as AstDocumentNode
|
|
108
|
+
|
|
109
|
+
const prefixName = (name: NameNode): NameNode =>
|
|
110
|
+
prefixed.has(name.value) ? { ...name, value: `${slug}_${name.value}` } : name
|
|
111
|
+
|
|
112
|
+
const prefixType = (type: AstTypeNode): AstTypeNode =>
|
|
113
|
+
type.kind === 'NamedType' ? { ...type, name: prefixName(type.name) } : { ...type, type: prefixType(type.type) }
|
|
114
|
+
|
|
115
|
+
const prefixFragmentConditions = (selectionSet: AstSelectionSetNode): AstSelectionSetNode => ({
|
|
116
|
+
...selectionSet,
|
|
117
|
+
selections: selectionSet.selections.map((sel): AstSelectionNode => {
|
|
118
|
+
if (sel.kind === 'InlineFragment') {
|
|
119
|
+
return {
|
|
120
|
+
...sel,
|
|
121
|
+
typeCondition: sel.typeCondition && { ...sel.typeCondition, name: prefixName(sel.typeCondition.name) },
|
|
122
|
+
selectionSet: prefixFragmentConditions(sel.selectionSet),
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
if (sel.kind === 'Field' && sel.selectionSet) {
|
|
126
|
+
return { ...sel, selectionSet: prefixFragmentConditions(sel.selectionSet) }
|
|
127
|
+
}
|
|
128
|
+
return sel
|
|
129
|
+
}),
|
|
130
|
+
})
|
|
131
|
+
|
|
132
|
+
const out: AstDocumentNode = {
|
|
133
|
+
...doc,
|
|
134
|
+
definitions: doc.definitions.map((def): AstDefinitionNode => {
|
|
135
|
+
if (def.kind === 'OperationDefinition') {
|
|
136
|
+
const op = def as AstOperationDefinitionNode
|
|
137
|
+
const namespaceField: AstFieldNode = {
|
|
138
|
+
kind: 'Field',
|
|
139
|
+
name: { kind: 'Name', value: slug },
|
|
140
|
+
selectionSet: prefixFragmentConditions(op.selectionSet),
|
|
141
|
+
}
|
|
142
|
+
return {
|
|
143
|
+
...op,
|
|
144
|
+
variableDefinitions: op.variableDefinitions?.map((v) => ({ ...v, type: prefixType(v.type) })),
|
|
145
|
+
selectionSet: { kind: 'SelectionSet', selections: [namespaceField] },
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
if (def.kind === 'FragmentDefinition') {
|
|
149
|
+
const frag = def as AstFragmentDefinitionNode
|
|
150
|
+
return {
|
|
151
|
+
...frag,
|
|
152
|
+
typeCondition: { ...frag.typeCondition, name: prefixName(frag.typeCondition.name) },
|
|
153
|
+
selectionSet: prefixFragmentConditions(frag.selectionSet),
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
return def
|
|
157
|
+
}),
|
|
158
|
+
}
|
|
159
|
+
return out as unknown as DocumentNode
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
/** Transforms 4–5 on the response payload. Pure (returns new objects); exported for tests. */
|
|
163
|
+
export function denamespaceData<T>(data: T, slug: string): T {
|
|
164
|
+
const unwrapped =
|
|
165
|
+
data && typeof data === 'object' && !Array.isArray(data) && slug in (data as Record<string, unknown>)
|
|
166
|
+
? (data as Record<string, unknown>)[slug]
|
|
167
|
+
: data
|
|
168
|
+
return stripTypenamePrefix(unwrapped, `${slug}_`) as T
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
function stripTypenamePrefix(value: unknown, prefix: string): unknown {
|
|
172
|
+
if (Array.isArray(value)) return value.map((v) => stripTypenamePrefix(v, prefix))
|
|
173
|
+
if (!value || typeof value !== 'object') return value
|
|
174
|
+
const out: Record<string, unknown> = {}
|
|
175
|
+
for (const [key, v] of Object.entries(value)) {
|
|
176
|
+
out[key] = key === '__typename' && typeof v === 'string' && v.startsWith(prefix) ? v.slice(prefix.length) : stripTypenamePrefix(v, prefix)
|
|
177
|
+
}
|
|
178
|
+
return out
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
/**
|
|
182
|
+
* @param slug tenant namespace — derive with `adopusSlugFromJwt(await getCachedJwt())`
|
|
183
|
+
* @param prefixedTypes contents of the codegen-emitted `adopus-prefixed-types.json`
|
|
184
|
+
*/
|
|
185
|
+
export function adopusNamespaceExchange({
|
|
186
|
+
slug,
|
|
187
|
+
prefixedTypes,
|
|
188
|
+
}: {
|
|
189
|
+
slug: string
|
|
190
|
+
prefixedTypes: readonly string[]
|
|
191
|
+
}): Exchange {
|
|
192
|
+
const prefixed: ReadonlySet<string> = new Set(prefixedTypes)
|
|
193
|
+
// documents are module-level gql.tada constants — stable references, so WeakMap memoizes
|
|
194
|
+
// the rewrite once per document (NOT per operation.key, which varies with variables)
|
|
195
|
+
const rewritten = new WeakMap<DocumentNode, DocumentNode>()
|
|
196
|
+
|
|
197
|
+
const rewriteOperation = (op: Operation): Operation => {
|
|
198
|
+
if (op.kind === 'teardown') return op
|
|
199
|
+
let query = rewritten.get(op.query)
|
|
200
|
+
if (!query) {
|
|
201
|
+
query = namespaceDocument(op.query, slug, prefixed)
|
|
202
|
+
rewritten.set(op.query, query)
|
|
203
|
+
}
|
|
204
|
+
return makeOperation(op.kind, { ...op, query }, op.context)
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
const rewriteResult = (result: OperationResult): OperationResult =>
|
|
208
|
+
result.operation.kind === 'teardown' || result.data == null
|
|
209
|
+
? result // ponytail: error paths keep the <slug> segment — cosmetic, fix if it ever confuses anyone
|
|
210
|
+
: { ...result, data: denamespaceData(result.data, slug) }
|
|
211
|
+
|
|
212
|
+
return ({ forward }) =>
|
|
213
|
+
(ops$) =>
|
|
214
|
+
pipe(forward(pipe(ops$, map(rewriteOperation))), map(rewriteResult))
|
|
215
|
+
}
|
|
@@ -23,8 +23,8 @@ function dispatchJwtChangedEvent(jwt?: ICheckSigninOptions<any>) {
|
|
|
23
23
|
dispatchSrvAuthEvents('jwt_changed', jwt, false)
|
|
24
24
|
}
|
|
25
25
|
/**
|
|
26
|
-
* @generic FeatureEnums - feature_names_enums from
|
|
27
|
-
* @generic SrvUrlsEnums - srv_names_enums from
|
|
26
|
+
* @generic FeatureEnums - feature_names_enums from directory introspection
|
|
27
|
+
* @generic SrvUrlsEnums - srv_names_enums from directory introspection
|
|
28
28
|
*/
|
|
29
29
|
//type EnvConfigsFn = () => { SRV_AUTH: string; DEVELOPMENT: boolean; ENVIRONMENT_TO_OPERATE: string }
|
|
30
30
|
|
package/src/index.ts
CHANGED
|
@@ -18,7 +18,6 @@ export * from './helpers/generateSrvAuthBindings.types.js'
|
|
|
18
18
|
export * from './helpers/getSubdomain.js'
|
|
19
19
|
export * from './helpers/checkForRegisteredSubdomains.js'
|
|
20
20
|
export * from './helpers/clearCacheData.js'
|
|
21
|
-
export * from './helpers/generateGenqlClient.js'
|
|
22
21
|
export * from './helpers/generateEnvConfigsBindings.js'
|
|
23
22
|
export * from './helpers/userTypingSignal.js'
|
|
24
23
|
export * from './helpers/base64ToFile.js'
|
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
import type { ClientOptions } from '@genql/runtime';
|
|
2
|
-
import { type IEnvironmentUrlsGenQLOnly } from './generateEnvConfigsBindings.js';
|
|
3
|
-
export interface CliOptions extends Omit<ClientOptions, 'url' | 'signal'> {
|
|
4
|
-
anonymous?: boolean;
|
|
5
|
-
}
|
|
6
|
-
export declare function generateGenqlClient<T extends ReturnType<typeof createClient>>({ setReqConfig, createClient, service, path, }: {
|
|
7
|
-
setReqConfig?: () => Promise<{
|
|
8
|
-
headers: Record<string, string>;
|
|
9
|
-
}>;
|
|
10
|
-
createClient: (options?: ClientOptions | undefined) => T;
|
|
11
|
-
service: keyof IEnvironmentUrlsGenQLOnly;
|
|
12
|
-
path?: string;
|
|
13
|
-
}): {
|
|
14
|
-
getGenqlClient: () => Promise<T>;
|
|
15
|
-
resetGenqlClient: () => void;
|
|
16
|
-
genqlClient: (options?: CliOptions & {
|
|
17
|
-
abortController?: AbortController;
|
|
18
|
-
}) => Promise<T>;
|
|
19
|
-
genqlClientWs: () => Promise<T>;
|
|
20
|
-
};
|
|
21
|
-
//# sourceMappingURL=generateGenqlClient.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"generateGenqlClient.d.ts","sourceRoot":"","sources":["../../src/helpers/generateGenqlClient.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAA;AAEnD,OAAO,EAEH,KAAK,yBAAyB,EAGjC,MAAM,iCAAiC,CAAA;AAIxC,MAAM,WAAW,UAAW,SAAQ,IAAI,CAAC,aAAa,EAAE,KAAK,GAAG,QAAQ,CAAC;IACrE,SAAS,CAAC,EAAE,OAAO,CAAA;CACtB;AAED,wBAAgB,mBAAmB,CAAC,CAAC,SAAS,UAAU,CAAC,OAAO,YAAY,CAAC,EAAE,EAC3E,YAAY,EACZ,YAAY,EACZ,OAAO,EAEP,IAAoB,GACvB,EAAE;IACC,YAAY,CAAC,EAAE,MAAM,OAAO,CAAC;QAAE,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;KAAE,CAAC,CAAA;IACjE,YAAY,EAAE,CAAC,OAAO,CAAC,EAAE,aAAa,GAAG,SAAS,KAAK,CAAC,CAAA;IAExD,OAAO,EAAE,MAAM,yBAAyB,CAAA;IACxC,IAAI,CAAC,EAAE,MAAM,CAAA;CAChB;;;4BA+DuC,UAAU,GAAG;QAAE,eAAe,CAAC,EAAE,eAAe,CAAA;KAAE,KAAQ,OAAO,CAAC,CAAC,CAAC;;EAqD3G"}
|
|
@@ -1,98 +0,0 @@
|
|
|
1
|
-
import { httpToWs } from './Config.js';
|
|
2
|
-
import { EnvConfigsFnInternal,
|
|
3
|
-
//IKeyEnvironmentUrls,
|
|
4
|
-
//IKeyEnvironmentUrlsOmit,
|
|
5
|
-
} from './generateEnvConfigsBindings.js';
|
|
6
|
-
import { getSrvUrlsInternal, registerCallbackOnSrvAuthEvents, setReqConfigInternal } from './generateSrvAuthBindings.js';
|
|
7
|
-
export function generateGenqlClient({ setReqConfig, createClient, service,
|
|
8
|
-
//serviceUrl,
|
|
9
|
-
path = '/v1/graphql', }) {
|
|
10
|
-
let client = null;
|
|
11
|
-
let wsClient = null;
|
|
12
|
-
let local_abortController_registry = [];
|
|
13
|
-
registerCallbackOnSrvAuthEvents('logout_event', () => {
|
|
14
|
-
local_abortController_registry.forEach((ac) => ac.abort());
|
|
15
|
-
resetClients();
|
|
16
|
-
});
|
|
17
|
-
function resetClients() {
|
|
18
|
-
client = null;
|
|
19
|
-
wsClient = null;
|
|
20
|
-
local_abortController_registry = [];
|
|
21
|
-
}
|
|
22
|
-
//registerCallbackOnSrvAuthEvents('logout_event', resetClients)
|
|
23
|
-
async function getGenqlClient() {
|
|
24
|
-
if (client === null) {
|
|
25
|
-
client = await genqlClient();
|
|
26
|
-
return client;
|
|
27
|
-
}
|
|
28
|
-
return client;
|
|
29
|
-
}
|
|
30
|
-
function resetGenqlClient() {
|
|
31
|
-
client = null;
|
|
32
|
-
wsClient = null;
|
|
33
|
-
}
|
|
34
|
-
function serviceUrlFn() {
|
|
35
|
-
let service_url = EnvConfigsFnInternal()[service];
|
|
36
|
-
if ('SRV_AO_WRAPPER' === service) {
|
|
37
|
-
const url = getSrvUrlsInternal()?.ao_wrapper;
|
|
38
|
-
if (url) {
|
|
39
|
-
service_url = url;
|
|
40
|
-
}
|
|
41
|
-
}
|
|
42
|
-
else if (service === 'SRV_CONNECTOR') {
|
|
43
|
-
const url = getSrvUrlsInternal()?.connector;
|
|
44
|
-
if (url) {
|
|
45
|
-
service_url = url;
|
|
46
|
-
}
|
|
47
|
-
}
|
|
48
|
-
if (!service_url) {
|
|
49
|
-
const message = `'required param serviceUrl() is undefined, please check EnvConfig object!', service: ${service}`;
|
|
50
|
-
throw Error(message);
|
|
51
|
-
}
|
|
52
|
-
console.log('asma-helpers - generateGenqlClient service_url', service_url);
|
|
53
|
-
return service_url;
|
|
54
|
-
}
|
|
55
|
-
const reqConf = setReqConfig || setReqConfigInternal;
|
|
56
|
-
async function genqlClient(options = {}) {
|
|
57
|
-
const { headers, abortController: abortControllerFromOpts, ...rest } = options;
|
|
58
|
-
/* if (!serviceUrl()) {
|
|
59
|
-
throw Error('required param srv_url is undefined, please check EnvConfig object!')
|
|
60
|
-
} */
|
|
61
|
-
const abortControllerLocal = createAbortControllerAndAbortOnLogoutEvent(abortControllerFromOpts);
|
|
62
|
-
const serviceUrlWithPath = serviceUrlFn() + path;
|
|
63
|
-
return createClient({
|
|
64
|
-
url: serviceUrlWithPath,
|
|
65
|
-
headers: async () => ({
|
|
66
|
-
...(options.anonymous ? {} : ((await reqConf()).headers ?? {})),
|
|
67
|
-
...headers,
|
|
68
|
-
}),
|
|
69
|
-
signal: abortControllerLocal.signal,
|
|
70
|
-
batch: { batchInterval: 50, maxBatchSize: 100 },
|
|
71
|
-
...rest,
|
|
72
|
-
});
|
|
73
|
-
}
|
|
74
|
-
async function genqlClientWs() {
|
|
75
|
-
if (!wsClient) {
|
|
76
|
-
const aborControllerLocal = createAbortControllerAndAbortOnLogoutEvent();
|
|
77
|
-
wsClient = createClient({
|
|
78
|
-
url: `${httpToWs(serviceUrlFn())}${path}`,
|
|
79
|
-
cache: 'reload',
|
|
80
|
-
batch: { batchInterval: 50, maxBatchSize: 100 },
|
|
81
|
-
signal: aborControllerLocal.signal,
|
|
82
|
-
subscription: {
|
|
83
|
-
reconnect: true,
|
|
84
|
-
reconnectionAttempts: 5,
|
|
85
|
-
headers: async () => ((await reqConf()).headers ?? {}),
|
|
86
|
-
},
|
|
87
|
-
});
|
|
88
|
-
}
|
|
89
|
-
return wsClient;
|
|
90
|
-
}
|
|
91
|
-
function createAbortControllerAndAbortOnLogoutEvent(abortControllerFromFnSig) {
|
|
92
|
-
const localAbrotController = abortControllerFromFnSig || new AbortController();
|
|
93
|
-
local_abortController_registry.push(localAbrotController);
|
|
94
|
-
return localAbrotController;
|
|
95
|
-
}
|
|
96
|
-
return { getGenqlClient, resetGenqlClient, genqlClient, genqlClientWs };
|
|
97
|
-
}
|
|
98
|
-
//# sourceMappingURL=generateGenqlClient.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"generateGenqlClient.js","sourceRoot":"","sources":["../../src/helpers/generateGenqlClient.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,145 +0,0 @@
|
|
|
1
|
-
import type { createClient } from '@genql/runtime'
|
|
2
|
-
import type { ClientOptions } from '@genql/runtime'
|
|
3
|
-
import { httpToWs } from './Config.js'
|
|
4
|
-
import {
|
|
5
|
-
EnvConfigsFnInternal,
|
|
6
|
-
type IEnvironmentUrlsGenQLOnly,
|
|
7
|
-
//IKeyEnvironmentUrls,
|
|
8
|
-
//IKeyEnvironmentUrlsOmit,
|
|
9
|
-
} from './generateEnvConfigsBindings.js'
|
|
10
|
-
import { getSrvUrlsInternal, registerCallbackOnSrvAuthEvents, setReqConfigInternal } from './generateSrvAuthBindings.js'
|
|
11
|
-
//import { parseJwt } from '../helpers/parseJwt'
|
|
12
|
-
|
|
13
|
-
export interface CliOptions extends Omit<ClientOptions, 'url' | 'signal'> {
|
|
14
|
-
anonymous?: boolean
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
export function generateGenqlClient<T extends ReturnType<typeof createClient>>({
|
|
18
|
-
setReqConfig,
|
|
19
|
-
createClient,
|
|
20
|
-
service,
|
|
21
|
-
//serviceUrl,
|
|
22
|
-
path = '/v1/graphql',
|
|
23
|
-
}: {
|
|
24
|
-
setReqConfig?: () => Promise<{ headers: Record<string, string> }>
|
|
25
|
-
createClient: (options?: ClientOptions | undefined) => T
|
|
26
|
-
//serviceUrl?: () => string
|
|
27
|
-
service: keyof IEnvironmentUrlsGenQLOnly
|
|
28
|
-
path?: string
|
|
29
|
-
}) {
|
|
30
|
-
let client: T | null = null
|
|
31
|
-
|
|
32
|
-
let wsClient: T | null = null
|
|
33
|
-
|
|
34
|
-
let local_abortController_registry: AbortController[] = []
|
|
35
|
-
|
|
36
|
-
registerCallbackOnSrvAuthEvents('logout_event', () => {
|
|
37
|
-
local_abortController_registry.forEach((ac) => ac.abort())
|
|
38
|
-
|
|
39
|
-
resetClients()
|
|
40
|
-
})
|
|
41
|
-
|
|
42
|
-
function resetClients() {
|
|
43
|
-
client = null
|
|
44
|
-
|
|
45
|
-
wsClient = null
|
|
46
|
-
|
|
47
|
-
local_abortController_registry = []
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
//registerCallbackOnSrvAuthEvents('logout_event', resetClients)
|
|
51
|
-
|
|
52
|
-
async function getGenqlClient() {
|
|
53
|
-
if (client === null) {
|
|
54
|
-
client = await genqlClient()
|
|
55
|
-
|
|
56
|
-
return client
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
return client
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
function resetGenqlClient() {
|
|
63
|
-
client = null
|
|
64
|
-
|
|
65
|
-
wsClient = null
|
|
66
|
-
}
|
|
67
|
-
function serviceUrlFn() {
|
|
68
|
-
let service_url = EnvConfigsFnInternal()[service]
|
|
69
|
-
|
|
70
|
-
if ('SRV_AO_WRAPPER' === service) {
|
|
71
|
-
const url = getSrvUrlsInternal()?.ao_wrapper
|
|
72
|
-
|
|
73
|
-
if (url) {
|
|
74
|
-
service_url = url
|
|
75
|
-
}
|
|
76
|
-
} else if (service === 'SRV_CONNECTOR') {
|
|
77
|
-
const url = getSrvUrlsInternal()?.connector
|
|
78
|
-
if (url) {
|
|
79
|
-
service_url = url
|
|
80
|
-
}
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
if (!service_url) {
|
|
84
|
-
const message = `'required param serviceUrl() is undefined, please check EnvConfig object!', service: ${service}`
|
|
85
|
-
throw Error(message)
|
|
86
|
-
}
|
|
87
|
-
console.log('asma-helpers - generateGenqlClient service_url', service_url)
|
|
88
|
-
return service_url
|
|
89
|
-
}
|
|
90
|
-
const reqConf = setReqConfig || setReqConfigInternal
|
|
91
|
-
|
|
92
|
-
async function genqlClient(options: CliOptions & { abortController?: AbortController } = {}): Promise<T> {
|
|
93
|
-
const { headers, abortController: abortControllerFromOpts, ...rest } = options
|
|
94
|
-
|
|
95
|
-
/* if (!serviceUrl()) {
|
|
96
|
-
throw Error('required param srv_url is undefined, please check EnvConfig object!')
|
|
97
|
-
} */
|
|
98
|
-
|
|
99
|
-
const abortControllerLocal = createAbortControllerAndAbortOnLogoutEvent(abortControllerFromOpts)
|
|
100
|
-
|
|
101
|
-
const serviceUrlWithPath = serviceUrlFn() + path
|
|
102
|
-
|
|
103
|
-
return createClient({
|
|
104
|
-
url: serviceUrlWithPath,
|
|
105
|
-
headers: async () => ({
|
|
106
|
-
...(options.anonymous ? {} : (((await reqConf()).headers ?? {}) as Record<string, string>)),
|
|
107
|
-
...headers,
|
|
108
|
-
}),
|
|
109
|
-
|
|
110
|
-
signal: abortControllerLocal.signal,
|
|
111
|
-
batch: { batchInterval: 50, maxBatchSize: 100 },
|
|
112
|
-
...rest,
|
|
113
|
-
})
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
async function genqlClientWs() {
|
|
117
|
-
if (!wsClient) {
|
|
118
|
-
const aborControllerLocal = createAbortControllerAndAbortOnLogoutEvent()
|
|
119
|
-
|
|
120
|
-
wsClient = createClient({
|
|
121
|
-
url: `${httpToWs(serviceUrlFn())}${path}`,
|
|
122
|
-
cache: 'reload',
|
|
123
|
-
batch: { batchInterval: 50, maxBatchSize: 100 },
|
|
124
|
-
signal: aborControllerLocal.signal,
|
|
125
|
-
subscription: {
|
|
126
|
-
reconnect: true,
|
|
127
|
-
reconnectionAttempts: 5,
|
|
128
|
-
headers: async () => ((await reqConf()).headers ?? {}) as Record<string, string>,
|
|
129
|
-
},
|
|
130
|
-
})
|
|
131
|
-
}
|
|
132
|
-
|
|
133
|
-
return wsClient
|
|
134
|
-
}
|
|
135
|
-
|
|
136
|
-
function createAbortControllerAndAbortOnLogoutEvent(abortControllerFromFnSig?: AbortController) {
|
|
137
|
-
const localAbrotController = abortControllerFromFnSig || new AbortController()
|
|
138
|
-
|
|
139
|
-
local_abortController_registry.push(localAbrotController)
|
|
140
|
-
|
|
141
|
-
return localAbrotController
|
|
142
|
-
}
|
|
143
|
-
|
|
144
|
-
return { getGenqlClient, resetGenqlClient, genqlClient, genqlClientWs }
|
|
145
|
-
}
|