@opsrev/acculynx-cli 1.3.0 → 1.5.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.js +72 -5
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -68,9 +68,26 @@ function createApiClient(config) {
|
|
|
68
68
|
}
|
|
69
69
|
return response.json();
|
|
70
70
|
}
|
|
71
|
+
async function doPostForm(path, body) {
|
|
72
|
+
const url = `${config.baseUrl}${path}`;
|
|
73
|
+
const { "Content-Type": _, ...formHeaders } = headers;
|
|
74
|
+
const response = await fetchWithRetry(url, {
|
|
75
|
+
method: "POST",
|
|
76
|
+
headers: formHeaders,
|
|
77
|
+
body
|
|
78
|
+
});
|
|
79
|
+
if (!response.ok) {
|
|
80
|
+
const text = await response.text();
|
|
81
|
+
throw new Error(
|
|
82
|
+
`API error (${response.status} ${response.statusText}): ${text}`
|
|
83
|
+
);
|
|
84
|
+
}
|
|
85
|
+
return response.json();
|
|
86
|
+
}
|
|
71
87
|
return {
|
|
72
88
|
get: doGet,
|
|
73
|
-
post: doPost
|
|
89
|
+
post: doPost,
|
|
90
|
+
postForm: doPostForm
|
|
74
91
|
};
|
|
75
92
|
}
|
|
76
93
|
|
|
@@ -82,6 +99,10 @@ function registerPingCommand(parentCmd, getClient2) {
|
|
|
82
99
|
});
|
|
83
100
|
}
|
|
84
101
|
|
|
102
|
+
// src/commands/jobs.ts
|
|
103
|
+
import { readFileSync } from "fs";
|
|
104
|
+
import { basename, extname } from "path";
|
|
105
|
+
|
|
85
106
|
// src/api-helpers.ts
|
|
86
107
|
var DEFAULT_PAGE_SIZE = 25;
|
|
87
108
|
var DEFAULT_LIMIT = 25;
|
|
@@ -125,9 +146,22 @@ async function readStdin(stream = process.stdin) {
|
|
|
125
146
|
}
|
|
126
147
|
|
|
127
148
|
// src/commands/jobs.ts
|
|
149
|
+
var DISALLOWED_EXTENSIONS = /* @__PURE__ */ new Set([
|
|
150
|
+
".exe",
|
|
151
|
+
".com",
|
|
152
|
+
".dll",
|
|
153
|
+
".msi",
|
|
154
|
+
".bat",
|
|
155
|
+
".cmd",
|
|
156
|
+
".sh",
|
|
157
|
+
".pl",
|
|
158
|
+
".vbs",
|
|
159
|
+
".py",
|
|
160
|
+
".php"
|
|
161
|
+
]);
|
|
128
162
|
function registerJobsCommands(parentCmd, getClient2) {
|
|
129
163
|
const jobs = parentCmd.command("jobs").description("Job operations");
|
|
130
|
-
jobs.command("list").description("List jobs (paginated)").option("--start-date <date>", "Start date (YYYY-MM-DD)").option("--end-date <date>", "End date (YYYY-MM-DD)").option("--date-filter-type <type>", "Date field to filter on").option("--milestones <milestones>", "Filter by milestones").option("--sort-by <field>", "Sort by: CreatedDate, MilestoneDate, ModifiedDate").option("--sort-order <order>", "Ascending or Descending").option("--includes <fields>", "Include: contact, initialAppointment").option("--limit <n>", "Max total results (default: 25)").option("--all", "Fetch all results (no limit)").action(async (opts) => {
|
|
164
|
+
jobs.command("list").description("List jobs (paginated)").option("--start-date <date>", "Start date (YYYY-MM-DD)").option("--end-date <date>", "End date (YYYY-MM-DD)").option("--date-filter-type <type>", "Date field to filter on").option("--milestones <milestones>", "Filter by milestones").option("--sort-by <field>", "Sort by: CreatedDate, MilestoneDate, ModifiedDate").option("--sort-order <order>", "Ascending or Descending").option("--includes <fields>", "Include: contact, initialAppointment").option("--assignment <type>", "Filter by assignment: assigned, unassigned").option("--limit <n>", "Max total results (default: 25)").option("--all", "Fetch all results (no limit)").action(async (opts) => {
|
|
131
165
|
const params = {};
|
|
132
166
|
if (opts.startDate) params.startDate = opts.startDate;
|
|
133
167
|
if (opts.endDate) params.endDate = opts.endDate;
|
|
@@ -136,6 +170,7 @@ function registerJobsCommands(parentCmd, getClient2) {
|
|
|
136
170
|
if (opts.sortBy) params.sortBy = opts.sortBy;
|
|
137
171
|
if (opts.sortOrder) params.sortOrder = opts.sortOrder;
|
|
138
172
|
if (opts.includes) params.includes = opts.includes;
|
|
173
|
+
if (opts.assignment) params.assignment = opts.assignment;
|
|
139
174
|
const limit = opts.all ? Infinity : opts.limit ? parseInt(opts.limit, 10) : void 0;
|
|
140
175
|
const result = await paginate(getClient2(), "/jobs", params, limit);
|
|
141
176
|
console.log(JSON.stringify(result));
|
|
@@ -170,6 +205,38 @@ function registerJobsCommands(parentCmd, getClient2) {
|
|
|
170
205
|
console.log(JSON.stringify(result));
|
|
171
206
|
});
|
|
172
207
|
}
|
|
208
|
+
jobs.command("document-folders").description("List document folders for the company").option("--page-size <n>", "Number of items per page").option("--record-start-index <n>", "Index of first element to return", "0").option("--sort-order <order>", "Ascending or Descending", "Ascending").action(async (opts) => {
|
|
209
|
+
const params = {
|
|
210
|
+
recordStartIndex: opts.recordStartIndex,
|
|
211
|
+
sortOrder: opts.sortOrder
|
|
212
|
+
};
|
|
213
|
+
if (opts.pageSize) params.pageSize = opts.pageSize;
|
|
214
|
+
const result = await getClient2().get(
|
|
215
|
+
"/company-settings/job-file-settings/document-folders",
|
|
216
|
+
params
|
|
217
|
+
);
|
|
218
|
+
console.log(JSON.stringify(result));
|
|
219
|
+
});
|
|
220
|
+
jobs.command("upload-document").argument("<jobId>", "Job ID").argument("<filePath>", "Path to the file to upload").requiredOption("--folder-id <id>", "Document folder ID (required)").option("--description <text>", "Brief description of the file").option("--external-id <id>", "External reference identifier").option("--external-source <source>", "External reference source").description("Upload a document to a job").action(async (jobId, filePath, opts) => {
|
|
221
|
+
const ext = extname(filePath).toLowerCase();
|
|
222
|
+
if (DISALLOWED_EXTENSIONS.has(ext)) {
|
|
223
|
+
throw new Error(`File type ${ext} is not allowed`);
|
|
224
|
+
}
|
|
225
|
+
const fileBuffer = readFileSync(filePath);
|
|
226
|
+
const fileName = basename(filePath);
|
|
227
|
+
const file = new File([fileBuffer], fileName);
|
|
228
|
+
const form = new FormData();
|
|
229
|
+
form.append("file", file);
|
|
230
|
+
form.append("documentFolderId", opts.folderId);
|
|
231
|
+
if (opts.description) form.append("description", opts.description);
|
|
232
|
+
if (opts.externalId) form.append("externalId", opts.externalId);
|
|
233
|
+
if (opts.externalSource) form.append("externalSource", opts.externalSource);
|
|
234
|
+
const result = await getClient2().postForm(
|
|
235
|
+
`/jobs/${jobId}/documents`,
|
|
236
|
+
form
|
|
237
|
+
);
|
|
238
|
+
console.log(JSON.stringify(result));
|
|
239
|
+
});
|
|
173
240
|
}
|
|
174
241
|
|
|
175
242
|
// src/commands/contacts.ts
|
|
@@ -236,7 +303,7 @@ function registerEstimatesCommands(parentCmd, getClient2) {
|
|
|
236
303
|
// src/unofficial/session-store.ts
|
|
237
304
|
import {
|
|
238
305
|
existsSync,
|
|
239
|
-
readFileSync,
|
|
306
|
+
readFileSync as readFileSync2,
|
|
240
307
|
writeFileSync,
|
|
241
308
|
mkdirSync,
|
|
242
309
|
readdirSync,
|
|
@@ -314,7 +381,7 @@ function loadSession(email, companyId) {
|
|
|
314
381
|
const file = join(SESSIONS_DIR, sessionKey(email, companyId));
|
|
315
382
|
if (!existsSync(file)) return null;
|
|
316
383
|
try {
|
|
317
|
-
const data = JSON.parse(
|
|
384
|
+
const data = JSON.parse(readFileSync2(file, "utf-8"));
|
|
318
385
|
return {
|
|
319
386
|
jar: CookieJar.fromJSON(data.cookies),
|
|
320
387
|
companyId: data.companyId,
|
|
@@ -351,7 +418,7 @@ function listSessions() {
|
|
|
351
418
|
return readdirSync(SESSIONS_DIR).filter((f) => f.endsWith(".json")).map((f) => {
|
|
352
419
|
try {
|
|
353
420
|
const data = JSON.parse(
|
|
354
|
-
|
|
421
|
+
readFileSync2(join(SESSIONS_DIR, f), "utf-8")
|
|
355
422
|
);
|
|
356
423
|
return { email: data.email, companyId: data.companyId, file: f };
|
|
357
424
|
} catch {
|