n8n-nodes-hudu 1.3.5 → 1.4.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 (96) hide show
  1. package/README.md +9 -7
  2. package/dist/nodes/Hudu/Hudu.node.js +2 -18
  3. package/dist/nodes/Hudu/Hudu.node.js.map +1 -1
  4. package/dist/nodes/Hudu/Hudu.node.ts +2 -30
  5. package/dist/nodes/Hudu/descriptions/asset_layouts.description.js +99 -10
  6. package/dist/nodes/Hudu/descriptions/asset_layouts.description.js.map +1 -1
  7. package/dist/nodes/Hudu/descriptions/asset_layouts.description.ts +99 -10
  8. package/dist/nodes/Hudu/descriptions/assets.description.js +38 -137
  9. package/dist/nodes/Hudu/descriptions/assets.description.js.map +1 -1
  10. package/dist/nodes/Hudu/descriptions/assets.description.ts +511 -609
  11. package/dist/nodes/Hudu/descriptions/index.js +0 -3
  12. package/dist/nodes/Hudu/descriptions/index.js.map +1 -1
  13. package/dist/nodes/Hudu/descriptions/index.ts +0 -3
  14. package/dist/nodes/Hudu/descriptions/resources.js +0 -12
  15. package/dist/nodes/Hudu/descriptions/resources.js.map +1 -1
  16. package/dist/nodes/Hudu/descriptions/resources.ts +0 -12
  17. package/dist/nodes/Hudu/optionLoaders/asset_layouts/getAssetLayoutFields.js +122 -70
  18. package/dist/nodes/Hudu/optionLoaders/asset_layouts/getAssetLayoutFields.js.map +1 -1
  19. package/dist/nodes/Hudu/optionLoaders/asset_layouts/getAssetLayoutFields.ts +143 -107
  20. package/dist/nodes/Hudu/optionLoaders/asset_layouts/index.js +0 -1
  21. package/dist/nodes/Hudu/optionLoaders/asset_layouts/index.js.map +1 -1
  22. package/dist/nodes/Hudu/optionLoaders/asset_layouts/index.ts +0 -1
  23. package/dist/nodes/Hudu/optionLoaders/assets/index.js +1 -2
  24. package/dist/nodes/Hudu/optionLoaders/assets/index.js.map +1 -1
  25. package/dist/nodes/Hudu/optionLoaders/assets/index.ts +1 -2
  26. package/dist/nodes/Hudu/resources/asset_layouts/asset_layouts.handler.js +11 -9
  27. package/dist/nodes/Hudu/resources/asset_layouts/asset_layouts.handler.js.map +1 -1
  28. package/dist/nodes/Hudu/resources/asset_layouts/asset_layouts.handler.ts +13 -10
  29. package/dist/nodes/Hudu/resources/assets/assets.handler.js +116 -50
  30. package/dist/nodes/Hudu/resources/assets/assets.handler.js.map +1 -1
  31. package/dist/nodes/Hudu/resources/assets/assets.handler.ts +172 -51
  32. package/dist/nodes/Hudu/resources/assets/assets.types.ts +43 -43
  33. package/dist/nodes/Hudu/resources/index.js +0 -6
  34. package/dist/nodes/Hudu/resources/index.js.map +1 -1
  35. package/dist/nodes/Hudu/resources/index.ts +0 -12
  36. package/dist/nodes/Hudu/utils/assetFieldUtils.js +273 -0
  37. package/dist/nodes/Hudu/utils/assetFieldUtils.js.map +1 -0
  38. package/dist/nodes/Hudu/utils/assetFieldUtils.ts +437 -0
  39. package/dist/nodes/Hudu/utils/constants.js +1 -0
  40. package/dist/nodes/Hudu/utils/constants.js.map +1 -1
  41. package/dist/nodes/Hudu/utils/constants.ts +1 -0
  42. package/dist/nodes/Hudu/utils/debugConfig.js +7 -4
  43. package/dist/nodes/Hudu/utils/debugConfig.js.map +1 -1
  44. package/dist/nodes/Hudu/utils/debugConfig.ts +9 -4
  45. package/dist/nodes/Hudu/utils/errorParser.js +57 -0
  46. package/dist/nodes/Hudu/utils/errorParser.js.map +1 -0
  47. package/dist/nodes/Hudu/utils/errorParser.ts +90 -0
  48. package/dist/nodes/Hudu/utils/fieldErrorUtils.js +17 -0
  49. package/dist/nodes/Hudu/utils/fieldErrorUtils.js.map +1 -0
  50. package/dist/nodes/Hudu/utils/fieldErrorUtils.ts +57 -0
  51. package/dist/nodes/Hudu/utils/fieldTypeUtils.js +145 -0
  52. package/dist/nodes/Hudu/utils/fieldTypeUtils.js.map +1 -0
  53. package/dist/nodes/Hudu/utils/fieldTypeUtils.ts +220 -0
  54. package/dist/nodes/Hudu/utils/index.js +3 -0
  55. package/dist/nodes/Hudu/utils/index.js.map +1 -1
  56. package/dist/nodes/Hudu/utils/index.ts +25 -19
  57. package/dist/nodes/Hudu/utils/requestUtils.js +71 -24
  58. package/dist/nodes/Hudu/utils/requestUtils.js.map +1 -1
  59. package/dist/nodes/Hudu/utils/requestUtils.ts +88 -26
  60. package/package.json +1 -1
  61. package/dist/nodes/Hudu/descriptions/HuduAssetCustomFieldDescription.js +0 -75
  62. package/dist/nodes/Hudu/descriptions/HuduAssetCustomFieldDescription.js.map +0 -1
  63. package/dist/nodes/Hudu/descriptions/HuduAssetCustomFieldDescription.ts +0 -73
  64. package/dist/nodes/Hudu/descriptions/HuduAssetLinkFieldDescription.js +0 -77
  65. package/dist/nodes/Hudu/descriptions/HuduAssetLinkFieldDescription.js.map +0 -1
  66. package/dist/nodes/Hudu/descriptions/HuduAssetLinkFieldDescription.ts +0 -75
  67. package/dist/nodes/Hudu/descriptions/HuduAssetStandardFieldDescription.js +0 -74
  68. package/dist/nodes/Hudu/descriptions/HuduAssetStandardFieldDescription.js.map +0 -1
  69. package/dist/nodes/Hudu/descriptions/HuduAssetStandardFieldDescription.ts +0 -72
  70. package/dist/nodes/Hudu/optionLoaders/asset_layouts/getAssetLinkFields.js +0 -51
  71. package/dist/nodes/Hudu/optionLoaders/asset_layouts/getAssetLinkFields.js.map +0 -1
  72. package/dist/nodes/Hudu/optionLoaders/asset_layouts/getAssetLinkFields.ts +0 -70
  73. package/dist/nodes/Hudu/optionLoaders/assets/getAssetCustomFields.js +0 -71
  74. package/dist/nodes/Hudu/optionLoaders/assets/getAssetCustomFields.js.map +0 -1
  75. package/dist/nodes/Hudu/optionLoaders/assets/getAssetCustomFields.ts +0 -80
  76. package/dist/nodes/Hudu/optionLoaders/assets/getLinkableAssets.js +0 -117
  77. package/dist/nodes/Hudu/optionLoaders/assets/getLinkableAssets.js.map +0 -1
  78. package/dist/nodes/Hudu/optionLoaders/assets/getLinkableAssets.ts +0 -147
  79. package/dist/nodes/Hudu/resources/assetCustomField/assetCustomField.handler.js +0 -222
  80. package/dist/nodes/Hudu/resources/assetCustomField/assetCustomField.handler.js.map +0 -1
  81. package/dist/nodes/Hudu/resources/assetCustomField/assetCustomField.handler.ts +0 -293
  82. package/dist/nodes/Hudu/resources/assetCustomField/assetCustomField.types.js +0 -3
  83. package/dist/nodes/Hudu/resources/assetCustomField/assetCustomField.types.js.map +0 -1
  84. package/dist/nodes/Hudu/resources/assetCustomField/assetCustomField.types.ts +0 -1
  85. package/dist/nodes/Hudu/resources/assetLinkField/assetLinkField.handler.js +0 -262
  86. package/dist/nodes/Hudu/resources/assetLinkField/assetLinkField.handler.js.map +0 -1
  87. package/dist/nodes/Hudu/resources/assetLinkField/assetLinkField.handler.ts +0 -363
  88. package/dist/nodes/Hudu/resources/assetLinkField/assetLinkField.types.js +0 -3
  89. package/dist/nodes/Hudu/resources/assetLinkField/assetLinkField.types.js.map +0 -1
  90. package/dist/nodes/Hudu/resources/assetLinkField/assetLinkField.types.ts +0 -1
  91. package/dist/nodes/Hudu/resources/assetStandardField/assetStandardField.handler.js +0 -93
  92. package/dist/nodes/Hudu/resources/assetStandardField/assetStandardField.handler.js.map +0 -1
  93. package/dist/nodes/Hudu/resources/assetStandardField/assetStandardField.handler.ts +0 -141
  94. package/dist/nodes/Hudu/resources/assetStandardField/assetStandardField.types.js +0 -3
  95. package/dist/nodes/Hudu/resources/assetStandardField/assetStandardField.types.js.map +0 -1
  96. package/dist/nodes/Hudu/resources/assetStandardField/assetStandardField.types.ts +0 -1
@@ -1,293 +0,0 @@
1
- import type { IExecuteFunctions, IDataObject } from 'n8n-workflow';
2
- import { NodeOperationError } from 'n8n-workflow';
3
- import { huduApiRequest } from '../../utils/requestUtils';
4
- import type { AssetCustomFieldOperation } from './assetCustomField.types';
5
- import { ASSET_LAYOUT_FIELD_TYPES } from '../../utils/constants';
6
- import { debugLog } from '../../utils/debugConfig';
7
-
8
- /**
9
- * Handles operations for asset custom fields in Hudu
10
- *
11
- * This handler manages custom fields for assets, which are user-defined fields
12
- * that appear in the asset fields array rather than as top-level properties.
13
- * Custom fields are stored in the Hudu API using snake_case versions of their labels.
14
- *
15
- * Different field types require special handling:
16
- * - Date fields: Require formatting as YYYY-MM-DD for the API
17
- * - CheckBox fields: Require boolean values
18
- * - Number fields: Require numeric values
19
- * - RichText fields: Support HTML markup
20
- * - Password fields: Treated as sensitive data
21
- *
22
- * @param operation - The operation to perform (get/update)
23
- * @param itemIndex - The index of the current item being processed
24
- * @returns The result of the operation
25
- */
26
- export async function handleAssetCustomFieldOperation(
27
- this: IExecuteFunctions,
28
- operation: AssetCustomFieldOperation,
29
- itemIndex: number,
30
- ): Promise<IDataObject | IDataObject[]> {
31
- debugLog('[RESOURCE_PROCESSING] Starting asset custom field operation', { operation, itemIndex });
32
-
33
- const assetId = this.getNodeParameter('assetId', itemIndex) as number;
34
- const rawFieldIdentifier = this.getNodeParameter('fieldIdentifier', itemIndex);
35
- if (typeof rawFieldIdentifier !== 'string' || !rawFieldIdentifier) {
36
- throw new NodeOperationError(this.getNode(), 'Custom Field Identifier is required and must be a string.', { itemIndex });
37
- }
38
- const fieldIdentifier = rawFieldIdentifier;
39
- const fieldIdentifierString = String(fieldIdentifier);
40
-
41
- if (!assetId) {
42
- throw new NodeOperationError(this.getNode(), 'Asset ID is required.', { itemIndex });
43
- }
44
-
45
- debugLog('[RESOURCE_PARAMS] Asset custom field parameters', { assetId, fieldIdentifier });
46
-
47
- // Check for placeholder value indicating no custom fields are available
48
- if (fieldIdentifier === 'NO_CUSTOM_FIELDS_FOUND') {
49
- throw new NodeOperationError(
50
- this.getNode(),
51
- `This asset doesn't have any custom fields. Please select an asset that has custom fields defined in its layout.`,
52
- { itemIndex }
53
- );
54
- }
55
-
56
- let response;
57
-
58
- if (operation === 'get') {
59
- debugLog('[OPERATION_GET] Getting asset custom field value');
60
-
61
- // Use the correct endpoint: /assets?id={assetId} (Hudu expects asset ID as a query parameter)
62
- const rawResponse = await huduApiRequest.call(this, 'GET', '/assets', {}, { id: assetId });
63
- debugLog('[API_RESPONSE] Asset response received');
64
-
65
- // The response should be an object with an 'assets' array
66
- if (!rawResponse || typeof rawResponse !== 'object' || !Array.isArray((rawResponse as IDataObject).assets)) {
67
- throw new NodeOperationError(this.getNode(), `Unexpected API response format when fetching asset ID '${assetId}'.`, { itemIndex });
68
- }
69
-
70
- const assetsArray = (rawResponse as IDataObject).assets as IDataObject[];
71
- if (!assetsArray.length) {
72
- throw new NodeOperationError(this.getNode(), `No asset found with ID '${assetId}'.`, { itemIndex });
73
- }
74
-
75
- const assetObject = assetsArray[0];
76
- debugLog('[RESOURCE_PROCESSING] Found asset', { assetId, layoutId: assetObject.asset_layout_id });
77
-
78
- // Asset fields might be null or undefined if no custom fields are set
79
- const assetFields = (assetObject.fields || []) as IDataObject[];
80
- const targetField = assetFields.find(field => field.label === fieldIdentifier);
81
-
82
- let fieldValue: any = null; // Default to null if field not found or has no value
83
- let fieldType: string | null = null;
84
-
85
- if (targetField) {
86
- fieldValue = targetField.value;
87
- fieldType = targetField.field_type as string || null;
88
- debugLog('[RESOURCE_TRANSFORM] Found field', {
89
- label: targetField.label,
90
- value: fieldValue,
91
- type: fieldType
92
- });
93
-
94
- // Format the value based on field type for better usability
95
- if (fieldType === ASSET_LAYOUT_FIELD_TYPES.DATE && fieldValue) {
96
- // Ensure dates are in a consistent format (ISO)
97
- try {
98
- const dateObj = new Date(fieldValue);
99
- if (!isNaN(dateObj.getTime())) {
100
- fieldValue = dateObj.toISOString();
101
- }
102
- } catch (error) {
103
- // If date parsing fails, keep the original value
104
- debugLog('[RESOURCE_TRANSFORM] Error parsing date value', { error });
105
- }
106
- } else if (fieldType === ASSET_LAYOUT_FIELD_TYPES.CHECKBOX) {
107
- // Ensure boolean values are actual booleans
108
- fieldValue = String(fieldValue).toLowerCase() === 'true';
109
- } else if (fieldType === ASSET_LAYOUT_FIELD_TYPES.NUMBER && fieldValue !== null && fieldValue !== undefined) {
110
- // Ensure numbers are numeric
111
- const numValue = parseFloat(String(fieldValue));
112
- if (!isNaN(numValue)) {
113
- fieldValue = numValue;
114
- }
115
- }
116
- } else {
117
- debugLog('[RESOURCE_TRANSFORM] Field not found', { fieldIdentifier });
118
- }
119
-
120
- response = {
121
- asset_id: assetId,
122
- field_identifier: fieldIdentifier,
123
- value: fieldValue,
124
- };
125
-
126
- } else if (operation === 'update') {
127
- debugLog('[OPERATION_UPDATE] Updating asset custom field value');
128
-
129
- const valueToSet = this.getNodeParameter('value', itemIndex);
130
- debugLog('[RESOURCE_PARAMS] Value to set', { valueToSet });
131
-
132
- // Fetch asset to get company_id and asset_layout_id
133
- const assetLookup = await huduApiRequest.call(this, 'GET', '/assets', {}, { id: assetId });
134
- debugLog('[API_RESPONSE] Asset lookup response received');
135
-
136
- const assetsArray = (assetLookup as IDataObject).assets as IDataObject[];
137
-
138
- if (!assetsArray?.length) {
139
- throw new NodeOperationError(this.getNode(), `No asset found with ID '${assetId}'.`, { itemIndex });
140
- }
141
-
142
- const assetObject = assetsArray[0];
143
- const companyId = assetObject.company_id;
144
- const assetLayoutId = assetObject.asset_layout_id;
145
-
146
- if (!companyId) {
147
- throw new NodeOperationError(this.getNode(), `Asset with ID '${assetId}' does not have a company_id.`, { itemIndex });
148
- }
149
- if (!assetLayoutId) {
150
- throw new NodeOperationError(this.getNode(), `Asset with ID '${assetId}' does not have an asset_layout_id.`, { itemIndex });
151
- }
152
-
153
- debugLog('[RESOURCE_PROCESSING] Found asset metadata', { companyId, assetLayoutId });
154
-
155
- // Fetch the asset layout to find the custom field definition
156
- debugLog('[RESOURCE_PROCESSING] Fetching asset layout to validate custom field');
157
- const layoutResponse = await huduApiRequest.call(this, 'GET', `/asset_layouts/${assetLayoutId}`);
158
- const layoutData = (layoutResponse as IDataObject).asset_layout as IDataObject || layoutResponse;
159
-
160
- if (!layoutData || !layoutData.fields || !Array.isArray(layoutData.fields)) {
161
- throw new NodeOperationError(this.getNode(), `Could not retrieve field definitions for asset layout ID '${assetLayoutId}'.`, { itemIndex });
162
- }
163
-
164
- // Find the custom field by label (and not of type AssetTag)
165
- const customField = (layoutData.fields as IDataObject[]).find(
166
- field => typeof field.label === 'string' && field.label === fieldIdentifier && field.field_type !== ASSET_LAYOUT_FIELD_TYPES.ASSET_TAG
167
- );
168
-
169
- if (!customField) {
170
- throw new NodeOperationError(
171
- this.getNode(),
172
- `Field '${fieldIdentifier}' is not found or is not a Custom Field in asset layout ID '${assetLayoutId}'.`,
173
- { itemIndex }
174
- );
175
- }
176
-
177
- debugLog('[RESOURCE_TRANSFORM] Found custom field in layout', {
178
- fieldId: customField.id,
179
- fieldType: customField.field_type,
180
- });
181
-
182
- // Detect legacy/unsupported field types (e.g., Dropdown) and prevent update
183
- const unsupportedTypes = ['Dropdown']; // Add more if needed
184
- if (typeof customField.field_type === 'string' && unsupportedTypes.includes(customField.field_type)) {
185
- debugLog('[RESOURCE_PARAMS] Attempted to update unsupported legacy field type', {
186
- fieldLabel: customField.label,
187
- fieldType: customField.field_type,
188
- });
189
- throw new NodeOperationError(
190
- this.getNode(),
191
- `The field '${customField.label}' is a legacy Dropdown field, which cannot be updated via the Hudu API. Please convert it to a List field in Hudu to enable API updates.`,
192
- { itemIndex }
193
- );
194
- }
195
-
196
- // Use robust toSnakeCase for the field key
197
- // Import toSnakeCase from formatters
198
- // (If not already imported, add: import { toSnakeCase } from '../../utils/formatters';)
199
- const { toSnakeCase } = await import('../../utils/formatters') as { toSnakeCase: (input: string) => string };
200
- const snakeCaseFieldLabel = toSnakeCase(fieldIdentifierString as string);
201
-
202
- if (!snakeCaseFieldLabel) {
203
- throw new NodeOperationError(this.getNode(), `Could not convert field label '${fieldIdentifier}' to snake_case.`, { itemIndex });
204
- }
205
-
206
- debugLog('[RESOURCE_TRANSFORM] Converted field name to snake_case', {
207
- original: fieldIdentifierString,
208
- snakeCase: snakeCaseFieldLabel
209
- });
210
-
211
- // Prepare the value based on field type
212
- let processedValue: any = valueToSet;
213
- if (customField.field_type === ASSET_LAYOUT_FIELD_TYPES.DATE && valueToSet) {
214
- // Format as YYYY-MM-DD, only if valueToSet is string or number
215
- if (typeof valueToSet === 'string' || typeof valueToSet === 'number') {
216
- const dateObj = new Date(valueToSet);
217
- if (!isNaN(dateObj.getTime())) {
218
- processedValue = dateObj.toISOString().split('T')[0];
219
- }
220
- }
221
- } else if (customField.field_type === ASSET_LAYOUT_FIELD_TYPES.CHECKBOX) {
222
- // Boolean
223
- processedValue = String(valueToSet ?? '').toLowerCase() === 'true';
224
- } else if (customField.field_type === ASSET_LAYOUT_FIELD_TYPES.NUMBER && valueToSet !== null && valueToSet !== undefined) {
225
- // Number
226
- const numValue = parseFloat(String(valueToSet));
227
- if (!isNaN(numValue)) {
228
- processedValue = numValue;
229
- }
230
- }
231
-
232
- /**
233
- * Hudu API expects certain custom field values (e.g., List fields) to be sent as stringified JSON.
234
- * If the processed value is an object or array, we must JSON.stringify it before sending.
235
- * This is based on Hudu support guidance and API behaviour.
236
- */
237
- if (typeof processedValue === 'object' && processedValue !== null) {
238
- debugLog('[RESOURCE_TRANSFORM] Stringifying value for custom field', {
239
- fieldType: customField.field_type,
240
- originalValue: processedValue
241
- });
242
- processedValue = JSON.stringify(processedValue);
243
- }
244
-
245
- debugLog('[RESOURCE_TRANSFORM] Processed value for field', {
246
- fieldType: customField.field_type,
247
- originalValue: valueToSet,
248
- processedValue
249
- });
250
-
251
- // Build custom_fields array with only the updated field
252
- const customFieldsArray: IDataObject[] = [
253
- { [snakeCaseFieldLabel]: processedValue }
254
- ];
255
-
256
- debugLog('[RESOURCE_TRANSFORM] Built custom_fields array for update', {
257
- customFieldsArray
258
- });
259
-
260
- // Prepare the update payload as a flat object (not wrapped in 'asset')
261
- const updatePayload: IDataObject = {
262
- name: assetObject.name,
263
- asset_layout_id: assetObject.asset_layout_id,
264
- custom_fields: customFieldsArray,
265
- };
266
- if (assetObject.primary_serial) updatePayload.primary_serial = assetObject.primary_serial;
267
- if (assetObject.primary_mail) updatePayload.primary_mail = assetObject.primary_mail;
268
- if (assetObject.primary_model) updatePayload.primary_model = assetObject.primary_model;
269
- if (assetObject.primary_manufacturer) updatePayload.primary_manufacturer = assetObject.primary_manufacturer;
270
-
271
- debugLog('[API_REQUEST] Updating asset with payload', updatePayload);
272
-
273
- // Use the same endpoint as assetLinkField.handler.ts
274
- const updateEndpoint = `/companies/${companyId}/assets/${assetId}`;
275
- const updateResponseData = await huduApiRequest.call(this, 'PUT', updateEndpoint, updatePayload);
276
- debugLog('[API_RESPONSE] Update asset response received');
277
-
278
- response = {
279
- message: `Successfully updated custom field '${fieldIdentifierString}' for asset ID '${assetId}'.`,
280
- asset_id: assetId,
281
- field_identifier: fieldIdentifierString,
282
- processed_value: processedValue,
283
- response: updateResponseData,
284
- };
285
- }
286
-
287
- if (response) {
288
- debugLog('[RESOURCE_PROCESSING] Completed asset custom field operation', { operation });
289
- return response;
290
- }
291
-
292
- throw new NodeOperationError(this.getNode(), `Operation '${operation}' not implemented in handleAssetCustomFieldOperation`, { itemIndex });
293
- }
@@ -1,3 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- //# sourceMappingURL=assetCustomField.types.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"assetCustomField.types.js","sourceRoot":"","sources":["../../../../../../src/nodes/Hudu/resources/assetCustomField/assetCustomField.types.ts"],"names":[],"mappings":""}
@@ -1 +0,0 @@
1
- export type AssetCustomFieldOperation = 'get' | 'update';
@@ -1,262 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.handleAssetLinkFieldOperation = void 0;
4
- const n8n_workflow_1 = require("n8n-workflow");
5
- const requestUtils_1 = require("../../utils/requestUtils");
6
- const formatters_1 = require("../../utils/formatters");
7
- const constants_1 = require("../../utils/constants");
8
- const debugConfig_1 = require("../../utils/debugConfig");
9
- async function handleAssetLinkFieldOperation(operation, itemIndex) {
10
- (0, debugConfig_1.debugLog)('[RESOURCE_PROCESSING] Starting asset link field operation', { operation, itemIndex });
11
- const assetId = this.getNodeParameter('assetId', itemIndex);
12
- const fieldIdentifier = this.getNodeParameter('fieldIdentifier', itemIndex);
13
- if (!assetId) {
14
- throw new n8n_workflow_1.NodeOperationError(this.getNode(), 'Asset ID is required.', { itemIndex });
15
- }
16
- if (!fieldIdentifier) {
17
- throw new n8n_workflow_1.NodeOperationError(this.getNode(), 'Link Field Identifier is required.', { itemIndex });
18
- }
19
- (0, debugConfig_1.debugLog)('[RESOURCE_PARAMS] Asset link field parameters', { assetId, fieldIdentifier });
20
- if (fieldIdentifier === 'NO_LINK_FIELDS_FOUND') {
21
- throw new n8n_workflow_1.NodeOperationError(this.getNode(), `This asset doesn't have any asset link fields. Please select an asset that has link fields defined in its layout.`, { itemIndex });
22
- }
23
- let response;
24
- if (operation === 'get') {
25
- (0, debugConfig_1.debugLog)('[OPERATION_GET] Getting asset link field value');
26
- const rawResponse = await requestUtils_1.huduApiRequest.call(this, 'GET', '/assets', {}, { id: assetId });
27
- (0, debugConfig_1.debugLog)('[API_RESPONSE] Asset response received');
28
- if (!rawResponse || typeof rawResponse !== 'object' || !Array.isArray(rawResponse.assets)) {
29
- throw new n8n_workflow_1.NodeOperationError(this.getNode(), `Unexpected API response format when fetching asset ID '${assetId}'.`, { itemIndex });
30
- }
31
- const assetsArray = rawResponse.assets;
32
- if (!assetsArray.length) {
33
- throw new n8n_workflow_1.NodeOperationError(this.getNode(), `No asset found with ID '${assetId}'.`, { itemIndex });
34
- }
35
- const assetObject = assetsArray[0];
36
- (0, debugConfig_1.debugLog)('[RESOURCE_PROCESSING] Found asset', { assetId, layoutId: assetObject.asset_layout_id });
37
- if (!Array.isArray(assetObject.fields)) {
38
- throw new n8n_workflow_1.NodeOperationError(this.getNode(), `Asset ID '${assetId}' does not have a 'fields' array or it's not an array.`, { itemIndex });
39
- }
40
- const assetFields = assetObject.fields;
41
- const targetField = assetFields.find(field => field.label === fieldIdentifier);
42
- if (!targetField) {
43
- throw new n8n_workflow_1.NodeOperationError(this.getNode(), `Link Field with label '${fieldIdentifier}' not found on asset ID '${assetId}'.`, { itemIndex });
44
- }
45
- (0, debugConfig_1.debugLog)('[RESOURCE_TRANSFORM] Found link field', {
46
- label: targetField.label,
47
- fieldType: targetField.field_type
48
- });
49
- let fieldValue = targetField.value;
50
- let assetIds = [];
51
- if (fieldValue === null || fieldValue === undefined) {
52
- (0, debugConfig_1.debugLog)('[RESOURCE_TRANSFORM] Field value is null/undefined, returning empty array');
53
- assetIds = [];
54
- }
55
- else if (typeof fieldValue === 'string') {
56
- (0, debugConfig_1.debugLog)('[RESOURCE_TRANSFORM] Field value is string, attempting to parse as JSON');
57
- try {
58
- const parsedValue = JSON.parse(fieldValue);
59
- if (Array.isArray(parsedValue)) {
60
- assetIds = parsedValue
61
- .filter(item => item && typeof item === 'object' && 'id' in item)
62
- .map(item => {
63
- const id = item.id;
64
- if (typeof id === 'number') {
65
- return id;
66
- }
67
- else if (typeof id === 'string') {
68
- return parseInt(id, 10);
69
- }
70
- return NaN;
71
- })
72
- .filter(id => !isNaN(id));
73
- (0, debugConfig_1.debugLog)('[RESOURCE_TRANSFORM] Parsed JSON array into asset IDs', { count: assetIds.length });
74
- }
75
- }
76
- catch (error) {
77
- (0, debugConfig_1.debugLog)('[RESOURCE_TRANSFORM] Error parsing JSON string', { error });
78
- assetIds = [];
79
- }
80
- }
81
- else if (Array.isArray(fieldValue)) {
82
- (0, debugConfig_1.debugLog)('[RESOURCE_TRANSFORM] Field value is already an array, extracting IDs');
83
- assetIds = fieldValue
84
- .map(item => {
85
- if (item && typeof item === 'object' && 'id' in item) {
86
- const id = item.id;
87
- if (typeof id === 'number') {
88
- return id;
89
- }
90
- else if (typeof id === 'string') {
91
- return parseInt(id, 10);
92
- }
93
- return NaN;
94
- }
95
- else if (typeof item === 'number') {
96
- return item;
97
- }
98
- else if (typeof item === 'string' && !isNaN(parseInt(item, 10))) {
99
- return parseInt(item, 10);
100
- }
101
- return NaN;
102
- })
103
- .filter(id => !isNaN(id));
104
- (0, debugConfig_1.debugLog)('[RESOURCE_TRANSFORM] Extracted asset IDs from array', { count: assetIds.length });
105
- }
106
- response = {
107
- asset_id: assetId,
108
- field_identifier: fieldIdentifier,
109
- value: assetIds.join(','),
110
- asset_ids: assetIds,
111
- };
112
- }
113
- else if (operation === 'update') {
114
- (0, debugConfig_1.debugLog)('[OPERATION_UPDATE] Updating asset link field value');
115
- const valueToSet = this.getNodeParameter('value', itemIndex);
116
- const linkedAssetIds = valueToSet.split(',')
117
- .map(id => parseInt(id.trim(), 10))
118
- .filter(id => !isNaN(id));
119
- (0, debugConfig_1.debugLog)('[RESOURCE_TRANSFORM] Converted comma-separated IDs to array', {
120
- input: valueToSet,
121
- output: linkedAssetIds
122
- });
123
- const snakeCaseFieldLabel = (0, formatters_1.toSnakeCase)(fieldIdentifier);
124
- if (!snakeCaseFieldLabel) {
125
- throw new n8n_workflow_1.NodeOperationError(this.getNode(), `Could not convert field label '${fieldIdentifier}' to snake_case.`, { itemIndex });
126
- }
127
- (0, debugConfig_1.debugLog)('[RESOURCE_TRANSFORM] Converted field name to snake_case', {
128
- original: fieldIdentifier,
129
- snakeCase: snakeCaseFieldLabel
130
- });
131
- const assetLookup = await requestUtils_1.huduApiRequest.call(this, 'GET', '/assets', {}, { id: assetId });
132
- (0, debugConfig_1.debugLog)('[API_RESPONSE] Asset lookup response received');
133
- const assetsArray = assetLookup.assets;
134
- if (!(assetsArray === null || assetsArray === void 0 ? void 0 : assetsArray.length)) {
135
- throw new n8n_workflow_1.NodeOperationError(this.getNode(), `No asset found with ID '${assetId}'.`, { itemIndex });
136
- }
137
- const assetObject = assetsArray[0];
138
- const companyId = assetObject.company_id;
139
- const assetLayoutId = assetObject.asset_layout_id;
140
- if (!companyId) {
141
- throw new n8n_workflow_1.NodeOperationError(this.getNode(), `Asset with ID '${assetId}' does not have a company_id.`, { itemIndex });
142
- }
143
- if (!assetLayoutId) {
144
- throw new n8n_workflow_1.NodeOperationError(this.getNode(), `Asset with ID '${assetId}' does not have an asset_layout_id.`, { itemIndex });
145
- }
146
- (0, debugConfig_1.debugLog)('[RESOURCE_PROCESSING] Found asset metadata', {
147
- assetId,
148
- companyId,
149
- assetLayoutId
150
- });
151
- (0, debugConfig_1.debugLog)('[RESOURCE_PROCESSING] Fetching asset layout to validate link field');
152
- const layoutResponse = await requestUtils_1.huduApiRequest.call(this, 'GET', `/asset_layouts/${assetLayoutId}`);
153
- const layoutData = layoutResponse.asset_layout || layoutResponse;
154
- if (!layoutData || !layoutData.fields || !Array.isArray(layoutData.fields)) {
155
- throw new n8n_workflow_1.NodeOperationError(this.getNode(), `Could not retrieve field definitions for asset layout ID '${assetLayoutId}'.`, { itemIndex });
156
- }
157
- const linkField = layoutData.fields.find(field => field.label === fieldIdentifier && field.field_type === constants_1.ASSET_LAYOUT_FIELD_TYPES.ASSET_TAG);
158
- if (!linkField) {
159
- throw new n8n_workflow_1.NodeOperationError(this.getNode(), `Field '${fieldIdentifier}' is not found or is not an Asset Link field in asset layout ID '${assetLayoutId}'.`, { itemIndex });
160
- }
161
- (0, debugConfig_1.debugLog)('[RESOURCE_TRANSFORM] Found link field in layout', {
162
- fieldId: linkField.id,
163
- fieldType: linkField.field_type,
164
- linkableId: linkField.linkable_id
165
- });
166
- const linkableId = linkField.linkable_id;
167
- if (!linkableId) {
168
- throw new n8n_workflow_1.NodeOperationError(this.getNode(), `Asset Link field '${fieldIdentifier}' does not have a linkable_id defined. Cannot validate linked assets.`, { itemIndex });
169
- }
170
- if (linkedAssetIds.length > 0) {
171
- (0, debugConfig_1.debugLog)('[RESOURCE_VALIDATION] Validating linked asset IDs', { count: linkedAssetIds.length });
172
- const invalidAssets = [];
173
- const missingAssets = [];
174
- const assetValidationPromises = linkedAssetIds.map(async (id) => {
175
- try {
176
- (0, debugConfig_1.debugLog)('[RESOURCE_VALIDATION] Validating asset ID', { id });
177
- const assetResponse = await requestUtils_1.huduApiRequest.call(this, 'GET', '/assets', {}, { id });
178
- const assetData = assetResponse.assets;
179
- if (!assetData || !assetData.length) {
180
- (0, debugConfig_1.debugLog)('[RESOURCE_VALIDATION] Asset not found', { id });
181
- missingAssets.push(id);
182
- return { id, exists: false };
183
- }
184
- const asset = assetData[0];
185
- if (asset.asset_layout_id !== linkableId) {
186
- (0, debugConfig_1.debugLog)('[RESOURCE_VALIDATION] Asset has incorrect layout', {
187
- id,
188
- actualLayoutId: asset.asset_layout_id,
189
- expectedLayoutId: linkableId
190
- });
191
- invalidAssets.push({
192
- id,
193
- reason: `Asset ID ${id} has layout ID ${asset.asset_layout_id}, but field '${fieldIdentifier}' requires layout ID ${linkableId}`
194
- });
195
- return { id, exists: true, valid: false };
196
- }
197
- (0, debugConfig_1.debugLog)('[RESOURCE_VALIDATION] Asset is valid', { id });
198
- return { id, exists: true, valid: true };
199
- }
200
- catch (error) {
201
- (0, debugConfig_1.debugLog)('[RESOURCE_VALIDATION] Error validating asset', { id, error });
202
- missingAssets.push(id);
203
- return { id, exists: false, error };
204
- }
205
- });
206
- await Promise.all(assetValidationPromises);
207
- if (missingAssets.length > 0 || invalidAssets.length > 0) {
208
- (0, debugConfig_1.debugLog)('[RESOURCE_VALIDATION] Validation failed', {
209
- missingCount: missingAssets.length,
210
- invalidCount: invalidAssets.length
211
- });
212
- let errorMessage = 'Validation failed for the following linked asset IDs:\n';
213
- if (missingAssets.length > 0) {
214
- errorMessage += `- Missing assets: ${missingAssets.join(', ')}\n`;
215
- }
216
- if (invalidAssets.length > 0) {
217
- errorMessage += '- Invalid assets:\n';
218
- invalidAssets.forEach(asset => {
219
- errorMessage += ` - ${asset.id}: ${asset.reason}\n`;
220
- });
221
- }
222
- throw new n8n_workflow_1.NodeOperationError(this.getNode(), errorMessage, { itemIndex });
223
- }
224
- (0, debugConfig_1.debugLog)('[RESOURCE_VALIDATION] All assets validated successfully');
225
- }
226
- const updatePayload = {
227
- name: assetObject.name,
228
- asset_layout_id: assetObject.asset_layout_id,
229
- custom_fields: [
230
- {
231
- [snakeCaseFieldLabel]: linkedAssetIds,
232
- }
233
- ],
234
- };
235
- if (assetObject.primary_serial)
236
- updatePayload.primary_serial = assetObject.primary_serial;
237
- if (assetObject.primary_mail)
238
- updatePayload.primary_mail = assetObject.primary_mail;
239
- if (assetObject.primary_model)
240
- updatePayload.primary_model = assetObject.primary_model;
241
- if (assetObject.primary_manufacturer)
242
- updatePayload.primary_manufacturer = assetObject.primary_manufacturer;
243
- (0, debugConfig_1.debugLog)('[API_REQUEST] Updating asset with payload', updatePayload);
244
- const updateEndpoint = `/companies/${companyId}/assets/${assetId}`;
245
- const updateResponseData = await requestUtils_1.huduApiRequest.call(this, 'PUT', updateEndpoint, updatePayload);
246
- (0, debugConfig_1.debugLog)('[API_RESPONSE] Update asset response received');
247
- response = {
248
- message: `Successfully updated link field '${fieldIdentifier}' for asset ID '${assetId}'.`,
249
- asset_id: assetId,
250
- field_identifier: fieldIdentifier,
251
- new_linked_asset_ids: linkedAssetIds,
252
- response: updateResponseData,
253
- };
254
- }
255
- if (response) {
256
- (0, debugConfig_1.debugLog)('[RESOURCE_PROCESSING] Completed asset link field operation', { operation });
257
- return response;
258
- }
259
- throw new n8n_workflow_1.NodeOperationError(this.getNode(), `Operation '${operation}' not implemented in handleAssetLinkFieldOperation`, { itemIndex });
260
- }
261
- exports.handleAssetLinkFieldOperation = handleAssetLinkFieldOperation;
262
- //# sourceMappingURL=assetLinkField.handler.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"assetLinkField.handler.js","sourceRoot":"","sources":["../../../../../../src/nodes/Hudu/resources/assetLinkField/assetLinkField.handler.ts"],"names":[],"mappings":";;;AACA,+CAAkD;AAClD,2DAA0D;AAC1D,uDAAqD;AAErD,qDAAiE;AACjE,yDAAmD;AAkB5C,KAAK,UAAU,6BAA6B,CAE/C,SAAkC,EAClC,SAAiB;IAEjB,IAAA,sBAAQ,EAAC,2DAA2D,EAAE,EAAE,SAAS,EAAE,SAAS,EAAE,CAAC,CAAC;IAEhG,MAAM,OAAO,GAAG,IAAI,CAAC,gBAAgB,CAAC,SAAS,EAAE,SAAS,CAAW,CAAC;IACtE,MAAM,eAAe,GAAG,IAAI,CAAC,gBAAgB,CAAC,iBAAiB,EAAE,SAAS,CAAW,CAAC;IAEtF,IAAI,CAAC,OAAO,EAAE;QACV,MAAM,IAAI,iCAAkB,CAAC,IAAI,CAAC,OAAO,EAAE,EAAE,uBAAuB,EAAE,EAAE,SAAS,EAAE,CAAC,CAAC;KACxF;IAED,IAAI,CAAC,eAAe,EAAE;QAClB,MAAM,IAAI,iCAAkB,CAAC,IAAI,CAAC,OAAO,EAAE,EAAE,oCAAoC,EAAE,EAAE,SAAS,EAAE,CAAC,CAAC;KACrG;IAED,IAAA,sBAAQ,EAAC,+CAA+C,EAAE,EAAE,OAAO,EAAE,eAAe,EAAE,CAAC,CAAC;IAGxF,IAAI,eAAe,KAAK,sBAAsB,EAAE;QAC5C,MAAM,IAAI,iCAAkB,CACxB,IAAI,CAAC,OAAO,EAAE,EACd,mHAAmH,EACnH,EAAE,SAAS,EAAE,CAChB,CAAC;KACL;IAED,IAAI,QAAQ,CAAC;IAEb,IAAI,SAAS,KAAK,KAAK,EAAE;QACrB,IAAA,sBAAQ,EAAC,gDAAgD,CAAC,CAAC;QAG3D,MAAM,WAAW,GAAG,MAAM,6BAAc,CAAC,IAAI,CAAC,IAAI,EAAE,KAAK,EAAE,SAAS,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,OAAO,EAAE,CAAC,CAAC;QAC3F,IAAA,sBAAQ,EAAC,wCAAwC,CAAC,CAAC;QAGnD,IAAI,CAAC,WAAW,IAAI,OAAO,WAAW,KAAK,QAAQ,IAAI,CAAC,KAAK,CAAC,OAAO,CAAE,WAA2B,CAAC,MAAM,CAAC,EAAE;YACxG,MAAM,IAAI,iCAAkB,CAAC,IAAI,CAAC,OAAO,EAAE,EAAE,0DAA0D,OAAO,IAAI,EAAE,EAAE,SAAS,EAAE,CAAC,CAAC;SACtI;QAED,MAAM,WAAW,GAAI,WAA2B,CAAC,MAAuB,CAAC;QACzE,IAAI,CAAC,WAAW,CAAC,MAAM,EAAE;YACrB,MAAM,IAAI,iCAAkB,CAAC,IAAI,CAAC,OAAO,EAAE,EAAE,2BAA2B,OAAO,IAAI,EAAE,EAAE,SAAS,EAAE,CAAC,CAAC;SACvG;QAED,MAAM,WAAW,GAAG,WAAW,CAAC,CAAC,CAAC,CAAC;QACnC,IAAA,sBAAQ,EAAC,mCAAmC,EAAE,EAAE,OAAO,EAAE,QAAQ,EAAE,WAAW,CAAC,eAAe,EAAE,CAAC,CAAC;QAElG,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,WAAW,CAAC,MAAM,CAAC,EAAE;YACpC,MAAM,IAAI,iCAAkB,CAAC,IAAI,CAAC,OAAO,EAAE,EAAE,aAAa,OAAO,wDAAwD,EAAE,EAAE,SAAS,EAAE,CAAC,CAAC;SAC7I;QAED,MAAM,WAAW,GAAG,WAAW,CAAC,MAAuB,CAAC;QACxD,MAAM,WAAW,GAAG,WAAW,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,KAAK,CAAC,KAAK,KAAK,eAAe,CAAC,CAAC;QAE/E,IAAI,CAAC,WAAW,EAAE;YACd,MAAM,IAAI,iCAAkB,CAAC,IAAI,CAAC,OAAO,EAAE,EAAE,0BAA0B,eAAe,4BAA4B,OAAO,IAAI,EAAE,EAAE,SAAS,EAAE,CAAC,CAAC;SACjJ;QAED,IAAA,sBAAQ,EAAC,uCAAuC,EAAE;YAC9C,KAAK,EAAE,WAAW,CAAC,KAAK;YACxB,SAAS,EAAE,WAAW,CAAC,UAAU;SACpC,CAAC,CAAC;QAEH,IAAI,UAAU,GAAG,WAAW,CAAC,KAAK,CAAC;QACnC,IAAI,QAAQ,GAAa,EAAE,CAAC;QAG5B,IAAI,UAAU,KAAK,IAAI,IAAI,UAAU,KAAK,SAAS,EAAE;YAEjD,IAAA,sBAAQ,EAAC,2EAA2E,CAAC,CAAC;YACtF,QAAQ,GAAG,EAAE,CAAC;SACjB;aAAM,IAAI,OAAO,UAAU,KAAK,QAAQ,EAAE;YACvC,IAAA,sBAAQ,EAAC,yEAAyE,CAAC,CAAC;YACpF,IAAI;gBAEA,MAAM,WAAW,GAAG,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC;gBAC3C,IAAI,KAAK,CAAC,OAAO,CAAC,WAAW,CAAC,EAAE;oBAE5B,QAAQ,GAAG,WAAW;yBACjB,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,IAAI,OAAO,IAAI,KAAK,QAAQ,IAAI,IAAI,IAAI,IAAI,CAAC;yBAChE,GAAG,CAAC,IAAI,CAAC,EAAE;wBACR,MAAM,EAAE,GAAG,IAAI,CAAC,EAAE,CAAC;wBACnB,IAAI,OAAO,EAAE,KAAK,QAAQ,EAAE;4BACxB,OAAO,EAAE,CAAC;yBACb;6BAAM,IAAI,OAAO,EAAE,KAAK,QAAQ,EAAE;4BAC/B,OAAO,QAAQ,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC;yBAC3B;wBACD,OAAO,GAAG,CAAC;oBACf,CAAC,CAAC;yBACD,MAAM,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC;oBAE9B,IAAA,sBAAQ,EAAC,uDAAuD,EAAE,EAAE,KAAK,EAAE,QAAQ,CAAC,MAAM,EAAE,CAAC,CAAC;iBACjG;aACJ;YAAC,OAAO,KAAK,EAAE;gBAEZ,IAAA,sBAAQ,EAAC,gDAAgD,EAAE,EAAE,KAAK,EAAE,CAAC,CAAC;gBACtE,QAAQ,GAAG,EAAE,CAAC;aACjB;SACJ;aAAM,IAAI,KAAK,CAAC,OAAO,CAAC,UAAU,CAAC,EAAE;YAClC,IAAA,sBAAQ,EAAC,sEAAsE,CAAC,CAAC;YAEjF,QAAQ,GAAG,UAAU;iBAChB,GAAG,CAAC,IAAI,CAAC,EAAE;gBACR,IAAI,IAAI,IAAI,OAAO,IAAI,KAAK,QAAQ,IAAI,IAAI,IAAI,IAAI,EAAE;oBAClD,MAAM,EAAE,GAAG,IAAI,CAAC,EAAE,CAAC;oBACnB,IAAI,OAAO,EAAE,KAAK,QAAQ,EAAE;wBACxB,OAAO,EAAE,CAAC;qBACb;yBAAM,IAAI,OAAO,EAAE,KAAK,QAAQ,EAAE;wBAC/B,OAAO,QAAQ,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC;qBAC3B;oBACD,OAAO,GAAG,CAAC;iBACd;qBAAM,IAAI,OAAO,IAAI,KAAK,QAAQ,EAAE;oBACjC,OAAO,IAAI,CAAC;iBACf;qBAAM,IAAI,OAAO,IAAI,KAAK,QAAQ,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,EAAE;oBAC/D,OAAO,QAAQ,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;iBAC7B;gBACD,OAAO,GAAG,CAAC;YACf,CAAC,CAAC;iBACD,MAAM,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC;YAE9B,IAAA,sBAAQ,EAAC,qDAAqD,EAAE,EAAE,KAAK,EAAE,QAAQ,CAAC,MAAM,EAAE,CAAC,CAAC;SAC/F;QAED,QAAQ,GAAG;YACP,QAAQ,EAAE,OAAO;YACjB,gBAAgB,EAAE,eAAe;YACjC,KAAK,EAAE,QAAQ,CAAC,IAAI,CAAC,GAAG,CAAC;YACzB,SAAS,EAAE,QAAQ;SACtB,CAAC;KAEL;SAAM,IAAI,SAAS,KAAK,QAAQ,EAAE;QAC/B,IAAA,sBAAQ,EAAC,oDAAoD,CAAC,CAAC;QAE/D,MAAM,UAAU,GAAG,IAAI,CAAC,gBAAgB,CAAC,OAAO,EAAE,SAAS,CAAW,CAAC;QAGvE,MAAM,cAAc,GAAG,UAAU,CAAC,KAAK,CAAC,GAAG,CAAC;aACvC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,QAAQ,CAAC,EAAE,CAAC,IAAI,EAAE,EAAE,EAAE,CAAC,CAAC;aAClC,MAAM,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC;QAE9B,IAAA,sBAAQ,EAAC,6DAA6D,EAAE;YACpE,KAAK,EAAE,UAAU;YACjB,MAAM,EAAE,cAAc;SACzB,CAAC,CAAC;QAEH,MAAM,mBAAmB,GAAG,IAAA,wBAAW,EAAC,eAAe,CAAC,CAAC;QAEzD,IAAI,CAAC,mBAAmB,EAAE;YACtB,MAAM,IAAI,iCAAkB,CAAC,IAAI,CAAC,OAAO,EAAE,EAAE,kCAAkC,eAAe,kBAAkB,EAAE,EAAE,SAAS,EAAE,CAAC,CAAC;SACpI;QAED,IAAA,sBAAQ,EAAC,yDAAyD,EAAE;YAChE,QAAQ,EAAE,eAAe;YACzB,SAAS,EAAE,mBAAmB;SACjC,CAAC,CAAC;QAGH,MAAM,WAAW,GAAG,MAAM,6BAAc,CAAC,IAAI,CAAC,IAAI,EAAE,KAAK,EAAE,SAAS,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,OAAO,EAAE,CAAC,CAAC;QAC3F,IAAA,sBAAQ,EAAC,+CAA+C,CAAC,CAAC;QAE1D,MAAM,WAAW,GAAI,WAA2B,CAAC,MAAuB,CAAC;QAEzE,IAAI,CAAC,CAAA,WAAW,aAAX,WAAW,uBAAX,WAAW,CAAE,MAAM,CAAA,EAAE;YACtB,MAAM,IAAI,iCAAkB,CAAC,IAAI,CAAC,OAAO,EAAE,EAAE,2BAA2B,OAAO,IAAI,EAAE,EAAE,SAAS,EAAE,CAAC,CAAC;SACvG;QAED,MAAM,WAAW,GAAG,WAAW,CAAC,CAAC,CAAC,CAAC;QACnC,MAAM,SAAS,GAAG,WAAW,CAAC,UAAU,CAAC;QACzC,MAAM,aAAa,GAAG,WAAW,CAAC,eAAe,CAAC;QAElD,IAAI,CAAC,SAAS,EAAE;YACZ,MAAM,IAAI,iCAAkB,CAAC,IAAI,CAAC,OAAO,EAAE,EAAE,kBAAkB,OAAO,+BAA+B,EAAE,EAAE,SAAS,EAAE,CAAC,CAAC;SACzH;QAED,IAAI,CAAC,aAAa,EAAE;YAChB,MAAM,IAAI,iCAAkB,CAAC,IAAI,CAAC,OAAO,EAAE,EAAE,kBAAkB,OAAO,qCAAqC,EAAE,EAAE,SAAS,EAAE,CAAC,CAAC;SAC/H;QAED,IAAA,sBAAQ,EAAC,4CAA4C,EAAE;YACnD,OAAO;YACP,SAAS;YACT,aAAa;SAChB,CAAC,CAAC;QAGH,IAAA,sBAAQ,EAAC,oEAAoE,CAAC,CAAC;QAC/E,MAAM,cAAc,GAAG,MAAM,6BAAc,CAAC,IAAI,CAAC,IAAI,EAAE,KAAK,EAAE,kBAAkB,aAAa,EAAE,CAAC,CAAC;QACjG,MAAM,UAAU,GAAI,cAA8B,CAAC,YAA2B,IAAI,cAAc,CAAC;QAEjG,IAAI,CAAC,UAAU,IAAI,CAAC,UAAU,CAAC,MAAM,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,UAAU,CAAC,MAAM,CAAC,EAAE;YACxE,MAAM,IAAI,iCAAkB,CAAC,IAAI,CAAC,OAAO,EAAE,EAAE,6DAA6D,aAAa,IAAI,EAAE,EAAE,SAAS,EAAE,CAAC,CAAC;SAC/I;QAGD,MAAM,SAAS,GAAI,UAAU,CAAC,MAAwB,CAAC,IAAI,CACvD,KAAK,CAAC,EAAE,CAAC,KAAK,CAAC,KAAK,KAAK,eAAe,IAAI,KAAK,CAAC,UAAU,KAAK,oCAAwB,CAAC,SAAS,CACtG,CAAC;QAEF,IAAI,CAAC,SAAS,EAAE;YACZ,MAAM,IAAI,iCAAkB,CACxB,IAAI,CAAC,OAAO,EAAE,EACd,UAAU,eAAe,oEAAoE,aAAa,IAAI,EAC9G,EAAE,SAAS,EAAE,CAChB,CAAC;SACL;QAED,IAAA,sBAAQ,EAAC,iDAAiD,EAAE;YACxD,OAAO,EAAE,SAAS,CAAC,EAAE;YACrB,SAAS,EAAE,SAAS,CAAC,UAAU;YAC/B,UAAU,EAAE,SAAS,CAAC,WAAW;SACpC,CAAC,CAAC;QAEH,MAAM,UAAU,GAAG,SAAS,CAAC,WAAW,CAAC;QAEzC,IAAI,CAAC,UAAU,EAAE;YACb,MAAM,IAAI,iCAAkB,CACxB,IAAI,CAAC,OAAO,EAAE,EACd,qBAAqB,eAAe,uEAAuE,EAC3G,EAAE,SAAS,EAAE,CAChB,CAAC;SACL;QAGD,IAAI,cAAc,CAAC,MAAM,GAAG,CAAC,EAAE;YAC3B,IAAA,sBAAQ,EAAC,mDAAmD,EAAE,EAAE,KAAK,EAAE,cAAc,CAAC,MAAM,EAAE,CAAC,CAAC;YAGhG,MAAM,aAAa,GAAwC,EAAE,CAAC;YAC9D,MAAM,aAAa,GAAa,EAAE,CAAC;YAGnC,MAAM,uBAAuB,GAAG,cAAc,CAAC,GAAG,CAAC,KAAK,EAAE,EAAE,EAAE,EAAE;gBAC5D,IAAI;oBACA,IAAA,sBAAQ,EAAC,2CAA2C,EAAE,EAAE,EAAE,EAAE,CAAC,CAAC;oBAC9D,MAAM,aAAa,GAAG,MAAM,6BAAc,CAAC,IAAI,CAAC,IAAI,EAAE,KAAK,EAAE,SAAS,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC,CAAC;oBACpF,MAAM,SAAS,GAAI,aAA6B,CAAC,MAAuB,CAAC;oBAEzE,IAAI,CAAC,SAAS,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE;wBACjC,IAAA,sBAAQ,EAAC,uCAAuC,EAAE,EAAE,EAAE,EAAE,CAAC,CAAC;wBAC1D,aAAa,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;wBACvB,OAAO,EAAE,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC;qBAChC;oBAED,MAAM,KAAK,GAAG,SAAS,CAAC,CAAC,CAAC,CAAC;oBAC3B,IAAI,KAAK,CAAC,eAAe,KAAK,UAAU,EAAE;wBACtC,IAAA,sBAAQ,EAAC,kDAAkD,EAAE;4BACzD,EAAE;4BACF,cAAc,EAAE,KAAK,CAAC,eAAe;4BACrC,gBAAgB,EAAE,UAAU;yBAC/B,CAAC,CAAC;wBAEH,aAAa,CAAC,IAAI,CAAC;4BACf,EAAE;4BACF,MAAM,EAAE,YAAY,EAAE,kBAAkB,KAAK,CAAC,eAAe,gBAAgB,eAAe,wBAAwB,UAAU,EAAE;yBACnI,CAAC,CAAC;wBACH,OAAO,EAAE,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC;qBAC7C;oBAED,IAAA,sBAAQ,EAAC,sCAAsC,EAAE,EAAE,EAAE,EAAE,CAAC,CAAC;oBACzD,OAAO,EAAE,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC;iBAC5C;gBAAC,OAAO,KAAK,EAAE;oBACZ,IAAA,sBAAQ,EAAC,8CAA8C,EAAE,EAAE,EAAE,EAAE,KAAK,EAAE,CAAC,CAAC;oBACxE,aAAa,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;oBACvB,OAAO,EAAE,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC;iBACvC;YACL,CAAC,CAAC,CAAC;YAEH,MAAM,OAAO,CAAC,GAAG,CAAC,uBAAuB,CAAC,CAAC;YAG3C,IAAI,aAAa,CAAC,MAAM,GAAG,CAAC,IAAI,aAAa,CAAC,MAAM,GAAG,CAAC,EAAE;gBACtD,IAAA,sBAAQ,EAAC,yCAAyC,EAAE;oBAChD,YAAY,EAAE,aAAa,CAAC,MAAM;oBAClC,YAAY,EAAE,aAAa,CAAC,MAAM;iBACrC,CAAC,CAAC;gBAEH,IAAI,YAAY,GAAG,yDAAyD,CAAC;gBAE7E,IAAI,aAAa,CAAC,MAAM,GAAG,CAAC,EAAE;oBAC1B,YAAY,IAAI,qBAAqB,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC;iBACrE;gBAED,IAAI,aAAa,CAAC,MAAM,GAAG,CAAC,EAAE;oBAC1B,YAAY,IAAI,qBAAqB,CAAC;oBACtC,aAAa,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE;wBAC1B,YAAY,IAAI,OAAO,KAAK,CAAC,EAAE,KAAK,KAAK,CAAC,MAAM,IAAI,CAAC;oBACzD,CAAC,CAAC,CAAC;iBACN;gBAED,MAAM,IAAI,iCAAkB,CAAC,IAAI,CAAC,OAAO,EAAE,EAAE,YAAY,EAAE,EAAE,SAAS,EAAE,CAAC,CAAC;aAC7E;YAED,IAAA,sBAAQ,EAAC,yDAAyD,CAAC,CAAC;SACvE;QAGD,MAAM,aAAa,GAAgB;YAC/B,IAAI,EAAE,WAAW,CAAC,IAAI;YACtB,eAAe,EAAE,WAAW,CAAC,eAAe;YAC5C,aAAa,EAAE;gBACX;oBACI,CAAC,mBAAmB,CAAC,EAAE,cAAc;iBACxC;aACJ;SACJ,CAAC;QAGF,IAAI,WAAW,CAAC,cAAc;YAAE,aAAa,CAAC,cAAc,GAAG,WAAW,CAAC,cAAc,CAAC;QAC1F,IAAI,WAAW,CAAC,YAAY;YAAE,aAAa,CAAC,YAAY,GAAG,WAAW,CAAC,YAAY,CAAC;QACpF,IAAI,WAAW,CAAC,aAAa;YAAE,aAAa,CAAC,aAAa,GAAG,WAAW,CAAC,aAAa,CAAC;QACvF,IAAI,WAAW,CAAC,oBAAoB;YAAE,aAAa,CAAC,oBAAoB,GAAG,WAAW,CAAC,oBAAoB,CAAC;QAE5G,IAAA,sBAAQ,EAAC,2CAA2C,EAAE,aAAa,CAAC,CAAC;QAGrE,MAAM,cAAc,GAAG,cAAc,SAAS,WAAW,OAAO,EAAE,CAAC;QACnE,MAAM,kBAAkB,GAAG,MAAM,6BAAc,CAAC,IAAI,CAAC,IAAI,EAAE,KAAK,EAAE,cAAc,EAAE,aAAa,CAAC,CAAC;QACjG,IAAA,sBAAQ,EAAC,+CAA+C,CAAC,CAAC;QAE1D,QAAQ,GAAG;YACP,OAAO,EAAE,oCAAoC,eAAe,mBAAmB,OAAO,IAAI;YAC1F,QAAQ,EAAE,OAAO;YACjB,gBAAgB,EAAE,eAAe;YACjC,oBAAoB,EAAE,cAAc;YACpC,QAAQ,EAAE,kBAAkB;SAC/B,CAAC;KACL;IAED,IAAI,QAAQ,EAAE;QACV,IAAA,sBAAQ,EAAC,4DAA4D,EAAE,EAAE,SAAS,EAAE,CAAC,CAAC;QACtF,OAAO,QAAQ,CAAC;KACnB;IAED,MAAM,IAAI,iCAAkB,CAAC,IAAI,CAAC,OAAO,EAAE,EAAE,cAAc,SAAS,oDAAoD,EAAE,EAAE,SAAS,EAAE,CAAC,CAAC;AAC7I,CAAC;AAlVD,sEAkVC"}