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.
Files changed (3) hide show
  1. package/README.md +10 -0
  2. package/package.json +1 -1
  3. 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
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "create-colonel",
3
- "version": "1.1.2",
3
+ "version": "1.1.3",
4
4
  "type": "module",
5
5
  "files": [
6
6
  "src",
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)}/api/provision-app`;
16
+ return `${ingestEndpoint.slice(0, -"/api/ingest".length)}${suffix}`;
15
17
  }
16
18
 
17
- return `${ingestEndpoint.replace(/\/$/, "")}/api/provision-app`;
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: string
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 provisionEndpoint = parseOptionValue(args, "--telemetry-provision-endpoint")
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" && provisionToken) {
189
- const provisioned = await provisionTelemetryApp(
190
- basename(targetDir),
191
- "create-colonel",
192
- provisionEndpoint,
193
- provisionToken
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);