@aloma.io/integration-sdk 3.8.54 ā 3.8.56
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/MULTI_RESOURCE_GUIDE.md +24 -21
 - package/OPENAPI_TO_CONNECTOR.md +146 -16
 - package/README.md +62 -10
 - package/build/cli.mjs +122 -33
 - package/build/openapi-to-connector.d.mts +92 -11
 - package/build/openapi-to-connector.mjs +968 -168
 - package/package.json +3 -1
 - package/src/cli.mts +140 -37
 - package/src/openapi-to-connector.mts +1092 -176
 - package/test/scenarios/README.md +148 -0
 - package/test/scenarios/complex/expected/controller.mts +271 -0
 - package/test/scenarios/complex/expected/orders-resource.mts +264 -0
 - package/test/scenarios/complex/expected/products-resource.mts +239 -0
 - package/test/scenarios/complex/specs/orders.json +362 -0
 - package/test/scenarios/complex/specs/products.json +308 -0
 - package/test/scenarios/simple/expected-controller.mts +60 -0
 - package/test/scenarios/simple/simple-api.json +39 -0
 - package/test/scenarios.test.mts +286 -0
 - package/test/verify-scenarios.mjs +298 -0
 - package/examples/api-without-servers.json +0 -32
 - package/examples/companies-resource-class.mts +0 -310
 - package/examples/companies-resource.mts +0 -310
 - package/examples/complete-example.sh +0 -116
 - package/examples/create-hubspot-connector.sh +0 -33
 - package/examples/generate-connector.sh +0 -35
 - package/examples/generated-controller.mts +0 -81
 - package/examples/hubspot-companies.json +0 -1889
 - package/examples/hubspot-contacts.json +0 -1919
 - package/examples/hubspot-controller-individual-params.mts +0 -323
 - package/examples/hubspot-controller-with-implementation.mts +0 -315
 - package/examples/hubspot-controller.mts +0 -192
 - package/examples/hubspot-lists.json +0 -5525
 - package/examples/main-controller-with-resources.mts +0 -35
 - package/examples/stripe.json +0 -182829
 - package/examples/utility-click.json +0 -8992
 
    
        package/build/cli.mjs
    CHANGED
    
    | 
         @@ -111,20 +111,16 @@ program 
     | 
|
| 
       111 
111 
     | 
    
         
             
                .option('--out <file>', 'output file path for the controller', 'src/controller/index.mts')
         
     | 
| 
       112 
112 
     | 
    
         
             
                .option('--resource <className>', 'Generate as a resource class with the specified class name (e.g., CompaniesResource)')
         
     | 
| 
       113 
113 
     | 
    
         
             
                .option('--multi-resource', 'Generate multiple resource files + main controller (requires multiple --spec files)')
         
     | 
| 
      
 114 
     | 
    
         
            +
                .option('--controller-only', 'Generate only the controller file, do not create full project structure')
         
     | 
| 
       114 
115 
     | 
    
         
             
                .option('--no-build', 'Skip installing dependencies and building the project')
         
     | 
| 
       115 
116 
     | 
    
         
             
                .action(async (name, options) => {
         
     | 
| 
       116 
117 
     | 
    
         
             
                name = name.replace(/[\/\.]/gi, '');
         
     | 
| 
       117 
118 
     | 
    
         
             
                if (!name)
         
     | 
| 
       118 
119 
     | 
    
         
             
                    throw new Error('name is empty');
         
     | 
| 
       119 
     | 
    
         
            -
                const target = `${process.cwd()}/${name}`;
         
     | 
| 
       120 
120 
     | 
    
         
             
                try {
         
     | 
| 
       121 
121 
     | 
    
         
             
                    // Read and parse the OpenAPI spec
         
     | 
| 
       122 
122 
     | 
    
         
             
                    const specContent = fs.readFileSync(options.spec, 'utf-8');
         
     | 
| 
       123 
123 
     | 
    
         
             
                    const spec = OpenAPIToConnector.parseSpec(specContent);
         
     | 
| 
       124 
     | 
    
         
            -
                    // Create the connector project structure
         
     | 
| 
       125 
     | 
    
         
            -
                    fs.mkdirSync(target);
         
     | 
| 
       126 
     | 
    
         
            -
                    console.log('Creating connector project...');
         
     | 
| 
       127 
     | 
    
         
            -
                    extract({ ...options, target, name });
         
     | 
| 
       128 
124 
     | 
    
         
             
                    // Generate the controller from OpenAPI spec
         
     | 
| 
       129 
125 
     | 
    
         
             
                    const generator = new OpenAPIToConnector(spec, name);
         
     | 
| 
       130 
126 
     | 
    
         
             
                    let controllerCode;
         
     | 
| 
         @@ -136,44 +132,66 @@ program 
     | 
|
| 
       136 
132 
     | 
    
         
             
                        console.log('Generating controller from OpenAPI specification...');
         
     | 
| 
       137 
133 
     | 
    
         
             
                        controllerCode = generator.generateController();
         
     | 
| 
       138 
134 
     | 
    
         
             
                    }
         
     | 
| 
       139 
     | 
    
         
            -
                     
     | 
| 
       140 
     | 
    
         
            -
             
     | 
| 
       141 
     | 
    
         
            -
             
     | 
| 
       142 
     | 
    
         
            -
             
     | 
| 
       143 
     | 
    
         
            -
             
     | 
| 
       144 
     | 
    
         
            -
             
     | 
| 
       145 
     | 
    
         
            -
             
     | 
| 
       146 
     | 
    
         
            -
             
     | 
| 
       147 
     | 
    
         
            -
             
     | 
| 
       148 
     | 
    
         
            -
             
     | 
| 
       149 
     | 
    
         
            -
             
     | 
| 
      
 135 
     | 
    
         
            +
                    if (options.controllerOnly) {
         
     | 
| 
      
 136 
     | 
    
         
            +
                        // Controller-only mode: just generate the controller file
         
     | 
| 
      
 137 
     | 
    
         
            +
                        const controllerPath = path.resolve(options.out);
         
     | 
| 
      
 138 
     | 
    
         
            +
                        fs.mkdirSync(path.dirname(controllerPath), { recursive: true });
         
     | 
| 
      
 139 
     | 
    
         
            +
                        fs.writeFileSync(controllerPath, controllerCode);
         
     | 
| 
      
 140 
     | 
    
         
            +
                        console.log(`\nā
 Success! Generated controller from OpenAPI specification
         
     | 
| 
      
 141 
     | 
    
         
            +
            š Connector name: ${name}
         
     | 
| 
      
 142 
     | 
    
         
            +
            š Found ${generator.getOperationsCount()} operations
         
     | 
| 
      
 143 
     | 
    
         
            +
            š Controller file: ${controllerPath}
         
     | 
| 
      
 144 
     | 
    
         
            +
                  
         
     | 
| 
      
 145 
     | 
    
         
            +
            Controller file generated successfully! You can now use it in your existing project.`);
         
     | 
| 
       150 
146 
     | 
    
         
             
                    }
         
     | 
| 
       151 
     | 
    
         
            -
                     
     | 
| 
       152 
     | 
    
         
            -
                         
     | 
| 
      
 147 
     | 
    
         
            +
                    else {
         
     | 
| 
      
 148 
     | 
    
         
            +
                        // Full project mode: create complete project structure
         
     | 
| 
      
 149 
     | 
    
         
            +
                        const target = `${process.cwd()}/${name}`;
         
     | 
| 
      
 150 
     | 
    
         
            +
                        // Create the connector project structure
         
     | 
| 
      
 151 
     | 
    
         
            +
                        fs.mkdirSync(target);
         
     | 
| 
      
 152 
     | 
    
         
            +
                        console.log('Creating connector project...');
         
     | 
| 
      
 153 
     | 
    
         
            +
                        extract({ ...options, target, name });
         
     | 
| 
      
 154 
     | 
    
         
            +
                        // Write the generated controller
         
     | 
| 
      
 155 
     | 
    
         
            +
                        const controllerPath = `${target}/${options.out}`;
         
     | 
| 
      
 156 
     | 
    
         
            +
                        fs.mkdirSync(path.dirname(controllerPath), { recursive: true });
         
     | 
| 
      
 157 
     | 
    
         
            +
                        fs.writeFileSync(controllerPath, controllerCode);
         
     | 
| 
      
 158 
     | 
    
         
            +
                        console.log('Generating keys...');
         
     | 
| 
      
 159 
     | 
    
         
            +
                        await generateKeys({ target });
         
     | 
| 
      
 160 
     | 
    
         
            +
                        if (options.build !== false) {
         
     | 
| 
      
 161 
     | 
    
         
            +
                            console.log('Installing dependencies...');
         
     | 
| 
      
 162 
     | 
    
         
            +
                            await exec(`cd ${target}; yarn --ignore-engines`);
         
     | 
| 
      
 163 
     | 
    
         
            +
                            console.log('Building...');
         
     | 
| 
      
 164 
     | 
    
         
            +
                            await exec(`cd ${target}; yarn build`);
         
     | 
| 
      
 165 
     | 
    
         
            +
                        }
         
     | 
| 
      
 166 
     | 
    
         
            +
                        const nextSteps = options.build !== false
         
     | 
| 
      
 167 
     | 
    
         
            +
                            ? `Next steps:
         
     | 
| 
       153 
168 
     | 
    
         
             
            1.) Add the connector to a workspace
         
     | 
| 
       154 
169 
     | 
    
         
             
            2.) Edit ./${name}/.env and insert the registration token
         
     | 
| 
       155 
170 
     | 
    
         
             
            3.) Implement the actual API calls in each method in ${options.out}
         
     | 
| 
       156 
171 
     | 
    
         
             
            4.) Start the connector with cd ./${name}/; yarn start`
         
     | 
| 
       157 
     | 
    
         
            -
             
     | 
| 
      
 172 
     | 
    
         
            +
                            : `Next steps:
         
     | 
| 
       158 
173 
     | 
    
         
             
            1.) Install dependencies: cd ./${name}/ && yarn --ignore-engines
         
     | 
| 
       159 
174 
     | 
    
         
             
            2.) Implement the actual API calls in each method in ${options.out}
         
     | 
| 
       160 
175 
     | 
    
         
             
            3.) Build the project: yarn build
         
     | 
| 
       161 
176 
     | 
    
         
             
            4.) Add the connector to a workspace
         
     | 
| 
       162 
177 
     | 
    
         
             
            5.) Edit ./${name}/.env and insert the registration token
         
     | 
| 
       163 
178 
     | 
    
         
             
            6.) Start the connector: yarn start`;
         
     | 
| 
       164 
     | 
    
         
            -
             
     | 
| 
       165 
     | 
    
         
            -
            ā
 Success! Generated connector from OpenAPI specification
         
     | 
| 
      
 179 
     | 
    
         
            +
                        console.log(`\nā
 Success! Generated connector from OpenAPI specification
         
     | 
| 
       166 
180 
     | 
    
         
             
            š Connector name: ${name}
         
     | 
| 
       167 
181 
     | 
    
         
             
            š Found ${generator.getOperationsCount()} operations
         
     | 
| 
       168 
182 
     | 
    
         
             
            š Controller generated: ${options.out}
         
     | 
| 
       169 
183 
     | 
    
         | 
| 
       170 
184 
     | 
    
         
             
            ${nextSteps}`);
         
     | 
| 
      
 185 
     | 
    
         
            +
                    }
         
     | 
| 
       171 
186 
     | 
    
         
             
                }
         
     | 
| 
       172 
187 
     | 
    
         
             
                catch (error) {
         
     | 
| 
       173 
188 
     | 
    
         
             
                    console.error('ā Error:', error instanceof Error ? error.message : 'Unknown error');
         
     | 
| 
       174 
     | 
    
         
            -
                    // Clean up on error
         
     | 
| 
       175 
     | 
    
         
            -
                    if ( 
     | 
| 
       176 
     | 
    
         
            -
                         
     | 
| 
      
 189 
     | 
    
         
            +
                    // Clean up on error (only if we created a project directory)
         
     | 
| 
      
 190 
     | 
    
         
            +
                    if (!options.controllerOnly) {
         
     | 
| 
      
 191 
     | 
    
         
            +
                        const target = `${process.cwd()}/${name}`;
         
     | 
| 
      
 192 
     | 
    
         
            +
                        if (fs.existsSync(target)) {
         
     | 
| 
      
 193 
     | 
    
         
            +
                            fs.rmSync(target, { recursive: true, force: true });
         
     | 
| 
      
 194 
     | 
    
         
            +
                        }
         
     | 
| 
       177 
195 
     | 
    
         
             
                    }
         
     | 
| 
       178 
196 
     | 
    
         
             
                    process.exit(1);
         
     | 
| 
       179 
197 
     | 
    
         
             
                }
         
     | 
| 
         @@ -223,6 +241,7 @@ program 
     | 
|
| 
       223 
241 
     | 
    
         
             
                    extract({ ...options, target, name });
         
     | 
| 
       224 
242 
     | 
    
         
             
                    // Generate each resource
         
     | 
| 
       225 
243 
     | 
    
         
             
                    const resources = [];
         
     | 
| 
      
 244 
     | 
    
         
            +
                    const parsedResourceSpecs = [];
         
     | 
| 
       226 
245 
     | 
    
         
             
                    let baseUrl = options.baseUrl;
         
     | 
| 
       227 
246 
     | 
    
         
             
                    for (const { className, specFile } of resourceSpecs) {
         
     | 
| 
       228 
247 
     | 
    
         
             
                        console.log(`Generating ${className} from ${specFile}...`);
         
     | 
| 
         @@ -242,12 +261,13 @@ program 
     | 
|
| 
       242 
261 
     | 
    
         
             
                        fs.mkdirSync(path.dirname(resourcePath), { recursive: true });
         
     | 
| 
       243 
262 
     | 
    
         
             
                        fs.writeFileSync(resourcePath, resourceCode);
         
     | 
| 
       244 
263 
     | 
    
         
             
                        resources.push({ className, fileName });
         
     | 
| 
      
 264 
     | 
    
         
            +
                        parsedResourceSpecs.push({ fileName, spec });
         
     | 
| 
       245 
265 
     | 
    
         
             
                    }
         
     | 
| 
       246 
266 
     | 
    
         
             
                    // Generate the main controller
         
     | 
| 
       247 
267 
     | 
    
         
             
                    console.log('Generating main controller...');
         
     | 
| 
       248 
268 
     | 
    
         
             
                    const firstSpec = OpenAPIToConnector.parseSpec(fs.readFileSync(resourceSpecs[0].specFile, 'utf-8'));
         
     | 
| 
       249 
269 
     | 
    
         
             
                    const mainGenerator = new OpenAPIToConnector(firstSpec, name);
         
     | 
| 
       250 
     | 
    
         
            -
                    const mainControllerCode = mainGenerator.generateMainController(resources);
         
     | 
| 
      
 270 
     | 
    
         
            +
                    const mainControllerCode = mainGenerator.generateMainController(resources, parsedResourceSpecs);
         
     | 
| 
       251 
271 
     | 
    
         
             
                    // Write the main controller
         
     | 
| 
       252 
272 
     | 
    
         
             
                    const controllerPath = `${target}/src/controller/index.mts`;
         
     | 
| 
       253 
273 
     | 
    
         
             
                    fs.writeFileSync(controllerPath, mainControllerCode);
         
     | 
| 
         @@ -296,12 +316,16 @@ program 
     | 
|
| 
       296 
316 
     | 
    
         
             
                if (!fs.existsSync(target)) {
         
     | 
| 
       297 
317 
     | 
    
         
             
                    throw new Error(`Project path does not exist: ${target}`);
         
     | 
| 
       298 
318 
     | 
    
         
             
                }
         
     | 
| 
      
 319 
     | 
    
         
            +
                const controllerPath = `${target}/src/controller/index.mts`;
         
     | 
| 
      
 320 
     | 
    
         
            +
                if (!fs.existsSync(controllerPath)) {
         
     | 
| 
      
 321 
     | 
    
         
            +
                    throw new Error(`Controller file not found: ${controllerPath}. This might not be a multi-resource connector project.`);
         
     | 
| 
      
 322 
     | 
    
         
            +
                }
         
     | 
| 
       299 
323 
     | 
    
         
             
                try {
         
     | 
| 
       300 
324 
     | 
    
         
             
                    console.log(`Adding ${options.className} resource to existing project...`);
         
     | 
| 
       301 
325 
     | 
    
         
             
                    // Read and parse the OpenAPI spec
         
     | 
| 
       302 
326 
     | 
    
         
             
                    const specContent = fs.readFileSync(options.spec, 'utf-8');
         
     | 
| 
       303 
327 
     | 
    
         
             
                    const spec = OpenAPIToConnector.parseSpec(specContent);
         
     | 
| 
       304 
     | 
    
         
            -
                    // Generate the resource  
     | 
| 
      
 328 
     | 
    
         
            +
                    // Generate the resource functions file (new function-based pattern)
         
     | 
| 
       305 
329 
     | 
    
         
             
                    const generator = new OpenAPIToConnector(spec, 'Resource');
         
     | 
| 
       306 
330 
     | 
    
         
             
                    const resourceCode = generator.generateResourceClass(options.className);
         
     | 
| 
       307 
331 
     | 
    
         
             
                    // Write the resource file
         
     | 
| 
         @@ -309,18 +333,83 @@ program 
     | 
|
| 
       309 
333 
     | 
    
         
             
                    const resourcePath = `${target}/src/resources/${fileName}.mts`;
         
     | 
| 
       310 
334 
     | 
    
         
             
                    fs.mkdirSync(path.dirname(resourcePath), { recursive: true });
         
     | 
| 
       311 
335 
     | 
    
         
             
                    fs.writeFileSync(resourcePath, resourceCode);
         
     | 
| 
       312 
     | 
    
         
            -
                     
     | 
| 
       313 
     | 
    
         
            -
                    console.log(' 
     | 
| 
       314 
     | 
    
         
            -
                     
     | 
| 
       315 
     | 
    
         
            -
                     
     | 
| 
       316 
     | 
    
         
            -
                     
     | 
| 
      
 336 
     | 
    
         
            +
                    // Update the main controller to include the new resource
         
     | 
| 
      
 337 
     | 
    
         
            +
                    console.log('Updating main controller...');
         
     | 
| 
      
 338 
     | 
    
         
            +
                    let controllerContent = fs.readFileSync(controllerPath, 'utf-8');
         
     | 
| 
      
 339 
     | 
    
         
            +
                    // Add import
         
     | 
| 
      
 340 
     | 
    
         
            +
                    const importStatement = `import * as ${fileName}Functions from '../resources/${fileName}.mjs';`;
         
     | 
| 
      
 341 
     | 
    
         
            +
                    if (!controllerContent.includes(importStatement)) {
         
     | 
| 
      
 342 
     | 
    
         
            +
                        // Find the last import and add after it
         
     | 
| 
      
 343 
     | 
    
         
            +
                        const importRegex = /^import.*from.*?;$/gm;
         
     | 
| 
      
 344 
     | 
    
         
            +
                        const imports = controllerContent.match(importRegex);
         
     | 
| 
      
 345 
     | 
    
         
            +
                        if (imports && imports.length > 0) {
         
     | 
| 
      
 346 
     | 
    
         
            +
                            const lastImport = imports[imports.length - 1];
         
     | 
| 
      
 347 
     | 
    
         
            +
                            controllerContent = controllerContent.replace(lastImport, `${lastImport}\n${importStatement}`);
         
     | 
| 
      
 348 
     | 
    
         
            +
                        }
         
     | 
| 
      
 349 
     | 
    
         
            +
                        else {
         
     | 
| 
      
 350 
     | 
    
         
            +
                            // If no imports found, add at the beginning
         
     | 
| 
      
 351 
     | 
    
         
            +
                            controllerContent = `${importStatement}\n\n${controllerContent}`;
         
     | 
| 
      
 352 
     | 
    
         
            +
                        }
         
     | 
| 
      
 353 
     | 
    
         
            +
                    }
         
     | 
| 
      
 354 
     | 
    
         
            +
                    // Add property declaration
         
     | 
| 
      
 355 
     | 
    
         
            +
                    const propertyDeclaration = `  ${fileName}: any = {};`;
         
     | 
| 
      
 356 
     | 
    
         
            +
                    if (!controllerContent.includes(propertyDeclaration)) {
         
     | 
| 
      
 357 
     | 
    
         
            +
                        // Find the existing properties and add the new one
         
     | 
| 
      
 358 
     | 
    
         
            +
                        const propertyRegex = /^  \w+: any = \{\};$/gm;
         
     | 
| 
      
 359 
     | 
    
         
            +
                        const properties = controllerContent.match(propertyRegex);
         
     | 
| 
      
 360 
     | 
    
         
            +
                        if (properties && properties.length > 0) {
         
     | 
| 
      
 361 
     | 
    
         
            +
                            const lastProperty = properties[properties.length - 1];
         
     | 
| 
      
 362 
     | 
    
         
            +
                            controllerContent = controllerContent.replace(lastProperty, `${lastProperty}\n${propertyDeclaration}`);
         
     | 
| 
      
 363 
     | 
    
         
            +
                        }
         
     | 
| 
      
 364 
     | 
    
         
            +
                        else {
         
     | 
| 
      
 365 
     | 
    
         
            +
                            // Add after class declaration
         
     | 
| 
      
 366 
     | 
    
         
            +
                            controllerContent = controllerContent.replace(/^export default class Controller extends AbstractController \{$/gm, `export default class Controller extends AbstractController {\n${propertyDeclaration}`);
         
     | 
| 
      
 367 
     | 
    
         
            +
                        }
         
     | 
| 
      
 368 
     | 
    
         
            +
                    }
         
     | 
| 
      
 369 
     | 
    
         
            +
                    // Add binding in start() method
         
     | 
| 
      
 370 
     | 
    
         
            +
                    const bindingStatement = `    this.bindResourceFunctions('${fileName}', ${fileName}Functions);`;
         
     | 
| 
      
 371 
     | 
    
         
            +
                    if (!controllerContent.includes(bindingStatement)) {
         
     | 
| 
      
 372 
     | 
    
         
            +
                        // Find the existing bindings and add the new one
         
     | 
| 
      
 373 
     | 
    
         
            +
                        const bindingRegex = /^    this\.bindResourceFunctions\(.*?\);$/gm;
         
     | 
| 
      
 374 
     | 
    
         
            +
                        const bindings = controllerContent.match(bindingRegex);
         
     | 
| 
      
 375 
     | 
    
         
            +
                        if (bindings && bindings.length > 0) {
         
     | 
| 
      
 376 
     | 
    
         
            +
                            const lastBinding = bindings[bindings.length - 1];
         
     | 
| 
      
 377 
     | 
    
         
            +
                            controllerContent = controllerContent.replace(lastBinding, `${lastBinding}\n${bindingStatement}`);
         
     | 
| 
      
 378 
     | 
    
         
            +
                        }
         
     | 
| 
      
 379 
     | 
    
         
            +
                    }
         
     | 
| 
      
 380 
     | 
    
         
            +
                    // Write the updated controller
         
     | 
| 
      
 381 
     | 
    
         
            +
                    fs.writeFileSync(controllerPath, controllerContent);
         
     | 
| 
      
 382 
     | 
    
         
            +
                    // Generate exposed methods for the new resource
         
     | 
| 
      
 383 
     | 
    
         
            +
                    console.log('Generating exposed methods for the new resource...');
         
     | 
| 
      
 384 
     | 
    
         
            +
                    const resources = [{ className: options.className, fileName }];
         
     | 
| 
      
 385 
     | 
    
         
            +
                    const resourceSpecs = [{ fileName, spec }];
         
     | 
| 
      
 386 
     | 
    
         
            +
                    // Create a temporary generator to generate just the exposed methods for this resource
         
     | 
| 
      
 387 
     | 
    
         
            +
                    const tempGenerator = new OpenAPIToConnector(spec, 'temp');
         
     | 
| 
      
 388 
     | 
    
         
            +
                    const exposedMethods = tempGenerator.generateExposedResourceMethods(resources, resourceSpecs);
         
     | 
| 
      
 389 
     | 
    
         
            +
                    // Add the exposed methods to the controller before the closing brace
         
     | 
| 
      
 390 
     | 
    
         
            +
                    if (exposedMethods.trim()) {
         
     | 
| 
      
 391 
     | 
    
         
            +
                        controllerContent = fs.readFileSync(controllerPath, 'utf-8');
         
     | 
| 
      
 392 
     | 
    
         
            +
                        // Find the last method and add the new exposed methods
         
     | 
| 
      
 393 
     | 
    
         
            +
                        const lastBrace = controllerContent.lastIndexOf('}');
         
     | 
| 
      
 394 
     | 
    
         
            +
                        if (lastBrace !== -1) {
         
     | 
| 
      
 395 
     | 
    
         
            +
                            const beforeBrace = controllerContent.substring(0, lastBrace);
         
     | 
| 
      
 396 
     | 
    
         
            +
                            const afterBrace = controllerContent.substring(lastBrace);
         
     | 
| 
      
 397 
     | 
    
         
            +
                            const updatedContent = `${beforeBrace}\n${exposedMethods}\n${afterBrace}`;
         
     | 
| 
      
 398 
     | 
    
         
            +
                            fs.writeFileSync(controllerPath, updatedContent);
         
     | 
| 
      
 399 
     | 
    
         
            +
                        }
         
     | 
| 
      
 400 
     | 
    
         
            +
                    }
         
     | 
| 
      
 401 
     | 
    
         
            +
                    console.log(`ā
 Resource ${options.className} added successfully!`);
         
     | 
| 
      
 402 
     | 
    
         
            +
                    console.log(`š Resource functions: ${resourcePath}`);
         
     | 
| 
      
 403 
     | 
    
         
            +
                    console.log(`šļø  Controller updated: ${controllerPath}`);
         
     | 
| 
      
 404 
     | 
    
         
            +
                    console.log(`\nš The new resource is fully integrated and ready to use!`);
         
     | 
| 
       317 
405 
     | 
    
         
             
                    if (options.build !== false) {
         
     | 
| 
       318 
     | 
    
         
            -
                        console.log('\ 
     | 
| 
      
 406 
     | 
    
         
            +
                        console.log('\nšØ Building project...');
         
     | 
| 
       319 
407 
     | 
    
         
             
                        await exec(`cd "${target}"; yarn build`);
         
     | 
| 
      
 408 
     | 
    
         
            +
                        console.log('ā
 Build complete!');
         
     | 
| 
       320 
409 
     | 
    
         
             
                    }
         
     | 
| 
       321 
410 
     | 
    
         
             
                }
         
     | 
| 
       322 
411 
     | 
    
         
             
                catch (error) {
         
     | 
| 
       323 
     | 
    
         
            -
                    console.error('Error adding resource:', error.message);
         
     | 
| 
      
 412 
     | 
    
         
            +
                    console.error('ā Error adding resource:', error.message);
         
     | 
| 
       324 
413 
     | 
    
         
             
                    process.exit(1);
         
     | 
| 
       325 
414 
     | 
    
         
             
                }
         
     | 
| 
       326 
415 
     | 
    
         
             
            });
         
     | 
| 
         @@ -20,10 +20,6 @@ export declare class OpenAPIToConnector { 
     | 
|
| 
       20 
20 
     | 
    
         
             
                 * Generate method name from operation info
         
     | 
| 
       21 
21 
     | 
    
         
             
                 */
         
     | 
| 
       22 
22 
     | 
    
         
             
                private generateMethodName;
         
     | 
| 
       23 
     | 
    
         
            -
                /**
         
     | 
| 
       24 
     | 
    
         
            -
                 * Generate JSDoc comment for an operation
         
     | 
| 
       25 
     | 
    
         
            -
                 */
         
     | 
| 
       26 
     | 
    
         
            -
                private generateJSDoc;
         
     | 
| 
       27 
23 
     | 
    
         
             
                /**
         
     | 
| 
       28 
24 
     | 
    
         
             
                 * Get the number of operations in the OpenAPI spec
         
     | 
| 
       29 
25 
     | 
    
         
             
                 */
         
     | 
| 
         @@ -33,26 +29,111 @@ export declare class OpenAPIToConnector { 
     | 
|
| 
       33 
29 
     | 
    
         
             
                 */
         
     | 
| 
       34 
30 
     | 
    
         
             
                private generateMethodSignature;
         
     | 
| 
       35 
31 
     | 
    
         
             
                /**
         
     | 
| 
       36 
     | 
    
         
            -
                 *  
     | 
| 
      
 32 
     | 
    
         
            +
                 * Resolve a schema reference to a TypeScript type name
         
     | 
| 
      
 33 
     | 
    
         
            +
                 */
         
     | 
| 
      
 34 
     | 
    
         
            +
                private resolveSchemaRef;
         
     | 
| 
      
 35 
     | 
    
         
            +
                /**
         
     | 
| 
      
 36 
     | 
    
         
            +
                 * Sanitize a name to be a valid TypeScript identifier
         
     | 
| 
      
 37 
     | 
    
         
            +
                 */
         
     | 
| 
      
 38 
     | 
    
         
            +
                private sanitizeTypeName;
         
     | 
| 
      
 39 
     | 
    
         
            +
                /**
         
     | 
| 
      
 40 
     | 
    
         
            +
                 * Get TypeScript type from schema object
         
     | 
| 
      
 41 
     | 
    
         
            +
                 */
         
     | 
| 
      
 42 
     | 
    
         
            +
                private getTypeFromSchema;
         
     | 
| 
      
 43 
     | 
    
         
            +
                /**
         
     | 
| 
      
 44 
     | 
    
         
            +
                 * Get TypeScript type for request body
         
     | 
| 
      
 45 
     | 
    
         
            +
                 */
         
     | 
| 
      
 46 
     | 
    
         
            +
                private getRequestBodyType;
         
     | 
| 
      
 47 
     | 
    
         
            +
                /**
         
     | 
| 
      
 48 
     | 
    
         
            +
                 * Add request body properties directly to options array (flatten the body)
         
     | 
| 
      
 49 
     | 
    
         
            +
                 */
         
     | 
| 
      
 50 
     | 
    
         
            +
                private addRequestBodyProperties;
         
     | 
| 
      
 51 
     | 
    
         
            +
                /**
         
     | 
| 
      
 52 
     | 
    
         
            +
                 * Get TypeScript type for response
         
     | 
| 
       37 
53 
     | 
    
         
             
                 */
         
     | 
| 
       38 
     | 
    
         
            -
                private  
     | 
| 
      
 54 
     | 
    
         
            +
                private getResponseType;
         
     | 
| 
       39 
55 
     | 
    
         
             
                /**
         
     | 
| 
       40 
     | 
    
         
            -
                 *  
     | 
| 
      
 56 
     | 
    
         
            +
                 * Get TypeScript type for a parameter based on its schema
         
     | 
| 
       41 
57 
     | 
    
         
             
                 */
         
     | 
| 
       42 
     | 
    
         
            -
                private  
     | 
| 
      
 58 
     | 
    
         
            +
                private getParameterType;
         
     | 
| 
       43 
59 
     | 
    
         
             
                /**
         
     | 
| 
       44 
     | 
    
         
            -
                 * Generate  
     | 
| 
      
 60 
     | 
    
         
            +
                 * Generate method implementation code for controller methods with discrete path parameters
         
     | 
| 
      
 61 
     | 
    
         
            +
                 */
         
     | 
| 
      
 62 
     | 
    
         
            +
                private generateControllerMethodImplementation;
         
     | 
| 
      
 63 
     | 
    
         
            +
                /**
         
     | 
| 
      
 64 
     | 
    
         
            +
                 * Generate method implementation for resource functions (using this.api instead of this.controller)
         
     | 
| 
      
 65 
     | 
    
         
            +
                 */
         
     | 
| 
      
 66 
     | 
    
         
            +
                private generateResourceFunctionImplementation;
         
     | 
| 
      
 67 
     | 
    
         
            +
                /**
         
     | 
| 
      
 68 
     | 
    
         
            +
                 * Generate exposed resource methods for API introspection
         
     | 
| 
      
 69 
     | 
    
         
            +
                 */
         
     | 
| 
      
 70 
     | 
    
         
            +
                generateExposedResourceMethods(resources: Array<{
         
     | 
| 
      
 71 
     | 
    
         
            +
                    className: string;
         
     | 
| 
      
 72 
     | 
    
         
            +
                    fileName: string;
         
     | 
| 
      
 73 
     | 
    
         
            +
                }>, resourceSpecs?: Array<{
         
     | 
| 
      
 74 
     | 
    
         
            +
                    fileName: string;
         
     | 
| 
      
 75 
     | 
    
         
            +
                    spec: OpenAPIV3.Document;
         
     | 
| 
      
 76 
     | 
    
         
            +
                }>): string;
         
     | 
| 
      
 77 
     | 
    
         
            +
                /**
         
     | 
| 
      
 78 
     | 
    
         
            +
                 * Generate parameter call for a specific operation based on path parameters
         
     | 
| 
      
 79 
     | 
    
         
            +
                 */
         
     | 
| 
      
 80 
     | 
    
         
            +
                private generateParameterCallForOperation;
         
     | 
| 
      
 81 
     | 
    
         
            +
                /**
         
     | 
| 
      
 82 
     | 
    
         
            +
                 * Generate TypeScript interface from OpenAPI schema
         
     | 
| 
      
 83 
     | 
    
         
            +
                 */
         
     | 
| 
      
 84 
     | 
    
         
            +
                private generateInterfaceFromSchema;
         
     | 
| 
      
 85 
     | 
    
         
            +
                /**
         
     | 
| 
      
 86 
     | 
    
         
            +
                 * Generate all TypeScript interfaces from OpenAPI components
         
     | 
| 
      
 87 
     | 
    
         
            +
                 */
         
     | 
| 
      
 88 
     | 
    
         
            +
                private generateAllInterfaces;
         
     | 
| 
      
 89 
     | 
    
         
            +
                /**
         
     | 
| 
      
 90 
     | 
    
         
            +
                 * Generate detailed JSDoc with schema field information
         
     | 
| 
      
 91 
     | 
    
         
            +
                 */
         
     | 
| 
      
 92 
     | 
    
         
            +
                private generateDetailedJSDoc;
         
     | 
| 
      
 93 
     | 
    
         
            +
                /**
         
     | 
| 
      
 94 
     | 
    
         
            +
                 * Add flattened request body documentation to JSDoc
         
     | 
| 
      
 95 
     | 
    
         
            +
                 */
         
     | 
| 
      
 96 
     | 
    
         
            +
                private addFlattenedBodyDocumentation;
         
     | 
| 
      
 97 
     | 
    
         
            +
                /**
         
     | 
| 
      
 98 
     | 
    
         
            +
                 * Add detailed schema field information to JSDoc
         
     | 
| 
      
 99 
     | 
    
         
            +
                 */
         
     | 
| 
      
 100 
     | 
    
         
            +
                private addSchemaDetails;
         
     | 
| 
      
 101 
     | 
    
         
            +
                /**
         
     | 
| 
      
 102 
     | 
    
         
            +
                 * Collect all schema types used in operations (including nested references)
         
     | 
| 
      
 103 
     | 
    
         
            +
                 */
         
     | 
| 
      
 104 
     | 
    
         
            +
                private collectUsedSchemaTypes;
         
     | 
| 
      
 105 
     | 
    
         
            +
                /**
         
     | 
| 
      
 106 
     | 
    
         
            +
                 * Collect types from request body schema
         
     | 
| 
      
 107 
     | 
    
         
            +
                 */
         
     | 
| 
      
 108 
     | 
    
         
            +
                private collectTypesFromRequestBody;
         
     | 
| 
      
 109 
     | 
    
         
            +
                /**
         
     | 
| 
      
 110 
     | 
    
         
            +
                 * Collect types from response schemas
         
     | 
| 
      
 111 
     | 
    
         
            +
                 */
         
     | 
| 
      
 112 
     | 
    
         
            +
                private collectTypesFromResponses;
         
     | 
| 
      
 113 
     | 
    
         
            +
                /**
         
     | 
| 
      
 114 
     | 
    
         
            +
                 * Collect types from a schema object
         
     | 
| 
      
 115 
     | 
    
         
            +
                 */
         
     | 
| 
      
 116 
     | 
    
         
            +
                private collectTypesFromSchema;
         
     | 
| 
      
 117 
     | 
    
         
            +
                /**
         
     | 
| 
      
 118 
     | 
    
         
            +
                 * Generate type imports for used schema types
         
     | 
| 
      
 119 
     | 
    
         
            +
                 */
         
     | 
| 
      
 120 
     | 
    
         
            +
                private generateTypeImports;
         
     | 
| 
      
 121 
     | 
    
         
            +
                /**
         
     | 
| 
      
 122 
     | 
    
         
            +
                 * Generate a resource file with exported functions (new pattern for proper introspection)
         
     | 
| 
       45 
123 
     | 
    
         
             
                 */
         
     | 
| 
       46 
124 
     | 
    
         
             
                generateResourceClass(className: string): string;
         
     | 
| 
       47 
125 
     | 
    
         
             
                /**
         
     | 
| 
       48 
     | 
    
         
            -
                 * Generate a main controller that composes multiple resources
         
     | 
| 
      
 126 
     | 
    
         
            +
                 * Generate a main controller that composes multiple resources using function binding
         
     | 
| 
       49 
127 
     | 
    
         
             
                 */
         
     | 
| 
       50 
128 
     | 
    
         
             
                generateMainController(resources: Array<{
         
     | 
| 
       51 
129 
     | 
    
         
             
                    className: string;
         
     | 
| 
       52 
130 
     | 
    
         
             
                    fileName: string;
         
     | 
| 
      
 131 
     | 
    
         
            +
                }>, resourceSpecs?: Array<{
         
     | 
| 
      
 132 
     | 
    
         
            +
                    fileName: string;
         
     | 
| 
      
 133 
     | 
    
         
            +
                    spec: OpenAPIV3.Document;
         
     | 
| 
       53 
134 
     | 
    
         
             
                }>): string;
         
     | 
| 
       54 
135 
     | 
    
         
             
                /**
         
     | 
| 
       55 
     | 
    
         
            -
                 * Generate the connector controller code
         
     | 
| 
      
 136 
     | 
    
         
            +
                 * Generate the connector controller code with improved pattern
         
     | 
| 
       56 
137 
     | 
    
         
             
                 */
         
     | 
| 
       57 
138 
     | 
    
         
             
                generateController(): string;
         
     | 
| 
       58 
139 
     | 
    
         
             
            }
         
     |