@meridesk/node-sdk 0.1.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/CHANGELOG.md +15 -0
- package/LICENSE +21 -0
- package/README.md +131 -0
- package/dist/index.cjs +265 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +303 -0
- package/dist/index.d.ts +303 -0
- package/dist/index.js +233 -0
- package/dist/index.js.map +1 -0
- package/package.json +61 -0
package/dist/index.js
ADDED
|
@@ -0,0 +1,233 @@
|
|
|
1
|
+
// src/errors.ts
|
|
2
|
+
var MerideskError = class _MerideskError extends Error {
|
|
3
|
+
constructor(message) {
|
|
4
|
+
super(message);
|
|
5
|
+
this.name = "MerideskError";
|
|
6
|
+
Object.setPrototypeOf(this, _MerideskError.prototype);
|
|
7
|
+
}
|
|
8
|
+
};
|
|
9
|
+
var MerideskConfigError = class _MerideskConfigError extends MerideskError {
|
|
10
|
+
constructor(message) {
|
|
11
|
+
super(message);
|
|
12
|
+
this.name = "MerideskConfigError";
|
|
13
|
+
Object.setPrototypeOf(this, _MerideskConfigError.prototype);
|
|
14
|
+
}
|
|
15
|
+
};
|
|
16
|
+
var MerideskAPIError = class _MerideskAPIError extends MerideskError {
|
|
17
|
+
constructor(message, status, body) {
|
|
18
|
+
super(message);
|
|
19
|
+
this.name = "MerideskAPIError";
|
|
20
|
+
this.status = status;
|
|
21
|
+
this.body = body;
|
|
22
|
+
Object.setPrototypeOf(this, _MerideskAPIError.prototype);
|
|
23
|
+
}
|
|
24
|
+
};
|
|
25
|
+
var MerideskConnectionError = class _MerideskConnectionError extends MerideskError {
|
|
26
|
+
constructor(message, cause) {
|
|
27
|
+
super(message);
|
|
28
|
+
this.name = "MerideskConnectionError";
|
|
29
|
+
this.cause = cause;
|
|
30
|
+
Object.setPrototypeOf(this, _MerideskConnectionError.prototype);
|
|
31
|
+
}
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
// src/http.ts
|
|
35
|
+
var DEFAULT_TIMEOUT_MS = 15e3;
|
|
36
|
+
var HttpClient = class {
|
|
37
|
+
constructor(options) {
|
|
38
|
+
this.apiKey = options.apiKey;
|
|
39
|
+
this.baseUrl = options.baseUrl.endsWith("/") ? options.baseUrl : `${options.baseUrl}/`;
|
|
40
|
+
this.timeoutMs = options.timeoutMs ?? DEFAULT_TIMEOUT_MS;
|
|
41
|
+
}
|
|
42
|
+
buildUrl(path, query) {
|
|
43
|
+
const url = new URL(path.replace(/^\//, ""), this.baseUrl);
|
|
44
|
+
if (query) {
|
|
45
|
+
for (const [key, value] of Object.entries(query)) {
|
|
46
|
+
if (value !== void 0 && value !== null) {
|
|
47
|
+
url.searchParams.set(key, String(value));
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
return url.toString();
|
|
52
|
+
}
|
|
53
|
+
async request(method, path, options = {}) {
|
|
54
|
+
const url = this.buildUrl(path, options.query);
|
|
55
|
+
const controller = new AbortController();
|
|
56
|
+
const timeout = setTimeout(() => controller.abort(), this.timeoutMs);
|
|
57
|
+
let response;
|
|
58
|
+
try {
|
|
59
|
+
response = await fetch(url, {
|
|
60
|
+
method,
|
|
61
|
+
headers: {
|
|
62
|
+
"Content-Type": "application/json",
|
|
63
|
+
Accept: "application/json",
|
|
64
|
+
"X-API-Key": this.apiKey,
|
|
65
|
+
"User-Agent": "meridesk-node-sdk"
|
|
66
|
+
},
|
|
67
|
+
body: options.body !== void 0 ? JSON.stringify(options.body) : void 0,
|
|
68
|
+
signal: controller.signal
|
|
69
|
+
});
|
|
70
|
+
} catch (err) {
|
|
71
|
+
if (err instanceof Error && err.name === "AbortError") {
|
|
72
|
+
throw new MerideskConnectionError(`Meridesk API request to ${path} timed out after ${this.timeoutMs}ms`, err);
|
|
73
|
+
}
|
|
74
|
+
throw new MerideskConnectionError(`Failed to reach the Meridesk API: ${err?.message ?? err}`, err);
|
|
75
|
+
} finally {
|
|
76
|
+
clearTimeout(timeout);
|
|
77
|
+
}
|
|
78
|
+
let json;
|
|
79
|
+
try {
|
|
80
|
+
json = await response.json();
|
|
81
|
+
} catch {
|
|
82
|
+
json = void 0;
|
|
83
|
+
}
|
|
84
|
+
if (!response.ok) {
|
|
85
|
+
const message = json?.message || `Meridesk API request failed with status ${response.status}`;
|
|
86
|
+
throw new MerideskAPIError(message, response.status, json);
|
|
87
|
+
}
|
|
88
|
+
return json && Object.prototype.hasOwnProperty.call(json, "data") ? json.data : json;
|
|
89
|
+
}
|
|
90
|
+
get(path, query) {
|
|
91
|
+
return this.request("GET", path, { query });
|
|
92
|
+
}
|
|
93
|
+
post(path, body) {
|
|
94
|
+
return this.request("POST", path, { body });
|
|
95
|
+
}
|
|
96
|
+
patch(path, body) {
|
|
97
|
+
return this.request("PATCH", path, { body });
|
|
98
|
+
}
|
|
99
|
+
};
|
|
100
|
+
|
|
101
|
+
// src/resources/articles.ts
|
|
102
|
+
var ArticlesResource = class {
|
|
103
|
+
constructor(http) {
|
|
104
|
+
this.http = http;
|
|
105
|
+
}
|
|
106
|
+
/** Lists all knowledge base categories (with their nested articles/topics) for this website. */
|
|
107
|
+
async listCategories() {
|
|
108
|
+
const { categories } = await this.http.get("/articles/categories");
|
|
109
|
+
return categories;
|
|
110
|
+
}
|
|
111
|
+
/** Full-text searches article titles/topics for this website. */
|
|
112
|
+
async search(query) {
|
|
113
|
+
const { results } = await this.http.get("/articles/search", { q: query });
|
|
114
|
+
return results;
|
|
115
|
+
}
|
|
116
|
+
};
|
|
117
|
+
|
|
118
|
+
// src/resources/customers.ts
|
|
119
|
+
var CustomersResource = class {
|
|
120
|
+
constructor(http) {
|
|
121
|
+
this.http = http;
|
|
122
|
+
}
|
|
123
|
+
/**
|
|
124
|
+
* Creates a customer if one doesn't exist for this email yet, or updates
|
|
125
|
+
* the provided fields on the existing one.
|
|
126
|
+
*/
|
|
127
|
+
async upsert(input) {
|
|
128
|
+
const { customer } = await this.http.post("/customers", input);
|
|
129
|
+
return customer;
|
|
130
|
+
}
|
|
131
|
+
/** Fetches a customer by email. */
|
|
132
|
+
async get(email) {
|
|
133
|
+
const { customer } = await this.http.get(`/customers/${encodeURIComponent(email)}`);
|
|
134
|
+
return customer;
|
|
135
|
+
}
|
|
136
|
+
/** Updates one or more fields on an existing customer. */
|
|
137
|
+
async update(email, input) {
|
|
138
|
+
const { customer } = await this.http.patch(`/customers/${encodeURIComponent(email)}`, input);
|
|
139
|
+
return customer;
|
|
140
|
+
}
|
|
141
|
+
};
|
|
142
|
+
|
|
143
|
+
// src/resources/identity.ts
|
|
144
|
+
import { createHmac } from "crypto";
|
|
145
|
+
var IdentityResource = class {
|
|
146
|
+
constructor(identitySecret) {
|
|
147
|
+
this.identitySecret = identitySecret;
|
|
148
|
+
}
|
|
149
|
+
/**
|
|
150
|
+
* Computes the identity hash for a given user identifier (typically the
|
|
151
|
+
* customer's email address).
|
|
152
|
+
*
|
|
153
|
+
* @throws {MerideskConfigError} if no `identitySecret` was provided when
|
|
154
|
+
* constructing the `Meridesk` client, or if `userId` is empty.
|
|
155
|
+
*/
|
|
156
|
+
generateUserHash(userId) {
|
|
157
|
+
if (!this.identitySecret) {
|
|
158
|
+
throw new MerideskConfigError(
|
|
159
|
+
"Set `identitySecret` when constructing the Meridesk client to use identity.generateUserHash(). Find it in your Meridesk dashboard under Settings > API Keys (shown once when a key is created or regenerated)."
|
|
160
|
+
);
|
|
161
|
+
}
|
|
162
|
+
if (!userId) {
|
|
163
|
+
throw new MerideskConfigError("userId is required to generate an identity hash");
|
|
164
|
+
}
|
|
165
|
+
return createHmac("sha256", this.identitySecret).update(String(userId)).digest("hex");
|
|
166
|
+
}
|
|
167
|
+
};
|
|
168
|
+
|
|
169
|
+
// src/resources/tickets.ts
|
|
170
|
+
var TicketsResource = class {
|
|
171
|
+
constructor(http) {
|
|
172
|
+
this.http = http;
|
|
173
|
+
}
|
|
174
|
+
/**
|
|
175
|
+
* Creates a support ticket on behalf of a customer, identified by email.
|
|
176
|
+
* The customer is created automatically if they don't already exist.
|
|
177
|
+
*/
|
|
178
|
+
async create(input) {
|
|
179
|
+
const { ticket } = await this.http.post("/tickets", input);
|
|
180
|
+
return ticket;
|
|
181
|
+
}
|
|
182
|
+
/** Lists tickets for this website, optionally filtered by customer email and/or status. */
|
|
183
|
+
async list(params = {}) {
|
|
184
|
+
const { tickets } = await this.http.get("/tickets", {
|
|
185
|
+
email: params.email,
|
|
186
|
+
status: params.status
|
|
187
|
+
});
|
|
188
|
+
return tickets;
|
|
189
|
+
}
|
|
190
|
+
/** Fetches a single ticket by id. */
|
|
191
|
+
async get(ticketId) {
|
|
192
|
+
const { ticket } = await this.http.get(`/tickets/${encodeURIComponent(ticketId)}`);
|
|
193
|
+
return ticket;
|
|
194
|
+
}
|
|
195
|
+
/** Adds a reply to a ticket (defaults to a 'support' reply from your backend). */
|
|
196
|
+
async reply(ticketId, input) {
|
|
197
|
+
const { ticket } = await this.http.post(`/tickets/${encodeURIComponent(ticketId)}/replies`, input);
|
|
198
|
+
return ticket;
|
|
199
|
+
}
|
|
200
|
+
};
|
|
201
|
+
|
|
202
|
+
// src/client.ts
|
|
203
|
+
var DEFAULT_BASE_URL = "https://api.north-america.meridesk.live/sdk/v1";
|
|
204
|
+
var Meridesk = class {
|
|
205
|
+
constructor(config) {
|
|
206
|
+
if (!config || !config.apiKey) {
|
|
207
|
+
throw new MerideskConfigError("An `apiKey` is required to initialize the Meridesk client. Find yours in your Meridesk dashboard under Settings > API Keys.");
|
|
208
|
+
}
|
|
209
|
+
this.http = new HttpClient({
|
|
210
|
+
apiKey: config.apiKey,
|
|
211
|
+
baseUrl: config.baseUrl ?? DEFAULT_BASE_URL,
|
|
212
|
+
timeoutMs: config.timeoutMs
|
|
213
|
+
});
|
|
214
|
+
this.identity = new IdentityResource(config.identitySecret);
|
|
215
|
+
this.customers = new CustomersResource(this.http);
|
|
216
|
+
this.tickets = new TicketsResource(this.http);
|
|
217
|
+
this.articles = new ArticlesResource(this.http);
|
|
218
|
+
}
|
|
219
|
+
/** Verifies the configured API key is valid and returns basic website/account info. */
|
|
220
|
+
me() {
|
|
221
|
+
return this.http.get("/me");
|
|
222
|
+
}
|
|
223
|
+
};
|
|
224
|
+
export {
|
|
225
|
+
DEFAULT_BASE_URL,
|
|
226
|
+
Meridesk,
|
|
227
|
+
MerideskAPIError,
|
|
228
|
+
MerideskConfigError,
|
|
229
|
+
MerideskConnectionError,
|
|
230
|
+
MerideskError,
|
|
231
|
+
Meridesk as default
|
|
232
|
+
};
|
|
233
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/errors.ts","../src/http.ts","../src/resources/articles.ts","../src/resources/customers.ts","../src/resources/identity.ts","../src/resources/tickets.ts","../src/client.ts"],"sourcesContent":["/**\n * Base class for all errors thrown by the Meridesk SDK.\n */\nexport class MerideskError extends Error {\n constructor(message: string) {\n super(message);\n this.name = 'MerideskError';\n Object.setPrototypeOf(this, MerideskError.prototype);\n }\n}\n\n/**\n * Thrown when the Meridesk client is misconfigured (missing/invalid\n * credentials, missing required arguments, etc.) — always a local,\n * pre-request error.\n */\nexport class MerideskConfigError extends MerideskError {\n constructor(message: string) {\n super(message);\n this.name = 'MerideskConfigError';\n Object.setPrototypeOf(this, MerideskConfigError.prototype);\n }\n}\n\n/**\n * Thrown when the Meridesk API responds with a non-2xx status code.\n */\nexport class MerideskAPIError extends MerideskError {\n /** HTTP status code returned by the API. */\n readonly status: number;\n /** Parsed JSON response body, if any. */\n readonly body: unknown;\n\n constructor(message: string, status: number, body?: unknown) {\n super(message);\n this.name = 'MerideskAPIError';\n this.status = status;\n this.body = body;\n Object.setPrototypeOf(this, MerideskAPIError.prototype);\n }\n}\n\n/**\n * Thrown when a request to the Meridesk API fails for network reasons\n * (timeout, DNS failure, connection reset, etc.) rather than an API error\n * response.\n */\nexport class MerideskConnectionError extends MerideskError {\n readonly cause?: unknown;\n\n constructor(message: string, cause?: unknown) {\n super(message);\n this.name = 'MerideskConnectionError';\n this.cause = cause;\n Object.setPrototypeOf(this, MerideskConnectionError.prototype);\n }\n}\n","import { MerideskAPIError, MerideskConnectionError } from './errors';\n\nexport interface HttpClientOptions {\n apiKey: string;\n baseUrl: string;\n timeoutMs?: number;\n}\n\ninterface RequestOptions {\n query?: Record<string, string | number | boolean | undefined | null>;\n body?: unknown;\n}\n\ninterface ApiEnvelope<T> {\n success: boolean;\n message?: string;\n data?: T;\n errors?: unknown;\n}\n\nconst DEFAULT_TIMEOUT_MS = 15_000;\n\n/**\n * Thin wrapper around the global `fetch` for talking to the Meridesk SDK API.\n * Handles auth headers, JSON encoding/decoding, timeouts, and translating\n * non-2xx responses into `MerideskAPIError`.\n */\nexport class HttpClient {\n private readonly apiKey: string;\n private readonly baseUrl: string;\n private readonly timeoutMs: number;\n\n constructor(options: HttpClientOptions) {\n this.apiKey = options.apiKey;\n this.baseUrl = options.baseUrl.endsWith('/') ? options.baseUrl : `${options.baseUrl}/`;\n this.timeoutMs = options.timeoutMs ?? DEFAULT_TIMEOUT_MS;\n }\n\n private buildUrl(path: string, query?: RequestOptions['query']): string {\n const url = new URL(path.replace(/^\\//, ''), this.baseUrl);\n if (query) {\n for (const [key, value] of Object.entries(query)) {\n if (value !== undefined && value !== null) {\n url.searchParams.set(key, String(value));\n }\n }\n }\n return url.toString();\n }\n\n private async request<T>(method: string, path: string, options: RequestOptions = {}): Promise<T> {\n const url = this.buildUrl(path, options.query);\n const controller = new AbortController();\n const timeout = setTimeout(() => controller.abort(), this.timeoutMs);\n\n let response: Response;\n try {\n response = await fetch(url, {\n method,\n headers: {\n 'Content-Type': 'application/json',\n Accept: 'application/json',\n 'X-API-Key': this.apiKey,\n 'User-Agent': 'meridesk-node-sdk'\n },\n body: options.body !== undefined ? JSON.stringify(options.body) : undefined,\n signal: controller.signal\n });\n } catch (err: unknown) {\n if (err instanceof Error && err.name === 'AbortError') {\n throw new MerideskConnectionError(`Meridesk API request to ${path} timed out after ${this.timeoutMs}ms`, err);\n }\n throw new MerideskConnectionError(`Failed to reach the Meridesk API: ${(err as Error)?.message ?? err}`, err);\n } finally {\n clearTimeout(timeout);\n }\n\n let json: ApiEnvelope<T> | undefined;\n try {\n json = (await response.json()) as ApiEnvelope<T>;\n } catch {\n json = undefined;\n }\n\n if (!response.ok) {\n const message = json?.message || `Meridesk API request failed with status ${response.status}`;\n throw new MerideskAPIError(message, response.status, json);\n }\n\n return (json && Object.prototype.hasOwnProperty.call(json, 'data') ? (json.data as T) : (json as unknown as T));\n }\n\n get<T>(path: string, query?: RequestOptions['query']): Promise<T> {\n return this.request<T>('GET', path, { query });\n }\n\n post<T>(path: string, body?: unknown): Promise<T> {\n return this.request<T>('POST', path, { body });\n }\n\n patch<T>(path: string, body?: unknown): Promise<T> {\n return this.request<T>('PATCH', path, { body });\n }\n}\n","import type { HttpClient } from '../http';\nimport type { ArticleCategory, ArticleSearchResult } from '../types';\n\ninterface CategoryListEnvelope {\n categories: ArticleCategory[];\n}\n\ninterface SearchEnvelope {\n results: ArticleSearchResult[];\n}\n\nexport class ArticlesResource {\n constructor(private readonly http: HttpClient) {}\n\n /** Lists all knowledge base categories (with their nested articles/topics) for this website. */\n async listCategories(): Promise<ArticleCategory[]> {\n const { categories } = await this.http.get<CategoryListEnvelope>('/articles/categories');\n return categories;\n }\n\n /** Full-text searches article titles/topics for this website. */\n async search(query: string): Promise<ArticleSearchResult[]> {\n const { results } = await this.http.get<SearchEnvelope>('/articles/search', { q: query });\n return results;\n }\n}\n","import type { HttpClient } from '../http';\nimport type { Customer, UpdateCustomerInput, UpsertCustomerInput } from '../types';\n\ninterface CustomerEnvelope {\n customer: Customer;\n}\n\nexport class CustomersResource {\n constructor(private readonly http: HttpClient) {}\n\n /**\n * Creates a customer if one doesn't exist for this email yet, or updates\n * the provided fields on the existing one.\n */\n async upsert(input: UpsertCustomerInput): Promise<Customer> {\n const { customer } = await this.http.post<CustomerEnvelope>('/customers', input);\n return customer;\n }\n\n /** Fetches a customer by email. */\n async get(email: string): Promise<Customer> {\n const { customer } = await this.http.get<CustomerEnvelope>(`/customers/${encodeURIComponent(email)}`);\n return customer;\n }\n\n /** Updates one or more fields on an existing customer. */\n async update(email: string, input: UpdateCustomerInput): Promise<Customer> {\n const { customer } = await this.http.patch<CustomerEnvelope>(`/customers/${encodeURIComponent(email)}`, input);\n return customer;\n }\n}\n","import { createHmac } from 'node:crypto';\nimport { MerideskConfigError } from '../errors';\n\n/**\n * Generates HMAC-SHA256 identity verification hashes for the Meridesk\n * widget's \"secure mode\", entirely locally — no network call is made.\n *\n * This mirrors the identity verification pattern used by Intercom/Zendesk:\n * your backend signs a stable identifier for the logged-in user (their\n * email or internal user id) with the `identitySecret` from your Meridesk\n * API key, and passes the resulting hash to the widget alongside that\n * identifier. Meridesk recomputes the hash server-side to confirm the\n * request really came from your backend.\n */\nexport class IdentityResource {\n constructor(private readonly identitySecret?: string) {}\n\n /**\n * Computes the identity hash for a given user identifier (typically the\n * customer's email address).\n *\n * @throws {MerideskConfigError} if no `identitySecret` was provided when\n * constructing the `Meridesk` client, or if `userId` is empty.\n */\n generateUserHash(userId: string): string {\n if (!this.identitySecret) {\n throw new MerideskConfigError(\n 'Set `identitySecret` when constructing the Meridesk client to use identity.generateUserHash(). ' +\n 'Find it in your Meridesk dashboard under Settings > API Keys (shown once when a key is created or regenerated).'\n );\n }\n\n if (!userId) {\n throw new MerideskConfigError('userId is required to generate an identity hash');\n }\n\n return createHmac('sha256', this.identitySecret).update(String(userId)).digest('hex');\n }\n}\n","import type { HttpClient } from '../http';\nimport type { CreateTicketInput, ListTicketsParams, ReplyToTicketInput, Ticket } from '../types';\n\ninterface TicketEnvelope {\n ticket: Ticket;\n}\n\ninterface TicketListEnvelope {\n tickets: Ticket[];\n}\n\nexport class TicketsResource {\n constructor(private readonly http: HttpClient) {}\n\n /**\n * Creates a support ticket on behalf of a customer, identified by email.\n * The customer is created automatically if they don't already exist.\n */\n async create(input: CreateTicketInput): Promise<Ticket> {\n const { ticket } = await this.http.post<TicketEnvelope>('/tickets', input);\n return ticket;\n }\n\n /** Lists tickets for this website, optionally filtered by customer email and/or status. */\n async list(params: ListTicketsParams = {}): Promise<Ticket[]> {\n const { tickets } = await this.http.get<TicketListEnvelope>('/tickets', {\n email: params.email,\n status: params.status\n });\n return tickets;\n }\n\n /** Fetches a single ticket by id. */\n async get(ticketId: string): Promise<Ticket> {\n const { ticket } = await this.http.get<TicketEnvelope>(`/tickets/${encodeURIComponent(ticketId)}`);\n return ticket;\n }\n\n /** Adds a reply to a ticket (defaults to a 'support' reply from your backend). */\n async reply(ticketId: string, input: ReplyToTicketInput): Promise<Ticket> {\n const { ticket } = await this.http.post<TicketEnvelope>(`/tickets/${encodeURIComponent(ticketId)}/replies`, input);\n return ticket;\n }\n}\n","import { MerideskConfigError } from './errors';\nimport { HttpClient } from './http';\nimport { ArticlesResource } from './resources/articles';\nimport { CustomersResource } from './resources/customers';\nimport { IdentityResource } from './resources/identity';\nimport { TicketsResource } from './resources/tickets';\nimport type { MeResponse, MerideskConfig } from './types';\n\nexport const DEFAULT_BASE_URL = 'https://api.north-america.meridesk.live/sdk/v1';\n\n/**\n * Official Meridesk Node.js SDK client for backend integrations.\n *\n * @example\n * ```ts\n * import { Meridesk } from '@meridesk/node-sdk';\n *\n * const meridesk = new Meridesk({\n * apiKey: process.env.MERIDESK_API_KEY!,\n * identitySecret: process.env.MERIDESK_IDENTITY_SECRET, // optional, for secure widget mode\n * });\n *\n * const ticket = await meridesk.tickets.create({\n * email: 'jane@example.com',\n * name: 'Jane Doe',\n * title: 'Refund request',\n * message: 'I would like a refund for order #1234.',\n * });\n * ```\n */\nexport class Meridesk {\n /** Generate secure widget identity verification hashes, computed locally. */\n readonly identity: IdentityResource;\n /** Create, fetch, and update customers. */\n readonly customers: CustomersResource;\n /** Create, list, fetch, and reply to support tickets. */\n readonly tickets: TicketsResource;\n /** List and search knowledge base articles. */\n readonly articles: ArticlesResource;\n\n private readonly http: HttpClient;\n\n constructor(config: MerideskConfig) {\n if (!config || !config.apiKey) {\n throw new MerideskConfigError('An `apiKey` is required to initialize the Meridesk client. Find yours in your Meridesk dashboard under Settings > API Keys.');\n }\n\n this.http = new HttpClient({\n apiKey: config.apiKey,\n baseUrl: config.baseUrl ?? DEFAULT_BASE_URL,\n timeoutMs: config.timeoutMs\n });\n\n this.identity = new IdentityResource(config.identitySecret);\n this.customers = new CustomersResource(this.http);\n this.tickets = new TicketsResource(this.http);\n this.articles = new ArticlesResource(this.http);\n }\n\n /** Verifies the configured API key is valid and returns basic website/account info. */\n me(): Promise<MeResponse> {\n return this.http.get<MeResponse>('/me');\n }\n}\n"],"mappings":"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","names":[]}
|
package/package.json
ADDED
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@meridesk/node-sdk",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Official Node.js SDK for Meridesk — integrate customer support (tickets, customers, knowledge base articles, secure widget identity verification) into your backend using an API key.",
|
|
5
|
+
"license": "MIT",
|
|
6
|
+
"author": "Meridesk <support@meridesk.live>",
|
|
7
|
+
"homepage": "https://docs.meridesk.live/docs/nodejs/getting-started/introduction",
|
|
8
|
+
"repository": {
|
|
9
|
+
"type": "git",
|
|
10
|
+
"url": "https://github.com/meridesk/meridesk-node-sdk"
|
|
11
|
+
},
|
|
12
|
+
"bugs": {
|
|
13
|
+
"url": "https://github.com/meridesk/meridesk-node-sdk/issues"
|
|
14
|
+
},
|
|
15
|
+
"keywords": [
|
|
16
|
+
"meridesk",
|
|
17
|
+
"sdk",
|
|
18
|
+
"customer-support",
|
|
19
|
+
"helpdesk",
|
|
20
|
+
"tickets",
|
|
21
|
+
"knowledge-base",
|
|
22
|
+
"identity-verification"
|
|
23
|
+
],
|
|
24
|
+
"type": "module",
|
|
25
|
+
"main": "./dist/index.cjs",
|
|
26
|
+
"module": "./dist/index.js",
|
|
27
|
+
"types": "./dist/index.d.ts",
|
|
28
|
+
"exports": {
|
|
29
|
+
".": {
|
|
30
|
+
"types": "./dist/index.d.ts",
|
|
31
|
+
"import": "./dist/index.js",
|
|
32
|
+
"require": "./dist/index.cjs"
|
|
33
|
+
},
|
|
34
|
+
"./package.json": "./package.json"
|
|
35
|
+
},
|
|
36
|
+
"sideEffects": false,
|
|
37
|
+
"files": [
|
|
38
|
+
"dist",
|
|
39
|
+
"README.md",
|
|
40
|
+
"LICENSE",
|
|
41
|
+
"CHANGELOG.md"
|
|
42
|
+
],
|
|
43
|
+
"engines": {
|
|
44
|
+
"node": ">=18"
|
|
45
|
+
},
|
|
46
|
+
"scripts": {
|
|
47
|
+
"build": "tsup",
|
|
48
|
+
"dev": "tsup --watch",
|
|
49
|
+
"test": "vitest run",
|
|
50
|
+
"test:watch": "vitest",
|
|
51
|
+
"typecheck": "tsc --noEmit",
|
|
52
|
+
"lint": "tsc --noEmit",
|
|
53
|
+
"prepublishOnly": "npm run build"
|
|
54
|
+
},
|
|
55
|
+
"devDependencies": {
|
|
56
|
+
"@types/node": "^20.14.0",
|
|
57
|
+
"tsup": "^8.2.4",
|
|
58
|
+
"typescript": "^5.5.4",
|
|
59
|
+
"vitest": "^2.0.5"
|
|
60
|
+
}
|
|
61
|
+
}
|