n8n-nodes-orbitpage 0.1.0

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/CHANGELOG.md ADDED
@@ -0,0 +1,11 @@
1
+ # Changelog
2
+
3
+ All notable changes to this package are documented here.
4
+
5
+ ## 0.1.0 - 2026-08-04
6
+
7
+ - Add guided access to all 84 OrbitPage Automation REST API operations.
8
+ - Add automatic `ETag` acquisition for revision-controlled writes.
9
+ - Add complete direct video and protected Shop-file upload workflows.
10
+ - Add an advanced custom API request operation.
11
+ - Add polling triggers for workspace, publication, domain and Shop changes.
package/LICENSE.md ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Paolo Ronco
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,229 @@
1
+ # n8n-nodes-orbitpage
2
+
3
+ [![CI](https://github.com/paoloronco/n8n-nodes-orbitpage/actions/workflows/ci.yml/badge.svg)](https://github.com/paoloronco/n8n-nodes-orbitpage/actions/workflows/ci.yml)
4
+ [![npm](https://img.shields.io/npm/v/n8n-nodes-orbitpage.svg)](https://www.npmjs.com/package/n8n-nodes-orbitpage)
5
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE.md)
6
+
7
+ Community nodes for managing a hosted OrbitPage end to end from n8n. The
8
+ package implements every operation in the OrbitPage Automation REST API, adds
9
+ safe automatic revision handling, supports direct binary uploads, and includes
10
+ a polling trigger for important workspace state changes.
11
+
12
+ ## Nodes
13
+
14
+ ### OrbitPage
15
+
16
+ An action node with guided resources for:
17
+
18
+ - workspace and complete draft;
19
+ - page blocks, profile, theme and subpages;
20
+ - menu, privacy, public text files and sitemap;
21
+ - publication, version history and managed backups;
22
+ - media, custom domains and analytics;
23
+ - reviewed AI plan/commit flows;
24
+ - Shop products, appearance, publishing and protected files;
25
+ - newsletter SMTP, subscribers and campaigns;
26
+ - team members, invitations and billing;
27
+ - protected operator CRM, promotion, moderation and tenant operations;
28
+ - relative custom API requests for forward-compatible access.
29
+
30
+ The guided catalog contains all 84 operations in the public OpenAPI contract.
31
+ See [the complete operation matrix](docs/OPERATIONS.md).
32
+
33
+ ### OrbitPage Trigger
34
+
35
+ A polling trigger that starts a workflow when one of these states changes:
36
+
37
+ - workspace revision;
38
+ - publication status;
39
+ - custom-domain status;
40
+ - Shop state.
41
+
42
+ The first production poll establishes a baseline and emits nothing unless
43
+ **Emit Initial State** is enabled. A manual test always returns the current
44
+ state.
45
+
46
+ ## Installation
47
+
48
+ ### n8n Community Nodes UI
49
+
50
+ Open **Settings → Community Nodes**, choose **Install**, then enter:
51
+
52
+ ```text
53
+ n8n-nodes-orbitpage
54
+ ```
55
+
56
+ Restart self-hosted n8n if your installation requires it. Verified community
57
+ node availability on n8n Cloud depends on the n8n review process.
58
+
59
+ ### Self-hosted command line
60
+
61
+ From the n8n data directory:
62
+
63
+ ```bash
64
+ npm install n8n-nodes-orbitpage
65
+ ```
66
+
67
+ Use Node.js 22 or newer.
68
+
69
+ ## Credentials
70
+
71
+ 1. In OrbitPage, open **Dashboard → Account → Personal API tokens**.
72
+ 2. Create one token for one workflow and environment.
73
+ 3. Grant only the scopes required by the selected operations.
74
+ 4. Copy the `op_pat_...` value immediately; OrbitPage shows it only once.
75
+ 5. In n8n, create an **OrbitPage API** credential and paste the token.
76
+
77
+ For `/operator` operations, create a separate 30-day token in the protected
78
+ OrbitPage operator console and choose **Protected Operator Token** in the n8n
79
+ credential. Never reuse an operator credential in tenant workflows.
80
+
81
+ The default Base URL is `https://orbitpage.com`. Change it only when OrbitPage
82
+ support provides a staging URL. HTTP is accepted only for localhost development.
83
+
84
+ ## Safe revision-controlled writes
85
+
86
+ OrbitPage protects draft writes with optimistic concurrency. For block,
87
+ profile, theme, page, settings and restore operations, the node defaults to
88
+ **Fetch Latest Automatically**:
89
+
90
+ 1. it reads the related resource;
91
+ 2. captures the response `ETag` or numeric revision;
92
+ 3. sends that value as `If-Match` with the write.
93
+
94
+ Choose **Enter Manually** only when an earlier node already read the state and
95
+ you intentionally want a conflict if anything changed afterward. A `409`
96
+ response should lead back to a new read; do not retry a stale write blindly.
97
+
98
+ Profile, theme, pages and supported settings update the draft by default.
99
+ Enable **Publish Immediately** for a single eligible mutation, or make several
100
+ draft changes and finish with **Publication → Publish Page**. Block `PATCH` and
101
+ `PUT` operations publish immediately by API design.
102
+
103
+ ## Binary uploads
104
+
105
+ ### Video media
106
+
107
+ Choose **Media → Upload Video Binary**. The node:
108
+
109
+ 1. reads an MP4 or WebM binary field from the input item;
110
+ 2. reserves a temporary upload with OrbitPage;
111
+ 3. sends bytes directly to the signed storage URL without forwarding the
112
+ OrbitPage bearer token;
113
+ 4. finalizes and registers the asset;
114
+ 5. attempts to abort the reservation if upload or finalization fails.
115
+
116
+ ### Protected Shop files
117
+
118
+ Choose **Shop → Upload Product File Binary**, provide the digital-product ID
119
+ and the input binary field. The node performs the same reserve/upload/finalize
120
+ sequence for supported protected product files.
121
+
122
+ Signed upload URLs expire quickly. Keep the three steps inside this compound
123
+ operation unless a workflow specifically needs the lower-level reserve and
124
+ finalize actions.
125
+
126
+ ## AI workflows
127
+
128
+ Use **AI → Plan Changes** to produce a validated preview without changing the
129
+ page. Review the returned operations and keep its `previewToken`, then call
130
+ **AI → Commit Changes** with that exact token. Put `"publish": true` in the
131
+ commit body only when the workflow is authorized to make the result public.
132
+
133
+ An OpenAI provider key is not an OrbitPage credential and must never be placed
134
+ in this node.
135
+
136
+ ## Custom API requests
137
+
138
+ **Advanced → Custom API Request** accepts a method, a path relative to
139
+ `/api/v1`, query parameters, a JSON body and an optional `If-Match` value.
140
+ Absolute URLs, query strings inside the path and dot segments are rejected so
141
+ the credential cannot be redirected to a different endpoint or host.
142
+
143
+ Use a guided operation whenever one exists: it documents the required scope,
144
+ path fields and revision behavior directly in the editor.
145
+
146
+ ## Output and item linking
147
+
148
+ Each input item produces one linked output item. The default output is the API
149
+ response body. Enable **Include Response Headers and Status** to receive:
150
+
151
+ ```json
152
+ {
153
+ "body": {},
154
+ "headers": {},
155
+ "statusCode": 200
156
+ }
157
+ ```
158
+
159
+ This is useful when a later node needs `ETag`, `Retry-After` or other response
160
+ metadata. **Continue On Fail** returns an error item linked to the failing input.
161
+
162
+ ## Security practices
163
+
164
+ - Store tokens only in n8n credentials, never workflow JSON or expressions.
165
+ - Use one token per workflow and environment with the smallest scopes.
166
+ - Prefer finite expiry and rotate before it is reached.
167
+ - Do not log credentials, signed upload URLs or sensitive response bodies.
168
+ - Respect `Retry-After`; OrbitPage currently applies per-token minute and daily
169
+ limits.
170
+ - Keep operator workflows and credentials isolated.
171
+ - Revoke a token immediately after suspected disclosure.
172
+
173
+ ## Documentation
174
+
175
+ - [OrbitPage API guide](https://orbitpage.com/en-US/docs/api-tokens)
176
+ - [OpenAPI 3.1 contract](https://orbitpage.com/api/openapi.json)
177
+ - [n8n community-node installation](https://docs.n8n.io/integrations/community-nodes/installation/)
178
+
179
+ ## Development
180
+
181
+ ```bash
182
+ npm install
183
+ npm run dev
184
+ ```
185
+
186
+ Quality checks:
187
+
188
+ ```bash
189
+ npm run lint
190
+ npm test
191
+ npm run build
192
+ ```
193
+
194
+ Importable example workflows are available in [`examples`](examples). After
195
+ changing the typed operation catalog, rebuild and regenerate its checked-in
196
+ reference with `npm run build && npm run docs:generate`.
197
+
198
+ The package has no runtime dependencies outside the `n8n-workflow` peer. It
199
+ uses the official `@n8n/node-cli` toolchain and publishes npm provenance through
200
+ GitHub Actions.
201
+
202
+ ## Releases
203
+
204
+ Releases are automated by [the publish workflow](.github/workflows/publish.yml).
205
+ Every version tag runs the complete quality suite before publishing the public
206
+ package with provenance.
207
+
208
+ The initial `0.1.0` release can be started after adding the temporary
209
+ package-scoped `NPM_TOKEN` repository secret:
210
+
211
+ ```bash
212
+ git tag 0.1.0
213
+ git push origin 0.1.0
214
+ ```
215
+
216
+ After the first publication, configure the npm Trusted Publisher for
217
+ `paoloronco/n8n-nodes-orbitpage` and `publish.yml`, then delete the GitHub secret
218
+ and revoke the temporary token. Future releases can be prepared with:
219
+
220
+ ```bash
221
+ npm run release
222
+ ```
223
+
224
+ OIDC is the permanent release path; no long-lived npm token belongs in GitHub
225
+ or the repository.
226
+
227
+ ## License
228
+
229
+ MIT © Paolo Ronco
@@ -0,0 +1,10 @@
1
+ import type { IAuthenticateGeneric, ICredentialTestRequest, ICredentialType, Icon, INodeProperties } from 'n8n-workflow';
2
+ export declare class OrbitPageApi implements ICredentialType {
3
+ name: string;
4
+ displayName: string;
5
+ icon: Icon;
6
+ documentationUrl: string;
7
+ properties: INodeProperties[];
8
+ authenticate: IAuthenticateGeneric;
9
+ test: ICredentialTestRequest;
10
+ }
@@ -0,0 +1,67 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.OrbitPageApi = void 0;
4
+ class OrbitPageApi {
5
+ constructor() {
6
+ this.name = 'orbitPageApi';
7
+ this.displayName = 'OrbitPage API';
8
+ this.icon = {
9
+ light: 'file:../icons/orbitpage.svg',
10
+ dark: 'file:../icons/orbitpage.dark.svg',
11
+ };
12
+ this.documentationUrl = 'https://orbitpage.com/en-US/docs/api-tokens';
13
+ this.properties = [
14
+ {
15
+ displayName: 'Token Type',
16
+ name: 'credentialKind',
17
+ type: 'options',
18
+ options: [
19
+ {
20
+ name: 'Personal Workspace Token',
21
+ value: 'workspace',
22
+ },
23
+ {
24
+ name: 'Protected Operator Token',
25
+ value: 'operator',
26
+ },
27
+ ],
28
+ default: 'workspace',
29
+ description: 'Personal tokens are created in Dashboard > Account. Operator tokens are created only in the protected operator console.',
30
+ },
31
+ {
32
+ displayName: 'Personal API Token',
33
+ name: 'accessToken',
34
+ type: 'string',
35
+ typeOptions: { password: true },
36
+ default: '',
37
+ placeholder: 'op_pat_...',
38
+ description: 'The scoped OrbitPage bearer token. It is stored encrypted by n8n.',
39
+ },
40
+ {
41
+ displayName: 'Base URL',
42
+ name: 'baseUrl',
43
+ type: 'string',
44
+ default: 'https://orbitpage.com',
45
+ description: 'Use the production URL unless OrbitPage support supplied a dedicated staging environment',
46
+ },
47
+ ];
48
+ this.authenticate = {
49
+ type: 'generic',
50
+ properties: {
51
+ headers: {
52
+ Authorization: '=Bearer {{$credentials.accessToken}}',
53
+ Accept: 'application/json',
54
+ },
55
+ },
56
+ };
57
+ this.test = {
58
+ request: {
59
+ baseURL: '={{$credentials.baseUrl.replace(/\\/$/, "")}}',
60
+ url: '={{$credentials.credentialKind === "operator" ? "/api/v1/operator/overview" : "/api/v1/workspace"}}',
61
+ method: 'GET',
62
+ },
63
+ };
64
+ }
65
+ }
66
+ exports.OrbitPageApi = OrbitPageApi;
67
+ //# sourceMappingURL=OrbitPageApi.credentials.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"OrbitPageApi.credentials.js","sourceRoot":"","sources":["../../credentials/OrbitPageApi.credentials.ts"],"names":[],"mappings":";;;AAQA,MAAa,YAAY;IAAzB;QACC,SAAI,GAAG,cAAc,CAAC;QAEtB,gBAAW,GAAG,eAAe,CAAC;QAE9B,SAAI,GAAS;YACZ,KAAK,EAAE,6BAA6B;YACpC,IAAI,EAAE,kCAAkC;SACxC,CAAC;QAEF,qBAAgB,GAAG,6CAA6C,CAAC;QAEjE,eAAU,GAAsB;YAC/B;gBACC,WAAW,EAAE,YAAY;gBACzB,IAAI,EAAE,gBAAgB;gBACtB,IAAI,EAAE,SAAS;gBACf,OAAO,EAAE;oBACR;wBACC,IAAI,EAAE,0BAA0B;wBAChC,KAAK,EAAE,WAAW;qBAClB;oBACD;wBACC,IAAI,EAAE,0BAA0B;wBAChC,KAAK,EAAE,UAAU;qBACjB;iBACD;gBACD,OAAO,EAAE,WAAW;gBACpB,WAAW,EACV,yHAAyH;aAC1H;YACD;gBACC,WAAW,EAAE,oBAAoB;gBACjC,IAAI,EAAE,aAAa;gBACnB,IAAI,EAAE,QAAQ;gBACd,WAAW,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE;gBAC/B,OAAO,EAAE,EAAE;gBACX,WAAW,EAAE,YAAY;gBACzB,WAAW,EAAE,mEAAmE;aAChF;YACD;gBACC,WAAW,EAAE,UAAU;gBACvB,IAAI,EAAE,SAAS;gBACf,IAAI,EAAE,QAAQ;gBACd,OAAO,EAAE,uBAAuB;gBAChC,WAAW,EACV,0FAA0F;aAC3F;SACD,CAAC;QAEF,iBAAY,GAAyB;YACpC,IAAI,EAAE,SAAS;YACf,UAAU,EAAE;gBACX,OAAO,EAAE;oBACR,aAAa,EAAE,sCAAsC;oBACrD,MAAM,EAAE,kBAAkB;iBAC1B;aACD;SACD,CAAC;QAEF,SAAI,GAA2B;YAC9B,OAAO,EAAE;gBACR,OAAO,EAAE,+CAA+C;gBACxD,GAAG,EAAE,qGAAqG;gBAC1G,MAAM,EAAE,KAAK;aACb;SACD,CAAC;IACH,CAAC;CAAA;AAnED,oCAmEC"}
@@ -0,0 +1,16 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64" role="img" aria-labelledby="title desc">
2
+ <title id="title">OrbitPage</title>
3
+ <desc id="desc">A blue page crossed by a bright orbit.</desc>
4
+ <defs>
5
+ <linearGradient id="page" x1="18" y1="15" x2="50" y2="52" gradientUnits="userSpaceOnUse"><stop stop-color="#5D82F2"/><stop offset=".58" stop-color="#29457F"/><stop offset="1" stop-color="#3B73FF"/></linearGradient>
6
+ <linearGradient id="fold" x1="22" y1="16" x2="42" y2="46" gradientUnits="userSpaceOnUse"><stop stop-color="#D7E2FF" stop-opacity=".34"/><stop offset="1" stop-color="#3568F4" stop-opacity="0"/></linearGradient>
7
+ <linearGradient id="orbit" x1="12" y1="48" x2="57" y2="16" gradientUnits="userSpaceOnUse"><stop stop-color="#5285FF"/><stop offset=".55" stop-color="#79A0FF"/><stop offset="1" stop-color="#C4D4FF"/></linearGradient>
8
+ <clipPath id="page-clip"><rect x="18" y="15" width="32" height="37" rx="5"/></clipPath>
9
+ </defs>
10
+ <path d="M35 14c11-5 21-2 21 8 0 9-7 20-16 26" fill="none" stroke="url(#orbit)" stroke-linecap="round" stroke-width="6"/>
11
+ <rect x="18" y="15" width="32" height="37" rx="5" fill="url(#page)"/>
12
+ <path d="M18 15h32L18 52Z" fill="url(#fold)" clip-path="url(#page-clip)"/>
13
+ <path d="M56 22c1 12-9 24-20 30-12 7-23 4-24-4-1-5 1-10 4-14" fill="none" stroke="url(#orbit)" stroke-linecap="round" stroke-width="6.5"/>
14
+ <path d="M55 20c1 9-5 19-12 26" fill="none" stroke="#fff" stroke-linecap="round" stroke-width="1.3"/>
15
+ <path d="M34 14c8-5 16-4 20 1" fill="none" stroke="#8CADFF" stroke-linecap="round" stroke-width="3"/>
16
+ </svg>
@@ -0,0 +1,16 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64" role="img" aria-labelledby="title desc">
2
+ <title id="title">OrbitPage</title>
3
+ <desc id="desc">A deep-blue page crossed by a bright blue orbit.</desc>
4
+ <defs>
5
+ <linearGradient id="page" x1="18" y1="15" x2="50" y2="52" gradientUnits="userSpaceOnUse"><stop stop-color="#223B70"/><stop offset=".58" stop-color="#101828"/><stop offset="1" stop-color="#2456D8"/></linearGradient>
6
+ <linearGradient id="fold" x1="22" y1="16" x2="42" y2="46" gradientUnits="userSpaceOnUse"><stop stop-color="#7BA2FF" stop-opacity=".28"/><stop offset="1" stop-color="#2456D8" stop-opacity="0"/></linearGradient>
7
+ <linearGradient id="orbit" x1="12" y1="48" x2="57" y2="16" gradientUnits="userSpaceOnUse"><stop stop-color="#2456D8"/><stop offset=".55" stop-color="#3568F4"/><stop offset="1" stop-color="#7BA2FF"/></linearGradient>
8
+ <clipPath id="page-clip"><rect x="18" y="15" width="32" height="37" rx="5"/></clipPath>
9
+ </defs>
10
+ <path d="M35 14c11-5 21-2 21 8 0 9-7 20-16 26" fill="none" stroke="url(#orbit)" stroke-linecap="round" stroke-width="6"/>
11
+ <rect x="18" y="15" width="32" height="37" rx="5" fill="url(#page)"/>
12
+ <path d="M18 15h32L18 52Z" fill="url(#fold)" clip-path="url(#page-clip)"/>
13
+ <path d="M56 22c1 12-9 24-20 30-12 7-23 4-24-4-1-5 1-10 4-14" fill="none" stroke="url(#orbit)" stroke-linecap="round" stroke-width="6.5"/>
14
+ <path d="M55 20c1 9-5 19-12 26" fill="none" stroke="#fff" stroke-linecap="round" stroke-width="1.3"/>
15
+ <path d="M34 14c8-5 16-4 20 1" fill="none" stroke="#3568F4" stroke-linecap="round" stroke-width="3"/>
16
+ </svg>
@@ -0,0 +1,7 @@
1
+ import type { IExecuteFunctions, INodeExecutionData, INodeType, INodeTypeDescription } from 'n8n-workflow';
2
+ import { type PathParameter } from './operations';
3
+ export declare class OrbitPage implements INodeType {
4
+ description: INodeTypeDescription;
5
+ execute(this: IExecuteFunctions): Promise<INodeExecutionData[][]>;
6
+ }
7
+ export declare const pathParameters: PathParameter[];