Core utilities for Medusa e-commerce platform including error handling, DI container, amount calculations, and configuration parsing
—
Pending
Does it follow best practices?
Impact
Pending
No eval scenarios have been run
Pending
The risk profile of this skill
Comprehensive data processing utilities including country code lookup, CORS origin parsing, field transformations, and validation functions for common data operations.
Complete country information with ISO codes and lookup functionality.
/**
* Country information structure
*/
type Country = {
/** ISO 3166-1 alpha-2 country code */
alpha2: string;
/** Country name */
name: string;
/** ISO 3166-1 alpha-3 country code */
alpha3: string;
/** ISO 3166-1 numeric country code */
numeric: string;
};
/**
* Complete array of all countries with ISO codes
*/
const countries: Country[];
/**
* Looks up ISO alpha-2 country code from country name or other ISO codes
* @param country - Country name, alpha-2, or alpha-3 code (case-insensitive)
* @returns ISO alpha-2 country code
* @throws Error if country is not found
*/
function isoCountryLookup(country: string): string;Usage Examples:
import { countries, isoCountryLookup } from "medusa-core-utils";
// Access complete country list
console.log(`Total countries: ${countries.length}`); // 249 countries
// Find specific country
const usa = countries.find(c => c.alpha2 === "US");
console.log(usa);
// { alpha2: "US", name: "United States", alpha3: "USA", numeric: "840" }
// Lookup by country name
const usCode = isoCountryLookup("United States"); // "US"
const ukCode = isoCountryLookup("United Kingdom"); // "GB"
// Lookup by alpha-3 code
const deCode = isoCountryLookup("DEU"); // "DE"
// Case-insensitive lookup
const frCode = isoCountryLookup("france"); // "FR"
const caCode = isoCountryLookup("CAN"); // "CA"
// Error handling
try {
const invalidCode = isoCountryLookup("Invalid Country");
} catch (error) {
console.log(error.message); // "Invalid country name"
}
// Validate shipping addresses
function validateShippingCountry(countryInput: string): string {
try {
return isoCountryLookup(countryInput);
} catch (error) {
throw new Error(`Invalid shipping country: ${countryInput}`);
}
}Parse and convert CORS origin strings into arrays of strings and regular expressions.
/**
* Parses a comma-separated CORS origin string into an array of origins
* Automatically converts regex patterns to RegExp objects
* @param str - Comma-separated string of origins, may include regex patterns
* @returns Array of origin strings and RegExp objects
*/
function parseCorsOrigins(str: string): (string | RegExp)[];Usage Examples:
import { parseCorsOrigins } from "medusa-core-utils";
// Simple origins
const simpleOrigins = parseCorsOrigins("http://localhost:3000,https://example.com");
// ["http://localhost:3000", "https://example.com"]
// Mixed origins with regex patterns
const mixedOrigins = parseCorsOrigins(
"http://localhost:3000,/https:\\/\\/.*\\.example\\.com/i,https://api.test.com"
);
// ["http://localhost:3000", /https:\/\/.*\.example\.com/i, "https://api.test.com"]
// Empty string handling
const emptyOrigins = parseCorsOrigins(""); // []
// Use with Express CORS
import cors from "cors";
const corsOptions = {
origin: parseCorsOrigins(process.env.ALLOWED_ORIGINS || ""),
credentials: true
};
app.use(cors(corsOptions));
// Dynamic CORS configuration
function setupCORS(environment: string) {
let allowedOrigins = "";
switch (environment) {
case "development":
allowedOrigins = "http://localhost:3000,http://localhost:3001";
break;
case "staging":
allowedOrigins = "/https:\\/\\/.*\\.staging\\.example\\.com/i";
break;
case "production":
allowedOrigins = "https://example.com,https://www.example.com";
break;
}
return parseCorsOrigins(allowedOrigins);
}Transform object fields by appending '_id' suffix to string values, useful for API payload normalization.
/**
* Transform object fields by appending '_id' suffix to string values
* @param obj - The object to transform
* @param fields - Array of field names to apply transformation to
* @returns New object with transformed field names
*/
function transformIdableFields<
T extends object = Record<string, unknown>,
TFields extends (keyof T | string)[] = (keyof T | string)[],
TOutput = {
[P in ComputePropertyNames<T, keyof T & string, TFields>]: P extends keyof T
? T[P]
: string
}
>(obj: T, fields: TFields): TOutput;
/**
* Type utility for computing transformed property names
*/
type ComputePropertyNames<
T,
TKey extends keyof T & string,
TFields extends (keyof T | string)[] = (keyof T | string)[]
> = TKey extends TFields[number]
? T[TKey] extends string
? `${TKey}_id`
: TKey
: TKey;Usage Examples:
import { transformIdableFields } from "medusa-core-utils";
// Basic transformation
const input = {
user: "user123", // string - will be transformed
category: "electronics", // string - will be transformed
price: 29.99, // number - will not be transformed
active: true // boolean - will not be transformed
};
const transformed = transformIdableFields(input, ["user", "category"]);
console.log(transformed);
// {
// user_id: "user123",
// category_id: "electronics",
// price: 29.99,
// active: true
// }
// API payload normalization
interface ProductInput {
name: string;
category: string | { id: string; name: string };
brand: string | { id: string; name: string };
price: number;
}
function normalizeProductPayload(payload: ProductInput) {
// Transform string references to _id fields
return transformIdableFields(payload, ["category", "brand"]);
}
const apiPayload = {
name: "Laptop",
category: "electronics", // String ID reference
brand: "apple", // String ID reference
price: 999.99
};
const normalized = normalizeProductPayload(apiPayload);
// { name: "Laptop", category_id: "electronics", brand_id: "apple", price: 999.99 }
// Handling mixed field types
const mixedInput = {
user: { id: "user123", name: "John" }, // Object - not transformed
role: "admin", // String - will be transformed
permissions: ["read", "write"], // Array - not transformed
status: "active" // String - will be transformed
};
const mixedResult = transformIdableFields(mixedInput, ["user", "role", "status"]);
// { user: { id: "user123", name: "John" }, role_id: "admin", permissions: ["read", "write"], status_id: "active" }Type-safe undefined checking with proper type guards.
/**
* Type-safe check for defined values with proper type narrowing
* @param val - Value to check for undefined
* @returns Type predicate indicating if value is defined
*/
function isDefined<T = undefined | unknown>(
val: T
): val is T extends undefined ? never : T;Usage Examples:
import { isDefined } from "medusa-core-utils";
// Basic undefined checking
const maybeString: string | undefined = getValue();
if (isDefined(maybeString)) {
// TypeScript knows maybeString is string here
console.log(maybeString.toUpperCase()); // No type error
}
// Array filtering
const mixedArray: (string | undefined | null)[] = [
"hello",
undefined,
"world",
null,
"test"
];
const definedStrings = mixedArray.filter(isDefined);
// TypeScript infers definedStrings as (string | null)[]
// Function parameter validation
function processUserData(user: {
id?: string;
name?: string;
email?: string;
}) {
const requiredFields = [user.id, user.name, user.email];
if (!requiredFields.every(isDefined)) {
throw new Error("Missing required user fields");
}
// TypeScript knows all fields are defined here
return {
id: user.id, // string (not string | undefined)
name: user.name, // string (not string | undefined)
email: user.email // string (not string | undefined)
};
}
// Optional chaining with type safety
interface NestedData {
user?: {
profile?: {
settings?: {
theme: string;
};
};
};
}
function getTheme(data: NestedData): string | undefined {
const theme = data.user?.profile?.settings?.theme;
if (isDefined(theme)) {
return theme; // TypeScript knows this is string
}
return undefined;
}Constants for indexing and search operations.
/**
* Index type constants for search and indexing operations
*/
const indexTypes: {
products: "products";
};Usage Examples:
import { indexTypes } from "medusa-core-utils";
// Search index configuration
const searchConfig = {
[indexTypes.products]: {
mappings: {
title: { type: "text", analyzer: "standard" },
description: { type: "text", analyzer: "standard" },
price: { type: "float" },
category: { type: "keyword" }
}
}
};
// Index type validation
function validateIndexType(type: string): boolean {
return Object.values(indexTypes).includes(type as any);
}
// Search operations
async function searchIndex(type: keyof typeof indexTypes, query: string) {
if (type === indexTypes.products) {
return await searchProducts(query);
}
throw new Error(`Unsupported index type: ${type}`);
}