@hostwebhook/node-types 1.82.0 → 1.84.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.
@@ -0,0 +1,90 @@
1
+ /**
2
+ * El nodo de Airtable: leer y escribir records de una tabla.
3
+ *
4
+ * ## Por qué existe
5
+ *
6
+ * [2026-09-15] Airtable expone una API REST con OAuth 2.0 (PKCE obligatorio,
7
+ * refresh que rota) y webhooks. Es «la hoja de cálculo con tipos» que mucha
8
+ * gente usa de base de datos ligera, así que este nodo se parece más a
9
+ * Postgres/Sheets que a un servicio de mensajería: casi todo es CRUD sobre
10
+ * una tabla.
11
+ *
12
+ * ## Cómo se nombra todo
13
+ *
14
+ * Una base es `appXXXXXXXXXXXXXX`, una tabla `tblXXXXXXXXXXXXXX`, una vista
15
+ * `viwXXXXXXXXXXXXXX`, un record `recXXXXXXXXXXXXXX`. Base y tabla se eligen
16
+ * en desplegables que lee el esquema (`GET /v0/meta/bases`,
17
+ * `GET /v0/meta/bases/{baseId}/tables`), y **los campos se escriben por
18
+ * nombre**, que es como los ve el usuario en Airtable. El esquema trae tipo
19
+ * y opciones de cada campo, y el editor de campos los usa para ofrecer lo
20
+ * que cabe: las opciones de un select, el formato de una fecha.
21
+ *
22
+ * ## Uno o un lote
23
+ *
24
+ * Cada operación de escritura trabaja sobre UN record —el caso normal, con
25
+ * el Loop node repitiendo si hacen falta varios— y tiene en Advanced un
26
+ * «Batch» que acepta un array del payload. Airtable admite 10 por llamada y
27
+ * 5 llamadas por segundo por base; el servicio trocea y espera, el usuario
28
+ * no tiene que saberlo.
29
+ *
30
+ * ## Por qué ocho
31
+ *
32
+ * Las seis de records (listar, uno, crear, editar, upsert, borrar) más las
33
+ * dos de esquema que un flujo puede necesitar (bases, tablas y campos).
34
+ * Fuera a propósito: comentarios, crear tablas o campos, y los webhooks,
35
+ * que son del trigger.
36
+ *
37
+ * ⚠️ El orden de este array es el orden del desplegable.
38
+ */
39
+ export declare const AIRTABLE_OPERATIONS: readonly ["listRecords", "getRecord", "createRecord", "updateRecord", "upsertRecord", "deleteRecord", "listBases", "getBaseSchema"];
40
+ export type AirtableOperation = (typeof AIRTABLE_OPERATIONS)[number];
41
+ export declare function isAirtableOperation(value: unknown): value is AirtableOperation;
42
+ /**
43
+ * Las que devuelven una COLECCIÓN sobre la que el nodo de abajo repite. Cada
44
+ * una itera SU campo (`iterateField`): `records`, `bases`, `tables`. La
45
+ * salida lleva `_meta.iterable: true`.
46
+ */
47
+ export declare const AIRTABLE_ITERABLE_OPERATIONS: ReadonlyArray<AirtableOperation>;
48
+ /**
49
+ * Tipos de parámetro. Los seis primeros son los de Apify. Los nuevos leen el
50
+ * esquema de la credencial y por eso son de Airtable:
51
+ *
52
+ * - `base`: desplegable de bases (`GET /airtable-actions/bases`); el valor es
53
+ * el `appXXX`.
54
+ * - `table`: desplegable de tablas de la base elegida; el valor es el `tblXXX`.
55
+ * - `view`: desplegable de vistas de la tabla (opcional); el valor es el `viwXXX`.
56
+ * - `field`: UN campo de la tabla, por nombre.
57
+ * - `fieldList`: VARIOS campos de la tabla, por nombre; se guarda como array.
58
+ * - `fields`: el editor de pares campo → valor, con el tipo y las opciones
59
+ * de cada campo delante; se guarda como objeto `{ "Nombre": valor }` y las
60
+ * cadenas admiten plantilla.
61
+ *
62
+ * Todos admiten plantilla como alternativa al desplegable, para cuando el id
63
+ * viene del payload.
64
+ */
65
+ export type AirtableParamType = "template" | "textarea" | "json" | "select" | "number" | "booleanSelect" | "base" | "table" | "view" | "field" | "fieldList" | "fields";
66
+ export interface AirtableParamSpec {
67
+ name: string;
68
+ label: string;
69
+ type: AirtableParamType;
70
+ required?: boolean;
71
+ description?: string;
72
+ placeholder?: string;
73
+ default?: string | number;
74
+ options?: ReadonlyArray<{
75
+ value: string;
76
+ label: string;
77
+ }>;
78
+ min?: number;
79
+ max?: number;
80
+ advanced?: boolean;
81
+ }
82
+ export interface AirtableOperationSpec {
83
+ label: string;
84
+ description: string;
85
+ apiRoute: string;
86
+ params: AirtableParamSpec[];
87
+ /** El campo de la salida que se itera; sólo en las iterables. */
88
+ iterateField?: string;
89
+ }
90
+ export declare const AIRTABLE_OPERATION_SPECS: Record<AirtableOperation, AirtableOperationSpec>;
@@ -0,0 +1,274 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.AIRTABLE_OPERATION_SPECS = exports.AIRTABLE_ITERABLE_OPERATIONS = exports.AIRTABLE_OPERATIONS = void 0;
4
+ exports.isAirtableOperation = isAirtableOperation;
5
+ /**
6
+ * El nodo de Airtable: leer y escribir records de una tabla.
7
+ *
8
+ * ## Por qué existe
9
+ *
10
+ * [2026-09-15] Airtable expone una API REST con OAuth 2.0 (PKCE obligatorio,
11
+ * refresh que rota) y webhooks. Es «la hoja de cálculo con tipos» que mucha
12
+ * gente usa de base de datos ligera, así que este nodo se parece más a
13
+ * Postgres/Sheets que a un servicio de mensajería: casi todo es CRUD sobre
14
+ * una tabla.
15
+ *
16
+ * ## Cómo se nombra todo
17
+ *
18
+ * Una base es `appXXXXXXXXXXXXXX`, una tabla `tblXXXXXXXXXXXXXX`, una vista
19
+ * `viwXXXXXXXXXXXXXX`, un record `recXXXXXXXXXXXXXX`. Base y tabla se eligen
20
+ * en desplegables que lee el esquema (`GET /v0/meta/bases`,
21
+ * `GET /v0/meta/bases/{baseId}/tables`), y **los campos se escriben por
22
+ * nombre**, que es como los ve el usuario en Airtable. El esquema trae tipo
23
+ * y opciones de cada campo, y el editor de campos los usa para ofrecer lo
24
+ * que cabe: las opciones de un select, el formato de una fecha.
25
+ *
26
+ * ## Uno o un lote
27
+ *
28
+ * Cada operación de escritura trabaja sobre UN record —el caso normal, con
29
+ * el Loop node repitiendo si hacen falta varios— y tiene en Advanced un
30
+ * «Batch» que acepta un array del payload. Airtable admite 10 por llamada y
31
+ * 5 llamadas por segundo por base; el servicio trocea y espera, el usuario
32
+ * no tiene que saberlo.
33
+ *
34
+ * ## Por qué ocho
35
+ *
36
+ * Las seis de records (listar, uno, crear, editar, upsert, borrar) más las
37
+ * dos de esquema que un flujo puede necesitar (bases, tablas y campos).
38
+ * Fuera a propósito: comentarios, crear tablas o campos, y los webhooks,
39
+ * que son del trigger.
40
+ *
41
+ * ⚠️ El orden de este array es el orden del desplegable.
42
+ */
43
+ exports.AIRTABLE_OPERATIONS = [
44
+ "listRecords",
45
+ "getRecord",
46
+ "createRecord",
47
+ "updateRecord",
48
+ "upsertRecord",
49
+ "deleteRecord",
50
+ "listBases",
51
+ "getBaseSchema",
52
+ ];
53
+ function isAirtableOperation(value) {
54
+ return (typeof value === "string" &&
55
+ exports.AIRTABLE_OPERATIONS.includes(value));
56
+ }
57
+ /**
58
+ * Las que devuelven una COLECCIÓN sobre la que el nodo de abajo repite. Cada
59
+ * una itera SU campo (`iterateField`): `records`, `bases`, `tables`. La
60
+ * salida lleva `_meta.iterable: true`.
61
+ */
62
+ exports.AIRTABLE_ITERABLE_OPERATIONS = [
63
+ "listRecords",
64
+ "listBases",
65
+ "getBaseSchema",
66
+ ];
67
+ const baseId = () => ({
68
+ name: "baseId",
69
+ label: "Base",
70
+ type: "base",
71
+ required: true,
72
+ description: "One of the bases the credential was granted access to.",
73
+ });
74
+ const tableId = () => ({
75
+ name: "tableId",
76
+ label: "Table",
77
+ type: "table",
78
+ required: true,
79
+ description: "A table in that base.",
80
+ });
81
+ const recordId = () => ({
82
+ name: "recordId",
83
+ label: "Record",
84
+ type: "template",
85
+ required: true,
86
+ placeholder: "{{payload.recordId}}",
87
+ description: "The record's ID (rec…), usually from an Airtable trigger or an earlier step.",
88
+ });
89
+ /* Los valores por nombre de campo. Cadenas con plantilla; el resto (números,
90
+ checkboxes, arrays de un multi-select o de linked records) como JSON. */
91
+ const fields = () => ({
92
+ name: "fields",
93
+ label: "Fields",
94
+ type: "fields",
95
+ description: "The values to write, by field name. Strings may use {{payload.x}}; select options, dates and linked records follow the field's type.",
96
+ });
97
+ /* `typecast` convierte "Sí" en un checkbox y "Done" en la opción de un
98
+ select aunque no exista todavía. Activado por defecto porque es lo que
99
+ uno espera al escribir desde un flujo; se puede apagar. */
100
+ const typecast = () => ({
101
+ name: "typecast",
102
+ label: "Convert values to the field's type",
103
+ type: "booleanSelect",
104
+ options: [
105
+ { value: "true", label: "Yes — text becomes the right type, new select options are created" },
106
+ { value: "false", label: "No — values must already match the field's type" },
107
+ ],
108
+ default: "true",
109
+ advanced: true,
110
+ description: "Airtable's typecast: with Yes, \"Yes\" fills a checkbox and an unknown option is added to a select.",
111
+ });
112
+ exports.AIRTABLE_OPERATION_SPECS = {
113
+ listRecords: {
114
+ label: "List records",
115
+ description: "Records of a table, optionally through a view and a filter formula. Comes back as the table shows them: fields by name.",
116
+ apiRoute: "GET /v0/{baseId}/{tableId}",
117
+ iterateField: "records",
118
+ params: [
119
+ baseId(),
120
+ tableId(),
121
+ {
122
+ name: "viewId",
123
+ label: "View",
124
+ type: "view",
125
+ description: "Only the records in this view, in the view's order. Empty = the whole table.",
126
+ },
127
+ {
128
+ name: "filterByFormula",
129
+ label: "Filter formula",
130
+ type: "textarea",
131
+ placeholder: '{Status} = "Done"',
132
+ description: "An Airtable formula; only records where it is true come back. Field names in braces. Supports {{payload.x}}.",
133
+ },
134
+ {
135
+ name: "fields",
136
+ label: "Only these fields",
137
+ type: "fieldList",
138
+ advanced: true,
139
+ description: "Fields to include in each record. Empty = every field.",
140
+ },
141
+ {
142
+ name: "sortField",
143
+ label: "Sort by",
144
+ type: "field",
145
+ advanced: true,
146
+ description: "A field to order by. Empty = the view's order, or the table's.",
147
+ },
148
+ {
149
+ name: "sortDirection",
150
+ label: "Direction",
151
+ type: "select",
152
+ options: [
153
+ { value: "asc", label: "Ascending" },
154
+ { value: "desc", label: "Descending" },
155
+ ],
156
+ default: "asc",
157
+ advanced: true,
158
+ },
159
+ {
160
+ name: "maxRecords",
161
+ label: "Max records",
162
+ type: "number",
163
+ min: 1,
164
+ max: 1000,
165
+ default: 100,
166
+ advanced: true,
167
+ description: "How many to bring into the flow, at most (Airtable pages by 100; the node keeps asking). Default 100.",
168
+ },
169
+ ],
170
+ },
171
+ getRecord: {
172
+ label: "Get record",
173
+ description: "One record by its ID, with every field.",
174
+ apiRoute: "GET /v0/{baseId}/{tableId}/{recordId}",
175
+ params: [baseId(), tableId(), recordId()],
176
+ },
177
+ createRecord: {
178
+ label: "Create record",
179
+ description: "Adds a record with the values you give it. For many at once, put an array in Batch (Advanced) — Airtable takes 10 per call and the node paces it.",
180
+ apiRoute: "POST /v0/{baseId}/{tableId}",
181
+ params: [
182
+ baseId(),
183
+ tableId(),
184
+ fields(),
185
+ {
186
+ name: "records",
187
+ label: "Batch",
188
+ type: "json",
189
+ placeholder: "{{payload.rows}}",
190
+ advanced: true,
191
+ description: "An array of objects, each { \"Field\": value, … } — e.g. {{payload.rows}}. When set, Fields above is ignored.",
192
+ },
193
+ typecast(),
194
+ ],
195
+ },
196
+ updateRecord: {
197
+ label: "Update record",
198
+ description: "Changes the fields you give it and leaves the rest as they are. For many at once, put an array in Batch (Advanced).",
199
+ apiRoute: "PATCH /v0/{baseId}/{tableId}",
200
+ params: [
201
+ baseId(),
202
+ tableId(),
203
+ recordId(),
204
+ fields(),
205
+ {
206
+ name: "records",
207
+ label: "Batch",
208
+ type: "json",
209
+ placeholder: "{{payload.rows}}",
210
+ advanced: true,
211
+ description: "An array of { \"id\": \"rec…\", \"fields\": { … } } objects. When set, Record and Fields above are ignored.",
212
+ },
213
+ typecast(),
214
+ ],
215
+ },
216
+ upsertRecord: {
217
+ label: "Upsert record",
218
+ description: "Finds a record by the fields you merge on and updates it; creates it when there is none. Fails if more than one matches.",
219
+ apiRoute: "PATCH /v0/{baseId}/{tableId} (performUpsert)",
220
+ params: [
221
+ baseId(),
222
+ tableId(),
223
+ {
224
+ name: "mergeOn",
225
+ label: "Match on",
226
+ type: "fieldList",
227
+ required: true,
228
+ description: "One to three fields that identify the record — an email, an external ID. Text, number, select or date fields; not formulas.",
229
+ },
230
+ fields(),
231
+ {
232
+ name: "records",
233
+ label: "Batch",
234
+ type: "json",
235
+ placeholder: "{{payload.rows}}",
236
+ advanced: true,
237
+ description: "An array of objects, each { \"Field\": value, … }. When set, Fields above is ignored.",
238
+ },
239
+ typecast(),
240
+ ],
241
+ },
242
+ deleteRecord: {
243
+ label: "Delete record",
244
+ description: "Deletes a record. For many at once, put their IDs in Batch (Advanced).",
245
+ apiRoute: "DELETE /v0/{baseId}/{tableId}",
246
+ params: [
247
+ baseId(),
248
+ tableId(),
249
+ recordId(),
250
+ {
251
+ name: "recordIds",
252
+ label: "Batch",
253
+ type: "template",
254
+ placeholder: "{{payload.ids}}",
255
+ advanced: true,
256
+ description: "Record IDs to delete — an array from the payload, or comma-separated. When set, Record above is ignored.",
257
+ },
258
+ ],
259
+ },
260
+ listBases: {
261
+ label: "List bases",
262
+ description: "The bases this credential can reach, with their IDs and your permission level in each.",
263
+ apiRoute: "GET /v0/meta/bases",
264
+ iterateField: "bases",
265
+ params: [],
266
+ },
267
+ getBaseSchema: {
268
+ label: "Get base schema",
269
+ description: "The tables of a base with their fields (name, type, options) and views. What a flow reads before writing into a table it does not know.",
270
+ apiRoute: "GET /v0/meta/bases/{baseId}/tables",
271
+ iterateField: "tables",
272
+ params: [baseId()],
273
+ },
274
+ };
@@ -0,0 +1,76 @@
1
+ /**
2
+ * El nodo de Calendly: lo que pasa alrededor de una reserva.
3
+ *
4
+ * ## Por qué existe
5
+ *
6
+ * [2026-09-15] Calendly expone una API v2 con OAuth 2.0 (PKCE + secret,
7
+ * refresh de un solo uso) y webhooks firmados. La reserva en sí la hace el
8
+ * invitado en Calendly; lo que HostWebhook necesita es leerla (el trigger la
9
+ * trae; este nodo la consulta), cancelarla, marcar el no-show, y las dos
10
+ * que cierran el círculo: un link de reserva que caduca al usarse y los
11
+ * huecos libres de un tipo de evento, para que un agente los ofrezca.
12
+ *
13
+ * ## Cómo se nombra todo
14
+ *
15
+ * Calendly identifica cada cosa por su URI completa
16
+ * (`https://api.calendly.com/scheduled_events/ABC…`), no por un id corto.
17
+ * Los parámetros que piden una la aceptan entera o sólo el uuid final; el
18
+ * servicio completa el prefijo. Los que piden «Mine / Whole organization»
19
+ * resuelven al `owner` y `organization` que la credencial guardó al
20
+ * conectar, así que el usuario no escribe URIs nunca.
21
+ *
22
+ * ## Por qué nueve
23
+ *
24
+ * Eventos (listar, uno, invitados, cancelar), no-show (poner y quitar),
25
+ * tipos de evento (listar), huecos libres y link de un solo uso. Fuera a
26
+ * propósito: crear tipos de evento, contactos, routing forms, recaps y toda
27
+ * la gestión de organización —nada de eso es «lo que pasa alrededor de una
28
+ * reserva». Los webhooks van en el trigger, no aquí.
29
+ *
30
+ * ⚠️ El orden de este array es el orden del desplegable.
31
+ */
32
+ export declare const CALENDLY_OPERATIONS: readonly ["listEvents", "getEvent", "listInvitees", "cancelEvent", "markNoShow", "undoNoShow", "listEventTypes", "getAvailableTimes", "createSchedulingLink"];
33
+ export type CalendlyOperation = (typeof CALENDLY_OPERATIONS)[number];
34
+ export declare function isCalendlyOperation(value: unknown): value is CalendlyOperation;
35
+ /**
36
+ * Las que devuelven una COLECCIÓN sobre la que el nodo de abajo repite. Cada
37
+ * una itera SU campo (`iterateField` en la spec): `events`, `invitees`,
38
+ * `eventTypes`, `slots`. La salida lleva `_meta.iterable: true`.
39
+ */
40
+ export declare const CALENDLY_ITERABLE_OPERATIONS: ReadonlyArray<CalendlyOperation>;
41
+ /**
42
+ * Tipos de parámetro. Los seis primeros son los de Apify. Los dos nuevos:
43
+ *
44
+ * - `datetime`: una fecha con hora, ISO 8601, en la zona horaria del
45
+ * usuario; el dashboard la pinta con el selector de Calendar y admite
46
+ * plantilla (`{{payload.startTime}}`).
47
+ * - `eventType`: un desplegable que lista los tipos de evento de la
48
+ * credencial (`GET /calendly-actions/event-types`); el valor es la URI del
49
+ * tipo. Admite plantilla para cuando viene del payload.
50
+ */
51
+ export type CalendlyParamType = "template" | "textarea" | "json" | "select" | "number" | "booleanSelect" | "datetime" | "eventType";
52
+ export interface CalendlyParamSpec {
53
+ name: string;
54
+ label: string;
55
+ type: CalendlyParamType;
56
+ required?: boolean;
57
+ description?: string;
58
+ placeholder?: string;
59
+ default?: string | number;
60
+ options?: ReadonlyArray<{
61
+ value: string;
62
+ label: string;
63
+ }>;
64
+ min?: number;
65
+ max?: number;
66
+ advanced?: boolean;
67
+ }
68
+ export interface CalendlyOperationSpec {
69
+ label: string;
70
+ description: string;
71
+ apiRoute: string;
72
+ params: CalendlyParamSpec[];
73
+ /** El campo de la salida que se itera; sólo en las iterables. */
74
+ iterateField?: string;
75
+ }
76
+ export declare const CALENDLY_OPERATION_SPECS: Record<CalendlyOperation, CalendlyOperationSpec>;