@togatherlabs/shared-utils 1.0.0 → 1.0.2

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
@@ -1 +1,175 @@
1
- # togather-shared-utils
1
+ # @togatherlabs/shared-utils
2
+
3
+ A collection of **shared TypeScript utilities, constants, and types** used across ToGather microservices.
4
+
5
+ [![npm package](https://img.shields.io/npm/v/@togatherlabs/shared-utils.svg)](https://www.npmjs.com/package/@togatherlabs/shared-utils)
6
+ [![npm downloads](https://img.shields.io/npm/dm/@togatherlabs/shared-utils.svg)](https://www.npmjs.com/package/@togatherlabs/shared-utils)
7
+ [![license](https://img.shields.io/npm/l/@togatherlabs/shared-utils.svg)](./LICENSE)
8
+
9
+ ## Table of Contents
10
+
11
+ 1. [Directory Structure](#directory-structure)
12
+ 2. [Package Development](#package-development)
13
+
14
+ * [Adding New Utilities](#adding-new-utilities)
15
+ * [Linting](#linting)
16
+ * [Building](#building)
17
+ * [Publishing Package](#publishing-package)
18
+ 3. [Using the Utilities](#using-the-utilities)
19
+
20
+ * [TypeScript](#typescript)
21
+ 4. [Best Practices](#best-practices)
22
+ 5. [Troubleshooting](#troubleshooting)
23
+ 6. [License](#license)
24
+
25
+ ## Directory Structure
26
+
27
+ The package follows a **clear folder structure** for maintainability:
28
+
29
+ ```
30
+ src/
31
+ ├── constants/
32
+ │ └── index.ts
33
+ ├── utils/
34
+ │ └── index.ts
35
+ ├── types/
36
+ │ └── index.ts
37
+ └── index.ts
38
+ ```
39
+
40
+ * **constants**: Shared constants across services
41
+ * **utils**: Reusable utility functions
42
+ * **types**: Shared TypeScript types and interfaces
43
+ * **index.ts**: Exports all public utilities
44
+
45
+ ## Package Development
46
+
47
+ ### Adding New Utilities
48
+
49
+ 1. Add your function, constant, or type in the appropriate folder (`utils`, `constants`, or `types`).
50
+ 2. Export it from the folder’s `index.ts`.
51
+ 3. Re-export from the root `index.ts` for public usage.
52
+
53
+ **Example:** Adding a new utility `capitalize`:
54
+
55
+ ```ts
56
+ // src/utils/capitalize.ts
57
+ export function capitalize(str: string): string {
58
+ return str.charAt(0).toUpperCase() + str.slice(1);
59
+ }
60
+
61
+ // src/utils/index.ts
62
+ export * from './capitalize';
63
+
64
+ // src/index.ts
65
+ export * from './utils';
66
+ ```
67
+
68
+ ### Linting
69
+
70
+ Check code style and catch errors using Biome:
71
+
72
+ ```bash
73
+ pnpm lint
74
+ pnpm lint:fix
75
+ ```
76
+
77
+ ### Building
78
+
79
+ Compile TypeScript into the `dist/` folder:
80
+
81
+ ```bash
82
+ pnpm build
83
+ ```
84
+
85
+ Check types without generating output:
86
+
87
+ ```bash
88
+ pnpm typecheck
89
+ ```
90
+
91
+ ### Publishing Package
92
+
93
+ To publish the package to npm:
94
+
95
+ ```bash
96
+ pnpm run release
97
+ ```
98
+
99
+ This script performs:
100
+
101
+ * Builds the package
102
+ * Commits changes
103
+ * Updates version (patch/minor/major)
104
+ * Publishes to npm with public access
105
+
106
+ Ensure all changes are committed and tests pass before publishing.
107
+
108
+ ## Using the Utilities
109
+
110
+ ### TypeScript
111
+
112
+ Install the package:
113
+
114
+ ```bash
115
+ pnpm add @togatherlabs/shared-utils
116
+ ```
117
+
118
+ Example usage:
119
+
120
+ ```ts
121
+ import { formatDate, generateId, logger } from '@togatherlabs/shared-utils';
122
+
123
+ // Format a date
124
+ console.log(formatDate(new Date()));
125
+
126
+ // Generate a unique ID
127
+ const id = generateId();
128
+ console.log(id);
129
+
130
+ // Log messages
131
+ logger.info('Service started');
132
+ logger.error('Failed to fetch data', { error: new Error('Network error') });
133
+ ```
134
+
135
+ ## Best Practices
136
+
137
+ * Keep utilities small and focused – each function should have a single responsibility.
138
+ * Type safety – use TypeScript types/interfaces, avoid `any`.
139
+ * Documentation – add JSDoc comments for each utility.
140
+ * Testing – write unit tests for every new utility.
141
+ * Consistent exports – always export utilities through `index.ts` files.
142
+
143
+ ## Troubleshooting
144
+
145
+ **Cannot find module '@togatherlabs/shared-utils'**
146
+
147
+ * Ensure the package is installed
148
+ * Check `tsconfig.json` paths if using path aliases
149
+ * Delete `node_modules` and reinstall dependencies
150
+
151
+ **Property 'myFunction' does not exist**
152
+
153
+ * Ensure the function is exported correctly
154
+ * Verify the import path matches the package export
155
+
156
+ **Build errors**
157
+
158
+ * Check for missing peer dependencies
159
+ * Ensure relative imports are correct
160
+ * Clean and rebuild the project
161
+
162
+ **Version mismatches across services**
163
+
164
+ * Make sure all services use compatible versions of shared-utils
165
+ * Check changelog for breaking changes
166
+
167
+ **TypeScript declaration errors**
168
+
169
+ * Ensure `declaration: true` is set in `tsconfig.json`
170
+ * Verify the `types` field in `package.json` points to the correct declaration file
171
+ * Run `pnpm build` to regenerate type definitions
172
+
173
+ ## License
174
+
175
+ MIT © ToGather Labs
@@ -1,3 +1,3 @@
1
- import type { UserConfig } from '@commitlint/types';
1
+ import type { UserConfig } from "@commitlint/types";
2
2
  declare const config: UserConfig;
3
3
  export default config;
@@ -1,89 +1,89 @@
1
1
  // This config follows the project guidelines
2
2
  // (https://docs.google.com/document/d/1psbMtN-PIF4oBbNc_pW_mtDPPAa_yPdV_apf-wq5spM/edit?tab=t.0)
3
3
  const config = {
4
- extends: ['@commitlint/config-conventional'],
4
+ extends: ["@commitlint/config-conventional"],
5
5
  rules: {
6
- 'scope-empty': [2, 'never'],
7
- 'scope-max-length': [2, 'always', 20],
6
+ "scope-empty": [2, "never"],
7
+ "scope-max-length": [2, "always", 20],
8
8
  // Subject rules
9
- 'subject-max-length': [2, 'always', 50],
10
- 'subject-case': [2, 'always', 'sentence-case'],
11
- 'subject-full-stop': [2, 'never', '.'],
9
+ "subject-max-length": [2, "always", 50],
10
+ "subject-case": [2, "always", "sentence-case"],
11
+ "subject-full-stop": [2, "never", "."],
12
12
  // Body rules
13
- 'body-empty': [0],
14
- 'body-max-line-length': [2, 'always', 72],
13
+ "body-empty": [0],
14
+ "body-max-line-length": [2, "always", 72],
15
15
  // Footer (optional)
16
- 'footer-max-line-length': [2, 'always', 72],
16
+ "footer-max-line-length": [2, "always", 72],
17
17
  },
18
18
  prompt: {
19
19
  settings: {
20
20
  enableMultipleScopes: false,
21
21
  },
22
22
  messages: {
23
- skip: ':skip (press enter to skip)',
24
- max: 'Max %d characters',
25
- min: 'Min %d characters',
26
- emptyWarning: 'This field cannot be empty',
27
- upperLimitWarning: 'Character limit exceeded',
28
- lowerLimitWarning: 'Too few characters',
23
+ skip: ":skip (press enter to skip)",
24
+ max: "Max %d characters",
25
+ min: "Min %d characters",
26
+ emptyWarning: "This field cannot be empty",
27
+ upperLimitWarning: "Character limit exceeded",
28
+ lowerLimitWarning: "Too few characters",
29
29
  },
30
30
  questions: {
31
31
  type: {
32
32
  description: "Select the type of change you're committing:",
33
33
  enum: {
34
34
  feat: {
35
- description: '✨ A new feature',
36
- title: 'Feature',
37
- emoji: '',
35
+ description: "✨ A new feature",
36
+ title: "Feature",
37
+ emoji: "",
38
38
  },
39
39
  fix: {
40
- description: '🐛 A bug fix',
41
- title: 'Bug Fix',
42
- emoji: '🐛',
40
+ description: "🐛 A bug fix",
41
+ title: "Bug Fix",
42
+ emoji: "🐛",
43
43
  },
44
44
  docs: {
45
- description: '📚 Documentation only changes',
46
- title: 'Documentation',
47
- emoji: '📚',
45
+ description: "📚 Documentation only changes",
46
+ title: "Documentation",
47
+ emoji: "📚",
48
48
  },
49
49
  style: {
50
- description: '💅 Changes that do not affect code meaning (formatting, etc.)',
51
- title: 'Style',
52
- emoji: '💅',
50
+ description: "💅 Changes that do not affect code meaning (formatting, etc.)",
51
+ title: "Style",
52
+ emoji: "💅",
53
53
  },
54
54
  refactor: {
55
- description: '🔧 Code change that neither fixes a bug nor adds a feature',
56
- title: 'Refactor',
57
- emoji: '🔧',
55
+ description: "🔧 Code change that neither fixes a bug nor adds a feature",
56
+ title: "Refactor",
57
+ emoji: "🔧",
58
58
  },
59
59
  test: {
60
- description: '✅ Adding or updating tests',
61
- title: 'Test',
62
- emoji: '',
60
+ description: "✅ Adding or updating tests",
61
+ title: "Test",
62
+ emoji: "",
63
63
  },
64
64
  chore: {
65
- description: '🛠 Maintenance tasks (e.g., tooling, dependencies)',
66
- title: 'Chore',
67
- emoji: '🛠',
65
+ description: "🛠 Maintenance tasks (e.g., tooling, dependencies)",
66
+ title: "Chore",
67
+ emoji: "🛠",
68
68
  },
69
- perf: { description: '⚡ Performance improvement', title: 'Performance', emoji: '' },
69
+ perf: { description: "⚡ Performance improvement", title: "Performance", emoji: "" },
70
70
  build: {
71
- description: '🏗 Build system or dependency changes',
72
- title: 'Build',
73
- emoji: '🏗',
71
+ description: "🏗 Build system or dependency changes",
72
+ title: "Build",
73
+ emoji: "🏗",
74
74
  },
75
- ci: { description: '🔁 CI/CD configuration', title: 'CI', emoji: '🔁' },
76
- revert: { description: '⏪ Reverts a previous commit', title: 'Revert', emoji: '' },
75
+ ci: { description: "🔁 CI/CD configuration", title: "CI", emoji: "🔁" },
76
+ revert: { description: "⏪ Reverts a previous commit", title: "Revert", emoji: "" },
77
77
  },
78
78
  },
79
79
  scope: {
80
- description: 'Scope of this change (e.g., auth, ui, api)',
80
+ description: "Scope of this change (e.g., auth, ui, api)",
81
81
  },
82
82
  subject: {
83
- description: 'Write a short, imperative description (max 50 chars, e.g., Add login validation)',
83
+ description: "Write a short, imperative description (max 50 chars, e.g., Add login validation)",
84
84
  },
85
85
  body: {
86
- description: 'Provide a detailed description of what changed, why, and how (optional)',
86
+ description: "Provide a detailed description of what changed, why, and how (optional)",
87
87
  },
88
88
  },
89
89
  },
@@ -1 +1 @@
1
- export * from './sample';
1
+ export * from "./sample";
@@ -1 +1 @@
1
- export * from './sample';
1
+ export * from "./sample";
@@ -1,3 +1,3 @@
1
1
  export const SAMPLE = {
2
- Char: 'A'
2
+ Char: "A",
3
3
  };
@@ -1,10 +1,10 @@
1
- export function formatDate(date, locale = 'en-IN') {
2
- if (!(date instanceof Date) || isNaN(date.getTime())) {
3
- throw new Error('Invalid Date');
1
+ export function formatDate(date, locale = "en-IN") {
2
+ if (!(date instanceof Date) || Number.isNaN(date.getTime())) {
3
+ throw new Error("Invalid Date");
4
4
  }
5
5
  return date.toLocaleDateString(locale, {
6
- year: 'numeric',
7
- month: 'short',
8
- day: 'numeric',
6
+ year: "numeric",
7
+ month: "short",
8
+ day: "numeric",
9
9
  });
10
10
  }
@@ -1 +1 @@
1
- export * from './formatDate';
1
+ export * from "./formatDate";
@@ -1 +1 @@
1
- export * from './formatDate';
1
+ export * from "./formatDate";
@@ -1,3 +1,3 @@
1
- export * from './helpers';
2
- export * from './constants';
3
- export * from './types';
1
+ export * from "./constants";
2
+ export * from "./helpers";
3
+ export * from "./types";
package/dist/src/index.js CHANGED
@@ -1,3 +1,3 @@
1
- export * from './helpers';
2
- export * from './constants';
3
- export * from './types';
1
+ export * from "./constants";
2
+ export * from "./helpers";
3
+ export * from "./types";
@@ -1 +1 @@
1
- export * from './user';
1
+ export * from "./user";
@@ -1 +1 @@
1
- export * from './user';
1
+ export * from "./user";
@@ -1,7 +1,7 @@
1
- import { describe, it, expect } from 'vitest';
2
- import * as constants from '../../../src/constants/sample';
3
- describe('sample constants', () => {
4
- it('should export constants correctly', () => {
1
+ import { describe, expect, it } from "vitest";
2
+ import * as constants from "../../../src/constants/sample";
3
+ describe("sample constants", () => {
4
+ it("should export constants correctly", () => {
5
5
  expect(constants).toBeDefined();
6
6
  });
7
7
  });
@@ -1,18 +1,18 @@
1
- import { describe, it, expect } from 'vitest';
2
- import { formatDate } from '../../../src/helpers/formatDate';
3
- describe('formatDate helper', () => {
4
- it('should format a valid date correctly', () => {
5
- const date = new Date('2025-10-14T00:00:00Z');
1
+ import { describe, expect, it } from "vitest";
2
+ import { formatDate } from "../../../src/helpers/formatDate";
3
+ describe("formatDate helper", () => {
4
+ it("should format a valid date correctly", () => {
5
+ const date = new Date("2025-10-14T00:00:00Z");
6
6
  const formatted = formatDate(date);
7
- expect(formatted).toBe('14 Oct 2025');
7
+ expect(formatted).toBe("14 Oct 2025");
8
8
  });
9
- it('should format date in custom locale', () => {
10
- const date = new Date('2025-10-14T00:00:00Z');
11
- const formatted = formatDate(date, 'en-US');
9
+ it("should format date in custom locale", () => {
10
+ const date = new Date("2025-10-14T00:00:00Z");
11
+ const formatted = formatDate(date, "en-US");
12
12
  expect(formatted).toMatch(/Oct/);
13
13
  });
14
- it('should throw an error for invalid date', () => {
14
+ it("should throw an error for invalid date", () => {
15
15
  // @ts-expect-error testing invalid date
16
- expect(() => formatDate('not-a-date')).toThrowError('Invalid Date');
16
+ expect(() => formatDate("not-a-date")).toThrowError("Invalid Date");
17
17
  });
18
18
  });
@@ -1,7 +1,7 @@
1
- import { describe, it, expect } from 'vitest';
2
- import * as utils from '../../src';
3
- describe('index.ts', () => {
4
- it('should export all modules correctly', () => {
1
+ import { describe, expect, it } from "vitest";
2
+ import * as utils from "../../src";
3
+ describe("index.ts", () => {
4
+ it("should export all modules correctly", () => {
5
5
  expect(utils).toBeDefined();
6
6
  expect(utils.formatDate).toBeInstanceOf(Function); // Example for a helper
7
7
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@togatherlabs/shared-utils",
3
- "version": "1.0.0",
3
+ "version": "1.0.2",
4
4
  "description": "Shared utility functions, constants, and types for ToGather microservices",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -55,7 +55,11 @@
55
55
  "test:ui": "vitest --ui",
56
56
  "commit": "git-cz",
57
57
  "package:patch": "pnpm version patch",
58
+ "package:minor": "pnpm version minor",
59
+ "package:major": "pnpm version major",
58
60
  "package:publish": "pnpm publish --access public",
59
- "release": "pnpm build && git add . && pnpm commit && pnpm package:patch && git push --follow-tags && pnpm package:publish"
61
+ "release:patch": "pnpm build && git add . && pnpm commit && pnpm package:patch && git push --follow-tags && pnpm package:publish",
62
+ "release:minor": "pnpm build && git add . && pnpm commit && pnpm package:minor && git push --follow-tags && pnpm package:publish",
63
+ "release:major": "pnpm build && git add . && pnpm commit && pnpm package:major && git push --follow-tags && pnpm package:publish"
60
64
  }
61
65
  }