@chargebee/chargebee-apps-libs 0.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.
Files changed (49) hide show
  1. package/LICENSE +24 -0
  2. package/README.md +270 -0
  3. package/SECURITY.md +8 -0
  4. package/config/README.md +83 -0
  5. package/config/allowed-modules.json +24 -0
  6. package/dist/config/config-loader.d.ts +24 -0
  7. package/dist/config/config-loader.js +95 -0
  8. package/dist/index.d.ts +4 -0
  9. package/dist/index.js +21 -0
  10. package/dist/libs/port-service.d.ts +18 -0
  11. package/dist/libs/port-service.js +27 -0
  12. package/dist/logger/cb-public-logger.d.ts +59 -0
  13. package/dist/logger/cb-public-logger.js +158 -0
  14. package/dist/sandbox/public-sandbox-wrapper.d.ts +41 -0
  15. package/dist/sandbox/public-sandbox-wrapper.js +208 -0
  16. package/package.json +44 -0
  17. package/templates/serverless-node-starter-app/.env +4 -0
  18. package/templates/serverless-node-starter-app/README.md +290 -0
  19. package/templates/serverless-node-starter-app/handler/handler.js +34 -0
  20. package/templates/serverless-node-starter-app/jsconfig.json +35 -0
  21. package/templates/serverless-node-starter-app/manifest.json +15 -0
  22. package/templates/serverless-node-starter-app/test_data/customer_created.json +51 -0
  23. package/templates/serverless-node-starter-app/test_data/invoice_generated.json +112 -0
  24. package/templates/serverless-node-starter-app/test_data/subscription_created.json +173 -0
  25. package/templates/serverless-node-starter-app/types/types.d.ts +45 -0
  26. package/templates/serverless-node-starter-app-with-iparams/.env +4 -0
  27. package/templates/serverless-node-starter-app-with-iparams/README.md +717 -0
  28. package/templates/serverless-node-starter-app-with-iparams/handler/handler.js +39 -0
  29. package/templates/serverless-node-starter-app-with-iparams/iparams.json +41 -0
  30. package/templates/serverless-node-starter-app-with-iparams/iparams.local.json +9 -0
  31. package/templates/serverless-node-starter-app-with-iparams/jsconfig.json +35 -0
  32. package/templates/serverless-node-starter-app-with-iparams/manifest.json +15 -0
  33. package/templates/serverless-node-starter-app-with-iparams/test_data/customer_created.json +51 -0
  34. package/templates/serverless-node-starter-app-with-iparams/test_data/invoice_generated.json +112 -0
  35. package/templates/serverless-node-starter-app-with-iparams/test_data/subscription_created.json +173 -0
  36. package/templates/serverless-node-starter-app-with-iparams/types/types.d.ts +63 -0
  37. package/ui/README.md +118 -0
  38. package/ui/web/assets/css/main.css +1121 -0
  39. package/ui/web/assets/images/Chargebee-logo.png +0 -0
  40. package/ui/web/assets/js/main.js +61 -0
  41. package/ui/web/assets/js/modules/api.js +97 -0
  42. package/ui/web/assets/js/modules/constants.js +33 -0
  43. package/ui/web/assets/js/modules/editors.js +41 -0
  44. package/ui/web/assets/js/modules/events.js +195 -0
  45. package/ui/web/assets/js/modules/form-utils.js +70 -0
  46. package/ui/web/assets/js/modules/iparams-inputs.js +495 -0
  47. package/ui/web/assets/js/modules/iparams.js +82 -0
  48. package/ui/web/assets/js/modules/ui-utils.js +87 -0
  49. package/ui/web/index.html +164 -0
@@ -0,0 +1,290 @@
1
+ # Serverless Node.js App Template
2
+
3
+ This is a serverless Node.js application template that demonstrates how to build and test serverless functions with event-driven architecture. This template provides a foundation for creating scalable serverless applications with built-in testing capabilities.
4
+
5
+ ## Features
6
+
7
+ - **Event-Driven Architecture**: Configure multiple event handlers in `manifest.json`
8
+ - **Handler Functions**: Implement your business logic in `handler.js`
9
+ - **Test Data**: Sample event data for local development and testing
10
+ - **Local Testing UI**: Interactive web interface to test your handlers
11
+ - **Logging**: Built-in logging system for debugging and monitoring
12
+
13
+ ## How It Works
14
+
15
+ 1. **Event Configuration**: The `manifest.json` file maps event types to their corresponding handler functions
16
+ 2. **Handler Implementation**: Each event type has its handler function in `handler.js`
17
+ 3. **Test Data**: Sample JSON files in `test_data/` folder match your event names (e.g., `onCustomerCreate.json`)
18
+ 4. **Local Testing**: Use the CLI tool to start a local testing server with a web UI
19
+ 5. **Interactive Testing**: Select event types from the dropdown and click "Test Data" to execute handlers
20
+ 6. **Real-time Logs**: View execution logs directly in your terminal
21
+
22
+ ## Quick Start
23
+
24
+ 1. **Create your app**: `chargebee-apps create <app_directory>`
25
+ 2. **Navigate to app**: `cd <app_directory>`
26
+ 3. **Configure API keys** (optional): Edit `.env` file and replace placeholder values with your Chargebee API keys
27
+ 4. **Start local server**: `chargebee-apps run <app_directory>`
28
+ 5. **Open browser**: Visit `http://localhost:15000`
29
+ 6. **Test handlers**: Select an event type and click "Test Data"
30
+ 7. **View logs**: Check your terminal for execution output
31
+ 8. **Package your app**: `chargebee-apps package <app_directory>`
32
+
33
+ ## Project Structure
34
+
35
+ ```
36
+ ├── handler/handler.js # Main serverless function handler
37
+ ├── test_data/ # Test data directory
38
+ ├── types/types.d.ts # Recognised types that can be used as JSDoc inside handler function
39
+ ├── .env # Environment variables (API keys)
40
+ ├── jsconfig.json # JS config for dev
41
+ ├── manifest.json # Project configuration
42
+ └── README.md # Read me file
43
+ ```
44
+
45
+ ## Configuration
46
+
47
+ ### Manifest.json
48
+
49
+ The `manifest.json` file is the core configuration file for your serverless application. It defines:
50
+
51
+ 1. **Event Handlers**: Maps Chargebee webhook events to your handler functions
52
+ 2. **Application Metadata**: Basic information about your application
53
+ 3. **Dependencies**: Custom npm packages your application requires
54
+
55
+ #### Basic Structure
56
+
57
+ ```json
58
+ {
59
+ "name": "my-app",
60
+ "version": "1.0.0",
61
+ "description": "A custom app",
62
+ "events": {
63
+ "customer_created": {
64
+ "handler": "customerCreateHandler"
65
+ },
66
+ "subscription_created": {
67
+ "handler": "subscriptionCreatedHandler"
68
+ },
69
+ "invoice_generated": {
70
+ "handler": "invoiceGeneratedHandler"
71
+ }
72
+ },
73
+ "dependencies": {
74
+ "lodash": "^4.17.21",
75
+ "axios": "^1.6.0"
76
+ }
77
+ }
78
+ ```
79
+
80
+ #### Event Handler Configuration
81
+
82
+ Each event in the `events` object maps a Chargebee webhook event to a handler function:
83
+
84
+ ```json
85
+ {
86
+ "events": {
87
+ "customer_created": {
88
+ "handler": "customerCreateHandler"
89
+ }
90
+ }
91
+ }
92
+ ```
93
+
94
+ The handler function must be exported from `handler/handler.js`. Each handler receives a single `payload` argument; use `payload.event` to access the event data:
95
+
96
+ ```javascript
97
+ // handler/handler.js
98
+ module.exports = {
99
+ customerCreateHandler: function(/** @type {import('../types/types.d.ts').HandlerPayload} */payload) {
100
+ // Your business logic here
101
+ console.log('Customer created:', payload.event.content.customer.email);
102
+
103
+ // Example: Send welcome email
104
+ const customerEmail = payload.event.content.customer.email;
105
+ const customerName = payload.event.content.customer.first_name;
106
+
107
+ // You can use custom dependencies here
108
+ const moment = require('moment');
109
+ const welcomeMessage = `Welcome ${customerName}! You joined on ${moment().format('MMMM Do YYYY')}`;
110
+
111
+ console.log(welcomeMessage);
112
+ }
113
+ };
114
+ ```
115
+
116
+ #### Custom Dependencies
117
+
118
+ You can add custom npm packages to your application by including them in the `dependencies` section:
119
+
120
+ ```json
121
+ {
122
+ "dependencies": {
123
+ "lodash": "^4.17.21",
124
+ "axios": "^1.6.0",
125
+ "uuid": "^9.0.0"
126
+ }
127
+ }
128
+ ```
129
+
130
+ Then use them in your handler functions:
131
+
132
+ ```javascript
133
+ // handler/handler.js
134
+ const _ = require('lodash');
135
+ const axios = require('axios');
136
+ const moment = require('moment');
137
+ const { v4: uuidv4 } = require('uuid');
138
+
139
+ module.exports = {
140
+ customerCreateHandler: function(/** @type {import('../types/types.d.ts').HandlerPayload} */payload) {
141
+ // Use lodash for data manipulation
142
+ const customerData = _.pick(payload.event.content.customer, ['email', 'first_name', 'last_name']);
143
+
144
+ // Generate unique ID
145
+ const customerId = uuidv4();
146
+
147
+ // Make HTTP requests
148
+ axios.post('https://api.example.com/customers', {
149
+ id: customerId,
150
+ ...customerData,
151
+ created_at: moment().toISOString()
152
+ }).then(response => {
153
+ console.log('Customer synced to external system:', response.data);
154
+ }).catch(error => {
155
+ console.error('Failed to sync customer:', error.message);
156
+ });
157
+ },
158
+
159
+ subscriptionCreatedHandler: function(/** @type {import('../types/types.d.ts').HandlerPayload} */payload) {
160
+ // Use moment for date formatting
161
+ const subscriptionDate = moment(payload.event.content.subscription.created_at * 1000);
162
+ const formattedDate = subscriptionDate.format('MMMM Do YYYY, h:mm:ss a');
163
+
164
+ console.log(`New subscription created on ${formattedDate}`);
165
+
166
+ // Use lodash for data validation
167
+ const requiredFields = ['id', 'customer_id', 'plan_id'];
168
+ const missingFields = _.difference(requiredFields, Object.keys(payload.event.content.subscription));
169
+
170
+ if (missingFields.length > 0) {
171
+ console.warn('Missing subscription fields:', missingFields);
172
+ }
173
+ }
174
+ };
175
+ ```
176
+
177
+ #### Supported Event Types
178
+ Chargebee Apps supports all the event types that are provided in the Chargebee's [documentation](https://apidocs.chargebee.com/docs/api/events#event_types).
179
+
180
+ ### Environment Variables
181
+
182
+ The CLI exposes **only these three** variables via `process.env`; no other environment variables are available to your handlers:
183
+
184
+ | Variable | Description |
185
+ |----------|-------------|
186
+ | `MKPLC_CB_READ_ONLY_API` | Chargebee read-only API key |
187
+ | `MKPLC_CB_READ_WRITE_API` | Chargebee read-write API key |
188
+ | `MKPLC_SITE_DOMAIN` | Chargebee site domain |
189
+
190
+ - **Production:** The system provides these values at runtime. You do not configure them in production.
191
+ - **Local development:** You must provide these values in the `.env` file so your handlers can run locally.
192
+
193
+ #### Setting up .env for local development
194
+
195
+ 1. **Open the `.env` file** in your project root
196
+ 2. **Replace the placeholder values** with your actual Chargebee API keys:
197
+
198
+ ```env
199
+ # Replace these with your actual Chargebee API keys
200
+ MKPLC_CB_READ_ONLY_API=your_read_only_api_key_here
201
+ MKPLC_CB_READ_WRITE_API=your_read_write_api_key_here
202
+ MKPLC_SITE_DOMAIN=yousite123
203
+ ```
204
+
205
+ #### Using these variables in your handlers
206
+
207
+ Access them through the `process.env` object in your handler functions:
208
+
209
+ ```javascript
210
+ // handler/handler.js
211
+ module.exports = {
212
+ customerCreateHandler: async function(/** @type {import('../types/types.d.ts').HandlerPayload} */payload) {
213
+ // Access your API keys
214
+ const readOnlyApiKey = process.env.MKPLC_CB_READ_ONLY_API;
215
+ const readWriteApiKey = process.env.MKPLC_CB_READ_WRITE_API;
216
+
217
+ if (!readOnlyApiKey || !readWriteApiKey) {
218
+ console.error('API keys not configured. Please check your .env file.');
219
+ return;
220
+ }
221
+
222
+ // Use the API keys for Chargebee API calls
223
+ console.log('Using API keys for Chargebee integration');
224
+
225
+ const Chargebee = require('chargebee');
226
+ const chargebee = new Chargebee({
227
+ site: process.env.MKPLC_SITE_DOMAIN,
228
+ apiKey: process.env.MKPLC_CB_READ_ONLY_API
229
+ });
230
+
231
+ const result = await chargebee.customer.retrieve(payload.event.content.customer.id);
232
+ console.log(result.customer);
233
+ }
234
+ };
235
+ ```
236
+
237
+ #### Security Notes
238
+
239
+ - **Never commit real API keys** to version control
240
+ - The `.env` file in this template contains placeholder values
241
+ - Replace the placeholder values with your actual API keys before testing
242
+ - Keep your API keys secure and don't share them publicly
243
+
244
+ ## Local Testing
245
+
246
+ Use the CLI tool to test your functions locally with an interactive web interface:
247
+
248
+ ```bash
249
+ # Start the testing server on a specific port
250
+ chargebee-apps run <app_directory> --port <port>
251
+ # Example:
252
+ chargebee-apps run ./sample_app_v0 --port 16000
253
+
254
+ # Open http://localhost:16000 in your browser
255
+ # Select event types from the dropdown and click "Test Data" to execute handlers
256
+ # View real-time logs in your terminal
257
+ ```
258
+
259
+ ## Testing
260
+
261
+ Test data files are located in the `test_data/` directory. Each file is named after its corresponding event type (e.g., `customer_created.json`, `customer_updated.json`). These JSON files contain sample event data that you can use to test your handlers during local development.
262
+
263
+ The test data structure should match the expected input format for your handler functions. You can modify these files to test different scenarios or add new test data files for additional event types.
264
+
265
+ ## Packaging
266
+
267
+ The package command bundles your serverless application into a zip file for deployment.
268
+
269
+ ### Basic Usage
270
+
271
+ ```bash
272
+ # Package with default name (app directory name)
273
+ chargebee-apps package <app_directory>
274
+
275
+ # Package with custom name
276
+ chargebee-apps package <app_directory> --name my-app-v1.0.0
277
+ ```
278
+
279
+ ### Examples
280
+
281
+ ```bash
282
+ # Package current directory
283
+ chargebee-apps package .
284
+
285
+ # Package specific directory
286
+ chargebee-apps package ./my-app
287
+
288
+ # Package with versioned name
289
+ chargebee-apps package ./my-app --name my-app-v1.0.0
290
+ ```
@@ -0,0 +1,34 @@
1
+ /**
2
+ * Serverless function handlers
3
+ * Each handler receives a single payload argument with payload.event
4
+ */
5
+ module.exports = {
6
+
7
+ /**
8
+ * Handles customer_created events
9
+ * @param {import('../types/types.d.ts').HandlerPayload} payload
10
+ */
11
+ customerCreateHandler: function(/** @type {import('../types/types.d.ts').HandlerPayload} */payload) {
12
+ console.log('Processing customer_created event');
13
+ console.log('Customer created for email: ', payload.event.content.customer.email);
14
+ },
15
+
16
+ /**
17
+ * Handles subscription_created events
18
+ * @param {import('../types/types.d.ts').HandlerPayload} payload
19
+ */
20
+ subscriptionCreatedHandler: function(/** @type {import('../types/types.d.ts').HandlerPayload} */payload) {
21
+ console.log('Processing subscription_created event');
22
+ console.log('Subscription created for email: ', payload.event.content.customer.email);
23
+ },
24
+
25
+ /**
26
+ * Handles invoice_generated events
27
+ * @param {import('../types/types.d.ts').HandlerPayload} payload
28
+ */
29
+ invoiceGeneratedHandler: function(/** @type {import('../types/types.d.ts').HandlerPayload} */payload) {
30
+ console.log('Processing invoice_generated event');
31
+ console.log('Invoice status: ', payload.event.content.invoice.status);
32
+ }
33
+
34
+ };
@@ -0,0 +1,35 @@
1
+ {
2
+ "compilerOptions": {
3
+ "target": "ES2020",
4
+ "module": "commonjs",
5
+ "allowSyntheticDefaultImports": true,
6
+ "esModuleInterop": true,
7
+ "allowJs": true,
8
+ "checkJs": true,
9
+ "resolveJsonModule": true,
10
+ "strict": false,
11
+ "noImplicitAny": false,
12
+ "noImplicitReturns": true,
13
+ "noImplicitThis": false,
14
+ "noUnusedLocals": true,
15
+ "noUnusedParameters": false,
16
+ "baseUrl": ".",
17
+ "paths": {
18
+ "@/*": ["./*"],
19
+ "@handler/*": ["./handler/*"],
20
+ "@types/*": ["./types/*"],
21
+ "@test_data/*": ["./test_data/*"]
22
+ },
23
+ "typeRoots": ["./types", "./node_modules/@types"]
24
+ },
25
+ "include": [
26
+ "**/*.js",
27
+ "**/*.d.ts",
28
+ "**/*.json"
29
+ ],
30
+ "exclude": [
31
+ "node_modules",
32
+ "dist",
33
+ "*.min.js"
34
+ ]
35
+ }
@@ -0,0 +1,15 @@
1
+ {
2
+ "name": "<your-app-name>",
3
+ "description": "<your-app-description>",
4
+ "events": {
5
+ "customer_created": {
6
+ "handler": "customerCreateHandler"
7
+ },
8
+ "subscription_created": {
9
+ "handler": "subscriptionCreatedHandler"
10
+ },
11
+ "invoice_generated": {
12
+ "handler": "invoiceGeneratedHandler"
13
+ }
14
+ }
15
+ }
@@ -0,0 +1,51 @@
1
+ {
2
+ "api_version": "v2",
3
+ "content": {
4
+ "customer": {
5
+ "allow_direct_debit": false,
6
+ "auto_collection": "on",
7
+ "billing_address": {
8
+ "country": "US",
9
+ "object": "billing_address",
10
+ "validation_status": "not_validated"
11
+ },
12
+ "card_status": "no_card",
13
+ "channel": "web",
14
+ "company": "Example",
15
+ "created_at": 1755783294,
16
+ "created_from_ip": "54.88.235.200",
17
+ "deleted": false,
18
+ "email": "johndoe@example.com",
19
+ "excess_payments": 0,
20
+ "first_name": "John",
21
+ "id": "AzqUAXUuVzllT3Zr",
22
+ "last_name": "Doe",
23
+ "mrr": 0,
24
+ "net_term_days": 0,
25
+ "object": "customer",
26
+ "phone": "123 456 7890",
27
+ "pii_cleared": "active",
28
+ "preferred_currency_code": "USD",
29
+ "promotional_credits": 0,
30
+ "refundable_credits": 0,
31
+ "resource_version": 1755783294193,
32
+ "taxability": "taxable",
33
+ "unbilled_charges": 0,
34
+ "updated_at": 1755783294
35
+ }
36
+ },
37
+ "event_type": "customer_created",
38
+ "id": "ev_AzqUAXUuVzlmf3Zs",
39
+ "object": "event",
40
+ "occurred_at": 1755783294,
41
+ "source": "admin_console",
42
+ "user": "foo@bar.com",
43
+ "webhook_status": "scheduled",
44
+ "webhooks": [
45
+ {
46
+ "id": "whv2_169zTyUkn2tgg2fOQ",
47
+ "object": "webhook",
48
+ "webhook_status": "scheduled"
49
+ }
50
+ ]
51
+ }
@@ -0,0 +1,112 @@
1
+ {
2
+ "api_version": "v2",
3
+ "content": {
4
+ "invoice": {
5
+ "adjustment_credit_notes": [],
6
+ "amount_adjusted": 0,
7
+ "amount_due": 0,
8
+ "amount_paid": 0,
9
+ "amount_to_collect": 0,
10
+ "applied_credits": [],
11
+ "base_currency_code": "USD",
12
+ "billing_address": {
13
+ "company": "Example",
14
+ "country": "US",
15
+ "first_name": "John",
16
+ "last_name": "Doe",
17
+ "object": "billing_address",
18
+ "validation_status": "not_validated"
19
+ },
20
+ "channel": "web",
21
+ "credits_applied": 0,
22
+ "currency_code": "USD",
23
+ "customer_id": "AzqUAXUuVzllT3Zr",
24
+ "date": 1755783502,
25
+ "deleted": false,
26
+ "due_date": 1755783502,
27
+ "dunning_attempts": [],
28
+ "exchange_rate": 1,
29
+ "first_invoice": true,
30
+ "generated_at": 1755783502,
31
+ "has_advance_charges": false,
32
+ "id": "93",
33
+ "is_gifted": false,
34
+ "issued_credit_notes": [],
35
+ "line_items": [
36
+ {
37
+ "amount": 0,
38
+ "customer_id": "AzqUAXUuVzllT3Zr",
39
+ "date_from": 1755783502,
40
+ "date_to": 1758461902,
41
+ "description": "Plan-Free",
42
+ "discount_amount": 0,
43
+ "entity_id": "cbdemo_free",
44
+ "entity_type": "plan",
45
+ "id": "li_AzZTN3UuW0e4m3il",
46
+ "is_taxed": false,
47
+ "item_level_discount_amount": 0,
48
+ "object": "line_item",
49
+ "pricing_model": "flat_fee",
50
+ "quantity": 1,
51
+ "subscription_id": "AzZTN3UuW0e4B3ij",
52
+ "tax_amount": 0,
53
+ "tax_exempt_reason": "tax_not_configured",
54
+ "unit_amount": 0
55
+ }
56
+ ],
57
+ "linked_orders": [],
58
+ "linked_payments": [],
59
+ "net_term_days": 0,
60
+ "new_sales_amount": 0,
61
+ "object": "invoice",
62
+ "paid_at": 1755783502,
63
+ "price_type": "tax_exclusive",
64
+ "recurring": true,
65
+ "resource_version": 1755783502991,
66
+ "round_off_amount": 0,
67
+ "site_details_at_creation": {
68
+ "organization_address": {
69
+ "city": "Hyderabad",
70
+ "country_code": "IN",
71
+ "line1": "asfdgdhfjgfgf",
72
+ "organization_name": "Chargebee",
73
+ "phone": "01234565543",
74
+ "state": "Andaman and Nicobar Islands",
75
+ "state_code": "AN",
76
+ "zip": "500028"
77
+ },
78
+ "timezone": "Universal"
79
+ },
80
+ "status": "paid",
81
+ "sub_total": 0,
82
+ "subscription_id": "AzZTN3UuW0e4B3ij",
83
+ "tax": 0,
84
+ "tax_origin": {
85
+ "country": "IN"
86
+ },
87
+ "term_finalized": true,
88
+ "total": 0,
89
+ "updated_at": 1755783502,
90
+ "write_off_amount": 0
91
+ }
92
+ },
93
+ "event_type": "invoice_generated",
94
+ "id": "ev_AzZTN3UuW0e7G3in",
95
+ "object": "event",
96
+ "occurred_at": 1755783503,
97
+ "source": "admin_console",
98
+ "user": "manideep@chargebee.com",
99
+ "webhook_status": "scheduled",
100
+ "webhooks": [
101
+ {
102
+ "id": "whv2_AzZX7CUVnj5rB1ZHq",
103
+ "object": "webhook",
104
+ "webhook_status": "disabled"
105
+ },
106
+ {
107
+ "id": "whv2_169zTyUkn2tgg2fOQ",
108
+ "object": "webhook",
109
+ "webhook_status": "scheduled"
110
+ }
111
+ ]
112
+ }