First I have notice there is naming error
temaplte
vs
template
.
Then when content of this type of nodes is lost and can be accessed when traversing result AST.
Example for which I have tested it:
@Injectable()
export class NotesFiltersEffects {
getFromLocalStorage$ = createEffect(() =>
this.actions
.pipe(
ofType(getNotesFiltersFromLocalStorage),
map(({defaultNoteFilter}: { defaultNoteFilter: NotesFiltersInterface}) => {
let existingNoteFilter: NotesFiltersInterface | null = JSON.parse(localStorage.getItem(defaultNoteFilter.id));
if (!existingNoteFilter) {
return getNotesFiltersFromLocalStorageFail({defaultNoteFilter});
} else {
if (!existingNoteFilter.searchPhrases) {
existingNoteFilter = {
...existingNoteFilter,
searchPhrases: []
};
}
return getNotesFiltersFromLocalStorageSuccess({existingNoteFilter});
}
})
)
);
constructor(private actions: Actions) {
}
}
Reproduce:
import * as fs from 'fs'
import { parse as babelParse } from '@babel/parser'
import { parse as astParse } from 'ast-parser'
function getNode(code) {
return babelParse(code, {
sourceType: 'module',
plugins: [
'classProperties',
'typescript',
'decorators-legacy'
],
});
}
const source = fs.readFileSync('test.ts', { encoding: 'utf8' });
const ast = astParse(getNode(source));
function hereIsProblem(node) {
console.log('NODE:', node);
console.log('MISING FUNCTION BODY:', node.string)
}
ast.program.body
.filter(({ nodeType }) => nodeType === 'ExportNamedDeclaration')
.map(({ declaration }) => declaration)
.filter(({ nodeType }) => nodeType === 'ClassDeclaration')
.forEach((declaration) => {
try {
declaration.body.body.filter(({ nodeType }) => nodeType === 'ClassProperty').forEach((property) => {
if (property.value.nodeType === 'CallExpression') {
if (property.value.callee.name === 'createEffect') {
const createEffectCallbackSourceAST = property.value.arguments[ 0 ].body;
if (createEffectCallbackSourceAST.nodeType !== 'CallExpression') {
throw Error('Unhandled createEffect body')
}
if (!createEffectCallbackSourceAST.callee.string.startsWith('this.actions')) {
throw Error('None standard use of createEffect callback');
}
const pipe = createEffectCallbackSourceAST.arguments;
const lastIndexOfTriggers = pipe.findIndex(({ callee: { name } }) => name === 'ofType');
const effectActionsTriggers = pipe.slice(lastIndexOfTriggers + 1);
effectActionsTriggers.forEach((trigger) => hereIsProblem(trigger));
}
} else {
throw new Error(`Unhandled property type: ${ property.value.nodeType } `)
}
});
} catch (e) {
console.error('effect module parsing error/class property', e)
}
});