Skip to content

Commit

Permalink
refactor: use deno.json and tasks. bump deps. Refactor usages #36
Browse files Browse the repository at this point in the history
  • Loading branch information
TillaTheHun0 committed Mar 9, 2023
1 parent fab069f commit c1922fa
Show file tree
Hide file tree
Showing 21 changed files with 629 additions and 629 deletions.
2 changes: 1 addition & 1 deletion .hooks/pre-commit
Original file line number Diff line number Diff line change
@@ -1 +1 @@
./scripts/test.sh
deno task test
3 changes: 3 additions & 0 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"deno.enable": true
}
22 changes: 10 additions & 12 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,35 +23,33 @@
`hyper.config.js`

```js
import { default as couchdb } from "https://x.nest.land/hyper-adapter-couchdb@VERSION/mod.js";
import { default as couchdb } from 'https://x.nest.land/hyper-adapter-couchdb@VERSION/mod.js'

export default {
app: opine,
adapter: [
{ port: "data", plugins: [couchdb({ url: "http://localhost:5984" })] },
{ port: 'data', plugins: [couchdb({ url: 'http://localhost:5984' })] },
],
};
}
```

The value of the connection url should be in the following format:

> `[protocol]://[key]:[secret]@[host]:[port]`
When a new database is created, the following roles will be added to the
security document:
When a new database is created, the following roles will be added to the security document:

- db-admin
- db-user

Using this adapter, you will not have any access to the \_users table or the
_replicator table
Using this adapter, you will not have any access to the \_users table or the _replicator table

### Credentials from ENV VARS

When using this adapter, you will need to configure three environment variables,
one for the `server-admin` credentials, so that the adapter can create/delete
databases, and one for the `db-admin` user so a search index can be created. And
finally one for the `db-user` user to manage documents.
When using this adapter, you will need to configure three environment variables, one for the
`server-admin` credentials, so that the adapter can create/delete databases, and one for the
`db-admin` user so a search index can be created. And finally one for the `db-user` user to manage
documents.

.env

Expand All @@ -69,7 +67,7 @@ This is a Deno module available to import from
deps.js

```js
export { default as couchdb } from "https://x.nest.land/hyper-adapter-couchdb@VERSION/mod.js";
export { default as couchdb } from 'https://x.nest.land/hyper-adapter-couchdb@VERSION/mod.js'
```

## Features
Expand Down
96 changes: 48 additions & 48 deletions adapter.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import { crocks, R } from "./deps.js";
import { bulk } from "./bulk.js";
import { handleHyperErr, HyperErr } from "./err.js";
import { crocks, R } from './deps.js'
import { bulk } from './bulk.js'
import { handleHyperErr, HyperErr } from './err.js'

const { Async } = crocks;
const { Async } = crocks

const {
always,
Expand All @@ -20,15 +20,15 @@ const {
reduce,
allPass,
pluck,
} = R;
} = R

const isDefined = complement(isNil);
const isDefined = complement(isNil)

const lowerCaseValue = compose(
([k, v]) => ({ [k]: toLower(v) }),
head,
toPairs,
);
)

/**
* Something wonky is happening with Ramda's reduce.
Expand All @@ -46,22 +46,22 @@ const foldDocs = (all) =>
(doc) => !(/^_design/.test(doc._id)), // filter out all design docs
]),
(doc) => {
docs.push(omit(["_rev"], doc));
return docs;
docs.push(omit(['_rev'], doc))
return docs
},
always(docs),
)(doc);
)(doc)
},
[],
all,
);
)

export function adapter({ config, asyncFetch, headers, handleResponse }) {
const retrieveDocument = ({ db, id }) =>
// https://docs.couchdb.org/en/stable/api/document/common.html#get--db-docid
asyncFetch(`${config.origin}/${db}/${id}`, {
headers,
}).chain(handleResponse(200));
}).chain(handleResponse(200))

return ({
// create database needs to
Expand All @@ -71,23 +71,23 @@ export function adapter({ config, asyncFetch, headers, handleResponse }) {
// to the database
createDatabase: (name) =>
asyncFetch(`${config.origin}/${name}`, {
method: "PUT",
method: 'PUT',
headers,
})
.chain(handleResponse(201))
// create security document
.chain(() =>
asyncFetch(`${config.origin}/${name}/_security`, {
method: "PUT",
method: 'PUT',
headers,
body: JSON.stringify({
admins: {
names: [],
roles: ["db-admins"],
roles: ['db-admins'],
},
members: {
names: [],
roles: ["db-users"],
roles: ['db-users'],
},
}),
})
Expand All @@ -101,7 +101,7 @@ export function adapter({ config, asyncFetch, headers, handleResponse }) {

removeDatabase: (name) =>
asyncFetch(`${config.origin}/${name}`, {
method: "DELETE",
method: 'DELETE',
headers,
})
.chain(handleResponse(200))
Expand All @@ -114,22 +114,22 @@ export function adapter({ config, asyncFetch, headers, handleResponse }) {
Async.of(doc)
.chain((doc) =>
isEmpty(doc)
? Async.Rejected(HyperErr({ status: 400, msg: "document empty" }))
? Async.Rejected(HyperErr({ status: 400, msg: 'document empty' }))
: Async.Resolved(doc)
)
.chain((doc) => Async.Resolved({ ...doc, _id: id }))
.chain((doc) =>
/^_design/.test(doc._id)
? Async.Rejected(HyperErr({
status: 403,
msg: "user can not create design docs",
msg: 'user can not create design docs',
}))
: Async.Resolved(doc)
)
.chain((doc) =>
// https://docs.couchdb.org/en/stable/api/database/common.html#post--db
asyncFetch(`${config.origin}/${db}`, {
method: "POST",
method: 'POST',
headers,
body: JSON.stringify(doc),
}).chain(handleResponse(201))
Expand All @@ -139,12 +139,12 @@ export function adapter({ config, asyncFetch, headers, handleResponse }) {
// TODO: see Status Codes section on https://docs.couchdb.org/en/stable/api/database/common.html#post--db
e.status !== 409 ? Async.Rejected(e) : Async.Rejected(HyperErr({
status: 409,
msg: "document conflict",
msg: 'document conflict',
})),
Async.Resolved,
)
)
.map(omit(["rev"])) // { ok, id }
.map(omit(['rev'])) // { ok, id }
.bichain(
handleHyperErr,
Async.Resolved,
Expand All @@ -153,11 +153,11 @@ export function adapter({ config, asyncFetch, headers, handleResponse }) {

retrieveDocument: ({ db, id }) =>
retrieveDocument({ db, id })
.map(omit(["_rev"]))
.map(omit(['_rev']))
.bichain(
(_) =>
Async.Rejected(
HyperErr({ status: 404, msg: "doc not found" }),
HyperErr({ status: 404, msg: 'doc not found' }),
),
Async.Resolved,
)
Expand All @@ -175,42 +175,42 @@ export function adapter({ config, asyncFetch, headers, handleResponse }) {
})
.chain((res) => Async.fromPromise(res.json.bind(res))())
.map((doc) => {
return doc.error ? null : doc;
return doc.error ? null : doc
})
.chain((old) =>
// https://docs.couchdb.org/en/stable/api/document/common.html#put--db-docid
old
? asyncFetch(`${config.origin}/${db}/${id}?rev=${old._rev}`, {
method: "PUT",
method: 'PUT',
headers,
body: JSON.stringify(doc),
})
: asyncFetch(`${config.origin}/${db}/${id}`, {
method: "PUT",
method: 'PUT',
headers,
body: JSON.stringify(doc),
})
)
.chain(handleResponse(201))
.map(omit(["rev"])) // { ok, id }
.map(omit(['rev'])) // { ok, id }
.bichain(
handleHyperErr,
Async.Resolved,
)
.toPromise();
.toPromise()
},

removeDocument: ({ db, id }) =>
retrieveDocument({ db, id })
.chain((old) =>
// https://docs.couchdb.org/en/stable/api/document/common.html#delete--db-docid
asyncFetch(`${config.origin}/${db}/${id}?rev=${old._rev}`, {
method: "DELETE",
method: 'DELETE',
headers,
})
)
.chain(handleResponse(200))
.map(omit(["rev"])) // { ok, id }
.map(omit(['rev'])) // { ok, id }
.bichain(
handleHyperErr,
Async.Resolved,
Expand All @@ -219,34 +219,34 @@ export function adapter({ config, asyncFetch, headers, handleResponse }) {

queryDocuments: ({ db, query }) => {
if (query.sort) {
query.sort = query.sort.map(lowerCaseValue);
query.sort = query.sort.map(lowerCaseValue)
}

if (!query.selector) {
query.selector = {};
query.selector = {}
}

// https://docs.couchdb.org/en/stable/api/database/find.html
return asyncFetch(`${config.origin}/${db}/_find`, {
method: "POST",
method: 'POST',
headers,
body: JSON.stringify(query),
})
.chain(handleResponse(200))
.map(prop("docs"))
.map(prop('docs'))
.map(foldDocs)
.map((docs) => ({ ok: true, docs }))
.bichain(
handleHyperErr,
Async.Resolved,
)
.toPromise();
.toPromise()
},

indexDocuments: ({ db, name, fields }) =>
// https://docs.couchdb.org/en/stable/api/database/find.html#post--db-_index
asyncFetch(`${config.origin}/${db}/_index`, {
method: "POST",
method: 'POST',
headers,
body: JSON.stringify({
index: {
Expand All @@ -264,30 +264,30 @@ export function adapter({ config, asyncFetch, headers, handleResponse }) {

listDocuments: ({ db, limit, startkey, endkey, keys, descending }) => {
// deno-lint-ignore camelcase
let options = { include_docs: true };
options = limit ? mergeRight({ limit: Number(limit) }, options) : options;
options = startkey ? mergeRight({ startkey }, options) : options;
options = endkey ? mergeRight({ endkey }, options) : options;
options = keys ? mergeRight({ keys: keys.split(",") }, options) : options;
options = descending ? mergeRight({ descending }, options) : options;
let options = { include_docs: true }
options = limit ? mergeRight({ limit: Number(limit) }, options) : options
options = startkey ? mergeRight({ startkey }, options) : options
options = endkey ? mergeRight({ endkey }, options) : options
options = keys ? mergeRight({ keys: keys.split(',') }, options) : options
options = descending ? mergeRight({ descending }, options) : options

// https://docs.couchdb.org/en/stable/api/database/bulk-api.html#post--db-_all_docs
return asyncFetch(`${config.origin}/${db}/_all_docs`, {
method: "POST",
method: 'POST',
headers,
body: JSON.stringify(options),
})
.chain(handleResponse(200))
.map(prop("rows"))
.map(pluck("doc"))
.map(prop('rows'))
.map(pluck('doc'))
.map(foldDocs)
.map((docs) => ({ ok: true, docs }))
.bichain(
handleHyperErr,
Async.Resolved,
)
.toPromise();
.toPromise()
},
bulkDocuments: bulk(config.origin, asyncFetch, headers, handleResponse),
});
})
}
Loading

0 comments on commit c1922fa

Please sign in to comment.