@adobe/helix-config-storage 2.1.7 → 2.2.1
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 +2 -2
- package/src/config-store.js +64 -3
- package/src/config-validator.js +2 -0
- package/src/schemas/apikeys.schema.cjs +12 -0
- package/src/schemas/apikeys.schema.json +50 -0
- package/src/schemas/org.schema.json +3 -0
- package/src/schemas/sidekick.schema.json +154 -56
- package/src/schemas/site.schema.json +3 -0
- package/validate-json-schemas.sh +1 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,17 @@
|
|
|
1
|
+
## [2.2.1](https://github.com/adobe/helix-config-storage/compare/v2.2.0...v2.2.1) (2025-04-29)
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
### Bug Fixes
|
|
5
|
+
|
|
6
|
+
* **deps:** update dependency @adobe/helix-shared-config to v11.1.4 ([#118](https://github.com/adobe/helix-config-storage/issues/118)) ([1c5893b](https://github.com/adobe/helix-config-storage/commit/1c5893b2dac59c9bc091d5ae278d54619e609a54))
|
|
7
|
+
|
|
8
|
+
# [2.2.0](https://github.com/adobe/helix-config-storage/compare/v2.1.7...v2.2.0) (2025-04-22)
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
### Features
|
|
12
|
+
|
|
13
|
+
* support storing api key information ([b4d7de7](https://github.com/adobe/helix-config-storage/commit/b4d7de7ae49105fdd5da4dfda2b2a94ea105cef9))
|
|
14
|
+
|
|
1
15
|
## [2.1.7](https://github.com/adobe/helix-config-storage/compare/v2.1.6...v2.1.7) (2025-04-15)
|
|
2
16
|
|
|
3
17
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@adobe/helix-config-storage",
|
|
3
|
-
"version": "2.1
|
|
3
|
+
"version": "2.2.1",
|
|
4
4
|
"description": "Helix Config Storage",
|
|
5
5
|
"main": "src/index.js",
|
|
6
6
|
"types": "src/index.d.ts",
|
|
@@ -60,7 +60,7 @@
|
|
|
60
60
|
},
|
|
61
61
|
"dependencies": {
|
|
62
62
|
"@adobe/fetch": "4.2.0",
|
|
63
|
-
"@adobe/helix-shared-config": "11.1.
|
|
63
|
+
"@adobe/helix-shared-config": "11.1.4",
|
|
64
64
|
"@adobe/helix-shared-git": "3.0.18",
|
|
65
65
|
"@adobe/helix-shared-storage": "1.3.0",
|
|
66
66
|
"@adobe/helix-shared-string": "2.1.0",
|
package/src/config-store.js
CHANGED
|
@@ -11,7 +11,9 @@
|
|
|
11
11
|
*/
|
|
12
12
|
/* eslint-disable no-param-reassign */
|
|
13
13
|
import crypto from 'crypto';
|
|
14
|
+
import { decodeJwt } from 'jose';
|
|
14
15
|
import { HelixStorage } from '@adobe/helix-shared-storage';
|
|
16
|
+
import { sanitizeName } from '@adobe/helix-shared-string';
|
|
15
17
|
import { StatusCodeError } from './status-code-error.js';
|
|
16
18
|
import {
|
|
17
19
|
createToken, createUser,
|
|
@@ -43,6 +45,7 @@ const FRAGMENTS_COMMON = {
|
|
|
43
45
|
name: 'id',
|
|
44
46
|
'.': 'secret',
|
|
45
47
|
},
|
|
48
|
+
'.allowEmpty': true,
|
|
46
49
|
},
|
|
47
50
|
access: {
|
|
48
51
|
'.': 'object',
|
|
@@ -70,6 +73,7 @@ const FRAGMENTS_COMMON = {
|
|
|
70
73
|
name: 'id',
|
|
71
74
|
'.': 'token',
|
|
72
75
|
},
|
|
76
|
+
'.allowEmpty': true,
|
|
73
77
|
},
|
|
74
78
|
groups: {
|
|
75
79
|
'.': 'object',
|
|
@@ -79,8 +83,15 @@ const FRAGMENTS_COMMON = {
|
|
|
79
83
|
},
|
|
80
84
|
},
|
|
81
85
|
public: '*',
|
|
82
|
-
features:
|
|
83
|
-
|
|
86
|
+
features: {
|
|
87
|
+
'.': '*',
|
|
88
|
+
'.allowEmpty': true,
|
|
89
|
+
|
|
90
|
+
},
|
|
91
|
+
limits: {
|
|
92
|
+
'.': '*',
|
|
93
|
+
'.allowEmpty': true,
|
|
94
|
+
},
|
|
84
95
|
robots: 'object',
|
|
85
96
|
events: {
|
|
86
97
|
github: 'object',
|
|
@@ -91,6 +102,13 @@ const FRAGMENTS = {
|
|
|
91
102
|
sites: {
|
|
92
103
|
...FRAGMENTS_COMMON,
|
|
93
104
|
extends: 'object',
|
|
105
|
+
apiKeys: {
|
|
106
|
+
'.': 'apiKeys',
|
|
107
|
+
'.param': {
|
|
108
|
+
name: 'id',
|
|
109
|
+
'.': 'apiKey',
|
|
110
|
+
},
|
|
111
|
+
},
|
|
94
112
|
},
|
|
95
113
|
profiles: FRAGMENTS_COMMON,
|
|
96
114
|
org: {
|
|
@@ -100,6 +118,15 @@ const FRAGMENTS = {
|
|
|
100
118
|
name: 'id',
|
|
101
119
|
'.': 'secret',
|
|
102
120
|
},
|
|
121
|
+
'.allowEmpty': true,
|
|
122
|
+
},
|
|
123
|
+
apiKeys: {
|
|
124
|
+
'.': 'apiKeys',
|
|
125
|
+
'.param': {
|
|
126
|
+
name: 'id',
|
|
127
|
+
'.': 'apiKey',
|
|
128
|
+
},
|
|
129
|
+
'.allowEmpty': true,
|
|
103
130
|
},
|
|
104
131
|
tokens: {
|
|
105
132
|
'.': 'tokens',
|
|
@@ -107,6 +134,7 @@ const FRAGMENTS = {
|
|
|
107
134
|
name: 'id',
|
|
108
135
|
'.': 'token',
|
|
109
136
|
},
|
|
137
|
+
'.allowEmpty': true,
|
|
110
138
|
},
|
|
111
139
|
users: {
|
|
112
140
|
'.': 'users',
|
|
@@ -151,6 +179,10 @@ export function getFragmentInfo(type, relPath = '') {
|
|
|
151
179
|
fragment = '*';
|
|
152
180
|
break;
|
|
153
181
|
}
|
|
182
|
+
if (typeof next === 'object' && next['.'] === '*') {
|
|
183
|
+
fragment = next;
|
|
184
|
+
break;
|
|
185
|
+
}
|
|
154
186
|
if (!next) {
|
|
155
187
|
next = fragment['.param'];
|
|
156
188
|
if (!next) {
|
|
@@ -165,6 +197,7 @@ export function getFragmentInfo(type, relPath = '') {
|
|
|
165
197
|
} else {
|
|
166
198
|
info.type = fragment['.'];
|
|
167
199
|
}
|
|
200
|
+
info.allowEmpty = fragment['.allowEmpty'] || false;
|
|
168
201
|
return info;
|
|
169
202
|
}
|
|
170
203
|
|
|
@@ -530,7 +563,7 @@ export class ConfigStore {
|
|
|
530
563
|
}
|
|
531
564
|
if (frag) {
|
|
532
565
|
if (!old) {
|
|
533
|
-
if (this.type === 'profiles' &&
|
|
566
|
+
if (this.type === 'profiles' && frag.allowEmpty) {
|
|
534
567
|
old = {};
|
|
535
568
|
} else {
|
|
536
569
|
throw new StatusCodeError(404, 'config not found.');
|
|
@@ -561,6 +594,34 @@ export class ConfigStore {
|
|
|
561
594
|
// don't expose hash in return value
|
|
562
595
|
delete ret.hash;
|
|
563
596
|
}
|
|
597
|
+
if (frag.type === 'apiKeys') {
|
|
598
|
+
if (data.jwt) {
|
|
599
|
+
try {
|
|
600
|
+
const payload = await decodeJwt(data.jwt);
|
|
601
|
+
data.id = payload.jti;
|
|
602
|
+
data.roles = payload.roles;
|
|
603
|
+
data.subject = payload.sub;
|
|
604
|
+
data.expiration = new Date(payload.exp * 1000).toISOString();
|
|
605
|
+
delete data.jwt;
|
|
606
|
+
} catch (e) {
|
|
607
|
+
throw new StatusCodeError(400, e.message);
|
|
608
|
+
}
|
|
609
|
+
}
|
|
610
|
+
frag.name = sanitizeName(data.id);
|
|
611
|
+
frag.type = 'apiKey';
|
|
612
|
+
frag.relPath.push(frag.name);
|
|
613
|
+
}
|
|
614
|
+
if (frag.type === 'apiKey') {
|
|
615
|
+
if (data.jwt) {
|
|
616
|
+
throw new StatusCodeError(400, 'jwt not allowed in existing apiKey');
|
|
617
|
+
}
|
|
618
|
+
const oldData = deepGetOrCreate(old, frag.relPath, true);
|
|
619
|
+
data.created = oldData.created || new Date().toISOString();
|
|
620
|
+
// ensure that the name is equal to the sanitized id
|
|
621
|
+
if (frag.name !== sanitizeName(data.id)) {
|
|
622
|
+
throw new StatusCodeError(400, 'apiKey id mismatch');
|
|
623
|
+
}
|
|
624
|
+
}
|
|
564
625
|
if (frag.type === 'secrets') {
|
|
565
626
|
// create new secret with random id
|
|
566
627
|
frag.name = crypto.randomBytes(32).toString('base64url');
|
package/src/config-validator.js
CHANGED
|
@@ -16,6 +16,7 @@ import { ValidationError } from './ValidationError.js';
|
|
|
16
16
|
import accessAdminSchema from './schemas/access-admin.schema.cjs';
|
|
17
17
|
import accessSchema from './schemas/access.schema.cjs';
|
|
18
18
|
import accessSiteSchema from './schemas/access-site.schema.cjs';
|
|
19
|
+
import apiKeysSchema from './schemas/apikeys.schema.cjs';
|
|
19
20
|
import cdnSchema from './schemas/cdn.schema.cjs';
|
|
20
21
|
import cdnProdFastlySchema from './schemas/cdn-prod-fastly.schema.cjs';
|
|
21
22
|
import cdnProdCloudflareSchema from './schemas/cdn-prod-cloudflare.schema.cjs';
|
|
@@ -53,6 +54,7 @@ export const SCHEMAS = [
|
|
|
53
54
|
accessAdminSchema,
|
|
54
55
|
accessSchema,
|
|
55
56
|
accessSiteSchema,
|
|
57
|
+
apiKeysSchema,
|
|
56
58
|
cdnProdAkamaiSchema,
|
|
57
59
|
cdnProdCloudflareSchema,
|
|
58
60
|
cdnProdCloudfrontSchema,
|
|
@@ -0,0 +1,12 @@
|
|
|
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
|
+
module.exports = require('./apikeys.schema.json');
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$comment": "https://github.com/adobe/helix-config/blob/main/LICENSE.txt",
|
|
3
|
+
"$schema": "https://json-schema.org/draft/2019-09/schema",
|
|
4
|
+
"$id": "https://ns.adobe.com/helix/config/apikeys",
|
|
5
|
+
"title": "ApiKeys",
|
|
6
|
+
"type": "object",
|
|
7
|
+
"description": "Stores information about generated admin API keys. The keys listed here have no operational meaning, but are used to track the keys that have been generated.",
|
|
8
|
+
"patternProperties": {
|
|
9
|
+
"^[a-zA-Z0-9-_]+$": {
|
|
10
|
+
"type": "object",
|
|
11
|
+
"properties": {
|
|
12
|
+
"id": {
|
|
13
|
+
"type": "string",
|
|
14
|
+
"pattern": "^[a-zA-Z0-9-_/+]+$",
|
|
15
|
+
"description": "the API token id (jti)"
|
|
16
|
+
},
|
|
17
|
+
"created": {
|
|
18
|
+
"type": "string",
|
|
19
|
+
"format": "date-time"
|
|
20
|
+
},
|
|
21
|
+
"expiration": {
|
|
22
|
+
"type": "string",
|
|
23
|
+
"format": "date-time"
|
|
24
|
+
},
|
|
25
|
+
"roles": {
|
|
26
|
+
"type": "array",
|
|
27
|
+
"items": {
|
|
28
|
+
"type": "string"
|
|
29
|
+
}
|
|
30
|
+
},
|
|
31
|
+
"subject": {
|
|
32
|
+
"type": "string",
|
|
33
|
+
"description": "the subject of the API token (sub)"
|
|
34
|
+
},
|
|
35
|
+
"description": {
|
|
36
|
+
"type": "string"
|
|
37
|
+
}
|
|
38
|
+
},
|
|
39
|
+
"required": [
|
|
40
|
+
"id",
|
|
41
|
+
"subject",
|
|
42
|
+
"created",
|
|
43
|
+
"expiration",
|
|
44
|
+
"roles"
|
|
45
|
+
],
|
|
46
|
+
"additionalProperties": false
|
|
47
|
+
}
|
|
48
|
+
},
|
|
49
|
+
"additionalProperties": false
|
|
50
|
+
}
|
|
@@ -6,17 +6,25 @@
|
|
|
6
6
|
"sidekickPlugin": {
|
|
7
7
|
"type": "object",
|
|
8
8
|
"properties": {
|
|
9
|
-
"
|
|
10
|
-
"type": "string",
|
|
11
|
-
"description": "The unique plugin ID"
|
|
12
|
-
},
|
|
13
|
-
"title": {
|
|
14
|
-
"type": "string",
|
|
15
|
-
"description": "The button text"
|
|
16
|
-
},
|
|
17
|
-
"url": {
|
|
9
|
+
"badgeVariant": {
|
|
18
10
|
"type": "string",
|
|
19
|
-
"description": "The
|
|
11
|
+
"description": "The variant of the badge following the Adobe Spectrum badge variants",
|
|
12
|
+
"enum": [
|
|
13
|
+
"gray",
|
|
14
|
+
"red",
|
|
15
|
+
"orange",
|
|
16
|
+
"yellow",
|
|
17
|
+
"chartreuse",
|
|
18
|
+
"celery",
|
|
19
|
+
"green",
|
|
20
|
+
"seafoam",
|
|
21
|
+
"cyan",
|
|
22
|
+
"blue",
|
|
23
|
+
"indigo",
|
|
24
|
+
"purple",
|
|
25
|
+
"fuchsia",
|
|
26
|
+
"magenta"
|
|
27
|
+
]
|
|
20
28
|
},
|
|
21
29
|
"containerId": {
|
|
22
30
|
"type": "string",
|
|
@@ -26,7 +34,16 @@
|
|
|
26
34
|
"type": "array",
|
|
27
35
|
"items": {
|
|
28
36
|
"type": "string",
|
|
29
|
-
"enum": [
|
|
37
|
+
"enum": [
|
|
38
|
+
"any",
|
|
39
|
+
"dev",
|
|
40
|
+
"admin",
|
|
41
|
+
"edit",
|
|
42
|
+
"preview",
|
|
43
|
+
"review",
|
|
44
|
+
"live",
|
|
45
|
+
"prod"
|
|
46
|
+
]
|
|
30
47
|
},
|
|
31
48
|
"description": "The environments to display this plugin in",
|
|
32
49
|
"default": "any"
|
|
@@ -40,43 +57,73 @@
|
|
|
40
57
|
"items": {
|
|
41
58
|
"type": "string"
|
|
42
59
|
},
|
|
43
|
-
"description": "
|
|
60
|
+
"description": "Excludes the plugin from these paths",
|
|
44
61
|
"examples": [
|
|
45
62
|
"/foo/**",
|
|
46
63
|
"**/:x:**"
|
|
47
64
|
]
|
|
48
65
|
},
|
|
66
|
+
"id": {
|
|
67
|
+
"type": "string",
|
|
68
|
+
"description": "The unique plugin ID"
|
|
69
|
+
},
|
|
49
70
|
"includePaths": {
|
|
50
71
|
"type": "array",
|
|
51
72
|
"items": {
|
|
52
73
|
"type": "string"
|
|
53
74
|
},
|
|
54
|
-
"description": "
|
|
75
|
+
"description": "Includes the plugin on these paths (overrides excludePaths)",
|
|
55
76
|
"examples": [
|
|
56
77
|
"/foo/bar/**",
|
|
57
78
|
"**.docx**"
|
|
58
79
|
]
|
|
59
80
|
},
|
|
81
|
+
"isBadge": {
|
|
82
|
+
"type": "boolean",
|
|
83
|
+
"description": "Renders the plugin as a badge"
|
|
84
|
+
},
|
|
60
85
|
"isContainer": {
|
|
61
86
|
"type": "boolean",
|
|
62
|
-
"description": "
|
|
87
|
+
"description": "Renders the plugin as a container for other plugins"
|
|
63
88
|
},
|
|
64
89
|
"isPalette": {
|
|
65
90
|
"type": "boolean",
|
|
66
91
|
"description": "Opens the URL in a palette instead of a new tab"
|
|
67
92
|
},
|
|
93
|
+
"isPopover": {
|
|
94
|
+
"type": "boolean",
|
|
95
|
+
"description": "Opens the URL in a popover instead of a new tab"
|
|
96
|
+
},
|
|
68
97
|
"paletteRect": {
|
|
69
98
|
"type": "string",
|
|
70
|
-
"description": "
|
|
99
|
+
"description": "The dimensions and position of the palette (top, left, bottom, right, width, height)",
|
|
100
|
+
"examples": [
|
|
101
|
+
"top: 100px; right: 20px; width: 200px; height: 50vh"
|
|
102
|
+
]
|
|
71
103
|
},
|
|
72
|
-
"
|
|
104
|
+
"passConfig": {
|
|
73
105
|
"type": "boolean",
|
|
74
|
-
"description": "
|
|
106
|
+
"description": "Append ref, repo, owner, host, and project as query params to the URL"
|
|
107
|
+
},
|
|
108
|
+
"passReferrer": {
|
|
109
|
+
"type": "boolean",
|
|
110
|
+
"description": "Append the referrer URL as a query param to the URL"
|
|
111
|
+
},
|
|
112
|
+
"pinned": {
|
|
113
|
+
"type": "boolean",
|
|
114
|
+
"description": "Renders the plugin in the bar (true, default) or the menu (false)"
|
|
75
115
|
},
|
|
76
116
|
"popoverRect": {
|
|
77
117
|
"type": "string",
|
|
78
|
-
"description": "The dimensions of
|
|
79
|
-
|
|
118
|
+
"description": "The dimensions of the popover (width, height)",
|
|
119
|
+
"examples": [
|
|
120
|
+
"width: 400px; height: 300px"
|
|
121
|
+
]
|
|
122
|
+
},
|
|
123
|
+
"title": {
|
|
124
|
+
"type": "string",
|
|
125
|
+
"description": "The button text"
|
|
126
|
+
},
|
|
80
127
|
"titleI18n": {
|
|
81
128
|
"type": "object",
|
|
82
129
|
"description": "The button text in other supported languages",
|
|
@@ -89,59 +136,110 @@
|
|
|
89
136
|
"minProperties": 1,
|
|
90
137
|
"additionalProperties": false
|
|
91
138
|
},
|
|
92
|
-
"
|
|
93
|
-
"type": "
|
|
94
|
-
"description": "
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
139
|
+
"url": {
|
|
140
|
+
"type": "string",
|
|
141
|
+
"description": "The URL to open when the button is clicked"
|
|
142
|
+
}
|
|
143
|
+
},
|
|
144
|
+
"required": [
|
|
145
|
+
"id"
|
|
146
|
+
],
|
|
147
|
+
"dependentRequired": {
|
|
148
|
+
"isPalette": [
|
|
149
|
+
"url"
|
|
150
|
+
],
|
|
151
|
+
"paletteRect": [
|
|
152
|
+
"isPalette"
|
|
153
|
+
],
|
|
154
|
+
"isPopover": [
|
|
155
|
+
"url"
|
|
156
|
+
],
|
|
157
|
+
"popoverRect": [
|
|
158
|
+
"isPopover"
|
|
159
|
+
],
|
|
160
|
+
"badgeVariant": [
|
|
161
|
+
"isBadge"
|
|
162
|
+
]
|
|
163
|
+
},
|
|
164
|
+
"additionalProperties": false
|
|
165
|
+
},
|
|
166
|
+
"sidekickSpecialView": {
|
|
167
|
+
"type": "object",
|
|
168
|
+
"properties": {
|
|
169
|
+
"id": {
|
|
170
|
+
"type": "string",
|
|
171
|
+
"description": "The unique view ID"
|
|
99
172
|
},
|
|
100
|
-
"
|
|
101
|
-
"type": "
|
|
102
|
-
"description": "
|
|
173
|
+
"path": {
|
|
174
|
+
"type": "string",
|
|
175
|
+
"description": "Open the special view on this path",
|
|
176
|
+
"examples": [
|
|
177
|
+
"/foo/**.json"
|
|
178
|
+
]
|
|
103
179
|
},
|
|
104
|
-
"
|
|
180
|
+
"viewer": {
|
|
105
181
|
"type": "string",
|
|
106
|
-
"description": "The
|
|
107
|
-
"
|
|
108
|
-
"
|
|
109
|
-
"red",
|
|
110
|
-
"orange",
|
|
111
|
-
"yellow",
|
|
112
|
-
"chartreuse",
|
|
113
|
-
"celery",
|
|
114
|
-
"green",
|
|
115
|
-
"seafoam",
|
|
116
|
-
"cyan",
|
|
117
|
-
"blue",
|
|
118
|
-
"indigo",
|
|
119
|
-
"purple",
|
|
120
|
-
"fuchsia",
|
|
121
|
-
"magenta"
|
|
182
|
+
"description": "The URL of the special view. The resource path will be passed to it via 'path' parameter",
|
|
183
|
+
"examples": [
|
|
184
|
+
"/tools/sidekick/foo/index.html"
|
|
122
185
|
]
|
|
123
186
|
}
|
|
124
187
|
},
|
|
125
188
|
"required": [
|
|
126
|
-
"id"
|
|
189
|
+
"id",
|
|
190
|
+
"path",
|
|
191
|
+
"viewer"
|
|
127
192
|
],
|
|
128
|
-
"
|
|
129
|
-
"isPalette": ["url"],
|
|
130
|
-
"paletteRect": ["isPalette"],
|
|
131
|
-
"isPopover": ["url"],
|
|
132
|
-
"popoverRect": ["isPopover"],
|
|
133
|
-
"badgeVariant": ["isBadge"]
|
|
134
|
-
}
|
|
193
|
+
"additionalProperties": false
|
|
135
194
|
}
|
|
136
195
|
},
|
|
137
196
|
"title": "Sidekick Config",
|
|
138
197
|
"type": "object",
|
|
139
198
|
"properties": {
|
|
199
|
+
"editUrlLabel": {
|
|
200
|
+
"type": "string",
|
|
201
|
+
"description": "The label of the custom editing environment."
|
|
202
|
+
},
|
|
203
|
+
"editUrlPattern": {
|
|
204
|
+
"type": "string",
|
|
205
|
+
"description": "The URL pattern for the custom editing environment. Supports placeholders like {{contentSourceUrl}} or {{pathname}}."
|
|
206
|
+
},
|
|
207
|
+
"host": {
|
|
208
|
+
"type": "string",
|
|
209
|
+
"format": "hostname",
|
|
210
|
+
"description": "The host name of the production website (overrides cdn.prod.host)"
|
|
211
|
+
},
|
|
212
|
+
"liveHost": {
|
|
213
|
+
"type": "string",
|
|
214
|
+
"format": "hostname",
|
|
215
|
+
"description": "The host name of the live environment (overrides cdn.live.host, defaults to *.aem.live)"
|
|
216
|
+
},
|
|
140
217
|
"plugins": {
|
|
141
218
|
"type": "array",
|
|
142
219
|
"items": {
|
|
143
220
|
"$ref": "#/definitions/sidekickPlugin"
|
|
144
221
|
}
|
|
222
|
+
},
|
|
223
|
+
"previewHost": {
|
|
224
|
+
"type": "string",
|
|
225
|
+
"format": "hostname",
|
|
226
|
+
"description": "The host name of the preview environment (overrides cdn.preview.host, defaults to *.aem.page)"
|
|
227
|
+
},
|
|
228
|
+
"project": {
|
|
229
|
+
"type": "string",
|
|
230
|
+
"description": "The name of the project to display in the sidekick"
|
|
231
|
+
},
|
|
232
|
+
"reviewHost": {
|
|
233
|
+
"type": "string",
|
|
234
|
+
"format": "hostname",
|
|
235
|
+
"description": "The host name of the review environment (overrides cdn.review.host, defaults to *.aem.reviews)"
|
|
236
|
+
},
|
|
237
|
+
"specialViews": {
|
|
238
|
+
"type": "array",
|
|
239
|
+
"items": {
|
|
240
|
+
"$ref": "#/definitions/sidekickSpecialView"
|
|
241
|
+
}
|
|
145
242
|
}
|
|
146
|
-
}
|
|
147
|
-
|
|
243
|
+
},
|
|
244
|
+
"additionalProperties": false
|
|
245
|
+
}
|
package/validate-json-schemas.sh
CHANGED
|
@@ -4,6 +4,7 @@ npx ajv-cli --spec=draft2019 -c ajv-formats compile \
|
|
|
4
4
|
-s src/schemas/access-admin.schema.json \
|
|
5
5
|
-s src/schemas/access-site.schema.json \
|
|
6
6
|
-s src/schemas/access.schema.json \
|
|
7
|
+
-s src/schemas/apikeys.schema.json \
|
|
7
8
|
-s src/schemas/cdn-prod-akamai.schema.json \
|
|
8
9
|
-s src/schemas/cdn-prod-cloudflare.schema.json \
|
|
9
10
|
-s src/schemas/cdn-prod-cloudfront.schema.json \
|