@junglesub/n8n-nodes-ajam 0.4.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/README.md ADDED
@@ -0,0 +1,49 @@
1
+ # @junglesub/n8n-nodes-ajam
2
+
3
+ Custom n8n community node package for aJam automation.
4
+
5
+ ## Nodes
6
+
7
+ - `aJam`
8
+ - `AI Cleanup > Run Scheduled Cleanup`
9
+ - `Daily Reminder > List Missing Timesheet Users`
10
+ - `Daily Reminder > Mark Reminder Sent`
11
+ - `Notion > Run Daily Maintenance`
12
+
13
+ The node has two outputs:
14
+
15
+ - `Summary`: normal operation results.
16
+ - `Alerts`: alert-ready items for failed Notion maintenance or AI cleanup runs. This output is empty when there are no automation errors.
17
+
18
+ ## Credentials
19
+
20
+ Create an `aJam API` credential in n8n:
21
+
22
+ - `Base URL`: deployed aJam URL, for example `https://ajam.example.com`
23
+ - `Internal API Token`: same value as `AJAM_INTERNAL_API_TOKEN` in aJam
24
+
25
+ ## Local Install
26
+
27
+ Build the package from the repository root:
28
+
29
+ ```powershell
30
+ pnpm --filter @junglesub/n8n-nodes-ajam build
31
+ ```
32
+
33
+ Install from the public npm registry:
34
+
35
+ ```bash
36
+ pnpm add @junglesub/n8n-nodes-ajam
37
+ ```
38
+
39
+ ## Publish
40
+
41
+ The package publishes to the public npm registry. GitHub Actions publishes automatically when the package `version` changes on `main` and n8n node verification passes. The repository secret `NPM_TOKEN` must contain an npm automation token.
42
+
43
+ Manual publish, if needed:
44
+
45
+ ```bash
46
+ pnpm --filter @junglesub/n8n-nodes-ajam build
47
+ cd packages/n8n-nodes-ajam
48
+ pnpm publish --access public
49
+ ```
@@ -0,0 +1,8 @@
1
+ import type { ICredentialType, INodeProperties } from "n8n-workflow";
2
+ export declare class AjamApi implements ICredentialType {
3
+ name: string;
4
+ displayName: string;
5
+ documentationUrl: string;
6
+ properties: INodeProperties[];
7
+ }
8
+ //# sourceMappingURL=AjamApi.credentials.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"AjamApi.credentials.d.ts","sourceRoot":"","sources":["../../credentials/AjamApi.credentials.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAErE,qBAAa,OAAQ,YAAW,eAAe;IAC7C,IAAI,SAAa;IACjB,WAAW,SAAc;IACzB,gBAAgB,SAAuC;IACvD,UAAU,EAAE,eAAe,EAAE,CAqB3B;CACH"}
@@ -0,0 +1,32 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.AjamApi = void 0;
4
+ class AjamApi {
5
+ name = "ajamApi";
6
+ displayName = "aJam API";
7
+ documentationUrl = "https://github.com/junglesub/ajam";
8
+ properties = [
9
+ {
10
+ default: "",
11
+ description: "Base URL of the aJam app, for example https://ajam.example.com.",
12
+ displayName: "Base URL",
13
+ name: "baseUrl",
14
+ placeholder: "https://ajam.example.com",
15
+ required: true,
16
+ type: "string"
17
+ },
18
+ {
19
+ default: "",
20
+ description: "Value of AJAM_INTERNAL_API_TOKEN configured in aJam.",
21
+ displayName: "Internal API Token",
22
+ name: "apiToken",
23
+ required: true,
24
+ type: "string",
25
+ typeOptions: {
26
+ password: true
27
+ }
28
+ }
29
+ ];
30
+ }
31
+ exports.AjamApi = AjamApi;
32
+ //# sourceMappingURL=AjamApi.credentials.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"AjamApi.credentials.js","sourceRoot":"","sources":["../../credentials/AjamApi.credentials.ts"],"names":[],"mappings":";;;AAEA,MAAa,OAAO;IAClB,IAAI,GAAG,SAAS,CAAC;IACjB,WAAW,GAAG,UAAU,CAAC;IACzB,gBAAgB,GAAG,mCAAmC,CAAC;IACvD,UAAU,GAAsB;QAC9B;YACE,OAAO,EAAE,EAAE;YACX,WAAW,EAAE,iEAAiE;YAC9E,WAAW,EAAE,UAAU;YACvB,IAAI,EAAE,SAAS;YACf,WAAW,EAAE,0BAA0B;YACvC,QAAQ,EAAE,IAAI;YACd,IAAI,EAAE,QAAQ;SACf;QACD;YACE,OAAO,EAAE,EAAE;YACX,WAAW,EAAE,sDAAsD;YACnE,WAAW,EAAE,oBAAoB;YACjC,IAAI,EAAE,UAAU;YAChB,QAAQ,EAAE,IAAI;YACd,IAAI,EAAE,QAAQ;YACd,WAAW,EAAE;gBACX,QAAQ,EAAE,IAAI;aACf;SACF;KACF,CAAC;CACH;AA1BD,0BA0BC"}
@@ -0,0 +1,6 @@
1
+ import { type IExecuteFunctions, type INodeExecutionData, type INodeType, type INodeTypeDescription } from "n8n-workflow";
2
+ export declare class Ajam implements INodeType {
3
+ description: INodeTypeDescription;
4
+ execute(this: IExecuteFunctions): Promise<INodeExecutionData[][]>;
5
+ }
6
+ //# sourceMappingURL=Ajam.node.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Ajam.node.d.ts","sourceRoot":"","sources":["../../../nodes/Ajam/Ajam.node.ts"],"names":[],"mappings":"AAAA,OAAO,EAAyC,KAAK,iBAAiB,EAAE,KAAK,kBAAkB,EAAE,KAAK,SAAS,EAAE,KAAK,oBAAoB,EAAE,MAAM,cAAc,CAAC;AA+GjK,qBAAa,IAAK,YAAW,SAAS;IACpC,WAAW,EAAE,oBAAoB,CAiN/B;IAEI,OAAO,CAAC,IAAI,EAAE,iBAAiB,GAAG,OAAO,CAAC,kBAAkB,EAAE,EAAE,CAAC;CAyIxE"}
@@ -0,0 +1,426 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.Ajam = void 0;
4
+ const n8n_workflow_1 = require("n8n-workflow");
5
+ function normalizeBaseUrl(baseUrl) {
6
+ return baseUrl.trim().replace(/\/+$/, "");
7
+ }
8
+ function getStringParameter(executeFunctions, name, itemIndex) {
9
+ return executeFunctions.getNodeParameter(name, itemIndex, "");
10
+ }
11
+ function buildNotionMaintenanceAlert(response) {
12
+ const errors = Array.isArray(response.errors) ? response.errors : [];
13
+ if (errors.length === 0) {
14
+ return null;
15
+ }
16
+ const dateKey = String(response.dateKey ?? "");
17
+ const lines = errors.map((error) => {
18
+ const item = error;
19
+ const username = String(item.username ?? item.userId ?? "unknown");
20
+ const message = String(item.message ?? "Unknown error");
21
+ return `- ${username}: ${message}`;
22
+ });
23
+ return {
24
+ dateKey,
25
+ errorCount: errors.length,
26
+ errors,
27
+ message: [
28
+ `${dateKey || "aJam"} Notion daily maintenance failed for ${errors.length} user${errors.length === 1 ? "" : "s"}.`,
29
+ "",
30
+ ...lines
31
+ ].join("\n"),
32
+ subject: `[aJam] Notion daily maintenance failed${dateKey ? ` (${dateKey})` : ""}`
33
+ };
34
+ }
35
+ function buildNotionRequestFailureAlert(params) {
36
+ const message = params.error instanceof Error ? params.error.message : "Unknown request error";
37
+ return {
38
+ dateKey: params.dateKey,
39
+ errorCount: 1,
40
+ errors: [{ message, username: "request" }],
41
+ message: [
42
+ `${params.dateKey || "aJam"} Notion daily maintenance request failed.`,
43
+ "",
44
+ `- request: ${message}`
45
+ ].join("\n"),
46
+ subject: `[aJam] Notion daily maintenance request failed${params.dateKey ? ` (${params.dateKey})` : ""}`
47
+ };
48
+ }
49
+ function buildAiScheduledCleanupAlert(response) {
50
+ const errors = Array.isArray(response.errors) ? response.errors : [];
51
+ if (errors.length === 0) {
52
+ return null;
53
+ }
54
+ const dateKey = String(response.dateKey ?? "");
55
+ const lines = errors.map((error) => {
56
+ const item = error;
57
+ const username = String(item.username ?? item.userId ?? "unknown");
58
+ const message = String(item.message ?? "Unknown error");
59
+ return `- ${username}: ${message}`;
60
+ });
61
+ return {
62
+ dateKey,
63
+ errorCount: errors.length,
64
+ errors,
65
+ message: [
66
+ `${dateKey || "aJam"} AI scheduled cleanup failed for ${errors.length} user${errors.length === 1 ? "" : "s"}.`,
67
+ "",
68
+ ...lines
69
+ ].join("\n"),
70
+ subject: `[aJam] AI scheduled cleanup failed${dateKey ? ` (${dateKey})` : ""}`
71
+ };
72
+ }
73
+ function buildAiRequestFailureAlert(params) {
74
+ const message = params.error instanceof Error ? params.error.message : "Unknown request error";
75
+ return {
76
+ dateKey: params.dateKey,
77
+ errorCount: 1,
78
+ errors: [{ message, username: "request" }],
79
+ message: [
80
+ `${params.dateKey || "aJam"} AI scheduled cleanup request failed.`,
81
+ "",
82
+ `- request: ${message}`
83
+ ].join("\n"),
84
+ subject: `[aJam] AI scheduled cleanup request failed${params.dateKey ? ` (${params.dateKey})` : ""}`
85
+ };
86
+ }
87
+ class Ajam {
88
+ description = {
89
+ displayName: "aJam",
90
+ name: "ajam",
91
+ icon: "file:ajam.svg",
92
+ group: ["transform"],
93
+ version: 1,
94
+ subtitle: '={{$parameter["operation"]}}',
95
+ description: "Use aJam internal automation APIs",
96
+ defaults: {
97
+ name: "aJam"
98
+ },
99
+ inputs: [n8n_workflow_1.NodeConnectionTypes.Main],
100
+ outputNames: ["Summary", "Alerts"],
101
+ outputs: [n8n_workflow_1.NodeConnectionTypes.Main, n8n_workflow_1.NodeConnectionTypes.Main],
102
+ credentials: [
103
+ {
104
+ name: "ajamApi",
105
+ required: true
106
+ }
107
+ ],
108
+ properties: [
109
+ {
110
+ default: "dailyReminder",
111
+ displayName: "Resource",
112
+ name: "resource",
113
+ noDataExpression: true,
114
+ options: [
115
+ {
116
+ name: "AI Cleanup",
117
+ value: "aiCleanup"
118
+ },
119
+ {
120
+ name: "Daily Reminder",
121
+ value: "dailyReminder"
122
+ },
123
+ {
124
+ name: "Notion",
125
+ value: "notion"
126
+ }
127
+ ],
128
+ required: true,
129
+ type: "options"
130
+ },
131
+ {
132
+ default: "listMissingTimesheetUsers",
133
+ displayName: "Operation",
134
+ displayOptions: {
135
+ show: {
136
+ resource: ["dailyReminder"]
137
+ }
138
+ },
139
+ name: "operation",
140
+ noDataExpression: true,
141
+ options: [
142
+ {
143
+ action: "List missing timesheet users",
144
+ description: "Return users who have not written today's timesheet",
145
+ name: "List Missing Timesheet Users",
146
+ value: "listMissingTimesheetUsers"
147
+ },
148
+ {
149
+ action: "Mark reminder sent",
150
+ description: "Record that a reminder email was sent",
151
+ name: "Mark Reminder Sent",
152
+ value: "markReminderSent"
153
+ }
154
+ ],
155
+ required: true,
156
+ type: "options"
157
+ },
158
+ {
159
+ default: "runScheduledCleanup",
160
+ displayName: "Operation",
161
+ displayOptions: {
162
+ show: {
163
+ resource: ["aiCleanup"]
164
+ }
165
+ },
166
+ name: "operation",
167
+ noDataExpression: true,
168
+ options: [
169
+ {
170
+ action: "Run scheduled AI cleanup",
171
+ description: "Fill missing English translations and short versions for users using scheduled AI cleanup",
172
+ name: "Run Scheduled Cleanup",
173
+ value: "runScheduledCleanup"
174
+ }
175
+ ],
176
+ required: true,
177
+ type: "options"
178
+ },
179
+ {
180
+ default: "runDailyMaintenance",
181
+ displayName: "Operation",
182
+ displayOptions: {
183
+ show: {
184
+ resource: ["notion"]
185
+ }
186
+ },
187
+ name: "operation",
188
+ noDataExpression: true,
189
+ options: [
190
+ {
191
+ action: "Run daily Notion maintenance",
192
+ description: "Sync recent open or newly closed Notion cards and update mapped Notion fields",
193
+ name: "Run Daily Maintenance",
194
+ value: "runDailyMaintenance"
195
+ }
196
+ ],
197
+ required: true,
198
+ type: "options"
199
+ },
200
+ {
201
+ default: "",
202
+ description: "Defaults to today's date in Asia/Seoul when empty.",
203
+ displayName: "Date Key",
204
+ name: "dateKey",
205
+ placeholder: "2026-05-29",
206
+ type: "string"
207
+ },
208
+ {
209
+ default: 7,
210
+ description: "How many recent days to scan, including the date key.",
211
+ displayName: "Lookback Days",
212
+ displayOptions: {
213
+ show: {
214
+ operation: ["runScheduledCleanup"],
215
+ resource: ["aiCleanup"]
216
+ }
217
+ },
218
+ name: "lookbackDays",
219
+ type: "number",
220
+ typeOptions: {
221
+ maxValue: 31,
222
+ minValue: 1,
223
+ numberPrecision: 0
224
+ }
225
+ },
226
+ {
227
+ default: 2,
228
+ description: "How many recent dates to sync, including the date key. Use 2 to catch cards that ended yesterday.",
229
+ displayName: "Lookback Days",
230
+ displayOptions: {
231
+ show: {
232
+ operation: ["runDailyMaintenance"],
233
+ resource: ["notion"]
234
+ }
235
+ },
236
+ name: "notionLookbackDays",
237
+ type: "number",
238
+ typeOptions: {
239
+ maxValue: 31,
240
+ minValue: 1,
241
+ numberPrecision: 0
242
+ }
243
+ },
244
+ {
245
+ default: false,
246
+ description: "Whether to include users already recorded as reminded for this date.",
247
+ displayName: "Include Already Sent",
248
+ displayOptions: {
249
+ show: {
250
+ operation: ["listMissingTimesheetUsers"],
251
+ resource: ["dailyReminder"]
252
+ }
253
+ },
254
+ name: "includeAlreadySent",
255
+ type: "boolean"
256
+ },
257
+ {
258
+ default: true,
259
+ description: "Whether to output one item per reminder target instead of the raw API response.",
260
+ displayName: "Split Targets Into Items",
261
+ displayOptions: {
262
+ show: {
263
+ operation: ["listMissingTimesheetUsers"],
264
+ resource: ["dailyReminder"]
265
+ }
266
+ },
267
+ name: "splitTargets",
268
+ type: "boolean"
269
+ },
270
+ {
271
+ default: "",
272
+ displayName: "User ID",
273
+ displayOptions: {
274
+ show: {
275
+ operation: ["markReminderSent"],
276
+ resource: ["dailyReminder"]
277
+ }
278
+ },
279
+ name: "userId",
280
+ required: true,
281
+ type: "string"
282
+ },
283
+ {
284
+ default: "",
285
+ displayName: "Email",
286
+ displayOptions: {
287
+ show: {
288
+ operation: ["markReminderSent"],
289
+ resource: ["dailyReminder"]
290
+ }
291
+ },
292
+ name: "email",
293
+ required: true,
294
+ type: "string"
295
+ }
296
+ ]
297
+ };
298
+ async execute() {
299
+ const inputItems = this.getInputData();
300
+ const items = inputItems.length > 0 ? inputItems : [{ json: {} }];
301
+ const returnData = [];
302
+ const alertData = [];
303
+ const credentials = (await this.getCredentials("ajamApi"));
304
+ const baseUrl = normalizeBaseUrl(credentials.baseUrl);
305
+ for (let itemIndex = 0; itemIndex < items.length; itemIndex += 1) {
306
+ const resource = this.getNodeParameter("resource", itemIndex);
307
+ const operation = this.getNodeParameter("operation", itemIndex);
308
+ const dateKey = getStringParameter(this, "dateKey", itemIndex).trim();
309
+ const body = {};
310
+ const url = resource === "notion"
311
+ ? `${baseUrl}/api/internal/notion/daily-maintenance`
312
+ : resource === "aiCleanup"
313
+ ? `${baseUrl}/api/internal/ai/scheduled-cleanup`
314
+ : `${baseUrl}/api/internal/reminders/daily-timesheet`;
315
+ if (resource === "notion") {
316
+ body.lookbackDays = this.getNodeParameter("notionLookbackDays", itemIndex, 2);
317
+ if (dateKey) {
318
+ body.dateKey = dateKey;
319
+ }
320
+ }
321
+ else if (resource === "aiCleanup") {
322
+ body.lookbackDays = this.getNodeParameter("lookbackDays", itemIndex, 7);
323
+ if (dateKey) {
324
+ body.dateKey = dateKey;
325
+ }
326
+ }
327
+ else if (operation === "markReminderSent") {
328
+ body.action = "mark-sent";
329
+ body.dateKey = dateKey;
330
+ body.email = getStringParameter(this, "email", itemIndex).trim();
331
+ body.userId = getStringParameter(this, "userId", itemIndex).trim();
332
+ }
333
+ else {
334
+ body.action = "list";
335
+ body.includeAlreadySent = this.getNodeParameter("includeAlreadySent", itemIndex, false);
336
+ if (dateKey) {
337
+ body.dateKey = dateKey;
338
+ }
339
+ }
340
+ let response;
341
+ try {
342
+ response = (await this.helpers.httpRequest({
343
+ body,
344
+ headers: {
345
+ Authorization: `Bearer ${credentials.apiToken}`,
346
+ "Content-Type": "application/json"
347
+ },
348
+ json: true,
349
+ method: "POST",
350
+ url
351
+ }));
352
+ }
353
+ catch (error) {
354
+ if (resource !== "notion" && resource !== "aiCleanup") {
355
+ throw error;
356
+ }
357
+ const alert = resource === "aiCleanup"
358
+ ? buildAiRequestFailureAlert({ dateKey, error })
359
+ : buildNotionRequestFailureAlert({ dateKey, error });
360
+ alertData.push({
361
+ json: alert,
362
+ pairedItem: {
363
+ item: itemIndex
364
+ }
365
+ });
366
+ returnData.push({
367
+ json: {
368
+ dateKey,
369
+ error: alert.message,
370
+ ok: false
371
+ },
372
+ pairedItem: {
373
+ item: itemIndex
374
+ }
375
+ });
376
+ continue;
377
+ }
378
+ if (operation === "listMissingTimesheetUsers" && this.getNodeParameter("splitTargets", itemIndex, true)) {
379
+ const targets = Array.isArray(response.targets) ? response.targets : [];
380
+ for (const target of targets) {
381
+ returnData.push({
382
+ json: {
383
+ dateKey: response.dateKey,
384
+ ...target
385
+ },
386
+ pairedItem: {
387
+ item: itemIndex
388
+ }
389
+ });
390
+ }
391
+ continue;
392
+ }
393
+ if (resource === "notion") {
394
+ const alert = buildNotionMaintenanceAlert(response);
395
+ if (alert) {
396
+ alertData.push({
397
+ json: alert,
398
+ pairedItem: {
399
+ item: itemIndex
400
+ }
401
+ });
402
+ }
403
+ }
404
+ else if (resource === "aiCleanup") {
405
+ const alert = buildAiScheduledCleanupAlert(response);
406
+ if (alert) {
407
+ alertData.push({
408
+ json: alert,
409
+ pairedItem: {
410
+ item: itemIndex
411
+ }
412
+ });
413
+ }
414
+ }
415
+ returnData.push({
416
+ json: response,
417
+ pairedItem: {
418
+ item: itemIndex
419
+ }
420
+ });
421
+ }
422
+ return [returnData, alertData];
423
+ }
424
+ }
425
+ exports.Ajam = Ajam;
426
+ //# sourceMappingURL=Ajam.node.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Ajam.node.js","sourceRoot":"","sources":["../../../nodes/Ajam/Ajam.node.ts"],"names":[],"mappings":";;;AAAA,+CAAiK;AAOjK,SAAS,gBAAgB,CAAC,OAAe;IACvC,OAAO,OAAO,CAAC,IAAI,EAAE,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;AAC5C,CAAC;AAED,SAAS,kBAAkB,CAAC,gBAAmC,EAAE,IAAY,EAAE,SAAiB;IAC9F,OAAO,gBAAgB,CAAC,gBAAgB,CAAC,IAAI,EAAE,SAAS,EAAE,EAAE,CAAW,CAAC;AAC1E,CAAC;AAED,SAAS,2BAA2B,CAAC,QAAqB;IACxD,MAAM,MAAM,GAAG,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC;IAErE,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACxB,OAAO,IAAI,CAAC;IACd,CAAC;IAED,MAAM,OAAO,GAAG,MAAM,CAAC,QAAQ,CAAC,OAAO,IAAI,EAAE,CAAC,CAAC;IAC/C,MAAM,KAAK,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE;QACjC,MAAM,IAAI,GAAG,KAAoB,CAAC;QAClC,MAAM,QAAQ,GAAG,MAAM,CAAC,IAAI,CAAC,QAAQ,IAAI,IAAI,CAAC,MAAM,IAAI,SAAS,CAAC,CAAC;QACnE,MAAM,OAAO,GAAG,MAAM,CAAC,IAAI,CAAC,OAAO,IAAI,eAAe,CAAC,CAAC;QAExD,OAAO,KAAK,QAAQ,KAAK,OAAO,EAAE,CAAC;IACrC,CAAC,CAAC,CAAC;IAEH,OAAO;QACL,OAAO;QACP,UAAU,EAAE,MAAM,CAAC,MAAM;QACzB,MAAM;QACN,OAAO,EAAE;YACP,GAAG,OAAO,IAAI,MAAM,wCAAwC,MAAM,CAAC,MAAM,QAAQ,MAAM,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,GAAG;YAClH,EAAE;YACF,GAAG,KAAK;SACT,CAAC,IAAI,CAAC,IAAI,CAAC;QACZ,OAAO,EAAE,yCAAyC,OAAO,CAAC,CAAC,CAAC,KAAK,OAAO,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE;KACnF,CAAC;AACJ,CAAC;AAED,SAAS,8BAA8B,CAAC,MAGvC;IACC,MAAM,OAAO,GAAG,MAAM,CAAC,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,uBAAuB,CAAC;IAE/F,OAAO;QACL,OAAO,EAAE,MAAM,CAAC,OAAO;QACvB,UAAU,EAAE,CAAC;QACb,MAAM,EAAE,CAAC,EAAE,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,CAAC;QAC1C,OAAO,EAAE;YACP,GAAG,MAAM,CAAC,OAAO,IAAI,MAAM,2CAA2C;YACtE,EAAE;YACF,cAAc,OAAO,EAAE;SACxB,CAAC,IAAI,CAAC,IAAI,CAAC;QACZ,OAAO,EAAE,iDAAiD,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,KAAK,MAAM,CAAC,OAAO,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE;KACzG,CAAC;AACJ,CAAC;AAED,SAAS,4BAA4B,CAAC,QAAqB;IACzD,MAAM,MAAM,GAAG,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC;IAErE,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACxB,OAAO,IAAI,CAAC;IACd,CAAC;IAED,MAAM,OAAO,GAAG,MAAM,CAAC,QAAQ,CAAC,OAAO,IAAI,EAAE,CAAC,CAAC;IAC/C,MAAM,KAAK,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE;QACjC,MAAM,IAAI,GAAG,KAAoB,CAAC;QAClC,MAAM,QAAQ,GAAG,MAAM,CAAC,IAAI,CAAC,QAAQ,IAAI,IAAI,CAAC,MAAM,IAAI,SAAS,CAAC,CAAC;QACnE,MAAM,OAAO,GAAG,MAAM,CAAC,IAAI,CAAC,OAAO,IAAI,eAAe,CAAC,CAAC;QAExD,OAAO,KAAK,QAAQ,KAAK,OAAO,EAAE,CAAC;IACrC,CAAC,CAAC,CAAC;IAEH,OAAO;QACL,OAAO;QACP,UAAU,EAAE,MAAM,CAAC,MAAM;QACzB,MAAM;QACN,OAAO,EAAE;YACP,GAAG,OAAO,IAAI,MAAM,oCAAoC,MAAM,CAAC,MAAM,QAAQ,MAAM,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,GAAG;YAC9G,EAAE;YACF,GAAG,KAAK;SACT,CAAC,IAAI,CAAC,IAAI,CAAC;QACZ,OAAO,EAAE,qCAAqC,OAAO,CAAC,CAAC,CAAC,KAAK,OAAO,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE;KAC/E,CAAC;AACJ,CAAC;AAED,SAAS,0BAA0B,CAAC,MAGnC;IACC,MAAM,OAAO,GAAG,MAAM,CAAC,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,uBAAuB,CAAC;IAE/F,OAAO;QACL,OAAO,EAAE,MAAM,CAAC,OAAO;QACvB,UAAU,EAAE,CAAC;QACb,MAAM,EAAE,CAAC,EAAE,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,CAAC;QAC1C,OAAO,EAAE;YACP,GAAG,MAAM,CAAC,OAAO,IAAI,MAAM,uCAAuC;YAClE,EAAE;YACF,cAAc,OAAO,EAAE;SACxB,CAAC,IAAI,CAAC,IAAI,CAAC;QACZ,OAAO,EAAE,6CAA6C,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,KAAK,MAAM,CAAC,OAAO,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE;KACrG,CAAC;AACJ,CAAC;AAED,MAAa,IAAI;IACf,WAAW,GAAyB;QAClC,WAAW,EAAE,MAAM;QACnB,IAAI,EAAE,MAAM;QACZ,IAAI,EAAE,eAAe;QACrB,KAAK,EAAE,CAAC,WAAW,CAAC;QACpB,OAAO,EAAE,CAAC;QACV,QAAQ,EAAE,8BAA8B;QACxC,WAAW,EAAE,mCAAmC;QAChD,QAAQ,EAAE;YACR,IAAI,EAAE,MAAM;SACb;QACD,MAAM,EAAE,CAAC,kCAAmB,CAAC,IAAI,CAAC;QAClC,WAAW,EAAE,CAAC,SAAS,EAAE,QAAQ,CAAC;QAClC,OAAO,EAAE,CAAC,kCAAmB,CAAC,IAAI,EAAE,kCAAmB,CAAC,IAAI,CAAC;QAC7D,WAAW,EAAE;YACX;gBACE,IAAI,EAAE,SAAS;gBACf,QAAQ,EAAE,IAAI;aACf;SACF;QACD,UAAU,EAAE;YACV;gBACE,OAAO,EAAE,eAAe;gBACxB,WAAW,EAAE,UAAU;gBACvB,IAAI,EAAE,UAAU;gBAChB,gBAAgB,EAAE,IAAI;gBACtB,OAAO,EAAE;oBACP;wBACE,IAAI,EAAE,YAAY;wBAClB,KAAK,EAAE,WAAW;qBACnB;oBACD;wBACE,IAAI,EAAE,gBAAgB;wBACtB,KAAK,EAAE,eAAe;qBACvB;oBACD;wBACE,IAAI,EAAE,QAAQ;wBACd,KAAK,EAAE,QAAQ;qBAChB;iBACF;gBACD,QAAQ,EAAE,IAAI;gBACd,IAAI,EAAE,SAAS;aAChB;YACD;gBACE,OAAO,EAAE,2BAA2B;gBACpC,WAAW,EAAE,WAAW;gBACxB,cAAc,EAAE;oBACd,IAAI,EAAE;wBACJ,QAAQ,EAAE,CAAC,eAAe,CAAC;qBAC5B;iBACF;gBACD,IAAI,EAAE,WAAW;gBACjB,gBAAgB,EAAE,IAAI;gBACtB,OAAO,EAAE;oBACP;wBACE,MAAM,EAAE,8BAA8B;wBACtC,WAAW,EAAE,qDAAqD;wBAClE,IAAI,EAAE,8BAA8B;wBACpC,KAAK,EAAE,2BAA2B;qBACnC;oBACD;wBACE,MAAM,EAAE,oBAAoB;wBAC5B,WAAW,EAAE,uCAAuC;wBACpD,IAAI,EAAE,oBAAoB;wBAC1B,KAAK,EAAE,kBAAkB;qBAC1B;iBACF;gBACD,QAAQ,EAAE,IAAI;gBACd,IAAI,EAAE,SAAS;aAChB;YACD;gBACE,OAAO,EAAE,qBAAqB;gBAC9B,WAAW,EAAE,WAAW;gBACxB,cAAc,EAAE;oBACd,IAAI,EAAE;wBACJ,QAAQ,EAAE,CAAC,WAAW,CAAC;qBACxB;iBACF;gBACD,IAAI,EAAE,WAAW;gBACjB,gBAAgB,EAAE,IAAI;gBACtB,OAAO,EAAE;oBACP;wBACE,MAAM,EAAE,0BAA0B;wBAClC,WAAW,EAAE,2FAA2F;wBACxG,IAAI,EAAE,uBAAuB;wBAC7B,KAAK,EAAE,qBAAqB;qBAC7B;iBACF;gBACD,QAAQ,EAAE,IAAI;gBACd,IAAI,EAAE,SAAS;aAChB;YACD;gBACE,OAAO,EAAE,qBAAqB;gBAC9B,WAAW,EAAE,WAAW;gBACxB,cAAc,EAAE;oBACd,IAAI,EAAE;wBACJ,QAAQ,EAAE,CAAC,QAAQ,CAAC;qBACrB;iBACF;gBACD,IAAI,EAAE,WAAW;gBACjB,gBAAgB,EAAE,IAAI;gBACtB,OAAO,EAAE;oBACP;wBACE,MAAM,EAAE,8BAA8B;wBACtC,WAAW,EAAE,+EAA+E;wBAC5F,IAAI,EAAE,uBAAuB;wBAC7B,KAAK,EAAE,qBAAqB;qBAC7B;iBACF;gBACD,QAAQ,EAAE,IAAI;gBACd,IAAI,EAAE,SAAS;aAChB;YACD;gBACE,OAAO,EAAE,EAAE;gBACX,WAAW,EAAE,oDAAoD;gBACjE,WAAW,EAAE,UAAU;gBACvB,IAAI,EAAE,SAAS;gBACf,WAAW,EAAE,YAAY;gBACzB,IAAI,EAAE,QAAQ;aACf;YACD;gBACE,OAAO,EAAE,CAAC;gBACV,WAAW,EAAE,uDAAuD;gBACpE,WAAW,EAAE,eAAe;gBAC5B,cAAc,EAAE;oBACd,IAAI,EAAE;wBACJ,SAAS,EAAE,CAAC,qBAAqB,CAAC;wBAClC,QAAQ,EAAE,CAAC,WAAW,CAAC;qBACxB;iBACF;gBACD,IAAI,EAAE,cAAc;gBACpB,IAAI,EAAE,QAAQ;gBACd,WAAW,EAAE;oBACX,QAAQ,EAAE,EAAE;oBACZ,QAAQ,EAAE,CAAC;oBACX,eAAe,EAAE,CAAC;iBACnB;aACF;YACD;gBACE,OAAO,EAAE,CAAC;gBACV,WAAW,EAAE,mGAAmG;gBAChH,WAAW,EAAE,eAAe;gBAC5B,cAAc,EAAE;oBACd,IAAI,EAAE;wBACJ,SAAS,EAAE,CAAC,qBAAqB,CAAC;wBAClC,QAAQ,EAAE,CAAC,QAAQ,CAAC;qBACrB;iBACF;gBACD,IAAI,EAAE,oBAAoB;gBAC1B,IAAI,EAAE,QAAQ;gBACd,WAAW,EAAE;oBACX,QAAQ,EAAE,EAAE;oBACZ,QAAQ,EAAE,CAAC;oBACX,eAAe,EAAE,CAAC;iBACnB;aACF;YACD;gBACE,OAAO,EAAE,KAAK;gBACd,WAAW,EAAE,sEAAsE;gBACnF,WAAW,EAAE,sBAAsB;gBACnC,cAAc,EAAE;oBACd,IAAI,EAAE;wBACJ,SAAS,EAAE,CAAC,2BAA2B,CAAC;wBACxC,QAAQ,EAAE,CAAC,eAAe,CAAC;qBAC5B;iBACF;gBACD,IAAI,EAAE,oBAAoB;gBAC1B,IAAI,EAAE,SAAS;aAChB;YACD;gBACE,OAAO,EAAE,IAAI;gBACb,WAAW,EAAE,iFAAiF;gBAC9F,WAAW,EAAE,0BAA0B;gBACvC,cAAc,EAAE;oBACd,IAAI,EAAE;wBACJ,SAAS,EAAE,CAAC,2BAA2B,CAAC;wBACxC,QAAQ,EAAE,CAAC,eAAe,CAAC;qBAC5B;iBACF;gBACD,IAAI,EAAE,cAAc;gBACpB,IAAI,EAAE,SAAS;aAChB;YACD;gBACE,OAAO,EAAE,EAAE;gBACX,WAAW,EAAE,SAAS;gBACtB,cAAc,EAAE;oBACd,IAAI,EAAE;wBACJ,SAAS,EAAE,CAAC,kBAAkB,CAAC;wBAC/B,QAAQ,EAAE,CAAC,eAAe,CAAC;qBAC5B;iBACF;gBACD,IAAI,EAAE,QAAQ;gBACd,QAAQ,EAAE,IAAI;gBACd,IAAI,EAAE,QAAQ;aACf;YACD;gBACE,OAAO,EAAE,EAAE;gBACX,WAAW,EAAE,OAAO;gBACpB,cAAc,EAAE;oBACd,IAAI,EAAE;wBACJ,SAAS,EAAE,CAAC,kBAAkB,CAAC;wBAC/B,QAAQ,EAAE,CAAC,eAAe,CAAC;qBAC5B;iBACF;gBACD,IAAI,EAAE,OAAO;gBACb,QAAQ,EAAE,IAAI;gBACd,IAAI,EAAE,QAAQ;aACf;SACF;KACF,CAAC;IAEF,KAAK,CAAC,OAAO;QACX,MAAM,UAAU,GAAG,IAAI,CAAC,YAAY,EAAE,CAAC;QACvC,MAAM,KAAK,GAAG,UAAU,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,EAAE,EAAE,CAAC,CAAC;QAClE,MAAM,UAAU,GAAyB,EAAE,CAAC;QAC5C,MAAM,SAAS,GAAyB,EAAE,CAAC;QAC3C,MAAM,WAAW,GAAG,CAAC,MAAM,IAAI,CAAC,cAAc,CAAC,SAAS,CAAC,CAAoB,CAAC;QAC9E,MAAM,OAAO,GAAG,gBAAgB,CAAC,WAAW,CAAC,OAAO,CAAC,CAAC;QAEtD,KAAK,IAAI,SAAS,GAAG,CAAC,EAAE,SAAS,GAAG,KAAK,CAAC,MAAM,EAAE,SAAS,IAAI,CAAC,EAAE,CAAC;YACjE,MAAM,QAAQ,GAAG,IAAI,CAAC,gBAAgB,CAAC,UAAU,EAAE,SAAS,CAAW,CAAC;YACxE,MAAM,SAAS,GAAG,IAAI,CAAC,gBAAgB,CAAC,WAAW,EAAE,SAAS,CAAW,CAAC;YAC1E,MAAM,OAAO,GAAG,kBAAkB,CAAC,IAAI,EAAE,SAAS,EAAE,SAAS,CAAC,CAAC,IAAI,EAAE,CAAC;YACtE,MAAM,IAAI,GAAgB,EAAE,CAAC;YAC7B,MAAM,GAAG,GAAG,QAAQ,KAAK,QAAQ;gBAC/B,CAAC,CAAC,GAAG,OAAO,wCAAwC;gBACpD,CAAC,CAAC,QAAQ,KAAK,WAAW;oBACxB,CAAC,CAAC,GAAG,OAAO,oCAAoC;oBAChD,CAAC,CAAC,GAAG,OAAO,yCAAyC,CAAC;YAE1D,IAAI,QAAQ,KAAK,QAAQ,EAAE,CAAC;gBAC1B,IAAI,CAAC,YAAY,GAAG,IAAI,CAAC,gBAAgB,CAAC,oBAAoB,EAAE,SAAS,EAAE,CAAC,CAAW,CAAC;gBAExF,IAAI,OAAO,EAAE,CAAC;oBACZ,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;gBACzB,CAAC;YACH,CAAC;iBAAM,IAAI,QAAQ,KAAK,WAAW,EAAE,CAAC;gBACpC,IAAI,CAAC,YAAY,GAAG,IAAI,CAAC,gBAAgB,CAAC,cAAc,EAAE,SAAS,EAAE,CAAC,CAAW,CAAC;gBAElF,IAAI,OAAO,EAAE,CAAC;oBACZ,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;gBACzB,CAAC;YACH,CAAC;iBAAM,IAAI,SAAS,KAAK,kBAAkB,EAAE,CAAC;gBAC5C,IAAI,CAAC,MAAM,GAAG,WAAW,CAAC;gBAC1B,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;gBACvB,IAAI,CAAC,KAAK,GAAG,kBAAkB,CAAC,IAAI,EAAE,OAAO,EAAE,SAAS,CAAC,CAAC,IAAI,EAAE,CAAC;gBACjE,IAAI,CAAC,MAAM,GAAG,kBAAkB,CAAC,IAAI,EAAE,QAAQ,EAAE,SAAS,CAAC,CAAC,IAAI,EAAE,CAAC;YACrE,CAAC;iBAAM,CAAC;gBACN,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;gBACrB,IAAI,CAAC,kBAAkB,GAAG,IAAI,CAAC,gBAAgB,CAAC,oBAAoB,EAAE,SAAS,EAAE,KAAK,CAAY,CAAC;gBAEnG,IAAI,OAAO,EAAE,CAAC;oBACZ,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;gBACzB,CAAC;YACH,CAAC;YAED,IAAI,QAAqB,CAAC;YAE1B,IAAI,CAAC;gBACH,QAAQ,GAAG,CAAC,MAAM,IAAI,CAAC,OAAO,CAAC,WAAW,CAAC;oBACzC,IAAI;oBACJ,OAAO,EAAE;wBACP,aAAa,EAAE,UAAU,WAAW,CAAC,QAAQ,EAAE;wBAC/C,cAAc,EAAE,kBAAkB;qBACnC;oBACD,IAAI,EAAE,IAAI;oBACV,MAAM,EAAE,MAAM;oBACd,GAAG;iBACJ,CAAC,CAAgB,CAAC;YACrB,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,IAAI,QAAQ,KAAK,QAAQ,IAAI,QAAQ,KAAK,WAAW,EAAE,CAAC;oBACtD,MAAM,KAAK,CAAC;gBACd,CAAC;gBAED,MAAM,KAAK,GAAG,QAAQ,KAAK,WAAW;oBACpC,CAAC,CAAC,0BAA0B,CAAC,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC;oBAChD,CAAC,CAAC,8BAA8B,CAAC,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC,CAAC;gBAEvD,SAAS,CAAC,IAAI,CAAC;oBACb,IAAI,EAAE,KAAK;oBACX,UAAU,EAAE;wBACV,IAAI,EAAE,SAAS;qBAChB;iBACF,CAAC,CAAC;gBACH,UAAU,CAAC,IAAI,CAAC;oBACd,IAAI,EAAE;wBACJ,OAAO;wBACP,KAAK,EAAE,KAAK,CAAC,OAAO;wBACpB,EAAE,EAAE,KAAK;qBACV;oBACD,UAAU,EAAE;wBACV,IAAI,EAAE,SAAS;qBAChB;iBACF,CAAC,CAAC;gBACH,SAAS;YACX,CAAC;YAED,IAAI,SAAS,KAAK,2BAA2B,IAAI,IAAI,CAAC,gBAAgB,CAAC,cAAc,EAAE,SAAS,EAAE,IAAI,CAAC,EAAE,CAAC;gBACxG,MAAM,OAAO,GAAG,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC;gBAExE,KAAK,MAAM,MAAM,IAAI,OAAO,EAAE,CAAC;oBAC7B,UAAU,CAAC,IAAI,CAAC;wBACd,IAAI,EAAE;4BACJ,OAAO,EAAE,QAAQ,CAAC,OAAO;4BACzB,GAAI,MAAsB;yBAC3B;wBACD,UAAU,EAAE;4BACV,IAAI,EAAE,SAAS;yBAChB;qBACF,CAAC,CAAC;gBACL,CAAC;gBACD,SAAS;YACX,CAAC;YAED,IAAI,QAAQ,KAAK,QAAQ,EAAE,CAAC;gBAC1B,MAAM,KAAK,GAAG,2BAA2B,CAAC,QAAQ,CAAC,CAAC;gBAEpD,IAAI,KAAK,EAAE,CAAC;oBACV,SAAS,CAAC,IAAI,CAAC;wBACb,IAAI,EAAE,KAAK;wBACX,UAAU,EAAE;4BACV,IAAI,EAAE,SAAS;yBAChB;qBACF,CAAC,CAAC;gBACL,CAAC;YACH,CAAC;iBAAM,IAAI,QAAQ,KAAK,WAAW,EAAE,CAAC;gBACpC,MAAM,KAAK,GAAG,4BAA4B,CAAC,QAAQ,CAAC,CAAC;gBAErD,IAAI,KAAK,EAAE,CAAC;oBACV,SAAS,CAAC,IAAI,CAAC;wBACb,IAAI,EAAE,KAAK;wBACX,UAAU,EAAE;4BACV,IAAI,EAAE,SAAS;yBAChB;qBACF,CAAC,CAAC;gBACL,CAAC;YACH,CAAC;YAED,UAAU,CAAC,IAAI,CAAC;gBACd,IAAI,EAAE,QAAQ;gBACd,UAAU,EAAE;oBACV,IAAI,EAAE,SAAS;iBAChB;aACF,CAAC,CAAC;QACL,CAAC;QAED,OAAO,CAAC,UAAU,EAAE,SAAS,CAAC,CAAC;IACjC,CAAC;CACF;AA7VD,oBA6VC"}
@@ -0,0 +1,18 @@
1
+ {
2
+ "node": "n8n-nodes-ajam.ajam",
3
+ "nodeVersion": "1.0",
4
+ "codexVersion": "1.0",
5
+ "categories": ["Productivity"],
6
+ "resources": {
7
+ "credentialDocumentation": [
8
+ {
9
+ "url": "https://github.com/junglesub/ajam"
10
+ }
11
+ ],
12
+ "primaryDocumentation": [
13
+ {
14
+ "url": "https://github.com/junglesub/ajam"
15
+ }
16
+ ]
17
+ }
18
+ }
@@ -0,0 +1,6 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64" role="img" aria-label="aJam">
2
+ <rect width="64" height="64" rx="14" fill="#020617"/>
3
+ <path d="M18 20h28v26H18z" fill="none" stroke="#99f6e4" stroke-width="4" stroke-linejoin="round"/>
4
+ <path d="M24 14v10M40 14v10M18 30h28" stroke="#99f6e4" stroke-width="4" stroke-linecap="round"/>
5
+ <path d="M26 39h12" stroke="#ffffff" stroke-width="4" stroke-linecap="round"/>
6
+ </svg>
package/package.json ADDED
@@ -0,0 +1,39 @@
1
+ {
2
+ "name": "@junglesub/n8n-nodes-ajam",
3
+ "version": "0.4.0",
4
+ "description": "n8n community nodes for aJam automation.",
5
+ "license": "MIT",
6
+ "type": "commonjs",
7
+ "main": "dist/nodes/Ajam/Ajam.node.js",
8
+ "publishConfig": {
9
+ "access": "public",
10
+ "registry": "https://registry.npmjs.org"
11
+ },
12
+ "files": [
13
+ "dist"
14
+ ],
15
+ "scripts": {
16
+ "build": "tsc -p tsconfig.json && node scripts/copy-assets.mjs",
17
+ "typecheck": "tsc --noEmit -p tsconfig.json"
18
+ },
19
+ "keywords": [
20
+ "n8n-community-node-package",
21
+ "n8n",
22
+ "ajam",
23
+ "timesheet"
24
+ ],
25
+ "n8n": {
26
+ "n8nNodesApiVersion": 1,
27
+ "credentials": [
28
+ "dist/credentials/AjamApi.credentials.js"
29
+ ],
30
+ "nodes": [
31
+ "dist/nodes/Ajam/Ajam.node.js"
32
+ ]
33
+ },
34
+ "devDependencies": {
35
+ "n8n-core": "^1.0.0",
36
+ "n8n-workflow": "^1.0.0",
37
+ "typescript": "^5.9.3"
38
+ }
39
+ }