@crownpeak/dqm-react-component 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (87) hide show
  1. package/AUTHENTICATION.md +281 -0
  2. package/BACKEND-API.md +1829 -0
  3. package/CHANGELOG.md +28 -0
  4. package/DEVELOPMENT.md +339 -0
  5. package/EXAMPLES.md +194 -0
  6. package/LICENSE +22 -0
  7. package/QUICKSTART.md +200 -0
  8. package/README.md +213 -0
  9. package/dist/DQMSidebar.d.ts +5 -0
  10. package/dist/DQMSidebar.d.ts.map +1 -0
  11. package/dist/ErrorBoundary.d.ts +34 -0
  12. package/dist/ErrorBoundary.d.ts.map +1 -0
  13. package/dist/auth-ui/assets/index-CehNKFGj.js +158 -0
  14. package/dist/auth-ui/index.html +30 -0
  15. package/dist/components/auth/DQMLogin.d.ts +16 -0
  16. package/dist/components/auth/DQMLogin.d.ts.map +1 -0
  17. package/dist/components/auth/OAuth2CallbackHandler.d.ts +15 -0
  18. package/dist/components/auth/OAuth2CallbackHandler.d.ts.map +1 -0
  19. package/dist/components/auth/index.d.ts +3 -0
  20. package/dist/components/auth/index.d.ts.map +1 -0
  21. package/dist/components/cards/CategoryCard.d.ts +2 -0
  22. package/dist/components/cards/CategoryCard.d.ts.map +1 -0
  23. package/dist/components/cards/FailedCheckpointsCard.d.ts +2 -0
  24. package/dist/components/cards/FailedCheckpointsCard.d.ts.map +1 -0
  25. package/dist/components/cards/QualityOverviewCard.d.ts +2 -0
  26. package/dist/components/cards/QualityOverviewCard.d.ts.map +1 -0
  27. package/dist/components/cards/index.d.ts +4 -0
  28. package/dist/components/cards/index.d.ts.map +1 -0
  29. package/dist/components/common/CircularProgressWithLabel.d.ts +5 -0
  30. package/dist/components/common/CircularProgressWithLabel.d.ts.map +1 -0
  31. package/dist/components/common/index.d.ts +2 -0
  32. package/dist/components/common/index.d.ts.map +1 -0
  33. package/dist/components/renderers/BrowserViewRenderer.d.ts +9 -0
  34. package/dist/components/renderers/BrowserViewRenderer.d.ts.map +1 -0
  35. package/dist/components/renderers/SafeParsedHtml.d.ts +4 -0
  36. package/dist/components/renderers/SafeParsedHtml.d.ts.map +1 -0
  37. package/dist/components/renderers/ShadowDOMRenderer.d.ts +11 -0
  38. package/dist/components/renderers/ShadowDOMRenderer.d.ts.map +1 -0
  39. package/dist/components/renderers/index.d.ts +4 -0
  40. package/dist/components/renderers/index.d.ts.map +1 -0
  41. package/dist/components/sidebar/SidebarContent.d.ts +2 -0
  42. package/dist/components/sidebar/SidebarContent.d.ts.map +1 -0
  43. package/dist/components/sidebar/SidebarFooter.d.ts +5 -0
  44. package/dist/components/sidebar/SidebarFooter.d.ts.map +1 -0
  45. package/dist/components/sidebar/SidebarHeader.d.ts +2 -0
  46. package/dist/components/sidebar/SidebarHeader.d.ts.map +1 -0
  47. package/dist/components/sidebar/SidebarSkeleton.d.ts +5 -0
  48. package/dist/components/sidebar/SidebarSkeleton.d.ts.map +1 -0
  49. package/dist/components/sidebar/StyledDrawer.d.ts +2 -0
  50. package/dist/components/sidebar/StyledDrawer.d.ts.map +1 -0
  51. package/dist/components/sidebar/StyledFab.d.ts +4 -0
  52. package/dist/components/sidebar/StyledFab.d.ts.map +1 -0
  53. package/dist/components/sidebar/index.d.ts +7 -0
  54. package/dist/components/sidebar/index.d.ts.map +1 -0
  55. package/dist/index.cjs +113 -0
  56. package/dist/index.cjs.map +1 -0
  57. package/dist/index.d.ts +4 -0
  58. package/dist/index.d.ts.map +1 -0
  59. package/dist/index.js +13712 -0
  60. package/dist/index.js.map +1 -0
  61. package/dist/server/config.js +21 -0
  62. package/dist/server/config.js.map +1 -0
  63. package/dist/server/index.js +74 -0
  64. package/dist/server/index.js.map +1 -0
  65. package/dist/server/middleware/authenticate.js +31 -0
  66. package/dist/server/middleware/authenticate.js.map +1 -0
  67. package/dist/server/middleware/errorHandler.js +8 -0
  68. package/dist/server/middleware/errorHandler.js.map +1 -0
  69. package/dist/server/routes/auth.js +142 -0
  70. package/dist/server/routes/auth.js.map +1 -0
  71. package/dist/server/routes/dqm.js +138 -0
  72. package/dist/server/routes/dqm.js.map +1 -0
  73. package/dist/server/services/dqmClient.js +127 -0
  74. package/dist/server/services/dqmClient.js.map +1 -0
  75. package/dist/server/services/sessionStore.js +250 -0
  76. package/dist/server/services/sessionStore.js.map +1 -0
  77. package/dist/server/types.js +2 -0
  78. package/dist/server/types.js.map +1 -0
  79. package/dist/types.d.ts +76 -0
  80. package/dist/types.d.ts.map +1 -0
  81. package/dist/utils/colors/GenerateCategoryColors.d.ts +12 -0
  82. package/dist/utils/colors/GenerateCategoryColors.d.ts.map +1 -0
  83. package/dist/utils/localStorage.d.ts +4 -0
  84. package/dist/utils/localStorage.d.ts.map +1 -0
  85. package/dist/utils/storage.d.ts +28 -0
  86. package/dist/utils/storage.d.ts.map +1 -0
  87. package/package.json +124 -0
@@ -0,0 +1,250 @@
1
+ import crypto from 'crypto';
2
+ import { config } from '../config.js';
3
+ import Redis from 'ioredis';
4
+ class SessionStore {
5
+ redis = null;
6
+ memoryStore = new Map();
7
+ useRedis = false;
8
+ constructor() {
9
+ this.initializeRedis();
10
+ }
11
+ /**
12
+ * Initialize Redis connection
13
+ */
14
+ async initializeRedis() {
15
+ const redisUrl = process.env.REDIS_URL;
16
+ if (redisUrl) {
17
+ try {
18
+ this.redis = new Redis(redisUrl, {
19
+ retryStrategy: (times) => {
20
+ if (times > 3) {
21
+ console.error('[SessionStore] Redis connection failed after 3 retries, falling back to in-memory');
22
+ return null; // Stop retrying
23
+ }
24
+ return Math.min(times * 100, 3000);
25
+ },
26
+ maxRetriesPerRequest: 3,
27
+ });
28
+ this.redis.on('connect', () => {
29
+ console.log('[SessionStore] ✅ Connected to Redis');
30
+ this.useRedis = true;
31
+ });
32
+ this.redis.on('error', (err) => {
33
+ console.error('[SessionStore] Redis error:', err.message);
34
+ this.useRedis = false;
35
+ });
36
+ this.redis.on('close', () => {
37
+ console.warn('[SessionStore] Redis connection closed, using in-memory fallback');
38
+ this.useRedis = false;
39
+ });
40
+ // Test connection
41
+ await this.redis.ping();
42
+ this.useRedis = true;
43
+ console.log('[SessionStore] Redis connection successful');
44
+ }
45
+ catch (error) {
46
+ console.warn('[SessionStore] Redis not available, using in-memory storage:', error instanceof Error ? error.message : 'Unknown error');
47
+ this.redis = null;
48
+ this.useRedis = false;
49
+ }
50
+ }
51
+ else {
52
+ console.log('[SessionStore] No REDIS_URL configured, using in-memory storage (sessions will be lost on restart)');
53
+ }
54
+ }
55
+ /**
56
+ * Generate a unique session token
57
+ */
58
+ generateToken() {
59
+ return crypto.randomBytes(32).toString('hex');
60
+ }
61
+ /**
62
+ * Create a new session
63
+ */
64
+ async create(apiKey, websiteId, userId) {
65
+ const token = this.generateToken();
66
+ const now = Date.now();
67
+ const session = {
68
+ apiKey,
69
+ websiteId,
70
+ userId,
71
+ createdAt: now,
72
+ expiresAt: now + config.session.ttl,
73
+ };
74
+ if (this.useRedis && this.redis) {
75
+ try {
76
+ // Store in Redis with TTL
77
+ await this.redis.setex(`session:${token}`, Math.floor(config.session.ttl / 1000), // TTL in seconds
78
+ JSON.stringify(session));
79
+ console.log(`[SessionStore] Created Redis session: ${token.substring(0, 8)}... (expires in ${config.session.ttl / 1000 / 60} minutes)`);
80
+ }
81
+ catch (error) {
82
+ console.error('[SessionStore] Redis write failed, falling back to in-memory:', error);
83
+ this.memoryStore.set(token, session);
84
+ }
85
+ }
86
+ else {
87
+ // Fallback to in-memory
88
+ this.memoryStore.set(token, session);
89
+ console.log(`[SessionStore] Created in-memory session: ${token.substring(0, 8)}... (expires in ${config.session.ttl / 1000 / 60} minutes)`);
90
+ }
91
+ return token;
92
+ }
93
+ /**
94
+ * Get session data by token
95
+ */
96
+ async get(token) {
97
+ if (this.useRedis && this.redis) {
98
+ try {
99
+ const data = await this.redis.get(`session:${token}`);
100
+ if (!data) {
101
+ return null;
102
+ }
103
+ const session = JSON.parse(data);
104
+ // Check if session expired (redundant check, Redis TTL should handle this)
105
+ if (Date.now() > session.expiresAt) {
106
+ await this.redis.del(`session:${token}`);
107
+ console.log(`[SessionStore] Session expired: ${token.substring(0, 8)}...`);
108
+ return null;
109
+ }
110
+ return session;
111
+ }
112
+ catch (error) {
113
+ console.error('[SessionStore] Redis read failed, checking in-memory:', error);
114
+ return this.getFromMemory(token);
115
+ }
116
+ }
117
+ else {
118
+ return this.getFromMemory(token);
119
+ }
120
+ }
121
+ /**
122
+ * Get session from in-memory store
123
+ */
124
+ getFromMemory(token) {
125
+ const session = this.memoryStore.get(token);
126
+ if (!session) {
127
+ return null;
128
+ }
129
+ // Check if session expired
130
+ if (Date.now() > session.expiresAt) {
131
+ this.memoryStore.delete(token);
132
+ console.log(`[SessionStore] Session expired: ${token.substring(0, 8)}...`);
133
+ return null;
134
+ }
135
+ return session;
136
+ }
137
+ /**
138
+ * Delete a session
139
+ */
140
+ async delete(token) {
141
+ if (this.useRedis && this.redis) {
142
+ try {
143
+ const result = await this.redis.del(`session:${token}`);
144
+ if (result > 0) {
145
+ console.log(`[SessionStore] Deleted Redis session: ${token.substring(0, 8)}...`);
146
+ return true;
147
+ }
148
+ return false;
149
+ }
150
+ catch (error) {
151
+ console.error('[SessionStore] Redis delete failed:', error);
152
+ return this.memoryStore.delete(token);
153
+ }
154
+ }
155
+ else {
156
+ const deleted = this.memoryStore.delete(token);
157
+ if (deleted) {
158
+ console.log(`[SessionStore] Deleted in-memory session: ${token.substring(0, 8)}...`);
159
+ }
160
+ return deleted;
161
+ }
162
+ }
163
+ /**
164
+ * Extend session expiration
165
+ */
166
+ async extend(token) {
167
+ if (this.useRedis && this.redis) {
168
+ try {
169
+ // Get current session data
170
+ const data = await this.redis.get(`session:${token}`);
171
+ if (!data) {
172
+ return false;
173
+ }
174
+ const session = JSON.parse(data);
175
+ session.expiresAt = Date.now() + config.session.ttl;
176
+ // Update with new expiration
177
+ await this.redis.setex(`session:${token}`, Math.floor(config.session.ttl / 1000), JSON.stringify(session));
178
+ return true;
179
+ }
180
+ catch (error) {
181
+ console.error('[SessionStore] Redis extend failed:', error);
182
+ return this.extendInMemory(token);
183
+ }
184
+ }
185
+ else {
186
+ return this.extendInMemory(token);
187
+ }
188
+ }
189
+ /**
190
+ * Extend session in memory
191
+ */
192
+ extendInMemory(token) {
193
+ const session = this.memoryStore.get(token);
194
+ if (!session) {
195
+ return false;
196
+ }
197
+ session.expiresAt = Date.now() + config.session.ttl;
198
+ return true;
199
+ }
200
+ /**
201
+ * Clean up expired sessions (only for in-memory)
202
+ */
203
+ cleanup() {
204
+ const now = Date.now();
205
+ let cleaned = 0;
206
+ for (const [token, session] of this.memoryStore.entries()) {
207
+ if (now > session.expiresAt) {
208
+ this.memoryStore.delete(token);
209
+ cleaned++;
210
+ }
211
+ }
212
+ if (cleaned > 0) {
213
+ console.log(`[SessionStore] Cleaned up ${cleaned} expired in-memory sessions`);
214
+ }
215
+ return cleaned;
216
+ }
217
+ /**
218
+ * Get session count (for monitoring)
219
+ */
220
+ async count() {
221
+ if (this.useRedis && this.redis) {
222
+ try {
223
+ const keys = await this.redis.keys('session:*');
224
+ return keys.length;
225
+ }
226
+ catch (error) {
227
+ console.error('[SessionStore] Redis count failed:', error);
228
+ return this.memoryStore.size;
229
+ }
230
+ }
231
+ else {
232
+ return this.memoryStore.size;
233
+ }
234
+ }
235
+ /**
236
+ * Get storage type
237
+ */
238
+ getStorageType() {
239
+ return this.useRedis ? 'redis' : 'memory';
240
+ }
241
+ }
242
+ // Singleton instance
243
+ export const sessionStore = new SessionStore();
244
+ // Auto-cleanup for in-memory sessions every hour
245
+ setInterval(() => {
246
+ if (sessionStore.getStorageType() === 'memory') {
247
+ sessionStore.cleanup();
248
+ }
249
+ }, 60 * 60 * 1000);
250
+ //# sourceMappingURL=sessionStore.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sessionStore.js","sourceRoot":"","sources":["../../../server/services/sessionStore.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../server/types.ts"],"names":[],"mappings":""}
@@ -0,0 +1,76 @@
1
+ import { default as React } from 'react';
2
+ export type AnalysisState = 'idle' | 'analyzing' | 'completed' | 'error';
3
+ export type AuthMode = 'props' | 'localStorage' | 'backend';
4
+ export type SessionType = 'direct' | 'backend';
5
+ export interface OAuth2Config {
6
+ authUrl: string;
7
+ tokenUrl: string;
8
+ clientId: string;
9
+ redirectUri: string;
10
+ scope?: string;
11
+ }
12
+ export interface DQMConfig {
13
+ apiKey?: string;
14
+ websiteId?: string;
15
+ authBackendUrl?: string;
16
+ oauth2Config?: OAuth2Config;
17
+ useLocalStorage?: boolean;
18
+ disabled?: boolean;
19
+ apiEndpoint?: string;
20
+ }
21
+ export interface DQMSidebarProps {
22
+ open: boolean;
23
+ onOpen: () => void;
24
+ onClose: () => void;
25
+ config?: DQMConfig;
26
+ onAuthSuccess?: (credentials: {
27
+ apiKey: string;
28
+ websiteId: string;
29
+ sessionToken?: string;
30
+ sessionType: SessionType;
31
+ }) => void;
32
+ onAuthError?: (error: Error) => void;
33
+ debugHtml?: string;
34
+ }
35
+ export interface ErrorBoundaryProps {
36
+ children: React.ReactNode;
37
+ /** When any value in this array changes, the boundary resets (e.g. route changes). */
38
+ resetKeys?: unknown[];
39
+ }
40
+ export interface Checkpoint {
41
+ colors: {
42
+ bg: string;
43
+ text: string;
44
+ };
45
+ id: string;
46
+ name: string;
47
+ description?: string;
48
+ reference: string;
49
+ number: number;
50
+ categoryNumber: number;
51
+ category: string;
52
+ priority: boolean;
53
+ failed: boolean;
54
+ topics: string[];
55
+ canHighlight: {
56
+ page: boolean;
57
+ source: boolean;
58
+ };
59
+ restricted: boolean;
60
+ checkpointType?: {
61
+ name: string;
62
+ modifiedBy: string;
63
+ modified: string;
64
+ };
65
+ created: string;
66
+ modified: string;
67
+ }
68
+ export interface AnalysisData {
69
+ assetId: string;
70
+ created: string;
71
+ siteName: string;
72
+ totalCheckpoints: number;
73
+ totalErrors: number;
74
+ checkpoints: Checkpoint[];
75
+ }
76
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,MAAM,OAAO,CAAC;AAG1B,MAAM,MAAM,aAAa,GAAG,MAAM,GAAG,WAAW,GAAG,WAAW,GAAG,OAAO,CAAC;AAGzE,MAAM,MAAM,QAAQ,GAAG,OAAO,GAAG,cAAc,GAAG,SAAS,CAAC;AAG5D,MAAM,MAAM,WAAW,GAAG,QAAQ,GAAG,SAAS,CAAC;AAG/C,MAAM,WAAW,YAAY;IAC3B,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;IACpB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAGD,MAAM,WAAW,SAAS;IAExB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE,MAAM,CAAC;IAGnB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,YAAY,CAAC,EAAE,YAAY,CAAC;IAG5B,eAAe,CAAC,EAAE,OAAO,CAAC;IAG1B,QAAQ,CAAC,EAAE,OAAO,CAAC;IAGnB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAGD,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,OAAO,CAAC;IACd,MAAM,EAAE,MAAM,IAAI,CAAC;IACnB,OAAO,EAAE,MAAM,IAAI,CAAC;IAGpB,MAAM,CAAC,EAAE,SAAS,CAAC;IAGnB,aAAa,CAAC,EAAE,CAAC,WAAW,EAAE;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAC;QAAC,YAAY,CAAC,EAAE,MAAM,CAAC;QAAC,WAAW,EAAE,WAAW,CAAA;KAAE,KAAK,IAAI,CAAC;IAC9H,WAAW,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,CAAC;IAErC,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAGD,MAAM,WAAW,kBAAkB;IACjC,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;IAC1B,sFAAsF;IACtF,SAAS,CAAC,EAAE,OAAO,EAAE,CAAC;CACvB;AAGD,MAAM,WAAW,UAAU;IACzB,MAAM,EAAE;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC;IACrC,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;IACf,cAAc,EAAE,MAAM,CAAC;IACvB,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,OAAO,CAAC;IAClB,MAAM,EAAE,OAAO,CAAC;IAChB,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,YAAY,EAAE;QACZ,IAAI,EAAE,OAAO,CAAC;QACd,MAAM,EAAE,OAAO,CAAC;KACjB,CAAC;IACF,UAAU,EAAE,OAAO,CAAC;IACpB,cAAc,CAAC,EAAE;QACf,IAAI,EAAE,MAAM,CAAC;QACb,UAAU,EAAE,MAAM,CAAC;QACnB,QAAQ,EAAE,MAAM,CAAC;KAClB,CAAC;IACF,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;CAClB;AAGD,MAAM,WAAW,YAAY;IAC3B,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;IACjB,gBAAgB,EAAE,MAAM,CAAC;IACzB,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,UAAU,EAAE,CAAC;CAC3B"}
@@ -0,0 +1,12 @@
1
+ export declare const generateCategoryColors: (categories: string[]) => Record<string, string>;
2
+ export declare const hexToRgb: (hex: string) => {
3
+ r: number;
4
+ g: number;
5
+ b: number;
6
+ };
7
+ export declare const getContrastTextColor: (bgColor: string) => "#000000" | "#FFFFFF";
8
+ export declare const getCategoryColor: (category: string, allCategories?: string[]) => {
9
+ bg: string;
10
+ text: string;
11
+ };
12
+ //# sourceMappingURL=GenerateCategoryColors.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"GenerateCategoryColors.d.ts","sourceRoot":"","sources":["../../../src/utils/colors/GenerateCategoryColors.tsx"],"names":[],"mappings":"AAIA,eAAO,MAAM,sBAAsB,GAAI,YAAY,MAAM,EAAE,KAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CA0BlF,CAAC;AACF,eAAO,MAAM,QAAQ,GAAI,KAAK,MAAM;;;;CAenC,CAAC;AACF,eAAO,MAAM,oBAAoB,GAAI,SAAS,MAAM,0BA0BnD,CAAC;AACF,eAAO,MAAM,gBAAgB,GAAI,UAAU,MAAM,EAAE,gBAAe,MAAM,EAAO,KAAG;IAC9E,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;CAmBhB,CAAC"}
@@ -0,0 +1,4 @@
1
+ export declare const getLocalStorageItem: (key: string) => string | null;
2
+ export declare const setLocalStorageItem: (key: string, value: string) => void;
3
+ export declare const removeLocalStorageItem: (key: string) => void;
4
+ //# sourceMappingURL=localStorage.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"localStorage.d.ts","sourceRoot":"","sources":["../../src/utils/localStorage.ts"],"names":[],"mappings":"AACA,eAAO,MAAM,mBAAmB,GAAI,KAAK,MAAM,KAAG,MAAM,GAAG,IAG1D,CAAC;AAEF,eAAO,MAAM,mBAAmB,GAAI,KAAK,MAAM,EAAE,OAAO,MAAM,KAAG,IAGhE,CAAC;AAEF,eAAO,MAAM,sBAAsB,GAAI,KAAK,MAAM,KAAG,IAGpD,CAAC"}
@@ -0,0 +1,28 @@
1
+ /**
2
+ * Save HTML content to IndexedDB
3
+ * @param key Storage key
4
+ * @param value HTML string to store
5
+ */
6
+ export declare const saveHtmlToStorage: (key: string, value: string) => Promise<void>;
7
+ /**
8
+ * Load HTML content from IndexedDB
9
+ * @param key Storage key
10
+ * @returns HTML string or null if not found
11
+ */
12
+ export declare const loadHtmlFromStorage: (key: string) => Promise<string | null>;
13
+ /**
14
+ * Delete HTML content from IndexedDB
15
+ * @param key Storage key
16
+ */
17
+ export declare const deleteHtmlFromStorage: (key: string) => Promise<void>;
18
+ /**
19
+ * Get the approximate size of stored HTML content
20
+ * @param key Storage key
21
+ * @returns Size in bytes, or 0 if not found
22
+ */
23
+ export declare const getStorageSize: (key: string) => Promise<number>;
24
+ /**
25
+ * Format bytes to human-readable string
26
+ */
27
+ export declare const formatBytes: (bytes: number) => string;
28
+ //# sourceMappingURL=storage.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"storage.d.ts","sourceRoot":"","sources":["../../src/utils/storage.ts"],"names":[],"mappings":"AAgCA;;;;GAIG;AACH,eAAO,MAAM,iBAAiB,GAAU,KAAK,MAAM,EAAE,OAAO,MAAM,KAAG,OAAO,CAAC,IAAI,CAehF,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,mBAAmB,GAAU,KAAK,MAAM,KAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAe5E,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,qBAAqB,GAAU,KAAK,MAAM,KAAG,OAAO,CAAC,IAAI,CAerE,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,cAAc,GAAU,KAAK,MAAM,KAAG,OAAO,CAAC,MAAM,CAMhE,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,WAAW,GAAI,OAAO,MAAM,KAAG,MAQ3C,CAAC"}
package/package.json ADDED
@@ -0,0 +1,124 @@
1
+ {
2
+ "name": "@crownpeak/dqm-react-component",
3
+ "version": "1.0.0",
4
+ "private": false,
5
+ "description": "A React component for Crownpeak Digital Quality Management (DQM) integration",
6
+ "type": "module",
7
+ "main": "./dist/index.cjs",
8
+ "module": "./dist/index.js",
9
+ "types": "./dist/index.d.ts",
10
+ "exports": {
11
+ ".": {
12
+ "types": "./dist/index.d.ts",
13
+ "import": "./dist/index.js",
14
+ "require": "./dist/index.cjs",
15
+ "default": "./dist/index.js"
16
+ },
17
+ "./dist/*": "./dist/*",
18
+ "./package.json": "./package.json"
19
+ },
20
+ "sideEffects": false,
21
+ "files": [
22
+ "dist",
23
+ "README.md",
24
+ "LICENSE",
25
+ "CHANGELOG.md",
26
+ "QUICKSTART.md",
27
+ "EXAMPLES.md",
28
+ "AUTHENTICATION.md",
29
+ "BACKEND-API.md",
30
+ "DEVELOPMENT.md",
31
+ "PUBLISHING.md"
32
+ ],
33
+ "keywords": [
34
+ "react",
35
+ "crownpeak",
36
+ "dqm",
37
+ "digital-quality-management",
38
+ "accessibility",
39
+ "quality-analysis",
40
+ "mui",
41
+ "component"
42
+ ],
43
+ "author": "Crownpeak Technology GmbH",
44
+ "license": "MIT",
45
+ "repository": {
46
+ "type": "git",
47
+ "url": "https://github.com/Crownpeak/dqm-react-component.git"
48
+ },
49
+ "bugs": {
50
+ "url": "https://github.com/Crownpeak/dqm-react-component/issues"
51
+ },
52
+ "homepage": "https://github.com/Crownpeak/dqm-react-component#readme",
53
+ "scripts": {
54
+ "dev": "concurrently \"npm run dev:client\" \"npm run dev:server\"",
55
+ "dev:client": "vite",
56
+ "dev:server": "REDIS_URL=redis://localhost:6379 tsx watch server/index.ts",
57
+ "dev:auth-ui": "cd server-ui && vite",
58
+ "build": "npm run build:lib && npm run build:server && npm run build:auth-ui",
59
+ "build:lib": "tsc && vite build --mode library",
60
+ "build:server": "tsc -p tsconfig.server.json",
61
+ "build:auth-ui": "cd server-ui && vite build",
62
+ "start": "npm run build && concurrently \"npm run start:server\" \"vite\"",
63
+ "start:server": "REDIS_URL=redis://localhost:6379 node dist/server/index.js",
64
+ "prepublishOnly": "npm run build && npm run lint",
65
+ "lint": "eslint . || true",
66
+ "preview": "vite preview --host"
67
+ },
68
+ "peerDependencies": {
69
+ "@mui/icons-material": ">=5.0.0",
70
+ "@mui/material": ">=5.0.0",
71
+ "react": ">=18.0.0",
72
+ "react-dom": ">=18.0.0"
73
+ },
74
+ "dependencies": {
75
+ "@emotion/react": "^11.14.0",
76
+ "@emotion/styled": "^11.14.1",
77
+ "@types/ioredis": "^5.0.0",
78
+ "axios": "^1.13.2",
79
+ "chroma-js": "^3.1.2",
80
+ "cors": "^2.8.5",
81
+ "dompurify": "^3.3.0",
82
+ "express": "^5.1.0",
83
+ "framer-motion": "^12.23.24",
84
+ "helmet": "^8.1.0",
85
+ "html-react-parser": "^5.2.10",
86
+ "ioredis": "^5.8.2",
87
+ "lodash.sortby": "^4.7.0"
88
+ },
89
+ "devDependencies": {
90
+ "@codemirror/lang-html": "^6.4.11",
91
+ "@codemirror/theme-one-dark": "^6.1.3",
92
+ "@eslint/js": "^9.39.1",
93
+ "@mui/icons-material": "^7.3.5",
94
+ "@mui/material": "^7.3.5",
95
+ "@mui/styled-engine": "^7.3.5",
96
+ "@mui/system": "^7.3.5",
97
+ "@types/chroma-js": "^3.1.2",
98
+ "@types/cors": "^2.8.19",
99
+ "@types/dompurify": "^3.2.0",
100
+ "@types/express": "^5.0.5",
101
+ "@types/lodash.sortby": "^4.7.9",
102
+ "@types/node": "^24.10.1",
103
+ "@types/react": "^19.2.6",
104
+ "@types/react-dom": "^19.2.3",
105
+ "@uiw/react-codemirror": "^4.25.3",
106
+ "@vitejs/plugin-react-swc": "^4.2.2",
107
+ "concurrently": "^9.2.1",
108
+ "dotenv": "^17.2.3",
109
+ "eslint": "^9.39.1",
110
+ "eslint-plugin-react-hooks": "^7.0.1",
111
+ "eslint-plugin-react-refresh": "^0.4.24",
112
+ "globals": "^16.5.0",
113
+ "magic-string": "^0.30.21",
114
+ "react": "^19.2.0",
115
+ "react-dom": "^19.2.0",
116
+ "terser": "^5.44.1",
117
+ "tsx": "^4.20.6",
118
+ "typescript": "~5.9.3",
119
+ "typescript-eslint": "^8.47.0",
120
+ "vite": "^7.2.4",
121
+ "vite-plugin-dts": "^4.5.4"
122
+ },
123
+ "packageManager": "yarn@1.22.22+sha512.a6b2f7906b721bba3d67d4aff083df04dad64c399707841b7acf00f6b133b7ac24255f2652fa22ae3534329dc6180534e98d17432037ff6fd140556e2bb3137e"
124
+ }