Skip to content

Commit

Permalink
feat: add fileStructureTemplate option
Browse files Browse the repository at this point in the history
  • Loading branch information
stepan662 committed May 17, 2024
1 parent 792c8c0 commit 47055d7
Show file tree
Hide file tree
Showing 4 changed files with 56 additions and 0 deletions.
4 changes: 4 additions & 0 deletions schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,10 @@
"description": "Export keys with array syntax (e.g. item[0]) as arrays.",
"type": "boolean"
},
"fileStructureTemplate": {
"description": "This is a template that defines the structure of the resulting .zip file content.\n\nThe template is a string that can contain the following placeholders: {namespace}, {languageTag}, {androidLanguageTag}, {snakeLanguageTag}, {extension}.\n\nFor example, when exporting to JSON with the template {namespace}/{languageTag}.{extension}, the English translations of the home namespace will be stored in home/en.json.\n\nThe {snakeLanguageTag} placeholder is the same as {languageTag} but in snake case. (e.g., en_US).\n\nThe Android specific {androidLanguageTag} placeholder is the same as {languageTag} but in Android format. (e.g., en-rUS)",
"type": "string"
},
"emptyDir": {
"description": "Empty [path] folder before inserting pulled files.",
"type": "boolean"
Expand Down
12 changes: 12 additions & 0 deletions src/commands/pull.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ type PullOptions = BaseOptions & {
tags?: string[];
supportArrays: boolean;
excludeTags?: string[];
fileStructureTemplate?: string;
};

async function fetchZipBlob(opts: PullOptions): Promise<Blob> {
Expand All @@ -36,6 +37,7 @@ async function fetchZipBlob(opts: PullOptions): Promise<Blob> {
filterNamespace: opts.namespaces,
filterTagIn: opts.tags,
filterTagNotIn: opts.excludeTags,
fileStructureTemplate: opts.fileStructureTemplate,
});
}

Expand Down Expand Up @@ -131,4 +133,14 @@ export default (config: Schema) =>
'Empty [path] directory before inserting pulled files.'
).default(config.pull?.emptyDir)
)
.addOption(
new Option(
'--file-structure-template <template>',
'This is a template that defines the structure of the resulting .zip file content.\n\n' +
'The template is a string that can contain the following placeholders: {namespace}, {languageTag}, {androidLanguageTag}, {snakeLanguageTag}, {extension}.\n\n' +
'For example, when exporting to JSON with the template {namespace}/{languageTag}.{extension}, the English translations of the home namespace will be stored in home/en.json.\n\n' +
'The {snakeLanguageTag} placeholder is the same as {languageTag} but in snake case. (e.g., en_US).\n\n' +
'The Android specific {androidLanguageTag} placeholder is the same as {languageTag} but in Android format. (e.g., en-rUS)'
).default(config.pull?.fileStructureTemplate)
)
.action(pullHandler());
12 changes: 12 additions & 0 deletions src/schema.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,18 @@ export interface Schema {
* Export keys with array syntax (e.g. item[0]) as arrays.
*/
supportArrays?: boolean;
/**
* This is a template that defines the structure of the resulting .zip file content.
*
* The template is a string that can contain the following placeholders: {namespace}, {languageTag}, {androidLanguageTag}, {snakeLanguageTag}, {extension}.
*
* For example, when exporting to JSON with the template {namespace}/{languageTag}.{extension}, the English translations of the home namespace will be stored in home/en.json.
*
* The {snakeLanguageTag} placeholder is the same as {languageTag} but in snake case. (e.g., en_US).
*
* The Android specific {androidLanguageTag} placeholder is the same as {languageTag} but in Android format. (e.g., en-rUS)
*/
fileStructureTemplate?: string;
/**
* Empty [path] folder before inserting pulled files.
*/
Expand Down
28 changes: 28 additions & 0 deletions test/e2e/pull.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -194,3 +194,31 @@ it('filters negatively by tag', async () => {
const content = (await import(join(TMP_FOLDER, 'drinks', 'en.json'))).default;
expect(content).toEqual({ water: 'Water' });
});

it('honors files template structure', async () => {
await mkdir(TMP_FOLDER);
const out = await run([
'pull',
'--api-key',
PROJECT_PAK_3,
'--exclude-tags',
'soda_tag',
'--file-structure-template',
'{namespace}/lang-{languageTag}.{extension}',
TMP_FOLDER,
]);

expect(out.code).toBe(0);
await expect(TMP_FOLDER).toMatchStructure(`
├── drinks/
| ├── lang-en.json
| └── lang-fr.json
├── food/
| ├── lang-en.json
| └── lang-fr.json
├── lang-en.json
└── lang-fr.json`);
const content = (await import(join(TMP_FOLDER, 'drinks', 'lang-en.json')))
.default;
expect(content).toEqual({ water: 'Water' });
});

0 comments on commit 47055d7

Please sign in to comment.