Skip to content

Commit

Permalink
fix(effects): allow downleveled annotations (#98)
Browse files Browse the repository at this point in the history
Applications using Google Closure Compiler with Angular's ngc can opt into downleveling specifically marked decorators into static properties. This change enables that usage.

Closes #93
  • Loading branch information
robwormald authored and MikeRyanDev committed Jul 18, 2017
1 parent 9f4664e commit 875b326
Show file tree
Hide file tree
Showing 2 changed files with 49 additions and 0 deletions.
18 changes: 18 additions & 0 deletions modules/effects/spec/effects_metadata.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,24 @@ describe('Effect Metadata', () => {
]);
});

it('should get the effects metadata for a downleveled class instance', () => {
class Fixture {
static get propDecorators() {
return {
a: [{ type: Effect, args: [{ dispatch: false }] }],
b: [{ type: Effect, args: [] }],
};
}
}

const mock = new Fixture();

expect(getSourceMetadata(mock)).toEqual([
{ propertyName: 'a', dispatch: false },
{ propertyName: 'b', dispatch: true },
]);
});

it('should return an empty array if the class has not been decorated', () => {
class Fixture {
a: any;
Expand Down
31 changes: 31 additions & 0 deletions modules/effects/src/effects_metadata.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,35 @@ export interface EffectMetadata {
dispatch: boolean;
}

function hasStaticMetadata(sourceType: any): boolean {
return !!(sourceType as any).propDecorators;
}

function getStaticMetadata(sourceType: any): EffectMetadata[] {
const propDecorators = sourceType.propDecorators;
return Object.keys(propDecorators).reduce(
(all, key) => all.concat(getStaticMetadataEntry(propDecorators[key], key)),
[]
);
}

function getStaticMetadataEntry(metadataEntry: any, propertyName: string) {
return metadataEntry
.filter((entry: any) => entry.type === Effect)
.map((entry: any) => {
let dispatch = true;
if (entry.args.length) {
dispatch = !!entry.args[0].dispatch;
}
return { propertyName, dispatch };
});
}

function getEffectMetadataEntries(sourceProto: any): EffectMetadata[] {
if (hasStaticMetadata(sourceProto.constructor)) {
return getStaticMetadata(sourceProto.constructor);
}

if (r.hasOwnMetadata(METADATA_KEY, sourceProto)) {
return r.getOwnMetadata(METADATA_KEY, sourceProto);
}
Expand All @@ -23,6 +51,9 @@ function setEffectMetadataEntries(sourceProto: any, entries: EffectMetadata[]) {
r.defineMetadata(METADATA_KEY, entries, sourceProto);
}

/**
* @Annotation
*/
export function Effect({ dispatch } = { dispatch: true }): PropertyDecorator {
return function(target: any, propertyName: string) {
const effects: EffectMetadata[] = getEffectMetadataEntries(target);
Expand Down

0 comments on commit 875b326

Please sign in to comment.