giget 0.1.4 → 0.1.6

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
@@ -9,7 +9,7 @@
9
9
 
10
10
  ## Features
11
11
 
12
- ✔ Support popular git providers (GitHub, GitLab, and Bitbucket) out of the box.
12
+ ✔ Support popular git providers (GitHub, GitLab, Bitbucket, Sourcehut) out of the box.
13
13
 
14
14
  ✔ Built-in and custom [template registry](#template-registry).
15
15
 
@@ -21,6 +21,8 @@
21
21
 
22
22
  ✔ Support extracting with a subdir.
23
23
 
24
+ ✔ Authorization support to download private templates
25
+
24
26
  ## Usage (CLI)
25
27
 
26
28
  ```bash
@@ -39,13 +41,18 @@ npx giget@latest <template> [<dir>] [...options]
39
41
  - `--prefer-offline`: Use cache if exists otherwise try to download.
40
42
  - `--force-clean`: ⚠️ Remove any existing directory or file recusively before cloning.
41
43
  - `--shell`: ⚠️ Open a new shell with current working directory in cloned dir. (Experimental).
42
- - `--registry`: URL to a custom registry.
44
+ - `--registry`: URL to a custom registry. (Can be overriden with `GIGET_REGISTRY` environment variable).
43
45
  - `--no-registry`: Disable registry lookup and functionality.
44
46
  - `--verbose`: Show verbose debugging info.
47
+ - `--cwd`: Set current working directory to resolve dirs relative to it.
48
+ - `--auth`: Custom Authorization token to use for downloading template. (Can be overriden with `GIGET_AUTH` environment variable).
45
49
 
46
50
  ### Examples
47
51
 
48
52
  ```sh
53
+ # Clone nuxt starter from giget template registry
54
+ npx giget@latest nuxt
55
+
49
56
  # Clone the main branch of github.com/unjs/template to unjs-template directory
50
57
  npx giget@latest gh:unjs/template
51
58
 
@@ -64,8 +71,8 @@ npx giget@latest gitlab:unjs/template
64
71
  # Clone from bitbucket
65
72
  npx giget@latest bitbucket:unjs/template
66
73
 
67
- # Clone nuxt starter from giget template registry
68
- npx giget@latest nuxt
74
+ # Clone from sourcehut
75
+ npx giget@latest sourcehut:pi0/unjs-template
69
76
  ```
70
77
 
71
78
  ## Template Registry
@@ -78,11 +85,12 @@ If you want to add your template to the built-in registry, just drop a PR to add
78
85
 
79
86
  A custom registry should provide an endpoint with dynamic path `/:template.json` that returns a JSON response with keys same as [custom providers](#custom-providers).
80
87
 
81
- - `name`: (required) Name of the template.
82
- - `tar` (required) Link to the tar download link.
83
- - `defaultDir`: (optional) Default cloning directory.
84
- - `url`: (optional) Webpage of the template.
85
- - `subpath` (optional) Subpath inside the tar file.
88
+ - `name`: (required) Name of the template.
89
+ - `tar` (required) Link to the tar download link.
90
+ - `defaultDir`: (optional) Default cloning directory.
91
+ - `url`: (optional) Webpage of the template.
92
+ - `subpath`: (optional) Subpath inside the tar file.
93
+ - `headers`: (optional) Custom headers to send while downloading template.
86
94
 
87
95
  Because of the simplicity, you can even use a github repository as template registry but also you can build something more powerful by bringing your own API.
88
96
 
@@ -124,7 +132,7 @@ const { source, dir } = await downloadTemplate('github:unjs/template')
124
132
  - `source`: (string) Input source in format of `[provider]:repo[/subpath][#ref]`.
125
133
  - `dir`: (string) Destination directory to clone to. If not provided, `user-name` will be used relative to the current directory.
126
134
  - `options`: (object) Options are usually inferred from the input string. You can customize them.
127
- - `provider`: (string) Either `github`, `gitlab` or `bitbucket`. The default is `github`.
135
+ - `provider`: (string) Either `github`, `gitlab`, `bitbucket` or `sourcehut`. The default is `github`.
128
136
  - `repo`: (string) Name of repository in format of `{username}/{reponame}`.
129
137
  - `ref`: (string) Git ref (branch or commit or tag). The default value is `main`.
130
138
  - `subdirpath`: (string) subdir of the repo to clone from. The default value is none.
@@ -133,7 +141,9 @@ const { source, dir } = await downloadTemplate('github:unjs/template')
133
141
  - `offline`: (boolean) Do not attempt to download and use cached version.
134
142
  - `preferOffline`: (boolean) Use cache if exists otherwise try to download.
135
143
  - `providers`: (object) A map from provider name to custom providers. Can be used to override built-ins too.
136
- - `registry`: (string or false) Set to `false` to disable registry. Set to a URL string (without trailing slash) for custom registry.
144
+ - `registry`: (string or false) Set to `false` to disable registry. Set to a URL string (without trailing slash) for custom registry. (Can be overriden with `GIGET_REGISTRY` environment variable).
145
+ - `cwd`: (string) Current working directory to resolve dirs relative to it.
146
+ - `auth`: (string) Custom Authorization token to use for downloading template. (Can be overriden with `GIGET_AUTH` environment variable).
137
147
 
138
148
  **Return value:**
139
149
 
@@ -151,10 +161,11 @@ Using programmatic method, you can make your own custom template providers.
151
161
  ```ts
152
162
  import type { TemplateProvider } from 'giget'
153
163
 
154
- const rainbow: TemplateProvider = async (input) => {
164
+ const rainbow: TemplateProvider = async (input, { auth }) => {
155
165
  return {
156
166
  name: 'rainbow',
157
167
  version: input,
168
+ headers: { Authorization: auth },
158
169
  url: `https://rainbow.template/?variant=${input}`,
159
170
  tar: `https://rainbow.template/dl/rainbow.${input}.tar.gz`
160
171
  }
@@ -175,19 +186,20 @@ const themes = registryProvider('https://raw.githubusercontent.com/unjs/giget/ma
175
186
  const { source, dir } = await downloadRepo('themes:test', { providers: { themes } })
176
187
  ```
177
188
 
178
- ## 💻 Development
179
-
180
- - Clone this repository
181
- - Enable [Corepack](https://github.com/nodejs/corepack) using `corepack enable` (use `npm i -g corepack` for Node.js < 16.10)
182
- - Install dependencies using `pnpm install`
183
- - Run interactive tests using `pnpm dev`
184
-
185
189
  ## Related projects
186
190
 
191
+ Giget wouldn't be possible without inspering from former projects. In comparation giget does not depend on any local command which increases stability and performance, supports custom template providers, auth and many more features out of the box.
192
+
187
193
  - https://github.com/samsonjs/gitter
188
194
  - https://github.com/tiged/tiged
189
195
  - https://github.com/Rich-Harris/degit
190
196
 
197
+ ## 💻 Development
198
+
199
+ - Clone this repository
200
+ - Enable [Corepack](https://github.com/nodejs/corepack) using `corepack enable` (use `npm i -g corepack` for Node.js < 16.10)
201
+ - Install dependencies using `pnpm install`
202
+ - Run interactive tests using `pnpm dev`
191
203
 
192
204
  ## License
193
205
 
@@ -196,14 +208,12 @@ Made with 💛
196
208
  Published under [MIT License](./LICENSE).
197
209
 
198
210
  <!-- Badges -->
211
+
199
212
  [npm-version-src]: https://img.shields.io/npm/v/giget?style=flat-square
200
213
  [npm-version-href]: https://npmjs.com/package/giget
201
-
202
214
  [npm-downloads-src]: https://img.shields.io/npm/dm/giget?style=flat-square
203
215
  [npm-downloads-href]: https://npmjs.com/package/giget
204
-
205
216
  [github-actions-src]: https://img.shields.io/github/workflow/status/unjs/giget/ci/main?style=flat-square
206
217
  [github-actions-href]: https://github.com/unjs/giget/actions?query=workflow%3Aci
207
-
208
218
  [codecov-src]: https://img.shields.io/codecov/c/gh/unjs/giget/main?style=flat-square
209
219
  [codecov-href]: https://codecov.io/gh/unjs/giget
package/dist/cli.cjs CHANGED
@@ -4,12 +4,13 @@
4
4
  const node_path = require('node:path');
5
5
  const mri = require('mri');
6
6
  const colorette = require('colorette');
7
- const giget = require('./shared/giget.774476cb.cjs');
7
+ const giget = require('./shared/giget.73314e21.cjs');
8
8
  require('node:fs/promises');
9
9
  require('node:os');
10
10
  require('node:fs');
11
11
  require('tar');
12
12
  require('pathe');
13
+ require('defu');
13
14
  require('node:stream/promises');
14
15
  require('node:child_process');
15
16
  require('node-fetch-native');
@@ -20,12 +21,13 @@ const mri__default = /*#__PURE__*/_interopDefaultLegacy(mri);
20
21
 
21
22
  async function main() {
22
23
  const args = mri__default(process.argv.slice(2), {
23
- boolean: ["help", "force", "force-clean", "offline", "prefer-offline", "shell", "registry", "verbose"]
24
+ boolean: ["help", "force", "force-clean", "offline", "prefer-offline", "shell", "verbose"],
25
+ string: ["registry", "cwd", "auth"]
24
26
  });
25
27
  const input = args._[0];
26
28
  const dir = args._[1];
27
29
  if (!input || args.help || args.h) {
28
- console.error("Usage: npx getgit@latest <input> [<dir>] [--force] [--force-clean] [--offline] [--prefer-offline] [--shell] [--registry] [--no-registry] [--verbose]");
30
+ console.error("Usage: npx getgit@latest <input> [<dir>] [--force] [--force-clean] [--offline] [--prefer-offline] [--shell] [--registry] [--no-registry] [--verbose] [--cwd] [--auth]");
29
31
  process.exit(1);
30
32
  }
31
33
  if (args.verbose) {
@@ -36,7 +38,9 @@ async function main() {
36
38
  force: args.force,
37
39
  forceClean: args["force-clean"],
38
40
  offline: args.offline,
39
- registry: args.registry
41
+ registry: args.registry,
42
+ cwd: args.cwd,
43
+ auth: args.auth
40
44
  });
41
45
  console.log(`\u2728 Successfully cloned ${colorette.cyan(r.name || r.url)} to ${colorette.cyan(node_path.relative(process.cwd(), r.dir))}
42
46
  `);
package/dist/cli.mjs CHANGED
@@ -2,24 +2,26 @@
2
2
  import { relative } from 'node:path';
3
3
  import mri from 'mri';
4
4
  import { cyan } from 'colorette';
5
- import { d as downloadTemplate, s as startShell } from './shared/giget.1430f5a2.mjs';
5
+ import { d as downloadTemplate, s as startShell } from './shared/giget.ae887001.mjs';
6
6
  import 'node:fs/promises';
7
7
  import 'node:os';
8
8
  import 'node:fs';
9
9
  import 'tar';
10
10
  import 'pathe';
11
+ import 'defu';
11
12
  import 'node:stream/promises';
12
13
  import 'node:child_process';
13
14
  import 'node-fetch-native';
14
15
 
15
16
  async function main() {
16
17
  const args = mri(process.argv.slice(2), {
17
- boolean: ["help", "force", "force-clean", "offline", "prefer-offline", "shell", "registry", "verbose"]
18
+ boolean: ["help", "force", "force-clean", "offline", "prefer-offline", "shell", "verbose"],
19
+ string: ["registry", "cwd", "auth"]
18
20
  });
19
21
  const input = args._[0];
20
22
  const dir = args._[1];
21
23
  if (!input || args.help || args.h) {
22
- console.error("Usage: npx getgit@latest <input> [<dir>] [--force] [--force-clean] [--offline] [--prefer-offline] [--shell] [--registry] [--no-registry] [--verbose]");
24
+ console.error("Usage: npx getgit@latest <input> [<dir>] [--force] [--force-clean] [--offline] [--prefer-offline] [--shell] [--registry] [--no-registry] [--verbose] [--cwd] [--auth]");
23
25
  process.exit(1);
24
26
  }
25
27
  if (args.verbose) {
@@ -30,7 +32,9 @@ async function main() {
30
32
  force: args.force,
31
33
  forceClean: args["force-clean"],
32
34
  offline: args.offline,
33
- registry: args.registry
35
+ registry: args.registry,
36
+ cwd: args.cwd,
37
+ auth: args.auth
34
38
  });
35
39
  console.log(`\u2728 Successfully cloned ${cyan(r.name || r.url)} to ${cyan(relative(process.cwd(), r.dir))}
36
40
  `);
package/dist/index.cjs CHANGED
@@ -2,12 +2,13 @@
2
2
 
3
3
  Object.defineProperty(exports, '__esModule', { value: true });
4
4
 
5
- const giget = require('./shared/giget.774476cb.cjs');
5
+ const giget = require('./shared/giget.73314e21.cjs');
6
6
  require('node:fs/promises');
7
7
  require('node:os');
8
8
  require('node:fs');
9
9
  require('tar');
10
10
  require('pathe');
11
+ require('defu');
11
12
  require('node:stream/promises');
12
13
  require('node:child_process');
13
14
  require('node-fetch-native');
package/dist/index.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  interface GitInfo {
2
- provider: 'github' | 'gitlab' | 'bitbucket';
2
+ provider: 'github' | 'gitlab' | 'bitbucket' | 'sourcehut';
3
3
  repo: string;
4
4
  subdir: string;
5
5
  ref: string;
@@ -11,11 +11,14 @@ interface TemplateInfo {
11
11
  subdir?: string;
12
12
  url?: string;
13
13
  defaultDir?: string;
14
+ headers?: Record<string, string>;
14
15
  source?: never;
15
16
  dir?: never;
16
17
  [key: string]: any;
17
18
  }
18
- declare type TemplateProvider = (input: string) => TemplateInfo | Promise<TemplateInfo> | null;
19
+ declare type TemplateProvider = (input: string, options: {
20
+ auth?: string;
21
+ }) => TemplateInfo | Promise<TemplateInfo> | null;
19
22
 
20
23
  interface DownloadTemplateOptions {
21
24
  provider?: string;
@@ -26,20 +29,17 @@ interface DownloadTemplateOptions {
26
29
  providers?: Record<string, TemplateProvider>;
27
30
  dir?: string;
28
31
  registry?: false | string;
32
+ cwd?: string;
33
+ auth?: string;
29
34
  }
30
- declare function downloadTemplate(input: string, opts?: DownloadTemplateOptions): Promise<{
31
- source: string;
35
+ declare type DownloadTemplateResult = Omit<TemplateInfo, 'dir' | 'source'> & {
32
36
  dir: string;
33
- name: string;
34
- tar: string;
35
- version?: string;
36
- subdir?: string;
37
- url?: string;
38
- defaultDir?: string;
39
- }>;
37
+ source: string;
38
+ };
39
+ declare function downloadTemplate(input: string, opts?: DownloadTemplateOptions): Promise<DownloadTemplateResult>;
40
40
 
41
41
  declare const registryProvider: (registryEndpoint?: string) => TemplateProvider;
42
42
 
43
43
  declare function startShell(cwd: string): void;
44
44
 
45
- export { DownloadTemplateOptions, GitInfo, TemplateInfo, TemplateProvider, downloadTemplate, registryProvider, startShell };
45
+ export { DownloadTemplateOptions, DownloadTemplateResult, GitInfo, TemplateInfo, TemplateProvider, downloadTemplate, registryProvider, startShell };
package/dist/index.mjs CHANGED
@@ -1,9 +1,10 @@
1
- export { d as downloadTemplate, r as registryProvider, s as startShell } from './shared/giget.1430f5a2.mjs';
1
+ export { d as downloadTemplate, r as registryProvider, s as startShell } from './shared/giget.ae887001.mjs';
2
2
  import 'node:fs/promises';
3
3
  import 'node:os';
4
4
  import 'node:fs';
5
5
  import 'tar';
6
6
  import 'pathe';
7
+ import 'defu';
7
8
  import 'node:stream/promises';
8
9
  import 'node:child_process';
9
10
  import 'node-fetch-native';
@@ -5,6 +5,7 @@ const node_os = require('node:os');
5
5
  const node_fs = require('node:fs');
6
6
  const tar = require('tar');
7
7
  const pathe = require('pathe');
8
+ const defu = require('defu');
8
9
  const promises$1 = require('node:stream/promises');
9
10
  const node_child_process = require('node:child_process');
10
11
  const fetch = require('node-fetch-native');
@@ -13,16 +14,16 @@ function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'defau
13
14
 
14
15
  const fetch__default = /*#__PURE__*/_interopDefaultLegacy(fetch);
15
16
 
16
- async function download(url, filePath) {
17
+ async function download(url, filePath, opts = {}) {
17
18
  const infoPath = filePath + ".json";
18
19
  const info = JSON.parse(await promises.readFile(infoPath, "utf8").catch(() => "{}"));
19
- const headRes = await fetch.fetch(url, { method: "HEAD" }).catch(() => null);
20
+ const headRes = await fetch.fetch(url, { method: "HEAD", headers: opts.headers }).catch(() => null);
20
21
  const etag = headRes?.headers.get("etag");
21
22
  if (info.etag === etag && node_fs.existsSync(filePath)) {
22
23
  return;
23
24
  }
24
25
  info.etag = etag;
25
- const res = await fetch.fetch(url);
26
+ const res = await fetch.fetch(url, { headers: opts.headers });
26
27
  if (res.status >= 400) {
27
28
  throw new Error(`Failed to download ${url}: ${res.status} ${res.statusText}`);
28
29
  }
@@ -64,41 +65,56 @@ function startShell(cwd) {
64
65
  });
65
66
  }
66
67
 
67
- const github = (input) => {
68
+ const github = (input, opts) => {
68
69
  const parsed = parseGitURI(input);
69
70
  return {
70
71
  name: parsed.repo.replace("/", "-"),
71
72
  version: parsed.ref,
72
73
  subdir: parsed.subdir,
74
+ headers: { Authorization: opts.auth ? `Bearer ${opts.auth}` : void 0 },
73
75
  url: `https://github.com/${parsed.repo}/tree/${parsed.ref}${parsed.subdir}`,
74
76
  tar: `https://github.com/${parsed.repo}/archive/${parsed.ref}.tar.gz`
75
77
  };
76
78
  };
77
- const gitlab = (input) => {
79
+ const gitlab = (input, opts) => {
78
80
  const parsed = parseGitURI(input);
79
81
  return {
80
82
  name: parsed.repo.replace("/", "-"),
81
83
  version: parsed.ref,
82
84
  subdir: parsed.subdir,
85
+ headers: { Authorization: opts.auth ? `Bearer ${opts.auth}` : void 0 },
83
86
  url: `https://gitlab.com/${parsed.repo}/tree/${parsed.ref}${parsed.subdir}`,
84
87
  tar: `https://gitlab.com/${parsed.repo}/-/archive/${parsed.ref}.tar.gz`
85
88
  };
86
89
  };
87
- const bitbucket = (input) => {
90
+ const bitbucket = (input, opts) => {
88
91
  const parsed = parseGitURI(input);
89
92
  return {
90
93
  name: parsed.repo.replace("/", "-"),
91
94
  version: parsed.ref,
92
95
  subdir: parsed.subdir,
96
+ headers: { Authorization: opts.auth ? `Bearer ${opts.auth}` : void 0 },
93
97
  url: `https://bitbucket.com/${parsed.repo}/src/${parsed.ref}${parsed.subdir}`,
94
98
  tar: `https://bitbucket.org/${parsed.repo}/get/${parsed.ref}.tar.gz`
95
99
  };
96
100
  };
101
+ const sourcehut = (input, opts) => {
102
+ const parsed = parseGitURI(input);
103
+ return {
104
+ name: parsed.repo.replace("/", "-"),
105
+ version: parsed.ref,
106
+ subdir: parsed.subdir,
107
+ headers: { Authorization: opts.auth ? `Bearer ${opts.auth}` : void 0 },
108
+ url: `https://git.sr.ht/~${parsed.repo}/tree/${parsed.ref}/item${parsed.subdir}`,
109
+ tar: `https://git.sr.ht/~${parsed.repo}/archive/${parsed.ref}.tar.gz`
110
+ };
111
+ };
97
112
  const providers = {
98
113
  github,
99
114
  gh: github,
100
115
  gitlab,
101
- bitbucket
116
+ bitbucket,
117
+ sourcehut
102
118
  };
103
119
 
104
120
  const DEFAULT_REGISTRY = "https://raw.githubusercontent.com/unjs/giget/main/templates";
@@ -121,6 +137,10 @@ const registryProvider = (registryEndpoint = DEFAULT_REGISTRY) => {
121
137
 
122
138
  const sourceProtoRe = /^([\w-.]+):/;
123
139
  async function downloadTemplate(input, opts = {}) {
140
+ opts = defu.defu({
141
+ registry: process.env.GIGET_REGISTRY,
142
+ auth: process.env.GIGET_AUTH
143
+ }, opts);
124
144
  const registry = opts.registry !== false ? registryProvider(opts.registry) : null;
125
145
  let providerName = opts.provider || (registryProvider ? "registry" : "github");
126
146
  let source = input;
@@ -133,12 +153,13 @@ async function downloadTemplate(input, opts = {}) {
133
153
  if (!provider) {
134
154
  throw new Error(`Unsupported provider: ${providerName}`);
135
155
  }
136
- const template = await Promise.resolve().then(() => provider(source)).catch((err) => {
156
+ const template = await Promise.resolve().then(() => provider(source, { auth: opts.auth })).catch((err) => {
137
157
  throw new Error(`Failed to download template from ${providerName}: ${err.message}`);
138
158
  });
139
159
  template.name = (template.name || "template").replace(/[^a-z0-9-]/gi, "-");
140
160
  template.defaultDir = (template.defaultDir || template.name).replace(/[^a-z0-9-]/gi, "-");
141
- const extractPath = pathe.resolve(opts.dir || template.defaultDir);
161
+ const cwd = pathe.resolve(opts.cwd || ".");
162
+ const extractPath = pathe.resolve(cwd, opts.dir || template.defaultDir);
142
163
  if (opts.forceClean) {
143
164
  await promises.rm(extractPath, { recursive: true, force: true });
144
165
  }
@@ -154,7 +175,7 @@ async function downloadTemplate(input, opts = {}) {
154
175
  if (!opts.offline) {
155
176
  await promises.mkdir(pathe.dirname(tarPath), { recursive: true });
156
177
  const s2 = Date.now();
157
- await download(template.tar, tarPath).catch((err) => {
178
+ await download(template.tar, tarPath, { headers: template.headers }).catch((err) => {
158
179
  if (!node_fs.existsSync(tarPath)) {
159
180
  throw err;
160
181
  }
@@ -174,7 +195,7 @@ async function downloadTemplate(input, opts = {}) {
174
195
  onentry(entry) {
175
196
  entry.path = entry.path.split("/").splice(1).join("/");
176
197
  if (subdir) {
177
- if (entry.path.startsWith(subdir)) {
198
+ if (entry.path.startsWith(subdir + "/")) {
178
199
  entry.path = entry.path.substring(subdir.length);
179
200
  } else {
180
201
  entry.path = "";
@@ -3,20 +3,21 @@ import { homedir } from 'node:os';
3
3
  import { existsSync, createWriteStream, readdirSync } from 'node:fs';
4
4
  import { extract } from 'tar';
5
5
  import { resolve, relative, dirname } from 'pathe';
6
+ import { defu } from 'defu';
6
7
  import { pipeline } from 'node:stream/promises';
7
8
  import { spawnSync } from 'node:child_process';
8
9
  import fetch$1, { fetch } from 'node-fetch-native';
9
10
 
10
- async function download(url, filePath) {
11
+ async function download(url, filePath, opts = {}) {
11
12
  const infoPath = filePath + ".json";
12
13
  const info = JSON.parse(await readFile(infoPath, "utf8").catch(() => "{}"));
13
- const headRes = await fetch(url, { method: "HEAD" }).catch(() => null);
14
+ const headRes = await fetch(url, { method: "HEAD", headers: opts.headers }).catch(() => null);
14
15
  const etag = headRes?.headers.get("etag");
15
16
  if (info.etag === etag && existsSync(filePath)) {
16
17
  return;
17
18
  }
18
19
  info.etag = etag;
19
- const res = await fetch(url);
20
+ const res = await fetch(url, { headers: opts.headers });
20
21
  if (res.status >= 400) {
21
22
  throw new Error(`Failed to download ${url}: ${res.status} ${res.statusText}`);
22
23
  }
@@ -58,41 +59,56 @@ function startShell(cwd) {
58
59
  });
59
60
  }
60
61
 
61
- const github = (input) => {
62
+ const github = (input, opts) => {
62
63
  const parsed = parseGitURI(input);
63
64
  return {
64
65
  name: parsed.repo.replace("/", "-"),
65
66
  version: parsed.ref,
66
67
  subdir: parsed.subdir,
68
+ headers: { Authorization: opts.auth ? `Bearer ${opts.auth}` : void 0 },
67
69
  url: `https://github.com/${parsed.repo}/tree/${parsed.ref}${parsed.subdir}`,
68
70
  tar: `https://github.com/${parsed.repo}/archive/${parsed.ref}.tar.gz`
69
71
  };
70
72
  };
71
- const gitlab = (input) => {
73
+ const gitlab = (input, opts) => {
72
74
  const parsed = parseGitURI(input);
73
75
  return {
74
76
  name: parsed.repo.replace("/", "-"),
75
77
  version: parsed.ref,
76
78
  subdir: parsed.subdir,
79
+ headers: { Authorization: opts.auth ? `Bearer ${opts.auth}` : void 0 },
77
80
  url: `https://gitlab.com/${parsed.repo}/tree/${parsed.ref}${parsed.subdir}`,
78
81
  tar: `https://gitlab.com/${parsed.repo}/-/archive/${parsed.ref}.tar.gz`
79
82
  };
80
83
  };
81
- const bitbucket = (input) => {
84
+ const bitbucket = (input, opts) => {
82
85
  const parsed = parseGitURI(input);
83
86
  return {
84
87
  name: parsed.repo.replace("/", "-"),
85
88
  version: parsed.ref,
86
89
  subdir: parsed.subdir,
90
+ headers: { Authorization: opts.auth ? `Bearer ${opts.auth}` : void 0 },
87
91
  url: `https://bitbucket.com/${parsed.repo}/src/${parsed.ref}${parsed.subdir}`,
88
92
  tar: `https://bitbucket.org/${parsed.repo}/get/${parsed.ref}.tar.gz`
89
93
  };
90
94
  };
95
+ const sourcehut = (input, opts) => {
96
+ const parsed = parseGitURI(input);
97
+ return {
98
+ name: parsed.repo.replace("/", "-"),
99
+ version: parsed.ref,
100
+ subdir: parsed.subdir,
101
+ headers: { Authorization: opts.auth ? `Bearer ${opts.auth}` : void 0 },
102
+ url: `https://git.sr.ht/~${parsed.repo}/tree/${parsed.ref}/item${parsed.subdir}`,
103
+ tar: `https://git.sr.ht/~${parsed.repo}/archive/${parsed.ref}.tar.gz`
104
+ };
105
+ };
91
106
  const providers = {
92
107
  github,
93
108
  gh: github,
94
109
  gitlab,
95
- bitbucket
110
+ bitbucket,
111
+ sourcehut
96
112
  };
97
113
 
98
114
  const DEFAULT_REGISTRY = "https://raw.githubusercontent.com/unjs/giget/main/templates";
@@ -115,6 +131,10 @@ const registryProvider = (registryEndpoint = DEFAULT_REGISTRY) => {
115
131
 
116
132
  const sourceProtoRe = /^([\w-.]+):/;
117
133
  async function downloadTemplate(input, opts = {}) {
134
+ opts = defu({
135
+ registry: process.env.GIGET_REGISTRY,
136
+ auth: process.env.GIGET_AUTH
137
+ }, opts);
118
138
  const registry = opts.registry !== false ? registryProvider(opts.registry) : null;
119
139
  let providerName = opts.provider || (registryProvider ? "registry" : "github");
120
140
  let source = input;
@@ -127,12 +147,13 @@ async function downloadTemplate(input, opts = {}) {
127
147
  if (!provider) {
128
148
  throw new Error(`Unsupported provider: ${providerName}`);
129
149
  }
130
- const template = await Promise.resolve().then(() => provider(source)).catch((err) => {
150
+ const template = await Promise.resolve().then(() => provider(source, { auth: opts.auth })).catch((err) => {
131
151
  throw new Error(`Failed to download template from ${providerName}: ${err.message}`);
132
152
  });
133
153
  template.name = (template.name || "template").replace(/[^a-z0-9-]/gi, "-");
134
154
  template.defaultDir = (template.defaultDir || template.name).replace(/[^a-z0-9-]/gi, "-");
135
- const extractPath = resolve(opts.dir || template.defaultDir);
155
+ const cwd = resolve(opts.cwd || ".");
156
+ const extractPath = resolve(cwd, opts.dir || template.defaultDir);
136
157
  if (opts.forceClean) {
137
158
  await rm(extractPath, { recursive: true, force: true });
138
159
  }
@@ -148,7 +169,7 @@ async function downloadTemplate(input, opts = {}) {
148
169
  if (!opts.offline) {
149
170
  await mkdir(dirname(tarPath), { recursive: true });
150
171
  const s2 = Date.now();
151
- await download(template.tar, tarPath).catch((err) => {
172
+ await download(template.tar, tarPath, { headers: template.headers }).catch((err) => {
152
173
  if (!existsSync(tarPath)) {
153
174
  throw err;
154
175
  }
@@ -168,7 +189,7 @@ async function downloadTemplate(input, opts = {}) {
168
189
  onentry(entry) {
169
190
  entry.path = entry.path.split("/").splice(1).join("/");
170
191
  if (subdir) {
171
- if (entry.path.startsWith(subdir)) {
192
+ if (entry.path.startsWith(subdir + "/")) {
172
193
  entry.path = entry.path.substring(subdir.length);
173
194
  } else {
174
195
  entry.path = "";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "giget",
3
- "version": "0.1.4",
3
+ "version": "0.1.6",
4
4
  "description": "Download templates and git repositories with pleasure!",
5
5
  "repository": "unjs/giget",
6
6
  "license": "MIT",
@@ -23,6 +23,7 @@
23
23
  ],
24
24
  "dependencies": {
25
25
  "colorette": "^2.0.19",
26
+ "defu": "^6.1.0",
26
27
  "mri": "^1.2.0",
27
28
  "node-fetch-native": "^0.1.4",
28
29
  "pathe": "^0.3.7",
@@ -33,11 +34,11 @@
33
34
  "@types/node": "^18.7.16",
34
35
  "@types/tar": "^6.1.2",
35
36
  "@vitest/coverage-c8": "^0.23.2",
36
- "eslint": "^8.23.0",
37
+ "eslint": "^8.23.1",
37
38
  "jiti": "^1.15.0",
38
39
  "standard-version": "^9.5.0",
39
40
  "typescript": "^4.8.3",
40
- "unbuild": "^0.8.10",
41
+ "unbuild": "^0.8.11",
41
42
  "vitest": "^0.23.2"
42
43
  },
43
44
  "packageManager": "pnpm@7.11.0",