@cocreate/file 1.14.1 → 1.15.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 CHANGED
@@ -1,3 +1,26 @@
1
+ # [1.15.0](https://github.com/CoCreate-app/CoCreate-file/compare/v1.14.2...v1.15.0) (2024-02-05)
2
+
3
+
4
+ ### Bug Fixes
5
+
6
+ * Removed https://cdn.cocreate.app/latest/CoCreate.min.css ([e0ae28d](https://github.com/CoCreate-app/CoCreate-file/commit/e0ae28de52a02ee58947093f6dad3dd9dfee93e8))
7
+ * renderValue ([4e3308a](https://github.com/CoCreate-app/CoCreate-file/commit/4e3308a157ee2257bc1eb603ddc1484b5579cac8))
8
+ * typo renderValue condition ([65ba50f](https://github.com/CoCreate-app/CoCreate-file/commit/65ba50fe6a84e02bad033f423d39a0ab22fdb766))
9
+
10
+
11
+ ### Features
12
+
13
+ * setValue() ([44d4012](https://github.com/CoCreate-app/CoCreate-file/commit/44d40127823d7ccdf8286943b435eeff939e6e2f))
14
+
15
+ ## [1.14.2](https://github.com/CoCreate-app/CoCreate-file/compare/v1.14.1...v1.14.2) (2024-01-17)
16
+
17
+
18
+ ### Bug Fixes
19
+
20
+ * await getFilter() ([339a343](https://github.com/CoCreate-app/CoCreate-file/commit/339a34379f51982b1447e5fffb81f4001c40b223))
21
+ * support defining storage and database in config ([bc992c1](https://github.com/CoCreate-app/CoCreate-file/commit/bc992c15dd586bdc3de580557617fc3eddb4a176))
22
+ * update to support new query system ([d3d43dc](https://github.com/CoCreate-app/CoCreate-file/commit/d3d43dc0585e6656167a8072fa3d2d848aca3b14))
23
+
1
24
  ## [1.14.1](https://github.com/CoCreate-app/CoCreate-file/compare/v1.14.0...v1.14.1) (2023-12-28)
2
25
 
3
26
 
package/demo/index.html CHANGED
@@ -32,10 +32,26 @@
32
32
  <button actions="upload">upload</button>
33
33
  </form>
34
34
 
35
+ <div
36
+ type="file"
37
+ array="test"
38
+ object=""
39
+ key="image"
40
+ accept="image/*"
41
+ placeholder="Upload Image or Video Thumbnail"
42
+ class="floating-label min-height:40px active"
43
+ render-selector="[template]"
44
+ active>
45
+ <div template>
46
+ <img src="{{image.src}}" alt="image" width="100%" />
47
+ </div>
48
+ </div>
49
+
35
50
  <form>
36
51
  <input
37
52
  type="file"
38
53
  directory
54
+ realtime="false"
39
55
  render-selector="document; [template]" />
40
56
 
41
57
  <button actions="saveLocally">saveLocally</button>
package/docs/index.html CHANGED
@@ -21,11 +21,6 @@
21
21
  property="og:image"
22
22
  content="https://cdn.cocreate.app/docs/file.png" />
23
23
 
24
- <!-- CoCreate CSS -->
25
- <link
26
- rel="stylesheet"
27
- href="https://cdn.cocreate.app/latest/CoCreate.min.css"
28
- type="text/css" />
29
24
  <link
30
25
  rel="stylesheet"
31
26
  href="../index.css"
package/package.json CHANGED
@@ -1,10 +1,9 @@
1
1
  {
2
2
  "name": "@cocreate/file",
3
- "version": "1.14.1",
3
+ "version": "1.15.0",
4
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
- "chain-functions",
8
7
  "cocreate",
9
8
  "low-code-framework",
10
9
  "no-code-framework",
package/src/client.js CHANGED
@@ -26,7 +26,7 @@ import Observer from '@cocreate/observer';
26
26
  import Crud from '@cocreate/crud-client';
27
27
  import Elements from '@cocreate/elements';
28
28
  import Actions from '@cocreate/actions';
29
- import render from '@cocreate/render';
29
+ import { render } from '@cocreate/render';
30
30
  import { queryElements } from '@cocreate/utils';
31
31
  import '@cocreate/element-prototype';
32
32
 
@@ -42,38 +42,67 @@ const Files = new Map();
42
42
  * - If a single element is provided, it initializes that element (assuming it is of type "file").
43
43
  * - If an array of elements is provided, each element in the array is initialized.
44
44
  */
45
- function init(elements) {
45
+ async function init(elements) {
46
46
  if (!elements)
47
47
  elements = document.querySelectorAll('[type="file"]')
48
48
  else if (!Array.isArray(elements))
49
49
  elements = [elements]
50
50
  for (let i = 0; i < elements.length; i++) {
51
- if (elements[i].tagName !== 'INPUT') {
52
- // TODO: create input and append to div if input dos not exist
53
- // check if input exist
54
- let input = document.createElement("input");
55
- input.type = "file";
56
- input.setAttribute('hidden', '')
57
- elements[i].appendChild(input);
51
+ let nestedInput, isInput = elements[i].tagName === 'INPUT'
52
+ if (!isInput) {
53
+ nestedInput = elements[i].querySelector('input[type="file"]')
58
54
  }
59
55
 
60
56
  elements[i].getValue = async () => await getFiles([elements[i]])
61
57
  elements[i].getFiles = async () => await getFiles([elements[i]])
58
+ elements[i].setValue = (files) => setFiles(elements[i], files);
59
+ elements[i].renderValue = (files) => setFiles(elements[i], files);
62
60
 
63
- // elements[i].setValue = (value) => pickr.setColor(value);
61
+ // if (elements[i].renderValue) {
62
+ // let data = await elements[i].getValue()
63
+ // if (data)
64
+ // elements[i].setValue(data)
65
+ // }
64
66
 
65
67
  if (elements[i].hasAttribute('directory')) {
66
- if (window.showDirectoryPicker)
68
+ if (!isInput && window.showDirectoryPicker)
67
69
  elements[i].addEventListener("click", fileEvent);
68
70
  else if ('webkitdirectory' in elements[i]) {
69
71
  elements[i].webkitdirectory = true
70
- elements[i].addEventListener("change", fileEvent)
72
+ if (!isInput && !nestedInput) {
73
+ nestedInput = document.createElement("input");
74
+ nestedInput.type = "file";
75
+ nestedInput.setAttribute('hidden', '')
76
+ elements[i].appendChild(nestedInput);
77
+ }
78
+
79
+ if (nestedInput) {
80
+ elements[i].addEventListener("click", function () {
81
+ nestedInput.click()
82
+ });
83
+ nestedInput.addEventListener("change", fileEvent);
84
+ } else
85
+ elements[i].addEventListener("change", fileEvent);
71
86
  } else
72
87
  console.error("Directory selection not supported in this browser.");
73
- } else if (window.showOpenFilePicker)
88
+ } else if (!isInput && window.showOpenFilePicker)
74
89
  elements[i].addEventListener("click", fileEvent);
75
- else
76
- elements[i].addEventListener("change", fileEvent);
90
+ else {
91
+ if (!isInput && !nestedInput) {
92
+ nestedInput = document.createElement("input");
93
+ nestedInput.type = "file";
94
+ nestedInput.setAttribute('hidden', '')
95
+ elements[i].appendChild(nestedInput);
96
+ }
97
+
98
+ if (nestedInput) {
99
+ elements[i].addEventListener("click", function () {
100
+ nestedInput.click()
101
+ });
102
+ nestedInput.addEventListener("change", fileEvent);
103
+ } else
104
+ elements[i].addEventListener("change", fileEvent);
105
+ }
77
106
  }
78
107
  }
79
108
 
@@ -82,7 +111,7 @@ async function fileEvent(event) {
82
111
  const input = event.target;
83
112
  let selected = inputs.get(input) || new Map()
84
113
  let files = input.files;
85
- if (!files.length) {
114
+ if (!files || !files.length) {
86
115
  event.preventDefault()
87
116
  const multiple = input.multiple
88
117
  if (input.hasAttribute('directory')) {
@@ -120,7 +149,7 @@ async function fileEvent(event) {
120
149
  }
121
150
 
122
151
  if (!files[i].src)
123
- files[i] = await readFile(files[i])
152
+ await readFile(files[i])
124
153
 
125
154
  files[i].directory = handle.directory || '/'
126
155
  files[i].path = handle.path || '/'
@@ -140,15 +169,14 @@ async function fileEvent(event) {
140
169
  inputs.set(input, selected);
141
170
  console.log("Files selected:", selected);
142
171
 
143
- if (!input.renderValue)
144
- input.renderValue(selected.values())
172
+ if (input.renderValue)
173
+ input.renderValue(Array.from(selected.values()))
145
174
 
146
175
  const isImport = input.getAttribute('import')
147
176
  const isRealtime = input.getAttribute('realtime')
148
177
  if (isRealtime !== 'false' && (isImport || isImport == "")) {
149
178
  Import(input)
150
179
  }
151
-
152
180
  }
153
181
  } catch (error) {
154
182
  if (error.name !== 'AbortError') {
@@ -201,9 +229,9 @@ async function getFiles(fileInputs) {
201
229
  for (let input of fileInputs) {
202
230
  const selected = inputs.get(input)
203
231
  if (selected) {
204
- for (let file of selected.values()) {
232
+ for (let file of Array.from(selected.values())) {
205
233
  if (!file.src)
206
- file = await readFile(file)
234
+ await readFile(file)
207
235
 
208
236
  file = await getCustomData({ ...file })
209
237
  files.push(file)
@@ -214,7 +242,6 @@ async function getFiles(fileInputs) {
214
242
  return files
215
243
  }
216
244
 
217
- // gets file custom data
218
245
  async function getCustomData(file) {
219
246
  let form = document.querySelector(`[file_id="${file.id}"]`);
220
247
  if (form) {
@@ -226,10 +253,12 @@ async function getCustomData(file) {
226
253
  }
227
254
  }
228
255
  }
256
+
257
+ delete file.input;
258
+
229
259
  return file;
230
260
  }
231
261
 
232
-
233
262
  // This function reads the file and returns its src
234
263
  function readFile(file) {
235
264
  return new Promise((resolve) => {
@@ -244,7 +273,7 @@ function readFile(file) {
244
273
  } else if (['mp4', 'avi', 'mov', 'mpeg', 'flv'].includes(fileType[1])
245
274
  || fileType[0] === 'video') {
246
275
  readAs = 'readAsDataURL';
247
- } if (['mp3', 'wav', 'wma', 'aac', 'ogg'].includes(fileType[1])
276
+ } else if (['mp3', 'wav', 'wma', 'aac', 'ogg'].includes(fileType[1])
248
277
  || fileType[0] === 'audio') { // updated condition
249
278
  readAs = 'readAsDataURL';
250
279
  } else if (fileType[1] === 'pdf') {
@@ -269,6 +298,24 @@ function readFile(file) {
269
298
  });
270
299
  }
271
300
 
301
+ function setFiles(element, files) {
302
+ if (!files) return
303
+ if (!Array.isArray(files))
304
+ files = [files]
305
+ else if (!files.length)
306
+ return
307
+
308
+ let selected = inputs.get(element) || new Map()
309
+ for (let i = 0; i < files.length; i++) {
310
+ files[i].input = element
311
+ selected.set(files[i].id, files[i])
312
+ Files.set(files[i].id, files[i])
313
+ }
314
+ inputs.set(element, selected);
315
+ if (element.renderValue)
316
+ render({ source: element, data: Array.from(selected.values()) })
317
+ }
318
+
272
319
  async function save(element, action, data) {
273
320
  try {
274
321
  if (!data)
@@ -374,7 +421,7 @@ async function upload(element, data) {
374
421
  let Data = Elements.getObject(input);
375
422
  if (Data.type) {
376
423
  if (input.getFilter)
377
- Data.$filter = input.getFilter()
424
+ Data.$filter = await input.getFilter()
378
425
 
379
426
  let files = await getFiles(input)
380
427
 
@@ -454,7 +501,7 @@ async function Import(element, data) {
454
501
  let Data = Elements.getObject(element[i]);
455
502
  if (Data.type) {
456
503
  if (element[i].getFilter)
457
- Data.$filter = element[i].getFilter()
504
+ Data.$filter = await element[i].getFilter()
458
505
 
459
506
  if (Data.type === 'key')
460
507
  Data.type = 'object'
@@ -504,7 +551,7 @@ async function Export(element, data) {
504
551
  let Data = Elements.getObject(element[i]);
505
552
  if (Data.type) {
506
553
  if (element[i].getFilter)
507
- Data.$filter = element[i].getFilter()
554
+ Data.$filter = await element[i].getFilter()
508
555
 
509
556
  if (Data.type === 'key')
510
557
  Data.type = 'object'
package/src/server.js CHANGED
@@ -127,10 +127,10 @@ module.exports = async function file(CoCreateConfig, configPath, match) {
127
127
  method: 'signIn',
128
128
  array: 'users',
129
129
  $filter: {
130
- query: [
131
- { key: 'email', value: config.email, operator: '$eq' },
132
- { key: 'password', value: config.password, operator: '$eq' }
133
- ]
130
+ query: {
131
+ email: config.email,
132
+ password: config.password
133
+ }
134
134
  },
135
135
  ...config
136
136
  }
@@ -267,6 +267,14 @@ module.exports = async function file(CoCreateConfig, configPath, match) {
267
267
  array: directory.array || 'files',
268
268
  object
269
269
  }
270
+
271
+ if (directory.storage)
272
+ newObject.storage = directory.storage
273
+ if (directory.database)
274
+ newObject.database = directory.database
275
+ if (directory.array)
276
+ newObject.array = directory.array || 'files'
277
+
270
278
  for (const key of Object.keys(directory.object)) {
271
279
  if (typeof directory.object[key] == 'string') {
272
280
 
@@ -284,7 +292,9 @@ module.exports = async function file(CoCreateConfig, configPath, match) {
284
292
  if (skip !== 'directory') {
285
293
  if (!newObject.object._id)
286
294
  newObject.$filter = {
287
- query: [{ key: 'pathname', value: pathname, operator: '$eq' }]
295
+ query: {
296
+ pathname
297
+ }
288
298
  }
289
299
 
290
300
  response = await runStore(newObject);
@@ -396,7 +406,9 @@ module.exports = async function file(CoCreateConfig, configPath, match) {
396
406
  let data = { array, object }
397
407
  if (!object._id && object.pathname)
398
408
  data.$filter = {
399
- query: [{ key: 'pathname', value: object.pathname, operator: '$or' }]
409
+ query: {
410
+ $or: [{ pathname: object.pathname }]
411
+ }
400
412
  }
401
413
 
402
414
  if (match.length && isMatch)