@seliseblocks/cli-os 0.2.1 → 0.2.3
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/AI_USAGE_GUIDE.md +551 -546
- package/LICENSE +21 -21
- package/README.md +171 -171
- package/bin/run.js +2 -2
- package/dist/commands/data/files/delete.js +5 -4
- package/dist/commands/data/files/get-many.js +1 -1
- package/dist/commands/data/files/get.js +1 -1
- package/dist/commands/data/files/info.js +1 -1
- package/dist/commands/data/files/object-tree.d.ts +23 -0
- package/dist/commands/data/files/object-tree.js +238 -0
- package/dist/commands/data/files/presigned-upload-url.js +9 -2
- package/dist/commands/data/files/update-additional-info.js +2 -2
- package/dist/commands/data/files/upload-to-local-storage.js +2 -2
- package/dist/commands/data/files/upload.d.ts +2 -4
- package/dist/commands/data/files/upload.js +14 -28
- package/dist/index.js +685 -647
- package/dist/lib/scaffold-web/root-files.js +158 -0
- package/dist/skills/blocks-data-gateway-configuration/SKILL.md +204 -204
- package/dist/skills/blocks-data-gateway-crud/SKILL.md +223 -223
- package/dist/skills/blocks-data-storage/SKILL.md +253 -161
- package/dist/skills/blocks-data-storage/flows/object-management.md +124 -0
- package/dist/skills/blocks-frontend-local-https/SKILL.md +100 -100
- package/dist/skills/blocks-iam-account/SKILL.md +169 -169
- package/dist/skills/blocks-iam-sso-oidc-implementation/SKILL.md +80 -80
- package/dist/skills/blocks-iam-users/SKILL.md +131 -131
- package/dist/skills/blocks-localization-configuration/SKILL.md +149 -149
- package/dist/skills/blocks-localization-implementation/SKILL.md +63 -63
- package/dist/skills/blocks-onboarding/SKILL.md +77 -77
- package/dist/skills/blocks-storage-configuration/SKILL.md +4 -4
- package/package.json +47 -47
- package/dist/commands/data/files/create-folder.d.ts +0 -1
- package/dist/commands/data/files/create-folder.js +0 -34
- package/dist/commands/data/files/delete-folder.d.ts +0 -1
- package/dist/commands/data/files/delete-folder.js +0 -25
- package/dist/commands/data/files/dms-list.d.ts +0 -1
- package/dist/commands/data/files/dms-list.js +0 -27
- package/dist/commands/data/files/dms-upload.d.ts +0 -6
- package/dist/commands/data/files/dms-upload.js +0 -41
|
@@ -0,0 +1,238 @@
|
|
|
1
|
+
import { booleanFlag, optionalBooleanFlag, optionalIntegerFlag, stringFlag } from "../../../lib/args.js";
|
|
2
|
+
import { blocksRequest } from "../../../lib/api.js";
|
|
3
|
+
import { confirmMutation } from "../../../lib/confirm.js";
|
|
4
|
+
import { compact, jsonBodyFlag, listFlag } from "../../../lib/json-flag.js";
|
|
5
|
+
import { writeOutput } from "../../../lib/output.js";
|
|
6
|
+
import { requestContext } from "../../../lib/request-context.js";
|
|
7
|
+
import { parseCommand, selectedProject } from "../../../lib/workspace.js";
|
|
8
|
+
export async function dataFilesList(argv) {
|
|
9
|
+
const { flags } = parseCommand(argv);
|
|
10
|
+
await read("/data/v4/objects/get-objects", flags, compact({
|
|
11
|
+
cursor: stringFlag(flags, "cursor") || undefined,
|
|
12
|
+
limit: optionalIntegerFlag(flags, "limit"),
|
|
13
|
+
moduleName: optionalIntegerFlag(flags, "module-name"),
|
|
14
|
+
parentDirectoryId: parentId(flags) || undefined,
|
|
15
|
+
search: stringFlag(flags, "search") || undefined,
|
|
16
|
+
type: stringFlag(flags, "type") || undefined
|
|
17
|
+
}));
|
|
18
|
+
}
|
|
19
|
+
export async function dataFilesSearch(argv) {
|
|
20
|
+
const { args, flags } = parseCommand(argv);
|
|
21
|
+
await read("/data/v4/objects/search-objects", flags, compact({
|
|
22
|
+
cursor: stringFlag(flags, "cursor") || undefined,
|
|
23
|
+
directoryId: stringFlag(flags, "directory-id") || undefined,
|
|
24
|
+
limit: optionalIntegerFlag(flags, "limit"),
|
|
25
|
+
query: args[0] || stringFlag(flags, "query", { required: true }),
|
|
26
|
+
type: stringFlag(flags, "type") || undefined
|
|
27
|
+
}));
|
|
28
|
+
}
|
|
29
|
+
export async function dataFilesTrash(argv) {
|
|
30
|
+
const { flags } = parseCommand(argv);
|
|
31
|
+
await read("/data/v4/objects/get-trash", flags, pageQuery(flags));
|
|
32
|
+
}
|
|
33
|
+
export async function dataFilesShared(argv) {
|
|
34
|
+
const { flags } = parseCommand(argv);
|
|
35
|
+
await read("/data/v4/objects/get-shared-objects", flags, pageQuery(flags));
|
|
36
|
+
}
|
|
37
|
+
export async function dataFilesRestore(argv) {
|
|
38
|
+
const { args, flags } = parseCommand(argv);
|
|
39
|
+
const resourceId = resourceArg(args, flags);
|
|
40
|
+
await mutate("/data/v4/objects/restore-from-trash", flags, { resourceId }, `Restore storage object '${resourceId}' from trash.`);
|
|
41
|
+
}
|
|
42
|
+
export async function dataFilesPurge(argv) {
|
|
43
|
+
const { args, flags } = parseCommand(argv);
|
|
44
|
+
const resourceId = resourceArg(args, flags);
|
|
45
|
+
await mutate("/data/v4/objects/delete-from-trash", flags, { resourceId }, `Permanently delete storage object '${resourceId}' from trash.`);
|
|
46
|
+
}
|
|
47
|
+
export async function dataFilesDirectoryCreate(argv) {
|
|
48
|
+
const { args, flags } = parseCommand(argv);
|
|
49
|
+
const base = await jsonBodyFlag(flags);
|
|
50
|
+
const name = args[0] || stringFlag(flags, "name") || String(base.name ?? "");
|
|
51
|
+
if (!name)
|
|
52
|
+
throw new Error("Provide a directory name as the first argument or --name.");
|
|
53
|
+
const body = { ...base, ...compact({
|
|
54
|
+
allowedFileExtensions: listFlag(flags, "allowed-extensions"),
|
|
55
|
+
configurationName: stringFlag(flags, "configuration-name") || undefined,
|
|
56
|
+
description: stringFlag(flags, "description") || undefined,
|
|
57
|
+
moduleName: optionalIntegerFlag(flags, "module-name"),
|
|
58
|
+
name,
|
|
59
|
+
parentDirectoryId: parentId(flags) || undefined
|
|
60
|
+
}) };
|
|
61
|
+
await mutate("/data/v4/directory/create-directory", flags, body, `Create storage directory '${name}'.`);
|
|
62
|
+
}
|
|
63
|
+
export async function dataFilesDirectoryGet(argv) {
|
|
64
|
+
const { args, flags } = parseCommand(argv);
|
|
65
|
+
const directoryId = directoryArg(args, flags);
|
|
66
|
+
await read("/data/v4/directory/get-directory", flags, { directoryId });
|
|
67
|
+
}
|
|
68
|
+
export async function dataFilesDirectoryUpdate(argv) {
|
|
69
|
+
const { args, flags } = parseCommand(argv);
|
|
70
|
+
const directoryId = directoryArg(args, flags);
|
|
71
|
+
const body = { ...(await jsonBodyFlag(flags)), ...compact({
|
|
72
|
+
description: stringFlag(flags, "description") || undefined,
|
|
73
|
+
directoryId,
|
|
74
|
+
name: stringFlag(flags, "name") || undefined
|
|
75
|
+
}) };
|
|
76
|
+
await mutate("/data/v4/directory/update-directory", flags, body, `Update storage directory '${directoryId}'.`);
|
|
77
|
+
}
|
|
78
|
+
export async function dataFilesDirectoryDelete(argv) {
|
|
79
|
+
const { args, flags } = parseCommand(argv);
|
|
80
|
+
const directoryId = directoryArg(args, flags);
|
|
81
|
+
const permanent = booleanFlag(flags, "permanent");
|
|
82
|
+
await mutate("/data/v4/directory/delete-directory", flags, { directoryId, permanent }, `${permanent ? "Permanently delete" : "Move"} storage directory '${directoryId}'${permanent ? "" : " to trash"}.`);
|
|
83
|
+
}
|
|
84
|
+
export async function dataFilesDirectoryMove(argv) {
|
|
85
|
+
const { args, flags } = parseCommand(argv);
|
|
86
|
+
const directoryId = directoryArg(args, flags);
|
|
87
|
+
const targetDirectoryId = stringFlag(flags, "target-directory-id") || stringFlag(flags, "target-id");
|
|
88
|
+
await mutate("/data/v4/directory/move-directory", flags, { directoryId, targetDirectoryId }, `Move storage directory '${directoryId}'.`);
|
|
89
|
+
}
|
|
90
|
+
export async function dataFilesVersions(argv) {
|
|
91
|
+
const { args, flags } = parseCommand(argv);
|
|
92
|
+
await read("/data/v4/files/get-file-versions", flags, compact({
|
|
93
|
+
cursor: stringFlag(flags, "cursor") || undefined,
|
|
94
|
+
fileId: fileArg(args, flags),
|
|
95
|
+
limit: optionalIntegerFlag(flags, "limit")
|
|
96
|
+
}));
|
|
97
|
+
}
|
|
98
|
+
export async function dataFilesCreateVersion(argv) {
|
|
99
|
+
const { args, flags } = parseCommand(argv);
|
|
100
|
+
const fileId = fileArg(args, flags);
|
|
101
|
+
await mutate("/data/v4/files/create-file-version", flags, compact({
|
|
102
|
+
configurationName: stringFlag(flags, "configuration-name") || undefined,
|
|
103
|
+
fileId
|
|
104
|
+
}), `Create a new upload version for file '${fileId}'.`);
|
|
105
|
+
}
|
|
106
|
+
export async function dataFilesCopy(argv) {
|
|
107
|
+
const { args, flags } = parseCommand(argv);
|
|
108
|
+
const fileId = fileArg(args, flags);
|
|
109
|
+
const targetDirectoryId = stringFlag(flags, "target-directory-id", { required: true });
|
|
110
|
+
await mutate("/data/v4/files/copy-file", flags, {
|
|
111
|
+
copyAccessPolicies: booleanFlag(flags, "copy-access-policies"), fileId, targetDirectoryId
|
|
112
|
+
}, `Copy file '${fileId}' to directory '${targetDirectoryId}'.`);
|
|
113
|
+
}
|
|
114
|
+
export async function dataFilesMove(argv) {
|
|
115
|
+
const { args, flags } = parseCommand(argv);
|
|
116
|
+
const fileId = fileArg(args, flags);
|
|
117
|
+
const targetDirectoryId = stringFlag(flags, "target-directory-id", { required: true });
|
|
118
|
+
await mutate("/data/v4/files/move-file", flags, { fileId, targetDirectoryId }, `Move file '${fileId}' to directory '${targetDirectoryId}'.`);
|
|
119
|
+
}
|
|
120
|
+
export async function dataFilesRename(argv) {
|
|
121
|
+
const { args, flags } = parseCommand(argv);
|
|
122
|
+
const fileId = fileArg(args, flags);
|
|
123
|
+
const name = stringFlag(flags, "name", { required: true });
|
|
124
|
+
await mutate("/data/v4/files/rename-file", flags, { fileId, name }, `Rename file '${fileId}' to '${name}'.`);
|
|
125
|
+
}
|
|
126
|
+
export async function dataFilesAccessList(argv) {
|
|
127
|
+
const { args, flags } = parseCommand(argv);
|
|
128
|
+
await read("/data/v4/objects/get-access-policies", flags, { resourceId: resourceArg(args, flags) });
|
|
129
|
+
}
|
|
130
|
+
export async function dataFilesAccessGrant(argv) {
|
|
131
|
+
await accessMutation(argv, "/data/v4/objects/grant-access", "Grant access to");
|
|
132
|
+
}
|
|
133
|
+
export async function dataFilesAccessUpdate(argv) {
|
|
134
|
+
await accessMutation(argv, "/data/v4/objects/update-access-policy", "Update access on", true);
|
|
135
|
+
}
|
|
136
|
+
export async function dataFilesAccessRevoke(argv) {
|
|
137
|
+
const { args, flags } = parseCommand(argv);
|
|
138
|
+
const resourceId = resourceArg(args, flags);
|
|
139
|
+
const policyItemId = stringFlag(flags, "policy-id", { required: true });
|
|
140
|
+
await mutate("/data/v4/objects/revoke-access-policy", flags, { policyItemId, resourceId }, `Revoke access policy '${policyItemId}' from '${resourceId}'.`);
|
|
141
|
+
}
|
|
142
|
+
export async function dataFilesAccessResolve(argv) {
|
|
143
|
+
const { args, flags } = parseCommand(argv);
|
|
144
|
+
await read("/data/v4/objects/resolve-access", flags, { resourceId: resourceArg(args, flags) });
|
|
145
|
+
}
|
|
146
|
+
export async function dataFilesInheritance(argv) {
|
|
147
|
+
const { args, flags } = parseCommand(argv);
|
|
148
|
+
const base = await jsonBodyFlag(flags);
|
|
149
|
+
const value = optionalBooleanFlag(flags, "enabled");
|
|
150
|
+
const inheritsParentAccess = value ?? base.inheritsParentAccess;
|
|
151
|
+
if (typeof inheritsParentAccess !== "boolean")
|
|
152
|
+
throw new Error("Provide --enabled=true|false.");
|
|
153
|
+
const resourceId = resourceArg(args, flags, base);
|
|
154
|
+
await mutate("/data/v4/objects/toggle-inheritance", flags, { ...base, inheritsParentAccess, resourceId }, `Set inheritance on '${resourceId}' to ${inheritsParentAccess}.`);
|
|
155
|
+
}
|
|
156
|
+
export async function dataFilesShare(argv) {
|
|
157
|
+
const { args, flags } = parseCommand(argv);
|
|
158
|
+
const base = await jsonBodyFlag(flags);
|
|
159
|
+
const resourceId = resourceArg(args, flags, base);
|
|
160
|
+
const body = accessBody(base, flags, resourceId);
|
|
161
|
+
delete body.effect;
|
|
162
|
+
delete body.policyItemId;
|
|
163
|
+
await mutate("/data/v4/objects/share-object", flags, body, `Share storage object '${resourceId}'.`);
|
|
164
|
+
}
|
|
165
|
+
async function accessMutation(argv, endpoint, action, update = false) {
|
|
166
|
+
const { args, flags } = parseCommand(argv);
|
|
167
|
+
const base = await jsonBodyFlag(flags);
|
|
168
|
+
const resourceId = resourceArg(args, flags, base);
|
|
169
|
+
const body = accessBody(base, flags, resourceId);
|
|
170
|
+
if (update && !body.policyItemId)
|
|
171
|
+
throw new Error("Provide --policy-id when updating an access policy.");
|
|
172
|
+
await mutate(endpoint, flags, body, `${action} storage object '${resourceId}'.`);
|
|
173
|
+
}
|
|
174
|
+
function accessBody(base, flags, resourceId) {
|
|
175
|
+
const body = { ...base, ...compact({
|
|
176
|
+
effect: stringFlag(flags, "effect") || undefined,
|
|
177
|
+
expiresAt: stringFlag(flags, "expires-at") || undefined,
|
|
178
|
+
permission: stringFlag(flags, "permission") || undefined,
|
|
179
|
+
policyItemId: stringFlag(flags, "policy-id") || undefined,
|
|
180
|
+
principalId: stringFlag(flags, "principal-id") || undefined,
|
|
181
|
+
principalType: stringFlag(flags, "principal-type") || undefined,
|
|
182
|
+
priority: optionalIntegerFlag(flags, "priority"),
|
|
183
|
+
resourceId,
|
|
184
|
+
resourceType: stringFlag(flags, "resource-type") || undefined
|
|
185
|
+
}) };
|
|
186
|
+
for (const field of ["permission", "principalType", "resourceType"]) {
|
|
187
|
+
if (!body[field])
|
|
188
|
+
throw new Error(`Provide --${field.replace(/[A-Z]/g, (letter) => `-${letter.toLowerCase()}`)}.`);
|
|
189
|
+
}
|
|
190
|
+
return body;
|
|
191
|
+
}
|
|
192
|
+
async function read(endpoint, flags, query) {
|
|
193
|
+
const projectKey = await selectedProject(flags);
|
|
194
|
+
const result = await blocksRequest(endpoint, {
|
|
195
|
+
impersonatedProjectAuth: true,
|
|
196
|
+
...requestContext(flags),
|
|
197
|
+
projectTenantId: projectKey,
|
|
198
|
+
query
|
|
199
|
+
});
|
|
200
|
+
writeOutput(result, flags);
|
|
201
|
+
}
|
|
202
|
+
async function mutate(endpoint, flags, body, prompt) {
|
|
203
|
+
if (booleanFlag(flags, "dry-run")) {
|
|
204
|
+
writeOutput({ dryRun: true, endpoint, request: body }, flags);
|
|
205
|
+
return;
|
|
206
|
+
}
|
|
207
|
+
await confirmMutation(flags, prompt);
|
|
208
|
+
const projectKey = await selectedProject(flags);
|
|
209
|
+
const result = await blocksRequest(endpoint, {
|
|
210
|
+
body,
|
|
211
|
+
impersonatedProjectAuth: true,
|
|
212
|
+
...requestContext(flags),
|
|
213
|
+
projectTenantId: projectKey
|
|
214
|
+
});
|
|
215
|
+
writeOutput(result, flags);
|
|
216
|
+
}
|
|
217
|
+
function pageQuery(flags) {
|
|
218
|
+
return compact({
|
|
219
|
+
cursor: stringFlag(flags, "cursor") || undefined,
|
|
220
|
+
limit: optionalIntegerFlag(flags, "limit"),
|
|
221
|
+
type: stringFlag(flags, "type") || undefined
|
|
222
|
+
});
|
|
223
|
+
}
|
|
224
|
+
function parentId(flags) {
|
|
225
|
+
return stringFlag(flags, "parent-directory-id") || stringFlag(flags, "parent-id");
|
|
226
|
+
}
|
|
227
|
+
function resourceArg(args, flags, base = {}) {
|
|
228
|
+
const value = args[0] || stringFlag(flags, "resource-id") || String(base.resourceId ?? "");
|
|
229
|
+
if (!value)
|
|
230
|
+
throw new Error("Provide a resource id as the first argument or --resource-id.");
|
|
231
|
+
return value;
|
|
232
|
+
}
|
|
233
|
+
function directoryArg(args, flags) {
|
|
234
|
+
return args[0] || stringFlag(flags, "directory-id", { required: true });
|
|
235
|
+
}
|
|
236
|
+
function fileArg(args, flags) {
|
|
237
|
+
return args[0] || stringFlag(flags, "file-id", { required: true });
|
|
238
|
+
}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import { optionalIntegerFlag, stringFlag } from "../../../lib/args.js";
|
|
1
|
+
import { booleanFlag, optionalIntegerFlag, stringFlag } from "../../../lib/args.js";
|
|
2
2
|
import { blocksRequest } from "../../../lib/api.js";
|
|
3
|
+
import { confirmMutation } from "../../../lib/confirm.js";
|
|
3
4
|
import { compact, jsonBodyFlag } from "../../../lib/json-flag.js";
|
|
4
5
|
import { writeOutput } from "../../../lib/output.js";
|
|
5
6
|
import { requestContext } from "../../../lib/request-context.js";
|
|
@@ -16,6 +17,7 @@ export async function dataFilesPresignedUploadUrl(argv) {
|
|
|
16
17
|
...compact({
|
|
17
18
|
accessModifier: stringFlag(flags, "access-modifier") || undefined,
|
|
18
19
|
configurationName: stringFlag(flags, "configuration-name") || undefined,
|
|
20
|
+
itemId: stringFlag(flags, "item-id") || undefined,
|
|
19
21
|
metaData: stringFlag(flags, "meta-data") || undefined,
|
|
20
22
|
moduleName: optionalIntegerFlag(flags, "module-name"),
|
|
21
23
|
name: stringFlag(flags, "name", { required: true }),
|
|
@@ -23,8 +25,13 @@ export async function dataFilesPresignedUploadUrl(argv) {
|
|
|
23
25
|
tags: stringFlag(flags, "tags") || undefined
|
|
24
26
|
})
|
|
25
27
|
};
|
|
28
|
+
if (booleanFlag(flags, "dry-run")) {
|
|
29
|
+
writeOutput({ dryRun: true, endpoint: "/data/v4/files/get-pre-signed-url-for-upload", request: body }, flags);
|
|
30
|
+
return;
|
|
31
|
+
}
|
|
32
|
+
await confirmMutation(flags, `Create file metadata and an upload URL for '${body.name}'.`);
|
|
26
33
|
const projectKey = await selectedProject(flags);
|
|
27
|
-
const result = await blocksRequest("/data/v4/
|
|
34
|
+
const result = await blocksRequest("/data/v4/files/get-pre-signed-url-for-upload", {
|
|
28
35
|
body,
|
|
29
36
|
impersonatedProjectAuth: true,
|
|
30
37
|
...requestContext(flags),
|
|
@@ -11,12 +11,12 @@ export async function dataFilesUpdateAdditionalInfo(argv) {
|
|
|
11
11
|
const additionalProperties = JSON.parse(additionalPropertiesRaw);
|
|
12
12
|
const body = { additionalProperties, itemId };
|
|
13
13
|
if (booleanFlag(flags, "dry-run")) {
|
|
14
|
-
writeOutput({ dryRun: true, endpoint: "/data/v4/
|
|
14
|
+
writeOutput({ dryRun: true, endpoint: "/data/v4/files/update-file-additional-info", request: body }, flags);
|
|
15
15
|
return;
|
|
16
16
|
}
|
|
17
17
|
await confirmMutation(flags, `Update additional info for file '${itemId}'.`);
|
|
18
18
|
const projectKey = await selectedProject(flags);
|
|
19
|
-
const result = await blocksRequest("/data/v4/
|
|
19
|
+
const result = await blocksRequest("/data/v4/files/update-file-additional-info", {
|
|
20
20
|
body,
|
|
21
21
|
impersonatedProjectAuth: true,
|
|
22
22
|
...requestContext(flags),
|
|
@@ -16,7 +16,7 @@ export async function dataFilesUploadToLocalStorage(argv) {
|
|
|
16
16
|
const name = stringFlag(flags, "name") || basename(filePath);
|
|
17
17
|
const additionalPropertiesRaw = stringFlag(flags, "additional-properties");
|
|
18
18
|
if (booleanFlag(flags, "dry-run")) {
|
|
19
|
-
writeOutput({ dryRun: true, endpoint: "/data/v4/
|
|
19
|
+
writeOutput({ dryRun: true, endpoint: "/data/v4/files/upload-file-to-local-storage", name, request: { file: filePath } }, flags);
|
|
20
20
|
return;
|
|
21
21
|
}
|
|
22
22
|
await confirmMutation(flags, `Upload '${filePath}' to local storage as '${name}'.`);
|
|
@@ -45,7 +45,7 @@ export async function dataFilesUploadToLocalStorage(argv) {
|
|
|
45
45
|
form.set(`AdditionalProperties[${key}]`, value);
|
|
46
46
|
}
|
|
47
47
|
const projectKey = await selectedProject(flags);
|
|
48
|
-
const result = await blocksRequest("/data/v4/
|
|
48
|
+
const result = await blocksRequest("/data/v4/files/upload-file-to-local-storage", {
|
|
49
49
|
body: form,
|
|
50
50
|
impersonatedProjectAuth: true,
|
|
51
51
|
...requestContext(flags),
|
|
@@ -1,7 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Composed upload:
|
|
3
|
-
*
|
|
4
|
-
* local-storage path) -- instead of you chaining presigned-upload-url/upload-to-url/dms-upload
|
|
5
|
-
* (or upload-to-local-storage) by hand.
|
|
2
|
+
* Composed upload: create the file/version metadata and PUT cloud bytes, or use the
|
|
3
|
+
* one-call local-storage path. The upload is immediately part of the object tree.
|
|
6
4
|
*/
|
|
7
5
|
export declare function dataFilesUpload(argv: string[]): Promise<void>;
|
|
@@ -3,7 +3,7 @@ import { basename, extname } from "node:path";
|
|
|
3
3
|
import { booleanFlag, optionalIntegerFlag, stringFlag } from "../../../lib/args.js";
|
|
4
4
|
import { blocksRequest } from "../../../lib/api.js";
|
|
5
5
|
import { confirmMutation } from "../../../lib/confirm.js";
|
|
6
|
-
import { compact
|
|
6
|
+
import { compact } from "../../../lib/json-flag.js";
|
|
7
7
|
import { writeOutput } from "../../../lib/output.js";
|
|
8
8
|
import { requestContext } from "../../../lib/request-context.js";
|
|
9
9
|
import { parseCommand, selectedProject } from "../../../lib/workspace.js";
|
|
@@ -25,10 +25,8 @@ const CONTENT_TYPES = {
|
|
|
25
25
|
".zip": "application/zip"
|
|
26
26
|
};
|
|
27
27
|
/**
|
|
28
|
-
* Composed upload:
|
|
29
|
-
*
|
|
30
|
-
* local-storage path) -- instead of you chaining presigned-upload-url/upload-to-url/dms-upload
|
|
31
|
-
* (or upload-to-local-storage) by hand.
|
|
28
|
+
* Composed upload: create the file/version metadata and PUT cloud bytes, or use the
|
|
29
|
+
* one-call local-storage path. The upload is immediately part of the object tree.
|
|
32
30
|
*/
|
|
33
31
|
export async function dataFilesUpload(argv) {
|
|
34
32
|
const { flags } = parseCommand(argv);
|
|
@@ -43,7 +41,7 @@ export async function dataFilesUpload(argv) {
|
|
|
43
41
|
async function uploadToLocalStorage(filePath, name, flags) {
|
|
44
42
|
const parentDirectoryId = stringFlag(flags, "parent-id") || stringFlag(flags, "parent-directory-id");
|
|
45
43
|
if (booleanFlag(flags, "dry-run")) {
|
|
46
|
-
writeOutput({ dryRun: true, endpoint: "/data/v4/
|
|
44
|
+
writeOutput({ dryRun: true, endpoint: "/data/v4/files/upload-file-to-local-storage", file: filePath, name }, flags);
|
|
47
45
|
return;
|
|
48
46
|
}
|
|
49
47
|
await confirmMutation(flags, `Upload '${filePath}' to local storage as '${name}'.`);
|
|
@@ -52,6 +50,9 @@ async function uploadToLocalStorage(filePath, name, flags) {
|
|
|
52
50
|
form.set("Name", name);
|
|
53
51
|
if (parentDirectoryId)
|
|
54
52
|
form.set("ParentDirectoryId", parentDirectoryId);
|
|
53
|
+
const itemId = stringFlag(flags, "item-id");
|
|
54
|
+
if (itemId)
|
|
55
|
+
form.set("ItemId", itemId);
|
|
55
56
|
const tags = stringFlag(flags, "tags");
|
|
56
57
|
if (tags)
|
|
57
58
|
form.set("Tags", tags);
|
|
@@ -62,7 +63,7 @@ async function uploadToLocalStorage(filePath, name, flags) {
|
|
|
62
63
|
if (configurationName)
|
|
63
64
|
form.set("ConfigurationName", configurationName);
|
|
64
65
|
const projectKey = await selectedProject(flags);
|
|
65
|
-
const result = await blocksRequest("/data/v4/
|
|
66
|
+
const result = await blocksRequest("/data/v4/files/upload-file-to-local-storage", {
|
|
66
67
|
body: form,
|
|
67
68
|
impersonatedProjectAuth: true,
|
|
68
69
|
...requestContext(flags),
|
|
@@ -77,6 +78,7 @@ async function uploadViaPresignedUrl(filePath, name, flags) {
|
|
|
77
78
|
const presignBody = compact({
|
|
78
79
|
accessModifier: stringFlag(flags, "access-modifier") || undefined,
|
|
79
80
|
configurationName: stringFlag(flags, "configuration-name") || undefined,
|
|
81
|
+
itemId: stringFlag(flags, "item-id") || undefined,
|
|
80
82
|
metaData: stringFlag(flags, "meta-data") || undefined,
|
|
81
83
|
moduleName: optionalIntegerFlag(flags, "module-name"),
|
|
82
84
|
name,
|
|
@@ -87,16 +89,15 @@ async function uploadViaPresignedUrl(filePath, name, flags) {
|
|
|
87
89
|
writeOutput({
|
|
88
90
|
dryRun: true,
|
|
89
91
|
steps: [
|
|
90
|
-
{ body: presignBody, endpoint: "/data/v4/
|
|
91
|
-
{ contentType, endpoint: "PUT <uploadUrl>", file: filePath }
|
|
92
|
-
{ endpoint: "/data/v4/Files/UploadFile" }
|
|
92
|
+
{ body: presignBody, endpoint: "/data/v4/files/get-pre-signed-url-for-upload" },
|
|
93
|
+
{ contentType, endpoint: "PUT <uploadUrl>", file: filePath }
|
|
93
94
|
]
|
|
94
95
|
}, flags);
|
|
95
96
|
return;
|
|
96
97
|
}
|
|
97
|
-
await confirmMutation(flags, `Upload '${filePath}' as '${name}' (
|
|
98
|
+
await confirmMutation(flags, `Upload '${filePath}' as '${name}' (create metadata + PUT bytes).`);
|
|
98
99
|
const projectKey = await selectedProject(flags);
|
|
99
|
-
const presigned = await blocksRequest("/data/v4/
|
|
100
|
+
const presigned = await blocksRequest("/data/v4/files/get-pre-signed-url-for-upload", {
|
|
100
101
|
body: presignBody,
|
|
101
102
|
impersonatedProjectAuth: true,
|
|
102
103
|
...requestContext(flags),
|
|
@@ -118,22 +119,7 @@ async function uploadViaPresignedUrl(filePath, name, flags) {
|
|
|
118
119
|
if (!putResponse.ok) {
|
|
119
120
|
throw new Error(`Upload PUT ${putResponse.status} ${putResponse.statusText}: ${await putResponse.text().catch(() => "")}`);
|
|
120
121
|
}
|
|
121
|
-
|
|
122
|
-
body: {
|
|
123
|
-
upload: [
|
|
124
|
-
compact({
|
|
125
|
-
artifactName: name,
|
|
126
|
-
fileStorageId: fileId,
|
|
127
|
-
parentId: parentDirectoryId || undefined,
|
|
128
|
-
tags: listFlag(flags, "tags")
|
|
129
|
-
})
|
|
130
|
-
]
|
|
131
|
-
},
|
|
132
|
-
impersonatedProjectAuth: true,
|
|
133
|
-
...requestContext(flags),
|
|
134
|
-
projectTenantId: projectKey
|
|
135
|
-
});
|
|
136
|
-
writeOutput({ fileId, registered, uploadUrl }, flags);
|
|
122
|
+
writeOutput({ fileId, uploadUrl, uploaded: true }, flags);
|
|
137
123
|
}
|
|
138
124
|
function firstString(record, keys) {
|
|
139
125
|
for (const key of keys) {
|