@adobe/spacecat-shared-data-access 1.23.6 → 1.24.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 CHANGED
@@ -1,3 +1,10 @@
1
+ # [@adobe/spacecat-shared-data-access-v1.24.0](https://github.com/adobe/spacecat-shared/compare/@adobe/spacecat-shared-data-access-v1.23.6...@adobe/spacecat-shared-data-access-v1.24.0) (2024-06-06)
2
+
3
+
4
+ ### Features
5
+
6
+ * Add import-job.js and import-url.js to the data model layer ([#250](https://github.com/adobe/spacecat-shared/issues/250)) ([447a95e](https://github.com/adobe/spacecat-shared/commit/447a95e0c4fbb6afa630d9ba78c699974b9f5d5c))
7
+
1
8
  # [@adobe/spacecat-shared-data-access-v1.23.6](https://github.com/adobe/spacecat-shared/compare/@adobe/spacecat-shared-data-access-v1.23.5...@adobe/spacecat-shared-data-access-v1.23.6) (2024-06-01)
2
9
 
3
10
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@adobe/spacecat-shared-data-access",
3
- "version": "1.23.6",
3
+ "version": "1.24.0",
4
4
  "description": "Shared modules of the Spacecat Services - Data Access",
5
5
  "type": "module",
6
6
  "main": "src/index.js",
@@ -0,0 +1,63 @@
1
+ /*
2
+ * Copyright 2024 Adobe. All rights reserved.
3
+ * This file is licensed to you under the Apache License, Version 2.0 (the "License");
4
+ * you may not use this file except in compliance with the License. You may obtain a copy
5
+ * of the License at http://www.apache.org/licenses/LICENSE-2.0
6
+ *
7
+ * Unless required by applicable law or agreed to in writing, software distributed under
8
+ * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
9
+ * OF ANY KIND, either express or implied. See the License for the specific language
10
+ * governing permissions and limitations under the License.
11
+ */
12
+
13
+ import { createImportJob } from '../models/importer/import-job.js';
14
+
15
+ /**
16
+ * Data Transfer Object for ImportJob
17
+ */
18
+
19
+ export const ImportJobDto = {
20
+
21
+ /**
22
+ * Converts an ImportJob object into a DynamoDB item.
23
+ * @param importJob
24
+ * @returns {{duration: *, baseURL: *, failedCount: *, apiKey: *,
25
+ * options: *, successCount: *, importQueueId: *, startTime: *, id: *,
26
+ * endTime: *, status: *}}
27
+ */
28
+ toDynamoItem: (importJob) => ({
29
+ id: importJob.getId(),
30
+ baseURL: importJob.getBaseURL(),
31
+ apiKey: importJob.getApiKey(),
32
+ options: importJob.getOptions(),
33
+ startTime: importJob.getStartTime(),
34
+ endTime: importJob.getEndTime(),
35
+ duration: importJob.getDuration(),
36
+ status: importJob.getStatus(),
37
+ successCount: importJob.getSuccessCount(),
38
+ failedCount: importJob.getFailedCount(),
39
+ importQueueId: importJob.getImportQueueId(),
40
+ GSI1PK: 'ALL_IMPORT_JOBS',
41
+ }),
42
+
43
+ /**
44
+ * Converts a DynamoDB item into an ImportJob object.
45
+ */
46
+ fromDynamoItem: (dynamoItem) => {
47
+ const importJobData = {
48
+ id: dynamoItem.id,
49
+ baseURL: dynamoItem.baseURL,
50
+ apiKey: dynamoItem.apiKey,
51
+ options: dynamoItem.options,
52
+ startTime: dynamoItem.startTime,
53
+ endTime: dynamoItem.endTime,
54
+ duration: dynamoItem.duration,
55
+ status: dynamoItem.status,
56
+ successCount: dynamoItem.successCount,
57
+ failedCount: dynamoItem.failedCount,
58
+ importQueueId: dynamoItem.importQueueId,
59
+ };
60
+
61
+ return createImportJob(importJobData);
62
+ },
63
+ };
@@ -0,0 +1,43 @@
1
+ /*
2
+ * Copyright 2024 Adobe. All rights reserved.
3
+ * This file is licensed to you under the Apache License, Version 2.0 (the "License");
4
+ * you may not use this file except in compliance with the License. You may obtain a copy
5
+ * of the License at http://www.apache.org/licenses/LICENSE-2.0
6
+ *
7
+ * Unless required by applicable law or agreed to in writing, software distributed under
8
+ * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
9
+ * OF ANY KIND, either express or implied. See the License for the specific language
10
+ * governing permissions and limitations under the License.
11
+ */
12
+
13
+ import { createImportUrl } from '../models/importer/import-url.js';
14
+
15
+ /**
16
+ * Data Transfer Object for ImportUrl
17
+ */
18
+
19
+ export const ImportUrlDto = {
20
+
21
+ /**
22
+ * Converts an importUrl object to a DynamoDB item
23
+ */
24
+ toDynamoItem: (importUrl) => ({
25
+ id: importUrl.getId(),
26
+ jobId: importUrl.getJobId(),
27
+ url: importUrl.getUrl(),
28
+ status: importUrl.getStatus(),
29
+ }),
30
+
31
+ /**
32
+ * Converts a DynamoDB item into an ImportUrl object
33
+ */
34
+ fromDynamoItem: (dynamoItem) => {
35
+ const importUrlData = {
36
+ id: dynamoItem.id,
37
+ jobId: dynamoItem.jobId,
38
+ url: dynamoItem.url,
39
+ status: dynamoItem.status,
40
+ };
41
+ return createImportUrl(importUrlData);
42
+ },
43
+ };
package/src/index.d.ts CHANGED
@@ -431,6 +431,87 @@ export interface Configuration {
431
431
 
432
432
  }
433
433
 
434
+ export interface ImportJob {
435
+ /**
436
+ * Retrieves the ID of the import job.
437
+ */
438
+ getId: () => string;
439
+
440
+ /**
441
+ * Retrieves the apiKey of the import job.
442
+ */
443
+ getApiKey: () => string;
444
+
445
+ /**
446
+ * Retrieves the status of the import job.
447
+ */
448
+ getStatus: () => string;
449
+
450
+ /**
451
+ * Retrieves the baseURL of the import job.
452
+ */
453
+ getBaseURL: () => string;
454
+
455
+ /**
456
+ * Retrieves the options of the import job.
457
+ */
458
+ getOptions: () => object;
459
+
460
+ /**
461
+ * Retrieves the startTime of the import job.
462
+ */
463
+ getStartTime: () => string;
464
+
465
+ /**
466
+ * Retrieves the endTime of the import job.
467
+ */
468
+ getEndTime: () => string;
469
+
470
+ /**
471
+ * Retrieves the duration of the import job.
472
+ */
473
+ getDuration: () => number;
474
+
475
+ /**
476
+ * Retrieves the success count of the import job.
477
+ */
478
+ getSuccessCount: () => number;
479
+
480
+ /**
481
+ * Retrieves the failure count of the import job.
482
+ */
483
+ getFailureCount: () => number;
484
+
485
+ /**
486
+ * Retrieves the importQueueId of the import job.
487
+ */
488
+ getImportQueueId: () => string;
489
+
490
+ }
491
+
492
+ export interface ImportUrl {
493
+ /**
494
+ * Retrieves the ID of the import URL.
495
+ */
496
+ getId: () => string;
497
+
498
+ /**
499
+ * Retrieves the status of the import URL.
500
+ */
501
+ getStatus: () => string;
502
+
503
+ /**
504
+ * Retrieves the URL of the import URL.
505
+ */
506
+ getUrl: () => string;
507
+
508
+ /**
509
+ * Retrieves the job ID of the import URL.
510
+ */
511
+ getJobId: () => string;
512
+
513
+ }
514
+
434
515
  export interface DataAccess {
435
516
  getAuditForSite: (
436
517
  sitedId: string,
@@ -520,6 +601,21 @@ export interface DataAccess {
520
601
  removeOrganization: (
521
602
  organizationId: string,
522
603
  ) => Promise<void>;
604
+ getImportJobByID: (
605
+ id: string,
606
+ ) => Promise<ImportJob | null>;
607
+ getImportJobsByStatus: (
608
+ status: string,
609
+ ) => Promise<ImportJob[]>;
610
+ createNewImportJob: (
611
+ importJobData: object,
612
+ ) => Promise<ImportJob>;
613
+ getImportUrlByID: (
614
+ id: string,
615
+ ) => Promise<ImportUrl | null>;
616
+ createNewImportUrl: (
617
+ importUrlData: object,
618
+ ) => Promise<ImportUrl>;
523
619
 
524
620
  // site candidate functions
525
621
  getSiteCandidateByBaseURL: (baseURL: string) => Promise<SiteCandidate>;
@@ -554,6 +650,8 @@ interface DataAccessConfig {
554
650
  tableNameSiteCandidates: string;
555
651
  tableNameConfigurations: string;
556
652
  tableNameSiteTopPages: string;
653
+ tableNameImportJobs: string;
654
+ tableNameImportUrls: string;
557
655
  indexNameAllKeyEventsBySiteId: string,
558
656
  indexNameAllSites: string;
559
657
  indexNameAllSitesOrganizations: string,
@@ -561,10 +659,12 @@ interface DataAccessConfig {
561
659
  indexNameAllLatestAuditScores: string;
562
660
  indexNameAllOrganizations: string,
563
661
  indexNameAllOrganizationsByImsOrgId: string,
662
+ indexNameAllImportJobsByStatus: string,
564
663
  pkAllSites: string;
565
664
  pkAllLatestAudits: string;
566
665
  pkAllOrganizations: string;
567
666
  pkAllConfigurations: string;
667
+ pkAllImportJobs: string;
568
668
  }
569
669
 
570
670
  export function createDataAccess(
package/src/index.js CHANGED
@@ -20,6 +20,8 @@ const TABLE_NAME_SITE_CANDIDATES = 'spacecat-services-site-candidates-dev';
20
20
  const TABLE_NAME_ORGANIZATIONS = 'spacecat-services-organizations-dev';
21
21
  const TABLE_NAME_CONFIGURATIONS = 'spacecat-services-configurations-dev';
22
22
  const TABLE_NAME_SITE_TOP_PAGES = 'spacecat-services-site-top-pages-dev';
23
+ const TABLE_NAME_IMPORT_JOBS = 'spacecat-services-import-jobs-dev';
24
+ const TABLE_NAME_IMPORT_URLS = 'spacecat-services-import-urls-dev';
23
25
 
24
26
  const INDEX_NAME_ALL_KEY_EVENTS_BY_SITE_ID = 'spacecat-services-key-events-by-site-id';
25
27
  const INDEX_NAME_ALL_SITES = 'spacecat-services-all-sites-dev';
@@ -28,11 +30,13 @@ const INDEX_NAME_ALL_ORGANIZATIONS_BY_IMS_ORG_ID = 'spacecat-services-all-organi
28
30
  const INDEX_NAME_ALL_SITES_BY_DELIVERY_TYPE = 'spacecat-services-all-sites-by-delivery-type-dev';
29
31
  const INDEX_NAME_ALL_LATEST_AUDIT_SCORES = 'spacecat-services-all-latest-audit-scores-dev';
30
32
  const INDEX_NAME_ALL_SITES_ORGANIZATIONS = 'spacecat-services-all-sites-organizations-dev';
33
+ const INDEX_NAME_ALL_IMPORT_JOBS_BY_STATUS = 'spacecat-services-all-import-jobs-by-status-dev';
31
34
 
32
35
  const PK_ALL_SITES = 'ALL_SITES';
33
36
  const PK_ALL_CONFIGURATIONS = 'ALL_CONFIGURATIONS';
34
37
  const PK_ALL_ORGANIZATIONS = 'ALL_ORGANIZATIONS';
35
38
  const PK_ALL_LATEST_AUDITS = 'ALL_LATEST_AUDITS';
39
+ const PK_ALL_IMPORT_JOBS = 'ALL_IMPORT_JOBS';
36
40
 
37
41
  export default function dataAccessWrapper(fn) {
38
42
  return async (request, context) => {
@@ -48,6 +52,8 @@ export default function dataAccessWrapper(fn) {
48
52
  DYNAMO_TABLE_NAME_ORGANIZATIONS = TABLE_NAME_ORGANIZATIONS,
49
53
  DYNAMO_TABLE_NAME_CONFIGURATIONS = TABLE_NAME_CONFIGURATIONS,
50
54
  DYNAMO_TABLE_NAME_SITE_TOP_PAGES = TABLE_NAME_SITE_TOP_PAGES,
55
+ DYNAMO_TABLE_NAME_IMPORT_JOBS = TABLE_NAME_IMPORT_JOBS,
56
+ DYNAMO_TABLE_NAME_IMPORT_URLS = TABLE_NAME_IMPORT_URLS,
51
57
  DYNAMO_INDEX_NAME_ALL_KEY_EVENTS_BY_SITE_ID = INDEX_NAME_ALL_KEY_EVENTS_BY_SITE_ID,
52
58
  DYNAMO_INDEX_NAME_ALL_SITES = INDEX_NAME_ALL_SITES,
53
59
  DYNAMO_INDEX_NAME_ALL_SITES_BY_DELIVERY_TYPE = INDEX_NAME_ALL_SITES_BY_DELIVERY_TYPE,
@@ -56,6 +62,7 @@ export default function dataAccessWrapper(fn) {
56
62
  // eslint-disable-next-line max-len
57
63
  DYNAMO_INDEX_NAME_ALL_ORGANIZATIONS_BY_IMS_ORG_ID = INDEX_NAME_ALL_ORGANIZATIONS_BY_IMS_ORG_ID,
58
64
  DYNAMO_INDEX_NAME_ALL_SITES_ORGANIZATIONS = INDEX_NAME_ALL_SITES_ORGANIZATIONS,
65
+ DYNAMO_INDEX_NAME_ALL_IMPORT_JOBS_BY_STATUS = INDEX_NAME_ALL_IMPORT_JOBS_BY_STATUS,
59
66
  } = context.env;
60
67
 
61
68
  context.dataAccess = createDataAccess({
@@ -67,6 +74,8 @@ export default function dataAccessWrapper(fn) {
67
74
  tableNameSiteCandidates: DYNAMO_TABLE_NAME_SITE_CANDIDATES,
68
75
  tableNameConfigurations: DYNAMO_TABLE_NAME_CONFIGURATIONS,
69
76
  tableNameSiteTopPages: DYNAMO_TABLE_NAME_SITE_TOP_PAGES,
77
+ tableNameImportJobs: DYNAMO_TABLE_NAME_IMPORT_JOBS,
78
+ tableNameImportUrls: DYNAMO_TABLE_NAME_IMPORT_URLS,
70
79
  indexNameAllKeyEventsBySiteId: DYNAMO_INDEX_NAME_ALL_KEY_EVENTS_BY_SITE_ID,
71
80
  indexNameAllSites: DYNAMO_INDEX_NAME_ALL_SITES,
72
81
  indexNameAllOrganizations: DYNAMO_INDEX_NAME_ALL_ORGANIZATIONS,
@@ -74,10 +83,12 @@ export default function dataAccessWrapper(fn) {
74
83
  indexNameAllSitesByDeliveryType: DYNAMO_INDEX_NAME_ALL_SITES_BY_DELIVERY_TYPE,
75
84
  indexNameAllLatestAuditScores: DYNAMO_INDEX_NAME_ALL_LATEST_AUDIT_SCORES,
76
85
  indexNameAllSitesOrganizations: DYNAMO_INDEX_NAME_ALL_SITES_ORGANIZATIONS,
86
+ indexNameAllImportJobsByStatus: DYNAMO_INDEX_NAME_ALL_IMPORT_JOBS_BY_STATUS,
77
87
  pkAllSites: PK_ALL_SITES,
78
88
  pkAllOrganizations: PK_ALL_ORGANIZATIONS,
79
89
  pkAllLatestAudits: PK_ALL_LATEST_AUDITS,
80
90
  pkAllConfigurations: PK_ALL_CONFIGURATIONS,
91
+ pkAllImportJobs: PK_ALL_IMPORT_JOBS,
81
92
  }, log);
82
93
  }
83
94
 
@@ -0,0 +1,175 @@
1
+ /*
2
+ * Copyright 2024 Adobe. All rights reserved.
3
+ * This file is licensed to you under the Apache License, Version 2.0 (the "License");
4
+ * you may not use this file except in compliance with the License. You may obtain a copy
5
+ * of the License at http://www.apache.org/licenses/LICENSE-2.0
6
+ *
7
+ * Unless required by applicable law or agreed to in writing, software distributed under
8
+ * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
9
+ * OF ANY KIND, either express or implied. See the License for the specific language
10
+ * governing permissions and limitations under the License.
11
+ */
12
+
13
+ import {
14
+ hasText, isIsoDate, isValidUrl, isObject, isString, isNumber,
15
+ } from '@adobe/spacecat-shared-utils';
16
+ import { Base } from '../base.js';
17
+
18
+ export const IMPORT_JOB_STATUS = {
19
+ RUNNING: 'RUNNING',
20
+ COMPLETE: 'COMPLETE',
21
+ FAILED: 'FAILED',
22
+ };
23
+
24
+ /**
25
+ * Creates a new ImportJob object.
26
+ *
27
+ * @param {Object} importJobData - The data for the ImportJob object.
28
+ * @returns {ImportJob} The new ImportJob object.
29
+ */
30
+ const ImportJob = (data) => {
31
+ const self = Base(data);
32
+
33
+ self.getBaseURL = () => self.state.baseURL;
34
+ self.getApiKey = () => self.state.apiKey;
35
+ self.getOptions = () => self.state.options;
36
+ self.getStartTime = () => self.state.startTime;
37
+ self.getEndTime = () => self.state.endTime;
38
+ self.getDuration = () => self.state.duration;
39
+ self.getStatus = () => self.state.status;
40
+ self.getSuccessCount = () => self.state.successCount;
41
+ self.getFailedCount = () => self.state.failedCount;
42
+ self.getImportQueueId = () => self.state.importQueueId;
43
+
44
+ /**
45
+ * Updates the end time of the ImportJob.
46
+ * @param {string} endTime - The new end time.
47
+ * @returns {ImportJob} The updated ImportJob object.
48
+ */
49
+ self.updateEndTime = (endTime) => {
50
+ if (!isIsoDate(endTime)) {
51
+ throw new Error(`Invalid end time during update: ${endTime}`);
52
+ }
53
+
54
+ self.state.endTime = endTime;
55
+ self.touch();
56
+
57
+ return self;
58
+ };
59
+
60
+ /**
61
+ * Updates the duration of the ImportJob.
62
+ * @param {number} duration - The new duration.
63
+ * @returns {ImportJob} The updated ImportJob object.
64
+ */
65
+ self.updateDuration = (duration) => {
66
+ if (!isNumber(duration)) {
67
+ throw new Error(`Invalid duration during update: ${duration}`);
68
+ }
69
+
70
+ self.state.duration = duration;
71
+ self.touch();
72
+
73
+ return self;
74
+ };
75
+
76
+ /**
77
+ * Updates the status of the ImportJob.
78
+ * @param {string} status - The new status.
79
+ * @returns {ImportJob} The updated ImportJob object.
80
+ */
81
+ self.updateStatus = (status) => {
82
+ if (!Object.values(IMPORT_JOB_STATUS).includes(status)) {
83
+ throw new Error(`Invalid Import Job status during update: ${status}`);
84
+ }
85
+
86
+ self.state.status = status;
87
+ self.touch();
88
+
89
+ return self;
90
+ };
91
+
92
+ /**
93
+ * Updates the success count of the ImportJob.
94
+ * @param {number} successCount - The new success count.
95
+ * @returns {ImportJob} The updated ImportJob object.
96
+ */
97
+ self.updateSuccessCount = (successCount) => {
98
+ if (!isNumber(successCount)) {
99
+ throw new Error(`Invalid success count during update: ${successCount}`);
100
+ }
101
+
102
+ self.state.successCount = successCount;
103
+ self.touch();
104
+
105
+ return self;
106
+ };
107
+
108
+ /**
109
+ * Updates the failed count of the ImportJob.
110
+ * @param {number} failedCount - The new failed count.
111
+ * @returns {ImportJob} The updated ImportJob object.
112
+ */
113
+ self.updateFailedCount = (failedCount) => {
114
+ if (!isNumber(failedCount)) {
115
+ throw new Error(`Invalid failed count during update: ${failedCount}`);
116
+ }
117
+
118
+ self.state.failedCount = failedCount;
119
+ self.touch();
120
+
121
+ return self;
122
+ };
123
+
124
+ /**
125
+ * Updates the import queue id of the ImportJob.
126
+ * @param {string} importQueueId - The new import queue id.
127
+ * @returns {ImportJob} The updated ImportJob object.
128
+ */
129
+ self.updateImportQueueId = (importQueueId) => {
130
+ if (!hasText(importQueueId)) {
131
+ throw new Error(`Invalid import queue id during update: ${importQueueId}`);
132
+ }
133
+
134
+ self.state.importQueueId = importQueueId;
135
+ self.touch();
136
+
137
+ return self;
138
+ };
139
+ return Object.freeze(self);
140
+ };
141
+
142
+ /**
143
+ * Creates a new ImportJob object.
144
+ * @param {Object} importJobData - The data for the ImportJob object.
145
+ * @returns {ImportJob} The new ImportJob object.
146
+ */
147
+ export const createImportJob = (data) => {
148
+ const newState = { ...data };
149
+
150
+ if (!isValidUrl(newState.baseURL)) {
151
+ throw new Error(`Invalid base URL: ${newState.baseURL}`);
152
+ }
153
+
154
+ if (!isString(newState.apiKey)) {
155
+ throw new Error(`Invalid API key: ${newState.apiKey}`);
156
+ }
157
+
158
+ if (hasText(newState.startTime) && !isIsoDate(newState.startTime)) {
159
+ throw new Error('"StartTime" should be a valid ISO string');
160
+ }
161
+
162
+ if (!hasText(newState.startTime)) {
163
+ newState.startTime = new Date().toISOString();
164
+ }
165
+
166
+ if (!Object.values(IMPORT_JOB_STATUS).includes(newState.status)) {
167
+ throw new Error(`Invalid Import Job status ${newState.status}`);
168
+ }
169
+
170
+ if (!isObject(newState.options)) {
171
+ throw new Error(`Invalid options: ${newState.options}`);
172
+ }
173
+
174
+ return ImportJob(newState);
175
+ };
@@ -0,0 +1,61 @@
1
+ /*
2
+ * Copyright 2024 Adobe. All rights reserved.
3
+ * This file is licensed to you under the Apache License, Version 2.0 (the "License");
4
+ * you may not use this file except in compliance with the License. You may obtain a copy
5
+ * of the License at http://www.apache.org/licenses/LICENSE-2.0
6
+ *
7
+ * Unless required by applicable law or agreed to in writing, software distributed under
8
+ * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
9
+ * OF ANY KIND, either express or implied. See the License for the specific language
10
+ * governing permissions and limitations under the License.
11
+ */
12
+
13
+ import { isValidUrl } from '@adobe/spacecat-shared-utils';
14
+ import { Base } from '../base.js';
15
+ import { IMPORT_JOB_STATUS } from './import-job.js';
16
+
17
+ /**
18
+ * Creates a new ImportUrl object
19
+ *
20
+ * @param {Object} importUrlData
21
+ * @returns {ImportUrl}
22
+ */
23
+ const ImportUrl = (data) => {
24
+ const self = Base(data);
25
+
26
+ self.getJobId = () => self.state.jobId;
27
+ self.getUrl = () => self.state.url;
28
+ self.getStatus = () => self.state.status;
29
+
30
+ /**
31
+ * Updates the status of the ImportUrl
32
+ */
33
+ self.updateStatus = (status) => {
34
+ if (!Object.values(IMPORT_JOB_STATUS).includes(status)) {
35
+ throw new Error(`Invalid Import URL status during update: ${status}`);
36
+ }
37
+
38
+ self.state.status = status;
39
+ self.touch();
40
+
41
+ return self;
42
+ };
43
+ return Object.freeze(self);
44
+ };
45
+
46
+ /**
47
+ * Creates a new ImportUrl object
48
+ */
49
+ export const createImportUrl = (data) => {
50
+ const newState = { ...data };
51
+
52
+ if (!isValidUrl(newState.url)) {
53
+ throw new Error(`Invalid Url: ${newState.url}`);
54
+ }
55
+
56
+ if (!Object.values(IMPORT_JOB_STATUS).includes(newState.status)) {
57
+ throw new Error(`Invalid Import URL status: ${newState.status}`);
58
+ }
59
+
60
+ return ImportUrl(newState);
61
+ };
@@ -0,0 +1,65 @@
1
+ /*
2
+ * Copyright 2024 Adobe. All rights reserved.
3
+ * This file is licensed to you under the Apache License, Version 2.0 (the "License");
4
+ * you may not use this file except in compliance with the License. You may obtain a copy
5
+ * of the License at http://www.apache.org/licenses/LICENSE-2.0
6
+ *
7
+ * Unless required by applicable law or agreed to in writing, software distributed under
8
+ * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
9
+ * OF ANY KIND, either express or implied. See the License for the specific language
10
+ * governing permissions and limitations under the License.
11
+ */
12
+
13
+ import { ImportJobDto } from '../../dto/import-job.js';
14
+ import { createImportJob } from '../../models/importer/import-job.js';
15
+
16
+ /**
17
+ * Get Import Job by ID
18
+ * @param {DynamoClient} dynamoClient
19
+ * @param {Object} config
20
+ * @param {Logger} log
21
+ * @param {string} id
22
+ * @returns {Promise<ImportJobDto> | null}
23
+ */
24
+ export const getImportJobByID = async (dynamoClient, config, log, id) => {
25
+ const item = await dynamoClient.getItem(
26
+ config.tableNameImportJobs,
27
+ { id },
28
+ );
29
+ return item ? ImportJobDto.fromDynamoItem(item) : null;
30
+ };
31
+
32
+ /**
33
+ * Get Import jobs by status
34
+ * @param {DynamoClient} dynamoClient
35
+ * @param {Object} config
36
+ * @param {Logger} log
37
+ * @param {string} status
38
+ * @returns {Promise<ImportJobDto[]>}
39
+ */
40
+ export const getImportJobsByStatus = async (dynamoClient, config, log, status) => {
41
+ const items = await dynamoClient.query({
42
+ TableName: config.tableNameImportJobs,
43
+ IndexName: config.indexNameAllImportJobsByStatus,
44
+ KeyConditionExpression: 'GSI1PK = :gsi1pk AND status = :status',
45
+ ExpressionAttributeValues: {
46
+ ':gsi1pk': config.pkAllImportJobs,
47
+ ':status': status,
48
+ },
49
+ });
50
+ return items.map((item) => ImportJobDto.fromDynamoItem(item));
51
+ };
52
+
53
+ /**
54
+ * Creates a new Import Job
55
+ * @param {DynamoClient} dynamoClient
56
+ * @param {Object} config
57
+ * @param {Logger} log
58
+ * @param {Object} importJobData
59
+ * @returns {Promise<ImportJobDto>}
60
+ */
61
+ export const createNewImportJob = async (dynamoClient, config, log, importJobData) => {
62
+ const importJob = createImportJob(importJobData);
63
+ await dynamoClient.putItem(config.tableNameImportJobs, ImportJobDto.toDynamoItem(importJob));
64
+ return importJob;
65
+ };
@@ -0,0 +1,38 @@
1
+ /*
2
+ * Copyright 2024 Adobe. All rights reserved.
3
+ * This file is licensed to you under the Apache License, Version 2.0 (the "License");
4
+ * you may not use this file except in compliance with the License. You may obtain a copy
5
+ * of the License at http://www.apache.org/licenses/LICENSE-2.0
6
+ *
7
+ * Unless required by applicable law or agreed to in writing, software distributed under
8
+ * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
9
+ * OF ANY KIND, either express or implied. See the License for the specific language
10
+ * governing permissions and limitations under the License.
11
+ */
12
+
13
+ import {
14
+ createNewImportJob,
15
+ getImportJobByID,
16
+ getImportJobsByStatus,
17
+ } from './accessPatterns.js';
18
+
19
+ export const importJobFunctions = (dynamoClient, config, log) => ({
20
+ getImportJobByID: (id) => getImportJobByID(
21
+ dynamoClient,
22
+ config,
23
+ log,
24
+ id,
25
+ ),
26
+ getImportJobsByStatus: (status) => getImportJobsByStatus(
27
+ dynamoClient,
28
+ config,
29
+ log,
30
+ status,
31
+ ),
32
+ createNewImportJob: (importJobData) => createNewImportJob(
33
+ dynamoClient,
34
+ config,
35
+ log,
36
+ importJobData,
37
+ ),
38
+ });
@@ -0,0 +1,47 @@
1
+ /*
2
+ * Copyright 2024 Adobe. All rights reserved.
3
+ * This file is licensed to you under the Apache License, Version 2.0 (the "License");
4
+ * you may not use this file except in compliance with the License. You may obtain a copy
5
+ * of the License at http://www.apache.org/licenses/LICENSE-2.0
6
+ *
7
+ * Unless required by applicable law or agreed to in writing, software distributed under
8
+ * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
9
+ * OF ANY KIND, either express or implied. See the License for the specific language
10
+ * governing permissions and limitations under the License.
11
+ */
12
+
13
+ import { ImportUrlDto } from '../../dto/import-url.js';
14
+ import { createImportUrl } from '../../models/importer/import-url.js';
15
+
16
+ /**
17
+ * Get import url by ID
18
+ * @param {DynamoClient} dynamoClient
19
+ * @param {Object} config
20
+ * @param {Logger} log
21
+ * @param {string} id
22
+ * @returns {Promise<ImportUrlDto> | null}
23
+ */
24
+ export const getImportUrlById = async (dynamoClient, config, log, id) => {
25
+ const item = await dynamoClient.getItem(
26
+ config.tableNameImportUrls,
27
+ { id },
28
+ );
29
+ return item ? ImportUrlDto.fromDynamoItem(item) : null;
30
+ };
31
+
32
+ /**
33
+ * Create a new Import Url
34
+ * @param {DynamoClient} dynamoClient
35
+ * @param {Object} config
36
+ * @param {Logger} log
37
+ * @param {Object} importUrlData
38
+ * @returns {Promise<ImportUrlDto>}
39
+ */
40
+ export const createNewImportUrl = async (dynamoClient, config, log, importUrlData) => {
41
+ const importUrl = createImportUrl(importUrlData);
42
+ await dynamoClient.putItem(
43
+ config.tableNameImportUrls,
44
+ ImportUrlDto.toDynamoItem(importUrl),
45
+ );
46
+ return importUrl;
47
+ };
@@ -0,0 +1,28 @@
1
+ /*
2
+ * Copyright 2024 Adobe. All rights reserved.
3
+ * This file is licensed to you under the Apache License, Version 2.0 (the "License");
4
+ * you may not use this file except in compliance with the License. You may obtain a copy
5
+ * of the License at http://www.apache.org/licenses/LICENSE-2.0
6
+ *
7
+ * Unless required by applicable law or agreed to in writing, software distributed under
8
+ * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
9
+ * OF ANY KIND, either express or implied. See the License for the specific language
10
+ * governing permissions and limitations under the License.
11
+ */
12
+
13
+ import { getImportUrlById, createNewImportUrl } from './accessPatterns.js';
14
+
15
+ export const importUrlFunctions = (dynamoClient, config, log) => ({
16
+ getImportUrlById: (id) => getImportUrlById(
17
+ dynamoClient,
18
+ config,
19
+ log,
20
+ id,
21
+ ),
22
+ createNewImportUrl: (importUrlData) => createNewImportUrl(
23
+ dynamoClient,
24
+ config,
25
+ log,
26
+ importUrlData,
27
+ ),
28
+ });
@@ -18,6 +18,8 @@ import { siteCandidateFunctions } from './site-candidates/index.js';
18
18
  import { organizationFunctions } from './organizations/index.js';
19
19
  import { configurationFunctions } from './configurations/index.js';
20
20
  import { siteTopPagesFunctions } from './site-top-pages/index.js';
21
+ import { importJobFunctions } from './import-job/index.js';
22
+ import { importUrlFunctions } from './import-url/index.js';
21
23
 
22
24
  /**
23
25
  * Creates a data access object.
@@ -25,6 +27,7 @@ import { siteTopPagesFunctions } from './site-top-pages/index.js';
25
27
  * @param {{pkAllSites: string, pkAllLatestAudits: string, indexNameAllLatestAuditScores: string,
26
28
  * tableNameAudits: string,tableNameLatestAudits: string, indexNameAllSitesOrganizations: string,
27
29
  * tableNameSites: string, tableNameOrganizations: string, indexNameAllSites: string,
30
+ * tableNameImportJobs: string, pkAllImportJobs: string, indexNameAllImportJobs: string,
28
31
  * tableNameSiteTopPages: string, indexNameAllOrganizations: string,
29
32
  * indexNameAllOrganizationsByImsOrgId: string, pkAllOrganizations: string}} config configuration
30
33
  * @param {Logger} log logger
@@ -40,6 +43,8 @@ export const createDataAccess = (config, log = console) => {
40
43
  const organizationFuncs = organizationFunctions(dynamoClient, config, log);
41
44
  const configurationFuncs = configurationFunctions(dynamoClient, config);
42
45
  const siteTopPagesFuncs = siteTopPagesFunctions(dynamoClient, config);
46
+ const importJobFuncs = importJobFunctions(dynamoClient, config, log);
47
+ const importUrlFuncs = importUrlFunctions(dynamoClient, config, log);
43
48
 
44
49
  return {
45
50
  ...auditFuncs,
@@ -49,5 +54,7 @@ export const createDataAccess = (config, log = console) => {
49
54
  ...organizationFuncs,
50
55
  ...configurationFuncs,
51
56
  ...siteTopPagesFuncs,
57
+ ...importJobFuncs,
58
+ ...importUrlFuncs,
52
59
  };
53
60
  };