@dboio/cli 0.6.11 → 0.6.12
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/README.md +17 -2
- package/package.json +1 -1
- package/src/commands/content.js +28 -7
- package/src/commands/deploy.js +32 -9
package/README.md
CHANGED
|
@@ -618,6 +618,7 @@ dbo content deploy albain3dwkofbhnd1qtd1q assets/css/colors.css
|
|
|
618
618
|
dbo content deploy rncjivlghu65bmkbjnxynq assets/js/app.js
|
|
619
619
|
dbo content deploy abc123 docs/readme.md --ticket myTicket
|
|
620
620
|
dbo content deploy abc123 test.html --confirm false # validate only
|
|
621
|
+
dbo content deploy abc123 image.png --multipart # binary file upload
|
|
621
622
|
```
|
|
622
623
|
|
|
623
624
|
This is a shorthand for:
|
|
@@ -632,6 +633,7 @@ dbo input -d 'RowUID:albain3dwkofbhnd1qtd1q;column:content.Content@assets/css/co
|
|
|
632
633
|
| `-C, --confirm <true\|false>` | Commit (default: `true`) |
|
|
633
634
|
| `--ticket <id>` | Override ticket ID |
|
|
634
635
|
| `--modify-key <key>` | Provide ModifyKey directly (skips interactive prompt) |
|
|
636
|
+
| `--multipart` | Use multipart/form-data upload (for binary files) |
|
|
635
637
|
|
|
636
638
|
#### `dbo content pull`
|
|
637
639
|
|
|
@@ -1361,6 +1363,17 @@ Create a `dbo.deploy.json` file in your project root to define named deployments
|
|
|
1361
1363
|
"file": "docs/colors.md",
|
|
1362
1364
|
"entity": "extension",
|
|
1363
1365
|
"column": "Text"
|
|
1366
|
+
},
|
|
1367
|
+
"img:logo": {
|
|
1368
|
+
"uid": "x9fk2m3npqrs7tuvwyz1ab",
|
|
1369
|
+
"file": "assets/images/logo.png",
|
|
1370
|
+
"multipart": true
|
|
1371
|
+
},
|
|
1372
|
+
"upload:icons": {
|
|
1373
|
+
"uid": "7ddf10982a96457fa4f440",
|
|
1374
|
+
"file": "assets/css/launchpad-icons.css",
|
|
1375
|
+
"multipart": true,
|
|
1376
|
+
"filename": "launchpad-icons.css"
|
|
1364
1377
|
}
|
|
1365
1378
|
}
|
|
1366
1379
|
}
|
|
@@ -1370,8 +1383,10 @@ Create a `dbo.deploy.json` file in your project root to define named deployments
|
|
|
1370
1383
|
|-------|-------------|---------|
|
|
1371
1384
|
| `uid` | Target record UID (required) | — |
|
|
1372
1385
|
| `file` | Local file path (required) | — |
|
|
1373
|
-
| `entity` | Target entity name | `content` |
|
|
1374
|
-
| `column` | Target column name | `Content` |
|
|
1386
|
+
| `entity` | Target entity name | `content` (`media` when `multipart: true`) |
|
|
1387
|
+
| `column` | Target column name | `Content` (`File` when `multipart: true`) |
|
|
1388
|
+
| `multipart` | Use multipart/form-data upload (for binary files) | `false` |
|
|
1389
|
+
| `filename` | Set the `Filename` column on the target record | basename of `file` |
|
|
1375
1390
|
|
|
1376
1391
|
This replaces the curl commands typically embedded in `package.json` scripts.
|
|
1377
1392
|
|
package/package.json
CHANGED
package/src/commands/content.js
CHANGED
|
@@ -31,6 +31,7 @@ const deployCmd = new Command('deploy')
|
|
|
31
31
|
.option('-C, --confirm <value>', 'Commit: true (default) or false', 'true')
|
|
32
32
|
.option('--ticket <id>', 'Override ticket ID')
|
|
33
33
|
.option('--modify-key <key>', 'Provide ModifyKey directly (skips interactive prompt)')
|
|
34
|
+
.option('--multipart', 'Use multipart/form-data upload (for binary files)')
|
|
34
35
|
.option('--json', 'Output raw JSON')
|
|
35
36
|
.option('-v, --verbose', 'Show HTTP request details')
|
|
36
37
|
.option('--domain <host>', 'Override domain')
|
|
@@ -66,7 +67,8 @@ const deployCmd = new Command('deploy')
|
|
|
66
67
|
if (options.ticket) extraParams['_OverrideTicketID'] = options.ticket;
|
|
67
68
|
if (modifyKeyResult.modifyKey) extraParams['_modify_key'] = modifyKeyResult.modifyKey;
|
|
68
69
|
|
|
69
|
-
const
|
|
70
|
+
const isMultipart = options.multipart === true;
|
|
71
|
+
const dataExprs = isMultipart ? [] : [`RowUID:${uid};column:content.Content@${filepath}`];
|
|
70
72
|
|
|
71
73
|
// Apply stored ticket if no --ticket flag
|
|
72
74
|
if (!options.ticket) {
|
|
@@ -77,16 +79,36 @@ const deployCmd = new Command('deploy')
|
|
|
77
79
|
}
|
|
78
80
|
await applyStoredTicketToSubmission(dataExprs, 'content', uid, uid, options, sessionTicketOverride);
|
|
79
81
|
|
|
80
|
-
|
|
81
|
-
|
|
82
|
+
// Submit helper — handles both URL-encoded and multipart modes
|
|
83
|
+
async function submit() {
|
|
84
|
+
if (isMultipart) {
|
|
85
|
+
const fields = { ...extraParams };
|
|
86
|
+
for (const expr of dataExprs) {
|
|
87
|
+
const eqIdx = expr.indexOf('=');
|
|
88
|
+
if (eqIdx !== -1) {
|
|
89
|
+
fields[expr.substring(0, eqIdx)] = expr.substring(eqIdx + 1);
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
const files = [{
|
|
93
|
+
fieldName: `RowUID:${uid};column:content.Content`,
|
|
94
|
+
filePath: filepath,
|
|
95
|
+
fileName: filepath.split('/').pop(),
|
|
96
|
+
}];
|
|
97
|
+
return client.postMultipart('/api/input/submit', fields, files);
|
|
98
|
+
} else {
|
|
99
|
+
const body = await buildInputBody(dataExprs, extraParams);
|
|
100
|
+
return client.postUrlEncoded('/api/input/submit', body);
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
let result = await submit();
|
|
82
105
|
|
|
83
106
|
// Reactive ModifyKey retry
|
|
84
107
|
if (!result.successful && result.messages?.some(m => isModifyKeyError(m))) {
|
|
85
108
|
const retryMK = await handleModifyKeyError();
|
|
86
109
|
if (retryMK.cancel) { log.info('Submission cancelled'); return; }
|
|
87
110
|
extraParams['_modify_key'] = retryMK.modifyKey;
|
|
88
|
-
|
|
89
|
-
result = await client.postUrlEncoded('/api/input/submit', body);
|
|
111
|
+
result = await submit();
|
|
90
112
|
}
|
|
91
113
|
|
|
92
114
|
// Retry with prompted params if needed (ticket, user, repo mismatch)
|
|
@@ -101,8 +123,7 @@ const deployCmd = new Command('deploy')
|
|
|
101
123
|
}
|
|
102
124
|
const params = errorResult.retryParams || errorResult;
|
|
103
125
|
Object.assign(extraParams, params);
|
|
104
|
-
|
|
105
|
-
result = await client.postUrlEncoded('/api/input/submit', body);
|
|
126
|
+
result = await submit();
|
|
106
127
|
}
|
|
107
128
|
|
|
108
129
|
formatResponse(result, { json: options.json });
|
package/src/commands/deploy.js
CHANGED
|
@@ -85,10 +85,12 @@ export const deployCommand = new Command('deploy')
|
|
|
85
85
|
continue;
|
|
86
86
|
}
|
|
87
87
|
|
|
88
|
-
const
|
|
89
|
-
const
|
|
88
|
+
const isMultipart = entry.multipart === true;
|
|
89
|
+
const entity = entry.entity || (isMultipart ? 'media' : 'content');
|
|
90
|
+
const column = entry.column || (isMultipart ? 'File' : 'Content');
|
|
90
91
|
const uid = entry.uid;
|
|
91
92
|
const file = entry.file;
|
|
93
|
+
const filename = entry.filename || file.split('/').pop();
|
|
92
94
|
|
|
93
95
|
if (!uid || !file) {
|
|
94
96
|
log.warn(`Skipping "${entryName}": missing uid or file.`);
|
|
@@ -101,7 +103,9 @@ export const deployCommand = new Command('deploy')
|
|
|
101
103
|
if (options.ticket) extraParams['_OverrideTicketID'] = options.ticket;
|
|
102
104
|
if (activeModifyKey) extraParams['_modify_key'] = activeModifyKey;
|
|
103
105
|
|
|
104
|
-
const dataExprs =
|
|
106
|
+
const dataExprs = isMultipart
|
|
107
|
+
? [`RowUID:${uid};column:${entity}.Filename=${filename}`]
|
|
108
|
+
: [`RowUID:${uid};column:${entity}.${column}@${file}`];
|
|
105
109
|
|
|
106
110
|
// Apply stored ticket if no --ticket flag
|
|
107
111
|
if (!options.ticket) {
|
|
@@ -112,8 +116,29 @@ export const deployCommand = new Command('deploy')
|
|
|
112
116
|
}
|
|
113
117
|
await applyStoredTicketToSubmission(dataExprs, entity, uid, uid, options, sessionTicketOverride);
|
|
114
118
|
|
|
115
|
-
|
|
116
|
-
|
|
119
|
+
// Submit helper — handles both URL-encoded and multipart modes
|
|
120
|
+
async function submit() {
|
|
121
|
+
if (isMultipart) {
|
|
122
|
+
const fields = { ...extraParams };
|
|
123
|
+
for (const expr of dataExprs) {
|
|
124
|
+
const eqIdx = expr.indexOf('=');
|
|
125
|
+
if (eqIdx !== -1) {
|
|
126
|
+
fields[expr.substring(0, eqIdx)] = expr.substring(eqIdx + 1);
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
const files = [{
|
|
130
|
+
fieldName: `RowUID:${uid};column:${entity}.${column}`,
|
|
131
|
+
filePath: file,
|
|
132
|
+
fileName: file.split('/').pop(),
|
|
133
|
+
}];
|
|
134
|
+
return client.postMultipart('/api/input/submit', fields, files);
|
|
135
|
+
} else {
|
|
136
|
+
const body = await buildInputBody(dataExprs, extraParams);
|
|
137
|
+
return client.postUrlEncoded('/api/input/submit', body);
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
let result = await submit();
|
|
117
142
|
|
|
118
143
|
// Reactive ModifyKey retry
|
|
119
144
|
if (!result.successful && result.messages?.some(m => isModifyKeyError(m))) {
|
|
@@ -121,8 +146,7 @@ export const deployCommand = new Command('deploy')
|
|
|
121
146
|
if (retryMK.cancel) { log.info('Submission cancelled'); break; }
|
|
122
147
|
activeModifyKey = retryMK.modifyKey;
|
|
123
148
|
extraParams['_modify_key'] = activeModifyKey;
|
|
124
|
-
|
|
125
|
-
result = await client.postUrlEncoded('/api/input/submit', body);
|
|
149
|
+
result = await submit();
|
|
126
150
|
}
|
|
127
151
|
|
|
128
152
|
// Retry with prompted params if needed (ticket, user, repo mismatch)
|
|
@@ -141,8 +165,7 @@ export const deployCommand = new Command('deploy')
|
|
|
141
165
|
}
|
|
142
166
|
const params = errorResult.retryParams || errorResult;
|
|
143
167
|
Object.assign(extraParams, params);
|
|
144
|
-
|
|
145
|
-
result = await client.postUrlEncoded('/api/input/submit', body);
|
|
168
|
+
result = await submit();
|
|
146
169
|
}
|
|
147
170
|
|
|
148
171
|
if (result.successful) {
|