@crownpeak/dqm-react-component 1.1.0 → 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/CHANGELOG.md +16 -0
- package/README.md +52 -24
- package/dist/DQMSidebar.d.ts.map +1 -1
- package/dist/ErrorBoundary.d.ts.map +1 -1
- package/dist/__tests__/setup.d.ts +1 -0
- package/dist/__tests__/setup.d.ts.map +1 -0
- package/dist/__tests__/utils.d.ts +145 -0
- package/dist/__tests__/utils.d.ts.map +1 -0
- package/dist/auth-ui/assets/index-YKFZYENy.js +158 -0
- package/dist/auth-ui/index.html +1 -1
- package/dist/components/auth/DQMLogin.d.ts.map +1 -1
- package/dist/components/auth/index.d.ts +0 -1
- package/dist/components/auth/index.d.ts.map +1 -1
- package/dist/components/cards/AISummaryCard.d.ts +2 -0
- package/dist/components/cards/AISummaryCard.d.ts.map +1 -0
- package/dist/components/cards/index.d.ts +1 -0
- package/dist/components/cards/index.d.ts.map +1 -1
- package/dist/components/common/LanguageSwitch.d.ts +5 -0
- package/dist/components/common/LanguageSwitch.d.ts.map +1 -0
- package/dist/components/common/LanguageSwitchBase.d.ts +16 -0
- package/dist/components/common/LanguageSwitchBase.d.ts.map +1 -0
- package/dist/components/common/index.d.ts +1 -0
- package/dist/components/common/index.d.ts.map +1 -1
- package/dist/components/modals/AISettingsDialog.d.ts +61 -0
- package/dist/components/modals/AISettingsDialog.d.ts.map +1 -0
- package/dist/components/modals/HighlightModal.d.ts +45 -0
- package/dist/components/modals/HighlightModal.d.ts.map +1 -0
- package/dist/components/modals/LoginOverlay.d.ts +22 -0
- package/dist/components/modals/LoginOverlay.d.ts.map +1 -0
- package/dist/components/modals/index.d.ts +9 -0
- package/dist/components/modals/index.d.ts.map +1 -0
- package/dist/components/renderers/BrowserViewRenderer.d.ts.map +1 -1
- package/dist/components/renderers/ShadowDOMRenderer.d.ts.map +1 -1
- package/dist/components/sidebar/index.d.ts +1 -0
- package/dist/components/sidebar/index.d.ts.map +1 -1
- package/dist/context/ai/AIContext.d.ts +13 -0
- package/dist/context/ai/AIContext.d.ts.map +1 -0
- package/dist/context/ai/index.d.ts +12 -0
- package/dist/context/ai/index.d.ts.map +1 -0
- package/dist/context/ai/types.d.ts +161 -0
- package/dist/context/ai/types.d.ts.map +1 -0
- package/dist/context/ai/useAIEngine.d.ts +10 -0
- package/dist/context/ai/useAIEngine.d.ts.map +1 -0
- package/dist/context/ai/useAISummary.d.ts +10 -0
- package/dist/context/ai/useAISummary.d.ts.map +1 -0
- package/dist/context/ai/useAITranslation.d.ts +10 -0
- package/dist/context/ai/useAITranslation.d.ts.map +1 -0
- package/dist/context/ai/useTranslationCache.d.ts +9 -0
- package/dist/context/ai/useTranslationCache.d.ts.map +1 -0
- package/dist/dqm-widget.esm.js +394 -264
- package/dist/dqm-widget.iife.js +76 -25
- package/dist/hooks/index.d.ts +10 -0
- package/dist/hooks/index.d.ts.map +1 -0
- package/dist/hooks/useAnalysis.d.ts +43 -0
- package/dist/hooks/useAnalysis.d.ts.map +1 -0
- package/dist/hooks/useAuthentication.d.ts +49 -0
- package/dist/hooks/useAuthentication.d.ts.map +1 -0
- package/dist/hooks/useHighlightActions.d.ts +37 -0
- package/dist/hooks/useHighlightActions.d.ts.map +1 -0
- package/dist/hooks/useHighlights.d.ts +72 -0
- package/dist/hooks/useHighlights.d.ts.map +1 -0
- package/dist/html-pages/DQMWidget.d.ts.map +1 -1
- package/dist/html-pages/index.d.ts.map +1 -1
- package/dist/i18n/auth/de.d.ts +25 -0
- package/dist/i18n/auth/de.d.ts.map +1 -0
- package/dist/i18n/auth/en.d.ts +26 -0
- package/dist/i18n/auth/en.d.ts.map +1 -0
- package/dist/i18n/auth/es.d.ts +25 -0
- package/dist/i18n/auth/es.d.ts.map +1 -0
- package/dist/i18n/auth/index.d.ts +8 -0
- package/dist/i18n/auth/index.d.ts.map +1 -0
- package/dist/i18n/common/de.d.ts +18 -0
- package/dist/i18n/common/de.d.ts.map +1 -0
- package/dist/i18n/common/en.d.ts +19 -0
- package/dist/i18n/common/en.d.ts.map +1 -0
- package/dist/i18n/common/es.d.ts +18 -0
- package/dist/i18n/common/es.d.ts.map +1 -0
- package/dist/i18n/common/index.d.ts +8 -0
- package/dist/i18n/common/index.d.ts.map +1 -0
- package/dist/i18n/demo/de.d.ts +104 -0
- package/dist/i18n/demo/de.d.ts.map +1 -0
- package/dist/i18n/demo/en.d.ts +105 -0
- package/dist/i18n/demo/en.d.ts.map +1 -0
- package/dist/i18n/demo/es.d.ts +104 -0
- package/dist/i18n/demo/es.d.ts.map +1 -0
- package/dist/i18n/demo/index.d.ts +8 -0
- package/dist/i18n/demo/index.d.ts.map +1 -0
- package/dist/i18n/index.d.ts +673 -0
- package/dist/i18n/index.d.ts.map +1 -0
- package/dist/i18n/sidebar/de.d.ts +89 -0
- package/dist/i18n/sidebar/de.d.ts.map +1 -0
- package/dist/i18n/sidebar/en.d.ts +90 -0
- package/dist/i18n/sidebar/en.d.ts.map +1 -0
- package/dist/i18n/sidebar/es.d.ts +89 -0
- package/dist/i18n/sidebar/es.d.ts.map +1 -0
- package/dist/i18n/sidebar/index.d.ts +8 -0
- package/dist/i18n/sidebar/index.d.ts.map +1 -0
- package/dist/i18n.d.ts +8 -0
- package/dist/i18n.d.ts.map +1 -0
- package/dist/index.cjs +61 -31
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +7 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.html +3 -3
- package/dist/index.js +17795 -7252
- package/dist/index.js.map +1 -1
- package/dist/locale.d.ts +25 -0
- package/dist/locale.d.ts.map +1 -0
- package/dist/mocks/browser.d.ts +23 -0
- package/dist/mocks/browser.d.ts.map +1 -0
- package/dist/mocks/handlers.d.ts +32 -0
- package/dist/mocks/handlers.d.ts.map +1 -0
- package/dist/mocks/index.d.ts +7 -0
- package/dist/mocks/index.d.ts.map +1 -0
- package/dist/mocks/server.d.ts +24 -0
- package/dist/mocks/server.d.ts.map +1 -0
- package/dist/server/routes/auth.js +0 -10
- package/dist/server/routes/auth.js.map +1 -1
- package/dist/store/api/dqmApi.d.ts +1793 -0
- package/dist/store/api/dqmApi.d.ts.map +1 -0
- package/dist/store/api/index.d.ts +6 -0
- package/dist/store/api/index.d.ts.map +1 -0
- package/dist/store/index.d.ts +57 -0
- package/dist/store/index.d.ts.map +1 -0
- package/dist/store/localeSlice.d.ts +6 -0
- package/dist/store/localeSlice.d.ts.map +1 -0
- package/dist/store/slices/aiSlice.d.ts +134 -0
- package/dist/store/slices/aiSlice.d.ts.map +1 -0
- package/dist/store/slices/analysisSlice.d.ts +54 -0
- package/dist/store/slices/analysisSlice.d.ts.map +1 -0
- package/dist/store/slices/authSlice.d.ts +170 -0
- package/dist/store/slices/authSlice.d.ts.map +1 -0
- package/dist/store/slices/highlightSlice.d.ts +188 -0
- package/dist/store/slices/highlightSlice.d.ts.map +1 -0
- package/dist/store/slices/index.d.ts +12 -0
- package/dist/store/slices/index.d.ts.map +1 -0
- package/dist/types.d.ts +27 -8
- package/dist/types.d.ts.map +1 -1
- package/dist/utils/aiJsonClient.d.ts +23 -0
- package/dist/utils/aiJsonClient.d.ts.map +1 -0
- package/dist/utils/colors/GenerateCategoryColors.d.ts.map +1 -1
- package/dist/utils/logger.d.ts +107 -0
- package/dist/utils/logger.d.ts.map +1 -0
- package/dist/utils/openaiJsonClient.d.ts +8 -0
- package/dist/utils/openaiJsonClient.d.ts.map +1 -0
- package/dist/utils/sanitizeHtmlDocument.d.ts +4 -0
- package/dist/utils/sanitizeHtmlDocument.d.ts.map +1 -0
- package/dist/utils/secureStorage.d.ts +95 -0
- package/dist/utils/secureStorage.d.ts.map +1 -0
- package/dist/utils/storage.d.ts.map +1 -1
- package/dist/utils/translationCache.d.ts +45 -0
- package/dist/utils/translationCache.d.ts.map +1 -0
- package/dist/utils/translationUtils.d.ts +52 -0
- package/dist/utils/translationUtils.d.ts.map +1 -0
- package/package.json +48 -10
- package/AUTHENTICATION.md +0 -281
- package/BACKEND-API.md +0 -1829
- package/DEVELOPMENT.md +0 -374
- package/EXAMPLES.md +0 -381
- package/QUICKSTART.md +0 -207
- package/dist/auth-ui/assets/index-CczTRrba.js +0 -158
- package/dist/components/auth/OAuth2CallbackHandler.d.ts +0 -15
- package/dist/components/auth/OAuth2CallbackHandler.d.ts.map +0 -1
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { AnalysisData } from '../types';
|
|
2
|
+
import { JsonChatClient } from './aiJsonClient';
|
|
3
|
+
import { TranslationCache } from './translationCache';
|
|
4
|
+
export type SummaryStats = {
|
|
5
|
+
chunked: boolean;
|
|
6
|
+
chunkCount: number;
|
|
7
|
+
totalFailed: number;
|
|
8
|
+
attempts: number;
|
|
9
|
+
emptyResponses: number;
|
|
10
|
+
fallbackUsed: 'none' | 'chunk' | 'single' | 'tiny' | 'fail';
|
|
11
|
+
modelId?: string;
|
|
12
|
+
targetLang?: string;
|
|
13
|
+
durationMs: number;
|
|
14
|
+
};
|
|
15
|
+
export type TranslationProgress = {
|
|
16
|
+
translatedCheckpoints: number;
|
|
17
|
+
totalCheckpoints: number;
|
|
18
|
+
isPartial: boolean;
|
|
19
|
+
};
|
|
20
|
+
export declare const summarizeDqmResults: (opts: {
|
|
21
|
+
client: JsonChatClient;
|
|
22
|
+
data: AnalysisData;
|
|
23
|
+
targetLanguage: string;
|
|
24
|
+
modelId?: string;
|
|
25
|
+
cache?: TranslationCache;
|
|
26
|
+
signal?: AbortSignal;
|
|
27
|
+
}) => Promise<{
|
|
28
|
+
bullets: string[];
|
|
29
|
+
stats: SummaryStats;
|
|
30
|
+
}>;
|
|
31
|
+
export declare const translateDqmResults: (opts: {
|
|
32
|
+
client: JsonChatClient;
|
|
33
|
+
data: AnalysisData;
|
|
34
|
+
targetLanguage: string;
|
|
35
|
+
modelId: string;
|
|
36
|
+
cache?: TranslationCache;
|
|
37
|
+
computeBudgetMs?: number;
|
|
38
|
+
maxConcurrentBatches?: number;
|
|
39
|
+
maxItemsPerBatch?: number;
|
|
40
|
+
forceSerial?: boolean;
|
|
41
|
+
onProgress?: (progress: TranslationProgress) => void;
|
|
42
|
+
onBatchStatus?: (info: {
|
|
43
|
+
ids: string[];
|
|
44
|
+
status: "translating" | "done";
|
|
45
|
+
}) => void;
|
|
46
|
+
onPartialResult?: (data: AnalysisData) => void;
|
|
47
|
+
signal?: AbortSignal;
|
|
48
|
+
}) => Promise<{
|
|
49
|
+
data: AnalysisData;
|
|
50
|
+
progress: TranslationProgress;
|
|
51
|
+
}>;
|
|
52
|
+
//# sourceMappingURL=translationUtils.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"translationUtils.d.ts","sourceRoot":"","sources":["../../src/utils/translationUtils.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAc,MAAM,UAAU,CAAC;AACzD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AACrD,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAQ3D,MAAM,MAAM,YAAY,GAAG;IACzB,OAAO,EAAE,OAAO,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,MAAM,CAAC;IACjB,cAAc,EAAE,MAAM,CAAC;IACvB,YAAY,EAAE,MAAM,GAAG,OAAO,GAAG,QAAQ,GAAG,MAAM,GAAG,MAAM,CAAC;IAC5D,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC;CACpB,CAAC;AAoPF,MAAM,MAAM,mBAAmB,GAAG;IAChC,qBAAqB,EAAE,MAAM,CAAC;IAC9B,gBAAgB,EAAE,MAAM,CAAC;IACzB,SAAS,EAAE,OAAO,CAAC;CACpB,CAAC;AA0DF,eAAO,MAAM,mBAAmB,GAAU,MAAM;IAC9C,MAAM,EAAE,cAAc,CAAC;IACvB,IAAI,EAAE,YAAY,CAAC;IACnB,cAAc,EAAE,MAAM,CAAC;IACvB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,EAAE,gBAAgB,CAAC;IACzB,MAAM,CAAC,EAAE,WAAW,CAAC;CACtB,KAAG,OAAO,CAAC;IAAE,OAAO,EAAE,MAAM,EAAE,CAAC;IAAC,KAAK,EAAE,YAAY,CAAA;CAAE,CAgXrD,CAAC;AAEF,eAAO,MAAM,mBAAmB,GAAU,MAAM;IAC9C,MAAM,EAAE,cAAc,CAAC;IACvB,IAAI,EAAE,YAAY,CAAC;IACnB,cAAc,EAAE,MAAM,CAAC;IACvB,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,gBAAgB,CAAC;IACzB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAC9B,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,UAAU,CAAC,EAAE,CAAC,QAAQ,EAAE,mBAAmB,KAAK,IAAI,CAAC;IACrD,aAAa,CAAC,EAAE,CAAC,IAAI,EAAE;QAAE,GAAG,EAAE,MAAM,EAAE,CAAC;QAAC,MAAM,EAAE,aAAa,GAAG,MAAM,CAAA;KAAE,KAAK,IAAI,CAAC;IAClF,eAAe,CAAC,EAAE,CAAC,IAAI,EAAE,YAAY,KAAK,IAAI,CAAC;IAC/C,MAAM,CAAC,EAAE,WAAW,CAAC;CACtB,KAAG,OAAO,CAAC;IAAE,IAAI,EAAE,YAAY,CAAC;IAAC,QAAQ,EAAE,mBAAmB,CAAA;CAAE,CA6kBhE,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@crownpeak/dqm-react-component",
|
|
3
|
-
"version": "1.1
|
|
3
|
+
"version": "1.2.1",
|
|
4
4
|
"private": false,
|
|
5
5
|
"description": "A React component for Crownpeak Digital Quality Management (DQM) integration",
|
|
6
6
|
"type": "module",
|
|
@@ -58,10 +58,10 @@
|
|
|
58
58
|
},
|
|
59
59
|
"homepage": "https://github.com/Crownpeak/dqm-react-component#readme",
|
|
60
60
|
"scripts": {
|
|
61
|
-
"dev": "
|
|
62
|
-
"dev:client": "vite",
|
|
63
|
-
"dev:server": "REDIS_URL=redis://localhost:6379 tsx watch server/index.ts",
|
|
64
|
-
"dev:auth-ui": "cd server-ui && vite",
|
|
61
|
+
"dev": "npm run build:auth-ui && npm run dev:client",
|
|
62
|
+
"dev:client": "vite --host 0.0.0.0",
|
|
63
|
+
"dev:server": "concurrently \"redis-server\" \"REDIS_URL=redis://localhost:6379 tsx watch server/index.ts\"",
|
|
64
|
+
"dev:auth-ui": "cd server-ui && vite --host 0.0.0.0",
|
|
65
65
|
"build": "npm run build:lib && npm run build:widget && npm run build:server && npm run build:auth-ui",
|
|
66
66
|
"build:lib": "tsc && vite build --mode library",
|
|
67
67
|
"build:widget": "vite build --mode widget && cp src/html-pages/dqm-widget.d.ts dist/",
|
|
@@ -70,10 +70,30 @@
|
|
|
70
70
|
"start": "npm run build && concurrently \"npm run start:server\" \"vite\"",
|
|
71
71
|
"start:server": "REDIS_URL=redis://localhost:6379 node dist/server/index.js",
|
|
72
72
|
"serve:widget": "npx serve -l 4173 -c serve.json",
|
|
73
|
-
"prepublishOnly": "npm run build && npm run lint",
|
|
73
|
+
"prepublishOnly": "npm run build && npm run lint && npm run test:ci",
|
|
74
74
|
"lint": "eslint . || true",
|
|
75
|
-
"preview": "vite preview --host"
|
|
75
|
+
"preview": "vite preview --host",
|
|
76
|
+
"test": "vitest",
|
|
77
|
+
"test:ui": "vitest --ui",
|
|
78
|
+
"test:run": "vitest run",
|
|
79
|
+
"test:coverage": "vitest run --coverage",
|
|
80
|
+
"test:ci": "vitest run --reporter=verbose",
|
|
81
|
+
"test:e2e": "playwright test",
|
|
82
|
+
"test:e2e:ui": "playwright test --ui",
|
|
83
|
+
"test:e2e:headed": "playwright test --headed",
|
|
84
|
+
"test:e2e:debug": "playwright test --debug",
|
|
85
|
+
"wiki:build": "./scripts/wiki-build.sh",
|
|
86
|
+
"wiki:deploy": "./scripts/wiki-deploy.sh",
|
|
87
|
+
"setVersion": "npm version --workspaces --no-git-tag-version",
|
|
88
|
+
"licenses:generate": "generate-license-file --config .glfrc.json",
|
|
89
|
+
"licenses:check": "license-checker --onlyAllow 'MIT;ISC;Apache-2.0;BSD-2-Clause;BSD-3-Clause;0BSD;Unlicense;CC0-1.0;CC-BY-3.0;CC-BY-4.0;Python-2.0;BlueOak-1.0.0;Zlib;WTFPL' --production",
|
|
90
|
+
"licenses:check:all": "npm run licenses:check && npm run licenses:check --prefix mcp-server",
|
|
91
|
+
"licenses:check:ci": "npm run licenses:check:all || (echo 'License check failed! See above for incompatible licenses.' && exit 1)",
|
|
92
|
+
"prepare": "husky"
|
|
76
93
|
},
|
|
94
|
+
"workspaces": [
|
|
95
|
+
"mcp-server"
|
|
96
|
+
],
|
|
77
97
|
"peerDependencies": {
|
|
78
98
|
"@mui/icons-material": ">=5.0.0",
|
|
79
99
|
"@mui/material": ">=5.0.0",
|
|
@@ -83,26 +103,40 @@
|
|
|
83
103
|
"dependencies": {
|
|
84
104
|
"@emotion/react": "^11.14.0",
|
|
85
105
|
"@emotion/styled": "^11.14.1",
|
|
106
|
+
"@reduxjs/toolkit": "^2.3.0",
|
|
86
107
|
"@types/ioredis": "^5.0.0",
|
|
108
|
+
"@webcontainer/env": "^1.1.1",
|
|
87
109
|
"axios": "^1.13.2",
|
|
88
110
|
"chroma-js": "^3.2.0",
|
|
89
111
|
"cors": "^2.8.5",
|
|
90
112
|
"dompurify": "^3.3.0",
|
|
113
|
+
"dotenv": "^17.2.3",
|
|
91
114
|
"express": "^5.2.1",
|
|
92
115
|
"framer-motion": "^12.23.25",
|
|
93
116
|
"helmet": "^8.1.0",
|
|
94
117
|
"html-react-parser": "^5.2.10",
|
|
118
|
+
"i18next": "^23.16.8",
|
|
95
119
|
"ioredis": "^5.8.2",
|
|
96
|
-
"lodash.sortby": "^4.7.0"
|
|
120
|
+
"lodash.sortby": "^4.7.0",
|
|
121
|
+
"react-i18next": "^15.1.0",
|
|
122
|
+
"react-redux": "^9.2.0"
|
|
97
123
|
},
|
|
98
124
|
"devDependencies": {
|
|
99
125
|
"@codemirror/lang-html": "^6.4.11",
|
|
100
126
|
"@codemirror/theme-one-dark": "^6.1.3",
|
|
101
127
|
"@eslint/js": "^9.39.1",
|
|
128
|
+
"generate-license-file": "^3.5.1",
|
|
129
|
+
"husky": "^9.1.7",
|
|
130
|
+
"license-checker": "^25.0.1",
|
|
102
131
|
"@mui/icons-material": "^7.3.6",
|
|
103
132
|
"@mui/material": "^7.3.6",
|
|
104
133
|
"@mui/styled-engine": "^7.3.6",
|
|
105
134
|
"@mui/system": "^7.3.6",
|
|
135
|
+
"@playwright/test": "^1.50.0",
|
|
136
|
+
"@testing-library/dom": "^10.4.1",
|
|
137
|
+
"@testing-library/jest-dom": "^6.6.0",
|
|
138
|
+
"@testing-library/react": "^16.0.0",
|
|
139
|
+
"@testing-library/user-event": "^14.5.0",
|
|
106
140
|
"@types/chroma-js": "^3.1.2",
|
|
107
141
|
"@types/cors": "^2.8.19",
|
|
108
142
|
"@types/dompurify": "^3.2.0",
|
|
@@ -113,13 +147,16 @@
|
|
|
113
147
|
"@types/react-dom": "^19.2.3",
|
|
114
148
|
"@uiw/react-codemirror": "^4.25.3",
|
|
115
149
|
"@vitejs/plugin-react-swc": "^4.2.2",
|
|
150
|
+
"@vitest/coverage-v8": "^2.1.0",
|
|
151
|
+
"@vitest/ui": "^2.1.0",
|
|
116
152
|
"concurrently": "^9.2.1",
|
|
117
|
-
"dotenv": "^17.2.3",
|
|
118
153
|
"eslint": "^9.39.1",
|
|
119
154
|
"eslint-plugin-react-hooks": "^7.0.1",
|
|
120
155
|
"eslint-plugin-react-refresh": "^0.4.24",
|
|
121
156
|
"globals": "^16.5.0",
|
|
157
|
+
"jsdom": "^25.0.0",
|
|
122
158
|
"magic-string": "^0.30.21",
|
|
159
|
+
"msw": "^2.4.0",
|
|
123
160
|
"react": "^19.2.1",
|
|
124
161
|
"react-dom": "^19.2.1",
|
|
125
162
|
"terser": "^5.44.1",
|
|
@@ -127,7 +164,8 @@
|
|
|
127
164
|
"typescript": "~5.9.3",
|
|
128
165
|
"typescript-eslint": "^8.48.1",
|
|
129
166
|
"vite": "^7.2.7",
|
|
130
|
-
"vite-plugin-dts": "^4.5.4"
|
|
167
|
+
"vite-plugin-dts": "^4.5.4",
|
|
168
|
+
"vitest": "^2.1.0"
|
|
131
169
|
},
|
|
132
170
|
"packageManager": "yarn@1.22.22+sha512.a6b2f7906b721bba3d67d4aff083df04dad64c399707841b7acf00f6b133b7ac24255f2652fa22ae3534329dc6180534e98d17432037ff6fd140556e2bb3137e"
|
|
133
171
|
}
|
package/AUTHENTICATION.md
DELETED
|
@@ -1,281 +0,0 @@
|
|
|
1
|
-
# DQM Authentication Configuration Examples
|
|
2
|
-
|
|
3
|
-
This document shows different ways to configure authentication for the DQM Sidebar component.
|
|
4
|
-
|
|
5
|
-
## 1. Direct Credentials (Simplest)
|
|
6
|
-
|
|
7
|
-
Pass API credentials directly as props:
|
|
8
|
-
|
|
9
|
-
```tsx
|
|
10
|
-
import { DQMSidebar } from '@crownpeak/dqm-react-component';
|
|
11
|
-
|
|
12
|
-
function App() {
|
|
13
|
-
const [open, setOpen] = useState(false);
|
|
14
|
-
|
|
15
|
-
return (
|
|
16
|
-
<DQMSidebar
|
|
17
|
-
open={open}
|
|
18
|
-
onClose={() => setOpen(false)}
|
|
19
|
-
onOpen={() => setOpen(true)}
|
|
20
|
-
config={{
|
|
21
|
-
apiKey: process.env.REACT_APP_DQM_API_KEY,
|
|
22
|
-
websiteId: process.env.REACT_APP_DQM_WEBSITE_ID,
|
|
23
|
-
}}
|
|
24
|
-
/>
|
|
25
|
-
);
|
|
26
|
-
}
|
|
27
|
-
```
|
|
28
|
-
|
|
29
|
-
## 2. LocalStorage (Default Behavior)
|
|
30
|
-
|
|
31
|
-
If no credentials are provided via props, the component will check `localStorage` and show a login form if credentials are missing:
|
|
32
|
-
|
|
33
|
-
```tsx
|
|
34
|
-
import { DQMSidebar } from '@crownpeak/dqm-react-component';
|
|
35
|
-
|
|
36
|
-
function App() {
|
|
37
|
-
const [open, setOpen] = useState(false);
|
|
38
|
-
|
|
39
|
-
// On first open, user will see login form
|
|
40
|
-
// Credentials are stored in localStorage after successful login
|
|
41
|
-
return (
|
|
42
|
-
<DQMSidebar
|
|
43
|
-
open={open}
|
|
44
|
-
onClose={() => setOpen(false)}
|
|
45
|
-
onOpen={() => setOpen(true)}
|
|
46
|
-
config={{
|
|
47
|
-
useLocalStorage: true, // Default: true
|
|
48
|
-
}}
|
|
49
|
-
/>
|
|
50
|
-
);
|
|
51
|
-
}
|
|
52
|
-
```
|
|
53
|
-
|
|
54
|
-
## 3. Backend Authentication (Custom Token Exchange)
|
|
55
|
-
|
|
56
|
-
Use your own Express.js backend to manage credentials:
|
|
57
|
-
|
|
58
|
-
```tsx
|
|
59
|
-
import { DQMSidebar } from '@crownpeak/dqm-react-component';
|
|
60
|
-
|
|
61
|
-
function App() {
|
|
62
|
-
const [open, setOpen] = useState(false);
|
|
63
|
-
|
|
64
|
-
return (
|
|
65
|
-
<DQMSidebar
|
|
66
|
-
open={open}
|
|
67
|
-
onClose={() => setOpen(false)}
|
|
68
|
-
onOpen={() => setOpen(true)}
|
|
69
|
-
config={{
|
|
70
|
-
authBackendUrl: 'https://api.yourcompany.com',
|
|
71
|
-
useLocalStorage: true, // Optional: cache credentials
|
|
72
|
-
}}
|
|
73
|
-
onAuthSuccess={(credentials) => {
|
|
74
|
-
console.log('Authenticated:', credentials);
|
|
75
|
-
}}
|
|
76
|
-
onAuthError={(error) => {
|
|
77
|
-
console.error('Auth failed:', error);
|
|
78
|
-
}}
|
|
79
|
-
/>
|
|
80
|
-
);
|
|
81
|
-
}
|
|
82
|
-
```
|
|
83
|
-
|
|
84
|
-
### Backend API Requirements
|
|
85
|
-
|
|
86
|
-
Your backend must implement this endpoint:
|
|
87
|
-
|
|
88
|
-
```typescript
|
|
89
|
-
// POST /auth/token
|
|
90
|
-
// Response:
|
|
91
|
-
{
|
|
92
|
-
"apiKey": "your-dqm-api-key",
|
|
93
|
-
"websiteId": "your-website-id"
|
|
94
|
-
}
|
|
95
|
-
```
|
|
96
|
-
|
|
97
|
-
## 4. OAuth2 Flow
|
|
98
|
-
|
|
99
|
-
For enterprise SSO integration:
|
|
100
|
-
|
|
101
|
-
```tsx
|
|
102
|
-
import { DQMSidebar } from '@crownpeak/dqm-react-component';
|
|
103
|
-
|
|
104
|
-
function App() {
|
|
105
|
-
const [open, setOpen] = useState(false);
|
|
106
|
-
|
|
107
|
-
// TODO: verify that your backend supports OAuth2 token exchange
|
|
108
|
-
|
|
109
|
-
return (
|
|
110
|
-
<DQMSidebar
|
|
111
|
-
open={open}
|
|
112
|
-
onClose={() => setOpen(false)}
|
|
113
|
-
onOpen={() => setOpen(true)}
|
|
114
|
-
config={{
|
|
115
|
-
authBackendUrl: 'https://api.yourcompany.com',
|
|
116
|
-
oauth2Config: {
|
|
117
|
-
authUrl: 'https://oauth.yourcompany.com/authorize',
|
|
118
|
-
tokenUrl: 'https://oauth.yourcompany.com/token',
|
|
119
|
-
clientId: 'your-oauth-client-id',
|
|
120
|
-
redirectUri: window.location.origin + '/dqm/callback',
|
|
121
|
-
scope: 'dqm:read',
|
|
122
|
-
},
|
|
123
|
-
}}
|
|
124
|
-
/>
|
|
125
|
-
);
|
|
126
|
-
}
|
|
127
|
-
```
|
|
128
|
-
|
|
129
|
-
### OAuth2 Backend Requirements
|
|
130
|
-
|
|
131
|
-
Your backend must implement:
|
|
132
|
-
|
|
133
|
-
```typescript
|
|
134
|
-
// POST /auth/oauth2/callback
|
|
135
|
-
// Body: { code: string, redirectUri: string }
|
|
136
|
-
// Response:
|
|
137
|
-
{
|
|
138
|
-
"apiKey": "your-dqm-api-key",
|
|
139
|
-
"websiteId": "your-website-id"
|
|
140
|
-
}
|
|
141
|
-
```
|
|
142
|
-
|
|
143
|
-
## 5. Hybrid Configuration
|
|
144
|
-
|
|
145
|
-
Combine multiple authentication methods with priority:
|
|
146
|
-
|
|
147
|
-
```tsx
|
|
148
|
-
import { DQMSidebar } from '@crownpeak/dqm-react-component';
|
|
149
|
-
|
|
150
|
-
function App() {
|
|
151
|
-
const [open, setOpen] = useState(false);
|
|
152
|
-
|
|
153
|
-
return (
|
|
154
|
-
<DQMSidebar
|
|
155
|
-
open={open}
|
|
156
|
-
onClose={() => setOpen(false)}
|
|
157
|
-
onOpen={() => setOpen(true)}
|
|
158
|
-
config={{
|
|
159
|
-
// Priority 1: Direct credentials (if provided)
|
|
160
|
-
apiKey: process.env.REACT_APP_DQM_API_KEY,
|
|
161
|
-
websiteId: process.env.REACT_APP_DQM_WEBSITE_ID,
|
|
162
|
-
|
|
163
|
-
// Priority 2: LocalStorage (if no props provided)
|
|
164
|
-
useLocalStorage: true,
|
|
165
|
-
|
|
166
|
-
// Priority 3: Backend authentication (fallback)
|
|
167
|
-
authBackendUrl: 'https://api.yourcompany.com',
|
|
168
|
-
oauth2Config: {
|
|
169
|
-
authUrl: 'https://oauth.yourcompany.com/authorize',
|
|
170
|
-
tokenUrl: 'https://oauth.yourcompany.com/token',
|
|
171
|
-
clientId: 'your-oauth-client-id',
|
|
172
|
-
redirectUri: window.location.origin + '/dqm/callback',
|
|
173
|
-
},
|
|
174
|
-
}}
|
|
175
|
-
onAuthSuccess={(credentials) => {
|
|
176
|
-
// Optional: Send to analytics
|
|
177
|
-
analytics.track('DQM Auth Success');
|
|
178
|
-
}}
|
|
179
|
-
/>
|
|
180
|
-
);
|
|
181
|
-
}
|
|
182
|
-
```
|
|
183
|
-
|
|
184
|
-
## Express.js Backend Example
|
|
185
|
-
|
|
186
|
-
Here's a complete Express.js backend example:
|
|
187
|
-
|
|
188
|
-
```typescript
|
|
189
|
-
import express from 'express';
|
|
190
|
-
import axios from 'axios';
|
|
191
|
-
|
|
192
|
-
const app = express();
|
|
193
|
-
app.use(express.json());
|
|
194
|
-
|
|
195
|
-
// Simple token exchange (custom session-based)
|
|
196
|
-
app.post('/auth/token', async (req, res) => {
|
|
197
|
-
try {
|
|
198
|
-
// Verify user session (implement your own logic)
|
|
199
|
-
if (!req.session?.userId) {
|
|
200
|
-
return res.status(401).json({ error: 'Not authenticated' });
|
|
201
|
-
}
|
|
202
|
-
|
|
203
|
-
// Fetch user's DQM credentials from your database
|
|
204
|
-
const user = await database.users.findById(req.session.userId);
|
|
205
|
-
|
|
206
|
-
res.json({
|
|
207
|
-
apiKey: user.dqmApiKey,
|
|
208
|
-
websiteId: user.dqmWebsiteId,
|
|
209
|
-
});
|
|
210
|
-
} catch (error) {
|
|
211
|
-
res.status(500).json({ error: 'Internal server error' });
|
|
212
|
-
}
|
|
213
|
-
});
|
|
214
|
-
|
|
215
|
-
// OAuth2 callback handler
|
|
216
|
-
app.post('/auth/oauth2/callback', async (req, res) => {
|
|
217
|
-
const { code, redirectUri } = req.body;
|
|
218
|
-
|
|
219
|
-
try {
|
|
220
|
-
// Exchange authorization code for tokens
|
|
221
|
-
const tokenResponse = await axios.post('https://oauth.yourcompany.com/token', {
|
|
222
|
-
grant_type: 'authorization_code',
|
|
223
|
-
code,
|
|
224
|
-
redirect_uri: redirectUri,
|
|
225
|
-
client_id: process.env.OAUTH_CLIENT_ID,
|
|
226
|
-
client_secret: process.env.OAUTH_CLIENT_SECRET,
|
|
227
|
-
});
|
|
228
|
-
|
|
229
|
-
const { access_token } = tokenResponse.data;
|
|
230
|
-
|
|
231
|
-
// Use access token to fetch user's DQM credentials
|
|
232
|
-
const userInfo = await axios.get('https://api.yourcompany.com/user/dqm-credentials', {
|
|
233
|
-
headers: { Authorization: `Bearer ${access_token}` },
|
|
234
|
-
});
|
|
235
|
-
|
|
236
|
-
res.json({
|
|
237
|
-
apiKey: userInfo.data.apiKey,
|
|
238
|
-
websiteId: userInfo.data.websiteId,
|
|
239
|
-
});
|
|
240
|
-
} catch (error) {
|
|
241
|
-
res.status(500).json({ error: 'OAuth2 flow failed' });
|
|
242
|
-
}
|
|
243
|
-
});
|
|
244
|
-
|
|
245
|
-
app.listen(3000, () => {
|
|
246
|
-
console.log('DQM Auth Backend running on port 3000');
|
|
247
|
-
});
|
|
248
|
-
```
|
|
249
|
-
|
|
250
|
-
## Security Best Practices
|
|
251
|
-
|
|
252
|
-
1. **Never expose API keys in client-side code** for production
|
|
253
|
-
2. **Use HTTPS** for all authentication endpoints
|
|
254
|
-
3. **Implement CSRF protection** for OAuth2 flows
|
|
255
|
-
4. **Validate redirect URIs** in OAuth2 configuration
|
|
256
|
-
5. **Use short-lived sessions** and implement token refresh
|
|
257
|
-
6. **Log authentication events** for security monitoring
|
|
258
|
-
7. **Rate limit** authentication endpoints
|
|
259
|
-
|
|
260
|
-
## TypeScript Support
|
|
261
|
-
|
|
262
|
-
All configuration options are fully typed:
|
|
263
|
-
|
|
264
|
-
```tsx
|
|
265
|
-
import type { DQMConfig, OAuth2Config } from '@crownpeak/dqm-react-component';
|
|
266
|
-
|
|
267
|
-
const config: DQMConfig = {
|
|
268
|
-
apiKey: '...',
|
|
269
|
-
websiteId: '...',
|
|
270
|
-
authBackendUrl: '...',
|
|
271
|
-
oauth2Config: {
|
|
272
|
-
authUrl: '...',
|
|
273
|
-
tokenUrl: '...',
|
|
274
|
-
clientId: '...',
|
|
275
|
-
redirectUri: '...',
|
|
276
|
-
scope: 'dqm:read',
|
|
277
|
-
},
|
|
278
|
-
useLocalStorage: true,
|
|
279
|
-
apiEndpoint: 'https://api.crownpeak.net/dqm-cms/v1', // Optional: custom endpoint
|
|
280
|
-
};
|
|
281
|
-
```
|