Skip to content

Commit 3f2d130

Browse files
authored
Merge pull request #2 from aymann90/master
TypeScript Support
2 parents 28e930b + 562da0c commit 3f2d130

File tree

13 files changed

+374
-82
lines changed

13 files changed

+374
-82
lines changed

.gitignore

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
.idea/**/usage.statistics.xml
55
.idea/**/dictionaries
66
.idea/**/shelf
7-
7+
.idea*
88
# AWS User-specific
99
.idea/**/aws.xml
1010

CHANGELOG.md

Lines changed: 70 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,24 @@
11
# Changelog
22

3-
## v1.2.1 - 27 Apr, 2025
3+
## [1.2.2] - 2025-04-29
4+
5+
### Added
6+
7+
- TypeScript support with type definitions (index.d.ts)
8+
- Comprehensive JSDoc comments for better code documentation
9+
10+
### Changed
11+
12+
- Updated all dependencies to latest compatible versions
13+
- Enhanced JSON response formatting for errors
14+
15+
### Fixed
16+
17+
- Connection cleanup on errors
18+
- Schema registration to avoid duplicates
19+
- Central domain validation logic
20+
21+
## [1.2.1] - 2025-04-29
422

523
### Features
624

@@ -31,7 +49,7 @@ const connection = await queue.connect('redis://test:test@redis.test');
3149

3250
---
3351

34-
## v1.2.0 - 16 Apr, 2025
52+
## [1.2.0] - 2025-04-16
3553

3654
### Features
3755

@@ -44,7 +62,7 @@ const connection = await queue.connect('redis://test:test@redis.test');
4462

4563
---
4664

47-
## v1.1.0 - 16 Mar, 2025
65+
## [1.1.0] - 2025-03-16
4866

4967
Adding jest tests and some code improvements to queue connection.
5068

@@ -66,54 +84,54 @@ queueClass.publishMessage('support_test', {'message': 'test'}, true);
6684
const {queue, config} = require('node-tenancy');
6785

6886
function setConnectionConfig(is_tenant_connection) {
69-
if (is_tenant_connection) {
70-
config.setConfig({
71-
'connection': 'tenant',
72-
});
73-
} else {
74-
config.setConfig({
75-
'connection': 'central',
76-
});
77-
}
87+
if (is_tenant_connection) {
88+
config.setConfig({
89+
'connection': 'tenant',
90+
});
91+
} else {
92+
config.setConfig({
93+
'connection': 'central',
94+
});
95+
}
7896
}
7997

8098
async function getMessages(queue_name, is_tenant_connection = false) {
81-
setConnectionConfig(is_tenant_connection);
82-
83-
const conn = await queue.connect(queue.getConnectionUrl());
84-
const channel = await conn.createChannel();
85-
86-
await channel.assertQueue(queue_name);
87-
88-
channel.consume(queue_name, async (msg) => {
89-
if (msg !== null) {
90-
console.log('Received:', msg.content.toString());
91-
channel.ack(msg);
92-
} else {
93-
console.log('Consumer cancelled by server');
94-
}
95-
await channel.close();
96-
await conn.close();
97-
});
99+
setConnectionConfig(is_tenant_connection);
100+
101+
const conn = await queue.connect(queue.getConnectionUrl());
102+
const channel = await conn.createChannel();
103+
104+
await channel.assertQueue(queue_name);
105+
106+
channel.consume(queue_name, async (msg) => {
107+
if (msg !== null) {
108+
console.log('Received:', msg.content.toString());
109+
channel.ack(msg);
110+
} else {
111+
console.log('Consumer cancelled by server');
112+
}
113+
await channel.close();
114+
await conn.close();
115+
});
98116
}
99117

100118
async function publishMessage(queue_name, message, is_tenant_connection = false) {
101-
setConnectionConfig(is_tenant_connection);
102-
103-
const conn = await queue.connect(queue.getConnectionUrl());
104-
const channel = await conn.createChannel();
105-
channel.sendToQueue(queue_name, Buffer.from(JSON.stringify(message)));
106-
setTimeout(function () {
107-
conn.close();
108-
}, 500);
119+
setConnectionConfig(is_tenant_connection);
120+
121+
const conn = await queue.connect(queue.getConnectionUrl());
122+
const channel = await conn.createChannel();
123+
channel.sendToQueue(queue_name, Buffer.from(JSON.stringify(message)));
124+
setTimeout(function () {
125+
conn.close();
126+
}, 500);
109127
}
110128

111129
module.exports = {getMessages, publishMessage};
112130
```
113131

114132
---
115133

116-
## v1.0.4 - 7 Mar, 2025
134+
## [1.0.4] - 2025-03-07
117135

118136
### File Structure
119137

@@ -129,23 +147,23 @@ errors you might get with v1.0.4***
129147
const {queue} = require('node-tenancy');
130148

131149
queue.connect(queue.getConnectionUrl(), function (connectionErr, connection) {
132-
if (connectionErr) {
133-
console.log(connectionErr);
134-
}
135-
connection.createChannel(function (channelErr, channel) {
136-
if (channelErr) {
137-
console.log(channelErr);
150+
if (connectionErr) {
151+
console.log(connectionErr);
138152
}
153+
connection.createChannel(function (channelErr, channel) {
154+
if (channelErr) {
155+
console.log(channelErr);
156+
}
139157

140-
const queue = 'test';
158+
const queue = 'test';
141159

142-
channel.assertQueue(queue, {
143-
durable: true
144-
});
160+
channel.assertQueue(queue, {
161+
durable: true
162+
});
145163

146-
channel.consume(queue, function (msg) {
147-
console.log(msg);
148-
});
149-
})
164+
channel.consume(queue, function (msg) {
165+
console.log(msg);
166+
});
167+
})
150168
});
151169
```

README.md

Lines changed: 40 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ Trying to make it like [Tenancy for Laravel](https://tenancyforlaravel.com)
1313
- [Queue](#2-queue-connection)
1414
- [Mongoose Usage](#3-using-mongoose)
1515
- [Sql Usage](#4-using-sql-with-sequelize)
16+
- [TypeScript Support](#typescript-support)
1617
- [CHANGELOG](CHANGELOG.md) (for latest updates and changes)
1718

1819
## Support
@@ -68,7 +69,7 @@ const tenancy = require('node-tenancy');
6869
router.use(tenancy.initializeTenancyMiddleware);
6970

7071
router.get('/get', function (Request, Response) {
71-
return Response.status(200).json("Hello");
72+
return Response.status(200).json("Hello");
7273
});
7374
```
7475

@@ -82,9 +83,9 @@ const tenancy = require('node-tenancy');
8283
router.use(tenancy.initializeCentralMiddleware);
8384

8485
router.get('/get', function (Request, Response) {
85-
return Response.status(200).json({
86-
'tenant_id': tenancy.config.getConfig().tenant_id
87-
});
86+
return Response.status(200).json({
87+
'tenant_id': tenancy.config.getConfig().tenant_id
88+
});
8889
});
8990
```
9091

@@ -119,3 +120,38 @@ Read more about it here [Sequelize guide](docs/SQL.md).
119120

120121
**In case you are using mongodb we assume that domains is an array inside
121122
tenants collection**
123+
124+
## TypeScript Support
125+
126+
Tenancy now includes TypeScript type definitions. Example usage:
127+
128+
```typescript
129+
import {config, TenantSchema, db} from 'node-tenancy';
130+
import {Schema} from 'mongoose';
131+
132+
// Define schemas with TypeScript types
133+
interface User {
134+
username: string;
135+
email: string;
136+
active: boolean;
137+
createdAt: Date;
138+
}
139+
140+
const userSchema = new Schema<User>({
141+
username: String,
142+
email: {type: String, required: true},
143+
active: {type: Boolean, default: true},
144+
createdAt: {type: Date, default: Date.now}
145+
});
146+
147+
// Configure tenancy
148+
config.setConfig({
149+
central_domains: ["admin.myapp.com"],
150+
tenant_schemas: {
151+
"User": userSchema
152+
},
153+
central_schemas: {
154+
"Tenant": TenantSchema
155+
}
156+
});
157+
```

index.d.ts

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
// Type definitions for node-tenancy
2+
// Project: https://github.com/johnabil/tenancy
3+
// Definitions by: node-tenancy team
4+
5+
import { Schema, Connection, Model } from 'mongoose';
6+
import { Sequelize, ModelOptions } from 'sequelize';
7+
8+
declare namespace NodeTenancy {
9+
/**
10+
* Configuration interface
11+
*/
12+
interface Config {
13+
setConfig(config: ConfigOptions): void;
14+
getConfig(): ConfigOptions;
15+
}
16+
17+
/**
18+
* Configuration options
19+
*/
20+
interface ConfigOptions {
21+
connection?: string;
22+
central_domains?: string[];
23+
tenant_id?: string;
24+
tenant_name?: string;
25+
tenant_connection?: Connection | Sequelize;
26+
central_connection?: Connection | Sequelize;
27+
queue_connection?: string;
28+
tenant_schemas?: Record<string, Schema> | Array<(sequelize: Sequelize) => any>;
29+
central_schemas?: Record<string, Schema> | Array<(sequelize: Sequelize) => any>;
30+
db_options?: Record<string, any>;
31+
}
32+
33+
/**
34+
* Database utility functions
35+
*/
36+
interface DatabaseUtils {
37+
getDriverClass(): any;
38+
resolveTenantConnection(connection: string, db_name: string, options?: object): Connection | Sequelize;
39+
resolveCentralConnection(options?: object): Connection | Sequelize;
40+
registerSchemas(connection: Connection | Sequelize, schemas: Record<string, Schema> | Array<(sequelize: Sequelize) => any>): void;
41+
getModel(model_name: string): Model<any> | any;
42+
getDefaultTenantSchema(): Schema | ((sequelize: Sequelize) => any);
43+
}
44+
45+
/**
46+
* Queue utility functions
47+
*/
48+
interface QueueUtils {
49+
getConnectionUrl(): string;
50+
connect(url?: string, options?: object): Promise<any>;
51+
}
52+
53+
/**
54+
* Express middleware function
55+
*/
56+
type Middleware = (req: any, res: any, next: any) => void | Promise<void>;
57+
58+
/**
59+
* Main module interface
60+
*/
61+
interface NodeTenancy {
62+
config: Config;
63+
db: DatabaseUtils;
64+
queue: QueueUtils;
65+
TenantSchema: Schema;
66+
DomainSchema: (sequelize: Sequelize) => any;
67+
initializeTenancyMiddleware: Middleware;
68+
initializeCentralMiddleware: Middleware;
69+
}
70+
}
71+
72+
declare const nodeTenancy: NodeTenancy.NodeTenancy;
73+
74+
export = nodeTenancy;

package-lock.json

Lines changed: 23 additions & 9 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)