Registry: resolve dev packages
Also resolve @sap packages, but forward non-cds packages to default registry
This commit is contained in:
@@ -1,27 +1,34 @@
|
|||||||
const { exec } = require ('child_process')
|
const { exec, execSync } = require ('child_process')
|
||||||
const isWin = process.platform === 'win32'
|
const isWin = process.platform === 'win32'
|
||||||
const express = require ('express')
|
const express = require ('express')
|
||||||
const fs = require ('fs')
|
const fs = require ('fs')
|
||||||
|
const { dirname, relative } = require('path')
|
||||||
|
const axios = require('axios')
|
||||||
const app = express()
|
const app = express()
|
||||||
|
|
||||||
const { PORT=4444 } = process.env
|
|
||||||
const [,,port=PORT,scope='@capire'] = process.argv
|
|
||||||
const cwd = __dirname
|
const cwd = __dirname
|
||||||
|
const port=process.env.PORT || 4444
|
||||||
|
let scopes = process.argv.filter(a => a.startsWith('@'))
|
||||||
|
if (!scopes.length) scopes = ['@capire']
|
||||||
|
|
||||||
// clean up on start (exit handler might not complete on Windows)
|
// clean up on start (exit handler might not complete on Windows)
|
||||||
exec(isWin ? 'del *.tgz' : 'rm *.tgz', {cwd})
|
exec(isWin ? 'del *.tgz' : 'rm *.tgz', {cwd})
|
||||||
|
|
||||||
|
|
||||||
app.use('/-/:tarball', (req,res,next) => {
|
app.use('/-/:tarball', async (req,res,next) => {
|
||||||
console.debug ('GET', req.params)
|
console.debug ('GET', req.params)
|
||||||
try {
|
try {
|
||||||
const { tarball } = req.params
|
const { tarball } = req.params
|
||||||
const pkgFull = tarball.substring(0, tarball.lastIndexOf('-'))
|
const pkgFull = tarball.substring(0, tarball.lastIndexOf('-'))
|
||||||
const [, pkg ] = /^\w+-(.+)/.exec(pkgFull)
|
const scope = '@'+pkgFull.substring(0, pkgFull.indexOf('-'))
|
||||||
|
const pkg = pkgFull.substring(pkgFull.indexOf('-')+1)
|
||||||
fs.lstat(tarball,(err => {
|
fs.lstat(tarball,(err => {
|
||||||
if (err) console.debug (`npm pack ../${pkg}`)
|
if (err) { // no tgz yet
|
||||||
if (err) exec(`npm pack ../${pkg}`,{cwd},next)
|
const loc = dirname(require.resolve(`${scope}/${pkg}/package.json`))
|
||||||
else next()
|
console.debug (`npm pack ${relative(cwd, loc)}`)
|
||||||
|
exec(`npm pack ${loc}`,{cwd},next)
|
||||||
|
}
|
||||||
|
else next() //> express.static below
|
||||||
}))
|
}))
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error(e)
|
console.error(e)
|
||||||
@@ -31,14 +38,20 @@ app.use('/-/:tarball', (req,res,next) => {
|
|||||||
|
|
||||||
app.use('/-', express.static(__dirname))
|
app.use('/-', express.static(__dirname))
|
||||||
|
|
||||||
app.get('/*', (req,res)=>{
|
app.get('/*', async (req,res)=>{
|
||||||
const urlRegex = /^\/(@[\w-]+)\/(.+)/
|
const urlRegex = /^\/(@[\w-]+)\/(.+)/
|
||||||
const url = decodeURIComponent(req.url)
|
const url = decodeURIComponent(req.url)
|
||||||
console.debug ('GET',url)
|
console.debug ('GET',url)
|
||||||
try {
|
try {
|
||||||
if (!urlRegex.test(url)) return res.sendStatus(404)
|
if (!urlRegex.test(url)) return res.sendStatus(404)
|
||||||
const [, scpe, pkg ] = urlRegex.exec(url)
|
const [, scpe, pkg ] = urlRegex.exec(url)
|
||||||
const package = require (`${scpe}/${pkg}/package.json`)
|
const packageName = `${scpe}/${pkg}`
|
||||||
|
|
||||||
|
// delegate to default registry for @sap/non-cds packages
|
||||||
|
if (scpe === ('@sap') && !packageName.startsWith('@sap/cds')) {
|
||||||
|
return forward(req, res)
|
||||||
|
}
|
||||||
|
const package = require (`${packageName}/package.json`)
|
||||||
const tarball = `${scpe.slice(1)}-${pkg}-${package.version}.tgz`
|
const tarball = `${scpe.slice(1)}-${pkg}-${package.version}.tgz`
|
||||||
// https://github.com/npm/registry/blob/master/docs/responses/package-metadata.md
|
// https://github.com/npm/registry/blob/master/docs/responses/package-metadata.md
|
||||||
res.json({
|
res.json({
|
||||||
@@ -53,6 +66,8 @@ app.get('/*', (req,res)=>{
|
|||||||
"dist": {
|
"dist": {
|
||||||
"tarball": `${server.url}/-/${tarball}`
|
"tarball": `${server.url}/-/${tarball}`
|
||||||
},
|
},
|
||||||
|
dependencies: package.dependencies,
|
||||||
|
devDependencies: package.devDependencies
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
@@ -64,15 +79,32 @@ app.get('/*', (req,res)=>{
|
|||||||
|
|
||||||
const server = app.listen(port, ()=>{
|
const server = app.listen(port, ()=>{
|
||||||
const url = server.url = `http://localhost:${server.address().port}`
|
const url = server.url = `http://localhost:${server.address().port}`
|
||||||
console.log (`npm set ${scope}:registry=${url}`)
|
|
||||||
exec(`npm set ${scope}:registry=${url}`)
|
for (const scope of scopes) {
|
||||||
console.log (`${scope} registry listening on ${url}`)
|
console.log (`npm set ${scope}:registry=${url}`)
|
||||||
|
execSync(`npm set ${scope}:registry=${url}`)
|
||||||
|
}
|
||||||
|
console.log (`registry listening on ${url}`)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
const _exit = ()=>{
|
const _exit = ()=>{
|
||||||
server.close()
|
server.close()
|
||||||
exec(`npm conf rm "${scope}:registry"`, ()=> { process.exit() })
|
for (const scope of scopes) {
|
||||||
|
execSync(`npm conf rm "${scope}:registry"`)
|
||||||
|
}
|
||||||
|
process.exit()
|
||||||
|
}
|
||||||
|
|
||||||
|
async function forward(req, res) {
|
||||||
|
try {
|
||||||
|
const url = `https://registry.npmjs.org${req.url}`
|
||||||
|
const resAxios = await axios.get(url)
|
||||||
|
console.debug('->', decodeURI(url), resAxios.status)
|
||||||
|
return res.json(resAxios.data)
|
||||||
|
} catch (e) {
|
||||||
|
return res.sendStatus(e.response.status)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
process.on ('SIGTERM',_exit)
|
process.on ('SIGTERM',_exit)
|
||||||
|
|||||||
Reference in New Issue
Block a user