@codexsploitx/schemaapi 1.1.8 → 1.1.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1 @@
1
+ export declare function handleAudit(args: string[]): void;
package/dist/cli.js CHANGED
@@ -6865,7 +6865,7 @@ function loadSchemaApi() {
6865
6865
  return {};
6866
6866
  }
6867
6867
  }
6868
- function loadContractsModule(contractsDir) {
6868
+ function loadContractsModule$1(contractsDir) {
6869
6869
  const cwd = process.cwd();
6870
6870
  const baseDir = path__namespace.join(cwd, contractsDir || "contracts");
6871
6871
  const candidates = ["index.js", "index.cjs", "index.ts"];
@@ -6925,7 +6925,7 @@ function generateDocs(config) {
6925
6925
  if (adapter || contractsDir) {
6926
6926
  console.log(`Using config: adapter=${adapter || "unknown"}, contractsDir=${contractsDir}`);
6927
6927
  }
6928
- const contractsModule = loadContractsModule(contractsDir);
6928
+ const contractsModule = loadContractsModule$1(contractsDir);
6929
6929
  if (!contractsModule) {
6930
6930
  console.error(`Could not find contracts entry in ${contractsDir}. Expected index.js or index.cjs`);
6931
6931
  return;
@@ -7099,6 +7099,88 @@ function handleGenerate(args) {
7099
7099
  }
7100
7100
  }
7101
7101
 
7102
+ function loadContractsModule(contractsDir) {
7103
+ const cwd = process.cwd();
7104
+ const baseDir = path__namespace.join(cwd, contractsDir);
7105
+ const candidates = ["index.js", "index.cjs", "index.ts"];
7106
+ for (const file of candidates) {
7107
+ const fullPath = path__namespace.join(baseDir, file);
7108
+ if (fs__namespace.existsSync(fullPath)) {
7109
+ try {
7110
+ // We use require/import to load the contract objects
7111
+ // In a real TS environment, we might need ts-node/register if loading .ts directly
7112
+ // But assuming the user has compiled code or we are running in a compatible env:
7113
+ if (file.endsWith('.ts')) {
7114
+ require('ts-node/register');
7115
+ }
7116
+ return require(fullPath);
7117
+ }
7118
+ catch (error) {
7119
+ console.error(`Failed to load contracts module at ${fullPath}:`, (error && error.message) || error);
7120
+ return null;
7121
+ }
7122
+ }
7123
+ }
7124
+ return null;
7125
+ }
7126
+ function handleAudit(args) {
7127
+ const config = loadConfig();
7128
+ const contractsDir = config?.contractsDir || "contracts";
7129
+ console.log(`šŸ” Starting SchemaApi Audit in directory: ${contractsDir}`);
7130
+ const contractsModule = loadContractsModule(contractsDir);
7131
+ if (!contractsModule) {
7132
+ console.error(`āŒ Could not find contracts entry in ${contractsDir}. Make sure index.ts/js exists and exports your contracts.`);
7133
+ return;
7134
+ }
7135
+ let totalIssues = 0;
7136
+ const candidates = Object.values(contractsModule).filter((value) => value &&
7137
+ typeof value === "object" &&
7138
+ typeof value.docs === "function" // Duck typing for Contract
7139
+ );
7140
+ if (candidates.length === 0) {
7141
+ console.warn("āš ļø No contracts found exported in the entry file.");
7142
+ return;
7143
+ }
7144
+ candidates.forEach((contract, index) => {
7145
+ const docs = contract.docs(); // This returns the contract structure
7146
+ const routes = docs.routes || [];
7147
+ console.log(`\nšŸ“„ Contract #${index + 1}: Found ${routes.length} routes`);
7148
+ routes.forEach((route) => {
7149
+ const issues = [];
7150
+ const method = route.method;
7151
+ const pathStr = route.path;
7152
+ const fullRoute = `${method} ${pathStr}`;
7153
+ // 1. Security Check: Roles
7154
+ if (!route.roles || route.roles.length === 0) {
7155
+ issues.push(`āš ļø [Security] No roles defined. Endpoint is public? Consider adding explicit roles or 'public'.`);
7156
+ }
7157
+ // 2. Validation Check: Params
7158
+ // Basic check: if path has :param, schema should have it
7159
+ const pathParams = (pathStr.match(/:[a-zA-Z0-9_]+/g) || []).map((p) => p.substring(1));
7160
+ if (pathParams.length > 0) ;
7161
+ // 3. Completeness: Errors
7162
+ if (!route.errors || Object.keys(route.errors).length === 0) {
7163
+ issues.push(`ā„¹ļø [Best Practice] No error status codes defined. Clients won't know what errors to expect.`);
7164
+ }
7165
+ if (issues.length > 0) {
7166
+ console.log(` šŸ”ø ${fullRoute}`);
7167
+ issues.forEach(issue => console.log(` ${issue}`));
7168
+ totalIssues += issues.length;
7169
+ }
7170
+ else {
7171
+ console.log(` āœ… ${fullRoute}`);
7172
+ }
7173
+ });
7174
+ });
7175
+ console.log(`\nšŸ Audit complete.`);
7176
+ if (totalIssues > 0) {
7177
+ console.log(`Found ${totalIssues} potential issues.`);
7178
+ }
7179
+ else {
7180
+ console.log(`No obvious issues found. Great job! šŸŽ‰`);
7181
+ }
7182
+ }
7183
+
7102
7184
  async function cli(args) {
7103
7185
  const command = args[0];
7104
7186
  switch (command) {
@@ -7109,7 +7191,7 @@ async function cli(args) {
7109
7191
  handleGenerate(args.slice(1));
7110
7192
  break;
7111
7193
  case 'audit':
7112
- console.log('Running SchemaApi audit');
7194
+ handleAudit(args.slice(1));
7113
7195
  break;
7114
7196
  case 'adapters':
7115
7197
  console.log(`