@saykit/config 0.11.0 → 0.12.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/README.md +6 -4
- package/dist/commands/index.cjs +59 -42
- package/dist/commands/index.mjs +51 -34
- package/dist/compile-BrwRUqtQ.cjs +286 -0
- package/dist/compile-VUAk0xEx.mjs +233 -0
- package/dist/emit-NFgnvdzK.cjs +182 -0
- package/dist/emit-q78c-G_t.mjs +117 -0
- package/dist/features/catalogue/index.cjs +12 -47
- package/dist/features/catalogue/index.d.cts +38 -33
- package/dist/features/catalogue/index.d.mts +38 -33
- package/dist/features/catalogue/index.mjs +1 -39
- package/dist/features/loader/index.cjs +1 -1
- package/dist/features/loader/index.d.cts +3 -6
- package/dist/features/loader/index.d.mts +3 -6
- package/dist/features/loader/index.mjs +1 -2
- package/dist/features/messages/index.cjs +15 -65
- package/dist/features/messages/index.d.cts +109 -54
- package/dist/features/messages/index.d.mts +109 -54
- package/dist/features/messages/index.mjs +6 -60
- package/dist/index.cjs +3 -6
- package/dist/index.d.cts +19 -21
- package/dist/index.d.mts +19 -21
- package/dist/index.mjs +1 -3
- package/dist/{loader-C6XxYhMl.mjs → loader-1PBbw7yb.mjs} +3 -6
- package/dist/{loader-XE7SprlF.cjs → loader-V92j1gfD.cjs} +8 -11
- package/dist/{shapes-CRlXtss0.d.cts → shapes-Dq0aJdsn.d.cts} +50 -52
- package/dist/{shapes-CRlXtss0.d.mts → shapes-Dq0aJdsn.d.mts} +50 -52
- package/package.json +10 -5
- package/dist/hash-51ce8YiG.cjs +0 -16
- package/dist/hash-DvzpieJD.mjs +0 -11
- package/dist/storage-8485YdBh.mjs +0 -59
- package/dist/storage-DSdC-TYq.cjs +0 -94
|
@@ -1,47 +1,56 @@
|
|
|
1
|
-
import { a as Message, n as Config, t as Bucket } from "../../shapes-
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
import { a as Message, n as Config, t as Bucket } from "../../shapes-Dq0aJdsn.cjs";
|
|
2
|
+
/**
|
|
3
|
+
* Where a locale's generated module goes: beside its catalogue, as `.js`.
|
|
4
|
+
*
|
|
5
|
+
* @throws If that is the catalogue itself, as for a formatter with a `.js` extension
|
|
6
|
+
*/
|
|
7
|
+
export declare function modulePathFor(bucket: Bucket, locale: string): string;
|
|
8
|
+
/**
|
|
9
|
+
* Build the source of a locale's generated module from its assembled record.
|
|
10
|
+
*
|
|
11
|
+
* The module is plain data, so it can cross a server/client boundary as JSON.
|
|
12
|
+
*
|
|
13
|
+
* @param record The locale's messages, keyed by id, as ICU
|
|
14
|
+
*/
|
|
15
|
+
export declare function generateCatalogueModule(record: Record<string, string>): string;
|
|
16
|
+
/**
|
|
17
|
+
* Compile one locale's catalogue, and its fallbacks, into a module on disk.
|
|
18
|
+
*
|
|
19
|
+
* The fallback chain is merged here, so the app still imports one module per locale.
|
|
20
|
+
*/
|
|
21
|
+
export declare function emitCatalogueModule(config: Config, bucket: Bucket, locale: string): Promise<{
|
|
22
|
+
path: string;
|
|
23
|
+
count: number;
|
|
24
|
+
}>;
|
|
25
|
+
export declare function mergeExtractedMessages(messages: Message[]): {
|
|
4
26
|
message: string;
|
|
5
|
-
comments: string[];
|
|
6
|
-
references: string[];
|
|
7
27
|
translation?: string | undefined;
|
|
8
28
|
id?: string | undefined;
|
|
9
29
|
context?: string | undefined;
|
|
10
|
-
}[];
|
|
11
|
-
declare function pruneLocaleMessages(existingMessages: Message[], sourceMessages: Message[]): {
|
|
12
|
-
message: string;
|
|
13
30
|
comments: string[];
|
|
14
31
|
references: string[];
|
|
32
|
+
}[];
|
|
33
|
+
export declare function pruneLocaleMessages(existingMessages: Message[], sourceMessages: Message[]): {
|
|
34
|
+
message: string;
|
|
15
35
|
translation?: string | undefined;
|
|
16
36
|
id?: string | undefined;
|
|
17
37
|
context?: string | undefined;
|
|
38
|
+
comments: string[];
|
|
39
|
+
references: string[];
|
|
18
40
|
}[];
|
|
19
|
-
|
|
20
|
-
//#region src/features/catalogue/path.d.ts
|
|
21
|
-
declare function expandBucketOutputPath(bucket: Bucket, locale: string, extension?: `.${string}`): string;
|
|
22
|
-
/**
|
|
23
|
-
* The declaration file that types a catalogue, e.g. `en.json` -> `en.d.json.ts`.
|
|
24
|
-
*
|
|
25
|
-
* TypeScript resolves `./en.json` by stripping the extension and looking for
|
|
26
|
-
* `en.d.json.ts`; the `en.json.d.ts` form is only consulted for extensions the
|
|
27
|
-
* resolver does not recognise. Non-JS extensions additionally require
|
|
28
|
-
* `allowArbitraryExtensions` in the consumer's tsconfig.
|
|
29
|
-
*/
|
|
30
|
-
declare function declarationPathFor(cataloguePath: string): string;
|
|
31
|
-
//#endregion
|
|
32
|
-
//#region src/features/catalogue/record.d.ts
|
|
41
|
+
export declare function expandBucketOutputPath(bucket: Bucket, locale: string, extension?: `.${string}`): string;
|
|
33
42
|
/**
|
|
34
43
|
* Resolve the fallback chain for a locale, most specific first. The source
|
|
35
44
|
* locale (the first configured locale) is always the final fallback, so an
|
|
36
45
|
* untranslated key ultimately resolves to the source string.
|
|
37
46
|
*/
|
|
38
|
-
declare function resolveFallbackChain(config: Config, locale: string): string[];
|
|
47
|
+
export declare function resolveFallbackChain(config: Config, locale: string): string[];
|
|
39
48
|
/**
|
|
40
49
|
* Resolve the catalogue files that contribute to a locale module, most specific
|
|
41
50
|
* first. When the path does not map to a configured locale it is loaded on its
|
|
42
51
|
* own.
|
|
43
52
|
*/
|
|
44
|
-
declare function resolveCatalogueSources(config: Config, bucket: Bucket, path: string): {
|
|
53
|
+
export declare function resolveCatalogueSources(config: Config, bucket: Bucket, path: string): {
|
|
45
54
|
locale: string | undefined;
|
|
46
55
|
sources: string[];
|
|
47
56
|
};
|
|
@@ -51,17 +60,13 @@ declare function resolveCatalogueSources(config: Config, bucket: Bucket, path: s
|
|
|
51
60
|
* (most specific first): more specific locales override their fallbacks, and any
|
|
52
61
|
* key still untranslated falls back to its source message.
|
|
53
62
|
*/
|
|
54
|
-
declare function assembleCatalogueRecord(bucket: Bucket, contents: string[]): Record<string, string>;
|
|
55
|
-
|
|
56
|
-
//#region src/features/catalogue/storage.d.ts
|
|
57
|
-
declare function readCatalogueMessages(bucket: Bucket, locale: string, path?: string): Promise<{
|
|
63
|
+
export declare function assembleCatalogueRecord(bucket: Bucket, contents: string[]): Record<string, string>;
|
|
64
|
+
export declare function readCatalogueMessages(bucket: Bucket, locale: string, path?: string): Promise<{
|
|
58
65
|
message: string;
|
|
59
|
-
comments: string[];
|
|
60
|
-
references: string[];
|
|
61
66
|
translation?: string | undefined;
|
|
62
67
|
id?: string | undefined;
|
|
63
68
|
context?: string | undefined;
|
|
69
|
+
comments: string[];
|
|
70
|
+
references: string[];
|
|
64
71
|
}[]>;
|
|
65
|
-
declare function writeCatalogueMessages(bucket: Bucket, locale: string, messages: Message[], path?: string): Promise<void>;
|
|
66
|
-
//#endregion
|
|
67
|
-
export { assembleCatalogueRecord, declarationPathFor, expandBucketOutputPath, mergeExtractedMessages, pruneLocaleMessages, readCatalogueMessages, resolveCatalogueSources, resolveFallbackChain, writeCatalogueMessages };
|
|
72
|
+
export declare function writeCatalogueMessages(bucket: Bucket, locale: string, messages: Message[], path?: string): Promise<void>;
|
|
@@ -1,47 +1,56 @@
|
|
|
1
|
-
import { a as Message, n as Config, t as Bucket } from "../../shapes-
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
import { a as Message, n as Config, t as Bucket } from "../../shapes-Dq0aJdsn.mjs";
|
|
2
|
+
/**
|
|
3
|
+
* Where a locale's generated module goes: beside its catalogue, as `.js`.
|
|
4
|
+
*
|
|
5
|
+
* @throws If that is the catalogue itself, as for a formatter with a `.js` extension
|
|
6
|
+
*/
|
|
7
|
+
export declare function modulePathFor(bucket: Bucket, locale: string): string;
|
|
8
|
+
/**
|
|
9
|
+
* Build the source of a locale's generated module from its assembled record.
|
|
10
|
+
*
|
|
11
|
+
* The module is plain data, so it can cross a server/client boundary as JSON.
|
|
12
|
+
*
|
|
13
|
+
* @param record The locale's messages, keyed by id, as ICU
|
|
14
|
+
*/
|
|
15
|
+
export declare function generateCatalogueModule(record: Record<string, string>): string;
|
|
16
|
+
/**
|
|
17
|
+
* Compile one locale's catalogue, and its fallbacks, into a module on disk.
|
|
18
|
+
*
|
|
19
|
+
* The fallback chain is merged here, so the app still imports one module per locale.
|
|
20
|
+
*/
|
|
21
|
+
export declare function emitCatalogueModule(config: Config, bucket: Bucket, locale: string): Promise<{
|
|
22
|
+
path: string;
|
|
23
|
+
count: number;
|
|
24
|
+
}>;
|
|
25
|
+
export declare function mergeExtractedMessages(messages: Message[]): {
|
|
4
26
|
message: string;
|
|
5
|
-
comments: string[];
|
|
6
|
-
references: string[];
|
|
7
27
|
translation?: string | undefined;
|
|
8
28
|
id?: string | undefined;
|
|
9
29
|
context?: string | undefined;
|
|
10
|
-
}[];
|
|
11
|
-
declare function pruneLocaleMessages(existingMessages: Message[], sourceMessages: Message[]): {
|
|
12
|
-
message: string;
|
|
13
30
|
comments: string[];
|
|
14
31
|
references: string[];
|
|
32
|
+
}[];
|
|
33
|
+
export declare function pruneLocaleMessages(existingMessages: Message[], sourceMessages: Message[]): {
|
|
34
|
+
message: string;
|
|
15
35
|
translation?: string | undefined;
|
|
16
36
|
id?: string | undefined;
|
|
17
37
|
context?: string | undefined;
|
|
38
|
+
comments: string[];
|
|
39
|
+
references: string[];
|
|
18
40
|
}[];
|
|
19
|
-
|
|
20
|
-
//#region src/features/catalogue/path.d.ts
|
|
21
|
-
declare function expandBucketOutputPath(bucket: Bucket, locale: string, extension?: `.${string}`): string;
|
|
22
|
-
/**
|
|
23
|
-
* The declaration file that types a catalogue, e.g. `en.json` -> `en.d.json.ts`.
|
|
24
|
-
*
|
|
25
|
-
* TypeScript resolves `./en.json` by stripping the extension and looking for
|
|
26
|
-
* `en.d.json.ts`; the `en.json.d.ts` form is only consulted for extensions the
|
|
27
|
-
* resolver does not recognise. Non-JS extensions additionally require
|
|
28
|
-
* `allowArbitraryExtensions` in the consumer's tsconfig.
|
|
29
|
-
*/
|
|
30
|
-
declare function declarationPathFor(cataloguePath: string): string;
|
|
31
|
-
//#endregion
|
|
32
|
-
//#region src/features/catalogue/record.d.ts
|
|
41
|
+
export declare function expandBucketOutputPath(bucket: Bucket, locale: string, extension?: `.${string}`): string;
|
|
33
42
|
/**
|
|
34
43
|
* Resolve the fallback chain for a locale, most specific first. The source
|
|
35
44
|
* locale (the first configured locale) is always the final fallback, so an
|
|
36
45
|
* untranslated key ultimately resolves to the source string.
|
|
37
46
|
*/
|
|
38
|
-
declare function resolveFallbackChain(config: Config, locale: string): string[];
|
|
47
|
+
export declare function resolveFallbackChain(config: Config, locale: string): string[];
|
|
39
48
|
/**
|
|
40
49
|
* Resolve the catalogue files that contribute to a locale module, most specific
|
|
41
50
|
* first. When the path does not map to a configured locale it is loaded on its
|
|
42
51
|
* own.
|
|
43
52
|
*/
|
|
44
|
-
declare function resolveCatalogueSources(config: Config, bucket: Bucket, path: string): {
|
|
53
|
+
export declare function resolveCatalogueSources(config: Config, bucket: Bucket, path: string): {
|
|
45
54
|
locale: string | undefined;
|
|
46
55
|
sources: string[];
|
|
47
56
|
};
|
|
@@ -51,17 +60,13 @@ declare function resolveCatalogueSources(config: Config, bucket: Bucket, path: s
|
|
|
51
60
|
* (most specific first): more specific locales override their fallbacks, and any
|
|
52
61
|
* key still untranslated falls back to its source message.
|
|
53
62
|
*/
|
|
54
|
-
declare function assembleCatalogueRecord(bucket: Bucket, contents: string[]): Record<string, string>;
|
|
55
|
-
|
|
56
|
-
//#region src/features/catalogue/storage.d.ts
|
|
57
|
-
declare function readCatalogueMessages(bucket: Bucket, locale: string, path?: string): Promise<{
|
|
63
|
+
export declare function assembleCatalogueRecord(bucket: Bucket, contents: string[]): Record<string, string>;
|
|
64
|
+
export declare function readCatalogueMessages(bucket: Bucket, locale: string, path?: string): Promise<{
|
|
58
65
|
message: string;
|
|
59
|
-
comments: string[];
|
|
60
|
-
references: string[];
|
|
61
66
|
translation?: string | undefined;
|
|
62
67
|
id?: string | undefined;
|
|
63
68
|
context?: string | undefined;
|
|
69
|
+
comments: string[];
|
|
70
|
+
references: string[];
|
|
64
71
|
}[]>;
|
|
65
|
-
declare function writeCatalogueMessages(bucket: Bucket, locale: string, messages: Message[], path?: string): Promise<void>;
|
|
66
|
-
//#endregion
|
|
67
|
-
export { assembleCatalogueRecord, declarationPathFor, expandBucketOutputPath, mergeExtractedMessages, pruneLocaleMessages, readCatalogueMessages, resolveCatalogueSources, resolveFallbackChain, writeCatalogueMessages };
|
|
72
|
+
export declare function writeCatalogueMessages(bucket: Bucket, locale: string, messages: Message[], path?: string): Promise<void>;
|
|
@@ -1,39 +1 @@
|
|
|
1
|
-
|
|
2
|
-
import { a as mergeExtractedMessages, i as expandBucketOutputPath, n as writeCatalogueMessages, o as pruneLocaleMessages, r as declarationPathFor, t as readCatalogueMessages } from "../../storage-8485YdBh.mjs";
|
|
3
|
-
import { resolve } from "node:path";
|
|
4
|
-
//#region src/features/catalogue/record.ts
|
|
5
|
-
function resolveFallbackChain(config, locale) {
|
|
6
|
-
const source = config.locales[0];
|
|
7
|
-
const configured = config.fallbackLocales?.[locale];
|
|
8
|
-
const fallbacks = configured ? Array.isArray(configured) ? configured : [configured] : [];
|
|
9
|
-
return Array.from(/* @__PURE__ */ new Set([
|
|
10
|
-
locale,
|
|
11
|
-
...fallbacks,
|
|
12
|
-
source
|
|
13
|
-
]));
|
|
14
|
-
}
|
|
15
|
-
function resolveCatalogueSources(config, bucket, path) {
|
|
16
|
-
const resolved = resolve(path);
|
|
17
|
-
const locale = config.locales.find((l) => expandBucketOutputPath(bucket, l) === resolved);
|
|
18
|
-
return {
|
|
19
|
-
locale,
|
|
20
|
-
sources: locale ? resolveFallbackChain(config, locale).map((l) => expandBucketOutputPath(bucket, l)) : [resolved]
|
|
21
|
-
};
|
|
22
|
-
}
|
|
23
|
-
function assembleCatalogueRecord(bucket, contents) {
|
|
24
|
-
const record = {};
|
|
25
|
-
for (const content of [...contents].reverse()) {
|
|
26
|
-
if (!content) continue;
|
|
27
|
-
for (const message of bucket.formatter.parse(content)) {
|
|
28
|
-
const key = message.id || generateHash(message.message, message.context);
|
|
29
|
-
if (message.translation) {
|
|
30
|
-
record[key] = message.translation;
|
|
31
|
-
continue;
|
|
32
|
-
}
|
|
33
|
-
if (!record[key] && message.message) record[key] = message.message;
|
|
34
|
-
}
|
|
35
|
-
}
|
|
36
|
-
return record;
|
|
37
|
-
}
|
|
38
|
-
//#endregion
|
|
39
|
-
export { assembleCatalogueRecord, declarationPathFor, expandBucketOutputPath, mergeExtractedMessages, pruneLocaleMessages, readCatalogueMessages, resolveCatalogueSources, resolveFallbackChain, writeCatalogueMessages };
|
|
1
|
+
export { i as assembleCatalogueRecord, t as emitCatalogueModule, l as expandBucketOutputPath, n as generateCatalogueModule, u as mergeExtractedMessages, r as modulePathFor, d as pruneLocaleMessages, s as readCatalogueMessages, a as resolveCatalogueSources, o as resolveFallbackChain, c as writeCatalogueMessages } from "../../emit-q78c-G_t.mjs";
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
|
-
const require_loader = require("../../loader-
|
|
2
|
+
const require_loader = require("../../loader-V92j1gfD.cjs");
|
|
3
3
|
exports.resolveConfig = require_loader.resolveConfig;
|
|
4
4
|
exports.resolveConfigFile = require_loader.resolveConfigFile;
|
|
@@ -1,11 +1,8 @@
|
|
|
1
|
-
import { n as Config } from "../../shapes-
|
|
2
|
-
//#region src/features/loader/resolve.d.ts
|
|
1
|
+
import { n as Config } from "../../shapes-Dq0aJdsn.cjs";
|
|
3
2
|
/**
|
|
4
3
|
* The config file {@link resolveConfig} would load, for callers that need the
|
|
5
4
|
* path itself rather than its contents, salting a bundler's cache key with it,
|
|
6
5
|
* for one, since what a catalogue assembles into depends on the config.
|
|
7
6
|
*/
|
|
8
|
-
declare function resolveConfigFile(name?: string): string;
|
|
9
|
-
declare function resolveConfig(name?: string): Config;
|
|
10
|
-
//#endregion
|
|
11
|
-
export { resolveConfig, resolveConfigFile };
|
|
7
|
+
export declare function resolveConfigFile(name?: string): string;
|
|
8
|
+
export declare function resolveConfig(name?: string): Config;
|
|
@@ -1,11 +1,8 @@
|
|
|
1
|
-
import { n as Config } from "../../shapes-
|
|
2
|
-
//#region src/features/loader/resolve.d.ts
|
|
1
|
+
import { n as Config } from "../../shapes-Dq0aJdsn.mjs";
|
|
3
2
|
/**
|
|
4
3
|
* The config file {@link resolveConfig} would load, for callers that need the
|
|
5
4
|
* path itself rather than its contents, salting a bundler's cache key with it,
|
|
6
5
|
* for one, since what a catalogue assembles into depends on the config.
|
|
7
6
|
*/
|
|
8
|
-
declare function resolveConfigFile(name?: string): string;
|
|
9
|
-
declare function resolveConfig(name?: string): Config;
|
|
10
|
-
//#endregion
|
|
11
|
-
export { resolveConfig, resolveConfigFile };
|
|
7
|
+
export declare function resolveConfigFile(name?: string): string;
|
|
8
|
+
export declare function resolveConfig(name?: string): Config;
|
|
@@ -1,2 +1 @@
|
|
|
1
|
-
|
|
2
|
-
export { resolveConfig, resolveConfigFile };
|
|
1
|
+
export { t as resolveConfig, n as resolveConfigFile } from "../../loader-1PBbw7yb.mjs";
|
|
@@ -1,20 +1,17 @@
|
|
|
1
1
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
|
-
const
|
|
3
|
-
|
|
4
|
-
let _messageformat_number_skeleton = require("@messageformat/number-skeleton");
|
|
5
|
-
//#region src/features/messages/escape.ts
|
|
2
|
+
const require_compile = require("../../compile-BrwRUqtQ.cjs");
|
|
3
|
+
// src/features/messages/escape.ts
|
|
6
4
|
function escapeIcuLiteral(text, hash = false) {
|
|
7
5
|
return text.replace(/'/gu, "''").replace(hash ? /[{}#]+/gu : /[{}]+/gu, (run) => `'${run}'`);
|
|
8
6
|
}
|
|
9
|
-
|
|
10
|
-
//#region src/features/messages/types.ts
|
|
7
|
+
// src/features/messages/types.ts
|
|
11
8
|
var Base = class {
|
|
12
9
|
toICUString() {
|
|
13
10
|
return convertMessageToIcu(this);
|
|
14
11
|
}
|
|
15
12
|
toHashString() {
|
|
16
13
|
const context = this instanceof CompositeMessage ? this.descriptor.context : void 0;
|
|
17
|
-
return
|
|
14
|
+
return require_compile.generateHash(this.toICUString(), context);
|
|
18
15
|
}
|
|
19
16
|
};
|
|
20
17
|
var LiteralMessage = class extends Base {
|
|
@@ -78,8 +75,7 @@ var CompositeMessage = class extends Base {
|
|
|
78
75
|
this.whitespace = whitespace;
|
|
79
76
|
}
|
|
80
77
|
};
|
|
81
|
-
|
|
82
|
-
//#region src/features/messages/identifier.ts
|
|
78
|
+
// src/features/messages/identifier.ts
|
|
83
79
|
const AUTO_INCREMENT_IDENTIFIER = Symbol("auto-increment");
|
|
84
80
|
const BRANCH_PATTERN = /^(?:=\d+|[^\p{Pattern_Syntax}\p{Pattern_White_Space}]+)$/u;
|
|
85
81
|
function getBranchCase(kind, identifier) {
|
|
@@ -148,8 +144,7 @@ function collectAssignedIdentifiers(message, equivalent) {
|
|
|
148
144
|
for (const tag of tags.keys()) if (values.has(tag)) throw new Error(`Element tag '${tag}' collides with an argument of the same name`);
|
|
149
145
|
return /* @__PURE__ */ new Set([...tags.keys(), ...values.keys()]);
|
|
150
146
|
}
|
|
151
|
-
|
|
152
|
-
//#region src/features/messages/convert.ts
|
|
147
|
+
// src/features/messages/convert.ts
|
|
153
148
|
function convertMessageToIcu(message) {
|
|
154
149
|
function internalConvertMessageToIcu(message, hash) {
|
|
155
150
|
switch (true) {
|
|
@@ -182,68 +177,23 @@ function convertMessageToIcu(message) {
|
|
|
182
177
|
}
|
|
183
178
|
return internalConvertMessageToIcu(message, void 0).trim();
|
|
184
179
|
}
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
const ARGUMENT_STYLES = {
|
|
188
|
-
number: ["integer", "percent"],
|
|
189
|
-
date: [
|
|
190
|
-
"short",
|
|
191
|
-
"medium",
|
|
192
|
-
"long",
|
|
193
|
-
"full"
|
|
194
|
-
],
|
|
195
|
-
time: [
|
|
196
|
-
"short",
|
|
197
|
-
"medium",
|
|
198
|
-
"long",
|
|
199
|
-
"full"
|
|
200
|
-
]
|
|
201
|
-
};
|
|
202
|
-
const ARGUMENT_TYPES = Object.keys(ARGUMENT_STYLES);
|
|
203
|
-
function isArgumentType(kind) {
|
|
204
|
-
return Object.hasOwn(ARGUMENT_STYLES, kind);
|
|
205
|
-
}
|
|
206
|
-
const LITERAL_STYLE_PATTERN = /^[^{}\r\n]*[#0][^{}\r\n]*$/;
|
|
207
|
-
const SKELETON = "::";
|
|
208
|
-
function invalidSkeleton(type, skeleton) {
|
|
209
|
-
if (skeleton === "") return "it names no fields";
|
|
210
|
-
const errors = [];
|
|
211
|
-
if (type === "number") {
|
|
212
|
-
(0, _messageformat_number_skeleton.getNumberFormatOptions)((0, _messageformat_number_skeleton.parseNumberSkeleton)(skeleton, (error) => errors.push(String(error))), (stem) => {
|
|
213
|
-
if (stem !== "scale") errors.push(`unsupported stem '${stem}'`);
|
|
214
|
-
});
|
|
215
|
-
return errors[0];
|
|
216
|
-
}
|
|
217
|
-
const options = (0, _messageformat_date_skeleton.getDateTimeFormatOptions)((0, _messageformat_date_skeleton.parseDateTokens)(skeleton), (_type, message) => errors.push(message));
|
|
218
|
-
if (errors.length > 0) return errors[0];
|
|
219
|
-
if (Object.keys(options).length === 0) return "it names no fields";
|
|
220
|
-
}
|
|
221
|
-
function validateArgumentStyle(type, style) {
|
|
222
|
-
const named = ARGUMENT_STYLES[type];
|
|
223
|
-
if (named.includes(style)) return;
|
|
224
|
-
if (style.startsWith(SKELETON)) {
|
|
225
|
-
const reason = invalidSkeleton(type, style.slice(2));
|
|
226
|
-
if (!reason) return;
|
|
227
|
-
throw new Error(`Invalid ${type} skeleton '${style}': ${reason}`);
|
|
228
|
-
}
|
|
229
|
-
if (type === "number" && LITERAL_STYLE_PATTERN.test(style)) return;
|
|
230
|
-
const expected = named.map((s) => `'${s}'`).join(", ");
|
|
231
|
-
throw new Error(`Invalid ${type} style '${style}', expected ${expected}, or a skeleton such as ` + (type === "number" ? "::currency/EUR" : "::yyyyMMdd") + (type === "number" ? ", or a literal number pattern such as #,##0.00" : ""));
|
|
232
|
-
}
|
|
233
|
-
//#endregion
|
|
234
|
-
exports.ARGUMENT_STYLES = ARGUMENT_STYLES;
|
|
235
|
-
exports.ARGUMENT_TYPES = ARGUMENT_TYPES;
|
|
180
|
+
exports.ARGUMENT_STYLES = require_compile.ARGUMENT_STYLES;
|
|
181
|
+
exports.ARGUMENT_TYPES = require_compile.ARGUMENT_TYPES;
|
|
236
182
|
exports.AUTO_INCREMENT_IDENTIFIER = AUTO_INCREMENT_IDENTIFIER;
|
|
237
183
|
exports.ArgumentMessage = ArgumentMessage;
|
|
238
184
|
exports.ChoiceMessage = ChoiceMessage;
|
|
239
185
|
exports.CompositeMessage = CompositeMessage;
|
|
240
186
|
exports.ElementMessage = ElementMessage;
|
|
241
187
|
exports.LiteralMessage = LiteralMessage;
|
|
188
|
+
exports.StyleError = require_compile.StyleError;
|
|
242
189
|
exports.assignSequenceIdentifiers = assignSequenceIdentifiers;
|
|
190
|
+
exports.compileMessage = require_compile.compileMessage;
|
|
243
191
|
exports.convertMessageToIcu = convertMessageToIcu;
|
|
192
|
+
exports.dateTimeStyle = require_compile.dateTimeStyle;
|
|
244
193
|
exports.escapeIcuLiteral = escapeIcuLiteral;
|
|
245
|
-
exports.generateHash =
|
|
194
|
+
exports.generateHash = require_compile.generateHash;
|
|
246
195
|
exports.getBranchCase = getBranchCase;
|
|
247
|
-
exports.isArgumentType = isArgumentType;
|
|
248
|
-
exports.
|
|
196
|
+
exports.isArgumentType = require_compile.isArgumentType;
|
|
197
|
+
exports.numberStyle = require_compile.numberStyle;
|
|
198
|
+
exports.validateArgumentStyle = require_compile.validateArgumentStyle;
|
|
249
199
|
exports.validateBranchIdentifier = validateBranchIdentifier;
|
|
@@ -1,41 +1,49 @@
|
|
|
1
|
-
//#region src/features/messages/format.d.ts
|
|
2
1
|
/**
|
|
3
|
-
*
|
|
4
|
-
*
|
|
5
|
-
* A style may also be a skeleton, which is where the formats these names have
|
|
6
|
-
* no word for live; see {@link validateArgumentStyle}.
|
|
2
|
+
* What each node in a compiled message is, by the number it starts with.
|
|
7
3
|
*
|
|
8
|
-
*
|
|
9
|
-
* code, so `{price, number, currency}` formats as a bare number. Currency
|
|
10
|
-
* belongs to a skeleton, `::currency/EUR`, which the formatter does honour.
|
|
11
|
-
*
|
|
12
|
-
* `spellout`, RBNF `ordinal` and `choice` are absent by decision: the first two
|
|
13
|
-
* are ICU4J/ICU4C rule-based formats with no `Intl` equivalent, and the third
|
|
14
|
-
* is deprecated in ICU itself in favour of `plural`.
|
|
4
|
+
* The numbers are the format, so a kind is only ever appended, never renumbered or reused.
|
|
15
5
|
*/
|
|
16
|
-
declare const
|
|
17
|
-
readonly
|
|
18
|
-
readonly
|
|
19
|
-
readonly
|
|
6
|
+
declare const Kind: {
|
|
7
|
+
readonly Value: 0;
|
|
8
|
+
readonly Number: 1;
|
|
9
|
+
readonly DateTime: 2;
|
|
10
|
+
readonly Plural: 3;
|
|
11
|
+
readonly Ordinal: 4;
|
|
12
|
+
readonly Select: 5;
|
|
13
|
+
readonly Hash: 6;
|
|
20
14
|
};
|
|
21
|
-
type
|
|
22
|
-
declare const ARGUMENT_TYPES: ArgumentType[];
|
|
23
|
-
declare function isArgumentType(kind: string): kind is ArgumentType;
|
|
15
|
+
type Kind = (typeof Kind)[keyof typeof Kind];
|
|
24
16
|
/**
|
|
25
|
-
*
|
|
26
|
-
*
|
|
17
|
+
* A compiled message.
|
|
18
|
+
*
|
|
19
|
+
* The CLI compiles a catalogue to this: strings and arrays, with styles already resolved to
|
|
20
|
+
* `Intl` options. It is plain JSON, so it can cross a server/client boundary.
|
|
27
21
|
*
|
|
28
|
-
* A
|
|
29
|
-
*
|
|
30
|
-
*
|
|
22
|
+
* A node is an array starting with its {@link Kind}; an array starting with anything else is a
|
|
23
|
+
* concatenation. Operands are descriptor keys, never nodes. A message with no placeholders is its
|
|
24
|
+
* own string.
|
|
25
|
+
*/
|
|
26
|
+
type Message$1 = string | Message$1[] | [typeof Kind.Value, string] | [typeof Kind.Number, string, Intl.NumberFormatOptions?, number?] | [typeof Kind.DateTime, string, Intl.DateTimeFormatOptions?] | [typeof Kind.Plural, string, Message$1.Cases, number?] | [typeof Kind.Ordinal, string, Message$1.Cases, number?] | [typeof Kind.Select, string, Message$1.Cases] | [typeof Kind.Hash];
|
|
27
|
+
declare namespace Message$1 {
|
|
28
|
+
/**
|
|
29
|
+
* A plural's or a select's branches, by key. A plural's keys are CLDR
|
|
30
|
+
* categories or an exact `=n`, and `other` is the fallback for both.
|
|
31
|
+
*/
|
|
32
|
+
type Cases = {
|
|
33
|
+
[key: string]: Message$1;
|
|
34
|
+
};
|
|
35
|
+
/** What a compiled message is called with: the descriptor the transform built. */
|
|
36
|
+
type Values = Record<string, unknown>;
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Compile one ICU MessageFormat 1 message.
|
|
31
40
|
*
|
|
32
|
-
*
|
|
33
|
-
*
|
|
41
|
+
* @param icu The message, in ICU MessageFormat 1 syntax
|
|
42
|
+
* @returns The compiled message
|
|
43
|
+
* @throws If the message is not valid ICU MessageFormat 1
|
|
34
44
|
*/
|
|
35
|
-
declare function
|
|
36
|
-
|
|
37
|
-
//#region src/features/messages/identifier.d.ts
|
|
38
|
-
declare const AUTO_INCREMENT_IDENTIFIER: unique symbol;
|
|
45
|
+
export declare function compileMessage(icu: string): Message$1;
|
|
46
|
+
export declare const AUTO_INCREMENT_IDENTIFIER: unique symbol;
|
|
39
47
|
/**
|
|
40
48
|
* The ICU case a branch is written as.
|
|
41
49
|
*
|
|
@@ -48,7 +56,7 @@ declare const AUTO_INCREMENT_IDENTIFIER: unique symbol;
|
|
|
48
56
|
* coerce to `=0`, which would pass for a key selecting zero and leave the
|
|
49
57
|
* author's own key out of the catalogue.
|
|
50
58
|
*/
|
|
51
|
-
declare function getBranchCase(kind: string, identifier: string | typeof AUTO_INCREMENT_IDENTIFIER): string;
|
|
59
|
+
export declare function getBranchCase(kind: string, identifier: string | typeof AUTO_INCREMENT_IDENTIFIER): string;
|
|
52
60
|
/**
|
|
53
61
|
* Reject a branch key ICU cannot express, while the key is still attached to a
|
|
54
62
|
* file and a line.
|
|
@@ -57,23 +65,77 @@ declare function getBranchCase(kind: string, identifier: string | typeof AUTO_IN
|
|
|
57
65
|
* builds, and extracts to a normal-looking catalogue entry, and the only sign
|
|
58
66
|
* of trouble is a parse error at format time.
|
|
59
67
|
*/
|
|
60
|
-
declare function validateBranchIdentifier(kind: string, identifier: string | typeof AUTO_INCREMENT_IDENTIFIER): void;
|
|
68
|
+
export declare function validateBranchIdentifier(kind: string, identifier: string | typeof AUTO_INCREMENT_IDENTIFIER): void;
|
|
61
69
|
/**
|
|
62
70
|
* Decides whether two placeholders sharing a name are the same placeholder, and
|
|
63
71
|
* so may share it. Only the syntax that produced them can answer that, so the
|
|
64
72
|
* caller supplies the comparison; by default nothing is interchangeable.
|
|
65
73
|
*/
|
|
66
|
-
type PlaceholderEquivalence = (a: any, b: any) => boolean;
|
|
67
|
-
declare function assignSequenceIdentifiers(message: Message, sequence?: {
|
|
74
|
+
export type PlaceholderEquivalence = (a: any, b: any) => boolean;
|
|
75
|
+
export declare function assignSequenceIdentifiers(message: Message, sequence?: {
|
|
68
76
|
current: number;
|
|
69
77
|
}, equivalent?: PlaceholderEquivalence): void;
|
|
70
|
-
|
|
71
|
-
|
|
78
|
+
/**
|
|
79
|
+
* Argument styles: which ones a macro may author, and the `Intl` options each resolves to.
|
|
80
|
+
*
|
|
81
|
+
* Validation and compilation share these functions, so a style the transform accepts is one the
|
|
82
|
+
* compiler honours.
|
|
83
|
+
*/
|
|
84
|
+
/**
|
|
85
|
+
* The ICU argument types a macro can author, and the named styles each accepts.
|
|
86
|
+
*
|
|
87
|
+
* `currency` is absent from `number` because MF1 has nowhere to write the code; use
|
|
88
|
+
* `::currency/EUR`.
|
|
89
|
+
* `duration`, `spellout`, RBNF `ordinal` and `choice` are absent too, and compile to the bare
|
|
90
|
+
* value.
|
|
91
|
+
*/
|
|
92
|
+
export declare const ARGUMENT_STYLES: {
|
|
93
|
+
readonly number: readonly ['integer', 'percent'];
|
|
94
|
+
readonly date: readonly ['short', 'medium', 'long', 'full'];
|
|
95
|
+
readonly time: readonly ['short', 'medium', 'long', 'full'];
|
|
96
|
+
};
|
|
97
|
+
export type ArgumentType = keyof typeof ARGUMENT_STYLES;
|
|
98
|
+
export declare const ARGUMENT_TYPES: ArgumentType[];
|
|
99
|
+
export declare function isArgumentType(kind: string): kind is ArgumentType;
|
|
100
|
+
/** The extra key a number's bag may carry, which `Intl` has no option for. */
|
|
101
|
+
export type NumberOptions = Intl.NumberFormatOptions & {
|
|
102
|
+
scale?: number;
|
|
103
|
+
};
|
|
104
|
+
/** A style that could not be resolved, with the reason it could not. */
|
|
105
|
+
export declare class StyleError extends Error {}
|
|
106
|
+
/**
|
|
107
|
+
* Turn a `date` or `time` argument style into `Intl.DateTimeFormat` options.
|
|
108
|
+
*
|
|
109
|
+
* A `::`-prefixed style is a skeleton such as `::yyyyMMdd`; an empty style takes MF1's default.
|
|
110
|
+
*
|
|
111
|
+
* @throws {StyleError} If the style names no fields
|
|
112
|
+
*/
|
|
113
|
+
export declare function dateTimeStyle(kind: 'date' | 'time', style: string): Intl.DateTimeFormatOptions;
|
|
114
|
+
/**
|
|
115
|
+
* Turn a `number` argument style into `Intl.NumberFormat` options.
|
|
116
|
+
*
|
|
117
|
+
* Accepts MF1's named styles, a `::`-prefixed skeleton, or a literal pattern such as `#,##0.00`.
|
|
118
|
+
* Named styles are expanded here because the pattern parser would read `percent` as literal text.
|
|
119
|
+
*
|
|
120
|
+
* `scale` comes back beside the bag, since `Intl` has no option for it.
|
|
121
|
+
*
|
|
122
|
+
* @throws {StyleError} If the style is not valid, or asks for something `Intl` cannot express
|
|
123
|
+
*/
|
|
124
|
+
export declare function numberStyle(style: string): NumberOptions;
|
|
125
|
+
/**
|
|
126
|
+
* Reject an argument style the compiler cannot honour, while it is still attached to a file and
|
|
127
|
+
* line.
|
|
128
|
+
*
|
|
129
|
+
* The compiler falls back to the default format, so an unchecked typo like `{d, date, meduim}` only
|
|
130
|
+
* misformats in production.
|
|
131
|
+
* Skeletons and patterns are checked by resolving them as the compiler will.
|
|
132
|
+
*/
|
|
133
|
+
export declare function validateArgumentStyle(type: ArgumentType, style: string): void;
|
|
72
134
|
declare abstract class Base {
|
|
73
135
|
toICUString(this: Message): string;
|
|
74
136
|
toHashString(this: Message): string;
|
|
75
137
|
}
|
|
76
|
-
declare class LiteralMessage extends Base {
|
|
138
|
+
export declare class LiteralMessage extends Base {
|
|
77
139
|
readonly text: string;
|
|
78
140
|
constructor(text: string);
|
|
79
141
|
}
|
|
@@ -85,23 +147,23 @@ declare class LiteralMessage extends Base {
|
|
|
85
147
|
* options, because the catalogue is the source of truth and only the ICU
|
|
86
148
|
* spelling round-trips back out of it.
|
|
87
149
|
*/
|
|
88
|
-
interface ArgumentFormat {
|
|
150
|
+
export interface ArgumentFormat {
|
|
89
151
|
type: ArgumentType;
|
|
90
152
|
style?: string;
|
|
91
153
|
}
|
|
92
|
-
declare class ArgumentMessage extends Base {
|
|
154
|
+
export declare class ArgumentMessage extends Base {
|
|
93
155
|
identifier: string | typeof AUTO_INCREMENT_IDENTIFIER;
|
|
94
156
|
readonly expression: any;
|
|
95
157
|
readonly format?: ArgumentFormat | undefined;
|
|
96
158
|
constructor(identifier: string | typeof AUTO_INCREMENT_IDENTIFIER, expression: any, format?: ArgumentFormat | undefined);
|
|
97
159
|
}
|
|
98
|
-
declare class ElementMessage extends Base {
|
|
160
|
+
export declare class ElementMessage extends Base {
|
|
99
161
|
identifier: string | typeof AUTO_INCREMENT_IDENTIFIER;
|
|
100
162
|
readonly children: Message[];
|
|
101
163
|
readonly expression: any;
|
|
102
164
|
constructor(identifier: string | typeof AUTO_INCREMENT_IDENTIFIER, children: Message[], expression: any);
|
|
103
165
|
}
|
|
104
|
-
declare class ChoiceMessage extends Base {
|
|
166
|
+
export declare class ChoiceMessage extends Base {
|
|
105
167
|
readonly kind: string;
|
|
106
168
|
identifier: string | typeof AUTO_INCREMENT_IDENTIFIER;
|
|
107
169
|
readonly branches: {
|
|
@@ -126,7 +188,7 @@ declare class ChoiceMessage extends Base {
|
|
|
126
188
|
*/
|
|
127
189
|
offset?: number | undefined);
|
|
128
190
|
}
|
|
129
|
-
declare class CompositeMessage extends Base {
|
|
191
|
+
export declare class CompositeMessage extends Base {
|
|
130
192
|
readonly descriptor: {
|
|
131
193
|
id?: string;
|
|
132
194
|
context?: string;
|
|
@@ -141,12 +203,8 @@ declare class CompositeMessage extends Base {
|
|
|
141
203
|
context?: string;
|
|
142
204
|
}, comments: string[], references: string[], children: Message[], accessor: any, whitespace?: boolean | undefined);
|
|
143
205
|
}
|
|
144
|
-
type Message = LiteralMessage | ArgumentMessage | ElementMessage | ChoiceMessage | CompositeMessage;
|
|
145
|
-
|
|
146
|
-
//#region src/features/messages/convert.d.ts
|
|
147
|
-
declare function convertMessageToIcu(message: Message): string;
|
|
148
|
-
//#endregion
|
|
149
|
-
//#region src/features/messages/escape.d.ts
|
|
206
|
+
export type Message = LiteralMessage | ArgumentMessage | ElementMessage | ChoiceMessage | CompositeMessage;
|
|
207
|
+
export declare function convertMessageToIcu(message: Message): string;
|
|
150
208
|
/**
|
|
151
209
|
* Quoting for text that has to survive a message format unchanged.
|
|
152
210
|
*
|
|
@@ -167,9 +225,7 @@ declare function convertMessageToIcu(message: Message): string;
|
|
|
167
225
|
* @param hash Whether `#` stands for a number here, i.e. whether some `plural`
|
|
168
226
|
* or `ordinal` encloses this text
|
|
169
227
|
*/
|
|
170
|
-
declare function escapeIcuLiteral(text: string, hash?: boolean): string;
|
|
171
|
-
//#endregion
|
|
172
|
-
//#region src/features/messages/hash.d.ts
|
|
228
|
+
export declare function escapeIcuLiteral(text: string, hash?: boolean): string;
|
|
173
229
|
/**
|
|
174
230
|
* Hashed in userland rather than with `node:crypto`, because this runs wherever
|
|
175
231
|
* a bundler runs it. `createHash` is one of the entry points `unenv` leaves
|
|
@@ -178,6 +234,5 @@ declare function escapeIcuLiteral(text: string, hash?: boolean): string;
|
|
|
178
234
|
* equivalent, `subtle.digest`, is async, and an id is resolved from a
|
|
179
235
|
* synchronous extraction pass.
|
|
180
236
|
*/
|
|
181
|
-
declare function generateHash(input: string, context?: string): string;
|
|
182
|
-
|
|
183
|
-
export { ARGUMENT_STYLES, ARGUMENT_TYPES, AUTO_INCREMENT_IDENTIFIER, ArgumentFormat, ArgumentMessage, ArgumentType, ChoiceMessage, CompositeMessage, ElementMessage, LiteralMessage, Message, PlaceholderEquivalence, assignSequenceIdentifiers, convertMessageToIcu, escapeIcuLiteral, generateHash, getBranchCase, isArgumentType, validateArgumentStyle, validateBranchIdentifier };
|
|
237
|
+
export declare function generateHash(input: string, context?: string): string;
|
|
238
|
+
export {};
|