create-dovite 2.0.0 → 2.0.1
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/package.json +3 -2
- package/src/files.js +72 -0
- package/src/prompts.js +49 -0
- package/src/setup.js +106 -0
- package/templates/react-js/jsconfig.json +7 -0
- package/templates/react-js/public/manifest.json +12 -0
- package/templates/react-js/public/thumbnail.png +0 -0
- package/templates/react-js/src/API/currentUserContext.jsx +56 -0
- package/templates/react-js/src/API/dataApi.js +235 -0
- package/templates/react-js/src/API/domoAPI.js +311 -0
- package/templates/react-js/src/App.jsx +13 -0
- package/templates/react-js/src/index.css +1 -0
- package/templates/react-js/vite.config.js +40 -0
- package/templates/react-ts/public/manifest.json +12 -0
- package/templates/react-ts/public/thumbnail.png +0 -0
- package/templates/react-ts/src/API/currentUserContext.tsx +66 -0
- package/templates/react-ts/src/API/dataApi.ts +338 -0
- package/templates/react-ts/src/API/domoAPI.ts +355 -0
- package/templates/react-ts/src/App.tsx +13 -0
- package/templates/react-ts/src/index.css +1 -0
- package/templates/react-ts/tsconfig.app.json +31 -0
- package/templates/react-ts/tsconfig.json +17 -0
- package/templates/react-ts/vite.config.ts +47 -0
|
@@ -0,0 +1,338 @@
|
|
|
1
|
+
import domo from "ryuu.js";
|
|
2
|
+
import axios from "axios";
|
|
3
|
+
|
|
4
|
+
// --- Type Definitions ---
|
|
5
|
+
|
|
6
|
+
// Quick module declaration for ryuu.js if missing types
|
|
7
|
+
declare module "ryuu.js" {
|
|
8
|
+
export function get(path: string): Promise<unknown>;
|
|
9
|
+
export function post(
|
|
10
|
+
path: string,
|
|
11
|
+
body: unknown,
|
|
12
|
+
options?: unknown
|
|
13
|
+
): Promise<unknown>;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
interface DomoSqlResponse {
|
|
17
|
+
columns: string[];
|
|
18
|
+
rows: unknown[][];
|
|
19
|
+
metadata?: unknown;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
interface AIResponse {
|
|
23
|
+
output?: string;
|
|
24
|
+
choices?: Array<{ output: string }>;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
interface EmailAttachment {
|
|
28
|
+
filename: string;
|
|
29
|
+
contentType: string;
|
|
30
|
+
base64: string;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
interface DomoUser {
|
|
34
|
+
id: number;
|
|
35
|
+
email: string;
|
|
36
|
+
role: string;
|
|
37
|
+
[key: string]: unknown;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
interface DomoDataset {
|
|
41
|
+
id: string;
|
|
42
|
+
name: string;
|
|
43
|
+
rows: number;
|
|
44
|
+
columns: number;
|
|
45
|
+
[key: string]: unknown;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
// --- API Functions ---
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* Fetches generated text from the Domo AI service.
|
|
52
|
+
*/
|
|
53
|
+
export async function fetchAIData(
|
|
54
|
+
prompt: string,
|
|
55
|
+
template?: string,
|
|
56
|
+
maxWords?: number | string
|
|
57
|
+
): Promise<string | null> {
|
|
58
|
+
try {
|
|
59
|
+
// Validate the required "prompt" parameter
|
|
60
|
+
if (!prompt || typeof prompt !== "string") {
|
|
61
|
+
throw new Error(
|
|
62
|
+
"The 'prompt' parameter is required and must be a string."
|
|
63
|
+
);
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
// Construct the body dynamically
|
|
67
|
+
const body: Record<string, unknown> = {
|
|
68
|
+
input: prompt,
|
|
69
|
+
};
|
|
70
|
+
|
|
71
|
+
if (template && typeof template === "string") {
|
|
72
|
+
body.promptTemplate = { template };
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
if (maxWords && !isNaN(Number(maxWords))) {
|
|
76
|
+
body.parameters = { max_words: maxWords.toString() };
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
// Send the POST request
|
|
80
|
+
const response = (await domo.post(
|
|
81
|
+
`/domo/ai/v1/text/generation`,
|
|
82
|
+
body
|
|
83
|
+
)) as AIResponse;
|
|
84
|
+
|
|
85
|
+
// console.log("AI Response:", response);
|
|
86
|
+
|
|
87
|
+
if (response?.output) {
|
|
88
|
+
return response.output;
|
|
89
|
+
}
|
|
90
|
+
if (response?.choices?.[0]?.output) {
|
|
91
|
+
return response.choices[0].output;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
return null;
|
|
95
|
+
} catch (error) {
|
|
96
|
+
console.error("Error fetching AI data:", error);
|
|
97
|
+
throw error;
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
/**
|
|
102
|
+
* Simple fetch for a dataset.
|
|
103
|
+
*/
|
|
104
|
+
export async function fetchData(dataset: string): Promise<unknown> {
|
|
105
|
+
try {
|
|
106
|
+
const response = await domo.get(`/data/v1/${dataset}`);
|
|
107
|
+
return response;
|
|
108
|
+
} catch (error) {
|
|
109
|
+
console.error(`Error fetching dataset ${dataset}:`, error);
|
|
110
|
+
throw error;
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
/**
|
|
115
|
+
* Executes a SQL query against a Domo dataset and returns a mapped JSON array.
|
|
116
|
+
* @template T - The expected shape of the row data.
|
|
117
|
+
*/
|
|
118
|
+
export async function fetchSqlData<T = Record<string, unknown>>(
|
|
119
|
+
dataset: string,
|
|
120
|
+
query: string
|
|
121
|
+
): Promise<T[]> {
|
|
122
|
+
// Ensure the query is a string
|
|
123
|
+
if (typeof query !== "string") {
|
|
124
|
+
throw new Error("Query must be a string");
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
try {
|
|
128
|
+
// Fetch data from the API
|
|
129
|
+
const apiData = (await domo.post(`/sql/v1/${dataset}`, query, {
|
|
130
|
+
contentType: "text/plain",
|
|
131
|
+
})) as DomoSqlResponse;
|
|
132
|
+
|
|
133
|
+
// Validate the fetched data
|
|
134
|
+
if (
|
|
135
|
+
!apiData ||
|
|
136
|
+
!Array.isArray(apiData.columns) ||
|
|
137
|
+
!Array.isArray(apiData.rows)
|
|
138
|
+
) {
|
|
139
|
+
throw new Error("Invalid data received from the API");
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
// Extract and clean column names
|
|
143
|
+
const cleanedColumns = apiData.columns.map((column: string) => {
|
|
144
|
+
return column
|
|
145
|
+
.replace(/`/g, "")
|
|
146
|
+
.replace(/T1\./g, "")
|
|
147
|
+
.replace(/avg\((.*?)\)/i, "$1")
|
|
148
|
+
.trim();
|
|
149
|
+
});
|
|
150
|
+
|
|
151
|
+
// Map rows to cleaned column names
|
|
152
|
+
const jsonResult = apiData.rows.map((row: unknown[]) => {
|
|
153
|
+
const jsonObject: Record<string, unknown> = {};
|
|
154
|
+
cleanedColumns.forEach((cleanedColumn: string, index: number) => {
|
|
155
|
+
jsonObject[cleanedColumn] = row[index];
|
|
156
|
+
});
|
|
157
|
+
return jsonObject as T;
|
|
158
|
+
});
|
|
159
|
+
|
|
160
|
+
// console.log("Mapped SQL DATA", jsonResult);
|
|
161
|
+
return jsonResult;
|
|
162
|
+
} catch (error) {
|
|
163
|
+
console.error("Error fetching or processing SQL data:", error);
|
|
164
|
+
throw error;
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
/**
|
|
169
|
+
* Triggers a Domo Workflow email.
|
|
170
|
+
*/
|
|
171
|
+
export async function sendEmail(
|
|
172
|
+
to: string | string[],
|
|
173
|
+
subject: string,
|
|
174
|
+
body: string,
|
|
175
|
+
attachment?: EmailAttachment
|
|
176
|
+
): Promise<void> {
|
|
177
|
+
const data: Record<string, unknown> = {
|
|
178
|
+
to,
|
|
179
|
+
subject,
|
|
180
|
+
body,
|
|
181
|
+
};
|
|
182
|
+
|
|
183
|
+
if (attachment) {
|
|
184
|
+
data.attachment = [attachment];
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
try {
|
|
188
|
+
const response = await domo.post(
|
|
189
|
+
`/domo/workflow/v1/models/email/start`,
|
|
190
|
+
data
|
|
191
|
+
);
|
|
192
|
+
if (response) {
|
|
193
|
+
console.log("Email sent successfully:", response);
|
|
194
|
+
}
|
|
195
|
+
} catch (err) {
|
|
196
|
+
console.error("Error sending email:", err);
|
|
197
|
+
throw err;
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
/**
|
|
202
|
+
* Triggers a Dataflow action.
|
|
203
|
+
*/
|
|
204
|
+
export const DataflowsActions = async (
|
|
205
|
+
action: string,
|
|
206
|
+
dataflowId: string | number
|
|
207
|
+
): Promise<void> => {
|
|
208
|
+
const data = {
|
|
209
|
+
action,
|
|
210
|
+
dataflowId,
|
|
211
|
+
result: true,
|
|
212
|
+
};
|
|
213
|
+
|
|
214
|
+
try {
|
|
215
|
+
const response = await domo.post(
|
|
216
|
+
`/domo/workflow/v1/models/dataflow/start`,
|
|
217
|
+
data
|
|
218
|
+
);
|
|
219
|
+
if (response) {
|
|
220
|
+
console.log("Dataflow action response:", response);
|
|
221
|
+
}
|
|
222
|
+
} catch (err) {
|
|
223
|
+
console.error("Error triggering dataflow:", err);
|
|
224
|
+
throw err;
|
|
225
|
+
}
|
|
226
|
+
};
|
|
227
|
+
|
|
228
|
+
/**
|
|
229
|
+
* Generates an OAuth Access Token.
|
|
230
|
+
*/
|
|
231
|
+
export const generateAccessToken = async (
|
|
232
|
+
clientId: string,
|
|
233
|
+
clientSecret: string
|
|
234
|
+
): Promise<string> => {
|
|
235
|
+
if (!clientId || !clientSecret) {
|
|
236
|
+
throw new Error("Client ID and Secret are required to generate a token.");
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
const tokenUrl = "https://api.domo.com/oauth/token";
|
|
240
|
+
|
|
241
|
+
try {
|
|
242
|
+
const response = await axios.post<{ access_token: string }>(
|
|
243
|
+
tokenUrl,
|
|
244
|
+
new URLSearchParams({
|
|
245
|
+
grant_type: "client_credentials",
|
|
246
|
+
scope: "user",
|
|
247
|
+
}).toString(),
|
|
248
|
+
{
|
|
249
|
+
headers: {
|
|
250
|
+
"Content-Type": "application/x-www-form-urlencoded",
|
|
251
|
+
},
|
|
252
|
+
auth: {
|
|
253
|
+
username: clientId,
|
|
254
|
+
password: clientSecret,
|
|
255
|
+
},
|
|
256
|
+
}
|
|
257
|
+
);
|
|
258
|
+
|
|
259
|
+
// console.log("Access Token generated successfully");
|
|
260
|
+
return response.data.access_token;
|
|
261
|
+
} catch (err) {
|
|
262
|
+
console.error("Error generating access token:", err);
|
|
263
|
+
throw err;
|
|
264
|
+
}
|
|
265
|
+
};
|
|
266
|
+
|
|
267
|
+
// --- Admin/Management Functions ---
|
|
268
|
+
|
|
269
|
+
export const fetchUsers = async (
|
|
270
|
+
accessToken: string
|
|
271
|
+
): Promise<DomoUser[] | undefined> => {
|
|
272
|
+
if (!accessToken) {
|
|
273
|
+
console.error("Access token missing in fetchUsers");
|
|
274
|
+
return;
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
const userUrl = `https://api.domo.com/v1/users?limit=500`;
|
|
278
|
+
|
|
279
|
+
try {
|
|
280
|
+
const response = await axios.get<DomoUser[]>(userUrl, {
|
|
281
|
+
headers: {
|
|
282
|
+
Authorization: `Bearer ${accessToken}`,
|
|
283
|
+
},
|
|
284
|
+
});
|
|
285
|
+
console.log(`Fetched ${response.data.length} users`);
|
|
286
|
+
return response.data;
|
|
287
|
+
} catch (err) {
|
|
288
|
+
console.error("Error fetching User details:", err);
|
|
289
|
+
throw err;
|
|
290
|
+
}
|
|
291
|
+
};
|
|
292
|
+
|
|
293
|
+
export const fetchDatasets = async (
|
|
294
|
+
accessToken: string
|
|
295
|
+
): Promise<DomoDataset[] | undefined> => {
|
|
296
|
+
if (!accessToken) {
|
|
297
|
+
console.error("Access token missing in fetchDatasets");
|
|
298
|
+
return;
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
const datasetUrl = `https://api.domo.com/v1/datasets`;
|
|
302
|
+
|
|
303
|
+
try {
|
|
304
|
+
const response = await axios.get<DomoDataset[]>(datasetUrl, {
|
|
305
|
+
headers: {
|
|
306
|
+
Authorization: `Bearer ${accessToken}`,
|
|
307
|
+
},
|
|
308
|
+
});
|
|
309
|
+
return response.data;
|
|
310
|
+
} catch (err) {
|
|
311
|
+
console.error("Error fetching dataset details:", err);
|
|
312
|
+
throw err;
|
|
313
|
+
}
|
|
314
|
+
};
|
|
315
|
+
|
|
316
|
+
export const fetchDatasetDetails = async (
|
|
317
|
+
accessToken: string,
|
|
318
|
+
datasetId: string
|
|
319
|
+
): Promise<DomoDataset | undefined> => {
|
|
320
|
+
if (!accessToken) {
|
|
321
|
+
console.error("Access token missing in fetchDatasetDetails");
|
|
322
|
+
return;
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
const datasetUrl = `https://api.domo.com/v1/datasets/${datasetId}`;
|
|
326
|
+
|
|
327
|
+
try {
|
|
328
|
+
const response = await axios.get<DomoDataset>(datasetUrl, {
|
|
329
|
+
headers: {
|
|
330
|
+
Authorization: `Bearer ${accessToken}`,
|
|
331
|
+
},
|
|
332
|
+
});
|
|
333
|
+
return response.data;
|
|
334
|
+
} catch (err) {
|
|
335
|
+
console.error("Error fetching dataset details:", err);
|
|
336
|
+
throw err;
|
|
337
|
+
}
|
|
338
|
+
};
|
|
@@ -0,0 +1,355 @@
|
|
|
1
|
+
// @ts-ignore
|
|
2
|
+
import domo from "ryuu.js";
|
|
3
|
+
|
|
4
|
+
const BASE_URL = "/domo/datastores/v1";
|
|
5
|
+
|
|
6
|
+
export interface User {
|
|
7
|
+
userId: string;
|
|
8
|
+
userName: string;
|
|
9
|
+
displayName: string;
|
|
10
|
+
avatarKey?: string;
|
|
11
|
+
[key: string]: any;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export interface Document {
|
|
15
|
+
[key: string]: any;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export interface Aggregations {
|
|
19
|
+
groupby?: string[];
|
|
20
|
+
count?: string;
|
|
21
|
+
avg?: Record<string, string>;
|
|
22
|
+
min?: Record<string, string>;
|
|
23
|
+
max?: Record<string, string>;
|
|
24
|
+
sum?: Record<string, string>;
|
|
25
|
+
unwind?: string[];
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
export interface QueryOptions {
|
|
29
|
+
orderby?: string;
|
|
30
|
+
limit?: number;
|
|
31
|
+
offset?: number;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
const GetCurrentUser = (): Promise<User> => {
|
|
35
|
+
return domo
|
|
36
|
+
.get("/domo/environment/v1")
|
|
37
|
+
.then((user: any) => ({
|
|
38
|
+
...user,
|
|
39
|
+
displayName: user.userName,
|
|
40
|
+
avatarKey: `/domo/avatars/v2/USER/${user.userId}`,
|
|
41
|
+
}))
|
|
42
|
+
.catch((error: any) => {
|
|
43
|
+
console.error("Error getting current user:", error);
|
|
44
|
+
throw error;
|
|
45
|
+
});
|
|
46
|
+
};
|
|
47
|
+
|
|
48
|
+
const GetAllUser = (): Promise<any> => {
|
|
49
|
+
return domo
|
|
50
|
+
.get(`/domo/users/v1?limit={500}`)
|
|
51
|
+
.then((response: any) => response)
|
|
52
|
+
.catch((error: any) => {
|
|
53
|
+
console.error("Error getting All users:", error);
|
|
54
|
+
throw error;
|
|
55
|
+
});
|
|
56
|
+
};
|
|
57
|
+
|
|
58
|
+
const GetUser = (userId: string): Promise<User> => {
|
|
59
|
+
return domo
|
|
60
|
+
.get(`/domo/users/v1/${userId}?includeDetails=true`)
|
|
61
|
+
.then((user: any) => ({ ...user, userName: user.displayName }))
|
|
62
|
+
.catch((error: any) => {
|
|
63
|
+
console.error("Error getting user:", error);
|
|
64
|
+
throw error;
|
|
65
|
+
});
|
|
66
|
+
};
|
|
67
|
+
|
|
68
|
+
const CreateDocument = (
|
|
69
|
+
collectionName: string,
|
|
70
|
+
document: Document
|
|
71
|
+
): Promise<any> => {
|
|
72
|
+
console.log(document);
|
|
73
|
+
console.log(collectionName);
|
|
74
|
+
|
|
75
|
+
return domo
|
|
76
|
+
.post(`${BASE_URL}/collections/${collectionName}/documents/`, {
|
|
77
|
+
content: document,
|
|
78
|
+
})
|
|
79
|
+
.then((response: any) => response)
|
|
80
|
+
.catch((error: any) => {
|
|
81
|
+
console.error("Error creating document:", error);
|
|
82
|
+
throw error;
|
|
83
|
+
});
|
|
84
|
+
};
|
|
85
|
+
|
|
86
|
+
const ListDocuments = (collectionName: string): Promise<any> => {
|
|
87
|
+
return domo
|
|
88
|
+
.get(`${BASE_URL}/collections/${collectionName}/documents/`)
|
|
89
|
+
.then((response: any) => response)
|
|
90
|
+
.catch((error: any) => {
|
|
91
|
+
console.error("Error listing documents:", error);
|
|
92
|
+
throw error;
|
|
93
|
+
});
|
|
94
|
+
};
|
|
95
|
+
|
|
96
|
+
const GetDocument = (
|
|
97
|
+
collectionName: string,
|
|
98
|
+
documentId: string
|
|
99
|
+
): Promise<any> => {
|
|
100
|
+
return domo
|
|
101
|
+
.get(`${BASE_URL}/collections/${collectionName}/documents/${documentId}`)
|
|
102
|
+
.then((response: any) => response)
|
|
103
|
+
.catch((error: any) => {
|
|
104
|
+
console.error("Error getting document:", error);
|
|
105
|
+
throw error;
|
|
106
|
+
});
|
|
107
|
+
};
|
|
108
|
+
|
|
109
|
+
const UpdateDocument = (
|
|
110
|
+
collectionName: string,
|
|
111
|
+
documentId: string,
|
|
112
|
+
document: Document
|
|
113
|
+
): Promise<any> => {
|
|
114
|
+
return domo
|
|
115
|
+
.put(`${BASE_URL}/collections/${collectionName}/documents/${documentId}`, {
|
|
116
|
+
content: document,
|
|
117
|
+
})
|
|
118
|
+
.then((response: any) => response)
|
|
119
|
+
.catch((error: any) => {
|
|
120
|
+
console.error("Error updating document:", error);
|
|
121
|
+
throw error;
|
|
122
|
+
});
|
|
123
|
+
};
|
|
124
|
+
|
|
125
|
+
const queryDocumentsWithAggregations = (
|
|
126
|
+
collectionName: string,
|
|
127
|
+
query: any = {},
|
|
128
|
+
aggregations: Aggregations = {},
|
|
129
|
+
options: QueryOptions = {}
|
|
130
|
+
): Promise<any> => {
|
|
131
|
+
// Base URL for the query
|
|
132
|
+
let url = `${BASE_URL}/collections/${collectionName}/documents/query?`;
|
|
133
|
+
|
|
134
|
+
// Helper function to format aggregation parameters
|
|
135
|
+
const formatAggregationParams = (params: Record<string, string>) => {
|
|
136
|
+
return Object.entries(params)
|
|
137
|
+
.map(([property, alias]) => `${property} ${alias}`)
|
|
138
|
+
.join(", ");
|
|
139
|
+
};
|
|
140
|
+
|
|
141
|
+
// Append aggregation parameters to URL
|
|
142
|
+
if (aggregations.groupby) url += `groupby=${aggregations.groupby.join(",")}&`;
|
|
143
|
+
if (aggregations.count) url += `count=${aggregations.count}&`;
|
|
144
|
+
if (aggregations.avg)
|
|
145
|
+
url += `avg=${formatAggregationParams(aggregations.avg)}&`;
|
|
146
|
+
if (aggregations.min)
|
|
147
|
+
url += `min=${formatAggregationParams(aggregations.min)}&`;
|
|
148
|
+
if (aggregations.max)
|
|
149
|
+
url += `max=${formatAggregationParams(aggregations.max)}&`;
|
|
150
|
+
if (aggregations.sum)
|
|
151
|
+
url += `sum=${formatAggregationParams(aggregations.sum)}&`;
|
|
152
|
+
if (aggregations.unwind) url += `unwind=${aggregations.unwind.join(",")}&`;
|
|
153
|
+
|
|
154
|
+
// Append options to the URL
|
|
155
|
+
if (options.orderby) url += `orderby=${options.orderby}&`;
|
|
156
|
+
if (options.limit !== undefined) url += `limit=${options.limit}&`;
|
|
157
|
+
if (options.offset !== undefined) url += `offset=${options.offset}&`;
|
|
158
|
+
|
|
159
|
+
// Remove trailing "&" or "?" from the URL
|
|
160
|
+
url = url.replace(/[&?]$/, "");
|
|
161
|
+
|
|
162
|
+
return domo
|
|
163
|
+
.post(url, query)
|
|
164
|
+
.then((response: any) => {
|
|
165
|
+
console.log("Query successful:", response);
|
|
166
|
+
return response;
|
|
167
|
+
})
|
|
168
|
+
.catch((error: any) => {
|
|
169
|
+
console.error("Error querying documents with aggregations:", error);
|
|
170
|
+
throw error;
|
|
171
|
+
});
|
|
172
|
+
};
|
|
173
|
+
|
|
174
|
+
const DeleteDocument = (
|
|
175
|
+
collectionName: string,
|
|
176
|
+
documentId: string
|
|
177
|
+
): Promise<any> => {
|
|
178
|
+
return domo
|
|
179
|
+
.delete(`${BASE_URL}/collections/${collectionName}/documents/${documentId}`)
|
|
180
|
+
.then((response: any) => response.data)
|
|
181
|
+
.catch((error: any) => {
|
|
182
|
+
console.error("Error deleting document:", error);
|
|
183
|
+
throw error;
|
|
184
|
+
});
|
|
185
|
+
};
|
|
186
|
+
|
|
187
|
+
const QueryDocument = (
|
|
188
|
+
collectionName: string,
|
|
189
|
+
query: any = {},
|
|
190
|
+
options: QueryOptions = {}
|
|
191
|
+
): Promise<any> => {
|
|
192
|
+
// Base URL for querying documents
|
|
193
|
+
let url = `${BASE_URL}/collections/${collectionName}/documents/query?`;
|
|
194
|
+
|
|
195
|
+
// Append optional parameters to the URL
|
|
196
|
+
if (options.limit !== undefined) url += `limit=${options.limit}&`;
|
|
197
|
+
if (options.offset !== undefined) url += `offset=${options.offset}&`;
|
|
198
|
+
if (options.orderby) url += `orderby=${options.orderby}&`;
|
|
199
|
+
|
|
200
|
+
// Remove trailing "&" or "?" from the URL
|
|
201
|
+
url = url.replace(/[&?]$/, "");
|
|
202
|
+
|
|
203
|
+
return domo
|
|
204
|
+
.post(url, query)
|
|
205
|
+
.then((response: any) => {
|
|
206
|
+
// console.log("Query successful:", response);
|
|
207
|
+
return response;
|
|
208
|
+
})
|
|
209
|
+
.catch((error: any) => {
|
|
210
|
+
console.error("Error querying documents:", error);
|
|
211
|
+
throw error;
|
|
212
|
+
});
|
|
213
|
+
};
|
|
214
|
+
|
|
215
|
+
// Query documents based on a specific date range
|
|
216
|
+
const queryDocumentsByDate = (
|
|
217
|
+
collectionName: string,
|
|
218
|
+
dateString: string,
|
|
219
|
+
options: QueryOptions = {}
|
|
220
|
+
): Promise<any> => {
|
|
221
|
+
const query = {
|
|
222
|
+
createdOn: {
|
|
223
|
+
$lte: { $date: dateString },
|
|
224
|
+
},
|
|
225
|
+
};
|
|
226
|
+
return QueryDocument(collectionName, query, options);
|
|
227
|
+
};
|
|
228
|
+
|
|
229
|
+
const BulkDeleteDocuments = (
|
|
230
|
+
collectionName: string,
|
|
231
|
+
ids: string[]
|
|
232
|
+
): Promise<any> => {
|
|
233
|
+
return domo
|
|
234
|
+
.delete(
|
|
235
|
+
`${BASE_URL}/collections/${collectionName}/documents/bulk?ids=${ids}`
|
|
236
|
+
)
|
|
237
|
+
.then((response: any) => response)
|
|
238
|
+
.catch((error: any) => {
|
|
239
|
+
console.error("Error bulk deleting documents:", error);
|
|
240
|
+
throw error;
|
|
241
|
+
});
|
|
242
|
+
};
|
|
243
|
+
|
|
244
|
+
const UploadFile = (
|
|
245
|
+
file: File,
|
|
246
|
+
name: string,
|
|
247
|
+
description: string = "",
|
|
248
|
+
isPublic: boolean = false
|
|
249
|
+
): Promise<any> => {
|
|
250
|
+
const formData = new FormData();
|
|
251
|
+
formData.append("file", file);
|
|
252
|
+
const url = `/domo/data-files/v1?name=
|
|
253
|
+
${name}&description=${description}&public=${isPublic}`;
|
|
254
|
+
const options = { contentType: "multipart" };
|
|
255
|
+
return domo
|
|
256
|
+
.post(url, formData, options)
|
|
257
|
+
.then((response: any) => response)
|
|
258
|
+
.catch((err: any) => {
|
|
259
|
+
console.log(err);
|
|
260
|
+
throw err;
|
|
261
|
+
});
|
|
262
|
+
};
|
|
263
|
+
|
|
264
|
+
const UploadRevision = (file: File, fileId: string): Promise<any> => {
|
|
265
|
+
const formData = new FormData();
|
|
266
|
+
formData.append("file", file);
|
|
267
|
+
const url = `/domo/data-files/v1/${fileId}`;
|
|
268
|
+
const options = { contentType: "multipart" };
|
|
269
|
+
return domo
|
|
270
|
+
.put(url, formData, options)
|
|
271
|
+
.then((response: any) => response)
|
|
272
|
+
.catch((err: any) => {
|
|
273
|
+
console.log(err);
|
|
274
|
+
throw err;
|
|
275
|
+
});
|
|
276
|
+
};
|
|
277
|
+
|
|
278
|
+
const GetFile = (fileId: string, revisionId?: string): Promise<any> => {
|
|
279
|
+
const options: any = { responseType: "blob" };
|
|
280
|
+
const url = `/domo/data-files/v1/${fileId}${
|
|
281
|
+
revisionId ? `/revisions/${revisionId}` : ""
|
|
282
|
+
}`;
|
|
283
|
+
return domo
|
|
284
|
+
.get(url, options)
|
|
285
|
+
.then((data: any) => data)
|
|
286
|
+
.catch((err: any) => {
|
|
287
|
+
console.log(err);
|
|
288
|
+
throw err;
|
|
289
|
+
});
|
|
290
|
+
};
|
|
291
|
+
|
|
292
|
+
const ListAllUsers = async (
|
|
293
|
+
includeDetails: boolean = false,
|
|
294
|
+
limit: number = 100,
|
|
295
|
+
offset: number = 0
|
|
296
|
+
): Promise<any> => {
|
|
297
|
+
try {
|
|
298
|
+
const response = await domo.get(
|
|
299
|
+
`/domo/users/v1?includeDetails=${includeDetails}&limit=${limit}&offset=${offset}`
|
|
300
|
+
);
|
|
301
|
+
return response;
|
|
302
|
+
} catch (error) {
|
|
303
|
+
console.error("Error listing users:", error);
|
|
304
|
+
throw error;
|
|
305
|
+
}
|
|
306
|
+
};
|
|
307
|
+
|
|
308
|
+
const partialupdateDocument = (
|
|
309
|
+
collectionName: string,
|
|
310
|
+
query: any,
|
|
311
|
+
operation: any
|
|
312
|
+
): Promise<any> => {
|
|
313
|
+
const requestBody = {
|
|
314
|
+
query: query,
|
|
315
|
+
operation: operation,
|
|
316
|
+
};
|
|
317
|
+
|
|
318
|
+
console.log("Request body:", requestBody);
|
|
319
|
+
|
|
320
|
+
return domo
|
|
321
|
+
.put(
|
|
322
|
+
`${BASE_URL}/collections/${collectionName}/documents/update`,
|
|
323
|
+
requestBody
|
|
324
|
+
)
|
|
325
|
+
.then((response: any) => {
|
|
326
|
+
console.log("Document updated successfully:", response);
|
|
327
|
+
return response;
|
|
328
|
+
})
|
|
329
|
+
.catch((error: any) => {
|
|
330
|
+
console.error("Error updating document:", error);
|
|
331
|
+
throw error;
|
|
332
|
+
});
|
|
333
|
+
};
|
|
334
|
+
|
|
335
|
+
const DomoApi = {
|
|
336
|
+
GetCurrentUser,
|
|
337
|
+
GetAllUser,
|
|
338
|
+
GetUser,
|
|
339
|
+
CreateDocument,
|
|
340
|
+
ListDocuments,
|
|
341
|
+
DeleteDocument,
|
|
342
|
+
BulkDeleteDocuments,
|
|
343
|
+
GetDocument,
|
|
344
|
+
UpdateDocument,
|
|
345
|
+
QueryDocument,
|
|
346
|
+
queryDocumentsByDate,
|
|
347
|
+
UploadFile,
|
|
348
|
+
UploadRevision,
|
|
349
|
+
GetFile,
|
|
350
|
+
queryDocumentsWithAggregations,
|
|
351
|
+
ListAllUsers,
|
|
352
|
+
partialupdateDocument,
|
|
353
|
+
};
|
|
354
|
+
|
|
355
|
+
export default DomoApi;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { useState } from "react";
|
|
2
|
+
import { Button } from "./components/ui/button";
|
|
3
|
+
import "./App.css";
|
|
4
|
+
function App() {
|
|
5
|
+
const [count, setCount] = useState(0);
|
|
6
|
+
return (
|
|
7
|
+
<div className="App">
|
|
8
|
+
<Button onClick={() => setCount(count + 1)}>Count: {count}</Button>
|
|
9
|
+
</div>
|
|
10
|
+
);
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export default App;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
@import "tailwindcss";
|