Skip to content

Commit

Permalink
feat: add impl draft
Browse files Browse the repository at this point in the history
  • Loading branch information
antongolub committed Apr 6, 2023
1 parent ec9acac commit 69adedc
Show file tree
Hide file tree
Showing 7 changed files with 134 additions and 14 deletions.
15 changes: 8 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,14 @@ import {formatNpmrc} from 'dotnpmrc'

const contents = formatNpmrc({
format: 'npm9',
scopes: [{
name: 'example',
registry: 'https://npm-registry.example.com/',
auth: 'base64-of-username-and-password',
authToken: 'npmToken.bearer',
alwaysAuth: true,
}],
scopes: {
example: {
registry: 'https://npm-registry.example.com/',
auth: 'base64-of-username-and-password',
authToken: 'npmToken.bearer',
alwaysAuth: true,
}
},
root: {
registry: 'https://registry.yarnpkg.com'
}
Expand Down
4 changes: 4 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,11 @@
"type": "git",
"url": "https://github.com/semrel-extra/npmrc.git"
},
"dependencies": {
"ini": "^4.0.0"
},
"devDependencies": {
"@types/ini": "^1.3.31",
"@types/node": "^18.15.10",
"c8": "^7.13.0",
"concurrently": "^7.6.0",
Expand Down
54 changes: 53 additions & 1 deletion src/main/ts/index.ts
Original file line number Diff line number Diff line change
@@ -1 +1,53 @@
export const foo = 'bar'
import {encode} from 'ini'

export interface INpmrcData {
format?: string,
root?: Record<string, string>,
scopes?: Record<string, {
registry: string
auth?: string
authToken?: string
username?: string
password?: string
[i: string]: string | undefined
}>
}

const credKeys = new Set(['_auth', '_authToken', 'username', '_password'])
const credAliases = new Set(['auth', 'authToken', 'password'])

// https://docs.npmjs.com/cli/v9/configuring-npm/npmrc
export const formatNpmrc = ({scopes = {}, root = {}, format}: INpmrcData): string => {
const config: Record<string, string> = {}
const registry = normalizeRegistry(root.registry || 'registry.npmjs.org')

for (const [name, scope] of Object.entries(scopes)) {
for (const [k, v] of Object.entries(scope)) {
if (k === 'registry') {
config[`@${normalizeScope(name)}:${k}`] = v as string
continue
}
config[`${normalizeRegistry(scope.registry)}:${normalizeKey(k)}`] = v || 'true'
}
}

for (const [_k, v, k = normalizeKey(_k)] of Object.entries(root)) {
if (format === 'npm9' && credKeys.has(k)) {
config[`${registry}:${k}`] = v || 'true'
continue
}
config[k] = v || 'true'
}

return encode(config)
}

const normalizeRegistry = (value: string): string => value
.replace(/^(https?:\/\/)?/, '//')
.replace(/\/*$/, '/')

const normalizeScope = (value: string): string => value.replace(/^@/, '')
const normalizeKey = (value: string): string =>
credAliases.has(value)
? `_${value}`
: value
4 changes: 2 additions & 2 deletions src/test/js/index.cjs
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
const { test } = require('uvu')
const assert = require('node:assert')
const toposource = require('@semrel-extra/npmrc')
const npmrc = require('@semrel-extra/npmrc')

test('index (cjs)', () => {
assert.ok(typeof toposource.foo === 'string')
assert.ok(typeof npmrc.formatNpmrc === 'function')
})

test.run()
4 changes: 2 additions & 2 deletions src/test/js/index.mjs
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import { test } from 'uvu'
import assert from 'node:assert'
import {foo} from '@semrel-extra/npmrc'
import { formatNpmrc } from '@semrel-extra/npmrc'

test('index (mjs)', () => {
assert.ok(typeof foo === 'string')
assert.ok(typeof formatNpmrc === 'function')
})

test.run()
57 changes: 55 additions & 2 deletions src/test/ts/index.test.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,63 @@
import { test } from 'uvu'
import * as assert from 'uvu/assert'

import { foo } from '../../main/ts'
import {formatNpmrc, INpmrcData} from '../../main/ts'

test('index has proper index', () => {
assert.ok(typeof foo === 'string')
assert.ok(typeof formatNpmrc === 'function')
})

test('`formatNpmrc()` returns proper contents', () => {
const cases: [INpmrcData, string][] = [
[
{},
''
],
[
{
scopes: {
test: {
registry: 'https://registry.example.com',
'always-auth': '',
auth: 'basic',
_authToken: 'bearer'
}
}
},
`@test:registry=https://registry.example.com
//registry.example.com/:always-auth=true
//registry.example.com/:_auth=basic
//registry.example.com/:_authToken=bearer
`
],
[
{
format: 'npm9',
root: {
'always-auth': '',
'auth': 'basic'
}
},
`always-auth=true
//registry.npmjs.org/:_auth=basic
`
],
[
{
root: {
'always-auth': '',
'auth': 'basic'
}
},
`always-auth=true
_auth=basic
`
]
];

for (const [data, expected] of cases) {
assert.equal(formatNpmrc(data), expected)
}
})

test.run()
10 changes: 10 additions & 0 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -243,6 +243,11 @@
"@nodelib/fs.scandir" "2.1.5"
fastq "^1.6.0"

"@types/ini@^1.3.31":
version "1.3.31"
resolved "https://registry.yarnpkg.com/@types/ini/-/ini-1.3.31.tgz#c78541a187bd88d5c73e990711c9d85214800d1b"
integrity sha512-8ecxxaG4AlVEM1k9+BsziMw8UsX0qy3jYI1ad/71RrDZ+rdL6aZB0wLfAuflQiDhkD5o4yJ0uPK3OSUic3fG0w==

"@types/istanbul-lib-coverage@^2.0.1":
version "2.0.4"
resolved "https://registry.yarnpkg.com/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.4.tgz#8467d4b3c087805d63580480890791277ce35c44"
Expand Down Expand Up @@ -1395,6 +1400,11 @@ inherits@2:
resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c"
integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==

ini@^4.0.0:
version "4.0.0"
resolved "https://registry.yarnpkg.com/ini/-/ini-4.0.0.tgz#35b4b0ba3bb9a3feb8c50dbf92fb1671efda88eb"
integrity sha512-t0ikzf5qkSFqRl1e6ejKBe+Tk2bsQd8ivEkcisyGXsku2t8NvXZ1Y3RRz5vxrDgOrTBOi13CvGsVoI5wVpd7xg==

internal-slot@^1.0.3, internal-slot@^1.0.5:
version "1.0.5"
resolved "https://registry.yarnpkg.com/internal-slot/-/internal-slot-1.0.5.tgz#f2a2ee21f668f8627a4667f309dc0f4fb6674986"
Expand Down

0 comments on commit 69adedc

Please sign in to comment.