Skip to content

Working with NPM

CodeScoring.Save implements npm Registry API with the /npm/<project>/<repository>/ prefix. It is compatible with standard npm, yarn, and pnpm clients.

Proxy Repository

curl -X POST https://save.example.com/api/v1/repos \
  -H "Content-Type: application/json" \
  -u "<username>:<password>" \
  -d '{
    "project": "frontend",
    "name": "npmjs-proxy",
    "format": "npm",
    "repository_type": "proxy",
    "remote_url": "https://registry.npmjs.org",
    "cache_ttl": 3600
  }'

Hosted Repository

curl -X POST https://save.example.com/api/v1/repos \
  -H "Content-Type: application/json" \
  -u "<username>:<password>" \
  -d '{
    "project": "frontend",
    "name": "npm-hosted",
    "format": "npm",
    "repository_type": "hosted"
  }'

Client Configuration

npm

# Set registry in the current project
echo "registry=https://save.example.com/npm/<project>/npmjs-proxy/" > .npmrc

# Authentication (npm 7+, _auth is base64(username:password))
NPM_AUTH=$(echo -n "<username>:<password>" | base64)
cat >> .npmrc << EOF
//save.example.com/npm/<project>/npmjs-proxy/:_auth=${NPM_AUTH}
//save.example.com/npm/<project>/npmjs-proxy/:always-auth=true
EOF

# Install dependency
npm install lodash

Robot accounts in CI

For CI/CD, use a robot account: username = sa$<robot-name>, password = <api-key>. The .npmrc structure remains the same; only _auth changes (base64 of sa$<robot-name>:<api-key>). For details, see Authentication.

Opaque bearer tokens

After npm adduser / npm login, the npm client stores the received opaque token and then uses it as Authorization: Bearer <token>. cs-auth classifies any non-JWT bearer token (a Bearer value without three dot-separated segments) as npm_token and validates it through service accounts linked to API keys.

Publishing to a hosted repository:

cat > .npmrc << EOF
registry=https://save.example.com/npm/<project>/npm-hosted/
//save.example.com/npm/<project>/npm-hosted/:_auth=${NPM_AUTH}
//save.example.com/npm/<project>/npm-hosted/:always-auth=true
EOF

npm publish

yarn

Yarn Classic (1.x)

Yarn 1.x uses the same .npmrc as npm:

echo "registry=https://save.example.com/npm/<project>/npmjs-proxy/" > .npmrc
yarn install

Yarn 2+ (Berry)

In .yarnrc.yml:

npmRegistryServer: "https://save.example.com/npm/<project>/npmjs-proxy/"

npmRegistries:
  "https://save.example.com/npm/<project>/npmjs-proxy/":
    npmAlwaysAuth: true
    npmAuthIdent: "<username>:<password>"

pnpm

pnpm reads the same .npmrc:

echo "registry=https://save.example.com/npm/<project>/npmjs-proxy/" > .npmrc
pnpm install

For scoped packages, configure a separate registry:

echo "@mycompany:registry=https://save.example.com/npm/<project>/npm-hosted/" >> .npmrc

Repository URL Migration

Use case: migrating an npm repository from Nexus / Artifactory to CodeScoring.Save.

Source .npmrc registry= before migration .npmrc registry= after migration
Nexus https://nexus.host.ru/repository/npm-proxy https://save.example.com/npm/<project>/npmjs-proxy/
Artifactory https://jfrog.host.ru/artifactory/api/npm/npm-remote https://save.example.com/npm/<project>/npmjs-proxy/
Official repository https://registry.npmjs.org https://save.example.com/npm/<project>/npmjs-proxy/

During migration, it is enough to replace the URL in .npmrc/.yarnrc.yml. Existing Nexus/Artifactory credentials can be reused as Basic Auth.

Troubleshooting

Checking Package Metadata

curl -u "<username>:<password>" \
  https://save.example.com/npm/<project>/npmjs-proxy/lodash | jq .

Whoami / Ping

curl -u "<username>:<password>" \
  https://save.example.com/npm/<project>/npmjs-proxy/-/whoami

curl -u "<username>:<password>" \
  https://save.example.com/npm/<project>/npmjs-proxy/-/ping

Service Status

curl https://save.example.com/health

Repository Audit

curl -u "<username>:<password>" \
  "https://save.example.com/api/v1/admin/audit?resource_type=repository&q=npmjs-proxy&limit=50"
Страница была полезна?