@burdenoff/microfe-store 2026.720.4 → 2026.728.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/generated/global-operations.d.ts +18 -0
- package/dist/generated/global-operations.js +16 -0
- package/dist/generated/global-operations.js.map +1 -1
- package/dist/generated/global-types.d.ts +2 -0
- package/dist/generated/global-types.js.map +1 -1
- package/dist/pages/MarketplaceHomePage.js.map +1 -1
- package/dist/pages/ProductDetailPage.js +479 -447
- package/dist/pages/ProductDetailPage.js.map +1 -1
- package/dist/utils/index.js +4 -1
- package/dist/utils/index.js.map +1 -1
- package/package.json +2 -1
package/dist/utils/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":[],"sources":["../../src/utils/index.ts"],"sourcesContent":["// Cache Intl.NumberFormat instances per currency to avoid per-call allocations.\nconst currencyFormatterCache = new Map<string, Intl.NumberFormat>();\n\nfunction getCurrencyFormatter(currency: string): Intl.NumberFormat {\n const cached = currencyFormatterCache.get(currency);\n if (cached) return cached;\n const fmt = new Intl.NumberFormat('en-US', { style: 'currency', currency });\n currencyFormatterCache.set(currency, fmt);\n return fmt;\n}\n\n/**\n * Format price with currency\n */\nexport function formatPrice(price: number, currency: string = 'USD'): string {\n return getCurrencyFormatter(currency).format(price);\n}\n\n/**\n * Format price honoring a pricing model. Returns \"Free\" for FREE model.\n */\nexport function formatPriceForModel(price: number, currency: string, model: string): string {\n if (model === 'FREE') return 'Free';\n return getCurrencyFormatter(currency || 'USD').format(price);\n}\n\n/**\n * Format number with abbreviation (1.2K, 3.4M, etc.)\n */\nexport function formatNumber(num: number): string {\n if (num >= 1000000) {\n return `${(num / 1000000).toFixed(1)}M`;\n }\n if (num >= 1000) {\n return `${(num / 1000).toFixed(1)}K`;\n }\n return num.toString();\n}\n\n/**\n * Calculate cart totals\n */\nexport function calculateCartTotals(\n items: Array<{ quantity: number; unitPrice: number }>,\n taxRate: number = 0.085\n) {\n const subtotal = items.reduce((sum, item) => sum + item.quantity * item.unitPrice, 0);\n const tax = subtotal * taxRate;\n const total = subtotal + tax;\n\n return { subtotal, tax, total };\n}\n\n/**\n * Generate rating stars array\n */\nexport function getRatingStars(rating: number): Array<'full' | 'half' | 'empty'> {\n const stars: Array<'full' | 'half' | 'empty'> = [];\n const fullStars = Math.floor(rating);\n const hasHalfStar = rating % 1 >= 0.5;\n\n for (let i = 0; i < fullStars; i++) {\n stars.push('full');\n }\n\n if (hasHalfStar) {\n stars.push('half');\n }\n\n while (stars.length < 5) {\n stars.push('empty');\n }\n\n return stars;\n}\n\n/**\n * Get item type display name\n */\nexport function getItemTypeName(itemType: string): string {\n const names: Record<string, string> = {\n APP: 'App',\n WORKFLOW: 'Workflow',\n TEMPLATE: 'Template',\n INTEGRATION: 'Integration',\n EXTENSION: 'Extension',\n THEME: 'Theme',\n PHYSICAL: 'Physical Product',\n BUNDLE: 'Bundle',\n };\n\n return names[itemType] || itemType;\n}\n\n/**\n * Get pricing model display name\n */\nexport function getPricingModelName(model: string): string {\n const names: Record<string, string> = {\n FREE: 'Free',\n ONE_TIME: 'One-time Purchase',\n SUBSCRIPTION: 'Subscription',\n USAGE_BASED: 'Usage-based',\n FREEMIUM: 'Freemium',\n PAY_WHAT_YOU_WANT: 'Pay What You Want',\n };\n\n return names[model] || model;\n}\n\n/**\n * Get status color variant\n */\nexport function getStatusColor(\n status: string\n): 'default' | 'success' | 'warning' | 'error' | 'info' {\n const colors: Record<string, 'default' | 'success' | 'warning' | 'error' | 'info'> = {\n // Product status\n DRAFT: 'default',\n PENDING_REVIEW: 'warning',\n APPROVED: 'success',\n PUBLISHED: 'success',\n REJECTED: 'error',\n DEPRECATED: 'warning',\n UNLISTED: 'default',\n\n // Installation status\n PENDING: 'warning',\n INSTALLING: 'info',\n CONFIGURING: 'info',\n ACTIVE: 'success',\n INACTIVE: 'default',\n FAILED: 'error',\n UNINSTALLING: 'warning',\n\n // License status (ACTIVE already defined above)\n EXPIRED: 'error',\n REVOKED: 'error',\n SUSPENDED: 'warning',\n PENDING_ACTIVATION: 'warning',\n\n // Order status (FAILED already defined above)\n PROCESSING: 'info',\n COMPLETED: 'success',\n REFUNDED: 'warning',\n };\n\n return colors[status] || 'default';\n}\n\n/**\n * Validate license key format\n */\nexport function validateLicenseKey(key: string): boolean {\n // Expected format: XXXX-XXXX-XXXX-XXXX\n const regex = /^[A-Z0-9]{4}-[A-Z0-9]{4}-[A-Z0-9]{4}-[A-Z0-9]{4}$/;\n return regex.test(key);\n}\n\n/**\n * Mask license key for display\n */\nexport function maskLicenseKey(key: string): string {\n const parts = key.split('-');\n if (parts.length !== 4) return key;\n\n return `${parts[0]}-${parts[1]}-****-****`;\n}\n\n/**\n * Calculate days until expiry\n */\nexport function getDaysUntilExpiry(expiryDate: string): number {\n const now = new Date();\n const expiry = new Date(expiryDate);\n const diffTime = expiry.getTime() - now.getTime();\n return Math.ceil(diffTime / (1000 * 60 * 60 * 24));\n}\n\n/**\n * Check if license is expiring soon (within 30 days)\n */\nexport function isLicenseExpiringSoon(expiryDate: string): boolean {\n const daysUntilExpiry = getDaysUntilExpiry(expiryDate);\n return daysUntilExpiry > 0 && daysUntilExpiry <= 30;\n}\n\n/**\n * Format file size\n */\nexport function formatFileSize(bytes: number): string {\n if (bytes === 0) return '0 Bytes';\n\n const k = 1024;\n const sizes = ['Bytes', 'KB', 'MB', 'GB'];\n const i = Math.floor(Math.log(bytes) / Math.log(k));\n\n return `${parseFloat((bytes / Math.pow(k, i)).toFixed(2))} ${sizes[i]}`;\n}\n\n/**\n * Generate unique cart item ID\n */\nexport function generateCartItemId(productId: string, variantId?: string): string {\n return variantId ? `${productId}-${variantId}` : productId;\n}\n\n/**\n * Debounce function\n */\nexport function debounce<T extends (...args: unknown[]) => unknown>(\n func: T,\n wait: number\n): (...args: Parameters<T>) => void {\n let timeout: ReturnType<typeof setTimeout> | null = null;\n\n return function executedFunction(...args: Parameters<T>) {\n const later = () => {\n timeout = null;\n func(...args);\n };\n\n if (timeout) {\n clearTimeout(timeout);\n }\n timeout = setTimeout(later, wait);\n };\n}\n\n/**\n * Truncate text with ellipsis\n */\nexport function truncate(text: string, maxLength: number): string {\n if (text.length <= maxLength) return text;\n return `${text.substring(0, maxLength)}...`;\n}\n"],"mappings":";AACA,IAAM,oBAAyB,IAAI,KAAgC;AAEnE,SAAS,EAAqB,GAAqC;CACjE,IAAM,IAAS,EAAuB,IAAI,EAAS;AACnD,KAAI,EAAQ,QAAO;CACnB,IAAM,IAAM,IAAI,KAAK,aAAa,SAAS;EAAE,OAAO;EAAY;EAAU,CAAC;AAE3E,QADA,EAAuB,IAAI,GAAU,EAAI,EAClC;;AAMT,SAAgB,EAAY,GAAe,IAAmB,OAAe;AAC3E,QAAO,EAAqB,EAAS,CAAC,OAAO,EAAM;;AAMrD,SAAgB,EAAoB,GAAe,GAAkB,GAAuB;AAE1F,QADI,MAAU,SAAe,SACtB,EAAqB,KAAY,MAAM,CAAC,OAAO,EAAM;;AAM9D,SAAgB,EAAa,GAAqB;AAOhD,QANI,KAAO,MACF,IAAI,IAAM,KAAS,QAAQ,EAAE,CAAC,KAEnC,KAAO,MACF,IAAI,IAAM,KAAM,QAAQ,EAAE,CAAC,KAE7B,EAAI,UAAU;;AAMvB,SAAgB,EACd,GACA,IAAkB,MAClB;CACA,IAAM,IAAW,EAAM,QAAQ,GAAK,MAAS,IAAM,EAAK,WAAW,EAAK,WAAW,EAAE,EAC/E,IAAM,IAAW;AAGvB,QAAO;EAAE;EAAU;EAAK,OAFV,IAAW;EAEM;;AAMjC,SAAgB,EAAe,GAAkD;CAC/E,IAAM,IAA0C,EAAE,EAC5C,IAAY,KAAK,MAAM,EAAO,EAC9B,IAAc,IAAS,KAAK;AAElC,MAAK,IAAI,IAAI,GAAG,IAAI,GAAW,IAC7B,GAAM,KAAK,OAAO;AAOpB,MAJI,KACF,EAAM,KAAK,OAAO,EAGb,EAAM,SAAS,GACpB,GAAM,KAAK,QAAQ;AAGrB,QAAO;;AAMT,SAAgB,EAAgB,GAA0B;
|
|
1
|
+
{"version":3,"file":"index.js","names":[],"sources":["../../src/utils/index.ts"],"sourcesContent":["// Cache Intl.NumberFormat instances per currency to avoid per-call allocations.\nconst currencyFormatterCache = new Map<string, Intl.NumberFormat>();\n\nfunction getCurrencyFormatter(currency: string): Intl.NumberFormat {\n const cached = currencyFormatterCache.get(currency);\n if (cached) return cached;\n const fmt = new Intl.NumberFormat('en-US', { style: 'currency', currency });\n currencyFormatterCache.set(currency, fmt);\n return fmt;\n}\n\n/**\n * Format price with currency\n */\nexport function formatPrice(price: number, currency: string = 'USD'): string {\n return getCurrencyFormatter(currency).format(price);\n}\n\n/**\n * Format price honoring a pricing model. Returns \"Free\" for FREE model.\n */\nexport function formatPriceForModel(price: number, currency: string, model: string): string {\n if (model === 'FREE') return 'Free';\n return getCurrencyFormatter(currency || 'USD').format(price);\n}\n\n/**\n * Format number with abbreviation (1.2K, 3.4M, etc.)\n */\nexport function formatNumber(num: number): string {\n if (num >= 1000000) {\n return `${(num / 1000000).toFixed(1)}M`;\n }\n if (num >= 1000) {\n return `${(num / 1000).toFixed(1)}K`;\n }\n return num.toString();\n}\n\n/**\n * Calculate cart totals\n */\nexport function calculateCartTotals(\n items: Array<{ quantity: number; unitPrice: number }>,\n taxRate: number = 0.085\n) {\n const subtotal = items.reduce((sum, item) => sum + item.quantity * item.unitPrice, 0);\n const tax = subtotal * taxRate;\n const total = subtotal + tax;\n\n return { subtotal, tax, total };\n}\n\n/**\n * Generate rating stars array\n */\nexport function getRatingStars(rating: number): Array<'full' | 'half' | 'empty'> {\n const stars: Array<'full' | 'half' | 'empty'> = [];\n const fullStars = Math.floor(rating);\n const hasHalfStar = rating % 1 >= 0.5;\n\n for (let i = 0; i < fullStars; i++) {\n stars.push('full');\n }\n\n if (hasHalfStar) {\n stars.push('half');\n }\n\n while (stars.length < 5) {\n stars.push('empty');\n }\n\n return stars;\n}\n\n/**\n * Get item type display name\n */\nexport function getItemTypeName(itemType: string): string {\n const names: Record<string, string> = {\n APP: 'App',\n WORKFLOW: 'Workflow',\n TEMPLATE: 'Template',\n INTEGRATION: 'Integration',\n EXTENSION: 'Extension',\n THEME: 'Theme',\n PHYSICAL: 'Physical Product',\n BUNDLE: 'Bundle',\n PARSER: 'Parser',\n WIDGET: 'Widget',\n DASHBOARD: 'Dashboard Template',\n };\n\n return names[itemType] || itemType;\n}\n\n/**\n * Get pricing model display name\n */\nexport function getPricingModelName(model: string): string {\n const names: Record<string, string> = {\n FREE: 'Free',\n ONE_TIME: 'One-time Purchase',\n SUBSCRIPTION: 'Subscription',\n USAGE_BASED: 'Usage-based',\n FREEMIUM: 'Freemium',\n PAY_WHAT_YOU_WANT: 'Pay What You Want',\n };\n\n return names[model] || model;\n}\n\n/**\n * Get status color variant\n */\nexport function getStatusColor(\n status: string\n): 'default' | 'success' | 'warning' | 'error' | 'info' {\n const colors: Record<string, 'default' | 'success' | 'warning' | 'error' | 'info'> = {\n // Product status\n DRAFT: 'default',\n PENDING_REVIEW: 'warning',\n APPROVED: 'success',\n PUBLISHED: 'success',\n REJECTED: 'error',\n DEPRECATED: 'warning',\n UNLISTED: 'default',\n\n // Installation status\n PENDING: 'warning',\n INSTALLING: 'info',\n CONFIGURING: 'info',\n ACTIVE: 'success',\n INACTIVE: 'default',\n FAILED: 'error',\n UNINSTALLING: 'warning',\n\n // License status (ACTIVE already defined above)\n EXPIRED: 'error',\n REVOKED: 'error',\n SUSPENDED: 'warning',\n PENDING_ACTIVATION: 'warning',\n\n // Order status (FAILED already defined above)\n PROCESSING: 'info',\n COMPLETED: 'success',\n REFUNDED: 'warning',\n };\n\n return colors[status] || 'default';\n}\n\n/**\n * Validate license key format\n */\nexport function validateLicenseKey(key: string): boolean {\n // Expected format: XXXX-XXXX-XXXX-XXXX\n const regex = /^[A-Z0-9]{4}-[A-Z0-9]{4}-[A-Z0-9]{4}-[A-Z0-9]{4}$/;\n return regex.test(key);\n}\n\n/**\n * Mask license key for display\n */\nexport function maskLicenseKey(key: string): string {\n const parts = key.split('-');\n if (parts.length !== 4) return key;\n\n return `${parts[0]}-${parts[1]}-****-****`;\n}\n\n/**\n * Calculate days until expiry\n */\nexport function getDaysUntilExpiry(expiryDate: string): number {\n const now = new Date();\n const expiry = new Date(expiryDate);\n const diffTime = expiry.getTime() - now.getTime();\n return Math.ceil(diffTime / (1000 * 60 * 60 * 24));\n}\n\n/**\n * Check if license is expiring soon (within 30 days)\n */\nexport function isLicenseExpiringSoon(expiryDate: string): boolean {\n const daysUntilExpiry = getDaysUntilExpiry(expiryDate);\n return daysUntilExpiry > 0 && daysUntilExpiry <= 30;\n}\n\n/**\n * Format file size\n */\nexport function formatFileSize(bytes: number): string {\n if (bytes === 0) return '0 Bytes';\n\n const k = 1024;\n const sizes = ['Bytes', 'KB', 'MB', 'GB'];\n const i = Math.floor(Math.log(bytes) / Math.log(k));\n\n return `${parseFloat((bytes / Math.pow(k, i)).toFixed(2))} ${sizes[i]}`;\n}\n\n/**\n * Generate unique cart item ID\n */\nexport function generateCartItemId(productId: string, variantId?: string): string {\n return variantId ? `${productId}-${variantId}` : productId;\n}\n\n/**\n * Debounce function\n */\nexport function debounce<T extends (...args: unknown[]) => unknown>(\n func: T,\n wait: number\n): (...args: Parameters<T>) => void {\n let timeout: ReturnType<typeof setTimeout> | null = null;\n\n return function executedFunction(...args: Parameters<T>) {\n const later = () => {\n timeout = null;\n func(...args);\n };\n\n if (timeout) {\n clearTimeout(timeout);\n }\n timeout = setTimeout(later, wait);\n };\n}\n\n/**\n * Truncate text with ellipsis\n */\nexport function truncate(text: string, maxLength: number): string {\n if (text.length <= maxLength) return text;\n return `${text.substring(0, maxLength)}...`;\n}\n"],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@burdenoff/microfe-store",
|
|
3
|
-
"version": "2026.
|
|
3
|
+
"version": "2026.728.1",
|
|
4
4
|
"description": "Store microfrontend for Burdenoff products",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"files": [
|
|
@@ -48,6 +48,7 @@
|
|
|
48
48
|
"lucide-react": "^0.468.0",
|
|
49
49
|
"react": "^19.0.0",
|
|
50
50
|
"react-dom": "^19.0.0",
|
|
51
|
+
"react-markdown": "^10.1.0",
|
|
51
52
|
"react-router-dom": "^7.1.3",
|
|
52
53
|
"tailwind-merge": "^3.4.0",
|
|
53
54
|
"zustand": "^5.0.3"
|