@walkinissue/angy 0.2.17 → 0.2.18

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/dist/plugin.js CHANGED
@@ -83,6 +83,21 @@ function validateLocaleAliasUsage(sourceLocale, targetLocale) {
83
83
  throw new Error('[angy] targetLocale cannot be "base". Use an explicit target locale or "working".');
84
84
  }
85
85
  }
86
+ function validateCatalogPathSemantics(next) {
87
+ const baseLocale = inferLocaleFromCatalogPath(next.basePoPath);
88
+ const workingLocale = inferLocaleFromCatalogPath(next.workingPoPath);
89
+ const expectedWorkingLocale = `${next.targetLocale}-working`;
90
+ if (baseLocale !== next.targetLocale) {
91
+ throw new Error(
92
+ `[angy] basePoPath must point to the ${next.targetLocale}.po catalog. Received "${baseLocale ?? "unknown"}".`
93
+ );
94
+ }
95
+ if (workingLocale !== expectedWorkingLocale) {
96
+ throw new Error(
97
+ `[angy] workingPoPath must point to the ${expectedWorkingLocale}.po catalog. Received "${workingLocale ?? "unknown"}".`
98
+ );
99
+ }
100
+ }
86
101
  function registerWorkingCatalogWatchController(controller) {
87
102
  workingCatalogWatchControllers.add(controller);
88
103
  return () => {
@@ -105,12 +120,14 @@ function resolveConfiguredLocaleAliases(next) {
105
120
  const resolvedSourceLocale = resolveLocaleAlias(rawSourceLocale, next);
106
121
  const resolvedTargetLocale = resolveLocaleAlias(rawTargetLocale, next);
107
122
  const usesDefaultSystemMessage = next.systemMessage === buildDefaultSystemMessage(rawSourceLocale, rawTargetLocale);
108
- return {
123
+ const resolved = {
109
124
  ...next,
110
125
  sourceLocale: resolvedSourceLocale,
111
126
  targetLocale: resolvedTargetLocale,
112
127
  systemMessage: usesDefaultSystemMessage ? buildDefaultSystemMessage(resolvedSourceLocale, resolvedTargetLocale) : next.systemMessage
113
128
  };
129
+ validateCatalogPathSemantics(resolved);
130
+ return resolved;
114
131
  }
115
132
  function completeAngyConfig(input) {
116
133
  assertNonEmptyString(input.basePoPath, "basePoPath");
@@ -118,8 +135,8 @@ function completeAngyConfig(input) {
118
135
  assertNonEmptyString(input.sourceLocale, "sourceLocale");
119
136
  assertNonEmptyString(input.targetLocale, "targetLocale");
120
137
  validateLocaleAliasUsage(input.sourceLocale, input.targetLocale);
121
- if (typeof input.apiKey !== "string") {
122
- throw new Error(`[angy] apiKey is required and must be a string. Use an empty string to disable suggestions.`);
138
+ if (typeof input.apiKey !== "string" && typeof input.apiKey !== "undefined") {
139
+ throw new Error(`[angy] apiKey must be a string when provided. Use an empty string to disable suggestions.`);
123
140
  }
124
141
  validateRoutePath(input.routePath);
125
142
  validateWatchIgnore(input.watchIgnore);
@@ -130,7 +147,7 @@ function completeAngyConfig(input) {
130
147
  sourceLocale: input.sourceLocale,
131
148
  targetLocale: input.targetLocale,
132
149
  routePath: input.routePath ?? "/api/translations",
133
- apiKey: input.apiKey,
150
+ apiKey: input.apiKey ?? "",
134
151
  systemMessage: input.systemMessage ?? buildDefaultSystemMessage(input.sourceLocale, input.targetLocale),
135
152
  suggestionModel: input.suggestionModel ?? "gpt-4.1-mini",
136
153
  watchIgnore: input.watchIgnore ?? ["**/en-working.po"],
@@ -138,7 +155,7 @@ function completeAngyConfig(input) {
138
155
  };
139
156
  }
140
157
  function defineAngyConfig(config2) {
141
- return completeAngyConfig(config2);
158
+ return resolveConfiguredLocaleAliases(completeAngyConfig(config2));
142
159
  }
143
160
  async function fileExists(path) {
144
161
  try {
@@ -158,13 +175,19 @@ async function loadTsConfigModule(path) {
158
175
  const tempPath = `${path}.angy.tmp.mjs`;
159
176
  await writeFile(tempPath, transformed.code, "utf8");
160
177
  try {
161
- return await import(`${pathToFileURL(tempPath).href}?t=${Date.now()}`);
178
+ return await import(
179
+ /* @vite-ignore */
180
+ `${pathToFileURL(tempPath).href}?t=${Date.now()}`
181
+ );
162
182
  } finally {
163
183
  await unlink(tempPath).catch(() => void 0);
164
184
  }
165
185
  }
166
186
  async function loadJsConfigModule(path) {
167
- return import(pathToFileURL(path).href);
187
+ return import(
188
+ /* @vite-ignore */
189
+ pathToFileURL(path).href
190
+ );
168
191
  }
169
192
  async function loadAngyConfigFromRoot(root) {
170
193
  if (loadedConfigRoot === root) {
@@ -235,7 +258,7 @@ function angy(options = {}) {
235
258
  return {
236
259
  define: {
237
260
  __ANGY_ROUTE_PATH__: JSON.stringify(resolvedConfig.routePath ?? "/api/translations"),
238
- __ANGY_LOCALES: JSON.stringify(localeRotation)
261
+ __ANGY_LOCALES__: JSON.stringify(localeRotation)
239
262
  },
240
263
  optimizeDeps: {
241
264
  exclude: ["angy", "angy/client", "angy/plugin", "angy/server"]
@@ -1,4 +1,5 @@
1
- export type TranslationOrigin = "base" | "working";
1
+ export type TranslationOrigin = "base" | "working";
2
+ export type TranslationStatus = "base" | "working" | "none" | "fuzzy" | "out_of_sync";
2
3
 
3
4
  export type CommitBatchItem = {
4
5
  resolvedMsgid: string;
@@ -22,10 +23,10 @@ export type PoTranslationEntry = {
22
23
  obsolete?: boolean;
23
24
  };
24
25
 
25
- export type NormalizedEntry = {
26
- msgid: string;
27
- msgctxt: string | null;
28
- msgidPlural: string | null;
26
+ export type NormalizedEntry = {
27
+ msgid: string;
28
+ msgctxt: string | null;
29
+ msgidPlural: string | null;
29
30
  msgstr: string[];
30
31
  references: string[];
31
32
  extractedComments: string[];
@@ -35,6 +36,27 @@ export type NormalizedEntry = {
35
36
  searchText: string;
36
37
  searchTokens: string[];
37
38
  hasTranslation: boolean;
38
- isFuzzy: boolean | undefined;
39
- translationOrigin: TranslationOrigin;
40
- };
39
+ isFuzzy: boolean | undefined;
40
+ translationOrigin: TranslationOrigin;
41
+ };
42
+
43
+ export type CatalogIntegrityIssue =
44
+ | {
45
+ type: "key_mismatch";
46
+ msgid: string;
47
+ msgctxt: string | null;
48
+ reason: "missing_in_working" | "missing_in_base";
49
+ }
50
+ | {
51
+ type: "missing_working_translation";
52
+ msgid: string;
53
+ msgctxt: string | null;
54
+ baseValue: string;
55
+ };
56
+
57
+ export type RotationImpactItem = {
58
+ msgid: string;
59
+ msgctxt: string | null;
60
+ baseValue: string;
61
+ workingValue: string;
62
+ };
package/dist/server.d.ts CHANGED
@@ -57,7 +57,7 @@ export type SuggestionProviderInput = {
57
57
  targetLocale: string;
58
58
  systemMessage: string;
59
59
  model: string;
60
- apiKey: string;
60
+ apiKey: string | undefined;
61
61
  };
62
62
 
63
63
  export type SuggestionProvider = (
@@ -70,7 +70,7 @@ export type AngyConfigInput = {
70
70
  sourceLocale: string;
71
71
  targetLocale: string;
72
72
  routePath?: string;
73
- apiKey: string;
73
+ apiKey?: string;
74
74
  systemMessage?: string;
75
75
  suggestionModel?: string;
76
76
  watchIgnore?: string[];