Does an eslint rule exist to prevent a class from being reassigned? - eslint

We have some older code that follows the following pattern...
class SomeClass extends Component { /* ... */ }
SomeClass = connect(
mapStateToProps,
mapDispatchToProps
)(SomeClass);
export default SomeClass;
What I would like...
export class SomeClass extends Component { /* ... */ }
export default connect(
mapStateToProps,
mapDispatchToProps
)(SomeClass);
I've tried adding the rules that I thought would cause this to error out when linting, but it is either being ignored or I have the wrong rules setup.
So what rule needs to be added to prevent this from slipping by?

The linter was hung on something. After a reboot, the no-class-assign rule was what I was looking for! Posting the answer in case someone else has the same question.

Related

How do you use a fallback exception filter in NestJs

I'm new to NestJs and I created a fallback exception filter, and now I would like to know how to use it. In other words, how do I import it in my application?
Here's my fallback exception filter:
#Catch(HttpException)
export class HttpExceptionFilter implements ExceptionFilter {
public catch(exception: HttpException, host: ArgumentsHost): any {
/* Some code here */
return response.status(statusCode).json({
status: statusCode,
datetime: new Date(),
createdBy: "HttpExceptionFilter",
errorMessage: exception.message,
})
}
}
You'd need to bind the filter globally to be the fallback. You can do this one of two ways
With a custom provider in any module. Add this to the module's providers array
{
provide: APP_FILTER,
useClass: HttpExceptionFilter
}
This will still take effect in e2e tests, as it's part of the module definition
By using useGlobalFilters in your bootstrap method like so
app.useGlobalFilters(new HttpExceptionFilter());
This will not take effect in your e2e tests, so you'll need to bind it in those too, if you want the same functionality.
Just add this in your main.ts and it should work fine:
app.useGlobalFilters(new FallbackExceptionFilter();

node/typescript: how to ensure imports with side effects are run?

I am writing a node app in typescript. I have written a class decorator #myDecorator, and the purpose of #myDecorator is such that I need to keep track of all the classes to which it's applied.
My question: how do I make sure all of those decorated classes are loaded before making use of that behavior? Some example code will help to make this more concrete:
Declaration of the decorator in file myDecorator.ts:
type ConstructorType = { new (...args: any[]): any };
// keep track of decorated classes
const registeredClasses: Map<string, ConstructorType> = new Map();
// class decorator
export function myDecorator<T extends ConstructorType>(targetConstructor: T) {
// create the modified class
const newClass = class extends targetConstructor { /* ... */ }
// register the modified class
registeredClasses.set(targetConstructor.name, newClass);
// and return it
return newClass;
}
export function doSomethingWithMyDecoratedClasses() {
//... some behavior that relies on `registeredClasses`
}
Declaration of a decorated class in file someClass.ts
import {myDecorator} from 'myDecorator.ts'
#myDecorator
class SomeClass { /* ... */ }
Making use of doSomethingWithMyDecoratedClasses in anotherFile.ts:
import { doSomethingWithMyDecoratedClasses } from 'myDecorator.ts`
//...
doSomethingWithMyDecoratedClasses()
//...
The problem is that I need to make sure that SomeClass has been added to registeredClasses before I make this call to doSomethingWithMyDecoratedClasses. And, in fact, I've written a number of such classes in my app, and I need to make sure they are all registered.
My current best understanding is that I need to call import 'someClass.ts' in anotherFile.ts (and, in fact, import all files where decorated classes are declared), so really I need to import someClass1.ts, import someClass2.ts, ...
Is that the best/only approach? Is there a recommended pattern for doing so?
Most applications have an index file that is responsible for importing the top level things. If you import doSomethingWithMyDecoratedClasses there, you'll guarantee that everything else is imported first.
An alternative would be to not call it in the root level of a module, and instead wait for an event.

Why am I getting a Reference error when I try to extend a class from an external class using JS

I have the following code...
class BasePage{
constructor(driver){
...
}
}
class Section extends BasePage{
constructor(driver, parent){
super(driver);
...
}
...
}
export {BasePage, Section}
This seems to work, however, when I try to move section into its own folder and file like this...
import {BasePage} from "../BasePage";
export class Section extends BasePage{
constructor(driver, parent){
super(driver);
}
}
I get an error...
(node:12480) UnhandledPromiseRejectionWarning: ReferenceError: BasePage is not defined
at file ... Section.mjs
This doesn't make any sense to me and if I take the extends off and try to instantiate it works fine...
export class Section{
constructor(driver, parent){
new BasePage(driver); // works fine
}
}
What is going on here? Why am I getting a BasePage not defined?
Update
Here is the whole code
You have a circular dependency.
index.mjs loads BasePage.mjs
BasePage.mjs loads Other.mjs before running export class BasePage {}
Other.mjs loads Section.mjs
Section.mjs skips BasePage.mjs because it already in-progress from step 2.
Section.mjs tries to run export class Section extends BasePage { /* ... */ }, which throws because export class BasePage {} from step 2 hasn't run yet.
You haven't shown why you need to import Other inside BasePage so it is hard to recommend changes, but essentially you'll want to not do that.

Inheritance TypeScript with exported class and modules

I'm getting crazy with inheritance using typescript. I don't know why but it cannot resolve the class I want to inherit.
lib/classes/Message.class.ts
///<reference path='./def/lib.d.ts'/>
///<reference path='./def/node.d.ts'/>
export module SharedCommunication {
export class Message{
// Stuff
}
}
lib/classes/ValidatorMessage.class.ts
///<reference path='./def/lib.d.ts'/>
///<reference path='./def/node.d.ts'/>
///<reference path='Message.class.ts'/>
export module SharedCommunication {
export class ValidatorMessage extends Message{
private _errors;
}
}
Message cannot be resolved. I tried SharedCommunication.Message too but it's the same. I reference the class so I don't understand at all what's going on. Do you have any idea?
I tried without the module (two class without be in any module) but it's the same. I need to export the class (and the module if I use it) to get them from another node_module: typescript.api, which I use to load the class and use it in node.
lib/message.js
var Message = require('./classes/Message.class.ts');
module.exports = Message.SharedCommunication.Message;
What's the trick here? Because I have source code on the same project in a different folder working with inheritance, without module or export. Thanks.
ValidatorMessage.class.ts should look like this:
///<reference path='./def/lib.d.ts'/>
///<reference path='./def/node.d.ts'/>
import message = require('./Message.class');
export module SharedCommunication {
export class ValidatorMessage extends message.SharedCommunication.Message {
private _errors;
}
}
It's usually redundant to have a single export module at the top level of a file since the file itself constitutes a namespace anyway.
Bill mentioned this in your other question, but I'd again caution on using RequireTS if you're just starting out with TypeScript - it sounds pretty unmature and is likely to introduce a lot of confusion.
Take out the export from the mododule declaration:
module SharedCommunication
{
export class ValidatorMessage extends message.SharedCommunication.Message
{
private _errors;
}
}

Black-hole error when route pointed to a class that extends plugin and uses extended class

In routes I have
Router::connect('/opauth-complete/*', array('controller' => 'app_users', 'action' => 'opauth_complete'));
If I change pointer to controller app_users with anything else and create controller everything works with no error. But I need it to work with AppUsersController.
AppUsersController looks like this
App::uses('UsersController', 'Users.Controller');
class AppUsersController extends UsersController {
public function beforeFilter() {
parent::beforeFilter();
$this->User = ClassRegistry::init('AppUser');
}
// ...
// ...
public function opauth_complete() {
die(1);
}
// ...
// ...
}
So, plugin is CakeDC Users and another plugin that goes to /example/callback after /example/auth/facebook is Opauth plugin.
Error message looks like this
The request has been black-holed
Error: The requested address '/example/opauth-complete' was not found on this server.
This is perfectly possible to make these two plugins work together; when browser points to /example/auth/facebook, it redirects to /example/auth/callback and somehow it needs opauth-complete route to link to specific method.
All works if not pointed to app_users that extends plugin, uses plugin. Does not work only with this case. How can users of these two plugins get around such situation.
I solved it by disabling Security component on Opauth action in my AppUsersController. Thing is that Opauth transfers data using POST and you should either change a method of it (ie: use Sessions, GET) or disable Security component.
For a method change use this in your bootstrap.php or core.php
Configure::write('Opauth.callback_transport', 'session'); // you can try 'get' too
To follow my approach add this to a controller where error occurs and where you place your opauth_complete method
public function beforeFilter() {
// ...
if (isset($this->Security) && $this->action == 'opauth_complete') {
$this->Security->validatePost = false;
$this->Security->csrfCheck = false;
}
// ...
}
P.S. Changing method to Sessions has its drawbacks, you can take a look at comments here at Github Opauth issue #16

Resources