create-colonel 1.1.2 → 1.1.3
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 +10 -0
- package/package.json +1 -1
- package/src/cli.ts +40 -19
package/README.md
CHANGED
|
@@ -28,6 +28,16 @@ bunx create-colonel my-app --skip-install
|
|
|
28
28
|
|
|
29
29
|
Telemetry flags:
|
|
30
30
|
|
|
31
|
+
```bash
|
|
32
|
+
bunx create-colonel my-app \
|
|
33
|
+
--telemetry yes \
|
|
34
|
+
--telemetry-endpoint https://colonel-telemetry.vercel.app/api/ingest
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
By default, when telemetry consent is `yes`, create-colonel uses the public provisioning endpoint to fetch app credentials automatically.
|
|
38
|
+
|
|
39
|
+
Optional secure provisioning override:
|
|
40
|
+
|
|
31
41
|
```bash
|
|
32
42
|
bunx create-colonel my-app \
|
|
33
43
|
--telemetry yes \
|
package/package.json
CHANGED
package/src/cli.ts
CHANGED
|
@@ -9,12 +9,14 @@ type TelemetryConsent = "yes" | "no";
|
|
|
9
9
|
|
|
10
10
|
const DEFAULT_TELEMETRY_ENDPOINT = "https://colonel-telemetry.vercel.app/api/ingest";
|
|
11
11
|
|
|
12
|
-
const deriveProvisionEndpoint = (ingestEndpoint: string): string => {
|
|
12
|
+
const deriveProvisionEndpoint = (ingestEndpoint: string, publicProvision = false): string => {
|
|
13
|
+
const suffix = publicProvision ? "/api/provision-public" : "/api/provision-app";
|
|
14
|
+
|
|
13
15
|
if (ingestEndpoint.endsWith("/api/ingest")) {
|
|
14
|
-
return `${ingestEndpoint.slice(0, -"/api/ingest".length)}
|
|
16
|
+
return `${ingestEndpoint.slice(0, -"/api/ingest".length)}${suffix}`;
|
|
15
17
|
}
|
|
16
18
|
|
|
17
|
-
return `${ingestEndpoint.replace(/\/$/, "")}
|
|
19
|
+
return `${ingestEndpoint.replace(/\/$/, "")}${suffix}`;
|
|
18
20
|
};
|
|
19
21
|
|
|
20
22
|
const upsertEnv = (content: string, key: string, value: string): string => {
|
|
@@ -70,15 +72,20 @@ const provisionTelemetryApp = async (
|
|
|
70
72
|
appName: string,
|
|
71
73
|
source: string,
|
|
72
74
|
provisionEndpoint: string,
|
|
73
|
-
provisionToken
|
|
75
|
+
provisionToken?: string
|
|
74
76
|
): Promise<{ appId: string; ingestKey: string } | null> => {
|
|
75
77
|
try {
|
|
78
|
+
const headers: Record<string, string> = {
|
|
79
|
+
"content-type": "application/json",
|
|
80
|
+
};
|
|
81
|
+
|
|
82
|
+
if (provisionToken) {
|
|
83
|
+
headers.authorization = `Bearer ${provisionToken}`;
|
|
84
|
+
}
|
|
85
|
+
|
|
76
86
|
const response = await fetch(provisionEndpoint, {
|
|
77
87
|
method: "POST",
|
|
78
|
-
headers
|
|
79
|
-
"content-type": "application/json",
|
|
80
|
-
authorization: `Bearer ${provisionToken}`,
|
|
81
|
-
},
|
|
88
|
+
headers,
|
|
82
89
|
body: JSON.stringify({ appName, source }),
|
|
83
90
|
});
|
|
84
91
|
|
|
@@ -128,25 +135,29 @@ const showHelp = args.includes("--help") || args.includes("-h");
|
|
|
128
135
|
const telemetryFlag = parseOptionValue(args, "--telemetry");
|
|
129
136
|
const telemetryConsentFromFlag = normalizeConsent(telemetryFlag);
|
|
130
137
|
const telemetryEndpoint = parseOptionValue(args, "--telemetry-endpoint") ?? process.env.COLONEL_TELEMETRY_ENDPOINT ?? DEFAULT_TELEMETRY_ENDPOINT;
|
|
131
|
-
const
|
|
138
|
+
const secureProvisionEndpoint = parseOptionValue(args, "--telemetry-provision-endpoint")
|
|
132
139
|
?? process.env.COLONEL_TELEMETRY_PROVISION_ENDPOINT
|
|
133
|
-
?? deriveProvisionEndpoint(telemetryEndpoint);
|
|
140
|
+
?? deriveProvisionEndpoint(telemetryEndpoint, false);
|
|
141
|
+
const publicProvisionEndpoint = parseOptionValue(args, "--telemetry-public-provision-endpoint")
|
|
142
|
+
?? process.env.COLONEL_TELEMETRY_PUBLIC_PROVISION_ENDPOINT
|
|
143
|
+
?? deriveProvisionEndpoint(telemetryEndpoint, true);
|
|
134
144
|
const provisionToken = parseOptionValue(args, "--telemetry-provision-token")
|
|
135
145
|
?? process.env.COLONEL_TELEMETRY_PROVISION_TOKEN;
|
|
136
146
|
|
|
137
147
|
if (showHelp) {
|
|
138
|
-
console.log("Usage: bunx create-colonel <project-name> [--skip-install] [--telemetry yes|no] [--telemetry-endpoint <url>] [--telemetry-provision-endpoint <url>] [--telemetry-provision-token <token>]");
|
|
148
|
+
console.log("Usage: bunx create-colonel <project-name> [--skip-install] [--telemetry yes|no] [--telemetry-endpoint <url>] [--telemetry-provision-endpoint <url>] [--telemetry-public-provision-endpoint <url>] [--telemetry-provision-token <token>]");
|
|
139
149
|
console.log("\nOptions:");
|
|
140
150
|
console.log(" --skip-install Scaffold files without running bun install");
|
|
141
151
|
console.log(" --telemetry Set anonymous telemetry consent without interactive prompt");
|
|
142
152
|
console.log(" --telemetry-endpoint Override telemetry ingestion endpoint");
|
|
143
153
|
console.log(" --telemetry-provision-endpoint Override telemetry app provisioning endpoint");
|
|
154
|
+
console.log(" --telemetry-public-provision-endpoint Override public app provisioning endpoint");
|
|
144
155
|
console.log(" --telemetry-provision-token Bearer token used for telemetry app provisioning");
|
|
145
156
|
process.exit(0);
|
|
146
157
|
}
|
|
147
158
|
|
|
148
159
|
if (!targetArg) {
|
|
149
|
-
console.error("Usage: bunx create-colonel <project-name> [--skip-install] [--telemetry yes|no] [--telemetry-endpoint <url>] [--telemetry-provision-endpoint <url>] [--telemetry-provision-token <token>]");
|
|
160
|
+
console.error("Usage: bunx create-colonel <project-name> [--skip-install] [--telemetry yes|no] [--telemetry-endpoint <url>] [--telemetry-provision-endpoint <url>] [--telemetry-public-provision-endpoint <url>] [--telemetry-provision-token <token>]");
|
|
150
161
|
process.exit(1);
|
|
151
162
|
}
|
|
152
163
|
|
|
@@ -185,16 +196,26 @@ const consent = telemetryConsentFromFlag ?? await askTelemetryConsent();
|
|
|
185
196
|
let provisionedAppId: string | undefined;
|
|
186
197
|
let provisionedIngestKey: string | undefined;
|
|
187
198
|
|
|
188
|
-
if (consent === "yes"
|
|
189
|
-
const provisioned =
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
199
|
+
if (consent === "yes") {
|
|
200
|
+
const provisioned = provisionToken
|
|
201
|
+
? await provisionTelemetryApp(
|
|
202
|
+
basename(targetDir),
|
|
203
|
+
"create-colonel",
|
|
204
|
+
secureProvisionEndpoint,
|
|
205
|
+
provisionToken
|
|
206
|
+
)
|
|
207
|
+
: await provisionTelemetryApp(
|
|
208
|
+
basename(targetDir),
|
|
209
|
+
"create-colonel",
|
|
210
|
+
publicProvisionEndpoint
|
|
211
|
+
);
|
|
195
212
|
|
|
196
213
|
provisionedAppId = provisioned?.appId;
|
|
197
214
|
provisionedIngestKey = provisioned?.ingestKey;
|
|
215
|
+
|
|
216
|
+
if (!provisionedAppId || !provisionedIngestKey) {
|
|
217
|
+
console.warn("Telemetry consented but provisioning did not return credentials.");
|
|
218
|
+
}
|
|
198
219
|
}
|
|
199
220
|
|
|
200
221
|
configureTelemetryEnv(targetDir, consent, telemetryEndpoint, provisionedAppId, provisionedIngestKey);
|