Skip to content

Instantly share code, notes, and snippets.

@ChenYFan
Last active August 18, 2023 13:15
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ChenYFan/5eb5d7f0b90f4691e71f0728b4cb1782 to your computer and use it in GitHub Desktop.
Save ChenYFan/5eb5d7f0b90f4691e71f0728b4cb1782 to your computer and use it in GitHub Desktop.
const upload_to_npm = async (NPM_TOKEN, package_json, files) => {
const tape = new tar()
function uint8ToString(buf) {
var i, length, out = '';
for (i = 0, length = buf.length; i < length; i += 1) {
out += String.fromCharCode(buf[i]);
}
return out;
}
function stringToUint8(input) {
var out = new Uint8Array(input.length), i;
for (i = 0; i < input.length; i += 1) {
out[i] = input.charCodeAt(i);
}
return out;
}
async function integrityMetadata(buffer, algorithm) {
const hashBuffer = await hashText(buffer, algorithm);
const base64string = btoa(
String.fromCharCode(...new Uint8Array(hashBuffer))
);
return `${algorithm}-${base64string}`;
}
async function hashText(buffer, algorithm) {
const digest = await crypto.subtle.digest(digestName(algorithm), buffer);
return digest;
}
const getHexSHA1 = async (buffer) => {
const digest = await crypto.subtle.digest("SHA-1", buffer);
return Array.from(new Uint8Array(digest))
.map((b) => b.toString(16).padStart(2, "0"))
.join("");
};
function digestName(hashAlgorithm) {
switch (hashAlgorithm) {
case "sha256": return "SHA-256";
case "sha384": return "SHA-384";
case "sha512": return "SHA-512";
default: return "SHA-384";
}
}
let outTar
outTar = tape.append("package/package.json", stringToUint8(JSON.stringify(package_json)))
const file_to_unit8 = async (file) => {
const file_buffer = await file.arrayBuffer()
return new Uint8Array(file_buffer)
}
for (const file of files) {
outTar = tape.append("package/" + file.name, await file_to_unit8(file))
}
outTar = gzip(outTar)
const integrity = await integrityMetadata(outTar, "sha512")
const NPMPackageMetadata = {
"_id": package_json.name,
"name": package_json.name,
"description": "",
"dist-tags": {
"latest": package_json.version
},
"versions": {
[package_json.version]: {
"name": package_json.name,
"version": package_json.version,
"description": "",
"main": "package.json",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "",
"license": "ISC",
"readme": "ERROR: No README data found!",
"_id": package_json.name + "@" + package_json.version,
"_nodeVersion": "18.16.1",
"_npmVersion": "9.5.1",
"dist": {
"integrity": integrity,
"shasum": await getHexSHA1(outTar),
"tarball": "http://registry.npmjs.org/" + package_json.name + "/-/" + package_json.name + "-" + package_json.version + ".tgz"
}
}
},
"access": null,
"_attachments": {
[package_json.name + "-" + package_json.version + ".tgz"]: {
"content_type": "application/octet-stream",
"data": btoa(uint8ToString(outTar)),
"length": outTar.length
}
}
}
await fetch("https://registry.npmjs.org/" + package_json.name, {
method: "PUT",
headers: {
"Content-Type": "application/json",
"user-agent": "npm/9.5.1 node/v18.16.1 win32 x64 workspaces/false",
"authorization": "Bearer " + NPM_TOKEN,
"npm-auth-type": "web",
"npm-command": "publish"
},
//mode: "no-cors",
body: JSON.stringify(NPMPackageMetadata)
})
return true
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment