@delofarag/crm-utils 0.2.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 (42) hide show
  1. package/README.md +151 -0
  2. package/dist/BaseCrm.d.ts +37 -0
  3. package/dist/BaseCrm.d.ts.map +1 -0
  4. package/dist/BaseCrm.js +3 -0
  5. package/dist/BaseCrm.js.map +1 -0
  6. package/dist/CRM.d.ts +37 -0
  7. package/dist/CRM.d.ts.map +1 -0
  8. package/dist/CRM.js +3 -0
  9. package/dist/CRM.js.map +1 -0
  10. package/dist/CrmConnection.d.ts +4 -0
  11. package/dist/CrmConnection.d.ts.map +1 -0
  12. package/dist/CrmConnection.js +3 -0
  13. package/dist/CrmConnection.js.map +1 -0
  14. package/dist/crms/hubspot/hubspot.d.ts +183 -0
  15. package/dist/crms/hubspot/hubspot.d.ts.map +1 -0
  16. package/dist/crms/hubspot/hubspot.js +349 -0
  17. package/dist/crms/hubspot/hubspot.js.map +1 -0
  18. package/dist/crms/hubspot/types.d.ts +52 -0
  19. package/dist/crms/hubspot/types.d.ts.map +1 -0
  20. package/dist/crms/hubspot/types.js +18 -0
  21. package/dist/crms/hubspot/types.js.map +1 -0
  22. package/dist/crms/hubspot.d.ts +108 -0
  23. package/dist/crms/hubspot.d.ts.map +1 -0
  24. package/dist/crms/hubspot.js +254 -0
  25. package/dist/crms/hubspot.js.map +1 -0
  26. package/dist/getCRM.d.ts +15 -0
  27. package/dist/getCRM.d.ts.map +1 -0
  28. package/dist/getCRM.js +13 -0
  29. package/dist/getCRM.js.map +1 -0
  30. package/dist/index.d.ts +8 -0
  31. package/dist/index.d.ts.map +1 -0
  32. package/dist/index.js +7 -0
  33. package/dist/index.js.map +1 -0
  34. package/dist/oauth-helpers.d.ts +5 -0
  35. package/dist/oauth-helpers.d.ts.map +1 -0
  36. package/dist/oauth-helpers.js +21 -0
  37. package/dist/oauth-helpers.js.map +1 -0
  38. package/dist/types.d.ts +24 -0
  39. package/dist/types.d.ts.map +1 -0
  40. package/dist/types.js +2 -0
  41. package/dist/types.js.map +1 -0
  42. package/package.json +26 -0
@@ -0,0 +1,254 @@
1
+ import CRM from "../CRM";
2
+ import CrmConnection from "../CrmConnection";
3
+ import { buildQueryString, postFormUrlEncoded, randomState, toExpiresAt } from "../oauth-helpers";
4
+ const HUBSPOT_AUTHORIZE = "https://app.hubspot.com/oauth/authorize";
5
+ const HUBSPOT_TOKEN = "https://api.hubapi.com/oauth/v1/token";
6
+ const HUBSPOT_API = "https://api.hubapi.com";
7
+ export class HubspotConnection extends CrmConnection {
8
+ provider = "hubspot";
9
+ /**
10
+ * OAuth-Start: Authorize-URL + state. Optional onPersistState für DB (z.B. Pending-Row).
11
+ */
12
+ async buildAuthorizeUrl(args) {
13
+ const state = args.state ?? randomState();
14
+ const tokenStore = {
15
+ state,
16
+ provider: this.provider,
17
+ workspace_id: args.workspace_id,
18
+ supabase_user_id: args.supabase_user_id,
19
+ connected_by_user_id: args.connected_by_user_id,
20
+ created_at: new Date(),
21
+ };
22
+ await this.maybePersist(args.onPersistState, tokenStore);
23
+ const qs = buildQueryString({
24
+ client_id: args.clientId,
25
+ redirect_uri: args.redirectUri,
26
+ scope: args.scopes.join(" "),
27
+ state,
28
+ });
29
+ const authorizeUrl = `${HUBSPOT_AUTHORIZE}?${qs}`;
30
+ return { authorizeUrl, state, tokenStore };
31
+ }
32
+ /**
33
+ * Callback: code → Tokens. Optional onPersistTokens nach erfolgreichem Exchange.
34
+ */
35
+ async exchangeAuthorizationCode(args) {
36
+ const res = await postFormUrlEncoded(HUBSPOT_TOKEN, {
37
+ grant_type: "authorization_code",
38
+ client_id: args.clientId,
39
+ client_secret: args.clientSecret,
40
+ redirect_uri: args.redirectUri,
41
+ code: args.code,
42
+ });
43
+ const text = await res.text();
44
+ if (!res.ok) {
45
+ throw new Error(`HubSpot token exchange failed: ${res.status} ${text}`);
46
+ }
47
+ const raw = JSON.parse(text);
48
+ const expires_at = toExpiresAt(raw.expires_in);
49
+ let portalId;
50
+ let meta;
51
+ if (raw.access_token) {
52
+ try {
53
+ meta = await this.fetchAccessTokenMetadata(raw.access_token);
54
+ portalId = meta.hub_id;
55
+ }
56
+ catch {
57
+ portalId = undefined;
58
+ }
59
+ }
60
+ const tokenStore = {
61
+ provider: this.provider,
62
+ workspace_id: args.workspace_id,
63
+ supabase_user_id: args.supabase_user_id,
64
+ connected_by_user_id: args.connected_by_user_id,
65
+ access_token: raw.access_token,
66
+ refresh_token: raw.refresh_token ?? null,
67
+ expires_at,
68
+ provider_account_id: portalId != null ? String(portalId) : undefined,
69
+ };
70
+ await this.maybePersist(args.onPersistTokens, tokenStore);
71
+ return { raw, tokenStore, portalId };
72
+ }
73
+ async refreshAccessToken(args) {
74
+ const res = await postFormUrlEncoded(HUBSPOT_TOKEN, {
75
+ grant_type: "refresh_token",
76
+ client_id: args.clientId,
77
+ client_secret: args.clientSecret,
78
+ refresh_token: args.refreshToken,
79
+ });
80
+ const text = await res.text();
81
+ if (!res.ok) {
82
+ throw new Error(`HubSpot refresh failed: ${res.status} ${text}`);
83
+ }
84
+ const raw = JSON.parse(text);
85
+ const expires_at = toExpiresAt(raw.expires_in);
86
+ const tokenStore = {
87
+ provider: this.provider,
88
+ workspace_id: args.workspace_id,
89
+ access_token: raw.access_token,
90
+ refresh_token: raw.refresh_token ?? args.refreshToken,
91
+ expires_at,
92
+ };
93
+ await this.maybePersist(args.onPersistTokens, tokenStore);
94
+ return { raw, tokenStore };
95
+ }
96
+ /**
97
+ * HubSpot: GET /oauth/v1/access-tokens/{token} — u.a. hub_id (Portal).
98
+ */
99
+ async fetchAccessTokenMetadata(accessToken) {
100
+ const r = await fetch(`${HUBSPOT_API}/oauth/v1/access-tokens/${encodeURIComponent(accessToken)}`);
101
+ const text = await r.text();
102
+ if (!r.ok) {
103
+ throw new Error(`HubSpot access-token metadata failed: ${r.status} ${text}`);
104
+ }
105
+ return JSON.parse(text);
106
+ }
107
+ /**
108
+ * Hilfe: gültigen Access Token — entweder aus tokenStore oder nach Refresh.
109
+ * Optional onPersistTokens wenn refresht.
110
+ */
111
+ async getValidAccessToken(args) {
112
+ const skew = args.skewMs ?? 60_000;
113
+ const exp = args.expiresAt instanceof Date
114
+ ? args.expiresAt.getTime()
115
+ : args.expiresAt
116
+ ? new Date(args.expiresAt).getTime()
117
+ : null;
118
+ if (args.accessToken &&
119
+ (exp == null || !Number.isFinite(exp) || exp > Date.now() + skew)) {
120
+ return args.accessToken;
121
+ }
122
+ if (!args.refreshToken) {
123
+ throw new Error("HubSpot: no valid access token and no refresh token");
124
+ }
125
+ const { tokenStore } = await this.refreshAccessToken({
126
+ refreshToken: args.refreshToken,
127
+ clientId: args.clientId,
128
+ clientSecret: args.clientSecret,
129
+ workspace_id: args.workspace_id,
130
+ onPersistTokens: args.onPersistTokens,
131
+ });
132
+ if (!tokenStore.access_token) {
133
+ throw new Error("HubSpot refresh returned no access_token");
134
+ }
135
+ return tokenStore.access_token;
136
+ }
137
+ }
138
+ async function hubspotFetchJson(path, options) {
139
+ const method = options.method ?? "GET";
140
+ const headers = {
141
+ Authorization: `Bearer ${options.accessToken}`,
142
+ Accept: "application/json",
143
+ };
144
+ let body;
145
+ if (options.body !== undefined) {
146
+ headers["Content-Type"] = "application/json";
147
+ body = JSON.stringify(options.body);
148
+ }
149
+ const r = await fetch(`${HUBSPOT_API}${path}`, { method, headers, body });
150
+ const text = await r.text();
151
+ if (!r.ok) {
152
+ throw new Error(`HubSpot API ${method} ${path}: ${r.status} ${text}`);
153
+ }
154
+ return text ? JSON.parse(text) : null;
155
+ }
156
+ export class Hubspot extends CRM {
157
+ provider = "hubspot";
158
+ connection;
159
+ constructor() {
160
+ super();
161
+ this.connection = new HubspotConnection();
162
+ }
163
+ async getContacts(options) {
164
+ const limit = options.limit ?? 10;
165
+ const params = new URLSearchParams({ limit: String(limit) });
166
+ if (options.after) {
167
+ params.set("after", options.after);
168
+ }
169
+ return hubspotFetchJson(`/crm/v3/objects/contacts?${params.toString()}`, {
170
+ accessToken: options.accessToken,
171
+ });
172
+ }
173
+ async getCompanies(options) {
174
+ const limit = options.limit ?? 10;
175
+ const params = new URLSearchParams({ limit: String(limit) });
176
+ if (options.after) {
177
+ params.set("after", options.after);
178
+ }
179
+ return hubspotFetchJson(`/crm/v3/objects/companies?${params.toString()}`, {
180
+ accessToken: options.accessToken,
181
+ });
182
+ }
183
+ async createContact(options) {
184
+ return hubspotFetchJson("/crm/v3/objects/contacts", {
185
+ accessToken: options.accessToken,
186
+ method: "POST",
187
+ body: { properties: options.properties },
188
+ });
189
+ }
190
+ async updateContact(options) {
191
+ return hubspotFetchJson(`/crm/v3/objects/contacts/${encodeURIComponent(options.id)}`, {
192
+ accessToken: options.accessToken,
193
+ method: "PATCH",
194
+ body: { properties: options.properties },
195
+ });
196
+ }
197
+ async createNote(options) {
198
+ return hubspotFetchJson("/crm/v3/objects/notes", {
199
+ accessToken: options.accessToken,
200
+ method: "POST",
201
+ body: {
202
+ properties: { hs_note_body: options.body },
203
+ associations: [
204
+ {
205
+ to: { id: options.associateToId },
206
+ types: [
207
+ {
208
+ associationCategory: "HUBSPOT_DEFINED",
209
+ associationTypeId: noteAssociationTypeId(options.associateToObjectType),
210
+ },
211
+ ],
212
+ },
213
+ ],
214
+ },
215
+ });
216
+ }
217
+ async searchRecords(options) {
218
+ const limit = options.limit ?? 10;
219
+ const body = { limit };
220
+ if (options.filterGroups) {
221
+ body.filterGroups = options.filterGroups;
222
+ }
223
+ if (options.properties) {
224
+ body.properties = options.properties;
225
+ }
226
+ if (options.after) {
227
+ body.after = options.after;
228
+ }
229
+ return hubspotFetchJson(`/crm/v3/objects/${encodeURIComponent(options.objectType)}/search`, {
230
+ accessToken: options.accessToken,
231
+ method: "POST",
232
+ body,
233
+ });
234
+ }
235
+ }
236
+ /**
237
+ * HubSpot association type ids (HUBSPOT_DEFINED) — notes to common objects.
238
+ * @see https://developers.hubspot.com/docs/api/crm/associations
239
+ */
240
+ function noteAssociationTypeId(associateToObjectType) {
241
+ const t = associateToObjectType.toLowerCase();
242
+ if (t === "contacts" || t === "contact") {
243
+ return 202;
244
+ }
245
+ if (t === "companies" || t === "company") {
246
+ return 190;
247
+ }
248
+ if (t === "deals" || t === "deal") {
249
+ return 214;
250
+ }
251
+ throw new Error(`HubSpot: unsupported note association object type: ${associateToObjectType}`);
252
+ }
253
+ export const hubspot = new Hubspot();
254
+ //# sourceMappingURL=hubspot.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hubspot.js","sourceRoot":"","sources":["../../src/crms/hubspot.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,15 @@
1
+ import { Hubspot } from "./crms/hubspot/hubspot";
2
+ import type { HubspotInit } from "./crms/hubspot/types";
3
+ export declare const CRMs: readonly ["hubspot"];
4
+ export type CRMName = (typeof CRMs)[number];
5
+ export type CRMInitMap = {
6
+ hubspot: HubspotInit;
7
+ };
8
+ export type CRMInstanceMap = {
9
+ hubspot: Hubspot;
10
+ };
11
+ export type CRMArgPairs = {
12
+ [K in keyof CRMInitMap]: [K, CRMInitMap[K]];
13
+ }[keyof CRMInitMap];
14
+ export declare function getCRM<N extends CRMName>(name: N, init: CRMInitMap[N]): CRMInstanceMap[N];
15
+ //# sourceMappingURL=getCRM.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"getCRM.d.ts","sourceRoot":"","sources":["../src/getCRM.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,wBAAwB,CAAA;AAChD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAA;AAEvD,eAAO,MAAM,IAAI,sBAAuB,CAAA;AACxC,MAAM,MAAM,OAAO,GAAG,CAAC,OAAO,IAAI,CAAC,CAAC,MAAM,CAAC,CAAA;AAE3C,MAAM,MAAM,UAAU,GAAG;IACxB,OAAO,EAAE,WAAW,CAAA;CACpB,CAAA;AAED,MAAM,MAAM,cAAc,GAAG;IAC5B,OAAO,EAAE,OAAO,CAAA;CAChB,CAAA;AAED,MAAM,MAAM,WAAW,GAAG;KACxB,CAAC,IAAI,MAAM,UAAU,GAAG,CAAC,CAAC,EAAE,UAAU,CAAC,CAAC,CAAC,CAAC;CAC3C,CAAC,MAAM,UAAU,CAAC,CAAA;AAEnB,wBAAgB,MAAM,CAAC,CAAC,SAAS,OAAO,EAAE,IAAI,EAAE,CAAC,EAAE,IAAI,EAAE,UAAU,CAAC,CAAC,CAAC,GAAG,cAAc,CAAC,CAAC,CAAC,CASzF"}
package/dist/getCRM.js ADDED
@@ -0,0 +1,13 @@
1
+ import { Hubspot } from "./crms/hubspot/hubspot";
2
+ export const CRMs = ["hubspot"];
3
+ export function getCRM(name, init) {
4
+ const crm = name;
5
+ switch (crm) {
6
+ case "hubspot":
7
+ return new Hubspot(init);
8
+ default:
9
+ crm;
10
+ throw new Error(`Unknown CRM: ${String(crm)}`);
11
+ }
12
+ }
13
+ //# sourceMappingURL=getCRM.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"getCRM.js","sourceRoot":"","sources":["../src/getCRM.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,wBAAwB,CAAA;AAGhD,MAAM,CAAC,MAAM,IAAI,GAAG,CAAC,SAAS,CAAU,CAAA;AAexC,MAAM,UAAU,MAAM,CAAoB,IAAO,EAAE,IAAmB;IACrE,MAAM,GAAG,GAAY,IAAI,CAAA;IACzB,QAAQ,GAAG,EAAE,CAAC;QACb,KAAK,SAAS;YACb,OAAO,IAAI,OAAO,CAAC,IAAI,CAAsB,CAAA;QAC9C;YACC,GAAmB,CAAA;YACnB,MAAM,IAAI,KAAK,CAAC,gBAAgB,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,CAAA;IAChD,CAAC;AACF,CAAC"}
@@ -0,0 +1,8 @@
1
+ export { default as CRM } from "./CRM";
2
+ export { default as CrmConnection } from "./CrmConnection";
3
+ export * from "./types";
4
+ export * from "./oauth-helpers";
5
+ export { Hubspot, HubspotConnection } from "./crms/hubspot/hubspot";
6
+ export type { HubspotInit } from "./crms/hubspot/types";
7
+ export * from "./getCRM";
8
+ //# 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,OAAO,IAAI,GAAG,EAAE,MAAM,OAAO,CAAA;AACtC,OAAO,EAAE,OAAO,IAAI,aAAa,EAAE,MAAM,iBAAiB,CAAA;AAC1D,cAAc,SAAS,CAAA;AACvB,cAAc,iBAAiB,CAAA;AAC/B,OAAO,EAAE,OAAO,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAA;AACnE,YAAY,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAA;AACvD,cAAc,UAAU,CAAA"}
package/dist/index.js ADDED
@@ -0,0 +1,7 @@
1
+ export { default as CRM } from "./CRM";
2
+ export { default as CrmConnection } from "./CrmConnection";
3
+ export * from "./types";
4
+ export * from "./oauth-helpers";
5
+ export { Hubspot, HubspotConnection } from "./crms/hubspot/hubspot";
6
+ export * from "./getCRM";
7
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,IAAI,GAAG,EAAE,MAAM,OAAO,CAAA;AACtC,OAAO,EAAE,OAAO,IAAI,aAAa,EAAE,MAAM,iBAAiB,CAAA;AAC1D,cAAc,SAAS,CAAA;AACvB,cAAc,iBAAiB,CAAA;AAC/B,OAAO,EAAE,OAAO,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAA;AAEnE,cAAc,UAAU,CAAA"}
@@ -0,0 +1,5 @@
1
+ export declare function randomState(byteLength?: number): string;
2
+ export declare function buildQueryString(params: Record<string, string>): string;
3
+ export declare function postFormUrlEncoded(url: string, body: Record<string, string>): Promise<Response>;
4
+ export declare function toExpiresAt(expiresInSeconds: number | undefined): Date | null;
5
+ //# sourceMappingURL=oauth-helpers.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"oauth-helpers.d.ts","sourceRoot":"","sources":["../src/oauth-helpers.ts"],"names":[],"mappings":"AAEA,wBAAgB,WAAW,CAAC,UAAU,GAAE,MAAW,GAAG,MAAM,CAE3D;AAED,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,MAAM,CAEvE;AAED,wBAAsB,kBAAkB,CACpC,GAAG,EAAE,MAAM,EACX,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAC7B,OAAO,CAAC,QAAQ,CAAC,CAMnB;AAED,wBAAgB,WAAW,CAAC,gBAAgB,EAAE,MAAM,GAAG,SAAS,GAAG,IAAI,GAAG,IAAI,CAK7E"}
@@ -0,0 +1,21 @@
1
+ import { randomBytes } from "node:crypto";
2
+ export function randomState(byteLength = 32) {
3
+ return randomBytes(byteLength).toString("hex");
4
+ }
5
+ export function buildQueryString(params) {
6
+ return new URLSearchParams(params).toString();
7
+ }
8
+ export async function postFormUrlEncoded(url, body) {
9
+ return fetch(url, {
10
+ method: "POST",
11
+ headers: { "Content-Type": "application/x-www-form-urlencoded" },
12
+ body: new URLSearchParams(body),
13
+ });
14
+ }
15
+ export function toExpiresAt(expiresInSeconds) {
16
+ if (typeof expiresInSeconds !== "number" || !Number.isFinite(expiresInSeconds)) {
17
+ return null;
18
+ }
19
+ return new Date(Date.now() + expiresInSeconds * 1000);
20
+ }
21
+ //# sourceMappingURL=oauth-helpers.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"oauth-helpers.js","sourceRoot":"","sources":["../src/oauth-helpers.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAA;AAEzC,MAAM,UAAU,WAAW,CAAC,aAAqB,EAAE;IAC/C,OAAO,WAAW,CAAC,UAAU,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAA;AAClD,CAAC;AAED,MAAM,UAAU,gBAAgB,CAAC,MAA8B;IAC3D,OAAO,IAAI,eAAe,CAAC,MAAM,CAAC,CAAC,QAAQ,EAAE,CAAA;AACjD,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,kBAAkB,CACpC,GAAW,EACX,IAA4B;IAE5B,OAAO,KAAK,CAAC,GAAG,EAAE;QACd,MAAM,EAAE,MAAM;QACd,OAAO,EAAE,EAAE,cAAc,EAAE,mCAAmC,EAAE;QAChE,IAAI,EAAE,IAAI,eAAe,CAAC,IAAI,CAAC;KAClC,CAAC,CAAA;AACN,CAAC;AAED,MAAM,UAAU,WAAW,CAAC,gBAAoC;IAC5D,IAAI,OAAO,gBAAgB,KAAK,QAAQ,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,gBAAgB,CAAC,EAAE,CAAC;QAC7E,OAAO,IAAI,CAAA;IACf,CAAC;IACD,OAAO,IAAI,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,gBAAgB,GAAG,IAAI,CAAC,CAAA;AACzD,CAAC"}
@@ -0,0 +1,24 @@
1
+ /**
2
+ * Flacher Record für OAuth/Tokens — ohne Generics.
3
+ * Felder je nach Phase optional; Callbacks/Returns nutzen dasselbe Shape.
4
+ */
5
+ export interface TokenStore {
6
+ /**
7
+ * von dir erfundener code zur wiederfindung des aktuellen users per oauth
8
+ */
9
+ state?: string;
10
+ /**
11
+ * die ID des users von seiner crm, wird bei jedem call der crm an meine app mitgeschickt
12
+ */
13
+ provider_account_id?: string;
14
+ /**
15
+ * die supabase-id
16
+ */
17
+ id?: string;
18
+ provider?: "hubspot" | string & {};
19
+ token_last_refreshed_at?: string | Date;
20
+ token_expires_at?: string | Date | null;
21
+ access_token?: string;
22
+ refresh_token?: string | null;
23
+ }
24
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,MAAM,WAAW,UAAU;IACvB;;OAEG;IACH,KAAK,CAAC,EAAE,MAAM,CAAA;IACd;;OAEG;IACH,mBAAmB,CAAC,EAAE,MAAM,CAAA;IAC5B;;OAEG;IACH,EAAE,CAAC,EAAE,MAAM,CAAA;IACX,QAAQ,CAAC,EAAE,SAAS,GAAG,MAAM,GAAG,EAAE,CAAA;IAClC,uBAAuB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IACvC,gBAAgB,CAAC,EAAE,MAAM,GAAG,IAAI,GAAG,IAAI,CAAA;IACvC,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,aAAa,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;CAChC"}
package/dist/types.js ADDED
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":""}
package/package.json ADDED
@@ -0,0 +1,26 @@
1
+ {
2
+ "name": "@delofarag/crm-utils",
3
+ "version": "0.2.0",
4
+ "type": "module",
5
+ "main": "./dist/index.js",
6
+ "types": "./dist/index.d.ts",
7
+ "exports": {
8
+ ".": {
9
+ "types": "./dist/index.d.ts",
10
+ "default": "./dist/index.js"
11
+ }
12
+ },
13
+ "files": [
14
+ "dist"
15
+ ],
16
+ "dependencies": {
17
+ "zod": "^3.25.76"
18
+ },
19
+ "devDependencies": {
20
+ "@types/node": "^20.0.0",
21
+ "typescript": "^5.0.0"
22
+ },
23
+ "scripts": {
24
+ "build": "tsc"
25
+ }
26
+ }