diff --git a/.github/workflows/on-push-trigger.yml b/.github/workflows/on-push-trigger.yml index 55c987c4e9d..459a6524f6d 100644 --- a/.github/workflows/on-push-trigger.yml +++ b/.github/workflows/on-push-trigger.yml @@ -8,6 +8,7 @@ on: permissions: contents: read actions: write + pull-requests: read jobs: trigger-deploy-workflow: @@ -16,15 +17,108 @@ jobs: steps: - name: Checkout uses: actions/checkout@v5 + with: + fetch-depth: 0 + + - name: Get PR Number + id: get-pr + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + run: | + PR_NUMBER=$(gh pr list --state merged --search "${{ github.sha }}" --json number --jq '.[0].number') + if [ -z "$PR_NUMBER" ]; then + echo "No PR found for this commit" + echo "pr_number=" >> $GITHUB_OUTPUT + else + echo "pr_number=$PR_NUMBER" >> $GITHUB_OUTPUT + echo "Found PR #$PR_NUMBER" + fi + + - name: Get PR Labels + id: get-labels + if: steps.get-pr.outputs.pr_number != '' + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + run: | + LABELS=$(gh pr view ${{ steps.get-pr.outputs.pr_number }} --json labels --jq '.labels[].name') + echo "Labels found:" + echo "$LABELS" + echo "labels<> $GITHUB_OUTPUT + echo "$LABELS" >> $GITHUB_OUTPUT + echo "EOF" >> $GITHUB_OUTPUT + + - name: Determine Services to Deploy + id: determine-services + env: + LABELS: ${{ steps.get-labels.outputs.labels || '' }} + run: | + DEPLOY_API=false + DEPLOY_WORKER=false + DEPLOY_WS=false + DEPLOY_WEBHOOK=false + SKIP_DEPLOYMENT=false + + # Check if only CI/CD label exists (standalone) + LABEL_COUNT=$(echo "$LABELS" | grep -v '^$' | wc -l | tr -d ' ') + if [ "$LABEL_COUNT" = "1" ] && echo "$LABELS" | grep -q "CI/CD"; then + echo "Only CI/CD label found, skipping deployment" + SKIP_DEPLOYMENT=true + elif echo "$LABELS" | grep -q "CI/CD"; then + echo "CI/CD label found with other labels, continuing with deployment" + fi + + # Check for service-specific labels only if not skipping + if [ "$SKIP_DEPLOYMENT" = "false" ]; then + if echo "$LABELS" | grep -q "@novu/api-service"; then + DEPLOY_API=true + echo "Found @novu/api-service label" + fi + + if echo "$LABELS" | grep -q "@novu/worker"; then + DEPLOY_WORKER=true + echo "Found @novu/worker label" + fi + + if echo "$LABELS" | grep -q "@novu/ws"; then + DEPLOY_WS=true + echo "Found @novu/ws label" + fi + + if echo "$LABELS" | grep -q "@novu/webhook"; then + DEPLOY_WEBHOOK=true + echo "Found @novu/webhook label" + fi + + # If no service labels found, deploy api and worker by default + if [ "$DEPLOY_API" = "false" ] && [ "$DEPLOY_WORKER" = "false" ] && [ "$DEPLOY_WS" = "false" ] && [ "$DEPLOY_WEBHOOK" = "false" ]; then + echo "No service labels found, deploying api and worker by default" + DEPLOY_API=true + DEPLOY_WORKER=true + fi + fi + + echo "skip_deployment=$SKIP_DEPLOYMENT" >> $GITHUB_OUTPUT + echo "deploy_api=$DEPLOY_API" >> $GITHUB_OUTPUT + echo "deploy_worker=$DEPLOY_WORKER" >> $GITHUB_OUTPUT + echo "deploy_ws=$DEPLOY_WS" >> $GITHUB_OUTPUT + echo "deploy_webhook=$DEPLOY_WEBHOOK" >> $GITHUB_OUTPUT + + echo "Final deployment configuration:" + echo " Skip: $SKIP_DEPLOYMENT" + echo " API: $DEPLOY_API" + echo " Worker: $DEPLOY_WORKER" + echo " WS: $DEPLOY_WS" + echo " Webhook: $DEPLOY_WEBHOOK" - name: Trigger Deploy Workflow via GitHub CLI + if: steps.determine-services.outputs.skip_deployment == 'false' env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} run: | gh workflow run "deploy.yml" \ --ref next \ -f environment=staging \ - -f deploy_api=true \ - -f deploy_worker=true \ - -f deploy_ws=true \ - -f deploy_webhook=true + -f deploy_api=${{ steps.determine-services.outputs.deploy_api }} \ + -f deploy_worker=${{ steps.determine-services.outputs.deploy_worker }} \ + -f deploy_ws=${{ steps.determine-services.outputs.deploy_ws }} \ + -f deploy_webhook=${{ steps.determine-services.outputs.deploy_webhook }} diff --git a/apps/api/src/app/inbox/e2e/mark-notification-as.e2e.ts b/apps/api/src/app/inbox/e2e/mark-notification-as.e2e.ts index 5d94906e874..e5d892e5915 100644 --- a/apps/api/src/app/inbox/e2e/mark-notification-as.e2e.ts +++ b/apps/api/src/app/inbox/e2e/mark-notification-as.e2e.ts @@ -133,7 +133,7 @@ describe('Mark Notification As - /inbox/notifications/:id/{read,unread,archive,u it('should update the read status', async () => { const { body, status } = await updateNotification({ id: message._id, status: 'read' }); - const updatedMessage = (await messageRepository.findOne({ + const updatedMessage = (await messageRepository.findOneForInbox({ _environmentId: session.environment._id, _subscriberId: subscriber?._id ?? '', _templateId: template._id, @@ -158,7 +158,7 @@ describe('Mark Notification As - /inbox/notifications/:id/{read,unread,archive,u const { body, status } = await updateNotification({ id: message._id, status: 'unread' }); - const updatedMessage = (await messageRepository.findOne({ + const updatedMessage = (await messageRepository.findOneForInbox({ _environmentId: session.environment._id, _subscriberId: subscriber?._id ?? '', _templateId: template._id, @@ -177,7 +177,7 @@ describe('Mark Notification As - /inbox/notifications/:id/{read,unread,archive,u it('should update the archived status', async () => { const { body, status } = await updateNotification({ id: message._id, status: 'archive' }); - const updatedMessage = (await messageRepository.findOne({ + const updatedMessage = (await messageRepository.findOneForInbox({ _environmentId: session.environment._id, _subscriberId: subscriber?._id ?? '', _templateId: template._id, @@ -202,7 +202,7 @@ describe('Mark Notification As - /inbox/notifications/:id/{read,unread,archive,u const { body, status } = await updateNotification({ id: message._id, status: 'unarchive' }); - const updatedMessage = (await messageRepository.findOne({ + const updatedMessage = (await messageRepository.findOneForInbox({ _environmentId: session.environment._id, _subscriberId: subscriber?._id ?? '', _templateId: template._id, @@ -226,7 +226,7 @@ describe('Mark Notification As - /inbox/notifications/:id/{read,unread,archive,u body: { snoozeUntil }, }); - const updatedMessage = (await messageRepository.findOne({ + const updatedMessage = (await messageRepository.findOneForInbox({ _environmentId: session.environment._id, _subscriberId: subscriber?._id ?? '', _templateId: template._id, @@ -254,7 +254,7 @@ describe('Mark Notification As - /inbox/notifications/:id/{read,unread,archive,u // Then unsnooze it const { body, status } = await updateNotification({ id: message._id, status: 'unsnooze' }); - const updatedMessage = (await messageRepository.findOne({ + const updatedMessage = (await messageRepository.findOneForInbox({ _environmentId: session.environment._id, _subscriberId: subscriber?._id ?? '', _templateId: template._id, @@ -267,4 +267,24 @@ describe('Mark Notification As - /inbox/notifications/:id/{read,unread,archive,u expect(body.data.isSnoozed).to.be.false; expect(body.data.snoozedUntil).to.be.undefined; }); + + it('should return workflow and to fields populated', async () => { + const { body, status } = await updateNotification({ id: message._id, status: 'read' }); + + expect(status).to.equal(200); + expect(body.data.workflow).to.exist; + expect(body.data.workflow.id).to.equal(String(template._id)); + expect(body.data.workflow.identifier).to.equal(template.triggers?.[0]?.identifier); + expect(body.data.workflow.name).to.equal(template.name); + expect(body.data.workflow.critical).to.equal(template.critical); + expect(body.data.workflow.tags).to.deep.equal(template.tags); + expect(body.data.workflow.severity).to.exist; + + expect(body.data.to).to.exist; + expect(body.data.to.id).to.equal(subscriber?._id ? String(subscriber._id) : ''); + expect(body.data.to.subscriberId).to.equal(subscriber?.subscriberId ?? ''); + expect(body.data.to.firstName).to.equal(subscriber?.firstName); + expect(body.data.to.lastName).to.equal(subscriber?.lastName); + expect(body.data.to.avatar).to.equal(subscriber?.avatar); + }); }); diff --git a/apps/api/src/app/inbox/e2e/update-notification-action.e2e.ts b/apps/api/src/app/inbox/e2e/update-notification-action.e2e.ts index 1c3fcbc8f17..8d2fa0735f7 100644 --- a/apps/api/src/app/inbox/e2e/update-notification-action.e2e.ts +++ b/apps/api/src/app/inbox/e2e/update-notification-action.e2e.ts @@ -201,7 +201,7 @@ describe('Update Notification Action - /inbox/notifications/:id/{complete/revert action: 'complete', actionType: ButtonTypeEnum.PRIMARY, }); - const updatedMessage = (await messageRepository.findOne({ + const updatedMessage = (await messageRepository.findOneForInbox({ _environmentId: session.environment._id, _subscriberId: subscriber?._id ?? '', _templateId: template._id, @@ -219,7 +219,7 @@ describe('Update Notification Action - /inbox/notifications/:id/{complete/revert action: 'complete', actionType: ButtonTypeEnum.SECONDARY, }); - const updatedMessage = (await messageRepository.findOne({ + const updatedMessage = (await messageRepository.findOneForInbox({ _environmentId: session.environment._id, _subscriberId: subscriber?._id ?? '', _templateId: template._id, @@ -230,4 +230,28 @@ describe('Update Notification Action - /inbox/notifications/:id/{complete/revert expect(body.data.primaryAction.isCompleted).to.be.false; expect(body.data.secondaryAction.isCompleted).to.be.true; }); + + it('should return workflow and to fields populated', async () => { + const { body, status } = await updateNotificationAction({ + id: message._id, + action: 'complete', + actionType: ButtonTypeEnum.PRIMARY, + }); + + expect(status).to.equal(200); + expect(body.data.workflow).to.exist; + expect(body.data.workflow.id).to.equal(String(template._id)); + expect(body.data.workflow.identifier).to.equal(template.triggers?.[0]?.identifier); + expect(body.data.workflow.name).to.equal(template.name); + expect(body.data.workflow.critical).to.equal(template.critical); + expect(body.data.workflow.tags).to.deep.equal(template.tags); + expect(body.data.workflow.severity).to.exist; + + expect(body.data.to).to.exist; + expect(body.data.to.id).to.equal(subscriber?._id ? String(subscriber._id) : ''); + expect(body.data.to.subscriberId).to.equal(subscriber?.subscriberId ?? ''); + expect(body.data.to.firstName).to.equal(subscriber?.firstName); + expect(body.data.to.lastName).to.equal(subscriber?.lastName); + expect(body.data.to.avatar).to.equal(subscriber?.avatar); + }); }); diff --git a/apps/api/src/app/inbox/usecases/mark-notification-as/mark-notification-as.spec.ts b/apps/api/src/app/inbox/usecases/mark-notification-as/mark-notification-as.spec.ts index be6d28a2c65..b41246901b2 100644 --- a/apps/api/src/app/inbox/usecases/mark-notification-as/mark-notification-as.spec.ts +++ b/apps/api/src/app/inbox/usecases/mark-notification-as/mark-notification-as.spec.ts @@ -83,7 +83,7 @@ describe('MarkNotificationAs', () => { }; getSubscriberMock.execute.resolves(mockSubscriber); - messageRepositoryMock.findOne.resolves(undefined); + messageRepositoryMock.findOneForInbox.resolves(undefined); try { await updateNotification.execute(command); @@ -104,8 +104,8 @@ describe('MarkNotificationAs', () => { const updatedMessageMock = { ...mockMessage, read: true }; getSubscriberMock.execute.resolves(mockSubscriber); - messageRepositoryMock.findOne.onFirstCall().resolves(mockMessage); - messageRepositoryMock.findOne.onSecondCall().resolves(updatedMessageMock); + messageRepositoryMock.findOneForInbox.onFirstCall().resolves(mockMessage); + messageRepositoryMock.findOneForInbox.onSecondCall().resolves(updatedMessageMock); markManyNotificationsAsMock.execute.resolves(); const updatedMessage = await updateNotification.execute(command); @@ -136,7 +136,8 @@ describe('MarkNotificationAs', () => { }; getSubscriberMock.execute.resolves(mockSubscriber); - messageRepositoryMock.findOne.resolves(mockMessage); + messageRepositoryMock.findOneForInbox.onFirstCall().resolves(mockMessage); + messageRepositoryMock.findOneForInbox.onSecondCall().resolves(mockMessage); await updateNotification.execute(command); diff --git a/apps/api/src/app/inbox/usecases/mark-notification-as/mark-notification-as.usecase.ts b/apps/api/src/app/inbox/usecases/mark-notification-as/mark-notification-as.usecase.ts index fbd1a050d14..7a8005609e2 100644 --- a/apps/api/src/app/inbox/usecases/mark-notification-as/mark-notification-as.usecase.ts +++ b/apps/api/src/app/inbox/usecases/mark-notification-as/mark-notification-as.usecase.ts @@ -29,7 +29,7 @@ export class MarkNotificationAs { throw new BadRequestException(`Subscriber with id: ${command.subscriberId} is not found.`); } - const message = await this.messageRepository.findOne({ + const message = await this.messageRepository.findOneForInbox({ _environmentId: command.environmentId, _subscriberId: subscriber._id, _id: command.notificationId, @@ -62,7 +62,7 @@ export class MarkNotificationAs { }); return mapToDto( - (await this.messageRepository.findOne({ + (await this.messageRepository.findOneForInbox({ _environmentId: command.environmentId, _id: command.notificationId, })) as MessageEntity diff --git a/apps/api/src/app/inbox/usecases/update-notification-action/update-notification-action.spec.ts b/apps/api/src/app/inbox/usecases/update-notification-action/update-notification-action.spec.ts index 7fe417c8ea9..6b3faaf8910 100644 --- a/apps/api/src/app/inbox/usecases/update-notification-action/update-notification-action.spec.ts +++ b/apps/api/src/app/inbox/usecases/update-notification-action/update-notification-action.spec.ts @@ -105,7 +105,7 @@ describe('UpdateNotificationAction', () => { }; getSubscriberMock.execute.resolves(mockSubscriber); - messageRepositoryMock.findOne.resolves(undefined); + messageRepositoryMock.findOneForInbox.resolves(undefined); try { await updateNotificationAction.execute(command); @@ -126,7 +126,7 @@ describe('UpdateNotificationAction', () => { }; getSubscriberMock.execute.resolves(mockSubscriber); - messageRepositoryMock.findOne.resolves(mockMessage); + messageRepositoryMock.findOneForInbox.resolves(mockMessage); try { await updateNotificationAction.execute(command); @@ -147,7 +147,7 @@ describe('UpdateNotificationAction', () => { }; getSubscriberMock.execute.resolves(mockSubscriber); - messageRepositoryMock.findOne.resolves(mockMessage); + messageRepositoryMock.findOneForInbox.resolves(mockMessage); try { await updateNotificationAction.execute(command); @@ -179,8 +179,8 @@ describe('UpdateNotificationAction', () => { }; getSubscriberMock.execute.resolves(mockSubscriber); - messageRepositoryMock.findOne.onFirstCall().resolves(mockMessageWithButtons); - messageRepositoryMock.findOne.onSecondCall().resolves(updatedMessageWithButtonsMock); + messageRepositoryMock.findOneForInbox.onFirstCall().resolves(mockMessageWithButtons); + messageRepositoryMock.findOneForInbox.onSecondCall().resolves(updatedMessageWithButtonsMock); messageRepositoryMock.updateActionStatus.resolves(); const updatedMessage = await updateNotificationAction.execute(command); @@ -211,7 +211,8 @@ describe('UpdateNotificationAction', () => { }; getSubscriberMock.execute.resolves(mockSubscriber); - messageRepositoryMock.findOne.resolves(mockMessageWithButtons); + messageRepositoryMock.findOneForInbox.onFirstCall().resolves(mockMessageWithButtons); + messageRepositoryMock.findOneForInbox.onSecondCall().resolves(mockMessageWithButtons); messageRepositoryMock.updateActionStatus.resolves(); await updateNotificationAction.execute(command); diff --git a/apps/api/src/app/inbox/usecases/update-notification-action/update-notification-action.usecase.ts b/apps/api/src/app/inbox/usecases/update-notification-action/update-notification-action.usecase.ts index 69c469e83f7..645f587d123 100644 --- a/apps/api/src/app/inbox/usecases/update-notification-action/update-notification-action.usecase.ts +++ b/apps/api/src/app/inbox/usecases/update-notification-action/update-notification-action.usecase.ts @@ -28,7 +28,7 @@ export class UpdateNotificationAction { throw new BadRequestException(`Subscriber with id: ${command.subscriberId} is not found.`); } - const message = await this.messageRepository.findOne({ + const message = await this.messageRepository.findOneForInbox({ _environmentId: command.environmentId, _subscriberId: subscriber._id, _id: command.notificationId, @@ -67,7 +67,7 @@ export class UpdateNotificationAction { }); return mapToDto( - (await this.messageRepository.findOne({ + (await this.messageRepository.findOneForInbox({ _environmentId: command.environmentId, _id: command.notificationId, })) as MessageEntity diff --git a/apps/api/src/app/subscribers-v2/dtos/subscriber-workflow-preference.dto.ts b/apps/api/src/app/subscribers-v2/dtos/subscriber-workflow-preference.dto.ts index ff2f0af7325..e02cbae1553 100644 --- a/apps/api/src/app/subscribers-v2/dtos/subscriber-workflow-preference.dto.ts +++ b/apps/api/src/app/subscribers-v2/dtos/subscriber-workflow-preference.dto.ts @@ -1,4 +1,4 @@ -import { ApiProperty } from '@nestjs/swagger'; +import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger'; import { Type } from 'class-transformer'; import { SubscriberPreferenceChannels } from '../../shared/dtos/preference-channels'; import { SubscriberPreferenceOverrideDto } from '../../subscribers/dtos'; @@ -22,4 +22,10 @@ export class SubscriberWorkflowPreferenceDto { @ApiProperty({ description: 'Workflow information', type: SubscriberPreferencesWorkflowInfoDto }) @Type(() => SubscriberPreferencesWorkflowInfoDto) workflow: SubscriberPreferencesWorkflowInfoDto; + + @ApiPropertyOptional({ + description: + 'Timestamp when the subscriber last updated their preference. Only present if subscriber explicitly set preferences.', + }) + updatedAt?: string; } diff --git a/apps/api/src/app/subscribers-v2/usecases/get-subscriber-preferences/get-subscriber-preferences.usecase.ts b/apps/api/src/app/subscribers-v2/usecases/get-subscriber-preferences/get-subscriber-preferences.usecase.ts index 45351fccbcd..9f688b7bfd9 100644 --- a/apps/api/src/app/subscribers-v2/usecases/get-subscriber-preferences/get-subscriber-preferences.usecase.ts +++ b/apps/api/src/app/subscribers-v2/usecases/get-subscriber-preferences/get-subscriber-preferences.usecase.ts @@ -72,6 +72,7 @@ export class GetSubscriberPreferences { enabled: preference.enabled, channels: preference.channels, overrides: preference.overrides, + updatedAt: preference.updatedAt, workflow: { slug: buildSlug(template.name, ShortIsPrefixEnum.WORKFLOW, template._id), identifier: template.triggers[0].identifier, diff --git a/apps/api/src/app/subscribers/usecases/get-subscriber-preference/get-subscriber-preference.usecase.ts b/apps/api/src/app/subscribers/usecases/get-subscriber-preference/get-subscriber-preference.usecase.ts index 64c5d7be4ec..86ea24f6338 100644 --- a/apps/api/src/app/subscribers/usecases/get-subscriber-preference/get-subscriber-preference.usecase.ts +++ b/apps/api/src/app/subscribers/usecases/get-subscriber-preference/get-subscriber-preference.usecase.ts @@ -174,11 +174,14 @@ export class GetSubscriberPreference { const { channels, overrides } = this.calculateChannelsAndOverrides(merged, initialChannels); - return { + const preference: ISubscriberPreferenceResponse = { preference: { channels, enabled: true, overrides, + ...(preferences.subscriberWorkflowPreference?.updatedAt && { + updatedAt: preferences.subscriberWorkflowPreference.updatedAt, + }), }, template: mapTemplateConfiguration({ ...workflow, @@ -186,6 +189,8 @@ export class GetSubscriberPreference { }), type: PreferencesTypeEnum.SUBSCRIBER_WORKFLOW, }; + + return preference; }) .filter((item): item is ISubscriberPreferenceResponse => item !== null); diff --git a/apps/dashboard/src/components/subscribers/preferences/workflow-preferences.tsx b/apps/dashboard/src/components/subscribers/preferences/workflow-preferences.tsx index 40c32ec6da9..e62cd236472 100644 --- a/apps/dashboard/src/components/subscribers/preferences/workflow-preferences.tsx +++ b/apps/dashboard/src/components/subscribers/preferences/workflow-preferences.tsx @@ -20,7 +20,7 @@ type WorkflowPreferencesProps = { export function WorkflowPreferences(props: WorkflowPreferencesProps) { const { workflowPreferences, onToggle, readOnly = false } = props; const [isExpanded, setIsExpanded] = useState(false); - const { workflow, channels } = workflowPreferences; + const { workflow, channels, updatedAt } = workflowPreferences; return ( - {workflow.updatedAt && ( + {updatedAt && ( Updated at{' '} - {formatDateSimple(workflow.updatedAt, { + {formatDateSimple(updatedAt, { month: 'short', day: '2-digit', year: 'numeric', diff --git a/apps/dashboard/src/utils/self-hosted/organization-switcher.tsx b/apps/dashboard/src/utils/self-hosted/organization-switcher.tsx index 687d428cedf..687f60197ab 100644 --- a/apps/dashboard/src/utils/self-hosted/organization-switcher.tsx +++ b/apps/dashboard/src/utils/self-hosted/organization-switcher.tsx @@ -1,30 +1,35 @@ import { Avatar } from '@/components/primitives/avatar'; -import { Button } from '@/components/primitives/button'; import { NovuLogoBlackBg } from './icons'; import { useOrganization } from './index'; function OrganizationSwitcherComponent() { - const { organization } = useOrganization() as { organization: { name: string } | undefined }; + const { organization, isLoaded } = useOrganization() as { + organization: { name: string } | undefined; + isLoaded: boolean; + }; + + if (!isLoaded) { + return ( +
+
+
+
+ ); + } if (!organization) return null; return ( -
- +
+ + + {organization.name} +
); } -export { OrganizationSwitcherComponent as OrganizationSwitcher, OrganizationSwitcherComponent as OrganizationDropdown }; +export { OrganizationSwitcherComponent as OrganizationDropdown, OrganizationSwitcherComponent as OrganizationSwitcher }; const OrganizationAvatar = ({ shining = false }: { shining?: boolean }) => { return ( diff --git a/apps/dashboard/src/utils/self-hosted/organization.resource.tsx b/apps/dashboard/src/utils/self-hosted/organization.resource.tsx index 28a925809ca..60b22f03a0d 100644 --- a/apps/dashboard/src/utils/self-hosted/organization.resource.tsx +++ b/apps/dashboard/src/utils/self-hosted/organization.resource.tsx @@ -16,10 +16,11 @@ const getCurrentOrganization = withJwtValidation(async () => { }); export function OrganizationContextProvider({ children }: any) { + const hasToken = !!getJwtToken(); const { data: organization, isLoading } = useQuery({ queryKey: [QueryKeys.myOrganization], queryFn: getCurrentOrganization, - enabled: !!getJwtToken(), + enabled: hasToken, }); const value = { @@ -34,17 +35,8 @@ export function OrganizationContextProvider({ children }: any) { }, _id: organization._id, } - : { - name: 'System Organization', - createdAt: new Date(), - updatedAt: new Date(), - externalOrgId: null, - publicMetadata: { - externalOrgId: null, - }, - _id: null, - }, - isLoaded: isLoading, + : undefined, + isLoaded: hasToken ? !isLoading : true, }; return {children}; diff --git a/apps/dashboard/src/utils/self-hosted/user.resource.tsx b/apps/dashboard/src/utils/self-hosted/user.resource.tsx index c699c204dce..81bf40f671d 100644 --- a/apps/dashboard/src/utils/self-hosted/user.resource.tsx +++ b/apps/dashboard/src/utils/self-hosted/user.resource.tsx @@ -4,10 +4,10 @@ import { DecodedJwt } from '.'; import { createUserFromJwt, SelfHostedUser } from './user.types'; export const UserContext = React.createContext<{ - user: SelfHostedUser; + user: SelfHostedUser | null; isLoaded: boolean; }>({ - user: createUserFromJwt(null), + user: null, isLoaded: false, }); diff --git a/apps/dashboard/src/utils/self-hosted/user.types.ts b/apps/dashboard/src/utils/self-hosted/user.types.ts index b03d0b7204f..5ca85bfd222 100644 --- a/apps/dashboard/src/utils/self-hosted/user.types.ts +++ b/apps/dashboard/src/utils/self-hosted/user.types.ts @@ -14,14 +14,18 @@ export interface SelfHostedUser { passwordEnabled: boolean; } -export function createUserFromJwt(decodedJwt: DecodedJwt | null): SelfHostedUser { +export function createUserFromJwt(decodedJwt: DecodedJwt | null): SelfHostedUser | null { + if (!decodedJwt) { + return null; + } + return { update: async () => null, reload: async () => null, - externalId: decodedJwt?._id, - firstName: decodedJwt?.firstName, - lastName: decodedJwt?.lastName, - emailAddresses: [{ emailAddress: decodedJwt?.email }], + externalId: decodedJwt._id, + firstName: decodedJwt.firstName, + lastName: decodedJwt.lastName, + emailAddresses: [{ emailAddress: decodedJwt.email }], createdAt: new Date(), publicMetadata: { newDashboardOptInStatus: 'opted_in' }, unsafeMetadata: { newDashboardOptInStatus: 'opted_in' }, diff --git a/apps/dashboard/vite.config.ts b/apps/dashboard/vite.config.ts index e634e498e1a..fecff649b7a 100644 --- a/apps/dashboard/vite.config.ts +++ b/apps/dashboard/vite.config.ts @@ -86,17 +86,16 @@ export default defineConfig(({ mode }) => { }, resolve: { alias: { - '@': path.resolve(__dirname, './src'), ...(isCommunitySelHosted ? { '@clerk/clerk-react': path.resolve(__dirname, './src/utils/self-hosted/index.tsx'), - '@/context/region': path.resolve(__dirname, './src/context/region/index.self-hosted.ts'), '@/components/side-navigation/organization-dropdown-clerk': path.resolve( __dirname, './src/utils/self-hosted/organization-switcher.tsx' ), } : {}), + '@': path.resolve(__dirname, './src'), // Explicitly map prettier imports to browser-compatible versions 'prettier/standalone': path.resolve(__dirname, './node_modules/prettier/standalone.js'), 'prettier/plugins/html': path.resolve(__dirname, './node_modules/prettier/plugins/html.js'), diff --git a/biome-plugins/pino-logger-arg-order.grit b/biome-plugins/pino-logger-arg-order.grit new file mode 100644 index 00000000000..d6ffc99fe43 --- /dev/null +++ b/biome-plugins/pino-logger-arg-order.grit @@ -0,0 +1,22 @@ +// Flags reversed pino arg order: this.logger.info(message, { ... }) +// Pino expects: this.logger.info({ ... }, message) + +engine biome(1.0) +language js(typescript) + +`this.logger.$level($message, $context)` where { + $level <: r"trace|debug|info|warn|error|fatal", + + // 2nd arg is an object literal (any properties, including shorthand) + $context <: r"\{[\s\S]*\}", + + // Avoid flagging correct order: this.logger.info({ ... }, message) + not $message <: r"\{[\s\S]*\}", + + register_diagnostic( + span = $match, + severity = "warn", + message = "Pino expects (object, message). Use this.logger.({ ... }, message) instead of this.logger.(message, { ... })." + ) +} + diff --git a/biome.json b/biome.json index ce8b5134cef..f554bab361f 100644 --- a/biome.json +++ b/biome.json @@ -279,6 +279,14 @@ } } }, + { + "includes": [ + "apps/api/**/*.{ts,tsx,js}", + "apps/worker/**/*.{ts,tsx,js}", + "libs/application-generic/**/*.{ts,tsx,js}" + ], + "plugins": ["./biome-plugins/pino-logger-arg-order.grit"] + }, { "includes": ["**/*.dto.ts"], "plugins": ["./biome-plugins/api-property-record-type.grit"] diff --git a/libs/dal/src/repositories/base-repository.ts b/libs/dal/src/repositories/base-repository.ts index ad8f643bd17..f491ebe3f3e 100644 --- a/libs/dal/src/repositories/base-repository.ts +++ b/libs/dal/src/repositories/base-repository.ts @@ -84,11 +84,14 @@ export class BaseRepository { readPreference?: 'secondaryPreferred' | 'primary'; query?: QueryOptions; session?: ClientSession | null; + enhanceQuery?: >( + queryBuilder: TQuery + ) => QueryWithHelpers; } = {} ): Promise { const { session, ...queryOptions } = options; - const queryBuilder = this.MongooseModel.findOne(query, select, queryOptions.query).read( + let queryBuilder = this.MongooseModel.findOne(query, select, queryOptions.query).read( queryOptions.readPreference || 'primary' ); @@ -96,6 +99,10 @@ export class BaseRepository { queryBuilder.session(session); } + if (options.enhanceQuery) { + queryBuilder = options.enhanceQuery(queryBuilder) as typeof queryBuilder; + } + const data = await queryBuilder; if (!data) return null; diff --git a/libs/dal/src/repositories/message/message.repository.ts b/libs/dal/src/repositories/message/message.repository.ts index b1a76b43845..b0929d44492 100644 --- a/libs/dal/src/repositories/message/message.repository.ts +++ b/libs/dal/src/repositories/message/message.repository.ts @@ -76,6 +76,30 @@ export class MessageRepository extends BaseRepository & EnforceEnvId, + select?: ProjectionType, + options: { + readPreference?: 'secondaryPreferred' | 'primary'; + query?: any; + session?: any; + } = {} + ): Promise { + const transformedQuery = this.transformContextKeysQuery(query) as FilterQuery & EnforceEnvId; + + return super.findOne(transformedQuery, select, { + ...options, + enhanceQuery: (queryBuilder) => + queryBuilder.populate('subscriber', '_id firstName lastName avatar subscriberId').populate({ + path: 'template', + select: '_id name tags data critical triggers severity', + options: { + withDeleted: true, + }, + }), + }); + } + private async getFilterQueryForMessage( environmentId: string, subscriberId: string, diff --git a/libs/dal/src/repositories/preferences/preferences.entity.ts b/libs/dal/src/repositories/preferences/preferences.entity.ts index b5432745bd3..28f779fcf5d 100644 --- a/libs/dal/src/repositories/preferences/preferences.entity.ts +++ b/libs/dal/src/repositories/preferences/preferences.entity.ts @@ -32,4 +32,8 @@ export class PreferencesEntity { preferences: WorkflowPreferencesPartial; schedule?: Schedule; + + createdAt?: string; + + updatedAt?: string; } diff --git a/libs/internal-sdk/.speakeasy/gen.yaml b/libs/internal-sdk/.speakeasy/gen.yaml index 529b22cc267..c7661901093 100755 --- a/libs/internal-sdk/.speakeasy/gen.yaml +++ b/libs/internal-sdk/.speakeasy/gen.yaml @@ -64,6 +64,7 @@ typescript: enableReactQuery: true enumFormat: union exportZodModelNamespace: false + flatAdditionalProperties: false flattenGlobalSecurity: true flatteningOrder: body-first formStringArrayEncodeMode: encoded-string diff --git a/libs/internal-sdk/src/funcs/activityWorkflowRunsList.ts b/libs/internal-sdk/src/funcs/activityWorkflowRunsList.ts index 4698e4e129c..90dece641a0 100644 --- a/libs/internal-sdk/src/funcs/activityWorkflowRunsList.ts +++ b/libs/internal-sdk/src/funcs/activityWorkflowRunsList.ts @@ -2,28 +2,28 @@ * Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT. */ -import { NovuCore } from "../core.js"; -import { encodeFormQuery, encodeSimple } from "../lib/encodings.js"; -import * as M from "../lib/matchers.js"; -import { compactMap } from "../lib/primitives.js"; -import { safeParse } from "../lib/schemas.js"; -import { RequestOptions } from "../lib/sdks.js"; -import { extractSecurity, resolveGlobalSecurity } from "../lib/security.js"; -import { pathToFunc } from "../lib/url.js"; -import * as components from "../models/components/index.js"; +import { NovuCore } from '../core.js'; +import { encodeFormQuery, encodeSimple } from '../lib/encodings.js'; +import * as M from '../lib/matchers.js'; +import { compactMap } from '../lib/primitives.js'; +import { safeParse } from '../lib/schemas.js'; +import { RequestOptions } from '../lib/sdks.js'; +import { extractSecurity, resolveGlobalSecurity } from '../lib/security.js'; +import { pathToFunc } from '../lib/url.js'; +import * as components from '../models/components/index.js'; import { ConnectionError, InvalidRequestError, RequestAbortedError, RequestTimeoutError, UnexpectedClientError, -} from "../models/errors/httpclienterrors.js"; -import { NovuError } from "../models/errors/novuerror.js"; -import { ResponseValidationError } from "../models/errors/responsevalidationerror.js"; -import { SDKValidationError } from "../models/errors/sdkvalidationerror.js"; -import * as operations from "../models/operations/index.js"; -import { APICall, APIPromise } from "../types/async.js"; -import { Result } from "../types/fp.js"; +} from '../models/errors/httpclienterrors.js'; +import { NovuError } from '../models/errors/novuerror.js'; +import { ResponseValidationError } from '../models/errors/responsevalidationerror.js'; +import { SDKValidationError } from '../models/errors/sdkvalidationerror.js'; +import * as operations from '../models/operations/index.js'; +import { APICall, APIPromise } from '../types/async.js'; +import { Result } from '../types/fp.js'; /** * List workflow runs @@ -34,7 +34,7 @@ import { Result } from "../types/fp.js"; export function activityWorkflowRunsList( client: NovuCore, request: operations.ActivityControllerGetWorkflowRunsRequest, - options?: RequestOptions, + options?: RequestOptions ): APIPromise< Result< components.GetWorkflowRunsResponseDto, @@ -48,17 +48,13 @@ export function activityWorkflowRunsList( | SDKValidationError > > { - return new APIPromise($do( - client, - request, - options, - )); + return new APIPromise($do(client, request, options)); } async function $do( client: NovuCore, request: operations.ActivityControllerGetWorkflowRunsRequest, - options?: RequestOptions, + options?: RequestOptions ): Promise< [ Result< @@ -77,60 +73,58 @@ async function $do( > { const parsed = safeParse( request, - (value) => - operations.ActivityControllerGetWorkflowRunsRequest$outboundSchema.parse( - value, - ), - "Input validation failed", + (value) => operations.ActivityControllerGetWorkflowRunsRequest$outboundSchema.parse(value), + 'Input validation failed' ); if (!parsed.ok) { - return [parsed, { status: "invalid" }]; + return [parsed, { status: 'invalid' }]; } const payload = parsed.value; const body = null; - const path = pathToFunc("/v1/activity/workflow-runs")(); + const path = pathToFunc('/v1/activity/workflow-runs')(); const query = encodeFormQuery({ - "channels": payload.channels, - "contextKeys": payload.contextKeys, - "createdGte": payload.createdGte, - "createdLte": payload.createdLte, - "cursor": payload.cursor, - "limit": payload.limit, - "severity": payload.severity, - "statuses": payload.statuses, - "subscriberIds": payload.subscriberIds, - "topicKey": payload.topicKey, - "transactionIds": payload.transactionIds, - "workflowIds": payload.workflowIds, + channels: payload.channels, + contextKeys: payload.contextKeys, + createdGte: payload.createdGte, + createdLte: payload.createdLte, + cursor: payload.cursor, + limit: payload.limit, + severity: payload.severity, + statuses: payload.statuses, + subscriberIds: payload.subscriberIds, + subscriptionId: payload.subscriptionId, + topicKey: payload.topicKey, + transactionIds: payload.transactionIds, + workflowIds: payload.workflowIds, }); - const headers = new Headers(compactMap({ - Accept: "application/json", - "idempotency-key": encodeSimple( - "idempotency-key", - payload["idempotency-key"], - { explode: false, charEncoding: "none" }, - ), - })); + const headers = new Headers( + compactMap({ + Accept: 'application/json', + 'idempotency-key': encodeSimple('idempotency-key', payload['idempotency-key'], { + explode: false, + charEncoding: 'none', + }), + }) + ); const securityInput = await extractSecurity(client._options.security); const requestSecurity = resolveGlobalSecurity(securityInput); const context = { options: client._options, - baseURL: options?.serverURL ?? client._baseURL ?? "", - operationID: "ActivityController_getWorkflowRuns", + baseURL: options?.serverURL ?? client._baseURL ?? '', + operationID: 'ActivityController_getWorkflowRuns', oAuth2Scopes: null, resolvedSecurity: requestSecurity, securitySource: client._options.security, - retryConfig: options?.retries - || client._options.retryConfig - || { - strategy: "backoff", + retryConfig: options?.retries || + client._options.retryConfig || { + strategy: 'backoff', backoff: { initialInterval: 1000, maxInterval: 30000, @@ -138,35 +132,38 @@ async function $do( maxElapsedTime: 3600000, }, retryConnectionErrors: true, - } - || { strategy: "none" }, - retryCodes: options?.retryCodes || ["408", "409", "429", "5XX"], + } || { strategy: 'none' }, + retryCodes: options?.retryCodes || ['408', '409', '429', '5XX'], }; - const requestRes = client._createRequest(context, { - security: requestSecurity, - method: "GET", - baseURL: options?.serverURL, - path: path, - headers: headers, - query: query, - body: body, - userAgent: client._options.userAgent, - timeoutMs: options?.timeoutMs || client._options.timeoutMs || -1, - }, options); + const requestRes = client._createRequest( + context, + { + security: requestSecurity, + method: 'GET', + baseURL: options?.serverURL, + path: path, + headers: headers, + query: query, + body: body, + userAgent: client._options.userAgent, + timeoutMs: options?.timeoutMs || client._options.timeoutMs || -1, + }, + options + ); if (!requestRes.ok) { - return [requestRes, { status: "invalid" }]; + return [requestRes, { status: 'invalid' }]; } const req = requestRes.value; const doResult = await client._do(req, { context, - errorCodes: ["4XX", "5XX"], + errorCodes: ['4XX', '5XX'], retryConfig: context.retryConfig, retryCodes: context.retryCodes, }); if (!doResult.ok) { - return [doResult, { status: "request-error", request: req }]; + return [doResult, { status: 'request-error', request: req }]; } const response = doResult.value; @@ -182,12 +179,12 @@ async function $do( | SDKValidationError >( M.json(200, components.GetWorkflowRunsResponseDto$inboundSchema), - M.fail("4XX"), - M.fail("5XX"), + M.fail('4XX'), + M.fail('5XX') )(response, req); if (!result.ok) { - return [result, { status: "complete", request: req, response }]; + return [result, { status: 'complete', request: req, response }]; } - return [result, { status: "complete", request: req, response }]; + return [result, { status: 'complete', request: req, response }]; } diff --git a/libs/internal-sdk/src/funcs/notificationsList.ts b/libs/internal-sdk/src/funcs/notificationsList.ts index 026e0360aa4..2afee6d13b5 100644 --- a/libs/internal-sdk/src/funcs/notificationsList.ts +++ b/libs/internal-sdk/src/funcs/notificationsList.ts @@ -2,28 +2,28 @@ * Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT. */ -import { NovuCore } from "../core.js"; -import { encodeFormQuery, encodeSimple } from "../lib/encodings.js"; -import * as M from "../lib/matchers.js"; -import { compactMap } from "../lib/primitives.js"; -import { safeParse } from "../lib/schemas.js"; -import { RequestOptions } from "../lib/sdks.js"; -import { extractSecurity, resolveGlobalSecurity } from "../lib/security.js"; -import { pathToFunc } from "../lib/url.js"; +import { NovuCore } from '../core.js'; +import { encodeFormQuery, encodeSimple } from '../lib/encodings.js'; +import * as M from '../lib/matchers.js'; +import { compactMap } from '../lib/primitives.js'; +import { safeParse } from '../lib/schemas.js'; +import { RequestOptions } from '../lib/sdks.js'; +import { extractSecurity, resolveGlobalSecurity } from '../lib/security.js'; +import { pathToFunc } from '../lib/url.js'; import { ConnectionError, InvalidRequestError, RequestAbortedError, RequestTimeoutError, UnexpectedClientError, -} from "../models/errors/httpclienterrors.js"; -import * as errors from "../models/errors/index.js"; -import { NovuError } from "../models/errors/novuerror.js"; -import { ResponseValidationError } from "../models/errors/responsevalidationerror.js"; -import { SDKValidationError } from "../models/errors/sdkvalidationerror.js"; -import * as operations from "../models/operations/index.js"; -import { APICall, APIPromise } from "../types/async.js"; -import { Result } from "../types/fp.js"; +} from '../models/errors/httpclienterrors.js'; +import * as errors from '../models/errors/index.js'; +import { NovuError } from '../models/errors/novuerror.js'; +import { ResponseValidationError } from '../models/errors/responsevalidationerror.js'; +import { SDKValidationError } from '../models/errors/sdkvalidationerror.js'; +import * as operations from '../models/operations/index.js'; +import { APICall, APIPromise } from '../types/async.js'; +import { Result } from '../types/fp.js'; /** * List all events @@ -37,7 +37,7 @@ import { Result } from "../types/fp.js"; export function notificationsList( client: NovuCore, request: operations.NotificationsControllerListNotificationsRequest, - options?: RequestOptions, + options?: RequestOptions ): APIPromise< Result< operations.NotificationsControllerListNotificationsResponse, @@ -53,17 +53,13 @@ export function notificationsList( | SDKValidationError > > { - return new APIPromise($do( - client, - request, - options, - )); + return new APIPromise($do(client, request, options)); } async function $do( client: NovuCore, request: operations.NotificationsControllerListNotificationsRequest, - options?: RequestOptions, + options?: RequestOptions ): Promise< [ Result< @@ -84,60 +80,59 @@ async function $do( > { const parsed = safeParse( request, - (value) => - operations.NotificationsControllerListNotificationsRequest$outboundSchema - .parse(value), - "Input validation failed", + (value) => operations.NotificationsControllerListNotificationsRequest$outboundSchema.parse(value), + 'Input validation failed' ); if (!parsed.ok) { - return [parsed, { status: "invalid" }]; + return [parsed, { status: 'invalid' }]; } const payload = parsed.value; const body = null; - const path = pathToFunc("/v1/notifications")(); + const path = pathToFunc('/v1/notifications')(); const query = encodeFormQuery({ - "after": payload.after, - "before": payload.before, - "channels": payload.channels, - "contextKeys": payload.contextKeys, - "emails": payload.emails, - "limit": payload.limit, - "page": payload.page, - "search": payload.search, - "severity": payload.severity, - "subscriberIds": payload.subscriberIds, - "templates": payload.templates, - "topicKey": payload.topicKey, - "transactionId": payload.transactionId, + after: payload.after, + before: payload.before, + channels: payload.channels, + contextKeys: payload.contextKeys, + emails: payload.emails, + limit: payload.limit, + page: payload.page, + search: payload.search, + severity: payload.severity, + subscriberIds: payload.subscriberIds, + subscriptionId: payload.subscriptionId, + templates: payload.templates, + topicKey: payload.topicKey, + transactionId: payload.transactionId, }); - const headers = new Headers(compactMap({ - Accept: "application/json", - "idempotency-key": encodeSimple( - "idempotency-key", - payload["idempotency-key"], - { explode: false, charEncoding: "none" }, - ), - })); + const headers = new Headers( + compactMap({ + Accept: 'application/json', + 'idempotency-key': encodeSimple('idempotency-key', payload['idempotency-key'], { + explode: false, + charEncoding: 'none', + }), + }) + ); const securityInput = await extractSecurity(client._options.security); const requestSecurity = resolveGlobalSecurity(securityInput); const context = { options: client._options, - baseURL: options?.serverURL ?? client._baseURL ?? "", - operationID: "NotificationsController_listNotifications", + baseURL: options?.serverURL ?? client._baseURL ?? '', + operationID: 'NotificationsController_listNotifications', oAuth2Scopes: null, resolvedSecurity: requestSecurity, securitySource: client._options.security, - retryConfig: options?.retries - || client._options.retryConfig - || { - strategy: "backoff", + retryConfig: options?.retries || + client._options.retryConfig || { + strategy: 'backoff', backoff: { initialInterval: 1000, maxInterval: 30000, @@ -145,51 +140,54 @@ async function $do( maxElapsedTime: 3600000, }, retryConnectionErrors: true, - } - || { strategy: "none" }, - retryCodes: options?.retryCodes || ["408", "409", "429", "5XX"], + } || { strategy: 'none' }, + retryCodes: options?.retryCodes || ['408', '409', '429', '5XX'], }; - const requestRes = client._createRequest(context, { - security: requestSecurity, - method: "GET", - baseURL: options?.serverURL, - path: path, - headers: headers, - query: query, - body: body, - userAgent: client._options.userAgent, - timeoutMs: options?.timeoutMs || client._options.timeoutMs || -1, - }, options); + const requestRes = client._createRequest( + context, + { + security: requestSecurity, + method: 'GET', + baseURL: options?.serverURL, + path: path, + headers: headers, + query: query, + body: body, + userAgent: client._options.userAgent, + timeoutMs: options?.timeoutMs || client._options.timeoutMs || -1, + }, + options + ); if (!requestRes.ok) { - return [requestRes, { status: "invalid" }]; + return [requestRes, { status: 'invalid' }]; } const req = requestRes.value; const doResult = await client._do(req, { context, errorCodes: [ - "400", - "401", - "403", - "404", - "405", - "409", - "413", - "414", - "415", - "422", - "429", - "4XX", - "500", - "503", - "5XX", + '400', + '401', + '403', + '404', + '405', + '409', + '413', + '414', + '415', + '422', + '429', + '4XX', + '500', + '503', + '5XX', ], retryConfig: context.retryConfig, retryCodes: context.retryCodes, }); if (!doResult.ok) { - return [doResult, { status: "request-error", request: req }]; + return [doResult, { status: 'request-error', request: req }]; } const response = doResult.value; @@ -210,27 +208,22 @@ async function $do( | UnexpectedClientError | SDKValidationError >( - M.json( - 200, - operations.NotificationsControllerListNotificationsResponse$inboundSchema, - { hdrs: true, key: "Result" }, - ), + M.json(200, operations.NotificationsControllerListNotificationsResponse$inboundSchema, { + hdrs: true, + key: 'Result', + }), M.jsonErr(414, errors.ErrorDto$inboundSchema), - M.jsonErr( - [400, 401, 403, 404, 405, 409, 413, 415], - errors.ErrorDto$inboundSchema, - { hdrs: true }, - ), + M.jsonErr([400, 401, 403, 404, 405, 409, 413, 415], errors.ErrorDto$inboundSchema, { hdrs: true }), M.jsonErr(422, errors.ValidationErrorDto$inboundSchema, { hdrs: true }), M.fail(429), M.jsonErr(500, errors.ErrorDto$inboundSchema, { hdrs: true }), M.fail(503), - M.fail("4XX"), - M.fail("5XX"), + M.fail('4XX'), + M.fail('5XX') )(response, req, { extraFields: responseFields }); if (!result.ok) { - return [result, { status: "complete", request: req, response }]; + return [result, { status: 'complete', request: req, response }]; } - return [result, { status: "complete", request: req, response }]; + return [result, { status: 'complete', request: req, response }]; } diff --git a/libs/internal-sdk/src/lib/config.ts b/libs/internal-sdk/src/lib/config.ts index b94a5a2dfa2..1bfe131b974 100644 --- a/libs/internal-sdk/src/lib/config.ts +++ b/libs/internal-sdk/src/lib/config.ts @@ -2,28 +2,22 @@ * Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT. */ -import * as components from "../models/components/index.js"; -import { HTTPClient } from "./http.js"; -import { Logger } from "./logger.js"; -import { RetryConfig } from "./retries.js"; -import { Params, pathToFunc } from "./url.js"; +import * as components from '../models/components/index.js'; +import { HTTPClient } from './http.js'; +import { Logger } from './logger.js'; +import { RetryConfig } from './retries.js'; +import { Params, pathToFunc } from './url.js'; /** * Contains the list of servers available to the SDK */ -export const ServerList = [ - "https://api.novu.co", - "https://eu.api.novu.co", -] as const; +export const ServerList = ['https://api.novu.co', 'https://eu.api.novu.co'] as const; export type SDKOptions = { /** * The security details required to authenticate the SDK */ - security?: - | components.Security - | (() => Promise) - | undefined; + security?: components.Security | (() => Promise) | undefined; httpClient?: HTTPClient; /** @@ -56,7 +50,7 @@ export function serverURLFromOptions(options: SDKOptions): URL | null { if (serverIdx < 0 || serverIdx >= ServerList.length) { throw new Error(`Invalid server index ${serverIdx}`); } - serverURL = ServerList[serverIdx] || ""; + serverURL = ServerList[serverIdx] || ''; } const u = pathToFunc(serverURL)(params); @@ -64,9 +58,9 @@ export function serverURLFromOptions(options: SDKOptions): URL | null { } export const SDK_METADATA = { - language: "typescript", - openapiDocVersion: "3.11.0", - sdkVersion: "0.1.21", - genVersion: "2.788.5", - userAgent: "speakeasy-sdk/typescript 0.1.21 2.788.5 3.11.0 @novu/api", + language: 'typescript', + openapiDocVersion: '3.11.0', + sdkVersion: '0.1.21', + genVersion: '2.791.1', + userAgent: 'speakeasy-sdk/typescript 0.1.21 2.791.1 3.11.0 @novu/api', } as const; diff --git a/libs/internal-sdk/src/models/components/getworkflowrunresponsedto.ts b/libs/internal-sdk/src/models/components/getworkflowrunresponsedto.ts index cc3a6f68d09..a5dab6b0c4f 100644 --- a/libs/internal-sdk/src/models/components/getworkflowrunresponsedto.ts +++ b/libs/internal-sdk/src/models/components/getworkflowrunresponsedto.ts @@ -2,40 +2,39 @@ * Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT. */ -import * as z from "zod/v3"; -import { safeParse } from "../../lib/schemas.js"; -import { ClosedEnum } from "../../types/enums.js"; -import { Result as SafeParseResult } from "../../types/fp.js"; -import { SDKValidationError } from "../errors/sdkvalidationerror.js"; -import { StepRunDto, StepRunDto$inboundSchema } from "./steprundto.js"; +import * as z from 'zod/v3'; +import { safeParse } from '../../lib/schemas.js'; +import { ClosedEnum } from '../../types/enums.js'; +import { Result as SafeParseResult } from '../../types/fp.js'; +import { SDKValidationError } from '../errors/sdkvalidationerror.js'; +import { StepRunDto, StepRunDto$inboundSchema } from './steprundto.js'; +import { TopicResponseDto, TopicResponseDto$inboundSchema } from './topicresponsedto.js'; /** * Workflow run status */ export const GetWorkflowRunResponseDtoStatus = { - Processing: "processing", - Completed: "completed", - Error: "error", + Processing: 'processing', + Completed: 'completed', + Error: 'error', } as const; /** * Workflow run status */ -export type GetWorkflowRunResponseDtoStatus = ClosedEnum< - typeof GetWorkflowRunResponseDtoStatus ->; +export type GetWorkflowRunResponseDtoStatus = ClosedEnum; /** * Workflow run delivery lifecycle status */ export const GetWorkflowRunResponseDtoDeliveryLifecycleStatus = { - Pending: "pending", - Sent: "sent", - Errored: "errored", - Skipped: "skipped", - Canceled: "canceled", - Merged: "merged", - Delivered: "delivered", - Interacted: "interacted", + Pending: 'pending', + Sent: 'sent', + Errored: 'errored', + Skipped: 'skipped', + Canceled: 'canceled', + Merged: 'merged', + Delivered: 'delivered', + Interacted: 'interacted', } as const; /** * Workflow run delivery lifecycle status @@ -48,17 +47,15 @@ export type GetWorkflowRunResponseDtoDeliveryLifecycleStatus = ClosedEnum< * Severity */ export const GetWorkflowRunResponseDtoSeverity = { - High: "high", - Medium: "medium", - Low: "low", - None: "none", + High: 'high', + Medium: 'medium', + Low: 'low', + None: 'none', } as const; /** * Severity */ -export type GetWorkflowRunResponseDtoSeverity = ClosedEnum< - typeof GetWorkflowRunResponseDtoSeverity ->; +export type GetWorkflowRunResponseDtoSeverity = ClosedEnum; /** * Trigger payload @@ -130,6 +127,10 @@ export type GetWorkflowRunResponseDto = { * Context (single or multi) in which the workflow run was executed */ contextKeys?: Array | undefined; + /** + * Topics + */ + topics?: Array | undefined; /** * Step runs */ @@ -141,14 +142,13 @@ export type GetWorkflowRunResponseDto = { }; /** @internal */ -export const GetWorkflowRunResponseDtoStatus$inboundSchema: z.ZodNativeEnum< - typeof GetWorkflowRunResponseDtoStatus -> = z.nativeEnum(GetWorkflowRunResponseDtoStatus); +export const GetWorkflowRunResponseDtoStatus$inboundSchema: z.ZodNativeEnum = + z.nativeEnum(GetWorkflowRunResponseDtoStatus); /** @internal */ -export const GetWorkflowRunResponseDtoDeliveryLifecycleStatus$inboundSchema: - z.ZodNativeEnum = z - .nativeEnum(GetWorkflowRunResponseDtoDeliveryLifecycleStatus); +export const GetWorkflowRunResponseDtoDeliveryLifecycleStatus$inboundSchema: z.ZodNativeEnum< + typeof GetWorkflowRunResponseDtoDeliveryLifecycleStatus +> = z.nativeEnum(GetWorkflowRunResponseDtoDeliveryLifecycleStatus); /** @internal */ export const GetWorkflowRunResponseDtoSeverity$inboundSchema: z.ZodNativeEnum< @@ -156,52 +156,46 @@ export const GetWorkflowRunResponseDtoSeverity$inboundSchema: z.ZodNativeEnum< > = z.nativeEnum(GetWorkflowRunResponseDtoSeverity); /** @internal */ -export const Payload$inboundSchema: z.ZodType = - z.object({}); +export const Payload$inboundSchema: z.ZodType = z.object({}); -export function payloadFromJSON( - jsonString: string, -): SafeParseResult { +export function payloadFromJSON(jsonString: string): SafeParseResult { return safeParse( jsonString, (x) => Payload$inboundSchema.parse(JSON.parse(x)), - `Failed to parse 'Payload' from JSON`, + `Failed to parse 'Payload' from JSON` ); } /** @internal */ -export const GetWorkflowRunResponseDto$inboundSchema: z.ZodType< - GetWorkflowRunResponseDto, - z.ZodTypeDef, - unknown -> = z.object({ - id: z.string(), - workflowId: z.string(), - workflowName: z.string(), - organizationId: z.string(), - environmentId: z.string(), - internalSubscriberId: z.string(), - subscriberId: z.string().optional(), - status: GetWorkflowRunResponseDtoStatus$inboundSchema, - deliveryLifecycleStatus: - GetWorkflowRunResponseDtoDeliveryLifecycleStatus$inboundSchema, - triggerIdentifier: z.string(), - transactionId: z.string(), - createdAt: z.string(), - updatedAt: z.string(), - severity: GetWorkflowRunResponseDtoSeverity$inboundSchema, - critical: z.boolean(), - contextKeys: z.array(z.string()).optional(), - steps: z.array(StepRunDto$inboundSchema), - payload: z.lazy(() => Payload$inboundSchema), -}); +export const GetWorkflowRunResponseDto$inboundSchema: z.ZodType = + z.object({ + id: z.string(), + workflowId: z.string(), + workflowName: z.string(), + organizationId: z.string(), + environmentId: z.string(), + internalSubscriberId: z.string(), + subscriberId: z.string().optional(), + status: GetWorkflowRunResponseDtoStatus$inboundSchema, + deliveryLifecycleStatus: GetWorkflowRunResponseDtoDeliveryLifecycleStatus$inboundSchema, + triggerIdentifier: z.string(), + transactionId: z.string(), + createdAt: z.string(), + updatedAt: z.string(), + severity: GetWorkflowRunResponseDtoSeverity$inboundSchema, + critical: z.boolean(), + contextKeys: z.array(z.string()).optional(), + topics: z.array(TopicResponseDto$inboundSchema).optional(), + steps: z.array(StepRunDto$inboundSchema), + payload: z.lazy(() => Payload$inboundSchema), + }); export function getWorkflowRunResponseDtoFromJSON( - jsonString: string, + jsonString: string ): SafeParseResult { return safeParse( jsonString, (x) => GetWorkflowRunResponseDto$inboundSchema.parse(JSON.parse(x)), - `Failed to parse 'GetWorkflowRunResponseDto' from JSON`, + `Failed to parse 'GetWorkflowRunResponseDto' from JSON` ); } diff --git a/libs/internal-sdk/src/models/components/getworkflowrunsdto.ts b/libs/internal-sdk/src/models/components/getworkflowrunsdto.ts index 9bb34898054..d562706ae08 100644 --- a/libs/internal-sdk/src/models/components/getworkflowrunsdto.ts +++ b/libs/internal-sdk/src/models/components/getworkflowrunsdto.ts @@ -2,59 +2,53 @@ * Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT. */ -import * as z from "zod/v3"; -import { safeParse } from "../../lib/schemas.js"; -import { ClosedEnum } from "../../types/enums.js"; -import { Result as SafeParseResult } from "../../types/fp.js"; -import { SDKValidationError } from "../errors/sdkvalidationerror.js"; -import { - WorkflowRunStepsDetailsDto, - WorkflowRunStepsDetailsDto$inboundSchema, -} from "./workflowrunstepsdetailsdto.js"; +import * as z from 'zod/v3'; +import { safeParse } from '../../lib/schemas.js'; +import { ClosedEnum } from '../../types/enums.js'; +import { Result as SafeParseResult } from '../../types/fp.js'; +import { SDKValidationError } from '../errors/sdkvalidationerror.js'; +import { TopicResponseDto, TopicResponseDto$inboundSchema } from './topicresponsedto.js'; +import { WorkflowRunStepsDetailsDto, WorkflowRunStepsDetailsDto$inboundSchema } from './workflowrunstepsdetailsdto.js'; /** * Workflow run status */ export const GetWorkflowRunsDtoStatus = { - Processing: "processing", - Completed: "completed", - Error: "error", + Processing: 'processing', + Completed: 'completed', + Error: 'error', } as const; /** * Workflow run status */ -export type GetWorkflowRunsDtoStatus = ClosedEnum< - typeof GetWorkflowRunsDtoStatus ->; +export type GetWorkflowRunsDtoStatus = ClosedEnum; /** * Workflow run delivery lifecycle status */ export const DeliveryLifecycleStatus = { - Pending: "pending", - Sent: "sent", - Errored: "errored", - Skipped: "skipped", - Canceled: "canceled", - Merged: "merged", - Delivered: "delivered", - Interacted: "interacted", + Pending: 'pending', + Sent: 'sent', + Errored: 'errored', + Skipped: 'skipped', + Canceled: 'canceled', + Merged: 'merged', + Delivered: 'delivered', + Interacted: 'interacted', } as const; /** * Workflow run delivery lifecycle status */ -export type DeliveryLifecycleStatus = ClosedEnum< - typeof DeliveryLifecycleStatus ->; +export type DeliveryLifecycleStatus = ClosedEnum; /** * Severity */ export const Severity = { - High: "high", - Medium: "medium", - Low: "low", - None: "none", + High: 'high', + Medium: 'medium', + Low: 'low', + None: 'none', } as const; /** * Severity @@ -126,6 +120,10 @@ export type GetWorkflowRunsDto = { * Context (single or multi) in which the workflow run was executed */ contextKeys?: Array | undefined; + /** + * Topics + */ + topics?: Array | undefined; /** * Workflow run steps */ @@ -133,25 +131,18 @@ export type GetWorkflowRunsDto = { }; /** @internal */ -export const GetWorkflowRunsDtoStatus$inboundSchema: z.ZodNativeEnum< - typeof GetWorkflowRunsDtoStatus -> = z.nativeEnum(GetWorkflowRunsDtoStatus); +export const GetWorkflowRunsDtoStatus$inboundSchema: z.ZodNativeEnum = + z.nativeEnum(GetWorkflowRunsDtoStatus); /** @internal */ -export const DeliveryLifecycleStatus$inboundSchema: z.ZodNativeEnum< - typeof DeliveryLifecycleStatus -> = z.nativeEnum(DeliveryLifecycleStatus); +export const DeliveryLifecycleStatus$inboundSchema: z.ZodNativeEnum = + z.nativeEnum(DeliveryLifecycleStatus); /** @internal */ -export const Severity$inboundSchema: z.ZodNativeEnum = z - .nativeEnum(Severity); +export const Severity$inboundSchema: z.ZodNativeEnum = z.nativeEnum(Severity); /** @internal */ -export const GetWorkflowRunsDto$inboundSchema: z.ZodType< - GetWorkflowRunsDto, - z.ZodTypeDef, - unknown -> = z.object({ +export const GetWorkflowRunsDto$inboundSchema: z.ZodType = z.object({ id: z.string(), workflowId: z.string(), workflowName: z.string(), @@ -168,15 +159,16 @@ export const GetWorkflowRunsDto$inboundSchema: z.ZodType< severity: Severity$inboundSchema, critical: z.boolean(), contextKeys: z.array(z.string()).optional(), + topics: z.array(TopicResponseDto$inboundSchema).optional(), steps: z.array(WorkflowRunStepsDetailsDto$inboundSchema), }); export function getWorkflowRunsDtoFromJSON( - jsonString: string, + jsonString: string ): SafeParseResult { return safeParse( jsonString, (x) => GetWorkflowRunsDto$inboundSchema.parse(JSON.parse(x)), - `Failed to parse 'GetWorkflowRunsDto' from JSON`, + `Failed to parse 'GetWorkflowRunsDto' from JSON` ); } diff --git a/libs/internal-sdk/src/models/components/inappcontroldto.ts b/libs/internal-sdk/src/models/components/inappcontroldto.ts index 310ad4acfe7..410badc763f 100644 --- a/libs/internal-sdk/src/models/components/inappcontroldto.ts +++ b/libs/internal-sdk/src/models/components/inappcontroldto.ts @@ -2,22 +2,17 @@ * Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT. */ -import * as z from "zod/v3"; -import { safeParse } from "../../lib/schemas.js"; -import { Result as SafeParseResult } from "../../types/fp.js"; -import { SDKValidationError } from "../errors/sdkvalidationerror.js"; -import { - ActionDto, - ActionDto$inboundSchema, - ActionDto$Outbound, - ActionDto$outboundSchema, -} from "./actiondto.js"; +import * as z from 'zod/v3'; +import { safeParse } from '../../lib/schemas.js'; +import { Result as SafeParseResult } from '../../types/fp.js'; +import { SDKValidationError } from '../errors/sdkvalidationerror.js'; +import { ActionDto, ActionDto$inboundSchema, ActionDto$Outbound, ActionDto$outboundSchema } from './actiondto.js'; import { RedirectDto, RedirectDto$inboundSchema, RedirectDto$Outbound, RedirectDto$outboundSchema, -} from "./redirectdto.js"; +} from './redirectdto.js'; export type InAppControlDto = { /** @@ -33,7 +28,7 @@ export type InAppControlDto = { */ subject?: string | undefined; /** - * URL for an avatar image. Must be a valid URL or start with / or {{"{{"}} variable }}. + * URL for an avatar image. Must be a valid URL or start with / or {{ variable }}. */ avatar?: string | undefined; /** @@ -59,11 +54,7 @@ export type InAppControlDto = { }; /** @internal */ -export const InAppControlDto$inboundSchema: z.ZodType< - InAppControlDto, - z.ZodTypeDef, - unknown -> = z.object({ +export const InAppControlDto$inboundSchema: z.ZodType = z.object({ skip: z.record(z.any()).optional(), body: z.string().optional(), subject: z.string().optional(), @@ -88,33 +79,26 @@ export type InAppControlDto$Outbound = { }; /** @internal */ -export const InAppControlDto$outboundSchema: z.ZodType< - InAppControlDto$Outbound, - z.ZodTypeDef, - InAppControlDto -> = z.object({ - skip: z.record(z.any()).optional(), - body: z.string().optional(), - subject: z.string().optional(), - avatar: z.string().optional(), - primaryAction: ActionDto$outboundSchema.optional(), - secondaryAction: ActionDto$outboundSchema.optional(), - redirect: RedirectDto$outboundSchema.optional(), - disableOutputSanitization: z.boolean().default(false), - data: z.record(z.any()).optional(), -}); +export const InAppControlDto$outboundSchema: z.ZodType = + z.object({ + skip: z.record(z.any()).optional(), + body: z.string().optional(), + subject: z.string().optional(), + avatar: z.string().optional(), + primaryAction: ActionDto$outboundSchema.optional(), + secondaryAction: ActionDto$outboundSchema.optional(), + redirect: RedirectDto$outboundSchema.optional(), + disableOutputSanitization: z.boolean().default(false), + data: z.record(z.any()).optional(), + }); -export function inAppControlDtoToJSON( - inAppControlDto: InAppControlDto, -): string { +export function inAppControlDtoToJSON(inAppControlDto: InAppControlDto): string { return JSON.stringify(InAppControlDto$outboundSchema.parse(inAppControlDto)); } -export function inAppControlDtoFromJSON( - jsonString: string, -): SafeParseResult { +export function inAppControlDtoFromJSON(jsonString: string): SafeParseResult { return safeParse( jsonString, (x) => InAppControlDto$inboundSchema.parse(JSON.parse(x)), - `Failed to parse 'InAppControlDto' from JSON`, + `Failed to parse 'InAppControlDto' from JSON` ); } diff --git a/libs/internal-sdk/src/models/components/inappstepresponsedto.ts b/libs/internal-sdk/src/models/components/inappstepresponsedto.ts index 4399cde0731..0de1af19383 100644 --- a/libs/internal-sdk/src/models/components/inappstepresponsedto.ts +++ b/libs/internal-sdk/src/models/components/inappstepresponsedto.ts @@ -2,25 +2,19 @@ * Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT. */ -import * as z from "zod/v3"; -import { remap as remap$ } from "../../lib/primitives.js"; -import { - collectExtraKeys as collectExtraKeys$, - safeParse, -} from "../../lib/schemas.js"; -import { Result as SafeParseResult } from "../../types/fp.js"; -import { SDKValidationError } from "../errors/sdkvalidationerror.js"; -import { ActionDto, ActionDto$inboundSchema } from "./actiondto.js"; +import * as z from 'zod/v3'; +import { remap as remap$ } from '../../lib/primitives.js'; +import { collectExtraKeys as collectExtraKeys$, safeParse } from '../../lib/schemas.js'; +import { Result as SafeParseResult } from '../../types/fp.js'; +import { SDKValidationError } from '../errors/sdkvalidationerror.js'; +import { ActionDto, ActionDto$inboundSchema } from './actiondto.js'; import { InAppControlsMetadataResponseDto, InAppControlsMetadataResponseDto$inboundSchema, -} from "./inappcontrolsmetadataresponsedto.js"; -import { RedirectDto, RedirectDto$inboundSchema } from "./redirectdto.js"; -import { - ResourceOriginEnum, - ResourceOriginEnum$inboundSchema, -} from "./resourceoriginenum.js"; -import { StepIssuesDto, StepIssuesDto$inboundSchema } from "./stepissuesdto.js"; +} from './inappcontrolsmetadataresponsedto.js'; +import { RedirectDto, RedirectDto$inboundSchema } from './redirectdto.js'; +import { ResourceOriginEnum, ResourceOriginEnum$inboundSchema } from './resourceoriginenum.js'; +import { StepIssuesDto, StepIssuesDto$inboundSchema } from './stepissuesdto.js'; /** * Control values for the in-app step @@ -39,7 +33,7 @@ export type InAppStepResponseDtoControlValues = { */ subject?: string | undefined; /** - * URL for an avatar image. Must be a valid URL or start with / or {{"{{"}} variable }}. + * URL for an avatar image. Must be a valid URL or start with / or {{ variable }}. */ avatar?: string | undefined; /** @@ -97,7 +91,7 @@ export type InAppStepResponseDto = { /** * Type of the step */ - type: "in_app"; + type: 'in_app'; /** * Origin of the layout */ @@ -122,62 +116,61 @@ export const InAppStepResponseDtoControlValues$inboundSchema: z.ZodType< z.ZodTypeDef, unknown > = collectExtraKeys$( - z.object({ - skip: z.record(z.any()).optional(), - body: z.string().optional(), - subject: z.string().optional(), - avatar: z.string().optional(), - primaryAction: ActionDto$inboundSchema.optional(), - secondaryAction: ActionDto$inboundSchema.optional(), - redirect: RedirectDto$inboundSchema.optional(), - disableOutputSanitization: z.boolean().default(false), - data: z.record(z.any()).optional(), - }).catchall(z.any()), - "additionalProperties", - true, + z + .object({ + skip: z.record(z.any()).optional(), + body: z.string().optional(), + subject: z.string().optional(), + avatar: z.string().optional(), + primaryAction: ActionDto$inboundSchema.optional(), + secondaryAction: ActionDto$inboundSchema.optional(), + redirect: RedirectDto$inboundSchema.optional(), + disableOutputSanitization: z.boolean().default(false), + data: z.record(z.any()).optional(), + }) + .catchall(z.any()), + 'additionalProperties', + true ); export function inAppStepResponseDtoControlValuesFromJSON( - jsonString: string, + jsonString: string ): SafeParseResult { return safeParse( jsonString, (x) => InAppStepResponseDtoControlValues$inboundSchema.parse(JSON.parse(x)), - `Failed to parse 'InAppStepResponseDtoControlValues' from JSON`, + `Failed to parse 'InAppStepResponseDtoControlValues' from JSON` ); } /** @internal */ -export const InAppStepResponseDto$inboundSchema: z.ZodType< - InAppStepResponseDto, - z.ZodTypeDef, - unknown -> = z.object({ - controls: InAppControlsMetadataResponseDto$inboundSchema, - controlValues: z.lazy(() => InAppStepResponseDtoControlValues$inboundSchema) - .optional(), - variables: z.record(z.any()), - stepId: z.string(), - _id: z.string(), - name: z.string(), - slug: z.string(), - type: z.literal("in_app"), - origin: ResourceOriginEnum$inboundSchema, - workflowId: z.string(), - workflowDatabaseId: z.string(), - issues: StepIssuesDto$inboundSchema.optional(), -}).transform((v) => { - return remap$(v, { - "_id": "id", +export const InAppStepResponseDto$inboundSchema: z.ZodType = z + .object({ + controls: InAppControlsMetadataResponseDto$inboundSchema, + controlValues: z.lazy(() => InAppStepResponseDtoControlValues$inboundSchema).optional(), + variables: z.record(z.any()), + stepId: z.string(), + _id: z.string(), + name: z.string(), + slug: z.string(), + type: z.literal('in_app'), + origin: ResourceOriginEnum$inboundSchema, + workflowId: z.string(), + workflowDatabaseId: z.string(), + issues: StepIssuesDto$inboundSchema.optional(), + }) + .transform((v) => { + return remap$(v, { + _id: 'id', + }); }); -}); export function inAppStepResponseDtoFromJSON( - jsonString: string, + jsonString: string ): SafeParseResult { return safeParse( jsonString, (x) => InAppStepResponseDto$inboundSchema.parse(JSON.parse(x)), - `Failed to parse 'InAppStepResponseDto' from JSON`, + `Failed to parse 'InAppStepResponseDto' from JSON` ); } diff --git a/libs/internal-sdk/src/models/components/notificationfeeditemdto.ts b/libs/internal-sdk/src/models/components/notificationfeeditemdto.ts index 992a630df50..972cda41c30 100644 --- a/libs/internal-sdk/src/models/components/notificationfeeditemdto.ts +++ b/libs/internal-sdk/src/models/components/notificationfeeditemdto.ts @@ -2,40 +2,29 @@ * Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT. */ -import * as z from "zod/v3"; -import { remap as remap$ } from "../../lib/primitives.js"; -import { safeParse } from "../../lib/schemas.js"; -import { ClosedEnum } from "../../types/enums.js"; -import { Result as SafeParseResult } from "../../types/fp.js"; -import { SDKValidationError } from "../errors/sdkvalidationerror.js"; -import { - ActorFeedItemDto, - ActorFeedItemDto$inboundSchema, -} from "./actorfeeditemdto.js"; -import { - ChannelTypeEnum, - ChannelTypeEnum$inboundSchema, -} from "./channeltypeenum.js"; -import { MessageCTA, MessageCTA$inboundSchema } from "./messagecta.js"; -import { - SubscriberFeedResponseDto, - SubscriberFeedResponseDto$inboundSchema, -} from "./subscriberfeedresponsedto.js"; +import * as z from 'zod/v3'; +import { remap as remap$ } from '../../lib/primitives.js'; +import { safeParse } from '../../lib/schemas.js'; +import { ClosedEnum } from '../../types/enums.js'; +import { Result as SafeParseResult } from '../../types/fp.js'; +import { SDKValidationError } from '../errors/sdkvalidationerror.js'; +import { ActorFeedItemDto, ActorFeedItemDto$inboundSchema } from './actorfeeditemdto.js'; +import { ChannelTypeEnum, ChannelTypeEnum$inboundSchema } from './channeltypeenum.js'; +import { MessageCTA, MessageCTA$inboundSchema } from './messagecta.js'; +import { SubscriberFeedResponseDto, SubscriberFeedResponseDto$inboundSchema } from './subscriberfeedresponsedto.js'; /** * Current status of the notification. */ export const NotificationFeedItemDtoStatus = { - Sent: "sent", - Error: "error", - Warning: "warning", + Sent: 'sent', + Error: 'error', + Warning: 'warning', } as const; /** * Current status of the notification. */ -export type NotificationFeedItemDtoStatus = ClosedEnum< - typeof NotificationFeedItemDtoStatus ->; +export type NotificationFeedItemDtoStatus = ClosedEnum; export type NotificationFeedItemDto = { /** @@ -122,6 +111,10 @@ export type NotificationFeedItemDto = { * Indicates whether the notification has been seen by the subscriber. */ seen: boolean; + /** + * Indicates whether the notification has been archived by the subscriber. + */ + archived: boolean; /** * Device tokens for push notifications, if applicable. */ @@ -153,68 +146,76 @@ export type NotificationFeedItemDto = { }; /** @internal */ -export const NotificationFeedItemDtoStatus$inboundSchema: z.ZodNativeEnum< - typeof NotificationFeedItemDtoStatus -> = z.nativeEnum(NotificationFeedItemDtoStatus); +export const NotificationFeedItemDtoStatus$inboundSchema: z.ZodNativeEnum = + z.nativeEnum(NotificationFeedItemDtoStatus); /** @internal */ -export const NotificationFeedItemDto$inboundSchema: z.ZodType< - NotificationFeedItemDto, - z.ZodTypeDef, - unknown -> = z.object({ - _id: z.string(), - _templateId: z.string(), - _environmentId: z.string(), - _messageTemplateId: z.string().optional(), - _organizationId: z.string(), - _notificationId: z.string(), - _subscriberId: z.string(), - _feedId: z.nullable(z.string()).optional(), - _jobId: z.string(), - createdAt: z.nullable( - z.string().datetime({ offset: true }).transform(v => new Date(v)), - ).optional(), - updatedAt: z.nullable( - z.string().datetime({ offset: true }).transform(v => new Date(v)), - ).optional(), - actor: ActorFeedItemDto$inboundSchema.optional(), - subscriber: SubscriberFeedResponseDto$inboundSchema.optional(), - transactionId: z.string(), - templateIdentifier: z.nullable(z.string()).optional(), - providerId: z.nullable(z.string()).optional(), - content: z.string(), - subject: z.nullable(z.string()).optional(), - channel: ChannelTypeEnum$inboundSchema, - read: z.boolean(), - seen: z.boolean(), - deviceTokens: z.nullable(z.array(z.string())).optional(), - cta: MessageCTA$inboundSchema, - status: NotificationFeedItemDtoStatus$inboundSchema, - payload: z.record(z.any()).optional(), - data: z.nullable(z.record(z.any())).optional(), - overrides: z.record(z.any()).optional(), - tags: z.nullable(z.array(z.string())).optional(), -}).transform((v) => { - return remap$(v, { - "_id": "id", - "_templateId": "templateId", - "_environmentId": "environmentId", - "_messageTemplateId": "messageTemplateId", - "_organizationId": "organizationId", - "_notificationId": "notificationId", - "_subscriberId": "subscriberId", - "_feedId": "feedId", - "_jobId": "jobId", +export const NotificationFeedItemDto$inboundSchema: z.ZodType = z + .object({ + _id: z.string(), + _templateId: z.string(), + _environmentId: z.string(), + _messageTemplateId: z.string().optional(), + _organizationId: z.string(), + _notificationId: z.string(), + _subscriberId: z.string(), + _feedId: z.nullable(z.string()).optional(), + _jobId: z.string(), + createdAt: z + .nullable( + z + .string() + .datetime({ offset: true }) + .transform((v) => new Date(v)) + ) + .optional(), + updatedAt: z + .nullable( + z + .string() + .datetime({ offset: true }) + .transform((v) => new Date(v)) + ) + .optional(), + actor: ActorFeedItemDto$inboundSchema.optional(), + subscriber: SubscriberFeedResponseDto$inboundSchema.optional(), + transactionId: z.string(), + templateIdentifier: z.nullable(z.string()).optional(), + providerId: z.nullable(z.string()).optional(), + content: z.string(), + subject: z.nullable(z.string()).optional(), + channel: ChannelTypeEnum$inboundSchema, + read: z.boolean(), + seen: z.boolean(), + archived: z.boolean(), + deviceTokens: z.nullable(z.array(z.string())).optional(), + cta: MessageCTA$inboundSchema, + status: NotificationFeedItemDtoStatus$inboundSchema, + payload: z.record(z.any()).optional(), + data: z.nullable(z.record(z.any())).optional(), + overrides: z.record(z.any()).optional(), + tags: z.nullable(z.array(z.string())).optional(), + }) + .transform((v) => { + return remap$(v, { + _id: 'id', + _templateId: 'templateId', + _environmentId: 'environmentId', + _messageTemplateId: 'messageTemplateId', + _organizationId: 'organizationId', + _notificationId: 'notificationId', + _subscriberId: 'subscriberId', + _feedId: 'feedId', + _jobId: 'jobId', + }); }); -}); export function notificationFeedItemDtoFromJSON( - jsonString: string, + jsonString: string ): SafeParseResult { return safeParse( jsonString, (x) => NotificationFeedItemDto$inboundSchema.parse(JSON.parse(x)), - `Failed to parse 'NotificationFeedItemDto' from JSON`, + `Failed to parse 'NotificationFeedItemDto' from JSON` ); } diff --git a/libs/internal-sdk/src/models/components/redirectdto.ts b/libs/internal-sdk/src/models/components/redirectdto.ts index d1fc1065f59..1eab6f53ad8 100644 --- a/libs/internal-sdk/src/models/components/redirectdto.ts +++ b/libs/internal-sdk/src/models/components/redirectdto.ts @@ -2,21 +2,21 @@ * Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT. */ -import * as z from "zod/v3"; -import { safeParse } from "../../lib/schemas.js"; -import { ClosedEnum } from "../../types/enums.js"; -import { Result as SafeParseResult } from "../../types/fp.js"; -import { SDKValidationError } from "../errors/sdkvalidationerror.js"; +import * as z from 'zod/v3'; +import { safeParse } from '../../lib/schemas.js'; +import { ClosedEnum } from '../../types/enums.js'; +import { Result as SafeParseResult } from '../../types/fp.js'; +import { SDKValidationError } from '../errors/sdkvalidationerror.js'; /** * Target window for the redirection. */ export const Target = { - Self: "_self", - Blank: "_blank", - Parent: "_parent", - Top: "_top", - UnfencedTop: "_unfencedTop", + Self: '_self', + Blank: '_blank', + Parent: '_parent', + Top: '_top', + UnfencedTop: '_unfencedTop', } as const; /** * Target window for the redirection. @@ -25,7 +25,7 @@ export type Target = ClosedEnum; export type RedirectDto = { /** - * URL for redirection. Must be a valid URL or start with / or {{"{{"}} variable }}. + * URL for redirection. Must be a valid URL or start with / or {{ variable }}. */ url?: string | undefined; /** @@ -35,20 +35,14 @@ export type RedirectDto = { }; /** @internal */ -export const Target$inboundSchema: z.ZodNativeEnum = z - .nativeEnum(Target); +export const Target$inboundSchema: z.ZodNativeEnum = z.nativeEnum(Target); /** @internal */ -export const Target$outboundSchema: z.ZodNativeEnum = - Target$inboundSchema; +export const Target$outboundSchema: z.ZodNativeEnum = Target$inboundSchema; /** @internal */ -export const RedirectDto$inboundSchema: z.ZodType< - RedirectDto, - z.ZodTypeDef, - unknown -> = z.object({ +export const RedirectDto$inboundSchema: z.ZodType = z.object({ url: z.string().optional(), - target: Target$inboundSchema.default("_self"), + target: Target$inboundSchema.default('_self'), }); /** @internal */ export type RedirectDto$Outbound = { @@ -57,24 +51,18 @@ export type RedirectDto$Outbound = { }; /** @internal */ -export const RedirectDto$outboundSchema: z.ZodType< - RedirectDto$Outbound, - z.ZodTypeDef, - RedirectDto -> = z.object({ +export const RedirectDto$outboundSchema: z.ZodType = z.object({ url: z.string().optional(), - target: Target$outboundSchema.default("_self"), + target: Target$outboundSchema.default('_self'), }); export function redirectDtoToJSON(redirectDto: RedirectDto): string { return JSON.stringify(RedirectDto$outboundSchema.parse(redirectDto)); } -export function redirectDtoFromJSON( - jsonString: string, -): SafeParseResult { +export function redirectDtoFromJSON(jsonString: string): SafeParseResult { return safeParse( jsonString, (x) => RedirectDto$inboundSchema.parse(JSON.parse(x)), - `Failed to parse 'RedirectDto' from JSON`, + `Failed to parse 'RedirectDto' from JSON` ); } diff --git a/libs/internal-sdk/src/models/components/subscriberworkflowpreferencedto.ts b/libs/internal-sdk/src/models/components/subscriberworkflowpreferencedto.ts index 83d365dd57c..45844f031e6 100644 --- a/libs/internal-sdk/src/models/components/subscriberworkflowpreferencedto.ts +++ b/libs/internal-sdk/src/models/components/subscriberworkflowpreferencedto.ts @@ -2,22 +2,22 @@ * Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT. */ -import * as z from "zod/v3"; -import { safeParse } from "../../lib/schemas.js"; -import { Result as SafeParseResult } from "../../types/fp.js"; -import { SDKValidationError } from "../errors/sdkvalidationerror.js"; +import * as z from 'zod/v3'; +import { safeParse } from '../../lib/schemas.js'; +import { Result as SafeParseResult } from '../../types/fp.js'; +import { SDKValidationError } from '../errors/sdkvalidationerror.js'; import { SubscriberPreferenceChannels, SubscriberPreferenceChannels$inboundSchema, -} from "./subscriberpreferencechannels.js"; +} from './subscriberpreferencechannels.js'; import { SubscriberPreferenceOverrideDto, SubscriberPreferenceOverrideDto$inboundSchema, -} from "./subscriberpreferenceoverridedto.js"; +} from './subscriberpreferenceoverridedto.js'; import { SubscriberPreferencesWorkflowInfoDto, SubscriberPreferencesWorkflowInfoDto$inboundSchema, -} from "./subscriberpreferencesworkflowinfodto.js"; +} from './subscriberpreferencesworkflowinfodto.js'; export type SubscriberWorkflowPreferenceDto = { /** @@ -36,6 +36,10 @@ export type SubscriberWorkflowPreferenceDto = { * Workflow information */ workflow: SubscriberPreferencesWorkflowInfoDto; + /** + * Timestamp when the subscriber last updated their preference. Only present if subscriber explicitly set preferences. + */ + updatedAt?: string | undefined; }; /** @internal */ @@ -48,14 +52,15 @@ export const SubscriberWorkflowPreferenceDto$inboundSchema: z.ZodType< channels: SubscriberPreferenceChannels$inboundSchema, overrides: z.array(SubscriberPreferenceOverrideDto$inboundSchema), workflow: SubscriberPreferencesWorkflowInfoDto$inboundSchema, + updatedAt: z.string().optional(), }); export function subscriberWorkflowPreferenceDtoFromJSON( - jsonString: string, + jsonString: string ): SafeParseResult { return safeParse( jsonString, (x) => SubscriberWorkflowPreferenceDto$inboundSchema.parse(JSON.parse(x)), - `Failed to parse 'SubscriberWorkflowPreferenceDto' from JSON`, + `Failed to parse 'SubscriberWorkflowPreferenceDto' from JSON` ); } diff --git a/libs/internal-sdk/src/models/operations/activitycontrollergetworkflowruns.ts b/libs/internal-sdk/src/models/operations/activitycontrollergetworkflowruns.ts index 3b036bc7eeb..ebb275ace5a 100644 --- a/libs/internal-sdk/src/models/operations/activitycontrollergetworkflowruns.ts +++ b/libs/internal-sdk/src/models/operations/activitycontrollergetworkflowruns.ts @@ -2,22 +2,22 @@ * Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT. */ -import * as z from "zod/v3"; -import { remap as remap$ } from "../../lib/primitives.js"; -import { ClosedEnum } from "../../types/enums.js"; +import * as z from 'zod/v3'; +import { remap as remap$ } from '../../lib/primitives.js'; +import { ClosedEnum } from '../../types/enums.js'; export const QueryParamStatuses = { - Processing: "processing", - Completed: "completed", - Error: "error", + Processing: 'processing', + Completed: 'completed', + Error: 'error', } as const; export type QueryParamStatuses = ClosedEnum; export const Severity = { - High: "high", - Medium: "medium", - Low: "low", - None: "none", + High: 'high', + Medium: 'medium', + Low: 'low', + None: 'none', } as const; export type Severity = ClosedEnum; @@ -30,6 +30,7 @@ export type ActivityControllerGetWorkflowRunsRequest = { statuses?: Array | undefined; channels?: Array | undefined; topicKey?: string | undefined; + subscriptionId?: string | undefined; createdGte?: string | undefined; createdLte?: string | undefined; severity?: Array | undefined; @@ -41,13 +42,11 @@ export type ActivityControllerGetWorkflowRunsRequest = { }; /** @internal */ -export const QueryParamStatuses$outboundSchema: z.ZodNativeEnum< - typeof QueryParamStatuses -> = z.nativeEnum(QueryParamStatuses); +export const QueryParamStatuses$outboundSchema: z.ZodNativeEnum = + z.nativeEnum(QueryParamStatuses); /** @internal */ -export const Severity$outboundSchema: z.ZodNativeEnum = z - .nativeEnum(Severity); +export const Severity$outboundSchema: z.ZodNativeEnum = z.nativeEnum(Severity); /** @internal */ export type ActivityControllerGetWorkflowRunsRequest$Outbound = { @@ -59,11 +58,12 @@ export type ActivityControllerGetWorkflowRunsRequest$Outbound = { statuses?: Array | undefined; channels?: Array | undefined; topicKey?: string | undefined; + subscriptionId?: string | undefined; createdGte?: string | undefined; createdLte?: string | undefined; severity?: Array | undefined; contextKeys?: Array | undefined; - "idempotency-key"?: string | undefined; + 'idempotency-key'?: string | undefined; }; /** @internal */ @@ -71,33 +71,33 @@ export const ActivityControllerGetWorkflowRunsRequest$outboundSchema: z.ZodType< ActivityControllerGetWorkflowRunsRequest$Outbound, z.ZodTypeDef, ActivityControllerGetWorkflowRunsRequest -> = z.object({ - limit: z.number().default(10), - cursor: z.string().optional(), - workflowIds: z.array(z.string()).optional(), - subscriberIds: z.array(z.string()).optional(), - transactionIds: z.array(z.string()).optional(), - statuses: z.array(QueryParamStatuses$outboundSchema).optional(), - channels: z.array(z.string()).optional(), - topicKey: z.string().optional(), - createdGte: z.string().optional(), - createdLte: z.string().optional(), - severity: z.array(Severity$outboundSchema).optional(), - contextKeys: z.array(z.string()).optional(), - idempotencyKey: z.string().optional(), -}).transform((v) => { - return remap$(v, { - idempotencyKey: "idempotency-key", +> = z + .object({ + limit: z.number().default(10), + cursor: z.string().optional(), + workflowIds: z.array(z.string()).optional(), + subscriberIds: z.array(z.string()).optional(), + transactionIds: z.array(z.string()).optional(), + statuses: z.array(QueryParamStatuses$outboundSchema).optional(), + channels: z.array(z.string()).optional(), + topicKey: z.string().optional(), + subscriptionId: z.string().optional(), + createdGte: z.string().optional(), + createdLte: z.string().optional(), + severity: z.array(Severity$outboundSchema).optional(), + contextKeys: z.array(z.string()).optional(), + idempotencyKey: z.string().optional(), + }) + .transform((v) => { + return remap$(v, { + idempotencyKey: 'idempotency-key', + }); }); -}); export function activityControllerGetWorkflowRunsRequestToJSON( - activityControllerGetWorkflowRunsRequest: - ActivityControllerGetWorkflowRunsRequest, + activityControllerGetWorkflowRunsRequest: ActivityControllerGetWorkflowRunsRequest ): string { return JSON.stringify( - ActivityControllerGetWorkflowRunsRequest$outboundSchema.parse( - activityControllerGetWorkflowRunsRequest, - ), + ActivityControllerGetWorkflowRunsRequest$outboundSchema.parse(activityControllerGetWorkflowRunsRequest) ); } diff --git a/libs/internal-sdk/src/models/operations/notificationscontrollerlistnotifications.ts b/libs/internal-sdk/src/models/operations/notificationscontrollerlistnotifications.ts index 5343f9fed39..44c5018b56e 100644 --- a/libs/internal-sdk/src/models/operations/notificationscontrollerlistnotifications.ts +++ b/libs/internal-sdk/src/models/operations/notificationscontrollerlistnotifications.ts @@ -2,12 +2,12 @@ * Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT. */ -import * as z from "zod/v3"; -import { remap as remap$ } from "../../lib/primitives.js"; -import { safeParse } from "../../lib/schemas.js"; -import { Result as SafeParseResult } from "../../types/fp.js"; -import * as components from "../components/index.js"; -import { SDKValidationError } from "../errors/sdkvalidationerror.js"; +import * as z from 'zod/v3'; +import { remap as remap$ } from '../../lib/primitives.js'; +import { safeParse } from '../../lib/schemas.js'; +import { Result as SafeParseResult } from '../../types/fp.js'; +import * as components from '../components/index.js'; +import { SDKValidationError } from '../errors/sdkvalidationerror.js'; export type NotificationsControllerListNotificationsRequest = { /** @@ -52,6 +52,10 @@ export type NotificationsControllerListNotificationsRequest = { * Topic Key for filtering notifications by topic */ topicKey?: string | undefined; + /** + * Subscription ID for filtering notifications by subscription + */ + subscriptionId?: string | undefined; /** * Filter by exact context keys, order insensitive (format: "type:id") */ @@ -87,19 +91,20 @@ export type NotificationsControllerListNotificationsRequest$Outbound = { limit: number; transactionId?: string | undefined; topicKey?: string | undefined; + subscriptionId?: string | undefined; contextKeys?: Array | undefined; after?: string | undefined; before?: string | undefined; - "idempotency-key"?: string | undefined; + 'idempotency-key'?: string | undefined; }; /** @internal */ -export const NotificationsControllerListNotificationsRequest$outboundSchema: - z.ZodType< - NotificationsControllerListNotificationsRequest$Outbound, - z.ZodTypeDef, - NotificationsControllerListNotificationsRequest - > = z.object({ +export const NotificationsControllerListNotificationsRequest$outboundSchema: z.ZodType< + NotificationsControllerListNotificationsRequest$Outbound, + z.ZodTypeDef, + NotificationsControllerListNotificationsRequest +> = z + .object({ channels: z.array(components.ChannelTypeEnum$outboundSchema).optional(), templates: z.array(z.string()).optional(), emails: z.array(z.string()).optional(), @@ -110,55 +115,51 @@ export const NotificationsControllerListNotificationsRequest$outboundSchema: limit: z.number().default(10), transactionId: z.string().optional(), topicKey: z.string().optional(), + subscriptionId: z.string().optional(), contextKeys: z.array(z.string()).optional(), after: z.string().optional(), before: z.string().optional(), idempotencyKey: z.string().optional(), - }).transform((v) => { + }) + .transform((v) => { return remap$(v, { - idempotencyKey: "idempotency-key", + idempotencyKey: 'idempotency-key', }); }); export function notificationsControllerListNotificationsRequestToJSON( - notificationsControllerListNotificationsRequest: - NotificationsControllerListNotificationsRequest, + notificationsControllerListNotificationsRequest: NotificationsControllerListNotificationsRequest ): string { return JSON.stringify( NotificationsControllerListNotificationsRequest$outboundSchema.parse( - notificationsControllerListNotificationsRequest, - ), + notificationsControllerListNotificationsRequest + ) ); } /** @internal */ -export const NotificationsControllerListNotificationsResponse$inboundSchema: - z.ZodType< - NotificationsControllerListNotificationsResponse, - z.ZodTypeDef, - unknown - > = z.object({ +export const NotificationsControllerListNotificationsResponse$inboundSchema: z.ZodType< + NotificationsControllerListNotificationsResponse, + z.ZodTypeDef, + unknown +> = z + .object({ Headers: z.record(z.array(z.string())).default({}), Result: components.ActivitiesResponseDto$inboundSchema, - }).transform((v) => { + }) + .transform((v) => { return remap$(v, { - "Headers": "headers", - "Result": "result", + Headers: 'headers', + Result: 'result', }); }); export function notificationsControllerListNotificationsResponseFromJSON( - jsonString: string, -): SafeParseResult< - NotificationsControllerListNotificationsResponse, - SDKValidationError -> { + jsonString: string +): SafeParseResult { return safeParse( jsonString, - (x) => - NotificationsControllerListNotificationsResponse$inboundSchema.parse( - JSON.parse(x), - ), - `Failed to parse 'NotificationsControllerListNotificationsResponse' from JSON`, + (x) => NotificationsControllerListNotificationsResponse$inboundSchema.parse(JSON.parse(x)), + `Failed to parse 'NotificationsControllerListNotificationsResponse' from JSON` ); } diff --git a/libs/internal-sdk/src/react-query/activityWorkflowRunsList.core.ts b/libs/internal-sdk/src/react-query/activityWorkflowRunsList.core.ts index ab5b86c910d..acaa9e6863a 100644 --- a/libs/internal-sdk/src/react-query/activityWorkflowRunsList.core.ts +++ b/libs/internal-sdk/src/react-query/activityWorkflowRunsList.core.ts @@ -2,45 +2,34 @@ * Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT. */ -import { - QueryClient, - QueryFunctionContext, - QueryKey, -} from "@tanstack/react-query"; -import { NovuCore } from "../core.js"; -import { activityWorkflowRunsList } from "../funcs/activityWorkflowRunsList.js"; -import { combineSignals } from "../lib/primitives.js"; -import { RequestOptions } from "../lib/sdks.js"; -import * as components from "../models/components/index.js"; -import * as operations from "../models/operations/index.js"; -import { unwrapAsync } from "../types/fp.js"; -export type ActivityWorkflowRunsListQueryData = - components.GetWorkflowRunsResponseDto; +import { QueryClient, QueryFunctionContext, QueryKey } from '@tanstack/react-query'; +import { NovuCore } from '../core.js'; +import { activityWorkflowRunsList } from '../funcs/activityWorkflowRunsList.js'; +import { combineSignals } from '../lib/primitives.js'; +import { RequestOptions } from '../lib/sdks.js'; +import * as components from '../models/components/index.js'; +import * as operations from '../models/operations/index.js'; +import { unwrapAsync } from '../types/fp.js'; +export type ActivityWorkflowRunsListQueryData = components.GetWorkflowRunsResponseDto; export function prefetchActivityWorkflowRunsList( queryClient: QueryClient, client$: NovuCore, request: operations.ActivityControllerGetWorkflowRunsRequest, - options?: RequestOptions, + options?: RequestOptions ): Promise { return queryClient.prefetchQuery({ - ...buildActivityWorkflowRunsListQuery( - client$, - request, - options, - ), + ...buildActivityWorkflowRunsListQuery(client$, request, options), }); } export function buildActivityWorkflowRunsListQuery( client$: NovuCore, request: operations.ActivityControllerGetWorkflowRunsRequest, - options?: RequestOptions, + options?: RequestOptions ): { queryKey: QueryKey; - queryFn: ( - context: QueryFunctionContext, - ) => Promise; + queryFn: (context: QueryFunctionContext) => Promise; } { return { queryKey: queryKeyActivityWorkflowRunsList({ @@ -52,51 +41,41 @@ export function buildActivityWorkflowRunsListQuery( statuses: request.statuses, channels: request.channels, topicKey: request.topicKey, + subscriptionId: request.subscriptionId, createdGte: request.createdGte, createdLte: request.createdLte, severity: request.severity, contextKeys: request.contextKeys, idempotencyKey: request.idempotencyKey, }), - queryFn: async function activityWorkflowRunsListQueryFn( - ctx, - ): Promise { - const sig = combineSignals( - ctx.signal, - options?.signal, - options?.fetchOptions?.signal, - ); + queryFn: async function activityWorkflowRunsListQueryFn(ctx): Promise { + const sig = combineSignals(ctx.signal, options?.signal, options?.fetchOptions?.signal); const mergedOptions = { ...options?.fetchOptions, ...options, signal: sig, }; - return unwrapAsync(activityWorkflowRunsList( - client$, - request, - mergedOptions, - )); + return unwrapAsync(activityWorkflowRunsList(client$, request, mergedOptions)); }, }; } -export function queryKeyActivityWorkflowRunsList( - parameters: { - limit: number | undefined; - cursor?: string | undefined; - workflowIds?: Array | undefined; - subscriberIds?: Array | undefined; - transactionIds?: Array | undefined; - statuses?: Array | undefined; - channels?: Array | undefined; - topicKey?: string | undefined; - createdGte?: string | undefined; - createdLte?: string | undefined; - severity?: Array | undefined; - contextKeys?: Array | undefined; - idempotencyKey?: string | undefined; - }, -): QueryKey { - return ["@novu/api", "WorkflowRuns", "list", parameters]; +export function queryKeyActivityWorkflowRunsList(parameters: { + limit: number | undefined; + cursor?: string | undefined; + workflowIds?: Array | undefined; + subscriberIds?: Array | undefined; + transactionIds?: Array | undefined; + statuses?: Array | undefined; + channels?: Array | undefined; + topicKey?: string | undefined; + subscriptionId?: string | undefined; + createdGte?: string | undefined; + createdLte?: string | undefined; + severity?: Array | undefined; + contextKeys?: Array | undefined; + idempotencyKey?: string | undefined; +}): QueryKey { + return ['@novu/api', 'WorkflowRuns', 'list', parameters]; } diff --git a/libs/internal-sdk/src/react-query/activityWorkflowRunsList.ts b/libs/internal-sdk/src/react-query/activityWorkflowRunsList.ts index 33c386e9f72..f3db7e2be74 100644 --- a/libs/internal-sdk/src/react-query/activityWorkflowRunsList.ts +++ b/libs/internal-sdk/src/react-query/activityWorkflowRunsList.ts @@ -5,24 +5,20 @@ import { InvalidateQueryFilters, QueryClient, - useQuery, UseQueryResult, - useSuspenseQuery, UseSuspenseQueryResult, -} from "@tanstack/react-query"; -import * as operations from "../models/operations/index.js"; -import { useNovuContext } from "./_context.js"; -import { - QueryHookOptions, - SuspenseQueryHookOptions, - TupleToPrefixes, -} from "./_types.js"; + useQuery, + useSuspenseQuery, +} from '@tanstack/react-query'; +import * as operations from '../models/operations/index.js'; +import { useNovuContext } from './_context.js'; +import { QueryHookOptions, SuspenseQueryHookOptions, TupleToPrefixes } from './_types.js'; import { ActivityWorkflowRunsListQueryData, buildActivityWorkflowRunsListQuery, prefetchActivityWorkflowRunsList, queryKeyActivityWorkflowRunsList, -} from "./activityWorkflowRunsList.core.js"; +} from './activityWorkflowRunsList.core.js'; export { type ActivityWorkflowRunsListQueryData, buildActivityWorkflowRunsListQuery, @@ -38,15 +34,11 @@ export { */ export function useActivityWorkflowRunsList( request: operations.ActivityControllerGetWorkflowRunsRequest, - options?: QueryHookOptions, + options?: QueryHookOptions ): UseQueryResult { const client = useNovuContext(); return useQuery({ - ...buildActivityWorkflowRunsListQuery( - client, - request, - options, - ), + ...buildActivityWorkflowRunsListQuery(client, request, options), ...options, }); } @@ -59,15 +51,11 @@ export function useActivityWorkflowRunsList( */ export function useActivityWorkflowRunsListSuspense( request: operations.ActivityControllerGetWorkflowRunsRequest, - options?: SuspenseQueryHookOptions, + options?: SuspenseQueryHookOptions ): UseSuspenseQueryResult { const client = useNovuContext(); return useSuspenseQuery({ - ...buildActivityWorkflowRunsListQuery( - client, - request, - options, - ), + ...buildActivityWorkflowRunsListQuery(client, request, options), ...options, }); } @@ -84,6 +72,7 @@ export function setActivityWorkflowRunsListData( statuses?: Array | undefined; channels?: Array | undefined; topicKey?: string | undefined; + subscriptionId?: string | undefined; createdGte?: string | undefined; createdLte?: string | undefined; severity?: Array | undefined; @@ -91,7 +80,7 @@ export function setActivityWorkflowRunsListData( idempotencyKey?: string | undefined; }, ], - data: ActivityWorkflowRunsListQueryData, + data: ActivityWorkflowRunsListQueryData ): ActivityWorkflowRunsListQueryData | undefined { const key = queryKeyActivityWorkflowRunsList(...queryKeyBase); @@ -101,36 +90,39 @@ export function setActivityWorkflowRunsListData( export function invalidateActivityWorkflowRunsList( client: QueryClient, queryKeyBase: TupleToPrefixes< - [parameters: { - limit: number | undefined; - cursor?: string | undefined; - workflowIds?: Array | undefined; - subscriberIds?: Array | undefined; - transactionIds?: Array | undefined; - statuses?: Array | undefined; - channels?: Array | undefined; - topicKey?: string | undefined; - createdGte?: string | undefined; - createdLte?: string | undefined; - severity?: Array | undefined; - contextKeys?: Array | undefined; - idempotencyKey?: string | undefined; - }] + [ + parameters: { + limit: number | undefined; + cursor?: string | undefined; + workflowIds?: Array | undefined; + subscriberIds?: Array | undefined; + transactionIds?: Array | undefined; + statuses?: Array | undefined; + channels?: Array | undefined; + topicKey?: string | undefined; + subscriptionId?: string | undefined; + createdGte?: string | undefined; + createdLte?: string | undefined; + severity?: Array | undefined; + contextKeys?: Array | undefined; + idempotencyKey?: string | undefined; + }, + ] >, - filters?: Omit, + filters?: Omit ): Promise { return client.invalidateQueries({ ...filters, - queryKey: ["@novu/api", "WorkflowRuns", "list", ...queryKeyBase], + queryKey: ['@novu/api', 'WorkflowRuns', 'list', ...queryKeyBase], }); } export function invalidateAllActivityWorkflowRunsList( client: QueryClient, - filters?: Omit, + filters?: Omit ): Promise { return client.invalidateQueries({ ...filters, - queryKey: ["@novu/api", "WorkflowRuns", "list"], + queryKey: ['@novu/api', 'WorkflowRuns', 'list'], }); } diff --git a/libs/internal-sdk/src/react-query/notificationsList.core.ts b/libs/internal-sdk/src/react-query/notificationsList.core.ts index 11292dab625..3658cab4f74 100644 --- a/libs/internal-sdk/src/react-query/notificationsList.core.ts +++ b/libs/internal-sdk/src/react-query/notificationsList.core.ts @@ -2,45 +2,34 @@ * Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT. */ -import { - QueryClient, - QueryFunctionContext, - QueryKey, -} from "@tanstack/react-query"; -import { NovuCore } from "../core.js"; -import { notificationsList } from "../funcs/notificationsList.js"; -import { combineSignals } from "../lib/primitives.js"; -import { RequestOptions } from "../lib/sdks.js"; -import * as components from "../models/components/index.js"; -import * as operations from "../models/operations/index.js"; -import { unwrapAsync } from "../types/fp.js"; -export type NotificationsListQueryData = - operations.NotificationsControllerListNotificationsResponse; +import { QueryClient, QueryFunctionContext, QueryKey } from '@tanstack/react-query'; +import { NovuCore } from '../core.js'; +import { notificationsList } from '../funcs/notificationsList.js'; +import { combineSignals } from '../lib/primitives.js'; +import { RequestOptions } from '../lib/sdks.js'; +import * as components from '../models/components/index.js'; +import * as operations from '../models/operations/index.js'; +import { unwrapAsync } from '../types/fp.js'; +export type NotificationsListQueryData = operations.NotificationsControllerListNotificationsResponse; export function prefetchNotificationsList( queryClient: QueryClient, client$: NovuCore, request: operations.NotificationsControllerListNotificationsRequest, - options?: RequestOptions, + options?: RequestOptions ): Promise { return queryClient.prefetchQuery({ - ...buildNotificationsListQuery( - client$, - request, - options, - ), + ...buildNotificationsListQuery(client$, request, options), }); } export function buildNotificationsListQuery( client$: NovuCore, request: operations.NotificationsControllerListNotificationsRequest, - options?: RequestOptions, + options?: RequestOptions ): { queryKey: QueryKey; - queryFn: ( - context: QueryFunctionContext, - ) => Promise; + queryFn: (context: QueryFunctionContext) => Promise; } { return { queryKey: queryKeyNotificationsList({ @@ -54,51 +43,41 @@ export function buildNotificationsListQuery( limit: request.limit, transactionId: request.transactionId, topicKey: request.topicKey, + subscriptionId: request.subscriptionId, contextKeys: request.contextKeys, after: request.after, before: request.before, idempotencyKey: request.idempotencyKey, }), - queryFn: async function notificationsListQueryFn( - ctx, - ): Promise { - const sig = combineSignals( - ctx.signal, - options?.signal, - options?.fetchOptions?.signal, - ); + queryFn: async function notificationsListQueryFn(ctx): Promise { + const sig = combineSignals(ctx.signal, options?.signal, options?.fetchOptions?.signal); const mergedOptions = { ...options?.fetchOptions, ...options, signal: sig, }; - return unwrapAsync(notificationsList( - client$, - request, - mergedOptions, - )); + return unwrapAsync(notificationsList(client$, request, mergedOptions)); }, }; } -export function queryKeyNotificationsList( - parameters: { - channels?: Array | undefined; - templates?: Array | undefined; - emails?: Array | undefined; - search?: string | undefined; - subscriberIds?: Array | undefined; - severity?: Array | undefined; - page?: number | undefined; - limit?: number | undefined; - transactionId?: string | undefined; - topicKey?: string | undefined; - contextKeys?: Array | undefined; - after?: string | undefined; - before?: string | undefined; - idempotencyKey?: string | undefined; - }, -): QueryKey { - return ["@novu/api", "Notifications", "list", parameters]; +export function queryKeyNotificationsList(parameters: { + channels?: Array | undefined; + templates?: Array | undefined; + emails?: Array | undefined; + search?: string | undefined; + subscriberIds?: Array | undefined; + severity?: Array | undefined; + page?: number | undefined; + limit?: number | undefined; + transactionId?: string | undefined; + topicKey?: string | undefined; + subscriptionId?: string | undefined; + contextKeys?: Array | undefined; + after?: string | undefined; + before?: string | undefined; + idempotencyKey?: string | undefined; +}): QueryKey { + return ['@novu/api', 'Notifications', 'list', parameters]; } diff --git a/libs/internal-sdk/src/react-query/notificationsList.ts b/libs/internal-sdk/src/react-query/notificationsList.ts index 4dc30a95a82..c223ae9e174 100644 --- a/libs/internal-sdk/src/react-query/notificationsList.ts +++ b/libs/internal-sdk/src/react-query/notificationsList.ts @@ -5,25 +5,21 @@ import { InvalidateQueryFilters, QueryClient, - useQuery, UseQueryResult, - useSuspenseQuery, UseSuspenseQueryResult, -} from "@tanstack/react-query"; -import * as components from "../models/components/index.js"; -import * as operations from "../models/operations/index.js"; -import { useNovuContext } from "./_context.js"; -import { - QueryHookOptions, - SuspenseQueryHookOptions, - TupleToPrefixes, -} from "./_types.js"; + useQuery, + useSuspenseQuery, +} from '@tanstack/react-query'; +import * as components from '../models/components/index.js'; +import * as operations from '../models/operations/index.js'; +import { useNovuContext } from './_context.js'; +import { QueryHookOptions, SuspenseQueryHookOptions, TupleToPrefixes } from './_types.js'; import { buildNotificationsListQuery, NotificationsListQueryData, prefetchNotificationsList, queryKeyNotificationsList, -} from "./notificationsList.core.js"; +} from './notificationsList.core.js'; export { buildNotificationsListQuery, type NotificationsListQueryData, @@ -42,15 +38,11 @@ export { */ export function useNotificationsList( request: operations.NotificationsControllerListNotificationsRequest, - options?: QueryHookOptions, + options?: QueryHookOptions ): UseQueryResult { const client = useNovuContext(); return useQuery({ - ...buildNotificationsListQuery( - client, - request, - options, - ), + ...buildNotificationsListQuery(client, request, options), ...options, }); } @@ -66,15 +58,11 @@ export function useNotificationsList( */ export function useNotificationsListSuspense( request: operations.NotificationsControllerListNotificationsRequest, - options?: SuspenseQueryHookOptions, + options?: SuspenseQueryHookOptions ): UseSuspenseQueryResult { const client = useNovuContext(); return useSuspenseQuery({ - ...buildNotificationsListQuery( - client, - request, - options, - ), + ...buildNotificationsListQuery(client, request, options), ...options, }); } @@ -93,13 +81,14 @@ export function setNotificationsListData( limit?: number | undefined; transactionId?: string | undefined; topicKey?: string | undefined; + subscriptionId?: string | undefined; contextKeys?: Array | undefined; after?: string | undefined; before?: string | undefined; idempotencyKey?: string | undefined; }, ], - data: NotificationsListQueryData, + data: NotificationsListQueryData ): NotificationsListQueryData | undefined { const key = queryKeyNotificationsList(...queryKeyBase); @@ -109,37 +98,40 @@ export function setNotificationsListData( export function invalidateNotificationsList( client: QueryClient, queryKeyBase: TupleToPrefixes< - [parameters: { - channels?: Array | undefined; - templates?: Array | undefined; - emails?: Array | undefined; - search?: string | undefined; - subscriberIds?: Array | undefined; - severity?: Array | undefined; - page?: number | undefined; - limit?: number | undefined; - transactionId?: string | undefined; - topicKey?: string | undefined; - contextKeys?: Array | undefined; - after?: string | undefined; - before?: string | undefined; - idempotencyKey?: string | undefined; - }] + [ + parameters: { + channels?: Array | undefined; + templates?: Array | undefined; + emails?: Array | undefined; + search?: string | undefined; + subscriberIds?: Array | undefined; + severity?: Array | undefined; + page?: number | undefined; + limit?: number | undefined; + transactionId?: string | undefined; + topicKey?: string | undefined; + subscriptionId?: string | undefined; + contextKeys?: Array | undefined; + after?: string | undefined; + before?: string | undefined; + idempotencyKey?: string | undefined; + }, + ] >, - filters?: Omit, + filters?: Omit ): Promise { return client.invalidateQueries({ ...filters, - queryKey: ["@novu/api", "Notifications", "list", ...queryKeyBase], + queryKey: ['@novu/api', 'Notifications', 'list', ...queryKeyBase], }); } export function invalidateAllNotificationsList( client: QueryClient, - filters?: Omit, + filters?: Omit ): Promise { return client.invalidateQueries({ ...filters, - queryKey: ["@novu/api", "Notifications", "list"], + queryKey: ['@novu/api', 'Notifications', 'list'], }); } diff --git a/packages/shared/src/entities/subscriber-preference/subscriber-preference.interface.ts b/packages/shared/src/entities/subscriber-preference/subscriber-preference.interface.ts index 73e2d7e0183..33e974b9354 100644 --- a/packages/shared/src/entities/subscriber-preference/subscriber-preference.interface.ts +++ b/packages/shared/src/entities/subscriber-preference/subscriber-preference.interface.ts @@ -26,6 +26,7 @@ interface IPreferenceResponse { channels: IPreferenceChannels; overrides: IPreferenceOverride[]; schedule?: Schedule; + updatedAt?: string; } export interface ITemplateConfiguration {