@eintrek/erp-shell 0.1.60 → 0.1.61

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.
@@ -54,3 +54,25 @@ export interface UrlOrgGateInput {
54
54
  /** The organisation a `[code]` segment names, among the caller's. */
55
55
  export declare function findOrganizationForCode<T extends UrlOrgGateOrganization>(code: string | undefined, organizations: readonly T[]): T | null;
56
56
  export declare function resolveUrlOrgGate({ code, organizations, organizationsStatus, organizationId, }: UrlOrgGateInput): UrlOrgGate;
57
+ /**
58
+ * What to do when the active organisation is not one of the user's — a
59
+ * browser that remembers an organisation that was deleted, or that the user
60
+ * has left. Pure, tested in url-org-gate.test.ts.
61
+ *
62
+ * none nothing to recover: the list has not loaded, there is no active
63
+ * organisation, or the active one is the user's.
64
+ * use make `targetId` active: the URL's organisation when the user is
65
+ * a member of it, otherwise the user's only organisation.
66
+ * forget clear it; the user has several organisations and the URL names
67
+ * none of them, so they pick one.
68
+ */
69
+ export type StaleOrganizationRecovery = {
70
+ action: "none";
71
+ } | {
72
+ action: "use";
73
+ targetId: string;
74
+ fromUrl: boolean;
75
+ } | {
76
+ action: "forget";
77
+ };
78
+ export declare function resolveStaleOrganization({ code, organizations, organizationsStatus, organizationId, }: UrlOrgGateInput): StaleOrganizationRecovery;
@@ -20,14 +20,63 @@
20
20
  export declare function getTabOrganizationId(): string | null;
21
21
  /** Record the organisation this tab is working in (browser only). */
22
22
  export declare function setTabOrganizationId(id: string | number | null | undefined): void;
23
+ /**
24
+ * Record the user's organisations (browser only). From then on a stored or
25
+ * tab organisation that is not among them loses to one that is: a browser
26
+ * that still remembers a deleted organisation — or one the user has left —
27
+ * must not keep sending it while the cookie names a good one.
28
+ */
29
+ export declare function setKnownOrganizationIds(ids: Iterable<string | number> | null): void;
30
+ /** Whether the loaded list says the user is NOT a member of `id`. */
31
+ export declare function isKnownStaleOrganizationId(id: string | number | null | undefined): boolean;
32
+ /**
33
+ * Marks a request that must not carry X-Organization-ID: the user's own list
34
+ * of organisations is how a stale organisation id is found out, so it cannot
35
+ * depend on one. An app's interceptor honours it by passing the request's
36
+ * config to getRequestOrganizationId(config).
37
+ *
38
+ * axiosInstance.get("/organizations", withoutOrganization({ params }))
39
+ */
40
+ export declare const WITHOUT_ORGANIZATION_FLAG = "erpWithoutOrganization";
41
+ export declare function withoutOrganization<T extends object = Record<never, never>>(config?: T): T & {
42
+ erpWithoutOrganization: true;
43
+ };
44
+ /**
45
+ * Marks a request for one particular organisation, whatever this tab has
46
+ * active. Used to retry the organisation list under each stored id when an
47
+ * API refuses it without one (see http/organization-fallback.ts).
48
+ */
49
+ export declare const FOR_ORGANIZATION_FIELD = "erpOrganizationId";
50
+ /**
51
+ * Every organisation id this browser has stored for the tab — the tab's
52
+ * own, localStorage, the cookie — distinct, in that order.
53
+ */
54
+ export declare function getStoredOrganizationIds(): string[];
23
55
  /**
24
56
  * The organisation a request from this tab belongs to: the tab's own, then
25
57
  * localStorage, then the cookie. Use it for the X-Organization-ID header —
26
58
  * and read it before any `await` in the interceptor, so the header names the
27
59
  * organisation that was active when the request was made.
28
60
  *
61
+ * Pass the request's config: a request marked withoutOrganization() gets
62
+ * null, so no header.
63
+ *
29
64
  * localStorage before the cookie: setOrganizationId writes localStorage
30
65
  * synchronously and then awaits a server action for the cookie, so during
31
66
  * that round trip the cookie still names the previous organisation.
67
+ *
68
+ * Once the user's organisations are known (setKnownOrganizationIds), the
69
+ * first of those that is one of them wins: 0.1.60 let a deleted
70
+ * organisation's id left in localStorage beat a valid cookie, and every
71
+ * request — the organisation list included — was refused. If none is a
72
+ * member the first is still sent, as before: the list may simply be behind
73
+ * (an organisation created a moment ago).
74
+ */
75
+ export declare function getRequestOrganizationId(config?: unknown): string | null;
76
+ /**
77
+ * Forget the active organisation everywhere this browser keeps it: the tab,
78
+ * localStorage and the `erp.organizationId` cookie. Call on sign-out, so the
79
+ * next person to sign in on this browser does not start in the previous
80
+ * person's organisation.
32
81
  */
33
- export declare function getRequestOrganizationId(): string | null;
82
+ export declare function clearStoredOrganization(): void;
package/dist/version.d.ts CHANGED
@@ -2,4 +2,4 @@
2
2
  * This package's version, attached to help messages so the back office can
3
3
  * tell which shell a report came from. Keep in step with package.json.
4
4
  */
5
- export declare const SHELL_VERSION = "0.1.60";
5
+ export declare const SHELL_VERSION = "0.1.61";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@eintrek/erp-shell",
3
- "version": "0.1.60",
3
+ "version": "0.1.61",
4
4
  "private": false,
5
5
  "type": "module",
6
6
  "description": "Shared frontend platform for ERP apps — HTTP client, providers, navigation, hooks.",