@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.
- package/LICENSE +24 -0
- package/README.md +270 -0
- package/SECURITY.md +8 -0
- package/config/README.md +83 -0
- package/config/allowed-modules.json +24 -0
- package/dist/config/config-loader.d.ts +24 -0
- package/dist/config/config-loader.js +95 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.js +21 -0
- package/dist/libs/port-service.d.ts +18 -0
- package/dist/libs/port-service.js +27 -0
- package/dist/logger/cb-public-logger.d.ts +59 -0
- package/dist/logger/cb-public-logger.js +158 -0
- package/dist/sandbox/public-sandbox-wrapper.d.ts +41 -0
- package/dist/sandbox/public-sandbox-wrapper.js +208 -0
- package/package.json +44 -0
- package/templates/serverless-node-starter-app/.env +4 -0
- package/templates/serverless-node-starter-app/README.md +290 -0
- package/templates/serverless-node-starter-app/handler/handler.js +34 -0
- package/templates/serverless-node-starter-app/jsconfig.json +35 -0
- package/templates/serverless-node-starter-app/manifest.json +15 -0
- package/templates/serverless-node-starter-app/test_data/customer_created.json +51 -0
- package/templates/serverless-node-starter-app/test_data/invoice_generated.json +112 -0
- package/templates/serverless-node-starter-app/test_data/subscription_created.json +173 -0
- package/templates/serverless-node-starter-app/types/types.d.ts +45 -0
- package/templates/serverless-node-starter-app-with-iparams/.env +4 -0
- package/templates/serverless-node-starter-app-with-iparams/README.md +717 -0
- package/templates/serverless-node-starter-app-with-iparams/handler/handler.js +39 -0
- package/templates/serverless-node-starter-app-with-iparams/iparams.json +41 -0
- package/templates/serverless-node-starter-app-with-iparams/iparams.local.json +9 -0
- package/templates/serverless-node-starter-app-with-iparams/jsconfig.json +35 -0
- package/templates/serverless-node-starter-app-with-iparams/manifest.json +15 -0
- package/templates/serverless-node-starter-app-with-iparams/test_data/customer_created.json +51 -0
- package/templates/serverless-node-starter-app-with-iparams/test_data/invoice_generated.json +112 -0
- package/templates/serverless-node-starter-app-with-iparams/test_data/subscription_created.json +173 -0
- package/templates/serverless-node-starter-app-with-iparams/types/types.d.ts +63 -0
- package/ui/README.md +118 -0
- package/ui/web/assets/css/main.css +1121 -0
- package/ui/web/assets/images/Chargebee-logo.png +0 -0
- package/ui/web/assets/js/main.js +61 -0
- package/ui/web/assets/js/modules/api.js +97 -0
- package/ui/web/assets/js/modules/constants.js +33 -0
- package/ui/web/assets/js/modules/editors.js +41 -0
- package/ui/web/assets/js/modules/events.js +195 -0
- package/ui/web/assets/js/modules/form-utils.js +70 -0
- package/ui/web/assets/js/modules/iparams-inputs.js +495 -0
- package/ui/web/assets/js/modules/iparams.js +82 -0
- package/ui/web/assets/js/modules/ui-utils.js +87 -0
- package/ui/web/index.html +164 -0
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.CBPublicLogger = void 0;
|
|
7
|
+
exports.createSafeConsole = createSafeConsole;
|
|
8
|
+
exports.createCBPublicLogger = createCBPublicLogger;
|
|
9
|
+
const chargebee_apps_shared_1 = require("@chargebee/chargebee-apps-shared");
|
|
10
|
+
const path_1 = __importDefault(require("path"));
|
|
11
|
+
const winston_1 = __importDefault(require("winston"));
|
|
12
|
+
/**
|
|
13
|
+
* Public logger implementation for local development
|
|
14
|
+
* This logger provides controlled logging capabilities for sandboxed code execution
|
|
15
|
+
* with correlation context and formatted output using Winston
|
|
16
|
+
*/
|
|
17
|
+
class CBPublicLogger {
|
|
18
|
+
constructor(fileSystem, process, userCodeDir) {
|
|
19
|
+
this.userCodeDir = userCodeDir || process.cwd();
|
|
20
|
+
this.fileSystem = fileSystem;
|
|
21
|
+
this.process = process;
|
|
22
|
+
this.logger = this.createWinstonLogger();
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Creates a Winston logger with console and file transports
|
|
26
|
+
* @returns {winston.Logger} Configured Winston logger instance
|
|
27
|
+
*/
|
|
28
|
+
createWinstonLogger() {
|
|
29
|
+
// Get current log level from environment
|
|
30
|
+
const currentLogLevel = this.process.env['CB_LOG_LEVEL'] || chargebee_apps_shared_1.LogLevel.INFO;
|
|
31
|
+
try {
|
|
32
|
+
// Use the user code directory (where the logs should be stored)
|
|
33
|
+
const logsDir = path_1.default.join(this.userCodeDir, 'logs');
|
|
34
|
+
const logFilePath = path_1.default.join(logsDir, 'cb.log');
|
|
35
|
+
// Create logs directory if it doesn't exist
|
|
36
|
+
if (!this.fileSystem.existsSync(logsDir)) {
|
|
37
|
+
this.fileSystem.mkdirSync(logsDir, { recursive: true });
|
|
38
|
+
}
|
|
39
|
+
// Clear the log file on each run by writing an empty string
|
|
40
|
+
this.fileSystem.writeFileSync(logFilePath, '');
|
|
41
|
+
// Create transports
|
|
42
|
+
const transports = [
|
|
43
|
+
// Console transport for development output
|
|
44
|
+
new winston_1.default.transports.Console({
|
|
45
|
+
level: currentLogLevel.toLowerCase(),
|
|
46
|
+
format: winston_1.default.format.combine(winston_1.default.format.timestamp(), winston_1.default.format.colorize(), winston_1.default.format.errors({ stack: true }), winston_1.default.format.printf((info) => {
|
|
47
|
+
return this.formatMessage(info);
|
|
48
|
+
}))
|
|
49
|
+
}),
|
|
50
|
+
// Single file transport for all logs
|
|
51
|
+
new winston_1.default.transports.File({
|
|
52
|
+
filename: logFilePath,
|
|
53
|
+
level: currentLogLevel.toLowerCase(),
|
|
54
|
+
format: winston_1.default.format.combine(winston_1.default.format.errors({ stack: true }), winston_1.default.format.printf((info) => {
|
|
55
|
+
return this.formatMessage(info);
|
|
56
|
+
}))
|
|
57
|
+
})
|
|
58
|
+
];
|
|
59
|
+
return winston_1.default.createLogger({
|
|
60
|
+
level: currentLogLevel.toLowerCase(),
|
|
61
|
+
format: winston_1.default.format.combine(winston_1.default.format.timestamp(), winston_1.default.format.errors({ stack: true })),
|
|
62
|
+
transports
|
|
63
|
+
});
|
|
64
|
+
}
|
|
65
|
+
catch (error) {
|
|
66
|
+
// Fallback to console if Winston initialization fails
|
|
67
|
+
chargebee_apps_shared_1.__logger.error('Failed to initialize Winston logger:', error);
|
|
68
|
+
// Return a minimal logger that just logs to console
|
|
69
|
+
return winston_1.default.createLogger({
|
|
70
|
+
level: currentLogLevel.toLowerCase(),
|
|
71
|
+
transports: [
|
|
72
|
+
new winston_1.default.transports.Console({
|
|
73
|
+
format: winston_1.default.format.simple()
|
|
74
|
+
})
|
|
75
|
+
]
|
|
76
|
+
});
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* Logs an info message
|
|
81
|
+
* @param {...any[]} args - The message arguments to log
|
|
82
|
+
*/
|
|
83
|
+
info(...args) {
|
|
84
|
+
this.logger.info(args.join(' '));
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* Logs a warning message
|
|
88
|
+
* @param {...any[]} args - The message arguments to log
|
|
89
|
+
*/
|
|
90
|
+
warn(...args) {
|
|
91
|
+
this.logger.warn(args.join(' '));
|
|
92
|
+
}
|
|
93
|
+
/**
|
|
94
|
+
* Logs an error message
|
|
95
|
+
* @param {...any[]} args - The message arguments to log
|
|
96
|
+
*/
|
|
97
|
+
error(...args) {
|
|
98
|
+
this.logger.error(args.join(' '));
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* Logs a debug message
|
|
102
|
+
* @param {...any[]} args - The message arguments to log
|
|
103
|
+
*/
|
|
104
|
+
debug(...args) {
|
|
105
|
+
this.logger.debug(args.join(' '));
|
|
106
|
+
}
|
|
107
|
+
/**
|
|
108
|
+
* Formats a message with timestamp and level
|
|
109
|
+
* @param {winston.Logform.TransformableInfo} info - The log info
|
|
110
|
+
* @returns {string} The formatted message
|
|
111
|
+
*/
|
|
112
|
+
formatMessage(info) {
|
|
113
|
+
const timestamp = info['timestamp'];
|
|
114
|
+
const level = info.level;
|
|
115
|
+
const message = info.message;
|
|
116
|
+
const context = chargebee_apps_shared_1.sandboxContext.getCurrentContext();
|
|
117
|
+
const eventId = context?.eventId || 'unknown';
|
|
118
|
+
const eventType = context?.eventType || 'unknown';
|
|
119
|
+
return `${timestamp} [${level}] [${eventId}] [${eventType}] ${message}`;
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
exports.CBPublicLogger = CBPublicLogger;
|
|
123
|
+
/**
|
|
124
|
+
* Creates a safe console object that uses the logger
|
|
125
|
+
* @param {ICBLogger} logger - The logger instance to use
|
|
126
|
+
* @returns {SafeConsole} A safe console object
|
|
127
|
+
*/
|
|
128
|
+
function createSafeConsole(logger) {
|
|
129
|
+
return Object.freeze({
|
|
130
|
+
log: (...args) => logger.info(...args),
|
|
131
|
+
info: (...args) => logger.info(...args),
|
|
132
|
+
warn: (...args) => logger.warn(...args),
|
|
133
|
+
error: (...args) => logger.error(...args),
|
|
134
|
+
debug: (...args) => logger.debug(...args),
|
|
135
|
+
// Disable potentially dangerous console methods
|
|
136
|
+
trace: () => { },
|
|
137
|
+
table: () => { },
|
|
138
|
+
time: () => { },
|
|
139
|
+
timeEnd: () => { },
|
|
140
|
+
timeLog: () => { },
|
|
141
|
+
count: () => { },
|
|
142
|
+
countReset: () => { },
|
|
143
|
+
group: () => { },
|
|
144
|
+
groupCollapsed: () => { },
|
|
145
|
+
groupEnd: () => { },
|
|
146
|
+
clear: () => { }
|
|
147
|
+
});
|
|
148
|
+
}
|
|
149
|
+
/**
|
|
150
|
+
* Creates a new CBPublicLogger instance for a specific user code directory
|
|
151
|
+
* @param {CBFileSystem} fileSystem - The filesystem implementation to use
|
|
152
|
+
* @param {CBProcess} process - The process implementation to use
|
|
153
|
+
* @param {string} userCodeDir - The user code directory where logs should be stored
|
|
154
|
+
* @returns {CBPublicLogger} A new CBPublicLogger instance
|
|
155
|
+
*/
|
|
156
|
+
function createCBPublicLogger(fileSystem, process, userCodeDir) {
|
|
157
|
+
return new CBPublicLogger(fileSystem, process, userCodeDir);
|
|
158
|
+
}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { AllowedModule, CBFileSystem, DependencyManager, ExecutionResult, HandlerPayload, ICBLogger, ISandboxWrapper, ManifestValidator, PackageValidator, SandboxEnvironment } from '@chargebee/chargebee-apps-shared';
|
|
2
|
+
/**
|
|
3
|
+
* PublicSandboxWrapper provides a secure environment for executing user-provided NodeJS code
|
|
4
|
+
* Public implementation for local development environment
|
|
5
|
+
*/
|
|
6
|
+
export declare class PublicSandboxWrapper implements ISandboxWrapper {
|
|
7
|
+
private allowedModules;
|
|
8
|
+
private manifestValidator;
|
|
9
|
+
private packageValidator;
|
|
10
|
+
private fileSystem;
|
|
11
|
+
private dependencyManager;
|
|
12
|
+
constructor(allowedModules: AllowedModule[], fileSystem: CBFileSystem, packageValidator: PackageValidator, dependencyManager: DependencyManager, manifestValidator: ManifestValidator);
|
|
13
|
+
/**
|
|
14
|
+
* Creates a safe require function that uses isolated node_modules
|
|
15
|
+
* @param {string} projectPath - Path to the user project
|
|
16
|
+
* @returns {Function} Safe require function
|
|
17
|
+
*/
|
|
18
|
+
createSafeRequire(projectPath: string): (moduleName: string) => any;
|
|
19
|
+
/**
|
|
20
|
+
* Loads environment variables from .env file in the project directory
|
|
21
|
+
* @param {string} projectPath - Path to the user project
|
|
22
|
+
* @returns {Record<string, string>} Environment variables object
|
|
23
|
+
*/
|
|
24
|
+
private loadEnvironmentVariables;
|
|
25
|
+
/**
|
|
26
|
+
* Creates a secure sandbox environment for code execution
|
|
27
|
+
* @param {string} projectPath - Path to the user project
|
|
28
|
+
* @param {HandlerPayload} payload - Handler payload (event + iparams) to expose to user code
|
|
29
|
+
* @param {ICBLogger} sessionLogger - Logger instance for this server session
|
|
30
|
+
* @returns {SandboxEnvironment} The sandbox environment object
|
|
31
|
+
*/
|
|
32
|
+
createSandbox(projectPath: string, payload: HandlerPayload, sessionLogger: ICBLogger): SandboxEnvironment;
|
|
33
|
+
/**
|
|
34
|
+
* Executes user-provided code in a secure sandbox environment.
|
|
35
|
+
* @param userCodePath - Path to the directory containing user code
|
|
36
|
+
* @param payload - Handler payload (event + iparams) to pass to the user handler
|
|
37
|
+
* @param sessionLogger - The logger instance for this server session
|
|
38
|
+
* @returns {Promise<ExecutionResult>} Execution result with success status and data/error
|
|
39
|
+
*/
|
|
40
|
+
execute(userCodePath: string, payload: HandlerPayload, sessionLogger: ICBLogger): Promise<ExecutionResult>;
|
|
41
|
+
}
|
|
@@ -0,0 +1,208 @@
|
|
|
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 __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
36
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
37
|
+
};
|
|
38
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
39
|
+
exports.PublicSandboxWrapper = void 0;
|
|
40
|
+
const chargebee_apps_shared_1 = require("@chargebee/chargebee-apps-shared");
|
|
41
|
+
const path_1 = __importDefault(require("path"));
|
|
42
|
+
const vm_1 = __importDefault(require("vm"));
|
|
43
|
+
const dotenv = __importStar(require("dotenv"));
|
|
44
|
+
const cb_public_logger_1 = require("../logger/cb-public-logger");
|
|
45
|
+
/**
|
|
46
|
+
* PublicSandboxWrapper provides a secure environment for executing user-provided NodeJS code
|
|
47
|
+
* Public implementation for local development environment
|
|
48
|
+
*/
|
|
49
|
+
class PublicSandboxWrapper {
|
|
50
|
+
constructor(allowedModules, fileSystem, packageValidator, dependencyManager, manifestValidator) {
|
|
51
|
+
this.fileSystem = fileSystem;
|
|
52
|
+
this.packageValidator = packageValidator;
|
|
53
|
+
this.dependencyManager = dependencyManager;
|
|
54
|
+
this.allowedModules = allowedModules;
|
|
55
|
+
this.manifestValidator = manifestValidator;
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Creates a safe require function that uses isolated node_modules
|
|
59
|
+
* @param {string} projectPath - Path to the user project
|
|
60
|
+
* @returns {Function} Safe require function
|
|
61
|
+
*/
|
|
62
|
+
createSafeRequire(projectPath) {
|
|
63
|
+
return this.dependencyManager.createIsolatedRequire(projectPath, this.allowedModules);
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* Loads environment variables from .env file in the project directory
|
|
67
|
+
* @param {string} projectPath - Path to the user project
|
|
68
|
+
* @returns {Record<string, string>} Environment variables object
|
|
69
|
+
*/
|
|
70
|
+
loadEnvironmentVariables(projectPath) {
|
|
71
|
+
const envPath = path_1.default.join(projectPath, '.env');
|
|
72
|
+
const envVars = {};
|
|
73
|
+
try {
|
|
74
|
+
// Load .env file if it exists
|
|
75
|
+
const result = dotenv.config({ path: envPath });
|
|
76
|
+
if (result.parsed) {
|
|
77
|
+
// Only include MKPLC_CB_READ_ONLY_API and MKPLC_CB_READ_WRITE_API keys
|
|
78
|
+
if (result.parsed['MKPLC_CB_READ_ONLY_API']) {
|
|
79
|
+
envVars['MKPLC_CB_READ_ONLY_API'] = result.parsed['MKPLC_CB_READ_ONLY_API'];
|
|
80
|
+
}
|
|
81
|
+
if (result.parsed['MKPLC_CB_READ_WRITE_API']) {
|
|
82
|
+
envVars['MKPLC_CB_READ_WRITE_API'] = result.parsed['MKPLC_CB_READ_WRITE_API'];
|
|
83
|
+
}
|
|
84
|
+
if (result.parsed['MKPLC_SITE_DOMAIN']) {
|
|
85
|
+
envVars['MKPLC_SITE_DOMAIN'] = result.parsed['MKPLC_SITE_DOMAIN'];
|
|
86
|
+
}
|
|
87
|
+
else {
|
|
88
|
+
envVars['MKPLC_SITE_DOMAIN'] = '';
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
catch (error) {
|
|
93
|
+
chargebee_apps_shared_1.__logger.debug(`Failed to load .env file from ${envPath}: ${error}`);
|
|
94
|
+
}
|
|
95
|
+
return envVars;
|
|
96
|
+
}
|
|
97
|
+
/**
|
|
98
|
+
* Creates a secure sandbox environment for code execution
|
|
99
|
+
* @param {string} projectPath - Path to the user project
|
|
100
|
+
* @param {HandlerPayload} payload - Handler payload (event + iparams) to expose to user code
|
|
101
|
+
* @param {ICBLogger} sessionLogger - Logger instance for this server session
|
|
102
|
+
* @returns {SandboxEnvironment} The sandbox environment object
|
|
103
|
+
*/
|
|
104
|
+
createSandbox(projectPath, payload, sessionLogger) {
|
|
105
|
+
const moduleObj = { exports: {} };
|
|
106
|
+
const exportsObj = moduleObj.exports;
|
|
107
|
+
// Load environment variables from .env file
|
|
108
|
+
const envVars = this.loadEnvironmentVariables(projectPath);
|
|
109
|
+
const hasIparams = Object.prototype.hasOwnProperty.call(payload, 'iparams');
|
|
110
|
+
const safePayload = Object.freeze(hasIparams
|
|
111
|
+
? { event: payload.event, iparams: payload.iparams ?? {} }
|
|
112
|
+
: { event: payload.event });
|
|
113
|
+
return {
|
|
114
|
+
// Controlled logging
|
|
115
|
+
console: (0, cb_public_logger_1.createSafeConsole)(sessionLogger),
|
|
116
|
+
// Read-only payload (event + iparams) for handler(payload)
|
|
117
|
+
payload: safePayload,
|
|
118
|
+
// Safe async primitives
|
|
119
|
+
setTimeout,
|
|
120
|
+
clearTimeout,
|
|
121
|
+
setImmediate,
|
|
122
|
+
clearImmediate,
|
|
123
|
+
// CommonJS emulation
|
|
124
|
+
module: moduleObj,
|
|
125
|
+
exports: exportsObj,
|
|
126
|
+
// Controlled module access
|
|
127
|
+
require: this.createSafeRequire(projectPath),
|
|
128
|
+
// Limited process access
|
|
129
|
+
process: {
|
|
130
|
+
cwd: () => process.cwd(),
|
|
131
|
+
env: envVars,
|
|
132
|
+
nextTick: process.nextTick
|
|
133
|
+
},
|
|
134
|
+
// Prevent escape hatches
|
|
135
|
+
global: undefined,
|
|
136
|
+
Buffer: undefined,
|
|
137
|
+
__dirname: undefined,
|
|
138
|
+
__filename: undefined
|
|
139
|
+
};
|
|
140
|
+
}
|
|
141
|
+
/**
|
|
142
|
+
* Executes user-provided code in a secure sandbox environment.
|
|
143
|
+
* @param userCodePath - Path to the directory containing user code
|
|
144
|
+
* @param payload - Handler payload (event + iparams) to pass to the user handler
|
|
145
|
+
* @param sessionLogger - The logger instance for this server session
|
|
146
|
+
* @returns {Promise<ExecutionResult>} Execution result with success status and data/error
|
|
147
|
+
*/
|
|
148
|
+
async execute(userCodePath, payload, sessionLogger) {
|
|
149
|
+
try {
|
|
150
|
+
chargebee_apps_shared_1.__logger.debug(`Executing user code from: ${userCodePath}`);
|
|
151
|
+
// Check if required files exist.
|
|
152
|
+
this.packageValidator.validateHandlerExists(userCodePath);
|
|
153
|
+
this.packageValidator.validateManifestExists(userCodePath);
|
|
154
|
+
// Validate manifest file.
|
|
155
|
+
const manifestPath = path_1.default.join(userCodePath, 'manifest.json');
|
|
156
|
+
const manifest = this.manifestValidator.validateAndGetManifestFile(manifestPath);
|
|
157
|
+
// Load user code
|
|
158
|
+
const eventType = payload.event.event_type;
|
|
159
|
+
const eventConfig = manifest.events[eventType];
|
|
160
|
+
if (!eventConfig) {
|
|
161
|
+
throw new Error(`No handler configured for event type: ${eventType}`);
|
|
162
|
+
}
|
|
163
|
+
const handler = eventConfig.handler;
|
|
164
|
+
const handlerPath = path_1.default.join(userCodePath, 'handler', 'handler.js');
|
|
165
|
+
const userCode = this.fileSystem.readFileSync(handlerPath, 'utf8');
|
|
166
|
+
// Create execution context
|
|
167
|
+
const contextData = {
|
|
168
|
+
eventId: payload.event.id || 'unknown',
|
|
169
|
+
eventType: payload.event.event_type || 'unknown',
|
|
170
|
+
};
|
|
171
|
+
return await chargebee_apps_shared_1.sandboxContext.run(contextData, async () => {
|
|
172
|
+
const sandbox = this.createSandbox(userCodePath, payload, sessionLogger);
|
|
173
|
+
const vmContext = vm_1.default.createContext(sandbox);
|
|
174
|
+
// Execute user code and run handler with single payload argument
|
|
175
|
+
const executeCode = `
|
|
176
|
+
(async function() {
|
|
177
|
+
"use strict";
|
|
178
|
+
try {
|
|
179
|
+
${userCode}
|
|
180
|
+
const handler = module.exports["${handler}"];
|
|
181
|
+
if (typeof handler !== 'function') {
|
|
182
|
+
throw new Error('Handler function "${handler}" not found in handler.js');
|
|
183
|
+
}
|
|
184
|
+
return await handler(payload);
|
|
185
|
+
} catch (error) {
|
|
186
|
+
console.error(error.stack ? error.stack : error);
|
|
187
|
+
throw error;
|
|
188
|
+
}
|
|
189
|
+
})()
|
|
190
|
+
`;
|
|
191
|
+
await vm_1.default.runInContext(executeCode, vmContext, {
|
|
192
|
+
timeout: 15000, // 15 second timeout
|
|
193
|
+
displayErrors: true
|
|
194
|
+
});
|
|
195
|
+
return { success: true, statusCode: 200 };
|
|
196
|
+
});
|
|
197
|
+
}
|
|
198
|
+
catch (error) {
|
|
199
|
+
const err = error;
|
|
200
|
+
return {
|
|
201
|
+
success: false,
|
|
202
|
+
error: `${err.message}`,
|
|
203
|
+
stack: err.stack || undefined
|
|
204
|
+
};
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
exports.PublicSandboxWrapper = PublicSandboxWrapper;
|
package/package.json
ADDED
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@chargebee/chargebee-apps-libs",
|
|
3
|
+
"version": "0.0.2",
|
|
4
|
+
"description": "Public library implementations for Chargebee Apps CLI",
|
|
5
|
+
"main": "dist/index.js",
|
|
6
|
+
"types": "dist/index.d.ts",
|
|
7
|
+
"files": [
|
|
8
|
+
"dist",
|
|
9
|
+
"templates",
|
|
10
|
+
"config",
|
|
11
|
+
"ui",
|
|
12
|
+
"LICENSE",
|
|
13
|
+
"SECURITY.md"
|
|
14
|
+
],
|
|
15
|
+
"scripts": {
|
|
16
|
+
"build": "tsc",
|
|
17
|
+
"clean": "rm -rf dist && rm -rf coverage",
|
|
18
|
+
"test": "jest",
|
|
19
|
+
"test:watch": "jest --watch",
|
|
20
|
+
"test:coverage": "jest --coverage",
|
|
21
|
+
"test:unit": "jest --testPathPattern=tests/unit",
|
|
22
|
+
"minify": "esbuild 'dist/**/*.js' --minify --platform=node --outdir=dist --allow-overwrite"
|
|
23
|
+
},
|
|
24
|
+
"dependencies": {
|
|
25
|
+
"@chargebee/chargebee-apps-shared": "0.0.2",
|
|
26
|
+
"dotenv": "^16.3.1"
|
|
27
|
+
},
|
|
28
|
+
"devDependencies": {
|
|
29
|
+
"@types/jest": "^29.5.0",
|
|
30
|
+
"@types/node": "^24.3.0",
|
|
31
|
+
"@types/dotenv": "^8.2.0",
|
|
32
|
+
"esbuild": "^0.28.1",
|
|
33
|
+
"jest": "^29.5.0",
|
|
34
|
+
"ts-jest": "^29.1.0",
|
|
35
|
+
"typescript": "^5.0.0"
|
|
36
|
+
},
|
|
37
|
+
"publishConfig": {
|
|
38
|
+
"access": "public"
|
|
39
|
+
},
|
|
40
|
+
"license": "MIT",
|
|
41
|
+
"engines": {
|
|
42
|
+
"node": ">=22.0.0"
|
|
43
|
+
}
|
|
44
|
+
}
|