airbridge-react-native-sdk
Version:
Airbridge SDK for React Native
181 lines (153 loc) • 4.51 kB
text/typescript
import { check } from './check'
import { compute } from './compute'
import { create } from './create'
import { extract } from './extract'
export type JSONObject = {
[key: string]: JSONElement
}
export type JSONArray = JSONElement[]
export type JSONElement = JSONObject | JSONArray | string | number | boolean | null
export const createJSONObject = (object: unknown): JSONObject | undefined => {
if (!check.object(object)) {
return undefined
}
return create.object.fromEntries(extract.entries(object).map(([key, value]): [string, JSONElement] | undefined => {
if (!check.string(key)) {
return undefined
}
if (
!check.string(value)
&& !check.number(value)
&& !check.boolean(value)
&& !check.array(value)
&& !check.object(value)
&& !check.null(value)
) {
return undefined
}
if (check.array(value)) {
return compute.defined(createJSONArray(value), array => {
return [key, array]
})
}
if (check.object(value)) {
return compute.defined(createJSONObject(value), object => {
return [key, object]
})
}
return [key, value]
}).filter(value => check.defined(value)))
}
export const createJSONArray = (array: unknown): JSONArray | undefined => {
if (!check.array(array)) {
return undefined
}
return array.map((value): JSONElement | undefined => {
if (
!check.string(value)
&& !check.number(value)
&& !check.boolean(value)
&& !check.array(value)
&& !check.object(value)
&& !check.null(value)
) {
return undefined
}
if (check.array(value)) {
return createJSONArray(value)
}
if (check.object(value)) {
return createJSONObject(value)
}
return value
}).filter(value => check.defined(value))
}
export const createJSONElement = (element: unknown): JSONElement | undefined => {
if (
!check.string(element)
&& !check.number(element)
&& !check.boolean(element)
&& !check.array(element)
&& !check.object(element)
&& !check.null(element)
) {
return undefined
}
if (check.array(element)) {
return createJSONArray(element)
}
if (check.object(element)) {
return createJSONObject(element)
}
return element
}
export const checkJSONObject = (object: unknown): object is JSONObject => {
if (!check.object(object)) {
return false
}
for (const [key, value] of extract.entries(object)) {
if (!check.string(key)) {
return false
}
if (
!check.string(value)
&& !check.number(value)
&& !check.boolean(value)
&& !check.array(value)
&& !check.object(value)
&& !check.null(value)
) {
return false
}
if (check.array(value) && !checkJSONArray(value)) {
return false
}
if (check.object(value) && !checkJSONObject(value)) {
return false
}
}
return true
}
export const checkJSONArray = (array: unknown): array is JSONArray => {
if (!check.array(array)) {
return false
}
for (const value of array) {
if (
!check.string(value)
&& !check.number(value)
&& !check.boolean(value)
&& !check.array(value)
&& !check.object(value)
&& !check.null(value)
) {
return false
}
if (check.array(value) && !checkJSONArray(value)) {
return false
}
if (check.object(value) && !checkJSONObject(value)) {
return false
}
}
return true
}
export const checkJSONElement = (element: unknown): element is JSONElement => {
if (
!check.string(element)
&& !check.number(element)
&& !check.boolean(element)
&& !check.array(element)
&& !check.object(element)
&& !check.null(element)
) {
return false
}
if (check.array(element) && !checkJSONArray(element)) {
return false
}
if (check.object(element) && !checkJSONObject(element)) {
return false
}
return true
}