diff --git a/scripts/setup-environment.ps1 b/scripts/setup-environment.ps1 deleted file mode 100644 index b949b29..0000000 --- a/scripts/setup-environment.ps1 +++ /dev/null @@ -1,55 +0,0 @@ -function Initialize-PowerShellEnvironment { - Write-Host "Initializing PowerShell environment..." -ForegroundColor Yellow - - # Add any environment setup logic here, such as importing modules, setting variables, etc. - # Example: Import-Module SomeModule - Import-Module powershell-yaml -ErrorAction SilentlyContinue - - Write-Host "PowerShell environment initialized." -ForegroundColor Green -} - -function Initialize-GenerateTools { - Write-Host "Initializing Node.js dependencies..." -ForegroundColor Yellow - - Push-Location -StackName NodeTools (Join-Path $PSScriptRoot "../tools/") - - Get-childitem -Path . -Directory | ForEach-Object { - Write-Host "Initializing $($_.Name)..." -ForegroundColor Cyan - - Push-Location -StackName NodeTools $_.FullName - try { - # Install Node.js dependencies - & npm install - if ($LASTEXITCODE -ne 0) { - Write-Error "npm install failed with exit code $LASTEXITCODE." - exit 1 - } - } - catch { - Write-Error "npm install failed for $($_.Name): $_" - exit 1 - } - finally { - Pop-Location -StackName NodeTools - } - } - - Pop-Location -StackName NodeTools - - Write-Host "Node.js dependencies initialized." -ForegroundColor Green -} - -function Invoke-Main { - Write-Host "Preparing environment..." -ForegroundColor Cyan - Write-Host - - Initialize-PowerShellEnvironment - Write-Host - - Initialize-GenerateTools - Write-Host - - Write-Host "Environment preparation complete!" -ForegroundColor Green -} - -Invoke-Main \ No newline at end of file diff --git a/scripts/setup-tools.ps1 b/scripts/setup-tools.ps1 new file mode 100644 index 0000000..f9ac67e --- /dev/null +++ b/scripts/setup-tools.ps1 @@ -0,0 +1,21 @@ +function Initialize-PowerShellEnvironment { + Write-Host "Initializing PowerShell environment..." -ForegroundColor Yellow + + # Add any environment setup logic here, such as importing modules, setting variables, etc. + # Example: Import-Module SomeModule + Import-Module powershell-yaml -ErrorAction SilentlyContinue + + Write-Host "PowerShell environment initialized." -ForegroundColor Green +} + +function Invoke-Main { + Write-Host "Preparing environment..." -ForegroundColor Cyan + Write-Host + + Initialize-PowerShellEnvironment + Write-Host + + Write-Host "Environment preparation complete!" -ForegroundColor Green +} + +Invoke-Main \ No newline at end of file diff --git a/setup-environment.bat b/setup-tools.bat similarity index 90% rename from setup-environment.bat rename to setup-tools.bat index 3ca07f7..1c0a11f 100644 --- a/setup-environment.bat +++ b/setup-tools.bat @@ -6,7 +6,7 @@ cd /D "%~dp0" echo. -@pwsh -NoProfile -ExecutionPolicy Bypass -Command .\scripts\setup-environment.ps1 %* +@pwsh -NoProfile -ExecutionPolicy Bypass -Command .\scripts\setup-tools.ps1 %* echo. diff --git a/tools/generate-http-requests/generate-http-requests.js b/tools/generate-http-requests/generate-http-requests.js deleted file mode 100644 index d0c0086..0000000 --- a/tools/generate-http-requests/generate-http-requests.js +++ /dev/null @@ -1,844 +0,0 @@ -#!/usr/bin/env node -import fs from 'fs'; -import path from 'path'; -import YAML from 'yaml'; -import stripJsonComments from 'strip-json-comments'; -import { fileURLToPath } from 'url'; - -const interpolationVariableRegex = /^{{(.*?)}}$/ -const DEFAULT_VAR_VALUE = 'EDIT_VALUE_HERE' -const VARIABLE_NAME_VALUE_SEPARATOR = '=' -const __filename = fileURLToPath(import.meta.url); -const __dirname = path.dirname(__filename); - -function findWorkspaceRoot(startDir) { - let current = startDir; - while (true) { - if (fs.existsSync(path.join(current, 'workspace.yml'))) { - return current; - } - const parent = path.dirname(current); - if (parent === current) { - throw new Error('workspace.yml not found from the provided start directory'); - } - current = parent; - } -} - -function parseYaml(filePath) { - try { - const text = fs.readFileSync(filePath, 'utf8'); - const parsed = YAML.parse(text); - return parsed || {}; - } catch (error) { - throw new Error(`Failed to parse YAML file ${filePath}: ${error.message}`); - } -} - -function readText(filePath) { - return fs.readFileSync(filePath, 'utf8'); -} - -function stripQuotes(value) { - const trimmed = String(value).trim(); - if ((trimmed.startsWith('"') && trimmed.endsWith('"')) || (trimmed.startsWith("'") && trimmed.endsWith("'"))) { - return trimmed.slice(1, -1); - } - return trimmed; -} - -function parseWorkspace(workspacePath) { - const text = readText(workspacePath); - const lines = text.split(/\r?\n/); - const collections = []; - let inCollections = false; - let currentCollection = null; - - for (const line of lines) { - const trimmed = line.trim(); - if (!inCollections && trimmed === 'collections:') { - inCollections = true; - continue; - } - - if (!inCollections) { - continue; - } - - if (!line.startsWith(' ') && !line.startsWith('\t') && trimmed) { - break; - } - - const nameMatch = line.match(/^\s*-\s+name:\s*(.+)$/); - if (nameMatch) { - currentCollection = { name: stripQuotes(nameMatch[1]) }; - collections.push(currentCollection); - continue; - } - - const pathMatch = line.match(/^\s*path:\s*(.+)$/); - if (pathMatch && currentCollection) { - currentCollection.path = stripQuotes(pathMatch[1]); - } - } - - return { collections }; -} - -function sanitizeVarName(value) { - return String(value) - .trim() - .replace(/[{}]/g, '') - .replace(/[^A-Za-z0-9_]/g, '_') - .replace(/^([0-9])/, '_$1') || 'value'; -} - -function parsePlaceholderContent(content) { - const trimmed = String(content).trim(); - const dotenvMatch = trimmed.match(/^\$dotenv\s+(.+)$/i); - if (dotenvMatch) { - return { name: dotenvMatch[1].trim(), isDotenv: true }; - } - return { name: trimmed, isDotenv: false }; -} - -function collectPlaceholders(value) { - if (typeof value !== 'string') { - return []; - } - const placeholders = []; - const regex = /\{\{([^{}]+)\}\}/g; - let match; - while ((match = regex.exec(value)) !== null) { - placeholders.push(parsePlaceholderContent(match[1]).name); - } - return placeholders; -} - -function findBlock(lines, keyName) { - for (let i = 0; i < lines.length; i += 1) { - const trimmed = lines[i].trim(); - if (trimmed !== keyName && !trimmed.startsWith(`${keyName}:`)) { - continue; - } - - const lineIndent = lines[i].match(/^\s*/)[0].length; - const block = []; - for (let j = i + 1; j < lines.length; j += 1) { - const currentLine = lines[j]; - const currentTrimmed = currentLine.trim(); - if (!currentTrimmed) { - block.push(currentLine); - continue; - } - const currentIndent = currentLine.match(/^\s*/)[0].length; - if (currentIndent <= lineIndent && !currentLine.startsWith(' ')) { - break; - } - if (currentIndent <= lineIndent && currentTrimmed.startsWith('#')) { - block.push(currentLine); - continue; - } - if (currentIndent <= lineIndent) { - break; - } - block.push(currentLine); - } - return block; - } - return []; -} - -function parseRequestInfo(text) { - const lines = text.split(/\r?\n/); - const infoLines = findBlock(lines, 'info'); - const nameMatch = infoLines.join('\n').match(/^\s*name:\s*(.+)$/m); - return nameMatch ? stripQuotes(nameMatch[1]) : ''; -} - -function parseHttpBlock(text) { - const parsed = YAML.parse(text) || {}; - const http = parsed.http || {}; - const headers = []; - - for (const header of Array.isArray(http.headers) ? http.headers : []) { - if (!header || typeof header !== 'object') { - continue; - } - headers.push({ - name: String(header.name || '').trim(), - value: String(header.value ?? '').trim(), - }); - } - - return { - method: http.method || 'GET', - url: http.url || '', - params: Array.isArray(http.params) ? http.params : [], - headers, - body: http.body && typeof http.body === 'object' ? http.body : null, - }; -} - -function formatVariableValue(value, renderContext = {}) { - if (value === null || value === undefined) { - return "''"; - } - - if (typeof value === 'string') { - if (value.trim() === '') { - return "''"; - } - const renderedValue = renderContext.renderValue ? renderContext.renderValue(value) : value; - if (/\s/.test(renderedValue)) { - return `"${renderedValue.replace(/"/g, '\\"')}"`; - } - return renderedValue; - } - - return JSON.stringify(value); -} - -export function mergeRequestConfig(base, updates) { - if (!updates || typeof updates !== 'object') { - return base; - } - - const merged = { ...(base || {}) }; - if (Object.prototype.hasOwnProperty.call(updates, 'auth')) { - if (updates.auth === 'inherit') { - if (merged.auth && typeof merged.auth === 'object') { - merged.auth = merged.auth; - } else { - delete merged.auth; - } - } else if (typeof updates.auth === 'object' && updates.auth !== null) { - merged.auth = updates.auth; - } else { - delete merged.auth; - } - } else { - delete merged.auth; - } - - if (Object.prototype.hasOwnProperty.call(updates, 'headers')) { - const headers = [...(Array.isArray(base.headers) ? base.headers : [])]; - const byName = new Map(); - for (const header of headers) { - if (header && header.name) { - byName.set(String(header.name), header); - } - } - for (const header of updates.headers) { - if (header && header.name) { - byName.set(String(header.name), header); - } - } - merged.headers = [...byName.values()]; - } - - if (Array.isArray(updates.variables)) { - const variables = [...(Array.isArray(base.variables) ? base.variables : [])]; - const byName = new Map(); - for (const variable of variables) { - if (variable && variable.name) { - byName.set(String(variable.name), variable); - } - } - for (const variable of updates.variables) { - if (variable && variable.name) { - byName.set(String(variable.name), variable); - } - } - merged.variables = [...byName.values()]; - } - - return merged; -} - -export function getRequestConfigForFile(yamlFile, sourceDir) { - const resolved = []; - const seenFiles = new Set(); - - const addFile = (filePath) => { - if (!filePath || seenFiles.has(filePath)) { - return; - } - seenFiles.add(filePath); - if (!fs.existsSync(filePath)) { - return; - } - - try { - const parsed = parseYaml(filePath); - let requestConfig = null; - - if (parsed && parsed.request && typeof parsed.request === 'object') { - requestConfig = parsed.request; - } else if (parsed && typeof parsed === 'object') { - const config = {}; - if (Object.prototype.hasOwnProperty.call(parsed, 'auth')) { - config.auth = parsed.auth; - } else if (parsed.http && typeof parsed.http === 'object' && Object.prototype.hasOwnProperty.call(parsed.http, 'auth')) { - config.auth = parsed.http.auth; - } - if (Array.isArray(parsed.variables)) { - config.variables = parsed.variables; - } - if (Object.keys(config).length > 0) { - requestConfig = config; - } - } - - if (requestConfig !== null) { - resolved.push(requestConfig); - } else if (path.resolve(filePath) === path.resolve(yamlFile)) { - resolved.push({}); - } - } catch (error) { - // Ignore files that cannot be parsed as YAML for request inheritance. - } - }; - - const dirChain = []; - let currentDir = path.dirname(yamlFile); - while (true) { - dirChain.unshift(currentDir); - if (currentDir === sourceDir) { - break; - } - const parentDir = path.dirname(currentDir); - if (parentDir === currentDir) { - break; - } - currentDir = parentDir; - } - - for (const dir of dirChain) { - addFile(path.join(dir, 'opencollection.yml')); - addFile(path.join(dir, 'folder.yml')); - } - - addFile(yamlFile); - - return resolved.reduce((result, config) => mergeRequestConfig(result, config), {}); -} - - -export function buildRequestContent(request, requestName, requestConfig = {}, dotenvVariables = new Set()) { - const lines = []; - const variableDefinitions = []; - const commentedVariableDefinitions = []; - const parameterVariableDefinitions = []; - const seenVariables = new Set(); - - const addVariable = (name, value) => { - if (!name) { - return; - } - const normalized = String(name).trim(); - if (!normalized || seenVariables.has(normalized) || dotenvVariables.has(normalized)) { - return; - } - seenVariables.add(normalized); - variableDefinitions.push({ name: normalized, value }); - }; - - const addParameterVariable = (name, value) => { - if (!name) { - return; - } - const normalized = String(name).trim(); - if (!normalized || seenVariables.has(normalized) || dotenvVariables.has(normalized)) { - return; - } - seenVariables.add(normalized); - parameterVariableDefinitions.push({ name: normalized, value }); - }; - - const addCommentedVariable = (name, value) => { - if (!name) { - return; - } - const normalized = String(name).trim(); - if (!normalized) { // || seenVariables.has(normalized) || dotenvVariables.has(normalized)) { - return; - } - // seenVariables.add(normalized); - commentedVariableDefinitions.push({ name: normalized, value }); - }; - - const addReferencedVariables = (value, fallbackValue = DEFAULT_VAR_VALUE) => { - for (const placeholder of collectPlaceholders(String(value))) { - addVariable(placeholder, fallbackValue); - } - }; - - const renderJsonValue = (value) => { - if (typeof value === 'string') { - return renderValue(value); - } - if (Array.isArray(value)) { - return value.map((item) => renderJsonValue(item)); - } - if (value && typeof value === 'object') { - return Object.fromEntries( - Object.entries(value).map(([key, nestedValue]) => [key, renderJsonValue(nestedValue)]), - ); - } - return value; - }; - - const addParameterVariables = (name, value) => { - addParameterVariable(name, value); - }; - - const addCommentedVariables = (name, value) => { - addCommentedVariable(name, value); - }; - - const renderValue = (value) => { - if (typeof value !== 'string') { - return value; - } - return value.replace(/\{\{([^{}]+)\}\}/g, (match, inner) => { - const placeholder = parsePlaceholderContent(inner); - if (placeholder.isDotenv) { - return match; - } - if (placeholder.name && dotenvVariables.has(placeholder.name)) { - return `{{$dotenv ${placeholder.name}}}`; - } - return match; - }); - }; - - const configVariables = Array.isArray(requestConfig.variables) ? requestConfig.variables : []; - for (const variable of configVariables) { - if (variable && variable.name) { - addVariable(variable.name, variable.value); - } - } - - let url = request.url || ''; - if (url) { - addReferencedVariables(url); - url = url.replace(/:([A-Za-z0-9_]+)/g, (_, name) => `{{${name}}}`); - url = renderValue(url); - // Since Bruno puts enabled params in the URL, this avoids duplicate query params - url = url.split('?')[0]; - } - - const queryParams = []; - const headers = []; - const addHeader = (name, value) => { - if (!name) { - return; - } - addReferencedVariables(value ?? ''); - headers.push({ name: String(name).trim(), value: renderValue(value ?? '') }); - }; - - for (const header of Array.isArray(request.headers) ? request.headers : []) { - if (!header || !header.name) { - continue; - } - addHeader(header.name, header.value ?? ''); - } - - for (const header of Array.isArray(requestConfig.headers) ? requestConfig.headers : []) { - if (!header || !header.name) { - continue; - } - addHeader(header.name, header.value ?? ''); - } - - for (const param of request.params || []) { - const name = param.name || ''; - const value = param.value || ''; - const type = (param.type || 'query').toLowerCase(); - const disabled = String(param.disabled).toLowerCase() === 'true'; - - if (disabled) { - addCommentedVariables(name, value); - continue; - } - - addReferencedVariables(value); - - if (type === 'header') { - headers.push({ name, value: renderValue(value) }); - } else { - queryParams.push({ name, value: `{{${name}}}` }); - addParameterVariables(name, value); - } - } - - if (requestConfig.auth) { - if (requestConfig.auth.type === 'bearer') { - addReferencedVariables(requestConfig.auth.token ?? ''); - addHeader('Authorization', `Bearer ${renderValue(requestConfig.auth.token ?? '')}`); - } else if (requestConfig.auth.type === 'basic') { - const username = requestConfig.auth.username ?? ''; - const password = requestConfig.auth.password ?? ''; - addReferencedVariables(username); - addReferencedVariables(password); - // VSCode REST Client can manage username:password format directly! - addHeader('Authorization', `Basic ${renderValue(username)}:${renderValue(password)}`); - } else { - headers.push({ - name: `UNKNOWN_${requestConfig.auth.type}`, - value: `Basic ${requestConfig.auth.token}`, - }); - } - } - - if (commentedVariableDefinitions.length > 0) { - lines.push(`# Other variables for ${requestName}`); - for (const variable of commentedVariableDefinitions.sort((a, b) => { - const nameComparison = a.name.localeCompare(b.name); - return nameComparison !== 0 ? nameComparison : a.value.localeCompare(b.value); - })) { - lines.push(`# @${sanitizeVarName(variable.name)}${VARIABLE_NAME_VALUE_SEPARATOR}${formatVariableValue(variable.value, { renderValue })}`); - } - } - - if (parameterVariableDefinitions.length > 0) { - lines.push(`# Parameter variables for ${requestName}`); - for (const variable of parameterVariableDefinitions.sort((a, b) => { - const nameComparison = a.name.localeCompare(b.name); - return nameComparison !== 0 ? nameComparison : a.value.localeCompare(b.value); - })) { - lines.push(`@${sanitizeVarName(variable.name)}${VARIABLE_NAME_VALUE_SEPARATOR}${formatVariableValue(variable.value, { renderValue })}`); - } - } - - let requestBody = ''; - if (request.body && typeof request.body === 'object') { - const bodyType = String(request.body.type || '').toLowerCase(); - if (bodyType === 'json') { - const jsonData = stripJsonComments(request.body.data, { whitespace: false }); - if (jsonData !== undefined && jsonData !== null) { - if (typeof jsonData === 'string') { - requestBody = renderValue(jsonData); - } else { - const renderedData = Array.isArray(jsonData) - ? jsonData.map((item) => renderJsonValue(item)) - : renderJsonValue(jsonData); - requestBody = JSON.stringify(renderedData, null, 2); - } - } - addHeader('Content-Type', 'application/json'); - } else if (bodyType === 'form-urlencoded') { - const parts = []; - for (const entry of Array.isArray(request.body.data) ? request.body.data : []) { - if (!entry || !entry.name) { - continue; - } - addReferencedVariables(entry.value ?? ''); - parts.push(`${entry.name}=${renderValue(entry.value ?? '')}`); - } - requestBody = parts.join('&'); - addHeader('Content-Type', 'application/x-www-form-urlencoded'); - } - } - - if (variableDefinitions.length > 0) { - lines.push(`# Variables for ${requestName}`); - for (const variable of variableDefinitions.sort((a, b) => { - const nameComparison = a.name.localeCompare(b.name); - return nameComparison !== 0 ? nameComparison : a.value.localeCompare(b.value); - })) { - lines.push(`@${sanitizeVarName(variable.name)}${VARIABLE_NAME_VALUE_SEPARATOR}${formatVariableValue(variable.value, { renderValue })}`); - } - } - - const method = (request.method || 'GET').toUpperCase(); - let requestUrl = url; - for (const param of queryParams) { - if (!param.name) { - continue; - } - const separator = requestUrl.includes('?') ? '&' : '?'; - requestUrl = `${requestUrl}${separator}${param.name}=${param.value}`; - } - - lines.push(''); - lines.push(`${method} ${requestUrl}`); - for (const header of headers) { - lines.push(`${header.name}: ${header.value}`); - } - if (requestBody) { - lines.push(''); - lines.push(requestBody); - } - return lines.join('\n'); -} - -function ensureDir(dirPath) { - fs.mkdirSync(dirPath, { recursive: true }); -} - -function walkYamlFiles(rootDir) { - const results = []; - const entries = fs.readdirSync(rootDir, { withFileTypes: true }); - for (const entry of entries) { - if (entry.name.startsWith('.') || entry.name === 'node_modules') { - continue; - } - const fullPath = path.join(rootDir, entry.name); - if (entry.isDirectory()) { - results.push(...walkYamlFiles(fullPath)); - } else if (entry.isFile() && /\.ya?ml$/i.test(entry.name)) { - results.push(fullPath); - } - } - return results; -} - -function getDotenvVariablesForTargetDir(targetDir, outputRoot, dotenvVariablesByTarget) { - const variables = new Set(); - let currentDir = targetDir; - - while (true) { - const vars = dotenvVariablesByTarget.get(currentDir); - if (vars) { - for (const variable of vars) { - variables.add(variable); - } - } - - if (currentDir === outputRoot || path.dirname(currentDir) === currentDir) { - break; - } - currentDir = path.dirname(currentDir); - } - - return variables; -} - -function writeEnvironmentTemplates(sourceDir, outputRoot) { - const targets = []; - const dotenvVariablesByTarget = new Map(); - - const visit = (currentDir) => { - const entries = fs.readdirSync(currentDir, { withFileTypes: true }); - const hasEnvironmentsDir = entries.some((entry) => entry.isDirectory() && entry.name === 'environments' && - fs.readdirSync(path.join(currentDir, 'environments'), { withFileTypes: true }).some((envEntry) => envEntry.isFile() && /\.ya?ml$/i.test(envEntry.name))); - - if (hasEnvironmentsDir) { - targets.push(currentDir); - } - - for (const entry of entries) { - if (!entry.isDirectory() || entry.name.startsWith('.') || entry.name === 'node_modules') { - continue; - } - visit(path.join(currentDir, entry.name)); - } - }; - - visit(sourceDir); - - for (const dir of targets) { - const relativeDir = path.relative(sourceDir, dir); - const targetDir = relativeDir && relativeDir !== '.' ? path.join(outputRoot, relativeDir) : outputRoot; - ensureDir(targetDir); - - const environmentsDir = path.join(dir, 'environments'); - if (!fs.existsSync(environmentsDir)) { - continue; - } - - const envFiles = fs.readdirSync(environmentsDir, { withFileTypes: true }) - .filter((entry) => entry.isFile() && /\.ya?ml$/i.test(entry.name)) - .map((entry) => path.join(environmentsDir, entry.name)); - - const variableNames = []; - const seenNames = new Set(); - - for (const envFile of envFiles) { - const parsed = parseYaml(envFile); - const variables = Array.isArray(parsed.variables) ? parsed.variables : []; - for (const variable of variables) { - if (!variable || !variable.name) { - continue; - } - const name = String(variable.name).trim(); - if (!name || seenNames.has(name)) { - continue; - } - seenNames.add(name); - variableNames.push(name); - } - } - - const templateContent = variableNames.length > 0 ? `${variableNames.map(v => `${v}=${DEFAULT_VAR_VALUE}`).join('\n')}\n` : ''; - fs.writeFileSync(path.join(targetDir, '.env.template'), templateContent, 'utf8'); - dotenvVariablesByTarget.set(targetDir, new Set(variableNames)); - } - - return dotenvVariablesByTarget; -} - -function writeJsFiles(sourceDir, outputRoot) { - const targets = []; - // const dotenvVariablesByTarget = new Map(); - - const visit = (currentDir) => { - const entries = fs.readdirSync(currentDir, { withFileTypes: true }); - const hasJsFiles = entries.some((entry) => entry.isFile() && /\.js$/i.test(entry.name)); - - if (hasJsFiles) { - targets.push(currentDir); - } - - for (const entry of entries) { - if (!entry.isDirectory() || entry.name.startsWith('.') || entry.name === 'node_modules') { - continue; - } - visit(path.join(currentDir, entry.name)); - } - }; - - visit(sourceDir); - - for (const dir of targets) { - const relativeDir = path.relative(sourceDir, dir); - const targetDir = relativeDir && relativeDir !== '.' ? path.join(outputRoot, relativeDir) : outputRoot; - ensureDir(targetDir); - - const jsFileDir = dir; - if (!fs.existsSync(jsFileDir)) { - continue; - } - - const jsFiles = fs.readdirSync(jsFileDir, { withFileTypes: true }) - .filter((entry) => entry.isFile() && /\.js$/i.test(entry.name)) - .map((entry) => [ path.join(jsFileDir, entry.name), path.join(targetDir, entry.name) ]); - - // const variableNames = []; - // const seenNames = new Set(); - - // for (const jsFile of jsFiles) { - // const parsed = parseYaml(jsFile); - // const variables = Array.isArray(parsed.variables) ? parsed.variables : []; - // for (const variable of variables) { - // if (!variable || !variable.name) { - // continue; - // } - // const name = String(variable.name).trim(); - // if (!name || seenNames.has(name)) { - // continue; - // } - // seenNames.add(name); - // variableNames.push(name); - // } - // } - - // const templateContent = variableNames.length > 0 ? `${variableNames.map(v => `${v}=${DEFAULT_ENV_VAR_VALUE}`).join('\n')}\n` : ''; - // fs.writeFileSync(path.join(targetDir, '.env.template'), templateContent, 'utf8'); - // dotenvVariablesByTarget.set(targetDir, new Set(variableNames)); - for (const jsFile of jsFiles) { - fs.copyFileSync(jsFile[0], jsFile[1]); - } - } - - return targets; -} - -function cleanFolder(dir) { - if (!fs.existsSync(dir)) return; - - const entries = fs.readdirSync(dir, { withFileTypes: true }); - - for (const entry of entries) { - const fullPath = path.join(dir, entry.name); - - if (entry.isDirectory()) { - // Ricorsione - cleanFolder(fullPath); - - // Dopo la pulizia, se la cartella è vuota → cancellala - const remaining = fs.readdirSync(fullPath); - if (remaining.length === 0) { - fs.rmdirSync(fullPath); - } - } else if (entry.isFile()) { - // File da eliminare - if ( - entry.name.endsWith(".js") || - entry.name.endsWith(".http") || - entry.name.endsWith(".env.template") - ) { - fs.unlinkSync(fullPath); - } - } - } -} - -function main() { - const workspaceRoot = findWorkspaceRoot(__dirname); - const workspaceFile = path.join(workspaceRoot, 'workspace.yml'); - const workspace = parseWorkspace(workspaceFile); - const collections = Array.isArray(workspace.collections) ? workspace.collections : []; - - if (collections.length === 0) { - throw new Error('No collections found in workspace.yml'); - } - - const outputBaseRoot = path.join(workspaceRoot, 'autogen', 'httpyac_node'); - cleanFolder(outputBaseRoot); - - for (const collection of collections) { - if (!collection || !collection.name || !collection.path) { - continue; - } - - const sourceDir = path.join(workspaceRoot, collection.path); - if (!fs.existsSync(sourceDir)) { - console.warn(`Skipping missing collection path: ${collection.path}`); - continue; - } - - const outputRoot = path.join(outputBaseRoot, collection.name); - ensureDir(outputRoot); - - const writtenJsFiles = writeJsFiles(sourceDir, outputRoot); - - const dotenvVariablesByTarget = writeEnvironmentTemplates(sourceDir, outputRoot); - - const yamlFiles = walkYamlFiles(sourceDir); - let processed = 0; - - for (const yamlFile of yamlFiles) { - const content = readText(yamlFile); - const requestName = parseRequestInfo(content) || path.basename(yamlFile, path.extname(yamlFile)); - const httpBlock = parseHttpBlock(content); - if (!httpBlock || !httpBlock.url) { - continue; - } - - const relativePath = path.relative(sourceDir, yamlFile); - const parsedPath = path.parse(relativePath); - const targetDir = path.join(outputRoot, parsedPath.dir); - ensureDir(targetDir); - - const requestConfig = getRequestConfigForFile(yamlFile, sourceDir); - const outputFile = path.join(targetDir, `${parsedPath.name}.http`); - const dotenvVariables = getDotenvVariablesForTargetDir(targetDir, outputRoot, dotenvVariablesByTarget); - const requestContent = buildRequestContent(httpBlock, requestName, requestConfig, dotenvVariables); - fs.writeFileSync(outputFile, `${requestContent}\n`, 'utf8'); - processed += 1; - } - - console.log(`${collection.name.padEnd(33)} => generated ${processed.toString().padStart(3)} .http file(s) and ${writtenJsFiles.length.toString().padStart(3)} .js file(s)`); - } -} - -try { - main(); -} catch (error) { - console.error(error.message); - process.exit(1); -} diff --git a/tools/generate-http-requests/generate-http-requests.test.mjs b/tools/generate-http-requests/generate-http-requests.test.mjs deleted file mode 100644 index 3f46f4b..0000000 --- a/tools/generate-http-requests/generate-http-requests.test.mjs +++ /dev/null @@ -1,47 +0,0 @@ -import test from 'node:test'; -import assert from 'node:assert/strict'; -import fs from 'node:fs'; -import os from 'node:os'; -import path from 'node:path'; -import { buildRequestContent, getRequestConfigForFile, mergeRequestConfig } from './generate-http-requests.js'; - -test('does not inherit parent auth when a child config has no auth override', () => { - const parentAuth = { type: 'bearer', token: 'parent-token' }; - const merged = mergeRequestConfig({ auth: parentAuth }, {}); - - assert.equal(merged.auth, undefined); -}); - -test('uses an explicit child auth object instead of inheriting the parent auth', () => { - const parentAuth = { type: 'bearer', token: 'parent-token' }; - const childAuth = { type: 'basic', username: 'user', password: 'pass' }; - const merged = mergeRequestConfig({ auth: parentAuth }, { auth: childAuth }); - - assert.deepEqual(merged.auth, childAuth); -}); - -test('reads auth inherit from a Bruno-style http block', () => { - const tempRoot = fs.mkdtempSync(path.join(os.tmpdir(), 'bruno-auth-')); - const childDir = path.join(tempRoot, 'nested'); - fs.mkdirSync(childDir, { recursive: true }); - fs.writeFileSync(path.join(tempRoot, 'opencollection.yml'), `request:\n auth:\n type: bearer\n token: "parent-token"\n`); - fs.writeFileSync(path.join(tempRoot, 'folder.yml'), 'auth: inherit\n'); - fs.writeFileSync(path.join(childDir, 'request.yml'), 'http:\n auth: inherit\n'); - - const config = getRequestConfigForFile(path.join(childDir, 'request.yml'), tempRoot); - - assert.deepEqual(config.auth, { type: 'bearer', token: 'parent-token' }); -}); - -test('renders dotenv placeholders in generated variable definitions', () => { - const request = { - url: 'https://example.test', - params: [ - { name: 'username', value: '{{elixFormsApiUsername}}', type: 'path' }, - ], - }; - - const output = buildRequestContent(request, 'Logout', {}, new Set(['elixFormsApiUsername'])); - - assert.match(output, /@username = "\{\{\$dotenv elixFormsApiUsername\}\}"/); -}); diff --git a/tools/generate-http-requests/package-lock.json b/tools/generate-http-requests/package-lock.json deleted file mode 100644 index f21b0b5..0000000 --- a/tools/generate-http-requests/package-lock.json +++ /dev/null @@ -1,43 +0,0 @@ -{ - "name": "generate-http-requests", - "version": "0.0.1", - "lockfileVersion": 3, - "requires": true, - "packages": { - "": { - "name": "generate-http-requests", - "version": "0.0.1", - "dependencies": { - "strip-json-comments": "^5.0.3", - "yaml": "^2.9.0" - } - }, - "node_modules/strip-json-comments": { - "version": "5.0.3", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-5.0.3.tgz", - "integrity": "sha512-1tB5mhVo7U+ETBKNf92xT4hrQa3pm0MZ0PQvuDnWgAAGHDsfp4lPSpiS6psrSiet87wyGPh9ft6wmhOMQ0hDiw==", - "license": "MIT", - "engines": { - "node": ">=14.16" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/yaml": { - "version": "2.9.0", - "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.9.0.tgz", - "integrity": "sha512-2AvhNX3mb8zd6Zy7INTtSpl1F15HW6Wnqj0srWlkKLcpYl/gMIMJiyuGq2KeI2YFxUPjdlB+3Lc10seMLtL4cA==", - "license": "ISC", - "bin": { - "yaml": "bin.mjs" - }, - "engines": { - "node": ">= 14.6" - }, - "funding": { - "url": "https://github.com/sponsors/eemeli" - } - } - } -} diff --git a/tools/generate-http-requests/package.json b/tools/generate-http-requests/package.json deleted file mode 100644 index 91b88cc..0000000 --- a/tools/generate-http-requests/package.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "name": "generate-http-requests", - "version": "0.0.1", - "type": "module", - "dependencies": { - "strip-json-comments": "^5.0.3", - "yaml": "^2.9.0" - } -} \ No newline at end of file