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.
Files changed (104) hide show
  1. package/.ncurc.cjs +3 -0
  2. package/CHANGES.md +14 -0
  3. package/dist/WorkInfo-es.js +262 -13
  4. package/dist/activateCallback-es.js +72 -10
  5. package/dist/dist/WorkInfo-es.d.ts +331 -0
  6. package/dist/dist/WorkInfo-es.d.ts.map +1 -0
  7. package/dist/dist/activateCallback-es.d.ts +17 -0
  8. package/dist/dist/activateCallback-es.d.ts.map +1 -0
  9. package/dist/dist/index-es.d.ts +619 -0
  10. package/dist/dist/index-es.d.ts.map +1 -0
  11. package/dist/dist/sw-helper.d.ts +3 -0
  12. package/dist/dist/sw-helper.d.ts.map +1 -0
  13. package/dist/eslint.config.d.ts +126 -0
  14. package/dist/eslint.config.d.ts.map +1 -0
  15. package/dist/index-es.js +860 -134
  16. package/dist/index-es.min.js +2 -2
  17. package/dist/resources/activateCallback.d.ts +23 -0
  18. package/dist/resources/activateCallback.d.ts.map +1 -0
  19. package/dist/resources/index.d.ts +128 -0
  20. package/dist/resources/index.d.ts.map +1 -0
  21. package/dist/resources/resultsDisplay.d.ts +110 -0
  22. package/dist/resources/resultsDisplay.d.ts.map +1 -0
  23. package/dist/resources/templates/index.d.ts +59 -0
  24. package/dist/resources/templates/index.d.ts.map +1 -0
  25. package/dist/resources/templates/languageSelect.d.ts +18 -0
  26. package/dist/resources/templates/languageSelect.d.ts.map +1 -0
  27. package/dist/resources/templates/resultsDisplayClient.d.ts +26 -0
  28. package/dist/resources/templates/resultsDisplayClient.d.ts.map +1 -0
  29. package/dist/resources/templates/resultsDisplayServerOrClient.d.ts +131 -0
  30. package/dist/resources/templates/resultsDisplayServerOrClient.d.ts.map +1 -0
  31. package/dist/resources/templates/utils/dom.d.ts +15 -0
  32. package/dist/resources/templates/utils/dom.d.ts.map +1 -0
  33. package/dist/resources/templates/utils/html.d.ts +3 -0
  34. package/dist/resources/templates/utils/html.d.ts.map +1 -0
  35. package/dist/resources/templates/workDisplay.d.ts +183 -0
  36. package/dist/resources/templates/workDisplay.d.ts.map +1 -0
  37. package/dist/resources/templates/workSelect.d.ts +18 -0
  38. package/dist/resources/templates/workSelect.d.ts.map +1 -0
  39. package/dist/resources/user-sample.d.ts +2 -0
  40. package/dist/resources/user-sample.d.ts.map +1 -0
  41. package/dist/resources/user.d.ts +2 -0
  42. package/dist/resources/user.d.ts.map +1 -0
  43. package/dist/resources/utils/IntlURLSearchParams.d.ts +56 -0
  44. package/dist/resources/utils/IntlURLSearchParams.d.ts.map +1 -0
  45. package/dist/resources/utils/Languages.d.ts +81 -0
  46. package/dist/resources/utils/Languages.d.ts.map +1 -0
  47. package/dist/resources/utils/Metadata.d.ts +133 -0
  48. package/dist/resources/utils/Metadata.d.ts.map +1 -0
  49. package/dist/resources/utils/Params.d.ts +30 -0
  50. package/dist/resources/utils/Params.d.ts.map +1 -0
  51. package/dist/resources/utils/Plugin.d.ts +274 -0
  52. package/dist/resources/utils/Plugin.d.ts.map +1 -0
  53. package/dist/resources/utils/ServiceWorker.d.ts +26 -0
  54. package/dist/resources/utils/ServiceWorker.d.ts.map +1 -0
  55. package/dist/resources/utils/WorkInfo.d.ts +104 -0
  56. package/dist/resources/utils/WorkInfo.d.ts.map +1 -0
  57. package/dist/resources/utils/dialogs.d.ts +155 -0
  58. package/dist/resources/utils/dialogs.d.ts.map +1 -0
  59. package/dist/resources/utils/getLocaleFallbackResults.d.ts +19 -0
  60. package/dist/resources/utils/getLocaleFallbackResults.d.ts.map +1 -0
  61. package/dist/resources/utils/sanitize.d.ts +6 -0
  62. package/dist/resources/utils/sanitize.d.ts.map +1 -0
  63. package/dist/resources/vendor/json-refs-min.d.ts +3 -0
  64. package/dist/resources/vendor/json-refs-min.d.ts.map +1 -0
  65. package/dist/resources/workDisplay.d.ts +81 -0
  66. package/dist/resources/workDisplay.d.ts.map +1 -0
  67. package/dist/resources/workSelect.d.ts +17 -0
  68. package/dist/resources/workSelect.d.ts.map +1 -0
  69. package/dist/rollup.config.d.ts +19 -0
  70. package/dist/rollup.config.d.ts.map +1 -0
  71. package/dist/server/main.d.ts +46 -0
  72. package/dist/server/main.d.ts.map +1 -0
  73. package/dist/sw-helper.d.ts +3 -0
  74. package/dist/sw-helper.d.ts.map +1 -0
  75. package/dist/sw-helper.js +52 -12
  76. package/dist/sw-sample.d.ts +2 -0
  77. package/dist/sw-sample.d.ts.map +1 -0
  78. package/general-schemas/files.jsonschema +6 -0
  79. package/package.json +22 -9
  80. package/resources/activateCallback.js +75 -10
  81. package/resources/index.js +161 -49
  82. package/resources/resultsDisplay.js +517 -152
  83. package/resources/templates/index.js +39 -16
  84. package/resources/templates/languageSelect.js +14 -1
  85. package/resources/templates/resultsDisplayClient.js +22 -3
  86. package/resources/templates/resultsDisplayServerOrClient.js +188 -49
  87. package/resources/templates/utils/dom.js +13 -2
  88. package/resources/templates/workDisplay.js +299 -75
  89. package/resources/templates/workSelect.js +16 -3
  90. package/resources/utils/IntlURLSearchParams.js +46 -4
  91. package/resources/utils/Languages.js +71 -4
  92. package/resources/utils/Metadata.js +219 -22
  93. package/resources/utils/Params.js +70 -23
  94. package/resources/utils/Plugin.js +169 -1
  95. package/resources/utils/ServiceWorker.js +48 -19
  96. package/resources/utils/WorkInfo.js +255 -43
  97. package/resources/utils/dialogs.js +105 -7
  98. package/resources/utils/getLocaleFallbackResults.js +12 -2
  99. package/resources/utils/sanitize.js +4 -0
  100. package/resources/workDisplay.js +151 -25
  101. package/resources/workSelect.js +37 -17
  102. package/server/main.js +111 -19
  103. package/tsconfig.json +30 -0
  104. 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 ({target: {value}}) {
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 = (langCodes && JSON.parse(langCodes)) || [preferredLocale];
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 this.langData['localization-strings'][langCode];
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
- lang.some((lan) => {
47
+ for (const lan of lang) {
13
48
  const p = [...properties];
14
- let strings = metadataObj['localization-strings'][lan];
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 = strings[p.shift()];
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
- return prop;
26
- });
27
- return prop;
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 = getMetaProp(
86
- lang,
87
- metadataObj,
88
- fieldValueAliasMap.localeKey.split('/'),
89
- true
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
- ret.aliases.push(
100
- getMetaProp(lang, metadataObj, ['fieldvalue', field, enm], true)
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
- ret.aliases.push(...fieldValueAliasMap[enm]);
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 = Object.values(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
- ret.aliases.push(
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
- x.toLowerCase().startsWith(v.toLowerCase())
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
- localeStrings[lng].fieldvalue;
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