@postman-cse/onboarding-repo-sync 2.3.1 → 2.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -113,7 +113,17 @@ with:
113
113
  monitor-id: 1e2f3a4b-monitor-id
114
114
  ```
115
115
 
116
- Repo-sync defaults to public mocks for anonymous validation. Set `mock-visibility: private` for teams that prohibit public mocks. Explicit, discovered, and newly created mocks must match the requested visibility and the expected baseline collection/environment; unknown visibility, stale URLs, and identity mismatches fail before `mock-url` is emitted. For private mocks, repo-sync emits `mock-auth-required: true` and installs a secret-free request hook in the smoke and contract collections. The runner must supply its PMAK as the transient `postmanPrivateMockApiKey` variable. Repo-sync never writes that credential to a collection, environment, output, or repository artifact.
116
+ Repo-sync defaults to public mocks for anonymous validation. Set `mock-visibility: private` for teams that prohibit public mocks. Explicit, discovered, and newly created mocks must match the requested visibility and the expected baseline collection/environment; unknown visibility, stale URLs, and identity mismatches fail before `mock-url` is emitted.
117
+
118
+ For private mocks, repo-sync emits `mock-auth-required: true` and installs a secret-free request hook in the smoke and contract collections. The hook reads the transient `postmanPrivateMockApiKey` variable and sends it as `x-api-key`, and only to `*.mock.pstmn.io` hosts, so it stays inert on runs that target a real environment. Repo-sync never writes that credential to a collection, environment, output, or repository artifact.
119
+
120
+ Where that variable comes from depends on who is running the collection:
121
+
122
+ - **Generated CI** supplies it automatically from the `POSTMAN_API_KEY` secret repo-sync already provisions for `postman login`. No extra secret and no workflow edit.
123
+ - **Manual runs in the Postman app** use the `<project> - Mock` environment, which carries `postmanPrivateMockApiKey` as an empty secret-typed variable. Paste a key with access to the mock. Requires `mock-environment-enabled: true`.
124
+ - **A runner you wire yourself** reads `mock-auth-required` and passes the variable however that system handles secrets.
125
+
126
+ A request to a private mock with no key set logs a console warning naming the variable, so a `401` explains its own fix.
117
127
 
118
128
  For manual collection validation against the resolved mock, opt in to a dedicated Postman environment:
119
129
 
package/dist/action.cjs CHANGED
@@ -134252,6 +134252,7 @@ function resolvePostmanEndpointProfile(stack, region = "us") {
134252
134252
  // src/lib/ci-workflow-template.ts
134253
134253
  var DEFAULT_POSTMAN_CLI_INSTALL_URL = POSTMAN_ENDPOINT_PROFILES.prod.cliInstallUrl;
134254
134254
  var DEFAULT_POSTMAN_CLI_WINDOWS_INSTALL_URL = POSTMAN_ENDPOINT_PROFILES.prod.cliWindowsInstallUrl;
134255
+ var PRIVATE_MOCK_AUTH_VARIABLE = "postmanPrivateMockApiKey";
134255
134256
  function validateHttpsInstallUrl(url) {
134256
134257
  const safeUrlPattern = /^https:\/\/[A-Za-z0-9.-]+\/[A-Za-z0-9._~/?=&%-]+$/;
134257
134258
  if (!safeUrlPattern.test(url)) {
@@ -134283,9 +134284,9 @@ function renderCiWorkflowTemplate(options = {}) {
134283
134284
  const rawUrl = String(options.postmanCliInstallUrl || "").trim() || DEFAULT_POSTMAN_CLI_INSTALL_URL;
134284
134285
  const installUrl = validateHttpsInstallUrl(rawUrl);
134285
134286
  const postmanRegion = resolvePostmanRegion(options.postmanRegion);
134286
- return buildCiWorkflowLines(installUrl, postmanRegion).join("\n");
134287
+ return buildCiWorkflowLines(installUrl, postmanRegion, options.privateMockAuth === true).join("\n");
134287
134288
  }
134288
- function buildCiWorkflowLines(installUrl, postmanRegion) {
134289
+ function buildCiWorkflowLines(installUrl, postmanRegion, privateMockAuth) {
134289
134290
  return [
134290
134291
  "name: CI/CD Pipeline",
134291
134292
  "on:",
@@ -134352,6 +134353,7 @@ function buildCiWorkflowLines(installUrl, postmanRegion) {
134352
134353
  ' -e "$POSTMAN_ENVIRONMENT_UID"',
134353
134354
  " --report-events",
134354
134355
  ` --env-var "CI_ENVIRONMENT=\${{ vars.CI_ENVIRONMENT || 'Production' }}")`,
134356
+ ...privateMockAuth ? [' CMD+=(--env-var "' + PRIVATE_MOCK_AUTH_VARIABLE + '=${{ secrets.POSTMAN_API_KEY }}")'] : [],
134355
134357
  ' if [ -f "$RUNNER_TEMP/postman-ssl/client.crt" ]; then',
134356
134358
  ' CMD+=(--ssl-client-cert "$RUNNER_TEMP/postman-ssl/client.crt"',
134357
134359
  ' --ssl-client-key "$RUNNER_TEMP/postman-ssl/client.key")',
@@ -134371,6 +134373,7 @@ function buildCiWorkflowLines(installUrl, postmanRegion) {
134371
134373
  ' -e "$POSTMAN_ENVIRONMENT_UID"',
134372
134374
  " --report-events",
134373
134375
  ` --env-var "CI_ENVIRONMENT=\${{ vars.CI_ENVIRONMENT || 'Production' }}")`,
134376
+ ...privateMockAuth ? [' CMD+=(--env-var "' + PRIVATE_MOCK_AUTH_VARIABLE + '=${{ secrets.POSTMAN_API_KEY }}")'] : [],
134374
134377
  ' if [ -f "$RUNNER_TEMP/postman-ssl/client.crt" ]; then',
134375
134378
  ' CMD+=(--ssl-client-cert "$RUNNER_TEMP/postman-ssl/client.crt"',
134376
134379
  ' --ssl-client-key "$RUNNER_TEMP/postman-ssl/client.key")',
@@ -134386,7 +134389,7 @@ function buildCiWorkflowLines(installUrl, postmanRegion) {
134386
134389
  ];
134387
134390
  }
134388
134391
  var CI_WORKFLOW_TEMPLATE = renderCiWorkflowTemplate();
134389
- function buildAdoWindowsCollectionRunLines(displayName, collectionEnvironmentName) {
134392
+ function buildAdoWindowsCollectionRunLines(displayName, collectionEnvironmentName, privateMockAuth) {
134390
134393
  return [
134391
134394
  " - pwsh: |",
134392
134395
  " $ErrorActionPreference = 'Stop'",
@@ -134398,6 +134401,7 @@ function buildAdoWindowsCollectionRunLines(displayName, collectionEnvironmentNam
134398
134401
  " $ciEnvironment = Resolve-AdoOptional $env:CI_ENVIRONMENT",
134399
134402
  " if ([string]::IsNullOrWhiteSpace($ciEnvironment)) { $ciEnvironment = 'Production' }",
134400
134403
  ` $arguments = @('collection', 'run', $collectionUid, '-e', $env:POSTMAN_ENVIRONMENT_UID, '--report-events', '--env-var', "CI_ENVIRONMENT=$ciEnvironment")`,
134404
+ ...privateMockAuth ? [` $arguments += @('--env-var', "${PRIVATE_MOCK_AUTH_VARIABLE}=$env:POSTMAN_API_KEY")`] : [],
134401
134405
  " $sslRoot = Join-Path $env:AGENT_TEMPDIRECTORY 'postman-ssl'",
134402
134406
  " $clientCert = Join-Path $sslRoot 'client.crt'",
134403
134407
  " $clientKey = Join-Path $sslRoot 'client.key'",
@@ -134419,10 +134423,11 @@ function buildAdoWindowsCollectionRunLines(displayName, collectionEnvironmentNam
134419
134423
  ` ${collectionEnvironmentName}: $(${collectionEnvironmentName})`,
134420
134424
  " POSTMAN_ENVIRONMENT_UID: $(POSTMAN_ENVIRONMENT_UID)",
134421
134425
  " CI_ENVIRONMENT: $(CI_ENVIRONMENT)",
134422
- " POSTMAN_SSL_CLIENT_PASSPHRASE: $(POSTMAN_SSL_CLIENT_PASSPHRASE)"
134426
+ " POSTMAN_SSL_CLIENT_PASSPHRASE: $(POSTMAN_SSL_CLIENT_PASSPHRASE)",
134427
+ ...privateMockAuth ? [" POSTMAN_API_KEY: $(POSTMAN_API_KEY)"] : []
134423
134428
  ];
134424
134429
  }
134425
- function buildAdoWindowsCiWorkflowLines(installUrl, postmanRegion) {
134430
+ function buildAdoWindowsCiWorkflowLines(installUrl, postmanRegion, privateMockAuth) {
134426
134431
  return [
134427
134432
  "trigger:",
134428
134433
  " branches:",
@@ -134507,12 +134512,12 @@ function buildAdoWindowsCiWorkflowLines(installUrl, postmanRegion) {
134507
134512
  " POSTMAN_SSL_CLIENT_CERT_B64: $(POSTMAN_SSL_CLIENT_CERT_B64)",
134508
134513
  " POSTMAN_SSL_CLIENT_KEY_B64: $(POSTMAN_SSL_CLIENT_KEY_B64)",
134509
134514
  " POSTMAN_SSL_EXTRA_CA_CERTS_B64: $(POSTMAN_SSL_EXTRA_CA_CERTS_B64)",
134510
- ...buildAdoWindowsCollectionRunLines("Run Smoke Tests", "POSTMAN_SMOKE_COLLECTION_UID"),
134511
- ...buildAdoWindowsCollectionRunLines("Run Contract Tests", "POSTMAN_CONTRACT_COLLECTION_UID"),
134515
+ ...buildAdoWindowsCollectionRunLines("Run Smoke Tests", "POSTMAN_SMOKE_COLLECTION_UID", privateMockAuth),
134516
+ ...buildAdoWindowsCollectionRunLines("Run Contract Tests", "POSTMAN_CONTRACT_COLLECTION_UID", privateMockAuth),
134512
134517
  ""
134513
134518
  ];
134514
134519
  }
134515
- function buildAdoCiWorkflowLines(installUrl, postmanRegion) {
134520
+ function buildAdoCiWorkflowLines(installUrl, postmanRegion, privateMockAuth) {
134516
134521
  return [
134517
134522
  "trigger:",
134518
134523
  " branches:",
@@ -134589,6 +134594,7 @@ function buildAdoCiWorkflowLines(installUrl, postmanRegion) {
134589
134594
  ' -e "$POSTMAN_ENVIRONMENT_UID"',
134590
134595
  " --report-events",
134591
134596
  ' --env-var "CI_ENVIRONMENT=${CI_ENVIRONMENT:-Production}")',
134597
+ ...privateMockAuth ? [' CMD+=(--env-var "' + PRIVATE_MOCK_AUTH_VARIABLE + '=$POSTMAN_API_KEY")'] : [],
134592
134598
  ' if [ -f "$(Agent.TempDirectory)/postman-ssl/client.crt" ]; then',
134593
134599
  ' CMD+=(--ssl-client-cert "$(Agent.TempDirectory)/postman-ssl/client.crt"',
134594
134600
  ' --ssl-client-key "$(Agent.TempDirectory)/postman-ssl/client.key")',
@@ -134604,6 +134610,7 @@ function buildAdoCiWorkflowLines(installUrl, postmanRegion) {
134604
134610
  " env:",
134605
134611
  " CI_ENVIRONMENT: $(CI_ENVIRONMENT)",
134606
134612
  " POSTMAN_SSL_CLIENT_PASSPHRASE: $(POSTMAN_SSL_CLIENT_PASSPHRASE)",
134613
+ ...privateMockAuth ? [" POSTMAN_API_KEY: $(POSTMAN_API_KEY)"] : [],
134607
134614
  " - script: |",
134608
134615
  " normalize_azure_optional_var() {",
134609
134616
  ' local name="$1"',
@@ -134620,6 +134627,7 @@ function buildAdoCiWorkflowLines(installUrl, postmanRegion) {
134620
134627
  ' -e "$POSTMAN_ENVIRONMENT_UID"',
134621
134628
  " --report-events",
134622
134629
  ' --env-var "CI_ENVIRONMENT=${CI_ENVIRONMENT:-Production}")',
134630
+ ...privateMockAuth ? [' CMD+=(--env-var "' + PRIVATE_MOCK_AUTH_VARIABLE + '=$POSTMAN_API_KEY")'] : [],
134623
134631
  ' if [ -f "$(Agent.TempDirectory)/postman-ssl/client.crt" ]; then',
134624
134632
  ' CMD+=(--ssl-client-cert "$(Agent.TempDirectory)/postman-ssl/client.crt"',
134625
134633
  ' --ssl-client-key "$(Agent.TempDirectory)/postman-ssl/client.key")',
@@ -134635,6 +134643,7 @@ function buildAdoCiWorkflowLines(installUrl, postmanRegion) {
134635
134643
  " env:",
134636
134644
  " CI_ENVIRONMENT: $(CI_ENVIRONMENT)",
134637
134645
  " POSTMAN_SSL_CLIENT_PASSPHRASE: $(POSTMAN_SSL_CLIENT_PASSPHRASE)",
134646
+ ...privateMockAuth ? [" POSTMAN_API_KEY: $(POSTMAN_API_KEY)"] : [],
134638
134647
  ""
134639
134648
  ];
134640
134649
  }
@@ -134696,7 +134705,8 @@ function getCiWorkflowTemplate(provider, options = {}) {
134696
134705
  const rawUrl = runnerOs === "windows" ? String(options.postmanCliWindowsInstallUrl || "").trim() || DEFAULT_POSTMAN_CLI_WINDOWS_INSTALL_URL : String(options.postmanCliInstallUrl || "").trim() || DEFAULT_POSTMAN_CLI_INSTALL_URL;
134697
134706
  const postmanRegion = resolvePostmanRegion(options.postmanRegion);
134698
134707
  const installUrl = validateHttpsInstallUrl(rawUrl);
134699
- return (runnerOs === "windows" ? buildAdoWindowsCiWorkflowLines(installUrl, postmanRegion) : buildAdoCiWorkflowLines(installUrl, postmanRegion)).join("\n");
134708
+ const privateMockAuth = options.privateMockAuth === true;
134709
+ return (runnerOs === "windows" ? buildAdoWindowsCiWorkflowLines(installUrl, postmanRegion, privateMockAuth) : buildAdoCiWorkflowLines(installUrl, postmanRegion, privateMockAuth)).join("\n");
134700
134710
  }
134701
134711
  return renderCiWorkflowTemplate(options);
134702
134712
  }
@@ -136984,16 +136994,39 @@ function requireMockVisibility(mock, requested) {
136984
136994
  }
136985
136995
  return mock;
136986
136996
  }
136987
- var PRIVATE_MOCK_AUTH_MARKER = "postman-enterprise-automation: private-mock-auth";
136988
- var PRIVATE_MOCK_AUTH_VARIABLE = "postmanPrivateMockApiKey";
136997
+ var PRIVATE_MOCK_AUTH_MARKER_PREFIX = "postman-enterprise-automation: private-mock-auth";
136998
+ var PRIVATE_MOCK_AUTH_MARKER = `${PRIVATE_MOCK_AUTH_MARKER_PREFIX}-v2`;
136999
+ var PRIVATE_MOCK_AUTH_VARIABLE2 = "postmanPrivateMockApiKey";
136989
137000
  var PRIVATE_MOCK_AUTH_SCRIPT = [
136990
137001
  `// ${PRIVATE_MOCK_AUTH_MARKER}`,
136991
- `var privateMockApiKey = pm.variables.get('${PRIVATE_MOCK_AUTH_VARIABLE}');`,
136992
- "var privateMockHost = String(pm.request.url && pm.request.url.getHost ? pm.request.url.getHost() : '');",
136993
- "if (privateMockApiKey && /(^|\\.)mock\\.pstmn\\.io$/i.test(privateMockHost)) {",
137002
+ `var privateMockApiKey = pm.variables.get('${PRIVATE_MOCK_AUTH_VARIABLE2}');`,
137003
+ "var privateMockHostValue = pm.request.url && pm.request.url.getHost ? pm.request.url.getHost() : '';",
137004
+ "var privateMockHost = Array.isArray(privateMockHostValue) ? privateMockHostValue.join('.') : String(privateMockHostValue);",
137005
+ "var isPrivateMockHost = /(^|\\.)mock\\.pstmn\\.io$/i.test(privateMockHost);",
137006
+ "if (isPrivateMockHost && privateMockApiKey) {",
136994
137007
  " pm.request.headers.upsert({ key: 'x-api-key', value: privateMockApiKey });",
137008
+ "} else if (isPrivateMockHost) {",
137009
+ ` console.warn('This mock server is private. Set the ${PRIVATE_MOCK_AUTH_VARIABLE2} variable to a Postman API key with access to it, or the request returns 401.');`,
136995
137010
  "}"
136996
137011
  ].join("\n");
137012
+ function stripPrivateMockAuthBlocks(code) {
137013
+ if (!code.includes(PRIVATE_MOCK_AUTH_MARKER_PREFIX)) return code.trim();
137014
+ const lines = code.split("\n");
137015
+ const kept = [];
137016
+ let skipping = false;
137017
+ for (const line of lines) {
137018
+ if (line.includes(PRIVATE_MOCK_AUTH_MARKER_PREFIX)) {
137019
+ skipping = true;
137020
+ continue;
137021
+ }
137022
+ if (skipping) {
137023
+ if (/^\s*(?:(?:var|if)\s|\}\selse\sif\s|\}|pm\.request|console\.warn)/.test(line)) continue;
137024
+ skipping = false;
137025
+ }
137026
+ kept.push(line);
137027
+ }
137028
+ return kept.join("\n").trim();
137029
+ }
136997
137030
  var MAX_CREATE_FLIGHTS = 256;
136998
137031
  var createFlights = /* @__PURE__ */ new Map();
136999
137032
  var PostmanGatewayAssetsClient = class {
@@ -137591,8 +137624,9 @@ var PostmanGatewayAssetsClient = class {
137591
137624
  const item = this.asRecord(response?.data) ?? listedItem;
137592
137625
  const scripts = Array.isArray(item.scripts) ? item.scripts.filter((entry) => Boolean(this.asRecord(entry))) : [];
137593
137626
  const before = scripts.find((script) => String(script.type ?? "") === "beforeRequest");
137594
- if (String(before?.code ?? "").includes(PRIVATE_MOCK_AUTH_MARKER)) continue;
137595
- const code = [String(before?.code ?? "").trim(), PRIVATE_MOCK_AUTH_SCRIPT].filter(Boolean).join("\n");
137627
+ const existingCode = String(before?.code ?? "");
137628
+ if (existingCode.includes(PRIVATE_MOCK_AUTH_MARKER)) continue;
137629
+ const code = [stripPrivateMockAuthBlocks(existingCode), PRIVATE_MOCK_AUTH_SCRIPT].filter(Boolean).join("\n");
137596
137630
  const nextScripts = [
137597
137631
  ...scripts.filter((script) => String(script.type ?? "") !== "beforeRequest"),
137598
137632
  { type: "beforeRequest", code, language: "text/javascript" }
@@ -138928,9 +138962,13 @@ function assertBranchAssetIds(inputs, decision, branchOwnedIds = process.env.POS
138928
138962
  );
138929
138963
  }
138930
138964
  }
138931
- function buildEnvironmentValues(envName, baseUrl) {
138965
+ function buildEnvironmentValues(envName, baseUrl, options = {}) {
138932
138966
  return [
138933
138967
  { key: "baseUrl", value: baseUrl, type: "default" },
138968
+ // A private mock refuses anonymous calls, so the manual-validation environment
138969
+ // carries a named, empty, secret-typed slot for the caller's own key. Repo-sync
138970
+ // never writes a value here; the developer pastes one in the Postman app.
138971
+ ...options.privateMockAuth ? [{ key: PRIVATE_MOCK_AUTH_VARIABLE2, value: "", type: "secret" }] : [],
138934
138972
  { key: "CI", value: "false", type: "default" },
138935
138973
  { key: "RESPONSE_TIME_THRESHOLD", value: "2000", type: "default" },
138936
138974
  { key: "AWS_ACCESS_KEY_ID", value: "", type: "secret" },
@@ -139377,12 +139415,12 @@ async function upsertEnvironments(inputs, dependencies, resourcesState, assetMar
139377
139415
  }
139378
139416
  return envUids;
139379
139417
  }
139380
- async function upsertMockEnvironment(inputs, dependencies, assetProjectName, mockUrl) {
139418
+ async function upsertMockEnvironment(inputs, dependencies, assetProjectName, mockUrl, privateMockAuth) {
139381
139419
  if (!inputs.mockEnvironmentEnabled || !inputs.workspaceId || !mockUrl) {
139382
139420
  return "";
139383
139421
  }
139384
139422
  const displayName = `${assetProjectName} - Mock`;
139385
- const values = buildEnvironmentValues("mock", mockUrl);
139423
+ const values = buildEnvironmentValues("mock", mockUrl, { privateMockAuth });
139386
139424
  const mask = resolveRepoSyncMasker(dependencies);
139387
139425
  try {
139388
139426
  const discovered = await dependencies.postman.findEnvironmentByName(
@@ -140111,14 +140149,16 @@ function renderCiWorkflow(inputs) {
140111
140149
  postmanCliInstallUrl: inputs.postmanCliInstallUrl,
140112
140150
  postmanCliWindowsInstallUrl: inputs.postmanCliWindowsInstallUrl,
140113
140151
  runnerOs: inputs.ciRunnerOs,
140114
- postmanRegion: inputs.postmanRegion
140152
+ postmanRegion: inputs.postmanRegion,
140153
+ privateMockAuth: inputs.mockVisibility === "private"
140115
140154
  });
140116
140155
  }
140117
140156
  return renderCiWorkflowTemplate({
140118
140157
  postmanCliInstallUrl: inputs.postmanCliInstallUrl,
140119
140158
  postmanCliWindowsInstallUrl: inputs.postmanCliWindowsInstallUrl,
140120
140159
  runnerOs: inputs.ciRunnerOs,
140121
- postmanRegion: inputs.postmanRegion
140160
+ postmanRegion: inputs.postmanRegion,
140161
+ privateMockAuth: inputs.mockVisibility === "private"
140122
140162
  });
140123
140163
  }
140124
140164
  function createRepoSummary(outputs, envUids, pushed) {
@@ -140473,18 +140513,26 @@ async function runRepoSyncInner(inputs, dependencies) {
140473
140513
  "PRIVATE_MOCK_RUNTIME_AUTH_UNAVAILABLE: The Postman client cannot configure runtime x-api-key injection."
140474
140514
  );
140475
140515
  }
140516
+ const configured = [];
140476
140517
  for (const collectionUid of [inputs.smokeCollectionId, inputs.contractCollectionId]) {
140477
140518
  if (collectionUid) {
140478
140519
  await dependencies.postman.configurePrivateMockRuntimeAuth(collectionUid);
140520
+ configured.push(collectionUid);
140479
140521
  }
140480
140522
  }
140523
+ if (configured.length > 0) {
140524
+ (dependencies.core.notice ?? dependencies.core.info)(
140525
+ `Private mock: installed a request hook on ${configured.length} collection(s) that sends the ${PRIVATE_MOCK_AUTH_VARIABLE2} variable as x-api-key, and only to *.mock.pstmn.io hosts. The generated CI workflow supplies it from the POSTMAN_API_KEY secret. For manual runs in the Postman app, set that variable to a key with access to the mock. No key is stored in the collection, environment, outputs, or repository.`
140526
+ );
140527
+ }
140481
140528
  }
140482
140529
  if (inputs.mockEnvironmentEnabled && isCanonicalWriter) {
140483
140530
  const mockEnvironmentUid = await upsertMockEnvironment(
140484
140531
  inputs,
140485
140532
  dependencies,
140486
140533
  assetProjectName,
140487
- resolvedMockUrl
140534
+ resolvedMockUrl,
140535
+ resolvedMockVisibility === "private"
140488
140536
  );
140489
140537
  outputs["mock-environment-uid"] = mockEnvironmentUid;
140490
140538
  outputs["mock-environment-status"] = mockEnvironmentUid ? "success" : "failed";
package/dist/cli.cjs CHANGED
@@ -132357,6 +132357,7 @@ function resolvePostmanEndpointProfile(stack, region = "us") {
132357
132357
  // src/lib/ci-workflow-template.ts
132358
132358
  var DEFAULT_POSTMAN_CLI_INSTALL_URL = POSTMAN_ENDPOINT_PROFILES.prod.cliInstallUrl;
132359
132359
  var DEFAULT_POSTMAN_CLI_WINDOWS_INSTALL_URL = POSTMAN_ENDPOINT_PROFILES.prod.cliWindowsInstallUrl;
132360
+ var PRIVATE_MOCK_AUTH_VARIABLE = "postmanPrivateMockApiKey";
132360
132361
  function validateHttpsInstallUrl(url) {
132361
132362
  const safeUrlPattern = /^https:\/\/[A-Za-z0-9.-]+\/[A-Za-z0-9._~/?=&%-]+$/;
132362
132363
  if (!safeUrlPattern.test(url)) {
@@ -132388,9 +132389,9 @@ function renderCiWorkflowTemplate(options = {}) {
132388
132389
  const rawUrl = String(options.postmanCliInstallUrl || "").trim() || DEFAULT_POSTMAN_CLI_INSTALL_URL;
132389
132390
  const installUrl = validateHttpsInstallUrl(rawUrl);
132390
132391
  const postmanRegion = resolvePostmanRegion(options.postmanRegion);
132391
- return buildCiWorkflowLines(installUrl, postmanRegion).join("\n");
132392
+ return buildCiWorkflowLines(installUrl, postmanRegion, options.privateMockAuth === true).join("\n");
132392
132393
  }
132393
- function buildCiWorkflowLines(installUrl, postmanRegion) {
132394
+ function buildCiWorkflowLines(installUrl, postmanRegion, privateMockAuth) {
132394
132395
  return [
132395
132396
  "name: CI/CD Pipeline",
132396
132397
  "on:",
@@ -132457,6 +132458,7 @@ function buildCiWorkflowLines(installUrl, postmanRegion) {
132457
132458
  ' -e "$POSTMAN_ENVIRONMENT_UID"',
132458
132459
  " --report-events",
132459
132460
  ` --env-var "CI_ENVIRONMENT=\${{ vars.CI_ENVIRONMENT || 'Production' }}")`,
132461
+ ...privateMockAuth ? [' CMD+=(--env-var "' + PRIVATE_MOCK_AUTH_VARIABLE + '=${{ secrets.POSTMAN_API_KEY }}")'] : [],
132460
132462
  ' if [ -f "$RUNNER_TEMP/postman-ssl/client.crt" ]; then',
132461
132463
  ' CMD+=(--ssl-client-cert "$RUNNER_TEMP/postman-ssl/client.crt"',
132462
132464
  ' --ssl-client-key "$RUNNER_TEMP/postman-ssl/client.key")',
@@ -132476,6 +132478,7 @@ function buildCiWorkflowLines(installUrl, postmanRegion) {
132476
132478
  ' -e "$POSTMAN_ENVIRONMENT_UID"',
132477
132479
  " --report-events",
132478
132480
  ` --env-var "CI_ENVIRONMENT=\${{ vars.CI_ENVIRONMENT || 'Production' }}")`,
132481
+ ...privateMockAuth ? [' CMD+=(--env-var "' + PRIVATE_MOCK_AUTH_VARIABLE + '=${{ secrets.POSTMAN_API_KEY }}")'] : [],
132479
132482
  ' if [ -f "$RUNNER_TEMP/postman-ssl/client.crt" ]; then',
132480
132483
  ' CMD+=(--ssl-client-cert "$RUNNER_TEMP/postman-ssl/client.crt"',
132481
132484
  ' --ssl-client-key "$RUNNER_TEMP/postman-ssl/client.key")',
@@ -132491,7 +132494,7 @@ function buildCiWorkflowLines(installUrl, postmanRegion) {
132491
132494
  ];
132492
132495
  }
132493
132496
  var CI_WORKFLOW_TEMPLATE = renderCiWorkflowTemplate();
132494
- function buildAdoWindowsCollectionRunLines(displayName, collectionEnvironmentName) {
132497
+ function buildAdoWindowsCollectionRunLines(displayName, collectionEnvironmentName, privateMockAuth) {
132495
132498
  return [
132496
132499
  " - pwsh: |",
132497
132500
  " $ErrorActionPreference = 'Stop'",
@@ -132503,6 +132506,7 @@ function buildAdoWindowsCollectionRunLines(displayName, collectionEnvironmentNam
132503
132506
  " $ciEnvironment = Resolve-AdoOptional $env:CI_ENVIRONMENT",
132504
132507
  " if ([string]::IsNullOrWhiteSpace($ciEnvironment)) { $ciEnvironment = 'Production' }",
132505
132508
  ` $arguments = @('collection', 'run', $collectionUid, '-e', $env:POSTMAN_ENVIRONMENT_UID, '--report-events', '--env-var', "CI_ENVIRONMENT=$ciEnvironment")`,
132509
+ ...privateMockAuth ? [` $arguments += @('--env-var', "${PRIVATE_MOCK_AUTH_VARIABLE}=$env:POSTMAN_API_KEY")`] : [],
132506
132510
  " $sslRoot = Join-Path $env:AGENT_TEMPDIRECTORY 'postman-ssl'",
132507
132511
  " $clientCert = Join-Path $sslRoot 'client.crt'",
132508
132512
  " $clientKey = Join-Path $sslRoot 'client.key'",
@@ -132524,10 +132528,11 @@ function buildAdoWindowsCollectionRunLines(displayName, collectionEnvironmentNam
132524
132528
  ` ${collectionEnvironmentName}: $(${collectionEnvironmentName})`,
132525
132529
  " POSTMAN_ENVIRONMENT_UID: $(POSTMAN_ENVIRONMENT_UID)",
132526
132530
  " CI_ENVIRONMENT: $(CI_ENVIRONMENT)",
132527
- " POSTMAN_SSL_CLIENT_PASSPHRASE: $(POSTMAN_SSL_CLIENT_PASSPHRASE)"
132531
+ " POSTMAN_SSL_CLIENT_PASSPHRASE: $(POSTMAN_SSL_CLIENT_PASSPHRASE)",
132532
+ ...privateMockAuth ? [" POSTMAN_API_KEY: $(POSTMAN_API_KEY)"] : []
132528
132533
  ];
132529
132534
  }
132530
- function buildAdoWindowsCiWorkflowLines(installUrl, postmanRegion) {
132535
+ function buildAdoWindowsCiWorkflowLines(installUrl, postmanRegion, privateMockAuth) {
132531
132536
  return [
132532
132537
  "trigger:",
132533
132538
  " branches:",
@@ -132612,12 +132617,12 @@ function buildAdoWindowsCiWorkflowLines(installUrl, postmanRegion) {
132612
132617
  " POSTMAN_SSL_CLIENT_CERT_B64: $(POSTMAN_SSL_CLIENT_CERT_B64)",
132613
132618
  " POSTMAN_SSL_CLIENT_KEY_B64: $(POSTMAN_SSL_CLIENT_KEY_B64)",
132614
132619
  " POSTMAN_SSL_EXTRA_CA_CERTS_B64: $(POSTMAN_SSL_EXTRA_CA_CERTS_B64)",
132615
- ...buildAdoWindowsCollectionRunLines("Run Smoke Tests", "POSTMAN_SMOKE_COLLECTION_UID"),
132616
- ...buildAdoWindowsCollectionRunLines("Run Contract Tests", "POSTMAN_CONTRACT_COLLECTION_UID"),
132620
+ ...buildAdoWindowsCollectionRunLines("Run Smoke Tests", "POSTMAN_SMOKE_COLLECTION_UID", privateMockAuth),
132621
+ ...buildAdoWindowsCollectionRunLines("Run Contract Tests", "POSTMAN_CONTRACT_COLLECTION_UID", privateMockAuth),
132617
132622
  ""
132618
132623
  ];
132619
132624
  }
132620
- function buildAdoCiWorkflowLines(installUrl, postmanRegion) {
132625
+ function buildAdoCiWorkflowLines(installUrl, postmanRegion, privateMockAuth) {
132621
132626
  return [
132622
132627
  "trigger:",
132623
132628
  " branches:",
@@ -132694,6 +132699,7 @@ function buildAdoCiWorkflowLines(installUrl, postmanRegion) {
132694
132699
  ' -e "$POSTMAN_ENVIRONMENT_UID"',
132695
132700
  " --report-events",
132696
132701
  ' --env-var "CI_ENVIRONMENT=${CI_ENVIRONMENT:-Production}")',
132702
+ ...privateMockAuth ? [' CMD+=(--env-var "' + PRIVATE_MOCK_AUTH_VARIABLE + '=$POSTMAN_API_KEY")'] : [],
132697
132703
  ' if [ -f "$(Agent.TempDirectory)/postman-ssl/client.crt" ]; then',
132698
132704
  ' CMD+=(--ssl-client-cert "$(Agent.TempDirectory)/postman-ssl/client.crt"',
132699
132705
  ' --ssl-client-key "$(Agent.TempDirectory)/postman-ssl/client.key")',
@@ -132709,6 +132715,7 @@ function buildAdoCiWorkflowLines(installUrl, postmanRegion) {
132709
132715
  " env:",
132710
132716
  " CI_ENVIRONMENT: $(CI_ENVIRONMENT)",
132711
132717
  " POSTMAN_SSL_CLIENT_PASSPHRASE: $(POSTMAN_SSL_CLIENT_PASSPHRASE)",
132718
+ ...privateMockAuth ? [" POSTMAN_API_KEY: $(POSTMAN_API_KEY)"] : [],
132712
132719
  " - script: |",
132713
132720
  " normalize_azure_optional_var() {",
132714
132721
  ' local name="$1"',
@@ -132725,6 +132732,7 @@ function buildAdoCiWorkflowLines(installUrl, postmanRegion) {
132725
132732
  ' -e "$POSTMAN_ENVIRONMENT_UID"',
132726
132733
  " --report-events",
132727
132734
  ' --env-var "CI_ENVIRONMENT=${CI_ENVIRONMENT:-Production}")',
132735
+ ...privateMockAuth ? [' CMD+=(--env-var "' + PRIVATE_MOCK_AUTH_VARIABLE + '=$POSTMAN_API_KEY")'] : [],
132728
132736
  ' if [ -f "$(Agent.TempDirectory)/postman-ssl/client.crt" ]; then',
132729
132737
  ' CMD+=(--ssl-client-cert "$(Agent.TempDirectory)/postman-ssl/client.crt"',
132730
132738
  ' --ssl-client-key "$(Agent.TempDirectory)/postman-ssl/client.key")',
@@ -132740,6 +132748,7 @@ function buildAdoCiWorkflowLines(installUrl, postmanRegion) {
132740
132748
  " env:",
132741
132749
  " CI_ENVIRONMENT: $(CI_ENVIRONMENT)",
132742
132750
  " POSTMAN_SSL_CLIENT_PASSPHRASE: $(POSTMAN_SSL_CLIENT_PASSPHRASE)",
132751
+ ...privateMockAuth ? [" POSTMAN_API_KEY: $(POSTMAN_API_KEY)"] : [],
132743
132752
  ""
132744
132753
  ];
132745
132754
  }
@@ -132801,7 +132810,8 @@ function getCiWorkflowTemplate(provider, options = {}) {
132801
132810
  const rawUrl = runnerOs === "windows" ? String(options.postmanCliWindowsInstallUrl || "").trim() || DEFAULT_POSTMAN_CLI_WINDOWS_INSTALL_URL : String(options.postmanCliInstallUrl || "").trim() || DEFAULT_POSTMAN_CLI_INSTALL_URL;
132802
132811
  const postmanRegion = resolvePostmanRegion(options.postmanRegion);
132803
132812
  const installUrl = validateHttpsInstallUrl(rawUrl);
132804
- return (runnerOs === "windows" ? buildAdoWindowsCiWorkflowLines(installUrl, postmanRegion) : buildAdoCiWorkflowLines(installUrl, postmanRegion)).join("\n");
132813
+ const privateMockAuth = options.privateMockAuth === true;
132814
+ return (runnerOs === "windows" ? buildAdoWindowsCiWorkflowLines(installUrl, postmanRegion, privateMockAuth) : buildAdoCiWorkflowLines(installUrl, postmanRegion, privateMockAuth)).join("\n");
132805
132815
  }
132806
132816
  return renderCiWorkflowTemplate(options);
132807
132817
  }
@@ -135089,16 +135099,39 @@ function requireMockVisibility(mock, requested) {
135089
135099
  }
135090
135100
  return mock;
135091
135101
  }
135092
- var PRIVATE_MOCK_AUTH_MARKER = "postman-enterprise-automation: private-mock-auth";
135093
- var PRIVATE_MOCK_AUTH_VARIABLE = "postmanPrivateMockApiKey";
135102
+ var PRIVATE_MOCK_AUTH_MARKER_PREFIX = "postman-enterprise-automation: private-mock-auth";
135103
+ var PRIVATE_MOCK_AUTH_MARKER = `${PRIVATE_MOCK_AUTH_MARKER_PREFIX}-v2`;
135104
+ var PRIVATE_MOCK_AUTH_VARIABLE2 = "postmanPrivateMockApiKey";
135094
135105
  var PRIVATE_MOCK_AUTH_SCRIPT = [
135095
135106
  `// ${PRIVATE_MOCK_AUTH_MARKER}`,
135096
- `var privateMockApiKey = pm.variables.get('${PRIVATE_MOCK_AUTH_VARIABLE}');`,
135097
- "var privateMockHost = String(pm.request.url && pm.request.url.getHost ? pm.request.url.getHost() : '');",
135098
- "if (privateMockApiKey && /(^|\\.)mock\\.pstmn\\.io$/i.test(privateMockHost)) {",
135107
+ `var privateMockApiKey = pm.variables.get('${PRIVATE_MOCK_AUTH_VARIABLE2}');`,
135108
+ "var privateMockHostValue = pm.request.url && pm.request.url.getHost ? pm.request.url.getHost() : '';",
135109
+ "var privateMockHost = Array.isArray(privateMockHostValue) ? privateMockHostValue.join('.') : String(privateMockHostValue);",
135110
+ "var isPrivateMockHost = /(^|\\.)mock\\.pstmn\\.io$/i.test(privateMockHost);",
135111
+ "if (isPrivateMockHost && privateMockApiKey) {",
135099
135112
  " pm.request.headers.upsert({ key: 'x-api-key', value: privateMockApiKey });",
135113
+ "} else if (isPrivateMockHost) {",
135114
+ ` console.warn('This mock server is private. Set the ${PRIVATE_MOCK_AUTH_VARIABLE2} variable to a Postman API key with access to it, or the request returns 401.');`,
135100
135115
  "}"
135101
135116
  ].join("\n");
135117
+ function stripPrivateMockAuthBlocks(code) {
135118
+ if (!code.includes(PRIVATE_MOCK_AUTH_MARKER_PREFIX)) return code.trim();
135119
+ const lines = code.split("\n");
135120
+ const kept = [];
135121
+ let skipping = false;
135122
+ for (const line of lines) {
135123
+ if (line.includes(PRIVATE_MOCK_AUTH_MARKER_PREFIX)) {
135124
+ skipping = true;
135125
+ continue;
135126
+ }
135127
+ if (skipping) {
135128
+ if (/^\s*(?:(?:var|if)\s|\}\selse\sif\s|\}|pm\.request|console\.warn)/.test(line)) continue;
135129
+ skipping = false;
135130
+ }
135131
+ kept.push(line);
135132
+ }
135133
+ return kept.join("\n").trim();
135134
+ }
135102
135135
  var MAX_CREATE_FLIGHTS = 256;
135103
135136
  var createFlights = /* @__PURE__ */ new Map();
135104
135137
  var PostmanGatewayAssetsClient = class {
@@ -135696,8 +135729,9 @@ var PostmanGatewayAssetsClient = class {
135696
135729
  const item = this.asRecord(response?.data) ?? listedItem;
135697
135730
  const scripts = Array.isArray(item.scripts) ? item.scripts.filter((entry) => Boolean(this.asRecord(entry))) : [];
135698
135731
  const before = scripts.find((script) => String(script.type ?? "") === "beforeRequest");
135699
- if (String(before?.code ?? "").includes(PRIVATE_MOCK_AUTH_MARKER)) continue;
135700
- const code = [String(before?.code ?? "").trim(), PRIVATE_MOCK_AUTH_SCRIPT].filter(Boolean).join("\n");
135732
+ const existingCode = String(before?.code ?? "");
135733
+ if (existingCode.includes(PRIVATE_MOCK_AUTH_MARKER)) continue;
135734
+ const code = [stripPrivateMockAuthBlocks(existingCode), PRIVATE_MOCK_AUTH_SCRIPT].filter(Boolean).join("\n");
135701
135735
  const nextScripts = [
135702
135736
  ...scripts.filter((script) => String(script.type ?? "") !== "beforeRequest"),
135703
135737
  { type: "beforeRequest", code, language: "text/javascript" }
@@ -136978,9 +137012,13 @@ function assertBranchAssetIds(inputs, decision, branchOwnedIds = process.env.POS
136978
137012
  );
136979
137013
  }
136980
137014
  }
136981
- function buildEnvironmentValues(envName, baseUrl) {
137015
+ function buildEnvironmentValues(envName, baseUrl, options = {}) {
136982
137016
  return [
136983
137017
  { key: "baseUrl", value: baseUrl, type: "default" },
137018
+ // A private mock refuses anonymous calls, so the manual-validation environment
137019
+ // carries a named, empty, secret-typed slot for the caller's own key. Repo-sync
137020
+ // never writes a value here; the developer pastes one in the Postman app.
137021
+ ...options.privateMockAuth ? [{ key: PRIVATE_MOCK_AUTH_VARIABLE2, value: "", type: "secret" }] : [],
136984
137022
  { key: "CI", value: "false", type: "default" },
136985
137023
  { key: "RESPONSE_TIME_THRESHOLD", value: "2000", type: "default" },
136986
137024
  { key: "AWS_ACCESS_KEY_ID", value: "", type: "secret" },
@@ -137285,12 +137323,12 @@ async function upsertEnvironments(inputs, dependencies, resourcesState, assetMar
137285
137323
  }
137286
137324
  return envUids;
137287
137325
  }
137288
- async function upsertMockEnvironment(inputs, dependencies, assetProjectName, mockUrl) {
137326
+ async function upsertMockEnvironment(inputs, dependencies, assetProjectName, mockUrl, privateMockAuth) {
137289
137327
  if (!inputs.mockEnvironmentEnabled || !inputs.workspaceId || !mockUrl) {
137290
137328
  return "";
137291
137329
  }
137292
137330
  const displayName = `${assetProjectName} - Mock`;
137293
- const values = buildEnvironmentValues("mock", mockUrl);
137331
+ const values = buildEnvironmentValues("mock", mockUrl, { privateMockAuth });
137294
137332
  const mask = resolveRepoSyncMasker(dependencies);
137295
137333
  try {
137296
137334
  const discovered = await dependencies.postman.findEnvironmentByName(
@@ -138019,14 +138057,16 @@ function renderCiWorkflow(inputs) {
138019
138057
  postmanCliInstallUrl: inputs.postmanCliInstallUrl,
138020
138058
  postmanCliWindowsInstallUrl: inputs.postmanCliWindowsInstallUrl,
138021
138059
  runnerOs: inputs.ciRunnerOs,
138022
- postmanRegion: inputs.postmanRegion
138060
+ postmanRegion: inputs.postmanRegion,
138061
+ privateMockAuth: inputs.mockVisibility === "private"
138023
138062
  });
138024
138063
  }
138025
138064
  return renderCiWorkflowTemplate({
138026
138065
  postmanCliInstallUrl: inputs.postmanCliInstallUrl,
138027
138066
  postmanCliWindowsInstallUrl: inputs.postmanCliWindowsInstallUrl,
138028
138067
  runnerOs: inputs.ciRunnerOs,
138029
- postmanRegion: inputs.postmanRegion
138068
+ postmanRegion: inputs.postmanRegion,
138069
+ privateMockAuth: inputs.mockVisibility === "private"
138030
138070
  });
138031
138071
  }
138032
138072
  function createRepoSummary(outputs, envUids, pushed) {
@@ -138381,18 +138421,26 @@ async function runRepoSyncInner(inputs, dependencies) {
138381
138421
  "PRIVATE_MOCK_RUNTIME_AUTH_UNAVAILABLE: The Postman client cannot configure runtime x-api-key injection."
138382
138422
  );
138383
138423
  }
138424
+ const configured = [];
138384
138425
  for (const collectionUid of [inputs.smokeCollectionId, inputs.contractCollectionId]) {
138385
138426
  if (collectionUid) {
138386
138427
  await dependencies.postman.configurePrivateMockRuntimeAuth(collectionUid);
138428
+ configured.push(collectionUid);
138387
138429
  }
138388
138430
  }
138431
+ if (configured.length > 0) {
138432
+ (dependencies.core.notice ?? dependencies.core.info)(
138433
+ `Private mock: installed a request hook on ${configured.length} collection(s) that sends the ${PRIVATE_MOCK_AUTH_VARIABLE2} variable as x-api-key, and only to *.mock.pstmn.io hosts. The generated CI workflow supplies it from the POSTMAN_API_KEY secret. For manual runs in the Postman app, set that variable to a key with access to the mock. No key is stored in the collection, environment, outputs, or repository.`
138434
+ );
138435
+ }
138389
138436
  }
138390
138437
  if (inputs.mockEnvironmentEnabled && isCanonicalWriter) {
138391
138438
  const mockEnvironmentUid = await upsertMockEnvironment(
138392
138439
  inputs,
138393
138440
  dependencies,
138394
138441
  assetProjectName,
138395
- resolvedMockUrl
138442
+ resolvedMockUrl,
138443
+ resolvedMockVisibility === "private"
138396
138444
  );
138397
138445
  outputs["mock-environment-uid"] = mockEnvironmentUid;
138398
138446
  outputs["mock-environment-status"] = mockEnvironmentUid ? "success" : "failed";
@@ -139401,6 +139449,9 @@ var ConsoleReporter = class {
139401
139449
  info(message) {
139402
139450
  console.error(message);
139403
139451
  }
139452
+ notice(message) {
139453
+ console.error(`notice: ${message}`);
139454
+ }
139404
139455
  warning(message) {
139405
139456
  console.error(`warning: ${message}`);
139406
139457
  }
package/dist/index.cjs CHANGED
@@ -134274,6 +134274,7 @@ function resolvePostmanEndpointProfile(stack, region = "us") {
134274
134274
  // src/lib/ci-workflow-template.ts
134275
134275
  var DEFAULT_POSTMAN_CLI_INSTALL_URL = POSTMAN_ENDPOINT_PROFILES.prod.cliInstallUrl;
134276
134276
  var DEFAULT_POSTMAN_CLI_WINDOWS_INSTALL_URL = POSTMAN_ENDPOINT_PROFILES.prod.cliWindowsInstallUrl;
134277
+ var PRIVATE_MOCK_AUTH_VARIABLE = "postmanPrivateMockApiKey";
134277
134278
  function validateHttpsInstallUrl(url) {
134278
134279
  const safeUrlPattern = /^https:\/\/[A-Za-z0-9.-]+\/[A-Za-z0-9._~/?=&%-]+$/;
134279
134280
  if (!safeUrlPattern.test(url)) {
@@ -134305,9 +134306,9 @@ function renderCiWorkflowTemplate(options = {}) {
134305
134306
  const rawUrl = String(options.postmanCliInstallUrl || "").trim() || DEFAULT_POSTMAN_CLI_INSTALL_URL;
134306
134307
  const installUrl = validateHttpsInstallUrl(rawUrl);
134307
134308
  const postmanRegion = resolvePostmanRegion(options.postmanRegion);
134308
- return buildCiWorkflowLines(installUrl, postmanRegion).join("\n");
134309
+ return buildCiWorkflowLines(installUrl, postmanRegion, options.privateMockAuth === true).join("\n");
134309
134310
  }
134310
- function buildCiWorkflowLines(installUrl, postmanRegion) {
134311
+ function buildCiWorkflowLines(installUrl, postmanRegion, privateMockAuth) {
134311
134312
  return [
134312
134313
  "name: CI/CD Pipeline",
134313
134314
  "on:",
@@ -134374,6 +134375,7 @@ function buildCiWorkflowLines(installUrl, postmanRegion) {
134374
134375
  ' -e "$POSTMAN_ENVIRONMENT_UID"',
134375
134376
  " --report-events",
134376
134377
  ` --env-var "CI_ENVIRONMENT=\${{ vars.CI_ENVIRONMENT || 'Production' }}")`,
134378
+ ...privateMockAuth ? [' CMD+=(--env-var "' + PRIVATE_MOCK_AUTH_VARIABLE + '=${{ secrets.POSTMAN_API_KEY }}")'] : [],
134377
134379
  ' if [ -f "$RUNNER_TEMP/postman-ssl/client.crt" ]; then',
134378
134380
  ' CMD+=(--ssl-client-cert "$RUNNER_TEMP/postman-ssl/client.crt"',
134379
134381
  ' --ssl-client-key "$RUNNER_TEMP/postman-ssl/client.key")',
@@ -134393,6 +134395,7 @@ function buildCiWorkflowLines(installUrl, postmanRegion) {
134393
134395
  ' -e "$POSTMAN_ENVIRONMENT_UID"',
134394
134396
  " --report-events",
134395
134397
  ` --env-var "CI_ENVIRONMENT=\${{ vars.CI_ENVIRONMENT || 'Production' }}")`,
134398
+ ...privateMockAuth ? [' CMD+=(--env-var "' + PRIVATE_MOCK_AUTH_VARIABLE + '=${{ secrets.POSTMAN_API_KEY }}")'] : [],
134396
134399
  ' if [ -f "$RUNNER_TEMP/postman-ssl/client.crt" ]; then',
134397
134400
  ' CMD+=(--ssl-client-cert "$RUNNER_TEMP/postman-ssl/client.crt"',
134398
134401
  ' --ssl-client-key "$RUNNER_TEMP/postman-ssl/client.key")',
@@ -134408,7 +134411,7 @@ function buildCiWorkflowLines(installUrl, postmanRegion) {
134408
134411
  ];
134409
134412
  }
134410
134413
  var CI_WORKFLOW_TEMPLATE = renderCiWorkflowTemplate();
134411
- function buildAdoWindowsCollectionRunLines(displayName, collectionEnvironmentName) {
134414
+ function buildAdoWindowsCollectionRunLines(displayName, collectionEnvironmentName, privateMockAuth) {
134412
134415
  return [
134413
134416
  " - pwsh: |",
134414
134417
  " $ErrorActionPreference = 'Stop'",
@@ -134420,6 +134423,7 @@ function buildAdoWindowsCollectionRunLines(displayName, collectionEnvironmentNam
134420
134423
  " $ciEnvironment = Resolve-AdoOptional $env:CI_ENVIRONMENT",
134421
134424
  " if ([string]::IsNullOrWhiteSpace($ciEnvironment)) { $ciEnvironment = 'Production' }",
134422
134425
  ` $arguments = @('collection', 'run', $collectionUid, '-e', $env:POSTMAN_ENVIRONMENT_UID, '--report-events', '--env-var', "CI_ENVIRONMENT=$ciEnvironment")`,
134426
+ ...privateMockAuth ? [` $arguments += @('--env-var', "${PRIVATE_MOCK_AUTH_VARIABLE}=$env:POSTMAN_API_KEY")`] : [],
134423
134427
  " $sslRoot = Join-Path $env:AGENT_TEMPDIRECTORY 'postman-ssl'",
134424
134428
  " $clientCert = Join-Path $sslRoot 'client.crt'",
134425
134429
  " $clientKey = Join-Path $sslRoot 'client.key'",
@@ -134441,10 +134445,11 @@ function buildAdoWindowsCollectionRunLines(displayName, collectionEnvironmentNam
134441
134445
  ` ${collectionEnvironmentName}: $(${collectionEnvironmentName})`,
134442
134446
  " POSTMAN_ENVIRONMENT_UID: $(POSTMAN_ENVIRONMENT_UID)",
134443
134447
  " CI_ENVIRONMENT: $(CI_ENVIRONMENT)",
134444
- " POSTMAN_SSL_CLIENT_PASSPHRASE: $(POSTMAN_SSL_CLIENT_PASSPHRASE)"
134448
+ " POSTMAN_SSL_CLIENT_PASSPHRASE: $(POSTMAN_SSL_CLIENT_PASSPHRASE)",
134449
+ ...privateMockAuth ? [" POSTMAN_API_KEY: $(POSTMAN_API_KEY)"] : []
134445
134450
  ];
134446
134451
  }
134447
- function buildAdoWindowsCiWorkflowLines(installUrl, postmanRegion) {
134452
+ function buildAdoWindowsCiWorkflowLines(installUrl, postmanRegion, privateMockAuth) {
134448
134453
  return [
134449
134454
  "trigger:",
134450
134455
  " branches:",
@@ -134529,12 +134534,12 @@ function buildAdoWindowsCiWorkflowLines(installUrl, postmanRegion) {
134529
134534
  " POSTMAN_SSL_CLIENT_CERT_B64: $(POSTMAN_SSL_CLIENT_CERT_B64)",
134530
134535
  " POSTMAN_SSL_CLIENT_KEY_B64: $(POSTMAN_SSL_CLIENT_KEY_B64)",
134531
134536
  " POSTMAN_SSL_EXTRA_CA_CERTS_B64: $(POSTMAN_SSL_EXTRA_CA_CERTS_B64)",
134532
- ...buildAdoWindowsCollectionRunLines("Run Smoke Tests", "POSTMAN_SMOKE_COLLECTION_UID"),
134533
- ...buildAdoWindowsCollectionRunLines("Run Contract Tests", "POSTMAN_CONTRACT_COLLECTION_UID"),
134537
+ ...buildAdoWindowsCollectionRunLines("Run Smoke Tests", "POSTMAN_SMOKE_COLLECTION_UID", privateMockAuth),
134538
+ ...buildAdoWindowsCollectionRunLines("Run Contract Tests", "POSTMAN_CONTRACT_COLLECTION_UID", privateMockAuth),
134534
134539
  ""
134535
134540
  ];
134536
134541
  }
134537
- function buildAdoCiWorkflowLines(installUrl, postmanRegion) {
134542
+ function buildAdoCiWorkflowLines(installUrl, postmanRegion, privateMockAuth) {
134538
134543
  return [
134539
134544
  "trigger:",
134540
134545
  " branches:",
@@ -134611,6 +134616,7 @@ function buildAdoCiWorkflowLines(installUrl, postmanRegion) {
134611
134616
  ' -e "$POSTMAN_ENVIRONMENT_UID"',
134612
134617
  " --report-events",
134613
134618
  ' --env-var "CI_ENVIRONMENT=${CI_ENVIRONMENT:-Production}")',
134619
+ ...privateMockAuth ? [' CMD+=(--env-var "' + PRIVATE_MOCK_AUTH_VARIABLE + '=$POSTMAN_API_KEY")'] : [],
134614
134620
  ' if [ -f "$(Agent.TempDirectory)/postman-ssl/client.crt" ]; then',
134615
134621
  ' CMD+=(--ssl-client-cert "$(Agent.TempDirectory)/postman-ssl/client.crt"',
134616
134622
  ' --ssl-client-key "$(Agent.TempDirectory)/postman-ssl/client.key")',
@@ -134626,6 +134632,7 @@ function buildAdoCiWorkflowLines(installUrl, postmanRegion) {
134626
134632
  " env:",
134627
134633
  " CI_ENVIRONMENT: $(CI_ENVIRONMENT)",
134628
134634
  " POSTMAN_SSL_CLIENT_PASSPHRASE: $(POSTMAN_SSL_CLIENT_PASSPHRASE)",
134635
+ ...privateMockAuth ? [" POSTMAN_API_KEY: $(POSTMAN_API_KEY)"] : [],
134629
134636
  " - script: |",
134630
134637
  " normalize_azure_optional_var() {",
134631
134638
  ' local name="$1"',
@@ -134642,6 +134649,7 @@ function buildAdoCiWorkflowLines(installUrl, postmanRegion) {
134642
134649
  ' -e "$POSTMAN_ENVIRONMENT_UID"',
134643
134650
  " --report-events",
134644
134651
  ' --env-var "CI_ENVIRONMENT=${CI_ENVIRONMENT:-Production}")',
134652
+ ...privateMockAuth ? [' CMD+=(--env-var "' + PRIVATE_MOCK_AUTH_VARIABLE + '=$POSTMAN_API_KEY")'] : [],
134645
134653
  ' if [ -f "$(Agent.TempDirectory)/postman-ssl/client.crt" ]; then',
134646
134654
  ' CMD+=(--ssl-client-cert "$(Agent.TempDirectory)/postman-ssl/client.crt"',
134647
134655
  ' --ssl-client-key "$(Agent.TempDirectory)/postman-ssl/client.key")',
@@ -134657,6 +134665,7 @@ function buildAdoCiWorkflowLines(installUrl, postmanRegion) {
134657
134665
  " env:",
134658
134666
  " CI_ENVIRONMENT: $(CI_ENVIRONMENT)",
134659
134667
  " POSTMAN_SSL_CLIENT_PASSPHRASE: $(POSTMAN_SSL_CLIENT_PASSPHRASE)",
134668
+ ...privateMockAuth ? [" POSTMAN_API_KEY: $(POSTMAN_API_KEY)"] : [],
134660
134669
  ""
134661
134670
  ];
134662
134671
  }
@@ -134718,7 +134727,8 @@ function getCiWorkflowTemplate(provider, options = {}) {
134718
134727
  const rawUrl = runnerOs === "windows" ? String(options.postmanCliWindowsInstallUrl || "").trim() || DEFAULT_POSTMAN_CLI_WINDOWS_INSTALL_URL : String(options.postmanCliInstallUrl || "").trim() || DEFAULT_POSTMAN_CLI_INSTALL_URL;
134719
134728
  const postmanRegion = resolvePostmanRegion(options.postmanRegion);
134720
134729
  const installUrl = validateHttpsInstallUrl(rawUrl);
134721
- return (runnerOs === "windows" ? buildAdoWindowsCiWorkflowLines(installUrl, postmanRegion) : buildAdoCiWorkflowLines(installUrl, postmanRegion)).join("\n");
134730
+ const privateMockAuth = options.privateMockAuth === true;
134731
+ return (runnerOs === "windows" ? buildAdoWindowsCiWorkflowLines(installUrl, postmanRegion, privateMockAuth) : buildAdoCiWorkflowLines(installUrl, postmanRegion, privateMockAuth)).join("\n");
134722
134732
  }
134723
134733
  return renderCiWorkflowTemplate(options);
134724
134734
  }
@@ -137006,16 +137016,39 @@ function requireMockVisibility(mock, requested) {
137006
137016
  }
137007
137017
  return mock;
137008
137018
  }
137009
- var PRIVATE_MOCK_AUTH_MARKER = "postman-enterprise-automation: private-mock-auth";
137010
- var PRIVATE_MOCK_AUTH_VARIABLE = "postmanPrivateMockApiKey";
137019
+ var PRIVATE_MOCK_AUTH_MARKER_PREFIX = "postman-enterprise-automation: private-mock-auth";
137020
+ var PRIVATE_MOCK_AUTH_MARKER = `${PRIVATE_MOCK_AUTH_MARKER_PREFIX}-v2`;
137021
+ var PRIVATE_MOCK_AUTH_VARIABLE2 = "postmanPrivateMockApiKey";
137011
137022
  var PRIVATE_MOCK_AUTH_SCRIPT = [
137012
137023
  `// ${PRIVATE_MOCK_AUTH_MARKER}`,
137013
- `var privateMockApiKey = pm.variables.get('${PRIVATE_MOCK_AUTH_VARIABLE}');`,
137014
- "var privateMockHost = String(pm.request.url && pm.request.url.getHost ? pm.request.url.getHost() : '');",
137015
- "if (privateMockApiKey && /(^|\\.)mock\\.pstmn\\.io$/i.test(privateMockHost)) {",
137024
+ `var privateMockApiKey = pm.variables.get('${PRIVATE_MOCK_AUTH_VARIABLE2}');`,
137025
+ "var privateMockHostValue = pm.request.url && pm.request.url.getHost ? pm.request.url.getHost() : '';",
137026
+ "var privateMockHost = Array.isArray(privateMockHostValue) ? privateMockHostValue.join('.') : String(privateMockHostValue);",
137027
+ "var isPrivateMockHost = /(^|\\.)mock\\.pstmn\\.io$/i.test(privateMockHost);",
137028
+ "if (isPrivateMockHost && privateMockApiKey) {",
137016
137029
  " pm.request.headers.upsert({ key: 'x-api-key', value: privateMockApiKey });",
137030
+ "} else if (isPrivateMockHost) {",
137031
+ ` console.warn('This mock server is private. Set the ${PRIVATE_MOCK_AUTH_VARIABLE2} variable to a Postman API key with access to it, or the request returns 401.');`,
137017
137032
  "}"
137018
137033
  ].join("\n");
137034
+ function stripPrivateMockAuthBlocks(code) {
137035
+ if (!code.includes(PRIVATE_MOCK_AUTH_MARKER_PREFIX)) return code.trim();
137036
+ const lines = code.split("\n");
137037
+ const kept = [];
137038
+ let skipping = false;
137039
+ for (const line of lines) {
137040
+ if (line.includes(PRIVATE_MOCK_AUTH_MARKER_PREFIX)) {
137041
+ skipping = true;
137042
+ continue;
137043
+ }
137044
+ if (skipping) {
137045
+ if (/^\s*(?:(?:var|if)\s|\}\selse\sif\s|\}|pm\.request|console\.warn)/.test(line)) continue;
137046
+ skipping = false;
137047
+ }
137048
+ kept.push(line);
137049
+ }
137050
+ return kept.join("\n").trim();
137051
+ }
137019
137052
  var MAX_CREATE_FLIGHTS = 256;
137020
137053
  var createFlights = /* @__PURE__ */ new Map();
137021
137054
  var PostmanGatewayAssetsClient = class {
@@ -137613,8 +137646,9 @@ var PostmanGatewayAssetsClient = class {
137613
137646
  const item = this.asRecord(response?.data) ?? listedItem;
137614
137647
  const scripts = Array.isArray(item.scripts) ? item.scripts.filter((entry) => Boolean(this.asRecord(entry))) : [];
137615
137648
  const before = scripts.find((script) => String(script.type ?? "") === "beforeRequest");
137616
- if (String(before?.code ?? "").includes(PRIVATE_MOCK_AUTH_MARKER)) continue;
137617
- const code = [String(before?.code ?? "").trim(), PRIVATE_MOCK_AUTH_SCRIPT].filter(Boolean).join("\n");
137649
+ const existingCode = String(before?.code ?? "");
137650
+ if (existingCode.includes(PRIVATE_MOCK_AUTH_MARKER)) continue;
137651
+ const code = [stripPrivateMockAuthBlocks(existingCode), PRIVATE_MOCK_AUTH_SCRIPT].filter(Boolean).join("\n");
137618
137652
  const nextScripts = [
137619
137653
  ...scripts.filter((script) => String(script.type ?? "") !== "beforeRequest"),
137620
137654
  { type: "beforeRequest", code, language: "text/javascript" }
@@ -138950,9 +138984,13 @@ function assertBranchAssetIds(inputs, decision, branchOwnedIds = process.env.POS
138950
138984
  );
138951
138985
  }
138952
138986
  }
138953
- function buildEnvironmentValues(envName, baseUrl) {
138987
+ function buildEnvironmentValues(envName, baseUrl, options = {}) {
138954
138988
  return [
138955
138989
  { key: "baseUrl", value: baseUrl, type: "default" },
138990
+ // A private mock refuses anonymous calls, so the manual-validation environment
138991
+ // carries a named, empty, secret-typed slot for the caller's own key. Repo-sync
138992
+ // never writes a value here; the developer pastes one in the Postman app.
138993
+ ...options.privateMockAuth ? [{ key: PRIVATE_MOCK_AUTH_VARIABLE2, value: "", type: "secret" }] : [],
138956
138994
  { key: "CI", value: "false", type: "default" },
138957
138995
  { key: "RESPONSE_TIME_THRESHOLD", value: "2000", type: "default" },
138958
138996
  { key: "AWS_ACCESS_KEY_ID", value: "", type: "secret" },
@@ -139399,12 +139437,12 @@ async function upsertEnvironments(inputs, dependencies, resourcesState, assetMar
139399
139437
  }
139400
139438
  return envUids;
139401
139439
  }
139402
- async function upsertMockEnvironment(inputs, dependencies, assetProjectName, mockUrl) {
139440
+ async function upsertMockEnvironment(inputs, dependencies, assetProjectName, mockUrl, privateMockAuth) {
139403
139441
  if (!inputs.mockEnvironmentEnabled || !inputs.workspaceId || !mockUrl) {
139404
139442
  return "";
139405
139443
  }
139406
139444
  const displayName = `${assetProjectName} - Mock`;
139407
- const values = buildEnvironmentValues("mock", mockUrl);
139445
+ const values = buildEnvironmentValues("mock", mockUrl, { privateMockAuth });
139408
139446
  const mask = resolveRepoSyncMasker(dependencies);
139409
139447
  try {
139410
139448
  const discovered = await dependencies.postman.findEnvironmentByName(
@@ -140133,14 +140171,16 @@ function renderCiWorkflow(inputs) {
140133
140171
  postmanCliInstallUrl: inputs.postmanCliInstallUrl,
140134
140172
  postmanCliWindowsInstallUrl: inputs.postmanCliWindowsInstallUrl,
140135
140173
  runnerOs: inputs.ciRunnerOs,
140136
- postmanRegion: inputs.postmanRegion
140174
+ postmanRegion: inputs.postmanRegion,
140175
+ privateMockAuth: inputs.mockVisibility === "private"
140137
140176
  });
140138
140177
  }
140139
140178
  return renderCiWorkflowTemplate({
140140
140179
  postmanCliInstallUrl: inputs.postmanCliInstallUrl,
140141
140180
  postmanCliWindowsInstallUrl: inputs.postmanCliWindowsInstallUrl,
140142
140181
  runnerOs: inputs.ciRunnerOs,
140143
- postmanRegion: inputs.postmanRegion
140182
+ postmanRegion: inputs.postmanRegion,
140183
+ privateMockAuth: inputs.mockVisibility === "private"
140144
140184
  });
140145
140185
  }
140146
140186
  function createRepoSummary(outputs, envUids, pushed) {
@@ -140495,18 +140535,26 @@ async function runRepoSyncInner(inputs, dependencies) {
140495
140535
  "PRIVATE_MOCK_RUNTIME_AUTH_UNAVAILABLE: The Postman client cannot configure runtime x-api-key injection."
140496
140536
  );
140497
140537
  }
140538
+ const configured = [];
140498
140539
  for (const collectionUid of [inputs.smokeCollectionId, inputs.contractCollectionId]) {
140499
140540
  if (collectionUid) {
140500
140541
  await dependencies.postman.configurePrivateMockRuntimeAuth(collectionUid);
140542
+ configured.push(collectionUid);
140501
140543
  }
140502
140544
  }
140545
+ if (configured.length > 0) {
140546
+ (dependencies.core.notice ?? dependencies.core.info)(
140547
+ `Private mock: installed a request hook on ${configured.length} collection(s) that sends the ${PRIVATE_MOCK_AUTH_VARIABLE2} variable as x-api-key, and only to *.mock.pstmn.io hosts. The generated CI workflow supplies it from the POSTMAN_API_KEY secret. For manual runs in the Postman app, set that variable to a key with access to the mock. No key is stored in the collection, environment, outputs, or repository.`
140548
+ );
140549
+ }
140503
140550
  }
140504
140551
  if (inputs.mockEnvironmentEnabled && isCanonicalWriter) {
140505
140552
  const mockEnvironmentUid = await upsertMockEnvironment(
140506
140553
  inputs,
140507
140554
  dependencies,
140508
140555
  assetProjectName,
140509
- resolvedMockUrl
140556
+ resolvedMockUrl,
140557
+ resolvedMockVisibility === "private"
140510
140558
  );
140511
140559
  outputs["mock-environment-uid"] = mockEnvironmentUid;
140512
140560
  outputs["mock-environment-status"] = mockEnvironmentUid ? "success" : "failed";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@postman-cse/onboarding-repo-sync",
3
- "version": "2.3.1",
3
+ "version": "2.4.0",
4
4
  "description": "Postman repo sync GitHub Action.",
5
5
  "type": "module",
6
6
  "main": "dist/index.cjs",