@fraym/crud 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md ADDED
@@ -0,0 +1,161 @@
1
+ # crud-nodejs
2
+
3
+ Client implementation in javascript for the CRUD service [streams](https://github.com/fraym/crud).
4
+
5
+ ## Installation
6
+
7
+ ```shell
8
+ npm i @fraym/crud
9
+ ```
10
+
11
+ ## Usage
12
+
13
+ ### Create the clients
14
+
15
+ delivery client:
16
+
17
+ ```typescript
18
+ const deliveryClient = await newDeliveryClient({
19
+ serverAddress: "127.0.0.1:9000",
20
+ groupId: "your-services-group-identifier",
21
+ });
22
+ ```
23
+
24
+ management client:
25
+
26
+ ```typescript
27
+ const managementClient = await newManagementClient({
28
+ serverAddress: "127.0.0.1:9000",
29
+ groupId: "your-services-group-identifier",
30
+ });
31
+ ```
32
+
33
+ ### Create one or multipe CRUD types
34
+
35
+ Crud types are defined by schemas. A schema can contain more than one type definition. See [SCHEMA.md](SCHEMA.md) for a reference.
36
+
37
+ ```typescript
38
+ await managementClient.createTypes("your schema here");
39
+ ```
40
+
41
+ ### Update one or multipe CRUD types
42
+
43
+ Crud types are defined by schemas. A schema can contain more than one type definition. See [SCHEMA.md](SCHEMA.md) for a reference.
44
+
45
+ ```typescript
46
+ await managementClient.updateTypes("your schema here");
47
+ ```
48
+
49
+ ### Remove one or multipe CRUD types
50
+
51
+ The name of `YourCrudType` has to equal your type name in your schema (also in casing).
52
+
53
+ ```typescript
54
+ await managementClient.removeTypes(["YourCrudType"]);
55
+ ```
56
+
57
+ ### Get list of existing CRUD types
58
+
59
+ ```typescript
60
+ const list = await managementClient.getAllTypes();
61
+ ```
62
+
63
+ ### Create data
64
+
65
+ The name of `YourCrudType` has to equal your type name in your schema (also in casing).
66
+
67
+ ```typescript
68
+ const { id } = await client.create("tenantId", "YourCrudType", {
69
+ // values here
70
+ });
71
+ ```
72
+
73
+ ### Update data
74
+
75
+ The name of `YourCrudType` has to equal your type name in your schema (also in casing).
76
+ The `id` has to match the id of the data that you want to update.
77
+
78
+ ```typescript
79
+ await client.update("tenantId", "YourCrudType", "id", {
80
+ // values here
81
+ });
82
+ ```
83
+
84
+ ### Delete data
85
+
86
+ The name of `YourCrudType` has to equal your type name in your schema (also in casing).
87
+ The `id` has to match the id of the data that you want to delete.
88
+
89
+ ```typescript
90
+ await client.delete("tenantId", "YourCrudType", "id");
91
+ ```
92
+
93
+ ### Get a single data element
94
+
95
+ The name of `YourCrudType` has to equal your type name in your schema (also in casing).
96
+ The `id` has to match the id of the data that you want to delete.
97
+
98
+ ```typescript
99
+ const data = await client.getData("tenantId", "YourCrudType", "id");
100
+ ```
101
+
102
+ ### Get (paginated) data
103
+
104
+ The name of `YourCrudType` has to equal your type name in your schema (also in casing).
105
+
106
+ No pagination:
107
+
108
+ ```typescript
109
+ const data = await client.getDataList("tenantId", "YourCrudType");
110
+ ```
111
+
112
+ With pagination:
113
+
114
+ ```typescript
115
+ const limit = 50; // elements to query per page
116
+ const page = 1; // number of the page you want to select, first page starts at: 1
117
+ const data = await client.getDataList("tenantId", "YourCrudType", limit, page);
118
+ ```
119
+
120
+ ### Gracefully close the clients
121
+
122
+ You won't lose any data if you don't. Use it for your peace of mind.
123
+
124
+ ```typescript
125
+ client.close();
126
+ ```
127
+
128
+ ## Development
129
+
130
+ You'll need the following apps for a smooth development experience:
131
+
132
+ - minikube
133
+ - lens
134
+ - okteto
135
+ - helm
136
+
137
+ ### Running the dev environment
138
+
139
+ - Start minikube if not already done:
140
+
141
+ ```shell
142
+ minikube start
143
+ ```
144
+
145
+ - add mongodb and minio to your lokal kubernetes
146
+ - use Makefiles in `./.dev/*`
147
+ - copy `.env.build` to `.env.build.local`
148
+ - add your personal access token (needs read access for private fraym org repositories)
149
+ - deploy the app to your cluster
150
+
151
+ ```
152
+ make init
153
+ ```
154
+
155
+ - start okteto
156
+
157
+ ```
158
+ make dev
159
+ ```
160
+
161
+ - connect your IDE to that okteto instance
@@ -0,0 +1,6 @@
1
+ export interface ClientConfig {
2
+ serverAddress: string;
3
+ keepaliveInterval?: number;
4
+ keepaliveTimeout?: number;
5
+ }
6
+ export declare const useConfigDefaults: (config: ClientConfig) => Required<ClientConfig>;
@@ -0,0 +1,12 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.useConfigDefaults = void 0;
4
+ const useConfigDefaults = (config) => {
5
+ var _a, _b;
6
+ return {
7
+ serverAddress: config.serverAddress,
8
+ keepaliveTimeout: (_a = config.keepaliveTimeout) !== null && _a !== void 0 ? _a : 3 * 1000,
9
+ keepaliveInterval: (_b = config.keepaliveInterval) !== null && _b !== void 0 ? _b : 40 * 1000,
10
+ };
11
+ };
12
+ exports.useConfigDefaults = useConfigDefaults;
@@ -0,0 +1,13 @@
1
+ import { ClientConfig } from "../config/config";
2
+ import { CreatedCrudData } from "./create";
3
+ import { GetCrudData } from "./getData";
4
+ import { GetCrudDataList } from "./getDataList";
5
+ export interface DeliveryClient {
6
+ create: (tenantId: string, type: string, data: Record<string, any>) => Promise<CreatedCrudData>;
7
+ update: (tenantId: string, type: string, id: string, data: Record<string, any>) => Promise<void>;
8
+ delete: (tenantId: string, type: string, id: string) => Promise<void>;
9
+ getData: (tenantId: string, type: string, id: string) => Promise<GetCrudData | null>;
10
+ getDataList: (tenantId: string, type: string, limit?: number, page?: number) => Promise<GetCrudDataList | null>;
11
+ close: () => Promise<void>;
12
+ }
13
+ export declare const newDeliveryClient: (config: ClientConfig) => Promise<DeliveryClient>;
@@ -0,0 +1,46 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.newDeliveryClient = void 0;
4
+ const config_1 = require("../config/config");
5
+ const crud_proto_1 = require("@fraym/crud-proto");
6
+ const grpc_js_1 = require("@grpc/grpc-js");
7
+ const create_1 = require("./create");
8
+ const update_1 = require("./update");
9
+ const delete_1 = require("./delete");
10
+ const getData_1 = require("./getData");
11
+ const getDataList_1 = require("./getDataList");
12
+ const newDeliveryClient = async (config) => {
13
+ config = (0, config_1.useConfigDefaults)(config);
14
+ const serviceClient = new crud_proto_1.DeliveryServiceClient(config.serverAddress, grpc_js_1.credentials.createInsecure(), {
15
+ "grpc.keepalive_time_ms": config.keepaliveInterval,
16
+ "grpc.keepalive_timeout_ms": config.keepaliveTimeout,
17
+ "grpc.keepalive_permit_without_calls": 1,
18
+ });
19
+ const create = async (tenantId, type, data) => {
20
+ return await (0, create_1.createCrudData)(tenantId, type, data, serviceClient);
21
+ };
22
+ const update = async (tenantId, type, id, data) => {
23
+ return await (0, update_1.updateCrudData)(tenantId, type, id, data, serviceClient);
24
+ };
25
+ const deleter = async (tenantId, type, id) => {
26
+ return await (0, delete_1.deleteCrudData)(tenantId, type, id, serviceClient);
27
+ };
28
+ const getData = async (tenantId, type, id) => {
29
+ return await (0, getData_1.getCrudData)(tenantId, type, id, serviceClient);
30
+ };
31
+ const getDataList = async (tenantId, type, limit = 0, page = 1) => {
32
+ return await (0, getDataList_1.getCrudDataList)(tenantId, type, limit, page, serviceClient);
33
+ };
34
+ const close = async () => {
35
+ serviceClient.close();
36
+ };
37
+ return {
38
+ create,
39
+ update,
40
+ delete: deleter,
41
+ getData,
42
+ getDataList,
43
+ close,
44
+ };
45
+ };
46
+ exports.newDeliveryClient = newDeliveryClient;
@@ -0,0 +1,5 @@
1
+ import { DeliveryServiceClient } from "@fraym/crud-proto";
2
+ export interface CreatedCrudData {
3
+ id: string;
4
+ }
5
+ export declare const createCrudData: (tenantId: string, type: string, data: Record<string, any>, serviceClient: DeliveryServiceClient) => Promise<CreatedCrudData>;
@@ -0,0 +1,30 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.createCrudData = void 0;
4
+ const createCrudData = async (tenantId, type, data, serviceClient) => {
5
+ const requestData = {};
6
+ for (const key in data) {
7
+ if (typeof data[key] === "string") {
8
+ requestData[key] = data[key];
9
+ }
10
+ else {
11
+ requestData[key] = JSON.stringify(data[key]);
12
+ }
13
+ }
14
+ return new Promise((resolve, reject) => {
15
+ serviceClient.createEntry({
16
+ tenantId,
17
+ type,
18
+ data: requestData,
19
+ }, (error, response) => {
20
+ if (error) {
21
+ reject(error.message);
22
+ return;
23
+ }
24
+ resolve({
25
+ id: response.id,
26
+ });
27
+ });
28
+ });
29
+ };
30
+ exports.createCrudData = createCrudData;
@@ -0,0 +1,2 @@
1
+ import { DeliveryServiceClient } from "@fraym/crud-proto";
2
+ export declare const deleteCrudData: (tenantId: string, type: string, id: string, serviceClient: DeliveryServiceClient) => Promise<void>;
@@ -0,0 +1,19 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.deleteCrudData = void 0;
4
+ const deleteCrudData = async (tenantId, type, id, serviceClient) => {
5
+ return new Promise((resolve, reject) => {
6
+ serviceClient.deleteEntry({
7
+ tenantId,
8
+ type,
9
+ id,
10
+ }, error => {
11
+ if (error) {
12
+ reject(error.message);
13
+ return;
14
+ }
15
+ resolve();
16
+ });
17
+ });
18
+ };
19
+ exports.deleteCrudData = deleteCrudData;
@@ -0,0 +1,3 @@
1
+ import { DeliveryServiceClient } from "@fraym/crud-proto";
2
+ export declare type GetCrudData = Record<string, any>;
3
+ export declare const getCrudData: (tenantId: string, type: string, id: string, serviceClient: DeliveryServiceClient) => Promise<GetCrudData | null>;
@@ -0,0 +1,30 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getCrudData = void 0;
4
+ const getCrudData = async (tenantId, type, id, serviceClient) => {
5
+ return new Promise((resolve, reject) => {
6
+ serviceClient.getEntries({
7
+ tenantId,
8
+ type,
9
+ id,
10
+ limit: 0,
11
+ page: 0,
12
+ }, (error, response) => {
13
+ if (error) {
14
+ reject(error.message);
15
+ return;
16
+ }
17
+ if (response.result.length !== 1) {
18
+ resolve(null);
19
+ return;
20
+ }
21
+ const data = {};
22
+ const resultData = response.result[0].data;
23
+ for (const key in resultData) {
24
+ data[key] = JSON.parse(resultData[key]);
25
+ }
26
+ resolve(data);
27
+ });
28
+ });
29
+ };
30
+ exports.getCrudData = getCrudData;
@@ -0,0 +1,7 @@
1
+ import { DeliveryServiceClient } from "@fraym/crud-proto";
2
+ export interface GetCrudDataList {
3
+ limit: number;
4
+ page: number;
5
+ data: Record<string, any>[];
6
+ }
7
+ export declare const getCrudDataList: (tenantId: string, type: string, limit: number, page: number, serviceClient: DeliveryServiceClient) => Promise<GetCrudDataList | null>;
@@ -0,0 +1,34 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getCrudDataList = void 0;
4
+ const getCrudDataList = async (tenantId, type, limit, page, serviceClient) => {
5
+ return new Promise((resolve, reject) => {
6
+ serviceClient.getEntries({
7
+ tenantId,
8
+ type,
9
+ id: "",
10
+ limit,
11
+ page,
12
+ }, (error, response) => {
13
+ if (error) {
14
+ reject(error.message);
15
+ return;
16
+ }
17
+ const data = [];
18
+ for (const result of response.result) {
19
+ const dataRecord = {};
20
+ const resultData = result.data;
21
+ for (const key in resultData) {
22
+ dataRecord[key] = JSON.parse(resultData[key]);
23
+ }
24
+ data.push(dataRecord);
25
+ }
26
+ resolve({
27
+ limit: response.limit,
28
+ page: response.page,
29
+ data,
30
+ });
31
+ });
32
+ });
33
+ };
34
+ exports.getCrudDataList = getCrudDataList;
@@ -0,0 +1,2 @@
1
+ import { DeliveryServiceClient } from "@fraym/crud-proto";
2
+ export declare const updateCrudData: (tenantId: string, type: string, id: string, data: Record<string, any>, serviceClient: DeliveryServiceClient) => Promise<void>;
@@ -0,0 +1,29 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.updateCrudData = void 0;
4
+ const updateCrudData = async (tenantId, type, id, data, serviceClient) => {
5
+ const requestData = {};
6
+ for (const key in data) {
7
+ if (typeof data[key] === "string") {
8
+ requestData[key] = data[key];
9
+ }
10
+ else {
11
+ requestData[key] = JSON.stringify(data[key]);
12
+ }
13
+ }
14
+ return new Promise((resolve, reject) => {
15
+ serviceClient.updateEntry({
16
+ tenantId,
17
+ type,
18
+ id,
19
+ data: requestData,
20
+ }, error => {
21
+ if (error) {
22
+ reject(error.message);
23
+ return;
24
+ }
25
+ resolve();
26
+ });
27
+ });
28
+ };
29
+ exports.updateCrudData = updateCrudData;
@@ -0,0 +1,3 @@
1
+ export * from "./delivery/client";
2
+ export * from "./management/client";
3
+ export { ClientConfig } from "./config/config";
package/dist/index.js ADDED
@@ -0,0 +1,18 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ __exportStar(require("./delivery/client"), exports);
18
+ __exportStar(require("./management/client"), exports);
@@ -0,0 +1,9 @@
1
+ import { ClientConfig } from "../config/config";
2
+ export interface ManagementClient {
3
+ createTypes: (schema: string) => Promise<void>;
4
+ updateTypes: (schema: string) => Promise<void>;
5
+ removeTypes: (typeNames: string[]) => Promise<void>;
6
+ getAllTypes: () => Promise<string[]>;
7
+ close: () => Promise<void>;
8
+ }
9
+ export declare const newManagementClient: (config: ClientConfig) => Promise<ManagementClient>;
@@ -0,0 +1,41 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.newManagementClient = void 0;
4
+ const crud_proto_1 = require("@fraym/crud-proto");
5
+ const grpc_js_1 = require("@grpc/grpc-js");
6
+ const config_1 = require("../config/config");
7
+ const create_1 = require("./create");
8
+ const getAll_1 = require("./getAll");
9
+ const remove_1 = require("./remove");
10
+ const update_1 = require("./update");
11
+ const newManagementClient = async (config) => {
12
+ config = (0, config_1.useConfigDefaults)(config);
13
+ const serviceClient = new crud_proto_1.ManagementServiceClient(config.serverAddress, grpc_js_1.credentials.createInsecure(), {
14
+ "grpc.keepalive_time_ms": config.keepaliveInterval,
15
+ "grpc.keepalive_timeout_ms": config.keepaliveTimeout,
16
+ "grpc.keepalive_permit_without_calls": 1,
17
+ });
18
+ const createTypes = async (schema) => {
19
+ await (0, create_1.createCrudTypes)(schema, serviceClient);
20
+ };
21
+ const updateTypes = async (schema) => {
22
+ await (0, update_1.updateCrudTypes)(schema, serviceClient);
23
+ };
24
+ const removeTypes = async (typeNames) => {
25
+ await (0, remove_1.removeCrudTypes)(typeNames, serviceClient);
26
+ };
27
+ const getAllTypes = async () => {
28
+ return await (0, getAll_1.getAllCrudTypes)(serviceClient);
29
+ };
30
+ const close = async () => {
31
+ serviceClient.close();
32
+ };
33
+ return {
34
+ createTypes,
35
+ updateTypes,
36
+ removeTypes,
37
+ getAllTypes,
38
+ close,
39
+ };
40
+ };
41
+ exports.newManagementClient = newManagementClient;
@@ -0,0 +1,2 @@
1
+ import { ManagementServiceClient } from "@fraym/crud-proto";
2
+ export declare const createCrudTypes: (schema: string, serviceClient: ManagementServiceClient) => Promise<void>;
@@ -0,0 +1,17 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.createCrudTypes = void 0;
4
+ const createCrudTypes = async (schema, serviceClient) => {
5
+ return new Promise((resolve, reject) => {
6
+ serviceClient.createTypes({
7
+ schema,
8
+ }, error => {
9
+ if (error) {
10
+ reject(error.message);
11
+ return;
12
+ }
13
+ resolve();
14
+ });
15
+ });
16
+ };
17
+ exports.createCrudTypes = createCrudTypes;
@@ -0,0 +1,2 @@
1
+ import { ManagementServiceClient } from "@fraym/crud-proto";
2
+ export declare const getAllCrudTypes: (serviceClient: ManagementServiceClient) => Promise<string[]>;
@@ -0,0 +1,15 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getAllCrudTypes = void 0;
4
+ const getAllCrudTypes = async (serviceClient) => {
5
+ return new Promise((resolve, reject) => {
6
+ serviceClient.getTypes({}, (error, response) => {
7
+ if (error) {
8
+ reject(error.message);
9
+ return;
10
+ }
11
+ resolve(response.typeNames);
12
+ });
13
+ });
14
+ };
15
+ exports.getAllCrudTypes = getAllCrudTypes;
@@ -0,0 +1,2 @@
1
+ import { ManagementServiceClient } from "@fraym/crud-proto";
2
+ export declare const removeCrudTypes: (typeNames: string[], serviceClient: ManagementServiceClient) => Promise<void>;
@@ -0,0 +1,17 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.removeCrudTypes = void 0;
4
+ const removeCrudTypes = async (typeNames, serviceClient) => {
5
+ return new Promise((resolve, reject) => {
6
+ serviceClient.removeTypes({
7
+ typeNames,
8
+ }, error => {
9
+ if (error) {
10
+ reject(error.message);
11
+ return;
12
+ }
13
+ resolve();
14
+ });
15
+ });
16
+ };
17
+ exports.removeCrudTypes = removeCrudTypes;
@@ -0,0 +1,2 @@
1
+ import { ManagementServiceClient } from "@fraym/crud-proto";
2
+ export declare const updateCrudTypes: (schema: string, serviceClient: ManagementServiceClient) => Promise<void>;
@@ -0,0 +1,17 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.updateCrudTypes = void 0;
4
+ const updateCrudTypes = async (schema, serviceClient) => {
5
+ return new Promise((resolve, reject) => {
6
+ serviceClient.updateTypes({
7
+ schema,
8
+ }, error => {
9
+ if (error) {
10
+ reject(error.message);
11
+ return;
12
+ }
13
+ resolve();
14
+ });
15
+ });
16
+ };
17
+ exports.updateCrudTypes = updateCrudTypes;
package/package.json ADDED
@@ -0,0 +1,37 @@
1
+ {
2
+ "name": "@fraym/crud",
3
+ "version": "0.1.0",
4
+ "license": "UNLICENSED",
5
+ "homepage": "https://github.com/fraym/crud-nodejs",
6
+ "repository": {
7
+ "type": "git",
8
+ "url": "git+https://github.com/fraym/crud-nodejs.git"
9
+ },
10
+ "description": "nodejs client implementation for our crud service",
11
+ "scripts": {
12
+ "test": "echo \"Error: no test specified\" && exit 0",
13
+ "format": "prettier --write \"**/*.{ts,tsx,json}\"",
14
+ "lint": "prettier --check \"**/*.{ts,tsx,json}\"",
15
+ "build": "npm run clean && tsc",
16
+ "clean": "rm -rf dist",
17
+ "prepublishOnly": "npm test && npm run lint && npm run build",
18
+ "preversion": "npm run lint"
19
+ },
20
+ "files": [
21
+ "dist/**/*"
22
+ ],
23
+ "main": "dist/index.js",
24
+ "types": "dist/index.d.ts",
25
+ "dependencies": {
26
+ "@fraym/crud-proto": "^1.0.0-alpha.5",
27
+ "@grpc/grpc-js": "^1.7.2",
28
+ "uuid": "^9.0.0"
29
+ },
30
+ "devDependencies": {
31
+ "@becklyn/prettier": "^1.0.2",
32
+ "@types/uuid": "^8.3.4",
33
+ "prettier": "^2.7.1",
34
+ "typescript": "^4.8.4"
35
+ },
36
+ "prettier": "@becklyn/prettier"
37
+ }