@nocios/crudify-ui 1.0.96 → 1.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/CrudifyDataProvider-F6UCGYUF.mjs +14 -0
- package/dist/chunk-ZV5J7FRE.mjs +1166 -0
- package/dist/index.d.mts +75 -1
- package/dist/index.d.ts +75 -1
- package/dist/index.js +1545 -1255
- package/dist/index.mjs +415 -1340
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -5,6 +5,9 @@ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
|
5
5
|
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
6
|
var __getProtoOf = Object.getPrototypeOf;
|
|
7
7
|
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
|
+
var __esm = (fn, res) => function __init() {
|
|
9
|
+
return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
|
|
10
|
+
};
|
|
8
11
|
var __export = (target, all) => {
|
|
9
12
|
for (var name in all)
|
|
10
13
|
__defProp(target, name, { get: all[name], enumerable: true });
|
|
@@ -28,6 +31,1211 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
|
|
|
28
31
|
));
|
|
29
32
|
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
30
33
|
|
|
34
|
+
// src/components/CrudifyLogin/utils/cookies.ts
|
|
35
|
+
var getCookie;
|
|
36
|
+
var init_cookies = __esm({
|
|
37
|
+
"src/components/CrudifyLogin/utils/cookies.ts"() {
|
|
38
|
+
"use strict";
|
|
39
|
+
getCookie = (name) => {
|
|
40
|
+
const match = document.cookie.match(new RegExp("(^|;)\\s*" + name + "=([^;]+)"));
|
|
41
|
+
return match ? match[2] : null;
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
// src/components/CrudifyLogin/utils/secureStorage.ts
|
|
47
|
+
var import_crypto_js, SecureStorage, secureSessionStorage, secureLocalStorage;
|
|
48
|
+
var init_secureStorage = __esm({
|
|
49
|
+
"src/components/CrudifyLogin/utils/secureStorage.ts"() {
|
|
50
|
+
"use strict";
|
|
51
|
+
import_crypto_js = __toESM(require("crypto-js"));
|
|
52
|
+
SecureStorage = class {
|
|
53
|
+
constructor(storageType = "sessionStorage") {
|
|
54
|
+
this.encryptionKey = this.generateEncryptionKey();
|
|
55
|
+
this.storage = storageType === "localStorage" ? window.localStorage : window.sessionStorage;
|
|
56
|
+
}
|
|
57
|
+
generateEncryptionKey() {
|
|
58
|
+
const browserFingerprint = [
|
|
59
|
+
navigator.userAgent,
|
|
60
|
+
navigator.language,
|
|
61
|
+
(/* @__PURE__ */ new Date()).getTimezoneOffset(),
|
|
62
|
+
screen.colorDepth,
|
|
63
|
+
screen.width,
|
|
64
|
+
screen.height,
|
|
65
|
+
"crudify-login"
|
|
66
|
+
].join("|");
|
|
67
|
+
return import_crypto_js.default.SHA256(browserFingerprint).toString();
|
|
68
|
+
}
|
|
69
|
+
setItem(key, value, expiryMinutes) {
|
|
70
|
+
try {
|
|
71
|
+
const encrypted = import_crypto_js.default.AES.encrypt(value, this.encryptionKey).toString();
|
|
72
|
+
this.storage.setItem(key, encrypted);
|
|
73
|
+
if (expiryMinutes) {
|
|
74
|
+
const expiryTime = (/* @__PURE__ */ new Date()).getTime() + expiryMinutes * 60 * 1e3;
|
|
75
|
+
this.storage.setItem(`${key}_expiry`, expiryTime.toString());
|
|
76
|
+
}
|
|
77
|
+
} catch (error) {
|
|
78
|
+
console.error("Failed to encrypt and store data:", error);
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
getItem(key) {
|
|
82
|
+
try {
|
|
83
|
+
const expiryKey = `${key}_expiry`;
|
|
84
|
+
const expiry = this.storage.getItem(expiryKey);
|
|
85
|
+
if (expiry) {
|
|
86
|
+
const expiryTime = parseInt(expiry, 10);
|
|
87
|
+
if ((/* @__PURE__ */ new Date()).getTime() > expiryTime) {
|
|
88
|
+
this.removeItem(key);
|
|
89
|
+
return null;
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
const encrypted = this.storage.getItem(key);
|
|
93
|
+
if (!encrypted) return null;
|
|
94
|
+
const decrypted = import_crypto_js.default.AES.decrypt(encrypted, this.encryptionKey);
|
|
95
|
+
const result = decrypted.toString(import_crypto_js.default.enc.Utf8);
|
|
96
|
+
if (!result) {
|
|
97
|
+
console.warn("Failed to decrypt stored data - may be corrupted");
|
|
98
|
+
this.removeItem(key);
|
|
99
|
+
return null;
|
|
100
|
+
}
|
|
101
|
+
return result;
|
|
102
|
+
} catch (error) {
|
|
103
|
+
console.error("Failed to decrypt data:", error);
|
|
104
|
+
this.removeItem(key);
|
|
105
|
+
return null;
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
removeItem(key) {
|
|
109
|
+
this.storage.removeItem(key);
|
|
110
|
+
this.storage.removeItem(`${key}_expiry`);
|
|
111
|
+
}
|
|
112
|
+
setToken(token) {
|
|
113
|
+
try {
|
|
114
|
+
const parts = token.split(".");
|
|
115
|
+
if (parts.length === 3) {
|
|
116
|
+
const payload = JSON.parse(atob(parts[1]));
|
|
117
|
+
if (payload.exp) {
|
|
118
|
+
const expiryTime = payload.exp * 1e3;
|
|
119
|
+
const now = (/* @__PURE__ */ new Date()).getTime();
|
|
120
|
+
const minutesUntilExpiry = Math.floor((expiryTime - now) / (60 * 1e3));
|
|
121
|
+
if (minutesUntilExpiry > 0) {
|
|
122
|
+
this.setItem("authToken", token, minutesUntilExpiry);
|
|
123
|
+
return;
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
} catch (error) {
|
|
128
|
+
console.warn("Failed to parse token expiry, using default expiry");
|
|
129
|
+
}
|
|
130
|
+
this.setItem("authToken", token, 24 * 60);
|
|
131
|
+
}
|
|
132
|
+
getToken() {
|
|
133
|
+
const token = this.getItem("authToken");
|
|
134
|
+
if (token) {
|
|
135
|
+
try {
|
|
136
|
+
const parts = token.split(".");
|
|
137
|
+
if (parts.length === 3) {
|
|
138
|
+
const payload = JSON.parse(atob(parts[1]));
|
|
139
|
+
if (payload.exp) {
|
|
140
|
+
const now = Math.floor(Date.now() / 1e3);
|
|
141
|
+
if (payload.exp < now) {
|
|
142
|
+
this.removeItem("authToken");
|
|
143
|
+
return null;
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
} catch (error) {
|
|
148
|
+
console.warn("Failed to validate token expiry");
|
|
149
|
+
this.removeItem("authToken");
|
|
150
|
+
return null;
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
return token;
|
|
154
|
+
}
|
|
155
|
+
};
|
|
156
|
+
secureSessionStorage = new SecureStorage("sessionStorage");
|
|
157
|
+
secureLocalStorage = new SecureStorage("localStorage");
|
|
158
|
+
}
|
|
159
|
+
});
|
|
160
|
+
|
|
161
|
+
// src/core/ConfigurationManager.ts
|
|
162
|
+
var _ConfigurationManager, ConfigurationManager, configurationManager;
|
|
163
|
+
var init_ConfigurationManager = __esm({
|
|
164
|
+
"src/core/ConfigurationManager.ts"() {
|
|
165
|
+
"use strict";
|
|
166
|
+
init_cookies();
|
|
167
|
+
_ConfigurationManager = class _ConfigurationManager {
|
|
168
|
+
constructor() {
|
|
169
|
+
this.resolvedConfig = null;
|
|
170
|
+
this.configError = null;
|
|
171
|
+
}
|
|
172
|
+
/**
|
|
173
|
+
* Singleton pattern to ensure consistent configuration across the app
|
|
174
|
+
*/
|
|
175
|
+
static getInstance() {
|
|
176
|
+
if (!_ConfigurationManager.instance) {
|
|
177
|
+
_ConfigurationManager.instance = new _ConfigurationManager();
|
|
178
|
+
}
|
|
179
|
+
return _ConfigurationManager.instance;
|
|
180
|
+
}
|
|
181
|
+
/**
|
|
182
|
+
* Reset the singleton instance (useful for testing)
|
|
183
|
+
*/
|
|
184
|
+
static resetInstance() {
|
|
185
|
+
_ConfigurationManager.instance = null;
|
|
186
|
+
}
|
|
187
|
+
/**
|
|
188
|
+
* Resolve configuration from all sources with proper priority
|
|
189
|
+
*/
|
|
190
|
+
resolveConfig(propsConfig = {}) {
|
|
191
|
+
if (this.resolvedConfig && this.isConfigStillValid(propsConfig)) {
|
|
192
|
+
return this.resolvedConfig;
|
|
193
|
+
}
|
|
194
|
+
try {
|
|
195
|
+
this.configError = null;
|
|
196
|
+
const envConfig = this.getEnvConfig();
|
|
197
|
+
const cookieConfig = this.getCookieConfig();
|
|
198
|
+
const configSource = {
|
|
199
|
+
env: "default",
|
|
200
|
+
publicApiKey: "default",
|
|
201
|
+
loginActions: "default",
|
|
202
|
+
appName: "default",
|
|
203
|
+
logo: "default",
|
|
204
|
+
colors: "default"
|
|
205
|
+
};
|
|
206
|
+
const env = this.resolveValue("env", propsConfig.env, envConfig.env, cookieConfig.env, "prod", configSource);
|
|
207
|
+
const publicApiKey = this.resolveValue("publicApiKey", propsConfig.publicApiKey, envConfig.publicApiKey, cookieConfig.publicApiKey, void 0, configSource);
|
|
208
|
+
const loginActions = this.resolveValue("loginActions", propsConfig.loginActions, envConfig.loginActions, cookieConfig.loginActions, [], configSource);
|
|
209
|
+
const appName = this.resolveValue("appName", propsConfig.appName, envConfig.appName, cookieConfig.appName, "Crudify App", configSource);
|
|
210
|
+
const logo = this.resolveValue("logo", propsConfig.logo, envConfig.logo, cookieConfig.logo, "", configSource);
|
|
211
|
+
const colors = this.resolveValue("colors", propsConfig.colors, envConfig.colors, cookieConfig.colors, {}, configSource);
|
|
212
|
+
if (!publicApiKey) {
|
|
213
|
+
throw new Error(
|
|
214
|
+
"publicApiKey is required. Provide it via:\n1. Props: <CrudifyDataProvider publicApiKey={...} />\n2. Environment: VITE_TEST_PUBLIC_API_KEY\n3. Cookie: publicApiKey"
|
|
215
|
+
);
|
|
216
|
+
}
|
|
217
|
+
this.resolvedConfig = {
|
|
218
|
+
env,
|
|
219
|
+
publicApiKey,
|
|
220
|
+
loginActions,
|
|
221
|
+
appName,
|
|
222
|
+
logo,
|
|
223
|
+
colors,
|
|
224
|
+
configSource,
|
|
225
|
+
rawConfig: {
|
|
226
|
+
props: propsConfig,
|
|
227
|
+
env: envConfig,
|
|
228
|
+
cookies: cookieConfig
|
|
229
|
+
}
|
|
230
|
+
};
|
|
231
|
+
console.log("\u{1F527} ConfigurationManager - Configuration resolved:", {
|
|
232
|
+
config: {
|
|
233
|
+
env: this.resolvedConfig.env,
|
|
234
|
+
publicApiKey: `${this.resolvedConfig.publicApiKey.substring(0, 8)}...`,
|
|
235
|
+
appName: this.resolvedConfig.appName,
|
|
236
|
+
loginActionsCount: this.resolvedConfig.loginActions.length
|
|
237
|
+
},
|
|
238
|
+
sources: this.resolvedConfig.configSource
|
|
239
|
+
});
|
|
240
|
+
return this.resolvedConfig;
|
|
241
|
+
} catch (error) {
|
|
242
|
+
this.configError = error instanceof Error ? error.message : "Unknown configuration error";
|
|
243
|
+
console.error("\u{1F527} ConfigurationManager - Configuration error:", this.configError);
|
|
244
|
+
this.resolvedConfig = {
|
|
245
|
+
env: "prod",
|
|
246
|
+
publicApiKey: "",
|
|
247
|
+
loginActions: [],
|
|
248
|
+
appName: "Crudify App",
|
|
249
|
+
logo: "",
|
|
250
|
+
colors: {},
|
|
251
|
+
configSource: {
|
|
252
|
+
env: "default",
|
|
253
|
+
publicApiKey: "default",
|
|
254
|
+
loginActions: "default",
|
|
255
|
+
appName: "default",
|
|
256
|
+
logo: "default",
|
|
257
|
+
colors: "default"
|
|
258
|
+
},
|
|
259
|
+
rawConfig: {
|
|
260
|
+
props: propsConfig,
|
|
261
|
+
env: {},
|
|
262
|
+
cookies: {},
|
|
263
|
+
error: this.configError
|
|
264
|
+
}
|
|
265
|
+
};
|
|
266
|
+
return this.resolvedConfig;
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
/**
|
|
270
|
+
* Check if current configuration is still valid for the given props
|
|
271
|
+
*/
|
|
272
|
+
isConfigStillValid(propsConfig) {
|
|
273
|
+
if (!this.resolvedConfig) return false;
|
|
274
|
+
const currentProps = this.resolvedConfig.rawConfig.props;
|
|
275
|
+
return JSON.stringify(currentProps) === JSON.stringify(propsConfig);
|
|
276
|
+
}
|
|
277
|
+
/**
|
|
278
|
+
* Resolve a single config value with priority and source tracking
|
|
279
|
+
*/
|
|
280
|
+
resolveValue(key, propsValue, envValue, cookieValue, defaultValue, configSource) {
|
|
281
|
+
if (propsValue !== void 0) {
|
|
282
|
+
configSource[key] = "props";
|
|
283
|
+
return propsValue;
|
|
284
|
+
}
|
|
285
|
+
if (envValue !== void 0) {
|
|
286
|
+
configSource[key] = "env";
|
|
287
|
+
return envValue;
|
|
288
|
+
}
|
|
289
|
+
if (cookieValue !== void 0) {
|
|
290
|
+
configSource[key] = "cookies";
|
|
291
|
+
return cookieValue;
|
|
292
|
+
}
|
|
293
|
+
configSource[key] = "default";
|
|
294
|
+
return defaultValue;
|
|
295
|
+
}
|
|
296
|
+
/**
|
|
297
|
+
* Get configuration from environment variables
|
|
298
|
+
*/
|
|
299
|
+
getEnvConfig() {
|
|
300
|
+
const config = {};
|
|
301
|
+
try {
|
|
302
|
+
} catch (error) {
|
|
303
|
+
console.warn("\u{1F527} ConfigurationManager - Environment variables not available:", error);
|
|
304
|
+
}
|
|
305
|
+
return config;
|
|
306
|
+
}
|
|
307
|
+
/**
|
|
308
|
+
* Get configuration from cookies (multi-tenant support)
|
|
309
|
+
*/
|
|
310
|
+
getCookieConfig() {
|
|
311
|
+
const config = {};
|
|
312
|
+
try {
|
|
313
|
+
const env = getCookie("environment");
|
|
314
|
+
if (env && ["dev", "stg", "prod"].includes(env)) {
|
|
315
|
+
config.env = env;
|
|
316
|
+
}
|
|
317
|
+
const publicApiKey = getCookie("publicApiKey");
|
|
318
|
+
if (publicApiKey) {
|
|
319
|
+
config.publicApiKey = publicApiKey;
|
|
320
|
+
}
|
|
321
|
+
const appName = getCookie("appName");
|
|
322
|
+
if (appName) {
|
|
323
|
+
config.appName = appName;
|
|
324
|
+
}
|
|
325
|
+
const loginActions = getCookie("loginActions");
|
|
326
|
+
if (loginActions) {
|
|
327
|
+
config.loginActions = loginActions.split(",").map((action) => action.trim()).filter(Boolean);
|
|
328
|
+
}
|
|
329
|
+
const logo = getCookie("logo");
|
|
330
|
+
if (logo) {
|
|
331
|
+
config.logo = logo;
|
|
332
|
+
}
|
|
333
|
+
const colors = getCookie("colors");
|
|
334
|
+
if (colors) {
|
|
335
|
+
try {
|
|
336
|
+
config.colors = JSON.parse(colors);
|
|
337
|
+
} catch (error) {
|
|
338
|
+
console.warn("\u{1F527} ConfigurationManager - Failed to parse colors from cookie:", error);
|
|
339
|
+
}
|
|
340
|
+
}
|
|
341
|
+
} catch (error) {
|
|
342
|
+
console.warn("\u{1F527} ConfigurationManager - Error reading cookies:", error);
|
|
343
|
+
}
|
|
344
|
+
return config;
|
|
345
|
+
}
|
|
346
|
+
/**
|
|
347
|
+
* Get the current resolved configuration
|
|
348
|
+
*/
|
|
349
|
+
getConfig() {
|
|
350
|
+
return this.resolvedConfig;
|
|
351
|
+
}
|
|
352
|
+
/**
|
|
353
|
+
* Get any configuration errors
|
|
354
|
+
*/
|
|
355
|
+
getConfigError() {
|
|
356
|
+
return this.configError;
|
|
357
|
+
}
|
|
358
|
+
/**
|
|
359
|
+
* Check if configuration is valid (no errors and has required fields)
|
|
360
|
+
*/
|
|
361
|
+
isConfigured() {
|
|
362
|
+
return this.resolvedConfig !== null && this.configError === null && !!this.resolvedConfig.publicApiKey;
|
|
363
|
+
}
|
|
364
|
+
/**
|
|
365
|
+
* Clear the current configuration (useful for testing or reconfiguration)
|
|
366
|
+
*/
|
|
367
|
+
clearConfig() {
|
|
368
|
+
this.resolvedConfig = null;
|
|
369
|
+
this.configError = null;
|
|
370
|
+
}
|
|
371
|
+
};
|
|
372
|
+
_ConfigurationManager.instance = null;
|
|
373
|
+
ConfigurationManager = _ConfigurationManager;
|
|
374
|
+
configurationManager = ConfigurationManager.getInstance();
|
|
375
|
+
}
|
|
376
|
+
});
|
|
377
|
+
|
|
378
|
+
// src/core/CrudifyInitializer.ts
|
|
379
|
+
var import_crudify_browser2, _CrudifyInitializer, CrudifyInitializer, crudifyInitializer;
|
|
380
|
+
var init_CrudifyInitializer = __esm({
|
|
381
|
+
"src/core/CrudifyInitializer.ts"() {
|
|
382
|
+
"use strict";
|
|
383
|
+
import_crudify_browser2 = __toESM(require("@nocios/crudify-browser"));
|
|
384
|
+
_CrudifyInitializer = class _CrudifyInitializer {
|
|
385
|
+
constructor() {
|
|
386
|
+
this.state = {
|
|
387
|
+
isInitialized: false,
|
|
388
|
+
isInitializing: false,
|
|
389
|
+
initializationError: null,
|
|
390
|
+
config: null,
|
|
391
|
+
initializationPromise: null
|
|
392
|
+
};
|
|
393
|
+
console.log("\u{1F680} CrudifyInitializer - Instance created");
|
|
394
|
+
}
|
|
395
|
+
/**
|
|
396
|
+
* Singleton pattern to ensure global initialization coordination
|
|
397
|
+
*/
|
|
398
|
+
static getInstance() {
|
|
399
|
+
if (!_CrudifyInitializer.instance) {
|
|
400
|
+
_CrudifyInitializer.instance = new _CrudifyInitializer();
|
|
401
|
+
}
|
|
402
|
+
return _CrudifyInitializer.instance;
|
|
403
|
+
}
|
|
404
|
+
/**
|
|
405
|
+
* Reset the singleton instance (useful for testing)
|
|
406
|
+
*/
|
|
407
|
+
static resetInstance() {
|
|
408
|
+
_CrudifyInitializer.instance = null;
|
|
409
|
+
}
|
|
410
|
+
/**
|
|
411
|
+
* Initialize crudify with the given configuration
|
|
412
|
+
* This method is idempotent and thread-safe
|
|
413
|
+
*/
|
|
414
|
+
async initialize(config) {
|
|
415
|
+
if (this.state.isInitialized && this.isConfigurationSame(config)) {
|
|
416
|
+
console.log("\u{1F680} CrudifyInitializer - Already initialized with same config");
|
|
417
|
+
return;
|
|
418
|
+
}
|
|
419
|
+
if (this.state.isInitializing && this.state.initializationPromise) {
|
|
420
|
+
console.log("\u{1F680} CrudifyInitializer - Waiting for ongoing initialization");
|
|
421
|
+
await this.state.initializationPromise;
|
|
422
|
+
return;
|
|
423
|
+
}
|
|
424
|
+
if (this.state.isInitialized && !this.isConfigurationSame(config)) {
|
|
425
|
+
console.log("\u{1F680} CrudifyInitializer - Configuration changed, re-initializing");
|
|
426
|
+
this.reset();
|
|
427
|
+
}
|
|
428
|
+
this.state.isInitializing = true;
|
|
429
|
+
this.state.initializationError = null;
|
|
430
|
+
this.state.initializationPromise = this.performInitialization(config);
|
|
431
|
+
try {
|
|
432
|
+
await this.state.initializationPromise;
|
|
433
|
+
this.state.isInitialized = true;
|
|
434
|
+
this.state.config = { ...config };
|
|
435
|
+
console.log("\u{1F680} CrudifyInitializer - Initialization completed successfully");
|
|
436
|
+
} catch (error) {
|
|
437
|
+
this.state.initializationError = error instanceof Error ? error.message : "Unknown initialization error";
|
|
438
|
+
console.error("\u{1F680} CrudifyInitializer - Initialization failed:", this.state.initializationError);
|
|
439
|
+
throw error;
|
|
440
|
+
} finally {
|
|
441
|
+
this.state.isInitializing = false;
|
|
442
|
+
this.state.initializationPromise = null;
|
|
443
|
+
}
|
|
444
|
+
}
|
|
445
|
+
/**
|
|
446
|
+
* Perform the actual initialization process
|
|
447
|
+
*/
|
|
448
|
+
async performInitialization(config) {
|
|
449
|
+
if (!config.publicApiKey) {
|
|
450
|
+
throw new Error("publicApiKey is required for crudify initialization");
|
|
451
|
+
}
|
|
452
|
+
console.log("\u{1F680} CrudifyInitializer - Starting initialization with config:", {
|
|
453
|
+
env: config.env,
|
|
454
|
+
publicApiKey: `${config.publicApiKey.substring(0, 8)}...`,
|
|
455
|
+
appName: config.appName
|
|
456
|
+
});
|
|
457
|
+
try {
|
|
458
|
+
const environment = config.env || "prod";
|
|
459
|
+
console.log("\u{1F680} CrudifyInitializer - Step 1: Configuring environment:", environment);
|
|
460
|
+
await import_crudify_browser2.default.config(environment);
|
|
461
|
+
console.log("\u{1F680} CrudifyInitializer - Step 2: Initializing with API key");
|
|
462
|
+
await import_crudify_browser2.default.init(config.publicApiKey, "none");
|
|
463
|
+
console.log("\u{1F680} CrudifyInitializer - Step 3: Verifying initialization");
|
|
464
|
+
await this.verifyInitialization();
|
|
465
|
+
console.log("\u{1F680} CrudifyInitializer - All initialization steps completed");
|
|
466
|
+
} catch (error) {
|
|
467
|
+
console.error("\u{1F680} CrudifyInitializer - Initialization failed at step:", error);
|
|
468
|
+
throw new Error(
|
|
469
|
+
`Crudify initialization failed: ${error instanceof Error ? error.message : "Unknown error"}. Please check your configuration (env: ${config.env || "prod"}, publicApiKey: ${config.publicApiKey ? "provided" : "missing"})`
|
|
470
|
+
);
|
|
471
|
+
}
|
|
472
|
+
}
|
|
473
|
+
/**
|
|
474
|
+
* Verify that crudify is properly initialized by checking core methods
|
|
475
|
+
*/
|
|
476
|
+
async verifyInitialization() {
|
|
477
|
+
const requiredMethods = ["readItems", "readItem", "createItem", "updateItem", "deleteItem", "login", "transaction"];
|
|
478
|
+
const missingMethods = [];
|
|
479
|
+
for (const method of requiredMethods) {
|
|
480
|
+
if (typeof import_crudify_browser2.default[method] !== "function") {
|
|
481
|
+
missingMethods.push(method);
|
|
482
|
+
}
|
|
483
|
+
}
|
|
484
|
+
if (missingMethods.length > 0) {
|
|
485
|
+
throw new Error(
|
|
486
|
+
`Crudify initialization incomplete. Missing methods: ${missingMethods.join(", ")}. This usually indicates a configuration or network issue.`
|
|
487
|
+
);
|
|
488
|
+
}
|
|
489
|
+
console.log("\u{1F680} CrudifyInitializer - Verification successful (test call skipped for performance)");
|
|
490
|
+
}
|
|
491
|
+
/**
|
|
492
|
+
* Check if the given configuration is the same as the current one
|
|
493
|
+
*/
|
|
494
|
+
isConfigurationSame(config) {
|
|
495
|
+
if (!this.state.config) return false;
|
|
496
|
+
return this.state.config.env === config.env && this.state.config.publicApiKey === config.publicApiKey;
|
|
497
|
+
}
|
|
498
|
+
/**
|
|
499
|
+
* Reset the initialization state (useful for testing or configuration changes)
|
|
500
|
+
*/
|
|
501
|
+
reset() {
|
|
502
|
+
console.log("\u{1F680} CrudifyInitializer - Resetting initialization state");
|
|
503
|
+
this.state = {
|
|
504
|
+
isInitialized: false,
|
|
505
|
+
isInitializing: false,
|
|
506
|
+
initializationError: null,
|
|
507
|
+
config: null,
|
|
508
|
+
initializationPromise: null
|
|
509
|
+
};
|
|
510
|
+
}
|
|
511
|
+
/**
|
|
512
|
+
* Get the current initialization status
|
|
513
|
+
*/
|
|
514
|
+
getStatus() {
|
|
515
|
+
return {
|
|
516
|
+
isInitialized: this.state.isInitialized,
|
|
517
|
+
isInitializing: this.state.isInitializing,
|
|
518
|
+
initializationError: this.state.initializationError,
|
|
519
|
+
config: this.state.config
|
|
520
|
+
};
|
|
521
|
+
}
|
|
522
|
+
/**
|
|
523
|
+
* Check if crudify is ready to use
|
|
524
|
+
*/
|
|
525
|
+
isReady() {
|
|
526
|
+
return this.state.isInitialized && !this.state.initializationError;
|
|
527
|
+
}
|
|
528
|
+
/**
|
|
529
|
+
* Get the current initialization error, if any
|
|
530
|
+
*/
|
|
531
|
+
getError() {
|
|
532
|
+
return this.state.initializationError;
|
|
533
|
+
}
|
|
534
|
+
/**
|
|
535
|
+
* Force re-initialization (useful when configuration changes)
|
|
536
|
+
*/
|
|
537
|
+
async reinitialize(config) {
|
|
538
|
+
console.log("\u{1F680} CrudifyInitializer - Forcing re-initialization");
|
|
539
|
+
this.reset();
|
|
540
|
+
await this.initialize(config);
|
|
541
|
+
}
|
|
542
|
+
/**
|
|
543
|
+
* Check if initialization is currently in progress
|
|
544
|
+
*/
|
|
545
|
+
isInitializing() {
|
|
546
|
+
return this.state.isInitializing;
|
|
547
|
+
}
|
|
548
|
+
/**
|
|
549
|
+
* Wait for any ongoing initialization to complete
|
|
550
|
+
*/
|
|
551
|
+
async waitForInitialization() {
|
|
552
|
+
if (this.state.initializationPromise) {
|
|
553
|
+
await this.state.initializationPromise;
|
|
554
|
+
}
|
|
555
|
+
}
|
|
556
|
+
};
|
|
557
|
+
_CrudifyInitializer.instance = null;
|
|
558
|
+
CrudifyInitializer = _CrudifyInitializer;
|
|
559
|
+
crudifyInitializer = CrudifyInitializer.getInstance();
|
|
560
|
+
}
|
|
561
|
+
});
|
|
562
|
+
|
|
563
|
+
// src/utils/jwtUtils.ts
|
|
564
|
+
var decodeJwtSafely, getCurrentUserEmail, isTokenExpired;
|
|
565
|
+
var init_jwtUtils = __esm({
|
|
566
|
+
"src/utils/jwtUtils.ts"() {
|
|
567
|
+
"use strict";
|
|
568
|
+
decodeJwtSafely = (token) => {
|
|
569
|
+
try {
|
|
570
|
+
const parts = token.split(".");
|
|
571
|
+
if (parts.length !== 3) {
|
|
572
|
+
console.warn("Invalid JWT format: token must have 3 parts");
|
|
573
|
+
return null;
|
|
574
|
+
}
|
|
575
|
+
const payload = parts[1];
|
|
576
|
+
const paddedPayload = payload + "=".repeat((4 - payload.length % 4) % 4);
|
|
577
|
+
const decodedPayload = JSON.parse(atob(paddedPayload));
|
|
578
|
+
return decodedPayload;
|
|
579
|
+
} catch (error) {
|
|
580
|
+
console.warn("Failed to decode JWT token:", error);
|
|
581
|
+
return null;
|
|
582
|
+
}
|
|
583
|
+
};
|
|
584
|
+
getCurrentUserEmail = () => {
|
|
585
|
+
try {
|
|
586
|
+
let token = null;
|
|
587
|
+
token = sessionStorage.getItem("authToken");
|
|
588
|
+
console.log("\u{1F50D} getCurrentUserEmail - authToken:", token ? `${token.substring(0, 20)}...` : null);
|
|
589
|
+
if (!token) {
|
|
590
|
+
token = sessionStorage.getItem("token");
|
|
591
|
+
console.log("\u{1F50D} getCurrentUserEmail - token:", token ? `${token.substring(0, 20)}...` : null);
|
|
592
|
+
}
|
|
593
|
+
if (!token) {
|
|
594
|
+
token = localStorage.getItem("authToken") || localStorage.getItem("token");
|
|
595
|
+
console.log("\u{1F50D} getCurrentUserEmail - localStorage:", token ? `${token.substring(0, 20)}...` : null);
|
|
596
|
+
}
|
|
597
|
+
if (!token) {
|
|
598
|
+
console.warn("\u{1F50D} getCurrentUserEmail - No token found in any storage");
|
|
599
|
+
return null;
|
|
600
|
+
}
|
|
601
|
+
const payload = decodeJwtSafely(token);
|
|
602
|
+
if (!payload) {
|
|
603
|
+
console.warn("\u{1F50D} getCurrentUserEmail - Failed to decode token");
|
|
604
|
+
return null;
|
|
605
|
+
}
|
|
606
|
+
const email = payload.email || payload["cognito:username"] || null;
|
|
607
|
+
console.log("\u{1F50D} getCurrentUserEmail - Extracted email:", email);
|
|
608
|
+
return email;
|
|
609
|
+
} catch (error) {
|
|
610
|
+
console.warn("Failed to get current user email:", error);
|
|
611
|
+
return null;
|
|
612
|
+
}
|
|
613
|
+
};
|
|
614
|
+
isTokenExpired = (token) => {
|
|
615
|
+
try {
|
|
616
|
+
const payload = decodeJwtSafely(token);
|
|
617
|
+
if (!payload || !payload.exp) return true;
|
|
618
|
+
const currentTime = Math.floor(Date.now() / 1e3);
|
|
619
|
+
return payload.exp < currentTime;
|
|
620
|
+
} catch {
|
|
621
|
+
return true;
|
|
622
|
+
}
|
|
623
|
+
};
|
|
624
|
+
}
|
|
625
|
+
});
|
|
626
|
+
|
|
627
|
+
// src/core/TokenManager.ts
|
|
628
|
+
var import_crudify_browser3, _TokenManager, TokenManager, tokenManager;
|
|
629
|
+
var init_TokenManager = __esm({
|
|
630
|
+
"src/core/TokenManager.ts"() {
|
|
631
|
+
"use strict";
|
|
632
|
+
import_crudify_browser3 = __toESM(require("@nocios/crudify-browser"));
|
|
633
|
+
init_secureStorage();
|
|
634
|
+
init_jwtUtils();
|
|
635
|
+
_TokenManager = class _TokenManager {
|
|
636
|
+
constructor() {
|
|
637
|
+
this.TOKEN_KEY = "authToken";
|
|
638
|
+
// Compatible with crudia-ui
|
|
639
|
+
this.tokenCache = null;
|
|
640
|
+
this.parsedTokenCache = null;
|
|
641
|
+
this.expirationCheckInterval = null;
|
|
642
|
+
this.storageEventListener = null;
|
|
643
|
+
this.initializeTokenManager();
|
|
644
|
+
}
|
|
645
|
+
/**
|
|
646
|
+
* Singleton pattern to ensure consistent token management
|
|
647
|
+
*/
|
|
648
|
+
static getInstance() {
|
|
649
|
+
if (!_TokenManager.instance) {
|
|
650
|
+
_TokenManager.instance = new _TokenManager();
|
|
651
|
+
}
|
|
652
|
+
return _TokenManager.instance;
|
|
653
|
+
}
|
|
654
|
+
/**
|
|
655
|
+
* Reset the singleton instance (useful for testing)
|
|
656
|
+
*/
|
|
657
|
+
static resetInstance() {
|
|
658
|
+
if (_TokenManager.instance) {
|
|
659
|
+
_TokenManager.instance.cleanup();
|
|
660
|
+
}
|
|
661
|
+
_TokenManager.instance = null;
|
|
662
|
+
}
|
|
663
|
+
/**
|
|
664
|
+
* Initialize the token manager with storage synchronization
|
|
665
|
+
*/
|
|
666
|
+
initializeTokenManager() {
|
|
667
|
+
console.log("\u{1F510} TokenManager - Initializing token management");
|
|
668
|
+
this.migrateFromLocalStorage();
|
|
669
|
+
this.loadTokenFromStorage();
|
|
670
|
+
this.setupExpirationCheck();
|
|
671
|
+
this.setupStorageListener();
|
|
672
|
+
console.log("\u{1F510} TokenManager - Initialization complete");
|
|
673
|
+
}
|
|
674
|
+
/**
|
|
675
|
+
* Migrate tokens from localStorage to sessionStorage for better security
|
|
676
|
+
* This ensures compatibility with older implementations
|
|
677
|
+
*/
|
|
678
|
+
migrateFromLocalStorage() {
|
|
679
|
+
try {
|
|
680
|
+
const legacyKeys = ["authToken", "token", "jwt", "jwtToken"];
|
|
681
|
+
for (const key of legacyKeys) {
|
|
682
|
+
const token = localStorage.getItem(key);
|
|
683
|
+
if (token && !secureSessionStorage.getToken()) {
|
|
684
|
+
console.log(`\u{1F510} TokenManager - Migrating token from localStorage key: ${key}`);
|
|
685
|
+
secureSessionStorage.setToken(token);
|
|
686
|
+
localStorage.removeItem(key);
|
|
687
|
+
break;
|
|
688
|
+
}
|
|
689
|
+
}
|
|
690
|
+
} catch (error) {
|
|
691
|
+
console.warn("\u{1F510} TokenManager - Token migration failed:", error);
|
|
692
|
+
}
|
|
693
|
+
}
|
|
694
|
+
/**
|
|
695
|
+
* Load token from storage and synchronize with crudify
|
|
696
|
+
*/
|
|
697
|
+
loadTokenFromStorage() {
|
|
698
|
+
console.log("\u{1F510} TokenManager - LOAD_FROM_STORAGE: Entry point - loading token from storage");
|
|
699
|
+
try {
|
|
700
|
+
console.log("\u{1F510} TokenManager - LOAD_FROM_STORAGE: Getting token from secure session storage");
|
|
701
|
+
const storedToken = secureSessionStorage.getToken();
|
|
702
|
+
console.log("\u{1F510} TokenManager - LOAD_FROM_STORAGE: Stored token exists:", !!storedToken);
|
|
703
|
+
if (storedToken && this.isTokenValid(storedToken)) {
|
|
704
|
+
console.log("\u{1F510} TokenManager - LOAD_FROM_STORAGE: Stored token is valid, updating cache");
|
|
705
|
+
this.tokenCache = storedToken;
|
|
706
|
+
this.parsedTokenCache = this.parseToken(storedToken);
|
|
707
|
+
this.syncTokenWithCrudify(storedToken);
|
|
708
|
+
console.log("\u{1F510} TokenManager - LOAD_FROM_STORAGE: Token loaded from storage and synchronized");
|
|
709
|
+
} else if (storedToken) {
|
|
710
|
+
console.log("\u{1F510} TokenManager - LOAD_FROM_STORAGE: Stored token exists but is invalid/expired, clearing");
|
|
711
|
+
this.clearToken();
|
|
712
|
+
} else {
|
|
713
|
+
console.log("\u{1F510} TokenManager - LOAD_FROM_STORAGE: No stored token found");
|
|
714
|
+
}
|
|
715
|
+
} catch (error) {
|
|
716
|
+
console.warn("\u{1F510} TokenManager - LOAD_FROM_STORAGE: Error loading token from storage:", error);
|
|
717
|
+
this.clearToken();
|
|
718
|
+
}
|
|
719
|
+
}
|
|
720
|
+
/**
|
|
721
|
+
* Set up automatic token expiration checking
|
|
722
|
+
*/
|
|
723
|
+
setupExpirationCheck() {
|
|
724
|
+
this.expirationCheckInterval = window.setInterval(() => {
|
|
725
|
+
if (this.tokenCache && !this.isTokenValid(this.tokenCache)) {
|
|
726
|
+
console.log("\u{1F510} TokenManager - Token expired, clearing automatically");
|
|
727
|
+
this.clearToken();
|
|
728
|
+
}
|
|
729
|
+
}, 3e4);
|
|
730
|
+
}
|
|
731
|
+
/**
|
|
732
|
+
* Set up storage event listener for cross-tab synchronization
|
|
733
|
+
*/
|
|
734
|
+
setupStorageListener() {
|
|
735
|
+
this.storageEventListener = (event) => {
|
|
736
|
+
if (event.key === this.TOKEN_KEY) {
|
|
737
|
+
console.log("\u{1F510} TokenManager - Token change detected from another tab");
|
|
738
|
+
this.loadTokenFromStorage();
|
|
739
|
+
}
|
|
740
|
+
};
|
|
741
|
+
window.addEventListener("storage", this.storageEventListener);
|
|
742
|
+
}
|
|
743
|
+
/**
|
|
744
|
+
* Set a new JWT token with automatic synchronization
|
|
745
|
+
*/
|
|
746
|
+
setToken(token) {
|
|
747
|
+
console.log("\u{1F510} TokenManager - SET_TOKEN: Entry point - setting token:", token ? "provided" : "null");
|
|
748
|
+
try {
|
|
749
|
+
if (!token) {
|
|
750
|
+
console.log("\u{1F510} TokenManager - SET_TOKEN: No token provided, clearing token");
|
|
751
|
+
this.clearToken();
|
|
752
|
+
return;
|
|
753
|
+
}
|
|
754
|
+
console.log("\u{1F510} TokenManager - SET_TOKEN: Validating token before setting");
|
|
755
|
+
if (!this.isTokenValid(token)) {
|
|
756
|
+
console.warn("\u{1F510} TokenManager - SET_TOKEN: Attempted to set invalid or expired token");
|
|
757
|
+
this.clearToken();
|
|
758
|
+
return;
|
|
759
|
+
}
|
|
760
|
+
console.log("\u{1F510} TokenManager - SET_TOKEN: Token is valid, updating cache");
|
|
761
|
+
this.tokenCache = token;
|
|
762
|
+
this.parsedTokenCache = this.parseToken(token);
|
|
763
|
+
console.log("\u{1F510} TokenManager - SET_TOKEN: Storing token in secure storage");
|
|
764
|
+
secureSessionStorage.setToken(token);
|
|
765
|
+
console.log("\u{1F510} TokenManager - SET_TOKEN: Synchronizing with crudify");
|
|
766
|
+
this.syncTokenWithCrudify(token);
|
|
767
|
+
console.log("\u{1F510} TokenManager - SET_TOKEN: Token set and synchronized successfully");
|
|
768
|
+
} catch (error) {
|
|
769
|
+
console.error("\u{1F510} TokenManager - SET_TOKEN: Error setting token:", error);
|
|
770
|
+
this.clearToken();
|
|
771
|
+
}
|
|
772
|
+
}
|
|
773
|
+
/**
|
|
774
|
+
* Get the current JWT token
|
|
775
|
+
*/
|
|
776
|
+
getToken() {
|
|
777
|
+
console.log("\u{1F510} TokenManager - GET_TOKEN: Entry point - checking cache");
|
|
778
|
+
if (this.tokenCache) {
|
|
779
|
+
console.log("\u{1F510} TokenManager - GET_TOKEN: Cache exists, validating token");
|
|
780
|
+
if (this.isTokenValid(this.tokenCache)) {
|
|
781
|
+
console.log("\u{1F510} TokenManager - GET_TOKEN: Cache valid, returning cached token");
|
|
782
|
+
return this.tokenCache;
|
|
783
|
+
} else {
|
|
784
|
+
console.log("\u{1F510} TokenManager - GET_TOKEN: Cache invalid, clearing cache");
|
|
785
|
+
this.tokenCache = null;
|
|
786
|
+
}
|
|
787
|
+
} else {
|
|
788
|
+
console.log("\u{1F510} TokenManager - GET_TOKEN: No cache, loading from storage");
|
|
789
|
+
}
|
|
790
|
+
console.log("\u{1F510} TokenManager - GET_TOKEN: Loading from storage");
|
|
791
|
+
this.loadTokenFromStorage();
|
|
792
|
+
console.log("\u{1F510} TokenManager - GET_TOKEN: Returning final token:", !!this.tokenCache);
|
|
793
|
+
return this.tokenCache;
|
|
794
|
+
}
|
|
795
|
+
/**
|
|
796
|
+
* Parse the current JWT token
|
|
797
|
+
*/
|
|
798
|
+
parseToken(token) {
|
|
799
|
+
console.log("\u{1F510} TokenManager - PARSE_TOKEN: Entry point - parsing token");
|
|
800
|
+
const targetToken = token !== void 0 ? token : this.tokenCache;
|
|
801
|
+
console.log("\u{1F510} TokenManager - PARSE_TOKEN: Target token exists:", !!targetToken);
|
|
802
|
+
if (!targetToken) {
|
|
803
|
+
console.log("\u{1F510} TokenManager - PARSE_TOKEN: No target token, returning null");
|
|
804
|
+
return null;
|
|
805
|
+
}
|
|
806
|
+
if (this.tokenCache === targetToken && this.parsedTokenCache) {
|
|
807
|
+
console.log("\u{1F510} TokenManager - PARSE_TOKEN: Returning cached parsed token");
|
|
808
|
+
return this.parsedTokenCache;
|
|
809
|
+
}
|
|
810
|
+
console.log("\u{1F510} TokenManager - PARSE_TOKEN: Cache miss, parsing token with decodeJwtSafely");
|
|
811
|
+
const parsed = decodeJwtSafely(targetToken);
|
|
812
|
+
console.log("\u{1F510} TokenManager - PARSE_TOKEN: Token parsed successfully:", !!parsed);
|
|
813
|
+
if (targetToken === this.tokenCache) {
|
|
814
|
+
console.log("\u{1F510} TokenManager - PARSE_TOKEN: Updating parsed token cache");
|
|
815
|
+
this.parsedTokenCache = parsed;
|
|
816
|
+
}
|
|
817
|
+
return parsed;
|
|
818
|
+
}
|
|
819
|
+
/**
|
|
820
|
+
* Check if a token is valid (properly formatted and not expired)
|
|
821
|
+
*/
|
|
822
|
+
isTokenValid(token) {
|
|
823
|
+
console.log("\u{1F510} TokenManager - IS_TOKEN_VALID: Entry point - checking token validity");
|
|
824
|
+
const targetToken = token !== void 0 ? token : this.tokenCache;
|
|
825
|
+
console.log("\u{1F510} TokenManager - IS_TOKEN_VALID: Target token exists:", !!targetToken);
|
|
826
|
+
if (!targetToken) {
|
|
827
|
+
console.log("\u{1F510} TokenManager - IS_TOKEN_VALID: No token, returning false");
|
|
828
|
+
return false;
|
|
829
|
+
}
|
|
830
|
+
try {
|
|
831
|
+
console.log("\u{1F510} TokenManager - IS_TOKEN_VALID: Checking if token is expired");
|
|
832
|
+
if (isTokenExpired(targetToken)) {
|
|
833
|
+
console.log("\u{1F510} TokenManager - IS_TOKEN_VALID: Token is expired, returning false");
|
|
834
|
+
return false;
|
|
835
|
+
}
|
|
836
|
+
console.log("\u{1F510} TokenManager - IS_TOKEN_VALID: Token not expired, checking if can be parsed");
|
|
837
|
+
const parsed = decodeJwtSafely(targetToken);
|
|
838
|
+
const isValid = parsed !== null;
|
|
839
|
+
console.log("\u{1F510} TokenManager - IS_TOKEN_VALID: Token parsing result:", isValid);
|
|
840
|
+
return isValid;
|
|
841
|
+
} catch (error) {
|
|
842
|
+
console.log("\u{1F510} TokenManager - IS_TOKEN_VALID: Error validating token:", error);
|
|
843
|
+
return false;
|
|
844
|
+
}
|
|
845
|
+
}
|
|
846
|
+
/**
|
|
847
|
+
* Get token expiration time as Date object
|
|
848
|
+
*/
|
|
849
|
+
getTokenExpiration() {
|
|
850
|
+
const token = this.getToken();
|
|
851
|
+
if (!token) return null;
|
|
852
|
+
const parsed = this.parseToken(token);
|
|
853
|
+
if (!parsed?.exp) return null;
|
|
854
|
+
return new Date(parsed.exp * 1e3);
|
|
855
|
+
}
|
|
856
|
+
/**
|
|
857
|
+
* Clear the current token from all storages and crudify
|
|
858
|
+
*/
|
|
859
|
+
clearToken() {
|
|
860
|
+
console.log("\u{1F510} TokenManager - CLEAR_TOKEN: Entry point - clearing all tokens");
|
|
861
|
+
try {
|
|
862
|
+
console.log("\u{1F510} TokenManager - CLEAR_TOKEN: Clearing cache");
|
|
863
|
+
this.tokenCache = null;
|
|
864
|
+
this.parsedTokenCache = null;
|
|
865
|
+
console.log("\u{1F510} TokenManager - CLEAR_TOKEN: Clearing from secure storage");
|
|
866
|
+
secureSessionStorage.removeItem(this.TOKEN_KEY);
|
|
867
|
+
console.log("\u{1F510} TokenManager - CLEAR_TOKEN: Clearing from crudify");
|
|
868
|
+
import_crudify_browser3.default.setToken("");
|
|
869
|
+
console.log("\u{1F510} TokenManager - CLEAR_TOKEN: Token cleared from all storages successfully");
|
|
870
|
+
} catch (error) {
|
|
871
|
+
console.warn("\u{1F510} TokenManager - CLEAR_TOKEN: Error clearing token:", error);
|
|
872
|
+
}
|
|
873
|
+
}
|
|
874
|
+
/**
|
|
875
|
+
* Synchronize token with crudify library
|
|
876
|
+
*/
|
|
877
|
+
syncTokenWithCrudify(token) {
|
|
878
|
+
try {
|
|
879
|
+
import_crudify_browser3.default.setToken(token);
|
|
880
|
+
console.log("\u{1F510} TokenManager - Token synchronized with crudify");
|
|
881
|
+
} catch (error) {
|
|
882
|
+
console.warn("\u{1F510} TokenManager - Failed to sync token with crudify:", error);
|
|
883
|
+
}
|
|
884
|
+
}
|
|
885
|
+
/**
|
|
886
|
+
* Refresh token (placeholder for future implementation)
|
|
887
|
+
*/
|
|
888
|
+
async refreshToken() {
|
|
889
|
+
throw new Error("Token refresh not yet implemented");
|
|
890
|
+
}
|
|
891
|
+
/**
|
|
892
|
+
* Get user information from the current token
|
|
893
|
+
*/
|
|
894
|
+
getUserInfo() {
|
|
895
|
+
const parsed = this.parseToken();
|
|
896
|
+
if (!parsed) {
|
|
897
|
+
return {
|
|
898
|
+
email: null,
|
|
899
|
+
userId: null,
|
|
900
|
+
userIdentifier: null,
|
|
901
|
+
username: null
|
|
902
|
+
};
|
|
903
|
+
}
|
|
904
|
+
return {
|
|
905
|
+
email: parsed.email || null,
|
|
906
|
+
userId: parsed.sub || null,
|
|
907
|
+
userIdentifier: parsed["cognito:username"] || parsed.email || parsed.sub || null,
|
|
908
|
+
username: parsed["cognito:username"] || null
|
|
909
|
+
};
|
|
910
|
+
}
|
|
911
|
+
/**
|
|
912
|
+
* Check if user is currently authenticated
|
|
913
|
+
*/
|
|
914
|
+
isAuthenticated() {
|
|
915
|
+
return this.isTokenValid();
|
|
916
|
+
}
|
|
917
|
+
/**
|
|
918
|
+
* Get time until token expires in minutes
|
|
919
|
+
*/
|
|
920
|
+
getTimeUntilExpiration() {
|
|
921
|
+
const expiration = this.getTokenExpiration();
|
|
922
|
+
if (!expiration) return null;
|
|
923
|
+
const now = /* @__PURE__ */ new Date();
|
|
924
|
+
const minutesUntilExpiry = Math.floor((expiration.getTime() - now.getTime()) / (60 * 1e3));
|
|
925
|
+
return Math.max(0, minutesUntilExpiry);
|
|
926
|
+
}
|
|
927
|
+
/**
|
|
928
|
+
* Cleanup resources (call when the component unmounts)
|
|
929
|
+
*/
|
|
930
|
+
cleanup() {
|
|
931
|
+
if (this.expirationCheckInterval) {
|
|
932
|
+
window.clearInterval(this.expirationCheckInterval);
|
|
933
|
+
this.expirationCheckInterval = null;
|
|
934
|
+
}
|
|
935
|
+
if (this.storageEventListener) {
|
|
936
|
+
window.removeEventListener("storage", this.storageEventListener);
|
|
937
|
+
this.storageEventListener = null;
|
|
938
|
+
}
|
|
939
|
+
console.log("\u{1F510} TokenManager - Cleanup completed");
|
|
940
|
+
}
|
|
941
|
+
/**
|
|
942
|
+
* Get debug information about the current token state
|
|
943
|
+
*/
|
|
944
|
+
getDebugInfo() {
|
|
945
|
+
const token = this.getToken();
|
|
946
|
+
const parsed = this.parseToken();
|
|
947
|
+
const expiration = this.getTokenExpiration();
|
|
948
|
+
return {
|
|
949
|
+
hasToken: !!token,
|
|
950
|
+
tokenLength: token?.length || 0,
|
|
951
|
+
isValid: this.isTokenValid(),
|
|
952
|
+
isAuthenticated: this.isAuthenticated(),
|
|
953
|
+
expiration: expiration?.toISOString() || null,
|
|
954
|
+
minutesUntilExpiry: this.getTimeUntilExpiration(),
|
|
955
|
+
userInfo: this.getUserInfo(),
|
|
956
|
+
parsedTokenKeys: parsed ? Object.keys(parsed) : []
|
|
957
|
+
};
|
|
958
|
+
}
|
|
959
|
+
};
|
|
960
|
+
_TokenManager.instance = null;
|
|
961
|
+
TokenManager = _TokenManager;
|
|
962
|
+
tokenManager = TokenManager.getInstance();
|
|
963
|
+
}
|
|
964
|
+
});
|
|
965
|
+
|
|
966
|
+
// src/providers/CrudifyDataProvider.tsx
|
|
967
|
+
var CrudifyDataProvider_exports = {};
|
|
968
|
+
__export(CrudifyDataProvider_exports, {
|
|
969
|
+
CrudifyDataProvider: () => CrudifyDataProvider,
|
|
970
|
+
configurationManager: () => configurationManager,
|
|
971
|
+
crudifyInitializer: () => crudifyInitializer,
|
|
972
|
+
tokenManager: () => tokenManager,
|
|
973
|
+
useCrudifyDataContext: () => useCrudifyDataContext
|
|
974
|
+
});
|
|
975
|
+
var import_react5, import_jsx_runtime4, CrudifyDataContext, CrudifyDataProvider, useCrudifyDataContext;
|
|
976
|
+
var init_CrudifyDataProvider = __esm({
|
|
977
|
+
"src/providers/CrudifyDataProvider.tsx"() {
|
|
978
|
+
"use strict";
|
|
979
|
+
import_react5 = require("react");
|
|
980
|
+
init_ConfigurationManager();
|
|
981
|
+
init_CrudifyInitializer();
|
|
982
|
+
init_TokenManager();
|
|
983
|
+
import_jsx_runtime4 = require("react/jsx-runtime");
|
|
984
|
+
CrudifyDataContext = (0, import_react5.createContext)(null);
|
|
985
|
+
CrudifyDataProvider = ({
|
|
986
|
+
children,
|
|
987
|
+
env,
|
|
988
|
+
publicApiKey,
|
|
989
|
+
loginActions,
|
|
990
|
+
appName,
|
|
991
|
+
logo,
|
|
992
|
+
colors
|
|
993
|
+
}) => {
|
|
994
|
+
const [config, setConfig] = (0, import_react5.useState)(null);
|
|
995
|
+
const [isConfigured, setIsConfigured] = (0, import_react5.useState)(false);
|
|
996
|
+
const [configError, setConfigError] = (0, import_react5.useState)(null);
|
|
997
|
+
const [isInitialized, setIsInitialized] = (0, import_react5.useState)(false);
|
|
998
|
+
const [isInitializing, setIsInitializing] = (0, import_react5.useState)(false);
|
|
999
|
+
const [initializationError, setInitializationError] = (0, import_react5.useState)(null);
|
|
1000
|
+
const [isAuthenticated, setIsAuthenticated] = (0, import_react5.useState)(false);
|
|
1001
|
+
const [token, setTokenState] = (0, import_react5.useState)(null);
|
|
1002
|
+
const [user, setUser] = (0, import_react5.useState)(null);
|
|
1003
|
+
const [tokenExpiration, setTokenExpiration] = (0, import_react5.useState)(null);
|
|
1004
|
+
const initializeConfiguration = (0, import_react5.useCallback)(() => {
|
|
1005
|
+
try {
|
|
1006
|
+
console.log("\u{1F30D} CrudifyDataProvider - Initializing configuration");
|
|
1007
|
+
const propsConfig = {
|
|
1008
|
+
env,
|
|
1009
|
+
publicApiKey,
|
|
1010
|
+
loginActions,
|
|
1011
|
+
appName,
|
|
1012
|
+
logo,
|
|
1013
|
+
colors
|
|
1014
|
+
};
|
|
1015
|
+
const resolvedConfig = configurationManager.resolveConfig(propsConfig);
|
|
1016
|
+
const error = configurationManager.getConfigError();
|
|
1017
|
+
setConfig(resolvedConfig);
|
|
1018
|
+
setConfigError(error);
|
|
1019
|
+
setIsConfigured(configurationManager.isConfigured());
|
|
1020
|
+
console.log("\u{1F30D} CrudifyDataProvider - Configuration initialized:", {
|
|
1021
|
+
isConfigured: configurationManager.isConfigured(),
|
|
1022
|
+
error,
|
|
1023
|
+
sources: resolvedConfig.configSource
|
|
1024
|
+
});
|
|
1025
|
+
return resolvedConfig;
|
|
1026
|
+
} catch (error) {
|
|
1027
|
+
const errorMessage = error instanceof Error ? error.message : "Configuration initialization failed";
|
|
1028
|
+
console.error("\u{1F30D} CrudifyDataProvider - Configuration error:", errorMessage);
|
|
1029
|
+
setConfigError(errorMessage);
|
|
1030
|
+
setIsConfigured(false);
|
|
1031
|
+
return null;
|
|
1032
|
+
}
|
|
1033
|
+
}, [env, publicApiKey, loginActions, appName, logo, colors]);
|
|
1034
|
+
const initializeCrudify = (0, import_react5.useCallback)(async (resolvedConfig) => {
|
|
1035
|
+
if (!resolvedConfig || !resolvedConfig.publicApiKey) {
|
|
1036
|
+
setInitializationError("Cannot initialize crudify without valid configuration");
|
|
1037
|
+
return;
|
|
1038
|
+
}
|
|
1039
|
+
try {
|
|
1040
|
+
setIsInitializing(true);
|
|
1041
|
+
setInitializationError(null);
|
|
1042
|
+
console.log("\u{1F680} CrudifyDataProvider - Starting crudify initialization");
|
|
1043
|
+
await crudifyInitializer.initialize({
|
|
1044
|
+
env: resolvedConfig.env,
|
|
1045
|
+
publicApiKey: resolvedConfig.publicApiKey,
|
|
1046
|
+
loginActions: resolvedConfig.loginActions,
|
|
1047
|
+
appName: resolvedConfig.appName,
|
|
1048
|
+
logo: resolvedConfig.logo,
|
|
1049
|
+
colors: resolvedConfig.colors
|
|
1050
|
+
});
|
|
1051
|
+
setIsInitialized(true);
|
|
1052
|
+
console.log("\u{1F680} CrudifyDataProvider - Crudify initialization completed");
|
|
1053
|
+
} catch (error) {
|
|
1054
|
+
const errorMessage = error instanceof Error ? error.message : "Crudify initialization failed";
|
|
1055
|
+
console.error("\u{1F680} CrudifyDataProvider - Initialization error:", errorMessage);
|
|
1056
|
+
setInitializationError(errorMessage);
|
|
1057
|
+
setIsInitialized(false);
|
|
1058
|
+
} finally {
|
|
1059
|
+
setIsInitializing(false);
|
|
1060
|
+
}
|
|
1061
|
+
}, []);
|
|
1062
|
+
const updateAuthenticationState = (0, import_react5.useCallback)(() => {
|
|
1063
|
+
console.log("\u{1F510} CrudifyDataProvider - UPDATE_AUTH_STATE: Starting authentication state update");
|
|
1064
|
+
try {
|
|
1065
|
+
console.log("\u{1F510} CrudifyDataProvider - UPDATE_AUTH_STATE: Getting token from TokenManager");
|
|
1066
|
+
const currentToken = tokenManager.getToken();
|
|
1067
|
+
console.log("\u{1F510} CrudifyDataProvider - UPDATE_AUTH_STATE: Token retrieved:", !!currentToken);
|
|
1068
|
+
console.log("\u{1F510} CrudifyDataProvider - UPDATE_AUTH_STATE: Parsing token");
|
|
1069
|
+
const parsedUser = tokenManager.parseToken();
|
|
1070
|
+
console.log("\u{1F510} CrudifyDataProvider - UPDATE_AUTH_STATE: Token parsed:", !!parsedUser);
|
|
1071
|
+
console.log("\u{1F510} CrudifyDataProvider - UPDATE_AUTH_STATE: Getting expiration");
|
|
1072
|
+
const expiration = tokenManager.getTokenExpiration();
|
|
1073
|
+
console.log("\u{1F510} CrudifyDataProvider - UPDATE_AUTH_STATE: Expiration retrieved:", !!expiration);
|
|
1074
|
+
console.log("\u{1F510} CrudifyDataProvider - UPDATE_AUTH_STATE: Checking authentication");
|
|
1075
|
+
const authenticated = tokenManager.isAuthenticated();
|
|
1076
|
+
console.log("\u{1F510} CrudifyDataProvider - UPDATE_AUTH_STATE: Authentication checked:", authenticated);
|
|
1077
|
+
console.log("\u{1F510} CrudifyDataProvider - UPDATE_AUTH_STATE: Updating state variables");
|
|
1078
|
+
setTokenState(currentToken);
|
|
1079
|
+
setUser(parsedUser);
|
|
1080
|
+
setTokenExpiration(expiration);
|
|
1081
|
+
setIsAuthenticated(authenticated);
|
|
1082
|
+
console.log("\u{1F510} CrudifyDataProvider - UPDATE_AUTH_STATE: Authentication state updated successfully:", {
|
|
1083
|
+
hasToken: !!currentToken,
|
|
1084
|
+
isAuthenticated: authenticated,
|
|
1085
|
+
userEmail: parsedUser?.email || null,
|
|
1086
|
+
expiration: expiration?.toISOString() || null
|
|
1087
|
+
});
|
|
1088
|
+
} catch (error) {
|
|
1089
|
+
console.error("\u{1F510} CrudifyDataProvider - UPDATE_AUTH_STATE: Error updating authentication state:", error);
|
|
1090
|
+
}
|
|
1091
|
+
}, []);
|
|
1092
|
+
const setToken = (0, import_react5.useCallback)((newToken) => {
|
|
1093
|
+
console.log("\u{1F510} CrudifyDataProvider - SET_TOKEN_CALLBACK: ===== STARTING TOKEN SET =====");
|
|
1094
|
+
console.log("\u{1F510} CrudifyDataProvider - SET_TOKEN_CALLBACK: New token:", newToken ? `${newToken.substring(0, 20)}...` : "null");
|
|
1095
|
+
console.log("\u{1F510} CrudifyDataProvider - SET_TOKEN_CALLBACK: Setting token in TokenManager...");
|
|
1096
|
+
tokenManager.setToken(newToken);
|
|
1097
|
+
console.log("\u{1F510} CrudifyDataProvider - SET_TOKEN_CALLBACK: Updating state using newToken directly");
|
|
1098
|
+
if (newToken) {
|
|
1099
|
+
const parsedUser = tokenManager.parseToken(newToken);
|
|
1100
|
+
const expiration = tokenManager.getTokenExpiration();
|
|
1101
|
+
const authenticated = tokenManager.isTokenValid(newToken);
|
|
1102
|
+
console.log("\u{1F510} CrudifyDataProvider - SET_TOKEN_CALLBACK: Setting state values:");
|
|
1103
|
+
console.log(" - setTokenState:", newToken ? `${newToken.substring(0, 20)}...` : "null");
|
|
1104
|
+
console.log(" - setUser:", parsedUser?.email || "null");
|
|
1105
|
+
console.log(" - setIsAuthenticated:", authenticated);
|
|
1106
|
+
setTokenState(newToken);
|
|
1107
|
+
setUser(parsedUser);
|
|
1108
|
+
setTokenExpiration(expiration);
|
|
1109
|
+
setIsAuthenticated(authenticated);
|
|
1110
|
+
console.log("\u{1F510} CrudifyDataProvider - SET_TOKEN_CALLBACK: \u2705 Token set, state updated", {
|
|
1111
|
+
hasToken: true,
|
|
1112
|
+
isAuthenticated: authenticated,
|
|
1113
|
+
userEmail: parsedUser?.email || null
|
|
1114
|
+
});
|
|
1115
|
+
} else {
|
|
1116
|
+
console.log("\u{1F510} CrudifyDataProvider - SET_TOKEN_CALLBACK: Clearing all states");
|
|
1117
|
+
setTokenState(null);
|
|
1118
|
+
setUser(null);
|
|
1119
|
+
setTokenExpiration(null);
|
|
1120
|
+
setIsAuthenticated(false);
|
|
1121
|
+
console.log("\u{1F510} CrudifyDataProvider - SET_TOKEN_CALLBACK: \u2705 Token cleared, state reset");
|
|
1122
|
+
}
|
|
1123
|
+
console.log("\u{1F510} CrudifyDataProvider - SET_TOKEN_CALLBACK: ===== TOKEN SET COMPLETE =====");
|
|
1124
|
+
}, []);
|
|
1125
|
+
const logout = (0, import_react5.useCallback)(() => {
|
|
1126
|
+
console.log("\u{1F510} CrudifyDataProvider - LOGOUT_CALLBACK: Logging out user");
|
|
1127
|
+
tokenManager.clearToken();
|
|
1128
|
+
console.log("\u{1F510} CrudifyDataProvider - LOGOUT_CALLBACK: Updating state directly");
|
|
1129
|
+
setTokenState(null);
|
|
1130
|
+
setUser(null);
|
|
1131
|
+
setTokenExpiration(null);
|
|
1132
|
+
setIsAuthenticated(false);
|
|
1133
|
+
console.log("\u{1F510} CrudifyDataProvider - LOGOUT_CALLBACK: User logged out, state cleared");
|
|
1134
|
+
}, []);
|
|
1135
|
+
const refreshConfig = (0, import_react5.useCallback)(() => {
|
|
1136
|
+
console.log("\u{1F30D} CrudifyDataProvider - Refreshing configuration");
|
|
1137
|
+
configurationManager.clearConfig();
|
|
1138
|
+
const newConfig = initializeConfiguration();
|
|
1139
|
+
if (newConfig && newConfig.publicApiKey) {
|
|
1140
|
+
initializeCrudify(newConfig);
|
|
1141
|
+
}
|
|
1142
|
+
}, [initializeConfiguration, initializeCrudify]);
|
|
1143
|
+
const reinitialize = (0, import_react5.useCallback)(async () => {
|
|
1144
|
+
if (!config || !config.publicApiKey) {
|
|
1145
|
+
console.warn("\u{1F680} CrudifyDataProvider - Cannot reinitialize without valid configuration");
|
|
1146
|
+
return;
|
|
1147
|
+
}
|
|
1148
|
+
console.log("\u{1F680} CrudifyDataProvider - Force reinitializing crudify");
|
|
1149
|
+
crudifyInitializer.reset();
|
|
1150
|
+
await initializeCrudify(config);
|
|
1151
|
+
}, [config, initializeCrudify]);
|
|
1152
|
+
const getDebugInfo = (0, import_react5.useCallback)(() => {
|
|
1153
|
+
return {
|
|
1154
|
+
provider: {
|
|
1155
|
+
isConfigured,
|
|
1156
|
+
configError,
|
|
1157
|
+
isInitialized,
|
|
1158
|
+
isInitializing,
|
|
1159
|
+
initializationError,
|
|
1160
|
+
isAuthenticated
|
|
1161
|
+
},
|
|
1162
|
+
configuration: {
|
|
1163
|
+
config: config ? {
|
|
1164
|
+
env: config.env,
|
|
1165
|
+
publicApiKey: `${config.publicApiKey.substring(0, 8)}...`,
|
|
1166
|
+
appName: config.appName,
|
|
1167
|
+
loginActionsCount: config.loginActions.length,
|
|
1168
|
+
hasLogo: !!config.logo,
|
|
1169
|
+
colorsCount: Object.keys(config.colors).length
|
|
1170
|
+
} : null,
|
|
1171
|
+
sources: config?.configSource || null,
|
|
1172
|
+
rawConfig: config?.rawConfig || null
|
|
1173
|
+
},
|
|
1174
|
+
authentication: {
|
|
1175
|
+
hasToken: !!token,
|
|
1176
|
+
tokenLength: token?.length || 0,
|
|
1177
|
+
userEmail: user?.email || null,
|
|
1178
|
+
userId: user?.sub || null,
|
|
1179
|
+
expiration: tokenExpiration?.toISOString() || null,
|
|
1180
|
+
minutesUntilExpiry: tokenManager.getTimeUntilExpiration()
|
|
1181
|
+
},
|
|
1182
|
+
tokenManager: tokenManager.getDebugInfo(),
|
|
1183
|
+
crudifyInitializer: crudifyInitializer.getStatus()
|
|
1184
|
+
};
|
|
1185
|
+
}, [isConfigured, configError, isInitialized, isInitializing, initializationError, isAuthenticated, config, token, user, tokenExpiration]);
|
|
1186
|
+
(0, import_react5.useEffect)(() => {
|
|
1187
|
+
console.log("\u{1F30D} CrudifyDataProvider - Provider mounting, starting initialization");
|
|
1188
|
+
const resolvedConfig = initializeConfiguration();
|
|
1189
|
+
updateAuthenticationState();
|
|
1190
|
+
if (resolvedConfig && resolvedConfig.publicApiKey) {
|
|
1191
|
+
initializeCrudify(resolvedConfig);
|
|
1192
|
+
}
|
|
1193
|
+
return () => {
|
|
1194
|
+
console.log("\u{1F30D} CrudifyDataProvider - Provider unmounting, cleaning up");
|
|
1195
|
+
tokenManager.cleanup();
|
|
1196
|
+
};
|
|
1197
|
+
}, []);
|
|
1198
|
+
(0, import_react5.useEffect)(() => {
|
|
1199
|
+
console.log("\u{1F510} CrudifyDataProvider - INITIAL_AUTH_EFFECT: Loading initial authentication state");
|
|
1200
|
+
updateAuthenticationState();
|
|
1201
|
+
}, []);
|
|
1202
|
+
const contextValue = {
|
|
1203
|
+
// Configuration
|
|
1204
|
+
config,
|
|
1205
|
+
isConfigured,
|
|
1206
|
+
configError,
|
|
1207
|
+
configSource: config ? JSON.stringify(config.configSource) : "none",
|
|
1208
|
+
// Initialization
|
|
1209
|
+
isInitialized,
|
|
1210
|
+
isInitializing,
|
|
1211
|
+
initializationError,
|
|
1212
|
+
// Authentication
|
|
1213
|
+
isAuthenticated,
|
|
1214
|
+
token,
|
|
1215
|
+
user,
|
|
1216
|
+
tokenExpiration,
|
|
1217
|
+
// Actions
|
|
1218
|
+
setToken,
|
|
1219
|
+
logout,
|
|
1220
|
+
refreshConfig,
|
|
1221
|
+
reinitialize,
|
|
1222
|
+
// Debug
|
|
1223
|
+
getDebugInfo
|
|
1224
|
+
};
|
|
1225
|
+
return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(CrudifyDataContext.Provider, { value: contextValue, children });
|
|
1226
|
+
};
|
|
1227
|
+
useCrudifyDataContext = () => {
|
|
1228
|
+
const context = (0, import_react5.useContext)(CrudifyDataContext);
|
|
1229
|
+
if (!context) {
|
|
1230
|
+
throw new Error(
|
|
1231
|
+
"useCrudifyDataContext must be used within a CrudifyDataProvider. Make sure to wrap your app with <CrudifyDataProvider>."
|
|
1232
|
+
);
|
|
1233
|
+
}
|
|
1234
|
+
return context;
|
|
1235
|
+
};
|
|
1236
|
+
}
|
|
1237
|
+
});
|
|
1238
|
+
|
|
31
1239
|
// src/index.ts
|
|
32
1240
|
var index_exports = {};
|
|
33
1241
|
__export(index_exports, {
|
|
@@ -37,10 +1245,12 @@ __export(index_exports, {
|
|
|
37
1245
|
ERROR_SEVERITY_MAP: () => ERROR_SEVERITY_MAP,
|
|
38
1246
|
UserProfileDisplay: () => UserProfileDisplay_default,
|
|
39
1247
|
configurationManager: () => configurationManager,
|
|
40
|
-
crudify: () =>
|
|
1248
|
+
crudify: () => import_crudify_browser8.default,
|
|
41
1249
|
crudifyInitializer: () => crudifyInitializer,
|
|
42
1250
|
decodeJwtSafely: () => decodeJwtSafely,
|
|
43
1251
|
getCookie: () => getCookie,
|
|
1252
|
+
getCrudifyInstanceAsync: () => getCrudifyInstanceAsync,
|
|
1253
|
+
getCrudifyInstanceSync: () => getCrudifyInstanceSync,
|
|
44
1254
|
getCurrentUserEmail: () => getCurrentUserEmail,
|
|
45
1255
|
getErrorMessage: () => getErrorMessage,
|
|
46
1256
|
handleCrudifyError: () => handleCrudifyError,
|
|
@@ -55,12 +1265,13 @@ __export(index_exports, {
|
|
|
55
1265
|
useCrudifyConfig: () => useCrudifyConfig,
|
|
56
1266
|
useCrudifyData: () => useCrudifyData,
|
|
57
1267
|
useCrudifyDataContext: () => useCrudifyDataContext,
|
|
1268
|
+
useCrudifyInstance: () => useCrudifyInstance,
|
|
58
1269
|
useCrudifyLogin: () => useCrudifyLogin,
|
|
59
1270
|
useCrudifyUser: () => useCrudifyUser,
|
|
60
1271
|
useUserProfile: () => useUserProfile
|
|
61
1272
|
});
|
|
62
1273
|
module.exports = __toCommonJS(index_exports);
|
|
63
|
-
var
|
|
1274
|
+
var import_crudify_browser8 = __toESM(require("@nocios/crudify-browser"));
|
|
64
1275
|
__reExport(index_exports, require("@nocios/crudify-browser"), module.exports);
|
|
65
1276
|
|
|
66
1277
|
// src/components/CrudifyLogin/index.tsx
|
|
@@ -217,14 +1428,7 @@ var useCrudify = () => {
|
|
|
217
1428
|
|
|
218
1429
|
// src/components/CrudifyLogin/context/LoginStateProvider.tsx
|
|
219
1430
|
var import_react4 = require("react");
|
|
220
|
-
|
|
221
|
-
// src/components/CrudifyLogin/utils/cookies.ts
|
|
222
|
-
var getCookie = (name) => {
|
|
223
|
-
const match = document.cookie.match(new RegExp("(^|;)\\s*" + name + "=([^;]+)"));
|
|
224
|
-
return match ? match[2] : null;
|
|
225
|
-
};
|
|
226
|
-
|
|
227
|
-
// src/components/CrudifyLogin/context/LoginStateProvider.tsx
|
|
1431
|
+
init_cookies();
|
|
228
1432
|
var import_jsx_runtime3 = require("react/jsx-runtime");
|
|
229
1433
|
var initialState = {
|
|
230
1434
|
currentScreen: "login",
|
|
@@ -449,115 +1653,7 @@ var useLoginState = () => {
|
|
|
449
1653
|
// src/components/CrudifyLogin/Forms/LoginForm.tsx
|
|
450
1654
|
var import_react6 = require("react");
|
|
451
1655
|
var import_material = require("@mui/material");
|
|
452
|
-
|
|
453
|
-
// src/components/CrudifyLogin/utils/secureStorage.ts
|
|
454
|
-
var import_crypto_js = __toESM(require("crypto-js"));
|
|
455
|
-
var SecureStorage = class {
|
|
456
|
-
constructor(storageType = "sessionStorage") {
|
|
457
|
-
this.encryptionKey = this.generateEncryptionKey();
|
|
458
|
-
this.storage = storageType === "localStorage" ? window.localStorage : window.sessionStorage;
|
|
459
|
-
}
|
|
460
|
-
generateEncryptionKey() {
|
|
461
|
-
const browserFingerprint = [
|
|
462
|
-
navigator.userAgent,
|
|
463
|
-
navigator.language,
|
|
464
|
-
(/* @__PURE__ */ new Date()).getTimezoneOffset(),
|
|
465
|
-
screen.colorDepth,
|
|
466
|
-
screen.width,
|
|
467
|
-
screen.height,
|
|
468
|
-
"crudify-login"
|
|
469
|
-
].join("|");
|
|
470
|
-
return import_crypto_js.default.SHA256(browserFingerprint).toString();
|
|
471
|
-
}
|
|
472
|
-
setItem(key, value, expiryMinutes) {
|
|
473
|
-
try {
|
|
474
|
-
const encrypted = import_crypto_js.default.AES.encrypt(value, this.encryptionKey).toString();
|
|
475
|
-
this.storage.setItem(key, encrypted);
|
|
476
|
-
if (expiryMinutes) {
|
|
477
|
-
const expiryTime = (/* @__PURE__ */ new Date()).getTime() + expiryMinutes * 60 * 1e3;
|
|
478
|
-
this.storage.setItem(`${key}_expiry`, expiryTime.toString());
|
|
479
|
-
}
|
|
480
|
-
} catch (error) {
|
|
481
|
-
console.error("Failed to encrypt and store data:", error);
|
|
482
|
-
}
|
|
483
|
-
}
|
|
484
|
-
getItem(key) {
|
|
485
|
-
try {
|
|
486
|
-
const expiryKey = `${key}_expiry`;
|
|
487
|
-
const expiry = this.storage.getItem(expiryKey);
|
|
488
|
-
if (expiry) {
|
|
489
|
-
const expiryTime = parseInt(expiry, 10);
|
|
490
|
-
if ((/* @__PURE__ */ new Date()).getTime() > expiryTime) {
|
|
491
|
-
this.removeItem(key);
|
|
492
|
-
return null;
|
|
493
|
-
}
|
|
494
|
-
}
|
|
495
|
-
const encrypted = this.storage.getItem(key);
|
|
496
|
-
if (!encrypted) return null;
|
|
497
|
-
const decrypted = import_crypto_js.default.AES.decrypt(encrypted, this.encryptionKey);
|
|
498
|
-
const result = decrypted.toString(import_crypto_js.default.enc.Utf8);
|
|
499
|
-
if (!result) {
|
|
500
|
-
console.warn("Failed to decrypt stored data - may be corrupted");
|
|
501
|
-
this.removeItem(key);
|
|
502
|
-
return null;
|
|
503
|
-
}
|
|
504
|
-
return result;
|
|
505
|
-
} catch (error) {
|
|
506
|
-
console.error("Failed to decrypt data:", error);
|
|
507
|
-
this.removeItem(key);
|
|
508
|
-
return null;
|
|
509
|
-
}
|
|
510
|
-
}
|
|
511
|
-
removeItem(key) {
|
|
512
|
-
this.storage.removeItem(key);
|
|
513
|
-
this.storage.removeItem(`${key}_expiry`);
|
|
514
|
-
}
|
|
515
|
-
setToken(token) {
|
|
516
|
-
try {
|
|
517
|
-
const parts = token.split(".");
|
|
518
|
-
if (parts.length === 3) {
|
|
519
|
-
const payload = JSON.parse(atob(parts[1]));
|
|
520
|
-
if (payload.exp) {
|
|
521
|
-
const expiryTime = payload.exp * 1e3;
|
|
522
|
-
const now = (/* @__PURE__ */ new Date()).getTime();
|
|
523
|
-
const minutesUntilExpiry = Math.floor((expiryTime - now) / (60 * 1e3));
|
|
524
|
-
if (minutesUntilExpiry > 0) {
|
|
525
|
-
this.setItem("authToken", token, minutesUntilExpiry);
|
|
526
|
-
return;
|
|
527
|
-
}
|
|
528
|
-
}
|
|
529
|
-
}
|
|
530
|
-
} catch (error) {
|
|
531
|
-
console.warn("Failed to parse token expiry, using default expiry");
|
|
532
|
-
}
|
|
533
|
-
this.setItem("authToken", token, 24 * 60);
|
|
534
|
-
}
|
|
535
|
-
getToken() {
|
|
536
|
-
const token = this.getItem("authToken");
|
|
537
|
-
if (token) {
|
|
538
|
-
try {
|
|
539
|
-
const parts = token.split(".");
|
|
540
|
-
if (parts.length === 3) {
|
|
541
|
-
const payload = JSON.parse(atob(parts[1]));
|
|
542
|
-
if (payload.exp) {
|
|
543
|
-
const now = Math.floor(Date.now() / 1e3);
|
|
544
|
-
if (payload.exp < now) {
|
|
545
|
-
this.removeItem("authToken");
|
|
546
|
-
return null;
|
|
547
|
-
}
|
|
548
|
-
}
|
|
549
|
-
}
|
|
550
|
-
} catch (error) {
|
|
551
|
-
console.warn("Failed to validate token expiry");
|
|
552
|
-
this.removeItem("authToken");
|
|
553
|
-
return null;
|
|
554
|
-
}
|
|
555
|
-
}
|
|
556
|
-
return token;
|
|
557
|
-
}
|
|
558
|
-
};
|
|
559
|
-
var secureSessionStorage = new SecureStorage("sessionStorage");
|
|
560
|
-
var secureLocalStorage = new SecureStorage("localStorage");
|
|
1656
|
+
init_secureStorage();
|
|
561
1657
|
|
|
562
1658
|
// src/utils/errorHandler.ts
|
|
563
1659
|
var ERROR_CODES = {
|
|
@@ -727,1139 +1823,110 @@ function parseTransactionError(response) {
|
|
|
727
1823
|
severity: "warning",
|
|
728
1824
|
details: { transactionIndex: index }
|
|
729
1825
|
});
|
|
730
|
-
} else if (!item.response || item.response.status !== "OK") {
|
|
731
|
-
errors.push({
|
|
732
|
-
code: ERROR_CODES.BAD_REQUEST,
|
|
733
|
-
message: "Transaction failed",
|
|
734
|
-
severity: "warning",
|
|
735
|
-
details: { transactionIndex: index, response: item.response }
|
|
736
|
-
});
|
|
737
|
-
}
|
|
738
|
-
});
|
|
739
|
-
return errors;
|
|
740
|
-
}
|
|
741
|
-
return parseApiError(response);
|
|
742
|
-
} catch (error) {
|
|
743
|
-
return [
|
|
744
|
-
{
|
|
745
|
-
code: ERROR_CODES.INTERNAL_SERVER_ERROR,
|
|
746
|
-
message: "Failed to parse transaction error",
|
|
747
|
-
severity: "error",
|
|
748
|
-
details: { originalError: error }
|
|
749
|
-
}
|
|
750
|
-
];
|
|
751
|
-
}
|
|
752
|
-
}
|
|
753
|
-
function isValidErrorCode(code) {
|
|
754
|
-
return Object.values(ERROR_CODES).includes(code);
|
|
755
|
-
}
|
|
756
|
-
function getErrorMessage(code) {
|
|
757
|
-
const messages = {
|
|
758
|
-
[ERROR_CODES.INVALID_CREDENTIALS]: "Invalid email or password",
|
|
759
|
-
[ERROR_CODES.UNAUTHORIZED]: "You are not authorized to perform this action",
|
|
760
|
-
[ERROR_CODES.INVALID_API_KEY]: "Invalid API key",
|
|
761
|
-
[ERROR_CODES.USER_NOT_FOUND]: "User not found",
|
|
762
|
-
[ERROR_CODES.USER_NOT_ACTIVE]: "User account is not active",
|
|
763
|
-
[ERROR_CODES.NO_PERMISSION]: "You do not have permission to perform this action",
|
|
764
|
-
[ERROR_CODES.ITEM_NOT_FOUND]: "Item not found",
|
|
765
|
-
[ERROR_CODES.NOT_FOUND]: "Resource not found",
|
|
766
|
-
[ERROR_CODES.IN_USE]: "Resource is currently in use",
|
|
767
|
-
[ERROR_CODES.FIELD_ERROR]: "Validation error",
|
|
768
|
-
[ERROR_CODES.BAD_REQUEST]: "Invalid request",
|
|
769
|
-
[ERROR_CODES.INVALID_EMAIL]: "Please enter a valid email address",
|
|
770
|
-
[ERROR_CODES.INVALID_CODE]: "Invalid or expired code",
|
|
771
|
-
[ERROR_CODES.INTERNAL_SERVER_ERROR]: "Internal server error",
|
|
772
|
-
[ERROR_CODES.DATABASE_CONNECTION_ERROR]: "Database connection error",
|
|
773
|
-
[ERROR_CODES.INVALID_CONFIGURATION]: "Invalid configuration",
|
|
774
|
-
[ERROR_CODES.UNKNOWN_OPERATION]: "Unknown operation",
|
|
775
|
-
[ERROR_CODES.TOO_MANY_REQUESTS]: "Too many requests. Please try again later.",
|
|
776
|
-
[ERROR_CODES.NETWORK_ERROR]: "Network error. Please check your connection.",
|
|
777
|
-
[ERROR_CODES.TIMEOUT_ERROR]: "Request timed out. Please try again."
|
|
778
|
-
};
|
|
779
|
-
return messages[code] || "An unknown error occurred";
|
|
780
|
-
}
|
|
781
|
-
function parseJavaScriptError(error) {
|
|
782
|
-
if (error instanceof Error) {
|
|
783
|
-
if (error.name === "AbortError") {
|
|
784
|
-
return {
|
|
785
|
-
code: ERROR_CODES.TIMEOUT_ERROR,
|
|
786
|
-
message: "Request was cancelled",
|
|
787
|
-
severity: "info"
|
|
788
|
-
};
|
|
789
|
-
}
|
|
790
|
-
if (error.message.includes("NetworkError") || error.message.includes("Failed to fetch")) {
|
|
791
|
-
return {
|
|
792
|
-
code: ERROR_CODES.NETWORK_ERROR,
|
|
793
|
-
message: getErrorMessage(ERROR_CODES.NETWORK_ERROR),
|
|
794
|
-
severity: "error"
|
|
795
|
-
};
|
|
796
|
-
}
|
|
797
|
-
return {
|
|
798
|
-
code: ERROR_CODES.INTERNAL_SERVER_ERROR,
|
|
799
|
-
message: error.message || "An unexpected error occurred",
|
|
800
|
-
severity: "error",
|
|
801
|
-
details: { originalError: error }
|
|
802
|
-
};
|
|
803
|
-
}
|
|
804
|
-
return {
|
|
805
|
-
code: ERROR_CODES.INTERNAL_SERVER_ERROR,
|
|
806
|
-
message: "An unknown error occurred",
|
|
807
|
-
severity: "error",
|
|
808
|
-
details: { originalError: error }
|
|
809
|
-
};
|
|
810
|
-
}
|
|
811
|
-
function handleCrudifyError(error) {
|
|
812
|
-
if (error instanceof Error) {
|
|
813
|
-
return [parseJavaScriptError(error)];
|
|
814
|
-
}
|
|
815
|
-
if (typeof error === "object" && error !== null) {
|
|
816
|
-
const response = error;
|
|
817
|
-
if (response.data && Array.isArray(response.data)) {
|
|
818
|
-
return parseTransactionError(error);
|
|
819
|
-
}
|
|
820
|
-
return parseApiError(error);
|
|
821
|
-
}
|
|
822
|
-
return [
|
|
823
|
-
{
|
|
824
|
-
code: ERROR_CODES.INTERNAL_SERVER_ERROR,
|
|
825
|
-
message: "An unknown error occurred",
|
|
826
|
-
severity: "error",
|
|
827
|
-
details: { originalError: error }
|
|
828
|
-
}
|
|
829
|
-
];
|
|
830
|
-
}
|
|
831
|
-
|
|
832
|
-
// src/providers/CrudifyDataProvider.tsx
|
|
833
|
-
var import_react5 = require("react");
|
|
834
|
-
|
|
835
|
-
// src/core/ConfigurationManager.ts
|
|
836
|
-
var _ConfigurationManager = class _ConfigurationManager {
|
|
837
|
-
constructor() {
|
|
838
|
-
this.resolvedConfig = null;
|
|
839
|
-
this.configError = null;
|
|
840
|
-
}
|
|
841
|
-
/**
|
|
842
|
-
* Singleton pattern to ensure consistent configuration across the app
|
|
843
|
-
*/
|
|
844
|
-
static getInstance() {
|
|
845
|
-
if (!_ConfigurationManager.instance) {
|
|
846
|
-
_ConfigurationManager.instance = new _ConfigurationManager();
|
|
847
|
-
}
|
|
848
|
-
return _ConfigurationManager.instance;
|
|
849
|
-
}
|
|
850
|
-
/**
|
|
851
|
-
* Reset the singleton instance (useful for testing)
|
|
852
|
-
*/
|
|
853
|
-
static resetInstance() {
|
|
854
|
-
_ConfigurationManager.instance = null;
|
|
855
|
-
}
|
|
856
|
-
/**
|
|
857
|
-
* Resolve configuration from all sources with proper priority
|
|
858
|
-
*/
|
|
859
|
-
resolveConfig(propsConfig = {}) {
|
|
860
|
-
if (this.resolvedConfig && this.isConfigStillValid(propsConfig)) {
|
|
861
|
-
return this.resolvedConfig;
|
|
862
|
-
}
|
|
863
|
-
try {
|
|
864
|
-
this.configError = null;
|
|
865
|
-
const envConfig = this.getEnvConfig();
|
|
866
|
-
const cookieConfig = this.getCookieConfig();
|
|
867
|
-
const configSource = {
|
|
868
|
-
env: "default",
|
|
869
|
-
publicApiKey: "default",
|
|
870
|
-
loginActions: "default",
|
|
871
|
-
appName: "default",
|
|
872
|
-
logo: "default",
|
|
873
|
-
colors: "default"
|
|
874
|
-
};
|
|
875
|
-
const env = this.resolveValue("env", propsConfig.env, envConfig.env, cookieConfig.env, "prod", configSource);
|
|
876
|
-
const publicApiKey = this.resolveValue("publicApiKey", propsConfig.publicApiKey, envConfig.publicApiKey, cookieConfig.publicApiKey, void 0, configSource);
|
|
877
|
-
const loginActions = this.resolveValue("loginActions", propsConfig.loginActions, envConfig.loginActions, cookieConfig.loginActions, [], configSource);
|
|
878
|
-
const appName = this.resolveValue("appName", propsConfig.appName, envConfig.appName, cookieConfig.appName, "Crudify App", configSource);
|
|
879
|
-
const logo = this.resolveValue("logo", propsConfig.logo, envConfig.logo, cookieConfig.logo, "", configSource);
|
|
880
|
-
const colors = this.resolveValue("colors", propsConfig.colors, envConfig.colors, cookieConfig.colors, {}, configSource);
|
|
881
|
-
if (!publicApiKey) {
|
|
882
|
-
throw new Error(
|
|
883
|
-
"publicApiKey is required. Provide it via:\n1. Props: <CrudifyDataProvider publicApiKey={...} />\n2. Environment: VITE_TEST_PUBLIC_API_KEY\n3. Cookie: publicApiKey"
|
|
884
|
-
);
|
|
885
|
-
}
|
|
886
|
-
this.resolvedConfig = {
|
|
887
|
-
env,
|
|
888
|
-
publicApiKey,
|
|
889
|
-
loginActions,
|
|
890
|
-
appName,
|
|
891
|
-
logo,
|
|
892
|
-
colors,
|
|
893
|
-
configSource,
|
|
894
|
-
rawConfig: {
|
|
895
|
-
props: propsConfig,
|
|
896
|
-
env: envConfig,
|
|
897
|
-
cookies: cookieConfig
|
|
898
|
-
}
|
|
899
|
-
};
|
|
900
|
-
console.log("\u{1F527} ConfigurationManager - Configuration resolved:", {
|
|
901
|
-
config: {
|
|
902
|
-
env: this.resolvedConfig.env,
|
|
903
|
-
publicApiKey: `${this.resolvedConfig.publicApiKey.substring(0, 8)}...`,
|
|
904
|
-
appName: this.resolvedConfig.appName,
|
|
905
|
-
loginActionsCount: this.resolvedConfig.loginActions.length
|
|
906
|
-
},
|
|
907
|
-
sources: this.resolvedConfig.configSource
|
|
908
|
-
});
|
|
909
|
-
return this.resolvedConfig;
|
|
910
|
-
} catch (error) {
|
|
911
|
-
this.configError = error instanceof Error ? error.message : "Unknown configuration error";
|
|
912
|
-
console.error("\u{1F527} ConfigurationManager - Configuration error:", this.configError);
|
|
913
|
-
this.resolvedConfig = {
|
|
914
|
-
env: "prod",
|
|
915
|
-
publicApiKey: "",
|
|
916
|
-
loginActions: [],
|
|
917
|
-
appName: "Crudify App",
|
|
918
|
-
logo: "",
|
|
919
|
-
colors: {},
|
|
920
|
-
configSource: {
|
|
921
|
-
env: "default",
|
|
922
|
-
publicApiKey: "default",
|
|
923
|
-
loginActions: "default",
|
|
924
|
-
appName: "default",
|
|
925
|
-
logo: "default",
|
|
926
|
-
colors: "default"
|
|
927
|
-
},
|
|
928
|
-
rawConfig: {
|
|
929
|
-
props: propsConfig,
|
|
930
|
-
env: {},
|
|
931
|
-
cookies: {},
|
|
932
|
-
error: this.configError
|
|
933
|
-
}
|
|
934
|
-
};
|
|
935
|
-
return this.resolvedConfig;
|
|
936
|
-
}
|
|
937
|
-
}
|
|
938
|
-
/**
|
|
939
|
-
* Check if current configuration is still valid for the given props
|
|
940
|
-
*/
|
|
941
|
-
isConfigStillValid(propsConfig) {
|
|
942
|
-
if (!this.resolvedConfig) return false;
|
|
943
|
-
const currentProps = this.resolvedConfig.rawConfig.props;
|
|
944
|
-
return JSON.stringify(currentProps) === JSON.stringify(propsConfig);
|
|
945
|
-
}
|
|
946
|
-
/**
|
|
947
|
-
* Resolve a single config value with priority and source tracking
|
|
948
|
-
*/
|
|
949
|
-
resolveValue(key, propsValue, envValue, cookieValue, defaultValue, configSource) {
|
|
950
|
-
if (propsValue !== void 0) {
|
|
951
|
-
configSource[key] = "props";
|
|
952
|
-
return propsValue;
|
|
953
|
-
}
|
|
954
|
-
if (envValue !== void 0) {
|
|
955
|
-
configSource[key] = "env";
|
|
956
|
-
return envValue;
|
|
957
|
-
}
|
|
958
|
-
if (cookieValue !== void 0) {
|
|
959
|
-
configSource[key] = "cookies";
|
|
960
|
-
return cookieValue;
|
|
961
|
-
}
|
|
962
|
-
configSource[key] = "default";
|
|
963
|
-
return defaultValue;
|
|
964
|
-
}
|
|
965
|
-
/**
|
|
966
|
-
* Get configuration from environment variables
|
|
967
|
-
*/
|
|
968
|
-
getEnvConfig() {
|
|
969
|
-
const config = {};
|
|
970
|
-
try {
|
|
971
|
-
} catch (error) {
|
|
972
|
-
console.warn("\u{1F527} ConfigurationManager - Environment variables not available:", error);
|
|
973
|
-
}
|
|
974
|
-
return config;
|
|
975
|
-
}
|
|
976
|
-
/**
|
|
977
|
-
* Get configuration from cookies (multi-tenant support)
|
|
978
|
-
*/
|
|
979
|
-
getCookieConfig() {
|
|
980
|
-
const config = {};
|
|
981
|
-
try {
|
|
982
|
-
const env = getCookie("environment");
|
|
983
|
-
if (env && ["dev", "stg", "prod"].includes(env)) {
|
|
984
|
-
config.env = env;
|
|
985
|
-
}
|
|
986
|
-
const publicApiKey = getCookie("publicApiKey");
|
|
987
|
-
if (publicApiKey) {
|
|
988
|
-
config.publicApiKey = publicApiKey;
|
|
989
|
-
}
|
|
990
|
-
const appName = getCookie("appName");
|
|
991
|
-
if (appName) {
|
|
992
|
-
config.appName = appName;
|
|
993
|
-
}
|
|
994
|
-
const loginActions = getCookie("loginActions");
|
|
995
|
-
if (loginActions) {
|
|
996
|
-
config.loginActions = loginActions.split(",").map((action) => action.trim()).filter(Boolean);
|
|
997
|
-
}
|
|
998
|
-
const logo = getCookie("logo");
|
|
999
|
-
if (logo) {
|
|
1000
|
-
config.logo = logo;
|
|
1001
|
-
}
|
|
1002
|
-
const colors = getCookie("colors");
|
|
1003
|
-
if (colors) {
|
|
1004
|
-
try {
|
|
1005
|
-
config.colors = JSON.parse(colors);
|
|
1006
|
-
} catch (error) {
|
|
1007
|
-
console.warn("\u{1F527} ConfigurationManager - Failed to parse colors from cookie:", error);
|
|
1008
|
-
}
|
|
1009
|
-
}
|
|
1010
|
-
} catch (error) {
|
|
1011
|
-
console.warn("\u{1F527} ConfigurationManager - Error reading cookies:", error);
|
|
1012
|
-
}
|
|
1013
|
-
return config;
|
|
1014
|
-
}
|
|
1015
|
-
/**
|
|
1016
|
-
* Get the current resolved configuration
|
|
1017
|
-
*/
|
|
1018
|
-
getConfig() {
|
|
1019
|
-
return this.resolvedConfig;
|
|
1020
|
-
}
|
|
1021
|
-
/**
|
|
1022
|
-
* Get any configuration errors
|
|
1023
|
-
*/
|
|
1024
|
-
getConfigError() {
|
|
1025
|
-
return this.configError;
|
|
1026
|
-
}
|
|
1027
|
-
/**
|
|
1028
|
-
* Check if configuration is valid (no errors and has required fields)
|
|
1029
|
-
*/
|
|
1030
|
-
isConfigured() {
|
|
1031
|
-
return this.resolvedConfig !== null && this.configError === null && !!this.resolvedConfig.publicApiKey;
|
|
1032
|
-
}
|
|
1033
|
-
/**
|
|
1034
|
-
* Clear the current configuration (useful for testing or reconfiguration)
|
|
1035
|
-
*/
|
|
1036
|
-
clearConfig() {
|
|
1037
|
-
this.resolvedConfig = null;
|
|
1038
|
-
this.configError = null;
|
|
1039
|
-
}
|
|
1040
|
-
};
|
|
1041
|
-
_ConfigurationManager.instance = null;
|
|
1042
|
-
var ConfigurationManager = _ConfigurationManager;
|
|
1043
|
-
var configurationManager = ConfigurationManager.getInstance();
|
|
1044
|
-
|
|
1045
|
-
// src/core/CrudifyInitializer.ts
|
|
1046
|
-
var import_crudify_browser2 = __toESM(require("@nocios/crudify-browser"));
|
|
1047
|
-
var _CrudifyInitializer = class _CrudifyInitializer {
|
|
1048
|
-
constructor() {
|
|
1049
|
-
this.state = {
|
|
1050
|
-
isInitialized: false,
|
|
1051
|
-
isInitializing: false,
|
|
1052
|
-
initializationError: null,
|
|
1053
|
-
config: null,
|
|
1054
|
-
initializationPromise: null
|
|
1055
|
-
};
|
|
1056
|
-
console.log("\u{1F680} CrudifyInitializer - Instance created");
|
|
1057
|
-
}
|
|
1058
|
-
/**
|
|
1059
|
-
* Singleton pattern to ensure global initialization coordination
|
|
1060
|
-
*/
|
|
1061
|
-
static getInstance() {
|
|
1062
|
-
if (!_CrudifyInitializer.instance) {
|
|
1063
|
-
_CrudifyInitializer.instance = new _CrudifyInitializer();
|
|
1064
|
-
}
|
|
1065
|
-
return _CrudifyInitializer.instance;
|
|
1066
|
-
}
|
|
1067
|
-
/**
|
|
1068
|
-
* Reset the singleton instance (useful for testing)
|
|
1069
|
-
*/
|
|
1070
|
-
static resetInstance() {
|
|
1071
|
-
_CrudifyInitializer.instance = null;
|
|
1072
|
-
}
|
|
1073
|
-
/**
|
|
1074
|
-
* Initialize crudify with the given configuration
|
|
1075
|
-
* This method is idempotent and thread-safe
|
|
1076
|
-
*/
|
|
1077
|
-
async initialize(config) {
|
|
1078
|
-
if (this.state.isInitialized && this.isConfigurationSame(config)) {
|
|
1079
|
-
console.log("\u{1F680} CrudifyInitializer - Already initialized with same config");
|
|
1080
|
-
return;
|
|
1081
|
-
}
|
|
1082
|
-
if (this.state.isInitializing && this.state.initializationPromise) {
|
|
1083
|
-
console.log("\u{1F680} CrudifyInitializer - Waiting for ongoing initialization");
|
|
1084
|
-
await this.state.initializationPromise;
|
|
1085
|
-
return;
|
|
1086
|
-
}
|
|
1087
|
-
if (this.state.isInitialized && !this.isConfigurationSame(config)) {
|
|
1088
|
-
console.log("\u{1F680} CrudifyInitializer - Configuration changed, re-initializing");
|
|
1089
|
-
this.reset();
|
|
1090
|
-
}
|
|
1091
|
-
this.state.isInitializing = true;
|
|
1092
|
-
this.state.initializationError = null;
|
|
1093
|
-
this.state.initializationPromise = this.performInitialization(config);
|
|
1094
|
-
try {
|
|
1095
|
-
await this.state.initializationPromise;
|
|
1096
|
-
this.state.isInitialized = true;
|
|
1097
|
-
this.state.config = { ...config };
|
|
1098
|
-
console.log("\u{1F680} CrudifyInitializer - Initialization completed successfully");
|
|
1099
|
-
} catch (error) {
|
|
1100
|
-
this.state.initializationError = error instanceof Error ? error.message : "Unknown initialization error";
|
|
1101
|
-
console.error("\u{1F680} CrudifyInitializer - Initialization failed:", this.state.initializationError);
|
|
1102
|
-
throw error;
|
|
1103
|
-
} finally {
|
|
1104
|
-
this.state.isInitializing = false;
|
|
1105
|
-
this.state.initializationPromise = null;
|
|
1106
|
-
}
|
|
1107
|
-
}
|
|
1108
|
-
/**
|
|
1109
|
-
* Perform the actual initialization process
|
|
1110
|
-
*/
|
|
1111
|
-
async performInitialization(config) {
|
|
1112
|
-
if (!config.publicApiKey) {
|
|
1113
|
-
throw new Error("publicApiKey is required for crudify initialization");
|
|
1114
|
-
}
|
|
1115
|
-
console.log("\u{1F680} CrudifyInitializer - Starting initialization with config:", {
|
|
1116
|
-
env: config.env,
|
|
1117
|
-
publicApiKey: `${config.publicApiKey.substring(0, 8)}...`,
|
|
1118
|
-
appName: config.appName
|
|
1119
|
-
});
|
|
1120
|
-
try {
|
|
1121
|
-
const environment = config.env || "prod";
|
|
1122
|
-
console.log("\u{1F680} CrudifyInitializer - Step 1: Configuring environment:", environment);
|
|
1123
|
-
await import_crudify_browser2.default.config(environment);
|
|
1124
|
-
console.log("\u{1F680} CrudifyInitializer - Step 2: Initializing with API key");
|
|
1125
|
-
await import_crudify_browser2.default.init(config.publicApiKey, "none");
|
|
1126
|
-
console.log("\u{1F680} CrudifyInitializer - Step 3: Verifying initialization");
|
|
1127
|
-
await this.verifyInitialization();
|
|
1128
|
-
console.log("\u{1F680} CrudifyInitializer - All initialization steps completed");
|
|
1129
|
-
} catch (error) {
|
|
1130
|
-
console.error("\u{1F680} CrudifyInitializer - Initialization failed at step:", error);
|
|
1131
|
-
throw new Error(
|
|
1132
|
-
`Crudify initialization failed: ${error instanceof Error ? error.message : "Unknown error"}. Please check your configuration (env: ${config.env || "prod"}, publicApiKey: ${config.publicApiKey ? "provided" : "missing"})`
|
|
1133
|
-
);
|
|
1134
|
-
}
|
|
1135
|
-
}
|
|
1136
|
-
/**
|
|
1137
|
-
* Verify that crudify is properly initialized by checking core methods
|
|
1138
|
-
*/
|
|
1139
|
-
async verifyInitialization() {
|
|
1140
|
-
const requiredMethods = ["readItems", "readItem", "createItem", "updateItem", "deleteItem", "login", "transaction"];
|
|
1141
|
-
const missingMethods = [];
|
|
1142
|
-
for (const method of requiredMethods) {
|
|
1143
|
-
if (typeof import_crudify_browser2.default[method] !== "function") {
|
|
1144
|
-
missingMethods.push(method);
|
|
1145
|
-
}
|
|
1146
|
-
}
|
|
1147
|
-
if (missingMethods.length > 0) {
|
|
1148
|
-
throw new Error(
|
|
1149
|
-
`Crudify initialization incomplete. Missing methods: ${missingMethods.join(", ")}. This usually indicates a configuration or network issue.`
|
|
1150
|
-
);
|
|
1151
|
-
}
|
|
1152
|
-
console.log("\u{1F680} CrudifyInitializer - Verification successful (test call skipped for performance)");
|
|
1153
|
-
}
|
|
1154
|
-
/**
|
|
1155
|
-
* Check if the given configuration is the same as the current one
|
|
1156
|
-
*/
|
|
1157
|
-
isConfigurationSame(config) {
|
|
1158
|
-
if (!this.state.config) return false;
|
|
1159
|
-
return this.state.config.env === config.env && this.state.config.publicApiKey === config.publicApiKey;
|
|
1160
|
-
}
|
|
1161
|
-
/**
|
|
1162
|
-
* Reset the initialization state (useful for testing or configuration changes)
|
|
1163
|
-
*/
|
|
1164
|
-
reset() {
|
|
1165
|
-
console.log("\u{1F680} CrudifyInitializer - Resetting initialization state");
|
|
1166
|
-
this.state = {
|
|
1167
|
-
isInitialized: false,
|
|
1168
|
-
isInitializing: false,
|
|
1169
|
-
initializationError: null,
|
|
1170
|
-
config: null,
|
|
1171
|
-
initializationPromise: null
|
|
1172
|
-
};
|
|
1173
|
-
}
|
|
1174
|
-
/**
|
|
1175
|
-
* Get the current initialization status
|
|
1176
|
-
*/
|
|
1177
|
-
getStatus() {
|
|
1178
|
-
return {
|
|
1179
|
-
isInitialized: this.state.isInitialized,
|
|
1180
|
-
isInitializing: this.state.isInitializing,
|
|
1181
|
-
initializationError: this.state.initializationError,
|
|
1182
|
-
config: this.state.config
|
|
1183
|
-
};
|
|
1184
|
-
}
|
|
1185
|
-
/**
|
|
1186
|
-
* Check if crudify is ready to use
|
|
1187
|
-
*/
|
|
1188
|
-
isReady() {
|
|
1189
|
-
return this.state.isInitialized && !this.state.initializationError;
|
|
1190
|
-
}
|
|
1191
|
-
/**
|
|
1192
|
-
* Get the current initialization error, if any
|
|
1193
|
-
*/
|
|
1194
|
-
getError() {
|
|
1195
|
-
return this.state.initializationError;
|
|
1196
|
-
}
|
|
1197
|
-
/**
|
|
1198
|
-
* Force re-initialization (useful when configuration changes)
|
|
1199
|
-
*/
|
|
1200
|
-
async reinitialize(config) {
|
|
1201
|
-
console.log("\u{1F680} CrudifyInitializer - Forcing re-initialization");
|
|
1202
|
-
this.reset();
|
|
1203
|
-
await this.initialize(config);
|
|
1204
|
-
}
|
|
1205
|
-
/**
|
|
1206
|
-
* Check if initialization is currently in progress
|
|
1207
|
-
*/
|
|
1208
|
-
isInitializing() {
|
|
1209
|
-
return this.state.isInitializing;
|
|
1210
|
-
}
|
|
1211
|
-
/**
|
|
1212
|
-
* Wait for any ongoing initialization to complete
|
|
1213
|
-
*/
|
|
1214
|
-
async waitForInitialization() {
|
|
1215
|
-
if (this.state.initializationPromise) {
|
|
1216
|
-
await this.state.initializationPromise;
|
|
1217
|
-
}
|
|
1218
|
-
}
|
|
1219
|
-
};
|
|
1220
|
-
_CrudifyInitializer.instance = null;
|
|
1221
|
-
var CrudifyInitializer = _CrudifyInitializer;
|
|
1222
|
-
var crudifyInitializer = CrudifyInitializer.getInstance();
|
|
1223
|
-
|
|
1224
|
-
// src/core/TokenManager.ts
|
|
1225
|
-
var import_crudify_browser3 = __toESM(require("@nocios/crudify-browser"));
|
|
1226
|
-
|
|
1227
|
-
// src/utils/jwtUtils.ts
|
|
1228
|
-
var decodeJwtSafely = (token) => {
|
|
1229
|
-
try {
|
|
1230
|
-
const parts = token.split(".");
|
|
1231
|
-
if (parts.length !== 3) {
|
|
1232
|
-
console.warn("Invalid JWT format: token must have 3 parts");
|
|
1233
|
-
return null;
|
|
1234
|
-
}
|
|
1235
|
-
const payload = parts[1];
|
|
1236
|
-
const paddedPayload = payload + "=".repeat((4 - payload.length % 4) % 4);
|
|
1237
|
-
const decodedPayload = JSON.parse(atob(paddedPayload));
|
|
1238
|
-
return decodedPayload;
|
|
1239
|
-
} catch (error) {
|
|
1240
|
-
console.warn("Failed to decode JWT token:", error);
|
|
1241
|
-
return null;
|
|
1242
|
-
}
|
|
1243
|
-
};
|
|
1244
|
-
var getCurrentUserEmail = () => {
|
|
1245
|
-
try {
|
|
1246
|
-
let token = null;
|
|
1247
|
-
token = sessionStorage.getItem("authToken");
|
|
1248
|
-
console.log("\u{1F50D} getCurrentUserEmail - authToken:", token ? `${token.substring(0, 20)}...` : null);
|
|
1249
|
-
if (!token) {
|
|
1250
|
-
token = sessionStorage.getItem("token");
|
|
1251
|
-
console.log("\u{1F50D} getCurrentUserEmail - token:", token ? `${token.substring(0, 20)}...` : null);
|
|
1252
|
-
}
|
|
1253
|
-
if (!token) {
|
|
1254
|
-
token = localStorage.getItem("authToken") || localStorage.getItem("token");
|
|
1255
|
-
console.log("\u{1F50D} getCurrentUserEmail - localStorage:", token ? `${token.substring(0, 20)}...` : null);
|
|
1256
|
-
}
|
|
1257
|
-
if (!token) {
|
|
1258
|
-
console.warn("\u{1F50D} getCurrentUserEmail - No token found in any storage");
|
|
1259
|
-
return null;
|
|
1260
|
-
}
|
|
1261
|
-
const payload = decodeJwtSafely(token);
|
|
1262
|
-
if (!payload) {
|
|
1263
|
-
console.warn("\u{1F50D} getCurrentUserEmail - Failed to decode token");
|
|
1264
|
-
return null;
|
|
1265
|
-
}
|
|
1266
|
-
const email = payload.email || payload["cognito:username"] || null;
|
|
1267
|
-
console.log("\u{1F50D} getCurrentUserEmail - Extracted email:", email);
|
|
1268
|
-
return email;
|
|
1269
|
-
} catch (error) {
|
|
1270
|
-
console.warn("Failed to get current user email:", error);
|
|
1271
|
-
return null;
|
|
1272
|
-
}
|
|
1273
|
-
};
|
|
1274
|
-
var isTokenExpired = (token) => {
|
|
1275
|
-
try {
|
|
1276
|
-
const payload = decodeJwtSafely(token);
|
|
1277
|
-
if (!payload || !payload.exp) return true;
|
|
1278
|
-
const currentTime = Math.floor(Date.now() / 1e3);
|
|
1279
|
-
return payload.exp < currentTime;
|
|
1280
|
-
} catch {
|
|
1281
|
-
return true;
|
|
1282
|
-
}
|
|
1283
|
-
};
|
|
1284
|
-
|
|
1285
|
-
// src/core/TokenManager.ts
|
|
1286
|
-
var _TokenManager = class _TokenManager {
|
|
1287
|
-
constructor() {
|
|
1288
|
-
this.TOKEN_KEY = "authToken";
|
|
1289
|
-
// Compatible with crudia-ui
|
|
1290
|
-
this.tokenCache = null;
|
|
1291
|
-
this.parsedTokenCache = null;
|
|
1292
|
-
this.expirationCheckInterval = null;
|
|
1293
|
-
this.storageEventListener = null;
|
|
1294
|
-
this.initializeTokenManager();
|
|
1295
|
-
}
|
|
1296
|
-
/**
|
|
1297
|
-
* Singleton pattern to ensure consistent token management
|
|
1298
|
-
*/
|
|
1299
|
-
static getInstance() {
|
|
1300
|
-
if (!_TokenManager.instance) {
|
|
1301
|
-
_TokenManager.instance = new _TokenManager();
|
|
1302
|
-
}
|
|
1303
|
-
return _TokenManager.instance;
|
|
1304
|
-
}
|
|
1305
|
-
/**
|
|
1306
|
-
* Reset the singleton instance (useful for testing)
|
|
1307
|
-
*/
|
|
1308
|
-
static resetInstance() {
|
|
1309
|
-
if (_TokenManager.instance) {
|
|
1310
|
-
_TokenManager.instance.cleanup();
|
|
1311
|
-
}
|
|
1312
|
-
_TokenManager.instance = null;
|
|
1313
|
-
}
|
|
1314
|
-
/**
|
|
1315
|
-
* Initialize the token manager with storage synchronization
|
|
1316
|
-
*/
|
|
1317
|
-
initializeTokenManager() {
|
|
1318
|
-
console.log("\u{1F510} TokenManager - Initializing token management");
|
|
1319
|
-
this.migrateFromLocalStorage();
|
|
1320
|
-
this.loadTokenFromStorage();
|
|
1321
|
-
this.setupExpirationCheck();
|
|
1322
|
-
this.setupStorageListener();
|
|
1323
|
-
console.log("\u{1F510} TokenManager - Initialization complete");
|
|
1324
|
-
}
|
|
1325
|
-
/**
|
|
1326
|
-
* Migrate tokens from localStorage to sessionStorage for better security
|
|
1327
|
-
* This ensures compatibility with older implementations
|
|
1328
|
-
*/
|
|
1329
|
-
migrateFromLocalStorage() {
|
|
1330
|
-
try {
|
|
1331
|
-
const legacyKeys = ["authToken", "token", "jwt", "jwtToken"];
|
|
1332
|
-
for (const key of legacyKeys) {
|
|
1333
|
-
const token = localStorage.getItem(key);
|
|
1334
|
-
if (token && !secureSessionStorage.getToken()) {
|
|
1335
|
-
console.log(`\u{1F510} TokenManager - Migrating token from localStorage key: ${key}`);
|
|
1336
|
-
secureSessionStorage.setToken(token);
|
|
1337
|
-
localStorage.removeItem(key);
|
|
1338
|
-
break;
|
|
1339
|
-
}
|
|
1340
|
-
}
|
|
1341
|
-
} catch (error) {
|
|
1342
|
-
console.warn("\u{1F510} TokenManager - Token migration failed:", error);
|
|
1343
|
-
}
|
|
1344
|
-
}
|
|
1345
|
-
/**
|
|
1346
|
-
* Load token from storage and synchronize with crudify
|
|
1347
|
-
*/
|
|
1348
|
-
loadTokenFromStorage() {
|
|
1349
|
-
console.log("\u{1F510} TokenManager - LOAD_FROM_STORAGE: Entry point - loading token from storage");
|
|
1350
|
-
try {
|
|
1351
|
-
console.log("\u{1F510} TokenManager - LOAD_FROM_STORAGE: Getting token from secure session storage");
|
|
1352
|
-
const storedToken = secureSessionStorage.getToken();
|
|
1353
|
-
console.log("\u{1F510} TokenManager - LOAD_FROM_STORAGE: Stored token exists:", !!storedToken);
|
|
1354
|
-
if (storedToken && this.isTokenValid(storedToken)) {
|
|
1355
|
-
console.log("\u{1F510} TokenManager - LOAD_FROM_STORAGE: Stored token is valid, updating cache");
|
|
1356
|
-
this.tokenCache = storedToken;
|
|
1357
|
-
this.parsedTokenCache = this.parseToken(storedToken);
|
|
1358
|
-
this.syncTokenWithCrudify(storedToken);
|
|
1359
|
-
console.log("\u{1F510} TokenManager - LOAD_FROM_STORAGE: Token loaded from storage and synchronized");
|
|
1360
|
-
} else if (storedToken) {
|
|
1361
|
-
console.log("\u{1F510} TokenManager - LOAD_FROM_STORAGE: Stored token exists but is invalid/expired, clearing");
|
|
1362
|
-
this.clearToken();
|
|
1363
|
-
} else {
|
|
1364
|
-
console.log("\u{1F510} TokenManager - LOAD_FROM_STORAGE: No stored token found");
|
|
1365
|
-
}
|
|
1366
|
-
} catch (error) {
|
|
1367
|
-
console.warn("\u{1F510} TokenManager - LOAD_FROM_STORAGE: Error loading token from storage:", error);
|
|
1368
|
-
this.clearToken();
|
|
1369
|
-
}
|
|
1370
|
-
}
|
|
1371
|
-
/**
|
|
1372
|
-
* Set up automatic token expiration checking
|
|
1373
|
-
*/
|
|
1374
|
-
setupExpirationCheck() {
|
|
1375
|
-
this.expirationCheckInterval = window.setInterval(() => {
|
|
1376
|
-
if (this.tokenCache && !this.isTokenValid(this.tokenCache)) {
|
|
1377
|
-
console.log("\u{1F510} TokenManager - Token expired, clearing automatically");
|
|
1378
|
-
this.clearToken();
|
|
1379
|
-
}
|
|
1380
|
-
}, 3e4);
|
|
1381
|
-
}
|
|
1382
|
-
/**
|
|
1383
|
-
* Set up storage event listener for cross-tab synchronization
|
|
1384
|
-
*/
|
|
1385
|
-
setupStorageListener() {
|
|
1386
|
-
this.storageEventListener = (event) => {
|
|
1387
|
-
if (event.key === this.TOKEN_KEY) {
|
|
1388
|
-
console.log("\u{1F510} TokenManager - Token change detected from another tab");
|
|
1389
|
-
this.loadTokenFromStorage();
|
|
1390
|
-
}
|
|
1391
|
-
};
|
|
1392
|
-
window.addEventListener("storage", this.storageEventListener);
|
|
1393
|
-
}
|
|
1394
|
-
/**
|
|
1395
|
-
* Set a new JWT token with automatic synchronization
|
|
1396
|
-
*/
|
|
1397
|
-
setToken(token) {
|
|
1398
|
-
console.log("\u{1F510} TokenManager - SET_TOKEN: Entry point - setting token:", token ? "provided" : "null");
|
|
1399
|
-
try {
|
|
1400
|
-
if (!token) {
|
|
1401
|
-
console.log("\u{1F510} TokenManager - SET_TOKEN: No token provided, clearing token");
|
|
1402
|
-
this.clearToken();
|
|
1403
|
-
return;
|
|
1404
|
-
}
|
|
1405
|
-
console.log("\u{1F510} TokenManager - SET_TOKEN: Validating token before setting");
|
|
1406
|
-
if (!this.isTokenValid(token)) {
|
|
1407
|
-
console.warn("\u{1F510} TokenManager - SET_TOKEN: Attempted to set invalid or expired token");
|
|
1408
|
-
this.clearToken();
|
|
1409
|
-
return;
|
|
1410
|
-
}
|
|
1411
|
-
console.log("\u{1F510} TokenManager - SET_TOKEN: Token is valid, updating cache");
|
|
1412
|
-
this.tokenCache = token;
|
|
1413
|
-
this.parsedTokenCache = this.parseToken(token);
|
|
1414
|
-
console.log("\u{1F510} TokenManager - SET_TOKEN: Storing token in secure storage");
|
|
1415
|
-
secureSessionStorage.setToken(token);
|
|
1416
|
-
console.log("\u{1F510} TokenManager - SET_TOKEN: Synchronizing with crudify");
|
|
1417
|
-
this.syncTokenWithCrudify(token);
|
|
1418
|
-
console.log("\u{1F510} TokenManager - SET_TOKEN: Token set and synchronized successfully");
|
|
1419
|
-
} catch (error) {
|
|
1420
|
-
console.error("\u{1F510} TokenManager - SET_TOKEN: Error setting token:", error);
|
|
1421
|
-
this.clearToken();
|
|
1422
|
-
}
|
|
1423
|
-
}
|
|
1424
|
-
/**
|
|
1425
|
-
* Get the current JWT token
|
|
1426
|
-
*/
|
|
1427
|
-
getToken() {
|
|
1428
|
-
console.log("\u{1F510} TokenManager - GET_TOKEN: Entry point - checking cache");
|
|
1429
|
-
if (this.tokenCache) {
|
|
1430
|
-
console.log("\u{1F510} TokenManager - GET_TOKEN: Cache exists, validating token");
|
|
1431
|
-
if (this.isTokenValid(this.tokenCache)) {
|
|
1432
|
-
console.log("\u{1F510} TokenManager - GET_TOKEN: Cache valid, returning cached token");
|
|
1433
|
-
return this.tokenCache;
|
|
1434
|
-
} else {
|
|
1435
|
-
console.log("\u{1F510} TokenManager - GET_TOKEN: Cache invalid, clearing cache");
|
|
1436
|
-
this.tokenCache = null;
|
|
1437
|
-
}
|
|
1438
|
-
} else {
|
|
1439
|
-
console.log("\u{1F510} TokenManager - GET_TOKEN: No cache, loading from storage");
|
|
1440
|
-
}
|
|
1441
|
-
console.log("\u{1F510} TokenManager - GET_TOKEN: Loading from storage");
|
|
1442
|
-
this.loadTokenFromStorage();
|
|
1443
|
-
console.log("\u{1F510} TokenManager - GET_TOKEN: Returning final token:", !!this.tokenCache);
|
|
1444
|
-
return this.tokenCache;
|
|
1445
|
-
}
|
|
1446
|
-
/**
|
|
1447
|
-
* Parse the current JWT token
|
|
1448
|
-
*/
|
|
1449
|
-
parseToken(token) {
|
|
1450
|
-
console.log("\u{1F510} TokenManager - PARSE_TOKEN: Entry point - parsing token");
|
|
1451
|
-
const targetToken = token !== void 0 ? token : this.tokenCache;
|
|
1452
|
-
console.log("\u{1F510} TokenManager - PARSE_TOKEN: Target token exists:", !!targetToken);
|
|
1453
|
-
if (!targetToken) {
|
|
1454
|
-
console.log("\u{1F510} TokenManager - PARSE_TOKEN: No target token, returning null");
|
|
1455
|
-
return null;
|
|
1456
|
-
}
|
|
1457
|
-
if (this.tokenCache === targetToken && this.parsedTokenCache) {
|
|
1458
|
-
console.log("\u{1F510} TokenManager - PARSE_TOKEN: Returning cached parsed token");
|
|
1459
|
-
return this.parsedTokenCache;
|
|
1460
|
-
}
|
|
1461
|
-
console.log("\u{1F510} TokenManager - PARSE_TOKEN: Cache miss, parsing token with decodeJwtSafely");
|
|
1462
|
-
const parsed = decodeJwtSafely(targetToken);
|
|
1463
|
-
console.log("\u{1F510} TokenManager - PARSE_TOKEN: Token parsed successfully:", !!parsed);
|
|
1464
|
-
if (targetToken === this.tokenCache) {
|
|
1465
|
-
console.log("\u{1F510} TokenManager - PARSE_TOKEN: Updating parsed token cache");
|
|
1466
|
-
this.parsedTokenCache = parsed;
|
|
1467
|
-
}
|
|
1468
|
-
return parsed;
|
|
1469
|
-
}
|
|
1470
|
-
/**
|
|
1471
|
-
* Check if a token is valid (properly formatted and not expired)
|
|
1472
|
-
*/
|
|
1473
|
-
isTokenValid(token) {
|
|
1474
|
-
console.log("\u{1F510} TokenManager - IS_TOKEN_VALID: Entry point - checking token validity");
|
|
1475
|
-
const targetToken = token !== void 0 ? token : this.tokenCache;
|
|
1476
|
-
console.log("\u{1F510} TokenManager - IS_TOKEN_VALID: Target token exists:", !!targetToken);
|
|
1477
|
-
if (!targetToken) {
|
|
1478
|
-
console.log("\u{1F510} TokenManager - IS_TOKEN_VALID: No token, returning false");
|
|
1479
|
-
return false;
|
|
1480
|
-
}
|
|
1481
|
-
try {
|
|
1482
|
-
console.log("\u{1F510} TokenManager - IS_TOKEN_VALID: Checking if token is expired");
|
|
1483
|
-
if (isTokenExpired(targetToken)) {
|
|
1484
|
-
console.log("\u{1F510} TokenManager - IS_TOKEN_VALID: Token is expired, returning false");
|
|
1485
|
-
return false;
|
|
1486
|
-
}
|
|
1487
|
-
console.log("\u{1F510} TokenManager - IS_TOKEN_VALID: Token not expired, checking if can be parsed");
|
|
1488
|
-
const parsed = decodeJwtSafely(targetToken);
|
|
1489
|
-
const isValid = parsed !== null;
|
|
1490
|
-
console.log("\u{1F510} TokenManager - IS_TOKEN_VALID: Token parsing result:", isValid);
|
|
1491
|
-
return isValid;
|
|
1492
|
-
} catch (error) {
|
|
1493
|
-
console.log("\u{1F510} TokenManager - IS_TOKEN_VALID: Error validating token:", error);
|
|
1494
|
-
return false;
|
|
1495
|
-
}
|
|
1496
|
-
}
|
|
1497
|
-
/**
|
|
1498
|
-
* Get token expiration time as Date object
|
|
1499
|
-
*/
|
|
1500
|
-
getTokenExpiration() {
|
|
1501
|
-
const token = this.getToken();
|
|
1502
|
-
if (!token) return null;
|
|
1503
|
-
const parsed = this.parseToken(token);
|
|
1504
|
-
if (!parsed?.exp) return null;
|
|
1505
|
-
return new Date(parsed.exp * 1e3);
|
|
1506
|
-
}
|
|
1507
|
-
/**
|
|
1508
|
-
* Clear the current token from all storages and crudify
|
|
1509
|
-
*/
|
|
1510
|
-
clearToken() {
|
|
1511
|
-
console.log("\u{1F510} TokenManager - CLEAR_TOKEN: Entry point - clearing all tokens");
|
|
1512
|
-
try {
|
|
1513
|
-
console.log("\u{1F510} TokenManager - CLEAR_TOKEN: Clearing cache");
|
|
1514
|
-
this.tokenCache = null;
|
|
1515
|
-
this.parsedTokenCache = null;
|
|
1516
|
-
console.log("\u{1F510} TokenManager - CLEAR_TOKEN: Clearing from secure storage");
|
|
1517
|
-
secureSessionStorage.removeItem(this.TOKEN_KEY);
|
|
1518
|
-
console.log("\u{1F510} TokenManager - CLEAR_TOKEN: Clearing from crudify");
|
|
1519
|
-
import_crudify_browser3.default.setToken("");
|
|
1520
|
-
console.log("\u{1F510} TokenManager - CLEAR_TOKEN: Token cleared from all storages successfully");
|
|
1521
|
-
} catch (error) {
|
|
1522
|
-
console.warn("\u{1F510} TokenManager - CLEAR_TOKEN: Error clearing token:", error);
|
|
1826
|
+
} else if (!item.response || item.response.status !== "OK") {
|
|
1827
|
+
errors.push({
|
|
1828
|
+
code: ERROR_CODES.BAD_REQUEST,
|
|
1829
|
+
message: "Transaction failed",
|
|
1830
|
+
severity: "warning",
|
|
1831
|
+
details: { transactionIndex: index, response: item.response }
|
|
1832
|
+
});
|
|
1833
|
+
}
|
|
1834
|
+
});
|
|
1835
|
+
return errors;
|
|
1523
1836
|
}
|
|
1837
|
+
return parseApiError(response);
|
|
1838
|
+
} catch (error) {
|
|
1839
|
+
return [
|
|
1840
|
+
{
|
|
1841
|
+
code: ERROR_CODES.INTERNAL_SERVER_ERROR,
|
|
1842
|
+
message: "Failed to parse transaction error",
|
|
1843
|
+
severity: "error",
|
|
1844
|
+
details: { originalError: error }
|
|
1845
|
+
}
|
|
1846
|
+
];
|
|
1524
1847
|
}
|
|
1525
|
-
|
|
1526
|
-
|
|
1527
|
-
|
|
1528
|
-
|
|
1529
|
-
|
|
1530
|
-
|
|
1531
|
-
|
|
1532
|
-
|
|
1533
|
-
|
|
1848
|
+
}
|
|
1849
|
+
function isValidErrorCode(code) {
|
|
1850
|
+
return Object.values(ERROR_CODES).includes(code);
|
|
1851
|
+
}
|
|
1852
|
+
function getErrorMessage(code) {
|
|
1853
|
+
const messages = {
|
|
1854
|
+
[ERROR_CODES.INVALID_CREDENTIALS]: "Invalid email or password",
|
|
1855
|
+
[ERROR_CODES.UNAUTHORIZED]: "You are not authorized to perform this action",
|
|
1856
|
+
[ERROR_CODES.INVALID_API_KEY]: "Invalid API key",
|
|
1857
|
+
[ERROR_CODES.USER_NOT_FOUND]: "User not found",
|
|
1858
|
+
[ERROR_CODES.USER_NOT_ACTIVE]: "User account is not active",
|
|
1859
|
+
[ERROR_CODES.NO_PERMISSION]: "You do not have permission to perform this action",
|
|
1860
|
+
[ERROR_CODES.ITEM_NOT_FOUND]: "Item not found",
|
|
1861
|
+
[ERROR_CODES.NOT_FOUND]: "Resource not found",
|
|
1862
|
+
[ERROR_CODES.IN_USE]: "Resource is currently in use",
|
|
1863
|
+
[ERROR_CODES.FIELD_ERROR]: "Validation error",
|
|
1864
|
+
[ERROR_CODES.BAD_REQUEST]: "Invalid request",
|
|
1865
|
+
[ERROR_CODES.INVALID_EMAIL]: "Please enter a valid email address",
|
|
1866
|
+
[ERROR_CODES.INVALID_CODE]: "Invalid or expired code",
|
|
1867
|
+
[ERROR_CODES.INTERNAL_SERVER_ERROR]: "Internal server error",
|
|
1868
|
+
[ERROR_CODES.DATABASE_CONNECTION_ERROR]: "Database connection error",
|
|
1869
|
+
[ERROR_CODES.INVALID_CONFIGURATION]: "Invalid configuration",
|
|
1870
|
+
[ERROR_CODES.UNKNOWN_OPERATION]: "Unknown operation",
|
|
1871
|
+
[ERROR_CODES.TOO_MANY_REQUESTS]: "Too many requests. Please try again later.",
|
|
1872
|
+
[ERROR_CODES.NETWORK_ERROR]: "Network error. Please check your connection.",
|
|
1873
|
+
[ERROR_CODES.TIMEOUT_ERROR]: "Request timed out. Please try again."
|
|
1874
|
+
};
|
|
1875
|
+
return messages[code] || "An unknown error occurred";
|
|
1876
|
+
}
|
|
1877
|
+
function parseJavaScriptError(error) {
|
|
1878
|
+
if (error instanceof Error) {
|
|
1879
|
+
if (error.name === "AbortError") {
|
|
1880
|
+
return {
|
|
1881
|
+
code: ERROR_CODES.TIMEOUT_ERROR,
|
|
1882
|
+
message: "Request was cancelled",
|
|
1883
|
+
severity: "info"
|
|
1884
|
+
};
|
|
1534
1885
|
}
|
|
1535
|
-
|
|
1536
|
-
/**
|
|
1537
|
-
* Refresh token (placeholder for future implementation)
|
|
1538
|
-
*/
|
|
1539
|
-
async refreshToken() {
|
|
1540
|
-
throw new Error("Token refresh not yet implemented");
|
|
1541
|
-
}
|
|
1542
|
-
/**
|
|
1543
|
-
* Get user information from the current token
|
|
1544
|
-
*/
|
|
1545
|
-
getUserInfo() {
|
|
1546
|
-
const parsed = this.parseToken();
|
|
1547
|
-
if (!parsed) {
|
|
1886
|
+
if (error.message.includes("NetworkError") || error.message.includes("Failed to fetch")) {
|
|
1548
1887
|
return {
|
|
1549
|
-
|
|
1550
|
-
|
|
1551
|
-
|
|
1552
|
-
username: null
|
|
1888
|
+
code: ERROR_CODES.NETWORK_ERROR,
|
|
1889
|
+
message: getErrorMessage(ERROR_CODES.NETWORK_ERROR),
|
|
1890
|
+
severity: "error"
|
|
1553
1891
|
};
|
|
1554
1892
|
}
|
|
1555
1893
|
return {
|
|
1556
|
-
|
|
1557
|
-
|
|
1558
|
-
|
|
1559
|
-
|
|
1894
|
+
code: ERROR_CODES.INTERNAL_SERVER_ERROR,
|
|
1895
|
+
message: error.message || "An unexpected error occurred",
|
|
1896
|
+
severity: "error",
|
|
1897
|
+
details: { originalError: error }
|
|
1560
1898
|
};
|
|
1561
1899
|
}
|
|
1562
|
-
|
|
1563
|
-
|
|
1564
|
-
|
|
1565
|
-
|
|
1566
|
-
|
|
1567
|
-
}
|
|
1568
|
-
|
|
1569
|
-
|
|
1570
|
-
|
|
1571
|
-
|
|
1572
|
-
const expiration = this.getTokenExpiration();
|
|
1573
|
-
if (!expiration) return null;
|
|
1574
|
-
const now = /* @__PURE__ */ new Date();
|
|
1575
|
-
const minutesUntilExpiry = Math.floor((expiration.getTime() - now.getTime()) / (60 * 1e3));
|
|
1576
|
-
return Math.max(0, minutesUntilExpiry);
|
|
1577
|
-
}
|
|
1578
|
-
/**
|
|
1579
|
-
* Cleanup resources (call when the component unmounts)
|
|
1580
|
-
*/
|
|
1581
|
-
cleanup() {
|
|
1582
|
-
if (this.expirationCheckInterval) {
|
|
1583
|
-
window.clearInterval(this.expirationCheckInterval);
|
|
1584
|
-
this.expirationCheckInterval = null;
|
|
1585
|
-
}
|
|
1586
|
-
if (this.storageEventListener) {
|
|
1587
|
-
window.removeEventListener("storage", this.storageEventListener);
|
|
1588
|
-
this.storageEventListener = null;
|
|
1589
|
-
}
|
|
1590
|
-
console.log("\u{1F510} TokenManager - Cleanup completed");
|
|
1591
|
-
}
|
|
1592
|
-
/**
|
|
1593
|
-
* Get debug information about the current token state
|
|
1594
|
-
*/
|
|
1595
|
-
getDebugInfo() {
|
|
1596
|
-
const token = this.getToken();
|
|
1597
|
-
const parsed = this.parseToken();
|
|
1598
|
-
const expiration = this.getTokenExpiration();
|
|
1599
|
-
return {
|
|
1600
|
-
hasToken: !!token,
|
|
1601
|
-
tokenLength: token?.length || 0,
|
|
1602
|
-
isValid: this.isTokenValid(),
|
|
1603
|
-
isAuthenticated: this.isAuthenticated(),
|
|
1604
|
-
expiration: expiration?.toISOString() || null,
|
|
1605
|
-
minutesUntilExpiry: this.getTimeUntilExpiration(),
|
|
1606
|
-
userInfo: this.getUserInfo(),
|
|
1607
|
-
parsedTokenKeys: parsed ? Object.keys(parsed) : []
|
|
1608
|
-
};
|
|
1900
|
+
return {
|
|
1901
|
+
code: ERROR_CODES.INTERNAL_SERVER_ERROR,
|
|
1902
|
+
message: "An unknown error occurred",
|
|
1903
|
+
severity: "error",
|
|
1904
|
+
details: { originalError: error }
|
|
1905
|
+
};
|
|
1906
|
+
}
|
|
1907
|
+
function handleCrudifyError(error) {
|
|
1908
|
+
if (error instanceof Error) {
|
|
1909
|
+
return [parseJavaScriptError(error)];
|
|
1609
1910
|
}
|
|
1610
|
-
|
|
1611
|
-
|
|
1612
|
-
|
|
1613
|
-
|
|
1614
|
-
|
|
1615
|
-
// src/providers/CrudifyDataProvider.tsx
|
|
1616
|
-
var import_jsx_runtime4 = require("react/jsx-runtime");
|
|
1617
|
-
var CrudifyDataContext = (0, import_react5.createContext)(null);
|
|
1618
|
-
var CrudifyDataProvider = ({
|
|
1619
|
-
children,
|
|
1620
|
-
env,
|
|
1621
|
-
publicApiKey,
|
|
1622
|
-
loginActions,
|
|
1623
|
-
appName,
|
|
1624
|
-
logo,
|
|
1625
|
-
colors
|
|
1626
|
-
}) => {
|
|
1627
|
-
const [config, setConfig] = (0, import_react5.useState)(null);
|
|
1628
|
-
const [isConfigured, setIsConfigured] = (0, import_react5.useState)(false);
|
|
1629
|
-
const [configError, setConfigError] = (0, import_react5.useState)(null);
|
|
1630
|
-
const [isInitialized, setIsInitialized] = (0, import_react5.useState)(false);
|
|
1631
|
-
const [isInitializing, setIsInitializing] = (0, import_react5.useState)(false);
|
|
1632
|
-
const [initializationError, setInitializationError] = (0, import_react5.useState)(null);
|
|
1633
|
-
const [isAuthenticated, setIsAuthenticated] = (0, import_react5.useState)(false);
|
|
1634
|
-
const [token, setTokenState] = (0, import_react5.useState)(null);
|
|
1635
|
-
const [user, setUser] = (0, import_react5.useState)(null);
|
|
1636
|
-
const [tokenExpiration, setTokenExpiration] = (0, import_react5.useState)(null);
|
|
1637
|
-
const initializeConfiguration = (0, import_react5.useCallback)(() => {
|
|
1638
|
-
try {
|
|
1639
|
-
console.log("\u{1F30D} CrudifyDataProvider - Initializing configuration");
|
|
1640
|
-
const propsConfig = {
|
|
1641
|
-
env,
|
|
1642
|
-
publicApiKey,
|
|
1643
|
-
loginActions,
|
|
1644
|
-
appName,
|
|
1645
|
-
logo,
|
|
1646
|
-
colors
|
|
1647
|
-
};
|
|
1648
|
-
const resolvedConfig = configurationManager.resolveConfig(propsConfig);
|
|
1649
|
-
const error = configurationManager.getConfigError();
|
|
1650
|
-
setConfig(resolvedConfig);
|
|
1651
|
-
setConfigError(error);
|
|
1652
|
-
setIsConfigured(configurationManager.isConfigured());
|
|
1653
|
-
console.log("\u{1F30D} CrudifyDataProvider - Configuration initialized:", {
|
|
1654
|
-
isConfigured: configurationManager.isConfigured(),
|
|
1655
|
-
error,
|
|
1656
|
-
sources: resolvedConfig.configSource
|
|
1657
|
-
});
|
|
1658
|
-
return resolvedConfig;
|
|
1659
|
-
} catch (error) {
|
|
1660
|
-
const errorMessage = error instanceof Error ? error.message : "Configuration initialization failed";
|
|
1661
|
-
console.error("\u{1F30D} CrudifyDataProvider - Configuration error:", errorMessage);
|
|
1662
|
-
setConfigError(errorMessage);
|
|
1663
|
-
setIsConfigured(false);
|
|
1664
|
-
return null;
|
|
1665
|
-
}
|
|
1666
|
-
}, [env, publicApiKey, loginActions, appName, logo, colors]);
|
|
1667
|
-
const initializeCrudify = (0, import_react5.useCallback)(async (resolvedConfig) => {
|
|
1668
|
-
if (!resolvedConfig || !resolvedConfig.publicApiKey) {
|
|
1669
|
-
setInitializationError("Cannot initialize crudify without valid configuration");
|
|
1670
|
-
return;
|
|
1671
|
-
}
|
|
1672
|
-
try {
|
|
1673
|
-
setIsInitializing(true);
|
|
1674
|
-
setInitializationError(null);
|
|
1675
|
-
console.log("\u{1F680} CrudifyDataProvider - Starting crudify initialization");
|
|
1676
|
-
await crudifyInitializer.initialize({
|
|
1677
|
-
env: resolvedConfig.env,
|
|
1678
|
-
publicApiKey: resolvedConfig.publicApiKey,
|
|
1679
|
-
loginActions: resolvedConfig.loginActions,
|
|
1680
|
-
appName: resolvedConfig.appName,
|
|
1681
|
-
logo: resolvedConfig.logo,
|
|
1682
|
-
colors: resolvedConfig.colors
|
|
1683
|
-
});
|
|
1684
|
-
setIsInitialized(true);
|
|
1685
|
-
console.log("\u{1F680} CrudifyDataProvider - Crudify initialization completed");
|
|
1686
|
-
} catch (error) {
|
|
1687
|
-
const errorMessage = error instanceof Error ? error.message : "Crudify initialization failed";
|
|
1688
|
-
console.error("\u{1F680} CrudifyDataProvider - Initialization error:", errorMessage);
|
|
1689
|
-
setInitializationError(errorMessage);
|
|
1690
|
-
setIsInitialized(false);
|
|
1691
|
-
} finally {
|
|
1692
|
-
setIsInitializing(false);
|
|
1693
|
-
}
|
|
1694
|
-
}, []);
|
|
1695
|
-
const updateAuthenticationState = (0, import_react5.useCallback)(() => {
|
|
1696
|
-
console.log("\u{1F510} CrudifyDataProvider - UPDATE_AUTH_STATE: Starting authentication state update");
|
|
1697
|
-
try {
|
|
1698
|
-
console.log("\u{1F510} CrudifyDataProvider - UPDATE_AUTH_STATE: Getting token from TokenManager");
|
|
1699
|
-
const currentToken = tokenManager.getToken();
|
|
1700
|
-
console.log("\u{1F510} CrudifyDataProvider - UPDATE_AUTH_STATE: Token retrieved:", !!currentToken);
|
|
1701
|
-
console.log("\u{1F510} CrudifyDataProvider - UPDATE_AUTH_STATE: Parsing token");
|
|
1702
|
-
const parsedUser = tokenManager.parseToken();
|
|
1703
|
-
console.log("\u{1F510} CrudifyDataProvider - UPDATE_AUTH_STATE: Token parsed:", !!parsedUser);
|
|
1704
|
-
console.log("\u{1F510} CrudifyDataProvider - UPDATE_AUTH_STATE: Getting expiration");
|
|
1705
|
-
const expiration = tokenManager.getTokenExpiration();
|
|
1706
|
-
console.log("\u{1F510} CrudifyDataProvider - UPDATE_AUTH_STATE: Expiration retrieved:", !!expiration);
|
|
1707
|
-
console.log("\u{1F510} CrudifyDataProvider - UPDATE_AUTH_STATE: Checking authentication");
|
|
1708
|
-
const authenticated = tokenManager.isAuthenticated();
|
|
1709
|
-
console.log("\u{1F510} CrudifyDataProvider - UPDATE_AUTH_STATE: Authentication checked:", authenticated);
|
|
1710
|
-
console.log("\u{1F510} CrudifyDataProvider - UPDATE_AUTH_STATE: Updating state variables");
|
|
1711
|
-
setTokenState(currentToken);
|
|
1712
|
-
setUser(parsedUser);
|
|
1713
|
-
setTokenExpiration(expiration);
|
|
1714
|
-
setIsAuthenticated(authenticated);
|
|
1715
|
-
console.log("\u{1F510} CrudifyDataProvider - UPDATE_AUTH_STATE: Authentication state updated successfully:", {
|
|
1716
|
-
hasToken: !!currentToken,
|
|
1717
|
-
isAuthenticated: authenticated,
|
|
1718
|
-
userEmail: parsedUser?.email || null,
|
|
1719
|
-
expiration: expiration?.toISOString() || null
|
|
1720
|
-
});
|
|
1721
|
-
} catch (error) {
|
|
1722
|
-
console.error("\u{1F510} CrudifyDataProvider - UPDATE_AUTH_STATE: Error updating authentication state:", error);
|
|
1723
|
-
}
|
|
1724
|
-
}, []);
|
|
1725
|
-
const setToken = (0, import_react5.useCallback)((newToken) => {
|
|
1726
|
-
console.log("\u{1F510} CrudifyDataProvider - SET_TOKEN_CALLBACK: Setting new token:", newToken ? "provided" : "null");
|
|
1727
|
-
tokenManager.setToken(newToken);
|
|
1728
|
-
console.log("\u{1F510} CrudifyDataProvider - SET_TOKEN_CALLBACK: Updating state using newToken directly");
|
|
1729
|
-
if (newToken) {
|
|
1730
|
-
const parsedUser = tokenManager.parseToken(newToken);
|
|
1731
|
-
const expiration = tokenManager.getTokenExpiration();
|
|
1732
|
-
const authenticated = tokenManager.isTokenValid(newToken);
|
|
1733
|
-
setTokenState(newToken);
|
|
1734
|
-
setUser(parsedUser);
|
|
1735
|
-
setTokenExpiration(expiration);
|
|
1736
|
-
setIsAuthenticated(authenticated);
|
|
1737
|
-
console.log("\u{1F510} CrudifyDataProvider - SET_TOKEN_CALLBACK: Token set, state updated", {
|
|
1738
|
-
hasToken: true,
|
|
1739
|
-
isAuthenticated: authenticated,
|
|
1740
|
-
userEmail: parsedUser?.email || null
|
|
1741
|
-
});
|
|
1742
|
-
} else {
|
|
1743
|
-
setTokenState(null);
|
|
1744
|
-
setUser(null);
|
|
1745
|
-
setTokenExpiration(null);
|
|
1746
|
-
setIsAuthenticated(false);
|
|
1747
|
-
console.log("\u{1F510} CrudifyDataProvider - SET_TOKEN_CALLBACK: Token cleared, state reset");
|
|
1748
|
-
}
|
|
1749
|
-
}, []);
|
|
1750
|
-
const logout = (0, import_react5.useCallback)(() => {
|
|
1751
|
-
console.log("\u{1F510} CrudifyDataProvider - LOGOUT_CALLBACK: Logging out user");
|
|
1752
|
-
tokenManager.clearToken();
|
|
1753
|
-
console.log("\u{1F510} CrudifyDataProvider - LOGOUT_CALLBACK: Updating state directly");
|
|
1754
|
-
setTokenState(null);
|
|
1755
|
-
setUser(null);
|
|
1756
|
-
setTokenExpiration(null);
|
|
1757
|
-
setIsAuthenticated(false);
|
|
1758
|
-
console.log("\u{1F510} CrudifyDataProvider - LOGOUT_CALLBACK: User logged out, state cleared");
|
|
1759
|
-
}, []);
|
|
1760
|
-
const refreshConfig = (0, import_react5.useCallback)(() => {
|
|
1761
|
-
console.log("\u{1F30D} CrudifyDataProvider - Refreshing configuration");
|
|
1762
|
-
configurationManager.clearConfig();
|
|
1763
|
-
const newConfig = initializeConfiguration();
|
|
1764
|
-
if (newConfig && newConfig.publicApiKey) {
|
|
1765
|
-
initializeCrudify(newConfig);
|
|
1766
|
-
}
|
|
1767
|
-
}, [initializeConfiguration, initializeCrudify]);
|
|
1768
|
-
const reinitialize = (0, import_react5.useCallback)(async () => {
|
|
1769
|
-
if (!config || !config.publicApiKey) {
|
|
1770
|
-
console.warn("\u{1F680} CrudifyDataProvider - Cannot reinitialize without valid configuration");
|
|
1771
|
-
return;
|
|
1772
|
-
}
|
|
1773
|
-
console.log("\u{1F680} CrudifyDataProvider - Force reinitializing crudify");
|
|
1774
|
-
crudifyInitializer.reset();
|
|
1775
|
-
await initializeCrudify(config);
|
|
1776
|
-
}, [config, initializeCrudify]);
|
|
1777
|
-
const getDebugInfo = (0, import_react5.useCallback)(() => {
|
|
1778
|
-
return {
|
|
1779
|
-
provider: {
|
|
1780
|
-
isConfigured,
|
|
1781
|
-
configError,
|
|
1782
|
-
isInitialized,
|
|
1783
|
-
isInitializing,
|
|
1784
|
-
initializationError,
|
|
1785
|
-
isAuthenticated
|
|
1786
|
-
},
|
|
1787
|
-
configuration: {
|
|
1788
|
-
config: config ? {
|
|
1789
|
-
env: config.env,
|
|
1790
|
-
publicApiKey: `${config.publicApiKey.substring(0, 8)}...`,
|
|
1791
|
-
appName: config.appName,
|
|
1792
|
-
loginActionsCount: config.loginActions.length,
|
|
1793
|
-
hasLogo: !!config.logo,
|
|
1794
|
-
colorsCount: Object.keys(config.colors).length
|
|
1795
|
-
} : null,
|
|
1796
|
-
sources: config?.configSource || null,
|
|
1797
|
-
rawConfig: config?.rawConfig || null
|
|
1798
|
-
},
|
|
1799
|
-
authentication: {
|
|
1800
|
-
hasToken: !!token,
|
|
1801
|
-
tokenLength: token?.length || 0,
|
|
1802
|
-
userEmail: user?.email || null,
|
|
1803
|
-
userId: user?.sub || null,
|
|
1804
|
-
expiration: tokenExpiration?.toISOString() || null,
|
|
1805
|
-
minutesUntilExpiry: tokenManager.getTimeUntilExpiration()
|
|
1806
|
-
},
|
|
1807
|
-
tokenManager: tokenManager.getDebugInfo(),
|
|
1808
|
-
crudifyInitializer: crudifyInitializer.getStatus()
|
|
1809
|
-
};
|
|
1810
|
-
}, [isConfigured, configError, isInitialized, isInitializing, initializationError, isAuthenticated, config, token, user, tokenExpiration]);
|
|
1811
|
-
(0, import_react5.useEffect)(() => {
|
|
1812
|
-
console.log("\u{1F30D} CrudifyDataProvider - Provider mounting, starting initialization");
|
|
1813
|
-
const resolvedConfig = initializeConfiguration();
|
|
1814
|
-
updateAuthenticationState();
|
|
1815
|
-
if (resolvedConfig && resolvedConfig.publicApiKey) {
|
|
1816
|
-
initializeCrudify(resolvedConfig);
|
|
1911
|
+
if (typeof error === "object" && error !== null) {
|
|
1912
|
+
const response = error;
|
|
1913
|
+
if (response.data && Array.isArray(response.data)) {
|
|
1914
|
+
return parseTransactionError(error);
|
|
1817
1915
|
}
|
|
1818
|
-
return ()
|
|
1819
|
-
console.log("\u{1F30D} CrudifyDataProvider - Provider unmounting, cleaning up");
|
|
1820
|
-
tokenManager.cleanup();
|
|
1821
|
-
};
|
|
1822
|
-
}, []);
|
|
1823
|
-
(0, import_react5.useEffect)(() => {
|
|
1824
|
-
console.log("\u{1F510} CrudifyDataProvider - INITIAL_AUTH_EFFECT: Loading initial authentication state");
|
|
1825
|
-
updateAuthenticationState();
|
|
1826
|
-
}, []);
|
|
1827
|
-
const contextValue = {
|
|
1828
|
-
// Configuration
|
|
1829
|
-
config,
|
|
1830
|
-
isConfigured,
|
|
1831
|
-
configError,
|
|
1832
|
-
configSource: config ? JSON.stringify(config.configSource) : "none",
|
|
1833
|
-
// Initialization
|
|
1834
|
-
isInitialized,
|
|
1835
|
-
isInitializing,
|
|
1836
|
-
initializationError,
|
|
1837
|
-
// Authentication
|
|
1838
|
-
isAuthenticated,
|
|
1839
|
-
token,
|
|
1840
|
-
user,
|
|
1841
|
-
tokenExpiration,
|
|
1842
|
-
// Actions
|
|
1843
|
-
setToken,
|
|
1844
|
-
logout,
|
|
1845
|
-
refreshConfig,
|
|
1846
|
-
reinitialize,
|
|
1847
|
-
// Debug
|
|
1848
|
-
getDebugInfo
|
|
1849
|
-
};
|
|
1850
|
-
return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(CrudifyDataContext.Provider, { value: contextValue, children });
|
|
1851
|
-
};
|
|
1852
|
-
var useCrudifyDataContext = () => {
|
|
1853
|
-
const context = (0, import_react5.useContext)(CrudifyDataContext);
|
|
1854
|
-
if (!context) {
|
|
1855
|
-
throw new Error(
|
|
1856
|
-
"useCrudifyDataContext must be used within a CrudifyDataProvider. Make sure to wrap your app with <CrudifyDataProvider>."
|
|
1857
|
-
);
|
|
1916
|
+
return parseApiError(error);
|
|
1858
1917
|
}
|
|
1859
|
-
return
|
|
1860
|
-
|
|
1918
|
+
return [
|
|
1919
|
+
{
|
|
1920
|
+
code: ERROR_CODES.INTERNAL_SERVER_ERROR,
|
|
1921
|
+
message: "An unknown error occurred",
|
|
1922
|
+
severity: "error",
|
|
1923
|
+
details: { originalError: error }
|
|
1924
|
+
}
|
|
1925
|
+
];
|
|
1926
|
+
}
|
|
1861
1927
|
|
|
1862
1928
|
// src/hooks/useCrudifyAuth.ts
|
|
1929
|
+
init_CrudifyDataProvider();
|
|
1863
1930
|
var useCrudifyAuth = () => {
|
|
1864
1931
|
const {
|
|
1865
1932
|
isAuthenticated,
|
|
@@ -1891,7 +1958,7 @@ var useCrudifyAuth = () => {
|
|
|
1891
1958
|
// src/components/CrudifyLogin/Forms/LoginForm.tsx
|
|
1892
1959
|
var import_jsx_runtime5 = require("react/jsx-runtime");
|
|
1893
1960
|
var LoginForm = ({ onScreenChange, onExternalNavigate, onLoginSuccess, onError, redirectUrl = "/" }) => {
|
|
1894
|
-
const { crudify:
|
|
1961
|
+
const { crudify: crudify8 } = useCrudify();
|
|
1895
1962
|
const { state, updateFormData, setFieldError, clearErrors, setLoading } = useLoginState();
|
|
1896
1963
|
const { setToken } = useCrudifyAuth();
|
|
1897
1964
|
const { t } = useTranslation();
|
|
@@ -1943,16 +2010,21 @@ var LoginForm = ({ onScreenChange, onExternalNavigate, onLoginSuccess, onError,
|
|
|
1943
2010
|
clearErrors();
|
|
1944
2011
|
setLoading(true);
|
|
1945
2012
|
try {
|
|
1946
|
-
if (!
|
|
2013
|
+
if (!crudify8) {
|
|
1947
2014
|
throw new Error("Crudify not initialized");
|
|
1948
2015
|
}
|
|
1949
|
-
const response = await
|
|
2016
|
+
const response = await crudify8.login(state.formData.username, state.formData.password);
|
|
1950
2017
|
setLoading(false);
|
|
1951
2018
|
if (response.success) {
|
|
2019
|
+
console.log("\u{1F510} LoginForm - Login successful, setting tokens");
|
|
1952
2020
|
secureSessionStorage.setToken(response.data.token);
|
|
2021
|
+
console.log("\u{1F510} LoginForm - Token set in secureSessionStorage");
|
|
2022
|
+
console.log("\u{1F510} LoginForm - Setting token in CrudifyDataProvider via setToken hook");
|
|
1953
2023
|
setToken(response.data.token);
|
|
2024
|
+
console.log("\u{1F510} LoginForm - Token set in CrudifyDataProvider");
|
|
1954
2025
|
const finalRedirectUrl = getRedirectUrl();
|
|
1955
2026
|
setTimeout(() => {
|
|
2027
|
+
console.log("\u{1F510} LoginForm - Calling onLoginSuccess after delay");
|
|
1956
2028
|
if (onLoginSuccess) {
|
|
1957
2029
|
onLoginSuccess(response.data, finalRedirectUrl);
|
|
1958
2030
|
}
|
|
@@ -2104,7 +2176,7 @@ var import_react7 = require("react");
|
|
|
2104
2176
|
var import_material2 = require("@mui/material");
|
|
2105
2177
|
var import_jsx_runtime6 = require("react/jsx-runtime");
|
|
2106
2178
|
var ForgotPasswordForm = ({ onScreenChange, onError }) => {
|
|
2107
|
-
const { crudify:
|
|
2179
|
+
const { crudify: crudify8 } = useCrudify();
|
|
2108
2180
|
const [email, setEmail] = (0, import_react7.useState)("");
|
|
2109
2181
|
const [loading, setLoading] = (0, import_react7.useState)(false);
|
|
2110
2182
|
const [errors, setErrors] = (0, import_react7.useState)([]);
|
|
@@ -2133,7 +2205,7 @@ var ForgotPasswordForm = ({ onScreenChange, onError }) => {
|
|
|
2133
2205
|
return emailRegex.test(email2);
|
|
2134
2206
|
};
|
|
2135
2207
|
const handleSubmit = async () => {
|
|
2136
|
-
if (loading || !
|
|
2208
|
+
if (loading || !crudify8) return;
|
|
2137
2209
|
setErrors([]);
|
|
2138
2210
|
setHelperTextEmail(null);
|
|
2139
2211
|
if (!email) {
|
|
@@ -2147,7 +2219,7 @@ var ForgotPasswordForm = ({ onScreenChange, onError }) => {
|
|
|
2147
2219
|
setLoading(true);
|
|
2148
2220
|
try {
|
|
2149
2221
|
const data = [{ operation: "requestPasswordReset", data: { email } }];
|
|
2150
|
-
const response = await
|
|
2222
|
+
const response = await crudify8.transaction(data);
|
|
2151
2223
|
if (response.success) {
|
|
2152
2224
|
if (response.data && response.data.existingCodeValid) {
|
|
2153
2225
|
setCodeAlreadyExists(true);
|
|
@@ -2250,7 +2322,7 @@ var import_react8 = require("react");
|
|
|
2250
2322
|
var import_material3 = require("@mui/material");
|
|
2251
2323
|
var import_jsx_runtime7 = require("react/jsx-runtime");
|
|
2252
2324
|
var ResetPasswordForm = ({ onScreenChange, onError, searchParams, onResetSuccess }) => {
|
|
2253
|
-
const { crudify:
|
|
2325
|
+
const { crudify: crudify8 } = useCrudify();
|
|
2254
2326
|
const [newPassword, setNewPassword] = (0, import_react8.useState)("");
|
|
2255
2327
|
const [confirmPassword, setConfirmPassword] = (0, import_react8.useState)("");
|
|
2256
2328
|
const [loading, setLoading] = (0, import_react8.useState)(false);
|
|
@@ -2330,9 +2402,9 @@ var ResetPasswordForm = ({ onScreenChange, onError, searchParams, onResetSuccess
|
|
|
2330
2402
|
setErrors([t("resetPassword.invalidCode")]);
|
|
2331
2403
|
setValidatingCode(false);
|
|
2332
2404
|
setTimeout(() => onScreenChange?.("forgotPassword"), 3e3);
|
|
2333
|
-
}, [searchParams,
|
|
2405
|
+
}, [searchParams, crudify8, t, onScreenChange]);
|
|
2334
2406
|
(0, import_react8.useEffect)(() => {
|
|
2335
|
-
if (
|
|
2407
|
+
if (crudify8 && pendingValidation && !isValidating) {
|
|
2336
2408
|
setIsValidating(true);
|
|
2337
2409
|
const validateCode = async (emailToValidate, codeToValidate) => {
|
|
2338
2410
|
try {
|
|
@@ -2342,7 +2414,7 @@ var ResetPasswordForm = ({ onScreenChange, onError, searchParams, onResetSuccess
|
|
|
2342
2414
|
data: { email: emailToValidate, codePassword: codeToValidate }
|
|
2343
2415
|
}
|
|
2344
2416
|
];
|
|
2345
|
-
const response = await
|
|
2417
|
+
const response = await crudify8.transaction(data);
|
|
2346
2418
|
if (response.data && Array.isArray(response.data)) {
|
|
2347
2419
|
const validationResult = response.data[0];
|
|
2348
2420
|
if (validationResult && validationResult.response && validationResult.response.status === "OK") {
|
|
@@ -2371,7 +2443,7 @@ var ResetPasswordForm = ({ onScreenChange, onError, searchParams, onResetSuccess
|
|
|
2371
2443
|
};
|
|
2372
2444
|
validateCode(pendingValidation.email, pendingValidation.code);
|
|
2373
2445
|
}
|
|
2374
|
-
}, [
|
|
2446
|
+
}, [crudify8, pendingValidation, t, onScreenChange]);
|
|
2375
2447
|
const validatePassword = (password) => {
|
|
2376
2448
|
if (password.length < 8) {
|
|
2377
2449
|
return t("resetPassword.passwordTooShort");
|
|
@@ -2379,7 +2451,7 @@ var ResetPasswordForm = ({ onScreenChange, onError, searchParams, onResetSuccess
|
|
|
2379
2451
|
return null;
|
|
2380
2452
|
};
|
|
2381
2453
|
const handleSubmit = async () => {
|
|
2382
|
-
if (loading || !
|
|
2454
|
+
if (loading || !crudify8) return;
|
|
2383
2455
|
setErrors([]);
|
|
2384
2456
|
setHelperTextNewPassword(null);
|
|
2385
2457
|
setHelperTextConfirmPassword(null);
|
|
@@ -2410,7 +2482,7 @@ var ResetPasswordForm = ({ onScreenChange, onError, searchParams, onResetSuccess
|
|
|
2410
2482
|
data: { email, codePassword: code, newPassword }
|
|
2411
2483
|
}
|
|
2412
2484
|
];
|
|
2413
|
-
const response = await
|
|
2485
|
+
const response = await crudify8.transaction(data);
|
|
2414
2486
|
if (response.success) {
|
|
2415
2487
|
setErrors([]);
|
|
2416
2488
|
setTimeout(() => {
|
|
@@ -2521,7 +2593,7 @@ var import_react9 = require("react");
|
|
|
2521
2593
|
var import_material4 = require("@mui/material");
|
|
2522
2594
|
var import_jsx_runtime8 = require("react/jsx-runtime");
|
|
2523
2595
|
var CheckCodeForm = ({ onScreenChange, onError, searchParams }) => {
|
|
2524
|
-
const { crudify:
|
|
2596
|
+
const { crudify: crudify8 } = useCrudify();
|
|
2525
2597
|
const [code, setCode] = (0, import_react9.useState)("");
|
|
2526
2598
|
const [loading, setLoading] = (0, import_react9.useState)(false);
|
|
2527
2599
|
const [errors, setErrors] = (0, import_react9.useState)([]);
|
|
@@ -2560,7 +2632,7 @@ var CheckCodeForm = ({ onScreenChange, onError, searchParams }) => {
|
|
|
2560
2632
|
}
|
|
2561
2633
|
}, [searchParams, onScreenChange]);
|
|
2562
2634
|
const handleSubmit = async () => {
|
|
2563
|
-
if (loading || !
|
|
2635
|
+
if (loading || !crudify8) return;
|
|
2564
2636
|
setErrors([]);
|
|
2565
2637
|
setHelperTextCode(null);
|
|
2566
2638
|
if (!code) {
|
|
@@ -2579,7 +2651,7 @@ var CheckCodeForm = ({ onScreenChange, onError, searchParams }) => {
|
|
|
2579
2651
|
data: { email, codePassword: code }
|
|
2580
2652
|
}
|
|
2581
2653
|
];
|
|
2582
|
-
const response = await
|
|
2654
|
+
const response = await crudify8.transaction(data);
|
|
2583
2655
|
if (response.success) {
|
|
2584
2656
|
onScreenChange?.("resetPassword", { email, code, fromCodeVerification: "true" });
|
|
2585
2657
|
} else {
|
|
@@ -2704,6 +2776,7 @@ var CrudifyInitializer2 = ({ children, fallback }) => {
|
|
|
2704
2776
|
|
|
2705
2777
|
// src/components/CrudifyLogin/hooks/useCrudifyLogin.ts
|
|
2706
2778
|
var import_react10 = require("react");
|
|
2779
|
+
init_cookies();
|
|
2707
2780
|
var useCrudifyLogin = (config, _options = {}) => {
|
|
2708
2781
|
const finalConfig = (0, import_react10.useMemo)(() => {
|
|
2709
2782
|
const publicApiKey = config.publicApiKey || getCookie("publicApiKey") || null;
|
|
@@ -2830,6 +2903,7 @@ var import_icons_material = require("@mui/icons-material");
|
|
|
2830
2903
|
// src/hooks/useUserProfile.ts
|
|
2831
2904
|
var import_react11 = require("react");
|
|
2832
2905
|
var import_crudify_browser4 = __toESM(require("@nocios/crudify-browser"));
|
|
2906
|
+
init_jwtUtils();
|
|
2833
2907
|
var useUserProfile = (options = {}) => {
|
|
2834
2908
|
const { autoFetch = true, retryOnError = false, maxRetries = 3 } = options;
|
|
2835
2909
|
const [userProfile, setUserProfile] = (0, import_react11.useState)(null);
|
|
@@ -3130,9 +3204,13 @@ var UserProfileDisplay = ({
|
|
|
3130
3204
|
};
|
|
3131
3205
|
var UserProfileDisplay_default = UserProfileDisplay;
|
|
3132
3206
|
|
|
3207
|
+
// src/index.ts
|
|
3208
|
+
init_CrudifyDataProvider();
|
|
3209
|
+
|
|
3133
3210
|
// src/hooks/useCrudifyUser.ts
|
|
3134
3211
|
var import_react13 = require("react");
|
|
3135
3212
|
var import_crudify_browser5 = __toESM(require("@nocios/crudify-browser"));
|
|
3213
|
+
init_CrudifyDataProvider();
|
|
3136
3214
|
var useCrudifyUser = (options = {}) => {
|
|
3137
3215
|
const { autoFetch = true, retryOnError = false, maxRetries = 3 } = options;
|
|
3138
3216
|
const {
|
|
@@ -3337,6 +3415,7 @@ var useCrudifyUser = (options = {}) => {
|
|
|
3337
3415
|
// src/hooks/useCrudifyData.ts
|
|
3338
3416
|
var import_react14 = require("react");
|
|
3339
3417
|
var import_crudify_browser6 = __toESM(require("@nocios/crudify-browser"));
|
|
3418
|
+
init_CrudifyDataProvider();
|
|
3340
3419
|
var useCrudifyData = () => {
|
|
3341
3420
|
const {
|
|
3342
3421
|
isInitialized,
|
|
@@ -3378,7 +3457,14 @@ var useCrudifyData = () => {
|
|
|
3378
3457
|
}, [isReady, initializationError, isInitializing]);
|
|
3379
3458
|
const readItems = (0, import_react14.useCallback)(async (moduleKey, filter, options) => {
|
|
3380
3459
|
ensureReady("readItems");
|
|
3381
|
-
console.log("\u{1F4CA} useCrudifyData - readItems:"
|
|
3460
|
+
console.log("\u{1F4CA} useCrudifyData - readItems called with:");
|
|
3461
|
+
console.log(" - moduleKey:", moduleKey);
|
|
3462
|
+
console.log(" - filter:", filter);
|
|
3463
|
+
console.log(" - options:", options);
|
|
3464
|
+
if (moduleKey === "__test_connection__") {
|
|
3465
|
+
console.error("\u{1F6A8} FOUND TEST CONNECTION CALL! Stack trace:");
|
|
3466
|
+
console.error(new Error().stack);
|
|
3467
|
+
}
|
|
3382
3468
|
try {
|
|
3383
3469
|
const response = await import_crudify_browser6.default.readItems(moduleKey, filter || {}, options);
|
|
3384
3470
|
console.log("\u{1F4CA} useCrudifyData - readItems response:", response);
|
|
@@ -3481,6 +3567,7 @@ var useCrudifyData = () => {
|
|
|
3481
3567
|
};
|
|
3482
3568
|
|
|
3483
3569
|
// src/hooks/useCrudifyConfig.ts
|
|
3570
|
+
init_CrudifyDataProvider();
|
|
3484
3571
|
var useCrudifyConfig = () => {
|
|
3485
3572
|
const {
|
|
3486
3573
|
config,
|
|
@@ -3500,6 +3587,206 @@ var useCrudifyConfig = () => {
|
|
|
3500
3587
|
getDebugInfo
|
|
3501
3588
|
};
|
|
3502
3589
|
};
|
|
3590
|
+
|
|
3591
|
+
// src/hooks/useCrudifyInstance.ts
|
|
3592
|
+
var import_react15 = require("react");
|
|
3593
|
+
var import_crudify_browser7 = __toESM(require("@nocios/crudify-browser"));
|
|
3594
|
+
init_CrudifyDataProvider();
|
|
3595
|
+
var useCrudifyInstance = () => {
|
|
3596
|
+
const {
|
|
3597
|
+
isInitialized,
|
|
3598
|
+
isInitializing,
|
|
3599
|
+
initializationError
|
|
3600
|
+
} = useCrudifyDataContext();
|
|
3601
|
+
const isReady = isInitialized && !initializationError && !isInitializing;
|
|
3602
|
+
const waitForReady = (0, import_react15.useCallback)(async () => {
|
|
3603
|
+
console.log("\u{1F504} useCrudifyInstance - waitForReady: Starting wait");
|
|
3604
|
+
console.log(" - isReady:", isReady);
|
|
3605
|
+
console.log(" - isInitialized:", isInitialized);
|
|
3606
|
+
console.log(" - isInitializing:", isInitializing);
|
|
3607
|
+
console.log(" - initializationError:", initializationError);
|
|
3608
|
+
if (isReady) {
|
|
3609
|
+
console.log("\u2705 useCrudifyInstance - waitForReady: Already ready, returning immediately");
|
|
3610
|
+
return;
|
|
3611
|
+
}
|
|
3612
|
+
if (initializationError) {
|
|
3613
|
+
throw new Error(`Crudify initialization failed: ${initializationError}`);
|
|
3614
|
+
}
|
|
3615
|
+
try {
|
|
3616
|
+
console.log("\u{1F504} useCrudifyInstance - waitForReady: Using CrudifyInitializer.waitForInitialization()");
|
|
3617
|
+
const { crudifyInitializer: crudifyInitializer2 } = await Promise.resolve().then(() => (init_CrudifyDataProvider(), CrudifyDataProvider_exports));
|
|
3618
|
+
await crudifyInitializer2.waitForInitialization();
|
|
3619
|
+
console.log("\u2705 useCrudifyInstance - waitForReady: CrudifyInitializer completed");
|
|
3620
|
+
if (!crudifyInitializer2.isReady()) {
|
|
3621
|
+
const error = crudifyInitializer2.getError();
|
|
3622
|
+
throw new Error(`Crudify initialization failed: ${error || "Unknown error"}`);
|
|
3623
|
+
}
|
|
3624
|
+
console.log("\u2705 useCrudifyInstance - waitForReady: Verification successful");
|
|
3625
|
+
} catch (error) {
|
|
3626
|
+
console.error("\u274C useCrudifyInstance - waitForReady: Error during wait:", error);
|
|
3627
|
+
throw error;
|
|
3628
|
+
}
|
|
3629
|
+
}, [isReady, initializationError, isInitialized, isInitializing]);
|
|
3630
|
+
const ensureReady = (0, import_react15.useCallback)(async (operationName) => {
|
|
3631
|
+
if (!isReady) {
|
|
3632
|
+
console.log(`\u{1F504} useCrudifyInstance - ${operationName}: Waiting for crudify to be ready...`);
|
|
3633
|
+
await waitForReady();
|
|
3634
|
+
console.log(`\u2705 useCrudifyInstance - ${operationName}: Crudify is ready`);
|
|
3635
|
+
}
|
|
3636
|
+
}, [isReady, waitForReady]);
|
|
3637
|
+
const getStructure = (0, import_react15.useCallback)(async (options) => {
|
|
3638
|
+
console.log("\u{1F4E1} useCrudifyInstance - getStructure: Starting");
|
|
3639
|
+
await ensureReady("getStructure");
|
|
3640
|
+
try {
|
|
3641
|
+
console.log("\u{1F4E1} useCrudifyInstance - getStructure: Calling crudify.getStructure");
|
|
3642
|
+
const response = await import_crudify_browser7.default.getStructure(options);
|
|
3643
|
+
console.log("\u{1F4E1} useCrudifyInstance - getStructure: Response received", response);
|
|
3644
|
+
return response;
|
|
3645
|
+
} catch (error) {
|
|
3646
|
+
console.error("\u{1F4E1} useCrudifyInstance - getStructure: Error", error);
|
|
3647
|
+
throw error;
|
|
3648
|
+
}
|
|
3649
|
+
}, [ensureReady]);
|
|
3650
|
+
const getStructurePublic = (0, import_react15.useCallback)(async (options) => {
|
|
3651
|
+
console.log("\u{1F4E1} useCrudifyInstance - getStructurePublic: Starting");
|
|
3652
|
+
await ensureReady("getStructurePublic");
|
|
3653
|
+
try {
|
|
3654
|
+
console.log("\u{1F4E1} useCrudifyInstance - getStructurePublic: Calling crudify.getStructurePublic");
|
|
3655
|
+
const response = await import_crudify_browser7.default.getStructurePublic(options);
|
|
3656
|
+
console.log("\u{1F4E1} useCrudifyInstance - getStructurePublic: Response received", response);
|
|
3657
|
+
return response;
|
|
3658
|
+
} catch (error) {
|
|
3659
|
+
console.error("\u{1F4E1} useCrudifyInstance - getStructurePublic: Error", error);
|
|
3660
|
+
throw error;
|
|
3661
|
+
}
|
|
3662
|
+
}, [ensureReady]);
|
|
3663
|
+
const readItems = (0, import_react15.useCallback)(async (moduleKey, filter, options) => {
|
|
3664
|
+
await ensureReady("readItems");
|
|
3665
|
+
if (moduleKey === "__test_connection__") {
|
|
3666
|
+
console.error("\u{1F6A8} FOUND TEST CONNECTION CALL in useCrudifyInstance! Stack trace:");
|
|
3667
|
+
console.error(new Error().stack);
|
|
3668
|
+
}
|
|
3669
|
+
try {
|
|
3670
|
+
const response = await import_crudify_browser7.default.readItems(moduleKey, filter || {}, options);
|
|
3671
|
+
return response;
|
|
3672
|
+
} catch (error) {
|
|
3673
|
+
console.error("\u{1F4CA} useCrudifyInstance - readItems error:", error);
|
|
3674
|
+
throw error;
|
|
3675
|
+
}
|
|
3676
|
+
}, [ensureReady]);
|
|
3677
|
+
const readItem = (0, import_react15.useCallback)(async (moduleKey, filter, options) => {
|
|
3678
|
+
await ensureReady("readItem");
|
|
3679
|
+
try {
|
|
3680
|
+
const response = await import_crudify_browser7.default.readItem(moduleKey, filter, options);
|
|
3681
|
+
return response;
|
|
3682
|
+
} catch (error) {
|
|
3683
|
+
console.error("\u{1F4CA} useCrudifyInstance - readItem error:", error);
|
|
3684
|
+
throw error;
|
|
3685
|
+
}
|
|
3686
|
+
}, [ensureReady]);
|
|
3687
|
+
const createItem = (0, import_react15.useCallback)(async (moduleKey, data, options) => {
|
|
3688
|
+
await ensureReady("createItem");
|
|
3689
|
+
try {
|
|
3690
|
+
const response = await import_crudify_browser7.default.createItem(moduleKey, data, options);
|
|
3691
|
+
return response;
|
|
3692
|
+
} catch (error) {
|
|
3693
|
+
console.error("\u{1F4CA} useCrudifyInstance - createItem error:", error);
|
|
3694
|
+
throw error;
|
|
3695
|
+
}
|
|
3696
|
+
}, [ensureReady]);
|
|
3697
|
+
const updateItem = (0, import_react15.useCallback)(async (moduleKey, data, options) => {
|
|
3698
|
+
await ensureReady("updateItem");
|
|
3699
|
+
try {
|
|
3700
|
+
const response = await import_crudify_browser7.default.updateItem(moduleKey, data, options);
|
|
3701
|
+
return response;
|
|
3702
|
+
} catch (error) {
|
|
3703
|
+
console.error("\u{1F4CA} useCrudifyInstance - updateItem error:", error);
|
|
3704
|
+
throw error;
|
|
3705
|
+
}
|
|
3706
|
+
}, [ensureReady]);
|
|
3707
|
+
const deleteItem = (0, import_react15.useCallback)(async (moduleKey, id, options) => {
|
|
3708
|
+
await ensureReady("deleteItem");
|
|
3709
|
+
try {
|
|
3710
|
+
const response = await import_crudify_browser7.default.deleteItem(moduleKey, id, options);
|
|
3711
|
+
return response;
|
|
3712
|
+
} catch (error) {
|
|
3713
|
+
console.error("\u{1F4CA} useCrudifyInstance - deleteItem error:", error);
|
|
3714
|
+
throw error;
|
|
3715
|
+
}
|
|
3716
|
+
}, [ensureReady]);
|
|
3717
|
+
const transaction = (0, import_react15.useCallback)(async (operations, options) => {
|
|
3718
|
+
await ensureReady("transaction");
|
|
3719
|
+
try {
|
|
3720
|
+
const response = await import_crudify_browser7.default.transaction(operations, options);
|
|
3721
|
+
return response;
|
|
3722
|
+
} catch (error) {
|
|
3723
|
+
console.error("\u{1F4CA} useCrudifyInstance - transaction error:", error);
|
|
3724
|
+
throw error;
|
|
3725
|
+
}
|
|
3726
|
+
}, [ensureReady]);
|
|
3727
|
+
const login = (0, import_react15.useCallback)(async (email, password) => {
|
|
3728
|
+
await ensureReady("login");
|
|
3729
|
+
try {
|
|
3730
|
+
const response = await import_crudify_browser7.default.login(email, password);
|
|
3731
|
+
return response;
|
|
3732
|
+
} catch (error) {
|
|
3733
|
+
console.error("\u{1F4CA} useCrudifyInstance - login error:", error);
|
|
3734
|
+
throw error;
|
|
3735
|
+
}
|
|
3736
|
+
}, [ensureReady]);
|
|
3737
|
+
return {
|
|
3738
|
+
// Core operations
|
|
3739
|
+
getStructure,
|
|
3740
|
+
getStructurePublic,
|
|
3741
|
+
readItems,
|
|
3742
|
+
readItem,
|
|
3743
|
+
createItem,
|
|
3744
|
+
updateItem,
|
|
3745
|
+
deleteItem,
|
|
3746
|
+
transaction,
|
|
3747
|
+
login,
|
|
3748
|
+
// State information
|
|
3749
|
+
isReady,
|
|
3750
|
+
isInitialized,
|
|
3751
|
+
isInitializing,
|
|
3752
|
+
initializationError,
|
|
3753
|
+
// Utility methods
|
|
3754
|
+
waitForReady
|
|
3755
|
+
};
|
|
3756
|
+
};
|
|
3757
|
+
var getCrudifyInstanceAsync = async () => {
|
|
3758
|
+
console.log("\u{1F504} getCrudifyInstanceAsync - Starting");
|
|
3759
|
+
const { crudifyInitializer: crudifyInitializer2 } = await Promise.resolve().then(() => (init_CrudifyDataProvider(), CrudifyDataProvider_exports));
|
|
3760
|
+
console.log("\u{1F504} getCrudifyInstanceAsync - Checking if ready");
|
|
3761
|
+
console.log(" - crudifyInitializer.isReady():", crudifyInitializer2.isReady());
|
|
3762
|
+
console.log(" - crudifyInitializer.getStatus():", crudifyInitializer2.getStatus());
|
|
3763
|
+
if (!crudifyInitializer2.isReady()) {
|
|
3764
|
+
console.log("\u{1F504} getCrudifyInstanceAsync - Waiting for crudify initialization...");
|
|
3765
|
+
await crudifyInitializer2.waitForInitialization();
|
|
3766
|
+
if (!crudifyInitializer2.isReady()) {
|
|
3767
|
+
const error = crudifyInitializer2.getError();
|
|
3768
|
+
throw new Error(`Crudify initialization failed: ${error || "Unknown error after waiting"}`);
|
|
3769
|
+
}
|
|
3770
|
+
console.log("\u2705 getCrudifyInstanceAsync - Crudify is ready after waiting");
|
|
3771
|
+
} else {
|
|
3772
|
+
console.log("\u2705 getCrudifyInstanceAsync - Already ready, no wait needed");
|
|
3773
|
+
}
|
|
3774
|
+
console.log("\u2705 getCrudifyInstanceAsync - Returning crudify instance");
|
|
3775
|
+
return import_crudify_browser7.default;
|
|
3776
|
+
};
|
|
3777
|
+
var getCrudifyInstanceSync = async () => {
|
|
3778
|
+
const { crudifyInitializer: crudifyInitializer2 } = await Promise.resolve().then(() => (init_CrudifyDataProvider(), CrudifyDataProvider_exports));
|
|
3779
|
+
if (!crudifyInitializer2.isReady()) {
|
|
3780
|
+
throw new Error("Crudify not ready. Use getCrudifyInstanceAsync() or call this from within a React component using useCrudifyInstance()");
|
|
3781
|
+
}
|
|
3782
|
+
return import_crudify_browser7.default;
|
|
3783
|
+
};
|
|
3784
|
+
|
|
3785
|
+
// src/index.ts
|
|
3786
|
+
init_CrudifyDataProvider();
|
|
3787
|
+
init_jwtUtils();
|
|
3788
|
+
init_cookies();
|
|
3789
|
+
init_secureStorage();
|
|
3503
3790
|
// Annotate the CommonJS export names for ESM import in node:
|
|
3504
3791
|
0 && (module.exports = {
|
|
3505
3792
|
CrudifyDataProvider,
|
|
@@ -3512,6 +3799,8 @@ var useCrudifyConfig = () => {
|
|
|
3512
3799
|
crudifyInitializer,
|
|
3513
3800
|
decodeJwtSafely,
|
|
3514
3801
|
getCookie,
|
|
3802
|
+
getCrudifyInstanceAsync,
|
|
3803
|
+
getCrudifyInstanceSync,
|
|
3515
3804
|
getCurrentUserEmail,
|
|
3516
3805
|
getErrorMessage,
|
|
3517
3806
|
handleCrudifyError,
|
|
@@ -3526,6 +3815,7 @@ var useCrudifyConfig = () => {
|
|
|
3526
3815
|
useCrudifyConfig,
|
|
3527
3816
|
useCrudifyData,
|
|
3528
3817
|
useCrudifyDataContext,
|
|
3818
|
+
useCrudifyInstance,
|
|
3529
3819
|
useCrudifyLogin,
|
|
3530
3820
|
useCrudifyUser,
|
|
3531
3821
|
useUserProfile,
|