@mandolin/jsdoc-plugin-hia-sys 0.1.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 +36 -0
- package/LICENSE +21 -0
- package/README.md +222 -0
- package/RELEASE_CHECKLIST.md +41 -0
- package/THIRD_PARTY_NOTICES.md +23 -0
- package/examples/basic/README.md +22 -0
- package/examples/basic/i18n/docs.hia-i18n.json +12 -0
- package/examples/basic/jsdoc.conf.json +42 -0
- package/examples/basic/src/greet.js +26 -0
- package/examples/basic/src/shared.js +20 -0
- package/package.json +61 -0
- package/src/config/defaults.cjs +114 -0
- package/src/index.cjs +37 -0
- package/src/micro-plugins/code-fragment.cjs +374 -0
- package/src/micro-plugins/diagnostics.cjs +18 -0
- package/src/micro-plugins/doc-i18n.cjs +796 -0
- package/src/micro-plugins/doclet-normalizer.cjs +23 -0
- package/src/micro-plugins/hia-ir-exporter.cjs +68 -0
- package/src/micro-plugins/index.cjs +23 -0
- package/src/micro-plugins/source-link.cjs +19 -0
- package/src/micro-plugins/source-preview.cjs +18 -0
- package/src/runtime/create-plugin-system.cjs +120 -0
- package/src/runtime/diagnostics.cjs +45 -0
- package/src/runtime/i18n.cjs +221 -0
- package/src/runtime/metadata.cjs +52 -0
- package/src/runtime/output-contract.cjs +416 -0
- package/src/runtime/source.cjs +547 -0
- package/src/version.cjs +5 -0
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
module.exports = {
|
|
4
|
+
name: "doclet-normalizer",
|
|
5
|
+
order: 50,
|
|
6
|
+
|
|
7
|
+
newDoclet(event, context) {
|
|
8
|
+
if (!event || !event.doclet) {
|
|
9
|
+
return;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
const doclet = event.doclet;
|
|
13
|
+
const metadata = context.markMicroPlugin(doclet, this.name);
|
|
14
|
+
|
|
15
|
+
metadata.doclet = {
|
|
16
|
+
name: doclet.name || "",
|
|
17
|
+
longname: doclet.longname || doclet.name || "",
|
|
18
|
+
kind: doclet.kind || "",
|
|
19
|
+
memberof: doclet.memberof || "",
|
|
20
|
+
scope: doclet.scope || ""
|
|
21
|
+
};
|
|
22
|
+
}
|
|
23
|
+
};
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
const {
|
|
4
|
+
buildOutputContract,
|
|
5
|
+
writeIntegrationOutput
|
|
6
|
+
} = require("../runtime/output-contract.cjs");
|
|
7
|
+
const { VERSION } = require("../version.cjs");
|
|
8
|
+
|
|
9
|
+
function toNode(doclet, context) {
|
|
10
|
+
const metadata = context.ensureDocletHia(doclet);
|
|
11
|
+
|
|
12
|
+
return {
|
|
13
|
+
id: metadata.doclet.longname || metadata.doclet.name,
|
|
14
|
+
name: metadata.doclet.name,
|
|
15
|
+
longname: metadata.doclet.longname,
|
|
16
|
+
kind: metadata.doclet.kind,
|
|
17
|
+
source: metadata.source,
|
|
18
|
+
i18n: metadata.i18n
|
|
19
|
+
};
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
module.exports = {
|
|
23
|
+
name: "hia-ir-exporter",
|
|
24
|
+
order: 110,
|
|
25
|
+
|
|
26
|
+
parseComplete(event, context) {
|
|
27
|
+
const doclets = event && Array.isArray(event.doclets) ? event.doclets : [];
|
|
28
|
+
|
|
29
|
+
context.state.doclets = doclets;
|
|
30
|
+
context.state.integration.ir = {
|
|
31
|
+
version: VERSION,
|
|
32
|
+
mode: context.config.mode,
|
|
33
|
+
nodes: doclets.map((doclet) => toNode(doclet, context))
|
|
34
|
+
};
|
|
35
|
+
},
|
|
36
|
+
|
|
37
|
+
processingComplete(event, context) {
|
|
38
|
+
const doclets = event && Array.isArray(event.doclets)
|
|
39
|
+
? event.doclets
|
|
40
|
+
: context.state.doclets;
|
|
41
|
+
const output = buildOutputContract(context.state, doclets);
|
|
42
|
+
|
|
43
|
+
context.state.output.standalone = output.standalone;
|
|
44
|
+
context.state.output.integration = output.integration;
|
|
45
|
+
context.state.output.themeContract = output.standalone.theme;
|
|
46
|
+
context.state.integration.ir = output.integration.ir;
|
|
47
|
+
|
|
48
|
+
try {
|
|
49
|
+
const writtenFile = writeIntegrationOutput(context.state, output.integration);
|
|
50
|
+
|
|
51
|
+
if (writtenFile) {
|
|
52
|
+
context.state.output.integrationOutputFile = writtenFile;
|
|
53
|
+
}
|
|
54
|
+
} catch (error) {
|
|
55
|
+
context.addDiagnostic({
|
|
56
|
+
code: "HIA_INTEGRATION_OUTPUT_WRITE_FAILED",
|
|
57
|
+
severity: "error",
|
|
58
|
+
message: `Cannot write HIA integration output: ${error.message}`,
|
|
59
|
+
plugin: this.name,
|
|
60
|
+
data: {
|
|
61
|
+
outputFile: context.config.integration.outputFile || ""
|
|
62
|
+
}
|
|
63
|
+
});
|
|
64
|
+
context.state.output.diagnostics = context.diagnostics.list();
|
|
65
|
+
context.state.output.diagnosticCounts = context.diagnostics.countBySeverity();
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
};
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
const codeFragment = require("./code-fragment.cjs");
|
|
4
|
+
const diagnostics = require("./diagnostics.cjs");
|
|
5
|
+
const docI18n = require("./doc-i18n.cjs");
|
|
6
|
+
const docletNormalizer = require("./doclet-normalizer.cjs");
|
|
7
|
+
const hiaIrExporter = require("./hia-ir-exporter.cjs");
|
|
8
|
+
const sourceLink = require("./source-link.cjs");
|
|
9
|
+
const sourcePreview = require("./source-preview.cjs");
|
|
10
|
+
|
|
11
|
+
const builtInMicroPlugins = [
|
|
12
|
+
codeFragment,
|
|
13
|
+
sourceLink,
|
|
14
|
+
sourcePreview,
|
|
15
|
+
docI18n,
|
|
16
|
+
docletNormalizer,
|
|
17
|
+
hiaIrExporter,
|
|
18
|
+
diagnostics
|
|
19
|
+
];
|
|
20
|
+
|
|
21
|
+
module.exports = {
|
|
22
|
+
builtInMicroPlugins
|
|
23
|
+
};
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
module.exports = {
|
|
4
|
+
name: "source-link",
|
|
5
|
+
order: 20,
|
|
6
|
+
|
|
7
|
+
newDoclet(event, context) {
|
|
8
|
+
if (!event || !event.doclet) {
|
|
9
|
+
return;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
const metadata = context.markMicroPlugin(event.doclet, this.name);
|
|
13
|
+
metadata.source.link = {
|
|
14
|
+
enabled: Boolean(context.config.source.link.enabled),
|
|
15
|
+
rootUrl: context.config.source.link.rootUrl,
|
|
16
|
+
openMode: context.config.source.link.openMode
|
|
17
|
+
};
|
|
18
|
+
}
|
|
19
|
+
};
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
module.exports = {
|
|
4
|
+
name: "source-preview",
|
|
5
|
+
order: 30,
|
|
6
|
+
|
|
7
|
+
newDoclet(event, context) {
|
|
8
|
+
if (!event || !event.doclet) {
|
|
9
|
+
return;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
const metadata = context.markMicroPlugin(event.doclet, this.name);
|
|
13
|
+
metadata.source.preview = {
|
|
14
|
+
enabled: Boolean(context.config.source.preview.enabled),
|
|
15
|
+
defaultExpanded: Boolean(context.config.source.preview.defaultExpanded)
|
|
16
|
+
};
|
|
17
|
+
}
|
|
18
|
+
};
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
const { loadConfig } = require("../config/defaults.cjs");
|
|
4
|
+
const { DiagnosticsCollector } = require("./diagnostics.cjs");
|
|
5
|
+
const {
|
|
6
|
+
attachDiagnostics,
|
|
7
|
+
ensureDocletHia,
|
|
8
|
+
markMicroPlugin
|
|
9
|
+
} = require("./metadata.cjs");
|
|
10
|
+
|
|
11
|
+
function createInitialState(config) {
|
|
12
|
+
return {
|
|
13
|
+
config,
|
|
14
|
+
diagnostics: new DiagnosticsCollector(),
|
|
15
|
+
sourceFiles: new Map(),
|
|
16
|
+
registries: {
|
|
17
|
+
sourceFragments: new Map()
|
|
18
|
+
},
|
|
19
|
+
doclets: [],
|
|
20
|
+
integration: {
|
|
21
|
+
ir: null
|
|
22
|
+
},
|
|
23
|
+
output: {}
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
function createPluginContext(state) {
|
|
28
|
+
return {
|
|
29
|
+
state,
|
|
30
|
+
get config() {
|
|
31
|
+
return state.config;
|
|
32
|
+
},
|
|
33
|
+
diagnostics: state.diagnostics,
|
|
34
|
+
addDiagnostic(diagnostic) {
|
|
35
|
+
return state.diagnostics.add(diagnostic);
|
|
36
|
+
},
|
|
37
|
+
ensureDocletHia(doclet) {
|
|
38
|
+
return ensureDocletHia(doclet, state);
|
|
39
|
+
},
|
|
40
|
+
markMicroPlugin(doclet, pluginName) {
|
|
41
|
+
return markMicroPlugin(doclet, state, pluginName);
|
|
42
|
+
},
|
|
43
|
+
attachDiagnostics(doclet) {
|
|
44
|
+
return attachDiagnostics(doclet, state);
|
|
45
|
+
}
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
function sortMicroPlugins(microPlugins) {
|
|
50
|
+
return microPlugins.slice().sort((left, right) => {
|
|
51
|
+
return (left.order || 100) - (right.order || 100);
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
function filterEnabledMicroPlugins(microPlugins, config) {
|
|
56
|
+
const enabledNames = new Set(config.microPlugins || []);
|
|
57
|
+
return sortMicroPlugins(
|
|
58
|
+
microPlugins.filter((plugin) => enabledNames.has(plugin.name))
|
|
59
|
+
);
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
function createPluginSystem(options) {
|
|
63
|
+
const config = loadConfig(options && options.configOverrides);
|
|
64
|
+
const state = createInitialState(config);
|
|
65
|
+
const context = createPluginContext(state);
|
|
66
|
+
const microPlugins = filterEnabledMicroPlugins(
|
|
67
|
+
(options && options.microPlugins) || [],
|
|
68
|
+
config
|
|
69
|
+
);
|
|
70
|
+
|
|
71
|
+
for (const plugin of microPlugins) {
|
|
72
|
+
if (typeof plugin.setup === "function") {
|
|
73
|
+
plugin.setup(context);
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
function runHook(hookName, event) {
|
|
78
|
+
for (const plugin of microPlugins) {
|
|
79
|
+
const hook = plugin[hookName];
|
|
80
|
+
|
|
81
|
+
if (typeof hook !== "function") {
|
|
82
|
+
continue;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
try {
|
|
86
|
+
hook.call(plugin, event, context);
|
|
87
|
+
} catch (error) {
|
|
88
|
+
context.addDiagnostic({
|
|
89
|
+
code: "HIA_PLUGIN_HOOK_FAILED",
|
|
90
|
+
severity: "error",
|
|
91
|
+
message: `${plugin.name}.${hookName} failed: ${error.message}`,
|
|
92
|
+
plugin: plugin.name
|
|
93
|
+
});
|
|
94
|
+
|
|
95
|
+
if (config.diagnostics.throwOnError) {
|
|
96
|
+
throw error;
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
return {
|
|
103
|
+
defineTags(dictionary) {
|
|
104
|
+
runHook("defineTags", { dictionary });
|
|
105
|
+
},
|
|
106
|
+
handle(hookName, event) {
|
|
107
|
+
runHook(hookName, event);
|
|
108
|
+
},
|
|
109
|
+
getState() {
|
|
110
|
+
return state;
|
|
111
|
+
},
|
|
112
|
+
getMicroPlugins() {
|
|
113
|
+
return microPlugins.slice();
|
|
114
|
+
}
|
|
115
|
+
};
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
module.exports = {
|
|
119
|
+
createPluginSystem
|
|
120
|
+
};
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
const VALID_SEVERITIES = new Set(["error", "warning", "info"]);
|
|
4
|
+
|
|
5
|
+
function normalizeSeverity(severity) {
|
|
6
|
+
return severity === "hint" ? "info" : severity;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
class DiagnosticsCollector {
|
|
10
|
+
constructor() {
|
|
11
|
+
this.items = [];
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
add(diagnostic) {
|
|
15
|
+
const item = {
|
|
16
|
+
code: diagnostic.code || "HIA0000",
|
|
17
|
+
severity: VALID_SEVERITIES.has(normalizeSeverity(diagnostic.severity))
|
|
18
|
+
? normalizeSeverity(diagnostic.severity)
|
|
19
|
+
: "warning",
|
|
20
|
+
message: diagnostic.message || "Unknown HIA diagnostic.",
|
|
21
|
+
plugin: diagnostic.plugin || "core",
|
|
22
|
+
filePath: diagnostic.filePath || "",
|
|
23
|
+
range: diagnostic.range || null,
|
|
24
|
+
data: diagnostic.data || null
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
this.items.push(item);
|
|
28
|
+
return item;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
list() {
|
|
32
|
+
return this.items.slice();
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
countBySeverity() {
|
|
36
|
+
return this.items.reduce((counts, item) => {
|
|
37
|
+
counts[item.severity] = (counts[item.severity] || 0) + 1;
|
|
38
|
+
return counts;
|
|
39
|
+
}, {});
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
module.exports = {
|
|
44
|
+
DiagnosticsCollector
|
|
45
|
+
};
|
|
@@ -0,0 +1,221 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
const fs = require("node:fs");
|
|
4
|
+
const path = require("node:path");
|
|
5
|
+
|
|
6
|
+
function parseLocaleValue(value) {
|
|
7
|
+
const text = String(value || "").trim();
|
|
8
|
+
const match = /^(\S+)\s+([\s\S]+)$/.exec(text);
|
|
9
|
+
|
|
10
|
+
if (!match) {
|
|
11
|
+
return {
|
|
12
|
+
locale: "",
|
|
13
|
+
value: text
|
|
14
|
+
};
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
return {
|
|
18
|
+
locale: match[1],
|
|
19
|
+
value: match[2].trim()
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
function ensureLocaleBucket(target, locale) {
|
|
24
|
+
if (!target[locale]) {
|
|
25
|
+
target[locale] = {};
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
return target[locale];
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
function resolveResourcePath(resourcePath, config) {
|
|
32
|
+
if (path.isAbsolute(resourcePath)) {
|
|
33
|
+
return resourcePath;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
const basePath =
|
|
37
|
+
config.i18n.resourceBasePath || config.source.basePath || process.cwd();
|
|
38
|
+
|
|
39
|
+
return path.resolve(basePath, resourcePath);
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
function toPosixPath(filePath) {
|
|
43
|
+
return String(filePath || "").split(path.sep).join("/");
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
function isSafeRelativePath(filePath) {
|
|
47
|
+
const text = toPosixPath(filePath);
|
|
48
|
+
|
|
49
|
+
return Boolean(text) &&
|
|
50
|
+
!path.isAbsolute(text) &&
|
|
51
|
+
!/^[A-Za-z]:\//.test(text) &&
|
|
52
|
+
!text.startsWith("/") &&
|
|
53
|
+
!text.startsWith("//") &&
|
|
54
|
+
!text.split("/").includes("..");
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
function getResourceRelativePath(absolutePath, resourcePath, config) {
|
|
58
|
+
if (isSafeRelativePath(resourcePath)) {
|
|
59
|
+
return toPosixPath(resourcePath);
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
const basePath =
|
|
63
|
+
config.i18n.resourceBasePath || config.source.basePath || process.cwd();
|
|
64
|
+
const relativePath = toPosixPath(path.relative(basePath, absolutePath));
|
|
65
|
+
|
|
66
|
+
if (isSafeRelativePath(relativePath)) {
|
|
67
|
+
return relativePath;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
return path.basename(absolutePath);
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
function collectResourceFields(entries) {
|
|
74
|
+
const fields = new Set();
|
|
75
|
+
|
|
76
|
+
for (const localeEntries of Object.values(entries || {})) {
|
|
77
|
+
for (const [key, value] of Object.entries(localeEntries || {})) {
|
|
78
|
+
fields.add(key);
|
|
79
|
+
|
|
80
|
+
if (value && typeof value === "object" && !Array.isArray(value)) {
|
|
81
|
+
const nestedFields = value.fields && typeof value.fields === "object"
|
|
82
|
+
? Object.keys(value.fields)
|
|
83
|
+
: [];
|
|
84
|
+
|
|
85
|
+
for (const fieldPath of nestedFields) {
|
|
86
|
+
fields.add(fieldPath);
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
return Array.from(fields).sort();
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
function normalizeResourceData(data, absolutePath) {
|
|
96
|
+
if (data && typeof data.locale === "string" && data.entries) {
|
|
97
|
+
return {
|
|
98
|
+
filePath: absolutePath,
|
|
99
|
+
entries: {
|
|
100
|
+
[data.locale]: data.entries
|
|
101
|
+
}
|
|
102
|
+
};
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
return {
|
|
106
|
+
filePath: absolutePath,
|
|
107
|
+
entries: data && typeof data === "object" ? data : {}
|
|
108
|
+
};
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
function loadLocalizationResources(config, diagnostics) {
|
|
112
|
+
const resources = [];
|
|
113
|
+
const entries = {};
|
|
114
|
+
|
|
115
|
+
for (const resourcePath of config.i18n.resources || []) {
|
|
116
|
+
const absolutePath = resolveResourcePath(resourcePath, config);
|
|
117
|
+
|
|
118
|
+
if (!fs.existsSync(absolutePath)) {
|
|
119
|
+
diagnostics.add({
|
|
120
|
+
code: "HIA_I18N_RESOURCE_MISSING",
|
|
121
|
+
severity: "error",
|
|
122
|
+
message: `Localization resource does not exist: ${resourcePath}`,
|
|
123
|
+
plugin: "doc-i18n",
|
|
124
|
+
filePath: absolutePath,
|
|
125
|
+
data: {
|
|
126
|
+
resourcePath
|
|
127
|
+
}
|
|
128
|
+
});
|
|
129
|
+
continue;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
try {
|
|
133
|
+
const resource = normalizeResourceData(
|
|
134
|
+
JSON.parse(fs.readFileSync(absolutePath, "utf8")),
|
|
135
|
+
absolutePath
|
|
136
|
+
);
|
|
137
|
+
|
|
138
|
+
resources.push({
|
|
139
|
+
kind: "external-resource",
|
|
140
|
+
path: getResourceRelativePath(absolutePath, resourcePath, config),
|
|
141
|
+
format: "hia-i18n-json",
|
|
142
|
+
fields: collectResourceFields(resource.entries),
|
|
143
|
+
locales: Object.keys(resource.entries).sort(),
|
|
144
|
+
localeCount: Object.keys(resource.entries).length
|
|
145
|
+
});
|
|
146
|
+
|
|
147
|
+
for (const [locale, localeEntries] of Object.entries(resource.entries)) {
|
|
148
|
+
const bucket = ensureLocaleBucket(entries, locale);
|
|
149
|
+
|
|
150
|
+
for (const [key, value] of Object.entries(localeEntries || {})) {
|
|
151
|
+
if (Object.prototype.hasOwnProperty.call(bucket, key)) {
|
|
152
|
+
diagnostics.add({
|
|
153
|
+
code: "HIA_I18N_RESOURCE_KEY_DUPLICATE",
|
|
154
|
+
severity: "error",
|
|
155
|
+
message: `Duplicate localization resource key: ${locale}:${key}`,
|
|
156
|
+
plugin: "doc-i18n",
|
|
157
|
+
filePath: absolutePath,
|
|
158
|
+
data: {
|
|
159
|
+
locale,
|
|
160
|
+
key
|
|
161
|
+
}
|
|
162
|
+
});
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
bucket[key] = value;
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
} catch (error) {
|
|
169
|
+
diagnostics.add({
|
|
170
|
+
code: "HIA_I18N_RESOURCE_INVALID",
|
|
171
|
+
severity: "error",
|
|
172
|
+
message: `Cannot read localization resource ${resourcePath}: ${error.message}`,
|
|
173
|
+
plugin: "doc-i18n",
|
|
174
|
+
filePath: absolutePath,
|
|
175
|
+
data: {
|
|
176
|
+
resourcePath
|
|
177
|
+
}
|
|
178
|
+
});
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
return {
|
|
183
|
+
resources,
|
|
184
|
+
entries
|
|
185
|
+
};
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
function getResourceEntry(entries, locale, key) {
|
|
189
|
+
const bucket = entries[locale];
|
|
190
|
+
|
|
191
|
+
if (!bucket) {
|
|
192
|
+
return null;
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
return bucket[key] || null;
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
function normalizeLocalizedValue(value) {
|
|
199
|
+
if (value && typeof value === "object" && !Array.isArray(value)) {
|
|
200
|
+
return {
|
|
201
|
+
text: value.text || value.description || "",
|
|
202
|
+
block: value.block || value.markdown || "",
|
|
203
|
+
source: "resource",
|
|
204
|
+
data: value
|
|
205
|
+
};
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
return {
|
|
209
|
+
text: String(value || ""),
|
|
210
|
+
block: "",
|
|
211
|
+
source: "resource",
|
|
212
|
+
data: value
|
|
213
|
+
};
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
module.exports = {
|
|
217
|
+
getResourceEntry,
|
|
218
|
+
loadLocalizationResources,
|
|
219
|
+
normalizeLocalizedValue,
|
|
220
|
+
parseLocaleValue
|
|
221
|
+
};
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
const { VERSION } = require("../version.cjs");
|
|
4
|
+
|
|
5
|
+
function ensureDocletHia(doclet, state) {
|
|
6
|
+
const key = state.config.metadataKey || "hia";
|
|
7
|
+
|
|
8
|
+
if (!doclet[key]) {
|
|
9
|
+
doclet[key] = {
|
|
10
|
+
version: VERSION,
|
|
11
|
+
mode: state.config.mode,
|
|
12
|
+
microPlugins: [],
|
|
13
|
+
doclet: {},
|
|
14
|
+
source: {
|
|
15
|
+
model: "hia-jsdoc-source",
|
|
16
|
+
modelVersion: "0.2.0",
|
|
17
|
+
mode: state.config.source.mode || "all",
|
|
18
|
+
definedIn: null,
|
|
19
|
+
primaryBlock: null,
|
|
20
|
+
fragments: [],
|
|
21
|
+
references: [],
|
|
22
|
+
diagnostics: []
|
|
23
|
+
},
|
|
24
|
+
i18n: {},
|
|
25
|
+
diagnostics: []
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
return doclet[key];
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
function markMicroPlugin(doclet, state, pluginName) {
|
|
33
|
+
const metadata = ensureDocletHia(doclet, state);
|
|
34
|
+
|
|
35
|
+
if (!metadata.microPlugins.includes(pluginName)) {
|
|
36
|
+
metadata.microPlugins.push(pluginName);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
return metadata;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
function attachDiagnostics(doclet, state) {
|
|
43
|
+
const metadata = ensureDocletHia(doclet, state);
|
|
44
|
+
metadata.diagnostics = state.diagnostics.list();
|
|
45
|
+
return metadata;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
module.exports = {
|
|
49
|
+
attachDiagnostics,
|
|
50
|
+
ensureDocletHia,
|
|
51
|
+
markMicroPlugin
|
|
52
|
+
};
|