@windwalker-io/unicorn-next 0.1.19 → 0.1.21

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 (107) hide show
  1. package/dist/chunks/_arrayPush.js +325 -108
  2. package/dist/chunks/_arrayPush.js.map +1 -1
  3. package/dist/chunks/_baseRest.js +155 -60
  4. package/dist/chunks/_baseRest.js.map +1 -1
  5. package/dist/chunks/_baseUnary.js +463 -0
  6. package/dist/chunks/_baseUnary.js.map +1 -0
  7. package/dist/chunks/_getPrototype.js +292 -100
  8. package/dist/chunks/_getPrototype.js.map +1 -1
  9. package/dist/chunks/alert-adapter.js +29 -0
  10. package/dist/chunks/alert-adapter.js.map +1 -0
  11. package/dist/chunks/alert.js +21 -0
  12. package/dist/chunks/alert.js.map +1 -0
  13. package/dist/chunks/arr.js +24 -0
  14. package/dist/chunks/arr.js.map +1 -0
  15. package/dist/chunks/button-radio.js +127 -145
  16. package/dist/chunks/button-radio.js.map +1 -1
  17. package/dist/chunks/checkboxes-multi-select.js +44 -43
  18. package/dist/chunks/checkboxes-multi-select.js.map +1 -1
  19. package/dist/chunks/chunk.js +24 -0
  20. package/dist/chunks/cloneDeep.js +679 -212
  21. package/dist/chunks/cloneDeep.js.map +1 -1
  22. package/dist/chunks/cropper.min.js +6 -5
  23. package/dist/chunks/cropper.min.js.map +1 -1
  24. package/dist/chunks/crypto.js +26 -0
  25. package/dist/chunks/crypto.js.map +1 -0
  26. package/dist/chunks/data.js +49 -0
  27. package/dist/chunks/data.js.map +1 -0
  28. package/dist/chunks/dom.js +128 -0
  29. package/dist/chunks/dom.js.map +1 -0
  30. package/dist/chunks/events.js +270 -0
  31. package/dist/chunks/events.js.map +1 -0
  32. package/dist/chunks/field-cascade-select.js +207 -250
  33. package/dist/chunks/field-cascade-select.js.map +1 -1
  34. package/dist/chunks/field-file-drag.js +175 -209
  35. package/dist/chunks/field-file-drag.js.map +1 -1
  36. package/dist/chunks/field-flatpickr.js +94 -898
  37. package/dist/chunks/field-flatpickr.js.map +1 -1
  38. package/dist/chunks/field-modal-select.js +728 -467
  39. package/dist/chunks/field-modal-select.js.map +1 -1
  40. package/dist/chunks/field-modal-tree.js +771 -766
  41. package/dist/chunks/field-modal-tree.js.map +1 -1
  42. package/dist/chunks/field-multi-uploader.js +249 -256
  43. package/dist/chunks/field-multi-uploader.js.map +1 -1
  44. package/dist/chunks/field-repeatable.js +111 -127
  45. package/dist/chunks/field-repeatable.js.map +1 -1
  46. package/dist/chunks/field-single-image-drag.js +286 -338
  47. package/dist/chunks/field-single-image-drag.js.map +1 -1
  48. package/dist/chunks/form.js +146 -159
  49. package/dist/chunks/form.js.map +1 -1
  50. package/dist/chunks/grid.js +349 -418
  51. package/dist/chunks/grid.js.map +1 -1
  52. package/dist/chunks/helper.js +39 -0
  53. package/dist/chunks/helper.js.map +1 -0
  54. package/dist/chunks/http-client.js +221 -211
  55. package/dist/chunks/http-client.js.map +1 -1
  56. package/dist/chunks/iframe-modal.js +95 -115
  57. package/dist/chunks/iframe-modal.js.map +1 -1
  58. package/dist/chunks/keep-tab.js +92 -101
  59. package/dist/chunks/keep-tab.js.map +1 -1
  60. package/dist/chunks/lang.js +250 -0
  61. package/dist/chunks/lang.js.map +1 -0
  62. package/dist/chunks/legacy.js +197 -201
  63. package/dist/chunks/legacy.js.map +1 -1
  64. package/dist/chunks/list-dependent.js +195 -228
  65. package/dist/chunks/list-dependent.js.map +1 -1
  66. package/dist/chunks/loader.js +106 -0
  67. package/dist/chunks/loader.js.map +1 -0
  68. package/dist/chunks/monthSelect.js +251 -0
  69. package/dist/chunks/monthSelect.js.map +1 -0
  70. package/dist/chunks/router.js +111 -0
  71. package/dist/chunks/router.js.map +1 -0
  72. package/dist/chunks/s3-multipart-uploader.js +183 -210
  73. package/dist/chunks/s3-multipart-uploader.js.map +1 -1
  74. package/dist/chunks/s3-uploader.js +106 -128
  75. package/dist/chunks/s3-uploader.js.map +1 -1
  76. package/dist/chunks/show-on.js +358 -205
  77. package/dist/chunks/show-on.js.map +1 -1
  78. package/dist/chunks/timing.js +10 -0
  79. package/dist/chunks/timing.js.map +1 -0
  80. package/dist/chunks/tinymce.js +153 -203
  81. package/dist/chunks/tinymce.js.map +1 -1
  82. package/dist/chunks/ui-bootstrap5.js +58 -72
  83. package/dist/chunks/ui-bootstrap5.js.map +1 -1
  84. package/dist/chunks/ui.js +320 -0
  85. package/dist/chunks/ui.js.map +1 -0
  86. package/dist/chunks/unicorn.js.map +1 -1
  87. package/dist/chunks/useQueue.js +111 -0
  88. package/dist/chunks/useQueue.js.map +1 -0
  89. package/dist/chunks/useStack.js +76 -0
  90. package/dist/chunks/useStack.js.map +1 -0
  91. package/dist/chunks/validation.js +761 -853
  92. package/dist/chunks/validation.js.map +1 -1
  93. package/dist/editor.css +1 -1
  94. package/dist/index.d.ts +10 -8
  95. package/dist/multi-level-menu.css +1 -1
  96. package/dist/switcher.css +1 -1
  97. package/dist/unicorn.js +805 -130
  98. package/dist/unicorn.js.map +1 -1
  99. package/package.json +3 -3
  100. package/src/composable/useBsModalAlert.ts +29 -0
  101. package/src/composable/useHttp.ts +13 -1
  102. package/src/module/s3-uploader.ts +1 -1
  103. package/vite.config.ts +5 -1
  104. package/dist/chunks/_commonjsHelpers.js +0 -7
  105. package/dist/chunks/index.js +0 -314
  106. package/dist/chunks/isArguments.js +0 -146
  107. package/dist/chunks/unicorn.js +0 -2621
@@ -1,137 +1,115 @@
1
- import { ah as Mixin, ae as data, a6 as mergeDeep, u as useHttpClient, ai as EventMixin } from "./unicorn.js";
2
- const instances = {};
1
+ import { n as Mixin, t as EventMixin } from "./events.js";
2
+ import { t as mergeDeep } from "./arr.js";
3
+ import { t as data } from "./data.js";
4
+ import { useHttpClient } from "../unicorn.js";
5
+ //#region src/module/s3-uploader.ts
6
+ var instances = {};
3
7
  function get(name, options = {}) {
4
- return instances[name] ??= create(name, options);
8
+ return instances[name] ??= create(name, options);
5
9
  }
6
10
  function create(name, options = {}) {
7
- return new S3Uploader(name, options);
11
+ return new S3Uploader(name, options);
8
12
  }
9
13
  function destroy(name) {
10
- delete instances[name];
14
+ delete instances[name];
11
15
  }
12
- const defaultOptions = {
13
- endpoint: "",
14
- subfolder: "",
15
- viewerHost: "",
16
- starts_with: [],
17
- formInputs: {
18
- acl: "",
19
- bucket: "",
20
- key: "",
21
- Policy: "",
22
- "X-Amz-Algorithm": "",
23
- "X-Amz-Credential": "",
24
- "X-Amz-Date": "",
25
- "X-Amz-Signature": ""
26
- }
16
+ var defaultOptions = {
17
+ endpoint: "",
18
+ subfolder: "",
19
+ viewerHost: "",
20
+ starts_with: [],
21
+ formInputs: {
22
+ acl: "",
23
+ bucket: "",
24
+ key: "",
25
+ Policy: "",
26
+ "X-Amz-Algorithm": "",
27
+ "X-Amz-Credential": "",
28
+ "X-Amz-Date": "",
29
+ "X-Amz-Signature": ""
30
+ }
31
+ };
32
+ var S3Uploader = class extends Mixin(EventMixin) {
33
+ options;
34
+ http;
35
+ constructor(name, options = {}) {
36
+ super();
37
+ this.name = name;
38
+ this.options = mergeDeep({}, defaultOptions, data("@s3.uploader." + name) || {}, options);
39
+ }
40
+ async getHttpClient() {
41
+ return this.http ??= await useHttpClient();
42
+ }
43
+ /**
44
+ * Do upload.
45
+ */
46
+ async upload(file, path, options = {}) {
47
+ const httpClient = await this.getHttpClient();
48
+ const fileData = new FormData();
49
+ const inputs = mergeDeep({}, this.options.formInputs, options.formInputs || {});
50
+ if (typeof file === "string") file = new Blob([file], { type: options["Content-Type"] || "text/plain" });
51
+ if (file instanceof Blob && !(file instanceof File) && path.endsWith(".{ext}")) throw new Error("If using Blob or file data string, you must provide a valid file extension in the path.");
52
+ if (file instanceof Blob || file instanceof File) options["Content-Type"] = options["Content-Type"] || file.type;
53
+ if (options["filename"]) {
54
+ const filename = this.replaceExt(options["filename"], file);
55
+ options["Content-Disposition"] = "attachment; filename*=UTF-8''" + encodeURIComponent(filename);
56
+ }
57
+ path = this.replaceExt(path, file);
58
+ options["key"] = trimSlashes(this.options.subfolder || "") + "/" + trimSlashes(path);
59
+ options["key"] = trimSlashes(options["key"]);
60
+ options["Content-Type"] = options["Content-Type"] || void 0;
61
+ options["Content-Disposition"] = options["Content-Disposition"] || void 0;
62
+ for (let key in inputs) fileData.set(key, inputs[key]);
63
+ for (let key of Object.keys(this.options.starts_with)) if (options[key]) fileData.set(key, options[key]);
64
+ fileData.append("file", file);
65
+ this.trigger("start", fileData);
66
+ try {
67
+ let res = await httpClient.post(this.options.endpoint || "", fileData, {
68
+ signal: options.signal,
69
+ onUploadProgress: (e) => {
70
+ if (options.onUploadProgress) options.onUploadProgress(e);
71
+ this.trigger("upload-progress", e);
72
+ if (e.total != null) this.trigger("progress", e.loaded / e.total, e);
73
+ }
74
+ });
75
+ const url = this.options.viewerHost + "/" + trimSlashes(path);
76
+ this.trigger("success", url, res);
77
+ res.url = url;
78
+ return res;
79
+ } finally {
80
+ this.trigger("end");
81
+ }
82
+ }
83
+ replaceExt(path, file) {
84
+ if (file instanceof File) {
85
+ const fileExt = file.name.split(".").pop();
86
+ if (path.endsWith(".{ext}")) return path.replace(/\.{ext}$/, fileExt ? "." + fileExt : "");
87
+ }
88
+ return path;
89
+ }
90
+ on(event, handler) {
91
+ return super.on(event, handler);
92
+ }
93
+ onStart(handler) {
94
+ return this.on("start", handler);
95
+ }
96
+ onSuccess(handler) {
97
+ return this.on("success", handler);
98
+ }
99
+ onEnd(handler) {
100
+ return this.on("end", handler);
101
+ }
102
+ onProgress(handler) {
103
+ return this.on("upload-progress", handler);
104
+ }
105
+ onProgressWithTotal(handler) {
106
+ return this.on("progress", handler);
107
+ }
27
108
  };
28
- class S3Uploader extends (/* @__PURE__ */ Mixin(EventMixin)) {
29
- constructor(name, options = {}) {
30
- super();
31
- this.name = name;
32
- const awsOptions = data("@s3.uploader." + name) || {};
33
- this.options = mergeDeep({}, defaultOptions, awsOptions, options);
34
- }
35
- options;
36
- http;
37
- async getHttpClient() {
38
- return this.http ??= await useHttpClient();
39
- }
40
- /**
41
- * Do upload.
42
- */
43
- async upload(file, path, options = {}) {
44
- const httpClient = await this.getHttpClient();
45
- const fileData = new FormData();
46
- const inputs = mergeDeep({}, this.options.formInputs, options.formInputs || {});
47
- if (typeof file === "string") {
48
- file = new Blob([file], { type: options["Content-Type"] || "text/plain" });
49
- }
50
- if (file instanceof Blob && path.endsWith(".{ext}")) {
51
- throw new Error("If using Blob or file data string, you must provide a valid file extension in the path.");
52
- }
53
- if (file instanceof Blob || file instanceof File) {
54
- options["Content-Type"] = options["Content-Type"] || file.type;
55
- }
56
- if (options["filename"]) {
57
- const filename = this.replaceExt(options["filename"], file);
58
- options["Content-Disposition"] = "attachment; filename*=UTF-8''" + encodeURIComponent(filename);
59
- }
60
- path = this.replaceExt(path, file);
61
- options["key"] = trimSlashes(this.options.subfolder || "") + "/" + trimSlashes(path);
62
- options["key"] = trimSlashes(options["key"]);
63
- options["Content-Type"] = options["Content-Type"] || void 0;
64
- options["Content-Disposition"] = options["Content-Disposition"] || void 0;
65
- for (let key in inputs) {
66
- fileData.set(key, inputs[key]);
67
- }
68
- for (let key of Object.keys(this.options.starts_with)) {
69
- if (options[key]) {
70
- fileData.set(key, options[key]);
71
- }
72
- }
73
- fileData.append("file", file);
74
- this.trigger("start", fileData);
75
- try {
76
- let res = await httpClient.post(
77
- this.options.endpoint || "",
78
- fileData,
79
- {
80
- signal: options.signal,
81
- onUploadProgress: (e) => {
82
- if (options.onUploadProgress) {
83
- options.onUploadProgress(e);
84
- }
85
- this.trigger("upload-progress", e);
86
- if (e.total != null) {
87
- this.trigger("progress", e.loaded / e.total, e);
88
- }
89
- }
90
- }
91
- );
92
- const url = this.options.viewerHost + "/" + trimSlashes(path);
93
- this.trigger("success", url, res);
94
- res.url = url;
95
- return res;
96
- } finally {
97
- this.trigger("end");
98
- }
99
- }
100
- replaceExt(path, file) {
101
- if (file instanceof File) {
102
- const fileExt = file.name.split(".").pop();
103
- if (path.endsWith(".{ext}")) {
104
- return path.replace(/\.{ext}$/, fileExt ? "." + fileExt : "");
105
- }
106
- }
107
- return path;
108
- }
109
- on(event, handler) {
110
- return super.on(event, handler);
111
- }
112
- onStart(handler) {
113
- return this.on("start", handler);
114
- }
115
- onSuccess(handler) {
116
- return this.on("success", handler);
117
- }
118
- onEnd(handler) {
119
- return this.on("end", handler);
120
- }
121
- onProgress(handler) {
122
- return this.on("upload-progress", handler);
123
- }
124
- onProgressWithTotal(handler) {
125
- return this.on("progress", handler);
126
- }
127
- }
128
109
  function trimSlashes(str) {
129
- return str.replace(/^\/+|\/+$/g, "");
110
+ return str.replace(/^\/+|\/+$/g, "");
130
111
  }
131
- export {
132
- S3Uploader,
133
- create,
134
- destroy,
135
- get
136
- };
137
- //# sourceMappingURL=s3-uploader.js.map
112
+ //#endregion
113
+ export { S3Uploader, create, destroy, get };
114
+
115
+ //# sourceMappingURL=s3-uploader.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"s3-uploader.js","sources":["../../src/module/s3-uploader.ts"],"sourcesContent":["import { useHttpClient } from '../composable';\nimport { data } from '../data';\nimport { EventAwareInterface, EventHandler, EventMixin } from '../events';\nimport type { UnicornHttpClient } from './http-client';\nimport { mergeDeep } from '../utilities';\nimport { AxiosProgressEvent, AxiosResponse } from 'axios';\nimport { Mixin } from 'ts-mixer';\n\nconst instances: Record<string, S3Uploader> = {};\nexport function get(name: string, options?: Partial<S3UploaderGlobalOptions>): S3Uploader;\nexport function get(\n name: string,\n options: Partial<S3UploaderGlobalOptions> = {}\n): S3Uploader | void {\n return instances[name] ??= create(name, options);\n}\n\nexport function create(name: string, options: Partial<S3UploaderGlobalOptions> = {}): S3Uploader {\n return new S3Uploader(name, options);\n}\n\nexport function destroy(name: string) {\n delete instances[name];\n}\n\nconst defaultOptions: S3UploaderGlobalOptions = {\n endpoint: '',\n subfolder: '',\n viewerHost: '',\n starts_with: [],\n formInputs: {\n acl: '',\n bucket: '',\n key: '',\n Policy: '',\n 'X-Amz-Algorithm': '',\n 'X-Amz-Credential': '',\n 'X-Amz-Date': '',\n 'X-Amz-Signature': '',\n }\n};\n\nexport class S3Uploader extends Mixin(EventMixin) implements EventAwareInterface {\n options: S3UploaderGlobalOptions;\n http?: UnicornHttpClient;\n\n constructor(protected name: string, options: Partial<S3UploaderGlobalOptions> = {}) {\n super();\n\n const awsOptions = data('@s3.uploader.' + name) || {};\n\n this.options = mergeDeep<S3UploaderGlobalOptions>({}, defaultOptions, awsOptions, options);\n }\n\n async getHttpClient() {\n return this.http ??= await useHttpClient();\n }\n\n /**\n * Do upload.\n */\n async upload(\n file: string | File | Blob,\n path: string,\n options: Partial<S3UploaderRequestOptions> = {}\n ): Promise<S3UploaderResponse> {\n const httpClient = await this.getHttpClient();\n\n const fileData = new FormData();\n const inputs = mergeDeep({}, this.options.formInputs, options.formInputs || {});\n\n if (typeof file === 'string') {\n file = new Blob([file], { type: options['Content-Type'] || 'text/plain' });\n }\n\n if (file instanceof Blob && path.endsWith('.{ext}')) {\n throw new Error('If using Blob or file data string, you must provide a valid file extension in the path.');\n }\n\n if ((file instanceof Blob) || (file as any) instanceof File) {\n options['Content-Type'] = options['Content-Type'] || file.type;\n }\n\n if (options['filename']) {\n const filename = this.replaceExt(options['filename'], file);\n options['Content-Disposition'] = 'attachment; filename*=UTF-8\\'\\'' + encodeURIComponent(filename);\n }\n\n path = this.replaceExt(path, file);\n\n options['key'] = trimSlashes(this.options.subfolder || '') + '/'\n + trimSlashes(path);\n options['key'] = trimSlashes(options['key']);\n options['Content-Type'] = options['Content-Type'] || undefined;\n options['Content-Disposition'] = options['Content-Disposition'] || undefined;\n\n // Prepare pre-signed data\n for (let key in inputs) {\n fileData.set(key, inputs[key]);\n }\n\n // Prepare custom data\n for (let key of Object.keys(this.options.starts_with)) {\n if (options[key]) {\n fileData.set(key, options[key]);\n }\n }\n\n fileData.append('file', file);\n\n this.trigger('start', fileData);\n\n try {\n let res = await httpClient.post(\n this.options.endpoint || '',\n fileData,\n {\n signal: options.signal,\n onUploadProgress: (e) => {\n if (options.onUploadProgress) {\n options.onUploadProgress(e);\n }\n\n this.trigger('upload-progress', e);\n\n if (e.total != null) {\n this.trigger('progress', e.loaded / e.total, e);\n }\n }\n }\n ) as S3UploaderResponse;\n\n const url = this.options.viewerHost + '/'\n + trimSlashes(path);\n\n this.trigger('success', url, res);\n\n res.url = url;\n\n return res;\n } finally {\n this.trigger('end');\n }\n }\n\n replaceExt(path: string, file: File | Blob): string {\n if (file instanceof File) {\n const fileExt = file.name.split('.').pop();\n\n if (path.endsWith('.{ext}')) {\n return path.replace(/\\.{ext}$/, fileExt ? '.' + fileExt : '');\n }\n }\n\n return path;\n }\n\n on(event: 'start', handler: StartEventHandler): this;\n on(event: 'success', handler: SuccessEventHandler): this;\n on(event: 'end', handler: EndEventHandler): this;\n on(event: 'upload-progress', handler: UploadProgressEventHandler): this;\n on(event: 'progress', handler: ProgressEventHandler): this;\n on(event: string | string[], handler: EventHandler): this {\n return super.on(event, handler);\n }\n\n onStart(handler: StartEventHandler): this {\n return this.on('start', handler);\n }\n\n onSuccess(handler: SuccessEventHandler): this {\n return this.on('success', handler);\n }\n\n onEnd(handler: EndEventHandler): this {\n return this.on('end', handler);\n }\n\n onProgress(handler: UploadProgressEventHandler): this {\n return this.on('upload-progress', handler);\n }\n\n onProgressWithTotal(handler: ProgressEventHandler): this {\n return this.on('progress', handler);\n }\n}\n\ntype EndEventHandler = () => void;\ntype SuccessEventHandler = (url: string, res: S3UploaderResponse) => void;\ntype StartEventHandler = (fileData: FormData) => void;\ntype UploadProgressEventHandler = (e: AxiosProgressEvent) => void;\ntype ProgressEventHandler = (total: number, e: AxiosProgressEvent) => void;\n\nfunction trimSlashes(str: string) {\n return str.replace(/^\\/+|\\/+$/g, '');\n}\n\nexport interface S3UploaderResponse extends AxiosResponse {\n url: string;\n}\n\nexport interface S3UploaderGlobalOptions {\n endpoint?: string;\n subfolder?: string;\n viewerHost?: string;\n starts_with: any[];\n formInputs?: {\n acl: string;\n bucket: string;\n key: string;\n Policy: string;\n 'X-Amz-Algorithm': string;\n 'X-Amz-Credential': string;\n 'X-Amz-Date': string;\n 'X-Amz-Signature': string;\n [name: string]: any\n },\n}\n\nexport interface S3UploaderRequestOptions {\n formInputs?: { [name: string]: any };\n onUploadProgress?: (e: AxiosProgressEvent) => void;\n 'Content-Type'?: string;\n 'Content-Disposition'?: string;\n key?: string;\n signal?: AbortSignal;\n\n [name: string]: any;\n}\n\nexport interface S3UploaderModule {\n get(name: string, options?: Partial<S3UploaderGlobalOptions>): S3Uploader;\n create(name: string, options?: Partial<S3UploaderGlobalOptions>): S3Uploader;\n destroy(name: string): void;\n S3Uploader: typeof S3Uploader;\n}\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"s3-uploader.js","names":[],"sources":["../../src/module/s3-uploader.ts"],"sourcesContent":["import { useHttpClient } from '../composable';\nimport { data } from '../data';\nimport { EventAwareInterface, EventHandler, EventMixin } from '../events';\nimport type { UnicornHttpClient } from './http-client';\nimport { mergeDeep } from '../utilities';\nimport { AxiosProgressEvent, AxiosResponse } from 'axios';\nimport { Mixin } from 'ts-mixer';\n\nconst instances: Record<string, S3Uploader> = {};\nexport function get(name: string, options?: Partial<S3UploaderGlobalOptions>): S3Uploader;\nexport function get(\n name: string,\n options: Partial<S3UploaderGlobalOptions> = {}\n): S3Uploader | void {\n return instances[name] ??= create(name, options);\n}\n\nexport function create(name: string, options: Partial<S3UploaderGlobalOptions> = {}): S3Uploader {\n return new S3Uploader(name, options);\n}\n\nexport function destroy(name: string) {\n delete instances[name];\n}\n\nconst defaultOptions: S3UploaderGlobalOptions = {\n endpoint: '',\n subfolder: '',\n viewerHost: '',\n starts_with: [],\n formInputs: {\n acl: '',\n bucket: '',\n key: '',\n Policy: '',\n 'X-Amz-Algorithm': '',\n 'X-Amz-Credential': '',\n 'X-Amz-Date': '',\n 'X-Amz-Signature': '',\n }\n};\n\nexport class S3Uploader extends Mixin(EventMixin) implements EventAwareInterface {\n options: S3UploaderGlobalOptions;\n http?: UnicornHttpClient;\n\n constructor(protected name: string, options: Partial<S3UploaderGlobalOptions> = {}) {\n super();\n\n const awsOptions = data('@s3.uploader.' + name) || {};\n\n this.options = mergeDeep<S3UploaderGlobalOptions>({}, defaultOptions, awsOptions, options);\n }\n\n async getHttpClient() {\n return this.http ??= await useHttpClient();\n }\n\n /**\n * Do upload.\n */\n async upload(\n file: string | File | Blob,\n path: string,\n options: Partial<S3UploaderRequestOptions> = {}\n ): Promise<S3UploaderResponse> {\n const httpClient = await this.getHttpClient();\n\n const fileData = new FormData();\n const inputs = mergeDeep({}, this.options.formInputs, options.formInputs || {});\n\n if (typeof file === 'string') {\n file = new Blob([file], { type: options['Content-Type'] || 'text/plain' });\n }\n\n if (file instanceof Blob && !(file instanceof File) && path.endsWith('.{ext}')) {\n throw new Error('If using Blob or file data string, you must provide a valid file extension in the path.');\n }\n\n if ((file instanceof Blob) || (file as any) instanceof File) {\n options['Content-Type'] = options['Content-Type'] || file.type;\n }\n\n if (options['filename']) {\n const filename = this.replaceExt(options['filename'], file);\n options['Content-Disposition'] = 'attachment; filename*=UTF-8\\'\\'' + encodeURIComponent(filename);\n }\n\n path = this.replaceExt(path, file);\n\n options['key'] = trimSlashes(this.options.subfolder || '') + '/'\n + trimSlashes(path);\n options['key'] = trimSlashes(options['key']);\n options['Content-Type'] = options['Content-Type'] || undefined;\n options['Content-Disposition'] = options['Content-Disposition'] || undefined;\n\n // Prepare pre-signed data\n for (let key in inputs) {\n fileData.set(key, inputs[key]);\n }\n\n // Prepare custom data\n for (let key of Object.keys(this.options.starts_with)) {\n if (options[key]) {\n fileData.set(key, options[key]);\n }\n }\n\n fileData.append('file', file);\n\n this.trigger('start', fileData);\n\n try {\n let res = await httpClient.post(\n this.options.endpoint || '',\n fileData,\n {\n signal: options.signal,\n onUploadProgress: (e) => {\n if (options.onUploadProgress) {\n options.onUploadProgress(e);\n }\n\n this.trigger('upload-progress', e);\n\n if (e.total != null) {\n this.trigger('progress', e.loaded / e.total, e);\n }\n }\n }\n ) as S3UploaderResponse;\n\n const url = this.options.viewerHost + '/'\n + trimSlashes(path);\n\n this.trigger('success', url, res);\n\n res.url = url;\n\n return res;\n } finally {\n this.trigger('end');\n }\n }\n\n replaceExt(path: string, file: File | Blob): string {\n if (file instanceof File) {\n const fileExt = file.name.split('.').pop();\n\n if (path.endsWith('.{ext}')) {\n return path.replace(/\\.{ext}$/, fileExt ? '.' + fileExt : '');\n }\n }\n\n return path;\n }\n\n on(event: 'start', handler: StartEventHandler): this;\n on(event: 'success', handler: SuccessEventHandler): this;\n on(event: 'end', handler: EndEventHandler): this;\n on(event: 'upload-progress', handler: UploadProgressEventHandler): this;\n on(event: 'progress', handler: ProgressEventHandler): this;\n on(event: string | string[], handler: EventHandler): this {\n return super.on(event, handler);\n }\n\n onStart(handler: StartEventHandler): this {\n return this.on('start', handler);\n }\n\n onSuccess(handler: SuccessEventHandler): this {\n return this.on('success', handler);\n }\n\n onEnd(handler: EndEventHandler): this {\n return this.on('end', handler);\n }\n\n onProgress(handler: UploadProgressEventHandler): this {\n return this.on('upload-progress', handler);\n }\n\n onProgressWithTotal(handler: ProgressEventHandler): this {\n return this.on('progress', handler);\n }\n}\n\ntype EndEventHandler = () => void;\ntype SuccessEventHandler = (url: string, res: S3UploaderResponse) => void;\ntype StartEventHandler = (fileData: FormData) => void;\ntype UploadProgressEventHandler = (e: AxiosProgressEvent) => void;\ntype ProgressEventHandler = (total: number, e: AxiosProgressEvent) => void;\n\nfunction trimSlashes(str: string) {\n return str.replace(/^\\/+|\\/+$/g, '');\n}\n\nexport interface S3UploaderResponse extends AxiosResponse {\n url: string;\n}\n\nexport interface S3UploaderGlobalOptions {\n endpoint?: string;\n subfolder?: string;\n viewerHost?: string;\n starts_with: any[];\n formInputs?: {\n acl: string;\n bucket: string;\n key: string;\n Policy: string;\n 'X-Amz-Algorithm': string;\n 'X-Amz-Credential': string;\n 'X-Amz-Date': string;\n 'X-Amz-Signature': string;\n [name: string]: any\n },\n}\n\nexport interface S3UploaderRequestOptions {\n formInputs?: { [name: string]: any };\n onUploadProgress?: (e: AxiosProgressEvent) => void;\n 'Content-Type'?: string;\n 'Content-Disposition'?: string;\n key?: string;\n signal?: AbortSignal;\n\n [name: string]: any;\n}\n\nexport interface S3UploaderModule {\n get(name: string, options?: Partial<S3UploaderGlobalOptions>): S3Uploader;\n create(name: string, options?: Partial<S3UploaderGlobalOptions>): S3Uploader;\n destroy(name: string): void;\n S3Uploader: typeof S3Uploader;\n}\n"],"mappings":"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"}