Skip to content

Commit

Permalink
Merge pull request #3 from nutgaard/feat/inject-timezone
Browse files Browse the repository at this point in the history
feat(tz): inject timezone into datetime skeletons
  • Loading branch information
nutgaard authored Jan 25, 2024
2 parents c512c99 + e343704 commit 0732761
Show file tree
Hide file tree
Showing 9 changed files with 111 additions and 9 deletions.
4 changes: 2 additions & 2 deletions .github/workflows/master.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ jobs:
runs-on: ubuntu-latest
strategy:
matrix:
node: [ 16, 18, 19 ]
node: [ 16, 18, 20 ]
steps:
- uses: actions/checkout@v1
- uses: actions/setup-node@v3
Expand All @@ -42,7 +42,7 @@ jobs:
# env:
# GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Publish package
if: ${{ matrix.node == '18' }}
if: ${{ matrix.node == '20' }}
run: npx semantic-release
env:
GITHUB_TOKEN: ${{secrets.GITHUB_TOKEN}}
Expand Down
6 changes: 4 additions & 2 deletions example/compiled/bundle_en.compiled.json
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,8 @@
"parsedOptions": {
"hour": "2-digit",
"hourCycle": "h23",
"minute": "2-digit"
"minute": "2-digit",
"timeZone": "Europe/Oslo"
},
"pattern": "HHmm",
"type": 1
Expand All @@ -49,7 +50,8 @@
"style": {
"parsedOptions": {
"day": "2-digit",
"month": "short"
"month": "short",
"timeZone": "Europe/Oslo"
},
"pattern": "ddMMM",
"type": 1
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@
"prepare": "husky install",
"commit": "git-cz",
"test": "vitest --coverage",
"test-local": "node lib/index.js build example/messages example/compiled -f formatjs --ast --lut --strict --typescript",
"test-local": "node lib/index.js build example/messages example/compiled -f formatjs --ast --lut --strict --typescript --timeZone Europe/Oslo",
"build": "rm -rf lib && tsc -p ."
},
"author": "Nicklas Utgaard",
Expand Down
25 changes: 21 additions & 4 deletions src/builder/compile-formatjs-bundle.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,19 @@
*/
import { Opts } from '@formatjs/cli-lib/src/compile';
import { resolveBuiltinFormatter } from '@formatjs/cli-lib/src/formatters';
import { MessageFormatElement } from '@formatjs/icu-messageformat-parser/types';
import { parse } from '@formatjs/icu-messageformat-parser';
import {
parse,
isDateElement,
isTimeElement,
isDateTimeSkeleton,
MessageFormatElement,
} from '@formatjs/icu-messageformat-parser';
import stringify from 'json-stable-stringify';
import { getFilesystem } from '../utils/get-filesystem';

export async function compile(inputFiles: string[], opts: Opts = {}): Promise<string> {
export type TZOpts = Opts & { timeZone?: string };

export async function compile(inputFiles: string[], opts: TZOpts = {}): Promise<string> {
const fs = getFilesystem();
const { ast, format, skipErrors } = opts;
const formatter = await resolveBuiltinFormatter(format);
Expand All @@ -36,7 +43,7 @@ Message from ${inputFile}: ${compiled[id]}
`);
}
try {
const msgAst = parse(compiled[id]);
const msgAst = injectTimeZone(opts.timeZone, parse(compiled[id]));
messages[id] = compiled[id];
messageAsts[id] = msgAst;
idsWithFileName[id] = inputFile;
Expand All @@ -54,3 +61,13 @@ Message from ${inputFile}: ${compiled[id]}
cmp: formatter.compareMessages || undefined,
});
}

function injectTimeZone(timeZone: string | undefined, parts: MessageFormatElement[]): MessageFormatElement[] {
if (!timeZone) return parts;
return parts.map((part) => {
if ((isDateElement(part) || isTimeElement(part)) && isDateTimeSkeleton(part.style)) {
part.style.parsedOptions.timeZone = timeZone;
}
return part;
});
}
1 change: 1 addition & 0 deletions src/commands/build.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ export default class Build {
const compiledFilename = path.join(config.outDir, `bundle_${locale}.compiled.json`);
const compiledBundle = await compile([filename], {
ast: true,
timeZone: config.timeZone,
});
fs.writeFileSync(compiledFilename, compiledBundle, { encoding: 'utf-8' });
}
Expand Down
1 change: 1 addition & 0 deletions src/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ export interface BuildOptions {
strict: boolean;
ast: boolean;
lut: boolean;
timeZone?: string;
exitOnError?: boolean;
hasFixerListener?: boolean;
}
Expand Down
1 change: 1 addition & 0 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ program
.option('--strict', 'Run validation before bundling', { default: false })
.option('--ast', 'Compile generated bundles (only availble with formatjs)', { default: false })
.option('--lut', 'Generate look-up-table', { default: false })
.option('-t, --timeZone <timezone>', 'Inject timezone into date/time skeletons')
.action(({ logger, args, options }) => {
BuildCmd.run(logger, { ...args, ...options } as unknown as BuildOptions);
});
Expand Down
59 changes: 59 additions & 0 deletions test/commands/__snapshots__/build.test.ts.snap
Original file line number Diff line number Diff line change
Expand Up @@ -521,3 +521,62 @@ export function createIntlLUT(intl: IntlShape<React.ReactNode>) {
}",
}
`;
exports[`build command > should should inject timezone into skeletons 1`] = `
{
"/app/compiled/bundle_en.compiled.json": "{
\\"date\\": [
{
\\"type\\": 0,
\\"value\\": \\"starts \\"
},
{
\\"style\\": {
\\"parsedOptions\\": {
\\"day\\": \\"2-digit\\",
\\"month\\": \\"short\\",
\\"timeZone\\": \\"Europe/Oslo\\"
},
\\"pattern\\": \\"ddMMM\\",
\\"type\\": 1
},
\\"type\\": 3,
\\"value\\": \\"date\\"
},
{
\\"type\\": 0,
\\"value\\": \\" at \\"
},
{
\\"style\\": {
\\"parsedOptions\\": {
\\"hour\\": \\"2-digit\\",
\\"hourCycle\\": \\"h23\\",
\\"minute\\": \\"2-digit\\",
\\"timeZone\\": \\"Europe/Oslo\\"
},
\\"pattern\\": \\"HHmm\\",
\\"type\\": 1
},
\\"type\\": 3,
\\"value\\": \\"date\\"
}
]
}",
"/app/compiled/bundle_en.json": "{
\\"date\\": {
\\"defaultMessage\\": \\"starts { date, date, ::ddMMM } at { date, date, ::HHmm }\\"
}
}",
"/app/compiled/lut.ts": "import React from \\"react\\";
import {IntlShape} from \\"@formatjs/intl\\";
// @ts-ignore
import {FormatXMLElementFn} from \\"intl-messageformat\\";
export function createIntlLUT(intl: IntlShape<React.ReactNode>) {
return {
\\"date\\": (args: { date: Date }) => intl.formatMessage({ id: 'date' }, {date: args.date}),
}
}",
}
`;
21 changes: 21 additions & 0 deletions test/commands/build.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,27 @@ describe('build command', () => {
expect(vol.toJSON('/app/compiled')).toMatchSnapshot();
});

it('should should inject timezone into skeletons', async () => {
vol.fromNestedJSON(
{
'date_en.txt': 'starts { date, date, ::ddMMM } at { date, date, ::HHmm }',
},
'/app/messages',
);

await Build.run(createLogger(), {
...defaultConfig,
strict: true,
typescript: true,
ast: true,
lut: true,
format: 'formatjs',
timeZone: 'Europe/Oslo',
});

expect(vol.toJSON('/app/compiled')).toMatchSnapshot();
});

it('should throw error if validation is enabled and texts mismatch', async () => {
vol.fromNestedJSON(
{
Expand Down

0 comments on commit 0732761

Please sign in to comment.