CodeSampleX

Sample

electron-publish 25.1.7: Publisher

Verified sample for npm electron-publish 25.1.7: Publisher. The contract ran on node 22 · linux debian/x64 · docker and passed.

sha256:d7a82059357132138badc928a2314d54e517aacd977336e6eaed265c0d8fb72b

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 debian/x64 · docker ed25519:c1973797be207ac4 PASS compile:SKIPPED · contract:PASS · load:PASS · resolve:PASS
CONTAINER_RUN · node-typescript@1node:22@sha256:8a34c4ab3ea2…
2026-09-02

Case

HOW
Goal
verify Publisher in pkg:npm/electron-publish@25.1.7
Packages
Symbols
  • Publisher
Environment
node 22.23.2
Created
2026-09-02T14:09:30Z

Contract

  1. Publisher provides an extensible base class for artifact publishing with providerName and upload methods
  2. HttpPublisher handles artifact uploads via doUpload with support for in-memory buffers and file stat sizing
  3. HttpPublisher uses safeArtifactName when configured and falls back to target file basename
  4. getCiTag parses CI environment tags or returns null when no tag environment variable is set

Files

  • PROMPT.md
  • csx.json
  • index.mjs
  • package-lock.json
  • package.json
  • spec.json
  • 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 Publisher in pkg:npm/electron-publish@25.1.7
Kind: HOW

Use EXACTLY these public packages and versions:
  - pkg:npm/electron-publish@25.1.7
Demonstrate these symbols/APIs:
  - Publisher

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:773f34f0872fc4a38a1c79b15ef7f53b79c2297f2b485091ae25268543716412","contract":["Publisher provides an extensible base class for artifact publishing with providerName and upload methods","HttpPublisher handles artifact uploads via doUpload with support for in-memory buffers and file stat sizing","HttpPublisher uses safeArtifactName when configured and falls back to target file basename","getCiTag parses CI environment tags or returns null when no tag environment variable is set"],"goal":"verify Publisher in pkg:npm/electron-publish@25.1.7","kind":"HOW","packages":["pkg:npm/electron-publish@25.1.7"],"schemaVersion":1,"symbols":["Publisher"]},"contractCommand":["node","test/contract.mjs"],"environment":{"arch":"x64","distro":"ubuntu","ecosystem":"npm","executionContext":"node","language":"javascript","libc":"glibc","libcVersion":"2.39","moduleSystem":"esm","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@25.1.7"],"schemaVersion":1,"subject":"pkg:npm/electron-publish@25.1.7","symbols":["Publisher"],"verifierAdapter":"node-typescript@1"}
index.mjs
import { Publisher, HttpPublisher, getCiTag } from 'electron-publish';
import { CancellationToken } from 'builder-util-runtime';

/**
 * Creates a minimal PublishContext.
 * @param {object} [options]
 * @returns {import('electron-publish').PublishContext}
 */
export function createPublishContext(options = {}) {
  return {
    cancellationToken: options.cancellationToken || new CancellationToken(),
    progress: options.progress || null
  };
}

/**
 * Custom memory publisher extending the base Publisher.
 */
export class CustomMemoryPublisher extends Publisher {
  /**
   * @param {import('electron-publish').PublishContext} context
   */
  constructor(context) {
    super(context);
    this.records = [];
  }

  get providerName() {
    return 'custom';
  }

  /**
   * @param {import('electron-publish').UploadTask} task
   */
  async upload(task) {
    const record = {
      file: task.file,
      arch: task.arch ?? null,
      safeArtifactName: task.safeArtifactName ?? null,
      hasContent: Boolean(task.fileContent),
      provider: this.providerName
    };
    this.records.push(record);
    return record;
  }

  toString() {
    return 'CustomMemoryPublisher';
  }
}

/**
 * Mock HTTP publisher extending HttpPublisher to capture doUpload calls.
 */
export class MockHttpPublisher extends HttpPublisher {
  /**
   * @param {import('electron-publish').PublishContext} context
   * @param {boolean} [useSafeArtifactName]
   */
  constructor(context, useSafeArtifactName = false) {
    super(context, useSafeArtifactName);
    this.uploads = [];
  }

  get providerName() {
    return 'custom';
  }

  /**
   * @param {string} fileName
   * @param {number} arch
   * @param {number} dataLength
   * @param {function} requestProcessor
   * @param {string} file
   */
  async doUpload(fileName, arch, dataLength, requestProcessor, file) {
    const item = {
      fileName,
      arch,
      dataLength,
      file
    };
    this.uploads.push(item);
    return item;
  }

  toString() {
    return 'MockHttpPublisher';
  }
}

export { Publisher, HttpPublisher, getCiTag };
package-lock.json
{
  "name": "sample",
  "version": "1.0.0",
  "lockfileVersion": 3,
  "requires": true,
  "packages": {
    "": {
      "name": "sample",
      "version": "1.0.0",
      "dependencies": {
        "electron-publish": "25.1.7"
      }
    },
    "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.4.1",
      "resolved": "https://registry.npmjs.org/@types/node/-/node-26.4.1.tgz",
      "integrity": "sha512-k97ENvZWtvA6yqz5/FS6a7duDgOPEeOQOc2iKS/nY6mX6qJUKtLnWzQS+Xj6tXweyj6ZcTAK2Qecetnvi9nCLA==",
      "license": "MIT",
      "dependencies": {
        "undici-types": "~8.3.0"
      }
    },
    "node_modules/7zip-bin": {
      "version": "5.2.0",
      "resolved": "https://registry.npmjs.org/7zip-bin/-/7zip-bin-5.2.0.tgz",
      "integrity": "sha512-ukTPVhqG4jNzMro2qA9HSCSSVJN3aN7tlb+hfqYCt3ER0yWroeA2VR38MNrOHLQ/cVj+DaIMad0kFCtWWowh/A==",
      "license": "MIT"
    },
    "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/app-builder-bin": {
      "version": "5.0.0-alpha.10",
      "resolved": "https://registry.npmjs.org/app-builder-bin/-/app-builder-bin-5.0.0-alpha.10.tgz",
      "integrity": "sha512-Ev4jj3D7Bo+O0GPD2NMvJl+PGiBAfS7pUGawntBNpCbxtpncfUixqFj9z9Jme7V7s3LBGqsWZZP54fxBX3JKJw==",
      "license": "MIT"
    },
    "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/bluebird": {
      "version": "3.7.2",
      "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz",
      "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==",
      "license": "MIT"
    },
    "node_modules/bluebird-lst": {
      "version": "1.0.9",
      "resolved": "https://registry.npmjs.org/bluebird-lst/-/bluebird-lst-1.0.9.tgz",
      "integrity": "sha512-7B1Rtx82hjnSD4PGLAjVWeYH3tHAcVUmChh85a3lltKQm6FresXh9ErQo6oAv6CqxttczC3/kEg8SY5NluPuUw==",
      "license": "MIT",
      "dependencies": {
        "bluebird": "^3.5.5"
      }
    },
    "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": "25.1.7",
      "resolved": "https://registry.npmjs.org/builder-util/-/builder-util-25.1.7.tgz",
      "integrity": "sha512-7jPjzBwEGRbwNcep0gGNpLXG9P94VA3CPAZQCzxkFXiV2GMQKlziMbY//rXPI7WKfhsvGgFXjTcXdBEwgXw9ww==",
      "license": "MIT",
      "dependencies": {
        "@types/debug": "^4.1.6",
        "7zip-bin": "~5.2.0",
        "app-builder-bin": "5.0.0-alpha.10",
        "bluebird-lst": "^1.0.9",
        "builder-util-runtime": "9.2.10",
        "chalk": "^4.1.2",
        "cross-spawn": "^7.0.3",
        "debug": "^4.3.4",
        "fs-extra": "^10.1.0",
        "http-proxy-agent": "^7.0.0",
        "https-proxy-agent": "^7.0.0",
        "is-ci": "^3.0.0",
        "js-yaml": "^4.1.0",
        "source-map-support": "^0.5.19",
        "stat-mode": "^1.0.0",
        "temp-file": "^3.4.0"
      }
    },
    "node_modules/builder-util-runtime": {
      "version": "9.2.10",
      "resolved": "https://registry.npmjs.org/builder-util-runtime/-/builder-util-runtime-9.2.10.tgz",
      "integrity": "sha512-6p/gfG1RJSQeIbz8TK5aPNkoztgY1q5TgmGFMAXcY8itsGW6Y2ld1ALsZ5UJn8rog7hKF3zHx5iQbNQ8uLcRlw==",
      "license": "MIT",
      "dependencies": {
        "debug": "^4.3.4",
        "sax": "^1.2.4"
      },
      "engines": {
        "node": ">=12.0.0"
      }
    },
    "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/ci-info": {
      "version": "3.9.0",
      "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.9.0.tgz",
      "integrity": "sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ==",
      "funding": [
        {
          "type": "github",
          "url": "https://github.com/sponsors/sibiraj-s"
        }
      ],
      "license": "MIT",
      "engines": {
        "node": ">=8"
      }
    },
    "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/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/electron-publish": {
      "version": "25.1.7",
      "resolved": "https://registry.npmjs.org/electron-publish/-/electron-publish-25.1.7.tgz",
      "integrity": "sha512-+jbTkR9m39eDBMP4gfbqglDd6UvBC7RLh5Y0MhFSsc6UkGHj9Vj9TWobxevHYMMqmoujL11ZLjfPpMX+Pt6YEg==",
      "license": "MIT",
      "dependencies": {
        "@types/fs-extra": "^9.0.11",
        "builder-util": "25.1.7",
        "builder-util-runtime": "9.2.10",
        "chalk": "^4.1.2",
        "fs-extra": "^10.1.0",
        "lazy-val": "^1.0.5",
        "mime": "^2.5.2"
      }
    },
    "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/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/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/is-ci": {
      "version": "3.0.1",
      "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-3.0.1.tgz",
      "integrity": "sha512-ZYvCgrefwqoQ6yTyYUbQu64HsITZ3NfKX1lzaEYdkTDcfKzzCI/wthRRYKkdjHKFVgNiXKAKm65Zo1pk2as/QQ==",
      "license": "MIT",
      "dependencies": {
        "ci-info": "^3.2.0"
      },
      "bin": {
        "is-ci": "bin.js"
      }
    },
    "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.2",
      "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.3.2.tgz",
      "integrity": "sha512-SFNOvSJ+Dgf/9An904Yx+CgSlIPCkIpao4qo51lpee25TIRejdH3rhR4EZMGoNx3/TP3O+wzWuiTFl4sqbltzA==",
      "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/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/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/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/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/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/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",
  "version": "1.0.0",
  "private": true,
  "type": "module",
  "dependencies": {
    "electron-publish": "25.1.7"
  }
}
spec.json
{
  "schemaVersion": 1,
  "goal": "verify Publisher in pkg:npm/electron-publish@25.1.7",
  "kind": "HOW",
  "packages": [
    "pkg:npm/electron-publish@25.1.7"
  ],
  "symbols": [
    "Publisher"
  ]
}
test/contract.mjs
import assert from 'node:assert/strict';
import fs from 'node:fs';
import path from 'node:path';
import os from 'node:os';
import {
  Publisher,
  HttpPublisher,
  getCiTag,
  createPublishContext,
  CustomMemoryPublisher,
  MockHttpPublisher
} from '../index.mjs';

async function main() {
  const tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), 'csx-ep-'));
  const testFile = path.join(tmpDir, 'app-build.zip');
  const dummyPayload = 'SAMPLE_BINARY_PAYLOAD_FOR_TESTING';
  fs.writeFileSync(testFile, dummyPayload, 'utf8');

  try {
    const context = createPublishContext();

    // 1. Verify Publisher base class and custom implementation
    assert.strictEqual(typeof Publisher, 'function', 'Publisher must be a class constructor');
    const memoryPub = new CustomMemoryPublisher(context);
    assert.strictEqual(memoryPub.providerName, 'custom', 'providerName must return custom provider');
    assert.strictEqual(memoryPub.toString(), 'CustomMemoryPublisher', 'toString must return class identifier');

    const memoryTask = {
      file: testFile,
      arch: 1, // Arch.x64
      safeArtifactName: 'app-release-linux.zip'
    };
    const uploadResult = await memoryPub.upload(memoryTask);
    assert.strictEqual(uploadResult.file, testFile, 'upload must retain file path');
    assert.strictEqual(uploadResult.safeArtifactName, 'app-release-linux.zip', 'upload must retain safeArtifactName');
    assert.strictEqual(uploadResult.hasContent, false, 'upload must reflect absence of explicit fileContent');
    assert.strictEqual(memoryPub.records.length, 1, 'MemoryPublisher must record the upload');

    // 2. Verify HttpPublisher base class with in-memory buffer
    assert.strictEqual(typeof HttpPublisher, 'function', 'HttpPublisher must be a class constructor');
    const httpPub = new MockHttpPublisher(context, false);
    assert.strictEqual(httpPub.providerName, 'custom', 'providerName must return custom provider');

    const bufferData = Buffer.from('buffered-content', 'utf8');
    await httpPub.upload({
      file: '/virtual/path/package.tar.gz',
      fileContent: bufferData,
      arch: 1
    });

    assert.strictEqual(httpPub.uploads.length, 1, 'HttpPublisher must process in-memory buffer upload');
    assert.strictEqual(httpPub.uploads[0].fileName, 'package.tar.gz', 'HttpPublisher must derive fileName from path basename by default');
    assert.strictEqual(httpPub.uploads[0].dataLength, bufferData.length, 'HttpPublisher must pass buffer length as dataLength');

    // 3. Verify HttpPublisher with safeArtifactName and file stat size
    const safeHttpPub = new MockHttpPublisher(context, true);
    await safeHttpPub.upload({
      file: testFile,
      arch: 1,
      safeArtifactName: 'custom-safe-name.zip'
    });

    assert.strictEqual(safeHttpPub.uploads.length, 1, 'safeHttpPub must record upload');
    assert.strictEqual(safeHttpPub.uploads[0].fileName, 'custom-safe-name.zip', 'HttpPublisher must use safeArtifactName when enabled');
    assert.strictEqual(safeHttpPub.uploads[0].dataLength, Buffer.byteLength(dummyPayload, 'utf8'), 'HttpPublisher must size file from disk stat');

    // 4. Verify getCiTag resolution from environment
    assert.strictEqual(typeof getCiTag, 'function', 'getCiTag must be a function');

    const envKeys = [
      'GITHUB_REF_TYPE',
      'GITHUB_REF_NAME',
      'TRAVIS_TAG',
      'CIRCLE_TAG',
      'APPVEYOR_REPO_TAG_NAME',
      'BITRISE_GIT_TAG',
      'CI_BUILD_TAG',
      'CI_COMMIT_TAG',
      'BITBUCKET_TAG'
    ];

    const savedEnv = {};
    for (const key of envKeys) {
      savedEnv[key] = process.env[key];
      delete process.env[key];
    }

    try {
      assert.strictEqual(getCiTag(), null, 'getCiTag must return null when no tag environment variables are set');

      process.env.GITHUB_REF_TYPE = 'tag';
      process.env.GITHUB_REF_NAME = 'v1.2.3';
      assert.strictEqual(getCiTag(), 'v1.2.3', 'getCiTag must resolve GitHub release tag');

      delete process.env.GITHUB_REF_TYPE;
      delete process.env.GITHUB_REF_NAME;
      process.env.TRAVIS_TAG = 'v2.0.0';
      assert.strictEqual(getCiTag(), 'v2.0.0', 'getCiTag must resolve Travis tag');

      delete process.env.TRAVIS_TAG;
      process.env.CI_COMMIT_TAG = 'release-3.0';
      assert.strictEqual(getCiTag(), 'release-3.0', 'getCiTag must resolve GitLab CI_COMMIT_TAG');
    } finally {
      for (const key of envKeys) {
        if (savedEnv[key] === undefined) {
          delete process.env[key];
        } else {
          process.env[key] = savedEnv[key];
        }
      }
    }

    console.log('Contract tests passed successfully.');
  } finally {
    try {
      fs.rmSync(tmpDir, { recursive: true, force: true });
    } catch {
      // ignore
    }
  }
}

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

Origin Seeder

anonymous