RobinBuschmann/soap-typescript/soap-decorators Example - node.js

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;
}

Related

How to dynamically register queues to nest js bull queue

When you know the list of queues to be registered, you can add them using registerQueue() in nestjs module instantiation but how to dynamically register a queue, for eg. if I have a multi tenant architecture, when a new tenant is created I want to register a new queue dynamically, is it possible to do with nest js bull queue ?
I don't know if you can do that with the Nest package. Check this GitHub issue response from the Nestjs's creator.
You can, however, use the vanilla Bull package.
For example, imagine that you have a Controller like this:
#Controller()
export class AppController {
constructor(
private queuesManager: QueuesManagerService
) {}
#Post(['generate-queue'])
generateQueue(
#Body() generateQueueDto: GenerateQueueDto
): Promise<GenerateQueueResponse> {
return this.queuesManager.generateQueue(generateQueueDto.name);
}
#Get(['get-all-jobs'])
getAllJobsFromQueue(
#Query() queryParameters: GetAllJobsEndpointQueryParameters
): Promise<Bull.Job[]> {
return this.queuesManager.getAllJobsFromQueue(queryParameters.name);
}
}
And the QueuesManagerService looks like this:
#Injectable()
export class QueuesManagerService {
async generateQueue(name: string): Promise<GenerateQueueResponse> {
const queue: Bull.Queue = new Bull(name);
await queue.add({ test: 'test' });
return {
status: 200,
message: `Queue with name ${name} generated successfully!`,
};
}
async getAllJobsFromQueue(name: string): Promise<Bull.Job[]> {
const jobStatuses: Bull.JobStatus[] = [
'waiting',
'delayed',
'active',
'completed',
'failed',
];
const queue: Bull.Queue = new Bull(name);
const jobs: Bull.Job[] = await queue.getJobs(jobStatuses);
return jobs;
}
}
You could interact with the server using curl:
$ curl -X POST -d 'name=myFirstQueue' localhost:3333/api/generate-queue
# response
{"status":200,"message":"Queue with name myFirstQueue generated successfully!"}
###
$ curl localhost:3333/api/get-all-jobs?name=myFirstQueue
# response
[{"id":"1","name":"__default__","data":{"test":"test"},"opts":{"attempts":1,"delay":0,"timestamp":1639085434398},"progress":0,"delay":0,"timestamp":1639085434398,"attemptsMade":0,"stacktrace":[],"returnvalue":null,"finishedOn":null,"processedOn":null}]
PS1:
Bull's Github
queue.getJobs() reference
PS2:
My Classes and Interfaces:
export class GetAllJobsEndpointQueryParameters {
#IsNotEmpty()
name!: string;
}
export class GenerateQueueDto {
#IsNotEmpty()
name!: string;
}
export interface GenerateQueueResponse {
status: number;
message: string;
}

How to upload Files and Other fields with Request Body in Nestjs

I want to upload three fields like:
Example Data:
partner_id: 3638,
review: [{'product_id': 155, 'order_sku_id': 155, 'review_title': 'Orange Review','rating': 5 }],
review_images[0][0]: ImageFile00
review_images[0][1]: ImageFile01
review_images[1][0]: ImageFile10
review_images is a array of images like the above.
My approach to upload these data. I have created a Dto:
export class CreateReviewDto {
partner_id : Number;
review: any[];
review_images: any[];
}
Controller:
#Controller('api/v1')
export class ReviewController {
constructor(private readonly reviewService: ReviewService) {}
#Post('/review')
#HttpCode(201)
#UseInterceptors(FilesInterceptor('review_images[]'))
create(#Body() createReviewDto: CreateReviewDto, #UploadedFiles() review_images: Express.Multer.File) {
return this.reviewService.create(params,createReviewDto);
}
}
But images are not coming in POSTMAN. Giving undefined Am I going to a right way? What should I do?
The first thing that I noticed. You should use 'review_images' in your FilesInterceptor (link on documentation)
#Controller('api/v1')
export class ReviewController {
constructor(private readonly reviewService: ReviewService) {}
#Post('/review')
#HttpCode(201)
#UseInterceptors(FilesInterceptor('review_images'))
create(#Body() createReviewDto: CreateReviewDto, #UploadedFiles() review_images: Express.Multer.File) {
return this.reviewService.create(params,createReviewDto);
}
}
The second thing. You should send the right request from postman. I suppose it should look like this

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.

How to add custom Request type to Express?

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 {}

Resources