@better-i18n/mcp 0.15.2 → 0.15.4

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.
Files changed (93) hide show
  1. package/dist/__tests__/base-tool.test.d.ts +2 -0
  2. package/dist/__tests__/base-tool.test.d.ts.map +1 -0
  3. package/dist/__tests__/base-tool.test.js +193 -0
  4. package/dist/__tests__/base-tool.test.js.map +1 -0
  5. package/dist/__tests__/contract.test.d.ts +24 -0
  6. package/dist/__tests__/contract.test.d.ts.map +1 -0
  7. package/dist/__tests__/contract.test.js +919 -0
  8. package/dist/__tests__/contract.test.js.map +1 -0
  9. package/dist/__tests__/fixtures/mock-client.d.ts +11 -0
  10. package/dist/__tests__/fixtures/mock-client.d.ts.map +1 -0
  11. package/dist/__tests__/fixtures/mock-client.js +33 -0
  12. package/dist/__tests__/fixtures/mock-client.js.map +1 -0
  13. package/dist/__tests__/helpers.d.ts +10 -0
  14. package/dist/__tests__/helpers.d.ts.map +1 -0
  15. package/dist/__tests__/helpers.js +27 -0
  16. package/dist/__tests__/helpers.js.map +1 -0
  17. package/dist/__tests__/schema-alignment.test.d.ts +15 -0
  18. package/dist/__tests__/schema-alignment.test.d.ts.map +1 -0
  19. package/dist/__tests__/schema-alignment.test.js +1011 -0
  20. package/dist/__tests__/schema-alignment.test.js.map +1 -0
  21. package/dist/__tests__/server-dispatch.test.d.ts +10 -0
  22. package/dist/__tests__/server-dispatch.test.d.ts.map +1 -0
  23. package/dist/__tests__/server-dispatch.test.js +202 -0
  24. package/dist/__tests__/server-dispatch.test.js.map +1 -0
  25. package/dist/tools/__tests__/createKeys.test.d.ts +2 -0
  26. package/dist/tools/__tests__/createKeys.test.d.ts.map +1 -0
  27. package/dist/tools/__tests__/createKeys.test.js +139 -0
  28. package/dist/tools/__tests__/createKeys.test.js.map +1 -0
  29. package/dist/tools/__tests__/deleteKeys.test.d.ts +2 -0
  30. package/dist/tools/__tests__/deleteKeys.test.d.ts.map +1 -0
  31. package/dist/tools/__tests__/deleteKeys.test.js +91 -0
  32. package/dist/tools/__tests__/deleteKeys.test.js.map +1 -0
  33. package/dist/tools/__tests__/getPendingChanges.test.d.ts +2 -0
  34. package/dist/tools/__tests__/getPendingChanges.test.d.ts.map +1 -0
  35. package/dist/tools/__tests__/getPendingChanges.test.js +50 -0
  36. package/dist/tools/__tests__/getPendingChanges.test.js.map +1 -0
  37. package/dist/tools/__tests__/getProject.test.d.ts +2 -0
  38. package/dist/tools/__tests__/getProject.test.d.ts.map +1 -0
  39. package/dist/tools/__tests__/getProject.test.js +55 -0
  40. package/dist/tools/__tests__/getProject.test.js.map +1 -0
  41. package/dist/tools/__tests__/getSync.test.d.ts +2 -0
  42. package/dist/tools/__tests__/getSync.test.d.ts.map +1 -0
  43. package/dist/tools/__tests__/getSync.test.js +42 -0
  44. package/dist/tools/__tests__/getSync.test.js.map +1 -0
  45. package/dist/tools/__tests__/getSyncs.test.d.ts +2 -0
  46. package/dist/tools/__tests__/getSyncs.test.d.ts.map +1 -0
  47. package/dist/tools/__tests__/getSyncs.test.js +66 -0
  48. package/dist/tools/__tests__/getSyncs.test.js.map +1 -0
  49. package/dist/tools/__tests__/getTranslations.test.d.ts +2 -0
  50. package/dist/tools/__tests__/getTranslations.test.d.ts.map +1 -0
  51. package/dist/tools/__tests__/getTranslations.test.js +114 -0
  52. package/dist/tools/__tests__/getTranslations.test.js.map +1 -0
  53. package/dist/tools/__tests__/listKeys.test.d.ts +2 -0
  54. package/dist/tools/__tests__/listKeys.test.d.ts.map +1 -0
  55. package/dist/tools/__tests__/listKeys.test.js +98 -0
  56. package/dist/tools/__tests__/listKeys.test.js.map +1 -0
  57. package/dist/tools/__tests__/listProjects.test.d.ts +2 -0
  58. package/dist/tools/__tests__/listProjects.test.d.ts.map +1 -0
  59. package/dist/tools/__tests__/listProjects.test.js +45 -0
  60. package/dist/tools/__tests__/listProjects.test.js.map +1 -0
  61. package/dist/tools/__tests__/proposeLanguageEdits.test.d.ts +2 -0
  62. package/dist/tools/__tests__/proposeLanguageEdits.test.d.ts.map +1 -0
  63. package/dist/tools/__tests__/proposeLanguageEdits.test.js +87 -0
  64. package/dist/tools/__tests__/proposeLanguageEdits.test.js.map +1 -0
  65. package/dist/tools/__tests__/proposeLanguages.test.d.ts +2 -0
  66. package/dist/tools/__tests__/proposeLanguages.test.d.ts.map +1 -0
  67. package/dist/tools/__tests__/proposeLanguages.test.js +109 -0
  68. package/dist/tools/__tests__/proposeLanguages.test.js.map +1 -0
  69. package/dist/tools/__tests__/publishTranslations.test.d.ts +2 -0
  70. package/dist/tools/__tests__/publishTranslations.test.d.ts.map +1 -0
  71. package/dist/tools/__tests__/publishTranslations.test.js +127 -0
  72. package/dist/tools/__tests__/publishTranslations.test.js.map +1 -0
  73. package/dist/tools/__tests__/updateKeys.test.d.ts +2 -0
  74. package/dist/tools/__tests__/updateKeys.test.d.ts.map +1 -0
  75. package/dist/tools/__tests__/updateKeys.test.js +122 -0
  76. package/dist/tools/__tests__/updateKeys.test.js.map +1 -0
  77. package/dist/tools/createKeys.d.ts.map +1 -1
  78. package/dist/tools/createKeys.js +11 -2
  79. package/dist/tools/createKeys.js.map +1 -1
  80. package/dist/tools/getTranslations.d.ts.map +1 -1
  81. package/dist/tools/getTranslations.js +5 -1
  82. package/dist/tools/getTranslations.js.map +1 -1
  83. package/dist/tools/listKeys.d.ts.map +1 -1
  84. package/dist/tools/listKeys.js +1 -0
  85. package/dist/tools/listKeys.js.map +1 -1
  86. package/dist/tools/updateKeys.d.ts.map +1 -1
  87. package/dist/tools/updateKeys.js +9 -3
  88. package/dist/tools/updateKeys.js.map +1 -1
  89. package/dist/worker.test.d.ts +16 -0
  90. package/dist/worker.test.d.ts.map +1 -0
  91. package/dist/worker.test.js +244 -0
  92. package/dist/worker.test.js.map +1 -0
  93. package/package.json +2 -2
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=base-tool.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"base-tool.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/base-tool.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,193 @@
1
+ import { describe, it, expect } from "vitest";
2
+ import { z } from "zod";
3
+ import { parseProject } from "../helpers.js";
4
+ import { success, error, executeTool, executeSimpleTool, projectSchema, } from "../base-tool.js";
5
+ import { isErrorResult, expectSuccess, expectError } from "./helpers.js";
6
+ // ---------------------------------------------------------------------------
7
+ // parseProject
8
+ // ---------------------------------------------------------------------------
9
+ describe("parseProject", () => {
10
+ it('parses "org/project" into workspaceId and projectSlug', () => {
11
+ expect(parseProject("org/project")).toEqual({
12
+ workspaceId: "org",
13
+ projectSlug: "project",
14
+ });
15
+ });
16
+ it("throws a descriptive error for a single-segment string", () => {
17
+ expect(() => parseProject("invalid")).toThrow(/Invalid project format "invalid"/);
18
+ });
19
+ it("throws for an empty string", () => {
20
+ expect(() => parseProject("")).toThrow(/Invalid project format/);
21
+ });
22
+ it("throws when there are 3 segments (a/b/c)", () => {
23
+ expect(() => parseProject("a/b/c")).toThrow(/Invalid project format "a\/b\/c"/);
24
+ });
25
+ it("throws when the slug part is empty (org/)", () => {
26
+ expect(() => parseProject("org/")).toThrow(/Invalid project format "org\/"/);
27
+ });
28
+ it("throws when the org part is empty (/project)", () => {
29
+ expect(() => parseProject("/project")).toThrow(/Invalid project format "\/project"/);
30
+ });
31
+ it("handles hyphens in both org and slug", () => {
32
+ expect(parseProject("org-with-hyphens/proj-123")).toEqual({
33
+ workspaceId: "org-with-hyphens",
34
+ projectSlug: "proj-123",
35
+ });
36
+ });
37
+ });
38
+ // ---------------------------------------------------------------------------
39
+ // projectSchema
40
+ // ---------------------------------------------------------------------------
41
+ describe("projectSchema", () => {
42
+ it("accepts a non-empty project string", () => {
43
+ expect(() => projectSchema.parse({ project: "org/slug" })).not.toThrow();
44
+ });
45
+ it("rejects an empty project string", () => {
46
+ expect(() => projectSchema.parse({ project: "" })).toThrow();
47
+ });
48
+ it("rejects a missing project field", () => {
49
+ expect(() => projectSchema.parse({})).toThrow();
50
+ });
51
+ });
52
+ // ---------------------------------------------------------------------------
53
+ // success
54
+ // ---------------------------------------------------------------------------
55
+ describe("success", () => {
56
+ it("produces a result with type=text content", () => {
57
+ const result = success({ data: 1 });
58
+ expect(result.content).toHaveLength(1);
59
+ expect(result.content[0]?.type).toBe("text");
60
+ });
61
+ it("serialises the payload as valid JSON", () => {
62
+ const result = success({ hello: "world", count: 42 });
63
+ const text = result.content[0]?.text;
64
+ expect(text).toBeDefined();
65
+ expect(() => JSON.parse(text)).not.toThrow();
66
+ expect(JSON.parse(text)).toEqual({ hello: "world", count: 42 });
67
+ });
68
+ it("does not set isError", () => {
69
+ const result = success({ ok: true });
70
+ expect(result.isError).toBeUndefined();
71
+ });
72
+ });
73
+ // ---------------------------------------------------------------------------
74
+ // error
75
+ // ---------------------------------------------------------------------------
76
+ describe("error", () => {
77
+ it("sets isError: true", () => {
78
+ const result = error("something went wrong");
79
+ expect(result.isError).toBe(true);
80
+ });
81
+ it("includes the message in the text content", () => {
82
+ const msg = "something went wrong";
83
+ const result = error(msg);
84
+ expect(result.content[0]?.text).toBe(msg);
85
+ });
86
+ it("produces exactly one content entry", () => {
87
+ const result = error("oops");
88
+ expect(result.content).toHaveLength(1);
89
+ expect(result.content[0]?.type).toBe("text");
90
+ });
91
+ });
92
+ // ---------------------------------------------------------------------------
93
+ // executeTool
94
+ // ---------------------------------------------------------------------------
95
+ describe("executeTool", () => {
96
+ const schema = z.object({ project: z.string().min(1), value: z.string() });
97
+ it("calls the handler with parsed input and ParsedProject on success", async () => {
98
+ const result = await executeTool({ project: "acme/website", value: "hello" }, schema, async (input, parsed) => {
99
+ return success({
100
+ value: input.value,
101
+ workspaceId: parsed.workspaceId,
102
+ projectSlug: parsed.projectSlug,
103
+ });
104
+ });
105
+ const data = expectSuccess(result);
106
+ expect(data.value).toBe("hello");
107
+ expect(data.workspaceId).toBe("acme");
108
+ expect(data.projectSlug).toBe("website");
109
+ });
110
+ it("returns isError: true with 'Validation error' on Zod failure", async () => {
111
+ const result = await executeTool({ project: "valid/project" /* missing required `value` */ }, schema, async () => success({}));
112
+ expect(isErrorResult(result)).toBe(true);
113
+ const msg = expectError(result);
114
+ expect(msg).toMatch(/Validation error/i);
115
+ });
116
+ it("returns isError: true when the handler throws", async () => {
117
+ const result = await executeTool({ project: "acme/website", value: "x" }, schema, async () => {
118
+ throw new Error("handler blew up");
119
+ });
120
+ expect(isErrorResult(result)).toBe(true);
121
+ expect(expectError(result)).toContain("handler blew up");
122
+ });
123
+ it("returns isError: true for invalid project format", async () => {
124
+ const result = await executeTool({ project: "not-a-valid-format", value: "x" }, schema, async () => success({}));
125
+ expect(isErrorResult(result)).toBe(true);
126
+ expect(expectError(result)).toMatch(/Invalid project format/i);
127
+ });
128
+ it("returns isError: true when args fail schema type coercion", async () => {
129
+ const result = await executeTool(null, // completely invalid args
130
+ schema, async () => success({}));
131
+ expect(isErrorResult(result)).toBe(true);
132
+ });
133
+ it("passes the full parsed project to the handler", async () => {
134
+ let capturedParsed = null;
135
+ await executeTool({ project: "my-org/my-slug", value: "test" }, schema, async (_input, parsed) => {
136
+ capturedParsed = parsed;
137
+ return success({});
138
+ });
139
+ expect(capturedParsed).toEqual({
140
+ workspaceId: "my-org",
141
+ projectSlug: "my-slug",
142
+ });
143
+ });
144
+ it("surfaces non-Error throws as string messages", async () => {
145
+ const result = await executeTool({ project: "acme/website", value: "x" }, schema, async () => {
146
+ // eslint-disable-next-line @typescript-eslint/no-throw-literal
147
+ throw "string error";
148
+ });
149
+ expect(isErrorResult(result)).toBe(true);
150
+ expect(expectError(result)).toBe("string error");
151
+ });
152
+ });
153
+ // ---------------------------------------------------------------------------
154
+ // executeSimpleTool
155
+ // ---------------------------------------------------------------------------
156
+ describe("executeSimpleTool", () => {
157
+ const schema = z.object({ name: z.string().min(1), count: z.number() });
158
+ it("calls the handler with parsed input and returns its result", async () => {
159
+ const result = await executeSimpleTool({ name: "test", count: 5 }, schema, async (input) => success({ echo: input.name, times: input.count }));
160
+ const data = expectSuccess(result);
161
+ expect(data.echo).toBe("test");
162
+ expect(data.times).toBe(5);
163
+ });
164
+ it("returns isError: true with 'Validation error' on Zod failure", async () => {
165
+ const result = await executeSimpleTool({ name: "" /* fails min(1) */, count: 3 }, schema, async () => success({}));
166
+ expect(isErrorResult(result)).toBe(true);
167
+ expect(expectError(result)).toMatch(/Validation error/i);
168
+ });
169
+ it("returns isError: true when the handler throws an Error", async () => {
170
+ const result = await executeSimpleTool({ name: "good", count: 1 }, schema, async () => {
171
+ throw new Error("simple handler failed");
172
+ });
173
+ expect(isErrorResult(result)).toBe(true);
174
+ expect(expectError(result)).toContain("simple handler failed");
175
+ });
176
+ it("returns isError: true when the handler throws a non-Error value", async () => {
177
+ const result = await executeSimpleTool({ name: "good", count: 1 }, schema, async () => {
178
+ // eslint-disable-next-line @typescript-eslint/no-throw-literal
179
+ throw 42;
180
+ });
181
+ expect(isErrorResult(result)).toBe(true);
182
+ expect(expectError(result)).toBe("42");
183
+ });
184
+ it("returns isError: true when args are completely invalid", async () => {
185
+ const result = await executeSimpleTool(undefined, schema, async () => success({}));
186
+ expect(isErrorResult(result)).toBe(true);
187
+ });
188
+ it("does not include isError on a successful result", async () => {
189
+ const result = await executeSimpleTool({ name: "ok", count: 0 }, schema, async () => success({ ok: true }));
190
+ expect(result.isError).toBeUndefined();
191
+ });
192
+ });
193
+ //# sourceMappingURL=base-tool.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"base-tool.test.js","sourceRoot":"","sources":["../../src/__tests__/base-tool.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,24 @@
1
+ /**
2
+ * contract.test.ts
3
+ *
4
+ * End-to-end contract tests that bridge the gap between tool logic and the real API.
5
+ *
6
+ * THREE test sections:
7
+ *
8
+ * 1. FORWARD CONTRACT — tool output → API schema validation
9
+ * Execute each tool with a mock client, capture what it ACTUALLY sends to the
10
+ * API (orgSlug, projectSlug, payload), and validate those args against the
11
+ * mcp-types Zod schemas (the real API contract). If the API schema rejects it,
12
+ * the tool has a normalization or mapping bug.
13
+ *
14
+ * 2. REVERSE CONTRACT — LLM-plausible args → tool acceptance
15
+ * Simulate inputs an LLM would plausibly generate from reading inputSchema,
16
+ * and assert the tool accepts them without isError. Catches regressions where
17
+ * a schema tightening breaks something an LLM was expected to send.
18
+ *
19
+ * 3. NEGATIVE CONTRACT — invalid args MUST be rejected
20
+ * Guard rails: assert that clearly invalid inputs are rejected (isError=true)
21
+ * so we never silently swallow bad data from an LLM.
22
+ */
23
+ export {};
24
+ //# sourceMappingURL=contract.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"contract.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/contract.test.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG"}