@anvilkit/plugin-asset-manager 0.1.1
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 +159 -0
- package/dist/adapters/data-url.cjs +78 -0
- package/dist/adapters/data-url.d.cts +6 -0
- package/dist/adapters/data-url.d.cts.map +1 -0
- package/dist/adapters/data-url.d.ts +6 -0
- package/dist/adapters/data-url.d.ts.map +1 -0
- package/dist/adapters/data-url.js +44 -0
- package/dist/adapters/extract-image-dimensions.cjs +69 -0
- package/dist/adapters/extract-image-dimensions.d.cts +21 -0
- package/dist/adapters/extract-image-dimensions.d.cts.map +1 -0
- package/dist/adapters/extract-image-dimensions.d.ts +21 -0
- package/dist/adapters/extract-image-dimensions.d.ts.map +1 -0
- package/dist/adapters/extract-image-dimensions.js +35 -0
- package/dist/adapters/in-memory.cjs +62 -0
- package/dist/adapters/in-memory.d.cts +3 -0
- package/dist/adapters/in-memory.d.cts.map +1 -0
- package/dist/adapters/in-memory.d.ts +3 -0
- package/dist/adapters/in-memory.d.ts.map +1 -0
- package/dist/adapters/in-memory.js +28 -0
- package/dist/adapters/s3-presigned.cjs +166 -0
- package/dist/adapters/s3-presigned.d.cts +59 -0
- package/dist/adapters/s3-presigned.d.cts.map +1 -0
- package/dist/adapters/s3-presigned.d.ts +59 -0
- package/dist/adapters/s3-presigned.d.ts.map +1 -0
- package/dist/adapters/s3-presigned.js +129 -0
- package/dist/asset-reference.cjs +38 -0
- package/dist/asset-reference.d.cts +10 -0
- package/dist/asset-reference.d.cts.map +1 -0
- package/dist/asset-reference.d.ts +10 -0
- package/dist/asset-reference.d.ts.map +1 -0
- package/dist/asset-reference.js +4 -0
- package/dist/csp.cjs +83 -0
- package/dist/csp.d.cts +45 -0
- package/dist/csp.d.cts.map +1 -0
- package/dist/csp.d.ts +45 -0
- package/dist/csp.d.ts.map +1 -0
- package/dist/csp.js +49 -0
- package/dist/errors.cjs +58 -0
- package/dist/errors.d.cts +15 -0
- package/dist/errors.d.cts.map +1 -0
- package/dist/errors.d.ts +15 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/errors.js +21 -0
- package/dist/header-action.cjs +44 -0
- package/dist/header-action.d.cts +3 -0
- package/dist/header-action.d.cts.map +1 -0
- package/dist/header-action.d.ts +3 -0
- package/dist/header-action.d.ts.map +1 -0
- package/dist/header-action.js +10 -0
- package/dist/index.cjs +90 -0
- package/dist/index.d.cts +18 -0
- package/dist/index.d.cts.map +1 -0
- package/dist/index.d.ts +18 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +10 -0
- package/dist/infer-kind.cjs +45 -0
- package/dist/infer-kind.d.cts +8 -0
- package/dist/infer-kind.d.cts.map +1 -0
- package/dist/infer-kind.d.ts +8 -0
- package/dist/infer-kind.d.ts.map +1 -0
- package/dist/infer-kind.js +11 -0
- package/dist/plugin.cjs +258 -0
- package/dist/plugin.d.cts +9 -0
- package/dist/plugin.d.cts.map +1 -0
- package/dist/plugin.d.ts +9 -0
- package/dist/plugin.d.ts.map +1 -0
- package/dist/plugin.js +212 -0
- package/dist/registry.cjs +198 -0
- package/dist/registry.d.cts +3 -0
- package/dist/registry.d.cts.map +1 -0
- package/dist/registry.d.ts +3 -0
- package/dist/registry.d.ts.map +1 -0
- package/dist/registry.js +164 -0
- package/dist/resolver.cjs +185 -0
- package/dist/resolver.d.cts +10 -0
- package/dist/resolver.d.cts.map +1 -0
- package/dist/resolver.d.ts +10 -0
- package/dist/resolver.d.ts.map +1 -0
- package/dist/resolver.js +148 -0
- package/dist/retry.cjs +123 -0
- package/dist/retry.d.cts +71 -0
- package/dist/retry.d.cts.map +1 -0
- package/dist/retry.d.ts +71 -0
- package/dist/retry.d.ts.map +1 -0
- package/dist/retry.js +86 -0
- package/dist/studio-asset-source.cjs +211 -0
- package/dist/studio-asset-source.d.cts +52 -0
- package/dist/studio-asset-source.d.cts.map +1 -0
- package/dist/studio-asset-source.d.ts +52 -0
- package/dist/studio-asset-source.d.ts.map +1 -0
- package/dist/studio-asset-source.js +171 -0
- package/dist/testing/index.cjs +66 -0
- package/dist/testing/index.d.cts +24 -0
- package/dist/testing/index.d.cts.map +1 -0
- package/dist/testing/index.d.ts +24 -0
- package/dist/testing/index.d.ts.map +1 -0
- package/dist/testing/index.js +29 -0
- package/dist/types.cjs +18 -0
- package/dist/types.d.cts +132 -0
- package/dist/types.d.cts.map +1 -0
- package/dist/types.d.ts +132 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +0 -0
- package/dist/ui/AssetBrowser.cjs +271 -0
- package/dist/ui/AssetBrowser.d.cts +45 -0
- package/dist/ui/AssetBrowser.d.cts.map +1 -0
- package/dist/ui/AssetBrowser.d.ts +45 -0
- package/dist/ui/AssetBrowser.d.ts.map +1 -0
- package/dist/ui/AssetBrowser.js +237 -0
- package/dist/ui/AssetCommandPalette.cjs +135 -0
- package/dist/ui/AssetCommandPalette.d.cts +21 -0
- package/dist/ui/AssetCommandPalette.d.cts.map +1 -0
- package/dist/ui/AssetCommandPalette.d.ts +21 -0
- package/dist/ui/AssetCommandPalette.d.ts.map +1 -0
- package/dist/ui/AssetCommandPalette.js +101 -0
- package/dist/ui/AssetManagerUI.cjs +169 -0
- package/dist/ui/AssetManagerUI.d.cts +15 -0
- package/dist/ui/AssetManagerUI.d.cts.map +1 -0
- package/dist/ui/AssetManagerUI.d.ts +15 -0
- package/dist/ui/AssetManagerUI.d.ts.map +1 -0
- package/dist/ui/AssetManagerUI.js +135 -0
- package/dist/ui/DeleteAssetDialog.cjs +70 -0
- package/dist/ui/DeleteAssetDialog.d.cts +22 -0
- package/dist/ui/DeleteAssetDialog.d.cts.map +1 -0
- package/dist/ui/DeleteAssetDialog.d.ts +22 -0
- package/dist/ui/DeleteAssetDialog.d.ts.map +1 -0
- package/dist/ui/DeleteAssetDialog.js +36 -0
- package/dist/ui/MetadataPanel.cjs +147 -0
- package/dist/ui/MetadataPanel.d.cts +21 -0
- package/dist/ui/MetadataPanel.d.cts.map +1 -0
- package/dist/ui/MetadataPanel.d.ts +21 -0
- package/dist/ui/MetadataPanel.d.ts.map +1 -0
- package/dist/ui/MetadataPanel.js +113 -0
- package/dist/ui/ReplaceAssetDialog.cjs +125 -0
- package/dist/ui/ReplaceAssetDialog.d.cts +14 -0
- package/dist/ui/ReplaceAssetDialog.d.cts.map +1 -0
- package/dist/ui/ReplaceAssetDialog.d.ts +14 -0
- package/dist/ui/ReplaceAssetDialog.d.ts.map +1 -0
- package/dist/ui/ReplaceAssetDialog.js +91 -0
- package/dist/ui/UploadButton.cjs +189 -0
- package/dist/ui/UploadButton.d.cts +17 -0
- package/dist/ui/UploadButton.d.cts.map +1 -0
- package/dist/ui/UploadButton.d.ts +17 -0
- package/dist/ui/UploadButton.d.ts.map +1 -0
- package/dist/ui/UploadButton.js +155 -0
- package/dist/ui/index.cjs +60 -0
- package/dist/ui/index.d.cts +15 -0
- package/dist/ui/index.d.cts.map +1 -0
- package/dist/ui/index.d.ts +15 -0
- package/dist/ui/index.d.ts.map +1 -0
- package/dist/ui/index.js +7 -0
- package/dist/validate-upload-result.cjs +149 -0
- package/dist/validate-upload-result.d.cts +9 -0
- package/dist/validate-upload-result.d.cts.map +1 -0
- package/dist/validate-upload-result.d.ts +9 -0
- package/dist/validate-upload-result.d.ts.map +1 -0
- package/dist/validate-upload-result.js +115 -0
- package/package.json +131 -0
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
import { Button } from "@anvilkit/ui/button";
|
|
2
|
+
import { validateSelectedFile } from "../plugin.js";
|
|
3
|
+
import { validateUploadResult } from "../validate-upload-result.js";
|
|
4
|
+
import * as __rspack_external_react from "react";
|
|
5
|
+
function UploadButton({ acceptedMimeTypes, allowMixedScriptHostnames, dataUrlAllowlistOptIn, maxFileSize, onError, onProgress, onUploaded, uploader }) {
|
|
6
|
+
const inputRef = __rspack_external_react.useRef(null);
|
|
7
|
+
const [errorMessage, setErrorMessage] = __rspack_external_react.useState(null);
|
|
8
|
+
const [batch, setBatch] = __rspack_external_react.useState(null);
|
|
9
|
+
const [isDragOver, setIsDragOver] = __rspack_external_react.useState(false);
|
|
10
|
+
const isUploading = null !== batch;
|
|
11
|
+
const acceptAttr = __rspack_external_react.useMemo(()=>acceptedMimeTypes?.join(","), [
|
|
12
|
+
acceptedMimeTypes
|
|
13
|
+
]);
|
|
14
|
+
async function processFiles(files) {
|
|
15
|
+
if (0 === files.length) return;
|
|
16
|
+
const total = files.length;
|
|
17
|
+
setErrorMessage(null);
|
|
18
|
+
const initial = {
|
|
19
|
+
completed: 0,
|
|
20
|
+
total
|
|
21
|
+
};
|
|
22
|
+
setBatch(initial);
|
|
23
|
+
onProgress?.(initial);
|
|
24
|
+
let lastError = null;
|
|
25
|
+
for(let index = 0; index < files.length; index += 1){
|
|
26
|
+
const file = files[index];
|
|
27
|
+
if (file) try {
|
|
28
|
+
validateSelectedFile(file, {
|
|
29
|
+
acceptedMimeTypes,
|
|
30
|
+
maxFileSize
|
|
31
|
+
});
|
|
32
|
+
const uploaded = await uploader(file);
|
|
33
|
+
const validated = validateUploadResult({
|
|
34
|
+
...uploaded,
|
|
35
|
+
meta: {
|
|
36
|
+
size: file.size,
|
|
37
|
+
...file.type ? {
|
|
38
|
+
mimeType: file.type
|
|
39
|
+
} : {},
|
|
40
|
+
...uploaded.meta ?? {}
|
|
41
|
+
}
|
|
42
|
+
}, {
|
|
43
|
+
dataUrlAllowlistOptIn,
|
|
44
|
+
allowMixedScriptHostnames
|
|
45
|
+
});
|
|
46
|
+
onUploaded?.(validated);
|
|
47
|
+
} catch (error) {
|
|
48
|
+
lastError = error instanceof Error ? error.message : String(error);
|
|
49
|
+
onError?.(error);
|
|
50
|
+
} finally{
|
|
51
|
+
const next = {
|
|
52
|
+
completed: index + 1,
|
|
53
|
+
total
|
|
54
|
+
};
|
|
55
|
+
setBatch(next);
|
|
56
|
+
onProgress?.(next);
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
if (null !== lastError) setErrorMessage(lastError);
|
|
60
|
+
setBatch(null);
|
|
61
|
+
onProgress?.(null);
|
|
62
|
+
}
|
|
63
|
+
async function handleChange(event) {
|
|
64
|
+
const list = event.currentTarget.files;
|
|
65
|
+
const picked = list ? Array.from(list) : [];
|
|
66
|
+
try {
|
|
67
|
+
await processFiles(picked);
|
|
68
|
+
} finally{
|
|
69
|
+
if (inputRef.current) inputRef.current.value = "";
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
function handleDragEnter(event) {
|
|
73
|
+
event.preventDefault();
|
|
74
|
+
event.stopPropagation();
|
|
75
|
+
if (event.dataTransfer?.types?.includes("Files")) setIsDragOver(true);
|
|
76
|
+
}
|
|
77
|
+
function handleDragOver(event) {
|
|
78
|
+
event.preventDefault();
|
|
79
|
+
event.stopPropagation();
|
|
80
|
+
if (event.dataTransfer) event.dataTransfer.dropEffect = "copy";
|
|
81
|
+
}
|
|
82
|
+
function handleDragLeave(event) {
|
|
83
|
+
event.preventDefault();
|
|
84
|
+
event.stopPropagation();
|
|
85
|
+
setIsDragOver(false);
|
|
86
|
+
}
|
|
87
|
+
async function handleDrop(event) {
|
|
88
|
+
event.preventDefault();
|
|
89
|
+
event.stopPropagation();
|
|
90
|
+
setIsDragOver(false);
|
|
91
|
+
const files = event.dataTransfer?.files ? Array.from(event.dataTransfer.files) : [];
|
|
92
|
+
await processFiles(files);
|
|
93
|
+
}
|
|
94
|
+
const statusMessage = errorMessage ?? (null !== batch ? `Uploading ${Math.min(batch.completed + 1, batch.total)} of ${batch.total}…` : "Accepted files upload through the configured adapter.");
|
|
95
|
+
return /*#__PURE__*/ __rspack_external_react.createElement("div", {
|
|
96
|
+
"data-asset-manager-drop-zone": true,
|
|
97
|
+
"data-drag-over": isDragOver ? "true" : void 0,
|
|
98
|
+
onDragEnter: handleDragEnter,
|
|
99
|
+
onDragLeave: handleDragLeave,
|
|
100
|
+
onDragOver: handleDragOver,
|
|
101
|
+
onDrop: (event)=>{
|
|
102
|
+
handleDrop(event);
|
|
103
|
+
},
|
|
104
|
+
tabIndex: -1
|
|
105
|
+
}, /*#__PURE__*/ __rspack_external_react.createElement("input", {
|
|
106
|
+
accept: acceptAttr,
|
|
107
|
+
multiple: true,
|
|
108
|
+
onChange: (event)=>{
|
|
109
|
+
handleChange(event);
|
|
110
|
+
},
|
|
111
|
+
ref: inputRef,
|
|
112
|
+
style: {
|
|
113
|
+
display: "none"
|
|
114
|
+
},
|
|
115
|
+
type: "file"
|
|
116
|
+
}), /*#__PURE__*/ __rspack_external_react.createElement(Button, {
|
|
117
|
+
"aria-label": "Upload asset file",
|
|
118
|
+
disabled: isUploading,
|
|
119
|
+
onClick: ()=>{
|
|
120
|
+
inputRef.current?.click();
|
|
121
|
+
},
|
|
122
|
+
type: "button",
|
|
123
|
+
variant: "outline"
|
|
124
|
+
}, isUploading ? /*#__PURE__*/ __rspack_external_react.createElement(UploadSpinner, null) : null, /*#__PURE__*/ __rspack_external_react.createElement("span", null, isUploading ? "Uploading…" : "Upload asset")), /*#__PURE__*/ __rspack_external_react.createElement("p", {
|
|
125
|
+
"aria-live": "polite",
|
|
126
|
+
role: "status"
|
|
127
|
+
}, statusMessage));
|
|
128
|
+
}
|
|
129
|
+
function UploadSpinner() {
|
|
130
|
+
return /*#__PURE__*/ __rspack_external_react.createElement("svg", {
|
|
131
|
+
"aria-hidden": true,
|
|
132
|
+
fill: "none",
|
|
133
|
+
height: 14,
|
|
134
|
+
style: {
|
|
135
|
+
display: "inline-block",
|
|
136
|
+
marginRight: 6,
|
|
137
|
+
animation: "spin 1s linear infinite"
|
|
138
|
+
},
|
|
139
|
+
viewBox: "0 0 24 24",
|
|
140
|
+
width: 14
|
|
141
|
+
}, /*#__PURE__*/ __rspack_external_react.createElement("circle", {
|
|
142
|
+
cx: "12",
|
|
143
|
+
cy: "12",
|
|
144
|
+
opacity: "0.25",
|
|
145
|
+
r: "10",
|
|
146
|
+
stroke: "currentColor",
|
|
147
|
+
strokeWidth: "4"
|
|
148
|
+
}), /*#__PURE__*/ __rspack_external_react.createElement("path", {
|
|
149
|
+
d: "M4 12a8 8 0 0 1 8-8",
|
|
150
|
+
stroke: "currentColor",
|
|
151
|
+
strokeLinecap: "round",
|
|
152
|
+
strokeWidth: "4"
|
|
153
|
+
}));
|
|
154
|
+
}
|
|
155
|
+
export { UploadButton };
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __webpack_require__ = {};
|
|
3
|
+
(()=>{
|
|
4
|
+
__webpack_require__.d = (exports1, definition)=>{
|
|
5
|
+
for(var key in definition)if (__webpack_require__.o(definition, key) && !__webpack_require__.o(exports1, key)) Object.defineProperty(exports1, key, {
|
|
6
|
+
enumerable: true,
|
|
7
|
+
get: definition[key]
|
|
8
|
+
});
|
|
9
|
+
};
|
|
10
|
+
})();
|
|
11
|
+
(()=>{
|
|
12
|
+
__webpack_require__.o = (obj, prop)=>Object.prototype.hasOwnProperty.call(obj, prop);
|
|
13
|
+
})();
|
|
14
|
+
(()=>{
|
|
15
|
+
__webpack_require__.r = (exports1)=>{
|
|
16
|
+
if ("u" > typeof Symbol && Symbol.toStringTag) Object.defineProperty(exports1, Symbol.toStringTag, {
|
|
17
|
+
value: 'Module'
|
|
18
|
+
});
|
|
19
|
+
Object.defineProperty(exports1, '__esModule', {
|
|
20
|
+
value: true
|
|
21
|
+
});
|
|
22
|
+
};
|
|
23
|
+
})();
|
|
24
|
+
var __webpack_exports__ = {};
|
|
25
|
+
__webpack_require__.r(__webpack_exports__);
|
|
26
|
+
__webpack_require__.d(__webpack_exports__, {
|
|
27
|
+
MetadataPanel: ()=>external_MetadataPanel_cjs_namespaceObject.MetadataPanel,
|
|
28
|
+
DeleteAssetDialog: ()=>external_DeleteAssetDialog_cjs_namespaceObject.DeleteAssetDialog,
|
|
29
|
+
AssetCommandPalette: ()=>external_AssetCommandPalette_cjs_namespaceObject.AssetCommandPalette,
|
|
30
|
+
UploadButton: ()=>external_UploadButton_cjs_namespaceObject.UploadButton,
|
|
31
|
+
AssetBrowser: ()=>external_AssetBrowser_cjs_namespaceObject.AssetBrowser,
|
|
32
|
+
AssetManagerUI: ()=>external_AssetManagerUI_cjs_namespaceObject.AssetManagerUI,
|
|
33
|
+
ReplaceAssetDialog: ()=>external_ReplaceAssetDialog_cjs_namespaceObject.ReplaceAssetDialog
|
|
34
|
+
});
|
|
35
|
+
const external_AssetBrowser_cjs_namespaceObject = require("./AssetBrowser.cjs");
|
|
36
|
+
const external_AssetCommandPalette_cjs_namespaceObject = require("./AssetCommandPalette.cjs");
|
|
37
|
+
const external_AssetManagerUI_cjs_namespaceObject = require("./AssetManagerUI.cjs");
|
|
38
|
+
const external_DeleteAssetDialog_cjs_namespaceObject = require("./DeleteAssetDialog.cjs");
|
|
39
|
+
const external_MetadataPanel_cjs_namespaceObject = require("./MetadataPanel.cjs");
|
|
40
|
+
const external_ReplaceAssetDialog_cjs_namespaceObject = require("./ReplaceAssetDialog.cjs");
|
|
41
|
+
const external_UploadButton_cjs_namespaceObject = require("./UploadButton.cjs");
|
|
42
|
+
exports.AssetBrowser = __webpack_exports__.AssetBrowser;
|
|
43
|
+
exports.AssetCommandPalette = __webpack_exports__.AssetCommandPalette;
|
|
44
|
+
exports.AssetManagerUI = __webpack_exports__.AssetManagerUI;
|
|
45
|
+
exports.DeleteAssetDialog = __webpack_exports__.DeleteAssetDialog;
|
|
46
|
+
exports.MetadataPanel = __webpack_exports__.MetadataPanel;
|
|
47
|
+
exports.ReplaceAssetDialog = __webpack_exports__.ReplaceAssetDialog;
|
|
48
|
+
exports.UploadButton = __webpack_exports__.UploadButton;
|
|
49
|
+
for(var __rspack_i in __webpack_exports__)if (-1 === [
|
|
50
|
+
"AssetBrowser",
|
|
51
|
+
"AssetCommandPalette",
|
|
52
|
+
"AssetManagerUI",
|
|
53
|
+
"DeleteAssetDialog",
|
|
54
|
+
"MetadataPanel",
|
|
55
|
+
"ReplaceAssetDialog",
|
|
56
|
+
"UploadButton"
|
|
57
|
+
].indexOf(__rspack_i)) exports[__rspack_i] = __webpack_exports__[__rspack_i];
|
|
58
|
+
Object.defineProperty(exports, '__esModule', {
|
|
59
|
+
value: true
|
|
60
|
+
});
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
export type { AssetBrowserProps } from "./AssetBrowser.js";
|
|
2
|
+
export { AssetBrowser } from "./AssetBrowser.js";
|
|
3
|
+
export type { AssetCommandPaletteProps } from "./AssetCommandPalette.js";
|
|
4
|
+
export { AssetCommandPalette } from "./AssetCommandPalette.js";
|
|
5
|
+
export type { AssetManagerUIProps } from "./AssetManagerUI.js";
|
|
6
|
+
export { AssetManagerUI } from "./AssetManagerUI.js";
|
|
7
|
+
export type { DeleteAssetDialogProps } from "./DeleteAssetDialog.js";
|
|
8
|
+
export { DeleteAssetDialog } from "./DeleteAssetDialog.js";
|
|
9
|
+
export type { MetadataPanelProps } from "./MetadataPanel.js";
|
|
10
|
+
export { MetadataPanel } from "./MetadataPanel.js";
|
|
11
|
+
export type { ReplaceAssetDialogProps } from "./ReplaceAssetDialog.js";
|
|
12
|
+
export { ReplaceAssetDialog } from "./ReplaceAssetDialog.js";
|
|
13
|
+
export type { UploadButtonProps, UploadProgressSnapshot, } from "./UploadButton.js";
|
|
14
|
+
export { UploadButton } from "./UploadButton.js";
|
|
15
|
+
//# sourceMappingURL=index.d.cts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.cts","sourceRoot":"","sources":["../../src/ui/index.ts"],"names":[],"mappings":"AAAA,YAAY,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AAC3D,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AACjD,YAAY,EAAE,wBAAwB,EAAE,MAAM,0BAA0B,CAAC;AACzE,OAAO,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAC;AAC/D,YAAY,EAAE,mBAAmB,EAAE,MAAM,qBAAqB,CAAC;AAC/D,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AACrD,YAAY,EAAE,sBAAsB,EAAE,MAAM,wBAAwB,CAAC;AACrE,OAAO,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAC3D,YAAY,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;AAC7D,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACnD,YAAY,EAAE,uBAAuB,EAAE,MAAM,yBAAyB,CAAC;AACvE,OAAO,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AAC7D,YAAY,EACX,iBAAiB,EACjB,sBAAsB,GACtB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
export type { AssetBrowserProps } from "./AssetBrowser.js";
|
|
2
|
+
export { AssetBrowser } from "./AssetBrowser.js";
|
|
3
|
+
export type { AssetCommandPaletteProps } from "./AssetCommandPalette.js";
|
|
4
|
+
export { AssetCommandPalette } from "./AssetCommandPalette.js";
|
|
5
|
+
export type { AssetManagerUIProps } from "./AssetManagerUI.js";
|
|
6
|
+
export { AssetManagerUI } from "./AssetManagerUI.js";
|
|
7
|
+
export type { DeleteAssetDialogProps } from "./DeleteAssetDialog.js";
|
|
8
|
+
export { DeleteAssetDialog } from "./DeleteAssetDialog.js";
|
|
9
|
+
export type { MetadataPanelProps } from "./MetadataPanel.js";
|
|
10
|
+
export { MetadataPanel } from "./MetadataPanel.js";
|
|
11
|
+
export type { ReplaceAssetDialogProps } from "./ReplaceAssetDialog.js";
|
|
12
|
+
export { ReplaceAssetDialog } from "./ReplaceAssetDialog.js";
|
|
13
|
+
export type { UploadButtonProps, UploadProgressSnapshot, } from "./UploadButton.js";
|
|
14
|
+
export { UploadButton } from "./UploadButton.js";
|
|
15
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/ui/index.ts"],"names":[],"mappings":"AAAA,YAAY,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AAC3D,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AACjD,YAAY,EAAE,wBAAwB,EAAE,MAAM,0BAA0B,CAAC;AACzE,OAAO,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAC;AAC/D,YAAY,EAAE,mBAAmB,EAAE,MAAM,qBAAqB,CAAC;AAC/D,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AACrD,YAAY,EAAE,sBAAsB,EAAE,MAAM,wBAAwB,CAAC;AACrE,OAAO,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAC3D,YAAY,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;AAC7D,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACnD,YAAY,EAAE,uBAAuB,EAAE,MAAM,yBAAyB,CAAC;AACvE,OAAO,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AAC7D,YAAY,EACX,iBAAiB,EACjB,sBAAsB,GACtB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC"}
|
package/dist/ui/index.js
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export { AssetBrowser } from "./AssetBrowser.js";
|
|
2
|
+
export { AssetCommandPalette } from "./AssetCommandPalette.js";
|
|
3
|
+
export { AssetManagerUI } from "./AssetManagerUI.js";
|
|
4
|
+
export { DeleteAssetDialog } from "./DeleteAssetDialog.js";
|
|
5
|
+
export { MetadataPanel } from "./MetadataPanel.js";
|
|
6
|
+
export { ReplaceAssetDialog } from "./ReplaceAssetDialog.js";
|
|
7
|
+
export { UploadButton } from "./UploadButton.js";
|
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __webpack_require__ = {};
|
|
3
|
+
(()=>{
|
|
4
|
+
__webpack_require__.d = (exports1, definition)=>{
|
|
5
|
+
for(var key in definition)if (__webpack_require__.o(definition, key) && !__webpack_require__.o(exports1, key)) Object.defineProperty(exports1, key, {
|
|
6
|
+
enumerable: true,
|
|
7
|
+
get: definition[key]
|
|
8
|
+
});
|
|
9
|
+
};
|
|
10
|
+
})();
|
|
11
|
+
(()=>{
|
|
12
|
+
__webpack_require__.o = (obj, prop)=>Object.prototype.hasOwnProperty.call(obj, prop);
|
|
13
|
+
})();
|
|
14
|
+
(()=>{
|
|
15
|
+
__webpack_require__.r = (exports1)=>{
|
|
16
|
+
if ("u" > typeof Symbol && Symbol.toStringTag) Object.defineProperty(exports1, Symbol.toStringTag, {
|
|
17
|
+
value: 'Module'
|
|
18
|
+
});
|
|
19
|
+
Object.defineProperty(exports1, '__esModule', {
|
|
20
|
+
value: true
|
|
21
|
+
});
|
|
22
|
+
};
|
|
23
|
+
})();
|
|
24
|
+
var __webpack_exports__ = {};
|
|
25
|
+
__webpack_require__.r(__webpack_exports__);
|
|
26
|
+
__webpack_require__.d(__webpack_exports__, {
|
|
27
|
+
validateUploadResult: ()=>validateUploadResult
|
|
28
|
+
});
|
|
29
|
+
const external_errors_cjs_namespaceObject = require("./errors.cjs");
|
|
30
|
+
const ALWAYS_ALLOWED_SCHEMES = new Set([
|
|
31
|
+
"http",
|
|
32
|
+
"https",
|
|
33
|
+
"blob"
|
|
34
|
+
]);
|
|
35
|
+
const HARD_BLOCKED_SCHEMES = new Set([
|
|
36
|
+
"javascript",
|
|
37
|
+
"vbscript"
|
|
38
|
+
]);
|
|
39
|
+
function validateUploadResult(result, options = {}) {
|
|
40
|
+
if ("string" != typeof result.id || "" === result.id.trim()) throw new external_errors_cjs_namespaceObject.AssetValidationError("INVALID_UPLOAD_ID", "Upload adapter returned an empty asset id.");
|
|
41
|
+
const normalizedUrl = normalizeAllowedUrl(result.url, options);
|
|
42
|
+
const trimmedName = "string" == typeof result.name ? result.name.trim() : "";
|
|
43
|
+
const nextResult = {
|
|
44
|
+
id: result.id.trim(),
|
|
45
|
+
url: normalizedUrl,
|
|
46
|
+
..."" !== trimmedName ? {
|
|
47
|
+
name: trimmedName
|
|
48
|
+
} : {},
|
|
49
|
+
...result.meta ? {
|
|
50
|
+
meta: stripUndefinedMeta(result.meta)
|
|
51
|
+
} : {},
|
|
52
|
+
...result.tags && result.tags.length > 0 ? {
|
|
53
|
+
tags: Object.freeze([
|
|
54
|
+
...result.tags
|
|
55
|
+
])
|
|
56
|
+
} : {}
|
|
57
|
+
};
|
|
58
|
+
return Object.freeze(nextResult);
|
|
59
|
+
}
|
|
60
|
+
function normalizeAllowedUrl(input, options) {
|
|
61
|
+
const candidate = normalizeCandidate(input);
|
|
62
|
+
if (!candidate) throw new external_errors_cjs_namespaceObject.AssetValidationError("EMPTY_UPLOAD_URL", "Upload adapter returned an empty URL.");
|
|
63
|
+
if (candidate.startsWith("//")) throw new external_errors_cjs_namespaceObject.AssetValidationError("UNSCHEMED_UPLOAD_URL", "Upload adapter returned a scheme-less URL. Use an absolute URL with an allowed scheme.");
|
|
64
|
+
const sanitized = stripUnsafeAscii(candidate);
|
|
65
|
+
const schemeMatch = sanitized.match(/^([a-z][a-z0-9+.-]*):/i);
|
|
66
|
+
if (!schemeMatch) throw new external_errors_cjs_namespaceObject.AssetValidationError("UNSCHEMED_UPLOAD_URL", "Upload adapter returned a URL without a scheme.");
|
|
67
|
+
const scheme = schemeMatch[1]?.toLowerCase();
|
|
68
|
+
if (!scheme) throw new external_errors_cjs_namespaceObject.AssetValidationError("UNSCHEMED_UPLOAD_URL", "Upload adapter returned a URL without a scheme.");
|
|
69
|
+
if (HARD_BLOCKED_SCHEMES.has(scheme)) throw new external_errors_cjs_namespaceObject.AssetValidationError("DISALLOWED_UPLOAD_URL_SCHEME", `Upload adapter returned a disallowed URL scheme "${scheme}".`);
|
|
70
|
+
if (!isSchemeAllowed(scheme, options)) throw new external_errors_cjs_namespaceObject.AssetValidationError("DISALLOWED_UPLOAD_URL_SCHEME", `Upload adapter returned URL scheme "${scheme}" which is not in the allowlist.`);
|
|
71
|
+
if ("http" === scheme || "https" === scheme || "blob" === scheme) assertNoPathTraversal(sanitized);
|
|
72
|
+
if ("http" === scheme || "https" === scheme) assertNoMixedScriptHostname(sanitized, options);
|
|
73
|
+
return candidate;
|
|
74
|
+
}
|
|
75
|
+
function isSchemeAllowed(scheme, options) {
|
|
76
|
+
if (ALWAYS_ALLOWED_SCHEMES.has(scheme)) return true;
|
|
77
|
+
if ("data" === scheme) return true === options.dataUrlAllowlistOptIn;
|
|
78
|
+
return false;
|
|
79
|
+
}
|
|
80
|
+
function assertNoPathTraversal(url) {
|
|
81
|
+
const lowered = url.toLowerCase();
|
|
82
|
+
if (lowered.includes("../") || lowered.includes("..%2f")) throw new external_errors_cjs_namespaceObject.AssetValidationError("PATH_TRAVERSAL_URL", "Upload adapter returned a URL containing path-traversal segments.");
|
|
83
|
+
if (lowered.includes("%2e%2e/") || lowered.includes("%2e%2e%2f")) throw new external_errors_cjs_namespaceObject.AssetValidationError("PATH_TRAVERSAL_URL", "Upload adapter returned a URL containing percent-encoded path-traversal segments.");
|
|
84
|
+
}
|
|
85
|
+
function assertNoMixedScriptHostname(url, options) {
|
|
86
|
+
if (true === options.allowMixedScriptHostnames) return;
|
|
87
|
+
const match = url.match(/^[a-z][a-z0-9+.-]*:\/\/(?:[^@/]+@)?([^:/?#]+)/i);
|
|
88
|
+
if (!match) return;
|
|
89
|
+
const hostname = match[1] ?? "";
|
|
90
|
+
if ("" === hostname) return;
|
|
91
|
+
const scripts = detectHostnameScripts(hostname);
|
|
92
|
+
const hasLatin = scripts.has("Latin");
|
|
93
|
+
const confusable = [
|
|
94
|
+
"Cyrillic",
|
|
95
|
+
"Greek"
|
|
96
|
+
].filter((s)=>scripts.has(s));
|
|
97
|
+
if (hasLatin && confusable.length > 0) throw new external_errors_cjs_namespaceObject.AssetValidationError("MIXED_SCRIPT_HOSTNAME", `Upload adapter returned a URL whose hostname mixes Latin with a visually confusable script (${confusable.join(", ")}). Set allowMixedScriptHostnames: true to permit this.`);
|
|
98
|
+
}
|
|
99
|
+
function detectHostnameScripts(host) {
|
|
100
|
+
const scripts = new Set();
|
|
101
|
+
for (const ch of host)if (!/[\p{Script=Common}\p{Script=Inherited}]/u.test(ch)) if (/\p{Script=Latin}/u.test(ch)) scripts.add("Latin");
|
|
102
|
+
else if (/\p{Script=Cyrillic}/u.test(ch)) scripts.add("Cyrillic");
|
|
103
|
+
else if (/\p{Script=Greek}/u.test(ch)) scripts.add("Greek");
|
|
104
|
+
else if (/\p{Script=Han}/u.test(ch)) scripts.add("Han");
|
|
105
|
+
else if (/\p{Script=Hiragana}/u.test(ch)) scripts.add("Hiragana");
|
|
106
|
+
else if (/\p{Script=Katakana}/u.test(ch)) scripts.add("Katakana");
|
|
107
|
+
else if (/\p{Script=Hangul}/u.test(ch)) scripts.add("Hangul");
|
|
108
|
+
else if (/\p{Script=Arabic}/u.test(ch)) scripts.add("Arabic");
|
|
109
|
+
else if (/\p{Script=Hebrew}/u.test(ch)) scripts.add("Hebrew");
|
|
110
|
+
else scripts.add("Other");
|
|
111
|
+
return scripts;
|
|
112
|
+
}
|
|
113
|
+
function normalizeCandidate(input) {
|
|
114
|
+
const candidate = input.trim();
|
|
115
|
+
return "" === candidate ? void 0 : candidate;
|
|
116
|
+
}
|
|
117
|
+
function stripUnsafeAscii(input) {
|
|
118
|
+
let output = "";
|
|
119
|
+
for (const character of input){
|
|
120
|
+
const codePoint = character.charCodeAt(0);
|
|
121
|
+
if (!(codePoint <= 0x20) && 0x7f !== codePoint) output += character;
|
|
122
|
+
}
|
|
123
|
+
return output;
|
|
124
|
+
}
|
|
125
|
+
function stripUndefinedMeta(meta) {
|
|
126
|
+
if (!meta) return;
|
|
127
|
+
const nextMeta = {
|
|
128
|
+
...void 0 !== meta.size ? {
|
|
129
|
+
size: meta.size
|
|
130
|
+
} : {},
|
|
131
|
+
...void 0 !== meta.mimeType ? {
|
|
132
|
+
mimeType: meta.mimeType
|
|
133
|
+
} : {},
|
|
134
|
+
...void 0 !== meta.width ? {
|
|
135
|
+
width: meta.width
|
|
136
|
+
} : {},
|
|
137
|
+
...void 0 !== meta.height ? {
|
|
138
|
+
height: meta.height
|
|
139
|
+
} : {}
|
|
140
|
+
};
|
|
141
|
+
return Object.freeze(nextMeta);
|
|
142
|
+
}
|
|
143
|
+
exports.validateUploadResult = __webpack_exports__.validateUploadResult;
|
|
144
|
+
for(var __rspack_i in __webpack_exports__)if (-1 === [
|
|
145
|
+
"validateUploadResult"
|
|
146
|
+
].indexOf(__rspack_i)) exports[__rspack_i] = __webpack_exports__[__rspack_i];
|
|
147
|
+
Object.defineProperty(exports, '__esModule', {
|
|
148
|
+
value: true
|
|
149
|
+
});
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { AssetManagerOptions, UploadResult } from "./types.js";
|
|
2
|
+
/**
|
|
3
|
+
* Subset of {@link AssetManagerOptions} consulted by the trust boundary.
|
|
4
|
+
* `urlAllowlist` is intentionally absent — Phase 4 replaced the raw
|
|
5
|
+
* allowlist with the two typed flags below.
|
|
6
|
+
*/
|
|
7
|
+
export type ValidateUploadResultOptions = Pick<AssetManagerOptions, "dataUrlAllowlistOptIn" | "allowMixedScriptHostnames">;
|
|
8
|
+
export declare function validateUploadResult(result: UploadResult, options?: ValidateUploadResultOptions): UploadResult;
|
|
9
|
+
//# sourceMappingURL=validate-upload-result.d.cts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"validate-upload-result.d.cts","sourceRoot":"","sources":["../src/validate-upload-result.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,mBAAmB,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAKpE;;;;GAIG;AACH,MAAM,MAAM,2BAA2B,GAAG,IAAI,CAC7C,mBAAmB,EACnB,uBAAuB,GAAG,2BAA2B,CACrD,CAAC;AAEF,wBAAgB,oBAAoB,CACnC,MAAM,EAAE,YAAY,EACpB,OAAO,GAAE,2BAAgC,GACvC,YAAY,CAqBd"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { AssetManagerOptions, UploadResult } from "./types.js";
|
|
2
|
+
/**
|
|
3
|
+
* Subset of {@link AssetManagerOptions} consulted by the trust boundary.
|
|
4
|
+
* `urlAllowlist` is intentionally absent — Phase 4 replaced the raw
|
|
5
|
+
* allowlist with the two typed flags below.
|
|
6
|
+
*/
|
|
7
|
+
export type ValidateUploadResultOptions = Pick<AssetManagerOptions, "dataUrlAllowlistOptIn" | "allowMixedScriptHostnames">;
|
|
8
|
+
export declare function validateUploadResult(result: UploadResult, options?: ValidateUploadResultOptions): UploadResult;
|
|
9
|
+
//# sourceMappingURL=validate-upload-result.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"validate-upload-result.d.ts","sourceRoot":"","sources":["../src/validate-upload-result.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,mBAAmB,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAKpE;;;;GAIG;AACH,MAAM,MAAM,2BAA2B,GAAG,IAAI,CAC7C,mBAAmB,EACnB,uBAAuB,GAAG,2BAA2B,CACrD,CAAC;AAEF,wBAAgB,oBAAoB,CACnC,MAAM,EAAE,YAAY,EACpB,OAAO,GAAE,2BAAgC,GACvC,YAAY,CAqBd"}
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
import { AssetValidationError } from "./errors.js";
|
|
2
|
+
const ALWAYS_ALLOWED_SCHEMES = new Set([
|
|
3
|
+
"http",
|
|
4
|
+
"https",
|
|
5
|
+
"blob"
|
|
6
|
+
]);
|
|
7
|
+
const HARD_BLOCKED_SCHEMES = new Set([
|
|
8
|
+
"javascript",
|
|
9
|
+
"vbscript"
|
|
10
|
+
]);
|
|
11
|
+
function validateUploadResult(result, options = {}) {
|
|
12
|
+
if ("string" != typeof result.id || "" === result.id.trim()) throw new AssetValidationError("INVALID_UPLOAD_ID", "Upload adapter returned an empty asset id.");
|
|
13
|
+
const normalizedUrl = normalizeAllowedUrl(result.url, options);
|
|
14
|
+
const trimmedName = "string" == typeof result.name ? result.name.trim() : "";
|
|
15
|
+
const nextResult = {
|
|
16
|
+
id: result.id.trim(),
|
|
17
|
+
url: normalizedUrl,
|
|
18
|
+
..."" !== trimmedName ? {
|
|
19
|
+
name: trimmedName
|
|
20
|
+
} : {},
|
|
21
|
+
...result.meta ? {
|
|
22
|
+
meta: stripUndefinedMeta(result.meta)
|
|
23
|
+
} : {},
|
|
24
|
+
...result.tags && result.tags.length > 0 ? {
|
|
25
|
+
tags: Object.freeze([
|
|
26
|
+
...result.tags
|
|
27
|
+
])
|
|
28
|
+
} : {}
|
|
29
|
+
};
|
|
30
|
+
return Object.freeze(nextResult);
|
|
31
|
+
}
|
|
32
|
+
function normalizeAllowedUrl(input, options) {
|
|
33
|
+
const candidate = normalizeCandidate(input);
|
|
34
|
+
if (!candidate) throw new AssetValidationError("EMPTY_UPLOAD_URL", "Upload adapter returned an empty URL.");
|
|
35
|
+
if (candidate.startsWith("//")) throw new AssetValidationError("UNSCHEMED_UPLOAD_URL", "Upload adapter returned a scheme-less URL. Use an absolute URL with an allowed scheme.");
|
|
36
|
+
const sanitized = stripUnsafeAscii(candidate);
|
|
37
|
+
const schemeMatch = sanitized.match(/^([a-z][a-z0-9+.-]*):/i);
|
|
38
|
+
if (!schemeMatch) throw new AssetValidationError("UNSCHEMED_UPLOAD_URL", "Upload adapter returned a URL without a scheme.");
|
|
39
|
+
const scheme = schemeMatch[1]?.toLowerCase();
|
|
40
|
+
if (!scheme) throw new AssetValidationError("UNSCHEMED_UPLOAD_URL", "Upload adapter returned a URL without a scheme.");
|
|
41
|
+
if (HARD_BLOCKED_SCHEMES.has(scheme)) throw new AssetValidationError("DISALLOWED_UPLOAD_URL_SCHEME", `Upload adapter returned a disallowed URL scheme "${scheme}".`);
|
|
42
|
+
if (!isSchemeAllowed(scheme, options)) throw new AssetValidationError("DISALLOWED_UPLOAD_URL_SCHEME", `Upload adapter returned URL scheme "${scheme}" which is not in the allowlist.`);
|
|
43
|
+
if ("http" === scheme || "https" === scheme || "blob" === scheme) assertNoPathTraversal(sanitized);
|
|
44
|
+
if ("http" === scheme || "https" === scheme) assertNoMixedScriptHostname(sanitized, options);
|
|
45
|
+
return candidate;
|
|
46
|
+
}
|
|
47
|
+
function isSchemeAllowed(scheme, options) {
|
|
48
|
+
if (ALWAYS_ALLOWED_SCHEMES.has(scheme)) return true;
|
|
49
|
+
if ("data" === scheme) return true === options.dataUrlAllowlistOptIn;
|
|
50
|
+
return false;
|
|
51
|
+
}
|
|
52
|
+
function assertNoPathTraversal(url) {
|
|
53
|
+
const lowered = url.toLowerCase();
|
|
54
|
+
if (lowered.includes("../") || lowered.includes("..%2f")) throw new AssetValidationError("PATH_TRAVERSAL_URL", "Upload adapter returned a URL containing path-traversal segments.");
|
|
55
|
+
if (lowered.includes("%2e%2e/") || lowered.includes("%2e%2e%2f")) throw new AssetValidationError("PATH_TRAVERSAL_URL", "Upload adapter returned a URL containing percent-encoded path-traversal segments.");
|
|
56
|
+
}
|
|
57
|
+
function assertNoMixedScriptHostname(url, options) {
|
|
58
|
+
if (true === options.allowMixedScriptHostnames) return;
|
|
59
|
+
const match = url.match(/^[a-z][a-z0-9+.-]*:\/\/(?:[^@/]+@)?([^:/?#]+)/i);
|
|
60
|
+
if (!match) return;
|
|
61
|
+
const hostname = match[1] ?? "";
|
|
62
|
+
if ("" === hostname) return;
|
|
63
|
+
const scripts = detectHostnameScripts(hostname);
|
|
64
|
+
const hasLatin = scripts.has("Latin");
|
|
65
|
+
const confusable = [
|
|
66
|
+
"Cyrillic",
|
|
67
|
+
"Greek"
|
|
68
|
+
].filter((s)=>scripts.has(s));
|
|
69
|
+
if (hasLatin && confusable.length > 0) throw new AssetValidationError("MIXED_SCRIPT_HOSTNAME", `Upload adapter returned a URL whose hostname mixes Latin with a visually confusable script (${confusable.join(", ")}). Set allowMixedScriptHostnames: true to permit this.`);
|
|
70
|
+
}
|
|
71
|
+
function detectHostnameScripts(host) {
|
|
72
|
+
const scripts = new Set();
|
|
73
|
+
for (const ch of host)if (!/[\p{Script=Common}\p{Script=Inherited}]/u.test(ch)) if (/\p{Script=Latin}/u.test(ch)) scripts.add("Latin");
|
|
74
|
+
else if (/\p{Script=Cyrillic}/u.test(ch)) scripts.add("Cyrillic");
|
|
75
|
+
else if (/\p{Script=Greek}/u.test(ch)) scripts.add("Greek");
|
|
76
|
+
else if (/\p{Script=Han}/u.test(ch)) scripts.add("Han");
|
|
77
|
+
else if (/\p{Script=Hiragana}/u.test(ch)) scripts.add("Hiragana");
|
|
78
|
+
else if (/\p{Script=Katakana}/u.test(ch)) scripts.add("Katakana");
|
|
79
|
+
else if (/\p{Script=Hangul}/u.test(ch)) scripts.add("Hangul");
|
|
80
|
+
else if (/\p{Script=Arabic}/u.test(ch)) scripts.add("Arabic");
|
|
81
|
+
else if (/\p{Script=Hebrew}/u.test(ch)) scripts.add("Hebrew");
|
|
82
|
+
else scripts.add("Other");
|
|
83
|
+
return scripts;
|
|
84
|
+
}
|
|
85
|
+
function normalizeCandidate(input) {
|
|
86
|
+
const candidate = input.trim();
|
|
87
|
+
return "" === candidate ? void 0 : candidate;
|
|
88
|
+
}
|
|
89
|
+
function stripUnsafeAscii(input) {
|
|
90
|
+
let output = "";
|
|
91
|
+
for (const character of input){
|
|
92
|
+
const codePoint = character.charCodeAt(0);
|
|
93
|
+
if (!(codePoint <= 0x20) && 0x7f !== codePoint) output += character;
|
|
94
|
+
}
|
|
95
|
+
return output;
|
|
96
|
+
}
|
|
97
|
+
function stripUndefinedMeta(meta) {
|
|
98
|
+
if (!meta) return;
|
|
99
|
+
const nextMeta = {
|
|
100
|
+
...void 0 !== meta.size ? {
|
|
101
|
+
size: meta.size
|
|
102
|
+
} : {},
|
|
103
|
+
...void 0 !== meta.mimeType ? {
|
|
104
|
+
mimeType: meta.mimeType
|
|
105
|
+
} : {},
|
|
106
|
+
...void 0 !== meta.width ? {
|
|
107
|
+
width: meta.width
|
|
108
|
+
} : {},
|
|
109
|
+
...void 0 !== meta.height ? {
|
|
110
|
+
height: meta.height
|
|
111
|
+
} : {}
|
|
112
|
+
};
|
|
113
|
+
return Object.freeze(nextMeta);
|
|
114
|
+
}
|
|
115
|
+
export { validateUploadResult };
|