@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.
- package/LICENSE +24 -0
- package/README.md +97 -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
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.
|
package/config/README.md
ADDED
|
@@ -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;
|
package/dist/index.d.ts
ADDED
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
|
+
}
|