@miguelmorales13/nestkit 0.1.1 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (57) hide show
  1. package/README.md +305 -1
  2. package/dist/auth/auth-user.entity.d.ts +8 -0
  3. package/dist/auth/auth-user.port.d.ts +16 -0
  4. package/dist/auth/auth.controller.d.ts +25 -0
  5. package/dist/auth/auth.dto.d.ts +13 -0
  6. package/dist/auth/auth.service.d.ts +24 -0
  7. package/dist/auth/authenticated-user.d.ts +7 -0
  8. package/dist/auth/current-tenant.decorator.d.ts +2 -0
  9. package/dist/auth/current-user.decorator.d.ts +1 -0
  10. package/dist/auth/hash.util.d.ts +2 -0
  11. package/dist/auth/index.cjs +265 -0
  12. package/dist/auth/index.d.ts +16 -0
  13. package/dist/auth/index.js +265 -0
  14. package/dist/auth/jwt-auth.guard.d.ts +5 -0
  15. package/dist/auth/require-tenant.guard.d.ts +9 -0
  16. package/dist/auth/roles.decorator.d.ts +3 -0
  17. package/dist/auth/roles.guard.d.ts +11 -0
  18. package/dist/auth/token.service.d.ts +7 -0
  19. package/dist/bootstrap/index.cjs +4 -3
  20. package/dist/bootstrap/index.js +3 -2
  21. package/dist/{chunk-4IDLJMQA.cjs → chunk-7FQQDWOZ.cjs} +6 -14
  22. package/dist/chunk-7SOM7EZP.cjs +1 -0
  23. package/dist/chunk-DQYAIQQ5.js +0 -0
  24. package/dist/{chunk-AR3EKJBR.cjs → chunk-FDNGAYTZ.cjs} +6 -6
  25. package/dist/{chunk-AUA4X3RE.cjs → chunk-O2ZMI3EK.cjs} +2 -2
  26. package/dist/{chunk-HGJX2GPE.js → chunk-ORWJ7LES.js} +1 -1
  27. package/dist/{chunk-EQXYK6AL.js → chunk-Q45IEPWU.js} +5 -13
  28. package/dist/chunk-R7BVS6CI.cjs +13 -0
  29. package/dist/{chunk-VPS5CLHT.js → chunk-RHNQGTAT.js} +1 -1
  30. package/dist/chunk-YFYHLYHN.js +13 -0
  31. package/dist/email/nodemailer/index.cjs +40 -0
  32. package/dist/email/nodemailer/index.d.ts +1 -0
  33. package/dist/email/nodemailer/index.js +40 -0
  34. package/dist/email/nodemailer/nodemailer.module.d.ts +4 -0
  35. package/dist/email/resend/index.cjs +31 -0
  36. package/dist/email/resend/index.d.ts +1 -0
  37. package/dist/email/resend/index.js +31 -0
  38. package/dist/email/resend/resend.module.d.ts +4 -0
  39. package/dist/errors/index.cjs +7 -4
  40. package/dist/errors/index.js +6 -3
  41. package/dist/index.cjs +17 -14
  42. package/dist/index.js +24 -21
  43. package/dist/stripe/index.cjs +78 -0
  44. package/dist/stripe/index.d.ts +3 -0
  45. package/dist/stripe/index.js +78 -0
  46. package/dist/stripe/stripe-webhook.controller.d.ts +20 -0
  47. package/dist/stripe/stripe.module.d.ts +4 -0
  48. package/dist/telegram/index.cjs +31 -0
  49. package/dist/telegram/index.d.ts +1 -0
  50. package/dist/telegram/index.js +31 -0
  51. package/dist/telegram/telegram.module.d.ts +8 -0
  52. package/dist/whatsapp/index.cjs +68 -0
  53. package/dist/whatsapp/index.d.ts +3 -0
  54. package/dist/whatsapp/index.js +68 -0
  55. package/dist/whatsapp/whatsapp-client.d.ts +21 -0
  56. package/dist/whatsapp/whatsapp.module.d.ts +4 -0
  57. package/package.json +74 -10
@@ -0,0 +1,78 @@
1
+ import {
2
+ UnauthorizedAppException
3
+ } from "../chunk-ORWJ7LES.js";
4
+ import "../chunk-YFYHLYHN.js";
5
+ import {
6
+ __decorateClass,
7
+ __decorateParam
8
+ } from "../chunk-4MGIQFAJ.js";
9
+
10
+ // src/stripe/stripe.module.ts
11
+ import { Module } from "@nestjs/common";
12
+ import Stripe from "stripe";
13
+ var STRIPE_CLIENT = /* @__PURE__ */ Symbol("STRIPE_CLIENT");
14
+ var StripeModule = class {
15
+ };
16
+ StripeModule = __decorateClass([
17
+ Module({
18
+ providers: [
19
+ {
20
+ provide: STRIPE_CLIENT,
21
+ useFactory: () => {
22
+ const secretKey = process.env.STRIPE_SECRET_KEY;
23
+ if (!secretKey) {
24
+ throw new Error("StripeModule: STRIPE_SECRET_KEY environment variable is not set");
25
+ }
26
+ const apiVersion = process.env.STRIPE_API_VERSION;
27
+ return apiVersion ? new Stripe(secretKey, { apiVersion }) : new Stripe(secretKey);
28
+ }
29
+ }
30
+ ],
31
+ exports: [STRIPE_CLIENT]
32
+ })
33
+ ], StripeModule);
34
+
35
+ // src/stripe/stripe-webhook.controller.ts
36
+ import { Controller, Headers, Inject, Post, Req } from "@nestjs/common";
37
+ function createStripeWebhookController(options) {
38
+ let StripeWebhookControllerHost = class {
39
+ constructor(stripe) {
40
+ this.stripe = stripe;
41
+ }
42
+ async handleWebhook(req, signature) {
43
+ const webhookSecret = process.env.STRIPE_WEBHOOK_SECRET;
44
+ if (!webhookSecret) {
45
+ throw new Error("StripeWebhookController: STRIPE_WEBHOOK_SECRET environment variable is not set");
46
+ }
47
+ const rawBody = req.rawBody;
48
+ if (!rawBody) {
49
+ throw new Error(
50
+ "StripeWebhookController: request.rawBody is undefined \u2014 create the Nest app with `NestFactory.create(AppModule, { rawBody: true })` (see README)."
51
+ );
52
+ }
53
+ let event;
54
+ try {
55
+ event = this.stripe.webhooks.constructEvent(rawBody, signature, webhookSecret);
56
+ } catch {
57
+ throw new UnauthorizedAppException("Invalid Stripe webhook signature", void 0, "INVALID_STRIPE_SIGNATURE");
58
+ }
59
+ await options.handlers[event.type]?.(event);
60
+ return { received: true };
61
+ }
62
+ };
63
+ __decorateClass([
64
+ Post(),
65
+ __decorateParam(0, Req()),
66
+ __decorateParam(1, Headers("stripe-signature"))
67
+ ], StripeWebhookControllerHost.prototype, "handleWebhook", 1);
68
+ StripeWebhookControllerHost = __decorateClass([
69
+ Controller(options.path ?? "stripe/webhook"),
70
+ __decorateParam(0, Inject(STRIPE_CLIENT))
71
+ ], StripeWebhookControllerHost);
72
+ return StripeWebhookControllerHost;
73
+ }
74
+ export {
75
+ STRIPE_CLIENT,
76
+ StripeModule,
77
+ createStripeWebhookController
78
+ };
@@ -0,0 +1,20 @@
1
+ import { type Type } from '@nestjs/common';
2
+ import type Stripe from 'stripe';
3
+ export interface CreateStripeWebhookControllerOptions {
4
+ /** Route prefix for the generated controller. Defaults to 'stripe/webhook'. */
5
+ path?: string;
6
+ /** Keyed by Stripe event type, e.g. 'checkout.session.completed'. Unhandled types are acked and ignored. */
7
+ handlers: Record<string, (event: Stripe.Event) => Promise<void> | void>;
8
+ }
9
+ /**
10
+ * Requires the Nest app to be created with
11
+ * `NestFactory.create(AppModule, { rawBody: true })` — Stripe signature
12
+ * verification needs the exact raw request bytes, which nestkit's
13
+ * `applyNestKitDefaults` (applied after app creation) cannot retroactively
14
+ * enable. See README.
15
+ */
16
+ export declare function createStripeWebhookController(options: CreateStripeWebhookControllerOptions): Type<{
17
+ handleWebhook(req: unknown, signature: string): Promise<{
18
+ received: true;
19
+ }>;
20
+ }>;
@@ -0,0 +1,4 @@
1
+ /** DI token for the Stripe client. Inject with `@Inject(STRIPE_CLIENT)`. */
2
+ export declare const STRIPE_CLIENT: unique symbol;
3
+ export declare class StripeModule {
4
+ }
@@ -0,0 +1,31 @@
1
+ "use strict";Object.defineProperty(exports, "__esModule", {value: true});
2
+
3
+ var _chunk2REOCMUDcjs = require('../chunk-2REOCMUD.cjs');
4
+
5
+ // src/telegram/telegram.module.ts
6
+ var _common = require('@nestjs/common');
7
+ var _telegraf = require('telegraf');
8
+ var TELEGRAM_BOT = /* @__PURE__ */ Symbol("TELEGRAM_BOT");
9
+ var TelegramModule = class {
10
+ };
11
+ TelegramModule = exports.TelegramModule = _chunk2REOCMUDcjs.__decorateClass.call(void 0, [
12
+ _common.Module.call(void 0, {
13
+ providers: [
14
+ {
15
+ provide: TELEGRAM_BOT,
16
+ useFactory: () => {
17
+ const token = process.env.TELEGRAM_BOT_TOKEN;
18
+ if (!token) {
19
+ throw new Error("TelegramModule: TELEGRAM_BOT_TOKEN environment variable is not set");
20
+ }
21
+ return new (0, _telegraf.Telegram)(token);
22
+ }
23
+ }
24
+ ],
25
+ exports: [TELEGRAM_BOT]
26
+ })
27
+ ], TelegramModule);
28
+
29
+
30
+
31
+ exports.TELEGRAM_BOT = TELEGRAM_BOT; exports.TelegramModule = TelegramModule;
@@ -0,0 +1 @@
1
+ export { TelegramModule, TELEGRAM_BOT } from './telegram.module.js';
@@ -0,0 +1,31 @@
1
+ import {
2
+ __decorateClass
3
+ } from "../chunk-4MGIQFAJ.js";
4
+
5
+ // src/telegram/telegram.module.ts
6
+ import { Module } from "@nestjs/common";
7
+ import { Telegram as TelegrafClient } from "telegraf";
8
+ var TELEGRAM_BOT = /* @__PURE__ */ Symbol("TELEGRAM_BOT");
9
+ var TelegramModule = class {
10
+ };
11
+ TelegramModule = __decorateClass([
12
+ Module({
13
+ providers: [
14
+ {
15
+ provide: TELEGRAM_BOT,
16
+ useFactory: () => {
17
+ const token = process.env.TELEGRAM_BOT_TOKEN;
18
+ if (!token) {
19
+ throw new Error("TelegramModule: TELEGRAM_BOT_TOKEN environment variable is not set");
20
+ }
21
+ return new TelegrafClient(token);
22
+ }
23
+ }
24
+ ],
25
+ exports: [TELEGRAM_BOT]
26
+ })
27
+ ], TelegramModule);
28
+ export {
29
+ TELEGRAM_BOT,
30
+ TelegramModule
31
+ };
@@ -0,0 +1,8 @@
1
+ /**
2
+ * DI token for the outbound Telegram Bot API client. Inject with
3
+ * `@Inject(TELEGRAM_BOT)`. Send-only — no polling, no webhook, no update
4
+ * handling, no full `Telegraf` bot instance.
5
+ */
6
+ export declare const TELEGRAM_BOT: unique symbol;
7
+ export declare class TelegramModule {
8
+ }
@@ -0,0 +1,68 @@
1
+ "use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _nullishCoalesce(lhs, rhsFn) { if (lhs != null) { return lhs; } else { return rhsFn(); } }
2
+
3
+ var _chunk2REOCMUDcjs = require('../chunk-2REOCMUD.cjs');
4
+
5
+ // src/whatsapp/whatsapp.module.ts
6
+ var _common = require('@nestjs/common');
7
+
8
+ // src/whatsapp/whatsapp-client.ts
9
+ var DEFAULT_API_VERSION = "v21.0";
10
+ var WhatsAppClient = class {
11
+ constructor(options) {
12
+ this.options = options;
13
+ const version = _nullishCoalesce(options.apiVersion, () => ( DEFAULT_API_VERSION));
14
+ this.baseUrl = `https://graph.facebook.com/${version}/${options.phoneNumberId}/messages`;
15
+ }
16
+ async sendTextMessage(to, body) {
17
+ const response = await fetch(this.baseUrl, {
18
+ method: "POST",
19
+ headers: {
20
+ Authorization: `Bearer ${this.options.accessToken}`,
21
+ "Content-Type": "application/json"
22
+ },
23
+ body: JSON.stringify({
24
+ messaging_product: "whatsapp",
25
+ to,
26
+ type: "text",
27
+ text: { body }
28
+ })
29
+ });
30
+ if (!response.ok) {
31
+ const errorBody = await response.text();
32
+ throw new Error(`WhatsAppClient: send failed (${response.status}): ${errorBody}`);
33
+ }
34
+ return await response.json();
35
+ }
36
+ };
37
+
38
+ // src/whatsapp/whatsapp.module.ts
39
+ var WHATSAPP_CLIENT = /* @__PURE__ */ Symbol("WHATSAPP_CLIENT");
40
+ function requireEnv(name) {
41
+ const value = process.env[name];
42
+ if (!value) {
43
+ throw new Error(`WhatsAppModule: ${name} environment variable is not set`);
44
+ }
45
+ return value;
46
+ }
47
+ var WhatsAppModule = class {
48
+ };
49
+ WhatsAppModule = exports.WhatsAppModule = _chunk2REOCMUDcjs.__decorateClass.call(void 0, [
50
+ _common.Module.call(void 0, {
51
+ providers: [
52
+ {
53
+ provide: WHATSAPP_CLIENT,
54
+ useFactory: () => new WhatsAppClient({
55
+ accessToken: requireEnv("WHATSAPP_ACCESS_TOKEN"),
56
+ phoneNumberId: requireEnv("WHATSAPP_PHONE_NUMBER_ID"),
57
+ apiVersion: process.env.WHATSAPP_API_VERSION
58
+ })
59
+ }
60
+ ],
61
+ exports: [WHATSAPP_CLIENT]
62
+ })
63
+ ], WhatsAppModule);
64
+
65
+
66
+
67
+
68
+ exports.WHATSAPP_CLIENT = WHATSAPP_CLIENT; exports.WhatsAppClient = WhatsAppClient; exports.WhatsAppModule = WhatsAppModule;
@@ -0,0 +1,3 @@
1
+ export { WhatsAppModule, WHATSAPP_CLIENT } from './whatsapp.module.js';
2
+ export { WhatsAppClient } from './whatsapp-client.js';
3
+ export type { WhatsAppClientOptions, WhatsAppSendResult } from './whatsapp-client.js';
@@ -0,0 +1,68 @@
1
+ import {
2
+ __decorateClass
3
+ } from "../chunk-4MGIQFAJ.js";
4
+
5
+ // src/whatsapp/whatsapp.module.ts
6
+ import { Module } from "@nestjs/common";
7
+
8
+ // src/whatsapp/whatsapp-client.ts
9
+ var DEFAULT_API_VERSION = "v21.0";
10
+ var WhatsAppClient = class {
11
+ constructor(options) {
12
+ this.options = options;
13
+ const version = options.apiVersion ?? DEFAULT_API_VERSION;
14
+ this.baseUrl = `https://graph.facebook.com/${version}/${options.phoneNumberId}/messages`;
15
+ }
16
+ async sendTextMessage(to, body) {
17
+ const response = await fetch(this.baseUrl, {
18
+ method: "POST",
19
+ headers: {
20
+ Authorization: `Bearer ${this.options.accessToken}`,
21
+ "Content-Type": "application/json"
22
+ },
23
+ body: JSON.stringify({
24
+ messaging_product: "whatsapp",
25
+ to,
26
+ type: "text",
27
+ text: { body }
28
+ })
29
+ });
30
+ if (!response.ok) {
31
+ const errorBody = await response.text();
32
+ throw new Error(`WhatsAppClient: send failed (${response.status}): ${errorBody}`);
33
+ }
34
+ return await response.json();
35
+ }
36
+ };
37
+
38
+ // src/whatsapp/whatsapp.module.ts
39
+ var WHATSAPP_CLIENT = /* @__PURE__ */ Symbol("WHATSAPP_CLIENT");
40
+ function requireEnv(name) {
41
+ const value = process.env[name];
42
+ if (!value) {
43
+ throw new Error(`WhatsAppModule: ${name} environment variable is not set`);
44
+ }
45
+ return value;
46
+ }
47
+ var WhatsAppModule = class {
48
+ };
49
+ WhatsAppModule = __decorateClass([
50
+ Module({
51
+ providers: [
52
+ {
53
+ provide: WHATSAPP_CLIENT,
54
+ useFactory: () => new WhatsAppClient({
55
+ accessToken: requireEnv("WHATSAPP_ACCESS_TOKEN"),
56
+ phoneNumberId: requireEnv("WHATSAPP_PHONE_NUMBER_ID"),
57
+ apiVersion: process.env.WHATSAPP_API_VERSION
58
+ })
59
+ }
60
+ ],
61
+ exports: [WHATSAPP_CLIENT]
62
+ })
63
+ ], WhatsAppModule);
64
+ export {
65
+ WHATSAPP_CLIENT,
66
+ WhatsAppClient,
67
+ WhatsAppModule
68
+ };
@@ -0,0 +1,21 @@
1
+ export interface WhatsAppClientOptions {
2
+ accessToken: string;
3
+ phoneNumberId: string;
4
+ apiVersion?: string;
5
+ }
6
+ export interface WhatsAppSendResult {
7
+ messagingProduct: 'whatsapp';
8
+ messages: Array<{
9
+ id: string;
10
+ }>;
11
+ }
12
+ /**
13
+ * Minimal outbound client for the WhatsApp Cloud API (Meta Graph API).
14
+ * No SDK dependency — built on Node's global `fetch` (18+).
15
+ */
16
+ export declare class WhatsAppClient {
17
+ private readonly options;
18
+ private readonly baseUrl;
19
+ constructor(options: WhatsAppClientOptions);
20
+ sendTextMessage(to: string, body: string): Promise<WhatsAppSendResult>;
21
+ }
@@ -0,0 +1,4 @@
1
+ /** DI token for the WhatsApp Cloud API client. Inject with `@Inject(WHATSAPP_CLIENT)`. */
2
+ export declare const WHATSAPP_CLIENT: unique symbol;
3
+ export declare class WhatsAppModule {
4
+ }
package/package.json CHANGED
@@ -1,10 +1,10 @@
1
1
  {
2
2
  "name": "@miguelmorales13/nestkit",
3
- "version": "0.1.1",
3
+ "version": "0.3.0",
4
4
  "private": false,
5
5
  "license": "MIT",
6
6
  "type": "module",
7
- "description": "Reusable NestJS building blocks: i18n, error handling, standardized responses, request tracking, base entities, generic CRUD, and Postgres/Supabase connection helpers.",
7
+ "description": "Reusable NestJS building blocks: i18n, error handling, standardized responses, request tracking, base entities, generic CRUD, Postgres/Supabase connection helpers, outbound Telegram/WhatsApp/Stripe clients, batteries-included auth, Stripe webhooks, and Resend/Nodemailer email.",
8
8
  "publishConfig": {
9
9
  "access": "public"
10
10
  },
@@ -61,6 +61,36 @@
61
61
  "import": "./dist/database/mongo/index.js",
62
62
  "require": "./dist/database/mongo/index.cjs"
63
63
  },
64
+ "./telegram": {
65
+ "types": "./dist/telegram/index.d.ts",
66
+ "import": "./dist/telegram/index.js",
67
+ "require": "./dist/telegram/index.cjs"
68
+ },
69
+ "./whatsapp": {
70
+ "types": "./dist/whatsapp/index.d.ts",
71
+ "import": "./dist/whatsapp/index.js",
72
+ "require": "./dist/whatsapp/index.cjs"
73
+ },
74
+ "./stripe": {
75
+ "types": "./dist/stripe/index.d.ts",
76
+ "import": "./dist/stripe/index.js",
77
+ "require": "./dist/stripe/index.cjs"
78
+ },
79
+ "./auth": {
80
+ "types": "./dist/auth/index.d.ts",
81
+ "import": "./dist/auth/index.js",
82
+ "require": "./dist/auth/index.cjs"
83
+ },
84
+ "./email/resend": {
85
+ "types": "./dist/email/resend/index.d.ts",
86
+ "import": "./dist/email/resend/index.js",
87
+ "require": "./dist/email/resend/index.cjs"
88
+ },
89
+ "./email/nodemailer": {
90
+ "types": "./dist/email/nodemailer/index.d.ts",
91
+ "import": "./dist/email/nodemailer/index.js",
92
+ "require": "./dist/email/nodemailer/index.cjs"
93
+ },
64
94
  "./i18n": {
65
95
  "types": "./dist/i18n/index.d.ts",
66
96
  "import": "./dist/i18n/index.js",
@@ -85,7 +115,13 @@
85
115
  "helmet": "^8.0.0",
86
116
  "pg": "^8.11.0",
87
117
  "reflect-metadata": "^0.2.0",
88
- "rxjs": "^7.8.0"
118
+ "rxjs": "^7.8.0",
119
+ "telegraf": "^4.16.0",
120
+ "stripe": "^22.0.0",
121
+ "class-validator": "^0.15.0",
122
+ "class-transformer": "^0.5.1",
123
+ "resend": "^6.20.0",
124
+ "nodemailer": "^9.0.5"
89
125
  },
90
126
  "peerDependenciesMeta": {
91
127
  "pg": {
@@ -99,25 +135,53 @@
99
135
  },
100
136
  "helmet": {
101
137
  "optional": true
138
+ },
139
+ "telegraf": {
140
+ "optional": true
141
+ },
142
+ "stripe": {
143
+ "optional": true
144
+ },
145
+ "class-validator": {
146
+ "optional": true
147
+ },
148
+ "class-transformer": {
149
+ "optional": true
150
+ },
151
+ "resend": {
152
+ "optional": true
153
+ },
154
+ "nodemailer": {
155
+ "optional": true
102
156
  }
103
157
  },
104
158
  "dependencies": {
105
- "nestjs-i18n": "^10.4.5"
159
+ "nestjs-i18n": "^10.4.5",
160
+ "bcryptjs": "^3.0.3",
161
+ "jsonwebtoken": "^9.0.3"
106
162
  },
107
163
  "devDependencies": {
108
- "typescript": "^5.6.0",
109
- "tsup": "^8.5.1",
110
- "@types/node": "^22.0.0",
111
164
  "@nestjs/common": "^11.0.0",
112
165
  "@nestjs/core": "^11.0.0",
113
166
  "@nestjs/swagger": "^11.0.0",
114
167
  "@supabase/supabase-js": "^2.45.0",
115
- "pg": "^8.11.0",
168
+ "@types/jsonwebtoken": "^9.0.10",
169
+ "@types/node": "^22.0.0",
170
+ "@types/nodemailer": "^8.0.1",
116
171
  "@types/pg": "^8.11.0",
172
+ "bcryptjs": "^3.0.3",
173
+ "class-transformer": "^0.5.1",
174
+ "class-validator": "^0.15.1",
117
175
  "helmet": "^8.0.0",
176
+ "jsonwebtoken": "^9.0.3",
177
+ "nodemailer": "^9.0.5",
178
+ "pg": "^8.11.0",
118
179
  "reflect-metadata": "^0.2.0",
180
+ "resend": "^6.20.0",
119
181
  "rxjs": "^7.8.0",
120
- "class-validator": "^0.14.0",
121
- "class-transformer": "^0.5.1"
182
+ "stripe": "^22.5.0",
183
+ "telegraf": "^4.16.3",
184
+ "tsup": "^8.5.1",
185
+ "typescript": "^5.6.0"
122
186
  }
123
187
  }