braid-blob 0.0.17 → 0.0.18

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/index.js CHANGED
@@ -1,4 +1,4 @@
1
- var {http_server: braidify, free_cors} = require('braid-http'),
1
+ var {http_server: braidify} = require('braid-http'),
2
2
  {url_file_db} = require('url-file-db'),
3
3
  fs = require('fs'),
4
4
  path = require('path')
@@ -10,7 +10,8 @@ function create_braid_blob() {
10
10
  cache: {},
11
11
  key_to_subs: {},
12
12
  peer: null, // we'll try to load this from a file, if not set by the user
13
- db: null // url-file-db instance
13
+ db: null, // url-file-db instance for blob storage
14
+ meta_db: null // url-file-db instance for meta storage
14
15
  }
15
16
 
16
17
  braid_blob.init = async () => {
@@ -27,10 +28,11 @@ function create_braid_blob() {
27
28
  await braid_blob.put(key, body, { skip_write: true })
28
29
  })
29
30
 
30
- // Create meta folder
31
- await fs.promises.mkdir(braid_blob.meta_folder, { recursive: true })
31
+ // Create url-file-db instance for meta storage (in a subfolder)
32
+ // This will create both meta_folder and the db subfolder with recursive: true
33
+ braid_blob.meta_db = await url_file_db.create(`${braid_blob.meta_folder}/db`)
32
34
 
33
- // establish a peer id
35
+ // establish a peer id (stored at root of meta_folder, sibling to db subfolder)
34
36
  if (!braid_blob.peer)
35
37
  try {
36
38
  braid_blob.peer = await fs.promises.readFile(`${braid_blob.meta_folder}/peer.txt`, 'utf8')
@@ -44,12 +46,11 @@ function create_braid_blob() {
44
46
  braid_blob.put = async (key, body, options = {}) => {
45
47
  await braid_blob.init()
46
48
 
47
- // Read the meta file
48
- const metaname = `${braid_blob.meta_folder}/${encode_filename(key)}`
49
+ // Read the meta data from meta_db
49
50
  var meta = {}
50
- try {
51
- meta = JSON.parse(await fs.promises.readFile(metaname, 'utf8'))
52
- } catch (e) {}
51
+ var meta_content = await braid_blob.meta_db.read(key)
52
+ if (meta_content)
53
+ meta = JSON.parse(meta_content.toString('utf8'))
53
54
 
54
55
  var their_e =
55
56
  !options.version ?
@@ -69,11 +70,11 @@ function create_braid_blob() {
69
70
  if (!options.skip_write)
70
71
  await braid_blob.db.write(key, body)
71
72
 
72
- // Write the meta file
73
+ // Write the meta data
73
74
  if (options.content_type)
74
75
  meta.content_type = options.content_type
75
76
 
76
- await fs.promises.writeFile(metaname, JSON.stringify(meta))
77
+ await braid_blob.meta_db.write(key, JSON.stringify(meta))
77
78
 
78
79
  // Notify all subscriptions of the update
79
80
  // (except the peer which made the PUT request itself)
@@ -93,12 +94,11 @@ function create_braid_blob() {
93
94
  braid_blob.get = async (key, options = {}) => {
94
95
  await braid_blob.init()
95
96
 
96
- // Read the meta file
97
- const metaname = `${braid_blob.meta_folder}/${encode_filename(key)}`
97
+ // Read the meta data from meta_db
98
98
  var meta = {}
99
- try {
100
- meta = JSON.parse(await fs.promises.readFile(metaname, 'utf8'))
101
- } catch (e) {}
99
+ var meta_content = await braid_blob.meta_db.read(key)
100
+ if (meta_content)
101
+ meta = JSON.parse(meta_content.toString('utf8'))
102
102
  if (meta.event == null) return null
103
103
 
104
104
  var result = {
@@ -171,13 +171,11 @@ function create_braid_blob() {
171
171
  var body = req.method === 'PUT' && await slurp(req)
172
172
 
173
173
  await within_fiber(options.key, async () => {
174
- const metaname = `${braid_blob.meta_folder}/${encode_filename(options.key)}`
175
-
176
- // Read the meta file
174
+ // Read the meta data from meta_db
177
175
  var meta = {}
178
- try {
179
- meta = JSON.parse(await fs.promises.readFile(metaname, 'utf8'))
180
- } catch (e) {}
176
+ var meta_content = await braid_blob.meta_db.read(options.key)
177
+ if (meta_content)
178
+ meta = JSON.parse(meta_content.toString('utf8'))
181
179
 
182
180
  if (req.method === 'GET') {
183
181
  if (!res.hasHeader("editable")) res.setHeader("Editable", "true")
@@ -234,12 +232,8 @@ function create_braid_blob() {
234
232
  res.setHeader("Version", version_to_header(meta.event != null ? [meta.event] : []))
235
233
  res.end('')
236
234
  } else if (req.method === 'DELETE') {
237
- try {
238
- await braid_blob.db.delete(options.key)
239
- } catch (e) {}
240
- try {
241
- await fs.promises.unlink(metaname)
242
- } catch (e) {}
235
+ await braid_blob.db.delete(options.key)
236
+ await braid_blob.meta_db.delete(options.key)
243
237
  res.statusCode = 204 // No Content
244
238
  res.end('')
245
239
  }
@@ -275,16 +269,6 @@ function create_braid_blob() {
275
269
  return ascii_ify(version.map(v => JSON.stringify(v)).join(', '))
276
270
  }
277
271
 
278
- function encode_filename(filename) {
279
- // Swap all "!" and "/" characters
280
- let swapped = filename.replace(/[!/]/g, (match) => (match === "!" ? "/" : "!"))
281
-
282
- // Encode the filename using encodeURIComponent()
283
- let encoded = encodeURIComponent(swapped)
284
-
285
- return encoded
286
- }
287
-
288
272
  function within_fiber(id, func) {
289
273
  if (!within_fiber.chains) within_fiber.chains = {}
290
274
  var prev = within_fiber.chains[id] || Promise.resolve()
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "braid-blob",
3
- "version": "0.0.17",
3
+ "version": "0.0.18",
4
4
  "description": "Library for collaborative blobs over http using braid.",
5
5
  "author": "Braid Working Group",
6
6
  "repository": "braid-org/braid-blob",
@@ -11,6 +11,6 @@
11
11
  },
12
12
  "dependencies": {
13
13
  "braid-http": "~1.3.82",
14
- "url-file-db": "~0.0.7"
14
+ "url-file-db": "~0.0.8"
15
15
  }
16
16
  }
package/server-demo.js CHANGED
@@ -8,6 +8,8 @@ var braid_blob = require(`${__dirname}/index.js`)
8
8
  // braid_blob.db_folder = './custom_files_folder'
9
9
  // braid_blob.meta_folder = './custom_meta_folder'
10
10
 
11
+ braid_blob.init()
12
+
11
13
  var server = require("http").createServer(async (req, res) => {
12
14
  console.log(`${req.method} ${req.url}`)
13
15
 
@@ -19,5 +21,5 @@ server.listen(port, () => {
19
21
  console.log(`files stored in: ${braid_blob.db_folder}`)
20
22
  })
21
23
 
22
- // curl -X PUT --data-binary @blob.png http://localhost:8888/blob.png
24
+ // curl -X PUT -H "Content-Type: image/png" --data-binary @blob.png http://localhost:8888/blob.png
23
25
  // curl http://localhost:8888/blob.png --output new-blob.png
package/test/tests.js CHANGED
@@ -688,6 +688,43 @@ runTest(
688
688
  'false'
689
689
  )
690
690
 
691
+ runTest(
692
+ "test that meta filenames distinguish between 'a' and 'A' on case-insensitive filesystems",
693
+ async () => {
694
+ var suffix = Math.random().toString(36).slice(2)
695
+ var key1 = 'test-' + suffix + '-a'
696
+ var key2 = 'test-' + suffix + '-A'
697
+
698
+ // PUT to lowercase key with version 100
699
+ var r = await braid_fetch(`/${key1}`, {
700
+ method: 'PUT',
701
+ version: ['100'],
702
+ body: 'lowercase content'
703
+ })
704
+ if (!r.ok) throw 'PUT to lowercase key failed: ' + r.status
705
+
706
+ // PUT to uppercase key with version 200
707
+ var r = await braid_fetch(`/${key2}`, {
708
+ method: 'PUT',
709
+ version: ['200'],
710
+ body: 'uppercase content'
711
+ })
712
+ if (!r.ok) throw 'PUT to uppercase key failed: ' + r.status
713
+
714
+ // GET both and verify they have different versions (stored in meta files)
715
+ var r1 = await braid_fetch(`/${key1}`)
716
+ if (!r1.ok) throw 'GET lowercase key failed: ' + r1.status
717
+ var version1 = r1.headers.get('version')
718
+
719
+ var r2 = await braid_fetch(`/${key2}`)
720
+ if (!r2.ok) throw 'GET uppercase key failed: ' + r2.status
721
+ var version2 = r2.headers.get('version')
722
+
723
+ return version1 + '|' + version2
724
+ },
725
+ '"100"|"200"'
726
+ )
727
+
691
728
  }
692
729
 
693
730
  // Export for Node.js (CommonJS)