@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.
- package/bin/launch-init.js +141 -0
- package/package.json +14 -2
- package/readme.md +14 -0
|
@@ -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.
|
|
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:
|