@ctcstack/ctcdocs-core 0.5.1 → 0.6.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.
|
@@ -100,6 +100,15 @@ export interface NavigationConfiguration {
|
|
|
100
100
|
* slugs are reserved either way, so turning this on or off moves no address.
|
|
101
101
|
*/
|
|
102
102
|
readonly sectionIndexPages: boolean;
|
|
103
|
+
/**
|
|
104
|
+
* The Unicode scripts a letter in a Drive name may belong to, such as
|
|
105
|
+
* `["Latin"]`, or `null` when any script is accepted. A name becomes a
|
|
106
|
+
* heading, a sidebar label and, once, a permanent address, so a deployment
|
|
107
|
+
* whose editors write in one alphabet can refuse a letter typed on the other
|
|
108
|
+
* keyboard layout before it reaches any of them. Whatever this allows, a
|
|
109
|
+
* single word never mixes Latin, Cyrillic and Greek letters (ADR-020).
|
|
110
|
+
*/
|
|
111
|
+
readonly nameScripts: readonly string[] | null;
|
|
103
112
|
}
|
|
104
113
|
export interface SiteConfiguration {
|
|
105
114
|
readonly brand: BrandConfiguration;
|
|
@@ -89,6 +89,36 @@ function flag(source, key, path) {
|
|
|
89
89
|
function optionalFlag(source, key, path, fallback) {
|
|
90
90
|
return source[key] === undefined ? fallback : flag(source, key, path);
|
|
91
91
|
}
|
|
92
|
+
/**
|
|
93
|
+
* A list of distinct Unicode script names, as a `\p{Script=…}` property
|
|
94
|
+
* escape spells them. Each name is proved by compiling that escape, so a typo
|
|
95
|
+
* fails here rather than letting every letter through, or none.
|
|
96
|
+
*/
|
|
97
|
+
function optionalScriptList(source, key, path) {
|
|
98
|
+
const value = source[key];
|
|
99
|
+
if (value === undefined) {
|
|
100
|
+
return null;
|
|
101
|
+
}
|
|
102
|
+
if (!Array.isArray(value) || value.length === 0) {
|
|
103
|
+
fail(path, 'must be a non-empty array of Unicode script names');
|
|
104
|
+
}
|
|
105
|
+
const scripts = value.map((entry, index) => {
|
|
106
|
+
if (typeof entry !== 'string' || !/^[A-Za-z_]+$/u.test(entry)) {
|
|
107
|
+
fail(`${path}[${index}]`, 'must be a Unicode script name such as "Latin"');
|
|
108
|
+
}
|
|
109
|
+
try {
|
|
110
|
+
new RegExp(`\\p{Script=${entry}}`, 'u');
|
|
111
|
+
}
|
|
112
|
+
catch {
|
|
113
|
+
fail(`${path}[${index}]`, 'must be a Unicode script name such as "Latin"');
|
|
114
|
+
}
|
|
115
|
+
return entry;
|
|
116
|
+
});
|
|
117
|
+
if (new Set(scripts).size !== scripts.length) {
|
|
118
|
+
fail(path, 'must not repeat a script');
|
|
119
|
+
}
|
|
120
|
+
return Object.freeze(scripts);
|
|
121
|
+
}
|
|
92
122
|
/**
|
|
93
123
|
* A count of things shown on a page. Zero is rejected along with fractions and
|
|
94
124
|
* negatives: a block configured to show nothing is hidden by the switch that
|
|
@@ -190,6 +220,7 @@ export function parseSiteConfiguration(input) {
|
|
|
190
220
|
navigation: {
|
|
191
221
|
landingDocumentTitles: titleList(navigationSource, 'landingDocumentTitles', 'navigation.landingDocumentTitles'),
|
|
192
222
|
sectionIndexPages: flag(navigationSource, 'sectionIndexPages', 'navigation.sectionIndexPages'),
|
|
223
|
+
nameScripts: optionalScriptList(navigationSource, 'nameScripts', 'navigation.nameScripts'),
|
|
193
224
|
},
|
|
194
225
|
sync: {
|
|
195
226
|
commitBotName: text(syncSource, 'commitBotName', 'sync.commitBotName'),
|
package/package.json
CHANGED
|
@@ -125,6 +125,15 @@ export interface NavigationConfiguration {
|
|
|
125
125
|
* slugs are reserved either way, so turning this on or off moves no address.
|
|
126
126
|
*/
|
|
127
127
|
readonly sectionIndexPages: boolean;
|
|
128
|
+
/**
|
|
129
|
+
* The Unicode scripts a letter in a Drive name may belong to, such as
|
|
130
|
+
* `["Latin"]`, or `null` when any script is accepted. A name becomes a
|
|
131
|
+
* heading, a sidebar label and, once, a permanent address, so a deployment
|
|
132
|
+
* whose editors write in one alphabet can refuse a letter typed on the other
|
|
133
|
+
* keyboard layout before it reaches any of them. Whatever this allows, a
|
|
134
|
+
* single word never mixes Latin, Cyrillic and Greek letters (ADR-020).
|
|
135
|
+
*/
|
|
136
|
+
readonly nameScripts: readonly string[] | null;
|
|
128
137
|
}
|
|
129
138
|
|
|
130
139
|
export interface SiteConfiguration {
|
|
@@ -242,6 +251,46 @@ function optionalFlag(
|
|
|
242
251
|
return source[key] === undefined ? fallback : flag(source, key, path);
|
|
243
252
|
}
|
|
244
253
|
|
|
254
|
+
/**
|
|
255
|
+
* A list of distinct Unicode script names, as a `\p{Script=…}` property
|
|
256
|
+
* escape spells them. Each name is proved by compiling that escape, so a typo
|
|
257
|
+
* fails here rather than letting every letter through, or none.
|
|
258
|
+
*/
|
|
259
|
+
function optionalScriptList(
|
|
260
|
+
source: Record<string, unknown>,
|
|
261
|
+
key: string,
|
|
262
|
+
path: string,
|
|
263
|
+
): readonly string[] | null {
|
|
264
|
+
const value = source[key];
|
|
265
|
+
if (value === undefined) {
|
|
266
|
+
return null;
|
|
267
|
+
}
|
|
268
|
+
if (!Array.isArray(value) || value.length === 0) {
|
|
269
|
+
fail(path, 'must be a non-empty array of Unicode script names');
|
|
270
|
+
}
|
|
271
|
+
const scripts = value.map((entry, index) => {
|
|
272
|
+
if (typeof entry !== 'string' || !/^[A-Za-z_]+$/u.test(entry)) {
|
|
273
|
+
fail(
|
|
274
|
+
`${path}[${index}]`,
|
|
275
|
+
'must be a Unicode script name such as "Latin"',
|
|
276
|
+
);
|
|
277
|
+
}
|
|
278
|
+
try {
|
|
279
|
+
new RegExp(`\\p{Script=${entry}}`, 'u');
|
|
280
|
+
} catch {
|
|
281
|
+
fail(
|
|
282
|
+
`${path}[${index}]`,
|
|
283
|
+
'must be a Unicode script name such as "Latin"',
|
|
284
|
+
);
|
|
285
|
+
}
|
|
286
|
+
return entry;
|
|
287
|
+
});
|
|
288
|
+
if (new Set(scripts).size !== scripts.length) {
|
|
289
|
+
fail(path, 'must not repeat a script');
|
|
290
|
+
}
|
|
291
|
+
return Object.freeze(scripts);
|
|
292
|
+
}
|
|
293
|
+
|
|
245
294
|
/**
|
|
246
295
|
* A count of things shown on a page. Zero is rejected along with fractions and
|
|
247
296
|
* negatives: a block configured to show nothing is hidden by the switch that
|
|
@@ -396,6 +445,11 @@ export function parseSiteConfiguration(input: unknown): SiteConfiguration {
|
|
|
396
445
|
'sectionIndexPages',
|
|
397
446
|
'navigation.sectionIndexPages',
|
|
398
447
|
),
|
|
448
|
+
nameScripts: optionalScriptList(
|
|
449
|
+
navigationSource,
|
|
450
|
+
'nameScripts',
|
|
451
|
+
'navigation.nameScripts',
|
|
452
|
+
),
|
|
399
453
|
},
|
|
400
454
|
sync: {
|
|
401
455
|
commitBotName: text(syncSource, 'commitBotName', 'sync.commitBotName'),
|