n8n-nodes-substack-new 0.0.1

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 (55) hide show
  1. package/LICENSE.md +19 -0
  2. package/README.md +139 -0
  3. package/dist/credentials/SubstackGatewayApi.credentials.d.ts +9 -0
  4. package/dist/credentials/SubstackGatewayApi.credentials.js +61 -0
  5. package/dist/credentials/SubstackGatewayApi.credentials.js.map +1 -0
  6. package/dist/nodes/SubstackGateway/Comment.fields.d.ts +2 -0
  7. package/dist/nodes/SubstackGateway/Comment.fields.js +36 -0
  8. package/dist/nodes/SubstackGateway/Comment.fields.js.map +1 -0
  9. package/dist/nodes/SubstackGateway/Comment.operations.d.ts +8 -0
  10. package/dist/nodes/SubstackGateway/Comment.operations.js +44 -0
  11. package/dist/nodes/SubstackGateway/Comment.operations.js.map +1 -0
  12. package/dist/nodes/SubstackGateway/Note.fields.d.ts +2 -0
  13. package/dist/nodes/SubstackGateway/Note.fields.js +150 -0
  14. package/dist/nodes/SubstackGateway/Note.fields.js.map +1 -0
  15. package/dist/nodes/SubstackGateway/Note.operations.d.ts +11 -0
  16. package/dist/nodes/SubstackGateway/Note.operations.js +109 -0
  17. package/dist/nodes/SubstackGateway/Note.operations.js.map +1 -0
  18. package/dist/nodes/SubstackGateway/Post.fields.d.ts +2 -0
  19. package/dist/nodes/SubstackGateway/Post.fields.js +66 -0
  20. package/dist/nodes/SubstackGateway/Post.fields.js.map +1 -0
  21. package/dist/nodes/SubstackGateway/Post.operations.d.ts +10 -0
  22. package/dist/nodes/SubstackGateway/Post.operations.js +74 -0
  23. package/dist/nodes/SubstackGateway/Post.operations.js.map +1 -0
  24. package/dist/nodes/SubstackGateway/Profile.fields.d.ts +2 -0
  25. package/dist/nodes/SubstackGateway/Profile.fields.js +61 -0
  26. package/dist/nodes/SubstackGateway/Profile.fields.js.map +1 -0
  27. package/dist/nodes/SubstackGateway/Profile.operations.d.ts +10 -0
  28. package/dist/nodes/SubstackGateway/Profile.operations.js +72 -0
  29. package/dist/nodes/SubstackGateway/Profile.operations.js.map +1 -0
  30. package/dist/nodes/SubstackGateway/Substack.node.d.ts +11 -0
  31. package/dist/nodes/SubstackGateway/Substack.node.js +148 -0
  32. package/dist/nodes/SubstackGateway/Substack.node.js.map +1 -0
  33. package/dist/nodes/SubstackGateway/Substack.node.json +22 -0
  34. package/dist/nodes/SubstackGateway/SubstackUtils.d.ts +12 -0
  35. package/dist/nodes/SubstackGateway/SubstackUtils.js +59 -0
  36. package/dist/nodes/SubstackGateway/SubstackUtils.js.map +1 -0
  37. package/dist/nodes/SubstackGateway/shared/DataFormatters.d.ts +9 -0
  38. package/dist/nodes/SubstackGateway/shared/DataFormatters.js +73 -0
  39. package/dist/nodes/SubstackGateway/shared/DataFormatters.js.map +1 -0
  40. package/dist/nodes/SubstackGateway/shared/OperationHandler.d.ts +11 -0
  41. package/dist/nodes/SubstackGateway/shared/OperationHandler.js +44 -0
  42. package/dist/nodes/SubstackGateway/shared/OperationHandler.js.map +1 -0
  43. package/dist/nodes/SubstackGateway/shared/OperationUtils.d.ts +5 -0
  44. package/dist/nodes/SubstackGateway/shared/OperationUtils.js +35 -0
  45. package/dist/nodes/SubstackGateway/shared/OperationUtils.js.map +1 -0
  46. package/dist/nodes/SubstackGateway/shared/SubstackGatewayClient.d.ts +69 -0
  47. package/dist/nodes/SubstackGateway/shared/SubstackGatewayClient.js +222 -0
  48. package/dist/nodes/SubstackGateway/shared/SubstackGatewayClient.js.map +1 -0
  49. package/dist/nodes/SubstackGateway/substack.svg +7 -0
  50. package/dist/nodes/SubstackGateway/types.d.ts +51 -0
  51. package/dist/nodes/SubstackGateway/types.js +3 -0
  52. package/dist/nodes/SubstackGateway/types.js.map +1 -0
  53. package/dist/package.json +67 -0
  54. package/dist/tsconfig.tsbuildinfo +1 -0
  55. package/package.json +66 -0
@@ -0,0 +1,66 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.postFields = void 0;
4
+ exports.postFields = [
5
+ {
6
+ displayName: 'Limit',
7
+ name: 'limit',
8
+ type: 'number',
9
+ default: 50,
10
+ description: 'Max number of results to return',
11
+ displayOptions: {
12
+ show: {
13
+ resource: ['post'],
14
+ operation: ['getAll'],
15
+ },
16
+ },
17
+ typeOptions: {
18
+ minValue: 1,
19
+ },
20
+ },
21
+ {
22
+ displayName: 'Slug',
23
+ name: 'slug',
24
+ type: 'string',
25
+ default: '',
26
+ description: 'The publication slug (subdomain)',
27
+ displayOptions: {
28
+ show: {
29
+ resource: ['post'],
30
+ operation: ['getPostsBySlug'],
31
+ },
32
+ },
33
+ required: true,
34
+ },
35
+ {
36
+ displayName: 'Limit',
37
+ name: 'limit',
38
+ type: 'number',
39
+ default: 50,
40
+ description: 'Max number of results to return',
41
+ displayOptions: {
42
+ show: {
43
+ resource: ['post'],
44
+ operation: ['getPostsBySlug'],
45
+ },
46
+ },
47
+ typeOptions: {
48
+ minValue: 1,
49
+ },
50
+ },
51
+ {
52
+ displayName: 'Post ID',
53
+ name: 'postId',
54
+ type: 'string',
55
+ default: '',
56
+ description: 'The ID of the post to retrieve',
57
+ displayOptions: {
58
+ show: {
59
+ resource: ['post'],
60
+ operation: ['getPostById'],
61
+ },
62
+ },
63
+ required: true,
64
+ },
65
+ ];
66
+ //# sourceMappingURL=Post.fields.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Post.fields.js","sourceRoot":"","sources":["../../../nodes/SubstackGateway/Post.fields.ts"],"names":[],"mappings":";;;AAEa,QAAA,UAAU,GAAsB;IAI5C;QACC,WAAW,EAAE,OAAO;QACpB,IAAI,EAAE,OAAO;QACb,IAAI,EAAE,QAAQ;QACd,OAAO,EAAE,EAAE;QACX,WAAW,EAAE,iCAAiC;QAC9C,cAAc,EAAE;YACf,IAAI,EAAE;gBACL,QAAQ,EAAE,CAAC,MAAM,CAAC;gBAClB,SAAS,EAAE,CAAC,QAAQ,CAAC;aACrB;SACD;QACD,WAAW,EAAE;YACZ,QAAQ,EAAE,CAAC;SACX;KACD;IAID;QACC,WAAW,EAAE,MAAM;QACnB,IAAI,EAAE,MAAM;QACZ,IAAI,EAAE,QAAQ;QACd,OAAO,EAAE,EAAE;QACX,WAAW,EAAE,kCAAkC;QAC/C,cAAc,EAAE;YACf,IAAI,EAAE;gBACL,QAAQ,EAAE,CAAC,MAAM,CAAC;gBAClB,SAAS,EAAE,CAAC,gBAAgB,CAAC;aAC7B;SACD;QACD,QAAQ,EAAE,IAAI;KACd;IACD;QACC,WAAW,EAAE,OAAO;QACpB,IAAI,EAAE,OAAO;QACb,IAAI,EAAE,QAAQ;QACd,OAAO,EAAE,EAAE;QACX,WAAW,EAAE,iCAAiC;QAC9C,cAAc,EAAE;YACf,IAAI,EAAE;gBACL,QAAQ,EAAE,CAAC,MAAM,CAAC;gBAClB,SAAS,EAAE,CAAC,gBAAgB,CAAC;aAC7B;SACD;QACD,WAAW,EAAE;YACZ,QAAQ,EAAE,CAAC;SACX;KACD;IAID;QACC,WAAW,EAAE,SAAS;QACtB,IAAI,EAAE,QAAQ;QACd,IAAI,EAAE,QAAQ;QACd,OAAO,EAAE,EAAE;QACX,WAAW,EAAE,gCAAgC;QAC7C,cAAc,EAAE;YACf,IAAI,EAAE;gBACL,QAAQ,EAAE,CAAC,MAAM,CAAC;gBAClB,SAAS,EAAE,CAAC,aAAa,CAAC;aAC1B;SACD;QACD,QAAQ,EAAE,IAAI;KACd;CACD,CAAC"}
@@ -0,0 +1,10 @@
1
+ import { IExecuteFunctions, INodeProperties } from 'n8n-workflow';
2
+ import { SubstackClient } from './shared/SubstackGatewayClient';
3
+ import { IStandardResponse } from './types';
4
+ export declare enum PostOperation {
5
+ GetAll = "getAll",
6
+ GetPostsBySlug = "getPostsBySlug",
7
+ GetPostById = "getPostById"
8
+ }
9
+ export declare const postOperations: INodeProperties[];
10
+ export declare const postOperationHandlers: Record<PostOperation, (executeFunctions: IExecuteFunctions, client: SubstackClient, publicationAddress: string, itemIndex: number) => Promise<IStandardResponse>>;
@@ -0,0 +1,74 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.postOperationHandlers = exports.postOperations = exports.PostOperation = void 0;
4
+ const DataFormatters_1 = require("./shared/DataFormatters");
5
+ const OperationUtils_1 = require("./shared/OperationUtils");
6
+ const OperationHandler_1 = require("./shared/OperationHandler");
7
+ var PostOperation;
8
+ (function (PostOperation) {
9
+ PostOperation["GetAll"] = "getAll";
10
+ PostOperation["GetPostsBySlug"] = "getPostsBySlug";
11
+ PostOperation["GetPostById"] = "getPostById";
12
+ })(PostOperation || (exports.PostOperation = PostOperation = {}));
13
+ exports.postOperations = [
14
+ {
15
+ displayName: 'Operation',
16
+ name: 'operation',
17
+ type: 'options',
18
+ default: 'getAll',
19
+ noDataExpression: true,
20
+ displayOptions: {
21
+ show: {
22
+ resource: ['post'],
23
+ },
24
+ },
25
+ options: [
26
+ {
27
+ name: 'Get All Posts',
28
+ value: PostOperation.GetAll,
29
+ description: 'Get all posts from own profile',
30
+ action: 'Get all posts',
31
+ },
32
+ {
33
+ name: 'Get Posts From Profile by Slug',
34
+ value: PostOperation.GetPostsBySlug,
35
+ description: 'Get posts from a profile by its publication slug',
36
+ action: 'Get posts by slug',
37
+ },
38
+ {
39
+ name: 'Get Post by ID',
40
+ value: PostOperation.GetPostById,
41
+ description: 'Get a specific post by its ID',
42
+ action: 'Get post by ID',
43
+ },
44
+ ],
45
+ },
46
+ ];
47
+ async function getAll(executeFunctions, client, publicationAddress, itemIndex) {
48
+ return OperationHandler_1.OperationHandler.execute(executeFunctions, itemIndex, async () => {
49
+ const limit = OperationHandler_1.OperationHandler.getLimit(executeFunctions, itemIndex);
50
+ const profile = await OperationHandler_1.OperationHandler.resolveProfile(client);
51
+ return OperationHandler_1.OperationHandler.collectFromIterable(profile.posts(), limit, (post) => DataFormatters_1.DataFormatters.formatPost(post, publicationAddress));
52
+ });
53
+ }
54
+ async function getPostsBySlug(executeFunctions, client, publicationAddress, itemIndex) {
55
+ return OperationHandler_1.OperationHandler.execute(executeFunctions, itemIndex, async () => {
56
+ const slug = executeFunctions.getNodeParameter('slug', itemIndex);
57
+ const limit = OperationHandler_1.OperationHandler.getLimit(executeFunctions, itemIndex);
58
+ const profile = await OperationHandler_1.OperationHandler.resolveProfile(client, slug);
59
+ return OperationHandler_1.OperationHandler.collectFromIterable(profile.posts(), limit, (post) => DataFormatters_1.DataFormatters.formatPost(post, publicationAddress));
60
+ });
61
+ }
62
+ async function getPostById(executeFunctions, client, publicationAddress, itemIndex) {
63
+ return OperationHandler_1.OperationHandler.execute(executeFunctions, itemIndex, async () => {
64
+ const postId = OperationUtils_1.OperationUtils.parseNumericParam(executeFunctions.getNodeParameter('postId', itemIndex), 'postId');
65
+ const post = await client.postForId(postId);
66
+ return DataFormatters_1.DataFormatters.formatPost(post, publicationAddress);
67
+ });
68
+ }
69
+ exports.postOperationHandlers = {
70
+ [PostOperation.GetAll]: getAll,
71
+ [PostOperation.GetPostsBySlug]: getPostsBySlug,
72
+ [PostOperation.GetPostById]: getPostById,
73
+ };
74
+ //# sourceMappingURL=Post.operations.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Post.operations.js","sourceRoot":"","sources":["../../../nodes/SubstackGateway/Post.operations.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ import { INodeProperties } from 'n8n-workflow';
2
+ export declare const profileFields: INodeProperties[];
@@ -0,0 +1,61 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.profileFields = void 0;
4
+ exports.profileFields = [
5
+ {
6
+ displayName: 'Slug',
7
+ name: 'slug',
8
+ type: 'string',
9
+ default: '',
10
+ description: 'The publication slug (subdomain)',
11
+ displayOptions: {
12
+ show: {
13
+ resource: ['profile'],
14
+ operation: ['getProfileBySlug'],
15
+ },
16
+ },
17
+ required: true,
18
+ },
19
+ {
20
+ displayName: 'Return Type',
21
+ name: 'returnType',
22
+ type: 'options',
23
+ options: [
24
+ {
25
+ name: 'Full Profiles',
26
+ value: 'profiles',
27
+ description: 'Return complete profile information',
28
+ },
29
+ {
30
+ name: 'User IDs Only',
31
+ value: 'ids',
32
+ description: 'Return only user IDs',
33
+ },
34
+ ],
35
+ default: 'profiles',
36
+ description: 'Choose what information to return about the users you follow',
37
+ displayOptions: {
38
+ show: {
39
+ resource: ['profile'],
40
+ operation: ['getFollowees'],
41
+ },
42
+ },
43
+ },
44
+ {
45
+ displayName: 'Limit',
46
+ name: 'limit',
47
+ type: 'number',
48
+ default: 50,
49
+ description: 'Max number of results to return',
50
+ displayOptions: {
51
+ show: {
52
+ resource: ['profile'],
53
+ operation: ['getFollowees'],
54
+ },
55
+ },
56
+ typeOptions: {
57
+ minValue: 1,
58
+ },
59
+ },
60
+ ];
61
+ //# sourceMappingURL=Profile.fields.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Profile.fields.js","sourceRoot":"","sources":["../../../nodes/SubstackGateway/Profile.fields.ts"],"names":[],"mappings":";;;AAEa,QAAA,aAAa,GAAsB;IAI/C;QACC,WAAW,EAAE,MAAM;QACnB,IAAI,EAAE,MAAM;QACZ,IAAI,EAAE,QAAQ;QACd,OAAO,EAAE,EAAE;QACX,WAAW,EAAE,kCAAkC;QAC/C,cAAc,EAAE;YACf,IAAI,EAAE;gBACL,QAAQ,EAAE,CAAC,SAAS,CAAC;gBACrB,SAAS,EAAE,CAAC,kBAAkB,CAAC;aAC/B;SACD;QACD,QAAQ,EAAE,IAAI;KACd;IAID;QACC,WAAW,EAAE,aAAa;QAC1B,IAAI,EAAE,YAAY;QAClB,IAAI,EAAE,SAAS;QACf,OAAO,EAAE;YACR;gBACC,IAAI,EAAE,eAAe;gBACrB,KAAK,EAAE,UAAU;gBACjB,WAAW,EAAE,qCAAqC;aAClD;YACD;gBACC,IAAI,EAAE,eAAe;gBACrB,KAAK,EAAE,KAAK;gBACZ,WAAW,EAAE,sBAAsB;aACnC;SACD;QACD,OAAO,EAAE,UAAU;QACnB,WAAW,EAAE,8DAA8D;QAC3E,cAAc,EAAE;YACf,IAAI,EAAE;gBACL,QAAQ,EAAE,CAAC,SAAS,CAAC;gBACrB,SAAS,EAAE,CAAC,cAAc,CAAC;aAC3B;SACD;KACD;IACD;QACC,WAAW,EAAE,OAAO;QACpB,IAAI,EAAE,OAAO;QACb,IAAI,EAAE,QAAQ;QACd,OAAO,EAAE,EAAE;QACX,WAAW,EAAE,iCAAiC;QAC9C,cAAc,EAAE;YACf,IAAI,EAAE;gBACL,QAAQ,EAAE,CAAC,SAAS,CAAC;gBACrB,SAAS,EAAE,CAAC,cAAc,CAAC;aAC3B;SACD;QACD,WAAW,EAAE;YACZ,QAAQ,EAAE,CAAC;SACX;KACD;CACD,CAAC"}
@@ -0,0 +1,10 @@
1
+ import { IExecuteFunctions, INodeProperties } from 'n8n-workflow';
2
+ import { SubstackClient } from './shared/SubstackGatewayClient';
3
+ import { IStandardResponse } from './types';
4
+ export declare enum ProfileOperation {
5
+ GetOwnProfile = "getOwnProfile",
6
+ GetProfileBySlug = "getProfileBySlug",
7
+ GetFollowees = "getFollowees"
8
+ }
9
+ export declare const profileOperations: INodeProperties[];
10
+ export declare const profileOperationHandlers: Record<ProfileOperation, (executeFunctions: IExecuteFunctions, client: SubstackClient, publicationAddress: string, itemIndex: number) => Promise<IStandardResponse>>;
@@ -0,0 +1,72 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.profileOperationHandlers = exports.profileOperations = exports.ProfileOperation = void 0;
4
+ const DataFormatters_1 = require("./shared/DataFormatters");
5
+ const OperationHandler_1 = require("./shared/OperationHandler");
6
+ var ProfileOperation;
7
+ (function (ProfileOperation) {
8
+ ProfileOperation["GetOwnProfile"] = "getOwnProfile";
9
+ ProfileOperation["GetProfileBySlug"] = "getProfileBySlug";
10
+ ProfileOperation["GetFollowees"] = "getFollowees";
11
+ })(ProfileOperation || (exports.ProfileOperation = ProfileOperation = {}));
12
+ exports.profileOperations = [
13
+ {
14
+ displayName: 'Operation',
15
+ name: 'operation',
16
+ type: 'options',
17
+ default: 'getOwnProfile',
18
+ noDataExpression: true,
19
+ displayOptions: {
20
+ show: {
21
+ resource: ['profile'],
22
+ },
23
+ },
24
+ options: [
25
+ {
26
+ name: 'Get Own Profile',
27
+ value: ProfileOperation.GetOwnProfile,
28
+ description: 'Get your own profile information',
29
+ action: 'Get own profile',
30
+ },
31
+ {
32
+ name: 'Get Profile by Slug',
33
+ value: ProfileOperation.GetProfileBySlug,
34
+ description: 'Get a profile by its publication slug',
35
+ action: 'Get profile by slug',
36
+ },
37
+ {
38
+ name: 'Get Followees',
39
+ value: ProfileOperation.GetFollowees,
40
+ description: 'Get users that you follow',
41
+ action: 'Get followees',
42
+ },
43
+ ],
44
+ },
45
+ ];
46
+ async function getOwnProfile(executeFunctions, client, publicationAddress, itemIndex) {
47
+ return OperationHandler_1.OperationHandler.execute(executeFunctions, itemIndex, async () => {
48
+ const profile = await client.ownProfile();
49
+ return DataFormatters_1.DataFormatters.formatProfile(profile);
50
+ });
51
+ }
52
+ async function getProfileBySlug(executeFunctions, client, publicationAddress, itemIndex) {
53
+ return OperationHandler_1.OperationHandler.execute(executeFunctions, itemIndex, async () => {
54
+ const slug = executeFunctions.getNodeParameter('slug', itemIndex);
55
+ const profile = await client.profileForSlug(slug);
56
+ return DataFormatters_1.DataFormatters.formatProfile(profile);
57
+ });
58
+ }
59
+ async function getFollowees(executeFunctions, client, publicationAddress, itemIndex) {
60
+ return OperationHandler_1.OperationHandler.execute(executeFunctions, itemIndex, async () => {
61
+ const returnType = executeFunctions.getNodeParameter('returnType', itemIndex, 'profiles');
62
+ const limit = OperationHandler_1.OperationHandler.getLimit(executeFunctions, itemIndex);
63
+ const ownProfile = await client.ownProfile();
64
+ return OperationHandler_1.OperationHandler.collectFromIterable(ownProfile.following(), limit, (followee) => DataFormatters_1.DataFormatters.formatFollowing(followee, returnType));
65
+ });
66
+ }
67
+ exports.profileOperationHandlers = {
68
+ [ProfileOperation.GetOwnProfile]: getOwnProfile,
69
+ [ProfileOperation.GetProfileBySlug]: getProfileBySlug,
70
+ [ProfileOperation.GetFollowees]: getFollowees,
71
+ };
72
+ //# sourceMappingURL=Profile.operations.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Profile.operations.js","sourceRoot":"","sources":["../../../nodes/SubstackGateway/Profile.operations.ts"],"names":[],"mappings":";;;AAGA,4DAAyD;AACzD,gEAA6D;AAE7D,IAAY,gBAIX;AAJD,WAAY,gBAAgB;IAC3B,mDAA+B,CAAA;IAC/B,yDAAqC,CAAA;IACrC,iDAA6B,CAAA;AAC9B,CAAC,EAJW,gBAAgB,gCAAhB,gBAAgB,QAI3B;AAEY,QAAA,iBAAiB,GAAsB;IACnD;QACC,WAAW,EAAE,WAAW;QACxB,IAAI,EAAE,WAAW;QACjB,IAAI,EAAE,SAAS;QACf,OAAO,EAAE,eAAe;QACxB,gBAAgB,EAAE,IAAI;QACtB,cAAc,EAAE;YACf,IAAI,EAAE;gBACL,QAAQ,EAAE,CAAC,SAAS,CAAC;aACrB;SACD;QACD,OAAO,EAAE;YACR;gBACC,IAAI,EAAE,iBAAiB;gBACvB,KAAK,EAAE,gBAAgB,CAAC,aAAa;gBACrC,WAAW,EAAE,kCAAkC;gBAC/C,MAAM,EAAE,iBAAiB;aACzB;YACD;gBACC,IAAI,EAAE,qBAAqB;gBAC3B,KAAK,EAAE,gBAAgB,CAAC,gBAAgB;gBACxC,WAAW,EAAE,uCAAuC;gBACpD,MAAM,EAAE,qBAAqB;aAC7B;YACD;gBACC,IAAI,EAAE,eAAe;gBACrB,KAAK,EAAE,gBAAgB,CAAC,YAAY;gBACpC,WAAW,EAAE,2BAA2B;gBACxC,MAAM,EAAE,eAAe;aACvB;SACD;KACD;CACD,CAAC;AAEF,KAAK,UAAU,aAAa,CAC3B,gBAAmC,EACnC,MAAsB,EACtB,kBAA0B,EAC1B,SAAiB;IAEjB,OAAO,mCAAgB,CAAC,OAAO,CAAC,gBAAgB,EAAE,SAAS,EAAE,KAAK,IAAI,EAAE;QACvE,MAAM,OAAO,GAAG,MAAM,MAAM,CAAC,UAAU,EAAE,CAAC;QAC1C,OAAO,+BAAc,CAAC,aAAa,CAAC,OAAO,CAAC,CAAC;IAC9C,CAAC,CAAC,CAAC;AACJ,CAAC;AAED,KAAK,UAAU,gBAAgB,CAC9B,gBAAmC,EACnC,MAAsB,EACtB,kBAA0B,EAC1B,SAAiB;IAEjB,OAAO,mCAAgB,CAAC,OAAO,CAAC,gBAAgB,EAAE,SAAS,EAAE,KAAK,IAAI,EAAE;QACvE,MAAM,IAAI,GAAG,gBAAgB,CAAC,gBAAgB,CAAC,MAAM,EAAE,SAAS,CAAW,CAAC;QAC5E,MAAM,OAAO,GAAG,MAAM,MAAM,CAAC,cAAc,CAAC,IAAI,CAAC,CAAC;QAClD,OAAO,+BAAc,CAAC,aAAa,CAAC,OAAO,CAAC,CAAC;IAC9C,CAAC,CAAC,CAAC;AACJ,CAAC;AAED,KAAK,UAAU,YAAY,CAC1B,gBAAmC,EACnC,MAAsB,EACtB,kBAA0B,EAC1B,SAAiB;IAEjB,OAAO,mCAAgB,CAAC,OAAO,CAAC,gBAAgB,EAAE,SAAS,EAAE,KAAK,IAAI,EAAE;QACvE,MAAM,UAAU,GAAG,gBAAgB,CAAC,gBAAgB,CACnD,YAAY,EACZ,SAAS,EACT,UAAU,CACA,CAAC;QACZ,MAAM,KAAK,GAAG,mCAAgB,CAAC,QAAQ,CAAC,gBAAgB,EAAE,SAAS,CAAC,CAAC;QAErE,MAAM,UAAU,GAAG,MAAM,MAAM,CAAC,UAAU,EAAE,CAAC;QAC7C,OAAO,mCAAgB,CAAC,mBAAmB,CAAC,UAAU,CAAC,SAAS,EAAE,EAAE,KAAK,EAAE,CAAC,QAAQ,EAAE,EAAE,CACvF,+BAAc,CAAC,eAAe,CAAC,QAAQ,EAAE,UAAU,CAAC,CACpD,CAAC;IACH,CAAC,CAAC,CAAC;AACJ,CAAC;AAEY,QAAA,wBAAwB,GAQjC;IACH,CAAC,gBAAgB,CAAC,aAAa,CAAC,EAAE,aAAa;IAC/C,CAAC,gBAAgB,CAAC,gBAAgB,CAAC,EAAE,gBAAgB;IACrD,CAAC,gBAAgB,CAAC,YAAY,CAAC,EAAE,YAAY;CAC7C,CAAC"}
@@ -0,0 +1,11 @@
1
+ import { IExecuteFunctions, INodeExecutionData, INodeType, INodeTypeDescription } from 'n8n-workflow';
2
+ export declare enum SubstackResource {
3
+ Profile = "profile",
4
+ Post = "post",
5
+ Note = "note",
6
+ Comment = "comment"
7
+ }
8
+ export declare class Substack implements INodeType {
9
+ description: INodeTypeDescription;
10
+ execute(this: IExecuteFunctions): Promise<INodeExecutionData[][]>;
11
+ }
@@ -0,0 +1,148 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.Substack = exports.SubstackResource = void 0;
4
+ const n8n_workflow_1 = require("n8n-workflow");
5
+ const Profile_fields_1 = require("./Profile.fields");
6
+ const Profile_operations_1 = require("./Profile.operations");
7
+ const Post_fields_1 = require("./Post.fields");
8
+ const Post_operations_1 = require("./Post.operations");
9
+ const Note_fields_1 = require("./Note.fields");
10
+ const Note_operations_1 = require("./Note.operations");
11
+ const Comment_fields_1 = require("./Comment.fields");
12
+ const Comment_operations_1 = require("./Comment.operations");
13
+ const SubstackUtils_1 = require("./SubstackUtils");
14
+ var SubstackResource;
15
+ (function (SubstackResource) {
16
+ SubstackResource["Profile"] = "profile";
17
+ SubstackResource["Post"] = "post";
18
+ SubstackResource["Note"] = "note";
19
+ SubstackResource["Comment"] = "comment";
20
+ })(SubstackResource || (exports.SubstackResource = SubstackResource = {}));
21
+ const resourceOperationHandlers = {
22
+ [SubstackResource.Profile]: Profile_operations_1.profileOperationHandlers,
23
+ [SubstackResource.Post]: Post_operations_1.postOperationHandlers,
24
+ [SubstackResource.Note]: Note_operations_1.noteOperationHandlers,
25
+ [SubstackResource.Comment]: Comment_operations_1.commentOperationHandlers,
26
+ };
27
+ class Substack {
28
+ constructor() {
29
+ this.description = {
30
+ displayName: 'Substack',
31
+ name: 'substack',
32
+ icon: 'file:substack.svg',
33
+ group: ['output'],
34
+ defaultVersion: 1,
35
+ version: [1],
36
+ subtitle: '={{$parameter["operation"] + ": " + $parameter["resource"]}}',
37
+ description: 'Interact with SubstackGateway API',
38
+ defaults: {
39
+ name: 'Substack',
40
+ },
41
+ inputs: ['main'],
42
+ outputs: ['main'],
43
+ usableAsTool: true,
44
+ credentials: [
45
+ {
46
+ name: 'substackApi',
47
+ required: true,
48
+ },
49
+ ],
50
+ properties: [
51
+ {
52
+ displayName: 'Resource',
53
+ name: 'resource',
54
+ type: 'options',
55
+ default: 'profile',
56
+ noDataExpression: true,
57
+ options: [
58
+ {
59
+ name: 'Comment',
60
+ value: SubstackResource.Comment,
61
+ },
62
+ {
63
+ name: 'Note',
64
+ value: SubstackResource.Note,
65
+ },
66
+ {
67
+ name: 'Post',
68
+ value: SubstackResource.Post,
69
+ },
70
+ {
71
+ name: 'Profile',
72
+ value: SubstackResource.Profile,
73
+ },
74
+ ],
75
+ },
76
+ ...Profile_operations_1.profileOperations,
77
+ ...Profile_fields_1.profileFields,
78
+ ...Post_operations_1.postOperations,
79
+ ...Post_fields_1.postFields,
80
+ ...Note_operations_1.noteOperations,
81
+ ...Note_fields_1.noteFields,
82
+ ...Comment_operations_1.commentOperations,
83
+ ...Comment_fields_1.commentFields,
84
+ ],
85
+ };
86
+ }
87
+ async execute() {
88
+ var _a;
89
+ const items = this.getInputData();
90
+ const returnData = [];
91
+ const { client, publicationAddress } = await SubstackUtils_1.SubstackUtils.initializeClient(this);
92
+ for (let i = 0; i < items.length; i++) {
93
+ try {
94
+ const resource = this.getNodeParameter('resource', i);
95
+ const operation = this.getNodeParameter('operation', i);
96
+ const fallback = () => {
97
+ if (!resourceOperationHandlers[resource]) {
98
+ throw new n8n_workflow_1.NodeOperationError(this.getNode(), `Unknown resource: ${resource}`, {
99
+ itemIndex: i,
100
+ });
101
+ }
102
+ throw new n8n_workflow_1.NodeOperationError(this.getNode(), `Unknown operation: ${operation} for resource: ${resource}`, {
103
+ itemIndex: i,
104
+ });
105
+ };
106
+ const operationHandler = ((_a = resourceOperationHandlers[resource]) === null || _a === void 0 ? void 0 : _a[operation]) || fallback;
107
+ const response = await operationHandler(this, client, publicationAddress, i);
108
+ if (!response.success) {
109
+ if (this.continueOnFail()) {
110
+ returnData.push({
111
+ json: { error: response.error },
112
+ pairedItem: { item: i },
113
+ });
114
+ continue;
115
+ }
116
+ throw new n8n_workflow_1.NodeOperationError(this.getNode(), response.error || 'Unknown error occurred');
117
+ }
118
+ if (Array.isArray(response.data)) {
119
+ response.data.forEach((item) => {
120
+ returnData.push({
121
+ json: item,
122
+ pairedItem: { item: i },
123
+ });
124
+ });
125
+ }
126
+ else {
127
+ returnData.push({
128
+ json: response.data,
129
+ pairedItem: { item: i },
130
+ });
131
+ }
132
+ }
133
+ catch (error) {
134
+ if (this.continueOnFail()) {
135
+ returnData.push({
136
+ json: { error: error.message },
137
+ pairedItem: { item: i },
138
+ });
139
+ continue;
140
+ }
141
+ throw error;
142
+ }
143
+ }
144
+ return [returnData];
145
+ }
146
+ }
147
+ exports.Substack = Substack;
148
+ //# sourceMappingURL=Substack.node.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Substack.node.js","sourceRoot":"","sources":["../../../nodes/SubstackGateway/Substack.node.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,22 @@
1
+ {
2
+ "displayName": "Substack Gateway",
3
+ "name": "substackGateway",
4
+ "icon": "file:substack.svg",
5
+ "group": ["output"],
6
+ "defaultVersion": 1,
7
+ "version": [1],
8
+ "subtitle": "={{$parameter[\"operation\"] + \": \" + $parameter[\"resource\"]}}",
9
+ "description": "Interact with Substack API - Read-only operations for profiles, posts, notes, and comments",
10
+ "defaults": {
11
+ "name": "Substack Gateway"
12
+ },
13
+ "inputs": ["main"],
14
+ "outputs": ["main"],
15
+ "usableAsTool": true,
16
+ "credentials": [
17
+ {
18
+ "name": "substackGatewayApi",
19
+ "required": true
20
+ }
21
+ ]
22
+ }
@@ -0,0 +1,12 @@
1
+ import { IExecuteFunctions } from 'n8n-workflow';
2
+ import { SubstackClient } from './shared/SubstackGatewayClient';
3
+ import { IErrorResponse, IStandardResponse } from './types';
4
+ export declare class SubstackUtils {
5
+ static initializeClient(executeFunctions: IExecuteFunctions): Promise<{
6
+ client: SubstackClient;
7
+ publicationAddress: string;
8
+ }>;
9
+ static formatUrl(publicationAddress: string, path: string): string;
10
+ static formatErrorResponse({ message, node, itemIndex }: IErrorResponse): IStandardResponse;
11
+ private static extractHostname;
12
+ }
@@ -0,0 +1,59 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.SubstackUtils = void 0;
4
+ const n8n_workflow_1 = require("n8n-workflow");
5
+ const SubstackGatewayClient_1 = require("./shared/SubstackGatewayClient");
6
+ class SubstackUtils {
7
+ static async initializeClient(executeFunctions) {
8
+ const credentials = await executeFunctions.getCredentials('substackApi');
9
+ const { publicationAddress, apiKey, gatewayUrl } = credentials;
10
+ if (!apiKey) {
11
+ throw new n8n_workflow_1.NodeOperationError(executeFunctions.getNode(), 'API key is required');
12
+ }
13
+ const hostname = this.extractHostname(publicationAddress, executeFunctions);
14
+ const client = new SubstackGatewayClient_1.SubstackClient({
15
+ publicationUrl: `https://${hostname}`,
16
+ token: apiKey,
17
+ gatewayUrl: gatewayUrl ? gatewayUrl : undefined,
18
+ });
19
+ return {
20
+ client,
21
+ publicationAddress: publicationAddress,
22
+ };
23
+ }
24
+ static formatUrl(publicationAddress, path) {
25
+ const cleanPath = path.startsWith('/') ? path : `/${path}`;
26
+ const cleanAddress = publicationAddress.replace(/\/+$/, '');
27
+ const encodedPath = cleanPath
28
+ .split('/')
29
+ .map((segment) => (segment ? encodeURIComponent(segment) : ''))
30
+ .join('/');
31
+ return `${cleanAddress}${encodedPath}`;
32
+ }
33
+ static formatErrorResponse({ message, node, itemIndex }) {
34
+ return {
35
+ success: false,
36
+ data: null,
37
+ error: message,
38
+ metadata: {
39
+ status: 'error',
40
+ },
41
+ };
42
+ }
43
+ static extractHostname(url, executeFunctions) {
44
+ try {
45
+ const cleanUrl = url.startsWith('http') ? url : `https://${url}`;
46
+ const urlObj = new URL(cleanUrl);
47
+ const hostname = urlObj.hostname;
48
+ if (!hostname.includes('.')) {
49
+ throw new Error('Invalid hostname format');
50
+ }
51
+ return hostname;
52
+ }
53
+ catch (error) {
54
+ throw new n8n_workflow_1.NodeOperationError(executeFunctions.getNode(), `Invalid publication URL provided: ${url}`);
55
+ }
56
+ }
57
+ }
58
+ exports.SubstackUtils = SubstackUtils;
59
+ //# sourceMappingURL=SubstackUtils.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SubstackUtils.js","sourceRoot":"","sources":["../../../nodes/SubstackGateway/SubstackUtils.ts"],"names":[],"mappings":";;;AAAA,+CAAqE;AACrE,0EAAgE;AAGhE,MAAa,aAAa;IACzB,MAAM,CAAC,KAAK,CAAC,gBAAgB,CAAC,gBAAmC;QAChE,MAAM,WAAW,GAAG,MAAM,gBAAgB,CAAC,cAAc,CAAC,aAAa,CAAC,CAAC;QACzE,MAAM,EAAE,kBAAkB,EAAE,MAAM,EAAE,UAAU,EAAE,GAAG,WAAW,CAAC;QAE/D,IAAI,CAAC,MAAM,EAAE,CAAC;YACb,MAAM,IAAI,iCAAkB,CAAC,gBAAgB,CAAC,OAAO,EAAE,EAAE,qBAAqB,CAAC,CAAC;QACjF,CAAC;QAED,MAAM,QAAQ,GAAG,IAAI,CAAC,eAAe,CAAC,kBAA4B,EAAE,gBAAgB,CAAC,CAAC;QAEtF,MAAM,MAAM,GAAG,IAAI,sCAAc,CAAC;YACjC,cAAc,EAAE,WAAW,QAAQ,EAAE;YACrC,KAAK,EAAE,MAAgB;YACvB,UAAU,EAAE,UAAU,CAAC,CAAC,CAAE,UAAqB,CAAC,CAAC,CAAC,SAAS;SAC3D,CAAC,CAAC;QAEH,OAAO;YACN,MAAM;YACN,kBAAkB,EAAE,kBAA4B;SAChD,CAAC;IACH,CAAC;IAED,MAAM,CAAC,SAAS,CAAC,kBAA0B,EAAE,IAAY;QACxD,MAAM,SAAS,GAAG,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,IAAI,EAAE,CAAC;QAC3D,MAAM,YAAY,GAAG,kBAAkB,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;QAG5D,MAAM,WAAW,GAAG,SAAS;aAC3B,KAAK,CAAC,GAAG,CAAC;aACV,GAAG,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,kBAAkB,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;aAC9D,IAAI,CAAC,GAAG,CAAC,CAAC;QAEZ,OAAO,GAAG,YAAY,GAAG,WAAW,EAAE,CAAC;IACxC,CAAC;IAED,MAAM,CAAC,mBAAmB,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,SAAS,EAAkB;QACtE,OAAO;YACN,OAAO,EAAE,KAAK;YACd,IAAI,EAAE,IAAI;YACV,KAAK,EAAE,OAAO;YACd,QAAQ,EAAE;gBACT,MAAM,EAAE,OAAO;aACf;SACD,CAAC;IACH,CAAC;IAKO,MAAM,CAAC,eAAe,CAAC,GAAW,EAAE,gBAAmC;QAC9E,IAAI,CAAC;YAEJ,MAAM,QAAQ,GAAG,GAAG,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,WAAW,GAAG,EAAE,CAAC;YACjE,MAAM,MAAM,GAAG,IAAI,GAAG,CAAC,QAAQ,CAAC,CAAC;YACjC,MAAM,QAAQ,GAAG,MAAM,CAAC,QAAQ,CAAC;YAEjC,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC;gBAC7B,MAAM,IAAI,KAAK,CAAC,yBAAyB,CAAC,CAAC;YAC5C,CAAC;YAED,OAAO,QAAQ,CAAC;QACjB,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YAChB,MAAM,IAAI,iCAAkB,CAC3B,gBAAgB,CAAC,OAAO,EAAE,EAC1B,qCAAqC,GAAG,EAAE,CAC1C,CAAC;QACH,CAAC;IACF,CAAC;CAED;AAtED,sCAsEC"}
@@ -0,0 +1,9 @@
1
+ import { ISubstackNote, ISubstackPost, ISubstackComment, ISubstackFollowing } from '../types';
2
+ export declare class DataFormatters {
3
+ static formatNote(note: any, publicationAddress: string): ISubstackNote;
4
+ static formatPost(post: any, publicationAddress: string): ISubstackPost;
5
+ static formatComment(comment: any, parentPostId?: number): ISubstackComment;
6
+ static formatProfile(profile: any): any;
7
+ static formatFollowing(followee: any, returnType: string): ISubstackFollowing;
8
+ static formatDate(date: any): string;
9
+ }