@docusaurus/core 0.0.0-4441 → 0.0.0-4443
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.
|
@@ -118,109 +118,142 @@ https://github.com/pugjs/babel-walk
|
|
|
118
118
|
function extractSourceCodeAstTranslations(ast, sourceCodeFilePath) {
|
|
119
119
|
function sourceWarningPart(node) {
|
|
120
120
|
var _a;
|
|
121
|
-
return `File: ${sourceCodeFilePath} at ${(_a = node.loc) === null || _a === void 0 ? void 0 : _a.start.line}
|
|
121
|
+
return `File: ${sourceCodeFilePath} at line ${(_a = node.loc) === null || _a === void 0 ? void 0 : _a.start.line}
|
|
122
|
+
Full code: ${(0, generator_1.default)(node).code}`;
|
|
122
123
|
}
|
|
123
124
|
const translations = {};
|
|
124
125
|
const warnings = [];
|
|
125
|
-
|
|
126
|
+
let translateComponentName;
|
|
127
|
+
let translateFunctionName;
|
|
128
|
+
// First pass: find import declarations of Translate / translate.
|
|
129
|
+
// If not found, don't process the rest to avoid false positives
|
|
126
130
|
(0, traverse_1.default)(ast, {
|
|
127
|
-
|
|
128
|
-
if (
|
|
129
|
-
.get('
|
|
130
|
-
.get('name')
|
|
131
|
-
.isJSXIdentifier({ name: 'Translate' })) {
|
|
131
|
+
ImportDeclaration(path) {
|
|
132
|
+
if (path.node.importKind === 'type' ||
|
|
133
|
+
path.get('source').node.value !== '@docusaurus/Translate') {
|
|
132
134
|
return;
|
|
133
135
|
}
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
.
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
136
|
+
const importSpecifiers = path.get('specifiers');
|
|
137
|
+
const defaultImport = importSpecifiers.find((specifier) => specifier.node.type === 'ImportDefaultSpecifier');
|
|
138
|
+
const callbackImport = importSpecifiers.find((specifier) => specifier.node.type === 'ImportSpecifier' &&
|
|
139
|
+
(specifier.get('imported')
|
|
140
|
+
.node.name === 'translate' ||
|
|
141
|
+
specifier.get('imported')
|
|
142
|
+
.node.value === 'translate'));
|
|
143
|
+
translateComponentName = defaultImport === null || defaultImport === void 0 ? void 0 : defaultImport.get('local').node.name;
|
|
144
|
+
translateFunctionName = callbackImport === null || callbackImport === void 0 ? void 0 : callbackImport.get('local').node.name;
|
|
145
|
+
},
|
|
146
|
+
});
|
|
147
|
+
(0, traverse_1.default)(ast, {
|
|
148
|
+
...(translateComponentName && {
|
|
149
|
+
JSXElement(path) {
|
|
150
|
+
if (!path
|
|
151
|
+
.get('openingElement')
|
|
152
|
+
.get('name')
|
|
153
|
+
.isJSXIdentifier({ name: translateComponentName })) {
|
|
154
|
+
return;
|
|
155
|
+
}
|
|
156
|
+
function evaluateJSXProp(propName) {
|
|
157
|
+
const attributePath = path
|
|
158
|
+
.get('openingElement.attributes')
|
|
159
|
+
.find((attr) => attr.isJSXAttribute() &&
|
|
160
|
+
attr
|
|
161
|
+
.get('name')
|
|
162
|
+
.isJSXIdentifier({ name: propName }));
|
|
163
|
+
if (attributePath) {
|
|
164
|
+
const attributeValue = attributePath.get('value');
|
|
165
|
+
const attributeValueEvaluated = attributeValue.isJSXExpressionContainer()
|
|
166
|
+
? attributeValue.get('expression').evaluate()
|
|
167
|
+
: attributeValue.evaluate();
|
|
168
|
+
if (attributeValueEvaluated.confident &&
|
|
169
|
+
typeof attributeValueEvaluated.value === 'string') {
|
|
170
|
+
return attributeValueEvaluated.value;
|
|
171
|
+
}
|
|
172
|
+
else {
|
|
173
|
+
warnings.push(`<Translate> prop=${propName} should be a statically evaluable object.
|
|
174
|
+
Example: <Translate id="optional id" description="optional description">Message</Translate>
|
|
175
|
+
Dynamically constructed values are not allowed, because they prevent translations to be extracted.
|
|
176
|
+
${sourceWarningPart(path.node)}`);
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
return undefined;
|
|
180
|
+
}
|
|
181
|
+
const id = evaluateJSXProp('id');
|
|
182
|
+
const description = evaluateJSXProp('description');
|
|
183
|
+
let message;
|
|
184
|
+
const childrenPath = path.get('children');
|
|
185
|
+
// Handle empty content
|
|
186
|
+
if (!childrenPath.length) {
|
|
187
|
+
if (!id) {
|
|
188
|
+
warnings.push(`<Translate> without children must have id prop.
|
|
189
|
+
Example: <Translate id="my-id" />
|
|
190
|
+
${sourceWarningPart(path.node)}`);
|
|
149
191
|
}
|
|
150
192
|
else {
|
|
151
|
-
|
|
193
|
+
translations[id] = {
|
|
194
|
+
message: message !== null && message !== void 0 ? message : id,
|
|
195
|
+
...(description && { description }),
|
|
196
|
+
};
|
|
152
197
|
}
|
|
198
|
+
return;
|
|
153
199
|
}
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
message: message !== null && message !== void 0 ? message : id,
|
|
170
|
-
...(description && { description }),
|
|
171
|
-
};
|
|
172
|
-
}
|
|
173
|
-
return;
|
|
174
|
-
}
|
|
175
|
-
// Handle single non-empty content
|
|
176
|
-
const singleChildren = childrenPath
|
|
177
|
-
// Remove empty/useless text nodes that might be around our translation!
|
|
178
|
-
// Makes the translation system more reliable to JSX formatting issues
|
|
179
|
-
.filter((children) => !(children.isJSXText() &&
|
|
180
|
-
children.node.value.replace('\n', '').trim() === ''))
|
|
181
|
-
.pop();
|
|
182
|
-
const isJSXText = singleChildren && singleChildren.isJSXText();
|
|
183
|
-
const isJSXExpressionContainer = singleChildren &&
|
|
184
|
-
singleChildren.isJSXExpressionContainer() &&
|
|
185
|
-
singleChildren.get('expression').evaluate().confident;
|
|
186
|
-
if (isJSXText || isJSXExpressionContainer) {
|
|
187
|
-
message = isJSXText
|
|
188
|
-
? singleChildren.node.value.trim().replace(/\s+/g, ' ')
|
|
189
|
-
: singleChildren.get('expression').evaluate().value;
|
|
190
|
-
translations[id !== null && id !== void 0 ? id : message] = {
|
|
191
|
-
message,
|
|
192
|
-
...(description && { description }),
|
|
193
|
-
};
|
|
194
|
-
}
|
|
195
|
-
else {
|
|
196
|
-
warnings.push(`Translate content could not be extracted. It has to be a static string and use optional but static props, like <Translate id="my-id" description="my-description">text</Translate>.\n${sourceWarningPart(path.node)}`);
|
|
197
|
-
}
|
|
198
|
-
},
|
|
199
|
-
CallExpression(path) {
|
|
200
|
-
if (!path.get('callee').isIdentifier({ name: 'translate' })) {
|
|
201
|
-
return;
|
|
202
|
-
}
|
|
203
|
-
const args = path.get('arguments');
|
|
204
|
-
if (args.length === 1 || args.length === 2) {
|
|
205
|
-
const firstArgPath = args[0];
|
|
206
|
-
// evaluation allows translate("x" + "y"); to be considered as translate("xy");
|
|
207
|
-
const firstArgEvaluated = firstArgPath.evaluate();
|
|
208
|
-
if (firstArgEvaluated.confident &&
|
|
209
|
-
typeof firstArgEvaluated.value === 'object') {
|
|
210
|
-
const { message, id, description } = firstArgEvaluated.value;
|
|
200
|
+
// Handle single non-empty content
|
|
201
|
+
const singleChildren = childrenPath
|
|
202
|
+
// Remove empty/useless text nodes that might be around our translation!
|
|
203
|
+
// Makes the translation system more reliable to JSX formatting issues
|
|
204
|
+
.filter((children) => !(children.isJSXText() &&
|
|
205
|
+
children.node.value.replace('\n', '').trim() === ''))
|
|
206
|
+
.pop();
|
|
207
|
+
const isJSXText = singleChildren && singleChildren.isJSXText();
|
|
208
|
+
const isJSXExpressionContainer = singleChildren &&
|
|
209
|
+
singleChildren.isJSXExpressionContainer() &&
|
|
210
|
+
singleChildren.get('expression').evaluate().confident;
|
|
211
|
+
if (isJSXText || isJSXExpressionContainer) {
|
|
212
|
+
message = isJSXText
|
|
213
|
+
? singleChildren.node.value.trim().replace(/\s+/g, ' ')
|
|
214
|
+
: singleChildren.get('expression').evaluate().value;
|
|
211
215
|
translations[id !== null && id !== void 0 ? id : message] = {
|
|
212
|
-
message
|
|
216
|
+
message,
|
|
213
217
|
...(description && { description }),
|
|
214
218
|
};
|
|
215
219
|
}
|
|
216
220
|
else {
|
|
217
|
-
warnings.push(`
|
|
221
|
+
warnings.push(`Translate content could not be extracted. It has to be a static string and use optional but static props, like <Translate id="my-id" description="my-description">text</Translate>.
|
|
222
|
+
${sourceWarningPart(path.node)}`);
|
|
218
223
|
}
|
|
219
|
-
}
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
+
},
|
|
225
|
+
}),
|
|
226
|
+
...(translateFunctionName && {
|
|
227
|
+
CallExpression(path) {
|
|
228
|
+
if (!path.get('callee').isIdentifier({ name: translateFunctionName })) {
|
|
229
|
+
return;
|
|
230
|
+
}
|
|
231
|
+
const args = path.get('arguments');
|
|
232
|
+
if (args.length === 1 || args.length === 2) {
|
|
233
|
+
const firstArgPath = args[0];
|
|
234
|
+
// evaluation allows translate("x" + "y"); to be considered as translate("xy");
|
|
235
|
+
const firstArgEvaluated = firstArgPath.evaluate();
|
|
236
|
+
if (firstArgEvaluated.confident &&
|
|
237
|
+
typeof firstArgEvaluated.value === 'object') {
|
|
238
|
+
const { message, id, description } = firstArgEvaluated.value;
|
|
239
|
+
translations[id !== null && id !== void 0 ? id : message] = {
|
|
240
|
+
message: message !== null && message !== void 0 ? message : id,
|
|
241
|
+
...(description && { description }),
|
|
242
|
+
};
|
|
243
|
+
}
|
|
244
|
+
else {
|
|
245
|
+
warnings.push(`translate() first arg should be a statically evaluable object.
|
|
246
|
+
Example: translate({message: "text",id: "optional.id",description: "optional description"}
|
|
247
|
+
Dynamically constructed values are not allowed, because they prevent translations to be extracted.
|
|
248
|
+
${sourceWarningPart(path.node)}`);
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
else {
|
|
252
|
+
warnings.push(`translate() function only takes 1 or 2 args
|
|
253
|
+
${sourceWarningPart(path.node)}`);
|
|
254
|
+
}
|
|
255
|
+
},
|
|
256
|
+
}),
|
|
224
257
|
});
|
|
225
258
|
return { sourceCodeFilePath, translations, warnings };
|
|
226
259
|
}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@docusaurus/core",
|
|
3
3
|
"description": "Easy to Maintain Open Source Documentation Websites",
|
|
4
|
-
"version": "0.0.0-
|
|
4
|
+
"version": "0.0.0-4443",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"publishConfig": {
|
|
7
7
|
"access": "public"
|
|
@@ -41,13 +41,13 @@
|
|
|
41
41
|
"@babel/runtime": "^7.16.3",
|
|
42
42
|
"@babel/runtime-corejs3": "^7.16.3",
|
|
43
43
|
"@babel/traverse": "^7.16.3",
|
|
44
|
-
"@docusaurus/cssnano-preset": "0.0.0-
|
|
45
|
-
"@docusaurus/logger": "0.0.0-
|
|
46
|
-
"@docusaurus/mdx-loader": "0.0.0-
|
|
44
|
+
"@docusaurus/cssnano-preset": "0.0.0-4443",
|
|
45
|
+
"@docusaurus/logger": "0.0.0-4443",
|
|
46
|
+
"@docusaurus/mdx-loader": "0.0.0-4443",
|
|
47
47
|
"@docusaurus/react-loadable": "5.5.2",
|
|
48
|
-
"@docusaurus/utils": "0.0.0-
|
|
49
|
-
"@docusaurus/utils-common": "0.0.0-
|
|
50
|
-
"@docusaurus/utils-validation": "0.0.0-
|
|
48
|
+
"@docusaurus/utils": "0.0.0-4443",
|
|
49
|
+
"@docusaurus/utils-common": "0.0.0-4443",
|
|
50
|
+
"@docusaurus/utils-validation": "0.0.0-4443",
|
|
51
51
|
"@slorber/static-site-generator-webpack-plugin": "^4.0.0",
|
|
52
52
|
"@svgr/webpack": "^6.0.0",
|
|
53
53
|
"autoprefixer": "^10.3.5",
|
|
@@ -108,8 +108,8 @@
|
|
|
108
108
|
"webpackbar": "^5.0.0-3"
|
|
109
109
|
},
|
|
110
110
|
"devDependencies": {
|
|
111
|
-
"@docusaurus/module-type-aliases": "0.0.0-
|
|
112
|
-
"@docusaurus/types": "0.0.0-
|
|
111
|
+
"@docusaurus/module-type-aliases": "0.0.0-4443",
|
|
112
|
+
"@docusaurus/types": "0.0.0-4443",
|
|
113
113
|
"@types/copy-webpack-plugin": "^8.0.1",
|
|
114
114
|
"@types/detect-port": "^1.3.0",
|
|
115
115
|
"@types/mini-css-extract-plugin": "^1.4.3",
|
|
@@ -128,5 +128,5 @@
|
|
|
128
128
|
"engines": {
|
|
129
129
|
"node": ">=14"
|
|
130
130
|
},
|
|
131
|
-
"gitHead": "
|
|
131
|
+
"gitHead": "2527fb4a3705407f060ff425874fa4972b8eea4c"
|
|
132
132
|
}
|