@inlang/sdk 0.1.0 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +4 -13
- package/dist/errors.d.ts +0 -6
- package/dist/errors.d.ts.map +1 -1
- package/dist/errors.js +0 -9
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/messages/variant.js +3 -4
- package/dist/openInlangProject.d.ts.map +1 -1
- package/dist/openInlangProject.js +2 -7
- package/dist/openInlangProject.test.js +2 -28
- package/dist/resolve-modules/import.d.ts +0 -6
- package/dist/resolve-modules/import.d.ts.map +1 -1
- package/dist/resolve-modules/import.js +1 -1
- package/dist/resolve-modules/import.test.js +0 -1
- package/dist/resolve-modules/plugins/errors.d.ts +3 -0
- package/dist/resolve-modules/plugins/errors.d.ts.map +1 -1
- package/dist/resolve-modules/plugins/errors.js +7 -0
- package/dist/resolve-modules/plugins/resolvePlugins.d.ts.map +1 -1
- package/dist/resolve-modules/plugins/resolvePlugins.js +6 -1
- package/dist/resolve-modules/plugins/resolvePlugins.test.js +36 -6
- package/dist/resolve-modules/plugins/types.d.ts +2 -2
- package/dist/resolve-modules/plugins/types.d.ts.map +1 -1
- package/dist/resolve-modules/resolveModules.js +1 -1
- package/dist/test-utilities/index.d.ts +1 -0
- package/dist/test-utilities/index.d.ts.map +1 -1
- package/dist/test-utilities/index.js +1 -0
- package/package.json +1 -2
- package/src/errors.ts +0 -12
- package/src/index.ts +0 -1
- package/src/messages/variant.ts +2 -3
- package/src/openInlangProject.test.ts +1 -36
- package/src/openInlangProject.ts +1 -9
- package/src/resolve-modules/import.test.ts +0 -1
- package/src/resolve-modules/import.ts +1 -7
- package/src/resolve-modules/plugins/errors.ts +8 -0
- package/src/resolve-modules/plugins/resolvePlugins.test.ts +41 -5
- package/src/resolve-modules/plugins/resolvePlugins.ts +14 -0
- package/src/resolve-modules/plugins/types.ts +2 -0
- package/src/resolve-modules/resolveModules.ts +2 -2
- package/src/test-utilities/index.ts +1 -0
package/README.md
CHANGED
|
@@ -2,24 +2,15 @@ Developer-first localization infrastructure that is built on git. Your git repos
|
|
|
2
2
|
|
|
3
3
|
<div>
|
|
4
4
|
<p align="center">
|
|
5
|
-
<img width="300" src="https://cdn.jsdelivr.net/gh/inlang/inlang/assets/logo-white-background.png"/>
|
|
5
|
+
<img width="300" src="https://cdn.jsdelivr.net/gh/inlang/monorepo/inlang/assets/logo-white-background.png"/>
|
|
6
6
|
</p>
|
|
7
7
|
<h4 align="center">
|
|
8
8
|
<!-- <a href="https://inlang.com/documentation" target="_blank">Get Started</a>
|
|
9
9
|
· -->
|
|
10
|
-
<a href="https://github.com/inlang/
|
|
10
|
+
<a href="https://github.com/inlang/monorepo/discussions" target="_blank">Discussions</a> · <a href="https://twitter.com/inlangHQ" target="_blank">Twitter</a>
|
|
11
11
|
</h4>
|
|
12
12
|
</div>
|
|
13
13
|
|
|
14
|
-
# @inlang/
|
|
14
|
+
# @inlang/sdk
|
|
15
15
|
|
|
16
|
-
The core module bundles "
|
|
17
|
-
|
|
18
|
-
## Modules
|
|
19
|
-
|
|
20
|
-
Click on the modules to get to their respective READMEs.
|
|
21
|
-
|
|
22
|
-
- [@inlang/core/ast](https://github.com/inlang/inlang/tree/main/source-code/core/src/ast/) - The AST.
|
|
23
|
-
- [@inlang/core/config](https://github.com/inlang/inlang/tree/main/source-code/core/src/config/) - The config that powers inlang.
|
|
24
|
-
- [@inlang/core/query](https://github.com/inlang/inlang/tree/main/source-code/core/src/query/) - A query module for the AST.
|
|
25
|
-
- [@inlang/core/utilities](https://github.com/inlang/inlang/tree/main/source-code/core/src/utilities/) - Utility types, functions, and more dealing that ease interactions with inlang, i18n, and localization.
|
|
16
|
+
The core module bundles "sdk" modules that depend on each other and is everything one needs to build [plugins](https://inlang.com/documentation/plugin) or entire [apps](https://inlang.com/documentation/develop-app) on inlang.
|
package/dist/errors.d.ts
CHANGED
|
@@ -13,10 +13,4 @@ export declare class PluginSaveMessagesError extends Error {
|
|
|
13
13
|
export declare class PluginLoadMessagesError extends Error {
|
|
14
14
|
constructor(message: string, options: ErrorOptions);
|
|
15
15
|
}
|
|
16
|
-
/**
|
|
17
|
-
* Error when no package provides the API to handle messages.
|
|
18
|
-
*/
|
|
19
|
-
export declare class NoPluginProvidesLoadOrSaveMessagesError extends Error {
|
|
20
|
-
constructor();
|
|
21
|
-
}
|
|
22
16
|
//# sourceMappingURL=errors.d.ts.map
|
package/dist/errors.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAAA,qBAAa,kBAAmB,SAAQ,KAAK;gBAChC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,YAAY;CAIlD;AAED,qBAAa,0BAA2B,SAAQ,KAAK;gBACxC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,YAAY;CAIlD;AAED,qBAAa,4BAA6B,SAAQ,KAAK;gBAC1C,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,YAAY;CAIlD;AAED,qBAAa,uBAAwB,SAAQ,KAAK;gBACrC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,YAAY;CAIlD;AAED,qBAAa,uBAAwB,SAAQ,KAAK;gBACrC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,YAAY;CAIlD
|
|
1
|
+
{"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAAA,qBAAa,kBAAmB,SAAQ,KAAK;gBAChC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,YAAY;CAIlD;AAED,qBAAa,0BAA2B,SAAQ,KAAK;gBACxC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,YAAY;CAIlD;AAED,qBAAa,4BAA6B,SAAQ,KAAK;gBAC1C,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,YAAY;CAIlD;AAED,qBAAa,uBAAwB,SAAQ,KAAK;gBACrC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,YAAY;CAIlD;AAED,qBAAa,uBAAwB,SAAQ,KAAK;gBACrC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,YAAY;CAIlD"}
|
package/dist/errors.js
CHANGED
|
@@ -28,12 +28,3 @@ export class PluginLoadMessagesError extends Error {
|
|
|
28
28
|
this.name = "PluginLoadMessagesError";
|
|
29
29
|
}
|
|
30
30
|
}
|
|
31
|
-
/**
|
|
32
|
-
* Error when no package provides the API to handle messages.
|
|
33
|
-
*/
|
|
34
|
-
export class NoPluginProvidesLoadOrSaveMessagesError extends Error {
|
|
35
|
-
constructor() {
|
|
36
|
-
super("It seems you did not install any plugin that handles messages. Please add one to make inlang work. See https://inlang.com/documentation/plugins/registry."); // TODO: check if link is correct
|
|
37
|
-
this.name = "NoPluginProvidesLoadOrSaveMessagesError";
|
|
38
|
-
}
|
|
39
|
-
}
|
package/dist/index.d.ts
CHANGED
|
@@ -8,7 +8,7 @@ export { type ImportFunction, createImport } from "./resolve-modules/index.js";
|
|
|
8
8
|
export { openInlangProject } from "./openInlangProject.js";
|
|
9
9
|
export { solidAdapter, type InlangProjectWithSolidAdapter } from "./adapter/solidAdapter.js";
|
|
10
10
|
export { createMessagesQuery } from "./createMessagesQuery.js";
|
|
11
|
-
export { ProjectFilePathNotFoundError, ProjectFileJSONSyntaxError, InvalidConfigError,
|
|
11
|
+
export { ProjectFilePathNotFoundError, ProjectFileJSONSyntaxError, InvalidConfigError, PluginLoadMessagesError, PluginSaveMessagesError, } from "./errors.js";
|
|
12
12
|
export * from "./messages/variant.js";
|
|
13
13
|
export * from "./versionedInterfaces.js";
|
|
14
14
|
export { InlangModule } from "@inlang/module";
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,YAAY,EACX,aAAa,EACb,wBAAwB,EACxB,eAAe,EACf,eAAe,EACf,YAAY,GACZ,MAAM,UAAU,CAAA;AACjB,OAAO,EAAE,KAAK,cAAc,EAAE,YAAY,EAAE,MAAM,4BAA4B,CAAA;AAC9E,OAAO,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAA;AAC1D,OAAO,EAAE,YAAY,EAAE,KAAK,6BAA6B,EAAE,MAAM,2BAA2B,CAAA;AAC5F,OAAO,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAA;AAC9D,OAAO,EACN,4BAA4B,EAC5B,0BAA0B,EAC1B,kBAAkB,EAClB,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,YAAY,EACX,aAAa,EACb,wBAAwB,EACxB,eAAe,EACf,eAAe,EACf,YAAY,GACZ,MAAM,UAAU,CAAA;AACjB,OAAO,EAAE,KAAK,cAAc,EAAE,YAAY,EAAE,MAAM,4BAA4B,CAAA;AAC9E,OAAO,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAA;AAC1D,OAAO,EAAE,YAAY,EAAE,KAAK,6BAA6B,EAAE,MAAM,2BAA2B,CAAA;AAC5F,OAAO,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAA;AAC9D,OAAO,EACN,4BAA4B,EAC5B,0BAA0B,EAC1B,kBAAkB,EAClB,uBAAuB,EACvB,uBAAuB,GACvB,MAAM,aAAa,CAAA;AAEpB,cAAc,uBAAuB,CAAA;AACrC,cAAc,0BAA0B,CAAA;AACxC,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAA"}
|
package/dist/index.js
CHANGED
|
@@ -7,7 +7,7 @@ export { createImport } from "./resolve-modules/index.js";
|
|
|
7
7
|
export { openInlangProject } from "./openInlangProject.js";
|
|
8
8
|
export { solidAdapter } from "./adapter/solidAdapter.js";
|
|
9
9
|
export { createMessagesQuery } from "./createMessagesQuery.js";
|
|
10
|
-
export { ProjectFilePathNotFoundError, ProjectFileJSONSyntaxError, InvalidConfigError,
|
|
10
|
+
export { ProjectFilePathNotFoundError, ProjectFileJSONSyntaxError, InvalidConfigError, PluginLoadMessagesError, PluginSaveMessagesError, } from "./errors.js";
|
|
11
11
|
export * from "./messages/variant.js";
|
|
12
12
|
export * from "./versionedInterfaces.js";
|
|
13
13
|
export { InlangModule } from "@inlang/module";
|
package/dist/messages/variant.js
CHANGED
|
@@ -104,10 +104,9 @@ const matchMostSpecificVariant = (message, languageTag, selectors) => {
|
|
|
104
104
|
// resolve preferenceSelectors to match length and order of message selectors
|
|
105
105
|
const resolvedSelectors = resolveSelector(message.selectors, selectors);
|
|
106
106
|
const index = {};
|
|
107
|
-
const
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
for (const variant of languageVariants) {
|
|
107
|
+
for (const variant of message.variants) {
|
|
108
|
+
if (variant.languageTag !== languageTag)
|
|
109
|
+
continue;
|
|
111
110
|
let isMatch = true;
|
|
112
111
|
//check if variant is a match
|
|
113
112
|
for (const [key, value] of Object.entries(variant.match)) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"openInlangProject.d.ts","sourceRoot":"","sources":["../src/openInlangProject.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EACX,aAAa,EAGb,YAAY,EACZ,MAAM,UAAU,CAAA;AACjB,OAAO,EAAE,KAAK,cAAc,EAAkB,MAAM,4BAA4B,CAAA;
|
|
1
|
+
{"version":3,"file":"openInlangProject.d.ts","sourceRoot":"","sources":["../src/openInlangProject.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EACX,aAAa,EAGb,YAAY,EACZ,MAAM,UAAU,CAAA;AACjB,OAAO,EAAE,KAAK,cAAc,EAAkB,MAAM,4BAA4B,CAAA;AAchF,OAAO,EAA0B,KAAK,uBAAuB,EAAE,MAAM,0BAA0B,CAAA;AAK/F;;;;;;GAMG;AACH,eAAO,MAAM,iBAAiB;qBACZ,MAAM;eACZ,uBAAuB;;qBAElB,MAAM,SAAS,OAAO,MAAM,EAAE,OAAO,CAAC,KAAK,IAAI;MAC5D,QAAQ,aAAa,CAiLxB,CAAA;AAyGD,wBAAgB,kBAAkB,CAAC,CAAC,EAAE,MAAM,EAAE,MAAM,CAAC,GAAG,YAAY,CAAC,CAAC,CAAC,CAQtE"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { resolveModules } from "./resolve-modules/index.js";
|
|
2
2
|
import { TypeCompiler } from "@sinclair/typebox/compiler";
|
|
3
3
|
import { Value } from "@sinclair/typebox/value";
|
|
4
|
-
import { ProjectFilePathNotFoundError, ProjectFileJSONSyntaxError, InvalidConfigError,
|
|
4
|
+
import { ProjectFilePathNotFoundError, ProjectFileJSONSyntaxError, InvalidConfigError, PluginLoadMessagesError, PluginSaveMessagesError, } from "./errors.js";
|
|
5
5
|
import { createRoot, createSignal, createEffect } from "./reactivity/solid.js";
|
|
6
6
|
import { createMessagesQuery } from "./createMessagesQuery.js";
|
|
7
7
|
import { debounce } from "throttle-debounce";
|
|
@@ -55,11 +55,6 @@ export const openInlangProject = async (args) => {
|
|
|
55
55
|
return;
|
|
56
56
|
loadModules({ config: conf, nodeishFs: args.nodeishFs, _import: args._import })
|
|
57
57
|
.then((resolvedModules) => {
|
|
58
|
-
// TODO move to resolveModules
|
|
59
|
-
if (!resolvedModules.resolvedPluginApi.loadMessages ||
|
|
60
|
-
!resolvedModules.resolvedPluginApi.saveMessages) {
|
|
61
|
-
throw new NoPluginProvidesLoadOrSaveMessagesError();
|
|
62
|
-
}
|
|
63
58
|
setResolvedModules(resolvedModules);
|
|
64
59
|
// TODO: handle `detectedLanguageTags`
|
|
65
60
|
})
|
|
@@ -98,7 +93,7 @@ export const openInlangProject = async (args) => {
|
|
|
98
93
|
meta: rule.meta,
|
|
99
94
|
module: resolvedModules()?.meta.find((m) => m.id.includes(rule.meta.id))?.module ??
|
|
100
95
|
"Unknown module. You stumbled on a bug in inlang's source code. Please open an issue.",
|
|
101
|
-
// default to warning, see https://github.com/inlang/
|
|
96
|
+
// default to warning, see https://github.com/inlang/monorepo/issues/1254
|
|
102
97
|
lintLevel: configValue.settings["project.messageLintRuleLevels"]?.[rule.meta.id] ?? "warning",
|
|
103
98
|
}));
|
|
104
99
|
};
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/* eslint-disable @typescript-eslint/no-non-null-assertion */
|
|
2
2
|
import { describe, it, expect, vi } from "vitest";
|
|
3
3
|
import { openInlangProject } from "./openInlangProject.js";
|
|
4
|
-
import { ProjectFilePathNotFoundError, ProjectFileJSONSyntaxError, InvalidConfigError,
|
|
4
|
+
import { ProjectFilePathNotFoundError, ProjectFileJSONSyntaxError, InvalidConfigError, } from "./errors.js";
|
|
5
5
|
import { createNodeishMemoryFs } from "@lix-js/fs";
|
|
6
6
|
// ------------------------------------------------------------------------------------------------
|
|
7
7
|
const getValue = (subscribable) => {
|
|
@@ -144,32 +144,6 @@ describe("initialization", () => {
|
|
|
144
144
|
});
|
|
145
145
|
});
|
|
146
146
|
describe("modules", () => {
|
|
147
|
-
it("should return an error if no plugin defines readMessages", async () => {
|
|
148
|
-
const $badImport = async () => ({
|
|
149
|
-
default: { ...mockPlugin, loadMessages: undefined },
|
|
150
|
-
});
|
|
151
|
-
const fs = await createNodeishMemoryFs();
|
|
152
|
-
await fs.writeFile("./project.inlang.json", JSON.stringify(config));
|
|
153
|
-
const inlang = await openInlangProject({
|
|
154
|
-
projectFilePath: "./project.inlang.json",
|
|
155
|
-
nodeishFs: fs,
|
|
156
|
-
_import: $badImport,
|
|
157
|
-
});
|
|
158
|
-
expect(inlang.errors()[0]).toBeInstanceOf(NoPluginProvidesLoadOrSaveMessagesError);
|
|
159
|
-
});
|
|
160
|
-
it("should return an error if no plugin defines writeMessages", async () => {
|
|
161
|
-
const $badImport = async () => ({
|
|
162
|
-
default: { ...mockPlugin, writeMessages: undefined },
|
|
163
|
-
});
|
|
164
|
-
const fs = createNodeishMemoryFs();
|
|
165
|
-
await fs.writeFile("./project.inlang.json", JSON.stringify(config));
|
|
166
|
-
const inlang = await openInlangProject({
|
|
167
|
-
projectFilePath: "./project.inlang.json",
|
|
168
|
-
nodeishFs: fs,
|
|
169
|
-
_import: $badImport,
|
|
170
|
-
});
|
|
171
|
-
expect(inlang.errors()[0]).toBeInstanceOf(NoPluginProvidesLoadOrSaveMessagesError);
|
|
172
|
-
});
|
|
173
147
|
it("should return an error if an error occurs while resolving a plugin", async () => {
|
|
174
148
|
const $badImport = async () => ({
|
|
175
149
|
default: {},
|
|
@@ -181,7 +155,7 @@ describe("initialization", () => {
|
|
|
181
155
|
nodeishFs: fs,
|
|
182
156
|
_import: $badImport,
|
|
183
157
|
});
|
|
184
|
-
expect(inlang.errors()).toHaveLength(
|
|
158
|
+
expect(inlang.errors()).not.toHaveLength(0);
|
|
185
159
|
});
|
|
186
160
|
// it.todo("should throw if lintRules contain errors ???")
|
|
187
161
|
// it.todo("should return meta data")
|
|
@@ -18,18 +18,12 @@ export type ImportFunction = (uri: string) => Promise<any>;
|
|
|
18
18
|
export declare function createImport(args: {
|
|
19
19
|
/** the fs from which the file can be read */
|
|
20
20
|
readFile: NodeishFilesystemSubset["readFile"];
|
|
21
|
-
/** http client implementation */
|
|
22
|
-
fetch: typeof fetch;
|
|
23
21
|
}): (uri: string) => ReturnType<typeof $import>;
|
|
24
22
|
declare function $import(uri: string, options: {
|
|
25
23
|
/**
|
|
26
24
|
* Required to import from a local path.
|
|
27
25
|
*/
|
|
28
26
|
readFile: NodeishFilesystemSubset["readFile"];
|
|
29
|
-
/**
|
|
30
|
-
* Required to import via network.
|
|
31
|
-
*/
|
|
32
|
-
fetch: typeof fetch;
|
|
33
27
|
}): Promise<any>;
|
|
34
28
|
export {};
|
|
35
29
|
//# sourceMappingURL=import.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"import.d.ts","sourceRoot":"","sources":["../../src/resolve-modules/import.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,gBAAgB,CAAA;AAG7D;;;;;GAKG;AACH,MAAM,MAAM,cAAc,GAAG,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC,GAAG,CAAC,CAAA;AAE1D;;;;;;;;GAQG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE;IAClC,6CAA6C;IAC7C,QAAQ,EAAE,uBAAuB,CAAC,UAAU,CAAC,CAAA;
|
|
1
|
+
{"version":3,"file":"import.d.ts","sourceRoot":"","sources":["../../src/resolve-modules/import.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,gBAAgB,CAAA;AAG7D;;;;;GAKG;AACH,MAAM,MAAM,cAAc,GAAG,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC,GAAG,CAAC,CAAA;AAE1D;;;;;;;;GAQG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE;IAClC,6CAA6C;IAC7C,QAAQ,EAAE,uBAAuB,CAAC,UAAU,CAAC,CAAA;CAC7C,GAAG,CAAC,GAAG,EAAE,MAAM,KAAK,UAAU,CAAC,OAAO,OAAO,CAAC,CAG9C;AAED,iBAAe,OAAO,CACrB,GAAG,EAAE,MAAM,EACX,OAAO,EAAE;IACR;;OAEG;IACH,QAAQ,EAAE,uBAAuB,CAAC,UAAU,CAAC,CAAA;CAC7C,GACC,OAAO,CAAC,GAAG,CAAC,CAwBd"}
|
|
@@ -17,7 +17,7 @@ export function createImport(args) {
|
|
|
17
17
|
async function $import(uri, options) {
|
|
18
18
|
let moduleAsText;
|
|
19
19
|
if (uri.startsWith("http")) {
|
|
20
|
-
moduleAsText = await (await
|
|
20
|
+
moduleAsText = await (await fetch(uri)).text();
|
|
21
21
|
}
|
|
22
22
|
else {
|
|
23
23
|
moduleAsText = await options.readFile(normalizePath(uri), { encoding: "utf-8" });
|
|
@@ -24,5 +24,8 @@ export declare class PluginSaveMessagesFunctionAlreadyDefinedError extends Plugi
|
|
|
24
24
|
export declare class PluginReturnedInvalidCustomApiError extends PluginError {
|
|
25
25
|
constructor(message: string, options: PluginErrorOptions);
|
|
26
26
|
}
|
|
27
|
+
export declare class PluginsDoNotProvideLoadOrSaveMessagesError extends PluginError {
|
|
28
|
+
constructor(message: string, options: PluginErrorOptions);
|
|
29
|
+
}
|
|
27
30
|
export {};
|
|
28
31
|
//# sourceMappingURL=errors.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../../src/resolve-modules/plugins/errors.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,gBAAgB,CAAA;AAE5C,KAAK,kBAAkB,GAAG;IACzB,MAAM,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,CAAA;CAC5B,GAAG,OAAO,CAAC,KAAK,CAAC,CAAA;AAElB,cAAM,WAAY,SAAQ,KAAK;IAC9B,SAAgB,MAAM,EAAE,MAAM,CAAA;gBAElB,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,kBAAkB;CAKxD;AAED,qBAAa,uBAAwB,SAAQ,WAAW;gBAC3C,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,kBAAkB;CAIxD;AAED,qBAAa,gCAAiC,SAAQ,WAAW;gBACpD,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,kBAAkB;CAIxD;AAED,qBAAa,2BAA4B,SAAQ,WAAW;gBAC/C,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,kBAAkB;CAIxD;AAED,qBAAa,6CAA8C,SAAQ,WAAW;gBACjE,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,kBAAkB;CAIxD;AAED,qBAAa,6CAA8C,SAAQ,WAAW;gBACjE,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,kBAAkB;CAIxD;AAED,qBAAa,mCAAoC,SAAQ,WAAW;gBACvD,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,kBAAkB;CAIxD"}
|
|
1
|
+
{"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../../src/resolve-modules/plugins/errors.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,gBAAgB,CAAA;AAE5C,KAAK,kBAAkB,GAAG;IACzB,MAAM,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,CAAA;CAC5B,GAAG,OAAO,CAAC,KAAK,CAAC,CAAA;AAElB,cAAM,WAAY,SAAQ,KAAK;IAC9B,SAAgB,MAAM,EAAE,MAAM,CAAA;gBAElB,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,kBAAkB;CAKxD;AAED,qBAAa,uBAAwB,SAAQ,WAAW;gBAC3C,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,kBAAkB;CAIxD;AAED,qBAAa,gCAAiC,SAAQ,WAAW;gBACpD,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,kBAAkB;CAIxD;AAED,qBAAa,2BAA4B,SAAQ,WAAW;gBAC/C,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,kBAAkB;CAIxD;AAED,qBAAa,6CAA8C,SAAQ,WAAW;gBACjE,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,kBAAkB;CAIxD;AAED,qBAAa,6CAA8C,SAAQ,WAAW;gBACjE,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,kBAAkB;CAIxD;AAED,qBAAa,mCAAoC,SAAQ,WAAW;gBACvD,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,kBAAkB;CAIxD;AAED,qBAAa,0CAA2C,SAAQ,WAAW;gBAC9D,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,kBAAkB;CAKxD"}
|
|
@@ -42,3 +42,10 @@ export class PluginReturnedInvalidCustomApiError extends PluginError {
|
|
|
42
42
|
this.name = "PluginReturnedInvalidCustomApiError";
|
|
43
43
|
}
|
|
44
44
|
}
|
|
45
|
+
export class PluginsDoNotProvideLoadOrSaveMessagesError extends PluginError {
|
|
46
|
+
constructor(message, options) {
|
|
47
|
+
super(message, options);
|
|
48
|
+
this.name = "PluginsDoNotProvideLoadOrSaveMessagesError";
|
|
49
|
+
options.plugin = "plugin.inlang.missing";
|
|
50
|
+
}
|
|
51
|
+
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"resolvePlugins.d.ts","sourceRoot":"","sources":["../../../src/resolve-modules/plugins/resolvePlugins.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,YAAY,CAAA;
|
|
1
|
+
{"version":3,"file":"resolvePlugins.d.ts","sourceRoot":"","sources":["../../../src/resolve-modules/plugins/resolvePlugins.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,YAAY,CAAA;AAuBxD,eAAO,MAAM,cAAc,EAAE,sBA+J5B,CAAA"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Plugin } from "@inlang/plugin";
|
|
2
|
-
import { PluginReturnedInvalidCustomApiError, PluginLoadMessagesFunctionAlreadyDefinedError, PluginSaveMessagesFunctionAlreadyDefinedError, PluginHasInvalidIdError, PluginHasInvalidSchemaError, PluginUsesReservedNamespaceError, } from "./errors.js";
|
|
2
|
+
import { PluginReturnedInvalidCustomApiError, PluginLoadMessagesFunctionAlreadyDefinedError, PluginSaveMessagesFunctionAlreadyDefinedError, PluginsDoNotProvideLoadOrSaveMessagesError, PluginHasInvalidIdError, PluginHasInvalidSchemaError, PluginUsesReservedNamespaceError, } from "./errors.js";
|
|
3
3
|
import { deepmerge } from "deepmerge-ts";
|
|
4
4
|
import { TypeCompiler } from "@sinclair/typebox/compiler";
|
|
5
5
|
import { tryCatch } from "@inlang/result";
|
|
@@ -104,5 +104,10 @@ export const resolvePlugins = async (args) => {
|
|
|
104
104
|
}
|
|
105
105
|
}
|
|
106
106
|
}
|
|
107
|
+
// --- LOADMESSAGE / SAVEMESSAGE NOT DEFINED ---
|
|
108
|
+
if (typeof result.data.loadMessages !== "function" ||
|
|
109
|
+
typeof result.data.saveMessages !== "function") {
|
|
110
|
+
result.errors.push(new PluginsDoNotProvideLoadOrSaveMessagesError("It seems you did not install any plugin that handles messages. Please add one to make inlang work. See https://inlang.com/documentation/plugins/registry.", { plugin: "plugin.inlang.missing" }));
|
|
111
|
+
}
|
|
107
112
|
return result;
|
|
108
113
|
};
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/* eslint-disable @typescript-eslint/no-non-null-assertion */
|
|
2
2
|
import { describe, expect, it } from "vitest";
|
|
3
3
|
import { resolvePlugins } from "./resolvePlugins.js";
|
|
4
|
-
import { PluginLoadMessagesFunctionAlreadyDefinedError, PluginSaveMessagesFunctionAlreadyDefinedError, PluginHasInvalidIdError, PluginUsesReservedNamespaceError, PluginReturnedInvalidCustomApiError, PluginHasInvalidSchemaError, } from "./errors.js";
|
|
4
|
+
import { PluginLoadMessagesFunctionAlreadyDefinedError, PluginSaveMessagesFunctionAlreadyDefinedError, PluginHasInvalidIdError, PluginUsesReservedNamespaceError, PluginReturnedInvalidCustomApiError, PluginHasInvalidSchemaError, PluginsDoNotProvideLoadOrSaveMessagesError, } from "./errors.js";
|
|
5
5
|
describe("generally", () => {
|
|
6
6
|
it("should return an error if a plugin uses an invalid id", async () => {
|
|
7
7
|
const mockPlugin = {
|
|
@@ -43,7 +43,6 @@ describe("generally", () => {
|
|
|
43
43
|
settings: {},
|
|
44
44
|
nodeishFs: {},
|
|
45
45
|
});
|
|
46
|
-
expect(resolved.errors.length).toBe(1);
|
|
47
46
|
expect(resolved.errors[0]).toBeInstanceOf(PluginHasInvalidSchemaError);
|
|
48
47
|
});
|
|
49
48
|
it("should not initialize a plugin that uses the 'inlang' namespace except for inlang whitelisted plugins", async () => {
|
|
@@ -60,7 +59,6 @@ describe("generally", () => {
|
|
|
60
59
|
settings: {},
|
|
61
60
|
nodeishFs: {},
|
|
62
61
|
});
|
|
63
|
-
expect(resolved.errors.length).toBe(1);
|
|
64
62
|
expect(resolved.errors[0]).toBeInstanceOf(PluginUsesReservedNamespaceError);
|
|
65
63
|
});
|
|
66
64
|
});
|
|
@@ -106,9 +104,25 @@ describe("loadMessages", () => {
|
|
|
106
104
|
nodeishFs: {},
|
|
107
105
|
settings: {},
|
|
108
106
|
});
|
|
109
|
-
expect(resolved.errors).toHaveLength(1);
|
|
110
107
|
expect(resolved.errors[0]).toBeInstanceOf(PluginLoadMessagesFunctionAlreadyDefinedError);
|
|
111
108
|
});
|
|
109
|
+
it("should return an error if no plugin defines loadMessages", async () => {
|
|
110
|
+
const mockPlugin = {
|
|
111
|
+
meta: {
|
|
112
|
+
id: "plugin.namepsace.loadMessagesFirst",
|
|
113
|
+
description: { en: "My plugin description" },
|
|
114
|
+
displayName: { en: "My plugin" },
|
|
115
|
+
},
|
|
116
|
+
saveMessages: async () => undefined,
|
|
117
|
+
};
|
|
118
|
+
const resolved = await resolvePlugins({
|
|
119
|
+
plugins: [mockPlugin],
|
|
120
|
+
nodeishFs: {},
|
|
121
|
+
settings: {},
|
|
122
|
+
});
|
|
123
|
+
expect(resolved.errors).toHaveLength(1);
|
|
124
|
+
expect(resolved.errors[0]).toBeInstanceOf(PluginsDoNotProvideLoadOrSaveMessagesError);
|
|
125
|
+
});
|
|
112
126
|
});
|
|
113
127
|
describe("saveMessages", () => {
|
|
114
128
|
it("should save messages to a local source", async () => {
|
|
@@ -118,6 +132,7 @@ describe("saveMessages", () => {
|
|
|
118
132
|
description: { en: "My plugin description" },
|
|
119
133
|
displayName: { en: "My plugin" },
|
|
120
134
|
},
|
|
135
|
+
loadMessages: async () => undefined,
|
|
121
136
|
saveMessages: async () => undefined,
|
|
122
137
|
};
|
|
123
138
|
const resolved = await resolvePlugins({
|
|
@@ -149,9 +164,25 @@ describe("saveMessages", () => {
|
|
|
149
164
|
settings: {},
|
|
150
165
|
nodeishFs: {},
|
|
151
166
|
});
|
|
152
|
-
expect(resolved.errors).toHaveLength(1);
|
|
153
167
|
expect(resolved.errors[0]).toBeInstanceOf(PluginSaveMessagesFunctionAlreadyDefinedError);
|
|
154
168
|
});
|
|
169
|
+
it("should return an error if no plugin defines saveMessages", async () => {
|
|
170
|
+
const mockPlugin = {
|
|
171
|
+
meta: {
|
|
172
|
+
id: "plugin.namepsace.loadMessagesFirst",
|
|
173
|
+
description: { en: "My plugin description" },
|
|
174
|
+
displayName: { en: "My plugin" },
|
|
175
|
+
},
|
|
176
|
+
loadMessages: async () => undefined,
|
|
177
|
+
};
|
|
178
|
+
const resolved = await resolvePlugins({
|
|
179
|
+
plugins: [mockPlugin],
|
|
180
|
+
nodeishFs: {},
|
|
181
|
+
settings: {},
|
|
182
|
+
});
|
|
183
|
+
expect(resolved.errors).toHaveLength(1);
|
|
184
|
+
expect(resolved.errors[0]).toBeInstanceOf(PluginsDoNotProvideLoadOrSaveMessagesError);
|
|
185
|
+
});
|
|
155
186
|
});
|
|
156
187
|
describe("detectedLanguageTags", () => {
|
|
157
188
|
it("should merge language tags from plugins", async () => {
|
|
@@ -258,7 +289,6 @@ describe("addCustomApi", () => {
|
|
|
258
289
|
settings: {},
|
|
259
290
|
nodeishFs: {},
|
|
260
291
|
});
|
|
261
|
-
expect(resolved.errors).toHaveLength(1);
|
|
262
292
|
expect(resolved.errors[0]).toBeInstanceOf(PluginReturnedInvalidCustomApiError);
|
|
263
293
|
});
|
|
264
294
|
it("it should throw an error if the passed options are not defined inside customApi", async () => {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { LanguageTag } from "@inlang/language-tag";
|
|
2
2
|
import type { NodeishFilesystem as LisaNodeishFilesystem } from "@lix-js/fs";
|
|
3
|
-
import type { PluginReturnedInvalidCustomApiError, PluginLoadMessagesFunctionAlreadyDefinedError, PluginSaveMessagesFunctionAlreadyDefinedError, PluginHasInvalidIdError, PluginHasInvalidSchemaError, PluginUsesReservedNamespaceError } from "./errors.js";
|
|
3
|
+
import type { PluginReturnedInvalidCustomApiError, PluginLoadMessagesFunctionAlreadyDefinedError, PluginSaveMessagesFunctionAlreadyDefinedError, PluginHasInvalidIdError, PluginHasInvalidSchemaError, PluginUsesReservedNamespaceError, PluginsDoNotProvideLoadOrSaveMessagesError } from "./errors.js";
|
|
4
4
|
import type { Message } from "@inlang/message";
|
|
5
5
|
import type { JSONObject } from "@inlang/json-types";
|
|
6
6
|
import type { CustomApiInlangIdeExtension, Plugin } from "@inlang/plugin";
|
|
@@ -19,7 +19,7 @@ export type ResolvePluginsFunction = (args: {
|
|
|
19
19
|
nodeishFs: NodeishFilesystemSubset;
|
|
20
20
|
}) => Promise<{
|
|
21
21
|
data: ResolvedPluginApi;
|
|
22
|
-
errors: Array<PluginReturnedInvalidCustomApiError | PluginLoadMessagesFunctionAlreadyDefinedError | PluginSaveMessagesFunctionAlreadyDefinedError | PluginHasInvalidIdError | PluginHasInvalidSchemaError | PluginUsesReservedNamespaceError>;
|
|
22
|
+
errors: Array<PluginReturnedInvalidCustomApiError | PluginLoadMessagesFunctionAlreadyDefinedError | PluginSaveMessagesFunctionAlreadyDefinedError | PluginHasInvalidIdError | PluginHasInvalidSchemaError | PluginUsesReservedNamespaceError | PluginsDoNotProvideLoadOrSaveMessagesError>;
|
|
23
23
|
}>;
|
|
24
24
|
/**
|
|
25
25
|
* The API after resolving the plugins.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/resolve-modules/plugins/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAA;AACvD,OAAO,KAAK,EAAE,iBAAiB,IAAI,qBAAqB,EAAE,MAAM,YAAY,CAAA;AAC5E,OAAO,KAAK,EACX,mCAAmC,EACnC,6CAA6C,EAC7C,6CAA6C,EAC7C,uBAAuB,EACvB,2BAA2B,EAC3B,gCAAgC,EAChC,MAAM,aAAa,CAAA;AACpB,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,iBAAiB,CAAA;AAC9C,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAA;AACpD,OAAO,KAAK,EAAE,2BAA2B,EAAE,MAAM,EAAE,MAAM,gBAAgB,CAAA;AAEzE;;;;GAIG;AACH,MAAM,MAAM,uBAAuB,GAAG,IAAI,CACzC,qBAAqB,EACrB,UAAU,GAAG,SAAS,GAAG,OAAO,GAAG,WAAW,CAC9C,CAAA;AAED;;GAEG;AACH,MAAM,MAAM,sBAAsB,GAAG,CAAC,IAAI,EAAE;IAC3C,OAAO,EAAE,KAAK,CAAC,MAAM,CAAC,CAAA;IACtB,QAAQ,EAAE,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,EAAE,UAAU,CAAC,CAAA;IAClD,SAAS,EAAE,uBAAuB,CAAA;CAClC,KAAK,OAAO,CAAC;IACb,IAAI,EAAE,iBAAiB,CAAA;IACvB,MAAM,EAAE,KAAK,CACV,mCAAmC,GACnC,6CAA6C,GAC7C,6CAA6C,GAC7C,uBAAuB,GACvB,2BAA2B,GAC3B,gCAAgC,
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/resolve-modules/plugins/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAA;AACvD,OAAO,KAAK,EAAE,iBAAiB,IAAI,qBAAqB,EAAE,MAAM,YAAY,CAAA;AAC5E,OAAO,KAAK,EACX,mCAAmC,EACnC,6CAA6C,EAC7C,6CAA6C,EAC7C,uBAAuB,EACvB,2BAA2B,EAC3B,gCAAgC,EAChC,0CAA0C,EAC1C,MAAM,aAAa,CAAA;AACpB,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,iBAAiB,CAAA;AAC9C,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAA;AACpD,OAAO,KAAK,EAAE,2BAA2B,EAAE,MAAM,EAAE,MAAM,gBAAgB,CAAA;AAEzE;;;;GAIG;AACH,MAAM,MAAM,uBAAuB,GAAG,IAAI,CACzC,qBAAqB,EACrB,UAAU,GAAG,SAAS,GAAG,OAAO,GAAG,WAAW,CAC9C,CAAA;AAED;;GAEG;AACH,MAAM,MAAM,sBAAsB,GAAG,CAAC,IAAI,EAAE;IAC3C,OAAO,EAAE,KAAK,CAAC,MAAM,CAAC,CAAA;IACtB,QAAQ,EAAE,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,EAAE,UAAU,CAAC,CAAA;IAClD,SAAS,EAAE,uBAAuB,CAAA;CAClC,KAAK,OAAO,CAAC;IACb,IAAI,EAAE,iBAAiB,CAAA;IACvB,MAAM,EAAE,KAAK,CACV,mCAAmC,GACnC,6CAA6C,GAC7C,6CAA6C,GAC7C,uBAAuB,GACvB,2BAA2B,GAC3B,gCAAgC,GAChC,0CAA0C,CAC5C,CAAA;CACD,CAAC,CAAA;AAEF;;GAEG;AACH,MAAM,MAAM,iBAAiB,GAAG;IAC/B,YAAY,EAAE,CAAC,IAAI,EAAE;QACpB,YAAY,EAAE,WAAW,EAAE,CAAA;QAC3B,iBAAiB,EAAE,WAAW,CAAA;KAC9B,KAAK,OAAO,CAAC,OAAO,EAAE,CAAC,GAAG,OAAO,EAAE,CAAA;IACpC,YAAY,EAAE,CAAC,IAAI,EAAE;QAAE,QAAQ,EAAE,OAAO,EAAE,CAAA;KAAE,KAAK,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAA;IACrE;;OAEG;IACH,oBAAoB,EAAE,WAAW,EAAE,CAAA;IACnC;;;;;;;;;;;;;;;;OAgBG;IACH,SAAS,EAAE,MAAM,CAAC,OAAO,MAAM,IAAI,MAAM,EAAE,GAAG,WAAW,MAAM,IAAI,MAAM,EAAE,EAAE,OAAO,CAAC,GAAG;QACvF,yBAAyB,CAAC,EAAE,2BAA2B,CAAA;KACvD,CAAA;CACD,CAAA"}
|
|
@@ -7,7 +7,7 @@ import { resolvePlugins } from "./plugins/resolvePlugins.js";
|
|
|
7
7
|
import { TypeCompiler } from "@sinclair/typebox/compiler";
|
|
8
8
|
const ModuleCompiler = TypeCompiler.Compile(InlangModule);
|
|
9
9
|
export const resolveModules = async (args) => {
|
|
10
|
-
const _import = args._import ?? createImport({ readFile: args.nodeishFs.readFile
|
|
10
|
+
const _import = args._import ?? createImport({ readFile: args.nodeishFs.readFile });
|
|
11
11
|
const moduleErrors = [];
|
|
12
12
|
const allPlugins = [];
|
|
13
13
|
const allMessageLintRules = [];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/test-utilities/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAA"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/test-utilities/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAA;AAClD,OAAO,EAAE,qBAAqB,EAAE,MAAM,YAAY,CAAA"}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@inlang/sdk",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "0.
|
|
4
|
+
"version": "0.3.0",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"publishConfig": {
|
|
7
7
|
"access": "public"
|
|
@@ -45,7 +45,6 @@
|
|
|
45
45
|
"ts-dedent": "2.2.0"
|
|
46
46
|
},
|
|
47
47
|
"devDependencies": {
|
|
48
|
-
"@placeholder-company/js-code-style": "*",
|
|
49
48
|
"@lix-js/fs": "*",
|
|
50
49
|
"@types/throttle-debounce": "5.0.0",
|
|
51
50
|
"@vitest/coverage-v8": "^0.33.0",
|
package/src/errors.ts
CHANGED
|
@@ -32,15 +32,3 @@ export class PluginLoadMessagesError extends Error {
|
|
|
32
32
|
this.name = "PluginLoadMessagesError"
|
|
33
33
|
}
|
|
34
34
|
}
|
|
35
|
-
|
|
36
|
-
/**
|
|
37
|
-
* Error when no package provides the API to handle messages.
|
|
38
|
-
*/
|
|
39
|
-
export class NoPluginProvidesLoadOrSaveMessagesError extends Error {
|
|
40
|
-
constructor() {
|
|
41
|
-
super(
|
|
42
|
-
"It seems you did not install any plugin that handles messages. Please add one to make inlang work. See https://inlang.com/documentation/plugins/registry.",
|
|
43
|
-
) // TODO: check if link is correct
|
|
44
|
-
this.name = "NoPluginProvidesLoadOrSaveMessagesError"
|
|
45
|
-
}
|
|
46
|
-
}
|
package/src/index.ts
CHANGED
package/src/messages/variant.ts
CHANGED
|
@@ -154,10 +154,9 @@ const matchMostSpecificVariant = (
|
|
|
154
154
|
const resolvedSelectors = resolveSelector(message.selectors, selectors)
|
|
155
155
|
const index: Record<string, any> = {}
|
|
156
156
|
|
|
157
|
-
const
|
|
158
|
-
|
|
157
|
+
for (const variant of message.variants) {
|
|
158
|
+
if (variant.languageTag !== languageTag) continue
|
|
159
159
|
|
|
160
|
-
for (const variant of languageVariants) {
|
|
161
160
|
let isMatch = true
|
|
162
161
|
|
|
163
162
|
//check if variant is a match
|
|
@@ -8,7 +8,6 @@ import {
|
|
|
8
8
|
ProjectFilePathNotFoundError,
|
|
9
9
|
ProjectFileJSONSyntaxError,
|
|
10
10
|
InvalidConfigError,
|
|
11
|
-
NoPluginProvidesLoadOrSaveMessagesError,
|
|
12
11
|
} from "./errors.js"
|
|
13
12
|
import { createNodeishMemoryFs } from "@lix-js/fs"
|
|
14
13
|
|
|
@@ -178,40 +177,6 @@ describe("initialization", () => {
|
|
|
178
177
|
})
|
|
179
178
|
|
|
180
179
|
describe("modules", () => {
|
|
181
|
-
it("should return an error if no plugin defines readMessages", async () => {
|
|
182
|
-
const $badImport: ImportFunction = async () =>
|
|
183
|
-
({
|
|
184
|
-
default: { ...mockPlugin, loadMessages: undefined as any } as Plugin,
|
|
185
|
-
} satisfies InlangModule)
|
|
186
|
-
|
|
187
|
-
const fs = await createNodeishMemoryFs()
|
|
188
|
-
await fs.writeFile("./project.inlang.json", JSON.stringify(config))
|
|
189
|
-
const inlang = await openInlangProject({
|
|
190
|
-
projectFilePath: "./project.inlang.json",
|
|
191
|
-
nodeishFs: fs,
|
|
192
|
-
_import: $badImport,
|
|
193
|
-
})
|
|
194
|
-
|
|
195
|
-
expect(inlang.errors()![0]).toBeInstanceOf(NoPluginProvidesLoadOrSaveMessagesError)
|
|
196
|
-
})
|
|
197
|
-
|
|
198
|
-
it("should return an error if no plugin defines writeMessages", async () => {
|
|
199
|
-
const $badImport: ImportFunction = async () =>
|
|
200
|
-
({
|
|
201
|
-
default: { ...mockPlugin, writeMessages: undefined as any } as Plugin,
|
|
202
|
-
} satisfies InlangModule)
|
|
203
|
-
|
|
204
|
-
const fs = createNodeishMemoryFs()
|
|
205
|
-
await fs.writeFile("./project.inlang.json", JSON.stringify(config))
|
|
206
|
-
const inlang = await openInlangProject({
|
|
207
|
-
projectFilePath: "./project.inlang.json",
|
|
208
|
-
nodeishFs: fs,
|
|
209
|
-
_import: $badImport,
|
|
210
|
-
})
|
|
211
|
-
|
|
212
|
-
expect(inlang.errors()![0]).toBeInstanceOf(NoPluginProvidesLoadOrSaveMessagesError)
|
|
213
|
-
})
|
|
214
|
-
|
|
215
180
|
it("should return an error if an error occurs while resolving a plugin", async () => {
|
|
216
181
|
const $badImport: ImportFunction = async () =>
|
|
217
182
|
({
|
|
@@ -227,7 +192,7 @@ describe("initialization", () => {
|
|
|
227
192
|
_import: $badImport,
|
|
228
193
|
})
|
|
229
194
|
|
|
230
|
-
expect(inlang.errors()).toHaveLength(
|
|
195
|
+
expect(inlang.errors()).not.toHaveLength(0)
|
|
231
196
|
})
|
|
232
197
|
// it.todo("should throw if lintRules contain errors ???")
|
|
233
198
|
// it.todo("should return meta data")
|
package/src/openInlangProject.ts
CHANGED
|
@@ -12,7 +12,6 @@ import {
|
|
|
12
12
|
ProjectFilePathNotFoundError,
|
|
13
13
|
ProjectFileJSONSyntaxError,
|
|
14
14
|
InvalidConfigError,
|
|
15
|
-
NoPluginProvidesLoadOrSaveMessagesError,
|
|
16
15
|
PluginLoadMessagesError,
|
|
17
16
|
PluginSaveMessagesError,
|
|
18
17
|
} from "./errors.js"
|
|
@@ -87,13 +86,6 @@ export const openInlangProject = async (args: {
|
|
|
87
86
|
|
|
88
87
|
loadModules({ config: conf, nodeishFs: args.nodeishFs, _import: args._import })
|
|
89
88
|
.then((resolvedModules) => {
|
|
90
|
-
// TODO move to resolveModules
|
|
91
|
-
if (
|
|
92
|
-
!resolvedModules.resolvedPluginApi.loadMessages ||
|
|
93
|
-
!resolvedModules.resolvedPluginApi.saveMessages
|
|
94
|
-
) {
|
|
95
|
-
throw new NoPluginProvidesLoadOrSaveMessagesError()
|
|
96
|
-
}
|
|
97
89
|
setResolvedModules(resolvedModules)
|
|
98
90
|
|
|
99
91
|
// TODO: handle `detectedLanguageTags`
|
|
@@ -146,7 +138,7 @@ export const openInlangProject = async (args: {
|
|
|
146
138
|
resolvedModules()?.meta.find((m) => m.id.includes(rule.meta.id))?.module ??
|
|
147
139
|
"Unknown module. You stumbled on a bug in inlang's source code. Please open an issue.",
|
|
148
140
|
|
|
149
|
-
// default to warning, see https://github.com/inlang/
|
|
141
|
+
// default to warning, see https://github.com/inlang/monorepo/issues/1254
|
|
150
142
|
lintLevel:
|
|
151
143
|
configValue.settings["project.messageLintRuleLevels"]?.[rule.meta.id] ?? "warning",
|
|
152
144
|
} satisfies InstalledMessageLintRule),
|
|
@@ -23,8 +23,6 @@ export type ImportFunction = (uri: string) => Promise<any>
|
|
|
23
23
|
export function createImport(args: {
|
|
24
24
|
/** the fs from which the file can be read */
|
|
25
25
|
readFile: NodeishFilesystemSubset["readFile"]
|
|
26
|
-
/** http client implementation */
|
|
27
|
-
fetch: typeof fetch
|
|
28
26
|
}): (uri: string) => ReturnType<typeof $import> {
|
|
29
27
|
// resembles a native import api
|
|
30
28
|
return (uri: string) => $import(uri, args)
|
|
@@ -37,16 +35,12 @@ async function $import(
|
|
|
37
35
|
* Required to import from a local path.
|
|
38
36
|
*/
|
|
39
37
|
readFile: NodeishFilesystemSubset["readFile"]
|
|
40
|
-
/**
|
|
41
|
-
* Required to import via network.
|
|
42
|
-
*/
|
|
43
|
-
fetch: typeof fetch
|
|
44
38
|
},
|
|
45
39
|
): Promise<any> {
|
|
46
40
|
let moduleAsText: string
|
|
47
41
|
|
|
48
42
|
if (uri.startsWith("http")) {
|
|
49
|
-
moduleAsText = await (await
|
|
43
|
+
moduleAsText = await (await fetch(uri)).text()
|
|
50
44
|
} else {
|
|
51
45
|
moduleAsText = await options.readFile(normalizePath(uri), { encoding: "utf-8" })
|
|
52
46
|
}
|
|
@@ -55,3 +55,11 @@ export class PluginReturnedInvalidCustomApiError extends PluginError {
|
|
|
55
55
|
this.name = "PluginReturnedInvalidCustomApiError"
|
|
56
56
|
}
|
|
57
57
|
}
|
|
58
|
+
|
|
59
|
+
export class PluginsDoNotProvideLoadOrSaveMessagesError extends PluginError {
|
|
60
|
+
constructor(message: string, options: PluginErrorOptions) {
|
|
61
|
+
super(message, options)
|
|
62
|
+
this.name = "PluginsDoNotProvideLoadOrSaveMessagesError"
|
|
63
|
+
options.plugin = "plugin.inlang.missing"
|
|
64
|
+
}
|
|
65
|
+
}
|
|
@@ -8,6 +8,7 @@ import {
|
|
|
8
8
|
PluginUsesReservedNamespaceError,
|
|
9
9
|
PluginReturnedInvalidCustomApiError,
|
|
10
10
|
PluginHasInvalidSchemaError,
|
|
11
|
+
PluginsDoNotProvideLoadOrSaveMessagesError,
|
|
11
12
|
} from "./errors.js"
|
|
12
13
|
import type { Plugin } from "@inlang/plugin"
|
|
13
14
|
|
|
@@ -57,7 +58,6 @@ describe("generally", () => {
|
|
|
57
58
|
nodeishFs: {} as any,
|
|
58
59
|
})
|
|
59
60
|
|
|
60
|
-
expect(resolved.errors.length).toBe(1)
|
|
61
61
|
expect(resolved.errors[0]).toBeInstanceOf(PluginHasInvalidSchemaError)
|
|
62
62
|
})
|
|
63
63
|
|
|
@@ -77,7 +77,6 @@ describe("generally", () => {
|
|
|
77
77
|
nodeishFs: {} as any,
|
|
78
78
|
})
|
|
79
79
|
|
|
80
|
-
expect(resolved.errors.length).toBe(1)
|
|
81
80
|
expect(resolved.errors[0]).toBeInstanceOf(PluginUsesReservedNamespaceError)
|
|
82
81
|
})
|
|
83
82
|
})
|
|
@@ -131,9 +130,28 @@ describe("loadMessages", () => {
|
|
|
131
130
|
settings: {},
|
|
132
131
|
})
|
|
133
132
|
|
|
134
|
-
expect(resolved.errors).toHaveLength(1)
|
|
135
133
|
expect(resolved.errors[0]).toBeInstanceOf(PluginLoadMessagesFunctionAlreadyDefinedError)
|
|
136
134
|
})
|
|
135
|
+
|
|
136
|
+
it("should return an error if no plugin defines loadMessages", async () => {
|
|
137
|
+
const mockPlugin: Plugin = {
|
|
138
|
+
meta: {
|
|
139
|
+
id: "plugin.namepsace.loadMessagesFirst",
|
|
140
|
+
description: { en: "My plugin description" },
|
|
141
|
+
displayName: { en: "My plugin" },
|
|
142
|
+
},
|
|
143
|
+
saveMessages: async () => undefined as any,
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
const resolved = await resolvePlugins({
|
|
147
|
+
plugins: [mockPlugin],
|
|
148
|
+
nodeishFs: {} as any,
|
|
149
|
+
settings: {},
|
|
150
|
+
})
|
|
151
|
+
|
|
152
|
+
expect(resolved.errors).toHaveLength(1)
|
|
153
|
+
expect(resolved.errors[0]).toBeInstanceOf(PluginsDoNotProvideLoadOrSaveMessagesError)
|
|
154
|
+
})
|
|
137
155
|
})
|
|
138
156
|
|
|
139
157
|
describe("saveMessages", () => {
|
|
@@ -144,6 +162,7 @@ describe("saveMessages", () => {
|
|
|
144
162
|
description: { en: "My plugin description" },
|
|
145
163
|
displayName: { en: "My plugin" },
|
|
146
164
|
},
|
|
165
|
+
loadMessages: async () => undefined as any,
|
|
147
166
|
saveMessages: async () => undefined as any,
|
|
148
167
|
}
|
|
149
168
|
|
|
@@ -181,9 +200,27 @@ describe("saveMessages", () => {
|
|
|
181
200
|
nodeishFs: {} as any,
|
|
182
201
|
})
|
|
183
202
|
|
|
184
|
-
expect(resolved.errors).toHaveLength(1)
|
|
185
203
|
expect(resolved.errors[0]).toBeInstanceOf(PluginSaveMessagesFunctionAlreadyDefinedError)
|
|
186
204
|
})
|
|
205
|
+
|
|
206
|
+
it("should return an error if no plugin defines saveMessages", async () => {
|
|
207
|
+
const mockPlugin: Plugin = {
|
|
208
|
+
meta: {
|
|
209
|
+
id: "plugin.namepsace.loadMessagesFirst",
|
|
210
|
+
description: { en: "My plugin description" },
|
|
211
|
+
displayName: { en: "My plugin" },
|
|
212
|
+
},
|
|
213
|
+
loadMessages: async () => undefined as any,
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
const resolved = await resolvePlugins({
|
|
217
|
+
plugins: [mockPlugin],
|
|
218
|
+
nodeishFs: {} as any,
|
|
219
|
+
settings: {},
|
|
220
|
+
})
|
|
221
|
+
expect(resolved.errors).toHaveLength(1)
|
|
222
|
+
expect(resolved.errors[0]).toBeInstanceOf(PluginsDoNotProvideLoadOrSaveMessagesError)
|
|
223
|
+
})
|
|
187
224
|
})
|
|
188
225
|
|
|
189
226
|
describe("detectedLanguageTags", () => {
|
|
@@ -304,7 +341,6 @@ describe("addCustomApi", () => {
|
|
|
304
341
|
nodeishFs: {} as any,
|
|
305
342
|
})
|
|
306
343
|
|
|
307
|
-
expect(resolved.errors).toHaveLength(1)
|
|
308
344
|
expect(resolved.errors[0]).toBeInstanceOf(PluginReturnedInvalidCustomApiError)
|
|
309
345
|
})
|
|
310
346
|
|
|
@@ -5,6 +5,7 @@ import {
|
|
|
5
5
|
PluginReturnedInvalidCustomApiError,
|
|
6
6
|
PluginLoadMessagesFunctionAlreadyDefinedError,
|
|
7
7
|
PluginSaveMessagesFunctionAlreadyDefinedError,
|
|
8
|
+
PluginsDoNotProvideLoadOrSaveMessagesError,
|
|
8
9
|
PluginHasInvalidIdError,
|
|
9
10
|
PluginHasInvalidSchemaError,
|
|
10
11
|
PluginUsesReservedNamespaceError,
|
|
@@ -166,5 +167,18 @@ export const resolvePlugins: ResolvePluginsFunction = async (args) => {
|
|
|
166
167
|
}
|
|
167
168
|
}
|
|
168
169
|
|
|
170
|
+
// --- LOADMESSAGE / SAVEMESSAGE NOT DEFINED ---
|
|
171
|
+
if (
|
|
172
|
+
typeof result.data.loadMessages !== "function" ||
|
|
173
|
+
typeof result.data.saveMessages !== "function"
|
|
174
|
+
) {
|
|
175
|
+
result.errors.push(
|
|
176
|
+
new PluginsDoNotProvideLoadOrSaveMessagesError(
|
|
177
|
+
"It seems you did not install any plugin that handles messages. Please add one to make inlang work. See https://inlang.com/documentation/plugins/registry.",
|
|
178
|
+
{ plugin: "plugin.inlang.missing" },
|
|
179
|
+
),
|
|
180
|
+
)
|
|
181
|
+
}
|
|
182
|
+
|
|
169
183
|
return result
|
|
170
184
|
}
|
|
@@ -7,6 +7,7 @@ import type {
|
|
|
7
7
|
PluginHasInvalidIdError,
|
|
8
8
|
PluginHasInvalidSchemaError,
|
|
9
9
|
PluginUsesReservedNamespaceError,
|
|
10
|
+
PluginsDoNotProvideLoadOrSaveMessagesError,
|
|
10
11
|
} from "./errors.js"
|
|
11
12
|
import type { Message } from "@inlang/message"
|
|
12
13
|
import type { JSONObject } from "@inlang/json-types"
|
|
@@ -38,6 +39,7 @@ export type ResolvePluginsFunction = (args: {
|
|
|
38
39
|
| PluginHasInvalidIdError
|
|
39
40
|
| PluginHasInvalidSchemaError
|
|
40
41
|
| PluginUsesReservedNamespaceError
|
|
42
|
+
| PluginsDoNotProvideLoadOrSaveMessagesError
|
|
41
43
|
>
|
|
42
44
|
}>
|
|
43
45
|
|
|
@@ -17,7 +17,7 @@ import { TypeCompiler } from "@sinclair/typebox/compiler"
|
|
|
17
17
|
const ModuleCompiler = TypeCompiler.Compile(InlangModule)
|
|
18
18
|
|
|
19
19
|
export const resolveModules: ResolveModuleFunction = async (args) => {
|
|
20
|
-
const _import = args._import ?? createImport({ readFile: args.nodeishFs.readFile
|
|
20
|
+
const _import = args._import ?? createImport({ readFile: args.nodeishFs.readFile })
|
|
21
21
|
const moduleErrors: Array<ModuleError> = []
|
|
22
22
|
|
|
23
23
|
const allPlugins: Array<Plugin> = []
|
|
@@ -81,7 +81,7 @@ export const resolveModules: ResolveModuleFunction = async (args) => {
|
|
|
81
81
|
|
|
82
82
|
const resolvedPlugins = await resolvePlugins({
|
|
83
83
|
plugins: allPlugins,
|
|
84
|
-
settings: args.config.settings
|
|
84
|
+
settings: args.config.settings,
|
|
85
85
|
nodeishFs: args.nodeishFs,
|
|
86
86
|
})
|
|
87
87
|
|