@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.
Files changed (159) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +159 -0
  3. package/dist/adapters/data-url.cjs +78 -0
  4. package/dist/adapters/data-url.d.cts +6 -0
  5. package/dist/adapters/data-url.d.cts.map +1 -0
  6. package/dist/adapters/data-url.d.ts +6 -0
  7. package/dist/adapters/data-url.d.ts.map +1 -0
  8. package/dist/adapters/data-url.js +44 -0
  9. package/dist/adapters/extract-image-dimensions.cjs +69 -0
  10. package/dist/adapters/extract-image-dimensions.d.cts +21 -0
  11. package/dist/adapters/extract-image-dimensions.d.cts.map +1 -0
  12. package/dist/adapters/extract-image-dimensions.d.ts +21 -0
  13. package/dist/adapters/extract-image-dimensions.d.ts.map +1 -0
  14. package/dist/adapters/extract-image-dimensions.js +35 -0
  15. package/dist/adapters/in-memory.cjs +62 -0
  16. package/dist/adapters/in-memory.d.cts +3 -0
  17. package/dist/adapters/in-memory.d.cts.map +1 -0
  18. package/dist/adapters/in-memory.d.ts +3 -0
  19. package/dist/adapters/in-memory.d.ts.map +1 -0
  20. package/dist/adapters/in-memory.js +28 -0
  21. package/dist/adapters/s3-presigned.cjs +166 -0
  22. package/dist/adapters/s3-presigned.d.cts +59 -0
  23. package/dist/adapters/s3-presigned.d.cts.map +1 -0
  24. package/dist/adapters/s3-presigned.d.ts +59 -0
  25. package/dist/adapters/s3-presigned.d.ts.map +1 -0
  26. package/dist/adapters/s3-presigned.js +129 -0
  27. package/dist/asset-reference.cjs +38 -0
  28. package/dist/asset-reference.d.cts +10 -0
  29. package/dist/asset-reference.d.cts.map +1 -0
  30. package/dist/asset-reference.d.ts +10 -0
  31. package/dist/asset-reference.d.ts.map +1 -0
  32. package/dist/asset-reference.js +4 -0
  33. package/dist/csp.cjs +83 -0
  34. package/dist/csp.d.cts +45 -0
  35. package/dist/csp.d.cts.map +1 -0
  36. package/dist/csp.d.ts +45 -0
  37. package/dist/csp.d.ts.map +1 -0
  38. package/dist/csp.js +49 -0
  39. package/dist/errors.cjs +58 -0
  40. package/dist/errors.d.cts +15 -0
  41. package/dist/errors.d.cts.map +1 -0
  42. package/dist/errors.d.ts +15 -0
  43. package/dist/errors.d.ts.map +1 -0
  44. package/dist/errors.js +21 -0
  45. package/dist/header-action.cjs +44 -0
  46. package/dist/header-action.d.cts +3 -0
  47. package/dist/header-action.d.cts.map +1 -0
  48. package/dist/header-action.d.ts +3 -0
  49. package/dist/header-action.d.ts.map +1 -0
  50. package/dist/header-action.js +10 -0
  51. package/dist/index.cjs +90 -0
  52. package/dist/index.d.cts +18 -0
  53. package/dist/index.d.cts.map +1 -0
  54. package/dist/index.d.ts +18 -0
  55. package/dist/index.d.ts.map +1 -0
  56. package/dist/index.js +10 -0
  57. package/dist/infer-kind.cjs +45 -0
  58. package/dist/infer-kind.d.cts +8 -0
  59. package/dist/infer-kind.d.cts.map +1 -0
  60. package/dist/infer-kind.d.ts +8 -0
  61. package/dist/infer-kind.d.ts.map +1 -0
  62. package/dist/infer-kind.js +11 -0
  63. package/dist/plugin.cjs +258 -0
  64. package/dist/plugin.d.cts +9 -0
  65. package/dist/plugin.d.cts.map +1 -0
  66. package/dist/plugin.d.ts +9 -0
  67. package/dist/plugin.d.ts.map +1 -0
  68. package/dist/plugin.js +212 -0
  69. package/dist/registry.cjs +198 -0
  70. package/dist/registry.d.cts +3 -0
  71. package/dist/registry.d.cts.map +1 -0
  72. package/dist/registry.d.ts +3 -0
  73. package/dist/registry.d.ts.map +1 -0
  74. package/dist/registry.js +164 -0
  75. package/dist/resolver.cjs +185 -0
  76. package/dist/resolver.d.cts +10 -0
  77. package/dist/resolver.d.cts.map +1 -0
  78. package/dist/resolver.d.ts +10 -0
  79. package/dist/resolver.d.ts.map +1 -0
  80. package/dist/resolver.js +148 -0
  81. package/dist/retry.cjs +123 -0
  82. package/dist/retry.d.cts +71 -0
  83. package/dist/retry.d.cts.map +1 -0
  84. package/dist/retry.d.ts +71 -0
  85. package/dist/retry.d.ts.map +1 -0
  86. package/dist/retry.js +86 -0
  87. package/dist/studio-asset-source.cjs +211 -0
  88. package/dist/studio-asset-source.d.cts +52 -0
  89. package/dist/studio-asset-source.d.cts.map +1 -0
  90. package/dist/studio-asset-source.d.ts +52 -0
  91. package/dist/studio-asset-source.d.ts.map +1 -0
  92. package/dist/studio-asset-source.js +171 -0
  93. package/dist/testing/index.cjs +66 -0
  94. package/dist/testing/index.d.cts +24 -0
  95. package/dist/testing/index.d.cts.map +1 -0
  96. package/dist/testing/index.d.ts +24 -0
  97. package/dist/testing/index.d.ts.map +1 -0
  98. package/dist/testing/index.js +29 -0
  99. package/dist/types.cjs +18 -0
  100. package/dist/types.d.cts +132 -0
  101. package/dist/types.d.cts.map +1 -0
  102. package/dist/types.d.ts +132 -0
  103. package/dist/types.d.ts.map +1 -0
  104. package/dist/types.js +0 -0
  105. package/dist/ui/AssetBrowser.cjs +271 -0
  106. package/dist/ui/AssetBrowser.d.cts +45 -0
  107. package/dist/ui/AssetBrowser.d.cts.map +1 -0
  108. package/dist/ui/AssetBrowser.d.ts +45 -0
  109. package/dist/ui/AssetBrowser.d.ts.map +1 -0
  110. package/dist/ui/AssetBrowser.js +237 -0
  111. package/dist/ui/AssetCommandPalette.cjs +135 -0
  112. package/dist/ui/AssetCommandPalette.d.cts +21 -0
  113. package/dist/ui/AssetCommandPalette.d.cts.map +1 -0
  114. package/dist/ui/AssetCommandPalette.d.ts +21 -0
  115. package/dist/ui/AssetCommandPalette.d.ts.map +1 -0
  116. package/dist/ui/AssetCommandPalette.js +101 -0
  117. package/dist/ui/AssetManagerUI.cjs +169 -0
  118. package/dist/ui/AssetManagerUI.d.cts +15 -0
  119. package/dist/ui/AssetManagerUI.d.cts.map +1 -0
  120. package/dist/ui/AssetManagerUI.d.ts +15 -0
  121. package/dist/ui/AssetManagerUI.d.ts.map +1 -0
  122. package/dist/ui/AssetManagerUI.js +135 -0
  123. package/dist/ui/DeleteAssetDialog.cjs +70 -0
  124. package/dist/ui/DeleteAssetDialog.d.cts +22 -0
  125. package/dist/ui/DeleteAssetDialog.d.cts.map +1 -0
  126. package/dist/ui/DeleteAssetDialog.d.ts +22 -0
  127. package/dist/ui/DeleteAssetDialog.d.ts.map +1 -0
  128. package/dist/ui/DeleteAssetDialog.js +36 -0
  129. package/dist/ui/MetadataPanel.cjs +147 -0
  130. package/dist/ui/MetadataPanel.d.cts +21 -0
  131. package/dist/ui/MetadataPanel.d.cts.map +1 -0
  132. package/dist/ui/MetadataPanel.d.ts +21 -0
  133. package/dist/ui/MetadataPanel.d.ts.map +1 -0
  134. package/dist/ui/MetadataPanel.js +113 -0
  135. package/dist/ui/ReplaceAssetDialog.cjs +125 -0
  136. package/dist/ui/ReplaceAssetDialog.d.cts +14 -0
  137. package/dist/ui/ReplaceAssetDialog.d.cts.map +1 -0
  138. package/dist/ui/ReplaceAssetDialog.d.ts +14 -0
  139. package/dist/ui/ReplaceAssetDialog.d.ts.map +1 -0
  140. package/dist/ui/ReplaceAssetDialog.js +91 -0
  141. package/dist/ui/UploadButton.cjs +189 -0
  142. package/dist/ui/UploadButton.d.cts +17 -0
  143. package/dist/ui/UploadButton.d.cts.map +1 -0
  144. package/dist/ui/UploadButton.d.ts +17 -0
  145. package/dist/ui/UploadButton.d.ts.map +1 -0
  146. package/dist/ui/UploadButton.js +155 -0
  147. package/dist/ui/index.cjs +60 -0
  148. package/dist/ui/index.d.cts +15 -0
  149. package/dist/ui/index.d.cts.map +1 -0
  150. package/dist/ui/index.d.ts +15 -0
  151. package/dist/ui/index.d.ts.map +1 -0
  152. package/dist/ui/index.js +7 -0
  153. package/dist/validate-upload-result.cjs +149 -0
  154. package/dist/validate-upload-result.d.cts +9 -0
  155. package/dist/validate-upload-result.d.cts.map +1 -0
  156. package/dist/validate-upload-result.d.ts +9 -0
  157. package/dist/validate-upload-result.d.ts.map +1 -0
  158. package/dist/validate-upload-result.js +115 -0
  159. 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"}
@@ -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 };