@chargebee/chargebee-apps-shared 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 +73 -0
- package/SECURITY.md +8 -0
- package/dist/config/environment.d.ts +78 -0
- package/dist/config/environment.js +150 -0
- package/dist/config/path-resolver.d.ts +117 -0
- package/dist/config/path-resolver.js +247 -0
- package/dist/dependency/dependency-manager.d.ts +66 -0
- package/dist/dependency/dependency-manager.js +257 -0
- package/dist/errors.d.ts +8 -0
- package/dist/errors.js +17 -0
- package/dist/index.d.ts +19 -0
- package/dist/index.js +36 -0
- package/dist/libs/archive-service.d.ts +21 -0
- package/dist/libs/archive-service.js +145 -0
- package/dist/libs/file-management-service.d.ts +59 -0
- package/dist/libs/file-management-service.js +189 -0
- package/dist/libs/iparams-service.d.ts +69 -0
- package/dist/libs/iparams-service.js +136 -0
- package/dist/libs/template-service.d.ts +57 -0
- package/dist/libs/template-service.js +152 -0
- package/dist/logger/cb-logger.d.ts +56 -0
- package/dist/logger/cb-logger.js +13 -0
- package/dist/logger/internal-logger.d.ts +81 -0
- package/dist/logger/internal-logger.js +146 -0
- package/dist/node/file-system.d.ts +66 -0
- package/dist/node/file-system.js +76 -0
- package/dist/node/process.d.ts +30 -0
- package/dist/node/process.js +25 -0
- package/dist/sandbox/sandbox-context.d.ts +37 -0
- package/dist/sandbox/sandbox-context.js +48 -0
- package/dist/sandbox/sandbox-wrapper.d.ts +75 -0
- package/dist/sandbox/sandbox-wrapper.js +2 -0
- package/dist/types/common.d.ts +135 -0
- package/dist/types/common.js +20 -0
- package/dist/validator/iparam-constants.d.ts +49 -0
- package/dist/validator/iparam-constants.js +52 -0
- package/dist/validator/iparam-defns-validator.d.ts +46 -0
- package/dist/validator/iparam-defns-validator.js +291 -0
- package/dist/validator/iparams-inputs-validator.d.ts +62 -0
- package/dist/validator/iparams-inputs-validator.js +289 -0
- package/dist/validator/manifest-validator.d.ts +48 -0
- package/dist/validator/manifest-validator.js +138 -0
- package/dist/validator/package-validator.d.ts +27 -0
- package/dist/validator/package-validator.js +43 -0
- package/dist/validator/validator-utils.d.ts +13 -0
- package/dist/validator/validator-utils.js +26 -0
- package/package.json +45 -0
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { CBFileSystem } from '../node/file-system';
|
|
2
|
+
import { AllowedModule, Manifest } from '../types/common';
|
|
3
|
+
/**
|
|
4
|
+
* ManifestValidator provides validation for Chargebee Apps application manifests
|
|
5
|
+
* Public implementation for validating user applications
|
|
6
|
+
*/
|
|
7
|
+
export declare class ManifestValidator {
|
|
8
|
+
private allowedModules;
|
|
9
|
+
private fileSystem;
|
|
10
|
+
constructor(allowedModulesConfig: AllowedModule[], fileSystem: CBFileSystem);
|
|
11
|
+
/**
|
|
12
|
+
* Validates a manifest file from disk
|
|
13
|
+
* @param {string} path - Path to the manifest.json file
|
|
14
|
+
* @returns {Object} The validated manifest
|
|
15
|
+
* @throws {Error} If manifest file is invalid or cannot be read
|
|
16
|
+
*/
|
|
17
|
+
validateAndGetManifestFile(path: string): Manifest;
|
|
18
|
+
/**
|
|
19
|
+
* Validates a complete manifest object
|
|
20
|
+
* @param {Manifest} manifest - The manifest object to validate
|
|
21
|
+
* @returns {Manifest} The validated manifest
|
|
22
|
+
* @throws {Error} If manifest is invalid
|
|
23
|
+
*/
|
|
24
|
+
protected validate(manifest: Manifest): void;
|
|
25
|
+
/**
|
|
26
|
+
* Validates the basic structure of the manifest
|
|
27
|
+
* @param {Object} manifest - The manifest object
|
|
28
|
+
* @throws {Error} If basic structure is invalid
|
|
29
|
+
*/
|
|
30
|
+
protected validateBasicStructure(manifest: Manifest): void;
|
|
31
|
+
/**
|
|
32
|
+
* Validates the events configuration
|
|
33
|
+
* @param {Object} manifest - The manifest object
|
|
34
|
+
* @throws {Error} If events configuration is invalid
|
|
35
|
+
*/
|
|
36
|
+
protected validateEvents(manifest: Manifest): void;
|
|
37
|
+
/**
|
|
38
|
+
* Validates the dependencies configuration
|
|
39
|
+
* @param {Object} manifest - The manifest object
|
|
40
|
+
* @throws {Error} If dependencies are invalid
|
|
41
|
+
*/
|
|
42
|
+
protected validateDependencies(manifest: Manifest): void;
|
|
43
|
+
/**
|
|
44
|
+
* Validates the metadata fields
|
|
45
|
+
* @param {Object} manifest - The manifest object
|
|
46
|
+
*/
|
|
47
|
+
protected validateMetadata(manifest: Manifest): void;
|
|
48
|
+
}
|
|
@@ -0,0 +1,138 @@
|
|
|
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.ManifestValidator = void 0;
|
|
7
|
+
const semver_1 = __importDefault(require("semver"));
|
|
8
|
+
const internal_logger_1 = require("../logger/internal-logger");
|
|
9
|
+
/**
|
|
10
|
+
* ManifestValidator provides validation for Chargebee Apps application manifests
|
|
11
|
+
* Public implementation for validating user applications
|
|
12
|
+
*/
|
|
13
|
+
class ManifestValidator {
|
|
14
|
+
constructor(allowedModulesConfig, fileSystem) {
|
|
15
|
+
this.allowedModules = allowedModulesConfig || [];
|
|
16
|
+
this.fileSystem = fileSystem;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Validates a manifest file from disk
|
|
20
|
+
* @param {string} path - Path to the manifest.json file
|
|
21
|
+
* @returns {Object} The validated manifest
|
|
22
|
+
* @throws {Error} If manifest file is invalid or cannot be read
|
|
23
|
+
*/
|
|
24
|
+
validateAndGetManifestFile(path) {
|
|
25
|
+
if (!this.fileSystem.existsSync(path)) {
|
|
26
|
+
throw new Error(`manifest.json not found in user code directory`);
|
|
27
|
+
}
|
|
28
|
+
try {
|
|
29
|
+
const manifestContent = this.fileSystem.readFileSync(path, 'utf8');
|
|
30
|
+
const manifest = JSON.parse(manifestContent);
|
|
31
|
+
this.validate(manifest);
|
|
32
|
+
return manifest;
|
|
33
|
+
}
|
|
34
|
+
catch (error) {
|
|
35
|
+
if (error instanceof SyntaxError) {
|
|
36
|
+
throw new Error(`Failed to parse manifest file: ${error.message}`);
|
|
37
|
+
}
|
|
38
|
+
const err = error;
|
|
39
|
+
throw new Error(`Failed to read manifest file: ${err.message}`);
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Validates a complete manifest object
|
|
44
|
+
* @param {Manifest} manifest - The manifest object to validate
|
|
45
|
+
* @returns {Manifest} The validated manifest
|
|
46
|
+
* @throws {Error} If manifest is invalid
|
|
47
|
+
*/
|
|
48
|
+
validate(manifest) {
|
|
49
|
+
// Basic structure validation
|
|
50
|
+
this.validateBasicStructure(manifest);
|
|
51
|
+
// Events validation
|
|
52
|
+
this.validateEvents(manifest);
|
|
53
|
+
// Dependencies validation
|
|
54
|
+
this.validateDependencies(manifest);
|
|
55
|
+
// Metadata validation
|
|
56
|
+
this.validateMetadata(manifest);
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Validates the basic structure of the manifest
|
|
60
|
+
* @param {Object} manifest - The manifest object
|
|
61
|
+
* @throws {Error} If basic structure is invalid
|
|
62
|
+
*/
|
|
63
|
+
validateBasicStructure(manifest) {
|
|
64
|
+
if (!manifest || typeof manifest !== 'object') {
|
|
65
|
+
throw new Error('Manifest must be a valid object');
|
|
66
|
+
}
|
|
67
|
+
if (manifest.events && typeof manifest.events !== 'object') {
|
|
68
|
+
throw new Error('Events mapping must be an object');
|
|
69
|
+
}
|
|
70
|
+
if (manifest.dependencies && typeof manifest.dependencies !== 'object') {
|
|
71
|
+
throw new Error('Dependencies must be an object');
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* Validates the events configuration
|
|
76
|
+
* @param {Object} manifest - The manifest object
|
|
77
|
+
* @throws {Error} If events configuration is invalid
|
|
78
|
+
*/
|
|
79
|
+
validateEvents(manifest) {
|
|
80
|
+
if (!manifest.events) {
|
|
81
|
+
throw new Error('Invalid manifest: missing "events" mapping');
|
|
82
|
+
}
|
|
83
|
+
for (const [eventType, handler] of Object.entries(manifest.events)) {
|
|
84
|
+
if (!handler || typeof handler !== 'object') {
|
|
85
|
+
throw new Error(`Handler name for event "${eventType}" must be a non-empty string`);
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* Validates the dependencies configuration
|
|
91
|
+
* @param {Object} manifest - The manifest object
|
|
92
|
+
* @throws {Error} If dependencies are invalid
|
|
93
|
+
*/
|
|
94
|
+
validateDependencies(manifest) {
|
|
95
|
+
if (!manifest.dependencies) {
|
|
96
|
+
return; // Dependencies are optional
|
|
97
|
+
}
|
|
98
|
+
if (typeof manifest.dependencies !== 'object') {
|
|
99
|
+
throw new Error('Invalid manifest: "dependencies" must be an object');
|
|
100
|
+
}
|
|
101
|
+
for (const [depName, depVersion] of Object.entries(manifest.dependencies)) {
|
|
102
|
+
if (typeof depName !== 'string' || typeof depVersion !== 'string') {
|
|
103
|
+
throw new Error(`Invalid dependency in manifest: "${depName}" must have string name and version`);
|
|
104
|
+
}
|
|
105
|
+
// Check if module is allowed
|
|
106
|
+
const allowedModule = this.allowedModules.find(module => module.name === depName);
|
|
107
|
+
if (!allowedModule) {
|
|
108
|
+
throw new Error(`Dependency "${depName}" is not allowed in this environment`);
|
|
109
|
+
}
|
|
110
|
+
// Validate version range
|
|
111
|
+
if (!semver_1.default.validRange(depVersion)) {
|
|
112
|
+
throw new Error(`Invalid version range "${depVersion}" for dependency "${depName}"`);
|
|
113
|
+
}
|
|
114
|
+
// Check version constraints if specified
|
|
115
|
+
if (allowedModule.version) {
|
|
116
|
+
if (!semver_1.default.satisfies(depVersion, allowedModule.version)) {
|
|
117
|
+
internal_logger_1.__logger.warn(`Dependency "${depName}" version range "${depVersion}" differs from allowed version constraint "${allowedModule.version}" - proceeding with warning`);
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
else {
|
|
121
|
+
throw new Error(`Configuration error: Allowed module "${depName}" does not have a version constraint`);
|
|
122
|
+
}
|
|
123
|
+
internal_logger_1.__logger.debug(`Dependency "${depName}" version "${depVersion}" is allowed`);
|
|
124
|
+
}
|
|
125
|
+
internal_logger_1.__logger.debug(`Validated ${Object.keys(manifest.dependencies).length} dependencies in manifest`);
|
|
126
|
+
}
|
|
127
|
+
/**
|
|
128
|
+
* Validates the metadata fields
|
|
129
|
+
* @param {Object} manifest - The manifest object
|
|
130
|
+
*/
|
|
131
|
+
validateMetadata(manifest) {
|
|
132
|
+
// Check for reasonable limits
|
|
133
|
+
if (manifest.dependencies && Object.keys(manifest.dependencies).length > 10) {
|
|
134
|
+
internal_logger_1.__logger.warn('Large number of dependencies detected - consider minimizing dependencies for better performance');
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
exports.ManifestValidator = ManifestValidator;
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { CBFileSystem } from "../node/file-system";
|
|
2
|
+
/**
|
|
3
|
+
* Package validator for validating app structure.
|
|
4
|
+
* This primarily validates the app directory and the structure of the app which developer bundles and uploads to Chargebee.
|
|
5
|
+
*/
|
|
6
|
+
export declare class PackageValidator {
|
|
7
|
+
private fileSystem;
|
|
8
|
+
constructor(fileSystem: CBFileSystem);
|
|
9
|
+
/**
|
|
10
|
+
* Validates that the app directory exists
|
|
11
|
+
* @param {string} targetDir - Target directory path
|
|
12
|
+
* @returns {boolean} True if directory exists
|
|
13
|
+
*/
|
|
14
|
+
validateAppDirectoryExists(targetDir: string): boolean;
|
|
15
|
+
/**
|
|
16
|
+
* Validates that manifest.json exists in the app directory
|
|
17
|
+
* @param {string} targetDir - Target directory path
|
|
18
|
+
* @returns {boolean} True if manifest.json exists
|
|
19
|
+
*/
|
|
20
|
+
validateManifestExists(targetDir: string): boolean;
|
|
21
|
+
/**
|
|
22
|
+
* Validates that handler.js exists in the app directory
|
|
23
|
+
* @param {string} targetDir - Target directory path
|
|
24
|
+
* @returns {boolean} True if handler.js exists
|
|
25
|
+
*/
|
|
26
|
+
validateHandlerExists(targetDir: string): boolean;
|
|
27
|
+
}
|
|
@@ -0,0 +1,43 @@
|
|
|
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.PackageValidator = void 0;
|
|
7
|
+
const path_1 = __importDefault(require("path"));
|
|
8
|
+
/**
|
|
9
|
+
* Package validator for validating app structure.
|
|
10
|
+
* This primarily validates the app directory and the structure of the app which developer bundles and uploads to Chargebee.
|
|
11
|
+
*/
|
|
12
|
+
class PackageValidator {
|
|
13
|
+
constructor(fileSystem) {
|
|
14
|
+
this.fileSystem = fileSystem;
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Validates that the app directory exists
|
|
18
|
+
* @param {string} targetDir - Target directory path
|
|
19
|
+
* @returns {boolean} True if directory exists
|
|
20
|
+
*/
|
|
21
|
+
validateAppDirectoryExists(targetDir) {
|
|
22
|
+
return this.fileSystem.existsSync(targetDir);
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Validates that manifest.json exists in the app directory
|
|
26
|
+
* @param {string} targetDir - Target directory path
|
|
27
|
+
* @returns {boolean} True if manifest.json exists
|
|
28
|
+
*/
|
|
29
|
+
validateManifestExists(targetDir) {
|
|
30
|
+
const manifestPath = path_1.default.join(targetDir, 'manifest.json');
|
|
31
|
+
return this.fileSystem.existsSync(manifestPath);
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Validates that handler.js exists in the app directory
|
|
35
|
+
* @param {string} targetDir - Target directory path
|
|
36
|
+
* @returns {boolean} True if handler.js exists
|
|
37
|
+
*/
|
|
38
|
+
validateHandlerExists(targetDir) {
|
|
39
|
+
const handlerPath = path_1.default.join(targetDir, 'handler', 'handler.js');
|
|
40
|
+
return this.fileSystem.existsSync(handlerPath);
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
exports.PackageValidator = PackageValidator;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { CBFileSystem } from '../node/file-system';
|
|
2
|
+
/**
|
|
3
|
+
* True only when `value` is a string and is not empty or whitespace-only after trim.
|
|
4
|
+
* Logically the opposite of `(typeof value !== 'string' || value.trim() === '')`.
|
|
5
|
+
* @param {unknown} value - Value to check
|
|
6
|
+
* @returns {value is string} Whether `value` is a usable non-empty string
|
|
7
|
+
*/
|
|
8
|
+
export declare function isNonEmptyString(value: unknown): value is string;
|
|
9
|
+
/**
|
|
10
|
+
* Throws if `filePath` does not exist on the given filesystem.
|
|
11
|
+
* Message uses the file basename, e.g. `iparams.json not found`.
|
|
12
|
+
*/
|
|
13
|
+
export declare function ensureFileExists(fileSystem: CBFileSystem, filePath: string): void;
|
|
@@ -0,0 +1,26 @@
|
|
|
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.isNonEmptyString = isNonEmptyString;
|
|
7
|
+
exports.ensureFileExists = ensureFileExists;
|
|
8
|
+
const path_1 = __importDefault(require("path"));
|
|
9
|
+
/**
|
|
10
|
+
* True only when `value` is a string and is not empty or whitespace-only after trim.
|
|
11
|
+
* Logically the opposite of `(typeof value !== 'string' || value.trim() === '')`.
|
|
12
|
+
* @param {unknown} value - Value to check
|
|
13
|
+
* @returns {value is string} Whether `value` is a usable non-empty string
|
|
14
|
+
*/
|
|
15
|
+
function isNonEmptyString(value) {
|
|
16
|
+
return typeof value === 'string' && value.trim() !== '';
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Throws if `filePath` does not exist on the given filesystem.
|
|
20
|
+
* Message uses the file basename, e.g. `iparams.json not found`.
|
|
21
|
+
*/
|
|
22
|
+
function ensureFileExists(fileSystem, filePath) {
|
|
23
|
+
if (!fileSystem.existsSync(filePath)) {
|
|
24
|
+
throw new Error(`${path_1.default.basename(filePath)} not found`);
|
|
25
|
+
}
|
|
26
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@chargebee/chargebee-apps-shared",
|
|
3
|
+
"version": "0.0.1",
|
|
4
|
+
"description": "Shared interfaces and utilities for Chargebee Apps CLI",
|
|
5
|
+
"main": "dist/index.js",
|
|
6
|
+
"types": "dist/index.d.ts",
|
|
7
|
+
"files": [
|
|
8
|
+
"dist",
|
|
9
|
+
"LICENSE",
|
|
10
|
+
"SECURITY.md"
|
|
11
|
+
],
|
|
12
|
+
"scripts": {
|
|
13
|
+
"build": "tsc",
|
|
14
|
+
"clean": "rm -rf dist && rm -rf coverage",
|
|
15
|
+
"test": "jest",
|
|
16
|
+
"test:watch": "jest --watch",
|
|
17
|
+
"test:coverage": "jest --coverage",
|
|
18
|
+
"test:unit": "jest --testPathPattern=tests/unit",
|
|
19
|
+
"minify": "esbuild 'dist/**/*.js' --minify --platform=node --outdir=dist --allow-overwrite"
|
|
20
|
+
},
|
|
21
|
+
"dependencies": {
|
|
22
|
+
"yauzl": "^2.10.0",
|
|
23
|
+
"winston": "^3.11.0",
|
|
24
|
+
"semver": "^7.7.2",
|
|
25
|
+
"archiver": "^7.0.1"
|
|
26
|
+
},
|
|
27
|
+
"devDependencies": {
|
|
28
|
+
"@types/archiver": "^6.0.3",
|
|
29
|
+
"@types/jest": "^29.5.0",
|
|
30
|
+
"@types/node": "^24.3.0",
|
|
31
|
+
"@types/yauzl": "^2.10.0",
|
|
32
|
+
"@types/winston": "^2.4.4",
|
|
33
|
+
"esbuild": "^0.28.1",
|
|
34
|
+
"jest": "^29.5.0",
|
|
35
|
+
"ts-jest": "^29.1.0",
|
|
36
|
+
"typescript": "^5.0.0"
|
|
37
|
+
},
|
|
38
|
+
"publishConfig": {
|
|
39
|
+
"access": "public"
|
|
40
|
+
},
|
|
41
|
+
"license": "MIT",
|
|
42
|
+
"engines": {
|
|
43
|
+
"node": ">=22.0.0"
|
|
44
|
+
}
|
|
45
|
+
}
|