@adobe/spacecat-shared-data-access 1.23.6 → 1.25.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,17 @@
1
+ # [@adobe/spacecat-shared-data-access-v1.25.0](https://github.com/adobe/spacecat-shared/compare/@adobe/spacecat-shared-data-access-v1.24.0...@adobe/spacecat-shared-data-access-v1.25.0) (2024-06-07)
2
+
3
+
4
+ ### Features
5
+
6
+ * Add update queries for import-job and import-url entites ([#254](https://github.com/adobe/spacecat-shared/issues/254)) ([d1cba93](https://github.com/adobe/spacecat-shared/commit/d1cba93c2ce1073426dc8333142a8d8fd81017ea))
7
+
8
+ # [@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)
9
+
10
+
11
+ ### Features
12
+
13
+ * 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))
14
+
1
15
  # [@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
16
 
3
17
 
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.25.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,27 @@ 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
+ updateImportJob: (
614
+ importJob: ImportJob,
615
+ ) => Promise<ImportJob>;
616
+ getImportUrlByID: (
617
+ id: string,
618
+ ) => Promise<ImportUrl | null>;
619
+ createNewImportUrl: (
620
+ importUrlData: object,
621
+ ) => Promise<ImportUrl>;
622
+ updateImportUrl: (
623
+ importUrl: ImportUrl,
624
+ ) => Promise<ImportUrl>;
523
625
 
524
626
  // site candidate functions
525
627
  getSiteCandidateByBaseURL: (baseURL: string) => Promise<SiteCandidate>;
@@ -554,6 +656,8 @@ interface DataAccessConfig {
554
656
  tableNameSiteCandidates: string;
555
657
  tableNameConfigurations: string;
556
658
  tableNameSiteTopPages: string;
659
+ tableNameImportJobs: string;
660
+ tableNameImportUrls: string;
557
661
  indexNameAllKeyEventsBySiteId: string,
558
662
  indexNameAllSites: string;
559
663
  indexNameAllSitesOrganizations: string,
@@ -561,10 +665,12 @@ interface DataAccessConfig {
561
665
  indexNameAllLatestAuditScores: string;
562
666
  indexNameAllOrganizations: string,
563
667
  indexNameAllOrganizationsByImsOrgId: string,
668
+ indexNameAllImportJobsByStatus: string,
564
669
  pkAllSites: string;
565
670
  pkAllLatestAudits: string;
566
671
  pkAllOrganizations: string;
567
672
  pkAllConfigurations: string;
673
+ pkAllImportJobs: string;
568
674
  }
569
675
 
570
676
  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,85 @@
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 { isObject } from '@adobe/spacecat-shared-utils';
14
+ import { ImportJobDto } from '../../dto/import-job.js';
15
+ import { createImportJob } from '../../models/importer/import-job.js';
16
+
17
+ /**
18
+ * Get Import Job by ID
19
+ * @param {DynamoClient} dynamoClient
20
+ * @param {Object} config
21
+ * @param {Logger} log
22
+ * @param {string} id
23
+ * @returns {Promise<ImportJobDto> | null}
24
+ */
25
+ export const getImportJobByID = async (dynamoClient, config, log, id) => {
26
+ const item = await dynamoClient.getItem(
27
+ config.tableNameImportJobs,
28
+ { id },
29
+ );
30
+ return item ? ImportJobDto.fromDynamoItem(item) : null;
31
+ };
32
+
33
+ /**
34
+ * Get Import jobs by status
35
+ * @param {DynamoClient} dynamoClient
36
+ * @param {Object} config
37
+ * @param {Logger} log
38
+ * @param {string} status
39
+ * @returns {Promise<ImportJobDto[]>}
40
+ */
41
+ export const getImportJobsByStatus = async (dynamoClient, config, log, status) => {
42
+ const items = await dynamoClient.query({
43
+ TableName: config.tableNameImportJobs,
44
+ IndexName: config.indexNameAllImportJobsByStatus,
45
+ KeyConditionExpression: 'GSI1PK = :gsi1pk AND status = :status',
46
+ ExpressionAttributeValues: {
47
+ ':gsi1pk': config.pkAllImportJobs,
48
+ ':status': status,
49
+ },
50
+ });
51
+ return items.map((item) => ImportJobDto.fromDynamoItem(item));
52
+ };
53
+
54
+ /**
55
+ * Creates a new Import Job
56
+ * @param {DynamoClient} dynamoClient
57
+ * @param {Object} config
58
+ * @param {Logger} log
59
+ * @param {Object} importJobData
60
+ * @returns {Promise<ImportJobDto>}
61
+ */
62
+ export const createNewImportJob = async (dynamoClient, config, log, importJobData) => {
63
+ const importJob = createImportJob(importJobData);
64
+ await dynamoClient.putItem(config.tableNameImportJobs, ImportJobDto.toDynamoItem(importJob));
65
+ return importJob;
66
+ };
67
+
68
+ /**
69
+ * Updates an Import Job
70
+ * @param {DynamoClient} dynamoClient
71
+ * @param {Object} config
72
+ * @param {Logger} log
73
+ * @param {ImportJobDto} importJob
74
+ */
75
+ export const updateImportJob = async (dynamoClient, config, log, importJob) => {
76
+ const existingImportJob = await getImportJobByID(dynamoClient, config, log, importJob.getId());
77
+
78
+ if (!isObject(existingImportJob)) {
79
+ throw new Error(`Import Job with id: ${importJob.getId()} does not exist`);
80
+ }
81
+
82
+ await dynamoClient.putItem(config.tableNameImportJobs, ImportJobDto.toDynamoItem(importJob));
83
+
84
+ return importJob;
85
+ };
@@ -0,0 +1,45 @@
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
+ updateImportJob,
18
+ } from './accessPatterns.js';
19
+
20
+ export const importJobFunctions = (dynamoClient, config, log) => ({
21
+ getImportJobByID: (id) => getImportJobByID(
22
+ dynamoClient,
23
+ config,
24
+ log,
25
+ id,
26
+ ),
27
+ getImportJobsByStatus: (status) => getImportJobsByStatus(
28
+ dynamoClient,
29
+ config,
30
+ log,
31
+ status,
32
+ ),
33
+ createNewImportJob: (importJobData) => createNewImportJob(
34
+ dynamoClient,
35
+ config,
36
+ log,
37
+ importJobData,
38
+ ),
39
+ updateImportJob: (importJobData) => updateImportJob(
40
+ dynamoClient,
41
+ config,
42
+ log,
43
+ importJobData,
44
+ ),
45
+ });
@@ -0,0 +1,73 @@
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 { isObject } from '@adobe/spacecat-shared-utils';
14
+ import { ImportUrlDto } from '../../dto/import-url.js';
15
+ import { createImportUrl } from '../../models/importer/import-url.js';
16
+
17
+ /**
18
+ * Get import url by ID
19
+ * @param {DynamoClient} dynamoClient
20
+ * @param {Object} config
21
+ * @param {Logger} log
22
+ * @param {string} id
23
+ * @returns {Promise<ImportUrlDto> | null}
24
+ */
25
+ export const getImportUrlById = async (dynamoClient, config, log, id) => {
26
+ const item = await dynamoClient.getItem(
27
+ config.tableNameImportUrls,
28
+ { id },
29
+ );
30
+ return item ? ImportUrlDto.fromDynamoItem(item) : null;
31
+ };
32
+
33
+ /**
34
+ * Create a new Import Url
35
+ * @param {DynamoClient} dynamoClient
36
+ * @param {Object} config
37
+ * @param {Logger} log
38
+ * @param {Object} importUrlData
39
+ * @returns {Promise<ImportUrlDto>}
40
+ */
41
+ export const createNewImportUrl = async (dynamoClient, config, log, importUrlData) => {
42
+ const importUrl = createImportUrl(importUrlData);
43
+ await dynamoClient.putItem(
44
+ config.tableNameImportUrls,
45
+ ImportUrlDto.toDynamoItem(importUrl),
46
+ );
47
+ return importUrl;
48
+ };
49
+
50
+ /**
51
+ * Update an existing Import Url
52
+ * @param {DynamoClient} dynamoClient
53
+ * @param {Object} config
54
+ * @param {Logger} log
55
+ * @param {Object} importUrl
56
+ * @returns {ImportUrlDto}
57
+ */
58
+ export const updateImportUrl = async (dynamoClient, config, log, importUrl) => {
59
+ const existingImportUrl = await getImportUrlById(
60
+ dynamoClient,
61
+ config,
62
+ log,
63
+ importUrl.getId(),
64
+ );
65
+
66
+ if (!isObject(existingImportUrl)) {
67
+ throw new Error(`Import Url with ID:${importUrl.getId()} does not exist`);
68
+ }
69
+
70
+ await dynamoClient.putItem(config.tableNameImportUrls, ImportUrlDto.toDynamoItem(importUrl));
71
+
72
+ return importUrl;
73
+ };
@@ -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
+ getImportUrlById,
15
+ createNewImportUrl,
16
+ updateImportUrl,
17
+ } from './accessPatterns.js';
18
+
19
+ export const importUrlFunctions = (dynamoClient, config, log) => ({
20
+ getImportUrlById: (id) => getImportUrlById(
21
+ dynamoClient,
22
+ config,
23
+ log,
24
+ id,
25
+ ),
26
+ createNewImportUrl: (importUrlData) => createNewImportUrl(
27
+ dynamoClient,
28
+ config,
29
+ log,
30
+ importUrlData,
31
+ ),
32
+ updateImportUrl: (importUrl) => updateImportUrl(
33
+ dynamoClient,
34
+ config,
35
+ log,
36
+ importUrl,
37
+ ),
38
+ });
@@ -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
  };