@adobe/spacecat-shared-utils 1.52.0 → 1.54.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/schemas.js +39 -5
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,17 @@
|
|
|
1
|
+
# [@adobe/spacecat-shared-utils-v1.54.0](https://github.com/adobe/spacecat-shared/compare/@adobe/spacecat-shared-utils-v1.53.0...@adobe/spacecat-shared-utils-v1.54.0) (2025-10-02)
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
### Features
|
|
5
|
+
|
|
6
|
+
* remove topic from brand alias and make regions mandatory in categories + make regions mandatory for categories ([#997](https://github.com/adobe/spacecat-shared/issues/997)) ([78e609a](https://github.com/adobe/spacecat-shared/commit/78e609a336cb2a2645199d94d4464c4843bd8c4a))
|
|
7
|
+
|
|
8
|
+
# [@adobe/spacecat-shared-utils-v1.53.0](https://github.com/adobe/spacecat-shared/compare/@adobe/spacecat-shared-utils-v1.52.0...@adobe/spacecat-shared-utils-v1.53.0) (2025-10-02)
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
### Features
|
|
12
|
+
|
|
13
|
+
* Add regions to categories and related validation on dependent entities ([#996](https://github.com/adobe/spacecat-shared/issues/996)) ([60c52e2](https://github.com/adobe/spacecat-shared/commit/60c52e2d9c7e79a67132ae2b26e40e617e8af358))
|
|
14
|
+
|
|
1
15
|
# [@adobe/spacecat-shared-utils-v1.52.0](https://github.com/adobe/spacecat-shared/compare/@adobe/spacecat-shared-utils-v1.51.1...@adobe/spacecat-shared-utils-v1.52.0) (2025-09-29)
|
|
2
16
|
|
|
3
17
|
|
package/package.json
CHANGED
package/src/schemas.js
CHANGED
|
@@ -36,14 +36,14 @@ import * as z from 'zod';
|
|
|
36
36
|
|
|
37
37
|
const nonEmptyString = z.string().min(1);
|
|
38
38
|
|
|
39
|
+
const region = z.string().length(2).regex(/^[a-z][a-z]$/i);
|
|
40
|
+
|
|
39
41
|
const entity = z.union([
|
|
40
|
-
z.object({ type: z.literal('category'), name: nonEmptyString }),
|
|
42
|
+
z.object({ type: z.literal('category'), name: nonEmptyString, region: z.union([region, z.array(region)]) }),
|
|
41
43
|
z.object({ type: z.literal('topic'), name: nonEmptyString }),
|
|
42
44
|
z.object({ type: nonEmptyString }),
|
|
43
45
|
]);
|
|
44
46
|
|
|
45
|
-
const region = z.string().length(2).regex(/^[a-z][a-z]$/i);
|
|
46
|
-
|
|
47
47
|
export const llmoConfig = z.object({
|
|
48
48
|
entities: z.record(z.uuid(), entity),
|
|
49
49
|
brands: z.object({
|
|
@@ -52,7 +52,6 @@ export const llmoConfig = z.object({
|
|
|
52
52
|
aliases: z.array(nonEmptyString),
|
|
53
53
|
category: z.uuid(),
|
|
54
54
|
region: z.union([region, z.array(region)]),
|
|
55
|
-
topic: z.uuid(),
|
|
56
55
|
}),
|
|
57
56
|
),
|
|
58
57
|
}),
|
|
@@ -72,11 +71,12 @@ export const llmoConfig = z.object({
|
|
|
72
71
|
|
|
73
72
|
brands.aliases.forEach((alias, index) => {
|
|
74
73
|
ensureEntityType(entities, ctx, alias.category, 'category', ['brands', 'aliases', index, 'category'], 'category');
|
|
75
|
-
|
|
74
|
+
ensureRegionCompatibility(entities, ctx, alias.category, alias.region, ['brands', 'aliases', index, 'region'], 'brand alias');
|
|
76
75
|
});
|
|
77
76
|
|
|
78
77
|
competitors.competitors.forEach((competitor, index) => {
|
|
79
78
|
ensureEntityType(entities, ctx, competitor.category, 'category', ['competitors', 'competitors', index, 'category'], 'category');
|
|
79
|
+
ensureRegionCompatibility(entities, ctx, competitor.category, competitor.region, ['competitors', 'competitors', index, 'region'], 'competitor');
|
|
80
80
|
});
|
|
81
81
|
});
|
|
82
82
|
|
|
@@ -107,3 +107,37 @@ function ensureEntityType(entities, ctx, id, expectedType, path, refLabel) {
|
|
|
107
107
|
});
|
|
108
108
|
}
|
|
109
109
|
}
|
|
110
|
+
|
|
111
|
+
/**
|
|
112
|
+
* @param {LLMOConfig['entities']} entities
|
|
113
|
+
* @param {z.RefinementCtx} ctx
|
|
114
|
+
* @param {string} categoryId
|
|
115
|
+
* @param {string | string[]} itemRegion
|
|
116
|
+
* @param {Array<number | string>} path
|
|
117
|
+
* @param {string} itemLabel
|
|
118
|
+
*/
|
|
119
|
+
function ensureRegionCompatibility(entities, ctx, categoryId, itemRegion, path, itemLabel) {
|
|
120
|
+
const categoryEntity = entities[categoryId];
|
|
121
|
+
if (!categoryEntity) {
|
|
122
|
+
// Category validation is handled by ensureEntityType
|
|
123
|
+
return;
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
const categoryRegions = categoryEntity.region;
|
|
127
|
+
|
|
128
|
+
// Normalize regions to arrays for comparison
|
|
129
|
+
const categoryRegionArray = Array.isArray(categoryRegions) ? categoryRegions : [categoryRegions];
|
|
130
|
+
const itemRegionArray = Array.isArray(itemRegion) ? itemRegion : [itemRegion];
|
|
131
|
+
|
|
132
|
+
// Check if all item regions are contained in category regions
|
|
133
|
+
const invalidRegions = itemRegionArray.filter(
|
|
134
|
+
(regionItem) => !categoryRegionArray.includes(regionItem),
|
|
135
|
+
);
|
|
136
|
+
if (invalidRegions.length > 0) {
|
|
137
|
+
ctx.addIssue({
|
|
138
|
+
code: 'custom',
|
|
139
|
+
path,
|
|
140
|
+
message: `${itemLabel} regions [${invalidRegions.join(', ')}] are not allowed. Category only supports regions: [${categoryRegionArray.join(', ')}]`,
|
|
141
|
+
});
|
|
142
|
+
}
|
|
143
|
+
}
|