Comparing version 1.0.2 to 1.1.0
@@ -10,2 +10,4 @@ const Strategy = require('@tangle/strategy') | ||
constructor (server, spec) { | ||
this.server = server | ||
this.spec = merge( | ||
@@ -19,3 +21,4 @@ { | ||
isUpdate: (spec && spec.hooks && spec.hooks.isUpdate) || [] | ||
} | ||
}, | ||
getTransformation: m => m.value.content | ||
}, | ||
@@ -28,5 +31,4 @@ spec | ||
this.spec.isUpdate = buildIsUpdate(this.spec) | ||
this.isValidProps = InputValidator('props', this.spec.props.composition) | ||
this.server = server | ||
} | ||
@@ -33,0 +35,0 @@ |
@@ -11,3 +11,4 @@ const Strategy = require('@tangle/strategy') | ||
staticProps, | ||
hooks | ||
hooks, | ||
getTransformation | ||
} = input | ||
@@ -24,5 +25,7 @@ | ||
// | ||
// tangle !=== group | ||
// tangle !== group | ||
/* compulsory */ | ||
/* Required */ | ||
// type | ||
if (typeof type !== 'string') errors.push('spec.type must be a String') | ||
@@ -33,6 +36,11 @@ Object.entries(props).forEach(([field, strategy]) => { | ||
/* optional (constructor has provide) */ | ||
if (typeof tangle !== 'string') errors.push('spec.tangle must be a String') | ||
/* Optional (constructor has provide) */ | ||
// tangle | ||
if (typeof tangle !== 'string' && tangle.length) errors.push('spec.tangle must be a String') | ||
// isValidNextStep | ||
if (typeof isValidNextStep !== 'function') errors.push('spec.isValidNextStep must be a function') | ||
// staticProps | ||
if (typeof staticProps !== 'object') errors.push('spec.staticProps must be an Object') | ||
@@ -50,2 +58,3 @@ else { | ||
// hooks | ||
if (typeof hooks !== 'object') errors.push('spec.hooks must be an Object') | ||
@@ -72,2 +81,6 @@ else { | ||
// getTransformation | ||
if (typeof getTransformation !== 'function') errors.push('spec.hooks.getTransformation must be function') | ||
/* Results */ | ||
if (errors.length === 0) return true | ||
@@ -74,0 +87,0 @@ |
@@ -42,3 +42,3 @@ const pull = require('pull-stream') | ||
getBacklinks: m => m.value.content.tangles[spec.tangle].previous, | ||
getTransformation: m => m.value.content, | ||
getTransformation: spec.getTransformation, | ||
isValid: spec.isValidNextStep | ||
@@ -45,0 +45,0 @@ }) |
{ | ||
"name": "ssb-crut", | ||
"version": "1.0.2", | ||
"version": "1.1.0", | ||
"description": "easy CRUT methods for secure scuttlebutt", | ||
@@ -39,3 +39,3 @@ "main": "index.js", | ||
"@tangle/overwrite": "^1.2.0", | ||
"scuttle-testbot": "^1.3.0", | ||
"scuttle-testbot": "^1.5.1", | ||
"ssb-backlinks": "^2.1.1", | ||
@@ -42,0 +42,0 @@ "ssb-query": "^2.4.5", |
@@ -88,3 +88,9 @@ # ssb-crut | ||
- NOTE - in the get + update check you don't currently have access to `context.graph` | ||
``` | ||
- `hooks` *Object* with properties: | ||
- `isRoot` *Array* a collection of validator functions which each root message must pass to proceed | ||
- `isUpdate` *Array* a collection of validator functions which each update message must pass to proceed | ||
- `getTransformation` *Function* | ||
- a function which is used to map a full message (`{ key, value }`) to a transformation | ||
- default: `m => m.value.content` | ||
- NOTE: if you're careful you can use this to decorate you transformation values with e.g. author info | ||
@@ -91,0 +97,0 @@ ### `crut.create(allProps, cb)` |
@@ -361,1 +361,66 @@ const test = require('tape') | ||
}) | ||
test('read (getTransformation)', t => { | ||
const server = Server() | ||
const spec = Spec({ | ||
getTransformation: m => { | ||
const { author, content } = m.value | ||
if (content.preferredName) { | ||
content.preferredName = { | ||
set: { author, value: content.preferredName.set } | ||
} | ||
} | ||
return content | ||
} | ||
}) | ||
const crut = new CRUT(server, spec) | ||
const Māui = server.id | ||
crut.create( | ||
{ | ||
parent: 'Taranga', | ||
preferredName: 'Māui', | ||
legalName: 'Ben', | ||
authors: { | ||
add: [{ id: Māui, seq: 33 }] | ||
} | ||
}, | ||
(err, profileId) => { | ||
t.error(err, 'creates a profile') | ||
crut.read(profileId, (err, profile) => { | ||
if (err) throw err | ||
t.deepEqual( | ||
profile, | ||
{ | ||
key: profileId, | ||
type: spec.type, | ||
originalAuthor: server.id, | ||
parent: 'Taranga', | ||
child: null, | ||
recps: null, | ||
states: [{ | ||
key: profileId, | ||
preferredName: { author: Māui, value: 'Māui' }, | ||
legalName: 'Ben', | ||
authors: { | ||
[Māui]: [{ start: 33, end: null }] | ||
} | ||
}] | ||
}, | ||
'reads decorated info' | ||
) | ||
server.get({ id: profileId, meta: true, private: true }, (err, m) => { | ||
if (err) throw err | ||
t.equal(m.value.content.preferredName.set, 'Māui', 'saves simple info') | ||
server.close() | ||
t.end() | ||
}) | ||
}) | ||
} | ||
) | ||
}) |
@@ -246,1 +246,86 @@ const test = require('tape') | ||
}) | ||
test('update (getTransformation)', t => { | ||
const server = Server() | ||
const server2 = Server() | ||
const spec = Spec({ | ||
getTransformation: m => { | ||
const { author, content } = m.value | ||
if (content.preferredName) { | ||
content.preferredName = { | ||
set: { author, value: content.preferredName.set } | ||
} | ||
} | ||
return content | ||
} | ||
}) | ||
const crut = new CRUT(server, spec) | ||
const crut2 = new CRUT(server2, spec) | ||
const Māui = server.id | ||
crut.create( | ||
{ | ||
parent: 'Taranga', | ||
preferredName: 'Māui', | ||
legalName: 'Ben', | ||
authors: { | ||
add: [ | ||
{ id: Māui, seq: 33 }, | ||
{ id: server2.id, seq: 1 } | ||
] | ||
} | ||
}, | ||
(err, profileId) => { | ||
t.error(err, 'creates a profile') | ||
replicate({ from: server, to: server2 }, (err) => { | ||
if (err) throw err | ||
crut2.update( | ||
profileId, | ||
{ preferredName: 'Māui !!!' }, | ||
(err, updateId) => { | ||
t.error(err, 'someone else updates') | ||
crut2.read(profileId, (err, profile) => { | ||
if (err) throw err | ||
t.deepEqual( | ||
profile, | ||
{ | ||
key: profileId, | ||
type: spec.type, | ||
originalAuthor: server.id, | ||
parent: 'Taranga', | ||
child: null, | ||
recps: null, | ||
states: [{ | ||
key: updateId, | ||
preferredName: { author: server2.id, value: 'Māui !!!' }, | ||
legalName: 'Ben', | ||
authors: { | ||
[Māui]: [{ start: 33, end: null }], | ||
[server2.id]: [{ start: 1, end: null }] | ||
} | ||
}] | ||
}, | ||
'reads decorated info' | ||
) | ||
server2.get({ id: updateId, meta: true, private: true }, (err, m) => { | ||
if (err) throw err | ||
t.equal(m.value.content.preferredName.set, 'Māui !!!', 'saves simple info') | ||
server.close() | ||
server2.close() | ||
t.end() | ||
}) | ||
}) | ||
} | ||
) | ||
}) | ||
} | ||
) | ||
}) |
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
New author
Supply chain riskA new npm collaborator published a version of the package for the first time. New collaborators are usually benign additions to a project, but do indicate a change to the security surface area of a package.
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
45264
1236
222
1