How to add custom Request type to Express? - typescript-typings

I want to add custom Request type to express.
There is way to just extend Request. But this way I have to check is auth undefined.
I cant find how to use AuthorizedRequest with app.get('/path/, ...)
How can I declare AuthorizedRequest properly?
// need to check undefined, auth can not exists so i cant remove "?"
declare module 'express-serve-static-core' {
interface Request {
auth?: {
test: string
}
}
}
// error with routing app.get(...)
declare module 'express-serve-static-core' {
interface AuthorizedRequest<P extends Params = ParamsDictionary> extends Request<P> {
auth: {
test: string
}
}
}
But I got the following error:
"- error TS2769: No overload matches this call."

Create ./typings/index.d.ts
Set tsconfig: "typeRoots": ["./typings", "./node_modules/#types"]
index.d.ts example:
type Params = {
test1: {
test2: string
},
test3: number
}
declare global {
namespace Express {
export interface Request extends Params {}
}
}
declare module 'express' {
export type ExtendableRequest = Request<any, any, any, any> &
}
export {}

Related

how can i extend the remixjs request headers object globally?

I wan to be able to exted the remixjs request headers object. i want to add one [k:string]: string
the key value pair i want to add is: k = 'Direction' val: 'onboarding'
i have the following. i have created a remix.d.ts at the root of my project inside #types folder
import "#remix-run/node";
import type { DataFunctionArgs, } from "#remix-run/node";
declare module "#remix-run/node" {
export interface LoaderArgs extends DataFunctionArgs {
headers: {
}
}
}
inside my loaderFunction i set the request type to LoaderArgs like so.
export const loader: LoaderFunction = async ({ request }: LoaderArgs) => {
console.log(request.headers)
return {}
}
yet i keep getting errors. like types are incompatible or you are not implementing all the functions in the header type.
so how can i extend the request interface globally so i can use it in every request?

How can I import a type declaration from another folder?

I want to separate my type declarations into separate folders like:
/types/index.d.ts
/types/express/index.d.ts
However, I lose the typings if I move the type definitions for express out of the root /types/index.d.ts file and import from a folder.
/types/index.ts
import './express'
/types/express/index.d.ts
// what do I export?
declare global { // is this correct?
namespace Express {
export interface Request {
user: User & {
id: string;
};
}
export interface Response {
clearAuthCookie: () => this;
}
}
}}
My ts.config:
...
"typeRoots": ["node_modules/#types", "types"]

Make class auto inter return types from declaration file

We are using a external package that doesn't have types, recreating it is too much overhaul.
We do know by trial and error the response of i.e (generateWallet) and want to make declarations for them instead of implementing each one.
What we currently have to do
Declaration file
interface ServiceClass {
generateWallet(): Wallet;
}
interface Wallet {
address: string;
privateKey: string;
}
Class
export class Service implements ServiceClass {
constructor() {}
generateWallet(): Wallet {
return externalPackage.generateWallet() // returns any;
}
// We dont want to do this for about hundred different functions
}
Wanted Output
import externalPackage from 'external-package';
const externalPackage.generateWallet(); // Shows return type as (Wallet)
You can add your own type description file for a package that does not have its own types.
Create package_name.d.ts file with a desired types like this:
/* eslint-disable camelcase */
declare module 'external-package' {
export interface Wallet {
address: string;
privateKey: string;
}
interface ExternalPackage {
generateWallet(): Wallet;
}
export default ExternalPackage;
}
Place this file into #types folder and add this folder to tsconfig.json:
{
"compilerOptions": {
... // other options
"typeRoots": [
"#types",
"node_modules/#types"
]
...
}

Is there any way to implement validation for file upload using class-validator?

I am using class-validator for validate data, I need to implement validation for file upload. Ex: file is not empty (It would be great if also implement file must be image).
I try in following way:
export class FileModel extends Model {
#IsNotEmpty()
file: File
constructor(body: any) {
super();
const {
file,
} = body;
this.file = file;
}
}
But it's always return "file should not be empty" even I select file. is there any way to implement validation for file upload.
Thanks in advance :)
You can create a custom class-validator custom validation decorator:
interface IsFileOptions {
mime: ('image/jpg' | 'image/png' | 'image/jpeg')[];
}
export function IsFile(options: IsFileOptions, validationOptions?: ValidationOptions) {
return function (object: Object, propertyName: string) {
return registerDecorator({
name: 'isFile',
target: object.constructor,
propertyName: propertyName,
constraints: [],
options: validationOptions,
validator: {
validate(value: any, args: ValidationArguments) {
if (value?.mimetype && (options?.mime ?? []).includes(value?.mimetype)) {
return true;
}
return false;
},
}
});
}
}
The preceding custom decorator just checks the mime-type of the file. You can write a more sophisticated implementation and also add file size check and etc.
You can use the custom-decorator like this in your DTO classes:
class UploadImageDto{
#IsFile({ mime: ['image/jpg', 'image/png']})
file: any;
}
Furthermore if you are using class-validator in NestJs you can use nestjs-form-data library which contains #HasMimeType, #IsFile, #MaxFileSize and more file validation decorators out of the box.

RobinBuschmann/soap-typescript/soap-decorators Example

Can someone please give me a detailed example of RobinBuschmann/soap-typescript/soap-decorators Example. I am looking to create a wsdl xml for node-soap. The example given on github of RobinBuschmann/soap-typescript does not seem to work as is. I put the first three code snippets in a file called createWsdl.js and ran it with "node createWsdl.js" and I get an error. I suspect I am not doing the right thing. Can someone please help me or give me a detailed example that actually works.
I used node-soap and soap-decorators to communicate with Quickbooks. The following is from my app.ts file:
this.express.use(
'/soap',
soap(this.quickbooksController, {
overrideRootElement: {
namespace: '',
xmlnsAttributes: [
{
name: 'xmlns',
value: 'http://developer.intuit.com/'
}
]
}
})
);
The controller is annotated like so:
import { SoapOperation, SoapService } from 'soap-decorators';
import { AuthenticateRequest, AuthenticateResponse } from './model/authenticate.interface';
#SoapService({
portName: 'QBWebConnectorSvcSoap',
serviceName: 'QBWebConnectorSvc',
targetNamespace: 'http://developer.intuit.com/'
})
export class QuickbooksController {
#SoapOperation(AuthenticateResponse)
authenticate(data: AuthenticateRequest, res: (res: AuthenticateResponse) => any): void {
res({ authenticateResult: { string: ['', 'NVU'] } });
}
}
My request and response objects are decorated as XSD types:
import { XSDComplexType, XSDElement } from 'soap-decorators';
#XSDComplexType
export class AuthenticateRequest {
#XSDElement
strUserName: string;
#XSDElement
strPassword: string;
}
#XSDComplexType
class AuthenticateResult {
#XSDElement({ type: 'string' })
string: string[];
}
#XSDComplexType({ name: 'authenticateResponse' })
export class AuthenticateResponse {
#XSDElement
authenticateResult: AuthenticateResult;
}

Resources