@repobit/dex-store-elements 2.0.2 → 2.0.3
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/CHANGELOG.md +7 -0
- package/README.md +15 -14
- package/dist/src/actions/action.attributes.d.ts +6 -5
- package/dist/src/actions/action.attributes.js +8 -6
- package/dist/src/actions/action.attributes.js.map +1 -1
- package/dist/src/contexts/context.scope.d.ts +19 -25
- package/dist/src/contexts/context.scope.js +7 -8
- package/dist/src/contexts/context.scope.js.map +1 -1
- package/dist/src/controllers/controller.action-resolve.d.ts +1 -0
- package/dist/src/controllers/controller.action-resolve.js +14 -0
- package/dist/src/controllers/controller.action-resolve.js.map +1 -1
- package/dist/src/core/actions.d.ts +8 -8
- package/dist/src/core/actions.js +4 -4
- package/dist/src/core/actions.js.map +1 -1
- package/dist/src/core/node.scope.d.ts +23 -28
- package/dist/src/core/node.scope.js +12 -35
- package/dist/src/core/node.scope.js.map +1 -1
- package/dist/src/eta/controller.js +11 -1
- package/dist/src/eta/controller.js.map +1 -1
- package/dist/src/eta/types.d.ts +2 -2
- package/dist/src/eta/types.js.map +1 -1
- package/dist/src/renders/attributes/hide.d.ts +1 -1
- package/dist/src/renders/attributes/hide.js +2 -2
- package/dist/src/renders/attributes/hide.js.map +1 -1
- package/dist/src/renders/context.d.ts +13 -16
- package/dist/src/renders/context.js +22 -12
- package/dist/src/renders/context.js.map +1 -1
- package/package.json +3 -3
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import deepmerge from 'deepmerge';
|
|
1
2
|
export function createRenderContext(scope, compute) {
|
|
2
3
|
return {
|
|
3
4
|
scope,
|
|
@@ -7,12 +8,12 @@ export function createRenderContext(scope, compute) {
|
|
|
7
8
|
compute
|
|
8
9
|
};
|
|
9
10
|
}
|
|
10
|
-
export function toDSLContext(ctx) {
|
|
11
|
-
return buildTemplateDslContext({
|
|
12
|
-
store: ctx.store,
|
|
11
|
+
export async function toDSLContext(ctx) {
|
|
12
|
+
return await buildTemplateDslContext({
|
|
13
13
|
product: ctx.product,
|
|
14
14
|
option: ctx.option,
|
|
15
|
-
state: ctx.compute
|
|
15
|
+
state: ctx.compute,
|
|
16
|
+
derived: ctx.scope?.derived
|
|
16
17
|
});
|
|
17
18
|
}
|
|
18
19
|
/**
|
|
@@ -22,22 +23,32 @@ export function toDSLContext(ctx) {
|
|
|
22
23
|
* Eta template controller (`core/node.scope.ts`) so the two surfaces agree
|
|
23
24
|
* on `it.option.*` / `it.product.*` / `it.state.*` / `it.ctx.*`.
|
|
24
25
|
*/
|
|
25
|
-
export function buildTemplateDslContext(input) {
|
|
26
|
-
const
|
|
26
|
+
export async function buildTemplateDslContext(input) {
|
|
27
|
+
const explicitProduct = input.product ?? undefined;
|
|
28
|
+
const option = input.option ?? undefined;
|
|
29
|
+
const product = explicitProduct ?? option?.getProduct();
|
|
27
30
|
const stateCtx = input.state
|
|
28
31
|
? buildStateContext(input.state)
|
|
29
32
|
: undefined;
|
|
30
|
-
|
|
31
|
-
store: input.store,
|
|
33
|
+
const base = {
|
|
32
34
|
product: product
|
|
33
35
|
? buildProductContext(product)
|
|
34
36
|
: undefined,
|
|
35
|
-
option:
|
|
36
|
-
? buildOptionContext(
|
|
37
|
+
option: option
|
|
38
|
+
? buildOptionContext(option)
|
|
37
39
|
: undefined,
|
|
38
40
|
state: stateCtx,
|
|
39
41
|
ctx: stateCtx
|
|
40
42
|
};
|
|
43
|
+
if (!input.derived) {
|
|
44
|
+
return base;
|
|
45
|
+
}
|
|
46
|
+
const derived = await input.derived({
|
|
47
|
+
product: explicitProduct,
|
|
48
|
+
option,
|
|
49
|
+
state: input.state
|
|
50
|
+
});
|
|
51
|
+
return deepmerge(base, derived ?? {});
|
|
41
52
|
}
|
|
42
53
|
function buildOptionContext(option) {
|
|
43
54
|
return {
|
|
@@ -108,8 +119,7 @@ function buildStateContext(state) {
|
|
|
108
119
|
max: state.discount.monthly.max.fmt
|
|
109
120
|
}
|
|
110
121
|
}
|
|
111
|
-
}
|
|
112
|
-
scenarios: state.scenarios
|
|
122
|
+
}
|
|
113
123
|
};
|
|
114
124
|
}
|
|
115
125
|
export function getDiscountedPrice(option, params) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"context.js","sourceRoot":"","sources":["../../../src/renders/context.ts"],"names":[],"mappings":"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","sourcesContent":["import type { BdComputeResult } from '@/compute/compute.expand.js';\nimport type { BdScope } from '@/contexts/context.scope.js';\nimport type { Product, ProductOption, Store } from '@repobit/dex-store';\n\nexport type RenderContext = Readonly<{\n scope? : BdScope;\n store? : BdScope['store'];\n product?: Product;\n option? : ProductOption;\n compute?: BdComputeResult;\n}>;\n\nexport type DSLContext = Record<string, unknown>;\n\n/**\n * Flattened option context exposed to Eta templates and the hide DSL.\n *\n * Mirrors the v1 `it.option.*` shape: every value is a pre-formatted string\n * (currency-aware), so templates and hide expressions never need to call\n * `option.getPrice()` directly. `links.trial` is the only callable — it\n * resolves a trial URL for a given duration (e.g. `'30 days'`).\n */\nexport type TemplateOptionContext = Readonly<{\n price: {\n full : string;\n discounted : string | undefined;\n fullMonthly : string;\n discountedMonthly: string | undefined;\n };\n discount: {\n percentage : string;\n percentageMonthly: string;\n value : string;\n valueMonthly : string;\n };\n links: {\n buy : string | undefined;\n trial: (trialDuration: string) => string | undefined;\n };\n devices : number;\n subscription: number;\n}>;\n\nexport type TemplateProductContext = Readonly<{\n id : string;\n campaign: string | undefined;\n name : string | undefined;\n}>;\n\nexport type TemplateStateContext = Readonly<{\n price: {\n full: {\n min : string;\n max : string;\n monthly: { min: string; max: string };\n };\n discounted: {\n min : string;\n max : string;\n monthly: { min: string; max: string };\n };\n };\n discount: {\n percentage: {\n min : string;\n max : string;\n monthly: { min: string; max: string };\n };\n value: {\n min : string;\n max : string;\n monthly: { min: string; max: string };\n };\n };\n scenarios: number;\n}>;\n\n/**\n * Shape consumed by Eta templates and the hide DSL.\n *\n * Mirrors the v1 `it.*` layout: `option` / `product` / `state` are flattened\n * DTOs, and `ctx` is an alias of `state`. `derived` is intentionally kept\n * nested (see {@link BdScopedTemplateContext}) — v1 merged derived into the\n * root via `deepmerge`; v2 exposes it explicitly so consumers can tell\n * user-provided values apart from store-provided ones.\n */\nexport type TemplateDslContext = Readonly<{\n store : Store | undefined;\n product: TemplateProductContext | undefined;\n option : TemplateOptionContext | undefined;\n state : TemplateStateContext | undefined;\n ctx : TemplateStateContext | undefined;\n}>;\n\nexport function createRenderContext(\n scope: BdScope | undefined,\n compute: BdComputeResult | undefined\n): RenderContext {\n return {\n scope,\n store : scope?.store,\n product: scope?.product ?? scope?.option?.getProduct(),\n option : scope?.option,\n compute\n };\n}\n\nexport function toDSLContext(\n ctx: RenderContext\n): DSLContext {\n return buildTemplateDslContext({\n store : ctx.store,\n product: ctx.product,\n option : ctx.option,\n state : ctx.compute\n });\n}\n\n/**\n * Build the flattened, v1-shaped DSL context.\n *\n * Used by both the hide DSL compiler (`renders/attributes/hide.ts`) and the\n * Eta template controller (`core/node.scope.ts`) so the two surfaces agree\n * on `it.option.*` / `it.product.*` / `it.state.*` / `it.ctx.*`.\n */\nexport function buildTemplateDslContext(input: {\n store : Store | undefined;\n product: Product | undefined;\n option : ProductOption | undefined;\n state : BdComputeResult | undefined;\n}): TemplateDslContext {\n const product = input.product ?? input.option?.getProduct();\n const stateCtx = input.state\n ? buildStateContext(input.state)\n : undefined;\n\n return {\n store : input.store,\n product: product\n ? buildProductContext(product)\n : undefined,\n option: input.option\n ? buildOptionContext(input.option)\n : undefined,\n state: stateCtx,\n ctx : stateCtx\n };\n}\n\nfunction buildOptionContext(\n option: ProductOption\n): TemplateOptionContext {\n return {\n price: {\n full : option.getPrice({ currency: true }),\n discounted : getDiscountedPrice(option),\n fullMonthly: option.getPrice({\n monthly : true,\n currency: true\n }),\n discountedMonthly: getDiscountedPrice(\n option,\n { monthly: true }\n )\n },\n discount: {\n percentage: getDiscountString(\n option,\n { percentage: true, monthly: false }\n ),\n percentageMonthly: getDiscountString(\n option,\n { percentage: true, monthly: true }\n ),\n value: getDiscountString(\n option,\n { percentage: false, monthly: false }\n ),\n valueMonthly: getDiscountString(\n option,\n { percentage: false, monthly: true }\n )\n },\n links: {\n buy : getBuyLink(option),\n trial: (trialDuration: string) =>\n option.getTrialLink(trialDuration)\n },\n devices : option.getDevices(),\n subscription: option.getSubscription()\n };\n}\n\nfunction buildProductContext(\n product: Product\n): TemplateProductContext {\n return {\n id : product.getId(),\n campaign: product.getCampaign(),\n name : getProductName(product)\n };\n}\n\nfunction buildStateContext(\n state: BdComputeResult\n): TemplateStateContext {\n return {\n price: {\n full: {\n min : state.price.min.fmt,\n max : state.price.max.fmt,\n monthly: {\n min: state.price.monthly.min.fmt,\n max: state.price.monthly.max.fmt\n }\n },\n discounted: {\n min : state.discountedPrice.min.fmt,\n max : state.discountedPrice.max.fmt,\n monthly: {\n min: state.discountedPrice.monthly.min.fmt,\n max: state.discountedPrice.monthly.max.fmt\n }\n }\n },\n discount: {\n percentage: {\n min : state.discount.percentage.min.fmt,\n max : state.discount.percentage.max.fmt,\n monthly: {\n min: state.discount.percentage.monthly.min.fmt,\n max: state.discount.percentage.monthly.max.fmt\n }\n },\n value: {\n min : state.discount.min.fmt,\n max : state.discount.max.fmt,\n monthly: {\n min: state.discount.monthly.min.fmt,\n max: state.discount.monthly.max.fmt\n }\n }\n },\n scenarios: state.scenarios\n };\n}\n\nexport function getDiscountedPrice(\n option: ProductOption,\n params?: {\n monthly?: boolean;\n }\n): string | undefined {\n const maybe =\n option as ProductOption & {\n getDiscountedPrice?: (\n params?: {\n monthly? : boolean;\n currency?: boolean;\n }\n ) => string | number | undefined;\n };\n\n const value: unknown =\n maybe.getDiscountedPrice?.({\n ...params,\n currency: true\n });\n\n return stringifyPresentValue(value);\n}\n\nexport function getDiscount(\n option: ProductOption,\n params?: {\n monthly? : boolean;\n percentage?: boolean;\n symbol? : boolean;\n }\n): string | undefined {\n const maybe =\n option as ProductOption & {\n getDiscount?: (\n params?: {\n monthly? : boolean;\n percentage?: boolean;\n symbol? : boolean;\n }\n ) => string | number | undefined;\n };\n\n const value: unknown =\n maybe.getDiscount?.(params);\n\n return stringifyPresentValue(value);\n}\n\nfunction getDiscountString(\n option: ProductOption,\n params: {\n percentage: boolean;\n monthly : boolean;\n }\n): string {\n return getDiscount(\n option,\n { ...params, symbol: true }\n ) ?? '';\n}\n\nfunction getBuyLink(\n option: ProductOption\n): string | undefined {\n const maybe =\n option as ProductOption & {\n getBuyLink?: () => string | undefined;\n };\n\n return maybe.getBuyLink?.();\n}\n\nfunction stringifyPresentValue(\n value: unknown\n): string | undefined {\n if (\n value === null ||\n value === undefined ||\n (\n typeof value === 'number' &&\n !Number.isFinite(value)\n )\n ) {\n return undefined;\n }\n\n return String(value);\n}\n\nexport function getProductName(\n product: Product\n): string | undefined {\n const maybe =\n product as Product & {\n getName?: () => string | undefined;\n };\n\n return maybe.getName?.();\n}\n"]}
|
|
1
|
+
{"version":3,"file":"context.js","sourceRoot":"","sources":["../../../src/renders/context.ts"],"names":[],"mappings":"AAMA,OAAO,SAAS,MAAM,WAAW,CAAC;AAyFlC,MAAM,UAAU,mBAAmB,CACjC,KAA0B,EAC1B,OAAoC;IAEpC,OAAO;QACL,KAAK;QACL,KAAK,EAAI,KAAK,EAAE,KAAK;QACrB,OAAO,EAAE,KAAK,EAAE,OAAO,IAAI,KAAK,EAAE,MAAM,EAAE,UAAU,EAAE;QACtD,MAAM,EAAG,KAAK,EAAE,MAAM;QACtB,OAAO;KACR,CAAC;AACJ,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,YAAY,CAChC,GAAkB;IAElB,OAAO,MAAM,uBAAuB,CAAC;QACnC,OAAO,EAAE,GAAG,CAAC,OAAO;QACpB,MAAM,EAAG,GAAG,CAAC,MAAM;QACnB,KAAK,EAAI,GAAG,CAAC,OAAO;QACpB,OAAO,EAAE,GAAG,CAAC,KAAK,EAAE,OAAO;KAC5B,CAAC,CAAC;AACL,CAAC;AAED;;;;;;GAMG;AACH,MAAM,CAAC,KAAK,UAAU,uBAAuB,CAAC,KAK7C;IACC,MAAM,eAAe,GAAG,KAAK,CAAC,OAAO,IAAI,SAAS,CAAC;IACnD,MAAM,MAAM,GAAG,KAAK,CAAC,MAAM,IAAI,SAAS,CAAC;IACzC,MAAM,OAAO,GAAG,eAAe,IAAI,MAAM,EAAE,UAAU,EAAE,CAAC;IACxD,MAAM,QAAQ,GAAG,KAAK,CAAC,KAAK;QAC1B,CAAC,CAAC,iBAAiB,CAAC,KAAK,CAAC,KAAK,CAAC;QAChC,CAAC,CAAC,SAAS,CAAC;IAEd,MAAM,IAAI,GAAuB;QAC/B,OAAO,EAAE,OAAO;YACd,CAAC,CAAC,mBAAmB,CAAC,OAAO,CAAC;YAC9B,CAAC,CAAC,SAAS;QACb,MAAM,EAAE,MAAM;YACZ,CAAC,CAAC,kBAAkB,CAAC,MAAM,CAAC;YAC5B,CAAC,CAAC,SAAS;QACb,KAAK,EAAE,QAAQ;QACf,GAAG,EAAI,QAAQ;KAChB,CAAC;IAEF,IAAI,CAAC,KAAK,CAAC,OAAO,EAAE,CAAC;QACnB,OAAO,IAAI,CAAC;IACd,CAAC;IAED,MAAM,OAAO,GAAG,MAAM,KAAK,CAAC,OAAO,CAAC;QAClC,OAAO,EAAE,eAAe;QACxB,MAAM;QACN,KAAK,EAAI,KAAK,CAAC,KAAK;KACrB,CAAC,CAAC;IAEH,OAAO,SAAS,CACd,IAAI,EACJ,OAAO,IAAI,EAAE,CACQ,CAAC;AAC1B,CAAC;AAED,SAAS,kBAAkB,CACzB,MAAqB;IAErB,OAAO;QACL,KAAK,EAAE;YACL,IAAI,EAAS,MAAM,CAAC,QAAQ,CAAC,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC;YAChD,UAAU,EAAG,kBAAkB,CAAC,MAAM,CAAC;YACvC,WAAW,EAAE,MAAM,CAAC,QAAQ,CAAC;gBAC3B,OAAO,EAAG,IAAI;gBACd,QAAQ,EAAE,IAAI;aACf,CAAC;YACF,iBAAiB,EAAE,kBAAkB,CACnC,MAAM,EACN,EAAE,OAAO,EAAE,IAAI,EAAE,CAClB;SACF;QACD,QAAQ,EAAE;YACR,UAAU,EAAE,iBAAiB,CAC3B,MAAM,EACN,EAAE,UAAU,EAAE,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,CACrC;YACD,iBAAiB,EAAE,iBAAiB,CAClC,MAAM,EACN,EAAE,UAAU,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,CACpC;YACD,KAAK,EAAE,iBAAiB,CACtB,MAAM,EACN,EAAE,UAAU,EAAE,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,CACtC;YACD,YAAY,EAAE,iBAAiB,CAC7B,MAAM,EACN,EAAE,UAAU,EAAE,KAAK,EAAE,OAAO,EAAE,IAAI,EAAE,CACrC;SACF;QACD,KAAK,EAAE;YACL,GAAG,EAAI,UAAU,CAAC,MAAM,CAAC;YACzB,KAAK,EAAE,CAAC,aAAqB,EAAE,EAAE,CAC/B,MAAM,CAAC,YAAY,CAAC,aAAa,CAAC;SACrC;QACD,OAAO,EAAO,MAAM,CAAC,UAAU,EAAE;QACjC,YAAY,EAAE,MAAM,CAAC,eAAe,EAAE;KACvC,CAAC;AACJ,CAAC;AAED,SAAS,mBAAmB,CAC1B,OAAgB;IAEhB,OAAO;QACL,EAAE,EAAQ,OAAO,CAAC,KAAK,EAAE;QACzB,QAAQ,EAAE,OAAO,CAAC,WAAW,EAAE;QAC/B,IAAI,EAAM,cAAc,CAAC,OAAO,CAAC;KAClC,CAAC;AACJ,CAAC;AAED,SAAS,iBAAiB,CACxB,KAAsB;IAEtB,OAAO;QACL,KAAK,EAAE;YACL,IAAI,EAAE;gBACJ,GAAG,EAAM,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG;gBAC5B,GAAG,EAAM,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG;gBAC5B,OAAO,EAAE;oBACP,GAAG,EAAE,KAAK,CAAC,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG;oBAChC,GAAG,EAAE,KAAK,CAAC,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG;iBACjC;aACF;YACD,UAAU,EAAE;gBACV,GAAG,EAAM,KAAK,CAAC,eAAe,CAAC,GAAG,CAAC,GAAG;gBACtC,GAAG,EAAM,KAAK,CAAC,eAAe,CAAC,GAAG,CAAC,GAAG;gBACtC,OAAO,EAAE;oBACP,GAAG,EAAE,KAAK,CAAC,eAAe,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG;oBAC1C,GAAG,EAAE,KAAK,CAAC,eAAe,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG;iBAC3C;aACF;SACF;QACD,QAAQ,EAAE;YACR,UAAU,EAAE;gBACV,GAAG,EAAM,KAAK,CAAC,QAAQ,CAAC,UAAU,CAAC,GAAG,CAAC,GAAG;gBAC1C,GAAG,EAAM,KAAK,CAAC,QAAQ,CAAC,UAAU,CAAC,GAAG,CAAC,GAAG;gBAC1C,OAAO,EAAE;oBACP,GAAG,EAAE,KAAK,CAAC,QAAQ,CAAC,UAAU,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG;oBAC9C,GAAG,EAAE,KAAK,CAAC,QAAQ,CAAC,UAAU,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG;iBAC/C;aACF;YACD,KAAK,EAAE;gBACL,GAAG,EAAM,KAAK,CAAC,QAAQ,CAAC,GAAG,CAAC,GAAG;gBAC/B,GAAG,EAAM,KAAK,CAAC,QAAQ,CAAC,GAAG,CAAC,GAAG;gBAC/B,OAAO,EAAE;oBACP,GAAG,EAAE,KAAK,CAAC,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG;oBACnC,GAAG,EAAE,KAAK,CAAC,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG;iBACpC;aACF;SACF;KACF,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,kBAAkB,CAChC,MAAqB,EACrB,MAEC;IAED,MAAM,KAAK,GACT,MAOC,CAAC;IAEJ,MAAM,KAAK,GACT,KAAK,CAAC,kBAAkB,EAAE,CAAC;QACzB,GAAG,MAAM;QACT,QAAQ,EAAE,IAAI;KACf,CAAC,CAAC;IAEL,OAAO,qBAAqB,CAAC,KAAK,CAAC,CAAC;AACtC,CAAC;AAED,MAAM,UAAU,WAAW,CACzB,MAAqB,EACrB,MAIC;IAED,MAAM,KAAK,GACT,MAQC,CAAC;IAEJ,MAAM,KAAK,GACT,KAAK,CAAC,WAAW,EAAE,CAAC,MAAM,CAAC,CAAC;IAE9B,OAAO,qBAAqB,CAAC,KAAK,CAAC,CAAC;AACtC,CAAC;AAED,SAAS,iBAAiB,CACxB,MAAqB,EACrB,MAGC;IAED,OAAO,WAAW,CAChB,MAAM,EACN,EAAE,GAAG,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,CAC5B,IAAI,EAAE,CAAC;AACV,CAAC;AAED,SAAS,UAAU,CACjB,MAAqB;IAErB,MAAM,KAAK,GACT,MAEC,CAAC;IAEJ,OAAO,KAAK,CAAC,UAAU,EAAE,EAAE,CAAC;AAC9B,CAAC;AAED,SAAS,qBAAqB,CAC5B,KAAc;IAEd,IACE,KAAK,KAAK,IAAI;QACd,KAAK,KAAK,SAAS;QACnB,CACE,OAAO,KAAK,KAAK,QAAQ;YACzB,CAAC,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,CACxB,EACD,CAAC;QACD,OAAO,SAAS,CAAC;IACnB,CAAC;IAED,OAAO,MAAM,CAAC,KAAK,CAAC,CAAC;AACvB,CAAC;AAED,MAAM,UAAU,cAAc,CAC5B,OAAgB;IAEhB,MAAM,KAAK,GACT,OAEC,CAAC;IAEJ,OAAO,KAAK,CAAC,OAAO,EAAE,EAAE,CAAC;AAC3B,CAAC","sourcesContent":["import type { BdComputeResult } from '@/compute/compute.expand.js';\nimport {\n type BdScope,\n type BdScopeDeriveFn\n} from '@/contexts/context.scope.js';\nimport type { Product, ProductOption } from '@repobit/dex-store';\nimport deepmerge from 'deepmerge';\n\nexport type RenderContext = Readonly<{\n scope? : BdScope;\n store? : BdScope['store'];\n product?: Product;\n option? : ProductOption;\n compute?: BdComputeResult;\n}>;\n\nexport type DSLContext = Record<string, unknown>;\n\n/**\n * Flattened option context exposed to Eta templates and the hide DSL.\n *\n * Mirrors the v1 `it.option.*` shape: every value is a pre-formatted string\n * (currency-aware), so templates and hide expressions never need to call\n * `option.getPrice()` directly. `links.trial` is the only callable — it\n * resolves a trial URL for a given duration (e.g. `'30 days'`).\n */\nexport type TemplateOptionContext = Readonly<{\n price: {\n full : string;\n discounted : string | undefined;\n fullMonthly : string;\n discountedMonthly: string | undefined;\n };\n discount: {\n percentage : string;\n percentageMonthly: string;\n value : string;\n valueMonthly : string;\n };\n links: {\n buy : string | undefined;\n trial: (trialDuration: string) => string | undefined;\n };\n devices : number;\n subscription: number;\n}>;\n\nexport type TemplateProductContext = Readonly<{\n id : string;\n campaign: string | undefined;\n name : string | undefined;\n}>;\n\nexport type TemplateStateContext = Readonly<{\n price: {\n full: {\n min : string;\n max : string;\n monthly: { min: string; max: string };\n };\n discounted: {\n min : string;\n max : string;\n monthly: { min: string; max: string };\n };\n };\n discount: {\n percentage: {\n min : string;\n max : string;\n monthly: { min: string; max: string };\n };\n value: {\n min : string;\n max : string;\n monthly: { min: string; max: string };\n };\n };\n}>;\n\n/**\n * Shape consumed by Eta templates and the hide DSL.\n *\n * Mirrors the v1 `it.*` layout. The base surface contains only\n * `option`, `product`, `state`, and the `ctx` alias. User-derived values\n * are deep-merged into this object at the root; the raw store and the full\n * internal scope are intentionally not exposed.\n */\nexport type TemplateDslContext = Readonly<Record<string, unknown> & {\n product: TemplateProductContext | undefined;\n option : TemplateOptionContext | undefined;\n state : TemplateStateContext | undefined;\n ctx : TemplateStateContext | undefined;\n}>;\n\nexport function createRenderContext(\n scope: BdScope | undefined,\n compute: BdComputeResult | undefined\n): RenderContext {\n return {\n scope,\n store : scope?.store,\n product: scope?.product ?? scope?.option?.getProduct(),\n option : scope?.option,\n compute\n };\n}\n\nexport async function toDSLContext(\n ctx: RenderContext\n): Promise<DSLContext> {\n return await buildTemplateDslContext({\n product: ctx.product,\n option : ctx.option,\n state : ctx.compute,\n derived: ctx.scope?.derived\n });\n}\n\n/**\n * Build the flattened, v1-shaped DSL context.\n *\n * Used by both the hide DSL compiler (`renders/attributes/hide.ts`) and the\n * Eta template controller (`core/node.scope.ts`) so the two surfaces agree\n * on `it.option.*` / `it.product.*` / `it.state.*` / `it.ctx.*`.\n */\nexport async function buildTemplateDslContext(input: {\n product?: Product | null;\n option? : ProductOption | null;\n state? : BdComputeResult;\n derived?: BdScopeDeriveFn;\n}): Promise<TemplateDslContext> {\n const explicitProduct = input.product ?? undefined;\n const option = input.option ?? undefined;\n const product = explicitProduct ?? option?.getProduct();\n const stateCtx = input.state\n ? buildStateContext(input.state)\n : undefined;\n\n const base: TemplateDslContext = {\n product: product\n ? buildProductContext(product)\n : undefined,\n option: option\n ? buildOptionContext(option)\n : undefined,\n state: stateCtx,\n ctx : stateCtx\n };\n\n if (!input.derived) {\n return base;\n }\n\n const derived = await input.derived({\n product: explicitProduct,\n option,\n state : input.state\n });\n\n return deepmerge(\n base,\n derived ?? {}\n ) as TemplateDslContext;\n}\n\nfunction buildOptionContext(\n option: ProductOption\n): TemplateOptionContext {\n return {\n price: {\n full : option.getPrice({ currency: true }),\n discounted : getDiscountedPrice(option),\n fullMonthly: option.getPrice({\n monthly : true,\n currency: true\n }),\n discountedMonthly: getDiscountedPrice(\n option,\n { monthly: true }\n )\n },\n discount: {\n percentage: getDiscountString(\n option,\n { percentage: true, monthly: false }\n ),\n percentageMonthly: getDiscountString(\n option,\n { percentage: true, monthly: true }\n ),\n value: getDiscountString(\n option,\n { percentage: false, monthly: false }\n ),\n valueMonthly: getDiscountString(\n option,\n { percentage: false, monthly: true }\n )\n },\n links: {\n buy : getBuyLink(option),\n trial: (trialDuration: string) =>\n option.getTrialLink(trialDuration)\n },\n devices : option.getDevices(),\n subscription: option.getSubscription()\n };\n}\n\nfunction buildProductContext(\n product: Product\n): TemplateProductContext {\n return {\n id : product.getId(),\n campaign: product.getCampaign(),\n name : getProductName(product)\n };\n}\n\nfunction buildStateContext(\n state: BdComputeResult\n): TemplateStateContext {\n return {\n price: {\n full: {\n min : state.price.min.fmt,\n max : state.price.max.fmt,\n monthly: {\n min: state.price.monthly.min.fmt,\n max: state.price.monthly.max.fmt\n }\n },\n discounted: {\n min : state.discountedPrice.min.fmt,\n max : state.discountedPrice.max.fmt,\n monthly: {\n min: state.discountedPrice.monthly.min.fmt,\n max: state.discountedPrice.monthly.max.fmt\n }\n }\n },\n discount: {\n percentage: {\n min : state.discount.percentage.min.fmt,\n max : state.discount.percentage.max.fmt,\n monthly: {\n min: state.discount.percentage.monthly.min.fmt,\n max: state.discount.percentage.monthly.max.fmt\n }\n },\n value: {\n min : state.discount.min.fmt,\n max : state.discount.max.fmt,\n monthly: {\n min: state.discount.monthly.min.fmt,\n max: state.discount.monthly.max.fmt\n }\n }\n }\n };\n}\n\nexport function getDiscountedPrice(\n option: ProductOption,\n params?: {\n monthly?: boolean;\n }\n): string | undefined {\n const maybe =\n option as ProductOption & {\n getDiscountedPrice?: (\n params?: {\n monthly? : boolean;\n currency?: boolean;\n }\n ) => string | number | undefined;\n };\n\n const value: unknown =\n maybe.getDiscountedPrice?.({\n ...params,\n currency: true\n });\n\n return stringifyPresentValue(value);\n}\n\nexport function getDiscount(\n option: ProductOption,\n params?: {\n monthly? : boolean;\n percentage?: boolean;\n symbol? : boolean;\n }\n): string | undefined {\n const maybe =\n option as ProductOption & {\n getDiscount?: (\n params?: {\n monthly? : boolean;\n percentage?: boolean;\n symbol? : boolean;\n }\n ) => string | number | undefined;\n };\n\n const value: unknown =\n maybe.getDiscount?.(params);\n\n return stringifyPresentValue(value);\n}\n\nfunction getDiscountString(\n option: ProductOption,\n params: {\n percentage: boolean;\n monthly : boolean;\n }\n): string {\n return getDiscount(\n option,\n { ...params, symbol: true }\n ) ?? '';\n}\n\nfunction getBuyLink(\n option: ProductOption\n): string | undefined {\n const maybe =\n option as ProductOption & {\n getBuyLink?: () => string | undefined;\n };\n\n return maybe.getBuyLink?.();\n}\n\nfunction stringifyPresentValue(\n value: unknown\n): string | undefined {\n if (\n value === null ||\n value === undefined ||\n (\n typeof value === 'number' &&\n !Number.isFinite(value)\n )\n ) {\n return undefined;\n }\n\n return String(value);\n}\n\nexport function getProductName(\n product: Product\n): string | undefined {\n const maybe =\n product as Product & {\n getName?: () => string | undefined;\n };\n\n return maybe.getName?.();\n}\n"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@repobit/dex-store-elements",
|
|
3
|
-
"version": "2.0.
|
|
3
|
+
"version": "2.0.3",
|
|
4
4
|
"description": "HTML elements layer for pricings",
|
|
5
5
|
"author": "Buga Adrian Alexandru <abuga@bitdefender.com>",
|
|
6
6
|
"homepage": "https://github.com/bitdefender/dex-core#readme",
|
|
@@ -52,7 +52,7 @@
|
|
|
52
52
|
"dependencies": {
|
|
53
53
|
"@lit/context": "^1.1.6",
|
|
54
54
|
"@lit/task": "^1.0.3",
|
|
55
|
-
"@repobit/dex-store": "1.5.
|
|
55
|
+
"@repobit/dex-store": "1.5.7",
|
|
56
56
|
"eta": "^4.5.1"
|
|
57
57
|
},
|
|
58
58
|
"contributes": {
|
|
@@ -62,5 +62,5 @@
|
|
|
62
62
|
]
|
|
63
63
|
}
|
|
64
64
|
},
|
|
65
|
-
"gitHead": "
|
|
65
|
+
"gitHead": "0e4f683459a5f4b8cd86aecf515bd160be184cf7"
|
|
66
66
|
}
|