tst-reflect
tst-reflect copied to clipboard
TypeError: Cannot read properties of undefined (reading 'declarations') (monorepo Nx)
The project is a monorepo created with Nx. I'm using ts-patch (ttypescript) to allow transformers globally on the project Is this error related to the local private pkg?
Stack
ERROR in ./apps/api/src/app.module.ts
Module build failed (from ./node_modules/ts-loader/index.js):
TypeError: Cannot read properties of undefined (reading 'declarations')
at processGenericCallExpression (/home/zzzzz/IdeaProjects/xxxx/node_modules/tst-reflect-transformer/dist/processGenericCallExpression.js:12:25)
at mainVisitor (/home/zzzzz/IdeaProjects/xxxx/node_modules/tst-reflect-transformer/dist/visitors/mainVisitor.js:43:97)
at Context._visitor (/home/zzzzz/IdeaProjects/xxxx/node_modules/tst-reflect-transformer/dist/contexts/Context.js:9:35)
at visitNodes (/home/zzzzz/IdeaProjects/xxxx/node_modules/typescript/lib/typescript.js:87060:48)
at Object.visitEachChild (/home/zzzzz/IdeaProjects/xxxx/node_modules/typescript/lib/typescript.js:87363:67)
at mainVisitor (/home/zzzzz/IdeaProjects/xxxx/node_modules/tst-reflect-transformer/dist/visitors/mainVisitor.js:85:15)
at Context._visitor (/home/zzzzz/IdeaProjects/xxxx/node_modules/tst-reflect-transformer/dist/contexts/Context.js:9:35)
at visitNode (/home/zzzzz/IdeaProjects/xxxx/node_modules/typescript/lib/typescript.js:87007:23)
at Object.visitEachChild (/home/zzzzz/IdeaProjects/xxxx/node_modules/typescript/lib/typescript.js:87634:115)
at mainVisitor (/home/zzzzz/IdeaProjects/xxxx/node_modules/tst-reflect-transformer/dist/visitors/mainVisitor.js:85:15)
Affected line
processGenericCallExpression.js
if (!fncType.symbol.declarations) {
throw new Error("Unable to resolve declarations of symbol.");
}
Affected file
import {Module} from '@nestjs/common';
import {AppController} from './app.controller';
import {AppService} from './app.service';
import {GraphQLModule} from '@nestjs/graphql';
import {ApolloDriver, ApolloDriverConfig} from '@nestjs/apollo';
import {join} from 'path'
import {TasksModule} from './task/task.module';
import {MongooseModule} from '@nestjs/mongoose';
import {RequestContextCreatorInterceptor, RequestContextModule} from "@privatepkt/nestjs-request-context";
import {APP_INTERCEPTOR} from "@nestjs/core";
@Module({
imports: [
RequestContextModule, // thread-local / asyncLocalStorage for the nest request
TasksModule,
GraphQLModule.forRoot<ApolloDriverConfig>({
driver: ApolloDriver,
autoSchemaFile: join(process.cwd(), 'apps/api/schema.gql'),
sortSchema: true,
definitions: {
path: join(process.cwd(), 'apps/api/schema.ts'),
outputAs: 'interface',
},
// TODO disable for prod
introspection: true,
debug: true,
playground: true,
}),
// TODO use env var
MongooseModule.forRoot('mongodb://localhost/db', {
user: "xxx",
pass: "xxx"
})
],
controllers: [AppController],
providers: [AppService,
{
provide: APP_INTERCEPTOR,
useClass: RequestContextCreatorInterceptor, // thread-local / asyncLocalStorage for the nest request, analyze request and fill data (graphql, http ect)
}],
})
export class AppModule {
}
tsconfig.base,json
"paths": {
"@privatepkt/graphql-utils": [
"libs/graphql-utils/src/index.ts"
],
"@privatepkt/nestjs-request-context": [
"libs/nestjs-request-context/src/index.ts"
]
},
,
"plugins": [
{
"transform": "tst-reflect-transformer"
}
]
If you have suggestion on how to fix this let me know :).
Hello @CristianPi ,
There must be some call of generic function/method/decorator which has no declararation (no .ts file nor .d.ts file).
I made some changes, I hope it will help. Try to install the new version [email protected] and let me know.
I did some quick test with Angular in the past, but I never test it with complex project. There can be some other issues.
PS: I work on a new major version, containing big changes... Angular support should be included. I prepared docs for Angular https://github.com/Hookyns/tst-reflect/blob/v0.10/docs/usage/angular.md There is a DEMO at the end of the guide. But you've already made it run, so nothing interesting for you.
Hi @Hookyns Currently i'm using Nestjs (node framework) and React as fronted, i know, Nest looks like angular but fortunately is not :)
I checked the change but the problem persist as symbol is missing on the fncType
fncType.symbol -> undefined
I patched the lib locally with
if (fncType.symbol == null || !fncType.symbol.declarations) {
if (context.config.debugMode) {
context.log.debug("Unable to resolve declaration of the generic type's symbol signature.\r\n" + (0, getNodeLocationText_1.getNodeLocationText)(node));
}
return undefined;
}
Also i don't see the emitted metadata :eyes: only
const _ßr = __webpack_require__("tst-reflect");
without any
_ßr.Type.store.set(...)
Don't know if the problem is related as this is a little bit tricky for me to know/check.
Probably the transformer is not working on the project, it could explain the fncType.symbol -> undefined
Example code
console.log("TasksService",getType<TasksService>())
[ERR] tst-reflect: You call getType() method directly. You have probably wrong configuration, because tst-reflect-transformer package should replace this call by the Type instance.
If you have right configuration it may be BUG so try to create an issue.
If it is not an issue and you don't want to see this debug message, create field 'tst-reflect-disable' in global object (window | global | globalThis) eg. `window['tst-reflect-disable'] = true;`
TasksService TypeActivator {
_name: 'unknown',
_fullName: 'unknown',
_kind: 2,
_constructors: [],
_properties: [],
_methods: [],
_decorators: [],
_typeParameters: [],
_ctor: [Function: ctor],
_ctorDesc: ConstructorImportActivator {},
_interface: undefined,
_isUnion: false,
_isIntersection: false,
_types: [],
_literalValue: undefined,
_typeArgs: [],
_conditionalType: undefined,
_indexedAccessType: undefined,
_genericTypeConstraint: undefined,
_genericTypeDefault: undefined,
_baseType: undefined
}
🤦 fixing from the bed... I missed Nest imports and the fact that the symbol is undefined not declaration... the error message is super clear. 🤦 I'll fix that tomorrow.
Do you have some kind of hot reloads? I think there is a bug with generated identifiers, webpack (or some loader) find identifiers unrelated while reloading and omit the metadata. Does full build work? Does just tsc work?
Do you use typelib or inline mode? https://github.com/Hookyns/tst-reflect/wiki/Configuration
Similar project: https://github.com/knowankit/fullstack-monorepo-boilerplate
Yes, it's using a hot reload but i have the same problem building for production/dev.
I tried changing the config (typelib and/or inline) inside the tsconfig.base.json but it's ignored. (a problem with reading the configs?) For testing i edited
function transform(program) {
TransformerContext_1.default.instance.init(program);
return (context) => {
return (node) => ts.visitNode(node, getVisitor(context, program));
};
}
and i enabled debug/changed flags but nothing.
testing with tsc:
tsc -p tsconfig.app.json (run inside apps/api)
and i get a crash
[WRN] tst-reflect-transformer Unexpected decorator argument. Only constant values are allowed.
At () => ID (/home/cristian/IdeaProjects/xxx/apps/api/src/task/task.schema.ts:16:9)
[WRN] tst-reflect-transformer Unexpected decorator argument. Only constant values are allowed.
At {required: true} (/home/cristian/IdeaProjects/xxx/apps/api/src/task/task.schema.ts:19:8)
[WRN] tst-reflect-transformer Unexpected decorator argument. Only constant values are allowed.
At {type:Date} (/home/cristian/IdeaProjects/xxx/apps/api/src/task/task.schema.ts:31:8)
[WRN] tst-reflect-transformer Unexpected decorator argument. Only constant values are allowed.
At {type:Date} (/home/cristian/IdeaProjects/xxx/apps/api/src/task/task.schema.ts:35:8)
[WRN] tst-reflect-transformer Unexpected decorator argument. Only constant values are allowed.
At {nullable: true} (/home/cristian/IdeaProjects/xxx/apps/api/src/task/task.schema.ts:36:9)
/home/cristian/IdeaProjects/xxx/node_modules/typescript/lib/tsc.js:115715
throw e;
^
Error: Debug Failure. False expression: Expected fileName to be present in command line
at Object.getOutputFileNames (/home/cristian/IdeaProjects/xxx/node_modules/typescript/lib/typescript.js:108442:18)
at getOutPathForSourceFile (/home/cristian/IdeaProjects/xxx/node_modules/tst-reflect-transformer/dist/helpers.js:266:19)
at getExportOfConstructor (/home/cristian/IdeaProjects/xxx/node_modules/tst-reflect-transformer/dist/getExports.js:28:56)
at getTypeDescription (/home/cristian/IdeaProjects/xxx/node_modules/tst-reflect-transformer/dist/getTypeDescription.js:242:79)
at getTypeCall (/home/cristian/IdeaProjects/xxx/node_modules/tst-reflect-transformer/dist/getTypeCall.js:21:71)
at /home/cristian/IdeaProjects/xxx/node_modules/tst-reflect-transformer/dist/getProperties.js:19:50
at Array.map (<anonymous>)
at getProperties (/home/cristian/IdeaProjects/xxx/node_modules/tst-reflect-transformer/dist/getProperties.js:14:14)
at getTypeDescription (/home/cristian/IdeaProjects/xxx/node_modules/tst-reflect-transformer/dist/getTypeDescription.js:235:50)
at getTypeCall (/home/cristian/IdeaProjects/xxx/node_modules/tst-reflect-transformer/dist/getTypeCall.js:21:71)
but looking at the .js files i see the metadatas
_ßr.Type.store.set(1308, { k: 4, n: "Date", args: [] });
_ßr.Type.store.set(92, { k: 1, n: "Task", fn: "xxx/apps/api/src/task/task.schema.ts:Task#92", props: [{ n: "_id", t: _ßr.Type.store.wrap({ n: "number", k: 2, ctor: function () {
return Promise.resolve(Number);
} }), d: [{ n: "Prop", fn: "@nestjs/mongoose/dist/decorators/prop.decorator.d.ts:Prop#98" }, { n: "Field", fn: "@nestjs/graphql/dist/decorators/field.decorator.d.ts:Field#99", args: [null] }], am: 2, acs: 0, ro: false, o: false }, { n: "title", t: _ßr.Type.store.wrap({ n: "string", k: 2, ctor: function () {
return Promise.resolve(String);
} }), d: [{ n: "Prop", fn: "@nestjs/mongoose/dist/decorators/prop.decorator.d.ts:Prop#98", args: [null] }, { n: "Field", fn: "@nestjs/graphql/dist/decorators/field.decorator.d.ts:Field#99" }], am: 2, acs: 0, ro: false, o: false }, { n: "description", t: _ßr.Type.store.wrap({ n: "string", k: 2, ctor: function () {
return Promise.resolve(String);
} }), d: [{ n: "Prop", fn: "@nestjs/mongoose/dist/decorators/prop.decorator.d.ts:Prop#98" }, { n: "Field", fn: "@nestjs/graphql/dist/decorators/field.decorator.d.ts:Field#99" }], am: 2, acs: 0, ro: false, o: false }, { n: "status", t: _ßr.Type.store.wrap({ n: "string", k: 2, ctor: function () {
return Promise.resolve(String);
} }), d: [{ n: "Prop", fn: "@nestjs/mongoose/dist/decorators/prop.decorator.d.ts:Prop#98" }, { n: "Field", fn: "@nestjs/graphql/dist/decorators/field.decorator.d.ts:Field#99" }], am: 2, acs: 0, ro: false, o: false }, { n: "startDate", t: _ßr.Type.store.get(1308), d: [{ n: "Prop", fn: "@nestjs/mongoose/dist/decorators/prop.decorator.d.ts:Prop#98", args: [null] }, { n: "Field", fn: "@nestjs/graphql/dist/decorators/field.decorator.d.ts:Field#99" }], am: 2, acs: 0, ro: false, o: false }, { n: "endDate", t: _ßr.Type.store.get(1308), d: [{ n: "Prop", fn: "@nestjs/mongoose/dist/decorators/prop.decorator.d.ts:Prop#98", args: [null] }, { n: "Field", fn: "@nestjs/graphql/dist/decorators/field.decorator.d.ts:Field#99", args: [null] }], am: 2, acs: 0, ro: false, o: false }], decs: [{ n: "reflect", fn: "tst-reflect/dist/reflect.d.ts:reflect#94" }, { n: "Schema", fn: "@nestjs/mongoose/dist/decorators/schema.decorator.d.ts:Schema#95" }, { n: "ObjectType", fn: "@nestjs/graphql/dist/decorators/object-type.decorator.d.ts:ObjectType#96" }], ctors: [{ params: [] }], ctor: function () {
return Promise.resolve(require("./task.schema").Task);
} });
my package.json
"ts-patch": "2.0.1",
"tst-reflect-transformer": "0.9.6",
"typescript": "4.6.4",
(tspach needs ts-patch install -s)
Just for reference I tried typescript-rtti and it's working (but breaks nestjs lol).
Tomorrow i'm going to create a fork of https://github.com/knowankit/fullstack-monorepo-boilerplate and configure tst-reflect for testing purpose
Error with sourcefile when building using tsc fixed by PR #38 Merged in main, not published yet.
Tomorrow i'm going to create a fork of https://github.com/knowankit/fullstack-monorepo-boilerplate and configure tst-reflect for testing purpose
It would be nice. I'll try it this weekend.
@Hookyns Sorry, life got the best of me.
Here the full configured repo: (npm i && npm run dev) https://github.com/CristianPi/fullstack-monorepo-boilerplate
i changed the webpack config to disable transpileOnly (the root cause of all!)
there's just a little problem: ReferenceError: _ßr is not defined
culprit: Missing import const _ßr = require("tst-reflect"); on every file
/***/ "./apps/api/src/task/task.service.ts":
/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.TasksService = void 0;
const tslib_1 = __webpack_require__("tslib");
const mongoose_1 = __webpack_require__("mongoose");
const common_1 = __webpack_require__("@nestjs/common");
const mongoose_2 = __webpack_require__("@nestjs/mongoose");
const task_schema_1 = __webpack_require__("./apps/api/src/task/task.schema.ts");
const tst_reflect_1 = __webpack_require__("tst-reflect");
//NOT DEFINED (_ßr)
_ßr.Type.store.set(109, { k: 1, n: "TasksService", fn: "complicated-todo/apps/api/src/task/task.service.ts:TasksService#109", props: [{ n: "tasksModel", t: _ßr.Type.store.get(126), d: [{ n: "InjectModel", fn: "@nestjs/mongoose/dist/common/mongoose.decorators.d.ts:__type#4103", args: [null] }], am: 0, acs: 0, ro: false, o: false }], meths: [{ n: "getTasks", params: [], rt: _ßr.Type.store.get(26145), tp: [], o: false, am: 2 }, { n: "getTask", params: [{ n: "id", t: _ßr.Type.store.get(101), o: false }], rt: _ßr.Type.store.get(26626), tp: [], o: false, am: 2 }, { n: "createTask", params: [{ n: "task", t: _ßr.Type.store.get(98), o: false }], rt: _ßr.Type.store.get(26626), tp: [], o: false, am: 2 }, { n: "updateTask", params: [{ n: "id", t: _ßr.Type.store.get(101), o: false }, { n: "update", t: _ßr.Type.store.get(103), o: false }], rt: _ßr.Type.store.get(26626), tp: [], o: false, am: 2 }, { n: "deleteTask", params: [{ n: "taskId", t: _ßr.Type.store.get(101), o: false }], rt: _ßr.Type.store.get(26626), tp: [], o: false, am: 2 }], decs: [{ n: "reflect", fn: "tst-reflect/dist/reflect.d.ts:reflect#111" }, { n: "Injectable", fn: "@nestjs/common/decorators/core/injectable.decorator.d.ts:Injectable#85" }], ctors: [{ params: [{ n: "tasksModel", t: _ßr.Type.store.get(126), o: false }] }], ctor: function () {
return Promise.resolve((__webpack_require__("./apps/api/src/task/task.service.ts").TasksService));
} });
let TasksService = class TasksService {
constructor(tasksModel) {
this.tasksModel = tasksModel;
}
getTasks() {
return (0, tslib_1.__awaiter)(this, void 0, void 0, function* () {
return this.tasksModel.find();
});
}
getTask(id) {
return (0, tslib_1.__awaiter)(this, void 0, void 0, function* () {
return this.tasksModel.findOne({ _id: id });
});
}
createTask(task) {
return (0, tslib_1.__awaiter)(this, void 0, void 0, function* () {
return this.tasksModel.create(task);
});
}
updateTask(id, update) {
return (0, tslib_1.__awaiter)(this, void 0, void 0, function* () {
return this.tasksModel.findOneAndUpdate({ _id: id }, update, {
new: true
});
});
}
deleteTask(taskId) {
return (0, tslib_1.__awaiter)(this, void 0, void 0, function* () {
return this.tasksModel.findOneAndRemove({ _id: taskId });
});
}
};
On my local project i fixed this, temporarily, declaring global._ßr = require("tst-reflect");
Fixed in v1. Not in the current version.