@gaoding/cli 0.0.0 → 1.0.0-alpha.25
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/LICENSE +21 -0
- package/README.md +40 -3
- package/contracts/operations/agent.send/input.schema.json +353 -0
- package/contracts/operations/agent.send/output.schema.json +271 -0
- package/contracts/operations/auth.status/input.schema.json +7 -0
- package/contracts/operations/auth.status/output.schema.json +132 -0
- package/contracts/operations/dam.copy/input.schema.json +19 -0
- package/contracts/operations/dam.copy/output.schema.json +19 -0
- package/contracts/operations/dam.delete/input.schema.json +23 -0
- package/contracts/operations/dam.delete/output.schema.json +6 -0
- package/contracts/operations/dam.download/input.schema.json +14 -0
- package/contracts/operations/dam.download/output.schema.json +25 -0
- package/contracts/operations/dam.folder.list/input.schema.json +15 -0
- package/contracts/operations/dam.folder.list/output.schema.json +37 -0
- package/contracts/operations/dam.get/input.schema.json +16 -0
- package/contracts/operations/dam.get/output.schema.json +46 -0
- package/contracts/operations/dam.list/input.schema.json +44 -0
- package/contracts/operations/dam.list/output.schema.json +71 -0
- package/contracts/operations/dam.move/input.schema.json +19 -0
- package/contracts/operations/dam.move/output.schema.json +18 -0
- package/contracts/operations/dam.recycle.list/input.schema.json +13 -0
- package/contracts/operations/dam.recycle.list/output.schema.json +34 -0
- package/contracts/operations/dam.recycle.restore/input.schema.json +14 -0
- package/contracts/operations/dam.recycle.restore/output.schema.json +6 -0
- package/contracts/operations/dam.rename/input.schema.json +18 -0
- package/contracts/operations/dam.rename/output.schema.json +18 -0
- package/contracts/operations/dam.repository.list/input.schema.json +8 -0
- package/contracts/operations/dam.repository.list/output.schema.json +52 -0
- package/contracts/operations/dam.search/input.schema.json +46 -0
- package/contracts/operations/dam.search/output.schema.json +71 -0
- package/contracts/operations/dam.tag.list/input.schema.json +12 -0
- package/contracts/operations/dam.tag.list/output.schema.json +26 -0
- package/contracts/operations/dam.upload/input.schema.json +31 -0
- package/contracts/operations/dam.upload/output.schema.json +46 -0
- package/contracts/operations/editor.apply/input.schema.json +134 -0
- package/contracts/operations/editor.apply/output.schema.json +15 -0
- package/contracts/operations/editor.connect/input.schema.json +15 -0
- package/contracts/operations/editor.connect/output.schema.json +17 -0
- package/contracts/operations/editor.disconnect/input.schema.json +8 -0
- package/contracts/operations/editor.disconnect/output.schema.json +14 -0
- package/contracts/operations/editor.save/input.schema.json +8 -0
- package/contracts/operations/editor.save/output.schema.json +23 -0
- package/contracts/operations/editor.screenshot/input.schema.json +8 -0
- package/contracts/operations/editor.screenshot/output.schema.json +16 -0
- package/contracts/operations/editor.snapshot/input.schema.json +8 -0
- package/contracts/operations/editor.snapshot/output.schema.json +113 -0
- package/contracts/operations/model.get/input.schema.json +18 -0
- package/contracts/operations/model.get/output.schema.json +191 -0
- package/contracts/operations/model.list/input.schema.json +15 -0
- package/contracts/operations/model.list/output.schema.json +111 -0
- package/contracts/operations/org.current/input.schema.json +7 -0
- package/contracts/operations/org.current/output.schema.json +49 -0
- package/contracts/operations/org.list/input.schema.json +7 -0
- package/contracts/operations/org.list/output.schema.json +71 -0
- package/contracts/operations/tool.call/input.schema.json +35 -0
- package/contracts/operations/tool.call/output.schema.json +129 -0
- package/contracts/operations/tool.list/input.schema.json +7 -0
- package/contracts/operations/tool.list/output.schema.json +45 -0
- package/dist/bin/gd-cli.js +60 -0
- package/dist/bin/postinstall.js +42 -0
- package/dist/src/bootstrap/create-cli.js +112 -0
- package/dist/src/bootstrap/create-runtime.js +290 -0
- package/dist/src/bootstrap/validators.js +157 -0
- package/dist/src/cli/action-binding.js +109 -0
- package/dist/src/cli/agent-commands.js +49 -0
- package/dist/src/cli/auth-commands.js +55 -0
- package/dist/src/cli/dam-commands.js +469 -0
- package/dist/src/cli/editor-commands.js +73 -0
- package/dist/src/cli/errors.js +157 -0
- package/dist/src/cli/model-commands.js +61 -0
- package/dist/src/cli/org-commands.js +58 -0
- package/dist/src/cli/presenter.js +105 -0
- package/dist/src/cli/prompt.js +30 -0
- package/dist/src/cli/tool-commands.js +77 -0
- package/dist/src/cli/update-command.js +14 -0
- package/dist/src/contracts/schema.js +4 -0
- package/dist/src/features/agent/creative-agent-adapter.js +36 -0
- package/dist/src/features/agent/creative-protocol.js +432 -0
- package/dist/src/features/agent/creative-stream.js +127 -0
- package/dist/src/features/agent/use-cases.js +150 -0
- package/dist/src/features/auth/access-policy.js +101 -0
- package/dist/src/features/auth/credential-store.js +62 -0
- package/dist/src/features/auth/sso-service.js +194 -0
- package/dist/src/features/auth/state.js +129 -0
- package/dist/src/features/auth/use-cases.js +136 -0
- package/dist/src/features/dam/asset-projection.js +278 -0
- package/dist/src/features/dam/dam-api-adapter.js +562 -0
- package/dist/src/features/dam/file-downloader.js +242 -0
- package/dist/src/features/dam/object-storage.js +193 -0
- package/dist/src/features/dam/operation-executor.js +72 -0
- package/dist/src/features/dam/registered-uploader.js +247 -0
- package/dist/src/features/dam/repository-catalog.js +127 -0
- package/dist/src/features/dam/storage-upload.js +141 -0
- package/dist/src/features/dam/transient-uploader.js +17 -0
- package/dist/src/features/dam/use-cases.js +470 -0
- package/dist/src/features/editor/bridge-client.js +109 -0
- package/dist/src/features/editor/bridge-process.js +222 -0
- package/dist/src/features/editor/bridge-server.js +337 -0
- package/dist/src/features/editor/protocol.js +1 -0
- package/dist/src/features/editor/public-url.js +36 -0
- package/dist/src/features/editor/session-state.js +78 -0
- package/dist/src/features/editor/session.js +207 -0
- package/dist/src/features/editor/use-cases.js +88 -0
- package/dist/src/features/org/org-service.js +76 -0
- package/dist/src/features/org/use-cases.js +156 -0
- package/dist/src/features/skill/bundled-skills.js +55 -0
- package/dist/src/features/skill/installer.js +271 -0
- package/dist/src/features/tool/catalog.js +83 -0
- package/dist/src/features/tool/dynamic-schema.js +128 -0
- package/dist/src/features/tool/mns-catalog-adapter.js +265 -0
- package/dist/src/features/tool/tool-api-adapter.js +352 -0
- package/dist/src/features/tool/use-cases.js +177 -0
- package/dist/src/features/update/latest-version.js +37 -0
- package/dist/src/features/update/update-notification.js +262 -0
- package/dist/src/features/update/update-service.js +183 -0
- package/dist/src/platform/json-input.js +67 -0
- package/dist/src/platform/local-json-file.js +59 -0
- package/dist/src/platform/open-browser.js +8 -0
- package/dist/src/platform/redact.js +80 -0
- package/dist/src/platform/remote-error-evidence.js +80 -0
- package/dist/src/platform/remote-protocol.js +10 -0
- package/dist/src/platform/safe-upload-file.js +146 -0
- package/dist/src/platform/signature.js +20 -0
- package/dist/src/platform/signed-http-transport.js +143 -0
- package/dist/src/platform/url-safety.js +100 -0
- package/dist/src/telemetry/invocation.js +156 -0
- package/dist/src/telemetry/sls-sink.js +31 -0
- package/package.json +54 -8
- package/skills/gd-cli/SKILL.md +15 -0
- package/skills/gd-cli/references/auth-org.md +9 -0
- package/skills/gd-cli/references/creation.md +115 -0
- package/skills/gd-cli/references/dam.md +52 -0
- package/skills/gd-cli/references/editor.md +254 -0
- package/skills/gd-cli/references/errors.md +13 -0
- package/skills/gd-cli/references/update.md +13 -0
- package/index.js +0 -3
|
@@ -0,0 +1,562 @@
|
|
|
1
|
+
import { RemoteRequestError } from "../../platform/signed-http-transport.js";
|
|
2
|
+
import { RemoteProtocolError } from "../../platform/remote-protocol.js";
|
|
3
|
+
import { parseSafeRemoteAssetUrl, UrlSafetyError } from "../../platform/url-safety.js";
|
|
4
|
+
import { projectDamAssetDetail, projectDamAssetSummary } from "./asset-projection.js";
|
|
5
|
+
export class DamAssetNotFoundError extends Error {
|
|
6
|
+
constructor() {
|
|
7
|
+
super("DAM 素材不存在。");
|
|
8
|
+
this.name = "DamAssetNotFoundError";
|
|
9
|
+
}
|
|
10
|
+
}
|
|
11
|
+
export class DamAssetNotDownloadableError extends Error {
|
|
12
|
+
constructor() {
|
|
13
|
+
super("该 DAM 素材当前不可下载。");
|
|
14
|
+
this.name = "DamAssetNotDownloadableError";
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
export class DamFolderNotFoundError extends Error {
|
|
18
|
+
constructor() {
|
|
19
|
+
super("DAM 文件夹不存在。");
|
|
20
|
+
this.name = "DamFolderNotFoundError";
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
const contentFormats = {
|
|
24
|
+
image: ["gdpic", "gdimage"],
|
|
25
|
+
video: ["gdvideo"],
|
|
26
|
+
audio: ["gdaudio"],
|
|
27
|
+
font: ["gdfont"],
|
|
28
|
+
template: ["gdtemplate"],
|
|
29
|
+
file: ["gdfile", "gdimage", "gdslide"]
|
|
30
|
+
};
|
|
31
|
+
function record(value) {
|
|
32
|
+
return value !== null && typeof value === "object" && !Array.isArray(value)
|
|
33
|
+
? value
|
|
34
|
+
: undefined;
|
|
35
|
+
}
|
|
36
|
+
function nonblank(value) {
|
|
37
|
+
return typeof value === "string" && value.trim() !== "" ? value : undefined;
|
|
38
|
+
}
|
|
39
|
+
function finiteNumber(value) {
|
|
40
|
+
return typeof value === "number" && Number.isFinite(value) ? value : undefined;
|
|
41
|
+
}
|
|
42
|
+
function nonnegativeInteger(value) {
|
|
43
|
+
return typeof value === "number" && Number.isInteger(value) && value >= 0 ? value : 0;
|
|
44
|
+
}
|
|
45
|
+
const permissions = new Set(["OWNER", "MANAGE", "EDIT", "USE", "READ"]);
|
|
46
|
+
function folderPermission(value) {
|
|
47
|
+
return typeof value === "string"
|
|
48
|
+
&& permissions.has(value)
|
|
49
|
+
? value
|
|
50
|
+
: undefined;
|
|
51
|
+
}
|
|
52
|
+
function optionalString(value) {
|
|
53
|
+
if (value === undefined || value === null)
|
|
54
|
+
return undefined;
|
|
55
|
+
const projected = String(value);
|
|
56
|
+
return projected.trim() === "" ? undefined : projected;
|
|
57
|
+
}
|
|
58
|
+
function folderRows(value) {
|
|
59
|
+
if (!Array.isArray(value))
|
|
60
|
+
throw new RemoteProtocolError();
|
|
61
|
+
return value.flatMap((candidate) => {
|
|
62
|
+
const item = record(candidate);
|
|
63
|
+
const folderId = nonblank(item?.id);
|
|
64
|
+
const title = nonblank(item?.title);
|
|
65
|
+
const parentId = nonblank(item?.parent_id);
|
|
66
|
+
const repositoryId = nonblank(item?.repository_id);
|
|
67
|
+
if (folderId === undefined
|
|
68
|
+
|| title === undefined
|
|
69
|
+
|| parentId === undefined
|
|
70
|
+
|| repositoryId === undefined)
|
|
71
|
+
return [];
|
|
72
|
+
const permissionCode = folderPermission(item?.permission_code);
|
|
73
|
+
const path = nonblank(item?.path);
|
|
74
|
+
const createdAt = optionalString(item?.created_at);
|
|
75
|
+
const updatedAt = optionalString(item?.updated_at);
|
|
76
|
+
return [{
|
|
77
|
+
folder_id: folderId,
|
|
78
|
+
title,
|
|
79
|
+
parent_id: parentId,
|
|
80
|
+
repository_id: repositoryId,
|
|
81
|
+
...(permissionCode === undefined ? {} : { permission_code: permissionCode }),
|
|
82
|
+
child_folder_count: nonnegativeInteger(item?.child_folder_count),
|
|
83
|
+
asset_count: nonnegativeInteger(item?.content_count),
|
|
84
|
+
...(path === undefined ? {} : { path }),
|
|
85
|
+
...(createdAt === undefined ? {} : { created_at: createdAt }),
|
|
86
|
+
...(updatedAt === undefined ? {} : { updated_at: updatedAt })
|
|
87
|
+
}];
|
|
88
|
+
});
|
|
89
|
+
}
|
|
90
|
+
function folderPagination(headers) {
|
|
91
|
+
const raw = headers.get("x-pagination");
|
|
92
|
+
if (raw === null)
|
|
93
|
+
throw new RemoteProtocolError();
|
|
94
|
+
let value;
|
|
95
|
+
try {
|
|
96
|
+
value = JSON.parse(raw);
|
|
97
|
+
}
|
|
98
|
+
catch {
|
|
99
|
+
throw new RemoteProtocolError();
|
|
100
|
+
}
|
|
101
|
+
const pagination = record(value);
|
|
102
|
+
const page = pagination?.num;
|
|
103
|
+
const pageSize = pagination?.size;
|
|
104
|
+
const total = pagination?.total;
|
|
105
|
+
if (!Number.isInteger(page) || page < 1
|
|
106
|
+
|| !Number.isInteger(pageSize) || pageSize < 1 || pageSize > 100
|
|
107
|
+
|| !Number.isInteger(total) || total < 0) {
|
|
108
|
+
throw new RemoteProtocolError();
|
|
109
|
+
}
|
|
110
|
+
return { page: page, pageSize: pageSize, total: total };
|
|
111
|
+
}
|
|
112
|
+
function tagRows(value) {
|
|
113
|
+
if (!Array.isArray(value))
|
|
114
|
+
throw new RemoteProtocolError();
|
|
115
|
+
return value.flatMap((candidate) => {
|
|
116
|
+
const item = record(candidate);
|
|
117
|
+
const tagId = nonblank(item?.id);
|
|
118
|
+
const name = nonblank(item?.name);
|
|
119
|
+
if (tagId === undefined || name === undefined)
|
|
120
|
+
return [];
|
|
121
|
+
const groupId = nonblank(item?.group_id);
|
|
122
|
+
return [{
|
|
123
|
+
tag_id: tagId,
|
|
124
|
+
name,
|
|
125
|
+
...(groupId === undefined ? {} : { group_id: groupId }),
|
|
126
|
+
asset_count: nonnegativeInteger(item?.file_count)
|
|
127
|
+
}];
|
|
128
|
+
});
|
|
129
|
+
}
|
|
130
|
+
function downloadUrls(value) {
|
|
131
|
+
if (!Array.isArray(value) || value.some((item) => typeof item !== "string")) {
|
|
132
|
+
throw new RemoteProtocolError();
|
|
133
|
+
}
|
|
134
|
+
const urls = value.filter((item) => (typeof item === "string" && item.trim() !== ""));
|
|
135
|
+
if (urls.length === 0)
|
|
136
|
+
throw new DamAssetNotDownloadableError();
|
|
137
|
+
for (const value of urls) {
|
|
138
|
+
try {
|
|
139
|
+
const url = parseSafeRemoteAssetUrl(value);
|
|
140
|
+
if (url.protocol !== "https:")
|
|
141
|
+
throw new UrlSafetyError();
|
|
142
|
+
}
|
|
143
|
+
catch (error) {
|
|
144
|
+
if (error instanceof UrlSafetyError)
|
|
145
|
+
throw new RemoteProtocolError();
|
|
146
|
+
throw error;
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
return urls;
|
|
150
|
+
}
|
|
151
|
+
function folderDetail(response) {
|
|
152
|
+
for (const source of responseRecords(response).reverse()) {
|
|
153
|
+
const entryId = nonblank(source.id);
|
|
154
|
+
const title = nonblank(source.title);
|
|
155
|
+
const repositoryId = nonblank(source.repository_id);
|
|
156
|
+
const parentId = nonblank(source.parent_id);
|
|
157
|
+
if (entryId !== undefined
|
|
158
|
+
&& title !== undefined
|
|
159
|
+
&& repositoryId !== undefined
|
|
160
|
+
&& parentId !== undefined) {
|
|
161
|
+
return {
|
|
162
|
+
entry_id: entryId,
|
|
163
|
+
kind: "folder",
|
|
164
|
+
title,
|
|
165
|
+
repository_id: repositoryId,
|
|
166
|
+
folder_id: parentId
|
|
167
|
+
};
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
throw new RemoteProtocolError();
|
|
171
|
+
}
|
|
172
|
+
function operationSubmission(response) {
|
|
173
|
+
const root = record(response);
|
|
174
|
+
const source = record(root?.data) ?? root;
|
|
175
|
+
if (source === undefined)
|
|
176
|
+
throw new RemoteProtocolError();
|
|
177
|
+
const rawTaskId = source.task_id;
|
|
178
|
+
let taskId;
|
|
179
|
+
if (rawTaskId !== undefined && rawTaskId !== null) {
|
|
180
|
+
if (typeof rawTaskId === "number") {
|
|
181
|
+
if (!Number.isSafeInteger(rawTaskId) || rawTaskId < 0)
|
|
182
|
+
throw new RemoteProtocolError();
|
|
183
|
+
if (rawTaskId !== 0)
|
|
184
|
+
taskId = String(rawTaskId);
|
|
185
|
+
}
|
|
186
|
+
else if (typeof rawTaskId === "string" && rawTaskId.trim() !== "") {
|
|
187
|
+
if (rawTaskId.trim() !== "0")
|
|
188
|
+
taskId = rawTaskId.trim();
|
|
189
|
+
}
|
|
190
|
+
else {
|
|
191
|
+
throw new RemoteProtocolError();
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
const rawResultIds = source.result_ids;
|
|
195
|
+
if (rawResultIds !== undefined && !Array.isArray(rawResultIds)) {
|
|
196
|
+
throw new RemoteProtocolError();
|
|
197
|
+
}
|
|
198
|
+
const resultIds = Array.isArray(rawResultIds)
|
|
199
|
+
? rawResultIds.filter((item) => nonblank(item) !== undefined)
|
|
200
|
+
: [];
|
|
201
|
+
return {
|
|
202
|
+
...(taskId === undefined ? {} : { task_id: taskId }),
|
|
203
|
+
...(rawResultIds === undefined ? {} : { result_ids: resultIds })
|
|
204
|
+
};
|
|
205
|
+
}
|
|
206
|
+
function taskRows(response) {
|
|
207
|
+
if (Array.isArray(response))
|
|
208
|
+
return response;
|
|
209
|
+
const data = record(response)?.data;
|
|
210
|
+
if (Array.isArray(data))
|
|
211
|
+
return data;
|
|
212
|
+
throw new RemoteProtocolError();
|
|
213
|
+
}
|
|
214
|
+
function operationTask(response, taskId) {
|
|
215
|
+
const matches = taskRows(response).flatMap((candidate) => {
|
|
216
|
+
const item = record(candidate);
|
|
217
|
+
return nonblank(item?.id) === taskId ? [item] : [];
|
|
218
|
+
});
|
|
219
|
+
if (matches.length === 0)
|
|
220
|
+
return null;
|
|
221
|
+
if (matches.length !== 1)
|
|
222
|
+
throw new RemoteProtocolError();
|
|
223
|
+
const item = matches[0];
|
|
224
|
+
const status = item.status;
|
|
225
|
+
const progress = item.progress;
|
|
226
|
+
const totalCount = item.total_count;
|
|
227
|
+
const successCount = item.success_count;
|
|
228
|
+
const failCount = item.fail_count;
|
|
229
|
+
if (!Number.isInteger(status)
|
|
230
|
+
|| typeof progress !== "number" || !Number.isFinite(progress) || progress < 0
|
|
231
|
+
|| (totalCount !== null
|
|
232
|
+
&& (!Number.isInteger(totalCount) || totalCount < 0))
|
|
233
|
+
|| (successCount !== null
|
|
234
|
+
&& (!Number.isInteger(successCount) || successCount < 0))
|
|
235
|
+
|| (failCount !== null
|
|
236
|
+
&& (!Number.isInteger(failCount) || failCount < 0))) {
|
|
237
|
+
throw new RemoteProtocolError();
|
|
238
|
+
}
|
|
239
|
+
return {
|
|
240
|
+
id: taskId,
|
|
241
|
+
status: status,
|
|
242
|
+
progress,
|
|
243
|
+
total_count: totalCount,
|
|
244
|
+
success_count: successCount,
|
|
245
|
+
fail_count: failCount
|
|
246
|
+
};
|
|
247
|
+
}
|
|
248
|
+
function operationChildren(response) {
|
|
249
|
+
const root = record(response);
|
|
250
|
+
const source = record(root?.data) ?? root;
|
|
251
|
+
if (source === undefined)
|
|
252
|
+
throw new RemoteProtocolError();
|
|
253
|
+
const rawResultIds = source.result_ids;
|
|
254
|
+
if (rawResultIds !== undefined && !Array.isArray(rawResultIds)) {
|
|
255
|
+
throw new RemoteProtocolError();
|
|
256
|
+
}
|
|
257
|
+
const repositoryId = nonblank(source.repository_id);
|
|
258
|
+
const targetRepositoryId = nonblank(source.target_repository_id);
|
|
259
|
+
const targetParentId = nonblank(source.target_parent_id);
|
|
260
|
+
return {
|
|
261
|
+
result_ids: Array.isArray(rawResultIds)
|
|
262
|
+
? rawResultIds.filter((item) => nonblank(item) !== undefined)
|
|
263
|
+
: [],
|
|
264
|
+
...(repositoryId === undefined ? {} : { repository_id: repositoryId }),
|
|
265
|
+
...(targetRepositoryId === undefined ? {} : {
|
|
266
|
+
target_repository_id: targetRepositoryId
|
|
267
|
+
}),
|
|
268
|
+
...(targetParentId === undefined ? {} : { target_parent_id: targetParentId })
|
|
269
|
+
};
|
|
270
|
+
}
|
|
271
|
+
function assertSingleOperationInput(input) {
|
|
272
|
+
if (nonblank(input.entryId) === undefined
|
|
273
|
+
|| (input.kind !== "asset" && input.kind !== "folder")
|
|
274
|
+
|| (input.operation !== "move" && input.operation !== "copy")
|
|
275
|
+
|| nonblank(input.sourceRepositoryId) === undefined
|
|
276
|
+
|| nonblank(input.targetRepositoryId) === undefined
|
|
277
|
+
|| nonblank(input.targetFolderId) === undefined) {
|
|
278
|
+
throw new TypeError("Invalid DAM single-entry operation input.");
|
|
279
|
+
}
|
|
280
|
+
}
|
|
281
|
+
function assetId(response) {
|
|
282
|
+
const root = record(response);
|
|
283
|
+
const nested = record(root?.data);
|
|
284
|
+
const id = nonblank(root?.id) ?? nonblank(nested?.id);
|
|
285
|
+
if (id === undefined)
|
|
286
|
+
throw new RemoteRequestError();
|
|
287
|
+
return id;
|
|
288
|
+
}
|
|
289
|
+
function responseRecords(response) {
|
|
290
|
+
const root = record(response);
|
|
291
|
+
const nested = record(root?.data);
|
|
292
|
+
return [root, nested].filter((item) => item !== undefined);
|
|
293
|
+
}
|
|
294
|
+
function searchItems(response) {
|
|
295
|
+
if (Array.isArray(response))
|
|
296
|
+
return response;
|
|
297
|
+
for (const source of responseRecords(response)) {
|
|
298
|
+
for (const key of ["data", "list", "items"]) {
|
|
299
|
+
if (Array.isArray(source[key]))
|
|
300
|
+
return source[key];
|
|
301
|
+
}
|
|
302
|
+
}
|
|
303
|
+
return undefined;
|
|
304
|
+
}
|
|
305
|
+
function firstValue(response, keys) {
|
|
306
|
+
for (const source of responseRecords(response).reverse()) {
|
|
307
|
+
for (const key of keys) {
|
|
308
|
+
if (source[key] !== undefined)
|
|
309
|
+
return source[key];
|
|
310
|
+
}
|
|
311
|
+
}
|
|
312
|
+
return undefined;
|
|
313
|
+
}
|
|
314
|
+
function searchResult(response, input) {
|
|
315
|
+
const items = searchItems(response);
|
|
316
|
+
if (items === undefined)
|
|
317
|
+
throw new RemoteRequestError();
|
|
318
|
+
const assets = items.flatMap((item) => {
|
|
319
|
+
const asset = projectDamAssetSummary(item);
|
|
320
|
+
return asset === undefined ? [] : [asset];
|
|
321
|
+
});
|
|
322
|
+
const suppliedTotal = finiteNumber(firstValue(response, ["total", "count"]));
|
|
323
|
+
const total = suppliedTotal === undefined || suppliedTotal < 0 ? items.length : suppliedTotal;
|
|
324
|
+
const suppliedFinish = firstValue(response, ["finish"]);
|
|
325
|
+
const finish = typeof suppliedFinish === "boolean"
|
|
326
|
+
? suppliedFinish
|
|
327
|
+
: items.length >= total;
|
|
328
|
+
const cursor = nonblank(firstValue(response, ["query_id", "cursor"]));
|
|
329
|
+
return {
|
|
330
|
+
repository_ids: input.repositoryIds,
|
|
331
|
+
page_size: input.pageSize,
|
|
332
|
+
total,
|
|
333
|
+
finish,
|
|
334
|
+
...(!finish && cursor !== undefined ? { next_cursor: cursor } : {}),
|
|
335
|
+
assets
|
|
336
|
+
};
|
|
337
|
+
}
|
|
338
|
+
function requestContext(input) {
|
|
339
|
+
return {
|
|
340
|
+
credential: input.access.credential,
|
|
341
|
+
organizationId: input.access.organizationId,
|
|
342
|
+
signal: input.signal
|
|
343
|
+
};
|
|
344
|
+
}
|
|
345
|
+
function recycleBody(input) {
|
|
346
|
+
return {
|
|
347
|
+
repository_id: input.repositoryId,
|
|
348
|
+
file_ids: [input.assetId],
|
|
349
|
+
folder_ids: []
|
|
350
|
+
};
|
|
351
|
+
}
|
|
352
|
+
export function createDamApiAdapter(dependencies) {
|
|
353
|
+
return {
|
|
354
|
+
async search(input) {
|
|
355
|
+
const response = await dependencies.transport.postJson({
|
|
356
|
+
path: "/dam/asset/v2/search/simple",
|
|
357
|
+
body: {
|
|
358
|
+
keyword: input.keyword,
|
|
359
|
+
repository_ids: input.repositoryIds,
|
|
360
|
+
folder_ids: input.folderId === undefined ? [] : [input.folderId],
|
|
361
|
+
include_child_folder: input.includeChildFolder,
|
|
362
|
+
recycle: false,
|
|
363
|
+
page_size: input.pageSize,
|
|
364
|
+
sort: ["-top_time", "-updated_at"],
|
|
365
|
+
...(input.cursor === undefined
|
|
366
|
+
? {}
|
|
367
|
+
: { query_id: input.cursor }),
|
|
368
|
+
...(input.type === undefined
|
|
369
|
+
? {}
|
|
370
|
+
: { content_format_list: contentFormats[input.type] }),
|
|
371
|
+
...(input.assetFormats === undefined || input.assetFormats.length === 0
|
|
372
|
+
? {}
|
|
373
|
+
: { format: input.assetFormats }),
|
|
374
|
+
...(input.tagIds === undefined || input.tagIds.length === 0
|
|
375
|
+
? {}
|
|
376
|
+
: { tag_ids: input.tagIds })
|
|
377
|
+
},
|
|
378
|
+
...requestContext(input)
|
|
379
|
+
});
|
|
380
|
+
return searchResult(response, input);
|
|
381
|
+
},
|
|
382
|
+
async listFolders(input) {
|
|
383
|
+
const response = await dependencies.transport.getJsonResponse({
|
|
384
|
+
path: "/tb-dam/folders",
|
|
385
|
+
query: {
|
|
386
|
+
repository_ids: input.repositoryId,
|
|
387
|
+
parent_id: input.parentId,
|
|
388
|
+
keyword: input.query ?? "",
|
|
389
|
+
page_num: String(input.page),
|
|
390
|
+
page_size: String(input.pageSize),
|
|
391
|
+
filter_no_permission: "true",
|
|
392
|
+
include_children: String(input.query !== undefined),
|
|
393
|
+
sort: "topTime:desc,updatedAt:desc"
|
|
394
|
+
},
|
|
395
|
+
...requestContext(input)
|
|
396
|
+
});
|
|
397
|
+
const pagination = folderPagination(response.headers);
|
|
398
|
+
return {
|
|
399
|
+
repository_id: input.repositoryId,
|
|
400
|
+
parent_id: input.parentId,
|
|
401
|
+
page: pagination.page,
|
|
402
|
+
page_size: pagination.pageSize,
|
|
403
|
+
total: pagination.total,
|
|
404
|
+
folders: folderRows(response.body)
|
|
405
|
+
};
|
|
406
|
+
},
|
|
407
|
+
async listTags(input) {
|
|
408
|
+
const response = await dependencies.transport.getJson({
|
|
409
|
+
path: "/tb-dam/tags",
|
|
410
|
+
query: {
|
|
411
|
+
repository_id: input.repositoryId,
|
|
412
|
+
group_id: "",
|
|
413
|
+
...(input.query === undefined ? {} : { keyword: input.query })
|
|
414
|
+
},
|
|
415
|
+
...requestContext(input)
|
|
416
|
+
});
|
|
417
|
+
return { repository_id: input.repositoryId, tags: tagRows(response) };
|
|
418
|
+
},
|
|
419
|
+
async getDownloadUrls(input) {
|
|
420
|
+
const response = await dependencies.transport.getJson({
|
|
421
|
+
path: `/dam/asset/files/download/${encodeURIComponent(input.assetId)}/url-list`,
|
|
422
|
+
query: { repository_id: input.repositoryId },
|
|
423
|
+
...requestContext(input)
|
|
424
|
+
});
|
|
425
|
+
return downloadUrls(response);
|
|
426
|
+
},
|
|
427
|
+
async getFolder(input) {
|
|
428
|
+
let response;
|
|
429
|
+
try {
|
|
430
|
+
response = await dependencies.transport.getJson({
|
|
431
|
+
path: `/dam/folders/${encodeURIComponent(input.folderId)}`,
|
|
432
|
+
query: { repository_id: input.repositoryId },
|
|
433
|
+
...requestContext(input)
|
|
434
|
+
});
|
|
435
|
+
}
|
|
436
|
+
catch (error) {
|
|
437
|
+
if (error instanceof RemoteRequestError && error.status === 404) {
|
|
438
|
+
throw new DamFolderNotFoundError();
|
|
439
|
+
}
|
|
440
|
+
throw error;
|
|
441
|
+
}
|
|
442
|
+
return folderDetail(response);
|
|
443
|
+
},
|
|
444
|
+
async renameEntry(input) {
|
|
445
|
+
await dependencies.transport.putJson({
|
|
446
|
+
path: input.kind === "asset"
|
|
447
|
+
? `/dam/asset/${encodeURIComponent(input.entryId)}/rename`
|
|
448
|
+
: `/dam/folders/${encodeURIComponent(input.entryId)}/rename`,
|
|
449
|
+
body: {
|
|
450
|
+
id: input.entryId,
|
|
451
|
+
repository_id: input.repositoryId,
|
|
452
|
+
title: input.title
|
|
453
|
+
},
|
|
454
|
+
...requestContext(input)
|
|
455
|
+
});
|
|
456
|
+
},
|
|
457
|
+
async submitEntryOperation(input) {
|
|
458
|
+
assertSingleOperationInput(input);
|
|
459
|
+
const asset = input.kind === "asset";
|
|
460
|
+
const body = asset
|
|
461
|
+
? {
|
|
462
|
+
source_infos: [{
|
|
463
|
+
source_repository_id: input.sourceRepositoryId,
|
|
464
|
+
content_ids: [input.entryId]
|
|
465
|
+
}],
|
|
466
|
+
target_folder_id: input.targetFolderId,
|
|
467
|
+
target_repository_id: input.targetRepositoryId,
|
|
468
|
+
...(input.operation === "copy" ? { expand: false } : {})
|
|
469
|
+
}
|
|
470
|
+
: {
|
|
471
|
+
folder_ids: [input.entryId],
|
|
472
|
+
parent_id: input.targetFolderId,
|
|
473
|
+
repository_id: input.sourceRepositoryId,
|
|
474
|
+
target_repository_id: input.targetRepositoryId,
|
|
475
|
+
...(input.operation === "copy" ? { expand: false } : {})
|
|
476
|
+
};
|
|
477
|
+
const response = await dependencies.transport.postJson({
|
|
478
|
+
path: asset
|
|
479
|
+
? `/dam/asset/multi-repository/${input.operation}`
|
|
480
|
+
: `/dam/folders/v2/${input.operation}`,
|
|
481
|
+
body,
|
|
482
|
+
...requestContext(input)
|
|
483
|
+
});
|
|
484
|
+
return operationSubmission(response);
|
|
485
|
+
},
|
|
486
|
+
async getOperationTask(input) {
|
|
487
|
+
const response = await dependencies.transport.getJson({
|
|
488
|
+
path: "/dam/task/list",
|
|
489
|
+
query: { ids: input.taskId },
|
|
490
|
+
...requestContext(input)
|
|
491
|
+
});
|
|
492
|
+
return operationTask(response, input.taskId);
|
|
493
|
+
},
|
|
494
|
+
async getOperationChildren(input) {
|
|
495
|
+
const response = await dependencies.transport.getJson({
|
|
496
|
+
path: `/dam/task/children-detail/${encodeURIComponent(input.taskId)}`,
|
|
497
|
+
...requestContext(input)
|
|
498
|
+
});
|
|
499
|
+
return operationChildren(response);
|
|
500
|
+
},
|
|
501
|
+
async getAsset(input) {
|
|
502
|
+
let response;
|
|
503
|
+
try {
|
|
504
|
+
response = await dependencies.transport.getJson({
|
|
505
|
+
path: `/dam/asset/${encodeURIComponent(input.assetId)}`,
|
|
506
|
+
...requestContext(input)
|
|
507
|
+
});
|
|
508
|
+
}
|
|
509
|
+
catch (error) {
|
|
510
|
+
if (error instanceof RemoteRequestError && error.status === 404) {
|
|
511
|
+
throw new DamAssetNotFoundError();
|
|
512
|
+
}
|
|
513
|
+
throw error;
|
|
514
|
+
}
|
|
515
|
+
const asset = projectDamAssetDetail(response, input.assetId);
|
|
516
|
+
if (asset === undefined)
|
|
517
|
+
throw new RemoteRequestError();
|
|
518
|
+
return asset;
|
|
519
|
+
},
|
|
520
|
+
async createAssetId(input) {
|
|
521
|
+
const response = await dependencies.transport.postJson({
|
|
522
|
+
path: "/tb-dam/asset/id",
|
|
523
|
+
body: {},
|
|
524
|
+
...requestContext(input)
|
|
525
|
+
});
|
|
526
|
+
return assetId(response);
|
|
527
|
+
},
|
|
528
|
+
async createMaterial(input) {
|
|
529
|
+
const response = await dependencies.transport.postJson({
|
|
530
|
+
path: "/dam/asset/createMaterial",
|
|
531
|
+
body: input.body,
|
|
532
|
+
...requestContext(input)
|
|
533
|
+
});
|
|
534
|
+
const asset = projectDamAssetDetail(response, input.fallback);
|
|
535
|
+
if (asset === undefined)
|
|
536
|
+
throw new RemoteRequestError();
|
|
537
|
+
return asset;
|
|
538
|
+
},
|
|
539
|
+
async getBatchStatus(input) {
|
|
540
|
+
const response = await dependencies.transport.getJson({
|
|
541
|
+
path: "/dam/asset/batch-status",
|
|
542
|
+
query: { ids: input.assetId },
|
|
543
|
+
...requestContext(input)
|
|
544
|
+
});
|
|
545
|
+
return projectDamAssetDetail(response, input.fallback) ?? null;
|
|
546
|
+
},
|
|
547
|
+
async recycle(input) {
|
|
548
|
+
await dependencies.transport.postJson({
|
|
549
|
+
path: "/dam/recycle-bin",
|
|
550
|
+
body: recycleBody(input),
|
|
551
|
+
...requestContext(input)
|
|
552
|
+
});
|
|
553
|
+
},
|
|
554
|
+
async deleteRecycled(input) {
|
|
555
|
+
await dependencies.transport.postJson({
|
|
556
|
+
path: "/dam/recycle-bin/delete",
|
|
557
|
+
body: recycleBody(input),
|
|
558
|
+
...requestContext(input)
|
|
559
|
+
});
|
|
560
|
+
}
|
|
561
|
+
};
|
|
562
|
+
}
|