@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 +175 -1
- package/dist/commitlint.config.d.ts +1 -1
- package/dist/commitlint.config.js +45 -45
- package/dist/src/constants/index.d.ts +1 -1
- package/dist/src/constants/index.js +1 -1
- package/dist/src/constants/sample.js +1 -1
- package/dist/src/helpers/formatDate.js +6 -6
- package/dist/src/helpers/index.d.ts +1 -1
- package/dist/src/helpers/index.js +1 -1
- package/dist/src/index.d.ts +3 -3
- package/dist/src/index.js +3 -3
- package/dist/src/types/index.d.ts +1 -1
- package/dist/src/types/index.js +1 -1
- package/dist/tests/unit/constants/sample.test.js +4 -4
- package/dist/tests/unit/helpers/formatDate.test.js +11 -11
- package/dist/tests/unit/index.test.js +4 -4
- package/package.json +6 -2
package/README.md
CHANGED
|
@@ -1 +1,175 @@
|
|
|
1
|
-
#
|
|
1
|
+
# @togatherlabs/shared-utils
|
|
2
|
+
|
|
3
|
+
A collection of **shared TypeScript utilities, constants, and types** used across ToGather microservices.
|
|
4
|
+
|
|
5
|
+
[](https://www.npmjs.com/package/@togatherlabs/shared-utils)
|
|
6
|
+
[](https://www.npmjs.com/package/@togatherlabs/shared-utils)
|
|
7
|
+
[](./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,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: [
|
|
4
|
+
extends: ["@commitlint/config-conventional"],
|
|
5
5
|
rules: {
|
|
6
|
-
|
|
7
|
-
|
|
6
|
+
"scope-empty": [2, "never"],
|
|
7
|
+
"scope-max-length": [2, "always", 20],
|
|
8
8
|
// Subject rules
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
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
|
-
|
|
14
|
-
|
|
13
|
+
"body-empty": [0],
|
|
14
|
+
"body-max-line-length": [2, "always", 72],
|
|
15
15
|
// Footer (optional)
|
|
16
|
-
|
|
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:
|
|
24
|
-
max:
|
|
25
|
-
min:
|
|
26
|
-
emptyWarning:
|
|
27
|
-
upperLimitWarning:
|
|
28
|
-
lowerLimitWarning:
|
|
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:
|
|
36
|
-
title:
|
|
37
|
-
emoji:
|
|
35
|
+
description: "✨ A new feature",
|
|
36
|
+
title: "Feature",
|
|
37
|
+
emoji: "✨",
|
|
38
38
|
},
|
|
39
39
|
fix: {
|
|
40
|
-
description:
|
|
41
|
-
title:
|
|
42
|
-
emoji:
|
|
40
|
+
description: "🐛 A bug fix",
|
|
41
|
+
title: "Bug Fix",
|
|
42
|
+
emoji: "🐛",
|
|
43
43
|
},
|
|
44
44
|
docs: {
|
|
45
|
-
description:
|
|
46
|
-
title:
|
|
47
|
-
emoji:
|
|
45
|
+
description: "📚 Documentation only changes",
|
|
46
|
+
title: "Documentation",
|
|
47
|
+
emoji: "📚",
|
|
48
48
|
},
|
|
49
49
|
style: {
|
|
50
|
-
description:
|
|
51
|
-
title:
|
|
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:
|
|
56
|
-
title:
|
|
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:
|
|
61
|
-
title:
|
|
62
|
-
emoji:
|
|
60
|
+
description: "✅ Adding or updating tests",
|
|
61
|
+
title: "Test",
|
|
62
|
+
emoji: "✅",
|
|
63
63
|
},
|
|
64
64
|
chore: {
|
|
65
|
-
description:
|
|
66
|
-
title:
|
|
67
|
-
emoji:
|
|
65
|
+
description: "🛠 Maintenance tasks (e.g., tooling, dependencies)",
|
|
66
|
+
title: "Chore",
|
|
67
|
+
emoji: "🛠",
|
|
68
68
|
},
|
|
69
|
-
perf: { description:
|
|
69
|
+
perf: { description: "⚡ Performance improvement", title: "Performance", emoji: "⚡" },
|
|
70
70
|
build: {
|
|
71
|
-
description:
|
|
72
|
-
title:
|
|
73
|
-
emoji:
|
|
71
|
+
description: "🏗 Build system or dependency changes",
|
|
72
|
+
title: "Build",
|
|
73
|
+
emoji: "🏗",
|
|
74
74
|
},
|
|
75
|
-
ci: { description:
|
|
76
|
-
revert: { description:
|
|
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:
|
|
80
|
+
description: "Scope of this change (e.g., auth, ui, api)",
|
|
81
81
|
},
|
|
82
82
|
subject: {
|
|
83
|
-
description:
|
|
83
|
+
description: "Write a short, imperative description (max 50 chars, e.g., Add login validation)",
|
|
84
84
|
},
|
|
85
85
|
body: {
|
|
86
|
-
description:
|
|
86
|
+
description: "Provide a detailed description of what changed, why, and how (optional)",
|
|
87
87
|
},
|
|
88
88
|
},
|
|
89
89
|
},
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export * from
|
|
1
|
+
export * from "./sample";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export * from
|
|
1
|
+
export * from "./sample";
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
export function formatDate(date, locale =
|
|
2
|
-
if (!(date instanceof Date) || isNaN(date.getTime())) {
|
|
3
|
-
throw new Error(
|
|
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:
|
|
7
|
-
month:
|
|
8
|
-
day:
|
|
6
|
+
year: "numeric",
|
|
7
|
+
month: "short",
|
|
8
|
+
day: "numeric",
|
|
9
9
|
});
|
|
10
10
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export * from
|
|
1
|
+
export * from "./formatDate";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export * from
|
|
1
|
+
export * from "./formatDate";
|
package/dist/src/index.d.ts
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
export * from
|
|
2
|
-
export * from
|
|
3
|
-
export * from
|
|
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
|
|
2
|
-
export * from
|
|
3
|
-
export * from
|
|
1
|
+
export * from "./constants";
|
|
2
|
+
export * from "./helpers";
|
|
3
|
+
export * from "./types";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export * from
|
|
1
|
+
export * from "./user";
|
package/dist/src/types/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export * from
|
|
1
|
+
export * from "./user";
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { describe,
|
|
2
|
-
import * as constants from
|
|
3
|
-
describe(
|
|
4
|
-
it(
|
|
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,
|
|
2
|
-
import { formatDate } from
|
|
3
|
-
describe(
|
|
4
|
-
it(
|
|
5
|
-
const date = new Date(
|
|
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(
|
|
7
|
+
expect(formatted).toBe("14 Oct 2025");
|
|
8
8
|
});
|
|
9
|
-
it(
|
|
10
|
-
const date = new Date(
|
|
11
|
-
const formatted = formatDate(date,
|
|
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(
|
|
14
|
+
it("should throw an error for invalid date", () => {
|
|
15
15
|
// @ts-expect-error testing invalid date
|
|
16
|
-
expect(() => formatDate(
|
|
16
|
+
expect(() => formatDate("not-a-date")).toThrowError("Invalid Date");
|
|
17
17
|
});
|
|
18
18
|
});
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { describe,
|
|
2
|
-
import * as utils from
|
|
3
|
-
describe(
|
|
4
|
-
it(
|
|
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.
|
|
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
|
}
|