Comparing version 1.3.3 to 2.0.0
@@ -80,3 +80,3 @@ #!/usr/bin/env node | ||
if (!checkResult) { | ||
console.log("Bookmarks are not up to date"); | ||
console.error("Bookmarks are not up to date"); | ||
process.exit(1); | ||
@@ -83,0 +83,0 @@ } |
@@ -26,2 +26,23 @@ # Advanced usage | ||
### Interpolating bookmarks | ||
`merge` works well when you have multiple local or remote `YAML` that all sit at the top level however you might have a situation where they need to be at different levels in your folder structure. For this you can use the interpolation helper within your `YAML` file. | ||
```YAML | ||
label: Interpolated bookmarks | ||
description: This is an example of interpolating YAML files | ||
folders: | ||
- | ||
{{ get './my-bookmarks.yaml' ' '}} | ||
- | ||
{{ get 'https://raw.githubusercontent.com/thearegee/bookworms/main/demo/config/bookmarks-for-merging.yaml' ' '}} | ||
``` | ||
All `YAML` files are passed through [Handlebars](https://handlebarsjs.com/). There is a registered helper called `get` that takes two parameters. | ||
- `path` - load local or remote bookmarks from path | ||
- `indentation` - the amount of spaces or tabs needed to indent the block. You can copy and paste this from the first `{` to the starting line. | ||
**NOTE:** I appreciate this `indentation` parameter is pretty gross at the time of writing this I couldn't think of a better way without potentially writing my own parser for the YAML file. If someone is interesting in conbributing and changing this code it would be welcome. | ||
## Merge | ||
@@ -28,0 +49,0 @@ |
@@ -41,7 +41,7 @@ # Developers | ||
- `fetchBookmarkConfig(path)` - load local or remote bookmarks from path | ||
- `fetchBookmarkConfig(path, asYAML)` - load local or remote bookmarks from path, asYAML is a boolean, default is false and returns JSON | ||
- `shouldFetchFromLocal(path)` - undersstand if a path is local or remote | ||
- `fetchLocaleBookmarkConfig(path)` - load bookmarks from `fs` | ||
- `fetchRemoteBoomarkConfig(path)` - load bookmarks from `http` request | ||
- `returnResponseAsJsonOn2xx(body, statusCode, path)` - handle non 2xx `http` responses | ||
- `fetchLocaleBookmarkYAML(path)` - load bookmarks from `fs` | ||
- `fetchRemoteBoomarkYAML(path)` - load bookmarks from `http` request | ||
- `returnResponseOn2xx(body, statusCode, path)` - handle non 2xx `http` responses | ||
- `returnResponseAsObject(response, path)` - return javascript object, converting YAML or JSON | ||
@@ -48,0 +48,0 @@ |
@@ -26,21 +26,31 @@ # Exporting existing bookmarks | ||
folders: | ||
- label: folder 1 | ||
- | ||
label: folder 1 | ||
folders: | ||
- label: sub folder 1 | ||
- | ||
label: sub folder 1 | ||
bookmarks: | ||
- label: sample url 1 | ||
- | ||
label: sample url 1 | ||
href: https://www.mywebsite.com | ||
- label: folder 2 | ||
- | ||
label: folder 2 | ||
folders: | ||
- label: sub folder 2 | ||
- | ||
label: sub folder 2 | ||
bookmarks: | ||
- label: sample url 2 | ||
- | ||
label: sample url 2 | ||
href: https://www.mywebsite.com | ||
- label: sample url 3 | ||
- | ||
label: sample url 3 | ||
href: https://www.mywebsite.com | ||
- label: sub folder 3 | ||
- | ||
label: sub folder 3 | ||
bookmarks: | ||
- label: sample url 4 | ||
- | ||
label: sample url 4 | ||
href: https://www.mywebsite.com | ||
- label: sample url 5 | ||
- | ||
label: sample url 5 | ||
href: https://www.mywebsite.com | ||
@@ -47,0 +57,0 @@ ``` |
{ | ||
"name": "bookworms", | ||
"version": "1.3.3", | ||
"version": "2.0.0", | ||
"description": "A cli tool for centralising and generating bookmarks", | ||
@@ -34,2 +34,4 @@ "main": "./src/index.js", | ||
"got": "^11.8.2", | ||
"handlebars": "^4.7.7", | ||
"handlebars-async-helpers": "^1.0.4", | ||
"js-yaml": "^4.1.0", | ||
@@ -36,0 +38,0 @@ "json-stringify-safe": "^5.0.1", |
@@ -25,6 +25,8 @@ <p align="center"> | ||
folders: | ||
- label: folder 1 | ||
- | ||
label: folder 1 | ||
description: This is to describe the folder structure | ||
folders: | ||
- label: sub folder 1 | ||
- | ||
label: sub folder 1 | ||
description: This is to describe the sub folder structure | ||
@@ -35,18 +37,24 @@ bookmarks: | ||
href: https://www.mywebsite.com | ||
- label: folder 2 | ||
- | ||
label: folder 2 | ||
folders: | ||
- label: sub folder 2 | ||
bookmarks: | ||
- label: sample url 2 | ||
- | ||
label: sample url 2 | ||
description: this is used to describe the bookmark | ||
href: https://www.mywebsite.com | ||
- label: sample url 3 | ||
- | ||
label: sample url 3 | ||
description: this is used to describe the bookmark | ||
href: https://www.mywebsite.com | ||
- label: sub folder 3 | ||
- | ||
label: sub folder 3 | ||
bookmarks: | ||
- label: sample url 4 | ||
- | ||
label: sample url 4 | ||
description: this is used to describe the bookmark | ||
href: https://www.mywebsite.com | ||
- label: sample url 5 | ||
- | ||
label: sample url 5 | ||
description: this is used to describe the bookmark | ||
@@ -116,6 +124,6 @@ href: https://www.mywebsite.com | ||
- Investigate a chrome extension that could load remote YAML files | ||
- Document Murphy Slackbot that uses Bookworms | ||
- Integrate with Slacks new bookmark feature | ||
## Credits | ||
The Bookworms logo was created by [James Barry Illustrations](https://www.jamesbarryillustration.com/). | ||
The Bookworms logo was created by [gullwing.io](https://www.gullwing.io/). |
@@ -1,90 +0,158 @@ | ||
import {fetchBookmarkConfig, shouldFetchFromLocal, fetchLocaleBookmarkConfig, fetchRemoteBoomarkConfig,returnResponseAsJsonOn2xx, returnResponseAsObject} from '../load-bookmarks'; | ||
import { | ||
fetchBookmarkConfig, | ||
shouldFetchFromLocal, | ||
fetchLocaleBookmarkYAML, | ||
fetchRemoteBoomarkYMAL, | ||
returnResponseOn2xx, | ||
returnResponseAsObject, | ||
} from "../load-bookmarks"; | ||
describe('loading bookmark config', () => { | ||
describe('fetchBookmarkConfig', () => { | ||
test('should return locale bookmarks', async () => { | ||
expect(await fetchBookmarkConfig('./demo/config/bookmarks.yaml')).toMatchSnapshot(); | ||
}) | ||
test('should return remote bookmarks', async () => { | ||
expect(await fetchBookmarkConfig('https://raw.githubusercontent.com/thearegee/bookworms/main/demo/config/bookmarks.yaml')).toMatchSnapshot(); | ||
}) | ||
}) | ||
describe('shouldFetchFromLocal', () => { | ||
test('should return true if path is local filesystem', () => { | ||
expect(shouldFetchFromLocal('./demo/config/bookmarks.yaml')).toBeTruthy(); | ||
}) | ||
test('should return false if path is remote http', () => { | ||
expect(shouldFetchFromLocal('https://raw.githubusercontent.com/thearegee/bookworms/main/demo/config/bookmarks.yaml')).toBeFalsy(); | ||
}) | ||
}) | ||
describe('fetchLocaleBookmarkConfig', () => { | ||
test('should return JSON from local YMAL', () => { | ||
expect(fetchLocaleBookmarkConfig('./demo/config/bookmarks.yaml')).toMatchSnapshot() | ||
}) | ||
}) | ||
describe('fetchRemoteBoomarkConfig', () => { | ||
test('should return JSON from http request', async () => { | ||
expect(await fetchRemoteBoomarkConfig('https://raw.githubusercontent.com/thearegee/bookworms/main/demo/config/bookmarks.yaml')).toMatchSnapshot() | ||
}) | ||
}) | ||
describe('returnResponseAsJsonOn2xx', () => { | ||
test('should throw with statusCode 100', () => { | ||
try { | ||
returnResponseAsJsonOn2xx("{'hello':'world'}", 100, 'https://raw.githubusercontent.com/thearegee/bookworms/main/demo/config/bookmarks.yaml') | ||
expect(true).toBe(false); | ||
} catch (error) { | ||
expect(error.message).toEqual('https://raw.githubusercontent.com/thearegee/bookworms/main/demo/config/bookmarks.yaml returned 100') | ||
} | ||
}) | ||
test('should throw with statusCode 300', () => { | ||
try { | ||
returnResponseAsJsonOn2xx("{'hello':'world'}", 300, 'https://raw.githubusercontent.com/thearegee/bookworms/main/demo/config/bookmarks.yaml') | ||
expect(true).toBe(false); | ||
} catch (error) { | ||
expect(error.message).toEqual('https://raw.githubusercontent.com/thearegee/bookworms/main/demo/config/bookmarks.yaml returned 300') | ||
} | ||
}) | ||
test('should return object with string of JSON', () => { | ||
try { | ||
const response = returnResponseAsJsonOn2xx("{'hello':'world'}", 200, 'https://raw.githubusercontent.com/thearegee/bookworms/main/demo/config/bookmarks.yaml') | ||
expect(response).toEqual({hello:"world"}) | ||
} catch (error) { | ||
expect(true).toBe(false); | ||
} | ||
}) | ||
}) | ||
describe('returnResponseAsObject', () => { | ||
test('should return throw with invalid response error', () => { | ||
try { | ||
returnResponseAsObject(undefined, 'https://raw.githubusercontent.com/thearegee/bookworms/main/demo/config/bookmarks.yaml'); | ||
expect(true).toBe(false); | ||
} catch (error) { | ||
expect(error.message).toEqual('https://raw.githubusercontent.com/thearegee/bookworms/main/demo/config/bookmarks.yaml returned invalid bookworms bookmarks structure') | ||
} | ||
}) | ||
test('should return object with string of JSON', () => { | ||
try { | ||
const response = returnResponseAsObject("{'hello':'world'}", 'https://raw.githubusercontent.com/thearegee/bookworms/main/demo/config/bookmarks.yaml'); | ||
expect(response).toEqual({hello:"world"}) | ||
} catch (error) { | ||
expect(true).toBe(false); | ||
} | ||
}) | ||
test('should return object with object', () => { | ||
try { | ||
const response = returnResponseAsObject({hello:"world"}, 'https://raw.githubusercontent.com/thearegee/bookworms/main/demo/config/bookmarks.yaml'); | ||
expect(response).toEqual({hello:"world"}) | ||
} catch (error) { | ||
expect(true).toBe(false); | ||
} | ||
}) | ||
test('should return object with YAML', () => { | ||
try { | ||
const response = returnResponseAsObject(`hello: world`, 'https://raw.githubusercontent.com/thearegee/bookworms/main/demo/config/bookmarks.yaml'); | ||
expect(response).toEqual({hello:"world"}) | ||
} catch (error) { | ||
expect(true).toBe(false); | ||
} | ||
}) | ||
}) | ||
}) | ||
describe("loading bookmark config", () => { | ||
describe("fetchBookmarkConfig", () => { | ||
test("should return locale bookmarks as JSON", async () => { | ||
expect( | ||
await fetchBookmarkConfig("./demo/config/bookmarks.yaml") | ||
).toMatchSnapshot(); | ||
}); | ||
test("should return remote bookmarks as JSON", async () => { | ||
expect( | ||
await fetchBookmarkConfig( | ||
"https://raw.githubusercontent.com/thearegee/bookworms/main/demo/config/bookmarks.yaml" | ||
) | ||
).toMatchSnapshot(); | ||
}); | ||
test("should return locale bookmarks as YAML", async () => { | ||
expect( | ||
await fetchBookmarkConfig("./demo/config/bookmarks.yaml", true) | ||
).toMatchSnapshot(); | ||
}); | ||
test("should return remote bookmarks as YAML", async () => { | ||
expect( | ||
await fetchBookmarkConfig( | ||
"https://raw.githubusercontent.com/thearegee/bookworms/main/demo/config/bookmarks.yaml", true | ||
) | ||
).toMatchSnapshot(); | ||
}); | ||
}); | ||
describe("shouldFetchFromLocal", () => { | ||
test("should return true if path is local filesystem", () => { | ||
expect(shouldFetchFromLocal("./demo/config/bookmarks.yaml")).toBeTruthy(); | ||
}); | ||
test("should return false if path is remote http", () => { | ||
expect( | ||
shouldFetchFromLocal( | ||
"https://raw.githubusercontent.com/thearegee/bookworms/main/demo/config/bookmarks.yaml" | ||
) | ||
).toBeFalsy(); | ||
}); | ||
}); | ||
describe("fetchLocaleBookmarkYAML", () => { | ||
test("should return JSON from local YMAL", () => { | ||
expect( | ||
fetchLocaleBookmarkYAML("./demo/config/bookmarks.yaml") | ||
).toMatchSnapshot(); | ||
}); | ||
}); | ||
describe("fetchRemoteBoomarkYMAL", () => { | ||
test("should return JSON from http request", async () => { | ||
expect( | ||
await fetchRemoteBoomarkYMAL( | ||
"https://raw.githubusercontent.com/thearegee/bookworms/main/demo/config/bookmarks.yaml" | ||
) | ||
).toMatchSnapshot(); | ||
}); | ||
}); | ||
describe("returnResponseOn2xx", () => { | ||
test("should throw with statusCode 100", () => { | ||
try { | ||
returnResponseOn2xx( | ||
"hello: world", | ||
100, | ||
"https://raw.githubusercontent.com/thearegee/bookworms/main/demo/config/bookmarks.yaml" | ||
); | ||
expect(true).toBe(false); | ||
} catch (error) { | ||
expect(error.message).toEqual( | ||
"https://raw.githubusercontent.com/thearegee/bookworms/main/demo/config/bookmarks.yaml returned 100" | ||
); | ||
} | ||
}); | ||
test("should throw with statusCode 300", () => { | ||
try { | ||
returnResponseOn2xx( | ||
"hello: world", | ||
300, | ||
"https://raw.githubusercontent.com/thearegee/bookworms/main/demo/config/bookmarks.yaml" | ||
); | ||
expect(true).toBe(false); | ||
} catch (error) { | ||
expect(error.message).toEqual( | ||
"https://raw.githubusercontent.com/thearegee/bookworms/main/demo/config/bookmarks.yaml returned 300" | ||
); | ||
} | ||
}); | ||
test("should return object with string of JSON", () => { | ||
try { | ||
const response = returnResponseOn2xx( | ||
"hello: world", | ||
200, | ||
"https://raw.githubusercontent.com/thearegee/bookworms/main/demo/config/bookmarks.yaml" | ||
); | ||
expect(response).toEqual({ | ||
body: "hello: world", | ||
path: "https://raw.githubusercontent.com/thearegee/bookworms/main/demo/config/bookmarks.yaml", | ||
}); | ||
} catch (error) { | ||
expect(true).toBe(false); | ||
} | ||
}); | ||
}); | ||
describe("returnResponseAsObject", () => { | ||
test("should return throw with invalid response error", () => { | ||
try { | ||
returnResponseAsObject( | ||
undefined, | ||
"https://raw.githubusercontent.com/thearegee/bookworms/main/demo/config/bookmarks.yaml" | ||
); | ||
expect(true).toBe(false); | ||
} catch (error) { | ||
expect(error.message).toEqual( | ||
"https://raw.githubusercontent.com/thearegee/bookworms/main/demo/config/bookmarks.yaml returned invalid bookworms bookmarks structure" | ||
); | ||
} | ||
}); | ||
test("should return object with string of JSON", () => { | ||
try { | ||
const response = returnResponseAsObject( | ||
"{'hello':'world'}", | ||
"https://raw.githubusercontent.com/thearegee/bookworms/main/demo/config/bookmarks.yaml" | ||
); | ||
expect(response).toEqual({ hello: "world" }); | ||
} catch (error) { | ||
expect(true).toBe(false); | ||
} | ||
}); | ||
test("should return object with object", () => { | ||
try { | ||
const response = returnResponseAsObject( | ||
{ hello: "world" }, | ||
"https://raw.githubusercontent.com/thearegee/bookworms/main/demo/config/bookmarks.yaml" | ||
); | ||
expect(response).toEqual({ hello: "world" }); | ||
} catch (error) { | ||
expect(true).toBe(false); | ||
} | ||
}); | ||
test("should return object with YAML", () => { | ||
try { | ||
const response = returnResponseAsObject( | ||
"hello: world", | ||
"https://raw.githubusercontent.com/thearegee/bookworms/main/demo/config/bookmarks.yaml" | ||
); | ||
expect(response).toEqual({ hello: "world" }); | ||
} catch (error) { | ||
expect(true).toBe(false); | ||
} | ||
}); | ||
}); | ||
}); |
@@ -33,3 +33,3 @@ import { fetchBookmarkConfig } from "./load-bookmarks.js"; | ||
} catch (e) { | ||
console.log(`Failed to read file ${filename}`); | ||
console.error(`Failed to read file ${filename}`); | ||
return false; | ||
@@ -36,0 +36,0 @@ } |
@@ -5,14 +5,26 @@ import got from 'got'; | ||
const fetchBookmarkConfig = async (path) => { | ||
const fetchBookmarkConfig = async (path, asYAML = false) => { | ||
let type; | ||
let body; | ||
if (shouldFetchFromLocal(path)) { | ||
return { | ||
type: 'local', | ||
body: fetchLocaleBookmarkConfig(path) | ||
type = 'local'; | ||
if (!asYAML) { | ||
body = returnResponseAsObject(fetchLocaleBookmarkYAML(path)); | ||
} else { | ||
body = fetchLocaleBookmarkYAML(path); | ||
} | ||
} else { | ||
return { | ||
type: 'remote', | ||
body: await fetchRemoteBoomarkConfig(path) | ||
type = 'remote'; | ||
if (!asYAML) { | ||
const response = await fetchRemoteBoomarkYMAL(path) | ||
body = returnResponseAsObject(response.body, response.path) | ||
} else { | ||
const reponse = await fetchRemoteBoomarkYMAL(path) | ||
body = reponse.body | ||
} | ||
} | ||
return { | ||
type, | ||
body | ||
} | ||
} | ||
@@ -29,5 +41,5 @@ | ||
const fetchLocaleBookmarkConfig = (path) => { | ||
const fetchLocaleBookmarkYAML = (path) => { | ||
try { | ||
return returnResponseAsObject(readFileSync(path, 'utf8')); | ||
return readFileSync(path, 'utf8'); | ||
} catch(error) { | ||
@@ -40,6 +52,6 @@ // todo add tests around this error handling | ||
const fetchRemoteBoomarkConfig = async (path) =>{ | ||
const fetchRemoteBoomarkYMAL = async (path) =>{ | ||
try { | ||
const { body, statusCode } = await got(path); | ||
return returnResponseAsJsonOn2xx(body, statusCode, path); | ||
return returnResponseOn2xx(body, statusCode, path); | ||
} catch (error) { | ||
@@ -52,5 +64,5 @@ // todo add tests around this error handling | ||
const returnResponseAsJsonOn2xx = (body, statusCode, path) => { | ||
const returnResponseOn2xx = (body, statusCode, path) => { | ||
if (statusCode >= 200 && statusCode < 300) { | ||
return returnResponseAsObject(body, path) | ||
return {body, path} | ||
} else { | ||
@@ -79,2 +91,2 @@ throw new Error(`${path} returned ${statusCode}`) | ||
export {fetchBookmarkConfig, shouldFetchFromLocal, fetchLocaleBookmarkConfig, fetchRemoteBoomarkConfig, returnResponseAsJsonOn2xx, returnResponseAsObject} | ||
export {fetchBookmarkConfig, shouldFetchFromLocal, fetchLocaleBookmarkYAML, fetchRemoteBoomarkYMAL, returnResponseOn2xx, returnResponseAsObject} |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
300998
43
1529
127
8
+ Addedhandlebars@^4.7.7
+ Addedhandlebars@4.7.64.7.8(transitive)
+ Addedhandlebars-async-helpers@1.0.6(transitive)
+ Addedminimist@1.2.8(transitive)
+ Addedneo-async@2.6.2(transitive)
+ Addedsource-map@0.6.1(transitive)
+ Addeduglify-js@3.19.3(transitive)
+ Addedwordwrap@1.0.0(transitive)