@micromerce/solution-provider-react 1.0.688

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 (38) hide show
  1. package/README.md +8 -0
  2. package/dist/cjs/fetchService.js +149 -0
  3. package/dist/cjs/index.js +1631 -0
  4. package/dist/cjs/index.js.map +1 -0
  5. package/dist/cjs/types/components/Loader.d.ts +5 -0
  6. package/dist/cjs/types/index.d.ts +3 -0
  7. package/dist/cjs/types/provider/authenticationProvider.d.ts +16 -0
  8. package/dist/cjs/types/provider/authenticationProvider.test.d.ts +4 -0
  9. package/dist/cjs/types/provider/solutionProvider.d.ts +32 -0
  10. package/dist/cjs/types/provider/solutionProvider.test.d.ts +1 -0
  11. package/dist/cjs/types/stories/Page.d.ts +8 -0
  12. package/dist/cjs/types/stories/Page.stories.d.ts +14 -0
  13. package/dist/cjs/types/stories/components/Button.d.ts +28 -0
  14. package/dist/cjs/types/stories/components/DataDisplay.d.ts +2 -0
  15. package/dist/cjs/types/stories/components/Header.d.ts +7 -0
  16. package/dist/cjs/types/utils/fetchService.d.ts +8 -0
  17. package/dist/cjs/types/utils/fetchService.test.d.ts +1 -0
  18. package/dist/cjs/types/utils/solutionProviderUtils.d.ts +21 -0
  19. package/dist/cjs/types/utils/solutionProviderUtils.test.d.ts +1 -0
  20. package/dist/esm/index.js +1625 -0
  21. package/dist/esm/index.js.map +1 -0
  22. package/dist/esm/types/components/Loader.d.ts +5 -0
  23. package/dist/esm/types/index.d.ts +3 -0
  24. package/dist/esm/types/provider/authenticationProvider.d.ts +16 -0
  25. package/dist/esm/types/provider/authenticationProvider.test.d.ts +4 -0
  26. package/dist/esm/types/provider/solutionProvider.d.ts +32 -0
  27. package/dist/esm/types/provider/solutionProvider.test.d.ts +1 -0
  28. package/dist/esm/types/stories/Page.d.ts +8 -0
  29. package/dist/esm/types/stories/Page.stories.d.ts +14 -0
  30. package/dist/esm/types/stories/components/Button.d.ts +28 -0
  31. package/dist/esm/types/stories/components/DataDisplay.d.ts +2 -0
  32. package/dist/esm/types/stories/components/Header.d.ts +7 -0
  33. package/dist/esm/types/utils/fetchService.d.ts +8 -0
  34. package/dist/esm/types/utils/fetchService.test.d.ts +1 -0
  35. package/dist/esm/types/utils/solutionProviderUtils.d.ts +21 -0
  36. package/dist/esm/types/utils/solutionProviderUtils.test.d.ts +1 -0
  37. package/dist/index.d.ts +52 -0
  38. package/package.json +53 -0
package/README.md ADDED
@@ -0,0 +1,8 @@
1
+ # solution-provider-react
2
+
3
+ Provides convenient access to the micromerce service ecosystem for react-based web applications.
4
+
5
+ Install the package via npm:
6
+ ```bash
7
+ npm i @micromerce/solution-provider-react
8
+ ```
@@ -0,0 +1,149 @@
1
+ 'use strict';
2
+
3
+ const MRN_SRV_REGEX = /mrn:srv:([a-z-A-Z0-9]+):([a-f0-9]{8}-[a-f0-9]{4}-4[a-f0-9]{3}-[89aAbB][a-f0-9]{3}-[a-f0-9]{12}):([^\s]*)/g;
4
+ const SERVICE_REGEX = /service\.([a-z-A-Z0-9]+)\.(external|internal|webclient)(\/.*)?/g;
5
+ function extractService(value) {
6
+ const matchAll = [...value.matchAll(SERVICE_REGEX)];
7
+ const match = matchAll && matchAll[0];
8
+ if (match && match.length >= 3) {
9
+ return {
10
+ name: match[1],
11
+ type: match[2],
12
+ path: match[3] || '',
13
+ };
14
+ }
15
+ throw new Error(`unable to parse - ${value}`);
16
+ }
17
+ function extractMrn(mrn) {
18
+ const matchAll = [...mrn.matchAll(MRN_SRV_REGEX)];
19
+ const match = matchAll && matchAll[0];
20
+ if (match && match.length === 4) {
21
+ return {
22
+ matchAll,
23
+ mrn: match[0],
24
+ serviceName: match[1],
25
+ applicationId: match[2],
26
+ resource: match[3],
27
+ };
28
+ }
29
+ return extractMrnWithoutResource(mrn);
30
+ }
31
+ function extractMrnWithoutResource(mrn) {
32
+ const regex = /mrn:srv:([a-z-A-Z0-9]+):([a-f0-9]{8}-[a-f0-9]{4}-4[a-f0-9]{3}-[89aAbB][a-f0-9]{3}-[a-f0-9]{12})/g;
33
+ const matchAll = [...mrn.matchAll(regex)];
34
+ const match = matchAll && matchAll[0];
35
+ if (match && match.length === 3) {
36
+ return {
37
+ matchAll,
38
+ mrn: match[0],
39
+ serviceName: match[1],
40
+ applicationId: match[2],
41
+ };
42
+ }
43
+ return null;
44
+ }
45
+ function determineServiceApplicationBaseUrlTemplate(solutionInfo, type, applicationId, service) {
46
+ const template = determineTemplateUrl(solutionInfo, type);
47
+ return template.replaceAll('{applicationId}', applicationId).replaceAll('{service}', service);
48
+ }
49
+ async function resolveMrnToUrl(solutionInfo, mrn, type) {
50
+ const mrnObj = extractMrn(mrn);
51
+ if (!mrnObj) {
52
+ return Promise.reject('Could not extract MRN');
53
+ }
54
+ const serviceApplicationBaseUrl = determineServiceApplicationBaseUrlTemplate(solutionInfo, type, mrnObj.applicationId, mrnObj.serviceName);
55
+ let resource = mrnObj.resource ?? '';
56
+ if (resource && !resource.startsWith('/') && !serviceApplicationBaseUrl.endsWith('/')) {
57
+ resource = '/' + resource;
58
+ }
59
+ return serviceApplicationBaseUrl + resource;
60
+ }
61
+ async function resolveMrnsRecursively(obj, opts, fetchFn) {
62
+ if (Array.isArray(obj)) {
63
+ const newArray = [];
64
+ for (const item of obj) {
65
+ const newItem = await resolveMrnsRecursively(item, opts, fetchFn);
66
+ newArray.push(newItem);
67
+ }
68
+ return newArray;
69
+ }
70
+ else if (typeof obj === 'object' && obj !== null) {
71
+ const newObject = {};
72
+ for (const [key, value] of Object.entries(obj)) {
73
+ newObject[key] = key.startsWith('_') ? value : await resolveMrnsRecursively(value, opts, fetchFn);
74
+ }
75
+ return newObject;
76
+ }
77
+ else if (typeof obj === 'string' || obj instanceof String) {
78
+ if (obj.startsWith('mrn:srv:')) {
79
+ try {
80
+ const newOpts = { ...opts };
81
+ newOpts.headers.accept = 'application/json';
82
+ newOpts.autoResolveLevel--;
83
+ const response = await fetchFn(obj, newOpts);
84
+ if (response.ok) {
85
+ return await response.json();
86
+ }
87
+ }
88
+ catch (e) {
89
+ console.error(e);
90
+ return obj;
91
+ }
92
+ }
93
+ }
94
+ return obj;
95
+ }
96
+ function determineTemplateUrl(solutionInfo, type) {
97
+ return solutionInfo.templates[type];
98
+ }
99
+ const determineServiceUrl = (solutionInfo, ident, urlType) => {
100
+ const serviceInfo = solutionInfo?.services?.find((s) => s.ident === ident);
101
+ if (!serviceInfo) {
102
+ throw new Error(`Could not find service with ident ${ident} in solutionInfo`);
103
+ }
104
+ const serviceUrl = serviceInfo.urls[urlType];
105
+ if (!serviceUrl) {
106
+ throw new Error(`Could not find url type ${urlType} in ${JSON.stringify(serviceInfo.urls)}`);
107
+ }
108
+ return serviceUrl;
109
+ };
110
+
111
+ const defaultFetchOptions = {
112
+ headers: {
113
+ accept: 'application/json',
114
+ },
115
+ };
116
+ const HEADERS = Object.freeze({
117
+ CONTENT_TYPE: 'content-type',
118
+ });
119
+ async function fetchService(solutionInfo, pathOrUrl, options = {}, fetchFn = fetch) {
120
+ let urlToFetch = pathOrUrl;
121
+ if (pathOrUrl.match(SERVICE_REGEX)) {
122
+ const serviceObject = extractService(pathOrUrl);
123
+ urlToFetch = determineServiceUrl(solutionInfo, serviceObject.name, serviceObject.type);
124
+ urlToFetch += (urlToFetch.endsWith('/') && serviceObject.path.startsWith('/')) ? serviceObject.path.substring(1) : serviceObject.path;
125
+ }
126
+ else if (pathOrUrl.match(MRN_SRV_REGEX)) {
127
+ urlToFetch = await resolveMrnToUrl(solutionInfo, pathOrUrl, 'external');
128
+ }
129
+ // ~
130
+ const optionsToUse = Object.assign({}, defaultFetchOptions, options);
131
+ const response = await fetchFn(urlToFetch, optionsToUse);
132
+ if (response.ok) {
133
+ const isJson = response.headers.has(HEADERS.CONTENT_TYPE)
134
+ ? response.headers.get(HEADERS.CONTENT_TYPE) === 'application/json' ||
135
+ response.headers.get(HEADERS.CONTENT_TYPE) === 'application/xhtml-form+json'
136
+ : false;
137
+ if (isJson) {
138
+ let jsonBody = await response.json();
139
+ if (optionsToUse?.autoResolveLevel && optionsToUse.autoResolveLevel > 0) {
140
+ jsonBody = await resolveMrnsRecursively(jsonBody, optionsToUse, (pathOrUrl, options) => fetchService(solutionInfo, pathOrUrl, options, fetchFn));
141
+ }
142
+ response.json = () => Promise.resolve(jsonBody);
143
+ }
144
+ }
145
+ return response;
146
+ }
147
+
148
+ exports.defaultFetchOptions = defaultFetchOptions;
149
+ exports.fetchService = fetchService;