waha-shared 1.0.474 → 1.0.475

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.
@@ -45,9 +45,10 @@ interface UploadSourceParams {
45
45
  /** The id of the project to upload to, from `crowdinProjectIds`. */
46
46
  projectId: string;
47
47
  /**
48
- * The file's path relative to the crowdin folder. Include the language
49
- * folder when the project uses one (`eng/app_interface_text.json`); pass a
50
- * bare filename for projects that keep sources at the root.
48
+ * Absolute path to the source file to upload, somewhere under a `crowdin/`
49
+ * directory (e.g. `/path/to/project/crowdin/eng/app_interface_text.json`,
50
+ * or `/path/to/project/crowdin/foo.md` for a project that keeps sources at
51
+ * the root). The path Crowdin sees is everything after `crowdin/`.
51
52
  */
52
53
  source: string;
53
54
  /** The Crowdin personal access token to use for authentication. */
@@ -21,13 +21,32 @@ exports.crowdinProjectIds = {
21
21
  dmc: '663528',
22
22
  emails: '929263',
23
23
  };
24
- const BASE_PATH = path_1.default.resolve(__dirname, '../../crowdin/eng');
25
24
  /**
26
25
  * Where a translated file lands, relative to the language folder. Every Waha
27
26
  * project maps a language's Crowdin three-letter code onto its Waha id, which
28
27
  * is why translations download straight into `crowdin/{wahaLanguageId}`.
29
28
  */
30
29
  exports.CROWDIN_TRANSLATION_PATTERN = '%three_letters_code%/%original_file_name%';
30
+ /**
31
+ * Derives the Crowdin-relative path (what's shown in the dashboard, e.g.
32
+ * `eng/app_interface_text.json`) from an absolute filesystem path. Every
33
+ * Waha project keeps its Crowdin sources under a `crowdin/` directory, so
34
+ * that directory's name is the anchor: everything after the last `crowdin`
35
+ * segment is the path Crowdin knows about.
36
+ *
37
+ * This indirection exists because callers pass an absolute path rather than
38
+ * one relative to this file. `shared/` ships as a published npm package, so
39
+ * this file can end up executing from inside a consumer's `node_modules`,
40
+ * where a base path hardcoded relative to `__dirname` points nowhere useful.
41
+ */
42
+ function crowdinRelativePath(absolutePath) {
43
+ const segments = absolutePath.split(path_1.default.sep);
44
+ const crowdinIndex = segments.lastIndexOf('crowdin');
45
+ if (crowdinIndex === -1) {
46
+ throw new Error(`Expected an absolute path under a "crowdin" directory, got "${absolutePath}".`);
47
+ }
48
+ return segments.slice(crowdinIndex + 1).join('/');
49
+ }
31
50
  /**
32
51
  * Downloads translations from Crowdin for a given project ID and source path.
33
52
  */
@@ -51,8 +70,9 @@ function downloadTranslations({ projectId, translationsFolder, token, sourcePatt
51
70
  async function uploadSource({ projectId, source, token, label, fileSettings, }) {
52
71
  const client = new crowdin_api_client_1.default({ token });
53
72
  const id = Number(projectId);
54
- const fileName = source.split('/').pop();
55
- const contents = fs_1.default.readFileSync(path_1.default.join(BASE_PATH, source), 'utf8');
73
+ const relativePath = crowdinRelativePath(source);
74
+ const fileName = relativePath.split('/').pop();
75
+ const contents = fs_1.default.readFileSync(source, 'utf8');
56
76
  const storage = await client.uploadStorageApi.addStorage(fileName, contents);
57
77
  /*
58
78
  * Replacing a file needs its numeric id, and the API has no by-path
@@ -64,7 +84,7 @@ async function uploadSource({ projectId, source, token, label, fileSettings, })
64
84
  filter: fileName,
65
85
  limit: 500,
66
86
  });
67
- const existing = files.data.find((file) => file.data.path === `/${source}`);
87
+ const existing = files.data.find((file) => file.data.path === `/${relativePath}`);
68
88
  const exportOptions = {
69
89
  exportPattern: `/${exports.CROWDIN_TRANSLATION_PATTERN}`,
70
90
  };
@@ -97,7 +117,7 @@ async function uploadSource({ projectId, source, token, label, fileSettings, })
97
117
  exportOptions,
98
118
  ...fileSettings,
99
119
  ...(attachLabelIds && { attachLabelIds }),
100
- ...(await directoryId(client, id, source)),
120
+ ...(await directoryId(client, id, relativePath)),
101
121
  };
102
122
  await client.sourceFilesApi.createFile(id, request);
103
123
  }
@@ -117,8 +137,8 @@ async function labelId(client, projectId, title) {
117
137
  * misspelled path that gets created silently uploads to a new file and
118
138
  * orphans every translation attached to the real one.
119
139
  */
120
- async function directoryId(client, projectId, source) {
121
- const segments = source.split('/').slice(0, -1);
140
+ async function directoryId(client, projectId, relativePath) {
141
+ const segments = relativePath.split('/').slice(0, -1);
122
142
  if (segments.length === 0)
123
143
  return {};
124
144
  const wanted = `/${segments.join('/')}`;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "waha-shared",
3
- "version": "1.0.474",
3
+ "version": "1.0.475",
4
4
  "author": "Waha",
5
5
  "dependencies": {
6
6
  "@types/signale": "^1.4.7",