fix(cli): batch record delete sends recordIds as query params

The API controller reads recordIds from @Query(), not @Body.
CLI was sending { records: ids } as JSON body, causing:
'expected array, received undefined at "recordIds"'

Fixed: rename deleteRecord→deleteRecords, send recordIds as
repeated query params (?recordIds=rec1&recordIds=rec2).
This commit is contained in:
yeuimu
2026-08-07 10:32:25 +00:00
parent 0891bda134
commit be21be9465
2 changed files with 90 additions and 24 deletions
+63 -16
View File
@@ -124,8 +124,9 @@ export class Client {
updateRecordOne(recordId: string, body: unknown) {
return this.call<unknown>('PATCH', `/api/record/${recordId}`, body);
}
deleteRecord(tableId: string, body: unknown) {
return this.call<unknown>('DELETE', `/api/table/${tableId}/record`, body);
deleteRecords(tableId: string, recordIds: string[]) {
const qs = recordIds.map((id) => `recordIds=${encodeURIComponent(id)}`).join('&');
return this.call<unknown>('DELETE', `/api/table/${tableId}/record?${qs}`);
}
// ---- view ----
@@ -163,23 +164,37 @@ export class Client {
createWorkflow(baseId: string, body: { name: string; description?: string }) {
return this.call<IWorkflowVo>('POST', `/api/base/${baseId}/workflow`, body);
}
updateWorkflow(baseId: string, workflowId: string, body: { name?: string; description?: string }) {
updateWorkflow(
baseId: string,
workflowId: string,
body: { name?: string; description?: string }
) {
return this.call<IWorkflowVo>('PATCH', `/api/base/${baseId}/workflow/${workflowId}`, body);
}
deleteWorkflow(baseId: string, workflowId: string) {
return this.call<unknown>('DELETE', `/api/base/${baseId}/workflow/${workflowId}`);
}
activateWorkflow(baseId: string, workflowId: string) {
return this.call<{ snapshotId: string }>('POST', `/api/base/${baseId}/workflow/${workflowId}/activate`);
return this.call<{ snapshotId: string }>(
'POST',
`/api/base/${baseId}/workflow/${workflowId}/activate`
);
}
deactivateWorkflow(baseId: string, workflowId: string) {
return this.call<unknown>('POST', `/api/base/${baseId}/workflow/${workflowId}/deactivate`);
}
testWorkflow(baseId: string, workflowId: string) {
return this.call<{ nodeResults: unknown[] }>('POST', `/api/base/${baseId}/workflow/${workflowId}/test`);
return this.call<{ nodeResults: unknown[] }>(
'POST',
`/api/base/${baseId}/workflow/${workflowId}/test`
);
}
/** PUT /node — whole-graph replacement (delete-all + create-all in a txn). */
replaceNodes(baseId: string, workflowId: string, body: { nodes: IWorkflowNodeVo[]; edges: IWorkflowEdgeVo[] }) {
replaceNodes(
baseId: string,
workflowId: string,
body: { nodes: IWorkflowNodeVo[]; edges: IWorkflowEdgeVo[] }
) {
return this.call<IWorkflowVo>('PUT', `/api/base/${baseId}/workflow/${workflowId}/node`, body);
}
@@ -187,14 +202,30 @@ export class Client {
listSecrets(baseId: string, workflowId: string) {
return this.call<unknown[]>('GET', `/api/base/${baseId}/workflow/${workflowId}/secret`);
}
createSecret(baseId: string, workflowId: string, body: { name: string; description?: string; value: string }) {
createSecret(
baseId: string,
workflowId: string,
body: { name: string; description?: string; value: string }
) {
return this.call<unknown>('POST', `/api/base/${baseId}/workflow/${workflowId}/secret`, body);
}
updateSecret(baseId: string, workflowId: string, secretId: string, body: { name?: string; description?: string; value?: string }) {
return this.call<unknown>('PATCH', `/api/base/${baseId}/workflow/${workflowId}/secret/${secretId}`, body);
updateSecret(
baseId: string,
workflowId: string,
secretId: string,
body: { name?: string; description?: string; value?: string }
) {
return this.call<unknown>(
'PATCH',
`/api/base/${baseId}/workflow/${workflowId}/secret/${secretId}`,
body
);
}
deleteSecret(baseId: string, workflowId: string, secretId: string) {
return this.call<unknown>('DELETE', `/api/base/${baseId}/workflow/${workflowId}/secret/${secretId}`);
return this.call<unknown>(
'DELETE',
`/api/base/${baseId}/workflow/${workflowId}/secret/${secretId}`
);
}
// ---- execution history ----
@@ -202,10 +233,16 @@ export class Client {
return this.call<unknown[]>('GET', `/api/base/${baseId}/workflow/${workflowId}/execution`);
}
getExecution(baseId: string, workflowId: string, executionId: string) {
return this.call<unknown>('GET', `/api/base/${baseId}/workflow/${workflowId}/execution/${executionId}`);
return this.call<unknown>(
'GET',
`/api/base/${baseId}/workflow/${workflowId}/execution/${executionId}`
);
}
rerunExecution(baseId: string, workflowId: string, executionId: string) {
return this.call<unknown>('POST', `/api/base/${baseId}/workflow/${workflowId}/execution/${executionId}/rerun`);
return this.call<unknown>(
'POST',
`/api/base/${baseId}/workflow/${workflowId}/execution/${executionId}/rerun`
);
}
// ---- trigger (manual fire for testing) ----
@@ -243,10 +280,20 @@ export class Client {
// ---- shared types (mirror backend workflow_node / workflow_edge shapes) ----
export type WorkflowNodeType = 'trigger' | 'action' | 'control';
export type WorkflowNodeCategory =
| 'recordCreated' | 'recordUpdated' | 'recordCondition' | 'recordCreatedOrUpdated'
| 'formSubmitted' | 'scheduledTime' | 'buttonClick' | 'webhook'
| 'script' | 'sendEmail' | 'httpRequest'
| 'createRecord' | 'updateRecord' | 'getRecords'
| 'recordCreated'
| 'recordUpdated'
| 'recordCondition'
| 'recordCreatedOrUpdated'
| 'formSubmitted'
| 'scheduledTime'
| 'buttonClick'
| 'webhook'
| 'script'
| 'sendEmail'
| 'httpRequest'
| 'createRecord'
| 'updateRecord'
| 'getRecords'
| 'triggerEnd';
export interface IWorkflowNodeVo {