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
5 changes: 3 additions & 2 deletions src/hyperjump-json-schema.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import "@hyperjump/json-schema/formats";
import { BASIC } from "@hyperjump/json-schema/experimental";
import { jsonSchemaErrors } from "../src/index.js";
import { FluentBundle, FluentResource } from "@fluent/bundle";
import { translations } from "./translations/index.js";

/**
* @import { SchemaObject } from "@hyperjump/json-schema"
Expand Down Expand Up @@ -153,8 +154,8 @@ const isCompatible = (compatibility, versionUnderTest) => {
};

/** @type (messageId: string, messageParams: MessageParams) => string */
const getMessage = await (async function () {
const ftl = await readFile(`${import.meta.dirname}/translations/en-US.ftl`, "utf-8");
const getMessage = (function () {
const ftl = translations["en-US"];
const resource = new FluentResource(ftl);
const bundle = new FluentBundle("en-US");
bundle.addResource(resource);
Expand Down
4 changes: 2 additions & 2 deletions src/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -172,10 +172,10 @@ export type ContainsRange = {
export const validate: (
(schemaUri: string) => Promise<EvaluateInstance>
) & (
(schemaUri: string, instance: Json, options?: ValidationOptions) => Promise<ValidationResult>
(schemaUri: string, instance: Json, options?: ValidationOptions) => ValidationResult
);

export type EvaluateInstance = (instance: Json, options?: ValidationOptions) => Promise<ValidationResult>;
export type EvaluateInstance = (instance: Json, options?: ValidationOptions) => ValidationResult;

export type ValidationOptions = {
/**
Expand Down
8 changes: 4 additions & 4 deletions src/json-schema-errors.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ export const jsonSchemaErrors = async (errorOutput, schemaUri, instance, options
errorIndex,
plugins: [...ast.plugins]
});
const localization = await Localization.forLocale(options.locale ?? "en-US");
const localization = Localization.forLocale(options.locale ?? "en-US");
return getErrors(normalizedErrors, rootInstance, localization, ast);
};

Expand Down Expand Up @@ -254,9 +254,9 @@ export const validate = async (schemaUri, instance, options) => {
}
};

/** @type (compiledSchema: CompiledSchema, instance: API.Json, options?: API.ValidationOptions) => Promise<API.ValidationResult> */
const evaluateCompiledSchema = async (compiledSchema, instance, options = {}) => {
const localization = await Localization.forLocale(options.locale ?? "en-US");
/** @type (compiledSchema: CompiledSchema, instance: API.Json, options?: API.ValidationOptions) => API.ValidationResult */
const evaluateCompiledSchema = (compiledSchema, instance, options = {}) => {
const localization = Localization.forLocale(options.locale ?? "en-US");
const jsonNode = Instance.fromJs(instance);
const outputPlugin = new JsonSchemaErrorsOutputPlugin();
const context = {
Expand Down
21 changes: 10 additions & 11 deletions src/localization.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { readFile } from "node:fs/promises";
import { translations } from "./translations/index.js";
import { FluentBundle, FluentResource } from "@fluent/bundle";

/**
Expand All @@ -21,18 +21,17 @@ export class Localization {
this.conjunction = new Intl.ListFormat(this.locale, { type: "conjunction" });
}

/** @type (locale: string) => Promise<Localization> */
static async forLocale(locale) {
/** @type (locale: string) => Localization */
static forLocale(locale) {
if (!localizationCache.has(locale)) {
try {
const ftl = await readFile(`${import.meta.dirname}/translations/${locale}.ftl`, "utf-8");
const resource = new FluentResource(ftl);
const bundle = new FluentBundle(locale);
bundle.addResource(resource);
localizationCache.set(locale, new Localization(locale, bundle));
} catch (error) {
throw Error(`The ${locale} locale is not supported.`, { cause: error });
const ftl = translations[locale];
if (!ftl) {
throw Error(`The ${locale} locale is not supported.`);
}
const resource = new FluentResource(ftl);
const bundle = new FluentBundle(locale);
bundle.addResource(resource);
localizationCache.set(locale, new Localization(locale, bundle));
}

return /** @type Localization */ (localizationCache.get(locale));
Expand Down
21 changes: 10 additions & 11 deletions src/localization.test.js
Original file line number Diff line number Diff line change
@@ -1,25 +1,24 @@
import { afterEach, beforeEach, describe, expect, test } from "vitest";
import { rm, writeFile } from "node:fs/promises";
import { beforeAll, afterAll, describe, expect, test } from "vitest";
import { translations } from "./translations/index.js";
import { Localization } from "./localization.js";

describe("Localization", () => {
const fixtureLocale = "fx-TR";

beforeEach(async () => {
await writeFile(`src/translations/${fixtureLocale}.ftl`, "example = message");
beforeAll(() => {
translations[fixtureLocale] = `test = unsupported locale`;
});

afterEach(async () => {
await rm(`src/translations/${fixtureLocale}.ftl`);
afterAll(() => {
delete translations[fixtureLocale];
});

test("unsupported locale", async () => {
const localization = Localization.forLocale("xx-XX");
await expect(localization).rejects.to.throw(Error);
test("unsupported locale", () => {
expect(() => Localization.forLocale("xx-XX")).to.throw(Error);
});

test("unsupported message", async () => {
const localization = await Localization.forLocale(fixtureLocale);
test("unsupported message", () => {
const localization = Localization.forLocale(fixtureLocale);
expect(() => localization.getBooleanSchemaErrorMessage()).to.throw(Error);
});
});
4 changes: 2 additions & 2 deletions src/normalization.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,9 @@ import { Localization } from "./localization.js";
* @import { OutputFormat } from "./index.js";
*/

describe("Normalization", async () => {
describe("Normalization", () => {
const schemaUri = "https://example.com/main";
const localization = await Localization.forLocale("en-US");
const localization = Localization.forLocale("en-US");

afterEach(() => {
unregisterSchema(schemaUri);
Expand Down
2 changes: 2 additions & 0 deletions src/translations/en-US.ftl → src/translations/en-US.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
export default `
// Any type keywords
boolean-schema-message = A value is not allowed here
type-message = Expected a {$expectedTypes}
Expand Down Expand Up @@ -47,3 +48,4 @@ oneOf-message = Expected the value to match exactly one alternative, {$matchCoun
*[other] but more than one
} matched
not-message = Expected a value that doesn't match the 'not' schema
`;
6 changes: 6 additions & 0 deletions src/translations/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import enUS from "./en-US.js";

/** @type Record<string, string> */
export const translations = {
"en-US": enUS
};