@the-apparel-lab/pricing-engine 1.0.0
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/config/pricing-config.json +23 -0
- package/dist/audit/actuals-comparison.d.ts +10 -0
- package/dist/audit/actuals-comparison.d.ts.map +1 -0
- package/dist/audit/actuals-comparison.js +96 -0
- package/dist/audit/actuals-comparison.js.map +1 -0
- package/dist/audit/margin.d.ts +20 -0
- package/dist/audit/margin.d.ts.map +1 -0
- package/dist/audit/margin.js +34 -0
- package/dist/audit/margin.js.map +1 -0
- package/dist/audit-runner.d.ts +11 -0
- package/dist/audit-runner.d.ts.map +1 -0
- package/dist/audit-runner.js +277 -0
- package/dist/audit-runner.js.map +1 -0
- package/dist/calculators/blanks.d.ts +18 -0
- package/dist/calculators/blanks.d.ts.map +1 -0
- package/dist/calculators/blanks.js +26 -0
- package/dist/calculators/blanks.js.map +1 -0
- package/dist/calculators/decoration.d.ts +32 -0
- package/dist/calculators/decoration.d.ts.map +1 -0
- package/dist/calculators/decoration.js +63 -0
- package/dist/calculators/decoration.js.map +1 -0
- package/dist/calculators/setup-fees.d.ts +27 -0
- package/dist/calculators/setup-fees.d.ts.map +1 -0
- package/dist/calculators/setup-fees.js +60 -0
- package/dist/calculators/setup-fees.js.map +1 -0
- package/dist/calculators/shipping.d.ts +14 -0
- package/dist/calculators/shipping.d.ts.map +1 -0
- package/dist/calculators/shipping.js +17 -0
- package/dist/calculators/shipping.js.map +1 -0
- package/dist/cli.d.ts +3 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +192 -0
- package/dist/cli.js.map +1 -0
- package/dist/config.d.ts +224 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +368 -0
- package/dist/config.js.map +1 -0
- package/dist/index.d.ts +20 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +295 -0
- package/dist/index.js.map +1 -0
- package/dist/types.d.ts +230 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +4 -0
- package/dist/types.js.map +1 -0
- package/dist/utils/blanks-lookup.d.ts +42 -0
- package/dist/utils/blanks-lookup.d.ts.map +1 -0
- package/dist/utils/blanks-lookup.js +99 -0
- package/dist/utils/blanks-lookup.js.map +1 -0
- package/dist/utils/money.d.ts +21 -0
- package/dist/utils/money.d.ts.map +1 -0
- package/dist/utils/money.js +38 -0
- package/dist/utils/money.js.map +1 -0
- package/dist/utils/vendor-lookup.d.ts +49 -0
- package/dist/utils/vendor-lookup.d.ts.map +1 -0
- package/dist/utils/vendor-lookup.js +308 -0
- package/dist/utils/vendor-lookup.js.map +1 -0
- package/package.json +28 -0
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.normalizeBrandSku = normalizeBrandSku;
|
|
4
|
+
exports.normalizeColor = normalizeColor;
|
|
5
|
+
exports.lookupBlankPricing = lookupBlankPricing;
|
|
6
|
+
/**
|
|
7
|
+
* Normalize a brand_sku like "Gildan 5000" to a lookup key like "gildan_5000".
|
|
8
|
+
*
|
|
9
|
+
* Handles common variations:
|
|
10
|
+
* "Bella+Canvas 3001" → "bella_canvas_3001"
|
|
11
|
+
* "Port & Company PC61" → "port_company_pc61"
|
|
12
|
+
* "Independent Trading Co. SS4500" → "independent_trading_co_ss4500"
|
|
13
|
+
* "Next Level 3600" → "next_level_3600"
|
|
14
|
+
*/
|
|
15
|
+
function normalizeBrandSku(brandSku) {
|
|
16
|
+
return brandSku
|
|
17
|
+
.toLowerCase()
|
|
18
|
+
.replace(/\+/g, '_')
|
|
19
|
+
.replace(/&/g, 'and')
|
|
20
|
+
.replace(/\./g, '')
|
|
21
|
+
.replace(/[^a-z0-9]+/g, '_')
|
|
22
|
+
.replace(/_+/g, '_')
|
|
23
|
+
.replace(/^_|_$/g, '');
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Normalize a color name for lookup.
|
|
27
|
+
* "Dark Heather" → "dark_heather"
|
|
28
|
+
* "Sport Grey" → "sport_grey"
|
|
29
|
+
*/
|
|
30
|
+
function normalizeColor(color) {
|
|
31
|
+
return color
|
|
32
|
+
.toLowerCase()
|
|
33
|
+
.replace(/[^a-z0-9]+/g, '_')
|
|
34
|
+
.replace(/_+/g, '_')
|
|
35
|
+
.replace(/^_|_$/g, '');
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Look up blank garment pricing from the blanks feed.
|
|
39
|
+
*
|
|
40
|
+
* Returns the cheapest standard-size price and cheapest oversized price
|
|
41
|
+
* for the given style and color. Uses the `standard_sizes` and `oversized_sizes`
|
|
42
|
+
* arrays from the feed to classify sizes.
|
|
43
|
+
*/
|
|
44
|
+
function lookupBlankPricing(blanksData, params) {
|
|
45
|
+
const styleKey = normalizeBrandSku(params.brandSku);
|
|
46
|
+
const colorKey = normalizeColor(params.color);
|
|
47
|
+
// Find style
|
|
48
|
+
const style = blanksData.styles[styleKey];
|
|
49
|
+
if (!style) {
|
|
50
|
+
const availableStyles = Object.keys(blanksData.styles).slice(0, 10).join(', ');
|
|
51
|
+
return {
|
|
52
|
+
unitPriceCents: null,
|
|
53
|
+
oversizedUnitPriceCents: null,
|
|
54
|
+
warning: `Style "${params.brandSku}" (key: "${styleKey}") not found in blanks pricing database. Available styles: ${availableStyles}${Object.keys(blanksData.styles).length > 10 ? '...' : ''}`,
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
// Find color
|
|
58
|
+
const color = style.colors[colorKey];
|
|
59
|
+
if (!color) {
|
|
60
|
+
const availableColors = Object.keys(style.colors).slice(0, 10).join(', ');
|
|
61
|
+
return {
|
|
62
|
+
unitPriceCents: null,
|
|
63
|
+
oversizedUnitPriceCents: null,
|
|
64
|
+
warning: `Color "${params.color}" (key: "${colorKey}") not found for ${style.brand_display} ${style.style_number}. Available colors: ${availableColors}${Object.keys(style.colors).length > 10 ? '...' : ''}`,
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
const standardSizes = new Set(style.standard_sizes);
|
|
68
|
+
const oversizedSizes = new Set(style.oversized_sizes);
|
|
69
|
+
// Find cheapest standard-size price
|
|
70
|
+
let cheapestStandard = null;
|
|
71
|
+
let standardSupplier;
|
|
72
|
+
for (const [sizeName, sizeData] of Object.entries(color.sizes)) {
|
|
73
|
+
if (standardSizes.has(sizeName) && (cheapestStandard === null || sizeData.price_cents < cheapestStandard)) {
|
|
74
|
+
cheapestStandard = sizeData.price_cents;
|
|
75
|
+
standardSupplier = sizeData.supplier;
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
// Find cheapest oversized price
|
|
79
|
+
let cheapestOversized = null;
|
|
80
|
+
let oversizedSupplier;
|
|
81
|
+
for (const [sizeName, sizeData] of Object.entries(color.sizes)) {
|
|
82
|
+
if (oversizedSizes.has(sizeName) && (cheapestOversized === null || sizeData.price_cents < cheapestOversized)) {
|
|
83
|
+
cheapestOversized = sizeData.price_cents;
|
|
84
|
+
oversizedSupplier = sizeData.supplier;
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
// Build warning if partial result
|
|
88
|
+
let warning;
|
|
89
|
+
if (cheapestStandard === null) {
|
|
90
|
+
warning = `No standard-size pricing found for ${style.brand_display} ${style.style_number} in color "${params.color}"`;
|
|
91
|
+
}
|
|
92
|
+
return {
|
|
93
|
+
unitPriceCents: cheapestStandard,
|
|
94
|
+
oversizedUnitPriceCents: cheapestOversized,
|
|
95
|
+
supplier: standardSupplier || oversizedSupplier,
|
|
96
|
+
warning,
|
|
97
|
+
};
|
|
98
|
+
}
|
|
99
|
+
//# sourceMappingURL=blanks-lookup.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"blanks-lookup.js","sourceRoot":"","sources":["../../src/utils/blanks-lookup.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Cents-based arithmetic helpers.
|
|
3
|
+
*
|
|
4
|
+
* All internal monetary math uses integer cents to avoid
|
|
5
|
+
* floating-point rounding errors. Convert to dollars only
|
|
6
|
+
* at the final output layer.
|
|
7
|
+
*/
|
|
8
|
+
/** Convert a dollar amount to integer cents. */
|
|
9
|
+
export declare function toCents(dollars: number): number;
|
|
10
|
+
/** Convert integer cents to a dollar amount (2 decimal places). */
|
|
11
|
+
export declare function toDollars(cents: number): number;
|
|
12
|
+
/**
|
|
13
|
+
* Round a dollar amount to the nearest cent.
|
|
14
|
+
* Useful at the output boundary when combining already-converted values.
|
|
15
|
+
*/
|
|
16
|
+
export declare function roundMoney(dollars: number): number;
|
|
17
|
+
/** Multiply cents by a multiplier, returning integer cents (rounded). */
|
|
18
|
+
export declare function multiplyCents(cents: number, multiplier: number): number;
|
|
19
|
+
/** Sum an array of cent values. */
|
|
20
|
+
export declare function sumCents(values: number[]): number;
|
|
21
|
+
//# sourceMappingURL=money.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"money.d.ts","sourceRoot":"","sources":["../../src/utils/money.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,gDAAgD;AAChD,wBAAgB,OAAO,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAE/C;AAED,mEAAmE;AACnE,wBAAgB,SAAS,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAE/C;AAED;;;GAGG;AACH,wBAAgB,UAAU,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAElD;AAED,yEAAyE;AACzE,wBAAgB,aAAa,CAAC,KAAK,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,MAAM,CAEvE;AAED,mCAAmC;AACnC,wBAAgB,QAAQ,CAAC,MAAM,EAAE,MAAM,EAAE,GAAG,MAAM,CAEjD"}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Cents-based arithmetic helpers.
|
|
4
|
+
*
|
|
5
|
+
* All internal monetary math uses integer cents to avoid
|
|
6
|
+
* floating-point rounding errors. Convert to dollars only
|
|
7
|
+
* at the final output layer.
|
|
8
|
+
*/
|
|
9
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
10
|
+
exports.toCents = toCents;
|
|
11
|
+
exports.toDollars = toDollars;
|
|
12
|
+
exports.roundMoney = roundMoney;
|
|
13
|
+
exports.multiplyCents = multiplyCents;
|
|
14
|
+
exports.sumCents = sumCents;
|
|
15
|
+
/** Convert a dollar amount to integer cents. */
|
|
16
|
+
function toCents(dollars) {
|
|
17
|
+
return Math.round(dollars * 100);
|
|
18
|
+
}
|
|
19
|
+
/** Convert integer cents to a dollar amount (2 decimal places). */
|
|
20
|
+
function toDollars(cents) {
|
|
21
|
+
return Math.round(cents) / 100;
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Round a dollar amount to the nearest cent.
|
|
25
|
+
* Useful at the output boundary when combining already-converted values.
|
|
26
|
+
*/
|
|
27
|
+
function roundMoney(dollars) {
|
|
28
|
+
return Math.round(dollars * 100) / 100;
|
|
29
|
+
}
|
|
30
|
+
/** Multiply cents by a multiplier, returning integer cents (rounded). */
|
|
31
|
+
function multiplyCents(cents, multiplier) {
|
|
32
|
+
return Math.round(cents * multiplier);
|
|
33
|
+
}
|
|
34
|
+
/** Sum an array of cent values. */
|
|
35
|
+
function sumCents(values) {
|
|
36
|
+
return values.reduce((sum, v) => sum + v, 0);
|
|
37
|
+
}
|
|
38
|
+
//# sourceMappingURL=money.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"money.js","sourceRoot":"","sources":["../../src/utils/money.ts"],"names":[],"mappings":";AAAA;;;;;;GAMG;;AAGH,0BAEC;AAGD,8BAEC;AAMD,gCAEC;AAGD,sCAEC;AAGD,4BAEC;AA1BD,gDAAgD;AAChD,SAAgB,OAAO,CAAC,OAAe;IACrC,OAAO,IAAI,CAAC,KAAK,CAAC,OAAO,GAAG,GAAG,CAAC,CAAC;AACnC,CAAC;AAED,mEAAmE;AACnE,SAAgB,SAAS,CAAC,KAAa;IACrC,OAAO,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,GAAG,CAAC;AACjC,CAAC;AAED;;;GAGG;AACH,SAAgB,UAAU,CAAC,OAAe;IACxC,OAAO,IAAI,CAAC,KAAK,CAAC,OAAO,GAAG,GAAG,CAAC,GAAG,GAAG,CAAC;AACzC,CAAC;AAED,yEAAyE;AACzE,SAAgB,aAAa,CAAC,KAAa,EAAE,UAAkB;IAC7D,OAAO,IAAI,CAAC,KAAK,CAAC,KAAK,GAAG,UAAU,CAAC,CAAC;AACxC,CAAC;AAED,mCAAmC;AACnC,SAAgB,QAAQ,CAAC,MAAgB;IACvC,OAAO,MAAM,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC,GAAG,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC;AAC/C,CAAC"}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import type { VendorPricingData } from '../config';
|
|
2
|
+
import type { DecorationMethod } from '../types';
|
|
3
|
+
export interface LookupResult {
|
|
4
|
+
/** Minimum cost per unit in cents, or null if lookup failed. */
|
|
5
|
+
perUnitCents: number | null;
|
|
6
|
+
/** The vendor_id whose price was selected (the cheapest). */
|
|
7
|
+
vendorId?: string;
|
|
8
|
+
warning?: string;
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* Find the best matching quantity tier from the available tiers.
|
|
12
|
+
* Uses the largest tier that is <= the target quantity.
|
|
13
|
+
* If the target is below the smallest tier, uses the smallest tier.
|
|
14
|
+
*/
|
|
15
|
+
export declare function findQuantityTier(availableTiers: number[], targetQuantity: number): number;
|
|
16
|
+
/**
|
|
17
|
+
* Find the best matching stitch level for embroidery.
|
|
18
|
+
* Rounds UP to the nearest available stitch tier (vendor convention).
|
|
19
|
+
* If above the highest tier, uses the highest tier.
|
|
20
|
+
*/
|
|
21
|
+
export declare function findStitchTier(availableLevels: number[], stitchCount: number): number;
|
|
22
|
+
/**
|
|
23
|
+
* Calculate square inches from design dimensions, rounding up.
|
|
24
|
+
*/
|
|
25
|
+
export declare function calculateSqInches(height: number, width: number): number;
|
|
26
|
+
/**
|
|
27
|
+
* Find the best matching sq-in tier from the available levels.
|
|
28
|
+
* Rounds UP to the nearest available tier (ceiling match).
|
|
29
|
+
* If above the highest tier, uses the highest tier.
|
|
30
|
+
*/
|
|
31
|
+
export declare function findSqInTier(availableLevels: number[], sqIn: number): number;
|
|
32
|
+
export interface LookupParams {
|
|
33
|
+
method: DecorationMethod;
|
|
34
|
+
quantity: number;
|
|
35
|
+
colorCount?: number;
|
|
36
|
+
stitchCount?: number;
|
|
37
|
+
sublimationProductKey?: string;
|
|
38
|
+
/** Design dimensions — used for DTF/DTG sq-in tier matching. */
|
|
39
|
+
designHeight?: number;
|
|
40
|
+
designWidth?: number;
|
|
41
|
+
/** DTG ink mode. Defaults to 'dark' (conservative — never undercharges). */
|
|
42
|
+
garmentColorCategory?: 'light' | 'dark';
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Main dispatch: look up per-unit decoration cost from vendor pricing data.
|
|
46
|
+
* Returns the min cost in cents, or null with a warning if unavailable.
|
|
47
|
+
*/
|
|
48
|
+
export declare function lookupDecorationCostPerUnit(vendorData: VendorPricingData, params: LookupParams): LookupResult;
|
|
49
|
+
//# sourceMappingURL=vendor-lookup.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"vendor-lookup.d.ts","sourceRoot":"","sources":["../../src/utils/vendor-lookup.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAA4C,MAAM,WAAW,CAAC;AAC7F,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,UAAU,CAAC;AAEjD,MAAM,WAAW,YAAY;IAC3B,gEAAgE;IAChE,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,6DAA6D;IAC7D,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAoCD;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,cAAc,EAAE,MAAM,EAAE,EAAE,cAAc,EAAE,MAAM,GAAG,MAAM,CAWzF;AAED;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,eAAe,EAAE,MAAM,EAAE,EAAE,WAAW,EAAE,MAAM,GAAG,MAAM,CAQrF;AA+FD;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,CAEvE;AAED;;;;GAIG;AACH,wBAAgB,YAAY,CAAC,eAAe,EAAE,MAAM,EAAE,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,CAQ5E;AAmFD,MAAM,WAAW,YAAY;IAC3B,MAAM,EAAE,gBAAgB,CAAC;IACzB,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,qBAAqB,CAAC,EAAE,MAAM,CAAC;IAC/B,gEAAgE;IAChE,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,4EAA4E;IAC5E,oBAAoB,CAAC,EAAE,OAAO,GAAG,MAAM,CAAC;CACzC;AAED;;;GAGG;AACH,wBAAgB,2BAA2B,CACzC,UAAU,EAAE,iBAAiB,EAC7B,MAAM,EAAE,YAAY,GACnB,YAAY,CAqId"}
|
|
@@ -0,0 +1,308 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.findQuantityTier = findQuantityTier;
|
|
4
|
+
exports.findStitchTier = findStitchTier;
|
|
5
|
+
exports.calculateSqInches = calculateSqInches;
|
|
6
|
+
exports.findSqInTier = findSqInTier;
|
|
7
|
+
exports.lookupDecorationCostPerUnit = lookupDecorationCostPerUnit;
|
|
8
|
+
/**
|
|
9
|
+
* Find the vendor with the lowest price from a standard vendors map.
|
|
10
|
+
* Used for screen printing, embroidery, DTG, and sublimation.
|
|
11
|
+
*/
|
|
12
|
+
function findMinVendor(vendors) {
|
|
13
|
+
if (!vendors || Object.keys(vendors).length === 0)
|
|
14
|
+
return undefined;
|
|
15
|
+
let minVendor;
|
|
16
|
+
let minPrice = Infinity;
|
|
17
|
+
for (const [vendorId, price] of Object.entries(vendors)) {
|
|
18
|
+
if (price < minPrice) {
|
|
19
|
+
minPrice = price;
|
|
20
|
+
minVendor = vendorId;
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
return minVendor;
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Find the vendor with the lowest total_cents from a DTF vendors map.
|
|
27
|
+
* DTF vendors have a detail object instead of a raw number.
|
|
28
|
+
*/
|
|
29
|
+
function findMinDtfVendor(vendors) {
|
|
30
|
+
if (!vendors || Object.keys(vendors).length === 0)
|
|
31
|
+
return undefined;
|
|
32
|
+
let minVendor;
|
|
33
|
+
let minPrice = Infinity;
|
|
34
|
+
for (const [vendorId, detail] of Object.entries(vendors)) {
|
|
35
|
+
if (detail.total_cents < minPrice) {
|
|
36
|
+
minPrice = detail.total_cents;
|
|
37
|
+
minVendor = vendorId;
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
return minVendor;
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Find the best matching quantity tier from the available tiers.
|
|
44
|
+
* Uses the largest tier that is <= the target quantity.
|
|
45
|
+
* If the target is below the smallest tier, uses the smallest tier.
|
|
46
|
+
*/
|
|
47
|
+
function findQuantityTier(availableTiers, targetQuantity) {
|
|
48
|
+
const sorted = [...availableTiers].sort((a, b) => a - b);
|
|
49
|
+
let best = sorted[0];
|
|
50
|
+
for (const tier of sorted) {
|
|
51
|
+
if (tier <= targetQuantity) {
|
|
52
|
+
best = tier;
|
|
53
|
+
}
|
|
54
|
+
else {
|
|
55
|
+
break;
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
return best;
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Find the best matching stitch level for embroidery.
|
|
62
|
+
* Rounds UP to the nearest available stitch tier (vendor convention).
|
|
63
|
+
* If above the highest tier, uses the highest tier.
|
|
64
|
+
*/
|
|
65
|
+
function findStitchTier(availableLevels, stitchCount) {
|
|
66
|
+
const sorted = [...availableLevels].sort((a, b) => a - b);
|
|
67
|
+
for (const level of sorted) {
|
|
68
|
+
if (stitchCount <= level) {
|
|
69
|
+
return level;
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
return sorted[sorted.length - 1];
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* Look up per-unit decoration cost for screen printing or screen print transfers.
|
|
76
|
+
* Keyed by `{N}_color` → quantity tier → min cents.
|
|
77
|
+
*/
|
|
78
|
+
function lookupScreenPrintCost(perPieceCents, referenceQuantities, colorCount, quantity) {
|
|
79
|
+
const colorKey = `${colorCount}_color`;
|
|
80
|
+
const colorTier = perPieceCents[colorKey];
|
|
81
|
+
if (!colorTier) {
|
|
82
|
+
const availableColors = Object.keys(perPieceCents).map(k => k.replace('_color', '')).join(', ');
|
|
83
|
+
return {
|
|
84
|
+
perUnitCents: null,
|
|
85
|
+
warning: `No pricing for ${colorCount}-color screen printing. Available color counts: ${availableColors}`,
|
|
86
|
+
};
|
|
87
|
+
}
|
|
88
|
+
const qtyTier = findQuantityTier(referenceQuantities, quantity);
|
|
89
|
+
const tierData = colorTier[String(qtyTier)];
|
|
90
|
+
if (!tierData) {
|
|
91
|
+
return {
|
|
92
|
+
perUnitCents: null,
|
|
93
|
+
warning: `No pricing for ${colorCount}-color screen printing at quantity tier ${qtyTier}`,
|
|
94
|
+
};
|
|
95
|
+
}
|
|
96
|
+
return { perUnitCents: tierData.min, vendorId: findMinVendor(tierData.vendors) };
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* Look up per-unit decoration cost for embroidery.
|
|
100
|
+
* Keyed by `{N}_stitches` → quantity tier → min cents.
|
|
101
|
+
*/
|
|
102
|
+
function lookupEmbroideryCost(perPieceCents, referenceQuantities, stitchLevels, stitchCount, quantity) {
|
|
103
|
+
const stitchTier = findStitchTier(stitchLevels, stitchCount);
|
|
104
|
+
const stitchKey = `${stitchTier}_stitches`;
|
|
105
|
+
const stitchData = perPieceCents[stitchKey];
|
|
106
|
+
if (!stitchData) {
|
|
107
|
+
return {
|
|
108
|
+
perUnitCents: null,
|
|
109
|
+
warning: `No pricing for ${stitchTier}-stitch embroidery tier`,
|
|
110
|
+
};
|
|
111
|
+
}
|
|
112
|
+
const qtyTier = findQuantityTier(referenceQuantities, quantity);
|
|
113
|
+
const tierData = stitchData[String(qtyTier)];
|
|
114
|
+
if (!tierData) {
|
|
115
|
+
return {
|
|
116
|
+
perUnitCents: null,
|
|
117
|
+
warning: `No pricing for ${stitchTier}-stitch embroidery at quantity tier ${qtyTier}`,
|
|
118
|
+
};
|
|
119
|
+
}
|
|
120
|
+
return { perUnitCents: tierData.min, vendorId: findMinVendor(tierData.vendors) };
|
|
121
|
+
}
|
|
122
|
+
/**
|
|
123
|
+
* Look up per-unit cost for sublimation.
|
|
124
|
+
* Sublimation uses product-based pricing (vendor supplies the garment).
|
|
125
|
+
* Requires a productKey to identify the product in the vendor JSON.
|
|
126
|
+
*/
|
|
127
|
+
function lookupSublimationCost(methodData, productKey) {
|
|
128
|
+
if (!productKey) {
|
|
129
|
+
return {
|
|
130
|
+
perUnitCents: null,
|
|
131
|
+
warning: 'Sublimation uses product-based pricing. Provide a sublimation_product_key or use manual_decoration_cost_per_unit.',
|
|
132
|
+
};
|
|
133
|
+
}
|
|
134
|
+
const product = methodData.products[productKey];
|
|
135
|
+
if (!product) {
|
|
136
|
+
const available = Object.keys(methodData.products).join(', ');
|
|
137
|
+
return {
|
|
138
|
+
perUnitCents: null,
|
|
139
|
+
warning: `Sublimation product "${productKey}" not found. Available: ${available}`,
|
|
140
|
+
};
|
|
141
|
+
}
|
|
142
|
+
return { perUnitCents: product.min, vendorId: findMinVendor(product.vendors) };
|
|
143
|
+
}
|
|
144
|
+
/**
|
|
145
|
+
* Calculate square inches from design dimensions, rounding up.
|
|
146
|
+
*/
|
|
147
|
+
function calculateSqInches(height, width) {
|
|
148
|
+
return Math.ceil(height * width);
|
|
149
|
+
}
|
|
150
|
+
/**
|
|
151
|
+
* Find the best matching sq-in tier from the available levels.
|
|
152
|
+
* Rounds UP to the nearest available tier (ceiling match).
|
|
153
|
+
* If above the highest tier, uses the highest tier.
|
|
154
|
+
*/
|
|
155
|
+
function findSqInTier(availableLevels, sqIn) {
|
|
156
|
+
const sorted = [...availableLevels].sort((a, b) => a - b);
|
|
157
|
+
for (const level of sorted) {
|
|
158
|
+
if (sqIn <= level) {
|
|
159
|
+
return level;
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
return sorted[sorted.length - 1];
|
|
163
|
+
}
|
|
164
|
+
/**
|
|
165
|
+
* Look up per-unit decoration cost for DTF.
|
|
166
|
+
* Keyed by `{N}_sqin` → quantity tier → min cents.
|
|
167
|
+
*/
|
|
168
|
+
function lookupDtfCost(perPieceCents, referenceQuantities, sqInLevels, height, width, quantity) {
|
|
169
|
+
const sqIn = calculateSqInches(height, width);
|
|
170
|
+
const tier = findSqInTier(sqInLevels, sqIn);
|
|
171
|
+
const sqInKey = `${tier}_sqin`;
|
|
172
|
+
const sqInData = perPieceCents[sqInKey];
|
|
173
|
+
if (!sqInData) {
|
|
174
|
+
return {
|
|
175
|
+
perUnitCents: null,
|
|
176
|
+
warning: `No DTF pricing for size tier "${sqInKey}"`,
|
|
177
|
+
};
|
|
178
|
+
}
|
|
179
|
+
const qtyTier = findQuantityTier(referenceQuantities, quantity);
|
|
180
|
+
const tierData = sqInData[String(qtyTier)];
|
|
181
|
+
if (!tierData) {
|
|
182
|
+
return {
|
|
183
|
+
perUnitCents: null,
|
|
184
|
+
warning: `No DTF pricing for size tier "${sqInKey}" at quantity tier ${qtyTier}`,
|
|
185
|
+
};
|
|
186
|
+
}
|
|
187
|
+
return { perUnitCents: tierData.min, vendorId: findMinDtfVendor(tierData.vendors) };
|
|
188
|
+
}
|
|
189
|
+
/**
|
|
190
|
+
* Look up per-unit decoration cost for DTG.
|
|
191
|
+
* Always uses dark_garment ink mode (conservative pricing).
|
|
192
|
+
* Keyed by "dark_garment" → `{N}_sqin` → quantity tier → min cents.
|
|
193
|
+
*/
|
|
194
|
+
function lookupDtgCost(perPieceCents, referenceQuantities, sqInLevels, height, width, quantity, garmentColorCategory = 'dark') {
|
|
195
|
+
const inkMode = `${garmentColorCategory}_garment`;
|
|
196
|
+
const inkData = perPieceCents[inkMode];
|
|
197
|
+
if (!inkData) {
|
|
198
|
+
return {
|
|
199
|
+
perUnitCents: null,
|
|
200
|
+
warning: `No DTG pricing for ink mode "${inkMode}"`,
|
|
201
|
+
};
|
|
202
|
+
}
|
|
203
|
+
const sqIn = calculateSqInches(height, width);
|
|
204
|
+
const tier = findSqInTier(sqInLevels, sqIn);
|
|
205
|
+
const sqInKey = `${tier}_sqin`;
|
|
206
|
+
const sqInData = inkData[sqInKey];
|
|
207
|
+
if (!sqInData) {
|
|
208
|
+
return {
|
|
209
|
+
perUnitCents: null,
|
|
210
|
+
warning: `No DTG pricing for ink mode "${inkMode}" at size tier "${sqInKey}"`,
|
|
211
|
+
};
|
|
212
|
+
}
|
|
213
|
+
const qtyTier = findQuantityTier(referenceQuantities, quantity);
|
|
214
|
+
const tierData = sqInData[String(qtyTier)];
|
|
215
|
+
if (!tierData) {
|
|
216
|
+
return {
|
|
217
|
+
perUnitCents: null,
|
|
218
|
+
warning: `No DTG pricing for ink mode "${inkMode}" at size tier "${sqInKey}" quantity tier ${qtyTier}`,
|
|
219
|
+
};
|
|
220
|
+
}
|
|
221
|
+
return { perUnitCents: tierData.min, vendorId: findMinVendor(tierData.vendors) };
|
|
222
|
+
}
|
|
223
|
+
/**
|
|
224
|
+
* Main dispatch: look up per-unit decoration cost from vendor pricing data.
|
|
225
|
+
* Returns the min cost in cents, or null with a warning if unavailable.
|
|
226
|
+
*/
|
|
227
|
+
function lookupDecorationCostPerUnit(vendorData, params) {
|
|
228
|
+
const { method, quantity } = params;
|
|
229
|
+
// Screen printing
|
|
230
|
+
if (method === 'screen_printing') {
|
|
231
|
+
const methodData = vendorData.methods.screen_printing;
|
|
232
|
+
if (methodData.status === 'pending') {
|
|
233
|
+
return { perUnitCents: null, warning: 'Screen printing pricing not available in vendor database (status: pending)' };
|
|
234
|
+
}
|
|
235
|
+
if (params.colorCount == null) {
|
|
236
|
+
return { perUnitCents: null, warning: 'color_count is required for screen printing lookup' };
|
|
237
|
+
}
|
|
238
|
+
return lookupScreenPrintCost(methodData.per_piece_cents, methodData.reference_quantities, params.colorCount, quantity);
|
|
239
|
+
}
|
|
240
|
+
// Screen print transfers — uses same pricing structure as screen printing
|
|
241
|
+
if (method === 'screen_print_transfers') {
|
|
242
|
+
const methodData = vendorData.methods.screen_print_transfers;
|
|
243
|
+
if (!methodData || methodData.status === 'pending') {
|
|
244
|
+
// Fall back to screen_printing pricing if transfers don't have their own data
|
|
245
|
+
const spData = vendorData.methods.screen_printing;
|
|
246
|
+
if (spData.status === 'pending') {
|
|
247
|
+
return { perUnitCents: null, warning: 'Screen print transfers pricing not available in vendor database' };
|
|
248
|
+
}
|
|
249
|
+
if (params.colorCount == null) {
|
|
250
|
+
return { perUnitCents: null, warning: 'color_count is required for screen print transfers lookup' };
|
|
251
|
+
}
|
|
252
|
+
const result = lookupScreenPrintCost(spData.per_piece_cents, spData.reference_quantities, params.colorCount, quantity);
|
|
253
|
+
if (result.perUnitCents != null) {
|
|
254
|
+
result.warning = 'Using screen printing pricing as proxy for screen print transfers';
|
|
255
|
+
}
|
|
256
|
+
return result;
|
|
257
|
+
}
|
|
258
|
+
if (params.colorCount == null) {
|
|
259
|
+
return { perUnitCents: null, warning: 'color_count is required for screen print transfers lookup' };
|
|
260
|
+
}
|
|
261
|
+
return lookupScreenPrintCost(methodData.per_piece_cents, methodData.reference_quantities, params.colorCount, quantity);
|
|
262
|
+
}
|
|
263
|
+
// Embroidery
|
|
264
|
+
if (method === 'embroidery') {
|
|
265
|
+
const methodData = vendorData.methods.embroidery;
|
|
266
|
+
if (methodData.status === 'pending') {
|
|
267
|
+
return { perUnitCents: null, warning: 'Embroidery pricing not available in vendor database (status: pending)' };
|
|
268
|
+
}
|
|
269
|
+
if (params.stitchCount == null) {
|
|
270
|
+
return { perUnitCents: null, warning: 'stitch_count is required for embroidery lookup' };
|
|
271
|
+
}
|
|
272
|
+
return lookupEmbroideryCost(methodData.per_piece_cents, methodData.reference_quantities, methodData.stitch_levels, params.stitchCount, quantity);
|
|
273
|
+
}
|
|
274
|
+
// Sublimation
|
|
275
|
+
if (method === 'sublimation') {
|
|
276
|
+
const methodData = vendorData.methods.sublimation;
|
|
277
|
+
if (methodData.status === 'pending') {
|
|
278
|
+
return { perUnitCents: null, warning: 'Sublimation pricing not available in vendor database (status: pending)' };
|
|
279
|
+
}
|
|
280
|
+
return lookupSublimationCost(methodData, params.sublimationProductKey);
|
|
281
|
+
}
|
|
282
|
+
// DTF
|
|
283
|
+
if (method === 'dtf') {
|
|
284
|
+
const methodData = vendorData.methods.dtf;
|
|
285
|
+
if (methodData.status === 'pending') {
|
|
286
|
+
return { perUnitCents: null, warning: 'DTF pricing not available in vendor database. Use manual_decoration_cost_per_unit.' };
|
|
287
|
+
}
|
|
288
|
+
if (params.designHeight == null || params.designWidth == null) {
|
|
289
|
+
return { perUnitCents: null, warning: 'designHeight and designWidth are required for DTF lookup' };
|
|
290
|
+
}
|
|
291
|
+
const dtf = methodData;
|
|
292
|
+
return lookupDtfCost(dtf.per_piece_cents, dtf.reference_quantities, dtf.sqin_levels, params.designHeight, params.designWidth, quantity);
|
|
293
|
+
}
|
|
294
|
+
// DTG
|
|
295
|
+
if (method === 'dtg') {
|
|
296
|
+
const methodData = vendorData.methods.dtg;
|
|
297
|
+
if (methodData.status === 'pending') {
|
|
298
|
+
return { perUnitCents: null, warning: 'DTG pricing not available in vendor database. Use manual_decoration_cost_per_unit.' };
|
|
299
|
+
}
|
|
300
|
+
if (params.designHeight == null || params.designWidth == null) {
|
|
301
|
+
return { perUnitCents: null, warning: 'designHeight and designWidth are required for DTG lookup' };
|
|
302
|
+
}
|
|
303
|
+
const dtg = methodData;
|
|
304
|
+
return lookupDtgCost(dtg.per_piece_cents, dtg.reference_quantities, dtg.sqin_levels, params.designHeight, params.designWidth, quantity, params.garmentColorCategory ?? 'dark');
|
|
305
|
+
}
|
|
306
|
+
return { perUnitCents: null, warning: `Unknown decoration method: ${method}` };
|
|
307
|
+
}
|
|
308
|
+
//# sourceMappingURL=vendor-lookup.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"vendor-lookup.js","sourceRoot":"","sources":["../../src/utils/vendor-lookup.ts"],"names":[],"mappings":";;AAkDA,4CAWC;AAOD,wCAQC;AAkGD,8CAEC;AAOD,oCAQC;AAoGD,kEAwIC;AAhaD;;;GAGG;AACH,SAAS,aAAa,CAAC,OAAgC;IACrD,IAAI,CAAC,OAAO,IAAI,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,SAAS,CAAC;IACpE,IAAI,SAA6B,CAAC;IAClC,IAAI,QAAQ,GAAG,QAAQ,CAAC;IACxB,KAAK,MAAM,CAAC,QAAQ,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC;QACxD,IAAI,KAAK,GAAG,QAAQ,EAAE,CAAC;YACrB,QAAQ,GAAG,KAAK,CAAC;YACjB,SAAS,GAAG,QAAQ,CAAC;QACvB,CAAC;IACH,CAAC;IACD,OAAO,SAAS,CAAC;AACnB,CAAC;AAED;;;GAGG;AACH,SAAS,gBAAgB,CAAC,OAAyC;IACjE,IAAI,CAAC,OAAO,IAAI,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,SAAS,CAAC;IACpE,IAAI,SAA6B,CAAC;IAClC,IAAI,QAAQ,GAAG,QAAQ,CAAC;IACxB,KAAK,MAAM,CAAC,QAAQ,EAAE,MAAM,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC;QACzD,IAAI,MAAM,CAAC,WAAW,GAAG,QAAQ,EAAE,CAAC;YAClC,QAAQ,GAAG,MAAM,CAAC,WAAW,CAAC;YAC9B,SAAS,GAAG,QAAQ,CAAC;QACvB,CAAC;IACH,CAAC;IACD,OAAO,SAAS,CAAC;AACnB,CAAC;AAED;;;;GAIG;AACH,SAAgB,gBAAgB,CAAC,cAAwB,EAAE,cAAsB;IAC/E,MAAM,MAAM,GAAG,CAAC,GAAG,cAAc,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;IACzD,IAAI,IAAI,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC;IACrB,KAAK,MAAM,IAAI,IAAI,MAAM,EAAE,CAAC;QAC1B,IAAI,IAAI,IAAI,cAAc,EAAE,CAAC;YAC3B,IAAI,GAAG,IAAI,CAAC;QACd,CAAC;aAAM,CAAC;YACN,MAAM;QACR,CAAC;IACH,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED;;;;GAIG;AACH,SAAgB,cAAc,CAAC,eAAyB,EAAE,WAAmB;IAC3E,MAAM,MAAM,GAAG,CAAC,GAAG,eAAe,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;IAC1D,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;QAC3B,IAAI,WAAW,IAAI,KAAK,EAAE,CAAC;YACzB,OAAO,KAAK,CAAC;QACf,CAAC;IACH,CAAC;IACD,OAAO,MAAM,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;AACnC,CAAC;AAED;;;GAGG;AACH,SAAS,qBAAqB,CAC5B,aAAwD,EACxD,mBAA6B,EAC7B,UAAkB,EAClB,QAAgB;IAEhB,MAAM,QAAQ,GAAG,GAAG,UAAU,QAAQ,CAAC;IACvC,MAAM,SAAS,GAAG,aAAa,CAAC,QAAQ,CAAC,CAAC;IAC1C,IAAI,CAAC,SAAS,EAAE,CAAC;QACf,MAAM,eAAe,GAAG,MAAM,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAChG,OAAO;YACL,YAAY,EAAE,IAAI;YAClB,OAAO,EAAE,kBAAkB,UAAU,mDAAmD,eAAe,EAAE;SAC1G,CAAC;IACJ,CAAC;IAED,MAAM,OAAO,GAAG,gBAAgB,CAAC,mBAAmB,EAAE,QAAQ,CAAC,CAAC;IAChE,MAAM,QAAQ,GAAG,SAAS,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC;IAC5C,IAAI,CAAC,QAAQ,EAAE,CAAC;QACd,OAAO;YACL,YAAY,EAAE,IAAI;YAClB,OAAO,EAAE,kBAAkB,UAAU,2CAA2C,OAAO,EAAE;SAC1F,CAAC;IACJ,CAAC;IAED,OAAO,EAAE,YAAY,EAAE,QAAQ,CAAC,GAAG,EAAE,QAAQ,EAAE,aAAa,CAAC,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC;AACnF,CAAC;AAED;;;GAGG;AACH,SAAS,oBAAoB,CAC3B,aAAwD,EACxD,mBAA6B,EAC7B,YAAsB,EACtB,WAAmB,EACnB,QAAgB;IAEhB,MAAM,UAAU,GAAG,cAAc,CAAC,YAAY,EAAE,WAAW,CAAC,CAAC;IAC7D,MAAM,SAAS,GAAG,GAAG,UAAU,WAAW,CAAC;IAC3C,MAAM,UAAU,GAAG,aAAa,CAAC,SAAS,CAAC,CAAC;IAC5C,IAAI,CAAC,UAAU,EAAE,CAAC;QAChB,OAAO;YACL,YAAY,EAAE,IAAI;YAClB,OAAO,EAAE,kBAAkB,UAAU,yBAAyB;SAC/D,CAAC;IACJ,CAAC;IAED,MAAM,OAAO,GAAG,gBAAgB,CAAC,mBAAmB,EAAE,QAAQ,CAAC,CAAC;IAChE,MAAM,QAAQ,GAAG,UAAU,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC;IAC7C,IAAI,CAAC,QAAQ,EAAE,CAAC;QACd,OAAO;YACL,YAAY,EAAE,IAAI;YAClB,OAAO,EAAE,kBAAkB,UAAU,uCAAuC,OAAO,EAAE;SACtF,CAAC;IACJ,CAAC;IAED,OAAO,EAAE,YAAY,EAAE,QAAQ,CAAC,GAAG,EAAE,QAAQ,EAAE,aAAa,CAAC,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC;AACnF,CAAC;AAED;;;;GAIG;AACH,SAAS,qBAAqB,CAC5B,UAAwG,EACxG,UAAmB;IAEnB,IAAI,CAAC,UAAU,EAAE,CAAC;QAChB,OAAO;YACL,YAAY,EAAE,IAAI;YAClB,OAAO,EAAE,mHAAmH;SAC7H,CAAC;IACJ,CAAC;IAED,MAAM,OAAO,GAAG,UAAU,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAC;IAChD,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,MAAM,SAAS,GAAG,MAAM,CAAC,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC9D,OAAO;YACL,YAAY,EAAE,IAAI;YAClB,OAAO,EAAE,wBAAwB,UAAU,2BAA2B,SAAS,EAAE;SAClF,CAAC;IACJ,CAAC;IAED,OAAO,EAAE,YAAY,EAAE,OAAO,CAAC,GAAG,EAAE,QAAQ,EAAE,aAAa,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC;AACjF,CAAC;AAED;;GAEG;AACH,SAAgB,iBAAiB,CAAC,MAAc,EAAE,KAAa;IAC7D,OAAO,IAAI,CAAC,IAAI,CAAC,MAAM,GAAG,KAAK,CAAC,CAAC;AACnC,CAAC;AAED;;;;GAIG;AACH,SAAgB,YAAY,CAAC,eAAyB,EAAE,IAAY;IAClE,MAAM,MAAM,GAAG,CAAC,GAAG,eAAe,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;IAC1D,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;QAC3B,IAAI,IAAI,IAAI,KAAK,EAAE,CAAC;YAClB,OAAO,KAAK,CAAC;QACf,CAAC;IACH,CAAC;IACD,OAAO,MAAM,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;AACnC,CAAC;AAED;;;GAGG;AACH,SAAS,aAAa,CACpB,aAA2D,EAC3D,mBAA6B,EAC7B,UAAoB,EACpB,MAAc,EACd,KAAa,EACb,QAAgB;IAEhB,MAAM,IAAI,GAAG,iBAAiB,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;IAC9C,MAAM,IAAI,GAAG,YAAY,CAAC,UAAU,EAAE,IAAI,CAAC,CAAC;IAC5C,MAAM,OAAO,GAAG,GAAG,IAAI,OAAO,CAAC;IAC/B,MAAM,QAAQ,GAAG,aAAa,CAAC,OAAO,CAAC,CAAC;IACxC,IAAI,CAAC,QAAQ,EAAE,CAAC;QACd,OAAO;YACL,YAAY,EAAE,IAAI;YAClB,OAAO,EAAE,iCAAiC,OAAO,GAAG;SACrD,CAAC;IACJ,CAAC;IAED,MAAM,OAAO,GAAG,gBAAgB,CAAC,mBAAmB,EAAE,QAAQ,CAAC,CAAC;IAChE,MAAM,QAAQ,GAAG,QAAQ,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC;IAC3C,IAAI,CAAC,QAAQ,EAAE,CAAC;QACd,OAAO;YACL,YAAY,EAAE,IAAI;YAClB,OAAO,EAAE,iCAAiC,OAAO,sBAAsB,OAAO,EAAE;SACjF,CAAC;IACJ,CAAC;IAED,OAAO,EAAE,YAAY,EAAE,QAAQ,CAAC,GAAG,EAAE,QAAQ,EAAE,gBAAgB,CAAC,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC;AACtF,CAAC;AAED;;;;GAIG;AACH,SAAS,aAAa,CACpB,aAAwE,EACxE,mBAA6B,EAC7B,UAAoB,EACpB,MAAc,EACd,KAAa,EACb,QAAgB,EAChB,uBAAyC,MAAM;IAE/C,MAAM,OAAO,GAAG,GAAG,oBAAoB,UAAU,CAAC;IAClD,MAAM,OAAO,GAAG,aAAa,CAAC,OAAO,CAAC,CAAC;IACvC,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,OAAO;YACL,YAAY,EAAE,IAAI;YAClB,OAAO,EAAE,gCAAgC,OAAO,GAAG;SACpD,CAAC;IACJ,CAAC;IAED,MAAM,IAAI,GAAG,iBAAiB,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;IAC9C,MAAM,IAAI,GAAG,YAAY,CAAC,UAAU,EAAE,IAAI,CAAC,CAAC;IAC5C,MAAM,OAAO,GAAG,GAAG,IAAI,OAAO,CAAC;IAC/B,MAAM,QAAQ,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IAClC,IAAI,CAAC,QAAQ,EAAE,CAAC;QACd,OAAO;YACL,YAAY,EAAE,IAAI;YAClB,OAAO,EAAE,gCAAgC,OAAO,mBAAmB,OAAO,GAAG;SAC9E,CAAC;IACJ,CAAC;IAED,MAAM,OAAO,GAAG,gBAAgB,CAAC,mBAAmB,EAAE,QAAQ,CAAC,CAAC;IAChE,MAAM,QAAQ,GAAG,QAAQ,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC;IAC3C,IAAI,CAAC,QAAQ,EAAE,CAAC;QACd,OAAO;YACL,YAAY,EAAE,IAAI;YAClB,OAAO,EAAE,gCAAgC,OAAO,mBAAmB,OAAO,mBAAmB,OAAO,EAAE;SACvG,CAAC;IACJ,CAAC;IAED,OAAO,EAAE,YAAY,EAAE,QAAQ,CAAC,GAAG,EAAE,QAAQ,EAAE,aAAa,CAAC,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC;AACnF,CAAC;AAeD;;;GAGG;AACH,SAAgB,2BAA2B,CACzC,UAA6B,EAC7B,MAAoB;IAEpB,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,GAAG,MAAM,CAAC;IAEpC,kBAAkB;IAClB,IAAI,MAAM,KAAK,iBAAiB,EAAE,CAAC;QACjC,MAAM,UAAU,GAAG,UAAU,CAAC,OAAO,CAAC,eAAe,CAAC;QACtD,IAAI,UAAU,CAAC,MAAM,KAAK,SAAS,EAAE,CAAC;YACpC,OAAO,EAAE,YAAY,EAAE,IAAI,EAAE,OAAO,EAAE,4EAA4E,EAAE,CAAC;QACvH,CAAC;QACD,IAAI,MAAM,CAAC,UAAU,IAAI,IAAI,EAAE,CAAC;YAC9B,OAAO,EAAE,YAAY,EAAE,IAAI,EAAE,OAAO,EAAE,oDAAoD,EAAE,CAAC;QAC/F,CAAC;QACD,OAAO,qBAAqB,CAC1B,UAAU,CAAC,eAAe,EAC1B,UAAU,CAAC,oBAAoB,EAC/B,MAAM,CAAC,UAAU,EACjB,QAAQ,CACT,CAAC;IACJ,CAAC;IAED,0EAA0E;IAC1E,IAAI,MAAM,KAAK,wBAAwB,EAAE,CAAC;QACxC,MAAM,UAAU,GAAG,UAAU,CAAC,OAAO,CAAC,sBAAsB,CAAC;QAC7D,IAAI,CAAC,UAAU,IAAI,UAAU,CAAC,MAAM,KAAK,SAAS,EAAE,CAAC;YACnD,8EAA8E;YAC9E,MAAM,MAAM,GAAG,UAAU,CAAC,OAAO,CAAC,eAAe,CAAC;YAClD,IAAI,MAAM,CAAC,MAAM,KAAK,SAAS,EAAE,CAAC;gBAChC,OAAO,EAAE,YAAY,EAAE,IAAI,EAAE,OAAO,EAAE,iEAAiE,EAAE,CAAC;YAC5G,CAAC;YACD,IAAI,MAAM,CAAC,UAAU,IAAI,IAAI,EAAE,CAAC;gBAC9B,OAAO,EAAE,YAAY,EAAE,IAAI,EAAE,OAAO,EAAE,2DAA2D,EAAE,CAAC;YACtG,CAAC;YACD,MAAM,MAAM,GAAG,qBAAqB,CAClC,MAAM,CAAC,eAAe,EACtB,MAAM,CAAC,oBAAoB,EAC3B,MAAM,CAAC,UAAU,EACjB,QAAQ,CACT,CAAC;YACF,IAAI,MAAM,CAAC,YAAY,IAAI,IAAI,EAAE,CAAC;gBAChC,MAAM,CAAC,OAAO,GAAG,mEAAmE,CAAC;YACvF,CAAC;YACD,OAAO,MAAM,CAAC;QAChB,CAAC;QACD,IAAI,MAAM,CAAC,UAAU,IAAI,IAAI,EAAE,CAAC;YAC9B,OAAO,EAAE,YAAY,EAAE,IAAI,EAAE,OAAO,EAAE,2DAA2D,EAAE,CAAC;QACtG,CAAC;QACD,OAAO,qBAAqB,CAC1B,UAAU,CAAC,eAAe,EAC1B,UAAU,CAAC,oBAAoB,EAC/B,MAAM,CAAC,UAAU,EACjB,QAAQ,CACT,CAAC;IACJ,CAAC;IAED,aAAa;IACb,IAAI,MAAM,KAAK,YAAY,EAAE,CAAC;QAC5B,MAAM,UAAU,GAAG,UAAU,CAAC,OAAO,CAAC,UAAU,CAAC;QACjD,IAAI,UAAU,CAAC,MAAM,KAAK,SAAS,EAAE,CAAC;YACpC,OAAO,EAAE,YAAY,EAAE,IAAI,EAAE,OAAO,EAAE,uEAAuE,EAAE,CAAC;QAClH,CAAC;QACD,IAAI,MAAM,CAAC,WAAW,IAAI,IAAI,EAAE,CAAC;YAC/B,OAAO,EAAE,YAAY,EAAE,IAAI,EAAE,OAAO,EAAE,gDAAgD,EAAE,CAAC;QAC3F,CAAC;QACD,OAAO,oBAAoB,CACzB,UAAU,CAAC,eAAe,EAC1B,UAAU,CAAC,oBAAoB,EAC/B,UAAU,CAAC,aAAa,EACxB,MAAM,CAAC,WAAW,EAClB,QAAQ,CACT,CAAC;IACJ,CAAC;IAED,cAAc;IACd,IAAI,MAAM,KAAK,aAAa,EAAE,CAAC;QAC7B,MAAM,UAAU,GAAG,UAAU,CAAC,OAAO,CAAC,WAAW,CAAC;QAClD,IAAI,UAAU,CAAC,MAAM,KAAK,SAAS,EAAE,CAAC;YACpC,OAAO,EAAE,YAAY,EAAE,IAAI,EAAE,OAAO,EAAE,wEAAwE,EAAE,CAAC;QACnH,CAAC;QACD,OAAO,qBAAqB,CAAC,UAAU,EAAE,MAAM,CAAC,qBAAqB,CAAC,CAAC;IACzE,CAAC;IAED,MAAM;IACN,IAAI,MAAM,KAAK,KAAK,EAAE,CAAC;QACrB,MAAM,UAAU,GAAG,UAAU,CAAC,OAAO,CAAC,GAAG,CAAC;QAC1C,IAAI,UAAU,CAAC,MAAM,KAAK,SAAS,EAAE,CAAC;YACpC,OAAO,EAAE,YAAY,EAAE,IAAI,EAAE,OAAO,EAAE,oFAAoF,EAAE,CAAC;QAC/H,CAAC;QACD,IAAI,MAAM,CAAC,YAAY,IAAI,IAAI,IAAI,MAAM,CAAC,WAAW,IAAI,IAAI,EAAE,CAAC;YAC9D,OAAO,EAAE,YAAY,EAAE,IAAI,EAAE,OAAO,EAAE,0DAA0D,EAAE,CAAC;QACrG,CAAC;QACD,MAAM,GAAG,GAAG,UAKX,CAAC;QACF,OAAO,aAAa,CAClB,GAAG,CAAC,eAAe,EACnB,GAAG,CAAC,oBAAoB,EACxB,GAAG,CAAC,WAAW,EACf,MAAM,CAAC,YAAY,EACnB,MAAM,CAAC,WAAW,EAClB,QAAQ,CACT,CAAC;IACJ,CAAC;IAED,MAAM;IACN,IAAI,MAAM,KAAK,KAAK,EAAE,CAAC;QACrB,MAAM,UAAU,GAAG,UAAU,CAAC,OAAO,CAAC,GAAG,CAAC;QAC1C,IAAI,UAAU,CAAC,MAAM,KAAK,SAAS,EAAE,CAAC;YACpC,OAAO,EAAE,YAAY,EAAE,IAAI,EAAE,OAAO,EAAE,oFAAoF,EAAE,CAAC;QAC/H,CAAC;QACD,IAAI,MAAM,CAAC,YAAY,IAAI,IAAI,IAAI,MAAM,CAAC,WAAW,IAAI,IAAI,EAAE,CAAC;YAC9D,OAAO,EAAE,YAAY,EAAE,IAAI,EAAE,OAAO,EAAE,0DAA0D,EAAE,CAAC;QACrG,CAAC;QACD,MAAM,GAAG,GAAG,UAKX,CAAC;QACF,OAAO,aAAa,CAClB,GAAG,CAAC,eAAe,EACnB,GAAG,CAAC,oBAAoB,EACxB,GAAG,CAAC,WAAW,EACf,MAAM,CAAC,YAAY,EACnB,MAAM,CAAC,WAAW,EAClB,QAAQ,EACR,MAAM,CAAC,oBAAoB,IAAI,MAAM,CACtC,CAAC;IACJ,CAAC;IAED,OAAO,EAAE,YAAY,EAAE,IAAI,EAAE,OAAO,EAAE,8BAA8B,MAAM,EAAE,EAAE,CAAC;AACjF,CAAC"}
|
package/package.json
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@the-apparel-lab/pricing-engine",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "Pricing engine for The Apparel Lab — calculates customer-facing prices with component-level multipliers",
|
|
5
|
+
"main": "dist/index.js",
|
|
6
|
+
"types": "dist/index.d.ts",
|
|
7
|
+
"files": [
|
|
8
|
+
"dist",
|
|
9
|
+
"config"
|
|
10
|
+
],
|
|
11
|
+
"scripts": {
|
|
12
|
+
"build": "tsc",
|
|
13
|
+
"test": "vitest run",
|
|
14
|
+
"prepare": "npm run build"
|
|
15
|
+
},
|
|
16
|
+
"keywords": [],
|
|
17
|
+
"author": "",
|
|
18
|
+
"license": "ISC",
|
|
19
|
+
"dependencies": {
|
|
20
|
+
"typescript": "^5.9.3",
|
|
21
|
+
"zod": "^4.3.6"
|
|
22
|
+
},
|
|
23
|
+
"devDependencies": {
|
|
24
|
+
"@types/node": "^25.3.5",
|
|
25
|
+
"ts-node": "^10.9.2",
|
|
26
|
+
"vitest": "^4.0.18"
|
|
27
|
+
}
|
|
28
|
+
}
|