@heliyos/heliyos-api-core 1.0.1 → 1.0.2
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/.env +1 -1
- package/README.md +206 -284
- package/package.json +1 -1
package/.env
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
|
|
1
|
+
NPM_TOKEN=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
|
package/README.md
CHANGED
|
@@ -1,400 +1,322 @@
|
|
|
1
1
|
# @heliyos/heliyos-api-core
|
|
2
2
|
|
|
3
|
-
This repository
|
|
3
|
+
This repository contains Heliyos's core API functions and middlewares. It's a private package hosted on npm.
|
|
4
4
|
|
|
5
|
-
# Table of
|
|
5
|
+
# Table of Contents
|
|
6
6
|
|
|
7
|
-
- [
|
|
8
|
-
- [
|
|
9
|
-
- [
|
|
10
|
-
- [
|
|
11
|
-
- [
|
|
12
|
-
- [
|
|
13
|
-
- [
|
|
14
|
-
- [
|
|
15
|
-
- [
|
|
16
|
-
- [
|
|
17
|
-
- [
|
|
18
|
-
- [
|
|
7
|
+
- [Installation](#installation)
|
|
8
|
+
- [Core Modules](#core-modules)
|
|
9
|
+
- [App Configuration](#app-configuration)
|
|
10
|
+
- [Authentication](#authentication)
|
|
11
|
+
- [Authorization](#authorization)
|
|
12
|
+
- [Axios HTTP Client](#axios-http-client)
|
|
13
|
+
- [Database (Knex)](#database-knex)
|
|
14
|
+
- [Validation](#validation)
|
|
15
|
+
- [Redis Client](#redis-client)
|
|
16
|
+
- [Pusher](#pusher)
|
|
17
|
+
- [SQS (Message Queue)](#sqs-message-queue)
|
|
18
|
+
- [Email Services](#email-services)
|
|
19
|
+
- [Environment Management](#environment-management)
|
|
20
|
+
- [Logging](#logging)
|
|
21
|
+
- [Development](#development)
|
|
22
|
+
- [Publishing](#publishing)
|
|
19
23
|
|
|
20
|
-
#
|
|
24
|
+
# Installation
|
|
21
25
|
|
|
22
|
-
|
|
26
|
+
1. Add `.npmrc` file in your project root:
|
|
23
27
|
|
|
24
|
-
Create a `.npmrc` file in project root and add this:
|
|
25
|
-
|
|
26
|
-
```
|
|
27
|
-
//registry.npmjs.org/:_authToken=${NPM_TOKEN}
|
|
28
|
-
```
|
|
29
|
-
|
|
30
|
-
Next, add `NPM_TOKEN` as an environment variable.
|
|
31
|
-
|
|
32
|
-
## 2 (a). Local usage
|
|
33
|
-
|
|
34
|
-
Export the `NPM_TOKEN` value to your bash environment
|
|
35
|
-
|
|
36
|
-
### Linux / Mac
|
|
37
|
-
|
|
38
|
-
Add this to your `~/.bash_profile` or `~/.zshrc`
|
|
39
|
-
|
|
40
|
-
```
|
|
41
|
-
export NPM_TOKEN="token-goes-here"
|
|
42
28
|
```
|
|
43
|
-
|
|
44
|
-
Reload bash by running
|
|
45
|
-
|
|
46
|
-
```
|
|
47
|
-
source ~/.bash_profile
|
|
29
|
+
registry.npmjs.org/:_authToken=${NPM_TOKEN}
|
|
48
30
|
```
|
|
49
31
|
|
|
50
|
-
|
|
32
|
+
2. Install the package:
|
|
51
33
|
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
```
|
|
55
|
-
setx NPM_TOKEN token-goes-here
|
|
34
|
+
```bash
|
|
35
|
+
npm install @heliyos/heliyos-api-core
|
|
56
36
|
```
|
|
57
37
|
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
## 2 (b). Remote usage: Heroku, AWS, etc
|
|
61
|
-
|
|
62
|
-
Add `NPM_TOKEN` to your env vars.
|
|
63
|
-
|
|
64
|
-
# Install
|
|
65
|
-
|
|
66
|
-
Run `npm i --save @heliyos/heliyos-api-core`
|
|
67
|
-
|
|
68
|
-
## Setup app
|
|
38
|
+
# Core Modules
|
|
69
39
|
|
|
70
|
-
|
|
40
|
+
## App Configuration
|
|
71
41
|
|
|
72
|
-
|
|
42
|
+
The core app setup provides middleware configuration and error handling.
|
|
73
43
|
|
|
74
44
|
```typescript
|
|
75
|
-
|
|
45
|
+
import { core_app } from "@heliyos/heliyos-api-core";
|
|
46
|
+
import userRoutes from "./routes/user";
|
|
76
47
|
|
|
77
|
-
|
|
78
|
-
import { heliyos_app } from "@heliyos/heliyos-api-core";
|
|
48
|
+
const routes = [userRoutes];
|
|
79
49
|
|
|
80
|
-
// Get all routes
|
|
81
|
-
import user_routes from "./routes/v1/user/user_routes";
|
|
82
|
-
|
|
83
|
-
const routes = [user_routes];
|
|
84
|
-
|
|
85
|
-
//
|
|
86
|
-
// Configure options (optional)
|
|
87
|
-
// If true, you must create a /static dir in root.
|
|
88
|
-
// If you prefer no static directory, do not specify
|
|
89
|
-
// a staticDir in options or set it to false.
|
|
90
|
-
//
|
|
91
50
|
const options = {
|
|
92
|
-
staticDir: true,
|
|
51
|
+
staticDir: true, // Enable static file serving
|
|
52
|
+
skipExternals: false, // Skip external middleware
|
|
53
|
+
skipInternals: false, // Skip internal middleware
|
|
54
|
+
excludedHeaderRegexString: "", // Regex for excluding headers
|
|
93
55
|
};
|
|
94
56
|
|
|
95
|
-
// Start app
|
|
96
57
|
const app = express();
|
|
97
|
-
|
|
98
|
-
```
|
|
99
|
-
|
|
100
|
-
Importing specific modules:
|
|
101
|
-
|
|
102
|
-
```typescript
|
|
103
|
-
import { heliyos_app, knex } from '@heliyos/heliyos-api-core';
|
|
104
|
-
|
|
105
|
-
await knex(...);
|
|
58
|
+
await core_app(app, routes, options);
|
|
106
59
|
```
|
|
107
60
|
|
|
108
|
-
##
|
|
109
|
-
|
|
110
|
-
```javascript
|
|
111
|
-
// File: app.js
|
|
61
|
+
## Authentication
|
|
112
62
|
|
|
113
|
-
|
|
114
|
-
const { heliyos_app } = require("@heliyos/heliyos-api-core");
|
|
63
|
+
Handles user authentication with support for Basic Auth, Bearer tokens, and API keys.
|
|
115
64
|
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
const routes = [user_routes];
|
|
65
|
+
```typescript
|
|
66
|
+
import { authentication } from "@heliyos/heliyos-api-core";
|
|
120
67
|
|
|
121
|
-
//
|
|
122
|
-
|
|
123
|
-
// If true, you must create a /static dir in root.
|
|
124
|
-
// If you prefer no static directory, do not specify
|
|
125
|
-
// a staticDir in options or set it to false.
|
|
126
|
-
//
|
|
127
|
-
const options = {
|
|
128
|
-
staticDir: true,
|
|
129
|
-
};
|
|
68
|
+
// Use as middleware
|
|
69
|
+
app.use(authentication);
|
|
130
70
|
|
|
131
|
-
//
|
|
132
|
-
|
|
133
|
-
|
|
71
|
+
// Required environment variables:
|
|
72
|
+
// SECRET_OF_SERVER
|
|
73
|
+
// BASE_URL_AUTH_SERVER
|
|
74
|
+
// SECRET_OF_AUTH_SERVER
|
|
134
75
|
```
|
|
135
76
|
|
|
136
|
-
|
|
77
|
+
## Authorization
|
|
137
78
|
|
|
138
|
-
|
|
139
|
-
const { validate } = require('@heliyos/heliyos-api-core');
|
|
79
|
+
Role-based access control for resources.
|
|
140
80
|
|
|
141
|
-
|
|
81
|
+
```typescript
|
|
82
|
+
import { authorize_user } from "@heliyos/heliyos-api-core";
|
|
83
|
+
|
|
84
|
+
const checkAccess = async (
|
|
85
|
+
organizationId: number,
|
|
86
|
+
userId: number,
|
|
87
|
+
action: string
|
|
88
|
+
) => {
|
|
89
|
+
const { isAllowed, userRole } = await authorize_user(
|
|
90
|
+
organizationId,
|
|
91
|
+
userId,
|
|
92
|
+
action
|
|
93
|
+
);
|
|
94
|
+
return isAllowed;
|
|
95
|
+
};
|
|
142
96
|
```
|
|
143
97
|
|
|
144
|
-
##
|
|
98
|
+
## Axios HTTP Client
|
|
145
99
|
|
|
146
|
-
|
|
100
|
+
Pre-configured Axios instances for internal services.
|
|
147
101
|
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
`heliyos_app` will provide server with external and internal middleware.
|
|
151
|
-
|
|
152
|
-
### External middleware
|
|
102
|
+
```typescript
|
|
103
|
+
import { axios } from "@heliyos/heliyos-api-core";
|
|
153
104
|
|
|
154
|
-
|
|
105
|
+
// Available instances:
|
|
106
|
+
await axios.auth_server.get("/endpoint");
|
|
107
|
+
await axios.billing_server.post("/endpoint", data);
|
|
108
|
+
await axios.event_server.put("/endpoint", data);
|
|
109
|
+
await axios.notification_server.delete("/endpoint");
|
|
110
|
+
await axios.user_server.patch("/endpoint", data);
|
|
155
111
|
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
app.use(express_validator());
|
|
163
|
-
app.disable("x-powered-by");
|
|
112
|
+
// Required environment variables for each server:
|
|
113
|
+
// BASE_URL_AUTH_SERVER + SECRET_OF_AUTH_SERVER
|
|
114
|
+
// BASE_URL_BILLING_SERVER + SECRET_OF_BILLING_SERVER
|
|
115
|
+
// BASE_URL_EVENT_API_SERVER + SECRET_OF_EVENT_API_SERVER
|
|
116
|
+
// BASE_URL_NOTIFICATION_SERVER + SECRET_OF_NOTIFICATION_SERVER
|
|
117
|
+
// BASE_URL_USERS_SERVER + SECRET_OF_USERS_SERVER
|
|
164
118
|
```
|
|
165
119
|
|
|
166
|
-
|
|
120
|
+
## Database (Knex)
|
|
167
121
|
|
|
168
|
-
|
|
122
|
+
Database connection and query builder with pagination support.
|
|
123
|
+
|
|
124
|
+
```typescript
|
|
125
|
+
import { knex } from "@heliyos/heliyos-api-core";
|
|
169
126
|
|
|
170
|
-
|
|
127
|
+
// Regular queries
|
|
128
|
+
const users = await knex("users").where({ active: true });
|
|
171
129
|
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
130
|
+
// With pagination
|
|
131
|
+
const results = await knex("users")
|
|
132
|
+
.where({ active: true })
|
|
133
|
+
.paginate(page, limit);
|
|
175
134
|
|
|
176
|
-
|
|
135
|
+
// Results format:
|
|
136
|
+
// {
|
|
137
|
+
// data: Array<T>,
|
|
138
|
+
// meta: {
|
|
139
|
+
// page: number,
|
|
140
|
+
// limit: number,
|
|
141
|
+
// offset: number,
|
|
142
|
+
// count: number
|
|
143
|
+
// }
|
|
144
|
+
// }
|
|
177
145
|
|
|
178
|
-
|
|
179
|
-
|
|
146
|
+
// Required environment variables:
|
|
147
|
+
// DATABASE_URL
|
|
180
148
|
```
|
|
181
149
|
|
|
182
|
-
|
|
150
|
+
## Validation
|
|
183
151
|
|
|
184
|
-
|
|
152
|
+
Input validation using Joi.
|
|
185
153
|
|
|
186
|
-
|
|
154
|
+
```typescript
|
|
155
|
+
import { validate, joiObject } from "@heliyos/heliyos-api-core";
|
|
187
156
|
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
157
|
+
const schema = (joi) =>
|
|
158
|
+
joi.object({
|
|
159
|
+
name: joi.string().required(),
|
|
160
|
+
email: joi.string().email().required(),
|
|
161
|
+
});
|
|
192
162
|
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
skipExternals?: boolean; // if true external middleware will not be applied
|
|
196
|
-
skipInternals?: boolean; // if true internal middleware will not be applied
|
|
197
|
-
}
|
|
198
|
-
```
|
|
163
|
+
// Validate input
|
|
164
|
+
validate(inputData, schema);
|
|
199
165
|
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
environment variables for certain modules.
|
|
205
|
-
|
|
206
|
-
```javascript
|
|
207
|
-
export { authentication } from "./authentication";
|
|
208
|
-
export { heliyos_app } from "./app";
|
|
209
|
-
export { heliyos_axios as axios } from "./axios";
|
|
210
|
-
export { heliyos_knex as knex } from "./knex";
|
|
211
|
-
export { validate } from "./validate";
|
|
212
|
-
export { auth_policy } from "./static/auth_policy_file";
|
|
213
|
-
export { database_config } from "./knexfile";
|
|
214
|
-
export { authorize_user } from "./authorization";
|
|
215
|
-
export { send_email } from "./sendgrid_email_service";
|
|
216
|
-
export { SQSUtil } from "./sqs";
|
|
166
|
+
// Using joiObject directly
|
|
167
|
+
const customSchema = joiObject.object({
|
|
168
|
+
// schema definition
|
|
169
|
+
});
|
|
217
170
|
```
|
|
218
171
|
|
|
219
|
-
##
|
|
220
|
-
|
|
221
|
-
You can use `.paginate` as a chain method with knex:
|
|
172
|
+
## Redis Client
|
|
222
173
|
|
|
223
|
-
|
|
174
|
+
Redis connection management.
|
|
224
175
|
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
```javascript
|
|
228
|
-
const { knex } = require("@heliyos/heliyos-api-core");
|
|
229
|
-
|
|
230
|
-
const logs = await knex("user.user_log")
|
|
231
|
-
.where({ store_id })
|
|
232
|
-
.orderBy("updated_at", "desc")
|
|
233
|
-
.paginate(+page, +limit);
|
|
176
|
+
```typescript
|
|
177
|
+
import { createRedisClient } from "@heliyos/heliyos-api-core";
|
|
234
178
|
|
|
235
|
-
|
|
236
|
-
|
|
179
|
+
const redisClient = createRedisClient({
|
|
180
|
+
url: "redis://localhost:6379",
|
|
181
|
+
});
|
|
237
182
|
```
|
|
238
183
|
|
|
239
|
-
|
|
184
|
+
## Pusher
|
|
240
185
|
|
|
241
|
-
|
|
186
|
+
Real-time event broadcasting.
|
|
242
187
|
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
const logs = await (
|
|
246
|
-
knex('user.user_log')
|
|
247
|
-
.where({ store_id })
|
|
248
|
-
.orderBy('updated_at', 'desc') as any
|
|
249
|
-
)
|
|
250
|
-
.paginate(+page, +limit);
|
|
188
|
+
```typescript
|
|
189
|
+
import { pusherTrigger, pusherTriggerBatch } from "@heliyos/heliyos-api-core";
|
|
251
190
|
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
```
|
|
191
|
+
// Single event
|
|
192
|
+
await pusherTrigger("channel-name", "event-name", { data: "payload" });
|
|
255
193
|
|
|
256
|
-
|
|
194
|
+
// Batch events
|
|
195
|
+
const batch = [
|
|
196
|
+
{ channel: "channel1", name: "event1", data: {} },
|
|
197
|
+
{ channel: "channel2", name: "event2", data: {} },
|
|
198
|
+
];
|
|
199
|
+
await pusherTriggerBatch(batch);
|
|
257
200
|
|
|
258
|
-
|
|
201
|
+
// Required environment variables:
|
|
202
|
+
// PUSHER_APP_ID
|
|
203
|
+
// PUSHER_KEY
|
|
204
|
+
// PUSHER_SECRET
|
|
205
|
+
// PUSHER_CLUSTER
|
|
206
|
+
```
|
|
259
207
|
|
|
260
|
-
|
|
261
|
-
const schema_gen = (joi) => {
|
|
262
|
-
return joi.object({
|
|
263
|
-
property_id: joi.number().required(),
|
|
264
|
-
name: joi.string().required(),
|
|
265
|
-
});
|
|
266
|
-
};
|
|
208
|
+
## SQS (Message Queue)
|
|
267
209
|
|
|
268
|
-
|
|
269
|
-
property_id: container.input.property_id,
|
|
270
|
-
name: container.input.body.name,
|
|
271
|
-
};
|
|
210
|
+
AWS SQS integration for message queuing.
|
|
272
211
|
|
|
273
|
-
|
|
274
|
-
|
|
212
|
+
```typescript
|
|
213
|
+
import { SQSUtil } from "@heliyos/heliyos-api-core";
|
|
275
214
|
|
|
276
|
-
|
|
215
|
+
const sqs = new SQSUtil();
|
|
277
216
|
|
|
278
|
-
|
|
217
|
+
// Write message
|
|
218
|
+
await sqs.write(
|
|
219
|
+
{
|
|
220
|
+
resource: "users",
|
|
221
|
+
type: "INSERT",
|
|
222
|
+
objectId: { name: "user_id", value: "123" },
|
|
223
|
+
data: { name: "John" },
|
|
224
|
+
},
|
|
225
|
+
"queue-url",
|
|
226
|
+
"optional-group-id"
|
|
227
|
+
);
|
|
279
228
|
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
process.env.SECRET_OF_SERVER;
|
|
229
|
+
// Read message
|
|
230
|
+
const messages = await sqs.read("queue-url");
|
|
283
231
|
|
|
284
|
-
//
|
|
285
|
-
|
|
286
|
-
process.env.SECRET_OF_AUTH_SERVER;
|
|
232
|
+
// Delete message
|
|
233
|
+
await sqs.delete(receiptHandle, "queue-url");
|
|
287
234
|
```
|
|
288
235
|
|
|
289
|
-
##
|
|
236
|
+
## Email Services
|
|
290
237
|
|
|
291
|
-
|
|
238
|
+
Email sending with template support using Resend.
|
|
292
239
|
|
|
293
|
-
|
|
240
|
+
```typescript
|
|
241
|
+
import { resendSendEmail } from "@heliyos/heliyos-api-core";
|
|
294
242
|
|
|
295
|
-
|
|
243
|
+
await resendSendEmail(
|
|
244
|
+
["recipient@example.com"],
|
|
245
|
+
"template-id",
|
|
246
|
+
{ name: "John" },
|
|
247
|
+
"Email Subject"
|
|
248
|
+
);
|
|
296
249
|
|
|
297
|
-
|
|
250
|
+
// Required environment variables:
|
|
251
|
+
// RESEND_API_KEY
|
|
252
|
+
// RESEND_FROM_RECIPIENT
|
|
253
|
+
```
|
|
298
254
|
|
|
299
|
-
|
|
255
|
+
## Environment Management
|
|
300
256
|
|
|
301
|
-
|
|
302
|
-
const queueURL = 'https://sqs.us-east-1.amazonaws.com/123456789012/MyQueue';
|
|
303
|
-
sqs.write({
|
|
304
|
-
resource: 'users',
|
|
305
|
-
type: 'INSERT',
|
|
306
|
-
objectId: { name: "user_uuid", value: "1234567890453" }
|
|
307
|
-
data: { name: "John", email: 'promise@cartloop.io' }
|
|
308
|
-
}, queueURL);
|
|
257
|
+
Load environment variables from AWS Secrets Manager.
|
|
309
258
|
|
|
310
|
-
|
|
311
|
-
|
|
259
|
+
```typescript
|
|
260
|
+
import { loadAppEnv } from "@heliyos/heliyos-api-core";
|
|
312
261
|
|
|
313
|
-
|
|
314
|
-
// event is an import("aws-lambda").SQSEvent
|
|
315
|
-
const eventRecord = event.Records[0]
|
|
316
|
-
const { receiptHandle } = eventRecord
|
|
317
|
-
sqs.delete(receiptHandle, queueURL);
|
|
262
|
+
const env = await loadAppEnv();
|
|
318
263
|
|
|
264
|
+
// Required environment variables:
|
|
265
|
+
// ENV_SECRET_NAME
|
|
319
266
|
```
|
|
320
267
|
|
|
321
|
-
##
|
|
322
|
-
|
|
323
|
-
You'll need to include env vars for the axios instances you plan to use.
|
|
324
|
-
|
|
325
|
-
```javascript
|
|
326
|
-
// Auth server
|
|
327
|
-
process.env.BASE_URL_AUTH_SERVER;
|
|
328
|
-
process.env.SECRET_OF_AUTH_SERVER;
|
|
268
|
+
## Logging
|
|
329
269
|
|
|
330
|
-
|
|
331
|
-
process.env.BASE_URL_BILLING_SERVER;
|
|
332
|
-
process.env.SECRET_OF_BILLING_SERVER;
|
|
270
|
+
Structured logging with Winston.
|
|
333
271
|
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
process.env.SECRET_OF_EVENT_API_SERVER;
|
|
337
|
-
|
|
338
|
-
// Notification server
|
|
339
|
-
process.env.BASE_URL_NOTIFICATION_SERVER;
|
|
340
|
-
process.env.SECRET_OF_NOTIFICATION_SERVER;
|
|
272
|
+
```typescript
|
|
273
|
+
import { logger } from "@heliyos/heliyos-api-core";
|
|
341
274
|
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
275
|
+
logger.info("Message", { meta: "data" });
|
|
276
|
+
logger.error("Error occurred", { error });
|
|
277
|
+
logger.warn("Warning message");
|
|
345
278
|
```
|
|
346
279
|
|
|
347
|
-
|
|
280
|
+
# Development
|
|
348
281
|
|
|
349
|
-
To test
|
|
282
|
+
To test changes locally:
|
|
350
283
|
|
|
351
|
-
1.
|
|
352
|
-
the built artifcats in the dist folder.
|
|
284
|
+
1. Build the package:
|
|
353
285
|
|
|
354
|
-
```
|
|
286
|
+
```bash
|
|
355
287
|
npm run build
|
|
356
288
|
```
|
|
357
289
|
|
|
358
|
-
2.
|
|
290
|
+
2. Create a tarball:
|
|
359
291
|
|
|
360
|
-
```
|
|
292
|
+
```bash
|
|
361
293
|
npm pack --pack-destination .
|
|
362
294
|
```
|
|
363
295
|
|
|
364
|
-
3. Install
|
|
296
|
+
3. Install in your project:
|
|
365
297
|
|
|
366
|
-
```
|
|
367
|
-
npm install
|
|
298
|
+
```bash
|
|
299
|
+
npm install /path/to/heliyos-api-core/heliyos-ai-heliyos-api-core-1.0.5.tgz
|
|
368
300
|
```
|
|
369
301
|
|
|
370
|
-
|
|
302
|
+
# Publishing
|
|
371
303
|
|
|
372
|
-
|
|
304
|
+
To publish updates (admin only):
|
|
373
305
|
|
|
374
|
-
|
|
306
|
+
1. Update version in package.json
|
|
375
307
|
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
1. Update the version of the npm package in package.json and run the following to update the lock file
|
|
379
|
-
|
|
380
|
-
```
|
|
381
|
-
npm i
|
|
308
|
+
```bash
|
|
309
|
+
npm version patch|minor|major
|
|
382
310
|
```
|
|
383
311
|
|
|
384
312
|
2. Build the project
|
|
385
313
|
|
|
386
|
-
```
|
|
314
|
+
```bash
|
|
387
315
|
npm run build
|
|
388
316
|
```
|
|
389
317
|
|
|
390
|
-
|
|
318
|
+
3. Publish
|
|
391
319
|
|
|
392
|
-
```
|
|
393
|
-
npm login
|
|
394
|
-
```
|
|
395
|
-
|
|
396
|
-
3. Publish the built project
|
|
397
|
-
|
|
398
|
-
```
|
|
320
|
+
```bash
|
|
399
321
|
npm publish
|
|
400
322
|
```
|