CodeSampleX

Sample

electron-publish 26.15.3

Verified sample for npm electron-publish 26.15.3. The contract ran on node 22 · linux alpine/x64 · docker and passed: Publisher abstract base class manages…

sha256:d427852990771ad77b22784baf1729045f0d7f55b38fa0875a8779507be79561

This network offers one thing: a sample that builds. It ran the sample in a sandbox and kept the signed receipt. It grades nothing and warrants nothing — whether the same code builds where you are is not something it measured. How many distinct signing keys filed a passing contract receipt. One is the author alone; more than one means somebody else built it too. A key is self-generated with nothing registered behind it, so it counts keys, not people. MIT-0

Execution evidence

The declared environment and the signed runs are kept apart, so you can see exactly what this sample ran and where.

Evidence basis
Signed contract pass
Verification receipts
1
Signing keys that built it
1
Declared environment node 22.23 linux 24 · ubuntu · glibc 2.39 x64 node 22.23 javascript npm 10

Verification-run environments

Environment Contract Stages Run
node 22 · linux alpine/x64 · docker ed25519:c1973797be207ac4 PASS compile:SKIPPED · contract:PASS · load:PASS · resolve:PASS
CONTAINER_RUN · node-typescript@1node:22-alpine@sha256:c610fcdfb1d5…
2026-08-26

Case

HOW
Goal
verify pkg:npm/electron-publish@26.15.3
Packages
Environment
node 22.23.2
Created
2026-08-26T08:43:47Z

Contract

  1. Publisher abstract base class manages publish context and coordinates progress bar creation above minimum upload size thresholds.
  2. HttpPublisher extends Publisher to handle upload tasks for in-memory buffers and streaming files with configurable safe artifact names.
  3. ProgressBar tracks tick counts, renders formatted progress templates, and marks completion upon reaching total units.
  4. ProgressCallback throttles intermediate progress updates and synchronizes completed progress states with ProgressBar.
  5. MultiProgress coordinates and terminates multiple concurrently managed progress bars across terminal streams.
  6. getCiTag detects active continuous integration release tag names from standard CI environment variables or returns null.
  7. resolveSnapCredentials parses snapcraft credential links or returns an empty credentials object when none are supplied.
  8. Exports provide publisher implementations for SnapStore, GitHub, GitLab, Bitbucket, Keygen, S3, and Spaces.

Files

  • PROMPT.md
  • csx.json
  • package-lock.json
  • package.json
  • spec.json
  • src/index.js
  • test/contract.mjs

Download the source artifact (tar.gz)

Source

PROMPT.md
Clean-room public code sample — generation instructions

Write a brand-new, minimal, self-contained code sample in this clean-room directory.
Do not copy, paraphrase, or reference any existing project source. Work only from this spec.

A csx.json manifest scaffold already exists. Do not recreate it from memory. Preserve its case.goal, packages and symbols; fill its empty case.contract with exact assertions and correct its environment, commands and verifierAdapter for the files you generate.

Goal: verify pkg:npm/electron-publish@26.15.3
Kind: HOW

Use EXACTLY these public packages and versions:
  - pkg:npm/electron-publish@26.15.3
Constraints:
  - executionContext: node
Required runtime conditions:
  - ecosystem: npm
  - language: javascript
  - moduleSystem: cjs
  - packageManager: npm@10.9.8
  - runtime: node@22.23.2

Rules:
  - One focused purpose; the smallest project that proves the goal.
  - Include a contract test (test/contract.*) that runs OFFLINE and exits 0 exactly when the goal behavior works.
  - Pin every dependency with a lockfile so resolution is reproducible.
  - No secrets, credentials, or tokens. No real URLs (only example.com or localhost). No absolute paths.
  - No personal names, emails, company names, or project identifiers of any kind.
  - No binaries and no generated output (node_modules, dist, target, venv, .git, .env).
  - Keep it under 200 files and 256KB packed.
csx.json
{"case":{"caseId":"case:sha256:e965edb76518787cc705c7d333c0fc0280f9314844ef14010def91a8a8fb7a06","constraints":{"executionContext":"node"},"contract":["Publisher abstract base class manages publish context and coordinates progress bar creation above minimum upload size thresholds.","HttpPublisher extends Publisher to handle upload tasks for in-memory buffers and streaming files with configurable safe artifact names.","ProgressBar tracks tick counts, renders formatted progress templates, and marks completion upon reaching total units.","ProgressCallback throttles intermediate progress updates and synchronizes completed progress states with ProgressBar.","MultiProgress coordinates and terminates multiple concurrently managed progress bars across terminal streams.","getCiTag detects active continuous integration release tag names from standard CI environment variables or returns null.","resolveSnapCredentials parses snapcraft credential links or returns an empty credentials object when none are supplied.","Exports provide publisher implementations for SnapStore, GitHub, GitLab, Bitbucket, Keygen, S3, and Spaces."],"goal":"verify pkg:npm/electron-publish@26.15.3","kind":"HOW","packages":["pkg:npm/electron-publish@26.15.3"],"schemaVersion":1},"contractCommand":["node","test/contract.mjs"],"environment":{"arch":"x64","distro":"ubuntu","ecosystem":"npm","executionContext":"node","language":"javascript","libc":"glibc","libcVersion":"2.39","moduleSystem":"cjs","os":"linux","osVersionBucket":"24","packageManager":"npm","packageManagerVersion":"10.9.8","runtime":"node","runtimeVersion":"22.23.2","schemaVersion":1},"license":"MIT-0","packages":["pkg:npm/electron-publish@26.15.3"],"schemaVersion":1,"subject":"pkg:npm/electron-publish@26.15.3","verifierAdapter":"node-typescript@1"}
package-lock.json
{
  "name": "sample-electron-publish",
  "version": "1.0.0",
  "lockfileVersion": 3,
  "requires": true,
  "packages": {
    "": {
      "name": "sample-electron-publish",
      "version": "1.0.0",
      "license": "MIT-0",
      "dependencies": {
        "electron-publish": "26.15.3"
      }
    },
    "node_modules/@types/debug": {
      "version": "4.1.13",
      "resolved": "https://registry.npmjs.org/@types/debug/-/debug-4.1.13.tgz",
      "integrity": "sha512-KSVgmQmzMwPlmtljOomayoR89W4FynCAi3E8PPs7vmDVPe84hT+vGPKkJfThkmXs0x0jAaa9U8uW8bbfyS2fWw==",
      "license": "MIT",
      "dependencies": {
        "@types/ms": "*"
      }
    },
    "node_modules/@types/fs-extra": {
      "version": "9.0.13",
      "resolved": "https://registry.npmjs.org/@types/fs-extra/-/fs-extra-9.0.13.tgz",
      "integrity": "sha512-nEnwB++1u5lVDM2UI4c1+5R+FYaKfaAzS4OococimjVm3nQw3TuzH5UNsocrcTBbhnerblyHj4A49qXbIiZdpA==",
      "license": "MIT",
      "dependencies": {
        "@types/node": "*"
      }
    },
    "node_modules/@types/ms": {
      "version": "2.1.0",
      "resolved": "https://registry.npmjs.org/@types/ms/-/ms-2.1.0.tgz",
      "integrity": "sha512-GsCCIZDE/p3i96vtEqx+7dBUGXrc7zeSK3wwPHIaRThS+9OhWIXRqzs4d6k1SVU8g91DrNRWxWUGhp5KXQb2VA==",
      "license": "MIT"
    },
    "node_modules/@types/node": {
      "version": "26.3.0",
      "resolved": "https://registry.npmjs.org/@types/node/-/node-26.3.0.tgz",
      "integrity": "sha512-L3fgrnchriRC2ExBflb8j4uZZURHZfQsmQeyVzhjcHW4kkwVyo8/0h1B2MVzMTrYUJYu6G7EWs14hW/L9putqw==",
      "license": "MIT",
      "dependencies": {
        "undici-types": "~8.3.0"
      }
    },
    "node_modules/agent-base": {
      "version": "7.1.4",
      "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.4.tgz",
      "integrity": "sha512-MnA+YT8fwfJPgBx3m60MNqakm30XOkyIoH1y6huTQvC0PwZG7ki8NacLBcrPbNoo8vEZy7Jpuk7+jMO+CUovTQ==",
      "license": "MIT",
      "engines": {
        "node": ">= 14"
      }
    },
    "node_modules/ansi-styles": {
      "version": "4.3.0",
      "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
      "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
      "license": "MIT",
      "dependencies": {
        "color-convert": "^2.0.1"
      },
      "engines": {
        "node": ">=8"
      },
      "funding": {
        "url": "https://github.com/chalk/ansi-styles?sponsor=1"
      }
    },
    "node_modules/argparse": {
      "version": "2.0.1",
      "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz",
      "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==",
      "license": "Python-2.0"
    },
    "node_modules/async-exit-hook": {
      "version": "2.0.1",
      "resolved": "https://registry.npmjs.org/async-exit-hook/-/async-exit-hook-2.0.1.tgz",
      "integrity": "sha512-NW2cX8m1Q7KPA7a5M2ULQeZ2wR5qI5PAbw5L0UOMxdioVk9PMZ0h1TmyZEkPYrCvYjDlFICusOu1dlEKAAeXBw==",
      "license": "MIT",
      "engines": {
        "node": ">=0.12.0"
      }
    },
    "node_modules/asynckit": {
      "version": "0.4.0",
      "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
      "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==",
      "license": "MIT"
    },
    "node_modules/aws4": {
      "version": "1.13.2",
      "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.13.2.tgz",
      "integrity": "sha512-lHe62zvbTB5eEABUVi/AwVh0ZKY9rMMDhmm+eeyuuUQbQ3+J+fONVQOZyj+DdrvD4BY33uYniyRJ4UJIaSKAfw==",
      "license": "MIT"
    },
    "node_modules/buffer-from": {
      "version": "1.1.2",
      "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz",
      "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==",
      "license": "MIT"
    },
    "node_modules/builder-util": {
      "version": "26.15.3",
      "resolved": "https://registry.npmjs.org/builder-util/-/builder-util-26.15.3.tgz",
      "integrity": "sha512-q2hn7Mbo2nFNkVekPiHFx6Nfo3hURmES3tfBn+k5Pqxl2RkmP3QGqZUhH/q9Pch/4G05NRhPjDlVj1O8q4Txvw==",
      "license": "MIT",
      "dependencies": {
        "@types/debug": "^4.1.6",
        "builder-util-runtime": "9.7.0",
        "chalk": "^4.1.2",
        "cross-spawn": "^7.0.6",
        "debug": "^4.3.4",
        "fs-extra": "^10.1.0",
        "http-proxy-agent": "^7.0.0",
        "https-proxy-agent": "^7.0.0",
        "js-yaml": "^4.1.0",
        "sanitize-filename": "^1.6.3",
        "source-map-support": "^0.5.19",
        "stat-mode": "^1.0.0",
        "temp-file": "^3.4.0",
        "tiny-async-pool": "1.3.0"
      },
      "engines": {
        "node": ">=14.0.0"
      }
    },
    "node_modules/builder-util-runtime": {
      "version": "9.7.0",
      "resolved": "https://registry.npmjs.org/builder-util-runtime/-/builder-util-runtime-9.7.0.tgz",
      "integrity": "sha512-g/kR520giAFYkSXTzcmF3kqQq7wi8F6N6SzeDgZrqTBN+VHdmgWOyTdD1yD7AATDId/yXLvuP34CxW46/BwCdw==",
      "license": "MIT",
      "dependencies": {
        "debug": "^4.3.4",
        "sax": "^1.2.4"
      },
      "engines": {
        "node": ">=12.0.0"
      }
    },
    "node_modules/call-bind-apply-helpers": {
      "version": "1.0.2",
      "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz",
      "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==",
      "license": "MIT",
      "dependencies": {
        "es-errors": "^1.3.0",
        "function-bind": "^1.1.2"
      },
      "engines": {
        "node": ">= 0.4"
      }
    },
    "node_modules/chalk": {
      "version": "4.1.2",
      "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
      "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
      "license": "MIT",
      "dependencies": {
        "ansi-styles": "^4.1.0",
        "supports-color": "^7.1.0"
      },
      "engines": {
        "node": ">=10"
      },
      "funding": {
        "url": "https://github.com/chalk/chalk?sponsor=1"
      }
    },
    "node_modules/color-convert": {
      "version": "2.0.1",
      "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
      "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
      "license": "MIT",
      "dependencies": {
        "color-name": "~1.1.4"
      },
      "engines": {
        "node": ">=7.0.0"
      }
    },
    "node_modules/color-name": {
      "version": "1.1.4",
      "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
      "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
      "license": "MIT"
    },
    "node_modules/combined-stream": {
      "version": "1.0.8",
      "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz",
      "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==",
      "license": "MIT",
      "dependencies": {
        "delayed-stream": "~1.0.0"
      },
      "engines": {
        "node": ">= 0.8"
      }
    },
    "node_modules/cross-spawn": {
      "version": "7.0.6",
      "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz",
      "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==",
      "license": "MIT",
      "dependencies": {
        "path-key": "^3.1.0",
        "shebang-command": "^2.0.0",
        "which": "^2.0.1"
      },
      "engines": {
        "node": ">= 8"
      }
    },
    "node_modules/debug": {
      "version": "4.4.3",
      "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz",
      "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==",
      "license": "MIT",
      "dependencies": {
        "ms": "^2.1.3"
      },
      "engines": {
        "node": ">=6.0"
      },
      "peerDependenciesMeta": {
        "supports-color": {
          "optional": true
        }
      }
    },
    "node_modules/delayed-stream": {
      "version": "1.0.0",
      "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
      "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==",
      "license": "MIT",
      "engines": {
        "node": ">=0.4.0"
      }
    },
    "node_modules/dunder-proto": {
      "version": "1.0.1",
      "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz",
      "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==",
      "license": "MIT",
      "dependencies": {
        "call-bind-apply-helpers": "^1.0.1",
        "es-errors": "^1.3.0",
        "gopd": "^1.2.0"
      },
      "engines": {
        "node": ">= 0.4"
      }
    },
    "node_modules/electron-publish": {
      "version": "26.15.3",
      "resolved": "https://registry.npmjs.org/electron-publish/-/electron-publish-26.15.3.tgz",
      "integrity": "sha512-g/2bn8YTavY4cuS5F+jOS7zmZbXXBV8KZ8yHKfJjFPoKtzBqrpCdNPxBd3tqdBwP7BVd0lGzf7Bk2s0KesWZ4Q==",
      "license": "MIT",
      "dependencies": {
        "@types/fs-extra": "^9.0.11",
        "aws4": "^1.13.2",
        "builder-util": "26.15.3",
        "builder-util-runtime": "9.7.0",
        "chalk": "^4.1.2",
        "form-data": "^4.0.5",
        "fs-extra": "^10.1.0",
        "lazy-val": "^1.0.5",
        "mime": "^2.5.2"
      }
    },
    "node_modules/es-define-property": {
      "version": "1.0.1",
      "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz",
      "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==",
      "license": "MIT",
      "engines": {
        "node": ">= 0.4"
      }
    },
    "node_modules/es-errors": {
      "version": "1.3.0",
      "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz",
      "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==",
      "license": "MIT",
      "engines": {
        "node": ">= 0.4"
      }
    },
    "node_modules/es-object-atoms": {
      "version": "1.1.2",
      "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.2.tgz",
      "integrity": "sha512-HWcBoN6NileqtSydK2FqHbS/LoDd2pqrnQHLyJzBj4kOp/ky2MWMN694xOfkK8/SnUsW2DH7EfyVlydKCsm1Zw==",
      "license": "MIT",
      "dependencies": {
        "es-errors": "^1.3.0"
      },
      "engines": {
        "node": ">= 0.4"
      }
    },
    "node_modules/es-set-tostringtag": {
      "version": "2.1.0",
      "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.1.0.tgz",
      "integrity": "sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==",
      "license": "MIT",
      "dependencies": {
        "es-errors": "^1.3.0",
        "get-intrinsic": "^1.2.6",
        "has-tostringtag": "^1.0.2",
        "hasown": "^2.0.2"
      },
      "engines": {
        "node": ">= 0.4"
      }
    },
    "node_modules/form-data": {
      "version": "4.0.6",
      "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.6.tgz",
      "integrity": "sha512-vKatAh4SlVfgbv+YtmhiRjhEMJsYpsG1Y2rMQtR+SVSbytsSD1YGzDIcrAJmdFec88u/+VoGmxnl+80gL1tRCQ==",
      "license": "MIT",
      "dependencies": {
        "asynckit": "^0.4.0",
        "combined-stream": "^1.0.8",
        "es-set-tostringtag": "^2.1.0",
        "hasown": "^2.0.4",
        "mime-types": "^2.1.35"
      },
      "engines": {
        "node": ">= 6"
      }
    },
    "node_modules/fs-extra": {
      "version": "10.1.0",
      "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz",
      "integrity": "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==",
      "license": "MIT",
      "dependencies": {
        "graceful-fs": "^4.2.0",
        "jsonfile": "^6.0.1",
        "universalify": "^2.0.0"
      },
      "engines": {
        "node": ">=12"
      }
    },
    "node_modules/function-bind": {
      "version": "1.1.2",
      "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz",
      "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==",
      "license": "MIT",
      "funding": {
        "url": "https://github.com/sponsors/ljharb"
      }
    },
    "node_modules/get-intrinsic": {
      "version": "1.3.0",
      "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz",
      "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==",
      "license": "MIT",
      "dependencies": {
        "call-bind-apply-helpers": "^1.0.2",
        "es-define-property": "^1.0.1",
        "es-errors": "^1.3.0",
        "es-object-atoms": "^1.1.1",
        "function-bind": "^1.1.2",
        "get-proto": "^1.0.1",
        "gopd": "^1.2.0",
        "has-symbols": "^1.1.0",
        "hasown": "^2.0.2",
        "math-intrinsics": "^1.1.0"
      },
      "engines": {
        "node": ">= 0.4"
      },
      "funding": {
        "url": "https://github.com/sponsors/ljharb"
      }
    },
    "node_modules/get-proto": {
      "version": "1.0.1",
      "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz",
      "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==",
      "license": "MIT",
      "dependencies": {
        "dunder-proto": "^1.0.1",
        "es-object-atoms": "^1.0.0"
      },
      "engines": {
        "node": ">= 0.4"
      }
    },
    "node_modules/gopd": {
      "version": "1.2.0",
      "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz",
      "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==",
      "license": "MIT",
      "engines": {
        "node": ">= 0.4"
      },
      "funding": {
        "url": "https://github.com/sponsors/ljharb"
      }
    },
    "node_modules/graceful-fs": {
      "version": "4.2.11",
      "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz",
      "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==",
      "license": "ISC"
    },
    "node_modules/has-flag": {
      "version": "4.0.0",
      "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
      "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
      "license": "MIT",
      "engines": {
        "node": ">=8"
      }
    },
    "node_modules/has-symbols": {
      "version": "1.1.0",
      "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz",
      "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==",
      "license": "MIT",
      "engines": {
        "node": ">= 0.4"
      },
      "funding": {
        "url": "https://github.com/sponsors/ljharb"
      }
    },
    "node_modules/has-tostringtag": {
      "version": "1.0.2",
      "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz",
      "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==",
      "license": "MIT",
      "dependencies": {
        "has-symbols": "^1.0.3"
      },
      "engines": {
        "node": ">= 0.4"
      },
      "funding": {
        "url": "https://github.com/sponsors/ljharb"
      }
    },
    "node_modules/hasown": {
      "version": "2.0.4",
      "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.4.tgz",
      "integrity": "sha512-T2UbfbBEF32wiepXIsMlTW9+dDYC6wMh/t/vYA4tuOMKqWz/n3vr1NFSxQiyP+zk2mXsoMA/i/7qV6LKut1t1A==",
      "license": "MIT",
      "dependencies": {
        "function-bind": "^1.1.2"
      },
      "engines": {
        "node": ">= 0.4"
      }
    },
    "node_modules/http-proxy-agent": {
      "version": "7.0.2",
      "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-7.0.2.tgz",
      "integrity": "sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig==",
      "license": "MIT",
      "dependencies": {
        "agent-base": "^7.1.0",
        "debug": "^4.3.4"
      },
      "engines": {
        "node": ">= 14"
      }
    },
    "node_modules/https-proxy-agent": {
      "version": "7.0.6",
      "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.6.tgz",
      "integrity": "sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw==",
      "license": "MIT",
      "dependencies": {
        "agent-base": "^7.1.2",
        "debug": "4"
      },
      "engines": {
        "node": ">= 14"
      }
    },
    "node_modules/isexe": {
      "version": "2.0.0",
      "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
      "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==",
      "license": "ISC"
    },
    "node_modules/js-yaml": {
      "version": "4.3.1",
      "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.3.1.tgz",
      "integrity": "sha512-CY6crGq313MX8GkwvB7tzgp99vjQxY1++5y10/BKN/GUfHqWaOGQMNZkBvqSzsZKWk/ijwHlWzzkLulsGHhjWQ==",
      "funding": [
        {
          "type": "github",
          "url": "https://github.com/sponsors/puzrin"
        },
        {
          "type": "github",
          "url": "https://github.com/sponsors/nodeca"
        }
      ],
      "license": "MIT",
      "dependencies": {
        "argparse": "^2.0.1"
      },
      "bin": {
        "js-yaml": "bin/js-yaml.js"
      }
    },
    "node_modules/jsonfile": {
      "version": "6.2.1",
      "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.2.1.tgz",
      "integrity": "sha512-zwOTdL3rFQ/lRdBnntKVOX6k5cKJwEc1HdilT71BWEu7J41gXIB2MRp+vxduPSwZJPWBxEzv4yH1wYLJGUHX4Q==",
      "license": "MIT",
      "dependencies": {
        "universalify": "^2.0.0"
      },
      "optionalDependencies": {
        "graceful-fs": "^4.1.6"
      }
    },
    "node_modules/lazy-val": {
      "version": "1.0.5",
      "resolved": "https://registry.npmjs.org/lazy-val/-/lazy-val-1.0.5.tgz",
      "integrity": "sha512-0/BnGCCfyUMkBpeDgWihanIAF9JmZhHBgUhEqzvf+adhNGLoP6TaiI5oF8oyb3I45P+PcnrqihSf01M0l0G5+Q==",
      "license": "MIT"
    },
    "node_modules/math-intrinsics": {
      "version": "1.1.0",
      "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz",
      "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==",
      "license": "MIT",
      "engines": {
        "node": ">= 0.4"
      }
    },
    "node_modules/mime": {
      "version": "2.6.0",
      "resolved": "https://registry.npmjs.org/mime/-/mime-2.6.0.tgz",
      "integrity": "sha512-USPkMeET31rOMiarsBNIHZKLGgvKc/LrjofAnBlOttf5ajRvqiRA8QsenbcooctK6d6Ts6aqZXBA+XbkKthiQg==",
      "license": "MIT",
      "bin": {
        "mime": "cli.js"
      },
      "engines": {
        "node": ">=4.0.0"
      }
    },
    "node_modules/mime-db": {
      "version": "1.52.0",
      "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz",
      "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==",
      "license": "MIT",
      "engines": {
        "node": ">= 0.6"
      }
    },
    "node_modules/mime-types": {
      "version": "2.1.35",
      "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz",
      "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==",
      "license": "MIT",
      "dependencies": {
        "mime-db": "1.52.0"
      },
      "engines": {
        "node": ">= 0.6"
      }
    },
    "node_modules/ms": {
      "version": "2.1.3",
      "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
      "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
      "license": "MIT"
    },
    "node_modules/path-key": {
      "version": "3.1.1",
      "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz",
      "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==",
      "license": "MIT",
      "engines": {
        "node": ">=8"
      }
    },
    "node_modules/sanitize-filename": {
      "version": "1.6.4",
      "resolved": "https://registry.npmjs.org/sanitize-filename/-/sanitize-filename-1.6.4.tgz",
      "integrity": "sha512-9ZyI08PsvdQl2r/bBIGubpVdR3RR9sY6RDiWFPreA21C/EFlQhmgo20UZlNjZMMZNubusLhAQozkA0Od5J21Eg==",
      "license": "WTFPL OR ISC",
      "dependencies": {
        "truncate-utf8-bytes": "^1.0.0"
      }
    },
    "node_modules/sax": {
      "version": "1.6.1",
      "resolved": "https://registry.npmjs.org/sax/-/sax-1.6.1.tgz",
      "integrity": "sha512-42tBVwLWnaQvW5zc4HbZrTuWccECCZfBi92FDuwtqxasH+JbPB3/FOKb1m222K42R4WxuxzzMsTswfzgtSu64Q==",
      "license": "BlueOak-1.0.0",
      "engines": {
        "node": ">=11.0.0"
      }
    },
    "node_modules/semver": {
      "version": "5.7.2",
      "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz",
      "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==",
      "license": "ISC",
      "bin": {
        "semver": "bin/semver"
      }
    },
    "node_modules/shebang-command": {
      "version": "2.0.0",
      "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz",
      "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==",
      "license": "MIT",
      "dependencies": {
        "shebang-regex": "^3.0.0"
      },
      "engines": {
        "node": ">=8"
      }
    },
    "node_modules/shebang-regex": {
      "version": "3.0.0",
      "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz",
      "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==",
      "license": "MIT",
      "engines": {
        "node": ">=8"
      }
    },
    "node_modules/source-map": {
      "version": "0.6.1",
      "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
      "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
      "license": "BSD-3-Clause",
      "engines": {
        "node": ">=0.10.0"
      }
    },
    "node_modules/source-map-support": {
      "version": "0.5.21",
      "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz",
      "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==",
      "license": "MIT",
      "dependencies": {
        "buffer-from": "^1.0.0",
        "source-map": "^0.6.0"
      }
    },
    "node_modules/stat-mode": {
      "version": "1.0.0",
      "resolved": "https://registry.npmjs.org/stat-mode/-/stat-mode-1.0.0.tgz",
      "integrity": "sha512-jH9EhtKIjuXZ2cWxmXS8ZP80XyC3iasQxMDV8jzhNJpfDb7VbQLVW4Wvsxz9QZvzV+G4YoSfBUVKDOyxLzi/sg==",
      "license": "MIT",
      "engines": {
        "node": ">= 6"
      }
    },
    "node_modules/supports-color": {
      "version": "7.2.0",
      "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
      "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
      "license": "MIT",
      "dependencies": {
        "has-flag": "^4.0.0"
      },
      "engines": {
        "node": ">=8"
      }
    },
    "node_modules/temp-file": {
      "version": "3.4.0",
      "resolved": "https://registry.npmjs.org/temp-file/-/temp-file-3.4.0.tgz",
      "integrity": "sha512-C5tjlC/HCtVUOi3KWVokd4vHVViOmGjtLwIh4MuzPo/nMYTV/p1urt3RnMz2IWXDdKEGJH3k5+KPxtqRsUYGtg==",
      "license": "MIT",
      "dependencies": {
        "async-exit-hook": "^2.0.1",
        "fs-extra": "^10.0.0"
      }
    },
    "node_modules/tiny-async-pool": {
      "version": "1.3.0",
      "resolved": "https://registry.npmjs.org/tiny-async-pool/-/tiny-async-pool-1.3.0.tgz",
      "integrity": "sha512-01EAw5EDrcVrdgyCLgoSPvqznC0sVxDSVeiOz09FUpjh71G79VCqneOr+xvt7T1r76CF6ZZfPjHorN2+d+3mqA==",
      "license": "MIT",
      "dependencies": {
        "semver": "^5.5.0"
      }
    },
    "node_modules/truncate-utf8-bytes": {
      "version": "1.0.2",
      "resolved": "https://registry.npmjs.org/truncate-utf8-bytes/-/truncate-utf8-bytes-1.0.2.tgz",
      "integrity": "sha512-95Pu1QXQvruGEhv62XCMO3Mm90GscOCClvrIUwCM0PYOXK3kaF3l3sIHxx71ThJfcbM2O5Au6SO3AWCSEfW4mQ==",
      "license": "WTFPL",
      "dependencies": {
        "utf8-byte-length": "^1.0.1"
      }
    },
    "node_modules/undici-types": {
      "version": "8.3.0",
      "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-8.3.0.tgz",
      "integrity": "sha512-j375ScV60dom+YkPFIfTLcOiPxkN/buHz5GobjLhixFuANaNs3C9l4GmrWqejgXWJ7BbJcFYpTEUkS1Ge8bpZQ==",
      "license": "MIT"
    },
    "node_modules/universalify": {
      "version": "2.0.1",
      "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz",
      "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==",
      "license": "MIT",
      "engines": {
        "node": ">= 10.0.0"
      }
    },
    "node_modules/utf8-byte-length": {
      "version": "1.0.5",
      "resolved": "https://registry.npmjs.org/utf8-byte-length/-/utf8-byte-length-1.0.5.tgz",
      "integrity": "sha512-Xn0w3MtiQ6zoz2vFyUVruaCL53O/DwUvkEeOvj+uulMm0BkUGYWmBYVyElqZaSLhY6ZD0ulfU3aBra2aVT4xfA==",
      "license": "(WTFPL OR MIT)"
    },
    "node_modules/which": {
      "version": "2.0.2",
      "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
      "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==",
      "license": "ISC",
      "dependencies": {
        "isexe": "^2.0.0"
      },
      "bin": {
        "node-which": "bin/node-which"
      },
      "engines": {
        "node": ">= 8"
      }
    }
  }
}
package.json
{
  "name": "sample-electron-publish",
  "version": "1.0.0",
  "private": true,
  "description": "Clean-room verification of electron-publish",
  "main": "src/index.js",
  "license": "MIT-0",
  "dependencies": {
    "electron-publish": "26.15.3"
  }
}
spec.json
{
  "schemaVersion": 1,
  "goal": "verify pkg:npm/electron-publish@26.15.3",
  "kind": "HOW",
  "packages": [
    "pkg:npm/electron-publish@26.15.3"
  ],
  "constraints": {
    "executionContext": "node"
  },
  "runtimeConditions": {
    "ecosystem": "npm",
    "language": "javascript",
    "moduleSystem": "cjs",
    "packageManager": "npm@10.9.8",
    "runtime": "node@22.23.2"
  }
}
src/index.js
const {
  Publisher,
  HttpPublisher,
  ProgressBar,
  ProgressCallback,
  MultiProgress,
  getCiTag,
  resolveSnapCredentials,
  SnapStorePublisher,
  GitHubPublisher,
  GitlabPublisher,
  BitbucketPublisher,
  KeygenPublisher,
  S3Publisher,
  SpacesPublisher
} = require('electron-publish');
const { Writable } = require('node:stream');

/**
 * Custom writable stream for capturing progress bar output without terminal side-effects.
 */
class StringStream extends Writable {
  constructor(options = {}) {
    super(options);
    this.data = '';
    this.columns = options.columns || 80;
    this.rows = options.rows || 24;
  }

  _write(chunk, encoding, callback) {
    this.data += chunk.toString();
    callback();
  }

  cursorTo(x, y) {}
  clearLine(dir) {}
  moveCursor(dx, dy) {}
}

/**
 * Mock ClientRequest for testing HTTP publisher upload pipelines offline.
 */
class MockClientRequest extends Writable {
  constructor(options = {}) {
    super(options);
    this.chunks = [];
    this.timeoutMs = null;
    this.timeoutCallback = null;
  }

  setTimeout(ms, cb) {
    this.timeoutMs = ms;
    this.timeoutCallback = cb;
  }

  _write(chunk, encoding, callback) {
    this.chunks.push(Buffer.from(chunk));
    callback();
  }

  get body() {
    return Buffer.concat(this.chunks);
  }
}

/**
 * Concrete HttpPublisher implementation for verifying upload behavior offline.
 */
class MemoryHttpPublisher extends HttpPublisher {
  constructor(context, useSafeArtifactName = false) {
    super(context, useSafeArtifactName);
    this.uploads = [];
  }

  get providerName() {
    return 'custom';
  }

  async doUpload(fileName, arch, dataLength, requestProcessor, file) {
    const mockReq = new MockClientRequest();
    return new Promise((resolve, reject) => {
      mockReq.on('finish', () => {
        const uploadedRecord = {
          fileName,
          arch,
          dataLength,
          file,
          body: mockReq.body
        };
        this.uploads.push(uploadedRecord);
        resolve(uploadedRecord);
      });
      mockReq.on('error', reject);

      try {
        requestProcessor(mockReq, reject);
      } catch (err) {
        reject(err);
      }
    });
  }

  toString() {
    return 'MemoryHttpPublisher';
  }
}

/**
 * Creates a PublishContext object with standard cancellation and progress handles.
 */
function createPublishContext(options = {}) {
  const cancellationToken = options.cancellationToken || {
    isCancelled: false,
    cancel() {
      this.isCancelled = true;
    }
  };
  const progress = options.progress !== undefined ? options.progress : null;
  return {
    cancellationToken,
    progress
  };
}

module.exports = {
  Publisher,
  HttpPublisher,
  ProgressBar,
  ProgressCallback,
  MultiProgress,
  getCiTag,
  resolveSnapCredentials,
  SnapStorePublisher,
  GitHubPublisher,
  GitlabPublisher,
  BitbucketPublisher,
  KeygenPublisher,
  S3Publisher,
  SpacesPublisher,
  StringStream,
  MockClientRequest,
  MemoryHttpPublisher,
  createPublishContext
};
test/contract.mjs
import assert from 'node:assert';
import path from 'node:path';
import os from 'node:os';
import fs from 'node:fs';
import { createRequire } from 'node:module';

const require = createRequire(import.meta.url);
const {
  Publisher,
  HttpPublisher,
  ProgressBar,
  ProgressCallback,
  MultiProgress,
  getCiTag,
  resolveSnapCredentials,
  SnapStorePublisher,
  GitHubPublisher,
  GitlabPublisher,
  BitbucketPublisher,
  KeygenPublisher,
  S3Publisher,
  SpacesPublisher,
  StringStream,
  MockClientRequest,
  MemoryHttpPublisher,
  createPublishContext
} = require('../src/index.js');

async function runContract() {
  const tmpDir = path.join(
    os.tmpdir(),
    `csx-contract-electron-publish-${Date.now()}-${Math.random().toString(36).slice(2)}`
  );
  fs.mkdirSync(tmpDir, { recursive: true });

  try {
    // 1. Publisher base class handles PublishContext and progress bar lifecycle
    const contextWithoutProgress = createPublishContext({ progress: null });
    assert.strictEqual(contextWithoutProgress.progress, null);
    assert.strictEqual(contextWithoutProgress.cancellationToken.isCancelled, false);

    class TestPublisher extends Publisher {
      get providerName() {
        return 'test-provider';
      }
      async upload(task) {
        return { uploaded: true, file: task.file };
      }
      toString() {
        return 'TestPublisher';
      }
    }

    const testPubNoProgress = new TestPublisher(contextWithoutProgress);
    assert.strictEqual(testPubNoProgress.providerName, 'test-provider');
    // Without progress manager, createProgressBar returns null regardless of size
    assert.strictEqual(testPubNoProgress.createProgressBar('test.zip', 1024 * 1024), null);
    // For small sizes under 512KB, createProgressBar returns null even with progress manager
    const stringOut = new StringStream();
    const multiProg = new MultiProgress();
    multiProg.stream = stringOut;
    const contextWithProgress = createPublishContext({ progress: multiProg });
    const testPubWithProgress = new TestPublisher(contextWithProgress);
    assert.strictEqual(testPubWithProgress.createProgressBar('small.zip', 100 * 1024), null);

    // 2. createReadStreamAndProgressBar returns readable file stream
    const testFilePath = path.join(tmpDir, 'sample-file.txt');
    fs.writeFileSync(testFilePath, 'Clean-room offline verification for electron-publish.', 'utf8');
    const stat = fs.statSync(testFilePath);

    const stream = testPubNoProgress.createReadStreamAndProgressBar(
      testFilePath,
      stat,
      null,
      (err) => { throw err; }
    );
    let collectedContent = '';
    for await (const chunk of stream) {
      collectedContent += chunk.toString();
    }
    assert.strictEqual(
      collectedContent,
      'Clean-room offline verification for electron-publish.',
      'createReadStreamAndProgressBar must stream file content accurately'
    );

    // 3. HttpPublisher processes direct buffer uploads and file uploads with artifact naming
    const httpPubDefault = new MemoryHttpPublisher(contextWithoutProgress, false);
    await httpPubDefault.upload({
      file: 'ignored/path/app-1.0.0.exe',
      fileContent: Buffer.from('binary-executable-payload'),
      arch: 1, // Arch.x64
      safeArtifactName: 'custom-safe-name.exe'
    });
    assert.strictEqual(httpPubDefault.uploads.length, 1);
    const bufferRecord = httpPubDefault.uploads[0];
    assert.strictEqual(bufferRecord.fileName, 'app-1.0.0.exe', 'Should use basename when useSafeArtifactName is false');
    assert.strictEqual(bufferRecord.body.toString(), 'binary-executable-payload');

    const httpPubSafe = new MemoryHttpPublisher(contextWithoutProgress, true);
    const fileUploadResult = await httpPubSafe.upload({
      file: testFilePath,
      arch: 1,
      safeArtifactName: 'renamed-safe-artifact.txt'
    });
    assert.strictEqual(httpPubSafe.uploads.length, 1);
    const fileRecord = httpPubSafe.uploads[0];
    assert.strictEqual(fileRecord.fileName, 'renamed-safe-artifact.txt', 'Should use safeArtifactName when configured');
    assert.strictEqual(fileRecord.body.toString(), 'Clean-room offline verification for electron-publish.');
    assert.deepStrictEqual(fileUploadResult, fileRecord);

    // 4. ProgressBar manages progress state, renders formatted progress indicators, and tracks completion with terminate
    const barStream = new StringStream();
    const bar = new ProgressBar('[:bar] :percent', {
      total: 10,
      stream: barStream,
      width: 10,
      complete: '=',
      incomplete: '-'
    });
    let terminated = false;
    bar.terminate = () => { terminated = true; };

    assert.strictEqual(bar.total, 10);
    assert.strictEqual(bar.current, 0);
    assert.strictEqual(bar.complete, false);

    bar.tick(5);
    assert.strictEqual(bar.current, 5);
    assert.strictEqual(bar.complete, false);
    assert.strictEqual(terminated, false);

    bar.update(0.8);
    assert.strictEqual(bar.current, 8);
    assert.strictEqual(bar.complete, false);

    bar.tick(2);
    assert.strictEqual(bar.current, 10);
    assert.strictEqual(bar.complete, true);
    assert.strictEqual(terminated, true);

    // 5. ProgressCallback throttles intermediate updates until interval or completion
    const cbBarStream = new StringStream();
    const cbBar = new ProgressBar('[:bar]', { total: 100, stream: cbBarStream });
    cbBar.terminate = () => {};
    const progressCb = new ProgressCallback(cbBar);

    // Throttled update: transferred < total before 1000ms does not update bar immediately
    progressCb.update(50, 100);
    assert.strictEqual(cbBar.current, 0, 'Intermediate update should be throttled');

    // Completion update: transferred >= total updates bar immediately
    progressCb.update(100, 100);
    assert.strictEqual(cbBar.total, 100);
    assert.strictEqual(cbBar.current, 100, 'Completion update should update immediately');
    assert.strictEqual(cbBar.complete, true);

    // 6. MultiProgress creates and coordinates progress bars with built-in terminate handling
    const mp = new MultiProgress();
    mp.stream = new StringStream();
    const mpBar = mp.createBar('[:bar] :current/:total', { total: 50 });
    assert.ok(mpBar instanceof ProgressBar);
    mpBar.tick(25);
    assert.strictEqual(mpBar.current, 25);
    mpBar.tick(25);
    assert.strictEqual(mpBar.current, 50);
    assert.strictEqual(mpBar.complete, true);
    mp.terminate();

    // 7. getCiTag detects CI environment tag names from standard CI environment variables
    const originalEnv = { ...process.env };
    try {
      // Clear CI tag vars
      delete process.env.TRAVIS_TAG;
      delete process.env.APPVEYOR_REPO_TAG_NAME;
      delete process.env.CIRCLE_TAG;
      delete process.env.BITRISE_GIT_TAG;
      delete process.env.CI_BUILD_TAG;
      delete process.env.CI_COMMIT_TAG;
      delete process.env.BITBUCKET_TAG;
      delete process.env.GITHUB_REF_TYPE;
      delete process.env.GITHUB_REF_NAME;

      assert.strictEqual(getCiTag(), null, 'getCiTag should return null when no CI tags are present');

      process.env.GITHUB_REF_TYPE = 'tag';
      process.env.GITHUB_REF_NAME = 'v1.2.3';
      assert.strictEqual(getCiTag(), 'v1.2.3', 'getCiTag should detect GITHUB_REF_NAME when type is tag');

      process.env.GITHUB_REF_TYPE = 'branch';
      assert.strictEqual(getCiTag(), null, 'getCiTag should ignore GITHUB_REF_NAME when type is branch');

      process.env.CIRCLE_TAG = 'v2.0.0';
      assert.strictEqual(getCiTag(), 'v2.0.0', 'getCiTag should detect CIRCLE_TAG');
    } finally {
      process.env = originalEnv;
    }

    // 8. resolveSnapCredentials parses credential links or returns empty object
    const emptyCreds = await resolveSnapCredentials(null, '/tmp');
    assert.deepStrictEqual(emptyCreds, {}, 'resolveSnapCredentials should return empty object for null/empty link');

    const emptyCredsWhitespace = await resolveSnapCredentials('   ', '/tmp');
    assert.deepStrictEqual(emptyCredsWhitespace, {}, 'resolveSnapCredentials should return empty object for whitespace link');

    // 9. Publisher implementations exports and identity
    assert.strictEqual(typeof SnapStorePublisher, 'function');
    assert.strictEqual(typeof GitHubPublisher, 'function');
    assert.strictEqual(typeof GitlabPublisher, 'function');
    assert.strictEqual(typeof BitbucketPublisher, 'function');
    assert.strictEqual(typeof KeygenPublisher, 'function');
    assert.strictEqual(typeof S3Publisher, 'function');
    assert.strictEqual(typeof SpacesPublisher, 'function');

    console.log('All contract assertions passed successfully.');
  } finally {
    fs.rmSync(tmpDir, { recursive: true, force: true });
  }
}

runContract().catch((err) => {
  console.error('Contract test failed:', err);
  process.exit(1);
});

Origin Seeder

anonymous