Skip to content

Commit 0071cd6

Browse files
committed
feat(cli): add csv support
1 parent 8df6091 commit 0071cd6

File tree

9 files changed

+873
-1
lines changed

9 files changed

+873
-1
lines changed

.changeset/famous-beans-remain.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
---
2+
"@replexica/spec": minor
3+
"@replexica/cli": minor
4+
"replexica": minor
5+
---
6+
7+
add csv format support

package/demo/csv/file.csv

Lines changed: 386 additions & 0 deletions
Large diffs are not rendered by default.

package/i18n.json

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,15 @@
33
"locale": {
44
"source": "en",
55
"targets": [
6-
"es"
6+
"it"
77
]
88
},
99
"buckets": {
10+
"csv": {
11+
"include": [
12+
"demo/csv/file.csv"
13+
]
14+
},
1015
"markdown": {
1116
"include": [
1217
"demo/markdown/[locale]/*.md"

package/i18n.lock

Lines changed: 381 additions & 0 deletions
Large diffs are not rendered by default.

packages/cli/package.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@
2424
"@replexica/spec": "workspace:*",
2525
"commander": "^12.1.0",
2626
"cors": "^2.8.5",
27+
"csv-parse": "^5.5.6",
28+
"csv-stringify": "^6.5.1",
2729
"dotenv": "^16.4.5",
2830
"express": "^4.19.2",
2931
"flat": "^6.0.1",
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
import { parse } from 'csv-parse/sync';
2+
import { stringify } from 'csv-stringify/sync';
3+
import _ from 'lodash';
4+
import { BucketLoader } from './_base';
5+
6+
export const csvLoader = (
7+
locale: string,
8+
loader: BucketLoader<void, string>
9+
): BucketLoader<void, Record<string, any>> => ({
10+
async load() {
11+
const inputText = await loader.load();
12+
const input = parse(inputText, {
13+
columns: true,
14+
});
15+
const result: Record<string, any> = {};
16+
17+
// Convert CSV rows to key-value pairs for the specified locale
18+
for (const row of input) {
19+
const key = row.id;
20+
if (key && row[locale]) {
21+
result[key] = row[locale];
22+
}
23+
}
24+
25+
console.log({ input, result });
26+
27+
return result;
28+
},
29+
30+
async save(payload) {
31+
const inputText = await loader.load();
32+
const input = parse(inputText, {
33+
columns: true,
34+
});
35+
36+
// Update or add translations for the specified locale
37+
const updatedRows = input.map((row: Record<string, any>) => ({
38+
...row,
39+
[locale]: payload[row.id] || row[locale] || ''
40+
}));
41+
42+
// Add any new keys that didn't exist before
43+
const existingKeys = new Set(input.map((row: Record<string, any>) => row.id));
44+
for (const [key, value] of Object.entries(payload)) {
45+
if (!existingKeys.has(key)) {
46+
const newRow: Record<string, string> = { id: key };
47+
// Initialize empty strings for all columns
48+
for (const column of Object.keys(input[0] || { id: '' })) {
49+
newRow[column] = column === locale ? value : '';
50+
}
51+
updatedRows.push(newRow);
52+
}
53+
}
54+
55+
const result = stringify(updatedRows, {
56+
header: true
57+
});
58+
59+
console.log({result});
60+
61+
return loader.save(result);
62+
}
63+
});

packages/cli/src/workers/bucket/index.ts

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ import { xcodeStringsLoader } from './xcode-strings';
1717
import { xcodeStringsdictLoader } from './xcode-stringsdict';
1818
import { flutterLoader } from './flutter';
1919
import { ReplexicaCLIError } from '../../utils/errors';
20+
import { csvLoader } from './csv';
2021

2122
// Path expansion
2223
export function expandPlaceholderedGlob(pathPattern: string, sourceLocale: string): string[] {
@@ -134,6 +135,16 @@ export function createBucketLoader(params: CreateBucketLoaderParams) {
134135
),
135136
flatLoader(),
136137
);
138+
case 'csv':
139+
return composeLoaders<string, Record<string, any>[]>(
140+
csvLoader(
141+
params.locale,
142+
composeLoaders(
143+
textLoader(filepath),
144+
),
145+
),
146+
flatLoader(),
147+
);
137148
case 'xcode-strings':
138149
return composeLoaders<string, Record<string, string>>(
139150
textLoader(filepath),

packages/spec/src/formats.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ export const bucketTypes = [
1212
'flutter',
1313
'android',
1414
'properties',
15+
'csv',
1516
] as const;
1617

1718
export const bucketTypeSchema = Z.enum(bucketTypes);

pnpm-lock.yaml

Lines changed: 16 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)