Skip to content

Commit

Permalink
Attempt at exporting individual modules
Browse files Browse the repository at this point in the history
  • Loading branch information
amannn committed Jul 11, 2023
1 parent 81cc026 commit 357d76f
Show file tree
Hide file tree
Showing 16 changed files with 203 additions and 71 deletions.
2 changes: 1 addition & 1 deletion packages/next-intl/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
},
"scripts": {
"build": "pnpm build:default && pnpm build:rsc",
"build:default": "rm -rf dist && dts build",
"build:default": "rm -rf dist && dts build --entry src/index.tsx --entry src/client.tsx --entry src/link.tsx --entry src/middleware.tsx --entry src/server.tsx",
"build:rsc": "tsc && rm -rf dist/test",
"test": "TZ=Europe/Berlin vitest",
"lint": "eslint src test && tsc --noEmit",
Expand Down
1 change: 1 addition & 0 deletions packages/next-intl/src/client.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from './client/index';
1 change: 1 addition & 0 deletions packages/next-intl/src/link.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export {default} from './link/index';
1 change: 1 addition & 0 deletions packages/next-intl/src/middleware.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export {default} from './middleware/index';
119 changes: 119 additions & 0 deletions packages/next-intl/src/react-server/getBaseTranslator.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
import {ReactElement, ReactNodeArray, cache} from 'react';
import {
Formats,
TranslationValues,
RichTranslationValues,
MessageKeys,
NamespaceKeys,
NestedKeyOf,
NestedValueOf,
createBaseTranslator
} from 'use-intl/core';
import getConfig from '../server/getConfig';

let hasWarned = false;

async function getTranslatorImpl<
NestedKey extends NamespaceKeys<
IntlMessages,
NestedKeyOf<IntlMessages>
> = never
>(
locale:
| string
| {
namespace?: NestedKey;
locale: string;
},
namespace?: NestedKey
): // Explicitly defining the return type is necessary as TypeScript would get it wrong
Promise<{
// Default invocation
<
TargetKey extends MessageKeys<
NestedValueOf<
{'!': IntlMessages},
[NestedKey] extends [never] ? '!' : `!.${NestedKey}`
>,
NestedKeyOf<
NestedValueOf<
{'!': IntlMessages},
[NestedKey] extends [never] ? '!' : `!.${NestedKey}`
>
>
>
>(
key: TargetKey,
values?: TranslationValues,
formats?: Partial<Formats>
): string;

// `rich`
rich<
TargetKey extends MessageKeys<
NestedValueOf<
{'!': IntlMessages},
[NestedKey] extends [never] ? '!' : `!.${NestedKey}`
>,
NestedKeyOf<
NestedValueOf<
{'!': IntlMessages},
[NestedKey] extends [never] ? '!' : `!.${NestedKey}`
>
>
>
>(
key: TargetKey,
values?: RichTranslationValues,
formats?: Partial<Formats>
): string | ReactElement | ReactNodeArray;

// `raw`
raw<
TargetKey extends MessageKeys<
NestedValueOf<
{'!': IntlMessages},
[NestedKey] extends [never] ? '!' : `!.${NestedKey}`
>,
NestedKeyOf<
NestedValueOf<
{'!': IntlMessages},
[NestedKey] extends [never] ? '!' : `!.${NestedKey}`
>
>
>
>(
key: TargetKey
): any;
}> {
if (typeof locale === 'object') {
const opts = locale;
namespace = opts.namespace;
locale = opts.locale;
if (!hasWarned) {
console.warn(
`
DEPRECATION WARNING: Calling \`getTranslator\` with an object argument is deprecated, please update your call site accordingly.
// Previously
getTranslator({locale: 'en', namespace: 'About'});
// Now
getTranslator('en', 'About');
See also https://next-intl-docs.vercel.app/docs/environments/metadata-route-handlers
`
);
hasWarned = true;
}
}

const config = await getConfig(locale);
return createBaseTranslator({
...config,
namespace,
messages: config.messages
});
}

export default cache(getTranslatorImpl);
12 changes: 7 additions & 5 deletions packages/next-intl/src/react-server/useTranslations.tsx
Original file line number Diff line number Diff line change
@@ -1,15 +1,17 @@
import type {useTranslations as useTranslationsType} from 'use-intl';
import getTranslator from '../server/getTranslator';
import getBaseTranslator from './getBaseTranslator';
import useHook from './useHook';
import useLocale from './useLocale';

export default function useTranslations(
...[namespace]: Parameters<typeof useTranslationsType>
): ReturnType<typeof useTranslationsType> {
const locale = useLocale();
const result = useHook('useTranslations', getTranslator(locale, namespace));

// The types are slightly off here and indicate that rich text formatting
// doesn't integrate with React - this is not the case.
return result as any;
const result = useHook(
'useTranslations',
getBaseTranslator(locale, namespace)
);

return result;
}
1 change: 1 addition & 0 deletions packages/next-intl/src/server.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from './server/index';
39 changes: 14 additions & 25 deletions packages/next-intl/src/server/getTranslations.tsx
Original file line number Diff line number Diff line change
@@ -1,15 +1,14 @@
/* eslint-disable import/default */

import {cache} from 'react';
import type {Formats, TranslationValues} from 'use-intl/core';
import createBaseTranslator, {
getMessagesOrError
} from 'use-intl/dist/src/core/createBaseTranslator';
import {CoreRichTranslationValues} from 'use-intl/dist/src/core/createTranslatorImpl';
import MessageKeys from 'use-intl/dist/src/core/utils/MessageKeys';
import NamespaceKeys from 'use-intl/dist/src/core/utils/NamespaceKeys';
import NestedKeyOf from 'use-intl/dist/src/core/utils/NestedKeyOf';
import NestedValueOf from 'use-intl/dist/src/core/utils/NestedValueOf';
import {
createTranslator,
Formats,
TranslationValues,
RichTranslationValuesPlain,
MessageKeys,
NamespaceKeys,
NestedKeyOf,
NestedValueOf
} from 'use-intl/core';
import getConfig from './getConfig';
import getLocaleFromHeader from './getLocaleFromHeader';

Expand Down Expand Up @@ -60,7 +59,7 @@ Promise<{
>
>(
key: TargetKey,
values?: CoreRichTranslationValues,
values?: RichTranslationValuesPlain,
formats?: Partial<Formats>
): string;

Expand Down Expand Up @@ -94,20 +93,10 @@ Learn more: https://next-intl-docs.vercel.app/docs/environments/metadata-route-h
const locale = getLocaleFromHeader();
const config = await getConfig(locale);

const messagesOrError = getMessagesOrError({
messages: config.messages as any,
namespace,
onError: config.onError
});

// We allow to resolve rich text formatting here, but the types forbid it when
// `getTranslations` is used directly. Supporting rich text is important when
// the react-server implementation calls into this function.
// @ts-ignore
return createBaseTranslator({
return createTranslator({
...config,
namespace,
messagesOrError
messages: config.messages || {},
namespace
});
}

Expand Down
21 changes: 12 additions & 9 deletions packages/next-intl/src/server/getTranslator.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
/* eslint-disable import/default */

import {cache} from 'react';
import {createTranslator, Formats, TranslationValues} from 'use-intl/core';
import {CoreRichTranslationValues} from 'use-intl/dist/src/core/createTranslatorImpl';
import MessageKeys from 'use-intl/dist/src/core/utils/MessageKeys';
import NamespaceKeys from 'use-intl/dist/src/core/utils/NamespaceKeys';
import NestedKeyOf from 'use-intl/dist/src/core/utils/NestedKeyOf';
import NestedValueOf from 'use-intl/dist/src/core/utils/NestedValueOf';
import {
createTranslator,
Formats,
TranslationValues,
RichTranslationValuesPlain,
MessageKeys,
NamespaceKeys,
NestedKeyOf,
NestedValueOf
} from 'use-intl/core';
import getConfig from './getConfig';

let hasWarned = false;
Expand Down Expand Up @@ -62,7 +64,7 @@ Promise<{
>
>(
key: TargetKey,
values?: CoreRichTranslationValues,
values?: RichTranslationValuesPlain,
formats?: Partial<Formats>
): string;

Expand Down Expand Up @@ -110,6 +112,7 @@ See also https://next-intl-docs.vercel.app/docs/environments/metadata-route-hand

return createTranslator({
...config,
messages: config.messages || {},
namespace
});
}
Expand Down
2 changes: 1 addition & 1 deletion packages/next-intl/test/server/getTranslator.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import {

vi.mock('next-intl/config', () => ({
default: async () =>
(await vi.importActual('../../src/server')).getRequestConfig({
((await vi.importActual('../../src/server')) as any).getRequestConfig({
locale: 'en',
now: new Date('2020-01-01T00:00:00.000Z'),
timeZone: 'Europe/London',
Expand Down
5 changes: 5 additions & 0 deletions packages/use-intl/src/core/TranslationValues.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,4 +19,9 @@ export type RichTranslationValues = Record<
TranslationValue | ((chunks: ReactNode) => ReactNode)
>;

export type RichTranslationValuesPlain = Record<
string,
TranslationValue | ((chunks: string) => string)
>;

export default TranslationValues;
16 changes: 16 additions & 0 deletions packages/use-intl/src/core/createBaseTranslator.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,22 @@ export type CreateBaseTranslatorProps<Messages> = InitializedIntlConfig & {
export default function createBaseTranslator<
Messages extends AbstractIntlMessages,
NestedKey extends NestedKeyOf<Messages>
>(config: Omit<CreateBaseTranslatorProps<Messages>, 'messagesOrError'>) {
const messagesOrError = getMessagesOrError({
messages: config.messages as any,
namespace: config.namespace,
onError: config.onError
}) as Messages | IntlError;

return createBaseTranslatorImpl<Messages, NestedKey>({
...config,
messagesOrError
});
}

function createBaseTranslatorImpl<
Messages extends AbstractIntlMessages,
NestedKey extends NestedKeyOf<Messages>
>({
cachedFormatsByLocale,
defaultTranslationValues,
Expand Down
10 changes: 5 additions & 5 deletions packages/use-intl/src/core/createTranslator.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import Formats from './Formats';
import IntlConfig from './IntlConfig';
import TranslationValues from './TranslationValues';
import createTranslatorImpl, {
CoreRichTranslationValues
} from './createTranslatorImpl';
import TranslationValues, {
RichTranslationValuesPlain
} from './TranslationValues';
import createTranslatorImpl from './createTranslatorImpl';
import {defaultGetMessageFallback, defaultOnError} from './defaults';
import MessageKeys from './utils/MessageKeys';
import NamespaceKeys from './utils/NamespaceKeys';
Expand Down Expand Up @@ -70,7 +70,7 @@ export default function createTranslator<
>
>(
key: TargetKey,
values?: CoreRichTranslationValues,
values?: RichTranslationValuesPlain,
formats?: Partial<Formats>
): string;

Expand Down
21 changes: 8 additions & 13 deletions packages/use-intl/src/core/createTranslatorImpl.tsx
Original file line number Diff line number Diff line change
@@ -1,16 +1,14 @@
import AbstractIntlMessages from './AbstractIntlMessages';
import {InitializedIntlConfig} from './IntlConfig';
import IntlError, {IntlErrorCode} from './IntlError';
import {RichTranslationValues, TranslationValue} from './TranslationValues';
import createBaseTranslator, {getMessagesOrError} from './createBaseTranslator';
import {
RichTranslationValues,
RichTranslationValuesPlain
} from './TranslationValues';
import createBaseTranslator from './createBaseTranslator';
import resolveNamespace from './resolveNamespace';
import NestedKeyOf from './utils/NestedKeyOf';

export type CoreRichTranslationValues = Record<
string,
TranslationValue | ((chunks: string) => string)
>;

export type CreateTranslatorImplProps<Messages> = Omit<
InitializedIntlConfig,
'messages'
Expand Down Expand Up @@ -41,11 +39,8 @@ export default function createTranslatorImpl<
...rest,
onError,
getMessageFallback,
messagesOrError: getMessagesOrError({
messages,
namespace,
onError
}) as Messages | IntlError
messages,
namespace
});

const originalRich = translator.rich;
Expand All @@ -58,7 +53,7 @@ export default function createTranslatorImpl<
base.rich = (
key: Parameters<typeof originalRich>[0],
/** Key value pairs for values to interpolate into the message. */
values: CoreRichTranslationValues,
values: RichTranslationValuesPlain,
formats?: Parameters<typeof originalRich>[2]
): string => {
// `chunks` is returned as a string when no React element
Expand Down
8 changes: 7 additions & 1 deletion packages/use-intl/src/core/index.tsx
Original file line number Diff line number Diff line change
@@ -1,16 +1,22 @@
export type {default as AbstractIntlMessages} from './AbstractIntlMessages';
export type {
default as TranslationValues,
RichTranslationValues
RichTranslationValues,
RichTranslationValuesPlain
} from './TranslationValues';
export type {default as Formats} from './Formats';
export type {default as IntlConfig} from './IntlConfig';
export type {default as DateTimeFormatOptions} from './DateTimeFormatOptions';
export type {default as NumberFormatOptions} from './NumberFormatOptions';
export {default as IntlError, IntlErrorCode} from './IntlError';
export {default as createTranslator} from './createTranslator';
export {default as createBaseTranslator} from './createBaseTranslator';
export {default as createFormatter} from './createFormatter';
export {default as initializeConfig} from './initializeConfig';
export {default as MessageKeys} from './utils/MessageKeys';
export {default as NamespaceKeys} from './utils/NamespaceKeys';
export {default as NestedKeyOf} from './utils/NestedKeyOf';
export {default as NestedValueOf} from './utils/NestedValueOf';

// TODO: Remove in next major version
export {default as createIntl} from './createIntl';
Loading

0 comments on commit 357d76f

Please sign in to comment.