Skip to content

Commit

Permalink
chore(shared): Modernize TS setup (#7696)
Browse files Browse the repository at this point in the history
  • Loading branch information
SokratisVidros authored Feb 11, 2025
1 parent 2e10294 commit ff738e7
Show file tree
Hide file tree
Showing 15 changed files with 111 additions and 77 deletions.
9 changes: 9 additions & 0 deletions apps/api/src/app/inbox/usecases/session/session.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -175,6 +175,7 @@ describe('Session', () => {
applicationIdentifier: 'app-id',
subscriberId: 'subscriber-id',
subscriberHash: 'hash',
origin: 'origin',
};

const environment = { _id: 'env-id', _organizationId: 'org-id', name: 'env-name', apiKeys: [{ key: 'api-key' }] };
Expand All @@ -193,5 +194,13 @@ describe('Session', () => {

expect(response.token).to.equal(token);
expect(response.totalUnreadCount).to.equal(notificationCount.data[0].count);
expect(
analyticsService.mixpanelTrack.calledWith(AnalyticsEventsEnum.SESSION_INITIALIZED, '', {
_organization: environment._organizationId,
environmentName: environment.name,
_subscriber: subscriber._id,
origin: command.origin,
})
).to.be.true;
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import {
IUserPreferenceSettings,
} from '@novu/notification-center';
import type { INovuThemeProvider, INotificationCenterStyles } from '@novu/notification-center';
import { IMessage, IOrganizationEntity, ButtonTypeEnum, isBrowser } from '@novu/shared';
import { IMessage, IOrganizationEntity, ButtonTypeEnum } from '@novu/shared';

import { API_URL, WS_URL } from '../../config';

Expand Down Expand Up @@ -107,7 +107,7 @@ export function NotificationCenterWidget(props: INotificationCenterWidgetProps)
}
};

if (process.env.NODE_ENV === 'test' || (isBrowser() && (window as any).Cypress)) {
if (process.env.NODE_ENV === 'test' || (window as any).Cypress) {
// eslint-disable-next-line
(window as any).initHandler = handler;
}
Expand Down
16 changes: 7 additions & 9 deletions apps/widget/src/config/env.config.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,10 @@
import { isBrowser, getContextPath, NovuComponentEnum } from '@novu/shared';
import { getContextPath, NovuComponentEnum } from '@novu/shared';

export const API_URL =
isBrowser() && (window as any).Cypress
? window._env_.REACT_APP_API_URL || process.env.REACT_APP_API_URL || 'http://127.0.0.1:1336'
: window._env_.REACT_APP_API_URL || process.env.REACT_APP_API_URL || 'http://127.0.0.1:3000';
export const WS_URL =
isBrowser() && (window as any).Cypress
? window._env_.REACT_APP_WS_URL || process.env.REACT_APP_WS_URL || 'http://127.0.0.1:1340'
: window._env_.REACT_APP_WS_URL || process.env.REACT_APP_WS_URL || 'http://127.0.0.1:3002';
export const API_URL = (window as any).Cypress
? window._env_.REACT_APP_API_URL || process.env.REACT_APP_API_URL || 'http://127.0.0.1:1336'
: window._env_.REACT_APP_API_URL || process.env.REACT_APP_API_URL || 'http://127.0.0.1:3000';
export const WS_URL = (window as any).Cypress
? window._env_.REACT_APP_WS_URL || process.env.REACT_APP_WS_URL || 'http://127.0.0.1:1340'
: window._env_.REACT_APP_WS_URL || process.env.REACT_APP_WS_URL || 'http://127.0.0.1:3002';

export const CONTEXT_PATH = getContextPath(NovuComponentEnum.WIDGET);
11 changes: 8 additions & 3 deletions packages/shared/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@
"afterinstall": "pnpm build",
"prebuild": "rimraf dist",
"build": "npm run build:cjs && npm run build:esm",
"build:esm": "cross-env node_modules/.bin/tsc -p tsconfig.esm.json",
"build:cjs": "cross-env node_modules/.bin/tsc -p tsconfig.json",
"build:esm": "tsc -p tsconfig.esm.json",
"build:cjs": "tsc -p tsconfig.json",
"build:watch": "cross-env node_modules/.bin/tsc -p tsconfig.json -w --preserveWatchOutput",
"postbuild": "npm run check:circulars",
"start:dev": "pnpm build:watch",
Expand All @@ -25,7 +25,12 @@
"module": "dist/esm/index.js",
"types": "dist/cjs/index.d.ts",
"files": [
"dist/"
"dist/",
"!**/*.spec.*",
"!**/*.json",
"CHANGELOG.md",
"LICENSE",
"README.md"
],
"exports": {
".": {
Expand Down
2 changes: 1 addition & 1 deletion packages/shared/src/clients/novu-base-client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ export class HttpError extends Error {
this.name = this.constructor.name;
}

toString(): string {
override toString(): string {
return `${this.name} (status: ${this.status}): ${this.responseText}`;
}
}
Expand Down
4 changes: 1 addition & 3 deletions packages/shared/src/config/processEnv.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,7 @@ const envFileFromNodeEnv = {
* @returns The path to the .env file.
*/
export function getEnvFileNameForNodeEnv(nodeEnv?: string): string {
const selectedEnvFile = envFileFromNodeEnv[nodeEnv || DEFAULT_ENV];

return selectedEnvFile;
return envFileFromNodeEnv[(nodeEnv || DEFAULT_ENV) as keyof typeof envFileFromNodeEnv];
}

/**
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
// @ts-nocheck
import { HandlebarHelpersEnum } from './handlebarHelpers';

import { TemplateVariableTypeEnum } from '../../types';
Expand Down Expand Up @@ -113,9 +114,8 @@ export function getTemplateVariables(bod): IMustacheVariable[] {
return stringVariables.concat(arrayVariables).concat(boolVariables).concat(pairVariables);
}

const shouldAddVariable = (variableName): boolean => {
const validRegExp = /^[a-zA-Z_][a-zA-Z0-9_-]*?/;
const isValid = variableName.match(validRegExp);
const VARIABLE_REGEX = /^[a-zA-Z_][a-zA-Z0-9_-]*?/;

return isValid;
const shouldAddVariable = (variableName: string): boolean => {
return VARIABLE_REGEX.test(variableName);
};
1 change: 0 additions & 1 deletion packages/shared/src/ui/index.ts
Original file line number Diff line number Diff line change
@@ -1,2 +1 @@
export * from './utils';
export * from './marketing';
3 changes: 0 additions & 3 deletions packages/shared/src/ui/utils.ts

This file was deleted.

17 changes: 11 additions & 6 deletions packages/shared/src/utils/env.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,16 @@
type CloudflareEnv = { env: Record<string, string> };

// https://remix.run/blog/remix-vite-stable#cloudflare-pages-support
const hasCloudflareProxyContext = (context): context is { cloudflare: CloudflareEnv } => {
/*
* https://remix.run/blog/remix-vite-stable#cloudflare-pages-support
*/

// eslint-disable-next-line @typescript-eslint/no-explicit-any
const hasCloudflareProxyContext = (context: any): context is { cloudflare: CloudflareEnv } => {
return !!context?.cloudflare?.env;
};

const hasCloudflareContext = (context): context is CloudflareEnv => {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const hasCloudflareContext = (context: any): context is CloudflareEnv => {
return !!context?.env;
};

Expand All @@ -16,7 +21,7 @@ const hasCloudflareContext = (context): context is CloudflareEnv => {
* @param name Pass the name of the environment variable. The param is case-sensitive.
* @returns string Returns the value of the environment variable if exists.
*/
export const getEnvVariable = (name: string, context?): string => {
export const getEnvVariable = (name: string, context?: unknown): string => {
// Node envs
if (typeof process !== 'undefined' && process.env && typeof process.env[name] === 'string') {
return process.env[name] as string;
Expand All @@ -36,8 +41,8 @@ export const getEnvVariable = (name: string, context?): string => {
}

// Check whether the value exists in the context object directly
if (context && typeof context[name] === 'string') {
return context[name] as string;
if (context && typeof context[name as keyof typeof context] === 'string') {
return context[name as keyof typeof context] as string;
}

// Cloudflare workers
Expand Down
20 changes: 13 additions & 7 deletions packages/shared/src/utils/normalizeEmail.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,21 +3,27 @@ const PLUS_AND_DOT = /\.|\+.*$/g;
const normalizableProviders = {
'gmail.com': {
cut: PLUS_AND_DOT,
aliasOf: '',
},
'googlemail.com': {
cut: PLUS_AND_DOT,
aliasOf: 'gmail.com',
},
'hotmail.com': {
cut: PLUS_ONLY,
aliasOf: '',
},
'live.com': {
cut: PLUS_AND_DOT,
aliasOf: '',
},
'outlook.com': {
cut: PLUS_ONLY,
aliasOf: '',
},
};
} as const;

type NormalizableProvider = keyof typeof normalizableProviders;

export function normalizeEmail(email: string): string {
if (typeof email !== 'string') {
Expand All @@ -31,16 +37,16 @@ export function normalizeEmail(email: string): string {
return email;
}

let username = emailParts[0];
let domain = emailParts[1];
let username = emailParts[0] || '';
let domain = emailParts[1] || '';

if (normalizableProviders.hasOwnProperty(domain)) {
if (normalizableProviders[domain].hasOwnProperty('cut')) {
username = username.replace(normalizableProviders[domain].cut, '');
if (normalizableProviders[domain as NormalizableProvider].cut) {
username = username.replace(normalizableProviders[domain as NormalizableProvider].cut, '');
}

if (normalizableProviders[domain].hasOwnProperty('aliasOf')) {
domain = normalizableProviders[domain].aliasOf;
if (normalizableProviders[domain as NormalizableProvider].aliasOf) {
domain = normalizableProviders[domain as NormalizableProvider].aliasOf;
}
}

Expand Down
61 changes: 32 additions & 29 deletions packages/shared/src/utils/schema/create-mock-object-from-schema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,36 +38,39 @@ export function createMockObjectFromSchema(
throw new Error('Schema must define an object with properties.');
}

return Object.entries(schema.properties).reduce((acc, [key, definition]) => {
if (typeof definition === 'boolean') {
return acc;
}
return Object.entries(schema.properties).reduce(
(acc, [key, definition]) => {
if (typeof definition === 'boolean') {
return acc;
}

const currentPath = path && path.length > 0 ? `${path}.${key}` : key;
const currentPath = path && path.length > 0 ? `${path}.${key}` : key;

if (definition.type === 'array' && definition.items) {
// handle array type by creating a mock object for the first item
acc[key] = [
createMockObjectFromSchema(
{
type: 'object',
properties:
typeof definition.items === 'object' && 'properties' in definition.items
? definition.items.properties
: {},
},
`${currentPath}.0`,
depth + 1
),
];
} else if (definition.default) {
acc[key] = definition.default;
} else if (definition.type === 'object' && definition.properties) {
acc[key] = createMockObjectFromSchema(definition, currentPath, depth + 1);
} else {
acc[key] = `{{${currentPath}}}`;
}
if (definition.type === 'array' && definition.items) {
// handle array type by creating a mock object for the first item
acc[key] = [
createMockObjectFromSchema(
{
type: 'object',
properties:
typeof definition.items === 'object' && 'properties' in definition.items
? definition.items.properties
: {},
},
`${currentPath}.0`,
depth + 1
),
];
} else if (definition.default) {
acc[key] = definition.default;
} else if (definition.type === 'object' && definition.properties) {
acc[key] = createMockObjectFromSchema(definition, currentPath, depth + 1);
} else {
acc[key] = `{{${currentPath}}}`;
}

return acc;
}, {});
return acc;
},
{} as Record<string, unknown>
);
}
4 changes: 3 additions & 1 deletion packages/shared/src/utils/slugify/slugify.spec.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
// @ts-nocheck
/* cspell:disable */
/* eslint-disable guard-for-in */

import { it, describe, expect } from 'vitest';
import { slugify } from './slugify';

describe('slugify', () => {
it('throws', () => {
try {
slugify(undefined as any);
slugify(undefined);
} catch (err) {
expect(err.message).toBe('Expected a string, got `undefined`');
}
Expand Down
1 change: 1 addition & 0 deletions packages/shared/tsconfig.esm.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
"extends": "./tsconfig.json",
"compilerOptions": {
"module": "ESNext",
"moduleResolution": "bundler",
"outDir": "./dist/esm"
}
}
27 changes: 19 additions & 8 deletions packages/shared/tsconfig.json
Original file line number Diff line number Diff line change
@@ -1,15 +1,26 @@
{
"extends": "../../tsconfig.json",
"compilerOptions": {
"strictNullChecks": true,
"module": "commonjs",
"target": "es6",
"composite": true,
"declaration": true,
"declarationMap": true,
"esModuleInterop": true,
"isolatedModules": true,
"lib": ["es2022", "dom"],
"module": "nodenext",
"moduleDetection": "force",
"moduleResolution": "nodenext",
"noImplicitOverride": true,
"noUncheckedIndexedAccess": true,
"outDir": "./dist/cjs",
"resolveJsonModule": true,
"rootDir": "./src",
"types": ["node"],
"moduleResolution": "node",
"resolveJsonModule": true
"skipLibCheck": true,
"sourceMap": true,
"strict": true,
"strictPropertyInitialization": false,
"target": "ES2022",
"verbatimModuleSyntax": false
},
"include": ["src/**/*"]
"include": ["src/**/*"],
"exclude": ["node_modules/**"]
}

0 comments on commit ff738e7

Please sign in to comment.