-
Notifications
You must be signed in to change notification settings - Fork 1
feat: add Nango integrations setup for data syncing #144
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,8 @@ | ||
| # Environment files | ||
| .env | ||
|
|
||
| # Nango compiled output | ||
| .nango/ | ||
|
|
||
| # Node modules | ||
| node_modules/ |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,74 @@ | ||
| "use strict"; | ||
| var __create = Object.create; | ||
| var __defProp = Object.defineProperty; | ||
| var __getOwnPropDesc = Object.getOwnPropertyDescriptor; | ||
| var __getOwnPropNames = Object.getOwnPropertyNames; | ||
| var __getProtoOf = Object.getPrototypeOf; | ||
| var __hasOwnProp = Object.prototype.hasOwnProperty; | ||
| var __export = (target, all) => { | ||
| for (var name in all) | ||
| __defProp(target, name, { get: all[name], enumerable: true }); | ||
| }; | ||
| var __copyProps = (to, from, except, desc) => { | ||
| if (from && typeof from === "object" || typeof from === "function") { | ||
| for (let key of __getOwnPropNames(from)) | ||
| if (!__hasOwnProp.call(to, key) && key !== except) | ||
| __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); | ||
| } | ||
| return to; | ||
| }; | ||
| var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps( | ||
| // If the importer is in node compatibility mode or this is not an ESM | ||
| // file that has been converted to a CommonJS file using a Babel- | ||
| // compatible transform (i.e. "__esModule" has not been set), then set | ||
| // "default" to the CommonJS "module.exports" for node compatibility. | ||
| isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target, | ||
| mod | ||
| )); | ||
| var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); | ||
|
|
||
| // nango-integrations/github/actions/createIssue.ts | ||
| var createIssue_exports = {}; | ||
| __export(createIssue_exports, { | ||
| default: () => createIssue_default | ||
| }); | ||
| module.exports = __toCommonJS(createIssue_exports); | ||
| var z = __toESM(require("zod"), 1); | ||
| var issueSchema = z.object({ | ||
| id: z.string(), | ||
| owner: z.string(), | ||
| repo: z.string(), | ||
| issue_number: z.number(), | ||
| title: z.string(), | ||
| state: z.string(), | ||
| author: z.string(), | ||
| author_id: z.number(), | ||
| body: z.string(), | ||
| date_created: z.string(), | ||
| date_last_modified: z.string() | ||
| }); | ||
| var action = { | ||
| type: "action", | ||
| description: `Create an issue in GitHub`, | ||
| version: "1.0.0", | ||
| endpoint: { | ||
| method: "POST", | ||
| path: "/example/github/issues", | ||
| group: "Issues" | ||
| }, | ||
| input: issueSchema, | ||
| output: z.void(), | ||
| // Action execution | ||
| exec: async (nango, input) => { | ||
| await nango.proxy({ | ||
| endpoint: "/repos/NangoHQ/interactive-demo/issues", | ||
| data: { | ||
| title: `[demo] ${input.title}`, | ||
| body: `This issue was created automatically using Nango Action.`, | ||
| labels: ["automatic"] | ||
| } | ||
| }); | ||
| } | ||
| }; | ||
| var createIssue_default = action; | ||
| //# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsibmFuZ28taW50ZWdyYXRpb25zL2dpdGh1Yi9hY3Rpb25zL2NyZWF0ZUlzc3VlLnRzIl0sCiAgInNvdXJjZXNDb250ZW50IjogWyJpbXBvcnQgeyBjcmVhdGVBY3Rpb24gfSBmcm9tICduYW5nbyc7XG5pbXBvcnQgKiBhcyB6IGZyb20gJ3pvZCc7XG5jb25zdCBpc3N1ZVNjaGVtYSA9IHoub2JqZWN0KHtcbiAgaWQ6IHouc3RyaW5nKCksXG4gIG93bmVyOiB6LnN0cmluZygpLFxuICByZXBvOiB6LnN0cmluZygpLFxuICBpc3N1ZV9udW1iZXI6IHoubnVtYmVyKCksXG4gIHRpdGxlOiB6LnN0cmluZygpLFxuICBzdGF0ZTogei5zdHJpbmcoKSxcbiAgYXV0aG9yOiB6LnN0cmluZygpLFxuICBhdXRob3JfaWQ6IHoubnVtYmVyKCksXG4gIGJvZHk6IHouc3RyaW5nKCksXG4gIGRhdGVfY3JlYXRlZDogei5zdHJpbmcoKSxcbiAgZGF0ZV9sYXN0X21vZGlmaWVkOiB6LnN0cmluZygpXG59KTtcbmNvbnN0IGFjdGlvbiA9IHtcbiAgdHlwZTogXCJhY3Rpb25cIixcbiAgZGVzY3JpcHRpb246IGBDcmVhdGUgYW4gaXNzdWUgaW4gR2l0SHViYCxcbiAgdmVyc2lvbjogJzEuMC4wJyxcbiAgZW5kcG9pbnQ6IHtcbiAgICBtZXRob2Q6ICdQT1NUJyxcbiAgICBwYXRoOiAnL2V4YW1wbGUvZ2l0aHViL2lzc3VlcycsXG4gICAgZ3JvdXA6ICdJc3N1ZXMnXG4gIH0sXG4gIGlucHV0OiBpc3N1ZVNjaGVtYSxcbiAgb3V0cHV0OiB6LnZvaWQoKSxcbiAgLy8gQWN0aW9uIGV4ZWN1dGlvblxuICBleGVjOiBhc3luYyAobmFuZ28sIGlucHV0KSA9PiB7XG4gICAgYXdhaXQgbmFuZ28ucHJveHkoe1xuICAgICAgZW5kcG9pbnQ6ICcvcmVwb3MvTmFuZ29IUS9pbnRlcmFjdGl2ZS1kZW1vL2lzc3VlcycsXG4gICAgICBkYXRhOiB7XG4gICAgICAgIHRpdGxlOiBgW2RlbW9dICR7aW5wdXQudGl0bGV9YCxcbiAgICAgICAgYm9keTogYFRoaXMgaXNzdWUgd2FzIGNyZWF0ZWQgYXV0b21hdGljYWxseSB1c2luZyBOYW5nbyBBY3Rpb24uYCxcbiAgICAgICAgbGFiZWxzOiBbJ2F1dG9tYXRpYyddXG4gICAgICB9XG4gICAgfSk7XG4gIH1cbn07XG5leHBvcnQgdHlwZSBOYW5nb0FjdGlvbkxvY2FsID0gUGFyYW1ldGVyczwodHlwZW9mIGFjdGlvbilbJ2V4ZWMnXT5bMF07XG5leHBvcnQgZGVmYXVsdCBhY3Rpb247Il0sCiAgIm1hcHBpbmdzIjogIjs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUNBLFFBQW1CO0FBQ25CLElBQU0sY0FBZ0IsU0FBTztBQUFBLEVBQzNCLElBQU0sU0FBTztBQUFBLEVBQ2IsT0FBUyxTQUFPO0FBQUEsRUFDaEIsTUFBUSxTQUFPO0FBQUEsRUFDZixjQUFnQixTQUFPO0FBQUEsRUFDdkIsT0FBUyxTQUFPO0FBQUEsRUFDaEIsT0FBUyxTQUFPO0FBQUEsRUFDaEIsUUFBVSxTQUFPO0FBQUEsRUFDakIsV0FBYSxTQUFPO0FBQUEsRUFDcEIsTUFBUSxTQUFPO0FBQUEsRUFDZixjQUFnQixTQUFPO0FBQUEsRUFDdkIsb0JBQXNCLFNBQU87QUFDL0IsQ0FBQztBQUNELElBQU0sU0FBUztBQUFBLEVBQ2IsTUFBTTtBQUFBLEVBQ04sYUFBYTtBQUFBLEVBQ2IsU0FBUztBQUFBLEVBQ1QsVUFBVTtBQUFBLElBQ1IsUUFBUTtBQUFBLElBQ1IsTUFBTTtBQUFBLElBQ04sT0FBTztBQUFBLEVBQ1Q7QUFBQSxFQUNBLE9BQU87QUFBQSxFQUNQLFFBQVUsT0FBSztBQUFBO0FBQUEsRUFFZixNQUFNLE9BQU8sT0FBTyxVQUFVO0FBQzVCLFVBQU0sTUFBTSxNQUFNO0FBQUEsTUFDaEIsVUFBVTtBQUFBLE1BQ1YsTUFBTTtBQUFBLFFBQ0osT0FBTyxVQUFVLE1BQU0sS0FBSztBQUFBLFFBQzVCLE1BQU07QUFBQSxRQUNOLFFBQVEsQ0FBQyxXQUFXO0FBQUEsTUFDdEI7QUFBQSxJQUNGLENBQUM7QUFBQSxFQUNIO0FBQ0Y7QUFFQSxJQUFPLHNCQUFROyIsCiAgIm5hbWVzIjogW10KfQo= |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,41 @@ | ||
| "use strict"; | ||
| var __defProp = Object.defineProperty; | ||
| var __getOwnPropDesc = Object.getOwnPropertyDescriptor; | ||
| var __getOwnPropNames = Object.getOwnPropertyNames; | ||
| var __hasOwnProp = Object.prototype.hasOwnProperty; | ||
| var __export = (target, all) => { | ||
| for (var name in all) | ||
| __defProp(target, name, { get: all[name], enumerable: true }); | ||
| }; | ||
| var __copyProps = (to, from, except, desc) => { | ||
| if (from && typeof from === "object" || typeof from === "function") { | ||
| for (let key of __getOwnPropNames(from)) | ||
| if (!__hasOwnProp.call(to, key) && key !== except) | ||
| __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); | ||
| } | ||
| return to; | ||
| }; | ||
| var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); | ||
|
|
||
| // nango-integrations/github/on-events/pre-connection-deletion.ts | ||
| var pre_connection_deletion_exports = {}; | ||
| __export(pre_connection_deletion_exports, { | ||
| default: () => pre_connection_deletion_default, | ||
| onEvent: () => onEvent | ||
| }); | ||
| module.exports = __toCommonJS(pre_connection_deletion_exports); | ||
| var onEvent = { | ||
| type: "onEvent", | ||
| event: "pre-connection-deletion", | ||
| // 'post-connection-creation' | 'validate-connection' | ||
| description: "This script is executed before a connection is deleted", | ||
| exec: async (nango) => { | ||
| await nango.log("Executed"); | ||
| } | ||
| }; | ||
| var pre_connection_deletion_default = onEvent; | ||
| // Annotate the CommonJS export names for ESM import in node: | ||
| 0 && (module.exports = { | ||
| onEvent | ||
| }); | ||
| //# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsibmFuZ28taW50ZWdyYXRpb25zL2dpdGh1Yi9vbi1ldmVudHMvcHJlLWNvbm5lY3Rpb24tZGVsZXRpb24udHMiXSwKICAic291cmNlc0NvbnRlbnQiOiBbImltcG9ydCB7IGNyZWF0ZU9uRXZlbnQgfSBmcm9tICduYW5nbyc7XG5leHBvcnQgY29uc3Qgb25FdmVudCA9IHtcbiAgdHlwZTogXCJvbkV2ZW50XCIsXG4gIGV2ZW50OiAncHJlLWNvbm5lY3Rpb24tZGVsZXRpb24nLFxuICAvLyAncG9zdC1jb25uZWN0aW9uLWNyZWF0aW9uJyB8ICd2YWxpZGF0ZS1jb25uZWN0aW9uJ1xuICBkZXNjcmlwdGlvbjogJ1RoaXMgc2NyaXB0IGlzIGV4ZWN1dGVkIGJlZm9yZSBhIGNvbm5lY3Rpb24gaXMgZGVsZXRlZCcsXG4gIGV4ZWM6IGFzeW5jIG5hbmdvID0+IHtcbiAgICBhd2FpdCBuYW5nby5sb2coJ0V4ZWN1dGVkJyk7XG4gIH1cbn07XG5leHBvcnQgZGVmYXVsdCBvbkV2ZW50OyJdLAogICJtYXBwaW5ncyI6ICI7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQ08sSUFBTSxVQUFVO0FBQUEsRUFDckIsTUFBTTtBQUFBLEVBQ04sT0FBTztBQUFBO0FBQUEsRUFFUCxhQUFhO0FBQUEsRUFDYixNQUFNLE9BQU0sVUFBUztBQUNuQixVQUFNLE1BQU0sSUFBSSxVQUFVO0FBQUEsRUFDNUI7QUFDRjtBQUNBLElBQU8sa0NBQVE7IiwKICAibmFtZXMiOiBbXQp9Cg== | ||
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,119 @@ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| "use strict"; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| var __create = Object.create; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| var __defProp = Object.defineProperty; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| var __getOwnPropDesc = Object.getOwnPropertyDescriptor; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| var __getOwnPropNames = Object.getOwnPropertyNames; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| var __getProtoOf = Object.getPrototypeOf; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| var __hasOwnProp = Object.prototype.hasOwnProperty; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| var __export = (target, all) => { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| for (var name in all) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| __defProp(target, name, { get: all[name], enumerable: true }); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| }; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| var __copyProps = (to, from, except, desc) => { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if (from && typeof from === "object" || typeof from === "function") { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| for (let key of __getOwnPropNames(from)) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if (!__hasOwnProp.call(to, key) && key !== except) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return to; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| }; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // If the importer is in node compatibility mode or this is not an ESM | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // file that has been converted to a CommonJS file using a Babel- | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // compatible transform (i.e. "__esModule" has not been set), then set | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // "default" to the CommonJS "module.exports" for node compatibility. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| mod | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| )); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // nango-integrations/github/syncs/fetchIssues.ts | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| var fetchIssues_exports = {}; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| __export(fetchIssues_exports, { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| default: () => fetchIssues_default | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| }); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| module.exports = __toCommonJS(fetchIssues_exports); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| var z = __toESM(require("zod"), 1); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| var LIMIT = 100; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| var issueSchema = z.object({ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| id: z.string(), | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| owner: z.string(), | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| repo: z.string(), | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| issue_number: z.number(), | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| title: z.string(), | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| state: z.string(), | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| author: z.string(), | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| author_id: z.number(), | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| body: z.string(), | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| date_created: z.string(), | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| date_last_modified: z.string() | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| }); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+38
to
+50
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🧩 Analysis chain🏁 Script executed: # Find the source TypeScript file
find . -name "fetchIssues.ts" -type fRepository: drifter089/orgOS Length of output: 108 🌐 Web query:
💡 Result: Common causes
Sources 🏁 Script executed: cat -n ./nango-integrations/github/syncs/fetchIssues.tsRepository: drifter089/orgOS Length of output: 3295 Fix nullable body field in schema. The - body: z.string(),
+ body: z.string().nullable(),📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||||||||||||||||||||||||||||||||||||||||||||||||||
| var sync = { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| type: "sync", | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| description: `Fetches the Github issues from all a user's repositories.`, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| version: "1.0.0", | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| endpoints: [{ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| method: "GET", | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| path: "/example/github/issues", | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| group: "Issues" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| }], | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| frequency: "every hour", | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| autoStart: true, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| syncType: "full", | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| metadata: z.void(), | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| models: { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| GithubIssue: issueSchema | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| }, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // Sync execution | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| exec: async (nango) => { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const repos = await getAllRepositories(nango); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| for (const repo of repos) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const proxyConfig = { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| endpoint: `/repos/${repo.owner.login}/${repo.name}/issues`, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| paginate: { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| limit: LIMIT | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| }; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| for await (const issueBatch of nango.paginate(proxyConfig)) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const issues = issueBatch.filter((issue) => !("pull_request" in issue)); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const mappedIssues = issues.map((issue) => ({ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| id: issue.id, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| owner: repo.owner.login, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| repo: repo.name, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| issue_number: issue.number, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| title: issue.title, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| state: issue.state, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| author: issue.user.login, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| author_id: issue.user.id, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| body: issue.body, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| date_created: issue.created_at, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| date_last_modified: issue.updated_at | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| })); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if (mappedIssues.length > 0) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| await nango.batchSave(mappedIssues, "GithubIssue"); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| await nango.log(`Sent ${mappedIssues.length} issues from ${repo.owner.login}/${repo.name}`); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+68
to
+97
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Add error handling for individual repository failures. The sync iterates through all repositories without try-catch blocks. If fetching issues from one repository fails (e.g., due to permissions or API errors), the entire sync will fail and subsequent repositories won't be processed. Consider wrapping the per-repository logic in try-catch in the source TypeScript file: for (const repo of repos) {
try {
const proxyConfig = { /* ... */ };
for await (const issueBatch of nango.paginate(proxyConfig)) {
// ... existing logic
}
} catch (error) {
await nango.log(`Failed to fetch issues from ${repo.owner.login}/${repo.name}: ${error}`);
// Continue with next repository
}
}🤖 Prompt for AI Agents |
||||||||||||||||||||||||||||||||||||||||||||||||||||||
| await nango.deleteRecordsFromPreviousExecutions("GithubIssue"); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| }, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // Webhook handler | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| onWebhook: async (nango, payload) => { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| await nango.log("This is a webhook script", payload); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| }; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| var fetchIssues_default = sync; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| async function getAllRepositories(nango) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const records = []; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const proxyConfig = { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| endpoint: "/user/repos", | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| paginate: { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| limit: LIMIT | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| }; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| for await (const recordBatch of nango.paginate(proxyConfig)) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| records.push(...recordBatch); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return records; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| //# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsibmFuZ28taW50ZWdyYXRpb25zL2dpdGh1Yi9zeW5jcy9mZXRjaElzc3Vlcy50cyJdLAogICJzb3VyY2VzQ29udGVudCI6IFsiaW1wb3J0IHsgY3JlYXRlU3luYyB9IGZyb20gJ25hbmdvJztcbmltcG9ydCAqIGFzIHogZnJvbSAnem9kJztcbmNvbnN0IExJTUlUID0gMTAwO1xuY29uc3QgaXNzdWVTY2hlbWEgPSB6Lm9iamVjdCh7XG4gIGlkOiB6LnN0cmluZygpLFxuICBvd25lcjogei5zdHJpbmcoKSxcbiAgcmVwbzogei5zdHJpbmcoKSxcbiAgaXNzdWVfbnVtYmVyOiB6Lm51bWJlcigpLFxuICB0aXRsZTogei5zdHJpbmcoKSxcbiAgc3RhdGU6IHouc3RyaW5nKCksXG4gIGF1dGhvcjogei5zdHJpbmcoKSxcbiAgYXV0aG9yX2lkOiB6Lm51bWJlcigpLFxuICBib2R5OiB6LnN0cmluZygpLFxuICBkYXRlX2NyZWF0ZWQ6IHouc3RyaW5nKCksXG4gIGRhdGVfbGFzdF9tb2RpZmllZDogei5zdHJpbmcoKVxufSk7XG50eXBlIEdpdGh1Yklzc3VlID0gei5pbmZlcjx0eXBlb2YgaXNzdWVTY2hlbWE+O1xuY29uc3Qgc3luYyA9IHtcbiAgdHlwZTogXCJzeW5jXCIsXG4gIGRlc2NyaXB0aW9uOiBgRmV0Y2hlcyB0aGUgR2l0aHViIGlzc3VlcyBmcm9tIGFsbCBhIHVzZXIncyByZXBvc2l0b3JpZXMuYCxcbiAgdmVyc2lvbjogJzEuMC4wJyxcbiAgZW5kcG9pbnRzOiBbe1xuICAgIG1ldGhvZDogJ0dFVCcsXG4gICAgcGF0aDogJy9leGFtcGxlL2dpdGh1Yi9pc3N1ZXMnLFxuICAgIGdyb3VwOiAnSXNzdWVzJ1xuICB9XSxcbiAgZnJlcXVlbmN5OiAnZXZlcnkgaG91cicsXG4gIGF1dG9TdGFydDogdHJ1ZSxcbiAgc3luY1R5cGU6ICdmdWxsJyxcbiAgbWV0YWRhdGE6IHoudm9pZCgpLFxuICBtb2RlbHM6IHtcbiAgICBHaXRodWJJc3N1ZTogaXNzdWVTY2hlbWFcbiAgfSxcbiAgLy8gU3luYyBleGVjdXRpb25cbiAgZXhlYzogYXN5bmMgbmFuZ28gPT4ge1xuICAgIGNvbnN0IHJlcG9zID0gYXdhaXQgZ2V0QWxsUmVwb3NpdG9yaWVzKG5hbmdvKTtcbiAgICBmb3IgKGNvbnN0IHJlcG8gb2YgcmVwb3MpIHtcbiAgICAgIGNvbnN0IHByb3h5Q29uZmlnID0ge1xuICAgICAgICBlbmRwb2ludDogYC9yZXBvcy8ke3JlcG8ub3duZXIubG9naW59LyR7cmVwby5uYW1lfS9pc3N1ZXNgLFxuICAgICAgICBwYWdpbmF0ZToge1xuICAgICAgICAgIGxpbWl0OiBMSU1JVFxuICAgICAgICB9XG4gICAgICB9O1xuICAgICAgZm9yIGF3YWl0IChjb25zdCBpc3N1ZUJhdGNoIG9mIG5hbmdvLnBhZ2luYXRlKHByb3h5Q29uZmlnKSkge1xuICAgICAgICBjb25zdCBpc3N1ZXMgPSBpc3N1ZUJhdGNoLmZpbHRlcihpc3N1ZSA9PiAhKCdwdWxsX3JlcXVlc3QnIGluIGlzc3VlKSk7XG4gICAgICAgIGNvbnN0IG1hcHBlZElzc3VlczogR2l0aHViSXNzdWVbXSA9IGlzc3Vlcy5tYXAoaXNzdWUgPT4gKHtcbiAgICAgICAgICBpZDogaXNzdWUuaWQsXG4gICAgICAgICAgb3duZXI6IHJlcG8ub3duZXIubG9naW4sXG4gICAgICAgICAgcmVwbzogcmVwby5uYW1lLFxuICAgICAgICAgIGlzc3VlX251bWJlcjogaXNzdWUubnVtYmVyLFxuICAgICAgICAgIHRpdGxlOiBpc3N1ZS50aXRsZSxcbiAgICAgICAgICBzdGF0ZTogaXNzdWUuc3RhdGUsXG4gICAgICAgICAgYXV0aG9yOiBpc3N1ZS51c2VyLmxvZ2luLFxuICAgICAgICAgIGF1dGhvcl9pZDogaXNzdWUudXNlci5pZCxcbiAgICAgICAgICBib2R5OiBpc3N1ZS5ib2R5LFxuICAgICAgICAgIGRhdGVfY3JlYXRlZDogaXNzdWUuY3JlYXRlZF9hdCxcbiAgICAgICAgICBkYXRlX2xhc3RfbW9kaWZpZWQ6IGlzc3VlLnVwZGF0ZWRfYXRcbiAgICAgICAgfSkpO1xuICAgICAgICBpZiAobWFwcGVkSXNzdWVzLmxlbmd0aCA+IDApIHtcbiAgICAgICAgICBhd2FpdCBuYW5nby5iYXRjaFNhdmUobWFwcGVkSXNzdWVzLCAnR2l0aHViSXNzdWUnKTtcbiAgICAgICAgICBhd2FpdCBuYW5nby5sb2coYFNlbnQgJHttYXBwZWRJc3N1ZXMubGVuZ3RofSBpc3N1ZXMgZnJvbSAke3JlcG8ub3duZXIubG9naW59LyR7cmVwby5uYW1lfWApO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICAgIGF3YWl0IG5hbmdvLmRlbGV0ZVJlY29yZHNGcm9tUHJldmlvdXNFeGVjdXRpb25zKCdHaXRodWJJc3N1ZScpO1xuICB9LFxuICAvLyBXZWJob29rIGhhbmRsZXJcbiAgb25XZWJob29rOiBhc3luYyAobmFuZ28sIHBheWxvYWQpID0+IHtcbiAgICBhd2FpdCBuYW5nby5sb2coJ1RoaXMgaXMgYSB3ZWJob29rIHNjcmlwdCcsIHBheWxvYWQpO1xuICB9XG59O1xuZXhwb3J0IHR5cGUgTmFuZ29TeW5jTG9jYWwgPSBQYXJhbWV0ZXJzPCh0eXBlb2Ygc3luYylbJ2V4ZWMnXT5bMF07XG5leHBvcnQgZGVmYXVsdCBzeW5jO1xuYXN5bmMgZnVuY3Rpb24gZ2V0QWxsUmVwb3NpdG9yaWVzKG5hbmdvOiBOYW5nb1N5bmNMb2NhbCk6IFByb21pc2U8YW55W10+IHtcbiAgY29uc3QgcmVjb3JkczogYW55W10gPSBbXTtcbiAgY29uc3QgcHJveHlDb25maWcgPSB7XG4gICAgZW5kcG9pbnQ6ICcvdXNlci9yZXBvcycsXG4gICAgcGFnaW5hdGU6IHtcbiAgICAgIGxpbWl0OiBMSU1JVFxuICAgIH1cbiAgfTtcbiAgZm9yIGF3YWl0IChjb25zdCByZWNvcmRCYXRjaCBvZiBuYW5nby5wYWdpbmF0ZShwcm94eUNvbmZpZykpIHtcbiAgICByZWNvcmRzLnB1c2goLi4ucmVjb3JkQmF0Y2gpO1xuICB9XG4gIHJldHVybiByZWNvcmRzO1xufSJd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 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,39 @@ | ||
| import { createAction } from "nango"; | ||
| import * as z from "zod"; | ||
|
|
||
| const issueSchema = z.object({ | ||
| id: z.string(), | ||
| owner: z.string(), | ||
| repo: z.string(), | ||
| issue_number: z.number(), | ||
| title: z.string(), | ||
| state: z.string(), | ||
| author: z.string(), | ||
| author_id: z.number(), | ||
| body: z.string(), | ||
| date_created: z.string(), | ||
| date_last_modified: z.string(), | ||
| }); | ||
|
|
||
| const action = createAction({ | ||
| description: `Create an issue in GitHub`, | ||
| version: "1.0.0", | ||
| endpoint: { method: "POST", path: "/example/github/issues", group: "Issues" }, | ||
| input: issueSchema, | ||
| output: z.void(), | ||
|
|
||
| // Action execution | ||
| exec: async (nango, input) => { | ||
| await nango.proxy({ | ||
| endpoint: "/repos/NangoHQ/interactive-demo/issues", | ||
| data: { | ||
| title: `[demo] ${input.title}`, | ||
| body: `This issue was created automatically using Nango Action.`, | ||
| labels: ["automatic"], | ||
| }, | ||
| }); | ||
| }, | ||
| }); | ||
|
|
||
| export type NangoActionLocal = Parameters<(typeof action)["exec"]>[0]; | ||
| export default action; |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,9 @@ | ||
| import { createOnEvent } from "nango"; | ||
|
|
||
| export default createOnEvent({ | ||
| event: "pre-connection-deletion", // 'post-connection-creation' | 'validate-connection' | ||
| description: "This script is executed before a connection is deleted", | ||
| exec: async (nango) => { | ||
| await nango.log("Executed"); | ||
| }, | ||
| }); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🧩 Analysis chain
🌐 Web query:
Nango integration framework build artifacts deployment requirements💡 Result:
Summary of key build-artifact / deployment requirements for Nango integrations:
Sources: Nango CLI & env docs; Functions/setup and deploy guides; Sample app deployment; Self-hosting (docker compose); note on NANGO_ENCRYPTION_KEY. [1][2][3][4][5]
🏁 Script executed:
Repository: drifter089/orgOS
Length of output: 465
🏁 Script executed:
Repository: drifter089/orgOS
Length of output: 151
🏁 Script executed:
Repository: drifter089/orgOS
Length of output: 42
🏁 Script executed:
Repository: drifter089/orgOS
Length of output: 620
🏁 Script executed:
Repository: drifter089/orgOS
Length of output: 423
🏁 Script executed:
Repository: drifter089/orgOS
Length of output: 342
🏁 Script executed:
Repository: drifter089/orgOS
Length of output: 874
🏁 Script executed:
Repository: drifter089/orgOS
Length of output: 42
🏁 Script executed:
# Verify the nango-integrations/.gitignore specifically cat nango-integrations/.gitignoreRepository: drifter089/orgOS
Length of output: 147
🏁 Script executed:
Repository: drifter089/orgOS
Length of output: 182
🏁 Script executed:
Repository: drifter089/orgOS
Length of output: 218
🏁 Script executed:
Repository: drifter089/orgOS
Length of output: 127
🏁 Script executed:
# Verify the compilation flow - does nango compile generate these files? cat nango-integrations/tsconfig.jsonRepository: drifter089/orgOS
Length of output: 986
Remove committed build artifacts from the nango-integrations/build directory.
The compiled
.cjsfiles innango-integrations/build/are build artifacts generated bynango compilefrom TypeScript sources. Nango's owntsconfig.jsonexplicitly excludes thebuilddirectory, indicating these files should not be in version control. They are regenerated during deployment vianango deploy. Remove all.cjsfiles fromnango-integrations/build/and addbuild/tonango-integrations/.gitignore. Keep only the source.tsfiles innango-integrations/github/.🤖 Prompt for AI Agents