@octonodes/cli 0.2.11 → 0.2.12
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 +65 -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 HTTPS Quick Tunnel automatically. Signed-in developers get a branded
|
|
23
|
+
preview URL when the service is available; otherwise the direct tunnel remains usable.
|
|
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 Quick Tunnel automatically. Signed-in developers get a branded preview when available.\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,wxCAiBpB,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 Quick Tunnel automatically. Signed-in developers get a branded preview when available.
|
|
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 Quick Tunnel automatically. Sign in with \`octonodes login\` for a branded URL when the preview service is available. 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;AAK1C,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,16 @@ 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");
|
|
16
19
|
async function startAppDev(directory, options = {}) {
|
|
17
20
|
if (options.localhost && options.tunnelUrl)
|
|
18
21
|
throw new Error("Choose --use-localhost or --tunnel-url");
|
|
19
22
|
if (options.workspace && options.localhost)
|
|
20
23
|
throw new Error("Studio preview requires an HTTPS tunnel; omit --use-localhost");
|
|
24
|
+
terminal_1.terminal.brand();
|
|
25
|
+
terminal_1.terminal.step(options.workspace ? `Connecting to ${options.workspace}` : "Preparing local preview");
|
|
21
26
|
const development = options.workspace
|
|
22
27
|
? await (0, development_1.createDevelopmentSession)(options.workspace, options.baseUrl, options.studioUrl)
|
|
23
28
|
: undefined;
|
|
@@ -40,6 +45,7 @@ async function startAppDev(directory, options = {}) {
|
|
|
40
45
|
source,
|
|
41
46
|
development: true,
|
|
42
47
|
});
|
|
48
|
+
let lease;
|
|
43
49
|
let tunnel;
|
|
44
50
|
let watcher;
|
|
45
51
|
let timer;
|
|
@@ -58,6 +64,7 @@ async function startAppDev(directory, options = {}) {
|
|
|
58
64
|
tunnel?.stop();
|
|
59
65
|
await host.close();
|
|
60
66
|
await buildTask;
|
|
67
|
+
await lease?.close().catch(() => process.stderr.write("Tunnel cleanup failed; the branded URL expires automatically\n"));
|
|
61
68
|
await development?.close();
|
|
62
69
|
process.off("SIGINT", onSignal);
|
|
63
70
|
process.off("SIGTERM", onSignal);
|
|
@@ -69,15 +76,18 @@ async function startAppDev(directory, options = {}) {
|
|
|
69
76
|
process.once("SIGTERM", onSignal);
|
|
70
77
|
try {
|
|
71
78
|
const port = await host.listen();
|
|
79
|
+
terminal_1.terminal.step(options.localhost ? "Starting local server" : "Opening secure tunnel");
|
|
72
80
|
const executable = !options.localhost && !options.tunnelUrl ? await (0, cloudflared_1.ensureCloudflared)(startup.signal) : undefined;
|
|
73
81
|
startup.signal.throwIfAborted();
|
|
74
|
-
|
|
82
|
+
let origin = options.localhost
|
|
75
83
|
? `http://127.0.0.1:${port}`
|
|
76
84
|
: options.tunnelUrl
|
|
77
85
|
? (0, tunnel_1.publicOrigin)(options.tunnelUrl)
|
|
78
86
|
: await (tunnel = (0, tunnel_1.startTunnel)(port, executable)).url;
|
|
87
|
+
const transportOrigin = origin;
|
|
79
88
|
host.setOrigin(origin);
|
|
80
89
|
if (!options.localhost) {
|
|
90
|
+
terminal_1.terminal.step("Checking public reachability");
|
|
81
91
|
let reachable = false;
|
|
82
92
|
for (let attempt = 0; attempt < 30; attempt++) {
|
|
83
93
|
try {
|
|
@@ -96,6 +106,33 @@ async function startAppDev(directory, options = {}) {
|
|
|
96
106
|
if (!reachable)
|
|
97
107
|
throw new Error("Tunnel URL does not reach this app server; check DNS or your custom tunnel's local port");
|
|
98
108
|
}
|
|
109
|
+
if (tunnel) {
|
|
110
|
+
let signedIn = false;
|
|
111
|
+
try {
|
|
112
|
+
signedIn = Boolean(await (0, auth_1.accessToken)());
|
|
113
|
+
}
|
|
114
|
+
catch {
|
|
115
|
+
process.stderr.write("Saved sign-in needs attention; using the direct Quick Tunnel. Run octonodes login to restore branded previews.\n");
|
|
116
|
+
}
|
|
117
|
+
if (signedIn) {
|
|
118
|
+
terminal_1.terminal.step("Registering branded preview");
|
|
119
|
+
let candidate;
|
|
120
|
+
try {
|
|
121
|
+
candidate = await (0, tunnel_lease_1.registerTunnel)(origin, host.secret, options.workspace, options.baseUrl);
|
|
122
|
+
host.setOrigin(candidate.url, origin);
|
|
123
|
+
const response = await fetch(`${candidate.url}/_octonode/ping`, { redirect: "error", signal: AbortSignal.timeout(10_000) });
|
|
124
|
+
if (!response.ok || await response.text() !== host.challenge)
|
|
125
|
+
throw new Error("Branded preview is unreachable");
|
|
126
|
+
lease = candidate;
|
|
127
|
+
origin = candidate.url;
|
|
128
|
+
}
|
|
129
|
+
catch (error) {
|
|
130
|
+
host.setOrigin(transportOrigin);
|
|
131
|
+
await candidate?.close().catch(() => { });
|
|
132
|
+
process.stderr.write(`Branded preview unavailable (${error instanceof Error ? error.message : String(error)}); using Quick Tunnel ${transportOrigin}\n`);
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
}
|
|
99
136
|
const rebuild = () => {
|
|
100
137
|
buildTask = buildTask.then(async () => {
|
|
101
138
|
if (closed)
|
|
@@ -116,7 +153,7 @@ async function startAppDev(directory, options = {}) {
|
|
|
116
153
|
throw new Error("web.entry must default-export a Fetch API handler");
|
|
117
154
|
}
|
|
118
155
|
host.update(source, web ?? built.directory, backend);
|
|
119
|
-
|
|
156
|
+
terminal_1.terminal.rebuilt();
|
|
120
157
|
}
|
|
121
158
|
catch (error) {
|
|
122
159
|
const message = error instanceof Error ? error.message : String(error);
|
|
@@ -126,12 +163,13 @@ async function startAppDev(directory, options = {}) {
|
|
|
126
163
|
});
|
|
127
164
|
return buildTask;
|
|
128
165
|
};
|
|
166
|
+
terminal_1.terminal.step(`Building ${source.name}`);
|
|
129
167
|
await rebuild();
|
|
130
168
|
if (development && !development.url)
|
|
131
169
|
throw new Error("Workspace preview could not start; see the development error above");
|
|
132
170
|
watcher = (0, node_fs_1.watch)(root, { recursive: true }, (_event, filename) => {
|
|
133
171
|
const file = String(filename ?? "").replaceAll("\\", "/");
|
|
134
|
-
if (file !== "octonode.app.json" && !file.startsWith("src/"))
|
|
172
|
+
if (file !== "octonode.app.json" && !file.startsWith("src/") && !file.startsWith("app/") && !["index.html", "next.config.mjs", "vite.config.mjs"].includes(file))
|
|
135
173
|
return;
|
|
136
174
|
clearTimeout(timer);
|
|
137
175
|
timer = setTimeout(() => void rebuild(), 150);
|
|
@@ -143,19 +181,32 @@ async function startAppDev(directory, options = {}) {
|
|
|
143
181
|
void close();
|
|
144
182
|
}
|
|
145
183
|
});
|
|
146
|
-
heartbeat = development
|
|
184
|
+
heartbeat = development || lease
|
|
147
185
|
? setInterval(() => {
|
|
148
|
-
void development
|
|
186
|
+
void development?.sync().catch((error) => process.stderr.write(`${error.message}\n`));
|
|
187
|
+
void lease?.renew().catch((error) => {
|
|
188
|
+
if (closed)
|
|
189
|
+
return;
|
|
190
|
+
const expired = lease;
|
|
191
|
+
lease = undefined;
|
|
192
|
+
origin = transportOrigin;
|
|
193
|
+
host.setOrigin(origin);
|
|
194
|
+
previewUrl = `${origin}/_octonode/#preview=${host.secret}`;
|
|
195
|
+
process.stderr.write(`Branded preview expired (${error.message}); continuing at ${previewUrl}\n`);
|
|
196
|
+
void expired?.close().catch(() => { });
|
|
197
|
+
void rebuild();
|
|
198
|
+
});
|
|
149
199
|
}, 60_000)
|
|
150
200
|
: undefined;
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
201
|
+
let previewUrl = `${origin}/_octonode/#preview=${host.secret}`;
|
|
202
|
+
if (!terminal_1.terminal.ready(source.name, origin, previewUrl, development?.url))
|
|
203
|
+
process.stdout.write(JSON.stringify({
|
|
204
|
+
url: origin,
|
|
205
|
+
previewUrl,
|
|
206
|
+
port,
|
|
207
|
+
studioUrl: development?.url,
|
|
208
|
+
mode: options.localhost ? "localhost" : "tunnel",
|
|
209
|
+
}) + "\n");
|
|
159
210
|
if (options.open !== false) {
|
|
160
211
|
const command = process.platform === "darwin" ? "open" : process.platform === "win32" ? "cmd" : "xdg-open";
|
|
161
212
|
const openUrl = development?.url ?? previewUrl;
|
|
@@ -164,7 +215,7 @@ async function startAppDev(directory, options = {}) {
|
|
|
164
215
|
browser.on("error", () => { });
|
|
165
216
|
browser.unref();
|
|
166
217
|
}
|
|
167
|
-
return { ...host, close, origin, previewUrl, rebuild };
|
|
218
|
+
return { ...host, close, get origin() { return origin; }, get previewUrl() { return previewUrl; }, rebuild };
|
|
168
219
|
}
|
|
169
220
|
catch (error) {
|
|
170
221
|
await close();
|