All-in-one full-stack package for managing complex web applications.
Installations
npm install backland
Developer Guide
Typescript
Yes
Module System
CommonJS, UMD
Node Version
18.14.0
NPM Version
9.3.1
Score
44.1
Supply Chain
58.1
Quality
72.4
Maintenance
50
Vulnerability
97.3
License
Releases
Unable to fetch releases
Contributors
Unable to fetch Contributors
Languages
TypeScript (97.47%)
JavaScript (2.51%)
Shell (0.01%)
Love this project? Help keep it running — sponsor us today! 🚀
Developer
antoniopresto
Download Statistics
Total Downloads
16,776
Last Day
16
Last Week
58
Last Month
152
Last Year
1,331
GitHub Statistics
4 Stars
634 Commits
1 Watching
12 Branches
3 Contributors
Bundle Size
430.44 kB
Minified
104.85 kB
Minified + Gzipped
Package Meta Information
Latest Version
0.2.10
Package Id
backland@0.2.10
Unpacked Size
12.48 kB
Size
3.79 kB
File Count
9
NPM Version
9.3.1
Node Version
18.14.0
Publised On
13 Feb 2023
Total Downloads
Cumulative downloads
Total Downloads
16,776
Last day
0%
16
Compared to previous day
Last week
123.1%
58
Compared to previous week
Last month
253.5%
152
Compared to previous month
Last year
-78.6%
1,331
Compared to previous year
Daily Downloads
Weekly Downloads
Monthly Downloads
Yearly Downloads
Dev Dependencies
34
Backland / Modules
Backland
All-in-one full-stack package for managing complex web applications.
Backland is the full-stack package of choice for creating, managing, and scaling complex web applications with support for single-table design.
Using Backland you can quickly create types that can be easily extended, transformed into GraphQL, TypeScript, and used in both frontend and backend applications.
Table of Contents
- Typescript Infer
- Extending Types
- Static typescript Infer
- Printing Types as Typescript
- Validation
- Entity & CRUD
- GraphQL
Creating and extending types
1import {
2 createGraphQLSchema,
3 createResolver,
4 createType,
5 createEntity,
6 Infer,
7} from 'backland';
8
9const AddressType = createType('Address', {
10 object: {
11 street: 'string',
12 number: {
13 union: [
14 'string',
15 'int?',
16 ],
17 },
18 },
19});
20
21const UserType = createType(
22 {
23 object: {
24 name: 'string', // any string
25 email: 'email?', // email type - will validate against email regex
26 age: 'int?', // optional integer
27 notes: '[int]?',
28
29 // declaring a union field - will infer as `string | undefined | number[]`
30 unionField: {
31 union: [
32 'string?',
33 '[int]?',
34 ],
35 },
36
37 // represents an enum
38 letter: {
39 enum: [
40 'a',
41 'b',
42 'c',
43 ],
44 },
45
46 // more detailed way to define enums
47 letterOptionalList: {
48 enum: [
49 'x',
50 'y',
51 'z',
52 ],
53 optional: true,
54 list: true,
55 },
56
57 // using a previous object as field type
58 addresses: {
59 type: AddressType,
60 list: true,
61 },
62
63 // another way to define object fields
64 deliveryAddress: {
65 object: {
66 street: 'string',
67 number: 'int?',
68 },
69 },
70 },
71 } as const // "as const" is needed to TS to infer types correctly
72);
Extending types
1const StoreType = UserType.clone((it) => 2 it.exclude(['addresses']).extendObjectDefinition({ storeId: 'ID', ownerId: 'string' }).graphType('Store') 3);
Static typescript infer
1type TStoreType = Infer<typeof StoreType>;
Printing types as Typescript
1const storeTS = await StoreType.typescriptPrint(); 2 3expect(storeTS.split('\n')).toEqual([ 4 'export interface Store {', 5 ' name: string;', 6 ' email?: Email;', 7 ' age?: number;', 8 ' notes?: number[];', 9 ' unionField?: string | number[];', 10 ' letter: "a" | "b" | "c";', 11 ' letterOptionalList?: ("x" | "y" | "z")[];', 12 ' deliveryAddress: {', 13 ' street: string;', 14 ' number?: number;', 15 ' };', 16 ' storeId: ID;', 17 ' ownerId: string;', 18 '}', 19 '', 20]);
Validation
1try { 2 const validStoreData = StoreType.parse({}); 3 console.log(validStoreData); 4} catch (e) { 5 /* 6 * Error: Store: ➤ field "ownerId": RequiredField. 7 * ➤ field "storeId": RequiredField. 8 * ➤ field "deliveryAddress": RequiredField. 9 * ➤ field "letter": RequiredField. 10 * ➤ field "name": RequiredField. 11 */ 12}
Entity and CRUD
1const StoreEntity = createEntity({
2 name: 'Store',
3 type: StoreType,
4 indexes: [
5 {
6 name: 'id1', // index in database to be used
7 PK: ['.storeId'],
8 },
9 {
10 name: 'id2',
11 PK: [
12 '.ownerId',
13 '.storeId',
14 ],
15 },
16 ],
17});
18
19const findStoreResolver = createResolver({
20 name: 'findStore',
21 type: StoreEntity.edgeType,
22 args: {
23 storeId: 'string',
24 },
25}).resolver(async (_, { storeId /* ✨ automaticly typed as string */ }, requestContext) => {
26 const filter = {
27 storeId,
28 };
29
30 return StoreEntity.findOne({ filter, context: requestContext });
31});
GraphQL
1const graphqlSchema = createGraphQLSchema([findStoreResolver]); 2 3const schemaTXT = graphqlSchema.utils.print(); 4 5expect(schemaTXT.split('\n')).toEqual([ 6 'type Query {', 7 ' findStore(storeId: String!): Store_Edge!', 8 '}', 9 '', 10 'type Store_Edge {', 11 ' cursor: String!', 12 ' node: StoreEntity!', 13 '}', 14 '', 15 'type StoreEntity {', 16 ' createdAt: Date!', 17 ' createdBy: String', 18 ' id: String!', 19 ' ulid: Ulid!', 20 ' updatedAt: Date!', 21 ' updatedBy: String', 22 '', 23 ' """', 24 ' The full string value of the first index following the RegExp format "^storeâ‹®id1â‹®.*"', 25 ' """', 26 ' _id: String!', 27 '', 28 ' """', 29 ' The id1PK field in the RegExp format "^storeâ‹®id1â‹®.*"', 30 ' """', 31 ' id1PK: String!', 32 '', 33 ' """', 34 ' The id2PK field in the RegExp format "^storeâ‹®id2â‹®.*"', 35 ' """', 36 ' id2PK: String!', 37 ' name: String!', 38 ' email: String', 39 ' age: Int', 40 ' notes: [Int]', 41 ' unionField: StoreEntity_unionField', 42 ' letter: StoreEntity_letter!', 43 ' letterOptionalList: [StoreEntity_letterOptionalList]', 44 ' deliveryAddress: StoreEntity_deliveryAddress!', 45 ' storeId: ID!', 46 ' ownerId: String!', 47 '}', 48 '', 49 'scalar Date', 50 '', 51 'scalar Ulid', 52 '', 53 '"""', 54 'Union of { optional:true, type: string } | { list:true, optional:true, type: int }', 55 '"""', 56 'scalar StoreEntity_unionField', 57 '', 58 'enum StoreEntity_letter {', 59 ' a', 60 ' b', 61 ' c', 62 '}', 63 '', 64 'enum StoreEntity_letterOptionalList {', 65 ' x', 66 ' y', 67 ' z', 68 '}', 69 '', 70 'type StoreEntity_deliveryAddress {', 71 ' street: String!', 72 ' number: Int', 73 '}', 74]);
No vulnerabilities found.
No security vulnerabilities found.
Gathering detailed insights and metrics for backland