@burger-api/cli 0.6.6 → 0.7.0

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.
@@ -1,260 +1,260 @@
1
- /**
2
- * GitHub Integration
3
- *
4
- * Downloads files from GitHub using Bun's built-in fetch.
5
- * No extra packages needed - we use the native fetch API that comes with Bun!
6
- *
7
- * This module handles all communication with GitHub to:
8
- * - Get lists of available middleware
9
- * - Download template files
10
- * - Download middleware code
11
- */
12
-
13
- import type { GitHubFile, MiddlewareInfo } from '../types/index';
14
- import { unlinkSync } from 'fs';
15
-
16
- /**
17
- * Configuration for GitHub repository
18
- * Change these if you fork the project or want to test with a different repo
19
- */
20
- const REPO_OWNER = 'isfhan';
21
- const REPO_NAME = 'burger-api';
22
- const BRANCH = 'main';
23
-
24
- // Build the URLs we'll use to access GitHub
25
- const RAW_URL = `https://raw.githubusercontent.com/${REPO_OWNER}/${REPO_NAME}/${BRANCH}`;
26
- const API_URL = `https://api.github.com/repos/${REPO_OWNER}/${REPO_NAME}`;
27
-
28
- /**
29
- * Get list of available middleware from GitHub
30
- * This scans the ecosystem/middlewares folder and returns what's available
31
- *
32
- * @returns Promise with array of middleware names
33
- * @throws Error if GitHub is unreachable or request fails
34
- * @example
35
- * const middleware = await getMiddlewareList();
36
- * // ['cors', 'logger', 'rate-limiter', ...]
37
- */
38
- export async function getMiddlewareList(): Promise<string[]> {
39
- try {
40
- // Use Bun's native fetch - no node-fetch package needed!
41
- const response = await fetch(
42
- `${API_URL}/contents/ecosystem/middlewares`,
43
- {
44
- headers: {
45
- Accept: 'application/vnd.github.v3+json',
46
- // Add User-Agent to be nice to GitHub
47
- 'User-Agent': 'burger-api-cli',
48
- },
49
- }
50
- );
51
-
52
- // Check if the request was successful
53
- if (!response.ok) {
54
- throw new Error(`GitHub returned status ${response.status}`);
55
- }
56
-
57
- // Parse the JSON response
58
- const files = (await response.json()) as GitHubFile[];
59
-
60
- // Filter to only show directories (each middleware is in its own folder)
61
- // Sort alphabetically to make it easier to find things
62
- return files
63
- .filter((f) => f.type === 'dir')
64
- .map((f) => f.name)
65
- .sort();
66
- } catch (err) {
67
- // Provide helpful error message
68
- throw new Error(
69
- 'Could not get middleware list from GitHub. Please check your internet connection.'
70
- );
71
- }
72
- }
73
-
74
- /**
75
- * Get detailed information about a specific middleware
76
- * This reads the README file to get the description
77
- *
78
- * @param name - Name of the middleware (e.g., 'cors')
79
- * @returns Promise with middleware information
80
- * @example
81
- * const info = await getMiddlewareInfo('cors');
82
- * console.log(info.description);
83
- */
84
- export async function getMiddlewareInfo(name: string): Promise<MiddlewareInfo> {
85
- try {
86
- // Get list of files in the middleware directory
87
- const response = await fetch(
88
- `${API_URL}/contents/ecosystem/middlewares/${name}`,
89
- {
90
- headers: {
91
- Accept: 'application/vnd.github.v3+json',
92
- 'User-Agent': 'burger-api-cli',
93
- },
94
- }
95
- );
96
-
97
- if (!response.ok) {
98
- throw new Error(`Middleware "${name}" not found`);
99
- }
100
-
101
- const files = (await response.json()) as GitHubFile[];
102
-
103
- // Try to find and read the README file for description
104
- const readmeFile = files.find(
105
- (f) => f.name.toLowerCase() === 'readme.md'
106
- );
107
- let description = 'No description available';
108
-
109
- if (readmeFile && readmeFile.download_url) {
110
- try {
111
- const readmeResponse = await fetch(readmeFile.download_url);
112
- const readmeContent = await readmeResponse.text();
113
-
114
- // Extract first non-empty line after the title as description
115
- const lines = readmeContent.split('\n');
116
- for (const line of lines) {
117
- const trimmed = line.trim();
118
- if (trimmed && !trimmed.startsWith('#')) {
119
- description = trimmed;
120
- break;
121
- }
122
- }
123
- } catch {
124
- // If we can't read the README, just use default description
125
- }
126
- }
127
-
128
- return {
129
- name,
130
- description,
131
- path: `ecosystem/middlewares/${name}`,
132
- files: files.map((f) => f.name),
133
- };
134
- } catch (err) {
135
- throw new Error(`Could not get info for middleware "${name}"`);
136
- }
137
- }
138
-
139
- /**
140
- * Download a file from GitHub
141
- *
142
- * @param path - Path in the repo (e.g., 'ecosystem/middlewares/cors/cors.ts')
143
- * @param destination - Where to save it on your computer
144
- * @returns Promise that resolves when download is complete
145
- * @throws Error if download fails
146
- * @example
147
- * await downloadFile('ecosystem/middlewares/cors/cors.ts', './middleware/cors.ts');
148
- */
149
- export async function downloadFile(
150
- path: string,
151
- destination: string
152
- ): Promise<void> {
153
- try {
154
- // Build the URL to the raw file content
155
- const url = `${RAW_URL}/${path}`;
156
-
157
- // Download using Bun's native fetch
158
- const response = await fetch(url);
159
-
160
- if (!response.ok) {
161
- throw new Error(`Could not download ${path}`);
162
- }
163
-
164
- // Get the file content
165
- const content = await response.text();
166
-
167
- // Save using Bun's fast file system
168
- // Bun.write is much faster than Node's fs.writeFile!
169
- await Bun.write(destination, content);
170
- } catch (err) {
171
- throw new Error(
172
- `Failed to download ${path}: ${
173
- err instanceof Error ? err.message : 'Unknown error'
174
- }`
175
- );
176
- }
177
- }
178
-
179
- /**
180
- * Download all files for a specific middleware
181
- *
182
- * @param middlewareName - Name of the middleware to download
183
- * @param targetDir - Directory to save files in
184
- * @returns Promise with number of files downloaded
185
- * @example
186
- * const count = await downloadMiddleware('cors', './middleware');
187
- * console.log(`Downloaded ${count} files`);
188
- */
189
- export async function downloadMiddleware(
190
- middlewareName: string,
191
- targetDir: string
192
- ): Promise<number> {
193
- try {
194
- // Get information about the middleware
195
- const info = await getMiddlewareInfo(middlewareName);
196
-
197
- // Create target directory if it doesn't exist
198
- await Bun.write(`${targetDir}/.gitkeep`, ''); // Creates dir
199
-
200
- let filesDownloaded = 0;
201
-
202
- // Download ALL files (including README.md)
203
- for (const fileName of info.files) {
204
- // Skip .gitkeep files - we don't need them
205
- if (fileName === '.gitkeep') {
206
- continue;
207
- }
208
-
209
- const sourcePath = `${info.path}/${fileName}`;
210
- const destPath = `${targetDir}/${fileName}`;
211
-
212
- await downloadFile(sourcePath, destPath);
213
- filesDownloaded++;
214
- }
215
-
216
- // Remove the .gitkeep file we created for the directory
217
- try {
218
- unlinkSync(`${targetDir}/.gitkeep`);
219
- } catch {
220
- // If .gitkeep doesn't exist or can't be deleted, ignore the error
221
- }
222
-
223
- return filesDownloaded;
224
- } catch (err) {
225
- throw new Error(
226
- `Failed to download middleware "${middlewareName}": ${
227
- err instanceof Error ? err.message : 'Unknown error'
228
- }`
229
- );
230
- }
231
- }
232
-
233
- /**
234
- * Check if a middleware exists on GitHub
235
- * This is useful before trying to download something
236
- *
237
- * @param name - Name of the middleware to check
238
- * @returns Promise with true if it exists, false otherwise
239
- * @example
240
- * if (await middlewareExists('cors')) {
241
- * await downloadMiddleware('cors', './middleware');
242
- * }
243
- */
244
- export async function middlewareExists(name: string): Promise<boolean> {
245
- try {
246
- const response = await fetch(
247
- `${API_URL}/contents/ecosystem/middlewares/${name}`,
248
- {
249
- headers: {
250
- Accept: 'application/vnd.github.v3+json',
251
- 'User-Agent': 'burger-api-cli',
252
- },
253
- }
254
- );
255
-
256
- return response.ok;
257
- } catch {
258
- return false;
259
- }
260
- }
1
+ /**
2
+ * GitHub Integration
3
+ *
4
+ * Downloads files from GitHub using Bun's built-in fetch.
5
+ * No extra packages needed - we use the native fetch API that comes with Bun!
6
+ *
7
+ * This module handles all communication with GitHub to:
8
+ * - Get lists of available middleware
9
+ * - Download template files
10
+ * - Download middleware code
11
+ */
12
+
13
+ import type { GitHubFile, MiddlewareInfo } from '../types/index';
14
+ import { unlinkSync } from 'fs';
15
+
16
+ /**
17
+ * Configuration for GitHub repository
18
+ * Change these if you fork the project or want to test with a different repo
19
+ */
20
+ const REPO_OWNER = 'isfhan';
21
+ const REPO_NAME = 'burger-api';
22
+ const BRANCH = 'main';
23
+
24
+ // Build the URLs we'll use to access GitHub
25
+ const RAW_URL = `https://raw.githubusercontent.com/${REPO_OWNER}/${REPO_NAME}/${BRANCH}`;
26
+ const API_URL = `https://api.github.com/repos/${REPO_OWNER}/${REPO_NAME}`;
27
+
28
+ /**
29
+ * Get list of available middleware from GitHub
30
+ * This scans the ecosystem/middlewares folder and returns what's available
31
+ *
32
+ * @returns Promise with array of middleware names
33
+ * @throws Error if GitHub is unreachable or request fails
34
+ * @example
35
+ * const middleware = await getMiddlewareList();
36
+ * // ['cors', 'logger', 'rate-limiter', ...]
37
+ */
38
+ export async function getMiddlewareList(): Promise<string[]> {
39
+ try {
40
+ // Use Bun's native fetch - no node-fetch package needed!
41
+ const response = await fetch(
42
+ `${API_URL}/contents/ecosystem/middlewares`,
43
+ {
44
+ headers: {
45
+ Accept: 'application/vnd.github.v3+json',
46
+ // Add User-Agent to be nice to GitHub
47
+ 'User-Agent': 'burger-api-cli',
48
+ },
49
+ }
50
+ );
51
+
52
+ // Check if the request was successful
53
+ if (!response.ok) {
54
+ throw new Error(`GitHub returned status ${response.status}`);
55
+ }
56
+
57
+ // Parse the JSON response
58
+ const files = (await response.json()) as GitHubFile[];
59
+
60
+ // Filter to only show directories (each middleware is in its own folder)
61
+ // Sort alphabetically to make it easier to find things
62
+ return files
63
+ .filter((f) => f.type === 'dir')
64
+ .map((f) => f.name)
65
+ .sort();
66
+ } catch (err) {
67
+ // Provide helpful error message
68
+ throw new Error(
69
+ 'Could not get middleware list from GitHub. Please check your internet connection.'
70
+ );
71
+ }
72
+ }
73
+
74
+ /**
75
+ * Get detailed information about a specific middleware
76
+ * This reads the README file to get the description
77
+ *
78
+ * @param name - Name of the middleware (e.g., 'cors')
79
+ * @returns Promise with middleware information
80
+ * @example
81
+ * const info = await getMiddlewareInfo('cors');
82
+ * console.log(info.description);
83
+ */
84
+ export async function getMiddlewareInfo(name: string): Promise<MiddlewareInfo> {
85
+ try {
86
+ // Get list of files in the middleware directory
87
+ const response = await fetch(
88
+ `${API_URL}/contents/ecosystem/middlewares/${name}`,
89
+ {
90
+ headers: {
91
+ Accept: 'application/vnd.github.v3+json',
92
+ 'User-Agent': 'burger-api-cli',
93
+ },
94
+ }
95
+ );
96
+
97
+ if (!response.ok) {
98
+ throw new Error(`Middleware "${name}" not found`);
99
+ }
100
+
101
+ const files = (await response.json()) as GitHubFile[];
102
+
103
+ // Try to find and read the README file for description
104
+ const readmeFile = files.find(
105
+ (f) => f.name.toLowerCase() === 'readme.md'
106
+ );
107
+ let description = 'No description available';
108
+
109
+ if (readmeFile && readmeFile.download_url) {
110
+ try {
111
+ const readmeResponse = await fetch(readmeFile.download_url);
112
+ const readmeContent = await readmeResponse.text();
113
+
114
+ // Extract first non-empty line after the title as description
115
+ const lines = readmeContent.split('\n');
116
+ for (const line of lines) {
117
+ const trimmed = line.trim();
118
+ if (trimmed && !trimmed.startsWith('#')) {
119
+ description = trimmed;
120
+ break;
121
+ }
122
+ }
123
+ } catch {
124
+ // If we can't read the README, just use default description
125
+ }
126
+ }
127
+
128
+ return {
129
+ name,
130
+ description,
131
+ path: `ecosystem/middlewares/${name}`,
132
+ files: files.map((f) => f.name),
133
+ };
134
+ } catch (err) {
135
+ throw new Error(`Could not get info for middleware "${name}"`);
136
+ }
137
+ }
138
+
139
+ /**
140
+ * Download a file from GitHub
141
+ *
142
+ * @param path - Path in the repo (e.g., 'ecosystem/middlewares/cors/cors.ts')
143
+ * @param destination - Where to save it on your computer
144
+ * @returns Promise that resolves when download is complete
145
+ * @throws Error if download fails
146
+ * @example
147
+ * await downloadFile('ecosystem/middlewares/cors/cors.ts', './middleware/cors.ts');
148
+ */
149
+ export async function downloadFile(
150
+ path: string,
151
+ destination: string
152
+ ): Promise<void> {
153
+ try {
154
+ // Build the URL to the raw file content
155
+ const url = `${RAW_URL}/${path}`;
156
+
157
+ // Download using Bun's native fetch
158
+ const response = await fetch(url);
159
+
160
+ if (!response.ok) {
161
+ throw new Error(`Could not download ${path}`);
162
+ }
163
+
164
+ // Get the file content
165
+ const content = await response.text();
166
+
167
+ // Save using Bun's fast file system
168
+ // Bun.write is much faster than Node's fs.writeFile!
169
+ await Bun.write(destination, content);
170
+ } catch (err) {
171
+ throw new Error(
172
+ `Failed to download ${path}: ${
173
+ err instanceof Error ? err.message : 'Unknown error'
174
+ }`
175
+ );
176
+ }
177
+ }
178
+
179
+ /**
180
+ * Download all files for a specific middleware
181
+ *
182
+ * @param middlewareName - Name of the middleware to download
183
+ * @param targetDir - Directory to save files in
184
+ * @returns Promise with number of files downloaded
185
+ * @example
186
+ * const count = await downloadMiddleware('cors', './middleware');
187
+ * console.log(`Downloaded ${count} files`);
188
+ */
189
+ export async function downloadMiddleware(
190
+ middlewareName: string,
191
+ targetDir: string
192
+ ): Promise<number> {
193
+ try {
194
+ // Get information about the middleware
195
+ const info = await getMiddlewareInfo(middlewareName);
196
+
197
+ // Create target directory if it doesn't exist
198
+ await Bun.write(`${targetDir}/.gitkeep`, ''); // Creates dir
199
+
200
+ let filesDownloaded = 0;
201
+
202
+ // Download ALL files (including README.md)
203
+ for (const fileName of info.files) {
204
+ // Skip .gitkeep files - we don't need them
205
+ if (fileName === '.gitkeep') {
206
+ continue;
207
+ }
208
+
209
+ const sourcePath = `${info.path}/${fileName}`;
210
+ const destPath = `${targetDir}/${fileName}`;
211
+
212
+ await downloadFile(sourcePath, destPath);
213
+ filesDownloaded++;
214
+ }
215
+
216
+ // Remove the .gitkeep file we created for the directory
217
+ try {
218
+ unlinkSync(`${targetDir}/.gitkeep`);
219
+ } catch {
220
+ // If .gitkeep doesn't exist or can't be deleted, ignore the error
221
+ }
222
+
223
+ return filesDownloaded;
224
+ } catch (err) {
225
+ throw new Error(
226
+ `Failed to download middleware "${middlewareName}": ${
227
+ err instanceof Error ? err.message : 'Unknown error'
228
+ }`
229
+ );
230
+ }
231
+ }
232
+
233
+ /**
234
+ * Check if a middleware exists on GitHub
235
+ * This is useful before trying to download something
236
+ *
237
+ * @param name - Name of the middleware to check
238
+ * @returns Promise with true if it exists, false otherwise
239
+ * @example
240
+ * if (await middlewareExists('cors')) {
241
+ * await downloadMiddleware('cors', './middleware');
242
+ * }
243
+ */
244
+ export async function middlewareExists(name: string): Promise<boolean> {
245
+ try {
246
+ const response = await fetch(
247
+ `${API_URL}/contents/ecosystem/middlewares/${name}`,
248
+ {
249
+ headers: {
250
+ Accept: 'application/vnd.github.v3+json',
251
+ 'User-Agent': 'burger-api-cli',
252
+ },
253
+ }
254
+ );
255
+
256
+ return response.ok;
257
+ } catch {
258
+ return false;
259
+ }
260
+ }