@cocreate/file 1.0.0 → 1.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +19 -0
- package/CoCreate.config.js +3 -5
- package/demo/index.html +14 -9
- package/package.json +7 -5
- package/src/client.js +318 -0
- package/src/index.js +14 -253
- package/src/{upload.js → server.js} +31 -18
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,22 @@
|
|
|
1
|
+
# [1.2.0](https://github.com/CoCreate-app/CoCreate-file/compare/v1.1.0...v1.2.0) (2023-06-09)
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
### Bug Fixes
|
|
5
|
+
|
|
6
|
+
* Update dependencies versions for [@cocreate](https://github.com/cocreate) libraries ([c86d68d](https://github.com/CoCreate-app/CoCreate-file/commit/c86d68d3ef7fa76e8f52867f7abecaa67bab8270))
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
### Features
|
|
10
|
+
|
|
11
|
+
* client and server functions ([af50769](https://github.com/CoCreate-app/CoCreate-file/commit/af5076902607f52c51f5a4fcca4a4a5554617b92))
|
|
12
|
+
|
|
13
|
+
# [1.1.0](https://github.com/CoCreate-app/CoCreate-file/compare/v1.0.0...v1.1.0) (2023-06-08)
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
### Features
|
|
17
|
+
|
|
18
|
+
* add template_id to fileInput and render selected files using template and placeholders ([ca29280](https://github.com/CoCreate-app/CoCreate-file/commit/ca292805b3b3d71e95a022cb249082ace540d33a))
|
|
19
|
+
|
|
1
20
|
# 1.0.0 (2023-06-06)
|
|
2
21
|
|
|
3
22
|
|
package/CoCreate.config.js
CHANGED
package/demo/index.html
CHANGED
|
@@ -13,23 +13,28 @@
|
|
|
13
13
|
</head>
|
|
14
14
|
<body>
|
|
15
15
|
<form>
|
|
16
|
-
<input type="file"
|
|
17
|
-
<button actions="
|
|
16
|
+
<input type="file" />
|
|
17
|
+
<button actions="upload">upload</button>
|
|
18
18
|
</form>
|
|
19
19
|
|
|
20
20
|
<form>
|
|
21
|
-
<input type="file"
|
|
22
|
-
<button actions="
|
|
21
|
+
<input type="file" multiple />
|
|
22
|
+
<button actions="upload">upload</button>
|
|
23
23
|
</form>
|
|
24
24
|
<form>
|
|
25
|
-
<input type="file"
|
|
26
|
-
<button actions="
|
|
25
|
+
<input type="file" directory />
|
|
26
|
+
<button actions="upload">upload</button>
|
|
27
27
|
</form>
|
|
28
28
|
<form>
|
|
29
|
-
<input type="file"
|
|
30
|
-
<
|
|
29
|
+
<input type="file" directory multiple template="file-preview" />
|
|
30
|
+
<div type="file" directory multiple>
|
|
31
|
+
// adds input with display none
|
|
32
|
+
</div>
|
|
33
|
+
<button actions="upload">upload</button>
|
|
31
34
|
</form>
|
|
32
|
-
|
|
35
|
+
<div template="file-preview">
|
|
36
|
+
<span>{{file.name}}</span>
|
|
37
|
+
</div>
|
|
33
38
|
<script src="../dist/CoCreate-file.js"></script>
|
|
34
39
|
<script src="https://cdn.cocreate.app/latest/CoCreate.min.js"></script>
|
|
35
40
|
</body>
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cocreate/file",
|
|
3
|
-
"version": "1.
|
|
4
|
-
"description": "
|
|
3
|
+
"version": "1.2.0",
|
|
4
|
+
"description": "A headless file uploader that uses HTML5 attributes for customization. Allows easy upload of files to server.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"file",
|
|
7
7
|
"chain-functions",
|
|
@@ -28,7 +28,8 @@
|
|
|
28
28
|
"start": "npx webpack --config webpack.config.js",
|
|
29
29
|
"build": "NODE_ENV=production npx webpack --config webpack.config.js",
|
|
30
30
|
"dev": "npx webpack --config webpack.config.js --watch",
|
|
31
|
-
"docs": "node ./node_modules/@cocreate/docs/src/index.js"
|
|
31
|
+
"docs": "node ./node_modules/@cocreate/docs/src/index.js",
|
|
32
|
+
"postinstall": "node ./node_modules/@cocreate/cli/check-coc.js"
|
|
32
33
|
},
|
|
33
34
|
"repository": {
|
|
34
35
|
"type": "git",
|
|
@@ -48,6 +49,7 @@
|
|
|
48
49
|
"devDependencies": {
|
|
49
50
|
"@babel/core": "^7.9.6",
|
|
50
51
|
"@babel/preset-env": "^7.9.6",
|
|
52
|
+
"@cocreate/cli": "^1.29.3",
|
|
51
53
|
"babel-loader": "^8.1.0",
|
|
52
54
|
"clean-webpack-plugin": "^3.0.0",
|
|
53
55
|
"file-loader": "^6.2.0",
|
|
@@ -60,7 +62,7 @@
|
|
|
60
62
|
},
|
|
61
63
|
"dependencies": {
|
|
62
64
|
"@cocreate/actions": "^1.8.18",
|
|
63
|
-
"@cocreate/docs": "^1.
|
|
64
|
-
"@cocreate/utils": "^1.21.
|
|
65
|
+
"@cocreate/docs": "^1.8.2",
|
|
66
|
+
"@cocreate/utils": "^1.21.3"
|
|
65
67
|
}
|
|
66
68
|
}
|
package/src/client.js
ADDED
|
@@ -0,0 +1,318 @@
|
|
|
1
|
+
import observer from '@cocreate/observer';
|
|
2
|
+
import crud from '@cocreate/crud-client';
|
|
3
|
+
import action from '@cocreate/actions';
|
|
4
|
+
import render from '@cocreate/render';
|
|
5
|
+
import '@cocreate/element-prototype';
|
|
6
|
+
|
|
7
|
+
let inputs = new Map();
|
|
8
|
+
|
|
9
|
+
function init(elements) {
|
|
10
|
+
// Returns an array of elements.
|
|
11
|
+
if (!elements)
|
|
12
|
+
elements = document.querySelectorAll('[type="file"]')
|
|
13
|
+
|
|
14
|
+
// If elements is an array of elements returns an array of elements.
|
|
15
|
+
else if (!Array.isArray(elements))
|
|
16
|
+
elements = [elements]
|
|
17
|
+
for (let i = 0; i < elements.length; i++) {
|
|
18
|
+
if (elements[i].tagName !== 'INPUT') {
|
|
19
|
+
// TODO: create input and append to div if input dos not exist
|
|
20
|
+
}
|
|
21
|
+
elements[i].getValue = async () => await getSelectedFiles([elements[i]], true)
|
|
22
|
+
|
|
23
|
+
// elements[i].setValue = (value) => pickr.setColor(value);
|
|
24
|
+
if (elements[i].hasAttribute('directory')) {
|
|
25
|
+
if (window.showDirectoryPicker)
|
|
26
|
+
elements[i].addEventListener("click", selectDirectory);
|
|
27
|
+
else if ('webkitdirectory' in elements[i]) {
|
|
28
|
+
elements[i].webkitdirectory = true
|
|
29
|
+
elements[i].addEventListener("change", handleFileInputChange)
|
|
30
|
+
} else
|
|
31
|
+
console.error("Directory selection not supported in this browser.");
|
|
32
|
+
} else if (window.showOpenFilePicker)
|
|
33
|
+
elements[i].addEventListener("click", selectFile);
|
|
34
|
+
else
|
|
35
|
+
elements[i].addEventListener("change", handleFileInputChange);
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
function handleFileInputChange(event) {
|
|
41
|
+
const input = event.target;
|
|
42
|
+
const files = input.files;
|
|
43
|
+
let selected = inputs.get(input) || []
|
|
44
|
+
selected.push(...files)
|
|
45
|
+
inputs.set(input, selected);
|
|
46
|
+
console.log("Files selected:", files);
|
|
47
|
+
renderFiles(input)
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
async function selectFile(event) {
|
|
51
|
+
event.preventDefault()
|
|
52
|
+
const input = event.target;
|
|
53
|
+
let selected = inputs.get(input) || []
|
|
54
|
+
try {
|
|
55
|
+
const multiple = input.multiple
|
|
56
|
+
const selectedFiles = await window.showOpenFilePicker({ multiple });
|
|
57
|
+
|
|
58
|
+
for (const handle of selectedFiles) {
|
|
59
|
+
selected.push(handle)
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
if (selected.length) {
|
|
63
|
+
inputs.set(input, selected);
|
|
64
|
+
console.log("Files selected:", selected);
|
|
65
|
+
renderFiles(input)
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
} catch (error) {
|
|
69
|
+
if (error.name !== 'AbortError') {
|
|
70
|
+
console.error("Error selecting files:", error);
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
async function selectDirectory(event) {
|
|
76
|
+
event.preventDefault()
|
|
77
|
+
const input = event.target;
|
|
78
|
+
let selected = inputs.get(input) || []
|
|
79
|
+
|
|
80
|
+
try {
|
|
81
|
+
const handle = await window.showDirectoryPicker();
|
|
82
|
+
selected.push(handle)
|
|
83
|
+
|
|
84
|
+
if (selected.length) {
|
|
85
|
+
inputs.set(input, selected);
|
|
86
|
+
console.log("Directory selected:", selected);
|
|
87
|
+
renderFiles(input)
|
|
88
|
+
}
|
|
89
|
+
} catch (error) {
|
|
90
|
+
if (error.name !== 'AbortError') {
|
|
91
|
+
console.error("Error selecting directory:", error);
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
async function getNewFileHandle() {
|
|
97
|
+
// const options = {
|
|
98
|
+
// types: [
|
|
99
|
+
// {
|
|
100
|
+
// description: 'Text Files',
|
|
101
|
+
// accept: {
|
|
102
|
+
// 'text/plain': ['.txt'],
|
|
103
|
+
// },
|
|
104
|
+
// },
|
|
105
|
+
// ],
|
|
106
|
+
// };
|
|
107
|
+
const handle = await window.showSaveFilePicker(options);
|
|
108
|
+
return handle;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
async function getSelectedFiles(fileInputs, isObject) {
|
|
112
|
+
const files = [];
|
|
113
|
+
|
|
114
|
+
if (!Array.isArray(fileInputs))
|
|
115
|
+
fileInputs = [fileInputs]
|
|
116
|
+
|
|
117
|
+
for (let input of fileInputs) {
|
|
118
|
+
const selected = inputs.get(input) || []
|
|
119
|
+
|
|
120
|
+
for (let i = 0; i < selected.length; i++) {
|
|
121
|
+
let file
|
|
122
|
+
if (selected[i] instanceof FileSystemDirectoryHandle) {
|
|
123
|
+
// The object is an instance of FileSystemFileHandle
|
|
124
|
+
const handles = await getSelectedDirectoryFiles(selected[i], selected[i].name)
|
|
125
|
+
for (let handle of handles) {
|
|
126
|
+
if (handle.kind === 'file')
|
|
127
|
+
file = await handle.getFile();
|
|
128
|
+
else if (handle.kind === 'directory')
|
|
129
|
+
file = { ...handle, name: handle.name }
|
|
130
|
+
else continue
|
|
131
|
+
|
|
132
|
+
if (isObject)
|
|
133
|
+
file = await readFile(file)
|
|
134
|
+
|
|
135
|
+
files.push(file)
|
|
136
|
+
}
|
|
137
|
+
} else {
|
|
138
|
+
if (selected[i] instanceof FileSystemFileHandle) {
|
|
139
|
+
// The object is an instance of FileSystemFileHandle
|
|
140
|
+
file = await selected[i].getFile();
|
|
141
|
+
} else {
|
|
142
|
+
// The object is not an instance of FileSystemFileHandle
|
|
143
|
+
console.log("It's not a FileSystemFileHandle object");
|
|
144
|
+
file = selected[i]
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
if (isObject)
|
|
148
|
+
file = await readFile(file)
|
|
149
|
+
|
|
150
|
+
files.push(file)
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
return files
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
async function getSelectedDirectoryFiles(handle, name) {
|
|
160
|
+
let files = [];
|
|
161
|
+
for await (const entry of handle.values()) {
|
|
162
|
+
entry.directory = '/' + name
|
|
163
|
+
entry.parentDirectory = name.split("/").pop();
|
|
164
|
+
entry.path = '/' + name + '/' + entry.name
|
|
165
|
+
if (!entry.webkitRelativePath)
|
|
166
|
+
entry.webkitRelativePath = name
|
|
167
|
+
|
|
168
|
+
if (entry.kind === 'file') {
|
|
169
|
+
files.push(entry);
|
|
170
|
+
} else if (entry.kind === 'directory') {
|
|
171
|
+
entry.type = 'text/directory'
|
|
172
|
+
files.push(entry);
|
|
173
|
+
const entries = await getSelectedDirectoryFiles(entry, name + '/' + entry.name);
|
|
174
|
+
files = files.concat(entries);
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
return files;
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
// This function reads the file and returns its src
|
|
181
|
+
function readFile(file) {
|
|
182
|
+
// Return a new promise that resolves the file object
|
|
183
|
+
return new Promise((resolve) => {
|
|
184
|
+
file["content-type"] = file.type
|
|
185
|
+
|
|
186
|
+
// Split the file type into an array
|
|
187
|
+
const fileType = file.type.split('/');
|
|
188
|
+
let readAs;
|
|
189
|
+
|
|
190
|
+
// Check if the file type is a directory
|
|
191
|
+
if (fileType[1] === 'directory') {
|
|
192
|
+
return resolve(file)
|
|
193
|
+
}
|
|
194
|
+
// Check if the file type is a image
|
|
195
|
+
else if (['jpg', 'jpeg', 'png', 'gif', 'bmp'].includes(fileType[1])
|
|
196
|
+
|| fileType[0] === 'image') {
|
|
197
|
+
readAs = 'readAsDataURL';
|
|
198
|
+
}
|
|
199
|
+
// Check if the file type is a video
|
|
200
|
+
else if (['mp4', 'avi', 'mov', 'mpeg', 'flv'].includes(fileType[1])
|
|
201
|
+
|| fileType[0] === 'video') {
|
|
202
|
+
readAs = 'readAsDataURL';
|
|
203
|
+
}
|
|
204
|
+
// Check if the file type is an audio
|
|
205
|
+
else if (['mp3', 'wav', 'wma', 'aac', 'ogg'].includes(fileType[1])
|
|
206
|
+
|| fileType[0] === 'audio') { // updated condition
|
|
207
|
+
readAs = 'readAsDataURL';
|
|
208
|
+
}
|
|
209
|
+
// Check if the file type is a pdf
|
|
210
|
+
else if (fileType[1] === 'pdf') {
|
|
211
|
+
readAs = 'readAsDataURL';
|
|
212
|
+
}
|
|
213
|
+
// Check if the file type is a document
|
|
214
|
+
else if (['doc', 'msword', 'docx', 'xlsx', 'pptx'].includes(fileType[1])) {
|
|
215
|
+
readAs = 'readAsBinaryString';
|
|
216
|
+
}
|
|
217
|
+
// Otherwise, assume the file type is text
|
|
218
|
+
else {
|
|
219
|
+
readAs = 'readAsText';
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
// Create a FileReader instance to read the file
|
|
223
|
+
const reader = new FileReader();
|
|
224
|
+
// Read the file based on the file type
|
|
225
|
+
reader[readAs](file);
|
|
226
|
+
// When the file is loaded, resolve the file object
|
|
227
|
+
reader.onload = () => {
|
|
228
|
+
file.src = reader.result;
|
|
229
|
+
// If the file type is a document, convert it to base64 encoding
|
|
230
|
+
if (['doc', 'msword', 'docx', 'xlsx', 'pptx'].includes(fileType)) {
|
|
231
|
+
file.src = btoa(file.src);
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
// Resolve the file object
|
|
235
|
+
resolve(file);
|
|
236
|
+
};
|
|
237
|
+
});
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
async function fileAction(btn, params, action) {
|
|
241
|
+
const form = btn.closest('form')
|
|
242
|
+
let inputs = form.querySelectorAll('input[type="file"]')
|
|
243
|
+
let fileObjects = await getSelectedFiles(Array.from(inputs), true)
|
|
244
|
+
|
|
245
|
+
console.log('fileObjects', fileObjects)
|
|
246
|
+
document.dispatchEvent(new CustomEvent(action, {
|
|
247
|
+
detail: {}
|
|
248
|
+
}));
|
|
249
|
+
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
// may be best to use getValue() so form so inputtype files can be can be managed in forms
|
|
253
|
+
async function save(inputs, collection, document_id) {
|
|
254
|
+
let files = await getSelectedFiles(inputs, true)
|
|
255
|
+
|
|
256
|
+
let response = await crud.updateDocument({
|
|
257
|
+
collection,
|
|
258
|
+
document: files,
|
|
259
|
+
upsert: true
|
|
260
|
+
});
|
|
261
|
+
|
|
262
|
+
if (response && (!document_id || document_id !== response.document_id)) {
|
|
263
|
+
crud.setDocumentId(element, collection, response.document_id);
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
return response
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
async function getFiles(inputs) {
|
|
270
|
+
let files = await getSelectedFiles(inputs)
|
|
271
|
+
return files
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
async function getObjects(inputs) {
|
|
275
|
+
let objects = await getSelectedFiles(inputs, true)
|
|
276
|
+
return objects
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
function renderFiles(input) {
|
|
280
|
+
// TODO: support
|
|
281
|
+
let template_id = input.getAttribute('template_id')
|
|
282
|
+
if (template_id) {
|
|
283
|
+
// if data items are handle it will not yet have all the details
|
|
284
|
+
const data = inputs.get(input)
|
|
285
|
+
if (data.length) return
|
|
286
|
+
render.data({
|
|
287
|
+
selector: `[template='${template_id}']`,
|
|
288
|
+
data
|
|
289
|
+
});
|
|
290
|
+
}
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
observer.init({
|
|
294
|
+
name: 'CoCreateFileAddedNodes',
|
|
295
|
+
observe: ['addedNodes'],
|
|
296
|
+
target: 'input[type="file"]',
|
|
297
|
+
callback: mutation => init(mutation.target)
|
|
298
|
+
|
|
299
|
+
});
|
|
300
|
+
|
|
301
|
+
observer.init({
|
|
302
|
+
name: 'CoCreateFileAttributes',
|
|
303
|
+
observe: ['attributes'],
|
|
304
|
+
attributeName: ['type'],
|
|
305
|
+
target: 'input[type="file"]',
|
|
306
|
+
callback: mutation => init(mutation.target)
|
|
307
|
+
});
|
|
308
|
+
|
|
309
|
+
action.init({
|
|
310
|
+
name: "upload",
|
|
311
|
+
callback: (btn, params) => {
|
|
312
|
+
fileAction(btn, params, "upload")
|
|
313
|
+
}
|
|
314
|
+
})
|
|
315
|
+
|
|
316
|
+
init()
|
|
317
|
+
|
|
318
|
+
export default { getFiles, getObjects }
|
package/src/index.js
CHANGED
|
@@ -1,253 +1,14 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
event.preventDefault()
|
|
16
|
-
const input = event.target;
|
|
17
|
-
let selected = inputs.get(input) || []
|
|
18
|
-
try {
|
|
19
|
-
const multiple = input.multiple
|
|
20
|
-
const selectedFiles = await window.showOpenFilePicker({ multiple });
|
|
21
|
-
|
|
22
|
-
for (const handle of selectedFiles) {
|
|
23
|
-
selected.push(handle)
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
if (selected.length) {
|
|
27
|
-
inputs.set(input, selected);
|
|
28
|
-
console.log("Files selected:", selected);
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
} catch (error) {
|
|
32
|
-
if (error.name !== 'AbortError') {
|
|
33
|
-
console.error("Error selecting files:", error);
|
|
34
|
-
}
|
|
35
|
-
}
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
async function selectDirectory(event) {
|
|
39
|
-
event.preventDefault()
|
|
40
|
-
const input = event.target;
|
|
41
|
-
let selected = inputs.get(input) || []
|
|
42
|
-
|
|
43
|
-
try {
|
|
44
|
-
const multiple = input.multiple
|
|
45
|
-
const handle = await window.showDirectoryPicker();
|
|
46
|
-
selected.push(handle)
|
|
47
|
-
|
|
48
|
-
if (selected.length) {
|
|
49
|
-
inputs.set(input, selected);
|
|
50
|
-
console.log("Directory selected:", selected);
|
|
51
|
-
}
|
|
52
|
-
} catch (error) {
|
|
53
|
-
if (error.name !== 'AbortError') {
|
|
54
|
-
console.error("Error selecting directory:", error);
|
|
55
|
-
}
|
|
56
|
-
}
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
async function getNewFileHandle() {
|
|
60
|
-
// const options = {
|
|
61
|
-
// types: [
|
|
62
|
-
// {
|
|
63
|
-
// description: 'Text Files',
|
|
64
|
-
// accept: {
|
|
65
|
-
// 'text/plain': ['.txt'],
|
|
66
|
-
// },
|
|
67
|
-
// },
|
|
68
|
-
// ],
|
|
69
|
-
// };
|
|
70
|
-
const handle = await window.showSaveFilePicker(options);
|
|
71
|
-
return handle;
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
async function generateFileObjects(fileInputs, isObject) {
|
|
75
|
-
const files = [];
|
|
76
|
-
|
|
77
|
-
if (!Array.isArray(fileInputs))
|
|
78
|
-
fileInputs = [fileInputs]
|
|
79
|
-
|
|
80
|
-
for (let input of fileInputs) {
|
|
81
|
-
const selected = inputs.get(input) || []
|
|
82
|
-
|
|
83
|
-
for (let i = 0; i < selected.length; i++) {
|
|
84
|
-
let file
|
|
85
|
-
if (selected[i] instanceof FileSystemDirectoryHandle) {
|
|
86
|
-
// The object is an instance of FileSystemFileHandle
|
|
87
|
-
const handles = await getFilesFromDirectory(selected[i], selected[i].name)
|
|
88
|
-
for (let handle of handles) {
|
|
89
|
-
file = await handle.getFile();
|
|
90
|
-
file.directory = handle.directory
|
|
91
|
-
file.parentDirectory = handle.parentDirectory
|
|
92
|
-
file.path = handle.path
|
|
93
|
-
|
|
94
|
-
if (isObject)
|
|
95
|
-
files.push(await createFileObject(file))
|
|
96
|
-
else
|
|
97
|
-
files.push(file)
|
|
98
|
-
}
|
|
99
|
-
} else {
|
|
100
|
-
if (selected[i] instanceof FileSystemFileHandle) {
|
|
101
|
-
// The object is an instance of FileSystemFileHandle
|
|
102
|
-
file = await selected[i].getFile();
|
|
103
|
-
} else {
|
|
104
|
-
// The object is not an instance of FileSystemFileHandle
|
|
105
|
-
console.log("It's not a FileSystemFileHandle object");
|
|
106
|
-
file = selected[i]
|
|
107
|
-
}
|
|
108
|
-
const fileUrl = URL.createObjectURL(file);
|
|
109
|
-
console.log(fileUrl);
|
|
110
|
-
if (isObject = true)
|
|
111
|
-
files.push(await createFileObject(file))
|
|
112
|
-
else
|
|
113
|
-
files.push(file)
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
}
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
return files
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
async function getFilesFromDirectory(handle, name) {
|
|
123
|
-
let files = [];
|
|
124
|
-
for await (const entry of handle.values()) {
|
|
125
|
-
if (entry.kind === 'file') {
|
|
126
|
-
entry.directory = '/' + name
|
|
127
|
-
entry.parentDirectory = name.split("/").pop();
|
|
128
|
-
entry.path = '/' + name + '/' + entry.name
|
|
129
|
-
if (!entry.webkitRelativePath)
|
|
130
|
-
entry.webkitRelativePath = name
|
|
131
|
-
|
|
132
|
-
files.push(entry);
|
|
133
|
-
} else if (entry.kind === 'directory') {
|
|
134
|
-
const entries = await getFilesFromDirectory(entry, name + '/' + entry.name);
|
|
135
|
-
files = files.concat(entries);
|
|
136
|
-
}
|
|
137
|
-
}
|
|
138
|
-
return files;
|
|
139
|
-
}
|
|
140
|
-
|
|
141
|
-
// This function creates a file object from the given file
|
|
142
|
-
function createFileObject(file) {
|
|
143
|
-
// Return a new promise that resolves the file object
|
|
144
|
-
return new Promise((resolve) => {
|
|
145
|
-
// Create a FileReader instance to read the file
|
|
146
|
-
const reader = new FileReader();
|
|
147
|
-
// Split the file type into an array
|
|
148
|
-
const fileType = file.type.split('/');
|
|
149
|
-
let readAs;
|
|
150
|
-
|
|
151
|
-
// Check if the file type is an image
|
|
152
|
-
if (['jpg', 'jpeg', 'png', 'gif', 'bmp'].includes(fileType[1])
|
|
153
|
-
|| fileType[0] === 'image') {
|
|
154
|
-
readAs = 'readAsDataURL';
|
|
155
|
-
}
|
|
156
|
-
// Check if the file type is a video
|
|
157
|
-
else if (['mp4', 'avi', 'mov', 'mpeg', 'flv'].includes(fileType[1])
|
|
158
|
-
|| fileType[0] === 'video') {
|
|
159
|
-
readAs = 'readAsDataURL';
|
|
160
|
-
}
|
|
161
|
-
// Check if the file type is an audio
|
|
162
|
-
else if (['mp3', 'wav', 'wma', 'aac', 'ogg'].includes(fileType[1])
|
|
163
|
-
|| fileType[0] === 'audio') { // updated condition
|
|
164
|
-
readAs = 'readAsDataURL';
|
|
165
|
-
}
|
|
166
|
-
// Check if the file type is a pdf
|
|
167
|
-
else if (fileType[1] === 'pdf') {
|
|
168
|
-
readAs = 'readAsDataURL';
|
|
169
|
-
}
|
|
170
|
-
// Check if the file type is a document
|
|
171
|
-
else if (['doc', 'msword', 'docx', 'xlsx', 'pptx'].includes(fileType[1])) {
|
|
172
|
-
readAs = 'readAsBinaryString';
|
|
173
|
-
}
|
|
174
|
-
// Otherwise, assume the file type is text
|
|
175
|
-
else {
|
|
176
|
-
readAs = 'readAsText';
|
|
177
|
-
}
|
|
178
|
-
|
|
179
|
-
// Read the file based on the file type
|
|
180
|
-
reader[readAs](file);
|
|
181
|
-
// When the file is loaded, resolve the file object
|
|
182
|
-
reader.onload = () => {
|
|
183
|
-
let src = reader.result;
|
|
184
|
-
// If the file type is a document, convert it to base64 encoding
|
|
185
|
-
if (['doc', 'msword', 'docx', 'xlsx', 'pptx'].includes(fileType)) {
|
|
186
|
-
src = btoa(src);
|
|
187
|
-
}
|
|
188
|
-
|
|
189
|
-
// Resolve the file object
|
|
190
|
-
resolve({
|
|
191
|
-
name: file.name,
|
|
192
|
-
path: file.path,
|
|
193
|
-
src,
|
|
194
|
-
directory: file.directory,
|
|
195
|
-
parentDirectory: file.parentDirectory,
|
|
196
|
-
size: file.size,
|
|
197
|
-
"content-type": file.type,
|
|
198
|
-
lastModified: file.lastModified,
|
|
199
|
-
lastModifiedDate: file.lastModifiedDate,
|
|
200
|
-
modified: { on: file.lastModifiedDate, by: "unknown" },
|
|
201
|
-
public: "true"
|
|
202
|
-
});
|
|
203
|
-
};
|
|
204
|
-
});
|
|
205
|
-
}
|
|
206
|
-
|
|
207
|
-
const fileInputs = document.querySelectorAll('input[type="file"]')
|
|
208
|
-
|
|
209
|
-
for (let i = 0; i < fileInputs.length; i++) {
|
|
210
|
-
if (fileInputs[i].hasAttribute('directory')) {
|
|
211
|
-
if (window.showDirectoryPicker)
|
|
212
|
-
fileInputs[i].addEventListener("click", selectDirectory);
|
|
213
|
-
else if ('webkitdirectory' in fileInputs[i]) {
|
|
214
|
-
fileInputs[i].webkitdirectory = true
|
|
215
|
-
fileInputs[i].addEventListener("change", handleFileInputChange)
|
|
216
|
-
} else
|
|
217
|
-
console.error("Directory selection not supported in this browser.");
|
|
218
|
-
} else if (window.showOpenFilePicker)
|
|
219
|
-
fileInputs[i].addEventListener("click", selectFile);
|
|
220
|
-
else
|
|
221
|
-
fileInputs[i].addEventListener("change", handleFileInputChange);
|
|
222
|
-
|
|
223
|
-
}
|
|
224
|
-
|
|
225
|
-
async function fileAction(btn, params, action) {
|
|
226
|
-
const form = btn.closest('form')
|
|
227
|
-
let inputs = form.querySelectorAll('input[type="file"]')
|
|
228
|
-
let fileObjects = await generateFileObjects(Array.from(inputs), true)
|
|
229
|
-
|
|
230
|
-
console.log('fileObjects', fileObjects)
|
|
231
|
-
document.dispatchEvent(new CustomEvent(action, {
|
|
232
|
-
detail: {}
|
|
233
|
-
}));
|
|
234
|
-
|
|
235
|
-
}
|
|
236
|
-
|
|
237
|
-
async function getFiles(inputs) {
|
|
238
|
-
let files = await generateFileObjects(fileInputs)
|
|
239
|
-
return files
|
|
240
|
-
}
|
|
241
|
-
async function getObjects(inputs) {
|
|
242
|
-
let objects = await generateFileObjects(fileInputs, true)
|
|
243
|
-
return objects
|
|
244
|
-
}
|
|
245
|
-
|
|
246
|
-
actions.init({
|
|
247
|
-
name: "uploadFiles",
|
|
248
|
-
callback: (btn, params) => {
|
|
249
|
-
fileAction(btn, params, "uploadFiles")
|
|
250
|
-
}
|
|
251
|
-
})
|
|
252
|
-
|
|
253
|
-
export default { getFiles, getObjects }
|
|
1
|
+
(function (root, factory) {
|
|
2
|
+
if (typeof define === 'function' && define.amd) {
|
|
3
|
+
define(["./client"], function (CoCreateFile) {
|
|
4
|
+
return factory(CoCreateFile)
|
|
5
|
+
});
|
|
6
|
+
} else if (typeof module === 'object' && module.exports) {
|
|
7
|
+
const CoCreateFile = require("./server.js")
|
|
8
|
+
module.exports = factory(CoCreateFile);
|
|
9
|
+
} else {
|
|
10
|
+
root.returnExports = factory(root["./client.js"]);
|
|
11
|
+
}
|
|
12
|
+
}(typeof self !== 'undefined' ? self : this, function (CoCreateFile) {
|
|
13
|
+
return CoCreateFile;
|
|
14
|
+
}));
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
const crud = require('@cocreate/crud-client')
|
|
2
|
+
const cli = require('@cocreate/cli')
|
|
2
3
|
const mime = require('mime-types')
|
|
3
4
|
const fs = require('fs');
|
|
4
5
|
const path = require('path');
|
|
5
6
|
|
|
6
7
|
|
|
7
|
-
module.exports = async function
|
|
8
|
+
module.exports = async function file(CoCreateConfig) {
|
|
8
9
|
|
|
9
|
-
let CoCreateConfig;
|
|
10
10
|
let configFile = path.resolve(process.cwd(), 'CoCreate.config.js');
|
|
11
11
|
if (fs.existsSync(configFile)) {
|
|
12
12
|
CoCreateConfig = require(configFile);
|
|
@@ -15,20 +15,34 @@ module.exports = async function upload(repos, args) {
|
|
|
15
15
|
process.exit()
|
|
16
16
|
}
|
|
17
17
|
|
|
18
|
-
let {
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
18
|
+
let { directories, sources } = CoCreateConfig;
|
|
19
|
+
let config = await cli.config([
|
|
20
|
+
{
|
|
21
|
+
key: 'organization_id',
|
|
22
|
+
prompt: 'Enter your organization_id: '
|
|
23
|
+
}, {
|
|
24
|
+
key: 'host',
|
|
25
|
+
prompt: 'Enter the host: '
|
|
26
|
+
}, {
|
|
27
|
+
propmt: 'Choose an authentication option: \n1.key\n2.Sign In\n',
|
|
28
|
+
choices: {
|
|
29
|
+
'1': {
|
|
30
|
+
key: 'key',
|
|
31
|
+
prompt: 'Enter your key: '
|
|
32
|
+
},
|
|
33
|
+
'2': [
|
|
34
|
+
{
|
|
35
|
+
key: 'email',
|
|
36
|
+
prompt: 'Enter your email: '
|
|
37
|
+
},
|
|
38
|
+
{
|
|
39
|
+
key: 'password',
|
|
40
|
+
prompt: 'Enter your password: '
|
|
41
|
+
}
|
|
42
|
+
]
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
])
|
|
32
46
|
|
|
33
47
|
if (!config.organization_id || !config.host || !config.key && (!config.password || config.email)) {
|
|
34
48
|
console.log('One or more required config params could not be found')
|
|
@@ -324,8 +338,7 @@ module.exports = async function upload(repos, args) {
|
|
|
324
338
|
|
|
325
339
|
delete newConfig.config.url
|
|
326
340
|
delete newConfig.config.broadcast
|
|
327
|
-
|
|
328
|
-
write_str = "module.exports = " + write_str;
|
|
341
|
+
const write_str = `module.exports = ${JSON.stringify(globalConfig, null, 4)};`;
|
|
329
342
|
|
|
330
343
|
fs.writeFileSync(configFile, write_str);
|
|
331
344
|
}
|