@econneq/gql-auth 1.2.10 → 2.0.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.
Files changed (51) hide show
  1. package/README.md +304 -22
  2. package/dist/api-factory.d.ts +11 -29
  3. package/dist/api-factory.d.ts.map +1 -1
  4. package/dist/api-factory.js +98 -47
  5. package/dist/api-factory.js.map +1 -0
  6. package/dist/authServer.d.ts +32 -0
  7. package/dist/authServer.d.ts.map +1 -0
  8. package/dist/authServer.js +93 -0
  9. package/dist/authServer.js.map +1 -0
  10. package/dist/client.d.ts +28 -14
  11. package/dist/client.d.ts.map +1 -1
  12. package/dist/client.js +77 -36
  13. package/dist/client.js.map +1 -0
  14. package/dist/env.d.ts +35 -0
  15. package/dist/env.d.ts.map +1 -0
  16. package/dist/env.js +65 -0
  17. package/dist/env.js.map +1 -0
  18. package/dist/errors.d.ts +10 -0
  19. package/dist/errors.d.ts.map +1 -0
  20. package/dist/errors.js +24 -0
  21. package/dist/errors.js.map +1 -0
  22. package/dist/functions.d.ts +24 -0
  23. package/dist/functions.d.ts.map +1 -0
  24. package/dist/functions.js +86 -0
  25. package/dist/functions.js.map +1 -0
  26. package/dist/index.d.ts +11 -84
  27. package/dist/index.d.ts.map +1 -1
  28. package/dist/index.js +22 -8
  29. package/dist/index.js.map +1 -0
  30. package/dist/query-server.d.ts +31 -12
  31. package/dist/query-server.d.ts.map +1 -1
  32. package/dist/query-server.js +63 -20
  33. package/dist/query-server.js.map +1 -0
  34. package/dist/tenant.d.ts +21 -0
  35. package/dist/tenant.d.ts.map +1 -0
  36. package/dist/tenant.js +50 -0
  37. package/dist/tenant.js.map +1 -0
  38. package/dist/types.d.ts +124 -0
  39. package/dist/types.d.ts.map +1 -0
  40. package/dist/types.js +5 -0
  41. package/dist/types.js.map +1 -0
  42. package/dist/upload-gql.d.ts +2 -20
  43. package/dist/upload-gql.d.ts.map +1 -1
  44. package/dist/upload-gql.js +63 -33
  45. package/dist/upload-gql.js.map +1 -0
  46. package/dist/utils.d.ts +24 -0
  47. package/dist/utils.d.ts.map +1 -0
  48. package/dist/utils.js +257 -0
  49. package/dist/utilsGeneral.d.ts +1 -1
  50. package/dist/utilsGeneral.d.ts.map +1 -1
  51. package/package.json +49 -22
@@ -1,14 +1,33 @@
1
- type ServerQueryArgs = {
2
- query: any;
3
- variables?: Record<string, any>;
4
- domain?: string | null;
5
- config: {
6
- protocol: string;
7
- RootApi: string;
8
- Subdomains: any[];
9
- apiKey: string;
10
- };
11
- };
1
+ import type { ServerMutationArgs, ServerQueryArgs } from "./types";
2
+ /**
3
+ * Run a GraphQL **query** from the server side.
4
+ *
5
+ * @example
6
+ * ```ts
7
+ * const data = await queryServerGraphQL<MyQuery>({
8
+ * query: MY_QUERY_GQL,
9
+ * variables: { id: "1" },
10
+ * domain: params.domain, // omit for single-tenant
11
+ * config,
12
+ * });
13
+ * ```
14
+ */
12
15
  export declare function queryServerGraphQL<T = any>({ query, variables, domain, config, }: ServerQueryArgs): Promise<T | null>;
13
- export {};
16
+ /**
17
+ * Run a GraphQL **mutation** from the server side.
18
+ *
19
+ * Useful in Server Actions or Route Handlers where you need to
20
+ * write data without going through the browser proxy.
21
+ *
22
+ * @example
23
+ * ```ts
24
+ * const data = await mutateServerGraphQL<MyMutation>({
25
+ * query: MY_MUTATION_GQL,
26
+ * variables: { input: { name: "Alice" } },
27
+ * domain: "acme",
28
+ * config,
29
+ * });
30
+ * ```
31
+ */
32
+ export declare function mutateServerGraphQL<T = any>({ query, variables, domain, config, }: ServerMutationArgs): Promise<T | null>;
14
33
  //# sourceMappingURL=query-server.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"query-server.d.ts","sourceRoot":"","sources":["../src/query-server.ts"],"names":[],"mappings":"AAMA,KAAK,eAAe,GAAG;IACrB,KAAK,EAAE,GAAG,CAAC;IACX,SAAS,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAChC,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,MAAM,EAAE;QACN,QAAQ,EAAE,MAAM,CAAC;QACjB,OAAO,EAAE,MAAM,CAAC;QAChB,UAAU,EAAE,GAAG,EAAE,CAAC;QAClB,MAAM,EAAE,MAAM,CAAC;KAChB,CAAC;CACH,CAAC;AAEF,wBAAsB,kBAAkB,CAAC,CAAC,GAAG,GAAG,EAAE,EAChD,KAAK,EACL,SAAc,EACd,MAAM,EACN,MAAM,GACP,EAAE,eAAe,GAAG,OAAO,CAAC,CAAC,GAAG,IAAI,CAAC,CA8BrC"}
1
+ {"version":3,"file":"query-server.d.ts","sourceRoot":"","sources":["../src/query-server.ts"],"names":[],"mappings":"AAaA,OAAO,KAAK,EAAE,kBAAkB,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AAKnE;;;;;;;;;;;;GAYG;AACH,wBAAsB,kBAAkB,CAAC,CAAC,GAAG,GAAG,EAAE,EAChD,KAAK,EACL,SAAc,EACd,MAAM,EACN,MAAM,GACP,EAAE,eAAe,GAAG,OAAO,CAAC,CAAC,GAAG,IAAI,CAAC,CAerC;AAID;;;;;;;;;;;;;;;GAeG;AACH,wBAAsB,mBAAmB,CAAC,CAAC,GAAG,GAAG,EAAE,EACjD,KAAK,EACL,SAAc,EACd,MAAM,EACN,MAAM,GACP,EAAE,kBAAkB,GAAG,OAAO,CAAC,CAAC,GAAG,IAAI,CAAC,CAexC"}
@@ -1,31 +1,74 @@
1
- // src/server-query.ts
2
- /// <reference types="next" />
3
- 'use server';
4
- import { cookies } from 'next/headers';
5
- import getApolloClient from './client.js';
1
+ // ============================================================
2
+ // @econneq/gql-auth Server-side GraphQL helpers
3
+ // ============================================================
4
+ //
5
+ // These functions are intended for use in Next.js Server
6
+ // Components, Server Actions, and API Routes.
7
+ //
8
+ // They connect through the internal Docker network and forward
9
+ // the caller's cookie string so Django session auth works.
10
+ // ─────────────────────────────────────────────────────────────
11
+ "use server";
12
+ import { getApolloClient } from "./client";
13
+ // ─── Query ───────────────────────────────────────────────────
14
+ /**
15
+ * Run a GraphQL **query** from the server side.
16
+ *
17
+ * @example
18
+ * ```ts
19
+ * const data = await queryServerGraphQL<MyQuery>({
20
+ * query: MY_QUERY_GQL,
21
+ * variables: { id: "1" },
22
+ * domain: params.domain, // omit for single-tenant
23
+ * config,
24
+ * });
25
+ * ```
26
+ */
6
27
  export async function queryServerGraphQL({ query, variables = {}, domain, config, }) {
7
28
  try {
8
- // 1. Get server-side cookies
9
- const cookieStore = await cookies();
10
- const cookieString = cookieStore.toString();
11
- // 2. Call getApolloClient with the correct 3 arguments:
12
- // Arg 1: options (cookies)
13
- // Arg 2: domain (subdomain string)
14
- // Arg 3: config (URLs and Subdomain array)
15
- const client = await getApolloClient({ cookie: cookieString }, domain, config);
16
- if (!client)
17
- return null;
29
+ const client = await getApolloClient({ domain, config });
18
30
  const result = await client.query({
19
31
  query,
20
32
  variables,
21
- fetchPolicy: 'no-cache',
33
+ fetchPolicy: "no-cache",
22
34
  });
23
- console.log("getting @e-conneq/gql-auth ........");
24
- return result?.data;
35
+ return result?.data ?? null;
25
36
  }
26
37
  catch (err) {
27
- // On the server, we console.error instead of using Swal
28
- console.error("GraphQL Server Error:", err);
38
+ console.error("[@econneq/gql-auth] queryServerGraphQL error:", err);
29
39
  return null;
30
40
  }
31
41
  }
42
+ // ─── Mutation ─────────────────────────────────────────────────
43
+ /**
44
+ * Run a GraphQL **mutation** from the server side.
45
+ *
46
+ * Useful in Server Actions or Route Handlers where you need to
47
+ * write data without going through the browser proxy.
48
+ *
49
+ * @example
50
+ * ```ts
51
+ * const data = await mutateServerGraphQL<MyMutation>({
52
+ * query: MY_MUTATION_GQL,
53
+ * variables: { input: { name: "Alice" } },
54
+ * domain: "acme",
55
+ * config,
56
+ * });
57
+ * ```
58
+ */
59
+ export async function mutateServerGraphQL({ query, variables = {}, domain, config, }) {
60
+ try {
61
+ const client = await getApolloClient({ domain, config });
62
+ const result = await client.mutate({
63
+ mutation: query,
64
+ variables,
65
+ fetchPolicy: "no-cache",
66
+ });
67
+ return result?.data ?? null;
68
+ }
69
+ catch (err) {
70
+ console.error("[@econneq/gql-auth] mutateServerGraphQL error:", err);
71
+ return null;
72
+ }
73
+ }
74
+ //# sourceMappingURL=query-server.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"query-server.js","sourceRoot":"","sources":["../src/query-server.ts"],"names":[],"mappings":"AAAA,+DAA+D;AAC/D,kDAAkD;AAClD,+DAA+D;AAC/D,EAAE;AACF,yDAAyD;AACzD,8CAA8C;AAC9C,EAAE;AACF,+DAA+D;AAC/D,2DAA2D;AAC3D,gEAAgE;AAEhE,YAAY,CAAC;AAGb,OAAO,EAAE,eAAe,EAAE,MAAM,UAAU,CAAC;AAE3C,gEAAgE;AAEhE;;;;;;;;;;;;GAYG;AACH,MAAM,CAAC,KAAK,UAAU,kBAAkB,CAAU,EAChD,KAAK,EACL,SAAS,GAAG,EAAE,EACd,MAAM,EACN,MAAM,GACU;IAChB,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,MAAM,eAAe,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;QAEzD,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,KAAK,CAAI;YACnC,KAAK;YACL,SAAS;YACT,WAAW,EAAE,UAAU;SACxB,CAAC,CAAC;QAEH,OAAO,MAAM,EAAE,IAAI,IAAI,IAAI,CAAC;IAC9B,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,OAAO,CAAC,KAAK,CAAC,+CAA+C,EAAE,GAAG,CAAC,CAAC;QACpE,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED,iEAAiE;AAEjE;;;;;;;;;;;;;;;GAeG;AACH,MAAM,CAAC,KAAK,UAAU,mBAAmB,CAAU,EACjD,KAAK,EACL,SAAS,GAAG,EAAE,EACd,MAAM,EACN,MAAM,GACa;IACnB,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,MAAM,eAAe,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;QAEzD,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,MAAM,CAAI;YACpC,QAAQ,EAAE,KAAK;YACf,SAAS;YACT,WAAW,EAAE,UAAU;SACxB,CAAC,CAAC;QAEH,OAAO,MAAM,EAAE,IAAI,IAAI,IAAI,CAAC;IAC9B,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,OAAO,CAAC,KAAK,CAAC,gDAAgD,EAAE,GAAG,CAAC,CAAC;QACrE,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC"}
@@ -0,0 +1,21 @@
1
+ import type { ConfigType, SubdomainItem, TenantParams } from "./types";
2
+ export type ResolvedTenant = SubdomainItem | null;
3
+ /**
4
+ * Resolves a tenant from the config.
5
+ *
6
+ * - Multi-tenant: matches params.domain against Subdomains[].subdomain
7
+ * - Single-tenant: returns Subdomains[0] when no domain is provided
8
+ * - Returns null when the Subdomains list is empty
9
+ */
10
+ export declare function resolveTenant(config: ConfigType, params?: TenantParams): ResolvedTenant;
11
+ /**
12
+ * Build the HTTP headers that identify a tenant to the backend.
13
+ * Returns an empty object when no tenant is resolved (public routes).
14
+ */
15
+ export declare function buildTenantHeaders(tenant: ResolvedTenant, apiKey?: string): Record<string, string>;
16
+ /**
17
+ * Throw when a multi-tenant setup cannot resolve the requested domain.
18
+ * Safe to call even in single-tenant mode (domain is undefined → no throw).
19
+ */
20
+ export declare function assertTenant(tenant: ResolvedTenant, domain?: string): asserts tenant is SubdomainItem;
21
+ //# sourceMappingURL=tenant.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tenant.d.ts","sourceRoot":"","sources":["../src/tenant.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,UAAU,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAEvE,MAAM,MAAM,cAAc,GAAG,aAAa,GAAG,IAAI,CAAC;AAElD;;;;;;GAMG;AACH,wBAAgB,aAAa,CAC3B,MAAM,EAAE,UAAU,EAClB,MAAM,CAAC,EAAE,YAAY,GACpB,cAAc,CAchB;AAED;;;GAGG;AACH,wBAAgB,kBAAkB,CAChC,MAAM,EAAE,cAAc,EACtB,MAAM,CAAC,EAAE,MAAM,GACd,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CASxB;AAED;;;GAGG;AACH,wBAAgB,YAAY,CAC1B,MAAM,EAAE,cAAc,EACtB,MAAM,CAAC,EAAE,MAAM,GACd,OAAO,CAAC,MAAM,IAAI,aAAa,CAOjC"}
package/dist/tenant.js ADDED
@@ -0,0 +1,50 @@
1
+ // ============================================================
2
+ // @econneq/gql-auth — Tenant resolver
3
+ // ============================================================
4
+ //
5
+ // Works for both single-tenant (no domain supplied) and
6
+ // multi-tenant (domain matched against Subdomains list).
7
+ // ─────────────────────────────────────────────────────────────
8
+ /**
9
+ * Resolves a tenant from the config.
10
+ *
11
+ * - Multi-tenant: matches params.domain against Subdomains[].subdomain
12
+ * - Single-tenant: returns Subdomains[0] when no domain is provided
13
+ * - Returns null when the Subdomains list is empty
14
+ */
15
+ export function resolveTenant(config, params) {
16
+ const { Subdomains } = config;
17
+ if (!Subdomains?.length)
18
+ return null;
19
+ const domain = params?.domain?.toLowerCase();
20
+ if (domain) {
21
+ return (Subdomains.find((s) => s.subdomain.toLowerCase() === domain) ?? null);
22
+ }
23
+ // Single-tenant fallback — use the first entry
24
+ return Subdomains[0] ?? null;
25
+ }
26
+ /**
27
+ * Build the HTTP headers that identify a tenant to the backend.
28
+ * Returns an empty object when no tenant is resolved (public routes).
29
+ */
30
+ export function buildTenantHeaders(tenant, apiKey) {
31
+ if (!tenant)
32
+ return {};
33
+ return {
34
+ "X-Tenant-ID": tenant.subdomain,
35
+ "X-Process-ID": tenant.processId ?? "",
36
+ "X-Widget-ID": tenant.widgetID ?? "",
37
+ ...(apiKey ? { "X-API-KEY": apiKey } : {}),
38
+ };
39
+ }
40
+ /**
41
+ * Throw when a multi-tenant setup cannot resolve the requested domain.
42
+ * Safe to call even in single-tenant mode (domain is undefined → no throw).
43
+ */
44
+ export function assertTenant(tenant, domain) {
45
+ if (!tenant) {
46
+ throw new Error(`[@econneq/gql-auth] No tenant found${domain ? ` for domain "${domain}"` : ""}. ` +
47
+ `Check your config.Subdomains list.`);
48
+ }
49
+ }
50
+ //# sourceMappingURL=tenant.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tenant.js","sourceRoot":"","sources":["../src/tenant.ts"],"names":[],"mappings":"AAAA,+DAA+D;AAC/D,sCAAsC;AACtC,+DAA+D;AAC/D,EAAE;AACF,wDAAwD;AACxD,yDAAyD;AACzD,gEAAgE;AAMhE;;;;;;GAMG;AACH,MAAM,UAAU,aAAa,CAC3B,MAAkB,EAClB,MAAqB;IAErB,MAAM,EAAE,UAAU,EAAE,GAAG,MAAM,CAAC;IAC9B,IAAI,CAAC,UAAU,EAAE,MAAM;QAAE,OAAO,IAAI,CAAC;IAErC,MAAM,MAAM,GAAG,MAAM,EAAE,MAAM,EAAE,WAAW,EAAE,CAAC;IAE7C,IAAI,MAAM,EAAE,CAAC;QACX,OAAO,CACL,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC,WAAW,EAAE,KAAK,MAAM,CAAC,IAAI,IAAI,CACrE,CAAC;IACJ,CAAC;IAED,+CAA+C;IAC/C,OAAO,UAAU,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC;AAC/B,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,kBAAkB,CAChC,MAAsB,EACtB,MAAe;IAEf,IAAI,CAAC,MAAM;QAAE,OAAO,EAAE,CAAC;IAEvB,OAAO;QACL,aAAa,EAAE,MAAM,CAAC,SAAS;QAC/B,cAAc,EAAE,MAAM,CAAC,SAAS,IAAI,EAAE;QACtC,aAAa,EAAE,MAAM,CAAC,QAAQ,IAAI,EAAE;QACpC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,WAAW,EAAE,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;KAC3C,CAAC;AACJ,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,YAAY,CAC1B,MAAsB,EACtB,MAAe;IAEf,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,MAAM,IAAI,KAAK,CACb,sCAAsC,MAAM,CAAC,CAAC,CAAC,gBAAgB,MAAM,GAAG,CAAC,CAAC,CAAC,EAAE,IAAI;YAC/E,oCAAoC,CACvC,CAAC;IACJ,CAAC;AACH,CAAC"}
@@ -0,0 +1,124 @@
1
+ export type SubdomainItem = {
2
+ id: number;
3
+ subdomain: string;
4
+ processId: string;
5
+ widgetID?: string;
6
+ };
7
+ export type ConfigType = {
8
+ Subdomains: SubdomainItem[];
9
+ fonts?: string[];
10
+ };
11
+ export type ApolloOptions = {
12
+ csrfToken?: string;
13
+ cookie?: string;
14
+ };
15
+ export interface JwtPayload {
16
+ iss?: string;
17
+ sub?: string;
18
+ aud?: string[] | string;
19
+ exp: number;
20
+ nbf?: number;
21
+ iat?: number;
22
+ jti?: string;
23
+ user_id?: number;
24
+ username?: string;
25
+ matricle?: string;
26
+ photo?: string;
27
+ is_superuser?: boolean;
28
+ is_staff?: boolean;
29
+ is_active?: boolean;
30
+ is_hod?: boolean;
31
+ role?: string;
32
+ depts?: string[] | any;
33
+ page?: string[] | any;
34
+ school?: number[] | any;
35
+ domain?: number[] | any;
36
+ permissions?: string[];
37
+ language?: string[];
38
+ last_login?: any;
39
+ }
40
+ export interface InterLoginData {
41
+ username: string;
42
+ password: string;
43
+ parent?: boolean;
44
+ }
45
+ /**
46
+ * Describes which tenant is being targeted.
47
+ * For single-tenant setups, domain can be omitted — the first
48
+ * Subdomain entry will be used as a fallback.
49
+ */
50
+ export type TenantParams = {
51
+ domain?: string;
52
+ [key: string]: any;
53
+ };
54
+ export type AlertOptions = {
55
+ title: string;
56
+ status: boolean;
57
+ duration: number;
58
+ };
59
+ export type ApiFactoryOptions = {
60
+ /** New data (single object or array). */
61
+ newData?: any;
62
+ /** Existing data to update (merged with newData when present). */
63
+ editData?: any;
64
+ /** The top-level GraphQL mutation name, e.g. "createUser". */
65
+ mutationName: string;
66
+ /** The nested model key inside the mutation response, e.g. "user". */
67
+ modelName: string;
68
+ /** Which field from the result to display in the success alert. Default: "title". */
69
+ successField?: string;
70
+ /** The GraphQL DocumentNode (gql``). */
71
+ query: any;
72
+ /** Tenant routing params — domain can be omitted for single-tenant. */
73
+ params?: TenantParams;
74
+ /** Next.js router (or any object with a push() method). */
75
+ router?: any;
76
+ /** JWT bearer token. Falls back to cookie-based token when omitted. */
77
+ token?: string;
78
+ /** Package config with Subdomains list. */
79
+ config: ConfigType;
80
+ /** Callback for user-visible alerts. */
81
+ onAlert: (options: AlertOptions) => void;
82
+ /** Redirect after success? Requires redirectPath. */
83
+ redirect?: boolean;
84
+ /** Path to push to after a successful mutation. */
85
+ redirectPath?: string;
86
+ /**
87
+ * When true, returns the `successField` value from the first result
88
+ * instead of triggering alert/reload.
89
+ */
90
+ returnResponseField?: boolean;
91
+ /**
92
+ * When true, returns the full mutation response object
93
+ * instead of triggering alert/reload.
94
+ */
95
+ returnResponseObject?: boolean;
96
+ /** Reload the page after success? Default: true. */
97
+ reload?: boolean;
98
+ /**
99
+ * Map variables keys → File objects for multipart uploads.
100
+ * Called once per item in a batch.
101
+ */
102
+ getFileMap?: (item: any) => Record<string, File>;
103
+ };
104
+ export type UploadGraphQLArgs = {
105
+ query: string;
106
+ variables: Record<string, any>;
107
+ fileMap?: Record<string, File>;
108
+ token?: string;
109
+ params?: TenantParams;
110
+ config: ConfigType;
111
+ };
112
+ export type ServerQueryArgs<V = Record<string, any>> = {
113
+ query: any;
114
+ variables?: V;
115
+ domain?: string | null;
116
+ config: ConfigType;
117
+ };
118
+ export type ServerMutationArgs<V = Record<string, any>> = {
119
+ query: any;
120
+ variables?: V;
121
+ domain?: string | null;
122
+ config: ConfigType;
123
+ };
124
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
package/dist/types.js ADDED
@@ -0,0 +1,5 @@
1
+ // ============================================================
2
+ // @econneq/gql-auth — Shared Types
3
+ // ============================================================
4
+ export {};
5
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,+DAA+D;AAC/D,mCAAmC;AACnC,+DAA+D"}
@@ -1,21 +1,3 @@
1
- type UploadGraphQLArgs = {
2
- query: string;
3
- variables: Record<string, any>;
4
- fileMap: Record<string, File>;
5
- token?: string;
6
- params: any;
7
- config: {
8
- protocol: string;
9
- RootApi: string;
10
- Subdomains: {
11
- subdomain: string;
12
- id: string | number;
13
- processId: string;
14
- widgetID: string;
15
- }[];
16
- apiKey?: string;
17
- };
18
- };
19
- export declare function uploadGraphQLMutation({ query, variables, fileMap, token, params, config }: UploadGraphQLArgs): Promise<any>;
20
- export {};
1
+ import type { UploadGraphQLArgs } from "./types";
2
+ export declare function uploadGraphQLMutation({ query, variables, fileMap, token, params, config, }: UploadGraphQLArgs): Promise<any>;
21
3
  //# sourceMappingURL=upload-gql.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"upload-gql.d.ts","sourceRoot":"","sources":["../src/upload-gql.ts"],"names":[],"mappings":"AAAA,KAAK,iBAAiB,GAAG;IACvB,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAC/B,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;IAC9B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,GAAG,CAAC;IACZ,MAAM,EAAE;QACN,QAAQ,EAAE,MAAM,CAAC;QACjB,OAAO,EAAE,MAAM,CAAC;QAChB,UAAU,EAAE;YAAE,SAAS,EAAE,MAAM,CAAC;YAAC,EAAE,EAAE,MAAM,GAAG,MAAM,CAAC;YAAC,SAAS,EAAE,MAAM,CAAC;YAAC,QAAQ,EAAE,MAAM,CAAA;SAAE,EAAE,CAAC;QAC9F,MAAM,CAAC,EAAE,MAAM,CAAC;KACjB,CAAC;CACH,CAAC;AAEF,wBAAsB,qBAAqB,CAAC,EAC1C,KAAK,EACL,SAAS,EACT,OAAO,EACP,KAAK,EACL,MAAM,EACN,MAAM,EACP,EAAE,iBAAiB,gBA0DnB"}
1
+ {"version":3,"file":"upload-gql.d.ts","sourceRoot":"","sources":["../src/upload-gql.ts"],"names":[],"mappings":"AAYA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,SAAS,CAAC;AASjD,wBAAsB,qBAAqB,CAAC,EAC1C,KAAK,EACL,SAAS,EACT,OAAY,EACZ,KAAK,EACL,MAAM,EACN,MAAM,GACP,EAAE,iBAAiB,GAAG,OAAO,CAAC,GAAG,CAAC,CA0ElC"}
@@ -1,45 +1,75 @@
1
- export async function uploadGraphQLMutation({ query, variables, fileMap, token, params, config }) {
2
- const { protocol, RootApi, Subdomains, apiKey } = config;
3
- const formData = new FormData();
1
+ // ============================================================
2
+ // @econneq/gql-auth Multipart GraphQL upload mutation
3
+ // ============================================================
4
+ //
5
+ // Implements the GraphQL multipart request spec:
6
+ // https://github.com/jaydenseric/graphql-multipart-request-spec
7
+ //
8
+ // Works in both server (Docker-internal) and client (proxied)
9
+ // environments. Tenant resolution falls back to Subdomains[0]
10
+ // for single-tenant setups.
11
+ // ─────────────────────────────────────────────────────────────
12
+ import { Env, externalGraphQLUrl, internalGraphQLUrl, isServer, } from "./env";
13
+ import { assertTenant, buildTenantHeaders, resolveTenant } from "./tenant";
14
+ export async function uploadGraphQLMutation({ query, variables, fileMap = {}, token, params, config, }) {
15
+ const server = isServer();
16
+ // ── Tenant ─────────────────────────────────────────────
17
+ const tenant = resolveTenant(config, params);
18
+ assertTenant(tenant, params?.domain);
19
+ // ── Endpoint ───────────────────────────────────────────
20
+ const apiLink = server ? internalGraphQLUrl() : externalGraphQLUrl();
21
+ // ── Build multipart body ────────────────────────────────
4
22
  const updatedVariables = { ...variables };
5
- // 1. Prepare GraphQL Multipart Request (Spec compliant)
6
- Object.keys(fileMap).forEach((key) => {
7
- updatedVariables[key] = null;
8
- });
9
- const operations = { query, variables: updatedVariables };
10
- const map = {};
11
23
  const fileKeys = Object.keys(fileMap);
12
- fileKeys.forEach((key, index) => {
13
- map[`${index}`] = [`variables.${key}`];
14
- });
24
+ const hasFiles = fileKeys.length > 0;
25
+ if (hasFiles) {
26
+ for (const key of fileKeys) {
27
+ updatedVariables[key] = null;
28
+ }
29
+ }
30
+ const operations = {
31
+ query,
32
+ variables: updatedVariables,
33
+ };
34
+ const formData = new FormData();
15
35
  formData.append("operations", JSON.stringify(operations));
16
- formData.append("map", JSON.stringify(map));
17
- fileKeys.forEach((key, index) => {
18
- formData.append(`${index}`, fileMap[key]);
19
- });
20
- // 2. Multi-tenant URL and Data Logic
21
- const requestedDomain = params?.domain || "";
22
- const tenantData = Subdomains.find((d) => d.subdomain.toLowerCase() === requestedDomain.toLowerCase());
23
- // Determine URL: Use subdomain api if tenant exists, otherwise use root API
24
- const API_LINK = `${protocol + RootApi}/graphql/`;
25
- // 3. Construct Headers
36
+ if (hasFiles) {
37
+ const map = {};
38
+ fileKeys.forEach((key, index) => {
39
+ map[`${index}`] = [`variables.${key}`];
40
+ });
41
+ formData.append("map", JSON.stringify(map));
42
+ fileKeys.forEach((key, index) => {
43
+ formData.append(`${index}`, fileMap[key]);
44
+ });
45
+ }
46
+ else {
47
+ // No files → still needs a map entry per spec
48
+ formData.append("map", JSON.stringify({}));
49
+ }
50
+ // ── Headers ─────────────────────────────────────────────
51
+ const tenantHeaders = buildTenantHeaders(tenant, Env.apiKey);
26
52
  const headers = {
27
- ...(token ? { "Authorization": `Bearer ${token}` } : {}),
28
- ...(apiKey ? { "X-API-KEY": apiKey } : {}),
53
+ ...tenantHeaders,
54
+ ...(token ? { Authorization: `Bearer ${token}` } : {}),
55
+ // Note: do NOT set Content-Type here — browser/fetch sets it
56
+ // automatically with the correct multipart boundary.
29
57
  };
30
- // Inject specific tenant metadata into headers for Django to read
31
- if (tenantData) {
32
- headers["X-Tenant-ID"] = String(tenantData.subdomain);
33
- headers["X-Process-ID"] = tenantData.processId || "";
34
- headers["X-Widget-ID"] = tenantData.widgetID || "";
58
+ if (server) {
59
+ // Host header helps Django route to the right backend service
60
+ headers["Host"] = Env.backendInt;
35
61
  }
36
- // 4. Execute Fetch
37
- const res = await fetch(API_LINK, {
62
+ // ── Fetch ────────────────────────────────────────────────
63
+ const res = await fetch(apiLink, {
38
64
  method: "POST",
39
65
  headers,
40
66
  body: formData,
41
- // credentials: "include" is important if you use cookies alongside headers
42
67
  credentials: "include",
43
68
  });
44
- return await res.json();
69
+ if (!res.ok) {
70
+ const text = await res.text().catch(() => res.statusText);
71
+ throw new Error(`[@econneq/gql-auth] uploadGraphQLMutation HTTP ${res.status}: ${text}`);
72
+ }
73
+ return res.json();
45
74
  }
75
+ //# sourceMappingURL=upload-gql.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"upload-gql.js","sourceRoot":"","sources":["../src/upload-gql.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,24 @@
1
+ import { InterFieldList, JwtPayload } from ".";
2
+ export declare const capitalizeEachWord: (str: string) => string;
3
+ export declare const errorLog: (err: any, show?: boolean) => string;
4
+ export declare const getToken: () => string | null;
5
+ export declare const getUser: () => JwtPayload | null;
6
+ export declare const getStoredFont: (FONTS: string[]) => string;
7
+ export declare const getTimeAgo: (dateStr: string, type: "past" | "future") => string;
8
+ export declare const getLanguage: () => "en" | "fr";
9
+ export declare const getTemplate: () => number;
10
+ export declare const decodeUrlID: (urlID: string) => string;
11
+ export declare function getAcademicYear(): string;
12
+ export declare const removeEmptyFields: (obj: any) => any;
13
+ export declare const Alert: ({ title, duration, status }: {
14
+ title: string;
15
+ duration: 1000 | 1500 | 2000 | 3000 | 4000 | 5000;
16
+ status?: boolean;
17
+ }) => void;
18
+ export declare const validateFormFields: (formData: any, currentStepFields: InterFieldList[]) => Record<string, string>;
19
+ export declare const lastYears: (number: number) => {
20
+ value: string;
21
+ label: string;
22
+ }[];
23
+ export declare const formatText: (text: string) => string;
24
+ //# sourceMappingURL=utils.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,cAAc,EAAE,UAAU,EAAE,MAAM,GAAG,CAAC;AAI/C,eAAO,MAAM,kBAAkB,GAAI,KAAK,MAAM,WAM7C,CAAC;AAEF,eAAO,MAAM,QAAQ,GAAI,KAAK,GAAG,EAAE,OAAO,OAAO,WAyBhD,CAAC;AAKF,eAAO,MAAM,QAAQ,qBAKpB,CAAC;AAEF,eAAO,MAAM,OAAO,yBAKnB,CAAA;AAED,eAAO,MAAM,aAAa,GAAI,OAAO,MAAM,EAAE,WAO5C,CAAC;AAEF,eAAO,MAAM,UAAU,GACnB,SAAS,MAAM,EACf,MAAM,MAAM,GAAG,QAAQ,KACxB,MA0CF,CAAC;AAGF,eAAO,MAAM,WAAW,mBAOvB,CAAC;AAEF,eAAO,MAAM,WAAW,cAMvB,CAAC;AAEF,eAAO,MAAM,WAAW,GAAI,OAAO,MAAM,WAIxC,CAAA;AAED,wBAAgB,eAAe,IAAI,MAAM,CAUxC;AAED,eAAO,MAAM,iBAAiB,GAAI,KAAK,GAAG,QAUzC,CAAC;AAGF,eAAO,MAAM,KAAK,GACd,6BACI;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,IAAI,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,CAAC;IAAC,MAAM,CAAC,EAAE,OAAO,CAAA;CAAE,SAU7F,CAAC;AAIF,eAAO,MAAM,kBAAkB,GAAI,UAAU,GAAG,EAAE,mBAAmB,cAAc,EAAE,2BAkDpF,CAAC;AAEF,eAAO,MAAM,SAAS,GAAI,QAAQ,MAAM;;;GAKvC,CAAC;AAEF,eAAO,MAAM,UAAU,GAAI,MAAM,MAAM,WAiDtC,CAAC"}