Skip to content

Commit

Permalink
feat: add --namespaces support to sync
Browse files Browse the repository at this point in the history
  • Loading branch information
gu-stav committed Dec 24, 2024
1 parent 10fd107 commit 9981bc1
Show file tree
Hide file tree
Showing 4 changed files with 107 additions and 2 deletions.
39 changes: 38 additions & 1 deletion src/commands/sync/sync.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import ansi from 'ansi-colors';
import {
extractKeysOfFiles,
filterExtractionResult,
NullNamespace,
} from '../../extractor/runner.js';
import { dumpWarnings } from '../../extractor/warnings.js';
import { type PartialKey, compareKeys, printKey } from './syncUtils.js';
Expand All @@ -24,6 +25,7 @@ type Options = BaseOptions & {
backup?: string | false;
removeUnused?: boolean;
continueOnWarning?: boolean;
namespaces?: string[];
yes?: boolean;
};

Expand Down Expand Up @@ -79,6 +81,25 @@ const syncHandler = (config: Schema) =>
}

const localKeys = filterExtractionResult(rawKeys);

if (
opts.namespaces &&
Array.isArray(opts.namespaces) &&
opts.namespaces.length
) {
for (const namespace of Reflect.ownKeys(localKeys)) {
if (
typeof namespace === 'string' &&
!opts.namespaces?.includes(namespace)
) {
localKeys[namespace].clear();
// if namespaces are managed explicitly, there should be no non-namespaced keys
} else if (namespace === NullNamespace) {
localKeys[NullNamespace].clear();
}
}
}

const allKeysLoadable = await opts.client.GET(
'/v2/projects/{projectId}/all-keys',
{
Expand All @@ -88,7 +109,17 @@ const syncHandler = (config: Schema) =>

handleLoadableError(allKeysLoadable);

const remoteKeys = allKeysLoadable.data?._embedded?.keys ?? [];
let remoteKeys = allKeysLoadable.data?._embedded?.keys ?? [];

if (
opts.namespaces &&
Array.isArray(opts.namespaces) &&
opts.namespaces.length
) {
remoteKeys = remoteKeys.filter(
(key) => key.namespace && opts.namespaces?.includes(key.namespace)
);
}

const diff = compareKeys(localKeys, remoteKeys);
if (!diff.added.length && !diff.removed.length) {
Expand Down Expand Up @@ -221,6 +252,12 @@ export default (config: Schema) =>
'Set this flag to continue the sync if warnings are detected during string extraction. By default, as warnings may indicate an invalid extraction, the CLI will abort the sync.'
).default(config.sync?.continueOnWarning ?? false)
)
.addOption(
new Option(
'-n, --namespaces <namespaces...>',
'Specifies which namespaces should be synchronized.'
).default(config.push?.namespaces)
)
.addOption(
new Option(
'-Y, --yes',
Expand Down
4 changes: 4 additions & 0 deletions src/schema.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,10 @@ export interface Schema {
* Delete unused keys from the Tolgee project
*/
removeUnused?: boolean;
/*
* Specifies which namespaces should be synchronized. By default all available namespaces are synchronized.
*/
namespaces: string[];
/**
* Skip prompts and automatically say yes to them. You will not be asked for confirmation before creating/deleting keys.
*/
Expand Down
64 changes: 64 additions & 0 deletions test/e2e/sync.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,40 @@ describe('Project 2', () => {
expect(keys.data?.page?.totalElements).toBe(0);
}, 30e3);

it('does not delete keys are not managed by the current namespace configuration', async () => {
const pakWithDelete = await createPak(client, [
...DEFAULT_SCOPES,
'keys.delete',
]);

const out = await run(
[
'sync',
'--yes',
'--remove-unused',
'--api-key',
pakWithDelete,
'--patterns',
CODE_PROJECT_2_DELETED,
'--namespaces',
'bird',
],
undefined,
20e3
);

expect(out.code).toBe(0);

const keys = await client.GET('/v2/projects/{projectId}/translations', {
params: {
path: { projectId: client.getProjectId() },
query: { filterKeyName: ['bird-name', 'bird-sound'] },
},
});

expect(keys.data?.page?.totalElements).toBe(2);
}, 30e3);

it('does a proper backup', async () => {
const out = await run(
[
Expand Down Expand Up @@ -214,4 +248,34 @@ describe('Project 3', () => {
},
});
}, 30e3);

it('synchronizes the defined namespaces only', async () => {
const out = await run(
[
'sync',
'--yes',
'--api-key',
pak,
'--patterns',
CODE_PROJECT_3,
'--namespaces',
'drinks',
],
undefined,
20e3
);

expect(out.code).toBe(0);

const keys = await client.GET('/v2/projects/{projectId}/translations', {
params: {
path: { projectId: client.getProjectId() },
},
});

const stored = tolgeeDataToDict(keys.data);

expect(Object.keys(stored)).toContain('table');
expect(Object.keys(stored)).not.toContain('welcome');
}, 30e3);
});
2 changes: 1 addition & 1 deletion test/e2e/utils/data.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
export function tolgeeDataToDict(data: any) {
return Object.fromEntries(
data._embedded.keys.map((k: any) => [
(data._embedded?.keys ?? []).map((k: any) => [
k.keyName,
{
__ns: k.keyNamespace,
Expand Down

0 comments on commit 9981bc1

Please sign in to comment.