@hostwebhook/node-types 1.70.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.
@@ -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
+ };
@@ -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 },
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' },
@@ -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
+ };
@@ -73,6 +73,7 @@ export const NODE_CONNECTIONS = {
73
73
  shopifyAction: { acceptsInputFrom: ACTION_INPUTS, canOutputTo: PROCESSING_OUTPUTS },
74
74
  githubAction: { acceptsInputFrom: ACTION_INPUTS, canOutputTo: PROCESSING_OUTPUTS },
75
75
  jiraAction: { acceptsInputFrom: ACTION_INPUTS, canOutputTo: PROCESSING_OUTPUTS },
76
+ bucketAction: { acceptsInputFrom: ACTION_INPUTS, canOutputTo: PROCESSING_OUTPUTS },
76
77
  googleContactsAction: { acceptsInputFrom: ACTION_INPUTS, canOutputTo: PROCESSING_OUTPUTS },
77
78
  googleAnalyticsAction: { acceptsInputFrom: ACTION_INPUTS, canOutputTo: PROCESSING_OUTPUTS },
78
79
  notionAction: { acceptsInputFrom: ACTION_INPUTS, canOutputTo: PROCESSING_OUTPUTS },
@@ -51,6 +51,7 @@ export const NODE_DISPATCH = {
51
51
  shopifyAction: { service: 'shopifyActionsService', collection: 'shopifyactions', hasFilters: true, outputFields: ['outputNodes'], customDispatch: true, pipelineDispatch: 'excluded' },
52
52
  githubAction: { service: 'githubActionsService', collection: 'githubactions', hasFilters: true, outputFields: ['outputNodes'], customDispatch: true, pipelineDispatch: 'excluded' },
53
53
  jiraAction: { service: 'jiraActionsService', collection: 'jiraactions', hasFilters: true, outputFields: ['outputNodes'], customDispatch: true, pipelineDispatch: 'excluded' },
54
+ bucketAction: { service: 'bucketActionsService', collection: 'bucketactions', hasFilters: true, outputFields: ['outputNodes'], customDispatch: true, pipelineDispatch: 'excluded' },
54
55
  slackAction: { service: 'slackActionsService', collection: 'slackactions', hasFilters: true, outputFields: ['outputNodes'], customDispatch: true, pipelineDispatch: 'excluded' },
55
56
  googleContactsAction: { service: 'googleContactsActionsService', collection: 'googlecontactsactions', hasFilters: true, outputFields: ['outputNodes'], customDispatch: true, pipelineDispatch: 'excluded' },
56
57
  googleAnalyticsAction: { service: 'googleAnalyticsActionsService', collection: 'googleanalyticsactions', hasFilters: true, outputFields: ['outputNodes'], customDispatch: true, pipelineDispatch: 'excluded' },
@@ -36,6 +36,8 @@ export { GITHUB_OPERATIONS, GITHUB_OPERATION_SPECS, GITHUB_DROPDOWN_OPERATIONS,
36
36
  export type { GithubOperation, GithubParamType, GithubParamSpec, GithubOperationSpec, } from './github-operations.js';
37
37
  export { JIRA_OPERATIONS, JIRA_OPERATION_SPECS, JIRA_DROPDOWN_OPERATIONS, JIRA_ITERABLE_OPERATIONS, isJiraOperation, } from './jira-operations.js';
38
38
  export type { JiraOperation, JiraParamType, JiraParamSpec, JiraOperationSpec, } from './jira-operations.js';
39
+ export { BUCKET_OPERATIONS, BUCKET_OPERATION_SPECS, BUCKET_ITERABLE_OPERATIONS, isBucketOperation, } from './bucket-operations.js';
40
+ export type { BucketOperation, BucketParamType, BucketParamSpec, BucketOperationSpec, } from './bucket-operations.js';
39
41
  export { SLACK_OPERATIONS, SLACK_OPERATION_SPECS, SLACK_CAPACIDADES_POR_CREDENCIAL, operacionesDeSlackPara, slackPuedeEjecutar, camposDeSlackNoDisponibles, isSlackOperation, } from './slack-operations.js';
40
42
  export type { SlackOperation, SlackParamSpec, SlackOperationSpec, } from './slack-operations.js';
41
43
  export { SLACK_TOOLKIT_SPECS, SLACK_TOOLKIT_BY_TOOL_NAME, herramientasDeSlackPara, } from './slack-toolkit.js';
package/dist/esm/index.js CHANGED
@@ -32,6 +32,7 @@ export { MAILCHIMP_OPERATIONS, MAILCHIMP_OPERATION_SPECS, MAILCHIMP_CONTACT_STAT
32
32
  export { SHOPIFY_OPERATIONS, SHOPIFY_OPERATION_SPECS, SHOPIFY_TAGGABLE_RESOURCES, SHOPIFY_SEARCHABLE_RESOURCES, isShopifyOperation, } from './shopify-operations.js';
33
33
  export { GITHUB_OPERATIONS, GITHUB_OPERATION_SPECS, GITHUB_DROPDOWN_OPERATIONS, GITHUB_ITERABLE_OPERATIONS, isGithubOperation, } from './github-operations.js';
34
34
  export { JIRA_OPERATIONS, JIRA_OPERATION_SPECS, JIRA_DROPDOWN_OPERATIONS, JIRA_ITERABLE_OPERATIONS, isJiraOperation, } from './jira-operations.js';
35
+ export { BUCKET_OPERATIONS, BUCKET_OPERATION_SPECS, BUCKET_ITERABLE_OPERATIONS, isBucketOperation, } from './bucket-operations.js';
35
36
  export { SLACK_OPERATIONS, SLACK_OPERATION_SPECS, SLACK_CAPACIDADES_POR_CREDENCIAL, operacionesDeSlackPara, slackPuedeEjecutar, camposDeSlackNoDisponibles, isSlackOperation, } from './slack-operations.js';
36
37
  /* Misma pareja que en Discord: `SlackOperationSpec` es el formulario,
37
38
  `SlackToolkitSpec` es la herramienta que ve el LLM. */
@@ -5,8 +5,8 @@
5
5
  * all per-node maps (colors, URLs, Redux keys, palette, delete, etc.)
6
6
  * from this registry. No more 18+ touch points.
7
7
  */
8
- import type { NodeType } from './types.js';
9
- export type NodeGroup = 'Sources' | 'Flow Control' | 'Actions' | 'Annotations';
8
+ import type { NodeType } from "./types.js";
9
+ export type NodeGroup = "Sources" | "Flow Control" | "Actions" | "Annotations";
10
10
  export interface NodeRegistryEntry {
11
11
  /** Canonical type (e.g., "httpAction") */
12
12
  type: NodeType;
@@ -69,7 +69,7 @@ export interface NodeVersionSpec {
69
69
  * `current` is what a new node is born on — exactly one per type.
70
70
  * `legacy` still runs but is on its way out. `beta` is opt-in.
71
71
  */
72
- status: 'current' | 'legacy' | 'beta';
72
+ status: "current" | "legacy" | "beta";
73
73
  /**
74
74
  * The config fields this version understands.
75
75
  *
@@ -106,7 +106,7 @@ export declare const NODE_TYPE_TO_PREFIX: Record<string, string>;
106
106
  * pass it, and the tests can exercise a versioned type without waiting
107
107
  * for a real one to exist.
108
108
  */
109
- export type VersionCatalog = Record<string, Pick<NodeRegistryEntry, 'type' | 'versions'>>;
109
+ export type VersionCatalog = Record<string, Pick<NodeRegistryEntry, "type" | "versions">>;
110
110
  /** True when this type ships more than one version. False for every type today. */
111
111
  export declare function isVersioned(type: string, catalog?: VersionCatalog): boolean;
112
112
  /**