@chargebee/chargebee-apps-shared 0.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (48) hide show
  1. package/LICENSE +24 -0
  2. package/README.md +113 -0
  3. package/SECURITY.md +8 -0
  4. package/dist/config/environment.d.ts +78 -0
  5. package/dist/config/environment.js +150 -0
  6. package/dist/config/path-resolver.d.ts +117 -0
  7. package/dist/config/path-resolver.js +247 -0
  8. package/dist/dependency/dependency-manager.d.ts +66 -0
  9. package/dist/dependency/dependency-manager.js +257 -0
  10. package/dist/errors.d.ts +8 -0
  11. package/dist/errors.js +17 -0
  12. package/dist/index.d.ts +19 -0
  13. package/dist/index.js +36 -0
  14. package/dist/libs/archive-service.d.ts +21 -0
  15. package/dist/libs/archive-service.js +145 -0
  16. package/dist/libs/file-management-service.d.ts +59 -0
  17. package/dist/libs/file-management-service.js +189 -0
  18. package/dist/libs/iparams-service.d.ts +69 -0
  19. package/dist/libs/iparams-service.js +136 -0
  20. package/dist/libs/template-service.d.ts +57 -0
  21. package/dist/libs/template-service.js +152 -0
  22. package/dist/logger/cb-logger.d.ts +56 -0
  23. package/dist/logger/cb-logger.js +13 -0
  24. package/dist/logger/internal-logger.d.ts +81 -0
  25. package/dist/logger/internal-logger.js +146 -0
  26. package/dist/node/file-system.d.ts +66 -0
  27. package/dist/node/file-system.js +76 -0
  28. package/dist/node/process.d.ts +30 -0
  29. package/dist/node/process.js +25 -0
  30. package/dist/sandbox/sandbox-context.d.ts +37 -0
  31. package/dist/sandbox/sandbox-context.js +48 -0
  32. package/dist/sandbox/sandbox-wrapper.d.ts +75 -0
  33. package/dist/sandbox/sandbox-wrapper.js +2 -0
  34. package/dist/types/common.d.ts +135 -0
  35. package/dist/types/common.js +20 -0
  36. package/dist/validator/iparam-constants.d.ts +49 -0
  37. package/dist/validator/iparam-constants.js +52 -0
  38. package/dist/validator/iparam-defns-validator.d.ts +46 -0
  39. package/dist/validator/iparam-defns-validator.js +291 -0
  40. package/dist/validator/iparams-inputs-validator.d.ts +62 -0
  41. package/dist/validator/iparams-inputs-validator.js +289 -0
  42. package/dist/validator/manifest-validator.d.ts +48 -0
  43. package/dist/validator/manifest-validator.js +138 -0
  44. package/dist/validator/package-validator.d.ts +27 -0
  45. package/dist/validator/package-validator.js +43 -0
  46. package/dist/validator/validator-utils.d.ts +13 -0
  47. package/dist/validator/validator-utils.js +26 -0
  48. 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.2",
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
+ }