Skip to main content
Glama
transform.ts4.17 kB
import { existsSync } from 'node:fs'; import { readFile } from 'node:fs/promises'; import { relative, resolve } from 'node:path'; import { multiselect } from '@clack/prompts'; import { type PackageName, transformFiles } from '@intlayer/chokidar'; import { colorizePath, type GetConfigurationOptions, getAppLogger, getConfiguration, } from '@intlayer/config'; import fg from 'fast-glob'; type TransformOptions = { files?: string[]; outputContentDeclarations?: string; configOptions?: GetConfigurationOptions; codeOnly?: boolean; declarationOnly?: boolean; }; // Helper to read package.json dependencies const getDependencies = async (baseDir: string) => { try { const packageJsonPath = resolve(baseDir, 'package.json'); if (!existsSync(packageJsonPath)) { // Try parent directory if not found in baseDir return {}; } const file = await readFile(packageJsonPath, 'utf8'); const packageJSON = JSON.parse(file); return packageJSON.dependencies; } catch { return {}; } }; export const transform = async (options: TransformOptions) => { const configuration = getConfiguration(options.configOptions); const appLogger = getAppLogger(configuration); const { baseDir } = configuration.content; const formatPath = (path: string) => { const relativePath = relative(baseDir, path); return colorizePath(relativePath); }; // Detect package const dependencies = await getDependencies(baseDir); let packageName: PackageName = 'react-intlayer'; if (dependencies['next-intlayer']) { packageName = 'next-intlayer'; } else if (dependencies['vue-intlayer']) { packageName = 'vue-intlayer'; } else if (dependencies['svelte-intlayer']) { packageName = 'svelte-intlayer'; } else if (dependencies['react-intlayer']) { packageName = 'react-intlayer'; } else if (dependencies['preact-intlayer']) { packageName = 'preact-intlayer'; } else if (dependencies['solid-intlayer']) { packageName = 'solid-intlayer'; } else if (dependencies['angular-intlayer']) { packageName = 'angular-intlayer'; } else if (dependencies['express-intlayer']) { packageName = 'express-intlayer'; } let filesToTransform = options.files ?? []; if (filesToTransform.length === 0) { const globPattern = '**/*.{tsx,jsx,vue,svelte,ts,js}'; const excludePattern = [ '**/*.content.{ts,tsx,js,jsx,mjs,cjs}', '**/*.config.{ts,tsx,js,jsx,mjs,cjs}', '**/*.test.{ts,tsx,js,jsx,mjs,cjs}', '**/*.stories.{ts,tsx,js,jsx,mjs,cjs}', '**/node_modules/**', '**/dist/**', '**/build/**', ]; const allFiles = await fg(globPattern, { cwd: baseDir, ignore: excludePattern, absolute: true, }); // Remove duplicates and non-existing files const uniqueFiles = [...new Set(allFiles)].filter((file) => existsSync(file) ); // Relative paths for selection const choices = uniqueFiles.map((file) => { const relPath = relative(baseDir, file); return { value: file, label: relPath, }; }); if (choices.length === 0) { appLogger('No transformable files found in the project.'); return; } const selectedFiles = await multiselect({ message: 'Select files to transform:', options: choices, required: false, }); if (typeof selectedFiles === 'symbol') { // User cancelled process.exit(0); } filesToTransform = selectedFiles as string[]; } if (filesToTransform.length === 0) { appLogger('No files selected for transformation.'); return; } const absoluteFiles = filesToTransform .map((file) => resolve(baseDir, file)) .filter((file) => { if (!existsSync(file)) { appLogger(`File not found: ${formatPath(file)}`); return false; } return true; }); if (absoluteFiles.length === 0) { return; } await transformFiles(absoluteFiles, packageName, { configOptions: options.configOptions, outputDir: options.outputContentDeclarations, codeOnly: options.codeOnly, declarationOnly: options.declarationOnly, }); };

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/aymericzip/intlayer'

If you have feedback or need assistance with the MCP directory API, please join our Discord server