Compare commits
No commits in common. "v0.1.0-develop.1" and "v0.0.1" have entirely different histories.
v0.1.0-dev
...
v0.0.1
|
@ -1,13 +0,0 @@
|
||||||
name: Build/Publish
|
|
||||||
|
|
||||||
on:
|
|
||||||
push:
|
|
||||||
branches:
|
|
||||||
- master
|
|
||||||
- develop
|
|
||||||
- develop-*
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
main:
|
|
||||||
uses: lumeweb/github-node-deploy-workflow/.github/workflows/main.yml@master
|
|
||||||
secrets: inherit
|
|
|
@ -1,5 +0,0 @@
|
||||||
{
|
|
||||||
"preset": [
|
|
||||||
"@lumeweb/node-library-preset"
|
|
||||||
]
|
|
||||||
}
|
|
|
@ -1,6 +0,0 @@
|
||||||
# [0.1.0-develop.1](https://git.lumeweb.com/LumeWeb/publish-webapp/compare/v0.0.1...v0.1.0-develop.1) (2023-08-15)
|
|
||||||
|
|
||||||
|
|
||||||
### Features
|
|
||||||
|
|
||||||
* initial version ([5de6422](https://git.lumeweb.com/LumeWeb/publish-webapp/commit/5de6422a16ef9603c713951932019c8299436cb4))
|
|
File diff suppressed because it is too large
Load Diff
38
package.json
38
package.json
|
@ -1,38 +0,0 @@
|
||||||
{
|
|
||||||
"name": "@lumeweb/publish-webapp",
|
|
||||||
"version": "0.1.0-develop.1",
|
|
||||||
"type": "module",
|
|
||||||
"main": "lib/index.js",
|
|
||||||
"bin": "./lib/index.js",
|
|
||||||
"repository": {
|
|
||||||
"type": "git",
|
|
||||||
"url": "gitea@git.lumeweb.com:LumeWeb/publish-webapp.git"
|
|
||||||
},
|
|
||||||
"devDependencies": {
|
|
||||||
"@lumeweb/node-library-preset": "^0.2.7",
|
|
||||||
"@types/mime": "^3.0.1",
|
|
||||||
"@types/prompts": "^2.4.4",
|
|
||||||
"presetter": "*"
|
|
||||||
},
|
|
||||||
"readme": "ERROR: No README data found!",
|
|
||||||
"scripts": {
|
|
||||||
"prepare": "presetter bootstrap",
|
|
||||||
"build": "run build",
|
|
||||||
"semantic-release": "semantic-release"
|
|
||||||
},
|
|
||||||
"dependencies": {
|
|
||||||
"@lumeweb/libweb": "0.2.0-develop.31",
|
|
||||||
"array-from-async": "^3.0.0",
|
|
||||||
"chalk": "^5.3.0",
|
|
||||||
"mime": "^3.0.0",
|
|
||||||
"msgpackr": "^1.9.7",
|
|
||||||
"p-queue": "^7.3.4",
|
|
||||||
"prompts": "^2.4.2"
|
|
||||||
},
|
|
||||||
"files": [
|
|
||||||
"lib"
|
|
||||||
],
|
|
||||||
"publishConfig": {
|
|
||||||
"access": "public"
|
|
||||||
}
|
|
||||||
}
|
|
122
src/index.ts
122
src/index.ts
|
@ -1,122 +0,0 @@
|
||||||
import fs from "fs/promises";
|
|
||||||
import path from "path";
|
|
||||||
import * as process from "process";
|
|
||||||
import fromAsync from "array-from-async";
|
|
||||||
|
|
||||||
import * as util from "util";
|
|
||||||
|
|
||||||
import {
|
|
||||||
hexToBytes,
|
|
||||||
loginActivePortals,
|
|
||||||
maybeInitDefaultPortals,
|
|
||||||
setActivePortalMasterKey,
|
|
||||||
uploadObject,
|
|
||||||
} from "@lumeweb/libweb";
|
|
||||||
|
|
||||||
import chalk from "chalk";
|
|
||||||
|
|
||||||
import mime from "mime";
|
|
||||||
import { pack } from "msgpackr";
|
|
||||||
import PQueue from "p-queue";
|
|
||||||
import prompts from "prompts";
|
|
||||||
|
|
||||||
import type { WebAppMetadata } from "#types.js";
|
|
||||||
|
|
||||||
let key = process.env.PORTAL_PRIVATE_KEY;
|
|
||||||
let dir = process.env.DIR;
|
|
||||||
const parallelUploads = parseInt(process.env.PARALLEL_UPLOADS ?? "0", 10) || 10;
|
|
||||||
|
|
||||||
if (!key) {
|
|
||||||
key = await prompts.prompts.password({
|
|
||||||
name: "private_key",
|
|
||||||
message: "Enter your private key",
|
|
||||||
validate: (prev: string) => prev && prev.length === 64,
|
|
||||||
type: undefined,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!dir) {
|
|
||||||
dir = (await prompts.prompts.text({
|
|
||||||
name: "dir",
|
|
||||||
message: "Enter the directory of the webapp",
|
|
||||||
validate: (prev: string) => prev && prev.length > 0,
|
|
||||||
type: undefined,
|
|
||||||
})) as unknown as string;
|
|
||||||
}
|
|
||||||
|
|
||||||
dir = path.resolve(dir) + "/";
|
|
||||||
|
|
||||||
setActivePortalMasterKey(hexToBytes(key as string));
|
|
||||||
maybeInitDefaultPortals();
|
|
||||||
|
|
||||||
const processedFiles: Array<{ cid: string; file: string; size: number }> = [];
|
|
||||||
const queue = new PQueue({ concurrency: parallelUploads });
|
|
||||||
|
|
||||||
void (await loginActivePortals());
|
|
||||||
|
|
||||||
const files: string[] = await fromAsync(walkSync(dir));
|
|
||||||
|
|
||||||
files.forEach((item) => {
|
|
||||||
void queue.add(async () => processFile(item));
|
|
||||||
});
|
|
||||||
|
|
||||||
await queue.onIdle();
|
|
||||||
|
|
||||||
const metadata: WebAppMetadata = {
|
|
||||||
type: "web_app",
|
|
||||||
paths: {},
|
|
||||||
tryFiles: ["index.html"],
|
|
||||||
};
|
|
||||||
|
|
||||||
processedFiles
|
|
||||||
.sort((a, b) => {
|
|
||||||
if (a.file < b.file) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
if (a.file > b.file) {
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
})
|
|
||||||
.forEach((item) => {
|
|
||||||
metadata.paths[item.file] = {
|
|
||||||
cid: item.cid,
|
|
||||||
contentType: mime.getType(item.file) ?? "application/octet-stream",
|
|
||||||
size: item.size,
|
|
||||||
};
|
|
||||||
});
|
|
||||||
|
|
||||||
const serializedMetadata = pack(metadata);
|
|
||||||
|
|
||||||
const [cid, err] = await uploadObject(serializedMetadata);
|
|
||||||
if (err) {
|
|
||||||
console.error("Failed to publish: ", err);
|
|
||||||
process.exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
console.log(
|
|
||||||
util.format("%s: %s", chalk.green("Web App successfully published"), cid),
|
|
||||||
);
|
|
||||||
|
|
||||||
async function processFile(filePath: string) {
|
|
||||||
const fd = await fs.open(filePath);
|
|
||||||
const size = (await fd.stat()).size;
|
|
||||||
const [cid, err] = await uploadObject(fd.createReadStream(), BigInt(size));
|
|
||||||
if (err) {
|
|
||||||
console.error("Failed to publish: ", err);
|
|
||||||
process.exit(1);
|
|
||||||
}
|
|
||||||
processedFiles.push({ cid, file: filePath.replace(dir as string, ""), size });
|
|
||||||
}
|
|
||||||
|
|
||||||
async function* walkSync(dir: string): AsyncGenerator<string> {
|
|
||||||
const files = await fs.readdir(dir, { withFileTypes: true });
|
|
||||||
for (const file of files) {
|
|
||||||
if (file.isDirectory()) {
|
|
||||||
yield* walkSync(path.join(dir, file.name));
|
|
||||||
} else {
|
|
||||||
yield path.join(dir, file.name);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
23
src/types.ts
23
src/types.ts
|
@ -1,23 +0,0 @@
|
||||||
export interface WebAppMetadata {
|
|
||||||
type: "web_app";
|
|
||||||
name?: string;
|
|
||||||
tryFiles?: string[];
|
|
||||||
errorPages?: {
|
|
||||||
[key: string]: string; // key should match the pattern ^\d{3}$
|
|
||||||
};
|
|
||||||
paths: {
|
|
||||||
[path: string]: PathContent; // path has maxLength 255
|
|
||||||
};
|
|
||||||
extraMetadata?: ExtraMetadata; // I'm assuming this as any since the actual structure isn't provided
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface PathContent {
|
|
||||||
cid: CID; // Assuming CID is another interface or type
|
|
||||||
contentType?: string; // Should match the provided pattern
|
|
||||||
size: number;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Placeholder definitions based on the $ref in the schema.
|
|
||||||
// You should replace these with the actual structures if you have them.
|
|
||||||
export type CID = any;
|
|
||||||
export type ExtraMetadata = any;
|
|
Loading…
Reference in New Issue