@adobe/spacecat-shared-data-access 2.27.0 → 2.29.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-v2.29.0](https://github.com/adobe/spacecat-shared/compare/@adobe/spacecat-shared-data-access-v2.28.0...@adobe/spacecat-shared-data-access-v2.29.0) (2025-06-20)
2
+
3
+
4
+ ### Features
5
+
6
+ * introduce findByPreviewURL in site collection ([#773](https://github.com/adobe/spacecat-shared/issues/773)) ([3b7c092](https://github.com/adobe/spacecat-shared/commit/3b7c0925ce66bcb8d38db3e05cc04fefd0cac229))
7
+
8
+ # [@adobe/spacecat-shared-data-access-v2.28.0](https://github.com/adobe/spacecat-shared/compare/@adobe/spacecat-shared-data-access-v2.27.0...@adobe/spacecat-shared-data-access-v2.28.0) (2025-06-20)
9
+
10
+
11
+ ### Features
12
+
13
+ * add paid audit type ([#811](https://github.com/adobe/spacecat-shared/issues/811)) ([e8aae98](https://github.com/adobe/spacecat-shared/commit/e8aae9853f2d53c22a352cf41417829a15e55319))
14
+
1
15
  # [@adobe/spacecat-shared-data-access-v2.27.0](https://github.com/adobe/spacecat-shared/compare/@adobe/spacecat-shared-data-access-v2.26.0...@adobe/spacecat-shared-data-access-v2.27.0) (2025-06-19)
2
16
 
3
17
 
package/README.md CHANGED
@@ -81,6 +81,8 @@ The module provides the following DAOs:
81
81
  - `addSite`
82
82
  - `updateSite`
83
83
  - `removeSite`
84
+ - `findByPreviewURL`
85
+ - `findByExternalOwnerIdAndExternalSiteId`
84
86
 
85
87
  ### Site Candidate Functions
86
88
  - `getSiteCandidateByBaseURL`
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@adobe/spacecat-shared-data-access",
3
- "version": "2.27.0",
3
+ "version": "2.29.0",
4
4
  "description": "Shared modules of the Spacecat Services - Data Access",
5
5
  "type": "module",
6
6
  "engines": {
@@ -35,7 +35,7 @@
35
35
  "access": "public"
36
36
  },
37
37
  "dependencies": {
38
- "@adobe/spacecat-shared-utils": "1.38.4",
38
+ "@adobe/spacecat-shared-utils": "1.39.1",
39
39
  "@aws-sdk/client-dynamodb": "3.828.0",
40
40
  "@aws-sdk/lib-dynamodb": "3.828.0",
41
41
  "@types/joi": "17.2.3",
@@ -49,6 +49,7 @@ class Audit extends BaseModel {
49
49
  ALT_TEXT: 'alt-text',
50
50
  ACCESSIBILITY: 'accessibility',
51
51
  SECURITY_CSP: 'security-csp',
52
+ PAID: 'paid',
52
53
  };
53
54
 
54
55
  static AUDIT_TYPE_PROPERTIES = {
@@ -176,4 +176,8 @@ export interface SiteCollection extends BaseCollection<Organization> {
176
176
  findByBaseURL(baseURL: string): Promise<Site | null>;
177
177
  findByDeliveryType(deliveryType: string): Promise<Site | null>;
178
178
  findByOrganizationId(organizationId: string): Promise<Site | null>;
179
+ findByPreviewURL(previewURL: string): Promise<Site | null>;
180
+ findByExternalOwnerIdAndExternalSiteId(
181
+ externalOwnerId: string, externalSiteId: string
182
+ ): Promise<Site | null>;
179
183
  }
@@ -10,12 +10,12 @@
10
10
  * governing permissions and limitations under the License.
11
11
  */
12
12
 
13
- import { hasText } from '@adobe/spacecat-shared-utils';
13
+ import { hasText, isValidHelixPreviewUrl, isValidUrl } from '@adobe/spacecat-shared-utils';
14
14
 
15
15
  import DataAccessError from '../../errors/data-access.error.js';
16
16
  import BaseCollection from '../base/base.collection.js';
17
17
 
18
- import Site from './site.model.js';
18
+ import Site, { AEM_CS_HOST, getPreviewType } from './site.model.js';
19
19
 
20
20
  /**
21
21
  * SiteCollection - A collection class responsible for managing Site entities.
@@ -71,6 +71,35 @@ class SiteCollection extends BaseCollection {
71
71
 
72
72
  return orderedSites;
73
73
  }
74
+
75
+ async findByPreviewURL(previewURL) {
76
+ if (!isValidUrl(previewURL)) {
77
+ throw new DataAccessError(`Invalid preview URL: ${previewURL}`, this);
78
+ }
79
+
80
+ const { hostname } = new URL(previewURL);
81
+ const previewType = getPreviewType(hostname, Site.DELIVERY_TYPES);
82
+
83
+ switch (previewType) {
84
+ case Site.DELIVERY_TYPES.AEM_EDGE: {
85
+ if (!isValidHelixPreviewUrl(previewURL)) {
86
+ throw new DataAccessError(`Invalid Helix preview URL: ${previewURL}`, this);
87
+ }
88
+ const [host] = hostname.split('.');
89
+ const [ref, site, owner] = host.split('--');
90
+ const externalOwnerId = `${ref}#${owner}`;
91
+ return this.findByExternalOwnerIdAndExternalSiteId(externalOwnerId, site);
92
+ }
93
+ case Site.DELIVERY_TYPES.AEM_CS: {
94
+ const [, programId, envId] = AEM_CS_HOST.exec(hostname);
95
+ const externalOwnerId = `p${programId}`;
96
+ const externalSiteId = `e${envId}`;
97
+ return this.findByExternalOwnerIdAndExternalSiteId(externalOwnerId, externalSiteId);
98
+ }
99
+ default:
100
+ throw new DataAccessError(`Unsupported preview URL: ${previewURL}`, this);
101
+ }
102
+ }
74
103
  }
75
104
 
76
105
  export default SiteCollection;
@@ -13,6 +13,50 @@
13
13
  import { composeAuditURL, hasText, isValidUrl } from '@adobe/spacecat-shared-utils';
14
14
  import BaseModel from '../base/base.model.js';
15
15
 
16
+ const HLX_HOST = /\.(?:aem|hlx)\.(?:page|live)$/i;
17
+ export const AEM_CS_HOST = /^author-p(\d+)-e(\d+)/i;
18
+
19
+ /**
20
+ * Computes external IDs based on delivery type and configuration
21
+ */
22
+ export const computeExternalIds = (attrs) => {
23
+ const { hlxConfig, deliveryConfig } = attrs;
24
+
25
+ if (hlxConfig) {
26
+ const rso = hlxConfig.rso ?? {};
27
+ const { ref, owner, site } = rso;
28
+
29
+ return {
30
+ externalOwnerId: ref && owner ? `${ref}#${owner}` : undefined,
31
+ externalSiteId: site || undefined,
32
+ };
33
+ }
34
+
35
+ if (deliveryConfig) {
36
+ const { programId, environmentId } = deliveryConfig;
37
+
38
+ return {
39
+ externalOwnerId: programId ? `p${programId}` : undefined,
40
+ externalSiteId: environmentId ? `e${environmentId}` : undefined,
41
+ };
42
+ }
43
+
44
+ return { externalOwnerId: undefined, externalSiteId: undefined };
45
+ };
46
+
47
+ /**
48
+ * Determines the preview type based on hostname
49
+ */
50
+ export const getPreviewType = (hostname, deliveryTypes) => {
51
+ if (HLX_HOST.test(hostname)) {
52
+ return deliveryTypes.AEM_EDGE;
53
+ }
54
+ if (AEM_CS_HOST.test(hostname)) {
55
+ return deliveryTypes.AEM_CS;
56
+ }
57
+ return null;
58
+ };
59
+
16
60
  /**
17
61
  * A class representing a Site entity. Provides methods to access and manipulate Site-specific data.
18
62
  * @class Site
@@ -35,7 +79,7 @@ class Site extends BaseModel {
35
79
  }
36
80
 
37
81
  /**
38
- * Resolves the site's base URL to a final URL by fetching the URL,
82
+ * Resolves the site's base URL to a final URL by fetching the URL,
39
83
  * following the redirects and returning the final URL.
40
84
  *
41
85
  * If the site has a configured overrideBaseURL, that one will be returned.
@@ -22,7 +22,7 @@ import {
22
22
  import { Config, DEFAULT_CONFIG, validateConfiguration } from './config.js';
23
23
  import SchemaBuilder from '../base/schema.builder.js';
24
24
 
25
- import Site from './site.model.js';
25
+ import Site, { computeExternalIds } from './site.model.js';
26
26
  import SiteCollection from './site.collection.js';
27
27
 
28
28
  /*
@@ -94,10 +94,28 @@ const schema = new SchemaBuilder(Site, SiteCollection)
94
94
  set: () => new Date().toISOString(),
95
95
  validate: (value) => !value || isIsoDate(value),
96
96
  })
97
+ .addAttribute('externalOwnerId', {
98
+ type: 'string',
99
+ hidden: true,
100
+ readOnly: true,
101
+ watch: ['hlxConfig', 'deliveryConfig'],
102
+ set: (_, attrs) => computeExternalIds(attrs).externalOwnerId,
103
+ })
104
+ .addAttribute('externalSiteId', {
105
+ type: 'string',
106
+ hidden: true,
107
+ readOnly: true,
108
+ watch: ['hlxConfig', 'deliveryConfig'],
109
+ set: (_, attrs) => computeExternalIds(attrs).externalSiteId,
110
+ })
97
111
  .addAllIndex(['baseURL'])
98
112
  .addIndex(
99
113
  { composite: ['deliveryType'] },
100
114
  { composite: ['updatedAt'] },
115
+ )
116
+ .addIndex(
117
+ { composite: ['externalOwnerId'] },
118
+ { composite: ['externalSiteId'] },
101
119
  );
102
120
 
103
121
  export default schema.build();