├── packages ├── nestjs-firebase │ ├── src │ │ ├── util │ │ │ ├── index.ts │ │ │ └── getFirebaseAdmin.ts │ │ ├── index.ts │ │ ├── firebase.decorator.ts │ │ ├── firebase.constants.ts │ │ ├── firebase.interface.ts │ │ ├── firebase.module.spec.ts │ │ └── firebase.module.ts │ ├── tsconfig.json │ ├── __tests__ │ │ └── getFirebaseAdmin.test.ts │ ├── package.json │ └── README.md ├── nestjs-slack-webhook │ ├── src │ │ ├── slackConstants.ts │ │ ├── index.ts │ │ ├── injectSlack.ts │ │ ├── getSlackClient.ts │ │ ├── createSlackProvider.ts │ │ ├── slackOptions.ts │ │ ├── slackModule.ts │ │ └── slackCoreModule.ts │ ├── tsconfig.json │ ├── __tests__ │ │ ├── getSlackClient.test.ts │ │ ├── injectSlack.test.ts │ │ └── slackModule.test.ts │ ├── package.json │ └── README.md ├── nestjs-zendesk │ ├── src │ │ ├── zendesk.constants.ts │ │ ├── index.ts │ │ ├── zendesk.inject.spec.ts │ │ ├── zendesk.inject.ts │ │ ├── zendesk.interface.ts │ │ ├── zendesk.module.spec.ts │ │ └── zendesk.module.ts │ ├── tsconfig.json │ ├── package.json │ └── README.md └── nestjs-graphql-relay │ ├── tsconfig.json │ ├── __tests__ │ ├── __snapshots__ │ │ └── index.test.ts.snap │ └── index.test.ts │ ├── src │ ├── orderBy.input.ts │ ├── pageInfo.ts │ ├── index.ts │ └── connectionArgs.ts │ ├── package.json │ └── README.md ├── example ├── nest-cli.json ├── tsconfig.build.json ├── src │ ├── app.service.ts │ ├── node │ │ ├── node.ts │ │ ├── node.module.ts │ │ ├── node.resolver.ts │ │ └── node.resolver.spec.ts │ ├── zendesk │ │ ├── zendesk.module.ts │ │ ├── zendesk.service.ts │ │ └── zendesk.service.spec.ts │ ├── notify │ │ ├── notify.module.ts │ │ ├── notify.service.ts │ │ ├── notify.controller.ts │ │ ├── notify.service.spec.ts │ │ └── notify.controller.spec.ts │ ├── app.controller.ts │ ├── config │ │ ├── zendesk.ts │ │ └── slack.ts │ ├── main.ts │ ├── recipes │ │ ├── recipes.module.ts │ │ ├── dto │ │ │ └── recipes.input.ts │ │ ├── models │ │ │ └── recipe.ts │ │ ├── recipes.service.ts │ │ ├── recipes.service.spec.ts │ │ ├── recipes.resolver.spec.ts │ │ └── recipes.resolver.ts │ ├── testing │ │ └── slack.ts │ ├── app.controller.spec.ts │ ├── schema.gql │ └── app.module.ts ├── tsconfig.json ├── __tests__ │ └── app.e2e-spec.ts └── package.json ├── .secretlintrc.json ├── .pre-commit-config.yaml ├── .devcontainer └── devcontainer.json ├── .github ├── workflows │ ├── bump-schedules.yml │ ├── actionlint.yml │ ├── nodejs.yml │ ├── npm-publish-packages.yml │ ├── dependabot.yml │ └── bump.yml ├── dependabot.yml ├── release.yml └── mergeable.yml ├── SECURITY.md ├── biome.json ├── tsconfig.json ├── LICENSE ├── package.json ├── README.md ├── dummy.firebase.amin.key.json ├── .gitignore └── CHANGELOG.md /packages/nestjs-firebase/src/util/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./getFirebaseAdmin"; 2 | -------------------------------------------------------------------------------- /example/nest-cli.json: -------------------------------------------------------------------------------- 1 | { 2 | "collection": "@nestjs/schematics", 3 | "sourceRoot": "src" 4 | } 5 | -------------------------------------------------------------------------------- /example/tsconfig.build.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.json", 3 | "exclude": ["__tests__/*", "*.spec.ts"] 4 | } 5 | -------------------------------------------------------------------------------- /.secretlintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "rules": [ 3 | { 4 | "id": "@secretlint/secretlint-rule-preset-recommend" 5 | } 6 | ] 7 | } 8 | -------------------------------------------------------------------------------- /.pre-commit-config.yaml: -------------------------------------------------------------------------------- 1 | repos: 2 | - repo: https://github.com/biomejs/pre-commit 3 | rev: "v2.2.3" 4 | hooks: 5 | - id: biome-check 6 | -------------------------------------------------------------------------------- /packages/nestjs-slack-webhook/src/slackConstants.ts: -------------------------------------------------------------------------------- 1 | export const SLACK_MODULE = "SlackModule"; 2 | 3 | export const SLACK_TOKEN = "SLACK_TOKEN"; 4 | -------------------------------------------------------------------------------- /packages/nestjs-zendesk/src/zendesk.constants.ts: -------------------------------------------------------------------------------- 1 | export const ZENDESK_MODULE = "ZENDESK_MODULE"; 2 | export const ZENDESK_TOKEN = "ZENDESK_TOKEN"; 3 | -------------------------------------------------------------------------------- /packages/nestjs-slack-webhook/src/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./injectSlack"; 2 | export * from "./slackConstants"; 3 | export * from "./slackModule"; 4 | export * from "./slackOptions"; 5 | -------------------------------------------------------------------------------- /packages/nestjs-zendesk/src/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./zendesk.constants"; 2 | export * from "./zendesk.inject"; 3 | export * from "./zendesk.interface"; 4 | export * from "./zendesk.module"; 5 | -------------------------------------------------------------------------------- /example/src/app.service.ts: -------------------------------------------------------------------------------- 1 | import { Injectable } from "@nestjs/common"; 2 | 3 | @Injectable() 4 | export class AppService { 5 | getHello(): string { 6 | return "Hello World!"; 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /packages/nestjs-firebase/src/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./firebase.constants"; 2 | export * from "./firebase.decorator"; 3 | export * from "./firebase.interface"; 4 | export * from "./firebase.module"; 5 | -------------------------------------------------------------------------------- /example/src/node/node.ts: -------------------------------------------------------------------------------- 1 | import { Field, ID, InterfaceType } from "@nestjs/graphql"; 2 | 3 | @InterfaceType() 4 | export abstract class Node { 5 | @Field(() => ID, { name: "id" }) 6 | readonly relayId: string; 7 | } 8 | -------------------------------------------------------------------------------- /packages/nestjs-slack-webhook/src/injectSlack.ts: -------------------------------------------------------------------------------- 1 | import { Inject } from "@nestjs/common"; 2 | import { SLACK_TOKEN } from "./slackConstants"; 3 | 4 | export function InjectSlack() { 5 | return Inject(SLACK_TOKEN); 6 | } 7 | -------------------------------------------------------------------------------- /packages/nestjs-zendesk/src/zendesk.inject.spec.ts: -------------------------------------------------------------------------------- 1 | import { expect, it } from "@jest/globals"; 2 | import { InjectZendesk } from "./zendesk.inject"; 3 | 4 | it("InjectZendesk", () => expect(InjectZendesk()).toBeDefined()); 5 | -------------------------------------------------------------------------------- /example/src/zendesk/zendesk.module.ts: -------------------------------------------------------------------------------- 1 | import { Module } from "@nestjs/common"; 2 | import { ZendeskService } from "./zendesk.service"; 3 | 4 | @Module({ 5 | providers: [ZendeskService], 6 | }) 7 | export class ZendeskModule {} 8 | -------------------------------------------------------------------------------- /packages/nestjs-zendesk/src/zendesk.inject.ts: -------------------------------------------------------------------------------- 1 | import { Inject } from "@nestjs/common"; 2 | import { ZENDESK_TOKEN } from "./zendesk.constants"; 3 | 4 | export function InjectZendesk() { 5 | return Inject(ZENDESK_TOKEN); 6 | } 7 | -------------------------------------------------------------------------------- /packages/nestjs-zendesk/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.json", 3 | "compilerOptions": { 4 | "outDir": "./lib", 5 | "noEmit": false 6 | }, 7 | "exclude": ["__tests__/*", "*.spec.ts"], 8 | "include": ["src"] 9 | } 10 | -------------------------------------------------------------------------------- /packages/nestjs-firebase/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.json", 3 | "compilerOptions": { 4 | "outDir": "./lib", 5 | "noEmit": false 6 | }, 7 | "exclude": ["__tests__/*", "*.spec.ts"], 8 | "include": ["src"] 9 | } 10 | -------------------------------------------------------------------------------- /packages/nestjs-firebase/src/firebase.decorator.ts: -------------------------------------------------------------------------------- 1 | import { Inject } from "@nestjs/common"; 2 | import { FirebaseConstants } from "./firebase.constants"; 3 | 4 | export function InjectFirebaseAdmin() { 5 | return Inject(FirebaseConstants.FIREBASE_TOKEN); 6 | } 7 | -------------------------------------------------------------------------------- /packages/nestjs-graphql-relay/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.json", 3 | "compilerOptions": { 4 | "outDir": "./lib", 5 | "noEmit": false 6 | }, 7 | "exclude": ["__tests__/*", "*.spec.ts"], 8 | "include": ["src"] 9 | } 10 | -------------------------------------------------------------------------------- /packages/nestjs-slack-webhook/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.json", 3 | "compilerOptions": { 4 | "outDir": "./lib", 5 | "noEmit": false 6 | }, 7 | "exclude": ["__tests__/*", "*.spec.ts"], 8 | "include": ["src"] 9 | } 10 | -------------------------------------------------------------------------------- /.devcontainer/devcontainer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Node.js 22", 3 | "image": "mcr.microsoft.com/devcontainers/typescript-node:22-bookworm", 4 | "customizations": {}, 5 | 6 | "containerEnv": { 7 | "SLACK_WEBHOOK_URL": "https://example.com" 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /packages/nestjs-firebase/src/firebase.constants.ts: -------------------------------------------------------------------------------- 1 | // biome-ignore lint/complexity/noStaticOnlyClass: NestJS module 2 | export class FirebaseConstants { 3 | public static readonly FIREBASE_MODULE = "FirebaseModule"; 4 | public static readonly FIREBASE_TOKEN = "FIREBASE_TOKEN"; 5 | } 6 | -------------------------------------------------------------------------------- /example/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../tsconfig.json", 3 | "compilerOptions": { 4 | "declaration": true, 5 | "noEmit": false, 6 | "outDir": "./dist", 7 | "removeComments": true, 8 | "sourceMap": true 9 | }, 10 | "exclude": ["__tests__/*", "*.spec.ts"] 11 | } 12 | -------------------------------------------------------------------------------- /.github/workflows/bump-schedules.yml: -------------------------------------------------------------------------------- 1 | name: Bump version (cron) 2 | 3 | on: 4 | schedule: 5 | - cron: "15 3 * * TUE" 6 | 7 | jobs: 8 | scheduled_bump: 9 | permissions: 10 | contents: write 11 | uses: ./.github/workflows/bump.yml 12 | secrets: inherit 13 | with: 14 | semver: minor 15 | -------------------------------------------------------------------------------- /example/src/notify/notify.module.ts: -------------------------------------------------------------------------------- 1 | import { Module } from "@nestjs/common"; 2 | import { NotifyController } from "./notify.controller"; 3 | import { NotifyService } from "./notify.service"; 4 | 5 | @Module({ 6 | providers: [NotifyService], 7 | controllers: [NotifyController], 8 | }) 9 | export class NotifyModule {} 10 | -------------------------------------------------------------------------------- /example/src/app.controller.ts: -------------------------------------------------------------------------------- 1 | import { Controller, Get } from "@nestjs/common"; 2 | import { AppService } from "./app.service"; 3 | 4 | @Controller() 5 | export class AppController { 6 | constructor(private readonly appService: AppService) {} 7 | 8 | @Get() 9 | getHello(): string { 10 | return this.appService.getHello(); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /packages/nestjs-slack-webhook/src/getSlackClient.ts: -------------------------------------------------------------------------------- 1 | import { IncomingWebhook } from "@slack/webhook"; 2 | import { SlackOptions } from "./slackOptions"; 3 | 4 | export function getSlackClient({ 5 | url, 6 | ...args 7 | }: SlackOptions): IncomingWebhook { 8 | const slackClient = new IncomingWebhook(url, args); 9 | return slackClient; 10 | } 11 | -------------------------------------------------------------------------------- /packages/nestjs-graphql-relay/__tests__/__snapshots__/index.test.ts.snap: -------------------------------------------------------------------------------- 1 | // Jest Snapshot v1, https://jestjs.io/docs/snapshot-testing 2 | 3 | exports[`app findAndPaginate find 1`] = ` 4 | { 5 | "endCursor": "YXJyYXljb25uZWN0aW9uOjA=", 6 | "hasNextPage": false, 7 | "hasPreviousPage": false, 8 | "startCursor": "YXJyYXljb25uZWN0aW9uOjA=", 9 | } 10 | `; 11 | -------------------------------------------------------------------------------- /example/src/config/zendesk.ts: -------------------------------------------------------------------------------- 1 | import { registerAs } from "@nestjs/config"; 2 | import type { ZendeskClientOptions } from "node-zendesk"; 3 | 4 | export default registerAs( 5 | "zendesk", 6 | (): ZendeskClientOptions => ({ 7 | username: process.env.ZENDESK_USER_NAME, 8 | token: process.env.ZENDESK_TOKEN, 9 | endpointUri: process.env.ZENDESK_REMOTE_URI, 10 | }), 11 | ); 12 | -------------------------------------------------------------------------------- /example/src/config/slack.ts: -------------------------------------------------------------------------------- 1 | import { registerAs } from "@nestjs/config"; 2 | import { SlackOptions } from "nestjs-slack-webhook"; 3 | 4 | export default registerAs( 5 | "slack", 6 | (url = process.env["SLACK_WEBHOOK_URL"]): SlackOptions => { 7 | if (!url) { 8 | throw new Error("SLACK_WEBHOOK_URL is not defined"); 9 | } 10 | return { 11 | url, 12 | }; 13 | }, 14 | ); 15 | -------------------------------------------------------------------------------- /example/src/zendesk/zendesk.service.ts: -------------------------------------------------------------------------------- 1 | import { Injectable } from "@nestjs/common"; 2 | import { InjectZendesk } from "nestjs-zendesk"; 3 | import { ZendeskClient } from "node-zendesk"; 4 | 5 | @Injectable() 6 | export class ZendeskService { 7 | constructor(@InjectZendesk() private readonly zendesk: ZendeskClient) {} 8 | 9 | async ticket() { 10 | return this.zendesk.tickets.list(); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /packages/nestjs-firebase/__tests__/getFirebaseAdmin.test.ts: -------------------------------------------------------------------------------- 1 | import { describe, expect, it } from "@jest/globals"; 2 | import { getFirebaseAdmin } from "../src/util/getFirebaseAdmin"; 3 | 4 | describe("getFirebaseAdmin", () => { 5 | it("returns firebase admin client", () => 6 | expect( 7 | getFirebaseAdmin({ 8 | googleApplicationCredential: undefined, 9 | }), 10 | ).toBeTruthy()); 11 | }); 12 | -------------------------------------------------------------------------------- /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | version: 2 2 | updates: 3 | - package-ecosystem: npm 4 | directory: "/" 5 | groups: 6 | nestjs: 7 | patterns: 8 | - "@nestjs*" 9 | schedule: 10 | interval: weekly 11 | - package-ecosystem: github-actions 12 | directory: "/" 13 | schedule: 14 | interval: weekly 15 | - package-ecosystem: devcontainers 16 | directory: "/.devcontainer" 17 | schedule: 18 | interval: weekly 19 | -------------------------------------------------------------------------------- /example/src/main.ts: -------------------------------------------------------------------------------- 1 | import { NestFactory } from "@nestjs/core"; 2 | import { 3 | FastifyAdapter, 4 | NestFastifyApplication, 5 | } from "@nestjs/platform-fastify"; 6 | import { AppModule } from "./app.module"; 7 | 8 | async function bootstrap() { 9 | const app = await NestFactory.create( 10 | AppModule, 11 | new FastifyAdapter(), 12 | ); 13 | await app.listen(3000); 14 | } 15 | bootstrap(); 16 | -------------------------------------------------------------------------------- /example/src/node/node.module.ts: -------------------------------------------------------------------------------- 1 | import { Module } from "@nestjs/common"; 2 | import { TypeOrmModule } from "@nestjs/typeorm"; 3 | import { Recipe } from "../recipes/models/recipe"; 4 | import { RecipesService } from "../recipes/recipes.service"; 5 | import { NodeResolver } from "./node.resolver"; 6 | 7 | @Module({ 8 | imports: [TypeOrmModule.forFeature([Recipe])], 9 | providers: [NodeResolver, RecipesService], 10 | }) 11 | export class NodeModule {} 12 | -------------------------------------------------------------------------------- /example/src/recipes/recipes.module.ts: -------------------------------------------------------------------------------- 1 | import { Module } from "@nestjs/common"; 2 | import { TypeOrmModule } from "@nestjs/typeorm"; 3 | import { Recipe } from "./models/recipe"; 4 | import { RecipesResolver } from "./recipes.resolver"; 5 | import { RecipesService } from "./recipes.service"; 6 | 7 | @Module({ 8 | imports: [TypeOrmModule.forFeature([Recipe])], 9 | providers: [RecipesResolver, RecipesService], 10 | }) 11 | export class RecipesModule {} 12 | -------------------------------------------------------------------------------- /example/src/notify/notify.service.ts: -------------------------------------------------------------------------------- 1 | import { Injectable } from "@nestjs/common"; 2 | import { IncomingWebhook, IncomingWebhookSendArguments } from "@slack/webhook"; 3 | import { InjectSlack } from "nestjs-slack-webhook"; 4 | 5 | @Injectable() 6 | export class NotifyService { 7 | constructor(@InjectSlack() private readonly slack: IncomingWebhook) {} 8 | 9 | async notify(args: IncomingWebhookSendArguments) { 10 | await this.slack.send(args); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /example/src/testing/slack.ts: -------------------------------------------------------------------------------- 1 | import { jest } from "@jest/globals"; 2 | import { Provider } from "@nestjs/common"; 3 | import { IncomingWebhook } from "@slack/webhook"; 4 | import { SLACK_TOKEN } from "nestjs-slack-webhook"; 5 | 6 | export function createSlackServiceMock(): Provider> { 7 | return { 8 | provide: SLACK_TOKEN, 9 | useValue: { 10 | send: jest 11 | .fn() 12 | .mockResolvedValue({ text: "ok" }), 13 | }, 14 | }; 15 | } 16 | -------------------------------------------------------------------------------- /packages/nestjs-slack-webhook/src/createSlackProvider.ts: -------------------------------------------------------------------------------- 1 | import { Provider } from "@nestjs/common"; 2 | import { IncomingWebhook } from "@slack/webhook"; 3 | import { getSlackClient } from "./getSlackClient"; 4 | import { SLACK_TOKEN } from "./slackConstants"; 5 | import { SlackOptions } from "./slackOptions"; 6 | 7 | export function createSlackProvider( 8 | options: SlackOptions, 9 | ): Provider { 10 | return { 11 | provide: SLACK_TOKEN, 12 | useValue: getSlackClient(options), 13 | }; 14 | } 15 | -------------------------------------------------------------------------------- /.github/release.yml: -------------------------------------------------------------------------------- 1 | # .github/release.yml 2 | 3 | changelog: 4 | exclude: 5 | labels: 6 | - ignore-for-release 7 | authors: 8 | - octocat 9 | categories: 10 | - title: ':boom: Type: Breaking Change' 11 | labels: 12 | - 'Type: Breaking Change' 13 | - title: ':bug: Type: Bug' 14 | labels: 15 | - 'Type: Bug' 16 | - title: ':rocket: Type: Feature' 17 | labels: 18 | - 'Type: Feature' 19 | - title: Other Changes 20 | labels: 21 | - '*' 22 | -------------------------------------------------------------------------------- /example/src/notify/notify.controller.ts: -------------------------------------------------------------------------------- 1 | import { Controller, Get } from "@nestjs/common"; 2 | import { IncomingWebhookSendArguments } from "@slack/webhook"; 3 | import { NotifyService } from "./notify.service"; 4 | 5 | @Controller("notify") 6 | export class NotifyController { 7 | constructor(private readonly notifyService: NotifyService) {} 8 | 9 | @Get() 10 | async notifyToSlack() { 11 | const args: IncomingWebhookSendArguments = { 12 | text: "Hello Slack!", 13 | }; 14 | return this.notifyService.notify(args); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /packages/nestjs-graphql-relay/src/orderBy.input.ts: -------------------------------------------------------------------------------- 1 | import { Field, InputType, registerEnumType } from "@nestjs/graphql"; 2 | 3 | export enum OrderByDirection { 4 | ASC = "ASC", 5 | DESC = "DESC", 6 | } 7 | 8 | registerEnumType(OrderByDirection, { name: "OrderByDirection" }); 9 | 10 | @InputType() 11 | export class OrderByInput { 12 | @Field(() => OrderByDirection, { nullable: true }) 13 | readonly createdAt?: OrderByDirection; 14 | 15 | @Field(() => OrderByDirection, { nullable: true }) 16 | readonly updatedAt?: OrderByDirection; 17 | } 18 | -------------------------------------------------------------------------------- /packages/nestjs-graphql-relay/src/pageInfo.ts: -------------------------------------------------------------------------------- 1 | import { Field, ObjectType } from "@nestjs/graphql"; 2 | import type { PageInfo as IPageInfo } from "graphql-relay"; 3 | 4 | @ObjectType() 5 | export class PageInfo implements IPageInfo { 6 | @Field(() => String, { nullable: true }) 7 | readonly startCursor: string | null; 8 | @Field(() => String, { nullable: true }) 9 | readonly endCursor: string | null; 10 | @Field(() => Boolean) 11 | readonly hasPreviousPage: boolean; 12 | @Field(() => Boolean) 13 | readonly hasNextPage: boolean; 14 | } 15 | -------------------------------------------------------------------------------- /.github/mergeable.yml: -------------------------------------------------------------------------------- 1 | version: 2 2 | mergeable: 3 | - when: pull_request.*, pull_request_review.* 4 | validate: 5 | - do: title 6 | must_exclude: 7 | regex: ^\[WIP\] 8 | message: This is work in progress. Do not merge yet. 9 | - do: description 10 | must_exclude: 11 | regex: TBA 12 | message: This is default templates yet. 13 | no_empty: 14 | enabled: true 15 | message: must include specs 16 | - do: label 17 | must_include: 18 | regex: ^Type 19 | message: must include types 20 | -------------------------------------------------------------------------------- /.github/workflows/actionlint.yml: -------------------------------------------------------------------------------- 1 | name: actionlint 2 | permissions: 3 | contents: read 4 | pull-requests: write 5 | 6 | on: 7 | pull_request: 8 | paths: 9 | - ".github/actions/**" 10 | - ".github/workflows/**" 11 | 12 | concurrency: 13 | group: ${{ github.workflow }}-${{ github.ref }} 14 | cancel-in-progress: true 15 | 16 | jobs: 17 | actionlint: 18 | runs-on: ubuntu-22.04 19 | steps: 20 | - uses: actions/checkout@v5 21 | - uses: reviewdog/action-actionlint@v1 22 | with: 23 | reporter: github-pr-review 24 | fail_on_error: true 25 | -------------------------------------------------------------------------------- /packages/nestjs-zendesk/src/zendesk.interface.ts: -------------------------------------------------------------------------------- 1 | import type { 2 | FactoryProvider, 3 | ModuleMetadata, 4 | Type, 5 | } from "@nestjs/common/interfaces"; 6 | import type { ZendeskClientOptions } from "node-zendesk"; 7 | 8 | export interface ZendeskOptionsFactory { 9 | createOptions(): Promise | ZendeskClientOptions; 10 | } 11 | 12 | export interface ZendeskAsyncOptions extends Pick { 13 | inject?: FactoryProvider["inject"]; 14 | useClass?: Type; 15 | useExisting?: Type; 16 | useFactory?: FactoryProvider["useFactory"]; 17 | } 18 | -------------------------------------------------------------------------------- /example/src/recipes/dto/recipes.input.ts: -------------------------------------------------------------------------------- 1 | import { 2 | ArgsType, 3 | Field, 4 | InputType, 5 | PartialType, 6 | PickType, 7 | } from "@nestjs/graphql"; 8 | import { ConnectionArgs, OrderByInput } from "nestjs-graphql-relay"; 9 | import { Recipe } from "../models/recipe"; 10 | 11 | @InputType() 12 | export class RecipeWhereInput extends PartialType( 13 | PickType(Recipe, ["title"], InputType), 14 | ) {} 15 | 16 | @ArgsType() 17 | export class RecipesConnectionArgs extends ConnectionArgs { 18 | @Field(() => RecipeWhereInput, { nullable: true }) 19 | readonly where?: RecipeWhereInput; 20 | 21 | @Field(() => OrderByInput, { nullable: true }) 22 | readonly orderBy?: OrderByInput; 23 | } 24 | -------------------------------------------------------------------------------- /SECURITY.md: -------------------------------------------------------------------------------- 1 | # Security Policy 2 | 3 | ## Supported Versions 4 | 5 | Use this section to tell people about which versions of your project are 6 | currently being supported with security updates. 7 | 8 | | Version | Supported | 9 | | ------- | ------------------ | 10 | | 5.1.x | :white_check_mark: | 11 | | 5.0.x | :x: | 12 | | 4.0.x | :white_check_mark: | 13 | | < 4.0 | :x: | 14 | 15 | ## Reporting a Vulnerability 16 | 17 | Use this section to tell people how to report a vulnerability. 18 | 19 | Tell them where to go, how often they can expect to get an update on a reported 20 | vulnerability, what to expect if the vulnerability is accepted or declined, etc. 21 | -------------------------------------------------------------------------------- /packages/nestjs-slack-webhook/__tests__/getSlackClient.test.ts: -------------------------------------------------------------------------------- 1 | import { describe, expect, it } from "@jest/globals"; 2 | import { IncomingWebhook } from "@slack/webhook"; 3 | import { getSlackClient } from "./../src/getSlackClient"; 4 | 5 | describe("getSlackClient", () => { 6 | const url = "SLACK_WEBHOOK_URL"; 7 | 8 | it("returns slack client", () => { 9 | const slackClient = getSlackClient({ url }); 10 | expect(slackClient).toBeInstanceOf(IncomingWebhook); 11 | }); 12 | 13 | it("returns slack client with custom options", () => { 14 | const slackClient = getSlackClient({ 15 | url, 16 | username: "test_user", 17 | }); 18 | 19 | expect(slackClient).toBeInstanceOf(IncomingWebhook); 20 | }); 21 | }); 22 | -------------------------------------------------------------------------------- /packages/nestjs-slack-webhook/src/slackOptions.ts: -------------------------------------------------------------------------------- 1 | import type { 2 | FactoryProvider, 3 | ModuleMetadata, 4 | Type, 5 | } from "@nestjs/common/interfaces"; 6 | import { IncomingWebhookDefaultArguments } from "@slack/webhook"; 7 | 8 | export interface SlackOptions extends IncomingWebhookDefaultArguments { 9 | url: string; 10 | } 11 | 12 | export interface SlackOptionsFactory { 13 | createSlackOptions(): Promise | SlackOptions; 14 | } 15 | 16 | export interface SlackAsyncOptions extends Pick { 17 | inject?: FactoryProvider["inject"]; 18 | useClass?: Type; 19 | useExisting?: Type; 20 | useFactory?: FactoryProvider["useFactory"]; 21 | } 22 | -------------------------------------------------------------------------------- /packages/nestjs-slack-webhook/src/slackModule.ts: -------------------------------------------------------------------------------- 1 | import { DynamicModule, Module } from "@nestjs/common"; 2 | import { SlackCoreModule } from "./slackCoreModule"; 3 | import { SlackAsyncOptions, SlackOptions } from "./slackOptions"; 4 | 5 | @Module({}) 6 | // biome-ignore lint/complexity/noStaticOnlyClass: NestJS module 7 | export class SlackModule { 8 | public static forRoot(options: SlackOptions): DynamicModule { 9 | return { 10 | module: SlackModule, 11 | imports: [SlackCoreModule.forRoot(options)], 12 | }; 13 | } 14 | 15 | public static forRootAsync(options: SlackAsyncOptions): DynamicModule { 16 | return { 17 | module: SlackModule, 18 | imports: [SlackCoreModule.forRootAsync(options)], 19 | }; 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /packages/nestjs-firebase/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "nestjs-firebase", 3 | "version": "11.0.1", 4 | "description": "@nestjs with firebase", 5 | "license": "MIT", 6 | "homepage": "https://github.com/g59/nestjs-plugins/tree/main/packages/nestjs-firebase", 7 | "main": "lib/index.js", 8 | "scripts": { 9 | "build": "npm run clean && tsc -p .", 10 | "clean": "tsc --build --clean", 11 | "lint": "tsc -p . --noEmit" 12 | }, 13 | "keywords": [ 14 | "nest", 15 | "firebase" 16 | ], 17 | "peerDependencies": { 18 | "@nestjs/common": "^11.0.0", 19 | "firebase-admin": "^13.4.0" 20 | }, 21 | "devDependencies": { 22 | "@google-cloud/firestore": "^8.0.0", 23 | "@google-cloud/storage": "^7.17.3" 24 | }, 25 | "types": "lib/index.d.ts" 26 | } 27 | -------------------------------------------------------------------------------- /example/src/app.controller.spec.ts: -------------------------------------------------------------------------------- 1 | import { beforeEach, describe, expect, it } from "@jest/globals"; 2 | import { Test, TestingModule } from "@nestjs/testing"; 3 | import { AppController } from "./app.controller"; 4 | import { AppService } from "./app.service"; 5 | 6 | describe("AppController", () => { 7 | let appController: AppController; 8 | 9 | beforeEach(async () => { 10 | const app: TestingModule = await Test.createTestingModule({ 11 | controllers: [AppController], 12 | providers: [AppService], 13 | }).compile(); 14 | 15 | appController = app.get(AppController); 16 | }); 17 | 18 | describe("root", () => { 19 | it('should return "Hello World!"', () => { 20 | expect(appController.getHello()).toBe("Hello World!"); 21 | }); 22 | }); 23 | }); 24 | -------------------------------------------------------------------------------- /example/src/recipes/models/recipe.ts: -------------------------------------------------------------------------------- 1 | import { Field, ID, ObjectType } from "@nestjs/graphql"; 2 | import { toGlobalId } from "graphql-relay"; 3 | import { Column, Entity, PrimaryColumn } from "typeorm"; 4 | import { Node } from "../../node/node"; 5 | 6 | @ObjectType({ implements: Node }) 7 | @Entity("recipes") 8 | export class Recipe implements Node { 9 | @PrimaryColumn() 10 | id: string; 11 | 12 | @Field() 13 | @Column() 14 | title: string; 15 | 16 | @Field({ nullable: true }) 17 | @Column({ nullable: true }) 18 | description?: string; 19 | 20 | @Field() 21 | creationDate: Date; 22 | 23 | @Field(() => [String]) 24 | ingredients: string[]; 25 | 26 | @Field(() => ID, { name: "id" }) 27 | get relayId(): string { 28 | return toGlobalId("Recipe", this.id); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /example/src/notify/notify.service.spec.ts: -------------------------------------------------------------------------------- 1 | import { beforeEach, describe, expect, it } from "@jest/globals"; 2 | import { Test, TestingModule } from "@nestjs/testing"; 3 | import { createSlackServiceMock } from "../testing/slack"; 4 | import { NotifyService } from "./notify.service"; 5 | 6 | describe("NotifyService", () => { 7 | let service: NotifyService; 8 | let slack: ReturnType; 9 | 10 | beforeEach(async () => { 11 | slack = createSlackServiceMock(); 12 | const module: TestingModule = await Test.createTestingModule({ 13 | providers: [NotifyService, slack], 14 | }).compile(); 15 | 16 | service = module.get(NotifyService); 17 | }); 18 | 19 | it("should be defined", () => { 20 | expect(service).toBeDefined(); 21 | }); 22 | }); 23 | -------------------------------------------------------------------------------- /example/src/zendesk/zendesk.service.spec.ts: -------------------------------------------------------------------------------- 1 | import { beforeEach, describe, expect, it, jest } from "@jest/globals"; 2 | import { Test, TestingModule } from "@nestjs/testing"; 3 | import { ZENDESK_TOKEN } from "nestjs-zendesk"; 4 | import { ZendeskService } from "./zendesk.service"; 5 | 6 | describe("ZendeskService", () => { 7 | let service: ZendeskService; 8 | 9 | beforeEach(async () => { 10 | const module: TestingModule = await Test.createTestingModule({ 11 | providers: [ 12 | ZendeskService, 13 | { 14 | provide: ZENDESK_TOKEN, 15 | useFactory: jest.fn(), 16 | }, 17 | ], 18 | }).compile(); 19 | 20 | service = module.get(ZendeskService); 21 | }); 22 | 23 | it("should be defined", () => expect(service).toBeDefined()); 24 | }); 25 | -------------------------------------------------------------------------------- /example/src/node/node.resolver.ts: -------------------------------------------------------------------------------- 1 | import { Args, ID, Query, Resolver } from "@nestjs/graphql"; 2 | import { fromGlobalId } from "graphql-relay"; 3 | import * as uuid from "uuid"; 4 | import { Node } from "../node/node"; 5 | import { RecipesService } from "../recipes/recipes.service"; 6 | 7 | @Resolver() 8 | export class NodeResolver { 9 | constructor(private readonly recipes: RecipesService) {} 10 | 11 | @Query(() => Node, { nullable: true }) 12 | async node(@Args({ name: "id", type: () => ID }) relayId: string) { 13 | const { id, type } = fromGlobalId(relayId); 14 | if (!uuid.validate(id)) { 15 | return null; 16 | } 17 | switch (type) { 18 | case "Recipe": 19 | return this.recipes.findById(id); 20 | default: 21 | break; 22 | } 23 | return null; 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /biome.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://biomejs.dev/schemas/2.2.3/schema.json", 3 | "assist": { 4 | "actions": { 5 | "source": { 6 | "organizeImports": "on" 7 | } 8 | } 9 | }, 10 | "files": { 11 | "includes": ["**", "!**/*.json"] 12 | }, 13 | "vcs": { 14 | "enabled": true, 15 | "clientKind": "git", 16 | "useIgnoreFile": true 17 | }, 18 | "formatter": { 19 | "indentStyle": "space" 20 | }, 21 | "linter": { 22 | "enabled": true, 23 | "rules": { 24 | "recommended": true, 25 | "style": { 26 | "useImportType": "off" 27 | }, 28 | "complexity": { 29 | "useLiteralKeys": "off" 30 | } 31 | } 32 | }, 33 | "javascript": { 34 | "parser": { 35 | "unsafeParameterDecoratorsEnabled": true 36 | } 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /.github/workflows/nodejs.yml: -------------------------------------------------------------------------------- 1 | name: Node CI 2 | permissions: 3 | contents: read 4 | 5 | on: 6 | push: 7 | 8 | jobs: 9 | build: 10 | timeout-minutes: 3 11 | runs-on: ubuntu-22.04 12 | strategy: 13 | matrix: 14 | node-version: [lts/*] 15 | 16 | steps: 17 | - uses: actions/checkout@v5 18 | - uses: biomejs/setup-biome@v2 19 | - run: biome ci . 20 | - name: Use Node.js ${{ matrix.node-version }} 21 | uses: actions/setup-node@v6 22 | with: 23 | node-version: ${{ matrix.node-version }} 24 | - run: npm ci 25 | - run: npm run build 26 | - run: npm run lint 27 | - run: npm test 28 | env: 29 | SLACK_WEBHOOK_URL: https://example.com 30 | CI: true 31 | - name: Codecov 32 | uses: codecov/codecov-action@v5 33 | -------------------------------------------------------------------------------- /example/src/recipes/recipes.service.ts: -------------------------------------------------------------------------------- 1 | import { Injectable } from "@nestjs/common"; 2 | import { InjectRepository } from "@nestjs/typeorm"; 3 | import { ConnectionArgs, findAndPaginate } from "nestjs-graphql-relay"; 4 | import { FindManyOptions, Repository } from "typeorm"; 5 | import { Recipe } from "./models/recipe"; 6 | 7 | @Injectable() 8 | export class RecipesService { 9 | constructor( 10 | @InjectRepository(Recipe) private readonly recipes: Repository, 11 | ) {} 12 | 13 | async findById(id: string) { 14 | return this.recipes.findOneOrFail({ where: { id } }); 15 | } 16 | 17 | async find( 18 | where: FindManyOptions["where"], 19 | order: FindManyOptions["order"], 20 | connArgs: ConnectionArgs, 21 | ) { 22 | return findAndPaginate({ where, order }, connArgs, this.recipes); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /packages/nestjs-zendesk/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "nestjs-zendesk", 3 | "version": "11.0.1", 4 | "description": "", 5 | "license": "MIT", 6 | "repository": { 7 | "type": "git", 8 | "url": "git+ssh://git@github.com/g59/nestjs-plugins.git" 9 | }, 10 | "author": "g59", 11 | "homepage": "https://github.com/g59/nestjs-plugins/tree/main/packages/nestjs-zendesk", 12 | "bugs": { 13 | "url": "https://github.com/g59/nestjs-plugins/issues" 14 | }, 15 | "main": "lib/index.js", 16 | "scripts": { 17 | "build": "npm run clean && tsc -p .", 18 | "clean": "tsc --build --clean", 19 | "lint": "tsc -p . --noEmit" 20 | }, 21 | "keywords": [ 22 | "nest", 23 | "zendesk" 24 | ], 25 | "peerDependencies": { 26 | "node-zendesk": "^6.0.1" 27 | }, 28 | "devDependencies": { 29 | "@nestjs/testing": "^11.1.9" 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /packages/nestjs-slack-webhook/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "nestjs-slack-webhook", 3 | "version": "11.0.1", 4 | "description": "Nest.js + slack-webhook", 5 | "license": "MIT", 6 | "repository": { 7 | "type": "git", 8 | "url": "git+ssh://git@github.com/g59/nestjs-plugins.git" 9 | }, 10 | "homepage": "https://github.com/g59/nestjs-plugins/tree/main/packages/nestjs-slack-webhook", 11 | "bugs": { 12 | "url": "https://github.com/g59/nestjs-plugins/issues" 13 | }, 14 | "main": "lib/index.js", 15 | "scripts": { 16 | "build": "npm run clean && tsc -p .", 17 | "clean": "tsc --build --clean", 18 | "lint": "tsc -p . --noEmit" 19 | }, 20 | "keywords": [ 21 | "nest", 22 | "slack-webhook" 23 | ], 24 | "peerDependencies": { 25 | "@nestjs/common": "^11.0.0", 26 | "@slack/webhook": "^7.0.6" 27 | }, 28 | "types": "lib/index.d.ts" 29 | } 30 | -------------------------------------------------------------------------------- /example/__tests__/app.e2e-spec.ts: -------------------------------------------------------------------------------- 1 | import { afterEach, beforeAll, describe, expect, it } from "@jest/globals"; 2 | import { 3 | FastifyAdapter, 4 | NestFastifyApplication, 5 | } from "@nestjs/platform-fastify"; 6 | import { Test, TestingModule } from "@nestjs/testing"; 7 | import { AppModule } from "../src/app.module"; 8 | 9 | describe("app (e2e)", () => { 10 | let app: NestFastifyApplication; 11 | 12 | beforeAll(async () => { 13 | const moduleFixture: TestingModule = await Test.createTestingModule({ 14 | imports: [AppModule], 15 | }).compile(); 16 | 17 | app = moduleFixture.createNestApplication( 18 | new FastifyAdapter(), 19 | ); 20 | await app.init(); 21 | }); 22 | 23 | afterEach(() => app.close()); 24 | 25 | // TODO fix https://github.com/nestjs/graphql/issues/2307 26 | it("defined", () => expect(app).toBeDefined()); 27 | }); 28 | -------------------------------------------------------------------------------- /packages/nestjs-firebase/README.md: -------------------------------------------------------------------------------- 1 | # nestjs-firebase 2 | 3 | ![Actions Status](https://github.com/g59/nestjs-plugins/workflows/Node%20CI/badge.svg) 4 | [![npm version](https://badge.fury.io/js/nestjs-firebase.svg)](https://badge.fury.io/js/nestjs-firebase) 5 | 6 | ## Install 7 | 8 | ``` 9 | npm install nestjs-firebase 10 | ``` 11 | 12 | ## Usage 13 | 14 | ```typescript 15 | @Module({ 16 | imports: [ 17 | FirebaseModule.forRoot({ 18 | googleApplicationCredential: "path/to/credential file.json", 19 | }), 20 | ], 21 | }) 22 | export class AppModule {} 23 | 24 | // using in service class 25 | export class Service { 26 | constructor( 27 | @InjectFirebaseAdmin() private readonly firebase: FirebaseAdmin, 28 | ) {} 29 | } 30 | ``` 31 | 32 | ## Contributing 33 | 34 | PRs accepted. 35 | 36 | ## License 37 | 38 | [MIT](https://github.com/g59/nestjs-plugins/blob/main/LICENSE) © g59 39 | -------------------------------------------------------------------------------- /example/src/recipes/recipes.service.spec.ts: -------------------------------------------------------------------------------- 1 | import { beforeEach, describe, expect, it } from "@jest/globals"; 2 | import { Test, TestingModule } from "@nestjs/testing"; 3 | import { getRepositoryToken } from "@nestjs/typeorm"; 4 | import { Repository } from "typeorm"; 5 | import { Recipe } from "./models/recipe"; 6 | import { RecipesService } from "./recipes.service"; 7 | 8 | describe("RecipesService", () => { 9 | let service: RecipesService; 10 | 11 | beforeEach(async () => { 12 | const module: TestingModule = await Test.createTestingModule({ 13 | providers: [ 14 | RecipesService, 15 | { 16 | provide: getRepositoryToken(Recipe), 17 | useClass: Repository, 18 | }, 19 | ], 20 | }).compile(); 21 | 22 | service = module.get(RecipesService); 23 | }); 24 | 25 | it("should be defined", () => expect(service).toBeDefined()); 26 | }); 27 | -------------------------------------------------------------------------------- /example/src/notify/notify.controller.spec.ts: -------------------------------------------------------------------------------- 1 | import { beforeEach, describe, expect, it } from "@jest/globals"; 2 | import { Test, TestingModule } from "@nestjs/testing"; 3 | import { createSlackServiceMock } from "../testing/slack"; 4 | import { NotifyController } from "./notify.controller"; 5 | import { NotifyService } from "./notify.service"; 6 | 7 | describe("Notify Controller", () => { 8 | let controller: NotifyController; 9 | let slack: ReturnType; 10 | 11 | beforeEach(async () => { 12 | slack = createSlackServiceMock(); 13 | const module: TestingModule = await Test.createTestingModule({ 14 | controllers: [NotifyController], 15 | providers: [NotifyService, slack], 16 | }).compile(); 17 | 18 | controller = module.get(NotifyController); 19 | }); 20 | 21 | it("should be defined", () => { 22 | expect(controller).toBeDefined(); 23 | }); 24 | }); 25 | -------------------------------------------------------------------------------- /packages/nestjs-zendesk/README.md: -------------------------------------------------------------------------------- 1 | # nestjs-zendesk 2 | 3 | ![Actions Status](https://github.com/g59/nestjs-plugins/workflows/Node%20CI/badge.svg) 4 | [![npm version](https://badge.fury.io/js/nestjs-zendesk.svg)](https://badge.fury.io/js/nestjs-zendesk) 5 | 6 | ## Install 7 | 8 | ``` 9 | npm install nestjs-zendesk 10 | ``` 11 | 12 | ## Usage 13 | 14 | ```typescript 15 | import * as zendesk from "node-zendesk"; 16 | 17 | @Module({ 18 | imports: [ 19 | zendeskModule.forRoot({ 20 | username: "name", 21 | token: "token", 22 | remoteUri: "http://example.com", 23 | }), 24 | ], 25 | }) 26 | export class AppModule {} 27 | 28 | // using in service class 29 | export class Service { 30 | constructor(@InjectZendesk() private readonly zendesk: zendesk.Client) {} 31 | } 32 | ``` 33 | 34 | ## Contributing 35 | 36 | PRs accepted. 37 | 38 | ## License 39 | 40 | [MIT](https://github.com/g59/nestjs-plugins/blob/main/LICENSE) © g59 41 | -------------------------------------------------------------------------------- /example/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "example", 3 | "version": "11.0.1", 4 | "private": true, 5 | "description": "nestjs-plugins examples", 6 | "license": "MIT", 7 | "author": "g59", 8 | "scripts": { 9 | "build": "nest build", 10 | "clean": "rimraf dist", 11 | "prebuild": "rimraf dist", 12 | "lint": "tsc -p . --noEmit", 13 | "start": "nest start --watch" 14 | }, 15 | "dependencies": { 16 | "@apollographql/graphql-playground-html": "^1.6.29", 17 | "@fastify/proxy-addr": "^5.1.0", 18 | "@nestjs/apollo": "^13.2.3", 19 | "@nestjs/cli": "^11.0.14", 20 | "@nestjs/config": "^4.0.2", 21 | "@nestjs/platform-fastify": "^11.1.9", 22 | "lodash.omit": "^4.5.0", 23 | "nestjs-firebase": "11.0.0", 24 | "nestjs-graphql-relay": "11.0.0", 25 | "nestjs-slack-webhook": "11.0.0", 26 | "nestjs-zendesk": "11.0.0" 27 | }, 28 | "devDependencies": { 29 | "@nestjs/testing": "^11.1.9" 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /example/src/node/node.resolver.spec.ts: -------------------------------------------------------------------------------- 1 | import { beforeEach, describe, expect, it } from "@jest/globals"; 2 | import { Test, TestingModule } from "@nestjs/testing"; 3 | import { getRepositoryToken } from "@nestjs/typeorm"; 4 | import { Repository } from "typeorm"; 5 | import { Recipe } from "../recipes/models/recipe"; 6 | import { RecipesService } from "../recipes/recipes.service"; 7 | import { NodeResolver } from "./node.resolver"; 8 | 9 | describe("NodeResolver", () => { 10 | let resolver: NodeResolver; 11 | 12 | beforeEach(async () => { 13 | const module: TestingModule = await Test.createTestingModule({ 14 | providers: [ 15 | NodeResolver, 16 | RecipesService, 17 | { 18 | provide: getRepositoryToken(Recipe), 19 | useClass: Repository, 20 | }, 21 | ], 22 | }).compile(); 23 | 24 | resolver = module.get(NodeResolver); 25 | }); 26 | 27 | it("should be defined", () => expect(resolver).toBeDefined()); 28 | }); 29 | -------------------------------------------------------------------------------- /example/src/recipes/recipes.resolver.spec.ts: -------------------------------------------------------------------------------- 1 | import { beforeEach, describe, expect, it } from "@jest/globals"; 2 | import { Test, TestingModule } from "@nestjs/testing"; 3 | import { getRepositoryToken } from "@nestjs/typeorm"; 4 | import { Repository } from "typeorm"; 5 | import { Recipe } from "./models/recipe"; 6 | import { RecipesResolver } from "./recipes.resolver"; 7 | import { RecipesService } from "./recipes.service"; 8 | 9 | describe("RecipesResolver", () => { 10 | let resolver: RecipesResolver; 11 | 12 | beforeEach(async () => { 13 | const module: TestingModule = await Test.createTestingModule({ 14 | providers: [ 15 | RecipesResolver, 16 | RecipesService, 17 | { 18 | provide: getRepositoryToken(Recipe), 19 | useClass: Repository, 20 | }, 21 | ], 22 | }).compile(); 23 | 24 | resolver = module.get(RecipesResolver); 25 | }); 26 | 27 | it("should be defined", () => expect(resolver).toBeDefined()); 28 | }); 29 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://json.schemastore.org/tsconfig", 3 | "compilerOptions": { 4 | "baseUrl": ".", 5 | "declaration": true, 6 | "emitDecoratorMetadata": true, 7 | "esModuleInterop": true, 8 | "experimentalDecorators": true, 9 | "importHelpers": true, 10 | "module": "commonjs", 11 | "noEmit": true, 12 | "noFallthroughCasesInSwitch": true, 13 | "noImplicitReturns": true, 14 | "noUnusedLocals": true, 15 | "noUnusedParameters": true, 16 | "outDir": "./lib", 17 | "paths": { 18 | "nestjs-firebase": [ 19 | "packages/nestjs-firebase/src" 20 | ], 21 | "nestjs-graphql-relay": [ 22 | "packages/nestjs-graphql-relay/src" 23 | ], 24 | "nestjs-slack-webhook": [ 25 | "packages/nestjs-slack-webhook/src" 26 | ], 27 | "nestjs-zendesk": [ 28 | "packages/nestjs-zendesk/src" 29 | ] 30 | }, 31 | "removeComments": true, 32 | "skipLibCheck": true, 33 | "sourceMap": true, 34 | "strict": true, 35 | "strictPropertyInitialization": false, 36 | "target": "ESNext" 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /packages/nestjs-slack-webhook/README.md: -------------------------------------------------------------------------------- 1 | # nestjs-slack-webhook 2 | 3 | ![Actions Status](https://github.com/g59/nestjs-plugins/workflows/Node%20CI/badge.svg) 4 | [![npm version](https://badge.fury.io/js/nestjs-slack-webhook.svg)](https://badge.fury.io/js/nestjs-slack-webhook) 5 | 6 | Nest.js + 7 | [Slack Incoming Webhook](https://github.com/slackapi/node-slack-sdk/tree/main/packages/webhook) 8 | 9 | ## Install 10 | 11 | ``` 12 | npm install nestjs-slack-webhook 13 | ``` 14 | 15 | ## Usage 16 | 17 | ```typescript 18 | @Module({ 19 | imports: [ 20 | SlackModule.forRoot({ 21 | url: "SLACK_WEBHOOK_URL", // ref: https://api.slack.com/messaging/webhooks#posting_with_webhooks 22 | }), 23 | ], 24 | }) 25 | export class AppModule {} 26 | ``` 27 | 28 | Inject IncomingWebhook instance 29 | 30 | ```typescript 31 | @Injectable() 32 | export class AppService { 33 | constructor( 34 | @InjectSlack() private readonly slack: IncomingWebhook, 35 | ) {} 36 | } 37 | ``` 38 | 39 | ## Contributing 40 | 41 | PRs accepted. 42 | 43 | ## License 44 | 45 | [MIT](https://github.com/g59/nestjs-plugins/blob/main/LICENSE) © g59 46 | -------------------------------------------------------------------------------- /packages/nestjs-firebase/src/util/getFirebaseAdmin.ts: -------------------------------------------------------------------------------- 1 | import * as admin from "firebase-admin"; 2 | import { FirebaseAdmin, FirebaseModuleOptions } from "../firebase.interface"; 3 | 4 | const createInstances = ( 5 | app: admin.app.App, 6 | initDatabase = false, 7 | ): FirebaseAdmin => ({ 8 | auth: app.auth(), 9 | messaging: app.messaging(), 10 | firestore: app.firestore(), 11 | database: initDatabase ? app.database() : undefined, 12 | storage: app.storage(), 13 | remoteConfig: app.remoteConfig(), 14 | }); 15 | 16 | export const getFirebaseAdmin = ( 17 | options?: FirebaseModuleOptions, 18 | ): FirebaseAdmin => { 19 | if (!options || Object.values(options).filter((v) => !!v).length === 0) { 20 | return createInstances(admin.initializeApp()); 21 | } 22 | const { googleApplicationCredential: serviceAccountPath, ...appOptions } = 23 | options; 24 | return createInstances( 25 | admin.initializeApp({ 26 | credential: serviceAccountPath 27 | ? admin.credential.cert(serviceAccountPath) 28 | : undefined, 29 | ...appOptions, 30 | }), 31 | !!appOptions.databaseURL, 32 | ); 33 | }; 34 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019 - 2020 g59 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /.github/workflows/npm-publish-packages.yml: -------------------------------------------------------------------------------- 1 | # This workflow will run tests using node and then publish a package to GitHub Packages when a release is created 2 | # For more information see: https://help.github.com/actions/language-and-framework-guides/publishing-nodejs-packages 3 | 4 | name: Node.js Package 5 | permissions: 6 | contents: read 7 | 8 | on: 9 | release: 10 | types: [created] 11 | 12 | jobs: 13 | build: 14 | runs-on: ubuntu-22.04 15 | steps: 16 | - uses: actions/checkout@v5 17 | - uses: actions/setup-node@v6 18 | with: 19 | node-version: lts/* 20 | - run: npm ci 21 | - run: npm run build 22 | - run: npm test 23 | env: 24 | SLACK_WEBHOOK_URL: https://example.com 25 | 26 | publish-gpr: 27 | needs: build 28 | runs-on: ubuntu-22.04 29 | steps: 30 | - uses: actions/checkout@v5 31 | - uses: actions/setup-node@v6 32 | with: 33 | node-version: lts/* 34 | registry-url: "https://registry.npmjs.org" 35 | - run: npm ci 36 | - run: npm run build 37 | - run: npm publish --workspaces 38 | env: 39 | NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} 40 | -------------------------------------------------------------------------------- /packages/nestjs-graphql-relay/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "nestjs-graphql-relay", 3 | "version": "11.0.1", 4 | "description": "@nestjs/graphql + graphql-relay + typeorm", 5 | "license": "MIT", 6 | "repository": { 7 | "type": "git", 8 | "url": "git+ssh://git@github.com/g59/nestjs-plugins.git" 9 | }, 10 | "homepage": "https://github.com/g59/nestjs-plugins/tree/main/packages/nestjs-graphql-relay", 11 | "bugs": { 12 | "url": "https://github.com/g59/nestjs-plugins/issues" 13 | }, 14 | "main": "lib/index.js", 15 | "scripts": { 16 | "build": "npm run clean && tsc -p .", 17 | "clean": "tsc --build --clean", 18 | "lint": "tsc -p . --noEmit" 19 | }, 20 | "keywords": [ 21 | "nest", 22 | "graphql-relay", 23 | "typeorm" 24 | ], 25 | "peerDependencies": { 26 | "@apollo/gateway": "^2.11.2", 27 | "@nestjs/graphql": "^13.1.0", 28 | "@nestjs/typeorm": "^11.0.0", 29 | "graphql-relay": "^0.10.2", 30 | "ts-morph": "^25.0.0 || ^26.0.0", 31 | "class-validator": "^0.14.2" 32 | }, 33 | "devDependencies": { 34 | "@types/validator": "^13.15.10", 35 | "@types/ws": "^8.18.1", 36 | "sqlite3": "^5.1.7" 37 | }, 38 | "types": "lib/index.d.ts" 39 | } 40 | -------------------------------------------------------------------------------- /example/src/recipes/recipes.resolver.ts: -------------------------------------------------------------------------------- 1 | import { Args, Field, ObjectType, Query, Resolver } from "@nestjs/graphql"; 2 | import * as Relay from "graphql-relay"; 3 | import { PageInfo } from "nestjs-graphql-relay"; 4 | import { RecipesConnectionArgs } from "./dto/recipes.input"; 5 | import { Recipe } from "./models/recipe"; 6 | import { RecipesService } from "./recipes.service"; 7 | 8 | @ObjectType({ isAbstract: true }) 9 | abstract class RecipesEdge implements Relay.Edge { 10 | @Field(() => Recipe) 11 | readonly node: Recipe; 12 | 13 | @Field() 14 | readonly cursor: Relay.ConnectionCursor; 15 | } 16 | 17 | @ObjectType() 18 | export class RecipesConnection implements Relay.Connection { 19 | @Field() 20 | readonly pageInfo: PageInfo; 21 | 22 | @Field(() => [RecipesEdge]) 23 | readonly edges: Array>; 24 | } 25 | 26 | @Resolver("Recipes") 27 | export class RecipesResolver { 28 | constructor(private readonly recipesService: RecipesService) {} 29 | 30 | @Query(() => RecipesConnection) 31 | recipes( 32 | @Args() { where, orderBy, ...args }: RecipesConnectionArgs, 33 | ): Promise { 34 | return this.recipesService.find(where, undefined, args); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /packages/nestjs-slack-webhook/__tests__/injectSlack.test.ts: -------------------------------------------------------------------------------- 1 | import { beforeEach, describe, expect, it } from "@jest/globals"; 2 | import { Injectable } from "@nestjs/common"; 3 | import { Test, TestingModule } from "@nestjs/testing"; 4 | import { IncomingWebhook } from "@slack/webhook"; 5 | import { InjectSlack } from "../src/injectSlack"; 6 | import { SlackModule } from "../src/slackModule"; 7 | 8 | describe("InjectSlack", () => { 9 | const url = "SLACK_WEBHOOK_URL"; 10 | let module: TestingModule; 11 | 12 | @Injectable() 13 | class TestService { 14 | public constructor( 15 | @InjectSlack() public readonly slackClient: IncomingWebhook, 16 | ) {} 17 | } 18 | 19 | beforeEach(async () => { 20 | module = await Test.createTestingModule({ 21 | imports: [SlackModule.forRoot({ url })], 22 | providers: [TestService], 23 | }).compile(); 24 | }); 25 | 26 | describe("when decorating a class constructor parameter", () => { 27 | it("should inject the slack client", () => { 28 | const testService = module.get(TestService); 29 | expect(testService).toHaveProperty("slackClient"); 30 | expect(testService.slackClient).toBeInstanceOf(IncomingWebhook); 31 | }); 32 | }); 33 | }); 34 | -------------------------------------------------------------------------------- /.github/workflows/dependabot.yml: -------------------------------------------------------------------------------- 1 | name: Dependabot auto-merge 2 | on: 3 | pull_request: 4 | types: opened 5 | 6 | concurrency: 7 | group: ${{ github.workflow }}-${{ github.ref }} 8 | cancel-in-progress: true 9 | 10 | permissions: 11 | contents: write 12 | pull-requests: write 13 | repository-projects: read 14 | 15 | jobs: 16 | dependabot: 17 | runs-on: ubuntu-22.04 18 | if: github.actor == 'dependabot[bot]' 19 | steps: 20 | - name: Dependabot metadata 21 | id: metadata 22 | uses: dependabot/fetch-metadata@v2 23 | with: 24 | github-token: "${{ secrets.GITHUB_TOKEN }}" 25 | 26 | - name: Approve a PR 27 | if: steps.metadata.outputs.update-type == 'version-update:semver-patch' 28 | run: gh pr review --approve "$PR_URL" 29 | env: 30 | PR_URL: ${{github.event.pull_request.html_url}} 31 | GITHUB_TOKEN: ${{secrets.GITHUB_TOKEN}} 32 | 33 | - name: Enable auto-merge for Dependabot PRs 34 | if: steps.metadata.outputs.update-type == 'version-update:semver-patch' 35 | run: gh pr merge --auto --merge "$PR_URL" 36 | env: 37 | PR_URL: ${{github.event.pull_request.html_url}} 38 | GITHUB_TOKEN: ${{secrets.GITHUB_TOKEN}} 39 | -------------------------------------------------------------------------------- /packages/nestjs-graphql-relay/README.md: -------------------------------------------------------------------------------- 1 | # nestjs-graphql-relay 2 | 3 | ![Actions Status](https://github.com/g59/nestjs-plugins/workflows/Node%20CI/badge.svg) 4 | [![npm version](https://badge.fury.io/js/nestjs-graphql-relay.svg)](https://badge.fury.io/js/nestjs-graphql-relay) 5 | 6 | Nest.js + typeorm + graphql-relay inspired 7 | [nestjs-graphql-relay](https://github.com/kazekyo/nestjs-graphql-relay) 8 | 9 | ## Install 10 | 11 | ``` 12 | npm install nestjs-graphql-relay 13 | ``` 14 | 15 | ## Usage 16 | 17 | [example resolver](https://github.com/g59/nestjs-plugins/blob/main/example/src/recipes/recipes.resolver.ts) 18 | 19 | ```typescript 20 | @ObjectType({ isAbstract: true }) 21 | abstract class RecipesEdge implements Relay.Edge { 22 | @Field(() => Recipe) 23 | readonly node: Recipe; 24 | 25 | @Field() 26 | readonly cursor: Relay.ConnectionCursor; 27 | } 28 | 29 | @ObjectType() 30 | export class RecipesConnection implements Relay.Connection { 31 | @Field() 32 | readonly pageInfo: PageInfo; 33 | 34 | @Field(() => [RecipesEdge]) 35 | readonly edges: Array>; 36 | } 37 | ``` 38 | 39 | ## Contributing 40 | 41 | PRs accepted. 42 | 43 | ## License 44 | 45 | [MIT](https://github.com/g59/nestjs-plugins/blob/main/LICENSE) © g59 46 | -------------------------------------------------------------------------------- /packages/nestjs-firebase/src/firebase.interface.ts: -------------------------------------------------------------------------------- 1 | import type { Type } from "@nestjs/common"; 2 | import type { 3 | FactoryProvider, 4 | ModuleMetadata, 5 | } from "@nestjs/common/interfaces"; 6 | import * as firebaseAdmin from "firebase-admin"; 7 | import { AppOptions } from "firebase-admin"; 8 | 9 | export type FirebaseModuleOptions = { 10 | googleApplicationCredential?: string | firebaseAdmin.ServiceAccount; 11 | } & Omit; 12 | 13 | export type FirebaseModuleAsyncOptions = { 14 | useClass?: Type; 15 | useFactory?: ( 16 | ...args: unknown[] 17 | ) => Promise | FirebaseModuleOptions; 18 | inject?: FactoryProvider["inject"]; 19 | useExisting?: Type; 20 | } & Pick; 21 | 22 | export interface FirebaseModuleOptionsFactory { 23 | createFirebaseModuleOptions(): 24 | | Promise 25 | | FirebaseModuleOptions; 26 | } 27 | 28 | export interface FirebaseAdmin { 29 | auth: firebaseAdmin.auth.Auth; 30 | messaging: firebaseAdmin.messaging.Messaging; 31 | firestore: firebaseAdmin.firestore.Firestore; 32 | database?: firebaseAdmin.database.Database; 33 | storage: firebaseAdmin.storage.Storage; 34 | remoteConfig: firebaseAdmin.remoteConfig.RemoteConfig; 35 | } 36 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "nestjs-plugins", 3 | "private": true, 4 | "repository": "git@github.com:g59/nestjs-plugins.git", 5 | "author": "g59", 6 | "engines": { 7 | "npm": ">=10" 8 | }, 9 | "version": "10.0.0", 10 | "scripts": { 11 | "build": "npm run build --workspaces", 12 | "clean": "npm run clean --workspaces", 13 | "lint": "npm run lint --workspaces", 14 | "test": "dotenv -e example/.env.test jest" 15 | }, 16 | "devDependencies": { 17 | "@as-integrations/fastify": "^3.1.0", 18 | "@jest/globals": "^30.2.0", 19 | "@nestjs/testing": "^11.1.9", 20 | "dotenv-cli": "^11.0.0", 21 | "jest-mock-extended": "^4.0.0", 22 | "rimraf": "^6.1.2", 23 | "ts-jest": "^29.4.6" 24 | }, 25 | "jest": { 26 | "preset": "ts-jest", 27 | "collectCoverage": true, 28 | "collectCoverageFrom": [ 29 | "packages/*/src/*.ts" 30 | ], 31 | "testEnvironment": "node", 32 | "moduleNameMapper": { 33 | "^nestjs-firebase$": "/packages/nestjs-firebase/src", 34 | "^nestjs-graphql-relay$": "/packages/nestjs-graphql-relay/src", 35 | "^nestjs-slack-webhook$": "/packages/nestjs-slack-webhook/src", 36 | "^nestjs-zendesk$": "/packages/nestjs-zendesk/src" 37 | } 38 | }, 39 | "workspaces": [ 40 | "packages/*", 41 | "example" 42 | ], 43 | "packageManager": "npm@11.0.0+sha512.11dff29565d2297c74e7c594a9762581bde969f0aa5cbe6f5b3644bf008a16c065ece61094d9ffbb81125be38df8e1ba43eb8244b3d30c61eb797e9a2440e3ec" 44 | } 45 | -------------------------------------------------------------------------------- /example/src/schema.gql: -------------------------------------------------------------------------------- 1 | # ------------------------------------------------------ 2 | # THIS FILE WAS AUTOMATICALLY GENERATED (DO NOT MODIFY) 3 | # ------------------------------------------------------ 4 | 5 | interface Node { 6 | id: ID! 7 | } 8 | 9 | type Recipe implements Node { 10 | id: ID! 11 | title: String! 12 | description: String 13 | creationDate: DateTime! 14 | ingredients: [String!]! 15 | } 16 | 17 | """ 18 | A date-time string at UTC, such as 2019-12-03T09:54:33Z, compliant with the date-time format. 19 | """ 20 | scalar DateTime 21 | 22 | type PageInfo { 23 | startCursor: String 24 | endCursor: String 25 | hasPreviousPage: Boolean! 26 | hasNextPage: Boolean! 27 | } 28 | 29 | type RecipesConnection { 30 | pageInfo: PageInfo! 31 | edges: [RecipesEdge!]! 32 | } 33 | 34 | type RecipesEdge { 35 | node: Recipe! 36 | cursor: String! 37 | } 38 | 39 | type Query { 40 | node(id: ID!): Node 41 | recipes( 42 | """ 43 | Paginate before opaque cursor 44 | """ 45 | before: String 46 | 47 | """ 48 | Paginate after opaque cursor 49 | """ 50 | after: String 51 | 52 | """ 53 | Paginate first 54 | """ 55 | first: Int 56 | 57 | """ 58 | Paginate last 59 | """ 60 | last: Int 61 | where: RecipeWhereInput 62 | orderBy: OrderByInput 63 | ): RecipesConnection! 64 | } 65 | 66 | input RecipeWhereInput { 67 | title: String 68 | } 69 | 70 | input OrderByInput { 71 | createdAt: OrderByDirection 72 | updatedAt: OrderByDirection 73 | } 74 | 75 | enum OrderByDirection { 76 | ASC 77 | DESC 78 | } 79 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # nestjs-plugins 2 | 3 | [![Node CI](https://github.com/g59/nestjs-plugins/actions/workflows/nodejs.yml/badge.svg)](https://github.com/g59/nestjs-plugins/actions/workflows/nodejs.yml) 4 | [![codecov](https://codecov.io/gh/g59/nestjs-plugins/graph/badge.svg?token=KVABG274X8)](https://codecov.io/gh/g59/nestjs-plugins) 5 | 6 | ## Install 7 | 8 | ```sh 9 | npm install 10 | ``` 11 | 12 | ## Packages 13 | 14 | This repository is managed as monorepo. 15 | 16 | | Package | Version | 17 | | :---------------------------------------------------------- | :----------------------------------------------------------------------------------------------------------------- | 18 | | **[nestjs-firebase](./packages/nestjs-firebase)** | [![npm version](https://badge.fury.io/js/nestjs-firebase.svg)](https://badge.fury.io/js/nestjs-firebase) | 19 | | **[nestjs-graphql-relay](./packages/nestjs-graphql-relay)** | [![npm version](https://badge.fury.io/js/nestjs-graphql-relay.svg)](https://badge.fury.io/js/nestjs-graphql-relay) | 20 | | **[nestjs-slack-webhook](./packages/nestjs-slack-webhook)** | [![npm version](https://badge.fury.io/js/nestjs-slack-webhook.svg)](https://badge.fury.io/js/nestjs-slack-webhook) | 21 | | **[nestjs-zendesk](./packages/nestjs-zendesk)** | [![npm version](https://badge.fury.io/js/nestjs-zendesk.svg)](https://badge.fury.io/js/nestjs-zendesk) | 22 | 23 | ## Usage 24 | 25 | ```sh 26 | # recommend 27 | pre-commit install 28 | npm run start:dev --workspace example 29 | ``` 30 | 31 | ## Contributing 32 | 33 | PRs accepted. 34 | 35 | ## License 36 | 37 | [MIT](./LICENSE) © g59 38 | -------------------------------------------------------------------------------- /dummy.firebase.amin.key.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "service_account", 3 | "project_id": "project_id", 4 | "private_key_id": "aaaaaaaaaabbbbbbbbbbccccccccccdddddddddd", 5 | "private_key": "-----BEGIN RSA PRIVATE KEY-----\nMIIEpAIBAAKCAQEAwJENcRev+eXZKvhhWLiV3Lz2MvO+naQRHo59g3vaNQnbgyduN/L4krlr\nJ5c6FiikXdtJNb/QrsAHSyJWCu8j3T9CruiwbidGAk2W0RuViTVspjHUTsIHExx9euWM0Uom\nGvYkoqXahdhPL/zViVSJt+Rt8bHLsMvpb8RquTIb9iKY3SMV2tCofNmyCSgVbghq/y7lKORt\nV/IRguWs6R22fbkb0r2MCYoNAbZ9dqnbRIFNZBC7itYtUoTEresRWcyFMh0zfAIJycWOJlVL\nDLqkY2SmIx8u7fuysCg1wcoSZoStuDq02nZEMw1dx8HGzE0hynpHlloRLByuIuOAfMCCYwID\nAQABAoIBADFtihu7TspAO0wSUTpqttzgC/nsIsNn95T2UjVLtyjiDNxPZLUrwq42tdCFur0x\nVW9Z+CK5x6DzXWvltlw8IeKKeF1ZEOBVaFzy+YFXKTz835SROcO1fgdjyrme7lRSShGlmKW/\nGKY+baUNquoDLw5qreXaE0SgMp0jt5ktyYuVxvhLDeV4omw2u6waoGkifsGm8lYivg5l3VR7\nw2IVOvYZTt4BuSYVwOM+qjwaS1vtL7gv0SUjrj85Ja6zERRdFiITDhZw6nsvacr9/+/aut9E\naL/koSSb62g5fntQMEwoT4hRnjPnAedmorM9Rhddh2TB3ZKTBbMN1tUk3fJxOuECgYEA+z6l\neSaAcZ3qvwpntcXSpwwJ0SSmzLTH2RJNf+Ld3eBHiSvLTG53dWB7lJtF4R1KcIwf+KGcOFJv\nsnepzcZBylRvT8RrAAkV0s9OiVm1lXZyaepbLg4GGFJBPi8A6VIAj7zYknToRApdW0s1x/XX\nChewfJDckqsevTMovdbg8YkCgYEAxDYX+3mfvv/opo6HNNY3SfVunM+4vVJL+n8gWZ2w9kz3\nQ9Ub9YbRmI7iQaiVkO5xNuoG1n9bM+3Mnm84aQ1YeNT01YqeyQsipP5Wi+um0PzYTaBw9RO+\n8Gh6992OwlJiRtFk5WjalNWOxY4MU0ImnJwIfKQlUODvLmcixm68NYsCgYEAuAqI3jkk55Vd\nKvotREsX5wP7gPePM+7NYiZ1HNQL4Ab1f/bTojZdTV8Sx6YCR0fUiqMqnE+OBvfkGGBtw22S\nLesx6sWf99Ov58+x4Q0U5dpxL0Lb7d2Z+2Dtp+Z4jXFjNeeI4ae/qG/LOR/b0pE0J5F415ap\n7Mpq5v89vepUtrkCgYAjMXytu4v+q1Ikhc4UmRPDrUUQ1WVSd+9u19yKlnFGTFnRjej86hiw\nH3jPxBhHra0a53EgiilmsBGSnWpl1WH4EmJz5vBCKUAmjgQiBrueIqv9iHiaTNdjsanUyaWw\njyxXfXl2eI80QPXh02+8g1H/pzESgjK7Rg1AqnkfVH9nrwKBgQDJVxKBPTw9pigYMVt9iHrR\niCl9zQVjRMbWiPOc0J56+/5FZYm/AOGl9rfhQ9vGxXZYZiOP5FsNkwt05Y1UoAAH4B4VQwbL\nqod71qOcI0ywgZiIR87CYw40gzRfjWnN+YEEW1qfyoNLilEwJB8iB/T+ZePHGmJ4MmQ/cTn9\nxpdLXA==\n-----END RSA PRIVATE KEY-----\n", 6 | "client_email": "foo@project_id.iam.gserviceaccount.com" 7 | } 8 | -------------------------------------------------------------------------------- /packages/nestjs-zendesk/src/zendesk.module.spec.ts: -------------------------------------------------------------------------------- 1 | import { beforeAll, describe, expect, it } from "@jest/globals"; 2 | import { Test } from "@nestjs/testing"; 3 | import { ZendeskClientOptions } from "node-zendesk"; 4 | import { ZendeskModule } from "./"; 5 | 6 | describe("ZendeskModule", () => { 7 | let module: ZendeskModule; 8 | const options: ZendeskClientOptions = { 9 | username: "name", 10 | token: "token", 11 | endpointUri: "http://example.com", 12 | }; 13 | 14 | beforeAll(async () => { 15 | const moduleFixture = await Test.createTestingModule({ 16 | imports: [ZendeskModule], 17 | }).compile(); 18 | 19 | module = moduleFixture.get(ZendeskModule); 20 | }); 21 | 22 | it("defined", () => expect(module).toBeDefined()); 23 | 24 | it("forRoot", () => { 25 | const res = ZendeskModule.forRoot(options); 26 | 27 | expect(res.exports).toHaveLength(1); 28 | expect(res.imports).toBeUndefined(); 29 | expect(res.module).toBeDefined(); 30 | expect(res.providers).toHaveLength(1); 31 | }); 32 | 33 | it("forRootAsync", () => { 34 | const res = ZendeskModule.forRootAsync({}); 35 | expect(res.exports).toMatchInlineSnapshot(` 36 | [ 37 | { 38 | "inject": [ 39 | "ZENDESK_MODULE", 40 | ], 41 | "provide": "ZENDESK_TOKEN", 42 | "useFactory": [Function], 43 | }, 44 | ] 45 | `); 46 | expect(res.imports).toBeUndefined(); 47 | expect(res.providers).toMatchInlineSnapshot(` 48 | [ 49 | { 50 | "inject": [], 51 | "provide": "ZENDESK_MODULE", 52 | "useFactory": [Function], 53 | }, 54 | { 55 | "inject": undefined, 56 | "provide": undefined, 57 | "useClass": undefined, 58 | }, 59 | { 60 | "inject": [ 61 | "ZENDESK_MODULE", 62 | ], 63 | "provide": "ZENDESK_TOKEN", 64 | "useFactory": [Function], 65 | }, 66 | ] 67 | `); 68 | expect(res.module).toBeDefined(); 69 | }); 70 | 71 | it("forRootAsync with useFactory", () => { 72 | const res = ZendeskModule.forRootAsync({ useFactory: () => options }); 73 | expect(res.exports).toHaveLength(1); 74 | expect(res.imports).toBeUndefined(); 75 | expect(res.module).toBeDefined(); 76 | expect(res.providers).toHaveLength(2); 77 | }); 78 | }); 79 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | lib/ 2 | nestjs-plugins-test 3 | /nestjs-plugins 4 | .changelog/ 5 | 6 | ### https://raw.github.com/github/gitignore/6c87d249af5f2b3f8ab65ae0a2648682ee4e8a2d/Node.gitignore 7 | 8 | # Logs 9 | logs 10 | *.log 11 | npm-debug.log* 12 | yarn-debug.log* 13 | yarn-error.log* 14 | lerna-debug.log* 15 | 16 | # Diagnostic reports (https://nodejs.org/api/report.html) 17 | report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json 18 | 19 | # Runtime data 20 | pids 21 | *.pid 22 | *.seed 23 | *.pid.lock 24 | 25 | # Directory for instrumented libs generated by jscoverage/JSCover 26 | lib-cov 27 | 28 | # Coverage directory used by tools like istanbul 29 | coverage 30 | *.lcov 31 | 32 | # nyc test coverage 33 | .nyc_output 34 | 35 | # Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files) 36 | .grunt 37 | 38 | # Bower dependency directory (https://bower.io/) 39 | bower_components 40 | 41 | # node-waf configuration 42 | .lock-wscript 43 | 44 | # Compiled binary addons (https://nodejs.org/api/addons.html) 45 | build/Release 46 | 47 | # Dependency directories 48 | node_modules/ 49 | jspm_packages/ 50 | 51 | # TypeScript v1 declaration files 52 | typings/ 53 | 54 | # TypeScript cache 55 | *.tsbuildinfo 56 | 57 | # Optional npm cache directory 58 | .npm 59 | 60 | # Optional eslint cache 61 | .eslintcache 62 | 63 | # Microbundle cache 64 | .rpt2_cache/ 65 | .rts2_cache_cjs/ 66 | .rts2_cache_es/ 67 | .rts2_cache_umd/ 68 | 69 | # Optional REPL history 70 | .node_repl_history 71 | 72 | # Output of 'npm pack' 73 | *.tgz 74 | 75 | # Yarn Integrity file 76 | .yarn-integrity 77 | 78 | # dotenv environment variables file 79 | .env 80 | .env.test 81 | 82 | # parcel-bundler cache (https://parceljs.org/) 83 | .cache 84 | 85 | # Next.js build output 86 | .next 87 | 88 | # Nuxt.js build / generate output 89 | .nuxt 90 | dist 91 | 92 | # Gatsby files 93 | .cache/ 94 | # Comment in the public line in if your project uses Gatsby and not Next.js 95 | # https://nextjs.org/blog/next-9-1#public-directory-support 96 | # public 97 | 98 | # vuepress build output 99 | .vuepress/dist 100 | 101 | # Serverless directories 102 | .serverless/ 103 | 104 | # FuseBox cache 105 | .fusebox/ 106 | 107 | # DynamoDB Local files 108 | .dynamodb/ 109 | 110 | # TernJS port file 111 | .tern-port 112 | 113 | # Stores VSCode versions used for testing VSCode extensions 114 | .vscode-test 115 | 116 | 117 | -------------------------------------------------------------------------------- /packages/nestjs-zendesk/src/zendesk.module.ts: -------------------------------------------------------------------------------- 1 | import { DynamicModule, Global, Module, Provider } from "@nestjs/common"; 2 | import type { ClassProvider } from "@nestjs/common/interfaces"; 3 | import * as zendesk from "node-zendesk"; 4 | import { ZENDESK_MODULE, ZENDESK_TOKEN } from "./zendesk.constants"; 5 | import type { 6 | ZendeskAsyncOptions, 7 | ZendeskOptionsFactory, 8 | } from "./zendesk.interface"; 9 | 10 | function createProvider( 11 | options: zendesk.ZendeskClientOptions, 12 | ): Provider { 13 | return { 14 | provide: ZENDESK_TOKEN, 15 | useValue: zendesk.createClient(options), 16 | }; 17 | } 18 | 19 | function createAsyncOptionsProvider({ 20 | useFactory, 21 | useExisting, 22 | useClass, 23 | inject, 24 | }: ZendeskAsyncOptions): Provider { 25 | if (useFactory) { 26 | return { 27 | provide: ZENDESK_MODULE, 28 | useFactory, 29 | inject, 30 | }; 31 | } 32 | return { 33 | provide: ZENDESK_MODULE, 34 | inject: useExisting ? [useExisting] : useClass ? [useClass] : [], 35 | useFactory: (f: ZendeskOptionsFactory) => f.createOptions(), 36 | }; 37 | } 38 | 39 | function createAsyncProviders(options: ZendeskAsyncOptions): Provider[] { 40 | if (options.useExisting || options.useFactory) { 41 | return [createAsyncOptionsProvider(options)]; 42 | } 43 | return [ 44 | createAsyncOptionsProvider(options), 45 | { 46 | provide: options.useClass, 47 | useClass: options.useClass, 48 | inject: options.inject, 49 | } as ClassProvider, 50 | ]; 51 | } 52 | 53 | @Global() 54 | @Module({}) 55 | // biome-ignore lint/complexity/noStaticOnlyClass: NestJS module 56 | export class ZendeskModule { 57 | static forRoot(options: zendesk.ZendeskClientOptions): DynamicModule { 58 | const provider = createProvider(options); 59 | return { 60 | module: ZendeskModule, 61 | exports: [provider], 62 | providers: [provider], 63 | }; 64 | } 65 | 66 | static forRootAsync(options: ZendeskAsyncOptions): DynamicModule { 67 | const provider: Provider = { 68 | inject: [ZENDESK_MODULE], 69 | provide: ZENDESK_TOKEN, 70 | useFactory: (options: zendesk.ZendeskClientOptions) => 71 | zendesk.createClient(options), 72 | }; 73 | 74 | return { 75 | exports: [provider], 76 | imports: options.imports, 77 | module: ZendeskModule, 78 | providers: [...createAsyncProviders(options), provider], 79 | }; 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /.github/workflows/bump.yml: -------------------------------------------------------------------------------- 1 | name: Bump version 2 | 3 | on: 4 | workflow_dispatch: 5 | inputs: 6 | semver: 7 | description: "Which SemVer" 8 | required: true 9 | default: "patch" 10 | type: choice 11 | options: 12 | - major 13 | - minor 14 | - patch 15 | workflow_call: 16 | inputs: 17 | semver: 18 | description: The image_name to build for. 19 | required: true 20 | type: string 21 | jobs: 22 | bump: 23 | permissions: 24 | contents: read 25 | pull-requests: write 26 | runs-on: ubuntu-22.04 27 | steps: 28 | - uses: actions/checkout@v5 29 | 30 | - run: npm version ${{ inputs.semver }} --no-git-tag-version --workspaces 31 | 32 | - name: generate new version and save to env variable 33 | id: get_version 34 | run: | 35 | echo "NEW_VERSION=$(cat packages/nestjs-firebase/package.json | jq -r .version)" >> $GITHUB_OUTPUT 36 | 37 | - name: Generate release notes 38 | uses: actions/github-script@v8 39 | id: get_release_note 40 | env: 41 | NEW_VERSION: ${{steps.get_version.outputs.NEW_VERSION}} 42 | with: 43 | github-token: ${{secrets.GITHUB_TOKEN}} 44 | result-encoding: string 45 | script: | 46 | const notes = await github.rest.repos.generateReleaseNotes( 47 | { 48 | owner: context.repo.owner, 49 | repo: context.repo.repo, 50 | tag_name: `v${process.env.NEW_VERSION}`, 51 | } 52 | ); 53 | return notes.data.body; 54 | 55 | - run: | 56 | cat << EOF >> new 57 | ## v${{ steps.get_version.outputs.NEW_VERSION }} ($(date '+%Y-%m-%d')) 58 | ${{ steps.get_release_note.outputs.result }} 59 | EOF 60 | - run: cat new ./CHANGELOG.md > temp 61 | - run: mv temp ./CHANGELOG.md 62 | - run: rm new 63 | 64 | - name: Create Pull Request 65 | uses: peter-evans/create-pull-request@v7 66 | with: 67 | base: main 68 | branch: release-${{ steps.get_version.outputs.NEW_VERSION }} 69 | token: ${{secrets.GITHUB_TOKEN}} 70 | commit-message: "bump: v${{ steps.get_version.outputs.NEW_VERSION }}" 71 | body: ${{ steps.get_release_note.outputs.result }} 72 | title: "chore: bump v${{ steps.get_version.outputs.NEW_VERSION }}" 73 | draft: true 74 | milestone: "v${{ steps.get_version.outputs.NEW_VERSION }}" 75 | -------------------------------------------------------------------------------- /example/src/app.module.ts: -------------------------------------------------------------------------------- 1 | import { join } from "node:path"; 2 | import { ApolloDriver } from "@nestjs/apollo"; 3 | import { Module } from "@nestjs/common"; 4 | import { ConfigModule, ConfigService } from "@nestjs/config"; 5 | import { GraphQLModule } from "@nestjs/graphql"; 6 | import { TypeOrmModule } from "@nestjs/typeorm"; 7 | import { FirebaseModule } from "nestjs-firebase"; 8 | import { SlackModule } from "nestjs-slack-webhook"; 9 | import { ZendeskModule } from "nestjs-zendesk"; 10 | import { AppController } from "./app.controller"; 11 | import { AppService } from "./app.service"; 12 | import slackConfig from "./config/slack"; 13 | import zendeskConfig from "./config/zendesk"; 14 | import { NodeModule } from "./node/node.module"; 15 | import { NotifyModule } from "./notify/notify.module"; 16 | import { RecipesModule } from "./recipes/recipes.module"; 17 | import { ZendeskModule as ZendeskWrapperModule } from "./zendesk/zendesk.module"; 18 | 19 | @Module({ 20 | imports: [ 21 | ConfigModule.forRoot({ 22 | ignoreEnvFile: true, 23 | load: [slackConfig, zendeskConfig], 24 | }), 25 | TypeOrmModule.forRoot({ 26 | type: "sqlite", 27 | database: "nestjs-plugins-test", 28 | entities: [join(__dirname, "./recipes/models/recipe.[t|j]s")], 29 | synchronize: true, 30 | }), 31 | FirebaseModule.forRoot({ 32 | googleApplicationCredential: join( 33 | __dirname, 34 | "../../dummy.firebase.amin.key.json", 35 | ), 36 | }), 37 | GraphQLModule.forRoot({ 38 | installSubscriptionHandlers: true, 39 | autoSchemaFile: join(__dirname, "./schema.gql"), 40 | playground: true, 41 | driver: ApolloDriver, 42 | }), 43 | SlackModule.forRootAsync({ 44 | imports: [ConfigModule], 45 | inject: [ConfigService], 46 | useFactory: (config: ConfigService) => { 47 | const slackConfig = config.get("slack"); 48 | if (!slackConfig) { 49 | throw new Error("Slack config not found"); 50 | } 51 | return slackConfig; 52 | }, 53 | }), 54 | ZendeskModule.forRootAsync({ 55 | imports: [ConfigModule], 56 | inject: [ConfigService], 57 | useFactory: (config: ConfigService) => { 58 | const zendeskConfig = config.get("zendesk"); 59 | if (!zendeskConfig) { 60 | throw new Error("Zendesk config not found"); 61 | } 62 | return zendeskConfig; 63 | }, 64 | }), 65 | NodeModule, 66 | RecipesModule, 67 | NotifyModule, 68 | ZendeskWrapperModule, 69 | ], 70 | controllers: [AppController], 71 | providers: [AppService], 72 | }) 73 | export class AppModule {} 74 | -------------------------------------------------------------------------------- /packages/nestjs-slack-webhook/src/slackCoreModule.ts: -------------------------------------------------------------------------------- 1 | import { DynamicModule, Global, Module, Provider } from "@nestjs/common"; 2 | import { ClassProvider } from "@nestjs/common/interfaces"; 3 | import { IncomingWebhook } from "@slack/webhook"; 4 | import { createSlackProvider } from "./createSlackProvider"; 5 | import { getSlackClient } from "./getSlackClient"; 6 | import { SLACK_MODULE, SLACK_TOKEN } from "./slackConstants"; 7 | import { 8 | SlackAsyncOptions, 9 | SlackOptions, 10 | SlackOptionsFactory, 11 | } from "./slackOptions"; 12 | 13 | @Global() 14 | @Module({}) 15 | // biome-ignore lint/complexity/noStaticOnlyClass: NestJS module 16 | export class SlackCoreModule { 17 | public static forRoot(options: SlackOptions): DynamicModule { 18 | const provider = createSlackProvider(options); 19 | 20 | return { 21 | exports: [provider], 22 | module: SlackCoreModule, 23 | providers: [provider], 24 | }; 25 | } 26 | 27 | static forRootAsync(options: SlackAsyncOptions): DynamicModule { 28 | const slackProvider: Provider = { 29 | inject: [SLACK_MODULE], 30 | provide: SLACK_TOKEN, 31 | useFactory: (slackOptions: SlackOptions) => getSlackClient(slackOptions), 32 | }; 33 | 34 | return { 35 | exports: [slackProvider], 36 | imports: options.imports, 37 | module: SlackCoreModule, 38 | providers: [ 39 | ...SlackCoreModule.createAsyncProviders(options), 40 | slackProvider, 41 | ], 42 | }; 43 | } 44 | 45 | private static createAsyncProviders(options: SlackAsyncOptions): Provider[] { 46 | if (options.useExisting || options.useFactory) { 47 | return [SlackCoreModule.createAsyncOptionsProvider(options)]; 48 | } 49 | return [ 50 | SlackCoreModule.createAsyncOptionsProvider(options), 51 | { 52 | provide: options.useClass, 53 | useClass: options.useClass, 54 | inject: options.inject, 55 | } as ClassProvider, 56 | ]; 57 | } 58 | 59 | private static createAsyncOptionsProvider( 60 | options: SlackAsyncOptions, 61 | ): Provider { 62 | if (options.useFactory) { 63 | return { 64 | inject: options.inject ?? [], 65 | provide: SLACK_MODULE, 66 | useFactory: options.useFactory, 67 | }; 68 | } 69 | return { 70 | inject: options.useExisting 71 | ? [options.useExisting] 72 | : options.useClass 73 | ? [options.useClass] 74 | : [], 75 | provide: SLACK_MODULE, 76 | useFactory: (optionsFactory: SlackOptionsFactory) => 77 | optionsFactory.createSlackOptions(), 78 | }; 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /packages/nestjs-firebase/src/firebase.module.spec.ts: -------------------------------------------------------------------------------- 1 | import * as path from "node:path"; 2 | import { describe, expect, it, jest } from "@jest/globals"; 3 | import { Test } from "@nestjs/testing"; 4 | import * as admin from "firebase-admin"; 5 | import { mock } from "jest-mock-extended"; 6 | import { FirebaseConstants } from "./firebase.constants"; 7 | import { 8 | FirebaseAdmin, 9 | FirebaseModuleOptions, 10 | FirebaseModuleOptionsFactory, 11 | } from "./firebase.interface"; 12 | import { FirebaseModule } from "./firebase.module"; 13 | 14 | describe("FirebaseModule", () => { 15 | jest.spyOn(admin, "initializeApp").mockReturnValue(mock()); 16 | 17 | const googleApplicationCredential = path.join( 18 | __dirname, 19 | "../../../dummy.firebase.amin.key.json", 20 | ); 21 | class TestService implements FirebaseModuleOptionsFactory { 22 | createFirebaseModuleOptions(): FirebaseModuleOptions { 23 | return { 24 | googleApplicationCredential, 25 | }; 26 | } 27 | } 28 | 29 | describe("forRoot", () => { 30 | it("should provide the firebase admin", async () => { 31 | const module = await Test.createTestingModule({ 32 | imports: [FirebaseModule.forRoot({ googleApplicationCredential })], 33 | }).compile(); 34 | 35 | const firebase = module.get( 36 | FirebaseConstants.FIREBASE_TOKEN, 37 | ); 38 | expect(firebase).toBeDefined(); 39 | }); 40 | }); 41 | 42 | describe("forRootAsync", () => { 43 | describe("when the `useFactory` option is used", () => { 44 | it("should provide the firebase admin", async () => { 45 | const module = await Test.createTestingModule({ 46 | imports: [ 47 | FirebaseModule.forRootAsync({ 48 | useFactory: () => ({ googleApplicationCredential }), 49 | }), 50 | ], 51 | }).compile(); 52 | 53 | const firebase = module.get( 54 | FirebaseConstants.FIREBASE_TOKEN, 55 | ); 56 | expect(firebase).toBeDefined(); 57 | }); 58 | }); 59 | describe("when the `useClass` option is used", () => { 60 | it("should provide firebase admin", async () => { 61 | const module = await Test.createTestingModule({ 62 | imports: [ 63 | FirebaseModule.forRootAsync({ 64 | useClass: TestService, 65 | }), 66 | ], 67 | }).compile(); 68 | 69 | const firebase = module.get( 70 | FirebaseConstants.FIREBASE_TOKEN, 71 | ); 72 | expect(firebase).toBeDefined(); 73 | }); 74 | }); 75 | }); 76 | }); 77 | -------------------------------------------------------------------------------- /packages/nestjs-graphql-relay/src/index.ts: -------------------------------------------------------------------------------- 1 | import * as Relay from "graphql-relay"; 2 | import { FindManyOptions, ObjectLiteral, Repository } from "typeorm"; 3 | import { ConnectionArgs } from "./connectionArgs"; 4 | 5 | export * from "./orderBy.input"; 6 | export * from "./pageInfo"; 7 | export { ConnectionArgs }; 8 | 9 | type PagingMeta = 10 | | { pagingType: "forward"; after?: string; first: number } 11 | | { pagingType: "backward"; before?: string; last: number } 12 | | { pagingType: "none" }; 13 | 14 | function getMeta({ 15 | first = 0, 16 | last = 0, 17 | after, 18 | before, 19 | }: ConnectionArgs): PagingMeta { 20 | const isForwardPaging = !!first || !!after; 21 | const isBackwardPaging = !!last || !!before; 22 | 23 | return isForwardPaging 24 | ? { pagingType: "forward", after, first } 25 | : isBackwardPaging 26 | ? { pagingType: "backward", before, last } 27 | : { pagingType: "none" }; 28 | } 29 | 30 | /* 31 | * Create a 'paging parameters' object with 'limit' and 'offset' fields based on the incoming 32 | * cursor-paging arguments. 33 | */ 34 | export function getPagingParameters(args: ConnectionArgs) { 35 | const meta = getMeta(args); 36 | 37 | switch (meta.pagingType) { 38 | case "forward": { 39 | let offset = 0; 40 | if (meta.after) { 41 | offset = Relay.cursorToOffset(meta.after) + 1; 42 | } 43 | 44 | if (Number.isNaN(offset)) { 45 | throw new Error("invalid before query"); 46 | } 47 | 48 | return { 49 | limit: meta.first, 50 | offset, 51 | }; 52 | } 53 | case "backward": { 54 | const { last, before } = meta; 55 | let limit = last; 56 | let offset = Relay.cursorToOffset(before || "") - last; 57 | 58 | if (Number.isNaN(offset)) { 59 | throw new Error("invalid before query"); 60 | } 61 | 62 | // Check to see if our before-page is underflowing past the 0th item 63 | if (offset < 0) { 64 | // Adjust the limit with the underflow value 65 | limit = Math.max(last + offset, 0); 66 | offset = 0; 67 | } 68 | 69 | return { offset, limit }; 70 | } 71 | default: 72 | return {}; 73 | } 74 | } 75 | 76 | export async function findAndPaginate( 77 | condition: FindManyOptions, 78 | connArgs: ConnectionArgs, 79 | repository: Repository, 80 | ) { 81 | const { limit, offset } = getPagingParameters(connArgs); 82 | const [entities, count] = await repository.findAndCount({ 83 | ...condition, 84 | skip: offset, 85 | take: limit, 86 | }); 87 | 88 | return Relay.connectionFromArraySlice(entities, connArgs, { 89 | arrayLength: count, 90 | sliceStart: offset || 0, 91 | }); 92 | } 93 | -------------------------------------------------------------------------------- /packages/nestjs-graphql-relay/src/connectionArgs.ts: -------------------------------------------------------------------------------- 1 | import { ArgsType, Field, Int } from "@nestjs/graphql"; 2 | import { 3 | Min, 4 | Validate, 5 | ValidateIf, 6 | ValidationArguments, 7 | ValidatorConstraint, 8 | ValidatorConstraintInterface, 9 | } from "class-validator"; 10 | import * as Relay from "graphql-relay"; 11 | import "reflect-metadata"; 12 | 13 | @ValidatorConstraint({ async: false }) 14 | export class CannotUseWithout implements ValidatorConstraintInterface { 15 | validate(_: unknown, args: ValidationArguments) { 16 | const object = args.object as Record; 17 | const required = args.constraints[0] as string; 18 | return object[required] !== undefined; 19 | } 20 | 21 | defaultMessage(args: ValidationArguments) { 22 | return `Cannot be used without \`${args.constraints[0]}\`.`; 23 | } 24 | } 25 | 26 | @ValidatorConstraint({ async: false }) 27 | export class CannotUseWith implements ValidatorConstraintInterface { 28 | validate(_: unknown, args: ValidationArguments) { 29 | const object = args.object as Record; 30 | const result = args.constraints.every((propertyName) => { 31 | return object[propertyName] === undefined; 32 | }); 33 | return result; 34 | } 35 | 36 | defaultMessage(args: ValidationArguments) { 37 | return `Cannot be used with \`${args.constraints.join("` , `")}\`.`; 38 | } 39 | } 40 | 41 | @ArgsType() 42 | export class ConnectionArgs implements Relay.ConnectionArguments { 43 | @Field(() => String, { 44 | nullable: true, 45 | description: "Paginate before opaque cursor", 46 | }) 47 | @ValidateIf((o) => o.before !== undefined) 48 | @Validate(CannotUseWithout, ["last"]) 49 | @Validate(CannotUseWith, ["after", "first"]) 50 | readonly before?: Relay.ConnectionCursor; 51 | 52 | @Field(() => String, { 53 | nullable: true, 54 | description: "Paginate after opaque cursor", 55 | }) 56 | @ValidateIf((o) => o.after !== undefined) 57 | @Validate(CannotUseWithout, ["first"]) 58 | @Validate(CannotUseWith, ["before", "last"]) 59 | readonly after?: Relay.ConnectionCursor; 60 | 61 | @Field(() => Int, { nullable: true, description: "Paginate first" }) 62 | @ValidateIf((o) => o.first !== undefined) 63 | @Min(1) 64 | @Validate(CannotUseWith, ["before", "last"]) 65 | readonly first?: number; 66 | 67 | @Field(() => Int, { nullable: true, description: "Paginate last" }) 68 | @ValidateIf((o) => o.last !== undefined) 69 | // Required `before`. This is a weird corner case. 70 | // We'd have to invert the ordering of query to get the last few items then re-invert it when emitting the results. 71 | // We'll just ignore it for now. 72 | @Validate(CannotUseWithout, ["before"]) 73 | @Validate(CannotUseWith, ["after", "first"]) 74 | @Min(1) 75 | readonly last?: number; 76 | } 77 | -------------------------------------------------------------------------------- /packages/nestjs-slack-webhook/__tests__/slackModule.test.ts: -------------------------------------------------------------------------------- 1 | import { describe, expect, it } from "@jest/globals"; 2 | import { Module } from "@nestjs/common"; 3 | import { Test } from "@nestjs/testing"; 4 | import { IncomingWebhook } from "@slack/webhook"; 5 | import { SLACK_TOKEN } from "./../src/slackConstants"; 6 | import { SlackModule } from "./../src/slackModule"; 7 | import { SlackOptions, SlackOptionsFactory } from "./../src/slackOptions"; 8 | 9 | describe("slackModule", () => { 10 | const url = "SLACK_WEBHOOK_URL"; 11 | 12 | class TestService implements SlackOptionsFactory { 13 | createSlackOptions(): SlackOptions { 14 | return { 15 | url, 16 | }; 17 | } 18 | } 19 | 20 | @Module({ 21 | exports: [TestService], 22 | providers: [TestService], 23 | }) 24 | class TestModule {} 25 | 26 | describe("forRoot", () => { 27 | it("provide slack client", async () => { 28 | const module = await Test.createTestingModule({ 29 | imports: [SlackModule.forRoot({ url })], 30 | }).compile(); 31 | 32 | const slackClient = module.get(SLACK_TOKEN); 33 | expect(slackClient).toBeDefined(); 34 | expect(slackClient).toBeInstanceOf(IncomingWebhook); 35 | }); 36 | }); 37 | 38 | describe("forRootAsync", () => { 39 | it("provide slack client with `useFactory`", async () => { 40 | const module = await Test.createTestingModule({ 41 | imports: [ 42 | SlackModule.forRootAsync({ 43 | useFactory: () => ({ url }), 44 | }), 45 | ], 46 | }).compile(); 47 | 48 | const slackClient = module.get(SLACK_TOKEN); 49 | expect(slackClient).toBeDefined(); 50 | expect(slackClient).toBeInstanceOf(IncomingWebhook); 51 | }); 52 | 53 | it("provide slack client with `useExisting`", async () => { 54 | const module = await Test.createTestingModule({ 55 | imports: [ 56 | SlackModule.forRootAsync({ 57 | imports: [TestModule], 58 | useExisting: TestService, 59 | }), 60 | ], 61 | }).compile(); 62 | 63 | const slackClient = module.get(SLACK_TOKEN); 64 | expect(slackClient).toBeDefined(); 65 | expect(slackClient).toBeInstanceOf(IncomingWebhook); 66 | }); 67 | 68 | it("provide slack client with `useClass`", async () => { 69 | const module = await Test.createTestingModule({ 70 | imports: [ 71 | SlackModule.forRootAsync({ 72 | useClass: TestService, 73 | }), 74 | ], 75 | }).compile(); 76 | 77 | const slackClient = module.get(SLACK_TOKEN); 78 | expect(slackClient).toBeDefined(); 79 | expect(slackClient).toBeInstanceOf(IncomingWebhook); 80 | }); 81 | }); 82 | }); 83 | -------------------------------------------------------------------------------- /packages/nestjs-graphql-relay/__tests__/index.test.ts: -------------------------------------------------------------------------------- 1 | import { afterAll, beforeAll, describe, expect, it } from "@jest/globals"; 2 | import { Column, DataSource, Entity, PrimaryGeneratedColumn } from "typeorm"; 3 | import { findAndPaginate, getPagingParameters } from "../src"; 4 | 5 | @Entity() 6 | class Example { 7 | @PrimaryGeneratedColumn() 8 | readonly id: number; 9 | 10 | @Column() 11 | readonly name: string; 12 | } 13 | 14 | describe("app", () => { 15 | let AppDataSource: DataSource; 16 | beforeAll(async () => { 17 | AppDataSource = new DataSource({ 18 | type: "sqlite", 19 | database: "nestjs-plugins", 20 | synchronize: true, 21 | entities: [Example], 22 | }); 23 | 24 | await AppDataSource.initialize(); 25 | 26 | const repo = AppDataSource.getRepository(Example); 27 | await AppDataSource.query(`DELETE from ${repo.metadata.tableName}`); 28 | }); 29 | 30 | afterAll(() => AppDataSource.destroy()); 31 | 32 | it("getPagingParameters", () => { 33 | expect(getPagingParameters({})).toEqual({}); 34 | expect(getPagingParameters({ first: 1 })).toEqual({ 35 | limit: 1, 36 | offset: 0, 37 | }); 38 | expect(() => 39 | getPagingParameters({ first: 1, after: "after" }), 40 | ).toThrowErrorMatchingInlineSnapshot(`"invalid before query"`); 41 | expect(() => 42 | getPagingParameters({ last: 1, before: "before" }), 43 | ).toThrowErrorMatchingInlineSnapshot(`"invalid before query"`); 44 | }); 45 | 46 | describe("findAndPaginate", () => { 47 | it("empty", async () => { 48 | const res = await findAndPaginate( 49 | { 50 | where: { name: "undefined" }, 51 | }, 52 | {}, 53 | AppDataSource.getRepository(Example), 54 | ); 55 | expect(res).toEqual({ 56 | edges: [], 57 | pageInfo: { 58 | endCursor: null, 59 | hasNextPage: false, 60 | hasPreviousPage: false, 61 | startCursor: null, 62 | }, 63 | }); 64 | }); 65 | 66 | it("find", async () => { 67 | const name = "name"; 68 | await AppDataSource.query( 69 | `INSERT INTO ${ 70 | AppDataSource.getRepository(Example).metadata.tableName 71 | } ("name") VALUES ("random name")`, 72 | ); 73 | await AppDataSource.query( 74 | `INSERT INTO ${ 75 | AppDataSource.getRepository(Example).metadata.tableName 76 | } ("name") VALUES ("${name}")`, 77 | ); 78 | 79 | const res = await findAndPaginate( 80 | { 81 | where: { name }, 82 | }, 83 | {}, 84 | AppDataSource.getRepository(Example), 85 | ); 86 | res.edges.map(({ node }) => expect(node.name).toEqual(name)); 87 | expect(res.pageInfo).toMatchSnapshot(); 88 | }); 89 | }); 90 | }); 91 | -------------------------------------------------------------------------------- /packages/nestjs-firebase/src/firebase.module.ts: -------------------------------------------------------------------------------- 1 | import { DynamicModule, Global, Module, Provider } from "@nestjs/common"; 2 | import { ClassProvider } from "@nestjs/common/interfaces"; 3 | import { FirebaseConstants } from "./firebase.constants"; 4 | import { 5 | FirebaseAdmin, 6 | FirebaseModuleAsyncOptions, 7 | FirebaseModuleOptions, 8 | FirebaseModuleOptionsFactory, 9 | } from "./firebase.interface"; 10 | import { getFirebaseAdmin } from "./util"; 11 | 12 | @Global() 13 | @Module({}) 14 | // biome-ignore lint/complexity/noStaticOnlyClass: NestJS module 15 | export class FirebaseModule { 16 | public static forRoot(options: FirebaseModuleOptions): DynamicModule { 17 | const provider: Provider = { 18 | provide: FirebaseConstants.FIREBASE_TOKEN, 19 | useValue: getFirebaseAdmin(options), 20 | }; 21 | 22 | return { 23 | exports: [provider], 24 | module: FirebaseModule, 25 | providers: [provider], 26 | }; 27 | } 28 | 29 | public static forRootAsync( 30 | options: FirebaseModuleAsyncOptions, 31 | ): DynamicModule { 32 | const firebaseProvider: Provider = { 33 | inject: [FirebaseConstants.FIREBASE_MODULE], 34 | provide: FirebaseConstants.FIREBASE_TOKEN, 35 | useFactory: (options: FirebaseModuleOptions) => getFirebaseAdmin(options), 36 | }; 37 | 38 | const asyncProviders = FirebaseModule.createAsyncProviders(options); 39 | return { 40 | module: FirebaseModule, 41 | imports: [...(options.imports || [])], 42 | providers: [...asyncProviders, firebaseProvider], 43 | exports: [firebaseProvider], 44 | }; 45 | } 46 | 47 | private static createAsyncProviders( 48 | options: FirebaseModuleAsyncOptions, 49 | ): Provider[] { 50 | if (options.useFactory || options.useExisting) { 51 | return [FirebaseModule.createAsyncOptionsProvider(options)]; 52 | } 53 | return [ 54 | FirebaseModule.createAsyncOptionsProvider(options), 55 | { 56 | provide: options.useClass, 57 | useClass: options.useClass, 58 | inject: options.inject, 59 | } as ClassProvider, 60 | ]; 61 | } 62 | 63 | private static createAsyncOptionsProvider( 64 | options: FirebaseModuleAsyncOptions, 65 | ): Provider { 66 | if (options.useFactory) { 67 | return { 68 | provide: FirebaseConstants.FIREBASE_MODULE, 69 | useFactory: options.useFactory, 70 | inject: options.inject || [], 71 | }; 72 | } 73 | return { 74 | provide: FirebaseConstants.FIREBASE_MODULE, 75 | useFactory: async ( 76 | optionsFactory: FirebaseModuleOptionsFactory, 77 | ): Promise => 78 | await optionsFactory.createFirebaseModuleOptions(), 79 | inject: options.useClass ? [options.useClass] : [], 80 | }; 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | ## v11.0.1 (2025-10-29) 2 | 3 | 4 | ## What's Changed 5 | ### Other Changes 6 | * chore(deps-dev): bump @google-cloud/storage from 7.17.0 to 7.17.1 by @dependabot[bot] in https://github.com/g59/nestjs-plugins/pull/1980 7 | * chore(deps-dev): bump @jest/globals from 29.7.0 to 30.1.2 by @dependabot[bot] in https://github.com/g59/nestjs-plugins/pull/1979 8 | * feat: remove dependency on @9renpoto/tsconfig by @9renpoto in https://github.com/g59/nestjs-plugins/pull/1982 9 | * chore(deps-dev): bump ts-jest from 29.4.1 to 29.4.4 by @dependabot[bot] in https://github.com/g59/nestjs-plugins/pull/1984 10 | * chore(deps-dev): bump @google-cloud/firestore from 7.11.3 to 7.11.4 by @dependabot[bot] in https://github.com/g59/nestjs-plugins/pull/1985 11 | * Potential fix for code scanning alert no. 12: Workflow does not contain permissions by @9renpoto in https://github.com/g59/nestjs-plugins/pull/1986 12 | * chore(deps-dev): bump @google-cloud/firestore from 7.11.4 to 7.11.6 by @dependabot[bot] in https://github.com/g59/nestjs-plugins/pull/1987 13 | * chore(deps-dev): bump @jest/globals from 30.1.2 to 30.2.0 by @dependabot[bot] in https://github.com/g59/nestjs-plugins/pull/1988 14 | * chore(deps): bump @fastify/proxy-addr from 5.0.0 to 5.1.0 by @dependabot[bot] in https://github.com/g59/nestjs-plugins/pull/1989 15 | * chore(deps): bump @nestjs/apollo from 13.1.0 to 13.2.1 in the nestjs group by @dependabot[bot] in https://github.com/g59/nestjs-plugins/pull/1991 16 | * chore(deps-dev): bump ts-jest from 29.4.4 to 29.4.5 by @dependabot[bot] in https://github.com/g59/nestjs-plugins/pull/1992 17 | * chore(deps-dev): bump @google-cloud/storage from 7.17.1 to 7.17.2 by @dependabot[bot] in https://github.com/g59/nestjs-plugins/pull/1994 18 | * chore(deps-dev): bump @as-integrations/fastify from 3.0.0 to 3.1.0 by @dependabot[bot] in https://github.com/g59/nestjs-plugins/pull/1993 19 | * chore(deps): bump the nestjs group with 2 updates by @dependabot[bot] in https://github.com/g59/nestjs-plugins/pull/1996 20 | * chore: sync example workspace versions by @9renpoto in https://github.com/g59/nestjs-plugins/pull/1998 21 | * chore(deps): bump the nestjs group with 2 updates by @dependabot[bot] in https://github.com/g59/nestjs-plugins/pull/1999 22 | * chore(deps-dev): bump @types/validator from 13.15.3 to 13.15.4 by @dependabot[bot] in https://github.com/g59/nestjs-plugins/pull/2001 23 | * chore(deps-dev): bump dotenv-cli from 10.0.0 to 11.0.0 by @dependabot[bot] in https://github.com/g59/nestjs-plugins/pull/2000 24 | * chore(deps): bump actions/setup-node from 5 to 6 by @dependabot[bot] in https://github.com/g59/nestjs-plugins/pull/1995 25 | 26 | 27 | **Full Changelog**: https://github.com/g59/nestjs-plugins/compare/v11.0.0...v11.0.1 28 | ## v11.0.0 (2025-09-09) 29 | 30 | 31 | ## What's Changed 32 | ### Other Changes 33 | * chore: upgrade nestjs v11 by @9renpoto in https://github.com/g59/nestjs-plugins/pull/1940 34 | * chore(deps): bump the nestjs group with 2 updates by @dependabot[bot] in https://github.com/g59/nestjs-plugins/pull/1942 35 | * chore(deps-dev): bump @types/validator from 13.12.2 to 13.12.3 by @dependabot[bot] in https://github.com/g59/nestjs-plugins/pull/1944 36 | * chore(deps): bump the nestjs group with 2 updates by @dependabot[bot] in https://github.com/g59/nestjs-plugins/pull/1945 37 | * chore(deps): bump the nestjs group with 3 updates by @dependabot[bot] in https://github.com/g59/nestjs-plugins/pull/1947 38 | * chore(deps-dev): bump @types/ws from 8.18.0 to 8.18.1 by @dependabot[bot] in https://github.com/g59/nestjs-plugins/pull/1948 39 | * chore(deps): bump @nestjs/common from 11.0.11 to 11.0.12 in the npm_and_yarn group by @dependabot[bot] in https://github.com/g59/nestjs-plugins/pull/1946 40 | * chore(deps-dev): bump @google-cloud/storage from 7.15.2 to 7.16.0 by @dependabot[bot] in https://github.com/g59/nestjs-plugins/pull/1950 41 | * chore(deps-dev): bump ts-jest from 29.2.6 to 29.3.2 by @dependabot[bot] in https://github.com/g59/nestjs-plugins/pull/1952 42 | * chore(deps): bump @apollo/server from 4.11.3 to 4.12.0 by @dependabot[bot] in https://github.com/g59/nestjs-plugins/pull/1953 43 | * chore(deps): bump the nestjs group with 3 updates by @dependabot[bot] in https://github.com/g59/nestjs-plugins/pull/1951 44 | * chore(deps): bump @nestjs/common from 11.0.13 to 11.0.20 in the npm_and_yarn group by @dependabot[bot] in https://github.com/g59/nestjs-plugins/pull/1954 45 | * chore(deps-dev): bump ts-jest from 29.3.2 to 29.3.4 by @dependabot[bot] in https://github.com/g59/nestjs-plugins/pull/1958 46 | * chore(deps): bump @apollo/server from 4.12.0 to 4.12.1 by @dependabot[bot] in https://github.com/g59/nestjs-plugins/pull/1959 47 | * chore(deps-dev): bump @google-cloud/firestore from 7.11.0 to 7.11.1 by @dependabot[bot] in https://github.com/g59/nestjs-plugins/pull/1960 48 | * chore(deps-dev): bump @types/validator from 13.12.3 to 13.15.1 by @dependabot[bot] in https://github.com/g59/nestjs-plugins/pull/1961 49 | * chore(deps): bump @apollo/server from 4.12.1 to 4.12.2 by @dependabot[bot] in https://github.com/g59/nestjs-plugins/pull/1962 50 | * chore(deps): bump the nestjs group with 3 updates by @dependabot[bot] in https://github.com/g59/nestjs-plugins/pull/1955 51 | * chore(deps-dev): bump @types/validator from 13.15.1 to 13.15.2 by @dependabot[bot] in https://github.com/g59/nestjs-plugins/pull/1965 52 | * chore(deps-dev): bump ts-jest from 29.3.4 to 29.4.0 by @dependabot[bot] in https://github.com/g59/nestjs-plugins/pull/1964 53 | * feat: Upgrade NestJS and other dependencies by @9renpoto in https://github.com/g59/nestjs-plugins/pull/1971 54 | * chore(deps): bump actions/checkout from 4 to 5 by @dependabot[bot] in https://github.com/g59/nestjs-plugins/pull/1969 55 | * chore(deps): bump the npm_and_yarn group with 1 update by @dependabot[bot] in https://github.com/g59/nestjs-plugins/pull/1970 56 | * chore: upgrade nestjs plugin v11 by @9renpoto in https://github.com/g59/nestjs-plugins/pull/1973 57 | * build(deps): remove @types/jest welcome @jest/globals by @9renpoto in https://github.com/g59/nestjs-plugins/pull/1974 58 | * chore(deps): bump actions/github-script from 7 to 8 by @dependabot[bot] in https://github.com/g59/nestjs-plugins/pull/1977 59 | * chore(deps): bump actions/setup-node from 4 to 5 by @dependabot[bot] in https://github.com/g59/nestjs-plugins/pull/1975 60 | * chore(deps-dev): bump @as-integrations/fastify from 2.1.1 to 3.0.0 by @dependabot[bot] in https://github.com/g59/nestjs-plugins/pull/1976 61 | 62 | 63 | **Full Changelog**: https://github.com/g59/nestjs-plugins/compare/v10.6.0...v11.0.0 64 | ## v10.6.0 (2025-03-03) 65 | 66 | 67 | ## What's Changed 68 | ### Other Changes 69 | * chore: bump v10.6.0 by @github-actions in https://github.com/g59/nestjs-plugins/pull/1868 70 | * chore(deps): bump @nestjs/cli from 10.4.7 to 10.4.8 in the nestjs group by @dependabot in https://github.com/g59/nestjs-plugins/pull/1908 71 | * chore(deps): bump the nestjs group with 2 updates by @dependabot in https://github.com/g59/nestjs-plugins/pull/1911 72 | * chore(deps): bump the nestjs group with 3 updates by @dependabot in https://github.com/g59/nestjs-plugins/pull/1913 73 | * chore(deps): bump the nestjs group with 3 updates by @dependabot in https://github.com/g59/nestjs-plugins/pull/1915 74 | * chore: s/ubuntu-latest/ubuntu-22.04/ by @9renpoto in https://github.com/g59/nestjs-plugins/pull/1916 75 | * chore(deps): bump the npm_and_yarn group with 2 updates by @dependabot in https://github.com/g59/nestjs-plugins/pull/1912 76 | * chore(deps-dev): bump @google-cloud/firestore from 7.10.0 to 7.11.0 by @dependabot in https://github.com/g59/nestjs-plugins/pull/1914 77 | * chore(deps-dev): bump @google-cloud/storage from 7.13.0 to 7.14.0 by @dependabot in https://github.com/g59/nestjs-plugins/pull/1909 78 | * chore(deps-dev): bump @biomejs/biome from 1.8.3 to 1.9.4 by @dependabot in https://github.com/g59/nestjs-plugins/pull/1891 79 | * chore(deps): bump peter-evans/create-pull-request from 6 to 7 by @dependabot in https://github.com/g59/nestjs-plugins/pull/1882 80 | * chore(deps): bump @apollo/server from 4.11.2 to 4.11.3 by @dependabot in https://github.com/g59/nestjs-plugins/pull/1918 81 | * chore(deps): bump uuid from 11.0.3 to 11.0.4 by @dependabot in https://github.com/g59/nestjs-plugins/pull/1920 82 | * chore(deps-dev): bump @9renpoto/tsconfig from 7.8.0 to 7.9.0 by @dependabot in https://github.com/g59/nestjs-plugins/pull/1919 83 | * chore(deps): bump uuid from 11.0.4 to 11.0.5 by @dependabot in https://github.com/g59/nestjs-plugins/pull/1921 84 | * chore(deps-dev): bump @google-cloud/storage from 7.14.0 to 7.15.0 by @dependabot in https://github.com/g59/nestjs-plugins/pull/1922 85 | * chore(deps-dev): bump @types/ws from 8.5.13 to 8.5.14 by @dependabot in https://github.com/g59/nestjs-plugins/pull/1924 86 | * Revert "chore: bump v10.6.0" by @9renpoto in https://github.com/g59/nestjs-plugins/pull/1926 87 | * chore(deps-dev): bump @google-cloud/storage from 7.15.0 to 7.15.1 by @dependabot in https://github.com/g59/nestjs-plugins/pull/1930 88 | * chore(deps-dev): bump ts-jest from 29.2.5 to 29.2.6 by @dependabot in https://github.com/g59/nestjs-plugins/pull/1931 89 | * chore(deps-dev): bump @google-cloud/storage from 7.15.1 to 7.15.2 by @dependabot in https://github.com/g59/nestjs-plugins/pull/1932 90 | * chore(deps): bump uuid from 11.0.5 to 11.1.0 by @dependabot in https://github.com/g59/nestjs-plugins/pull/1933 91 | * fix: audit by @9renpoto in https://github.com/g59/nestjs-plugins/pull/1936 92 | * chore: update badge by @9renpoto in https://github.com/g59/nestjs-plugins/pull/1937 93 | 94 | 95 | **Full Changelog**: https://github.com/g59/nestjs-plugins/compare/v10.5.2...v10.6.0 96 | ## v10.5.1 (2024-09-01) 97 | 98 | 99 | ## What's Changed 100 | ### Other Changes 101 | * chore(deps): bump @apollo/server from 4.10.2 to 4.10.4 by @dependabot in https://github.com/g59/nestjs-plugins/pull/1831 102 | * chore(deps): bump the nestjs group with 2 updates by @dependabot in https://github.com/g59/nestjs-plugins/pull/1830 103 | * chore(deps-dev): bump @google-cloud/storage from 7.9.0 to 7.10.0 by @dependabot in https://github.com/g59/nestjs-plugins/pull/1828 104 | * chore(deps-dev): bump @google-cloud/firestore from 7.6.0 to 7.7.0 by @dependabot in https://github.com/g59/nestjs-plugins/pull/1836 105 | * chore(deps-dev): bump jest-mock-extended from 3.0.6 to 3.0.7 by @dependabot in https://github.com/g59/nestjs-plugins/pull/1834 106 | * chore(deps-dev): bump @types/validator from 13.11.9 to 13.11.10 by @dependabot in https://github.com/g59/nestjs-plugins/pull/1837 107 | * chore(deps-dev): bump ts-jest from 29.1.2 to 29.1.3 by @dependabot in https://github.com/g59/nestjs-plugins/pull/1839 108 | * chore(deps-dev): bump @google-cloud/storage from 7.10.0 to 7.11.1 by @dependabot in https://github.com/g59/nestjs-plugins/pull/1840 109 | * chore(deps-dev): bump ts-jest from 29.1.3 to 29.1.4 by @dependabot in https://github.com/g59/nestjs-plugins/pull/1841 110 | * chore(.github): weekly update by @9renpoto in https://github.com/g59/nestjs-plugins/pull/1842 111 | * chore(deps-dev): bump @google-cloud/firestore from 7.7.0 to 7.8.0 by @dependabot in https://github.com/g59/nestjs-plugins/pull/1848 112 | * chore(deps-dev): bump @biomejs/biome from 1.7.3 to 1.8.0 by @dependabot in https://github.com/g59/nestjs-plugins/pull/1845 113 | * chore(deps): bump the nestjs group with 2 updates by @dependabot in https://github.com/g59/nestjs-plugins/pull/1844 114 | * chore(deps-dev): bump @google-cloud/storage from 7.11.1 to 7.11.2 by @dependabot in https://github.com/g59/nestjs-plugins/pull/1847 115 | * chore(deps-dev): bump @grpc/grpc-js from 1.8.21 to 1.8.22 in the npm_and_yarn group by @dependabot in https://github.com/g59/nestjs-plugins/pull/1850 116 | * chore(deps): bump braces from 3.0.2 to 3.0.3 in the npm_and_yarn group across 1 directory by @dependabot in https://github.com/g59/nestjs-plugins/pull/1851 117 | * chore(deps): bump uuid from 9.0.1 to 10.0.0 by @dependabot in https://github.com/g59/nestjs-plugins/pull/1846 118 | * chore(deps-dev): bump @types/uuid from 9.0.8 to 10.0.0 by @dependabot in https://github.com/g59/nestjs-plugins/pull/1857 119 | * chore(deps-dev): bump @biomejs/biome from 1.8.0 to 1.8.2 by @dependabot in https://github.com/g59/nestjs-plugins/pull/1856 120 | * chore(deps-dev): bump ts-jest from 29.1.4 to 29.1.5 by @dependabot in https://github.com/g59/nestjs-plugins/pull/1853 121 | * chore(deps-dev): bump @types/validator from 13.11.10 to 13.12.0 by @dependabot in https://github.com/g59/nestjs-plugins/pull/1854 122 | * chore(deps): bump ws from 7.5.9 to 7.5.10 in the npm_and_yarn group by @dependabot in https://github.com/g59/nestjs-plugins/pull/1855 123 | * chore(deps-dev): bump @biomejs/biome from 1.8.2 to 1.8.3 by @dependabot in https://github.com/g59/nestjs-plugins/pull/1858 124 | * chore(deps-dev): bump @google-cloud/firestore from 7.8.0 to 7.9.0 by @dependabot in https://github.com/g59/nestjs-plugins/pull/1859 125 | * chore(deps-dev): bump ts-jest from 29.1.5 to 29.2.2 by @dependabot in https://github.com/g59/nestjs-plugins/pull/1863 126 | * chore(deps-dev): bump @types/ws from 8.5.10 to 8.5.11 by @dependabot in https://github.com/g59/nestjs-plugins/pull/1862 127 | * chore(deps-dev): bump ts-jest from 29.2.2 to 29.2.3 by @dependabot in https://github.com/g59/nestjs-plugins/pull/1864 128 | * chore(deps-dev): bump @google-cloud/storage from 7.11.2 to 7.12.0 by @dependabot in https://github.com/g59/nestjs-plugins/pull/1865 129 | * chore(deps): bump fast-xml-parser from 4.3.2 to 4.4.1 in the npm_and_yarn group by @dependabot in https://github.com/g59/nestjs-plugins/pull/1867 130 | * chore(deps): bump @apollo/server from 4.10.4 to 4.10.5 by @dependabot in https://github.com/g59/nestjs-plugins/pull/1866 131 | * chore(deps-dev): bump @types/ws from 8.5.11 to 8.5.12 by @dependabot in https://github.com/g59/nestjs-plugins/pull/1870 132 | * chore(deps): bump @apollo/server from 4.10.5 to 4.11.0 by @dependabot in https://github.com/g59/nestjs-plugins/pull/1872 133 | * chore(deps-dev): bump @google-cloud/storage from 7.12.0 to 7.12.1 by @dependabot in https://github.com/g59/nestjs-plugins/pull/1873 134 | * chore(deps-dev): bump ts-jest from 29.2.3 to 29.2.5 by @dependabot in https://github.com/g59/nestjs-plugins/pull/1876 135 | * chore(deps): bump micromatch from 4.0.5 to 4.0.8 in the npm_and_yarn group by @dependabot in https://github.com/g59/nestjs-plugins/pull/1877 136 | 137 | 138 | **Full Changelog**: https://github.com/g59/nestjs-plugins/compare/v10.5.0...v10.5.1 139 | ## v10.5.0 (2024-04-13) 140 | 141 | 142 | ## What's Changed 143 | ### :rocket: Type: Feature 144 | * feat: allow firebase-admin v12 by @h3mpti in https://github.com/g59/nestjs-plugins/pull/1826 145 | ### Other Changes 146 | * chore(deps): bump ip from 2.0.0 to 2.0.1 by @dependabot in https://github.com/g59/nestjs-plugins/pull/1800 147 | * chore(deps-dev): bump @google-cloud/storage from 7.7.0 to 7.8.0 by @dependabot in https://github.com/g59/nestjs-plugins/pull/1807 148 | * chore(deps): bump jose from 4.15.4 to 4.15.5 by @dependabot in https://github.com/g59/nestjs-plugins/pull/1806 149 | * chore(deps): bump @apollo/server from 4.10.0 to 4.10.1 by @dependabot in https://github.com/g59/nestjs-plugins/pull/1805 150 | * Update nodejs.yml by @9renpoto in https://github.com/g59/nestjs-plugins/pull/1813 151 | * chore(deps): bump peter-evans/create-pull-request from 5 to 6 by @dependabot in https://github.com/g59/nestjs-plugins/pull/1792 152 | * chore(deps): bump codecov/codecov-action from 3 to 4 by @dependabot in https://github.com/g59/nestjs-plugins/pull/1793 153 | * chore(deps): bump follow-redirects from 1.15.4 to 1.15.6 by @dependabot in https://github.com/g59/nestjs-plugins/pull/1808 154 | * chore(deps-dev): bump @google-cloud/firestore from 7.3.0 to 7.4.0 by @dependabot in https://github.com/g59/nestjs-plugins/pull/1809 155 | * chore(deps): bump the nestjs group with 2 updates by @dependabot in https://github.com/g59/nestjs-plugins/pull/1814 156 | * chore(deps): bump the nestjs group with 1 update by @dependabot in https://github.com/g59/nestjs-plugins/pull/1817 157 | * chore(deps-dev): bump @google-cloud/firestore from 7.4.0 to 7.5.0 by @dependabot in https://github.com/g59/nestjs-plugins/pull/1818 158 | * chore(deps): bump @apollo/server from 4.10.1 to 4.10.2 by @dependabot in https://github.com/g59/nestjs-plugins/pull/1815 159 | * chore(deps-dev): bump @google-cloud/storage from 7.8.0 to 7.9.0 by @dependabot in https://github.com/g59/nestjs-plugins/pull/1811 160 | * chore(deps): bump express from 4.18.2 to 4.19.2 by @dependabot in https://github.com/g59/nestjs-plugins/pull/1819 161 | * chore(deps): bump the nestjs group with 2 updates by @dependabot in https://github.com/g59/nestjs-plugins/pull/1821 162 | * chore(deps): bump @nestjs/config from 3.2.1 to 3.2.2 in the nestjs group by @dependabot in https://github.com/g59/nestjs-plugins/pull/1823 163 | * chore(deps-dev): bump @google-cloud/firestore from 7.5.0 to 7.6.0 by @dependabot in https://github.com/g59/nestjs-plugins/pull/1822 164 | * chore(deps): bump tar from 6.2.0 to 6.2.1 in the npm_and_yarn group by @dependabot in https://github.com/g59/nestjs-plugins/pull/1825 165 | * chore(deps-dev): bump jest-mock-extended from 3.0.5 to 3.0.6 by @dependabot in https://github.com/g59/nestjs-plugins/pull/1824 166 | 167 | ## New Contributors 168 | * @h3mpti made their first contribution in https://github.com/g59/nestjs-plugins/pull/1826 169 | 170 | **Full Changelog**: https://github.com/g59/nestjs-plugins/compare/v10.4.0...v10.5.0 171 | ## v10.4.0 (2024-02-20) 172 | 173 | 174 | ## What's Changed 175 | ### Other Changes 176 | * chore(deps): update dependency @9renpoto/tsconfig to v7.7.4 by @renovate in https://github.com/g59/nestjs-plugins/pull/1760 177 | * Delete .github/renovate.json by @9renpoto in https://github.com/g59/nestjs-plugins/pull/1761 178 | * chore(deps-dev): bump @google-cloud/storage from 7.6.0 to 7.7.0 by @dependabot in https://github.com/g59/nestjs-plugins/pull/1764 179 | * chore(deps-dev): bump lint-staged from 15.1.0 to 15.2.0 by @dependabot in https://github.com/g59/nestjs-plugins/pull/1765 180 | * chore(deps-dev): bump @types/jest from 29.5.10 to 29.5.11 by @dependabot in https://github.com/g59/nestjs-plugins/pull/1766 181 | * chore(deps-dev): bump @nestjs/testing from 10.2.10 to 10.3.0 by @dependabot in https://github.com/g59/nestjs-plugins/pull/1769 182 | * chore(deps): bump @nestjs/platform-fastify from 10.2.10 to 10.3.0 by @dependabot in https://github.com/g59/nestjs-plugins/pull/1770 183 | * chore(deps): bump @apollo/server from 4.9.5 to 4.10.0 by @dependabot in https://github.com/g59/nestjs-plugins/pull/1772 184 | * chore(deps): bump follow-redirects from 1.15.3 to 1.15.4 by @dependabot in https://github.com/g59/nestjs-plugins/pull/1776 185 | * chore(deps): bump @nestjs/cli from 10.2.1 to 10.3.0 by @dependabot in https://github.com/g59/nestjs-plugins/pull/1774 186 | * chore(deps-dev): bump sqlite3 from 5.1.6 to 5.1.7 by @dependabot in https://github.com/g59/nestjs-plugins/pull/1773 187 | * chore(deps-dev): bump @9renpoto/tsconfig from 7.7.4 to 7.8.0 by @dependabot in https://github.com/g59/nestjs-plugins/pull/1777 188 | * chore(deps-dev): bump @google-cloud/firestore from 7.1.0 to 7.2.0 by @dependabot in https://github.com/g59/nestjs-plugins/pull/1780 189 | * chore: use biome by @9renpoto in https://github.com/g59/nestjs-plugins/pull/1781 190 | * chore: group nestjs by @9renpoto in https://github.com/g59/nestjs-plugins/pull/1788 191 | * chore(deps-dev): bump @types/uuid from 9.0.7 to 9.0.8 by @dependabot in https://github.com/g59/nestjs-plugins/pull/1787 192 | * chore(deps-dev): bump ts-jest from 29.1.1 to 29.1.2 by @dependabot in https://github.com/g59/nestjs-plugins/pull/1782 193 | * chore(deps-dev): bump @nestjs/testing from 10.3.0 to 10.3.1 by @dependabot in https://github.com/g59/nestjs-plugins/pull/1784 194 | * fix(.github): group nestjs by @9renpoto in https://github.com/g59/nestjs-plugins/pull/1789 195 | * chore(deps): bump the nestjs group with 1 update by @dependabot in https://github.com/g59/nestjs-plugins/pull/1790 196 | * chore(deps-dev): bump @types/validator from 13.11.7 to 13.11.8 by @dependabot in https://github.com/g59/nestjs-plugins/pull/1775 197 | * chore(deps-dev): bump @google-cloud/firestore from 7.2.0 to 7.3.0 by @dependabot in https://github.com/g59/nestjs-plugins/pull/1791 198 | * chore(deps-dev): bump @types/jest from 29.5.11 to 29.5.12 by @dependabot in https://github.com/g59/nestjs-plugins/pull/1794 199 | * chore(deps-dev): bump @types/validator from 13.11.8 to 13.11.9 by @dependabot in https://github.com/g59/nestjs-plugins/pull/1796 200 | * chore(deps): bump the nestjs group with 5 updates by @dependabot in https://github.com/g59/nestjs-plugins/pull/1797 201 | * chore(deps): bump the nestjs group with 2 updates by @dependabot in https://github.com/g59/nestjs-plugins/pull/1799 202 | 203 | 204 | **Full Changelog**: https://github.com/g59/nestjs-plugins/compare/v10.3.0...v10.4.0 205 | ## v10.3.0 (2023-11-23) 206 | 207 | 208 | ## What's Changed 209 | ### :rocket: Type: Feature 210 | * (feat): add remote config to nestjs firebase module by @Duduzera1997 in https://github.com/g59/nestjs-plugins/pull/1706 211 | * refactor: upgrade zendesk by @9renpoto in https://github.com/g59/nestjs-plugins/pull/1726 212 | * refactor: use managed types by @9renpoto in https://github.com/g59/nestjs-plugins/pull/1727 213 | * chore: firebase ability to use Realtime Database by @9renpoto in https://github.com/g59/nestjs-plugins/pull/1728 214 | ### Other Changes 215 | * chore(deps): update dependency @google-cloud/firestore to v7 by @renovate in https://github.com/g59/nestjs-plugins/pull/1697 216 | * chore(deps): update dependency @slack/webhook to v7 by @renovate in https://github.com/g59/nestjs-plugins/pull/1698 217 | * fix(deps): update dependency @apollo/server to v4.9.4 by @renovate in https://github.com/g59/nestjs-plugins/pull/1699 218 | * fix(deps): update dependency @as-integrations/fastify to v2.1.1 by @renovate in https://github.com/g59/nestjs-plugins/pull/1700 219 | * fix(deps): update nest monorepo to v10.2.7 by @renovate in https://github.com/g59/nestjs-plugins/pull/1703 220 | * chore(deps): update dependency @google-cloud/storage to v7.2.0 by @renovate in https://github.com/g59/nestjs-plugins/pull/1704 221 | * chore(deps): update dependency @types/uuid to v9.0.5 by @renovate in https://github.com/g59/nestjs-plugins/pull/1705 222 | * chore(deps): update dependency @types/ws to v8.5.7 by @renovate in https://github.com/g59/nestjs-plugins/pull/1708 223 | * chore(deps): update dependency @google-cloud/storage to v7.3.0 by @renovate in https://github.com/g59/nestjs-plugins/pull/1709 224 | * chore(deps): update dependency @types/validator to v13.11.3 by @renovate in https://github.com/g59/nestjs-plugins/pull/1710 225 | * chore(deps): update dependency @google-cloud/firestore to v7.1.0 by @renovate in https://github.com/g59/nestjs-plugins/pull/1711 226 | * chore(deps): update dependency lint-staged to v15 by @renovate in https://github.com/g59/nestjs-plugins/pull/1712 227 | * chore(deps): update dependency lint-staged to v15.0.1 by @renovate in https://github.com/g59/nestjs-plugins/pull/1713 228 | * chore(deps): update actions/checkout action to v4.1.1 by @renovate in https://github.com/g59/nestjs-plugins/pull/1714 229 | * chore(deps): update dependency @types/jest to v29.5.6 by @renovate in https://github.com/g59/nestjs-plugins/pull/1718 230 | * chore(deps): update dependency @types/node-zendesk to v2.0.13 by @renovate in https://github.com/g59/nestjs-plugins/pull/1719 231 | * chore(deps): update dependency @types/validator to v13.11.5 by @renovate in https://github.com/g59/nestjs-plugins/pull/1721 232 | * chore(deps): update dependency @types/uuid to v9.0.6 by @renovate in https://github.com/g59/nestjs-plugins/pull/1720 233 | * chore(deps): update dependency @types/ws to v8.5.8 by @renovate in https://github.com/g59/nestjs-plugins/pull/1722 234 | * chore(deps): update actions/checkout digest to b4ffde6 by @renovate in https://github.com/g59/nestjs-plugins/pull/1723 235 | * chore(deps): update dependency lint-staged to v15.0.2 by @renovate in https://github.com/g59/nestjs-plugins/pull/1724 236 | * chore(deps): update dependency @google-cloud/storage to v7.3.1 by @renovate in https://github.com/g59/nestjs-plugins/pull/1725 237 | * chore(deps-dev): bump @babel/traverse from 7.22.5 to 7.23.2 by @dependabot in https://github.com/g59/nestjs-plugins/pull/1715 238 | * fix(.github): rename branches by @9renpoto in https://github.com/g59/nestjs-plugins/pull/1729 239 | * Revert "fix(.github): rename branches" by @9renpoto in https://github.com/g59/nestjs-plugins/pull/1730 240 | * chore(deps): update actions/setup-node action to v3.8.2 by @renovate in https://github.com/g59/nestjs-plugins/pull/1731 241 | * fix(deps): update dependency @nestjs/cli to v10.2.0 by @renovate in https://github.com/g59/nestjs-plugins/pull/1732 242 | * chore(deps): update actions/setup-node action to v4 by @renovate in https://github.com/g59/nestjs-plugins/pull/1733 243 | * chore(deps): update dependency @google-cloud/storage to v7.3.2 by @renovate in https://github.com/g59/nestjs-plugins/pull/1734 244 | * chore(deps): update dependency @google-cloud/storage to v7.4.0 by @renovate in https://github.com/g59/nestjs-plugins/pull/1735 245 | * fix(deps): update dependency @apollo/server to v4.9.5 by @renovate in https://github.com/g59/nestjs-plugins/pull/1736 246 | * fix(deps): update dependency @nestjs/cli to v10.2.1 by @renovate in https://github.com/g59/nestjs-plugins/pull/1738 247 | * chore(deps): update dependency @google-cloud/storage to v7.5.0 by @renovate in https://github.com/g59/nestjs-plugins/pull/1739 248 | * chore(deps): update dependency @types/jest to v29.5.7 by @renovate in https://github.com/g59/nestjs-plugins/pull/1740 249 | * fix(deps): update nest monorepo to v10.2.8 by @renovate in https://github.com/g59/nestjs-plugins/pull/1741 250 | * chore(deps): update dependency @types/jest to v29.5.8 by @renovate in https://github.com/g59/nestjs-plugins/pull/1742 251 | * chore(deps): update dependency @types/uuid to v9.0.7 by @renovate in https://github.com/g59/nestjs-plugins/pull/1743 252 | * chore(deps): update dependency @types/ws to v8.5.9 by @renovate in https://github.com/g59/nestjs-plugins/pull/1745 253 | * chore(deps): update dependency @types/validator to v13.11.6 by @renovate in https://github.com/g59/nestjs-plugins/pull/1744 254 | * fix(deps): update dependency @nestjs/apollo to v12.0.10 by @renovate in https://github.com/g59/nestjs-plugins/pull/1746 255 | * chore(deps): update dependency @google-cloud/storage to v7.6.0 by @renovate in https://github.com/g59/nestjs-plugins/pull/1747 256 | * feat: coveralls to codecov by @9renpoto in https://github.com/g59/nestjs-plugins/pull/1748 257 | * chore(deps): update dependency lint-staged to v15.1.0 by @renovate in https://github.com/g59/nestjs-plugins/pull/1749 258 | * chore(deps): update actions/github-script action to v7 by @renovate in https://github.com/g59/nestjs-plugins/pull/1750 259 | * fix(deps): update dependency @nestjs/apollo to v12.0.11 by @renovate in https://github.com/g59/nestjs-plugins/pull/1751 260 | * fix(deps): update nest monorepo to v10.2.9 by @renovate in https://github.com/g59/nestjs-plugins/pull/1752 261 | * fix(deps): update nest monorepo to v10.2.10 by @renovate in https://github.com/g59/nestjs-plugins/pull/1753 262 | * chore(deps): update dependency @types/validator to v13.11.7 by @renovate in https://github.com/g59/nestjs-plugins/pull/1754 263 | * chore(deps): update dependency @types/ws to v8.5.10 by @renovate in https://github.com/g59/nestjs-plugins/pull/1756 264 | * chore(deps): update dependency @types/jest to v29.5.9 by @renovate in https://github.com/g59/nestjs-plugins/pull/1755 265 | * chore(deps): update dependency @types/jest to v29.5.10 by @renovate in https://github.com/g59/nestjs-plugins/pull/1757 266 | * fix: generate release notes by @9renpoto in https://github.com/g59/nestjs-plugins/pull/1758 267 | 268 | ## New Contributors 269 | * @Duduzera1997 made their first contribution in https://github.com/g59/nestjs-plugins/pull/1706 270 | 271 | **Full Changelog**: https://github.com/g59/nestjs-plugins/compare/v10.2.0...v10.3.0 272 | ## v10.2.0 (2023-09-30) 273 | 274 | 275 | ## What's Changed 276 | ### Other Changes 277 | * chore(deps): update coverallsapp/github-action action to v2.2.3 by @renovate in https://github.com/g59/nestjs-plugins/pull/1674 278 | * chore(deps): update dependency @google-cloud/storage to v7.1.0 by @renovate in https://github.com/g59/nestjs-plugins/pull/1675 279 | * fix(deps): update nest monorepo to v10.2.5 by @renovate in https://github.com/g59/nestjs-plugins/pull/1676 280 | * fix(deps): update dependency @nestjs/apollo to v12.0.9 by @renovate in https://github.com/g59/nestjs-plugins/pull/1680 281 | * fix(deps): update dependency @nestjs/config to v3.1.0 by @renovate in https://github.com/g59/nestjs-plugins/pull/1681 282 | * fix(deps): update dependency uuid to v9.0.1 by @renovate in https://github.com/g59/nestjs-plugins/pull/1682 283 | * fix(deps): update dependency @nestjs/config to v3.1.1 by @renovate in https://github.com/g59/nestjs-plugins/pull/1683 284 | * chore(deps): update dependency node-zendesk to v4 by @renovate in https://github.com/g59/nestjs-plugins/pull/1684 285 | * chore(deps): update dependency @types/uuid to v9.0.4 by @renovate in https://github.com/g59/nestjs-plugins/pull/1685 286 | * chore(deps): update dependency @types/jest to v29.5.5 by @renovate in https://github.com/g59/nestjs-plugins/pull/1686 287 | * chore(deps): bump graphql from 16.7.1 to 16.8.1 by @dependabot in https://github.com/g59/nestjs-plugins/pull/1687 288 | * fix(deps): update dependency @nestjs/cli to v10.1.18 by @renovate in https://github.com/g59/nestjs-plugins/pull/1688 289 | * fix(deps): update nest monorepo to v10.2.6 by @renovate in https://github.com/g59/nestjs-plugins/pull/1689 290 | * chore(deps): update actions/checkout digest to 8ade135 by @renovate in https://github.com/g59/nestjs-plugins/pull/1690 291 | * chore(deps): update actions/checkout action to v4.1.0 by @renovate in https://github.com/g59/nestjs-plugins/pull/1691 292 | * chore(deps): update dependency @types/node-zendesk to v2.0.12 by @renovate in https://github.com/g59/nestjs-plugins/pull/1692 293 | * chore(deps): update dependency @types/ws to v8.5.6 by @renovate in https://github.com/g59/nestjs-plugins/pull/1693 294 | * chore(deps): update dependency @types/validator to v13.11.2 by @renovate in https://github.com/g59/nestjs-plugins/pull/1694 295 | * chore(deps): update dependency @google-cloud/firestore to v6.8.0 by @renovate in https://github.com/g59/nestjs-plugins/pull/1695 296 | 297 | 298 | **Full Changelog**: https://github.com/g59/nestjs-plugins/compare/v10.1.0...v10.2.0 299 | ## v10.1.0 (2023-09-07) 300 | 301 | 302 | ## What's Changed 303 | ### Other Changes 304 | * fix(deps): update dependency @apollo/server to v4.7.5 by @renovate in https://github.com/g59/nestjs-plugins/pull/1593 305 | * fix(deps): update dependency @nestjs/apollo to v12.0.4 by @renovate in https://github.com/g59/nestjs-plugins/pull/1594 306 | * chore(deps): update dependency lint-staged to v13.2.3 by @renovate in https://github.com/g59/nestjs-plugins/pull/1596 307 | * fix(deps): update dependency @nestjs/apollo to v12.0.7 by @renovate in https://github.com/g59/nestjs-plugins/pull/1597 308 | * fix(deps): update nest monorepo to v10.0.4 by @renovate in https://github.com/g59/nestjs-plugins/pull/1598 309 | * chore(deps): update dependency ts-jest to v29.1.1 by @renovate in https://github.com/g59/nestjs-plugins/pull/1599 310 | * fix(deps): update dependency @nestjs/cli to v10.1.0 by @renovate in https://github.com/g59/nestjs-plugins/pull/1600 311 | * fix(deps): update dependency @nestjs/cli to v10.1.1 by @renovate in https://github.com/g59/nestjs-plugins/pull/1604 312 | * fix(deps): update nest monorepo to v10.0.5 by @renovate in https://github.com/g59/nestjs-plugins/pull/1606 313 | * fix(deps): update dependency @nestjs/cli to v10.1.4 by @renovate in https://github.com/g59/nestjs-plugins/pull/1608 314 | * fix(deps): update dependency @nestjs/cli to v10.1.7 by @renovate in https://github.com/g59/nestjs-plugins/pull/1609 315 | * chore(deps): update actions/setup-node action to v3.7.0 by @renovate in https://github.com/g59/nestjs-plugins/pull/1610 316 | * chore(deps): update dependency @types/jest to v29.5.3 by @renovate in https://github.com/g59/nestjs-plugins/pull/1611 317 | * fix(deps): update dependency @nestjs/cli to v10.1.8 by @renovate in https://github.com/g59/nestjs-plugins/pull/1613 318 | * chore(deps): bump semver from 6.3.0 to 6.3.1 by @dependabot in https://github.com/g59/nestjs-plugins/pull/1612 319 | * chore(deps): update coverallsapp/github-action action to v2.2.1 by @renovate in https://github.com/g59/nestjs-plugins/pull/1614 320 | * chore(deps): update dependency @google-cloud/storage to v6.12.0 by @renovate in https://github.com/g59/nestjs-plugins/pull/1615 321 | * chore(deps): update dependency @9renpoto/tsconfig to v7.7.2 by @renovate in https://github.com/g59/nestjs-plugins/pull/1617 322 | * fix(deps): update dependency @nestjs/cli to v10.1.9 by @renovate in https://github.com/g59/nestjs-plugins/pull/1618 323 | * fix(deps): update nest monorepo to v10.1.0 by @renovate in https://github.com/g59/nestjs-plugins/pull/1619 324 | * chore: bump version task by @9renpoto in https://github.com/g59/nestjs-plugins/pull/1620 325 | * fix(deps): update dependency @nestjs/cli to v10.1.10 by @renovate in https://github.com/g59/nestjs-plugins/pull/1623 326 | * chore(deps): bump word-wrap from 1.2.3 to 1.2.4 by @dependabot in https://github.com/g59/nestjs-plugins/pull/1622 327 | * chore(deps): update dependency @google-cloud/firestore to v6.7.0 by @renovate in https://github.com/g59/nestjs-plugins/pull/1624 328 | * fix(deps): update dependency @apollo/server to v4.8.0 by @renovate in https://github.com/g59/nestjs-plugins/pull/1625 329 | * Update nodejs.yml by @9renpoto in https://github.com/g59/nestjs-plugins/pull/1626 330 | * fix(deps): update dependency @as-integrations/fastify to v2.1.0 by @renovate in https://github.com/g59/nestjs-plugins/pull/1627 331 | * fix(deps): update dependency @apollo/server to v4.8.1 by @renovate in https://github.com/g59/nestjs-plugins/pull/1628 332 | * fix(deps): update nest monorepo to v10.1.1 by @renovate in https://github.com/g59/nestjs-plugins/pull/1629 333 | * fix(deps): update nest monorepo to v10.1.2 by @renovate in https://github.com/g59/nestjs-plugins/pull/1630 334 | * fix: remote label by @9renpoto in https://github.com/g59/nestjs-plugins/pull/1631 335 | * fix(deps): update dependency @apollo/server to v4.9.0 by @renovate in https://github.com/g59/nestjs-plugins/pull/1632 336 | * fix(deps): update dependency @nestjs/cli to v10.1.11 by @renovate in https://github.com/g59/nestjs-plugins/pull/1633 337 | * fix(deps): update nest monorepo to v10.1.3 by @renovate in https://github.com/g59/nestjs-plugins/pull/1634 338 | * chore(deps): update dependency @types/validator to v13.9.0 by @renovate in https://github.com/g59/nestjs-plugins/pull/1635 339 | * chore(deps): update dependency @google-cloud/storage to v7 by @renovate in https://github.com/g59/nestjs-plugins/pull/1636 340 | * fix(deps): update dependency @apollo/server to v4.9.1 by @renovate in https://github.com/g59/nestjs-plugins/pull/1637 341 | * chore(deps): update dependency @google-cloud/storage to v7.0.1 by @renovate in https://github.com/g59/nestjs-plugins/pull/1638 342 | * chore(deps): update dependency @types/validator to v13.11.1 by @renovate in https://github.com/g59/nestjs-plugins/pull/1639 343 | * chore(deps): update dependency @9renpoto/tsconfig to v7.7.3 by @renovate in https://github.com/g59/nestjs-plugins/pull/1640 344 | * chore(deps): update dependency lint-staged to v13.3.0 by @renovate in https://github.com/g59/nestjs-plugins/pull/1641 345 | * chore(deps): update dependency lint-staged to v14 by @renovate in https://github.com/g59/nestjs-plugins/pull/1642 346 | * chore(deps): update actions/setup-node action to v3.8.0 by @renovate in https://github.com/g59/nestjs-plugins/pull/1643 347 | * fix(deps): update dependency @nestjs/cli to v10.1.12 by @renovate in https://github.com/g59/nestjs-plugins/pull/1644 348 | * chore(deps): update actions/setup-node action to v3.8.1 by @renovate in https://github.com/g59/nestjs-plugins/pull/1645 349 | * fix(deps): update nest monorepo to v10.2.0 by @renovate in https://github.com/g59/nestjs-plugins/pull/1648 350 | * chore(deps): update dependency lint-staged to v14.0.1 by @renovate in https://github.com/g59/nestjs-plugins/pull/1647 351 | * chore(deps): update dependency node-zendesk to v3 by @renovate in https://github.com/g59/nestjs-plugins/pull/1646 352 | * fix(deps): update nest monorepo to v10.2.1 by @renovate in https://github.com/g59/nestjs-plugins/pull/1649 353 | * fix(deps): update dependency @nestjs/cli to v10.1.13 by @renovate in https://github.com/g59/nestjs-plugins/pull/1650 354 | * chore(deps): update dependency @types/jest to v29.5.4 by @renovate in https://github.com/g59/nestjs-plugins/pull/1651 355 | * fix(deps): update dependency @nestjs/cli to v10.1.14 by @renovate in https://github.com/g59/nestjs-plugins/pull/1653 356 | * chore(deps): update actions/checkout action to v3.6.0 by @renovate in https://github.com/g59/nestjs-plugins/pull/1655 357 | * fix(deps): update dependency @nestjs/cli to v10.1.15 by @renovate in https://github.com/g59/nestjs-plugins/pull/1654 358 | * fix(deps): update dependency @apollo/server to v4.9.2 by @renovate in https://github.com/g59/nestjs-plugins/pull/1656 359 | * fix(deps): update dependency @nestjs/cli to v10.1.16 by @renovate in https://github.com/g59/nestjs-plugins/pull/1658 360 | * fix(deps): update nest monorepo to v10.2.2 by @renovate in https://github.com/g59/nestjs-plugins/pull/1659 361 | * fix(deps): update nest monorepo to v10.2.3 by @renovate in https://github.com/g59/nestjs-plugins/pull/1660 362 | * fix(deps): update dependency @apollo/server to v4.9.3 [security] by @renovate in https://github.com/g59/nestjs-plugins/pull/1662 363 | * chore(deps): update dependency @types/uuid to v9.0.3 by @renovate in https://github.com/g59/nestjs-plugins/pull/1663 364 | * fix(deps): update dependency @nestjs/cli to v10.1.17 by @renovate in https://github.com/g59/nestjs-plugins/pull/1666 365 | * fix(deps): update dependency @nestjs/config to v3.0.1 by @renovate in https://github.com/g59/nestjs-plugins/pull/1667 366 | * fix(deps): update nest monorepo to v10.2.4 by @renovate in https://github.com/g59/nestjs-plugins/pull/1668 367 | * chore(deps): update npm to v10 by @renovate in https://github.com/g59/nestjs-plugins/pull/1669 368 | * chore(deps): update coverallsapp/github-action action to v2.2.2 by @renovate in https://github.com/g59/nestjs-plugins/pull/1670 369 | * chore(deps): update actions/checkout action to v4 by @renovate in https://github.com/g59/nestjs-plugins/pull/1671 370 | * fix: generate release note comment by @9renpoto in https://github.com/g59/nestjs-plugins/pull/1672 371 | 372 | 373 | **Full Changelog**: https://github.com/g59/nestjs-plugins/compare/v10.0.0...v10.1.0 374 | ## v8.1.0 (2021-09-17) 375 | 376 | #### :rocket: Enhancement 377 | 378 | - `nestjs-firebase` 379 | - [#924](https://github.com/g59/nestjs-plugins/pull/924) chore: firebase 380 | AppOptions ([@9renpoto](https://github.com/9renpoto)) 381 | - `nestjs-firebase`, `nestjs-graphql-relay`, `nestjs-slack-webhook`, 382 | `nestjs-zendesk` 383 | - [#905](https://github.com/g59/nestjs-plugins/pull/905) feat: export firebase 384 | admin storage ([@9renpoto](https://github.com/9renpoto)) 385 | 386 | #### Committers: 1 387 | 388 | - Keisuke Kan ([@9renpoto](https://github.com/9renpoto)) 389 | 390 | ## v8.0.0 (2021-08-18) 391 | 392 | #### :rocket: Enhancement 393 | 394 | - `nestjs-firebase`, `nestjs-graphql-relay`, `nestjs-slack-webhook` 395 | - [#864](https://github.com/g59/nestjs-plugins/pull/864) chore: upgrade 396 | @nestjs v8 ([@9renpoto](https://github.com/9renpoto)) 397 | 398 | #### Committers: 1 399 | 400 | - Keisuke Kan ([@9renpoto](https://github.com/9renpoto)) 401 | 402 | ## v1.2.0 (2021-04-26) 403 | 404 | #### :rocket: Enhancement 405 | 406 | - `nestjs-graphql-relay`, `nestjs-zendesk` 407 | - [#632](https://github.com/g59/nestjs-plugins/pull/632) feat: add 408 | nestjs-zendesk module ([@9renpoto](https://github.com/9renpoto)) 409 | 410 | #### Committers: 1 411 | 412 | - Keisuke Kan ([@9renpoto](https://github.com/9renpoto)) 413 | 414 | ## v1.1.0 (2021-04-21) 415 | 416 | #### :rocket: Enhancement 417 | 418 | - `nestjs-graphql-relay` 419 | - [#158](https://github.com/g59/nestjs-plugins/pull/158) chore(deps): update 420 | dependency typeorm to v0.2.29 421 | ([@renovate[bot]](https://github.com/apps/renovate)) 422 | 423 | #### Committers: 2 424 | 425 | - Keisuke Kan ([@9renpoto](https://github.com/9renpoto)) 426 | - [@dependabot-preview[bot]](https://github.com/apps/dependabot-preview) 427 | 428 | ## v0.0.4 (2020-06-02) 429 | 430 | #### :rocket: Enhancement 431 | 432 | - `nestjs-firebase` 433 | - [#170](https://github.com/g59/nestjs-plugins/pull/170) feat: added firebase 434 | plugin ([@abyssparanoia](https://github.com/abyssparanoia)) 435 | 436 | #### Committers: 2 437 | 438 | - Keisuke Kan ([@9renpoto](https://github.com/9renpoto)) 439 | - [@abyssparanoia](https://github.com/abyssparanoia) 440 | 441 | ## v0.0.3 (2020-05-18) 442 | 443 | #### :rocket: Enhancement 444 | 445 | - `nestjs-graphql-relay` 446 | - [#152](https://github.com/g59/nestjs-plugins/pull/152) fix: skip aggregate 447 | ([@9renpoto](https://github.com/9renpoto)) 448 | - `nestjs-graphql-relay`, `nestjs-slack-webhook` 449 | - [#91](https://github.com/g59/nestjs-plugins/pull/91) chore: update 450 | dependencies ([@9renpoto](https://github.com/9renpoto)) 451 | 452 | #### Committers: 1 453 | 454 | - Keisuke Kan ([@9renpoto](https://github.com/9renpoto)) 455 | 456 | ## v0.0.2 (2020-03-16) 457 | 458 | #### :rocket: Enhancement 459 | 460 | - `nestjs-slack-webhook` 461 | - [#37](https://github.com/g59/nestjs-plugins/pull/37) rename: package 462 | nestjs-slack-webhook ([@Yasai-T](https://github.com/Yasai-T)) 463 | - `nestjs-slack` 464 | - [#25](https://github.com/g59/nestjs-plugins/pull/25) feat: nestjs-slack 465 | plugin ([@Yasai-T](https://github.com/Yasai-T)) 466 | 467 | #### Committers: 2 468 | 469 | - Keisuke Kan ([@9renpoto](https://github.com/9renpoto)) 470 | - tomoki midorikawa ([@Yasai-T](https://github.com/Yasai-T)) 471 | --------------------------------------------------------------------------------