@aryanbansal-launch/edge-utils 0.1.2 → 0.1.4

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.
@@ -0,0 +1,141 @@
1
+ #!/usr/bin/env node
2
+
3
+ import fs from 'fs';
4
+ import path from 'path';
5
+
6
+ const functionsDir = path.join(process.cwd(), 'functions');
7
+ const edgeFile = path.join(functionsDir, '[proxy].edge.js');
8
+
9
+ // Simple ANSI colors for better terminal output
10
+ const colors = {
11
+ reset: '\x1b[0m',
12
+ bright: '\x1b[1m',
13
+ green: '\x1b[32m',
14
+ yellow: '\x1b[33m',
15
+ cyan: '\x1b[36m',
16
+ blue: '\x1b[34m'
17
+ };
18
+
19
+ const template = `
20
+ import {
21
+ jsonResponse,
22
+ passThrough,
23
+ redirectIfMatch,
24
+ protectWithBasicAuth,
25
+ ipAccessControl,
26
+ blockAICrawlers,
27
+ getGeoHeaders,
28
+ handleNextJS_RSC
29
+ } from "@aryanbansal-launch/edge-utils";
30
+
31
+ /**
32
+ * Default Edge Handler for Contentstack Launch
33
+ * This file was automatically generated by @aryanbansal-launch/edge-utils
34
+ */
35
+ export default async function handler(request, context) {
36
+ // 1. ⚛️ Fix Next.js RSC issues for specific paths
37
+ const rscResponse = await handleNextJS_RSC(request, {
38
+ affectedPaths: ["/my-rsc-page", "/another-page"]
39
+ });
40
+ if (rscResponse) return rscResponse;
41
+
42
+ // 2. 🛡️ Block AI bots immediately
43
+ const botResponse = blockAICrawlers(request);
44
+ if (botResponse) return botResponse;
45
+
46
+ // 3. 🧱 IP Whitelisting
47
+ const ipResponse = ipAccessControl(request, { allow: ["203.0.113.10"] });
48
+ if (ipResponse) return ipResponse;
49
+
50
+ // 4. 🔐 Domain-specific Basic Auth
51
+ const authResponse = await protectWithBasicAuth(request, {
52
+ hostnameIncludes: "staging.myapp.com",
53
+ username: "admin",
54
+ password: "securepassword123"
55
+ });
56
+ if (authResponse && authResponse.status === 401) return authResponse;
57
+
58
+ // 5. 🔀 SEO-friendly Redirects
59
+ const redirectResponse = redirectIfMatch(request, {
60
+ path: "/legacy-url",
61
+ to: "/modern-url",
62
+ status: 301
63
+ });
64
+ if (redirectResponse) return redirectResponse;
65
+
66
+ // 6. 📍 Geo-Location Access
67
+ const geo = getGeoHeaders(request);
68
+ if (geo.country === "US") {
69
+ console.log(\`User from \${geo.city}, \${geo.region}\`);
70
+ }
71
+
72
+ // 7. 📤 Custom JSON Responses
73
+ if (new URL(request.url).pathname === "/api/health") {
74
+ return jsonResponse({ status: "healthy", region: geo.region });
75
+ }
76
+
77
+ // 8. 🚀 Pass through to origin
78
+ return passThrough(request);
79
+ }
80
+ `.trim();
81
+
82
+ async function init() {
83
+ console.log(`\n${colors.bright}${colors.cyan}🚀 Edge Utilities: Contentstack Launch Setup${colors.reset}\n`);
84
+
85
+ let actionsTaken = 0;
86
+ let isRoot = true;
87
+
88
+ // 1. Root level check: Look for package.json
89
+ const packageJsonPath = path.join(process.cwd(), 'package.json');
90
+ if (!fs.existsSync(packageJsonPath)) {
91
+ isRoot = false;
92
+ console.log(`${colors.yellow}⚠️ Warning: Root directory not detected.${colors.reset}`);
93
+ console.log(`${colors.yellow} We couldn't find a package.json. If this isn't your project root,${colors.reset}`);
94
+ console.log(`${colors.yellow} the 'functions' folder might be created in the wrong place.\n${colors.reset}`);
95
+ }
96
+
97
+ try {
98
+ // 2. Folder existence check
99
+ if (!fs.existsSync(functionsDir)) {
100
+ fs.mkdirSync(functionsDir, { recursive: true });
101
+ console.log(`${colors.green}✨ New:${colors.reset} Created /functions directory`);
102
+ actionsTaken++;
103
+ } else {
104
+ console.log(`${colors.blue}ℹ️ Existing:${colors.reset} /functions directory already found`);
105
+ }
106
+
107
+ // 3. File existence check (don't overwrite user's work)
108
+ if (!fs.existsSync(edgeFile)) {
109
+ fs.writeFileSync(edgeFile, template + '\n');
110
+ console.log(`${colors.green}✨ New:${colors.reset} Created /functions/[proxy].edge.js`);
111
+ actionsTaken++;
112
+ } else {
113
+ console.log(`${colors.blue}ℹ️ Existing:${colors.reset} /functions/[proxy].edge.js already found`);
114
+ }
115
+
116
+ // Final Summary Messages based on the state
117
+ if (!isRoot) {
118
+ console.log(`\n${colors.yellow}⚠️ Setup detected in a subdirectory!${colors.reset}`);
119
+ console.log(`The 'functions' folder exists here, but Contentstack Launch`);
120
+ console.log(`requires it to be at the ${colors.bright}project root${colors.reset} (next to package.json).`);
121
+ } else if (actionsTaken === 0) {
122
+ console.log(`\n${colors.bright}${colors.blue}🏁 Everything is already set up!${colors.reset}`);
123
+ console.log(`No changes were made to your existing files.`);
124
+ } else {
125
+ console.log(`\n${colors.bright}${colors.green}🎉 Setup Complete!${colors.reset}`);
126
+ console.log(`Successfully prepared your edge environment.`);
127
+ }
128
+
129
+ console.log(`\n${colors.bright}Next Steps:${colors.reset}`);
130
+ console.log(`1. Open ${colors.cyan}functions/[proxy].edge.js${colors.reset}`);
131
+ console.log(`2. Customize your redirects, auth, and RSC paths`);
132
+ console.log(`3. Deploy your project to Contentstack Launch\n`);
133
+
134
+ console.log(`${colors.blue}Documentation:${colors.reset} https://github.com/AryanBansal-launch/launch-edge-utils#readme\n`);
135
+ } catch (error) {
136
+ console.error(`\n${colors.red}❌ Error during setup:${colors.reset}`, error.message);
137
+ process.exit(1);
138
+ }
139
+ }
140
+
141
+ init();
package/package.json CHANGED
@@ -1,14 +1,26 @@
1
1
  {
2
2
  "name": "@aryanbansal-launch/edge-utils",
3
- "version": "0.1.2",
3
+ "version": "0.1.4",
4
4
  "license": "MIT",
5
5
  "type": "module",
6
+ "repository": {
7
+ "type": "git",
8
+ "url": "https://github.com/AryanBansal-launch/launch-edge-utils.git"
9
+ },
10
+ "homepage": "https://github.com/AryanBansal-launch/launch-edge-utils#readme",
11
+ "bugs": {
12
+ "url": "https://github.com/AryanBansal-launch/launch-edge-utils/issues"
13
+ },
6
14
  "main": "dist/index.js",
15
+ "bin": {
16
+ "launch-init": "./bin/launch-init.js"
17
+ },
7
18
  "exports": {
8
19
  ".": "./dist/index.js"
9
20
  },
10
21
  "files": [
11
- "dist"
22
+ "dist",
23
+ "bin"
12
24
  ],
13
25
  "scripts": {
14
26
  "build": "tsc"
package/readme.md CHANGED
@@ -27,6 +27,20 @@ npm install @launch/edge-utils
27
27
 
28
28
  ---
29
29
 
30
+ ## ⚡ Quick Start (Automatic Setup)
31
+
32
+ If you are using **Contentstack Launch**, you can automatically set up your edge function directory and boilerplate handler with a single command:
33
+
34
+ ```bash
35
+ npx launch-init
36
+ ```
37
+
38
+ This command will:
39
+ 1. Create a `functions/` directory in your project root.
40
+ 2. Generate a `[proxy].edge.js` file with a production-ready boilerplate.
41
+
42
+ ---
43
+
30
44
  ## 🛠️ Usage Example
31
45
 
32
46
  Transform your edge handler into a powerful middleware chain: