@wcstack/upload 4.7.0 → 4.9.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/README.ja.md +30 -2
- package/README.md +30 -2
- package/dist/auto.min.js +1 -1
- package/dist/auto.min.js.map +1 -1
- package/dist/index.d.ts +35 -1
- package/dist/index.esm.js +99 -5
- package/dist/index.esm.js.map +1 -1
- package/package.json +2 -1
package/dist/index.esm.js
CHANGED
|
@@ -3,6 +3,7 @@ const _config = {
|
|
|
3
3
|
triggerAttribute: "data-uploadtarget",
|
|
4
4
|
tagNames: {
|
|
5
5
|
upload: "wcs-upload",
|
|
6
|
+
uploadHeader: "wcs-upload-header",
|
|
6
7
|
},
|
|
7
8
|
};
|
|
8
9
|
function deepFreeze(obj) {
|
|
@@ -967,9 +968,11 @@ class WcsUpload extends HTMLElement {
|
|
|
967
968
|
_core;
|
|
968
969
|
_files = null;
|
|
969
970
|
_trigger = false;
|
|
970
|
-
// The reasons `[wcs/command-not-ready]` was said for, once each
|
|
971
|
-
// (docs/v4-direction-2026-10.md §5.1, the I/O command policy).
|
|
971
|
+
// The reasons `[wcs/command-not-ready]` was said for in this outage, once each
|
|
972
|
+
// (docs/v4-direction-2026-10.md §5.1, the I/O command policy); an upload starting clears them.
|
|
972
973
|
_told = null;
|
|
974
|
+
// `[wcs/upload-helper-undefined]` was said for this element (once per element, as fetch's)
|
|
975
|
+
_toldUndefinedHelper = false;
|
|
973
976
|
// automatic-mode files assigned while there was no url: sent when the url arrives
|
|
974
977
|
_waitingForUrl = false;
|
|
975
978
|
_connectedCallbackPromise = Promise.resolve();
|
|
@@ -1212,9 +1215,22 @@ class WcsUpload extends HTMLElement {
|
|
|
1212
1215
|
this._core.setError(validationError);
|
|
1213
1216
|
return null;
|
|
1214
1217
|
}
|
|
1218
|
+
// ready again (an upload starts): a refusal in the next outage is said again
|
|
1219
|
+
this._told = null;
|
|
1220
|
+
// the <wcs-upload-header> elements inside, read now: a header bound from state goes out with
|
|
1221
|
+
// the value it has when the upload starts, not the one it had when the element connected
|
|
1222
|
+
const headers = this._collectHeaders();
|
|
1223
|
+
// An upload is always multipart/form-data: a manual Content-Type drops the boundary the
|
|
1224
|
+
// browser adds, and the server cannot read the parts. Sent as written (as fetch does), but said.
|
|
1225
|
+
if (Object.keys(headers).some((name) => name.toLowerCase() === "content-type")) {
|
|
1226
|
+
console.warn("[@wcstack/upload] A Content-Type header was set on an upload. An upload is sent as " +
|
|
1227
|
+
"multipart/form-data, and a manual Content-Type drops the boundary the browser adds; " +
|
|
1228
|
+
`remove the Content-Type <${config.tagNames.uploadHeader}>.`, this);
|
|
1229
|
+
}
|
|
1215
1230
|
const result = await this._core.upload(this.url, files, {
|
|
1216
1231
|
method: this.method,
|
|
1217
1232
|
fieldName: this.fieldName,
|
|
1233
|
+
headers,
|
|
1218
1234
|
});
|
|
1219
1235
|
// 自分が開始したアップロードのファイルだけをリセット
|
|
1220
1236
|
// (途中で新しい files がセットされていたら触らない)
|
|
@@ -1227,16 +1243,48 @@ class WcsUpload extends HTMLElement {
|
|
|
1227
1243
|
}
|
|
1228
1244
|
return result;
|
|
1229
1245
|
}
|
|
1246
|
+
_collectHeaders() {
|
|
1247
|
+
const headers = {};
|
|
1248
|
+
const headerElements = this.querySelectorAll(config.tagNames.uploadHeader);
|
|
1249
|
+
for (const el of headerElements) {
|
|
1250
|
+
if (typeof el.hasHeader !== "boolean") {
|
|
1251
|
+
this._warnUndefinedHelper(config.tagNames.uploadHeader);
|
|
1252
|
+
continue;
|
|
1253
|
+
}
|
|
1254
|
+
// a header without a value attribute is not sent (WcsUploadHeader)
|
|
1255
|
+
if (el.hasHeader) {
|
|
1256
|
+
headers[el.name] = el.value;
|
|
1257
|
+
}
|
|
1258
|
+
}
|
|
1259
|
+
return headers;
|
|
1260
|
+
}
|
|
1261
|
+
/**
|
|
1262
|
+
* A `<wcs-upload-header>` whose definition never loaded is a plain element, and its header would
|
|
1263
|
+
* be left out of the upload without a word: a page that defines the tags itself (an autoloader's
|
|
1264
|
+
* wrapper module, a scoped registry) defined `<wcs-upload>` only — fetch's
|
|
1265
|
+
* `[wcs/fetch-helper-undefined]` (docs/seam-apps.md, fw-inventory). Said once per element.
|
|
1266
|
+
*/
|
|
1267
|
+
_warnUndefinedHelper(tag) {
|
|
1268
|
+
if (this._toldUndefinedHelper)
|
|
1269
|
+
return;
|
|
1270
|
+
this._toldUndefinedHelper = true;
|
|
1271
|
+
console.warn(`[@wcstack/upload] [wcs/upload-helper-undefined] <${tag}> inside this <${config.tagNames.upload}> is not ` +
|
|
1272
|
+
"defined, so its header is not sent. Load @wcstack/upload/auto, or define WcsUploadHeader with WcsUpload " +
|
|
1273
|
+
"when the page defines the tags itself. (Said once per element.)", this);
|
|
1274
|
+
}
|
|
1230
1275
|
// A refused upload sent nothing and said nothing (no `error`, by design): a `trigger`
|
|
1231
1276
|
// written before `url` / `files` (`data-wcs` bindings and a framework's props are applied in
|
|
1232
|
-
// the order written), a retry after the files were used up.
|
|
1277
|
+
// the order written), a retry after the files were used up. Said once per reason and outage:
|
|
1278
|
+
// once per element was once per page life — a route puts the same element back on every
|
|
1279
|
+
// entry, so the next outage went unsaid (docs/seam-apps.md, shift-desk).
|
|
1233
1280
|
_warnNotReady(reason) {
|
|
1234
1281
|
if (this._told?.has(reason))
|
|
1235
1282
|
return;
|
|
1236
1283
|
(this._told ??= new Set()).add(reason);
|
|
1237
1284
|
console.warn(`[@wcstack/upload] [wcs/command-not-ready] The upload was refused: ${reason}, so nothing is sent. ` +
|
|
1238
1285
|
"Write url and files before trigger (data-wcs bindings and a framework's props are applied in the order " +
|
|
1239
|
-
"written), and assign files again for each retry: an upload uses them up.
|
|
1286
|
+
"written), and assign files again for each retry: an upload uses them up. " +
|
|
1287
|
+
"(Said once per reason until an upload is sent again.)", this);
|
|
1240
1288
|
}
|
|
1241
1289
|
// --- Lifecycle ---
|
|
1242
1290
|
attributeChangedCallback(_name, _oldValue, newValue) {
|
|
@@ -1263,6 +1311,49 @@ class WcsUpload extends HTMLElement {
|
|
|
1263
1311
|
}
|
|
1264
1312
|
}
|
|
1265
1313
|
|
|
1314
|
+
/**
|
|
1315
|
+
* `<wcs-upload-header name value>`: one request header of the `<wcs-upload>` it sits in, read when
|
|
1316
|
+
* an upload starts — the same shape as `@wcstack/fetch`'s `<wcs-fetch-header>`. `name` / `value`
|
|
1317
|
+
* are properties too, reflected to the attributes (`null` removes one, `undefined` restores the
|
|
1318
|
+
* markup's), so a binding — `data-wcs="value: authHeader"` — sets the header. Without a `value`
|
|
1319
|
+
* attribute the header is not sent: a token that is not there yet sends no `Authorization` instead
|
|
1320
|
+
* of an empty one. Before this, `<wcs-upload>` sent no header at all, and an API that wants
|
|
1321
|
+
* `Authorization` on every request could only be reached through `UploadCore` (docs/seam-apps.md,
|
|
1322
|
+
* family-ledger).
|
|
1323
|
+
*
|
|
1324
|
+
* It declares no `wcBindable`: it is part of `<wcs-upload>`'s markup, not an I/O node of its own.
|
|
1325
|
+
*/
|
|
1326
|
+
class WcsUploadHeader extends HTMLElement {
|
|
1327
|
+
connectedCallback() {
|
|
1328
|
+
// A value assigned before the element was upgraded sits on the instance and hides the
|
|
1329
|
+
// accessor: pass it through the setter (the upgrade-properties pattern, for two members).
|
|
1330
|
+
for (const key of ["name", "value"]) {
|
|
1331
|
+
if (Object.prototype.hasOwnProperty.call(this, key)) {
|
|
1332
|
+
const value = this[key];
|
|
1333
|
+
delete this[key];
|
|
1334
|
+
this[key] = value;
|
|
1335
|
+
}
|
|
1336
|
+
}
|
|
1337
|
+
this.style.display = "none";
|
|
1338
|
+
}
|
|
1339
|
+
get name() {
|
|
1340
|
+
return this.getAttribute("name") ?? "";
|
|
1341
|
+
}
|
|
1342
|
+
set name(value) {
|
|
1343
|
+
reflectAttribute(this, "name", value);
|
|
1344
|
+
}
|
|
1345
|
+
get value() {
|
|
1346
|
+
return this.getAttribute("value") ?? "";
|
|
1347
|
+
}
|
|
1348
|
+
set value(value) {
|
|
1349
|
+
reflectAttribute(this, "value", value);
|
|
1350
|
+
}
|
|
1351
|
+
/** Whether the header is sent: it has a name and a `value` attribute (an empty one included). */
|
|
1352
|
+
get hasHeader() {
|
|
1353
|
+
return this.name !== "" && this.hasAttribute("value");
|
|
1354
|
+
}
|
|
1355
|
+
}
|
|
1356
|
+
|
|
1266
1357
|
/**
|
|
1267
1358
|
* Register this package's tags. Pass a scoped `CustomElementRegistry` to define
|
|
1268
1359
|
* them for a single shadow tree -- scoped registries do not inherit the global
|
|
@@ -1272,6 +1363,9 @@ function registerComponents(registry = customElements) {
|
|
|
1272
1363
|
if (!registry.get(config.tagNames.upload)) {
|
|
1273
1364
|
registry.define(config.tagNames.upload, WcsUpload);
|
|
1274
1365
|
}
|
|
1366
|
+
if (!registry.get(config.tagNames.uploadHeader)) {
|
|
1367
|
+
registry.define(config.tagNames.uploadHeader, WcsUploadHeader);
|
|
1368
|
+
}
|
|
1275
1369
|
}
|
|
1276
1370
|
|
|
1277
1371
|
function bootstrapUpload(userConfig, registry) {
|
|
@@ -1281,5 +1375,5 @@ function bootstrapUpload(userConfig, registry) {
|
|
|
1281
1375
|
registerComponents(registry);
|
|
1282
1376
|
}
|
|
1283
1377
|
|
|
1284
|
-
export { UploadCore, WCS_UPLOAD_ERROR_CODE, WcsUpload, bootstrapUpload, getConfig };
|
|
1378
|
+
export { UploadCore, WCS_UPLOAD_ERROR_CODE, WcsUpload, WcsUploadHeader, bootstrapUpload, getConfig };
|
|
1285
1379
|
//# sourceMappingURL=index.esm.js.map
|