@xalantis/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/dist/index.mjs ADDED
@@ -0,0 +1,239 @@
1
+ // src/http.ts
2
+ var XalantisError = class extends Error {
3
+ constructor(message, code, status, details, retryAfter) {
4
+ super(message);
5
+ this.name = "XalantisError";
6
+ this.code = code;
7
+ this.status = status;
8
+ this.details = details;
9
+ this.retryAfter = retryAfter;
10
+ }
11
+ };
12
+ var DEFAULT_TIMEOUT_MS = 3e4;
13
+ var HttpClient = class {
14
+ constructor(config) {
15
+ this.apiKey = config.apiKey;
16
+ this.timeoutMs = config.timeout ?? DEFAULT_TIMEOUT_MS;
17
+ const raw = config.baseUrl || "https://xalantis.com";
18
+ const parsed = new URL(raw);
19
+ if (parsed.protocol !== "https:" && !config.baseUrl) {
20
+ throw new Error("Xalantis SDK: baseUrl must use HTTPS");
21
+ }
22
+ this.baseUrl = parsed.origin;
23
+ Object.defineProperty(this, "apiKey", { enumerable: false });
24
+ }
25
+ /** @internal Prevent accidental serialization of sensitive data. */
26
+ toJSON() {
27
+ return { baseUrl: this.baseUrl };
28
+ }
29
+ async request(method, path, body, params) {
30
+ const url = new URL(`${this.baseUrl}/api/v1${path}`);
31
+ if (params) {
32
+ for (const [key, value] of Object.entries(params)) {
33
+ if (value !== void 0 && value !== null) {
34
+ url.searchParams.set(key, String(value));
35
+ }
36
+ }
37
+ }
38
+ const headers = {
39
+ "Authorization": `Bearer ${this.apiKey}`,
40
+ "Accept": "application/json",
41
+ "Content-Type": "application/json"
42
+ };
43
+ const controller = new AbortController();
44
+ const timeoutId = setTimeout(() => controller.abort(), this.timeoutMs);
45
+ let response;
46
+ try {
47
+ response = await fetch(url.toString(), {
48
+ method,
49
+ headers,
50
+ body: body ? JSON.stringify(body) : void 0,
51
+ signal: controller.signal
52
+ });
53
+ } catch (err) {
54
+ clearTimeout(timeoutId);
55
+ if (err instanceof DOMException && err.name === "AbortError") {
56
+ throw new XalantisError(`Request timed out after ${this.timeoutMs}ms`, "TIMEOUT", 0);
57
+ }
58
+ throw new XalantisError(
59
+ err instanceof Error ? err.message : "Network request failed",
60
+ "NETWORK_ERROR",
61
+ 0
62
+ );
63
+ } finally {
64
+ clearTimeout(timeoutId);
65
+ }
66
+ let json;
67
+ try {
68
+ json = await response.json();
69
+ } catch {
70
+ throw new XalantisError(
71
+ `Server returned non-JSON response (HTTP ${response.status})`,
72
+ "INVALID_RESPONSE",
73
+ response.status
74
+ );
75
+ }
76
+ if (typeof json !== "object" || json === null || !("success" in json)) {
77
+ throw new XalantisError(
78
+ "Invalid API response format",
79
+ "INVALID_RESPONSE",
80
+ response.status
81
+ );
82
+ }
83
+ if (!response.ok || json.success === false) {
84
+ const error = json;
85
+ let retryAfter;
86
+ if (response.status === 429) {
87
+ const retryHeader = response.headers.get("Retry-After");
88
+ retryAfter = retryHeader ? parseInt(retryHeader, 10) : void 0;
89
+ }
90
+ throw new XalantisError(
91
+ error.error?.message || `Request failed with status ${response.status}`,
92
+ error.error?.code || "UNKNOWN_ERROR",
93
+ response.status,
94
+ error.error?.details,
95
+ retryAfter
96
+ );
97
+ }
98
+ return json;
99
+ }
100
+ /** Send a GET request and return a single resource. */
101
+ async get(path, params) {
102
+ return this.request("GET", path, void 0, params);
103
+ }
104
+ /** Send a GET request and return a paginated list. */
105
+ async getPaginated(path, params) {
106
+ return this.request("GET", path, void 0, params);
107
+ }
108
+ /** Send a POST request. */
109
+ async post(path, body) {
110
+ return this.request("POST", path, body);
111
+ }
112
+ /** Send a PATCH request. */
113
+ async patch(path, body) {
114
+ return this.request("PATCH", path, body);
115
+ }
116
+ /** Send a DELETE request. */
117
+ async delete(path) {
118
+ return this.request("DELETE", path);
119
+ }
120
+ };
121
+
122
+ // src/resources/tickets.ts
123
+ var UUID_RE = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
124
+ var VALID_PRIORITIES = ["low", "medium", "high", "urgent"];
125
+ var VALID_STATUSES = ["new", "open", "pending", "on_hold", "resolved", "closed"];
126
+ var VALID_CHANNELS = ["api", "email", "phone", "chat", "web", "widget"];
127
+ function assertUuid(value, label) {
128
+ if (!UUID_RE.test(value)) {
129
+ throw new Error(`Xalantis SDK: ${label} must be a valid UUID (got "${value}")`);
130
+ }
131
+ }
132
+ var TicketsResource = class {
133
+ constructor(http) {
134
+ this.http = http;
135
+ }
136
+ /**
137
+ * List tickets with optional filters and pagination.
138
+ *
139
+ * @example
140
+ * const tickets = await client.tickets.list({ status: 'open', per_page: 10 })
141
+ */
142
+ async list(params) {
143
+ return this.http.getPaginated("/tickets", params);
144
+ }
145
+ /**
146
+ * Get a single ticket by UUID.
147
+ *
148
+ * @example
149
+ * const ticket = await client.tickets.get('uuid-here')
150
+ */
151
+ async get(uuid) {
152
+ assertUuid(uuid, "ticket uuid");
153
+ return this.http.get(`/tickets/${uuid}`);
154
+ }
155
+ /**
156
+ * Create a new ticket.
157
+ *
158
+ * @example
159
+ * const ticket = await client.tickets.create({
160
+ * subject: 'Login issue',
161
+ * description: 'Cannot login since update',
162
+ * requester_email: 'user@example.com',
163
+ * priority: 'high',
164
+ * })
165
+ */
166
+ async create(input) {
167
+ if (!input.subject || input.subject.trim().length === 0) {
168
+ throw new Error("Xalantis SDK: subject is required");
169
+ }
170
+ if (!input.description || input.description.trim().length === 0) {
171
+ throw new Error("Xalantis SDK: description is required");
172
+ }
173
+ if (!input.requester_email || input.requester_email.trim().length === 0) {
174
+ throw new Error("Xalantis SDK: requester_email is required");
175
+ }
176
+ if (input.priority && !VALID_PRIORITIES.includes(input.priority)) {
177
+ throw new Error(`Xalantis SDK: invalid priority "${input.priority}" (must be ${VALID_PRIORITIES.join(", ")})`);
178
+ }
179
+ if (input.channel && !VALID_CHANNELS.includes(input.channel)) {
180
+ throw new Error(`Xalantis SDK: invalid channel "${input.channel}" (must be ${VALID_CHANNELS.join(", ")})`);
181
+ }
182
+ return this.http.post("/tickets", input);
183
+ }
184
+ /**
185
+ * Update an existing ticket.
186
+ *
187
+ * @example
188
+ * const ticket = await client.tickets.update('uuid-here', { status: 'resolved' })
189
+ */
190
+ async update(uuid, input) {
191
+ assertUuid(uuid, "ticket uuid");
192
+ if (input.priority && !VALID_PRIORITIES.includes(input.priority)) {
193
+ throw new Error(`Xalantis SDK: invalid priority "${input.priority}" (must be ${VALID_PRIORITIES.join(", ")})`);
194
+ }
195
+ if (input.status && !VALID_STATUSES.includes(input.status)) {
196
+ throw new Error(`Xalantis SDK: invalid status "${input.status}" (must be ${VALID_STATUSES.join(", ")})`);
197
+ }
198
+ return this.http.patch(`/tickets/${uuid}`, input);
199
+ }
200
+ /**
201
+ * List replies for a ticket.
202
+ *
203
+ * @example
204
+ * const replies = await client.tickets.listReplies('uuid-here')
205
+ */
206
+ async listReplies(ticketUuid, params) {
207
+ assertUuid(ticketUuid, "ticket uuid");
208
+ return this.http.getPaginated(`/tickets/${ticketUuid}/replies`, params);
209
+ }
210
+ /**
211
+ * Add a reply to a ticket.
212
+ *
213
+ * @example
214
+ * await client.tickets.reply('uuid-here', { content: 'Thanks for reporting!' })
215
+ */
216
+ async reply(ticketUuid, input) {
217
+ assertUuid(ticketUuid, "ticket uuid");
218
+ if (!input.content || input.content.trim().length === 0) {
219
+ throw new Error("Xalantis SDK: reply content is required");
220
+ }
221
+ return this.http.post(`/tickets/${ticketUuid}/replies`, input);
222
+ }
223
+ };
224
+
225
+ // src/client.ts
226
+ var Xalantis = class {
227
+ constructor(config) {
228
+ if (!config.apiKey) {
229
+ throw new Error("Xalantis SDK: apiKey is required");
230
+ }
231
+ this.http = new HttpClient(config);
232
+ this.tickets = new TicketsResource(this.http);
233
+ }
234
+ };
235
+ export {
236
+ Xalantis,
237
+ XalantisError
238
+ };
239
+ //# sourceMappingURL=index.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/http.ts","../src/resources/tickets.ts","../src/client.ts"],"sourcesContent":["import type { ApiError, ApiResponse, PaginatedResponse, XalantisConfig } from './types'\n\n/**\n * Error thrown when the Xalantis API returns a non-success response.\n *\n * @example\n * ```ts\n * try {\n * await client.tickets.create({ ... })\n * } catch (error) {\n * if (error instanceof XalantisError) {\n * console.error(error.code) // 'VALIDATION_ERROR'\n * console.error(error.status) // 422\n * console.error(error.details) // { subject: ['Required'] }\n * }\n * }\n * ```\n */\nexport class XalantisError extends Error {\n /** Machine-readable error code (e.g. `VALIDATION_ERROR`, `NOT_FOUND`, `UNAUTHORIZED`). */\n code: string\n /** HTTP status code. */\n status: number\n /** Field-level validation errors, keyed by field name. Only present for 422 responses. */\n details?: Record<string, string[]>\n /** Value of `Retry-After` header when rate-limited (429). */\n retryAfter?: number\n\n constructor(message: string, code: string, status: number, details?: Record<string, string[]>, retryAfter?: number) {\n super(message)\n this.name = 'XalantisError'\n this.code = code\n this.status = status\n this.details = details\n this.retryAfter = retryAfter\n }\n}\n\n/** Default request timeout in milliseconds (30 seconds). */\nconst DEFAULT_TIMEOUT_MS = 30_000\n\n/**\n * Low-level HTTP client for the Xalantis API.\n * Handles authentication, request building, and error mapping.\n * @internal Use the `Xalantis` class instead.\n */\nexport class HttpClient {\n private baseUrl: string\n private apiKey: string\n private timeoutMs: number\n\n constructor(config: XalantisConfig) {\n this.apiKey = config.apiKey\n this.timeoutMs = config.timeout ?? DEFAULT_TIMEOUT_MS\n\n // [SECURITY] Validate baseUrl\n const raw = config.baseUrl || 'https://xalantis.com'\n const parsed = new URL(raw)\n\n if (parsed.protocol !== 'https:' && !config.baseUrl) {\n throw new Error('Xalantis SDK: baseUrl must use HTTPS')\n }\n\n this.baseUrl = parsed.origin\n\n // [SECURITY] Prevent API key from appearing in JSON.stringify / console.log\n Object.defineProperty(this, 'apiKey', { enumerable: false })\n }\n\n /** @internal Prevent accidental serialization of sensitive data. */\n toJSON(): Record<string, unknown> {\n return { baseUrl: this.baseUrl }\n }\n\n private async request<T>(method: string, path: string, body?: unknown, params?: Record<string, unknown>): Promise<T> {\n const url = new URL(`${this.baseUrl}/api/v1${path}`)\n\n if (params) {\n for (const [key, value] of Object.entries(params)) {\n if (value !== undefined && value !== null) {\n url.searchParams.set(key, String(value))\n }\n }\n }\n\n const headers: Record<string, string> = {\n 'Authorization': `Bearer ${this.apiKey}`,\n 'Accept': 'application/json',\n 'Content-Type': 'application/json',\n }\n\n // [SECURITY] AbortController timeout to prevent slowloris / hanging connections\n const controller = new AbortController()\n const timeoutId = setTimeout(() => controller.abort(), this.timeoutMs)\n\n let response: Response\n try {\n response = await fetch(url.toString(), {\n method,\n headers,\n body: body ? JSON.stringify(body) : undefined,\n signal: controller.signal,\n })\n } catch (err: unknown) {\n clearTimeout(timeoutId)\n if (err instanceof DOMException && err.name === 'AbortError') {\n throw new XalantisError(`Request timed out after ${this.timeoutMs}ms`, 'TIMEOUT', 0)\n }\n throw new XalantisError(\n err instanceof Error ? err.message : 'Network request failed',\n 'NETWORK_ERROR',\n 0,\n )\n } finally {\n clearTimeout(timeoutId)\n }\n\n // [SECURITY] Handle non-JSON responses (502/503 HTML pages, etc.)\n let json: unknown\n try {\n json = await response.json()\n } catch {\n throw new XalantisError(\n `Server returned non-JSON response (HTTP ${response.status})`,\n 'INVALID_RESPONSE',\n response.status,\n )\n }\n\n // [SECURITY] Validate response structure\n if (typeof json !== 'object' || json === null || !('success' in json)) {\n throw new XalantisError(\n 'Invalid API response format',\n 'INVALID_RESPONSE',\n response.status,\n )\n }\n\n if (!response.ok || (json as Record<string, unknown>).success === false) {\n const error = json as ApiError\n\n // Handle 429 Rate Limiting with Retry-After header\n let retryAfter: number | undefined\n if (response.status === 429) {\n const retryHeader = response.headers.get('Retry-After')\n retryAfter = retryHeader ? parseInt(retryHeader, 10) : undefined\n }\n\n throw new XalantisError(\n error.error?.message || `Request failed with status ${response.status}`,\n error.error?.code || 'UNKNOWN_ERROR',\n response.status,\n error.error?.details,\n retryAfter,\n )\n }\n\n return json as T\n }\n\n /** Send a GET request and return a single resource. */\n async get<T>(path: string, params?: Record<string, unknown>): Promise<ApiResponse<T>> {\n return this.request('GET', path, undefined, params)\n }\n\n /** Send a GET request and return a paginated list. */\n async getPaginated<T>(path: string, params?: Record<string, unknown>): Promise<PaginatedResponse<T>> {\n return this.request('GET', path, undefined, params)\n }\n\n /** Send a POST request. */\n async post<T>(path: string, body: unknown): Promise<ApiResponse<T>> {\n return this.request('POST', path, body)\n }\n\n /** Send a PATCH request. */\n async patch<T>(path: string, body: unknown): Promise<ApiResponse<T>> {\n return this.request('PATCH', path, body)\n }\n\n /** Send a DELETE request. */\n async delete(path: string): Promise<ApiResponse<null>> {\n return this.request('DELETE', path)\n }\n}\n","import type { HttpClient } from '../http'\nimport type {\n ApiResponse,\n CreateTicketInput,\n CreateTicketReplyInput,\n ListTicketRepliesParams,\n ListTicketsParams,\n PaginatedResponse,\n Ticket,\n TicketReply,\n UpdateTicketInput,\n} from '../types'\n\nconst UUID_RE = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i\n\nconst VALID_PRIORITIES = ['low', 'medium', 'high', 'urgent']\nconst VALID_STATUSES = ['new', 'open', 'pending', 'on_hold', 'resolved', 'closed']\nconst VALID_CHANNELS = ['api', 'email', 'phone', 'chat', 'web', 'widget']\n\n/** Validate UUID format to prevent path traversal. */\nfunction assertUuid(value: string, label: string): void {\n if (!UUID_RE.test(value)) {\n throw new Error(`Xalantis SDK: ${label} must be a valid UUID (got \"${value}\")`)\n }\n}\n\nexport class TicketsResource {\n constructor(private http: HttpClient) {}\n\n /**\n * List tickets with optional filters and pagination.\n *\n * @example\n * const tickets = await client.tickets.list({ status: 'open', per_page: 10 })\n */\n async list(params?: ListTicketsParams): Promise<PaginatedResponse<Ticket>> {\n return this.http.getPaginated<Ticket>('/tickets', params as Record<string, unknown>)\n }\n\n /**\n * Get a single ticket by UUID.\n *\n * @example\n * const ticket = await client.tickets.get('uuid-here')\n */\n async get(uuid: string): Promise<ApiResponse<Ticket>> {\n assertUuid(uuid, 'ticket uuid')\n return this.http.get<Ticket>(`/tickets/${uuid}`)\n }\n\n /**\n * Create a new ticket.\n *\n * @example\n * const ticket = await client.tickets.create({\n * subject: 'Login issue',\n * description: 'Cannot login since update',\n * requester_email: 'user@example.com',\n * priority: 'high',\n * })\n */\n async create(input: CreateTicketInput): Promise<ApiResponse<Ticket>> {\n if (!input.subject || input.subject.trim().length === 0) {\n throw new Error('Xalantis SDK: subject is required')\n }\n if (!input.description || input.description.trim().length === 0) {\n throw new Error('Xalantis SDK: description is required')\n }\n if (!input.requester_email || input.requester_email.trim().length === 0) {\n throw new Error('Xalantis SDK: requester_email is required')\n }\n if (input.priority && !VALID_PRIORITIES.includes(input.priority)) {\n throw new Error(`Xalantis SDK: invalid priority \"${input.priority}\" (must be ${VALID_PRIORITIES.join(', ')})`)\n }\n if (input.channel && !VALID_CHANNELS.includes(input.channel)) {\n throw new Error(`Xalantis SDK: invalid channel \"${input.channel}\" (must be ${VALID_CHANNELS.join(', ')})`)\n }\n\n return this.http.post<Ticket>('/tickets', input)\n }\n\n /**\n * Update an existing ticket.\n *\n * @example\n * const ticket = await client.tickets.update('uuid-here', { status: 'resolved' })\n */\n async update(uuid: string, input: UpdateTicketInput): Promise<ApiResponse<Ticket>> {\n assertUuid(uuid, 'ticket uuid')\n\n if (input.priority && !VALID_PRIORITIES.includes(input.priority)) {\n throw new Error(`Xalantis SDK: invalid priority \"${input.priority}\" (must be ${VALID_PRIORITIES.join(', ')})`)\n }\n if (input.status && !VALID_STATUSES.includes(input.status)) {\n throw new Error(`Xalantis SDK: invalid status \"${input.status}\" (must be ${VALID_STATUSES.join(', ')})`)\n }\n\n return this.http.patch<Ticket>(`/tickets/${uuid}`, input)\n }\n\n /**\n * List replies for a ticket.\n *\n * @example\n * const replies = await client.tickets.listReplies('uuid-here')\n */\n async listReplies(ticketUuid: string, params?: ListTicketRepliesParams): Promise<PaginatedResponse<TicketReply>> {\n assertUuid(ticketUuid, 'ticket uuid')\n return this.http.getPaginated<TicketReply>(`/tickets/${ticketUuid}/replies`, params as Record<string, unknown>)\n }\n\n /**\n * Add a reply to a ticket.\n *\n * @example\n * await client.tickets.reply('uuid-here', { content: 'Thanks for reporting!' })\n */\n async reply(ticketUuid: string, input: CreateTicketReplyInput): Promise<ApiResponse<TicketReply>> {\n assertUuid(ticketUuid, 'ticket uuid')\n\n if (!input.content || input.content.trim().length === 0) {\n throw new Error('Xalantis SDK: reply content is required')\n }\n\n return this.http.post<TicketReply>(`/tickets/${ticketUuid}/replies`, input)\n }\n}\n","import { HttpClient } from './http'\nimport { TicketsResource } from './resources/tickets'\nimport type { XalantisConfig } from './types'\n\n/**\n * Xalantis SDK Client.\n *\n * @example\n * ```ts\n * import { Xalantis } from '@xalantis/sdk'\n *\n * const client = new Xalantis({ apiKey: 'xal_live_...' })\n *\n * // Create a ticket\n * const { data: ticket } = await client.tickets.create({\n * subject: 'Bug report',\n * description: 'Something is broken',\n * requester_email: 'user@example.com',\n * })\n *\n * // List tickets\n * const { data: tickets } = await client.tickets.list({ status: 'open' })\n *\n * // Get a ticket\n * const { data: ticket } = await client.tickets.get('uuid-here')\n *\n * // Update a ticket\n * await client.tickets.update('uuid-here', { status: 'resolved' })\n *\n * // Reply to a ticket\n * await client.tickets.reply('uuid-here', { content: 'Fixed!' })\n * ```\n */\nexport class Xalantis {\n private http: HttpClient\n\n /** Ticket management (create, list, get, update, reply). */\n public tickets: TicketsResource\n\n constructor(config: XalantisConfig) {\n if (!config.apiKey) {\n throw new Error('Xalantis SDK: apiKey is required')\n }\n\n this.http = new HttpClient(config)\n this.tickets = new TicketsResource(this.http)\n }\n}\n"],"mappings":"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","names":[]}
package/package.json ADDED
@@ -0,0 +1,35 @@
1
+ {
2
+ "name": "@xalantis/sdk",
3
+ "version": "0.1.0",
4
+ "description": "Official Xalantis JavaScript/TypeScript SDK",
5
+ "main": "dist/index.js",
6
+ "module": "dist/index.mjs",
7
+ "types": "dist/index.d.ts",
8
+ "exports": {
9
+ ".": {
10
+ "types": "./dist/index.d.ts",
11
+ "import": "./dist/index.mjs",
12
+ "require": "./dist/index.js"
13
+ }
14
+ },
15
+ "files": ["dist"],
16
+ "scripts": {
17
+ "build": "tsup",
18
+ "dev": "tsup --watch",
19
+ "lint": "tsc --noEmit",
20
+ "test": "vitest run --exclude tests/integration.test.ts",
21
+ "test:integration": "vitest run tests/integration.test.ts",
22
+ "test:watch": "vitest --exclude tests/integration.test.ts"
23
+ },
24
+ "keywords": ["xalantis", "sdk", "api", "crm", "tickets", "support"],
25
+ "author": "WAZMINE <dev@xalantis.com>",
26
+ "license": "MIT",
27
+ "devDependencies": {
28
+ "tsup": "^8.0.0",
29
+ "typescript": "^5.7.0",
30
+ "vitest": "^3.0.0"
31
+ },
32
+ "engines": {
33
+ "node": ">=18.0.0"
34
+ }
35
+ }