Has anyone used the Script construct to generate d...
# help
Has anyone used the Script construct to generate docs using tsoa as part of the deploy process? When using the script construct, it looks like the only the relevant files related to the function thats being executed are zipped. Is it even possible to include the src directory?
Copy code
[FAILED] from custom resource. Message returned: [src/**/*Controller.ts] globs found 0 controllers.
Copy code
export class GenerateDocsStack extends sst.Stack {
    constructor(scope: <http://sst.App|sst.App>, id: string, props: GenerateDocsStackProps) {
        super(scope, id, props);

        const { bikeApi } = props;

        new sst.Script(this, 'Bike-Api-Docs', {
            onCreate: {
                handler: 'src/generateDocs.create',
                permissions: ['apigateway'],
                environment: {
                    apiId: bikeApi.httpApi.httpApiId,
                    region: scope.region,
                timeout: 500,
for example this is my generateDocs.ts
Copy code
import { InternalServerError } from '@local/errorTypes';
import { ApiGatewayV2 } from 'aws-sdk';
import { ExtendedSpecConfig, generateSpec } from 'tsoa';

export const downloadApiGatewaySpec = async (apiId: string, region: string): Promise<Record<string, unknown>> => {
    const apiGatewayV2 = new ApiGatewayV2({ region })
            ApiId: apiId,
            OutputType: 'JSON',
            Specification: 'OAS30',

    try {
        const apiSpec = await apiGatewayV2;
        const apiString = apiSpec.body?.toString();
        return Promise.resolve(apiString && JSON.parse(apiString));
    } catch (e) {
        return Promise.reject(e);

const deepMergeApiSpec = (apiGatewaySpec: Record<string, unknown>) => {
    const specOptions: ExtendedSpecConfig = {
        entryFile: 'src/handlers.ts',
        description: `Api docs`,
        specVersion: 3,
        outputDirectory: 'docs',
        controllerPathGlobs: ['src/**/*Controller.ts'],
        noImplicitAdditionalProperties: 'throw-on-extras',
        spec: apiGatewaySpec,
        specMerging: 'deepmerge',
    // TODO: push to S3
    return generateSpec(specOptions);

export const create = async () => {
    const { apiId, region } = process.env;

    if (!apiId || !region) {
        throw new InternalServerError(`Unable to generate api docs. Check apiId ${apiId}`);

    try {
        console.log(`Generating docs for apiId: ${apiId}`);
        const apiGatewaySpec = await downloadApiGatewaySpec(apiId, region);
        await deepMergeApiSpec(apiGatewaySpec);
        return { statusCode: 200, message: 'Success spec generated' };
    } catch (e: any) {
        throw new InternalServerError(e.message);
We have a copyFiles option in bundle where you can copy additional files into the bundle before we upload it