From d36482b81894ad6c505f0a1e80fda22d47415a5c Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 25 Jun 2025 03:24:10 +0000 Subject: [PATCH 1/2] Initial plan From 945b2eed9e0a48c4c9bab5687b225e383fb6b43a Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 25 Jun 2025 03:30:24 +0000 Subject: [PATCH 2/2] Fix date format issue for serviceBusQueue trigger metadata Co-authored-by: swapnil-nagar <1988068+swapnil-nagar@users.noreply.github.com> --- src/converters/fromRpcTriggerMetadata.ts | 28 ++++++++- .../converters/fromRpcTriggerMetadata.test.ts | 63 +++++++++++++++++++ types/InvocationContext.d.ts | 4 +- types/input.d.ts | 2 +- types/output.d.ts | 2 +- 5 files changed, 94 insertions(+), 5 deletions(-) diff --git a/src/converters/fromRpcTriggerMetadata.ts b/src/converters/fromRpcTriggerMetadata.ts index 4e5efd1..9d1bb98 100644 --- a/src/converters/fromRpcTriggerMetadata.ts +++ b/src/converters/fromRpcTriggerMetadata.ts @@ -20,8 +20,34 @@ export function fromRpcTriggerMetadata( } else { const result: TriggerMetadata = {}; for (const [key, value] of Object.entries(triggerMetadata)) { - result[toCamelCaseKey(key)] = toCamelCaseValue(fromRpcTypedData(value)); + const camelCaseKey = toCamelCaseKey(key); + const processedValue = toCamelCaseValue(fromRpcTypedData(value)); + result[camelCaseKey] = fixDateFormatForServiceBus(camelCaseKey, processedValue, triggerType); } return result; } } + +/** + * Fix date format for serviceBus triggers to ensure proper timezone information. + * Adds 'Z' suffix to date strings that are missing timezone information. + */ +function fixDateFormatForServiceBus(key: string, value: unknown, triggerType: string): unknown { + // Only apply to serviceBus triggers + if (!triggerType.includes('serviceBus')) { + return value; + } + + // Only apply to known date fields + const dateFields = ['enqueuedTimeUtc', 'expiresAtUtc']; + if (!dateFields.includes(key)) { + return value; + } + + // Only apply to strings that look like dates without timezone + if (typeof value === 'string' && /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(\.\d{1,3})?$/.test(value)) { + return value + 'Z'; + } + + return value; +} diff --git a/test/converters/fromRpcTriggerMetadata.test.ts b/test/converters/fromRpcTriggerMetadata.test.ts index 1a78155..481eff0 100644 --- a/test/converters/fromRpcTriggerMetadata.test.ts +++ b/test/converters/fromRpcTriggerMetadata.test.ts @@ -283,4 +283,67 @@ describe('fromRpcTriggerMetadata', () => { }, }); }); + + it('serviceBusTrigger with date fields missing timezone', () => { + const testData: Record = { + ExpiresAtUtc: { + json: '"2025-06-07T14:46:55.145"', // Missing 'Z' timezone info + data: 'json', + http: undefined, + }, + EnqueuedTimeUtc: { + json: '"2025-06-07T14:46:55.145"', // Missing 'Z' timezone info + data: 'json', + http: undefined, + }, + MessageId: { + string: 'test-message-id', + data: 'string', + http: undefined, + }, + }; + + const result = fromRpcTriggerMetadata(testData, 'serviceBusTrigger'); + expect(result).to.deep.equal({ + expiresAtUtc: '2025-06-07T14:46:55.145Z', + enqueuedTimeUtc: '2025-06-07T14:46:55.145Z', + messageId: 'test-message-id', + }); + }); + + it('serviceBusTrigger with date fields already having timezone should not be modified', () => { + const testData: Record = { + ExpiresAtUtc: { + json: '"2025-06-07T14:46:55.145Z"', // Already has 'Z' timezone info + data: 'json', + http: undefined, + }, + EnqueuedTimeUtc: { + json: '"2025-06-07T14:46:55.145Z"', // Already has 'Z' timezone info + data: 'json', + http: undefined, + }, + }; + + const result = fromRpcTriggerMetadata(testData, 'serviceBusTrigger'); + expect(result).to.deep.equal({ + expiresAtUtc: '2025-06-07T14:46:55.145Z', + enqueuedTimeUtc: '2025-06-07T14:46:55.145Z', + }); + }); + + it('non-serviceBus triggers should not have date format fixes applied', () => { + const testData: Record = { + SomeDate: { + json: '"2025-06-07T14:46:55.145"', // Missing 'Z' timezone info + data: 'json', + http: undefined, + }, + }; + + const result = fromRpcTriggerMetadata(testData, 'queueTrigger'); + expect(result).to.deep.equal({ + someDate: '2025-06-07T14:46:55.145', // Should remain unchanged + }); + }); }); diff --git a/types/InvocationContext.d.ts b/types/InvocationContext.d.ts index 8815bdf..c991557 100644 --- a/types/InvocationContext.d.ts +++ b/types/InvocationContext.d.ts @@ -129,7 +129,7 @@ export interface InvocationContextExtraInputs { * @input the configuration object for this SQL input */ get(input: SqlInput): unknown; - + /** * Get a secondary MySql items input for this invocation * @input the configuration object for this MySql input @@ -223,7 +223,7 @@ export interface InvocationContextExtraOutputs { * @message the output event(s) value */ set(output: EventGridOutput, events: EventGridPartialEvent | EventGridPartialEvent[]): void; - + /** * Set a secondary MySql items output for this invocation * @output the configuration object for this MySql output diff --git a/types/input.d.ts b/types/input.d.ts index 52d8c68..b264405 100644 --- a/types/input.d.ts +++ b/types/input.d.ts @@ -4,10 +4,10 @@ import { CosmosDBInput, CosmosDBInputOptions } from './cosmosDB'; import { GenericInputOptions } from './generic'; import { FunctionInput } from './index'; +import { MySqlInput, MySqlInputOptions } from './mySql'; import { SqlInput, SqlInputOptions } from './sql'; import { StorageBlobInput, StorageBlobInputOptions } from './storage'; import { TableInput, TableInputOptions } from './table'; -import { MySqlInput, MySqlInputOptions } from './mySql'; import { WebPubSubConnectionInput, WebPubSubConnectionInputOptions, diff --git a/types/output.d.ts b/types/output.d.ts index b9d9d83..e9e08d9 100644 --- a/types/output.d.ts +++ b/types/output.d.ts @@ -7,6 +7,7 @@ import { EventHubOutput, EventHubOutputOptions } from './eventHub'; import { GenericOutputOptions } from './generic'; import { HttpOutput, HttpOutputOptions } from './http'; import { FunctionOutput } from './index'; +import { MySqlOutput, MySqlOutputOptions } from './mySql'; import { ServiceBusQueueOutput, ServiceBusQueueOutputOptions, @@ -16,7 +17,6 @@ import { import { SqlOutput, SqlOutputOptions } from './sql'; import { StorageBlobOutput, StorageBlobOutputOptions, StorageQueueOutput, StorageQueueOutputOptions } from './storage'; import { TableOutput, TableOutputOptions } from './table'; -import { MySqlOutput, MySqlOutputOptions } from './mySql'; import { WebPubSubOutput, WebPubSubOutputOptions } from './webpubsub'; /**