@inlang/sdk
Advanced tools
Comparing version 0.15.0 to 0.16.0
@@ -35,2 +35,8 @@ import type { ValueError } from "@sinclair/typebox/errors"; | ||
} | ||
export declare class ModuleSettingsAreInvalidError extends ModuleError { | ||
constructor(options: { | ||
module: string; | ||
errors: ValueError[]; | ||
}); | ||
} | ||
//# sourceMappingURL=errors.d.ts.map |
@@ -38,1 +38,9 @@ export * from "./plugins/errors.js"; | ||
} | ||
export class ModuleSettingsAreInvalidError extends ModuleError { | ||
constructor(options) { | ||
super(`The settings are invalid of "${module}" are invalid:\n\n${options.errors | ||
.map((error) => `Path "${error.path}" with value "${error.value}": "${error.message}"`) | ||
.join("\n")}`, options); | ||
this.name = "ModuleSettingsAreInvalidError"; | ||
} | ||
} |
import { InlangModule } from "@inlang/module"; | ||
import { ModuleError, ModuleImportError, ModuleHasNoExportsError, ModuleExportIsInvalidError, } from "./errors.js"; | ||
import { ModuleError, ModuleImportError, ModuleHasNoExportsError, ModuleExportIsInvalidError, ModuleSettingsAreInvalidError, } from "./errors.js"; | ||
import { tryCatch } from "@inlang/result"; | ||
@@ -8,2 +8,3 @@ import { resolveMessageLintRules } from "./message-lint-rules/resolveMessageLintRules.js"; | ||
import { TypeCompiler } from "@sinclair/typebox/compiler"; | ||
import { validatedModuleSettings } from "./validatedModuleSettings.js"; | ||
const ModuleCompiler = TypeCompiler.Compile(InlangModule); | ||
@@ -36,2 +37,3 @@ export const resolveModules = async (args) => { | ||
} | ||
// -- CHECK IF MODULE IS SYNTACTIALLY VALID | ||
const isValidModule = ModuleCompiler.Check(importedModule.data); | ||
@@ -46,2 +48,11 @@ if (isValidModule === false) { | ||
} | ||
// -- VALIDATE MODULE SETTINGS | ||
const result = validatedModuleSettings({ | ||
settingsSchema: importedModule.data.default.settingsSchema, | ||
moduleSettings: args.settings[importedModule.data.default.id], | ||
}); | ||
if (result !== "isValid") { | ||
moduleErrors.push(new ModuleSettingsAreInvalidError({ module: module, errors: result })); | ||
continue; | ||
} | ||
meta.push({ | ||
@@ -58,3 +69,3 @@ module: module, | ||
else { | ||
throw new Error(`Unimplemented module type. Must start with "plugin." or "messageLintRule.`); | ||
moduleErrors.push(new ModuleError(`Unimplemented module type ${importedModule.data.default.id}.The module has not been installed.`, { module: module })); | ||
} | ||
@@ -61,0 +72,0 @@ } |
import { expect, it } from "vitest"; | ||
import { ModuleError, ModuleExportIsInvalidError, ModuleHasNoExportsError, ModuleImportError, } from "./errors.js"; | ||
import { ModuleError, ModuleExportIsInvalidError, ModuleHasNoExportsError, ModuleImportError, ModuleSettingsAreInvalidError, } from "./errors.js"; | ||
import { resolveModules } from "./resolveModules.js"; | ||
import { Type } from "@sinclair/typebox"; | ||
it("should return an error if a plugin cannot be imported", async () => { | ||
@@ -130,1 +131,25 @@ const settings = { | ||
}); | ||
it("should return an error if a moduleSettings are invalid", async () => { | ||
const settings = { | ||
sourceLanguageTag: "en", | ||
languageTags: ["de", "en"], | ||
modules: ["plugin.js"], | ||
"plugin.namespace.mock": { | ||
ignore: ["invalid"], | ||
}, | ||
}; | ||
const _import = async () => ({ | ||
default: { | ||
id: "plugin.namespace.mock", | ||
description: { en: "Mock plugin description" }, | ||
displayName: { en: "Mock Plugin" }, | ||
settingsSchema: Type.Object({ | ||
ignore: Type.String(), | ||
}), | ||
}, | ||
}); | ||
// Call the function | ||
const resolved = await resolveModules({ settings, _import, nodeishFs: {} }); | ||
// Assert results | ||
expect(resolved.errors[0]).toBeInstanceOf(ModuleSettingsAreInvalidError); | ||
}); |
{ | ||
"name": "@inlang/sdk", | ||
"type": "module", | ||
"version": "0.15.0", | ||
"version": "0.16.0", | ||
"license": "Apache-2.0", | ||
@@ -6,0 +6,0 @@ "publishConfig": { |
@@ -35,2 +35,3 @@ /* eslint-disable @typescript-eslint/no-non-null-assertion */ | ||
displayName: { en: "Mock Plugin" }, | ||
loadMessages: () => exampleMessages, | ||
@@ -80,2 +81,3 @@ saveMessages: () => undefined, | ||
displayName: { en: "Mock Lint Rule" }, | ||
run: () => undefined, | ||
@@ -184,2 +186,3 @@ } | ||
}, | ||
loadMessages: ({ settings }) => (settings.languageTags.length ? exampleMessages : []), | ||
@@ -186,0 +189,0 @@ saveMessages: () => undefined, |
@@ -10,2 +10,3 @@ import { beforeEach, describe, expect, test, vi } from "vitest" | ||
description: { en: "" }, | ||
run: vi.fn(), | ||
@@ -18,2 +19,3 @@ } satisfies MessageLintRule | ||
description: { en: "" }, | ||
run: vi.fn(), | ||
@@ -20,0 +22,0 @@ } satisfies MessageLintRule |
@@ -11,2 +11,3 @@ import { beforeEach, describe, expect, test, vi } from "vitest" | ||
description: "", | ||
run: vi.fn(), | ||
@@ -19,2 +20,3 @@ } satisfies MessageLintRule | ||
description: "", | ||
run: vi.fn(), | ||
@@ -21,0 +23,0 @@ } satisfies MessageLintRule |
@@ -42,2 +42,3 @@ /* eslint-disable @typescript-eslint/no-non-null-assertion */ | ||
displayName: { en: "Mock Plugin" }, | ||
loadMessages: () => exampleMessages, | ||
@@ -429,2 +430,3 @@ saveMessages: () => undefined as any, | ||
displayName: { en: "Mock Plugin" }, | ||
loadMessages: () => [{ id: "some-message", selectors: [], variants: [] }], | ||
@@ -467,2 +469,3 @@ saveMessages: () => undefined, | ||
displayName: { en: "Mock Lint Rule" }, | ||
run: ({ report }) => { | ||
@@ -480,2 +483,3 @@ report({ | ||
displayName: { en: "Mock Plugin" }, | ||
loadMessages: () => [{ id: "some-message", selectors: [], variants: [] }], | ||
@@ -586,2 +590,3 @@ saveMessages: () => undefined, | ||
displayName: { en: "Mock Plugin" }, | ||
loadMessages: () => exampleMessages, | ||
@@ -761,2 +766,3 @@ saveMessages: mockSaveFn, | ||
displayName: "Mock Plugin", | ||
loadMessages: () => [ | ||
@@ -763,0 +769,0 @@ createMessage("first", { en: "first message" }), |
@@ -50,1 +50,13 @@ import type { ValueError } from "@sinclair/typebox/errors" | ||
} | ||
export class ModuleSettingsAreInvalidError extends ModuleError { | ||
constructor(options: { module: string; errors: ValueError[] }) { | ||
super( | ||
`The settings are invalid of "${module}" are invalid:\n\n${options.errors | ||
.map((error) => `Path "${error.path}" with value "${error.value}": "${error.message}"`) | ||
.join("\n")}`, | ||
options | ||
) | ||
this.name = "ModuleSettingsAreInvalidError" | ||
} | ||
} |
@@ -117,2 +117,3 @@ /* eslint-disable @typescript-eslint/no-non-null-assertion */ | ||
displayName: { en: "My plugin" }, | ||
loadMessages: async () => undefined as any, | ||
@@ -124,2 +125,3 @@ } | ||
displayName: { en: "My plugin" }, | ||
loadMessages: async () => undefined as any, | ||
@@ -142,2 +144,3 @@ } | ||
displayName: { en: "My plugin" }, | ||
saveMessages: async () => undefined as any, | ||
@@ -187,3 +190,2 @@ } | ||
displayName: { en: "My plugin" }, | ||
saveMessages: async () => undefined as any, | ||
@@ -206,2 +208,3 @@ } | ||
displayName: { en: "My plugin" }, | ||
loadMessages: async () => undefined as any, | ||
@@ -226,3 +229,2 @@ } | ||
displayName: { en: "My plugin" }, | ||
addCustomApi: () => ({ | ||
@@ -262,3 +264,2 @@ "my-app": { | ||
displayName: { en: "My plugin" }, | ||
addCustomApi: () => ({ | ||
@@ -265,0 +266,0 @@ "my-app-3": { |
@@ -10,2 +10,3 @@ /* eslint-disable @typescript-eslint/no-non-null-assertion */ | ||
ModuleImportError, | ||
ModuleSettingsAreInvalidError, | ||
} from "./errors.js" | ||
@@ -15,2 +16,3 @@ import { resolveModules } from "./resolveModules.js" | ||
import type { InlangModule } from "@inlang/module" | ||
import { Type } from "@sinclair/typebox" | ||
@@ -44,2 +46,3 @@ it("should return an error if a plugin cannot be imported", async () => { | ||
displayName: { en: "Mock Plugin" }, | ||
loadMessages: () => undefined as any, | ||
@@ -58,2 +61,3 @@ saveMessages: () => undefined as any, | ||
displayName: { en: "Mock Lint Rule" }, | ||
run: () => undefined, | ||
@@ -167,1 +171,28 @@ } | ||
}) | ||
it("should return an error if a moduleSettings are invalid", async () => { | ||
const settings: ProjectSettings = { | ||
sourceLanguageTag: "en", | ||
languageTags: ["de", "en"], | ||
modules: ["plugin.js"], | ||
"plugin.namespace.mock": { | ||
ignore: ["invalid"], | ||
}, | ||
} | ||
const _import = async () => ({ | ||
default: { | ||
id: "plugin.namespace.mock", | ||
description: { en: "Mock plugin description" }, | ||
displayName: { en: "Mock Plugin" }, | ||
settingsSchema: Type.Object({ | ||
ignore: Type.String(), | ||
}), | ||
}, | ||
}) | ||
// Call the function | ||
const resolved = await resolveModules({ settings, _import, nodeishFs: {} as any }) | ||
// Assert results | ||
expect(resolved.errors[0]).toBeInstanceOf(ModuleSettingsAreInvalidError) | ||
}) |
@@ -8,2 +8,3 @@ import type { ResolveModuleFunction } from "./types.js" | ||
ModuleExportIsInvalidError, | ||
ModuleSettingsAreInvalidError, | ||
} from "./errors.js" | ||
@@ -17,2 +18,3 @@ import { tryCatch } from "@inlang/result" | ||
import { TypeCompiler } from "@sinclair/typebox/compiler" | ||
import { validatedModuleSettings } from "./validatedModuleSettings.js" | ||
@@ -36,4 +38,4 @@ const ModuleCompiler = TypeCompiler.Compile(InlangModule) | ||
const importedModule = await tryCatch<InlangModule>(() => _import(module)) | ||
// -- IMPORT MODULE -- | ||
// -- IMPORT MODULE -- | ||
if (importedModule.error) { | ||
@@ -50,2 +52,3 @@ moduleErrors.push( | ||
// -- MODULE DOES NOT EXPORT ANYTHING -- | ||
if (importedModule.data?.default === undefined) { | ||
@@ -60,4 +63,5 @@ moduleErrors.push( | ||
// -- CHECK IF MODULE IS SYNTACTIALLY VALID | ||
const isValidModule = ModuleCompiler.Check(importedModule.data) | ||
if (isValidModule === false) { | ||
@@ -71,5 +75,17 @@ const errors = [...ModuleCompiler.Errors(importedModule.data)] | ||
) | ||
continue | ||
} | ||
// -- VALIDATE MODULE SETTINGS | ||
const result = validatedModuleSettings({ | ||
settingsSchema: importedModule.data.default.settingsSchema, | ||
moduleSettings: args.settings[importedModule.data.default.id], | ||
}) | ||
if (result !== "isValid") { | ||
moduleErrors.push(new ModuleSettingsAreInvalidError({ module: module, errors: result })) | ||
continue | ||
} | ||
meta.push({ | ||
@@ -85,6 +101,10 @@ module: module, | ||
} else { | ||
throw new Error(`Unimplemented module type. Must start with "plugin." or "messageLintRule.`) | ||
moduleErrors.push( | ||
new ModuleError( | ||
`Unimplemented module type ${importedModule.data.default.id}.The module has not been installed.`, | ||
{ module: module } | ||
) | ||
) | ||
} | ||
} | ||
const resolvedPlugins = await resolvePlugins({ | ||
@@ -91,0 +111,0 @@ plugins: allPlugins, |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
370624
198
9526