Para was designed as a simple and modular backend framework for object persistence and retrieval. It helps you build applications faster by taking care of the backend. It works on three levels - objects are stored in a NoSQL data store or any old relational database, then automatically indexed by a search engine and finally, cached.
This is the JavaScript client for Para.
npm install para-client-js --saveInitialize the client in your code like so:
import { ParaClient } from 'para-client-js';
var pc = new ParaClient('ACCESS_KEY', 'SECRET_KEY');If your code runs in a browser environment, you should use a blank secret key and then call signIn():
pc.signIn("password", "{email}::{password}", function(user) {
// do something with the newly created user
});
It's a bad idea to hardcode your Para secret key in your code because it will run in an insecure client-side environment. Instead use the signIn() method to get an access token (JWT) with limited client permissions. Think of it like this: API key+secret = full API access, paraClient.signIn() = limited API access for clients with JWT tokens.
You can have a special user object created just for your JS app and assign it special permissions so that your app can access a part of the Para API before authenticating another real user. Read the documentation for more information about client permissions.
For granting resource permissions to your client users go to console.paraio.org where you can edit your app object and allow your users the call specific API methods.
To use para-client-js in the browser run:
npm install
npm run buildThis will generate dist/browser/para-client-js.global.iife.js which you can include directly in the browser:
<html>
<head>
<script src="dist/browser/para-client-js.global.iife.js"></script>
</head>
<body>
<script>
var pc = new ParaClient('ACCESS_KEY', '');
</script>
</body>
</html>npm run buildbundles ESM, CommonJS, and browser artifacts intodist/using tsdown. Types are emitted vianpm run types.npm testruns ESLint, the type tests intest/types, and the fast unit tests intest/unit.- Integration tests live under
test/integrationand require a running Para server. Copy.env.exampleto.env, adjustPARA_*values, then runnpm run test:integration.
Most methods return a promise object and also accept a callback function as last parameter. You can choose to either use callbacks or promises. For example:
// using promises
pc.read('user', '1234').then(
function (user) {
// do something with user object
},
function (err) {
// request failed
}
);
// using callbacks
pc.read('user', '1234', function (user, err) {
// do something with user object
});Type declarations ship with the package. You do not need to install a separate @types package.
The default export and the named export are the same class:
import ParaClient from 'para-client-js';
import { ParaClient as NamedParaClient } from 'para-client-js';
const first: ParaClient = new ParaClient('ACCESS_KEY', 'SECRET_KEY');
const second: NamedParaClient = new ParaClient('ACCESS_KEY', 'SECRET_KEY');Most methods return a promise, so the callback is optional. The promise result is typed:
import { ParaClient, ParaObject, Pager } from 'para-client-js';
const pc = new ParaClient('ACCESS_KEY', 'SECRET_KEY');
const pager = new Pager(1, 'name', true, 10);
async function example(): Promise<void> {
const created: ParaObject | null = await pc.create(new ParaObject());
const user: ParaObject | null = await pc.read('user', '1234');
const users: ParaObject[] = await pc.list('user', pager);
const count: number = await pc.getCount('user', {});
const allowed: boolean = await pc.isAllowedTo('*', 'utils/timestamp', 'GET');
void [created, user, users, count, allowed];
}ParaObject and Pager constructors accept optional arguments. Constraint provides static factory methods:
import { ParaObject, Pager, Constraint } from 'para-client-js';
const obj = new ParaObject('1234', 'user');
const empty = new ParaObject();
const pager = new Pager();
const descending: boolean = pager.desc;
const required: Constraint = Constraint.required();Set moduleResolution to bundler, node16, or nodenext. With node16 or nodenext, set module to the same value. TypeScript then reads the exports map and the types entry. A minimal tsconfig.json:
{
"compilerOptions": {
"target": "ES2020",
"module": "ESNext",
"moduleResolution": "bundler",
"strict": true
}
}The exports map provides an ESM build and a CommonJS build. TypeScript resolves the matching declarations for each mode. Use import in ESM code. The default export is the ParaClient class. In CommonJS code, require() returns the module object, so use the named export:
const { ParaClient } = require('para-client-js');In the browser, use a blank secret key and call signIn(). AWS Signature Version 4 signing is not available in the browser:
import ParaClient from 'para-client-js';
const pc = new ParaClient('ACCESS_KEY', '');
async function signIn(): Promise<void> {
const user = await pc.signIn('password', '{email}::{password}', true);
void user;
}- Fork this repository and clone the fork to your machine
- Create a branch (
git checkout -b my-new-feature) - Implement a new feature or fix a bug and add some tests
- Commit your changes (
git commit -am 'Added a new feature') - Push the branch to your fork on GitHub (
git push origin my-new-feature) - Create new Pull Request from your fork
For more information see CONTRIBUTING.md
