Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/The-Commit-Company/frappe-js-sdk
TypeScript/JavaScript library for Frappe REST API
https://github.com/The-Commit-Company/frappe-js-sdk
Last synced: 4 months ago
JSON representation
TypeScript/JavaScript library for Frappe REST API
- Host: GitHub
- URL: https://github.com/The-Commit-Company/frappe-js-sdk
- Owner: The-Commit-Company
- License: mit
- Created: 2021-12-22T09:10:43.000Z (almost 3 years ago)
- Default Branch: main
- Last Pushed: 2024-03-19T17:07:22.000Z (9 months ago)
- Last Synced: 2024-05-02T03:13:13.602Z (8 months ago)
- Language: TypeScript
- Size: 149 KB
- Stars: 102
- Watchers: 7
- Forks: 39
- Open Issues: 7
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
- awesome-frappe - Frappe JS SDK - TypeScript/JavaScript library for Frappe REST API (Uncategorized / Uncategorized)
README
# frappe-js-sdk
TypeScript/JavaScript library for a [Frappe Framework](https://frappeframework.com) backend.
## Features
The library currently supports the following features:
- 🔐 Authentication - login with username and password (cookie based) + token based authentication
- 🗄 Database - Get document, get list of documents, get count, create, update and delete documents
- 📄 File upload
- 🤙🏻 API callsWe plan to add the following features in the future:
- Support for common functions like `exists` in the database.
The library uses [Axios](https://axios-http.com) under the hood to make API calls to your Frappe backend.
## Maintainers
| Maintainer | GitHub | Social |
| -------------- | ----------------------------------------------- | ------------------------------------------------------------ |
| Nikhil Kothari | [nikkothari22](https://github.com/nikkothari22) | [@nik_kothari22](https://twitter.com/nik_kothari22) |
| Janhvi Patil | [janhvipatil](https://github.com/janhvipatil) | [@janhvipatil_](https://twitter.com/janhvipatil_) |
| Sumit Jain | [sumitjain236](https://github.com/sumitjain236) | [LinkedIn](https://www.linkedin.com/in/sumit-jain-66bb5719a) |## Installation
```bash
npm install frappe-js-sdk
```or
```bash
yarn add frappe-js-sdk
```## Initialising the library
To get started, initialise the library:
```js
import { FrappeApp } from 'frappe-js-sdk';
//Add your Frappe backend's URL
const frappe = new FrappeApp('https://test.frappe.cloud');
```In case you want to use the library with token based authentication (OAuth bearer tokens or API key/secret pairs), you can initialise the library like this:
```js
import { FrappeApp } from "frappe-js-sdk";const frappe = new FrappeApp("https://test.frappe.cloud", {
useToken: true,
// Pass a custom function that returns the token as a string - this could be fetched from LocalStorage or auth providers like Firebase, Auth0 etc.
token: getTokenFromLocalStorage(),
// This can be "Bearer" or "token"
type: "Bearer"
})
```## Authentication
#### Initialise the auth library
```js
const auth = frappe.auth()
```#### Login a user:
This makes an API call to the `/api/method/login` endpoint.
```js
auth
.loginWithUsernamePassword({ username: 'admin', password: 'my-password' })
.then((response) => console.log('Logged in'))
.catch((error) => console.error(error));
```#### Get currently logged in user:
This makes an API call to the `/api/method/frappe.auth.get_logged_user` endpoint.
```js
auth
.getLoggedInUser()
.then((user) => console.log(`User ${user} is logged in.`))
.catch((error) => console.error(error));
```#### Logout:
This makes an API call to the `/api/method/logout` endpoint.
```js
auth
.logout()
.then(() => console.log('Logged out.'))
.catch((error) => console.error(error));
```#### Forget Password
This makes an API sends a password reset link to the specified email address.
```js
auth
.forgetPassword('[email protected]')
.then(() => console.log('Password Reset Email Sent!'))
.catch(() => console.error("We couldn't find your account."));
```## Database
#### Initialise the database library
```js
const db = frappe.db();
```#### Fetch document using document name
```js
db.getDoc('DocType', 'My DocType Name')
.then((doc) => console.log(doc))
.catch((error) => console.error(error));
```#### Fetch list of documents
```js
db.getDocList('DocType')
.then((docs) => console.log(docs))
.catch((error) => console.error(error));
```Optionally, a second argument can be provided to filter, sort, limit and paginate results.
```js
db.getDocList('DocType', {
/** Fields to be fetched */
fields: ['name', 'creation'],
/** Filters to be applied - SQL AND operation */
filters: [['creation', '>', '2021-10-09']],
/** Filters to be applied - SQL OR operation */
orFilters: [],
/** Fetch from nth document in filtered and sorted list. Used for pagination */
limit_start: 5,
/** Number of documents to be fetched. Default is 20 */
limit: 10,
/** Sort results by field and order */
orderBy: {
field: 'creation',
order: 'desc',
},
/** Group the results by particular field */
groupBy: 'name',
/** Fetch documents as a dictionary */
asDict: false,
})
.then((docs) => console.log(docs))
.catch((error) => console.error(error));
```Type declarations are available for the second argument in the source code.
#### Fetch number of documents with filters
```js
const filters = [['creation', '>', '2021-10-09']];
const useCache = true; /** Default is false - Optional **/
const debug = false; /** Default is false - Optional **/db.getCount('DocType', filters, cache, debug)
.then((count) => console.log(count))
.catch((error) => console.error(error));
```#### Create a document
To create a new document, pass the name of the DocType and the fields to `createDoc`.
```js
db.createDoc('My Custom DocType', {
name: 'Test',
test_field: 'This is a test field',
})
.then((doc) => console.log(doc))
.catch((error) => console.error(error));
```#### Update a document
To update an existing document, pass the name of the DocType, name of the document and the fields to be updated to `updateDoc`.
```js
db.updateDoc('My Custom DocType', 'Test', {
test_field: 'This is an updated test field.',
})
.then((doc) => console.log(doc))
.catch((error) => console.error(error));
```#### Delete a document
To create a new document, pass the name of the DocType and the name of the document to be deleted to `deleteDoc`.
```js
db.deleteDoc('My Custom DocType', 'Test')
.then((response) => console.log(response.message)) // Message will be "ok"
.catch((error) => console.error(error));
```## Usage with Typescript
The library supports Typescript out of the box.
For example, to enforce type on the `updateDoc` method:```ts
interface TestDoc {
test_field: string;
}
db.updateDoc('My Custom DocType', 'Test', {
test_field: 'This is an updated test field.',
});
```The library also has an inbuilt type `FrappeDoc` which adds the following fields to your type declarations when you use it with the database methods:
```ts
export type FrappeDoc = T & {
/** User who created the document */
owner: string;
/** Date and time when the document was created - ISO format */
creation: string;
/** Date and time when the document was last modified - ISO format */
modified: string;
/** User who last modified the document */
modified_by: string;
idx: number;
/** 0 - Saved, 1 - Submitted, 2 - Cancelled */
docstatus: 0 | 1 | 2;
parent?: any;
parentfield?: any;
parenttype?: any;
/** The primary key of the DocType table */
name: string;
};
```All document responses are returned as an intersection of `FrappeDoc` and the specified type.
## API Calls
#### Initialise the call library
```ts
const call = frappe.call();
```Make sure all endpoints are whitelisted (`@frappe.whitelist()`) in your backend
#### GET request
Make a GET request to your endpoint with parameters.
```js
const searchParams = {
doctype: 'Currency',
txt: 'IN',
};
call
.get('frappe.desk.search_link', searchParams)
.then((result) => console.log(result))
.catch((error) => console.error(error));
```#### POST request
Make a POST request to your endpoint with parameters.
```js
const updatedFields = {
doctype: 'User',
name: 'Administrator',
fieldname: 'interest',
value: 'Frappe Framework, ERPNext',
};
call
.post('frappe.client.set_value', updatedFields)
.then((result) => console.log(result))
.catch((error) => console.error(error));
```#### PUT request
Make a PUT request to your endpoint with parameters.
```js
const updatedFields = {
doctype: 'User',
name: 'Administrator',
fieldname: 'interest',
value: 'Frappe Framework, ERPNext',
};
call
.put('frappe.client.set_value', updatedFields)
.then((result) => console.log(result))
.catch((error) => console.error(error));
```#### DELETE request
Make a DELETE request to your endpoint with parameters.
```js
const documentToBeDeleted = {
doctype: 'Tag',
name: 'Random Tag',
};
call
.put('frappe.client.delete', documentToBeDeleted)
.then((result) => console.log(result))
.catch((error) => console.error(error));
```## File Uploads
#### Initialise the file library
```ts
const file = frappe.file();
```#### Upload a file with on progress callback
```js
const myFile; //Your File objectconst fileArgs = {
/** If the file access is private then set to TRUE (optional) */
"isPrivate": true,
/** Folder the file exists in (optional) */
"folder": "Home",
/** File URL (optional) */
"file_url": "",
/** Doctype associated with the file (optional) */
"doctype": "User",
/** Docname associated with the file (mandatory if doctype is present) */
"docname": "Administrator",
/** Field in the document **/
"fieldname": "image"
}file.uploadFile(
myFile,
fileArgs,
/** Progress Indicator callback function **/
(completedBytes, totalBytes) => console.log(Math.round((completedBytes / totalBytes) * 100), " completed")
)
.then(() => console.log("File Upload complete"))
.catch(e => console.error(e))
```## License
See [LICENSE](./LICENSE).