@teamvortexsoftware/vortex-fastify-5-sdk 0.0.6 → 0.2.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.
package/README.md CHANGED
@@ -2,6 +2,21 @@
2
2
 
3
3
  Drop-in Fastify integration for Vortex invitations and JWT functionality. Get up and running in under 2 minutes!
4
4
 
5
+ ## Features
6
+
7
+ ### Invitation Delivery Types
8
+
9
+ Vortex supports multiple delivery methods for invitations:
10
+
11
+ - **`email`** - Email invitations sent by Vortex (includes reminders and nudges)
12
+ - **`phone`** - Phone invitations sent by the user/customer
13
+ - **`share`** - Shareable invitation links for social sharing
14
+ - **`internal`** - Internal invitations managed entirely by your application
15
+ - No email/SMS communication triggered by Vortex
16
+ - Target value can be any customer-defined identifier (UUID, string, number)
17
+ - Useful for in-app invitation flows where you handle the delivery
18
+ - Example use case: In-app notifications, dashboard invites, etc.
19
+
5
20
  ## 🚀 Quick Start
6
21
 
7
22
  ```bash
package/dist/config.d.ts CHANGED
@@ -2,9 +2,11 @@ import { FastifyRequest, FastifyReply } from 'fastify';
2
2
  export interface AuthenticatedUser {
3
3
  userId: string;
4
4
  userEmail?: string;
5
+ name?: string;
6
+ avatarUrl?: string;
5
7
  adminScopes?: string[];
6
8
  identifiers?: {
7
- type: 'email' | 'sms';
9
+ type: 'email' | 'phone';
8
10
  value: string;
9
11
  }[];
10
12
  groups?: {
@@ -21,10 +23,15 @@ export interface InvitationResource {
21
23
  }
22
24
  export interface InvitationTargetResource {
23
25
  invitationIds: string[];
24
- target: {
26
+ target?: {
25
27
  type: string;
26
28
  value: string;
27
29
  };
30
+ user?: {
31
+ email?: string;
32
+ phone?: string;
33
+ name?: string;
34
+ };
28
35
  }
29
36
  export interface GroupResource {
30
37
  groupType: string;
@@ -1 +1 @@
1
- {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAEvD,MAAM,WAAW,iBAAiB;IAChC,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,WAAW,CAAC,EAAE,MAAM,EAAE,CAAC;IAGvB,WAAW,CAAC,EAAE;QAAE,IAAI,EAAE,OAAO,GAAG,KAAK,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;IACzD,MAAM,CAAC,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,EAAE,CAAC,EAAE,MAAM,CAAC;QAAC,OAAO,CAAC,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;IACzE,IAAI,CAAC,EAAE,MAAM,CAAC;IAGd,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;CAClC;AAGD,MAAM,WAAW,kBAAkB;IACjC,YAAY,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,wBAAwB;IACvC,aAAa,EAAE,MAAM,EAAE,CAAC;IACxB,MAAM,EAAE;QACN,IAAI,EAAE,MAAM,CAAC;QACb,KAAK,EAAE,MAAM,CAAC;KACf,CAAC;CACH;AAED,MAAM,WAAW,aAAa;IAC5B,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;CACjB;AAGD,MAAM,WAAW,iBAAiB,CAAC,CAAC,GAAG,OAAO;IAC5C,CAAC,OAAO,EAAE,cAAc,EAAE,KAAK,EAAE,YAAY,EAAE,IAAI,EAAE,iBAAiB,GAAG,IAAI,EAAE,QAAQ,CAAC,EAAE,CAAC,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;CAChH;AAGD,MAAM,MAAM,oBAAoB,GAAG,iBAAiB,CAAC,kBAAkB,CAAC,CAAC;AACzE,MAAM,MAAM,0BAA0B,GAAG,iBAAiB,CAAC,wBAAwB,CAAC,CAAC;AACrF,MAAM,MAAM,eAAe,GAAG,iBAAiB,CAAC,aAAa,CAAC,CAAC;AAC/D,MAAM,MAAM,eAAe,GAAG,iBAAiB,CAAC,IAAI,CAAC,CAAC;AAEtD,MAAM,WAAW,YAAY;IAC3B,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,gBAAgB,CAAC,EAAE,CAAC,OAAO,EAAE,cAAc,EAAE,KAAK,EAAE,YAAY,KAAK,OAAO,CAAC,iBAAiB,GAAG,IAAI,CAAC,CAAC;IAEvG,4BAA4B,CAAC,EAAE,eAAe,CAAC;IAC/C,mBAAmB,CAAC,EAAE,oBAAoB,CAAC;IAC3C,mBAAmB,CAAC,EAAE,oBAAoB,CAAC;IAC3C,oBAAoB,CAAC,EAAE,0BAA0B,CAAC;IAClD,2BAA2B,CAAC,EAAE,eAAe,CAAC;IAC9C,2BAA2B,CAAC,EAAE,eAAe,CAAC;IAC9C,WAAW,CAAC,EAAE,oBAAoB,CAAC;CACpC;AAQD,wBAAgB,eAAe,CAAC,MAAM,EAAE,YAAY,GAAG,IAAI,CAY1D;AAED,wBAAgB,oBAAoB,CAAC,qBAAqB,EAAE,OAAO,CAAC,YAAY,CAAC,GAAG,YAAY,GAAG,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAQtH;AAED,wBAAgB,mBAAmB,CAAC,aAAa,EAAE,MAAM,OAAO,CAAC,YAAY,CAAC,GAAG,IAAI,CAKpF;AAED,wBAAsB,eAAe,IAAI,OAAO,CAAC,YAAY,CAAC,CAwC7D;AAGD,wBAAsB,mBAAmB,CAAC,OAAO,EAAE,cAAc,EAAE,KAAK,EAAE,YAAY,GAAG,OAAO,CAAC,iBAAiB,GAAG,IAAI,CAAC,CAczH;AAED;;;GAGG;AACH,wBAAgB,2BAA2B;;;;;;;;EAY1C"}
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"invitations.d.ts","sourceRoot":"","sources":["../../src/handlers/invitations.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAKvD,wBAAsB,4BAA4B,CAAC,OAAO,EAAE,cAAc,EAAE,KAAK,EAAE,YAAY,kBAuC9F;AAED,wBAAsB,mBAAmB,CAAC,OAAO,EAAE,cAAc,EAAE,KAAK,EAAE,YAAY,kBAiCrF;AAED,wBAAsB,sBAAsB,CAAC,OAAO,EAAE,cAAc,EAAE,KAAK,EAAE,YAAY,kBA+BxF;AAED,wBAAsB,uBAAuB,CAAC,OAAO,EAAE,cAAc,EAAE,KAAK,EAAE,YAAY,kBAyDzF;AAED,wBAAsB,2BAA2B,CAAC,OAAO,EAAE,cAAc,EAAE,KAAK,EAAE,YAAY,kBAqC7F;AAED,wBAAsB,8BAA8B,CAAC,OAAO,EAAE,cAAc,EAAE,KAAK,EAAE,YAAY,kBAqChG;AAED,wBAAsB,cAAc,CAAC,OAAO,EAAE,cAAc,EAAE,KAAK,EAAE,YAAY,kBA+BhF"}
1
+ {"version":3,"file":"invitations.d.ts","sourceRoot":"","sources":["../../src/handlers/invitations.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAKvD,wBAAsB,4BAA4B,CAAC,OAAO,EAAE,cAAc,EAAE,KAAK,EAAE,YAAY,kBAuC9F;AAED,wBAAsB,mBAAmB,CAAC,OAAO,EAAE,cAAc,EAAE,KAAK,EAAE,YAAY,kBAiCrF;AAED,wBAAsB,sBAAsB,CAAC,OAAO,EAAE,cAAc,EAAE,KAAK,EAAE,YAAY,kBA+BxF;AAED,wBAAsB,uBAAuB,CAAC,OAAO,EAAE,cAAc,EAAE,KAAK,EAAE,YAAY,kBAgFzF;AAED,wBAAsB,2BAA2B,CAAC,OAAO,EAAE,cAAc,EAAE,KAAK,EAAE,YAAY,kBAqC7F;AAED,wBAAsB,8BAA8B,CAAC,OAAO,EAAE,cAAc,EAAE,KAAK,EAAE,YAAY,kBAqChG;AAED,wBAAsB,cAAc,CAAC,OAAO,EAAE,cAAc,EAAE,KAAK,EAAE,YAAY,kBA+BhF"}
@@ -199,7 +199,7 @@ function handleRevokeInvitation(request, reply) {
199
199
  }
200
200
  function handleAcceptInvitations(request, reply) {
201
201
  return __awaiter(this, void 0, void 0, function () {
202
- var body, invitationIds, target, sanitizedIds, targetObj, validatedTarget, config, user, hasAccess, vortex, result, error_4;
202
+ var body, invitationIds, target, user, sanitizedIds, acceptData, userObj, targetObj, config, authenticatedUser, resource, hasAccess, vortex, result, error_4;
203
203
  return __generator(this, function (_a) {
204
204
  switch (_a.label) {
205
205
  case 0:
@@ -210,8 +210,7 @@ function handleAcceptInvitations(request, reply) {
210
210
  return [4 /*yield*/, (0, utils_1.parseRequestBody)(request)];
211
211
  case 1:
212
212
  body = _a.sent();
213
- (0, utils_1.validateRequiredFields)(body, ['invitationIds', 'target']);
214
- invitationIds = body.invitationIds, target = body.target;
213
+ invitationIds = body.invitationIds, target = body.target, user = body.user;
215
214
  if (!Array.isArray(invitationIds) || invitationIds.length === 0) {
216
215
  return [2 /*return*/, (0, utils_1.createErrorResponse)(reply, 'invitationIds must be a non-empty array', 400)];
217
216
  }
@@ -219,22 +218,48 @@ function handleAcceptInvitations(request, reply) {
219
218
  if (sanitizedIds.length !== invitationIds.length) {
220
219
  return [2 /*return*/, (0, utils_1.createErrorResponse)(reply, 'Invalid invitation IDs provided', 400)];
221
220
  }
222
- targetObj = target;
223
- if (!targetObj.type || !targetObj.value) {
224
- return [2 /*return*/, (0, utils_1.createErrorResponse)(reply, 'target must have type and value properties', 400)];
221
+ // Support both new format (user) and legacy format (target)
222
+ if (!user && !target) {
223
+ return [2 /*return*/, (0, utils_1.createErrorResponse)(reply, 'Either user or target must be provided', 400)];
224
+ }
225
+ acceptData = void 0;
226
+ if (user) {
227
+ userObj = user;
228
+ if (!userObj.email && !userObj.phone) {
229
+ return [2 /*return*/, (0, utils_1.createErrorResponse)(reply, 'user must have either email or phone', 400)];
230
+ }
231
+ acceptData = {
232
+ email: userObj.email ? (0, utils_1.sanitizeInput)(userObj.email) : undefined,
233
+ phone: userObj.phone ? (0, utils_1.sanitizeInput)(userObj.phone) : undefined,
234
+ name: userObj.name ? (0, utils_1.sanitizeInput)(userObj.name) : undefined,
235
+ };
236
+ }
237
+ else {
238
+ targetObj = target;
239
+ if (!targetObj.type || !targetObj.value) {
240
+ return [2 /*return*/, (0, utils_1.createErrorResponse)(reply, 'target must have type and value properties', 400)];
241
+ }
242
+ if (!['email', 'username', 'phoneNumber', 'phone'].includes(targetObj.type)) {
243
+ return [2 /*return*/, (0, utils_1.createErrorResponse)(reply, 'target.type must be email, username, phoneNumber, or phone', 400)];
244
+ }
245
+ acceptData = {
246
+ type: targetObj.type,
247
+ value: (0, utils_1.sanitizeInput)(targetObj.value) || targetObj.value
248
+ };
225
249
  }
226
- if (!['email', 'username', 'phoneNumber'].includes(targetObj.type)) {
227
- return [2 /*return*/, (0, utils_1.createErrorResponse)(reply, 'target.type must be email, username, or phoneNumber', 400)];
228
- }
229
- validatedTarget = { type: targetObj.type, value: targetObj.value };
230
250
  return [4 /*yield*/, (0, config_1.getVortexConfig)()];
231
251
  case 2:
232
252
  config = _a.sent();
233
253
  return [4 /*yield*/, (0, config_1.authenticateRequest)(request, reply)];
234
254
  case 3:
235
- user = _a.sent();
255
+ authenticatedUser = _a.sent();
236
256
  if (!config.canAcceptInvitations) return [3 /*break*/, 5];
237
- return [4 /*yield*/, config.canAcceptInvitations(request, reply, user, { invitationIds: sanitizedIds, target: validatedTarget })];
257
+ resource = {
258
+ invitationIds: sanitizedIds,
259
+ target: target,
260
+ user: user,
261
+ };
262
+ return [4 /*yield*/, config.canAcceptInvitations(request, reply, authenticatedUser, resource)];
238
263
  case 4:
239
264
  hasAccess = _a.sent();
240
265
  if (!hasAccess) {
@@ -242,16 +267,13 @@ function handleAcceptInvitations(request, reply) {
242
267
  }
243
268
  return [3 /*break*/, 6];
244
269
  case 5:
245
- if (!user) {
270
+ if (!authenticatedUser) {
246
271
  return [2 /*return*/, (0, utils_1.createErrorResponse)(reply, 'Access denied. Configure access control hooks for invitation endpoints.', 403)];
247
272
  }
248
273
  _a.label = 6;
249
274
  case 6:
250
275
  vortex = new vortex_node_22_sdk_1.Vortex(config.apiKey);
251
- return [4 /*yield*/, vortex.acceptInvitations(sanitizedIds, {
252
- type: validatedTarget.type,
253
- value: (0, utils_1.sanitizeInput)(validatedTarget.value) || validatedTarget.value
254
- })];
276
+ return [4 /*yield*/, vortex.acceptInvitations(sanitizedIds, acceptData)];
255
277
  case 7:
256
278
  result = _a.sent();
257
279
  return [2 /*return*/, (0, utils_1.createApiResponse)(reply, result)];
@@ -1 +1 @@
1
- {"version":3,"file":"jwt.d.ts","sourceRoot":"","sources":["../../src/handlers/jwt.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAKvD,wBAAsB,mBAAmB,CAAC,OAAO,EAAE,cAAc,EAAE,KAAK,EAAE,YAAY,kBAgDrF"}
1
+ {"version":3,"file":"jwt.d.ts","sourceRoot":"","sources":["../../src/handlers/jwt.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAKvD,wBAAsB,mBAAmB,CAAC,OAAO,EAAE,cAAc,EAAE,KAAK,EAAE,YAAY,kBAkDrF"}
@@ -79,7 +79,7 @@ function handleJwtGeneration(request, reply) {
79
79
  return [2 /*return*/, (0, utils_1.createErrorResponse)(reply, 'Invalid user format: must provide userId and userEmail', 500)];
80
80
  }
81
81
  jwtParams = {
82
- user: __assign({ id: authenticatedUser.userId, email: authenticatedUser.userEmail }, (authenticatedUser.adminScopes && authenticatedUser.adminScopes.length > 0 && {
82
+ user: __assign(__assign(__assign({ id: authenticatedUser.userId, email: authenticatedUser.userEmail }, (authenticatedUser.name && { name: authenticatedUser.name })), (authenticatedUser.avatarUrl && { avatarUrl: authenticatedUser.avatarUrl })), (authenticatedUser.adminScopes && authenticatedUser.adminScopes.length > 0 && {
83
83
  adminScopes: authenticatedUser.adminScopes
84
84
  })),
85
85
  };
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "@teamvortexsoftware/vortex-fastify-5-sdk",
3
3
  "description": "Drop-in Fastify module for Vortex API integration",
4
4
  "author": "@teamvortexsoftware",
5
- "version": "0.0.6",
5
+ "version": "0.2.0",
6
6
  "main": "./dist/index.js",
7
7
  "types": "./dist/index.d.ts",
8
8
  "exports": {
@@ -28,17 +28,17 @@
28
28
  "testEnvironment": "node"
29
29
  },
30
30
  "devDependencies": {
31
- "@eslint/js": "9.39.1",
31
+ "@eslint/js": "9.39.2",
32
32
  "@jest/globals": "29.7.0",
33
33
  "@types/node": "24.10.1",
34
- "eslint": "9.39.1",
34
+ "eslint": "9.39.2",
35
35
  "fastify": "^5.1.0",
36
36
  "jest": "29.7.0",
37
37
  "ts-jest": "29.4.6",
38
- "typescript-eslint": "8.46.2"
38
+ "typescript-eslint": "8.50.1"
39
39
  },
40
40
  "dependencies": {
41
- "@teamvortexsoftware/vortex-node-22-sdk": "^0.1.2"
41
+ "@teamvortexsoftware/vortex-node-22-sdk": "^0.3.0"
42
42
  },
43
43
  "peerDependencies": {
44
44
  "fastify": ">=5.0.0"