Skip to content

refactor: extract Function abstraction and split domain/api types#6196

Merged
kaposke merged 3 commits into
masterfrom
gui/2026-05-20/refactor-functions-abstraction
May 22, 2026
Merged

refactor: extract Function abstraction and split domain/api types#6196
kaposke merged 3 commits into
masterfrom
gui/2026-05-20/refactor-functions-abstraction

Conversation

@kaposke

@kaposke kaposke commented May 20, 2026

Copy link
Copy Markdown
Contributor

Been adding a bunch of these functions to deal with the abstract concept of a function (sync_configs and on-event scripts behind the scenes). This is a refactor to clean things up a bit.

  • Move read-side function logic (listFunctions / getFunction) into a dedicated packages/shared/lib/services/functions/ folder split into repository.ts, service.ts, mappers.ts, index.ts — sets up a clear home for the eventual write-side consolidation.
  • Moved NangoFunction types from packages/types/lib/functions/api.ts into domain.ts
  • Renamed NangoXxxFunctionDeployedDeployedNangoXxxFunction — adjective-first reads more naturally and groups deployed variants together.
  • De-duplicate the on-event enum mapping: EVENT_TYPE_MAPPINGS / eventTypeMapper

@kaposke kaposke requested a review from a team May 20, 2026 18:19
@superagent-security superagent-security Bot added contributor:verified Contributor passed trust analysis. pr:verified PR passed security analysis. labels May 20, 2026

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No issues found across 9 files

Confidence score: 5/5

  • Automated review surfaced no issues in the provided summaries.
  • No files require special attention.

Re-trigger cubic

// Today only the read side (`listFunctions` / `getFunction`) lives here, plus shared mappers
// (`EVENT_TYPE_MAPPINGS`, `eventTypeMapper`, `toDeployedNangoFunction`). The eventual roadmap
// is to consolidate write-side operations (deploy, deactivation, conflict detection) here too,
// so callers stop reaching into the underlying tables directly.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what about a functions package? 🙃

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Considered it but felt early / didn't really have enough of a justification yet.

search: string | undefined;
limit: number;
offset: number;
}): Promise<{ rows: DeployedNangoFunction[]; total: number }> {

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should return a Result if it can fail

Comment thread packages/types/lib/functions/domain.ts Outdated
input?: string;
returns: string[];
json_schema: JSONSchema7 | null;
/** Cron expression. */

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is it a cron or some every X mins kind of expression?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah what you said

case 'on-event': {
const apiEvent = row.event ? EVENT_TYPE_MAPPINGS[row.event as DBOnEventScript['event']] : undefined;
if (!apiEvent) {
return undefined;

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

that's silently dropping row if unknown on-event type. Is it on purpose?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It was but I realized this may screw up pagination. Changed to failure (using Result)

last_deployed: Date;
source: FunctionSource;
event: string | null;
}

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would put FunctionRow in repository. It is a db related construct. Mappers are what converts the row into the domain types

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

True, good feedback

@@ -1,49 +1,10 @@
import db from '@nangohq/database';

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have used the naming convention ./models/records.ts or ./models/tasks.ts in other part of the codebase for the logic interacting with the db. Repository isn't a bad name but we should stay consistent imho

])
.first();

return row ?? undefined;

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

?? undefined is redundant I think.

}
throw new Error(`Unknown event type: ${eventType}`);
}
};

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

do EVENT_TYPE_MAPPINGS and eventTypeMapper need to be exported?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nope indeed

return EVENT_TYPE_MAPPINGS[event];
},
toDb: (eventType: OnEventType): DBOnEventScript['event'] => {
for (const [key, value] of Object.entries(EVENT_TYPE_MAPPINGS)) {

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can we do a reverse map instead of a for loop?

@kaposke kaposke added this pull request to the merge queue May 22, 2026
Merged via the queue into master with commit 2941bf0 May 22, 2026
28 checks passed
@kaposke kaposke deleted the gui/2026-05-20/refactor-functions-abstraction branch May 22, 2026 13:24
sapnesh-nango pushed a commit that referenced this pull request May 24, 2026
)

Been adding a bunch of these functions to deal with the abstract concept
of a function (sync_configs and on-event scripts behind the scenes).
This is a refactor to clean things up a bit.

- Move read-side function logic (`listFunctions` / `getFunction`) into a
dedicated `packages/shared/lib/services/functions/` folder split into
`repository.ts`, `service.ts`, `mappers.ts`, `index.ts` — sets up a
clear home for the eventual write-side consolidation.
- Moved `NangoFunction` types from `packages/types/lib/functions/api.ts`
into `domain.ts`
- Renamed `NangoXxxFunctionDeployed` → `DeployedNangoXxxFunction` —
adjective-first reads more naturally and groups deployed variants
together.
- De-duplicate the on-event enum mapping: EVENT_TYPE_MAPPINGS /
eventTypeMapper
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

contributor:verified Contributor passed trust analysis. pr:verified PR passed security analysis.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants