@a-cube-io/ereceipts-js-sdk 2.0.6 → 2.0.8

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/dist/index.cjs.js CHANGED
@@ -2,8 +2,8 @@
2
2
 
3
3
  Object.defineProperty(exports, '__esModule', { value: true });
4
4
 
5
- var axios = require('axios');
6
5
  var z = require('zod');
6
+ var axios = require('axios');
7
7
 
8
8
  function _interopNamespaceDefault(e) {
9
9
  var n = Object.create(null);
@@ -1861,135 +1861,440 @@ function extractRoles(jwtRoles) {
1861
1861
  return allRoles;
1862
1862
  }
1863
1863
 
1864
- class AuthenticationService {
1865
- get user$() {
1866
- return this.userSubject.asObservable();
1867
- }
1868
- get isAuthenticated$() {
1869
- return this.userSubject.pipe(map((user) => user !== null), distinctUntilChanged(), takeUntil(this.destroy$));
1870
- }
1871
- get authState$() {
1872
- return this.authStateSubject.asObservable();
1864
+ function clearObject(input) {
1865
+ if (input === null || input === undefined || input === '') {
1866
+ return undefined;
1873
1867
  }
1874
- constructor(httpPort, tokenStorage, config, events = {}) {
1875
- this.httpPort = httpPort;
1876
- this.tokenStorage = tokenStorage;
1877
- this.config = config;
1878
- this.events = events;
1879
- this.userSubject = new BehaviorSubject(null);
1880
- this.authStateSubject = new BehaviorSubject('idle');
1881
- this.destroy$ = new Subject();
1868
+ if (Array.isArray(input)) {
1869
+ const cleanedArray = input
1870
+ .map((item) => clearObject(item))
1871
+ .filter((item) => item !== undefined);
1872
+ return cleanedArray;
1882
1873
  }
1883
- async login(credentials) {
1884
- this.authStateSubject.next('authenticating');
1885
- try {
1886
- const response = await this.httpPort.post(`${this.config.authUrl}/login`, {
1887
- email: credentials.email,
1888
- password: credentials.password,
1889
- });
1890
- const jwtPayload = parseJwt(response.data.token);
1891
- const expiresAt = jwtPayload.exp * 1000;
1892
- await this.tokenStorage.saveAccessToken(response.data.token, expiresAt);
1893
- const user = this.createUserFromPayload(jwtPayload);
1894
- await this.tokenStorage.saveUser(user);
1895
- this.userSubject.next(user);
1896
- this.authStateSubject.next('authenticated');
1897
- this.events.onUserChanged?.(user);
1898
- return user;
1899
- }
1900
- catch (error) {
1901
- this.authStateSubject.next('error');
1902
- throw error;
1874
+ if (typeof input === 'object' && input.constructor === Object) {
1875
+ const cleaned = {};
1876
+ for (const [key, value] of Object.entries(input)) {
1877
+ const cleanedValue = clearObject(value);
1878
+ if (cleanedValue !== undefined) {
1879
+ cleaned[key] = cleanedValue;
1880
+ }
1903
1881
  }
1882
+ return cleaned;
1904
1883
  }
1905
- async logout() {
1906
- await this.tokenStorage.clearTokens();
1907
- this.userSubject.next(null);
1908
- this.authStateSubject.next('idle');
1909
- this.events.onUserChanged?.(null);
1884
+ return input;
1885
+ }
1886
+ function clearObjectShallow(obj) {
1887
+ if (!obj || typeof obj !== 'object') {
1888
+ return {};
1910
1889
  }
1911
- async getCurrentUser() {
1912
- const currentUser = this.userSubject.value;
1913
- if (currentUser) {
1914
- return currentUser;
1915
- }
1916
- const storedUser = await this.tokenStorage.getUser();
1917
- if (storedUser) {
1918
- this.userSubject.next(storedUser);
1919
- this.authStateSubject.next('authenticated');
1920
- return storedUser;
1921
- }
1922
- const token = await this.tokenStorage.getAccessToken();
1923
- if (!token) {
1924
- return null;
1925
- }
1926
- const jwtPayload = parseJwt(token);
1927
- if (isTokenExpired(jwtPayload)) {
1928
- await this.tokenStorage.clearTokens();
1929
- return null;
1890
+ const cleaned = {};
1891
+ for (const [key, value] of Object.entries(obj)) {
1892
+ if (value !== null && value !== undefined && value !== '') {
1893
+ cleaned[key] = value;
1930
1894
  }
1931
- const user = this.createUserFromPayload(jwtPayload);
1932
- await this.tokenStorage.saveUser(user);
1933
- this.userSubject.next(user);
1934
- this.authStateSubject.next('authenticated');
1935
- return user;
1936
1895
  }
1937
- async isAuthenticated() {
1938
- const token = await this.tokenStorage.getAccessToken();
1939
- if (!token) {
1940
- return false;
1941
- }
1942
- const jwtPayload = parseJwt(token);
1943
- return !isTokenExpired(jwtPayload);
1896
+ return cleaned;
1897
+ }
1898
+ function isEmpty(value) {
1899
+ return value === null || value === undefined || value === '';
1900
+ }
1901
+ function hasNonEmptyValues(obj) {
1902
+ if (!obj || typeof obj !== 'object') {
1903
+ return false;
1944
1904
  }
1945
- async getAccessToken() {
1946
- const token = await this.tokenStorage.getAccessToken();
1947
- if (!token) {
1948
- return null;
1949
- }
1950
- const jwtPayload = parseJwt(token);
1951
- if (isTokenExpired(jwtPayload)) {
1952
- await this.tokenStorage.clearTokens();
1953
- this.userSubject.next(null);
1954
- this.authStateSubject.next('idle');
1955
- this.events.onUserChanged?.(null);
1956
- return null;
1957
- }
1958
- return token;
1905
+ return Object.values(obj).some((value) => !isEmpty(value));
1906
+ }
1907
+
1908
+ /**
1909
+ * Platform detection utilities
1910
+ */
1911
+ /**
1912
+ * Detect the current platform
1913
+ */
1914
+ function detectPlatform() {
1915
+ // Check for React Native
1916
+ if (typeof global !== 'undefined' &&
1917
+ global.__DEV__ !== undefined &&
1918
+ typeof global.navigator !== 'undefined' &&
1919
+ global.navigator.product === 'ReactNative') {
1920
+ return {
1921
+ platform: 'react-native',
1922
+ isReactNative: true,
1923
+ isWeb: false,
1924
+ isNode: false,
1925
+ isExpo: checkExpo(),
1926
+ };
1959
1927
  }
1960
- createUserFromPayload(jwtPayload) {
1928
+ // Check for Web/Browser
1929
+ if (typeof window !== 'undefined' &&
1930
+ typeof window.document !== 'undefined' &&
1931
+ typeof window.navigator !== 'undefined') {
1961
1932
  return {
1962
- id: jwtPayload.uid.toString(),
1963
- email: jwtPayload.username,
1964
- username: jwtPayload.username,
1965
- roles: jwtPayload.roles,
1966
- fid: jwtPayload.fid,
1967
- pid: jwtPayload.pid,
1968
- expiresAt: jwtPayload.exp * 1000,
1933
+ platform: 'web',
1934
+ isReactNative: false,
1935
+ isWeb: true,
1936
+ isNode: false,
1937
+ isExpo: false,
1969
1938
  };
1970
1939
  }
1971
- destroy() {
1972
- this.destroy$.next();
1973
- this.destroy$.complete();
1940
+ // Check for Node.js
1941
+ if (typeof process !== 'undefined' && process.versions && process.versions.node) {
1942
+ return {
1943
+ platform: 'node',
1944
+ isReactNative: false,
1945
+ isWeb: false,
1946
+ isNode: true,
1947
+ isExpo: false,
1948
+ };
1974
1949
  }
1950
+ // Unknown platform
1951
+ return {
1952
+ platform: 'unknown',
1953
+ isReactNative: false,
1954
+ isWeb: false,
1955
+ isNode: false,
1956
+ isExpo: false,
1957
+ };
1975
1958
  }
1976
-
1977
- const CERTIFICATE_KEY = 'acube_certificate';
1978
- class CertificateService {
1979
- get certificate$() {
1980
- return this.certificateSubject.asObservable();
1959
+ /**
1960
+ * Check if running in Expo
1961
+ */
1962
+ function checkExpo() {
1963
+ try {
1964
+ return (typeof global !== 'undefined' &&
1965
+ (typeof global.Expo !== 'undefined' || typeof global.expo !== 'undefined'));
1981
1966
  }
1982
- get hasCertificate$() {
1983
- return this.certificateSubject.pipe(map((cert) => cert !== null), distinctUntilChanged());
1967
+ catch {
1968
+ return false;
1984
1969
  }
1985
- get state$() {
1986
- return this.stateSubject.asObservable();
1970
+ }
1971
+
1972
+ function getDefaultExportFromCjs (x) {
1973
+ return x && x.__esModule && Object.prototype.hasOwnProperty.call(x, 'default') ? x['default'] : x;
1974
+ }
1975
+
1976
+ var picocolors_browser = {exports: {}};
1977
+
1978
+ var x=String;
1979
+ var create=function() {return {isColorSupported:false,reset:x,bold:x,dim:x,italic:x,underline:x,inverse:x,hidden:x,strikethrough:x,black:x,red:x,green:x,yellow:x,blue:x,magenta:x,cyan:x,white:x,gray:x,bgBlack:x,bgRed:x,bgGreen:x,bgYellow:x,bgBlue:x,bgMagenta:x,bgCyan:x,bgWhite:x,blackBright:x,redBright:x,greenBright:x,yellowBright:x,blueBright:x,magentaBright:x,cyanBright:x,whiteBright:x,bgBlackBright:x,bgRedBright:x,bgGreenBright:x,bgYellowBright:x,bgBlueBright:x,bgMagentaBright:x,bgCyanBright:x,bgWhiteBright:x}};
1980
+ picocolors_browser.exports=create();
1981
+ picocolors_browser.exports.createColors = create;
1982
+
1983
+ var picocolors_browserExports = picocolors_browser.exports;
1984
+ var pc = /*@__PURE__*/getDefaultExportFromCjs(picocolors_browserExports);
1985
+
1986
+ const levelColors = {
1987
+ debug: {
1988
+ prefix: pc.gray,
1989
+ message: pc.gray,
1990
+ data: pc.dim,
1991
+ },
1992
+ info: {
1993
+ prefix: pc.cyan,
1994
+ message: pc.white,
1995
+ data: pc.dim,
1996
+ },
1997
+ warn: {
1998
+ prefix: pc.yellow,
1999
+ message: pc.yellow,
2000
+ data: pc.dim,
2001
+ },
2002
+ error: {
2003
+ prefix: pc.red,
2004
+ message: pc.red,
2005
+ data: pc.dim,
2006
+ },
2007
+ };
2008
+ const levelIcons = {
2009
+ debug: '🔍',
2010
+ info: 'ℹ️ ',
2011
+ warn: '⚠️ ',
2012
+ error: '❌',
2013
+ };
2014
+ /**
2015
+ * Format data for pretty display in logs
2016
+ */
2017
+ function formatData(data, level) {
2018
+ if (data === undefined || data === null) {
2019
+ return String(data);
1987
2020
  }
1988
- constructor(secureStorage) {
1989
- this.secureStorage = secureStorage;
1990
- this.certificateSubject = new BehaviorSubject(null);
1991
- this.stateSubject = new BehaviorSubject('idle');
1992
- this.destroy$ = new Subject();
2021
+ // For primitive types, just return as string
2022
+ if (typeof data !== 'object') {
2023
+ return String(data);
2024
+ }
2025
+ // For Error objects, format nicely
2026
+ if (data instanceof Error) {
2027
+ return `${data.name}: ${data.message}${data.stack ? `\n${pc.dim(data.stack)}` : ''}`;
2028
+ }
2029
+ try {
2030
+ // Apply level-specific coloring
2031
+ const colors = levelColors[level];
2032
+ return colors.data(JSON.stringify(data, null, 2));
2033
+ }
2034
+ catch {
2035
+ // Fallback to JSON.stringify if pretty-format fails
2036
+ try {
2037
+ return JSON.stringify(data, null, 2);
2038
+ }
2039
+ catch {
2040
+ return String(data);
2041
+ }
2042
+ }
2043
+ }
2044
+ class Logger {
2045
+ constructor() {
2046
+ this.enabled = false;
2047
+ }
2048
+ setEnabled(enabled) {
2049
+ this.enabled = enabled;
2050
+ }
2051
+ isEnabled() {
2052
+ return this.enabled;
2053
+ }
2054
+ debug(prefix, message, data) {
2055
+ if (!this.enabled)
2056
+ return;
2057
+ this.log('debug', prefix, message, data);
2058
+ }
2059
+ info(prefix, message, data) {
2060
+ if (!this.enabled)
2061
+ return;
2062
+ this.log('info', prefix, message, data);
2063
+ }
2064
+ warn(prefix, message, data) {
2065
+ this.log('warn', prefix, message, data);
2066
+ }
2067
+ error(prefix, message, data) {
2068
+ this.log('error', prefix, message, data);
2069
+ }
2070
+ log(level, prefix, message, data) {
2071
+ const colors = levelColors[level];
2072
+ const icon = levelIcons[level];
2073
+ const isoTime = new Date().toISOString().split('T')[1] ?? '';
2074
+ const timestamp = pc.dim(isoTime.slice(0, 12));
2075
+ const formattedPrefix = colors.prefix(`[${prefix}]`);
2076
+ const formattedMessage = colors.message(message);
2077
+ const consoleMethod = level === 'debug'
2078
+ ? console.debug
2079
+ : level === 'info'
2080
+ ? console.info
2081
+ : level === 'warn'
2082
+ ? console.warn
2083
+ : console.error;
2084
+ const header = `${timestamp} ${icon} ${formattedPrefix} ${formattedMessage}`;
2085
+ if (data !== undefined) {
2086
+ const formattedData = formatData(data, level);
2087
+ // Check if data is an object (multi-line) or primitive (single-line)
2088
+ const isMultiLine = typeof data === 'object' && data !== null;
2089
+ if (isMultiLine) {
2090
+ consoleMethod(`${header}\n${formattedData}`);
2091
+ }
2092
+ else {
2093
+ consoleMethod(`${header}`, formattedData);
2094
+ }
2095
+ }
2096
+ else {
2097
+ consoleMethod(header);
2098
+ }
2099
+ }
2100
+ }
2101
+ const logger = new Logger();
2102
+ function createPrefixedLogger(prefix) {
2103
+ return {
2104
+ debug: (message, data) => logger.debug(prefix, message, data),
2105
+ info: (message, data) => logger.info(prefix, message, data),
2106
+ warn: (message, data) => logger.warn(prefix, message, data),
2107
+ error: (message, data) => logger.error(prefix, message, data),
2108
+ };
2109
+ }
2110
+
2111
+ /**
2112
+ * Formats a numeric string value to have exactly the specified number of decimal places.
2113
+ * E.g., "1" → "1.00", "10" → "10.00", "1.5" → "1.50"
2114
+ * Returns undefined for undefined input (preserves optional fields).
2115
+ *
2116
+ * @param value - The string value to format
2117
+ * @param decimals - Number of decimal places (default: 2)
2118
+ * @returns Formatted string or undefined if input is undefined
2119
+ */
2120
+ function formatDecimal(value, decimals = 2) {
2121
+ if (value === undefined)
2122
+ return undefined;
2123
+ const num = parseFloat(value);
2124
+ if (isNaN(num))
2125
+ return value;
2126
+ return num.toFixed(decimals);
2127
+ }
2128
+
2129
+ const log$g = createPrefixedLogger('AUTH-SERVICE');
2130
+ class AuthenticationService {
2131
+ get user$() {
2132
+ return this.userSubject.asObservable();
2133
+ }
2134
+ get isAuthenticated$() {
2135
+ return this.userSubject.pipe(map((user) => user !== null), distinctUntilChanged(), takeUntil(this.destroy$));
2136
+ }
2137
+ get authState$() {
2138
+ return this.authStateSubject.asObservable();
2139
+ }
2140
+ constructor(httpPort, tokenStorage, config, events = {}) {
2141
+ this.httpPort = httpPort;
2142
+ this.tokenStorage = tokenStorage;
2143
+ this.config = config;
2144
+ this.events = events;
2145
+ this.userSubject = new BehaviorSubject(null);
2146
+ this.authStateSubject = new BehaviorSubject('idle');
2147
+ this.destroy$ = new Subject();
2148
+ }
2149
+ async login(credentials) {
2150
+ this.authStateSubject.next('authenticating');
2151
+ log$g.info('Login attempt', {
2152
+ authUrl: this.config.authUrl,
2153
+ email: credentials.email,
2154
+ });
2155
+ try {
2156
+ const response = await this.httpPort.post(`${this.config.authUrl}/login`, {
2157
+ email: credentials.email,
2158
+ password: credentials.password,
2159
+ });
2160
+ const jwtPayload = parseJwt(response.data.token);
2161
+ const expiresAt = jwtPayload.exp * 1000;
2162
+ log$g.info('Login successful', {
2163
+ authUrl: this.config.authUrl,
2164
+ tokenPrefix: response.data.token.substring(0, 30) + '...',
2165
+ expiresAt: new Date(expiresAt).toISOString(),
2166
+ });
2167
+ await this.tokenStorage.saveAccessToken(response.data.token, expiresAt);
2168
+ const user = this.createUserFromPayload(jwtPayload);
2169
+ await this.tokenStorage.saveUser(user);
2170
+ this.userSubject.next(user);
2171
+ this.authStateSubject.next('authenticated');
2172
+ this.events.onUserChanged?.(user);
2173
+ return user;
2174
+ }
2175
+ catch (error) {
2176
+ this.authStateSubject.next('error');
2177
+ throw error;
2178
+ }
2179
+ }
2180
+ async logout() {
2181
+ await this.tokenStorage.clearTokens();
2182
+ this.userSubject.next(null);
2183
+ this.authStateSubject.next('idle');
2184
+ this.events.onUserChanged?.(null);
2185
+ }
2186
+ async getCurrentUser() {
2187
+ // Always verify token is valid before returning user
2188
+ const token = await this.tokenStorage.getAccessToken();
2189
+ if (!token) {
2190
+ // No token - clear any stale user state
2191
+ log$g.debug('getCurrentUser: No token in storage');
2192
+ if (this.userSubject.value) {
2193
+ this.userSubject.next(null);
2194
+ this.authStateSubject.next('idle');
2195
+ }
2196
+ return null;
2197
+ }
2198
+ log$g.debug('getCurrentUser: Token found', {
2199
+ tokenPrefix: token.substring(0, 30) + '...',
2200
+ tokenLength: token.length,
2201
+ });
2202
+ const jwtPayload = parseJwt(token);
2203
+ if (isTokenExpired(jwtPayload)) {
2204
+ // Token expired - clear everything
2205
+ log$g.warn('getCurrentUser: Token expired');
2206
+ await this.tokenStorage.clearTokens();
2207
+ this.userSubject.next(null);
2208
+ this.authStateSubject.next('idle');
2209
+ this.events.onUserChanged?.(null);
2210
+ return null;
2211
+ }
2212
+ // Token is valid - return cached user if available
2213
+ const currentUser = this.userSubject.value;
2214
+ if (currentUser) {
2215
+ log$g.debug('getCurrentUser: Returning cached user', {
2216
+ email: currentUser.email,
2217
+ roles: currentUser.roles,
2218
+ });
2219
+ return currentUser;
2220
+ }
2221
+ // Check stored user
2222
+ const storedUser = await this.tokenStorage.getUser();
2223
+ if (storedUser) {
2224
+ this.userSubject.next(storedUser);
2225
+ this.authStateSubject.next('authenticated');
2226
+ return storedUser;
2227
+ }
2228
+ // Create user from token
2229
+ const user = this.createUserFromPayload(jwtPayload);
2230
+ await this.tokenStorage.saveUser(user);
2231
+ this.userSubject.next(user);
2232
+ this.authStateSubject.next('authenticated');
2233
+ return user;
2234
+ }
2235
+ async isAuthenticated() {
2236
+ const token = await this.tokenStorage.getAccessToken();
2237
+ if (!token) {
2238
+ log$g.debug('isAuthenticated: No token in storage');
2239
+ return false;
2240
+ }
2241
+ const jwtPayload = parseJwt(token);
2242
+ const expired = isTokenExpired(jwtPayload);
2243
+ log$g.debug('isAuthenticated: Token check', {
2244
+ hasToken: true,
2245
+ expired,
2246
+ expiresAt: new Date(jwtPayload.exp * 1000).toISOString(),
2247
+ });
2248
+ return !expired;
2249
+ }
2250
+ async getAccessToken() {
2251
+ const token = await this.tokenStorage.getAccessToken();
2252
+ if (!token) {
2253
+ return null;
2254
+ }
2255
+ const jwtPayload = parseJwt(token);
2256
+ if (isTokenExpired(jwtPayload)) {
2257
+ await this.tokenStorage.clearTokens();
2258
+ this.userSubject.next(null);
2259
+ this.authStateSubject.next('idle');
2260
+ this.events.onUserChanged?.(null);
2261
+ return null;
2262
+ }
2263
+ return token;
2264
+ }
2265
+ createUserFromPayload(jwtPayload) {
2266
+ return {
2267
+ id: jwtPayload.uid.toString(),
2268
+ email: jwtPayload.username,
2269
+ username: jwtPayload.username,
2270
+ roles: jwtPayload.roles,
2271
+ fid: jwtPayload.fid,
2272
+ pid: jwtPayload.pid,
2273
+ expiresAt: jwtPayload.exp * 1000,
2274
+ };
2275
+ }
2276
+ destroy() {
2277
+ this.destroy$.next();
2278
+ this.destroy$.complete();
2279
+ }
2280
+ }
2281
+
2282
+ const CERTIFICATE_KEY = 'acube_certificate';
2283
+ class CertificateService {
2284
+ get certificate$() {
2285
+ return this.certificateSubject.asObservable();
2286
+ }
2287
+ get hasCertificate$() {
2288
+ return this.certificateSubject.pipe(map((cert) => cert !== null), distinctUntilChanged());
2289
+ }
2290
+ get state$() {
2291
+ return this.stateSubject.asObservable();
2292
+ }
2293
+ constructor(secureStorage) {
2294
+ this.secureStorage = secureStorage;
2295
+ this.certificateSubject = new BehaviorSubject(null);
2296
+ this.stateSubject = new BehaviorSubject('idle');
2297
+ this.destroy$ = new Subject();
1993
2298
  }
1994
2299
  async hasCertificate() {
1995
2300
  const cert = await this.getCertificate();
@@ -2080,409 +2385,680 @@ function hasAnyRole(userRoles, required) {
2080
2385
  return Object.values(userRoles).some((roles) => required.some((role) => roles.includes(role)));
2081
2386
  }
2082
2387
 
2083
- class AuthStrategy {
2084
- constructor(jwtHandler, mtlsHandler, userProvider, mtlsAdapter) {
2085
- this.jwtHandler = jwtHandler;
2086
- this.mtlsHandler = mtlsHandler;
2087
- this.userProvider = userProvider;
2088
- this.mtlsAdapter = mtlsAdapter;
2388
+ class ConfigManager {
2389
+ constructor(userConfig) {
2390
+ this.config = this.buildConfig(userConfig);
2089
2391
  }
2090
- async determineAuthConfig(url, method, explicitMode) {
2091
- if (this.isNotificationEndpoint(url) || this.isTelemetryEndpoint(url)) {
2092
- return { mode: 'mtls', usePort444: true };
2093
- }
2094
- const platform = this.detectPlatform();
2095
- const userRole = await this.getUserRole();
2096
- const isReceiptEndpoint = this.isReceiptEndpoint(url);
2097
- if (userRole === 'SUPPLIER') {
2098
- return { mode: 'jwt', usePort444: false };
2099
- }
2100
- if (userRole === 'CASHIER') {
2101
- if (!isReceiptEndpoint) {
2102
- return { mode: 'jwt', usePort444: false };
2103
- }
2104
- if (platform === 'mobile') {
2105
- return { mode: 'mtls', usePort444: true };
2106
- }
2107
- return { mode: 'jwt', usePort444: true };
2108
- }
2109
- if (userRole === 'MERCHANT') {
2110
- if (!isReceiptEndpoint) {
2111
- return { mode: 'jwt', usePort444: false };
2112
- }
2113
- if (this.isReturnableItemsEndpoint(url)) {
2114
- return { mode: 'mtls', usePort444: true };
2115
- }
2116
- if (method === 'GET') {
2117
- if (this.isDetailedReceiptEndpoint(url)) {
2118
- if (platform === 'mobile') {
2119
- return { mode: 'mtls', usePort444: true };
2120
- }
2121
- return { mode: 'jwt', usePort444: true };
2122
- }
2123
- return { mode: 'jwt', usePort444: false };
2124
- }
2125
- if (['POST', 'PUT', 'PATCH', 'DELETE'].includes(method)) {
2126
- if (platform === 'mobile') {
2127
- return { mode: 'mtls', usePort444: true };
2128
- }
2129
- return { mode: 'jwt', usePort444: true };
2130
- }
2131
- return { mode: 'jwt', usePort444: false };
2132
- }
2133
- if (explicitMode) {
2134
- if (userRole === 'SUPPLIER' && explicitMode === 'mtls') {
2135
- return { mode: 'jwt', usePort444: false };
2136
- }
2137
- return {
2138
- mode: explicitMode,
2139
- usePort444: explicitMode === 'mtls' || (platform === 'web' && isReceiptEndpoint),
2140
- };
2141
- }
2142
- if (platform === 'web') {
2143
- return { mode: 'jwt', usePort444: isReceiptEndpoint };
2144
- }
2145
- if (isReceiptEndpoint && platform === 'mobile') {
2146
- return { mode: 'mtls', usePort444: true };
2147
- }
2148
- return { mode: 'jwt', usePort444: false };
2149
- }
2150
- async getAuthHeaders() {
2151
- return this.jwtHandler.getAuthHeaders();
2152
- }
2153
- getMtlsHandler() {
2154
- return this.mtlsHandler;
2155
- }
2156
- getJwtHandler() {
2157
- return this.jwtHandler;
2392
+ buildConfig(userConfig) {
2393
+ return {
2394
+ environment: userConfig.environment,
2395
+ apiUrl: this.getDefaultApiUrl(userConfig.environment),
2396
+ authUrl: this.getDefaultAuthUrl(userConfig.environment),
2397
+ timeout: 30000,
2398
+ retryAttempts: 3,
2399
+ debug: userConfig.debug ?? false,
2400
+ customHeaders: {},
2401
+ };
2158
2402
  }
2159
- detectPlatform() {
2160
- if (!this.mtlsAdapter) {
2161
- return 'web';
2403
+ getDefaultApiUrl(environment) {
2404
+ switch (environment) {
2405
+ case 'production':
2406
+ return 'https://ereceipts-it.acubeapi.com';
2407
+ case 'development':
2408
+ return 'https://ereceipts-it.dev.acubeapi.com';
2409
+ case 'sandbox':
2410
+ default:
2411
+ return 'https://ereceipts-it-sandbox.acubeapi.com';
2162
2412
  }
2163
- const platformInfo = this.mtlsAdapter.getPlatformInfo();
2164
- return platformInfo.platform === 'web' ? 'web' : 'mobile';
2165
2413
  }
2166
- async getUserRole() {
2167
- if (!this.userProvider) {
2168
- return null;
2169
- }
2170
- const user = await this.userProvider.getCurrentUser();
2171
- if (!user || !user.roles) {
2172
- return null;
2173
- }
2174
- if (hasRole(user.roles, 'ROLE_SUPPLIER')) {
2175
- return 'SUPPLIER';
2176
- }
2177
- if (hasRole(user.roles, 'ROLE_MERCHANT')) {
2178
- return 'MERCHANT';
2179
- }
2180
- if (hasRole(user.roles, 'ROLE_CASHIER')) {
2181
- return 'CASHIER';
2414
+ getDefaultAuthUrl(environment) {
2415
+ switch (environment) {
2416
+ case 'production':
2417
+ return 'https://common.api.acubeapi.com';
2418
+ case 'development':
2419
+ case 'sandbox':
2420
+ default:
2421
+ return 'https://common-sandbox.api.acubeapi.com';
2182
2422
  }
2183
- return null;
2184
2423
  }
2185
- isReceiptEndpoint(url) {
2186
- return url.includes('/receipts') || url.includes('/mf1/receipts');
2187
- }
2188
- isReturnableItemsEndpoint(url) {
2189
- return !!(url.match(/\/receipts\/[a-f0-9-]+\/returnable-items$/) ||
2190
- url.match(/\/mf1\/receipts\/[a-f0-9-]+\/returnable-items$/));
2191
- }
2192
- isDetailedReceiptEndpoint(url) {
2193
- return !!(url.match(/\/receipts\/[a-f0-9-]+\/details$/) ||
2194
- url.match(/\/mf1\/receipts\/[a-f0-9-]+\/details$/));
2424
+ getConfig() {
2425
+ return {
2426
+ environment: this.config.environment,
2427
+ debug: this.config.debug,
2428
+ };
2195
2429
  }
2196
- isNotificationEndpoint(url) {
2197
- return url.includes('/mf1/notifications');
2430
+ getApiUrl() {
2431
+ return this.config.apiUrl;
2198
2432
  }
2199
- isTelemetryEndpoint(url) {
2200
- return !!url.match(/\/mf1\/pems\/[^/]+\/telemetry/);
2433
+ getAuthUrl() {
2434
+ return this.config.authUrl;
2201
2435
  }
2202
- }
2203
-
2204
- class JwtAuthHandler {
2205
- constructor(tokenStorage) {
2206
- this.tokenStorage = tokenStorage;
2436
+ getEnvironment() {
2437
+ return this.config.environment;
2207
2438
  }
2208
- async getAuthConfig(_url, _method) {
2209
- return { mode: 'jwt', usePort444: false };
2439
+ isDebugEnabled() {
2440
+ return this.config.debug;
2210
2441
  }
2211
- async getAuthHeaders() {
2212
- const token = await this.tokenStorage.getAccessToken();
2213
- if (!token) {
2214
- return {};
2215
- }
2216
- return { Authorization: `Bearer ${token}` };
2442
+ getTimeout() {
2443
+ return this.config.timeout;
2217
2444
  }
2218
- }
2219
-
2220
- function clearObject(input) {
2221
- if (input === null || input === undefined || input === '') {
2222
- return undefined;
2445
+ getRetryAttempts() {
2446
+ return this.config.retryAttempts;
2223
2447
  }
2224
- if (Array.isArray(input)) {
2225
- const cleanedArray = input
2226
- .map((item) => clearObject(item))
2227
- .filter((item) => item !== undefined);
2228
- return cleanedArray;
2448
+ getCustomHeaders() {
2449
+ return { ...this.config.customHeaders };
2229
2450
  }
2230
- if (typeof input === 'object' && input.constructor === Object) {
2231
- const cleaned = {};
2232
- for (const [key, value] of Object.entries(input)) {
2233
- const cleanedValue = clearObject(value);
2234
- if (cleanedValue !== undefined) {
2235
- cleaned[key] = cleanedValue;
2236
- }
2451
+ updateConfig(updates) {
2452
+ if (updates.environment) {
2453
+ this.config.environment = updates.environment;
2454
+ this.config.apiUrl = this.getDefaultApiUrl(updates.environment);
2455
+ this.config.authUrl = this.getDefaultAuthUrl(updates.environment);
2237
2456
  }
2238
- return cleaned;
2239
- }
2240
- return input;
2241
- }
2242
- function clearObjectShallow(obj) {
2243
- if (!obj || typeof obj !== 'object') {
2244
- return {};
2245
- }
2246
- const cleaned = {};
2247
- for (const [key, value] of Object.entries(obj)) {
2248
- if (value !== null && value !== undefined && value !== '') {
2249
- cleaned[key] = value;
2457
+ if (updates.debug !== undefined) {
2458
+ this.config.debug = updates.debug;
2250
2459
  }
2251
2460
  }
2252
- return cleaned;
2253
- }
2254
- function isEmpty(value) {
2255
- return value === null || value === undefined || value === '';
2256
- }
2257
- function hasNonEmptyValues(obj) {
2258
- if (!obj || typeof obj !== 'object') {
2259
- return false;
2260
- }
2261
- return Object.values(obj).some((value) => !isEmpty(value));
2262
2461
  }
2263
2462
 
2264
- /**
2265
- * Platform detection utilities
2266
- */
2267
- /**
2268
- * Detect the current platform
2269
- */
2270
- function detectPlatform() {
2271
- // Check for React Native
2272
- if (typeof global !== 'undefined' &&
2273
- global.__DEV__ !== undefined &&
2274
- typeof global.navigator !== 'undefined' &&
2275
- global.navigator.product === 'ReactNative') {
2276
- return {
2277
- platform: 'react-native',
2278
- isReactNative: true,
2279
- isWeb: false,
2280
- isNode: false,
2281
- isExpo: checkExpo(),
2282
- };
2283
- }
2284
- // Check for Web/Browser
2285
- if (typeof window !== 'undefined' &&
2286
- typeof window.document !== 'undefined' &&
2287
- typeof window.navigator !== 'undefined') {
2288
- return {
2289
- platform: 'web',
2290
- isReactNative: false,
2291
- isWeb: true,
2292
- isNode: false,
2293
- isExpo: false,
2294
- };
2295
- }
2296
- // Check for Node.js
2297
- if (typeof process !== 'undefined' && process.versions && process.versions.node) {
2298
- return {
2299
- platform: 'node',
2300
- isReactNative: false,
2301
- isWeb: false,
2302
- isNode: true,
2303
- isExpo: false,
2304
- };
2305
- }
2306
- // Unknown platform
2307
- return {
2308
- platform: 'unknown',
2309
- isReactNative: false,
2310
- isWeb: false,
2311
- isNode: false,
2312
- isExpo: false,
2313
- };
2314
- }
2315
- /**
2316
- * Check if running in Expo
2317
- */
2318
- function checkExpo() {
2319
- try {
2320
- return (typeof global !== 'undefined' &&
2321
- (typeof global.Expo !== 'undefined' || typeof global.expo !== 'undefined'));
2463
+ // Enum options arrays
2464
+ const VAT_RATE_CODE_OPTIONS = [
2465
+ '4.00',
2466
+ '5.00',
2467
+ '10.00',
2468
+ '22.00',
2469
+ '2.00',
2470
+ '6.40',
2471
+ '7.00',
2472
+ '7.30',
2473
+ '7.50',
2474
+ '7.65',
2475
+ '7.95',
2476
+ '8.30',
2477
+ '8.50',
2478
+ '8.80',
2479
+ '9.50',
2480
+ '12.30',
2481
+ 'N1',
2482
+ 'N2',
2483
+ 'N3',
2484
+ 'N4',
2485
+ 'N5',
2486
+ 'N6',
2487
+ ];
2488
+ const GOOD_OR_SERVICE_OPTIONS = ['goods', 'service'];
2489
+ const RECEIPT_PROOF_TYPE_OPTIONS = ['POS', 'VR', 'ND'];
2490
+ // Enum types for receipt validation
2491
+ const VatRateCodeSchema = z__namespace.enum(VAT_RATE_CODE_OPTIONS);
2492
+ const GoodOrServiceSchema = z__namespace.enum(GOOD_OR_SERVICE_OPTIONS);
2493
+ const ReceiptProofTypeSchema = z__namespace.enum(RECEIPT_PROOF_TYPE_OPTIONS);
2494
+ // Receipt Item Schema
2495
+ const ReceiptItemSchema = z__namespace.object({
2496
+ type: GoodOrServiceSchema.optional(),
2497
+ quantity: z__namespace.string().min(1, { error: 'fieldIsRequired' }),
2498
+ description: z__namespace.string().min(1, { error: 'fieldIsRequired' }),
2499
+ unit_price: z__namespace.string().min(1, { error: 'fieldIsRequired' }),
2500
+ vat_rate_code: VatRateCodeSchema.optional(),
2501
+ simplified_vat_allocation: z__namespace.boolean().optional(),
2502
+ discount: z__namespace.string().nullable().optional(),
2503
+ is_down_payment_or_voucher_redemption: z__namespace.boolean().optional(),
2504
+ complimentary: z__namespace.boolean().optional(),
2505
+ });
2506
+ // Main Receipt Input Schema
2507
+ const ReceiptInputSchema = z__namespace
2508
+ .object({
2509
+ items: z__namespace.array(ReceiptItemSchema).min(1, { error: 'arrayMin1' }),
2510
+ customer_tax_code: z__namespace.string().optional(),
2511
+ customer_lottery_code: z__namespace.string().optional(),
2512
+ discount: z__namespace.string().nullable().optional(),
2513
+ invoice_issuing: z__namespace.boolean().optional(),
2514
+ uncollected_dcr_to_ssn: z__namespace.boolean().optional(),
2515
+ services_uncollected_amount: z__namespace.string().nullable().optional(),
2516
+ goods_uncollected_amount: z__namespace.string().nullable().optional(),
2517
+ cash_payment_amount: z__namespace.string().nullable().optional(),
2518
+ electronic_payment_amount: z__namespace.string().nullable().optional(),
2519
+ ticket_restaurant_payment_amount: z__namespace.string().nullable().optional(),
2520
+ ticket_restaurant_quantity: z__namespace.number().optional(),
2521
+ })
2522
+ .refine((data) => {
2523
+ // At least one payment method should be provided
2524
+ const hasCashPayment = data.cash_payment_amount && parseFloat(data.cash_payment_amount) > 0;
2525
+ const hasElectronicPayment = data.electronic_payment_amount && parseFloat(data.electronic_payment_amount) > 0;
2526
+ const hasTicketPayment = data.ticket_restaurant_payment_amount &&
2527
+ parseFloat(data.ticket_restaurant_payment_amount) > 0;
2528
+ return hasCashPayment || hasElectronicPayment || hasTicketPayment;
2529
+ }, {
2530
+ error: 'At least one payment method is required',
2531
+ path: ['payment_methods'],
2532
+ })
2533
+ .refine((data) => {
2534
+ // only one between customer_tax_code and customer_lottery_code can be provided
2535
+ return !data.customer_tax_code || !data.customer_lottery_code;
2536
+ }, {
2537
+ error: 'Only one between customer_tax_code and customer_lottery_code can be provided',
2538
+ path: ['customer_tax_code', 'customer_lottery_code'],
2539
+ });
2540
+ // Receipt Return or Void via PEM Schema
2541
+ const ReceiptReturnOrVoidViaPEMInputSchema = z__namespace.object({
2542
+ device_id: z__namespace.string().optional(),
2543
+ items: z__namespace.array(ReceiptItemSchema).min(1, { error: 'arrayMin1' }),
2544
+ document_number: z__namespace.string().min(1, { error: 'fieldIsRequired' }),
2545
+ document_datetime: z__namespace.string().optional(),
2546
+ lottery_code: z__namespace.string().optional(),
2547
+ });
2548
+ // Receipt Return or Void with Proof Schema
2549
+ const ReceiptReturnOrVoidWithProofInputSchema = z__namespace.object({
2550
+ items: z__namespace.array(ReceiptItemSchema).min(1, { error: 'arrayMin1' }),
2551
+ proof: ReceiptProofTypeSchema,
2552
+ document_datetime: z__namespace.string().min(1, { error: 'fieldIsRequired' }),
2553
+ });
2554
+ // Void Receipt Schema
2555
+ const VoidReceiptInputSchema = z__namespace.object({
2556
+ document_number: z__namespace.string().min(1, { error: 'fieldIsRequired' }),
2557
+ });
2558
+ const ReceiptReturnItemSchema = z__namespace
2559
+ .array(z__namespace.object({
2560
+ id: z__namespace.number(),
2561
+ quantity: z__namespace.string().min(1, { error: 'fieldIsRequired' }),
2562
+ }))
2563
+ .min(1, { error: 'arrayMin1' });
2564
+ // Receipt Return Schema
2565
+ const ReceiptReturnInputSchema = z__namespace.object({
2566
+ items: z__namespace.array(ReceiptReturnItemSchema).min(1, { error: 'arrayMin1' }),
2567
+ document_number: z__namespace.string().min(1, { error: 'fieldIsRequired' }),
2568
+ });
2569
+
2570
+ // Cashier Create Input Schema (MF1)
2571
+ const CashierCreateInputSchema = z__namespace.object({
2572
+ email: z__namespace
2573
+ .string()
2574
+ .min(1, { error: 'fieldIsRequired' })
2575
+ .max(255, { error: 'emailMaxLength' })
2576
+ .email({ error: 'invalidEmail' }),
2577
+ password: z__namespace
2578
+ .string()
2579
+ .min(8, { error: 'passwordMinLength' })
2580
+ .max(40, { error: 'passwordMaxLength' }),
2581
+ name: z__namespace.string().min(1, { error: 'fieldIsRequired' }).max(255, { error: 'nameMaxLength' }),
2582
+ display_name: z__namespace
2583
+ .string()
2584
+ .min(1, { error: 'fieldIsRequired' })
2585
+ .max(255, { error: 'displayNameMaxLength' }),
2586
+ });
2587
+
2588
+ // Enum options arrays
2589
+ const PEM_STATUS_OPTIONS = [
2590
+ 'NEW',
2591
+ 'REGISTERED',
2592
+ 'ACTIVATED',
2593
+ 'ONLINE',
2594
+ 'OFFLINE',
2595
+ 'DISCARDED',
2596
+ ];
2597
+ // Address Schema (reusable)
2598
+ const AddressSchema = z__namespace.object({
2599
+ street_address: z__namespace.string().min(1, { error: 'fieldIsRequired' }),
2600
+ street_number: z__namespace.string().min(1, { error: 'fieldIsRequired' }),
2601
+ zip_code: z__namespace
2602
+ .string()
2603
+ .min(1, { error: 'fieldIsRequired' })
2604
+ .regex(/^\d{5}$/, { error: 'invalidZipCode' }),
2605
+ city: z__namespace.string().min(1, { error: 'fieldIsRequired' }),
2606
+ province: z__namespace
2607
+ .string()
2608
+ .min(2, { error: 'provinceMinLength' })
2609
+ .max(2, { error: 'provinceMaxLength' })
2610
+ .toUpperCase(),
2611
+ });
2612
+ // PEM Status Schema
2613
+ const PEMStatusSchema = z__namespace.enum(PEM_STATUS_OPTIONS);
2614
+ // Activation Request Schema
2615
+ const ActivationRequestSchema = z__namespace.object({
2616
+ registration_key: z__namespace.string().min(1, { error: 'fieldIsRequired' }),
2617
+ });
2618
+ // PEM Status Offline Request Schema
2619
+ const PEMStatusOfflineRequestSchema = z__namespace.object({
2620
+ timestamp: z__namespace
2621
+ .string()
2622
+ .min(1, { error: 'fieldIsRequired' })
2623
+ .refine((val) => !isNaN(Date.parse(val)), {
2624
+ error: 'invalidDateFormat',
2625
+ }),
2626
+ reason: z__namespace.string().min(1, { error: 'fieldIsRequired' }),
2627
+ });
2628
+
2629
+ // Cash Register Create Schema
2630
+ const CashRegisterCreateSchema = z__namespace.object({
2631
+ pem_serial_number: z__namespace.string().min(1, { error: 'fieldIsRequired' }),
2632
+ name: z__namespace.string().min(1, { error: 'fieldIsRequired' }).max(100, { error: 'nameMaxLength' }),
2633
+ });
2634
+
2635
+ // VAT number validation regex (Partita IVA - 11 digits)
2636
+ const VAT_NUMBER_REGEX = /^\d{11}$/;
2637
+ // Fiscal code validation regex (Codice Fiscale - 11 digits only for merchants)
2638
+ const FISCAL_CODE_REGEX = /^\d{11}$/;
2639
+ // Password validation regex (from OpenAPI spec)
2640
+ const PASSWORD_REGEX = /^((?=.*[A-Z])(?=.*[a-z])(?=.*[0-9])(?=.*[!@#$%^&*])(?=.{10,}).*)$/;
2641
+ // Merchant Create Input Schema
2642
+ const MerchantCreateInputSchema = z__namespace
2643
+ .object({
2644
+ vat_number: z__namespace
2645
+ .string()
2646
+ .min(1, { error: 'fieldIsRequired' })
2647
+ .regex(VAT_NUMBER_REGEX, { error: 'invalidVatNumber' }),
2648
+ fiscal_code: z__namespace.string().regex(FISCAL_CODE_REGEX, { error: 'invalidFiscalCode' }).optional(),
2649
+ business_name: z__namespace.string().max(200, { error: 'businessNameMaxLength' }).optional().nullable(),
2650
+ first_name: z__namespace.string().max(100, { error: 'firstNameMaxLength' }).optional().nullable(),
2651
+ last_name: z__namespace.string().max(100, { error: 'lastNameMaxLength' }).optional().nullable(),
2652
+ email: z__namespace.string().min(1, { error: 'fieldIsRequired' }).email({ error: 'invalidEmail' }),
2653
+ password: z__namespace
2654
+ .string()
2655
+ .min(1, { error: 'fieldIsRequired' })
2656
+ .regex(PASSWORD_REGEX, { error: 'passwordComplexity' }),
2657
+ address: AddressSchema.optional(),
2658
+ })
2659
+ .refine((data) => {
2660
+ const hasBusinessName = data.business_name && data.business_name.trim() !== '';
2661
+ const hasPersonalNames = (data.first_name && data.first_name.trim() !== '') ||
2662
+ (data.last_name && data.last_name.trim() !== '');
2663
+ // If business name is set, first/last name must not be provided
2664
+ if (hasBusinessName && hasPersonalNames) {
2665
+ return false;
2322
2666
  }
2323
- catch {
2667
+ // At least one naming method must be provided
2668
+ if (!hasBusinessName && !hasPersonalNames) {
2324
2669
  return false;
2325
2670
  }
2326
- }
2671
+ return true;
2672
+ }, {
2673
+ error: 'businessNameOrPersonalNamesRequired',
2674
+ path: ['business_name'],
2675
+ });
2676
+ // Merchant Update Input Schema
2677
+ const MerchantUpdateInputSchema = z__namespace.object({
2678
+ business_name: z__namespace.string().max(200, { error: 'businessNameMaxLength' }).optional().nullable(),
2679
+ first_name: z__namespace.string().max(100, { error: 'firstNameMaxLength' }).optional().nullable(),
2680
+ last_name: z__namespace.string().max(100, { error: 'lastNameMaxLength' }).optional().nullable(),
2681
+ address: AddressSchema.optional().nullable(),
2682
+ });
2683
+
2684
+ // Enum options arrays
2685
+ const PEM_TYPE_OPTIONS = ['AP', 'SP', 'TM', 'PV'];
2686
+ // PEM Data Schema
2687
+ const PemDataSchema = z__namespace.object({
2688
+ version: z__namespace.string().min(1, { error: 'fieldIsRequired' }),
2689
+ type: z__namespace.enum(PEM_TYPE_OPTIONS, {
2690
+ error: 'invalidPemType',
2691
+ }),
2692
+ });
2693
+ // PEM Create Input Schema
2694
+ const PemCreateInputSchema = z__namespace.object({
2695
+ merchant_uuid: z__namespace.string().min(1, { error: 'fieldIsRequired' }).uuid({ error: 'invalidUuid' }),
2696
+ address: AddressSchema.optional(),
2697
+ /* external_pem_data: PemDataSchema.optional(), */
2698
+ });
2699
+
2700
+ // Italian Fiscal ID validation regex (Codice Fiscale for individuals or Partita IVA for companies)
2701
+ const FISCAL_ID_REGEX = /^([A-Z]{6}[0-9LMNPQRSTUV]{2}[ABCDEHLMPRST][0-9LMNPQRSTUV]{2}[A-Z][0-9LMNPQRSTUV]{3}[A-Z]|[0-9]{11})$/;
2702
+ // Supplier Create Input Schema
2703
+ const SupplierCreateInputSchema = z__namespace.object({
2704
+ fiscal_id: z__namespace
2705
+ .string()
2706
+ .min(1, { error: 'fieldIsRequired' })
2707
+ .regex(FISCAL_ID_REGEX, { error: 'invalidFiscalId' })
2708
+ .toUpperCase(),
2709
+ name: z__namespace.string().min(1, { error: 'fieldIsRequired' }).max(200, { error: 'nameMaxLength' }),
2710
+ address: AddressSchema.optional(),
2711
+ });
2712
+ // Supplier Update Input Schema
2713
+ const SupplierUpdateInputSchema = z__namespace.object({
2714
+ name: z__namespace.string().min(1, { error: 'fieldIsRequired' }).max(200, { error: 'nameMaxLength' }),
2715
+ address: AddressSchema.optional(),
2716
+ });
2717
+
2718
+ // Journal Close Input Schema
2719
+ const JournalCloseInputSchema = z__namespace.object({
2720
+ closing_timestamp: z__namespace
2721
+ .string()
2722
+ .min(1, { error: 'fieldIsRequired' })
2723
+ .refine((val) => !isNaN(Date.parse(val)), {
2724
+ error: 'invalidDateFormat',
2725
+ }),
2726
+ reason: z__namespace.string().max(255, { error: 'reasonMaxLength' }).optional(),
2727
+ });
2728
+
2729
+ // Daily Report Status Options
2730
+ const DAILY_REPORT_STATUS_OPTIONS = ['pending', 'sent', 'error'];
2731
+ // Daily Report Status Schema
2732
+ const DailyReportStatusSchema = z__namespace.enum(DAILY_REPORT_STATUS_OPTIONS, {
2733
+ error: 'invalidDailyReportStatus',
2734
+ });
2735
+ // Daily Reports List Parameters Schema
2736
+ const DailyReportsParamsSchema = z__namespace.object({
2737
+ pem_serial_number: z__namespace.string().min(1, { error: 'fieldIsRequired' }).optional(),
2738
+ date_from: z__namespace
2739
+ .string()
2740
+ .refine((val) => !isNaN(Date.parse(val)), {
2741
+ error: 'invalidDateFormat',
2742
+ })
2743
+ .optional(),
2744
+ date_to: z__namespace
2745
+ .string()
2746
+ .refine((val) => !isNaN(Date.parse(val)), {
2747
+ error: 'invalidDateFormat',
2748
+ })
2749
+ .optional(),
2750
+ status: DailyReportStatusSchema.optional(),
2751
+ page: z__namespace.number().min(1, { error: 'pageMinValue' }).optional(),
2752
+ });
2753
+
2754
+ const NotificationScopeSchema = z__namespace.object({
2755
+ type: z__namespace.literal('global'),
2756
+ });
2757
+ const PemStatusSchema = z__namespace.enum(['ONLINE', 'OFFLINE']);
2758
+ const NotificationDataBlockAtSchema = z__namespace.object({
2759
+ block_at: z__namespace.string(),
2760
+ });
2761
+ const NotificationDataPemStatusSchema = z__namespace.object({
2762
+ from: PemStatusSchema,
2763
+ to: PemStatusSchema,
2764
+ });
2765
+ const NotificationBaseSchema = z__namespace.object({
2766
+ uuid: z__namespace.string().uuid({ error: 'invalidUuid' }),
2767
+ scope: NotificationScopeSchema,
2768
+ source: z__namespace.enum(['system', 'Italian Tax Authority']),
2769
+ level: z__namespace.enum(['info', 'warning', 'error', 'critical']),
2770
+ created_at: z__namespace.string(),
2771
+ });
2772
+ const NotificationMf2UnreachableSchema = NotificationBaseSchema.extend({
2773
+ type: z__namespace.literal('INTERNAL_COMMUNICATION_FAILURE'),
2774
+ code: z__namespace.literal('SYS-W-01'),
2775
+ data: NotificationDataBlockAtSchema,
2776
+ });
2777
+ const NotificationPemsBlockedSchema = NotificationBaseSchema.extend({
2778
+ type: z__namespace.literal('PEM_STATUS_CHANGED'),
2779
+ code: z__namespace.literal('SYS-C-01'),
2780
+ data: NotificationDataPemStatusSchema,
2781
+ });
2782
+ const NotificationPemBackOnlineSchema = NotificationBaseSchema.extend({
2783
+ type: z__namespace.literal('PEM_STATUS_CHANGED'),
2784
+ code: z__namespace.literal('SYS-I-01'),
2785
+ data: NotificationDataPemStatusSchema,
2786
+ });
2787
+ const NotificationSchema = z__namespace.discriminatedUnion('code', [
2788
+ NotificationMf2UnreachableSchema,
2789
+ NotificationPemsBlockedSchema,
2790
+ NotificationPemBackOnlineSchema,
2791
+ ]);
2792
+ const NotificationListResponseSchema = z__namespace.object({
2793
+ members: z__namespace.array(NotificationSchema),
2794
+ });
2795
+
2796
+ const TelemetryMerchantSchema = z__namespace.object({
2797
+ vat_number: z__namespace.string(),
2798
+ fiscal_code: z__namespace.string().nullable(),
2799
+ business_name: z__namespace.string(),
2800
+ });
2801
+ const TelemetrySupplierSchema = z__namespace.object({
2802
+ vat_number: z__namespace.string(),
2803
+ fiscal_code: z__namespace.string().nullable(),
2804
+ business_name: z__namespace.string(),
2805
+ });
2806
+ const TelemetrySoftwareVersionSchema = z__namespace.object({
2807
+ version: z__namespace.string(),
2808
+ swid: z__namespace.string(),
2809
+ installed_at: z__namespace.string(),
2810
+ status: z__namespace.enum(['active', 'inactive', 'archived']),
2811
+ });
2812
+ const TelemetrySoftwareSchema = z__namespace.object({
2813
+ code: z__namespace.string(),
2814
+ name: z__namespace.string(),
2815
+ approval_reference: z__namespace.string(),
2816
+ version_info: TelemetrySoftwareVersionSchema,
2817
+ });
2818
+ const PendingReceiptsSchema = z__namespace.object({
2819
+ count: z__namespace.number().int().nonnegative(),
2820
+ total_amount: z__namespace.string(),
2821
+ });
2822
+ const TransmissionSchema = z__namespace.object({
2823
+ attempted_at: z__namespace.string(),
2824
+ outcome: z__namespace.enum(['success', 'failed', 'pending']),
2825
+ });
2826
+ const MessageSchema = z__namespace.object({
2827
+ received_at: z__namespace.string(),
2828
+ content: z__namespace.string(),
2829
+ });
2830
+ const LotterySecretRequestSchema = z__namespace.object({
2831
+ requested_at: z__namespace.string(),
2832
+ outcome: z__namespace.enum(['success', 'failed', 'pending']),
2833
+ });
2834
+ const LotterySchema = z__namespace.object({
2835
+ last_transmission: TransmissionSchema,
2836
+ secret_request: LotterySecretRequestSchema,
2837
+ });
2838
+ const TelemetrySchema = z__namespace.object({
2839
+ pem_id: z__namespace.string(),
2840
+ pem_status: z__namespace.enum(['ONLINE', 'OFFLINE', 'ERROR']),
2841
+ pem_status_changed_at: z__namespace.string(),
2842
+ merchant: TelemetryMerchantSchema,
2843
+ supplier: TelemetrySupplierSchema,
2844
+ software: TelemetrySoftwareSchema,
2845
+ last_communication_at: z__namespace.string(),
2846
+ pending_receipts: PendingReceiptsSchema,
2847
+ last_receipt_transmission: TransmissionSchema,
2848
+ last_message_from_mf2: MessageSchema,
2849
+ ade_corrispettivi_transmission: TransmissionSchema,
2850
+ last_message_from_ade: MessageSchema,
2851
+ lottery: LotterySchema,
2852
+ });
2853
+
2854
+ // Receipt schemas and types
2855
+ // Common validation utilities
2856
+ const ValidationMessages = {
2857
+ fieldIsRequired: 'This field is required',
2858
+ arrayMin1: 'At least one item is required',
2859
+ paymentMethodRequired: 'At least one payment method is required',
2860
+ invalidEmail: 'Please enter a valid email address',
2861
+ passwordMinLength: 'Password must be at least 8 characters long',
2862
+ passwordComplexity: 'Password must contain at least one uppercase letter, one lowercase letter, one number, and one special character',
2863
+ invalidZipCode: 'Please enter a valid 5-digit zip code',
2864
+ provinceMinLength: 'Province code must be 2 characters',
2865
+ provinceMaxLength: 'Province code must be 2 characters',
2866
+ invalidDateFormat: 'Please enter a valid date',
2867
+ nameMaxLength: 'Name is too long',
2868
+ invalidFiscalId: 'Please enter a valid Italian fiscal ID (Codice Fiscale or Partita IVA)',
2869
+ invalidVatNumber: 'Please enter a valid VAT number (11 digits)',
2870
+ invalidFiscalCode: 'Please enter a valid fiscal code (11 digits)',
2871
+ businessNameMaxLength: 'Business name is too long (max 200 characters)',
2872
+ businessNameOrPersonalNamesRequired: 'Please provide either a business name or first/last name, but not both',
2873
+ firstNameMaxLength: 'First name is too long (max 100 characters)',
2874
+ lastNameMaxLength: 'Last name is too long (max 100 characters)',
2875
+ invalidUuid: 'Please enter a valid UUID',
2876
+ invalidPemType: 'PEM type must be one of: AP, SP, TM, PV',
2877
+ reasonMaxLength: 'Reason is too long (max 255 characters)',
2878
+ pageMinValue: 'Page number must be at least 1',
2879
+ invalidDailyReportStatus: 'Daily report status must be one of: pending, sent, error',
2880
+ displayNameMaxLength: 'Display name is too long (max 255 characters)',
2881
+ };
2882
+ // Validation helper functions
2883
+ const validateInput = (schema, data) => {
2884
+ const result = schema.safeParse(data);
2885
+ if (!result.success) {
2886
+ const errors = result.error.issues.map((error) => ({
2887
+ field: error.path.join('.'),
2888
+ message: error.message,
2889
+ code: error.code,
2890
+ }));
2891
+ return {
2892
+ success: false,
2893
+ errors,
2894
+ data: null,
2895
+ };
2896
+ }
2897
+ return {
2898
+ success: true,
2899
+ errors: [],
2900
+ data: result.data,
2901
+ };
2902
+ };
2327
2903
 
2328
- function getDefaultExportFromCjs (x) {
2329
- return x && x.__esModule && Object.prototype.hasOwnProperty.call(x, 'default') ? x['default'] : x;
2904
+ class ACubeSDKError extends Error {
2905
+ constructor(type, message, originalError, statusCode, violations) {
2906
+ super(message);
2907
+ this.type = type;
2908
+ this.originalError = originalError;
2909
+ this.statusCode = statusCode;
2910
+ this.name = 'ACubeSDKError';
2911
+ this.violations = violations;
2912
+ }
2330
2913
  }
2331
2914
 
2332
- var picocolors_browser = {exports: {}};
2333
-
2334
- var x=String;
2335
- var create=function() {return {isColorSupported:false,reset:x,bold:x,dim:x,italic:x,underline:x,inverse:x,hidden:x,strikethrough:x,black:x,red:x,green:x,yellow:x,blue:x,magenta:x,cyan:x,white:x,gray:x,bgBlack:x,bgRed:x,bgGreen:x,bgYellow:x,bgBlue:x,bgMagenta:x,bgCyan:x,bgWhite:x,blackBright:x,redBright:x,greenBright:x,yellowBright:x,blueBright:x,magentaBright:x,cyanBright:x,whiteBright:x,bgBlackBright:x,bgRedBright:x,bgGreenBright:x,bgYellowBright:x,bgBlueBright:x,bgMagentaBright:x,bgCyanBright:x,bgWhiteBright:x}};
2336
- picocolors_browser.exports=create();
2337
- picocolors_browser.exports.createColors = create;
2338
-
2339
- var picocolors_browserExports = picocolors_browser.exports;
2340
- var pc = /*@__PURE__*/getDefaultExportFromCjs(picocolors_browserExports);
2341
-
2342
- const levelColors = {
2343
- debug: {
2344
- prefix: pc.gray,
2345
- message: pc.gray,
2346
- data: pc.dim,
2347
- },
2348
- info: {
2349
- prefix: pc.cyan,
2350
- message: pc.white,
2351
- data: pc.dim,
2352
- },
2353
- warn: {
2354
- prefix: pc.yellow,
2355
- message: pc.yellow,
2356
- data: pc.dim,
2357
- },
2358
- error: {
2359
- prefix: pc.red,
2360
- message: pc.red,
2361
- data: pc.dim,
2362
- },
2363
- };
2364
- const levelIcons = {
2365
- debug: '🔍',
2366
- info: 'ℹ️ ',
2367
- warn: '⚠️ ',
2368
- error: '❌',
2369
- };
2370
- /**
2371
- * Format data for pretty display in logs
2372
- */
2373
- function formatData(data, level) {
2374
- if (data === undefined || data === null) {
2375
- return String(data);
2915
+ const log$f = createPrefixedLogger('AUTH-STRATEGY');
2916
+ class AuthStrategy {
2917
+ constructor(jwtHandler, mtlsHandler, userProvider, mtlsAdapter) {
2918
+ this.jwtHandler = jwtHandler;
2919
+ this.mtlsHandler = mtlsHandler;
2920
+ this.userProvider = userProvider;
2921
+ this.mtlsAdapter = mtlsAdapter;
2376
2922
  }
2377
- // For primitive types, just return as string
2378
- if (typeof data !== 'object') {
2379
- return String(data);
2923
+ async determineAuthConfig(url, method, explicitMode) {
2924
+ if (this.isNotificationEndpoint(url) || this.isTelemetryEndpoint(url)) {
2925
+ return { mode: 'mtls', usePort444: true };
2926
+ }
2927
+ const platform = this.detectPlatform();
2928
+ const userRole = await this.getUserRole();
2929
+ const isReceiptEndpoint = this.isReceiptEndpoint(url);
2930
+ log$f.debug('Determining auth config', {
2931
+ url,
2932
+ method,
2933
+ platform,
2934
+ userRole,
2935
+ isReceiptEndpoint,
2936
+ explicitMode,
2937
+ });
2938
+ if (userRole === 'SUPPLIER') {
2939
+ return { mode: 'jwt', usePort444: false };
2940
+ }
2941
+ if (userRole === 'CASHIER') {
2942
+ if (!isReceiptEndpoint) {
2943
+ return { mode: 'jwt', usePort444: false };
2944
+ }
2945
+ if (platform === 'mobile') {
2946
+ return { mode: 'mtls', usePort444: true };
2947
+ }
2948
+ return { mode: 'jwt', usePort444: true };
2949
+ }
2950
+ if (userRole === 'MERCHANT') {
2951
+ if (!isReceiptEndpoint) {
2952
+ return { mode: 'jwt', usePort444: false };
2953
+ }
2954
+ if (this.isReturnableItemsEndpoint(url)) {
2955
+ return { mode: 'mtls', usePort444: true };
2956
+ }
2957
+ if (method === 'GET') {
2958
+ if (this.isDetailedReceiptEndpoint(url)) {
2959
+ if (platform === 'mobile') {
2960
+ return { mode: 'mtls', usePort444: true };
2961
+ }
2962
+ return { mode: 'jwt', usePort444: true };
2963
+ }
2964
+ return { mode: 'jwt', usePort444: false };
2965
+ }
2966
+ if (['POST', 'PUT', 'PATCH', 'DELETE'].includes(method)) {
2967
+ if (platform === 'mobile') {
2968
+ return { mode: 'mtls', usePort444: true };
2969
+ }
2970
+ return { mode: 'jwt', usePort444: true };
2971
+ }
2972
+ return { mode: 'jwt', usePort444: false };
2973
+ }
2974
+ if (explicitMode) {
2975
+ if (userRole === 'SUPPLIER' && explicitMode === 'mtls') {
2976
+ return { mode: 'jwt', usePort444: false };
2977
+ }
2978
+ return {
2979
+ mode: explicitMode,
2980
+ usePort444: explicitMode === 'mtls' || (platform === 'web' && isReceiptEndpoint),
2981
+ };
2982
+ }
2983
+ if (platform === 'web') {
2984
+ return { mode: 'jwt', usePort444: isReceiptEndpoint };
2985
+ }
2986
+ if (isReceiptEndpoint && platform === 'mobile') {
2987
+ return { mode: 'mtls', usePort444: true };
2988
+ }
2989
+ return { mode: 'jwt', usePort444: false };
2380
2990
  }
2381
- // For Error objects, format nicely
2382
- if (data instanceof Error) {
2383
- return `${data.name}: ${data.message}${data.stack ? `\n${pc.dim(data.stack)}` : ''}`;
2991
+ async getAuthHeaders() {
2992
+ return this.jwtHandler.getAuthHeaders();
2384
2993
  }
2385
- try {
2386
- // Apply level-specific coloring
2387
- const colors = levelColors[level];
2388
- return colors.data(JSON.stringify(data, null, 2));
2994
+ getMtlsHandler() {
2995
+ return this.mtlsHandler;
2389
2996
  }
2390
- catch {
2391
- // Fallback to JSON.stringify if pretty-format fails
2392
- try {
2393
- return JSON.stringify(data, null, 2);
2997
+ getJwtHandler() {
2998
+ return this.jwtHandler;
2999
+ }
3000
+ detectPlatform() {
3001
+ if (!this.mtlsAdapter) {
3002
+ return 'web';
2394
3003
  }
2395
- catch {
2396
- return String(data);
3004
+ const platformInfo = this.mtlsAdapter.getPlatformInfo();
3005
+ return platformInfo.platform === 'web' ? 'web' : 'mobile';
3006
+ }
3007
+ async getUserRole() {
3008
+ if (!this.userProvider) {
3009
+ return null;
3010
+ }
3011
+ const user = await this.userProvider.getCurrentUser();
3012
+ if (!user || !user.roles) {
3013
+ return null;
3014
+ }
3015
+ if (hasRole(user.roles, 'ROLE_SUPPLIER')) {
3016
+ return 'SUPPLIER';
3017
+ }
3018
+ if (hasRole(user.roles, 'ROLE_MERCHANT')) {
3019
+ return 'MERCHANT';
2397
3020
  }
3021
+ if (hasRole(user.roles, 'ROLE_CASHIER')) {
3022
+ return 'CASHIER';
3023
+ }
3024
+ return null;
2398
3025
  }
2399
- }
2400
- class Logger {
2401
- constructor() {
2402
- this.enabled = false;
3026
+ isReceiptEndpoint(url) {
3027
+ return url.includes('/receipts') || url.includes('/mf1/receipts');
2403
3028
  }
2404
- setEnabled(enabled) {
2405
- this.enabled = enabled;
3029
+ isReturnableItemsEndpoint(url) {
3030
+ return !!(url.match(/\/receipts\/[a-f0-9-]+\/returnable-items$/) ||
3031
+ url.match(/\/mf1\/receipts\/[a-f0-9-]+\/returnable-items$/));
2406
3032
  }
2407
- isEnabled() {
2408
- return this.enabled;
3033
+ isDetailedReceiptEndpoint(url) {
3034
+ return !!(url.match(/\/receipts\/[a-f0-9-]+\/details$/) ||
3035
+ url.match(/\/mf1\/receipts\/[a-f0-9-]+\/details$/));
2409
3036
  }
2410
- debug(prefix, message, data) {
2411
- if (!this.enabled)
2412
- return;
2413
- this.log('debug', prefix, message, data);
3037
+ isNotificationEndpoint(url) {
3038
+ return url.includes('/mf1/notifications');
2414
3039
  }
2415
- info(prefix, message, data) {
2416
- if (!this.enabled)
2417
- return;
2418
- this.log('info', prefix, message, data);
3040
+ isTelemetryEndpoint(url) {
3041
+ return !!url.match(/\/mf1\/pems\/[^/]+\/telemetry/);
2419
3042
  }
2420
- warn(prefix, message, data) {
2421
- this.log('warn', prefix, message, data);
3043
+ }
3044
+
3045
+ class JwtAuthHandler {
3046
+ constructor(tokenStorage) {
3047
+ this.tokenStorage = tokenStorage;
2422
3048
  }
2423
- error(prefix, message, data) {
2424
- this.log('error', prefix, message, data);
3049
+ async getAuthConfig(_url, _method) {
3050
+ return { mode: 'jwt', usePort444: false };
2425
3051
  }
2426
- log(level, prefix, message, data) {
2427
- const colors = levelColors[level];
2428
- const icon = levelIcons[level];
2429
- const isoTime = new Date().toISOString().split('T')[1] ?? '';
2430
- const timestamp = pc.dim(isoTime.slice(0, 12));
2431
- const formattedPrefix = colors.prefix(`[${prefix}]`);
2432
- const formattedMessage = colors.message(message);
2433
- const consoleMethod = level === 'debug'
2434
- ? console.debug
2435
- : level === 'info'
2436
- ? console.info
2437
- : level === 'warn'
2438
- ? console.warn
2439
- : console.error;
2440
- const header = `${timestamp} ${icon} ${formattedPrefix} ${formattedMessage}`;
2441
- if (data !== undefined) {
2442
- const formattedData = formatData(data, level);
2443
- // Check if data is an object (multi-line) or primitive (single-line)
2444
- const isMultiLine = typeof data === 'object' && data !== null;
2445
- if (isMultiLine) {
2446
- consoleMethod(`${header}\n${formattedData}`);
2447
- }
2448
- else {
2449
- consoleMethod(`${header}`, formattedData);
2450
- }
2451
- }
2452
- else {
2453
- consoleMethod(header);
3052
+ async getAuthHeaders() {
3053
+ const token = await this.tokenStorage.getAccessToken();
3054
+ if (!token) {
3055
+ return {};
2454
3056
  }
3057
+ return { Authorization: `Bearer ${token}` };
2455
3058
  }
2456
3059
  }
2457
- const logger = new Logger();
2458
- function createPrefixedLogger(prefix) {
2459
- return {
2460
- debug: (message, data) => logger.debug(prefix, message, data),
2461
- info: (message, data) => logger.info(prefix, message, data),
2462
- warn: (message, data) => logger.warn(prefix, message, data),
2463
- error: (message, data) => logger.error(prefix, message, data),
2464
- };
2465
- }
2466
-
2467
- /**
2468
- * Formats a numeric string value to have exactly the specified number of decimal places.
2469
- * E.g., "1" → "1.00", "10" → "10.00", "1.5" → "1.50"
2470
- * Returns undefined for undefined input (preserves optional fields).
2471
- *
2472
- * @param value - The string value to format
2473
- * @param decimals - Number of decimal places (default: 2)
2474
- * @returns Formatted string or undefined if input is undefined
2475
- */
2476
- function formatDecimal(value, decimals = 2) {
2477
- if (value === undefined)
2478
- return undefined;
2479
- const num = parseFloat(value);
2480
- if (isNaN(num))
2481
- return value;
2482
- return num.toFixed(decimals);
2483
- }
2484
3060
 
2485
- const log$f = createPrefixedLogger('MTLS-HANDLER');
3061
+ const log$e = createPrefixedLogger('MTLS-HANDLER');
2486
3062
  class MtlsAuthHandler {
2487
3063
  constructor(mtlsAdapter, certificatePort) {
2488
3064
  this.mtlsAdapter = mtlsAdapter;
@@ -2524,7 +3100,7 @@ class MtlsAuthHandler {
2524
3100
  async makeRequest(url, config, jwtToken) {
2525
3101
  const requestKey = this.generateRequestKey(url, config, jwtToken);
2526
3102
  if (this.pendingRequests.has(requestKey)) {
2527
- log$f.debug('Deduplicating concurrent request:', url);
3103
+ log$e.debug('Deduplicating concurrent request:', url);
2528
3104
  return this.pendingRequests.get(requestKey);
2529
3105
  }
2530
3106
  const requestPromise = this.executeRequest(url, config, jwtToken, false);
@@ -2548,10 +3124,10 @@ class MtlsAuthHandler {
2548
3124
  };
2549
3125
  if (jwtToken) {
2550
3126
  headers['Authorization'] = `Bearer ${jwtToken}`;
2551
- log$f.debug('JWT token present:', jwtToken.substring(0, 20) + '...');
3127
+ log$e.debug('JWT token present:', jwtToken.substring(0, 20) + '...');
2552
3128
  }
2553
3129
  else {
2554
- log$f.warn('No JWT token provided for mTLS request');
3130
+ log$e.warn('No JWT token provided for mTLS request');
2555
3131
  }
2556
3132
  const fullUrl = this.constructMtlsUrl(url);
2557
3133
  const mtlsConfig = {
@@ -2562,25 +3138,25 @@ class MtlsAuthHandler {
2562
3138
  timeout: config.timeout,
2563
3139
  responseType: config.responseType,
2564
3140
  };
2565
- log$f.debug('header-mtls', headers);
2566
- log$f.debug(`${config.method} ${fullUrl}`);
3141
+ log$e.debug('header-mtls', headers);
3142
+ log$e.debug(`${config.method} ${fullUrl}`);
2567
3143
  if (config.data) {
2568
- log$f.debug('Request body:', config.data);
3144
+ log$e.debug('Request body:', config.data);
2569
3145
  }
2570
3146
  try {
2571
3147
  const response = await this.mtlsAdapter.request(mtlsConfig);
2572
- log$f.debug(`Response ${response.status} from ${fullUrl}`);
3148
+ log$e.debug(`Response ${response.status} from ${fullUrl}`);
2573
3149
  if (response.data) {
2574
- log$f.debug('Response body:', response.data);
3150
+ log$e.debug('Response body:', response.data);
2575
3151
  }
2576
3152
  return response.data;
2577
3153
  }
2578
3154
  catch (error) {
2579
- log$f.error(`Response error from ${fullUrl}:`, error);
3155
+ log$e.error(`Response error from ${fullUrl}:`, error);
2580
3156
  if (error && typeof error === 'object' && 'response' in error) {
2581
3157
  const axiosError = error;
2582
3158
  if (axiosError.response?.data) {
2583
- log$f.error('Response body:', axiosError.response.data);
3159
+ log$e.error('Response body:', axiosError.response.data);
2584
3160
  }
2585
3161
  }
2586
3162
  if (isRetryAttempt) {
@@ -2590,7 +3166,7 @@ class MtlsAuthHandler {
2590
3166
  if (!shouldRetry) {
2591
3167
  throw error;
2592
3168
  }
2593
- log$f.debug('Request failed, reconfiguring certificate and retrying...');
3169
+ log$e.debug('Request failed, reconfiguring certificate and retrying...');
2594
3170
  try {
2595
3171
  await this.configureCertificate(certificate);
2596
3172
  return await this.executeRequest(url, config, jwtToken, true);
@@ -3317,7 +3893,7 @@ function decompressData(data, compressed) {
3317
3893
  return new CompressionAdapter().decompress(data, compressed);
3318
3894
  }
3319
3895
 
3320
- const log$e = createPrefixedLogger('CACHE-RN');
3896
+ const log$d = createPrefixedLogger('CACHE-RN');
3321
3897
  /**
3322
3898
  * React Native cache adapter using SQLite (Expo or react-native-sqlite-storage)
3323
3899
  * Cache never expires - data persists until explicitly invalidated
@@ -3401,26 +3977,26 @@ class ReactNativeCacheAdapter {
3401
3977
  await this.runMigrations();
3402
3978
  }
3403
3979
  async runMigrations() {
3404
- log$e.debug('Running database migrations...');
3980
+ log$d.debug('Running database migrations...');
3405
3981
  try {
3406
3982
  // Check if compressed column exists
3407
3983
  this.hasCompressedColumn = await this.checkColumnExists('compressed');
3408
3984
  if (!this.hasCompressedColumn) {
3409
- log$e.debug('Adding compressed column to cache table');
3985
+ log$d.debug('Adding compressed column to cache table');
3410
3986
  const addColumnSQL = `ALTER TABLE ${ReactNativeCacheAdapter.TABLE_NAME} ADD COLUMN compressed INTEGER DEFAULT 0`;
3411
3987
  await this.executeSql(addColumnSQL);
3412
3988
  this.hasCompressedColumn = true;
3413
- log$e.debug('Successfully added compressed column');
3989
+ log$d.debug('Successfully added compressed column');
3414
3990
  }
3415
3991
  else {
3416
- log$e.debug('Compressed column already exists');
3992
+ log$d.debug('Compressed column already exists');
3417
3993
  }
3418
- log$e.debug('Database migrations completed', {
3994
+ log$d.debug('Database migrations completed', {
3419
3995
  hasCompressedColumn: this.hasCompressedColumn,
3420
3996
  });
3421
3997
  }
3422
3998
  catch (error) {
3423
- log$e.debug('Migration failed, disabling compression features', error);
3999
+ log$d.debug('Migration failed, disabling compression features', error);
3424
4000
  this.hasCompressedColumn = false;
3425
4001
  // Don't throw - allow the app to continue even if migration fails
3426
4002
  // The compressed feature will just be disabled
@@ -3431,20 +4007,20 @@ class ReactNativeCacheAdapter {
3431
4007
  const pragmaSQL = `PRAGMA table_info(${ReactNativeCacheAdapter.TABLE_NAME})`;
3432
4008
  const results = await this.executeSql(pragmaSQL);
3433
4009
  const columns = this.normalizeResults(results);
3434
- log$e.debug('Table columns found', { columns: columns.map((c) => c.name) });
4010
+ log$d.debug('Table columns found', { columns: columns.map((c) => c.name) });
3435
4011
  return columns.some((column) => column.name === columnName);
3436
4012
  }
3437
4013
  catch (error) {
3438
- log$e.debug('Error checking column existence', error);
4014
+ log$d.debug('Error checking column existence', error);
3439
4015
  return false;
3440
4016
  }
3441
4017
  }
3442
4018
  async get(key) {
3443
4019
  await this.ensureInitialized();
3444
4020
  const sql = `SELECT * FROM ${ReactNativeCacheAdapter.TABLE_NAME} WHERE cache_key = ?`;
3445
- log$e.debug('Executing get query', { sql, key });
4021
+ log$d.debug('Executing get query', { sql, key });
3446
4022
  const results = await this.executeSql(sql, [key]);
3447
- log$e.debug('Get query results', { key, hasResults: !!results });
4023
+ log$d.debug('Get query results', { key, hasResults: !!results });
3448
4024
  // Normalize results from different SQLite implementations
3449
4025
  const rows = this.normalizeResults(results);
3450
4026
  if (!rows || rows.length === 0) {
@@ -3467,7 +4043,7 @@ class ReactNativeCacheAdapter {
3467
4043
  data,
3468
4044
  timestamp: Date.now(),
3469
4045
  };
3470
- log$e.debug('Setting cache item', { key });
4046
+ log$d.debug('Setting cache item', { key });
3471
4047
  return this.setItem(key, item);
3472
4048
  }
3473
4049
  async setItem(key, item) {
@@ -3480,7 +4056,7 @@ class ReactNativeCacheAdapter {
3480
4056
  const compressionResult = compressData(serializedData, this.options.compressionThreshold);
3481
4057
  finalData = compressionResult.data;
3482
4058
  isCompressed = compressionResult.compressed;
3483
- log$e.debug('Compression result', {
4059
+ log$d.debug('Compression result', {
3484
4060
  key,
3485
4061
  originalSize: compressionResult.originalSize,
3486
4062
  compressedSize: compressionResult.compressedSize,
@@ -3488,7 +4064,7 @@ class ReactNativeCacheAdapter {
3488
4064
  savings: compressionResult.originalSize - compressionResult.compressedSize,
3489
4065
  });
3490
4066
  }
3491
- log$e.debug('Setting item with metadata', {
4067
+ log$d.debug('Setting item with metadata', {
3492
4068
  key,
3493
4069
  timestamp: item.timestamp,
3494
4070
  compressed: isCompressed,
@@ -3514,14 +4090,14 @@ class ReactNativeCacheAdapter {
3514
4090
  `;
3515
4091
  params = [key, finalData, item.timestamp];
3516
4092
  }
3517
- log$e.debug('Executing setItem SQL', { key, paramsCount: params.length });
4093
+ log$d.debug('Executing setItem SQL', { key, paramsCount: params.length });
3518
4094
  await this.executeSql(sql, params);
3519
4095
  }
3520
4096
  async setBatch(items) {
3521
4097
  if (items.length === 0)
3522
4098
  return;
3523
4099
  await this.ensureInitialized();
3524
- log$e.debug('Batch setting items', { count: items.length });
4100
+ log$d.debug('Batch setting items', { count: items.length });
3525
4101
  if (this.isExpo) {
3526
4102
  await this.db.withTransactionAsync(async () => {
3527
4103
  for (const [key, item] of items) {
@@ -3539,7 +4115,7 @@ class ReactNativeCacheAdapter {
3539
4115
  }, reject, () => resolve());
3540
4116
  });
3541
4117
  }
3542
- log$e.debug('Batch operation completed', { count: items.length });
4118
+ log$d.debug('Batch operation completed', { count: items.length });
3543
4119
  }
3544
4120
  async setBatchItem(key, item) {
3545
4121
  // Handle compression if enabled and compressed column is available
@@ -3713,10 +4289,10 @@ class MemoryCacheAdapter {
3713
4289
  return keySize + itemSize;
3714
4290
  }
3715
4291
  async get(key) {
3716
- log$e.debug('Getting cache item', { key });
4292
+ log$d.debug('Getting cache item', { key });
3717
4293
  const item = this.cache.get(key);
3718
4294
  if (!item) {
3719
- log$e.debug('Cache miss', { key });
4295
+ log$d.debug('Cache miss', { key });
3720
4296
  return null;
3721
4297
  }
3722
4298
  // Handle decompression if needed
@@ -3726,7 +4302,7 @@ class MemoryCacheAdapter {
3726
4302
  const decompressed = decompressData(item.data, true);
3727
4303
  finalData = JSON.parse(decompressed.data);
3728
4304
  }
3729
- log$e.debug('Cache hit', { key, compressed: isCompressed });
4305
+ log$d.debug('Cache hit', { key, compressed: isCompressed });
3730
4306
  return {
3731
4307
  ...item,
3732
4308
  data: finalData,
@@ -3734,7 +4310,7 @@ class MemoryCacheAdapter {
3734
4310
  };
3735
4311
  }
3736
4312
  async set(key, data) {
3737
- log$e.debug('Setting cache item', { key });
4313
+ log$d.debug('Setting cache item', { key });
3738
4314
  // Handle compression if enabled
3739
4315
  let finalData = data;
3740
4316
  let isCompressed = false;
@@ -3744,7 +4320,7 @@ class MemoryCacheAdapter {
3744
4320
  if (compressionResult.compressed) {
3745
4321
  finalData = compressionResult.data;
3746
4322
  isCompressed = true;
3747
- log$e.debug('Compression result', {
4323
+ log$d.debug('Compression result', {
3748
4324
  key,
3749
4325
  originalSize: compressionResult.originalSize,
3750
4326
  compressedSize: compressionResult.compressedSize,
@@ -3776,13 +4352,13 @@ class MemoryCacheAdapter {
3776
4352
  const oldestItemSize = this.calculateItemSize(oldestKey, oldestItem);
3777
4353
  this.totalBytes -= oldestItemSize;
3778
4354
  this.cache.delete(oldestKey);
3779
- log$e.debug('Removed oldest item for capacity', { oldestKey, freedBytes: oldestItemSize });
4355
+ log$d.debug('Removed oldest item for capacity', { oldestKey, freedBytes: oldestItemSize });
3780
4356
  }
3781
4357
  }
3782
4358
  // Set new item and update total size
3783
4359
  this.cache.set(key, item);
3784
4360
  this.totalBytes += newItemSize;
3785
- log$e.debug('Updated cache size', {
4361
+ log$d.debug('Updated cache size', {
3786
4362
  entries: this.cache.size,
3787
4363
  totalBytes: this.totalBytes,
3788
4364
  newItemSize,
@@ -3791,7 +4367,7 @@ class MemoryCacheAdapter {
3791
4367
  async setBatch(items) {
3792
4368
  if (items.length === 0)
3793
4369
  return;
3794
- log$e.debug('Batch setting items', { count: items.length });
4370
+ log$d.debug('Batch setting items', { count: items.length });
3795
4371
  let totalNewBytes = 0;
3796
4372
  let totalOldBytes = 0;
3797
4373
  const itemsToRemove = [];
@@ -3820,7 +4396,7 @@ class MemoryCacheAdapter {
3820
4396
  itemsToRemove.push(oldKey);
3821
4397
  }
3822
4398
  if (itemsToRemove.length > 0) {
3823
- log$e.debug('Removed items for batch capacity', {
4399
+ log$d.debug('Removed items for batch capacity', {
3824
4400
  removedCount: itemsToRemove.length,
3825
4401
  removedKeys: itemsToRemove,
3826
4402
  });
@@ -3832,7 +4408,7 @@ class MemoryCacheAdapter {
3832
4408
  for (const [key, item] of items) {
3833
4409
  this.cache.set(key, item);
3834
4410
  }
3835
- log$e.debug('Batch operation completed', {
4411
+ log$d.debug('Batch operation completed', {
3836
4412
  count: items.length,
3837
4413
  totalBytes: this.totalBytes,
3838
4414
  entries: this.cache.size,
@@ -3854,7 +4430,7 @@ class MemoryCacheAdapter {
3854
4430
  }
3855
4431
  }
3856
4432
  if (removed > 0) {
3857
- log$e.debug('Invalidation completed', {
4433
+ log$d.debug('Invalidation completed', {
3858
4434
  pattern,
3859
4435
  entriesRemoved: removed,
3860
4436
  bytesFreed,
@@ -3866,7 +4442,7 @@ class MemoryCacheAdapter {
3866
4442
  async clear() {
3867
4443
  this.cache.clear();
3868
4444
  this.totalBytes = 0;
3869
- log$e.debug('Cache cleared', { entries: 0, bytes: 0 });
4445
+ log$d.debug('Cache cleared', { entries: 0, bytes: 0 });
3870
4446
  }
3871
4447
  async getSize() {
3872
4448
  return {
@@ -4197,7 +4773,7 @@ replaceTraps((oldTraps) => ({
4197
4773
  },
4198
4774
  }));
4199
4775
 
4200
- const log$d = createPrefixedLogger('CACHE-WEB');
4776
+ const log$c = createPrefixedLogger('CACHE-WEB');
4201
4777
  /**
4202
4778
  * Web cache adapter using IndexedDB with automatic error recovery
4203
4779
  * Cache never expires - data persists until explicitly invalidated
@@ -4220,18 +4796,18 @@ class WebCacheAdapter {
4220
4796
  async initialize() {
4221
4797
  if (this.db)
4222
4798
  return;
4223
- log$d.debug('Initializing IndexedDB cache', {
4799
+ log$c.debug('Initializing IndexedDB cache', {
4224
4800
  dbName: WebCacheAdapter.DB_NAME,
4225
4801
  version: WebCacheAdapter.DB_VERSION,
4226
4802
  });
4227
4803
  try {
4228
4804
  this.db = await this.openDatabase();
4229
- log$d.debug('IndexedDB cache initialized successfully');
4805
+ log$c.debug('IndexedDB cache initialized successfully');
4230
4806
  this.retryCount = 0; // Reset retry count on success
4231
4807
  }
4232
4808
  catch (error) {
4233
4809
  const errorMessage = error instanceof Error ? error.message : 'Unknown error';
4234
- log$d.debug('Failed to initialize IndexedDB', { error: errorMessage });
4810
+ log$c.debug('Failed to initialize IndexedDB', { error: errorMessage });
4235
4811
  // Check if this is a version conflict error
4236
4812
  if (this.isVersionConflictError(errorMessage)) {
4237
4813
  await this.handleVersionConflict();
@@ -4244,32 +4820,32 @@ class WebCacheAdapter {
4244
4820
  async openDatabase() {
4245
4821
  return await openDB(WebCacheAdapter.DB_NAME, WebCacheAdapter.DB_VERSION, {
4246
4822
  upgrade: (db, oldVersion, newVersion, transaction) => {
4247
- log$d.debug('Database upgrade needed', { oldVersion, newVersion });
4823
+ log$c.debug('Database upgrade needed', { oldVersion, newVersion });
4248
4824
  this.handleUpgrade(db, oldVersion, newVersion, transaction);
4249
4825
  },
4250
4826
  blocked: () => {
4251
- log$d.debug('Database blocked - another tab may be open');
4827
+ log$c.debug('Database blocked - another tab may be open');
4252
4828
  },
4253
4829
  blocking: () => {
4254
- log$d.debug('Database blocking - will close connection');
4830
+ log$c.debug('Database blocking - will close connection');
4255
4831
  if (this.db) {
4256
4832
  this.db.close();
4257
4833
  this.db = null;
4258
4834
  }
4259
4835
  },
4260
4836
  terminated: () => {
4261
- log$d.debug('Database connection terminated unexpectedly');
4837
+ log$c.debug('Database connection terminated unexpectedly');
4262
4838
  this.db = null;
4263
4839
  },
4264
4840
  });
4265
4841
  }
4266
4842
  handleUpgrade(db, oldVersion, newVersion, transaction) {
4267
- log$d.debug('Handling database upgrade', { oldVersion, newVersion });
4843
+ log$c.debug('Handling database upgrade', { oldVersion, newVersion });
4268
4844
  // Create cache store if it doesn't exist (initial setup)
4269
4845
  if (!db.objectStoreNames.contains(WebCacheAdapter.STORE_NAME)) {
4270
4846
  const store = db.createObjectStore(WebCacheAdapter.STORE_NAME, { keyPath: 'key' });
4271
4847
  store.createIndex('timestamp', 'timestamp', { unique: false });
4272
- log$d.debug('Created cache store and timestamp index');
4848
+ log$c.debug('Created cache store and timestamp index');
4273
4849
  }
4274
4850
  // Handle migration from version 1 to 2
4275
4851
  if (oldVersion < 2) {
@@ -4280,16 +4856,16 @@ class WebCacheAdapter {
4280
4856
  try {
4281
4857
  if (store.indexNames.contains(indexName)) {
4282
4858
  store.deleteIndex(indexName);
4283
- log$d.debug(`Removed unused index: ${indexName}`);
4859
+ log$c.debug(`Removed unused index: ${indexName}`);
4284
4860
  }
4285
4861
  }
4286
4862
  catch (error) {
4287
4863
  // Ignore errors if indexes don't exist
4288
- log$d.debug(`Warning: Could not remove index ${indexName}`, error);
4864
+ log$c.debug(`Warning: Could not remove index ${indexName}`, error);
4289
4865
  }
4290
4866
  });
4291
4867
  }
4292
- log$d.debug('Database upgrade completed');
4868
+ log$c.debug('Database upgrade completed');
4293
4869
  }
4294
4870
  isVersionConflictError(errorMessage) {
4295
4871
  return (errorMessage.includes('less than the existing version') ||
@@ -4297,7 +4873,7 @@ class WebCacheAdapter {
4297
4873
  errorMessage.includes('VersionError'));
4298
4874
  }
4299
4875
  async handleVersionConflict() {
4300
- log$d.debug('Handling version conflict, attempting recovery...');
4876
+ log$c.debug('Handling version conflict, attempting recovery...');
4301
4877
  if (this.retryCount >= this.maxRetries) {
4302
4878
  throw new Error('Failed to resolve IndexedDB version conflict after multiple attempts');
4303
4879
  }
@@ -4309,19 +4885,19 @@ class WebCacheAdapter {
4309
4885
  this.db = null;
4310
4886
  }
4311
4887
  // Delete the problematic database
4312
- log$d.debug('Deleting problematic database to resolve version conflict');
4888
+ log$c.debug('Deleting problematic database to resolve version conflict');
4313
4889
  await deleteDB(WebCacheAdapter.DB_NAME);
4314
4890
  // Wait a bit for the deletion to complete
4315
4891
  await new Promise((resolve) => setTimeout(resolve, 200));
4316
4892
  // Try to open the database again
4317
- log$d.debug(`Retrying database initialization (attempt ${this.retryCount}/${this.maxRetries})`);
4893
+ log$c.debug(`Retrying database initialization (attempt ${this.retryCount}/${this.maxRetries})`);
4318
4894
  this.db = await this.openDatabase();
4319
- log$d.debug('Successfully recovered from version conflict');
4895
+ log$c.debug('Successfully recovered from version conflict');
4320
4896
  this.retryCount = 0; // Reset retry count on success
4321
4897
  }
4322
4898
  catch (retryError) {
4323
4899
  const retryErrorMessage = retryError instanceof Error ? retryError.message : 'Unknown error';
4324
- log$d.debug('Recovery attempt failed', { attempt: this.retryCount, error: retryErrorMessage });
4900
+ log$c.debug('Recovery attempt failed', { attempt: this.retryCount, error: retryErrorMessage });
4325
4901
  if (this.retryCount < this.maxRetries) {
4326
4902
  // Try again
4327
4903
  await this.handleVersionConflict();
@@ -4333,7 +4909,7 @@ class WebCacheAdapter {
4333
4909
  }
4334
4910
  async get(key) {
4335
4911
  await this.ensureInitialized();
4336
- log$d.debug('Getting cache item', { key });
4912
+ log$c.debug('Getting cache item', { key });
4337
4913
  try {
4338
4914
  const transaction = this.db.transaction([WebCacheAdapter.STORE_NAME], 'readonly');
4339
4915
  const store = transaction.objectStore(WebCacheAdapter.STORE_NAME);
@@ -4359,7 +4935,7 @@ class WebCacheAdapter {
4359
4935
  };
4360
4936
  }
4361
4937
  catch (error) {
4362
- log$d.debug('Error getting cache item', { key, error });
4938
+ log$c.debug('Error getting cache item', { key, error });
4363
4939
  return null; // Return null on error instead of throwing
4364
4940
  }
4365
4941
  }
@@ -4381,7 +4957,7 @@ class WebCacheAdapter {
4381
4957
  if (compressionResult.compressed) {
4382
4958
  finalData = compressionResult.data;
4383
4959
  isCompressed = true;
4384
- log$d.debug('Compression result', {
4960
+ log$c.debug('Compression result', {
4385
4961
  key,
4386
4962
  originalSize: compressionResult.originalSize,
4387
4963
  compressedSize: compressionResult.compressedSize,
@@ -4390,7 +4966,7 @@ class WebCacheAdapter {
4390
4966
  });
4391
4967
  }
4392
4968
  }
4393
- log$d.debug('Setting cache item', { key, timestamp: item.timestamp, compressed: isCompressed });
4969
+ log$c.debug('Setting cache item', { key, timestamp: item.timestamp, compressed: isCompressed });
4394
4970
  const storedItem = {
4395
4971
  key,
4396
4972
  data: finalData,
@@ -4403,7 +4979,7 @@ class WebCacheAdapter {
4403
4979
  await store.put(storedItem);
4404
4980
  }
4405
4981
  catch (error) {
4406
- log$d.debug('Error setting cache item', { key, error });
4982
+ log$c.debug('Error setting cache item', { key, error });
4407
4983
  // Silently fail for cache writes
4408
4984
  }
4409
4985
  }
@@ -4411,7 +4987,7 @@ class WebCacheAdapter {
4411
4987
  if (items.length === 0)
4412
4988
  return;
4413
4989
  await this.ensureInitialized();
4414
- log$d.debug('Batch setting items', { count: items.length });
4990
+ log$c.debug('Batch setting items', { count: items.length });
4415
4991
  try {
4416
4992
  const transaction = this.db.transaction([WebCacheAdapter.STORE_NAME], 'readwrite');
4417
4993
  const store = transaction.objectStore(WebCacheAdapter.STORE_NAME);
@@ -4421,10 +4997,10 @@ class WebCacheAdapter {
4421
4997
  return store.put(storedItem);
4422
4998
  });
4423
4999
  await Promise.all(promises);
4424
- log$d.debug('Batch operation completed', { count: items.length });
5000
+ log$c.debug('Batch operation completed', { count: items.length });
4425
5001
  }
4426
5002
  catch (error) {
4427
- log$d.debug('Error in batch operation', { count: items.length, error });
5003
+ log$c.debug('Error in batch operation', { count: items.length, error });
4428
5004
  // Silently fail for batch writes
4429
5005
  }
4430
5006
  }
@@ -4459,10 +5035,10 @@ class WebCacheAdapter {
4459
5035
  const transaction = this.db.transaction([WebCacheAdapter.STORE_NAME], 'readwrite');
4460
5036
  const store = transaction.objectStore(WebCacheAdapter.STORE_NAME);
4461
5037
  await store.clear();
4462
- log$d.debug('Cache cleared successfully');
5038
+ log$c.debug('Cache cleared successfully');
4463
5039
  }
4464
5040
  catch (error) {
4465
- log$d.debug('Error clearing cache', error);
5041
+ log$c.debug('Error clearing cache', error);
4466
5042
  // Silently fail for cache clear
4467
5043
  }
4468
5044
  }
@@ -4488,7 +5064,7 @@ class WebCacheAdapter {
4488
5064
  };
4489
5065
  }
4490
5066
  catch (error) {
4491
- log$d.debug('Error getting cache size', error);
5067
+ log$c.debug('Error getting cache size', error);
4492
5068
  return {
4493
5069
  entries: 0,
4494
5070
  bytes: 0,
@@ -4513,7 +5089,7 @@ class WebCacheAdapter {
4513
5089
  return allKeys.filter((key) => regex.test(key));
4514
5090
  }
4515
5091
  catch (error) {
4516
- log$d.debug('Error getting cache keys', error);
5092
+ log$c.debug('Error getting cache keys', error);
4517
5093
  return [];
4518
5094
  }
4519
5095
  }
@@ -4526,7 +5102,7 @@ class WebCacheAdapter {
4526
5102
  return true;
4527
5103
  }
4528
5104
  catch (error) {
4529
- log$d.debug('Error deleting cache item', { key, error });
5105
+ log$c.debug('Error deleting cache item', { key, error });
4530
5106
  return false;
4531
5107
  }
4532
5108
  }
@@ -4538,7 +5114,7 @@ class WebCacheAdapter {
4538
5114
  await this.initPromise;
4539
5115
  }
4540
5116
  catch (error) {
4541
- log$d.debug('Failed to ensure initialization', error);
5117
+ log$c.debug('Failed to ensure initialization', error);
4542
5118
  // Reset and try once more
4543
5119
  this.initPromise = null;
4544
5120
  this.db = null;
@@ -4557,7 +5133,7 @@ WebCacheAdapter.DB_NAME = 'acube_cache';
4557
5133
  WebCacheAdapter.DB_VERSION = 2;
4558
5134
  WebCacheAdapter.STORE_NAME = 'cache_entries';
4559
5135
 
4560
- const log$c = createPrefixedLogger('CACHE-LOADER');
5136
+ const log$b = createPrefixedLogger('CACHE-LOADER');
4561
5137
  function loadCacheAdapter(platform) {
4562
5138
  try {
4563
5139
  switch (platform) {
@@ -4589,7 +5165,7 @@ function loadCacheAdapter(platform) {
4589
5165
  }
4590
5166
  }
4591
5167
  catch (error) {
4592
- log$c.warn(`Cache adapter not available for platform ${platform}:`, error);
5168
+ log$b.warn(`Cache adapter not available for platform ${platform}:`, error);
4593
5169
  return undefined;
4594
5170
  }
4595
5171
  }
@@ -4646,7 +5222,7 @@ class BaseSecureStorageAdapter {
4646
5222
  }
4647
5223
  }
4648
5224
 
4649
- const log$b = createPrefixedLogger('NETWORK-BASE');
5225
+ const log$a = createPrefixedLogger('NETWORK-BASE');
4650
5226
  class NetworkBase {
4651
5227
  constructor(initialOnline = true, debounceMs = 300) {
4652
5228
  this.destroy$ = new Subject();
@@ -4666,14 +5242,14 @@ class NetworkBase {
4666
5242
  const current = this.statusSubject.getValue();
4667
5243
  if (current.online !== online) {
4668
5244
  this.statusSubject.next({ online, timestamp: Date.now() });
4669
- log$b.debug(`Network status changed: ${online ? 'online' : 'offline'}`);
5245
+ log$a.debug(`Network status changed: ${online ? 'online' : 'offline'}`);
4670
5246
  }
4671
5247
  }
4672
5248
  destroy() {
4673
5249
  this.destroy$.next();
4674
5250
  this.destroy$.complete();
4675
5251
  this.statusSubject.complete();
4676
- log$b.debug('Network monitor destroyed');
5252
+ log$a.debug('Network monitor destroyed');
4677
5253
  }
4678
5254
  }
4679
5255
 
@@ -4733,7 +5309,7 @@ class NodeSecureStorageAdapter extends BaseSecureStorageAdapter {
4733
5309
  }
4734
5310
  }
4735
5311
 
4736
- const log$a = createPrefixedLogger('RN-STORAGE');
5312
+ const log$9 = createPrefixedLogger('RN-STORAGE');
4737
5313
  /**
4738
5314
  * React Native storage adapter using AsyncStorage
4739
5315
  * Note: Uses native batch operations for better performance (not base class)
@@ -4765,7 +5341,7 @@ class ReactNativeStorageAdapter {
4765
5341
  return await this.AsyncStorage.getItem(key);
4766
5342
  }
4767
5343
  catch (error) {
4768
- log$a.error('Failed to get item from AsyncStorage:', error);
5344
+ log$9.error('Failed to get item from AsyncStorage:', error);
4769
5345
  return null;
4770
5346
  }
4771
5347
  }
@@ -4806,7 +5382,7 @@ class ReactNativeStorageAdapter {
4806
5382
  return await this.AsyncStorage.getAllKeys();
4807
5383
  }
4808
5384
  catch (error) {
4809
- log$a.error('Failed to get all keys:', error);
5385
+ log$9.error('Failed to get all keys:', error);
4810
5386
  return [];
4811
5387
  }
4812
5388
  }
@@ -4823,7 +5399,7 @@ class ReactNativeStorageAdapter {
4823
5399
  return result;
4824
5400
  }
4825
5401
  catch (error) {
4826
- log$a.error('Failed to get multiple items:', error);
5402
+ log$9.error('Failed to get multiple items:', error);
4827
5403
  const result = {};
4828
5404
  keys.forEach((key) => {
4829
5405
  result[key] = null;
@@ -4873,7 +5449,7 @@ class ReactNativeSecureStorageAdapter extends BaseSecureStorageAdapter {
4873
5449
  return;
4874
5450
  }
4875
5451
  catch {
4876
- log$a.debug('expo-secure-store not available, trying react-native-keychain');
5452
+ log$9.debug('expo-secure-store not available, trying react-native-keychain');
4877
5453
  }
4878
5454
  try {
4879
5455
  const Keychain = require('react-native-keychain');
@@ -4882,7 +5458,7 @@ class ReactNativeSecureStorageAdapter extends BaseSecureStorageAdapter {
4882
5458
  return;
4883
5459
  }
4884
5460
  catch {
4885
- log$a.error('react-native-keychain not available');
5461
+ log$9.error('react-native-keychain not available');
4886
5462
  }
4887
5463
  throw new Error('No secure storage available. Please install expo-secure-store or react-native-keychain');
4888
5464
  }
@@ -4900,7 +5476,7 @@ class ReactNativeSecureStorageAdapter extends BaseSecureStorageAdapter {
4900
5476
  }
4901
5477
  }
4902
5478
  catch (error) {
4903
- log$a.error('Failed to get secure item:', error);
5479
+ log$9.error('Failed to get secure item:', error);
4904
5480
  }
4905
5481
  return null;
4906
5482
  }
@@ -4937,10 +5513,10 @@ class ReactNativeSecureStorageAdapter extends BaseSecureStorageAdapter {
4937
5513
  }
4938
5514
  }
4939
5515
  async clear() {
4940
- log$a.warn('Clear all secure items not fully implemented for React Native');
5516
+ log$9.warn('Clear all secure items not fully implemented for React Native');
4941
5517
  }
4942
5518
  async getAllKeys() {
4943
- log$a.warn('Get all secure keys not implemented for React Native');
5519
+ log$9.warn('Get all secure keys not implemented for React Native');
4944
5520
  return [];
4945
5521
  }
4946
5522
  async isAvailable() {
@@ -5158,7 +5734,7 @@ class NodeNetworkMonitor extends NetworkBase {
5158
5734
  }
5159
5735
  }
5160
5736
 
5161
- const log$9 = createPrefixedLogger('RN-NETWORK');
5737
+ const log$8 = createPrefixedLogger('RN-NETWORK');
5162
5738
  /**
5163
5739
  * React Native network monitor using RxJS
5164
5740
  * Supports both @react-native-community/netinfo and expo-network
@@ -5171,7 +5747,7 @@ class ReactNativeNetworkMonitor extends NetworkBase {
5171
5747
  this.moduleReady$ = new Subject();
5172
5748
  this.isExpo = detectPlatform().isExpo;
5173
5749
  this.init().catch((error) => {
5174
- log$9.error('Network monitor initialization failed:', error);
5750
+ log$8.error('Network monitor initialization failed:', error);
5175
5751
  });
5176
5752
  }
5177
5753
  async init() {
@@ -5190,10 +5766,10 @@ class ReactNativeNetworkMonitor extends NetworkBase {
5190
5766
  try {
5191
5767
  const module = require('@react-native-community/netinfo');
5192
5768
  this.netInfoModule = module.default || module;
5193
- log$9.debug('Loaded @react-native-community/netinfo module');
5769
+ log$8.debug('Loaded @react-native-community/netinfo module');
5194
5770
  }
5195
5771
  catch (error) {
5196
- log$9.error('Failed to load React Native NetInfo module:', error);
5772
+ log$8.error('Failed to load React Native NetInfo module:', error);
5197
5773
  this.netInfoModule = null;
5198
5774
  }
5199
5775
  }
@@ -5201,10 +5777,10 @@ class ReactNativeNetworkMonitor extends NetworkBase {
5201
5777
  try {
5202
5778
  const module = require('expo-network');
5203
5779
  this.netInfoModule = module.default || module;
5204
- log$9.debug('Loaded expo-network module');
5780
+ log$8.debug('Loaded expo-network module');
5205
5781
  }
5206
5782
  catch (error) {
5207
- log$9.error('Failed to load Expo Network module:', error);
5783
+ log$8.error('Failed to load Expo Network module:', error);
5208
5784
  this.netInfoModule = null;
5209
5785
  }
5210
5786
  }
@@ -5221,16 +5797,16 @@ class ReactNativeNetworkMonitor extends NetworkBase {
5221
5797
  }
5222
5798
  const online = !!(state.isConnected && state.isInternetReachable !== false);
5223
5799
  this.updateStatus(online);
5224
- log$9.debug('Initial network state:', online ? 'online' : 'offline');
5800
+ log$8.debug('Initial network state:', online ? 'online' : 'offline');
5225
5801
  }
5226
5802
  catch (error) {
5227
- log$9.warn('Could not fetch initial network state:', error);
5803
+ log$8.warn('Could not fetch initial network state:', error);
5228
5804
  }
5229
5805
  }
5230
5806
  subscribeToStateChanges() {
5231
5807
  if (!this.netInfoModule)
5232
5808
  return;
5233
- log$9.debug('Subscribing to network state changes');
5809
+ log$8.debug('Subscribing to network state changes');
5234
5810
  const handleState = (state) => {
5235
5811
  const online = !!(state.isConnected && (state.isInternetReachable ?? true));
5236
5812
  this.updateStatus(online);
@@ -5272,7 +5848,7 @@ class ReactNativeNetworkMonitor extends NetworkBase {
5272
5848
  };
5273
5849
  }
5274
5850
  catch (error) {
5275
- log$9.error('Failed to fetch detailed network info:', error);
5851
+ log$8.error('Failed to fetch detailed network info:', error);
5276
5852
  return null;
5277
5853
  }
5278
5854
  }
@@ -5408,7 +5984,7 @@ class CertificateValidator {
5408
5984
  }
5409
5985
  }
5410
5986
 
5411
- const log$8 = createPrefixedLogger('RN-MTLS');
5987
+ const log$7 = createPrefixedLogger('RN-MTLS');
5412
5988
  /**
5413
5989
  * React Native mTLS Adapter using @a-cube-io/expo-mutual-tls
5414
5990
  */
@@ -5430,7 +6006,7 @@ class ReactNativeMTLSAdapter {
5430
6006
  this.expoMTLS = ExpoMutualTls;
5431
6007
  // Set up debug logging with the correct event signature
5432
6008
  const debugListener = ExpoMutualTls.onDebugLog((event) => {
5433
- log$8.debug(`${event.type}: ${event.message}`, {
6009
+ log$7.debug(`${event.type}: ${event.message}`, {
5434
6010
  method: event.method,
5435
6011
  url: event.url,
5436
6012
  statusCode: event.statusCode,
@@ -5440,28 +6016,28 @@ class ReactNativeMTLSAdapter {
5440
6016
  this.eventListeners.push(debugListener);
5441
6017
  // Set up error logging with the correct event signature
5442
6018
  const errorListener = ExpoMutualTls.onError((event) => {
5443
- log$8.error(event.message, {
6019
+ log$7.error(event.message, {
5444
6020
  code: event.code,
5445
6021
  });
5446
6022
  });
5447
6023
  this.eventListeners.push(errorListener);
5448
6024
  // Set up certificate expiry monitoring with the correct event signature
5449
6025
  const expiryListener = ExpoMutualTls.onCertificateExpiry((event) => {
5450
- log$8.warn(`Certificate ${event.subject} expires at ${new Date(event.expiry)}`, {
6026
+ log$7.warn(`Certificate ${event.subject} expires at ${new Date(event.expiry)}`, {
5451
6027
  alias: event.alias,
5452
6028
  warning: event.warning,
5453
6029
  });
5454
6030
  });
5455
6031
  this.eventListeners.push(expiryListener);
5456
- log$8.debug('Expo mTLS module loaded successfully');
6032
+ log$7.debug('Expo mTLS module loaded successfully');
5457
6033
  }
5458
6034
  catch (error) {
5459
- log$8.warn('@a-cube-io/expo-mutual-tls not available:', error);
6035
+ log$7.warn('@a-cube-io/expo-mutual-tls not available:', error);
5460
6036
  }
5461
6037
  }
5462
6038
  async isMTLSSupported() {
5463
6039
  const supported = this.expoMTLS !== null;
5464
- log$8.debug('mTLS support check:', {
6040
+ log$7.debug('mTLS support check:', {
5465
6041
  supported,
5466
6042
  platform: this.getPlatformInfo().platform,
5467
6043
  moduleAvailable: !!this.expoMTLS,
@@ -5473,7 +6049,7 @@ class ReactNativeMTLSAdapter {
5473
6049
  throw new MTLSError(exports.MTLSErrorType.NOT_SUPPORTED, 'Expo mTLS module not available');
5474
6050
  }
5475
6051
  this.config = config;
5476
- log$8.debug('Initialized with config:', {
6052
+ log$7.debug('Initialized with config:', {
5477
6053
  baseUrl: config.baseUrl,
5478
6054
  port: config.port,
5479
6055
  timeout: config.timeout,
@@ -5487,7 +6063,7 @@ class ReactNativeMTLSAdapter {
5487
6063
  if (!this.config) {
5488
6064
  throw new MTLSError(exports.MTLSErrorType.CONFIGURATION_ERROR, 'Adapter not initialized. Call initialize() first.');
5489
6065
  }
5490
- log$8.debug('Configuring certificate:', {
6066
+ log$7.debug('Configuring certificate:', {
5491
6067
  format: certificateData.format,
5492
6068
  hasPassword: !!certificateData.password,
5493
6069
  certificateLength: certificateData.certificate.length,
@@ -5504,14 +6080,14 @@ class ReactNativeMTLSAdapter {
5504
6080
  'client-key-service', // keyService
5505
6081
  true // enableLogging - let the native module handle its own debug logging
5506
6082
  );
5507
- log$8.debug('PEM services configured:', configResult);
6083
+ log$7.debug('PEM services configured:', configResult);
5508
6084
  if (!configResult.success) {
5509
6085
  throw new MTLSError(exports.MTLSErrorType.CONFIGURATION_ERROR, `PEM configuration failed: ${configResult.state}`);
5510
6086
  }
5511
6087
  // Step 2: Store the actual PEM certificate and private key
5512
6088
  const storeResult = await this.expoMTLS.storePEM(certificateData.certificate, certificateData.privateKey, certificateData.password // passphrase (optional)
5513
6089
  );
5514
- log$8.debug('PEM certificate store result:', storeResult);
6090
+ log$7.debug('PEM certificate store result:', storeResult);
5515
6091
  if (!storeResult) {
5516
6092
  throw new MTLSError(exports.MTLSErrorType.CERTIFICATE_INVALID, 'Failed to store PEM certificate');
5517
6093
  }
@@ -5524,14 +6100,14 @@ class ReactNativeMTLSAdapter {
5524
6100
  const configResult = await this.expoMTLS.configureP12('client-p12-service', // keychainService
5525
6101
  true // enableLogging - let the native module handle its own debug logging
5526
6102
  );
5527
- log$8.debug('P12 service configured:', configResult);
6103
+ log$7.debug('P12 service configured:', configResult);
5528
6104
  if (!configResult.success) {
5529
6105
  throw new MTLSError(exports.MTLSErrorType.CONFIGURATION_ERROR, `P12 configuration failed: ${configResult.state}`);
5530
6106
  }
5531
6107
  // Step 2: Store the P12 certificate data
5532
6108
  const storeResult = await this.expoMTLS.storeP12(certificateData.certificate, // P12 data in certificate field
5533
6109
  certificateData.password);
5534
- log$8.debug('P12 certificate store result:', storeResult);
6110
+ log$7.debug('P12 certificate store result:', storeResult);
5535
6111
  if (!storeResult) {
5536
6112
  throw new MTLSError(exports.MTLSErrorType.CERTIFICATE_INVALID, 'Failed to store P12 certificate');
5537
6113
  }
@@ -5545,7 +6121,7 @@ class ReactNativeMTLSAdapter {
5545
6121
  if (error instanceof MTLSError) {
5546
6122
  throw error;
5547
6123
  }
5548
- log$8.error('Certificate configuration failed:', error);
6124
+ log$7.error('Certificate configuration failed:', error);
5549
6125
  throw new MTLSError(exports.MTLSErrorType.CONFIGURATION_ERROR, 'Failed to configure certificate', error);
5550
6126
  }
5551
6127
  }
@@ -5556,38 +6132,38 @@ class ReactNativeMTLSAdapter {
5556
6132
  try {
5557
6133
  // Use static method call
5558
6134
  const hasCert = await this.expoMTLS.hasCertificate();
5559
- log$8.debug('Certificate availability check:', hasCert);
6135
+ log$7.debug('Certificate availability check:', hasCert);
5560
6136
  return hasCert;
5561
6137
  }
5562
6138
  catch (error) {
5563
- log$8.error('Certificate check failed:', error);
6139
+ log$7.error('Certificate check failed:', error);
5564
6140
  return false;
5565
6141
  }
5566
6142
  }
5567
6143
  async getCertificateInfo() {
5568
6144
  if (!this.expoMTLS) {
5569
- log$8.debug('Certificate info requested but module not available');
6145
+ log$7.debug('Certificate info requested but module not available');
5570
6146
  return null;
5571
6147
  }
5572
6148
  try {
5573
6149
  const hasCert = await this.hasCertificate();
5574
6150
  if (!hasCert) {
5575
- log$8.debug('No certificate stored');
6151
+ log$7.debug('No certificate stored');
5576
6152
  return null;
5577
6153
  }
5578
6154
  // Use getCertificatesInfo to retrieve information about stored certificates
5579
6155
  const result = await this.expoMTLS.getCertificatesInfo();
5580
6156
  if (!result || !result.certificates || result.certificates.length === 0) {
5581
- log$8.debug('No certificate information available');
6157
+ log$7.debug('No certificate information available');
5582
6158
  return null;
5583
6159
  }
5584
6160
  // Get the first certificate (primary client certificate)
5585
6161
  const cert = result.certificates[0];
5586
6162
  if (!cert) {
5587
- log$8.debug('Certificate data is empty');
6163
+ log$7.debug('Certificate data is empty');
5588
6164
  return null;
5589
6165
  }
5590
- log$8.debug('Retrieved certificate info:', {
6166
+ log$7.debug('Retrieved certificate info:', {
5591
6167
  subject: cert.subject.commonName,
5592
6168
  issuer: cert.issuer.commonName,
5593
6169
  validFrom: new Date(cert.validFrom),
@@ -5606,7 +6182,7 @@ class ReactNativeMTLSAdapter {
5606
6182
  };
5607
6183
  }
5608
6184
  catch (error) {
5609
- log$8.error('Failed to get certificate info:', error);
6185
+ log$7.error('Failed to get certificate info:', error);
5610
6186
  return null;
5611
6187
  }
5612
6188
  }
@@ -5617,7 +6193,7 @@ class ReactNativeMTLSAdapter {
5617
6193
  */
5618
6194
  async parseCertificateData(certificateData) {
5619
6195
  if (!this.expoMTLS) {
5620
- log$8.debug('Parse certificate: Module not available');
6196
+ log$7.debug('Parse certificate: Module not available');
5621
6197
  return null;
5622
6198
  }
5623
6199
  try {
@@ -5634,14 +6210,14 @@ class ReactNativeMTLSAdapter {
5634
6210
  else {
5635
6211
  throw new MTLSError(exports.MTLSErrorType.CERTIFICATE_INVALID, `Unsupported certificate format: ${certificateData.format}`);
5636
6212
  }
5637
- log$8.debug('Certificate parsed successfully:', {
6213
+ log$7.debug('Certificate parsed successfully:', {
5638
6214
  certificateCount: result.certificates.length,
5639
6215
  subjects: result.certificates.map((cert) => cert.subject.commonName),
5640
6216
  });
5641
6217
  return result;
5642
6218
  }
5643
6219
  catch (error) {
5644
- log$8.error('Failed to parse certificate:', error);
6220
+ log$7.error('Failed to parse certificate:', error);
5645
6221
  if (error instanceof MTLSError) {
5646
6222
  throw error;
5647
6223
  }
@@ -5656,7 +6232,7 @@ class ReactNativeMTLSAdapter {
5656
6232
  if (!hasCert) {
5657
6233
  throw new MTLSError(exports.MTLSErrorType.CERTIFICATE_NOT_FOUND, 'No certificate configured');
5658
6234
  }
5659
- log$8.debug('Making mTLS request:', {
6235
+ log$7.debug('Making mTLS request:', {
5660
6236
  method: requestConfig.method || 'GET',
5661
6237
  url: requestConfig.url,
5662
6238
  headers: requestConfig.headers,
@@ -5664,7 +6240,7 @@ class ReactNativeMTLSAdapter {
5664
6240
  responseType: requestConfig.responseType,
5665
6241
  });
5666
6242
  if (requestConfig.data) {
5667
- log$8.debug('mTLS request body:', requestConfig.data);
6243
+ log$7.debug('mTLS request body:', requestConfig.data);
5668
6244
  }
5669
6245
  try {
5670
6246
  const response = await this.expoMTLS.request(requestConfig.url, {
@@ -5673,7 +6249,7 @@ class ReactNativeMTLSAdapter {
5673
6249
  body: requestConfig.data ? JSON.stringify(requestConfig.data) : undefined,
5674
6250
  responseType: requestConfig.responseType,
5675
6251
  });
5676
- log$8.debug('mTLS request successful:', response);
6252
+ log$7.debug('mTLS request successful:', response);
5677
6253
  if (!response.success) {
5678
6254
  throw new MTLSError(exports.MTLSErrorType.CONNECTION_FAILED, `mTLS request failed: ${response.statusMessage} (${response.statusCode})`, undefined, response.statusCode);
5679
6255
  }
@@ -5685,7 +6261,7 @@ class ReactNativeMTLSAdapter {
5685
6261
  data = JSON.parse(response.body);
5686
6262
  }
5687
6263
  catch (parseError) {
5688
- log$8.warn('Failed to parse JSON response:', parseError);
6264
+ log$7.warn('Failed to parse JSON response:', parseError);
5689
6265
  // If parsing fails, keep raw body
5690
6266
  }
5691
6267
  }
@@ -5702,7 +6278,7 @@ class ReactNativeMTLSAdapter {
5702
6278
  };
5703
6279
  }
5704
6280
  catch (error) {
5705
- log$8.error('mTLS request failed:', error);
6281
+ log$7.error('mTLS request failed:', error);
5706
6282
  throw new MTLSError(exports.MTLSErrorType.CONNECTION_FAILED, 'mTLS request failed', error);
5707
6283
  }
5708
6284
  }
@@ -5715,18 +6291,18 @@ class ReactNativeMTLSAdapter {
5715
6291
  */
5716
6292
  async testConnection() {
5717
6293
  if (!this.expoMTLS || !this.config) {
5718
- log$8.debug('Diagnostic test: No mTLS module or config available');
6294
+ log$7.debug('Diagnostic test: No mTLS module or config available');
5719
6295
  return false;
5720
6296
  }
5721
6297
  try {
5722
6298
  const hasCert = await this.hasCertificate();
5723
6299
  if (!hasCert) {
5724
- log$8.debug('Diagnostic test: No certificate configured');
6300
+ log$7.debug('Diagnostic test: No certificate configured');
5725
6301
  return false;
5726
6302
  }
5727
- log$8.debug('Running diagnostic test (may fail even if mTLS works):', this.config.baseUrl);
6303
+ log$7.debug('Running diagnostic test (may fail even if mTLS works):', this.config.baseUrl);
5728
6304
  const result = await this.expoMTLS.testConnection(this.config.baseUrl);
5729
- log$8.debug('Diagnostic test result (NOT validation):', {
6305
+ log$7.debug('Diagnostic test result (NOT validation):', {
5730
6306
  success: result.success,
5731
6307
  statusCode: result.statusCode,
5732
6308
  statusMessage: result.statusMessage,
@@ -5737,13 +6313,13 @@ class ReactNativeMTLSAdapter {
5737
6313
  return result.success;
5738
6314
  }
5739
6315
  catch (error) {
5740
- log$8.warn('Diagnostic test failed (this is expected):', error);
6316
+ log$7.warn('Diagnostic test failed (this is expected):', error);
5741
6317
  return false;
5742
6318
  }
5743
6319
  }
5744
6320
  async removeCertificate() {
5745
6321
  if (!this.expoMTLS) {
5746
- log$8.debug('Remove certificate: Module not available');
6322
+ log$7.debug('Remove certificate: Module not available');
5747
6323
  return;
5748
6324
  }
5749
6325
  try {
@@ -5752,10 +6328,10 @@ class ReactNativeMTLSAdapter {
5752
6328
  this.isConfigured = false;
5753
6329
  // Cleanup event listeners
5754
6330
  this.cleanupEventListeners();
5755
- log$8.debug('Certificate removed successfully');
6331
+ log$7.debug('Certificate removed successfully');
5756
6332
  }
5757
6333
  catch (error) {
5758
- log$8.error('Failed to remove certificate:', error);
6334
+ log$7.error('Failed to remove certificate:', error);
5759
6335
  throw new MTLSError(exports.MTLSErrorType.CONFIGURATION_ERROR, 'Failed to remove certificate', error);
5760
6336
  }
5761
6337
  }
@@ -5764,7 +6340,7 @@ class ReactNativeMTLSAdapter {
5764
6340
  */
5765
6341
  cleanupEventListeners() {
5766
6342
  if (this.eventListeners.length > 0) {
5767
- log$8.debug(`Cleaning up ${this.eventListeners.length} event listeners`);
6343
+ log$7.debug(`Cleaning up ${this.eventListeners.length} event listeners`);
5768
6344
  }
5769
6345
  // Remove individual listeners if they have remove methods
5770
6346
  this.eventListeners.forEach((listener) => {
@@ -5801,7 +6377,7 @@ class ReactNativeMTLSAdapter {
5801
6377
  }
5802
6378
  }
5803
6379
 
5804
- const log$7 = createPrefixedLogger('WEB-MTLS');
6380
+ const log$6 = createPrefixedLogger('WEB-MTLS');
5805
6381
  /**
5806
6382
  * Web mTLS Adapter - Graceful fallback for web browsers
5807
6383
  *
@@ -5815,13 +6391,13 @@ const log$7 = createPrefixedLogger('WEB-MTLS');
5815
6391
  */
5816
6392
  class WebMTLSAdapter {
5817
6393
  constructor() {
5818
- log$7.warn('Web browsers do not support programmatic mTLS configuration');
5819
- log$7.info('Use JWT authentication or configure client certificates in browser settings');
6394
+ log$6.warn('Web browsers do not support programmatic mTLS configuration');
6395
+ log$6.info('Use JWT authentication or configure client certificates in browser settings');
5820
6396
  }
5821
6397
  async isMTLSSupported() {
5822
6398
  // mTLS is not supported programmatically in web browsers
5823
6399
  const supported = false;
5824
- log$7.debug('mTLS support check:', {
6400
+ log$6.debug('mTLS support check:', {
5825
6401
  supported,
5826
6402
  platform: this.getPlatformInfo().platform,
5827
6403
  reason: 'Browser security model prevents programmatic certificate configuration',
@@ -5830,14 +6406,14 @@ class WebMTLSAdapter {
5830
6406
  return supported;
5831
6407
  }
5832
6408
  async initialize(config) {
5833
- log$7.warn('Initialized but mTLS not available in web browsers:', {
6409
+ log$6.warn('Initialized but mTLS not available in web browsers:', {
5834
6410
  baseUrl: config.baseUrl,
5835
6411
  port: config.port,
5836
6412
  recommendation: 'Use standard HTTPS with JWT authentication',
5837
6413
  });
5838
6414
  }
5839
6415
  async configureCertificate(certificateData) {
5840
- log$7.error('Certificate configuration attempted:', {
6416
+ log$6.error('Certificate configuration attempted:', {
5841
6417
  format: certificateData.format,
5842
6418
  reason: 'Not supported in web browsers',
5843
6419
  alternatives: [
@@ -5852,15 +6428,15 @@ class WebMTLSAdapter {
5852
6428
  }
5853
6429
  async hasCertificate() {
5854
6430
  // We cannot detect if the browser has certificates configured
5855
- log$7.debug('Certificate availability check: Cannot detect browser certificates programmatically');
6431
+ log$6.debug('Certificate availability check: Cannot detect browser certificates programmatically');
5856
6432
  return false;
5857
6433
  }
5858
6434
  async getCertificateInfo() {
5859
- log$7.debug('Certificate info requested: Not accessible in web browsers');
6435
+ log$6.debug('Certificate info requested: Not accessible in web browsers');
5860
6436
  return null;
5861
6437
  }
5862
6438
  async request(requestConfig) {
5863
- log$7.error('mTLS request attempted:', {
6439
+ log$6.error('mTLS request attempted:', {
5864
6440
  method: requestConfig.method,
5865
6441
  url: requestConfig.url,
5866
6442
  reason: 'Not supported in web browsers',
@@ -5875,11 +6451,11 @@ class WebMTLSAdapter {
5875
6451
  'are properly configured in the browser certificate store.');
5876
6452
  }
5877
6453
  async testConnection() {
5878
- log$7.debug('Connection test: mTLS not available in web browsers');
6454
+ log$6.debug('Connection test: mTLS not available in web browsers');
5879
6455
  return false;
5880
6456
  }
5881
6457
  async removeCertificate() {
5882
- log$7.debug('Remove certificate: No certificates to remove (not supported in web browsers)');
6458
+ log$6.debug('Remove certificate: No certificates to remove (not supported in web browsers)');
5883
6459
  // No-op - cannot remove certificates programmatically in browsers
5884
6460
  }
5885
6461
  /**
@@ -5887,7 +6463,7 @@ class WebMTLSAdapter {
5887
6463
  * Always returns null for web browsers as mTLS is not supported
5888
6464
  */
5889
6465
  getBaseUrl() {
5890
- log$7.debug('Base URL requested: Not supported in web browsers');
6466
+ log$6.debug('Base URL requested: Not supported in web browsers');
5891
6467
  return null;
5892
6468
  }
5893
6469
  getPlatformInfo() {
@@ -5920,7 +6496,7 @@ class WebMTLSAdapter {
5920
6496
  }
5921
6497
  }
5922
6498
 
5923
- const log$6 = createPrefixedLogger('MTLS-LOADER');
6499
+ const log$5 = createPrefixedLogger('MTLS-LOADER');
5924
6500
  function loadMTLSAdapter(platform, config) {
5925
6501
  try {
5926
6502
  let adapter;
@@ -5954,7 +6530,7 @@ function loadMTLSAdapter(platform, config) {
5954
6530
  return adapter;
5955
6531
  }
5956
6532
  catch (error) {
5957
- log$6.warn(`mTLS adapter not available for platform ${platform}:`, error);
6533
+ log$5.warn(`mTLS adapter not available for platform ${platform}:`, error);
5958
6534
  return null;
5959
6535
  }
5960
6536
  }
@@ -5964,7 +6540,7 @@ async function initializeAdapterAsync(adapter, config) {
5964
6540
  if (isSupported) {
5965
6541
  await adapter.initialize(config);
5966
6542
  const platformInfo = adapter.getPlatformInfo();
5967
- log$6.debug('mTLS adapter initialized:', {
6543
+ log$5.debug('mTLS adapter initialized:', {
5968
6544
  platform: platformInfo.platform,
5969
6545
  mtlsSupported: platformInfo.mtlsSupported,
5970
6546
  certificateStorage: platformInfo.certificateStorage,
@@ -5973,20 +6549,20 @@ async function initializeAdapterAsync(adapter, config) {
5973
6549
  }
5974
6550
  }
5975
6551
  catch (error) {
5976
- log$6.warn('Failed to initialize mTLS adapter:', error);
6552
+ log$5.warn('Failed to initialize mTLS adapter:', error);
5977
6553
  }
5978
6554
  }
5979
6555
 
5980
- const log$5 = createPrefixedLogger('ADAPTER-LOADER');
6556
+ const log$4 = createPrefixedLogger('ADAPTER-LOADER');
5981
6557
  function loadPlatformAdapters(options = {}) {
5982
6558
  const { mtlsConfig } = options;
5983
6559
  const { platform } = detectPlatform();
5984
- log$5.debug('Loading adapters for platform:', platform);
6560
+ log$4.debug('Loading adapters for platform:', platform);
5985
6561
  const storageAdapters = loadStorageAdapters(platform);
5986
6562
  const networkMonitor = loadNetworkMonitor(platform);
5987
6563
  const cache = loadCacheAdapter(platform);
5988
6564
  const mtls = loadMTLSAdapter(platform, mtlsConfig);
5989
- log$5.debug('Adapters loaded:', {
6565
+ log$4.debug('Adapters loaded:', {
5990
6566
  platform,
5991
6567
  hasStorage: !!storageAdapters.storage,
5992
6568
  hasSecureStorage: !!storageAdapters.secureStorage,
@@ -6012,92 +6588,6 @@ function createACubeMTLSConfig(baseUrl, timeout, autoInitialize = true, forcePor
6012
6588
  };
6013
6589
  }
6014
6590
 
6015
- class ConfigManager {
6016
- constructor(userConfig) {
6017
- this.config = this.buildConfig(userConfig);
6018
- }
6019
- buildConfig(userConfig) {
6020
- return {
6021
- environment: userConfig.environment,
6022
- apiUrl: this.getDefaultApiUrl(userConfig.environment),
6023
- authUrl: this.getDefaultAuthUrl(userConfig.environment),
6024
- timeout: 30000,
6025
- retryAttempts: 3,
6026
- debug: userConfig.debug ?? false,
6027
- customHeaders: {},
6028
- };
6029
- }
6030
- getDefaultApiUrl(environment) {
6031
- switch (environment) {
6032
- case 'production':
6033
- return 'https://ereceipts-it.acubeapi.com';
6034
- case 'development':
6035
- return 'https://ereceipts-it.dev.acubeapi.com';
6036
- case 'sandbox':
6037
- default:
6038
- return 'https://ereceipts-it-sandbox.acubeapi.com';
6039
- }
6040
- }
6041
- getDefaultAuthUrl(environment) {
6042
- switch (environment) {
6043
- case 'production':
6044
- return 'https://common.api.acubeapi.com';
6045
- case 'development':
6046
- case 'sandbox':
6047
- default:
6048
- return 'https://common-sandbox.api.acubeapi.com';
6049
- }
6050
- }
6051
- getConfig() {
6052
- return {
6053
- environment: this.config.environment,
6054
- debug: this.config.debug,
6055
- };
6056
- }
6057
- getApiUrl() {
6058
- return this.config.apiUrl;
6059
- }
6060
- getAuthUrl() {
6061
- return this.config.authUrl;
6062
- }
6063
- getEnvironment() {
6064
- return this.config.environment;
6065
- }
6066
- isDebugEnabled() {
6067
- return this.config.debug;
6068
- }
6069
- getTimeout() {
6070
- return this.config.timeout;
6071
- }
6072
- getRetryAttempts() {
6073
- return this.config.retryAttempts;
6074
- }
6075
- getCustomHeaders() {
6076
- return { ...this.config.customHeaders };
6077
- }
6078
- updateConfig(updates) {
6079
- if (updates.environment) {
6080
- this.config.environment = updates.environment;
6081
- this.config.apiUrl = this.getDefaultApiUrl(updates.environment);
6082
- this.config.authUrl = this.getDefaultAuthUrl(updates.environment);
6083
- }
6084
- if (updates.debug !== undefined) {
6085
- this.config.debug = updates.debug;
6086
- }
6087
- }
6088
- }
6089
-
6090
- class ACubeSDKError extends Error {
6091
- constructor(type, message, originalError, statusCode, violations) {
6092
- super(message);
6093
- this.type = type;
6094
- this.originalError = originalError;
6095
- this.statusCode = statusCode;
6096
- this.name = 'ACubeSDKError';
6097
- this.violations = violations;
6098
- }
6099
- }
6100
-
6101
6591
  const DI_TOKENS = {
6102
6592
  HTTP_PORT: Symbol('HTTP_PORT'),
6103
6593
  BASE_HTTP_PORT: Symbol('BASE_HTTP_PORT'),
@@ -7098,7 +7588,7 @@ class TelemetryRepositoryImpl {
7098
7588
  }
7099
7589
  }
7100
7590
 
7101
- const log$4 = createPrefixedLogger('CACHE-KEY');
7591
+ const log$3 = createPrefixedLogger('CACHE-KEY');
7102
7592
  const URL_PATTERNS = [
7103
7593
  // Receipt (mf1) - specific patterns first
7104
7594
  {
@@ -7113,7 +7603,7 @@ const URL_PATTERNS = [
7113
7603
  },
7114
7604
  { pattern: /^\/mf1\/receipts\/([^/]+)$/, resource: 'receipt' },
7115
7605
  {
7116
- pattern: /^\/mf1\/point-of-sales\/([^/]+)\/receipts$/,
7606
+ pattern: /^\/mf1\/pems\/([^/]+)\/receipts$/,
7117
7607
  resource: 'receipt',
7118
7608
  parent: 'point-of-sale',
7119
7609
  isList: true,
@@ -7130,8 +7620,8 @@ const URL_PATTERNS = [
7130
7620
  { pattern: /^\/mf1\/cash-registers\/([^/]+)$/, resource: 'cash-register' },
7131
7621
  { pattern: /^\/mf1\/cash-registers$/, resource: 'cash-register', isList: true },
7132
7622
  // Point of Sale (mf1)
7133
- { pattern: /^\/mf1\/point-of-sales\/([^/]+)$/, resource: 'point-of-sale' },
7134
- { pattern: /^\/mf1\/point-of-sales$/, resource: 'point-of-sale', isList: true },
7623
+ { pattern: /^\/mf1\/pems\/([^/]+)$/, resource: 'point-of-sale' },
7624
+ { pattern: /^\/mf1\/pems$/, resource: 'point-of-sale', isList: true },
7135
7625
  // Nested resources under merchant (mf2)
7136
7626
  {
7137
7627
  pattern: /^\/mf2\/merchants\/([^/]+)\/suppliers\/([^/]+)$/,
@@ -7158,15 +7648,15 @@ const URL_PATTERNS = [
7158
7648
  },
7159
7649
  // PEM (mf2)
7160
7650
  {
7161
- pattern: /^\/mf2\/point-of-sales\/([^/]+)\/certificates$/,
7651
+ pattern: /^\/mf2\/pems\/([^/]+)\/certificates$/,
7162
7652
  resource: 'pem',
7163
7653
  action: 'certificates',
7164
7654
  },
7165
- { pattern: /^\/mf2\/point-of-sales\/([^/]+)$/, resource: 'pem' },
7655
+ { pattern: /^\/mf2\/pems\/([^/]+)$/, resource: 'pem' },
7166
7656
  // Others
7167
7657
  { pattern: /^\/mf1\/notifications/, resource: 'notification', isList: true },
7168
7658
  {
7169
- pattern: /^\/mf1\/point-of-sales\/([^/]+)\/telemetry$/,
7659
+ pattern: /^\/mf1\/pems\/([^/]+)\/telemetry$/,
7170
7660
  resource: 'telemetry',
7171
7661
  },
7172
7662
  ];
@@ -7191,7 +7681,7 @@ const DEFAULT_TTL = 5 * 60 * 1000; // 5 minutes
7191
7681
  class CacheKeyGenerator {
7192
7682
  constructor(customConfig) {
7193
7683
  this.config = { ...DEFAULT_TTL_CONFIG, ...customConfig };
7194
- log$4.info('CacheKeyGenerator initialized with config:', {
7684
+ log$3.info('CacheKeyGenerator initialized with config:', {
7195
7685
  resources: Object.keys(this.config),
7196
7686
  });
7197
7687
  }
@@ -7201,7 +7691,7 @@ class CacheKeyGenerator {
7201
7691
  // Fallback: use URL as key
7202
7692
  const paramStr = params ? this.serializeParams(params) : '';
7203
7693
  const key = paramStr ? `${url}?${paramStr}` : url;
7204
- log$4.debug('URL not matched, using fallback key:', { url, key });
7694
+ log$3.debug('URL not matched, using fallback key:', { url, key });
7205
7695
  return key;
7206
7696
  }
7207
7697
  const { resource, ids, action, isList, parent } = parsed;
@@ -7209,21 +7699,21 @@ class CacheKeyGenerator {
7209
7699
  const paramStr = params ? this.serializeParams(params) : '';
7210
7700
  const parentPart = parent && ids.length > 0 ? `${parent}=${ids[0]}&` : '';
7211
7701
  const key = `${resource}:list:${parentPart}${paramStr}`;
7212
- log$4.debug('Generated list cache key:', { url, key, resource });
7702
+ log$3.debug('Generated list cache key:', { url, key, resource });
7213
7703
  return key;
7214
7704
  }
7215
7705
  // Single item
7216
7706
  if (ids.length === 0 && action) {
7217
7707
  // Special case for endpoints like /cashiers/me
7218
7708
  const key = `${resource}:${action}`;
7219
- log$4.debug('Generated special action cache key:', { url, key, resource, action });
7709
+ log$3.debug('Generated special action cache key:', { url, key, resource, action });
7220
7710
  return key;
7221
7711
  }
7222
7712
  let key = `${resource}:${ids.join(':')}`;
7223
7713
  if (action) {
7224
7714
  key += `:${action}`;
7225
7715
  }
7226
- log$4.debug('Generated item cache key:', { url, key, resource, ids, action });
7716
+ log$3.debug('Generated item cache key:', { url, key, resource, ids, action });
7227
7717
  return key;
7228
7718
  }
7229
7719
  parseResource(url) {
@@ -7233,23 +7723,23 @@ class CacheKeyGenerator {
7233
7723
  getTTL(url) {
7234
7724
  const resource = this.parseResource(url);
7235
7725
  if (!resource) {
7236
- log$4.debug('No resource found for URL, using default TTL:', { url, ttl: DEFAULT_TTL });
7726
+ log$3.debug('No resource found for URL, using default TTL:', { url, ttl: DEFAULT_TTL });
7237
7727
  return DEFAULT_TTL;
7238
7728
  }
7239
7729
  const ttl = this.config[resource].ttlMs;
7240
- log$4.debug('TTL for resource:', { url, resource, ttlMs: ttl, ttlMin: ttl / 60000 });
7730
+ log$3.debug('TTL for resource:', { url, resource, ttlMs: ttl, ttlMin: ttl / 60000 });
7241
7731
  return ttl;
7242
7732
  }
7243
7733
  shouldCache(url) {
7244
7734
  const parsed = this.parseUrl(url);
7245
7735
  if (!parsed) {
7246
- log$4.debug('URL not recognized, should not cache:', { url });
7736
+ log$3.debug('URL not recognized, should not cache:', { url });
7247
7737
  return false;
7248
7738
  }
7249
7739
  const { resource, isList } = parsed;
7250
7740
  const config = this.config[resource];
7251
7741
  if (isList) {
7252
- log$4.debug('List endpoint cache decision:', {
7742
+ log$3.debug('List endpoint cache decision:', {
7253
7743
  url,
7254
7744
  resource,
7255
7745
  isList: true,
@@ -7257,7 +7747,7 @@ class CacheKeyGenerator {
7257
7747
  });
7258
7748
  return config.cacheList;
7259
7749
  }
7260
- log$4.debug('Item endpoint cache decision:', {
7750
+ log$3.debug('Item endpoint cache decision:', {
7261
7751
  url,
7262
7752
  resource,
7263
7753
  isList: false,
@@ -7268,7 +7758,7 @@ class CacheKeyGenerator {
7268
7758
  getInvalidationPatterns(url, method) {
7269
7759
  const parsed = this.parseUrl(url);
7270
7760
  if (!parsed) {
7271
- log$4.debug('No patterns to invalidate for URL:', { url, method });
7761
+ log$3.debug('No patterns to invalidate for URL:', { url, method });
7272
7762
  return [];
7273
7763
  }
7274
7764
  const { resource, ids, parent } = parsed;
@@ -7290,7 +7780,7 @@ class CacheKeyGenerator {
7290
7780
  if (resource === 'cashier' && (method === 'PUT' || method === 'DELETE')) {
7291
7781
  patterns.push('cashier:me');
7292
7782
  }
7293
- log$4.debug('Invalidation patterns:', { url, method, patterns });
7783
+ log$3.debug('Invalidation patterns:', { url, method, patterns });
7294
7784
  return patterns;
7295
7785
  }
7296
7786
  parseUrl(url) {
@@ -7325,7 +7815,7 @@ class CacheKeyGenerator {
7325
7815
  }
7326
7816
  }
7327
7817
 
7328
- const log$3 = createPrefixedLogger('CACHE');
7818
+ const log$2 = createPrefixedLogger('CACHE');
7329
7819
  class CachingHttpDecorator {
7330
7820
  constructor(http, cache, keyGenerator, networkMonitor, config = {}) {
7331
7821
  this.http = http;
@@ -7335,7 +7825,7 @@ class CachingHttpDecorator {
7335
7825
  this.config = config;
7336
7826
  this.currentOnlineState = true;
7337
7827
  this.authToken = null;
7338
- log$3.info('CachingHttpDecorator initialized', {
7828
+ log$2.info('CachingHttpDecorator initialized', {
7339
7829
  enabled: config.enabled !== false,
7340
7830
  hasNetworkMonitor: !!networkMonitor,
7341
7831
  });
@@ -7345,7 +7835,7 @@ class CachingHttpDecorator {
7345
7835
  if (this.networkMonitor) {
7346
7836
  this.networkSubscription = this.networkMonitor.online$.subscribe((online) => {
7347
7837
  if (this.currentOnlineState !== online) {
7348
- log$3.info('Network state changed:', { online });
7838
+ log$2.info('Network state changed:', { online });
7349
7839
  }
7350
7840
  this.currentOnlineState = online;
7351
7841
  });
@@ -7364,19 +7854,19 @@ class CachingHttpDecorator {
7364
7854
  const startTime = Date.now();
7365
7855
  // Check if caching is disabled globally
7366
7856
  if (this.config.enabled === false) {
7367
- log$3.debug('GET (cache disabled globally):', { url });
7857
+ log$2.debug('GET (cache disabled globally):', { url });
7368
7858
  return this.http.get(url, config);
7369
7859
  }
7370
7860
  // Check if this URL should be cached
7371
7861
  const shouldCache = this.keyGenerator.shouldCache(url);
7372
7862
  if (!shouldCache) {
7373
- log$3.debug('GET (not cacheable - likely a list endpoint):', { url });
7863
+ log$2.debug('GET (not cacheable - likely a list endpoint):', { url });
7374
7864
  return this.http.get(url, config);
7375
7865
  }
7376
7866
  const cacheKey = this.keyGenerator.generate(url, config?.params);
7377
7867
  const ttl = this.keyGenerator.getTTL(url);
7378
7868
  const resource = this.keyGenerator.parseResource(url);
7379
- log$3.info('GET request starting:', {
7869
+ log$2.info('GET request starting:', {
7380
7870
  url,
7381
7871
  resource,
7382
7872
  cacheKey,
@@ -7389,18 +7879,18 @@ class CachingHttpDecorator {
7389
7879
  try {
7390
7880
  cached = await this.cache.get(cacheKey);
7391
7881
  if (cached) {
7392
- log$3.debug('Cache entry found:', {
7882
+ log$2.debug('Cache entry found:', {
7393
7883
  cacheKey,
7394
7884
  timestamp: new Date(cached.timestamp).toISOString(),
7395
7885
  ageMs: Date.now() - cached.timestamp,
7396
7886
  });
7397
7887
  }
7398
7888
  else {
7399
- log$3.debug('Cache entry not found:', { cacheKey });
7889
+ log$2.debug('Cache entry not found:', { cacheKey });
7400
7890
  }
7401
7891
  }
7402
7892
  catch (error) {
7403
- log$3.warn('Cache lookup failed:', {
7893
+ log$2.warn('Cache lookup failed:', {
7404
7894
  cacheKey,
7405
7895
  error: error instanceof Error ? error.message : error,
7406
7896
  });
@@ -7408,7 +7898,7 @@ class CachingHttpDecorator {
7408
7898
  if (cached) {
7409
7899
  const age = Date.now() - cached.timestamp;
7410
7900
  const isExpired = age >= ttl;
7411
- log$3.debug('Cache analysis:', {
7901
+ log$2.debug('Cache analysis:', {
7412
7902
  cacheKey,
7413
7903
  ageMs: age,
7414
7904
  ageSec: Math.round(age / 1000),
@@ -7419,7 +7909,7 @@ class CachingHttpDecorator {
7419
7909
  // If within TTL, return cached data
7420
7910
  if (!isExpired) {
7421
7911
  const duration = Date.now() - startTime;
7422
- log$3.info('CACHE HIT:', {
7912
+ log$2.info('CACHE HIT:', {
7423
7913
  url,
7424
7914
  cacheKey,
7425
7915
  ageMs: age,
@@ -7434,7 +7924,7 @@ class CachingHttpDecorator {
7434
7924
  // If offline and cache is stale, return stale data
7435
7925
  if (!this.isOnline()) {
7436
7926
  const duration = Date.now() - startTime;
7437
- log$3.info('CACHE STALE (offline):', {
7927
+ log$2.info('CACHE STALE (offline):', {
7438
7928
  url,
7439
7929
  cacheKey,
7440
7930
  ageMs: age,
@@ -7446,25 +7936,25 @@ class CachingHttpDecorator {
7446
7936
  headers: { 'x-cache': 'STALE' },
7447
7937
  };
7448
7938
  }
7449
- log$3.debug('Cache expired, fetching fresh data:', { cacheKey, ageMs: age, ttlMs: ttl });
7939
+ log$2.debug('Cache expired, fetching fresh data:', { cacheKey, ageMs: age, ttlMs: ttl });
7450
7940
  }
7451
7941
  // Fetch fresh data
7452
7942
  try {
7453
- log$3.debug('Fetching from network:', { url });
7943
+ log$2.debug('Fetching from network:', { url });
7454
7944
  const response = await this.http.get(url, config);
7455
7945
  // Cache the response
7456
7946
  try {
7457
7947
  await this.cache.set(cacheKey, response.data);
7458
- log$3.debug('Response cached successfully:', { cacheKey });
7948
+ log$2.debug('Response cached successfully:', { cacheKey });
7459
7949
  }
7460
7950
  catch (error) {
7461
- log$3.error('Failed to cache response:', {
7951
+ log$2.error('Failed to cache response:', {
7462
7952
  cacheKey,
7463
7953
  error: error instanceof Error ? error.message : error,
7464
7954
  });
7465
7955
  }
7466
7956
  const duration = Date.now() - startTime;
7467
- log$3.info('CACHE MISS (fetched fresh):', {
7957
+ log$2.info('CACHE MISS (fetched fresh):', {
7468
7958
  url,
7469
7959
  cacheKey,
7470
7960
  status: response.status,
@@ -7479,7 +7969,7 @@ class CachingHttpDecorator {
7479
7969
  // On error, return stale cache if available
7480
7970
  if (cached) {
7481
7971
  const duration = Date.now() - startTime;
7482
- log$3.warn('CACHE STALE (network error):', {
7972
+ log$2.warn('CACHE STALE (network error):', {
7483
7973
  url,
7484
7974
  cacheKey,
7485
7975
  error: error instanceof Error ? error.message : 'Unknown error',
@@ -7491,7 +7981,7 @@ class CachingHttpDecorator {
7491
7981
  headers: { 'x-cache': 'STALE' },
7492
7982
  };
7493
7983
  }
7494
- log$3.error('Network error with no cache fallback:', {
7984
+ log$2.error('Network error with no cache fallback:', {
7495
7985
  url,
7496
7986
  error: error instanceof Error ? error.message : error,
7497
7987
  });
@@ -7499,31 +7989,35 @@ class CachingHttpDecorator {
7499
7989
  }
7500
7990
  }
7501
7991
  async post(url, data, config) {
7502
- log$3.info('POST request:', { url });
7992
+ log$2.info('POST request:', { url });
7503
7993
  const response = await this.http.post(url, data, config);
7504
7994
  await this.invalidateRelated(url, 'POST');
7505
7995
  return response;
7506
7996
  }
7507
7997
  async put(url, data, config) {
7508
- log$3.info('PUT request:', { url });
7998
+ log$2.info('PUT request:', { url });
7509
7999
  const response = await this.http.put(url, data, config);
7510
8000
  await this.invalidateRelated(url, 'PUT');
7511
8001
  return response;
7512
8002
  }
7513
8003
  async patch(url, data, config) {
7514
- log$3.info('PATCH request:', { url });
8004
+ log$2.info('PATCH request:', { url });
7515
8005
  const response = await this.http.patch(url, data, config);
7516
8006
  await this.invalidateRelated(url, 'PATCH');
7517
8007
  return response;
7518
8008
  }
7519
8009
  async delete(url, config) {
7520
- log$3.info('DELETE request:', { url });
8010
+ log$2.info('DELETE request:', { url });
7521
8011
  const response = await this.http.delete(url, config);
7522
8012
  await this.invalidateRelated(url, 'DELETE');
7523
8013
  return response;
7524
8014
  }
7525
8015
  setAuthToken(token) {
7526
- log$3.debug('Auth token updated:', { hasToken: !!token });
8016
+ log$2.debug('CachingHttpDecorator.setAuthToken called:', {
8017
+ hasToken: !!token,
8018
+ tokenPrefix: token?.substring(0, 20),
8019
+ underlyingHttpType: this.http.constructor.name,
8020
+ });
7527
8021
  this.authToken = token;
7528
8022
  this.http.setAuthToken(token);
7529
8023
  }
@@ -7533,17 +8027,17 @@ class CachingHttpDecorator {
7533
8027
  async invalidateRelated(url, method) {
7534
8028
  const patterns = this.keyGenerator.getInvalidationPatterns(url, method);
7535
8029
  if (patterns.length === 0) {
7536
- log$3.debug('No cache patterns to invalidate:', { url, method });
8030
+ log$2.debug('No cache patterns to invalidate:', { url, method });
7537
8031
  return;
7538
8032
  }
7539
- log$3.info('Invalidating cache patterns:', { url, method, patterns });
8033
+ log$2.info('Invalidating cache patterns:', { url, method, patterns });
7540
8034
  for (const pattern of patterns) {
7541
8035
  try {
7542
8036
  await this.cache.invalidate(pattern);
7543
- log$3.debug('Cache pattern invalidated:', { pattern });
8037
+ log$2.debug('Cache pattern invalidated:', { pattern });
7544
8038
  }
7545
8039
  catch (error) {
7546
- log$3.error('Failed to invalidate pattern:', {
8040
+ log$2.error('Failed to invalidate pattern:', {
7547
8041
  pattern,
7548
8042
  error: error instanceof Error ? error.message : error,
7549
8043
  });
@@ -7551,12 +8045,13 @@ class CachingHttpDecorator {
7551
8045
  }
7552
8046
  }
7553
8047
  destroy() {
7554
- log$3.debug('CachingHttpDecorator destroyed');
8048
+ log$2.debug('CachingHttpDecorator destroyed');
7555
8049
  this.networkSubscription?.unsubscribe();
7556
8050
  }
7557
8051
  }
7558
8052
 
7559
- const log$2 = createPrefixedLogger('HTTP-MTLS');
8053
+ const logJwt = createPrefixedLogger('HTTP-JWT');
8054
+ const logMtls = createPrefixedLogger('HTTP-MTLS');
7560
8055
  class AxiosHttpAdapter {
7561
8056
  constructor(config) {
7562
8057
  this.authToken = null;
@@ -7574,23 +8069,30 @@ class AxiosHttpAdapter {
7574
8069
  }
7575
8070
  setMTLSAdapter(adapter) {
7576
8071
  this.mtlsAdapter = adapter;
7577
- log$2.debug('mTLS adapter configured:', !!adapter);
8072
+ logMtls.debug('mTLS adapter configured:', !!adapter);
7578
8073
  }
7579
8074
  setAuthStrategy(strategy) {
7580
8075
  this.authStrategy = strategy;
7581
- log$2.debug('Auth strategy configured:', !!strategy);
8076
+ logJwt.debug('Auth strategy configured:', !!strategy);
7582
8077
  }
7583
8078
  async shouldUseMTLS(url, method) {
7584
8079
  if (!this.mtlsAdapter) {
8080
+ logJwt.debug(`No mTLS adapter, using JWT for ${method} ${url}`);
7585
8081
  return false;
7586
8082
  }
7587
8083
  if (this.authStrategy) {
7588
8084
  const config = await this.authStrategy.determineAuthConfig(url, method);
7589
- log$2.debug(`Auth config for ${method} ${url}:`, config);
8085
+ const logger = config.mode === 'mtls' ? logMtls : logJwt;
8086
+ logger.debug(`Auth config for ${method} ${url}:`, config);
7590
8087
  return config.mode === 'mtls';
7591
8088
  }
7592
8089
  // Fallback: use mTLS for mf1/mf2 endpoints if no strategy
7593
- return url.startsWith('/mf1') || url.startsWith('/mf2');
8090
+ // This should rarely happen - only before SDK is fully initialized
8091
+ const useMtls = url.startsWith('/mf1') || url.startsWith('/mf2');
8092
+ if (useMtls) {
8093
+ logMtls.warn(`No auth strategy set, falling back to mTLS for ${method} ${url}`);
8094
+ }
8095
+ return useMtls;
7594
8096
  }
7595
8097
  async makeMTLSRequest(url, method, data, config) {
7596
8098
  if (!this.mtlsAdapter) {
@@ -7603,10 +8105,10 @@ class AxiosHttpAdapter {
7603
8105
  };
7604
8106
  if (this.authToken) {
7605
8107
  headers['Authorization'] = `Bearer ${this.authToken}`;
7606
- log$2.debug('JWT token present for mTLS request');
8108
+ logMtls.debug('JWT token present for mTLS request');
7607
8109
  }
7608
8110
  else {
7609
- log$2.warn('No JWT token for mTLS request');
8111
+ logMtls.warn('No JWT token for mTLS request');
7610
8112
  }
7611
8113
  const mtlsConfig = {
7612
8114
  url: fullUrl,
@@ -7615,15 +8117,15 @@ class AxiosHttpAdapter {
7615
8117
  data,
7616
8118
  timeout: config?.timeout,
7617
8119
  };
7618
- log$2.debug(`mTLS ${method} ${fullUrl}`);
8120
+ logMtls.debug(`mTLS ${method} ${fullUrl}`);
7619
8121
  if (data) {
7620
- log$2.debug('Request body:', data);
8122
+ logMtls.debug('Request body:', data);
7621
8123
  }
7622
8124
  try {
7623
8125
  const response = await this.mtlsAdapter.request(mtlsConfig);
7624
- log$2.debug(`mTLS Response ${response.status} from ${fullUrl}`);
8126
+ logMtls.debug(`mTLS Response ${response.status} from ${fullUrl}`);
7625
8127
  if (response.data) {
7626
- log$2.debug('Response body:', response.data);
8128
+ logMtls.debug('Response body:', response.data);
7627
8129
  }
7628
8130
  return {
7629
8131
  data: response.data,
@@ -7632,11 +8134,11 @@ class AxiosHttpAdapter {
7632
8134
  };
7633
8135
  }
7634
8136
  catch (error) {
7635
- log$2.error(`mTLS Response error from ${fullUrl}:`, error);
8137
+ logMtls.error(`mTLS Response error from ${fullUrl}:`, error);
7636
8138
  if (error && typeof error === 'object' && 'response' in error) {
7637
8139
  const axiosError = error;
7638
8140
  if (axiosError.response?.data) {
7639
- log$2.error('Response body:', axiosError.response.data);
8141
+ logMtls.error('Response body:', axiosError.response.data);
7640
8142
  }
7641
8143
  }
7642
8144
  throw error;
@@ -7651,36 +8153,46 @@ class AxiosHttpAdapter {
7651
8153
  this.client.interceptors.request.use((config) => {
7652
8154
  if (this.authToken) {
7653
8155
  config.headers.Authorization = `Bearer ${this.authToken}`;
7654
- log$2.debug('Adding JWT token to request');
8156
+ logJwt.debug('Adding JWT token to request', {
8157
+ tokenPrefix: this.authToken.substring(0, 30) + '...',
8158
+ tokenLength: this.authToken.length,
8159
+ });
7655
8160
  }
7656
8161
  else {
7657
- log$2.warn('No JWT token available for request:', { url: config.url });
8162
+ logJwt.warn('No JWT token available for request:', { url: config.url });
7658
8163
  }
7659
8164
  const method = config.method?.toUpperCase() ?? 'UNKNOWN';
7660
- log$2.debug(`→ ${method} ${config.url}`);
8165
+ const authHeader = config.headers.Authorization;
8166
+ // Log full request details for debugging
8167
+ logJwt.info(`→ ${method} ${config.url}`, {
8168
+ baseURL: config.baseURL,
8169
+ fullURL: `${config.baseURL}${config.url}`,
8170
+ hasAuthHeader: !!authHeader,
8171
+ authHeaderValue: authHeader ? `${String(authHeader).substring(0, 50)}...` : 'MISSING',
8172
+ });
7661
8173
  if (config.params && Object.keys(config.params).length > 0) {
7662
- log$2.debug('Request params:', config.params);
8174
+ logJwt.debug('Request params:', config.params);
7663
8175
  }
7664
8176
  if (config.data) {
7665
- log$2.debug('Request body:', config.data);
8177
+ logJwt.debug('Request body:', config.data);
7666
8178
  }
7667
8179
  return config;
7668
8180
  }, (error) => {
7669
- log$2.error('Request error:', error);
8181
+ logJwt.error('Request error:', error);
7670
8182
  return Promise.reject(error);
7671
8183
  });
7672
8184
  this.client.interceptors.response.use((response) => {
7673
8185
  const method = response.config.method?.toUpperCase() ?? 'UNKNOWN';
7674
- log$2.debug(`← ${method} ${response.status} ${response.config.url}`);
8186
+ logJwt.debug(`← ${method} ${response.status} ${response.config.url}`);
7675
8187
  if (response.data) {
7676
- log$2.debug('Response body:', response.data);
8188
+ logJwt.debug('Response body:', response.data);
7677
8189
  }
7678
8190
  return response;
7679
8191
  }, (error) => {
7680
8192
  const method = error.config?.method?.toUpperCase() ?? 'UNKNOWN';
7681
- log$2.error(`← ${method} ${error.response?.status ?? 'ERR'} ${error.config?.url ?? 'unknown'}`);
8193
+ logJwt.error(`← ${method} ${error.response?.status ?? 'ERR'} ${error.config?.url ?? 'unknown'}`);
7682
8194
  if (error.response?.data) {
7683
- log$2.error('Response body:', error.response.data);
8195
+ logJwt.error('Response body:', error.response.data);
7684
8196
  }
7685
8197
  return Promise.reject(error);
7686
8198
  });
@@ -7750,7 +8262,10 @@ class AxiosHttpAdapter {
7750
8262
  return this.mapResponse(response);
7751
8263
  }
7752
8264
  setAuthToken(token) {
7753
- log$2.info('setAuthToken called:', { hasToken: !!token, tokenPrefix: token?.substring(0, 20) });
8265
+ logJwt.info('setAuthToken called:', {
8266
+ hasToken: !!token,
8267
+ tokenPrefix: token?.substring(0, 20),
8268
+ });
7754
8269
  this.authToken = token;
7755
8270
  }
7756
8271
  getAuthToken() {
@@ -7966,6 +8481,11 @@ class ACubeSDK {
7966
8481
  const tokenStorage = this.container.get(DI_TOKENS.TOKEN_STORAGE_PORT);
7967
8482
  const httpPort = this.container.get(DI_TOKENS.HTTP_PORT);
7968
8483
  const baseHttpPort = this.container.get(DI_TOKENS.BASE_HTTP_PORT);
8484
+ log$1.debug('HTTP ports initialized', {
8485
+ httpPortType: httpPort.constructor.name,
8486
+ baseHttpPortType: baseHttpPort.constructor.name,
8487
+ areSameInstance: httpPort === baseHttpPort,
8488
+ });
7969
8489
  log$1.debug('Initializing authentication service');
7970
8490
  this.authService = new AuthenticationService(httpPort, tokenStorage, {
7971
8491
  authUrl: this.config.getAuthUrl(),
@@ -7998,12 +8518,22 @@ class ACubeSDK {
7998
8518
  this.offlineManager.sync().catch(() => { });
7999
8519
  }
8000
8520
  });
8001
- if (await this.authService.isAuthenticated()) {
8521
+ const isAuth = await this.authService.isAuthenticated();
8522
+ log$1.debug('Checking authentication status during init', { isAuthenticated: isAuth });
8523
+ if (isAuth) {
8002
8524
  const token = await this.authService.getAccessToken();
8525
+ log$1.debug('Token retrieved during init', {
8526
+ hasToken: !!token,
8527
+ tokenPrefix: token?.substring(0, 20),
8528
+ });
8003
8529
  if (token) {
8004
8530
  httpPort.setAuthToken(token);
8531
+ log$1.info('Auth token set on HTTP port during initialization');
8005
8532
  }
8006
8533
  }
8534
+ else {
8535
+ log$1.warn('User not authenticated during SDK init - token will be set after login');
8536
+ }
8007
8537
  if (this.adapters?.mtls && 'setMTLSAdapter' in baseHttpPort) {
8008
8538
  log$1.debug('Connecting mTLS adapter to HTTP port');
8009
8539
  const httpWithMtls = baseHttpPort;
@@ -8822,842 +9352,401 @@ class SDKManager {
8822
9352
  this.appStateService.state$.subscribe(this.events.onAppStateChanged);
8823
9353
  }
8824
9354
  if (this.events?.onTelemetryStateChanged) {
8825
- this.telemetryService.state$.subscribe(this.events.onTelemetryStateChanged);
8826
- }
8827
- this.isInitialized = true;
8828
- // Only start polling for MERCHANT/CASHIER users (SUPPLIER gets 401 on these endpoints)
8829
- const user = await this.sdk.getCurrentUser();
8830
- const canPoll = user && hasAnyRole(user.roles, ['ROLE_MERCHANT', 'ROLE_CASHIER']);
8831
- if (canPoll) {
8832
- this.notificationService.startPolling();
8833
- await this.startTelemetryPollingAuto();
8834
- this.isPollingActive = true;
8835
- }
8836
- // AppStateService remains active for all users (handles OFFLINE network state)
8837
- }
8838
- /**
8839
- * Observable stream of app state
8840
- * Emits AppState with mode (NORMAL, WARNING, BLOCKED, OFFLINE)
8841
- */
8842
- get appState$() {
8843
- this.ensureInitialized();
8844
- return this.appStateService.state$;
8845
- }
8846
- /**
8847
- * Observable stream of app mode only
8848
- * Emits AppMode with distinctUntilChanged
8849
- */
8850
- get mode$() {
8851
- this.ensureInitialized();
8852
- return this.appStateService.mode$;
8853
- }
8854
- /**
8855
- * Observable stream indicating if app is blocked
8856
- */
8857
- get isBlocked$() {
8858
- this.ensureInitialized();
8859
- return this.appStateService.isBlocked$;
8860
- }
8861
- /**
8862
- * Observable stream of warning state with countdown
8863
- */
8864
- get warning$() {
8865
- this.ensureInitialized();
8866
- return this.appStateService.warning$;
8867
- }
8868
- /**
8869
- * Observable stream of telemetry state (data, isLoading, isCached, error)
8870
- */
8871
- get telemetryState$() {
8872
- this.ensureInitialized();
8873
- return this.telemetryService.state$;
8874
- }
8875
- /**
8876
- * Get the pemId from the installed certificate
8877
- */
8878
- async getPemId() {
8879
- this.ensureInitialized();
8880
- try {
8881
- const certInfo = await this.sdk.getCertificatesInfo();
8882
- return certInfo?.pemId ?? null;
8883
- }
8884
- catch {
8885
- return null;
8886
- }
8887
- }
8888
- /**
8889
- * Start polling telemetry using the pemId from installed certificate
8890
- * Returns the pemId if successful, null if no certificate is installed
8891
- */
8892
- async startTelemetryPollingAuto() {
8893
- this.ensureInitialized();
8894
- const pemId = await this.getPemId();
8895
- if (pemId) {
8896
- this.telemetryService.startPolling(pemId);
8897
- }
8898
- return pemId;
8899
- }
8900
- /**
8901
- * Start polling telemetry for a specific PEM
8902
- */
8903
- startTelemetryPolling(pemId) {
8904
- this.ensureInitialized();
8905
- this.telemetryService.startPolling(pemId);
8906
- }
8907
- /**
8908
- * Stop telemetry polling
8909
- */
8910
- stopTelemetryPolling() {
8911
- this.ensureInitialized();
8912
- this.telemetryService.stopPolling();
8913
- }
8914
- /**
8915
- * Get simplified services for product use
8916
- */
8917
- getServices() {
8918
- this.ensureInitialized();
8919
- const sdk = this.sdk;
8920
- const telemetryService = this.telemetryService;
8921
- return {
8922
- receipts: sdk.receipts,
8923
- merchants: sdk.merchants,
8924
- cashiers: sdk.cashiers,
8925
- cashRegisters: sdk.cashRegisters,
8926
- pointOfSales: sdk.pointOfSales,
8927
- suppliers: sdk.suppliers,
8928
- pems: sdk.pems,
8929
- dailyReports: sdk.dailyReports,
8930
- journals: sdk.journals,
8931
- telemetry: {
8932
- startPollingAuto: () => this.startTelemetryPollingAuto(),
8933
- startPolling: (pemId) => telemetryService.startPolling(pemId),
8934
- stopPolling: () => telemetryService.stopPolling(),
8935
- getTelemetry: (pemId) => telemetryService.getTelemetry(pemId),
8936
- refreshTelemetry: (pemId) => telemetryService.refreshTelemetry(pemId),
8937
- triggerSync: () => telemetryService.triggerSync(),
8938
- clearTelemetry: () => telemetryService.clearTelemetry(),
8939
- getPemId: () => this.getPemId(),
8940
- },
8941
- login: (credentials) => sdk.login(credentials),
8942
- logout: () => sdk.logout(),
8943
- getCurrentUser: () => sdk.getCurrentUser(),
8944
- isAuthenticated: () => sdk.isAuthenticated(),
8945
- storeCertificate: (certificate, privateKey, options) => sdk.storeCertificate(certificate, privateKey, options),
8946
- hasCertificate: () => sdk.hasCertificate(),
8947
- clearCertificate: () => sdk.clearCertificate(),
8948
- isOnline: () => sdk.isOnline(),
8949
- };
9355
+ this.telemetryService.state$.subscribe(this.events.onTelemetryStateChanged);
9356
+ }
9357
+ this.isInitialized = true;
9358
+ // Only start polling for MERCHANT/CASHIER users (SUPPLIER gets 401 on these endpoints)
9359
+ const user = await this.sdk.getCurrentUser();
9360
+ const canPoll = user && hasAnyRole(user.roles, ['ROLE_MERCHANT', 'ROLE_CASHIER']);
9361
+ if (canPoll) {
9362
+ this.notificationService.startPolling();
9363
+ await this.startTelemetryPollingAuto();
9364
+ this.isPollingActive = true;
9365
+ }
9366
+ // AppStateService remains active for all users (handles OFFLINE network state)
8950
9367
  }
8951
9368
  /**
8952
- * Manually trigger a notification sync
9369
+ * Observable stream of app state
9370
+ * Emits AppState with mode (NORMAL, WARNING, BLOCKED, OFFLINE)
8953
9371
  */
8954
- async syncNotifications() {
9372
+ get appState$() {
8955
9373
  this.ensureInitialized();
8956
- await this.notificationService.triggerSync();
9374
+ return this.appStateService.state$;
8957
9375
  }
8958
9376
  /**
8959
- * Manually trigger a telemetry sync
9377
+ * Observable stream of app mode only
9378
+ * Emits AppMode with distinctUntilChanged
8960
9379
  */
8961
- async syncTelemetry() {
9380
+ get mode$() {
8962
9381
  this.ensureInitialized();
8963
- return this.telemetryService.triggerSync();
9382
+ return this.appStateService.mode$;
8964
9383
  }
8965
9384
  /**
8966
- * Check if the manager is initialized
9385
+ * Observable stream indicating if app is blocked
8967
9386
  */
8968
- getIsInitialized() {
8969
- return this.isInitialized;
9387
+ get isBlocked$() {
9388
+ this.ensureInitialized();
9389
+ return this.appStateService.isBlocked$;
8970
9390
  }
8971
9391
  /**
8972
- * Get the underlying SDK instance (for advanced use cases)
9392
+ * Observable stream of warning state with countdown
8973
9393
  */
8974
- getSDK() {
9394
+ get warning$() {
8975
9395
  this.ensureInitialized();
8976
- return this.sdk;
8977
- }
8978
- cleanup() {
8979
- this.notificationService?.destroy();
8980
- this.telemetryService?.destroy();
8981
- this.appStateService?.destroy();
8982
- this.sdk?.destroy();
8983
- this.notificationService = null;
8984
- this.telemetryService = null;
8985
- this.appStateService = null;
8986
- this.sdk = null;
8987
- this.isInitialized = false;
8988
- this.isPollingActive = false;
8989
- }
8990
- ensureInitialized() {
8991
- if (!this.isInitialized) {
8992
- throw new ACubeSDKError('SDK_NOT_INITIALIZED', 'SDKManager not initialized. Call initialize() first.');
8993
- }
8994
- }
8995
- }
8996
- SDKManager.instance = null;
8997
-
8998
- const RECEIPT_READY = 'ready';
8999
- const RECEIPT_SENT = 'sent';
9000
- const RECEIPT_SORT_DESCENDING = 'descending';
9001
- const RECEIPT_SORT_ASCENDING = 'ascending';
9002
-
9003
- const log = createPrefixedLogger('CACHE-HANDLER');
9004
- class CacheHandler {
9005
- constructor(cache, networkMonitor) {
9006
- this.cache = cache;
9007
- this.networkMonitor = networkMonitor;
9008
- this.currentOnlineState = true;
9009
- this.setupNetworkMonitoring();
9010
- }
9011
- setupNetworkMonitoring() {
9012
- if (this.networkMonitor) {
9013
- this.networkSubscription = this.networkMonitor.online$.subscribe((online) => {
9014
- this.currentOnlineState = online;
9015
- });
9016
- }
9017
- }
9018
- isOnline() {
9019
- if (this.networkMonitor) {
9020
- return this.currentOnlineState;
9021
- }
9022
- if (typeof navigator !== 'undefined' && 'onLine' in navigator) {
9023
- return navigator.onLine;
9024
- }
9025
- return false;
9026
- }
9027
- async handleCachedRequest(url, requestFn, config) {
9028
- if (!this.cache || config?.useCache === false) {
9029
- const response = await requestFn();
9030
- return response.data;
9031
- }
9032
- const cacheKey = this.generateCacheKey(url);
9033
- const online = this.isOnline();
9034
- log.debug('Request:', { url, cacheKey, online });
9035
- if (online) {
9036
- try {
9037
- const response = await requestFn();
9038
- if (this.cache) {
9039
- await this.cache.set(cacheKey, response.data).catch((error) => {
9040
- log.error('Failed to cache:', error instanceof Error ? error.message : error);
9041
- });
9042
- }
9043
- return response.data;
9044
- }
9045
- catch (error) {
9046
- const cached = await this.cache.get(cacheKey).catch(() => null);
9047
- if (cached) {
9048
- log.debug('Network failed, using cache fallback');
9049
- return cached.data;
9050
- }
9051
- throw error;
9052
- }
9053
- }
9054
- else {
9055
- const cached = await this.cache.get(cacheKey).catch(() => null);
9056
- if (cached) {
9057
- log.debug('Offline, returning cached data');
9058
- return cached.data;
9059
- }
9060
- throw new Error('Offline: No cached data available');
9061
- }
9396
+ return this.appStateService.warning$;
9062
9397
  }
9063
- generateCacheKey(url) {
9064
- return url;
9398
+ /**
9399
+ * Observable stream of telemetry state (data, isLoading, isCached, error)
9400
+ */
9401
+ get telemetryState$() {
9402
+ this.ensureInitialized();
9403
+ return this.telemetryService.state$;
9065
9404
  }
9066
- async invalidateCache(pattern) {
9067
- if (!this.cache)
9068
- return;
9405
+ /**
9406
+ * Get the pemId from the installed certificate
9407
+ */
9408
+ async getPemId() {
9409
+ this.ensureInitialized();
9069
9410
  try {
9070
- await this.cache.invalidate(pattern);
9411
+ const certInfo = await this.sdk.getCertificatesInfo();
9412
+ return certInfo?.pemId ?? null;
9071
9413
  }
9072
- catch (error) {
9073
- log.error('Invalidation failed:', error instanceof Error ? error.message : error);
9414
+ catch {
9415
+ return null;
9074
9416
  }
9075
9417
  }
9076
- getCacheStatus() {
9077
- return {
9078
- available: !!this.cache,
9079
- networkMonitorAvailable: !!this.networkMonitor,
9080
- isOnline: this.isOnline(),
9081
- };
9082
- }
9083
- destroy() {
9084
- this.networkSubscription?.unsubscribe();
9085
- }
9086
- }
9087
-
9088
- function transformError(error) {
9089
- if (axios.isAxiosError(error)) {
9090
- const response = error.response;
9091
- if (!response) {
9092
- return new ACubeSDKError('NETWORK_ERROR', 'Network error occurred', error);
9093
- }
9094
- const status = response.status;
9095
- const data = response.data;
9096
- const violations = data?.violations;
9097
- let message = 'Unknown error occurred';
9098
- if (data?.detail) {
9099
- message = data.detail;
9100
- }
9101
- else if (data?.title) {
9102
- message = data.title;
9103
- }
9104
- else if (error.message) {
9105
- message = error.message;
9106
- }
9107
- switch (status) {
9108
- case 400:
9109
- return new ACubeSDKError('VALIDATION_ERROR', message, error, status, violations);
9110
- case 401:
9111
- return new ACubeSDKError('AUTH_ERROR', message, error, status, violations);
9112
- case 403:
9113
- return new ACubeSDKError('FORBIDDEN_ERROR', message, error, status, violations);
9114
- case 404:
9115
- return new ACubeSDKError('NOT_FOUND_ERROR', message, error, status, violations);
9116
- case 422:
9117
- return new ACubeSDKError('VALIDATION_ERROR', message, error, status, violations);
9118
- default:
9119
- return new ACubeSDKError('UNKNOWN_ERROR', message, error, status, violations);
9418
+ /**
9419
+ * Start polling telemetry using the pemId from installed certificate
9420
+ * Returns the pemId if successful, null if no certificate is installed
9421
+ */
9422
+ async startTelemetryPollingAuto() {
9423
+ this.ensureInitialized();
9424
+ const pemId = await this.getPemId();
9425
+ if (pemId) {
9426
+ this.telemetryService.startPolling(pemId);
9120
9427
  }
9428
+ return pemId;
9121
9429
  }
9122
- return new ACubeSDKError('UNKNOWN_ERROR', 'Unknown error occurred', error);
9123
- }
9124
-
9125
- exports.ErrorCategory = void 0;
9126
- (function (ErrorCategory) {
9127
- ErrorCategory["SERVER_ERROR"] = "SERVER_ERROR";
9128
- ErrorCategory["CLIENT_ERROR"] = "CLIENT_ERROR";
9129
- ErrorCategory["AUTH_ERROR"] = "AUTH_ERROR";
9130
- ErrorCategory["CERTIFICATE_ERROR"] = "CERTIFICATE_ERROR";
9131
- ErrorCategory["NETWORK_ERROR"] = "NETWORK_ERROR";
9132
- ErrorCategory["UNKNOWN_ERROR"] = "UNKNOWN_ERROR";
9133
- })(exports.ErrorCategory || (exports.ErrorCategory = {}));
9134
- function extractStatusCode(error) {
9135
- if (error instanceof MTLSError && error.statusCode) {
9136
- return error.statusCode;
9137
- }
9138
- const errorObj = error;
9139
- if (errorObj?.response?.status) {
9140
- return errorObj.response.status;
9141
- }
9142
- if (typeof errorObj?.statusCode === 'number') {
9143
- return errorObj.statusCode;
9144
- }
9145
- return undefined;
9146
- }
9147
- function classifyError(error) {
9148
- const statusCode = extractStatusCode(error);
9149
- const errorMessage = error instanceof Error ? error.message : String(error);
9150
- if (statusCode && statusCode >= 500 && statusCode < 600) {
9151
- return {
9152
- category: exports.ErrorCategory.SERVER_ERROR,
9153
- statusCode,
9154
- message: errorMessage,
9155
- shouldRetry: false,
9156
- userMessage: `Server error (${statusCode}): The server encountered an error.`,
9157
- };
9158
- }
9159
- if (statusCode === 401 || statusCode === 403) {
9160
- return {
9161
- category: exports.ErrorCategory.AUTH_ERROR,
9162
- statusCode,
9163
- message: errorMessage,
9164
- shouldRetry: false,
9165
- userMessage: `Authentication error (${statusCode}): Invalid credentials or insufficient permissions.`,
9166
- };
9167
- }
9168
- if (statusCode && statusCode >= 400 && statusCode < 500) {
9169
- return {
9170
- category: exports.ErrorCategory.CLIENT_ERROR,
9171
- statusCode,
9172
- message: errorMessage,
9173
- shouldRetry: false,
9174
- userMessage: `Request error (${statusCode}): ${errorMessage}`,
9175
- };
9430
+ /**
9431
+ * Start polling telemetry for a specific PEM
9432
+ */
9433
+ startTelemetryPolling(pemId) {
9434
+ this.ensureInitialized();
9435
+ this.telemetryService.startPolling(pemId);
9176
9436
  }
9177
- if (error instanceof MTLSError) {
9178
- return {
9179
- category: exports.ErrorCategory.CERTIFICATE_ERROR,
9180
- statusCode,
9181
- message: errorMessage,
9182
- shouldRetry: true,
9183
- userMessage: 'Certificate error: Unable to establish secure connection.',
9184
- };
9437
+ /**
9438
+ * Stop telemetry polling
9439
+ */
9440
+ stopTelemetryPolling() {
9441
+ this.ensureInitialized();
9442
+ this.telemetryService.stopPolling();
9185
9443
  }
9186
- if (!statusCode &&
9187
- (errorMessage.toLowerCase().includes('network') ||
9188
- errorMessage.toLowerCase().includes('timeout') ||
9189
- errorMessage.toLowerCase().includes('connection'))) {
9444
+ /**
9445
+ * Get simplified services for product use
9446
+ */
9447
+ getServices() {
9448
+ this.ensureInitialized();
9449
+ const sdk = this.sdk;
9450
+ const telemetryService = this.telemetryService;
9190
9451
  return {
9191
- category: exports.ErrorCategory.NETWORK_ERROR,
9192
- message: errorMessage,
9193
- shouldRetry: true,
9194
- userMessage: 'Network error: Unable to connect to server.',
9452
+ receipts: sdk.receipts,
9453
+ merchants: sdk.merchants,
9454
+ cashiers: sdk.cashiers,
9455
+ cashRegisters: sdk.cashRegisters,
9456
+ pointOfSales: sdk.pointOfSales,
9457
+ suppliers: sdk.suppliers,
9458
+ pems: sdk.pems,
9459
+ dailyReports: sdk.dailyReports,
9460
+ journals: sdk.journals,
9461
+ telemetry: {
9462
+ startPollingAuto: () => this.startTelemetryPollingAuto(),
9463
+ startPolling: (pemId) => telemetryService.startPolling(pemId),
9464
+ stopPolling: () => telemetryService.stopPolling(),
9465
+ getTelemetry: (pemId) => telemetryService.getTelemetry(pemId),
9466
+ refreshTelemetry: (pemId) => telemetryService.refreshTelemetry(pemId),
9467
+ triggerSync: () => telemetryService.triggerSync(),
9468
+ clearTelemetry: () => telemetryService.clearTelemetry(),
9469
+ getPemId: () => this.getPemId(),
9470
+ },
9471
+ login: (credentials) => sdk.login(credentials),
9472
+ logout: () => sdk.logout(),
9473
+ getCurrentUser: () => sdk.getCurrentUser(),
9474
+ isAuthenticated: () => sdk.isAuthenticated(),
9475
+ storeCertificate: (certificate, privateKey, options) => sdk.storeCertificate(certificate, privateKey, options),
9476
+ hasCertificate: () => sdk.hasCertificate(),
9477
+ clearCertificate: () => sdk.clearCertificate(),
9478
+ isOnline: () => sdk.isOnline(),
9195
9479
  };
9196
9480
  }
9197
- return {
9198
- category: exports.ErrorCategory.UNKNOWN_ERROR,
9199
- statusCode,
9200
- message: errorMessage,
9201
- shouldRetry: false,
9202
- userMessage: `Unexpected error: ${errorMessage}`,
9203
- };
9204
- }
9205
- function shouldReconfigureCertificate(error) {
9206
- const classification = classifyError(error);
9207
- return classification.category === exports.ErrorCategory.CERTIFICATE_ERROR;
9208
- }
9209
- function shouldRetryRequest(error, isRetryAttempt) {
9210
- if (isRetryAttempt) {
9211
- return false;
9481
+ /**
9482
+ * Manually trigger a notification sync
9483
+ */
9484
+ async syncNotifications() {
9485
+ this.ensureInitialized();
9486
+ await this.notificationService.triggerSync();
9212
9487
  }
9213
- const classification = classifyError(error);
9214
- return classification.shouldRetry;
9215
- }
9216
- function getUserFriendlyMessage(error) {
9217
- const classification = classifyError(error);
9218
- return classification.userMessage;
9219
- }
9220
-
9221
- // Enum options arrays
9222
- const VAT_RATE_CODE_OPTIONS = [
9223
- '4.00',
9224
- '5.00',
9225
- '10.00',
9226
- '22.00',
9227
- '2.00',
9228
- '6.40',
9229
- '7.00',
9230
- '7.30',
9231
- '7.50',
9232
- '7.65',
9233
- '7.95',
9234
- '8.30',
9235
- '8.50',
9236
- '8.80',
9237
- '9.50',
9238
- '12.30',
9239
- 'N1',
9240
- 'N2',
9241
- 'N3',
9242
- 'N4',
9243
- 'N5',
9244
- 'N6',
9245
- ];
9246
- const GOOD_OR_SERVICE_OPTIONS = ['goods', 'service'];
9247
- const RECEIPT_PROOF_TYPE_OPTIONS = ['POS', 'VR', 'ND'];
9248
- // Enum types for receipt validation
9249
- const VatRateCodeSchema = z__namespace.enum(VAT_RATE_CODE_OPTIONS);
9250
- const GoodOrServiceSchema = z__namespace.enum(GOOD_OR_SERVICE_OPTIONS);
9251
- const ReceiptProofTypeSchema = z__namespace.enum(RECEIPT_PROOF_TYPE_OPTIONS);
9252
- // Receipt Item Schema
9253
- const ReceiptItemSchema = z__namespace.object({
9254
- type: GoodOrServiceSchema.optional(),
9255
- quantity: z__namespace.string().min(1, { error: 'fieldIsRequired' }),
9256
- description: z__namespace.string().min(1, { error: 'fieldIsRequired' }),
9257
- unit_price: z__namespace.string().min(1, { error: 'fieldIsRequired' }),
9258
- vat_rate_code: VatRateCodeSchema.optional(),
9259
- simplified_vat_allocation: z__namespace.boolean().optional(),
9260
- discount: z__namespace.string().nullable().optional(),
9261
- is_down_payment_or_voucher_redemption: z__namespace.boolean().optional(),
9262
- complimentary: z__namespace.boolean().optional(),
9263
- });
9264
- // Main Receipt Input Schema
9265
- const ReceiptInputSchema = z__namespace
9266
- .object({
9267
- items: z__namespace.array(ReceiptItemSchema).min(1, { error: 'arrayMin1' }),
9268
- customer_tax_code: z__namespace.string().optional(),
9269
- customer_lottery_code: z__namespace.string().optional(),
9270
- discount: z__namespace.string().nullable().optional(),
9271
- invoice_issuing: z__namespace.boolean().optional(),
9272
- uncollected_dcr_to_ssn: z__namespace.boolean().optional(),
9273
- services_uncollected_amount: z__namespace.string().nullable().optional(),
9274
- goods_uncollected_amount: z__namespace.string().nullable().optional(),
9275
- cash_payment_amount: z__namespace.string().nullable().optional(),
9276
- electronic_payment_amount: z__namespace.string().nullable().optional(),
9277
- ticket_restaurant_payment_amount: z__namespace.string().nullable().optional(),
9278
- ticket_restaurant_quantity: z__namespace.number().optional(),
9279
- })
9280
- .refine((data) => {
9281
- // At least one payment method should be provided
9282
- const hasCashPayment = data.cash_payment_amount && parseFloat(data.cash_payment_amount) > 0;
9283
- const hasElectronicPayment = data.electronic_payment_amount && parseFloat(data.electronic_payment_amount) > 0;
9284
- const hasTicketPayment = data.ticket_restaurant_payment_amount &&
9285
- parseFloat(data.ticket_restaurant_payment_amount) > 0;
9286
- return hasCashPayment || hasElectronicPayment || hasTicketPayment;
9287
- }, {
9288
- error: 'At least one payment method is required',
9289
- path: ['payment_methods'],
9290
- })
9291
- .refine((data) => {
9292
- // only one between customer_tax_code and customer_lottery_code can be provided
9293
- return !data.customer_tax_code || !data.customer_lottery_code;
9294
- }, {
9295
- error: 'Only one between customer_tax_code and customer_lottery_code can be provided',
9296
- path: ['customer_tax_code', 'customer_lottery_code'],
9297
- });
9298
- // Receipt Return or Void via PEM Schema
9299
- const ReceiptReturnOrVoidViaPEMInputSchema = z__namespace.object({
9300
- device_id: z__namespace.string().optional(),
9301
- items: z__namespace.array(ReceiptItemSchema).min(1, { error: 'arrayMin1' }),
9302
- document_number: z__namespace.string().min(1, { error: 'fieldIsRequired' }),
9303
- document_datetime: z__namespace.string().optional(),
9304
- lottery_code: z__namespace.string().optional(),
9305
- });
9306
- // Receipt Return or Void with Proof Schema
9307
- const ReceiptReturnOrVoidWithProofInputSchema = z__namespace.object({
9308
- items: z__namespace.array(ReceiptItemSchema).min(1, { error: 'arrayMin1' }),
9309
- proof: ReceiptProofTypeSchema,
9310
- document_datetime: z__namespace.string().min(1, { error: 'fieldIsRequired' }),
9311
- });
9312
- // Void Receipt Schema
9313
- const VoidReceiptInputSchema = z__namespace.object({
9314
- document_number: z__namespace.string().min(1, { error: 'fieldIsRequired' }),
9315
- });
9316
- const ReceiptReturnItemSchema = z__namespace
9317
- .array(z__namespace.object({
9318
- id: z__namespace.number(),
9319
- quantity: z__namespace.string().min(1, { error: 'fieldIsRequired' }),
9320
- }))
9321
- .min(1, { error: 'arrayMin1' });
9322
- // Receipt Return Schema
9323
- const ReceiptReturnInputSchema = z__namespace.object({
9324
- items: z__namespace.array(ReceiptReturnItemSchema).min(1, { error: 'arrayMin1' }),
9325
- document_number: z__namespace.string().min(1, { error: 'fieldIsRequired' }),
9326
- });
9327
-
9328
- // Cashier Create Input Schema (MF1)
9329
- const CashierCreateInputSchema = z__namespace.object({
9330
- email: z__namespace
9331
- .string()
9332
- .min(1, { error: 'fieldIsRequired' })
9333
- .max(255, { error: 'emailMaxLength' })
9334
- .email({ error: 'invalidEmail' }),
9335
- password: z__namespace
9336
- .string()
9337
- .min(8, { error: 'passwordMinLength' })
9338
- .max(40, { error: 'passwordMaxLength' }),
9339
- name: z__namespace.string().min(1, { error: 'fieldIsRequired' }).max(255, { error: 'nameMaxLength' }),
9340
- display_name: z__namespace
9341
- .string()
9342
- .min(1, { error: 'fieldIsRequired' })
9343
- .max(255, { error: 'displayNameMaxLength' }),
9344
- });
9345
-
9346
- // Enum options arrays
9347
- const PEM_STATUS_OPTIONS = [
9348
- 'NEW',
9349
- 'REGISTERED',
9350
- 'ACTIVATED',
9351
- 'ONLINE',
9352
- 'OFFLINE',
9353
- 'DISCARDED',
9354
- ];
9355
- // Address Schema (reusable)
9356
- const AddressSchema = z__namespace.object({
9357
- street_address: z__namespace.string().min(1, { error: 'fieldIsRequired' }),
9358
- street_number: z__namespace.string().min(1, { error: 'fieldIsRequired' }),
9359
- zip_code: z__namespace
9360
- .string()
9361
- .min(1, { error: 'fieldIsRequired' })
9362
- .regex(/^\d{5}$/, { error: 'invalidZipCode' }),
9363
- city: z__namespace.string().min(1, { error: 'fieldIsRequired' }),
9364
- province: z__namespace
9365
- .string()
9366
- .min(2, { error: 'provinceMinLength' })
9367
- .max(2, { error: 'provinceMaxLength' })
9368
- .toUpperCase(),
9369
- });
9370
- // PEM Status Schema
9371
- const PEMStatusSchema = z__namespace.enum(PEM_STATUS_OPTIONS);
9372
- // Activation Request Schema
9373
- const ActivationRequestSchema = z__namespace.object({
9374
- registration_key: z__namespace.string().min(1, { error: 'fieldIsRequired' }),
9375
- });
9376
- // PEM Status Offline Request Schema
9377
- const PEMStatusOfflineRequestSchema = z__namespace.object({
9378
- timestamp: z__namespace
9379
- .string()
9380
- .min(1, { error: 'fieldIsRequired' })
9381
- .refine((val) => !isNaN(Date.parse(val)), {
9382
- error: 'invalidDateFormat',
9383
- }),
9384
- reason: z__namespace.string().min(1, { error: 'fieldIsRequired' }),
9385
- });
9488
+ /**
9489
+ * Manually trigger a telemetry sync
9490
+ */
9491
+ async syncTelemetry() {
9492
+ this.ensureInitialized();
9493
+ return this.telemetryService.triggerSync();
9494
+ }
9495
+ /**
9496
+ * Check if the manager is initialized
9497
+ */
9498
+ getIsInitialized() {
9499
+ return this.isInitialized;
9500
+ }
9501
+ /**
9502
+ * Get the underlying SDK instance (for advanced use cases)
9503
+ */
9504
+ getSDK() {
9505
+ this.ensureInitialized();
9506
+ return this.sdk;
9507
+ }
9508
+ cleanup() {
9509
+ this.notificationService?.destroy();
9510
+ this.telemetryService?.destroy();
9511
+ this.appStateService?.destroy();
9512
+ this.sdk?.destroy();
9513
+ this.notificationService = null;
9514
+ this.telemetryService = null;
9515
+ this.appStateService = null;
9516
+ this.sdk = null;
9517
+ this.isInitialized = false;
9518
+ this.isPollingActive = false;
9519
+ }
9520
+ ensureInitialized() {
9521
+ if (!this.isInitialized) {
9522
+ throw new ACubeSDKError('SDK_NOT_INITIALIZED', 'SDKManager not initialized. Call initialize() first.');
9523
+ }
9524
+ }
9525
+ }
9526
+ SDKManager.instance = null;
9386
9527
 
9387
- // Cash Register Create Schema
9388
- const CashRegisterCreateSchema = z__namespace.object({
9389
- pem_serial_number: z__namespace.string().min(1, { error: 'fieldIsRequired' }),
9390
- name: z__namespace.string().min(1, { error: 'fieldIsRequired' }).max(100, { error: 'nameMaxLength' }),
9391
- });
9528
+ const RECEIPT_READY = 'ready';
9529
+ const RECEIPT_SENT = 'sent';
9530
+ const RECEIPT_SORT_DESCENDING = 'descending';
9531
+ const RECEIPT_SORT_ASCENDING = 'ascending';
9392
9532
 
9393
- // VAT number validation regex (Partita IVA - 11 digits)
9394
- const VAT_NUMBER_REGEX = /^\d{11}$/;
9395
- // Fiscal code validation regex (Codice Fiscale - 11 digits only for merchants)
9396
- const FISCAL_CODE_REGEX = /^\d{11}$/;
9397
- // Password validation regex (from OpenAPI spec)
9398
- const PASSWORD_REGEX = /^((?=.*[A-Z])(?=.*[a-z])(?=.*[0-9])(?=.*[!@#$%^&*])(?=.{10,}).*)$/;
9399
- // Merchant Create Input Schema
9400
- const MerchantCreateInputSchema = z__namespace
9401
- .object({
9402
- vat_number: z__namespace
9403
- .string()
9404
- .min(1, { error: 'fieldIsRequired' })
9405
- .regex(VAT_NUMBER_REGEX, { error: 'invalidVatNumber' }),
9406
- fiscal_code: z__namespace.string().regex(FISCAL_CODE_REGEX, { error: 'invalidFiscalCode' }).optional(),
9407
- business_name: z__namespace.string().max(200, { error: 'businessNameMaxLength' }).optional().nullable(),
9408
- first_name: z__namespace.string().max(100, { error: 'firstNameMaxLength' }).optional().nullable(),
9409
- last_name: z__namespace.string().max(100, { error: 'lastNameMaxLength' }).optional().nullable(),
9410
- email: z__namespace.string().min(1, { error: 'fieldIsRequired' }).email({ error: 'invalidEmail' }),
9411
- password: z__namespace
9412
- .string()
9413
- .min(1, { error: 'fieldIsRequired' })
9414
- .regex(PASSWORD_REGEX, { error: 'passwordComplexity' }),
9415
- address: AddressSchema.optional(),
9416
- })
9417
- .refine((data) => {
9418
- const hasBusinessName = data.business_name && data.business_name.trim() !== '';
9419
- const hasPersonalNames = (data.first_name && data.first_name.trim() !== '') ||
9420
- (data.last_name && data.last_name.trim() !== '');
9421
- // If business name is set, first/last name must not be provided
9422
- if (hasBusinessName && hasPersonalNames) {
9423
- return false;
9533
+ const log = createPrefixedLogger('CACHE-HANDLER');
9534
+ class CacheHandler {
9535
+ constructor(cache, networkMonitor) {
9536
+ this.cache = cache;
9537
+ this.networkMonitor = networkMonitor;
9538
+ this.currentOnlineState = true;
9539
+ this.setupNetworkMonitoring();
9424
9540
  }
9425
- // At least one naming method must be provided
9426
- if (!hasBusinessName && !hasPersonalNames) {
9541
+ setupNetworkMonitoring() {
9542
+ if (this.networkMonitor) {
9543
+ this.networkSubscription = this.networkMonitor.online$.subscribe((online) => {
9544
+ this.currentOnlineState = online;
9545
+ });
9546
+ }
9547
+ }
9548
+ isOnline() {
9549
+ if (this.networkMonitor) {
9550
+ return this.currentOnlineState;
9551
+ }
9552
+ if (typeof navigator !== 'undefined' && 'onLine' in navigator) {
9553
+ return navigator.onLine;
9554
+ }
9427
9555
  return false;
9428
9556
  }
9429
- return true;
9430
- }, {
9431
- error: 'businessNameOrPersonalNamesRequired',
9432
- path: ['business_name'],
9433
- });
9434
- // Merchant Update Input Schema
9435
- const MerchantUpdateInputSchema = z__namespace.object({
9436
- business_name: z__namespace.string().max(200, { error: 'businessNameMaxLength' }).optional().nullable(),
9437
- first_name: z__namespace.string().max(100, { error: 'firstNameMaxLength' }).optional().nullable(),
9438
- last_name: z__namespace.string().max(100, { error: 'lastNameMaxLength' }).optional().nullable(),
9439
- address: AddressSchema.optional().nullable(),
9440
- });
9441
-
9442
- // Enum options arrays
9443
- const PEM_TYPE_OPTIONS = ['AP', 'SP', 'TM', 'PV'];
9444
- // PEM Data Schema
9445
- const PemDataSchema = z__namespace.object({
9446
- version: z__namespace.string().min(1, { error: 'fieldIsRequired' }),
9447
- type: z__namespace.enum(PEM_TYPE_OPTIONS, {
9448
- error: 'invalidPemType',
9449
- }),
9450
- });
9451
- // PEM Create Input Schema
9452
- const PemCreateInputSchema = z__namespace.object({
9453
- merchant_uuid: z__namespace.string().min(1, { error: 'fieldIsRequired' }).uuid({ error: 'invalidUuid' }),
9454
- address: AddressSchema.optional(),
9455
- /* external_pem_data: PemDataSchema.optional(), */
9456
- });
9457
-
9458
- // Italian Fiscal ID validation regex (Codice Fiscale for individuals or Partita IVA for companies)
9459
- const FISCAL_ID_REGEX = /^([A-Z]{6}[0-9LMNPQRSTUV]{2}[ABCDEHLMPRST][0-9LMNPQRSTUV]{2}[A-Z][0-9LMNPQRSTUV]{3}[A-Z]|[0-9]{11})$/;
9460
- // Supplier Create Input Schema
9461
- const SupplierCreateInputSchema = z__namespace.object({
9462
- fiscal_id: z__namespace
9463
- .string()
9464
- .min(1, { error: 'fieldIsRequired' })
9465
- .regex(FISCAL_ID_REGEX, { error: 'invalidFiscalId' })
9466
- .toUpperCase(),
9467
- name: z__namespace.string().min(1, { error: 'fieldIsRequired' }).max(200, { error: 'nameMaxLength' }),
9468
- address: AddressSchema.optional(),
9469
- });
9470
- // Supplier Update Input Schema
9471
- const SupplierUpdateInputSchema = z__namespace.object({
9472
- name: z__namespace.string().min(1, { error: 'fieldIsRequired' }).max(200, { error: 'nameMaxLength' }),
9473
- address: AddressSchema.optional(),
9474
- });
9475
-
9476
- // Journal Close Input Schema
9477
- const JournalCloseInputSchema = z__namespace.object({
9478
- closing_timestamp: z__namespace
9479
- .string()
9480
- .min(1, { error: 'fieldIsRequired' })
9481
- .refine((val) => !isNaN(Date.parse(val)), {
9482
- error: 'invalidDateFormat',
9483
- }),
9484
- reason: z__namespace.string().max(255, { error: 'reasonMaxLength' }).optional(),
9485
- });
9486
-
9487
- // Daily Report Status Options
9488
- const DAILY_REPORT_STATUS_OPTIONS = ['pending', 'sent', 'error'];
9489
- // Daily Report Status Schema
9490
- const DailyReportStatusSchema = z__namespace.enum(DAILY_REPORT_STATUS_OPTIONS, {
9491
- error: 'invalidDailyReportStatus',
9492
- });
9493
- // Daily Reports List Parameters Schema
9494
- const DailyReportsParamsSchema = z__namespace.object({
9495
- pem_serial_number: z__namespace.string().min(1, { error: 'fieldIsRequired' }).optional(),
9496
- date_from: z__namespace
9497
- .string()
9498
- .refine((val) => !isNaN(Date.parse(val)), {
9499
- error: 'invalidDateFormat',
9500
- })
9501
- .optional(),
9502
- date_to: z__namespace
9503
- .string()
9504
- .refine((val) => !isNaN(Date.parse(val)), {
9505
- error: 'invalidDateFormat',
9506
- })
9507
- .optional(),
9508
- status: DailyReportStatusSchema.optional(),
9509
- page: z__namespace.number().min(1, { error: 'pageMinValue' }).optional(),
9510
- });
9511
-
9512
- const NotificationScopeSchema = z__namespace.object({
9513
- type: z__namespace.literal('global'),
9514
- });
9515
- const PemStatusSchema = z__namespace.enum(['ONLINE', 'OFFLINE']);
9516
- const NotificationDataBlockAtSchema = z__namespace.object({
9517
- block_at: z__namespace.string(),
9518
- });
9519
- const NotificationDataPemStatusSchema = z__namespace.object({
9520
- from: PemStatusSchema,
9521
- to: PemStatusSchema,
9522
- });
9523
- const NotificationBaseSchema = z__namespace.object({
9524
- uuid: z__namespace.string().uuid({ error: 'invalidUuid' }),
9525
- scope: NotificationScopeSchema,
9526
- source: z__namespace.enum(['system', 'Italian Tax Authority']),
9527
- level: z__namespace.enum(['info', 'warning', 'error', 'critical']),
9528
- created_at: z__namespace.string(),
9529
- });
9530
- const NotificationMf2UnreachableSchema = NotificationBaseSchema.extend({
9531
- type: z__namespace.literal('INTERNAL_COMMUNICATION_FAILURE'),
9532
- code: z__namespace.literal('SYS-W-01'),
9533
- data: NotificationDataBlockAtSchema,
9534
- });
9535
- const NotificationPemsBlockedSchema = NotificationBaseSchema.extend({
9536
- type: z__namespace.literal('PEM_STATUS_CHANGED'),
9537
- code: z__namespace.literal('SYS-C-01'),
9538
- data: NotificationDataPemStatusSchema,
9539
- });
9540
- const NotificationPemBackOnlineSchema = NotificationBaseSchema.extend({
9541
- type: z__namespace.literal('PEM_STATUS_CHANGED'),
9542
- code: z__namespace.literal('SYS-I-01'),
9543
- data: NotificationDataPemStatusSchema,
9544
- });
9545
- const NotificationSchema = z__namespace.discriminatedUnion('code', [
9546
- NotificationMf2UnreachableSchema,
9547
- NotificationPemsBlockedSchema,
9548
- NotificationPemBackOnlineSchema,
9549
- ]);
9550
- const NotificationListResponseSchema = z__namespace.object({
9551
- members: z__namespace.array(NotificationSchema),
9552
- });
9557
+ async handleCachedRequest(url, requestFn, config) {
9558
+ if (!this.cache || config?.useCache === false) {
9559
+ const response = await requestFn();
9560
+ return response.data;
9561
+ }
9562
+ const cacheKey = this.generateCacheKey(url);
9563
+ const online = this.isOnline();
9564
+ log.debug('Request:', { url, cacheKey, online });
9565
+ if (online) {
9566
+ try {
9567
+ const response = await requestFn();
9568
+ if (this.cache) {
9569
+ await this.cache.set(cacheKey, response.data).catch((error) => {
9570
+ log.error('Failed to cache:', error instanceof Error ? error.message : error);
9571
+ });
9572
+ }
9573
+ return response.data;
9574
+ }
9575
+ catch (error) {
9576
+ const cached = await this.cache.get(cacheKey).catch(() => null);
9577
+ if (cached) {
9578
+ log.debug('Network failed, using cache fallback');
9579
+ return cached.data;
9580
+ }
9581
+ throw error;
9582
+ }
9583
+ }
9584
+ else {
9585
+ const cached = await this.cache.get(cacheKey).catch(() => null);
9586
+ if (cached) {
9587
+ log.debug('Offline, returning cached data');
9588
+ return cached.data;
9589
+ }
9590
+ throw new Error('Offline: No cached data available');
9591
+ }
9592
+ }
9593
+ generateCacheKey(url) {
9594
+ return url;
9595
+ }
9596
+ async invalidateCache(pattern) {
9597
+ if (!this.cache)
9598
+ return;
9599
+ try {
9600
+ await this.cache.invalidate(pattern);
9601
+ }
9602
+ catch (error) {
9603
+ log.error('Invalidation failed:', error instanceof Error ? error.message : error);
9604
+ }
9605
+ }
9606
+ getCacheStatus() {
9607
+ return {
9608
+ available: !!this.cache,
9609
+ networkMonitorAvailable: !!this.networkMonitor,
9610
+ isOnline: this.isOnline(),
9611
+ };
9612
+ }
9613
+ destroy() {
9614
+ this.networkSubscription?.unsubscribe();
9615
+ }
9616
+ }
9553
9617
 
9554
- const TelemetryMerchantSchema = z__namespace.object({
9555
- vat_number: z__namespace.string(),
9556
- fiscal_code: z__namespace.string().nullable(),
9557
- business_name: z__namespace.string(),
9558
- });
9559
- const TelemetrySupplierSchema = z__namespace.object({
9560
- vat_number: z__namespace.string(),
9561
- fiscal_code: z__namespace.string().nullable(),
9562
- business_name: z__namespace.string(),
9563
- });
9564
- const TelemetrySoftwareVersionSchema = z__namespace.object({
9565
- version: z__namespace.string(),
9566
- swid: z__namespace.string(),
9567
- installed_at: z__namespace.string(),
9568
- status: z__namespace.enum(['active', 'inactive', 'archived']),
9569
- });
9570
- const TelemetrySoftwareSchema = z__namespace.object({
9571
- code: z__namespace.string(),
9572
- name: z__namespace.string(),
9573
- approval_reference: z__namespace.string(),
9574
- version_info: TelemetrySoftwareVersionSchema,
9575
- });
9576
- const PendingReceiptsSchema = z__namespace.object({
9577
- count: z__namespace.number().int().nonnegative(),
9578
- total_amount: z__namespace.string(),
9579
- });
9580
- const TransmissionSchema = z__namespace.object({
9581
- attempted_at: z__namespace.string(),
9582
- outcome: z__namespace.enum(['success', 'failed', 'pending']),
9583
- });
9584
- const MessageSchema = z__namespace.object({
9585
- received_at: z__namespace.string(),
9586
- content: z__namespace.string(),
9587
- });
9588
- const LotterySecretRequestSchema = z__namespace.object({
9589
- requested_at: z__namespace.string(),
9590
- outcome: z__namespace.enum(['success', 'failed', 'pending']),
9591
- });
9592
- const LotterySchema = z__namespace.object({
9593
- last_transmission: TransmissionSchema,
9594
- secret_request: LotterySecretRequestSchema,
9595
- });
9596
- const TelemetrySchema = z__namespace.object({
9597
- pem_id: z__namespace.string(),
9598
- pem_status: z__namespace.enum(['ONLINE', 'OFFLINE', 'ERROR']),
9599
- pem_status_changed_at: z__namespace.string(),
9600
- merchant: TelemetryMerchantSchema,
9601
- supplier: TelemetrySupplierSchema,
9602
- software: TelemetrySoftwareSchema,
9603
- last_communication_at: z__namespace.string(),
9604
- pending_receipts: PendingReceiptsSchema,
9605
- last_receipt_transmission: TransmissionSchema,
9606
- last_message_from_mf2: MessageSchema,
9607
- ade_corrispettivi_transmission: TransmissionSchema,
9608
- last_message_from_ade: MessageSchema,
9609
- lottery: LotterySchema,
9610
- });
9618
+ function transformError(error) {
9619
+ if (axios.isAxiosError(error)) {
9620
+ const response = error.response;
9621
+ if (!response) {
9622
+ return new ACubeSDKError('NETWORK_ERROR', 'Network error occurred', error);
9623
+ }
9624
+ const status = response.status;
9625
+ const data = response.data;
9626
+ const violations = data?.violations;
9627
+ let message = 'Unknown error occurred';
9628
+ if (data?.detail) {
9629
+ message = data.detail;
9630
+ }
9631
+ else if (data?.title) {
9632
+ message = data.title;
9633
+ }
9634
+ else if (error.message) {
9635
+ message = error.message;
9636
+ }
9637
+ switch (status) {
9638
+ case 400:
9639
+ return new ACubeSDKError('VALIDATION_ERROR', message, error, status, violations);
9640
+ case 401:
9641
+ return new ACubeSDKError('AUTH_ERROR', message, error, status, violations);
9642
+ case 403:
9643
+ return new ACubeSDKError('FORBIDDEN_ERROR', message, error, status, violations);
9644
+ case 404:
9645
+ return new ACubeSDKError('NOT_FOUND_ERROR', message, error, status, violations);
9646
+ case 422:
9647
+ return new ACubeSDKError('VALIDATION_ERROR', message, error, status, violations);
9648
+ default:
9649
+ return new ACubeSDKError('UNKNOWN_ERROR', message, error, status, violations);
9650
+ }
9651
+ }
9652
+ return new ACubeSDKError('UNKNOWN_ERROR', 'Unknown error occurred', error);
9653
+ }
9611
9654
 
9612
- // Receipt schemas and types
9613
- // Common validation utilities
9614
- const ValidationMessages = {
9615
- fieldIsRequired: 'This field is required',
9616
- arrayMin1: 'At least one item is required',
9617
- paymentMethodRequired: 'At least one payment method is required',
9618
- invalidEmail: 'Please enter a valid email address',
9619
- passwordMinLength: 'Password must be at least 8 characters long',
9620
- passwordComplexity: 'Password must contain at least one uppercase letter, one lowercase letter, one number, and one special character',
9621
- invalidZipCode: 'Please enter a valid 5-digit zip code',
9622
- provinceMinLength: 'Province code must be 2 characters',
9623
- provinceMaxLength: 'Province code must be 2 characters',
9624
- invalidDateFormat: 'Please enter a valid date',
9625
- nameMaxLength: 'Name is too long',
9626
- invalidFiscalId: 'Please enter a valid Italian fiscal ID (Codice Fiscale or Partita IVA)',
9627
- invalidVatNumber: 'Please enter a valid VAT number (11 digits)',
9628
- invalidFiscalCode: 'Please enter a valid fiscal code (11 digits)',
9629
- businessNameMaxLength: 'Business name is too long (max 200 characters)',
9630
- businessNameOrPersonalNamesRequired: 'Please provide either a business name or first/last name, but not both',
9631
- firstNameMaxLength: 'First name is too long (max 100 characters)',
9632
- lastNameMaxLength: 'Last name is too long (max 100 characters)',
9633
- invalidUuid: 'Please enter a valid UUID',
9634
- invalidPemType: 'PEM type must be one of: AP, SP, TM, PV',
9635
- reasonMaxLength: 'Reason is too long (max 255 characters)',
9636
- pageMinValue: 'Page number must be at least 1',
9637
- invalidDailyReportStatus: 'Daily report status must be one of: pending, sent, error',
9638
- displayNameMaxLength: 'Display name is too long (max 255 characters)',
9639
- };
9640
- // Validation helper functions
9641
- const validateInput = (schema, data) => {
9642
- const result = schema.safeParse(data);
9643
- if (!result.success) {
9644
- const errors = result.error.issues.map((error) => ({
9645
- field: error.path.join('.'),
9646
- message: error.message,
9647
- code: error.code,
9648
- }));
9655
+ exports.ErrorCategory = void 0;
9656
+ (function (ErrorCategory) {
9657
+ ErrorCategory["SERVER_ERROR"] = "SERVER_ERROR";
9658
+ ErrorCategory["CLIENT_ERROR"] = "CLIENT_ERROR";
9659
+ ErrorCategory["AUTH_ERROR"] = "AUTH_ERROR";
9660
+ ErrorCategory["CERTIFICATE_ERROR"] = "CERTIFICATE_ERROR";
9661
+ ErrorCategory["NETWORK_ERROR"] = "NETWORK_ERROR";
9662
+ ErrorCategory["UNKNOWN_ERROR"] = "UNKNOWN_ERROR";
9663
+ })(exports.ErrorCategory || (exports.ErrorCategory = {}));
9664
+ function extractStatusCode(error) {
9665
+ if (error instanceof MTLSError && error.statusCode) {
9666
+ return error.statusCode;
9667
+ }
9668
+ const errorObj = error;
9669
+ if (errorObj?.response?.status) {
9670
+ return errorObj.response.status;
9671
+ }
9672
+ if (typeof errorObj?.statusCode === 'number') {
9673
+ return errorObj.statusCode;
9674
+ }
9675
+ return undefined;
9676
+ }
9677
+ function classifyError(error) {
9678
+ const statusCode = extractStatusCode(error);
9679
+ const errorMessage = error instanceof Error ? error.message : String(error);
9680
+ if (statusCode && statusCode >= 500 && statusCode < 600) {
9649
9681
  return {
9650
- success: false,
9651
- errors,
9652
- data: null,
9682
+ category: exports.ErrorCategory.SERVER_ERROR,
9683
+ statusCode,
9684
+ message: errorMessage,
9685
+ shouldRetry: false,
9686
+ userMessage: `Server error (${statusCode}): The server encountered an error.`,
9687
+ };
9688
+ }
9689
+ if (statusCode === 401 || statusCode === 403) {
9690
+ return {
9691
+ category: exports.ErrorCategory.AUTH_ERROR,
9692
+ statusCode,
9693
+ message: errorMessage,
9694
+ shouldRetry: false,
9695
+ userMessage: `Authentication error (${statusCode}): Invalid credentials or insufficient permissions.`,
9696
+ };
9697
+ }
9698
+ if (statusCode && statusCode >= 400 && statusCode < 500) {
9699
+ return {
9700
+ category: exports.ErrorCategory.CLIENT_ERROR,
9701
+ statusCode,
9702
+ message: errorMessage,
9703
+ shouldRetry: false,
9704
+ userMessage: `Request error (${statusCode}): ${errorMessage}`,
9705
+ };
9706
+ }
9707
+ if (error instanceof MTLSError) {
9708
+ return {
9709
+ category: exports.ErrorCategory.CERTIFICATE_ERROR,
9710
+ statusCode,
9711
+ message: errorMessage,
9712
+ shouldRetry: true,
9713
+ userMessage: 'Certificate error: Unable to establish secure connection.',
9714
+ };
9715
+ }
9716
+ if (!statusCode &&
9717
+ (errorMessage.toLowerCase().includes('network') ||
9718
+ errorMessage.toLowerCase().includes('timeout') ||
9719
+ errorMessage.toLowerCase().includes('connection'))) {
9720
+ return {
9721
+ category: exports.ErrorCategory.NETWORK_ERROR,
9722
+ message: errorMessage,
9723
+ shouldRetry: true,
9724
+ userMessage: 'Network error: Unable to connect to server.',
9653
9725
  };
9654
9726
  }
9655
9727
  return {
9656
- success: true,
9657
- errors: [],
9658
- data: result.data,
9728
+ category: exports.ErrorCategory.UNKNOWN_ERROR,
9729
+ statusCode,
9730
+ message: errorMessage,
9731
+ shouldRetry: false,
9732
+ userMessage: `Unexpected error: ${errorMessage}`,
9659
9733
  };
9660
- };
9734
+ }
9735
+ function shouldReconfigureCertificate(error) {
9736
+ const classification = classifyError(error);
9737
+ return classification.category === exports.ErrorCategory.CERTIFICATE_ERROR;
9738
+ }
9739
+ function shouldRetryRequest(error, isRetryAttempt) {
9740
+ if (isRetryAttempt) {
9741
+ return false;
9742
+ }
9743
+ const classification = classifyError(error);
9744
+ return classification.shouldRetry;
9745
+ }
9746
+ function getUserFriendlyMessage(error) {
9747
+ const classification = classifyError(error);
9748
+ return classification.userMessage;
9749
+ }
9661
9750
 
9662
9751
  var MTLSErrorType;
9663
9752
  (function (MTLSErrorType) {