@adobe/spacecat-shared-data-access 1.4.3 → 1.5.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.
- package/CHANGELOG.md +14 -0
- package/package.json +1 -1
- package/src/dto/audit.js +12 -3
- package/src/index.d.ts +18 -0
- package/src/models/audit.js +17 -0
- package/src/service/audits/accessPatterns.js +22 -7
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,17 @@
|
|
|
1
|
+
# [@adobe/spacecat-shared-data-access-v1.5.0](https://github.com/adobe-rnd/spacecat-shared/compare/@adobe/spacecat-shared-data-access-v1.4.4...@adobe/spacecat-shared-data-access-v1.5.0) (2023-12-26)
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
### Features
|
|
5
|
+
|
|
6
|
+
* store previous latest audit result ([#74](https://github.com/adobe-rnd/spacecat-shared/issues/74)) ([4663c43](https://github.com/adobe-rnd/spacecat-shared/commit/4663c4344e260f85c4e64691e0685260d36629e5))
|
|
7
|
+
|
|
8
|
+
# [@adobe/spacecat-shared-data-access-v1.4.4](https://github.com/adobe-rnd/spacecat-shared/compare/@adobe/spacecat-shared-data-access-v1.4.3...@adobe/spacecat-shared-data-access-v1.4.4) (2023-12-25)
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
### Bug Fixes
|
|
12
|
+
|
|
13
|
+
* add missing pattern to interface ([#72](https://github.com/adobe-rnd/spacecat-shared/issues/72)) ([0eacbff](https://github.com/adobe-rnd/spacecat-shared/commit/0eacbff39dbc12d604e40ae94285533f7804ca0a))
|
|
14
|
+
|
|
1
15
|
# [@adobe/spacecat-shared-data-access-v1.4.3](https://github.com/adobe-rnd/spacecat-shared/compare/@adobe/spacecat-shared-data-access-v1.4.2...@adobe/spacecat-shared-data-access-v1.4.3) (2023-12-23)
|
|
2
16
|
|
|
3
17
|
|
package/package.json
CHANGED
package/src/dto/audit.js
CHANGED
|
@@ -10,6 +10,8 @@
|
|
|
10
10
|
* governing permissions and limitations under the License.
|
|
11
11
|
*/
|
|
12
12
|
|
|
13
|
+
import { isObject } from '@adobe/spacecat-shared-utils';
|
|
14
|
+
|
|
13
15
|
import { createAudit } from '../models/audit.js';
|
|
14
16
|
|
|
15
17
|
function parseEpochToDate(epochInSeconds) {
|
|
@@ -28,10 +30,10 @@ export const AuditDto = {
|
|
|
28
30
|
/**
|
|
29
31
|
* Converts an Audit object into a DynamoDB item.
|
|
30
32
|
* @param {Readonly<Audit>} audit - Audit object.
|
|
31
|
-
* @param {boolean}
|
|
33
|
+
* @param {boolean} isLatestAudit - If true, returns the latest audit flavor.
|
|
32
34
|
* @returns {{siteId, auditedAt, auditResult, auditType, expiresAt, fullAuditRef, SK: string}}
|
|
33
35
|
*/
|
|
34
|
-
toDynamoItem: (audit,
|
|
36
|
+
toDynamoItem: (audit, isLatestAudit = false) => {
|
|
35
37
|
const GSI1PK = 'ALL_LATEST_AUDITS';
|
|
36
38
|
let GSI1SK;
|
|
37
39
|
|
|
@@ -41,7 +43,12 @@ export const AuditDto = {
|
|
|
41
43
|
GSI1SK = `${audit.getAuditType()}#${Object.values(audit.getScores()).join('#')}`;
|
|
42
44
|
}
|
|
43
45
|
|
|
44
|
-
const latestAuditProps =
|
|
46
|
+
const latestAuditProps = isLatestAudit ? {
|
|
47
|
+
GSI1PK,
|
|
48
|
+
GSI1SK,
|
|
49
|
+
...(isObject(audit.getPreviousAuditResult())
|
|
50
|
+
&& { previousAuditResult: audit.getPreviousAuditResult() }),
|
|
51
|
+
} : {};
|
|
45
52
|
|
|
46
53
|
return {
|
|
47
54
|
siteId: audit.getSiteId(),
|
|
@@ -70,6 +77,8 @@ export const AuditDto = {
|
|
|
70
77
|
expiresAt: parseEpochToDate(dynamoItem.expiresAt),
|
|
71
78
|
fullAuditRef: dynamoItem.fullAuditRef,
|
|
72
79
|
isLive: dynamoItem.isLive,
|
|
80
|
+
...(isObject(dynamoItem.previousAuditResult)
|
|
81
|
+
&& { previousAuditResult: dynamoItem.previousAuditResult }),
|
|
73
82
|
};
|
|
74
83
|
|
|
75
84
|
return createAudit(auditData);
|
package/src/index.d.ts
CHANGED
|
@@ -34,6 +34,19 @@ export interface Audit {
|
|
|
34
34
|
*/
|
|
35
35
|
getAuditResult: () => object;
|
|
36
36
|
|
|
37
|
+
/**
|
|
38
|
+
* Retrieves the result of the previous audit.
|
|
39
|
+
* This serves for comparison purposes.
|
|
40
|
+
* @returns {object|null} The parsed audit result.
|
|
41
|
+
*/
|
|
42
|
+
getPreviousAuditResult: () => object | null;
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* Sets the result of the previous audit.
|
|
46
|
+
* @param {object} result The parsed audit result.
|
|
47
|
+
*/
|
|
48
|
+
setPreviousAuditResult: (result: object) => void;
|
|
49
|
+
|
|
37
50
|
/**
|
|
38
51
|
* Retrieves the type of the audit.
|
|
39
52
|
* @returns {object} The audit type.
|
|
@@ -195,6 +208,11 @@ export interface Site {
|
|
|
195
208
|
}
|
|
196
209
|
|
|
197
210
|
export interface DataAccess {
|
|
211
|
+
getAuditForSite: (
|
|
212
|
+
sitedId: string,
|
|
213
|
+
auditType: string,
|
|
214
|
+
auditedAt: string,
|
|
215
|
+
) => Promise<Audit | null>;
|
|
198
216
|
getAuditsForSite: (
|
|
199
217
|
siteId: string,
|
|
200
218
|
auditType?: string,
|
package/src/models/audit.js
CHANGED
|
@@ -36,6 +36,10 @@ const validateScores = (auditResult, auditType) => {
|
|
|
36
36
|
return true;
|
|
37
37
|
}
|
|
38
38
|
|
|
39
|
+
if (!isObject(auditResult.scores)) {
|
|
40
|
+
throw new Error(`Missing scores property for audit type '${auditType}'`);
|
|
41
|
+
}
|
|
42
|
+
|
|
39
43
|
const expectedProperties = AUDIT_TYPE_PROPERTIES[auditType];
|
|
40
44
|
if (!expectedProperties) {
|
|
41
45
|
throw new Error(`Unknown audit type: ${auditType}`);
|
|
@@ -66,6 +70,11 @@ const Audit = (data = {}) => {
|
|
|
66
70
|
self.getFullAuditRef = () => self.state.fullAuditRef;
|
|
67
71
|
self.isLive = () => self.state.isLive;
|
|
68
72
|
self.isError = () => hasText(self.getAuditResult().runtimeError?.code);
|
|
73
|
+
self.getPreviousAuditResult = () => self.state.previousAuditResult;
|
|
74
|
+
self.setPreviousAuditResult = (previousAuditResult) => {
|
|
75
|
+
validateScores(previousAuditResult, self.getAuditType());
|
|
76
|
+
self.state.previousAuditResult = previousAuditResult;
|
|
77
|
+
};
|
|
69
78
|
self.getScores = () => self.getAuditResult().scores;
|
|
70
79
|
|
|
71
80
|
return Object.freeze(self);
|
|
@@ -98,6 +107,14 @@ export const createAudit = (data) => {
|
|
|
98
107
|
|
|
99
108
|
validateScores(data.auditResult, data.auditType);
|
|
100
109
|
|
|
110
|
+
if (data.previousAuditResult && !isObject(data.previousAuditResult)) {
|
|
111
|
+
throw new Error('Previous audit result must be an object');
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
if (data.previousAuditResult) {
|
|
115
|
+
validateScores(data.previousAuditResult, data.auditType);
|
|
116
|
+
}
|
|
117
|
+
|
|
101
118
|
if (!hasText(newState.fullAuditRef)) {
|
|
102
119
|
throw new Error('Full audit ref must be provided');
|
|
103
120
|
}
|
|
@@ -184,25 +184,40 @@ export const addAudit = async (
|
|
|
184
184
|
log,
|
|
185
185
|
auditData,
|
|
186
186
|
) => {
|
|
187
|
-
const
|
|
187
|
+
const newAudit = createAudit(auditData);
|
|
188
188
|
const existingAudit = await getAuditForSite(
|
|
189
189
|
dynamoClient,
|
|
190
190
|
config,
|
|
191
191
|
log,
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
192
|
+
newAudit.getSiteId(),
|
|
193
|
+
newAudit.getAuditType(),
|
|
194
|
+
newAudit.getAuditedAt(),
|
|
195
195
|
);
|
|
196
196
|
|
|
197
197
|
if (isObject(existingAudit)) {
|
|
198
198
|
throw new Error('Audit already exists');
|
|
199
199
|
}
|
|
200
200
|
|
|
201
|
+
const latestAudit = await getLatestAuditForSite(
|
|
202
|
+
dynamoClient,
|
|
203
|
+
config,
|
|
204
|
+
log,
|
|
205
|
+
newAudit.getSiteId(),
|
|
206
|
+
newAudit.getAuditType(),
|
|
207
|
+
);
|
|
208
|
+
|
|
209
|
+
if (isObject(latestAudit)) {
|
|
210
|
+
newAudit.setPreviousAuditResult(latestAudit.getAuditResult());
|
|
211
|
+
}
|
|
212
|
+
|
|
201
213
|
// TODO: Add transaction support
|
|
202
|
-
await dynamoClient.putItem(config.tableNameAudits, AuditDto.toDynamoItem(
|
|
203
|
-
await dynamoClient.putItem(
|
|
214
|
+
await dynamoClient.putItem(config.tableNameAudits, AuditDto.toDynamoItem(newAudit));
|
|
215
|
+
await dynamoClient.putItem(
|
|
216
|
+
config.tableNameLatestAudits,
|
|
217
|
+
AuditDto.toDynamoItem(newAudit, true),
|
|
218
|
+
);
|
|
204
219
|
|
|
205
|
-
return
|
|
220
|
+
return newAudit;
|
|
206
221
|
};
|
|
207
222
|
|
|
208
223
|
/**
|