@ponchopay/pp-browser 1.1.0 → 1.2.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/README.md CHANGED
@@ -12,16 +12,15 @@ You can import the compiled file directly from our servers:
12
12
 
13
13
  ```html
14
14
  <script
15
- type="module"
16
15
  src="https://pay.ponchopay.com/api/integration/generic/asset/pp-browser.<version>.min.js"
17
16
  ></script>
18
17
  ```
19
18
 
20
- After this HTML declaration, you will be able to use the web component.
19
+ After this HTML declaration, you will be able to use the web components.
21
20
 
22
21
  ### NPM installation
23
22
 
24
- You can install the module from `npm`:
23
+ You can install the module from `npm` (or the package manager of your preference):
25
24
 
26
25
  ```bash
27
26
  npm i @ponchopay/pp-browser
@@ -33,36 +32,20 @@ After this command, you can import the web componet like this:
33
32
  import '@ponchopay/pp-browser';
34
33
  ```
35
34
 
36
- ## Using the web component
35
+ ## Using the web components
37
36
 
38
- The web component can be used by declaring it in HTML like this:
39
-
40
- ```html
41
- <pp-payment {properties}>{text}</pp-payment>
42
- ```
43
-
44
- The following the list of accepted properties (please, refer to the [official documentation](https://pay.ponchopay.com/api/docs) for their meaning):
45
-
46
- | Name | Mandatory |
47
- | -------- | --------- |
48
- | token | Yes |
49
- | metadata | Yes |
50
- | urn | Yes |
51
- | amount | Yes |
52
- | email | Yes |
53
- | note | No |
54
- | expiry | No |
55
-
56
- The component's text is optional being "Pay with PonchoPay" the default text. Feel free to change it as you see fit.
37
+ This library injects 2 new HTML elements:
38
+ - [pp-payment](https://github.com/ponchocare/pp-browser/blob/master/docs/pp-payment.md): This web component simplifies the payment initialisation directly from the browser.
39
+ - [pp-subscription](https://github.com/ponchocare/pp-browser/blob/master/docs/pp-subscription.md): This web component simplifies the subscription initialisation directly from the browser.
57
40
 
58
41
  ## Considerations
59
42
 
60
- Unfortunately, this web component required `HTMLElement` class to exist which means that it is not suitable for Server Side Rendering applications.
43
+ Unfortunately, these web components require the `HTMLElement` class to exist which means that it is not suitable for Server Side Rendering (SSR) applications.
61
44
  There are, however, some techniques that can be used to mitigate this.
62
45
 
63
46
  ### SvelteKit
64
47
 
65
- When using SvelteKit, the component import can be pushed to the `onMount` event:
48
+ When using SvelteKit, the components' import can be pushed to the `onMount` event:
66
49
 
67
50
  ```svelte
68
51
  <script>
@@ -76,7 +59,7 @@ When using SvelteKit, the component import can be pushed to the `onMount` event:
76
59
  <pp-payment>It worked!</pp-payment>
77
60
  ```
78
61
 
79
- Alternatively, the route can be made non-ssr by exporting [`export const ssr = false;`](https://kit.svelte.dev/docs/page-options#ssr) in the loader file.
62
+ Alternatively, the route can be made non-ssr by exporting [`export const ssr = false;`](https://kit.svelte.dev/docs/page-options#ssr) in the `+page.js` file.
80
63
 
81
64
  ## Development
82
65
 
@@ -106,10 +89,11 @@ npm run test
106
89
 
107
90
  For most of the tools, the configuration is in the `package.json` to reduce the amount of files in the project.
108
91
 
109
- ## Local Demo with `web-dev-server`
92
+ ## Local Demo with `vite`
110
93
 
111
94
  ```bash
112
- npm start
95
+ npm run start
113
96
  ```
114
97
 
115
- To run a local development server that serves the basic demo located in `demo/index.html`
98
+ This command will initiate a development server and open the `example/index.html` page automatically.
99
+ Feel free to browse this page to find examples on how to use the components.
@@ -0,0 +1,17 @@
1
+ import { Field } from './validation.js';
2
+ export declare abstract class PpForm extends HTMLElement {
3
+ private readonly path;
4
+ private readonly label;
5
+ private readonly fields;
6
+ protected constructor(path: string, label: string, fields: Record<string, Field>);
7
+ private getAttributeWithFallback;
8
+ private isAttributeSet;
9
+ private syncAttributes;
10
+ private showErrorMessage;
11
+ connectedCallback(): void;
12
+ disconnectedCallback(): void;
13
+ attributeChangedCallback(): void;
14
+ submit(): void;
15
+ checkValidity(): boolean;
16
+ static get observedAttributes(): string[];
17
+ }
@@ -0,0 +1,143 @@
1
+ import { formatName, joinPaths, split } from './utils.js';
2
+ import { mandatory, single } from './validation.js';
3
+ const DEFAULT_BASE = 'https://pay.ponchopay.com/';
4
+ export class PpForm extends HTMLElement {
5
+ constructor(path, label, fields) {
6
+ super();
7
+ this.path = path;
8
+ this.label = label;
9
+ this.fields = { ...fields, token: mandatory(single()) };
10
+ this.attachShadow({ mode: 'open' });
11
+ }
12
+ getAttributeWithFallback(name, fallback) {
13
+ var _a;
14
+ return (_a = this.getAttribute(name)) !== null && _a !== void 0 ? _a : fallback;
15
+ }
16
+ isAttributeSet(name) {
17
+ return this.getAttributeWithFallback(name, '').length > 0;
18
+ }
19
+ syncAttributes() {
20
+ const form = this.shadowRoot.querySelector('form');
21
+ if (form) {
22
+ const base = this.getAttributeWithFallback('base', DEFAULT_BASE);
23
+ form.action = joinPaths(base, this.path);
24
+ form.replaceChildren();
25
+ Object.entries(this.fields).forEach(([attribute, { collection }]) => {
26
+ if (this.hasAttribute(attribute)) {
27
+ const attr = this.getAttribute(attribute);
28
+ let name = formatName(attribute);
29
+ let values = attr.length > 0 ? [attr] : [];
30
+ if (collection) {
31
+ name = `${name}[]`;
32
+ values = split(attr, ',');
33
+ }
34
+ values.forEach(value => {
35
+ const input = document.createElement('input');
36
+ input.type = 'hidden';
37
+ input.name = name;
38
+ input.value = value;
39
+ form.appendChild(input);
40
+ });
41
+ }
42
+ });
43
+ const slot = document.createElement('slot');
44
+ slot.innerHTML = this.label;
45
+ const button = document.createElement('button');
46
+ button.setAttribute('part', 'button');
47
+ button.type = 'submit';
48
+ button.appendChild(slot);
49
+ form.appendChild(button);
50
+ }
51
+ }
52
+ showErrorMessage() {
53
+ var _a;
54
+ const form = this.shadowRoot.querySelector('form');
55
+ if (form) {
56
+ (_a = form.querySelector('div')) === null || _a === void 0 ? void 0 : _a.remove();
57
+ const div = document.createElement('div');
58
+ div.setAttribute('part', 'error');
59
+ div.className = 'error';
60
+ div.innerHTML = 'Some attributes are incorrect. Please, review them.';
61
+ form.appendChild(div);
62
+ }
63
+ }
64
+ connectedCallback() {
65
+ const base = this.getAttributeWithFallback('base', DEFAULT_BASE);
66
+ const style = document.createElement('style');
67
+ style.textContent = `
68
+ form {
69
+ display: contents;
70
+ }
71
+
72
+ button {
73
+ width: 100%;
74
+ background-color: #02C2A0;
75
+ white-space: nowrap;
76
+ text-decoration-line: none;
77
+ border-radius: .25rem;
78
+ box-shadow: 0 1px 2px 0 rgb(0 0 0 / 0.05);
79
+ text-align: center;
80
+ font-size: 1.25rem;
81
+ line-height: 1.75rem;
82
+ color: white;
83
+ margin-top: .5rem;
84
+ margin-bottom: .75rem;
85
+ padding: .75rem 1rem;
86
+ display: flex;
87
+ flex-wrap: nowrap;
88
+ align-items: center;
89
+ justify-content: space-evenly;
90
+ cursor: pointer;
91
+ text-transform: none;
92
+ box-sizing: border-box;
93
+ border-width: 0;
94
+ border-style: solid;
95
+ border-color: currentColor;
96
+ }
97
+
98
+ div.error {
99
+ color: #EB3B50;
100
+ font-size: 0.875rem;
101
+ }`;
102
+ const form = document.createElement('form');
103
+ form.action = joinPaths(base, this.path);
104
+ form.method = 'post';
105
+ form.onsubmit = event => {
106
+ if (!this.checkValidity()) {
107
+ event.preventDefault();
108
+ this.showErrorMessage();
109
+ }
110
+ };
111
+ this.shadowRoot.append(style, form);
112
+ this.syncAttributes();
113
+ }
114
+ disconnectedCallback() {
115
+ this.shadowRoot.replaceChildren();
116
+ }
117
+ attributeChangedCallback() {
118
+ this.syncAttributes();
119
+ }
120
+ submit() {
121
+ var _a;
122
+ (_a = this.shadowRoot.querySelector('form')) === null || _a === void 0 ? void 0 : _a.requestSubmit();
123
+ }
124
+ checkValidity() {
125
+ return Object.entries(this.fields).every(([attribute, { required }]) => {
126
+ if (required === true) {
127
+ return this.isAttributeSet(attribute);
128
+ }
129
+ if (Array.isArray(required)) {
130
+ const [dependant, value] = required;
131
+ if ((value === true || this.getAttribute(dependant) === value) &&
132
+ this.isAttributeSet(dependant)) {
133
+ return this.isAttributeSet(attribute);
134
+ }
135
+ }
136
+ return true;
137
+ });
138
+ }
139
+ static get observedAttributes() {
140
+ return ['base', 'token'];
141
+ }
142
+ }
143
+ //# sourceMappingURL=PpForm.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"PpForm.js","sourceRoot":"","sources":["../../src/PpForm.ts"],"names":[],"mappings":"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","sourcesContent":["import { formatName, joinPaths, split } from './utils.js';\nimport { Field, mandatory, single } from './validation.js';\n\nconst DEFAULT_BASE = 'https://pay.ponchopay.com/';\n\nexport abstract class PpForm extends HTMLElement {\n private readonly path: string;\n private readonly label: string;\n private readonly fields: Record<string, Field>;\n\n protected constructor(\n path: string,\n label: string,\n fields: Record<string, Field>\n ) {\n super();\n this.path = path;\n this.label = label;\n this.fields = { ...fields, token: mandatory(single()) };\n this.attachShadow({ mode: 'open' });\n }\n\n private getAttributeWithFallback(name: string, fallback: string): string {\n return this.getAttribute(name) ?? fallback;\n }\n\n private isAttributeSet(name: string): boolean {\n return this.getAttributeWithFallback(name, '').length > 0;\n }\n\n private syncAttributes(): void {\n const form = this.shadowRoot!.querySelector('form');\n if (form) {\n const base = this.getAttributeWithFallback('base', DEFAULT_BASE);\n\n form.action = joinPaths(base, this.path);\n form.replaceChildren();\n\n Object.entries(this.fields).forEach(([attribute, { collection }]) => {\n if (this.hasAttribute(attribute)) {\n const attr = this.getAttribute(attribute)!;\n\n let name = formatName(attribute);\n let values = attr.length > 0 ? [attr] : [];\n if (collection) {\n name = `${name}[]`;\n values = split(attr, ',');\n }\n\n values.forEach(value => {\n const input = document.createElement('input');\n input.type = 'hidden';\n input.name = name;\n input.value = value;\n form.appendChild(input);\n });\n }\n });\n\n const slot = document.createElement('slot');\n slot.innerHTML = this.label;\n\n const button = document.createElement('button');\n button.setAttribute('part', 'button');\n button.type = 'submit';\n button.appendChild(slot);\n form.appendChild(button);\n }\n }\n\n private showErrorMessage(): void {\n const form = this.shadowRoot!.querySelector('form');\n if (form) {\n form.querySelector('div')?.remove();\n\n const div = document.createElement('div');\n div.setAttribute('part', 'error');\n div.className = 'error';\n div.innerHTML = 'Some attributes are incorrect. Please, review them.';\n form.appendChild(div);\n }\n }\n\n public connectedCallback(): void {\n const base = this.getAttributeWithFallback('base', DEFAULT_BASE);\n\n const style = document.createElement('style');\n style.textContent = `\n form {\n display: contents;\n }\n\n button {\n width: 100%;\n background-color: #02C2A0;\n white-space: nowrap;\n text-decoration-line: none;\n border-radius: .25rem;\n box-shadow: 0 1px 2px 0 rgb(0 0 0 / 0.05);\n text-align: center;\n font-size: 1.25rem;\n line-height: 1.75rem;\n color: white;\n margin-top: .5rem;\n margin-bottom: .75rem;\n padding: .75rem 1rem;\n display: flex;\n flex-wrap: nowrap;\n align-items: center;\n justify-content: space-evenly;\n cursor: pointer;\n text-transform: none;\n box-sizing: border-box;\n border-width: 0;\n border-style: solid;\n border-color: currentColor;\n }\n\n div.error {\n color: #EB3B50;\n font-size: 0.875rem;\n }`;\n\n const form = document.createElement('form');\n form.action = joinPaths(base, this.path);\n form.method = 'post';\n form.onsubmit = event => {\n if (!this.checkValidity()) {\n event.preventDefault();\n this.showErrorMessage();\n }\n };\n this.shadowRoot!.append(style, form);\n\n this.syncAttributes();\n }\n\n public disconnectedCallback(): void {\n this.shadowRoot!.replaceChildren();\n }\n\n public attributeChangedCallback(): void {\n this.syncAttributes();\n }\n\n public submit(): void {\n this.shadowRoot!.querySelector('form')?.requestSubmit();\n }\n\n public checkValidity(): boolean {\n return Object.entries(this.fields).every(([attribute, { required }]) => {\n if (required === true) {\n return this.isAttributeSet(attribute);\n }\n\n if (Array.isArray(required)) {\n const [dependant, value] = required;\n\n if (\n (value === true || this.getAttribute(dependant) === value) &&\n this.isAttributeSet(dependant)\n ) {\n return this.isAttributeSet(attribute);\n }\n }\n\n return true;\n });\n }\n\n public static get observedAttributes() {\n return ['base', 'token'];\n }\n}\n"]}
@@ -1,23 +1,5 @@
1
- export declare class PpPayment extends HTMLElement {
2
- private sr;
1
+ import { PpForm } from './PpForm.js';
2
+ export declare class PpPayment extends PpForm {
3
3
  constructor();
4
- private redrawContents;
5
- set base(value: string);
6
- get base(): string;
7
- set token(value: string);
8
- get token(): string;
9
- set metadata(value: string);
10
- get metadata(): string;
11
- set urn(value: string);
12
- get urn(): string;
13
- set amount(value: string | number);
14
- get amount(): string;
15
- set email(value: string);
16
- get email(): string;
17
- set note(value: string);
18
- get note(): string;
19
- set expiry(value: Date | string);
20
- get expiry(): string;
21
- attributeChangedCallback(): void;
22
4
  static get observedAttributes(): string[];
23
5
  }
@@ -1,115 +1,20 @@
1
- import { buildButton, buildForm, buildHiddenInput, buildSlot, buildStyle, } from './utils';
2
- const ENDPOINT = '/api/integration/generic/initiate';
3
- const ATTRIBUTES = [
4
- 'token',
5
- 'metadata',
6
- 'urn',
7
- 'amount',
8
- 'email',
9
- 'note',
10
- 'expiry',
11
- ];
12
- const STYLES = [
13
- 'width: 100%',
14
- 'background-color: #02C2A0',
15
- 'white-space: nowrap',
16
- 'text-decoration-line: none',
17
- 'border-radius: .25rem',
18
- 'box-shadow: 0 1px 2px 0 rgb(0 0 0 / 0.05)',
19
- 'text-align: center',
20
- 'font-size: 1.25rem',
21
- 'line-height: 1.75rem',
22
- 'color: white',
23
- 'margin-top: .5rem',
24
- 'margin-bottom: .75rem',
25
- 'padding: .75rem 1rem',
26
- 'display: flex',
27
- 'flex-wrap: nowrap',
28
- 'align-items: center',
29
- 'justify-content: space-evenly',
30
- 'cursor: pointer',
31
- 'text-transform: none',
32
- 'box-sizing: border-box',
33
- 'border-width: 0',
34
- 'border-style: solid',
35
- 'border-color: currentColor',
36
- ];
37
- export class PpPayment extends HTMLElement {
1
+ import { PpForm } from './PpForm.js';
2
+ import { mandatory, optional, single } from './validation.js';
3
+ const fields = {
4
+ amount: mandatory(single()),
5
+ metadata: mandatory(single()),
6
+ urn: mandatory(single()),
7
+ email: mandatory(single()),
8
+ note: optional(single()),
9
+ expiry: optional(single()),
10
+ 'constraints.minimum_card_amount': optional(single()),
11
+ };
12
+ export class PpPayment extends PpForm {
38
13
  constructor() {
39
- super();
40
- this.sr = this.attachShadow({ mode: 'open' });
41
- this.redrawContents();
42
- }
43
- redrawContents() {
44
- let base = this.base;
45
- while (base.slice(-1) === '/')
46
- base = base.slice(0, -1);
47
- if (base === '')
48
- base = 'https://pay.ponchopay.com';
49
- this.sr.replaceChildren();
50
- this.sr.appendChild(buildForm(`${base}${ENDPOINT}`, ...ATTRIBUTES.filter(name => this[name] !== '').map(name => buildHiddenInput(name, this[name])), buildStyle(`button { ${STYLES.join(';')} ${this.getAttribute('style')} } button:active { transform: translate(1px,1px); }`), buildButton(buildSlot('Pay with PonchoPay'))));
51
- }
52
- set base(value) {
53
- this.setAttribute('base', value);
54
- }
55
- get base() {
56
- var _a;
57
- return (_a = this.getAttribute('base')) !== null && _a !== void 0 ? _a : '';
58
- }
59
- set token(value) {
60
- this.setAttribute('token', value);
61
- }
62
- get token() {
63
- var _a;
64
- return (_a = this.getAttribute('token')) !== null && _a !== void 0 ? _a : '';
65
- }
66
- set metadata(value) {
67
- this.setAttribute('metadata', value);
68
- }
69
- get metadata() {
70
- var _a;
71
- return (_a = this.getAttribute('metadata')) !== null && _a !== void 0 ? _a : '';
72
- }
73
- set urn(value) {
74
- this.setAttribute('urn', value);
75
- }
76
- get urn() {
77
- var _a;
78
- return (_a = this.getAttribute('urn')) !== null && _a !== void 0 ? _a : '';
79
- }
80
- set amount(value) {
81
- this.setAttribute('amount', String(value));
82
- }
83
- get amount() {
84
- var _a;
85
- return (_a = this.getAttribute('amount')) !== null && _a !== void 0 ? _a : '';
86
- }
87
- set email(value) {
88
- this.setAttribute('email', value);
89
- }
90
- get email() {
91
- var _a;
92
- return (_a = this.getAttribute('email')) !== null && _a !== void 0 ? _a : '';
93
- }
94
- set note(value) {
95
- this.setAttribute('note', value);
96
- }
97
- get note() {
98
- var _a;
99
- return (_a = this.getAttribute('note')) !== null && _a !== void 0 ? _a : '';
100
- }
101
- set expiry(value) {
102
- this.setAttribute('expiry', value instanceof Date ? value.toISOString() : value);
103
- }
104
- get expiry() {
105
- var _a;
106
- return (_a = this.getAttribute('expiry')) !== null && _a !== void 0 ? _a : '';
107
- }
108
- attributeChangedCallback() {
109
- this.redrawContents();
14
+ super('/api/integration/generic/initiate', 'Pay with PonchoPay', fields);
110
15
  }
111
16
  static get observedAttributes() {
112
- return [...ATTRIBUTES, 'base'];
17
+ return [...PpForm.observedAttributes, ...Object.keys(fields)];
113
18
  }
114
19
  }
115
20
  //# sourceMappingURL=PpPayment.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"PpPayment.js","sourceRoot":"","sources":["../../src/PpPayment.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n buildButton,\n buildForm,\n buildHiddenInput,\n buildSlot,\n buildStyle,\n} from './utils';\n\nconst ENDPOINT = '/api/integration/generic/initiate';\nconst ATTRIBUTES = [\n 'token',\n 'metadata',\n 'urn',\n 'amount',\n 'email',\n 'note',\n 'expiry',\n] as const;\nconst STYLES = [\n 'width: 100%',\n 'background-color: #02C2A0',\n 'white-space: nowrap',\n 'text-decoration-line: none',\n 'border-radius: .25rem',\n 'box-shadow: 0 1px 2px 0 rgb(0 0 0 / 0.05)',\n 'text-align: center',\n 'font-size: 1.25rem',\n 'line-height: 1.75rem',\n 'color: white',\n 'margin-top: .5rem',\n 'margin-bottom: .75rem',\n 'padding: .75rem 1rem',\n 'display: flex',\n 'flex-wrap: nowrap',\n 'align-items: center',\n 'justify-content: space-evenly',\n 'cursor: pointer',\n 'text-transform: none',\n 'box-sizing: border-box',\n 'border-width: 0',\n 'border-style: solid',\n 'border-color: currentColor',\n];\n\nexport class PpPayment extends HTMLElement {\n private sr: ShadowRoot;\n\n public constructor() {\n super();\n\n this.sr = this.attachShadow({ mode: 'open' });\n this.redrawContents();\n }\n\n private redrawContents(): void {\n let base = this.base;\n while (base.slice(-1) === '/') base = base.slice(0, -1);\n if (base === '') base = 'https://pay.ponchopay.com';\n\n this.sr.replaceChildren();\n this.sr.appendChild(\n buildForm(\n `${base}${ENDPOINT}`,\n ...ATTRIBUTES.filter(name => this[name] !== '').map(name =>\n buildHiddenInput(name, this[name])\n ),\n buildStyle(\n `button { ${STYLES.join(';')} ${this.getAttribute(\n 'style'\n )} } button:active { transform: translate(1px,1px); }`\n ),\n buildButton(buildSlot('Pay with PonchoPay'))\n )\n );\n }\n\n public set base(value: string) {\n this.setAttribute('base', value);\n }\n\n public get base(): string {\n return this.getAttribute('base') ?? '';\n }\n\n public set token(value: string) {\n this.setAttribute('token', value);\n }\n\n public get token(): string {\n return this.getAttribute('token') ?? '';\n }\n\n public set metadata(value: string) {\n this.setAttribute('metadata', value);\n }\n\n public get metadata(): string {\n return this.getAttribute('metadata') ?? '';\n }\n\n public set urn(value: string) {\n this.setAttribute('urn', value);\n }\n\n public get urn(): string {\n return this.getAttribute('urn') ?? '';\n }\n\n public set amount(value: string | number) {\n this.setAttribute('amount', String(value));\n }\n\n public get amount(): string {\n return this.getAttribute('amount') ?? '';\n }\n\n public set email(value: string) {\n this.setAttribute('email', value);\n }\n\n public get email(): string {\n return this.getAttribute('email') ?? '';\n }\n\n public set note(value: string) {\n this.setAttribute('note', value);\n }\n\n public get note(): string {\n return this.getAttribute('note') ?? '';\n }\n\n public set expiry(value: Date | string) {\n this.setAttribute(\n 'expiry',\n value instanceof Date ? value.toISOString() : value\n );\n }\n\n public get expiry(): string {\n return this.getAttribute('expiry') ?? '';\n }\n\n public attributeChangedCallback(): void {\n this.redrawContents();\n }\n\n public static get observedAttributes() {\n return [...ATTRIBUTES, 'base'];\n }\n}\n"]}
1
+ {"version":3,"file":"PpPayment.js","sourceRoot":"","sources":["../../src/PpPayment.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AACrC,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,iBAAiB,CAAC;AAE9D,MAAM,MAAM,GAAG;IACb,MAAM,EAAE,SAAS,CAAC,MAAM,EAAE,CAAC;IAC3B,QAAQ,EAAE,SAAS,CAAC,MAAM,EAAE,CAAC;IAC7B,GAAG,EAAE,SAAS,CAAC,MAAM,EAAE,CAAC;IACxB,KAAK,EAAE,SAAS,CAAC,MAAM,EAAE,CAAC;IAC1B,IAAI,EAAE,QAAQ,CAAC,MAAM,EAAE,CAAC;IACxB,MAAM,EAAE,QAAQ,CAAC,MAAM,EAAE,CAAC;IAC1B,iCAAiC,EAAE,QAAQ,CAAC,MAAM,EAAE,CAAC;CACtD,CAAC;AAEF,MAAM,OAAO,SAAU,SAAQ,MAAM;IACnC;QACE,KAAK,CAAC,mCAAmC,EAAE,oBAAoB,EAAE,MAAM,CAAC,CAAC;IAC3E,CAAC;IAEM,MAAM,KAAK,kBAAkB;QAClC,OAAO,CAAC,GAAG,MAAM,CAAC,kBAAkB,EAAE,GAAG,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC;IAChE,CAAC;CACF","sourcesContent":["import { PpForm } from './PpForm.js';\nimport { mandatory, optional, single } from './validation.js';\n\nconst fields = {\n amount: mandatory(single()),\n metadata: mandatory(single()),\n urn: mandatory(single()),\n email: mandatory(single()),\n note: optional(single()),\n expiry: optional(single()),\n 'constraints.minimum_card_amount': optional(single()),\n};\n\nexport class PpPayment extends PpForm {\n public constructor() {\n super('/api/integration/generic/initiate', 'Pay with PonchoPay', fields);\n }\n\n public static get observedAttributes() {\n return [...PpForm.observedAttributes, ...Object.keys(fields)];\n }\n}\n"]}
@@ -0,0 +1,5 @@
1
+ import { PpForm } from './PpForm.js';
2
+ export declare class PpSubscription extends PpForm {
3
+ constructor();
4
+ static get observedAttributes(): string[];
5
+ }
@@ -0,0 +1,30 @@
1
+ import { PpForm } from './PpForm.js';
2
+ import { dependant, mandatory, multiple, optional, single, } from './validation.js';
3
+ const fields = {
4
+ amount: mandatory(single()),
5
+ metadata: mandatory(single()),
6
+ urn: mandatory(single()),
7
+ email: mandatory(single()),
8
+ note: optional(single()),
9
+ 'repetition.granularity': mandatory(single()),
10
+ 'repetition.period': mandatory(single()),
11
+ 'repetition.weekdays': dependant('repetition.granularity', 'weekly', multiple()),
12
+ 'repetition.day': dependant('repetition.granularity', 'monthly', single()),
13
+ 'ending.condition': optional(single()),
14
+ 'ending.occurrences': dependant('ending.condition', 'occurrences', single()),
15
+ 'ending.date': dependant('ending.condition', 'date', single()),
16
+ 'additional_one_time_payment.amount': optional(single()),
17
+ 'additional_one_time_payment.metadata': dependant('additional_one_time_payment.amount', true, single()),
18
+ 'additional_one_time_payment.note': optional(single()),
19
+ 'additional_one_time_payment.expiry': optional(single()),
20
+ 'additional_one_time_payment.constraints.minimum_card_amount': optional(single()),
21
+ };
22
+ export class PpSubscription extends PpForm {
23
+ constructor() {
24
+ super('/api/integration/generic/subscription/redirect', 'Subscribe with PonchoPay', fields);
25
+ }
26
+ static get observedAttributes() {
27
+ return [...PpForm.observedAttributes, ...Object.keys(fields)];
28
+ }
29
+ }
30
+ //# sourceMappingURL=PpSubscription.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"PpSubscription.js","sourceRoot":"","sources":["../../src/PpSubscription.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AACrC,OAAO,EACL,SAAS,EACT,SAAS,EACT,QAAQ,EACR,QAAQ,EACR,MAAM,GACP,MAAM,iBAAiB,CAAC;AAEzB,MAAM,MAAM,GAAG;IACb,MAAM,EAAE,SAAS,CAAC,MAAM,EAAE,CAAC;IAC3B,QAAQ,EAAE,SAAS,CAAC,MAAM,EAAE,CAAC;IAC7B,GAAG,EAAE,SAAS,CAAC,MAAM,EAAE,CAAC;IACxB,KAAK,EAAE,SAAS,CAAC,MAAM,EAAE,CAAC;IAC1B,IAAI,EAAE,QAAQ,CAAC,MAAM,EAAE,CAAC;IACxB,wBAAwB,EAAE,SAAS,CAAC,MAAM,EAAE,CAAC;IAC7C,mBAAmB,EAAE,SAAS,CAAC,MAAM,EAAE,CAAC;IACxC,qBAAqB,EAAE,SAAS,CAC9B,wBAAwB,EACxB,QAAQ,EACR,QAAQ,EAAE,CACX;IACD,gBAAgB,EAAE,SAAS,CAAC,wBAAwB,EAAE,SAAS,EAAE,MAAM,EAAE,CAAC;IAC1E,kBAAkB,EAAE,QAAQ,CAAC,MAAM,EAAE,CAAC;IACtC,oBAAoB,EAAE,SAAS,CAAC,kBAAkB,EAAE,aAAa,EAAE,MAAM,EAAE,CAAC;IAC5E,aAAa,EAAE,SAAS,CAAC,kBAAkB,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC;IAC9D,oCAAoC,EAAE,QAAQ,CAAC,MAAM,EAAE,CAAC;IACxD,sCAAsC,EAAE,SAAS,CAC/C,oCAAoC,EACpC,IAAI,EACJ,MAAM,EAAE,CACT;IACD,kCAAkC,EAAE,QAAQ,CAAC,MAAM,EAAE,CAAC;IACtD,oCAAoC,EAAE,QAAQ,CAAC,MAAM,EAAE,CAAC;IACxD,6DAA6D,EAAE,QAAQ,CACrE,MAAM,EAAE,CACT;CACF,CAAC;AAEF,MAAM,OAAO,cAAe,SAAQ,MAAM;IACxC;QACE,KAAK,CACH,gDAAgD,EAChD,0BAA0B,EAC1B,MAAM,CACP,CAAC;IACJ,CAAC;IAEM,MAAM,KAAK,kBAAkB;QAClC,OAAO,CAAC,GAAG,MAAM,CAAC,kBAAkB,EAAE,GAAG,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC;IAChE,CAAC;CACF","sourcesContent":["import { PpForm } from './PpForm.js';\nimport {\n dependant,\n mandatory,\n multiple,\n optional,\n single,\n} from './validation.js';\n\nconst fields = {\n amount: mandatory(single()),\n metadata: mandatory(single()),\n urn: mandatory(single()),\n email: mandatory(single()),\n note: optional(single()),\n 'repetition.granularity': mandatory(single()),\n 'repetition.period': mandatory(single()),\n 'repetition.weekdays': dependant(\n 'repetition.granularity',\n 'weekly',\n multiple()\n ),\n 'repetition.day': dependant('repetition.granularity', 'monthly', single()),\n 'ending.condition': optional(single()),\n 'ending.occurrences': dependant('ending.condition', 'occurrences', single()),\n 'ending.date': dependant('ending.condition', 'date', single()),\n 'additional_one_time_payment.amount': optional(single()),\n 'additional_one_time_payment.metadata': dependant(\n 'additional_one_time_payment.amount',\n true,\n single()\n ),\n 'additional_one_time_payment.note': optional(single()),\n 'additional_one_time_payment.expiry': optional(single()),\n 'additional_one_time_payment.constraints.minimum_card_amount': optional(\n single()\n ),\n};\n\nexport class PpSubscription extends PpForm {\n public constructor() {\n super(\n '/api/integration/generic/subscription/redirect',\n 'Subscribe with PonchoPay',\n fields\n );\n }\n\n public static get observedAttributes() {\n return [...PpForm.observedAttributes, ...Object.keys(fields)];\n }\n}\n"]}
package/dist/src/index.js CHANGED
@@ -1,5 +1,9 @@
1
1
  import { PpPayment } from './PpPayment.js';
2
+ import { PpSubscription } from './PpSubscription.js';
2
3
  if (!window.customElements.get('pp-payment')) {
3
4
  window.customElements.define('pp-payment', PpPayment);
4
5
  }
6
+ if (!window.customElements.get('pp-subscription')) {
7
+ window.customElements.define('pp-subscription', PpSubscription);
8
+ }
5
9
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAE3C,IAAI,CAAC,MAAM,CAAC,cAAc,CAAC,GAAG,CAAC,YAAY,CAAC,EAAE;IAC5C,MAAM,CAAC,cAAc,CAAC,MAAM,CAAC,YAAY,EAAE,SAAS,CAAC,CAAC;CACvD","sourcesContent":["import { PpPayment } from './PpPayment.js';\n\nif (!window.customElements.get('pp-payment')) {\n window.customElements.define('pp-payment', PpPayment);\n}\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAC3C,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAErD,IAAI,CAAC,MAAM,CAAC,cAAc,CAAC,GAAG,CAAC,YAAY,CAAC,EAAE;IAC5C,MAAM,CAAC,cAAc,CAAC,MAAM,CAAC,YAAY,EAAE,SAAS,CAAC,CAAC;CACvD;AAED,IAAI,CAAC,MAAM,CAAC,cAAc,CAAC,GAAG,CAAC,iBAAiB,CAAC,EAAE;IACjD,MAAM,CAAC,cAAc,CAAC,MAAM,CAAC,iBAAiB,EAAE,cAAc,CAAC,CAAC;CACjE","sourcesContent":["import { PpPayment } from './PpPayment.js';\nimport { PpSubscription } from './PpSubscription.js';\n\nif (!window.customElements.get('pp-payment')) {\n window.customElements.define('pp-payment', PpPayment);\n}\n\nif (!window.customElements.get('pp-subscription')) {\n window.customElements.define('pp-subscription', PpSubscription);\n}\n"]}
@@ -1,5 +1,13 @@
1
- export declare function buildHiddenInput(name: string, value: string): HTMLInputElement;
2
- export declare function buildForm(action: string, ...elements: HTMLElement[]): HTMLFormElement;
3
- export declare function buildSlot(fallback: HTMLElement[] | string): HTMLSlotElement;
4
- export declare function buildButton(children: HTMLElement): HTMLButtonElement;
5
- export declare function buildStyle(styles: string): HTMLStyleElement;
1
+ export type Maybe<T> = T | undefined;
2
+ /**
3
+ * Joins two paths with a single forward slash in the middle
4
+ */
5
+ export declare function joinPaths(left: string, right: string): string;
6
+ /**
7
+ * Prepares the property name for the API's format
8
+ */
9
+ export declare function formatName(name: string): string;
10
+ /**
11
+ * Splits a haystack by the needle. If the haystack is an empty string, it will return an empty array
12
+ */
13
+ export declare function split(haystack: string, needle: string): string[];
package/dist/src/utils.js CHANGED
@@ -1,27 +1,41 @@
1
- function buildElement(tag, props, children) {
2
- const element = document.createElement(tag);
3
- Object.entries(props !== null && props !== void 0 ? props : {}).forEach(([key, value]) => element.setAttribute(key, value));
4
- if (typeof children === 'string') {
5
- element.innerText = children;
6
- }
7
- else if (Array.isArray(children)) {
8
- children.forEach(element.appendChild.bind(element));
9
- }
10
- return element;
11
- }
12
- export function buildHiddenInput(name, value) {
13
- return buildElement('input', { type: 'hidden', name, value });
1
+ /**
2
+ * Clears the start of the string from any matching character
3
+ */
4
+ function trimStart(haystack, needle) {
5
+ const regex = new RegExp(`^[${needle}]+`);
6
+ return haystack.replace(regex, '');
14
7
  }
15
- export function buildForm(action, ...elements) {
16
- return buildElement('form', { action, method: 'post' }, elements);
8
+ /**
9
+ * Clears the end of the string from any matching character
10
+ */
11
+ function trimEnd(haystack, needle) {
12
+ const regex = new RegExp(`[${needle}]+$`);
13
+ return haystack.replace(regex, '');
17
14
  }
18
- export function buildSlot(fallback) {
19
- return buildElement('slot', {}, fallback);
15
+ /**
16
+ * Joins two paths with a single forward slash in the middle
17
+ */
18
+ export function joinPaths(left, right) {
19
+ return `${trimEnd(left, '/')}/${trimStart(right, '/')}`;
20
20
  }
21
- export function buildButton(children) {
22
- return buildElement('button', { type: 'submit' }, [children]);
21
+ /**
22
+ * Prepares the property name for the API's format
23
+ */
24
+ export function formatName(name) {
25
+ const [root, ...path] = name.split('.');
26
+ let properties = '';
27
+ if (path.length > 0) {
28
+ properties = `[${path.join('][')}]`;
29
+ }
30
+ return `${root}${properties}`;
23
31
  }
24
- export function buildStyle(styles) {
25
- return buildElement('style', {}, styles);
32
+ /**
33
+ * Splits a haystack by the needle. If the haystack is an empty string, it will return an empty array
34
+ */
35
+ export function split(haystack, needle) {
36
+ if (haystack.length === 0) {
37
+ return [];
38
+ }
39
+ return haystack.split(needle);
26
40
  }
27
41
  //# sourceMappingURL=utils.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"utils.js","sourceRoot":"","sources":["../../src/utils.ts"],"names":[],"mappings":"AAAA,SAAS,YAAY,CACnB,GAAS,EACT,KAA4C,EAC5C,QAAiC;IAEjC,MAAM,OAAO,GAAG,QAAQ,CAAC,aAAa,CAAC,GAAG,CAAC,CAAC;IAC5C,MAAM,CAAC,OAAO,CAAC,KAAK,aAAL,KAAK,cAAL,KAAK,GAAI,EAAE,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,EAAE,KAAK,CAAC,EAAE,EAAE,CACnD,OAAO,CAAC,YAAY,CAAC,GAAG,EAAE,KAAK,CAAC,CACjC,CAAC;IACF,IAAI,OAAO,QAAQ,KAAK,QAAQ,EAAE;QAChC,OAAO,CAAC,SAAS,GAAG,QAAQ,CAAC;KAC9B;SAAM,IAAI,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE;QAClC,QAAQ,CAAC,OAAO,CAAC,OAAO,CAAC,WAAW,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC;KACrD;IACD,OAAO,OAAO,CAAC;AACjB,CAAC;AAED,MAAM,UAAU,gBAAgB,CAC9B,IAAY,EACZ,KAAa;IAEb,OAAO,YAAY,CAAC,OAAO,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;AAChE,CAAC;AAED,MAAM,UAAU,SAAS,CACvB,MAAc,EACd,GAAG,QAAuB;IAE1B,OAAO,YAAY,CAAC,MAAM,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,EAAE,QAAQ,CAAC,CAAC;AACpE,CAAC;AAED,MAAM,UAAU,SAAS,CAAC,QAAgC;IACxD,OAAO,YAAY,CAAC,MAAM,EAAE,EAAE,EAAE,QAAQ,CAAC,CAAC;AAC5C,CAAC;AAED,MAAM,UAAU,WAAW,CAAC,QAAqB;IAC/C,OAAO,YAAY,CAAC,QAAQ,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAC;AAChE,CAAC;AAED,MAAM,UAAU,UAAU,CAAC,MAAc;IACvC,OAAO,YAAY,CAAC,OAAO,EAAE,EAAE,EAAE,MAAM,CAAC,CAAC;AAC3C,CAAC","sourcesContent":["function buildElement<TTag extends keyof HTMLElementTagNameMap>(\n tag: TTag,\n props?: Partial<HTMLElementTagNameMap[TTag]>,\n children?: HTMLElement[] | string\n): HTMLElementTagNameMap[TTag] {\n const element = document.createElement(tag);\n Object.entries(props ?? {}).forEach(([key, value]) =>\n element.setAttribute(key, value)\n );\n if (typeof children === 'string') {\n element.innerText = children;\n } else if (Array.isArray(children)) {\n children.forEach(element.appendChild.bind(element));\n }\n return element;\n}\n\nexport function buildHiddenInput(\n name: string,\n value: string\n): HTMLInputElement {\n return buildElement('input', { type: 'hidden', name, value });\n}\n\nexport function buildForm(\n action: string,\n ...elements: HTMLElement[]\n): HTMLFormElement {\n return buildElement('form', { action, method: 'post' }, elements);\n}\n\nexport function buildSlot(fallback: HTMLElement[] | string): HTMLSlotElement {\n return buildElement('slot', {}, fallback);\n}\n\nexport function buildButton(children: HTMLElement): HTMLButtonElement {\n return buildElement('button', { type: 'submit' }, [children]);\n}\n\nexport function buildStyle(styles: string): HTMLStyleElement {\n return buildElement('style', {}, styles);\n}\n"]}
1
+ {"version":3,"file":"utils.js","sourceRoot":"","sources":["../../src/utils.ts"],"names":[],"mappings":"AAEA;;GAEG;AACH,SAAS,SAAS,CAAC,QAAgB,EAAE,MAAc;IACjD,MAAM,KAAK,GAAG,IAAI,MAAM,CAAC,KAAK,MAAM,IAAI,CAAC,CAAC;IAC1C,OAAO,QAAQ,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;AACrC,CAAC;AAED;;GAEG;AACH,SAAS,OAAO,CAAC,QAAgB,EAAE,MAAc;IAC/C,MAAM,KAAK,GAAG,IAAI,MAAM,CAAC,IAAI,MAAM,KAAK,CAAC,CAAC;IAC1C,OAAO,QAAQ,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;AACrC,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,SAAS,CAAC,IAAY,EAAE,KAAa;IACnD,OAAO,GAAG,OAAO,CAAC,IAAI,EAAE,GAAG,CAAC,IAAI,SAAS,CAAC,KAAK,EAAE,GAAG,CAAC,EAAE,CAAC;AAC1D,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,UAAU,CAAC,IAAY;IACrC,MAAM,CAAC,IAAI,EAAE,GAAG,IAAI,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IACxC,IAAI,UAAU,GAAG,EAAE,CAAC;IACpB,IAAI,IAAI,CAAC,MAAM,GAAG,CAAC,EAAE;QACnB,UAAU,GAAG,IAAI,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC;KACrC;IAED,OAAO,GAAG,IAAI,GAAG,UAAU,EAAE,CAAC;AAChC,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,KAAK,CAAC,QAAgB,EAAE,MAAc;IACpD,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC,EAAE;QACzB,OAAO,EAAE,CAAC;KACX;IAED,OAAO,QAAQ,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;AAChC,CAAC","sourcesContent":["export type Maybe<T> = T | undefined;\n\n/**\n * Clears the start of the string from any matching character\n */\nfunction trimStart(haystack: string, needle: string): string {\n const regex = new RegExp(`^[${needle}]+`);\n return haystack.replace(regex, '');\n}\n\n/**\n * Clears the end of the string from any matching character\n */\nfunction trimEnd(haystack: string, needle: string): string {\n const regex = new RegExp(`[${needle}]+$`);\n return haystack.replace(regex, '');\n}\n\n/**\n * Joins two paths with a single forward slash in the middle\n */\nexport function joinPaths(left: string, right: string): string {\n return `${trimEnd(left, '/')}/${trimStart(right, '/')}`;\n}\n\n/**\n * Prepares the property name for the API's format\n */\nexport function formatName(name: string): string {\n const [root, ...path] = name.split('.');\n let properties = '';\n if (path.length > 0) {\n properties = `[${path.join('][')}]`;\n }\n\n return `${root}${properties}`;\n}\n\n/**\n * Splits a haystack by the needle. If the haystack is an empty string, it will return an empty array\n */\nexport function split(haystack: string, needle: string): string[] {\n if (haystack.length === 0) {\n return [];\n }\n\n return haystack.split(needle);\n}\n"]}
@@ -0,0 +1,37 @@
1
+ /**
2
+ * Collection: Whether the attribute is expected to have comma-separated values ot nor.
3
+ * - false: Single
4
+ * - true: Multiple
5
+ *
6
+ * Required: Whether the attribute is required to submit the form or not.
7
+ * - false: Optional
8
+ * - true: Mandatory
9
+ * - [string, string | true]: Mandatory if the attribute in the first index is set. If the second
10
+ * is a string, it also needs to match that value. Optional otherwise.
11
+ */
12
+ export type Field = {
13
+ collection: boolean;
14
+ required: boolean | [string, string | true];
15
+ };
16
+ /**
17
+ * Marks the attribute as representing a single value.
18
+ * Note: By default it makes the attribute optional. Use the other functions to change this.
19
+ */
20
+ export declare function single(): Field;
21
+ /**
22
+ * Marks the attribute as representing multiple values.
23
+ * Note: By default it makes the attribute optional. Use the other functions to change this.
24
+ */
25
+ export declare function multiple(): Field;
26
+ /**
27
+ * Marks the attribute as mandatory.
28
+ */
29
+ export declare function mandatory(attribute: Field): Field;
30
+ /**
31
+ * Marks the attribute as optional.
32
+ */
33
+ export declare function optional(attribute: Field): Field;
34
+ /**
35
+ * Marks the attribute's requirement as dependant on another attribute's existance.
36
+ */
37
+ export declare function dependant(name: string, value: string | true, attribute: Field): Field;
@@ -0,0 +1,33 @@
1
+ /**
2
+ * Marks the attribute as representing a single value.
3
+ * Note: By default it makes the attribute optional. Use the other functions to change this.
4
+ */
5
+ export function single() {
6
+ return { required: false, collection: false };
7
+ }
8
+ /**
9
+ * Marks the attribute as representing multiple values.
10
+ * Note: By default it makes the attribute optional. Use the other functions to change this.
11
+ */
12
+ export function multiple() {
13
+ return { required: false, collection: true };
14
+ }
15
+ /**
16
+ * Marks the attribute as mandatory.
17
+ */
18
+ export function mandatory(attribute) {
19
+ return { ...attribute, required: true };
20
+ }
21
+ /**
22
+ * Marks the attribute as optional.
23
+ */
24
+ export function optional(attribute) {
25
+ return { ...attribute, required: false };
26
+ }
27
+ /**
28
+ * Marks the attribute's requirement as dependant on another attribute's existance.
29
+ */
30
+ export function dependant(name, value, attribute) {
31
+ return { ...attribute, required: [name, value] };
32
+ }
33
+ //# sourceMappingURL=validation.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"validation.js","sourceRoot":"","sources":["../../src/validation.ts"],"names":[],"mappings":"AAgBA;;;GAGG;AACH,MAAM,UAAU,MAAM;IACpB,OAAO,EAAE,QAAQ,EAAE,KAAK,EAAE,UAAU,EAAE,KAAK,EAAE,CAAC;AAChD,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,QAAQ;IACtB,OAAO,EAAE,QAAQ,EAAE,KAAK,EAAE,UAAU,EAAE,IAAI,EAAE,CAAC;AAC/C,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,SAAS,CAAC,SAAgB;IACxC,OAAO,EAAE,GAAG,SAAS,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC;AAC1C,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,QAAQ,CAAC,SAAgB;IACvC,OAAO,EAAE,GAAG,SAAS,EAAE,QAAQ,EAAE,KAAK,EAAE,CAAC;AAC3C,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,SAAS,CACvB,IAAY,EACZ,KAAoB,EACpB,SAAgB;IAEhB,OAAO,EAAE,GAAG,SAAS,EAAE,QAAQ,EAAE,CAAC,IAAI,EAAE,KAAK,CAAC,EAAE,CAAC;AACnD,CAAC","sourcesContent":["/**\n * Collection: Whether the attribute is expected to have comma-separated values ot nor.\n * - false: Single\n * - true: Multiple\n *\n * Required: Whether the attribute is required to submit the form or not.\n * - false: Optional\n * - true: Mandatory\n * - [string, string | true]: Mandatory if the attribute in the first index is set. If the second\n * is a string, it also needs to match that value. Optional otherwise.\n */\nexport type Field = {\n collection: boolean;\n required: boolean | [string, string | true];\n};\n\n/**\n * Marks the attribute as representing a single value.\n * Note: By default it makes the attribute optional. Use the other functions to change this.\n */\nexport function single(): Field {\n return { required: false, collection: false };\n}\n\n/**\n * Marks the attribute as representing multiple values.\n * Note: By default it makes the attribute optional. Use the other functions to change this.\n */\nexport function multiple(): Field {\n return { required: false, collection: true };\n}\n\n/**\n * Marks the attribute as mandatory.\n */\nexport function mandatory(attribute: Field): Field {\n return { ...attribute, required: true };\n}\n\n/**\n * Marks the attribute as optional.\n */\nexport function optional(attribute: Field): Field {\n return { ...attribute, required: false };\n}\n\n/**\n * Marks the attribute's requirement as dependant on another attribute's existance.\n */\nexport function dependant(\n name: string,\n value: string | true,\n attribute: Field\n): Field {\n return { ...attribute, required: [name, value] };\n}\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ponchopay/pp-browser",
3
- "version": "1.1.0",
3
+ "version": "1.2.0",
4
4
  "description": "Tools to integrate PonchoPay on the browser",
5
5
  "type": "module",
6
6
  "main": "dist/src/index.js",
@@ -22,29 +22,30 @@
22
22
  ],
23
23
  "scripts": {
24
24
  "clean": "rimraf build dist",
25
- "start": "npm run clean && tsc && concurrently -k -r \"tsc --watch --preserveWatchOutput\" \"wds\"",
25
+ "start": "npm run clean && tsc --outDir example/dist && concurrently -k -r \"tsc --watch --preserveWatchOutput --outDir example/dist\" \"vite --open\"",
26
26
  "build": "npm run clean && tsc && rollup -c",
27
- "test": "playwright test",
27
+ "test": "vitest run",
28
28
  "lint": "eslint --ext .ts,.html . --ignore-path .gitignore && prettier \"**/*.ts\" --check --ignore-path .gitignore",
29
29
  "format": "eslint --ext .ts,.html . --fix --ignore-path .gitignore && prettier \"**/*.ts\" --write --ignore-path .gitignore"
30
30
  },
31
31
  "devDependencies": {
32
32
  "@open-wc/eslint-config": "^9.2.1",
33
- "@playwright/test": "^1.38.0",
34
33
  "@rollup/plugin-terser": "^0.4.3",
35
34
  "@typescript-eslint/eslint-plugin": "^5.48.0",
36
35
  "@typescript-eslint/parser": "^5.48.0",
37
- "@web/dev-server": "^0.1.34",
38
36
  "concurrently": "^5.3.0",
39
37
  "eslint": "^8.31.0",
40
38
  "eslint-config-prettier": "^8.3.0",
41
39
  "husky": "^4.3.8",
40
+ "jsdom": "^26.0.0",
42
41
  "lint-staged": "^10.5.4",
43
42
  "prettier": "^2.4.1",
44
43
  "rimraf": "^5.0.1",
45
44
  "rollup": "^3.29.0",
46
45
  "tslib": "^2.3.1",
47
- "typescript": "^4.5.2"
46
+ "typescript": "^4.5.2",
47
+ "vite": "^6.2.6",
48
+ "vitest": "^3.1.1"
48
49
  },
49
50
  "repository": {
50
51
  "type": "git",
@@ -78,7 +79,9 @@
78
79
  "error"
79
80
  ],
80
81
  "import/no-unresolved": "off",
81
- "import/extensions": "off"
82
+ "import/extensions": "off",
83
+ "lines-between-class-members": "off",
84
+ "wc/no-constructor-params": "off"
82
85
  }
83
86
  },
84
87
  "prettier": {