ts-morph#Project TypeScript Examples

The following examples show how to use ts-morph#Project. You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: gengen.ts    From gengen with MIT License 6 votes vote down vote up
export async function init(options: IOptions = defaultOptions): Promise<void> {
    const generator = new ConfigGenerator();
    const project = new Project(generatorsOptions);

    project.createSourceFile(
        `${options.configOutput}/${configOptions.filename}`,
        { statements: generator.getConfigCodeStructure() },
        { overwrite: true }
    );

    await project.save();
}
Example #2
Source File: gengen.ts    From gengen with MIT License 6 votes vote down vote up
export async function config(options: IOptions): Promise<void> {
    const settings = getOptions(options);
    const swaggerJson = await getOpenAPISpec(settings);

    const typesGuard = new OpenAPITypesGuard();
    const openAPIService = new OpenAPIService(swaggerJson, typesGuard);
    const endpointNameResolver = new EndpointNameResolver();
    const endpointsService = new EndpointsService(openAPIService, endpointNameResolver);
    const controllers = endpointsService.getActionsGroupedByController();

    const project = new Project(generatorsOptions);
    const generator = new ConfigGenerator();
    const sourceFile = project.createSourceFile(
        `${settings.configOutput}/${configOptions.className.toLowerCase()}.ts`,
        { statements: generator.getEndpointsCodeStructure(controllers) },
        { overwrite: true }
    );

    sourceFile.formatText();

    await project.save();
}
Example #3
Source File: api-client-generator.ts    From selling-partner-api-sdk with MIT License 6 votes vote down vote up
function generateExportStatements(project: Project, apiModels: APIModel[]) {
  log.info(`Starting exporting api clients`)

  const compileExportStatement = template(`export * from './<%= apiClientFileName %>'`)
  const exportStatements = apiModels.map((apiModel) =>
    compileExportStatement({
      apiClientFileName: generateAPIClientFileName(apiModel),
    }),
  )
  project.createSourceFile('src/api-clients/index.ts', exportStatements.join('\n'), {
    overwrite: true,
  })
  log.info(`Finished exporting api clients`)
}
Example #4
Source File: api-client-generator.ts    From selling-partner-api-sdk with MIT License 6 votes vote down vote up
export function generateAPIClients(apiModels: APIModel[]): void {
  const compileAPIClient = template(apiClientTemplate)
  const project = new Project({
    tsConfigFilePath: TS_CONFIG_FILE_PATH,
    libFolderPath: TS_LIB_FOLDER_PATH,
  })

  for (const apiModel of apiModels) {
    const apiClientFileName = generateAPIClientFileName(apiModel)
    generateAPIClient(
      project,
      compileAPIClient,
      apiModel,
      apiClientFileName,
      generateAPIClientClassname(apiClientFileName),
    )
  }

  generateExportStatements(project, apiModels)
  project.saveSync()
}
Example #5
Source File: api-model-generator.ts    From selling-partner-api-sdk with MIT License 6 votes vote down vote up
export async function generateExportStatement(model: APIModel): Promise<string> {
  // Export all enums and interfaces
  const sourceFile = new Project({
    tsConfigFilePath: TS_CONFIG_FILE_PATH,
    libFolderPath: TS_LIB_FOLDER_PATH,
  }).getSourceFileOrThrow(`${model.outputPath}/${API_MODEL_FILE_NAME}`)

  const exports = [...sourceFile.getEnums(), ...sourceFile.getInterfaces()]
    .map(
      (declaration) =>
        `${declaration.getName()} as ${upperFirst(
          camelCase(model.dirname),
        )}${declaration.getName()}`,
    )
    .join(', ')

  return `export { ${exports} } from './${model.dirname}'`
}
Example #6
Source File: enum-mapping.ts    From selling-partner-api-sdk with MIT License 6 votes vote down vote up
export function mapEnums2UnionType(): Promise<void>[] {
  const project = new Project({
    tsConfigFilePath: TS_CONFIG_FILE_PATH,
    libFolderPath: TS_LIB_FOLDER_PATH,
  })

  return project.getSourceFiles(`src/api-models/**/${API_MODEL_FILE_NAME}`).map((sourceFile) => {
    const filePath = `${sourceFile.getDirectory().getBaseName()}/${sourceFile.getBaseName()}`
    log.info(`Starting mapping ${filePath}`)

    const interfaceMembers: TypeElementTypes[] = sourceFile
      .getInterfaces()
      ?.map((itf) => itf.getMembers())
      .flat()
    const enumsOrUnion = interfaceMembers?.filter((member) => {
      const memberType = member.getType()
      // TODO: filter both union and intersection type.
      return memberType.isUnion() || memberType.isEnum() || memberType.isEnumLiteral()
    })
    const arrayOrUnion = interfaceMembers?.filter((member) => {
      const memberType = member.getType()
      // TODO: filter both union and intersection type.
      return memberType.isUnion() || memberType.isArray()
    })

    if (enumsOrUnion) {
      processEnumNodes(sourceFile, enumsOrUnion)
    }

    if (arrayOrUnion) {
      processArrayNodes(sourceFile, arrayOrUnion)
    }

    log.info(`Finished mapping ${filePath}`)
    return project.save()
  })
}
Example #7
Source File: GenGenCodeGen.ts    From gengen with MIT License 6 votes vote down vote up
protected generateProject(modelsCode: StatementStructures[], servicesCode: StatementStructures[]): Project {
        const project = new Project(generatorsOptions);

        project
            .createSourceFile(
                `${this.options.output}/${this.injector.aliasResolver.getModelsFileName()}`,
                { statements: modelsCode },
                { overwrite: true }
            )
            .formatText();

        project
            .createSourceFile(
                `${this.options.output}/${this.injector.aliasResolver.getServicesFileName()}`,
                { statements: servicesCode },
                { overwrite: true }
            )
            .formatText();

        return project;
    }
Example #8
Source File: apiCamelCase.ts    From taiga-front-next with GNU Affero General Public License v3.0 6 votes vote down vote up
function compile() {
  const project = new Project({
    tsConfigFilePath: 'tsconfig.json',
    addFilesFromTsConfig: false,
  });

  project.addSourceFilesAtPaths('src/**/*.ts');

  project.getSourceFiles().forEach((sourceFile) => {
    apiCamelCaseReplacements(sourceFile);
    sourceFile.save();
  });
}
Example #9
Source File: index.ts    From tarojs-router-next with MIT License 6 votes vote down vote up
constructor(private readonly root: RouterCodeGenerator) {
    this.targetModulePath = path.resolve(this.root.ctx.paths.nodeModulesPath, 'tarojs-router-next')
    const tsConfigFilePath = path.resolve(this.targetModulePath, 'tsconfig.json')
    this.project = new Project({
      tsConfigFilePath,
    })
    this.routerSourceFile = this.project.addSourceFileAtPath(
      path.resolve(this.targetModulePath, './src/router/index.ts')
    )
  }
Example #10
Source File: instructions.ts    From adonis5-jwt with MIT License 6 votes vote down vote up
async function getTsMorphProject(projectRoot: string) {
    const { indentationText, newLineKind } = await getIntendationConfigForTsMorph(projectRoot);
    return new Project({
        tsConfigFilePath: projectRoot + "/tsconfig.json",
        manipulationSettings: {
            indentationText: indentationText,
            newLineKind: newLineKind,
            useTrailingCommas: true,
        },
    });
}
Example #11
Source File: index.ts    From tarojs-router-next with MIT License 6 votes vote down vote up
/** 解析传入包的所有路由方法 */
  parse(options: { pkg: PackageConfig }) {
    const { pkg } = options
    const project = new Project()

    const configSourceFiles = this.readConfigSourceFiles({ pkg, project })
    let pages = this.createPages({ pkg })

    for (const p of pages) {
      p.config = pkg.pageConfigs.find((it) => it.dir === p.dir)
    }

    for (const sourceFile of configSourceFiles) {
      const page = pages.find((p) => {
        return path.resolve(p.fullPath, 'route.config.ts') === path.normalize(sourceFile.compilerNode.fileName)
      })
      if (!page) continue
      this.parseSourceFile({
        page,
        project,
        sourceFile,
      })
    }

    pkg.pages = pages
  }
Example #12
Source File: factory-get-source-file.ts    From prisma-nestjs-graphql with MIT License 6 votes vote down vote up
export function factoryGetSourceFile(args: {
  output: string;
  outputFilePattern: string;
  project: Project;
  getModelName(name: string): string | undefined;
  eventEmitter: AwaitEventEmitter;
}) {
  const { outputFilePattern, output, getModelName, project } = args;

  return function getSourceFile(args: { type: string; name: string }) {
    const { name, type } = args;
    let filePath = generateFileName({
      getModelName,
      name,
      type,
      template: outputFilePattern,
    });
    filePath = `${output}/${filePath}`;

    return (
      project.getSourceFile(filePath) ||
      project.createSourceFile(filePath, undefined, { overwrite: true })
    );
  };
}
Example #13
Source File: swagger.handler.ts    From cli with MIT License 5 votes vote down vote up
async function swaggerHandlerCore(
  { cwd: projectDirPath }: ICoreInstance,
  opts: SwaggerOptions
) {
  consola.info(`Project location: ${chalk.green(projectDirPath)}`);

  const { dry } = applyDefaultValueToSharedOption(opts);
  const { ui = false, namespace = 'swagger' } = opts;

  if (dry) {
    consola.success('Executing in `dry run` mode, nothing will happen.');
  }

  if (ui) {
    consola.info(
      '`swagger-ui-dist` will be installed as `dependencies` by enabled `--ui` option.'
    );
    SWAGGER_DEP.push(...SWAGGER_DEV_DEP);
    SWAGGER_DEV_DEP.pop();
  }

  dry
    ? consola.info('`[DryRun]` Skip `dependencies` installation check.')
    : await ensureDepsInstalled(SWAGGER_DEP, projectDirPath);

  dry
    ? consola.info('`[DryRun]` Skip `devDependencies` installation check.')
    : await ensureDevDepsInstalled(SWAGGER_DEV_DEP, projectDirPath);

  if (!dry) {
    consola.info('Source code will be transformed.');

    const project = new Project();

    const configurationPath = path.resolve(
      projectDirPath,
      './src/configuration.ts'
    );

    if (!fs.existsSync(configurationPath)) {
      consola.error(
        `Cannot find ${chalk.cyan('configuration.ts')} in ${chalk.green(
          configurationPath
        )}.`
      );
      process.exit(0);
    }

    const configurationSource = project.addSourceFileAtPath(configurationPath);

    addImportDeclaration(
      configurationSource,
      namespace,
      '@midwayjs/swagger',
      ImportType.NAMESPACE_IMPORT
    );

    updateDecoratorArrayArgs(
      configurationSource,
      'Configuration',
      'imports',
      namespace
    );

    formatTSFile(configurationPath);
  } else {
    consola.info('`[DryRun]` Source code will be transformed.');
  }
}
Example #14
Source File: generate.spec.ts    From prisma-nestjs-graphql with MIT License 5 votes vote down vote up
describe('scalar arrays with noAtomicOperations', () => {
  let project: Project;
  before(async () => {
    ({ project } = await testGenerate({
      schema: `
        model User {
          id String @id
          ints Int[]
          articles Article[] @relation("ArticleAuthor")
        }
        model Article {
          id String @id
          author   User   @relation(name: "ArticleAuthor", fields: [authorId], references: [id])
          authorId String
        }
        `,
      options: [
        `
        noAtomicOperations = true
      `,
      ],
    }));
  });

  describe('ints should be array', () => {
    for (const className of ['UserCreateInput']) {
      it(className, () => {
        const s = testSourceFile({
          project,
          class: className,
          property: 'ints',
        });

        expect(s.fieldDecoratorType).toEqual('() => [Int]');
      });
    }
  });

  it('create many inputs should not be deleted', () => {
    const s = testSourceFile({
      project,
      class: 'UserCreateInput',
      property: 'articles',
    });

    expect(s.property?.type).toBe('ArticleCreateNestedManyWithoutAuthorInput');
  });
});
Example #15
Source File: sample.ts    From cli with MIT License 5 votes vote down vote up
project = new Project()
Example #16
Source File: mongodb.spec.ts    From prisma-nestjs-graphql with MIT License 5 votes vote down vote up
project: Project
Example #17
Source File: custom-decorators.spec.ts    From prisma-nestjs-graphql with MIT License 5 votes vote down vote up
project: Project
Example #18
Source File: hide-field.spec.ts    From prisma-nestjs-graphql with MIT License 5 votes vote down vote up
project: Project
Example #19
Source File: helpers.ts    From prisma-nestjs-graphql with MIT License 5 votes vote down vote up
export function testSourceFile(args: {
  project: Project;
  file?: string;
  class?: string;
  property?: string;
}) {
  const { project, file, property, class: className } = args;
  let sourceFile: SourceFile;
  if (file) {
    sourceFile = project.getSourceFileOrThrow(s => s.getFilePath().endsWith(file));
  } else if (className) {
    sourceFile = project.getSourceFileOrThrow(s => Boolean(s.getClass(className)));
  } else {
    throw new TypeError('file or class must be provided');
  }

  const importDeclarations = sourceFile
    .getImportDeclarations()
    .map(d => d.getStructure());
  const classFile = sourceFile.getClass(() => true)!;
  const propertyStructure =
    property && classFile.getProperty(p => p.getName() === property)?.getStructure();
  const propertyDecorators = (
    propertyStructure as PropertyDeclarationStructure | undefined
  )?.decorators;
  const fieldDecorator = propertyDecorators?.find(d => d.name === 'Field');

  type ImportElement = { name: string; specifier: string };
  const namedImports: ImportElement[] = [];
  const namespaceImports: ImportElement[] = [];

  for (const d of importDeclarations) {
    if (d.namespaceImport) {
      namespaceImports.push({
        name: d.namespaceImport,
        specifier: d.moduleSpecifier,
      });
    }
    for (const s of (d.namedImports || []) as ImportSpecifierStructure[]) {
      namedImports.push({
        name: s.name,
        specifier: d.moduleSpecifier,
      });
    }
  }

  return {
    sourceFile,
    classFile,
    sourceText: sourceFile.getText(),
    namedImports,
    namespaceImports,
    property: propertyStructure as PropertyDeclarationStructure | undefined,
    propertyDecorators,
    fieldDecorator,
    fieldDecoratorType: fieldDecorator?.arguments?.[0],
    fieldDecoratorOptions: fieldDecorator?.arguments?.[1],
  };
}
Example #20
Source File: decimal.spec.ts    From prisma-nestjs-graphql with MIT License 5 votes vote down vote up
describe('decimal graphql noAtomicOperations', () => {
  let project: Project;
  before(async () => {
    ({ project } = await testGenerate({
      schema: `
        model User {
          id String @id
          transfers Decimal[]
        }
        `,
      options: `
        noAtomicOperations = true
      `,
    }));
  });

  it('should be array', () => {
    const s = testSourceFile({
      project,
      class: 'UserCreateInput',
      property: 'transfers',
    });

    expect(s.propertyDecorators).toContainEqual(
      expect.objectContaining({
        name: 'Type',
        arguments: ['() => Object'],
      }),
    );

    expect(s.propertyDecorators).toContainEqual(
      expect.objectContaining({
        name: 'Transform',
        arguments: ['transformToDecimal'],
      }),
    );

    expect(s.property?.type).toEqual('Array<Decimal>');
  });
});
Example #21
Source File: decimal.spec.ts    From prisma-nestjs-graphql with MIT License 5 votes vote down vote up
describe('nested object decorate', () => {
  let project: Project;
  before(async () => {
    ({ project } = await testGenerate({
      schema: `
        model Job {
          id          Int      @id
          salaryId    Int?
          salary Salary? @relation(fields: [salaryId], references: [id], onDelete: Cascade)
        }
        model Salary {
          id         Int      @id
          from       Decimal
          to         Decimal
          job Job[]
        }
        `,
      options: `
        noAtomicOperations = true
      `,
    }));
  });

  it('deep field should be decorated up to root', () => {
    const s = testSourceFile({
      project,
      class: 'JobCreateInput',
      property: 'salary',
    });

    expect(s.propertyDecorators).toContainEqual(
      expect.objectContaining({ name: 'Type' }),
    );
  });

  describe('should be decorated by type', () => {
    [
      'create',
      'connectOrCreate',
      'upsert',
      'createMany',
      'set',
      'disconnect',
      'delete',
      'connect',
      'update',
      'updateMany',
      'deleteMany',
      // eslint-disable-next-line unicorn/no-array-for-each
    ].forEach(property => {
      it(property, () => {
        const s = testSourceFile({
          project,
          class: 'JobUncheckedUpdateManyWithoutSalaryInput',
          property,
        });

        expect(s.propertyDecorators).toContainEqual(
          expect.objectContaining({ name: 'Type' }),
        );
      });
    });
  });

  it('property data should be decorated', () => {
    const s = testSourceFile({
      project,
      class: 'JobCreateManySalaryInputEnvelope',
      property: 'data',
    });

    expect(s.propertyDecorators).toContainEqual(
      expect.objectContaining({ name: 'Type' }),
    );
  });
});
Example #22
Source File: generate.spec.ts    From prisma-nestjs-graphql with MIT License 5 votes vote down vote up
project: Project
Example #23
Source File: test.spec.ts    From prisma-nestjs-graphql with MIT License 5 votes vote down vote up
project: Project
Example #24
Source File: oss.handler.ts    From cli with MIT License 5 votes vote down vote up
async function ossHandlerCore(
  { cwd: projectDirPath }: ICoreInstance,
  opts: OSSOptions
) {
  consola.info(`Project location: ${chalk.green(projectDirPath)}`);

  const { dry } = applyDefaultValueToSharedOption(opts);
  const { namespace = 'oss' } = opts;

  if (dry) {
    consola.success('Executing in `dry run` mode, nothing will happen.');
  }

  dry
    ? consola.info('`[DryRun]` Skip `dependencies` installation check.')
    : await ensureDepsInstalled(OSS_DEP, projectDirPath);

  dry
    ? consola.info('`[DryRun]` Skip `devDependencies` installation check.')
    : await ensureDevDepsInstalled(OSS_DEV_DEP, projectDirPath);

  if (!dry) {
    consola.info('Source code will be transformed.');

    const project = new Project();

    const configurationPath = path.resolve(
      projectDirPath,
      './src/configuration.ts'
    );

    if (!fs.existsSync(configurationPath)) {
      consola.error(
        `Cannot find ${chalk.cyan('configuration.ts')} in ${chalk.green(
          configurationPath
        )}.`
      );
      process.exit(0);
    }

    const configurationSource = project.addSourceFileAtPath(configurationPath);

    addImportDeclaration(
      configurationSource,
      namespace,
      '@midwayjs/oss',
      ImportType.NAMESPACE_IMPORT
    );

    updateDecoratorArrayArgs(
      configurationSource,
      'Configuration',
      'imports',
      namespace
    );

    formatTSFile(configurationPath);
  } else {
    consola.info('`[DryRun]` Source code will be transformed.');
  }
}
Example #25
Source File: transformer.ts    From telefunc with MIT License 5 votes vote down vote up
generateShield = (
  telefuncFileCode: string
): string => {
  const project = new Project({
    compilerOptions: {
      strict: true
    }
  })

  project.createSourceFile("types.ts", typesSrc)
  const telefuncFileSource = project.createSourceFile("telefunc.ts", telefuncFileCode)
  // this source file is used for evaluating the template literal types' values
  const shieldStrSource = project.createSourceFile("shield-str.ts")

  shieldStrSource.addImportDeclaration({
    moduleSpecifier: "./types",
    namedImports: ["ShieldArrStr"]
  })

  const telefunctions = telefuncFileSource.getFunctions().filter(f => f.isExported())
  const telefunctionNames = telefunctions.flatMap(telefunction => {
    const name = telefunction.getName()
    if (!name) return []
    return [name]
  })
  shieldStrSource.addImportDeclaration({
    moduleSpecifier: "./telefunc",
    namedImports: telefunctionNames
  })

  // assign the template literal type to a string
  // then diagnostics are used to get the value of the template literal type
  for (const telefunctionName of telefunctionNames) {
    shieldStrSource.addTypeAlias({
      name: `${telefunctionName}Shield`,
      type: `ShieldArrStr<Parameters<typeof ${telefunctionName}>>`
    })
  }

  const shieldAlias = '__shieldGenerator_shield'  // alias for shield
  telefuncFileSource.addImportDeclaration({
    moduleSpecifier: 'telefunc',
    namedImports: [{
      name: 'shield',
      alias: shieldAlias
    }]
  })
  telefuncFileSource.addVariableStatement({
    declarationKind: VariableDeclarationKind.Const,
    declarations: [{
      name: tAlias,
      initializer: `${shieldAlias}.type`,
    }]
  })

  for (const telefunctionName of telefunctionNames) {
    const typeAlias = shieldStrSource.getTypeAlias(`${telefunctionName}Shield`)
    assert(typeAlias, `Failed to get typeAlias '${telefunctionName}Shield'.`)

    const shieldStr = typeAlias.getType().getLiteralValue()

    if (!shieldStr || typeof shieldStr !== 'string') {
      assertWarning(false, `Failed to generate shield() for telefunction ${telefunctionName}()`, { onlyOnce: false })
      continue
    }
    const shieldStrWithAlias = replaceShieldTypeAlias(shieldStr)
    telefuncFileSource.addStatements(`${shieldAlias}(${telefunctionName}, ${shieldStrWithAlias}, { __autoGenerated: true })`)
  }

  return telefuncFileSource.getText()
}
Example #26
Source File: cache.handler.ts    From cli with MIT License 5 votes vote down vote up
async function cacheHandlerCore(
  { cwd: projectDirPath }: ICoreInstance,
  opts: CacheOptions
) {
  consola.info(`Project location: ${chalk.green(projectDirPath)}`);

  const { dry } = applyDefaultValueToSharedOption(opts);
  const { namespace = 'cache' } = opts;

  if (dry) {
    consola.success('Executing in `dry run` mode, nothing will happen.');
  }

  dry
    ? consola.info('`[DryRun]` Skip `dependencies` installation check.')
    : await ensureDepsInstalled(CACHE_DEP, projectDirPath);

  dry
    ? consola.info('`[DryRun]` Skip `devDependencies` installation check.')
    : await ensureDevDepsInstalled(CACHE_DEV_DEP, projectDirPath);

  if (!dry) {
    consola.info('Source code will be transformed.');

    const project = new Project();

    const configurationPath = path.resolve(
      projectDirPath,
      './src/configuration.ts'
    );

    if (!fs.existsSync(configurationPath)) {
      consola.error(
        `Cannot find ${chalk.cyan('configuration.ts')} in ${chalk.green(
          configurationPath
        )}.`
      );
      process.exit(0);
    }

    const configurationSource = project.addSourceFileAtPath(configurationPath);

    addImportDeclaration(
      configurationSource,
      namespace,
      '@midwayjs/cache',
      ImportType.NAMESPACE_IMPORT
    );

    updateDecoratorArrayArgs(
      configurationSource,
      'Configuration',
      'imports',
      namespace
    );

    formatTSFile(configurationPath);
  } else {
    consola.info('`[DryRun]` Source code will be transformed.');
  }
}
Example #27
Source File: axios.handler.ts    From cli with MIT License 5 votes vote down vote up
async function axiosHandlerCore(
  { cwd: projectDirPath }: ICoreInstance,
  opts: AxiosOptions
) {
  consola.info(`Project location: ${chalk.green(projectDirPath)}`);

  const { dry } = applyDefaultValueToSharedOption(opts);
  const { namespace = 'axios' } = opts;

  if (dry) {
    consola.success('Executing in `dry run` mode, nothing will happen.');
  }

  dry
    ? consola.info('`[DryRun]` Skip `dependencies` installation check.')
    : await ensureDepsInstalled(AXIOS_DEP, projectDirPath);

  if (!dry) {
    consola.info('Source code will be transformed.');

    const project = new Project();

    const configurationPath = path.resolve(
      projectDirPath,
      './src/configuration.ts'
    );

    if (!fs.existsSync(configurationPath)) {
      consola.error(
        `Cannot find ${chalk.cyan('configuration.ts')} in ${chalk.green(
          configurationPath
        )}.`
      );
      process.exit(0);
    }

    const configurationSource = project.addSourceFileAtPath(configurationPath);

    addImportDeclaration(
      configurationSource,
      namespace,
      '@midwayjs/axios',
      ImportType.NAMESPACE_IMPORT
    );

    updateDecoratorArrayArgs(
      configurationSource,
      'Configuration',
      'imports',
      namespace
    );

    formatTSFile(configurationPath);
  } else {
    consola.info('`[DryRun]` Source code will be transformed.');
  }
}
Example #28
Source File: index.ts    From tarojs-router-next with MIT License 5 votes vote down vote up
/** 解析 route.config.ts 导出的 Params、Data、Ext */
  parseSourceFile(options: { page: Page; project: Project; sourceFile: SourceFile }) {
    const { page, project, sourceFile } = options
    const checker = project.getTypeChecker()

    const pageQuery: {
      params?: QueryMeta
      data?: QueryMeta
      ext?: string
    } = {}

    sourceFile.getExportedDeclarations().forEach((declarations, name) => {
      if (declarations.length > 1) return
      const declaration = declarations[0] as any
      switch (name) {
        case 'Params':
          pageQuery.params = extractType({
            name,
            declaration,
            checker,
          })
          break
        case 'Data':
          pageQuery.data = extractType({
            name,
            declaration,
            checker,
          })
          break
        case 'Ext':
          pageQuery.ext = extractValue({
            name,
            declaration,
            checker,
          })
          break
      }
    })

    page.query = pageQuery

    return page
  }
Example #29
Source File: index.ts    From tarojs-router-next with MIT License 5 votes vote down vote up
/** 读取传入包的所有 route.config.ts 配置文件 */
  readConfigSourceFiles(options: { pkg: PackageConfig; project: Project }) {
    const { project } = options
    const { fullPagesPath } = options.pkg
    project.addSourceFilesAtPaths(fullPagesPath + '/**/route.config.ts')
    project.resolveSourceFileDependencies()
    return project.getSourceFiles().filter((it) => it.compilerNode.fileName.endsWith('route.config.ts'))
  }