@hasna/shortlinks 0.1.0 → 0.1.2
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 +1 -1
- package/dist/cli/index.js +17 -3
- package/dist/cloudflare.d.ts +1 -1
- package/dist/cloudflare.js +15 -3
- package/dist/index.js +15 -3
- package/package.json +3 -3
- package/dist/cli/cli.test.d.ts +0 -1
- package/dist/cloudflare.test.d.ts +0 -1
- package/dist/server.test.d.ts +0 -1
- package/dist/store.test.d.ts +0 -1
package/README.md
CHANGED
|
@@ -96,7 +96,7 @@ shortlinks cloudflare worker \
|
|
|
96
96
|
--origin https://shortlinks.hasna.xyz
|
|
97
97
|
```
|
|
98
98
|
|
|
99
|
-
Upsert DNS when `CLOUDFLARE_API_TOKEN` is available
|
|
99
|
+
Upsert DNS when `CLOUDFLARE_API_TOKEN` is available. Global API key auth is also supported with `CLOUDFLARE_API_KEY` plus `CLOUDFLARE_EMAIL`.
|
|
100
100
|
|
|
101
101
|
```bash
|
|
102
102
|
shortlinks cloudflare dns has.na --target shortlinks.hasna.xyz
|
package/dist/cli/index.js
CHANGED
|
@@ -3224,11 +3224,25 @@ SHORTLINKS_ORIGIN = "${options.origin || "https://shortlinks.example.com"}"
|
|
|
3224
3224
|
`);
|
|
3225
3225
|
return { workerPath, wranglerPath };
|
|
3226
3226
|
}
|
|
3227
|
+
function cloudflareAuthHeaders(token) {
|
|
3228
|
+
const apiToken = token || process.env.CLOUDFLARE_API_TOKEN;
|
|
3229
|
+
if (apiToken)
|
|
3230
|
+
return { authorization: `Bearer ${apiToken}` };
|
|
3231
|
+
const apiKey = process.env.CLOUDFLARE_API_KEY;
|
|
3232
|
+
const email = process.env.CLOUDFLARE_EMAIL;
|
|
3233
|
+
if (apiKey && email) {
|
|
3234
|
+
return {
|
|
3235
|
+
"x-auth-key": apiKey,
|
|
3236
|
+
"x-auth-email": email
|
|
3237
|
+
};
|
|
3238
|
+
}
|
|
3239
|
+
throw new Error("Cloudflare auth is required: set CLOUDFLARE_API_TOKEN, or CLOUDFLARE_API_KEY plus CLOUDFLARE_EMAIL.");
|
|
3240
|
+
}
|
|
3227
3241
|
async function cloudflareRequest(token, path, init = {}) {
|
|
3228
3242
|
const response = await fetch(`https://api.cloudflare.com/client/v4${path}`, {
|
|
3229
3243
|
...init,
|
|
3230
3244
|
headers: {
|
|
3231
|
-
|
|
3245
|
+
...cloudflareAuthHeaders(token),
|
|
3232
3246
|
"content-type": "application/json",
|
|
3233
3247
|
...init.headers || {}
|
|
3234
3248
|
}
|
|
@@ -3266,8 +3280,6 @@ async function upsertCloudflareDnsRecord(options) {
|
|
|
3266
3280
|
});
|
|
3267
3281
|
if (options.dryRun)
|
|
3268
3282
|
return plan;
|
|
3269
|
-
if (!token)
|
|
3270
|
-
throw new Error("CLOUDFLARE_API_TOKEN is required unless --dry-run is used.");
|
|
3271
3283
|
const zoneId = options.zoneId || await findCloudflareZoneId(plan.hostname, token);
|
|
3272
3284
|
const existing = await cloudflareRequest(token, `/zones/${zoneId}/dns_records?type=CNAME&name=${encodeURIComponent(plan.hostname)}`);
|
|
3273
3285
|
const payload = JSON.stringify(plan.dnsRecord);
|
|
@@ -3832,6 +3844,8 @@ program2.command("doctor").description("Check local shortlinks tooling and integ
|
|
|
3832
3844
|
},
|
|
3833
3845
|
environment: {
|
|
3834
3846
|
cloudflare_api_token_present: Boolean(process.env.CLOUDFLARE_API_TOKEN),
|
|
3847
|
+
cloudflare_api_key_present: Boolean(process.env.CLOUDFLARE_API_KEY),
|
|
3848
|
+
cloudflare_email_present: Boolean(process.env.CLOUDFLARE_EMAIL),
|
|
3835
3849
|
shortlinks_origin_present: Boolean(process.env.SHORTLINKS_ORIGIN)
|
|
3836
3850
|
}
|
|
3837
3851
|
};
|
package/dist/cloudflare.d.ts
CHANGED
|
@@ -36,7 +36,7 @@ export declare function writeWorkerFiles(options?: {
|
|
|
36
36
|
workerPath: string;
|
|
37
37
|
wranglerPath: string;
|
|
38
38
|
};
|
|
39
|
-
export declare function findCloudflareZoneId(hostname: string, token
|
|
39
|
+
export declare function findCloudflareZoneId(hostname: string, token?: string): Promise<string>;
|
|
40
40
|
export declare function upsertCloudflareDnsRecord(options: CloudflareDnsOptions): Promise<CloudflareSetupPlan | {
|
|
41
41
|
id: string;
|
|
42
42
|
action: "created" | "updated";
|
package/dist/cloudflare.js
CHANGED
|
@@ -87,11 +87,25 @@ SHORTLINKS_ORIGIN = "${options.origin || "https://shortlinks.example.com"}"
|
|
|
87
87
|
`);
|
|
88
88
|
return { workerPath, wranglerPath };
|
|
89
89
|
}
|
|
90
|
+
function cloudflareAuthHeaders(token) {
|
|
91
|
+
const apiToken = token || process.env.CLOUDFLARE_API_TOKEN;
|
|
92
|
+
if (apiToken)
|
|
93
|
+
return { authorization: `Bearer ${apiToken}` };
|
|
94
|
+
const apiKey = process.env.CLOUDFLARE_API_KEY;
|
|
95
|
+
const email = process.env.CLOUDFLARE_EMAIL;
|
|
96
|
+
if (apiKey && email) {
|
|
97
|
+
return {
|
|
98
|
+
"x-auth-key": apiKey,
|
|
99
|
+
"x-auth-email": email
|
|
100
|
+
};
|
|
101
|
+
}
|
|
102
|
+
throw new Error("Cloudflare auth is required: set CLOUDFLARE_API_TOKEN, or CLOUDFLARE_API_KEY plus CLOUDFLARE_EMAIL.");
|
|
103
|
+
}
|
|
90
104
|
async function cloudflareRequest(token, path, init = {}) {
|
|
91
105
|
const response = await fetch(`https://api.cloudflare.com/client/v4${path}`, {
|
|
92
106
|
...init,
|
|
93
107
|
headers: {
|
|
94
|
-
|
|
108
|
+
...cloudflareAuthHeaders(token),
|
|
95
109
|
"content-type": "application/json",
|
|
96
110
|
...init.headers || {}
|
|
97
111
|
}
|
|
@@ -129,8 +143,6 @@ async function upsertCloudflareDnsRecord(options) {
|
|
|
129
143
|
});
|
|
130
144
|
if (options.dryRun)
|
|
131
145
|
return plan;
|
|
132
|
-
if (!token)
|
|
133
|
-
throw new Error("CLOUDFLARE_API_TOKEN is required unless --dry-run is used.");
|
|
134
146
|
const zoneId = options.zoneId || await findCloudflareZoneId(plan.hostname, token);
|
|
135
147
|
const existing = await cloudflareRequest(token, `/zones/${zoneId}/dns_records?type=CNAME&name=${encodeURIComponent(plan.hostname)}`);
|
|
136
148
|
const payload = JSON.stringify(plan.dnsRecord);
|
package/dist/index.js
CHANGED
|
@@ -656,11 +656,25 @@ SHORTLINKS_ORIGIN = "${options.origin || "https://shortlinks.example.com"}"
|
|
|
656
656
|
`);
|
|
657
657
|
return { workerPath, wranglerPath };
|
|
658
658
|
}
|
|
659
|
+
function cloudflareAuthHeaders(token) {
|
|
660
|
+
const apiToken = token || process.env.CLOUDFLARE_API_TOKEN;
|
|
661
|
+
if (apiToken)
|
|
662
|
+
return { authorization: `Bearer ${apiToken}` };
|
|
663
|
+
const apiKey = process.env.CLOUDFLARE_API_KEY;
|
|
664
|
+
const email = process.env.CLOUDFLARE_EMAIL;
|
|
665
|
+
if (apiKey && email) {
|
|
666
|
+
return {
|
|
667
|
+
"x-auth-key": apiKey,
|
|
668
|
+
"x-auth-email": email
|
|
669
|
+
};
|
|
670
|
+
}
|
|
671
|
+
throw new Error("Cloudflare auth is required: set CLOUDFLARE_API_TOKEN, or CLOUDFLARE_API_KEY plus CLOUDFLARE_EMAIL.");
|
|
672
|
+
}
|
|
659
673
|
async function cloudflareRequest(token, path, init = {}) {
|
|
660
674
|
const response = await fetch(`https://api.cloudflare.com/client/v4${path}`, {
|
|
661
675
|
...init,
|
|
662
676
|
headers: {
|
|
663
|
-
|
|
677
|
+
...cloudflareAuthHeaders(token),
|
|
664
678
|
"content-type": "application/json",
|
|
665
679
|
...init.headers || {}
|
|
666
680
|
}
|
|
@@ -698,8 +712,6 @@ async function upsertCloudflareDnsRecord(options) {
|
|
|
698
712
|
});
|
|
699
713
|
if (options.dryRun)
|
|
700
714
|
return plan;
|
|
701
|
-
if (!token)
|
|
702
|
-
throw new Error("CLOUDFLARE_API_TOKEN is required unless --dry-run is used.");
|
|
703
715
|
const zoneId = options.zoneId || await findCloudflareZoneId(plan.hostname, token);
|
|
704
716
|
const existing = await cloudflareRequest(token, `/zones/${zoneId}/dns_records?type=CNAME&name=${encodeURIComponent(plan.hostname)}`);
|
|
705
717
|
const payload = JSON.stringify(plan.dnsRecord);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@hasna/shortlinks",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.2",
|
|
4
4
|
"description": "CLI-only shortlink manager for custom domains, click tracking, Cloudflare setup, and @hasna cloud sync",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -30,7 +30,7 @@
|
|
|
30
30
|
"SECURITY.md"
|
|
31
31
|
],
|
|
32
32
|
"scripts": {
|
|
33
|
-
"build": "bun build src/cli/index.ts --outdir dist/cli --target bun --external @hasna/cloud && bun build src/index.ts --outdir dist --target bun --external @hasna/cloud && bun build src/server.ts --outdir dist --target bun && bun build src/cloudflare.ts --outdir dist --target bun && tsc --emitDeclarationOnly --outDir dist",
|
|
33
|
+
"build": "rm -rf dist && bun build src/cli/index.ts --outdir dist/cli --target bun --external @hasna/cloud && bun build src/index.ts --outdir dist --target bun --external @hasna/cloud && bun build src/server.ts --outdir dist --target bun && bun build src/cloudflare.ts --outdir dist --target bun && tsc -p tsconfig.build.json --emitDeclarationOnly --outDir dist",
|
|
34
34
|
"typecheck": "tsc --noEmit",
|
|
35
35
|
"test": "bun test",
|
|
36
36
|
"dev:cli": "bun run src/cli/index.ts",
|
|
@@ -54,7 +54,7 @@
|
|
|
54
54
|
},
|
|
55
55
|
"repository": {
|
|
56
56
|
"type": "git",
|
|
57
|
-
"url": "https://github.com/hasna/shortlinks.git"
|
|
57
|
+
"url": "git+https://github.com/hasna/shortlinks.git"
|
|
58
58
|
},
|
|
59
59
|
"homepage": "https://github.com/hasna/shortlinks",
|
|
60
60
|
"bugs": {
|
package/dist/cli/cli.test.d.ts
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
package/dist/server.test.d.ts
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
package/dist/store.test.d.ts
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|