emilsoftware-utilities 2.0.0-dev.70 → 2.0.0-dev.72

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 (39) hide show
  1. package/README.MD +30 -0
  2. package/dist/accessi/client/admin/index.d.ts +18 -0
  3. package/dist/accessi/client/admin/index.js +58 -0
  4. package/dist/accessi/client/admin/index.js.map +1 -0
  5. package/dist/accessi/client/createAccessiClient.d.ts +21 -0
  6. package/dist/accessi/client/createAccessiClient.js +31 -0
  7. package/dist/accessi/client/createAccessiClient.js.map +1 -0
  8. package/dist/accessi/client/generated/admin.d.ts +601 -0
  9. package/dist/accessi/client/generated/admin.js +557 -0
  10. package/dist/accessi/client/generated/admin.js.map +1 -0
  11. package/dist/accessi/client/generated/public.d.ts +121 -0
  12. package/dist/accessi/client/generated/public.js +119 -0
  13. package/dist/accessi/client/generated/public.js.map +1 -0
  14. package/dist/accessi/client/generated/service.d.ts +53 -0
  15. package/dist/accessi/client/generated/service.js +63 -0
  16. package/dist/accessi/client/generated/service.js.map +1 -0
  17. package/dist/accessi/client/index.d.ts +29 -11
  18. package/dist/accessi/client/index.js +52 -2
  19. package/dist/accessi/client/index.js.map +1 -1
  20. package/dist/accessi/client/public/index.d.ts +18 -0
  21. package/dist/accessi/client/public/index.js +58 -0
  22. package/dist/accessi/client/public/index.js.map +1 -0
  23. package/dist/accessi/client/service/index.d.ts +17 -0
  24. package/dist/accessi/client/service/index.js +57 -0
  25. package/dist/accessi/client/service/index.js.map +1 -0
  26. package/dist/accessi-module/Console/accessiFetch.d.ts +27 -0
  27. package/dist/accessi-module/Console/accessiFetch.js +41 -5
  28. package/dist/accessi-module/Console/accessiFetch.js.map +1 -1
  29. package/dist/accessi-module/Console/console.js +14 -3
  30. package/dist/accessi-module/Console/wiki.js +10 -1
  31. package/dist/accessi-module/Console/wiki.js.map +1 -1
  32. package/dist/accessi-module/Controllers/AccessiIntrospectionController.js +1 -1
  33. package/dist/accessi-module/Controllers/AccessiIntrospectionController.js.map +1 -1
  34. package/dist/accessi-module/security/accessTokenRevocation.js +5 -2
  35. package/dist/accessi-module/security/accessTokenRevocation.js.map +1 -1
  36. package/dist/emilsoftware-utilities-2.0.0-dev.72.tgz +0 -0
  37. package/integration-prompt.md +6 -2
  38. package/package.json +23 -4
  39. package/dist/emilsoftware-utilities-2.0.0-dev.70.tgz +0 -0
@@ -3,24 +3,42 @@
3
3
  *
4
4
  * Il client e pensato per essere usato da backend fratelli, frontend e tool
5
5
  * amministrativi. Configurare base URL e token provider prima della prima call.
6
+ *
7
+ * Per limitare le operazioni disponibili usare gli entry point per scope:
8
+ * `accessi/client/public`, `accessi/client/admin` e `accessi/client/service`.
6
9
  */
10
+ import * as generated from "../../accessi-module/Console/generated/emilsoftware-utilities";
11
+ import type { AccessiClientConfig } from "../../accessi-module/Console/accessiFetch";
12
+ import { type AccessiScopedClient } from "./createAccessiClient";
7
13
  export * from "../../accessi-module/Console/generated/emilsoftware-utilities";
8
14
  export * from "../../accessi-module/Console/generated/model";
9
15
  export { AccessiRequestError } from "../../accessi-module/Console/accessiFetch";
10
- export { ACCESSI_UNAUTHORIZED_EVENT, setAccessiFetchBaseUrl, setAccessiFetchTokenProvider, } from "../../accessi-module/Console/accessiFetch";
11
- /** Configurazione globale del client. */
12
- export interface AccessiClientConfig {
13
- /** Base URL di Accessi Service, es. `https://accessi.example.com`. */
14
- baseUrl?: string | null;
15
- /** Token statico. Preferire `getToken` per token che cambiano nel tempo. */
16
- token?: string | null;
17
- /** Provider asincrono/sincrono del token corrente. */
18
- getToken?: () => string | null | Promise<string | null>;
19
- }
16
+ export { ACCESSI_UNAUTHORIZED_EVENT, getAccessiClientConfig, runWithAccessiClient, setAccessiFetchBaseUrl, setAccessiFetchTokenProvider, } from "../../accessi-module/Console/accessiFetch";
17
+ export type { AccessiClientConfig } from "../../accessi-module/Console/accessiFetch";
18
+ /** Client completo: tutte le operazioni, con configurazione isolata per istanza. */
19
+ export type AccessiClient = AccessiScopedClient<typeof generated>;
20
20
  /**
21
- * Configura il trasporto del client generato.
21
+ * Configura il trasporto del client generato globale.
22
22
  *
23
23
  * Uso tipico backend: `configureAccessiClient({ baseUrl, getToken })`.
24
24
  * Uso tipico frontend: `configureAccessiClient({ baseUrl, token })` dopo il login.
25
+ *
26
+ * Per usare piu Accessi Service (o tenant) nello stesso processo preferire
27
+ * `createAccessiClient`: la configurazione globale resta il default per le
28
+ * chiamate agli export del package.
25
29
  */
26
30
  export declare function configureAccessiClient(config?: AccessiClientConfig): void;
31
+ /**
32
+ * Crea un client isolato con la propria base URL e il proprio token.
33
+ *
34
+ * Le istanze possono essere usate in concorrenza: la configurazione viene
35
+ * applicata alla singola chiamata, quindi due client con base URL o token
36
+ * diversi non si sovrascrivono.
37
+ *
38
+ * ```ts
39
+ * const milano = createAccessiClient({ baseUrl: 'https://accessi-milano.example.com', getToken });
40
+ * const roma = createAccessiClient({ baseUrl: 'https://accessi-roma.example.com', token });
41
+ * const [utentiMilano, utentiRoma] = await Promise.all([milano.getUsers(), roma.getUsers()]);
42
+ * ```
43
+ */
44
+ export declare function createAccessiClient(config?: AccessiClientConfig): AccessiClient;
@@ -10,32 +10,66 @@ var __createBinding = (this && this.__createBinding) || (Object.create ? (functi
10
10
  if (k2 === undefined) k2 = k;
11
11
  o[k2] = m[k];
12
12
  }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
13
35
  var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
36
  for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
37
  };
16
38
  Object.defineProperty(exports, "__esModule", { value: true });
17
- exports.setAccessiFetchTokenProvider = exports.setAccessiFetchBaseUrl = exports.ACCESSI_UNAUTHORIZED_EVENT = exports.AccessiRequestError = void 0;
39
+ exports.setAccessiFetchTokenProvider = exports.setAccessiFetchBaseUrl = exports.runWithAccessiClient = exports.getAccessiClientConfig = exports.ACCESSI_UNAUTHORIZED_EVENT = exports.AccessiRequestError = void 0;
18
40
  exports.configureAccessiClient = configureAccessiClient;
41
+ exports.createAccessiClient = createAccessiClient;
19
42
  /**
20
43
  * Client HTTP generato dal contratto OpenAPI di Accessi.
21
44
  *
22
45
  * Il client e pensato per essere usato da backend fratelli, frontend e tool
23
46
  * amministrativi. Configurare base URL e token provider prima della prima call.
47
+ *
48
+ * Per limitare le operazioni disponibili usare gli entry point per scope:
49
+ * `accessi/client/public`, `accessi/client/admin` e `accessi/client/service`.
24
50
  */
51
+ const generated = __importStar(require("../../accessi-module/Console/generated/emilsoftware-utilities"));
52
+ const createAccessiClient_1 = require("./createAccessiClient");
25
53
  __exportStar(require("../../accessi-module/Console/generated/emilsoftware-utilities"), exports);
26
54
  __exportStar(require("../../accessi-module/Console/generated/model"), exports);
27
55
  var accessiFetch_1 = require("../../accessi-module/Console/accessiFetch");
28
56
  Object.defineProperty(exports, "AccessiRequestError", { enumerable: true, get: function () { return accessiFetch_1.AccessiRequestError; } });
29
57
  var accessiFetch_2 = require("../../accessi-module/Console/accessiFetch");
30
58
  Object.defineProperty(exports, "ACCESSI_UNAUTHORIZED_EVENT", { enumerable: true, get: function () { return accessiFetch_2.ACCESSI_UNAUTHORIZED_EVENT; } });
59
+ Object.defineProperty(exports, "getAccessiClientConfig", { enumerable: true, get: function () { return accessiFetch_2.getAccessiClientConfig; } });
60
+ Object.defineProperty(exports, "runWithAccessiClient", { enumerable: true, get: function () { return accessiFetch_2.runWithAccessiClient; } });
31
61
  Object.defineProperty(exports, "setAccessiFetchBaseUrl", { enumerable: true, get: function () { return accessiFetch_2.setAccessiFetchBaseUrl; } });
32
62
  Object.defineProperty(exports, "setAccessiFetchTokenProvider", { enumerable: true, get: function () { return accessiFetch_2.setAccessiFetchTokenProvider; } });
33
63
  const accessiFetch_3 = require("../../accessi-module/Console/accessiFetch");
34
64
  /**
35
- * Configura il trasporto del client generato.
65
+ * Configura il trasporto del client generato globale.
36
66
  *
37
67
  * Uso tipico backend: `configureAccessiClient({ baseUrl, getToken })`.
38
68
  * Uso tipico frontend: `configureAccessiClient({ baseUrl, token })` dopo il login.
69
+ *
70
+ * Per usare piu Accessi Service (o tenant) nello stesso processo preferire
71
+ * `createAccessiClient`: la configurazione globale resta il default per le
72
+ * chiamate agli export del package.
39
73
  */
40
74
  function configureAccessiClient(config = {}) {
41
75
  var _a;
@@ -46,4 +80,20 @@ function configureAccessiClient(config = {}) {
46
80
  }
47
81
  (0, accessiFetch_3.setAccessiFetchTokenProvider)(() => { var _a; return (_a = config.token) !== null && _a !== void 0 ? _a : null; });
48
82
  }
83
+ /**
84
+ * Crea un client isolato con la propria base URL e il proprio token.
85
+ *
86
+ * Le istanze possono essere usate in concorrenza: la configurazione viene
87
+ * applicata alla singola chiamata, quindi due client con base URL o token
88
+ * diversi non si sovrascrivono.
89
+ *
90
+ * ```ts
91
+ * const milano = createAccessiClient({ baseUrl: 'https://accessi-milano.example.com', getToken });
92
+ * const roma = createAccessiClient({ baseUrl: 'https://accessi-roma.example.com', token });
93
+ * const [utentiMilano, utentiRoma] = await Promise.all([milano.getUsers(), roma.getUsers()]);
94
+ * ```
95
+ */
96
+ function createAccessiClient(config = {}) {
97
+ return (0, createAccessiClient_1.createAccessiClientFromModule)(generated, config);
98
+ }
49
99
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/accessi/client/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;AAoCA,wDAOC;AA3CD;;;;;GAKG;AACH,gGAA8E;AAC9E,+EAA6D;AAC7D,0EAAgF;AAAvE,mHAAA,mBAAmB,OAAA;AAC5B,0EAImD;AAHjD,0HAAA,0BAA0B,OAAA;AAC1B,sHAAA,sBAAsB,OAAA;AACtB,4HAAA,4BAA4B,OAAA;AAG9B,4EAGmD;AAYnD;;;;;GAKG;AACH,SAAgB,sBAAsB,CAAC,SAA8B,EAAE;;IACrE,IAAA,qCAAsB,EAAC,MAAA,MAAM,CAAC,OAAO,mCAAI,IAAI,CAAC,CAAC;IAC/C,IAAI,MAAM,CAAC,QAAQ,EAAE,CAAC;QACpB,IAAA,2CAA4B,EAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;QAC9C,OAAO;IACT,CAAC;IACD,IAAA,2CAA4B,EAAC,GAAG,EAAE,WAAC,OAAA,MAAA,MAAM,CAAC,KAAK,mCAAI,IAAI,CAAA,EAAA,CAAC,CAAC;AAC3D,CAAC","sourcesContent":["/**\n * Client HTTP generato dal contratto OpenAPI di Accessi.\n *\n * Il client e pensato per essere usato da backend fratelli, frontend e tool\n * amministrativi. Configurare base URL e token provider prima della prima call.\n */\nexport * from \"../../accessi-module/Console/generated/emilsoftware-utilities\";\nexport * from \"../../accessi-module/Console/generated/model\";\nexport { AccessiRequestError } from \"../../accessi-module/Console/accessiFetch\";\nexport {\n ACCESSI_UNAUTHORIZED_EVENT,\n setAccessiFetchBaseUrl,\n setAccessiFetchTokenProvider,\n} from \"../../accessi-module/Console/accessiFetch\";\n\nimport {\n setAccessiFetchBaseUrl,\n setAccessiFetchTokenProvider,\n} from \"../../accessi-module/Console/accessiFetch\";\n\n/** Configurazione globale del client. */\nexport interface AccessiClientConfig {\n /** Base URL di Accessi Service, es. `https://accessi.example.com`. */\n baseUrl?: string | null;\n /** Token statico. Preferire `getToken` per token che cambiano nel tempo. */\n token?: string | null;\n /** Provider asincrono/sincrono del token corrente. */\n getToken?: () => string | null | Promise<string | null>;\n}\n\n/**\n * Configura il trasporto del client generato.\n *\n * Uso tipico backend: `configureAccessiClient({ baseUrl, getToken })`.\n * Uso tipico frontend: `configureAccessiClient({ baseUrl, token })` dopo il login.\n */\nexport function configureAccessiClient(config: AccessiClientConfig = {}): void {\n setAccessiFetchBaseUrl(config.baseUrl ?? null);\n if (config.getToken) {\n setAccessiFetchTokenProvider(config.getToken);\n return;\n }\n setAccessiFetchTokenProvider(() => config.token ?? null);\n}\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/accessi/client/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA8CA,wDAOC;AAeD,kDAEC;AAtED;;;;;;;;GAQG;AACH,yGAA2F;AAE3F,+DAG+B;AAE/B,gGAA8E;AAC9E,+EAA6D;AAC7D,0EAAgF;AAAvE,mHAAA,mBAAmB,OAAA;AAC5B,0EAMmD;AALjD,0HAAA,0BAA0B,OAAA;AAC1B,sHAAA,sBAAsB,OAAA;AACtB,oHAAA,oBAAoB,OAAA;AACpB,sHAAA,sBAAsB,OAAA;AACtB,4HAAA,4BAA4B,OAAA;AAI9B,4EAGmD;AAKnD;;;;;;;;;GASG;AACH,SAAgB,sBAAsB,CAAC,SAA8B,EAAE;;IACrE,IAAA,qCAAsB,EAAC,MAAA,MAAM,CAAC,OAAO,mCAAI,IAAI,CAAC,CAAC;IAC/C,IAAI,MAAM,CAAC,QAAQ,EAAE,CAAC;QACpB,IAAA,2CAA4B,EAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;QAC9C,OAAO;IACT,CAAC;IACD,IAAA,2CAA4B,EAAC,GAAG,EAAE,WAAC,OAAA,MAAA,MAAM,CAAC,KAAK,mCAAI,IAAI,CAAA,EAAA,CAAC,CAAC;AAC3D,CAAC;AAED;;;;;;;;;;;;GAYG;AACH,SAAgB,mBAAmB,CAAC,SAA8B,EAAE;IAClE,OAAO,IAAA,mDAA6B,EAAC,SAAS,EAAE,MAAM,CAAC,CAAC;AAC1D,CAAC","sourcesContent":["/**\n * Client HTTP generato dal contratto OpenAPI di Accessi.\n *\n * Il client e pensato per essere usato da backend fratelli, frontend e tool\n * amministrativi. Configurare base URL e token provider prima della prima call.\n *\n * Per limitare le operazioni disponibili usare gli entry point per scope:\n * `accessi/client/public`, `accessi/client/admin` e `accessi/client/service`.\n */\nimport * as generated from \"../../accessi-module/Console/generated/emilsoftware-utilities\";\nimport type { AccessiClientConfig } from \"../../accessi-module/Console/accessiFetch\";\nimport {\n createAccessiClientFromModule,\n type AccessiScopedClient,\n} from \"./createAccessiClient\";\n\nexport * from \"../../accessi-module/Console/generated/emilsoftware-utilities\";\nexport * from \"../../accessi-module/Console/generated/model\";\nexport { AccessiRequestError } from \"../../accessi-module/Console/accessiFetch\";\nexport {\n ACCESSI_UNAUTHORIZED_EVENT,\n getAccessiClientConfig,\n runWithAccessiClient,\n setAccessiFetchBaseUrl,\n setAccessiFetchTokenProvider,\n} from \"../../accessi-module/Console/accessiFetch\";\nexport type { AccessiClientConfig } from \"../../accessi-module/Console/accessiFetch\";\n\nimport {\n setAccessiFetchBaseUrl,\n setAccessiFetchTokenProvider,\n} from \"../../accessi-module/Console/accessiFetch\";\n\n/** Client completo: tutte le operazioni, con configurazione isolata per istanza. */\nexport type AccessiClient = AccessiScopedClient<typeof generated>;\n\n/**\n * Configura il trasporto del client generato globale.\n *\n * Uso tipico backend: `configureAccessiClient({ baseUrl, getToken })`.\n * Uso tipico frontend: `configureAccessiClient({ baseUrl, token })` dopo il login.\n *\n * Per usare piu Accessi Service (o tenant) nello stesso processo preferire\n * `createAccessiClient`: la configurazione globale resta il default per le\n * chiamate agli export del package.\n */\nexport function configureAccessiClient(config: AccessiClientConfig = {}): void {\n setAccessiFetchBaseUrl(config.baseUrl ?? null);\n if (config.getToken) {\n setAccessiFetchTokenProvider(config.getToken);\n return;\n }\n setAccessiFetchTokenProvider(() => config.token ?? null);\n}\n\n/**\n * Crea un client isolato con la propria base URL e il proprio token.\n *\n * Le istanze possono essere usate in concorrenza: la configurazione viene\n * applicata alla singola chiamata, quindi due client con base URL o token\n * diversi non si sovrascrivono.\n *\n * ```ts\n * const milano = createAccessiClient({ baseUrl: 'https://accessi-milano.example.com', getToken });\n * const roma = createAccessiClient({ baseUrl: 'https://accessi-roma.example.com', token });\n * const [utentiMilano, utentiRoma] = await Promise.all([milano.getUsers(), roma.getUsers()]);\n * ```\n */\nexport function createAccessiClient(config: AccessiClientConfig = {}): AccessiClient {\n return createAccessiClientFromModule(generated, config);\n}\n"]}
@@ -0,0 +1,18 @@
1
+ /**
2
+ * Client per le API pubbliche di Accessi: login, refresh, 2FA, reset password,
3
+ * registrazione pubblica e scambio ticket console.
4
+ *
5
+ * Non include le operazioni amministrative (utenti, ruoli, menu, schema, filtri,
6
+ * service token). Per quelle usare `accessi/client/admin`.
7
+ */
8
+ import * as generated from '../generated/public';
9
+ import type { AccessiClientConfig } from '../../../accessi-module/Console/accessiFetch';
10
+ import { type AccessiScopedClient } from '../createAccessiClient';
11
+ export * from '../generated/public';
12
+ export * from '../../../accessi-module/Console/generated/model';
13
+ export { AccessiRequestError } from '../../../accessi-module/Console/accessiFetch';
14
+ export type { AccessiClientConfig } from '../../../accessi-module/Console/accessiFetch';
15
+ /** Client pubblico con configurazione isolata per istanza. */
16
+ export type AccessiPublicClient = AccessiScopedClient<typeof generated>;
17
+ /** Crea un client delle sole API pubbliche, con base URL e token propri. */
18
+ export declare function createAccessiPublicClient(config?: AccessiClientConfig): AccessiPublicClient;
@@ -0,0 +1,58 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
36
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
37
+ };
38
+ Object.defineProperty(exports, "__esModule", { value: true });
39
+ exports.AccessiRequestError = void 0;
40
+ exports.createAccessiPublicClient = createAccessiPublicClient;
41
+ /**
42
+ * Client per le API pubbliche di Accessi: login, refresh, 2FA, reset password,
43
+ * registrazione pubblica e scambio ticket console.
44
+ *
45
+ * Non include le operazioni amministrative (utenti, ruoli, menu, schema, filtri,
46
+ * service token). Per quelle usare `accessi/client/admin`.
47
+ */
48
+ const generated = __importStar(require("../generated/public"));
49
+ const createAccessiClient_1 = require("../createAccessiClient");
50
+ __exportStar(require("../generated/public"), exports);
51
+ __exportStar(require("../../../accessi-module/Console/generated/model"), exports);
52
+ var accessiFetch_1 = require("../../../accessi-module/Console/accessiFetch");
53
+ Object.defineProperty(exports, "AccessiRequestError", { enumerable: true, get: function () { return accessiFetch_1.AccessiRequestError; } });
54
+ /** Crea un client delle sole API pubbliche, con base URL e token propri. */
55
+ function createAccessiPublicClient(config = {}) {
56
+ return (0, createAccessiClient_1.createAccessiClientFromModule)(generated, config);
57
+ }
58
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/accessi/client/public/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAuBA,8DAIC;AA3BD;;;;;;GAMG;AACH,+DAAiD;AAEjD,gEAGgC;AAEhC,sDAAoC;AACpC,kFAAgE;AAChE,6EAAmF;AAA1E,mHAAA,mBAAmB,OAAA;AAM5B,4EAA4E;AAC5E,SAAgB,yBAAyB,CACvC,SAA8B,EAAE;IAEhC,OAAO,IAAA,mDAA6B,EAAC,SAAS,EAAE,MAAM,CAAC,CAAC;AAC1D,CAAC","sourcesContent":["/**\n * Client per le API pubbliche di Accessi: login, refresh, 2FA, reset password,\n * registrazione pubblica e scambio ticket console.\n *\n * Non include le operazioni amministrative (utenti, ruoli, menu, schema, filtri,\n * service token). Per quelle usare `accessi/client/admin`.\n */\nimport * as generated from '../generated/public';\nimport type { AccessiClientConfig } from '../../../accessi-module/Console/accessiFetch';\nimport {\n createAccessiClientFromModule,\n type AccessiScopedClient,\n} from '../createAccessiClient';\n\nexport * from '../generated/public';\nexport * from '../../../accessi-module/Console/generated/model';\nexport { AccessiRequestError } from '../../../accessi-module/Console/accessiFetch';\nexport type { AccessiClientConfig } from '../../../accessi-module/Console/accessiFetch';\n\n/** Client pubblico con configurazione isolata per istanza. */\nexport type AccessiPublicClient = AccessiScopedClient<typeof generated>;\n\n/** Crea un client delle sole API pubbliche, con base URL e token propri. */\nexport function createAccessiPublicClient(\n config: AccessiClientConfig = {},\n): AccessiPublicClient {\n return createAccessiClientFromModule(generated, config);\n}\n"]}
@@ -0,0 +1,17 @@
1
+ /**
2
+ * Client per le API service-to-service di Accessi: gestione dei service token
3
+ * (creazione, rotazione, revoca, elenco) e introspezione degli access token.
4
+ *
5
+ * Pensato per backend fratelli e job: non va distribuito a frontend pubblici.
6
+ */
7
+ import * as generated from '../generated/service';
8
+ import type { AccessiClientConfig } from '../../../accessi-module/Console/accessiFetch';
9
+ import { type AccessiScopedClient } from '../createAccessiClient';
10
+ export * from '../generated/service';
11
+ export * from '../../../accessi-module/Console/generated/model';
12
+ export { AccessiRequestError } from '../../../accessi-module/Console/accessiFetch';
13
+ export type { AccessiClientConfig } from '../../../accessi-module/Console/accessiFetch';
14
+ /** Client service-to-service con configurazione isolata per istanza. */
15
+ export type AccessiServiceClient = AccessiScopedClient<typeof generated>;
16
+ /** Crea un client delle API service-to-service, con base URL e token propri. */
17
+ export declare function createAccessiServiceClient(config?: AccessiClientConfig): AccessiServiceClient;
@@ -0,0 +1,57 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
36
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
37
+ };
38
+ Object.defineProperty(exports, "__esModule", { value: true });
39
+ exports.AccessiRequestError = void 0;
40
+ exports.createAccessiServiceClient = createAccessiServiceClient;
41
+ /**
42
+ * Client per le API service-to-service di Accessi: gestione dei service token
43
+ * (creazione, rotazione, revoca, elenco) e introspezione degli access token.
44
+ *
45
+ * Pensato per backend fratelli e job: non va distribuito a frontend pubblici.
46
+ */
47
+ const generated = __importStar(require("../generated/service"));
48
+ const createAccessiClient_1 = require("../createAccessiClient");
49
+ __exportStar(require("../generated/service"), exports);
50
+ __exportStar(require("../../../accessi-module/Console/generated/model"), exports);
51
+ var accessiFetch_1 = require("../../../accessi-module/Console/accessiFetch");
52
+ Object.defineProperty(exports, "AccessiRequestError", { enumerable: true, get: function () { return accessiFetch_1.AccessiRequestError; } });
53
+ /** Crea un client delle API service-to-service, con base URL e token propri. */
54
+ function createAccessiServiceClient(config = {}) {
55
+ return (0, createAccessiClient_1.createAccessiClientFromModule)(generated, config);
56
+ }
57
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/accessi/client/service/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAsBA,gEAIC;AA1BD;;;;;GAKG;AACH,gEAAkD;AAElD,gEAGgC;AAEhC,uDAAqC;AACrC,kFAAgE;AAChE,6EAAmF;AAA1E,mHAAA,mBAAmB,OAAA;AAM5B,gFAAgF;AAChF,SAAgB,0BAA0B,CACxC,SAA8B,EAAE;IAEhC,OAAO,IAAA,mDAA6B,EAAC,SAAS,EAAE,MAAM,CAAC,CAAC;AAC1D,CAAC","sourcesContent":["/**\n * Client per le API service-to-service di Accessi: gestione dei service token\n * (creazione, rotazione, revoca, elenco) e introspezione degli access token.\n *\n * Pensato per backend fratelli e job: non va distribuito a frontend pubblici.\n */\nimport * as generated from '../generated/service';\nimport type { AccessiClientConfig } from '../../../accessi-module/Console/accessiFetch';\nimport {\n createAccessiClientFromModule,\n type AccessiScopedClient,\n} from '../createAccessiClient';\n\nexport * from '../generated/service';\nexport * from '../../../accessi-module/Console/generated/model';\nexport { AccessiRequestError } from '../../../accessi-module/Console/accessiFetch';\nexport type { AccessiClientConfig } from '../../../accessi-module/Console/accessiFetch';\n\n/** Client service-to-service con configurazione isolata per istanza. */\nexport type AccessiServiceClient = AccessiScopedClient<typeof generated>;\n\n/** Crea un client delle API service-to-service, con base URL e token propri. */\nexport function createAccessiServiceClient(\n config: AccessiClientConfig = {},\n): AccessiServiceClient {\n return createAccessiClientFromModule(generated, config);\n}\n"]}
@@ -1,3 +1,17 @@
1
+ /**
2
+ * Configurazione di un client Accessi.
3
+ *
4
+ * Usata sia dalla configurazione globale (`configureAccessiClient`) sia dalle
5
+ * istanze isolate create con `createAccessiClient`.
6
+ */
7
+ export interface AccessiClientConfig {
8
+ /** Base URL di Accessi Service, es. `https://accessi.example.com`. */
9
+ baseUrl?: string | null;
10
+ /** Token statico. Preferire `getToken` per token che cambiano nel tempo. */
11
+ token?: string | null;
12
+ /** Provider asincrono/sincrono del token corrente. */
13
+ getToken?: () => string | null | Promise<string | null>;
14
+ }
1
15
  declare global {
2
16
  interface Window {
3
17
  __ACCESSI_API_BASE_URL__?: string;
@@ -18,6 +32,19 @@ export declare function setAccessiConsoleToken(token: string | null): void;
18
32
  export declare function setAccessiFetchBaseUrl(url: string | null): void;
19
33
  /** Token provider per client esterni alla console (server-to-server o frontend). */
20
34
  export declare function setAccessiFetchTokenProvider(provider: (() => string | null | Promise<string | null>) | null): void;
35
+ /** Configurazione isolata attiva in questo momento, se una chiamata e in corso. */
36
+ export declare function getAccessiClientConfig(): AccessiClientConfig | null;
37
+ /**
38
+ * Esegue `callback` con una configurazione del client isolata.
39
+ *
40
+ * Le funzioni generate da Orval invocano il trasporto in modo sincrono, quindi
41
+ * la configurazione viene letta all'inizio della richiesta: due client diversi
42
+ * possono chiamare in concorrenza senza sovrascriversi a vicenda.
43
+ *
44
+ * Per un uso continuativo preferire `createAccessiClient`, che applica il
45
+ * contesto a ogni metodo.
46
+ */
47
+ export declare function runWithAccessiClient<T>(config: AccessiClientConfig, callback: () => T): T;
21
48
  /**
22
49
  * Trasporto comune del client Orval: aggiunge il Bearer token e converte le
23
50
  * risposte di errore Accessi in Error JavaScript leggibili dalla console.
@@ -13,10 +13,13 @@ exports.AccessiRequestError = exports.ACCESSI_UNAUTHORIZED_EVENT = void 0;
13
13
  exports.setAccessiConsoleToken = setAccessiConsoleToken;
14
14
  exports.setAccessiFetchBaseUrl = setAccessiFetchBaseUrl;
15
15
  exports.setAccessiFetchTokenProvider = setAccessiFetchTokenProvider;
16
+ exports.getAccessiClientConfig = getAccessiClientConfig;
17
+ exports.runWithAccessiClient = runWithAccessiClient;
16
18
  exports.accessiFetch = accessiFetch;
17
19
  let accessToken = null;
18
20
  let baseUrl = null;
19
21
  let tokenProvider = null;
22
+ let scopedConfig = null;
20
23
  const loadingEventName = 'accessi-console-network';
21
24
  /** Emesso quando una richiesta autenticata riceve 401: la console deve riportare al login. */
22
25
  exports.ACCESSI_UNAUTHORIZED_EVENT = 'accessi-console-unauthorized';
@@ -49,6 +52,30 @@ function setAccessiFetchBaseUrl(url) {
49
52
  function setAccessiFetchTokenProvider(provider) {
50
53
  tokenProvider = provider;
51
54
  }
55
+ /** Configurazione isolata attiva in questo momento, se una chiamata e in corso. */
56
+ function getAccessiClientConfig() {
57
+ return scopedConfig;
58
+ }
59
+ /**
60
+ * Esegue `callback` con una configurazione del client isolata.
61
+ *
62
+ * Le funzioni generate da Orval invocano il trasporto in modo sincrono, quindi
63
+ * la configurazione viene letta all'inizio della richiesta: due client diversi
64
+ * possono chiamare in concorrenza senza sovrascriversi a vicenda.
65
+ *
66
+ * Per un uso continuativo preferire `createAccessiClient`, che applica il
67
+ * contesto a ogni metodo.
68
+ */
69
+ function runWithAccessiClient(config, callback) {
70
+ const previous = scopedConfig;
71
+ scopedConfig = config;
72
+ try {
73
+ return callback();
74
+ }
75
+ finally {
76
+ scopedConfig = previous;
77
+ }
78
+ }
52
79
  /** Legge una stringa non vuota dal payload di errore Accessi, ignorando tipi inattesi. */
53
80
  function payloadString(payload, key) {
54
81
  if (!payload || typeof payload !== 'object')
@@ -62,17 +89,26 @@ function payloadString(payload, key) {
62
89
  */
63
90
  function accessiFetch(url, options) {
64
91
  return __awaiter(this, void 0, void 0, function* () {
65
- var _a, _b, _c, _d;
92
+ var _a, _b, _c, _d, _e;
93
+ // Il contesto va letto prima di ogni await: la funzione generata invoca il
94
+ // trasporto in modo sincrono, quindi la configurazione appartiene a questa call.
95
+ const config = scopedConfig;
66
96
  const headers = new Headers(options.headers);
67
97
  headers.set('Accept', 'application/json');
68
98
  if (options.body !== undefined && !headers.has('Content-Type')) {
69
99
  headers.set('Content-Type', 'application/json');
70
100
  }
71
- const resolvedToken = tokenProvider ? yield tokenProvider() : accessToken;
101
+ const resolvedToken = config
102
+ ? (config.getToken ? yield config.getToken() : (_a = config.token) !== null && _a !== void 0 ? _a : null)
103
+ : tokenProvider
104
+ ? yield tokenProvider()
105
+ : accessToken;
72
106
  const authenticatedRequest = resolvedToken !== null && resolvedToken !== undefined;
73
107
  if (resolvedToken)
74
108
  headers.set('Authorization', `Bearer ${resolvedToken}`);
75
- const runtimeBaseUrl = baseUrl !== null && baseUrl !== void 0 ? baseUrl : (typeof window !== 'undefined' ? (_a = window.__ACCESSI_API_BASE_URL__) !== null && _a !== void 0 ? _a : null : null);
109
+ const runtimeBaseUrl = (config === null || config === void 0 ? void 0 : config.baseUrl) !== undefined
110
+ ? config.baseUrl
111
+ : baseUrl !== null && baseUrl !== void 0 ? baseUrl : (typeof window !== 'undefined' ? (_b = window.__ACCESSI_API_BASE_URL__) !== null && _b !== void 0 ? _b : null : null);
76
112
  const requestUrl = runtimeBaseUrl && url.startsWith('/')
77
113
  ? `${runtimeBaseUrl.replace(/\/+$/, '')}${url}`
78
114
  : url;
@@ -81,14 +117,14 @@ function accessiFetch(url, options) {
81
117
  const response = yield fetch(requestUrl, Object.assign(Object.assign({}, options), { headers }));
82
118
  const payload = yield response.json().catch(() => undefined);
83
119
  if (!response.ok) {
84
- const message = (_c = (_b = payloadString(payload, 'message')) !== null && _b !== void 0 ? _b : payloadString(payload, 'error')) !== null && _c !== void 0 ? _c : `Errore HTTP ${response.status}`;
120
+ const message = (_d = (_c = payloadString(payload, 'message')) !== null && _c !== void 0 ? _c : payloadString(payload, 'error')) !== null && _d !== void 0 ? _d : `Errore HTTP ${response.status}`;
85
121
  const rawDetails = payload && typeof payload === 'object' ? payload.details : undefined;
86
122
  const details = Array.isArray(rawDetails) ? rawDetails.map((item) => String(item)) : undefined;
87
123
  // Un 401 su una richiesta autenticata significa sessione scaduta/revocata: il token non e piu valido.
88
124
  if (response.status === 401 && authenticatedRequest && typeof window !== 'undefined') {
89
125
  window.dispatchEvent(new CustomEvent(exports.ACCESSI_UNAUTHORIZED_EVENT));
90
126
  }
91
- throw new AccessiRequestError(message, response.status, (_d = payloadString(payload, 'code')) !== null && _d !== void 0 ? _d : payloadString(payload, 'error'), details);
127
+ throw new AccessiRequestError(message, response.status, (_e = payloadString(payload, 'code')) !== null && _e !== void 0 ? _e : payloadString(payload, 'error'), details);
92
128
  }
93
129
  return {
94
130
  data: payload,
@@ -1 +1 @@
1
- {"version":3,"file":"accessiFetch.js","sourceRoot":"","sources":["../../../src/accessi-module/Console/accessiFetch.ts"],"names":[],"mappings":"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","sourcesContent":["let accessToken: string | null = null;\nlet baseUrl: string | null = null;\nlet tokenProvider: (() => string | null | Promise<string | null>) | null = null;\n\ndeclare global {\n interface Window {\n __ACCESSI_API_BASE_URL__?: string;\n }\n}\n\nconst loadingEventName = 'accessi-console-network';\n/** Emesso quando una richiesta autenticata riceve 401: la console deve riportare al login. */\nexport const ACCESSI_UNAUTHORIZED_EVENT = 'accessi-console-unauthorized';\n\n/** Errore del client console: conserva status, codice stabile Accessi e dettagli di validazione. */\nexport class AccessiRequestError extends Error {\n constructor(message: string, readonly status: number, readonly code?: string, readonly details?: string[]) {\n super(message);\n this.name = 'AccessiRequestError';\n }\n}\n\n/** Notifies the browser shell without coupling generated Orval calls to the UI implementation. */\nfunction notifyNetworkActivity(active: boolean): void {\n if (typeof window !== 'undefined') {\n window.dispatchEvent(new CustomEvent(loadingEventName, { detail: { active } }));\n }\n}\n\n/** Imposta il JWT usato da tutte le funzioni generate da Orval. */\nexport function setAccessiConsoleToken(token: string | null): void {\n accessToken = token;\n}\n\n/** Prefissa le chiamate relative del client generato (es. `https://accessi.example.com`). */\nexport function setAccessiFetchBaseUrl(url: string | null): void {\n baseUrl = url ? url.replace(/\\/+$/, '') : null;\n}\n\n/** Token provider per client esterni alla console (server-to-server o frontend). */\nexport function setAccessiFetchTokenProvider(\n provider: (() => string | null | Promise<string | null>) | null,\n): void {\n tokenProvider = provider;\n}\n\n/** Legge una stringa non vuota dal payload di errore Accessi, ignorando tipi inattesi. */\nfunction payloadString(payload: unknown, key: string): string | undefined {\n if (!payload || typeof payload !== 'object') return undefined;\n const value = (payload as Record<string, unknown>)[key];\n return typeof value === 'string' && value.length > 0 ? value : undefined;\n}\n\n/**\n * Trasporto comune del client Orval: aggiunge il Bearer token e converte le\n * risposte di errore Accessi in Error JavaScript leggibili dalla console.\n */\nexport async function accessiFetch<T>(url: string, options: RequestInit): Promise<T> {\n const headers = new Headers(options.headers);\n headers.set('Accept', 'application/json');\n if (options.body !== undefined && !headers.has('Content-Type')) {\n headers.set('Content-Type', 'application/json');\n }\n const resolvedToken = tokenProvider ? await tokenProvider() : accessToken;\n const authenticatedRequest = resolvedToken !== null && resolvedToken !== undefined;\n if (resolvedToken) headers.set('Authorization', `Bearer ${resolvedToken}`);\n const runtimeBaseUrl = baseUrl\n ?? (typeof window !== 'undefined' ? window.__ACCESSI_API_BASE_URL__ ?? null : null);\n const requestUrl = runtimeBaseUrl && url.startsWith('/')\n ? `${runtimeBaseUrl.replace(/\\/+$/, '')}${url}`\n : url;\n\n notifyNetworkActivity(true);\n try {\n const response = await fetch(requestUrl, { ...options, headers });\n const payload = await response.json().catch(() => undefined);\n if (!response.ok) {\n const message = payloadString(payload, 'message') ?? payloadString(payload, 'error') ?? `Errore HTTP ${response.status}`;\n const rawDetails = payload && typeof payload === 'object' ? (payload as { details?: unknown }).details : undefined;\n const details = Array.isArray(rawDetails) ? rawDetails.map((item) => String(item)) : undefined;\n // Un 401 su una richiesta autenticata significa sessione scaduta/revocata: il token non e piu valido.\n if (response.status === 401 && authenticatedRequest && typeof window !== 'undefined') {\n window.dispatchEvent(new CustomEvent(ACCESSI_UNAUTHORIZED_EVENT));\n }\n throw new AccessiRequestError(message, response.status, payloadString(payload, 'code') ?? payloadString(payload, 'error'), details);\n }\n return {\n data: payload,\n status: response.status,\n headers: response.headers,\n } as T;\n } finally {\n notifyNetworkActivity(false);\n }\n}\n"]}
1
+ {"version":3,"file":"accessiFetch.js","sourceRoot":"","sources":["../../../src/accessi-module/Console/accessiFetch.ts"],"names":[],"mappings":"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","sourcesContent":["let accessToken: string | null = null;\nlet baseUrl: string | null = null;\nlet tokenProvider: (() => string | null | Promise<string | null>) | null = null;\nlet scopedConfig: AccessiClientConfig | null = null;\n\n/**\n * Configurazione di un client Accessi.\n *\n * Usata sia dalla configurazione globale (`configureAccessiClient`) sia dalle\n * istanze isolate create con `createAccessiClient`.\n */\nexport interface AccessiClientConfig {\n /** Base URL di Accessi Service, es. `https://accessi.example.com`. */\n baseUrl?: string | null;\n /** Token statico. Preferire `getToken` per token che cambiano nel tempo. */\n token?: string | null;\n /** Provider asincrono/sincrono del token corrente. */\n getToken?: () => string | null | Promise<string | null>;\n}\n\ndeclare global {\n interface Window {\n __ACCESSI_API_BASE_URL__?: string;\n }\n}\n\nconst loadingEventName = 'accessi-console-network';\n/** Emesso quando una richiesta autenticata riceve 401: la console deve riportare al login. */\nexport const ACCESSI_UNAUTHORIZED_EVENT = 'accessi-console-unauthorized';\n\n/** Errore del client console: conserva status, codice stabile Accessi e dettagli di validazione. */\nexport class AccessiRequestError extends Error {\n constructor(message: string, readonly status: number, readonly code?: string, readonly details?: string[]) {\n super(message);\n this.name = 'AccessiRequestError';\n }\n}\n\n/** Notifies the browser shell without coupling generated Orval calls to the UI implementation. */\nfunction notifyNetworkActivity(active: boolean): void {\n if (typeof window !== 'undefined') {\n window.dispatchEvent(new CustomEvent(loadingEventName, { detail: { active } }));\n }\n}\n\n/** Imposta il JWT usato da tutte le funzioni generate da Orval. */\nexport function setAccessiConsoleToken(token: string | null): void {\n accessToken = token;\n}\n\n/** Prefissa le chiamate relative del client generato (es. `https://accessi.example.com`). */\nexport function setAccessiFetchBaseUrl(url: string | null): void {\n baseUrl = url ? url.replace(/\\/+$/, '') : null;\n}\n\n/** Token provider per client esterni alla console (server-to-server o frontend). */\nexport function setAccessiFetchTokenProvider(\n provider: (() => string | null | Promise<string | null>) | null,\n): void {\n tokenProvider = provider;\n}\n\n/** Configurazione isolata attiva in questo momento, se una chiamata e in corso. */\nexport function getAccessiClientConfig(): AccessiClientConfig | null {\n return scopedConfig;\n}\n\n/**\n * Esegue `callback` con una configurazione del client isolata.\n *\n * Le funzioni generate da Orval invocano il trasporto in modo sincrono, quindi\n * la configurazione viene letta all'inizio della richiesta: due client diversi\n * possono chiamare in concorrenza senza sovrascriversi a vicenda.\n *\n * Per un uso continuativo preferire `createAccessiClient`, che applica il\n * contesto a ogni metodo.\n */\nexport function runWithAccessiClient<T>(config: AccessiClientConfig, callback: () => T): T {\n const previous = scopedConfig;\n scopedConfig = config;\n try {\n return callback();\n } finally {\n scopedConfig = previous;\n }\n}\n\n/** Legge una stringa non vuota dal payload di errore Accessi, ignorando tipi inattesi. */\nfunction payloadString(payload: unknown, key: string): string | undefined {\n if (!payload || typeof payload !== 'object') return undefined;\n const value = (payload as Record<string, unknown>)[key];\n return typeof value === 'string' && value.length > 0 ? value : undefined;\n}\n\n/**\n * Trasporto comune del client Orval: aggiunge il Bearer token e converte le\n * risposte di errore Accessi in Error JavaScript leggibili dalla console.\n */\nexport async function accessiFetch<T>(url: string, options: RequestInit): Promise<T> {\n // Il contesto va letto prima di ogni await: la funzione generata invoca il\n // trasporto in modo sincrono, quindi la configurazione appartiene a questa call.\n const config = scopedConfig;\n const headers = new Headers(options.headers);\n headers.set('Accept', 'application/json');\n if (options.body !== undefined && !headers.has('Content-Type')) {\n headers.set('Content-Type', 'application/json');\n }\n const resolvedToken = config\n ? (config.getToken ? await config.getToken() : config.token ?? null)\n : tokenProvider\n ? await tokenProvider()\n : accessToken;\n const authenticatedRequest = resolvedToken !== null && resolvedToken !== undefined;\n if (resolvedToken) headers.set('Authorization', `Bearer ${resolvedToken}`);\n const runtimeBaseUrl = config?.baseUrl !== undefined\n ? config.baseUrl\n : baseUrl ?? (typeof window !== 'undefined' ? window.__ACCESSI_API_BASE_URL__ ?? null : null);\n const requestUrl = runtimeBaseUrl && url.startsWith('/')\n ? `${runtimeBaseUrl.replace(/\\/+$/, '')}${url}`\n : url;\n\n notifyNetworkActivity(true);\n try {\n const response = await fetch(requestUrl, { ...options, headers });\n const payload = await response.json().catch(() => undefined);\n if (!response.ok) {\n const message = payloadString(payload, 'message') ?? payloadString(payload, 'error') ?? `Errore HTTP ${response.status}`;\n const rawDetails = payload && typeof payload === 'object' ? (payload as { details?: unknown }).details : undefined;\n const details = Array.isArray(rawDetails) ? rawDetails.map((item) => String(item)) : undefined;\n // Un 401 su una richiesta autenticata significa sessione scaduta/revocata: il token non e piu valido.\n if (response.status === 401 && authenticatedRequest && typeof window !== 'undefined') {\n window.dispatchEvent(new CustomEvent(ACCESSI_UNAUTHORIZED_EVENT));\n }\n throw new AccessiRequestError(message, response.status, payloadString(payload, 'code') ?? payloadString(payload, 'error'), details);\n }\n return {\n data: payload,\n status: response.status,\n headers: response.headers,\n } as T;\n } finally {\n notifyNetworkActivity(false);\n }\n}\n"]}
@@ -2,6 +2,7 @@
2
2
  var accessToken = null;
3
3
  var baseUrl = null;
4
4
  var tokenProvider = null;
5
+ var scopedConfig = null;
5
6
  var loadingEventName = "accessi-console-network";
6
7
  var ACCESSI_UNAUTHORIZED_EVENT = "accessi-console-unauthorized";
7
8
  var AccessiRequestError = class extends Error {
@@ -27,15 +28,16 @@ function payloadString(payload, key) {
27
28
  return typeof value === "string" && value.length > 0 ? value : void 0;
28
29
  }
29
30
  async function accessiFetch(url, options) {
31
+ const config = scopedConfig;
30
32
  const headers = new Headers(options.headers);
31
33
  headers.set("Accept", "application/json");
32
34
  if (options.body !== void 0 && !headers.has("Content-Type")) {
33
35
  headers.set("Content-Type", "application/json");
34
36
  }
35
- const resolvedToken = tokenProvider ? await tokenProvider() : accessToken;
37
+ const resolvedToken = config ? config.getToken ? await config.getToken() : config.token ?? null : tokenProvider ? await tokenProvider() : accessToken;
36
38
  const authenticatedRequest = resolvedToken !== null && resolvedToken !== void 0;
37
39
  if (resolvedToken) headers.set("Authorization", `Bearer ${resolvedToken}`);
38
- const runtimeBaseUrl = baseUrl ?? (typeof window !== "undefined" ? window.__ACCESSI_API_BASE_URL__ ?? null : null);
40
+ const runtimeBaseUrl = config?.baseUrl !== void 0 ? config.baseUrl : baseUrl ?? (typeof window !== "undefined" ? window.__ACCESSI_API_BASE_URL__ ?? null : null);
39
41
  const requestUrl = runtimeBaseUrl && url.startsWith("/") ? `${runtimeBaseUrl.replace(/\/+$/, "")}${url}` : url;
40
42
  notifyNetworkActivity(true);
41
43
  try {
@@ -1000,6 +1002,9 @@ var WIKI_SECTIONS = [
1000
1002
  ["accessi/server", "Bootstrap completo: DB, SMTP, migrazioni, console, API.", "s\xEC"],
1001
1003
  ["accessi/resource-server", "Guard/middleware per backend fratelli: verifica JWT e autorizzazione remota.", "no"],
1002
1004
  ["accessi/client", "Client OpenAPI generato per chiamare Accessi Service.", "no"],
1005
+ ["accessi/client/public", "Solo API pubbliche (login, refresh, 2FA, reset password, registrazione, ticket console).", "no"],
1006
+ ["accessi/client/admin", "Solo API amministrative (utenti, ruoli, menu, filtri, provider federati, schema).", "no"],
1007
+ ["accessi/client/service", "Solo API service-to-service (service token e introspezione), mai nei frontend.", "no"],
1003
1008
  ["accessi/contracts", "Tipi, enum e helper puri browser-safe.", "no"],
1004
1009
  ["accessi/contracts/dtos", "DTO Nest con class-validator e decoratori OpenAPI.", "no"],
1005
1010
  ["accessi/openapi", "setupOpenApi e merge del documento OpenAPI.", "no"],
@@ -1009,15 +1014,21 @@ var WIKI_SECTIONS = [
1009
1014
  ),
1010
1015
  p(`Topologia consigliata: un solo Accessi Service possiede database, encryptionKey, SMTP, chiavi JWT e console. Gli altri backend usano resource-server e client, senza credenziali del database Accessi.`),
1011
1016
  p(`Per avviare Accessi come servizio autonomo usare startAccessiService: espone /health/live, /health/ready, /health/metrics, valida la configurazione e gestisce SIGTERM/SIGINT.`),
1017
+ p(`Per parlare con piu Accessi Service o tenant dallo stesso processo usare createAccessiClient: ogni istanza ha base URL e token propri, isolati anche tra richieste concorrenti. configureAccessiClient resta il default globale per le funzioni esportate dal package.`),
1012
1018
  good("ts", [
1013
1019
  "// Backend che ospita Accessi",
1014
1020
  "import { initializeAccessiModule } from 'emilsoftware-utilities/accessi/server';",
1015
1021
  "",
1016
1022
  "// Backend fratello: nessun AccessiModule, nessun DB Accessi",
1017
1023
  "import { createAccessiAuthMiddleware } from 'emilsoftware-utilities/accessi/resource-server';",
1018
- "import { configureAccessiClient, login } from 'emilsoftware-utilities/accessi/client';"
1024
+ "import { createAccessiClient } from 'emilsoftware-utilities/accessi/client';",
1025
+ "",
1026
+ "const milano = createAccessiClient({ baseUrl: 'https://accessi-milano.example.com', getToken });",
1027
+ "const roma = createAccessiClient({ baseUrl: 'https://accessi-roma.example.com', token: tokenRoma });",
1028
+ "const [utentiMilano, utentiRoma] = await Promise.all([milano.getUsers(), roma.getUsers()]);"
1019
1029
  ].join("\n"), "Import corretti per ruolo"),
1020
1030
  note("warn", `Un solo proprietario`, `Non montare AccessiModule in due backend puntati allo stesso database: migrazioni, bootstrap admin, ticket console e rate limit diventano ambigui.`),
1031
+ note("info", `Client per scope`, `Usare accessi/client/public nei frontend pubblici, accessi/client/admin nella console e nei tool amministrativi, accessi/client/service solo nei backend fratelli. Gli scope partizionano il client completo e condividono gli stessi tipi; il client completo resta disponibile per compatibilita.`),
1021
1032
  note("info", `Prompt di integrazione`, `Il file integration-prompt.md nella root del repository contiene il contesto completo per frontend, backend e agenti AI.`)
1022
1033
  ]
1023
1034
  },
@@ -133,6 +133,9 @@ exports.WIKI_SECTIONS = [
133
133
  ['accessi/server', 'Bootstrap completo: DB, SMTP, migrazioni, console, API.', 'sì'],
134
134
  ['accessi/resource-server', 'Guard/middleware per backend fratelli: verifica JWT e autorizzazione remota.', 'no'],
135
135
  ['accessi/client', 'Client OpenAPI generato per chiamare Accessi Service.', 'no'],
136
+ ['accessi/client/public', 'Solo API pubbliche (login, refresh, 2FA, reset password, registrazione, ticket console).', 'no'],
137
+ ['accessi/client/admin', 'Solo API amministrative (utenti, ruoli, menu, filtri, provider federati, schema).', 'no'],
138
+ ['accessi/client/service', 'Solo API service-to-service (service token e introspezione), mai nei frontend.', 'no'],
136
139
  ['accessi/contracts', 'Tipi, enum e helper puri browser-safe.', 'no'],
137
140
  ['accessi/contracts/dtos', 'DTO Nest con class-validator e decoratori OpenAPI.', 'no'],
138
141
  ['accessi/openapi', 'setupOpenApi e merge del documento OpenAPI.', 'no'],
@@ -141,15 +144,21 @@ exports.WIKI_SECTIONS = [
141
144
  ]),
142
145
  p(`Topologia consigliata: un solo Accessi Service possiede database, encryptionKey, SMTP, chiavi JWT e console. Gli altri backend usano resource-server e client, senza credenziali del database Accessi.`),
143
146
  p(`Per avviare Accessi come servizio autonomo usare startAccessiService: espone /health/live, /health/ready, /health/metrics, valida la configurazione e gestisce SIGTERM/SIGINT.`),
147
+ p(`Per parlare con piu Accessi Service o tenant dallo stesso processo usare createAccessiClient: ogni istanza ha base URL e token propri, isolati anche tra richieste concorrenti. configureAccessiClient resta il default globale per le funzioni esportate dal package.`),
144
148
  good('ts', [
145
149
  "// Backend che ospita Accessi",
146
150
  "import { initializeAccessiModule } from 'emilsoftware-utilities/accessi/server';",
147
151
  '',
148
152
  "// Backend fratello: nessun AccessiModule, nessun DB Accessi",
149
153
  "import { createAccessiAuthMiddleware } from 'emilsoftware-utilities/accessi/resource-server';",
150
- "import { configureAccessiClient, login } from 'emilsoftware-utilities/accessi/client';",
154
+ "import { createAccessiClient } from 'emilsoftware-utilities/accessi/client';",
155
+ '',
156
+ "const milano = createAccessiClient({ baseUrl: 'https://accessi-milano.example.com', getToken });",
157
+ "const roma = createAccessiClient({ baseUrl: 'https://accessi-roma.example.com', token: tokenRoma });",
158
+ "const [utentiMilano, utentiRoma] = await Promise.all([milano.getUsers(), roma.getUsers()]);",
151
159
  ].join('\n'), 'Import corretti per ruolo'),
152
160
  note('warn', `Un solo proprietario`, `Non montare AccessiModule in due backend puntati allo stesso database: migrazioni, bootstrap admin, ticket console e rate limit diventano ambigui.`),
161
+ note('info', `Client per scope`, `Usare accessi/client/public nei frontend pubblici, accessi/client/admin nella console e nei tool amministrativi, accessi/client/service solo nei backend fratelli. Gli scope partizionano il client completo e condividono gli stessi tipi; il client completo resta disponibile per compatibilita.`),
153
162
  note('info', `Prompt di integrazione`, `Il file integration-prompt.md nella root del repository contiene il contesto completo per frontend, backend e agenti AI.`),
154
163
  ],
155
164
  },