fix authorization headers generation
add unit tests
This commit is contained in:
@@ -197,38 +197,7 @@ function formatVariableValue(value) {
|
|||||||
return JSON.stringify(value);
|
return JSON.stringify(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
function mergeRequestConfig(base, updates) {
|
export function getRequestConfigForFile(yamlFile, sourceDir) {
|
||||||
if (!updates || typeof updates !== 'object') {
|
|
||||||
return base;
|
|
||||||
}
|
|
||||||
|
|
||||||
const merged = { ...(base || {}) };
|
|
||||||
if (updates.auth) {
|
|
||||||
if (updates.auth === 'inherit' && merged.auth && typeof merged.auth === 'object') {
|
|
||||||
merged.auth = merged.auth;
|
|
||||||
} else if (typeof updates.auth === 'object') {
|
|
||||||
merged.auth = updates.auth;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
function getRequestConfigForFile(yamlFile, sourceDir) {
|
|
||||||
const resolved = [];
|
const resolved = [];
|
||||||
const seenFiles = new Set();
|
const seenFiles = new Set();
|
||||||
|
|
||||||
@@ -243,16 +212,35 @@ function getRequestConfigForFile(yamlFile, sourceDir) {
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
const parsed = parseYaml(filePath);
|
const parsed = parseYaml(filePath);
|
||||||
|
let requestConfig = null;
|
||||||
|
|
||||||
if (parsed && parsed.request && typeof parsed.request === 'object') {
|
if (parsed && parsed.request && typeof parsed.request === 'object') {
|
||||||
resolved.push(parsed.request);
|
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) {
|
} catch (error) {
|
||||||
// Ignore files that cannot be parsed as YAML for request inheritance.
|
// Ignore files that cannot be parsed as YAML for request inheritance.
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
addFile(yamlFile);
|
|
||||||
|
|
||||||
const dirChain = [];
|
const dirChain = [];
|
||||||
let currentDir = path.dirname(yamlFile);
|
let currentDir = path.dirname(yamlFile);
|
||||||
while (true) {
|
while (true) {
|
||||||
@@ -272,9 +260,52 @@ function getRequestConfigForFile(yamlFile, sourceDir) {
|
|||||||
addFile(path.join(dir, 'folder.yml'));
|
addFile(path.join(dir, 'folder.yml'));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
addFile(yamlFile);
|
||||||
|
|
||||||
return resolved.reduce((result, config) => mergeRequestConfig(result, config), {});
|
return resolved.reduce((result, config) => mergeRequestConfig(result, config), {});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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 (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;
|
||||||
|
}
|
||||||
|
|
||||||
function buildRequestContent(request, requestName, requestConfig = {}, dotenvVariables = new Set()) {
|
function buildRequestContent(request, requestName, requestConfig = {}, dotenvVariables = new Set()) {
|
||||||
const lines = [];
|
const lines = [];
|
||||||
const variableDefinitions = [];
|
const variableDefinitions = [];
|
||||||
|
|||||||
@@ -0,0 +1,34 @@
|
|||||||
|
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 { getRequestConfigForFile, mergeRequestConfig } from './generate-http-docs.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' });
|
||||||
|
});
|
||||||
Reference in New Issue
Block a user