skyflow-js 2.6.0 → 2.7.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
@@ -1458,7 +1458,7 @@ Properties your provided when you created the element remain the same until you
1458
1458
  ### End to end example
1459
1459
  ```javascript
1460
1460
  // Create a collect container.
1461
- const collectContainer = skyflow.container(Skyflow.ContainerType.COLLECT);
1461
+ const collectContainer = skyflowClient.container(Skyflow.ContainerType.COLLECT);
1462
1462
 
1463
1463
  const stylesOptions = {
1464
1464
  inputStyles: {
@@ -1540,853 +1540,2375 @@ cardNumberElement.update({
1540
1540
 
1541
1541
  ---
1542
1542
 
1543
- # Securely collecting data client-side using Composable Elements
1544
-
1545
- Composable Elements combine multiple Skyflow Elements in a single iframe, letting you create multiple Skyflow Elements in a single row. The following steps create a composable element and securely collect data through it.
1546
-
1547
- ### Step 1: Create a composable container
1548
-
1549
- Create a container for the composable element using the `container(Skyflow.ContainerType)` method of the Skyflow client:
1550
-
1551
- ``` javascript
1552
- const collectContainer = skyflow.container(Skyflow.ContainerType.COMPOSABLE,containerOptions);
1553
- ```
1554
- The container requires an options object that contains the following keys:
1555
1543
 
1556
- 1. `layout`: An array that indicates the number of rows in the container and the number of elements in each row. The index value of the array defines the number of rows, and each value in the array represents the number of elements in that row, in order.
1557
-
1558
- For example: `[2,1]` means the container has two rows, with two elements in the first row and one element in the second row.
1544
+ ## Using Skyflow File Element to upload a file
1559
1545
 
1560
- `Note`: The sum of values in the layout array should be equal to the number of elements created
1546
+ You can upload binary files to a vault using the Skyflow File Element. Use the following steps to securely upload a file.
1547
+ ### Step 1: Create a container
1561
1548
 
1562
- 2. `styles`: CSS styles to apply to the composable container.
1563
- 3. `errorTextStyles`: CSS styles to apply if an error is encountered.
1549
+ Create a container for the form elements using the container(Skyflow.ContainerType) method of the Skyflow client:
1564
1550
 
1565
1551
  ```javascript
1566
- const options = {
1567
- layout: [2, 1], // Required
1568
- styles: { // Optional
1569
- base: {
1570
- border: '1px solid #DFE3EB',
1571
- padding: '8px',
1572
- borderRadius: '4px',
1573
- margin: '12px 2px',
1574
- },
1575
- },
1576
- errorTextStyles: { // Optional
1577
- base: {
1578
- color: 'red',
1579
- fontFamily: '"Roboto", sans-serif'
1580
- },
1581
- global: {
1582
- '@import': 'url("https://fonts.googleapis.com/css2?family=Roboto&display=swap")',
1583
- }
1584
- },
1585
- };
1552
+ const container = skyflowClient.container(Skyflow.ContainerType.COLLECT)
1586
1553
  ```
1587
1554
 
1588
- ### Step 2: Create Composable Elements
1589
- Composable Elements use the following schema:
1555
+ ### Step 2: Create a File Element
1556
+
1557
+ Skyflow Collect Elements are defined as follows:
1590
1558
 
1591
1559
  ```javascript
1592
- const composableElement = {
1593
- table: 'string', // Required. The table this data belongs to.
1594
- column: 'string', // Required. The column this data belongs to.
1595
- type: Skyflow.ElementType, // Skyflow.ElementType enum.
1596
- inputStyles: {}, // Optional. Styles applied to the form element.
1597
- labelStyles: {}, // Optional. Styles for the label of the collect element.
1598
- errorTextStyles: {}, // Optional. Styles for the errorText of the collect element.
1599
- label: 'string', // Optional. Label for the form element.
1600
- placeholder: 'string', // Optional. Placeholder for the form element.
1601
- altText: 'string', // (DEPRECATED) Initial value for the collect element.
1602
- validations: [], // Optional. Array of validation rules.
1560
+ const collectElement = {
1561
+ type: Skyflow.ElementType.FILE_INPUT, // Skyflow.ElementType enum.
1562
+ table: 'string', // The table this data belongs to.
1563
+ column: 'string', // The column into which this data should be inserted.
1564
+ skyflowID: 'string', // The skyflow_id of the record.
1565
+ inputStyles: {}, // Optional, styles that should be applied to the form element.
1566
+ labelStyles: {}, // Optional, styles that will be applied to the label of the collect element.
1567
+ errorTextStyles:{}, // Optional, styles that will be applied to the errorText of the collect element.
1603
1568
  }
1604
1569
  ```
1605
- The `table` and `column` fields indicate which table and column in the vault the Element correspond to.
1606
-
1607
- Note: Use dot-delimited strings to specify columns nested inside JSON fields (for example, `address.street.line1`).
1570
+ The `table` and `column` fields indicate which table and column the Element corresponds to.
1608
1571
 
1609
- All elements can be styled with [JSS](https://cssinjs.org/?v=v10.7.1) syntax.
1572
+ `skyflowID` indicates the record that stores the file.
1610
1573
 
1611
- The `inputStyles` field accepts an object of CSS properties to apply to the form element in the following states:
1574
+ **Notes**:
1575
+ - `skyflowID` is required while creating File element
1576
+ - Use period-delimited strings to specify columns nested inside JSON fields (e.g. `address.street.line1`).
1612
1577
 
1613
- * `base`: all variants inherit from these styles
1614
- * `complete`: applied when the Element has valid input
1615
- * `empty`: applied when the Element has no input
1616
- * `focus`: applied when the Element has focus
1617
- * `invalid`: applied when the Element has invalid input
1618
- * `cardIcon`: applied to the card type icon in CARD_NUMBER Element
1619
- * `copyIcon`: applied to copy icon in Elements when enableCopy option is true
1620
- * `global`: used for global styles like font-family.
1578
+ ### Step 3: Mount elements to the DOM
1621
1579
 
1622
- An example of an `inputStyles` object:
1580
+ To specify where to render Elements on your page, create placeholder `<div>` elements with unique `id` tags. For instance, the form below has an empty div with a unique id as a placeholder for a Skyflow Element.
1623
1581
 
1624
- ```javascript
1625
- inputStyles: {
1626
- base: {
1627
- border: '1px solid #eae8ee',
1628
- padding: '10px 16px',
1629
- borderRadius: '4px',
1630
- color: '#1d1d1d',
1631
- fontFamily: '"Roboto", sans-serif'
1632
- },
1633
- complete: {
1634
- color: '#4caf50',
1635
- },
1636
- empty: {},
1637
- focus: {},
1638
- invalid: {
1639
- color: '#f44336',
1640
- },
1641
- cardIcon: {
1642
- position: 'absolute',
1643
- left: '8px',
1644
- bottom: 'calc(50% - 12px)',
1645
- },
1646
- copyIcon: {
1647
- position: 'absolute',
1648
- right: '8px',
1649
- },
1650
- global: {
1651
- '@import': 'url("https://fonts.googleapis.com/css2?family=Roboto&display=swap")',
1652
- }
1653
- }
1582
+ ```html
1583
+ <form>
1584
+ <div id="file"/>
1585
+ <br/>
1586
+ <button type="submit">Submit</button>
1587
+ </form>
1654
1588
  ```
1655
- The states that are available for `labelStyles` are `base`, `focus`, `global`.
1656
- * requiredAsterisk: styles applied for the Asterisk symbol in the label.
1657
1589
 
1658
- An example `labelStyles` object:
1590
+ Now, when the `mount(domElement)` method of the Element is called, the Element is inserted in the specified div. For instance, the call below inserts the Element into the div with the id "#file".
1659
1591
 
1660
1592
  ```javascript
1661
- labelStyles: {
1662
- base: {
1663
- fontSize: '12px',
1664
- fontWeight: 'bold',
1665
- fontFamily: '"Roboto", sans-serif'
1666
- },
1667
- focus: {
1668
- color: '#1d1d1d'
1669
- },
1670
- global: {
1671
- '@import' :'url("https://fonts.googleapis.com/css2?family=Roboto&display=swap")',
1672
- }
1673
- }
1593
+ element.mount('#file');
1674
1594
  ```
1675
-
1676
- The JS SDK supports the following composable elements:
1677
-
1678
- - `CARDHOLDER_NAME`
1679
- - `CARD_NUMBER`
1680
- - `EXPIRATION_DATE`
1681
- - `EXPIRATION_MONTH`
1682
- - `EXPIRATION_YEAR`
1683
- - `CVV`
1684
- - `INPUT_FIELD`
1685
- - `PIN`
1686
-
1687
- `Note`: Only when the entered value in the below composable elements is valid, the focus shifts automatically. The element types are:
1688
- - `CARD_NUMBER`
1689
- - `EXPIRATION_DATE`
1690
- - `EXPIRATION_MONTH`
1691
- - `EXPIRATION_YEAR`
1692
-
1693
- The `INPUT_FIELD` type is a custom UI element without any built-in validations. For information on validations, see [validations](#validations).
1694
-
1695
- Along with the Composable Element definition, you can define additional options for the element:
1595
+ Use the `unmount` method to reset a Collect Element to its initial state.
1696
1596
 
1697
1597
  ```javascript
1698
- const options = {
1699
- required: false, // Optional, indicates whether the field is marked as required. Defaults to 'false'
1700
- enableCardIcon: true, // Optional, indicates whether card icon should be enabled (only applicable for CARD_NUMBER ElementType)
1701
- format: String, // Optional, format for the element (only applicable currently for EXPIRATION_DATE ElementType),
1702
- enableCopy: false // Optional, enables the copy icon in collect and reveal elements to copy text to clipboard. Defaults to 'false')
1703
- }
1598
+ element.unmount();
1704
1599
  ```
1600
+ ### Step 4: Collect data from elements
1705
1601
 
1706
- - `required`: Whether or not the field is marked as required. Defaults to `false`.
1707
- - `enableCardIcon`: Whether or not the icon is visible for the CARD_NUMBER element. Defaults to `true`.
1708
- - `format`: Format pattern for the element. Only applicable to EXPIRATION_DATE and EXPIRATION_YEAR element types.
1709
- - `enableCopy`: Whether or not the copy icon is visible in collect and reveal elements. Defaults to `false`.
1602
+ When you're ready to upload the file, call the `uploadFiles()` method on the container object.
1710
1603
 
1711
- The accepted `EXPIRATION_DATE` values are
1604
+ ```javascript
1605
+ container.uploadFiles();
1606
+ ```
1607
+ ### File upload limitations:
1712
1608
 
1713
- - `MM/YY` (default)
1714
- - `MM/YYYY`
1715
- - `YY/MM`
1716
- - `YYYY/MM`
1609
+ - Only non-executable file are allowed to be uploaded.
1610
+ - Files must have a maximum size of 32 MB
1611
+ - File columns can't enable tokenization, redaction, or arrays.
1612
+ - Re-uploading a file overwrites previously uploaded data.
1613
+ - Partial uploads or resuming a previous upload isn't supported.
1717
1614
 
1615
+ ### End-to-end file upload
1718
1616
 
1719
- The accepted `EXPIRATION_YEAR` values are
1617
+ ```javascript
1618
+ // Step 1.
1619
+ const container = skyflowClient.container(Skyflow.ContainerType.COLLECT);
1720
1620
 
1721
- - `YY` (default)
1722
- - `YYYY`
1621
+ // Step 2.
1622
+ const element = container.create({
1623
+ table: 'pii_fields',
1624
+ column: 'file',
1625
+ skyflowID: '431eaa6c-5c15-4513-aa15-29f50babe882',
1626
+ inputstyles: {
1627
+ base: {
1628
+ color: '#1d1d1d',
1629
+ },
1630
+ },
1631
+ labelStyles: {
1632
+ base: {
1633
+ fontSize: '12px',
1634
+ fontWeight: 'bold',
1635
+ },
1636
+ },
1637
+ errorTextStyles: {
1638
+ base: {
1639
+ color: '#f44336',
1640
+ },
1641
+ },
1642
+ type: Skyflow.ElementType.FILE_INPUT,
1643
+ });
1723
1644
 
1645
+ // Step 3.
1646
+ element.mount('#file'); // Assumes there is a div with id='#file' in the webpage.
1724
1647
 
1725
- Once you define the Element object and options, add it to the container using the `create(element, options)` method:
1648
+ // Step 4.
1649
+ container.uploadFiles();
1650
+ ```
1726
1651
 
1652
+ **Sample Response :**
1727
1653
  ```javascript
1728
- const composableElement = {
1729
- table: 'string', // Required, the table this data belongs to.
1730
- column: 'string', // Required, the column into which this data should be inserted.
1731
- type: Skyflow.ElementType, // Skyflow.ElementType enum.
1732
- inputStyles: {}, // Optional, styles that should be applied to the form element.
1733
- labelStyles: {}, // Optional, styles that will be applied to the label of the collect element.
1734
- errorTextStyles: {}, // Optional, styles that will be applied to the errorText of the collect element.
1735
- label: 'string', // Optional, label for the form element.
1736
- placeholder: 'string', // Optional, placeholder for the form element.
1737
- altText: 'string', // (DEPRECATED) string that acts as an initial value for the collect element.
1738
- validations: [], // Optional, array of validation rules.
1654
+ {
1655
+ fileUploadResponse: [
1656
+ {
1657
+ "skyflow_id": "431eaa6c-5c15-4513-aa15-29f50babe882"
1658
+ }
1659
+ ]
1739
1660
  }
1661
+ ```
1662
+ ### File upload with options:
1740
1663
 
1664
+ Along with fileElementInput, you can define other options in the Options object as described below:
1665
+ ```js
1741
1666
  const options = {
1742
- required: false, // Optional, indicates whether the field is marked as required. Defaults to 'false'.
1743
- enableCardIcon: true, // Optional, indicates whether card icon should be enabled (only applicable for CARD_NUMBER ElementType).
1744
- format: String, // Optional, format for the element (only applicable currently for EXPIRATION_DATE ElementType).
1745
- enableCopy: false, // Optional, enables the copy icon in collect and reveal elements to copy text to clipboard. Defaults to 'false').
1746
- };
1747
-
1748
- const element = container.create(composableElement, options);
1667
+ allowedFileType: String[], // Optional, indicates the allowed file types for upload
1668
+ }
1749
1669
  ```
1670
+ `allowedFileType`: An array of string value that indicates the allowedFileTypes to be uploaded.
1750
1671
 
1751
- ### Step 3: Mount Container to the DOM
1752
-
1753
-
1754
- To specify where the Elements are rendered on your page, create a placeholder `<div>` element with unique `id` attribute. Use this empty `<div>` placeholder to mount the composable container.
1672
+ #### File upload with options example
1755
1673
 
1756
1674
  ```javascript
1757
- <form>
1758
- <div id="composableContainer"/>
1759
- <br/>
1760
- <div id="button-id"/>
1761
- <button type="submit">Submit</button>
1762
- </form>
1763
- ```
1764
- Use the composable container's `mount(domElement)` method to insert the container's Elements into the specified `<div>`. For instance, the following call inserts Elements into the `<div>` with the `id "#composableContainer"`.
1765
-
1766
- ```javacript
1767
- container.mount('#composableContainer');
1768
- ```
1675
+ // Create collect Container.
1676
+ const collectContainer = skyflowClient.container(Skyflow.ContainerType.COLLECT);
1769
1677
 
1770
- ### Step 4: Collect data from elements
1678
+ // Create collect elements.
1679
+ const cardNumberElement = collectContainer.create({
1680
+ table: 'newTable',
1681
+ column: 'card_number',
1682
+ inputstyles: {
1683
+ base: {
1684
+ color: '#1d1d1d',
1685
+ },
1686
+ },
1687
+ labelStyles: {
1688
+ base: {
1689
+ fontSize: '12px',
1690
+ fontWeight: 'bold',
1691
+ },
1692
+ },
1693
+ errorTextStyles: {
1694
+ base: {
1695
+ color: '#f44336',
1696
+ },
1697
+ },
1698
+ placeholder: 'card number',
1699
+ label: 'Card Number',
1700
+ type: Skyflow.ElementType.CARD_NUMBER,
1701
+ });
1702
+ const options = {
1703
+ allowedFileType: [".pdf",".png"];
1704
+ };
1705
+ const fileElement = collectContainer.create({
1706
+ table: 'newTable',
1707
+ column: 'file',
1708
+ skyflowID: '431eaa6c-5c15-4513-aa15-29f50babe882',
1709
+ inputstyles: {
1710
+ base: {
1711
+ color: '#1d1d1d',
1712
+ },
1713
+ },
1714
+ labelStyles: {
1715
+ base: {
1716
+ fontSize: '12px',
1717
+ fontWeight: 'bold',
1718
+ },
1719
+ },
1720
+ errorTextStyles: {
1721
+ base: {
1722
+ color: '#f44336',
1723
+ },
1724
+ },
1725
+ type: Skyflow.ElementType.FILE_INPUT,
1726
+ },
1727
+ options
1728
+ );
1771
1729
 
1730
+ // Mount the elements.
1731
+ cardNumberElement.mount('#collectCardNumber');
1732
+ fileElement.mount('#collectFile');
1772
1733
 
1773
- When the form is ready to be submitted, call the container's `collect(options?)` method. The options parameter takes an object of optional parameters as follows:
1774
- - `tokens`: Whether or not tokens for the collected data are returned. Defaults to 'true'
1775
- - `additionalFields`: Non-PCI elements data to insert into the vault, specified in the records object format.
1776
- - `upsert`: To support upsert operations, the table containing the data and a column marked as unique in that table.
1734
+ // Collect and upload methods.
1735
+ collectContainer.collect({});
1736
+ collectContainer.uploadFiles();
1777
1737
 
1738
+ ```
1739
+ **Sample Response for collect():**
1778
1740
  ```javascript
1779
- const options = {
1780
- tokens: true, // Optional, indicates whether tokens for the collected data should be returned. Defaults to 'true'.
1781
- additionalFields: {
1782
- records: [
1783
- {
1784
- table: 'string', // Table into which record should be inserted.
1785
- fields: {
1786
- column1: 'value', // Column names should match vault column names.
1787
- // ...additional fields here.
1788
- },
1789
- },
1790
- // ...additional records here.
1791
- ],
1792
- }, // Optional
1793
- upsert: [ // Upsert operations support in the vault
1741
+ {
1742
+ "records": [
1794
1743
  {
1795
- table: 'string', // Table name
1796
- column: 'value', // Unique column in the table
1797
- },
1798
- ], // Optional
1799
- };
1744
+ "table": "newTable",
1745
+ "fields": {
1746
+ "card_number": "f3907186-e7e2-466f-91e5-48e12c2bcbc1",
1747
+ }
1748
+ }
1749
+ ]
1750
+ }
1800
1751
  ```
1801
-
1802
- ### End to end example of collecting data with Composable Elements
1752
+ **Sample Response for file uploadFiles() :**
1753
+ ```javascript
1754
+ {
1755
+ "fileUploadResponse": [
1756
+ {
1757
+ "skyflow_id": "431eaa6c-5c15-4513-aa15-29f50babe882"
1758
+ }
1759
+ ]
1760
+ }
1761
+ ```
1762
+ #### File upload with additional elements
1803
1763
 
1804
1764
  ```javascript
1805
- // Step 1
1806
- const containerOptions = {
1807
- layout: [2, 1],
1808
- styles: {
1765
+ // Create collect Container.
1766
+ const collectContainer = skyflowClient.container(Skyflow.ContainerType.COLLECT);
1767
+
1768
+ // Create collect elements.
1769
+ const cardNumberElement = collectContainer.create({
1770
+ table: 'newTable',
1771
+ column: 'card_number',
1772
+ inputstyles: {
1809
1773
  base: {
1810
- border: '1px solid #eae8ee',
1811
- padding: '10px 16px',
1812
- borderRadius: '4px',
1813
- margin: '12px 2px',
1774
+ color: '#1d1d1d',
1775
+ },
1776
+ },
1777
+ labelStyles: {
1778
+ base: {
1779
+ fontSize: '12px',
1780
+ fontWeight: 'bold',
1814
1781
  },
1815
1782
  },
1816
1783
  errorTextStyles: {
1817
1784
  base: {
1818
- color: 'red',
1785
+ color: '#f44336',
1819
1786
  },
1820
1787
  },
1821
- };
1822
-
1823
- const composableContainer = skyflow.container(
1824
- Skyflow.ContainerType.COMPOSABLE,
1825
- containerOptions
1826
- );
1827
-
1828
- // Step 2
1788
+ placeholder: 'card number',
1789
+ label: 'Card Number',
1790
+ type: Skyflow.ElementType.CARD_NUMBER,
1791
+ });
1829
1792
 
1830
- const collectStylesOptions = {
1831
- inputStyles: {
1793
+ const fileElement = collectContainer.create({
1794
+ table: 'newTable',
1795
+ column: 'file',
1796
+ skyflowID: '431eaa6c-5c15-4513-aa15-29f50babe882',
1797
+ inputstyles: {
1832
1798
  base: {
1833
- fontFamily: 'Inter',
1834
- fontStyle: 'normal',
1835
- fontWeight: 400,
1836
- fontSize: '14px',
1837
- lineHeight: '21px',
1838
- width: '294px',
1799
+ color: '#1d1d1d',
1800
+ },
1801
+ },
1802
+ labelStyles: {
1803
+ base: {
1804
+ fontSize: '12px',
1805
+ fontWeight: 'bold',
1839
1806
  },
1840
1807
  },
1841
- labelStyles: {},
1842
1808
  errorTextStyles: {
1843
- base: {},
1809
+ base: {
1810
+ color: '#f44336',
1811
+ },
1844
1812
  },
1845
- };
1846
-
1847
- const cardHolderNameElement = composableContainer.create({
1848
- table: 'pii_fields',
1849
- column: 'first_name',
1850
- ...collectStylesOptions,
1851
- placeholder: 'Cardholder Name',
1852
- type: Skyflow.ElementType.CARDHOLDER_NAME,
1853
- });
1854
-
1855
- const cardNumberElement = composableContainer.create({
1856
- table: 'pii_fields',
1857
- column: 'card_number',
1858
- ...collectStylesOptions,
1859
- placeholder: 'Card Number',
1860
- type: Skyflow.ElementType.CARD_NUMBER,
1813
+ type: Skyflow.ElementType.FILE_INPUT,
1861
1814
  });
1862
1815
 
1863
- const cvvElement = composableContainer.create({
1864
- table: 'pii_fields',
1865
- column: 'cvv',
1866
- ...collectStylesOptions,
1867
- placeholder: 'CVV',
1868
- type: Skyflow.ElementType.CVV,
1869
- });
1816
+ // Mount the elements.
1817
+ cardNumberElement.mount('#collectCardNumber');
1818
+ fileElement.mount('#collectFile');
1870
1819
 
1871
- // Step 3
1872
- composableContainer.mount('#composableContainer'); // Assumes there is a div with id='#composableContainer' in the webpage.
1820
+ // Collect and upload methods.
1821
+ collectContainer.collect({});
1822
+ collectContainer.uploadFiles();
1873
1823
 
1874
- // Step 4
1875
- composableContainer.collect({
1876
- tokens: true,
1877
- });
1878
1824
  ```
1879
- ### Sample Response:
1880
-
1825
+ **Sample Response for collect():**
1881
1826
  ```javascript
1882
1827
  {
1883
- "records": [
1828
+ "records": [
1829
+ {
1830
+ "table": "newTable",
1831
+ "fields": {
1832
+ "card_number": "f3907186-e7e2-466f-91e5-48e12c2bcbc1",
1833
+ }
1834
+ }
1835
+ ]
1836
+ }
1837
+ ```
1838
+ **Sample Response for file uploadFiles() :**
1839
+ ```javascript
1840
+ {
1841
+ "fileUploadResponse": [
1884
1842
  {
1885
- "table": "pii_fields",
1886
- "fields": {
1887
- "skyflow_id": "431eaa6c-5c15-4513-aa15-29f50babe882",
1888
- "first_name": "63b5eeee-3624-493f-825e-137a9336f882",
1889
- "card_number": "f3907186-e7e2-466f-91e5-48e12c2bcbc1",
1890
- "cvv": "7baf5bda-aa22-4587-a5c5-412f6f783a19",
1891
- }
1843
+ "skyflow_id": "431eaa6c-5c15-4513-aa15-29f50babe882"
1892
1844
  }
1893
1845
  ]
1894
1846
  }
1895
1847
  ```
1896
- For information on validations, see [validations](#validations).
1897
1848
 
1898
- ### Set an event listener on Composable Elements:
1849
+ Note: File name should contain only alphanumeric characters and !-_.*()
1899
1850
 
1900
- You can communicate with Skyflow Elements by listening to element events:
1901
1851
 
1902
- ```javascript
1903
- element.on(Skyflow.EventName,handler:function)
1904
- ```
1852
+ # Securely collecting data client-side using Composable Elements
1853
+ - [**Using Skyflow Composable Elements to collect data**](#using-skyflow-composable-elements-to-collect-data)
1854
+ - [**Event listener on Composable Element**](#set-an-event-listener-on-composable-elements)
1855
+ - [**Event listener on Composable Container**](#set-an-event-listener-on-a-composable-container)
1856
+ - [**Update Composable Elements**](#update-composable-elements)
1857
+ - [**Using Skyflow File Element to upload a file**](#using-skyflow-composable-file-element-to-upload-a-file)
1858
+ - [**Using Skyflow File Element to upload multiple files**](#using-skyflow-composable-file-element-to-upload-multiple-files)
1905
1859
 
1906
1860
 
1907
- The SDK supports four events:
1861
+ ## Using Skyflow Composable Elements to collect data
1862
+ Composable Elements combine multiple Skyflow Elements in a single iframe, letting you create multiple Skyflow Elements in a single row. The following steps create a composable element and securely collect data through it.
1908
1863
 
1909
- - `CHANGE`: Triggered when the Element's value changes.
1910
- - `READY`: Triggered when the Element is fully rendered.
1911
- - `FOCUS`: Triggered when the Element gains focus.
1912
- - `BLUR`: Triggered when the Element loses focus.
1864
+ ### Step 1: Create a composable container
1913
1865
 
1914
- The handler `function(state) => void` is a callback function you provide that's called when the event is fired with a state object that uses the following schema:
1866
+ Create a container for the composable element using the `container(Skyflow.ContainerType)` method of the Skyflow client:
1867
+
1868
+ ``` javascript
1869
+ const collectContainer = skyflowClient.container(Skyflow.ContainerType.COMPOSABLE,containerOptions);
1870
+ ```
1871
+ Pass an options object that contains the following keys:
1872
+
1873
+ 1. `layout`: An array that indicates the number of rows in the container and the number of elements in each row. The index value of the array defines the number of rows, and each value in the array represents the number of elements in that row, in order.
1874
+
1875
+ For example: `[2,1]` means the container has two rows, with two elements in the first row and one element in the second row.
1876
+
1877
+ `Note`: The sum of values in the layout array should be equal to the number of elements created
1878
+
1879
+ 2. `styles`: CSS styles to apply to the composable container.
1880
+ 3. `errorTextStyles`: CSS styles to apply if an error is encountered.
1915
1881
 
1916
1882
  ```javascript
1917
- state : {
1918
- elementType: Skyflow.ElementType
1919
- isEmpty: boolean
1920
- isFocused: boolean
1921
- isValid: boolean
1922
- value: string
1923
- }
1883
+ const options = {
1884
+ layout: [2, 1], // Required
1885
+ styles: { // Optional
1886
+ base: {
1887
+ border: '1px solid #DFE3EB',
1888
+ padding: '8px',
1889
+ borderRadius: '4px',
1890
+ margin: '12px 2px',
1891
+ },
1892
+ },
1893
+ errorTextStyles: { // Optional
1894
+ base: {
1895
+ color: 'red',
1896
+ fontFamily: '"Roboto", sans-serif'
1897
+ },
1898
+ global: {
1899
+ '@import': 'url("https://fonts.googleapis.com/css2?family=Roboto&display=swap")',
1900
+ }
1901
+ },
1902
+ };
1924
1903
  ```
1925
- `Note`: Events only include element values when in the state object when env is DEV. By default, value is an empty string.
1926
1904
 
1927
- ### Example Usage of Event Listener on Composable Elements
1905
+ ### Step 2: Create Composable Elements
1906
+ Composable Elements use the following schema:
1928
1907
 
1929
1908
  ```javascript
1930
- const containerOptions = {
1931
- layout: [1],
1932
- styles: {
1933
- base: {
1934
- border: '1px solid #eae8ee',
1935
- padding: '10px 16px',
1936
- borderRadius: '4px',
1937
- margin: '12px 2px',
1938
- }
1939
- },
1940
- errorTextStyles: {
1941
- base: {
1942
- color: 'red'
1943
- }
1944
- }
1909
+ const composableElement = {
1910
+ table: 'string', // Required. The table this data belongs to.
1911
+ column: 'string', // Required. The column this data belongs to.
1912
+ type: Skyflow.ElementType, // Skyflow.ElementType enum.
1913
+ inputStyles: {}, // Optional. Styles applied to the form element.
1914
+ labelStyles: {}, // Optional. Styles for the label of the collect element.
1915
+ errorTextStyles: {}, // Optional. Styles for the errorText of the collect element.
1916
+ label: 'string', // Optional. Label for the form element.
1917
+ placeholder: 'string', // Optional. Placeholder for the form element.
1918
+ altText: 'string', // (DEPRECATED) Initial value for the collect element.
1919
+ validations: [], // Optional. Array of validation rules.
1945
1920
  }
1921
+ ```
1922
+ The `table` and `column` fields indicate which table and column in the vault the Element correspond to.
1946
1923
 
1947
- const composableContainer = skyflow.container(Skyflow.ContainerType.COMPOSABLE, containerOptions);
1924
+ Note: Use dot-delimited strings to specify columns nested inside JSON fields (for example, `address.street.line1`).
1948
1925
 
1949
- const cvv = composableContainer.create({
1950
- table: 'pii_fields',
1951
- column: 'primary_card.cvv',
1952
- type: Skyflow.ElementType.CVV,
1953
- });
1926
+ All elements can be styled with [JSS](https://cssinjs.org/?v=v10.7.1) syntax.
1954
1927
 
1955
- composableContainer.mount('#cvvContainer');
1928
+ The `inputStyles` field accepts an object of CSS properties to apply to the form element in the following states:
1956
1929
 
1957
- // Subscribing to CHANGE event, which gets triggered when element changes.
1958
- cvv.on(Skyflow.EventName.CHANGE, state => {
1959
- // Your implementation when Change event occurs.
1960
- console.log(state);
1961
- });
1962
- ```
1930
+ * `base`: all variants inherit from these styles
1931
+ * `complete`: applied when the Element has valid input
1932
+ * `empty`: applied when the Element has no input
1933
+ * `focus`: applied when the Element has focus
1934
+ * `invalid`: applied when the Element has invalid input
1935
+ * `cardIcon`: applied to the card type icon in CARD_NUMBER Element
1936
+ * `copyIcon`: applied to copy icon in Elements when enableCopy option is true
1937
+ * `global`: used for global styles like font-family.
1963
1938
 
1964
- Sample Element state object when env is `DEV`
1939
+ An example of an `inputStyles` object:
1965
1940
 
1966
1941
  ```javascript
1967
- {
1968
- elementType: 'CVV'
1969
- isEmpty: false
1970
- isFocused: true
1971
- isValid: false
1972
- value: '411'
1942
+ inputStyles: {
1943
+ base: {
1944
+ border: '1px solid #eae8ee',
1945
+ padding: '10px 16px',
1946
+ borderRadius: '4px',
1947
+ color: '#1d1d1d',
1948
+ fontFamily: '"Roboto", sans-serif'
1949
+ },
1950
+ complete: {
1951
+ color: '#4caf50',
1952
+ },
1953
+ empty: {},
1954
+ focus: {},
1955
+ invalid: {
1956
+ color: '#f44336',
1957
+ },
1958
+ cardIcon: {
1959
+ position: 'absolute',
1960
+ left: '8px',
1961
+ bottom: 'calc(50% - 12px)',
1962
+ },
1963
+ copyIcon: {
1964
+ position: 'absolute',
1965
+ right: '8px',
1966
+ },
1967
+ global: {
1968
+ '@import': 'url("https://fonts.googleapis.com/css2?family=Roboto&display=swap")',
1969
+ }
1973
1970
  }
1974
1971
  ```
1972
+ The states that are available for `labelStyles` are `base`, `focus`, `global`.
1973
+ * requiredAsterisk: styles applied for the Asterisk symbol in the label.
1975
1974
 
1976
- Sample Element state object when env is `PROD`
1975
+ An example `labelStyles` object:
1977
1976
 
1978
1977
  ```javascript
1979
- {
1980
- elementType: 'CVV'
1981
- isEmpty: false
1982
- isFocused: true
1983
- isValid: false
1984
- value: ''
1978
+ labelStyles: {
1979
+ base: {
1980
+ fontSize: '12px',
1981
+ fontWeight: 'bold',
1982
+ fontFamily: '"Roboto", sans-serif'
1983
+ },
1984
+ focus: {
1985
+ color: '#1d1d1d'
1986
+ },
1987
+ global: {
1988
+ '@import' :'url("https://fonts.googleapis.com/css2?family=Roboto&display=swap")',
1989
+ }
1985
1990
  }
1986
1991
  ```
1987
1992
 
1988
- ### Update composable elements
1989
- You can update composable element properties with the `update` interface.
1990
-
1993
+ The JS SDK supports the following composable elements:
1991
1994
 
1992
- The `update` interface takes the below object:
1993
- ```javascript
1994
- const updateElement = {
1995
- table: 'string', // Optional. The table this data belongs to.
1996
- column: 'string', // Optional. The column this data belongs to.
1997
- inputStyles: {}, // Optional. Styles applied to the form element.
1998
- labelStyles: {}, // Optional. Styles for the label of the element.
1999
- errorTextStyles: {}, // Optional. Styles for the errorText of element.
2000
- label: 'string', // Optional. Label for the form element.
2001
- placeholder: 'string', // Optional. Placeholder for the form element.
2002
- validations: [], // Optional. Array of validation rules.
2003
- };
2004
- ```
1995
+ - `CARDHOLDER_NAME`
1996
+ - `CARD_NUMBER`
1997
+ - `EXPIRATION_DATE`
1998
+ - `EXPIRATION_MONTH`
1999
+ - `EXPIRATION_YEAR`
2000
+ - `CVV`
2001
+ - `INPUT_FIELD`
2002
+ - `PIN`
2005
2003
 
2006
- Only include the properties that you want to update for the specified composable element.
2004
+ `Note`: Only when the entered value in the below composable elements is valid, the focus shifts automatically. The element types are:
2005
+ - `CARD_NUMBER`
2006
+ - `EXPIRATION_DATE`
2007
+ - `EXPIRATION_MONTH`
2008
+ - `EXPIRATION_YEAR`
2007
2009
 
2008
- Properties your provided when you created the element remain the same until you explicitly update them.
2010
+ The `INPUT_FIELD` type is a custom UI element without any built-in validations. For information on validations, see [validations](#validations).
2009
2011
 
2010
- `Note`: You can't update the `type` property of an element.
2012
+ Along with the Composable Element definition, you can define additional options for the element:
2011
2013
 
2012
- ### End to end example
2013
2014
  ```javascript
2014
- const containerOptions = { layout: [2, 1] };
2015
+ const options = {
2016
+ required: false, // Optional, indicates whether the field is marked as required. Defaults to 'false'
2017
+ enableCardIcon: true, // Optional, indicates whether card icon should be enabled (only applicable for CARD_NUMBER ElementType)
2018
+ format: String, // Optional, format for the element (only applicable currently for EXPIRATION_DATE ElementType),
2019
+ enableCopy: false // Optional, enables the copy icon in collect and reveal elements to copy text to clipboard. Defaults to 'false')
2020
+ }
2021
+ ```
2015
2022
 
2016
- // Create a composable container.
2017
- const composableContainer = skyflow.container(
2018
- Skyflow.ContainerType.COMPOSABLE,
2019
- containerOptions
2020
- );
2023
+ - `required`: Whether or not the field is marked as required. Defaults to `false`.
2024
+ - `enableCardIcon`: Whether or not the icon is visible for the CARD_NUMBER element. Defaults to `true`.
2025
+ - `format`: Format pattern for the element. Only applicable to EXPIRATION_DATE and EXPIRATION_YEAR element types.
2026
+ - `enableCopy`: Whether or not the copy icon is visible in collect and reveal elements. Defaults to `false`.
2021
2027
 
2022
- const stylesOptions = {
2023
- inputStyles: {
2024
- base: {
2025
- fontFamily: 'Inter',
2026
- fontStyle: 'normal',
2027
- fontWeight: 400,
2028
- fontSize: '14px',
2029
- lineHeight: '21px',
2030
- width: '294px',
2031
- },
2032
- },
2033
- labelStyles: {},
2034
- errorTextStyles: {
2035
- base: {},
2036
- },
2037
- };
2028
+ The accepted `EXPIRATION_DATE` values are
2038
2029
 
2039
- // Create composable elements.
2040
- const cardHolderNameElement = composableContainer.create({
2041
- table: 'pii_fields',
2042
- column: 'first_name',
2043
- ...stylesOptions,
2044
- placeholder: 'Cardholder Name',
2045
- type: Skyflow.ElementType.CARDHOLDER_NAME,
2046
- });
2030
+ - `MM/YY` (default)
2031
+ - `MM/YYYY`
2032
+ - `YY/MM`
2033
+ - `YYYY/MM`
2047
2034
 
2048
2035
 
2049
- const cardNumberElement = composableContainer.create({
2050
- table: 'pii_fields',
2051
- column: 'card_number',
2052
- ...stylesOptions,
2053
- placeholder: 'Card Number',
2054
- type: Skyflow.ElementType.CARD_NUMBER,
2055
- });
2036
+ The accepted `EXPIRATION_YEAR` values are
2056
2037
 
2057
- const cvvElement = composableContainer.create({
2058
- table: 'pii_fields',
2059
- column: 'cvv',
2060
- ...stylesOptions,
2061
- placeholder: 'CVV',
2062
- type: Skyflow.ElementType.CVV,
2063
- });
2038
+ - `YY` (default)
2039
+ - `YYYY`
2064
2040
 
2065
- // Mount the composable container.
2066
- composableContainer.mount('#compostableContainer'); // Assumes there is a div with id='#composableContainer' in the webpage.
2067
-
2068
- // ...
2069
-
2070
- // Update validations property on cvvElement.
2071
- cvvElement.update({
2072
- validations: [{
2073
- type: Skyflow.ValidationRuleType.LENGTH_MATCH_RULE,
2074
- params: {
2075
- max: 3,
2076
- error: 'cvv must be 3 digits',
2077
- },
2078
- }]
2079
- })
2080
2041
 
2081
- // Update label, placeholder properties on cardHolderNameElement.
2082
- cardHolderNameElement.update({
2083
- label: 'CARDHOLDER NAME',
2084
- placeholder: 'Eg: John'
2085
- });
2042
+ Once you define the Element object and options, add it to the container using the `create(element, options)` method:
2086
2043
 
2087
- // Update table, column, inputStyles properties on cardNumberElement.
2088
- cardNumberElement.update({
2089
- table:'cards',
2090
- column:'card_number',
2091
- inputStyles:{
2092
- base:{
2093
- color:'blue'
2094
- }
2095
- }
2096
- });
2044
+ ```javascript
2045
+ const composableElement = {
2046
+ table: 'string', // Required, the table this data belongs to.
2047
+ column: 'string', // Required, the column into which this data should be inserted.
2048
+ type: Skyflow.ElementType, // Skyflow.ElementType enum.
2049
+ inputStyles: {}, // Optional, styles that should be applied to the form element.
2050
+ labelStyles: {}, // Optional, styles that will be applied to the label of the collect element.
2051
+ errorTextStyles: {}, // Optional, styles that will be applied to the errorText of the collect element.
2052
+ label: 'string', // Optional, label for the form element.
2053
+ placeholder: 'string', // Optional, placeholder for the form element.
2054
+ altText: 'string', // (DEPRECATED) string that acts as an initial value for the collect element.
2055
+ validations: [], // Optional, array of validation rules.
2056
+ }
2097
2057
 
2058
+ const options = {
2059
+ required: false, // Optional, indicates whether the field is marked as required. Defaults to 'false'.
2060
+ enableCardIcon: true, // Optional, indicates whether card icon should be enabled (only applicable for CARD_NUMBER ElementType).
2061
+ format: String, // Optional, format for the element (only applicable currently for EXPIRATION_DATE ElementType).
2062
+ enableCopy: false, // Optional, enables the copy icon in collect and reveal elements to copy text to clipboard. Defaults to 'false').
2063
+ };
2098
2064
 
2065
+ const element = container.create(composableElement, options);
2099
2066
  ```
2100
- ### Set an event listener on a composable container
2101
- Currently, the SDK supports one event:
2102
- - `SUBMIT`: Triggered when the `Enter` key is pressed in any container element.
2103
2067
 
2104
- The handler `function(void) => void` is a callback function you provide that's called when the `SUBMIT' event fires.
2068
+ ### Step 3: Mount Container to the DOM
2069
+ To specify where the Elements are rendered on your page, create a placeholder `<div>` element with unique `id` attribute. Use this empty `<div>` placeholder to mount the composable container.
2105
2070
 
2106
- ### Example
2107
2071
  ```javascript
2108
- const containerOptions = { layout: [1] }
2072
+ <form>
2073
+ <div id="composableContainer"/>
2074
+ <br/>
2075
+ <div id="button-id"/>
2076
+ <button type="submit">Submit</button>
2077
+ </form>
2078
+ ```
2079
+ Use the composable container's `mount(domElement)` method to insert the container's Elements into the specified `<div>`. For instance, the following call inserts Elements into the `<div>` with the `id "#composableContainer"`.
2109
2080
 
2110
- // Creating a composable container.
2111
- const composableContainer = skyflow.container(Skyflow.ContainerType.COMPOSABLE, containerOptions);
2081
+ ```javacript
2082
+ container.mount('#composableContainer');
2083
+ ```
2112
2084
 
2113
- // Creating the element.
2114
- const cvv = composableContainer.create({
2115
- table: 'pii_fields',
2116
- column: 'primary_card.cvv',
2117
- type: Skyflow.ElementType.CVV,
2118
- });
2085
+ ### Step 4: Collect data from elements
2119
2086
 
2120
- // Mounting the container.
2121
- composableContainer.mount('#cvvContainer');
2122
2087
 
2123
- // Subscribing to the `SUBMIT` event, which gets triggered when the user hits `enter` key in any container element input.
2124
- composableContainer.on(Skyflow.EventName.SUBMIT, ()=> {
2125
- // Your implementation when the SUBMIT(enter) event occurs.
2126
- console.log('Submit Event Listener is being Triggered.');
2127
- });
2088
+ When the form is ready to be submitted, call the container's `collect(options?)` method. The options parameter takes an object of optional parameters as follows:
2089
+ - `tokens`: Whether or not tokens for the collected data are returned. Defaults to 'true'
2090
+ - `additionalFields`: Non-PCI elements data to insert into the vault, specified in the records object format.
2091
+ - `upsert`: To support upsert operations, the table containing the data and a column marked as unique in that table.
2092
+
2093
+ ```javascript
2094
+ const options = {
2095
+ tokens: true, // Optional, indicates whether tokens for the collected data should be returned. Defaults to 'true'.
2096
+ additionalFields: {
2097
+ records: [
2098
+ {
2099
+ table: 'string', // Table into which record should be inserted.
2100
+ fields: {
2101
+ column1: 'value', // Column names should match vault column names.
2102
+ // ...additional fields here.
2103
+ },
2104
+ },
2105
+ // ...additional records here.
2106
+ ],
2107
+ }, // Optional
2108
+ upsert: [ // Upsert operations support in the vault
2109
+ {
2110
+ table: 'string', // Table name
2111
+ column: 'value', // Unique column in the table
2112
+ },
2113
+ ], // Optional
2114
+ };
2128
2115
  ```
2129
2116
 
2130
- ---
2131
- # Securely revealing data client-side
2132
- - [**Retrieving data from the vault**](#retrieving-data-from-the-vault)
2133
- - [**Using Skyflow Elements to reveal data**](#using-skyflow-elements-to-reveal-data)
2134
- - [**UI Error for Reveal Elements**](#ui-error-for-reveal-elements)
2135
- - [**Set token for Reveal Elements**](#set-token-for-reveal-elements)
2136
- - [**Set and clear altText for Reveal Elements**](#set-and-clear-alttext-for-reveal-elements)
2137
- - [**Render a file with a File Element**](#render-a-file-with-a-file-element)
2138
- - [**Update Reveal Elements**](#update-reveal-elements)
2117
+ ### End to end example of collecting data with Composable Elements
2139
2118
 
2140
- ## Retrieving data from the vault
2119
+ ```javascript
2120
+ // Step 1
2121
+ const containerOptions = {
2122
+ layout: [2, 1],
2123
+ styles: {
2124
+ base: {
2125
+ border: '1px solid #eae8ee',
2126
+ padding: '10px 16px',
2127
+ borderRadius: '4px',
2128
+ margin: '12px 2px',
2129
+ },
2130
+ },
2131
+ errorTextStyles: {
2132
+ base: {
2133
+ color: 'red',
2134
+ },
2135
+ },
2136
+ };
2141
2137
 
2142
- For non-PCI use-cases, retrieving data from the vault and revealing it in the browser can be done either using the SkyflowID's, unique column values or tokens as described below
2138
+ const composableContainer = skyflowClient.container(
2139
+ Skyflow.ContainerType.COMPOSABLE,
2140
+ containerOptions
2141
+ );
2143
2142
 
2144
- - ### Using Skyflow tokens
2145
- In order to retrieve data from your vault using tokens that you have previously generated for that data, you can use the `detokenize(records)` method. The records parameter takes a JSON object that contains `records` to be fetched as shown below.
2143
+ // Step 2
2146
2144
 
2147
- ```javascript
2148
- const records = {
2149
- records: [
2150
- {
2151
- token: 'string', // Token for the record to be fetched.
2152
- redaction: RedactionType // Optional. Redaction to be applied for retrieved data.
2145
+ const collectStylesOptions = {
2146
+ inputStyles: {
2147
+ base: {
2148
+ fontFamily: 'Inter',
2149
+ fontStyle: 'normal',
2150
+ fontWeight: 400,
2151
+ fontSize: '14px',
2152
+ lineHeight: '21px',
2153
+ width: '294px',
2153
2154
  },
2154
- ],
2155
+ },
2156
+ labelStyles: {},
2157
+ errorTextStyles: {
2158
+ base: {},
2159
+ },
2155
2160
  };
2156
2161
 
2157
- Note: If you do not provide a redaction type, RedactionType.PLAIN_TEXT is the default.
2162
+ const cardHolderNameElement = composableContainer.create({
2163
+ table: 'pii_fields',
2164
+ column: 'first_name',
2165
+ ...collectStylesOptions,
2166
+ placeholder: 'Cardholder Name',
2167
+ type: Skyflow.ElementType.CARDHOLDER_NAME,
2168
+ });
2158
2169
 
2159
- skyflow.detokenize(records);
2160
- ```
2161
- An [example](https://github.com/skyflowapi/skyflow-js/blob/main/samples/using-script-tag/pure-js.html) of a detokenize call:
2170
+ const cardNumberElement = composableContainer.create({
2171
+ table: 'pii_fields',
2172
+ column: 'card_number',
2173
+ ...collectStylesOptions,
2174
+ placeholder: 'Card Number',
2175
+ type: Skyflow.ElementType.CARD_NUMBER,
2176
+ });
2162
2177
 
2163
- ```javascript
2164
- skyflow.detokenize({
2165
- records: [
2166
- {
2167
- token: '131e70dc-6f76-4319-bdd3-96281e051051',
2168
- },
2169
- {
2170
- token: '1r434532-6f76-4319-bdd3-96281e051051',
2171
- redaction: Skyflow.RedactionType.MASKED
2172
- }
2173
- ],
2178
+ const cvvElement = composableContainer.create({
2179
+ table: 'pii_fields',
2180
+ column: 'cvv',
2181
+ ...collectStylesOptions,
2182
+ placeholder: 'CVV',
2183
+ type: Skyflow.ElementType.CVV,
2184
+ });
2185
+
2186
+ // Step 3
2187
+ composableContainer.mount('#composableContainer'); // Assumes there is a div with id='#composableContainer' in the webpage.
2188
+
2189
+ // Step 4
2190
+ composableContainer.collect({
2191
+ tokens: true,
2174
2192
  });
2175
2193
  ```
2194
+ ### Sample Response:
2176
2195
 
2177
- The sample response:
2178
2196
  ```javascript
2179
2197
  {
2180
- "records": [
2181
- {
2182
- "token": "131e70dc-6f76-4319-bdd3-96281e051051",
2183
- "value": "1990-01-01",
2184
- "valueType": "STRING"
2185
- },
2186
- {
2187
- "token": "1r434532-6f76-4319-bdd3-96281e051051",
2188
- "value": "xxxxxxer",
2189
- "valueType": "STRING"
2190
- }
2191
- ]
2198
+ "records": [
2199
+ {
2200
+ "table": "pii_fields",
2201
+ "fields": {
2202
+ "skyflow_id": "431eaa6c-5c15-4513-aa15-29f50babe882",
2203
+ "first_name": "63b5eeee-3624-493f-825e-137a9336f882",
2204
+ "card_number": "f3907186-e7e2-466f-91e5-48e12c2bcbc1",
2205
+ "cvv": "7baf5bda-aa22-4587-a5c5-412f6f783a19",
2206
+ }
2207
+ }
2208
+ ]
2192
2209
  }
2193
2210
  ```
2211
+ For information on validations, see [validations](#validations).
2194
2212
 
2195
- - ### Using Skyflow ID's or Unique Column Values
2196
- You can retrieve data from the vault with the `get(records, options)` method using either Skyflow IDs or unique column values.
2213
+ ### Set an event listener on Composable Elements:
2197
2214
 
2198
- The records parameter accepts a JSON object that contains an array of either Skyflow IDs or unique column names and values.
2215
+ You can communicate with Skyflow Elements by listening to element events:
2199
2216
 
2200
- The options is an optional `IGetOptions` object that retrieves the tokens for SkyflowIDs.
2201
-
2202
- Notes:
2217
+ ```javascript
2218
+ element.on(Skyflow.EventName,handler:function)
2219
+ ```
2203
2220
 
2204
- - You can use either Skyflow IDs or unique values to retrieve records. You can't use both at the same time.
2205
- - `options` parameter is applicable only for retrieving tokens using Skyflow ID.
2206
- - You can't pass options along with the redaction type.
2207
- - `tokens` defaults to false.
2208
-
2209
- Skyflow.RedactionTypes accepts four values:
2210
- - `PLAIN_TEXT`
2211
- - `MASKED`
2212
- - `REDACTED`
2213
- - `DEFAULT`
2214
2221
 
2215
- You must apply a redaction type to retrieve data.
2222
+ The SDK supports four events:
2216
2223
 
2217
- #### Schema (Skyflow IDs)
2224
+ - `CHANGE`: Triggered when the Element's value changes.
2225
+ - `READY`: Triggered when the Element is fully rendered.
2226
+ - `FOCUS`: Triggered when the Element gains focus.
2227
+ - `BLUR`: Triggered when the Element loses focus.
2228
+
2229
+ The handler `function(state) => void` is a callback function you provide that's called when the event is fired with a state object that uses the following schema:
2218
2230
 
2219
2231
  ```javascript
2220
- data = {
2221
- records: [
2222
- {
2223
- ids: ["SKYFLOW_ID_1", "SKYFLOW_ID_2"], // List of skyflow_ids for the records to fetch.
2224
- table: "NAME_OF_SKYFLOW_TABLE", // Name of table holding the records in the vault.
2225
- redaction: Skyflow.RedactionType, // Redaction type to apply to retrieved data.
2226
- },
2227
- ],
2228
- };
2232
+ state : {
2233
+ elementType: Skyflow.ElementType
2234
+ isEmpty: boolean
2235
+ isFocused: boolean
2236
+ isValid: boolean
2237
+ value: string
2238
+ }
2229
2239
  ```
2230
- #### Schema (Unique column values)
2240
+ `Note`: Events only include element values when in the state object when env is DEV. By default, value is an empty string.
2241
+
2242
+ ### Example Usage of Event Listener on Composable Elements
2231
2243
 
2232
2244
  ```javascript
2233
- data = {
2234
- records: [
2235
- {
2236
- table: "NAME_OF_SKYFLOW_TABLE", // Name of table holding the records in the vault.
2237
- columnName: "UNIQUE_COLUMN_NAME", // Unique column name in the vault.
2238
- columnValues: [ // List of given unique column values.
2239
- "<COLUMN_VALUE_2>",
2240
- "<COLUMN_VALUE_3>",
2241
- ], // Required when specifying a unique column
2242
- redaction: Skyflow.RedactionType, // Redaction type applies to retrieved data.
2245
+ const containerOptions = {
2246
+ layout: [1],
2247
+ styles: {
2248
+ base: {
2249
+ border: '1px solid #eae8ee',
2250
+ padding: '10px 16px',
2251
+ borderRadius: '4px',
2252
+ margin: '12px 2px',
2253
+ }
2254
+ },
2255
+ errorTextStyles: {
2256
+ base: {
2257
+ color: 'red'
2258
+ }
2259
+ }
2260
+ }
2243
2261
 
2244
- },
2245
- ],
2246
- };
2247
- ```
2248
- [Example usage (Skyflow IDs)](https://github.com/skyflowapi/skyflow-js/blob/main/samples/using-script-tag/get-pure-js.html)
2262
+ const composableContainer = skyflowClient.container(Skyflow.ContainerType.COMPOSABLE, containerOptions);
2249
2263
 
2250
- ```javascript
2251
- skyflow.get({
2252
- records: [
2253
- {
2254
- ids: ["f8d8a622-b557-4c6b-a12c-c5ebe0b0bfd9"],
2255
- table: "cards",
2256
- redaction: Skyflow.RedactionType.PLAIN_TEXT,
2257
- },
2258
- {
2259
- ids: ["da26de53-95d5-4bdb-99db-8d8c66a35ff9"],
2260
- table: "contacts",
2261
- redaction: Skyflow.RedactionType.PLAIN_TEXT,
2262
- },
2263
- ],
2264
+ const cvv = composableContainer.create({
2265
+ table: 'pii_fields',
2266
+ column: 'primary_card.cvv',
2267
+ type: Skyflow.ElementType.CVV,
2268
+ });
2269
+
2270
+ composableContainer.mount('#cvvContainer');
2271
+
2272
+ // Subscribing to CHANGE event, which gets triggered when element changes.
2273
+ cvv.on(Skyflow.EventName.CHANGE, state => {
2274
+ // Your implementation when Change event occurs.
2275
+ console.log(state);
2264
2276
  });
2265
2277
  ```
2266
- Example response
2278
+
2279
+ Sample Element state object when env is `DEV`
2267
2280
 
2268
2281
  ```javascript
2269
2282
  {
2270
- "records": [
2271
- {
2272
- "fields": {
2273
- "card_number": "4111111111111111",
2274
- "cvv": "127",
2275
- "expiry_date": "11/2035",
2276
- "fullname": "myname",
2277
- "id": "f8d8a622-b557-4c6b-a12c-c5ebe0b0bfd9"
2278
- },
2279
- "table": "cards"
2280
- }
2281
- ],
2282
- "errors": [
2283
- {
2284
- "error": {
2285
- "code": "404",
2286
- "description": "No Records Found"
2287
- },
2288
- "ids": ["da26de53-95d5-4bdb-99db-8d8c66a35ff9"]
2289
- }
2290
- ]
2283
+ elementType: 'CVV'
2284
+ isEmpty: false
2285
+ isFocused: true
2286
+ isValid: false
2287
+ value: '411'
2291
2288
  }
2292
2289
  ```
2293
- [Example usage (Unique column values)](https://github.com/skyflowapi/skyflow-js/blob/main/samples/using-script-tag/get-pure-js.html)
2294
2290
 
2295
- ```javascript
2296
- skyflow.get({
2297
- records: [
2298
- {
2299
- table: "cards",
2300
- redaction: RedactionType.PLAIN_TEXT,
2301
- columnName: "card_id",
2302
- columnValues: ["123", "456"],
2303
- }
2304
- ],
2305
- });
2306
- ```
2307
- Sample response:
2291
+ Sample Element state object when env is `PROD`
2292
+
2308
2293
  ```javascript
2309
2294
  {
2310
- "records": [
2311
- {
2312
- "fields": {
2313
- "card_id": "123",
2314
- "expiry_date": "11/35",
2315
- "fullname": "myname",
2316
- "id": "f8d2-b557-4c6b-a12c-c5ebfd9"
2317
- },
2318
- "table": "cards"
2319
- },
2320
- {
2321
- "fields": {
2322
- "card_id": "456",
2323
- "expiry_date": "10/23",
2324
- "fullname": "sam",
2325
- "id": "da53-95d5-4bdb-99db-8d8c5ff9"
2326
- },
2327
- "table": "cards"
2328
- }
2329
- ]
2295
+ elementType: 'CVV'
2296
+ isEmpty: false
2297
+ isFocused: true
2298
+ isValid: false
2299
+ value: ''
2330
2300
  }
2331
2301
  ```
2332
2302
 
2333
- [Example usage (Fetch tokens using Skyflow IDs)](https://github.com/skyflowapi/skyflow-js/blob/main/samples/using-script-tag/get-pure-js.html)
2334
- ```javascript
2335
- skyflow.get({
2336
- records: [
2337
- {
2338
- ids: [
2339
- "f8d8a622-b557-4c6b-a12c-c5ebe0b0bfd9",
2340
- "da26de53-95d5-4bdb-99db-8d8c66a35ff9"
2341
- ],
2342
- table: "cards",
2343
- },
2344
- ],
2345
- }, { tokens: true });
2346
- ```
2347
- Sample response:
2303
+ ### Update composable elements
2304
+ You can update composable element properties with the `update` interface.
2305
+
2306
+
2307
+ The `update` interface takes the below object:
2348
2308
  ```javascript
2349
- {
2350
- "records": [
2351
- {
2352
- "fields": {
2353
- "card_id": "f689e421-4cf8-4438-8dbd-cc8e7654b7d9",
2354
- "expiry_date": "d9ef1cb8-5c22-48b0-b769-64ac20ccee01",
2355
- "fullname": "37480f82-d237-4efc-a06a-ebe57121be06",
2356
- "id": "f8d2-b557-4c6b-a12c-c5ebfd9"
2357
- },
2358
- "table": "cards"
2359
- },
2360
- {
2361
- "fields": {
2362
- "card_id": "d794b64c-e283-4fb8-8eef-9f6710730b69",
2363
- "expiry_date": "ff848fc3-a093-4ed4-9414-877b74a33111",
2364
- "fullname": "dfb6c247-3ee6-4fd2-8d1e-19d8e11c25ce",
2365
- "id": "da53-95d5-4bdb-99db-8d8c5ff9"
2366
- },
2367
- "table": "cards"
2368
- }
2369
- ]
2370
- }
2309
+ const updateElement = {
2310
+ table: 'string', // Optional. The table this data belongs to.
2311
+ column: 'string', // Optional. The column this data belongs to.
2312
+ inputStyles: {}, // Optional. Styles applied to the form element.
2313
+ labelStyles: {}, // Optional. Styles for the label of the element.
2314
+ errorTextStyles: {}, // Optional. Styles for the errorText of element.
2315
+ label: 'string', // Optional. Label for the form element.
2316
+ placeholder: 'string', // Optional. Placeholder for the form element.
2317
+ validations: [], // Optional. Array of validation rules.
2318
+ };
2371
2319
  ```
2372
2320
 
2373
- ## Using Skyflow Elements to reveal data
2321
+ Only include the properties that you want to update for the specified composable element.
2374
2322
 
2375
- Skyflow Elements can be used to securely reveal data in a browser without exposing your front end to the sensitive data. This is great for use cases like card issuance where you may want to reveal the card number to a user without increasing your PCI compliance scope.
2323
+ Properties your provided when you created the element remain the same until you explicitly update them.
2376
2324
 
2377
- ### Step 1: Create a container
2378
- To start, create a container using the `container(Skyflow.ContainerType)` method of the Skyflow client as shown below.
2325
+ `Note`: You can't update the `type` property of an element.
2379
2326
 
2327
+ ### End to end example
2380
2328
  ```javascript
2381
- const container = skyflowClient.container(Skyflow.ContainerType.REVEAL)
2329
+ const containerOptions = { layout: [2, 1] };
2330
+
2331
+ // Create a composable container.
2332
+ const composableContainer = skyflowClient.container(
2333
+ Skyflow.ContainerType.COMPOSABLE,
2334
+ containerOptions
2335
+ );
2336
+
2337
+ const stylesOptions = {
2338
+ inputStyles: {
2339
+ base: {
2340
+ fontFamily: 'Inter',
2341
+ fontStyle: 'normal',
2342
+ fontWeight: 400,
2343
+ fontSize: '14px',
2344
+ lineHeight: '21px',
2345
+ width: '294px',
2346
+ },
2347
+ },
2348
+ labelStyles: {},
2349
+ errorTextStyles: {
2350
+ base: {},
2351
+ },
2352
+ };
2353
+
2354
+ // Create composable elements.
2355
+ const cardHolderNameElement = composableContainer.create({
2356
+ table: 'pii_fields',
2357
+ column: 'first_name',
2358
+ ...stylesOptions,
2359
+ placeholder: 'Cardholder Name',
2360
+ type: Skyflow.ElementType.CARDHOLDER_NAME,
2361
+ });
2362
+
2363
+
2364
+ const cardNumberElement = composableContainer.create({
2365
+ table: 'pii_fields',
2366
+ column: 'card_number',
2367
+ ...stylesOptions,
2368
+ placeholder: 'Card Number',
2369
+ type: Skyflow.ElementType.CARD_NUMBER,
2370
+ });
2371
+
2372
+ const cvvElement = composableContainer.create({
2373
+ table: 'pii_fields',
2374
+ column: 'cvv',
2375
+ ...stylesOptions,
2376
+ placeholder: 'CVV',
2377
+ type: Skyflow.ElementType.CVV,
2378
+ });
2379
+
2380
+ // Mount the composable container.
2381
+ composableContainer.mount('#compostableContainer'); // Assumes there is a div with id='#composableContainer' in the webpage.
2382
+
2383
+ // ...
2384
+
2385
+ // Update validations property on cvvElement.
2386
+ cvvElement.update({
2387
+ validations: [{
2388
+ type: Skyflow.ValidationRuleType.LENGTH_MATCH_RULE,
2389
+ params: {
2390
+ max: 3,
2391
+ error: 'cvv must be 3 digits',
2392
+ },
2393
+ }]
2394
+ })
2395
+
2396
+ // Update label, placeholder properties on cardHolderNameElement.
2397
+ cardHolderNameElement.update({
2398
+ label: 'CARDHOLDER NAME',
2399
+ placeholder: 'Eg: John'
2400
+ });
2401
+
2402
+ // Update table, column, inputStyles properties on cardNumberElement.
2403
+ cardNumberElement.update({
2404
+ table:'cards',
2405
+ column:'card_number',
2406
+ inputStyles:{
2407
+ base:{
2408
+ color:'blue'
2409
+ }
2410
+ }
2411
+ });
2412
+
2413
+
2414
+ ```
2415
+ ### Set an event listener on a composable container
2416
+ Currently, the SDK supports one event:
2417
+ - `SUBMIT`: Triggered when the `Enter` key is pressed in any container element.
2418
+
2419
+ The handler `function(void) => void` is a callback function you provide that's called when the `SUBMIT' event fires.
2420
+
2421
+ ### Example
2422
+ ```javascript
2423
+ const containerOptions = { layout: [1] }
2424
+
2425
+ // Creating a composable container.
2426
+ const composableContainer = skyflowClient.container(Skyflow.ContainerType.COMPOSABLE, containerOptions);
2427
+
2428
+ // Creating the element.
2429
+ const cvv = composableContainer.create({
2430
+ table: 'pii_fields',
2431
+ column: 'primary_card.cvv',
2432
+ type: Skyflow.ElementType.CVV,
2433
+ });
2434
+
2435
+ // Mounting the container.
2436
+ composableContainer.mount('#cvvContainer');
2437
+
2438
+ // Subscribing to the `SUBMIT` event, which gets triggered when the user hits `enter` key in any container element input.
2439
+ composableContainer.on(Skyflow.EventName.SUBMIT, ()=> {
2440
+ // Your implementation when the SUBMIT(enter) event occurs.
2441
+ console.log('Submit Event Listener is being Triggered.');
2442
+ });
2443
+ ```
2444
+
2445
+ ## Using Skyflow Composable File Element to upload a file
2446
+ You can upload binary files to a vault using the Skyflow File Element. Use the following steps to securely upload a file.
2447
+ ### Step 1: Create a container
2448
+
2449
+ Create a container for the form elements using the container(Skyflow.ContainerType) method of the Skyflow client:
2450
+
2451
+ ```javascript
2452
+ const containerOptions = { layout: [1] }
2453
+
2454
+ // Creating a composable container.
2455
+ const composableContainer = skyflowClient.container(Skyflow.ContainerType.COMPOSABLE, containerOptions);
2456
+ ```
2457
+
2458
+ ### Step 2: Create a File Element
2459
+
2460
+ Skyflow Collect Elements are defined as follows:
2461
+
2462
+ ```javascript
2463
+ const collectElement = {
2464
+ type: Skyflow.ElementType.FILE_INPUT, // Skyflow.ElementType enum.
2465
+ table: 'string', // The table this data belongs to.
2466
+ column: 'string', // The column into which this data should be inserted.
2467
+ skyflowID: 'string', // The skyflow_id of the record.
2468
+ inputStyles: {}, // Optional, styles that should be applied to the form element.
2469
+ labelStyles: {}, // Optional, styles that will be applied to the label of the collect element.
2470
+ errorTextStyles:{}, // Optional, styles that will be applied to the errorText of the collect element.
2471
+ }
2472
+ ```
2473
+ The `table` and `column` fields indicate which table and column the Element corresponds to.
2474
+
2475
+ `skyflowID` indicates the record that stores the file.
2476
+
2477
+ **Notes**:
2478
+ - `skyflowID` is required while creating File element
2479
+ - Use period-delimited strings to specify columns nested inside JSON fields (e.g. `address.street.line1`).
2480
+
2481
+ ### Step 3: Mount Container to the DOM
2482
+ Mount Elements for file upload to the DOM the same way as Elements used for collecting data. Refer to Step 3 of the [section above](#step-3-mount-container-to-the-dom).
2483
+
2484
+ ### Step 4: Collect data from elements
2485
+
2486
+ When you're ready to upload the file, call the `uploadFiles()` method on the container object.
2487
+
2488
+ ```javascript
2489
+ composableContainer.uploadFiles();
2490
+ ```
2491
+ ### File upload limitations:
2492
+
2493
+ - Only non-executable file are allowed to be uploaded.
2494
+ - Files must have a maximum size of 32 MB
2495
+ - File columns can't enable tokenization, redaction, or arrays.
2496
+ - Re-uploading a file overwrites previously uploaded data.
2497
+ - Partial uploads or resuming a previous upload isn't supported.
2498
+
2499
+ ### End-to-end file upload
2500
+
2501
+ ```javascript
2502
+ // Step 1.
2503
+ const containerOptions = { layout: [1] }
2504
+
2505
+ // Creating a composable container.
2506
+ const container = skyflowClient.container(Skyflow.ContainerType.COMPOSABLE, containerOptions);
2507
+
2508
+ // Step 2.
2509
+ const element = container.create({
2510
+ table: 'pii_fields',
2511
+ column: 'file',
2512
+ skyflowID: '431eaa6c-5c15-4513-aa15-29f50babe882',
2513
+ inputstyles: {
2514
+ base: {
2515
+ color: '#1d1d1d',
2516
+ },
2517
+ },
2518
+ labelStyles: {
2519
+ base: {
2520
+ fontSize: '12px',
2521
+ fontWeight: 'bold',
2522
+ },
2523
+ },
2524
+ errorTextStyles: {
2525
+ base: {
2526
+ color: '#f44336',
2527
+ },
2528
+ },
2529
+ type: Skyflow.ElementType.FILE_INPUT,
2530
+ });
2531
+
2532
+ // Step 3.
2533
+ container.mount('#file'); // Assumes there is a div with id='#file' in the webpage.
2534
+
2535
+ // Step 4.
2536
+ container.uploadFiles();
2537
+ ```
2538
+
2539
+ **Sample Response :**
2540
+ ```javascript
2541
+ {
2542
+ fileUploadResponse: [
2543
+ {
2544
+ "skyflow_id": "431eaa6c-5c15-4513-aa15-29f50babe882"
2545
+ }
2546
+ ]
2547
+ }
2548
+ ```
2549
+ ### File upload with options:
2550
+
2551
+ Along with fileElementInput, you can define other options in the Options object as described below:
2552
+ ```js
2553
+ const options = {
2554
+ allowedFileType: String[], // Optional, indicates the allowed file types for upload
2555
+ }
2556
+ ```
2557
+ `allowedFileType`: An array of string value that indicates the allowedFileTypes to be uploaded.
2558
+
2559
+ #### File upload with options example
2560
+
2561
+ ```javascript
2562
+ // Create collect Container.
2563
+ const containerOptions = { layout: [1] }
2564
+
2565
+ // Creating a composable container.
2566
+ const collectContainer = skyflowClient.container(Skyflow.ContainerType.COMPOSABLE, containerOptions);
2567
+
2568
+ // Create collect elements.
2569
+ const cardNumberElement = collectContainer.create({
2570
+ table: 'newTable',
2571
+ column: 'card_number',
2572
+ inputstyles: {
2573
+ base: {
2574
+ color: '#1d1d1d',
2575
+ },
2576
+ },
2577
+ labelStyles: {
2578
+ base: {
2579
+ fontSize: '12px',
2580
+ fontWeight: 'bold',
2581
+ },
2582
+ },
2583
+ errorTextStyles: {
2584
+ base: {
2585
+ color: '#f44336',
2586
+ },
2587
+ },
2588
+ placeholder: 'card number',
2589
+ label: 'Card Number',
2590
+ type: Skyflow.ElementType.CARD_NUMBER,
2591
+ });
2592
+ const options = {
2593
+ allowedFileType: [".pdf",".png"];
2594
+ };
2595
+ const fileElement = collectContainer.create({
2596
+ table: 'newTable',
2597
+ column: 'file',
2598
+ skyflowID: '431eaa6c-5c15-4513-aa15-29f50babe882',
2599
+ inputstyles: {
2600
+ base: {
2601
+ color: '#1d1d1d',
2602
+ },
2603
+ },
2604
+ labelStyles: {
2605
+ base: {
2606
+ fontSize: '12px',
2607
+ fontWeight: 'bold',
2608
+ },
2609
+ },
2610
+ errorTextStyles: {
2611
+ base: {
2612
+ color: '#f44336',
2613
+ },
2614
+ },
2615
+ type: Skyflow.ElementType.FILE_INPUT,
2616
+ },
2617
+ options
2618
+ );
2619
+
2620
+ // Mount the elements.
2621
+ collectContainer.mount('#collectContainer');
2622
+
2623
+ // Collect and upload methods.
2624
+ collectContainer.collect({});
2625
+ collectContainer.uploadFiles();
2626
+
2627
+ ```
2628
+ **Sample Response for collect():**
2629
+ ```javascript
2630
+ {
2631
+ "records": [
2632
+ {
2633
+ "table": "newTable",
2634
+ "fields": {
2635
+ "card_number": "f3907186-e7e2-466f-91e5-48e12c2bcbc1",
2636
+ }
2637
+ }
2638
+ ]
2639
+ }
2640
+ ```
2641
+ **Sample Response for file uploadFiles() :**
2642
+ ```javascript
2643
+ {
2644
+ "fileUploadResponse": [
2645
+ {
2646
+ "skyflow_id": "431eaa6c-5c15-4513-aa15-29f50babe882"
2647
+ }
2648
+ ]
2649
+ }
2650
+ ```
2651
+ #### File upload with additional elements
2652
+
2653
+ ```javascript
2654
+ // Create collect Container.
2655
+ const containerOptions = { layout: [1,1] }
2656
+
2657
+ // Creating a composable container.
2658
+ const collectContainer = skyflowClient.container(Skyflow.ContainerType.COMPOSABLE, containerOptions);
2659
+
2660
+ // Create collect elements.
2661
+ const cardNumberElement = collectContainer.create({
2662
+ table: 'newTable',
2663
+ column: 'card_number',
2664
+ inputstyles: {
2665
+ base: {
2666
+ color: '#1d1d1d',
2667
+ },
2668
+ },
2669
+ labelStyles: {
2670
+ base: {
2671
+ fontSize: '12px',
2672
+ fontWeight: 'bold',
2673
+ },
2674
+ },
2675
+ errorTextStyles: {
2676
+ base: {
2677
+ color: '#f44336',
2678
+ },
2679
+ },
2680
+ placeholder: 'card number',
2681
+ label: 'Card Number',
2682
+ type: Skyflow.ElementType.CARD_NUMBER,
2683
+ });
2684
+
2685
+ const fileElement = collectContainer.create({
2686
+ table: 'newTable',
2687
+ column: 'file',
2688
+ skyflowID: '431eaa6c-5c15-4513-aa15-29f50babe882',
2689
+ inputstyles: {
2690
+ base: {
2691
+ color: '#1d1d1d',
2692
+ },
2693
+ },
2694
+ labelStyles: {
2695
+ base: {
2696
+ fontSize: '12px',
2697
+ fontWeight: 'bold',
2698
+ },
2699
+ },
2700
+ errorTextStyles: {
2701
+ base: {
2702
+ color: '#f44336',
2703
+ },
2704
+ },
2705
+ type: Skyflow.ElementType.FILE_INPUT,
2706
+ });
2707
+
2708
+ // Mount the elements.
2709
+ cardNumberElement.mount('#collectCardNumber');
2710
+ fileElement.mount('#collectFile');
2711
+
2712
+ // Collect and upload methods.
2713
+ collectContainer.collect({});
2714
+ collectContainer.uploadFiles();
2715
+
2716
+ ```
2717
+ **Sample Response for collect():**
2718
+ ```javascript
2719
+ {
2720
+ "records": [
2721
+ {
2722
+ "table": "newTable",
2723
+ "fields": {
2724
+ "card_number": "f3907186-e7e2-466f-91e5-48e12c2bcbc1",
2725
+ }
2726
+ }
2727
+ ]
2728
+ }
2729
+ ```
2730
+ **Sample Response for file uploadFiles() :**
2731
+ ```javascript
2732
+ {
2733
+ "fileUploadResponse": [
2734
+ {
2735
+ "skyflow_id": "431eaa6c-5c15-4513-aa15-29f50babe882"
2736
+ }
2737
+ ]
2738
+ }
2739
+ ```
2740
+
2741
+ Note: File name should contain only alphanumeric characters and !-_.*()
2742
+
2743
+
2744
+ ## Using Skyflow Composable File Element to upload multiple files
2745
+ You can upload binary files to a vault using the Skyflow File Element. Use the following steps to securely upload a file.
2746
+ ### Step 1: Create a container
2747
+
2748
+ Create a container for the form elements using the container(Skyflow.ContainerType) method of the Skyflow client:
2749
+
2750
+ ```javascript
2751
+ const containerOptions = { layout: [1] }
2752
+
2753
+ // Creating a composable container.
2754
+ const composableContainer = skyflowClient.container(Skyflow.ContainerType.COMPOSABLE, containerOptions);
2755
+ ```
2756
+
2757
+ ### Step 2: Create a File Element
2758
+
2759
+ Skyflow Collect Elements are defined as follows:
2760
+
2761
+ ```javascript
2762
+ const collectElement = {
2763
+ type: Skyflow.ElementType.MULTI_FILE_INPUT, // Skyflow.ElementType enum.
2764
+ table: 'string', // The table this data belongs to.
2765
+ column: 'string', // The column into which this data should be inserted.
2766
+ inputStyles: {}, // Optional, styles that should be applied to the form element.
2767
+ labelStyles: {}, // Optional, styles that will be applied to the label of the collect element.
2768
+ errorTextStyles:{}, // Optional, styles that will be applied to the errorText of the collect element.
2769
+ }
2770
+ ```
2771
+ The `table` and `column` fields indicate which table and column the Element corresponds to.
2772
+
2773
+ **Notes**:
2774
+ - Use period-delimited strings to specify columns nested inside JSON fields (e.g. `address.street.line1`).
2775
+
2776
+ ### Step 3: Mount container to the DOM
2777
+ Elements used for rendering files are mounted to the DOM the same way as Elements used for collecting data. Refer to Step 3 of the [section above](#step-3-mount-elements-to-the-dom-1).
2778
+
2779
+ ### Step 4: Collect data from elements
2780
+
2781
+ When you're ready to upload the file, call the `uploadMultipleFiles()` method on the element.
2782
+
2783
+ ```javascript
2784
+ const metaData = {card_number: '123'} // Optional: used to generate Skyflow IDs, and upload files to those IDs
2785
+
2786
+ element.uploadMultipleFiles();
2787
+ ```
2788
+ Note:
2789
+ - If `MetaData` is provided, that will be used to generate Skyflow IDs, and upload files to those IDs
2790
+ - If `MetaData` is not provided, the files will be uploaded as a new record.
2791
+
2792
+ ### File upload limitations:
2793
+
2794
+ - Only non-executable file are allowed to be uploaded.
2795
+ - Files must have a maximum size of 32 MB
2796
+ - File columns can't enable tokenization, redaction, or arrays.
2797
+ - Re-uploading a file overwrites previously uploaded data.
2798
+ - Partial uploads or resuming a previous upload isn't supported.
2799
+
2800
+ ### End-to-end file upload
2801
+
2802
+ ```javascript
2803
+ // Step 1.
2804
+ const containerOptions = { layout: [1] }
2805
+
2806
+ // Creating a composable container.
2807
+ const container = skyflowClient.container(Skyflow.ContainerType.COMPOSABLE, containerOptions);
2808
+
2809
+ // Step 2.
2810
+ const element = container.create({
2811
+ table: 'pii_fields',
2812
+ column: 'file',
2813
+ skyflowID: '431eaa6c-5c15-4513-aa15-29f50babe882',
2814
+ inputstyles: {
2815
+ base: {
2816
+ color: '#1d1d1d',
2817
+ },
2818
+ },
2819
+ labelStyles: {
2820
+ base: {
2821
+ fontSize: '12px',
2822
+ fontWeight: 'bold',
2823
+ },
2824
+ },
2825
+ errorTextStyles: {
2826
+ base: {
2827
+ color: '#f44336',
2828
+ },
2829
+ },
2830
+ type: Skyflow.ElementType.MULTI_FILE_INPUT,
2831
+ });
2832
+
2833
+ // Step 3.
2834
+ container.mount('#file'); // Assumes there is a div with id='#file' in the webpage.
2835
+
2836
+ // Step 4.
2837
+ element.uploadMultipleFiles();
2838
+ ```
2839
+
2840
+ **Sample Response :**
2841
+ ```javascript
2842
+ {
2843
+ fileUploadResponse: [
2844
+ {
2845
+ "skyflow_id": "431eaa6c-5c15-4513-aa15-29f50babe882"
2846
+ }
2847
+ ]
2848
+ }
2849
+ ```
2850
+ ### File upload with options:
2851
+
2852
+ Along with fileElementInput, you can define other options in the Options object as described below:
2853
+ ```js
2854
+ const options = {
2855
+ allowedFileType: String[], // Optional, indicates the allowed file types for upload
2856
+ }
2857
+ ```
2858
+ `allowedFileType`: An array of string value that indicates the allowedFileTypes to be uploaded.
2859
+
2860
+ #### File upload with options example
2861
+
2862
+ ```javascript
2863
+ // Create collect Container.
2864
+ const containerOptions = { layout: [1] }
2865
+
2866
+ // Creating a composable container.
2867
+ const collectContainer = skyflowClient.container(Skyflow.ContainerType.COMPOSABLE, containerOptions);
2868
+
2869
+ // Create collect elements.
2870
+ const cardNumberElement = collectContainer.create({
2871
+ table: 'newTable',
2872
+ column: 'card_number',
2873
+ inputstyles: {
2874
+ base: {
2875
+ color: '#1d1d1d',
2876
+ },
2877
+ },
2878
+ labelStyles: {
2879
+ base: {
2880
+ fontSize: '12px',
2881
+ fontWeight: 'bold',
2882
+ },
2883
+ },
2884
+ errorTextStyles: {
2885
+ base: {
2886
+ color: '#f44336',
2887
+ },
2888
+ },
2889
+ placeholder: 'card number',
2890
+ label: 'Card Number',
2891
+ type: Skyflow.ElementType.CARD_NUMBER,
2892
+ });
2893
+ const options = {
2894
+ allowedFileType: [".pdf",".png"];
2895
+ };
2896
+ const fileElement = collectContainer.create({
2897
+ table: 'newTable',
2898
+ column: 'file',
2899
+ skyflowID: '431eaa6c-5c15-4513-aa15-29f50babe882',
2900
+ inputstyles: {
2901
+ base: {
2902
+ color: '#1d1d1d',
2903
+ },
2904
+ },
2905
+ labelStyles: {
2906
+ base: {
2907
+ fontSize: '12px',
2908
+ fontWeight: 'bold',
2909
+ },
2910
+ },
2911
+ errorTextStyles: {
2912
+ base: {
2913
+ color: '#f44336',
2914
+ },
2915
+ },
2916
+ type: Skyflow.ElementType.MULTI_FILE_INPUT,
2917
+ },
2918
+ options
2919
+ );
2920
+
2921
+ // Mount the elements.
2922
+ collectContainer.mount('#collectContainer');
2923
+
2924
+ // Collect and upload methods.
2925
+ collectContainer.collect({});
2926
+ fileElement.uploadMultipleFiles();
2927
+
2928
+ ```
2929
+ **Sample Response for collect():**
2930
+ ```javascript
2931
+ {
2932
+ "records": [
2933
+ {
2934
+ "table": "newTable",
2935
+ "fields": {
2936
+ "card_number": "f3907186-e7e2-466f-91e5-48e12c2bcbc1",
2937
+ }
2938
+ }
2939
+ ]
2940
+ }
2941
+ ```
2942
+ **Sample Response for file uploadFiles() :**
2943
+ ```javascript
2944
+ {
2945
+ "fileUploadResponse": [
2946
+ {
2947
+ "skyflow_id": "431eaa6c-5c15-4513-aa15-29f50babe882"
2948
+ }
2949
+ ]
2950
+ }
2951
+ ```
2952
+ #### File upload with additional elements
2953
+
2954
+ ```javascript
2955
+ // Create collect Container.
2956
+ const containerOptions = { layout: [1,1] }
2957
+
2958
+ // Creating a composable container.
2959
+ const collectContainer = skyflowClient.container(Skyflow.ContainerType.COMPOSABLE, containerOptions);
2960
+
2961
+ // Create collect elements.
2962
+ const cardNumberElement = collectContainer.create({
2963
+ table: 'newTable',
2964
+ column: 'card_number',
2965
+ inputstyles: {
2966
+ base: {
2967
+ color: '#1d1d1d',
2968
+ },
2969
+ },
2970
+ labelStyles: {
2971
+ base: {
2972
+ fontSize: '12px',
2973
+ fontWeight: 'bold',
2974
+ },
2975
+ },
2976
+ errorTextStyles: {
2977
+ base: {
2978
+ color: '#f44336',
2979
+ },
2980
+ },
2981
+ placeholder: 'card number',
2982
+ label: 'Card Number',
2983
+ type: Skyflow.ElementType.CARD_NUMBER,
2984
+ });
2985
+
2986
+ const fileElement = collectContainer.create({
2987
+ table: 'newTable',
2988
+ column: 'file',
2989
+ skyflowID: '431eaa6c-5c15-4513-aa15-29f50babe882',
2990
+ inputstyles: {
2991
+ base: {
2992
+ color: '#1d1d1d',
2993
+ },
2994
+ },
2995
+ labelStyles: {
2996
+ base: {
2997
+ fontSize: '12px',
2998
+ fontWeight: 'bold',
2999
+ },
3000
+ },
3001
+ errorTextStyles: {
3002
+ base: {
3003
+ color: '#f44336',
3004
+ },
3005
+ },
3006
+ type: Skyflow.ElementType.MULTI_FILE_INPUT,
3007
+ });
3008
+
3009
+ // Mount the elements.
3010
+ collectContainer.mount('#collectContainer');
3011
+
3012
+ // Collect and upload methods.
3013
+ collectContainer.collect({});
3014
+ fileElement.uploadMultipleFiles();
3015
+
3016
+ ```
3017
+ **Sample Response for collect():**
3018
+ ```javascript
3019
+ {
3020
+ "records": [
3021
+ {
3022
+ "table": "newTable",
3023
+ "fields": {
3024
+ "card_number": "f3907186-e7e2-466f-91e5-48e12c2bcbc1",
3025
+ }
3026
+ }
3027
+ ]
3028
+ }
3029
+ ```
3030
+ **Sample Response for file uploadFiles() :**
3031
+ ```javascript
3032
+ {
3033
+ "fileUploadResponse": [
3034
+ {
3035
+ "skyflow_id": "431eaa6c-5c15-4513-aa15-29f50babe882"
3036
+ },
3037
+ {
3038
+ "skyflow_id": "546eaa6c-5c15-4513-aa15-29f50babe809"
3039
+ }
3040
+ ]
3041
+ }
3042
+ ```
3043
+ Note: File name should contain only alphanumeric characters and !-_.*()
3044
+
3045
+ ---
3046
+
3047
+
3048
+ # Securely revealing data client-side
3049
+ - [**Retrieving data from the vault**](#retrieving-data-from-the-vault)
3050
+ - [**Using Skyflow Elements to reveal data**](#using-skyflow-elements-to-reveal-data)
3051
+ - [**UI Error for Reveal Elements**](#ui-error-for-reveal-elements)
3052
+ - [**Set token for Reveal Elements**](#set-token-for-reveal-elements)
3053
+ - [**Set and clear altText for Reveal Elements**](#set-and-clear-alttext-for-reveal-elements)
3054
+ - [**Render a file with a File Element**](#render-a-file-with-a-file-element)
3055
+ - [**Update Reveal Elements**](#update-reveal-elements)
3056
+ - [**Using Composable Reveal Elements to reveal data**](#using-composable-reveal-elements-to-reveal-data)
3057
+ - [**Update Composable Reveal Elements**](#update-reveal-composable-elements)
3058
+ - [**Render a file with a composable file element**](#render-a-file-with-a-composable-file-element)
3059
+
3060
+
3061
+ ## Retrieving data from the vault
3062
+
3063
+ For non-PCI use-cases, retrieving data from the vault and revealing it in the browser can be done either using the SkyflowID's, unique column values or tokens as described below
3064
+
3065
+ - ### Using Skyflow tokens
3066
+ In order to retrieve data from your vault using tokens that you have previously generated for that data, you can use the `detokenize(records)` method. The records parameter takes a JSON object that contains `records` to be fetched as shown below.
3067
+
3068
+ ```javascript
3069
+ const records = {
3070
+ records: [
3071
+ {
3072
+ token: 'string', // Token for the record to be fetched.
3073
+ redaction: RedactionType // Optional. Redaction to be applied for retrieved data.
3074
+ },
3075
+ ],
3076
+ };
3077
+
3078
+ Note: If you do not provide a redaction type, RedactionType.PLAIN_TEXT is the default.
3079
+
3080
+ skyflow.detokenize(records);
3081
+ ```
3082
+ An [example](https://github.com/skyflowapi/skyflow-js/blob/main/samples/using-script-tag/pure-js.html) of a detokenize call:
3083
+
3084
+ ```javascript
3085
+ skyflow.detokenize({
3086
+ records: [
3087
+ {
3088
+ token: '131e70dc-6f76-4319-bdd3-96281e051051',
3089
+ },
3090
+ {
3091
+ token: '1r434532-6f76-4319-bdd3-96281e051051',
3092
+ redaction: Skyflow.RedactionType.MASKED
3093
+ }
3094
+ ],
3095
+ });
3096
+ ```
3097
+
3098
+ The sample response:
3099
+ ```javascript
3100
+ {
3101
+ "records": [
3102
+ {
3103
+ "token": "131e70dc-6f76-4319-bdd3-96281e051051",
3104
+ "value": "1990-01-01",
3105
+ "valueType": "STRING"
3106
+ },
3107
+ {
3108
+ "token": "1r434532-6f76-4319-bdd3-96281e051051",
3109
+ "value": "xxxxxxer",
3110
+ "valueType": "STRING"
3111
+ }
3112
+ ]
3113
+ }
3114
+ ```
3115
+
3116
+ - ### Using Skyflow ID's or Unique Column Values
3117
+ You can retrieve data from the vault with the `get(records, options)` method using either Skyflow IDs or unique column values.
3118
+
3119
+ The records parameter accepts a JSON object that contains an array of either Skyflow IDs or unique column names and values.
3120
+
3121
+ The options is an optional `IGetOptions` object that retrieves the tokens for SkyflowIDs.
3122
+
3123
+ Notes:
3124
+
3125
+ - You can use either Skyflow IDs or unique values to retrieve records. You can't use both at the same time.
3126
+ - `options` parameter is applicable only for retrieving tokens using Skyflow ID.
3127
+ - You can't pass options along with the redaction type.
3128
+ - `tokens` defaults to false.
3129
+
3130
+ Skyflow.RedactionTypes accepts four values:
3131
+ - `PLAIN_TEXT`
3132
+ - `MASKED`
3133
+ - `REDACTED`
3134
+ - `DEFAULT`
3135
+
3136
+ You must apply a redaction type to retrieve data.
3137
+
3138
+ #### Schema (Skyflow IDs)
3139
+
3140
+ ```javascript
3141
+ data = {
3142
+ records: [
3143
+ {
3144
+ ids: ["SKYFLOW_ID_1", "SKYFLOW_ID_2"], // List of skyflow_ids for the records to fetch.
3145
+ table: "NAME_OF_SKYFLOW_TABLE", // Name of table holding the records in the vault.
3146
+ redaction: Skyflow.RedactionType, // Redaction type to apply to retrieved data.
3147
+ },
3148
+ ],
3149
+ };
3150
+ ```
3151
+ #### Schema (Unique column values)
3152
+
3153
+ ```javascript
3154
+ data = {
3155
+ records: [
3156
+ {
3157
+ table: "NAME_OF_SKYFLOW_TABLE", // Name of table holding the records in the vault.
3158
+ columnName: "UNIQUE_COLUMN_NAME", // Unique column name in the vault.
3159
+ columnValues: [ // List of given unique column values.
3160
+ "<COLUMN_VALUE_2>",
3161
+ "<COLUMN_VALUE_3>",
3162
+ ], // Required when specifying a unique column
3163
+ redaction: Skyflow.RedactionType, // Redaction type applies to retrieved data.
3164
+
3165
+ },
3166
+ ],
3167
+ };
3168
+ ```
3169
+ [Example usage (Skyflow IDs)](https://github.com/skyflowapi/skyflow-js/blob/main/samples/using-script-tag/get-pure-js.html)
3170
+
3171
+ ```javascript
3172
+ skyflow.get({
3173
+ records: [
3174
+ {
3175
+ ids: ["f8d8a622-b557-4c6b-a12c-c5ebe0b0bfd9"],
3176
+ table: "cards",
3177
+ redaction: Skyflow.RedactionType.PLAIN_TEXT,
3178
+ },
3179
+ {
3180
+ ids: ["da26de53-95d5-4bdb-99db-8d8c66a35ff9"],
3181
+ table: "contacts",
3182
+ redaction: Skyflow.RedactionType.PLAIN_TEXT,
3183
+ },
3184
+ ],
3185
+ });
3186
+ ```
3187
+ Example response
3188
+
3189
+ ```javascript
3190
+ {
3191
+ "records": [
3192
+ {
3193
+ "fields": {
3194
+ "card_number": "4111111111111111",
3195
+ "cvv": "127",
3196
+ "expiry_date": "11/2035",
3197
+ "fullname": "myname",
3198
+ "id": "f8d8a622-b557-4c6b-a12c-c5ebe0b0bfd9"
3199
+ },
3200
+ "table": "cards"
3201
+ }
3202
+ ],
3203
+ "errors": [
3204
+ {
3205
+ "error": {
3206
+ "code": "404",
3207
+ "description": "No Records Found"
3208
+ },
3209
+ "ids": ["da26de53-95d5-4bdb-99db-8d8c66a35ff9"]
3210
+ }
3211
+ ]
3212
+ }
3213
+ ```
3214
+ [Example usage (Unique column values)](https://github.com/skyflowapi/skyflow-js/blob/main/samples/using-script-tag/get-pure-js.html)
3215
+
3216
+ ```javascript
3217
+ skyflow.get({
3218
+ records: [
3219
+ {
3220
+ table: "cards",
3221
+ redaction: RedactionType.PLAIN_TEXT,
3222
+ columnName: "card_id",
3223
+ columnValues: ["123", "456"],
3224
+ }
3225
+ ],
3226
+ });
3227
+ ```
3228
+ Sample response:
3229
+ ```javascript
3230
+ {
3231
+ "records": [
3232
+ {
3233
+ "fields": {
3234
+ "card_id": "123",
3235
+ "expiry_date": "11/35",
3236
+ "fullname": "myname",
3237
+ "id": "f8d2-b557-4c6b-a12c-c5ebfd9"
3238
+ },
3239
+ "table": "cards"
3240
+ },
3241
+ {
3242
+ "fields": {
3243
+ "card_id": "456",
3244
+ "expiry_date": "10/23",
3245
+ "fullname": "sam",
3246
+ "id": "da53-95d5-4bdb-99db-8d8c5ff9"
3247
+ },
3248
+ "table": "cards"
3249
+ }
3250
+ ]
3251
+ }
3252
+ ```
3253
+
3254
+ [Example usage (Fetch tokens using Skyflow IDs)](https://github.com/skyflowapi/skyflow-js/blob/main/samples/using-script-tag/get-pure-js.html)
3255
+ ```javascript
3256
+ skyflow.get({
3257
+ records: [
3258
+ {
3259
+ ids: [
3260
+ "f8d8a622-b557-4c6b-a12c-c5ebe0b0bfd9",
3261
+ "da26de53-95d5-4bdb-99db-8d8c66a35ff9"
3262
+ ],
3263
+ table: "cards",
3264
+ },
3265
+ ],
3266
+ }, { tokens: true });
3267
+ ```
3268
+ Sample response:
3269
+ ```javascript
3270
+ {
3271
+ "records": [
3272
+ {
3273
+ "fields": {
3274
+ "card_id": "f689e421-4cf8-4438-8dbd-cc8e7654b7d9",
3275
+ "expiry_date": "d9ef1cb8-5c22-48b0-b769-64ac20ccee01",
3276
+ "fullname": "37480f82-d237-4efc-a06a-ebe57121be06",
3277
+ "id": "f8d2-b557-4c6b-a12c-c5ebfd9"
3278
+ },
3279
+ "table": "cards"
3280
+ },
3281
+ {
3282
+ "fields": {
3283
+ "card_id": "d794b64c-e283-4fb8-8eef-9f6710730b69",
3284
+ "expiry_date": "ff848fc3-a093-4ed4-9414-877b74a33111",
3285
+ "fullname": "dfb6c247-3ee6-4fd2-8d1e-19d8e11c25ce",
3286
+ "id": "da53-95d5-4bdb-99db-8d8c5ff9"
3287
+ },
3288
+ "table": "cards"
3289
+ }
3290
+ ]
3291
+ }
3292
+ ```
3293
+
3294
+ ## Using Skyflow Elements to reveal data
3295
+
3296
+ Skyflow Elements can be used to securely reveal data in a browser without exposing your front end to the sensitive data. This is great for use cases like card issuance where you may want to reveal the card number to a user without increasing your PCI compliance scope.
3297
+
3298
+ ### Step 1: Create a container
3299
+ To start, create a container using the `container(Skyflow.ContainerType)` method of the Skyflow client as shown below.
3300
+
3301
+ ```javascript
3302
+ const container = skyflowClient.container(Skyflow.ContainerType.REVEAL)
3303
+ ```
3304
+
3305
+ ### Step 2: Create a reveal Element
3306
+
3307
+ Then define a Skyflow Element to reveal data as shown below.
3308
+
3309
+ ```javascript
3310
+ const revealElement = {
3311
+ token: 'string', // Required, token of the data being revealed.
3312
+ inputStyles: {}, // Optional, styles to be applied to the element.
3313
+ labelStyles: {}, // Optional, styles to be applied to the label of the reveal element.
3314
+ errorTextStyles: {}, // Optional, styles that will be applied to the errorText of the reveal element.
3315
+ label: 'string', // Optional, label for the form element.
3316
+ altText: 'string', // Optional, string that is shown before reveal, will show token if altText is not provided.
3317
+ redaction: RedactionType, //Optional, Redaction Type to be applied to data, RedactionType.PLAIN_TEXT will be applied if not provided.
3318
+ };
3319
+ ```
3320
+
3321
+ Note: If you don't provide a redaction type, RedactionType.PLAIN_TEXT will apply by default.
3322
+
3323
+ The `inputStyles`, `labelStyles` and `errorTextStyles` parameters accepts a styles object as described in the [previous section](#step-2-create-a-collect-element) for collecting data. But for reveal element, `inputStyles` accepts only `base` variant, `copyIcon` and `global` style objects.
3324
+
3325
+ An example of a inputStyles object:
3326
+
3327
+ ```javascript
3328
+ inputStyles: {
3329
+ base: {
3330
+ color: '#1d1d1d',
3331
+ },
3332
+ copyIcon: {
3333
+ position: 'absolute',
3334
+ right: '8px',
3335
+ top: 'calc(50% - 10px)',
3336
+ },
3337
+ global: {
3338
+ '@import' :'url("https://fonts.googleapis.com/css2?family=Roboto&display=swap")',
3339
+ }
3340
+ },
3341
+ ```
3342
+
3343
+ An example of a labelStyles object:
3344
+
3345
+ ```javascript
3346
+ labelStyles: {
3347
+ base: {
3348
+ fontSize: '12px',
3349
+ fontWeight: 'bold',
3350
+ },
3351
+ global: {
3352
+ '@import' :'url("https://fonts.googleapis.com/css2?family=Roboto&display=swap")',
3353
+ }
3354
+ },
3355
+ ```
3356
+
3357
+ An example of a errorTextStyles object:
3358
+
3359
+ ```javascript
3360
+ errorTextStyles: {
3361
+ base: {
3362
+ color: '#f44336',
3363
+ },
3364
+ global: {
3365
+ '@import' :'url("https://fonts.googleapis.com/css2?family=Roboto&display=swap")',
3366
+ }
3367
+ },
3368
+ ```
3369
+
3370
+ Along with RevealElementInput, you can define other options in the RevealElementOptions object as described below:
3371
+ ```js
3372
+ const options = {
3373
+ enableCopy: false, // Optional, enables the copy icon to reveal elements to copy text to clipboard. Defaults to 'false').
3374
+ format: String, // Optional, format for the element
3375
+ translation: {} // Optional, indicates the allowed data type value for format.
3376
+ }
3377
+ ```
3378
+
3379
+ `format`: A string value that indicates how the reveal element should display the value, including placeholder characters that map to keys `translation` If `translation` isn't specified to any character in the `format` value is considered as a string literal.
3380
+
3381
+ `translation`: An object of key value pairs, where the key is a character that appears in `format` and the value is a simple regex pattern of acceptable inputs for that character. Each key can only appear once. Defaults to `{ ‘X’: ‘[0-9]’ }`.
3382
+
3383
+ **Reveal Element Options examples:**
3384
+ Example 1
3385
+ ```js
3386
+ const revealElementInput = {
3387
+ token: '<token>'
3388
+ };
3389
+
3390
+ const options = {
3391
+ format: '(XXX) XXX-XXXX',
3392
+ translation: { 'X': '[0-9]'}
3393
+ };
3394
+
3395
+ const revealElement = revealContainer.create(revealElementInput,options);
3396
+ ```
3397
+
3398
+ Value from vault: "1234121234"
3399
+ Revealed Value displayed in element: "(123) 412-1234"
3400
+
3401
+ Example 2:
3402
+ ```js
3403
+ const revealElementInput = {
3404
+ token: '<token>'
3405
+ };
3406
+
3407
+ const options = {
3408
+ format: 'XXXX-XXXXXX-XXXXX',
3409
+ translation: { 'X': '[0-9]' }
3410
+ };
3411
+
3412
+ const revealElement = revealContainer.create(revealElementInput,options);
3413
+ ```
3414
+
3415
+ Value from vault: "374200000000004"
3416
+ Revealed Value displayed in element: "3742-000000-00004"
3417
+
3418
+ Once you've defined a Skyflow Element, you can use the `create(element)` method of the container to create the Element as shown below:
3419
+
3420
+ ```javascript
3421
+ const element = container.create(revealElement)
3422
+ ```
3423
+
3424
+ ### Step 3: Mount Elements to the DOM
3425
+
3426
+ Elements used for revealing data are mounted to the DOM the same way as Elements used for collecting data. Refer to Step 3 of the [section above](#step-3-mount-elements-to-the-dom).
3427
+
3428
+
3429
+ ### Step 4: Reveal data
3430
+ When the sensitive data is ready to be retrieved and revealed, call the `reveal()` method on the container as shown below:
3431
+
3432
+ ```javascript
3433
+ container
3434
+ .reveal()
3435
+ .then(data => {
3436
+ // Handle success.
3437
+ })
3438
+ .catch(err => {
3439
+ // Handle error.
3440
+ });
3441
+ ```
3442
+
3443
+
3444
+ ### End to end example of all steps
3445
+
3446
+ **[Sample Code:](https://github.com/skyflowapi/skyflow-js/blob/main/samples/using-script-tag/skyflow-elements.html)**
3447
+ ```javascript
3448
+ // Step 1.
3449
+ const container = skyflowClient.container(Skyflow.ContainerType.REVEAL);
3450
+
3451
+ // Step 2.
3452
+ const cardNumberElement = container.create({
3453
+ token: 'b63ec4e0-bbad-4e43-96e6-6bd50f483f75',
3454
+ inputStyles: {
3455
+ base: {
3456
+ color: '#1d1d1d',
3457
+ },
3458
+ },
3459
+ labelStyles: {
3460
+ base: {
3461
+ fontSize: '12px',
3462
+ },
3463
+ },
3464
+ errorTextStyles: {
3465
+ base: {
3466
+ color: '#f44336',
3467
+ },
3468
+ },
3469
+ label: 'card_number',
3470
+ altText: 'XXXX XXXX XXXX XXXX',
3471
+ redaction: Skyflow.RedactionType.MASKED
3472
+ });
3473
+
3474
+ const cvvElement = container.create({
3475
+ token: '89024714-6a26-4256-b9d4-55ad69aa4047',
3476
+ inputStyles: {
3477
+ base: {
3478
+ color: '#1d1d1d',
3479
+ },
3480
+ },
3481
+ label: 'cvv',
3482
+ altText: 'XXX',
3483
+ });
3484
+
3485
+ const expiryDate= container.create({
3486
+ token: 'a4b24714-6a26-4256-b9d4-55ad69aa4047',
3487
+ inputStyles: {
3488
+ base: {
3489
+ color: '#1d1d1d',
3490
+ },
3491
+ },
3492
+ label: 'expiryDate',
3493
+ altText: 'MM/YYYY',
3494
+ });
3495
+ // Step 3.
3496
+ cardNumberElement.mount('#cardNumber'); // Assumes there is a placeholder div with id='cardNumber' on the page
3497
+ cvvElement.mount('#cvv'); // Assumes there is a placeholder div with id='cvv' on the page
3498
+ expiryDate.mount('#expiryDate'); // Assumes there is a placeholder div with id='expiryDate' on the page
3499
+
3500
+ // Step 4.
3501
+ container
3502
+ .reveal()
3503
+ .then(data => {
3504
+ // Handle success.
3505
+ })
3506
+ .catch(err => {
3507
+ // Handle error.
3508
+ });
3509
+ ```
3510
+
3511
+ The response below shows that some tokens assigned to the reveal elements get revealed successfully, while others fail and remain unrevealed.
3512
+
3513
+ ### Sample Response
3514
+
3515
+ ```
3516
+ {
3517
+ "success": [
3518
+ {
3519
+ "token": "b63ec4e0-bbad-4e43-96e6-6bd50f483f75",
3520
+ "value": "xxxxxxxxx4163"
3521
+ "valueType": "STRING"
3522
+ },
3523
+ {
3524
+ "token": "a4b24714-6a26-4256-b9d4-55ad69aa4047",
3525
+ "value": "12/2098"
3526
+ "valueType": "STRING"
3527
+ }
3528
+ ],
3529
+ "errors": [
3530
+ {
3531
+ "token": "89024714-6a26-4256-b9d4-55ad69aa4047",
3532
+ "error": {
3533
+ "code": 404,
3534
+ "description": "Tokens not found for 89024714-6a26-4256-b9d4-55ad69aa4047"
3535
+ }
3536
+ }
3537
+ ]
3538
+ }
3539
+ ```
3540
+
3541
+ ### UI Error for Reveal Elements
3542
+ Helps to display custom error messages on the Skyflow Elements through the methods `setError` and `resetError` on the elements.
3543
+
3544
+ `setError(error: string)` method is used to set the error text for the element, when this method is triggered, all the current errors present on the element will be overridden with the custom error message passed. This error will be displayed on the element until `resetError()` is triggered on the same element.
3545
+
3546
+ `resetError()` method is used to clear the custom error message that is set using `setError`.
3547
+
3548
+ ##### Sample code snippet for setError and resetError
3549
+
3550
+ ```javascript
3551
+ const container = skyflowClient.container(Skyflow.ContainerType.REVEAL);
3552
+
3553
+ const cardNumber = container.create({
3554
+ token: '89024714-6a26-4256-b9d4-55ad69aa4047',
3555
+ });
3556
+
3557
+ // Set custom error.
3558
+ cardNumber.setError('custom error');
3559
+
3560
+ // Reset custom error.
3561
+ cardNumber.resetError();
3562
+ ```
3563
+
3564
+ ### Override default error messages
3565
+
3566
+ You can override the default error messages with custom ones by using `setErrorOverride`. This is especially useful to override default error messages in non-English languages.
3567
+
3568
+ ```javascript
3569
+ const container = skyflowClient.container(Skyflow.ContainerType.REVEAL);
3570
+
3571
+ const cardNumber = container.create({
3572
+ token: '89024714-6a26-4256-b9d4-55ad69aa4047',
3573
+ });
3574
+
3575
+ const revealButton = document.getElementById('revealPCIData');
3576
+
3577
+ if (revealButton) {
3578
+ revealButton.addEventListener('click', () => {
3579
+ revealContainer.reveal().then((res) => {
3580
+ //handle reveal response
3581
+ }).catch((err) => {
3582
+ cardNumber.setErrorOverride("custom error")
3583
+ });
3584
+ });
3585
+ }
3586
+ ```
3587
+
3588
+ ### Set token for Reveal Elements
3589
+
3590
+ The `setToken(value: string)` method can be used to set the token of the Reveal Element. If no altText is set, the set token will be displayed on the UI as well. If altText is set, then there will be no change in the UI but the token of the element will be internally updated.
3591
+
3592
+ ##### Sample code snippet for setToken
3593
+ ```javascript
3594
+ const container = skyflowClient.container(Skyflow.ContainerType.REVEAL);
3595
+
3596
+ const cardNumber = container.create({
3597
+ altText: 'Card Number',
3598
+ });
3599
+
3600
+ // Set token.
3601
+ cardNumber.setToken('89024714-6a26-4256-b9d4-55ad69aa4047');
3602
+ ```
3603
+ ### Set and Clear altText for Reveal Elements
3604
+ The `setAltText(value: string)` method can be used to set the altText of the Reveal Element. This will cause the altText to be displayed in the UI regardless of whether the token or value is currently being displayed.
3605
+
3606
+ `clearAltText()` method can be used to clear the altText, this will cause the element to display the token or actual value of the element. If the element has no token, the element will be empty.
3607
+ ##### Sample code snippet for setAltText and clearAltText
3608
+
3609
+ ```javascript
3610
+ const container = skyflowClient.container(Skyflow.ContainerType.REVEAL);
3611
+
3612
+ const cardNumber = container.create({
3613
+ token: '89024714-6a26-4256-b9d4-55ad69aa4047',
3614
+ });
3615
+
3616
+ // Set altText.
3617
+ cardNumber.setAltText('Card Number');
3618
+
3619
+ // Clear altText.
3620
+ cardNumber.clearAltText();
3621
+
3622
+ ```
3623
+
3624
+ ## Render a file with a File Element
3625
+
3626
+ You can render files using the Skyflow File Element. Use the following steps to securely render a file.
3627
+
3628
+ ### Step 1: Create a container
3629
+ Create a container for the form elements using the container(Skyflow.ContainerType) method of the Skyflow client:
3630
+
3631
+ ```javascript
3632
+ const container = skyflowClient.container(Skyflow.ContainerType.REVEAL)
3633
+ ```
3634
+
3635
+ ### Step 2: Create a File Element
3636
+ Define a Skyflow Element to render the file as shown below.
3637
+
3638
+ ```javascript
3639
+ const fileElement = {
3640
+ inputStyles: {}, // Optional, styles to be applied to the element.
3641
+ errorTextStyles: {}, // Optional, styles that will be applied to the errorText of the render element.
3642
+ altText: 'string', // Optional, string that is shown before file render call
3643
+ skyflowID: 'string', // Required, skyflow id of the file to render
3644
+ column: 'string', // Required, column name of the file to render
3645
+ table: 'string', // Required, table name of the file to render
3646
+ };
3647
+ ```
3648
+ The inputStyles and errorTextStyles parameters accept a styles object as described in the [previous section](https://github.com/skyflowapi/skyflow-js#step-2-create-a-collect-element) for collecting data. But for render file elements, inputStyles accepts only base variant, global style objects.
3649
+
3650
+ An example of a inputStyles object:
3651
+
3652
+ ```javascript
3653
+ inputStyles: {
3654
+ base: {
3655
+ height: '400px',
3656
+ width: '300px',
3657
+ },
3658
+ global: {
3659
+ '@import' :'url("https://fonts.googleapis.com/css2?family=Roboto&display=swap")',
3660
+ }
3661
+ }
3662
+ ```
3663
+ An example of a errorTextStyles object:
3664
+ ```javascript
3665
+ errorTextStyles: {
3666
+ base: {
3667
+ color: '#f44336',
3668
+ },
3669
+ global: {
3670
+ '@import' :'url("https://fonts.googleapis.com/css2?family=Roboto&display=swap")',
3671
+ }
3672
+ }
3673
+ ```
3674
+
3675
+ ### Step 3: Mount Elements to the DOM
3676
+ Elements used for rendering files are mounted to the DOM the same way as Elements used for collecting data. Refer to Step 3 of the [section above](https://github.com/skyflowapi/skyflow-js#step-3-mount-elements-to-the-dom).
3677
+
3678
+ ### Step 4: Render File
3679
+ After you create and mount the element, call the `renderFile()` method on the element as shown below:
3680
+ ```javascript
3681
+ fileElement
3682
+ .renderFile()
3683
+ .then(data => {
3684
+ // Handle success.
3685
+ })
3686
+ .catch(err => {
3687
+ // Handle error.
3688
+ });
3689
+ ```
3690
+
3691
+ ### End to end example of file render
3692
+ ```javascript
3693
+ // Step 1.
3694
+ const container = skyflowClient.container(Skyflow.ContainerType.REVEAL);
3695
+
3696
+ // REPLACE with your custom implementation to fetch skyflow_id from backend service.
3697
+ // Sample implementation
3698
+ fetch("<BACKEND_URL>")
3699
+ .then((response) => {
3700
+
3701
+ // on successful fetch skyflow_id
3702
+ const skyflowID = response.skyflow_id;
3703
+
3704
+ // Step 2.
3705
+ const fileElement = container.create({
3706
+ skyflowID: "b63ec4e0-bbad-4e43-96e6-6bd50f483f75",
3707
+ column: "file",
3708
+ table: "table",
3709
+ inputStyles: {
3710
+ base: {
3711
+ height: "400px",
3712
+ width: "300px",
3713
+ },
3714
+ },
3715
+ errorTextStyles: {
3716
+ base: {
3717
+ color: "#f44336",
3718
+ },
3719
+ },
3720
+ altText: "This is an altText",
3721
+ });
3722
+ // Step 3.
3723
+ fileElement.mount("#renderFile"); // Assumes there is a placeholder div with id=renderFile on the page
3724
+
3725
+ const renderButton = document.getElementById("renderFiles"); // button to call render file
3726
+
3727
+ if (renderButton) {
3728
+ renderButton.addEventListener("click", () => {
3729
+
3730
+ // Step 4.
3731
+ fileElement
3732
+ .renderFile()
3733
+ .then((data) => {
3734
+ // Handle success.
3735
+ })
3736
+ .catch((err) => {
3737
+ // Handle error.
3738
+ });
3739
+ });
3740
+ }
3741
+ })
3742
+ .catch((err) => {
3743
+ // failed to fetch skyflow_id
3744
+ console.log(err);
3745
+ });
3746
+
3747
+ ```
3748
+
3749
+ ### Sample Success Response
3750
+ ```json
3751
+ {
3752
+ "success": [
3753
+ {
3754
+ "skyflow_id": "b63ec4e0-bbad-4e43-96e6-6bd50f483f75",
3755
+ "column": "file"
3756
+ },
3757
+ ]
3758
+ }
3759
+ ```
3760
+
3761
+ ## Update Reveal Elements
3762
+
3763
+ You can update reveal element properties with the `update` interface.
3764
+
3765
+ The `update` interface takes the below object:
3766
+ ```javascript
3767
+ const updateElement = {
3768
+ token: 'string', // Optional, token of the data being revealed.
3769
+ inputStyles: {}, // Optional, styles to be applied to the element.
3770
+ labelStyles: {}, // Optional, styles to be applied to the label of the reveal element.
3771
+ errorTextStyles: {}, // Optional, styles that will be applied to the errorText of the reveal element.
3772
+ label: 'string', // Optional, label for the form element.
3773
+ altText: 'string', // Optional, string that is shown before reveal, will show token if altText is not provided.
3774
+ redaction: RedactionType, // Optional, Redaction Type to be applied to data.
3775
+ skyflowID: 'string', // Optional, Skyflow ID of the file to render.
3776
+ table: 'string', // Optional, table name of the file to render.
3777
+ column: 'string' // Optional, column name of the file to render.
3778
+ };
3779
+ ```
3780
+
3781
+ Only include the properties that you want to update for the specified reveal element.
3782
+
3783
+ Properties your provided when you created the element remain the same until you explicitly update them.
3784
+
3785
+ ### End to end example
3786
+ ```javascript
3787
+ // Create a reveal container.
3788
+ const revealContainer = skyflowClient.container(Skyflow.ContainerType.REVEAL);
3789
+
3790
+ const stylesOptions = {
3791
+ inputStyles: {
3792
+ base: {
3793
+ fontFamily: 'Inter',
3794
+ fontStyle: 'normal',
3795
+ fontWeight: 400,
3796
+ fontSize: '14px',
3797
+ lineHeight: '21px',
3798
+ width: '294px',
3799
+ },
3800
+ },
3801
+ labelStyles: {},
3802
+ errorTextStyles: {
3803
+ base: {
3804
+ color: '#f44336'
3805
+ },
3806
+ },
3807
+ };
3808
+
3809
+ // Create reveal elements
3810
+ const cardHolderNameRevealElement = revealContainer.create({
3811
+ token: 'ed5fdd1f-5009-435c-a06b-3417ce76d2c8',
3812
+ altText: 'first name',
3813
+ ...stylesOptions,
3814
+ label: 'Card Holder Name',
3815
+ });
3816
+
3817
+ const cardNumberRevealElement = revealContainer.create({
3818
+ token: '8ee84061-7107-4faf-bb25-e044f3d191fe',
3819
+ altText: 'xxxx',
3820
+ ...stylesOptions,
3821
+ label: 'Card Number',
3822
+ redaction: 'RedactionType.CARD_NUMBER'
3823
+ });
3824
+
3825
+ // Mount the reveal elements.
3826
+ cardHolderNameRevealElement.mount('#cardHolderNameRevealElement'); // Assumes there is a div with id='#cardHolderNameRevealElement' in the webpage.
3827
+ cardNumberRevealElement.mount('#cardNumberRevealElement'); // Assumes there is a div with id='#cardNumberRevealElement' in the webpage.
3828
+
3829
+ // ...
3830
+
3831
+ // Update label, labelStyles properties on cardHolderNameRevealElement.
3832
+ cardHolderNameRevealElement.update({
3833
+ label: 'CARDHOLDER NAME',
3834
+ labelStyles: {
3835
+ base: {
3836
+ color: '#aa11aa'
3837
+ }
3838
+ }
3839
+ });
3840
+
3841
+ // Update inputStyles, errorTextStyles properties on cardNumberRevealElement.
3842
+ cardNumberRevealElement.update({
3843
+ inputStyles: {
3844
+ base: {
3845
+ color: '#fff',
3846
+ backgroundColor: '#000',
3847
+ borderColor: '#f00',
3848
+ borderWidth: '5px'
3849
+ }
3850
+ },
3851
+ errorTextStyles: {
3852
+ base: {
3853
+ backgroundColor: '#000',
3854
+ }
3855
+ }
3856
+ });
3857
+ ```
3858
+
3859
+ ---
3860
+
3861
+
3862
+ # Using Composable Reveal Elements to reveal data
3863
+
3864
+ Composable Reveal Elements combine multiple Skyflow Elements in a single iframe, letting you create multiple Skyflow Elements in a single row. The following steps create a composable reveal element and securely collect data through it.
3865
+
3866
+ ### Step 1: Create a composable reveal container
3867
+
3868
+ Create a container for the composable reveal element using the `container(Skyflow.ContainerType)` method of the Skyflow client:
3869
+
3870
+ ``` javascript
3871
+ const revealComposableContainer = skyflowClient.container(Skyflow.ContainerType.COMPOSE_REVEAL, containerOptions);
3872
+ ```
3873
+ Pass an options object that contains the following keys:
3874
+
3875
+ 1. `layout`: An array that indicates the number of rows in the container and the number of elements in each row. The index value of the array defines the number of rows, and each value in the array represents the number of elements in that row, in order.
3876
+
3877
+ For example: `[2,1]` means the container has two rows, with two elements in the first row and one element in the second row.
3878
+
3879
+ `Note`: The sum of values in the layout array should be equal to the number of elements created
3880
+
3881
+ 2. `styles`: CSS styles to apply to the reveal composable container.
3882
+ 3. `errorTextStyles`: CSS styles to apply if an error is encountered.
3883
+
3884
+ ```javascript
3885
+ const containerOptions = {
3886
+ layout: [2, 1], // Required
3887
+ styles: { // Optional
3888
+ base: {
3889
+ border: '1px solid #DFE3EB',
3890
+ padding: '8px',
3891
+ borderRadius: '4px',
3892
+ margin: '12px 2px',
3893
+ },
3894
+ },
3895
+ errorTextStyles: { // Optional
3896
+ base: {
3897
+ color: 'red',
3898
+ fontFamily: '"Roboto", sans-serif'
3899
+ },
3900
+ global: {
3901
+ '@import': 'url("https://fonts.googleapis.com/css2?family=Roboto&display=swap")',
3902
+ }
3903
+ },
3904
+ };
2382
3905
  ```
2383
3906
 
2384
- ### Step 2: Create a reveal Element
2385
-
2386
- Then define a Skyflow Element to reveal data as shown below.
3907
+ ### Step 2: Create Composable Reveal Elements
3908
+ Composable Reveal Elements use the following schema:
2387
3909
 
2388
3910
  ```javascript
2389
- const revealElement = {
3911
+ const revealComposableElement = {
2390
3912
  token: 'string', // Required, token of the data being revealed.
2391
3913
  inputStyles: {}, // Optional, styles to be applied to the element.
2392
3914
  labelStyles: {}, // Optional, styles to be applied to the label of the reveal element.
@@ -2396,7 +3918,6 @@ const revealElement = {
2396
3918
  redaction: RedactionType, //Optional, Redaction Type to be applied to data, RedactionType.PLAIN_TEXT will be applied if not provided.
2397
3919
  };
2398
3920
  ```
2399
-
2400
3921
  Note: If you don't provide a redaction type, RedactionType.PLAIN_TEXT will apply by default.
2401
3922
 
2402
3923
  The `inputStyles`, `labelStyles` and `errorTextStyles` parameters accepts a styles object as described in the [previous section](#step-2-create-a-collect-element) for collecting data. But for reveal element, `inputStyles` accepts only `base` variant, `copyIcon` and `global` style objects.
@@ -2455,334 +3976,90 @@ const options = {
2455
3976
  }
2456
3977
  ```
2457
3978
 
2458
- `format`: A string value that indicates how the reveal element should display the value, including placeholder characters that map to keys `translation` If `translation` isn't specified to any character in the `format` value is considered as a string literal.
2459
-
2460
- `translation`: An object of key value pairs, where the key is a character that appears in `format` and the value is a simple regex pattern of acceptable inputs for that character. Each key can only appear once. Defaults to `{ ‘X’: ‘[0-9]’ }`.
2461
-
2462
- **Reveal Element Options examples:**
2463
- Example 1
2464
- ```js
2465
- const revealElementInput = {
2466
- token: '<token>'
2467
- };
2468
-
2469
- const options = {
2470
- format: '(XXX) XXX-XXXX',
2471
- translation: { 'X': '[0-9]'}
2472
- };
2473
-
2474
- const revealElement = revealContainer.create(revealElementInput,options);
2475
- ```
2476
-
2477
- Value from vault: "1234121234"
2478
- Revealed Value displayed in element: "(123) 412-1234"
2479
-
2480
- Example 2:
2481
- ```js
2482
- const revealElementInput = {
2483
- token: '<token>'
2484
- };
2485
-
2486
- const options = {
2487
- format: 'XXXX-XXXXXX-XXXXX',
2488
- translation: { 'X': '[0-9]' }
2489
- };
2490
-
2491
- const revealElement = revealContainer.create(revealElementInput,options);
2492
- ```
2493
-
2494
- Value from vault: "374200000000004"
2495
- Revealed Value displayed in element: "3742-000000-00004"
2496
-
2497
- Once you've defined a Skyflow Element, you can use the `create(element)` method of the container to create the Element as shown below:
2498
-
2499
- ```javascript
2500
- const element = container.create(revealElement)
2501
- ```
2502
-
2503
- ### Step 3: Mount Elements to the DOM
2504
-
2505
- Elements used for revealing data are mounted to the DOM the same way as Elements used for collecting data. Refer to Step 3 of the [section above](#step-3-mount-elements-to-the-dom).
2506
-
2507
-
2508
- ### Step 4: Reveal data
2509
- When the sensitive data is ready to be retrieved and revealed, call the `reveal()` method on the container as shown below:
2510
-
2511
- ```javascript
2512
- container
2513
- .reveal()
2514
- .then(data => {
2515
- // Handle success.
2516
- })
2517
- .catch(err => {
2518
- // Handle error.
2519
- });
2520
- ```
2521
-
2522
-
2523
- ### End to end example of all steps
2524
-
2525
- **[Sample Code:](https://github.com/skyflowapi/skyflow-js/blob/main/samples/using-script-tag/skyflow-elements.html)**
2526
- ```javascript
2527
- // Step 1.
2528
- const container = skyflowClient.container(Skyflow.ContainerType.REVEAL);
2529
-
2530
- // Step 2.
2531
- const cardNumberElement = container.create({
2532
- token: 'b63ec4e0-bbad-4e43-96e6-6bd50f483f75',
2533
- inputStyles: {
2534
- base: {
2535
- color: '#1d1d1d',
2536
- },
2537
- },
2538
- labelStyles: {
2539
- base: {
2540
- fontSize: '12px',
2541
- },
2542
- },
2543
- errorTextStyles: {
2544
- base: {
2545
- color: '#f44336',
2546
- },
2547
- },
2548
- label: 'card_number',
2549
- altText: 'XXXX XXXX XXXX XXXX',
2550
- redaction: Skyflow.RedactionType.MASKED
2551
- });
2552
-
2553
- const cvvElement = container.create({
2554
- token: '89024714-6a26-4256-b9d4-55ad69aa4047',
2555
- inputStyles: {
2556
- base: {
2557
- color: '#1d1d1d',
2558
- },
2559
- },
2560
- label: 'cvv',
2561
- altText: 'XXX',
2562
- });
2563
-
2564
- const expiryDate= container.create({
2565
- token: 'a4b24714-6a26-4256-b9d4-55ad69aa4047',
2566
- inputStyles: {
2567
- base: {
2568
- color: '#1d1d1d',
2569
- },
2570
- },
2571
- label: 'expiryDate',
2572
- altText: 'MM/YYYY',
2573
- });
2574
- // Step 3.
2575
- cardNumberElement.mount('#cardNumber'); // Assumes there is a placeholder div with id='cardNumber' on the page
2576
- cvvElement.mount('#cvv'); // Assumes there is a placeholder div with id='cvv' on the page
2577
- expiryDate.mount('#expiryDate'); // Assumes there is a placeholder div with id='expiryDate' on the page
2578
-
2579
- // Step 4.
2580
- container
2581
- .reveal()
2582
- .then(data => {
2583
- // Handle success.
2584
- })
2585
- .catch(err => {
2586
- // Handle error.
2587
- });
2588
- ```
2589
-
2590
- The response below shows that some tokens assigned to the reveal elements get revealed successfully, while others fail and remain unrevealed.
2591
-
2592
- ### Sample Response
2593
-
2594
- ```
2595
- {
2596
- "success": [
2597
- {
2598
- "token": "b63ec4e0-bbad-4e43-96e6-6bd50f483f75",
2599
- "value": "xxxxxxxxx4163"
2600
- "valueType": "STRING"
2601
- },
2602
- {
2603
- "token": "a4b24714-6a26-4256-b9d4-55ad69aa4047",
2604
- "value": "12/2098"
2605
- "valueType": "STRING"
2606
- }
2607
- ],
2608
- "errors": [
2609
- {
2610
- "token": "89024714-6a26-4256-b9d4-55ad69aa4047",
2611
- "error": {
2612
- "code": 404,
2613
- "description": "Tokens not found for 89024714-6a26-4256-b9d4-55ad69aa4047"
2614
- }
2615
- }
2616
- ]
2617
- }
2618
- ```
2619
-
2620
- ### UI Error for Reveal Elements
2621
- Helps to display custom error messages on the Skyflow Elements through the methods `setError` and `resetError` on the elements.
2622
-
2623
- `setError(error: string)` method is used to set the error text for the element, when this method is triggered, all the current errors present on the element will be overridden with the custom error message passed. This error will be displayed on the element until `resetError()` is triggered on the same element.
2624
-
2625
- `resetError()` method is used to clear the custom error message that is set using `setError`.
2626
-
2627
- ##### Sample code snippet for setError and resetError
2628
-
2629
- ```javascript
2630
- const container = skyflowClient.container(Skyflow.ContainerType.REVEAL);
2631
-
2632
- const cardNumber = container.create({
2633
- token: '89024714-6a26-4256-b9d4-55ad69aa4047',
2634
- });
2635
-
2636
- // Set custom error.
2637
- cardNumber.setError('custom error');
2638
-
2639
- // Reset custom error.
2640
- cardNumber.resetError();
2641
- ```
2642
-
2643
- ### Override default error messages
2644
-
2645
- You can override the default error messages with custom ones by using `setErrorOverride`. This is especially useful to override default error messages in non-English languages.
2646
-
2647
- ```javascript
2648
- const container = skyflowClient.container(Skyflow.ContainerType.REVEAL);
2649
-
2650
- const cardNumber = container.create({
2651
- token: '89024714-6a26-4256-b9d4-55ad69aa4047',
2652
- });
2653
-
2654
- const revealButton = document.getElementById('revealPCIData');
2655
-
2656
- if (revealButton) {
2657
- revealButton.addEventListener('click', () => {
2658
- revealContainer.reveal().then((res) => {
2659
- //handle reveal response
2660
- }).catch((err) => {
2661
- cardNumber.setErrorOverride("custom error")
2662
- });
2663
- });
2664
- }
2665
- ```
2666
-
2667
- ### Set token for Reveal Elements
2668
-
2669
- The `setToken(value: string)` method can be used to set the token of the Reveal Element. If no altText is set, the set token will be displayed on the UI as well. If altText is set, then there will be no change in the UI but the token of the element will be internally updated.
2670
-
2671
- ##### Sample code snippet for setToken
2672
- ```javascript
2673
- const container = skyflowClient.container(Skyflow.ContainerType.REVEAL);
2674
-
2675
- const cardNumber = container.create({
2676
- altText: 'Card Number',
2677
- });
2678
-
2679
- // Set token.
2680
- cardNumber.setToken('89024714-6a26-4256-b9d4-55ad69aa4047');
2681
- ```
2682
- ### Set and Clear altText for Reveal Elements
2683
- The `setAltText(value: string)` method can be used to set the altText of the Reveal Element. This will cause the altText to be displayed in the UI regardless of whether the token or value is currently being displayed.
2684
-
2685
- `clearAltText()` method can be used to clear the altText, this will cause the element to display the token or actual value of the element. If the element has no token, the element will be empty.
2686
- ##### Sample code snippet for setAltText and clearAltText
2687
-
2688
- ```javascript
2689
- const container = skyflowClient.container(Skyflow.ContainerType.REVEAL);
2690
-
2691
- const cardNumber = container.create({
2692
- token: '89024714-6a26-4256-b9d4-55ad69aa4047',
2693
- });
3979
+ `format`: A string value that indicates how the reveal element should display the value, including placeholder characters that map to keys `translation` If `translation` isn't specified to any character in the `format` value is considered as a string literal.
2694
3980
 
2695
- // Set altText.
2696
- cardNumber.setAltText('Card Number');
3981
+ `translation`: An object of key value pairs, where the key is a character that appears in `format` and the value is a simple regex pattern of acceptable inputs for that character. Each key can only appear once. Defaults to `{ ‘X’: ‘[0-9]’ }`.
2697
3982
 
2698
- // Clear altText.
2699
- cardNumber.clearAltText();
3983
+ **Reveal Element Options examples:**
3984
+ Example 1
3985
+ ```js
3986
+ const revealElementInput = {
3987
+ token: '<token>'
3988
+ };
3989
+
3990
+ const options = {
3991
+ format: '(XXX) XXX-XXXX',
3992
+ translation: { 'X': '[0-9]'}
3993
+ };
2700
3994
 
3995
+ const revealElement = revealComposableContainer.create(revealElementInput,options);
2701
3996
  ```
2702
3997
 
2703
- ## Using Skyflow File Element to upload a file
3998
+ Value from vault: "1234121234"
3999
+ Revealed Value displayed in element: "(123) 412-1234"
2704
4000
 
2705
- You can upload binary files to a vault using the Skyflow File Element. Use the following steps to securely upload a file.
2706
- ### Step 1: Create a container
4001
+ Example 2:
4002
+ ```js
4003
+ const revealElementInput = {
4004
+ token: '<token>'
4005
+ };
2707
4006
 
2708
- Create a container for the form elements using the container(Skyflow.ContainerType) method of the Skyflow client:
4007
+ const options = {
4008
+ format: 'XXXX-XXXXXX-XXXXX',
4009
+ translation: { 'X': '[0-9]' }
4010
+ };
2709
4011
 
2710
- ```javascript
2711
- const container = skyflowClient.container(Skyflow.ContainerType.COLLECT)
4012
+ const revealElement = revealComposableContainer.create(revealElementInput,options);
2712
4013
  ```
2713
4014
 
2714
- ### Step 2: Create a File Element
4015
+ Value from vault: "374200000000004"
4016
+ Revealed Value displayed in element: "3742-000000-00004"
2715
4017
 
2716
- Skyflow Collect Elements are defined as follows:
4018
+ Once you've defined a Skyflow Element, you can use the `create(element)` method of the container to create the Element as shown below:
2717
4019
 
2718
4020
  ```javascript
2719
- const collectElement = {
2720
- type: Skyflow.ElementType.FILE_INPUT, // Skyflow.ElementType enum.
2721
- table: 'string', // The table this data belongs to.
2722
- column: 'string', // The column into which this data should be inserted.
2723
- skyflowID: 'string', // The skyflow_id of the record.
2724
- inputStyles: {}, // Optional, styles that should be applied to the form element.
2725
- labelStyles: {}, // Optional, styles that will be applied to the label of the collect element.
2726
- errorTextStyles:{}, // Optional, styles that will be applied to the errorText of the collect element.
2727
- }
4021
+ const element = revealComposableContainer.create(revealElement)
2728
4022
  ```
2729
- The `table` and `column` fields indicate which table and column the Element corresponds to.
2730
-
2731
- `skyflowID` indicates the record that stores the file.
2732
-
2733
- **Notes**:
2734
- - `skyflowID` is required while creating File element
2735
- - Use period-delimited strings to specify columns nested inside JSON fields (e.g. `address.street.line1`).
2736
-
2737
- ## Step 3: Mount elements to the DOM
2738
4023
 
2739
- To specify where to render Elements on your page, create placeholder `<div>` elements with unique `id` tags. For instance, the form below has an empty div with a unique id as a placeholder for a Skyflow Element.
4024
+ ### Step 3: Mount Container to the DOM
4025
+ To specify where the Elements are rendered on your page, create a placeholder `<div>` element with unique `id` attribute. Use this empty `<div>` placeholder to mount the composable reveal container.
2740
4026
 
2741
- ```html
4027
+ ```javascript
2742
4028
  <form>
2743
- <div id="file"/>
4029
+ <div id="composableRevealContainer"/>
2744
4030
  <br/>
4031
+ <div id="button-id"/>
2745
4032
  <button type="submit">Submit</button>
2746
4033
  </form>
2747
4034
  ```
4035
+ Use the composable container's `mount(domElement)` method to insert the container's Elements into the specified `<div>`. For instance, the following call inserts Elements into the `<div>` with the `id "#composableContainer"`.
2748
4036
 
2749
- Now, when the `mount(domElement)` method of the Element is called, the Element is inserted in the specified div. For instance, the call below inserts the Element into the div with the id "#file".
2750
-
2751
- ```javascript
2752
- element.mount('#file');
2753
- ```
2754
- Use the `unmount` method to reset a Collect Element to its initial state.
2755
-
2756
- ```javascript
2757
- element.unmount();
4037
+ ```javacript
4038
+ revealComposableContainer.mount('#composableRevealContainer');
2758
4039
  ```
2759
- ## Step 4: Collect data from elements
2760
4040
 
2761
- When the file is ready to be uploaded, call the `uploadFiles()` method on the container object.
4041
+ ### Step 4: Reveal data
4042
+ When the sensitive data is ready to be retrieved and revealed, call the `reveal()` method on the container as shown below:
2762
4043
 
2763
4044
  ```javascript
2764
- container.uploadFiles();
4045
+ container
4046
+ .reveal()
4047
+ .then(data => {
4048
+ // Handle success.
4049
+ })
4050
+ .catch(err => {
4051
+ // Handle error.
4052
+ });
2765
4053
  ```
2766
- ### File upload limitations:
2767
-
2768
- - Only non-executable file are allowed to be uploaded.
2769
- - Files must have a maximum size of 32 MB
2770
- - File columns can't enable tokenization, redaction, or arrays.
2771
- - Re-uploading a file overwrites previously uploaded data.
2772
- - Partial uploads or resuming a previous upload isn't supported.
2773
-
2774
- ### End-to-end file upload
2775
4054
 
4055
+ ### End to end example of reveal data with Composable Reveal Elements
2776
4056
  ```javascript
2777
4057
  // Step 1.
2778
- const container = skyflowClient.container(Skyflow.ContainerType.COLLECT);
2779
-
4058
+ const container = skyflowClient.container(Skyflow.ContainerType.COMPOSE_REVEAL, containerOptions);
2780
4059
  // Step 2.
2781
- const element = container.create({
2782
- table: 'pii_fields',
2783
- column: 'file',
2784
- skyflowID: '431eaa6c-5c15-4513-aa15-29f50babe882',
2785
- inputstyles: {
4060
+ const cardNumberElement = container.create({
4061
+ token: 'b63ec4e0-bbad-4e43-96e6-6bd50f483f75',
4062
+ inputStyles: {
2786
4063
  base: {
2787
4064
  color: '#1d1d1d',
2788
4065
  },
@@ -2790,7 +4067,6 @@ const element = container.create({
2790
4067
  labelStyles: {
2791
4068
  base: {
2792
4069
  fontSize: '12px',
2793
- fontWeight: 'bold',
2794
4070
  },
2795
4071
  },
2796
4072
  errorTextStyles: {
@@ -2798,227 +4074,186 @@ const element = container.create({
2798
4074
  color: '#f44336',
2799
4075
  },
2800
4076
  },
2801
- type: Skyflow.ElementType.FILE_INPUT,
4077
+ label: 'card_number',
4078
+ altText: 'XXXX XXXX XXXX XXXX',
4079
+ redaction: Skyflow.RedactionType.MASKED
2802
4080
  });
2803
4081
 
2804
- // Step 3.
2805
- element.mount('#file'); // Assumes there is a div with id='#file' in the webpage.
2806
-
2807
- // Step 4.
2808
- container.uploadFiles();
2809
- ```
2810
-
2811
- **Sample Response :**
2812
- ```javascript
2813
- {
2814
- fileUploadResponse: [
2815
- {
2816
- "skyflow_id": "431eaa6c-5c15-4513-aa15-29f50babe882"
2817
- }
2818
- ]
2819
- }
2820
- ```
2821
- ### File upload with options:
2822
-
2823
- Along with fileElementInput, you can define other options in the Options object as described below:
2824
- ```js
2825
- const options = {
2826
- allowedFileType: String[], // Optional, indicates the allowed file types for upload
2827
- }
2828
- ```
2829
- `allowedFileType`: An array of string value that indicates the allowedFileTypes to be uploaded.
2830
-
2831
- #### File upload with options example
2832
-
2833
- ```javascript
2834
- // Create collect Container.
2835
- const collectContainer = skyflow.container(Skyflow.ContainerType.COLLECT);
2836
-
2837
- // Create collect elements.
2838
- const cardNumberElement = collectContainer.create({
2839
- table: 'newTable',
2840
- column: 'card_number',
2841
- inputstyles: {
4082
+ const cvvElement = container.create({
4083
+ token: '89024714-6a26-4256-b9d4-55ad69aa4047',
4084
+ inputStyles: {
2842
4085
  base: {
2843
4086
  color: '#1d1d1d',
2844
4087
  },
2845
4088
  },
2846
- labelStyles: {
2847
- base: {
2848
- fontSize: '12px',
2849
- fontWeight: 'bold',
2850
- },
2851
- },
2852
- errorTextStyles: {
2853
- base: {
2854
- color: '#f44336',
2855
- },
2856
- },
2857
- placeholder: 'card number',
2858
- label: 'Card Number',
2859
- type: Skyflow.ElementType.CARD_NUMBER,
4089
+ label: 'cvv',
4090
+ altText: 'XXX',
2860
4091
  });
2861
- const options = {
2862
- allowedFileType: [".pdf",".png"];
2863
- };
2864
- const fileElement = collectContainer.create({
2865
- table: 'newTable',
2866
- column: 'file',
2867
- skyflowID: '431eaa6c-5c15-4513-aa15-29f50babe882',
2868
- inputstyles: {
2869
- base: {
2870
- color: '#1d1d1d',
2871
- },
2872
- },
2873
- labelStyles: {
2874
- base: {
2875
- fontSize: '12px',
2876
- fontWeight: 'bold',
2877
- },
2878
- },
2879
- errorTextStyles: {
2880
- base: {
2881
- color: '#f44336',
2882
- },
2883
- },
2884
- type: Skyflow.ElementType.FILE_INPUT,
2885
- },
2886
- options
2887
- );
2888
4092
 
2889
- // Mount the elements.
2890
- cardNumberElement.mount('#collectCardNumber');
2891
- fileElement.mount('#collectFile');
4093
+ const expiryDate= container.create({
4094
+ token: 'a4b24714-6a26-4256-b9d4-55ad69aa4047',
4095
+ inputStyles: {
4096
+ base: {
4097
+ color: '#1d1d1d',
4098
+ },
4099
+ },
4100
+ label: 'expiryDate',
4101
+ altText: 'MM/YYYY',
4102
+ });
4103
+ // Step 3.
4104
+ container.mount('#container')
4105
+ // Step 4.
4106
+ container
4107
+ .reveal()
4108
+ .then(data => {
4109
+ // Handle success.
4110
+ })
4111
+ .catch(err => {
4112
+ // Handle error.
4113
+ });
4114
+ ```
4115
+ The response below shows that some tokens assigned to the reveal elements get revealed successfully, while others fail and remain unrevealed.
2892
4116
 
2893
- // Collect and upload methods.
2894
- collectContainer.collect({});
2895
- collectContainer.uploadFiles();
4117
+ ### Sample Response
2896
4118
 
2897
4119
  ```
2898
- **Sample Response for collect():**
2899
- ```javascript
2900
4120
  {
2901
- "records": [
4121
+ "success": [
4122
+ {
4123
+ "token": "b63ec4e0-bbad-4e43-96e6-6bd50f483f75",
4124
+ "value": "xxxxxxxxx4163"
4125
+ "valueType": "STRING"
4126
+ },
4127
+ {
4128
+ "token": "a4b24714-6a26-4256-b9d4-55ad69aa4047",
4129
+ "value": "12/2098"
4130
+ "valueType": "STRING"
4131
+ }
4132
+ ],
4133
+ "errors": [
2902
4134
  {
2903
- "table": "newTable",
2904
- "fields": {
2905
- "card_number": "f3907186-e7e2-466f-91e5-48e12c2bcbc1",
2906
- }
2907
- }
2908
- ]
2909
- }
2910
- ```
2911
- **Sample Response for file uploadFiles() :**
2912
- ```javascript
2913
- {
2914
- "fileUploadResponse": [
2915
- {
2916
- "skyflow_id": "431eaa6c-5c15-4513-aa15-29f50babe882"
2917
- }
2918
- ]
4135
+ "token": "89024714-6a26-4256-b9d4-55ad69aa4047",
4136
+ "error": {
4137
+ "code": 404,
4138
+ "description": "Tokens not found for 89024714-6a26-4256-b9d4-55ad69aa4047"
4139
+ }
4140
+ }
4141
+ ]
2919
4142
  }
2920
4143
  ```
2921
- #### File upload with additional elements
2922
4144
 
4145
+ ## Update Reveal Composable Elements
4146
+
4147
+ You can update reveal composable element properties with the `update` interface.
4148
+
4149
+ The `update` interface takes the below object:
2923
4150
  ```javascript
2924
- // Create collect Container.
2925
- const collectContainer = skyflow.container(Skyflow.ContainerType.COLLECT);
4151
+ const updateElement = {
4152
+ token: 'string', // Optional, token of the data being revealed.
4153
+ inputStyles: {}, // Optional, styles to be applied to the element.
4154
+ labelStyles: {}, // Optional, styles to be applied to the label of the reveal element.
4155
+ errorTextStyles: {}, // Optional, styles that will be applied to the errorText of the reveal element.
4156
+ label: 'string', // Optional, label for the form element.
4157
+ altText: 'string', // Optional, string that is shown before reveal, will show token if altText is not provided.
4158
+ redaction: RedactionType, // Optional, Redaction Type to be applied to data.
4159
+ skyflowID: 'string', // Optional, Skyflow ID of the file to render.
4160
+ table: 'string', // Optional, table name of the file to render.
4161
+ column: 'string' // Optional, column name of the file to render.
4162
+ };
4163
+ ```
2926
4164
 
2927
- // Create collect elements.
2928
- const cardNumberElement = collectContainer.create({
2929
- table: 'newTable',
2930
- column: 'card_number',
2931
- inputstyles: {
2932
- base: {
2933
- color: '#1d1d1d',
2934
- },
2935
- },
2936
- labelStyles: {
4165
+ Only include the properties that you want to update for the specified reveal element.
4166
+
4167
+ Properties your provided when you created the element remain the same until you explicitly update them.
4168
+
4169
+
4170
+ ### End to end example
4171
+ ```javascript
4172
+ // Create a reveal composable container.
4173
+ const revealComposableContainer = skyflowClient.container(Skyflow.ContainerType.COMPOSE_REVEAL, containerOptions);
4174
+
4175
+ const stylesOptions = {
4176
+ inputStyles: {
2937
4177
  base: {
2938
- fontSize: '12px',
2939
- fontWeight: 'bold',
4178
+ fontFamily: 'Inter',
4179
+ fontStyle: 'normal',
4180
+ fontWeight: 400,
4181
+ fontSize: '14px',
4182
+ lineHeight: '21px',
4183
+ width: '294px',
2940
4184
  },
2941
4185
  },
4186
+ labelStyles: {},
2942
4187
  errorTextStyles: {
2943
4188
  base: {
2944
- color: '#f44336',
4189
+ color: '#f44336'
2945
4190
  },
2946
4191
  },
2947
- placeholder: 'card number',
4192
+ };
4193
+
4194
+ // Create reveal elements
4195
+ const cardHolderNameRevealElement = revealComposableContainer.create({
4196
+ token: 'ed5fdd1f-5009-435c-a06b-3417ce76d2c8',
4197
+ altText: 'first name',
4198
+ ...stylesOptions,
4199
+ label: 'Card Holder Name',
4200
+ });
4201
+
4202
+ const cardNumberRevealElement = revealComposableContainer.create({
4203
+ token: '8ee84061-7107-4faf-bb25-e044f3d191fe',
4204
+ altText: 'xxxx',
4205
+ ...stylesOptions,
2948
4206
  label: 'Card Number',
2949
- type: Skyflow.ElementType.CARD_NUMBER,
4207
+ redaction: 'RedactionType.CARD_NUMBER'
2950
4208
  });
2951
4209
 
2952
- const fileElement = collectContainer.create({
2953
- table: 'newTable',
2954
- column: 'file',
2955
- skyflowID: '431eaa6c-5c15-4513-aa15-29f50babe882',
2956
- inputstyles: {
2957
- base: {
2958
- color: '#1d1d1d',
2959
- },
2960
- },
4210
+ // Mount the reveal elements.
4211
+ revealContainer.mount('#container'); // Assumes there is a div with container
4212
+ // ...
4213
+
4214
+ // Update label, labelStyles properties on cardHolderNameRevealElement.
4215
+ cardHolderNameRevealElement.update({
4216
+ label: 'CARDHOLDER NAME',
2961
4217
  labelStyles: {
2962
4218
  base: {
2963
- fontSize: '12px',
2964
- fontWeight: 'bold',
2965
- },
4219
+ color: '#aa11aa'
4220
+ }
4221
+ }
4222
+ });
4223
+
4224
+ // Update inputStyles, errorTextStyles properties on cardNumberRevealElement.
4225
+ cardNumberRevealElement.update({
4226
+ inputStyles: {
4227
+ base: {
4228
+ color: '#fff',
4229
+ backgroundColor: '#000',
4230
+ borderColor: '#f00',
4231
+ borderWidth: '5px'
4232
+ }
2966
4233
  },
2967
4234
  errorTextStyles: {
2968
4235
  base: {
2969
- color: '#f44336',
2970
- },
2971
- },
2972
- type: Skyflow.ElementType.FILE_INPUT,
2973
- });
2974
-
2975
- // Mount the elements.
2976
- cardNumberElement.mount('#collectCardNumber');
2977
- fileElement.mount('#collectFile');
2978
-
2979
- // Collect and upload methods.
2980
- collectContainer.collect({});
2981
- collectContainer.uploadFiles();
2982
-
2983
- ```
2984
- **Sample Response for collect():**
2985
- ```javascript
2986
- {
2987
- "records": [
2988
- {
2989
- "table": "newTable",
2990
- "fields": {
2991
- "card_number": "f3907186-e7e2-466f-91e5-48e12c2bcbc1",
2992
- }
4236
+ backgroundColor: '#000',
2993
4237
  }
2994
- ]
2995
- }
2996
- ```
2997
- **Sample Response for file uploadFiles() :**
2998
- ```javascript
2999
- {
3000
- "fileUploadResponse": [
3001
- {
3002
- "skyflow_id": "431eaa6c-5c15-4513-aa15-29f50babe882"
3003
- }
3004
- ]
3005
- }
4238
+ }
4239
+ });
3006
4240
  ```
3007
4241
 
3008
- Note: File name should contain only alphanumeric characters and !-_.*()
4242
+ ---
3009
4243
 
3010
- ## Render a file with a File Element
4244
+
4245
+ ## Render a file with a Composable File Element
3011
4246
 
3012
4247
  You can render files using the Skyflow File Element. Use the following steps to securely render a file.
3013
4248
 
3014
- ## Step 1: Create a container
4249
+ ### Step 1: Create a container
3015
4250
  Create a container for the form elements using the container(Skyflow.ContainerType) method of the Skyflow client:
3016
4251
 
3017
4252
  ```javascript
3018
- const container = skyflowClient.container(Skyflow.ContainerType.REVEAL)
4253
+ const container = skyflowClient.container(Skyflow.ContainerType.COMPOSE_REVEAL, containerOptions)
3019
4254
  ```
3020
4255
 
3021
- ## Step 2: Create a File Element
4256
+ ### Step 2: Create a File Element
3022
4257
  Define a Skyflow Element to render the file as shown below.
3023
4258
 
3024
4259
  ```javascript
@@ -3057,11 +4292,11 @@ errorTextStyles: {
3057
4292
  }
3058
4293
  }
3059
4294
  ```
3060
- ## Step 3: Mount Elements to the DOM
3061
- Elements used for rendering files are mounted to the DOM the same way as Elements used for collecting data. Refer to Step 3 of the [section above](https://github.com/skyflowapi/skyflow-js#step-3-mount-elements-to-the-dom).
4295
+ ### Step 3: Mount Container to the DOM
4296
+ Mount Elements for file rendering to the DOM the same way as Elements used for revealing data. Refer to Step 3 of the [section above](#step-3-mount-container-to-the-dom).
3062
4297
 
3063
- ## Step 4: Render File
3064
- When the element is created and mounted, call the renderFile() method on the element as shown below:
4298
+ ### Step 4: Render File
4299
+ After you create and mount the element, call the renderFile() method on the element as shown below:
3065
4300
  ```javascript
3066
4301
  fileElement
3067
4302
  .renderFile()
@@ -3073,10 +4308,10 @@ fileElement
3073
4308
  });
3074
4309
  ```
3075
4310
 
3076
- ## End to end example of file render
4311
+ ### End to end example of file render
3077
4312
  ```javascript
3078
4313
  // Step 1.
3079
- const container = skyflowClient.container(Skyflow.ContainerType.REVEAL);
4314
+ const container = skyflowClient.container(Skyflow.ContainerType.COMPOSE_REVEAL, containerOptions);
3080
4315
 
3081
4316
  // REPLACE with your custom implementation to fetch skyflow_id from backend service.
3082
4317
  // Sample implementation
@@ -3131,117 +4366,6 @@ fetch("<BACKEND_URL>")
3131
4366
 
3132
4367
  ```
3133
4368
 
3134
- ## Sample Success Response
3135
- ```json
3136
- {
3137
- "success": [
3138
- {
3139
- "skyflow_id": "b63ec4e0-bbad-4e43-96e6-6bd50f483f75",
3140
- "column": "file"
3141
- },
3142
- ]
3143
- }
3144
- ```
3145
-
3146
- ### Update Reveal Elements
3147
-
3148
- You can update reveal element properties with the `update` interface.
3149
-
3150
- The `update` interface takes the below object:
3151
- ```javascript
3152
- const updateElement = {
3153
- token: 'string', // Optional, token of the data being revealed.
3154
- inputStyles: {}, // Optional, styles to be applied to the element.
3155
- labelStyles: {}, // Optional, styles to be applied to the label of the reveal element.
3156
- errorTextStyles: {}, // Optional, styles that will be applied to the errorText of the reveal element.
3157
- label: 'string', // Optional, label for the form element.
3158
- altText: 'string', // Optional, string that is shown before reveal, will show token if altText is not provided.
3159
- redaction: RedactionType, // Optional, Redaction Type to be applied to data.
3160
- skyflowID: 'string', // Optional, Skyflow ID of the file to render.
3161
- table: 'string', // Optional, table name of the file to render.
3162
- column: 'string' // Optional, column name of the file to render.
3163
- };
3164
- ```
3165
-
3166
- Only include the properties that you want to update for the specified reveal element.
3167
-
3168
- Properties your provided when you created the element remain the same until you explicitly update them.
3169
-
3170
- ### End to end example
3171
- ```javascript
3172
- // Create a reveal container.
3173
- const revealContainer = skyflow.container(Skyflow.ContainerType.REVEAL);
3174
-
3175
- const stylesOptions = {
3176
- inputStyles: {
3177
- base: {
3178
- fontFamily: 'Inter',
3179
- fontStyle: 'normal',
3180
- fontWeight: 400,
3181
- fontSize: '14px',
3182
- lineHeight: '21px',
3183
- width: '294px',
3184
- },
3185
- },
3186
- labelStyles: {},
3187
- errorTextStyles: {
3188
- base: {
3189
- color: '#f44336'
3190
- },
3191
- },
3192
- };
3193
-
3194
- // Create reveal elements
3195
- const cardHolderNameRevealElement = revealContainer.create({
3196
- token: 'ed5fdd1f-5009-435c-a06b-3417ce76d2c8',
3197
- altText: 'first name',
3198
- ...stylesOptions,
3199
- label: 'Card Holder Name',
3200
- });
3201
-
3202
- const cardNumberRevealElement = revealContainer.create({
3203
- token: '8ee84061-7107-4faf-bb25-e044f3d191fe',
3204
- altText: 'xxxx',
3205
- ...stylesOptions,
3206
- label: 'Card Number',
3207
- redaction: 'RedactionType.CARD_NUMBER'
3208
- });
3209
-
3210
- // Mount the reveal elements.
3211
- cardHolderNameRevealElement.mount('#cardHolderNameRevealElement'); // Assumes there is a div with id='#cardHolderNameRevealElement' in the webpage.
3212
- cardNumberRevealElement.mount('#cardNumberRevealElement'); // Assumes there is a div with id='#cardNumberRevealElement' in the webpage.
3213
-
3214
- // ...
3215
-
3216
- // Update label, labelStyles properties on cardHolderNameRevealElement.
3217
- cardHolderNameRevealElement.update({
3218
- label: 'CARDHOLDER NAME',
3219
- labelStyles: {
3220
- base: {
3221
- color: '#aa11aa'
3222
- }
3223
- }
3224
- });
3225
-
3226
- // Update inputStyles, errorTextStyles properties on cardNumberRevealElement.
3227
- cardNumberRevealElement.update({
3228
- inputStyles: {
3229
- base: {
3230
- color: '#fff',
3231
- backgroundColor: '#000',
3232
- borderColor: '#f00',
3233
- borderWidth: '5px'
3234
- }
3235
- },
3236
- errorTextStyles: {
3237
- base: {
3238
- backgroundColor: '#000',
3239
- }
3240
- }
3241
- });
3242
- ```
3243
-
3244
- ---
3245
4369
  # Securely deleting data client-side
3246
4370
  - [**Deleting data from the vault**](#deleting-data-from-the-vault)
3247
4371