NODEDC_PLATFORM/packages/n8n-nodes-ndc/nodes/NdcDataProductPublish/NdcDataProductPublish.node.ts

123 lines
4.1 KiB
TypeScript

import type {
IExecuteFunctions,
ILoadOptionsFunctions,
INodeExecutionData,
INodeType,
INodeTypeDescription,
} from 'n8n-workflow';
import { NodeConnectionTypes, NodeOperationError } from 'n8n-workflow';
import {
DATA_PRODUCT_BASE_PATH,
DATA_PLANE_DEFAULT_BASE_URL,
DATA_PLANE_BASE_URL_ENV,
DATA_PRODUCT_WRITER_CATALOG_PATH,
NDC_DATA_PRODUCT_WRITER_CREDENTIAL,
NDC_NODE_ICON,
} from '../shared/constants';
import { buildPublishPayload, encodeIdentifierPath } from '../shared/contracts';
import { safeHttpError, safeInputError } from '../shared/errors';
import { loadDataProductOptions, ndcRequest, serviceBaseUrl } from '../shared/http';
export class NdcDataProductPublish implements INodeType {
description: INodeTypeDescription = {
displayName: 'NDC Data Product Publish',
name: 'ndcDataProductPublish',
icon: NDC_NODE_ICON,
group: ['output'],
version: [1, 2],
subtitle: '={{$parameter["dataProductId"]}}',
description: 'Publish canonical facts through a scoped NDC Data Product grant',
defaults: { name: 'NDC Data Product Publish' },
inputs: [NodeConnectionTypes.Main],
outputs: [NodeConnectionTypes.Main],
credentials: [{ name: NDC_DATA_PRODUCT_WRITER_CREDENTIAL, required: true }],
properties: [
{
displayName: 'Data Product Name or ID',
name: 'dataProductId',
type: 'options',
typeOptions: { loadOptionsMethod: 'getDataProducts' },
default: '',
required: true,
},
{
displayName: 'Publish Mode',
name: 'publishMode',
type: 'options',
options: [
{ name: 'Create or Update', value: 'upsert' },
{ name: 'Replace Complete Snapshot', value: 'replace' },
],
default: 'upsert',
required: true,
displayOptions: { show: { '@version': [2] } },
description: 'Replace commits one complete generation atomically and removes keys absent from it',
},
{
displayName: 'Batch Sequence',
name: 'sequence',
type: 'number',
typeOptions: { minValue: 0, numberStepSize: 1 },
default: 0,
required: true,
description: 'Sequence number when one execution publishes several batches',
},
],
};
methods = {
loadOptions: {
async getDataProducts(this: ILoadOptionsFunctions) {
return loadDataProductOptions(
this,
NDC_DATA_PRODUCT_WRITER_CREDENTIAL,
DATA_PLANE_BASE_URL_ENV,
DATA_PLANE_DEFAULT_BASE_URL,
DATA_PRODUCT_WRITER_CATALOG_PATH,
);
},
},
};
async execute(this: IExecuteFunctions): Promise<INodeExecutionData[][]> {
const inputItems = this.getInputData();
const dataProductId = this.getNodeParameter('dataProductId', 0) as string;
const sequence = this.getNodeParameter('sequence', 0, 0) as number;
const publishMode = this.getNode().typeVersion >= 2
? this.getNodeParameter('publishMode', 0, 'upsert') as 'upsert' | 'replace'
: 'upsert';
let body;
let encodedProductId;
try {
body = buildPublishPayload(
inputItems,
this.getExecutionId(),
String(this.getWorkflow().id ?? 'workflow'),
this.getNode().id,
dataProductId,
sequence,
publishMode,
);
encodedProductId = encodeIdentifierPath(dataProductId, 'dataProductId');
} catch (error) {
throw new NodeOperationError(this.getNode(), safeInputError(error, 'ndc_data_product_publish_input_invalid'));
}
try {
const baseUrl = serviceBaseUrl(DATA_PLANE_BASE_URL_ENV, DATA_PLANE_DEFAULT_BASE_URL);
const response = await ndcRequest(this, NDC_DATA_PRODUCT_WRITER_CREDENTIAL, {
method: 'POST',
url: `${baseUrl}${DATA_PRODUCT_BASE_PATH}/${encodedProductId}/publish`,
body,
});
return [[{
json: response as INodeExecutionData['json'],
pairedItem: inputItems.map((_item, index) => ({ item: index })),
}]];
} catch (error) {
throw new NodeOperationError(this.getNode(), safeHttpError(error, 'ndc_data_product_publish_failed'));
}
}
}