feat: allow to config cors async

Bump version of the fastify-cors.
Add CorsOptionsDelegate interface.
Add CorsOptionsDelegate as an acceptable type
for every enableCors usage.

Closes nestjs/nest#6118
This commit is contained in:
Maciej Sikorski
2021-01-25 12:40:00 +01:00
parent 2bc2c8adfa
commit ec9727093d
21 changed files with 600 additions and 145 deletions

View File

@@ -0,0 +1,177 @@
import { NestFastifyApplication } from '@nestjs/platform-fastify';
import { Test } from '@nestjs/testing';
import * as request from 'supertest';
import { AppModule } from '../src/app.module';
describe('Express Cors', () => {
let app: NestFastifyApplication;
const configs = [
{
origin: 'example.com',
methods: 'GET',
credentials: true,
exposedHeaders: ['foo', 'bar'],
allowedHeaders: ['baz', 'woo'],
maxAge: 123,
},
{
origin: 'sample.com',
methods: 'GET',
credentials: true,
exposedHeaders: ['zoo', 'bar'],
allowedHeaders: ['baz', 'foo'],
maxAge: 321,
},
];
describe('Dynamic config', () => {
describe('enableCors', () => {
before(async () => {
const module = await Test.createTestingModule({
imports: [AppModule],
}).compile();
app = module.createNestApplication<NestFastifyApplication>();
let requestId = 0;
const configDelegation = function (req, cb) {
const config = configs[requestId];
requestId++;
cb(null, config);
};
app.enableCors(configDelegation);
await app.init();
});
it(`Should add cors headers based on the first config`, async () => {
return request(app.getHttpServer())
.get('/')
.expect('access-control-allow-origin', 'example.com')
.expect('vary', 'Origin')
.expect('access-control-allow-credentials', 'true')
.expect('access-control-expose-headers', 'foo,bar')
.expect('content-length', '0');
});
it(`Should add cors headers based on the second config`, async () => {
return request(app.getHttpServer())
.options('/')
.expect('access-control-allow-origin', 'sample.com')
.expect('vary', 'Origin')
.expect('access-control-allow-credentials', 'true')
.expect('access-control-expose-headers', 'zoo,bar')
.expect('access-control-allow-methods', 'GET')
.expect('access-control-allow-headers', 'baz,foo')
.expect('access-control-max-age', '321')
.expect('content-length', '0');
});
after(async () => {
await app.close();
});
});
describe('Application Options', () => {
before(async () => {
const module = await Test.createTestingModule({
imports: [AppModule],
}).compile();
let requestId = 0;
const configDelegation = function (req, cb) {
const config = configs[requestId];
requestId++;
cb(null, config);
};
app = module.createNestApplication<NestFastifyApplication>(null, {
cors: configDelegation,
});
await app.init();
});
it(`Should add cors headers based on the first config`, async () => {
return request(app.getHttpServer())
.get('/')
.expect('access-control-allow-origin', 'example.com')
.expect('vary', 'Origin')
.expect('access-control-allow-credentials', 'true')
.expect('access-control-expose-headers', 'foo,bar')
.expect('content-length', '0');
});
it(`Should add cors headers based on the second config`, async () => {
return request(app.getHttpServer())
.options('/')
.expect('access-control-allow-origin', 'sample.com')
.expect('vary', 'Origin')
.expect('access-control-allow-credentials', 'true')
.expect('access-control-expose-headers', 'zoo,bar')
.expect('access-control-allow-methods', 'GET')
.expect('access-control-allow-headers', 'baz,foo')
.expect('access-control-max-age', '321')
.expect('content-length', '0');
});
after(async () => {
await app.close();
});
});
});
describe('Static config', () => {
describe('enableCors', () => {
before(async () => {
const module = await Test.createTestingModule({
imports: [AppModule],
}).compile();
app = module.createNestApplication<NestFastifyApplication>();
app.enableCors(configs[0]);
await app.init();
});
it(`CORS headers`, async () => {
return request(app.getHttpServer())
.get('/')
.expect('access-control-allow-origin', 'example.com')
.expect('vary', 'Origin')
.expect('access-control-allow-credentials', 'true')
.expect('access-control-expose-headers', 'foo,bar')
.expect('content-length', '0');
});
});
after(async () => {
await app.close();
});
describe('Application Options', () => {
before(async () => {
const module = await Test.createTestingModule({
imports: [AppModule],
}).compile();
app = module.createNestApplication<NestFastifyApplication>(null, {
cors: configs[0],
});
await app.init();
});
it(`CORS headers`, async () => {
return request(app.getHttpServer())
.get('/')
.expect('access-control-allow-origin', 'example.com')
.expect('vary', 'Origin')
.expect('access-control-allow-credentials', 'true')
.expect('access-control-expose-headers', 'foo,bar')
.expect('content-length', '0');
});
after(async () => {
await app.close();
});
});
});
});

View File

@@ -0,0 +1,177 @@
import { NestFastifyApplication } from '@nestjs/platform-fastify';
import { Test } from '@nestjs/testing';
import * as request from 'supertest';
import { AppModule } from '../src/app.module';
describe('Fastify Cors', () => {
let app: NestFastifyApplication;
const configs = [
{
origin: 'example.com',
methods: 'GET',
credentials: true,
exposedHeaders: ['foo', 'bar'],
allowedHeaders: ['baz', 'woo'],
maxAge: 123,
},
{
origin: 'sample.com',
methods: 'GET',
credentials: true,
exposedHeaders: ['zoo', 'bar'],
allowedHeaders: ['baz', 'foo'],
maxAge: 321,
},
];
describe('Dynamic config', () => {
describe('enableCors', () => {
before(async () => {
const module = await Test.createTestingModule({
imports: [AppModule],
}).compile();
app = module.createNestApplication<NestFastifyApplication>();
let requestId = 0;
const configDelegation = function (req, cb) {
const config = configs[requestId];
requestId++;
cb(null, config);
};
app.enableCors(configDelegation);
await app.init();
});
it(`Should add cors headers based on the first config`, async () => {
return request(app.getHttpServer())
.get('/')
.expect('access-control-allow-origin', 'example.com')
.expect('vary', 'Origin')
.expect('access-control-allow-credentials', 'true')
.expect('access-control-expose-headers', 'foo,bar')
.expect('content-length', '0');
});
it(`Should add cors headers based on the second config`, async () => {
return request(app.getHttpServer())
.options('/')
.expect('access-control-allow-origin', 'sample.com')
.expect('vary', 'Origin')
.expect('access-control-allow-credentials', 'true')
.expect('access-control-expose-headers', 'zoo,bar')
.expect('access-control-allow-methods', 'GET')
.expect('access-control-allow-headers', 'baz,foo')
.expect('access-control-max-age', '321')
.expect('content-length', '0');
});
after(async () => {
await app.close();
});
});
describe('Application Options', () => {
before(async () => {
const module = await Test.createTestingModule({
imports: [AppModule],
}).compile();
let requestId = 0;
const configDelegation = function (req, cb) {
const config = configs[requestId];
requestId++;
cb(null, config);
};
app = module.createNestApplication<NestFastifyApplication>(null, {
cors: configDelegation,
});
await app.init();
});
it(`Should add cors headers based on the first config`, async () => {
return request(app.getHttpServer())
.get('/')
.expect('access-control-allow-origin', 'example.com')
.expect('vary', 'Origin')
.expect('access-control-allow-credentials', 'true')
.expect('access-control-expose-headers', 'foo,bar')
.expect('content-length', '0');
});
it(`Should add cors headers based on the second config`, async () => {
return request(app.getHttpServer())
.options('/')
.expect('access-control-allow-origin', 'sample.com')
.expect('vary', 'Origin')
.expect('access-control-allow-credentials', 'true')
.expect('access-control-expose-headers', 'zoo,bar')
.expect('access-control-allow-methods', 'GET')
.expect('access-control-allow-headers', 'baz,foo')
.expect('access-control-max-age', '321')
.expect('content-length', '0');
});
after(async () => {
await app.close();
});
});
});
describe('Static config', () => {
describe('enableCors', () => {
before(async () => {
const module = await Test.createTestingModule({
imports: [AppModule],
}).compile();
app = module.createNestApplication<NestFastifyApplication>();
app.enableCors(configs[0]);
await app.init();
});
it(`CORS headers`, async () => {
return request(app.getHttpServer())
.get('/')
.expect('access-control-allow-origin', 'example.com')
.expect('vary', 'Origin')
.expect('access-control-allow-credentials', 'true')
.expect('access-control-expose-headers', 'foo,bar')
.expect('content-length', '0');
});
});
after(async () => {
await app.close();
});
describe('Application Options', () => {
before(async () => {
const module = await Test.createTestingModule({
imports: [AppModule],
}).compile();
app = module.createNestApplication<NestFastifyApplication>(null, {
cors: configs[0],
});
await app.init();
});
it(`CORS headers`, async () => {
return request(app.getHttpServer())
.get('/')
.expect('access-control-allow-origin', 'example.com')
.expect('vary', 'Origin')
.expect('access-control-allow-credentials', 'true')
.expect('access-control-expose-headers', 'foo,bar')
.expect('content-length', '0');
});
});
after(async () => {
await app.close();
});
});
});

View File

@@ -0,0 +1,9 @@
import { Controller, Get } from '@nestjs/common';
@Controller()
export class AppController {
@Get()
getGlobals() {
return '';
}
}

View File

@@ -0,0 +1,7 @@
import { Module } from '@nestjs/common';
import { AppController } from './app.controller';
@Module({
controllers: [AppController],
})
export class AppModule {}

View File

@@ -0,0 +1,22 @@
{
"compilerOptions": {
"module": "commonjs",
"declaration": false,
"noImplicitAny": false,
"removeComments": true,
"noLib": false,
"emitDecoratorMetadata": true,
"experimentalDecorators": true,
"target": "es6",
"sourceMap": true,
"allowJs": true,
"outDir": "./dist"
},
"include": [
"src/**/*",
"e2e/**/*"
],
"exclude": [
"node_modules",
]
}

View File

@@ -1,4 +1,11 @@
import { Body, Controller, HttpCode, OnModuleInit, Post, OnModuleDestroy } from '@nestjs/common';
import {
Body,
Controller,
HttpCode,
OnModuleInit,
Post,
OnModuleDestroy,
} from '@nestjs/common';
import { Logger } from '@nestjs/common/services/logger.service';
import { Client, ClientKafka, Transport } from '@nestjs/microservices';
import { Observable } from 'rxjs';

View File

@@ -78,4 +78,3 @@ export class HttpException extends Error {
: { statusCode, message: objectOrError, error: description };
}
}

View File

@@ -52,3 +52,10 @@ export interface CorsOptions {
*/
optionsSuccessStatus?: number;
}
export interface CorsOptionsCallback {
(error: Error, options: CorsOptions): void;
}
export interface CorsOptionsDelegate<T> {
(req: T, cb: CorsOptionsCallback): void;
}

View File

@@ -1,5 +1,8 @@
import { RequestMethod } from '../../enums';
import { CorsOptions } from '../../interfaces/external/cors-options.interface';
import {
CorsOptions,
CorsOptionsDelegate,
} from '../../interfaces/external/cors-options.interface';
import { NestApplicationOptions } from '../../interfaces/nest-application-options.interface';
export type ErrorHandler<TRequest = any, TResponse = any> = (
@@ -62,7 +65,7 @@ export interface HttpServer<TRequest = any, TResponse = any> {
getRequestUrl?(request: TResponse): string;
getInstance(): any;
registerParserMiddleware(): any;
enableCors(options: CorsOptions): any;
enableCors(options: CorsOptions | CorsOptionsDelegate<TRequest>): any;
getHttpServer(): any;
initHttpServer(options: NestApplicationOptions): void;
close(): any;

View File

@@ -1,4 +1,7 @@
import { CorsOptions } from './external/cors-options.interface';
import {
CorsOptions,
CorsOptionsDelegate,
} from './external/cors-options.interface';
import { HttpsOptions } from './external/https-options.interface';
import { NestApplicationContextOptions } from './nest-application-context-options.interface';
@@ -9,7 +12,7 @@ export interface NestApplicationOptions extends NestApplicationContextOptions {
/**
* CORS options from [CORS package](https://github.com/expressjs/cors#configuration-options)
*/
cors?: boolean | CorsOptions;
cors?: boolean | CorsOptions | CorsOptionsDelegate<any>;
/**
* Whether to use underlying platform body parser.
*/

View File

@@ -1,4 +1,7 @@
import { CorsOptions } from './external/cors-options.interface';
import {
CorsOptions,
CorsOptionsDelegate,
} from './external/cors-options.interface';
import { CanActivate } from './features/can-activate.interface';
import { NestInterceptor } from './features/nest-interceptor.interface';
import { HttpServer } from './http/http-server.interface';
@@ -30,7 +33,7 @@ export interface INestApplication extends INestApplicationContext {
*
* @returns {void}
*/
enableCors(options?: CorsOptions): void;
enableCors(options?: CorsOptions | CorsOptionsDelegate<any>): void;
/**
* Starts the application.

View File

@@ -2,6 +2,7 @@ import { HttpServer, RequestMethod } from '@nestjs/common';
import { RequestHandler } from '@nestjs/common/interfaces';
import { CorsOptions } from '@nestjs/common/interfaces/external/cors-options.interface';
import { NestApplicationOptions } from '@nestjs/common/interfaces/nest-application-options.interface';
import { CorsOptionsDelegate } from '../../common/interfaces/external/cors-options.interface';
/**
* @publicApi
@@ -97,7 +98,10 @@ export abstract class AbstractHttpAdapter<
abstract setNotFoundHandler(handler: Function, prefix?: string);
abstract setHeader(response, name: string, value: string);
abstract registerParserMiddleware(prefix?: string);
abstract enableCors(options: CorsOptions, prefix?: string);
abstract enableCors(
options: CorsOptions | CorsOptionsDelegate<TRequest>,
prefix?: string,
);
abstract createMiddlewareFactory(
requestMethod: RequestMethod,
):

View File

@@ -14,12 +14,8 @@ export class ApplicationConfig {
private globalInterceptors: NestInterceptor[] = [];
private globalGuards: CanActivate[] = [];
private readonly globalRequestPipes: InstanceWrapper<PipeTransform>[] = [];
private readonly globalRequestFilters: InstanceWrapper<
ExceptionFilter
>[] = [];
private readonly globalRequestInterceptors: InstanceWrapper<
NestInterceptor
>[] = [];
private readonly globalRequestFilters: InstanceWrapper<ExceptionFilter>[] = [];
private readonly globalRequestInterceptors: InstanceWrapper<NestInterceptor>[] = [];
private readonly globalRequestGuards: InstanceWrapper<CanActivate>[] = [];
constructor(private ioAdapter: WebSocketAdapter | null = null) {}

View File

@@ -38,9 +38,7 @@ export interface ExternalContextOptions {
export class ExternalContextCreator {
private readonly contextUtils = new ContextUtils();
private readonly externalErrorProxy = new ExternalErrorProxy();
private readonly handlerMetadataStorage = new HandlerMetadataStorage<
ExternalHandlerMetadata
>();
private readonly handlerMetadataStorage = new HandlerMetadataStorage<ExternalHandlerMetadata>();
private container: NestContainer;
constructor(

View File

@@ -26,6 +26,8 @@ import { MiddlewareModule } from './middleware/middleware-module';
import { NestApplicationContext } from './nest-application-context';
import { Resolver } from './router/interfaces/resolver.interface';
import { RoutesResolver } from './router/routes-resolver';
import { isFunction } from 'util';
import { CorsOptionsDelegate } from '../common/interfaces/external/cors-options.interface';
const { SocketModule } = optionalRequire(
'@nestjs/websockets/socket-module',
@@ -102,11 +104,15 @@ export class NestApplication
if (!this.appOptions || !this.appOptions.cors) {
return undefined;
}
const isCorsOptionsObj = isObject(this.appOptions.cors);
if (!isCorsOptionsObj) {
const passCustomOptions =
isObject(this.appOptions.cors) ||
typeof this.appOptions.cors === 'function';
if (!passCustomOptions) {
return this.enableCors();
}
return this.enableCors(this.appOptions.cors as CorsOptions);
return this.enableCors(
this.appOptions.cors as CorsOptions | CorsOptionsDelegate<any>,
);
}
public createServer<T = any>(): T {
@@ -224,7 +230,7 @@ export class NestApplication
return this;
}
public enableCors(options?: CorsOptions): void {
public enableCors(options?: CorsOptions | CorsOptionsDelegate<any>): void {
this.httpAdapter.enableCors(options);
}

View File

@@ -41,9 +41,7 @@ export interface RpcHandlerMetadata {
export class RpcContextCreator {
private readonly contextUtils = new ContextUtils();
private readonly rpcParamsFactory = new RpcParamsFactory();
private readonly handlerMetadataStorage = new HandlerMetadataStorage<
RpcHandlerMetadata
>();
private readonly handlerMetadataStorage = new HandlerMetadataStorage<RpcHandlerMetadata>();
constructor(
private readonly rpcProxy: RpcProxy,

View File

@@ -10,6 +10,7 @@ import * as express from 'express';
import * as http from 'http';
import * as https from 'https';
import { ServeStaticOptions } from '../interfaces/serve-static-options.interface';
import { CorsOptionsDelegate } from '../../common/interfaces/external/cors-options.interface';
export class ExpressAdapter extends AbstractHttpAdapter {
private readonly routerMethodFactory = new RouterMethodFactory();
@@ -108,7 +109,7 @@ export class ExpressAdapter extends AbstractHttpAdapter {
return request.originalUrl;
}
public enableCors(options: CorsOptions) {
public enableCors(options: CorsOptions | CorsOptionsDelegate<any>) {
return this.use(cors(options));
}

View File

@@ -33,6 +33,7 @@ import {
FastifyStaticOptions,
PointOfViewOptions,
} from '../interfaces/external';
import { CorsOptionsDelegate } from '../../common/interfaces/external/cors-options.interface';
type FastifyHttp2SecureOptions<
Server extends http2.Http2SecureServer,
@@ -257,8 +258,18 @@ export class FastifyAdapter<
return request.raw ? request.raw.url : request.url;
}
public enableCors(options: CorsOptions) {
this.register(require('fastify-cors'), options);
public enableCors(
options:
| CorsOptions
| CorsOptionsDelegate<
FastifyRequest<RequestGenericInterface, TServer, TRawRequest>
>,
) {
if (typeof options === 'function') {
this.register(require('fastify-cors'), () => options);
} else {
this.register(require('fastify-cors'), options);
}
}
public registerParserMiddleware() {

View File

@@ -39,9 +39,7 @@ export interface WsHandlerMetadata {
export class WsContextCreator {
private readonly contextUtils = new ContextUtils();
private readonly wsParamsFactory = new WsParamsFactory();
private readonly handlerMetadataStorage = new HandlerMetadataStorage<
WsHandlerMetadata
>();
private readonly handlerMetadataStorage = new HandlerMetadataStorage<WsHandlerMetadata>();
constructor(
private readonly wsProxy: WsProxy,

View File

@@ -1,4 +1,3 @@
/** ------------------------------------------------------
* THIS FILE WAS AUTOMATICALLY GENERATED (DO NOT MODIFY)
* -------------------------------------------------------
@@ -6,175 +5,205 @@
/* tslint:disable */
export enum MutationType {
CREATED = "CREATED",
UPDATED = "UPDATED",
DELETED = "DELETED"
CREATED = 'CREATED',
UPDATED = 'UPDATED',
DELETED = 'DELETED',
}
export enum PostOrderByInput {
id_ASC = "id_ASC",
id_DESC = "id_DESC",
isPublished_ASC = "isPublished_ASC",
isPublished_DESC = "isPublished_DESC",
title_ASC = "title_ASC",
title_DESC = "title_DESC",
text_ASC = "text_ASC",
text_DESC = "text_DESC"
id_ASC = 'id_ASC',
id_DESC = 'id_DESC',
isPublished_ASC = 'isPublished_ASC',
isPublished_DESC = 'isPublished_DESC',
title_ASC = 'title_ASC',
title_DESC = 'title_DESC',
text_ASC = 'text_ASC',
text_DESC = 'text_DESC',
}
export class PostCreateInput {
id?: string;
isPublished?: boolean;
title: string;
text: string;
id?: string;
isPublished?: boolean;
title: string;
text: string;
}
export class PostSubscriptionWhereInput {
AND?: PostSubscriptionWhereInput[];
OR?: PostSubscriptionWhereInput[];
NOT?: PostSubscriptionWhereInput[];
mutation_in?: MutationType[];
updatedFields_contains?: string;
updatedFields_contains_every?: string[];
updatedFields_contains_some?: string[];
node?: PostWhereInput;
AND?: PostSubscriptionWhereInput[];
OR?: PostSubscriptionWhereInput[];
NOT?: PostSubscriptionWhereInput[];
mutation_in?: MutationType[];
updatedFields_contains?: string;
updatedFields_contains_every?: string[];
updatedFields_contains_some?: string[];
node?: PostWhereInput;
}
export class PostUpdateInput {
isPublished?: boolean;
title?: string;
text?: string;
isPublished?: boolean;
title?: string;
text?: string;
}
export class PostUpdateManyMutationInput {
isPublished?: boolean;
title?: string;
text?: string;
isPublished?: boolean;
title?: string;
text?: string;
}
export class PostWhereInput {
AND?: PostWhereInput[];
OR?: PostWhereInput[];
NOT?: PostWhereInput[];
id?: string;
id_not?: string;
id_in?: string[];
id_not_in?: string[];
id_lt?: string;
id_lte?: string;
id_gt?: string;
id_gte?: string;
id_contains?: string;
id_not_contains?: string;
id_starts_with?: string;
id_not_starts_with?: string;
id_ends_with?: string;
id_not_ends_with?: string;
isPublished?: boolean;
isPublished_not?: boolean;
title?: string;
title_not?: string;
title_in?: string[];
title_not_in?: string[];
title_lt?: string;
title_lte?: string;
title_gt?: string;
title_gte?: string;
title_contains?: string;
title_not_contains?: string;
title_starts_with?: string;
title_not_starts_with?: string;
title_ends_with?: string;
title_not_ends_with?: string;
text?: string;
text_not?: string;
text_in?: string[];
text_not_in?: string[];
text_lt?: string;
text_lte?: string;
text_gt?: string;
text_gte?: string;
text_contains?: string;
text_not_contains?: string;
text_starts_with?: string;
text_not_starts_with?: string;
text_ends_with?: string;
text_not_ends_with?: string;
AND?: PostWhereInput[];
OR?: PostWhereInput[];
NOT?: PostWhereInput[];
id?: string;
id_not?: string;
id_in?: string[];
id_not_in?: string[];
id_lt?: string;
id_lte?: string;
id_gt?: string;
id_gte?: string;
id_contains?: string;
id_not_contains?: string;
id_starts_with?: string;
id_not_starts_with?: string;
id_ends_with?: string;
id_not_ends_with?: string;
isPublished?: boolean;
isPublished_not?: boolean;
title?: string;
title_not?: string;
title_in?: string[];
title_not_in?: string[];
title_lt?: string;
title_lte?: string;
title_gt?: string;
title_gte?: string;
title_contains?: string;
title_not_contains?: string;
title_starts_with?: string;
title_not_starts_with?: string;
title_ends_with?: string;
title_not_ends_with?: string;
text?: string;
text_not?: string;
text_in?: string[];
text_not_in?: string[];
text_lt?: string;
text_lte?: string;
text_gt?: string;
text_gte?: string;
text_contains?: string;
text_not_contains?: string;
text_starts_with?: string;
text_not_starts_with?: string;
text_ends_with?: string;
text_not_ends_with?: string;
}
export class PostWhereUniqueInput {
id?: string;
id?: string;
}
export interface Node {
id: string;
id: string;
}
export class AggregatePost {
count: number;
count: number;
}
export class BatchPayload {
count: Long;
count: Long;
}
export abstract class IMutation {
abstract createPost(data: PostCreateInput): Post | Promise<Post>;
abstract updatePost(data: PostUpdateInput, where: PostWhereUniqueInput): Post | Promise<Post>;
abstract deletePost(where: PostWhereUniqueInput): Post | Promise<Post>;
abstract upsertPost(where: PostWhereUniqueInput, create: PostCreateInput, update: PostUpdateInput): Post | Promise<Post>;
abstract updateManyPosts(data: PostUpdateManyMutationInput, where?: PostWhereInput): BatchPayload | Promise<BatchPayload>;
abstract deleteManyPosts(where?: PostWhereInput): BatchPayload | Promise<BatchPayload>;
abstract createPost(data: PostCreateInput): Post | Promise<Post>;
abstract updatePost(
data: PostUpdateInput,
where: PostWhereUniqueInput,
): Post | Promise<Post>;
abstract deletePost(where: PostWhereUniqueInput): Post | Promise<Post>;
abstract upsertPost(
where: PostWhereUniqueInput,
create: PostCreateInput,
update: PostUpdateInput,
): Post | Promise<Post>;
abstract updateManyPosts(
data: PostUpdateManyMutationInput,
where?: PostWhereInput,
): BatchPayload | Promise<BatchPayload>;
abstract deleteManyPosts(
where?: PostWhereInput,
): BatchPayload | Promise<BatchPayload>;
}
export class PageInfo {
hasNextPage: boolean;
hasPreviousPage: boolean;
startCursor?: string;
endCursor?: string;
hasNextPage: boolean;
hasPreviousPage: boolean;
startCursor?: string;
endCursor?: string;
}
export class Post implements Node {
id: string;
isPublished: boolean;
title: string;
text: string;
id: string;
isPublished: boolean;
title: string;
text: string;
}
export class PostConnection {
pageInfo: PageInfo;
edges: PostEdge[];
aggregate: AggregatePost;
pageInfo: PageInfo;
edges: PostEdge[];
aggregate: AggregatePost;
}
export class PostEdge {
node: Post;
cursor: string;
node: Post;
cursor: string;
}
export class PostPreviousValues {
id: string;
isPublished: boolean;
title: string;
text: string;
id: string;
isPublished: boolean;
title: string;
text: string;
}
export class PostSubscriptionPayload {
mutation: MutationType;
node?: Post;
updatedFields?: string[];
previousValues?: PostPreviousValues;
mutation: MutationType;
node?: Post;
updatedFields?: string[];
previousValues?: PostPreviousValues;
}
export abstract class IQuery {
abstract posts(where?: PostWhereInput, orderBy?: PostOrderByInput, skip?: number, after?: string, before?: string, first?: number, last?: number): Post[] | Promise<Post[]>;
abstract post(where: PostWhereUniqueInput): Post | Promise<Post>;
abstract postsConnection(where?: PostWhereInput, orderBy?: PostOrderByInput, skip?: number, after?: string, before?: string, first?: number, last?: number): PostConnection | Promise<PostConnection>;
abstract node(id: string): Node | Promise<Node>;
abstract posts(
where?: PostWhereInput,
orderBy?: PostOrderByInput,
skip?: number,
after?: string,
before?: string,
first?: number,
last?: number,
): Post[] | Promise<Post[]>;
abstract post(where: PostWhereUniqueInput): Post | Promise<Post>;
abstract postsConnection(
where?: PostWhereInput,
orderBy?: PostOrderByInput,
skip?: number,
after?: string,
before?: string,
first?: number,
last?: number,
): PostConnection | Promise<PostConnection>;
abstract node(id: string): Node | Promise<Node>;
}
export abstract class ISubscription {
abstract post(where?: PostSubscriptionWhereInput): PostSubscriptionPayload | Promise<PostSubscriptionPayload>;
abstract post(
where?: PostSubscriptionWhereInput,
): PostSubscriptionPayload | Promise<PostSubscriptionPayload>;
}
export type Long = any;

View File

@@ -49,7 +49,7 @@ async function executeNpmScriptInSamples(
task('install:samples', async () =>
executeNpmScriptInSamples(
// 'npm ci --no-audit --no-shrinkwrap --no-optional',
'npm install'
'npm install',
),
);
task('build:samples', async () => executeNpmScriptInSamples('npm run build'));