Skip to content

Commit

Permalink
fix(@angular-devkit/schematics): update Rule type to support return…
Browse files Browse the repository at this point in the history
…ing a `Promise` of `Tree`

The `Rule` type has been updated to align with its intended functionality, allowing it to return a `Promise<Tree>`. Previously, this behavior was supported but not properly typed.

Closes #22783

(cherry picked from commit 4f80308)
  • Loading branch information
alan-agius4 committed Jan 14, 2025
1 parent 8e110bb commit 2f55209
Show file tree
Hide file tree
Showing 3 changed files with 25 additions and 2 deletions.
2 changes: 1 addition & 1 deletion goldens/public-api/angular_devkit/schematics/index.api.md
Original file line number Diff line number Diff line change
Expand Up @@ -722,7 +722,7 @@ interface RequiredWorkflowExecutionContext {
}

// @public (undocumented)
export type Rule = (tree: Tree_2, context: SchematicContext) => Tree_2 | Observable<Tree_2> | Rule | Promise<void | Rule> | void;
export type Rule = (tree: Tree_2, context: SchematicContext) => Tree_2 | Observable<Tree_2> | Rule | Promise<void | Tree_2 | Rule> | void;

// @public
export type RuleFactory<T extends object> = (options: T) => Rule;
Expand Down
2 changes: 1 addition & 1 deletion packages/angular_devkit/schematics/src/engine/interface.ts
Original file line number Diff line number Diff line change
Expand Up @@ -236,4 +236,4 @@ export type Source = (context: SchematicContext) => Tree | Observable<Tree>;
export type Rule = (
tree: Tree,
context: SchematicContext,
) => Tree | Observable<Tree> | Rule | Promise<void | Rule> | void;
) => Tree | Observable<Tree> | Rule | Promise<void | Tree | Rule> | void;
23 changes: 23 additions & 0 deletions packages/angular_devkit/schematics/src/rules/base_spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,29 @@ describe('chain', () => {
.then(done, done.fail);
});

it('works with async rules', (done) => {
const rulesCalled: Tree[] = [];

const tree0 = empty();
const tree1 = empty();
const tree2 = empty();
const tree3 = empty();

const rule0: Rule = async (tree: Tree) => ((rulesCalled[0] = tree), tree1);
const rule1: Rule = async (tree: Tree) => ((rulesCalled[1] = tree), tree2);
const rule2: Rule = async (tree: Tree) => ((rulesCalled[2] = tree), tree3);

lastValueFrom(callRule(chain([rule0, rule1, rule2]), tree0, context))
.then((result) => {
expect(result).not.toBe(tree0);
expect(rulesCalled[0]).toBe(tree0);
expect(rulesCalled[1]).toBe(tree1);
expect(rulesCalled[2]).toBe(tree2);
expect(result).toBe(tree3);
})
.then(done, done.fail);
});

it('works with a sync generator of rules', async () => {
const rulesCalled: Tree[] = [];

Expand Down

0 comments on commit 2f55209

Please sign in to comment.