next-intl 4.5.7 → 4.6.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/dist/cjs/development/ExtractorCodec-DZKNn0Zq.cjs +37 -0
- package/dist/cjs/development/JSONCodec-Dlcx71xz.cjs +41 -0
- package/dist/cjs/development/POCodec-BW-UDNcq.cjs +94 -0
- package/dist/cjs/development/plugin.cjs +28 -5
- package/dist/esm/development/extractor/ExtractionCompiler.js +22 -25
- package/dist/esm/development/extractor/catalog/CatalogLocales.js +0 -33
- package/dist/esm/development/extractor/catalog/CatalogManager.js +134 -102
- package/dist/esm/development/extractor/catalog/CatalogPersister.js +31 -13
- package/dist/esm/development/extractor/catalog/SaveScheduler.js +33 -14
- package/dist/esm/development/extractor/catalogLoader.js +10 -10
- package/dist/esm/development/extractor/extractMessages.js +9 -2
- package/dist/esm/development/extractor/extractionLoader.js +27 -4
- package/dist/esm/development/extractor/extractor/MessageExtractor.js +5 -4
- package/dist/esm/development/extractor/format/ExtractorCodec.js +5 -0
- package/dist/esm/development/extractor/format/codecs/JSONCodec.js +40 -0
- package/dist/esm/development/extractor/format/codecs/POCodec.js +93 -0
- package/dist/esm/development/extractor/format/index.js +44 -0
- package/dist/esm/development/extractor/source/SourceFileScanner.js +2 -1
- package/dist/esm/development/extractor/source/SourceFileWatcher.js +38 -0
- package/dist/esm/development/extractor/utils.js +16 -1
- package/dist/esm/development/extractor.js +1 -0
- package/dist/esm/development/plugin/createNextIntlPlugin.js +1 -1
- package/dist/esm/development/plugin/getNextConfig.js +7 -4
- package/dist/esm/production/extractor/ExtractionCompiler.js +1 -1
- package/dist/esm/production/extractor/catalog/CatalogLocales.js +1 -1
- package/dist/esm/production/extractor/catalog/CatalogManager.js +1 -1
- package/dist/esm/production/extractor/catalog/CatalogPersister.js +1 -1
- package/dist/esm/production/extractor/catalog/SaveScheduler.js +1 -1
- package/dist/esm/production/extractor/catalogLoader.js +1 -1
- package/dist/esm/production/extractor/extractMessages.js +1 -1
- package/dist/esm/production/extractor/extractionLoader.js +1 -1
- package/dist/esm/production/extractor/extractor/MessageExtractor.js +1 -1
- package/dist/esm/production/extractor/format/ExtractorCodec.js +1 -0
- package/dist/esm/production/extractor/format/codecs/JSONCodec.js +1 -0
- package/dist/esm/production/extractor/format/codecs/POCodec.js +1 -0
- package/dist/esm/production/extractor/format/index.js +1 -0
- package/dist/esm/production/extractor/source/SourceFileScanner.js +1 -1
- package/dist/esm/production/extractor/source/SourceFileWatcher.js +1 -0
- package/dist/esm/production/extractor/utils.js +1 -1
- package/dist/esm/production/extractor.js +1 -1
- package/dist/esm/production/plugin/createNextIntlPlugin.js +1 -1
- package/dist/esm/production/plugin/getNextConfig.js +1 -1
- package/dist/types/extractor/ExtractionCompiler.d.ts +5 -10
- package/dist/types/extractor/catalog/CatalogLocales.d.ts +0 -2
- package/dist/types/extractor/catalog/CatalogManager.d.ts +21 -11
- package/dist/types/extractor/catalog/CatalogPersister.d.ts +15 -6
- package/dist/types/extractor/catalog/SaveScheduler.d.ts +1 -0
- package/dist/types/extractor/extractor/MessageExtractor.d.ts +6 -6
- package/dist/types/extractor/format/ExtractorCodec.d.ts +33 -0
- package/dist/types/extractor/format/codecs/JSONCodec.d.ts +2 -0
- package/dist/types/extractor/format/codecs/POCodec.d.ts +2 -0
- package/dist/types/extractor/format/codecs/fixtures/JSONCodecStructured.d.ts +2 -0
- package/dist/types/extractor/format/codecs/fixtures/POCodecSourceMessageKey.d.ts +2 -0
- package/dist/types/extractor/format/index.d.ts +15 -0
- package/dist/types/extractor/format/types.d.ts +8 -0
- package/dist/types/extractor/index.d.ts +1 -0
- package/dist/types/extractor/source/SourceFileFilter.d.ts +1 -1
- package/dist/types/extractor/source/SourceFileScanner.d.ts +1 -1
- package/dist/types/extractor/source/SourceFileWatcher.d.ts +12 -0
- package/dist/types/extractor/types.d.ts +2 -2
- package/dist/types/extractor/utils.d.ts +3 -0
- package/dist/types/plugin/types.d.ts +1 -1
- package/package.json +6 -5
- package/dist/esm/development/extractor/formatters/Formatter.js +0 -3
- package/dist/esm/development/extractor/formatters/JSONFormatter.js +0 -42
- package/dist/esm/development/extractor/formatters/POFormatter.js +0 -51
- package/dist/esm/development/extractor/formatters/index.js +0 -6
- package/dist/esm/development/extractor/formatters/utils.js +0 -15
- package/dist/esm/production/extractor/formatters/Formatter.js +0 -1
- package/dist/esm/production/extractor/formatters/JSONFormatter.js +0 -1
- package/dist/esm/production/extractor/formatters/POFormatter.js +0 -1
- package/dist/esm/production/extractor/formatters/index.js +0 -1
- package/dist/esm/production/extractor/formatters/utils.js +0 -1
- package/dist/types/extractor/formatters/Formatter.d.ts +0 -10
- package/dist/types/extractor/formatters/JSONFormatter.d.ts +0 -10
- package/dist/types/extractor/formatters/POFormatter.d.ts +0 -10
- package/dist/types/extractor/formatters/index.d.ts +0 -5
- package/dist/types/extractor/formatters/utils.d.ts +0 -2
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
type StrictExtractedMessage =
|
|
3
|
-
references: NonNullable<
|
|
1
|
+
import type { ExtractorMessage } from '../types.js';
|
|
2
|
+
type StrictExtractedMessage = ExtractorMessage & {
|
|
3
|
+
references: NonNullable<ExtractorMessage['references']>;
|
|
4
4
|
};
|
|
5
5
|
export default class MessageExtractor {
|
|
6
6
|
private isDevelopment;
|
|
@@ -8,11 +8,11 @@ export default class MessageExtractor {
|
|
|
8
8
|
private sourceMap;
|
|
9
9
|
private compileCache;
|
|
10
10
|
constructor(opts: {
|
|
11
|
-
isDevelopment
|
|
12
|
-
projectRoot
|
|
11
|
+
isDevelopment?: boolean;
|
|
12
|
+
projectRoot?: string;
|
|
13
13
|
sourceMap?: boolean;
|
|
14
14
|
});
|
|
15
|
-
|
|
15
|
+
extract(absoluteFilePath: string, source: string): Promise<{
|
|
16
16
|
messages: Array<StrictExtractedMessage>;
|
|
17
17
|
code: string;
|
|
18
18
|
map?: string;
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import type { ExtractorMessage, Locale } from '../types.js';
|
|
2
|
+
type ExtractorCodecContext = {
|
|
3
|
+
locale: Locale;
|
|
4
|
+
};
|
|
5
|
+
export default interface ExtractorCodec {
|
|
6
|
+
/**
|
|
7
|
+
* Decode the content of a file into a list of extracted messages. This is used
|
|
8
|
+
* to load existing messages from disk.
|
|
9
|
+
*/
|
|
10
|
+
decode(content: string, context: ExtractorCodecContext): Array<ExtractorMessage>;
|
|
11
|
+
/**
|
|
12
|
+
* Encode a list of extracted messages into a string that can be written as
|
|
13
|
+
* file content to the disk.
|
|
14
|
+
*/
|
|
15
|
+
encode(messages: Array<ExtractorMessage>, context: ExtractorCodecContext & {
|
|
16
|
+
sourceMessagesById: Map</* ID */ string, ExtractorMessage>;
|
|
17
|
+
}): string;
|
|
18
|
+
/**
|
|
19
|
+
* Turns the content of a file into a JSON string that represents extracted
|
|
20
|
+
* messages. The returned value will be passed to `JSON.parse`.
|
|
21
|
+
*
|
|
22
|
+
* @return E.g. `[{"id":"+YJVTi","message":"Hey!"}]`
|
|
23
|
+
*
|
|
24
|
+
* This is used when loading messages into your application, typically via a
|
|
25
|
+
* dynamic import (e.g. `import(`../messages/${locale}.json`)`).
|
|
26
|
+
*
|
|
27
|
+
* If your file content is JSON and should be used as-is, you can set this to
|
|
28
|
+
* an identity function.
|
|
29
|
+
*/
|
|
30
|
+
toJSONString(content: string, context: ExtractorCodecContext): string;
|
|
31
|
+
}
|
|
32
|
+
export declare function defineCodec(factory: () => ExtractorCodec): () => ExtractorCodec;
|
|
33
|
+
export {};
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type ExtractorCodec from './ExtractorCodec.js';
|
|
2
|
+
import type { MessagesFormat } from './types.js';
|
|
3
|
+
declare const formats: {
|
|
4
|
+
json: {
|
|
5
|
+
codec: () => Promise<typeof import("./codecs/JSONCodec.js")>;
|
|
6
|
+
extension: ".json";
|
|
7
|
+
};
|
|
8
|
+
po: {
|
|
9
|
+
codec: () => Promise<typeof import("./codecs/POCodec.js")>;
|
|
10
|
+
extension: ".po";
|
|
11
|
+
};
|
|
12
|
+
};
|
|
13
|
+
export default formats;
|
|
14
|
+
export declare function getFormatExtension(format: MessagesFormat): string;
|
|
15
|
+
export declare function resolveCodec(format: MessagesFormat, projectRoot: string): Promise<ExtractorCodec>;
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type formats from './index.js';
|
|
2
|
+
export type BuiltInMessagesFormat = keyof typeof formats;
|
|
3
|
+
type CustomMessagesFormat = {
|
|
4
|
+
codec: string;
|
|
5
|
+
extension: `.${string}`;
|
|
6
|
+
};
|
|
7
|
+
export type MessagesFormat = BuiltInMessagesFormat | CustomMessagesFormat;
|
|
8
|
+
export {};
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
export default class SourceFileFilter {
|
|
2
2
|
static readonly EXTENSIONS: string[];
|
|
3
|
-
|
|
3
|
+
static readonly IGNORED_DIRECTORIES: string[];
|
|
4
4
|
static isSourceFile(filePath: string): boolean;
|
|
5
5
|
static shouldEnterDirectory(dirPath: string, srcPaths: Array<string>): boolean;
|
|
6
6
|
private static isIgnoredDirectoryExplicitlyIncluded;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { type Event } from '@parcel/watcher';
|
|
2
|
+
type OnChange = (events: Array<Event>) => Promise<void>;
|
|
3
|
+
export default class SourceFileWatcher implements Disposable {
|
|
4
|
+
private subscriptions;
|
|
5
|
+
private roots;
|
|
6
|
+
private onChange;
|
|
7
|
+
constructor(roots: Array<string>, onChange: OnChange);
|
|
8
|
+
start(): Promise<void>;
|
|
9
|
+
stop(): Promise<void>;
|
|
10
|
+
[Symbol.dispose](): void;
|
|
11
|
+
}
|
|
12
|
+
export {};
|
|
@@ -1,2 +1,5 @@
|
|
|
1
|
+
import type { ExtractorMessage } from './types.js';
|
|
1
2
|
export declare function setNestedProperty(obj: Record<string, any>, keyPath: string, value: any): void;
|
|
3
|
+
export declare function getSortedMessages(messages: Array<ExtractorMessage>): Array<ExtractorMessage>;
|
|
2
4
|
export declare function localeCompare(a: string, b: string): number;
|
|
5
|
+
export declare function getDefaultProjectRoot(): string;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "next-intl",
|
|
3
|
-
"version": "4.
|
|
3
|
+
"version": "4.6.0",
|
|
4
4
|
"sideEffects": false,
|
|
5
5
|
"author": "Jan Amann <jan@amann.work>",
|
|
6
6
|
"funding": [
|
|
@@ -125,11 +125,12 @@
|
|
|
125
125
|
],
|
|
126
126
|
"dependencies": {
|
|
127
127
|
"@formatjs/intl-localematcher": "^0.5.4",
|
|
128
|
+
"@parcel/watcher": "^2.4.1",
|
|
128
129
|
"@swc/core": "^1.15.2",
|
|
129
130
|
"negotiator": "^1.0.0",
|
|
130
|
-
"next-intl-swc-plugin-extractor": "^4.
|
|
131
|
-
"po-parser": "^
|
|
132
|
-
"use-intl": "^4.
|
|
131
|
+
"next-intl-swc-plugin-extractor": "^4.6.0",
|
|
132
|
+
"po-parser": "^2.0.0",
|
|
133
|
+
"use-intl": "^4.6.0"
|
|
133
134
|
},
|
|
134
135
|
"peerDependencies": {
|
|
135
136
|
"next": "^12.0.0 || ^13.0.0 || ^14.0.0 || ^15.0.0 || ^16.0.0",
|
|
@@ -141,5 +142,5 @@
|
|
|
141
142
|
"optional": true
|
|
142
143
|
}
|
|
143
144
|
},
|
|
144
|
-
"gitHead": "
|
|
145
|
+
"gitHead": "70a047daa5cb235fdcadcf6ebf1daed32ad30c85"
|
|
145
146
|
}
|
|
@@ -1,42 +0,0 @@
|
|
|
1
|
-
import { setNestedProperty } from '../utils.js';
|
|
2
|
-
import Formatter from './Formatter.js';
|
|
3
|
-
import { getSortedMessages } from './utils.js';
|
|
4
|
-
|
|
5
|
-
class JSONFormatter extends Formatter {
|
|
6
|
-
static NAMESPACE_SEPARATOR = '.';
|
|
7
|
-
EXTENSION = '.json';
|
|
8
|
-
parse(source) {
|
|
9
|
-
const json = JSON.parse(source);
|
|
10
|
-
const messages = [];
|
|
11
|
-
this.traverseMessages(json, (message, id) => {
|
|
12
|
-
messages.push({
|
|
13
|
-
id,
|
|
14
|
-
message
|
|
15
|
-
});
|
|
16
|
-
});
|
|
17
|
-
return messages;
|
|
18
|
-
}
|
|
19
|
-
serialize(messages) {
|
|
20
|
-
const root = {};
|
|
21
|
-
for (const message of getSortedMessages(messages)) {
|
|
22
|
-
setNestedProperty(root, message.id, message.message);
|
|
23
|
-
}
|
|
24
|
-
return JSON.stringify(root, null, 2);
|
|
25
|
-
}
|
|
26
|
-
toJSONString(source) {
|
|
27
|
-
return source;
|
|
28
|
-
}
|
|
29
|
-
traverseMessages(obj, callback, path = '') {
|
|
30
|
-
for (const key of Object.keys(obj)) {
|
|
31
|
-
const newPath = path ? path + JSONFormatter.NAMESPACE_SEPARATOR + key : key;
|
|
32
|
-
const value = obj[key];
|
|
33
|
-
if (typeof value === 'string') {
|
|
34
|
-
callback(value, newPath);
|
|
35
|
-
} else if (typeof value === 'object') {
|
|
36
|
-
this.traverseMessages(value, callback, newPath);
|
|
37
|
-
}
|
|
38
|
-
}
|
|
39
|
-
}
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
export { JSONFormatter as default };
|
|
@@ -1,51 +0,0 @@
|
|
|
1
|
-
import POParser from 'po-parser';
|
|
2
|
-
import { setNestedProperty } from '../utils.js';
|
|
3
|
-
import Formatter from './Formatter.js';
|
|
4
|
-
import { getSortedMessages } from './utils.js';
|
|
5
|
-
|
|
6
|
-
class POFormatter extends Formatter {
|
|
7
|
-
// See also https://www.gnu.org/software/gettext/manual/html_node/Header-Entry.html
|
|
8
|
-
static DEFAULT_METADATA = {
|
|
9
|
-
// Recommended by spec
|
|
10
|
-
'Content-Type': 'text/plain; charset=utf-8',
|
|
11
|
-
'Content-Transfer-Encoding': '8bit',
|
|
12
|
-
// Otherwise other tools might set this
|
|
13
|
-
'X-Generator': 'next-intl',
|
|
14
|
-
// Crowdin defaults to using msgid as source key
|
|
15
|
-
'X-Crowdin-SourceKey': 'msgstr'
|
|
16
|
-
};
|
|
17
|
-
EXTENSION = '.po';
|
|
18
|
-
|
|
19
|
-
// Metadata is stored so it can be retained when writing
|
|
20
|
-
metadataByLocale = (() => new Map())();
|
|
21
|
-
parse(content, context) {
|
|
22
|
-
const catalog = POParser.parse(content);
|
|
23
|
-
|
|
24
|
-
// Store metadata for this locale
|
|
25
|
-
if (catalog.meta) {
|
|
26
|
-
this.metadataByLocale.set(context.locale, catalog.meta);
|
|
27
|
-
}
|
|
28
|
-
return catalog.messages || [];
|
|
29
|
-
}
|
|
30
|
-
serialize(messages, context) {
|
|
31
|
-
const meta = {
|
|
32
|
-
Language: context.locale,
|
|
33
|
-
...POFormatter.DEFAULT_METADATA,
|
|
34
|
-
...this.metadataByLocale.get(context.locale)
|
|
35
|
-
};
|
|
36
|
-
return POParser.serialize({
|
|
37
|
-
meta,
|
|
38
|
-
messages: getSortedMessages(messages)
|
|
39
|
-
});
|
|
40
|
-
}
|
|
41
|
-
toJSONString(source, context) {
|
|
42
|
-
const parsed = this.parse(source, context);
|
|
43
|
-
const messagesObject = {};
|
|
44
|
-
for (const message of parsed) {
|
|
45
|
-
setNestedProperty(messagesObject, message.id, message.message);
|
|
46
|
-
}
|
|
47
|
-
return JSON.stringify(messagesObject, null, 2);
|
|
48
|
-
}
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
export { POFormatter as default };
|
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
import { localeCompare } from '../utils.js';
|
|
2
|
-
|
|
3
|
-
function getSortedMessages(messages) {
|
|
4
|
-
return messages.toSorted((messageA, messageB) => {
|
|
5
|
-
const pathA = messageA.references?.[0]?.path ?? '';
|
|
6
|
-
const pathB = messageB.references?.[0]?.path ?? '';
|
|
7
|
-
if (pathA === pathB) {
|
|
8
|
-
return localeCompare(messageA.id, messageB.id);
|
|
9
|
-
} else {
|
|
10
|
-
return localeCompare(pathA, pathB);
|
|
11
|
-
}
|
|
12
|
-
});
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
export { getSortedMessages };
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
class a{}export{a as default};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{setNestedProperty as s}from"../utils.js";import e from"./Formatter.js";import{getSortedMessages as t}from"./utils.js";class r extends e{static NAMESPACE_SEPARATOR=".";EXTENSION=".json";parse(s){const e=JSON.parse(s),t=[];return this.traverseMessages(e,((s,e)=>{t.push({id:e,message:s})})),t}serialize(e){const r={};for(const o of t(e))s(r,o.id,o.message);return JSON.stringify(r,null,2)}toJSONString(s){return s}traverseMessages(s,e,t=""){for(const o of Object.keys(s)){const a=t?t+r.NAMESPACE_SEPARATOR+o:o,i=s[o];"string"==typeof i?e(i,a):"object"==typeof i&&this.traverseMessages(i,e,a)}}}export{r as default};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import t from"po-parser";import{setNestedProperty as e}from"../utils.js";import a from"./Formatter.js";import{getSortedMessages as s}from"./utils.js";class r extends a{static DEFAULT_METADATA={"Content-Type":"text/plain; charset=utf-8","Content-Transfer-Encoding":"8bit","X-Generator":"next-intl","X-Crowdin-SourceKey":"msgstr"};EXTENSION=".po";metadataByLocale=(()=>new Map)();parse(e,a){const s=t.parse(e);return s.meta&&this.metadataByLocale.set(a.locale,s.meta),s.messages||[]}serialize(e,a){const o={Language:a.locale,...r.DEFAULT_METADATA,...this.metadataByLocale.get(a.locale)};return t.serialize({meta:o,messages:s(e)})}toJSONString(t,a){const s=this.parse(t,a),r={};for(const t of s)e(r,t.id,t.message);return JSON.stringify(r,null,2)}}export{r as default};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
const t={json:()=>import("./JSONFormatter.js"),po:()=>import("./POFormatter.js")};export{t as default};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{localeCompare as e}from"../utils.js";function r(r){return r.toSorted(((r,t)=>{const n=r.references?.[0]?.path??"",o=t.references?.[0]?.path??"";return n===o?e(r.id,t.id):e(n,o)}))}export{r as getSortedMessages};
|
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
import type { ExtractedMessage, Locale } from '../types.js';
|
|
2
|
-
export type FormatterContext = {
|
|
3
|
-
locale: Locale;
|
|
4
|
-
};
|
|
5
|
-
export default abstract class Formatter {
|
|
6
|
-
abstract readonly EXTENSION: `.${string}`;
|
|
7
|
-
abstract parse(content: string, context: FormatterContext): Array<ExtractedMessage>;
|
|
8
|
-
abstract serialize(messages: Array<ExtractedMessage>, context: FormatterContext): string;
|
|
9
|
-
abstract toJSONString(source: string, context: FormatterContext): string;
|
|
10
|
-
}
|
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
import type { ExtractedMessage } from '../types.js';
|
|
2
|
-
import Formatter from './Formatter.js';
|
|
3
|
-
export default class JSONFormatter extends Formatter {
|
|
4
|
-
static readonly NAMESPACE_SEPARATOR = ".";
|
|
5
|
-
readonly EXTENSION = ".json";
|
|
6
|
-
parse(source: string): Array<ExtractedMessage>;
|
|
7
|
-
serialize(messages: Array<ExtractedMessage>): string;
|
|
8
|
-
toJSONString(source: string): string;
|
|
9
|
-
private traverseMessages;
|
|
10
|
-
}
|
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
import type { ExtractedMessage } from '../types.js';
|
|
2
|
-
import Formatter, { type FormatterContext } from './Formatter.js';
|
|
3
|
-
export default class POFormatter extends Formatter {
|
|
4
|
-
private static readonly DEFAULT_METADATA;
|
|
5
|
-
readonly EXTENSION = ".po";
|
|
6
|
-
private metadataByLocale;
|
|
7
|
-
parse(content: string, context: FormatterContext): Array<ExtractedMessage>;
|
|
8
|
-
serialize(messages: Array<ExtractedMessage>, context: FormatterContext): string;
|
|
9
|
-
toJSONString(source: string, context: FormatterContext): string;
|
|
10
|
-
}
|