@honeyfield/rent2b-mcp 1.0.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/dist/api-client.d.ts +24 -0
- package/dist/api-client.js +77 -0
- package/dist/api-client.js.map +1 -0
- package/dist/config.d.ts +5 -0
- package/dist/config.js +14 -0
- package/dist/config.js.map +1 -0
- package/dist/generator/openapi-parser.d.ts +30 -0
- package/dist/generator/openapi-parser.js +95 -0
- package/dist/generator/openapi-parser.js.map +1 -0
- package/dist/generator/tool-generator.d.ts +13 -0
- package/dist/generator/tool-generator.js +68 -0
- package/dist/generator/tool-generator.js.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +65 -0
- package/dist/index.js.map +1 -0
- package/dist/overrides/index.d.ts +10 -0
- package/dist/overrides/index.js +19 -0
- package/dist/overrides/index.js.map +1 -0
- package/dist/overrides/tool-overrides.json +184 -0
- package/dist/server.d.ts +3 -0
- package/dist/server.js +114 -0
- package/dist/server.js.map +1 -0
- package/generated/tools.json +3136 -0
- package/package.json +54 -0
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { Config } from './config.js';
|
|
2
|
+
export interface ApiResponse<T = unknown> {
|
|
3
|
+
data: T;
|
|
4
|
+
status: number;
|
|
5
|
+
}
|
|
6
|
+
export interface ApiError {
|
|
7
|
+
message: string;
|
|
8
|
+
statusCode: number;
|
|
9
|
+
details?: unknown;
|
|
10
|
+
}
|
|
11
|
+
export declare class Rent2bApiClient {
|
|
12
|
+
private config;
|
|
13
|
+
private client;
|
|
14
|
+
private organizationId;
|
|
15
|
+
constructor(config: Config);
|
|
16
|
+
resolveOrganization(): Promise<number>;
|
|
17
|
+
getOrganizationId(): number;
|
|
18
|
+
request<T = unknown>(method: 'GET' | 'POST' | 'PATCH' | 'PUT' | 'DELETE', path: string, data?: unknown, params?: Record<string, unknown>): Promise<ApiResponse<T>>;
|
|
19
|
+
get<T = unknown>(path: string, params?: Record<string, unknown>): Promise<ApiResponse<T>>;
|
|
20
|
+
post<T = unknown>(path: string, data?: unknown): Promise<ApiResponse<T>>;
|
|
21
|
+
patch<T = unknown>(path: string, data?: unknown): Promise<ApiResponse<T>>;
|
|
22
|
+
put<T = unknown>(path: string, data?: unknown): Promise<ApiResponse<T>>;
|
|
23
|
+
delete<T = unknown>(path: string): Promise<ApiResponse<T>>;
|
|
24
|
+
}
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import axios, { AxiosError } from 'axios';
|
|
2
|
+
export class Rent2bApiClient {
|
|
3
|
+
config;
|
|
4
|
+
client;
|
|
5
|
+
organizationId = null;
|
|
6
|
+
constructor(config) {
|
|
7
|
+
this.config = config;
|
|
8
|
+
this.client = axios.create({
|
|
9
|
+
baseURL: config.apiUrl,
|
|
10
|
+
headers: {
|
|
11
|
+
'X-API-Key': config.apiKey,
|
|
12
|
+
'Content-Type': 'application/json',
|
|
13
|
+
},
|
|
14
|
+
timeout: 30_000,
|
|
15
|
+
});
|
|
16
|
+
}
|
|
17
|
+
async resolveOrganization() {
|
|
18
|
+
if (this.organizationId)
|
|
19
|
+
return this.organizationId;
|
|
20
|
+
const response = await this.client.get('/organizations');
|
|
21
|
+
const orgs = response.data;
|
|
22
|
+
if (!Array.isArray(orgs) || orgs.length === 0) {
|
|
23
|
+
throw new Error('No organizations found for this API key');
|
|
24
|
+
}
|
|
25
|
+
this.organizationId = orgs[0].id;
|
|
26
|
+
return this.organizationId;
|
|
27
|
+
}
|
|
28
|
+
getOrganizationId() {
|
|
29
|
+
if (!this.organizationId) {
|
|
30
|
+
throw new Error('Organization not resolved. Call resolveOrganization() first.');
|
|
31
|
+
}
|
|
32
|
+
return this.organizationId;
|
|
33
|
+
}
|
|
34
|
+
async request(method, path, data, params) {
|
|
35
|
+
const resolvedPath = path.replace('{organizationId}', String(this.getOrganizationId()));
|
|
36
|
+
try {
|
|
37
|
+
const response = await this.client.request({
|
|
38
|
+
method,
|
|
39
|
+
url: resolvedPath,
|
|
40
|
+
data,
|
|
41
|
+
params,
|
|
42
|
+
});
|
|
43
|
+
return { data: response.data, status: response.status };
|
|
44
|
+
}
|
|
45
|
+
catch (error) {
|
|
46
|
+
if (error instanceof AxiosError && error.response) {
|
|
47
|
+
const apiError = {
|
|
48
|
+
message: error.response.data?.message || error.message,
|
|
49
|
+
statusCode: error.response.status,
|
|
50
|
+
details: error.response.data,
|
|
51
|
+
};
|
|
52
|
+
throw apiError;
|
|
53
|
+
}
|
|
54
|
+
throw {
|
|
55
|
+
message: error instanceof Error ? error.message : 'Network error',
|
|
56
|
+
statusCode: 0,
|
|
57
|
+
details: null,
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
async get(path, params) {
|
|
62
|
+
return this.request('GET', path, undefined, params);
|
|
63
|
+
}
|
|
64
|
+
async post(path, data) {
|
|
65
|
+
return this.request('POST', path, data);
|
|
66
|
+
}
|
|
67
|
+
async patch(path, data) {
|
|
68
|
+
return this.request('PATCH', path, data);
|
|
69
|
+
}
|
|
70
|
+
async put(path, data) {
|
|
71
|
+
return this.request('PUT', path, data);
|
|
72
|
+
}
|
|
73
|
+
async delete(path) {
|
|
74
|
+
return this.request('DELETE', path);
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
//# sourceMappingURL=api-client.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"api-client.js","sourceRoot":"","sources":["../src/api-client.ts"],"names":[],"mappings":"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"}
|
package/dist/config.d.ts
ADDED
package/dist/config.js
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
export function loadConfig() {
|
|
2
|
+
const apiKey = process.env.RENT2B_API_KEY;
|
|
3
|
+
if (!apiKey) {
|
|
4
|
+
throw new Error('RENT2B_API_KEY environment variable is required');
|
|
5
|
+
}
|
|
6
|
+
if (!apiKey.startsWith('r2b_')) {
|
|
7
|
+
throw new Error('RENT2B_API_KEY must start with "r2b_"');
|
|
8
|
+
}
|
|
9
|
+
return {
|
|
10
|
+
apiKey,
|
|
11
|
+
apiUrl: process.env.RENT2B_API_URL || 'https://api.rent2b.net/api/v1',
|
|
12
|
+
};
|
|
13
|
+
}
|
|
14
|
+
//# sourceMappingURL=config.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAKA,MAAM,UAAU,UAAU;IACxB,MAAM,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,cAAc,CAAC;IAC1C,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,MAAM,IAAI,KAAK,CAAC,iDAAiD,CAAC,CAAC;IACrE,CAAC;IACD,IAAI,CAAC,MAAM,CAAC,UAAU,CAAC,MAAM,CAAC,EAAE,CAAC;QAC/B,MAAM,IAAI,KAAK,CAAC,uCAAuC,CAAC,CAAC;IAC3D,CAAC;IACD,OAAO;QACL,MAAM;QACN,MAAM,EAAE,OAAO,CAAC,GAAG,CAAC,cAAc,IAAI,+BAA+B;KACtE,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
export interface ParsedEndpoint {
|
|
2
|
+
operationId: string;
|
|
3
|
+
method: string;
|
|
4
|
+
path: string;
|
|
5
|
+
summary: string;
|
|
6
|
+
description: string;
|
|
7
|
+
parameters: ParsedParameter[];
|
|
8
|
+
requestBody?: ParsedRequestBody;
|
|
9
|
+
tags: string[];
|
|
10
|
+
}
|
|
11
|
+
export interface ParsedParameter {
|
|
12
|
+
name: string;
|
|
13
|
+
in: 'path' | 'query' | 'header';
|
|
14
|
+
required: boolean;
|
|
15
|
+
type: string;
|
|
16
|
+
description: string;
|
|
17
|
+
}
|
|
18
|
+
export interface ParsedRequestBody {
|
|
19
|
+
required: boolean;
|
|
20
|
+
properties: Record<string, {
|
|
21
|
+
type: string;
|
|
22
|
+
description?: string;
|
|
23
|
+
required?: boolean;
|
|
24
|
+
enum?: string[];
|
|
25
|
+
format?: string;
|
|
26
|
+
}>;
|
|
27
|
+
}
|
|
28
|
+
export declare function shouldIncludeEndpoint(path: string): boolean;
|
|
29
|
+
export declare function fetchAndParseOpenApi(swaggerUrl: string): Promise<ParsedEndpoint[]>;
|
|
30
|
+
export declare function parseOpenApiSpec(spec: any): ParsedEndpoint[];
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
import axios from 'axios';
|
|
2
|
+
const INCLUDED_PREFIXES = [
|
|
3
|
+
'/items',
|
|
4
|
+
'/rooms',
|
|
5
|
+
'/bookings',
|
|
6
|
+
'/locations',
|
|
7
|
+
'/time-slots',
|
|
8
|
+
'/categories',
|
|
9
|
+
'/organizations/{organizationId}/guests',
|
|
10
|
+
'/statistics',
|
|
11
|
+
'/organizations/{organizationId}/locations/{locationId}/items/{itemId}/availability',
|
|
12
|
+
];
|
|
13
|
+
function stripApiPrefix(path) {
|
|
14
|
+
return path.replace(/^\/api\/v\d+/, '');
|
|
15
|
+
}
|
|
16
|
+
export function shouldIncludeEndpoint(path) {
|
|
17
|
+
const stripped = stripApiPrefix(path);
|
|
18
|
+
return INCLUDED_PREFIXES.some((prefix) => stripped.startsWith(prefix));
|
|
19
|
+
}
|
|
20
|
+
function resolveRef(spec, ref) {
|
|
21
|
+
const parts = ref.replace('#/', '').split('/');
|
|
22
|
+
let current = spec;
|
|
23
|
+
for (const part of parts) {
|
|
24
|
+
current = current?.[part];
|
|
25
|
+
}
|
|
26
|
+
return current;
|
|
27
|
+
}
|
|
28
|
+
function extractProperties(spec, schema) {
|
|
29
|
+
if (!schema)
|
|
30
|
+
return {};
|
|
31
|
+
const resolved = schema.$ref ? resolveRef(spec, schema.$ref) : schema;
|
|
32
|
+
if (!resolved?.properties)
|
|
33
|
+
return {};
|
|
34
|
+
const requiredFields = new Set(resolved.required || []);
|
|
35
|
+
const props = {};
|
|
36
|
+
for (const [name, prop] of Object.entries(resolved.properties)) {
|
|
37
|
+
const resolvedProp = prop.$ref ? resolveRef(spec, prop.$ref) : prop;
|
|
38
|
+
props[name] = {
|
|
39
|
+
type: resolvedProp.type || 'string',
|
|
40
|
+
description: resolvedProp.description,
|
|
41
|
+
required: requiredFields.has(name),
|
|
42
|
+
enum: resolvedProp.enum,
|
|
43
|
+
format: resolvedProp.format,
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
return props;
|
|
47
|
+
}
|
|
48
|
+
export async function fetchAndParseOpenApi(swaggerUrl) {
|
|
49
|
+
const response = await axios.get(swaggerUrl);
|
|
50
|
+
const spec = response.data;
|
|
51
|
+
return parseOpenApiSpec(spec);
|
|
52
|
+
}
|
|
53
|
+
export function parseOpenApiSpec(spec) {
|
|
54
|
+
const endpoints = [];
|
|
55
|
+
for (const [path, methods] of Object.entries(spec.paths || {})) {
|
|
56
|
+
if (!shouldIncludeEndpoint(path))
|
|
57
|
+
continue;
|
|
58
|
+
for (const [method, operation] of Object.entries(methods)) {
|
|
59
|
+
if (['get', 'post', 'put', 'patch', 'delete'].indexOf(method) === -1)
|
|
60
|
+
continue;
|
|
61
|
+
const parameters = (operation.parameters || []).map((p) => {
|
|
62
|
+
const resolved = p.$ref ? resolveRef(spec, p.$ref) : p;
|
|
63
|
+
return {
|
|
64
|
+
name: resolved.name,
|
|
65
|
+
in: resolved.in,
|
|
66
|
+
required: resolved.required ?? false,
|
|
67
|
+
type: resolved.schema?.type || 'string',
|
|
68
|
+
description: resolved.description || '',
|
|
69
|
+
};
|
|
70
|
+
});
|
|
71
|
+
let requestBody;
|
|
72
|
+
if (operation.requestBody) {
|
|
73
|
+
const content = operation.requestBody.content?.['application/json']?.schema;
|
|
74
|
+
if (content) {
|
|
75
|
+
requestBody = {
|
|
76
|
+
required: operation.requestBody.required ?? false,
|
|
77
|
+
properties: extractProperties(spec, content),
|
|
78
|
+
};
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
endpoints.push({
|
|
82
|
+
operationId: operation.operationId || `${method}_${path.replace(/\//g, '_')}`,
|
|
83
|
+
method: method.toUpperCase(),
|
|
84
|
+
path: stripApiPrefix(path),
|
|
85
|
+
summary: operation.summary || '',
|
|
86
|
+
description: operation.description || operation.summary || '',
|
|
87
|
+
parameters,
|
|
88
|
+
requestBody,
|
|
89
|
+
tags: operation.tags || [],
|
|
90
|
+
});
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
return endpoints;
|
|
94
|
+
}
|
|
95
|
+
//# sourceMappingURL=openapi-parser.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"openapi-parser.js","sourceRoot":"","sources":["../../src/generator/openapi-parser.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { ParsedEndpoint } from './openapi-parser.js';
|
|
2
|
+
export interface GeneratedTool {
|
|
3
|
+
name: string;
|
|
4
|
+
description: string;
|
|
5
|
+
method: string;
|
|
6
|
+
path: string;
|
|
7
|
+
inputSchema: {
|
|
8
|
+
type: 'object';
|
|
9
|
+
properties: Record<string, any>;
|
|
10
|
+
required: string[];
|
|
11
|
+
};
|
|
12
|
+
}
|
|
13
|
+
export declare function generateTools(endpoints: ParsedEndpoint[]): GeneratedTool[];
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import { getOverride } from '../overrides/index.js';
|
|
2
|
+
function generateToolName(endpoint) {
|
|
3
|
+
const { method, path } = endpoint;
|
|
4
|
+
const cleaned = path
|
|
5
|
+
.replace(/\/organizations\/\{organizationId\}/g, '')
|
|
6
|
+
.replace(/\/\{[^}]+\}/g, '')
|
|
7
|
+
.replace(/^\//, '')
|
|
8
|
+
.replace(/\//g, '_')
|
|
9
|
+
.replace(/-/g, '_');
|
|
10
|
+
const action = method === 'GET'
|
|
11
|
+
? 'list'
|
|
12
|
+
: method === 'POST'
|
|
13
|
+
? 'create'
|
|
14
|
+
: method === 'PATCH' || method === 'PUT'
|
|
15
|
+
? 'update'
|
|
16
|
+
: method === 'DELETE'
|
|
17
|
+
? 'delete'
|
|
18
|
+
: method.toLowerCase();
|
|
19
|
+
return `rent2b_${cleaned}_${action}`;
|
|
20
|
+
}
|
|
21
|
+
export function generateTools(endpoints) {
|
|
22
|
+
const tools = [];
|
|
23
|
+
for (const endpoint of endpoints) {
|
|
24
|
+
const override = getOverride(endpoint.method, endpoint.path);
|
|
25
|
+
const properties = {};
|
|
26
|
+
const required = [];
|
|
27
|
+
for (const param of endpoint.parameters) {
|
|
28
|
+
if (param.name === 'organizationId')
|
|
29
|
+
continue;
|
|
30
|
+
if (param.in === 'header')
|
|
31
|
+
continue;
|
|
32
|
+
properties[param.name] = {
|
|
33
|
+
type: param.type,
|
|
34
|
+
description: param.description || `${param.name} parameter`,
|
|
35
|
+
};
|
|
36
|
+
if (param.required) {
|
|
37
|
+
required.push(param.name);
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
if (endpoint.requestBody) {
|
|
41
|
+
for (const [name, prop] of Object.entries(endpoint.requestBody.properties)) {
|
|
42
|
+
properties[name] = {
|
|
43
|
+
type: prop.type,
|
|
44
|
+
description: prop.description || name,
|
|
45
|
+
};
|
|
46
|
+
if (prop.enum) {
|
|
47
|
+
properties[name].enum = prop.enum;
|
|
48
|
+
}
|
|
49
|
+
if (prop.required) {
|
|
50
|
+
required.push(name);
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
tools.push({
|
|
55
|
+
name: override?.name || generateToolName(endpoint),
|
|
56
|
+
description: override?.description || endpoint.description || endpoint.summary,
|
|
57
|
+
method: endpoint.method,
|
|
58
|
+
path: endpoint.path,
|
|
59
|
+
inputSchema: {
|
|
60
|
+
type: 'object',
|
|
61
|
+
properties,
|
|
62
|
+
required,
|
|
63
|
+
},
|
|
64
|
+
});
|
|
65
|
+
}
|
|
66
|
+
return tools;
|
|
67
|
+
}
|
|
68
|
+
//# sourceMappingURL=tool-generator.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tool-generator.js","sourceRoot":"","sources":["../../src/generator/tool-generator.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
ADDED
package/dist/index.js
ADDED
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
|
|
3
|
+
import { loadConfig } from './config.js';
|
|
4
|
+
import { Rent2bApiClient } from './api-client.js';
|
|
5
|
+
import { createServer } from './server.js';
|
|
6
|
+
async function main() {
|
|
7
|
+
const args = process.argv.slice(2);
|
|
8
|
+
const useSSE = args.includes('--sse');
|
|
9
|
+
const port = parseInt(args.find((a) => a.startsWith('--port='))?.split('=')[1] || '8080', 10);
|
|
10
|
+
const config = loadConfig();
|
|
11
|
+
const apiClient = new Rent2bApiClient(config);
|
|
12
|
+
console.error('Resolving organization from API key...');
|
|
13
|
+
try {
|
|
14
|
+
const orgId = await apiClient.resolveOrganization();
|
|
15
|
+
console.error(`Organization resolved: ${orgId}`);
|
|
16
|
+
}
|
|
17
|
+
catch (err) {
|
|
18
|
+
const message = err instanceof Error
|
|
19
|
+
? err.message
|
|
20
|
+
: typeof err === 'object' && err !== null && 'message' in err
|
|
21
|
+
? String(err.message)
|
|
22
|
+
: String(err);
|
|
23
|
+
console.error(`Failed to resolve organization: ${message}`);
|
|
24
|
+
process.exit(1);
|
|
25
|
+
}
|
|
26
|
+
if (useSSE) {
|
|
27
|
+
const { SSEServerTransport } = await import('@modelcontextprotocol/sdk/server/sse.js');
|
|
28
|
+
const express = (await import('express')).default;
|
|
29
|
+
const app = express();
|
|
30
|
+
const transports = new Map();
|
|
31
|
+
app.get('/sse', async (req, res) => {
|
|
32
|
+
const server = createServer(apiClient);
|
|
33
|
+
const transport = new SSEServerTransport('/messages', res);
|
|
34
|
+
transports.set(transport.sessionId, transport);
|
|
35
|
+
res.on('close', () => {
|
|
36
|
+
transports.delete(transport.sessionId);
|
|
37
|
+
});
|
|
38
|
+
await server.connect(transport);
|
|
39
|
+
});
|
|
40
|
+
app.post('/messages', async (req, res) => {
|
|
41
|
+
const sessionId = req.query.sessionId;
|
|
42
|
+
const transport = transports.get(sessionId);
|
|
43
|
+
if (transport) {
|
|
44
|
+
await transport.handlePostMessage(req, res);
|
|
45
|
+
}
|
|
46
|
+
else {
|
|
47
|
+
res.status(400).json({ error: 'Unknown or expired session' });
|
|
48
|
+
}
|
|
49
|
+
});
|
|
50
|
+
app.listen(port, () => {
|
|
51
|
+
console.error(`rent2b MCP server (SSE) listening on port ${port}`);
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
else {
|
|
55
|
+
const server = createServer(apiClient);
|
|
56
|
+
const transport = new StdioServerTransport();
|
|
57
|
+
await server.connect(transport);
|
|
58
|
+
console.error('rent2b MCP server running on stdio');
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
main().catch((err) => {
|
|
62
|
+
console.error('Fatal error:', err);
|
|
63
|
+
process.exit(1);
|
|
64
|
+
});
|
|
65
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export interface ToolOverride {
|
|
2
|
+
name: string;
|
|
3
|
+
description?: string;
|
|
4
|
+
parameterHints?: Record<string, string>;
|
|
5
|
+
}
|
|
6
|
+
export interface OverridesMap {
|
|
7
|
+
[endpointKey: string]: ToolOverride;
|
|
8
|
+
}
|
|
9
|
+
export declare function loadOverrides(): OverridesMap;
|
|
10
|
+
export declare function getOverride(method: string, path: string): ToolOverride | undefined;
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { readFileSync } from 'fs';
|
|
2
|
+
import { fileURLToPath } from 'url';
|
|
3
|
+
import { dirname, join } from 'path';
|
|
4
|
+
let overridesCache = null;
|
|
5
|
+
export function loadOverrides() {
|
|
6
|
+
if (overridesCache)
|
|
7
|
+
return overridesCache;
|
|
8
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
9
|
+
const __dirname = dirname(__filename);
|
|
10
|
+
const raw = readFileSync(join(__dirname, 'tool-overrides.json'), 'utf-8');
|
|
11
|
+
const parsed = JSON.parse(raw);
|
|
12
|
+
overridesCache = parsed.overrides;
|
|
13
|
+
return overridesCache;
|
|
14
|
+
}
|
|
15
|
+
export function getOverride(method, path) {
|
|
16
|
+
const overrides = loadOverrides();
|
|
17
|
+
return overrides[`${method} ${path}`];
|
|
18
|
+
}
|
|
19
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/overrides/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,IAAI,CAAC;AAClC,OAAO,EAAE,aAAa,EAAE,MAAM,KAAK,CAAC;AACpC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAYrC,IAAI,cAAc,GAAwB,IAAI,CAAC;AAE/C,MAAM,UAAU,aAAa;IAC3B,IAAI,cAAc;QAAE,OAAO,cAAc,CAAC;IAE1C,MAAM,UAAU,GAAG,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IAClD,MAAM,SAAS,GAAG,OAAO,CAAC,UAAU,CAAC,CAAC;IACtC,MAAM,GAAG,GAAG,YAAY,CAAC,IAAI,CAAC,SAAS,EAAE,qBAAqB,CAAC,EAAE,OAAO,CAAC,CAAC;IAC1E,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IAC/B,cAAc,GAAG,MAAM,CAAC,SAAyB,CAAC;IAClD,OAAO,cAAc,CAAC;AACxB,CAAC;AAED,MAAM,UAAU,WAAW,CACzB,MAAc,EACd,IAAY;IAEZ,MAAM,SAAS,GAAG,aAAa,EAAE,CAAC;IAClC,OAAO,SAAS,CAAC,GAAG,MAAM,IAAI,IAAI,EAAE,CAAC,CAAC;AACxC,CAAC"}
|
|
@@ -0,0 +1,184 @@
|
|
|
1
|
+
{
|
|
2
|
+
"overrides": {
|
|
3
|
+
"GET /items/organization/current-org": {
|
|
4
|
+
"name": "rent2b_items_list",
|
|
5
|
+
"description": "List all rental items in the organization. Supports pagination with page and limit query params."
|
|
6
|
+
},
|
|
7
|
+
"POST /items": {
|
|
8
|
+
"name": "rent2b_items_create",
|
|
9
|
+
"description": "Create a new rental item in the organization."
|
|
10
|
+
},
|
|
11
|
+
"GET /items/{id}": {
|
|
12
|
+
"name": "rent2b_items_get",
|
|
13
|
+
"description": "Get details of a specific rental item by ID."
|
|
14
|
+
},
|
|
15
|
+
"PATCH /items/{id}": {
|
|
16
|
+
"name": "rent2b_items_update",
|
|
17
|
+
"description": "Update a rental item's properties."
|
|
18
|
+
},
|
|
19
|
+
"DELETE /items/{id}": {
|
|
20
|
+
"name": "rent2b_items_delete",
|
|
21
|
+
"description": "Delete a rental item."
|
|
22
|
+
},
|
|
23
|
+
"GET /rooms/organization/current-org": {
|
|
24
|
+
"name": "rent2b_rooms_list",
|
|
25
|
+
"description": "List all rooms in the organization. Supports pagination."
|
|
26
|
+
},
|
|
27
|
+
"POST /rooms": {
|
|
28
|
+
"name": "rent2b_rooms_create",
|
|
29
|
+
"description": "Create a new room."
|
|
30
|
+
},
|
|
31
|
+
"GET /rooms/{id}": {
|
|
32
|
+
"name": "rent2b_rooms_get",
|
|
33
|
+
"description": "Get details of a specific room by ID."
|
|
34
|
+
},
|
|
35
|
+
"PATCH /rooms/{id}": {
|
|
36
|
+
"name": "rent2b_rooms_update",
|
|
37
|
+
"description": "Update a room's properties."
|
|
38
|
+
},
|
|
39
|
+
"DELETE /rooms/{id}": {
|
|
40
|
+
"name": "rent2b_rooms_delete",
|
|
41
|
+
"description": "Delete a room."
|
|
42
|
+
},
|
|
43
|
+
"POST /bookings": {
|
|
44
|
+
"name": "rent2b_bookings_create",
|
|
45
|
+
"description": "Create a new booking for an item or room."
|
|
46
|
+
},
|
|
47
|
+
"GET /bookings": {
|
|
48
|
+
"name": "rent2b_bookings_my_list",
|
|
49
|
+
"description": "List bookings where the authenticated user is the renter."
|
|
50
|
+
},
|
|
51
|
+
"GET /bookings/organization": {
|
|
52
|
+
"name": "rent2b_bookings_list",
|
|
53
|
+
"description": "List all bookings for the organization (where user is lessor)."
|
|
54
|
+
},
|
|
55
|
+
"GET /bookings/{bookingId}/checklists": {
|
|
56
|
+
"name": "rent2b_checklists_list",
|
|
57
|
+
"description": "List all checklists for a specific booking."
|
|
58
|
+
},
|
|
59
|
+
"GET /bookings/{bookingId}/checklists/{id}": {
|
|
60
|
+
"name": "rent2b_checklists_get",
|
|
61
|
+
"description": "Get a specific checklist by ID for a booking."
|
|
62
|
+
},
|
|
63
|
+
"GET /bookings/{id}": {
|
|
64
|
+
"name": "rent2b_bookings_get",
|
|
65
|
+
"description": "Get details of a specific booking."
|
|
66
|
+
},
|
|
67
|
+
"PATCH /bookings/{id}": {
|
|
68
|
+
"name": "rent2b_bookings_update",
|
|
69
|
+
"description": "Update a booking."
|
|
70
|
+
},
|
|
71
|
+
"DELETE /bookings/{id}": {
|
|
72
|
+
"name": "rent2b_bookings_cancel",
|
|
73
|
+
"description": "Cancel a booking and process refund."
|
|
74
|
+
},
|
|
75
|
+
"POST /bookings/{id}/confirm": {
|
|
76
|
+
"name": "rent2b_bookings_confirm",
|
|
77
|
+
"description": "Confirm a pending booking."
|
|
78
|
+
},
|
|
79
|
+
"POST /bookings/{id}/reject": {
|
|
80
|
+
"name": "rent2b_bookings_reject",
|
|
81
|
+
"description": "Reject a pending booking."
|
|
82
|
+
},
|
|
83
|
+
"POST /bookings/check-availability": {
|
|
84
|
+
"name": "rent2b_availability_check",
|
|
85
|
+
"description": "Check availability and pricing for an item or room for a specific date range."
|
|
86
|
+
},
|
|
87
|
+
"GET /bookings/items/{itemId}/availability": {
|
|
88
|
+
"name": "rent2b_items_availability",
|
|
89
|
+
"description": "Get availability calendar for a specific item."
|
|
90
|
+
},
|
|
91
|
+
"GET /bookings/rooms/{roomId}/availability": {
|
|
92
|
+
"name": "rent2b_rooms_availability",
|
|
93
|
+
"description": "Get availability calendar for a specific room."
|
|
94
|
+
},
|
|
95
|
+
"GET /bookings/available": {
|
|
96
|
+
"name": "rent2b_available_resources",
|
|
97
|
+
"description": "Get all available rooms and items for the organization."
|
|
98
|
+
},
|
|
99
|
+
"GET /locations": {
|
|
100
|
+
"name": "rent2b_locations_list",
|
|
101
|
+
"description": "List all locations for the organization."
|
|
102
|
+
},
|
|
103
|
+
"POST /locations": {
|
|
104
|
+
"name": "rent2b_locations_create",
|
|
105
|
+
"description": "Create a new location."
|
|
106
|
+
},
|
|
107
|
+
"GET /locations/{id}": {
|
|
108
|
+
"name": "rent2b_locations_get",
|
|
109
|
+
"description": "Get details of a specific location."
|
|
110
|
+
},
|
|
111
|
+
"PATCH /locations/{id}": {
|
|
112
|
+
"name": "rent2b_locations_update",
|
|
113
|
+
"description": "Update a location."
|
|
114
|
+
},
|
|
115
|
+
"DELETE /locations/{id}": {
|
|
116
|
+
"name": "rent2b_locations_delete",
|
|
117
|
+
"description": "Delete a location."
|
|
118
|
+
},
|
|
119
|
+
"GET /time-slots/{locationId}": {
|
|
120
|
+
"name": "rent2b_timeslots_list",
|
|
121
|
+
"description": "List time slots for a specific location."
|
|
122
|
+
},
|
|
123
|
+
"POST /time-slots/{locationId}": {
|
|
124
|
+
"name": "rent2b_timeslots_create",
|
|
125
|
+
"description": "Create a time slot for a location."
|
|
126
|
+
},
|
|
127
|
+
"POST /time-slots/{locationId}/weekly": {
|
|
128
|
+
"name": "rent2b_timeslots_create_weekly",
|
|
129
|
+
"description": "Create a full weekly schedule of time slots for a location."
|
|
130
|
+
},
|
|
131
|
+
"PATCH /time-slots/{locationId}/{id}": {
|
|
132
|
+
"name": "rent2b_timeslots_update",
|
|
133
|
+
"description": "Update a time slot."
|
|
134
|
+
},
|
|
135
|
+
"DELETE /time-slots/{locationId}/{id}": {
|
|
136
|
+
"name": "rent2b_timeslots_delete",
|
|
137
|
+
"description": "Delete a time slot."
|
|
138
|
+
},
|
|
139
|
+
"GET /categories": {
|
|
140
|
+
"name": "rent2b_categories_list",
|
|
141
|
+
"description": "List all item categories."
|
|
142
|
+
},
|
|
143
|
+
"GET /categories/{categoryId}": {
|
|
144
|
+
"name": "rent2b_categories_get",
|
|
145
|
+
"description": "Get a specific category by ID."
|
|
146
|
+
},
|
|
147
|
+
"POST /organizations/{organizationId}/guests": {
|
|
148
|
+
"name": "rent2b_guests_create",
|
|
149
|
+
"description": "Create a new guest for the organization."
|
|
150
|
+
},
|
|
151
|
+
"GET /organizations/{organizationId}/guests": {
|
|
152
|
+
"name": "rent2b_guests_list",
|
|
153
|
+
"description": "List guests for the organization. Supports search and pagination."
|
|
154
|
+
},
|
|
155
|
+
"GET /organizations/{organizationId}/guests/{id}": {
|
|
156
|
+
"name": "rent2b_guests_get",
|
|
157
|
+
"description": "Get a specific guest by ID."
|
|
158
|
+
},
|
|
159
|
+
"PATCH /organizations/{organizationId}/guests/{id}": {
|
|
160
|
+
"name": "rent2b_guests_update",
|
|
161
|
+
"description": "Update a guest's information."
|
|
162
|
+
},
|
|
163
|
+
"DELETE /organizations/{organizationId}/guests/{id}": {
|
|
164
|
+
"name": "rent2b_guests_delete",
|
|
165
|
+
"description": "Delete a guest."
|
|
166
|
+
},
|
|
167
|
+
"GET /statistics/organization/{organizationId}": {
|
|
168
|
+
"name": "rent2b_statistics_overview",
|
|
169
|
+
"description": "Get comprehensive organization statistics including bookings, revenue, and utilization."
|
|
170
|
+
},
|
|
171
|
+
"GET /statistics/organization/{organizationId}/summary": {
|
|
172
|
+
"name": "rent2b_statistics_summary",
|
|
173
|
+
"description": "Get a quick summary of organization statistics."
|
|
174
|
+
},
|
|
175
|
+
"GET /statistics/organization/{organizationId}/revenue": {
|
|
176
|
+
"name": "rent2b_statistics_revenue",
|
|
177
|
+
"description": "Get detailed revenue statistics for the organization."
|
|
178
|
+
},
|
|
179
|
+
"GET /statistics/organization/{organizationId}/utilization": {
|
|
180
|
+
"name": "rent2b_statistics_utilization",
|
|
181
|
+
"description": "Get utilization statistics for the organization."
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
}
|