@chargebee/chargebee-apps-libs 0.0.1

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 +97 -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
package/LICENSE ADDED
@@ -0,0 +1,24 @@
1
+ The MIT License
2
+
3
+ Copyright (c) 2011-2024 Chargebee, Inc.
4
+
5
+ Permission is hereby granted, free of charge, to any person
6
+ obtaining a copy of this software and associated documentation
7
+ files (the "Software"), to deal in the Software without
8
+ restriction, including without limitation the rights to use,
9
+ copy, modify, merge, publish, distribute, sublicense, and/or sell
10
+ copies of the Software, and to permit persons to whom the
11
+ Software is furnished to do so, subject to the following
12
+ conditions:
13
+
14
+ The above copyright notice and this permission notice shall be
15
+ included in all copies or substantial portions of the Software.
16
+
17
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
18
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
19
+ OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
20
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
21
+ HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
22
+ WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
23
+ FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
24
+ OTHER DEALINGS IN THE SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,97 @@
1
+ # @chargebee/chargebee-apps-libs
2
+
3
+ Library implementations for the Chargebee Apps CLI — local development, sandbox execution, logging, configuration, and the web testing UI.
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ npm install @chargebee/chargebee-apps-libs
9
+ ```
10
+
11
+ This package is typically installed as a dependency of [`@chargebee/chargebee-apps`](https://www.npmjs.com/package/@chargebee/chargebee-apps). You can also use it directly when building tools on top of the Chargebee Apps platform.
12
+
13
+ ## What's included
14
+
15
+ - **Configuration** — application config loading with caching and validation
16
+ - **Logging** — structured logging and a safe console for sandboxed user code
17
+ - **Sandbox** — VM-based secure execution for event handlers
18
+ - **Utilities** — port validation and related helpers
19
+ - **Templates** — starter app scaffolds used by the CLI
20
+ - **Web UI** — browser interface for local handler testing
21
+
22
+ ## Templates
23
+
24
+ ### `serverless-node-starter-app`
25
+
26
+ Basic Node.js serverless app with sample handlers, test data, and TypeScript definitions.
27
+
28
+ ### `serverless-node-starter-app-with-iparams`
29
+
30
+ Same as the starter app, plus sectioned installation parameters:
31
+
32
+ - `iparams.json` — parameter definitions under `installation_parameters.sections`
33
+ - `iparams.local.json` — local values keyed by section name
34
+ - Handlers receive `payload.iparams.<section>.<param>`
35
+
36
+ See [`templates/serverless-node-starter-app-with-iparams/README.md`](templates/serverless-node-starter-app-with-iparams/README.md) for the full iparams schema and examples.
37
+
38
+ ## Usage
39
+
40
+ ```typescript
41
+ import {
42
+ ConfigLoader,
43
+ createCBPublicLogger,
44
+ PublicSandboxWrapper,
45
+ } from '@chargebee/chargebee-apps-libs';
46
+ import {
47
+ CBFileSystem,
48
+ CBProcess,
49
+ DependencyManager,
50
+ ManifestValidator,
51
+ PackageValidator,
52
+ } from '@chargebee/chargebee-apps-shared';
53
+
54
+ const configLoader = new ConfigLoader();
55
+ const allowedModules = configLoader.loadAllowedModules();
56
+
57
+ const fileSystem = new CBFileSystem();
58
+ const processService = new CBProcess();
59
+ const packageValidator = new PackageValidator(fileSystem);
60
+ const manifestValidator = new ManifestValidator(allowedModules);
61
+ const dependencyManager = new DependencyManager(fileSystem);
62
+
63
+ const manifest = manifestValidator.validateFile('./my-app/manifest.json');
64
+ await dependencyManager.ensureDependencies('./my-app', manifest);
65
+
66
+ const logger = createCBPublicLogger(fileSystem, processService, './my-app');
67
+
68
+ const sandbox = new PublicSandboxWrapper(
69
+ allowedModules,
70
+ fileSystem,
71
+ packageValidator,
72
+ dependencyManager,
73
+ manifestValidator
74
+ );
75
+
76
+ const result = await sandbox.execute('./my-app', { event: eventData }, logger);
77
+ ```
78
+
79
+ ## Security
80
+
81
+ - **Module whitelisting** — only approved npm modules can be used
82
+ - **Sandboxed execution** — user code runs in isolated VM contexts
83
+ - **Controlled logging** — user code logging is managed and correlated
84
+
85
+ ## Dependencies
86
+
87
+ - `@chargebee/chargebee-apps-shared` — shared interfaces, validators, and utilities
88
+ - `dotenv` — environment variable loading for local development
89
+
90
+ ## Related packages
91
+
92
+ - [`@chargebee/chargebee-apps`](https://www.npmjs.com/package/@chargebee/chargebee-apps) — CLI for creating, running, and packaging apps
93
+ - [`@chargebee/chargebee-apps-shared`](https://www.npmjs.com/package/@chargebee/chargebee-apps-shared) — shared types and core utilities
94
+
95
+ ## License
96
+
97
+ MIT
package/SECURITY.md ADDED
@@ -0,0 +1,8 @@
1
+ # Security Policy
2
+
3
+ At Chargebee, we take data integrity and security very seriously. Due to the nature of the product and service we provide, we are committed to working with individuals to stay updated on the latest security techniques and fix any security weakness in our application or infrastructure reported to us responsibly by external parties.
4
+
5
+ https://www.chargebee.com/security/responsible-disclosure-policy/
6
+
7
+ ## Reporting a vulnerability
8
+ Reach out to us at security@chargebee.com. Please do not open GitHub issues or pull requests as this makes the problem immediately visible to everyone, including malicious actors. Chargebee's security team will triage your report and respond according to its impact.
@@ -0,0 +1,83 @@
1
+ # Configuration
2
+
3
+ This directory contains static configuration files for the Chargebee Apps CLI tool.
4
+
5
+ ## Files
6
+
7
+ ### `allowed-modules.json`
8
+
9
+ Defines the list of Node.js modules that are allowed to be used in user applications. This configuration ensures security by restricting which modules can be imported in the sandbox environment.
10
+
11
+ #### Structure
12
+
13
+ ```json
14
+ {
15
+ "modules": [
16
+ {
17
+ "name": "module-name",
18
+ "version": "semver-range"
19
+ }
20
+ ]
21
+ }
22
+ ```
23
+
24
+ #### Fields
25
+
26
+ - **name** (required): The npm package name
27
+ - **version** (optional): A semver range that specifies allowed versions
28
+
29
+ #### Example
30
+
31
+ ```json
32
+ {
33
+ "modules": [
34
+ {
35
+ "name": "lodash",
36
+ "version": "^4.17.0",
37
+ "description": "Utility library for common JavaScript operations"
38
+ },
39
+ {
40
+ "name": "axios",
41
+ "version": "^1.0.0",
42
+ "description": "HTTP client for making API requests"
43
+ },
44
+ {
45
+ "name": "uuid",
46
+ "version": "^9.0.0 || ^10.0.0",
47
+ "description": "Generate RFC-compliant UUIDs"
48
+ }
49
+ ]
50
+ }
51
+ ```
52
+
53
+ #### Semver Version Examples
54
+
55
+ The `version` field supports various semver patterns:
56
+
57
+ - **All versions**: `*` (allows any version)
58
+ - **Exact version**: `4.17.21` (only this specific version)
59
+ - **Caret range**: `^4.17.0` (allows 4.17.x but not 5.0.0)
60
+ - **Tilde range**: `~4.17.0` (allows 4.17.x but not 4.18.0)
61
+ - **Range**: `>=4.17.0 <5.0.0` (custom range)
62
+ - **Multiple ranges**: `^9.0.0 || ^10.0.0` (allows either 9.x.x or 10.x.x)
63
+
64
+ ## Usage
65
+
66
+ The configuration is loaded by the `ConfigLoader` class in `src/libs/config-loader.ts` and used by the sandbox environment to validate user dependencies.
67
+
68
+ ## Notes
69
+
70
+ - This is static configuration that doesn't change during runtime
71
+ - Located in the root directory for easy access and modification
72
+ - Used by the sandbox to enforce security restrictions
73
+
74
+ ## Future Plans
75
+
76
+ **⚠️ Temporary Implementation**: This static JSON configuration is a temporary solution. In the future, the allowed modules configuration will be moved to a dynamic API that will be served by Chargebee. This will allow for:
77
+
78
+ - **Dynamic updates**: Module allowlist can be updated without CLI releases
79
+ - **Centralized management**: All configurations managed by Chargebee
80
+ - **Real-time changes**: Immediate updates to security policies
81
+ - **Better scalability**: Support for more complex module management
82
+
83
+ The current static JSON approach is maintained for development and testing purposes until the API integration is complete.
@@ -0,0 +1,24 @@
1
+ {
2
+ "modules": [
3
+ {
4
+ "name": "lodash",
5
+ "version": "^4.17.0",
6
+ "description": "Utility library for common JavaScript operations"
7
+ },
8
+ {
9
+ "name": "axios",
10
+ "version": "^1.0.0",
11
+ "description": "HTTP client for making API requests"
12
+ },
13
+ {
14
+ "name": "uuid",
15
+ "version": "^9.0.0 || ^10.0.0",
16
+ "description": "Generate RFC-compliant UUIDs"
17
+ },
18
+ {
19
+ "name": "chargebee",
20
+ "version": "^3.0.0",
21
+ "description": "Chargebee SDK for Node.js"
22
+ }
23
+ ]
24
+ }
@@ -0,0 +1,24 @@
1
+ import { AllowedModule, CBFileSystem } from '@chargebee/chargebee-apps-shared';
2
+ /**
3
+ * ConfigLoader provides utilities for loading and managing configuration files
4
+ * Public implementation for loading allowed modules configuration
5
+ */
6
+ export declare class ConfigLoader {
7
+ private cache;
8
+ private fileSystem;
9
+ constructor(fileSystem: CBFileSystem);
10
+ /**
11
+ * Loads and validates the allowed modules configuration
12
+ * @returns {AllowedModule[]} Array of validated allowed modules
13
+ * @throws {Error} If configuration is invalid or cannot be loaded
14
+ */
15
+ loadAllowedModules(): AllowedModule[];
16
+ /**
17
+ * Loads a JSON configuration file with caching
18
+ * @param {string} configPath - Path to the configuration file
19
+ * @param {boolean} useCache - Whether to use cached version if available
20
+ * @returns {any} Parsed configuration object
21
+ * @throws {Error} If file cannot be loaded or parsed
22
+ */
23
+ loadConfig(configPath: string, useCache?: boolean): any;
24
+ }
@@ -0,0 +1,95 @@
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.ConfigLoader = void 0;
7
+ const chargebee_apps_shared_1 = require("@chargebee/chargebee-apps-shared");
8
+ const path_1 = __importDefault(require("path"));
9
+ const semver_1 = __importDefault(require("semver"));
10
+ /**
11
+ * ConfigLoader provides utilities for loading and managing configuration files
12
+ * Public implementation for loading allowed modules configuration
13
+ */
14
+ class ConfigLoader {
15
+ constructor(fileSystem) {
16
+ this.fileSystem = fileSystem;
17
+ this.cache = new Map();
18
+ }
19
+ /**
20
+ * Loads and validates the allowed modules configuration
21
+ * @returns {AllowedModule[]} Array of validated allowed modules
22
+ * @throws {Error} If configuration is invalid or cannot be loaded
23
+ */
24
+ loadAllowedModules() {
25
+ try {
26
+ // Get config file path
27
+ let configPath;
28
+ try {
29
+ // Production: Find @chargebee/chargebee-apps-libs package and get config from package root
30
+ const packageJsonPath = require.resolve('@chargebee/chargebee-apps-libs');
31
+ const packageRoot = path_1.default.dirname(path_1.default.dirname(packageJsonPath));
32
+ configPath = path_1.default.join(packageRoot, 'config', 'allowed-modules.json');
33
+ }
34
+ catch (error) {
35
+ chargebee_apps_shared_1.__logger.error('Error: Failed to find allowed modules in the published package', error);
36
+ // Development: Use relative path
37
+ configPath = path_1.default.join(__dirname, '../../config/allowed-modules.json');
38
+ }
39
+ const config = this.loadConfig(configPath);
40
+ if (!config.modules || !Array.isArray(config.modules)) {
41
+ throw new Error('Invalid allowed modules format: "modules" must be an array');
42
+ }
43
+ const validatedModules = config.modules.map((module, index) => {
44
+ if (!module.name || typeof module.name !== 'string') {
45
+ throw new Error(`Invalid module at index ${index}: "name" must be a string`);
46
+ }
47
+ if (module.version && typeof module.version !== 'string') {
48
+ throw new Error(`Invalid module "${module.name}": "version" must be a string`);
49
+ }
50
+ if (module.version && !semver_1.default.validRange(module.version)) {
51
+ throw new Error(`Invalid semver range "${module.version}" for module "${module.name}"`);
52
+ }
53
+ return module;
54
+ });
55
+ chargebee_apps_shared_1.__logger.debug(`Loaded ${validatedModules.length} allowed modules from configuration`);
56
+ return validatedModules;
57
+ }
58
+ catch (error) {
59
+ const err = error;
60
+ chargebee_apps_shared_1.__logger.error('Failed to load allowed-modules.json:', err.message);
61
+ throw err;
62
+ }
63
+ }
64
+ /**
65
+ * Loads a JSON configuration file with caching
66
+ * @param {string} configPath - Path to the configuration file
67
+ * @param {boolean} useCache - Whether to use cached version if available
68
+ * @returns {any} Parsed configuration object
69
+ * @throws {Error} If file cannot be loaded or parsed
70
+ */
71
+ loadConfig(configPath, useCache = true) {
72
+ const absolutePath = path_1.default.resolve(configPath);
73
+ // Check cache first
74
+ if (useCache && this.cache.has(absolutePath)) {
75
+ return this.cache.get(absolutePath);
76
+ }
77
+ try {
78
+ if (!this.fileSystem.existsSync(absolutePath)) {
79
+ throw new Error(`Configuration file not found: ${absolutePath}`);
80
+ }
81
+ const configContent = this.fileSystem.readFileSync(absolutePath, 'utf8');
82
+ const config = JSON.parse(configContent);
83
+ // Cache the result
84
+ if (useCache) {
85
+ this.cache.set(absolutePath, config);
86
+ }
87
+ return config;
88
+ }
89
+ catch (error) {
90
+ const err = error;
91
+ throw new Error(`Failed to load configuration from ${absolutePath}: ${err.message}`);
92
+ }
93
+ }
94
+ }
95
+ exports.ConfigLoader = ConfigLoader;
@@ -0,0 +1,4 @@
1
+ export * from './config/config-loader';
2
+ export * from './libs/port-service';
3
+ export * from './logger/cb-public-logger';
4
+ export * from './sandbox/public-sandbox-wrapper';
package/dist/index.js ADDED
@@ -0,0 +1,21 @@
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
+ // Export all public library implementations
18
+ __exportStar(require("./config/config-loader"), exports);
19
+ __exportStar(require("./libs/port-service"), exports);
20
+ __exportStar(require("./logger/cb-public-logger"), exports);
21
+ __exportStar(require("./sandbox/public-sandbox-wrapper"), exports);
@@ -0,0 +1,18 @@
1
+ /**
2
+ * Port parsing service
3
+ */
4
+ export declare class PortService {
5
+ constructor();
6
+ /**
7
+ * Validates port number
8
+ * @param {string} port - Port string input
9
+ * @returns {boolean} True if port is valid
10
+ */
11
+ isValidPort(port: string): boolean;
12
+ /**
13
+ * Parses port number from string input
14
+ * @param {string} port - Port string input
15
+ * @returns {number} Parsed port number or default
16
+ */
17
+ parsePort(port: string): number;
18
+ }
@@ -0,0 +1,27 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.PortService = void 0;
4
+ /**
5
+ * Port parsing service
6
+ */
7
+ class PortService {
8
+ constructor() { }
9
+ /**
10
+ * Validates port number
11
+ * @param {string} port - Port string input
12
+ * @returns {boolean} True if port is valid
13
+ */
14
+ isValidPort(port) {
15
+ const parsedPort = parseInt(port);
16
+ return !isNaN(parsedPort);
17
+ }
18
+ /**
19
+ * Parses port number from string input
20
+ * @param {string} port - Port string input
21
+ * @returns {number} Parsed port number or default
22
+ */
23
+ parsePort(port) {
24
+ return parseInt(port);
25
+ }
26
+ }
27
+ exports.PortService = PortService;
@@ -0,0 +1,59 @@
1
+ import { CBFileSystem, CBProcess, ICBLogger, SafeConsole } from '@chargebee/chargebee-apps-shared';
2
+ import winston from 'winston';
3
+ /**
4
+ * Public logger implementation for local development
5
+ * This logger provides controlled logging capabilities for sandboxed code execution
6
+ * with correlation context and formatted output using Winston
7
+ */
8
+ export declare class CBPublicLogger implements ICBLogger {
9
+ private logger;
10
+ private userCodeDir;
11
+ private fileSystem;
12
+ private process;
13
+ constructor(fileSystem: CBFileSystem, process: CBProcess, userCodeDir: string);
14
+ /**
15
+ * Creates a Winston logger with console and file transports
16
+ * @returns {winston.Logger} Configured Winston logger instance
17
+ */
18
+ protected createWinstonLogger(): winston.Logger;
19
+ /**
20
+ * Logs an info message
21
+ * @param {...any[]} args - The message arguments to log
22
+ */
23
+ info(...args: any[]): void;
24
+ /**
25
+ * Logs a warning message
26
+ * @param {...any[]} args - The message arguments to log
27
+ */
28
+ warn(...args: any[]): void;
29
+ /**
30
+ * Logs an error message
31
+ * @param {...any[]} args - The message arguments to log
32
+ */
33
+ error(...args: any[]): void;
34
+ /**
35
+ * Logs a debug message
36
+ * @param {...any[]} args - The message arguments to log
37
+ */
38
+ debug(...args: any[]): void;
39
+ /**
40
+ * Formats a message with timestamp and level
41
+ * @param {winston.Logform.TransformableInfo} info - The log info
42
+ * @returns {string} The formatted message
43
+ */
44
+ formatMessage(info: winston.Logform.TransformableInfo): string;
45
+ }
46
+ /**
47
+ * Creates a safe console object that uses the logger
48
+ * @param {ICBLogger} logger - The logger instance to use
49
+ * @returns {SafeConsole} A safe console object
50
+ */
51
+ export declare function createSafeConsole(logger: ICBLogger): SafeConsole;
52
+ /**
53
+ * Creates a new CBPublicLogger instance for a specific user code directory
54
+ * @param {CBFileSystem} fileSystem - The filesystem implementation to use
55
+ * @param {CBProcess} process - The process implementation to use
56
+ * @param {string} userCodeDir - The user code directory where logs should be stored
57
+ * @returns {CBPublicLogger} A new CBPublicLogger instance
58
+ */
59
+ export declare function createCBPublicLogger(fileSystem: CBFileSystem, process: CBProcess, userCodeDir: string): CBPublicLogger;
@@ -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
+ }