@vaiyen_og/n8n-nodes-ninjaone 1.5.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.
Files changed (30) hide show
  1. package/README.md +142 -0
  2. package/dist/credentials/NinjaOneClientCredentialsApi.credentials.d.ts +10 -0
  3. package/dist/credentials/NinjaOneClientCredentialsApi.credentials.js +78 -0
  4. package/dist/credentials/NinjaOneClientCredentialsApi.credentials.js.map +1 -0
  5. package/dist/credentials/NinjaOneOAuth2Api.credentials.d.ts +10 -0
  6. package/dist/credentials/NinjaOneOAuth2Api.credentials.js +79 -0
  7. package/dist/credentials/NinjaOneOAuth2Api.credentials.js.map +1 -0
  8. package/dist/nodes/NinjaOne/GenericFunctions.d.ts +14 -0
  9. package/dist/nodes/NinjaOne/GenericFunctions.js +98 -0
  10. package/dist/nodes/NinjaOne/GenericFunctions.js.map +1 -0
  11. package/dist/nodes/NinjaOne/NinjaOne.node.d.ts +10 -0
  12. package/dist/nodes/NinjaOne/NinjaOne.node.js +713 -0
  13. package/dist/nodes/NinjaOne/NinjaOne.node.js.map +1 -0
  14. package/dist/nodes/NinjaOne/NinjaOneTrigger.node.d.ts +12 -0
  15. package/dist/nodes/NinjaOne/NinjaOneTrigger.node.js +108 -0
  16. package/dist/nodes/NinjaOne/NinjaOneTrigger.node.js.map +1 -0
  17. package/dist/nodes/NinjaOne/descriptions/DeviceDescription.d.ts +3 -0
  18. package/dist/nodes/NinjaOne/descriptions/DeviceDescription.js +151 -0
  19. package/dist/nodes/NinjaOne/descriptions/DeviceDescription.js.map +1 -0
  20. package/dist/nodes/NinjaOne/descriptions/OrganizationDescription.d.ts +3 -0
  21. package/dist/nodes/NinjaOne/descriptions/OrganizationDescription.js +106 -0
  22. package/dist/nodes/NinjaOne/descriptions/OrganizationDescription.js.map +1 -0
  23. package/dist/nodes/NinjaOne/descriptions/OtherDescriptions.d.ts +27 -0
  24. package/dist/nodes/NinjaOne/descriptions/OtherDescriptions.js +30 -0
  25. package/dist/nodes/NinjaOne/descriptions/OtherDescriptions.js.map +1 -0
  26. package/dist/nodes/NinjaOne/descriptions/TicketingDescription.d.ts +3 -0
  27. package/dist/nodes/NinjaOne/descriptions/TicketingDescription.js +322 -0
  28. package/dist/nodes/NinjaOne/descriptions/TicketingDescription.js.map +1 -0
  29. package/dist/nodes/NinjaOne/ninjaone.png +0 -0
  30. package/package.json +54 -0
package/README.md ADDED
@@ -0,0 +1,142 @@
1
+ # @vaiyen_og/n8n-nodes-ninjaone
2
+
3
+ Vollständige **n8n Community Node** für die [NinjaOne](https://www.ninjaone.com/) RMM API (v2).
4
+ Unterstützt alle regionalen Instanzen (EU, US, OC, CA) mit OAuth2 Authorization Code **und** Client Credentials Authentifizierung.
5
+
6
+ ## Installation
7
+
8
+ 1. Öffne deine n8n-Instanz
9
+ 2. Gehe zu **Settings → Community Nodes**
10
+ 3. Klicke **Install**
11
+ 4. Gib `@vaiyen_og/n8n-nodes-ninjaone` ein
12
+ 5. Bestätige die Installation
13
+
14
+ ## Authentifizierung
15
+
16
+ ### Option 1: OAuth2 Authorization Code (für Ticket-Erstellung mit User-Kontext)
17
+
18
+ 1. In NinjaOne: **Administration → Apps → API → Client App IDs → Add**
19
+ 2. Plattform: **Web**
20
+ 3. Wähle **Authorization Code** und **Refresh Token** als Grant Types
21
+ 4. Scopes: `monitoring`, `management`, `control`
22
+ 5. Redirect URI: `https://<dein-n8n>/rest/oauth2-credential/callback`
23
+ 6. In n8n: Neue Credential erstellen → **NinjaOne OAuth2 API**
24
+ 7. Toggle auf **OAuth2 (Authorization Code)**
25
+ 8. Trage **Client ID**, **Client Secret** ein und wähle die **Region**
26
+ 9. Klicke **Connect** zum Autorisieren
27
+
28
+ ### Option 2: Client Credentials / Machine-to-Machine (für Kontakte, Lesen, etc.)
29
+
30
+ 1. In NinjaOne: **Administration → Apps → API → Client App IDs → Add**
31
+ 2. Plattform: **Machine-to-Machine**
32
+ 3. Scopes: `monitoring`, `management`, `control`
33
+ 4. In n8n: Neue Credential erstellen → **NinjaOne OAuth2 API**
34
+ 5. Toggle auf **Client Credentials**
35
+ 6. Trage **Client ID**, **Client Secret** ein und wähle die **Region**
36
+ 7. Klicke **Save**
37
+
38
+ ### Wann welche Credential?
39
+
40
+ - **OAuth2 Authorization Code** → Tickets erstellen/bearbeiten (braucht User-Kontext)
41
+ - **Client Credentials** → Kontakte lesen/erstellen, Devices auflisten, alles was keinen User-Kontext braucht
42
+
43
+ Du kannst beide Credentials im selben Workflow verwenden – einfach pro Node die passende auswählen.
44
+
45
+ ## Unterstützte Ressourcen & Operationen
46
+
47
+ ### Organization
48
+ - Create, Get, Get Many, Update, Delete
49
+
50
+ ### Device
51
+ - Get, Get Many (mit Device Filter Syntax)
52
+ - Get Activities, Custom Fields, Disks, Network Interfaces, OS Patches, Processors, Software, Volumes
53
+ - Approve/Reject, Reboot, Run Script, Maintenance Mode
54
+ - Update Custom Fields
55
+
56
+ ### Ticketing
57
+ - Create Ticket, Get Ticket, Get Many (per Board ID), Update, Delete
58
+ - Create Contact, Get Contacts
59
+ - Add Comment, Get Log Entries
60
+ - Get Boards, Statuses, Ticket Forms
61
+
62
+ ### User
63
+ - Create, Get, Get Many, Update, Delete
64
+
65
+ ### Group
66
+ - Get, Get Many, Get Device IDs
67
+
68
+ ### Query (Bulk-Abfragen)
69
+ - Alerts, Antivirus Status, Antivirus Threats, Custom Fields
70
+ - Device Health, Disks, Network Interfaces
71
+ - OS Patches, OS Patch Installs, Processors
72
+ - RAID Drives, Software, Software Patches, Windows Services
73
+
74
+ ### Alert
75
+ - Get Many, Reset, Reset with Activity Data
76
+
77
+ ### Location
78
+ - Create, Get Many, Update
79
+
80
+ ### Backup
81
+ - Get Backup Jobs, Get Integrity Check Results
82
+
83
+ ### Webhook
84
+ - Configure (Create/Update), Delete
85
+
86
+ ### Custom Field
87
+ - Get/Update Device Custom Fields
88
+ - Get/Update Organization Custom Fields
89
+
90
+ ### Knowledge Base Article
91
+ - Create, Get, Get Many, Update, Delete
92
+
93
+ ### Organization Document
94
+ - Create, Get, Get Many, Update, Delete
95
+
96
+ ### Document Template
97
+ - Get, Get Many
98
+
99
+ ### Related Item
100
+ - Create, Get Many, Delete
101
+
102
+ ## Trigger Node
103
+
104
+ Der **NinjaOne Trigger** Node empfängt Webhook-Events in Echtzeit:
105
+
106
+ - Alert Triggered/Reset
107
+ - Condition Triggered/Reset
108
+ - Device Added/Deleted/Online/Offline/Approval
109
+ - Patch Management
110
+ - Script Run
111
+ - Ticket Created/Updated/Deleted
112
+
113
+ ## Device Filter Syntax
114
+
115
+ Viele Endpoints unterstützen die NinjaOne Device Filter Syntax (Parameter `df`), z.B.:
116
+
117
+ ```
118
+ class in (WINDOWS_WORKSTATION, WINDOWS_SERVER)
119
+ org = 1
120
+ status = ONLINE
121
+ ```
122
+
123
+ Siehe [NinjaOne Device Filter Dokumentation](https://resources.ninjarmm.com/API/Ninja+RMM+Public+API+v2.0.5+Device+Filter+Syntax.pdf).
124
+
125
+ ## API Regionen
126
+
127
+ | Region | Base URL |
128
+ |----------|-----------------------------|
129
+ | EU | `https://eu.ninjarmm.com` |
130
+ | US | `https://app.ninjarmm.com` |
131
+ | Oceania | `https://oc.ninjarmm.com` |
132
+ | Canada | `https://ca.ninjarmm.com` |
133
+
134
+ ## Lizenz
135
+
136
+ MIT
137
+
138
+ ## Links
139
+
140
+ - [NinjaOne API Docs (EU)](https://eu.ninjarmm.com/apidocs/?links.active=core)
141
+ - [NinjaOne OAuth Setup](https://www.ninjaone.com/docs/application-programming-interface-api/oauth-token-configuration/)
142
+ - [n8n Community Nodes Docs](https://docs.n8n.io/integrations/community-nodes/)
@@ -0,0 +1,10 @@
1
+ import { ICredentialDataDecryptedObject, ICredentialType, IHttpRequestOptions, INodeProperties } from 'n8n-workflow';
2
+ export declare class NinjaOneClientCredentialsApi implements ICredentialType {
3
+ name: string;
4
+ displayName: string;
5
+ documentationUrl: string;
6
+ properties: INodeProperties[];
7
+ authenticate(credentials: ICredentialDataDecryptedObject, requestOptions: IHttpRequestOptions): Promise<IHttpRequestOptions>;
8
+ private getBaseUrl;
9
+ private getAccessToken;
10
+ }
@@ -0,0 +1,78 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.NinjaOneClientCredentialsApi = void 0;
4
+ class NinjaOneClientCredentialsApi {
5
+ constructor() {
6
+ this.name = 'ninjaOneClientCredentialsApi';
7
+ this.displayName = 'NinjaOne Client Credentials API';
8
+ this.documentationUrl = 'https://www.ninjaone.com/docs/application-programming-interface-api/oauth-token-configuration/';
9
+ this.properties = [
10
+ {
11
+ displayName: 'Region',
12
+ name: 'region',
13
+ type: 'options',
14
+ options: [
15
+ { name: 'EU (eu.ninjarmm.com)', value: 'eu' },
16
+ { name: 'US (app.ninjarmm.com)', value: 'us' },
17
+ { name: 'Oceania (oc.ninjarmm.com)', value: 'oc' },
18
+ { name: 'CA (ca.ninjarmm.com)', value: 'ca' },
19
+ ],
20
+ default: 'eu',
21
+ description: 'The NinjaOne regional instance to connect to',
22
+ },
23
+ {
24
+ displayName: 'Client ID',
25
+ name: 'clientId',
26
+ type: 'string',
27
+ default: '',
28
+ required: true,
29
+ description: 'OAuth2 Client ID from NinjaOne (Administration → Apps → API)',
30
+ },
31
+ {
32
+ displayName: 'Client Secret',
33
+ name: 'clientSecret',
34
+ type: 'string',
35
+ typeOptions: { password: true },
36
+ default: '',
37
+ required: true,
38
+ description: 'OAuth2 Client Secret from NinjaOne',
39
+ },
40
+ ];
41
+ }
42
+ async authenticate(credentials, requestOptions) {
43
+ const region = credentials.region;
44
+ const baseUrl = this.getBaseUrl(region);
45
+ const tokenResponse = await this.getAccessToken(baseUrl, credentials.clientId, credentials.clientSecret);
46
+ requestOptions.headers = {
47
+ ...requestOptions.headers,
48
+ Authorization: `Bearer ${tokenResponse}`,
49
+ };
50
+ return requestOptions;
51
+ }
52
+ getBaseUrl(region) {
53
+ switch (region) {
54
+ case 'eu': return 'https://eu.ninjarmm.com';
55
+ case 'oc': return 'https://oc.ninjarmm.com';
56
+ case 'ca': return 'https://ca.ninjarmm.com';
57
+ default: return 'https://app.ninjarmm.com';
58
+ }
59
+ }
60
+ async getAccessToken(baseUrl, clientId, clientSecret) {
61
+ const url = `${baseUrl}/ws/oauth/token`;
62
+ const params = new URLSearchParams({
63
+ grant_type: 'client_credentials',
64
+ client_id: clientId,
65
+ client_secret: clientSecret,
66
+ scope: 'monitoring management control',
67
+ });
68
+ const response = await fetch(url, {
69
+ method: 'POST',
70
+ headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
71
+ body: params.toString(),
72
+ });
73
+ const data = await response.json();
74
+ return data.access_token;
75
+ }
76
+ }
77
+ exports.NinjaOneClientCredentialsApi = NinjaOneClientCredentialsApi;
78
+ //# sourceMappingURL=NinjaOneClientCredentialsApi.credentials.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"NinjaOneClientCredentialsApi.credentials.js","sourceRoot":"","sources":["../../credentials/NinjaOneClientCredentialsApi.credentials.ts"],"names":[],"mappings":";;;AAOA,MAAa,4BAA4B;IAAzC;QACC,SAAI,GAAG,8BAA8B,CAAC;QACtC,gBAAW,GAAG,iCAAiC,CAAC;QAChD,qBAAgB,GAAG,gGAAgG,CAAC;QAEpH,eAAU,GAAsB;YAC/B;gBACC,WAAW,EAAE,QAAQ;gBACrB,IAAI,EAAE,QAAQ;gBACd,IAAI,EAAE,SAAS;gBACf,OAAO,EAAE;oBACR,EAAE,IAAI,EAAE,sBAAsB,EAAE,KAAK,EAAE,IAAI,EAAE;oBAC7C,EAAE,IAAI,EAAE,uBAAuB,EAAE,KAAK,EAAE,IAAI,EAAE;oBAC9C,EAAE,IAAI,EAAE,2BAA2B,EAAE,KAAK,EAAE,IAAI,EAAE;oBAClD,EAAE,IAAI,EAAE,sBAAsB,EAAE,KAAK,EAAE,IAAI,EAAE;iBAC7C;gBACD,OAAO,EAAE,IAAI;gBACb,WAAW,EAAE,8CAA8C;aAC3D;YACD;gBACC,WAAW,EAAE,WAAW;gBACxB,IAAI,EAAE,UAAU;gBAChB,IAAI,EAAE,QAAQ;gBACd,OAAO,EAAE,EAAE;gBACX,QAAQ,EAAE,IAAI;gBACd,WAAW,EAAE,8DAA8D;aAC3E;YACD;gBACC,WAAW,EAAE,eAAe;gBAC5B,IAAI,EAAE,cAAc;gBACpB,IAAI,EAAE,QAAQ;gBACd,WAAW,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE;gBAC/B,OAAO,EAAE,EAAE;gBACX,QAAQ,EAAE,IAAI;gBACd,WAAW,EAAE,oCAAoC;aACjD;SACD,CAAC;IAsDH,CAAC;IApDA,KAAK,CAAC,YAAY,CACjB,WAA2C,EAC3C,cAAmC;QAEnC,MAAM,MAAM,GAAG,WAAW,CAAC,MAAgB,CAAC;QAC5C,MAAM,OAAO,GAAG,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC;QAExC,MAAM,aAAa,GAAG,MAAM,IAAI,CAAC,cAAc,CAC9C,OAAO,EACP,WAAW,CAAC,QAAkB,EAC9B,WAAW,CAAC,YAAsB,CAClC,CAAC;QAEF,cAAc,CAAC,OAAO,GAAG;YACxB,GAAG,cAAc,CAAC,OAAO;YACzB,aAAa,EAAE,UAAU,aAAa,EAAE;SACxC,CAAC;QAEF,OAAO,cAAc,CAAC;IACvB,CAAC;IAEO,UAAU,CAAC,MAAc;QAChC,QAAQ,MAAM,EAAE,CAAC;YAChB,KAAK,IAAI,CAAC,CAAC,OAAO,yBAAyB,CAAC;YAC5C,KAAK,IAAI,CAAC,CAAC,OAAO,yBAAyB,CAAC;YAC5C,KAAK,IAAI,CAAC,CAAC,OAAO,yBAAyB,CAAC;YAC5C,OAAO,CAAC,CAAC,OAAO,0BAA0B,CAAC;QAC5C,CAAC;IACF,CAAC;IAEO,KAAK,CAAC,cAAc,CAC3B,OAAe,EACf,QAAgB,EAChB,YAAoB;QAEpB,MAAM,GAAG,GAAG,GAAG,OAAO,iBAAiB,CAAC;QACxC,MAAM,MAAM,GAAG,IAAI,eAAe,CAAC;YAClC,UAAU,EAAE,oBAAoB;YAChC,SAAS,EAAE,QAAQ;YACnB,aAAa,EAAE,YAAY;YAC3B,KAAK,EAAE,+BAA+B;SACtC,CAAC,CAAC;QAEH,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,GAAG,EAAE;YACjC,MAAM,EAAE,MAAM;YACd,OAAO,EAAE,EAAE,cAAc,EAAE,mCAAmC,EAAE;YAChE,IAAI,EAAE,MAAM,CAAC,QAAQ,EAAE;SACvB,CAAC,CAAC;QAEH,MAAM,IAAI,GAAG,MAAM,QAAQ,CAAC,IAAI,EAA8B,CAAC;QAC/D,OAAO,IAAI,CAAC,YAAY,CAAC;IAC1B,CAAC;CACD;AA1FD,oEA0FC"}
@@ -0,0 +1,10 @@
1
+ import { IAuthenticateGeneric, ICredentialTestRequest, ICredentialType, INodeProperties } from 'n8n-workflow';
2
+ export declare class NinjaOneOAuth2Api implements ICredentialType {
3
+ name: string;
4
+ displayName: string;
5
+ documentationUrl: string;
6
+ extends: string[];
7
+ properties: INodeProperties[];
8
+ authenticate: IAuthenticateGeneric;
9
+ test: ICredentialTestRequest;
10
+ }
@@ -0,0 +1,79 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.NinjaOneOAuth2Api = void 0;
4
+ class NinjaOneOAuth2Api {
5
+ constructor() {
6
+ this.name = 'ninjaOneOAuth2Api';
7
+ this.displayName = 'NinjaOne OAuth2 API';
8
+ this.documentationUrl = 'https://www.ninjaone.com/docs/application-programming-interface-api/oauth-token-configuration/';
9
+ this.extends = ['oAuth2Api'];
10
+ this.properties = [
11
+ {
12
+ displayName: 'Region',
13
+ name: 'region',
14
+ type: 'options',
15
+ options: [
16
+ { name: 'EU (eu.ninjarmm.com)', value: 'eu' },
17
+ { name: 'US (app.ninjarmm.com)', value: 'us' },
18
+ { name: 'Oceania (oc.ninjarmm.com)', value: 'oc' },
19
+ { name: 'CA (ca.ninjarmm.com)', value: 'ca' },
20
+ ],
21
+ default: 'eu',
22
+ description: 'The NinjaOne regional instance to connect to',
23
+ },
24
+ {
25
+ displayName: 'Grant Type',
26
+ name: 'grantType',
27
+ type: 'hidden',
28
+ default: 'authorizationCode',
29
+ },
30
+ {
31
+ displayName: 'Authorization URL',
32
+ name: 'authUrl',
33
+ type: 'hidden',
34
+ default: '={{$self["region"] === "eu" ? "https://eu.ninjarmm.com" : $self["region"] === "oc" ? "https://oc.ninjarmm.com" : $self["region"] === "ca" ? "https://ca.ninjarmm.com" : "https://app.ninjarmm.com"}}/ws/oauth/authorize',
35
+ },
36
+ {
37
+ displayName: 'Access Token URL',
38
+ name: 'accessTokenUrl',
39
+ type: 'hidden',
40
+ default: '={{$self["region"] === "eu" ? "https://eu.ninjarmm.com" : $self["region"] === "oc" ? "https://oc.ninjarmm.com" : $self["region"] === "ca" ? "https://ca.ninjarmm.com" : "https://app.ninjarmm.com"}}/ws/oauth/token',
41
+ },
42
+ {
43
+ displayName: 'Scope',
44
+ name: 'scope',
45
+ type: 'hidden',
46
+ default: 'monitoring management control offline_access',
47
+ },
48
+ {
49
+ displayName: 'Auth URI Query Parameters',
50
+ name: 'authQueryParameters',
51
+ type: 'hidden',
52
+ default: 'response_type=code',
53
+ },
54
+ {
55
+ displayName: 'Authentication',
56
+ name: 'authentication',
57
+ type: 'hidden',
58
+ default: 'header',
59
+ },
60
+ ];
61
+ this.authenticate = {
62
+ type: 'generic',
63
+ properties: {
64
+ headers: {
65
+ Authorization: '=Bearer {{$credentials.oauthTokenData.access_token}}',
66
+ },
67
+ },
68
+ };
69
+ this.test = {
70
+ request: {
71
+ baseURL: '={{$credentials.region === "eu" ? "https://eu.ninjarmm.com" : $credentials.region === "oc" ? "https://oc.ninjarmm.com" : $credentials.region === "ca" ? "https://ca.ninjarmm.com" : "https://app.ninjarmm.com"}}',
72
+ url: '/api/v2/organizations',
73
+ method: 'GET',
74
+ },
75
+ };
76
+ }
77
+ }
78
+ exports.NinjaOneOAuth2Api = NinjaOneOAuth2Api;
79
+ //# sourceMappingURL=NinjaOneOAuth2Api.credentials.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"NinjaOneOAuth2Api.credentials.js","sourceRoot":"","sources":["../../credentials/NinjaOneOAuth2Api.credentials.ts"],"names":[],"mappings":";;;AAOA,MAAa,iBAAiB;IAA9B;QACC,SAAI,GAAG,mBAAmB,CAAC;QAC3B,gBAAW,GAAG,qBAAqB,CAAC;QACpC,qBAAgB,GAAG,gGAAgG,CAAC;QACpH,YAAO,GAAG,CAAC,WAAW,CAAC,CAAC;QAExB,eAAU,GAAsB;YAC/B;gBACC,WAAW,EAAE,QAAQ;gBACrB,IAAI,EAAE,QAAQ;gBACd,IAAI,EAAE,SAAS;gBACf,OAAO,EAAE;oBACR,EAAE,IAAI,EAAE,sBAAsB,EAAE,KAAK,EAAE,IAAI,EAAE;oBAC7C,EAAE,IAAI,EAAE,uBAAuB,EAAE,KAAK,EAAE,IAAI,EAAE;oBAC9C,EAAE,IAAI,EAAE,2BAA2B,EAAE,KAAK,EAAE,IAAI,EAAE;oBAClD,EAAE,IAAI,EAAE,sBAAsB,EAAE,KAAK,EAAE,IAAI,EAAE;iBAC7C;gBACD,OAAO,EAAE,IAAI;gBACb,WAAW,EAAE,8CAA8C;aAC3D;YACD;gBACC,WAAW,EAAE,YAAY;gBACzB,IAAI,EAAE,WAAW;gBACjB,IAAI,EAAE,QAAQ;gBACd,OAAO,EAAE,mBAAmB;aAC5B;YACD;gBACC,WAAW,EAAE,mBAAmB;gBAChC,IAAI,EAAE,SAAS;gBACf,IAAI,EAAE,QAAQ;gBACd,OAAO,EACN,yNAAyN;aAC1N;YACD;gBACC,WAAW,EAAE,kBAAkB;gBAC/B,IAAI,EAAE,gBAAgB;gBACtB,IAAI,EAAE,QAAQ;gBACd,OAAO,EACN,qNAAqN;aACtN;YACD;gBACC,WAAW,EAAE,OAAO;gBACpB,IAAI,EAAE,OAAO;gBACb,IAAI,EAAE,QAAQ;gBACd,OAAO,EAAE,8CAA8C;aACvD;YACD;gBACC,WAAW,EAAE,2BAA2B;gBACxC,IAAI,EAAE,qBAAqB;gBAC3B,IAAI,EAAE,QAAQ;gBACd,OAAO,EAAE,oBAAoB;aAC7B;YACD;gBACC,WAAW,EAAE,gBAAgB;gBAC7B,IAAI,EAAE,gBAAgB;gBACtB,IAAI,EAAE,QAAQ;gBACd,OAAO,EAAE,QAAQ;aACjB;SACD,CAAC;QAEF,iBAAY,GAAyB;YACpC,IAAI,EAAE,SAAS;YACf,UAAU,EAAE;gBACX,OAAO,EAAE;oBACR,aAAa,EAAE,sDAAsD;iBACrE;aACD;SACD,CAAC;QAEF,SAAI,GAA2B;YAC9B,OAAO,EAAE;gBACR,OAAO,EACN,kNAAkN;gBACnN,GAAG,EAAE,uBAAuB;gBAC5B,MAAM,EAAE,KAAK;aACb;SACD,CAAC;IACH,CAAC;CAAA;AA7ED,8CA6EC"}
@@ -0,0 +1,14 @@
1
+ import { IExecuteFunctions, IHookFunctions, ILoadOptionsFunctions, IHttpRequestMethods, INodeExecutionData } from 'n8n-workflow';
2
+ /** Return the base URL for the selected NinjaOne region */
3
+ export declare function getBaseUrl(credentials: {
4
+ region?: string;
5
+ }): string;
6
+ /** Perform an authenticated request against the NinjaOne API */
7
+ export declare function ninjaOneApiRequest(this: IExecuteFunctions | ILoadOptionsFunctions | IHookFunctions, method: IHttpRequestMethods, endpoint: string, body?: object, qs?: Record<string, string | number | boolean | undefined>, uri?: string): Promise<any>;
8
+ /**
9
+ * Paginate through all results using cursor-based pagination (NinjaOne style).
10
+ * NinjaOne uses `pageSize` + `after` (last ID) for many list endpoints.
11
+ */
12
+ export declare function ninjaOneApiRequestAllItems(this: IExecuteFunctions | ILoadOptionsFunctions, method: IHttpRequestMethods, endpoint: string, body?: object, qs?: Record<string, string | number | boolean | undefined>, idField?: string): Promise<any[]>;
13
+ /** Convert n8n items to proper output format */
14
+ export declare function toItems(data: any[]): INodeExecutionData[];
@@ -0,0 +1,98 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.toItems = exports.ninjaOneApiRequestAllItems = exports.ninjaOneApiRequest = exports.getBaseUrl = void 0;
4
+ const n8n_workflow_1 = require("n8n-workflow");
5
+ /** Return the base URL for the selected NinjaOne region */
6
+ function getBaseUrl(credentials) {
7
+ switch (credentials.region) {
8
+ case 'eu': return 'https://eu.ninjarmm.com';
9
+ case 'oc': return 'https://oc.ninjarmm.com';
10
+ case 'ca': return 'https://ca.ninjarmm.com';
11
+ default: return 'https://app.ninjarmm.com';
12
+ }
13
+ }
14
+ exports.getBaseUrl = getBaseUrl;
15
+ /** Perform an authenticated request against the NinjaOne API */
16
+ async function ninjaOneApiRequest(method, endpoint, body = {}, qs = {}, uri) {
17
+ const authType = this.getNodeParameter('authentication', 0, 'oAuth2');
18
+ const credentialName = authType === 'clientCredentials'
19
+ ? 'ninjaOneClientCredentialsApi'
20
+ : 'ninjaOneOAuth2Api';
21
+ const credentials = await this.getCredentials(credentialName);
22
+ const baseUrl = uri ?? `${getBaseUrl(credentials)}${endpoint}`;
23
+ // Strip undefined qs values
24
+ const cleanQs = {};
25
+ for (const [k, v] of Object.entries(qs)) {
26
+ if (v !== undefined && v !== '')
27
+ cleanQs[k] = v;
28
+ }
29
+ const options = {
30
+ method,
31
+ url: baseUrl,
32
+ qs: cleanQs,
33
+ body,
34
+ json: true,
35
+ headers: {
36
+ Accept: 'application/json',
37
+ 'Content-Type': 'application/json',
38
+ },
39
+ };
40
+ if (method === 'GET' || method === 'DELETE') {
41
+ delete options.body;
42
+ }
43
+ try {
44
+ return await this.helpers.requestWithAuthentication.call(this, credentialName, options);
45
+ }
46
+ catch (error) {
47
+ throw new n8n_workflow_1.NodeApiError(this.getNode(), error);
48
+ }
49
+ }
50
+ exports.ninjaOneApiRequest = ninjaOneApiRequest;
51
+ /**
52
+ * Paginate through all results using cursor-based pagination (NinjaOne style).
53
+ * NinjaOne uses `pageSize` + `after` (last ID) for many list endpoints.
54
+ */
55
+ async function ninjaOneApiRequestAllItems(method, endpoint, body = {}, qs = {}, idField = 'id') {
56
+ const returnData = [];
57
+ let lastId;
58
+ qs.pageSize = qs.pageSize ?? 1000;
59
+ do {
60
+ if (lastId !== undefined) {
61
+ qs.after = lastId;
62
+ }
63
+ const responseData = await ninjaOneApiRequest.call(this, method, endpoint, body, qs);
64
+ if (Array.isArray(responseData)) {
65
+ returnData.push(...responseData);
66
+ if (responseData.length < qs.pageSize)
67
+ break;
68
+ const last = responseData[responseData.length - 1];
69
+ lastId = last?.[idField];
70
+ if (!lastId)
71
+ break;
72
+ }
73
+ else {
74
+ // Some endpoints return { results: [...] } or direct objects
75
+ if (responseData.results && Array.isArray(responseData.results)) {
76
+ returnData.push(...responseData.results);
77
+ if (responseData.results.length < qs.pageSize)
78
+ break;
79
+ const last = responseData.results[responseData.results.length - 1];
80
+ lastId = last?.[idField];
81
+ if (!lastId)
82
+ break;
83
+ }
84
+ else {
85
+ returnData.push(responseData);
86
+ break;
87
+ }
88
+ }
89
+ } while (true);
90
+ return returnData;
91
+ }
92
+ exports.ninjaOneApiRequestAllItems = ninjaOneApiRequestAllItems;
93
+ /** Convert n8n items to proper output format */
94
+ function toItems(data) {
95
+ return data.map((item) => ({ json: item }));
96
+ }
97
+ exports.toItems = toItems;
98
+ //# sourceMappingURL=GenericFunctions.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"GenericFunctions.js","sourceRoot":"","sources":["../../../nodes/NinjaOne/GenericFunctions.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,10 @@
1
+ import { IExecuteFunctions, INodeExecutionData, INodeType, INodeTypeDescription, ILoadOptionsFunctions, INodePropertyOptions } from 'n8n-workflow';
2
+ export declare class NinjaOne implements INodeType {
3
+ description: INodeTypeDescription;
4
+ methods: {
5
+ loadOptions: {
6
+ getOrganizations(this: ILoadOptionsFunctions): Promise<INodePropertyOptions[]>;
7
+ };
8
+ };
9
+ execute(this: IExecuteFunctions): Promise<INodeExecutionData[][]>;
10
+ }