@inlang/sdk 0.1.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.
Files changed (170) hide show
  1. package/README.md +25 -0
  2. package/dist/adapter/solidAdapter.d.ts +32 -0
  3. package/dist/adapter/solidAdapter.d.ts.map +1 -0
  4. package/dist/adapter/solidAdapter.js +39 -0
  5. package/dist/adapter/solidAdapter.test.d.ts +2 -0
  6. package/dist/adapter/solidAdapter.test.d.ts.map +1 -0
  7. package/dist/adapter/solidAdapter.test.js +284 -0
  8. package/dist/api.d.ts +88 -0
  9. package/dist/api.d.ts.map +1 -0
  10. package/dist/api.js +1 -0
  11. package/dist/createMessageLintReportsQuery.d.ts +9 -0
  12. package/dist/createMessageLintReportsQuery.d.ts.map +1 -0
  13. package/dist/createMessageLintReportsQuery.js +48 -0
  14. package/dist/createMessagesQuery.d.ts +7 -0
  15. package/dist/createMessagesQuery.d.ts.map +1 -0
  16. package/dist/createMessagesQuery.js +57 -0
  17. package/dist/createMessagesQuery.test.d.ts +2 -0
  18. package/dist/createMessagesQuery.test.d.ts.map +1 -0
  19. package/dist/createMessagesQuery.test.js +304 -0
  20. package/dist/errors.d.ts +22 -0
  21. package/dist/errors.d.ts.map +1 -0
  22. package/dist/errors.js +39 -0
  23. package/dist/index.d.ts +15 -0
  24. package/dist/index.d.ts.map +1 -0
  25. package/dist/index.js +13 -0
  26. package/dist/lint/index.d.ts +3 -0
  27. package/dist/lint/index.d.ts.map +1 -0
  28. package/dist/lint/index.js +2 -0
  29. package/dist/lint/message/errors.d.ts +7 -0
  30. package/dist/lint/message/errors.d.ts.map +1 -0
  31. package/dist/lint/message/errors.js +9 -0
  32. package/dist/lint/message/lintMessages.d.ts +17 -0
  33. package/dist/lint/message/lintMessages.d.ts.map +1 -0
  34. package/dist/lint/message/lintMessages.js +12 -0
  35. package/dist/lint/message/lintMessages.test.d.ts +2 -0
  36. package/dist/lint/message/lintMessages.test.d.ts.map +1 -0
  37. package/dist/lint/message/lintMessages.test.js +105 -0
  38. package/dist/lint/message/lintSingleMessage.d.ts +23 -0
  39. package/dist/lint/message/lintSingleMessage.d.ts.map +1 -0
  40. package/dist/lint/message/lintSingleMessage.js +36 -0
  41. package/dist/lint/message/lintSingleMessage.test.d.ts +2 -0
  42. package/dist/lint/message/lintSingleMessage.test.d.ts.map +1 -0
  43. package/dist/lint/message/lintSingleMessage.test.js +155 -0
  44. package/dist/messages/errors.d.ts +13 -0
  45. package/dist/messages/errors.d.ts.map +1 -0
  46. package/dist/messages/errors.js +18 -0
  47. package/dist/messages/index.d.ts +3 -0
  48. package/dist/messages/index.d.ts.map +1 -0
  49. package/dist/messages/index.js +2 -0
  50. package/dist/messages/variant.d.ts +46 -0
  51. package/dist/messages/variant.d.ts.map +1 -0
  52. package/dist/messages/variant.js +177 -0
  53. package/dist/messages/variant.test.d.ts +2 -0
  54. package/dist/messages/variant.test.d.ts.map +1 -0
  55. package/dist/messages/variant.test.js +379 -0
  56. package/dist/openInlangProject.d.ts +18 -0
  57. package/dist/openInlangProject.d.ts.map +1 -0
  58. package/dist/openInlangProject.js +226 -0
  59. package/dist/openInlangProject.test.d.ts +2 -0
  60. package/dist/openInlangProject.test.d.ts.map +1 -0
  61. package/dist/openInlangProject.test.js +627 -0
  62. package/dist/parseConfig.d.ts +8 -0
  63. package/dist/parseConfig.d.ts.map +1 -0
  64. package/dist/parseConfig.js +26 -0
  65. package/dist/reactivity/map.d.ts +66 -0
  66. package/dist/reactivity/map.d.ts.map +1 -0
  67. package/dist/reactivity/map.js +143 -0
  68. package/dist/reactivity/solid.d.ts +12 -0
  69. package/dist/reactivity/solid.d.ts.map +1 -0
  70. package/dist/reactivity/solid.js +13 -0
  71. package/dist/reactivity/trigger.d.ts +11 -0
  72. package/dist/reactivity/trigger.d.ts.map +1 -0
  73. package/dist/reactivity/trigger.js +46 -0
  74. package/dist/resolve-modules/errors.d.ts +34 -0
  75. package/dist/resolve-modules/errors.d.ts.map +1 -0
  76. package/dist/resolve-modules/errors.js +35 -0
  77. package/dist/resolve-modules/import.d.ts +35 -0
  78. package/dist/resolve-modules/import.d.ts.map +1 -0
  79. package/dist/resolve-modules/import.js +40 -0
  80. package/dist/resolve-modules/import.test.d.ts +2 -0
  81. package/dist/resolve-modules/import.test.d.ts.map +1 -0
  82. package/dist/resolve-modules/import.test.js +45 -0
  83. package/dist/resolve-modules/index.d.ts +3 -0
  84. package/dist/resolve-modules/index.d.ts.map +1 -0
  85. package/dist/resolve-modules/index.js +2 -0
  86. package/dist/resolve-modules/message-lint-rules/errors.d.ts +8 -0
  87. package/dist/resolve-modules/message-lint-rules/errors.d.ts.map +1 -0
  88. package/dist/resolve-modules/message-lint-rules/errors.js +8 -0
  89. package/dist/resolve-modules/message-lint-rules/resolveMessageLintRules.d.ts +9 -0
  90. package/dist/resolve-modules/message-lint-rules/resolveMessageLintRules.d.ts.map +1 -0
  91. package/dist/resolve-modules/message-lint-rules/resolveMessageLintRules.js +21 -0
  92. package/dist/resolve-modules/plugins/errors.d.ts +28 -0
  93. package/dist/resolve-modules/plugins/errors.d.ts.map +1 -0
  94. package/dist/resolve-modules/plugins/errors.js +44 -0
  95. package/dist/resolve-modules/plugins/resolvePlugins.d.ts +3 -0
  96. package/dist/resolve-modules/plugins/resolvePlugins.d.ts.map +1 -0
  97. package/dist/resolve-modules/plugins/resolvePlugins.js +108 -0
  98. package/dist/resolve-modules/plugins/resolvePlugins.test.d.ts +2 -0
  99. package/dist/resolve-modules/plugins/resolvePlugins.test.d.ts.map +1 -0
  100. package/dist/resolve-modules/plugins/resolvePlugins.test.js +289 -0
  101. package/dist/resolve-modules/plugins/types.d.ts +60 -0
  102. package/dist/resolve-modules/plugins/types.d.ts.map +1 -0
  103. package/dist/resolve-modules/plugins/types.js +1 -0
  104. package/dist/resolve-modules/plugins/types.test.d.ts +2 -0
  105. package/dist/resolve-modules/plugins/types.test.d.ts.map +1 -0
  106. package/dist/resolve-modules/plugins/types.test.js +49 -0
  107. package/dist/resolve-modules/resolveModules.d.ts +3 -0
  108. package/dist/resolve-modules/resolveModules.d.ts.map +1 -0
  109. package/dist/resolve-modules/resolveModules.js +70 -0
  110. package/dist/resolve-modules/resolveModules.test.d.ts +2 -0
  111. package/dist/resolve-modules/resolveModules.test.d.ts.map +1 -0
  112. package/dist/resolve-modules/resolveModules.test.js +143 -0
  113. package/dist/resolve-modules/types.d.ts +62 -0
  114. package/dist/resolve-modules/types.d.ts.map +1 -0
  115. package/dist/resolve-modules/types.js +1 -0
  116. package/dist/test-utilities/createMessage.d.ts +17 -0
  117. package/dist/test-utilities/createMessage.d.ts.map +1 -0
  118. package/dist/test-utilities/createMessage.js +16 -0
  119. package/dist/test-utilities/createMessage.test.d.ts +2 -0
  120. package/dist/test-utilities/createMessage.test.d.ts.map +1 -0
  121. package/dist/test-utilities/createMessage.test.js +91 -0
  122. package/dist/test-utilities/index.d.ts +2 -0
  123. package/dist/test-utilities/index.d.ts.map +1 -0
  124. package/dist/test-utilities/index.js +1 -0
  125. package/dist/versionedInterfaces.d.ts +8 -0
  126. package/dist/versionedInterfaces.d.ts.map +1 -0
  127. package/dist/versionedInterfaces.js +8 -0
  128. package/package.json +58 -0
  129. package/src/adapter/solidAdapter.test.ts +363 -0
  130. package/src/adapter/solidAdapter.ts +77 -0
  131. package/src/api.ts +86 -0
  132. package/src/createMessageLintReportsQuery.ts +77 -0
  133. package/src/createMessagesQuery.test.ts +435 -0
  134. package/src/createMessagesQuery.ts +64 -0
  135. package/src/errors.ts +46 -0
  136. package/src/index.ts +29 -0
  137. package/src/lint/index.ts +2 -0
  138. package/src/lint/message/errors.ts +9 -0
  139. package/src/lint/message/lintMessages.test.ts +122 -0
  140. package/src/lint/message/lintMessages.ts +33 -0
  141. package/src/lint/message/lintSingleMessage.test.ts +183 -0
  142. package/src/lint/message/lintSingleMessage.ts +62 -0
  143. package/src/messages/errors.ts +25 -0
  144. package/src/messages/index.ts +2 -0
  145. package/src/messages/variant.test.ts +444 -0
  146. package/src/messages/variant.ts +242 -0
  147. package/src/openInlangProject.test.ts +734 -0
  148. package/src/openInlangProject.ts +337 -0
  149. package/src/parseConfig.ts +33 -0
  150. package/src/reactivity/map.ts +135 -0
  151. package/src/reactivity/solid.ts +36 -0
  152. package/src/reactivity/trigger.ts +46 -0
  153. package/src/resolve-modules/errors.ts +39 -0
  154. package/src/resolve-modules/import.test.ts +58 -0
  155. package/src/resolve-modules/import.ts +69 -0
  156. package/src/resolve-modules/index.ts +2 -0
  157. package/src/resolve-modules/message-lint-rules/errors.ts +9 -0
  158. package/src/resolve-modules/message-lint-rules/resolveMessageLintRules.ts +24 -0
  159. package/src/resolve-modules/plugins/errors.ts +57 -0
  160. package/src/resolve-modules/plugins/resolvePlugins.test.ts +340 -0
  161. package/src/resolve-modules/plugins/resolvePlugins.ts +170 -0
  162. package/src/resolve-modules/plugins/types.test.ts +57 -0
  163. package/src/resolve-modules/plugins/types.ts +77 -0
  164. package/src/resolve-modules/resolveModules.test.ts +176 -0
  165. package/src/resolve-modules/resolveModules.ts +97 -0
  166. package/src/resolve-modules/types.ts +71 -0
  167. package/src/test-utilities/createMessage.test.ts +100 -0
  168. package/src/test-utilities/createMessage.ts +20 -0
  169. package/src/test-utilities/index.ts +1 -0
  170. package/src/versionedInterfaces.ts +9 -0
@@ -0,0 +1,122 @@
1
+ import { beforeEach, describe, expect, test, vi } from "vitest"
2
+ import { lintMessages } from "./lintMessages.js"
3
+ import type { MessageLintReport, MessageLintRule } from "@inlang/message-lint-rule"
4
+ import type { Message } from "@inlang/message"
5
+
6
+ const lintRule1 = {
7
+ meta: {
8
+ id: "messageLintRule.x.1",
9
+ displayName: { en: "" },
10
+ description: { en: "" },
11
+ },
12
+ message: vi.fn(),
13
+ } satisfies MessageLintRule
14
+
15
+ const lintRule2 = {
16
+ meta: {
17
+ id: "messageLintRule.x.2",
18
+ displayName: { en: "" },
19
+ description: { en: "" },
20
+ },
21
+ message: vi.fn(),
22
+ } satisfies MessageLintRule
23
+
24
+ const message1 = { id: "m1" } as Message
25
+ const message2 = { id: "m2" } as Message
26
+ const message3 = { id: "m3" } as Message
27
+
28
+ const messages = [message1, message2, message3]
29
+
30
+ describe("lintMessages", async () => {
31
+ beforeEach(() => {
32
+ vi.resetAllMocks()
33
+ })
34
+
35
+ test("it should await all messages", async () => {
36
+ let called = 0
37
+ lintRule2.message.mockImplementation(async () => {
38
+ await new Promise((resolve) => setTimeout(resolve, 0))
39
+ called++
40
+ })
41
+
42
+ await lintMessages({
43
+ ruleLevels: {
44
+ [lintRule1.meta.id]: "warning",
45
+ [lintRule2.meta.id]: "warning",
46
+ },
47
+ ruleSettings: {},
48
+ sourceLanguageTag: "en",
49
+ languageTags: [],
50
+ messages,
51
+ rules: [lintRule1, lintRule2],
52
+ })
53
+
54
+ expect(lintRule1.message).toHaveBeenCalledTimes(3)
55
+ expect(called).toBe(3)
56
+ })
57
+
58
+ test("it should process all messages and rules in parallel", async () => {
59
+ const fn = vi.fn()
60
+
61
+ lintRule1.message.mockImplementation(async ({ message }) => {
62
+ fn("r1", "before", message.id)
63
+ await new Promise((resolve) => setTimeout(resolve, 0))
64
+ fn("r1", "after", message.id)
65
+ })
66
+ lintRule2.message.mockImplementation(async ({ message }) => {
67
+ fn("r2", "before", message.id)
68
+ await new Promise((resolve) => setTimeout(resolve, 0))
69
+ fn("r2", "after", message.id)
70
+ })
71
+
72
+ await lintMessages({
73
+ ruleLevels: {
74
+ [lintRule1.meta.id]: "warning",
75
+ [lintRule2.meta.id]: "warning",
76
+ },
77
+ ruleSettings: {},
78
+ rules: [lintRule1, lintRule2],
79
+ sourceLanguageTag: "en",
80
+ languageTags: [],
81
+ messages,
82
+ })
83
+
84
+ expect(fn).toHaveBeenCalledTimes(12)
85
+ expect(fn).toHaveBeenNthCalledWith(1, "r1", "before", "m1")
86
+ expect(fn).toHaveBeenNthCalledWith(2, "r2", "before", "m1")
87
+ expect(fn).toHaveBeenNthCalledWith(3, "r1", "before", "m2")
88
+ expect(fn).toHaveBeenNthCalledWith(4, "r2", "before", "m2")
89
+ expect(fn).toHaveBeenNthCalledWith(5, "r1", "before", "m3")
90
+ expect(fn).toHaveBeenNthCalledWith(6, "r2", "before", "m3")
91
+ expect(fn).toHaveBeenNthCalledWith(7, "r1", "after", "m1")
92
+ expect(fn).toHaveBeenNthCalledWith(8, "r2", "after", "m1")
93
+ expect(fn).toHaveBeenNthCalledWith(9, "r1", "after", "m2")
94
+ expect(fn).toHaveBeenNthCalledWith(10, "r2", "after", "m2")
95
+ expect(fn).toHaveBeenNthCalledWith(11, "r1", "after", "m3")
96
+ expect(fn).toHaveBeenNthCalledWith(12, "r2", "after", "m3")
97
+ })
98
+
99
+ test("it should not abort the linting process when errors occur", async () => {
100
+ lintRule1.message.mockImplementation(({ report }) => {
101
+ report({} as MessageLintReport)
102
+ })
103
+ lintRule2.message.mockImplementation(() => {
104
+ throw new Error("error")
105
+ })
106
+
107
+ const { data, errors } = await lintMessages({
108
+ ruleLevels: {
109
+ [lintRule1.meta.id]: "warning",
110
+ [lintRule2.meta.id]: "warning",
111
+ },
112
+ ruleSettings: {},
113
+ sourceLanguageTag: "en",
114
+ languageTags: [],
115
+ messages,
116
+ rules: [lintRule1, lintRule2],
117
+ })
118
+
119
+ expect(data).toHaveLength(3)
120
+ expect(errors).toHaveLength(3)
121
+ })
122
+ })
@@ -0,0 +1,33 @@
1
+ import type { Message } from "@inlang/message"
2
+ import { lintSingleMessage } from "./lintSingleMessage.js"
3
+ import type { MessagedLintRuleThrowedError } from "./errors.js"
4
+ import type { LanguageTag } from "@inlang/language-tag"
5
+ import type { JSONObject } from "@inlang/json-types"
6
+ import type {
7
+ MessageLintLevel,
8
+ MessageLintReport,
9
+ MessageLintRule,
10
+ } from "@inlang/message-lint-rule"
11
+
12
+ export const lintMessages = async (args: {
13
+ sourceLanguageTag: LanguageTag
14
+ languageTags: LanguageTag[]
15
+ ruleSettings: Record<MessageLintRule["meta"]["id"], JSONObject>
16
+ ruleLevels: Record<MessageLintRule["meta"]["id"], MessageLintLevel>
17
+ rules: MessageLintRule[]
18
+ messages: Message[]
19
+ }): Promise<{ data: MessageLintReport[]; errors: MessagedLintRuleThrowedError[] }> => {
20
+ const promises = args.messages.map((message) =>
21
+ lintSingleMessage({
22
+ ...args,
23
+ message,
24
+ }),
25
+ )
26
+
27
+ const results = await Promise.all(promises)
28
+
29
+ return {
30
+ data: results.flatMap((result) => result.data).filter(Boolean),
31
+ errors: results.flatMap((result) => result.errors).filter(Boolean),
32
+ }
33
+ }
@@ -0,0 +1,183 @@
1
+ import { beforeEach, describe, expect, test, vi } from "vitest"
2
+ import { lintSingleMessage } from "./lintSingleMessage.js"
3
+ import type { MessageLintReport, MessageLintRule } from "@inlang/message-lint-rule"
4
+ import type { Message } from "@inlang/message"
5
+ import { tryCatch } from "@inlang/result"
6
+
7
+ const lintRule1 = {
8
+ meta: {
9
+ id: "messageLintRule.r.1",
10
+ displayName: { en: "" },
11
+ description: { en: "" },
12
+ },
13
+ message: vi.fn(),
14
+ } satisfies MessageLintRule
15
+
16
+ const lintRule2 = {
17
+ meta: {
18
+ id: "messageLintRule.r.2",
19
+ displayName: { en: "" },
20
+ description: { en: "" },
21
+ },
22
+ message: vi.fn(),
23
+ } satisfies MessageLintRule
24
+
25
+ const message1 = {} as Message
26
+
27
+ const messages = [message1]
28
+
29
+ describe("lintSingleMessage", async () => {
30
+ beforeEach(() => {
31
+ vi.resetAllMocks()
32
+ })
33
+
34
+ describe("resolve rules and settings", async () => {
35
+ // the lint function is un-opinionated and does not set a default level.
36
+ // opinionated users like the inlang instance can very well set a default level (separation of concerns)
37
+ test("it should throw if a lint level is not provided for a given lint rule", async () => {
38
+ lintRule1.message.mockImplementation(({ report }) => report({} as MessageLintReport))
39
+
40
+ const result = await tryCatch(() =>
41
+ lintSingleMessage({
42
+ ruleLevels: {},
43
+ ruleSettings: {},
44
+ sourceLanguageTag: "en",
45
+ languageTags: ["en"],
46
+ messages,
47
+ message: message1,
48
+ rules: [lintRule1],
49
+ }),
50
+ )
51
+ expect(result.error).toBeDefined()
52
+ expect(result.data).toBeUndefined()
53
+ })
54
+
55
+ test("it should override the default lint level", async () => {
56
+ lintRule1.message.mockImplementation(({ report }) => report({} as MessageLintReport))
57
+
58
+ const reports = await lintSingleMessage({
59
+ ruleLevels: {
60
+ [lintRule1.meta.id]: "error",
61
+ },
62
+ ruleSettings: {},
63
+ sourceLanguageTag: "en",
64
+ languageTags: ["en"],
65
+ messages,
66
+ message: message1,
67
+ rules: [lintRule1],
68
+ })
69
+ expect(reports.data[0]?.level).toBe("error")
70
+ })
71
+
72
+ test("it should pass the correct settings", async () => {
73
+ const settings = {}
74
+
75
+ const fn = vi.fn()
76
+ lintRule1.message.mockImplementation(({ settings }) => fn(settings))
77
+
78
+ await lintSingleMessage({
79
+ ruleLevels: {
80
+ [lintRule1.meta.id]: "warning",
81
+ },
82
+ ruleSettings: {
83
+ [lintRule1.meta.id]: settings,
84
+ },
85
+ sourceLanguageTag: "en",
86
+ languageTags: ["en"],
87
+ messages,
88
+ message: message1,
89
+ rules: [lintRule1],
90
+ })
91
+
92
+ expect(fn).toHaveBeenCalledWith(settings)
93
+ })
94
+ })
95
+
96
+ test("it should await all rules", async () => {
97
+ let m1Called = false
98
+ let m2Called = false
99
+ lintRule1.message.mockImplementation(() => {
100
+ m1Called = true
101
+ })
102
+ lintRule2.message.mockImplementation(async () => {
103
+ await new Promise((resolve) => setTimeout(resolve, 0))
104
+ m2Called = true
105
+ })
106
+
107
+ await lintSingleMessage({
108
+ ruleLevels: {
109
+ [lintRule1.meta.id]: "warning",
110
+ [lintRule2.meta.id]: "warning",
111
+ },
112
+ ruleSettings: {},
113
+ sourceLanguageTag: "en",
114
+ languageTags: ["en"],
115
+ messages,
116
+ message: message1,
117
+ rules: [lintRule1, lintRule2],
118
+ })
119
+
120
+ expect(m1Called).toBe(true)
121
+ expect(m2Called).toBe(true)
122
+ })
123
+
124
+ test("it should process all rules in parallel", async () => {
125
+ const fn = vi.fn()
126
+
127
+ lintRule1.message.mockImplementation(async () => {
128
+ fn(lintRule1.meta.id, "before")
129
+ await new Promise((resolve) => setTimeout(resolve, 0))
130
+ fn(lintRule1.meta.id, "after")
131
+ })
132
+ lintRule2.message.mockImplementation(async () => {
133
+ fn(lintRule2.meta.id, "before")
134
+ await new Promise((resolve) => setTimeout(resolve, 0))
135
+ fn(lintRule2.meta.id, "after")
136
+ })
137
+
138
+ await lintSingleMessage({
139
+ ruleLevels: {
140
+ [lintRule1.meta.id]: "warning",
141
+ [lintRule2.meta.id]: "warning",
142
+ },
143
+ ruleSettings: {},
144
+ sourceLanguageTag: "en",
145
+ languageTags: ["en"],
146
+ messages,
147
+ message: message1,
148
+ rules: [lintRule1, lintRule2],
149
+ })
150
+
151
+ expect(fn).toHaveBeenCalledTimes(4)
152
+ expect(fn).toHaveBeenNthCalledWith(1, lintRule1.meta.id, "before")
153
+ expect(fn).toHaveBeenNthCalledWith(2, lintRule2.meta.id, "before")
154
+ expect(fn).toHaveBeenNthCalledWith(3, lintRule1.meta.id, "after")
155
+ expect(fn).toHaveBeenNthCalledWith(4, lintRule2.meta.id, "after")
156
+ })
157
+
158
+ test("it should not abort the linting process when errors occur", async () => {
159
+ lintRule1.message.mockImplementation(() => {
160
+ throw new Error("error")
161
+ })
162
+
163
+ lintRule2.message.mockImplementation(({ report }) => {
164
+ report({} as MessageLintReport)
165
+ })
166
+
167
+ const result = await lintSingleMessage({
168
+ ruleLevels: {
169
+ [lintRule1.meta.id]: "warning",
170
+ [lintRule2.meta.id]: "warning",
171
+ },
172
+ ruleSettings: {},
173
+ sourceLanguageTag: "en",
174
+ languageTags: ["en"],
175
+ messages,
176
+ message: message1,
177
+ rules: [lintRule1, lintRule2],
178
+ })
179
+
180
+ expect(result.data).length(1)
181
+ expect(result.errors).length(1)
182
+ })
183
+ })
@@ -0,0 +1,62 @@
1
+ import type {
2
+ MessageLintLevel,
3
+ MessageLintRule,
4
+ MessageLintReport,
5
+ } from "@inlang/message-lint-rule"
6
+ import type { Message } from "@inlang/message"
7
+ import { MessagedLintRuleThrowedError } from "./errors.js"
8
+ import type { LanguageTag } from "@inlang/language-tag"
9
+ import type { JSONObject } from "@inlang/json-types"
10
+
11
+ /**
12
+ * Lint a single message.
13
+ *
14
+ * - the lint rule levels defaults to `warning`.
15
+ */
16
+ export const lintSingleMessage = async (args: {
17
+ sourceLanguageTag: LanguageTag
18
+ languageTags: LanguageTag[]
19
+ ruleSettings: Record<MessageLintRule["meta"]["id"], JSONObject>
20
+ ruleLevels: Record<MessageLintRule["meta"]["id"], MessageLintLevel>
21
+ rules: MessageLintRule[]
22
+ messages: Message[]
23
+ message: Message
24
+ }): Promise<{ data: MessageLintReport[]; errors: MessagedLintRuleThrowedError[] }> => {
25
+ const reports: MessageLintReport[] = []
26
+ const errors: MessagedLintRuleThrowedError[] = []
27
+
28
+ const promises = args.rules.map(async (rule) => {
29
+ const ruleId = rule.meta.id
30
+ const settings = args.ruleSettings?.[ruleId] ?? {}
31
+ const level = args.ruleLevels?.[ruleId]
32
+
33
+ if (level === undefined) {
34
+ throw Error("No lint level provided for lint rule: " + ruleId)
35
+ }
36
+
37
+ try {
38
+ await rule.message({
39
+ ...args,
40
+ settings,
41
+ report: (reportArgs) => {
42
+ reports.push({
43
+ ruleId,
44
+ level,
45
+ ...reportArgs,
46
+ })
47
+ },
48
+ })
49
+ } catch (error) {
50
+ errors.push(
51
+ new MessagedLintRuleThrowedError(
52
+ `Lint rule '${ruleId}' throwed while linting message "${args.message.id}".`,
53
+ { cause: error },
54
+ ),
55
+ )
56
+ }
57
+ })
58
+
59
+ await Promise.all(promises)
60
+
61
+ return { data: reports, errors }
62
+ }
@@ -0,0 +1,25 @@
1
+ export class MessageVariantDoesNotExistError extends Error {
2
+ readonly #id = "MessageVariantDoesNotExistError"
3
+
4
+ constructor(messageId: string, languageTag: string) {
5
+ super(
6
+ `For message '${messageId}' and '${languageTag}', there doesn't exist a variant for this specific matchers.`,
7
+ )
8
+ }
9
+ }
10
+ export class MessageVariantAlreadyExistsError extends Error {
11
+ readonly #id = "MessageVariantAlreadyExistsError"
12
+
13
+ constructor(messageId: string, languageTag: string) {
14
+ super(
15
+ `For message '${messageId}' and '${languageTag}', there already exists a variant for this specific matchers.`,
16
+ )
17
+ }
18
+ }
19
+ export class MessagePatternsForLanguageTagDoNotExistError extends Error {
20
+ readonly #id = "MessagePatternsForLanguageTagDoNotExistError"
21
+
22
+ constructor(messageId: string, languageTag: string) {
23
+ super(`For message '${messageId}' there are no patterns with the languageTag '${languageTag}'.`)
24
+ }
25
+ }
@@ -0,0 +1,2 @@
1
+ export * from "./variant.js"
2
+ export * from "./errors.js"