robodev 0.20.0 → 0.21.1
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/package.json +1 -1
- package/src/emit-starter.test.ts +1 -1
- package/src/index.ts +14 -4
- package/src/print-live-url.test.ts +31 -0
- package/src/print-live-url.ts +6 -0
- package/templates/auth-chat/.rulesync/skills/media-feature/SKILL.md +1 -1
- package/templates/auth-chat/package.json +1 -1
- package/templates/backend/package.json +1 -1
- package/templates/empty/package.json +1 -1
- package/templates/space/.rulesync/skills/media-feature/SKILL.md +1 -1
- package/templates/space/openapi.json +1 -1
- package/templates/space/package.json +1 -1
- /package/templates/backend/api/files/{presigned-url.ts → upload-request.ts} +0 -0
- /package/templates/space/api/files/{presigned-url.ts → upload-request.ts} +0 -0
package/package.json
CHANGED
package/src/emit-starter.test.ts
CHANGED
|
@@ -84,7 +84,7 @@ test("collectFiles for space starter is Tiny APIs without apps/fe", async () =>
|
|
|
84
84
|
assert.ok(paths.has("api/planets.ts"));
|
|
85
85
|
assert.ok(paths.has("api/planets/paginate.ts"));
|
|
86
86
|
assert.ok(paths.has("api/aliens/labels.ts"));
|
|
87
|
-
assert.ok(paths.has("api/files/
|
|
87
|
+
assert.ok(paths.has("api/files/upload-request.ts"));
|
|
88
88
|
assert.ok(paths.has("api/files/upload.ts"));
|
|
89
89
|
assert.ok(!paths.has("index.html"));
|
|
90
90
|
assert.ok(!paths.has("src/main.tsx"));
|
package/src/index.ts
CHANGED
|
@@ -32,6 +32,7 @@ import {
|
|
|
32
32
|
type Starter,
|
|
33
33
|
} from "./emit-starter.js";
|
|
34
34
|
import { parseCreateArgs } from "./parse-create-args.js";
|
|
35
|
+
import { printLiveUrl } from "./print-live-url.js";
|
|
35
36
|
|
|
36
37
|
const execFileAsync = promisify(execFile);
|
|
37
38
|
|
|
@@ -230,7 +231,10 @@ async function collectDeployFiles(
|
|
|
230
231
|
}
|
|
231
232
|
|
|
232
233
|
/** Uploads schema, APIs, and frontend. Destructive schema changes need confirmation or `--force`. */
|
|
233
|
-
async function runDeploy(
|
|
234
|
+
async function runDeploy(
|
|
235
|
+
forceFlag: boolean,
|
|
236
|
+
options: DeployOptions = {},
|
|
237
|
+
): Promise<string | undefined> {
|
|
234
238
|
const root = options.root ?? process.cwd();
|
|
235
239
|
const link = await readLink(root);
|
|
236
240
|
if (!link) {
|
|
@@ -273,7 +277,7 @@ async function runDeploy(forceFlag: boolean, options: DeployOptions = {}): Promi
|
|
|
273
277
|
for (const route of result.routes) {
|
|
274
278
|
console.log(` ${route.method.toUpperCase()} ${route.path}`);
|
|
275
279
|
}
|
|
276
|
-
return;
|
|
280
|
+
return result.appUrl ?? result.apiUrl;
|
|
277
281
|
} catch (error) {
|
|
278
282
|
if (
|
|
279
283
|
error instanceof ApiError &&
|
|
@@ -299,7 +303,7 @@ async function runDeploy(forceFlag: boolean, options: DeployOptions = {}): Promi
|
|
|
299
303
|
const answer = await prompt("Apply destructive changes? (y/N) ");
|
|
300
304
|
if (!/^y(es)?$/i.test(answer.trim())) {
|
|
301
305
|
console.log("Deploy cancelled.");
|
|
302
|
-
return;
|
|
306
|
+
return undefined;
|
|
303
307
|
}
|
|
304
308
|
force = true;
|
|
305
309
|
continue;
|
|
@@ -512,7 +516,7 @@ async function runCreate(args: string[]): Promise<void> {
|
|
|
512
516
|
skipFrontendBuild = true;
|
|
513
517
|
}
|
|
514
518
|
}
|
|
515
|
-
await runDeploy(false, { root, frontendFiles, skipFrontendBuild });
|
|
519
|
+
const liveUrl = await runDeploy(false, { root, frontendFiles, skipFrontendBuild });
|
|
516
520
|
|
|
517
521
|
try {
|
|
518
522
|
await npmInstall(root);
|
|
@@ -529,6 +533,9 @@ async function runCreate(args: string[]): Promise<void> {
|
|
|
529
533
|
} else {
|
|
530
534
|
console.log("Run `npm install` in the project folder, then `npm run dev`.");
|
|
531
535
|
}
|
|
536
|
+
if (liveUrl) {
|
|
537
|
+
printLiveUrl(liveUrl);
|
|
538
|
+
}
|
|
532
539
|
return;
|
|
533
540
|
}
|
|
534
541
|
|
|
@@ -553,6 +560,9 @@ async function runCreate(args: string[]): Promise<void> {
|
|
|
553
560
|
}
|
|
554
561
|
console.log(" npm run dev");
|
|
555
562
|
}
|
|
563
|
+
if (liveUrl) {
|
|
564
|
+
printLiveUrl(liveUrl);
|
|
565
|
+
}
|
|
556
566
|
}
|
|
557
567
|
|
|
558
568
|
async function main(): Promise<void> {
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import assert from "node:assert/strict";
|
|
2
|
+
import { test } from "node:test";
|
|
3
|
+
import { printLiveUrl } from "./print-live-url.js";
|
|
4
|
+
|
|
5
|
+
test("printLiveUrl writes a blank line, Live label, and verbatim URL", () => {
|
|
6
|
+
const lines: string[] = [];
|
|
7
|
+
const original = console.log;
|
|
8
|
+
console.log = (...args: unknown[]) => {
|
|
9
|
+
lines.push(args.map(String).join(" "));
|
|
10
|
+
};
|
|
11
|
+
try {
|
|
12
|
+
printLiveUrl("https://prj_1.robodev.povio.dev");
|
|
13
|
+
} finally {
|
|
14
|
+
console.log = original;
|
|
15
|
+
}
|
|
16
|
+
assert.deepEqual(lines, ["", "Live", "https://prj_1.robodev.povio.dev"]);
|
|
17
|
+
});
|
|
18
|
+
|
|
19
|
+
test("printLiveUrl prints a local project host verbatim", () => {
|
|
20
|
+
const lines: string[] = [];
|
|
21
|
+
const original = console.log;
|
|
22
|
+
console.log = (...args: unknown[]) => {
|
|
23
|
+
lines.push(args.map(String).join(" "));
|
|
24
|
+
};
|
|
25
|
+
try {
|
|
26
|
+
printLiveUrl("http://prj_1.localhost:4000");
|
|
27
|
+
} finally {
|
|
28
|
+
console.log = original;
|
|
29
|
+
}
|
|
30
|
+
assert.deepEqual(lines, ["", "Live", "http://prj_1.localhost:4000"]);
|
|
31
|
+
});
|
|
@@ -11,7 +11,7 @@ codexcli:
|
|
|
11
11
|
Preserve the upload contract:
|
|
12
12
|
|
|
13
13
|
1. Frontend selects a `File`.
|
|
14
|
-
2. Frontend calls `MediaQueries.useUploadRequest` with metadata only (`POST /api/files/
|
|
14
|
+
2. Frontend calls `MediaQueries.useUploadRequest` with metadata only (`POST /api/files/upload-request`).
|
|
15
15
|
3. Frontend uploads bytes to the returned URL (`POST /api/files/upload` via Starbase `ctx.storage`).
|
|
16
16
|
4. Feature create/update submits only `image: { id }`.
|
|
17
17
|
5. Feature reads resolve that ID to `image: { id, url }`.
|
|
@@ -11,7 +11,7 @@ codexcli:
|
|
|
11
11
|
Preserve the upload contract:
|
|
12
12
|
|
|
13
13
|
1. Frontend selects a `File`.
|
|
14
|
-
2. Frontend calls `MediaQueries.useUploadRequest` with metadata only (`POST /api/files/
|
|
14
|
+
2. Frontend calls `MediaQueries.useUploadRequest` with metadata only (`POST /api/files/upload-request`).
|
|
15
15
|
3. Frontend uploads bytes to the returned URL (`POST /api/files/upload` via Starbase `ctx.storage`).
|
|
16
16
|
4. Feature create/update submits only `image: { id }`.
|
|
17
17
|
5. Feature reads resolve that ID to `image: { id, url }`.
|
|
@@ -1209,7 +1209,7 @@
|
|
|
1209
1209
|
"x-bl": "Consumes a valid unused password reset code."
|
|
1210
1210
|
}
|
|
1211
1211
|
},
|
|
1212
|
-
"/api/files/
|
|
1212
|
+
"/api/files/upload-request": {
|
|
1213
1213
|
"post": {
|
|
1214
1214
|
"operationId": "MediaLibraryController_uploadRequest",
|
|
1215
1215
|
"tags": ["Media"],
|
|
File without changes
|
|
File without changes
|