@rushstack/localization-utilities 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/LICENSE +24 -0
- package/README.md +3 -0
- package/dist/localization-utilities.d.ts +103 -0
- package/dist/tsdoc-metadata.json +11 -0
- package/lib/LocFileParser.d.ts +17 -0
- package/lib/LocFileParser.d.ts.map +1 -0
- package/lib/LocFileParser.js +73 -0
- package/lib/LocFileParser.js.map +1 -0
- package/lib/LocFileTypingsGenerator.d.ts +23 -0
- package/lib/LocFileTypingsGenerator.d.ts.map +1 -0
- package/lib/LocFileTypingsGenerator.js +36 -0
- package/lib/LocFileTypingsGenerator.js.map +1 -0
- package/lib/Pseudolocalization.d.ts +8 -0
- package/lib/Pseudolocalization.d.ts.map +1 -0
- package/lib/Pseudolocalization.js +23 -0
- package/lib/Pseudolocalization.js.map +1 -0
- package/lib/ResxReader.d.ts +20 -0
- package/lib/ResxReader.d.ts.map +1 -0
- package/lib/ResxReader.js +207 -0
- package/lib/ResxReader.js.map +1 -0
- package/lib/index.d.ts +6 -0
- package/lib/index.d.ts.map +1 -0
- package/lib/index.js +15 -0
- package/lib/index.js.map +1 -0
- package/lib/interfaces.d.ts +31 -0
- package/lib/interfaces.d.ts.map +1 -0
- package/lib/interfaces.js +5 -0
- package/lib/interfaces.js.map +1 -0
- package/lib/schemas/locJson.schema.json +28 -0
- package/package.json +32 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
@rushstack/localization-utilities
|
|
2
|
+
|
|
3
|
+
Copyright (c) Microsoft Corporation. All rights reserved.
|
|
4
|
+
|
|
5
|
+
MIT License
|
|
6
|
+
|
|
7
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
|
8
|
+
a copy of this software and associated documentation files (the
|
|
9
|
+
"Software"), to deal in the Software without restriction, including
|
|
10
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
|
11
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
|
12
|
+
permit persons to whom the Software is furnished to do so, subject to
|
|
13
|
+
the following conditions:
|
|
14
|
+
|
|
15
|
+
The above copyright notice and this permission notice shall be
|
|
16
|
+
included in all copies or substantial portions of the Software.
|
|
17
|
+
|
|
18
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
19
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
20
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
21
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
|
22
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
|
23
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
|
24
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
import { ITerminal } from '@rushstack/node-core-library';
|
|
2
|
+
import { NewlineKind } from '@rushstack/node-core-library';
|
|
3
|
+
import { StringValuesTypingsGenerator } from '@rushstack/typings-generator';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Get a function that pseudolocalizes a string.
|
|
7
|
+
*
|
|
8
|
+
* @public
|
|
9
|
+
*/
|
|
10
|
+
export declare function getPseudolocalizer(options: IPseudolocaleOptions): (str: string) => string;
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* @public
|
|
14
|
+
*/
|
|
15
|
+
export declare interface ILocalizationFile {
|
|
16
|
+
[stringName: string]: ILocalizedString;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* @public
|
|
21
|
+
*/
|
|
22
|
+
export declare interface ILocalizedString {
|
|
23
|
+
value: string;
|
|
24
|
+
comment?: string;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* @public
|
|
29
|
+
*/
|
|
30
|
+
export declare interface IParseLocFileOptions {
|
|
31
|
+
terminal: ITerminal;
|
|
32
|
+
filePath: string;
|
|
33
|
+
content: string;
|
|
34
|
+
resxNewlineNormalization: NewlineKind | undefined;
|
|
35
|
+
ignoreMissingResxComments: boolean | undefined;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* Options for the pseudolocale library.
|
|
40
|
+
*
|
|
41
|
+
* @internalRemarks
|
|
42
|
+
* Eventually this should be replaced with DefinitelyTyped types.
|
|
43
|
+
*
|
|
44
|
+
* @public
|
|
45
|
+
*/
|
|
46
|
+
export declare interface IPseudolocaleOptions {
|
|
47
|
+
prepend?: string;
|
|
48
|
+
append?: string;
|
|
49
|
+
delimiter?: string;
|
|
50
|
+
startDelimiter?: string;
|
|
51
|
+
endDelimiter?: string;
|
|
52
|
+
extend?: number;
|
|
53
|
+
override?: string;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* @public
|
|
58
|
+
*/
|
|
59
|
+
export declare interface IResxReaderOptions {
|
|
60
|
+
resxFilePath: string;
|
|
61
|
+
terminal: ITerminal;
|
|
62
|
+
newlineNormalization: NewlineKind | undefined;
|
|
63
|
+
warnOnMissingComment: boolean;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* @public
|
|
68
|
+
*/
|
|
69
|
+
export declare interface ITypingsGeneratorOptions {
|
|
70
|
+
srcFolder: string;
|
|
71
|
+
generatedTsFolder: string;
|
|
72
|
+
terminal?: ITerminal;
|
|
73
|
+
exportAsDefault?: boolean;
|
|
74
|
+
globsToIgnore?: string[];
|
|
75
|
+
resxNewlineNormalization?: NewlineKind | undefined;
|
|
76
|
+
ignoreMissingResxComments?: boolean | undefined;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
/**
|
|
80
|
+
* @public
|
|
81
|
+
*/
|
|
82
|
+
export declare function parseLocFile(options: IParseLocFileOptions): ILocalizationFile;
|
|
83
|
+
|
|
84
|
+
/**
|
|
85
|
+
* @public
|
|
86
|
+
*/
|
|
87
|
+
export declare function readResxAsLocFile(resxContents: string, options: IResxReaderOptions): ILocalizationFile;
|
|
88
|
+
|
|
89
|
+
/**
|
|
90
|
+
* @public
|
|
91
|
+
*/
|
|
92
|
+
export declare function readResxFileAsLocFile(options: IResxReaderOptions): ILocalizationFile;
|
|
93
|
+
|
|
94
|
+
/**
|
|
95
|
+
* This is a simple tool that generates .d.ts files for .loc.json, .resx.json, .resjson, and .resx files.
|
|
96
|
+
*
|
|
97
|
+
* @public
|
|
98
|
+
*/
|
|
99
|
+
export declare class TypingsGenerator extends StringValuesTypingsGenerator {
|
|
100
|
+
constructor(options: ITypingsGeneratorOptions);
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
export { }
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
// This file is read by tools that parse documentation comments conforming to the TSDoc standard.
|
|
2
|
+
// It should be published with your NPM package. It should not be tracked by Git.
|
|
3
|
+
{
|
|
4
|
+
"tsdocVersion": "0.12",
|
|
5
|
+
"toolPackages": [
|
|
6
|
+
{
|
|
7
|
+
"packageName": "@microsoft/api-extractor",
|
|
8
|
+
"packageVersion": "7.24.2"
|
|
9
|
+
}
|
|
10
|
+
]
|
|
11
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { ITerminal, NewlineKind } from '@rushstack/node-core-library';
|
|
2
|
+
import { ILocalizationFile } from './interfaces';
|
|
3
|
+
/**
|
|
4
|
+
* @public
|
|
5
|
+
*/
|
|
6
|
+
export interface IParseLocFileOptions {
|
|
7
|
+
terminal: ITerminal;
|
|
8
|
+
filePath: string;
|
|
9
|
+
content: string;
|
|
10
|
+
resxNewlineNormalization: NewlineKind | undefined;
|
|
11
|
+
ignoreMissingResxComments: boolean | undefined;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* @public
|
|
15
|
+
*/
|
|
16
|
+
export declare function parseLocFile(options: IParseLocFileOptions): ILocalizationFile;
|
|
17
|
+
//# sourceMappingURL=LocFileParser.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"LocFileParser.d.ts","sourceRoot":"","sources":["../src/LocFileParser.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,SAAS,EAAE,WAAW,EAAwB,MAAM,8BAA8B,CAAC;AAE5F,OAAO,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAC;AAKjD;;GAEG;AACH,MAAM,WAAW,oBAAoB;IACnC,QAAQ,EAAE,SAAS,CAAC;IACpB,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,wBAAwB,EAAE,WAAW,GAAG,SAAS,CAAC;IAClD,yBAAyB,EAAE,OAAO,GAAG,SAAS,CAAC;CAChD;AASD;;GAEG;AACH,wBAAgB,YAAY,CAAC,OAAO,EAAE,oBAAoB,GAAG,iBAAiB,CA0D7E"}
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license.
|
|
3
|
+
// See LICENSE in the project root for license information.
|
|
4
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
5
|
+
exports.parseLocFile = void 0;
|
|
6
|
+
const node_core_library_1 = require("@rushstack/node-core-library");
|
|
7
|
+
const ResxReader_1 = require("./ResxReader");
|
|
8
|
+
const LOC_JSON_SCHEMA = node_core_library_1.JsonSchema.fromFile(`${__dirname}/schemas/locJson.schema.json`);
|
|
9
|
+
const parseCache = new Map();
|
|
10
|
+
/**
|
|
11
|
+
* @public
|
|
12
|
+
*/
|
|
13
|
+
function parseLocFile(options) {
|
|
14
|
+
const fileCacheKey = `${options.filePath}?${options.resxNewlineNormalization || 'none'}`;
|
|
15
|
+
if (parseCache.has(fileCacheKey)) {
|
|
16
|
+
const entry = parseCache.get(fileCacheKey);
|
|
17
|
+
if (entry.content === options.content) {
|
|
18
|
+
return entry.parsedFile;
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
let parsedFile;
|
|
22
|
+
if (/\.resx$/i.test(options.filePath)) {
|
|
23
|
+
parsedFile = (0, ResxReader_1.readResxAsLocFile)(options.content, {
|
|
24
|
+
terminal: options.terminal,
|
|
25
|
+
resxFilePath: options.filePath,
|
|
26
|
+
newlineNormalization: options.resxNewlineNormalization,
|
|
27
|
+
warnOnMissingComment: !options.ignoreMissingResxComments
|
|
28
|
+
});
|
|
29
|
+
}
|
|
30
|
+
else if (/\.(resx|loc)\.json$/i.test(options.filePath)) {
|
|
31
|
+
parsedFile = node_core_library_1.JsonFile.parseString(options.content);
|
|
32
|
+
try {
|
|
33
|
+
LOC_JSON_SCHEMA.validateObject(parsedFile, options.filePath);
|
|
34
|
+
}
|
|
35
|
+
catch (e) {
|
|
36
|
+
options.terminal.writeError(`The loc file is invalid. Error: ${e}`);
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
else if (/\.resjson$/i.test(options.filePath)) {
|
|
40
|
+
const resjsonFile = node_core_library_1.JsonFile.parseString(options.content);
|
|
41
|
+
parsedFile = {};
|
|
42
|
+
const comments = new Map();
|
|
43
|
+
for (const [key, value] of Object.entries(resjsonFile)) {
|
|
44
|
+
if (key.startsWith('_') && key.endsWith('.comment')) {
|
|
45
|
+
const commentKey = key.substring(1, key.length - '.comment'.length);
|
|
46
|
+
comments.set(commentKey, value);
|
|
47
|
+
}
|
|
48
|
+
else {
|
|
49
|
+
parsedFile[key] = { value };
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
const orphanComments = [];
|
|
53
|
+
for (const [key, comment] of comments) {
|
|
54
|
+
if (parsedFile[key]) {
|
|
55
|
+
parsedFile[key].comment = comment;
|
|
56
|
+
}
|
|
57
|
+
else {
|
|
58
|
+
orphanComments.push(key);
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
if (orphanComments.length > 0) {
|
|
62
|
+
options.terminal.writeErrorLine('The resjson file is invalid. Comments exist for the following string keys ' +
|
|
63
|
+
`that don't have values: ${orphanComments.join(', ')}.`);
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
else {
|
|
67
|
+
throw new Error(`Unsupported file extension in file: ${options.filePath}`);
|
|
68
|
+
}
|
|
69
|
+
parseCache.set(fileCacheKey, { content: options.content, parsedFile });
|
|
70
|
+
return parsedFile;
|
|
71
|
+
}
|
|
72
|
+
exports.parseLocFile = parseLocFile;
|
|
73
|
+
//# sourceMappingURL=LocFileParser.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"LocFileParser.js","sourceRoot":"","sources":["../src/LocFileParser.ts"],"names":[],"mappings":"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","sourcesContent":["// Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license.\n// See LICENSE in the project root for license information.\n\nimport { ITerminal, NewlineKind, JsonFile, JsonSchema } from '@rushstack/node-core-library';\n\nimport { ILocalizationFile } from './interfaces';\nimport { readResxAsLocFile } from './ResxReader';\n\nconst LOC_JSON_SCHEMA: JsonSchema = JsonSchema.fromFile(`${__dirname}/schemas/locJson.schema.json`);\n\n/**\n * @public\n */\nexport interface IParseLocFileOptions {\n terminal: ITerminal;\n filePath: string;\n content: string;\n resxNewlineNormalization: NewlineKind | undefined;\n ignoreMissingResxComments: boolean | undefined;\n}\n\ninterface IParseCacheEntry {\n content: string;\n parsedFile: ILocalizationFile;\n}\n\nconst parseCache: Map<string, IParseCacheEntry> = new Map<string, IParseCacheEntry>();\n\n/**\n * @public\n */\nexport function parseLocFile(options: IParseLocFileOptions): ILocalizationFile {\n const fileCacheKey: string = `${options.filePath}?${options.resxNewlineNormalization || 'none'}`;\n if (parseCache.has(fileCacheKey)) {\n const entry: IParseCacheEntry = parseCache.get(fileCacheKey)!;\n if (entry.content === options.content) {\n return entry.parsedFile;\n }\n }\n\n let parsedFile: ILocalizationFile;\n if (/\\.resx$/i.test(options.filePath)) {\n parsedFile = readResxAsLocFile(options.content, {\n terminal: options.terminal,\n resxFilePath: options.filePath,\n newlineNormalization: options.resxNewlineNormalization,\n warnOnMissingComment: !options.ignoreMissingResxComments\n });\n } else if (/\\.(resx|loc)\\.json$/i.test(options.filePath)) {\n parsedFile = JsonFile.parseString(options.content);\n try {\n LOC_JSON_SCHEMA.validateObject(parsedFile, options.filePath);\n } catch (e) {\n options.terminal.writeError(`The loc file is invalid. Error: ${e}`);\n }\n } else if (/\\.resjson$/i.test(options.filePath)) {\n const resjsonFile: Record<string, string> = JsonFile.parseString(options.content);\n parsedFile = {};\n const comments: Map<string, string> = new Map();\n for (const [key, value] of Object.entries(resjsonFile)) {\n if (key.startsWith('_') && key.endsWith('.comment')) {\n const commentKey: string = key.substring(1, key.length - '.comment'.length);\n comments.set(commentKey, value);\n } else {\n parsedFile[key] = { value };\n }\n }\n\n const orphanComments: string[] = [];\n for (const [key, comment] of comments) {\n if (parsedFile[key]) {\n parsedFile[key].comment = comment;\n } else {\n orphanComments.push(key);\n }\n }\n\n if (orphanComments.length > 0) {\n options.terminal.writeErrorLine(\n 'The resjson file is invalid. Comments exist for the following string keys ' +\n `that don't have values: ${orphanComments.join(', ')}.`\n );\n }\n } else {\n throw new Error(`Unsupported file extension in file: ${options.filePath}`);\n }\n\n parseCache.set(fileCacheKey, { content: options.content, parsedFile });\n return parsedFile;\n}\n"]}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { StringValuesTypingsGenerator } from '@rushstack/typings-generator';
|
|
2
|
+
import { ITerminal, NewlineKind } from '@rushstack/node-core-library';
|
|
3
|
+
/**
|
|
4
|
+
* @public
|
|
5
|
+
*/
|
|
6
|
+
export interface ITypingsGeneratorOptions {
|
|
7
|
+
srcFolder: string;
|
|
8
|
+
generatedTsFolder: string;
|
|
9
|
+
terminal?: ITerminal;
|
|
10
|
+
exportAsDefault?: boolean;
|
|
11
|
+
globsToIgnore?: string[];
|
|
12
|
+
resxNewlineNormalization?: NewlineKind | undefined;
|
|
13
|
+
ignoreMissingResxComments?: boolean | undefined;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* This is a simple tool that generates .d.ts files for .loc.json, .resx.json, .resjson, and .resx files.
|
|
17
|
+
*
|
|
18
|
+
* @public
|
|
19
|
+
*/
|
|
20
|
+
export declare class LocFileTypingsGenerator extends StringValuesTypingsGenerator {
|
|
21
|
+
constructor(options: ITypingsGeneratorOptions);
|
|
22
|
+
}
|
|
23
|
+
//# sourceMappingURL=LocFileTypingsGenerator.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"LocFileTypingsGenerator.d.ts","sourceRoot":"","sources":["../src/LocFileTypingsGenerator.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,4BAA4B,EAAsB,MAAM,8BAA8B,CAAC;AAChG,OAAO,EAAE,SAAS,EAAE,WAAW,EAAE,MAAM,8BAA8B,CAAC;AAKtE;;GAEG;AACH,MAAM,WAAW,wBAAwB;IACvC,SAAS,EAAE,MAAM,CAAC;IAClB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,EAAE,SAAS,CAAC;IACrB,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,aAAa,CAAC,EAAE,MAAM,EAAE,CAAC;IACzB,wBAAwB,CAAC,EAAE,WAAW,GAAG,SAAS,CAAC;IACnD,yBAAyB,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;CACjD;AAED;;;;GAIG;AACH,qBAAa,uBAAwB,SAAQ,4BAA4B;gBACpD,OAAO,EAAE,wBAAwB;CA2BrD"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license.
|
|
3
|
+
// See LICENSE in the project root for license information.
|
|
4
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
5
|
+
exports.LocFileTypingsGenerator = void 0;
|
|
6
|
+
const typings_generator_1 = require("@rushstack/typings-generator");
|
|
7
|
+
const LocFileParser_1 = require("./LocFileParser");
|
|
8
|
+
/**
|
|
9
|
+
* This is a simple tool that generates .d.ts files for .loc.json, .resx.json, .resjson, and .resx files.
|
|
10
|
+
*
|
|
11
|
+
* @public
|
|
12
|
+
*/
|
|
13
|
+
class LocFileTypingsGenerator extends typings_generator_1.StringValuesTypingsGenerator {
|
|
14
|
+
constructor(options) {
|
|
15
|
+
super(Object.assign(Object.assign({}, options), { fileExtensions: ['.resx', '.resx.json', '.loc.json', '.resjson'], parseAndGenerateTypings: (fileContents, filePath) => {
|
|
16
|
+
const locFileData = (0, LocFileParser_1.parseLocFile)({
|
|
17
|
+
filePath: filePath,
|
|
18
|
+
content: fileContents,
|
|
19
|
+
terminal: this._options.terminal,
|
|
20
|
+
resxNewlineNormalization: options.resxNewlineNormalization,
|
|
21
|
+
ignoreMissingResxComments: options.ignoreMissingResxComments
|
|
22
|
+
});
|
|
23
|
+
const typings = [];
|
|
24
|
+
// eslint-disable-next-line guard-for-in
|
|
25
|
+
for (const stringName in locFileData) {
|
|
26
|
+
typings.push({
|
|
27
|
+
exportName: stringName,
|
|
28
|
+
comment: locFileData[stringName].comment
|
|
29
|
+
});
|
|
30
|
+
}
|
|
31
|
+
return { typings };
|
|
32
|
+
} }));
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
exports.LocFileTypingsGenerator = LocFileTypingsGenerator;
|
|
36
|
+
//# sourceMappingURL=LocFileTypingsGenerator.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"LocFileTypingsGenerator.js","sourceRoot":"","sources":["../src/LocFileTypingsGenerator.ts"],"names":[],"mappings":";AAAA,4FAA4F;AAC5F,2DAA2D;;;AAE3D,oEAAgG;AAIhG,mDAA+C;AAe/C;;;;GAIG;AACH,MAAa,uBAAwB,SAAQ,gDAA4B;IACvE,YAAmB,OAAiC;QAClD,KAAK,iCACA,OAAO,KACV,cAAc,EAAE,CAAC,OAAO,EAAE,YAAY,EAAE,WAAW,EAAE,UAAU,CAAC,EAChE,uBAAuB,EAAE,CAAC,YAAoB,EAAE,QAAgB,EAAE,EAAE;gBAClE,MAAM,WAAW,GAAsB,IAAA,4BAAY,EAAC;oBAClD,QAAQ,EAAE,QAAQ;oBAClB,OAAO,EAAE,YAAY;oBACrB,QAAQ,EAAE,IAAI,CAAC,QAAQ,CAAC,QAAS;oBACjC,wBAAwB,EAAE,OAAO,CAAC,wBAAwB;oBAC1D,yBAAyB,EAAE,OAAO,CAAC,yBAAyB;iBAC7D,CAAC,CAAC;gBAEH,MAAM,OAAO,GAAyB,EAAE,CAAC;gBAEzC,wCAAwC;gBACxC,KAAK,MAAM,UAAU,IAAI,WAAW,EAAE;oBACpC,OAAO,CAAC,IAAI,CAAC;wBACX,UAAU,EAAE,UAAU;wBACtB,OAAO,EAAE,WAAW,CAAC,UAAU,CAAC,CAAC,OAAO;qBACzC,CAAC,CAAC;iBACJ;gBAED,OAAO,EAAE,OAAO,EAAE,CAAC;YACrB,CAAC,IACD,CAAC;IACL,CAAC;CACF;AA5BD,0DA4BC","sourcesContent":["// Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license.\n// See LICENSE in the project root for license information.\n\nimport { StringValuesTypingsGenerator, IStringValueTyping } from '@rushstack/typings-generator';\nimport { ITerminal, NewlineKind } from '@rushstack/node-core-library';\n\nimport { ILocalizationFile } from './interfaces';\nimport { parseLocFile } from './LocFileParser';\n\n/**\n * @public\n */\nexport interface ITypingsGeneratorOptions {\n srcFolder: string;\n generatedTsFolder: string;\n terminal?: ITerminal;\n exportAsDefault?: boolean;\n globsToIgnore?: string[];\n resxNewlineNormalization?: NewlineKind | undefined;\n ignoreMissingResxComments?: boolean | undefined;\n}\n\n/**\n * This is a simple tool that generates .d.ts files for .loc.json, .resx.json, .resjson, and .resx files.\n *\n * @public\n */\nexport class LocFileTypingsGenerator extends StringValuesTypingsGenerator {\n public constructor(options: ITypingsGeneratorOptions) {\n super({\n ...options,\n fileExtensions: ['.resx', '.resx.json', '.loc.json', '.resjson'],\n parseAndGenerateTypings: (fileContents: string, filePath: string) => {\n const locFileData: ILocalizationFile = parseLocFile({\n filePath: filePath,\n content: fileContents,\n terminal: this._options.terminal!,\n resxNewlineNormalization: options.resxNewlineNormalization,\n ignoreMissingResxComments: options.ignoreMissingResxComments\n });\n\n const typings: IStringValueTyping[] = [];\n\n // eslint-disable-next-line guard-for-in\n for (const stringName in locFileData) {\n typings.push({\n exportName: stringName,\n comment: locFileData[stringName].comment\n });\n }\n\n return { typings };\n }\n });\n }\n}\n"]}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { IPseudolocaleOptions } from './interfaces';
|
|
2
|
+
/**
|
|
3
|
+
* Get a function that pseudolocalizes a string.
|
|
4
|
+
*
|
|
5
|
+
* @public
|
|
6
|
+
*/
|
|
7
|
+
export declare function getPseudolocalizer(options: IPseudolocaleOptions): (str: string) => string;
|
|
8
|
+
//# sourceMappingURL=Pseudolocalization.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Pseudolocalization.d.ts","sourceRoot":"","sources":["../src/Pseudolocalization.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,oBAAoB,EAAE,MAAM,cAAc,CAAC;AAEpD;;;;GAIG;AACH,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,oBAAoB,GAAG,CAAC,GAAG,EAAE,MAAM,KAAK,MAAM,CAUzF"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license.
|
|
3
|
+
// See LICENSE in the project root for license information.
|
|
4
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
5
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
6
|
+
};
|
|
7
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
8
|
+
exports.getPseudolocalizer = void 0;
|
|
9
|
+
const decache_1 = __importDefault(require("decache"));
|
|
10
|
+
/**
|
|
11
|
+
* Get a function that pseudolocalizes a string.
|
|
12
|
+
*
|
|
13
|
+
* @public
|
|
14
|
+
*/
|
|
15
|
+
function getPseudolocalizer(options) {
|
|
16
|
+
// pseudolocale maintains static state, so we need to load it as isolated modules
|
|
17
|
+
(0, decache_1.default)('pseudolocale');
|
|
18
|
+
const pseudolocale = require('pseudolocale'); // eslint-disable-line
|
|
19
|
+
pseudolocale.option = Object.assign(Object.assign({}, pseudolocale.option), options);
|
|
20
|
+
return pseudolocale.str;
|
|
21
|
+
}
|
|
22
|
+
exports.getPseudolocalizer = getPseudolocalizer;
|
|
23
|
+
//# sourceMappingURL=Pseudolocalization.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Pseudolocalization.js","sourceRoot":"","sources":["../src/Pseudolocalization.ts"],"names":[],"mappings":";AAAA,4FAA4F;AAC5F,2DAA2D;;;;;;AAE3D,sDAA8B;AAI9B;;;;GAIG;AACH,SAAgB,kBAAkB,CAAC,OAA6B;IAC9D,iFAAiF;IACjF,IAAA,iBAAO,EAAC,cAAc,CAAC,CAAC;IACxB,MAAM,YAAY,GAAG,OAAO,CAAC,cAAc,CAAC,CAAC,CAAC,sBAAsB;IAEpE,YAAY,CAAC,MAAM,mCACd,YAAY,CAAC,MAAM,GACnB,OAAO,CACX,CAAC;IACF,OAAO,YAAY,CAAC,GAAG,CAAC;AAC1B,CAAC;AAVD,gDAUC","sourcesContent":["// Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license.\n// See LICENSE in the project root for license information.\n\nimport decache from 'decache';\n\nimport { IPseudolocaleOptions } from './interfaces';\n\n/**\n * Get a function that pseudolocalizes a string.\n *\n * @public\n */\nexport function getPseudolocalizer(options: IPseudolocaleOptions): (str: string) => string {\n // pseudolocale maintains static state, so we need to load it as isolated modules\n decache('pseudolocale');\n const pseudolocale = require('pseudolocale'); // eslint-disable-line\n\n pseudolocale.option = {\n ...pseudolocale.option,\n ...options\n };\n return pseudolocale.str;\n}\n"]}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { ITerminal, NewlineKind } from '@rushstack/node-core-library';
|
|
2
|
+
import { ILocalizationFile } from './interfaces';
|
|
3
|
+
/**
|
|
4
|
+
* @public
|
|
5
|
+
*/
|
|
6
|
+
export interface IResxReaderOptions {
|
|
7
|
+
resxFilePath: string;
|
|
8
|
+
terminal: ITerminal;
|
|
9
|
+
newlineNormalization: NewlineKind | undefined;
|
|
10
|
+
warnOnMissingComment: boolean;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* @public
|
|
14
|
+
*/
|
|
15
|
+
export declare function readResxFileAsLocFile(options: IResxReaderOptions): ILocalizationFile;
|
|
16
|
+
/**
|
|
17
|
+
* @public
|
|
18
|
+
*/
|
|
19
|
+
export declare function readResxAsLocFile(resxContents: string, options: IResxReaderOptions): ILocalizationFile;
|
|
20
|
+
//# sourceMappingURL=ResxReader.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ResxReader.d.ts","sourceRoot":"","sources":["../src/ResxReader.ts"],"names":[],"mappings":"AAGA,OAAO,EAAc,SAAS,EAAQ,WAAW,EAAE,MAAM,8BAA8B,CAAC;AAGxF,OAAO,EAAoB,iBAAiB,EAAE,MAAM,cAAc,CAAC;AAInE;;GAEG;AACH,MAAM,WAAW,kBAAkB;IACjC,YAAY,EAAE,MAAM,CAAC;IACrB,QAAQ,EAAE,SAAS,CAAC;IACpB,oBAAoB,EAAE,WAAW,GAAG,SAAS,CAAC;IAC9C,oBAAoB,EAAE,OAAO,CAAC;CAC/B;AAcD;;GAEG;AACH,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,kBAAkB,GAAG,iBAAiB,CAGpF;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,YAAY,EAAE,MAAM,EAAE,OAAO,EAAE,kBAAkB,GAAG,iBAAiB,CAmBtG"}
|
|
@@ -0,0 +1,207 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license.
|
|
3
|
+
// See LICENSE in the project root for license information.
|
|
4
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
5
|
+
exports.readResxAsLocFile = exports.readResxFileAsLocFile = void 0;
|
|
6
|
+
const node_core_library_1 = require("@rushstack/node-core-library");
|
|
7
|
+
const xmldoc_1 = require("xmldoc");
|
|
8
|
+
const STRING_NAME_RESX = /^[A-z_$][A-z0-9_$]*$/;
|
|
9
|
+
/**
|
|
10
|
+
* @public
|
|
11
|
+
*/
|
|
12
|
+
function readResxFileAsLocFile(options) {
|
|
13
|
+
const resxContents = node_core_library_1.FileSystem.readFile(options.resxFilePath);
|
|
14
|
+
return readResxAsLocFile(resxContents, options);
|
|
15
|
+
}
|
|
16
|
+
exports.readResxFileAsLocFile = readResxFileAsLocFile;
|
|
17
|
+
/**
|
|
18
|
+
* @public
|
|
19
|
+
*/
|
|
20
|
+
function readResxAsLocFile(resxContents, options) {
|
|
21
|
+
const writeError = options.terminal.writeErrorLine.bind(options.terminal);
|
|
22
|
+
const writeWarning = options.terminal.writeWarningLine.bind(options.terminal);
|
|
23
|
+
const loggingFunctions = {
|
|
24
|
+
logError: (message) => writeError(message),
|
|
25
|
+
logWarning: (message) => writeWarning(message),
|
|
26
|
+
logFileError: (message, filePath, line, position) => {
|
|
27
|
+
_logWithLocation(writeError, message, filePath, line, position);
|
|
28
|
+
},
|
|
29
|
+
logFileWarning: (message, filePath, line, position) => {
|
|
30
|
+
_logWithLocation(writeWarning, message, filePath, line, position);
|
|
31
|
+
}
|
|
32
|
+
};
|
|
33
|
+
return _readResxAsLocFileInternal(Object.assign(Object.assign({}, options), { resxContents,
|
|
34
|
+
loggingFunctions }));
|
|
35
|
+
}
|
|
36
|
+
exports.readResxAsLocFile = readResxAsLocFile;
|
|
37
|
+
function _readResxAsLocFileInternal(options) {
|
|
38
|
+
const xmlDocument = new xmldoc_1.XmlDocument(options.resxContents);
|
|
39
|
+
if (xmlDocument.name !== 'root') {
|
|
40
|
+
_logErrorWithLocation(options, `Expected RESX to have a "root" element, found "${xmlDocument.name}"`, xmlDocument);
|
|
41
|
+
}
|
|
42
|
+
const locFile = {};
|
|
43
|
+
for (const childNode of xmlDocument.children) {
|
|
44
|
+
switch (childNode.type) {
|
|
45
|
+
case 'element': {
|
|
46
|
+
switch (childNode.name) {
|
|
47
|
+
case 'data': {
|
|
48
|
+
const stringName = childNode.attr.name;
|
|
49
|
+
if (!stringName) {
|
|
50
|
+
_logErrorWithLocation(options, 'Unexpected missing or empty string name', childNode);
|
|
51
|
+
}
|
|
52
|
+
else if (!STRING_NAME_RESX.test(stringName)) {
|
|
53
|
+
_logErrorWithLocation(options, `Invalid string name "${stringName}"`, childNode);
|
|
54
|
+
}
|
|
55
|
+
else {
|
|
56
|
+
if (locFile.hasOwnProperty(stringName)) {
|
|
57
|
+
_logErrorWithLocation(options, `Duplicate string value "${stringName}"`, childNode);
|
|
58
|
+
}
|
|
59
|
+
const locString = _readDataElement(options, childNode);
|
|
60
|
+
if (locString) {
|
|
61
|
+
locFile[stringName] = locString;
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
break;
|
|
65
|
+
}
|
|
66
|
+
// Other allowed elements
|
|
67
|
+
case 'xsd:schema':
|
|
68
|
+
case 'resheader':
|
|
69
|
+
break;
|
|
70
|
+
default:
|
|
71
|
+
_logErrorWithLocation(options, `Unexpected RESX element ${childNode.name}`, childNode);
|
|
72
|
+
}
|
|
73
|
+
break;
|
|
74
|
+
}
|
|
75
|
+
case 'text': {
|
|
76
|
+
if (childNode.text.trim() !== '') {
|
|
77
|
+
_logErrorWithLocation(options, 'Found unexpected non-empty text node in RESX');
|
|
78
|
+
}
|
|
79
|
+
break;
|
|
80
|
+
}
|
|
81
|
+
case 'comment':
|
|
82
|
+
break;
|
|
83
|
+
default:
|
|
84
|
+
_logErrorWithLocation(options, `Unexpected ${childNode.type} child in RESX`);
|
|
85
|
+
break;
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
return locFile;
|
|
89
|
+
}
|
|
90
|
+
function _readDataElement(options, dataElement) {
|
|
91
|
+
let foundCommentElement = false;
|
|
92
|
+
let foundValueElement = false;
|
|
93
|
+
let comment = undefined;
|
|
94
|
+
let value = undefined;
|
|
95
|
+
for (const childNode of dataElement.children) {
|
|
96
|
+
switch (childNode.type) {
|
|
97
|
+
case 'element': {
|
|
98
|
+
switch (childNode.name) {
|
|
99
|
+
case 'value': {
|
|
100
|
+
if (foundValueElement) {
|
|
101
|
+
_logErrorWithLocation(options, 'Duplicate <value> element found', childNode);
|
|
102
|
+
}
|
|
103
|
+
else {
|
|
104
|
+
foundValueElement = true;
|
|
105
|
+
value = _readTextElement(options, childNode);
|
|
106
|
+
if (value && options.newlineNormalization) {
|
|
107
|
+
value = node_core_library_1.Text.convertTo(value, options.newlineNormalization);
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
break;
|
|
111
|
+
}
|
|
112
|
+
case 'comment': {
|
|
113
|
+
if (foundCommentElement) {
|
|
114
|
+
_logErrorWithLocation(options, 'Duplicate <comment> element found', childNode);
|
|
115
|
+
}
|
|
116
|
+
else {
|
|
117
|
+
foundCommentElement = true;
|
|
118
|
+
comment = _readTextElement(options, childNode);
|
|
119
|
+
}
|
|
120
|
+
break;
|
|
121
|
+
}
|
|
122
|
+
default:
|
|
123
|
+
_logErrorWithLocation(options, `Unexpected RESX element ${childNode.name}`, childNode);
|
|
124
|
+
break;
|
|
125
|
+
}
|
|
126
|
+
break;
|
|
127
|
+
}
|
|
128
|
+
case 'text': {
|
|
129
|
+
if (childNode.text.trim() !== '') {
|
|
130
|
+
_logErrorWithLocation(options, 'Found unexpected non-empty text node in RESX <data> element', dataElement);
|
|
131
|
+
}
|
|
132
|
+
break;
|
|
133
|
+
}
|
|
134
|
+
case 'comment':
|
|
135
|
+
break;
|
|
136
|
+
default:
|
|
137
|
+
_logErrorWithLocation(options, `Unexpected ${childNode.type} child in RESX <data> element`, dataElement);
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
if (!foundValueElement) {
|
|
141
|
+
_logErrorWithLocation(options, 'Missing string value in <data> element', dataElement);
|
|
142
|
+
}
|
|
143
|
+
else {
|
|
144
|
+
if (comment === undefined && options.warnOnMissingComment) {
|
|
145
|
+
_logWarningWithLocation(options, 'Missing string comment in <data> element', dataElement);
|
|
146
|
+
}
|
|
147
|
+
return {
|
|
148
|
+
value: value || '',
|
|
149
|
+
comment
|
|
150
|
+
};
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
function _readTextElement(options, element) {
|
|
154
|
+
let foundText = undefined;
|
|
155
|
+
for (const childNode of element.children) {
|
|
156
|
+
switch (childNode.type) {
|
|
157
|
+
case 'cdata':
|
|
158
|
+
case 'text': {
|
|
159
|
+
if (foundText !== undefined) {
|
|
160
|
+
_logErrorWithLocation(options, 'More than one child node found containing text content', element);
|
|
161
|
+
break;
|
|
162
|
+
}
|
|
163
|
+
foundText = childNode.type === 'text' ? childNode.text : childNode.cdata;
|
|
164
|
+
break;
|
|
165
|
+
}
|
|
166
|
+
case 'comment':
|
|
167
|
+
break;
|
|
168
|
+
case 'element':
|
|
169
|
+
_logErrorWithLocation(options, `Unexpected element`, childNode);
|
|
170
|
+
break;
|
|
171
|
+
default:
|
|
172
|
+
_logErrorWithLocation(options, `Unexpected ${element.type} child`, element);
|
|
173
|
+
break;
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
return foundText;
|
|
177
|
+
}
|
|
178
|
+
function _logErrorWithLocation(options, message, element) {
|
|
179
|
+
if (element) {
|
|
180
|
+
options.loggingFunctions.logFileError(message, options.resxFilePath, element.line + 1, element.column + 1);
|
|
181
|
+
}
|
|
182
|
+
else {
|
|
183
|
+
options.loggingFunctions.logFileError(message, options.resxFilePath);
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
function _logWarningWithLocation(options, message, element) {
|
|
187
|
+
if (element) {
|
|
188
|
+
options.loggingFunctions.logFileWarning(message, options.resxFilePath, element.line + 1, element.column + 1);
|
|
189
|
+
}
|
|
190
|
+
else {
|
|
191
|
+
options.loggingFunctions.logFileWarning(message, options.resxFilePath);
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
function _logWithLocation(loggingFn, message, filePath, line, position) {
|
|
195
|
+
let location;
|
|
196
|
+
if (position !== undefined) {
|
|
197
|
+
location = `${filePath}(${line},${position})`;
|
|
198
|
+
}
|
|
199
|
+
else if (line !== undefined) {
|
|
200
|
+
location = `${filePath}(${line})`;
|
|
201
|
+
}
|
|
202
|
+
else {
|
|
203
|
+
location = filePath;
|
|
204
|
+
}
|
|
205
|
+
loggingFn(`${location}: ${message}`);
|
|
206
|
+
}
|
|
207
|
+
//# sourceMappingURL=ResxReader.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ResxReader.js","sourceRoot":"","sources":["../src/ResxReader.ts"],"names":[],"mappings":"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","sourcesContent":["// Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license.\n// See LICENSE in the project root for license information.\n\nimport { FileSystem, ITerminal, Text, NewlineKind } from '@rushstack/node-core-library';\nimport { XmlDocument, XmlElement } from 'xmldoc';\n\nimport { ILocalizedString, ILocalizationFile } from './interfaces';\n\nconst STRING_NAME_RESX: RegExp = /^[A-z_$][A-z0-9_$]*$/;\n\n/**\n * @public\n */\nexport interface IResxReaderOptions {\n resxFilePath: string;\n terminal: ITerminal;\n newlineNormalization: NewlineKind | undefined;\n warnOnMissingComment: boolean;\n}\n\ninterface ILoggingFunctions {\n logError: (message: string) => void;\n logWarning: (message: string) => void;\n logFileError: (message: string, filePath: string, line?: number, position?: number) => void;\n logFileWarning: (message: string, filePath: string, line?: number, position?: number) => void;\n}\n\ninterface IResxReaderOptionsInternal extends Omit<IResxReaderOptions, 'terminal'> {\n resxContents: string;\n loggingFunctions: ILoggingFunctions;\n}\n\n/**\n * @public\n */\nexport function readResxFileAsLocFile(options: IResxReaderOptions): ILocalizationFile {\n const resxContents: string = FileSystem.readFile(options.resxFilePath);\n return readResxAsLocFile(resxContents, options);\n}\n\n/**\n * @public\n */\nexport function readResxAsLocFile(resxContents: string, options: IResxReaderOptions): ILocalizationFile {\n const writeError: (message: string) => void = options.terminal.writeErrorLine.bind(options.terminal);\n const writeWarning: (message: string) => void = options.terminal.writeWarningLine.bind(options.terminal);\n const loggingFunctions: ILoggingFunctions = {\n logError: (message: string) => writeError(message),\n logWarning: (message: string) => writeWarning(message),\n logFileError: (message: string, filePath: string, line?: number, position?: number) => {\n _logWithLocation(writeError, message, filePath, line, position);\n },\n logFileWarning: (message: string, filePath: string, line?: number, position?: number) => {\n _logWithLocation(writeWarning, message, filePath, line, position);\n }\n };\n\n return _readResxAsLocFileInternal({\n ...options,\n resxContents,\n loggingFunctions\n });\n}\n\nfunction _readResxAsLocFileInternal(options: IResxReaderOptionsInternal): ILocalizationFile {\n const xmlDocument: XmlDocument = new XmlDocument(options.resxContents);\n\n if (xmlDocument.name !== 'root') {\n _logErrorWithLocation(\n options,\n `Expected RESX to have a \"root\" element, found \"${xmlDocument.name}\"`,\n xmlDocument\n );\n }\n\n const locFile: ILocalizationFile = {};\n\n for (const childNode of xmlDocument.children) {\n switch (childNode.type) {\n case 'element': {\n switch (childNode.name) {\n case 'data': {\n const stringName: string = childNode.attr.name;\n if (!stringName) {\n _logErrorWithLocation(options, 'Unexpected missing or empty string name', childNode);\n } else if (!STRING_NAME_RESX.test(stringName)) {\n _logErrorWithLocation(options, `Invalid string name \"${stringName}\"`, childNode);\n } else {\n if (locFile.hasOwnProperty(stringName)) {\n _logErrorWithLocation(options, `Duplicate string value \"${stringName}\"`, childNode);\n }\n\n const locString: ILocalizedString | undefined = _readDataElement(options, childNode);\n\n if (locString) {\n locFile[stringName] = locString;\n }\n }\n\n break;\n }\n\n // Other allowed elements\n case 'xsd:schema':\n case 'resheader':\n break;\n\n default:\n _logErrorWithLocation(options, `Unexpected RESX element ${childNode.name}`, childNode);\n }\n\n break;\n }\n\n case 'text': {\n if (childNode.text.trim() !== '') {\n _logErrorWithLocation(options, 'Found unexpected non-empty text node in RESX');\n }\n\n break;\n }\n\n case 'comment':\n break;\n\n default:\n _logErrorWithLocation(options, `Unexpected ${childNode.type} child in RESX`);\n break;\n }\n }\n\n return locFile;\n}\n\nfunction _readDataElement(\n options: IResxReaderOptionsInternal,\n dataElement: XmlElement\n): ILocalizedString | undefined {\n let foundCommentElement: boolean = false;\n let foundValueElement: boolean = false;\n let comment: string | undefined = undefined;\n let value: string | undefined = undefined;\n\n for (const childNode of dataElement.children) {\n switch (childNode.type) {\n case 'element': {\n switch (childNode.name) {\n case 'value': {\n if (foundValueElement) {\n _logErrorWithLocation(options, 'Duplicate <value> element found', childNode);\n } else {\n foundValueElement = true;\n value = _readTextElement(options, childNode);\n if (value && options.newlineNormalization) {\n value = Text.convertTo(value, options.newlineNormalization);\n }\n }\n\n break;\n }\n\n case 'comment': {\n if (foundCommentElement) {\n _logErrorWithLocation(options, 'Duplicate <comment> element found', childNode);\n } else {\n foundCommentElement = true;\n comment = _readTextElement(options, childNode);\n }\n\n break;\n }\n\n default:\n _logErrorWithLocation(options, `Unexpected RESX element ${childNode.name}`, childNode);\n break;\n }\n\n break;\n }\n\n case 'text': {\n if (childNode.text.trim() !== '') {\n _logErrorWithLocation(\n options,\n 'Found unexpected non-empty text node in RESX <data> element',\n dataElement\n );\n }\n\n break;\n }\n\n case 'comment':\n break;\n\n default:\n _logErrorWithLocation(\n options,\n `Unexpected ${childNode.type} child in RESX <data> element`,\n dataElement\n );\n }\n }\n\n if (!foundValueElement) {\n _logErrorWithLocation(options, 'Missing string value in <data> element', dataElement);\n } else {\n if (comment === undefined && options.warnOnMissingComment) {\n _logWarningWithLocation(options, 'Missing string comment in <data> element', dataElement);\n }\n\n return {\n value: value || '',\n comment\n };\n }\n}\n\nfunction _readTextElement(options: IResxReaderOptionsInternal, element: XmlElement): string | undefined {\n let foundText: string | undefined = undefined;\n\n for (const childNode of element.children) {\n switch (childNode.type) {\n case 'cdata':\n case 'text': {\n if (foundText !== undefined) {\n _logErrorWithLocation(options, 'More than one child node found containing text content', element);\n break;\n }\n\n foundText = childNode.type === 'text' ? childNode.text : childNode.cdata;\n break;\n }\n\n case 'comment':\n break;\n\n case 'element':\n _logErrorWithLocation(options, `Unexpected element`, childNode);\n break;\n\n default:\n _logErrorWithLocation(options, `Unexpected ${element.type} child`, element);\n break;\n }\n }\n\n return foundText;\n}\n\nfunction _logErrorWithLocation(\n options: IResxReaderOptionsInternal,\n message: string,\n element?: XmlElement | XmlDocument\n): void {\n if (element) {\n options.loggingFunctions.logFileError(\n message,\n options.resxFilePath,\n element.line + 1,\n element.column + 1\n );\n } else {\n options.loggingFunctions.logFileError(message, options.resxFilePath);\n }\n}\n\nfunction _logWarningWithLocation(\n options: IResxReaderOptionsInternal,\n message: string,\n element?: XmlElement | XmlDocument\n): void {\n if (element) {\n options.loggingFunctions.logFileWarning(\n message,\n options.resxFilePath,\n element.line + 1,\n element.column + 1\n );\n } else {\n options.loggingFunctions.logFileWarning(message, options.resxFilePath);\n }\n}\n\nfunction _logWithLocation(\n loggingFn: (message: string) => void,\n message: string,\n filePath: string,\n line?: number,\n position?: number\n): void {\n let location: string;\n if (position !== undefined) {\n location = `${filePath}(${line},${position})`;\n } else if (line !== undefined) {\n location = `${filePath}(${line})`;\n } else {\n location = filePath;\n }\n\n loggingFn(`${location}: ${message}`);\n}\n"]}
|
package/lib/index.d.ts
ADDED
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export { ILocalizationFile, ILocalizedString, IPseudolocaleOptions } from './interfaces';
|
|
2
|
+
export { parseLocFile, IParseLocFileOptions } from './LocFileParser';
|
|
3
|
+
export { ITypingsGeneratorOptions, LocFileTypingsGenerator as TypingsGenerator } from './LocFileTypingsGenerator';
|
|
4
|
+
export { readResxFileAsLocFile, readResxAsLocFile, IResxReaderOptions } from './ResxReader';
|
|
5
|
+
export { getPseudolocalizer } from './Pseudolocalization';
|
|
6
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,oBAAoB,EAAE,MAAM,cAAc,CAAC;AACzF,OAAO,EAAE,YAAY,EAAE,oBAAoB,EAAE,MAAM,iBAAiB,CAAC;AACrE,OAAO,EACL,wBAAwB,EACxB,uBAAuB,IAAI,gBAAgB,EAC5C,MAAM,2BAA2B,CAAC;AACnC,OAAO,EAAE,qBAAqB,EAAE,iBAAiB,EAAE,kBAAkB,EAAE,MAAM,cAAc,CAAC;AAC5F,OAAO,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC"}
|
package/lib/index.js
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license.
|
|
3
|
+
// See LICENSE in the project root for license information.
|
|
4
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
5
|
+
exports.getPseudolocalizer = exports.readResxAsLocFile = exports.readResxFileAsLocFile = exports.TypingsGenerator = exports.parseLocFile = void 0;
|
|
6
|
+
var LocFileParser_1 = require("./LocFileParser");
|
|
7
|
+
Object.defineProperty(exports, "parseLocFile", { enumerable: true, get: function () { return LocFileParser_1.parseLocFile; } });
|
|
8
|
+
var LocFileTypingsGenerator_1 = require("./LocFileTypingsGenerator");
|
|
9
|
+
Object.defineProperty(exports, "TypingsGenerator", { enumerable: true, get: function () { return LocFileTypingsGenerator_1.LocFileTypingsGenerator; } });
|
|
10
|
+
var ResxReader_1 = require("./ResxReader");
|
|
11
|
+
Object.defineProperty(exports, "readResxFileAsLocFile", { enumerable: true, get: function () { return ResxReader_1.readResxFileAsLocFile; } });
|
|
12
|
+
Object.defineProperty(exports, "readResxAsLocFile", { enumerable: true, get: function () { return ResxReader_1.readResxAsLocFile; } });
|
|
13
|
+
var Pseudolocalization_1 = require("./Pseudolocalization");
|
|
14
|
+
Object.defineProperty(exports, "getPseudolocalizer", { enumerable: true, get: function () { return Pseudolocalization_1.getPseudolocalizer; } });
|
|
15
|
+
//# sourceMappingURL=index.js.map
|
package/lib/index.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAAA,4FAA4F;AAC5F,2DAA2D;;;AAG3D,iDAAqE;AAA5D,6GAAA,YAAY,OAAA;AACrB,qEAGmC;AADjC,2HAAA,uBAAuB,OAAoB;AAE7C,2CAA4F;AAAnF,mHAAA,qBAAqB,OAAA;AAAE,+GAAA,iBAAiB,OAAA;AACjD,2DAA0D;AAAjD,wHAAA,kBAAkB,OAAA","sourcesContent":["// Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license.\n// See LICENSE in the project root for license information.\n\nexport { ILocalizationFile, ILocalizedString, IPseudolocaleOptions } from './interfaces';\nexport { parseLocFile, IParseLocFileOptions } from './LocFileParser';\nexport {\n ITypingsGeneratorOptions,\n LocFileTypingsGenerator as TypingsGenerator\n} from './LocFileTypingsGenerator';\nexport { readResxFileAsLocFile, readResxAsLocFile, IResxReaderOptions } from './ResxReader';\nexport { getPseudolocalizer } from './Pseudolocalization';\n"]}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Options for the pseudolocale library.
|
|
3
|
+
*
|
|
4
|
+
* @internalRemarks
|
|
5
|
+
* Eventually this should be replaced with DefinitelyTyped types.
|
|
6
|
+
*
|
|
7
|
+
* @public
|
|
8
|
+
*/
|
|
9
|
+
export interface IPseudolocaleOptions {
|
|
10
|
+
prepend?: string;
|
|
11
|
+
append?: string;
|
|
12
|
+
delimiter?: string;
|
|
13
|
+
startDelimiter?: string;
|
|
14
|
+
endDelimiter?: string;
|
|
15
|
+
extend?: number;
|
|
16
|
+
override?: string;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* @public
|
|
20
|
+
*/
|
|
21
|
+
export interface ILocalizationFile {
|
|
22
|
+
[stringName: string]: ILocalizedString;
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* @public
|
|
26
|
+
*/
|
|
27
|
+
export interface ILocalizedString {
|
|
28
|
+
value: string;
|
|
29
|
+
comment?: string;
|
|
30
|
+
}
|
|
31
|
+
//# sourceMappingURL=interfaces.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"interfaces.d.ts","sourceRoot":"","sources":["../src/interfaces.ts"],"names":[],"mappings":"AAGA;;;;;;;GAOG;AACH,MAAM,WAAW,oBAAoB;IACnC,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED;;GAEG;AACH,MAAM,WAAW,iBAAiB;IAChC,CAAC,UAAU,EAAE,MAAM,GAAG,gBAAgB,CAAC;CACxC;AAED;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB"}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license.
|
|
3
|
+
// See LICENSE in the project root for license information.
|
|
4
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
5
|
+
//# sourceMappingURL=interfaces.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"interfaces.js","sourceRoot":"","sources":["../src/interfaces.ts"],"names":[],"mappings":";AAAA,4FAA4F;AAC5F,2DAA2D","sourcesContent":["// Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license.\n// See LICENSE in the project root for license information.\n\n/**\n * Options for the pseudolocale library.\n *\n * @internalRemarks\n * Eventually this should be replaced with DefinitelyTyped types.\n *\n * @public\n */\nexport interface IPseudolocaleOptions {\n prepend?: string;\n append?: string;\n delimiter?: string;\n startDelimiter?: string;\n endDelimiter?: string;\n extend?: number;\n override?: string;\n}\n\n/**\n * @public\n */\nexport interface ILocalizationFile {\n [stringName: string]: ILocalizedString;\n}\n\n/**\n * @public\n */\nexport interface ILocalizedString {\n value: string;\n comment?: string;\n}\n"]}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "http://json-schema.org/draft-04/schema#",
|
|
3
|
+
"title": "Localizable JSON file",
|
|
4
|
+
|
|
5
|
+
"properties": {
|
|
6
|
+
"$schema": {
|
|
7
|
+
"description": "Part of the JSON Schema standard, this optional keyword declares the URL of the schema that the file conforms to. Editors may download the schema and use it to perform syntax highlighting.",
|
|
8
|
+
"type": "string"
|
|
9
|
+
}
|
|
10
|
+
},
|
|
11
|
+
"patternProperties": {
|
|
12
|
+
"^[A-Za-z_][0-9A-Za-z_]*$": {
|
|
13
|
+
"type": "object",
|
|
14
|
+
"properties": {
|
|
15
|
+
"value": {
|
|
16
|
+
"type": "string"
|
|
17
|
+
},
|
|
18
|
+
"comment": {
|
|
19
|
+
"type": "string"
|
|
20
|
+
}
|
|
21
|
+
},
|
|
22
|
+
"additionalProperties": false,
|
|
23
|
+
"required": ["value"]
|
|
24
|
+
}
|
|
25
|
+
},
|
|
26
|
+
"additionalProperties": false,
|
|
27
|
+
"type": "object"
|
|
28
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@rushstack/localization-utilities",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "This plugin contains some useful functions for localization.",
|
|
5
|
+
"main": "lib/index.js",
|
|
6
|
+
"typings": "dist/localization-utilities.d.ts",
|
|
7
|
+
"license": "MIT",
|
|
8
|
+
"repository": {
|
|
9
|
+
"type": "git",
|
|
10
|
+
"url": "https://github.com/microsoft/rushstack.git",
|
|
11
|
+
"directory": "libraries/localization-utilities"
|
|
12
|
+
},
|
|
13
|
+
"dependencies": {
|
|
14
|
+
"@rushstack/node-core-library": "3.45.5",
|
|
15
|
+
"@rushstack/typings-generator": "0.6.25",
|
|
16
|
+
"decache": "~4.5.1",
|
|
17
|
+
"pseudolocale": "~1.1.0",
|
|
18
|
+
"xmldoc": "~1.1.2"
|
|
19
|
+
},
|
|
20
|
+
"devDependencies": {
|
|
21
|
+
"@rushstack/eslint-config": "2.6.0",
|
|
22
|
+
"@rushstack/heft": "0.45.5",
|
|
23
|
+
"@rushstack/heft-node-rig": "1.9.6",
|
|
24
|
+
"@types/node": "12.20.24",
|
|
25
|
+
"@types/xmldoc": "1.1.4"
|
|
26
|
+
},
|
|
27
|
+
"scripts": {
|
|
28
|
+
"build": "heft build --clean",
|
|
29
|
+
"_phase:build": "heft build --clean"
|
|
30
|
+
},
|
|
31
|
+
"readme": "# @rushstack/localization-utilities\n\nThis library provides a set of utilities for working with localization files.\n"
|
|
32
|
+
}
|