@nangohq/runner-sdk 0.70.8 → 0.71.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.
@@ -1,19 +1,2 @@
1
- /**
2
- * Denylist helpers for runner-sdk sandbox code.
3
- *
4
- * Keep aligned with `packages/utils/lib/proxy/baseUrlOverrideDenylist.ts` (canonical for services).
5
- * runner-sdk cannot depend on other `@nangohq/*` packages, so this module is duplicated in-package.
6
- */
7
- export declare const DEFAULT_NANGO_PROXY_BASE_URL_OVERRIDE_DENYLIST: readonly ["169.254.169.254", "metadata.google.internal", "localhost", "127.0.0.1", "[::1]", "[::ffff:127.0.0.1]", "[::ffff:169.254.169.254]"];
8
- export declare function canonicalizeHostnameForDenylist(host: string): string;
9
- export declare function normalizeDenylistHost(entry: string): string;
10
- export declare function normalizeDenylist(denylist: string[] | undefined): Set<string>;
11
- export declare function isBaseUrlOverrideDenied(overrideUrl: string, denylist: Set<string>): boolean;
12
- export declare function mergeProxyBaseUrlOverrideDenylist(customEntries: string[]): string[];
13
- /**
14
- * Runner-side denylist resolution. Unlike server env parsing, runners always apply secure defaults
15
- * when the env is unset or empty (`[]` / `''`) so a server-level opt-out is not inherited.
16
- */
17
- export declare function resolveProxyBaseUrlOverrideDenylist(raw: string | undefined): string[];
1
+ export { DEFAULT_NANGO_PROXY_BASE_URL_OVERRIDE_DENYLIST, canonicalizeHostnameForDenylist, isBaseUrlOverrideDenied, mergeProxyBaseUrlOverrideDenylist, normalizeDenylist, normalizeDenylistHost, resolveProxyBaseUrlOverrideDenylistForRunner as resolveProxyBaseUrlOverrideDenylist } from '@nangohq/egress';
18
2
  export declare function isBaseUrlOverridePolicyEnabledFromEnv(): boolean;
19
- export declare function getBaseUrlOverrideDenylistFromEnv(): Set<string>;
@@ -1,76 +1,5 @@
1
- /**
2
- * Denylist helpers for runner-sdk sandbox code.
3
- *
4
- * Keep aligned with `packages/utils/lib/proxy/baseUrlOverrideDenylist.ts` (canonical for services).
5
- * runner-sdk cannot depend on other `@nangohq/*` packages, so this module is duplicated in-package.
6
- */
7
- export const DEFAULT_NANGO_PROXY_BASE_URL_OVERRIDE_DENYLIST = [
8
- '169.254.169.254',
9
- 'metadata.google.internal',
10
- 'localhost',
11
- '127.0.0.1',
12
- '[::1]',
13
- '[::ffff:127.0.0.1]',
14
- '[::ffff:169.254.169.254]'
15
- ];
16
- export function canonicalizeHostnameForDenylist(host) {
17
- let h = host.trim().toLowerCase();
18
- if (h.startsWith('[') && h.endsWith(']')) {
19
- h = h.slice(1, -1);
20
- }
21
- while (h.endsWith('.')) {
22
- h = h.slice(0, -1);
23
- }
24
- return h;
25
- }
26
- export function normalizeDenylistHost(entry) {
27
- const trimmed = entry.trim();
28
- if (!trimmed) {
29
- return '';
30
- }
31
- let host;
32
- if (trimmed.includes('://')) {
33
- try {
34
- host = new URL(trimmed).hostname;
35
- }
36
- catch {
37
- host = trimmed;
38
- }
39
- }
40
- else {
41
- try {
42
- host = new URL(`http://${trimmed}`).hostname;
43
- }
44
- catch {
45
- host = trimmed;
46
- }
47
- }
48
- return canonicalizeHostnameForDenylist(host);
49
- }
50
- export function normalizeDenylist(denylist) {
51
- if (!denylist?.length) {
52
- return new Set();
53
- }
54
- return new Set(denylist.map(normalizeDenylistHost).filter(Boolean));
55
- }
56
- export function isBaseUrlOverrideDenied(overrideUrl, denylist) {
57
- if (denylist.size === 0) {
58
- return false;
59
- }
60
- let hostname;
61
- try {
62
- hostname = canonicalizeHostnameForDenylist(new URL(overrideUrl).hostname);
63
- }
64
- catch {
65
- return true;
66
- }
67
- return denylist.has(hostname);
68
- }
69
- export function mergeProxyBaseUrlOverrideDenylist(customEntries) {
70
- const merged = [...DEFAULT_NANGO_PROXY_BASE_URL_OVERRIDE_DENYLIST, ...customEntries];
71
- return [...new Set(merged)];
72
- }
73
- function isBaseUrlOverrideEnabledFromEnv() {
1
+ export { DEFAULT_NANGO_PROXY_BASE_URL_OVERRIDE_DENYLIST, canonicalizeHostnameForDenylist, isBaseUrlOverrideDenied, mergeProxyBaseUrlOverrideDenylist, normalizeDenylist, normalizeDenylistHost, resolveProxyBaseUrlOverrideDenylistForRunner as resolveProxyBaseUrlOverrideDenylist } from '@nangohq/egress';
2
+ export function isBaseUrlOverridePolicyEnabledFromEnv() {
74
3
  const raw = typeof process !== 'undefined' ? process.env['NANGO_PROXY_BASE_URL_OVERRIDE_ENABLED'] : undefined;
75
4
  if (raw === undefined) {
76
5
  return true;
@@ -78,55 +7,4 @@ function isBaseUrlOverrideEnabledFromEnv() {
78
7
  const normalized = raw.trim().toLowerCase();
79
8
  return normalized !== 'false' && normalized !== '0';
80
9
  }
81
- /**
82
- * Runner-side denylist resolution. Unlike server env parsing, runners always apply secure defaults
83
- * when the env is unset or empty (`[]` / `''`) so a server-level opt-out is not inherited.
84
- */
85
- export function resolveProxyBaseUrlOverrideDenylist(raw) {
86
- if (raw === undefined) {
87
- return [...DEFAULT_NANGO_PROXY_BASE_URL_OVERRIDE_DENYLIST];
88
- }
89
- const trimmed = raw.trim();
90
- if (trimmed === '') {
91
- return [...DEFAULT_NANGO_PROXY_BASE_URL_OVERRIDE_DENYLIST];
92
- }
93
- try {
94
- const parsed = JSON.parse(trimmed);
95
- if (!Array.isArray(parsed)) {
96
- return [...DEFAULT_NANGO_PROXY_BASE_URL_OVERRIDE_DENYLIST];
97
- }
98
- if (parsed.length === 0) {
99
- return [...DEFAULT_NANGO_PROXY_BASE_URL_OVERRIDE_DENYLIST];
100
- }
101
- const customEntries = parsed
102
- .filter((v) => typeof v === 'string')
103
- .map((v) => v.trim())
104
- .filter(Boolean);
105
- return mergeProxyBaseUrlOverrideDenylist(customEntries);
106
- }
107
- catch {
108
- return [...DEFAULT_NANGO_PROXY_BASE_URL_OVERRIDE_DENYLIST];
109
- }
110
- }
111
- let memoizedBaseUrlOverrideDenylist = null;
112
- export function isBaseUrlOverridePolicyEnabledFromEnv() {
113
- return isBaseUrlOverrideEnabledFromEnv();
114
- }
115
- export function getBaseUrlOverrideDenylistFromEnv() {
116
- if (memoizedBaseUrlOverrideDenylist) {
117
- return memoizedBaseUrlOverrideDenylist;
118
- }
119
- const raw = typeof process !== 'undefined' ? process.env['NANGO_PROXY_BASE_URL_OVERRIDE_DENYLIST'] : undefined;
120
- const entries = isBaseUrlOverrideEnabledFromEnv() ? resolveProxyBaseUrlOverrideDenylist(raw) : [...DEFAULT_NANGO_PROXY_BASE_URL_OVERRIDE_DENYLIST];
121
- const denylist = normalizeDenylist(entries);
122
- const lambdaRuntimeApi = typeof process !== 'undefined' ? process.env['AWS_LAMBDA_RUNTIME_API'] : undefined;
123
- if (lambdaRuntimeApi) {
124
- const normalized = normalizeDenylistHost(lambdaRuntimeApi);
125
- if (normalized) {
126
- denylist.add(normalized);
127
- }
128
- }
129
- memoizedBaseUrlOverrideDenylist = denylist;
130
- return memoizedBaseUrlOverrideDenylist;
131
- }
132
10
  //# sourceMappingURL=baseUrlOverrideDenylist.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"baseUrlOverrideDenylist.js","sourceRoot":"","sources":["../lib/baseUrlOverrideDenylist.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"baseUrlOverrideDenylist.js","sourceRoot":"","sources":["../lib/baseUrlOverrideDenylist.ts"],"names":[],"mappings":"AAAA,OAAO,EACH,8CAA8C,EAC9C,+BAA+B,EAC/B,uBAAuB,EACvB,iCAAiC,EACjC,iBAAiB,EACjB,qBAAqB,EACrB,4CAA4C,IAAI,mCAAmC,EACtF,MAAM,iBAAiB,CAAC;AAEzB,MAAM,UAAU,qCAAqC;IACjD,MAAM,GAAG,GAAG,OAAO,OAAO,KAAK,WAAW,CAAC,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,uCAAuC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;IAC9G,IAAI,GAAG,KAAK,SAAS,EAAE,CAAC;QACpB,OAAO,IAAI,CAAC;IAChB,CAAC;IACD,MAAM,UAAU,GAAG,GAAG,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;IAC5C,OAAO,UAAU,KAAK,OAAO,IAAI,UAAU,KAAK,GAAG,CAAC;AACxD,CAAC"}
@@ -0,0 +1,259 @@
1
+ import type { ProxyConfiguration } from './action.js';
2
+ import type { ZodCheckpoint, ZodMetadata, ZodModel } from './types.js';
3
+ import type { UncontrolledFetchOptions } from './uncontrolledFetch.js';
4
+ import type { AllAuthCredentials, EnvironmentVariable, FunctionCapabilities, GetPublicConnection, GetPublicIntegration, HTTP_METHOD, MaybePromise, MergingStrategy, OnEventType, SdkLogger } from '@nangohq/types';
5
+ import type * as z from 'zod';
6
+ type InferZod<T> = T extends z.ZodTypeAny ? z.infer<T> : never;
7
+ export type ConcurrencyLimit = 1 | 'max';
8
+ /**
9
+ * Declares where the debounce/coalescing key is extracted from:
10
+ * - `{ body: '$.portalId' }`: dot notation path into the body
11
+ * - `{ header: 'x-goog-resource-id' }`: flat, case-insensitive header lookup
12
+ */
13
+ export type DebounceKeySource = {
14
+ body: string;
15
+ } | {
16
+ header: string;
17
+ };
18
+ export interface DebounceOptions {
19
+ keyBy?: DebounceKeySource | DebounceKeySource[];
20
+ windowMs: number;
21
+ maxEntities?: number;
22
+ take?: 'latest' | 'first' | 'all';
23
+ }
24
+ /**
25
+ * A trigger declares how a function is initiated FROM OUTSIDE; the `kind` discriminates what initiates execution.
26
+ * - `schedule`: a periodic schedule
27
+ * - `http`: an incoming http call or webhook request
28
+ * - `event`: an internal Nango lifecycle event
29
+ */
30
+ export type TriggerDefinition = {
31
+ kind: 'schedule';
32
+ frequency: string;
33
+ autoStart?: boolean;
34
+ } | {
35
+ kind: 'http';
36
+ subscriptions?: string[];
37
+ debounce?: DebounceOptions;
38
+ } | {
39
+ kind: 'event';
40
+ events: OnEventType[];
41
+ };
42
+ export interface HttpRequest {
43
+ method: HTTP_METHOD;
44
+ path: string;
45
+ headers: Record<string, string>;
46
+ query: Record<string, string>;
47
+ body: unknown;
48
+ }
49
+ export interface CoalescedInfo {
50
+ count: number;
51
+ firstSeenAt: Date;
52
+ lastSeenAt: Date;
53
+ }
54
+ type HttpPayload<TT, TInput extends z.ZodTypeAny> = TT extends {
55
+ debounce: {
56
+ take: 'all';
57
+ };
58
+ } ? z.infer<TInput>[] : z.infer<TInput>;
59
+ interface TriggerBase {
60
+ /**
61
+ * Present when the run carries connection context (invoke calls may pass one;
62
+ * http/event may resolve one). Undefined for connection-less runs.
63
+ */
64
+ connection?: {
65
+ connection_id: string;
66
+ integrationId: string;
67
+ };
68
+ }
69
+ export type InvokeTrigger<TInput extends z.ZodTypeAny> = TriggerBase & {
70
+ kind: 'invoke';
71
+ input: z.infer<TInput>;
72
+ };
73
+ export type ScheduleTrigger = TriggerBase & {
74
+ kind: 'schedule';
75
+ input: null;
76
+ };
77
+ export type HttpTrigger<TT, TInput extends z.ZodTypeAny> = TriggerBase & {
78
+ kind: 'http';
79
+ input: HttpPayload<TT, TInput>;
80
+ request: HttpRequest;
81
+ subscriptions?: string[];
82
+ coalesced: CoalescedInfo;
83
+ };
84
+ export type EventTrigger = TriggerBase & {
85
+ kind: 'event';
86
+ input: {
87
+ event: OnEventType;
88
+ };
89
+ };
90
+ /**
91
+ * The runtime trigger a function `exec` receives. Any function can be invoked by another, but an
92
+ * invoke reuses the declared trigger's shape rather than adding a separate arrival — so `exec` only
93
+ * ever sees its declared kind and never has to discriminate. On the invoke path the runtime
94
+ * synthesizes the envelope (e.g. an http `request`/`coalesced` derived from the invoked input).
95
+ * A function with no declared trigger is invoke-only and receives `InvokeTrigger`.
96
+ */
97
+ export type Trigger<TT extends TriggerDefinition | undefined, TInput extends z.ZodTypeAny> = TT extends {
98
+ kind: 'schedule';
99
+ } ? ScheduleTrigger : TT extends {
100
+ kind: 'http';
101
+ } ? HttpTrigger<TT, TInput> : TT extends {
102
+ kind: 'event';
103
+ } ? EventTrigger : InvokeTrigger<TInput>;
104
+ export interface NangoBase {
105
+ log(message: string, options?: unknown): Promise<void>;
106
+ setLogger(logger: SdkLogger): void;
107
+ getEnvironmentVariables(): Promise<EnvironmentVariable[] | null>;
108
+ }
109
+ export interface ConnectionCapability {
110
+ getConnection(): Promise<GetPublicConnection['Success']>;
111
+ getToken(): Promise<string | AllAuthCredentials>;
112
+ getIntegration(queries?: GetPublicIntegration['Querystring']): Promise<GetPublicIntegration['Success']['data']>;
113
+ getVariant(): string;
114
+ }
115
+ /**
116
+ * Present for connection-less runs instead of `getConnection`.
117
+ * Resolves the connection(s) an incoming event targets before fanning out work to them.
118
+ */
119
+ export interface ConnectionSearchCapability {
120
+ searchConnections(filter: unknown): Promise<GetPublicConnection['Success'][]>;
121
+ }
122
+ /**
123
+ * Present when `requires.outbound` is not `false`:
124
+ * - outbound http via proxy
125
+ * - or direct fetch via `uncontrolledFetch`.
126
+ */
127
+ export interface ProxyCapability {
128
+ proxy<T = unknown>(config: ProxyConfiguration): Promise<T>;
129
+ get<T = unknown>(config: Omit<ProxyConfiguration, 'method'>): Promise<T>;
130
+ post<T = unknown>(config: Omit<ProxyConfiguration, 'method'>): Promise<T>;
131
+ put<T = unknown>(config: Omit<ProxyConfiguration, 'method'>): Promise<T>;
132
+ patch<T = unknown>(config: Omit<ProxyConfiguration, 'method'>): Promise<T>;
133
+ delete<T = unknown>(config: Omit<ProxyConfiguration, 'method'>): Promise<T>;
134
+ paginate<T = unknown>(config: ProxyConfiguration): AsyncGenerator<T[]>;
135
+ uncontrolledFetch(options: UncontrolledFetchOptions): Promise<Response>;
136
+ }
137
+ export interface RecordCapability<TModels extends Record<string, ZodModel>> {
138
+ batchSave<K extends keyof TModels>(records: z.infer<TModels[K]>[], model: K): Promise<void>;
139
+ batchUpdate<K extends keyof TModels>(records: z.infer<TModels[K]>[], model: K): Promise<void>;
140
+ batchDelete<K extends keyof TModels>(records: z.infer<TModels[K]>[], model: K): Promise<void>;
141
+ setMergingStrategy(merging: MergingStrategy, model: keyof TModels): Promise<void>;
142
+ trackDeletesStart(model: keyof TModels): Promise<void>;
143
+ trackDeletesEnd(model: keyof TModels): Promise<void>;
144
+ }
145
+ export interface CheckpointCapability<TValue> {
146
+ getCheckpoint(): Promise<TValue | undefined>;
147
+ saveCheckpoint(checkpoint: TValue): Promise<void>;
148
+ clearCheckpoint(): Promise<void>;
149
+ }
150
+ export interface MetadataCapability<TValue> {
151
+ getMetadata(): Promise<TValue>;
152
+ setMetadata(metadata: TValue): Promise<void>;
153
+ updateMetadata(metadata: Partial<TValue>): Promise<void>;
154
+ }
155
+ type InferInput<T> = T extends CreateFunctionResponse<infer _M, infer I extends z.ZodTypeAny, infer _O, infer _Me, infer _Cp, infer _Tr, infer _R> ? z.infer<I> : void;
156
+ type InferOutput<T> = T extends CreateFunctionResponse<infer _M, infer _I, infer O extends z.ZodTypeAny, infer _Me, infer _Cp, infer _Tr, infer _R> ? z.infer<O> : void;
157
+ type InvokeConnection = {
158
+ connection_id: string;
159
+ integrationId: string;
160
+ };
161
+ type InvokeTarget = {
162
+ type: 'function';
163
+ capabilities: FunctionCapabilities;
164
+ };
165
+ type InvokeArgs<T> = [InferInput<T>] extends [void] ? [options?: {
166
+ connection?: InvokeConnection;
167
+ }] : [options: {
168
+ input: InferInput<T>;
169
+ connection?: InvokeConnection;
170
+ }];
171
+ export interface InvokeCapability {
172
+ invoke<T extends InvokeTarget>(fn: T, ...args: InvokeArgs<T>): Promise<InferOutput<T>>;
173
+ }
174
+ export type Nango<TModels extends Record<string, ZodModel>, TMetadata extends ZodMetadata, TCheckpoint extends ZodCheckpoint, TRequires extends Requires> = TRequires extends {
175
+ connection: false;
176
+ } ? NangoBase & ConnectionSearchCapability & (TRequires extends {
177
+ invoke: true;
178
+ } ? InvokeCapability : unknown) : NangoBase & ConnectionCapability & (TRequires extends {
179
+ outbound: false;
180
+ } ? unknown : ProxyCapability) & (TRequires extends {
181
+ invoke: true;
182
+ } ? InvokeCapability : unknown) & ([keyof TModels] extends [never] ? unknown : RecordCapability<TModels>) & (TCheckpoint extends undefined ? unknown : CheckpointCapability<InferZod<TCheckpoint>>) & (TMetadata extends undefined ? unknown : MetadataCapability<InferZod<TMetadata>>);
183
+ export type Requires = {
184
+ connection?: true;
185
+ outbound?: boolean;
186
+ invoke?: boolean;
187
+ } | {
188
+ connection: false;
189
+ outbound?: false;
190
+ invoke?: boolean;
191
+ };
192
+ export interface CreateFunctionProps<TModels extends Record<string, ZodModel> = Record<never, ZodModel>, TInput extends z.ZodTypeAny = z.ZodVoid, TOutput extends z.ZodTypeAny = z.ZodVoid, TMetadata extends ZodMetadata = undefined, TCheckpoint extends ZodCheckpoint = undefined, TTrigger extends TriggerDefinition | undefined = undefined, TRequires extends Requires = {
193
+ outbound: true;
194
+ connection: true;
195
+ }> {
196
+ description: string;
197
+ input?: TTrigger extends {
198
+ kind: 'schedule';
199
+ } | {
200
+ kind: 'event';
201
+ } ? never : TInput;
202
+ output?: TOutput;
203
+ data?: TRequires extends {
204
+ connection: false;
205
+ } ? never : {
206
+ models?: TModels;
207
+ metadata?: TMetadata;
208
+ checkpoint?: TCheckpoint;
209
+ };
210
+ trigger?: TTrigger;
211
+ requires?: TRequires;
212
+ limits?: {
213
+ concurrency?: {
214
+ perConnection?: TTrigger extends {
215
+ kind: 'schedule';
216
+ } ? 1 : ConcurrencyLimit;
217
+ };
218
+ };
219
+ exec: (nango: Nango<TModels, TMetadata, TCheckpoint, TRequires>, trigger: Trigger<TTrigger, TInput>) => MaybePromise<z.infer<TOutput>>;
220
+ }
221
+ export interface CreateFunctionResponse<TModels extends Record<string, ZodModel> = Record<never, ZodModel>, TInput extends z.ZodTypeAny = z.ZodVoid, TOutput extends z.ZodTypeAny = z.ZodVoid, TMetadata extends ZodMetadata = undefined, TCheckpoint extends ZodCheckpoint = undefined, TTrigger extends TriggerDefinition | undefined = undefined, TRequires extends Requires = {
222
+ outbound: true;
223
+ connection: true;
224
+ }> extends CreateFunctionProps<TModels, TInput, TOutput, TMetadata, TCheckpoint, TTrigger, TRequires> {
225
+ type: 'function';
226
+ capabilities: FunctionCapabilities;
227
+ }
228
+ /**
229
+ * Create a function, a trigger-agnostic primitive with capabilities.
230
+ *
231
+ * @experimental **Not production ready.**
232
+ * The function primitive is under active development.
233
+ * Its API may change or be removed without notice, do NOT USE it in production integrations.
234
+ *
235
+ * @example
236
+ * ```ts
237
+ * export default createFunction({
238
+ * description: 'Fetch issues from GitHub',
239
+ * trigger: { kind: 'schedule', frequency: 'every hour' },
240
+ * data: { models: { GithubIssue: z.object({ id: z.string() }) } },
241
+ * exec: async (nango) => {
242
+ * await nango.batchSave([{ id: '1' }], 'GithubIssue');
243
+ * }
244
+ * });
245
+ * ```
246
+ */
247
+ export declare function createFunction<TModels extends Record<string, ZodModel> = Record<never, ZodModel>, TInput extends z.ZodTypeAny = z.ZodVoid, TOutput extends z.ZodTypeAny = z.ZodVoid, TMetadata extends ZodMetadata = undefined, TCheckpoint extends ZodCheckpoint = undefined, TTrigger extends TriggerDefinition | undefined = undefined, TRequires extends Requires = {
248
+ outbound: true;
249
+ connection: true;
250
+ }>(params: CreateFunctionProps<TModels, TInput, TOutput, TMetadata, TCheckpoint, TTrigger, TRequires>): CreateFunctionResponse<TModels, TInput, TOutput, TMetadata, TCheckpoint, TTrigger, TRequires>;
251
+ export declare function deriveFunctionCapabilities(params: {
252
+ data?: {
253
+ models?: Record<string, ZodModel>;
254
+ metadata?: ZodMetadata;
255
+ checkpoint?: ZodCheckpoint;
256
+ } | undefined;
257
+ requires?: Requires | undefined;
258
+ }): FunctionCapabilities;
259
+ export {};
@@ -0,0 +1,36 @@
1
+ /**
2
+ * Create a function, a trigger-agnostic primitive with capabilities.
3
+ *
4
+ * @experimental **Not production ready.**
5
+ * The function primitive is under active development.
6
+ * Its API may change or be removed without notice, do NOT USE it in production integrations.
7
+ *
8
+ * @example
9
+ * ```ts
10
+ * export default createFunction({
11
+ * description: 'Fetch issues from GitHub',
12
+ * trigger: { kind: 'schedule', frequency: 'every hour' },
13
+ * data: { models: { GithubIssue: z.object({ id: z.string() }) } },
14
+ * exec: async (nango) => {
15
+ * await nango.batchSave([{ id: '1' }], 'GithubIssue');
16
+ * }
17
+ * });
18
+ * ```
19
+ */
20
+ export function createFunction(params) {
21
+ return { type: 'function', ...params, capabilities: deriveFunctionCapabilities(params) };
22
+ }
23
+ // Derives the runtime capabilities from function definition
24
+ export function deriveFunctionCapabilities(params) {
25
+ const models = params.data?.models;
26
+ // A connection-less function has no connection to proxy through, so outbound is always off.
27
+ const connectionLess = params.requires?.connection === false;
28
+ return {
29
+ usesRecords: !!models && Object.keys(models).length > 0,
30
+ usesCheckpoints: !!params.data?.checkpoint,
31
+ usesMetadata: !!params.data?.metadata,
32
+ usesOutbound: !connectionLess && params.requires?.outbound !== false,
33
+ usesInvoke: params.requires?.invoke === true
34
+ };
35
+ }
36
+ //# sourceMappingURL=function.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"function.js","sourceRoot":"","sources":["../lib/function.ts"],"names":[],"mappings":"AA8QA;;;;;;;;;;;;;;;;;;GAkBG;AACH,MAAM,UAAU,cAAc,CAS1B,MAAkG;IAElG,OAAO,EAAE,IAAI,EAAE,UAAU,EAAE,GAAG,MAAM,EAAE,YAAY,EAAE,0BAA0B,CAAC,MAAM,CAAC,EAAE,CAAC;AAC7F,CAAC;AAED,4DAA4D;AAC5D,MAAM,UAAU,0BAA0B,CAAC,MAG1C;IACG,MAAM,MAAM,GAAG,MAAM,CAAC,IAAI,EAAE,MAAM,CAAC;IACnC,4FAA4F;IAC5F,MAAM,cAAc,GAAG,MAAM,CAAC,QAAQ,EAAE,UAAU,KAAK,KAAK,CAAC;IAC7D,OAAO;QACH,WAAW,EAAE,CAAC,CAAC,MAAM,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,MAAM,GAAG,CAAC;QACvD,eAAe,EAAE,CAAC,CAAC,MAAM,CAAC,IAAI,EAAE,UAAU;QAC1C,YAAY,EAAE,CAAC,CAAC,MAAM,CAAC,IAAI,EAAE,QAAQ;QACrC,YAAY,EAAE,CAAC,cAAc,IAAI,MAAM,CAAC,QAAQ,EAAE,QAAQ,KAAK,KAAK;QACpE,UAAU,EAAE,MAAM,CAAC,QAAQ,EAAE,MAAM,KAAK,IAAI;KAC/C,CAAC;AACN,CAAC"}