Skip to content

Commit

Permalink
refactor: add bin for bunx
Browse files Browse the repository at this point in the history
  • Loading branch information
eknowles committed Aug 19, 2024
1 parent 9f37486 commit 760a607
Show file tree
Hide file tree
Showing 11 changed files with 124 additions and 55 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,4 @@
test.sh
node_modules
coverage/
tilepack
8 changes: 6 additions & 2 deletions .npmignore
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
*.lockb
.husky/
src/
test.sh
tests/
*.sh
.github/
node_modules/
*.gif
eslint.config.mjs
39 changes: 26 additions & 13 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,19 +6,32 @@ Take a XYZ tile URL and pack the tile images into a MBTiles file.

![gif](./pmtiles.gif)

## Installation

1. Homebrew (macOS/Linux)
```bash
brew tap eknowles/tools
brew install tilepack
```
1. Download the latest release from the [releases page](https://github.com/eknowles/tilepack/releases) (Windows, macOS, Linux)
1. Build from source (Requires [Bun](https://bun.sh/))
```bash
git clone git@github.com:eknowles/tilepack.git
bun run build
```
## Installation Options

### Homebrew (macOS/Linux)

```bash
brew tap eknowles/tools
brew install tilepack
```

### Binary

Download the latest release from the [releases page](https://github.com/eknowles/tilepack/releases) (Windows, macOS, Linux)

- darwin (amd64)
- darwin (arm64)
- linux (x64)
- windows (amd64)

### Build from source

Requires [Bun](https://bun.sh/)

```bash
git clone git@github.com:eknowles/tilepack.git
bun run build
```

## Example

Expand Down
6 changes: 5 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
{
"name": "tilepack",
"version": "1.3.0",
"main": "index.js",
"devDependencies": {
"@eslint/js": "^9.9.0",
"@types/bun": "^1.1.6",
Expand All @@ -15,7 +14,12 @@
},
"description": "Scrape XYZ tiles to an mbtiles file",
"private": true,
"main": "./src/TilePack.ts",
"bin": {
"tilepack": "./src/cli.ts"
},
"scripts": {
"start": "bun run src/cli.ts",
"build": "bun build --compile --minify src/cli.ts --outfile tilepack",
"test": "bun test",
"prepare": "husky"
Expand Down
35 changes: 35 additions & 0 deletions src/TilePack.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import { setupDatabase } from "./db";
import { processZoomLevel } from "./tile";
import { parseBoundingBox, BoundingBox } from "./utils";
import { Args } from "./types";

export type TilePackOptions = Omit<Args, "help" | "version">;

export class TilePack {
private readonly options: TilePackOptions;
private readonly bbox: BoundingBox;
private readonly headers: Record<string, string>;

constructor(options: TilePackOptions) {
this.options = options;
this.bbox = parseBoundingBox(this.options.bbox);
this.headers = Object.fromEntries(
this.options.header.map((h) => h.split(":")),
);
}

public async run() {
const db = setupDatabase(this.options.output, this.options, this.bbox);

for (
let zoom = this.options.minzoom;
zoom <= this.options.maxzoom;
zoom++
) {
await processZoomLevel(db, zoom, this.bbox, this.options, this.headers);
}

console.log("Finished processing all zoom levels");
db.close();
}
}
18 changes: 2 additions & 16 deletions src/args.ts
Original file line number Diff line number Diff line change
@@ -1,21 +1,7 @@
import { parseArgs } from "util";
import { Args } from "./types";

export interface CliArgs {
version: boolean;
help: boolean;
output: string;
input: string;
minzoom: number;
maxzoom: number;
bbox: string;
header: string[];
token: string;
retry: number;
format: string;
concurrency: number;
}

export function parseCliArgs(): CliArgs {
export function parseCliArgs(): Args {
const { values } = parseArgs({
args: Bun.argv.slice(2),
options: {
Expand Down
20 changes: 3 additions & 17 deletions src/cli.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
#!/usr/bin/env bun
import { parseCliArgs } from "./args";
import { setupDatabase } from "./db";
import { processZoomLevel } from "./tile";
import { parseBoundingBox } from "./utils";
import { TilePack } from "./TilePack";
import pkg from "../package.json";

const args = parseCliArgs();
Expand All @@ -19,17 +17,5 @@ if (!args.input || !args.bbox) {
process.exit(1);
}

const bbox = parseBoundingBox(args.bbox);
const headers: Record<string, string> = Object.fromEntries(
args.header.map((h) => h.split(":")),
);

const db = setupDatabase(args.output, args, bbox);

(async () => {
for (let zoom = args.minzoom; zoom <= args.maxzoom; zoom++) {
await processZoomLevel(db, zoom, bbox, args, headers);
}
console.log("Finished processing all zoom levels");
db.close();
})();
const tilePack = new TilePack(args);
tilePack.run();
4 changes: 2 additions & 2 deletions src/db.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import { Database } from "bun:sqlite";
import { CliArgs } from "./args";
import { Args } from "./types";
import { BoundingBox } from "./utils";

export type DBArgs = Pick<CliArgs, "format" | "bbox" | "minzoom" | "maxzoom">;
export type DBArgs = Pick<Args, "format" | "bbox" | "minzoom" | "maxzoom">;

export function setupDatabase(
filename: string,
Expand Down
6 changes: 3 additions & 3 deletions src/tile.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { Database } from "bun:sqlite";
import { CliArgs } from "./args";
import { Args } from "./types";
import {
BoundingBox,
createTileUrl,
Expand All @@ -13,7 +13,7 @@ export async function processTile(
zoom: number,
row: number,
column: number,
args: CliArgs,
args: Pick<Args, "input" | "token">,
headers: Record<string, string>,
): Promise<void> {
const insertTile = db.prepare(
Expand Down Expand Up @@ -53,7 +53,7 @@ export async function processZoomLevel(
db: Database,
zoom: number,
bbox: BoundingBox,
args: CliArgs,
args: Pick<Args, "concurrency" | "input" | "token">,
headers: Record<string, string>,
): Promise<void> {
const { minColumn, maxColumn, minRow, maxRow } = zoomBox(zoom, bbox);
Expand Down
37 changes: 37 additions & 0 deletions src/types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
export interface Args {
// Show the version number
version: boolean;

// Show this help message
help: boolean;

// The path where the MBTiles file will be saved (default: output.mbtiles)
output: string;

// The base URL for the XYZ tiles (required)
input: string;

// The minimum zoom level to fetch tiles
minzoom: number;

// The maximum zoom level to fetch tiles
maxzoom: number;

// The bounding box for the tile fetching in the format minLon,minLat,maxLon,maxLat
bbox: string;

// HTTP headers to include in tile requests
header: string[];

// An API token for authenticated requests. Used in input URL
token: string;

// The number of retry attempts for failed requests (default: 0)
retry: number;

// The format of the tiles (e.g., png, jpeg) (default: png)
format: string;

// The number of concurrent requests to fetch tiles (default: 15)
concurrency: number;
}
5 changes: 4 additions & 1 deletion tests/args.test.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
import { describe, it, expect } from "bun:test";
import { parseCliArgs } from "../src/args";

describe("parseCliArgs", () => {
describe("parseArgs", () => {
it("should parse all arguments correctly", () => {
const input = "http://example.com/{z}/{y}/{x}?token={token}";

// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-expect-error
Bun.argv = [
"node",
"script.js",
Expand Down

0 comments on commit 760a607

Please sign in to comment.