Skip to content

Commit

Permalink
chore(root): Release 2025-02-06 11:01 (#7673)
Browse files Browse the repository at this point in the history
  • Loading branch information
github-actions[bot] authored Feb 6, 2025
2 parents b3d78d5 + 79739cb commit fc2e5c2
Show file tree
Hide file tree
Showing 75 changed files with 1,380 additions and 421 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ describe('Create expireAt - TTL support - with pending jobs', function () {
});

it('should add expireAt to pending events that were digested', async function () {
await session.awaitRunningJobs(digestTemplate?._id, false, 5);
await session.waitForJobCompletion(digestTemplate?._id, false, 5);

await notificationExpireAt(query);

Expand Down
8 changes: 4 additions & 4 deletions apps/api/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,9 @@
"pretest": "pnpm build:metadata",
"generate:swagger": "cross-env NODE_ENV=test PORT=1336 ts-node exportOpenAPIJSON.ts",
"generate:sdk": " (cd ../../libs/internal-sdk && speakeasy run --skip-compile --minimal --skip-versioning) && (cd ../../libs/internal-sdk && pnpm build) ",
"test": "cross-env TS_NODE_COMPILER_OPTIONS='{\"strictNullChecks\": false}' NODE_ENV=test mocha --require ts-node/register --exit 'src/**/*.spec.ts'",
"test:e2e:novu-v1": "cross-env TS_NODE_COMPILER_OPTIONS='{\"strictNullChecks\": false}' NODE_ENV=test mocha --grep '#novu-v1' --require ts-node/register --exit --file e2e/setup.ts src/**/*.e2e{,-ee}.ts",
"test:e2e:novu-v2": "cross-env TS_NODE_COMPILER_OPTIONS='{\"strictNullChecks\": false}' NODE_ENV=test CI_EE_TEST=true CLERK_ENABLED=true NODE_OPTIONS=--max_old_space_size=8192 mocha --grep '#novu-v2' --require ts-node/register --exit --file e2e/setup.ts 'src/**/*.e2e{,-ee}.ts'",
"test": "cross-env TS_NODE_COMPILER_OPTIONS='{\"strictNullChecks\": false}' NODE_ENV=test mocha --timeout 5000 --require ts-node/register --exit 'src/**/*.spec.ts'",
"test:e2e:novu-v1": "cross-env TS_NODE_COMPILER_OPTIONS='{\"strictNullChecks\": false}' NODE_ENV=test mocha --timeout 5000 --grep '#novu-v1' --require ts-node/register --exit --file e2e/setup.ts src/**/*.e2e{,-ee}.ts ",
"test:e2e:novu-v2": "cross-env TS_NODE_COMPILER_OPTIONS='{\"strictNullChecks\": false}' NODE_ENV=test CI_EE_TEST=true CLERK_ENABLED=true NODE_OPTIONS=--max_old_space_size=8192 mocha --timeout 5000 --grep '#novu-v2' --require ts-node/register --exit --file e2e/setup.ts 'src/**/*.e2e{,-ee}.ts'",
"migration": "cross-env NODE_ENV=local MIGRATION=true ts-node --transpileOnly",
"link:submodules": "pnpm link ../../enterprise/packages/auth && pnpm link ../../enterprise/packages/translation && pnpm link ../../enterprise/packages/billing",
"admin:remove-user-account": "cross-env NODE_ENV=local MIGRATION=true ts-node --transpileOnly ./admin/remove-user-account.ts",
Expand All @@ -37,7 +37,7 @@
"@aws-sdk/client-secrets-manager": "^3.716.0",
"@godaddy/terminus": "^4.12.1",
"@google-cloud/storage": "^6.2.3",
"@maily-to/render": "^0.0.17",
"@maily-to/render": "^0.0.19",
"@nestjs/axios": "3.0.3",
"@nestjs/common": "10.4.1",
"@nestjs/core": "10.4.1",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -559,13 +559,13 @@ describe('EmailOutputRendererUsecase', () => {
});
});

describe('for block transformation and expansion', () => {
it('should handle for loop block transformation with array of objects', async () => {
describe('repeat block transformation and expansion', () => {
it('should handle repeat loop block transformation with array of objects', async () => {
const mockTipTapNode: MailyJSONContent = {
type: 'doc',
content: [
{
type: 'for',
type: 'repeat',
attrs: {
each: 'payload.comments',
isUpdatingKey: false,
Expand Down Expand Up @@ -610,7 +610,7 @@ describe('EmailOutputRendererUsecase', () => {

const renderCommand = {
controlValues: {
subject: 'For Loop Test',
subject: 'Repeat Loop Test',
body: JSON.stringify(mockTipTapNode),
},
fullPayloadForRender: {
Expand All @@ -626,12 +626,12 @@ describe('EmailOutputRendererUsecase', () => {
expect(result.body).to.include('This is an author: <!-- -->Jane<!-- -->Post Title');
});

it('should handle for loop block transformation with array of primitives', async () => {
it('should handle repeat loop block transformation with array of primitives', async () => {
const mockTipTapNode: MailyJSONContent = {
type: 'doc',
content: [
{
type: 'for',
type: 'repeat',
attrs: {
each: 'payload.names',
isUpdatingKey: false,
Expand Down Expand Up @@ -662,7 +662,7 @@ describe('EmailOutputRendererUsecase', () => {

const renderCommand = {
controlValues: {
subject: 'For Loop Test',
subject: 'Repeat Loop Test',
body: JSON.stringify(mockTipTapNode),
},
fullPayloadForRender: {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
/* eslint-disable no-param-reassign */
import { render as mailyRender, JSONContent as MailyJSONContent } from '@maily-to/render';
import { Injectable } from '@nestjs/common';
import { Liquid } from 'liquidjs';
import { EmailRenderOutput } from '@novu/shared';
import { InstrumentUsecase } from '@novu/application-generic';

import { FullPayloadForRender, RenderCommand } from './render-command';
import { WrapMailyInLiquidUseCase } from './maily-to-liquid/wrap-maily-in-liquid.usecase';
import { MAILY_ITERABLE_MARK, MailyAttrsEnum, MailyContentTypeEnum } from './maily-to-liquid/maily.types';
import { MAILY_ITERABLE_MARK, MailyAttrsEnum } from './maily-to-liquid/maily.types';
import { parseLiquid } from '../../../shared/helpers/liquid';
import { hasShow, isRepeatNode, isVariableNode } from './maily-to-liquid/maily-utils';

export class EmailOutputRendererCommand extends RenderCommand {}

Expand Down Expand Up @@ -88,15 +89,15 @@ export class EmailOutputRendererUsecase {
while (queue.length > 0) {
const current = queue.shift()!;

if (this.hasShow(current.node)) {
if (hasShow(current.node)) {
await this.handleShowNode(current.node, variables, current.parent);
}

if (this.isForNode(current.node)) {
if (isRepeatNode(current.node)) {
await this.handleEachNode(current.node, variables, current.parent);
}

if (this.isVariableNode(current.node)) {
if (isVariableNode(current.node)) {
this.processVariableNodeTypes(current.node);
}

Expand Down Expand Up @@ -156,23 +157,6 @@ export class EmailOutputRendererUsecase {
node.text = node.attrs?.id || '';
}

private isForNode(
node: MailyJSONContent
): node is MailyJSONContent & { attrs: { [MailyAttrsEnum.EACH_KEY]: string } } {
return !!(
node.type === MailyContentTypeEnum.FOR &&
node.attrs &&
node.attrs[MailyAttrsEnum.EACH_KEY] !== undefined &&
typeof node.attrs[MailyAttrsEnum.EACH_KEY] === 'string'
);
}

private hasShow(
node: MailyJSONContent
): node is MailyJSONContent & { attrs: { [MailyAttrsEnum.SHOW_IF_KEY]: string } } {
return node.attrs?.[MailyAttrsEnum.SHOW_IF_KEY] !== undefined && node.attrs?.[MailyAttrsEnum.SHOW_IF_KEY] !== null;
}

/**
* For 'each' node, multiply the content by the number of items in the iterable array
* and add indexes to the placeholders.
Expand Down Expand Up @@ -229,7 +213,7 @@ export class EmailOutputRendererUsecase {
return nodes.map((node) => {
const processedNode = { ...node };

if (this.isVariableNode(processedNode)) {
if (isVariableNode(processedNode)) {
this.processVariableNodeTypes(processedNode);

if (processedNode.text) {
Expand Down Expand Up @@ -257,15 +241,4 @@ export class EmailOutputRendererUsecase {
return Boolean(normalized);
}
}

private isVariableNode(
node: MailyJSONContent
): node is MailyJSONContent & { attrs: { [MailyAttrsEnum.ID]: string } } {
return !!(
node.type === MailyContentTypeEnum.VARIABLE &&
node.attrs &&
node.attrs[MailyAttrsEnum.ID] !== undefined &&
typeof node.attrs[MailyAttrsEnum.ID] === 'string'
);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import { JSONContent as MailyJSONContent } from '@maily-to/render';

import { MailyAttrsEnum, MailyContentTypeEnum } from './maily.types';

export const isRepeatNode = (
node: MailyJSONContent
): node is MailyJSONContent & { attrs: { [MailyAttrsEnum.EACH_KEY]: string } } => {
return !!(
(node.type === MailyContentTypeEnum.REPEAT || node.type === MailyContentTypeEnum.FOR) &&
node.attrs &&
node.attrs[MailyAttrsEnum.EACH_KEY] !== undefined &&
typeof node.attrs[MailyAttrsEnum.EACH_KEY] === 'string'
);
};

export const isVariableNode = (
node: MailyJSONContent
): node is MailyJSONContent & { attrs: { [MailyAttrsEnum.ID]: string } } => {
return !!(
node.type === MailyContentTypeEnum.VARIABLE &&
node.attrs &&
node.attrs[MailyAttrsEnum.ID] !== undefined &&
typeof node.attrs[MailyAttrsEnum.ID] === 'string'
);
};

export const hasShow = (
node: MailyJSONContent
): node is MailyJSONContent & { attrs: { [MailyAttrsEnum.SHOW_IF_KEY]: string } } => {
return node.attrs?.[MailyAttrsEnum.SHOW_IF_KEY] !== undefined && node.attrs?.[MailyAttrsEnum.SHOW_IF_KEY] !== null;
};

export const hasAttrs = (node: MailyJSONContent): node is MailyJSONContent & { attrs: Record<string, any> } => {
return !!node.attrs;
};

export const hasMarks = (node: MailyJSONContent): node is MailyJSONContent & { marks: Record<string, any>[] } => {
return !!node.marks;
};
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
export enum MailyContentTypeEnum {
VARIABLE = 'variable',
REPEAT = 'repeat',
/**
* Legacy enum value maintained for backwards compatibility
* @deprecated
*/
FOR = 'for',
BUTTON = 'button',
IMAGE = 'image',
Expand Down
Original file line number Diff line number Diff line change
@@ -1,21 +1,23 @@
/* eslint-disable no-param-reassign */
import { Injectable } from '@nestjs/common';
import { JSONContent as MailyJSONContent } from '@maily-to/render';

import { WrapMailyInLiquidCommand } from './wrap-maily-in-liquid.command';
import {
MailyContentTypeEnum,
MailyAttrsEnum,
MAILY_ITERABLE_MARK,
MAILY_FIRST_CITIZEN_VARIABLE_KEY,
} from './maily.types';
import { hasAttrs, hasMarks, isRepeatNode } from './maily-utils';

/**
* Enriches Maily JSON content with Liquid syntax for variables.
* Enriches Maily JSON content with Liquid syntax repeat variables.
*
* @example
* Input:
* {
* type: "for",
* type: "repeat",
* attrs: { each: "payload.comments" },
* content: [{
* type: "variable",
Expand Down Expand Up @@ -53,19 +55,19 @@ export class WrapMailyInLiquidUseCase {
const newNode = { ...node } as MailyJSONContent & { attrs: Record<string, any> };

// if this is a for loop node, track its variable
if (this.isForNode(node)) {
if (isRepeatNode(node)) {
parentForLoopKey = node.attrs[MailyAttrsEnum.EACH_KEY];
}

if (node.content) {
newNode.content = node.content.map((child) => this.wrapVariablesInLiquid(child, parentForLoopKey));
}

if (this.hasAttrs(node)) {
if (hasAttrs(node)) {
newNode.attrs = this.processVariableNodeAttributes(node, parentForLoopKey);
}

if (this.hasMarks(node)) {
if (hasMarks(node)) {
newNode.marks = this.processNodeMarks(node);
}

Expand Down Expand Up @@ -144,25 +146,6 @@ export class WrapMailyInLiquidUseCase {

return `{{ ${variableName}${fallbackSuffix} }}`;
}

private hasAttrs(node: MailyJSONContent): node is MailyJSONContent & { attrs: Record<string, any> } {
return !!node.attrs;
}

private hasMarks(node: MailyJSONContent): node is MailyJSONContent & { marks: Record<string, any>[] } {
return !!node.marks;
}

private isForNode(
node: MailyJSONContent
): node is MailyJSONContent & { attrs: { [MailyAttrsEnum.EACH_KEY]: string } } {
return !!(
node.type === MailyContentTypeEnum.FOR &&
node.attrs &&
node.attrs[MailyAttrsEnum.EACH_KEY] !== undefined &&
typeof node.attrs[MailyAttrsEnum.EACH_KEY] === 'string'
);
}
}

const variableAttributeConfig = (type: MailyContentTypeEnum) => {
Expand Down
Loading

0 comments on commit fc2e5c2

Please sign in to comment.