@hostwebhook/node-types 1.72.0 → 1.73.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.
@@ -33,6 +33,28 @@
33
33
  * Los `slot` siguen haciendo falta: separan la identidad del documento de los
34
34
  * campos de la operación, aunque ahora las dos vayan debajo del selector. Un
35
35
  * bucle único ordenaría por el array de params y no por ese criterio.
36
+ *
37
+ * ── Qué exige el motor (y por qué está escrito aquí) ──
38
+ * Este esquema declaraba CERO obligatorios en las cinco operaciones, y el
39
+ * ejecutor —`api/src/nodes/docs-actions/docs-actions.service.ts`— rechaza cinco
40
+ * cosas. Esa distancia no se veía como un error de validación sino como un
41
+ * nodo que no guía: sin ningún obligatorio no hay nada que esperar, ningún paso
42
+ * desbloquea al siguiente, y el guiado que el panel SÍ monta no se nota.
43
+ *
44
+ * Los cinco 400 del ejecutor, uno por línea, que son los cinco `required` de
45
+ * este fichero:
46
+ *
47
+ * :323 readDoc documentId 'Document ID is required'
48
+ * :440 appendText documentId 'Document ID is required'
49
+ * :447 appendText contentTemplate 'Content template is required'
50
+ * :498 replaceText documentId 'Document ID is required'
51
+ * :505 replaceText searchText 'Search text is required'
52
+ * :560 insertTable documentId 'Document ID is required'
53
+ *
54
+ * Y los cuatro que NO se marcan, con el defecto que los salva: `documentTitle`
55
+ * cae en `entity.name`, `contentTemplate` de `createDoc` en un documento vacío,
56
+ * `tableRows`/`tableCols` en `|| 3`, y `replaceWith` vacío es un BORRADO, no un
57
+ * hueco. Cada uno lo explica en su sitio.
36
58
  */
37
59
  export declare const DOCS_OPERATIONS: readonly ["readDoc", "createDoc", "appendText", "replaceText", "insertTable"];
38
60
  export type DocsOperation = (typeof DOCS_OPERATIONS)[number];
@@ -67,6 +89,23 @@ export interface DocsParamSpec {
67
89
  label: string;
68
90
  type: DocsParamType;
69
91
  slot: DocsParamSlot;
92
+ /**
93
+ * Lo exige el EJECUTOR: sin él, `docs-actions.service.ts` devuelve un 400 y
94
+ * el nodo no corre.
95
+ *
96
+ * No es «lo que conviene rellenar», y la diferencia importa en las dos
97
+ * direcciones. De menos, un obligatorio que falta deja la familia con cero y
98
+ * `esGuiable` (`check-cuantos-faltan-por-guiar.mjs`) la echa del censo: el
99
+ * panel monta `useGuidedConfig`, pero sin nada que esperar ningún paso
100
+ * desbloquea al siguiente y el guiado se ve como si no existiera — que es el
101
+ * fallo que este campo arregla. De más, marcar algo que el ejecutor SÍ acepta
102
+ * vacío esconde tras un hueco imposible un nodo que habría funcionado, porque
103
+ * `frena()` sólo mira `obligatorio && !contestado`.
104
+ *
105
+ * Por eso cada `required: true` de este fichero apunta a la línea que lo
106
+ * exige, y los que no lo llevan dicen dónde el ejecutor pone su defecto.
107
+ */
108
+ required?: boolean;
70
109
  /** Texto de ayuda. Llano: el paquete no lleva React. */
71
110
  description?: string;
72
111
  placeholder?: string;
@@ -34,6 +34,28 @@
34
34
  * Los `slot` siguen haciendo falta: separan la identidad del documento de los
35
35
  * campos de la operación, aunque ahora las dos vayan debajo del selector. Un
36
36
  * bucle único ordenaría por el array de params y no por ese criterio.
37
+ *
38
+ * ── Qué exige el motor (y por qué está escrito aquí) ──
39
+ * Este esquema declaraba CERO obligatorios en las cinco operaciones, y el
40
+ * ejecutor —`api/src/nodes/docs-actions/docs-actions.service.ts`— rechaza cinco
41
+ * cosas. Esa distancia no se veía como un error de validación sino como un
42
+ * nodo que no guía: sin ningún obligatorio no hay nada que esperar, ningún paso
43
+ * desbloquea al siguiente, y el guiado que el panel SÍ monta no se nota.
44
+ *
45
+ * Los cinco 400 del ejecutor, uno por línea, que son los cinco `required` de
46
+ * este fichero:
47
+ *
48
+ * :323 readDoc documentId 'Document ID is required'
49
+ * :440 appendText documentId 'Document ID is required'
50
+ * :447 appendText contentTemplate 'Content template is required'
51
+ * :498 replaceText documentId 'Document ID is required'
52
+ * :505 replaceText searchText 'Search text is required'
53
+ * :560 insertTable documentId 'Document ID is required'
54
+ *
55
+ * Y los cuatro que NO se marcan, con el defecto que los salva: `documentTitle`
56
+ * cae en `entity.name`, `contentTemplate` de `createDoc` en un documento vacío,
57
+ * `tableRows`/`tableCols` en `|| 3`, y `replaceWith` vacío es un BORRADO, no un
58
+ * hueco. Cada uno lo explica en su sitio.
37
59
  */
38
60
  Object.defineProperty(exports, "__esModule", { value: true });
39
61
  exports.DOCS_OPERATION_SPECS = exports.DOCS_OPERATIONS = void 0;
@@ -50,19 +72,42 @@ function isDocsOperation(value) {
50
72
  return typeof value === 'string' && exports.DOCS_OPERATIONS.includes(value);
51
73
  }
52
74
  /* Los campos que comparten varias operaciones. */
75
+ /**
76
+ * `required: true` va aquí y no operación por operación porque las CUATRO que
77
+ * lo usan lo exigen: `executeRead` (:323), `executeAppend` (:440),
78
+ * `executeReplace` (:498) y `executeInsertTable` (:560) devuelven todas el
79
+ * mismo 400, «Document ID is required». La quinta, `createDoc`, no llama a este
80
+ * ayudante — el documento aún no existe.
81
+ */
53
82
  const documentId = () => ({
54
83
  name: 'documentId',
55
84
  label: 'Or paste Document ID / template',
56
85
  type: 'docPicker',
57
86
  slot: 'document',
87
+ required: true,
58
88
  placeholder: '1BxiMVs0XRA5nFMdKvBd... or {{payload.documentId}}',
59
89
  });
60
- const contentTemplate = () => ({
90
+ /**
91
+ * Éste NO puede llevar `required` en el ayudante, y es la única asimetría del
92
+ * fichero: sus dos usuarios no piden lo mismo.
93
+ *
94
+ * `appendText` lo exige (`executeAppend` :447, «Content template is required»):
95
+ * añadir la cadena vacía al final de un documento no es una operación, es un
96
+ * viaje a Google para no hacer nada. `createDoc` no (`executeCreate` :362 lo
97
+ * lee con un ternario y :375 sólo inserta `if (content)`): un documento nuevo y
98
+ * vacío es un resultado legítimo, y bloquearlo sería inventarse un requisito
99
+ * que la api no tiene.
100
+ *
101
+ * De ahí el `over`, como el `columnMapping` de Sheets: el que lo exige lo dice
102
+ * en su sitio.
103
+ */
104
+ const contentTemplate = (over = {}) => ({
61
105
  name: 'contentTemplate',
62
106
  label: 'Content',
63
107
  type: 'htmlTemplate',
64
108
  slot: 'config',
65
109
  placeholder: 'Text to insert... supports {{payload.x}} templates',
110
+ ...over,
66
111
  });
67
112
  exports.DOCS_OPERATION_SPECS = {
68
113
  readDoc: {
@@ -77,13 +122,22 @@ exports.DOCS_OPERATION_SPECS = {
77
122
  labelShort: 'Create',
78
123
  description: 'Create a new Google Doc',
79
124
  /* La única SIN `documentId`: aquí el documento no existe todavía. Eso es lo
80
- que en la página eran dos compuertas negadas (`!== "createDoc"`). */
125
+ que en la página eran dos compuertas negadas (`!== "createDoc"`).
126
+
127
+ Y la única con CERO obligatorios, porque el ejecutor no exige ninguno:
128
+ `executeCreate` no tiene un solo `return 400`. Un `createDoc` sin nada
129
+ contestado corre y crea un documento vacío con el nombre del nodo. */
81
130
  params: [
82
131
  {
83
132
  name: 'documentTitle',
84
133
  label: 'Document Title',
85
134
  type: 'template',
86
135
  slot: 'document',
136
+ /* Opcional a propósito: `executeCreate` (:361) lo lee como
137
+ `render(entity.documentTitle || entity.name)`. Sin título el
138
+ documento sale con el NOMBRE DEL NODO, que es un defecto de verdad y
139
+ no un descuido. Marcarlo obligatorio pararía la guía delante de un
140
+ campo que la api sabe rellenar sola. */
87
141
  placeholder: 'Report — {{payload.date}} or My Document',
88
142
  },
89
143
  contentTemplate(),
@@ -93,7 +147,7 @@ exports.DOCS_OPERATION_SPECS = {
93
147
  label: 'Append Text',
94
148
  labelShort: 'Append',
95
149
  description: 'Add text to end of document',
96
- params: [documentId(), contentTemplate()],
150
+ params: [documentId(), contentTemplate({ required: true })],
97
151
  },
98
152
  replaceText: {
99
153
  label: 'Replace Text',
@@ -106,6 +160,9 @@ exports.DOCS_OPERATION_SPECS = {
106
160
  label: 'Search Text',
107
161
  type: 'template',
108
162
  slot: 'config',
163
+ /* `executeReplace` (:505): «Search text is required». Sin qué buscar,
164
+ `replaceAllText` no tiene nada que hacer. */
165
+ required: true,
109
166
  placeholder: '{{PLACEHOLDER}} or text to find',
110
167
  },
111
168
  {
@@ -113,6 +170,11 @@ exports.DOCS_OPERATION_SPECS = {
113
170
  label: 'Replace With',
114
171
  type: 'template',
115
172
  slot: 'config',
173
+ /* Opcional, y aquí el vacío SIGNIFICA algo: `executeReplace` lo pasa
174
+ tal cual a `replaceAllText`, así que dejarlo en blanco BORRA todas
175
+ las apariciones de `searchText`. Es la única forma de pedir un
176
+ borrado, y por eso el ejecutor no lo comprueba: hacerlo obligatorio
177
+ quitaría una operación que hoy funciona. */
116
178
  placeholder: '{{payload.value}} or replacement text',
117
179
  },
118
180
  ],
@@ -123,7 +185,15 @@ exports.DOCS_OPERATION_SPECS = {
123
185
  description: 'Insert a table at end of document',
124
186
  params: [
125
187
  documentId(),
126
- /* Los topes son distintos y no es un descuido: 50 filas, 20 columnas. */
188
+ /* Los topes son distintos y no es un descuido: 50 filas, 20 columnas.
189
+
190
+ Y los dos siguen OPCIONALES teniendo `default: 3`, que es justo el
191
+ caso que el contrato vigila: `executeInsertTable` (:555) los lee con
192
+ `entity.tableRows || 3`, o sea que el 3×3 lo pone la api tanto si el
193
+ formulario lo manda como si no. Un obligatorio con `default` sería
194
+ además la trampa de la regla 10 — `defectoPintable` le borra el
195
+ `default` para no pintar como contestado algo que nadie eligió, y
196
+ estos dos sí quieren pintarlo. */
127
197
  { name: 'tableRows', label: 'Rows', type: 'number', slot: 'config', min: 1, max: 50, default: 3 },
128
198
  { name: 'tableCols', label: 'Columns', type: 'number', slot: 'config', min: 1, max: 20, default: 3 },
129
199
  ],
@@ -33,6 +33,28 @@
33
33
  * Los `slot` siguen haciendo falta: separan la identidad del documento de los
34
34
  * campos de la operación, aunque ahora las dos vayan debajo del selector. Un
35
35
  * bucle único ordenaría por el array de params y no por ese criterio.
36
+ *
37
+ * ── Qué exige el motor (y por qué está escrito aquí) ──
38
+ * Este esquema declaraba CERO obligatorios en las cinco operaciones, y el
39
+ * ejecutor —`api/src/nodes/docs-actions/docs-actions.service.ts`— rechaza cinco
40
+ * cosas. Esa distancia no se veía como un error de validación sino como un
41
+ * nodo que no guía: sin ningún obligatorio no hay nada que esperar, ningún paso
42
+ * desbloquea al siguiente, y el guiado que el panel SÍ monta no se nota.
43
+ *
44
+ * Los cinco 400 del ejecutor, uno por línea, que son los cinco `required` de
45
+ * este fichero:
46
+ *
47
+ * :323 readDoc documentId 'Document ID is required'
48
+ * :440 appendText documentId 'Document ID is required'
49
+ * :447 appendText contentTemplate 'Content template is required'
50
+ * :498 replaceText documentId 'Document ID is required'
51
+ * :505 replaceText searchText 'Search text is required'
52
+ * :560 insertTable documentId 'Document ID is required'
53
+ *
54
+ * Y los cuatro que NO se marcan, con el defecto que los salva: `documentTitle`
55
+ * cae en `entity.name`, `contentTemplate` de `createDoc` en un documento vacío,
56
+ * `tableRows`/`tableCols` en `|| 3`, y `replaceWith` vacío es un BORRADO, no un
57
+ * hueco. Cada uno lo explica en su sitio.
36
58
  */
37
59
  export declare const DOCS_OPERATIONS: readonly ["readDoc", "createDoc", "appendText", "replaceText", "insertTable"];
38
60
  export type DocsOperation = (typeof DOCS_OPERATIONS)[number];
@@ -67,6 +89,23 @@ export interface DocsParamSpec {
67
89
  label: string;
68
90
  type: DocsParamType;
69
91
  slot: DocsParamSlot;
92
+ /**
93
+ * Lo exige el EJECUTOR: sin él, `docs-actions.service.ts` devuelve un 400 y
94
+ * el nodo no corre.
95
+ *
96
+ * No es «lo que conviene rellenar», y la diferencia importa en las dos
97
+ * direcciones. De menos, un obligatorio que falta deja la familia con cero y
98
+ * `esGuiable` (`check-cuantos-faltan-por-guiar.mjs`) la echa del censo: el
99
+ * panel monta `useGuidedConfig`, pero sin nada que esperar ningún paso
100
+ * desbloquea al siguiente y el guiado se ve como si no existiera — que es el
101
+ * fallo que este campo arregla. De más, marcar algo que el ejecutor SÍ acepta
102
+ * vacío esconde tras un hueco imposible un nodo que habría funcionado, porque
103
+ * `frena()` sólo mira `obligatorio && !contestado`.
104
+ *
105
+ * Por eso cada `required: true` de este fichero apunta a la línea que lo
106
+ * exige, y los que no lo llevan dicen dónde el ejecutor pone su defecto.
107
+ */
108
+ required?: boolean;
70
109
  /** Texto de ayuda. Llano: el paquete no lleva React. */
71
110
  description?: string;
72
111
  placeholder?: string;
@@ -33,6 +33,28 @@
33
33
  * Los `slot` siguen haciendo falta: separan la identidad del documento de los
34
34
  * campos de la operación, aunque ahora las dos vayan debajo del selector. Un
35
35
  * bucle único ordenaría por el array de params y no por ese criterio.
36
+ *
37
+ * ── Qué exige el motor (y por qué está escrito aquí) ──
38
+ * Este esquema declaraba CERO obligatorios en las cinco operaciones, y el
39
+ * ejecutor —`api/src/nodes/docs-actions/docs-actions.service.ts`— rechaza cinco
40
+ * cosas. Esa distancia no se veía como un error de validación sino como un
41
+ * nodo que no guía: sin ningún obligatorio no hay nada que esperar, ningún paso
42
+ * desbloquea al siguiente, y el guiado que el panel SÍ monta no se nota.
43
+ *
44
+ * Los cinco 400 del ejecutor, uno por línea, que son los cinco `required` de
45
+ * este fichero:
46
+ *
47
+ * :323 readDoc documentId 'Document ID is required'
48
+ * :440 appendText documentId 'Document ID is required'
49
+ * :447 appendText contentTemplate 'Content template is required'
50
+ * :498 replaceText documentId 'Document ID is required'
51
+ * :505 replaceText searchText 'Search text is required'
52
+ * :560 insertTable documentId 'Document ID is required'
53
+ *
54
+ * Y los cuatro que NO se marcan, con el defecto que los salva: `documentTitle`
55
+ * cae en `entity.name`, `contentTemplate` de `createDoc` en un documento vacío,
56
+ * `tableRows`/`tableCols` en `|| 3`, y `replaceWith` vacío es un BORRADO, no un
57
+ * hueco. Cada uno lo explica en su sitio.
36
58
  */
37
59
  export const DOCS_OPERATIONS = [
38
60
  'readDoc', // leer el contenido como texto plano
@@ -46,19 +68,42 @@ export function isDocsOperation(value) {
46
68
  return typeof value === 'string' && DOCS_OPERATIONS.includes(value);
47
69
  }
48
70
  /* Los campos que comparten varias operaciones. */
71
+ /**
72
+ * `required: true` va aquí y no operación por operación porque las CUATRO que
73
+ * lo usan lo exigen: `executeRead` (:323), `executeAppend` (:440),
74
+ * `executeReplace` (:498) y `executeInsertTable` (:560) devuelven todas el
75
+ * mismo 400, «Document ID is required». La quinta, `createDoc`, no llama a este
76
+ * ayudante — el documento aún no existe.
77
+ */
49
78
  const documentId = () => ({
50
79
  name: 'documentId',
51
80
  label: 'Or paste Document ID / template',
52
81
  type: 'docPicker',
53
82
  slot: 'document',
83
+ required: true,
54
84
  placeholder: '1BxiMVs0XRA5nFMdKvBd... or {{payload.documentId}}',
55
85
  });
56
- const contentTemplate = () => ({
86
+ /**
87
+ * Éste NO puede llevar `required` en el ayudante, y es la única asimetría del
88
+ * fichero: sus dos usuarios no piden lo mismo.
89
+ *
90
+ * `appendText` lo exige (`executeAppend` :447, «Content template is required»):
91
+ * añadir la cadena vacía al final de un documento no es una operación, es un
92
+ * viaje a Google para no hacer nada. `createDoc` no (`executeCreate` :362 lo
93
+ * lee con un ternario y :375 sólo inserta `if (content)`): un documento nuevo y
94
+ * vacío es un resultado legítimo, y bloquearlo sería inventarse un requisito
95
+ * que la api no tiene.
96
+ *
97
+ * De ahí el `over`, como el `columnMapping` de Sheets: el que lo exige lo dice
98
+ * en su sitio.
99
+ */
100
+ const contentTemplate = (over = {}) => ({
57
101
  name: 'contentTemplate',
58
102
  label: 'Content',
59
103
  type: 'htmlTemplate',
60
104
  slot: 'config',
61
105
  placeholder: 'Text to insert... supports {{payload.x}} templates',
106
+ ...over,
62
107
  });
63
108
  export const DOCS_OPERATION_SPECS = {
64
109
  readDoc: {
@@ -73,13 +118,22 @@ export const DOCS_OPERATION_SPECS = {
73
118
  labelShort: 'Create',
74
119
  description: 'Create a new Google Doc',
75
120
  /* La única SIN `documentId`: aquí el documento no existe todavía. Eso es lo
76
- que en la página eran dos compuertas negadas (`!== "createDoc"`). */
121
+ que en la página eran dos compuertas negadas (`!== "createDoc"`).
122
+
123
+ Y la única con CERO obligatorios, porque el ejecutor no exige ninguno:
124
+ `executeCreate` no tiene un solo `return 400`. Un `createDoc` sin nada
125
+ contestado corre y crea un documento vacío con el nombre del nodo. */
77
126
  params: [
78
127
  {
79
128
  name: 'documentTitle',
80
129
  label: 'Document Title',
81
130
  type: 'template',
82
131
  slot: 'document',
132
+ /* Opcional a propósito: `executeCreate` (:361) lo lee como
133
+ `render(entity.documentTitle || entity.name)`. Sin título el
134
+ documento sale con el NOMBRE DEL NODO, que es un defecto de verdad y
135
+ no un descuido. Marcarlo obligatorio pararía la guía delante de un
136
+ campo que la api sabe rellenar sola. */
83
137
  placeholder: 'Report — {{payload.date}} or My Document',
84
138
  },
85
139
  contentTemplate(),
@@ -89,7 +143,7 @@ export const DOCS_OPERATION_SPECS = {
89
143
  label: 'Append Text',
90
144
  labelShort: 'Append',
91
145
  description: 'Add text to end of document',
92
- params: [documentId(), contentTemplate()],
146
+ params: [documentId(), contentTemplate({ required: true })],
93
147
  },
94
148
  replaceText: {
95
149
  label: 'Replace Text',
@@ -102,6 +156,9 @@ export const DOCS_OPERATION_SPECS = {
102
156
  label: 'Search Text',
103
157
  type: 'template',
104
158
  slot: 'config',
159
+ /* `executeReplace` (:505): «Search text is required». Sin qué buscar,
160
+ `replaceAllText` no tiene nada que hacer. */
161
+ required: true,
105
162
  placeholder: '{{PLACEHOLDER}} or text to find',
106
163
  },
107
164
  {
@@ -109,6 +166,11 @@ export const DOCS_OPERATION_SPECS = {
109
166
  label: 'Replace With',
110
167
  type: 'template',
111
168
  slot: 'config',
169
+ /* Opcional, y aquí el vacío SIGNIFICA algo: `executeReplace` lo pasa
170
+ tal cual a `replaceAllText`, así que dejarlo en blanco BORRA todas
171
+ las apariciones de `searchText`. Es la única forma de pedir un
172
+ borrado, y por eso el ejecutor no lo comprueba: hacerlo obligatorio
173
+ quitaría una operación que hoy funciona. */
112
174
  placeholder: '{{payload.value}} or replacement text',
113
175
  },
114
176
  ],
@@ -119,7 +181,15 @@ export const DOCS_OPERATION_SPECS = {
119
181
  description: 'Insert a table at end of document',
120
182
  params: [
121
183
  documentId(),
122
- /* Los topes son distintos y no es un descuido: 50 filas, 20 columnas. */
184
+ /* Los topes son distintos y no es un descuido: 50 filas, 20 columnas.
185
+
186
+ Y los dos siguen OPCIONALES teniendo `default: 3`, que es justo el
187
+ caso que el contrato vigila: `executeInsertTable` (:555) los lee con
188
+ `entity.tableRows || 3`, o sea que el 3×3 lo pone la api tanto si el
189
+ formulario lo manda como si no. Un obligatorio con `default` sería
190
+ además la trampa de la regla 10 — `defectoPintable` le borra el
191
+ `default` para no pintar como contestado algo que nadie eligió, y
192
+ estos dos sí quieren pintarlo. */
123
193
  { name: 'tableRows', label: 'Rows', type: 'number', slot: 'config', min: 1, max: 50, default: 3 },
124
194
  { name: 'tableCols', label: 'Columns', type: 'number', slot: 'config', min: 1, max: 20, default: 3 },
125
195
  ],
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hostwebhook/node-types",
3
- "version": "1.72.0",
3
+ "version": "1.73.0",
4
4
  "description": "Shared node type definitions, connection rules, and dispatch config for HostWebhook",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/esm/index.js",