🎩 You're Invited:Meet the Socket team at Black Hat in Las Vegas, August 3-6.RSVP
Sign In

@chargebee/chargebee-apps-shared

Package Overview
Dependencies
Maintainers
4
Versions
6
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@chargebee/chargebee-apps-shared - npm Package Compare versions

Comparing version
0.0.1
to
0.0.3
+1
-150
dist/config/environment.js

@@ -1,150 +0,1 @@

"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || (function () {
var ownKeys = function(o) {
ownKeys = Object.getOwnPropertyNames || function (o) {
var ar = [];
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
return ar;
};
return ownKeys(o);
};
return function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
__setModuleDefault(result, mod);
return result;
};
})();
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.EnvironmentConfig = exports.EnvironmentType = void 0;
const path_1 = __importDefault(require("path"));
const fs = __importStar(require("fs"));
/**
* Environment type enum
*/
var EnvironmentType;
(function (EnvironmentType) {
EnvironmentType["DEVELOPMENT"] = "development";
EnvironmentType["PRODUCTION"] = "production";
})(EnvironmentType || (exports.EnvironmentType = EnvironmentType = {}));
/**
* Environment configuration class that detects the current environment
* @class EnvironmentConfig
* @implements {IEnvironmentConfig}
*
* @description
* This class provides environment detection based on multiple indicators:
* 1. NODE_ENV environment variable
* 2. Presence of workspace structure (workspaces field in package.json)
* 3. Module resolution capability (can resolve published packages)
*
* @example
* ```typescript
* const envConfig = new EnvironmentConfig();
* if (envConfig.isDevelopment()) {
* console.log('Running in development mode');
* }
* ```
*/
class EnvironmentConfig {
constructor() {
this.environment = this.detectEnvironment();
}
/**
* Detects the current environment based on various indicators
* @returns {EnvironmentType} The detected environment type
* @private
*/
detectEnvironment() {
// Check NODE_ENV first
const nodeEnv = process.env['NODE_ENV']?.toLowerCase();
if (nodeEnv === 'production') {
return EnvironmentType.PRODUCTION;
}
if (nodeEnv === 'development') {
return EnvironmentType.DEVELOPMENT;
}
// If NODE_ENV is not set, detect based on workspace structure
// In development, we should be in a monorepo with workspaces
// In production, packages are published and installed independently
try {
const currentDir = __dirname;
const projectRoot = this.findProjectRoot(currentDir);
if (projectRoot) {
const packageJsonPath = path_1.default.join(projectRoot, 'package.json');
if (fs.existsSync(packageJsonPath)) {
const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, 'utf8'));
// If workspaces field exists, we're in development
if (packageJson.workspaces) {
return EnvironmentType.DEVELOPMENT;
}
}
}
}
catch (error) {
// If we can't find workspace structure, assume production
}
// Default to production if we can't determine
return EnvironmentType.PRODUCTION;
}
/**
* Finds the project root by traversing up the directory tree
* @param {string} startDir - Directory to start searching from
* @returns {string | null} Path to project root or null if not found
* @private
*/
findProjectRoot(startDir) {
let currentDir = startDir;
const root = path_1.default.parse(currentDir).root;
while (currentDir !== root) {
const packageJsonPath = path_1.default.join(currentDir, 'package.json');
if (fs.existsSync(packageJsonPath)) {
return currentDir;
}
currentDir = path_1.default.dirname(currentDir);
}
return null;
}
/**
* Gets the current environment type
* @returns {EnvironmentType} The current environment
*/
getEnvironment() {
return this.environment;
}
/**
* Checks if running in development mode
* @returns {boolean} True if in development mode
*/
isDevelopment() {
return this.environment === EnvironmentType.DEVELOPMENT;
}
/**
* Checks if running in production mode
* @returns {boolean} True if in production mode
*/
isProduction() {
return this.environment === EnvironmentType.PRODUCTION;
}
}
exports.EnvironmentConfig = EnvironmentConfig;
"use strict";var __createBinding=this&&this.__createBinding||(Object.create?(function(n,e,t,r){r===void 0&&(r=t);var o=Object.getOwnPropertyDescriptor(e,t);(!o||("get"in o?!e.__esModule:o.writable||o.configurable))&&(o={enumerable:!0,get:function(){return e[t]}}),Object.defineProperty(n,r,o)}):(function(n,e,t,r){r===void 0&&(r=t),n[r]=e[t]})),__setModuleDefault=this&&this.__setModuleDefault||(Object.create?(function(n,e){Object.defineProperty(n,"default",{enumerable:!0,value:e})}):function(n,e){n.default=e}),__importStar=this&&this.__importStar||(function(){var n=function(e){return n=Object.getOwnPropertyNames||function(t){var r=[];for(var o in t)Object.prototype.hasOwnProperty.call(t,o)&&(r[r.length]=o);return r},n(e)};return function(e){if(e&&e.__esModule)return e;var t={};if(e!=null)for(var r=n(e),o=0;o<r.length;o++)r[o]!=="default"&&__createBinding(t,e,r[o]);return __setModuleDefault(t,e),t}})(),__importDefault=this&&this.__importDefault||function(n){return n&&n.__esModule?n:{default:n}};Object.defineProperty(exports,"__esModule",{value:!0}),exports.EnvironmentConfig=exports.EnvironmentType=void 0;const path_1=__importDefault(require("path")),fs=__importStar(require("fs"));var EnvironmentType;(function(n){n.DEVELOPMENT="development",n.PRODUCTION="production"})(EnvironmentType||(exports.EnvironmentType=EnvironmentType={}));class EnvironmentConfig{constructor(){this.environment=this.detectEnvironment()}detectEnvironment(){const e=process.env.NODE_ENV?.toLowerCase();if(e==="production")return EnvironmentType.PRODUCTION;if(e==="development")return EnvironmentType.DEVELOPMENT;try{const t=__dirname,r=this.findProjectRoot(t);if(r){const o=path_1.default.join(r,"package.json");if(fs.existsSync(o)&&JSON.parse(fs.readFileSync(o,"utf8")).workspaces)return EnvironmentType.DEVELOPMENT}}catch{}return EnvironmentType.PRODUCTION}findProjectRoot(e){let t=e;const r=path_1.default.parse(t).root;for(;t!==r;){const o=path_1.default.join(t,"package.json");if(fs.existsSync(o))return t;t=path_1.default.dirname(t)}return null}getEnvironment(){return this.environment}isDevelopment(){return this.environment===EnvironmentType.DEVELOPMENT}isProduction(){return this.environment===EnvironmentType.PRODUCTION}}exports.EnvironmentConfig=EnvironmentConfig;

@@ -1,247 +0,1 @@

"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || (function () {
var ownKeys = function(o) {
ownKeys = Object.getOwnPropertyNames || function (o) {
var ar = [];
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
return ar;
};
return ownKeys(o);
};
return function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
__setModuleDefault(result, mod);
return result;
};
})();
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.PathResolver = exports.PathType = void 0;
const path_1 = __importDefault(require("path"));
const fs = __importStar(require("fs"));
const environment_1 = require("./environment");
/**
* Path type enum for different package paths
*/
var PathType;
(function (PathType) {
/** Root directory of the CLI workspace */
PathType["CLI_ROOT"] = "CLI_ROOT";
/** Private application distribution directory */
PathType["PRIVATE_APP_DIST"] = "PRIVATE_APP_DIST";
/** Private application root directory */
PathType["PRIVATE_APP_ROOT"] = "PRIVATE_APP_ROOT";
/** Public libs templates directory */
PathType["PUBLIC_LIBS_TEMPLATES"] = "PUBLIC_LIBS_TEMPLATES";
/** Public libs UI web directory */
PathType["PUBLIC_LIBS_UI_WEB"] = "PUBLIC_LIBS_UI_WEB";
})(PathType || (exports.PathType = PathType = {}));
/**
* Path resolver class for resolving paths based on environment
* @class PathResolver
* @implements {IPathResolver}
*
* @description
* This class provides centralized path resolution for all packages in the CLI.
* It detects the environment (development vs production) and resolves paths accordingly:
* - In development: Uses workspace-relative paths
* - In production: Uses require.resolve to find installed packages
*
* This eliminates the need for try-catch error handling scattered across the codebase.
*
* @example
* ```typescript
* const pathResolver = new PathResolver();
* const templatesDir = pathResolver.getPublicLibsTemplatesDir();
* console.log(`Templates directory: ${templatesDir}`);
* ```
*/
class PathResolver {
constructor(envConfig) {
this.cliRoot = null;
this.envConfig = envConfig || new environment_1.EnvironmentConfig();
}
/**
* Resolves a path based on the path type and environment
* @param {PathType} pathType - Type of path to resolve
* @returns {string} Resolved path
* @throws {Error} If path cannot be resolved
*/
resolvePath(pathType) {
switch (pathType) {
case PathType.CLI_ROOT:
return this.getCliRoot();
case PathType.PRIVATE_APP_DIST:
return this.getPrivateAppDistDir();
case PathType.PRIVATE_APP_ROOT:
return this.getPrivateAppRootDir();
case PathType.PUBLIC_LIBS_TEMPLATES:
return this.getPublicLibsTemplatesDir();
case PathType.PUBLIC_LIBS_UI_WEB:
return this.getPublicLibsUiWebDir();
default:
throw new Error(`Unknown path type: ${pathType}`);
}
}
/**
* Gets the CLI workspace root path
* @returns {string} Path to CLI workspace root
*/
getCliRoot() {
if (this.cliRoot) {
return this.cliRoot;
}
if (this.envConfig.isDevelopment()) {
// Development: Find the project root by looking for package.json with workspaces
this.cliRoot = this.findProjectRootWithWorkspaces(__dirname);
}
else {
// Production: Use the package installation directory
// In production, packages are installed via npm and there's no workspace structure
this.cliRoot = path_1.default.resolve(__dirname, '../..');
}
return this.cliRoot;
}
/**
* Gets the private application distribution directory path
* @returns {string} Path to private application dist directory
*/
getPrivateAppDistDir() {
if (this.envConfig.isDevelopment()) {
// Development: Use workspace path
const cliRoot = this.getCliRoot();
return path_1.default.join(cliRoot, 'packages', 'private-application', 'dist');
}
else {
// Production: Find the installed package
try {
const resolvedPath = require.resolve('@chargebee-private/chargebee-apps-private-application');
return path_1.default.dirname(resolvedPath);
}
catch (error) {
throw new Error('Failed to resolve private-application path. ' +
'Ensure @chargebee-private/chargebee-apps-private-application is installed.');
}
}
}
/**
* Gets the private application root directory path
* @returns {string} Path to private application root directory
*/
getPrivateAppRootDir() {
if (this.envConfig.isDevelopment()) {
// Development: Use workspace path
const cliRoot = this.getCliRoot();
return path_1.default.join(cliRoot, 'packages', 'private-application');
}
else {
// Production: Find the installed package root
try {
const packageJsonPath = require.resolve('@chargebee-private/chargebee-apps-private-application/package.json');
return path_1.default.dirname(packageJsonPath);
}
catch (error) {
throw new Error('Failed to resolve private-application root path. ' +
'Ensure @chargebee-private/chargebee-apps-private-application is installed.');
}
}
}
/**
* Gets the public libs templates directory path
* @returns {string} Path to public libs templates directory
*/
getPublicLibsTemplatesDir() {
if (this.envConfig.isDevelopment()) {
// Development: Use workspace path
const cliRoot = this.getCliRoot();
return path_1.default.join(cliRoot, 'packages', 'public-libs', 'templates');
}
else {
// Production: Find the installed package and get templates from package root
try {
const publicLibsPath = require.resolve('@chargebee/chargebee-apps-libs');
const packageRoot = path_1.default.dirname(path_1.default.dirname(publicLibsPath));
return path_1.default.join(packageRoot, 'templates');
}
catch (error) {
throw new Error('Failed to resolve public-libs templates path. ' +
'Ensure @chargebee/chargebee-apps-libs is installed.');
}
}
}
/**
* Gets the public libs UI web directory path
* @returns {string} Path to public libs UI web directory
*/
getPublicLibsUiWebDir() {
if (this.envConfig.isDevelopment()) {
// Development: Use workspace path
const cliRoot = this.getCliRoot();
return path_1.default.join(cliRoot, 'packages', 'public-libs', 'ui', 'web');
}
else {
// Production: Find the installed package and get UI from package root
try {
const publicLibsPath = require.resolve('@chargebee/chargebee-apps-libs');
const packageRoot = path_1.default.dirname(path_1.default.dirname(publicLibsPath));
return path_1.default.join(packageRoot, 'ui', 'web');
}
catch (error) {
throw new Error('Failed to resolve public-libs UI web path. ' +
'Ensure @chargebee/chargebee-apps-libs is installed.');
}
}
}
/**
* Finds the project root by looking for package.json with workspaces
* @param {string} startDir - Directory to start searching from
* @returns {string} Path to project root
* @throws {Error} If project root cannot be found
* @private
*/
findProjectRootWithWorkspaces(startDir) {
let currentDir = startDir;
const root = path_1.default.parse(currentDir).root;
while (currentDir !== root) {
const packageJsonPath = path_1.default.join(currentDir, 'package.json');
if (fs.existsSync(packageJsonPath)) {
try {
const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, 'utf8'));
if (packageJson.workspaces) {
return currentDir;
}
}
catch (error) {
// Continue searching if package.json is invalid
}
}
const parent = path_1.default.dirname(currentDir);
if (parent === currentDir) {
break;
}
currentDir = parent;
}
throw new Error('Could not find project root with workspaces');
}
}
exports.PathResolver = PathResolver;
"use strict";var __createBinding=this&&this.__createBinding||(Object.create?(function(r,e,t,i){i===void 0&&(i=t);var a=Object.getOwnPropertyDescriptor(e,t);(!a||("get"in a?!e.__esModule:a.writable||a.configurable))&&(a={enumerable:!0,get:function(){return e[t]}}),Object.defineProperty(r,i,a)}):(function(r,e,t,i){i===void 0&&(i=t),r[i]=e[t]})),__setModuleDefault=this&&this.__setModuleDefault||(Object.create?(function(r,e){Object.defineProperty(r,"default",{enumerable:!0,value:e})}):function(r,e){r.default=e}),__importStar=this&&this.__importStar||(function(){var r=function(e){return r=Object.getOwnPropertyNames||function(t){var i=[];for(var a in t)Object.prototype.hasOwnProperty.call(t,a)&&(i[i.length]=a);return i},r(e)};return function(e){if(e&&e.__esModule)return e;var t={};if(e!=null)for(var i=r(e),a=0;a<i.length;a++)i[a]!=="default"&&__createBinding(t,e,i[a]);return __setModuleDefault(t,e),t}})(),__importDefault=this&&this.__importDefault||function(r){return r&&r.__esModule?r:{default:r}};Object.defineProperty(exports,"__esModule",{value:!0}),exports.PathResolver=exports.PathType=void 0;const path_1=__importDefault(require("path")),fs=__importStar(require("fs")),environment_1=require("./environment");var PathType;(function(r){r.CLI_ROOT="CLI_ROOT",r.PRIVATE_APP_DIST="PRIVATE_APP_DIST",r.PRIVATE_APP_ROOT="PRIVATE_APP_ROOT",r.PUBLIC_LIBS_TEMPLATES="PUBLIC_LIBS_TEMPLATES",r.PUBLIC_LIBS_UI_WEB="PUBLIC_LIBS_UI_WEB"})(PathType||(exports.PathType=PathType={}));class PathResolver{constructor(e){this.cliRoot=null,this.envConfig=e||new environment_1.EnvironmentConfig}resolvePath(e){switch(e){case PathType.CLI_ROOT:return this.getCliRoot();case PathType.PRIVATE_APP_DIST:return this.getPrivateAppDistDir();case PathType.PRIVATE_APP_ROOT:return this.getPrivateAppRootDir();case PathType.PUBLIC_LIBS_TEMPLATES:return this.getPublicLibsTemplatesDir();case PathType.PUBLIC_LIBS_UI_WEB:return this.getPublicLibsUiWebDir();default:throw new Error(`Unknown path type: ${e}`)}}getCliRoot(){return this.cliRoot?this.cliRoot:(this.envConfig.isDevelopment()?this.cliRoot=this.findProjectRootWithWorkspaces(__dirname):this.cliRoot=path_1.default.resolve(__dirname,"../.."),this.cliRoot)}getPrivateAppDistDir(){if(this.envConfig.isDevelopment()){const e=this.getCliRoot();return path_1.default.join(e,"packages","private-application","dist")}else try{const e=require.resolve("@chargebee-private/chargebee-apps-private-application");return path_1.default.dirname(e)}catch{throw new Error("Failed to resolve private-application path. Ensure @chargebee-private/chargebee-apps-private-application is installed.")}}getPrivateAppRootDir(){if(this.envConfig.isDevelopment()){const e=this.getCliRoot();return path_1.default.join(e,"packages","private-application")}else try{const e=require.resolve("@chargebee-private/chargebee-apps-private-application/package.json");return path_1.default.dirname(e)}catch{throw new Error("Failed to resolve private-application root path. Ensure @chargebee-private/chargebee-apps-private-application is installed.")}}getPublicLibsTemplatesDir(){if(this.envConfig.isDevelopment()){const e=this.getCliRoot();return path_1.default.join(e,"packages","public-libs","templates")}else try{const e=require.resolve("@chargebee/chargebee-apps-libs"),t=path_1.default.dirname(path_1.default.dirname(e));return path_1.default.join(t,"templates")}catch{throw new Error("Failed to resolve public-libs templates path. Ensure @chargebee/chargebee-apps-libs is installed.")}}getPublicLibsUiWebDir(){if(this.envConfig.isDevelopment()){const e=this.getCliRoot();return path_1.default.join(e,"packages","public-libs","ui","web")}else try{const e=require.resolve("@chargebee/chargebee-apps-libs"),t=path_1.default.dirname(path_1.default.dirname(e));return path_1.default.join(t,"ui","web")}catch{throw new Error("Failed to resolve public-libs UI web path. Ensure @chargebee/chargebee-apps-libs is installed.")}}findProjectRootWithWorkspaces(e){let t=e;const i=path_1.default.parse(t).root;for(;t!==i;){const a=path_1.default.join(t,"package.json");if(fs.existsSync(a))try{if(JSON.parse(fs.readFileSync(a,"utf8")).workspaces)return t}catch{}const o=path_1.default.dirname(t);if(o===t)break;t=o}throw new Error("Could not find project root with workspaces")}}exports.PathResolver=PathResolver;

@@ -1,257 +0,1 @@

"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.DependencyManager = void 0;
const child_process_1 = require("child_process");
const path_1 = __importDefault(require("path"));
const semver_1 = __importDefault(require("semver"));
const internal_logger_1 = require("../logger/internal-logger");
/**
* DependencyManager handles isolated npm installations for user projects
* Public implementation for managing dependencies in development environment
*/
class DependencyManager {
constructor(fileSystem) {
this.fileSystem = fileSystem;
this.installed = false;
}
/**
* Ensures dependencies are installed for a user project
* @param {string} projectPath - Path to the user project directory
* @param {Manifest} manifest - The project manifest containing dependencies
* @returns {Promise<void>}
*/
async ensureDependencies(projectPath, manifest) {
if (!manifest.dependencies || Object.keys(manifest.dependencies).length === 0) {
internal_logger_1.__logger.debug('No dependencies to install');
return;
}
// Check if already installed
if (this.installed) {
internal_logger_1.__logger.debug('Dependencies already installed for this project');
return;
}
const handlerPath = path_1.default.join(projectPath, 'handler');
const packageJsonPath = path_1.default.join(handlerPath, 'package.json');
try {
// Create handler directory if it doesn't exist
if (!this.fileSystem.existsSync(handlerPath)) {
this.fileSystem.mkdirSync(handlerPath, { recursive: true });
}
// Create or update package.json
await this.createPackageJson(packageJsonPath, manifest.dependencies);
// Install dependencies
await this.installDependencies(handlerPath);
// Mark as installed
this.installed = true;
internal_logger_1.__logger.info(`Installed ${Object.keys(manifest.dependencies).length} dependencies for project`);
}
catch (error) {
const err = error;
internal_logger_1.__logger.error('Failed to install dependencies:', err.message);
throw new Error(`Dependency installation failed: ${err.message}`);
}
}
/**
* Creates a safe require function that uses isolated node_modules
* @param {string} projectPath - Path to the user project
* @param {AllowedModule[]} allowedModules - List of allowed modules
* @returns {Function} Safe require function
*/
createIsolatedRequire(projectPath, allowedModules) {
const handlerPath = path_1.default.resolve(projectPath, 'handler');
const nodeModulesPath = path_1.default.join(handlerPath, 'node_modules');
return (moduleName) => {
// Check if the module is a relative path
if (moduleName.startsWith('./')) {
// Normalize the path to prevent path traversal attacks
return this.getRelativePathRequire(moduleName, handlerPath);
}
// Handle direct CommonJS paths (e.g., 'axios/dist/node/axios.cjs')
if (moduleName.includes('/')) {
// Extract the base module name
return this.getGenericDependencyRequire(moduleName, allowedModules, nodeModulesPath);
}
// Verify version if constraint is specified
const resolvedModulePath = this.validateAndGetModulePath(allowedModules, nodeModulesPath, moduleName);
try {
// Check if this is an ES module that loaded but doesn't have the expected interface
// This happens when ES modules export named exports instead of a default function
// Try to load the module and handle ES module issues with cjs (if available) else fallback to the ES module
return this.tryLoadCommonJSAlternative(moduleName, resolvedModulePath);
}
catch (error) {
const err = error;
throw new Error(`Failed to load module "${moduleName}": ${err.message}`);
}
};
}
/**
* Creates or updates package.json for the project
* @param {string} packageJsonPath - Path to package.json
* @param {Record<string, string>} dependencies - Dependencies from manifest
*/
async createPackageJson(packageJsonPath, dependencies) {
const packageJson = {
dependencies: { ...dependencies }
};
const content = JSON.stringify(packageJson, null, 2);
this.fileSystem.writeFileSync(packageJsonPath, content);
internal_logger_1.__logger.debug('Created/updated package.json');
}
/**
* Installs dependencies using npm
* @param {string} handlerPath - Path to the handler directory
*/
async installDependencies(handlerPath) {
try {
(0, child_process_1.execSync)('npm install --ignore-scripts --no-audit --no-fund --loglevel=error', {
cwd: handlerPath,
stdio: 'pipe',
timeout: 60000 // 60 second timeout
});
internal_logger_1.__logger.debug('npm install completed successfully');
}
catch (error) {
const err = error;
throw new Error(`npm install failed: ${err.message}`);
}
}
/**
* Tries to load a CommonJS alternative for an ES module. This is a fallback for when the common JS is not the default export.
* @param moduleName - Name of the module to require
* @param resolvedModulePath - Path to the resolved module
* @returns
*/
tryLoadCommonJSAlternative(moduleName, resolvedModulePath) {
const module = require(resolvedModulePath);
if (module && typeof module === 'object' && module.__esModule && typeof module !== 'function') {
internal_logger_1.__logger.debug(`ES module detected for ${moduleName} (loaded but has named exports), looking for CommonJS alternative`);
const packageJsonPath = path_1.default.join(resolvedModulePath, 'package.json');
if (this.fileSystem.existsSync(packageJsonPath)) {
const packageJson = JSON.parse(this.fileSystem.readFileSync(packageJsonPath, 'utf8'));
// Try to find CommonJS export from package.json exports
if (packageJson.exports && packageJson.exports['.']) {
const exports = packageJson.exports['.'];
// Try direct require field
if (exports.require) {
const cjsPath = path_1.default.resolve(resolvedModulePath, exports.require);
internal_logger_1.__logger.debug(`Trying CommonJS path: ${exports.require}`);
return require(cjsPath);
}
// Try nested default.require (like axios)
if (exports.default && exports.default.require) {
const cjsPath = path_1.default.resolve(resolvedModulePath, exports.default.require);
internal_logger_1.__logger.debug(`Trying default CommonJS path: ${exports.default.require}`);
return require(cjsPath);
}
}
// Try to find CommonJS entry point from main field
if (packageJson.main) {
const mainPath = path_1.default.resolve(resolvedModulePath, packageJson.main);
internal_logger_1.__logger.debug(`Trying main field: ${packageJson.main}`);
return require(mainPath);
}
}
// If we can't find a CommonJS alternative, return the ES module as-is
internal_logger_1.__logger.error(`No CommonJS alternative found for ${moduleName}, using ES module as-is`);
return module;
}
return module;
}
/**
* Gets the relative path require.
* @param moduleName - Name of the module to require
* @param handlerPath - Path to the handler directory
* @returns
*/
getRelativePathRequire(moduleName, handlerPath) {
const normalizedPath = path_1.default.normalize(moduleName);
// Check for any path traversal attempts after normalization
if (normalizedPath.includes('..')) {
throw new Error('Path traversal not allowed in relative imports');
}
// Resolve the path relative to handlerPath
const resolvedPath = path_1.default.resolve(handlerPath, normalizedPath);
// Validate that the resolved path is within the handlerPath directory
if (!resolvedPath.startsWith(handlerPath)) {
throw new Error('Relative import path resolves outside of handler directory');
}
// Check if the file exists and determine the correct path to require
let finalPath = resolvedPath;
if (!this.fileSystem.existsSync(resolvedPath)) {
const jsPath = resolvedPath + ".js";
if (this.fileSystem.existsSync(jsPath)) {
finalPath = jsPath; // Use the .js path that actually exists
}
else {
throw new Error(`File or module not found: ${moduleName}`);
}
}
return require(finalPath);
}
/**
* Gets the generic dependency require. Unless there are special cases like ES modules, this should work for all dependencies.
* @param moduleName - Name of the module to require
* @param allowedModules - List of allowed modules
* @param nodeModulesPath - Path to the node_modules directory
* @returns
*/
getGenericDependencyRequire(moduleName, allowedModules, nodeModulesPath) {
const baseModuleName = moduleName.split('/')[0];
// Check if the base module is allowed
const allowedModule = allowedModules.find(module => module.name === baseModuleName);
if (!allowedModule) {
throw new Error(`Module "${baseModuleName}" is not allowed in this environment`);
}
// Check if the full path exists in project's node_modules
const fullModulePath = path_1.default.join(nodeModulesPath, moduleName);
if (!this.fileSystem.existsSync(fullModulePath)) {
throw new Error(`Module path "${moduleName}" is not installed. Please ensure dependencies are installed.`);
}
internal_logger_1.__logger.debug(`Loading CommonJS path: ${moduleName}`);
return require(path_1.default.resolve(fullModulePath));
}
/**
* Validates and gets the resolved path to the module.
* @param allowedModules - List of allowed modules
* @param nodeModulesPath - Path to the node_modules directory
* @param moduleName - Name of the module to validate
* @returns Path to the module
*/
validateAndGetModulePath(allowedModules, nodeModulesPath, moduleName) {
// Check if module is installed in project's node_modules
const modulePath = path_1.default.join(nodeModulesPath, moduleName);
if (!this.fileSystem.existsSync(modulePath)) {
throw new Error(`Module "${moduleName}" is not installed. Please ensure dependencies are installed.`);
}
// Check if module is allowed
const allowedModule = allowedModules.find(module => module.name === moduleName);
if (!allowedModule) {
throw new Error(`Module "${moduleName}" is not allowed in this environment`);
}
if (allowedModule.version) {
try {
const packageJsonPath = path_1.default.join(modulePath, 'package.json');
const packageJson = JSON.parse(this.fileSystem.readFileSync(packageJsonPath, 'utf8'));
const installedVersion = packageJson.version;
if (!semver_1.default.satisfies(installedVersion, allowedModule.version)) {
throw new Error(`Module "${moduleName}" version ${installedVersion} does not satisfy allowed version constraint ${allowedModule.version}`);
}
internal_logger_1.__logger.debug(`Module "${moduleName}" version ${installedVersion} satisfies constraint ${allowedModule.version}`);
}
catch (error) {
const err = error;
internal_logger_1.__logger.warn(`Warning: Could not verify version for module "${moduleName}":`, err.message);
}
}
else {
throw new Error(`Configuration error: Allowed module "${moduleName}" does not have a version constraint`);
}
// Fallback to the module path, might or might not work for some dependencies.
return path_1.default.resolve(modulePath);
}
}
exports.DependencyManager = DependencyManager;
"use strict";var __importDefault=this&&this.__importDefault||function(a){return a&&a.__esModule?a:{default:a}};Object.defineProperty(exports,"__esModule",{value:!0}),exports.DependencyManager=void 0;const child_process_1=require("child_process"),path_1=__importDefault(require("path")),semver_1=__importDefault(require("semver")),internal_logger_1=require("../logger/internal-logger");class DependencyManager{constructor(s){this.fileSystem=s,this.installed=!1}async ensureDependencies(s,n){if(!n.dependencies||Object.keys(n.dependencies).length===0){internal_logger_1.__logger.debug("No dependencies to install");return}if(this.installed){internal_logger_1.__logger.debug("Dependencies already installed for this project");return}const e=path_1.default.join(s,"handler"),i=path_1.default.join(e,"package.json");try{this.fileSystem.existsSync(e)||this.fileSystem.mkdirSync(e,{recursive:!0}),await this.createPackageJson(i,n.dependencies),await this.installDependencies(e),this.installed=!0,internal_logger_1.__logger.info(`Installed ${Object.keys(n.dependencies).length} dependencies for project`)}catch(t){const r=t;throw internal_logger_1.__logger.error("Failed to install dependencies:",r.message),new Error(`Dependency installation failed: ${r.message}`)}}createIsolatedRequire(s,n){const e=path_1.default.resolve(s,"handler"),i=path_1.default.join(e,"node_modules");return t=>{if(t.startsWith("./"))return this.getRelativePathRequire(t,e);if(t.includes("/"))return this.getGenericDependencyRequire(t,n,i);const r=this.validateAndGetModulePath(n,i,t);try{return this.tryLoadCommonJSAlternative(t,r)}catch(o){const l=o;throw new Error(`Failed to load module "${t}": ${l.message}`)}}}async createPackageJson(s,n){const e={dependencies:{...n}},i=JSON.stringify(e,null,2);this.fileSystem.writeFileSync(s,i),internal_logger_1.__logger.debug("Created/updated package.json")}async installDependencies(s){try{(0,child_process_1.execSync)("npm install --ignore-scripts --no-audit --no-fund --loglevel=error",{cwd:s,stdio:"pipe",timeout:6e4}),internal_logger_1.__logger.debug("npm install completed successfully")}catch(n){const e=n;throw new Error(`npm install failed: ${e.message}`)}}tryLoadCommonJSAlternative(s,n){const e=require(n);if(e&&typeof e=="object"&&e.__esModule&&typeof e!="function"){internal_logger_1.__logger.debug(`ES module detected for ${s} (loaded but has named exports), looking for CommonJS alternative`);const i=path_1.default.join(n,"package.json");if(this.fileSystem.existsSync(i)){const t=JSON.parse(this.fileSystem.readFileSync(i,"utf8"));if(t.exports&&t.exports["."]){const r=t.exports["."];if(r.require){const o=path_1.default.resolve(n,r.require);return internal_logger_1.__logger.debug(`Trying CommonJS path: ${r.require}`),require(o)}if(r.default&&r.default.require){const o=path_1.default.resolve(n,r.default.require);return internal_logger_1.__logger.debug(`Trying default CommonJS path: ${r.default.require}`),require(o)}}if(t.main){const r=path_1.default.resolve(n,t.main);return internal_logger_1.__logger.debug(`Trying main field: ${t.main}`),require(r)}}return internal_logger_1.__logger.error(`No CommonJS alternative found for ${s}, using ES module as-is`),e}return e}getRelativePathRequire(s,n){const e=path_1.default.normalize(s);if(e.includes(".."))throw new Error("Path traversal not allowed in relative imports");const i=path_1.default.resolve(n,e);if(!i.startsWith(n))throw new Error("Relative import path resolves outside of handler directory");let t=i;if(!this.fileSystem.existsSync(i)){const r=i+".js";if(this.fileSystem.existsSync(r))t=r;else throw new Error(`File or module not found: ${s}`)}return require(t)}getGenericDependencyRequire(s,n,e){const i=s.split("/")[0];if(!n.find(o=>o.name===i))throw new Error(`Module "${i}" is not allowed in this environment`);const r=path_1.default.join(e,s);if(!this.fileSystem.existsSync(r))throw new Error(`Module path "${s}" is not installed. Please ensure dependencies are installed.`);return internal_logger_1.__logger.debug(`Loading CommonJS path: ${s}`),require(path_1.default.resolve(r))}validateAndGetModulePath(s,n,e){const i=path_1.default.join(n,e);if(!this.fileSystem.existsSync(i))throw new Error(`Module "${e}" is not installed. Please ensure dependencies are installed.`);const t=s.find(r=>r.name===e);if(!t)throw new Error(`Module "${e}" is not allowed in this environment`);if(t.version)try{const r=path_1.default.join(i,"package.json"),l=JSON.parse(this.fileSystem.readFileSync(r,"utf8")).version;if(!semver_1.default.satisfies(l,t.version))throw new Error(`Module "${e}" version ${l} does not satisfy allowed version constraint ${t.version}`);internal_logger_1.__logger.debug(`Module "${e}" version ${l} satisfies constraint ${t.version}`)}catch(r){const o=r;internal_logger_1.__logger.warn(`Warning: Could not verify version for module "${e}":`,o.message)}else throw new Error(`Configuration error: Allowed module "${e}" does not have a version constraint`);return path_1.default.resolve(i)}}exports.DependencyManager=DependencyManager;

@@ -1,17 +0,1 @@

"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.MissingRequiredParamsError = void 0;
/**
* Error thrown when required installation parameters are missing.
* Carries the list of missing parameter names for API responses.
*/
class MissingRequiredParamsError extends Error {
constructor(missing) {
const params = missing.join(', ');
super(`Missing required parameter${missing.length > 1 ? 's' : ''}: ${params}`);
this.name = 'MissingRequiredParamsError';
this.missing = missing;
Object.setPrototypeOf(this, MissingRequiredParamsError.prototype);
}
}
exports.MissingRequiredParamsError = MissingRequiredParamsError;
"use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.MissingRequiredParamsError=void 0;class MissingRequiredParamsError extends Error{constructor(r){const e=r.join(", ");super(`Missing required parameter${r.length>1?"s":""}: ${e}`),this.name="MissingRequiredParamsError",this.missing=r,Object.setPrototypeOf(this,MissingRequiredParamsError.prototype)}}exports.MissingRequiredParamsError=MissingRequiredParamsError;

@@ -1,36 +0,1 @@

"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __exportStar = (this && this.__exportStar) || function(m, exports) {
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
};
Object.defineProperty(exports, "__esModule", { value: true });
// Export all shared interfaces and types
__exportStar(require("./config/environment"), exports);
__exportStar(require("./errors"), exports);
__exportStar(require("./config/path-resolver"), exports);
__exportStar(require("./dependency/dependency-manager"), exports);
__exportStar(require("./libs/archive-service"), exports);
__exportStar(require("./libs/file-management-service"), exports);
__exportStar(require("./libs/iparams-service"), exports);
__exportStar(require("./libs/template-service"), exports);
__exportStar(require("./logger/cb-logger"), exports);
__exportStar(require("./logger/internal-logger"), exports);
__exportStar(require("./node/file-system"), exports);
__exportStar(require("./node/process"), exports);
__exportStar(require("./sandbox/sandbox-context"), exports);
__exportStar(require("./sandbox/sandbox-wrapper"), exports);
__exportStar(require("./types/common"), exports);
__exportStar(require("./validator/manifest-validator"), exports);
__exportStar(require("./validator/package-validator"), exports);
__exportStar(require("./validator/iparams-inputs-validator"), exports);
__exportStar(require("./validator/iparam-defns-validator"), exports);
"use strict";var __createBinding=this&&this.__createBinding||(Object.create?(function(i,r,e,t){t===void 0&&(t=e);var o=Object.getOwnPropertyDescriptor(r,e);(!o||("get"in o?!r.__esModule:o.writable||o.configurable))&&(o={enumerable:!0,get:function(){return r[e]}}),Object.defineProperty(i,t,o)}):(function(i,r,e,t){t===void 0&&(t=e),i[t]=r[e]})),__exportStar=this&&this.__exportStar||function(i,r){for(var e in i)e!=="default"&&!Object.prototype.hasOwnProperty.call(r,e)&&__createBinding(r,i,e)};Object.defineProperty(exports,"__esModule",{value:!0}),__exportStar(require("./config/environment"),exports),__exportStar(require("./errors"),exports),__exportStar(require("./config/path-resolver"),exports),__exportStar(require("./dependency/dependency-manager"),exports),__exportStar(require("./libs/archive-service"),exports),__exportStar(require("./libs/file-management-service"),exports),__exportStar(require("./libs/iparams-service"),exports),__exportStar(require("./libs/template-service"),exports),__exportStar(require("./logger/cb-logger"),exports),__exportStar(require("./logger/internal-logger"),exports),__exportStar(require("./node/file-system"),exports),__exportStar(require("./node/process"),exports),__exportStar(require("./sandbox/sandbox-context"),exports),__exportStar(require("./sandbox/sandbox-wrapper"),exports),__exportStar(require("./types/common"),exports),__exportStar(require("./validator/manifest-validator"),exports),__exportStar(require("./validator/package-validator"),exports),__exportStar(require("./validator/iparams-inputs-validator"),exports),__exportStar(require("./validator/iparam-defns-validator"),exports);

@@ -1,145 +0,1 @@

"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || (function () {
var ownKeys = function(o) {
ownKeys = Object.getOwnPropertyNames || function (o) {
var ar = [];
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
return ar;
};
return ownKeys(o);
};
return function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
__setModuleDefault(result, mod);
return result;
};
})();
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.ArchiveService = void 0;
const archiver_1 = __importDefault(require("archiver"));
const path_1 = __importDefault(require("path"));
const internal_logger_1 = require("../logger/internal-logger");
const yauzl = __importStar(require("yauzl"));
const fs_1 = __importDefault(require("fs"));
const fs_2 = require("fs");
/**
* Archive service for managing zip file creation and extraction
*/
class ArchiveService {
constructor(fileSystem) {
this.fileSystem = fileSystem;
}
/**
* Creates the zip package
* @param {string[]} files - Array of files to package
* @param {string} appDir - The application directory
* @param {string} outputPath - The output path for the package
*/
createZipPackage(files, appDir, outputPath) {
return new Promise((resolve, reject) => {
const output = this.fileSystem.createWriteStream(outputPath);
const archive = (0, archiver_1.default)('zip');
output.on('close', () => {
internal_logger_1.__logger.info(`Archive created: ${archive.pointer()} total bytes`);
resolve();
});
output.on('error', (err) => {
internal_logger_1.__logger.error('Error writing to output file:', err);
reject(err);
});
archive.on('error', (err) => {
internal_logger_1.__logger.error('Error creating archive:', err);
reject(err);
});
archive.pipe(output);
// Add files to the archive
files.forEach(file => {
const filePath = path_1.default.join(appDir, file);
if (this.fileSystem.existsSync(filePath)) {
archive.file(filePath, { name: file });
internal_logger_1.__logger.info(` - Added: ${file}`);
}
});
archive.finalize();
});
}
/**
* Extract zip file to specified directory using yauzl
* @param {string} zipFilePath - Path to the zip file
* @param {string} extractDir - Directory to extract contents to
*/
extractZipFile(zipFilePath, extractDir) {
return new Promise((resolve, reject) => {
yauzl.open(zipFilePath, { lazyEntries: true }, (err, zipfile) => {
if (err) {
internal_logger_1.__logger.error('Error opening zip file:', err);
reject(err);
return;
}
zipfile.readEntry();
zipfile.on('entry', (entry) => {
if (/\/$/.test(entry.fileName)) {
// Directory entry
const dirPath = path_1.default.join(extractDir, entry.fileName);
fs_1.default.mkdirSync(dirPath, { recursive: true });
zipfile.readEntry();
}
else {
// File entry
zipfile.openReadStream(entry, (err, readStream) => {
if (err) {
internal_logger_1.__logger.error('Error opening read stream:', err);
reject(err);
return;
}
const filePath = path_1.default.join(extractDir, entry.fileName);
const dirPath = path_1.default.dirname(filePath);
// Ensure directory exists
fs_1.default.mkdirSync(dirPath, { recursive: true });
const writeStream = (0, fs_2.createWriteStream)(filePath);
readStream.pipe(writeStream);
writeStream.on('close', () => {
internal_logger_1.__logger.info(`Extracted: ${entry.fileName}`);
zipfile.readEntry();
});
writeStream.on('error', (err) => {
internal_logger_1.__logger.error('Error writing to file:', err);
reject(err);
});
});
}
});
zipfile.on('end', () => {
internal_logger_1.__logger.info('Extraction completed');
resolve();
});
zipfile.on('error', (err) => {
internal_logger_1.__logger.error('Error processing zip file:', err);
reject(err);
});
});
});
}
}
exports.ArchiveService = ArchiveService;
"use strict";var __createBinding=this&&this.__createBinding||(Object.create?(function(i,e,n,t){t===void 0&&(t=n);var r=Object.getOwnPropertyDescriptor(e,n);(!r||("get"in r?!e.__esModule:r.writable||r.configurable))&&(r={enumerable:!0,get:function(){return e[n]}}),Object.defineProperty(i,t,r)}):(function(i,e,n,t){t===void 0&&(t=n),i[t]=e[n]})),__setModuleDefault=this&&this.__setModuleDefault||(Object.create?(function(i,e){Object.defineProperty(i,"default",{enumerable:!0,value:e})}):function(i,e){i.default=e}),__importStar=this&&this.__importStar||(function(){var i=function(e){return i=Object.getOwnPropertyNames||function(n){var t=[];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(t[t.length]=r);return t},i(e)};return function(e){if(e&&e.__esModule)return e;var n={};if(e!=null)for(var t=i(e),r=0;r<t.length;r++)t[r]!=="default"&&__createBinding(n,e,t[r]);return __setModuleDefault(n,e),n}})(),__importDefault=this&&this.__importDefault||function(i){return i&&i.__esModule?i:{default:i}};Object.defineProperty(exports,"__esModule",{value:!0}),exports.ArchiveService=void 0;const archiver_1=__importDefault(require("archiver")),path_1=__importDefault(require("path")),internal_logger_1=require("../logger/internal-logger"),yauzl=__importStar(require("yauzl")),fs_1=__importDefault(require("fs")),fs_2=require("fs");class ArchiveService{constructor(e){this.fileSystem=e}createZipPackage(e,n,t){return new Promise((r,c)=>{const u=this.fileSystem.createWriteStream(t),a=(0,archiver_1.default)("zip");u.on("close",()=>{internal_logger_1.__logger.info(`Archive created: ${a.pointer()} total bytes`),r()}),u.on("error",o=>{internal_logger_1.__logger.error("Error writing to output file:",o),c(o)}),a.on("error",o=>{internal_logger_1.__logger.error("Error creating archive:",o),c(o)}),a.pipe(u),e.forEach(o=>{const l=path_1.default.join(n,o);this.fileSystem.existsSync(l)&&(a.file(l,{name:o}),internal_logger_1.__logger.info(` - Added: ${o}`))}),a.finalize()})}extractZipFile(e,n){return new Promise((t,r)=>{yauzl.open(e,{lazyEntries:!0},(c,u)=>{if(c){internal_logger_1.__logger.error("Error opening zip file:",c),r(c);return}u.readEntry(),u.on("entry",a=>{if(/\/$/.test(a.fileName)){const o=path_1.default.join(n,a.fileName);fs_1.default.mkdirSync(o,{recursive:!0}),u.readEntry()}else u.openReadStream(a,(o,l)=>{if(o){internal_logger_1.__logger.error("Error opening read stream:",o),r(o);return}const f=path_1.default.join(n,a.fileName),g=path_1.default.dirname(f);fs_1.default.mkdirSync(g,{recursive:!0});const s=(0,fs_2.createWriteStream)(f);l.pipe(s),s.on("close",()=>{internal_logger_1.__logger.info(`Extracted: ${a.fileName}`),u.readEntry()}),s.on("error",_=>{internal_logger_1.__logger.error("Error writing to file:",_),r(_)})})}),u.on("end",()=>{internal_logger_1.__logger.info("Extraction completed"),t()}),u.on("error",a=>{internal_logger_1.__logger.error("Error processing zip file:",a),r(a)})})})}}exports.ArchiveService=ArchiveService;

@@ -1,189 +0,1 @@

"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.FileManagementService = void 0;
const internal_logger_1 = require("../logger/internal-logger");
const path_1 = __importDefault(require("path"));
/**
* File management service for handling file operations
*/
class FileManagementService {
constructor(fileSystem, packageConfig) {
this.fileSystem = fileSystem;
this.packageConfig = packageConfig;
}
/**
* Collects essential files for the serverless application package
* Only includes files and directories specified in packageConfig
* @param {string} appDir - The application directory
* @returns {string[]} Array of file paths to package
*/
collectFilesToPackage(appDir) {
const files = [];
// Process directories specified in packageConfig
this.packageConfig.include.directories.forEach(dirConfig => {
if (dirConfig.name === '.') {
// Handle root directory case - collect files directly from appDir
const rootFiles = this.getFilesRecursively(appDir, dirConfig);
files.push(...rootFiles);
}
else {
// Handle subdirectory case
const dirPath = path_1.default.join(appDir, dirConfig.name);
if (this.fileSystem.existsSync(dirPath)) {
const dirFiles = this.getFilesRecursively(dirPath, dirConfig);
// Add directory files with directory prefix
dirFiles.forEach((file) => {
files.push(`${dirConfig.name}/${file}`);
});
}
else {
throw new Error(`Directory ${dirPath} does not exist`);
}
}
});
internal_logger_1.__logger.info(`Collected ${files.length} files to package`);
internal_logger_1.__logger.info(` - Directories: ${this.packageConfig.include.directories.map(d => d.name).join(', ')}`);
return files;
}
/**
* Cleans all files and folders inside the dist directory
* @param {string} appDir - The application directory
*/
cleanExistingPackages(appDir) {
const distDir = path_1.default.join(appDir, 'dist');
if (!this.fileSystem.existsSync(distDir)) {
this.fileSystem.mkdirSync(distDir, { recursive: true });
return;
}
const files = this.fileSystem.readdirSync(distDir);
if (files.length > 0) {
internal_logger_1.__logger.info(`Cleaning ${files.length} item(s) in dist directory...`);
files.forEach(item => {
const itemPath = path_1.default.join(distDir, item);
const stat = this.fileSystem.statSync(itemPath);
if (stat.isDirectory()) {
this.deleteDirectoryRecursively(itemPath);
internal_logger_1.__logger.info(` - Removed directory: ${item}/`);
}
else {
this.fileSystem.unlinkSync(itemPath);
}
});
}
}
/**
* Determines the output path for the package
* @param {string} appDir - The application directory
* @param {string} appName - The application name
* @param {PackageOptions} options - Package options
* @returns {string} The output path for the package
*/
determineOutputPath(appDir, appName, packageName) {
const distDir = path_1.default.join(appDir, 'dist');
packageName = packageName || appName;
const zipFileName = `${packageName}.zip`;
return path_1.default.join(distDir, zipFileName);
}
/**
* Gets the file size in a human-readable format
* @param {string} filePath - The file path
* @returns {string} Human-readable file size
*/
getFileSize(filePath) {
const stats = this.fileSystem.statSync(filePath);
const bytes = stats.size;
if (bytes === 0) {
return '0 Bytes';
}
const k = 1024;
const sizes = ['Bytes', 'KB', 'MB', 'GB'];
const i = Math.floor(Math.log(bytes) / Math.log(k));
return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i];
}
/**
* Collects files recursively from a directory based on directory-specific configurations
* @param {string} dir - The directory to scan
* @param {DirectoryConfig} dirConfig - Directory configuration with file inclusion/exclusion rules
* @returns {string[]} Array of file paths relative to the scanned directory
*/
getFilesRecursively(dir, dirConfig) {
const files = [];
// Get configuration values
const allowedExtensions = dirConfig.allowedExtensions || [];
const excludeSubdirs = dirConfig.excludeSubdirs || [];
const includeFiles = dirConfig.includeFiles || [];
const excludeFiles = dirConfig.excludeFiles || [];
const scanDirectory = (currentDir, baseDir) => {
const items = this.fileSystem.readdirSync(currentDir);
for (const item of items) {
const itemPath = path_1.default.join(currentDir, item);
const lstat = this.fileSystem.lstatSync(itemPath);
// Skip symlinks — they may be broken (e.g. .bin/ entries in Docker overlay fs)
if (lstat.isSymbolicLink()) {
continue;
}
const stat = this.fileSystem.statSync(itemPath);
if (stat.isDirectory()) {
// Skip excluded subdirectories
if (!excludeSubdirs.includes(item)) {
scanDirectory(itemPath, baseDir);
}
}
else {
// Apply file inclusion/exclusion logic
if (item && typeof item === 'string') {
const relativePath = path_1.default.relative(baseDir, itemPath);
let shouldInclude = false;
// Priority 1: Check specific file inclusion (highest priority)
if (includeFiles.length > 0) {
shouldInclude = includeFiles.includes(item);
}
// Priority 2: Check extension-based inclusion (if no specific files defined)
else if (allowedExtensions.length > 0) {
const ext = path_1.default.extname(item).toLowerCase();
shouldInclude = allowedExtensions.includes(ext);
}
// Priority 3: Include all files if no inclusion rules defined
else {
shouldInclude = true;
}
// Apply exclusion rules (always applied if file was included)
if (shouldInclude && excludeFiles.length > 0) {
shouldInclude = !excludeFiles.includes(item);
}
if (shouldInclude) {
files.push(relativePath);
}
}
}
}
};
if (this.fileSystem.existsSync(dir)) {
scanDirectory(dir, dir);
}
return files;
}
/**
* Recursively deletes a directory and all its contents
* @param {string} dirPath - The directory path to delete
*/
deleteDirectoryRecursively(dirPath) {
const files = this.fileSystem.readdirSync(dirPath);
for (const file of files) {
const filePath = path_1.default.join(dirPath, file);
const stat = this.fileSystem.statSync(filePath);
if (stat.isDirectory()) {
this.deleteDirectoryRecursively(filePath);
}
else {
this.fileSystem.unlinkSync(filePath);
}
}
// Remove the empty directory
this.fileSystem.rmdirSync(dirPath);
}
}
exports.FileManagementService = FileManagementService;
"use strict";var __importDefault=this&&this.__importDefault||function(r){return r&&r.__esModule?r:{default:r}};Object.defineProperty(exports,"__esModule",{value:!0}),exports.FileManagementService=void 0;const internal_logger_1=require("../logger/internal-logger"),path_1=__importDefault(require("path"));class FileManagementService{constructor(i,t){this.fileSystem=i,this.packageConfig=t}collectFilesToPackage(i){const t=[];return this.packageConfig.include.directories.forEach(e=>{if(e.name==="."){const s=this.getFilesRecursively(i,e);t.push(...s)}else{const s=path_1.default.join(i,e.name);if(this.fileSystem.existsSync(s))this.getFilesRecursively(s,e).forEach(n=>{t.push(`${e.name}/${n}`)});else throw new Error(`Directory ${s} does not exist`)}}),internal_logger_1.__logger.info(`Collected ${t.length} files to package`),internal_logger_1.__logger.info(` - Directories: ${this.packageConfig.include.directories.map(e=>e.name).join(", ")}`),t}cleanExistingPackages(i){const t=path_1.default.join(i,"dist");if(!this.fileSystem.existsSync(t)){this.fileSystem.mkdirSync(t,{recursive:!0});return}const e=this.fileSystem.readdirSync(t);e.length>0&&(internal_logger_1.__logger.info(`Cleaning ${e.length} item(s) in dist directory...`),e.forEach(s=>{const l=path_1.default.join(t,s);this.fileSystem.statSync(l).isDirectory()?(this.deleteDirectoryRecursively(l),internal_logger_1.__logger.info(` - Removed directory: ${s}/`)):this.fileSystem.unlinkSync(l)}))}determineOutputPath(i,t,e){const s=path_1.default.join(i,"dist");e=e||t;const l=`${e}.zip`;return path_1.default.join(s,l)}getFileSize(i){const e=this.fileSystem.statSync(i).size;if(e===0)return"0 Bytes";const s=1024,l=["Bytes","KB","MB","GB"],n=Math.floor(Math.log(e)/Math.log(s));return parseFloat((e/Math.pow(s,n)).toFixed(2))+" "+l[n]}getFilesRecursively(i,t){const e=[],s=t.allowedExtensions||[],l=t.excludeSubdirs||[],n=t.includeFiles||[],f=t.excludeFiles||[],u=(y,h)=>{const d=this.fileSystem.readdirSync(y);for(const o of d){const a=path_1.default.join(y,o);if(this.fileSystem.lstatSync(a).isSymbolicLink())continue;if(this.fileSystem.statSync(a).isDirectory())l.includes(o)||u(a,h);else if(o&&typeof o=="string"){const S=path_1.default.relative(h,a);let c=!1;if(n.length>0)c=n.includes(o);else if(s.length>0){const g=path_1.default.extname(o).toLowerCase();c=s.includes(g)}else c=!0;c&&f.length>0&&(c=!f.includes(o)),c&&e.push(S)}}};return this.fileSystem.existsSync(i)&&u(i,i),e}deleteDirectoryRecursively(i){const t=this.fileSystem.readdirSync(i);for(const e of t){const s=path_1.default.join(i,e);this.fileSystem.statSync(s).isDirectory()?this.deleteDirectoryRecursively(s):this.fileSystem.unlinkSync(s)}this.fileSystem.rmdirSync(i)}}exports.FileManagementService=FileManagementService;

@@ -1,136 +0,1 @@

"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.IparamsService = void 0;
const path_1 = __importDefault(require("path"));
const errors_1 = require("../errors");
const iparams_inputs_validator_1 = require("../validator/iparams-inputs-validator");
const iparam_defns_validator_1 = require("../validator/iparam-defns-validator");
const validator_utils_1 = require("../validator/validator-utils");
/**
* Service for managing parameters
* Handles loading, validation, and management of iparams and inputs
*/
class IparamsService {
constructor(fileSystem) {
this.fileSystem = fileSystem;
this.iparamDefnsValidator = new iparam_defns_validator_1.IparamDefnsValidator(fileSystem);
this.inputsValidator = new iparams_inputs_validator_1.IparamInputsValidator(fileSystem);
}
getIparamsFilePath(appDir) {
return path_1.default.join(appDir, 'iparams.json');
}
getInputsFilePath(appDir) {
return path_1.default.join(appDir, 'iparams.local.json');
}
/**
* Checks if iparams.json file exists
* @param {string} appDir - The application directory
* @returns {boolean} True if the file exists
*/
iparamsFileExists(appDir) {
return this.fileSystem.existsSync(this.getIparamsFilePath(appDir));
}
/**
* Loads and validates the iparamDefns
* @param {string} appDir - The application directory
* @returns {IparamDefns} The validated iparamDefns
* @throws {Error} If the iparamDefns is invalid or cannot be read
*/
loadIparamDefns(appDir) {
return this.iparamDefnsValidator.validateAndGetIparamDefnsFile(this.getIparamsFilePath(appDir));
}
/**
* Loads iparam inputs (without validation against defns). Validates file shape only.
* @param {string} appDir - The application directory
* @returns {IparamInputs} The loaded inputs
* @throws {Error} If `iparams.local.json` is missing, invalid JSON, or not a plain object
*/
loadInputs(appDir) {
return this.inputsValidator.validateAndGetIparamInputsFile(this.getInputsFilePath(appDir));
}
/**
* Merges inputs with defaults per section.
* @param {IparamInputs} inputs - The provided input values
* @param {IparamDefns} iparamDefns - The iparam defns
* @returns {IparamInputs} The merged inputs with defaults applied
* @throws {MissingRequiredParamsError} When required parameters are missing
*/
mergeInputsWithDefaults(inputs, iparamDefns) {
const mergedInputs = {};
const missingRequired = [];
for (const section of iparamDefns.installation_parameters?.sections ?? []) {
const sectionInputs = inputs[section.name] ?? {};
const mergedSection = {};
for (const param of section.parameters) {
const value = sectionInputs[param.name];
const hasValue = iparams_inputs_validator_1.IparamInputsValidator.isProvidedIparamInputValue(value);
if (hasValue) {
mergedSection[param.name] = value;
continue;
}
if (param.default !== undefined && param.default !== null) {
mergedSection[param.name] = param.default;
continue;
}
if (param.required) {
missingRequired.push(`${section.name}.${param.name}`);
}
}
if (Object.keys(mergedSection).length > 0) {
mergedInputs[section.name] = mergedSection;
}
}
if (missingRequired.length > 0) {
throw new errors_1.MissingRequiredParamsError(missingRequired);
}
return mergedInputs;
}
/**
* Loads inputs and defns, validates inputs against defns, merges with defaults, returns resolved iparams.
* @param {string} appDir - The application directory
* @returns {IparamInputs} The merged inputs with defaults applied
* @throws {Error} If validation fails, or required parameters are missing and have no defaults
*/
validateAndGetInputsForExecution(appDir) {
const inputs = this.loadInputs(appDir);
const iparamDefns = this.loadIparamDefns(appDir);
this.inputsValidator.validateInputs(inputs, iparamDefns);
return this.mergeInputsWithDefaults(inputs, iparamDefns);
}
/**
* Saves the iparamDefns to file
* @param {string} appDir - The application directory
* @param {IparamDefns} iparamDefns - The iparamDefns to save
* @throws {Error} If the iparamDefns is invalid or cannot be written
*/
saveIparamDefns(appDir, iparamDefns) {
(0, validator_utils_1.ensureFileExists)(this.fileSystem, this.getIparamsFilePath(appDir));
this.iparamDefnsValidator.validate(iparamDefns);
this.fileSystem.writeFileSync(this.getIparamsFilePath(appDir), JSON.stringify(iparamDefns, null, '\t'));
}
/**
* Loads defns and merges inputs, ensures iparams.local.json exists, then writes.
* @param {string} appDir - The application directory
* @param {IparamInputs} inputs - The raw input values from the request
* @throws {Error} If iparams.json or iparams.local.json is missing, or validation fails
*/
saveInputs(appDir, inputs) {
const iparamDefns = this.loadIparamDefns(appDir);
this.inputsValidator.validateInputs(inputs, iparamDefns);
const mergedInputs = this.mergeInputsWithDefaults(inputs, iparamDefns);
(0, validator_utils_1.ensureFileExists)(this.fileSystem, this.getInputsFilePath(appDir));
this.fileSystem.writeFileSync(this.getInputsFilePath(appDir), JSON.stringify(mergedInputs, null, '\t'));
}
/**
* Validates iparams file without loading it
* @param {string} appDir - The application directory
* @throws {Error} If the iparamDefns is invalid
*/
validateIparamDefns(appDir) {
this.iparamDefnsValidator.validateAndGetIparamDefnsFile(this.getIparamsFilePath(appDir));
}
}
exports.IparamsService = IparamsService;
"use strict";var __importDefault=this&&this.__importDefault||function(i){return i&&i.__esModule?i:{default:i}};Object.defineProperty(exports,"__esModule",{value:!0}),exports.IparamsService=void 0;const path_1=__importDefault(require("path")),errors_1=require("../errors"),iparams_inputs_validator_1=require("../validator/iparams-inputs-validator"),iparam_defns_validator_1=require("../validator/iparam-defns-validator"),validator_utils_1=require("../validator/validator-utils");class IparamsService{constructor(t){this.fileSystem=t,this.iparamDefnsValidator=new iparam_defns_validator_1.IparamDefnsValidator(t),this.inputsValidator=new iparams_inputs_validator_1.IparamInputsValidator(t)}getIparamsFilePath(t){return path_1.default.join(t,"iparams.json")}getInputsFilePath(t){return path_1.default.join(t,"iparams.local.json")}iparamsFileExists(t){return this.fileSystem.existsSync(this.getIparamsFilePath(t))}loadIparamDefns(t){return this.iparamDefnsValidator.validateAndGetIparamDefnsFile(this.getIparamsFilePath(t))}loadInputs(t){return this.inputsValidator.validateAndGetIparamInputsFile(this.getInputsFilePath(t))}mergeInputsWithDefaults(t,a){const e={},r=[];for(const n of a.installation_parameters?.sections??[]){const o=t[n.name]??{},l={};for(const s of n.parameters){const u=o[s.name];if(iparams_inputs_validator_1.IparamInputsValidator.isProvidedIparamInputValue(u)){l[s.name]=u;continue}if(s.default!==void 0&&s.default!==null){l[s.name]=s.default;continue}s.required&&r.push(`${n.name}.${s.name}`)}Object.keys(l).length>0&&(e[n.name]=l)}if(r.length>0)throw new errors_1.MissingRequiredParamsError(r);return e}validateAndGetInputsForExecution(t){const a=this.loadInputs(t),e=this.loadIparamDefns(t);return this.inputsValidator.validateInputs(a,e),this.mergeInputsWithDefaults(a,e)}saveIparamDefns(t,a){(0,validator_utils_1.ensureFileExists)(this.fileSystem,this.getIparamsFilePath(t)),this.iparamDefnsValidator.validate(a),this.fileSystem.writeFileSync(this.getIparamsFilePath(t),JSON.stringify(a,null," "))}saveInputs(t,a){const e=this.loadIparamDefns(t);this.inputsValidator.validateInputs(a,e);const r=this.mergeInputsWithDefaults(a,e);(0,validator_utils_1.ensureFileExists)(this.fileSystem,this.getInputsFilePath(t)),this.fileSystem.writeFileSync(this.getInputsFilePath(t),JSON.stringify(r,null," "))}validateIparamDefns(t){this.iparamDefnsValidator.validateAndGetIparamDefnsFile(this.getIparamsFilePath(t))}}exports.IparamsService=IparamsService;

@@ -1,152 +0,1 @@

"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.TemplateService = void 0;
const path_1 = __importDefault(require("path"));
const internal_logger_1 = require("../logger/internal-logger");
/**
* Template service for managing templates across different CLI packages
*/
class TemplateService {
constructor(fileSystem, templatesDir) {
this.fileSystem = fileSystem;
this.templatesDir = templatesDir;
}
/**
* Validates template exists
* @param {string} template - Template name to validate
* @returns {boolean} True if template is valid
*/
validateTemplate(template) {
const availableTemplates = this.getAvailableTemplates();
return availableTemplates.includes(template);
}
/**
* Validates app directory for conflicts
* @param {string} targetDir - Target directory path
* @param {string} appDir - Original app directory argument
* @param {string} template - Template name
* @returns {string[]} Array of conflicting files (empty if no conflicts)
*/
validateAppDirectory(targetDir, appDir, template) {
if (!this.fileSystem.existsSync(targetDir)) {
return [];
}
if (appDir === '.') {
// When using current directory, check for conflicting files
const templatePath = path_1.default.join(this.templatesDir, template);
const templateFiles = this.getTemplateFiles(templatePath);
const existingFiles = this.fileSystem.readdirSync(targetDir);
return templateFiles.filter(file => existingFiles.includes(file));
}
else {
// For other directories, check if not empty
const files = this.fileSystem.readdirSync(targetDir);
if (files.length > 0) {
throw new Error(`Directory '${targetDir}' already exists and is not empty.`);
}
return [];
}
}
/**
* Gets a list of available templates from the templates directory
* @returns {string[]} Array of template names
*/
getAvailableTemplates() {
if (!this.fileSystem.existsSync(this.templatesDir)) {
internal_logger_1.__logger.warn(`Templates directory not found: ${this.templatesDir}`);
return [];
}
const templates = this.fileSystem.readdirSync(this.templatesDir, { withFileTypes: true })
.filter(dirent => dirent.isDirectory())
.map(dirent => dirent.name);
return templates;
}
/**
* Gets the full path to a specific template
* @param {string} template - Template name
* @returns {string} Full path to the template directory
*/
getTemplatePath(template) {
return path_1.default.join(this.templatesDir, template);
}
/**
* Gets the templates directory path
* @returns {string} Path to the templates directory
*/
getTemplatesDirectory() {
return this.templatesDir;
}
/**
* Recursively collects all files from a template directory
* @param {string} templatePath - Path to the template directory
* @returns {string[]} Array of file paths relative to template root
*/
getTemplateFiles(templatePath) {
const files = [];
const collectFiles = (dir, basePath = '') => {
const items = this.fileSystem.readdirSync(dir);
for (const item of items) {
const sourcePath = path_1.default.join(dir, item);
const relativePath = path_1.default.join(basePath, item);
const stat = this.fileSystem.statSync(sourcePath);
if (stat.isDirectory()) {
collectFiles(sourcePath, relativePath);
}
else {
files.push(relativePath);
}
}
};
collectFiles(templatePath);
return files;
}
/**
* Recursively copies all files from template directory to target directory
* @param {string} templatePath - Source template directory path
* @param {string} targetPath - Target directory path
*/
copyTemplateFiles(templatePath, targetPath) {
const items = this.fileSystem.readdirSync(templatePath);
for (const item of items) {
const sourcePath = path_1.default.join(templatePath, item);
const destPath = path_1.default.join(targetPath, item);
const stat = this.fileSystem.statSync(sourcePath);
if (stat.isDirectory()) {
this.fileSystem.mkdirSync(destPath, { recursive: true });
this.copyTemplateFiles(sourcePath, destPath);
}
else {
this.fileSystem.copyFileSync(sourcePath, destPath);
}
}
}
/**
* Prints a tree-like structure of the project directory
* @param {string} dir - Directory path to print structure for
* @param {string} [indent=''] - Current indentation level
*/
printProjectStructure(dir, indent = '') {
const items = this.fileSystem.readdirSync(dir);
for (let i = 0; i < items.length; i++) {
const item = items[i];
const itemPath = path_1.default.join(dir, item || '');
const stat = this.fileSystem.statSync(itemPath);
const isDirectory = stat.isDirectory();
const isLastItem = i === items.length - 1;
// Tree characters
const treeChar = isLastItem ? '└── ' : '├── ';
const nextIndent = isLastItem ? ' ' : '│ ';
// File/directory name
const name = isDirectory ? item + '/' : item;
const coloredName = name;
internal_logger_1.__logger.info(`${indent}${treeChar}${coloredName}`);
if (isDirectory) {
this.printProjectStructure(itemPath, indent + nextIndent);
}
}
}
}
exports.TemplateService = TemplateService;
"use strict";var __importDefault=this&&this.__importDefault||function(a){return a&&a.__esModule?a:{default:a}};Object.defineProperty(exports,"__esModule",{value:!0}),exports.TemplateService=void 0;const path_1=__importDefault(require("path")),internal_logger_1=require("../logger/internal-logger");class TemplateService{constructor(e,t){this.fileSystem=e,this.templatesDir=t}validateTemplate(e){return this.getAvailableTemplates().includes(e)}validateAppDirectory(e,t,r){if(!this.fileSystem.existsSync(e))return[];if(t==="."){const s=path_1.default.join(this.templatesDir,r),i=this.getTemplateFiles(s),l=this.fileSystem.readdirSync(e);return i.filter(n=>l.includes(n))}else{if(this.fileSystem.readdirSync(e).length>0)throw new Error(`Directory '${e}' already exists and is not empty.`);return[]}}getAvailableTemplates(){return this.fileSystem.existsSync(this.templatesDir)?this.fileSystem.readdirSync(this.templatesDir,{withFileTypes:!0}).filter(t=>t.isDirectory()).map(t=>t.name):(internal_logger_1.__logger.warn(`Templates directory not found: ${this.templatesDir}`),[])}getTemplatePath(e){return path_1.default.join(this.templatesDir,e)}getTemplatesDirectory(){return this.templatesDir}getTemplateFiles(e){const t=[],r=(s,i="")=>{const l=this.fileSystem.readdirSync(s);for(const n of l){const o=path_1.default.join(s,n),c=path_1.default.join(i,n);this.fileSystem.statSync(o).isDirectory()?r(o,c):t.push(c)}};return r(e),t}copyTemplateFiles(e,t){const r=this.fileSystem.readdirSync(e);for(const s of r){const i=path_1.default.join(e,s),l=path_1.default.join(t,s);this.fileSystem.statSync(i).isDirectory()?(this.fileSystem.mkdirSync(l,{recursive:!0}),this.copyTemplateFiles(i,l)):this.fileSystem.copyFileSync(i,l)}}printProjectStructure(e,t=""){const r=this.fileSystem.readdirSync(e);for(let s=0;s<r.length;s++){const i=r[s],l=path_1.default.join(e,i||""),o=this.fileSystem.statSync(l).isDirectory(),c=s===r.length-1,m=c?"\u2514\u2500\u2500 ":"\u251C\u2500\u2500 ",f=c?" ":"\u2502 ",p=o?i+"/":i;internal_logger_1.__logger.info(`${t}${m}${p}`),o&&this.printProjectStructure(l,t+f)}}}exports.TemplateService=TemplateService;

@@ -1,13 +0,1 @@

"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.LogLevel = void 0;
/**
* Log levels enum for consistent logging across packages
*/
var LogLevel;
(function (LogLevel) {
LogLevel["ERROR"] = "ERROR";
LogLevel["WARN"] = "WARN";
LogLevel["INFO"] = "INFO";
LogLevel["DEBUG"] = "DEBUG";
})(LogLevel || (exports.LogLevel = LogLevel = {}));
"use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.LogLevel=void 0;var LogLevel;(function(e){e.ERROR="ERROR",e.WARN="WARN",e.INFO="INFO",e.DEBUG="DEBUG"})(LogLevel||(exports.LogLevel=LogLevel={}));

@@ -1,146 +0,2 @@

"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.__logger = exports.InternalLogger = void 0;
const cb_logger_1 = require("./cb-logger");
const winston_1 = __importDefault(require("winston"));
/**
* Winston-based InternalLogger provides logging capabilities for the Chargebee Apps CLI itself
* This is separate from the user-facing cb-logger and uses Winston for structured logging
* Shared implementation for both public and private CLI packages
*/
class InternalLogger {
constructor(config = {}) {
this.config = {
useJsonFormat: false,
...config
};
this.logger = this.createWinstonLogger();
}
/**
* Creates a Winston logger instance with appropriate formatting
* @returns {winston.Logger} The configured Winston logger
*/
createWinstonLogger() {
const logLevel = process.env['CB_LOG_LEVEL'] || cb_logger_1.LogLevel.INFO;
// Create custom format based on configuration
const customFormat = winston_1.default.format.combine(winston_1.default.format.timestamp(), winston_1.default.format.errors({ stack: true }), this.config.useJsonFormat ? this.createJsonFormat() : this.createTextFormat());
return winston_1.default.createLogger({
level: logLevel.toLowerCase(),
format: customFormat,
transports: [
new winston_1.default.transports.Console({})
]
});
}
/**
* Creates JSON format for structured logging
* @returns {winston.Logform.Format} The JSON format
*/
createJsonFormat() {
return winston_1.default.format.combine(winston_1.default.format.timestamp(), winston_1.default.format.printf((info) => {
const logEntry = {
timestamp: info['timestamp'],
level: info.level,
service: 'Internal',
message: info.message
};
// Include all additional context from child loggers
Object.keys(info).forEach(key => {
if (!['timestamp', 'level', 'message', 'stack'].includes(key)) {
logEntry[key] = info[key];
}
});
if (info['stack']) {
logEntry.stack = info['stack'];
}
return JSON.stringify(logEntry);
}));
}
/**
* Creates text format for human-readable logging
* @returns {winston.Logform.Format} The text format
*/
createTextFormat() {
return winston_1.default.format.combine(winston_1.default.format.timestamp(), winston_1.default.format.colorize(), winston_1.default.format.printf((info) => {
const timestamp = info['timestamp'];
const level = info.level;
const service = 'Internal';
const message = info.message;
const stack = info['stack'] ? `\n${info['stack']}` : '';
// Build context string from additional properties
const contextParts = [];
Object.keys(info).forEach(key => {
if (!['timestamp', 'level', 'message', 'stack'].includes(key)) {
contextParts.push(`${key}=${info[key]}`);
}
});
const contextStr = contextParts.length > 0 ? ` [${contextParts.join(', ')}]` : '';
return `${timestamp} [${level}] [${service}]${contextStr} ${message}${stack}`;
}));
}
/**
* Logs an informational message
* @param {...any} args - The message arguments to log
*/
info(...args) {
const message = args.join(' ');
this.logger.info(message);
}
/**
* Logs a warning message
* @param {...any} args - The message arguments to log
*/
warn(...args) {
const message = args.join(' ');
this.logger.warn(message);
}
/**
* Logs an error message
* @param {...any} args - The message arguments to log
*/
error(...args) {
const message = args.join(' ');
this.logger.error(message);
}
/**
* Logs a debug message
* @param {...any} args - The message arguments to log
*/
debug(...args) {
const message = args.join(' ');
this.logger.debug(message);
}
/**
* Logs a success message (alias for info with success indicator)
* @param {...any} args - The message arguments to log
*/
success(...args) {
const message = args.join(' ');
this.logger.info(`✅ ${message}`);
}
/**
* Logs a failure message (alias for error with failure indicator)
* @param {...any} args - The message arguments to log
*/
failure(...args) {
const message = args.join(' ');
this.logger.error(`❌ ${message}`);
}
/**
* Creates a child logger with additional context
* @param {ChildLoggerContext} context - Additional context to include in all log messages
* @returns {InternalLogger} A new InternalLogger instance with the child context
*/
child(context) {
const childLogger = new InternalLogger(this.config);
// Create a Winston child logger with the provided context
childLogger.logger = this.logger.child(context);
return childLogger;
}
}
exports.InternalLogger = InternalLogger;
// Create a singleton instance for default logger
exports.__logger = new InternalLogger();
"use strict";var __importDefault=this&&this.__importDefault||function(r){return r&&r.__esModule?r:{default:r}};Object.defineProperty(exports,"__esModule",{value:!0}),exports.__logger=exports.InternalLogger=void 0;const cb_logger_1=require("./cb-logger"),winston_1=__importDefault(require("winston"));class InternalLogger{constructor(e={}){this.config={useJsonFormat:!1,...e},this.logger=this.createWinstonLogger()}createWinstonLogger(){const e=process.env.CB_LOG_LEVEL||cb_logger_1.LogLevel.INFO,t=winston_1.default.format.combine(winston_1.default.format.timestamp(),winston_1.default.format.errors({stack:!0}),this.config.useJsonFormat?this.createJsonFormat():this.createTextFormat());return winston_1.default.createLogger({level:e.toLowerCase(),format:t,transports:[new winston_1.default.transports.Console({})]})}createJsonFormat(){return winston_1.default.format.combine(winston_1.default.format.timestamp(),winston_1.default.format.printf(e=>{const t={timestamp:e.timestamp,level:e.level,service:"Internal",message:e.message};return Object.keys(e).forEach(s=>{["timestamp","level","message","stack"].includes(s)||(t[s]=e[s])}),e.stack&&(t.stack=e.stack),JSON.stringify(t)}))}createTextFormat(){return winston_1.default.format.combine(winston_1.default.format.timestamp(),winston_1.default.format.colorize(),winston_1.default.format.printf(e=>{const t=e.timestamp,s=e.level,n="Internal",c=e.message,l=e.stack?`
${e.stack}`:"",o=[];Object.keys(e).forEach(a=>{["timestamp","level","message","stack"].includes(a)||o.push(`${a}=${e[a]}`)});const g=o.length>0?` [${o.join(", ")}]`:"";return`${t} [${s}] [${n}]${g} ${c}${l}`}))}info(...e){const t=e.join(" ");this.logger.info(t)}warn(...e){const t=e.join(" ");this.logger.warn(t)}error(...e){const t=e.join(" ");this.logger.error(t)}debug(...e){const t=e.join(" ");this.logger.debug(t)}success(...e){const t=e.join(" ");this.logger.info(`\u2705 ${t}`)}failure(...e){const t=e.join(" ");this.logger.error(`\u274C ${t}`)}child(e){const t=new InternalLogger(this.config);return t.logger=this.logger.child(e),t}}exports.InternalLogger=InternalLogger,exports.__logger=new InternalLogger;

@@ -1,76 +0,1 @@

"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.FileSystemService = void 0;
const fs_1 = __importDefault(require("fs"));
/**
* FileSystemService provides a class-based implementation of the FileSystem interface.
* Use this for dependency injection for all the filesystem operations, and for testing we can use custom implemenatation if needed.
*/
class FileSystemService {
existsSync(path) {
return fs_1.default.existsSync(path);
}
readdirSync(path, options) {
return fs_1.default.readdirSync(path, options);
}
mkdirSync(path, options) {
fs_1.default.mkdirSync(path, options);
}
unlinkSync(path) {
fs_1.default.unlinkSync(path);
}
rmdirSync(path) {
fs_1.default.rmdirSync(path);
}
statSync(path) {
return fs_1.default.statSync(path);
}
createWriteStream(path) {
return fs_1.default.createWriteStream(path);
}
readFileSync(path, encoding) {
return fs_1.default.readFileSync(path, encoding);
}
writeFileSync(path, data) {
fs_1.default.writeFileSync(path, data);
}
copyFileSync(src, dest) {
fs_1.default.copyFileSync(src, dest);
}
lstatSync(path) {
return fs_1.default.lstatSync(path);
}
renameSync(oldPath, newPath) {
try {
fs_1.default.renameSync(oldPath, newPath);
}
catch (err) {
if (err.code === 'EXDEV') {
// Cross-device rename (e.g. Docker overlay filesystem) — fall back to copy + delete
try {
fs_1.default.cpSync(oldPath, newPath, { recursive: true });
fs_1.default.rmSync(oldPath, { recursive: true, force: true });
}
catch (copyErr) {
try {
fs_1.default.rmSync(newPath, { recursive: true, force: true });
}
catch {
// best-effort cleanup; ignore errors
}
throw copyErr;
}
}
else {
throw err;
}
}
}
cpSync(src, dest, options) {
fs_1.default.cpSync(src, dest, options);
}
}
exports.FileSystemService = FileSystemService;
"use strict";var __importDefault=this&&this.__importDefault||function(t){return t&&t.__esModule?t:{default:t}};Object.defineProperty(exports,"__esModule",{value:!0}),exports.FileSystemService=void 0;const fs_1=__importDefault(require("fs"));class FileSystemService{existsSync(e){return fs_1.default.existsSync(e)}readdirSync(e,r){return fs_1.default.readdirSync(e,r)}mkdirSync(e,r){fs_1.default.mkdirSync(e,r)}unlinkSync(e){fs_1.default.unlinkSync(e)}rmdirSync(e){fs_1.default.rmdirSync(e)}statSync(e){return fs_1.default.statSync(e)}createWriteStream(e){return fs_1.default.createWriteStream(e)}readFileSync(e,r){return fs_1.default.readFileSync(e,r)}writeFileSync(e,r){fs_1.default.writeFileSync(e,r)}copyFileSync(e,r){fs_1.default.copyFileSync(e,r)}lstatSync(e){return fs_1.default.lstatSync(e)}renameSync(e,r){try{fs_1.default.renameSync(e,r)}catch(c){if(c.code==="EXDEV")try{fs_1.default.cpSync(e,r,{recursive:!0}),fs_1.default.rmSync(e,{recursive:!0,force:!0})}catch(u){try{fs_1.default.rmSync(r,{recursive:!0,force:!0})}catch{}throw u}else throw c}}cpSync(e,r,c){fs_1.default.cpSync(e,r,c)}}exports.FileSystemService=FileSystemService;

@@ -1,25 +0,1 @@

"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.ProcessService = void 0;
/**
* ProcessService provides a class-based implementation of the Process interface.
* Use this for dependency injection for all the process operations, and for testing we can use custom implemenatation if needed.
*/
class ProcessService {
chdir(path) {
process.chdir(path);
}
cwd() {
return process.cwd();
}
exit(code) {
process.exit(code);
}
on(event, listener) {
process.on(event, listener);
}
get env() {
return process.env;
}
}
exports.ProcessService = ProcessService;
"use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.ProcessService=void 0;class ProcessService{chdir(e){process.chdir(e)}cwd(){return process.cwd()}exit(e){process.exit(e)}on(e,r){process.on(e,r)}get env(){return process.env}}exports.ProcessService=ProcessService;

@@ -1,48 +0,1 @@

"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.sandboxContext = exports.SandboxContext = void 0;
const async_hooks_1 = require("async_hooks");
/**
* SandboxContext manages the execution context for sandboxed code execution
* using AsyncLocalStorage to maintain correlation between event and site information
*/
class SandboxContext {
constructor() {
this.asyncLocalStorage = new async_hooks_1.AsyncLocalStorage();
}
/**
* Creates a new execution context with event and site information
* @param {Object} contextData - The context data containing event and site information
* @param {string} contextData.eventId - The unique identifier for the event
* @param {string} contextData.eventType - The type of the event (e.g., 'customer_created')
* @param {string} contextData.site - The site/tenant identifier in Chargebee
* @param {Function} callback - The function to execute within this context
* @returns {Promise<any>} The result of the callback execution
*/
async run(contextData, callback) {
const context = {
eventId: contextData.eventId || 'unknown',
eventType: contextData.eventType || 'unknown',
startTime: new Date().toISOString(),
};
return this.asyncLocalStorage.run(context, () => callback());
}
/**
* Gets the current execution context
* @returns {Object|null} The current context or null if not in an execution context
*/
getCurrentContext() {
return this.asyncLocalStorage.getStore();
}
/**
* Checks if there is an active execution context
* @returns {boolean} True if there is an active context, false otherwise
*/
hasContext() {
return this.asyncLocalStorage.getStore() !== undefined;
}
}
exports.SandboxContext = SandboxContext;
// Create a singleton instance
exports.sandboxContext = new SandboxContext();
exports.default = exports.sandboxContext;
"use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.sandboxContext=exports.SandboxContext=void 0;const async_hooks_1=require("async_hooks");class SandboxContext{constructor(){this.asyncLocalStorage=new async_hooks_1.AsyncLocalStorage}async run(t,e){const n={eventId:t.eventId||"unknown",eventType:t.eventType||"unknown",startTime:new Date().toISOString()};return this.asyncLocalStorage.run(n,()=>e())}getCurrentContext(){return this.asyncLocalStorage.getStore()}hasContext(){return this.asyncLocalStorage.getStore()!==void 0}}exports.SandboxContext=SandboxContext,exports.sandboxContext=new SandboxContext,exports.default=exports.sandboxContext;
+1
-2

@@ -1,2 +0,1 @@

"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
"use strict";Object.defineProperty(exports,"__esModule",{value:!0});

@@ -1,20 +0,1 @@

"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.VALID_IPARAM_TYPES = exports.IPARAM_TYPE_VALUE_MAP = void 0;
/**
* Map of iparam `type` identifiers to placeholder values.
* Keys match valid `type` values in `iparams.json`; each value’s TypeScript type is the allowed
* JSON shape for that type in definition defaults and `iparams.local.json`.
*/
exports.IPARAM_TYPE_VALUE_MAP = {
NUMBER: 0,
TEXT: '',
DROPDOWN: '',
MULTISELECT_DROPDOWN: [],
DATE: '',
URL: '',
BOOLEAN: false,
SECRET: ''
};
/** Valid `type` strings for runtime checks. */
exports.VALID_IPARAM_TYPES = Object.keys(exports.IPARAM_TYPE_VALUE_MAP);
"use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.VALID_IPARAM_TYPES=exports.IPARAM_TYPE_VALUE_MAP=void 0,exports.IPARAM_TYPE_VALUE_MAP={NUMBER:0,TEXT:"",DROPDOWN:"",MULTISELECT_DROPDOWN:[],DATE:"",URL:"",BOOLEAN:!1,SECRET:""},exports.VALID_IPARAM_TYPES=Object.keys(exports.IPARAM_TYPE_VALUE_MAP);

@@ -1,52 +0,1 @@

"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.IPARAM_URL_ALLOWED_PROTOCOLS = exports.IPARAM_VALUE_MAX_LENGTHS = exports.OPTIONS_LIMITS = exports.IPARAM_DEFN_MAX_LENGTHS = exports.IPARAMS_MAX_COUNT = exports.IPARAMS_INSTALLATION_PARAMETERS_ALLOWED_KEYS = exports.IPARAMS_SECTIONS_LABEL = exports.IPARAMS_JSON_FILENAME = exports.IPARAMS_ROOT_ALLOWED_KEYS = exports.IPARAMS_INSTALLATION_PARAMETERS_LABEL = void 0;
/**
* Allowed top-level keys in `iparams.json`.
*/
exports.IPARAMS_INSTALLATION_PARAMETERS_LABEL = 'installation_parameters';
exports.IPARAMS_ROOT_ALLOWED_KEYS = [exports.IPARAMS_INSTALLATION_PARAMETERS_LABEL];
/**
* File name for iparam definitions in an app directory.
*/
exports.IPARAMS_JSON_FILENAME = 'iparams.json';
/**
* Label for the `sections` array in validation error messages.
*/
exports.IPARAMS_SECTIONS_LABEL = 'sections';
/**
* Allowed keys under `installation_parameters` in `iparams.json`.
*/
exports.IPARAMS_INSTALLATION_PARAMETERS_ALLOWED_KEYS = [exports.IPARAMS_SECTIONS_LABEL];
/**
* Maximum number of parameter definitions allowed in a single `iparams.json` array.
*/
exports.IPARAMS_MAX_COUNT = 20;
/**
* Central limits for iparam definition fields (`iparams.json`).
*/
exports.IPARAM_DEFN_MAX_LENGTHS = {
NAME: 50,
DISPLAY_NAME: 50,
DESCRIPTION: 250
};
/**
* Limits for DROPDOWN and MULTISELECT_DROPDOWN `options` arrays in definitions.
*/
exports.OPTIONS_LIMITS = {
MAX_COUNT: 20,
MAX_OPTION_LENGTH: 250
};
/**
* Max lengths for iparam input values when validating `iparams.local.json` / runtime inputs.
*/
exports.IPARAM_VALUE_MAX_LENGTHS = {
TEXT: 250,
SECRET: 250,
URL: 250,
DATE: 10
};
/**
* Allowed {@link URL#protocol} values for iparam type `URL`.
*/
exports.IPARAM_URL_ALLOWED_PROTOCOLS = ['http:', 'https:'];
"use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.IPARAM_URL_ALLOWED_PROTOCOLS=exports.IPARAM_VALUE_MAX_LENGTHS=exports.OPTIONS_LIMITS=exports.IPARAM_DEFN_MAX_LENGTHS=exports.IPARAMS_MAX_COUNT=exports.IPARAMS_INSTALLATION_PARAMETERS_ALLOWED_KEYS=exports.IPARAMS_SECTIONS_LABEL=exports.IPARAMS_JSON_FILENAME=exports.IPARAMS_ROOT_ALLOWED_KEYS=exports.IPARAMS_INSTALLATION_PARAMETERS_LABEL=void 0,exports.IPARAMS_INSTALLATION_PARAMETERS_LABEL="installation_parameters",exports.IPARAMS_ROOT_ALLOWED_KEYS=[exports.IPARAMS_INSTALLATION_PARAMETERS_LABEL],exports.IPARAMS_JSON_FILENAME="iparams.json",exports.IPARAMS_SECTIONS_LABEL="sections",exports.IPARAMS_INSTALLATION_PARAMETERS_ALLOWED_KEYS=[exports.IPARAMS_SECTIONS_LABEL],exports.IPARAMS_MAX_COUNT=20,exports.IPARAM_DEFN_MAX_LENGTHS={NAME:50,DISPLAY_NAME:50,DESCRIPTION:250},exports.OPTIONS_LIMITS={MAX_COUNT:20,MAX_OPTION_LENGTH:250},exports.IPARAM_VALUE_MAX_LENGTHS={TEXT:250,SECRET:250,URL:250,DATE:10},exports.IPARAM_URL_ALLOWED_PROTOCOLS=["http:","https:"];

@@ -1,291 +0,1 @@

"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || (function () {
var ownKeys = function(o) {
ownKeys = Object.getOwnPropertyNames || function (o) {
var ar = [];
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
return ar;
};
return ownKeys(o);
};
return function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
__setModuleDefault(result, mod);
return result;
};
})();
Object.defineProperty(exports, "__esModule", { value: true });
exports.IparamDefnsValidator = void 0;
const common_1 = require("../types/common");
const iparam_constants_1 = require("./iparam-constants");
const iparams_inputs_validator_1 = require("./iparams-inputs-validator");
const validatorUtils = __importStar(require("./validator-utils"));
/**
* Validator for iparamDefns
* Validates the sectioned iparams.json schema
*/
class IparamDefnsValidator {
constructor(fileSystem) {
this.fileSystem = fileSystem;
this.inputsValidator = new iparams_inputs_validator_1.IparamInputsValidator(fileSystem);
}
/**
* Validates and loads the iparamDefns from a file
* @param {string} path - Path to the iparams.json file
* @returns {IparamDefns} The validated iparamDefns
* @throws {Error} If the iparamDefns is invalid or cannot be read
*/
validateAndGetIparamDefnsFile(path) {
validatorUtils.ensureFileExists(this.fileSystem, path);
try {
const iparamDefns = JSON.parse(this.fileSystem.readFileSync(path, 'utf8'));
try {
this.validate(iparamDefns);
return iparamDefns;
}
catch (validationError) {
const err = new Error(validationError.message);
err.rawContent = iparamDefns;
throw err;
}
}
catch (error) {
if (error.rawContent !== undefined) {
throw error;
}
if (error instanceof SyntaxError) {
throw new Error(`Failed to parse ${iparam_constants_1.IPARAMS_JSON_FILENAME}: ${error.message}`);
}
throw new Error(`Failed to read ${iparam_constants_1.IPARAMS_JSON_FILENAME}: ${error.message}`);
}
}
/**
* Validates an iparamDefns object
* @param {IparamDefns} iparamDefns - The iparamDefns object to validate
* @throws {Error} If the iparamDefns is invalid
*/
validate(iparamDefns) {
if (!iparamDefns || typeof iparamDefns !== 'object' || Array.isArray(iparamDefns)) {
throw new Error(`${iparam_constants_1.IPARAMS_JSON_FILENAME} must be an object`);
}
this.rejectUnknownKeys(iparamDefns, iparam_constants_1.IPARAMS_ROOT_ALLOWED_KEYS, iparam_constants_1.IPARAMS_JSON_FILENAME);
if (!Object.prototype.hasOwnProperty.call(iparamDefns, iparam_constants_1.IPARAMS_INSTALLATION_PARAMETERS_LABEL)) {
return;
}
const installationParameters = iparamDefns.installation_parameters;
if (!installationParameters || typeof installationParameters !== 'object' || Array.isArray(installationParameters)) {
throw new Error(`${iparam_constants_1.IPARAMS_JSON_FILENAME} must include ${iparam_constants_1.IPARAMS_INSTALLATION_PARAMETERS_LABEL} as an object containing a ${iparam_constants_1.IPARAMS_SECTIONS_LABEL} array`);
}
this.rejectUnknownKeys(installationParameters, iparam_constants_1.IPARAMS_INSTALLATION_PARAMETERS_ALLOWED_KEYS, iparam_constants_1.IPARAMS_INSTALLATION_PARAMETERS_LABEL);
if (!Object.prototype.hasOwnProperty.call(installationParameters, iparam_constants_1.IPARAMS_SECTIONS_LABEL)) {
throw new Error(`${iparam_constants_1.IPARAMS_INSTALLATION_PARAMETERS_LABEL} must include ${iparam_constants_1.IPARAMS_SECTIONS_LABEL} in ${iparam_constants_1.IPARAMS_JSON_FILENAME}`);
}
const sections = installationParameters.sections;
if (!Array.isArray(sections)) {
throw new Error(`${iparam_constants_1.IPARAMS_INSTALLATION_PARAMETERS_LABEL}.${iparam_constants_1.IPARAMS_SECTIONS_LABEL} must be an array of section objects`);
}
if (sections.length === 0) {
throw new Error(`${iparam_constants_1.IPARAMS_INSTALLATION_PARAMETERS_LABEL}.${iparam_constants_1.IPARAMS_SECTIONS_LABEL} must contain at least one section`);
}
for (let i = 0; i < sections.length; i++) {
this.validateSection(sections[i], i);
}
const totalParamCount = sections.reduce((count, section) => count + section.parameters.length, 0);
if (totalParamCount > iparam_constants_1.IPARAMS_MAX_COUNT) {
throw new Error(`${iparam_constants_1.IPARAMS_JSON_FILENAME} cannot define more than ${iparam_constants_1.IPARAMS_MAX_COUNT} parameters (found ${totalParamCount})`);
}
const sectionNames = sections.map((section) => section.name.trim());
const seenSectionNames = new Set();
const duplicateSections = [];
for (const name of sectionNames) {
if (seenSectionNames.has(name))
duplicateSections.push(name);
else
seenSectionNames.add(name);
}
if (duplicateSections.length > 0) {
throw new Error(`Duplicate section names found: ${duplicateSections.join(', ')}`);
}
for (const section of sections) {
const paramNames = section.parameters.map((param) => param.name.trim());
const seenParamNames = new Set();
const duplicateParams = [];
for (const name of paramNames) {
if (seenParamNames.has(name))
duplicateParams.push(name);
else
seenParamNames.add(name);
}
if (duplicateParams.length > 0) {
throw new Error(`Duplicate parameter names found in section "${section.name}": ${duplicateParams.join(', ')}`);
}
}
}
/**
* Validates a single section definition
* @param {any} section - The section definition to validate
* @param {number} index - The index of the section in the array (for error messages)
* @throws {Error} If the section is invalid
*/
validateSection(section, index) {
if (!section || typeof section !== 'object') {
throw new Error(`Section at index ${index} must be an object`);
}
const sectionName = this.validateSectionName(section, index);
this.requireNonEmptyStringField(section, sectionName, 'display_name', iparam_constants_1.IPARAM_DEFN_MAX_LENGTHS.DISPLAY_NAME, 'Section');
this.requireNonEmptyStringField(section, sectionName, 'description', iparam_constants_1.IPARAM_DEFN_MAX_LENGTHS.DESCRIPTION, 'Section');
const parameters = section['parameters'];
if (!Array.isArray(parameters)) {
throw new Error(`Section "${sectionName}": "parameters" must be an array`);
}
if (parameters.length === 0) {
throw new Error(`Section "${sectionName}": "parameters" must contain at least one parameter`);
}
for (let i = 0; i < parameters.length; i++) {
this.validateParameter(parameters[i], sectionName, i);
}
}
/**
* Validates a single parameter definition
* @param {any} param - The parameter definition to validate
* @param {string} sectionName - Parent section name for error messages
* @param {number} index - The index of the parameter in the section (for error messages)
* @throws {Error} If the parameter is invalid
*/
validateParameter(param, sectionName, index) {
if (!param || typeof param !== 'object') {
throw new Error(`Section "${sectionName}": parameter at index ${index} must be an object`);
}
const paramName = this.validateParamName(param, sectionName, index);
const sectionDotParam = `${sectionName}.${paramName}`;
this.requireNonEmptyStringField(param, sectionDotParam, 'display_name', iparam_constants_1.IPARAM_DEFN_MAX_LENGTHS.DISPLAY_NAME);
this.requireNonEmptyStringField(param, sectionDotParam, 'description', iparam_constants_1.IPARAM_DEFN_MAX_LENGTHS.DESCRIPTION);
this.validateType(param, sectionDotParam);
if (param.required !== undefined && typeof param.required !== 'boolean') {
throw new Error(`Parameter "${sectionDotParam}": "required" must be a boolean`);
}
this.validateOptions(param, sectionDotParam);
if (param.type === 'SECRET' && param.default !== undefined && param.default !== null) {
throw new Error(`Parameter "${sectionDotParam}": SECRET type cannot have a default value`);
}
this.validateDefaultValue(param, sectionDotParam);
}
requireNonEmptyStringField(entity, entityName, fieldName, maxLength, entityLabel = 'Parameter') {
const value = entity[fieldName];
if (!validatorUtils.isNonEmptyString(value)) {
throw new Error(`${entityLabel} "${entityName}": "${fieldName}" must be a non-empty string`);
}
const trimmed = value.trim();
if (maxLength !== undefined && trimmed.length > maxLength) {
throw new Error(`${entityLabel} "${entityName}": "${fieldName}" cannot exceed ${maxLength} characters`);
}
}
rejectUnknownKeys(entity, allowedKeys, entityLabel) {
for (const key of Object.keys(entity)) {
if (!allowedKeys.includes(key)) {
throw new Error(`${entityLabel} must only contain ${allowedKeys.map((k) => `"${k}"`).join(', ')}`);
}
}
}
validateSectionName(section, index) {
const name = section['name'];
if (!validatorUtils.isNonEmptyString(name)) {
throw new Error(`Section at index ${index}: "name" must be a non-empty string`);
}
const sectionName = name.trim();
if (!/^[a-zA-Z_][a-zA-Z0-9_-]*$/.test(sectionName)) {
throw new Error(`Section "${sectionName}": "name" can only contain letters, numbers, underscores, and hyphens, and must start with a letter or underscore`);
}
if (sectionName.length > iparam_constants_1.IPARAM_DEFN_MAX_LENGTHS.NAME) {
throw new Error(`Section "${sectionName}": "name" must be between 1 and ${iparam_constants_1.IPARAM_DEFN_MAX_LENGTHS.NAME} characters`);
}
return sectionName;
}
validateParamName(param, sectionName, index) {
const name = param['name'];
if (!validatorUtils.isNonEmptyString(name)) {
throw new Error(`Section "${sectionName}": parameter at index ${index}: "name" must be a non-empty string`);
}
const paramName = name.trim();
if (!/^[a-zA-Z_][a-zA-Z0-9_-]*$/.test(paramName)) {
throw new Error(`Parameter "${sectionName}.${paramName}": "name" can only contain letters, numbers, underscores, and hyphens, and must start with a letter or underscore`);
}
if (paramName.length > iparam_constants_1.IPARAM_DEFN_MAX_LENGTHS.NAME) {
throw new Error(`Parameter "${sectionName}.${paramName}": "name" must be between 1 and ${iparam_constants_1.IPARAM_DEFN_MAX_LENGTHS.NAME} characters`);
}
return paramName;
}
validateType(param, sectionDotParam) {
const type = param['type'];
if (!type || !common_1.VALID_IPARAM_TYPES.includes(type)) {
throw new Error(`Parameter "${sectionDotParam}": "type" must be one of: ${common_1.VALID_IPARAM_TYPES.join(', ')}`);
}
}
validateOptions(param, sectionDotParam) {
const paramType = param['type'];
if (paramType !== 'DROPDOWN' && paramType !== 'MULTISELECT_DROPDOWN') {
if (Object.prototype.hasOwnProperty.call(param, 'options')) {
throw new Error(`Parameter "${sectionDotParam}": "options" is only allowed for DROPDOWN and MULTISELECT_DROPDOWN types`);
}
return;
}
const options = param['options'];
if (!options || !Array.isArray(options) || options.length === 0) {
throw new Error(`Parameter "${sectionDotParam}": "options" is required and must be a non-empty array of strings for ${paramType} type`);
}
if (options.length > iparam_constants_1.OPTIONS_LIMITS.MAX_COUNT) {
throw new Error(`Parameter "${sectionDotParam}": "options" cannot exceed ${iparam_constants_1.OPTIONS_LIMITS.MAX_COUNT} items for ${paramType} type`);
}
const seenTrimmedOptions = new Set();
for (let i = 0; i < options.length; i++) {
if (typeof options[i] !== 'string') {
throw new Error(`Parameter "${sectionDotParam}": option at index ${i} must be a string`);
}
const optionStr = options[i].trim();
if (optionStr === '') {
throw new Error(`Parameter "${sectionDotParam}": option at index ${i} cannot be an empty string`);
}
if (seenTrimmedOptions.has(optionStr)) {
throw new Error(`Parameter "${sectionDotParam}": "options" must not contain duplicate entries`);
}
seenTrimmedOptions.add(optionStr);
if (optionStr.length > iparam_constants_1.OPTIONS_LIMITS.MAX_OPTION_LENGTH) {
throw new Error(`Parameter "${sectionDotParam}": option at index ${i} cannot exceed ${iparam_constants_1.OPTIONS_LIMITS.MAX_OPTION_LENGTH} characters`);
}
}
}
validateDefaultValue(param, sectionDotParam) {
const defaultValue = param['default'];
if (defaultValue === undefined || defaultValue === null)
return;
if (typeof defaultValue === 'string' && defaultValue.trim() === '') {
throw new Error(`Parameter "${sectionDotParam}": default value cannot be an empty string. Either remove the "default" key, set it to null, or provide a non-empty value.`);
}
try {
this.inputsValidator.validateParamValue(param, defaultValue, sectionDotParam);
}
catch (error) {
const msg = error.message.replace(/\bvalue\b/g, 'default value');
throw new Error(msg);
}
}
}
exports.IparamDefnsValidator = IparamDefnsValidator;
"use strict";var __createBinding=this&&this.__createBinding||(Object.create?(function(s,e,t,r){r===void 0&&(r=t);var n=Object.getOwnPropertyDescriptor(e,t);(!n||("get"in n?!e.__esModule:n.writable||n.configurable))&&(n={enumerable:!0,get:function(){return e[t]}}),Object.defineProperty(s,r,n)}):(function(s,e,t,r){r===void 0&&(r=t),s[r]=e[t]})),__setModuleDefault=this&&this.__setModuleDefault||(Object.create?(function(s,e){Object.defineProperty(s,"default",{enumerable:!0,value:e})}):function(s,e){s.default=e}),__importStar=this&&this.__importStar||(function(){var s=function(e){return s=Object.getOwnPropertyNames||function(t){var r=[];for(var n in t)Object.prototype.hasOwnProperty.call(t,n)&&(r[r.length]=n);return r},s(e)};return function(e){if(e&&e.__esModule)return e;var t={};if(e!=null)for(var r=s(e),n=0;n<r.length;n++)r[n]!=="default"&&__createBinding(t,e,r[n]);return __setModuleDefault(t,e),t}})();Object.defineProperty(exports,"__esModule",{value:!0}),exports.IparamDefnsValidator=void 0;const common_1=require("../types/common"),iparam_constants_1=require("./iparam-constants"),iparams_inputs_validator_1=require("./iparams-inputs-validator"),validatorUtils=__importStar(require("./validator-utils"));class IparamDefnsValidator{constructor(e){this.fileSystem=e,this.inputsValidator=new iparams_inputs_validator_1.IparamInputsValidator(e)}validateAndGetIparamDefnsFile(e){validatorUtils.ensureFileExists(this.fileSystem,e);try{const t=JSON.parse(this.fileSystem.readFileSync(e,"utf8"));try{return this.validate(t),t}catch(r){const n=new Error(r.message);throw n.rawContent=t,n}}catch(t){throw t.rawContent!==void 0?t:t instanceof SyntaxError?new Error(`Failed to parse ${iparam_constants_1.IPARAMS_JSON_FILENAME}: ${t.message}`):new Error(`Failed to read ${iparam_constants_1.IPARAMS_JSON_FILENAME}: ${t.message}`)}}validate(e){if(!e||typeof e!="object"||Array.isArray(e))throw new Error(`${iparam_constants_1.IPARAMS_JSON_FILENAME} must be an object`);if(this.rejectUnknownKeys(e,iparam_constants_1.IPARAMS_ROOT_ALLOWED_KEYS,iparam_constants_1.IPARAMS_JSON_FILENAME),!Object.prototype.hasOwnProperty.call(e,iparam_constants_1.IPARAMS_INSTALLATION_PARAMETERS_LABEL))return;const t=e.installation_parameters;if(!t||typeof t!="object"||Array.isArray(t))throw new Error(`${iparam_constants_1.IPARAMS_JSON_FILENAME} must include ${iparam_constants_1.IPARAMS_INSTALLATION_PARAMETERS_LABEL} as an object containing a ${iparam_constants_1.IPARAMS_SECTIONS_LABEL} array`);if(this.rejectUnknownKeys(t,iparam_constants_1.IPARAMS_INSTALLATION_PARAMETERS_ALLOWED_KEYS,iparam_constants_1.IPARAMS_INSTALLATION_PARAMETERS_LABEL),!Object.prototype.hasOwnProperty.call(t,iparam_constants_1.IPARAMS_SECTIONS_LABEL))throw new Error(`${iparam_constants_1.IPARAMS_INSTALLATION_PARAMETERS_LABEL} must include ${iparam_constants_1.IPARAMS_SECTIONS_LABEL} in ${iparam_constants_1.IPARAMS_JSON_FILENAME}`);const r=t.sections;if(!Array.isArray(r))throw new Error(`${iparam_constants_1.IPARAMS_INSTALLATION_PARAMETERS_LABEL}.${iparam_constants_1.IPARAMS_SECTIONS_LABEL} must be an array of section objects`);if(r.length===0)throw new Error(`${iparam_constants_1.IPARAMS_INSTALLATION_PARAMETERS_LABEL}.${iparam_constants_1.IPARAMS_SECTIONS_LABEL} must contain at least one section`);for(let o=0;o<r.length;o++)this.validateSection(r[o],o);const n=r.reduce((o,l)=>o+l.parameters.length,0);if(n>iparam_constants_1.IPARAMS_MAX_COUNT)throw new Error(`${iparam_constants_1.IPARAMS_JSON_FILENAME} cannot define more than ${iparam_constants_1.IPARAMS_MAX_COUNT} parameters (found ${n})`);const a=r.map(o=>o.name.trim()),i=new Set,c=[];for(const o of a)i.has(o)?c.push(o):i.add(o);if(c.length>0)throw new Error(`Duplicate section names found: ${c.join(", ")}`);for(const o of r){const l=o.parameters.map(A=>A.name.trim()),E=new Set,u=[];for(const A of l)E.has(A)?u.push(A):E.add(A);if(u.length>0)throw new Error(`Duplicate parameter names found in section "${o.name}": ${u.join(", ")}`)}}validateSection(e,t){if(!e||typeof e!="object")throw new Error(`Section at index ${t} must be an object`);const r=this.validateSectionName(e,t);this.requireNonEmptyStringField(e,r,"display_name",iparam_constants_1.IPARAM_DEFN_MAX_LENGTHS.DISPLAY_NAME,"Section"),this.requireNonEmptyStringField(e,r,"description",iparam_constants_1.IPARAM_DEFN_MAX_LENGTHS.DESCRIPTION,"Section");const n=e.parameters;if(!Array.isArray(n))throw new Error(`Section "${r}": "parameters" must be an array`);if(n.length===0)throw new Error(`Section "${r}": "parameters" must contain at least one parameter`);for(let a=0;a<n.length;a++)this.validateParameter(n[a],r,a)}validateParameter(e,t,r){if(!e||typeof e!="object")throw new Error(`Section "${t}": parameter at index ${r} must be an object`);const n=this.validateParamName(e,t,r),a=`${t}.${n}`;if(this.requireNonEmptyStringField(e,a,"display_name",iparam_constants_1.IPARAM_DEFN_MAX_LENGTHS.DISPLAY_NAME),this.requireNonEmptyStringField(e,a,"description",iparam_constants_1.IPARAM_DEFN_MAX_LENGTHS.DESCRIPTION),this.validateType(e,a),e.required!==void 0&&typeof e.required!="boolean")throw new Error(`Parameter "${a}": "required" must be a boolean`);if(this.validateOptions(e,a),e.type==="SECRET"&&e.default!==void 0&&e.default!==null)throw new Error(`Parameter "${a}": SECRET type cannot have a default value`);this.validateDefaultValue(e,a)}requireNonEmptyStringField(e,t,r,n,a="Parameter"){const i=e[r];if(!validatorUtils.isNonEmptyString(i))throw new Error(`${a} "${t}": "${r}" must be a non-empty string`);const c=i.trim();if(n!==void 0&&c.length>n)throw new Error(`${a} "${t}": "${r}" cannot exceed ${n} characters`)}rejectUnknownKeys(e,t,r){for(const n of Object.keys(e))if(!t.includes(n))throw new Error(`${r} must only contain ${t.map(a=>`"${a}"`).join(", ")}`)}validateSectionName(e,t){const r=e.name;if(!validatorUtils.isNonEmptyString(r))throw new Error(`Section at index ${t}: "name" must be a non-empty string`);const n=r.trim();if(!/^[a-zA-Z_][a-zA-Z0-9_-]*$/.test(n))throw new Error(`Section "${n}": "name" can only contain letters, numbers, underscores, and hyphens, and must start with a letter or underscore`);if(n.length>iparam_constants_1.IPARAM_DEFN_MAX_LENGTHS.NAME)throw new Error(`Section "${n}": "name" must be between 1 and ${iparam_constants_1.IPARAM_DEFN_MAX_LENGTHS.NAME} characters`);return n}validateParamName(e,t,r){const n=e.name;if(!validatorUtils.isNonEmptyString(n))throw new Error(`Section "${t}": parameter at index ${r}: "name" must be a non-empty string`);const a=n.trim();if(!/^[a-zA-Z_][a-zA-Z0-9_-]*$/.test(a))throw new Error(`Parameter "${t}.${a}": "name" can only contain letters, numbers, underscores, and hyphens, and must start with a letter or underscore`);if(a.length>iparam_constants_1.IPARAM_DEFN_MAX_LENGTHS.NAME)throw new Error(`Parameter "${t}.${a}": "name" must be between 1 and ${iparam_constants_1.IPARAM_DEFN_MAX_LENGTHS.NAME} characters`);return a}validateType(e,t){const r=e.type;if(!r||!common_1.VALID_IPARAM_TYPES.includes(r))throw new Error(`Parameter "${t}": "type" must be one of: ${common_1.VALID_IPARAM_TYPES.join(", ")}`)}validateOptions(e,t){const r=e.type;if(r!=="DROPDOWN"&&r!=="MULTISELECT_DROPDOWN"){if(Object.prototype.hasOwnProperty.call(e,"options"))throw new Error(`Parameter "${t}": "options" is only allowed for DROPDOWN and MULTISELECT_DROPDOWN types`);return}const n=e.options;if(!n||!Array.isArray(n)||n.length===0)throw new Error(`Parameter "${t}": "options" is required and must be a non-empty array of strings for ${r} type`);if(n.length>iparam_constants_1.OPTIONS_LIMITS.MAX_COUNT)throw new Error(`Parameter "${t}": "options" cannot exceed ${iparam_constants_1.OPTIONS_LIMITS.MAX_COUNT} items for ${r} type`);const a=new Set;for(let i=0;i<n.length;i++){if(typeof n[i]!="string")throw new Error(`Parameter "${t}": option at index ${i} must be a string`);const c=n[i].trim();if(c==="")throw new Error(`Parameter "${t}": option at index ${i} cannot be an empty string`);if(a.has(c))throw new Error(`Parameter "${t}": "options" must not contain duplicate entries`);if(a.add(c),c.length>iparam_constants_1.OPTIONS_LIMITS.MAX_OPTION_LENGTH)throw new Error(`Parameter "${t}": option at index ${i} cannot exceed ${iparam_constants_1.OPTIONS_LIMITS.MAX_OPTION_LENGTH} characters`)}}validateDefaultValue(e,t){const r=e.default;if(r!=null){if(typeof r=="string"&&r.trim()==="")throw new Error(`Parameter "${t}": default value cannot be an empty string. Either remove the "default" key, set it to null, or provide a non-empty value.`);try{this.inputsValidator.validateParamValue(e,r,t)}catch(n){const a=n.message.replace(/\bvalue\b/g,"default value");throw new Error(a)}}}}exports.IparamDefnsValidator=IparamDefnsValidator;

@@ -1,289 +0,1 @@

"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || (function () {
var ownKeys = function(o) {
ownKeys = Object.getOwnPropertyNames || function (o) {
var ar = [];
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
return ar;
};
return ownKeys(o);
};
return function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
__setModuleDefault(result, mod);
return result;
};
})();
Object.defineProperty(exports, "__esModule", { value: true });
exports.IparamInputsValidator = void 0;
const errors_1 = require("../errors");
const internal_logger_1 = require("../logger/internal-logger");
const iparam_constants_1 = require("./iparam-constants");
const validatorUtils = __importStar(require("./validator-utils"));
/**
* Validator for parameter inputs
* Validates input values against the sectioned iparamDefns
*/
class IparamInputsValidator {
constructor(fileSystem) {
this.fileSystem = fileSystem;
}
/**
* Validates whether the value counts as a provided input.
* Not whether it is allowed by iparam definitions—that is handled by {@link IparamInputsValidator.validateInputs}.
*/
static isProvidedIparamInputValue(value) {
if (value === undefined || value === null)
return false;
if (typeof value === 'string')
return value.trim() !== '';
if (Array.isArray(value))
return value.length > 0;
return true;
}
/**
* Validates and loads the iparam inputs from a file (no validation against iparamDefns).
* Only ensures the file is valid JSON and the root value is an object.
* @param {string} path - Path to the iparams.local.json file
* @returns {IparamInputs} The loaded inputs
* @throws {Error} If the file does not exist, cannot be read or parsed, or root is not an object
*/
validateAndGetIparamInputsFile(path) {
validatorUtils.ensureFileExists(this.fileSystem, path);
try {
const inputs = JSON.parse(this.fileSystem.readFileSync(path, 'utf8'));
if (typeof inputs !== 'object' || Array.isArray(inputs)) {
throw new Error('iparams.local.json must be an object');
}
return inputs;
}
catch (error) {
if (error instanceof SyntaxError) {
throw new Error(`Failed to parse iparams.local.json: ${error.message}`);
}
throw new Error(`Failed to read iparams.local.json: ${error.message}`);
}
}
/**
* Ensures the inputs value is a plain object
* @param {any} inputs - The value to check
* @throws {Error} If inputs is not a plain object
*/
ensureInputsIsObject(inputs) {
if (inputs === null || typeof inputs !== 'object' || Array.isArray(inputs)) {
throw new Error('Inputs must be an object');
}
}
/**
* Validates inputs against the iparamDefns (without applying defaults)
* Only validates provided values, does not include defaults in the result
* @param {IparamInputs} inputs - The input values to validate
* @param {IparamDefns} iparamDefns - The iparamDefns
* @returns {IparamInputs} The validated inputs (only provided values, no defaults)
* @throws {Error} If validation fails
* @throws {MissingRequiredParamsError} If required parameters are missing
*/
validateInputs(inputs, iparamDefns) {
this.ensureInputsIsObject(inputs);
const validatedInputs = {};
const missingRequired = [];
const sections = iparamDefns.installation_parameters?.sections ?? [];
const sectionByName = new Map(sections.map((section) => [section.name, section]));
for (const section of sections) {
const sectionInputs = inputs[section.name];
if (sectionInputs !== undefined && sectionInputs !== null) {
if (typeof sectionInputs !== 'object' || Array.isArray(sectionInputs)) {
throw new Error(`Section "${section.name}": inputs must be an object`);
}
}
const sectionObject = {};
for (const param of section.parameters) {
const sectionDotParam = `${section.name}.${param.name}`;
const value = sectionInputs?.[param.name];
if (IparamInputsValidator.isProvidedIparamInputValue(value)) {
this.validateParamValue(param, value, sectionDotParam);
sectionObject[param.name] = value;
}
else if (param.required && (param.default === undefined || param.default === null)) {
missingRequired.push(sectionDotParam);
}
}
if (Object.keys(sectionObject).length > 0) {
validatedInputs[section.name] = sectionObject;
}
}
if (missingRequired.length > 0) {
throw new errors_1.MissingRequiredParamsError(missingRequired);
}
for (const [sectionName, sectionInputs] of Object.entries(inputs)) {
const section = sectionByName.get(sectionName);
if (!section) {
internal_logger_1.__logger.warn(`Unknown section "${sectionName}" will be ignored`);
continue;
}
if (sectionInputs === undefined || sectionInputs === null)
continue;
if (typeof sectionInputs !== 'object' || Array.isArray(sectionInputs))
continue;
const knownParamNames = new Set(section.parameters.map((param) => param.name));
for (const key of Object.keys(sectionInputs)) {
if (!knownParamNames.has(key)) {
internal_logger_1.__logger.warn(`Unknown parameter "${sectionName}.${key}" will be ignored`);
}
}
}
return validatedInputs;
}
/**
* Validates a single parameter value against its parameter definition.
* @param {IparamDefn} param - The parameter definition
* @param {any} value - The value to validate
* @param {string} [sectionDotParam] - Optional section.param identifier for error messages (e.g. processing_fee_configuration.fee_percentage)
* @throws {Error} If the value is invalid
*/
validateParamValue(param, value, sectionDotParam = param.name) {
switch (param.type) {
case 'NUMBER':
this.validateNumber(sectionDotParam, value);
break;
case 'TEXT':
this.requireNonEmptyString(sectionDotParam, value, iparam_constants_1.IPARAM_VALUE_MAX_LENGTHS.TEXT);
break;
case 'SECRET':
this.requireNonEmptyString(sectionDotParam, value, iparam_constants_1.IPARAM_VALUE_MAX_LENGTHS.SECRET);
break;
case 'BOOLEAN':
this.validateBoolean(sectionDotParam, value);
break;
case 'URL':
this.validateUrl(sectionDotParam, value);
break;
case 'DATE':
this.validateDate(sectionDotParam, value);
break;
case 'DROPDOWN':
this.validateDropdown(param, value, sectionDotParam);
break;
case 'MULTISELECT_DROPDOWN':
this.validateMultiselectDropdown(param, value, sectionDotParam);
break;
default: {
const exhaustive = param.type;
throw new Error(`Parameter "${sectionDotParam}": unknown type "${exhaustive}"`);
}
}
}
/**
* Requires value to be a non-empty string, optionally with max length.
* @throws {Error} If not a string, empty after trim, or exceeds maxLength
*/
requireNonEmptyString(paramName, value, maxLength) {
if (!validatorUtils.isNonEmptyString(value)) {
throw new Error(`Parameter "${paramName}": value must be a non-empty string`);
}
if (maxLength !== undefined && value.length > maxLength) {
throw new Error(`Parameter "${paramName}": value cannot exceed ${maxLength} characters`);
}
}
/**
* Requires value to be one of the allowed options.
*/
requireInOptions(paramName, value, options) {
if (options.length === 0 || options.includes(value))
return;
throw new Error(`Parameter "${paramName}": value must be one of: ${options.join(', ')}`);
}
validateNumber(paramName, value) {
if (typeof value !== 'number' || !Number.isFinite(value)) {
throw new Error(`Parameter "${paramName}": value must be a finite number`);
}
if (value > Number.MAX_SAFE_INTEGER || value < Number.MIN_SAFE_INTEGER) {
throw new Error(`Parameter "${paramName}": value must be within the range of ${Number.MIN_SAFE_INTEGER} to ${Number.MAX_SAFE_INTEGER}`);
}
}
validateBoolean(paramName, value) {
if (typeof value !== 'boolean') {
throw new Error(`Parameter "${paramName}": value must be a boolean`);
}
}
validateUrl(paramName, value) {
this.requireNonEmptyString(paramName, value, iparam_constants_1.IPARAM_VALUE_MAX_LENGTHS.URL);
let parsed;
try {
parsed = new URL(value);
}
catch {
throw new Error(`Parameter "${paramName}": value must be a valid URL`);
}
if (!iparam_constants_1.IPARAM_URL_ALLOWED_PROTOCOLS.some((p) => p === parsed.protocol)) {
throw new Error(`Parameter "${paramName}": value must be a valid URL with protocol ${iparam_constants_1.IPARAM_URL_ALLOWED_PROTOCOLS.join(' or ')}`);
}
}
validateDate(paramName, value) {
this.requireNonEmptyString(paramName, value, iparam_constants_1.IPARAM_VALUE_MAX_LENGTHS.DATE);
const str = value;
if (!/^\d{4}-\d{2}-\d{2}$/.test(str)) {
throw new Error(`Parameter "${paramName}": value must be a valid date in YYYY-MM-DD format (e.g., 2025-12-31)`);
}
const [y, m, d] = str.split('-').map(Number);
const dateObj = new Date(Date.UTC(y, m - 1, d));
if (isNaN(dateObj.getTime()) ||
dateObj.getUTCFullYear() !== y ||
dateObj.getUTCMonth() !== m - 1 ||
dateObj.getUTCDate() !== d) {
throw new Error(`Parameter "${paramName}": value must be a valid date in YYYY-MM-DD format (e.g., 2025-12-31)`);
}
}
validateDropdown(param, value, sectionDotParam) {
if (typeof value !== 'string') {
throw new Error(`Parameter "${sectionDotParam}": value must be a string for DROPDOWN type`);
}
this.requireNonEmptyString(sectionDotParam, value);
if (param.options)
this.requireInOptions(sectionDotParam, value, param.options);
}
validateMultiselectDropdown(param, value, sectionDotParam) {
if (!Array.isArray(value)) {
throw new Error(`Parameter "${sectionDotParam}": value must be an array of strings for MULTISELECT_DROPDOWN type`);
}
if (value.length === 0) {
throw new Error(`Parameter "${sectionDotParam}": value must be a non-empty array of strings for MULTISELECT_DROPDOWN type`);
}
const seenTrimmed = new Set();
for (let i = 0; i < value.length; i++) {
try {
this.requireNonEmptyString(sectionDotParam, value[i]);
if (param.options)
this.requireInOptions(sectionDotParam, value[i], param.options);
}
catch (error) {
const msg = error.message.replace(/\bvalue\b/g, `value array item at index ${i}`);
throw new Error(msg);
}
const trimmed = value[i].trim();
if (seenTrimmed.has(trimmed)) {
throw new Error(`Parameter "${sectionDotParam}": multiselect value must not contain duplicate entries`);
}
seenTrimmed.add(trimmed);
}
}
}
exports.IparamInputsValidator = IparamInputsValidator;
"use strict";var __createBinding=this&&this.__createBinding||(Object.create?(function(s,e,r,t){t===void 0&&(t=r);var n=Object.getOwnPropertyDescriptor(e,r);(!n||("get"in n?!e.__esModule:n.writable||n.configurable))&&(n={enumerable:!0,get:function(){return e[r]}}),Object.defineProperty(s,t,n)}):(function(s,e,r,t){t===void 0&&(t=r),s[t]=e[r]})),__setModuleDefault=this&&this.__setModuleDefault||(Object.create?(function(s,e){Object.defineProperty(s,"default",{enumerable:!0,value:e})}):function(s,e){s.default=e}),__importStar=this&&this.__importStar||(function(){var s=function(e){return s=Object.getOwnPropertyNames||function(r){var t=[];for(var n in r)Object.prototype.hasOwnProperty.call(r,n)&&(t[t.length]=n);return t},s(e)};return function(e){if(e&&e.__esModule)return e;var r={};if(e!=null)for(var t=s(e),n=0;n<t.length;n++)t[n]!=="default"&&__createBinding(r,e,t[n]);return __setModuleDefault(r,e),r}})();Object.defineProperty(exports,"__esModule",{value:!0}),exports.IparamInputsValidator=void 0;const errors_1=require("../errors"),internal_logger_1=require("../logger/internal-logger"),iparam_constants_1=require("./iparam-constants"),validatorUtils=__importStar(require("./validator-utils"));class IparamInputsValidator{constructor(e){this.fileSystem=e}static isProvidedIparamInputValue(e){return e==null?!1:typeof e=="string"?e.trim()!=="":Array.isArray(e)?e.length>0:!0}validateAndGetIparamInputsFile(e){validatorUtils.ensureFileExists(this.fileSystem,e);try{const r=JSON.parse(this.fileSystem.readFileSync(e,"utf8"));if(typeof r!="object"||Array.isArray(r))throw new Error("iparams.local.json must be an object");return r}catch(r){throw r instanceof SyntaxError?new Error(`Failed to parse iparams.local.json: ${r.message}`):new Error(`Failed to read iparams.local.json: ${r.message}`)}}ensureInputsIsObject(e){if(e===null||typeof e!="object"||Array.isArray(e))throw new Error("Inputs must be an object")}validateInputs(e,r){this.ensureInputsIsObject(e);const t={},n=[],o=r.installation_parameters?.sections??[],l=new Map(o.map(i=>[i.name,i]));for(const i of o){const a=e[i.name];if(a!=null&&(typeof a!="object"||Array.isArray(a)))throw new Error(`Section "${i.name}": inputs must be an object`);const f={};for(const u of i.parameters){const c=`${i.name}.${u.name}`,d=a?.[u.name];IparamInputsValidator.isProvidedIparamInputValue(d)?(this.validateParamValue(u,d,c),f[u.name]=d):u.required&&(u.default===void 0||u.default===null)&&n.push(c)}Object.keys(f).length>0&&(t[i.name]=f)}if(n.length>0)throw new errors_1.MissingRequiredParamsError(n);for(const[i,a]of Object.entries(e)){const f=l.get(i);if(!f){internal_logger_1.__logger.warn(`Unknown section "${i}" will be ignored`);continue}if(a==null||typeof a!="object"||Array.isArray(a))continue;const u=new Set(f.parameters.map(c=>c.name));for(const c of Object.keys(a))u.has(c)||internal_logger_1.__logger.warn(`Unknown parameter "${i}.${c}" will be ignored`)}return t}validateParamValue(e,r,t=e.name){switch(e.type){case"NUMBER":this.validateNumber(t,r);break;case"TEXT":this.requireNonEmptyString(t,r,iparam_constants_1.IPARAM_VALUE_MAX_LENGTHS.TEXT);break;case"SECRET":this.requireNonEmptyString(t,r,iparam_constants_1.IPARAM_VALUE_MAX_LENGTHS.SECRET);break;case"BOOLEAN":this.validateBoolean(t,r);break;case"URL":this.validateUrl(t,r);break;case"DATE":this.validateDate(t,r);break;case"DROPDOWN":this.validateDropdown(e,r,t);break;case"MULTISELECT_DROPDOWN":this.validateMultiselectDropdown(e,r,t);break;default:{const n=e.type;throw new Error(`Parameter "${t}": unknown type "${n}"`)}}}requireNonEmptyString(e,r,t){if(!validatorUtils.isNonEmptyString(r))throw new Error(`Parameter "${e}": value must be a non-empty string`);if(t!==void 0&&r.length>t)throw new Error(`Parameter "${e}": value cannot exceed ${t} characters`)}requireInOptions(e,r,t){if(!(t.length===0||t.includes(r)))throw new Error(`Parameter "${e}": value must be one of: ${t.join(", ")}`)}validateNumber(e,r){if(typeof r!="number"||!Number.isFinite(r))throw new Error(`Parameter "${e}": value must be a finite number`);if(r>Number.MAX_SAFE_INTEGER||r<Number.MIN_SAFE_INTEGER)throw new Error(`Parameter "${e}": value must be within the range of ${Number.MIN_SAFE_INTEGER} to ${Number.MAX_SAFE_INTEGER}`)}validateBoolean(e,r){if(typeof r!="boolean")throw new Error(`Parameter "${e}": value must be a boolean`)}validateUrl(e,r){this.requireNonEmptyString(e,r,iparam_constants_1.IPARAM_VALUE_MAX_LENGTHS.URL);let t;try{t=new URL(r)}catch{throw new Error(`Parameter "${e}": value must be a valid URL`)}if(!iparam_constants_1.IPARAM_URL_ALLOWED_PROTOCOLS.some(n=>n===t.protocol))throw new Error(`Parameter "${e}": value must be a valid URL with protocol ${iparam_constants_1.IPARAM_URL_ALLOWED_PROTOCOLS.join(" or ")}`)}validateDate(e,r){this.requireNonEmptyString(e,r,iparam_constants_1.IPARAM_VALUE_MAX_LENGTHS.DATE);const t=r;if(!/^\d{4}-\d{2}-\d{2}$/.test(t))throw new Error(`Parameter "${e}": value must be a valid date in YYYY-MM-DD format (e.g., 2025-12-31)`);const[n,o,l]=t.split("-").map(Number),i=new Date(Date.UTC(n,o-1,l));if(isNaN(i.getTime())||i.getUTCFullYear()!==n||i.getUTCMonth()!==o-1||i.getUTCDate()!==l)throw new Error(`Parameter "${e}": value must be a valid date in YYYY-MM-DD format (e.g., 2025-12-31)`)}validateDropdown(e,r,t){if(typeof r!="string")throw new Error(`Parameter "${t}": value must be a string for DROPDOWN type`);this.requireNonEmptyString(t,r),e.options&&this.requireInOptions(t,r,e.options)}validateMultiselectDropdown(e,r,t){if(!Array.isArray(r))throw new Error(`Parameter "${t}": value must be an array of strings for MULTISELECT_DROPDOWN type`);if(r.length===0)throw new Error(`Parameter "${t}": value must be a non-empty array of strings for MULTISELECT_DROPDOWN type`);const n=new Set;for(let o=0;o<r.length;o++){try{this.requireNonEmptyString(t,r[o]),e.options&&this.requireInOptions(t,r[o],e.options)}catch(i){const a=i.message.replace(/\bvalue\b/g,`value array item at index ${o}`);throw new Error(a)}const l=r[o].trim();if(n.has(l))throw new Error(`Parameter "${t}": multiselect value must not contain duplicate entries`);n.add(l)}}}exports.IparamInputsValidator=IparamInputsValidator;

@@ -1,138 +0,1 @@

"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.ManifestValidator = void 0;
const semver_1 = __importDefault(require("semver"));
const internal_logger_1 = require("../logger/internal-logger");
/**
* ManifestValidator provides validation for Chargebee Apps application manifests
* Public implementation for validating user applications
*/
class ManifestValidator {
constructor(allowedModulesConfig, fileSystem) {
this.allowedModules = allowedModulesConfig || [];
this.fileSystem = fileSystem;
}
/**
* Validates a manifest file from disk
* @param {string} path - Path to the manifest.json file
* @returns {Object} The validated manifest
* @throws {Error} If manifest file is invalid or cannot be read
*/
validateAndGetManifestFile(path) {
if (!this.fileSystem.existsSync(path)) {
throw new Error(`manifest.json not found in user code directory`);
}
try {
const manifestContent = this.fileSystem.readFileSync(path, 'utf8');
const manifest = JSON.parse(manifestContent);
this.validate(manifest);
return manifest;
}
catch (error) {
if (error instanceof SyntaxError) {
throw new Error(`Failed to parse manifest file: ${error.message}`);
}
const err = error;
throw new Error(`Failed to read manifest file: ${err.message}`);
}
}
/**
* Validates a complete manifest object
* @param {Manifest} manifest - The manifest object to validate
* @returns {Manifest} The validated manifest
* @throws {Error} If manifest is invalid
*/
validate(manifest) {
// Basic structure validation
this.validateBasicStructure(manifest);
// Events validation
this.validateEvents(manifest);
// Dependencies validation
this.validateDependencies(manifest);
// Metadata validation
this.validateMetadata(manifest);
}
/**
* Validates the basic structure of the manifest
* @param {Object} manifest - The manifest object
* @throws {Error} If basic structure is invalid
*/
validateBasicStructure(manifest) {
if (!manifest || typeof manifest !== 'object') {
throw new Error('Manifest must be a valid object');
}
if (manifest.events && typeof manifest.events !== 'object') {
throw new Error('Events mapping must be an object');
}
if (manifest.dependencies && typeof manifest.dependencies !== 'object') {
throw new Error('Dependencies must be an object');
}
}
/**
* Validates the events configuration
* @param {Object} manifest - The manifest object
* @throws {Error} If events configuration is invalid
*/
validateEvents(manifest) {
if (!manifest.events) {
throw new Error('Invalid manifest: missing "events" mapping');
}
for (const [eventType, handler] of Object.entries(manifest.events)) {
if (!handler || typeof handler !== 'object') {
throw new Error(`Handler name for event "${eventType}" must be a non-empty string`);
}
}
}
/**
* Validates the dependencies configuration
* @param {Object} manifest - The manifest object
* @throws {Error} If dependencies are invalid
*/
validateDependencies(manifest) {
if (!manifest.dependencies) {
return; // Dependencies are optional
}
if (typeof manifest.dependencies !== 'object') {
throw new Error('Invalid manifest: "dependencies" must be an object');
}
for (const [depName, depVersion] of Object.entries(manifest.dependencies)) {
if (typeof depName !== 'string' || typeof depVersion !== 'string') {
throw new Error(`Invalid dependency in manifest: "${depName}" must have string name and version`);
}
// Check if module is allowed
const allowedModule = this.allowedModules.find(module => module.name === depName);
if (!allowedModule) {
throw new Error(`Dependency "${depName}" is not allowed in this environment`);
}
// Validate version range
if (!semver_1.default.validRange(depVersion)) {
throw new Error(`Invalid version range "${depVersion}" for dependency "${depName}"`);
}
// Check version constraints if specified
if (allowedModule.version) {
if (!semver_1.default.satisfies(depVersion, allowedModule.version)) {
internal_logger_1.__logger.warn(`Dependency "${depName}" version range "${depVersion}" differs from allowed version constraint "${allowedModule.version}" - proceeding with warning`);
}
}
else {
throw new Error(`Configuration error: Allowed module "${depName}" does not have a version constraint`);
}
internal_logger_1.__logger.debug(`Dependency "${depName}" version "${depVersion}" is allowed`);
}
internal_logger_1.__logger.debug(`Validated ${Object.keys(manifest.dependencies).length} dependencies in manifest`);
}
/**
* Validates the metadata fields
* @param {Object} manifest - The manifest object
*/
validateMetadata(manifest) {
// Check for reasonable limits
if (manifest.dependencies && Object.keys(manifest.dependencies).length > 10) {
internal_logger_1.__logger.warn('Large number of dependencies detected - consider minimizing dependencies for better performance');
}
}
}
exports.ManifestValidator = ManifestValidator;
"use strict";var __importDefault=this&&this.__importDefault||function(r){return r&&r.__esModule?r:{default:r}};Object.defineProperty(exports,"__esModule",{value:!0}),exports.ManifestValidator=void 0;const semver_1=__importDefault(require("semver")),internal_logger_1=require("../logger/internal-logger");class ManifestValidator{constructor(e,n){this.allowedModules=e||[],this.fileSystem=n}validateAndGetManifestFile(e){if(!this.fileSystem.existsSync(e))throw new Error("manifest.json not found in user code directory");try{const n=this.fileSystem.readFileSync(e,"utf8"),t=JSON.parse(n);return this.validate(t),t}catch(n){if(n instanceof SyntaxError)throw new Error(`Failed to parse manifest file: ${n.message}`);const t=n;throw new Error(`Failed to read manifest file: ${t.message}`)}}validate(e){this.validateBasicStructure(e),this.validateEvents(e),this.validateDependencies(e),this.validateMetadata(e)}validateBasicStructure(e){if(!e||typeof e!="object")throw new Error("Manifest must be a valid object");if(e.events&&typeof e.events!="object")throw new Error("Events mapping must be an object");if(e.dependencies&&typeof e.dependencies!="object")throw new Error("Dependencies must be an object")}validateEvents(e){if(!e.events)throw new Error('Invalid manifest: missing "events" mapping');for(const[n,t]of Object.entries(e.events))if(!t||typeof t!="object")throw new Error(`Handler name for event "${n}" must be a non-empty string`)}validateDependencies(e){if(e.dependencies){if(typeof e.dependencies!="object")throw new Error('Invalid manifest: "dependencies" must be an object');for(const[n,t]of Object.entries(e.dependencies)){if(typeof n!="string"||typeof t!="string")throw new Error(`Invalid dependency in manifest: "${n}" must have string name and version`);const i=this.allowedModules.find(o=>o.name===n);if(!i)throw new Error(`Dependency "${n}" is not allowed in this environment`);if(!semver_1.default.validRange(t))throw new Error(`Invalid version range "${t}" for dependency "${n}"`);if(i.version)semver_1.default.satisfies(t,i.version)||internal_logger_1.__logger.warn(`Dependency "${n}" version range "${t}" differs from allowed version constraint "${i.version}" - proceeding with warning`);else throw new Error(`Configuration error: Allowed module "${n}" does not have a version constraint`);internal_logger_1.__logger.debug(`Dependency "${n}" version "${t}" is allowed`)}internal_logger_1.__logger.debug(`Validated ${Object.keys(e.dependencies).length} dependencies in manifest`)}}validateMetadata(e){e.dependencies&&Object.keys(e.dependencies).length>10&&internal_logger_1.__logger.warn("Large number of dependencies detected - consider minimizing dependencies for better performance")}}exports.ManifestValidator=ManifestValidator;

@@ -1,43 +0,1 @@

"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.PackageValidator = void 0;
const path_1 = __importDefault(require("path"));
/**
* Package validator for validating app structure.
* This primarily validates the app directory and the structure of the app which developer bundles and uploads to Chargebee.
*/
class PackageValidator {
constructor(fileSystem) {
this.fileSystem = fileSystem;
}
/**
* Validates that the app directory exists
* @param {string} targetDir - Target directory path
* @returns {boolean} True if directory exists
*/
validateAppDirectoryExists(targetDir) {
return this.fileSystem.existsSync(targetDir);
}
/**
* Validates that manifest.json exists in the app directory
* @param {string} targetDir - Target directory path
* @returns {boolean} True if manifest.json exists
*/
validateManifestExists(targetDir) {
const manifestPath = path_1.default.join(targetDir, 'manifest.json');
return this.fileSystem.existsSync(manifestPath);
}
/**
* Validates that handler.js exists in the app directory
* @param {string} targetDir - Target directory path
* @returns {boolean} True if handler.js exists
*/
validateHandlerExists(targetDir) {
const handlerPath = path_1.default.join(targetDir, 'handler', 'handler.js');
return this.fileSystem.existsSync(handlerPath);
}
}
exports.PackageValidator = PackageValidator;
"use strict";var __importDefault=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(exports,"__esModule",{value:!0}),exports.PackageValidator=void 0;const path_1=__importDefault(require("path"));class PackageValidator{constructor(t){this.fileSystem=t}validateAppDirectoryExists(t){return this.fileSystem.existsSync(t)}validateManifestExists(t){const s=path_1.default.join(t,"manifest.json");return this.fileSystem.existsSync(s)}validateHandlerExists(t){const s=path_1.default.join(t,"handler","handler.js");return this.fileSystem.existsSync(s)}}exports.PackageValidator=PackageValidator;

@@ -1,26 +0,1 @@

"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.isNonEmptyString = isNonEmptyString;
exports.ensureFileExists = ensureFileExists;
const path_1 = __importDefault(require("path"));
/**
* True only when `value` is a string and is not empty or whitespace-only after trim.
* Logically the opposite of `(typeof value !== 'string' || value.trim() === '')`.
* @param {unknown} value - Value to check
* @returns {value is string} Whether `value` is a usable non-empty string
*/
function isNonEmptyString(value) {
return typeof value === 'string' && value.trim() !== '';
}
/**
* Throws if `filePath` does not exist on the given filesystem.
* Message uses the file basename, e.g. `iparams.json not found`.
*/
function ensureFileExists(fileSystem, filePath) {
if (!fileSystem.existsSync(filePath)) {
throw new Error(`${path_1.default.basename(filePath)} not found`);
}
}
"use strict";var __importDefault=this&&this.__importDefault||function(t){return t&&t.__esModule?t:{default:t}};Object.defineProperty(exports,"__esModule",{value:!0}),exports.isNonEmptyString=isNonEmptyString,exports.ensureFileExists=ensureFileExists;const path_1=__importDefault(require("path"));function isNonEmptyString(t){return typeof t=="string"&&t.trim()!==""}function ensureFileExists(t,e){if(!t.existsSync(e))throw new Error(`${path_1.default.basename(e)} not found`)}
{
"name": "@chargebee/chargebee-apps-shared",
"version": "0.0.1",
"version": "0.0.3",
"description": "Shared interfaces and utilities for Chargebee Apps CLI",

@@ -5,0 +5,0 @@ "main": "dist/index.js",