ESLint only allow specified named imports for module - eslint

Is there a rule in ESLint that only allows you to import specified named imports from module? Let's say I have the following import statement:
import { Airline, Airport } from '#prisma/client';
And I want only allow to import specific name from that module:
import { Prisma, PrismaClient } from '#prisma/client';
I found the no-restricted-imports but it seems to only have allow all except definition pattern and I need disallow all except.

Related

Missing #Injectable annotation when importing json value

I'm currently trying to inject a json file into a service that I am building. This class is injecting the json via a #inject() tag in the constructor.
Below you can find the code that I'm using.
DiContainer.ts
import { Container, decorate, injectable } from "inversify";
import { IResponseBuilder, InjectionTypes, IUserIdGenerator, ILogger, IResponseRepository, IResponseService, IContextService, IFileWriter, IBoardSessionService, IIntent } from "./src/common/types";
import GoogleResponseBuilder from "./src/common/builders/googleResponseBuilder";
import UserIdGenerator from "./src/common/helpers/userIdGenerator";
import { DialogflowConversation } from "actions-on-google";
import WinstonLogger from "./src/common/winstonLogger";
import FileWriter from "./src/common/helpers/fileWriter";
import TextResponseRepository from "./src/repositories/textResponseRepository";
import SsmlResponseRepository from "./src/repositories/ssmlResponseRepository";
import ResponseSerivce from "./src/services/responseService";
import ContextService from "./src/services/contextService";
import { BoardService } from "./src/services/boardService";
import { BoardSessionService } from "./src/services/boardSessionService";
import WelcomeIntent from "./src/intents/new/welcomeIntent";
import uuid from "uuid/v4";
const sessionJson = require("./src/data/boardSessions.json");
const DIContainer = new Container();
DIContainer.bind<IResponseBuilder<DialogflowConversation>>(InjectionTypes.GoogleResponseBuilder).to(GoogleResponseBuilder);
DIContainer.bind<ILogger>(InjectionTypes.WinstonLogger).to(WinstonLogger);
DIContainer.bind<IFileWriter>(InjectionTypes.FileWriter).to(FileWriter);
DIContainer.bind<IUserIdGenerator>(InjectionTypes.UserIdGenerator).to(UserIdGenerator);
DIContainer.bind<IIntent>(InjectionTypes.WelcomeIntent).to(WelcomeIntent);
DIContainer.bind<IResponseRepository>(InjectionTypes.TextResponseRepository).to(TextResponseRepository);
DIContainer.bind<IResponseRepository>(InjectionTypes.SsmlResponseRepository).to(SsmlResponseRepository);
DIContainer.bind<IResponseService>(InjectionTypes.ResponseService).to(ResponseSerivce);
DIContainer.bind<IBoardSessionService>(InjectionTypes.BoardSessionService).to(BoardSessionService);
DIContainer.bind<IContextService>(InjectionTypes.ContextService).to(ContextService);
DIContainer.bind(InjectionTypes.SessionJSON).to(sessionJson);
DIContainer.bind(InjectionTypes.UUIDv4).toFunction(uuid);
export default DIContainer;
Every dependency you try to inject via #inject has to be marked with #injectable and registered through bind.
I don't really know how the decorate function works (so I don't know if you can use it to mark a function, and not a class, as injectable).
By the way, I think you can achieve what you want just registering your dependency as a dynamic value and returning the desired function, as stated here. In your case, something like this:
DIContainer.bind(InjectionTypes.UUIDv4).toDynamicValue((context: interfaces.Context) => { return uuid });
Alternatively, you could just directly import the function in your service without injecting it, or wrap the function in another service you can mark as injectable (let say, an uuid provider service).

Is there a way to abstract the import from a node module using typescript config files in the same style as the 'paths' property?

I am creating private node modules which for now might change considerably in structure which could mean splitting existing code into multiple packages.
If I have 100 files importing from a package that no longer holds the import I can do a find and replace but it becomes more difficult when classes are imported from that package...
so something like:
import { thing1, thing2} from 'my-package';
in the future may need to be:
import { thing1} from 'my-package';
import { thing2} from 'my-package2';
You can abstract imports using tsconfig like so:
"paths": {
"#shared/*": ["app/shared/*"]
}
But I cant figure out a way to do the same thing with node modules so that if there is a bigger change I only need to change 1 line. Is this possible?
Create index.ts file , import and export your modules:
import { assign, assignWith } from 'lodash';
import { addDays } from 'date-fns';
export { assign, assignWith, addDays };
and import modules from that index:
import { assign, addDays } from './index';
Check https://github.com/nrwl/nx
They can help you in using monorepo approach.
You can split your system into Applications and Libraries.

How to add imports to default export in TypeScript

I have this TypeScript node module that imports some base errors (errors1 and errors2) and define some module specific errors3:
// in errors3.ts
import errors1 from './errors1'
import errors2 from './errors2'
const errors3 = {
...
}
export default ? // <-- want to merge and export all errors here
Is there a way to combine all 3 error objects into one default export without explicit merging these objects into one manually (i.e. via Object.assign, lodash, etc?
You can use a barrel to export them all and then import them under a namespace.
https://basarat.gitbooks.io/typescript/docs/tips/barrel.html

Difference between `import from` and `import require` in TypeScript

I use node.js and I recently decided to give TypeScript a shot, But I'm kinda confused on how modules get imported. I see two different syntax that I couldn't find out what's their difference exactly:
import * as a from 'a'; // ES6 standard to import stuff
// OR ...
import a = require('a');
Are these the same thing? and if they're not, where should I use each one of them?
import * as a from 'a'; is the new "ES6 style" import syntax (available since Typescript 1.5).
Whenever possible, this syntax should now be used.
There is one caveat though. The ES6 import syntax can only import modules (as defined by ES6) or objects (classes, interfaces, vars,... ) exported as part of a module.
Some Javascript librairies will directly export a function or class, and the corresponding definition file will typically look like this:
declare module "my-class" {
class MyClass { ... }
export = MyClass
}
In this case, the "old" import syntax is the only one that can be used
import MyClass = require("my-class");
Failure to use this syntax will result in error TS2497
Check this issue for details and a possible workaround which would be, in the previous case, to add an empty module declaration to the definition file
declare module "my-class" {
class MyClass { ... }
module MyClass {} // <=
export = MyClass
}

How to use TypeScript ambient declaration interfaces in interface declared in d.ts file

I want to do a helper in .ts file like:
class ResponseHelper implements IResponseHelper {...}
and IResponseHelper is simple .d.ts file with
import * as mongoose from 'mongoose';
import * as express from 'express'
interface IResponseHelper {
toStandartResponse(response: mongoose.Promise<any>, res: express.Response): mongoose.Promise<any>;
}
as you can see params in toStandartResponse are coming from mongoose which is ambiently declared. So this if fine but if i do so I cannot us it with 'implements' like class ResponseHelper implements IResponseHelper because I got errror 'Could not find symbol IResponseHelper in external module ResponseHelper' in other words compiler cannot see d.ts file.
If i remove import statements from d.ts. file everuthing is ok but i cannot specify response types then.
Is there any way to use it all together?
I believe when you use import in makes the file a module, so you must export any members you want visible:
export interface IResponseHelper { }
Now you can import it from other files:
import {IResponseHelper} from "./IResponseHelper";
class ResponseHelper implements IResponseHelper { }

Resources