Skip to content

Commit

Permalink
feat: 🎸 support params in pipe and directive
Browse files Browse the repository at this point in the history
✅ Closes: #153
  • Loading branch information
shaharkazaz committed Aug 6, 2024
1 parent d867d5c commit 020e6bc
Show file tree
Hide file tree
Showing 11 changed files with 122 additions and 32 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ import {
defaultValue,
generateKeys,
mockResolveProjectBasePath,
resolveValueWithParams,
paramsTestConfig,
} from '../../../spec-utils';
import { Config } from '../../../../src/types';

Expand Down Expand Up @@ -36,5 +38,15 @@ export function testDirectiveExtraction(fileFormat: Config['fileFormat']) {
buildTranslationFiles(config);
assertTranslation({ type, expected, fileFormat });
});

it('should extract params', () => {
const expected = {
...generateKeys({ end: 3, withParams: true }),
...generateKeys({ start: 4, end: 5 }),
'admin.key': resolveValueWithParams(['a', 'b.c', 'b.d.e', 'b.f']),
};
buildTranslationFiles(paramsTestConfig(config));
assertTranslation({ type, expected, fileFormat });
});
});
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
<div class="bot-setup-container width-100 d-flex">
<form class="da-form d-flex-column width-100" [formGroup]="bot" novalidate>
<!-- Bot name -->
<div class="bot-setup-header allow-full-line d-flex">
<da-editable-input-text [value]="botSetupStore.bot.controls.name.value" [entity]="'bot'"
(onChange)="onNameChange($event)"></da-editable-input-text>
</div>

<edge-wizard-step transloco="admin.key" [translocoParams]="{a: '123', b: {c: 123, d: {e: ''}, f:''}}"
[validate]="simulateRestore" [useFormCtrlValidation]="profile">
<ui-view [transloco]="'1'" [translocoParams]="{'1': '123'}"></ui-view>

<!-- Footer error message -->
<div transloco="5" translocoParams="dontTake2" class="footer-error-message d-flex" *ngIf="errorCounter > 0" [transloco]="dontTake">
asasd
</div>
<div transloco="4" [translocoParams]="dontTake" class="allow-full-line footer-buttons d-flex align-end-center">
<div class="setup-buttons d-flex">
<button transloco="2" [translocoParams]="{'2': asd}" class="da-btn secondary save-button" *ngIf="isEditState && !isDuplicate as bla" (click)="onSubmit(false)">
</button>
<button class="da-btn primary save-run-button" (click)="onSubmit(true)" transloco="{{'3'}}" [translocoParams]="{'3': 123}">

</button>
</div>
</div>
</edge-wizard-step>
</form>
</div>
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import {
generateKeys,
mockResolveProjectBasePath,
resolveValueWithParams,
setParamsInput,
paramsTestConfig,
} from '../../../spec-utils';
import { Config } from '../../../../src/types';

Expand Down Expand Up @@ -56,9 +56,9 @@ export function testPipeExtraction(fileFormat: Config['fileFormat']) {
it('should extract params', () => {
const expected = {
...generateKeys({ end: 2, withParams: true }),
'admin.1': resolveValueWithParams(['someKey']),
'admin.1': resolveValueWithParams(['a', 'b.c']),
};
buildTranslationFiles(setParamsInput(config));
buildTranslationFiles(paramsTestConfig(config));
assertTranslation({ type, expected, fileFormat });
});
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,6 @@
</div>

<a [title]="'admin.1' | lowercase
| transloco:{someKey: 'asd'}"
| transloco:{a: 'asd', b: {c: 123}}"
[routerLink]="'admin' | lowercase">
</a>
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,9 @@ import {
TranslationTestCase,
} from '../../build-translation-utils';
import {
buildKeysFromParams,
mockResolveProjectBasePath,
setParamsInput,
generateKeys,
mockResolveProjectBasePath,
paramsTestConfig,
resolveValueWithParams,
} from '../../../spec-utils';
import { Config } from '../../../../src/types';
Expand Down Expand Up @@ -43,7 +42,7 @@ export function testPureFunctionExtraction(fileFormat: Config['fileFormat']) {
4: resolveValueWithParams(['foo', 'a', 'b.c']),
};

buildTranslationFiles(setParamsInput(config));
buildTranslationFiles(paramsTestConfig(config));
assertTranslation({ type, expected, fileFormat });
});
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import {
generateKeys,
mockResolveProjectBasePath,
buildKeysFromParams,
setParamsInput,
paramsTestConfig,
} from '../../../spec-utils';
import { Config } from '../../../../src/types';

Expand Down Expand Up @@ -101,7 +101,7 @@ export function testServiceExtraction(fileFormat: Config['fileFormat']) {
]),
};

buildTranslationFiles(setParamsInput(config));
buildTranslationFiles(paramsTestConfig(config));
assertTranslation({ type, expected, fileFormat });
});
});
Expand Down
2 changes: 1 addition & 1 deletion __tests__/spec-utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ export function buildConfig({ config = {}, sourceRoot }: BuildConfigOptions) {
} as Config;
}

export function setParamsInput(config: Config) {
export function paramsTestConfig(config: Config) {
return {
...config,
input: [nodePath.resolve(config.input[0], '../', 'with-params')],
Expand Down
69 changes: 49 additions & 20 deletions src/keys-builder/template/directive.extractor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import {
TmplAstTextAttribute,
} from '@angular/compiler';

import { ExtractorConfig } from '../../types';
import { ExtractorConfig, OrArray } from '../../types';
import { addKey } from '../add-key';
import { resolveAliasAndKey } from '../utils/resolvers.utils';

Expand All @@ -18,12 +18,15 @@ import {
isElement,
isInterpolation,
isLiteralExpression,
isLiteralMap,
isSupportedNode,
isTemplate,
isTextAttribute,
parseTemplate,
resolveBlockChildNodes,
resolveKeysFromLiteralMap,
} from './utils';
import { coerceArray } from '../../utils/collection.utils';

export function directiveExtractor(config: TemplateExtractorConfig) {
const ast = parseTemplate(config);
Expand All @@ -41,7 +44,18 @@ function traverse(nodes: TmplAstNode[], config: ExtractorConfig) {
continue;
}

const astTrees = [...node.inputs, ...node.attributes]
const params = node.inputs
.filter(isTranslocoParams)
.map((ast) => {
const value = ast.value;
if (value instanceof ASTWithSource && isLiteralMap(value.ast)) {
return resolveKeysFromLiteralMap(value.ast);
}

return [];
})
.flat();
const keys = [...node.inputs, ...node.attributes]
.filter(isTranslocoDirective)
.map((ast) => {
let value = ast.value;
Expand All @@ -51,9 +65,11 @@ function traverse(nodes: TmplAstNode[], config: ExtractorConfig) {

return isInterpolation(value) ? (value.expressions as AST[]) : value;
})
.flat()
.map(resolveKey)
.flat();
addKeys(keys, params, config);
traverse(node.children, config);
addKeysFromAst(astTrees, config);
}
}

Expand All @@ -65,24 +81,37 @@ function isTranslocoDirective(
);
}

function addKeysFromAst(
expressions: Array<string | AST>,
function isTranslocoParams(ast: unknown): ast is TmplAstBoundAttribute {
return isBoundAttribute(ast) && ast.name === 'translocoParams';
}

function resolveKey(ast: OrArray<AST | string>): string[] {
return coerceArray(ast)
.map((expression) => {
if (typeof expression === 'string') {
return expression;
} else if (isConditionalExpression(expression)) {
return resolveKey([expression.trueExp, expression.falseExp]);
} else if (isLiteralExpression(expression)) {
return expression.value;
}
})
.filter(Boolean)
.flat();
}

function addKeys(
keys: string[],
params: string[],
config: ExtractorConfig,
): void {
for (const exp of expressions) {
const isString = typeof exp === 'string';
if (isConditionalExpression(exp)) {
addKeysFromAst([exp.trueExp, exp.falseExp], config);
} else if (isLiteralExpression(exp) || isString) {
const [key, scopeAlias] = resolveAliasAndKey(
isString ? exp : exp.value,
config.scopes,
);
addKey({
...config,
keyWithoutScope: key,
scopeAlias,
});
}
for (const rawKey of keys) {
const [key, scopeAlias] = resolveAliasAndKey(rawKey, config.scopes);
addKey({
...config,
keyWithoutScope: key,
scopeAlias,
params,
});
}
}
3 changes: 2 additions & 1 deletion src/keys-builder/template/pipe.extractor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ import {
parseTemplate,
isBlockNode,
resolveBlockChildNodes,
resolveKeysFromLiteralMap,
} from './utils';
import { notNil } from '../../utils/validators.utils';

Expand Down Expand Up @@ -136,7 +137,7 @@ function addKeysFromAst(keys: KeyWithParam[], config: ExtractorConfig): void {
for (const { keyNode, paramsNode } of keys) {
const [key, scopeAlias] = resolveAliasAndKey(keyNode.value, config.scopes);
const params = isLiteralMap(paramsNode)
? paramsNode.keys.map((k) => k.key)
? resolveKeysFromLiteralMap(paramsNode)
: [];
addKey({
...config,
Expand Down
20 changes: 20 additions & 0 deletions src/keys-builder/template/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -191,3 +191,23 @@ export function resolveBlockChildNodes(node: BlockNode): TmplAstNode[] {

return node.children;
}

export function resolveKeysFromLiteralMap(node: LiteralMap): string[] {
let keys: string[] = [];

for (let i = 0; i < node.values.length; i++) {
const { key } = node.keys[i];
const value = node.values[i];

if (isLiteralMap(value)) {
const prefixedKeys = resolveKeysFromLiteralMap(value).map(
(k) => `${key}.${k}`,
);
keys = keys.concat(prefixedKeys);
} else {
keys.push(key);
}
}

return keys;
}
1 change: 1 addition & 0 deletions src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -65,3 +65,4 @@ export type BaseParams = {
};

export type Translation = Record<string, any>;
export type OrArray<T> = T | T[];

0 comments on commit 020e6bc

Please sign in to comment.