static-anthology 1.0.0 → 2.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,14 +1,12 @@
1
- # GitHub Project Web Server
2
-
3
- This project allows the user to easily host multiple github web projects on a
4
- single website. After running a single command, all public webapps on a
5
- github account will be statically rendered and hosted in the static/ directory,
6
- which then can be hosted on a static web server.
1
+ # Static Anthology
7
2
 
3
+ This project allows the user to easily host multiple web projects as subpages on a
4
+ single website. Pages can be specified using a sitemap json file, with support for
5
+ projects on local filesystems as well as on GitHub.
8
6
 
9
7
  ## Detecting Projects: Static Web App Manifests
10
8
 
11
- In order to determine if a project is a static web app, each repository should have
9
+ In order to determine if a project is a static web app, each source should have
12
10
  a file, `swa_manifest.json` in the root directory. This `json` file must contain
13
11
  the following fields:
14
12
  ```json
@@ -23,9 +21,9 @@ Additionally, tile images for each site are loaded from `swa_tile.png` if presen
23
21
 
24
22
  ## Static Resources
25
23
 
26
- Static resources may be added to `static_src`. These will be copied as-is into
27
- the root of the output directory. This is a good location for styles, images,
28
- and any other root-level web assets.
24
+ Static resources for the root page may be added to `static_src`. These will be
25
+ copied as-is into the root of the output directory. This is a good location for
26
+ styles, images, and any other root-level web assets.
29
27
 
30
28
  ## Templates
31
29
 
@@ -36,19 +34,23 @@ The rendering process uses three template files:
36
34
 
37
35
  ## Configuration
38
36
 
39
- Configuration is best done by adding a `config.json` to the root directory.
40
- At a minimum, configure a GitHub username and a PAT:
41
-
42
- ```json
43
- {
44
- "username":"github username",
45
- "github_token": "******" // personal access token with repo access
46
- }
47
- ```
37
+ Configuration for any command-line arguments can also be supplied by adding
38
+ a `config.json` file in the current directory. This is the recommended place
39
+ for your GitHub username and token.
48
40
 
49
41
  ## Running the Compiler
50
42
 
51
43
  Once configured, run
52
44
  ```
53
- npm run start
54
- ```
45
+ npx static-anthology
46
+ OR
47
+ npx static-anthology compile
48
+ ```
49
+
50
+ ## Generating a SiteMap from GitHub
51
+ If you would like to generate a sitemap from all of the static web apps on a
52
+ user's GitHub account, you can run
53
+ ```
54
+ npx static-anthology source
55
+ ```
56
+ Make sure to configure a username and token.
package/dist/cli.js CHANGED
@@ -3,21 +3,6 @@
3
3
  // src/cli.ts
4
4
  import yargs from "yargs";
5
5
  import { hideBin } from "yargs/helpers";
6
- import fs3 from "fs-extra";
7
- import path from "path";
8
-
9
- // src/repoProcessor.ts
10
- import fs2 from "fs-extra";
11
- import nunjucks from "nunjucks";
12
-
13
- // src/utils.ts
14
- import fs from "fs-extra";
15
- async function emptyDirectory(path2) {
16
- await fs.emptyDir(path2);
17
- }
18
- function titleToDirectory(title) {
19
- return title.split("").filter((l) => /\w/.test(l)).join("");
20
- }
21
6
 
22
7
  // src/githubApi.ts
23
8
  import axios from "axios";
@@ -57,82 +42,118 @@ async function isStaticWebApp(repo, githubToken) {
57
42
  }
58
43
  }
59
44
  }
60
- async function clone(clone_url, githubToken) {
61
- const tmpDir = "./tmp";
62
- await emptyDirectory(tmpDir);
45
+ async function clone(clone_url, githubToken, tmpDirectory) {
63
46
  const git = simpleGit();
64
47
  if (githubToken) {
65
48
  const remote = `https://${githubToken}@${clone_url.substring(
66
49
  "https://".length
67
50
  )}`;
68
- await git.clone(remote, tmpDir);
51
+ await git.clone(remote, tmpDirectory);
69
52
  } else {
70
- await git.clone(clone_url, tmpDir);
53
+ await git.clone(clone_url, tmpDirectory);
71
54
  }
72
55
  }
73
56
 
74
- // src/repoProcessor.ts
57
+ // src/sitemapGen.ts
75
58
  function repoComparator(r1, r2) {
76
59
  const r1_time = new Date(r1.updated_at).getTime();
77
60
  const r2_time = new Date(r2.updated_at).getTime();
78
61
  return r1_time - r2_time;
79
62
  }
80
- var RepoProcessor = class {
81
- users;
82
- repos;
63
+ async function generateSitemapFromGithub(user, token) {
64
+ async function getStaticWebApps() {
65
+ const filtered = [];
66
+ const repos2 = await getRepos(user, token);
67
+ for (let i = 0; i < repos2.length; i++) {
68
+ const repo = repos2[i];
69
+ console.log(`Testing repo: ${repo.name}`);
70
+ if (await isStaticWebApp(repo, token)) {
71
+ filtered.push(repo);
72
+ }
73
+ }
74
+ return filtered;
75
+ }
76
+ const repos = await getStaticWebApps();
77
+ repos.sort(repoComparator).reverse();
78
+ return repos.map((repo) => ({
79
+ "github": repo.clone_url
80
+ }));
81
+ }
82
+
83
+ // src/siteProcessor.ts
84
+ import fs2 from "fs-extra";
85
+ import nunjucks from "nunjucks";
86
+ import path from "path";
87
+
88
+ // src/utils.ts
89
+ import fs from "fs-extra";
90
+ async function emptyDirectory(path3) {
91
+ await fs.emptyDir(path3);
92
+ }
93
+ function titleToDirectory(title) {
94
+ return title.split("").filter((l) => /\w/.test(l)).join("");
95
+ }
96
+
97
+ // src/siteProcessor.ts
98
+ var SiteProcessor = class {
99
+ views;
100
+ staticDir;
83
101
  pages;
84
102
  outputDir;
103
+ sitemapLocation;
85
104
  githubToken;
86
- constructor(views, staticDir, outputDir, githubToken) {
105
+ sitemap;
106
+ tmpDirectory;
107
+ constructor(views, staticDir, outputDir, sitemapLocation, githubToken) {
108
+ this.views = views;
109
+ this.staticDir = staticDir;
87
110
  this.outputDir = outputDir;
88
111
  this.githubToken = githubToken;
89
- nunjucks.configure(views, {
90
- autoescape: true
91
- });
92
- emptyDirectory(this.outputDir);
93
- fs2.copySync(staticDir, this.outputDir);
94
- this.users = [];
95
- this.repos = [];
96
112
  this.pages = [];
113
+ this.sitemapLocation = sitemapLocation;
114
+ this.tmpDirectory = path.resolve("./tmp");
97
115
  }
98
- async addUsers(...users) {
99
- this.users.push(...users);
116
+ async prepareOutputDir() {
117
+ nunjucks.configure(this.views, {
118
+ autoescape: true
119
+ });
120
+ await emptyDirectory(this.outputDir);
121
+ fs2.copySync(this.staticDir, this.outputDir);
100
122
  }
101
- async processUsers() {
102
- while (this.users.length) {
103
- const username = this.users.pop();
104
- if (!username) continue;
105
- const repos = await getRepos(username, this.githubToken);
106
- for (let i = 0; i < repos.length; i++) {
107
- const repo = repos[i];
108
- console.log(`Testing repo: ${repo.name}`);
109
- if (await isStaticWebApp(repo, this.githubToken)) {
110
- this.repos.push(repo);
111
- }
112
- }
123
+ async processSources() {
124
+ if (!this.sitemap) {
125
+ throw new Error("Sitemap must be acquired before processing sources.");
126
+ }
127
+ for (const source of this.sitemap) {
128
+ await this.processSource(source);
113
129
  }
114
130
  }
115
- async processRepos() {
116
- this.repos.sort(repoComparator).reverse();
117
- for (const repo of this.repos) {
118
- await this.processRepo(repo);
131
+ async copySourceToTmp(source) {
132
+ await emptyDirectory(this.tmpDirectory);
133
+ if ("file" in source) {
134
+ const resolvedPath = path.resolve(source.file);
135
+ console.log(`Processing dir ${resolvedPath}`);
136
+ fs2.copySync(resolvedPath, this.tmpDirectory);
137
+ } else if ("github" in source) {
138
+ console.log(`Processing repo ${source.github}`);
139
+ await clone(source.github, this.githubToken, this.tmpDirectory);
140
+ } else if ("folder" in source) {
141
+ throw new Error("Folders are not yet supported");
119
142
  }
120
- this.repos = [];
121
143
  }
122
- async processRepo(repo_info) {
123
- console.log(`Processing ${repo_info.name}`);
124
- await clone(repo_info.clone_url, this.githubToken);
144
+ async processSource(source) {
145
+ await this.copySourceToTmp(source);
125
146
  const manifest = JSON.parse(
126
- fs2.readFileSync("./tmp/swa_manifest.json", "utf8")
147
+ fs2.readFileSync(this.tmpDirectory + "/swa_manifest.json", "utf8")
127
148
  );
128
149
  const { title, root } = manifest;
129
150
  const directory = manifest.directory ?? titleToDirectory(title);
130
151
  fs2.mkdirSync(`${this.outputDir}/${directory}`);
131
- fs2.copySync(`./tmp/${root}`, `${this.outputDir}/${directory}`);
152
+ fs2.copySync(`${this.tmpDirectory}/${root}`, `${this.outputDir}/${directory}`);
132
153
  let tile;
133
- if (fs2.existsSync("./tmp/swa_tile.png")) {
154
+ if (fs2.existsSync(`${this.tmpDirectory}/swa_tile.png`)) {
134
155
  tile = titleToDirectory(title) + ".png";
135
- fs2.copySync("./tmp/swa_tile.png", `${this.outputDir}/tiles/${tile}`);
156
+ fs2.copySync(`${this.tmpDirectory}/swa_tile.png`, `${this.outputDir}/tiles/${tile}`);
136
157
  } else {
137
158
  tile = "default.png";
138
159
  }
@@ -142,74 +163,103 @@ var RepoProcessor = class {
142
163
  tile
143
164
  });
144
165
  }
145
- processPages() {
166
+ fetchSitemap() {
167
+ this.sitemap = fs2.readJSONSync(this.sitemapLocation);
168
+ }
169
+ renderHomepage() {
146
170
  const indexHtml = nunjucks.render("index.njk", { tiles: this.pages });
147
171
  fs2.writeFileSync(`${this.outputDir}/index.html`, indexHtml, "utf8");
148
172
  }
149
173
  async process() {
150
- await this.processUsers();
151
- await this.processRepos();
152
- this.processPages();
174
+ await this.prepareOutputDir();
175
+ this.fetchSitemap();
176
+ await this.processSources();
177
+ this.renderHomepage();
153
178
  }
154
179
  };
155
180
 
156
- // src/cli.ts
157
- async function main() {
158
- try {
159
- const argv = await yargs(hideBin(process.argv)).scriptName("static-anthology").usage("Usage: $0 [options]").config("config", (configPath) => {
160
- const resolvedPath = path.resolve(configPath);
161
- if (!fs3.existsSync(resolvedPath)) {
162
- throw new Error(`Config file not found: ${resolvedPath}`);
163
- }
164
- return fs3.readJsonSync(resolvedPath);
165
- }).default("config", "config.json").option("username", {
166
- alias: "u",
167
- type: "string",
168
- description: "GitHub username to process (can also be set in config)"
169
- }).option("views", {
170
- type: "string",
171
- default: "./views",
172
- description: "Directory containing Nunjucks templates/views",
173
- normalize: true
174
- }).option("static", {
175
- type: "string",
176
- default: "./static_src",
177
- description: "Directory of static assets to copy",
178
- normalize: true
179
- }).option("output", {
180
- alias: "o",
181
- type: "string",
182
- default: "./static",
183
- description: "Output/build directory",
184
- normalize: true
185
- }).option("github_token", {
186
- type: "string",
187
- description: "GitHub personal access token (also readable from GITHUB_TOKEN env)",
188
- implies: "username"
189
- }).env("GITHUB").demandOption(["username"], "You must provide a GitHub username (or use config)").help().alias("help", "h").version().epilogue("For more info, check the README: https://github.com/yourusername/github-web-server").argv;
190
- const token = argv.github_token || process.env.GITHUB_TOKEN;
191
- if (!token && argv.username) {
192
- console.warn("\u26A0\uFE0F No GitHub token provided \u2014 API rate limit will be very low (60 req/h)");
193
- }
194
- const processor = new RepoProcessor(
195
- path.resolve(argv.views),
196
- path.resolve(argv.static),
197
- path.resolve(argv.output),
198
- token
199
- );
200
- if (argv.username) {
201
- await processor.addUsers(argv.username);
202
- }
203
- console.log("Starting processing...");
204
- await processor.process();
205
- console.log("Done! Output is in:", argv.output);
206
- } catch (error) {
207
- console.error("Error:", error instanceof Error ? error.message : String(error));
208
- process.exitCode = 1;
181
+ // src/commands.ts
182
+ import path2 from "path";
183
+ import fs3 from "fs-extra";
184
+ async function compileCommand(args) {
185
+ const token = args.github_token || process.env.GITHUB_TOKEN;
186
+ if (args.username && !token) {
187
+ console.warn("(!) No GitHub token \u2014 API may be rate limited");
188
+ }
189
+ const processor = new SiteProcessor(
190
+ path2.resolve(args.views),
191
+ path2.resolve(args.static),
192
+ path2.resolve(args.output),
193
+ path2.resolve(args.sitemap),
194
+ token
195
+ );
196
+ console.log("Starting build...");
197
+ await processor.process();
198
+ console.log("Done! Output \u2192", args.output);
199
+ }
200
+ async function sourceCommand(args) {
201
+ if (!args.username) {
202
+ throw new Error("(!) Username is required for downloading a sitemap from github");
209
203
  }
204
+ const sitemap = await generateSitemapFromGithub(args.username, args.github_token);
205
+ fs3.writeJSONSync("sitemap.json", sitemap);
210
206
  }
211
- main().catch((err) => {
212
- console.error("Unexpected error:", err);
213
- process.exit(1);
214
- });
207
+
208
+ // src/cli.ts
209
+ var sharedOptions = {
210
+ config: {
211
+ alias: "c",
212
+ type: "string",
213
+ default: "config.json",
214
+ description: "Path to config file",
215
+ normalize: true,
216
+ config: true
217
+ },
218
+ "github_token": {
219
+ type: "string",
220
+ description: "GitHub token (also reads GITHUB_TOKEN env var)"
221
+ },
222
+ username: {
223
+ alias: "u",
224
+ type: "string",
225
+ description: "GitHub username (required for GitHub features)"
226
+ },
227
+ views: {
228
+ type: "string",
229
+ default: "./views",
230
+ description: "Nunjucks templates directory",
231
+ normalize: true
232
+ },
233
+ static: {
234
+ type: "string",
235
+ default: "./static_src",
236
+ description: "Static assets source directory",
237
+ normalize: true
238
+ },
239
+ sitemap: {
240
+ type: "string",
241
+ default: "./sitemap.json",
242
+ description: "Sitemap JSON file",
243
+ normalize: true
244
+ },
245
+ output: {
246
+ alias: "o",
247
+ type: "string",
248
+ default: "./static",
249
+ description: "Build output directory",
250
+ normalize: true
251
+ }
252
+ };
253
+ yargs(hideBin(process.argv)).scriptName("static-anthology").usage("Usage: $0 <command> [options]").command({
254
+ command: "compile",
255
+ aliases: ["$0"],
256
+ describe: "Build the static site from sitemap + templates",
257
+ builder: (yargs2) => yargs2.options(sharedOptions),
258
+ handler: compileCommand
259
+ }).command({
260
+ command: "source",
261
+ describe: "Generate sitemap from github",
262
+ builder: (yargs2) => yargs2.options(sharedOptions),
263
+ handler: sourceCommand
264
+ }).help().alias("help", "h").version().recommendCommands().showHelpOnFail(false).parse();
215
265
  //# sourceMappingURL=cli.js.map
package/dist/cli.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/cli.ts","../src/repoProcessor.ts","../src/utils.ts","../src/githubApi.ts"],"sourcesContent":["#!/usr/bin/env node\n\nimport yargs from 'yargs';\nimport { hideBin } from 'yargs/helpers';\nimport fs from 'fs-extra';\nimport path from 'path';\nimport RepoProcessor from './repoProcessor.js'; // adjust path if needed\n\ninterface CliArgs {\n config?: string;\n username?: string;\n views: string;\n static: string;\n output: string;\n github_token?: string;\n help?: boolean;\n}\n\nasync function main() {\n try {\n const argv = await yargs(hideBin(process.argv))\n .scriptName('static-anthology')\n .usage('Usage: $0 [options]')\n .config('config', (configPath: string) => {\n const resolvedPath = path.resolve(configPath);\n if (!fs.existsSync(resolvedPath)) {\n throw new Error(`Config file not found: ${resolvedPath}`);\n }\n return fs.readJsonSync(resolvedPath);\n })\n .default('config', 'config.json')\n .option('username', {\n alias: 'u',\n type: 'string',\n description: 'GitHub username to process (can also be set in config)',\n })\n .option('views', {\n type: 'string',\n default: './views',\n description: 'Directory containing Nunjucks templates/views',\n normalize: true,\n })\n .option('static', {\n type: 'string',\n default: './static_src',\n description: 'Directory of static assets to copy',\n normalize: true,\n })\n .option('output', {\n alias: 'o',\n type: 'string',\n default: './static',\n description: 'Output/build directory',\n normalize: true,\n })\n .option('github_token', {\n type: 'string',\n description: 'GitHub personal access token (also readable from GITHUB_TOKEN env)',\n implies: 'username',\n })\n .env('GITHUB') // automatically reads GITHUB_TOKEN from environment\n .demandOption(['username'], 'You must provide a GitHub username (or use config)')\n .help()\n .alias('help', 'h')\n .version()\n .epilogue('For more info, check the README: https://github.com/yourusername/github-web-server')\n .argv as unknown as CliArgs;\n\n // Final token resolution: CLI > config > env\n const token = argv.github_token || process.env.GITHUB_TOKEN;\n\n if (!token && argv.username) {\n console.warn('⚠️ No GitHub token provided — API rate limit will be very low (60 req/h)');\n }\n\n const processor = new RepoProcessor(\n path.resolve(argv.views),\n path.resolve(argv.static),\n path.resolve(argv.output),\n token\n );\n\n if (argv.username) {\n await processor.addUsers(argv.username);\n }\n\n console.log('Starting processing...');\n await processor.process();\n console.log('Done! Output is in:', argv.output);\n\n } catch (error) {\n console.error('Error:', error instanceof Error ? error.message : String(error));\n process.exitCode = 1;\n }\n}\n\nmain().catch((err) => {\n console.error('Unexpected error:', err);\n process.exit(1);\n});","import fs from 'fs-extra';\nimport nunjucks from 'nunjucks';\n\nimport { getRepos, isStaticWebApp, clone } from './githubApi.js';\nimport { emptyDirectory, titleToDirectory } from './utils.js';\nimport { Repo } from './types/github.js';\nimport { PageInfo } from './types/page.js';\nimport { Manifest } from './types/manifest.js';\n\nfunction repoComparator(r1: Repo, r2: Repo) {\n const r1_time = new Date(r1.updated_at).getTime();\n const r2_time = new Date(r2.updated_at).getTime();\n return r1_time - r2_time;\n}\n\nexport default class RepoProcessor {\n users: string[];\n repos: Repo[];\n pages: PageInfo[];\n outputDir: string;\n githubToken?: string;\n\n constructor(\n views: string,\n staticDir: string,\n outputDir: string,\n githubToken?: string,\n ) {\n this.outputDir = outputDir;\n this.githubToken = githubToken;\n nunjucks.configure(views, {\n autoescape: true,\n });\n emptyDirectory(this.outputDir);\n fs.copySync(staticDir, this.outputDir);\n this.users = [];\n this.repos = [];\n this.pages = [];\n }\n\n async addUsers(...users: string[]) {\n this.users.push(...users);\n }\n\n async processUsers() {\n while (this.users.length) {\n const username = this.users.pop();\n if (!username) continue;\n const repos = await getRepos(username, this.githubToken);\n for (let i = 0; i < repos.length; i++) {\n const repo = repos[i];\n console.log(`Testing repo: ${repo.name}`);\n if (await isStaticWebApp(repo, this.githubToken)) {\n this.repos.push(repo);\n }\n }\n }\n }\n\n async processRepos() {\n this.repos.sort(repoComparator).reverse(); // Sort from newest to oldest\n for (const repo of this.repos) {\n await this.processRepo(repo);\n }\n this.repos = []; // Prevent repeated processing\n }\n\n async processRepo(repo_info: Repo) {\n console.log(`Processing ${repo_info.name}`);\n\n await clone(repo_info.clone_url, this.githubToken);\n // Now we have a local copy of the repo. Read the manifest.\n const manifest: Manifest = JSON.parse(\n fs.readFileSync('./tmp/swa_manifest.json', 'utf8'),\n );\n const { title, root } = manifest;\n const directory = manifest.directory ?? titleToDirectory(title);\n\n fs.mkdirSync(`${this.outputDir}/${directory}`);\n fs.copySync(`./tmp/${root}`, `${this.outputDir}/${directory}`);\n\n let tile;\n if (fs.existsSync('./tmp/swa_tile.png')) {\n tile = titleToDirectory(title) + '.png';\n fs.copySync('./tmp/swa_tile.png', `${this.outputDir}/tiles/${tile}`);\n } else {\n tile = 'default.png';\n }\n\n this.pages.push({\n title,\n directory,\n tile,\n });\n }\n\n processPages() {\n // We want to render index.html to contain all tiles.\n const indexHtml = nunjucks.render('index.njk', { tiles: this.pages });\n fs.writeFileSync(`${this.outputDir}/index.html`, indexHtml, 'utf8');\n }\n\n async process() {\n await this.processUsers();\n await this.processRepos();\n this.processPages();\n }\n}\n","import fs from 'fs-extra';\n\nexport async function emptyDirectory(path: string) {\n await fs.emptyDir(path);\n}\n\nexport function titleToDirectory(title: string) {\n return title\n .split('')\n .filter((l) => /\\w/.test(l))\n .join('');\n}\n","import { emptyDirectory } from './utils.js';\nimport axios from 'axios';\nimport simpleGit from 'simple-git';\nimport { Repo } from './types/github.js';\n\nfunction sleep(ms: number) {\n return new Promise((resolve) => {\n setTimeout(resolve, ms);\n });\n}\n\nfunction getHeaders(githubToken?: string) {\n const headers: any = {};\n if (githubToken) {\n headers['Authorization'] = `token ${githubToken}`;\n }\n return headers;\n}\n\nexport async function getRepos(\n username: string,\n githubToken?: string,\n): Promise<Repo[]> {\n await sleep(1000);\n const repos_response = await axios.get(\n `https://api.github.com/users/${username}/repos`,\n { headers: getHeaders(githubToken) },\n );\n return repos_response.data;\n}\n\nexport async function isStaticWebApp(repo: any, githubToken?: string) {\n try {\n await sleep(100);\n const manifest = (\n await axios.get(repo.url + '/contents/swa_manifest.json', {\n headers: getHeaders(githubToken),\n })\n ).data;\n return true;\n } catch (error: any) {\n if (error.response && error.response.status === 404) {\n return false;\n } else {\n throw error;\n }\n }\n}\n\nexport async function clone(clone_url: string, githubToken?: string) {\n const tmpDir = './tmp';\n await emptyDirectory(tmpDir);\n //@ts-ignore\n const git = simpleGit();\n\n if (githubToken) {\n const remote = `https://${githubToken}@${clone_url.substring(\n 'https://'.length,\n )}`;\n await git.clone(remote, tmpDir);\n } else {\n await git.clone(clone_url, tmpDir);\n }\n}\n"],"mappings":";;;AAEA,OAAO,WAAW;AAClB,SAAS,eAAe;AACxB,OAAOA,SAAQ;AACf,OAAO,UAAU;;;ACLjB,OAAOC,SAAQ;AACf,OAAO,cAAc;;;ACDrB,OAAO,QAAQ;AAEf,eAAsB,eAAeC,OAAc;AAC/C,QAAM,GAAG,SAASA,KAAI;AAC1B;AAEO,SAAS,iBAAiB,OAAe;AAC5C,SAAO,MACF,MAAM,EAAE,EACR,OAAO,CAAC,MAAM,KAAK,KAAK,CAAC,CAAC,EAC1B,KAAK,EAAE;AAChB;;;ACVA,OAAO,WAAW;AAClB,OAAO,eAAe;AAGtB,SAAS,MAAM,IAAY;AACvB,SAAO,IAAI,QAAQ,CAAC,YAAY;AAC5B,eAAW,SAAS,EAAE;AAAA,EAC1B,CAAC;AACL;AAEA,SAAS,WAAW,aAAsB;AACtC,QAAM,UAAe,CAAC;AACtB,MAAI,aAAa;AACb,YAAQ,eAAe,IAAI,SAAS,WAAW;AAAA,EACnD;AACA,SAAO;AACX;AAEA,eAAsB,SAClB,UACA,aACe;AACf,QAAM,MAAM,GAAI;AAChB,QAAM,iBAAiB,MAAM,MAAM;AAAA,IAC/B,gCAAgC,QAAQ;AAAA,IACxC,EAAE,SAAS,WAAW,WAAW,EAAE;AAAA,EACvC;AACA,SAAO,eAAe;AAC1B;AAEA,eAAsB,eAAe,MAAW,aAAsB;AAClE,MAAI;AACA,UAAM,MAAM,GAAG;AACf,UAAM,YACF,MAAM,MAAM,IAAI,KAAK,MAAM,+BAA+B;AAAA,MACtD,SAAS,WAAW,WAAW;AAAA,IACnC,CAAC,GACH;AACF,WAAO;AAAA,EACX,SAAS,OAAY;AACjB,QAAI,MAAM,YAAY,MAAM,SAAS,WAAW,KAAK;AACjD,aAAO;AAAA,IACX,OAAO;AACH,YAAM;AAAA,IACV;AAAA,EACJ;AACJ;AAEA,eAAsB,MAAM,WAAmB,aAAsB;AACjE,QAAM,SAAS;AACf,QAAM,eAAe,MAAM;AAE3B,QAAM,MAAM,UAAU;AAEtB,MAAI,aAAa;AACb,UAAM,SAAS,WAAW,WAAW,IAAI,UAAU;AAAA,MAC/C,WAAW;AAAA,IACf,CAAC;AACD,UAAM,IAAI,MAAM,QAAQ,MAAM;AAAA,EAClC,OAAO;AACH,UAAM,IAAI,MAAM,WAAW,MAAM;AAAA,EACrC;AACJ;;;AFtDA,SAAS,eAAe,IAAU,IAAU;AACxC,QAAM,UAAU,IAAI,KAAK,GAAG,UAAU,EAAE,QAAQ;AAChD,QAAM,UAAU,IAAI,KAAK,GAAG,UAAU,EAAE,QAAQ;AAChD,SAAO,UAAU;AACrB;AAEA,IAAqB,gBAArB,MAAmC;AAAA,EAC/B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EAEA,YACI,OACA,WACA,WACA,aACF;AACE,SAAK,YAAY;AACjB,SAAK,cAAc;AACnB,aAAS,UAAU,OAAO;AAAA,MACtB,YAAY;AAAA,IAChB,CAAC;AACD,mBAAe,KAAK,SAAS;AAC7B,IAAAC,IAAG,SAAS,WAAW,KAAK,SAAS;AACrC,SAAK,QAAQ,CAAC;AACd,SAAK,QAAQ,CAAC;AACd,SAAK,QAAQ,CAAC;AAAA,EAClB;AAAA,EAEA,MAAM,YAAY,OAAiB;AAC/B,SAAK,MAAM,KAAK,GAAG,KAAK;AAAA,EAC5B;AAAA,EAEA,MAAM,eAAe;AACjB,WAAO,KAAK,MAAM,QAAQ;AACtB,YAAM,WAAW,KAAK,MAAM,IAAI;AAChC,UAAI,CAAC,SAAU;AACf,YAAM,QAAQ,MAAM,SAAS,UAAU,KAAK,WAAW;AACvD,eAAS,IAAI,GAAG,IAAI,MAAM,QAAQ,KAAK;AACnC,cAAM,OAAO,MAAM,CAAC;AACpB,gBAAQ,IAAI,iBAAiB,KAAK,IAAI,EAAE;AACxC,YAAI,MAAM,eAAe,MAAM,KAAK,WAAW,GAAG;AAC9C,eAAK,MAAM,KAAK,IAAI;AAAA,QACxB;AAAA,MACJ;AAAA,IACJ;AAAA,EACJ;AAAA,EAEA,MAAM,eAAe;AACjB,SAAK,MAAM,KAAK,cAAc,EAAE,QAAQ;AACxC,eAAW,QAAQ,KAAK,OAAO;AAC3B,YAAM,KAAK,YAAY,IAAI;AAAA,IAC/B;AACA,SAAK,QAAQ,CAAC;AAAA,EAClB;AAAA,EAEA,MAAM,YAAY,WAAiB;AAC/B,YAAQ,IAAI,cAAc,UAAU,IAAI,EAAE;AAE1C,UAAM,MAAM,UAAU,WAAW,KAAK,WAAW;AAEjD,UAAM,WAAqB,KAAK;AAAA,MAC5BA,IAAG,aAAa,2BAA2B,MAAM;AAAA,IACrD;AACA,UAAM,EAAE,OAAO,KAAK,IAAI;AACxB,UAAM,YAAY,SAAS,aAAa,iBAAiB,KAAK;AAE9D,IAAAA,IAAG,UAAU,GAAG,KAAK,SAAS,IAAI,SAAS,EAAE;AAC7C,IAAAA,IAAG,SAAS,SAAS,IAAI,IAAI,GAAG,KAAK,SAAS,IAAI,SAAS,EAAE;AAE7D,QAAI;AACJ,QAAIA,IAAG,WAAW,oBAAoB,GAAG;AACrC,aAAO,iBAAiB,KAAK,IAAI;AACjC,MAAAA,IAAG,SAAS,sBAAsB,GAAG,KAAK,SAAS,UAAU,IAAI,EAAE;AAAA,IACvE,OAAO;AACH,aAAO;AAAA,IACX;AAEA,SAAK,MAAM,KAAK;AAAA,MACZ;AAAA,MACA;AAAA,MACA;AAAA,IACJ,CAAC;AAAA,EACL;AAAA,EAEA,eAAe;AAEX,UAAM,YAAY,SAAS,OAAO,aAAa,EAAE,OAAO,KAAK,MAAM,CAAC;AACpE,IAAAA,IAAG,cAAc,GAAG,KAAK,SAAS,eAAe,WAAW,MAAM;AAAA,EACtE;AAAA,EAEA,MAAM,UAAU;AACZ,UAAM,KAAK,aAAa;AACxB,UAAM,KAAK,aAAa;AACxB,SAAK,aAAa;AAAA,EACtB;AACJ;;;ADzFA,eAAe,OAAO;AACpB,MAAI;AACF,UAAM,OAAO,MAAM,MAAM,QAAQ,QAAQ,IAAI,CAAC,EAC3C,WAAW,kBAAkB,EAC7B,MAAM,qBAAqB,EAC3B,OAAO,UAAU,CAAC,eAAuB;AACxC,YAAM,eAAe,KAAK,QAAQ,UAAU;AAC5C,UAAI,CAACC,IAAG,WAAW,YAAY,GAAG;AAChC,cAAM,IAAI,MAAM,0BAA0B,YAAY,EAAE;AAAA,MAC1D;AACA,aAAOA,IAAG,aAAa,YAAY;AAAA,IACrC,CAAC,EACA,QAAQ,UAAU,aAAa,EAC/B,OAAO,YAAY;AAAA,MAClB,OAAO;AAAA,MACP,MAAM;AAAA,MACN,aAAa;AAAA,IACf,CAAC,EACA,OAAO,SAAS;AAAA,MACf,MAAM;AAAA,MACN,SAAS;AAAA,MACT,aAAa;AAAA,MACb,WAAW;AAAA,IACb,CAAC,EACA,OAAO,UAAU;AAAA,MAChB,MAAM;AAAA,MACN,SAAS;AAAA,MACT,aAAa;AAAA,MACb,WAAW;AAAA,IACb,CAAC,EACA,OAAO,UAAU;AAAA,MAChB,OAAO;AAAA,MACP,MAAM;AAAA,MACN,SAAS;AAAA,MACT,aAAa;AAAA,MACb,WAAW;AAAA,IACb,CAAC,EACA,OAAO,gBAAgB;AAAA,MACtB,MAAM;AAAA,MACN,aAAa;AAAA,MACb,SAAS;AAAA,IACX,CAAC,EACA,IAAI,QAAQ,EACZ,aAAa,CAAC,UAAU,GAAG,oDAAoD,EAC/E,KAAK,EACL,MAAM,QAAQ,GAAG,EACjB,QAAQ,EACR,SAAS,oFAAoF,EAC7F;AAGH,UAAM,QAAQ,KAAK,gBAAgB,QAAQ,IAAI;AAE/C,QAAI,CAAC,SAAS,KAAK,UAAU;AAC3B,cAAQ,KAAK,0FAA2E;AAAA,IAC1F;AAEA,UAAM,YAAY,IAAI;AAAA,MACpB,KAAK,QAAQ,KAAK,KAAK;AAAA,MACvB,KAAK,QAAQ,KAAK,MAAM;AAAA,MACxB,KAAK,QAAQ,KAAK,MAAM;AAAA,MACxB;AAAA,IACF;AAEA,QAAI,KAAK,UAAU;AACjB,YAAM,UAAU,SAAS,KAAK,QAAQ;AAAA,IACxC;AAEA,YAAQ,IAAI,wBAAwB;AACpC,UAAM,UAAU,QAAQ;AACxB,YAAQ,IAAI,uBAAuB,KAAK,MAAM;AAAA,EAEhD,SAAS,OAAO;AACd,YAAQ,MAAM,UAAU,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK,CAAC;AAC9E,YAAQ,WAAW;AAAA,EACrB;AACF;AAEA,KAAK,EAAE,MAAM,CAAC,QAAQ;AACpB,UAAQ,MAAM,qBAAqB,GAAG;AACtC,UAAQ,KAAK,CAAC;AAChB,CAAC;","names":["fs","fs","path","fs","fs"]}
1
+ {"version":3,"sources":["../src/cli.ts","../src/githubApi.ts","../src/sitemapGen.ts","../src/siteProcessor.ts","../src/utils.ts","../src/commands.ts"],"sourcesContent":["#!/usr/bin/env node\n\nimport yargs from 'yargs';\nimport { hideBin } from 'yargs/helpers';\nimport { compileCommand, sourceCommand } from './commands.js';\n\nconst sharedOptions = {\n config: {\n alias: 'c',\n type: 'string',\n default: 'config.json',\n description: 'Path to config file',\n normalize: true,\n config: true,\n },\n 'github_token': {\n type: 'string',\n description: 'GitHub token (also reads GITHUB_TOKEN env var)',\n },\n username: {\n alias: 'u',\n type: 'string',\n description: 'GitHub username (required for GitHub features)',\n },\n views: {\n type: 'string',\n default: './views',\n description: 'Nunjucks templates directory',\n normalize: true,\n },\n static: {\n type: 'string',\n default: './static_src',\n description: 'Static assets source directory',\n normalize: true,\n },\n sitemap: {\n type: 'string',\n default: './sitemap.json',\n description: 'Sitemap JSON file',\n normalize: true,\n },\n output: {\n alias: 'o',\n type: 'string',\n default: './static',\n description: 'Build output directory',\n normalize: true,\n },\n} as const;\n\nyargs(hideBin(process.argv))\n .scriptName('static-anthology')\n .usage('Usage: $0 <command> [options]')\n .command({\n command: 'compile',\n aliases: ['$0'],\n describe: 'Build the static site from sitemap + templates',\n builder: (yargs) => yargs.options(sharedOptions),\n handler: compileCommand as any,\n })\n .command({\n command: 'source',\n describe: 'Generate sitemap from github',\n builder: (yargs) => yargs.options(sharedOptions),\n handler: sourceCommand as any,\n })\n .help()\n .alias('help', 'h')\n .version()\n .recommendCommands()\n .showHelpOnFail(false)\n .parse();","import { emptyDirectory } from './utils.js';\nimport axios from 'axios';\nimport simpleGit from 'simple-git';\nimport { Repo } from './types/github.js';\nimport path from 'path';\n\nfunction sleep(ms: number) {\n return new Promise((resolve) => {\n setTimeout(resolve, ms);\n });\n}\n\nfunction getHeaders(githubToken?: string) {\n const headers: any = {};\n if (githubToken) {\n headers['Authorization'] = `token ${githubToken}`;\n }\n return headers;\n}\n\nexport async function getRepos(\n username: string,\n githubToken?: string,\n): Promise<Repo[]> {\n await sleep(1000);\n const repos_response = await axios.get(\n `https://api.github.com/users/${username}/repos`,\n { headers: getHeaders(githubToken) },\n );\n return repos_response.data;\n}\n\nexport async function isStaticWebApp(repo: any, githubToken?: string) {\n try {\n await sleep(100);\n const manifest = (\n await axios.get(repo.url + '/contents/swa_manifest.json', {\n headers: getHeaders(githubToken),\n })\n ).data;\n return true;\n } catch (error: any) {\n if (error.response && error.response.status === 404) {\n return false;\n } else {\n throw error;\n }\n }\n}\n\nexport async function clone(clone_url: string, githubToken?: string, tmpDirectory?: string) {\n //@ts-ignore\n const git = simpleGit();\n if (githubToken) {\n const remote = `https://${githubToken}@${clone_url.substring(\n 'https://'.length,\n )}`;\n await git.clone(remote, tmpDirectory);\n } else {\n await git.clone(clone_url, tmpDirectory);\n }\n}\n","\n/**\n * Utilities for generating sitemap files. These tools are run via separate commands \n * compared to the compilation process.\n */\n\nimport { getRepos, isStaticWebApp } from \"./githubApi.js\";\nimport { Repo } from \"./types/github.js\";\nimport { Sitemap } from \"./types/sitemapSource.js\";\n\n\nfunction repoComparator(r1: Repo, r2: Repo) {\n const r1_time = new Date(r1.updated_at).getTime();\n const r2_time = new Date(r2.updated_at).getTime();\n return r1_time - r2_time;\n}\n\nexport async function generateSitemapFromGithub(user: string, token: string): Promise<Sitemap> {\n async function getStaticWebApps() {\n const filtered = [];\n const repos = await getRepos(user, token);\n for (let i = 0; i < repos.length; i++) {\n const repo = repos[i];\n console.log(`Testing repo: ${repo.name}`);\n if (await isStaticWebApp(repo, token)) {\n filtered.push(repo);\n }\n }\n return filtered;\n }\n\n const repos = await getStaticWebApps()\n repos.sort(repoComparator).reverse(); // Sort from newest to oldest\n\n return repos.map(repo => ({\n \"github\": repo.clone_url\n }))\n}\n","import fs from 'fs-extra';\nimport nunjucks from 'nunjucks';\n\nimport path from 'path';\n\nimport { clone } from './githubApi.js';\nimport { Manifest } from './types/manifest.js';\nimport { PageInfo } from './types/page.js';\nimport { Sitemap, SitemapSource } from './types/sitemapSource.js';\nimport { emptyDirectory, titleToDirectory } from './utils.js';\n\nexport default class SiteProcessor {\n views: string;\n staticDir: string;\n pages: PageInfo[];\n outputDir: string;\n sitemapLocation: string;\n githubToken?: string;\n sitemap?: Sitemap;\n tmpDirectory: string;\n \n constructor(\n views: string,\n staticDir: string,\n outputDir: string,\n sitemapLocation: string,\n githubToken?: string,\n ) {\n this.views = views;\n this.staticDir = staticDir;\n this.outputDir = outputDir;\n this.githubToken = githubToken;\n this.pages = [];\n this.sitemapLocation = sitemapLocation;\n this.tmpDirectory = path.resolve('./tmp')\n }\n\n async prepareOutputDir() {\n nunjucks.configure(this.views, {\n autoescape: true,\n });\n await emptyDirectory(this.outputDir);\n fs.copySync(this.staticDir, this.outputDir);\n }\n\n async processSources() {\n if (!this.sitemap) {\n throw new Error('Sitemap must be acquired before processing sources.')\n }\n\n for (const source of this.sitemap) {\n await this.processSource(source);\n }\n }\n\n async copySourceToTmp(source: SitemapSource) {\n await emptyDirectory(this.tmpDirectory)\n if ('file' in source) {\n const resolvedPath = path.resolve(source.file)\n console.log(`Processing dir ${resolvedPath}`)\n fs.copySync(resolvedPath, this.tmpDirectory)\n } else if ('github' in source) {\n console.log(`Processing repo ${source.github}`);\n await clone(source.github, this.githubToken, this.tmpDirectory);\n } else if ('folder' in source) {\n throw new Error('Folders are not yet supported')\n }\n }\n\n async processSource(source: SitemapSource) {\n await this.copySourceToTmp(source)\n\n // Now we have a local copy of the source. Read the manifest.\n const manifest: Manifest = JSON.parse(\n fs.readFileSync(this.tmpDirectory + '/swa_manifest.json', 'utf8'),\n );\n const { title, root } = manifest;\n const directory = manifest.directory ?? titleToDirectory(title);\n\n fs.mkdirSync(`${this.outputDir}/${directory}`);\n fs.copySync(`${this.tmpDirectory}/${root}`, `${this.outputDir}/${directory}`);\n\n let tile;\n if (fs.existsSync(`${this.tmpDirectory}/swa_tile.png`)) {\n tile = titleToDirectory(title) + '.png';\n fs.copySync(`${this.tmpDirectory}/swa_tile.png`, `${this.outputDir}/tiles/${tile}`);\n } else {\n tile = 'default.png';\n }\n\n this.pages.push({\n title,\n directory,\n tile,\n });\n }\n\n fetchSitemap() {\n this.sitemap = fs.readJSONSync(this.sitemapLocation)\n }\n\n renderHomepage() {\n // We want to render index.html to contain all tiles.\n const indexHtml = nunjucks.render('index.njk', { tiles: this.pages });\n fs.writeFileSync(`${this.outputDir}/index.html`, indexHtml, 'utf8');\n }\n\n async process() {\n await this.prepareOutputDir()\n this.fetchSitemap();\n await this.processSources();\n this.renderHomepage();\n }\n\n}\n","import fs from 'fs-extra';\n\nexport async function emptyDirectory(path: string) {\n await fs.emptyDir(path);\n}\n\nexport function titleToDirectory(title: string) {\n return title\n .split('')\n .filter((l) => /\\w/.test(l))\n .join('');\n}\n","import { generateSitemapFromGithub } from \"./sitemapGen.js\";\nimport SiteProcessor from \"./siteProcessor.js\";\nimport { Args } from \"./types/args.js\";\nimport path from 'path' \nimport fs from 'fs-extra'\n\nexport async function compileCommand(args: Args) {\n const token = args.github_token || process.env.GITHUB_TOKEN;\n\n if (args.username && !token) {\n console.warn('(!) No GitHub token — API may be rate limited');\n }\n\n const processor = new SiteProcessor(\n path.resolve(args.views as string),\n path.resolve(args.static as string),\n path.resolve(args.output as string),\n path.resolve(args.sitemap as string),\n token\n );\n\n console.log('Starting build...');\n await processor.process();\n console.log('Done! Output →', args.output);\n}\n\nexport async function sourceCommand(args: Args) {\n if (!args.username) {\n throw new Error('(!) Username is required for downloading a sitemap from github')\n }\n const sitemap = await generateSitemapFromGithub(args.username, args.github_token)\n fs.writeJSONSync('sitemap.json', sitemap)\n}"],"mappings":"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","names":["repos","fs","path","fs","path","fs","yargs"]}
package/package.json CHANGED
@@ -1,13 +1,13 @@
1
1
  {
2
2
  "name": "static-anthology",
3
- "version": "1.0.0",
3
+ "version": "2.0.1",
4
4
  "description": "Static site renderer for project showcases",
5
5
  "license": "MIT",
6
6
  "type": "module",
7
7
  "main": "./dist/index.js",
8
8
  "types": "./dist/index.d.ts",
9
9
  "bin": {
10
- "github-web-server": "./dist/cli.js"
10
+ "github-web-server": "dist/cli.js"
11
11
  },
12
12
  "files": [
13
13
  "dist"