pricing-renderer 0.1.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.
Files changed (85) hide show
  1. package/CHANGELOG.md +21 -0
  2. package/LICENSE +21 -0
  3. package/README.md +419 -0
  4. package/THIRD_PARTY_NOTICES.md +10 -0
  5. package/custom-elements.json +122 -0
  6. package/dist/core/config.d.ts +6 -0
  7. package/dist/core/config.d.ts.map +1 -0
  8. package/dist/core/config.js +62 -0
  9. package/dist/core/config.js.map +1 -0
  10. package/dist/core/expression.d.ts +4 -0
  11. package/dist/core/expression.d.ts.map +1 -0
  12. package/dist/core/expression.js +583 -0
  13. package/dist/core/expression.js.map +1 -0
  14. package/dist/core/i18n.d.ts +10 -0
  15. package/dist/core/i18n.d.ts.map +1 -0
  16. package/dist/core/i18n.js +207 -0
  17. package/dist/core/i18n.js.map +1 -0
  18. package/dist/core/index.d.ts +9 -0
  19. package/dist/core/index.d.ts.map +1 -0
  20. package/dist/core/index.js +8 -0
  21. package/dist/core/index.js.map +1 -0
  22. package/dist/core/normalize.d.ts +4 -0
  23. package/dist/core/normalize.d.ts.map +1 -0
  24. package/dist/core/normalize.js +301 -0
  25. package/dist/core/normalize.js.map +1 -0
  26. package/dist/core/resolve.d.ts +6 -0
  27. package/dist/core/resolve.d.ts.map +1 -0
  28. package/dist/core/resolve.js +123 -0
  29. package/dist/core/resolve.js.map +1 -0
  30. package/dist/core/types.d.ts +308 -0
  31. package/dist/core/types.d.ts.map +1 -0
  32. package/dist/core/types.js +2 -0
  33. package/dist/core/types.js.map +1 -0
  34. package/dist/core/utils.d.ts +16 -0
  35. package/dist/core/utils.d.ts.map +1 -0
  36. package/dist/core/utils.js +125 -0
  37. package/dist/core/utils.js.map +1 -0
  38. package/dist/core/view-model.d.ts +9 -0
  39. package/dist/core/view-model.d.ts.map +1 -0
  40. package/dist/core/view-model.js +427 -0
  41. package/dist/core/view-model.js.map +1 -0
  42. package/dist/element/define.d.ts +6 -0
  43. package/dist/element/define.d.ts.map +1 -0
  44. package/dist/element/define.js +20 -0
  45. package/dist/element/define.js.map +1 -0
  46. package/dist/element/events.d.ts +31 -0
  47. package/dist/element/events.d.ts.map +1 -0
  48. package/dist/element/events.js +2 -0
  49. package/dist/element/events.js.map +1 -0
  50. package/dist/element/index.d.ts +8 -0
  51. package/dist/element/index.d.ts.map +1 -0
  52. package/dist/element/index.js +2 -0
  53. package/dist/element/index.js.map +1 -0
  54. package/dist/element/pricing-renderer-element.d.ts +152 -0
  55. package/dist/element/pricing-renderer-element.d.ts.map +1 -0
  56. package/dist/element/pricing-renderer-element.js +598 -0
  57. package/dist/element/pricing-renderer-element.js.map +1 -0
  58. package/dist/element/renderers.d.ts +43 -0
  59. package/dist/element/renderers.d.ts.map +1 -0
  60. package/dist/element/renderers.js +866 -0
  61. package/dist/element/renderers.js.map +1 -0
  62. package/dist/react/index.d.ts +55 -0
  63. package/dist/react/index.d.ts.map +1 -0
  64. package/dist/react/index.js +23 -0
  65. package/dist/react/index.js.map +1 -0
  66. package/dist/styles/base.css +1110 -0
  67. package/dist/styles/styles.css +2 -0
  68. package/dist/styles/theme.css +84 -0
  69. package/dist/yaml/index.d.ts +4 -0
  70. package/dist/yaml/index.d.ts.map +1 -0
  71. package/dist/yaml/index.js +3 -0
  72. package/dist/yaml/index.js.map +1 -0
  73. package/dist/yaml/load.d.ts +3 -0
  74. package/dist/yaml/load.d.ts.map +1 -0
  75. package/dist/yaml/load.js +97 -0
  76. package/dist/yaml/load.js.map +1 -0
  77. package/dist/yaml/parser.d.ts +4 -0
  78. package/dist/yaml/parser.d.ts.map +1 -0
  79. package/dist/yaml/parser.js +80 -0
  80. package/dist/yaml/parser.js.map +1 -0
  81. package/dist/yaml/types.d.ts +27 -0
  82. package/dist/yaml/types.d.ts.map +1 -0
  83. package/dist/yaml/types.js +2 -0
  84. package/dist/yaml/types.js.map +1 -0
  85. package/package.json +132 -0
package/CHANGELOG.md ADDED
@@ -0,0 +1,21 @@
1
+ # Changelog
2
+
3
+ ## [0.1.0] - 2026-07-29
4
+
5
+ - Initial public npm release of the DOM-free TypeScript core, light-DOM Web
6
+ Component, and React 18/19 adapter.
7
+ - Complete Pricing2Yaml 3.1 normalization, best-effort 3.x compatibility,
8
+ bounded remote loading, and safe AST-based expression evaluation.
9
+ - Responsive commercial and catalog experiences with selectable plan/add-on
10
+ cards, billing, editable variables, constrained quantities, dependency and
11
+ exclusion confirmation, partial totals, and quote pricing.
12
+ - Typed feature and usage-limit highlights with manual, automatic, and hybrid
13
+ modes; verified “Everything in …, plus” inheritance; and configurable plan
14
+ badges.
15
+ - Project, YAML, and per-instance presentation configuration; English and
16
+ Spanish catalogs; accessible light/dark/forced-color themes; RTL; reduced
17
+ motion; CSS tokens; and stable `data-pr-part` hooks.
18
+ - Public documentation, Vanilla/React/Next examples, visual baselines, and
19
+ GitHub Release CD with npm provenance.
20
+
21
+ [0.1.0]: https://github.com/javiercavlop/pricing-renderer/releases/tag/v0.1.0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Francisco Javier Cavero
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,419 @@
1
+ # Pricing Renderer
2
+
3
+ [![CI](https://github.com/javiercavlop/pricing-renderer/actions/workflows/ci.yml/badge.svg)](https://github.com/javiercavlop/pricing-renderer/actions/workflows/ci.yml)
4
+ [![npm release CD](https://github.com/javiercavlop/pricing-renderer/actions/workflows/release.yml/badge.svg)](https://github.com/javiercavlop/pricing-renderer/actions/workflows/release.yml)
5
+ [![npm version](https://img.shields.io/npm/v/pricing-renderer.svg?logo=npm)](https://www.npmjs.com/package/pricing-renderer)
6
+ [![License: MIT](https://img.shields.io/badge/license-MIT-5e51e8.svg)](./LICENSE)
7
+ [![Pricing2Yaml 3.1](https://img.shields.io/badge/Pricing2Yaml-3.1-0c9b6b.svg)](./docs/pricing2yaml-compatibility.md)
8
+
9
+ Turn a Pricing2Yaml document into an elegant, responsive, interactive pricing
10
+ experience. Use the complete light-DOM Web Component, its React 18/19 adapter,
11
+ or the DOM-free TypeScript core to build a product-specific UI.
12
+
13
+ ![Pricing Renderer interactive plans](docs/assets/demo-desktop-light.png)
14
+
15
+ The library is distributed as the public
16
+ [`pricing-renderer`](https://www.npmjs.com/package/pricing-renderer) package.
17
+ Source, issues, release notes, and immutable version tags remain public in
18
+ [`javiercavlop/pricing-renderer`](https://github.com/javiercavlop/pricing-renderer).
19
+
20
+ ## Why it exists
21
+
22
+ - Complete Pricing2Yaml 3.1 normalization and best-effort compatibility for
23
+ other 3.x revisions.
24
+ - Reactive formulas parsed into a restricted AST—never `eval` or `Function`.
25
+ - Variables, billing periods, plan comparison, partial totals, quote prices,
26
+ compatible add-ons, dependency/exclusion confirmation, and constrained
27
+ quantities.
28
+ - Commercial and catalog modes with container-responsive layouts from 320 px.
29
+ - Accessible semantic HTML, keyboard flows, dark mode, forced colors, RTL, zoom,
30
+ and reduced motion.
31
+ - CSS variables and stable `data-pr-part` hooks that let the renderer belong to
32
+ the host product.
33
+ - Extensible syntax adapters, locale registry, allow-listed expression
34
+ functions, and preserved custom data.
35
+ - SSR-safe imports and a client-island React/Next integration.
36
+
37
+ ## Review the live example
38
+
39
+ Node.js 22+ and pnpm are required for local development:
40
+
41
+ ```bash
42
+ git clone https://github.com/javiercavlop/pricing-renderer.git
43
+ cd pricing-renderer
44
+ corepack enable
45
+ pnpm install
46
+ pnpm demo
47
+ ```
48
+
49
+ The showcase uses the real built package. Change seats, boolean/select
50
+ variables, billing, plans, add-ons, quantities, language, theme, and rendering
51
+ mode while watching resolved state and events.
52
+
53
+ Additional runnable integrations:
54
+
55
+ ```bash
56
+ pnpm demo:react
57
+ pnpm demo:next
58
+ ```
59
+
60
+ The Next example keeps the page server-rendered and isolates only the interactive
61
+ renderer behind a client boundary.
62
+
63
+ ![Pricing Renderer mobile add-on quantity](docs/assets/demo-mobile-light.png)
64
+
65
+ See the full [demo validation guide](./docs/demo.md).
66
+
67
+ ## Installation and package location
68
+
69
+ Install the latest stable release from npm:
70
+
71
+ ```bash
72
+ npm install pricing-renderer
73
+ # or
74
+ pnpm add pricing-renderer
75
+ # or
76
+ yarn add pricing-renderer
77
+ ```
78
+
79
+ Pin the initial release when an exact, reproducible version is required:
80
+
81
+ ```bash
82
+ npm install pricing-renderer@0.1.0
83
+ ```
84
+
85
+ Release locations:
86
+
87
+ - npm package and provenance:
88
+ [`pricing-renderer`](https://www.npmjs.com/package/pricing-renderer)
89
+ - `0.1.0` release notes and source tag:
90
+ [`v0.1.0`](https://github.com/javiercavlop/pricing-renderer/releases/tag/v0.1.0)
91
+ - all GitHub releases:
92
+ [`javiercavlop/pricing-renderer/releases`](https://github.com/javiercavlop/pricing-renderer/releases)
93
+
94
+ Every published GitHub Release triggers the npm CD workflow. Stable releases
95
+ publish under the `latest` dist-tag and GitHub prereleases under `next`; a tag,
96
+ version, documentation, test, accessibility, visual, or package-validation
97
+ failure stops before `npm publish`.
98
+
99
+ Confirm the installed registry version with:
100
+
101
+ ```bash
102
+ npm view pricing-renderer version
103
+ ```
104
+
105
+ See the [release guide](./docs/releasing.md) for provenance, validation, and
106
+ Trusted Publishing details.
107
+
108
+ ## Package entry points
109
+
110
+ | Import | Purpose |
111
+ | ----------------------------- | --------------------------------------------------------------- |
112
+ | `pricing-renderer` | Types, normalization, resolution, expressions, i18n, view-model |
113
+ | `pricing-renderer/yaml` | YAML parsing and bounded remote loading |
114
+ | `pricing-renderer/element` | Web Component class without global registration |
115
+ | `pricing-renderer/define` | Register `<pricing-renderer>` |
116
+ | `pricing-renderer/react` | Typed React 18/19 adapter |
117
+ | `pricing-renderer/base.css` | Required structural and accessibility styles |
118
+ | `pricing-renderer/theme.css` | Default professional visual tokens |
119
+ | `pricing-renderer/styles.css` | Base and theme combined |
120
+
121
+ ## Web Component
122
+
123
+ Initialize project-wide defaults before creating renderer instances:
124
+
125
+ ```ts
126
+ import { configurePricingRenderer } from 'pricing-renderer';
127
+
128
+ configurePricingRenderer({
129
+ locale: 'en-US',
130
+ pricingPath: '/pricing',
131
+ selectionEnabled: true,
132
+ ctaEnabled: true,
133
+ variablesEnabled: true,
134
+ presentation: {
135
+ planInheritance: 'auto',
136
+ },
137
+ });
138
+ ```
139
+
140
+ Every option is optional. The deterministic built-in defaults are English
141
+ (`en-US`), `/pricing`, selectable plans/add-ons, visible CTAs, and editable
142
+ variables. `pricingPath` is the canonical host-application route; the library
143
+ exposes it but does not mutate or install routes in the host router. An
144
+ individual element or React instance can override any value. With
145
+ `variablesEnabled: false`, formulas use the iPricing variable defaults.
146
+
147
+ Import registration and styles once:
148
+
149
+ ```ts
150
+ import 'pricing-renderer/define';
151
+ import 'pricing-renderer/styles.css';
152
+ ```
153
+
154
+ Render a public remote source:
155
+
156
+ ```html
157
+ <pricing-renderer
158
+ src="https://cdn.example.com/pricing.yml"
159
+ locale="en-US"
160
+ pricing-path="/pricing"
161
+ mode="commercial"
162
+ theme="auto"
163
+ ></pricing-renderer>
164
+ ```
165
+
166
+ `locale` and `pricingPath` are initial host configuration. Set them globally,
167
+ when the renderer is created, or through the equivalent properties/React props.
168
+ The library does not inject a language picker into production UI. The showcase
169
+ picker only demonstrates that locale configuration can be changed reactively.
170
+
171
+ Or assign a YAML string or iPricing-compatible object as a JavaScript property:
172
+
173
+ ```ts
174
+ const renderer = document.querySelector('pricing-renderer');
175
+ renderer.yaml = pricingYaml;
176
+ // renderer.pricing = iPricing;
177
+ ```
178
+
179
+ Exactly one of `pricing`, `yaml`, or `src` is accepted. Conflicts produce a
180
+ structured diagnostic instead of implicit precedence.
181
+
182
+ ## React and Next
183
+
184
+ ```tsx
185
+ 'use client';
186
+
187
+ import { PricingRenderer } from 'pricing-renderer/react';
188
+ import 'pricing-renderer/styles.css';
189
+
190
+ export function PricingPage({ pricing }: { pricing: Record<string, unknown> }) {
191
+ return (
192
+ <PricingRenderer
193
+ pricing={pricing}
194
+ locale="en-US"
195
+ pricingPath="/pricing"
196
+ theme="auto"
197
+ onSelectionChange={(event) => {
198
+ console.info(event.detail.selection, event.detail.resolved);
199
+ }}
200
+ onAction={(event) => {
201
+ event.preventDefault();
202
+ openCheckout(event.detail);
203
+ }}
204
+ />
205
+ );
206
+ }
207
+ ```
208
+
209
+ The React entry is safe to import during SSR and is marked as a client
210
+ component. Full pricing content appears after hydration; deep light-DOM SSR is
211
+ not a v1 contract.
212
+
213
+ ## Plan highlights, inheritance, and badges
214
+
215
+ Card highlights can reference both features and usage limits without ambiguity.
216
+ The hybrid mode renders configured items first and fills remaining slots from
217
+ the plan data:
218
+
219
+ ```ts
220
+ configurePricingRenderer({
221
+ presentation: {
222
+ planInheritance: 'auto',
223
+ planBadges: {
224
+ growth: [
225
+ {
226
+ id: 'most-popular',
227
+ label: 'Most popular',
228
+ tone: 'accent',
229
+ emphasize: true,
230
+ },
231
+ ],
232
+ },
233
+ planHighlights: {
234
+ growth: {
235
+ mode: 'hybrid',
236
+ maxItems: 5,
237
+ items: [
238
+ { id: 'auditLog', kind: 'feature' },
239
+ { id: 'storage', kind: 'usage-limit' },
240
+ ],
241
+ },
242
+ },
243
+ },
244
+ });
245
+ ```
246
+
247
+ The same `PricingPresentation` object can be supplied per component or under
248
+ `custom.pricingRenderer` in YAML. Instance props win over project defaults,
249
+ which win over YAML-owned presentation values.
250
+
251
+ `planInheritance: "auto"` checks the complete feature/limit set against the
252
+ previous visible plan. “Everything in …, plus” only appears when the current
253
+ plan is demonstrably at least as capable; otherwise the claim is omitted.
254
+ Per-plan `inheritsFrom` can select a specific base plan or disable inheritance.
255
+ Badges are optional, support `accent`, `success`, `warning`, and `neutral`
256
+ tones, and only emphasize a card when `emphasize: true`.
257
+
258
+ ## Variables and multicontractable add-ons
259
+
260
+ Primitive variables referenced by formulas become controls automatically.
261
+ Presentation metadata can upgrade them to sliders or selects:
262
+
263
+ ```yaml
264
+ custom:
265
+ pricingRenderer:
266
+ planBadges:
267
+ growth:
268
+ - id: most-popular
269
+ label: Most popular
270
+ tone: accent
271
+ emphasize: true
272
+ variableControls:
273
+ - path: seats
274
+ type: slider
275
+ label: Team seats
276
+ min: 1
277
+ max: 250
278
+ step: 1
279
+ - path: region
280
+ type: select
281
+ label: Billing region
282
+ options:
283
+ - value: eu
284
+ label: Europe
285
+ - value: us
286
+ label: United States
287
+ ```
288
+
289
+ Add-ons with `subscriptionConstraints` receive a quantity stepper that respects
290
+ `minQuantity`, `maxQuantity`, and `quantityStep`. Dependency and exclusion
291
+ changes are listed in an accessible confirmation dialog before mutation.
292
+ Usage-limit values expressed as `.inf` render as the localized **Unlimited**
293
+ label.
294
+
295
+ ## CTAs and host-owned checkout
296
+
297
+ ```ts
298
+ renderer.presentation = {
299
+ ctas: [
300
+ {
301
+ id: 'start-growth',
302
+ planId: 'growth',
303
+ label: 'Start free trial',
304
+ href: '/checkout/growth',
305
+ metadata: { source: 'pricing-page' },
306
+ },
307
+ ],
308
+ };
309
+
310
+ renderer.addEventListener('pricing-action', (event) => {
311
+ event.preventDefault();
312
+ openCheckout(event.detail);
313
+ });
314
+ ```
315
+
316
+ The cancelable event includes the selected plan, billing period, variables,
317
+ add-ons, resolved prices, subtotal, quote state, and metadata. Checkout,
318
+ authentication, and contracting remain host responsibilities.
319
+
320
+ Public events:
321
+
322
+ - `pricing-ready`
323
+ - `pricing-selection-change`
324
+ - `pricing-action`
325
+ - `pricing-diagnostic`
326
+
327
+ ## Private remote sources
328
+
329
+ Secrets are property-only and never reflected into markup:
330
+
331
+ ```ts
332
+ renderer.src = 'https://api.example.com/private/pricing.yml';
333
+ renderer.request = {
334
+ credentials: 'include',
335
+ headers: async () => ({
336
+ Authorization: `Bearer ${await refreshAccessToken()}`,
337
+ }),
338
+ timeoutMs: 15_000,
339
+ maxBytes: 2 * 1024 * 1024,
340
+ };
341
+ ```
342
+
343
+ Use `loadPricing` for OAuth exchanges, signed URLs, proxies, or SDK clients. The
344
+ built-in loader permits HTTP/HTTPS `GET` only, defaults to
345
+ `credentials: "omit"`, honors cancellation, and never fetches during SSR.
346
+
347
+ ## Theming
348
+
349
+ ```css
350
+ pricing-renderer {
351
+ --pr-color-accent: #0057ff;
352
+ --pr-radius-lg: 0.75rem;
353
+ --pr-shell-padding: clamp(1rem, 3vw, 2.5rem);
354
+ }
355
+
356
+ pricing-renderer [data-pr-part='plan-card'] {
357
+ font-family: var(--brand-font);
358
+ }
359
+ ```
360
+
361
+ Import `styles.css` for the full theme or only `base.css` and supply your own.
362
+ CSS variables and `data-pr-part` values are stable; internal `pr-*` classes are
363
+ not. Read the [theming guide](./docs/theming.md) before applying broad host
364
+ resets to light-DOM content.
365
+
366
+ ![Pricing Renderer dark theme](docs/assets/demo-desktop-dark.png)
367
+
368
+ ## Headless and extension APIs
369
+
370
+ ```ts
371
+ import {
372
+ createPricingViewModel,
373
+ normalizePricing,
374
+ registerMessageCatalog,
375
+ resolvePricing,
376
+ } from 'pricing-renderer';
377
+ import { loadPricingFromUrl, parsePricingYaml } from 'pricing-renderer/yaml';
378
+ ```
379
+
380
+ Extend future/vendor syntax with `PricingSyntaxAdapter`, translations with
381
+ `registerMessageCatalog`, and domain calculations through explicitly
382
+ allow-listed expression functions. See [Extending](./docs/extending.md).
383
+
384
+ ## Documentation
385
+
386
+ - [Architecture](./docs/architecture.md)
387
+ - [API reference](./docs/api-reference.md)
388
+ - [Project and instance configuration](./docs/configuration.md)
389
+ - [Demo and release acceptance](./docs/demo.md)
390
+ - [Release and npm publication](./docs/releasing.md)
391
+ - [Extending the library](./docs/extending.md)
392
+ - [Theming](./docs/theming.md)
393
+ - [Internationalization](./docs/i18n.md)
394
+ - [Pricing2Yaml compatibility](./docs/pricing2yaml-compatibility.md)
395
+ - [Contributing](./CONTRIBUTING.md)
396
+ - [Security policy](./SECURITY.md)
397
+ - [Changelog](./CHANGELOG.md)
398
+
399
+ ## Quality gates
400
+
401
+ ```bash
402
+ pnpm lint
403
+ pnpm format:check
404
+ pnpm typecheck
405
+ pnpm test
406
+ pnpm build
407
+ pnpm test:browser
408
+ pnpm package:check
409
+ ```
410
+
411
+ Browser coverage includes Chromium, Firefox, WebKit, Axe, keyboard paths, and
412
+ visual breakpoints. Releases use Changesets, SemVer, npm provenance, and MIT.
413
+
414
+ ## Security
415
+
416
+ Pricing text is escaped, links use safe schemes, and expressions cannot reach
417
+ globals or prototypes. `private` only controls presentation—remove confidential
418
+ data before delivering YAML to a browser. Report vulnerabilities through the
419
+ process in [SECURITY.md](./SECURITY.md).
@@ -0,0 +1,10 @@
1
+ # Third-party notices
2
+
3
+ This project was informed by the following MIT-licensed projects. Their editor
4
+ implementations are not bundled into this package.
5
+
6
+ - Sphere — Copyright Alex-GF and contributors — https://github.com/Alex-GF/Sphere
7
+ - Pricing4TS — Copyright Alex-GF and contributors — https://github.com/Alex-GF/Pricing4TS
8
+
9
+ The full dependency license inventory is generated from the lockfile for every
10
+ release. Each runtime dependency retains its own copyright and license terms.
@@ -0,0 +1,122 @@
1
+ {
2
+ "schemaVersion": "1.0.0",
3
+ "readme": "README.md",
4
+ "modules": [
5
+ {
6
+ "kind": "javascript-module",
7
+ "path": "dist/element/pricing-renderer-element.js",
8
+ "declarations": [
9
+ {
10
+ "kind": "class",
11
+ "name": "PricingRendererElement",
12
+ "customElement": true,
13
+ "tagName": "pricing-renderer",
14
+ "description": "A responsive, themeable renderer for Pricing2Yaml 3.x.",
15
+ "members": [
16
+ { "kind": "field", "name": "pricing", "type": { "text": "IPricingLike" } },
17
+ { "kind": "field", "name": "yaml", "type": { "text": "string" } },
18
+ { "kind": "field", "name": "src", "type": { "text": "string" }, "attribute": "src" },
19
+ {
20
+ "kind": "field",
21
+ "name": "request",
22
+ "type": { "text": "PricingRequestOptions" }
23
+ },
24
+ { "kind": "field", "name": "loadPricing", "type": { "text": "PricingLoader" } },
25
+ {
26
+ "kind": "field",
27
+ "name": "normalizeOptions",
28
+ "type": { "text": "NormalizePricingOptions" }
29
+ },
30
+ {
31
+ "kind": "field",
32
+ "name": "expressionOptions",
33
+ "type": { "text": "ExpressionOptions" }
34
+ },
35
+ { "kind": "field", "name": "selection", "type": { "text": "PricingSelection" } },
36
+ {
37
+ "kind": "field",
38
+ "name": "defaultSelection",
39
+ "type": { "text": "Partial<PricingSelection>" }
40
+ },
41
+ {
42
+ "kind": "field",
43
+ "name": "presentation",
44
+ "type": { "text": "PricingPresentation" }
45
+ },
46
+ {
47
+ "kind": "field",
48
+ "name": "locale",
49
+ "type": { "text": "string" },
50
+ "attribute": "locale"
51
+ },
52
+ {
53
+ "kind": "field",
54
+ "name": "pricingPath",
55
+ "type": { "text": "string" },
56
+ "attribute": "pricing-path"
57
+ },
58
+ {
59
+ "kind": "field",
60
+ "name": "selectionEnabled",
61
+ "type": { "text": "boolean" }
62
+ },
63
+ { "kind": "field", "name": "ctaEnabled", "type": { "text": "boolean" } },
64
+ {
65
+ "kind": "field",
66
+ "name": "variablesEnabled",
67
+ "type": { "text": "boolean" }
68
+ },
69
+ { "kind": "field", "name": "messages", "type": { "text": "MessageCatalog" } },
70
+ {
71
+ "kind": "field",
72
+ "name": "mode",
73
+ "type": { "text": "\"commercial\" | \"catalog\"" },
74
+ "attribute": "mode"
75
+ },
76
+ {
77
+ "kind": "field",
78
+ "name": "layout",
79
+ "type": { "text": "\"auto\" | \"compact\" | \"table\"" },
80
+ "attribute": "layout"
81
+ },
82
+ {
83
+ "kind": "field",
84
+ "name": "visibility",
85
+ "type": { "text": "\"public-only\" | \"all\"" },
86
+ "attribute": "visibility"
87
+ },
88
+ {
89
+ "kind": "field",
90
+ "name": "theme",
91
+ "type": { "text": "\"light\" | \"dark\" | \"auto\"" },
92
+ "attribute": "theme"
93
+ },
94
+ {
95
+ "kind": "field",
96
+ "name": "loadingLabel",
97
+ "type": { "text": "string" },
98
+ "attribute": "loading-label"
99
+ },
100
+ {
101
+ "kind": "method",
102
+ "name": "reload",
103
+ "return": { "type": { "text": "Promise<void>" } }
104
+ }
105
+ ],
106
+ "events": [
107
+ { "name": "pricing-ready", "type": { "text": "CustomEvent<PricingReadyDetail>" } },
108
+ {
109
+ "name": "pricing-selection-change",
110
+ "type": { "text": "CustomEvent<PricingSelectionChangeDetail>" }
111
+ },
112
+ { "name": "pricing-action", "type": { "text": "CustomEvent<PricingActionDetail>" } },
113
+ {
114
+ "name": "pricing-diagnostic",
115
+ "type": { "text": "CustomEvent<PricingDiagnosticDetail>" }
116
+ }
117
+ ]
118
+ }
119
+ ]
120
+ }
121
+ ]
122
+ }
@@ -0,0 +1,6 @@
1
+ import type { PricingRendererConfig } from './types.js';
2
+ export declare const DEFAULT_PRICING_RENDERER_CONFIG: Readonly<PricingRendererConfig>;
3
+ export declare function createPricingRendererConfig(options?: Partial<PricingRendererConfig>): Readonly<PricingRendererConfig>;
4
+ export declare function configurePricingRenderer(options?: Partial<PricingRendererConfig>): Readonly<PricingRendererConfig>;
5
+ export declare function getPricingRendererConfig(): Readonly<PricingRendererConfig>;
6
+ //# sourceMappingURL=config.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/core/config.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,YAAY,CAAC;AAExD,eAAO,MAAM,+BAA+B,EAAE,QAAQ,CAAC,qBAAqB,CAO1E,CAAC;AAyCH,wBAAgB,2BAA2B,CACzC,OAAO,GAAE,OAAO,CAAC,qBAAqB,CAAM,GAC3C,QAAQ,CAAC,qBAAqB,CAAC,CA+BjC;AAED,wBAAgB,wBAAwB,CACtC,OAAO,GAAE,OAAO,CAAC,qBAAqB,CAAM,GAC3C,QAAQ,CAAC,qBAAqB,CAAC,CAGjC;AAED,wBAAgB,wBAAwB,IAAI,QAAQ,CAAC,qBAAqB,CAAC,CAE1E"}
@@ -0,0 +1,62 @@
1
+ export const DEFAULT_PRICING_RENDERER_CONFIG = Object.freeze({
2
+ locale: 'en-US',
3
+ pricingPath: '/pricing',
4
+ selectionEnabled: true,
5
+ ctaEnabled: true,
6
+ variablesEnabled: true,
7
+ presentation: Object.freeze({}),
8
+ });
9
+ let configuredDefaults = DEFAULT_PRICING_RENDERER_CONFIG;
10
+ function normalizeLocale(locale) {
11
+ const value = locale.trim();
12
+ if (!value)
13
+ throw new TypeError('Pricing renderer locale cannot be empty.');
14
+ try {
15
+ return Intl.getCanonicalLocales(value)[0] ?? value;
16
+ }
17
+ catch {
18
+ throw new TypeError(`Invalid pricing renderer locale: ${locale}`);
19
+ }
20
+ }
21
+ function normalizePricingPath(pricingPath) {
22
+ const value = pricingPath.trim();
23
+ if (!value.startsWith('/') ||
24
+ value.startsWith('//') ||
25
+ value.includes('?') ||
26
+ value.includes('#')) {
27
+ throw new TypeError('Pricing renderer pricingPath must be an absolute application pathname such as "/pricing".');
28
+ }
29
+ return value.length > 1 ? value.replace(/\/+$/, '') : value;
30
+ }
31
+ function normalizeFeatureFlag(value, fallback, name) {
32
+ if (value === undefined)
33
+ return fallback;
34
+ if (typeof value !== 'boolean') {
35
+ throw new TypeError(`Pricing renderer ${name} must be a boolean.`);
36
+ }
37
+ return value;
38
+ }
39
+ export function createPricingRendererConfig(options = {}) {
40
+ if (options.presentation !== undefined &&
41
+ (typeof options.presentation !== 'object' ||
42
+ options.presentation === null ||
43
+ Array.isArray(options.presentation))) {
44
+ throw new TypeError('Pricing renderer presentation must be an object.');
45
+ }
46
+ return Object.freeze({
47
+ locale: normalizeLocale(options.locale ?? DEFAULT_PRICING_RENDERER_CONFIG.locale),
48
+ pricingPath: normalizePricingPath(options.pricingPath ?? DEFAULT_PRICING_RENDERER_CONFIG.pricingPath),
49
+ selectionEnabled: normalizeFeatureFlag(options.selectionEnabled, DEFAULT_PRICING_RENDERER_CONFIG.selectionEnabled, 'selectionEnabled'),
50
+ ctaEnabled: normalizeFeatureFlag(options.ctaEnabled, DEFAULT_PRICING_RENDERER_CONFIG.ctaEnabled, 'ctaEnabled'),
51
+ variablesEnabled: normalizeFeatureFlag(options.variablesEnabled, DEFAULT_PRICING_RENDERER_CONFIG.variablesEnabled, 'variablesEnabled'),
52
+ presentation: Object.freeze({ ...(options.presentation ?? {}) }),
53
+ });
54
+ }
55
+ export function configurePricingRenderer(options = {}) {
56
+ configuredDefaults = createPricingRendererConfig(options);
57
+ return configuredDefaults;
58
+ }
59
+ export function getPricingRendererConfig() {
60
+ return configuredDefaults;
61
+ }
62
+ //# sourceMappingURL=config.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/core/config.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,4 @@
1
+ import type { ExpressionEvaluation, ExpressionOptions } from './types.js';
2
+ export declare function collectExpressionDependencies(source: string): string[];
3
+ export declare function evaluatePriceExpression(source: string, variables: Record<string, unknown>, options?: ExpressionOptions): ExpressionEvaluation;
4
+ //# sourceMappingURL=expression.d.ts.map