@octonodes/cli 0.2.11 → 0.2.13
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 +27 -6
- package/dist/apps/build.d.ts.map +1 -1
- package/dist/apps/build.js +15 -0
- package/dist/apps/build.js.map +1 -1
- package/dist/apps/constants.d.ts +1 -1
- package/dist/apps/constants.d.ts.map +1 -1
- package/dist/apps/constants.js +5 -2
- package/dist/apps/constants.js.map +1 -1
- package/dist/apps/create.d.ts +1 -1
- package/dist/apps/create.d.ts.map +1 -1
- package/dist/apps/create.js +52 -22
- package/dist/apps/create.js.map +1 -1
- package/dist/apps/dev.d.ts +2 -2
- package/dist/apps/dev.d.ts.map +1 -1
- package/dist/apps/dev.js +67 -14
- package/dist/apps/dev.js.map +1 -1
- package/dist/apps/development.d.ts.map +1 -1
- package/dist/apps/development.js +1 -1
- package/dist/apps/development.js.map +1 -1
- package/dist/apps/index.d.ts.map +1 -1
- package/dist/apps/index.js +7 -1
- package/dist/apps/index.js.map +1 -1
- package/dist/apps/server.d.ts +1 -1
- package/dist/apps/server.d.ts.map +1 -1
- package/dist/apps/server.js +30 -1
- package/dist/apps/server.js.map +1 -1
- package/dist/apps/source.d.ts.map +1 -1
- package/dist/apps/source.js +2 -1
- package/dist/apps/source.js.map +1 -1
- package/dist/apps/tunnel-lease.d.ts +6 -0
- package/dist/apps/tunnel-lease.d.ts.map +1 -0
- package/dist/apps/tunnel-lease.js +61 -0
- package/dist/apps/tunnel-lease.js.map +1 -0
- package/dist/apps/types.d.ts +1 -0
- package/dist/apps/types.d.ts.map +1 -1
- package/dist/apps/welcome.d.ts +4 -0
- package/dist/apps/welcome.d.ts.map +1 -0
- package/dist/apps/welcome.js +39 -0
- package/dist/apps/welcome.js.map +1 -0
- package/dist/auth.d.ts.map +1 -1
- package/dist/auth.js +8 -2
- package/dist/auth.js.map +1 -1
- package/dist/index.js +5 -1
- package/dist/index.js.map +1 -1
- package/dist/terminal.d.ts +9 -0
- package/dist/terminal.d.ts.map +1 -0
- package/dist/terminal.js +47 -0
- package/dist/terminal.js.map +1 -0
- package/package.json +3 -3
- package/runtime/plugin-lifecycle.cjs +6 -1
package/README.md
CHANGED
|
@@ -6,7 +6,8 @@ wraps `@octonodes/sdk`, so every generated SDK operation is available without wr
|
|
|
6
6
|
## Create an app
|
|
7
7
|
|
|
8
8
|
Use Node 24 and a CLI release containing `octonodes app`. The default scaffold
|
|
9
|
-
is
|
|
9
|
+
is a full Vite app with a welcome page, backend, and workspace block.
|
|
10
|
+
Use `--template extension` for an extension-only app.
|
|
10
11
|
|
|
11
12
|
```sh
|
|
12
13
|
octonodes app create workspace-notice
|
|
@@ -18,32 +19,52 @@ npm run dev
|
|
|
18
19
|
|
|
19
20
|
Edit `octonode.app.json` and `src/extensions/notice.tsx`. `npm test`
|
|
20
21
|
checks types and verifies build hashes. `npm run dev` watches changes and starts
|
|
21
|
-
a verified
|
|
22
|
+
a verified public HTTPS Quick Tunnel automatically. Branded Octonode preview URLs
|
|
23
|
+
are planned for a later rollout.
|
|
24
|
+
Use `--use-localhost` to skip the
|
|
22
25
|
tunnel; `--tunnel-url <https-origin> --port <port>` uses your own. Preview
|
|
23
26
|
in Studio with `octonodes login` followed by
|
|
24
27
|
`octonodes app dev --workspace user:<id>`.
|
|
28
|
+
Octonode colors are enabled automatically in interactive terminals.
|
|
29
|
+
Redirected output stays plain for scripts.
|
|
25
30
|
|
|
26
31
|
```sh
|
|
27
32
|
octonodes app extension add overview --target app.page
|
|
28
33
|
octonodes app publish --workspace user:<id>
|
|
29
34
|
```
|
|
30
35
|
|
|
31
|
-
|
|
36
|
+
The default app includes a page. Extension-only apps can add one with the command above.
|
|
37
|
+
Install through Studio → Apps; a block appears on
|
|
32
38
|
workspace home, and a page-capable app opens from Apps. An administrator can
|
|
33
39
|
configure or disable an installation. The first publication returns the app ID
|
|
34
40
|
and revision. Increment the source version and publish an update with
|
|
35
41
|
`--app-id <id> --revision <current-revision>`; existing installs remain pinned
|
|
36
42
|
until their administrator approves an update.
|
|
37
43
|
|
|
38
|
-
|
|
39
|
-
full`. Set `web.applicationUrl` in `octonode.app.json` to a permanent HTTPS
|
|
44
|
+
Full apps include a connected backend. Set `web.applicationUrl` in `octonode.app.json` to a permanent HTTPS
|
|
40
45
|
origin, add only necessary `web.requestedActions`, and run `npm test`. The CLI
|
|
41
|
-
publishes release metadata; deploy `dist/web
|
|
46
|
+
publishes release metadata; deploy `dist/web/<app-id>` to a Node 24
|
|
42
47
|
host yourself, set `OCTONODE_APP_ID` and `OCTONODE_API_URL`, and run
|
|
43
48
|
`node start.cjs`. Keep prior content-hashed assets for pinned installations.
|
|
44
49
|
The [Playbook app guide](https://playbook.octonodes.com/docs/apps) covers the
|
|
45
50
|
project file, SDKs, hosting, consent, publishing and updates.
|
|
46
51
|
|
|
52
|
+
Choose the web platform (Vite is the default):
|
|
53
|
+
|
|
54
|
+
```sh
|
|
55
|
+
octonodes app create my-app # Vite
|
|
56
|
+
octonodes app create my-vite-app --platform vite
|
|
57
|
+
octonodes app create my-next-app --platform next
|
|
58
|
+
octonodes app create my-plain-app --platform plain
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
Vite and Next.js create a full app with a real framework page in `src/web/App.tsx`,
|
|
62
|
+
an Octonode welcome page, a workspace block, and the verified `/api/context` backend. The CLI
|
|
63
|
+
builds Vite or a Next.js static export into the same verified web artifact and
|
|
64
|
+
serves it through the development tunnel. Next.js server features are outside
|
|
65
|
+
this static export; add backend routes in `src/server.ts`.
|
|
66
|
+
Plain uses `src/welcome.html` and the same backend without Vite or Next.js.
|
|
67
|
+
|
|
47
68
|
## Create and publish plugins
|
|
48
69
|
|
|
49
70
|
```sh
|
package/dist/apps/build.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"build.d.ts","sourceRoot":"","sources":["../../src/apps/build.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"build.d.ts","sourceRoot":"","sources":["../../src/apps/build.ts"],"names":[],"mappings":"AAgBA,OAAO,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AAKxD,wBAAsB,eAAe,CAAC,SAAS,EAAE,MAAM,EAAE,cAAc,CAAC,EAAE,MAAM;;;;GAqK/E;AAED,wBAAgB,cAAc,CAAC,SAAS,EAAE,MAAM;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAa/C"}
|
package/dist/apps/build.js
CHANGED
|
@@ -4,6 +4,8 @@ exports.buildAppProject = buildAppProject;
|
|
|
4
4
|
exports.verifyWebBuild = verifyWebBuild;
|
|
5
5
|
const node_fs_1 = require("node:fs");
|
|
6
6
|
const node_path_1 = require("node:path");
|
|
7
|
+
const node_child_process_1 = require("node:child_process");
|
|
8
|
+
const node_util_1 = require("node:util");
|
|
7
9
|
const esbuild_1 = require("esbuild");
|
|
8
10
|
const plugins_1 = require("@octonodes/sdk/plugins");
|
|
9
11
|
const app_1 = require("../plugins/app");
|
|
@@ -101,6 +103,19 @@ async function buildAppProject(directory, applicationUrl) {
|
|
|
101
103
|
assertSourceInputs(root, Object.keys(backend.metafile.inputs));
|
|
102
104
|
if (backend.warnings.length)
|
|
103
105
|
throw new Error(backend.warnings.map((warning) => warning.text).join("\n"));
|
|
106
|
+
if (source.web.platform === "vite" || source.web.platform === "next") {
|
|
107
|
+
const command = source.web.platform === "next" ? "next/dist/bin/next" : "vite/bin/vite.js";
|
|
108
|
+
await (0, node_util_1.promisify)(node_child_process_1.execFile)(process.execPath, [(0, node_path_1.join)(root, "node_modules", command), "build"], {
|
|
109
|
+
cwd: root,
|
|
110
|
+
maxBuffer: 8 * 1024 * 1024,
|
|
111
|
+
});
|
|
112
|
+
const site = (0, node_path_1.join)(root, source.web.platform === "next" ? "out" : "web-dist");
|
|
113
|
+
(0, artifact_1.pluginFiles)(site);
|
|
114
|
+
(0, node_fs_1.cpSync)(site, (0, node_path_1.join)(stage, "site"), { recursive: true, dereference: false });
|
|
115
|
+
}
|
|
116
|
+
else if ((0, node_fs_1.existsSync)((0, node_path_1.join)(root, "src/welcome.html"))) {
|
|
117
|
+
(0, node_fs_1.copyFileSync)((0, source_1.sourceFile)(root, "src/welcome.html"), (0, node_path_1.join)(stage, "welcome.html"));
|
|
118
|
+
}
|
|
104
119
|
const previousWeb = (0, node_path_1.join)(root, "dist/web", source.id);
|
|
105
120
|
if ((0, node_fs_1.existsSync)(previousWeb)) {
|
|
106
121
|
verifyWebBuild(previousWeb);
|
package/dist/apps/build.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"build.js","sourceRoot":"","sources":["../../src/apps/build.ts"],"names":[],"mappings":";;;;AAAA,
|
|
1
|
+
{"version":3,"file":"build.js","sourceRoot":"","sources":["../../src/apps/build.ts"],"names":[],"mappings":"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"}
|
package/dist/apps/constants.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
export declare const APP_SOURCE = "octonode.app.json";
|
|
2
|
-
export declare const APP_HELP = "Usage:\n octonodes app create <name> [--template extension|full]\n octonodes app extension add <id> --target workspace.block|app.page [--cwd <directory>]\n octonodes app dev [directory] [--use-localhost | --tunnel-url <https-origin>] [--port <port>] [--no-open] [--workspace kind:id]\n octonodes app build [directory] [--app-url <https-origin>]\n octonodes app serve [directory] [--port <port>]\n octonodes app publish [directory] --workspace kind:id [--app-id <id> --revision <n>]\n octonodes app validate <artifact-directory>\n\nCreate defaults to a workspace block
|
|
2
|
+
export declare const APP_HELP = "Usage:\n octonodes app create <name> [--template extension|full] [--platform plain|vite|next]\n octonodes app extension add <id> --target workspace.block|app.page [--cwd <directory>]\n octonodes app dev [directory] [--use-localhost | --tunnel-url <https-origin>] [--port <port>] [--no-open] [--workspace kind:id]\n octonodes app build [directory] [--app-url <https-origin>]\n octonodes app serve [directory] [--port <port>]\n octonodes app publish [directory] --workspace kind:id [--app-id <id> --revision <n>]\n octonodes app validate <artifact-directory>\n\nCreate defaults to a full Vite app (--platform vite). Use --platform plain for HTML or\n--platform next for Next.js. Use --template extension for an extension-only workspace block.\nBuild compiles declared browser entries and generates\nrelease hashes in dist/apps/<id>. Existing projects are never overwritten. No login is needed.\napp dev opens a public Quick Tunnel automatically.\napp dev automatically downloads and caches its tunnel helper. No Cloudflare account or install is needed. --workspace opens an expiring Studio preview after login.\napp publish creates an immutable release; full apps must deploy their backend separately.\nInstallation requires Studio consent.\n";
|
|
3
3
|
export declare const CLOUDFLARED_VERSION = "2026.9.3";
|
|
4
4
|
export declare const CLOUDFLARED_ASSETS: Record<string, import("./types").CloudflaredAsset>;
|
|
5
5
|
//# sourceMappingURL=constants.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../../src/apps/constants.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,UAAU,sBAAsB,CAAC;AAC9C,eAAO,MAAM,QAAQ,
|
|
1
|
+
{"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../../src/apps/constants.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,UAAU,sBAAsB,CAAC;AAC9C,eAAO,MAAM,QAAQ,ouCAiBpB,CAAC;AAGF,eAAO,MAAM,mBAAmB,aAAa,CAAC;AAC9C,eAAO,MAAM,kBAAkB,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,SAAS,EAAE,gBAAgB,CAuBjF,CAAC"}
|
package/dist/apps/constants.js
CHANGED
|
@@ -3,7 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.CLOUDFLARED_ASSETS = exports.CLOUDFLARED_VERSION = exports.APP_HELP = exports.APP_SOURCE = void 0;
|
|
4
4
|
exports.APP_SOURCE = "octonode.app.json";
|
|
5
5
|
exports.APP_HELP = `Usage:
|
|
6
|
-
octonodes app create <name> [--template extension|full]
|
|
6
|
+
octonodes app create <name> [--template extension|full] [--platform plain|vite|next]
|
|
7
7
|
octonodes app extension add <id> --target workspace.block|app.page [--cwd <directory>]
|
|
8
8
|
octonodes app dev [directory] [--use-localhost | --tunnel-url <https-origin>] [--port <port>] [--no-open] [--workspace kind:id]
|
|
9
9
|
octonodes app build [directory] [--app-url <https-origin>]
|
|
@@ -11,8 +11,11 @@ exports.APP_HELP = `Usage:
|
|
|
11
11
|
octonodes app publish [directory] --workspace kind:id [--app-id <id> --revision <n>]
|
|
12
12
|
octonodes app validate <artifact-directory>
|
|
13
13
|
|
|
14
|
-
Create defaults to a
|
|
14
|
+
Create defaults to a full Vite app (--platform vite). Use --platform plain for HTML or
|
|
15
|
+
--platform next for Next.js. Use --template extension for an extension-only workspace block.
|
|
16
|
+
Build compiles declared browser entries and generates
|
|
15
17
|
release hashes in dist/apps/<id>. Existing projects are never overwritten. No login is needed.
|
|
18
|
+
app dev opens a public Quick Tunnel automatically.
|
|
16
19
|
app dev automatically downloads and caches its tunnel helper. No Cloudflare account or install is needed. --workspace opens an expiring Studio preview after login.
|
|
17
20
|
app publish creates an immutable release; full apps must deploy their backend separately.
|
|
18
21
|
Installation requires Studio consent.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"constants.js","sourceRoot":"","sources":["../../src/apps/constants.ts"],"names":[],"mappings":";;;AAAa,QAAA,UAAU,GAAG,mBAAmB,CAAC;AACjC,QAAA,QAAQ,GAAG
|
|
1
|
+
{"version":3,"file":"constants.js","sourceRoot":"","sources":["../../src/apps/constants.ts"],"names":[],"mappings":";;;AAAa,QAAA,UAAU,GAAG,mBAAmB,CAAC;AACjC,QAAA,QAAQ,GAAG;;;;;;;;;;;;;;;;;CAiBvB,CAAC;AAEF,2FAA2F;AAC9E,QAAA,mBAAmB,GAAG,UAAU,CAAC;AACjC,QAAA,kBAAkB,GAAuD;IACpF,YAAY,EAAE;QACZ,IAAI,EAAE,8BAA8B;QACpC,MAAM,EAAE,kEAAkE;QAC1E,YAAY,EAAE,kEAAkE;KACjF;IACD,cAAc,EAAE;QACd,IAAI,EAAE,8BAA8B;QACpC,MAAM,EAAE,kEAAkE;QAC1E,YAAY,EAAE,kEAAkE;KACjF;IACD,WAAW,EAAE;QACX,IAAI,EAAE,yBAAyB;QAC/B,MAAM,EAAE,kEAAkE;KAC3E;IACD,aAAa,EAAE;QACb,IAAI,EAAE,yBAAyB;QAC/B,MAAM,EAAE,kEAAkE;KAC3E;IACD,WAAW,EAAE;QACX,IAAI,EAAE,+BAA+B;QACrC,MAAM,EAAE,kEAAkE;KAC3E;CACF,CAAC"}
|
package/dist/apps/create.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export declare function createApp(name: string, version: string, template?: string): string;
|
|
1
|
+
export declare function createApp(name: string, version: string, template?: string, platform?: string | undefined): string;
|
|
2
2
|
export declare function addAppExtension(directory: string, id: string, target: string): {
|
|
3
3
|
id: string;
|
|
4
4
|
target: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"create.d.ts","sourceRoot":"","sources":["../../src/apps/create.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"create.d.ts","sourceRoot":"","sources":["../../src/apps/create.ts"],"names":[],"mappings":"AAgBA,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,QAAQ,SAAS,EAAE,QAAQ,GAAE,MAAM,GAAG,SAAoD,GAAG,MAAM,CAiN3J;AACD,wBAAgB,eAAe,CAAC,SAAS,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM;;;;EA8B5E"}
|
package/dist/apps/create.js
CHANGED
|
@@ -6,6 +6,7 @@ const node_fs_1 = require("node:fs");
|
|
|
6
6
|
const node_path_1 = require("node:path");
|
|
7
7
|
const constants_1 = require("./constants");
|
|
8
8
|
const source_1 = require("./source");
|
|
9
|
+
const welcome_1 = require("./welcome");
|
|
9
10
|
const json = (value) => JSON.stringify(value, null, 2) + "\n";
|
|
10
11
|
function extensionCode(target) {
|
|
11
12
|
return `import { defineExtension, Section } from "@octonodes/ui-extensions/react";
|
|
@@ -15,11 +16,16 @@ export default defineExtension(${JSON.stringify(target)}, function Notice() {
|
|
|
15
16
|
});
|
|
16
17
|
`;
|
|
17
18
|
}
|
|
18
|
-
function createApp(name, version, template = "
|
|
19
|
+
function createApp(name, version, template = "full", platform = template === "full" ? "vite" : undefined) {
|
|
19
20
|
if (!/^[a-z0-9][a-z0-9-]*$/.test(name))
|
|
20
21
|
throw new Error("App name must be lowercase alphanumeric/dash");
|
|
21
22
|
if (!["extension", "full"].includes(template))
|
|
22
23
|
throw new Error("Choose --template extension or full");
|
|
24
|
+
if (platform && !["plain", "vite", "next"].includes(platform))
|
|
25
|
+
throw new Error("Choose --platform plain, vite or next");
|
|
26
|
+
if (platform && template !== "full")
|
|
27
|
+
throw new Error("--platform requires --template full");
|
|
28
|
+
const framework = platform === "vite" || platform === "next";
|
|
23
29
|
const root = (0, node_path_1.resolve)(name);
|
|
24
30
|
(0, node_fs_1.mkdirSync)(root);
|
|
25
31
|
try {
|
|
@@ -30,16 +36,27 @@ function createApp(name, version, template = "extension") {
|
|
|
30
36
|
id: name,
|
|
31
37
|
name,
|
|
32
38
|
version: "0.1.0",
|
|
33
|
-
...(template === "full" ? { web: { entry: "src/server.ts" } } : {}),
|
|
39
|
+
...(template === "full" ? { web: { entry: "src/server.ts", ...(platform ? { platform } : {}) } } : {}),
|
|
34
40
|
...(template === "extension"
|
|
35
41
|
? { settings: [{ id: "message", label: "Message", defaultValue: "Welcome to the workspace" }] }
|
|
36
42
|
: {}),
|
|
37
|
-
extensions: [
|
|
43
|
+
extensions: [
|
|
44
|
+
{ id: "notice", target: "workspace.block", entry: "src/extensions/notice.tsx" },
|
|
45
|
+
...(template === "full" ? [{ id: "welcome", target: "app.page", entry: "src/extensions/welcome.tsx" }] : []),
|
|
46
|
+
],
|
|
38
47
|
}));
|
|
39
48
|
(0, node_fs_1.writeFileSync)((0, node_path_1.join)(root, "src/extensions/notice.tsx"), extensionCode("workspace.block"));
|
|
40
|
-
if (template === "full")
|
|
49
|
+
if (template === "full") {
|
|
50
|
+
(0, node_fs_1.writeFileSync)((0, node_path_1.join)(root, "src/extensions/welcome.tsx"), `import { defineExtension, Section } from "@octonodes/ui-extensions/react";
|
|
51
|
+
export default defineExtension("app.page", function Welcome() {
|
|
52
|
+
return <Section title="Welcome to ${name}">Your app is ready. Open the developer-hosted page to see its backend connection.</Section>;
|
|
53
|
+
});
|
|
54
|
+
`);
|
|
55
|
+
if (!framework)
|
|
56
|
+
(0, node_fs_1.writeFileSync)((0, node_path_1.join)(root, "src/welcome.html"), (0, welcome_1.welcomeHtml)(name));
|
|
41
57
|
(0, node_fs_1.writeFileSync)((0, node_path_1.join)(root, "src/server.ts"), `// Export a Fetch API handler. app dev and app serve adapt it to Node HTTP.
|
|
42
58
|
import { connectAppServer } from "@octonodes/ui-extensions/app/server";
|
|
59
|
+
${framework ? "" : 'import { readFileSync } from "node:fs";\nimport { join } from "node:path";'}
|
|
43
60
|
export default async function handle(request: Request): Promise<Response> {
|
|
44
61
|
const path = new URL(request.url).pathname;
|
|
45
62
|
if (path === "/api/context") {
|
|
@@ -54,18 +71,26 @@ export default async function handle(request: Request): Promise<Response> {
|
|
|
54
71
|
}
|
|
55
72
|
if (path === "/api/hello") return Response.json({ message: "Hello from your app backend" });
|
|
56
73
|
if (path !== "/") return new Response("Not found", { status: 404 });
|
|
57
|
-
return new Response(
|
|
58
|
-
<body><h1>My Octonode app</h1><p id="message" role="status">Loading…</p>
|
|
59
|
-
<script>const bearer = new URLSearchParams(location.hash.slice(1)).get('octonode_session');
|
|
60
|
-
history.replaceState(null, '', location.pathname + location.search);
|
|
61
|
-
const output = document.getElementById('message');
|
|
62
|
-
if (!bearer) output.textContent = 'Open this app from Octonode Apps to connect your workspace.';
|
|
63
|
-
else fetch('/api/context', {headers:{authorization:'Bearer '+bearer}}).then(async response=>{
|
|
64
|
-
if(!response.ok) throw Error('Your session expired or access was revoked. Reopen this app from Octonode Apps.');
|
|
65
|
-
const data=await response.json(); output.textContent='Connected to '+data.workspace.kind+':'+data.workspace.id;
|
|
66
|
-
}).catch(error=>output.textContent=error.message);</script></body></html>\`, { headers: { "content-type": "text/html; charset=utf-8" } });
|
|
74
|
+
${framework ? 'return new Response("Not found", { status: 404 });' : 'return new Response(readFileSync(join(__dirname, "welcome.html"), "utf8"), { headers: { "content-type": "text/html; charset=utf-8" } });'}
|
|
67
75
|
}
|
|
68
76
|
`);
|
|
77
|
+
if (framework) {
|
|
78
|
+
(0, node_fs_1.mkdirSync)((0, node_path_1.join)(root, "src/web"), { recursive: true });
|
|
79
|
+
(0, node_fs_1.writeFileSync)((0, node_path_1.join)(root, "src/web/App.tsx"), (0, welcome_1.welcomeReact)(name));
|
|
80
|
+
(0, node_fs_1.writeFileSync)((0, node_path_1.join)(root, "src/web/welcome.css"), welcome_1.welcomeCss + "\n");
|
|
81
|
+
if (platform === "vite") {
|
|
82
|
+
(0, node_fs_1.writeFileSync)((0, node_path_1.join)(root, "index.html"), `<!doctype html><html lang="en"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width,initial-scale=1"><title>${name} · Octonode</title></head><body><div id="root"></div><script type="module" src="/src/web/main.tsx"></script></body></html>\n`);
|
|
83
|
+
(0, node_fs_1.writeFileSync)((0, node_path_1.join)(root, "src/web/main.tsx"), 'import { createRoot } from "react-dom/client";\nimport App from "./App";\nimport "./welcome.css";\ncreateRoot(document.getElementById("root")!).render(<App />);\n');
|
|
84
|
+
(0, node_fs_1.writeFileSync)((0, node_path_1.join)(root, "vite.config.mjs"), 'export default { build: { outDir: "web-dist" } };\n');
|
|
85
|
+
}
|
|
86
|
+
else {
|
|
87
|
+
(0, node_fs_1.mkdirSync)((0, node_path_1.join)(root, "app"));
|
|
88
|
+
(0, node_fs_1.writeFileSync)((0, node_path_1.join)(root, "app/page.tsx"), 'import App from "../src/web/App";\nexport default App;\n');
|
|
89
|
+
(0, node_fs_1.writeFileSync)((0, node_path_1.join)(root, "app/layout.tsx"), `import "../src/web/welcome.css";\nexport const metadata = { title: "${name} · Octonode" };\nexport default function Layout({ children }: { children: React.ReactNode }) { return <html lang="en"><body>{children}</body></html>; }\n`);
|
|
90
|
+
(0, node_fs_1.writeFileSync)((0, node_path_1.join)(root, "next.config.mjs"), 'export default { output: "export" };\n');
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
}
|
|
69
94
|
(0, node_fs_1.writeFileSync)((0, node_path_1.join)(root, "package.json"), json({
|
|
70
95
|
name,
|
|
71
96
|
private: true,
|
|
@@ -75,14 +100,17 @@ else fetch('/api/context', {headers:{authorization:'Bearer '+bearer}}).then(asyn
|
|
|
75
100
|
dev: "octonodes app dev",
|
|
76
101
|
...(template === "full" ? { start: "octonodes app serve" } : {}),
|
|
77
102
|
build: "tsc --noEmit && octonodes app build",
|
|
78
|
-
test:
|
|
103
|
+
test: `tsc --noEmit && octonodes app build${template === "full" ? " --app-url https://development.example" : ""} && node --test tests/*.test.cjs`,
|
|
79
104
|
},
|
|
80
105
|
dependencies: { "@octonodes/ui-extensions": version, react: "^19.0.0", "react-dom": "^19.0.0" },
|
|
81
106
|
devDependencies: {
|
|
82
107
|
"@octonodes/cli": version,
|
|
83
108
|
typescript: "5.9.3",
|
|
84
109
|
"@types/react": "^19.0.0",
|
|
110
|
+
...(platform === "vite" ? { "@types/react-dom": "^19.0.0" } : {}),
|
|
85
111
|
"@types/node": "^24.0.0",
|
|
112
|
+
...(platform === "vite" ? { vite: "8.3.1" } : {}),
|
|
113
|
+
...(platform === "next" ? { next: "16.3.6" } : {}),
|
|
86
114
|
},
|
|
87
115
|
}));
|
|
88
116
|
(0, node_fs_1.writeFileSync)((0, node_path_1.join)(root, "tsconfig.json"), json({
|
|
@@ -95,9 +123,9 @@ else fetch('/api/context', {headers:{authorization:'Bearer '+bearer}}).then(asyn
|
|
|
95
123
|
skipLibCheck: true,
|
|
96
124
|
noEmit: true,
|
|
97
125
|
},
|
|
98
|
-
include: ["src/**/*.ts", "src/**/*.tsx"],
|
|
126
|
+
include: ["src/**/*.ts", "src/**/*.tsx", ...(platform === "next" ? ["app/**/*.tsx"] : [])],
|
|
99
127
|
}));
|
|
100
|
-
(0, node_fs_1.writeFileSync)((0, node_path_1.join)(root, ".gitignore"), "node_modules/\ndist/\n.env\n.env.*\n");
|
|
128
|
+
(0, node_fs_1.writeFileSync)((0, node_path_1.join)(root, ".gitignore"), "node_modules/\ndist/\nweb-dist/\n.next/\nout/\n.env\n.env.*\n");
|
|
101
129
|
(0, node_fs_1.writeFileSync)((0, node_path_1.join)(root, "tests/app.test.cjs"), `const { test } = require("node:test");
|
|
102
130
|
const assert = require("node:assert/strict");
|
|
103
131
|
const { readFileSync } = require("node:fs");
|
|
@@ -115,8 +143,8 @@ test("release bundles match the manifest", () => {
|
|
|
115
143
|
`);
|
|
116
144
|
(0, node_fs_1.writeFileSync)((0, node_path_1.join)(root, "README.md"), `# ${name}
|
|
117
145
|
|
|
118
|
-
An Octonode app created by \`octonodes app create\`.
|
|
119
|
-
\`workspace.block\` on workspace home. Add a page only if the app needs one.
|
|
146
|
+
An Octonode app created by \`octonodes app create\`. It includes a
|
|
147
|
+
\`workspace.block\` on workspace home.${template === "full" ? " The full app also has an Octonode app page and a hosted welcome page." : " Add a page only if the app needs one."}
|
|
120
148
|
|
|
121
149
|
## Work locally
|
|
122
150
|
|
|
@@ -127,11 +155,11 @@ npm run dev
|
|
|
127
155
|
\`\`\`
|
|
128
156
|
|
|
129
157
|
The CLI opens a live HTTPS preview and downloads a verified tunnel helper on first
|
|
130
|
-
use. No Cloudflare account or separate installation is needed. Use
|
|
158
|
+
use. Development opens a public Quick Tunnel automatically. No Cloudflare account or separate installation is needed. Use
|
|
131
159
|
\`octonodes app dev --use-localhost\` for offline UI work.
|
|
132
|
-
Edit \`octonode.app.json\` and \`src/extensions/notice.tsx\`. The descriptor owns
|
|
160
|
+
Edit \`octonode.app.json\` and \`src/extensions/notice.tsx\`. ${framework ? `The ${platform === "next" ? "Next.js" : "Vite"} welcome page lives in \`src/web/App.tsx\`. ` : ""}The descriptor owns
|
|
133
161
|
app identity, version, extension targets and entry files. Do not edit \`dist/\`.
|
|
134
|
-
Add a page with
|
|
162
|
+
${template === "extension" ? "Add a page with `octonodes app extension add overview --target app.page`." : "Edit `src/extensions/welcome.tsx` for the Octonode app page."}
|
|
135
163
|
|
|
136
164
|
## Preview and publish in Octonode
|
|
137
165
|
|
|
@@ -161,6 +189,8 @@ before building and publishing. Add only the \`web.requestedActions\` your
|
|
|
161
189
|
app needs. The generated \`/api/context\` route verifies an installed app
|
|
162
190
|
bearer through \`@octonodes/ui-extensions/app/server\`.
|
|
163
191
|
|
|
192
|
+
${framework ? `The ${platform === "next" ? "Next.js" : "Vite"} page is a native React project. \`octonodes app dev\` builds its static output and serves it together with the Octonode backend. Static export does not support server-only framework features; use \`src/server.ts\` for app API routes.\n\n` : ""}
|
|
193
|
+
|
|
164
194
|
Publishing registers metadata but does not deploy the backend. After the first
|
|
165
195
|
publish returns the app ID, copy the entire \`dist/web/${name}\` directory
|
|
166
196
|
to a Node 24 host. Configure HTTPS, \`PORT\`, \`OCTONODE_APP_ID\` and
|
package/dist/apps/create.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"create.js","sourceRoot":"","sources":["../../src/apps/create.ts"],"names":[],"mappings":";;;;AAAA,qCAA+F;AAC/F,yCAA0C;AAC1C,2CAAyC;AACzC,qCAAsD;
|
|
1
|
+
{"version":3,"file":"create.js","sourceRoot":"","sources":["../../src/apps/create.ts"],"names":[],"mappings":"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"}
|
package/dist/apps/dev.d.ts
CHANGED
|
@@ -4,7 +4,7 @@ export declare function startAppDev(directory: string, options?: DevOptions): Pr
|
|
|
4
4
|
secret: string;
|
|
5
5
|
challenge: string;
|
|
6
6
|
listen(): Promise<number>;
|
|
7
|
-
setOrigin(value: string): void;
|
|
7
|
+
setOrigin(value: string, transportOrigin?: string): void;
|
|
8
8
|
update(source: import("./types").AppSource, directory: string, backend?: (request: Request) => Response | Promise<Response>): void;
|
|
9
9
|
fail(message: string): void;
|
|
10
10
|
close: () => Promise<void>;
|
|
@@ -17,7 +17,7 @@ export declare function serveApp(directory: string, port: number): Promise<{
|
|
|
17
17
|
secret: string;
|
|
18
18
|
challenge: string;
|
|
19
19
|
listen(): Promise<number>;
|
|
20
|
-
setOrigin(value: string): void;
|
|
20
|
+
setOrigin(value: string, transportOrigin?: string): void;
|
|
21
21
|
update(source: import("./types").AppSource, directory: string, backend?: (request: Request) => Response | Promise<Response>): void;
|
|
22
22
|
fail(message: string): void;
|
|
23
23
|
close: () => Promise<void>;
|
package/dist/apps/dev.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dev.d.ts","sourceRoot":"","sources":["../../src/apps/dev.ts"],"names":[],"mappings":"AAWA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;
|
|
1
|
+
{"version":3,"file":"dev.d.ts","sourceRoot":"","sources":["../../src/apps/dev.ts"],"names":[],"mappings":"AAWA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AAQ1C,wBAAsB,WAAW,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,GAAE,UAAe;;;;;;;;;;;;GAqM5E;AAED,wBAAsB,QAAQ,CAAC,SAAS,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM;;;;;;;;;;GAmC7D"}
|
package/dist/apps/dev.js
CHANGED
|
@@ -13,11 +13,18 @@ const server_1 = require("./server");
|
|
|
13
13
|
const cloudflared_1 = require("./cloudflared");
|
|
14
14
|
const tunnel_1 = require("./tunnel");
|
|
15
15
|
const development_1 = require("./development");
|
|
16
|
+
const tunnel_lease_1 = require("./tunnel-lease");
|
|
17
|
+
const auth_1 = require("../auth");
|
|
18
|
+
const terminal_1 = require("../terminal");
|
|
19
|
+
// Enable after the private preview route has wildcard TLS and passes the live smoke test.
|
|
20
|
+
const BRANDED_APP_PREVIEWS_ENABLED = false;
|
|
16
21
|
async function startAppDev(directory, options = {}) {
|
|
17
22
|
if (options.localhost && options.tunnelUrl)
|
|
18
23
|
throw new Error("Choose --use-localhost or --tunnel-url");
|
|
19
24
|
if (options.workspace && options.localhost)
|
|
20
25
|
throw new Error("Studio preview requires an HTTPS tunnel; omit --use-localhost");
|
|
26
|
+
terminal_1.terminal.brand();
|
|
27
|
+
terminal_1.terminal.step(options.workspace ? `Connecting to ${options.workspace}` : "Preparing local preview");
|
|
21
28
|
const development = options.workspace
|
|
22
29
|
? await (0, development_1.createDevelopmentSession)(options.workspace, options.baseUrl, options.studioUrl)
|
|
23
30
|
: undefined;
|
|
@@ -40,6 +47,7 @@ async function startAppDev(directory, options = {}) {
|
|
|
40
47
|
source,
|
|
41
48
|
development: true,
|
|
42
49
|
});
|
|
50
|
+
let lease;
|
|
43
51
|
let tunnel;
|
|
44
52
|
let watcher;
|
|
45
53
|
let timer;
|
|
@@ -58,6 +66,7 @@ async function startAppDev(directory, options = {}) {
|
|
|
58
66
|
tunnel?.stop();
|
|
59
67
|
await host.close();
|
|
60
68
|
await buildTask;
|
|
69
|
+
await lease?.close().catch(() => process.stderr.write("Tunnel cleanup failed; the branded URL expires automatically\n"));
|
|
61
70
|
await development?.close();
|
|
62
71
|
process.off("SIGINT", onSignal);
|
|
63
72
|
process.off("SIGTERM", onSignal);
|
|
@@ -69,15 +78,18 @@ async function startAppDev(directory, options = {}) {
|
|
|
69
78
|
process.once("SIGTERM", onSignal);
|
|
70
79
|
try {
|
|
71
80
|
const port = await host.listen();
|
|
81
|
+
terminal_1.terminal.step(options.localhost ? "Starting local server" : "Opening secure tunnel");
|
|
72
82
|
const executable = !options.localhost && !options.tunnelUrl ? await (0, cloudflared_1.ensureCloudflared)(startup.signal) : undefined;
|
|
73
83
|
startup.signal.throwIfAborted();
|
|
74
|
-
|
|
84
|
+
let origin = options.localhost
|
|
75
85
|
? `http://127.0.0.1:${port}`
|
|
76
86
|
: options.tunnelUrl
|
|
77
87
|
? (0, tunnel_1.publicOrigin)(options.tunnelUrl)
|
|
78
88
|
: await (tunnel = (0, tunnel_1.startTunnel)(port, executable)).url;
|
|
89
|
+
const transportOrigin = origin;
|
|
79
90
|
host.setOrigin(origin);
|
|
80
91
|
if (!options.localhost) {
|
|
92
|
+
terminal_1.terminal.step("Checking public reachability");
|
|
81
93
|
let reachable = false;
|
|
82
94
|
for (let attempt = 0; attempt < 30; attempt++) {
|
|
83
95
|
try {
|
|
@@ -96,6 +108,33 @@ async function startAppDev(directory, options = {}) {
|
|
|
96
108
|
if (!reachable)
|
|
97
109
|
throw new Error("Tunnel URL does not reach this app server; check DNS or your custom tunnel's local port");
|
|
98
110
|
}
|
|
111
|
+
if (tunnel && BRANDED_APP_PREVIEWS_ENABLED) {
|
|
112
|
+
let signedIn = false;
|
|
113
|
+
try {
|
|
114
|
+
signedIn = Boolean(await (0, auth_1.accessToken)());
|
|
115
|
+
}
|
|
116
|
+
catch {
|
|
117
|
+
process.stderr.write("Saved sign-in needs attention; using the direct Quick Tunnel. Run octonodes login to restore branded previews.\n");
|
|
118
|
+
}
|
|
119
|
+
if (signedIn) {
|
|
120
|
+
terminal_1.terminal.step("Registering branded preview");
|
|
121
|
+
let candidate;
|
|
122
|
+
try {
|
|
123
|
+
candidate = await (0, tunnel_lease_1.registerTunnel)(origin, host.secret, options.workspace, options.baseUrl);
|
|
124
|
+
host.setOrigin(candidate.url, origin);
|
|
125
|
+
const response = await fetch(`${candidate.url}/_octonode/ping`, { redirect: "error", signal: AbortSignal.timeout(10_000) });
|
|
126
|
+
if (!response.ok || await response.text() !== host.challenge)
|
|
127
|
+
throw new Error("Branded preview is unreachable");
|
|
128
|
+
lease = candidate;
|
|
129
|
+
origin = candidate.url;
|
|
130
|
+
}
|
|
131
|
+
catch (error) {
|
|
132
|
+
host.setOrigin(transportOrigin);
|
|
133
|
+
await candidate?.close().catch(() => { });
|
|
134
|
+
process.stderr.write(`Branded preview unavailable (${error instanceof Error ? error.message : String(error)}); using Quick Tunnel ${transportOrigin}\n`);
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
}
|
|
99
138
|
const rebuild = () => {
|
|
100
139
|
buildTask = buildTask.then(async () => {
|
|
101
140
|
if (closed)
|
|
@@ -116,7 +155,7 @@ async function startAppDev(directory, options = {}) {
|
|
|
116
155
|
throw new Error("web.entry must default-export a Fetch API handler");
|
|
117
156
|
}
|
|
118
157
|
host.update(source, web ?? built.directory, backend);
|
|
119
|
-
|
|
158
|
+
terminal_1.terminal.rebuilt();
|
|
120
159
|
}
|
|
121
160
|
catch (error) {
|
|
122
161
|
const message = error instanceof Error ? error.message : String(error);
|
|
@@ -126,12 +165,13 @@ async function startAppDev(directory, options = {}) {
|
|
|
126
165
|
});
|
|
127
166
|
return buildTask;
|
|
128
167
|
};
|
|
168
|
+
terminal_1.terminal.step(`Building ${source.name}`);
|
|
129
169
|
await rebuild();
|
|
130
170
|
if (development && !development.url)
|
|
131
171
|
throw new Error("Workspace preview could not start; see the development error above");
|
|
132
172
|
watcher = (0, node_fs_1.watch)(root, { recursive: true }, (_event, filename) => {
|
|
133
173
|
const file = String(filename ?? "").replaceAll("\\", "/");
|
|
134
|
-
if (file !== "octonode.app.json" && !file.startsWith("src/"))
|
|
174
|
+
if (file !== "octonode.app.json" && !file.startsWith("src/") && !file.startsWith("app/") && !["index.html", "next.config.mjs", "vite.config.mjs"].includes(file))
|
|
135
175
|
return;
|
|
136
176
|
clearTimeout(timer);
|
|
137
177
|
timer = setTimeout(() => void rebuild(), 150);
|
|
@@ -143,19 +183,32 @@ async function startAppDev(directory, options = {}) {
|
|
|
143
183
|
void close();
|
|
144
184
|
}
|
|
145
185
|
});
|
|
146
|
-
heartbeat = development
|
|
186
|
+
heartbeat = development || lease
|
|
147
187
|
? setInterval(() => {
|
|
148
|
-
void development
|
|
188
|
+
void development?.sync().catch((error) => process.stderr.write(`${error.message}\n`));
|
|
189
|
+
void lease?.renew().catch((error) => {
|
|
190
|
+
if (closed)
|
|
191
|
+
return;
|
|
192
|
+
const expired = lease;
|
|
193
|
+
lease = undefined;
|
|
194
|
+
origin = transportOrigin;
|
|
195
|
+
host.setOrigin(origin);
|
|
196
|
+
previewUrl = `${origin}/_octonode/#preview=${host.secret}`;
|
|
197
|
+
process.stderr.write(`Branded preview expired (${error.message}); continuing at ${previewUrl}\n`);
|
|
198
|
+
void expired?.close().catch(() => { });
|
|
199
|
+
void rebuild();
|
|
200
|
+
});
|
|
149
201
|
}, 60_000)
|
|
150
202
|
: undefined;
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
203
|
+
let previewUrl = `${origin}/_octonode/#preview=${host.secret}`;
|
|
204
|
+
if (!terminal_1.terminal.ready(source.name, origin, previewUrl, development?.url))
|
|
205
|
+
process.stdout.write(JSON.stringify({
|
|
206
|
+
url: origin,
|
|
207
|
+
previewUrl,
|
|
208
|
+
port,
|
|
209
|
+
studioUrl: development?.url,
|
|
210
|
+
mode: options.localhost ? "localhost" : "tunnel",
|
|
211
|
+
}) + "\n");
|
|
159
212
|
if (options.open !== false) {
|
|
160
213
|
const command = process.platform === "darwin" ? "open" : process.platform === "win32" ? "cmd" : "xdg-open";
|
|
161
214
|
const openUrl = development?.url ?? previewUrl;
|
|
@@ -164,7 +217,7 @@ async function startAppDev(directory, options = {}) {
|
|
|
164
217
|
browser.on("error", () => { });
|
|
165
218
|
browser.unref();
|
|
166
219
|
}
|
|
167
|
-
return { ...host, close, origin, previewUrl, rebuild };
|
|
220
|
+
return { ...host, close, get origin() { return origin; }, get previewUrl() { return previewUrl; }, rebuild };
|
|
168
221
|
}
|
|
169
222
|
catch (error) {
|
|
170
223
|
await close();
|