@hostwebhook/node-types 1.69.0 → 1.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.
Files changed (101) hide show
  1. package/dist/bucket-operations.d.ts +88 -0
  2. package/dist/bucket-operations.js +140 -0
  3. package/dist/calendar-toolkit.d.ts +1 -1
  4. package/dist/connections.d.ts +1 -1
  5. package/dist/connections.js +1 -0
  6. package/dist/discord-operations.d.ts +1 -1
  7. package/dist/discord-operations.js +4 -4
  8. package/dist/discord-toolkit.d.ts +1 -1
  9. package/dist/discord-toolkit.js +3 -3
  10. package/dist/dispatch.d.ts +1 -1
  11. package/dist/dispatch.js +1 -0
  12. package/dist/docs-toolkit.d.ts +1 -1
  13. package/dist/drive-toolkit.d.ts +1 -1
  14. package/dist/esm/bucket-operations.d.ts +88 -0
  15. package/dist/esm/bucket-operations.js +136 -0
  16. package/dist/esm/calendar-operations.d.ts +67 -0
  17. package/dist/esm/calendar-operations.js +176 -0
  18. package/dist/esm/calendar-toolkit.d.ts +50 -0
  19. package/dist/esm/calendar-toolkit.js +152 -0
  20. package/dist/esm/capacidad-de-credencial.d.ts +75 -0
  21. package/dist/esm/capacidad-de-credencial.js +68 -0
  22. package/dist/esm/connections.d.ts +17 -0
  23. package/dist/esm/connections.js +107 -0
  24. package/dist/esm/credentials.d.ts +144 -0
  25. package/dist/esm/credentials.js +199 -0
  26. package/dist/esm/discord-operations.d.ts +104 -0
  27. package/dist/esm/discord-operations.js +407 -0
  28. package/dist/esm/discord-toolkit.d.ts +64 -0
  29. package/dist/esm/discord-toolkit.js +260 -0
  30. package/dist/esm/dispatch.d.ts +16 -0
  31. package/dist/esm/dispatch.js +77 -0
  32. package/dist/esm/docs-operations.d.ts +99 -0
  33. package/dist/esm/docs-operations.js +127 -0
  34. package/dist/esm/docs-toolkit.d.ts +42 -0
  35. package/dist/esm/docs-toolkit.js +97 -0
  36. package/dist/esm/drive-operations.d.ts +103 -0
  37. package/dist/esm/drive-operations.js +319 -0
  38. package/dist/esm/drive-toolkit.d.ts +54 -0
  39. package/dist/esm/drive-toolkit.js +177 -0
  40. package/dist/esm/github-operations.d.ts +147 -0
  41. package/dist/esm/github-operations.js +551 -0
  42. package/dist/esm/gmail-operations.d.ts +190 -0
  43. package/dist/esm/gmail-operations.js +560 -0
  44. package/dist/esm/google-analytics-operations.d.ts +99 -0
  45. package/dist/esm/google-analytics-operations.js +222 -0
  46. package/dist/esm/google-contacts-operations.d.ts +93 -0
  47. package/dist/esm/google-contacts-operations.js +363 -0
  48. package/dist/esm/index.d.ts +68 -0
  49. package/dist/esm/index.js +51 -0
  50. package/dist/esm/jira-operations.d.ts +164 -0
  51. package/dist/esm/jira-operations.js +470 -0
  52. package/dist/esm/llm-models.d.ts +101 -0
  53. package/dist/esm/llm-models.js +230 -0
  54. package/dist/esm/mailchimp-operations.d.ts +56 -0
  55. package/dist/esm/mailchimp-operations.js +155 -0
  56. package/dist/esm/mongo-operations.d.ts +61 -0
  57. package/dist/esm/mongo-operations.js +120 -0
  58. package/dist/esm/notion-operations.d.ts +125 -0
  59. package/dist/esm/notion-operations.js +511 -0
  60. package/dist/esm/openrouter.d.ts +142 -0
  61. package/dist/esm/openrouter.js +99 -0
  62. package/dist/esm/package.json +4 -0
  63. package/dist/esm/postgres-operations.d.ts +60 -0
  64. package/dist/esm/postgres-operations.js +75 -0
  65. package/dist/esm/registry.d.ts +160 -0
  66. package/dist/esm/registry.js +885 -0
  67. package/dist/esm/sheets-operations.d.ts +78 -0
  68. package/dist/esm/sheets-operations.js +150 -0
  69. package/dist/esm/sheets-toolkit.d.ts +49 -0
  70. package/dist/esm/sheets-toolkit.js +127 -0
  71. package/dist/esm/shopify-operations.d.ts +95 -0
  72. package/dist/esm/shopify-operations.js +259 -0
  73. package/dist/esm/slack-operations.d.ts +81 -0
  74. package/dist/esm/slack-operations.js +244 -0
  75. package/dist/esm/slack-toolkit.d.ts +60 -0
  76. package/dist/esm/slack-toolkit.js +235 -0
  77. package/dist/esm/telegram-operations.d.ts +104 -0
  78. package/dist/esm/telegram-operations.js +351 -0
  79. package/dist/esm/telegram-toolkit.d.ts +52 -0
  80. package/dist/esm/telegram-toolkit.js +183 -0
  81. package/dist/esm/types.d.ts +149 -0
  82. package/dist/esm/types.js +8 -0
  83. package/dist/esm/ui.d.ts +13 -0
  84. package/dist/esm/ui.js +152 -0
  85. package/dist/esm/whatsapp-operations.d.ts +23 -0
  86. package/dist/esm/whatsapp-operations.js +36 -0
  87. package/dist/index.d.ts +68 -66
  88. package/dist/index.js +193 -187
  89. package/dist/openrouter.d.ts +1 -1
  90. package/dist/registry.d.ts +4 -4
  91. package/dist/registry.js +540 -210
  92. package/dist/sheets-toolkit.d.ts +1 -1
  93. package/dist/slack-operations.d.ts +1 -1
  94. package/dist/slack-operations.js +4 -4
  95. package/dist/slack-toolkit.d.ts +1 -1
  96. package/dist/slack-toolkit.js +3 -3
  97. package/dist/telegram-toolkit.d.ts +1 -1
  98. package/dist/types.d.ts +1 -1
  99. package/dist/ui.d.ts +1 -1
  100. package/dist/ui.js +2 -0
  101. package/package.json +21 -3
@@ -0,0 +1,88 @@
1
+ /**
2
+ * El nodo de bucket: guardar, firmar y borrar objetos en un almacenamiento
3
+ * compatible con S3.
4
+ *
5
+ * ## Por qué se llama `bucket` y no `r2`
6
+ *
7
+ * Porque el proveedor es un ENDPOINT, no un tipo de nodo. La credencial
8
+ * `aws_s3` ya guarda `endpoint`, `bucket` y `region`, así que el mismo nodo
9
+ * habla con Cloudflare R2, con AWS S3, con MinIO o con Backblaze sin cambiar
10
+ * una línea. Llamarlo `r2Action` habría obligado, el día que llegue AWS, a
11
+ * tener dos nodos casi idénticos o a renombrar un tipo — y el prefijo del tipo
12
+ * vive DENTRO de los ids de nodo ya guardados en la base de cada cliente, así
13
+ * que renombrar es migrar datos.
14
+ *
15
+ * ## La operación que motiva el nodo
16
+ *
17
+ * `presignDownload`. La plataforma sabe firmar peticiones S3 desde el nodo
18
+ * HTTP —`common/s3-signer.ts`— pero **por cabecera**, y una cabecera no cabe en
19
+ * un enlace que se manda por correo. Sin esto no había forma de entregarle a un
20
+ * comprador una descarga temporal desde un flujo.
21
+ *
22
+ * ## Por qué sólo cuatro operaciones
23
+ *
24
+ * Listar y subida multiparte son las dos que piden el SDK de AWS de verdad
25
+ * —paginación y reanudación— y el ejecutor hoy no tiene ni un `@aws-sdk/*`.
26
+ * Entrar sin esa dependencia y traerla cuando aparezca la operación que la
27
+ * justifique es más barato que al revés. Y un nodo con veinte operaciones es un
28
+ * nodo que nadie entiende.
29
+ */
30
+ export declare const BUCKET_OPERATIONS: readonly ["presignDownload", "putObject", "headObject", "deleteObject"];
31
+ export type BucketOperation = (typeof BUCKET_OPERATIONS)[number];
32
+ export declare function isBucketOperation(value: unknown): value is BucketOperation;
33
+ /**
34
+ * Ninguna es iterable.
35
+ *
36
+ * Una operación iterable es la que devuelve una COLECCIÓN sobre la que el nodo
37
+ * de abajo repite. Las cuatro de aquí actúan sobre UN objeto, así que el que
38
+ * viene detrás recibe un resultado, no una lista. El día que entre `listObjects`
39
+ * ésa sí entra en esta lista.
40
+ */
41
+ export declare const BUCKET_ITERABLE_OPERATIONS: readonly BucketOperation[];
42
+ export type BucketParamType =
43
+ /** La clave del objeto dentro del bucket. Con autocompletado de
44
+ * `{{payload.*}}`, porque el 90% de los casos la construye del evento:
45
+ * `cuadernillos/{{payload.orderId}}.pdf`. */
46
+ "template"
47
+ /** Área de texto larga, también con autocompletado. */
48
+ | "textarea"
49
+ /** `<select>` normal; las etiquetas no son los valores, `options` obliga. */
50
+ | "select" | "number"
51
+ /**
52
+ * `<select>` de `''` / `'true'` / `'false'` que se guarda como BOOLEANO, o
53
+ * no se guarda si es `''`. "— sin tocar —" tiene que significar que la clave
54
+ * no viaja, no que viaja en `false`.
55
+ */
56
+ | "booleanSelect";
57
+ export interface BucketParamSpec {
58
+ /** La clave de `operationConfig`. Es lo que lee la api, no un nombre de UI. */
59
+ name: string;
60
+ label: string;
61
+ type: BucketParamType;
62
+ required?: boolean;
63
+ /** Ayuda bajo el campo. Texto plano: el paquete no lleva React. */
64
+ description?: string;
65
+ placeholder?: string;
66
+ /** Prerrellenado cuando la config guardada no trae valor para esta clave. */
67
+ default?: string | number;
68
+ /** Obligatorio en `select` y `booleanSelect`. */
69
+ options?: ReadonlyArray<{
70
+ value: string;
71
+ label: string;
72
+ }>;
73
+ min?: number;
74
+ max?: number;
75
+ /** Se pinta en la pestaña "Advanced" en vez de en "Config". */
76
+ advanced?: boolean;
77
+ }
78
+ export interface BucketOperationSpec {
79
+ /** Etiqueta de la fila en el desplegable de operación. */
80
+ label: string;
81
+ /** Sub-línea bajo la etiqueta. */
82
+ description: string;
83
+ /** La llamada S3 a la que mapea, para poder cotejarla con los docs. */
84
+ apiRoute: string;
85
+ /** Esquema de parámetros. El orden ES el orden en pantalla. */
86
+ params: BucketParamSpec[];
87
+ }
88
+ export declare const BUCKET_OPERATION_SPECS: Record<BucketOperation, BucketOperationSpec>;
@@ -0,0 +1,140 @@
1
+ "use strict";
2
+ /**
3
+ * El nodo de bucket: guardar, firmar y borrar objetos en un almacenamiento
4
+ * compatible con S3.
5
+ *
6
+ * ## Por qué se llama `bucket` y no `r2`
7
+ *
8
+ * Porque el proveedor es un ENDPOINT, no un tipo de nodo. La credencial
9
+ * `aws_s3` ya guarda `endpoint`, `bucket` y `region`, así que el mismo nodo
10
+ * habla con Cloudflare R2, con AWS S3, con MinIO o con Backblaze sin cambiar
11
+ * una línea. Llamarlo `r2Action` habría obligado, el día que llegue AWS, a
12
+ * tener dos nodos casi idénticos o a renombrar un tipo — y el prefijo del tipo
13
+ * vive DENTRO de los ids de nodo ya guardados en la base de cada cliente, así
14
+ * que renombrar es migrar datos.
15
+ *
16
+ * ## La operación que motiva el nodo
17
+ *
18
+ * `presignDownload`. La plataforma sabe firmar peticiones S3 desde el nodo
19
+ * HTTP —`common/s3-signer.ts`— pero **por cabecera**, y una cabecera no cabe en
20
+ * un enlace que se manda por correo. Sin esto no había forma de entregarle a un
21
+ * comprador una descarga temporal desde un flujo.
22
+ *
23
+ * ## Por qué sólo cuatro operaciones
24
+ *
25
+ * Listar y subida multiparte son las dos que piden el SDK de AWS de verdad
26
+ * —paginación y reanudación— y el ejecutor hoy no tiene ni un `@aws-sdk/*`.
27
+ * Entrar sin esa dependencia y traerla cuando aparezca la operación que la
28
+ * justifique es más barato que al revés. Y un nodo con veinte operaciones es un
29
+ * nodo que nadie entiende.
30
+ */
31
+ Object.defineProperty(exports, "__esModule", { value: true });
32
+ exports.BUCKET_OPERATION_SPECS = exports.BUCKET_ITERABLE_OPERATIONS = exports.BUCKET_OPERATIONS = void 0;
33
+ exports.isBucketOperation = isBucketOperation;
34
+ exports.BUCKET_OPERATIONS = [
35
+ "presignDownload",
36
+ "putObject",
37
+ "headObject",
38
+ "deleteObject",
39
+ ];
40
+ function isBucketOperation(value) {
41
+ return (typeof value === "string" &&
42
+ exports.BUCKET_OPERATIONS.includes(value));
43
+ }
44
+ /**
45
+ * Ninguna es iterable.
46
+ *
47
+ * Una operación iterable es la que devuelve una COLECCIÓN sobre la que el nodo
48
+ * de abajo repite. Las cuatro de aquí actúan sobre UN objeto, así que el que
49
+ * viene detrás recibe un resultado, no una lista. El día que entre `listObjects`
50
+ * ésa sí entra en esta lista.
51
+ */
52
+ exports.BUCKET_ITERABLE_OPERATIONS = [];
53
+ /* Ayudantes — repetir el mismo objeto cuatro veces es cómo se desincronizan las
54
+ descripciones. */
55
+ const objectKey = (placeholder) => ({
56
+ name: "key",
57
+ label: "Object key",
58
+ type: "template",
59
+ required: true,
60
+ placeholder,
61
+ description: "La ruta dentro del bucket. Sin barra inicial. Admite {{payload.x}}.",
62
+ });
63
+ exports.BUCKET_OPERATION_SPECS = {
64
+ presignDownload: {
65
+ label: "Sign download link",
66
+ description: "Devuelve una URL temporal para descargar un objeto privado. No mueve el fichero.",
67
+ apiRoute: "GET (presigned)",
68
+ params: [
69
+ objectKey("cuadernillos/{{payload.orderId}}.pdf"),
70
+ {
71
+ name: "expiresIn",
72
+ label: "Link valid for (seconds)",
73
+ type: "number",
74
+ required: true,
75
+ default: 3600,
76
+ min: 60,
77
+ /* El tope de SigV4 es de siete días y no se puede pasar: firmar por
78
+ más tiempo produce una URL que el proveedor rechaza, y el error
79
+ llega tarde y sin explicación. */
80
+ max: 604800,
81
+ description: "Desde 60 s hasta 7 días, que es el máximo que admite la firma. Pasado ese plazo el enlace deja de servir.",
82
+ },
83
+ {
84
+ name: "downloadAs",
85
+ label: "Download as (filename)",
86
+ type: "template",
87
+ placeholder: "Cuadernillo 1.pdf",
88
+ description: "Si se rellena, el navegador DESCARGA el fichero con ese nombre en vez de abrirlo. Déjalo vacío para que lo abra.",
89
+ },
90
+ ],
91
+ },
92
+ putObject: {
93
+ label: "Upload object",
94
+ description: "Guarda un objeto en el bucket. Sobreescribe si la clave ya existe.",
95
+ apiRoute: "PUT /{bucket}/{key}",
96
+ params: [
97
+ objectKey("recibos/{{payload.orderId}}.json"),
98
+ {
99
+ name: "body",
100
+ label: "Contents",
101
+ type: "textarea",
102
+ required: true,
103
+ placeholder: "{{payload}}",
104
+ description: "Lo que se guarda. Admite {{payload.x}}; un objeto se guarda como JSON.",
105
+ },
106
+ {
107
+ name: "contentType",
108
+ label: "Content type",
109
+ type: "template",
110
+ default: "application/json",
111
+ placeholder: "application/pdf",
112
+ description: "Lo que el navegador usará para decidir qué hacer con el fichero.",
113
+ },
114
+ ],
115
+ },
116
+ headObject: {
117
+ label: "Check object exists",
118
+ description: "Comprueba si un objeto existe, y su tamaño, sin descargarlo.",
119
+ apiRoute: "HEAD /{bucket}/{key}",
120
+ params: [
121
+ objectKey("cuadernillos/{{payload.orderId}}.pdf"),
122
+ {
123
+ name: "failIfMissing",
124
+ label: "Fail when the object is missing",
125
+ type: "booleanSelect",
126
+ options: [
127
+ { value: "true", label: "Sí — cortar el flujo" },
128
+ { value: "false", label: "No — seguir con exists: false" },
129
+ ],
130
+ description: 'Con "No", el paso sale bien y el de abajo decide. Con "Sí", un objeto que falta corta el flujo.',
131
+ },
132
+ ],
133
+ },
134
+ deleteObject: {
135
+ label: "Delete object",
136
+ description: "Borra un objeto del bucket. No se puede deshacer.",
137
+ apiRoute: "DELETE /{bucket}/{key}",
138
+ params: [objectKey("temporales/{{payload.id}}.tmp")],
139
+ },
140
+ };
@@ -28,7 +28,7 @@
28
28
  * El array se generó desde la copia de la api para que las descripciones largas
29
29
  * salieran idénticas, no tecleadas.
30
30
  */
31
- import type { GoogleCalendarOperation } from './calendar-operations';
31
+ import type { GoogleCalendarOperation } from './calendar-operations.js';
32
32
  export interface GoogleCalendarToolkitParameter {
33
33
  name: string;
34
34
  type: 'string' | 'number' | 'boolean';
@@ -6,7 +6,7 @@
6
6
  *
7
7
  * Adding a new node type = add 1 entry here. All repos import from this package.
8
8
  */
9
- import type { NodeType, NodeConnectionConfig } from './types';
9
+ import type { NodeType, NodeConnectionConfig } from './types.js';
10
10
  export declare const NODE_CONNECTIONS: Record<NodeType, NodeConnectionConfig>;
11
11
  export declare function canReceiveFrom(targetType: NodeType, sourceType: NodeType): boolean;
12
12
  export declare function canReceiveFromNodes(nodeType: NodeType): boolean;
@@ -81,6 +81,7 @@ exports.NODE_CONNECTIONS = {
81
81
  shopifyAction: { acceptsInputFrom: ACTION_INPUTS, canOutputTo: PROCESSING_OUTPUTS },
82
82
  githubAction: { acceptsInputFrom: ACTION_INPUTS, canOutputTo: PROCESSING_OUTPUTS },
83
83
  jiraAction: { acceptsInputFrom: ACTION_INPUTS, canOutputTo: PROCESSING_OUTPUTS },
84
+ bucketAction: { acceptsInputFrom: ACTION_INPUTS, canOutputTo: PROCESSING_OUTPUTS },
84
85
  googleContactsAction: { acceptsInputFrom: ACTION_INPUTS, canOutputTo: PROCESSING_OUTPUTS },
85
86
  googleAnalyticsAction: { acceptsInputFrom: ACTION_INPUTS, canOutputTo: PROCESSING_OUTPUTS },
86
87
  notionAction: { acceptsInputFrom: ACTION_INPUTS, canOutputTo: PROCESSING_OUTPUTS },
@@ -17,7 +17,7 @@
17
17
  * forum-post create) extend this list — bump the package and re-install
18
18
  * in consumers, same pattern as Gmail / Calendar / Drive / Telegram.
19
19
  */
20
- import { type CapacidadesPorCredencial } from './capacidad-de-credencial';
20
+ import { type CapacidadesPorCredencial } from './capacidad-de-credencial.js';
21
21
  export declare const DISCORD_OPERATIONS: readonly ["sendMessage", "editMessage", "deleteMessage", "getMessage", "addReaction", "removeReaction", "pinMessage", "createChannel", "editChannel", "deleteChannel", "getChannel", "listChannels", "createThread", "sendDM", "addRole", "removeRole", "getMember"];
22
22
  export type DiscordOperation = (typeof DISCORD_OPERATIONS)[number];
23
23
  /** Type guard — useful when validating untrusted input (DTOs, tool calls). */
@@ -24,7 +24,7 @@ exports.camposDeDiscordNoDisponibles = camposDeDiscordNoDisponibles;
24
24
  * forum-post create) extend this list — bump the package and re-install
25
25
  * in consumers, same pattern as Gmail / Calendar / Drive / Telegram.
26
26
  */
27
- const capacidad_de_credencial_1 = require("./capacidad-de-credencial");
27
+ const capacidad_de_credencial_js_1 = require("./capacidad-de-credencial.js");
28
28
  exports.DISCORD_OPERATIONS = [
29
29
  // Messages
30
30
  'sendMessage',
@@ -402,13 +402,13 @@ exports.DISCORD_CAPACIDADES_POR_CREDENCIAL = {
402
402
  };
403
403
  /** Las operaciones que ofrecer para una credencial de Discord. */
404
404
  function operacionesDeDiscordPara(tipoDeCredencial) {
405
- return (0, capacidad_de_credencial_1.operacionesPara)(exports.DISCORD_OPERATIONS, exports.DISCORD_CAPACIDADES_POR_CREDENCIAL, tipoDeCredencial);
405
+ return (0, capacidad_de_credencial_js_1.operacionesPara)(exports.DISCORD_OPERATIONS, exports.DISCORD_CAPACIDADES_POR_CREDENCIAL, tipoDeCredencial);
406
406
  }
407
407
  /** Si esa credencial puede ejecutar esa operación de Discord. */
408
408
  function discordPuedeEjecutar(tipoDeCredencial, operacion) {
409
- return (0, capacidad_de_credencial_1.puedeEjecutar)(exports.DISCORD_OPERATIONS, exports.DISCORD_CAPACIDADES_POR_CREDENCIAL, tipoDeCredencial, operacion);
409
+ return (0, capacidad_de_credencial_js_1.puedeEjecutar)(exports.DISCORD_OPERATIONS, exports.DISCORD_CAPACIDADES_POR_CREDENCIAL, tipoDeCredencial, operacion);
410
410
  }
411
411
  /** Los campos que esa credencial de Discord no deja elegir. */
412
412
  function camposDeDiscordNoDisponibles(tipoDeCredencial) {
413
- return (0, capacidad_de_credencial_1.camposNoDisponiblesPara)(exports.DISCORD_CAPACIDADES_POR_CREDENCIAL, tipoDeCredencial);
413
+ return (0, capacidad_de_credencial_js_1.camposNoDisponiblesPara)(exports.DISCORD_CAPACIDADES_POR_CREDENCIAL, tipoDeCredencial);
414
414
  }
@@ -22,7 +22,7 @@
22
22
  * pueda usarse sin adaptador. Los textos van en inglés porque los lee el modelo
23
23
  * y quien mire la lista de herramientas del servidor MCP.
24
24
  */
25
- import type { DiscordOperation } from './discord-operations';
25
+ import type { DiscordOperation } from './discord-operations.js';
26
26
  export interface DiscordToolkitParameter {
27
27
  name: string;
28
28
  type: 'string' | 'number' | 'boolean';
@@ -26,7 +26,7 @@
26
26
  Object.defineProperty(exports, "__esModule", { value: true });
27
27
  exports.DISCORD_TOOLKIT_BY_TOOL_NAME = exports.DISCORD_TOOLKIT_SPECS = void 0;
28
28
  exports.herramientasDeDiscordPara = herramientasDeDiscordPara;
29
- const discord_operations_1 = require("./discord-operations");
29
+ const discord_operations_js_1 = require("./discord-operations.js");
30
30
  const p = (name, description, required = true, type = 'string') => ({ name, type, description, required });
31
31
  exports.DISCORD_TOOLKIT_SPECS = [
32
32
  // ── Messages ───────────────────────────────────────────────────
@@ -252,8 +252,8 @@ exports.DISCORD_TOOLKIT_BY_TOOL_NAME = Object.fromEntries(exports.DISCORD_TOOLKI
252
252
  * fallar, porque parece que funcionó.
253
253
  */
254
254
  function herramientasDeDiscordPara(tipoDeCredencial) {
255
- const permitidas = new Set((0, discord_operations_1.operacionesDeDiscordPara)(tipoDeCredencial));
256
- const fuera = (0, discord_operations_1.camposDeDiscordNoDisponibles)(tipoDeCredencial);
255
+ const permitidas = new Set((0, discord_operations_js_1.operacionesDeDiscordPara)(tipoDeCredencial));
256
+ const fuera = (0, discord_operations_js_1.camposDeDiscordNoDisponibles)(tipoDeCredencial);
257
257
  return exports.DISCORD_TOOLKIT_SPECS.filter((s) => permitidas.has(s.operation)).map((s) =>
258
258
  /* Se devuelve una copia sólo cuando hay algo que quitar: así el camino
259
259
  normal —el bot, que puede con todo— sigue entregando las MISMAS
@@ -8,7 +8,7 @@
8
8
  * orphan the node (the symptom Vector Store / AI / Markdown / Code /
9
9
  * File Transform all hit before this refactor).
10
10
  */
11
- import type { NodeType, NodeDispatchConfig } from './types';
11
+ import type { NodeType, NodeDispatchConfig } from './types.js';
12
12
  export declare const NODE_DISPATCH: Record<NodeType, NodeDispatchConfig>;
13
13
  /** Get all MongoDB collection names for cascade cleanup */
14
14
  export declare function getAllNodeCollections(): string[];
package/dist/dispatch.js CHANGED
@@ -56,6 +56,7 @@ exports.NODE_DISPATCH = {
56
56
  shopifyAction: { service: 'shopifyActionsService', collection: 'shopifyactions', hasFilters: true, outputFields: ['outputNodes'], customDispatch: true, pipelineDispatch: 'excluded' },
57
57
  githubAction: { service: 'githubActionsService', collection: 'githubactions', hasFilters: true, outputFields: ['outputNodes'], customDispatch: true, pipelineDispatch: 'excluded' },
58
58
  jiraAction: { service: 'jiraActionsService', collection: 'jiraactions', hasFilters: true, outputFields: ['outputNodes'], customDispatch: true, pipelineDispatch: 'excluded' },
59
+ bucketAction: { service: 'bucketActionsService', collection: 'bucketactions', hasFilters: true, outputFields: ['outputNodes'], customDispatch: true, pipelineDispatch: 'excluded' },
59
60
  slackAction: { service: 'slackActionsService', collection: 'slackactions', hasFilters: true, outputFields: ['outputNodes'], customDispatch: true, pipelineDispatch: 'excluded' },
60
61
  googleContactsAction: { service: 'googleContactsActionsService', collection: 'googlecontactsactions', hasFilters: true, outputFields: ['outputNodes'], customDispatch: true, pipelineDispatch: 'excluded' },
61
62
  googleAnalyticsAction: { service: 'googleAnalyticsActionsService', collection: 'googleanalyticsactions', hasFilters: true, outputFields: ['outputNodes'], customDispatch: true, pipelineDispatch: 'excluded' },
@@ -13,7 +13,7 @@
13
13
  * usarse sin adaptador. Los textos van en inglés porque los lee el modelo y
14
14
  * quien mire la lista de herramientas del servidor MCP.
15
15
  */
16
- import type { DocsOperation } from './docs-operations';
16
+ import type { DocsOperation } from './docs-operations.js';
17
17
  export interface DocsToolkitParameter {
18
18
  name: string;
19
19
  /** El esquema MCP sólo admite estos tres. */
@@ -19,7 +19,7 @@
19
19
  * herramientas del mismo grupo tienen que ir seguidas. Los tres grupos son los
20
20
  * que ya inventaba el JSX que sustituye.
21
21
  */
22
- import type { DriveOperation } from './drive-operations';
22
+ import type { DriveOperation } from './drive-operations.js';
23
23
  export interface DriveToolkitParameter {
24
24
  name: string;
25
25
  type: 'string' | 'number' | 'boolean';
@@ -0,0 +1,88 @@
1
+ /**
2
+ * El nodo de bucket: guardar, firmar y borrar objetos en un almacenamiento
3
+ * compatible con S3.
4
+ *
5
+ * ## Por qué se llama `bucket` y no `r2`
6
+ *
7
+ * Porque el proveedor es un ENDPOINT, no un tipo de nodo. La credencial
8
+ * `aws_s3` ya guarda `endpoint`, `bucket` y `region`, así que el mismo nodo
9
+ * habla con Cloudflare R2, con AWS S3, con MinIO o con Backblaze sin cambiar
10
+ * una línea. Llamarlo `r2Action` habría obligado, el día que llegue AWS, a
11
+ * tener dos nodos casi idénticos o a renombrar un tipo — y el prefijo del tipo
12
+ * vive DENTRO de los ids de nodo ya guardados en la base de cada cliente, así
13
+ * que renombrar es migrar datos.
14
+ *
15
+ * ## La operación que motiva el nodo
16
+ *
17
+ * `presignDownload`. La plataforma sabe firmar peticiones S3 desde el nodo
18
+ * HTTP —`common/s3-signer.ts`— pero **por cabecera**, y una cabecera no cabe en
19
+ * un enlace que se manda por correo. Sin esto no había forma de entregarle a un
20
+ * comprador una descarga temporal desde un flujo.
21
+ *
22
+ * ## Por qué sólo cuatro operaciones
23
+ *
24
+ * Listar y subida multiparte son las dos que piden el SDK de AWS de verdad
25
+ * —paginación y reanudación— y el ejecutor hoy no tiene ni un `@aws-sdk/*`.
26
+ * Entrar sin esa dependencia y traerla cuando aparezca la operación que la
27
+ * justifique es más barato que al revés. Y un nodo con veinte operaciones es un
28
+ * nodo que nadie entiende.
29
+ */
30
+ export declare const BUCKET_OPERATIONS: readonly ["presignDownload", "putObject", "headObject", "deleteObject"];
31
+ export type BucketOperation = (typeof BUCKET_OPERATIONS)[number];
32
+ export declare function isBucketOperation(value: unknown): value is BucketOperation;
33
+ /**
34
+ * Ninguna es iterable.
35
+ *
36
+ * Una operación iterable es la que devuelve una COLECCIÓN sobre la que el nodo
37
+ * de abajo repite. Las cuatro de aquí actúan sobre UN objeto, así que el que
38
+ * viene detrás recibe un resultado, no una lista. El día que entre `listObjects`
39
+ * ésa sí entra en esta lista.
40
+ */
41
+ export declare const BUCKET_ITERABLE_OPERATIONS: readonly BucketOperation[];
42
+ export type BucketParamType =
43
+ /** La clave del objeto dentro del bucket. Con autocompletado de
44
+ * `{{payload.*}}`, porque el 90% de los casos la construye del evento:
45
+ * `cuadernillos/{{payload.orderId}}.pdf`. */
46
+ "template"
47
+ /** Área de texto larga, también con autocompletado. */
48
+ | "textarea"
49
+ /** `<select>` normal; las etiquetas no son los valores, `options` obliga. */
50
+ | "select" | "number"
51
+ /**
52
+ * `<select>` de `''` / `'true'` / `'false'` que se guarda como BOOLEANO, o
53
+ * no se guarda si es `''`. "— sin tocar —" tiene que significar que la clave
54
+ * no viaja, no que viaja en `false`.
55
+ */
56
+ | "booleanSelect";
57
+ export interface BucketParamSpec {
58
+ /** La clave de `operationConfig`. Es lo que lee la api, no un nombre de UI. */
59
+ name: string;
60
+ label: string;
61
+ type: BucketParamType;
62
+ required?: boolean;
63
+ /** Ayuda bajo el campo. Texto plano: el paquete no lleva React. */
64
+ description?: string;
65
+ placeholder?: string;
66
+ /** Prerrellenado cuando la config guardada no trae valor para esta clave. */
67
+ default?: string | number;
68
+ /** Obligatorio en `select` y `booleanSelect`. */
69
+ options?: ReadonlyArray<{
70
+ value: string;
71
+ label: string;
72
+ }>;
73
+ min?: number;
74
+ max?: number;
75
+ /** Se pinta en la pestaña "Advanced" en vez de en "Config". */
76
+ advanced?: boolean;
77
+ }
78
+ export interface BucketOperationSpec {
79
+ /** Etiqueta de la fila en el desplegable de operación. */
80
+ label: string;
81
+ /** Sub-línea bajo la etiqueta. */
82
+ description: string;
83
+ /** La llamada S3 a la que mapea, para poder cotejarla con los docs. */
84
+ apiRoute: string;
85
+ /** Esquema de parámetros. El orden ES el orden en pantalla. */
86
+ params: BucketParamSpec[];
87
+ }
88
+ export declare const BUCKET_OPERATION_SPECS: Record<BucketOperation, BucketOperationSpec>;
@@ -0,0 +1,136 @@
1
+ /**
2
+ * El nodo de bucket: guardar, firmar y borrar objetos en un almacenamiento
3
+ * compatible con S3.
4
+ *
5
+ * ## Por qué se llama `bucket` y no `r2`
6
+ *
7
+ * Porque el proveedor es un ENDPOINT, no un tipo de nodo. La credencial
8
+ * `aws_s3` ya guarda `endpoint`, `bucket` y `region`, así que el mismo nodo
9
+ * habla con Cloudflare R2, con AWS S3, con MinIO o con Backblaze sin cambiar
10
+ * una línea. Llamarlo `r2Action` habría obligado, el día que llegue AWS, a
11
+ * tener dos nodos casi idénticos o a renombrar un tipo — y el prefijo del tipo
12
+ * vive DENTRO de los ids de nodo ya guardados en la base de cada cliente, así
13
+ * que renombrar es migrar datos.
14
+ *
15
+ * ## La operación que motiva el nodo
16
+ *
17
+ * `presignDownload`. La plataforma sabe firmar peticiones S3 desde el nodo
18
+ * HTTP —`common/s3-signer.ts`— pero **por cabecera**, y una cabecera no cabe en
19
+ * un enlace que se manda por correo. Sin esto no había forma de entregarle a un
20
+ * comprador una descarga temporal desde un flujo.
21
+ *
22
+ * ## Por qué sólo cuatro operaciones
23
+ *
24
+ * Listar y subida multiparte son las dos que piden el SDK de AWS de verdad
25
+ * —paginación y reanudación— y el ejecutor hoy no tiene ni un `@aws-sdk/*`.
26
+ * Entrar sin esa dependencia y traerla cuando aparezca la operación que la
27
+ * justifique es más barato que al revés. Y un nodo con veinte operaciones es un
28
+ * nodo que nadie entiende.
29
+ */
30
+ export const BUCKET_OPERATIONS = [
31
+ "presignDownload",
32
+ "putObject",
33
+ "headObject",
34
+ "deleteObject",
35
+ ];
36
+ export function isBucketOperation(value) {
37
+ return (typeof value === "string" &&
38
+ BUCKET_OPERATIONS.includes(value));
39
+ }
40
+ /**
41
+ * Ninguna es iterable.
42
+ *
43
+ * Una operación iterable es la que devuelve una COLECCIÓN sobre la que el nodo
44
+ * de abajo repite. Las cuatro de aquí actúan sobre UN objeto, así que el que
45
+ * viene detrás recibe un resultado, no una lista. El día que entre `listObjects`
46
+ * ésa sí entra en esta lista.
47
+ */
48
+ export const BUCKET_ITERABLE_OPERATIONS = [];
49
+ /* Ayudantes — repetir el mismo objeto cuatro veces es cómo se desincronizan las
50
+ descripciones. */
51
+ const objectKey = (placeholder) => ({
52
+ name: "key",
53
+ label: "Object key",
54
+ type: "template",
55
+ required: true,
56
+ placeholder,
57
+ description: "La ruta dentro del bucket. Sin barra inicial. Admite {{payload.x}}.",
58
+ });
59
+ export const BUCKET_OPERATION_SPECS = {
60
+ presignDownload: {
61
+ label: "Sign download link",
62
+ description: "Devuelve una URL temporal para descargar un objeto privado. No mueve el fichero.",
63
+ apiRoute: "GET (presigned)",
64
+ params: [
65
+ objectKey("cuadernillos/{{payload.orderId}}.pdf"),
66
+ {
67
+ name: "expiresIn",
68
+ label: "Link valid for (seconds)",
69
+ type: "number",
70
+ required: true,
71
+ default: 3600,
72
+ min: 60,
73
+ /* El tope de SigV4 es de siete días y no se puede pasar: firmar por
74
+ más tiempo produce una URL que el proveedor rechaza, y el error
75
+ llega tarde y sin explicación. */
76
+ max: 604800,
77
+ description: "Desde 60 s hasta 7 días, que es el máximo que admite la firma. Pasado ese plazo el enlace deja de servir.",
78
+ },
79
+ {
80
+ name: "downloadAs",
81
+ label: "Download as (filename)",
82
+ type: "template",
83
+ placeholder: "Cuadernillo 1.pdf",
84
+ description: "Si se rellena, el navegador DESCARGA el fichero con ese nombre en vez de abrirlo. Déjalo vacío para que lo abra.",
85
+ },
86
+ ],
87
+ },
88
+ putObject: {
89
+ label: "Upload object",
90
+ description: "Guarda un objeto en el bucket. Sobreescribe si la clave ya existe.",
91
+ apiRoute: "PUT /{bucket}/{key}",
92
+ params: [
93
+ objectKey("recibos/{{payload.orderId}}.json"),
94
+ {
95
+ name: "body",
96
+ label: "Contents",
97
+ type: "textarea",
98
+ required: true,
99
+ placeholder: "{{payload}}",
100
+ description: "Lo que se guarda. Admite {{payload.x}}; un objeto se guarda como JSON.",
101
+ },
102
+ {
103
+ name: "contentType",
104
+ label: "Content type",
105
+ type: "template",
106
+ default: "application/json",
107
+ placeholder: "application/pdf",
108
+ description: "Lo que el navegador usará para decidir qué hacer con el fichero.",
109
+ },
110
+ ],
111
+ },
112
+ headObject: {
113
+ label: "Check object exists",
114
+ description: "Comprueba si un objeto existe, y su tamaño, sin descargarlo.",
115
+ apiRoute: "HEAD /{bucket}/{key}",
116
+ params: [
117
+ objectKey("cuadernillos/{{payload.orderId}}.pdf"),
118
+ {
119
+ name: "failIfMissing",
120
+ label: "Fail when the object is missing",
121
+ type: "booleanSelect",
122
+ options: [
123
+ { value: "true", label: "Sí — cortar el flujo" },
124
+ { value: "false", label: "No — seguir con exists: false" },
125
+ ],
126
+ description: 'Con "No", el paso sale bien y el de abajo decide. Con "Sí", un objeto que falta corta el flujo.',
127
+ },
128
+ ],
129
+ },
130
+ deleteObject: {
131
+ label: "Delete object",
132
+ description: "Borra un objeto del bucket. No se puede deshacer.",
133
+ apiRoute: "DELETE /{bucket}/{key}",
134
+ params: [objectKey("temporales/{{payload.id}}.tmp")],
135
+ },
136
+ };
@@ -0,0 +1,67 @@
1
+ /**
2
+ * Google Calendar operation enum — single source of truth across the API,
3
+ * Dashboard, and Message Broker. Used by:
4
+ * - calendarAction entity / DTO (api): operation field + validation
5
+ * - dashboard CalendarActionGoogleOperation type
6
+ * - broker hostwebhook types + tool schemas
7
+ * - any future calendar-related node
8
+ *
9
+ * Adding a new Calendar operation = add it here, bump this package's
10
+ * version, publish to npm, and re-install in the consuming repos.
11
+ * Each consumer still owns its operation-specific config schema (the
12
+ * dashboard owns the UI form schema, the api owns the dispatch logic),
13
+ * but the canonical list of valid operation strings lives here.
14
+ */
15
+ export declare const GOOGLE_CALENDAR_OPERATIONS: readonly ["createEvent", "updateEvent", "deleteEvent", "listEvents", "getEvent", "listCalendars", "findFreeSlots", "proposeEvent", "confirmEvent"];
16
+ export type GoogleCalendarOperation = (typeof GOOGLE_CALENDAR_OPERATIONS)[number];
17
+ /** Type guard — useful when validating untrusted input (DTOs, tool calls). */
18
+ export declare function isGoogleCalendarOperation(value: unknown): value is GoogleCalendarOperation;
19
+ export type GoogleCalendarParamTarget = 'eventConfig' | 'listConfig' | 'root';
20
+ export type GoogleCalendarParamType =
21
+ /** Campo de texto con autocompletado de `{{payload.*}}`. */
22
+ 'template' | 'number' | 'select'
23
+ /** El `TimezonePicker` que ya existe en el dashboard. */
24
+ | 'timezone';
25
+ export interface GoogleCalendarParamSpec {
26
+ /** La clave DENTRO de `target`. Es la del cable, no un nombre de UI. */
27
+ name: string;
28
+ /** Dónde vive en la entidad. */
29
+ target: GoogleCalendarParamTarget;
30
+ label: string;
31
+ type: GoogleCalendarParamType;
32
+ required?: boolean;
33
+ /** Texto de ayuda. Llano: el paquete no lleva React. */
34
+ description?: string;
35
+ placeholder?: string;
36
+ default?: string | number;
37
+ options?: ReadonlyArray<{
38
+ value: string;
39
+ label: string;
40
+ }>;
41
+ min?: number;
42
+ max?: number;
43
+ /**
44
+ * Cómo se llama esta misma cosa en el `config` que espera el ejecutor
45
+ * compartido (`google-calendar-operations.service.ts`). El ejecutor está
46
+ * escrito para la ruta del toolkit, donde el LLM manda los nombres **sin**
47
+ * sufijo, así que `summaryTemplate` viaja como `summary`. Sólo lo llevan los
48
+ * params de las operaciones que van por ese despachador.
49
+ */
50
+ execKey?: string;
51
+ }
52
+ export interface GoogleCalendarOperationSpec {
53
+ /** Etiqueta del desplegable, y la misma que pinta el lienzo y el panel. */
54
+ label: string;
55
+ /** Sub-línea del desplegable. */
56
+ description: string;
57
+ /** Método de la API de Google al que corresponde. */
58
+ apiMethod: string;
59
+ /**
60
+ * Si se ejecuta por el despachador genérico (`calendarOps.run`) en vez de por
61
+ * un `case` escrito a mano. Son las cuatro que se abrieron el 2026-08-11.
62
+ */
63
+ viaExecutor?: boolean;
64
+ /** Orden de pantalla. */
65
+ params: GoogleCalendarParamSpec[];
66
+ }
67
+ export declare const GOOGLE_CALENDAR_OPERATION_SPECS: Record<GoogleCalendarOperation, GoogleCalendarOperationSpec>;