@foxscheduling/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.
Files changed (74) hide show
  1. package/README.md +58 -0
  2. package/dist/auth/apiKey.d.ts +10 -0
  3. package/dist/auth/apiKey.d.ts.map +1 -0
  4. package/dist/auth/apiKey.js +17 -0
  5. package/dist/auth/oauth.d.ts +29 -0
  6. package/dist/auth/oauth.d.ts.map +1 -0
  7. package/dist/auth/oauth.js +110 -0
  8. package/dist/auth/pkce.d.ts +4 -0
  9. package/dist/auth/pkce.d.ts.map +1 -0
  10. package/dist/auth/pkce.js +10 -0
  11. package/dist/auth/tokenManager.d.ts +24 -0
  12. package/dist/auth/tokenManager.d.ts.map +1 -0
  13. package/dist/auth/tokenManager.js +50 -0
  14. package/dist/auth/tokenStore.d.ts +21 -0
  15. package/dist/auth/tokenStore.d.ts.map +1 -0
  16. package/dist/auth/tokenStore.js +49 -0
  17. package/dist/cjs/auth/apiKey.cjs +21 -0
  18. package/dist/cjs/auth/apiKey.d.ts +10 -0
  19. package/dist/cjs/auth/apiKey.d.ts.map +1 -0
  20. package/dist/cjs/auth/oauth.cjs +114 -0
  21. package/dist/cjs/auth/oauth.d.ts +29 -0
  22. package/dist/cjs/auth/oauth.d.ts.map +1 -0
  23. package/dist/cjs/auth/pkce.cjs +15 -0
  24. package/dist/cjs/auth/pkce.d.ts +4 -0
  25. package/dist/cjs/auth/pkce.d.ts.map +1 -0
  26. package/dist/cjs/auth/tokenManager.cjs +55 -0
  27. package/dist/cjs/auth/tokenManager.d.ts +24 -0
  28. package/dist/cjs/auth/tokenManager.d.ts.map +1 -0
  29. package/dist/cjs/auth/tokenStore.cjs +87 -0
  30. package/dist/cjs/auth/tokenStore.d.ts +21 -0
  31. package/dist/cjs/auth/tokenStore.d.ts.map +1 -0
  32. package/dist/cjs/client.cjs +48 -0
  33. package/dist/cjs/client.d.ts +16 -0
  34. package/dist/cjs/client.d.ts.map +1 -0
  35. package/dist/cjs/errors.cjs +19 -0
  36. package/dist/cjs/errors.d.ts +9 -0
  37. package/dist/cjs/errors.d.ts.map +1 -0
  38. package/dist/cjs/http/client.cjs +62 -0
  39. package/dist/cjs/http/client.d.ts +13 -0
  40. package/dist/cjs/http/client.d.ts.map +1 -0
  41. package/dist/cjs/index.cjs +19 -0
  42. package/dist/cjs/index.d.ts +7 -0
  43. package/dist/cjs/index.d.ts.map +1 -0
  44. package/dist/cjs/resources/index.cjs +120 -0
  45. package/dist/cjs/resources/index.d.ts +71 -0
  46. package/dist/cjs/resources/index.d.ts.map +1 -0
  47. package/dist/cjs/types.cjs +4 -0
  48. package/dist/cjs/types.d.ts +31 -0
  49. package/dist/cjs/types.d.ts.map +1 -0
  50. package/dist/cjs/webhooks/verify.cjs +16 -0
  51. package/dist/cjs/webhooks/verify.d.ts +7 -0
  52. package/dist/cjs/webhooks/verify.d.ts.map +1 -0
  53. package/dist/client.d.ts +16 -0
  54. package/dist/client.d.ts.map +1 -0
  55. package/dist/client.js +44 -0
  56. package/dist/errors.d.ts +9 -0
  57. package/dist/errors.d.ts.map +1 -0
  58. package/dist/errors.js +14 -0
  59. package/dist/http/client.d.ts +13 -0
  60. package/dist/http/client.d.ts.map +1 -0
  61. package/dist/http/client.js +58 -0
  62. package/dist/index.d.ts +7 -0
  63. package/dist/index.d.ts.map +1 -0
  64. package/dist/index.js +6 -0
  65. package/dist/resources/index.d.ts +71 -0
  66. package/dist/resources/index.d.ts.map +1 -0
  67. package/dist/resources/index.js +110 -0
  68. package/dist/types.d.ts +31 -0
  69. package/dist/types.d.ts.map +1 -0
  70. package/dist/types.js +1 -0
  71. package/dist/webhooks/verify.d.ts +7 -0
  72. package/dist/webhooks/verify.d.ts.map +1 -0
  73. package/dist/webhooks/verify.js +13 -0
  74. package/package.json +39 -0
@@ -0,0 +1,55 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.TokenManager = void 0;
4
+ exports.tokenSetFromOAuthResponse = tokenSetFromOAuthResponse;
5
+ const REFRESH_BUFFER_MS = 5 * 60 * 1000;
6
+ class TokenManager {
7
+ store;
8
+ client;
9
+ refreshPromise = null;
10
+ constructor(store, client) {
11
+ this.store = store;
12
+ this.client = client;
13
+ }
14
+ async getValidAccessToken() {
15
+ const tokens = await this.store.load();
16
+ if (!tokens) {
17
+ throw new Error("No OAuth tokens stored. Complete authorization first.");
18
+ }
19
+ if (Date.now() >= tokens.expiresAt - REFRESH_BUFFER_MS) {
20
+ const refreshed = await this.refresh(tokens.refreshToken);
21
+ return refreshed.accessToken;
22
+ }
23
+ return tokens.accessToken;
24
+ }
25
+ async setTokens(tokens) {
26
+ await this.store.save(tokens);
27
+ }
28
+ async refresh(refreshToken) {
29
+ if (!this.refreshPromise) {
30
+ this.refreshPromise = this.client
31
+ .refresh(refreshToken)
32
+ .then(async (tokens) => {
33
+ await this.store.save(tokens);
34
+ return tokens;
35
+ })
36
+ .finally(() => {
37
+ this.refreshPromise = null;
38
+ });
39
+ }
40
+ return this.refreshPromise;
41
+ }
42
+ async clear() {
43
+ await this.store.clear();
44
+ }
45
+ }
46
+ exports.TokenManager = TokenManager;
47
+ function tokenSetFromOAuthResponse(data) {
48
+ return {
49
+ accessToken: data.access_token,
50
+ refreshToken: data.refresh_token,
51
+ expiresAt: Date.now() + data.expires_in * 1000,
52
+ scope: data.scope,
53
+ tokenType: data.token_type,
54
+ };
55
+ }
@@ -0,0 +1,24 @@
1
+ import type { TokenSet } from "../types.js";
2
+ import type { TokenStore } from "./tokenStore.js";
3
+ export interface OAuthTokenClient {
4
+ exchangeCode(code: string, codeVerifier: string): Promise<TokenSet>;
5
+ refresh(refreshToken: string): Promise<TokenSet>;
6
+ }
7
+ export declare class TokenManager {
8
+ private readonly store;
9
+ private readonly client;
10
+ private refreshPromise;
11
+ constructor(store: TokenStore, client: OAuthTokenClient);
12
+ getValidAccessToken(): Promise<string>;
13
+ setTokens(tokens: TokenSet): Promise<void>;
14
+ refresh(refreshToken: string): Promise<TokenSet>;
15
+ clear(): Promise<void>;
16
+ }
17
+ export declare function tokenSetFromOAuthResponse(data: {
18
+ access_token: string;
19
+ refresh_token: string;
20
+ expires_in: number;
21
+ scope: string;
22
+ token_type: string;
23
+ }): TokenSet;
24
+ //# sourceMappingURL=tokenManager.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tokenManager.d.ts","sourceRoot":"","sources":["../../../src/auth/tokenManager.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAIlD,MAAM,WAAW,gBAAgB;IAC/B,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC,QAAQ,CAAC,CAAC;IACpE,OAAO,CAAC,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC,QAAQ,CAAC,CAAC;CAClD;AAED,qBAAa,YAAY;IAIrB,OAAO,CAAC,QAAQ,CAAC,KAAK;IACtB,OAAO,CAAC,QAAQ,CAAC,MAAM;IAJzB,OAAO,CAAC,cAAc,CAAkC;gBAGrC,KAAK,EAAE,UAAU,EACjB,MAAM,EAAE,gBAAgB;IAGrC,mBAAmB,IAAI,OAAO,CAAC,MAAM,CAAC;IAYtC,SAAS,CAAC,MAAM,EAAE,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC;IAI1C,OAAO,CAAC,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC,QAAQ,CAAC;IAehD,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;CAG7B;AAED,wBAAgB,yBAAyB,CAAC,IAAI,EAAE;IAC9C,YAAY,EAAE,MAAM,CAAC;IACrB,aAAa,EAAE,MAAM,CAAC;IACtB,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,EAAE,MAAM,CAAC;IACd,UAAU,EAAE,MAAM,CAAC;CACpB,GAAG,QAAQ,CAQX"}
@@ -0,0 +1,87 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.FileTokenStore = exports.MemoryTokenStore = void 0;
37
+ class MemoryTokenStore {
38
+ tokens = null;
39
+ async load() {
40
+ return this.tokens;
41
+ }
42
+ async save(tokens) {
43
+ this.tokens = tokens;
44
+ }
45
+ async clear() {
46
+ this.tokens = null;
47
+ }
48
+ }
49
+ exports.MemoryTokenStore = MemoryTokenStore;
50
+ class FileTokenStore {
51
+ filePath;
52
+ constructor(filePath) {
53
+ this.filePath = filePath;
54
+ }
55
+ async readFile() {
56
+ const fs = await Promise.resolve().then(() => __importStar(require("node:fs/promises")));
57
+ try {
58
+ return await fs.readFile(this.filePath, "utf8");
59
+ }
60
+ catch (err) {
61
+ if (err.code === "ENOENT")
62
+ return null;
63
+ throw err;
64
+ }
65
+ }
66
+ async load() {
67
+ const raw = await this.readFile();
68
+ if (!raw)
69
+ return null;
70
+ return JSON.parse(raw);
71
+ }
72
+ async save(tokens) {
73
+ const fs = await Promise.resolve().then(() => __importStar(require("node:fs/promises")));
74
+ await fs.writeFile(this.filePath, JSON.stringify(tokens, null, 2), "utf8");
75
+ }
76
+ async clear() {
77
+ const fs = await Promise.resolve().then(() => __importStar(require("node:fs/promises")));
78
+ try {
79
+ await fs.unlink(this.filePath);
80
+ }
81
+ catch (err) {
82
+ if (err.code !== "ENOENT")
83
+ throw err;
84
+ }
85
+ }
86
+ }
87
+ exports.FileTokenStore = FileTokenStore;
@@ -0,0 +1,21 @@
1
+ import type { TokenSet } from "../types.js";
2
+ export interface TokenStore {
3
+ load(): Promise<TokenSet | null>;
4
+ save(tokens: TokenSet): Promise<void>;
5
+ clear(): Promise<void>;
6
+ }
7
+ export declare class MemoryTokenStore implements TokenStore {
8
+ private tokens;
9
+ load(): Promise<TokenSet | null>;
10
+ save(tokens: TokenSet): Promise<void>;
11
+ clear(): Promise<void>;
12
+ }
13
+ export declare class FileTokenStore implements TokenStore {
14
+ private readonly filePath;
15
+ constructor(filePath: string);
16
+ private readFile;
17
+ load(): Promise<TokenSet | null>;
18
+ save(tokens: TokenSet): Promise<void>;
19
+ clear(): Promise<void>;
20
+ }
21
+ //# sourceMappingURL=tokenStore.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tokenStore.d.ts","sourceRoot":"","sources":["../../../src/auth/tokenStore.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAE5C,MAAM,WAAW,UAAU;IACzB,IAAI,IAAI,OAAO,CAAC,QAAQ,GAAG,IAAI,CAAC,CAAC;IACjC,IAAI,CAAC,MAAM,EAAE,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACtC,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CACxB;AAED,qBAAa,gBAAiB,YAAW,UAAU;IACjD,OAAO,CAAC,MAAM,CAAyB;IAEjC,IAAI,IAAI,OAAO,CAAC,QAAQ,GAAG,IAAI,CAAC;IAIhC,IAAI,CAAC,MAAM,EAAE,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC;IAIrC,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;CAG7B;AAED,qBAAa,cAAe,YAAW,UAAU;IACnC,OAAO,CAAC,QAAQ,CAAC,QAAQ;gBAAR,QAAQ,EAAE,MAAM;YAE/B,QAAQ;IAUhB,IAAI,IAAI,OAAO,CAAC,QAAQ,GAAG,IAAI,CAAC;IAMhC,IAAI,CAAC,MAAM,EAAE,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC;IAKrC,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;CAQ7B"}
@@ -0,0 +1,48 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.FoxScheduling = void 0;
4
+ const apiKey_js_1 = require("./auth/apiKey.cjs");
5
+ const oauth_js_1 = require("./auth/oauth.cjs");
6
+ const client_js_1 = require("./http/client.cjs");
7
+ const index_js_1 = require("./resources/index.cjs");
8
+ const types_js_1 = require("./types.cjs");
9
+ class FoxScheduling {
10
+ oauth;
11
+ business;
12
+ services;
13
+ staff;
14
+ availability;
15
+ bookings;
16
+ customers;
17
+ webhooks;
18
+ http;
19
+ constructor(config) {
20
+ const baseUrl = config.baseUrl ?? types_js_1.DEFAULT_BASE_URL;
21
+ const fetchImpl = config.fetch ?? fetch;
22
+ let auth;
23
+ if (config.auth.type === "apiKey") {
24
+ auth = new apiKey_js_1.ApiKeyAuthProvider(config.auth.apiKey);
25
+ }
26
+ else {
27
+ const oauth = new oauth_js_1.OAuthClient({
28
+ baseUrl,
29
+ clientId: config.auth.clientId,
30
+ clientSecret: config.auth.clientSecret,
31
+ redirectUri: config.auth.redirectUri,
32
+ tokenStore: config.auth.tokenStore,
33
+ fetchImpl,
34
+ });
35
+ this.oauth = oauth;
36
+ auth = oauth;
37
+ }
38
+ this.http = new client_js_1.HttpClient(baseUrl, auth, fetchImpl);
39
+ this.business = new index_js_1.BusinessResource(this.http);
40
+ this.services = new index_js_1.ServicesResource(this.http);
41
+ this.staff = new index_js_1.StaffResource(this.http);
42
+ this.availability = new index_js_1.AvailabilityResource(this.http);
43
+ this.bookings = new index_js_1.BookingsResource(this.http);
44
+ this.customers = new index_js_1.CustomersResource(this.http);
45
+ this.webhooks = new index_js_1.WebhooksResource(this.http);
46
+ }
47
+ }
48
+ exports.FoxScheduling = FoxScheduling;
@@ -0,0 +1,16 @@
1
+ import { OAuthClient } from "./auth/oauth.js";
2
+ import { AvailabilityResource, BookingsResource, BusinessResource, CustomersResource, ServicesResource, StaffResource, WebhooksResource } from "./resources/index.js";
3
+ import { type FoxSchedulingConfig } from "./types.js";
4
+ export declare class FoxScheduling {
5
+ readonly oauth?: OAuthClient;
6
+ readonly business: BusinessResource;
7
+ readonly services: ServicesResource;
8
+ readonly staff: StaffResource;
9
+ readonly availability: AvailabilityResource;
10
+ readonly bookings: BookingsResource;
11
+ readonly customers: CustomersResource;
12
+ readonly webhooks: WebhooksResource;
13
+ private readonly http;
14
+ constructor(config: FoxSchedulingConfig);
15
+ }
16
+ //# sourceMappingURL=client.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../src/client.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAE9C,OAAO,EACL,oBAAoB,EACpB,gBAAgB,EAChB,gBAAgB,EAChB,iBAAiB,EACjB,gBAAgB,EAChB,aAAa,EACb,gBAAgB,EACjB,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EAEL,KAAK,mBAAmB,EACzB,MAAM,YAAY,CAAC;AAEpB,qBAAa,aAAa;IACxB,QAAQ,CAAC,KAAK,CAAC,EAAE,WAAW,CAAC;IAC7B,QAAQ,CAAC,QAAQ,EAAE,gBAAgB,CAAC;IACpC,QAAQ,CAAC,QAAQ,EAAE,gBAAgB,CAAC;IACpC,QAAQ,CAAC,KAAK,EAAE,aAAa,CAAC;IAC9B,QAAQ,CAAC,YAAY,EAAE,oBAAoB,CAAC;IAC5C,QAAQ,CAAC,QAAQ,EAAE,gBAAgB,CAAC;IACpC,QAAQ,CAAC,SAAS,EAAE,iBAAiB,CAAC;IACtC,QAAQ,CAAC,QAAQ,EAAE,gBAAgB,CAAC;IAEpC,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAa;gBAEtB,MAAM,EAAE,mBAAmB;CA6BxC"}
@@ -0,0 +1,19 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.FoxSchedulingError = void 0;
4
+ exports.isFoxSchedulingError = isFoxSchedulingError;
5
+ class FoxSchedulingError extends Error {
6
+ errorCode;
7
+ constructor(errorCode, message) {
8
+ super(message ?? errorCode);
9
+ this.name = "FoxSchedulingError";
10
+ this.errorCode = errorCode;
11
+ }
12
+ static fromResponse(errorCode) {
13
+ return new FoxSchedulingError(errorCode);
14
+ }
15
+ }
16
+ exports.FoxSchedulingError = FoxSchedulingError;
17
+ function isFoxSchedulingError(err) {
18
+ return err instanceof FoxSchedulingError;
19
+ }
@@ -0,0 +1,9 @@
1
+ import type { ErrorCodes } from "@foxscheduling/shared";
2
+ export declare class FoxSchedulingError extends Error {
3
+ readonly errorCode: string;
4
+ constructor(errorCode: string, message?: string);
5
+ static fromResponse(errorCode: string): FoxSchedulingError;
6
+ }
7
+ export declare function isFoxSchedulingError(err: unknown): err is FoxSchedulingError;
8
+ export type { ErrorCodes };
9
+ //# sourceMappingURL=errors.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../src/errors.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAC;AAExD,qBAAa,kBAAmB,SAAQ,KAAK;IAC3C,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;gBAEf,SAAS,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM;IAM/C,MAAM,CAAC,YAAY,CAAC,SAAS,EAAE,MAAM,GAAG,kBAAkB;CAG3D;AAED,wBAAgB,oBAAoB,CAAC,GAAG,EAAE,OAAO,GAAG,GAAG,IAAI,kBAAkB,CAE5E;AAED,YAAY,EAAE,UAAU,EAAE,CAAC"}
@@ -0,0 +1,62 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.HttpClient = void 0;
4
+ const errors_js_1 = require("../errors.js");
5
+ class HttpClient {
6
+ baseUrl;
7
+ auth;
8
+ fetchImpl;
9
+ constructor(baseUrl, auth, fetchImpl) {
10
+ this.baseUrl = baseUrl;
11
+ this.auth = auth;
12
+ this.fetchImpl = fetchImpl;
13
+ }
14
+ async request(path, options = {}, retried = false) {
15
+ const authHeader = await this.auth.getAuthorizationHeader();
16
+ const headers = new Headers(options.headers);
17
+ headers.set("Authorization", authHeader);
18
+ if (options.body && !headers.has("Content-Type")) {
19
+ headers.set("Content-Type", "application/json");
20
+ }
21
+ const res = await this.fetchImpl(`${this.baseUrl}${path}`, {
22
+ ...options,
23
+ headers,
24
+ });
25
+ const json = (await res.json());
26
+ if (json.statusMessage === "ERROR" || json.errorCode) {
27
+ throw errors_js_1.FoxSchedulingError.fromResponse(json.errorCode ?? "UNKNOWN_ERROR");
28
+ }
29
+ if (res.status === 401 && !retried && this.auth.onUnauthorized) {
30
+ const refreshed = await this.auth.onUnauthorized();
31
+ if (refreshed)
32
+ return this.request(path, options, true);
33
+ }
34
+ if (!res.ok) {
35
+ throw errors_js_1.FoxSchedulingError.fromResponse(json.errorCode ?? "HTTP_ERROR");
36
+ }
37
+ return json.data;
38
+ }
39
+ get(path, query) {
40
+ const qs = query
41
+ ? `?${new URLSearchParams(Object.entries(query).filter(([, v]) => v != null)).toString()}`
42
+ : "";
43
+ return this.request(`${path}${qs}`, { method: "GET" });
44
+ }
45
+ post(path, body, query) {
46
+ const qs = query ? `?${new URLSearchParams(query).toString()}` : "";
47
+ return this.request(`${path}${qs}`, {
48
+ method: "POST",
49
+ body: body !== undefined ? JSON.stringify(body) : undefined,
50
+ });
51
+ }
52
+ patch(path, body) {
53
+ return this.request(path, {
54
+ method: "PATCH",
55
+ body: body !== undefined ? JSON.stringify(body) : undefined,
56
+ });
57
+ }
58
+ delete(path) {
59
+ return this.request(path, { method: "DELETE" });
60
+ }
61
+ }
62
+ exports.HttpClient = HttpClient;
@@ -0,0 +1,13 @@
1
+ import type { AuthProvider } from "../auth/apiKey.js";
2
+ export declare class HttpClient {
3
+ private readonly baseUrl;
4
+ private readonly auth;
5
+ private readonly fetchImpl;
6
+ constructor(baseUrl: string, auth: AuthProvider, fetchImpl: typeof fetch);
7
+ request<T>(path: string, options?: RequestInit, retried?: boolean): Promise<T>;
8
+ get<T>(path: string, query?: Record<string, string | undefined>): Promise<T>;
9
+ post<T>(path: string, body?: unknown, query?: Record<string, string>): Promise<T>;
10
+ patch<T>(path: string, body?: unknown): Promise<T>;
11
+ delete<T>(path: string): Promise<T>;
12
+ }
13
+ //# sourceMappingURL=client.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../../src/http/client.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAQtD,qBAAa,UAAU;IAEnB,OAAO,CAAC,QAAQ,CAAC,OAAO;IACxB,OAAO,CAAC,QAAQ,CAAC,IAAI;IACrB,OAAO,CAAC,QAAQ,CAAC,SAAS;gBAFT,OAAO,EAAE,MAAM,EACf,IAAI,EAAE,YAAY,EAClB,SAAS,EAAE,OAAO,KAAK;IAGpC,OAAO,CAAC,CAAC,EACb,IAAI,EAAE,MAAM,EACZ,OAAO,GAAE,WAAgB,EACzB,OAAO,UAAQ,GACd,OAAO,CAAC,CAAC,CAAC;IA8Bb,GAAG,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC;IAS5E,IAAI,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,OAAO,EAAE,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC;IAQjF,KAAK,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,OAAO,GAAG,OAAO,CAAC,CAAC,CAAC;IAOlD,MAAM,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,CAAC,CAAC;CAGpC"}
@@ -0,0 +1,19 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.DEFAULT_BASE_URL = exports.verifyFoxWebhookSignature = exports.generateState = exports.generateCodeChallengeS256 = exports.generateCodeVerifier = exports.FileTokenStore = exports.MemoryTokenStore = exports.isFoxSchedulingError = exports.FoxSchedulingError = exports.FoxScheduling = void 0;
4
+ var client_js_1 = require("./client.cjs");
5
+ Object.defineProperty(exports, "FoxScheduling", { enumerable: true, get: function () { return client_js_1.FoxScheduling; } });
6
+ var errors_js_1 = require("./errors.cjs");
7
+ Object.defineProperty(exports, "FoxSchedulingError", { enumerable: true, get: function () { return errors_js_1.FoxSchedulingError; } });
8
+ Object.defineProperty(exports, "isFoxSchedulingError", { enumerable: true, get: function () { return errors_js_1.isFoxSchedulingError; } });
9
+ var tokenStore_js_1 = require("./auth/tokenStore.cjs");
10
+ Object.defineProperty(exports, "MemoryTokenStore", { enumerable: true, get: function () { return tokenStore_js_1.MemoryTokenStore; } });
11
+ Object.defineProperty(exports, "FileTokenStore", { enumerable: true, get: function () { return tokenStore_js_1.FileTokenStore; } });
12
+ var pkce_js_1 = require("./auth/pkce.cjs");
13
+ Object.defineProperty(exports, "generateCodeVerifier", { enumerable: true, get: function () { return pkce_js_1.generateCodeVerifier; } });
14
+ Object.defineProperty(exports, "generateCodeChallengeS256", { enumerable: true, get: function () { return pkce_js_1.generateCodeChallengeS256; } });
15
+ Object.defineProperty(exports, "generateState", { enumerable: true, get: function () { return pkce_js_1.generateState; } });
16
+ var verify_js_1 = require("./webhooks/verify.cjs");
17
+ Object.defineProperty(exports, "verifyFoxWebhookSignature", { enumerable: true, get: function () { return verify_js_1.verifyFoxWebhookSignature; } });
18
+ var types_js_1 = require("./types.cjs");
19
+ Object.defineProperty(exports, "DEFAULT_BASE_URL", { enumerable: true, get: function () { return types_js_1.DEFAULT_BASE_URL; } });
@@ -0,0 +1,7 @@
1
+ export { FoxScheduling } from "./client.js";
2
+ export { FoxSchedulingError, isFoxSchedulingError } from "./errors.js";
3
+ export { MemoryTokenStore, FileTokenStore, type TokenStore, } from "./auth/tokenStore.js";
4
+ export { generateCodeVerifier, generateCodeChallengeS256, generateState, } from "./auth/pkce.js";
5
+ export { verifyFoxWebhookSignature } from "./webhooks/verify.js";
6
+ export { DEFAULT_BASE_URL, type FoxSchedulingConfig, type FoxSchedulingAuth, type FoxSchedulingApiKeyAuth, type FoxSchedulingOAuthAuth, type TokenSet, type AuthorizationUrlResult, } from "./types.js";
7
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,EAAE,kBAAkB,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAC;AACvE,OAAO,EACL,gBAAgB,EAChB,cAAc,EACd,KAAK,UAAU,GAChB,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EACL,oBAAoB,EACpB,yBAAyB,EACzB,aAAa,GACd,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAAE,yBAAyB,EAAE,MAAM,sBAAsB,CAAC;AACjE,OAAO,EACL,gBAAgB,EAChB,KAAK,mBAAmB,EACxB,KAAK,iBAAiB,EACtB,KAAK,uBAAuB,EAC5B,KAAK,sBAAsB,EAC3B,KAAK,QAAQ,EACb,KAAK,sBAAsB,GAC5B,MAAM,YAAY,CAAC"}
@@ -0,0 +1,120 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.WebhooksResource = exports.CustomersResource = exports.BookingsResource = exports.AvailabilityResource = exports.StaffResource = exports.ServicesResource = exports.BusinessResource = void 0;
4
+ class BusinessResource {
5
+ http;
6
+ constructor(http) {
7
+ this.http = http;
8
+ }
9
+ get() {
10
+ return this.http.get("/partner/business");
11
+ }
12
+ }
13
+ exports.BusinessResource = BusinessResource;
14
+ class ServicesResource {
15
+ http;
16
+ constructor(http) {
17
+ this.http = http;
18
+ }
19
+ list() {
20
+ return this.http.get("/partner/services");
21
+ }
22
+ get(id) {
23
+ return this.http.get(`/partner/services/${id}`);
24
+ }
25
+ }
26
+ exports.ServicesResource = ServicesResource;
27
+ class StaffResource {
28
+ http;
29
+ constructor(http) {
30
+ this.http = http;
31
+ }
32
+ list() {
33
+ return this.http.get("/partner/staff");
34
+ }
35
+ get(id) {
36
+ return this.http.get(`/partner/staff/${id}`);
37
+ }
38
+ }
39
+ exports.StaffResource = StaffResource;
40
+ class AvailabilityResource {
41
+ http;
42
+ constructor(http) {
43
+ this.http = http;
44
+ }
45
+ list() {
46
+ return this.http.get("/partner/availability");
47
+ }
48
+ get(id) {
49
+ return this.http.get(`/partner/availability/${id}`);
50
+ }
51
+ create(body) {
52
+ return this.http.post("/partner/availability", body);
53
+ }
54
+ update(id, body) {
55
+ return this.http.patch(`/partner/availability/${id}`, body);
56
+ }
57
+ delete(id) {
58
+ return this.http.delete(`/partner/availability/${id}`);
59
+ }
60
+ }
61
+ exports.AvailabilityResource = AvailabilityResource;
62
+ class BookingsResource {
63
+ http;
64
+ constructor(http) {
65
+ this.http = http;
66
+ }
67
+ list(query) {
68
+ return this.http.get("/partner/bookings", query);
69
+ }
70
+ get(id, serviceId) {
71
+ return this.http.get(`/partner/bookings/${id}`, { serviceId });
72
+ }
73
+ create(body) {
74
+ return this.http.post("/partner/bookings", body);
75
+ }
76
+ cancel(id, serviceId) {
77
+ return this.http.post(`/partner/bookings/${id}/cancel`, undefined, {
78
+ serviceId,
79
+ });
80
+ }
81
+ }
82
+ exports.BookingsResource = BookingsResource;
83
+ class CustomersResource {
84
+ http;
85
+ constructor(http) {
86
+ this.http = http;
87
+ }
88
+ list() {
89
+ return this.http.get("/partner/customers");
90
+ }
91
+ get(id) {
92
+ return this.http.get(`/partner/customers/${id}`);
93
+ }
94
+ create(body) {
95
+ return this.http.post("/partner/customers", body);
96
+ }
97
+ update(id, body) {
98
+ return this.http.patch(`/partner/customers/${id}`, body);
99
+ }
100
+ }
101
+ exports.CustomersResource = CustomersResource;
102
+ class WebhooksResource {
103
+ http;
104
+ constructor(http) {
105
+ this.http = http;
106
+ }
107
+ list() {
108
+ return this.http.get("/partner/webhooks");
109
+ }
110
+ create(body) {
111
+ return this.http.post("/partner/webhooks", body);
112
+ }
113
+ update(id, body) {
114
+ return this.http.patch(`/partner/webhooks/${id}`, body);
115
+ }
116
+ delete(id) {
117
+ return this.http.delete(`/partner/webhooks/${id}`);
118
+ }
119
+ }
120
+ exports.WebhooksResource = WebhooksResource;
@@ -0,0 +1,71 @@
1
+ import type { BusinessProfileDto, PartnerBookingDto, PartnerCustomerDto, PartnerServiceDto, PartnerStaffDto, PartnerWebhookEvent } from "@foxscheduling/shared";
2
+ import type { HttpClient } from "../http/client.js";
3
+ export declare class BusinessResource {
4
+ private readonly http;
5
+ constructor(http: HttpClient);
6
+ get(): Promise<BusinessProfileDto>;
7
+ }
8
+ export declare class ServicesResource {
9
+ private readonly http;
10
+ constructor(http: HttpClient);
11
+ list(): Promise<PartnerServiceDto[]>;
12
+ get(id: string): Promise<PartnerServiceDto>;
13
+ }
14
+ export declare class StaffResource {
15
+ private readonly http;
16
+ constructor(http: HttpClient);
17
+ list(): Promise<PartnerStaffDto[]>;
18
+ get(id: string): Promise<PartnerStaffDto>;
19
+ }
20
+ export declare class AvailabilityResource {
21
+ private readonly http;
22
+ constructor(http: HttpClient);
23
+ list(): Promise<unknown[]>;
24
+ get(id: string): Promise<unknown>;
25
+ create(body: unknown): Promise<unknown>;
26
+ update(id: string, body: unknown): Promise<unknown>;
27
+ delete(id: string): Promise<unknown>;
28
+ }
29
+ export declare class BookingsResource {
30
+ private readonly http;
31
+ constructor(http: HttpClient);
32
+ list(query?: Record<string, string>): Promise<PartnerBookingDto[]>;
33
+ get(id: string, serviceId: string): Promise<PartnerBookingDto>;
34
+ create(body: unknown): Promise<unknown>;
35
+ cancel(id: string, serviceId: string): Promise<unknown>;
36
+ }
37
+ export declare class CustomersResource {
38
+ private readonly http;
39
+ constructor(http: HttpClient);
40
+ list(): Promise<PartnerCustomerDto[]>;
41
+ get(id: string): Promise<PartnerCustomerDto>;
42
+ create(body: {
43
+ name: string;
44
+ email: string;
45
+ }): Promise<PartnerCustomerDto>;
46
+ update(id: string, body: unknown): Promise<PartnerCustomerDto>;
47
+ }
48
+ export interface WebhookSubscriptionPublic {
49
+ id: string;
50
+ url: string;
51
+ events: PartnerWebhookEvent[];
52
+ creationDate?: string;
53
+ }
54
+ export declare class WebhooksResource {
55
+ private readonly http;
56
+ constructor(http: HttpClient);
57
+ list(): Promise<WebhookSubscriptionPublic[]>;
58
+ create(body: {
59
+ url: string;
60
+ events: PartnerWebhookEvent[];
61
+ }): Promise<{
62
+ subscription: WebhookSubscriptionPublic;
63
+ secret: string;
64
+ }>;
65
+ update(id: string, body: Partial<{
66
+ url: string;
67
+ events: PartnerWebhookEvent[];
68
+ }>): Promise<WebhookSubscriptionPublic>;
69
+ delete(id: string): Promise<unknown>;
70
+ }
71
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/resources/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,kBAAkB,EAClB,iBAAiB,EACjB,kBAAkB,EAClB,iBAAiB,EACjB,eAAe,EACf,mBAAmB,EACpB,MAAM,uBAAuB,CAAC;AAC/B,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAEpD,qBAAa,gBAAgB;IACf,OAAO,CAAC,QAAQ,CAAC,IAAI;gBAAJ,IAAI,EAAE,UAAU;IAE7C,GAAG,IAAI,OAAO,CAAC,kBAAkB,CAAC;CAGnC;AAED,qBAAa,gBAAgB;IACf,OAAO,CAAC,QAAQ,CAAC,IAAI;gBAAJ,IAAI,EAAE,UAAU;IAE7C,IAAI,IAAI,OAAO,CAAC,iBAAiB,EAAE,CAAC;IAIpC,GAAG,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,iBAAiB,CAAC;CAG5C;AAED,qBAAa,aAAa;IACZ,OAAO,CAAC,QAAQ,CAAC,IAAI;gBAAJ,IAAI,EAAE,UAAU;IAE7C,IAAI,IAAI,OAAO,CAAC,eAAe,EAAE,CAAC;IAIlC,GAAG,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,eAAe,CAAC;CAG1C;AAED,qBAAa,oBAAoB;IACnB,OAAO,CAAC,QAAQ,CAAC,IAAI;gBAAJ,IAAI,EAAE,UAAU;IAE7C,IAAI,IAAI,OAAO,CAAC,OAAO,EAAE,CAAC;IAI1B,GAAG,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAIjC,MAAM,CAAC,IAAI,EAAE,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC;IAIvC,MAAM,CAAC,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC;IAInD,MAAM,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;CAGrC;AAED,qBAAa,gBAAgB;IACf,OAAO,CAAC,QAAQ,CAAC,IAAI;gBAAJ,IAAI,EAAE,UAAU;IAE7C,IAAI,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,OAAO,CAAC,iBAAiB,EAAE,CAAC;IAIlE,GAAG,CAAC,EAAE,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,iBAAiB,CAAC;IAI9D,MAAM,CAAC,IAAI,EAAE,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC;IAIvC,MAAM,CAAC,EAAE,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;CAKxD;AAED,qBAAa,iBAAiB;IAChB,OAAO,CAAC,QAAQ,CAAC,IAAI;gBAAJ,IAAI,EAAE,UAAU;IAE7C,IAAI,IAAI,OAAO,CAAC,kBAAkB,EAAE,CAAC;IAIrC,GAAG,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,kBAAkB,CAAC;IAI5C,MAAM,CAAC,IAAI,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,kBAAkB,CAAC;IAI1E,MAAM,CAAC,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,GAAG,OAAO,CAAC,kBAAkB,CAAC;CAG/D;AAED,MAAM,WAAW,yBAAyB;IACxC,EAAE,EAAE,MAAM,CAAC;IACX,GAAG,EAAE,MAAM,CAAC;IACZ,MAAM,EAAE,mBAAmB,EAAE,CAAC;IAC9B,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED,qBAAa,gBAAgB;IACf,OAAO,CAAC,QAAQ,CAAC,IAAI;gBAAJ,IAAI,EAAE,UAAU;IAE7C,IAAI,IAAI,OAAO,CAAC,yBAAyB,EAAE,CAAC;IAI5C,MAAM,CAAC,IAAI,EAAE;QACX,GAAG,EAAE,MAAM,CAAC;QACZ,MAAM,EAAE,mBAAmB,EAAE,CAAC;KAC/B,GAAG,OAAO,CAAC;QAAE,YAAY,EAAE,yBAAyB,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC;IAIxE,MAAM,CACJ,EAAE,EAAE,MAAM,EACV,IAAI,EAAE,OAAO,CAAC;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,mBAAmB,EAAE,CAAA;KAAE,CAAC,GAC5D,OAAO,CAAC,yBAAyB,CAAC;IAIrC,MAAM,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;CAGrC"}
@@ -0,0 +1,4 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.DEFAULT_BASE_URL = void 0;
4
+ exports.DEFAULT_BASE_URL = "https://foxscheduling.com/api/v1";
@@ -0,0 +1,31 @@
1
+ export declare const DEFAULT_BASE_URL = "https://foxscheduling.com/api/v1";
2
+ export interface TokenSet {
3
+ accessToken: string;
4
+ refreshToken: string;
5
+ expiresAt: number;
6
+ scope: string;
7
+ tokenType: string;
8
+ }
9
+ export interface FoxSchedulingApiKeyAuth {
10
+ type: "apiKey";
11
+ apiKey: string;
12
+ }
13
+ export interface FoxSchedulingOAuthAuth {
14
+ type: "oauth";
15
+ clientId: string;
16
+ clientSecret?: string;
17
+ redirectUri: string;
18
+ tokenStore: import("./auth/tokenStore.js").TokenStore;
19
+ }
20
+ export type FoxSchedulingAuth = FoxSchedulingApiKeyAuth | FoxSchedulingOAuthAuth;
21
+ export interface FoxSchedulingConfig {
22
+ auth: FoxSchedulingAuth;
23
+ baseUrl?: string;
24
+ fetch?: typeof fetch;
25
+ }
26
+ export interface AuthorizationUrlResult {
27
+ url: string;
28
+ codeVerifier: string;
29
+ state: string;
30
+ }
31
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/types.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,gBAAgB,qCAAqC,CAAC;AAEnE,MAAM,WAAW,QAAQ;IACvB,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,MAAM,CAAC;IACrB,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,uBAAuB;IACtC,IAAI,EAAE,QAAQ,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,sBAAsB;IACrC,IAAI,EAAE,OAAO,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,OAAO,sBAAsB,EAAE,UAAU,CAAC;CACvD;AAED,MAAM,MAAM,iBAAiB,GAAG,uBAAuB,GAAG,sBAAsB,CAAC;AAEjF,MAAM,WAAW,mBAAmB;IAClC,IAAI,EAAE,iBAAiB,CAAC;IACxB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,EAAE,OAAO,KAAK,CAAC;CACtB;AAED,MAAM,WAAW,sBAAsB;IACrC,GAAG,EAAE,MAAM,CAAC;IACZ,YAAY,EAAE,MAAM,CAAC;IACrB,KAAK,EAAE,MAAM,CAAC;CACf"}