textbrowser 0.49.1 → 0.51.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/.ncurc.cjs +3 -0
- package/CHANGES.md +14 -0
- package/dist/WorkInfo-es.js +262 -13
- package/dist/activateCallback-es.js +72 -10
- package/dist/dist/WorkInfo-es.d.ts +331 -0
- package/dist/dist/WorkInfo-es.d.ts.map +1 -0
- package/dist/dist/activateCallback-es.d.ts +17 -0
- package/dist/dist/activateCallback-es.d.ts.map +1 -0
- package/dist/dist/index-es.d.ts +619 -0
- package/dist/dist/index-es.d.ts.map +1 -0
- package/dist/dist/sw-helper.d.ts +3 -0
- package/dist/dist/sw-helper.d.ts.map +1 -0
- package/dist/eslint.config.d.ts +126 -0
- package/dist/eslint.config.d.ts.map +1 -0
- package/dist/index-es.js +860 -134
- package/dist/index-es.min.js +2 -2
- package/dist/resources/activateCallback.d.ts +23 -0
- package/dist/resources/activateCallback.d.ts.map +1 -0
- package/dist/resources/index.d.ts +128 -0
- package/dist/resources/index.d.ts.map +1 -0
- package/dist/resources/resultsDisplay.d.ts +110 -0
- package/dist/resources/resultsDisplay.d.ts.map +1 -0
- package/dist/resources/templates/index.d.ts +59 -0
- package/dist/resources/templates/index.d.ts.map +1 -0
- package/dist/resources/templates/languageSelect.d.ts +18 -0
- package/dist/resources/templates/languageSelect.d.ts.map +1 -0
- package/dist/resources/templates/resultsDisplayClient.d.ts +26 -0
- package/dist/resources/templates/resultsDisplayClient.d.ts.map +1 -0
- package/dist/resources/templates/resultsDisplayServerOrClient.d.ts +131 -0
- package/dist/resources/templates/resultsDisplayServerOrClient.d.ts.map +1 -0
- package/dist/resources/templates/utils/dom.d.ts +15 -0
- package/dist/resources/templates/utils/dom.d.ts.map +1 -0
- package/dist/resources/templates/utils/html.d.ts +3 -0
- package/dist/resources/templates/utils/html.d.ts.map +1 -0
- package/dist/resources/templates/workDisplay.d.ts +183 -0
- package/dist/resources/templates/workDisplay.d.ts.map +1 -0
- package/dist/resources/templates/workSelect.d.ts +18 -0
- package/dist/resources/templates/workSelect.d.ts.map +1 -0
- package/dist/resources/user-sample.d.ts +2 -0
- package/dist/resources/user-sample.d.ts.map +1 -0
- package/dist/resources/user.d.ts +2 -0
- package/dist/resources/user.d.ts.map +1 -0
- package/dist/resources/utils/IntlURLSearchParams.d.ts +56 -0
- package/dist/resources/utils/IntlURLSearchParams.d.ts.map +1 -0
- package/dist/resources/utils/Languages.d.ts +81 -0
- package/dist/resources/utils/Languages.d.ts.map +1 -0
- package/dist/resources/utils/Metadata.d.ts +133 -0
- package/dist/resources/utils/Metadata.d.ts.map +1 -0
- package/dist/resources/utils/Params.d.ts +30 -0
- package/dist/resources/utils/Params.d.ts.map +1 -0
- package/dist/resources/utils/Plugin.d.ts +274 -0
- package/dist/resources/utils/Plugin.d.ts.map +1 -0
- package/dist/resources/utils/ServiceWorker.d.ts +26 -0
- package/dist/resources/utils/ServiceWorker.d.ts.map +1 -0
- package/dist/resources/utils/WorkInfo.d.ts +104 -0
- package/dist/resources/utils/WorkInfo.d.ts.map +1 -0
- package/dist/resources/utils/dialogs.d.ts +155 -0
- package/dist/resources/utils/dialogs.d.ts.map +1 -0
- package/dist/resources/utils/getLocaleFallbackResults.d.ts +19 -0
- package/dist/resources/utils/getLocaleFallbackResults.d.ts.map +1 -0
- package/dist/resources/utils/sanitize.d.ts +6 -0
- package/dist/resources/utils/sanitize.d.ts.map +1 -0
- package/dist/resources/vendor/json-refs-min.d.ts +3 -0
- package/dist/resources/vendor/json-refs-min.d.ts.map +1 -0
- package/dist/resources/workDisplay.d.ts +81 -0
- package/dist/resources/workDisplay.d.ts.map +1 -0
- package/dist/resources/workSelect.d.ts +17 -0
- package/dist/resources/workSelect.d.ts.map +1 -0
- package/dist/rollup.config.d.ts +19 -0
- package/dist/rollup.config.d.ts.map +1 -0
- package/dist/server/main.d.ts +46 -0
- package/dist/server/main.d.ts.map +1 -0
- package/dist/sw-helper.d.ts +3 -0
- package/dist/sw-helper.d.ts.map +1 -0
- package/dist/sw-helper.js +52 -12
- package/dist/sw-sample.d.ts +2 -0
- package/dist/sw-sample.d.ts.map +1 -0
- package/general-schemas/files.jsonschema +6 -0
- package/package.json +22 -9
- package/resources/activateCallback.js +75 -10
- package/resources/index.js +161 -49
- package/resources/resultsDisplay.js +517 -152
- package/resources/templates/index.js +39 -16
- package/resources/templates/languageSelect.js +14 -1
- package/resources/templates/resultsDisplayClient.js +22 -3
- package/resources/templates/resultsDisplayServerOrClient.js +188 -49
- package/resources/templates/utils/dom.js +13 -2
- package/resources/templates/workDisplay.js +299 -75
- package/resources/templates/workSelect.js +16 -3
- package/resources/utils/IntlURLSearchParams.js +46 -4
- package/resources/utils/Languages.js +71 -4
- package/resources/utils/Metadata.js +219 -22
- package/resources/utils/Params.js +70 -23
- package/resources/utils/Plugin.js +169 -1
- package/resources/utils/ServiceWorker.js +48 -19
- package/resources/utils/WorkInfo.js +255 -43
- package/resources/utils/dialogs.js +105 -7
- package/resources/utils/getLocaleFallbackResults.js +12 -2
- package/resources/utils/sanitize.js +4 -0
- package/resources/workDisplay.js +151 -25
- package/resources/workSelect.js +37 -17
- package/server/main.js +111 -19
- package/tsconfig.json +30 -0
- package/resources/user.js +0 -20
|
@@ -1,6 +1,17 @@
|
|
|
1
1
|
import {jml, $} from 'jamilih';
|
|
2
|
+
|
|
3
|
+
// @ts-expect-error -- Missing TS
|
|
2
4
|
import {deserialize as formDeserialize} from 'form-serialization';
|
|
3
5
|
|
|
6
|
+
/**
|
|
7
|
+
* @param {{
|
|
8
|
+
* groups: import('../utils/WorkInfo.js').FileGroup[]
|
|
9
|
+
* workI18n: import('intl-dom').I18NCallback
|
|
10
|
+
* getNextAlias: () => string|string[]|import('../../server/main.js').LocalizationStrings
|
|
11
|
+
* $p: import('../utils/IntlURLSearchParams.js').default
|
|
12
|
+
* followParams: (formSelector: string, cb: () => void) => void
|
|
13
|
+
* }} cfg
|
|
14
|
+
*/
|
|
4
15
|
const workSelect = function ({groups, workI18n, getNextAlias, $p, followParams}) {
|
|
5
16
|
const form = jml(
|
|
6
17
|
'form',
|
|
@@ -10,7 +21,7 @@ const workSelect = function ({groups, workI18n, getNextAlias, $p, followParams})
|
|
|
10
21
|
}
|
|
11
22
|
}},
|
|
12
23
|
groups.map((group, i) => {
|
|
13
|
-
return ['div', [
|
|
24
|
+
return /** @type {import('jamilih').JamilihArray} */ (['div', [
|
|
14
25
|
i > 0 ? ['br', 'br', 'br'] : '',
|
|
15
26
|
['div', [
|
|
16
27
|
workI18n(group.directions.localeKey)
|
|
@@ -23,7 +34,9 @@ const workSelect = function ({groups, workI18n, getNextAlias, $p, followParams})
|
|
|
23
34
|
name: group.name.localeKey
|
|
24
35
|
},
|
|
25
36
|
$on: {
|
|
26
|
-
change (
|
|
37
|
+
change (e) {
|
|
38
|
+
// eslint-disable-next-line prefer-destructuring -- TS
|
|
39
|
+
const value = /** @type {HTMLSelectElement} */ (e.target).value;
|
|
27
40
|
/*
|
|
28
41
|
// If using click, but click doesn't always fire
|
|
29
42
|
if (e.target.nodeName.toLowerCase() === 'select') {
|
|
@@ -45,7 +58,7 @@ const workSelect = function ({groups, workI18n, getNextAlias, $p, followParams})
|
|
|
45
58
|
]]
|
|
46
59
|
// Todo: Add in Go button (with 'submitgo' localization string) to
|
|
47
60
|
// avoid need for pull-down if using first selection?
|
|
48
|
-
]];
|
|
61
|
+
]]);
|
|
49
62
|
}),
|
|
50
63
|
$('#main')
|
|
51
64
|
);
|
|
@@ -2,10 +2,10 @@
|
|
|
2
2
|
* @file Note that this should be kept as a polyglot client-server file.
|
|
3
3
|
*/
|
|
4
4
|
/**
|
|
5
|
-
*
|
|
6
|
-
* @param {string} param
|
|
7
|
-
* @param {boolean} skip
|
|
8
5
|
* @this {IntlURLSearchParams}
|
|
6
|
+
* @param {string} param
|
|
7
|
+
* @param {boolean} [skip]
|
|
8
|
+
* @throws {Error}
|
|
9
9
|
* @returns {string}
|
|
10
10
|
*/
|
|
11
11
|
function _prepareParam (param, skip) {
|
|
@@ -16,39 +16,81 @@ function _prepareParam (param, skip) {
|
|
|
16
16
|
// start, end, toggle
|
|
17
17
|
const endNums = /\d+(-\d+)?$/;
|
|
18
18
|
const indexed = param.match(endNums);
|
|
19
|
+
if (!this.l10n) {
|
|
20
|
+
throw new Error('l10n is not defined');
|
|
21
|
+
}
|
|
19
22
|
if (indexed) {
|
|
20
23
|
// Todo: We could i18nize numbers as well
|
|
21
24
|
return this.l10n(['params', 'indexed', param.replace(endNums, '')]) + indexed[0];
|
|
22
25
|
}
|
|
23
|
-
return this.l10n(['params', param]);
|
|
26
|
+
return /** @type {string} */ (this.l10n(['params', param]));
|
|
24
27
|
}
|
|
25
28
|
|
|
26
29
|
class IntlURLSearchParams {
|
|
30
|
+
/**
|
|
31
|
+
* @param {object} [options]
|
|
32
|
+
* @param {import('intl-dom').I18NCallback} [options.l10n]
|
|
33
|
+
* @param {URLSearchParams|string} [options.params]
|
|
34
|
+
*/
|
|
27
35
|
constructor ({l10n, params} = {}) {
|
|
28
36
|
this.l10n = l10n;
|
|
37
|
+
this.localizeParamNames = false;
|
|
29
38
|
if (!params) {
|
|
30
39
|
params = location.hash.slice(1);
|
|
31
40
|
}
|
|
32
41
|
if (typeof params === 'string') {
|
|
33
42
|
params = new URLSearchParams(params);
|
|
34
43
|
}
|
|
44
|
+
/** @type {URLSearchParams} */
|
|
35
45
|
this.params = params;
|
|
36
46
|
}
|
|
47
|
+
/**
|
|
48
|
+
* @param {string} param
|
|
49
|
+
* @param {boolean} [skip]
|
|
50
|
+
* @returns {string|null}
|
|
51
|
+
*/
|
|
37
52
|
get (param, skip) {
|
|
38
53
|
return this.params.get(_prepareParam.call(this, param, skip));
|
|
39
54
|
}
|
|
55
|
+
/**
|
|
56
|
+
* @param {string} param
|
|
57
|
+
* @param {boolean} skip
|
|
58
|
+
* @returns {string[]}
|
|
59
|
+
*/
|
|
40
60
|
getAll (param, skip) {
|
|
41
61
|
return this.params.getAll(_prepareParam.call(this, param, skip));
|
|
42
62
|
}
|
|
63
|
+
/**
|
|
64
|
+
* @param {string} param
|
|
65
|
+
* @param {boolean} [skip]
|
|
66
|
+
* @returns {boolean}
|
|
67
|
+
*/
|
|
43
68
|
has (param, skip) {
|
|
44
69
|
return this.params.has(_prepareParam.call(this, param, skip));
|
|
45
70
|
}
|
|
71
|
+
/**
|
|
72
|
+
* @param {string} param
|
|
73
|
+
* @param {boolean} skip
|
|
74
|
+
* @returns {void}
|
|
75
|
+
*/
|
|
46
76
|
delete (param, skip) {
|
|
47
77
|
return this.params.delete(_prepareParam.call(this, param, skip));
|
|
48
78
|
}
|
|
79
|
+
/**
|
|
80
|
+
* @param {string} param
|
|
81
|
+
* @param {string} value
|
|
82
|
+
* @param {boolean} [skip]
|
|
83
|
+
* @returns {void}
|
|
84
|
+
*/
|
|
49
85
|
set (param, value, skip) {
|
|
50
86
|
return this.params.set(_prepareParam.call(this, param, skip), value);
|
|
51
87
|
}
|
|
88
|
+
/**
|
|
89
|
+
* @param {string} param
|
|
90
|
+
* @param {string} value
|
|
91
|
+
* @param {boolean} skip
|
|
92
|
+
* @returns {void}
|
|
93
|
+
*/
|
|
52
94
|
append (param, value, skip) {
|
|
53
95
|
return this.params.append(_prepareParam.call(this, param, skip), value);
|
|
54
96
|
}
|
|
@@ -1,10 +1,21 @@
|
|
|
1
1
|
// Todo: remember this locales choice by cookie?
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* @param {{
|
|
5
|
+
* namespace: string,
|
|
6
|
+
* preferredLocale: string
|
|
7
|
+
* }} cfg
|
|
8
|
+
*/
|
|
2
9
|
export const getPreferredLanguages = ({namespace, preferredLocale}) => {
|
|
3
10
|
// Todo: Add to this optionally with one-off tag input box
|
|
4
11
|
// Todo: Switch to fallbackLanguages so can default to
|
|
5
12
|
// navigator.languages?
|
|
6
13
|
const langCodes = localStorage.getItem(namespace + '-langCodes');
|
|
7
|
-
const lngs =
|
|
14
|
+
const lngs = /** @type {string[]} */ (
|
|
15
|
+
(langCodes && JSON.parse(langCodes)) || [preferredLocale]
|
|
16
|
+
);
|
|
17
|
+
|
|
18
|
+
/** @type {string[]} */
|
|
8
19
|
const langArr = [];
|
|
9
20
|
lngs.forEach((lng) => {
|
|
10
21
|
// Todo: Check for multiple separate hyphenated
|
|
@@ -23,23 +34,66 @@ export const getPreferredLanguages = ({namespace, preferredLocale}) => {
|
|
|
23
34
|
* @classdesc Note that this should be kept as a polyglot client-server class.
|
|
24
35
|
*/
|
|
25
36
|
export class Languages {
|
|
37
|
+
/**
|
|
38
|
+
* @param {{
|
|
39
|
+
* langData: import('../../server/main.js').LanguagesData
|
|
40
|
+
* }} cfg
|
|
41
|
+
*/
|
|
26
42
|
constructor ({langData}) {
|
|
27
43
|
this.langData = langData;
|
|
28
44
|
}
|
|
45
|
+
/**
|
|
46
|
+
* @param {string} langCode
|
|
47
|
+
* @returns {{
|
|
48
|
+
* languages: {
|
|
49
|
+
* [key: string]: string
|
|
50
|
+
* }
|
|
51
|
+
* }}
|
|
52
|
+
*/
|
|
29
53
|
localeFromLangData (langCode) {
|
|
30
|
-
return
|
|
54
|
+
return (
|
|
55
|
+
/**
|
|
56
|
+
* @type {{
|
|
57
|
+
* languages: {
|
|
58
|
+
* [key: string]: string
|
|
59
|
+
* }
|
|
60
|
+
* }}
|
|
61
|
+
*/ (
|
|
62
|
+
this.langData['localization-strings'][langCode]
|
|
63
|
+
)
|
|
64
|
+
);
|
|
31
65
|
}
|
|
66
|
+
/**
|
|
67
|
+
* @param {string} code
|
|
68
|
+
* @returns {string}
|
|
69
|
+
*/
|
|
32
70
|
getLanguageFromCode (code) {
|
|
33
71
|
return this.localeFromLangData(code).languages[code];
|
|
34
72
|
// Could add something like this in place or as fallback, though need to pass in locale
|
|
35
73
|
// || new Intl.DisplayNames([locale], {type: 'language'}).of(code);
|
|
36
74
|
}
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
* @param {{
|
|
78
|
+
* pluginName: string,
|
|
79
|
+
* workI18n: import('intl-dom').I18NCallback,
|
|
80
|
+
* targetLanguage: string,
|
|
81
|
+
* applicableFieldI18N: string|string[],
|
|
82
|
+
* meta: {
|
|
83
|
+
* [key: string]: string
|
|
84
|
+
* },
|
|
85
|
+
* metaApplicableField: {
|
|
86
|
+
* [key: string]: string
|
|
87
|
+
* },
|
|
88
|
+
* }} cfg
|
|
89
|
+
* @returns {string}
|
|
90
|
+
*/
|
|
37
91
|
getFieldNameFromPluginNameAndLocales ({
|
|
38
92
|
pluginName,
|
|
39
93
|
// locales,
|
|
40
94
|
workI18n, targetLanguage, applicableFieldI18N, meta, metaApplicableField
|
|
41
95
|
}) {
|
|
42
|
-
return workI18n(['plugins', pluginName, 'fieldname'], {
|
|
96
|
+
return /** @type {string} */ (workI18n(['plugins', pluginName, 'fieldname'], {
|
|
43
97
|
...meta,
|
|
44
98
|
...metaApplicableField,
|
|
45
99
|
applicableField: applicableFieldI18N,
|
|
@@ -49,10 +103,23 @@ export class Languages {
|
|
|
49
103
|
}, {
|
|
50
104
|
// We provide more than may be desired by the plugin
|
|
51
105
|
throwOnExtraSuppliedFormatters: false
|
|
52
|
-
});
|
|
106
|
+
}));
|
|
53
107
|
}
|
|
108
|
+
|
|
109
|
+
/**
|
|
110
|
+
* @param {{$p: import('./IntlURLSearchParams.js').default}} cfg
|
|
111
|
+
* @returns {{
|
|
112
|
+
* lang: string[],
|
|
113
|
+
* langs: import('../../server/main.js').LanguageInfo[],
|
|
114
|
+
* languageParam: string|null,
|
|
115
|
+
* fallbackLanguages: string[]
|
|
116
|
+
* }}
|
|
117
|
+
*/
|
|
54
118
|
getLanguageInfo ({$p}) {
|
|
55
119
|
const langs = this.langData.languages;
|
|
120
|
+
/**
|
|
121
|
+
* @param {string} lcl
|
|
122
|
+
*/
|
|
56
123
|
const localePass = (lcl) => {
|
|
57
124
|
return langs.some(({code}) => code === lcl) ? lcl : false;
|
|
58
125
|
};
|
|
@@ -6,14 +6,53 @@ const getCurrDir = () => {
|
|
|
6
6
|
return window.location.href.replace(/(index\.html)?#.*$/, '');
|
|
7
7
|
};
|
|
8
8
|
|
|
9
|
+
/**
|
|
10
|
+
* @typedef {{
|
|
11
|
+
* [key: string]: string|Integer|(string|Integer)[]|{
|
|
12
|
+
* [key: string]: string|Integer
|
|
13
|
+
* }
|
|
14
|
+
* }} FieldValueAliases
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* @typedef {{
|
|
19
|
+
* "localization-strings": import('../../server/main.js').LocalizationStrings
|
|
20
|
+
* table: {browse_fields: (string|{
|
|
21
|
+
* name?: string,
|
|
22
|
+
* set: string[],
|
|
23
|
+
* presort?: boolean
|
|
24
|
+
* })[]}
|
|
25
|
+
* fields: {
|
|
26
|
+
* [key: string]: {
|
|
27
|
+
* prefer_alias: boolean|string,
|
|
28
|
+
* name: string|{localeKey: string},
|
|
29
|
+
* alias: string|{localeKey: string},
|
|
30
|
+
* lang: string,
|
|
31
|
+
* 'fieldvalue-aliases': FieldValueAliases
|
|
32
|
+
* }
|
|
33
|
+
* }
|
|
34
|
+
* }} MetadataObj
|
|
35
|
+
*/
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* @param {string[]} lang
|
|
39
|
+
* @param {MetadataObj} metadataObj
|
|
40
|
+
* @param {string|string[]} properties
|
|
41
|
+
* @param {boolean} [allowObjects]
|
|
42
|
+
* @returns {string|string[]|import('../../server/main.js').LocalizationStrings}
|
|
43
|
+
*/
|
|
9
44
|
export const getMetaProp = function getMetaProp (lang, metadataObj, properties, allowObjects) {
|
|
10
45
|
let prop;
|
|
11
46
|
properties = typeof properties === 'string' ? [properties] : properties;
|
|
12
|
-
|
|
47
|
+
for (const lan of lang) {
|
|
13
48
|
const p = [...properties];
|
|
14
|
-
let strings =
|
|
49
|
+
let strings = /** @type {string|string[]|import('../../server/main.js').LocalizationStrings} */ (
|
|
50
|
+
metadataObj['localization-strings'][lan]
|
|
51
|
+
);
|
|
15
52
|
while (strings && p.length) {
|
|
16
|
-
strings =
|
|
53
|
+
strings = /** @type {import('../../server/main.js').LocalizationStrings} */ (
|
|
54
|
+
strings
|
|
55
|
+
)[/** @type {string} */ (p.shift())];
|
|
17
56
|
}
|
|
18
57
|
// Todo: Fix this allowance for allowObjects (as it does not properly
|
|
19
58
|
// fallback if an object is returned from a language because
|
|
@@ -22,9 +61,13 @@ export const getMetaProp = function getMetaProp (lang, metadataObj, properties,
|
|
|
22
61
|
prop = (allowObjects || typeof strings === 'string')
|
|
23
62
|
? strings
|
|
24
63
|
: undefined;
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
64
|
+
if (prop) {
|
|
65
|
+
break;
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
return /** @type {string|string[]|import('../../server/main.js').LocalizationStrings} */ (
|
|
69
|
+
prop
|
|
70
|
+
);
|
|
28
71
|
};
|
|
29
72
|
|
|
30
73
|
// Use the following to dynamically add specific file schema in place of
|
|
@@ -32,17 +75,43 @@ export const getMetaProp = function getMetaProp (lang, metadataObj, properties,
|
|
|
32
75
|
// filesSchema.properties.groups.items.properties.files.items.properties.
|
|
33
76
|
// file.anyOf.splice(1, 1, {$ref: schemaFile});
|
|
34
77
|
// Todo: Allow use of dbs and fileGroup together in base directories?
|
|
78
|
+
|
|
79
|
+
/**
|
|
80
|
+
* @typedef {{
|
|
81
|
+
* items: {
|
|
82
|
+
* items: {
|
|
83
|
+
* title: string,
|
|
84
|
+
* type: string
|
|
85
|
+
* format?: string
|
|
86
|
+
* }[]
|
|
87
|
+
* }
|
|
88
|
+
* }} SchemaObj
|
|
89
|
+
*/
|
|
90
|
+
|
|
91
|
+
/**
|
|
92
|
+
* @param {string} file
|
|
93
|
+
* @param {string} property
|
|
94
|
+
* @param {string} [basePath]
|
|
95
|
+
* @returns {Promise<MetadataObj|SchemaObj>}
|
|
96
|
+
*/
|
|
35
97
|
export const getMetadata = async (file, property, basePath) => {
|
|
36
98
|
const url = new URL(basePath || getCurrDir());
|
|
37
99
|
url.search = ''; // Clear out query string, e.g., `?fbclid` from Facebook
|
|
38
100
|
url.pathname = file;
|
|
39
101
|
url.hash = property ? '#/' + property : '';
|
|
40
102
|
|
|
41
|
-
return (await JsonRefs.
|
|
103
|
+
return /** @type {MetadataObj} */ ((await JsonRefs.
|
|
42
104
|
resolveRefsAt(
|
|
43
105
|
url.toString(),
|
|
44
106
|
{
|
|
45
107
|
loaderOptions: {
|
|
108
|
+
/**
|
|
109
|
+
* @param {{
|
|
110
|
+
* text: string,
|
|
111
|
+
* body: any
|
|
112
|
+
* }} res
|
|
113
|
+
* @param {(err?: Error, cbValue: any) => void} callback
|
|
114
|
+
*/
|
|
46
115
|
processContent (res, callback) {
|
|
47
116
|
callback(undefined, JSON.parse(
|
|
48
117
|
res.text ||
|
|
@@ -53,9 +122,39 @@ export const getMetadata = async (file, property, basePath) => {
|
|
|
53
122
|
}
|
|
54
123
|
}
|
|
55
124
|
}
|
|
56
|
-
)).resolved;
|
|
125
|
+
)).resolved);
|
|
57
126
|
};
|
|
58
127
|
|
|
128
|
+
/**
|
|
129
|
+
* @typedef {{
|
|
130
|
+
* field: string,
|
|
131
|
+
* schemaItems: {
|
|
132
|
+
* title: string,
|
|
133
|
+
* type: string,
|
|
134
|
+
* enum?: string[]
|
|
135
|
+
* }[],
|
|
136
|
+
* metadataObj: MetadataObj,
|
|
137
|
+
* getFieldAliasOrName: (field: string) => string|string[]|import('../../server/main.js').LocalizationStrings,
|
|
138
|
+
* lang: string[]
|
|
139
|
+
* }} GetFieldNameAndValueAliasesOptions
|
|
140
|
+
*/
|
|
141
|
+
|
|
142
|
+
/**
|
|
143
|
+
* @param {GetFieldNameAndValueAliasesOptions} cfg
|
|
144
|
+
* @returns {{
|
|
145
|
+
* aliases: string[]|null,
|
|
146
|
+
* fieldValueAliasMap: FieldValueAliases|null,
|
|
147
|
+
* rawFieldValueAliasMap: FieldValueAliases|null,
|
|
148
|
+
* fieldName: string,
|
|
149
|
+
* fieldSchema: {
|
|
150
|
+
* title: string,
|
|
151
|
+
* type: string
|
|
152
|
+
* },
|
|
153
|
+
* fieldSchemaIndex: number,
|
|
154
|
+
* preferAlias: boolean|string,
|
|
155
|
+
* lang: string
|
|
156
|
+
* }}
|
|
157
|
+
*/
|
|
59
158
|
export const getFieldNameAndValueAliases = function ({
|
|
60
159
|
field, schemaItems, metadataObj, getFieldAliasOrName, lang
|
|
61
160
|
}) {
|
|
@@ -66,27 +165,46 @@ export const getFieldNameAndValueAliases = function ({
|
|
|
66
165
|
|
|
67
166
|
const fieldInfo = metadataObj.fields[field];
|
|
68
167
|
|
|
168
|
+
/**
|
|
169
|
+
* @type {{
|
|
170
|
+
* aliases: string[]|null,
|
|
171
|
+
* fieldValueAliasMap: FieldValueAliases|null,
|
|
172
|
+
* rawFieldValueAliasMap: FieldValueAliases|null,
|
|
173
|
+
* fieldName: string,
|
|
174
|
+
* fieldSchema: {
|
|
175
|
+
* title: string,
|
|
176
|
+
* type: string
|
|
177
|
+
* },
|
|
178
|
+
* fieldSchemaIndex: number,
|
|
179
|
+
* preferAlias: boolean|string,
|
|
180
|
+
* lang: string
|
|
181
|
+
* }}
|
|
182
|
+
*/
|
|
69
183
|
const ret = {
|
|
70
184
|
// field,
|
|
71
185
|
aliases: null,
|
|
72
186
|
fieldValueAliasMap: null,
|
|
73
187
|
rawFieldValueAliasMap: null,
|
|
74
|
-
fieldName: getFieldAliasOrName(field),
|
|
188
|
+
fieldName: /** @type {string} */ (getFieldAliasOrName(field)),
|
|
75
189
|
fieldSchema,
|
|
76
190
|
fieldSchemaIndex,
|
|
77
191
|
preferAlias: fieldInfo.prefer_alias,
|
|
78
192
|
lang: fieldInfo.lang
|
|
79
193
|
};
|
|
80
194
|
|
|
195
|
+
/** @type {FieldValueAliases} */
|
|
81
196
|
let fieldValueAliasMap = fieldInfo && fieldInfo['fieldvalue-aliases'];
|
|
82
197
|
|
|
83
198
|
if (fieldValueAliasMap) {
|
|
84
199
|
if (fieldValueAliasMap.localeKey) {
|
|
85
|
-
fieldValueAliasMap =
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
200
|
+
fieldValueAliasMap = /** @type {FieldValueAliases} */ (
|
|
201
|
+
getMetaProp(
|
|
202
|
+
lang,
|
|
203
|
+
metadataObj,
|
|
204
|
+
/** @type {string} */
|
|
205
|
+
(fieldValueAliasMap.localeKey).split('/'),
|
|
206
|
+
true
|
|
207
|
+
)
|
|
90
208
|
);
|
|
91
209
|
}
|
|
92
210
|
// eslint-disable-next-line unicorn/prefer-structured-clone -- Expecting JSON
|
|
@@ -96,14 +214,18 @@ export const getFieldNameAndValueAliases = function ({
|
|
|
96
214
|
// needed cases
|
|
97
215
|
if (fieldSchema.enum && fieldSchema.enum.length) {
|
|
98
216
|
fieldSchema.enum.forEach((enm) => {
|
|
99
|
-
|
|
100
|
-
|
|
217
|
+
/** @type {string[]} */
|
|
218
|
+
(ret.aliases).push(
|
|
219
|
+
/** @type {string} */ (
|
|
220
|
+
getMetaProp(lang, metadataObj, ['fieldvalue', field, enm], true)
|
|
221
|
+
)
|
|
101
222
|
);
|
|
102
223
|
if (enm in fieldValueAliasMap &&
|
|
103
224
|
// Todo: We could allow numbers here too, but crowds
|
|
104
225
|
// pull-down
|
|
105
226
|
typeof fieldValueAliasMap[enm] === 'string') {
|
|
106
|
-
|
|
227
|
+
/** @type {string[]} */
|
|
228
|
+
(ret.aliases).push(...fieldValueAliasMap[enm]);
|
|
107
229
|
}
|
|
108
230
|
});
|
|
109
231
|
} else {
|
|
@@ -114,15 +236,24 @@ export const getFieldNameAndValueAliases = function ({
|
|
|
114
236
|
// We'll preserve the numbers since probably more useful if
|
|
115
237
|
// stored with data (as opposed to enums)
|
|
116
238
|
if (!Array.isArray(aliases)) {
|
|
117
|
-
aliases =
|
|
239
|
+
aliases = /** @type {string[]} */ (
|
|
240
|
+
Object.values(/** @type {import('../../server/main.js').LocalizationStrings} */ (
|
|
241
|
+
aliases
|
|
242
|
+
))
|
|
243
|
+
);
|
|
118
244
|
}
|
|
119
245
|
// We'll assume the longest version is best for auto-complete
|
|
120
|
-
|
|
246
|
+
/** @type {string[]} */
|
|
247
|
+
(ret.aliases).push(
|
|
121
248
|
...(
|
|
122
249
|
aliases.filter((v) => {
|
|
123
250
|
return aliases.every((x) => {
|
|
124
251
|
return x === v || !(
|
|
125
|
-
|
|
252
|
+
/** @type {string} */
|
|
253
|
+
(x).toLowerCase().startsWith(
|
|
254
|
+
/** @type {string} */
|
|
255
|
+
(v).toLowerCase()
|
|
256
|
+
)
|
|
126
257
|
);
|
|
127
258
|
});
|
|
128
259
|
}).map((v) => v + ' (' + key + ')') // Todo: i18nize
|
|
@@ -131,12 +262,55 @@ export const getFieldNameAndValueAliases = function ({
|
|
|
131
262
|
});
|
|
132
263
|
}
|
|
133
264
|
// eslint-disable-next-line unicorn/prefer-structured-clone -- Expecting JSON
|
|
134
|
-
ret.fieldValueAliasMap = JSON.parse(JSON.stringify(fieldValueAliasMap));
|
|
265
|
+
ret.fieldValueAliasMap = /** @type {FieldValueAliases} */ (JSON.parse(JSON.stringify(fieldValueAliasMap)));
|
|
135
266
|
// ret.aliases.sort();
|
|
136
267
|
}
|
|
137
268
|
return ret;
|
|
138
269
|
};
|
|
139
270
|
|
|
271
|
+
/**
|
|
272
|
+
* @typedef {number} Integer
|
|
273
|
+
*/
|
|
274
|
+
|
|
275
|
+
/**
|
|
276
|
+
* @typedef {{
|
|
277
|
+
* aliases: string[]|null,
|
|
278
|
+
* fieldValueAliasMap: FieldValueAliases|null,
|
|
279
|
+
* rawFieldValueAliasMap: FieldValueAliases|null,
|
|
280
|
+
* fieldName: string,
|
|
281
|
+
* fieldSchema: {
|
|
282
|
+
* title: string,
|
|
283
|
+
* type: string,
|
|
284
|
+
* minimum?: Integer,
|
|
285
|
+
* maximum?: Integer
|
|
286
|
+
* },
|
|
287
|
+
* fieldSchemaIndex: number,
|
|
288
|
+
* preferAlias: boolean|string,
|
|
289
|
+
* lang: string
|
|
290
|
+
* }[]} BrowseFields
|
|
291
|
+
*/
|
|
292
|
+
|
|
293
|
+
/**
|
|
294
|
+
* @typedef {{
|
|
295
|
+
* metadataObj: MetadataObj,
|
|
296
|
+
* schemaItems: {
|
|
297
|
+
* title: string,
|
|
298
|
+
* type: string
|
|
299
|
+
* }[],
|
|
300
|
+
* getFieldAliasOrName: (field: string) => string|string[]|import('../../server/main.js').LocalizationStrings,
|
|
301
|
+
* lang: string[],
|
|
302
|
+
* callback: (cfg: {
|
|
303
|
+
* setName: string,
|
|
304
|
+
* browseFields: BrowseFields,
|
|
305
|
+
* i: number,
|
|
306
|
+
* presort: boolean|undefined
|
|
307
|
+
* }) => void
|
|
308
|
+
* }} GetBrowseFieldDataOptions
|
|
309
|
+
*/
|
|
310
|
+
|
|
311
|
+
/**
|
|
312
|
+
* @param {GetBrowseFieldDataOptions} cfg
|
|
313
|
+
*/
|
|
140
314
|
export const getBrowseFieldData = function ({
|
|
141
315
|
metadataObj, schemaItems, getFieldAliasOrName, lang, callback
|
|
142
316
|
}) {
|
|
@@ -167,16 +341,37 @@ export const getBrowseFieldData = function ({
|
|
|
167
341
|
|
|
168
342
|
// Todo: Incorporate other methods into this class
|
|
169
343
|
export class Metadata {
|
|
344
|
+
/**
|
|
345
|
+
* @param {{
|
|
346
|
+
* metadataObj: MetadataObj
|
|
347
|
+
* }} cfg
|
|
348
|
+
*/
|
|
170
349
|
constructor ({metadataObj}) {
|
|
171
350
|
this.metadataObj = metadataObj;
|
|
172
351
|
}
|
|
173
352
|
|
|
353
|
+
/**
|
|
354
|
+
* @param {string} field
|
|
355
|
+
* @returns {string|undefined}
|
|
356
|
+
*/
|
|
174
357
|
getFieldLang (field) {
|
|
175
358
|
const {metadataObj} = this;
|
|
176
359
|
const fields = metadataObj && metadataObj.fields;
|
|
177
360
|
return fields && fields[field] && fields[field].lang;
|
|
178
361
|
}
|
|
179
362
|
|
|
363
|
+
/**
|
|
364
|
+
* @param {{
|
|
365
|
+
* namespace: string,
|
|
366
|
+
* preferredLocale: string,
|
|
367
|
+
* schemaItems: {
|
|
368
|
+
* title: string,
|
|
369
|
+
* type: string
|
|
370
|
+
* }[],
|
|
371
|
+
* pluginsForWork: import('./Plugin.js').PluginsForWork
|
|
372
|
+
* }} cfg
|
|
373
|
+
* @returns {(field: string) => boolean}
|
|
374
|
+
*/
|
|
180
375
|
getFieldMatchesLocale ({
|
|
181
376
|
namespace, preferredLocale, schemaItems,
|
|
182
377
|
pluginsForWork
|
|
@@ -203,7 +398,9 @@ export class Metadata {
|
|
|
203
398
|
const hasFieldValue = localeStrings &&
|
|
204
399
|
Object.keys(localeStrings).some((lng) => {
|
|
205
400
|
const fv = localeStrings[lng] &&
|
|
206
|
-
|
|
401
|
+
/** @type {import('../../server/main.js').LocalizationStrings} */
|
|
402
|
+
(/** @type {import('../../server/main.js').LocalizationStrings} */
|
|
403
|
+
(localeStrings[lng]).fieldvalue);
|
|
207
404
|
return fv && fv[field];
|
|
208
405
|
});
|
|
209
406
|
|