Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,8 @@
"prepare": "bob build",
"example": "yarn --cwd example",
"bootstrap": "yarn example && yarn && yarn example pods",
"build": "bob build"
"build": "bob build",
"docs-gen": "node scripts/doc-gen/components-json-gen.js && node scripts/doc-gen/markdown-gen.js"
},
"keywords": [
"react-native",
Expand Down Expand Up @@ -129,6 +130,7 @@
"dependencies": {
"jwt-decode": "^3.1.2",
"lodash": "^4.17.21",
"react-docgen-typescript": "^2.2.2",
"react-native-uuid": "^2.0.1",
"set-value": "^4.1.0"
}
Expand Down
68 changes: 68 additions & 0 deletions scripts/doc-gen/components-json-gen.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
/* eslint-disable no-undef */
/* eslint-disable @typescript-eslint/no-var-requires */
const fs = require('fs');
const path = require('path');
const docgen = require('react-docgen-typescript');

const tsConfigParser = docgen.withCustomConfig('./tsconfig.json', {
savePropValueAsString: true,
skipChildrenPropWithoutDoc: false,
propFilter: {
skipPropsWithoutDoc: false,
skipPropsWithName: 'children',
},
shouldExtractLiteralValuesFromEnum: true,
});

const paths = ['components', 'hooks'];
const excludeDirs = [];

function getFiles(dir, files = []) {
const fileNames = fs.readdirSync(dir);

fileNames.forEach((fileName) => {
const filePath = path.join(dir, fileName);
const stat = fs.statSync(filePath);
if (stat.isDirectory() && !excludeDirs.includes(fileName)) {
getFiles(filePath, files);
} else if (fileName === 'index.tsx' || fileName === 'index.ts') {
files.push(filePath);
}
});

return files;
}

function generateDocumentationJson() {
const docJson = {};
const rootPath = path.join(__dirname, '../../');

paths.forEach((item) => {
const pathJsonArray = [];
const folderPath = path.join(rootPath, 'src', item);
const files = getFiles(folderPath);
files.forEach((file) => {
const relativePath = path.relative(rootPath, file);
const docs = tsConfigParser.parse(relativePath);
pathJsonArray.push(docs[0]);
});
docJson[item] = pathJsonArray;
});
return docJson;
}

function createDocJsonFile(json) {
const dirPath = path.join(__dirname, '../../', 'docs', 'json');
const filePath = path.join(dirPath, 'components.json');

// Create docs/json folder if it doesn't exist
if (!fs.existsSync(dirPath)) {
fs.mkdirSync(dirPath);
}

// Write to components.json file
fs.writeFileSync(filePath, JSON.stringify(json, null, 2));
console.log('Json documentation is generated at docs/json');
}

createDocJsonFile(generateDocumentationJson());
125 changes: 125 additions & 0 deletions scripts/doc-gen/markdown-gen.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
/* eslint-disable @typescript-eslint/no-var-requires */
const components = require('../../docs/json/components.json');
const fs = require('fs');
const path = require('path');

function formatTypeColumn(str, propType) {
if (!str) {
return '';
}
const parts = str.split('|').map((s) => s.trim());
if (parts.length === 1) {
return `\`${str}\``;
}
if (!propType) {
return `\`${parts[0]}\``;
}
return `\`${parts[0]} / ${parts[1]}\``;
}

// Output directory for Markdown files
const outputDir = './docs/markdown';

// Overview page to list elements
let overviewContent = `
{% env enable="reactNativeSdkRef" %}

# React-Native

Some documentation for the overview page.
`;

// Loop through each component in the JSON object
Object.keys(components).forEach((key) => {
overviewContent += `\n## ${
key == 'core'
? 'Skyflow Provider'
: key == 'elements'
? 'Components'
: key.charAt(0).toUpperCase() + key.slice(1)
}\n\n`;

components[key]
.filter((component) => component)
.forEach((component) => {
// Create the Markdown file path based on the component name
const componentPath = path.join(
outputDir,
key,
`${component.displayName}.md`
);

const name = `${component.displayName}`;
overviewContent += `- [${name}](/sdks/skyflow-react-native/${key}/${name})\n`;

const sortedProps = Object.entries(component.props)
.sort(([_, propA], [__, propB]) => {
if (propA.required && !propB.required) {
return -1; // propA comes before propB
} else if (!propA.required && propB.required) {
return 1; // propB comes before propA
}
return 0; // no change in order
})
.reduce((sorted, [key, value]) => {
sorted[key] = value;
return sorted;
}, {});

// Generate the Markdown content for the component
let markdownContent = `---
id: ${component.displayName}
title: ${component.displayName}
sidebar_label: ${component.displayName}
---

{% env enable="reactNativeSdkRef" %}

# ${component.displayName}

${component.description}

## Import

\`\`\`
import {${component.displayName}} from 'skyflow-react-native';
\`\`\`
`;
const propsDetails = `
## Props

| Name | Type | Description | Required |
|-------------------------|----------------------|---------------------------------------------------------|------------------|
${Object.keys(sortedProps)
.map((propName) => {
const prop = sortedProps[propName];
return `| ${prop.name} | ${formatTypeColumn(
prop.type.name,
prop.required
)} | ${prop.description} | ${prop.required} |`;
})
.join('\n')}

`;
if (Object.keys(component.props).length) {
markdownContent += propsDetails;
}

if (Object.keys(component.tags).length > 0 && component.tags['returns']) {
markdownContent += `\n## Returns\n${component.tags['returns']}\n\n`;
}

markdownContent += '{% /env %}';
const folderPath = path.dirname(componentPath);

// Create the folder if it doesn't exist
if (!fs.existsSync(folderPath)) {
fs.mkdirSync(folderPath, { recursive: true });
}
// Write the Markdown content to the file
fs.writeFileSync(componentPath, markdownContent);
});
});
overviewContent += '\n{% /env %}';
fs.writeFileSync(path.join(outputDir, 'Overview.md'), overviewContent);
console.log('markdown files generated at docs/markdown');
3 changes: 3 additions & 0 deletions src/components/CardHolderNameElement/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,9 @@ import SkyflowError from "../../utils/skyflow-error";
import SKYFLOW_ERROR_CODE from "../../utils/skyflow-error-code";
import uuid from 'react-native-uuid';

/**
* Element to collect cardholder names.
*/
const CardHolderNameElement: React.FC<CollectElementProps> = ({ container, options = { required: false }, ...rest }) => {
const [element, setElement] = React.useState<CollectElement>();
const [elementValue, setElementValue] = React.useState<string>('');
Expand Down
3 changes: 3 additions & 0 deletions src/components/CardNumberElement/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@ import SkyflowError from "../../utils/skyflow-error";
import SKYFLOW_ERROR_CODE from "../../utils/skyflow-error-code";
import uuid from 'react-native-uuid';

/**
* Element to collect card numbers.
*/
const CardNumberElement: React.FC<CollectElementProps> = ({ container, options = { required: false }, ...rest }) => {
const [element, setElement] = React.useState<CollectElement>(undefined);
const [elementValue, setElementValue] = React.useState<string>('');
Expand Down
3 changes: 3 additions & 0 deletions src/components/CvvElement/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,9 @@ import SkyflowError from "../../utils/skyflow-error";
import SKYFLOW_ERROR_CODE from "../../utils/skyflow-error-code";
import uuid from 'react-native-uuid';

/**
* Element to collect CVVs.
*/
const CvvElement: React.FC<CollectElementProps> = ({ container, options = { requried: false }, ...rest }) => {
const [element, setElement] = React.useState<CollectElement>();
const [elementValue, setElementValue] = React.useState<string>('');
Expand Down
3 changes: 3 additions & 0 deletions src/components/ExpirationDateElement/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,9 @@ import SkyflowError from "../../utils/skyflow-error";
import SKYFLOW_ERROR_CODE from "../../utils/skyflow-error-code";
import uuid from 'react-native-uuid';

/**
* Element to collect expiration dates.
*/
const ExpirationDateElement: React.FC<CollectElementProps> = ({ container, options, ...rest }) => {
const [element, setElement] = React.useState<CollectElement>();
const [elementValue, setElementValue] = React.useState<string>('');
Expand Down
3 changes: 3 additions & 0 deletions src/components/ExpirationMonthElement/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,9 @@ import SkyflowError from "../../utils/skyflow-error";
import SKYFLOW_ERROR_CODE from "../../utils/skyflow-error-code";
import uuid from 'react-native-uuid';

/**
* Element to collect expiration month values.
*/
const ExpirationMonthElement: React.FC<CollectElementProps> = ({ container, options = { required: false }, ...rest }) => {
const [element, setElement] = React.useState<CollectElement>();
const [elementValue, setElementValue] = React.useState<string>('');
Expand Down
3 changes: 3 additions & 0 deletions src/components/ExpirationYearElement/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,9 @@ import SKYFLOW_ERROR_CODE from "../../utils/skyflow-error-code";
import uuid from 'react-native-uuid';


/**
* Element to collect expiration year values.
*/
const ExpirationYearElement: React.FC<CollectElementProps> = ({ container, options, ...rest }) => {
const [element, setElement] = React.useState<CollectElement>();
const [elementValue, setElementValue] = React.useState<string>('');
Expand Down
3 changes: 3 additions & 0 deletions src/components/InputFieldElement/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,9 @@ import SkyflowError from "../../utils/skyflow-error";
import SKYFLOW_ERROR_CODE from "../../utils/skyflow-error-code";
import uuid from 'react-native-uuid';

/**
* Element to collect arbitrary values.
*/
const InputFieldElement: React.FC<CollectElementProps> = ({ container, options = { required: false }, ...rest }) => {
const [element, setElement] = React.useState<CollectElement>(undefined);
const [elementValue, setElementValue] = React.useState<string>('');
Expand Down
3 changes: 3 additions & 0 deletions src/components/PinElement/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,9 @@ import SkyflowError from "../../utils/skyflow-error";
import SKYFLOW_ERROR_CODE from "../../utils/skyflow-error-code";
import uuid from 'react-native-uuid';

/**
* Element to collect PIN values.
*/
const PinElement: React.FC<CollectElementProps> = ({ container, options = { required: false }, ...rest }) => {
const [element, setElement] = React.useState<CollectElement>();
const [elementValue, setElementValue] = React.useState<string>('');
Expand Down
4 changes: 3 additions & 1 deletion src/components/RevealElement/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,9 @@ import { RevealElementProps } from "../../utils/constants"
import SkyflowError from "../../utils/skyflow-error";
import SKYFLOW_ERROR_CODE from "../../utils/skyflow-error-code";


/**
* Configuration for Reveal Elements.
*/
const RevealElement: React.FC<RevealElementProps> = ({ container, label, ...rest }) => {
const [element, setElement] = React.useState<RevealSkyflowElement>(undefined);
const [errorText, setErrorText] = React.useState<string>('');
Expand Down
4 changes: 4 additions & 0 deletions src/components/SkyflowProvider/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,15 @@ import Skyflow from '../../core/Skyflow';
import { IConfig, SkyflowConfigIntialState } from '../../utils/constants';

export interface ISkyflowProvider {
/** Configuration object for SkyflowProvider. */
config: IConfig,
}

export const skyflowContext = React.createContext<Skyflow>(null);

/**
* Sets up the Skyflow context using the provided configuration.
*/
const SkyflowProvider: React.FC<React.PropsWithChildren<ISkyflowProvider>> = ({children,config}): JSX.Element => {
const skyflow = new Skyflow(config);
return <skyflowContext.Provider value={skyflow}>{children}</skyflowContext.Provider>
Expand Down
4 changes: 4 additions & 0 deletions src/hooks/useCollectContainer/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,10 @@
import useSkyflowContext from '../../components/SkyflowProvider/hook';
import CollectContainer from '../../core/CollectContainer';

/**
* Container for Collect Elements.
* @returns Returns the CollectContainer instance.
*/
const useCollectContainer = () => {
const skyflowClient = useSkyflowContext();
return new CollectContainer(skyflowClient);
Expand Down
4 changes: 4 additions & 0 deletions src/hooks/useRevealContainer/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,10 @@
import useSkyflowContext from '../../components/SkyflowProvider/hook';
import RevealContainer from '../../core/RevealContainer';

/**
* Container for Reveal Elements.
* @returns Returns the RevealContainer instance.
*/
const useRevealContainer = () => {
const skyflowClient = useSkyflowContext();
return new RevealContainer(skyflowClient);
Expand Down
Loading