Skip to content

Commit

Permalink
refactor normalize headers utility
Browse files Browse the repository at this point in the history
  • Loading branch information
pi0 committed Feb 17, 2023
1 parent 3f1853b commit 02ebb22
Show file tree
Hide file tree
Showing 3 changed files with 58 additions and 30 deletions.
32 changes: 19 additions & 13 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -113,18 +113,18 @@ Import:

```js
// ESM
import { downloadTemplate } from 'giget'
import { downloadTemplate } from "giget";

// CommonJS
const { downloadTemplate } = require('giget')
const { downloadTemplate } = require("giget");
```

### `downloadTemplate(source, options?)`

**Example:**

```js
const { source, dir } = await downloadTemplate('github:unjs/template')
const { source, dir } = await downloadTemplate("github:unjs/template");
```

**Options:**
Expand Down Expand Up @@ -159,31 +159,37 @@ The return value is a promise that resolves to the resolved template.
Using programmatic method, you can make your own custom template providers.

```ts
import type { TemplateProvider } from 'giget'
import type { TemplateProvider } from "giget";

const rainbow: TemplateProvider = async (input, { auth }) => {
return {
name: 'rainbow',
name: "rainbow",
version: input,
headers: { Authorization: auth },
headers: { authorization: auth },
url: `https://rainbow.template/?variant=${input}`,
tar: `https://rainbow.template/dl/rainbow.${input}.tar.gz`
}
}
tar: `https://rainbow.template/dl/rainbow.${input}.tar.gz`,
};
};

const { source, dir } = await downloadRepo('rainbow:one', { providers: { rainbow } })
const { source, dir } = await downloadRepo("rainbow:one", {
providers: { rainbow },
});
```

### Custom Registry Providers

You can define additional [custom registry](#custom-registry) providers using `registryProvider` utility and register to `providers`.

```ts
import { registryProvider } from 'giget'
import { registryProvider } from "giget";

const themes = registryProvider('https://raw.githubusercontent.com/unjs/giget/main/templates')
const themes = registryProvider(
"https://raw.githubusercontent.com/unjs/giget/main/templates"
);

const { source, dir } = await downloadRepo('themes:test', { providers: { themes } })
const { source, dir } = await downloadRepo("themes:test", {
providers: { themes },
});
```

## Related projects
Expand Down
47 changes: 37 additions & 10 deletions src/_utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { spawnSync } from "node:child_process";
import { readFile, writeFile } from "node:fs/promises";
import { homedir } from "node:os";
import { promisify } from "node:util";
import type { Agent } from "node:http";
import { relative, resolve } from "pathe";
import { fetch } from "node-fetch-native";
import createHttpsProxyAgent from "https-proxy-agent";
Expand Down Expand Up @@ -62,16 +63,31 @@ export function debug(...arguments_) {
}

// eslint-disable-next-line no-undef
export async function sendFetch(url: string, options?: RequestInit) {
const proxy =
process.env.HTTPS_PROXY ||
process.env.https_proxy ||
process.env.HTTP_PROXY ||
process.env.http_proxy;
const requestOptions = proxy
? { agent: createHttpsProxyAgent(proxy), ...options }
: options;
return await fetch(url, requestOptions);
interface InternalFetchOptions extends Exclude<RequestInit, "headers"> {
headers?: Record<string, string>;
agent?: Agent;
}

export async function sendFetch(
url: string,
options: InternalFetchOptions = {}
) {
if (!options.agent) {
const proxyEnv =
process.env.HTTPS_PROXY ||
process.env.https_proxy ||
process.env.HTTP_PROXY ||
process.env.http_proxy;
if (proxyEnv) {
options.agent = createHttpsProxyAgent(proxyEnv);
}
}

if (options?.headers) {
options.headers = normalizeHeaders(options.headers as any);
}

return await fetch(url, options);
}

export function cacheDirectory() {
Expand All @@ -80,6 +96,17 @@ export function cacheDirectory() {
: resolve(homedir(), ".cache/giget");
}

export function normalizeHeaders(headers: Record<string, string>) {
const normalized: Record<string, string> = {};
for (const [key, value] of Object.entries(headers)) {
if (!value) {
continue;
}
normalized[key.toLowerCase()] = value;
}
return normalized;
}

// -- Experimental --

export function currentShell() {
Expand Down
9 changes: 2 additions & 7 deletions src/giget.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { existsSync, readdirSync } from "node:fs";
import { extract } from "tar";
import { resolve, dirname } from "pathe";
import { defu } from "defu";
import { cacheDirectory, download, debug } from "./_utils";
import { cacheDirectory, download, debug, normalizeHeaders } from "./_utils";
import { providers } from "./providers";
import { registryProvider } from "./registry";
import type { TemplateInfo, TemplateProvider } from "./types";
Expand Down Expand Up @@ -103,15 +103,10 @@ export async function downloadTemplate(
if (!options.offline) {
await mkdir(dirname(tarPath), { recursive: true });
const s = Date.now();
const templateHeaders = Object.fromEntries(
Object.entries(template.headers || {})
.filter((entry) => entry[1])
.map(([key, value]) => [key.toLowerCase(), value])
);
await download(template.tar, tarPath, {
headers: {
authorization: options.auth ? `Bearer ${options.auth}` : undefined,
...templateHeaders,
...normalizeHeaders(template.headers),
},
}).catch((error) => {
if (!existsSync(tarPath)) {
Expand Down

0 comments on commit 02ebb22

Please sign in to comment.