eblanshey / safe-api Goto Github PK
View Code? Open in Web Editor NEWJavascript API + React helpers for interacting with the SAFE Network created by MaidSafe
Javascript API + React helpers for interacting with the SAFE Network created by MaidSafe
Hi, nice project.
I tried to run a little test script from the commandline:
´´´
var safe_api = require('safe-api')
safe_api.setup({ firebaseApp: 'intense-torch-2025' })
´´´
but i get an error somewhere:
´´´
Error: No transports available
at Error (native)
at Dh (C:\Users\henrud\Documents\SAFE\safe-api-test\node_modules\safe-api\lib\index.js:16920:645)
at Fh (C:\Users\henrud\Documents\SAFE\safe-api-test\node_modules\safe-api\lib\index.js:16921:23)
at new Eh (C:\Users\henrud\Documents\SAFE\safe-api-test\node_modules\safe-api\lib\index.js:16920:881)
at bi (C:\Users\henrud\Documents\SAFE\safe-api-test\node_modules\safe-api\lib\index.js:16940:230)
at null._onTimeout (C:\Users\henrud\Documents\SAFE\safe-api-test\node_modules\safe-api\lib\index.js:16938:147)
at Timer.listOnTimeout (timers.js:119:15)
´´´
Any ideas?
and btw how do i build your project so it doesnt minimize the code?
Allow devs to define all of the application's entities and collections using models. The following functionality should be provided by the models:
get()
, put()
, and delete()
methods on the models. Only PUT if data has changed, and DELETE if data exists.fullName()
helper method could concatenate an object's first_name
and last_name
fields and then return the result.name
field, for example, it expects it to be a string of a certain length, and NOT an integer or array. In SAFE, anybody can upload any data they want, so client-side data validation must be included in the app to prevent breakage. Task: create an easy way for the dev to set rules for their data. If rules are not met, then either use some defaults, or remove the object entirely. The dev will have a guarantee that the object returned from the API will follow the application's rules, even if a nefarious user tries to cause trouble. Allow devs to attach error messages for each validation rule so they could be used to quickly validate forms, too. See proposal here.string
field may eventually become an array
field to allow multiple options. The developer cannot go and change all existing data to reflect this change, so his app needs to be smart and maintain backwards compatibility for every single object schema change. Over time, this can lead to massive headaches and spaghetti code in order to make sure old data is supported. Task: introduce versioning for models. Every object PUT to the network should have an integer version number. Upon fetching it, if the model detects that the version number is not the latest one, it incrementally modifies its data using the model's set rules until it matches the rules of the latest version. This should make app development much easier knowing that even old data on the network will be returned using the latest schemas. This allows newer code to read older data, but not vice versa. Bonus: if the requester of the data is also the data owner, automatically UPDATE the object on the network (if possible) so that the same version processing won't be required in the future for all requests. With Structured Data this will be free. See proposal here.The following illustrates the proposed functionality, not including validation and versioning
// Define a new model (using ES2015 syntax, submit issue if you want ES5)
class Post extends Model {
// Define a helper getter method (optional)
titleUpper() {
return this.data('title').toUpperCase();
}
}
Post.name = 'Post';
// Let's create a new model
var data = {
title: "My New Post",
description: "This is my post description"
};
// Use constructor to fill model
var post = new Post(data);
// Read and set data from the model.
// For consistency, all top-level data must be objects.
post.raw(); // returns the data as is
post.data('title'); // "My New Post"
post.set('description', 'This is a new description'); // returns true
post.data('description'); // 'This is a new description'
post.set('myArray', ['a', 'b']); // true
post.get('myArray.0'); // 'a'
// Use our custom method
post.titleUpper(); // "MY NEW POST"
// Set multiple fields at once
post.fill({title: 'New Title', description: 'A better description'}); // true
// Does the data exist on the network?
post.exists; // bool
// Model name -- could be used as part of the tag_type in Structured Data (SD)
post.name; // 'Post'
// Save the data to the network. Throw error if not authenticated,
// or object does not belong to authenticated user.
post.put()
.then(() => console.log('The model has been saved.'))
.catch((error) => console.log(error));
// Userid of the owner. `put()` sets the owner to our userid, of course.
post.owner; // 'aUserIdHere', or null if not exists yet
// ID of this model -- could be the `identifier` in SD
post.id; // 'aPostId', or null if not exists yet
// get a model from the network using its userid and id
var post = Post.identify(userid, id);
post.get()
.then((post) => console.log(post.exists ? 'Found it' : 'Not found'))
.catch((error) => console.log(error));
post.loading; // bool. is it currently doing a GET, PUT, or DELETE request?
post.networkError; // string if network error encountered.
// Date last retrieved or put to the network
post.timestamp; // Date() instance, or null if not yet fetched/uploaded
// Delete the model. throws error if you're not the owner.
post.delete();
post.exists; // false
Thoughts, suggestions, and questions welcome!
Add data validation and data versioning to models, which is absolutely critical for the SAFE network. The descriptions below are a copy-paste from the proposal:
name
field, for example, it expects it to be a string of a certain length, and NOT an integer or array. In SAFE, anybody can upload any data they want, so client-side data validation must be included in the app to prevent breakage. Task: create an easy way for the dev to set rules for their data. If rules are not met, then either use some defaults, or remove the object entirely. The dev will have a guarantee that the object returned from the API will follow the application's rules, even if a nefarious user tries to cause trouble. Allow devs to attach error messages for each validation rule so they could be used to quickly validate forms, too.string
field may eventually become an array
field to allow multiple options. The developer cannot go and change all existing data to reflect this change, so his app needs to be smart and maintain backwards compatibility for every single object schema change. Over time, this can lead to massive headaches and spaghetti code in order to make sure old data is supported. Task: introduce versioning for models. Every object PUT to the network should have an integer version number. Upon fetching it, if the model detects that the version number is not the latest one, it incrementally modifies its data using the model's set rules until it matches the rules of the latest version. This should make app development much easier knowing that even old data on the network will be returned using the latest schemas. This allows newer code to read older data, but not vice versa. Bonus: if the requester of the data is also the data owner, automatically UPDATE the object on the network (if possible) so that the same version processing won't be required in the future for all requests. With Structured Data this will be free.Fields validated will have rules set like this:
// Define a model that has 5 properties: title, myNumber, date, myName, and hello.
Model.validation = {
0: { // version of the rules (explained later)
title: { // property name
rules: Rules.required().string().max(100), // chainable rules
default: "Default Title" // if fails validation, return this value
},
myNumber: {
rules: Rules.integer().min(0),
default: undefined // remove this property if validation fails
},
date: {
rules: Rules.date().dateBetween('2015-01-01', '2015-12-31'), // as parsable by MomentJS
default: Remove // special object for critical props that, if provided as default value, essentially ignores this whole object
},
myName: {
rules: Rules.custom(function(entity) {
if (!entity[myName].includes('Hi, my name is')) {
return false; // fails
} else {
return true; // passes
}
default: 'Hi, my name is John Doe'
},
hello: {} // no validation at all, but this is required if the field is present
}
}
Each property in the object being retrieved or put to the network must pass the validation rules provided. Each property is an object that contains rules
and default
, both optional.
A Rules
object is supplied to rules
that contains many chainable validation methods, including custom()
allowing you to supply your own validation function that is passed an entity object. It should return a boolean indicating passing or failure. If it returns a function, then the return value of that function will be used as the new value. No validation rules are run if rules
is not supplied. Rules are run in order of appearance.
If data is being PUT
to the network and validation fails, it will throw an error. The required()
rule only applies before PUTs
.
If data is being retrieved, the default
value will be used in place of fields that failed validation. If default
is not set, it defaults to undefined
. If default
is undefined
, the field will be removed from the entity. If default
is a function, it will be called given the entity
object, allowing to create a default value based on other fields. If default
is an instance of "Remove", the entire entity will be set as exists = false
and data discarded, in other words, as if it doesn't exist on the network. If the field does not exist on the object at all, it will be set to the default value.
Example validation rules:
string
, number
, array
, boolean
, etcmax
, min
, between
max
, min
, size
, alpha
, alphanum
, base64
, etcdate
, dateBetween
, dateFormat
trim
(strings)If a field is present in the entity that has no matching key in the validation object, it is discarded. Thus, every field in an entity must be defined in the validator.
When defining models, add a static currentVersion
property that for the first time should be 0
. Every time any of the above rules are modified in a non-backwards-compatible way, such as a string
becoming an array
, increment the static version by one and add a transformer function that transforms the entity object from the previous rule-set.
Every entity must have a property version
set that is an integer value, indicating the version of the validation used when creating or last updating the object. If not set on the entity, it is discarded (discuss--or should it assume the latest version?)
When changing an existing rule, the process is as follows:
Take the following Post model as an example:
class Post extends Model {}
Post.name = 'Post'
Post.currentVersion = 0
Post.validation = {
0: {
title: {
rules: Rules.required().string()
},
category: {
rules: Rules.required().string() // e.g. 'art'
}
}
}
We now have Post model whose current version is 0. The current validation rules define title
and category
fields, which are both strings. Now what if we wanted to make category
an array instead of a string to support multiple categories? We can't just change the rules, since all the existing data on the network has a string, and thus would fail validation. We need to define a transformer along with the new rule:
Post.currentVersion = 1 // increment the current model version
Post.validation = {
0: {
title: {
rules: Rules.string()
},
category: {
rules: Rules.string(), // e.g. 'art'
default: 'Misc'
}
},
1: { // add a new validation rule that overrides the previous one
category: {
rules: Rules.array(),
default: ['Misc']
}
}
}
Post.transformers = {
// Takes entity with version 0 and turns it into version 1.
// By the time this function is called, validation 0 has already been called.
// Thus you are guaranteed to work with valid data.
1: function(entity) {
// turn category into an array
entity.category = [entity.category]
}
If a post is retrieved from the network with a version
set to 0, meaning it was uploaded when version 1 didn't exist, the following will happen:
required()
, isNumeric()
, etc. I am thinking to delay this part as it's not technically related to SAFE.Have any comments or questions? Please share!
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.