@adobe/spacecat-shared-data-access 2.8.3 → 2.9.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.9.0](https://github.com/adobe/spacecat-shared/compare/@adobe/spacecat-shared-data-access-v2.8.4...@adobe/spacecat-shared-data-access-v2.9.0) (2025-02-25)
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
### Features
|
|
5
|
+
|
|
6
|
+
* import config schema ([#626](https://github.com/adobe/spacecat-shared/issues/626)) ([df147d8](https://github.com/adobe/spacecat-shared/commit/df147d8c8f83cc45f373b1d89823229afe035129))
|
|
7
|
+
|
|
8
|
+
# [@adobe/spacecat-shared-data-access-v2.8.4](https://github.com/adobe/spacecat-shared/compare/@adobe/spacecat-shared-data-access-v2.8.3...@adobe/spacecat-shared-data-access-v2.8.4) (2025-02-25)
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
### Bug Fixes
|
|
12
|
+
|
|
13
|
+
* add in progress suggestion status ([#627](https://github.com/adobe/spacecat-shared/issues/627)) ([188c83f](https://github.com/adobe/spacecat-shared/commit/188c83f03a16406085e1ae6ecbd129a27a6d41e7))
|
|
14
|
+
|
|
1
15
|
# [@adobe/spacecat-shared-data-access-v2.8.3](https://github.com/adobe/spacecat-shared/compare/@adobe/spacecat-shared-data-access-v2.8.2...@adobe/spacecat-shared-data-access-v2.8.3) (2025-02-22)
|
|
2
16
|
|
|
3
17
|
|
package/package.json
CHANGED
|
@@ -12,13 +12,75 @@
|
|
|
12
12
|
|
|
13
13
|
import Joi from 'joi';
|
|
14
14
|
|
|
15
|
+
export const IMPORT_TYPES = {
|
|
16
|
+
ORGANIC_KEYWORDS: 'organic-keywords',
|
|
17
|
+
ORGANIC_TRAFFIC: 'organic-traffic',
|
|
18
|
+
TOP_PAGES: 'top-pages',
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
export const IMPORT_DESTINATIONS = {
|
|
22
|
+
DEFAULT: 'default',
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
export const IMPORT_SOURCES = {
|
|
26
|
+
AHREFS: 'ahrefs',
|
|
27
|
+
GSC: 'google',
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
const IMPORT_BASE_KEYS = {
|
|
31
|
+
destinations: Joi.array().items(Joi.string().valid(IMPORT_DESTINATIONS.DEFAULT)).required(),
|
|
32
|
+
sources: Joi.array().items(Joi.string().valid(...Object.values(IMPORT_SOURCES))).required(),
|
|
33
|
+
enabled: Joi.boolean().required().default(true),
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
export const IMPORT_TYPE_SCHEMAS = {
|
|
37
|
+
[IMPORT_TYPES.ORGANIC_KEYWORDS]: Joi.object({
|
|
38
|
+
type: Joi.string().valid(IMPORT_TYPES.ORGANIC_KEYWORDS).required(),
|
|
39
|
+
...IMPORT_BASE_KEYS,
|
|
40
|
+
pageUrl: Joi.string().uri(),
|
|
41
|
+
}),
|
|
42
|
+
[IMPORT_TYPES.ORGANIC_TRAFFIC]: Joi.object({
|
|
43
|
+
type: Joi.string().valid(IMPORT_TYPES.ORGANIC_TRAFFIC).required(),
|
|
44
|
+
...IMPORT_BASE_KEYS,
|
|
45
|
+
}),
|
|
46
|
+
[IMPORT_TYPES.TOP_PAGES]: Joi.object({
|
|
47
|
+
type: Joi.string().valid(IMPORT_TYPES.TOP_PAGES).required(),
|
|
48
|
+
...IMPORT_BASE_KEYS,
|
|
49
|
+
geo: Joi.string(),
|
|
50
|
+
}),
|
|
51
|
+
};
|
|
52
|
+
|
|
53
|
+
export const DEFAULT_IMPORT_CONFIGS = {
|
|
54
|
+
'organic-keywords': {
|
|
55
|
+
type: 'organic-keywords',
|
|
56
|
+
destinations: ['default'],
|
|
57
|
+
sources: ['ahrefs'],
|
|
58
|
+
enabled: true,
|
|
59
|
+
},
|
|
60
|
+
'organic-traffic': {
|
|
61
|
+
type: 'organic-traffic',
|
|
62
|
+
destinations: ['default'],
|
|
63
|
+
sources: ['ahrefs'],
|
|
64
|
+
enabled: true,
|
|
65
|
+
},
|
|
66
|
+
'top-pages': {
|
|
67
|
+
type: 'top-pages',
|
|
68
|
+
destinations: ['default'],
|
|
69
|
+
sources: ['ahrefs'],
|
|
70
|
+
enabled: true,
|
|
71
|
+
geo: 'global',
|
|
72
|
+
},
|
|
73
|
+
};
|
|
74
|
+
|
|
15
75
|
export const configSchema = Joi.object({
|
|
16
76
|
slack: Joi.object({
|
|
17
77
|
workspace: Joi.string(),
|
|
18
78
|
channel: Joi.string(),
|
|
19
79
|
invitedUserCount: Joi.number().integer().min(0),
|
|
20
80
|
}),
|
|
21
|
-
imports: Joi.array().items(
|
|
81
|
+
imports: Joi.array().items(
|
|
82
|
+
Joi.alternatives().try(...Object.values(IMPORT_TYPE_SCHEMAS)),
|
|
83
|
+
),
|
|
22
84
|
fetchConfig: Joi.object({
|
|
23
85
|
headers: Joi.object().pattern(Joi.string(), Joi.string()),
|
|
24
86
|
}).optional(),
|
|
@@ -136,6 +198,47 @@ export const Config = (data = {}) => {
|
|
|
136
198
|
state.fetchConfig = fetchConfig;
|
|
137
199
|
};
|
|
138
200
|
|
|
201
|
+
self.enableImport = (type, config = {}) => {
|
|
202
|
+
if (!IMPORT_TYPE_SCHEMAS[type]) {
|
|
203
|
+
throw new Error(`Unknown import type: ${type}`);
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
const defaultConfig = DEFAULT_IMPORT_CONFIGS[type];
|
|
207
|
+
const newConfig = {
|
|
208
|
+
...defaultConfig, ...config, type, enabled: true,
|
|
209
|
+
};
|
|
210
|
+
|
|
211
|
+
// Validate the new config against its schema
|
|
212
|
+
const { error } = IMPORT_TYPE_SCHEMAS[type].validate(newConfig);
|
|
213
|
+
if (error) {
|
|
214
|
+
throw new Error(`Invalid import config: ${error.message}`);
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
state.imports = state.imports || [];
|
|
218
|
+
// Remove existing import of same type if present
|
|
219
|
+
state.imports = state.imports.filter((imp) => imp.type !== type);
|
|
220
|
+
state.imports.push(newConfig);
|
|
221
|
+
|
|
222
|
+
validateConfiguration(state);
|
|
223
|
+
};
|
|
224
|
+
|
|
225
|
+
self.disableImport = (type) => {
|
|
226
|
+
if (!state.imports) return;
|
|
227
|
+
|
|
228
|
+
state.imports = state.imports.map(
|
|
229
|
+
(imp) => (imp.type === type ? { ...imp, enabled: false } : imp),
|
|
230
|
+
);
|
|
231
|
+
|
|
232
|
+
validateConfiguration(state);
|
|
233
|
+
};
|
|
234
|
+
|
|
235
|
+
self.getImportConfig = (type) => state.imports?.find((imp) => imp.type === type);
|
|
236
|
+
|
|
237
|
+
self.isImportEnabled = (type) => {
|
|
238
|
+
const config = self.getImportConfig(type);
|
|
239
|
+
return config?.enabled ?? false;
|
|
240
|
+
};
|
|
241
|
+
|
|
139
242
|
return Object.freeze(self);
|
|
140
243
|
};
|
|
141
244
|
|
|
@@ -23,13 +23,95 @@ import type {
|
|
|
23
23
|
SiteTopPage,
|
|
24
24
|
} from '../index';
|
|
25
25
|
|
|
26
|
+
export type IMPORT_TYPES = {
|
|
27
|
+
readonly ORGANIC_KEYWORDS: 'organic-keywords';
|
|
28
|
+
readonly ORGANIC_TRAFFIC: 'organic-traffic';
|
|
29
|
+
readonly TOP_PAGES: 'top-pages';
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
export type IMPORT_DESTINATIONS = {
|
|
33
|
+
readonly DEFAULT: 'default';
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
export type IMPORT_SOURCES = {
|
|
37
|
+
readonly AHREFS: 'ahrefs';
|
|
38
|
+
readonly GSC: 'google';
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
export type ImportType = 'organic-keywords' | 'organic-traffic' | 'top-pages';
|
|
42
|
+
export type ImportDestination = 'default';
|
|
43
|
+
export type ImportSource = 'ahrefs' | 'google';
|
|
44
|
+
|
|
45
|
+
export interface ImportConfig {
|
|
46
|
+
type: ImportType;
|
|
47
|
+
destinations: ImportDestination[];
|
|
48
|
+
sources: ImportSource[];
|
|
49
|
+
enabled: boolean;
|
|
50
|
+
pageUrl?: string;
|
|
51
|
+
geo?: string;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
export interface SiteConfig {
|
|
55
|
+
state: {
|
|
56
|
+
slack?: {
|
|
57
|
+
workspace?: string;
|
|
58
|
+
channel?: string;
|
|
59
|
+
invitedUserCount?: number;
|
|
60
|
+
};
|
|
61
|
+
imports?: ImportConfig[];
|
|
62
|
+
handlers?: Record<string, {
|
|
63
|
+
mentions?: Record<string, string[]>;
|
|
64
|
+
excludedURLs?: string[];
|
|
65
|
+
manualOverwrites?: Array<{
|
|
66
|
+
brokenTargetURL?: string;
|
|
67
|
+
targetURL?: string;
|
|
68
|
+
}>;
|
|
69
|
+
fixedURLs?: Array<{
|
|
70
|
+
brokenTargetURL?: string;
|
|
71
|
+
targetURL?: string;
|
|
72
|
+
}>;
|
|
73
|
+
includedURLs?: string[];
|
|
74
|
+
groupedURLs?: Array<{
|
|
75
|
+
name: string;
|
|
76
|
+
pattern: string;
|
|
77
|
+
}>;
|
|
78
|
+
latestMetrics?: {
|
|
79
|
+
pageViewsChange: number;
|
|
80
|
+
ctrChange: number;
|
|
81
|
+
projectedTrafficValue: number;
|
|
82
|
+
};
|
|
83
|
+
}>;
|
|
84
|
+
fetchConfig?: {
|
|
85
|
+
headers?: Record<string, string>;
|
|
86
|
+
};
|
|
87
|
+
};
|
|
88
|
+
getSlackConfig(): { workspace?: string; channel?: string; invitedUserCount?: number };
|
|
89
|
+
getImports(): ImportConfig[];
|
|
90
|
+
getImportConfig(type: ImportType): ImportConfig | undefined;
|
|
91
|
+
isImportEnabled(type: ImportType): boolean;
|
|
92
|
+
enableImport(type: ImportType, config?: Partial<ImportConfig>): void;
|
|
93
|
+
disableImport(type: ImportType): void;
|
|
94
|
+
getHandlers(): Record<string, object>;
|
|
95
|
+
getHandlerConfig(type: string): object;
|
|
96
|
+
getSlackMentions(type: string): string[] | undefined;
|
|
97
|
+
getExcludedURLs(type: string): string[] | undefined;
|
|
98
|
+
getManualOverwrites(type: string):
|
|
99
|
+
Array<{ brokenTargetURL?: string; targetURL?: string }> | undefined;
|
|
100
|
+
getFixedURLs(type: string): Array<{ brokenTargetURL?: string; targetURL?: string }> | undefined;
|
|
101
|
+
getIncludedURLs(type: string): string[] | undefined;
|
|
102
|
+
getGroupedURLs(type: string): Array<{ name: string; pattern: string }> | undefined;
|
|
103
|
+
getLatestMetrics(type: string):
|
|
104
|
+
{ pageViewsChange: number; ctrChange: number; projectedTrafficValue: number } | undefined;
|
|
105
|
+
getFetchConfig(): { headers?: Record<string, string> } | undefined;
|
|
106
|
+
}
|
|
107
|
+
|
|
26
108
|
export interface Site extends BaseModel {
|
|
27
109
|
getAudits(): Promise<Audit>;
|
|
28
110
|
getAuditsByAuditType(auditType: string): Promise<Audit>;
|
|
29
111
|
getAuditsByAuditTypeAndAuditedAt(auditType: string, auditedAt: string): Promise<Audit>;
|
|
30
112
|
getBaseURL(): string;
|
|
31
113
|
getName(): string;
|
|
32
|
-
getConfig():
|
|
114
|
+
getConfig(): SiteConfig;
|
|
33
115
|
getDeliveryType(): string;
|
|
34
116
|
getExperiments(): Promise<Experiment[]>;
|
|
35
117
|
getExperimentsByExpId(expId: string): Promise<Experiment[]>;
|