From 1714e631ad24b9249831612775577fedb69ac943 Mon Sep 17 00:00:00 2001 From: Mrsandeep27 Date: Mon, 20 Apr 2026 01:03:32 +0530 Subject: [PATCH] feat(auth): add empty collection variables for auth placeholders on import MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When an OpenAPI spec declares a security scheme, the generated Postman collection's auth block references templates like `{{basicAuthUsername}}`, `{{basicAuthPassword}}`, `{{bearerToken}}`, etc. Today those variables are not added to `collection.variable`, so the first time a user sends a request they hit an "unresolved variable" warning and have to discover where credentials are expected. This mirrors the existing `baseUrl` treatment: after `collection.auth` is set, scan the auth helper for `{{identifier}}` placeholders and push an empty Variable for each unique one into `collection.variable`. That way users see all auth credentials alongside `baseUrl` in the Variables tab and can fill them in one place. - schemaUtils.getAuthCollectionVariables(authHelper): new helper that recursively scans the auth helper payload for `{{...}}` placeholders and returns empty collection-level `Variable` objects for each unique name. No-op for `noauth`. - schemapack.js: after setting `generatedStore.collection.auth`, push the returned variables alongside `baseUrl`. - Extended the existing basic-auth test to assert `basicAuthUsername` and `basicAuthPassword` now appear as empty entries in `collection.variable`. Works uniformly for all auth schemes that use variable placeholders (basic, bearer, digest, apiKey, oauth2, …) without needing per-scheme mappings. Closes #894 Co-Authored-By: Claude --- lib/schemaUtils.js | 52 +++++++++++++++++++++++++++++++++++++ lib/schemapack.js | 11 ++++++++ test/unit/convertV2.test.js | 16 ++++++++++++ 3 files changed, 79 insertions(+) diff --git a/lib/schemaUtils.js b/lib/schemaUtils.js index 3ad72128..bde17cbc 100644 --- a/lib/schemaUtils.js +++ b/lib/schemaUtils.js @@ -534,6 +534,58 @@ module.exports = { return variables; }, + /** + * Given a Postman auth helper produced by `getAuthHelper`, returns an array of + * collection-level Variable objects (empty values) for every `{{variable}}` + * placeholder the helper references. This lets users of an imported collection + * see / fill the auth credentials in the Variables tab alongside `baseUrl`, + * instead of hitting unresolved-variable warnings the first time they send a + * request. + * + * Only variables that are clearly credential placeholders are emitted — the + * helper values are scanned for `{{}}` substrings and each unique + * identifier becomes an empty Variable. No-op for `noauth`. + * + * @param {object} authHelper - the object returned by `getAuthHelper`. + * @returns {Variable[]} collection variables for credential placeholders. + */ + getAuthCollectionVariables: function(authHelper) { + if (!_.isObject(authHelper) || !authHelper.type || authHelper.type === 'noauth') { + return []; + } + + const placeholderKeys = new Set(); + const placeholderRegex = /\{\{\s*([A-Za-z0-9_]+)\s*\}\}/g; + + const scan = (value) => { + if (_.isString(value)) { + let match; + while ((match = placeholderRegex.exec(value)) !== null) { + placeholderKeys.add(match[1]); + } + } + else if (_.isArray(value)) { + value.forEach(scan); + } + else if (_.isObject(value)) { + _.forEach(value, scan); + } + }; + + // Only scan the helper payload, not the top-level `type`. + _.forEach(authHelper, (value, key) => { + if (key !== 'type') { + scan(value); + } + }); + + return Array.from(placeholderKeys).map((key) => new Variable({ + key: key, + value: '', + type: 'string' + })); + }, + /** * Returns params applied to specific operation with resolved references. Params from parent * blocks (collection/folder) are merged, so that the request has a flattened list of params needed. diff --git a/lib/schemapack.js b/lib/schemapack.js index 85bc4e89..ad81a629 100644 --- a/lib/schemapack.js +++ b/lib/schemapack.js @@ -364,6 +364,17 @@ class SchemaPack { generatedStore.collection.variables.add(element); }); + // Mirror the baseUrl treatment for auth credentials — when the spec uses + // a security scheme, expose empty placeholders (basicAuthUsername / + // basicAuthPassword / bearerToken / apiKey / …) in the Variables tab so + // users can fill them in one place instead of hitting unresolved-variable + // warnings on first send. See #894. + if (authHelper) { + schemaUtils.getAuthCollectionVariables(authHelper).forEach((element) => { + generatedStore.collection.variables.add(element); + }); + } + generatedStore.collection.describe(schemaUtils.getCollectionDescription(openapi)); // Only change the stack limit if the optimizeConversion option is true diff --git a/test/unit/convertV2.test.js b/test/unit/convertV2.test.js index ed266b8b..fb97c0f2 100644 --- a/test/unit/convertV2.test.js +++ b/test/unit/convertV2.test.js @@ -1523,6 +1523,22 @@ describe('The convert v2 Function', function() { expect(conversionResult.output[0].data.item.length).to.equal(1); expect(conversionResult.output[0].data.auth.basic[0].value).to.equal('{{basicAuthUsername}}'); expect(conversionResult.output[0].data.auth.basic[1].value).to.equal('{{basicAuthPassword}}'); + + // Empty collection-level variables for the auth placeholders should be + // pushed alongside `baseUrl` so users can fill them in the Variables + // tab. See #894. + const variableKeys = conversionResult.output[0].data.variable.map((v) => v.key); + expect(variableKeys).to.include('basicAuthUsername'); + expect(variableKeys).to.include('basicAuthPassword'); + const basicAuthUsername = conversionResult.output[0].data.variable.find( + (v) => v.key === 'basicAuthUsername' + ); + const basicAuthPassword = conversionResult.output[0].data.variable.find( + (v) => v.key === 'basicAuthPassword' + ); + expect(basicAuthUsername.value).to.equal(''); + expect(basicAuthPassword.value).to.equal(''); + done(); }); });