@dalmore/api-contracts 0.0.0-dev.2dc8e92 → 1.0.1

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.
@@ -1,6 +1,14 @@
1
1
  /**
2
- * Contract helpers - minimal subset for API documentation generation
2
+ * Contract helpers - minimal subset for API contracts package
3
+ * This file is copied directly to @dalmore/api-contracts
3
4
  */
5
+ import { HttpStatus } from '@nestjs/common';
6
+ import parsePhoneNumberFromString, {
7
+ CountryCode,
8
+ PhoneNumber,
9
+ } from 'libphonenumber-js';
10
+ import { err, ok, Result } from 'neverthrow';
11
+ import { ErrorResult } from '../types/common.types';
4
12
 
5
13
  type CurlOptions = {
6
14
  query?: Record<string, string>;
@@ -57,3 +65,24 @@ export const generateApiDescription = (
57
65
  ${curlExample}
58
66
  \`\`\``;
59
67
  };
68
+
69
+ /**
70
+ * Normalizes a phone number to E.164 format
71
+ */
72
+ export function normalizePhoneNumber(
73
+ phoneNumber: string,
74
+ countryCode: CountryCode,
75
+ ): Result<PhoneNumber, ErrorResult> {
76
+ const parsedPhoneNumber = parsePhoneNumberFromString(
77
+ phoneNumber,
78
+ countryCode,
79
+ );
80
+
81
+ if (!parsedPhoneNumber || !parsedPhoneNumber.isValid()) {
82
+ return err({
83
+ status: HttpStatus.BAD_REQUEST,
84
+ message: 'Invalid phone number. Only numbers',
85
+ });
86
+ }
87
+ return ok(parsedPhoneNumber);
88
+ }
@@ -0,0 +1,88 @@
1
+ /**
2
+ * Contract helpers - minimal subset for API contracts package
3
+ * This file is copied directly to @dalmore/api-contracts
4
+ */
5
+ import { HttpStatus } from '@nestjs/common';
6
+ import parsePhoneNumberFromString, {
7
+ CountryCode,
8
+ PhoneNumber,
9
+ } from 'libphonenumber-js';
10
+ import { err, ok, Result } from 'neverthrow';
11
+ import { ErrorResult } from './common.types';
12
+
13
+ type CurlOptions = {
14
+ query?: Record<string, string>;
15
+ headers?: Record<string, string>;
16
+ body?: Record<string, unknown>;
17
+ formData?: Record<string, string>;
18
+ };
19
+
20
+ export const authHeader: CurlOptions['headers'] = {
21
+ Authorization: 'Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9',
22
+ };
23
+
24
+ const generateCurlExample = (
25
+ method: string,
26
+ path: string,
27
+ options: CurlOptions,
28
+ ) => {
29
+ const baseUrl = 'https://dalmore-client-portal-api-prod.onrender.com/api/v1';
30
+ let curl = `curl -X ${method.toUpperCase()} '${baseUrl}${path}`;
31
+ if (options.query) {
32
+ const queryString = new URLSearchParams(options.query).toString();
33
+ curl += `?${queryString}`;
34
+ }
35
+ curl += "'";
36
+ if (options.headers) {
37
+ Object.entries(options.headers).forEach(([key, value]) => {
38
+ curl += ` \\\n --header '${key}: ${value}'`;
39
+ });
40
+ }
41
+ if (options.body) {
42
+ curl += ` \\\n --header 'Content-Type: application/json'`;
43
+ curl += ` \\\n --data '${JSON.stringify(options.body)}'`;
44
+ }
45
+ if (options.formData) {
46
+ Object.entries(options.formData).forEach(([key, value]) => {
47
+ curl += ` \\\n --form '${key}=${value}'`;
48
+ });
49
+ }
50
+ return curl;
51
+ };
52
+
53
+ export const generateApiDescription = (
54
+ summary: string,
55
+ method: string,
56
+ path: string,
57
+ options: CurlOptions,
58
+ ) => {
59
+ const curlExample = generateCurlExample(method, path, options);
60
+ return `${summary}
61
+
62
+ ### Example curl request
63
+
64
+ \`\`\`bash
65
+ ${curlExample}
66
+ \`\`\``;
67
+ };
68
+
69
+ /**
70
+ * Normalizes a phone number to E.164 format
71
+ */
72
+ export function normalizePhoneNumber(
73
+ phoneNumber: string,
74
+ countryCode: CountryCode,
75
+ ): Result<PhoneNumber, ErrorResult> {
76
+ const parsedPhoneNumber = parsePhoneNumberFromString(
77
+ phoneNumber,
78
+ countryCode,
79
+ );
80
+
81
+ if (!parsedPhoneNumber || !parsedPhoneNumber.isValid()) {
82
+ return err({
83
+ status: HttpStatus.BAD_REQUEST,
84
+ message: 'Invalid phone number. Only numbers',
85
+ });
86
+ }
87
+ return ok(parsedPhoneNumber);
88
+ }
@@ -1,5 +1,5 @@
1
1
  import { z } from 'zod';
2
- import { normalizePhoneNumber } from '../helpers';
2
+ import { normalizePhoneNumber } from './contract-helpers';
3
3
  import { CountryCodes } from './countries.types';
4
4
  import { CountryCode } from 'libphonenumber-js';
5
5
  import { ok } from 'neverthrow';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dalmore/api-contracts",
3
- "version": "0.0.0-dev.2dc8e92",
3
+ "version": "1.0.1",
4
4
  "description": "Type-safe API contracts for Dalmore Client Portal",
5
5
  "main": "./contracts/index.ts",
6
6
  "types": "./contracts/index.ts",
@@ -40,6 +40,10 @@
40
40
  "./types/*": {
41
41
  "types": "./common/types/*.ts",
42
42
  "default": "./common/types/*.ts"
43
+ },
44
+ "./helpers": {
45
+ "types": "./common/helpers/index.ts",
46
+ "default": "./common/helpers/index.ts"
43
47
  }
44
48
  },
45
49
  "files": [
@@ -64,7 +68,10 @@
64
68
  },
65
69
  "peerDependencies": {
66
70
  "@anatine/zod-openapi": "^1.14.2",
71
+ "@nestjs/common": "^11.0.0",
67
72
  "@ts-rest/core": "^3.52.1",
73
+ "libphonenumber-js": "^1.12.0",
74
+ "neverthrow": "^8.0.0",
68
75
  "typeid-js": "^1.2.0",
69
76
  "zod": "^3.24.4"
70
77
  },
@@ -74,4 +81,4 @@
74
81
  "engines": {
75
82
  "node": ">=24.0.0 <25.0.0"
76
83
  }
77
- }
84
+ }