Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 17 additions & 17 deletions packages/next-intl/src/extractor/catalog/CatalogManager.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import type {
ExtractorConfig,
ExtractorMessage,
Locale,
SourceMessage
SourceExtractedMessage
} from '../types.js';
import {
compareReferences,
Expand Down Expand Up @@ -43,17 +43,17 @@ export default class CatalogManager implements Disposable {
*/
private sourceMessagesByFile: Map<
/* File path */ string,
Map</* ID */ string, Array<SourceMessage>>
Map</* ID */ string, Array<SourceExtractedMessage>>
> = new Map();

/**
* Reverse index for rebuilding aggregated messages without scanning all files.
* Contains the same `SourceMessage` arrays as `sourceMessagesByFile` and is
* Contains the same `SourceExtractedMessage` arrays as `sourceMessagesByFile` and is
* kept in sync with it.
*/
private sourceMessagesById: Map<
/* ID */ string,
Map</* File path */ string, Array<SourceMessage>>
Map</* File path */ string, Array<SourceExtractedMessage>>
> = new Map();

/**
Expand Down Expand Up @@ -308,8 +308,8 @@ export default class CatalogManager implements Disposable {

private async extractFile(
absoluteFilePath: string
): Promise<Array<SourceMessage> | undefined> {
let messages: Array<SourceMessage> = [];
): Promise<Array<SourceExtractedMessage> | undefined> {
let messages: Array<SourceExtractedMessage> = [];
try {
const content = await fs.readFile(absoluteFilePath, 'utf8');
let extraction: Awaited<ReturnType<typeof this.extractor.extract>>;
Expand All @@ -330,7 +330,7 @@ export default class CatalogManager implements Disposable {

private applyFileMessages(
absoluteFilePath: string,
messages: Array<SourceMessage>
messages: Array<SourceExtractedMessage>
): boolean {
const prevFileMessages = this.sourceMessagesByFile.get(absoluteFilePath);
const nextFileMessages = this.groupSourceMessagesById(messages);
Expand Down Expand Up @@ -378,9 +378,9 @@ export default class CatalogManager implements Disposable {
}

private groupSourceMessagesById(
messages: Array<SourceMessage>
): Map<string, Array<SourceMessage>> {
const result = new Map<string, Array<SourceMessage>>();
messages: Array<SourceExtractedMessage>
): Map<string, Array<SourceExtractedMessage>> {
const result = new Map<string, Array<SourceExtractedMessage>>();
for (const message of messages) {
const messagesById = result.get(message.id);
if (messagesById) {
Expand Down Expand Up @@ -429,7 +429,7 @@ export default class CatalogManager implements Disposable {
}

private mergeDescriptions(
messages: Array<SourceMessage>
messages: Array<SourceExtractedMessage>
): ExtractorMessage['description'] {
const sortedByReference = messages.toSorted((a, b) =>
compareReferences(a.reference, b.reference)
Expand All @@ -447,8 +447,8 @@ export default class CatalogManager implements Disposable {
}

private haveMessagesChangedForFile(
beforeMessages: Map<string, Array<SourceMessage>> | undefined,
afterMessages: Map<string, Array<SourceMessage>>
beforeMessages: Map<string, Array<SourceExtractedMessage>> | undefined,
afterMessages: Map<string, Array<SourceExtractedMessage>>
): boolean {
// If one exists and the other doesn't, there's a change
if (!beforeMessages) {
Expand Down Expand Up @@ -481,8 +481,8 @@ export default class CatalogManager implements Disposable {
}

private areSourceMessageArraysEqual(
messages1: Array<SourceMessage>,
messages2: Array<SourceMessage>
messages1: Array<SourceExtractedMessage>,
messages2: Array<SourceExtractedMessage>
): boolean {
return (
messages1.length === messages2.length &&
Expand All @@ -493,8 +493,8 @@ export default class CatalogManager implements Disposable {
}

private areSourceMessagesEqual(
msg1: SourceMessage,
msg2: SourceMessage
msg1: SourceExtractedMessage,
msg2: SourceExtractedMessage
): boolean {
return (
msg1.id === msg2.id &&
Expand Down
23 changes: 17 additions & 6 deletions packages/next-intl/src/extractor/extractor/MessageExtractor.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import {createRequire} from 'module';
import path from 'path';
import {transform} from '@swc/core';
import type {SourceMessage} from '../types.js';
import type {SourceExtractedMessage} from '../types.js';
import {getDefaultProjectRoot, normalizePathToPosix} from '../utils.js';
import LRUCache from './LRUCache.js';

Expand All @@ -12,7 +12,7 @@ export default class MessageExtractor {
private projectRoot: string;
private sourceMap: boolean;
private compileCache = new LRUCache<{
messages: Array<SourceMessage>;
messages: Array<SourceExtractedMessage>;
code: string;
map?: string;
}>(750);
Expand All @@ -31,7 +31,7 @@ export default class MessageExtractor {
absoluteFilePath: string,
source: string
): Promise<{
messages: Array<SourceMessage>;
messages: Array<SourceExtractedMessage>;
code: string;
map?: string;
}> {
Expand Down Expand Up @@ -79,9 +79,20 @@ export default class MessageExtractor {

// TODO: Improve the typing of @swc/core
const output = (result as any).output as string;
const messages = JSON.parse(
JSON.parse(output).results
) as Array<SourceMessage>;
// The plugin emits a tagged union of extracted messages and
// `useTranslations` usages; this extractor only consumes the former.
const messages = (
JSON.parse(JSON.parse(output).results) as Array<
{type: 'extracted' | 'translation'} & SourceExtractedMessage
>
)
.filter((item) => item.type === 'extracted')
.map((item) => ({
id: item.id,
message: item.message,
description: item.description,
reference: item.reference
}));

const extractionResult = {
code: result.code,
Expand Down
2 changes: 1 addition & 1 deletion packages/next-intl/src/extractor/types.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ export type ExtractorMessageReference = {
};

/** A single statically extracted source-code usage before any aggregation. */
export type SourceMessage = {
export type SourceExtractedMessage = {
id: string;
message: string;
description: string | null;
Expand Down
Loading
Loading