Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

@prismicio/types-internal

Package Overview
Dependencies
Maintainers
19
Versions
166
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@prismicio/types-internal - npm Package Compare versions

Comparing version 0.1.1 to 0.2.0

lib/customtypes/CustomType.d.ts

48

package.json
{
"name": "@prismicio/types-internal",
"version": "0.1.1",
"version": "0.2.0",
"description": "Prismic types for Custom Types and Prismic Data",

@@ -15,6 +15,6 @@ "keywords": [

"author": "Prismic <contact@prismic.io> (https://prismic.io)",
"main": "dist/index.js",
"types": "dist/index.d.ts",
"main": "lib/index.js",
"types": "lib/index.d.ts",
"files": [
"dist",
"lib",
"src"

@@ -31,30 +31,42 @@ ],

"release:alpha:dry": "standard-version --release-as major --prerelease alpha --dry-run",
"lint": "eslint --ext .js,.ts .",
"unit": "nyc --reporter=lcovonly --reporter=text --exclude-after-remap=false ava",
"size": "size-limit",
"test": "npm run lint && npm run unit && npm run build && npm run size"
"test": "jest --no-cache --silent=false --verbose=false",
"eslint": "eslint . --cache --cache-location .caches/eslint --cache-strategy content --ext js,ts,tsx --max-warnings 0",
"eslint-fix": "npm run eslint -- --fix",
"preflight": "npm run prettier && npm run build && npm run eslint",
"prettier": "prettier --check .",
"prettier-write": "prettier --write ."
},
"dependencies": {
"fp-ts": "^2.11.8",
"io-ts": "^2.2.16",
"io-ts-types": "^0.5.16"
"monocle-ts": "^2.3.11",
"newtype-ts": "^0.3.5",
"tslib": "^2.3.1"
},
"devDependencies": {
"@size-limit/preset-small-lib": "^7.0.5",
"@relmify/jest-fp-ts": "^1.1.1",
"@types/jest": "^27.4.0",
"@typescript-eslint/eslint-plugin": "^5.8.1",
"@typescript-eslint/parser": "^5.8.1",
"ava": "^3.15.0",
"eslint": "^8.6.0",
"eslint-config-prettier": "^8.3.0",
"eslint-plugin-prettier": "^4.0.0",
"eslint-plugin-tsdoc": "^0.2.14",
"eslint": "8.6.0",
"eslint-config-prettier": "8.3.0",
"eslint-plugin-only-warn": "1.0.3",
"eslint-plugin-simple-import-sort": "7.0.0",
"eslint-plugin-storybook": "0.5.5",
"fp-ts": "^2.11.8",
"io-ts": "^2.2.16",
"io-ts-types": "^0.5.16",
"jest": "^27.5.1",
"nyc": "^15.1.0",
"prettier": "^2.5.1",
"prettier-plugin-jsdoc": "^0.3.30",
"siroc": "^0.16.0",
"size-limit": "^7.0.5",
"standard-version": "^9.3.2",
"ts-eager": "^2.0.2",
"ts-jest": "^27.1.3",
"typescript": "^4.5.5"
},
"peerDependencies": {
"fp-ts": "^2.11.8",
"io-ts": "^2.2.16",
"io-ts-types": "^0.5.16"
},
"engines": {

@@ -61,0 +73,0 @@ "node": ">=12.7.0"

@@ -13,3 +13,3 @@ <!--

# prismic-types-internal
# @prismicio/types-internal

@@ -42,3 +42,3 @@ [![npm version][npm-version-src]][npm-version-href]

```bash
npm install prismic-types-internal
npm install @prismicio/types-internal
```

@@ -95,19 +95,19 @@

[forum-question]: https://community.prismic.io
[repo-bug-report]: https://github.com/prismicio/prismic-types-internal/issues/new?assignees=&labels=bug&template=bug_report.md&title=
[repo-feature-request]: https://github.com/prismicio/prismic-types-internal/issues/new?assignees=&labels=enhancement&template=feature_request.md&title=
[repo-pull-requests]: https://github.com/prismicio/prismic-types-internal/pulls
[repo-bug-report]: https://github.com/prismicio/@prismicio/types-internal/issues/new?assignees=&labels=bug&template=bug_report.md&title=
[repo-feature-request]: https://github.com/prismicio/@prismicio/types-internal/issues/new?assignees=&labels=enhancement&template=feature_request.md&title=
[repo-pull-requests]: https://github.com/prismicio/@prismicio/types-internal/pulls
<!-- Badges -->
[npm-version-src]: https://img.shields.io/npm/v/prismic-types-internal/latest.svg
[npm-version-href]: https://npmjs.com/package/prismic-types-internal
[npm-downloads-src]: https://img.shields.io/npm/dm/prismic-types-internal.svg
[npm-downloads-href]: https://npmjs.com/package/prismic-types-internal
[npm-version-src]: https://img.shields.io/npm/v/@prismicio/types-internal/latest.svg
[npm-version-href]: https://npmjs.com/package/@prismicio/types-internal
[npm-downloads-src]: https://img.shields.io/npm/dm/@prismicio/types-internal.svg
[npm-downloads-href]: https://npmjs.com/package/@prismicio/types-internal
[github-actions-ci-src]: https://github.com/prismicio/prismic-types-internal/workflows/ci/badge.svg
[github-actions-ci-href]: https://github.com/prismicio/prismic-types-internal/actions?query=workflow%3Aci
[codecov-src]: https://img.shields.io/codecov/c/github/prismicio/prismic-types-internal.svg
[codecov-href]: https://codecov.io/gh/prismicio/prismic-types-internal
[codecov-src]: https://img.shields.io/codecov/c/github/prismicio/@prismicio/types-internal.svg
[codecov-href]: https://codecov.io/gh/prismicio/@prismicio/types-internal
[conventional-commits-src]: https://img.shields.io/badge/Conventional%20Commits-1.0.0-yellow.svg
[conventional-commits-href]: https://conventionalcommits.org
[license-src]: https://img.shields.io/npm/l/prismic-types-internal.svg
[license-href]: https://npmjs.com/package/prismic-types-internal
[license-src]: https://img.shields.io/npm/l/@prismicio/types-internal.svg
[license-href]: https://npmjs.com/package/@prismicio/types-internal

@@ -1,51 +0,53 @@

import * as t from 'io-ts'
import { StringOrNull } from '../validators/StringOrNull'
import { Either, right, left } from 'fp-ts/lib/Either'
import { withFallback } from 'io-ts-types/lib/withFallback'
import { Either, left, right } from "fp-ts/lib/Either"
import * as t from "io-ts"
import { withFallback } from "io-ts-types/lib/withFallback"
import { Format } from './Format'
import { DynamicWidget } from './widgets/Widget'
import SharedSlice from './widgets/slices/SharedSlice'
import { DynamicSlice } from './widgets/slices/Slice'
import { DynamicSlices } from './widgets/slices/Slices'
import WidgetTypes from './widgets/WidgetTypes'
import SlicesTypes from './widgets/slices/SlicesTypes'
import { StringOrNull } from "../validators"
import { Format } from "./Format"
import {
DynamicSection,
sectionReader,
Sections,
StaticSection,
} from "./Section"
import type SharedSlice from "./widgets/slices/SharedSlice"
import type { DynamicSlice } from "./widgets/slices/Slice"
import type { DynamicSlices } from "./widgets/slices/Slices"
import SlicesTypes from "./widgets/slices/SlicesTypes"
import type { DynamicWidget } from "./widgets/Widget"
import WidgetTypes from "./widgets/WidgetTypes"
import { StaticSection, DynamicSection, sectionReader, Sections } from './Section'
class CustomTypeSlicesError extends Error {
slices: Array<string>
message: string
slices: Array<string>
override message: string
constructor(slices: Array<string>) {
super()
this.slices = slices
this.message = this._formatError(slices)
}
constructor(slices: Array<string>) {
super()
this.slices = slices
this.message = this._formatError(slices)
}
_formatError(slicesRefs: Array<string>) {
const slicesMsg = slicesRefs.map(ref => `\t - ${ref}`);
return (
`The following slices doesn't exists in your Prismic repository:
${slicesMsg.join('\n')}
_formatError(slicesRefs: Array<string>) {
const slicesMsg = slicesRefs.map((ref) => `\t - ${ref}`)
return `The following slices doesn't exists in your Prismic repository:
${slicesMsg.join("\n")}
`
)
}
}
}
function customTypeReader<F extends Format>(format: F) {
return t.exact(
t.intersection([
t.type({
id: t.string,
label: StringOrNull,
repeatable: withFallback(t.boolean, true),
json: t.record(t.string, sectionReader(format)),
status: withFallback(t.boolean, true)
}),
t.partial({
hash: t.string
})
])
)
return t.exact(
t.intersection([
t.type({
id: t.string,
label: StringOrNull,
repeatable: withFallback(t.boolean, true),
json: t.record(t.string, sectionReader(format)),
status: withFallback(t.boolean, true),
}),
t.partial({
hash: t.string,
}),
]),
)
}

@@ -60,84 +62,139 @@

function _retrieveSharedSlicesRef(customType: CustomType): Array<string> {
const flattenWidgets: Array<[string, DynamicWidget]> = Object.entries(customType.json)
.reduce((acc: Array<[string, DynamicWidget]>, [, section]: [string, DynamicSection]) => {
const sectionWidgets: Array<[string, DynamicWidget]> = Object.entries(section)
return acc.concat(sectionWidgets);
}, [])
const flattenWidgets: Array<[string, DynamicWidget]> = Object.entries(
customType.json,
).reduce(
(
acc: Array<[string, DynamicWidget]>,
[, section]: [string, DynamicSection],
) => {
const sectionWidgets: Array<[string, DynamicWidget]> =
Object.entries(section)
return acc.concat(sectionWidgets)
},
[],
)
const slicezones = flattenWidgets.filter(([, widget]: [string, DynamicWidget]) => widget.type === WidgetTypes.Slices) as Array<[string, DynamicSlices]>
const slicezones = flattenWidgets.filter(
([, widget]: [string, DynamicWidget]) => widget.type === WidgetTypes.Slices,
) as Array<[string, DynamicSlices]>
const allSharedRefs = slicezones.reduce((acc: Array<string>, [, slicezone]) => {
const sharedRefs = Object.entries(slicezone.config && slicezone.config.choices ? slicezone.config.choices : {})
.filter(([, slice]: [string, DynamicSlice]) => slice.type === SlicesTypes.SharedSlice)
.map(([key]) => key)
return acc.concat(sharedRefs);
}, []);
const allSharedRefs = slicezones.reduce(
(acc: Array<string>, [, slicezone]) => {
const sharedRefs = Object.entries(
slicezone.config && slicezone.config.choices
? slicezone.config.choices
: {},
)
.filter(
([, slice]: [string, DynamicSlice]) =>
slice.type === SlicesTypes.SharedSlice,
)
.map(([key]) => key)
return acc.concat(sharedRefs)
},
[],
)
return allSharedRefs
return allSharedRefs
}
function _mapSharedSlicesRefs<A>(customType: CustomType): (mapFn: (ref: string) => A) => Array<A> {
const refs = _retrieveSharedSlicesRef(customType)
function _mapSharedSlicesRefs<A>(
customType: CustomType,
): (mapFn: (ref: string) => A) => Array<A> {
const refs = _retrieveSharedSlicesRef(customType)
return function(mapFn: (ref: string) => A): Array<A> {
return refs.map(mapFn)
}
return function (mapFn: (ref: string) => A): Array<A> {
return refs.map(mapFn)
}
}
export function toStatic(customType: CustomType, sharedSlices: Map<string, SharedSlice>): StaticCustomType {
const json = Object.entries(customType.json)
.reduce((acc: { [key: string]: StaticSection }, [sectionKey, dynSection]: [string, DynamicSection]) => {
return { ...acc, [sectionKey]: Sections.toStatic(dynSection, sharedSlices) };
}, {})
export function toStatic(
customType: CustomType,
sharedSlices: Map<string, SharedSlice>,
): StaticCustomType {
const json = Object.entries(customType.json).reduce(
(
acc: { [key: string]: StaticSection },
[sectionKey, dynSection]: [string, DynamicSection],
) => {
return {
...acc,
[sectionKey]: Sections.toStatic(dynSection, sharedSlices),
}
},
{},
)
return { ...customType, json } as StaticCustomType;
return { ...customType, json } as StaticCustomType
}
export function validateSlices(customType: CustomType, sharedSlices: Map<string, SharedSlice>): Either<CustomTypeSlicesError, CustomType> {
const missingSlices = _mapSharedSlicesRefs<string | undefined>(customType)((ref: string) => {
const slice: SharedSlice | undefined = sharedSlices.get(ref)
const isMissing = !Boolean(slice)
if(isMissing) return ref
}).filter(Boolean) as Array<string>
export function validateSlices(
customType: CustomType,
sharedSlices: Map<string, SharedSlice>,
): Either<CustomTypeSlicesError, CustomType> {
const missingSlices = _mapSharedSlicesRefs<string | undefined>(customType)(
(ref: string) => {
const slice: SharedSlice | undefined = sharedSlices.get(ref)
const isMissing = !slice
if (isMissing) return ref
return
},
).filter(Boolean) as Array<string>
if(missingSlices.length > 0) return left(new CustomTypeSlicesError(missingSlices))
else return right(customType)
if (missingSlices.length > 0)
return left(new CustomTypeSlicesError(missingSlices))
else return right(customType)
}
export function collectWidgets(customType: CustomType, f:((ref: string, widget: DynamicWidget) => DynamicWidget|undefined)): CustomType {
const json = Object.entries(customType.json)
.reduce((acc, [sectionId, section]: [string, DynamicSection]) => {
const updatedSection = Object
.entries(section)
.reduce((acc, [ref, widget]) => {
const updatedWidget = f(ref, widget)
if (!!updatedWidget) {
return {...acc, [ref]: updatedWidget}
}
return acc;
}, {});
return {...acc, [sectionId]: updatedSection};
}, {});
export function collectWidgets(
customType: CustomType,
f: (ref: string, widget: DynamicWidget) => DynamicWidget | undefined,
): CustomType {
const json = Object.entries(customType.json).reduce(
(acc, [sectionId, section]: [string, DynamicSection]) => {
const updatedSection = Object.entries(section).reduce(
(acc, [ref, widget]) => {
const updatedWidget = f(ref, widget)
if (updatedWidget) {
return { ...acc, [ref]: updatedWidget }
}
return acc
},
{},
)
return { ...acc, [sectionId]: updatedSection }
},
{},
)
return { ...customType, json };
return { ...customType, json }
}
export function filterMissingSharedSlices(customType: CustomType, sharedSlices: Map<string, SharedSlice>): CustomType {
return collectWidgets(customType, (_widgetId, widget) => {
if (widget.type === WidgetTypes.Slices) {
if(!widget.config || !widget.config.choices) return widget
export function filterMissingSharedSlices(
customType: CustomType,
sharedSlices: Map<string, SharedSlice>,
): CustomType {
return collectWidgets(customType, (_widgetId, widget) => {
if (widget.type === WidgetTypes.Slices) {
if (!widget.config || !widget.config.choices) return widget
const choices = Object.entries(widget.config.choices)
.reduce((acc, [ sliceId, sliceValue ]: [string, DynamicSlice]) => {
if (sliceValue.type === SlicesTypes.SharedSlice && !sharedSlices.get(sliceId)) return acc
return { ...acc, [sliceId]: sliceValue }
}, {})
const choices = Object.entries(widget.config.choices).reduce(
(acc, [sliceId, sliceValue]: [string, DynamicSlice]) => {
if (
sliceValue.type === SlicesTypes.SharedSlice &&
!sharedSlices.get(sliceId)
)
return acc
return { ...acc, [sliceId]: sliceValue }
},
{},
)
const config = { ...widget.config, choices }
const config = { ...widget.config, choices }
return {...widget, config }
}
return { ...widget, config }
}
return widget
})
}
return widget
})
}
export enum Format {
Static = 'static',
Dynamic = 'dynamic'
}
Static = "static",
Dynamic = "dynamic",
}

@@ -1,4 +0,4 @@

export { Format } from './Format'
export * as Section from './Section'
export * as Widgets from './widgets'
export * from './CustomType'
export * from "./CustomType"
export { Format } from "./Format"
export * as Section from "./Section"
export * as Widgets from "./widgets"

@@ -1,9 +0,14 @@

import * as t from 'io-ts'
import * as t from "io-ts"
import { Format } from './Format'
import { widgetReader, StaticWidget, DynamicWidget, Widgets } from './widgets/Widget'
import SharedSlice from './widgets/slices/SharedSlice'
import { Format } from "./Format"
import type SharedSlice from "./widgets/slices/SharedSlice"
import {
DynamicWidget,
StaticWidget,
widgetReader,
Widgets,
} from "./widgets/Widget"
export function sectionReader<F extends Format>(format: F) {
return t.record(t.string, widgetReader(format))
return t.record(t.string, widgetReader(format))
}

@@ -18,9 +23,17 @@

export const Sections = {
toStatic(dynamic: DynamicSection, sharedSlices: Map<string, SharedSlice>): StaticSection {
const section = Object.entries(dynamic)
.reduce((acc: { [key: string]: StaticWidget }, [widgetKey, widget]: [string, DynamicWidget]) => {
return {...acc, [widgetKey]: Widgets.toStatic(widget, sharedSlices)}
}, {})
return section as StaticSection
}
}
toStatic(
dynamic: DynamicSection,
sharedSlices: Map<string, SharedSlice>,
): StaticSection {
const section = Object.entries(dynamic).reduce(
(
acc: { [key: string]: StaticWidget },
[widgetKey, widget]: [string, DynamicWidget],
) => {
return { ...acc, [widgetKey]: Widgets.toStatic(widget, sharedSlices) }
},
{},
)
return section as StaticSection
},
}

@@ -1,12 +0,13 @@

import * as t from 'io-ts'
import { StringOrNull } from '../../validators/StringOrNull'
import WidgetTypes from './WidgetTypes'
import NestableWidget from './nestable/NestableWidget'
import * as t from "io-ts"
import { StringOrNull } from "../../validators"
import NestableWidget from "./nestable/NestableWidget"
import WidgetTypes from "./WidgetTypes"
const GroupConfig = t.exact(
t.partial({
label: StringOrNull,
repeat: t.boolean,
fields: t.record(t.string, NestableWidget)
})
t.partial({
label: StringOrNull,
repeat: t.boolean,
fields: t.record(t.string, NestableWidget),
}),
)

@@ -16,13 +17,13 @@ type GroupConfig = t.TypeOf<typeof GroupConfig>

const Group = t.exact(
t.intersection([
t.type({
type: t.literal(WidgetTypes.Group)
}),
t.partial({
fieldset: StringOrNull,
icon: t.string,
description: t.string,
config: GroupConfig
})
])
t.intersection([
t.type({
type: t.literal(WidgetTypes.Group),
}),
t.partial({
fieldset: StringOrNull,
icon: t.string,
description: t.string,
config: GroupConfig,
}),
]),
)

@@ -29,0 +30,0 @@ type Group = t.TypeOf<typeof Group>

@@ -1,7 +0,7 @@

export * as Nestable from './nestable'
export * as Shared from './shared'
export * as Slices from './slices'
export * as Widget from './Widget'
export { default as Group } from './Group'
export { default as UID } from './UID'
export { default as WidgetTypes } from './WidgetTypes'
export { default as Group } from "./Group"
export * as Nestable from "./nestable"
export * as Shared from "./shared"
export * as Slices from "./slices"
export { default as UID } from "./UID"
export * as Widget from "./Widget"
export { default as WidgetTypes } from "./WidgetTypes"

@@ -1,12 +0,13 @@

import * as t from 'io-ts'
import { StringOrNull } from '../../../validators/StringOrNull'
import WidgetTypes from '../WidgetTypes'
import * as t from "io-ts"
import { StringOrNull } from "../../../validators"
import WidgetTypes from "../WidgetTypes"
const BooleanConfig = t.exact(
t.partial({
label: StringOrNull,
default_value: t.boolean,
placeholder_true: t.string,
placeholder_false: t.string
})
t.partial({
label: StringOrNull,
default_value: t.boolean,
placeholder_true: t.string,
placeholder_false: t.string,
}),
)

@@ -17,10 +18,10 @@

const BooleanField = t.exact(
t.intersection([
t.type({
type: t.literal(WidgetTypes.BooleanField)
}),
t.partial({
config: BooleanConfig
})
])
t.intersection([
t.type({
type: t.literal(WidgetTypes.BooleanField),
}),
t.partial({
config: BooleanConfig,
}),
]),
)

@@ -30,3 +31,2 @@

export default BooleanField
export default BooleanField

@@ -1,10 +0,11 @@

import * as t from 'io-ts'
import { StringOrNull } from '../../../validators/StringOrNull'
import WidgetTypes from '../WidgetTypes'
import * as t from "io-ts"
import { StringOrNull } from "../../../validators"
import WidgetTypes from "../WidgetTypes"
const ColorConfig = t.exact(
t.partial({
label: StringOrNull,
placeholder: t.string,
})
t.partial({
label: StringOrNull,
placeholder: t.string,
}),
)

@@ -14,11 +15,11 @@ type ColorConfig = t.TypeOf<typeof ColorConfig>

const Color = t.exact(
t.intersection([
t.type({
type: t.literal(WidgetTypes.Color)
}),
t.partial({
fieldset: StringOrNull,
config: ColorConfig
})
])
t.intersection([
t.type({
type: t.literal(WidgetTypes.Color),
}),
t.partial({
fieldset: StringOrNull,
config: ColorConfig,
}),
]),
)

@@ -25,0 +26,0 @@ type Color = t.TypeOf<typeof Color>

@@ -1,11 +0,12 @@

import * as t from 'io-ts'
import { StringOrNull } from '../../../validators/StringOrNull'
import WidgetTypes from '../WidgetTypes'
import * as t from "io-ts"
import { StringOrNull } from "../../../validators"
import WidgetTypes from "../WidgetTypes"
const DateConfig = t.exact(
t.partial({
label: StringOrNull,
placeholder: t.string,
default: t.string
})
t.partial({
label: StringOrNull,
placeholder: t.string,
default: t.string,
}),
)

@@ -15,14 +16,14 @@ type DateConfig = t.TypeOf<typeof DateConfig>

const Date = t.exact(
t.intersection([
t.type({
type: t.literal(WidgetTypes.Date)
}),
t.partial({
fieldset: StringOrNull,
config: DateConfig
})
])
t.intersection([
t.type({
type: t.literal(WidgetTypes.Date),
}),
t.partial({
fieldset: StringOrNull,
config: DateConfig,
}),
]),
)
type Date = t.TypeOf<typeof Date>
export default Date
export default Date

@@ -1,11 +0,12 @@

import * as t from 'io-ts'
import { StringOrNull } from '../../../validators/StringOrNull'
import WidgetTypes from '../WidgetTypes'
import * as t from "io-ts"
import { StringOrNull } from "../../../validators"
import WidgetTypes from "../WidgetTypes"
const EmbedConfig = t.exact(
t.partial({
label: StringOrNull,
placeholder: t.string,
useAsTitle: t.boolean
})
t.partial({
label: StringOrNull,
placeholder: t.string,
useAsTitle: t.boolean,
}),
)

@@ -15,14 +16,14 @@ type EmbedConfig = t.TypeOf<typeof EmbedConfig>

const Embed = t.exact(
t.intersection([
t.type({
type: t.literal(WidgetTypes.Embed)
}),
t.partial({
fieldset: StringOrNull,
config: EmbedConfig
})
])
t.intersection([
t.type({
type: t.literal(WidgetTypes.Embed),
}),
t.partial({
fieldset: StringOrNull,
config: EmbedConfig,
}),
]),
)
type Embed = t.TypeOf<typeof Embed>
export default Embed
export default Embed

@@ -1,9 +0,10 @@

import * as t from 'io-ts'
import { StringOrNull } from '../../../validators/StringOrNull'
import WidgetTypes from '../WidgetTypes'
import * as t from "io-ts"
import { StringOrNull } from "../../../validators"
import WidgetTypes from "../WidgetTypes"
const GeoPointConfig = t.exact(
t.partial({
label: StringOrNull
})
t.partial({
label: StringOrNull,
}),
)

@@ -13,14 +14,14 @@ type GeoPointConfig = t.TypeOf<typeof GeoPointConfig>

const GeoPoint = t.exact(
t.intersection([
t.type({
type: t.literal(WidgetTypes.GeoPoint)
}),
t.partial({
fieldset: StringOrNull,
config: GeoPointConfig
})
])
t.intersection([
t.type({
type: t.literal(WidgetTypes.GeoPoint),
}),
t.partial({
fieldset: StringOrNull,
config: GeoPointConfig,
}),
]),
)
type GeoPoint = t.TypeOf<typeof GeoPoint>
export default GeoPoint
export default GeoPoint

@@ -1,13 +0,14 @@

import * as t from 'io-ts'
import { StringOrNull } from '../../../validators/StringOrNull'
import WidgetTypes from '../WidgetTypes'
import ImageConstraint from '../shared/ImageConstraint'
import * as t from "io-ts"
import { StringOrNull } from "../../../validators"
import ImageConstraint from "../shared/ImageConstraint"
import WidgetTypes from "../WidgetTypes"
const Thumbnail = t.exact(
t.intersection([
t.type({
name: t.string
}),
ImageConstraint
])
t.intersection([
t.type({
name: t.string,
}),
ImageConstraint,
]),
)

@@ -17,22 +18,21 @@ type Thumbnail = t.TypeOf<typeof Thumbnail>

const ImageConfig = t.exact(
t.partial({
label: StringOrNull,
placeholder: t.string,
constraint: ImageConstraint,
thumbnails: t.array(Thumbnail)
})
t.partial({
label: StringOrNull,
placeholder: t.string,
constraint: ImageConstraint,
thumbnails: t.array(Thumbnail),
}),
)
type ImageConfig = t.TypeOf<typeof ImageConfig>
const Image = t.exact(
t.intersection([
t.type({
type: t.literal(WidgetTypes.Image)
}),
t.partial({
fieldset: StringOrNull,
config: ImageConfig
})
])
t.intersection([
t.type({
type: t.literal(WidgetTypes.Image),
}),
t.partial({
fieldset: StringOrNull,
config: ImageConfig,
}),
]),
)

@@ -39,0 +39,0 @@ type Image = t.TypeOf<typeof Image>

@@ -1,15 +0,15 @@

export { default as BooleanField } from './BooleanField'
export { default as Color } from './Color'
export { default as Date } from './Date'
export { default as GeoPoint } from './GeoPoint'
export { default as Image } from './Image'
export { default as IntegrationField } from './IntegrationField'
export { default as Link } from './Link'
export { default as NestableWidget } from './NestableWidget'
export { default as Number } from './Number'
export { default as Range } from './Range'
export { default as RichText } from './RichText'
export { default as Select } from './Select'
export { default as Separator } from './Separator'
export { default as Text } from './Text'
export { default as Timestamp } from './Timestamp'
export { default as BooleanField } from "./BooleanField"
export { default as Color } from "./Color"
export { default as Date } from "./Date"
export { default as GeoPoint } from "./GeoPoint"
export { default as Image } from "./Image"
export { default as IntegrationField } from "./IntegrationField"
export { default as Link } from "./Link"
export { default as NestableWidget } from "./NestableWidget"
export { default as Number } from "./Number"
export { default as Range } from "./Range"
export { default as RichText } from "./RichText"
export { default as Select } from "./Select"
export { default as Separator } from "./Separator"
export { default as Text } from "./Text"
export { default as Timestamp } from "./Timestamp"

@@ -1,11 +0,12 @@

import * as t from 'io-ts'
import { StringOrNull } from '../../../validators/StringOrNull'
import WidgetTypes from '../WidgetTypes'
import * as t from "io-ts"
import { StringOrNull } from "../../../validators"
import WidgetTypes from "../WidgetTypes"
const IntegrationFieldConfig = t.exact(
t.partial({
label: StringOrNull,
placeholder: t.string,
catalog: t.string
})
t.partial({
label: StringOrNull,
placeholder: t.string,
catalog: t.string,
}),
)

@@ -15,11 +16,11 @@ type IntegrationFieldConfig = t.TypeOf<typeof IntegrationFieldConfig>

const IntegrationField = t.exact(
t.intersection([
t.type({
type: t.literal(WidgetTypes.IntegrationField)
}),
t.partial({
fieldset: StringOrNull,
config: IntegrationFieldConfig
})
])
t.intersection([
t.type({
type: t.literal(WidgetTypes.IntegrationField),
}),
t.partial({
fieldset: StringOrNull,
config: IntegrationFieldConfig,
}),
]),
)

@@ -26,0 +27,0 @@ type IntegrationField = t.TypeOf<typeof IntegrationField>

@@ -1,69 +0,81 @@

import * as t from 'io-ts'
import { withFallback } from 'io-ts-types/lib/withFallback'
import { either } from 'fp-ts/lib/Either'
import { StringOrNull } from '../../../validators/StringOrNull'
import WidgetTypes from '../WidgetTypes'
import { either } from "fp-ts/lib/Either"
import * as t from "io-ts"
import { withFallback } from "io-ts-types/lib/withFallback"
const arrayString = (entries: string | string[] | {
[x: string]: {
name: string;
}[];
} | null) => {
if(entries instanceof Array) {
const isValidEntries = entries.reduce((acc, l) => acc && typeof l === 'string', true)
if(isValidEntries) return t.success(entries)
}
import { StringOrNull } from "../../../validators"
import WidgetTypes from "../WidgetTypes"
const arrayString = (
entries:
| string
| string[]
| {
[x: string]: {
name: string
}[]
}
| undefined,
) => {
if (entries instanceof Array) {
const isValidEntries = entries.reduce(
(acc, l) => acc && typeof l === "string",
true,
)
if (isValidEntries) return t.success(entries)
}
return
}
const plainString = (entries: string | string[] | {
[x: string]: {
name: string;
}[];
} | null) => {
if(typeof entries === 'string') {
return t.success([entries])
}
const plainString = (
entries:
| string
| string[]
| {
[x: string]: {
name: string
}[]
}
| undefined,
) => {
if (typeof entries === "string") {
return t.success([entries])
}
return
}
const MasksArrayString = new t.Type<Array<string>, object, unknown>(
'MasksArrayString',
(u: unknown): u is any => {
return u instanceof Array
},
(u: unknown, context: t.Context) => {
return either.chain(
t.union([
t.array(t.string),
t.string,
]).validate(u, context), (masks) => {
return (
arrayString(masks) ||
plainString(masks) ||
t.failure(u, context)
)
}
)
},
res => res
"MasksArrayString",
(u: unknown): u is Array<string> => {
return u instanceof Array
},
(u: unknown, context: t.Context) => {
return either.chain(
t.union([t.array(t.string), t.string]).validate(u, context),
(masks) => {
return arrayString(masks) || plainString(masks) || t.failure(u, context)
},
)
},
(res) => res,
)
const LinkConfig = t.exact(
t.partial({
label: StringOrNull,
useAsTitle: t.boolean,
placeholder: t.string,
select: withFallback(
t.union([
t.literal('media'),
t.literal('document'),
t.literal('web'),
t.null
]),
null
),
customtypes: t.array(t.string), // `customtypes` and `masks` are alternatives
masks: MasksArrayString,
tags: MasksArrayString,
allowTargetBlank: t.boolean
})
t.partial({
label: StringOrNull,
useAsTitle: t.boolean,
placeholder: t.string,
select: withFallback(
t.union([
t.literal("media"),
t.literal("document"),
t.literal("web"),
t.null,
]),
null,
),
customtypes: t.array(t.string), // `customtypes` and `masks` are alternatives
masks: MasksArrayString,
tags: MasksArrayString,
allowTargetBlank: t.boolean,
}),
)

@@ -73,11 +85,11 @@ type LinkConfig = t.TypeOf<typeof LinkConfig>

const Link = t.exact(
t.intersection([
t.type({
type: t.literal(WidgetTypes.Link)
}),
t.partial({
fieldset: StringOrNull,
config: LinkConfig
})
])
t.intersection([
t.type({
type: t.literal(WidgetTypes.Link),
}),
t.partial({
fieldset: StringOrNull,
config: LinkConfig,
}),
]),
)

@@ -84,0 +96,0 @@ type Link = t.TypeOf<typeof Link>

@@ -1,35 +0,35 @@

import * as t from 'io-ts'
import * as t from "io-ts"
import Color from './Color'
import BooleanField from './BooleanField'
import Date from './Date'
import Embed from './Embed'
import GeoPoint from './GeoPoint'
import Number from './Number'
import Range from './Range'
import RichText from './RichText'
import Select from './Select'
import Separator from './Separator'
import Text from './Text'
import Timestamp from './Timestamp'
import Link from './Link'
import Image from './Image'
import IntegrationField from './IntegrationField'
import BooleanField from "./BooleanField"
import Color from "./Color"
import Date from "./Date"
import Embed from "./Embed"
import GeoPoint from "./GeoPoint"
import Image from "./Image"
import IntegrationField from "./IntegrationField"
import Link from "./Link"
import Number from "./Number"
import Range from "./Range"
import RichText from "./RichText"
import Select from "./Select"
import Separator from "./Separator"
import Text from "./Text"
import Timestamp from "./Timestamp"
const NestableWidget = t.union([
Color,
BooleanField,
Embed,
GeoPoint,
Date,
Number,
Range,
RichText,
Select,
Separator,
Text,
Timestamp,
Link,
Image,
IntegrationField
Color,
BooleanField,
Embed,
GeoPoint,
Date,
Number,
Range,
RichText,
Select,
Separator,
Text,
Timestamp,
Link,
Image,
IntegrationField,
])

@@ -39,2 +39,2 @@

export default NestableWidget
export default NestableWidget

@@ -1,14 +0,15 @@

import * as t from 'io-ts'
import { StringOrNull } from '../../../validators/StringOrNull'
import WidgetTypes from '../WidgetTypes'
import { NumberFromString } from 'io-ts-types/lib/NumberFromString'
import * as t from "io-ts"
import { NumberFromString } from "io-ts-types/lib/NumberFromString"
import { StringOrNull } from "../../../validators"
import WidgetTypes from "../WidgetTypes"
const NumberConfig = t.exact(
t.partial({
label: StringOrNull,
placeholder: t.string,
min: t.union([t.number, NumberFromString]),
max: t.union([t.number, NumberFromString]),
step: t.union([t.number, NumberFromString])
})
t.partial({
label: StringOrNull,
placeholder: t.string,
min: t.union([t.number, NumberFromString]),
max: t.union([t.number, NumberFromString]),
step: t.union([t.number, NumberFromString]),
}),
)

@@ -18,14 +19,14 @@ type NumberConfig = t.TypeOf<typeof NumberConfig>

const Number = t.exact(
t.intersection([
t.type({
type: t.literal(WidgetTypes.Number)
}),
t.partial({
fieldset: StringOrNull,
config: NumberConfig
})
])
t.intersection([
t.type({
type: t.literal(WidgetTypes.Number),
}),
t.partial({
fieldset: StringOrNull,
config: NumberConfig,
}),
]),
)
type Number = t.TypeOf<typeof Number>
export default Number
export default Number

@@ -1,14 +0,15 @@

import * as t from 'io-ts'
import { StringOrNull } from '../../../validators/StringOrNull'
import WidgetTypes from '../WidgetTypes'
import { NumberFromString } from 'io-ts-types/lib/NumberFromString'
import * as t from "io-ts"
import { NumberFromString } from "io-ts-types/lib/NumberFromString"
import { StringOrNull } from "../../../validators"
import WidgetTypes from "../WidgetTypes"
const RangeConfig = t.exact(
t.partial({
label: StringOrNull,
placeholder: t.string,
min: t.union([t.number, NumberFromString]),
max: t.union([t.number, NumberFromString]),
step: t.union([t.number, NumberFromString]),
})
t.partial({
label: StringOrNull,
placeholder: t.string,
min: t.union([t.number, NumberFromString]),
max: t.union([t.number, NumberFromString]),
step: t.union([t.number, NumberFromString]),
}),
)

@@ -18,14 +19,14 @@ type RangeConfig = t.TypeOf<typeof RangeConfig>

const Range = t.exact(
t.intersection([
t.type({
type: t.literal(WidgetTypes.Range)
}),
t.partial({
fieldset: StringOrNull,
config: RangeConfig
})
])
t.intersection([
t.type({
type: t.literal(WidgetTypes.Range),
}),
t.partial({
fieldset: StringOrNull,
config: RangeConfig,
}),
]),
)
type Range = t.TypeOf<typeof Range>
export default Range
export default Range

@@ -1,144 +0,174 @@

import * as t from 'io-ts'
import { StringOrNull } from '../../../validators/StringOrNull'
import { either } from 'fp-ts/lib/Either'
import WidgetTypes from '../WidgetTypes'
import ImageConstraint from '../shared/ImageConstraint'
import { either } from "fp-ts/lib/Either"
import * as t from "io-ts"
const DEFAULT_OPTION = 'paragraph'
import { StringOrNull } from "../../../validators"
import ImageConstraint from "../shared/ImageConstraint"
import WidgetTypes from "../WidgetTypes"
const DEFAULT_OPTION = "paragraph"
const options = [
'heading1',
'heading2',
'heading3',
'heading4',
'heading5',
'heading6',
'paragraph',
'strong',
'em',
'preformatted',
'hyperlink',
'image',
'embed',
'list-item',
'o-list-item',
'rtl'
];
"heading1",
"heading2",
"heading3",
"heading4",
"heading5",
"heading6",
"paragraph",
"strong",
"em",
"preformatted",
"hyperlink",
"image",
"embed",
"list-item",
"o-list-item",
"rtl",
]
const RichTextOptions = new t.Type<string, string, unknown>(
'RichTextOptions',
(u: unknown): u is string => typeof u === 'string',
(u: unknown, context: t.Context) => {
return either.chain(
t.union([
t.string,
t.null
]).validate(u as unknown, context), (s: string | null) => {
if(!s) return t.success(DEFAULT_OPTION)
const entries = s.split(',').map((e: string) => e.trim())
const filtered = entries.filter(entry => options.includes(entry))
if(!filtered.length) return t.success(DEFAULT_OPTION)
return t.success(filtered.join(','))
}
);
},
a => a
"RichTextOptions",
(u: unknown): u is string => typeof u === "string",
(u: unknown, context: t.Context) => {
return either.chain(
t.union([t.string, t.null]).validate(u, context),
(s: string | null) => {
if (!s) return t.success(DEFAULT_OPTION)
const entries = s.split(",").map((e: string) => e.trim())
const filtered = entries.filter((entry) => options.includes(entry))
if (!filtered.length) return t.success(DEFAULT_OPTION)
return t.success(filtered.join(","))
},
)
},
(a) => a,
)
const NoLabels = (labels: string | string[] | {
[x: string]: {
name: string;
}[];
} | null) => {
if(!labels) return t.success([])
const NoLabels = (
labels:
| string
| string[]
| {
[x: string]: {
name: string
}[]
}
| null,
) => {
if (!labels) return t.success([])
return
}
const LabelsAsObject = (labels: string | string[] | {
[x: string]: {
name: string;
}[];
} | null) => {
if(labels instanceof Object) {
const labelsObj = labels as { [x: string]: { name: string }[] }
// empty labels
if(!Object.entries(labelsObj).length) return t.success([])
// weird case labels with empty key as parent
if(labelsObj['']) {
return t.success(labelsObj[''].map(l => l.name))
}
const LabelsAsObject = (
labels:
| string
| string[]
| {
[x: string]: {
name: string
}[]
}
| null,
) => {
if (labels instanceof Object) {
const labelsObj = labels as { [x: string]: { name: string }[] }
const convertedObjectToArray = Object.entries(labelsObj)
.reduce<ReadonlyArray<string>>((acc, [, labelsEntries]) => {
return acc.concat(labelsEntries.map(l => l.name))
}, [])
.filter(Boolean)
// empty labels
if (!Object.entries(labelsObj).length) return t.success([])
return t.success(convertedObjectToArray)
}
// weird case labels with empty key as parent
if (labelsObj[""]) {
return t.success(labelsObj[""].map((l) => l.name))
}
const convertedObjectToArray = Object.entries(labelsObj)
.reduce<ReadonlyArray<string>>((acc, [, labelsEntries]) => {
return acc.concat(labelsEntries.map((l) => l.name))
}, [])
.filter(Boolean)
return t.success(convertedObjectToArray)
}
return
}
const LabelsAsArray = (labels: string | string[] | {
[x: string]: {
name: string;
}[];
} | null) => {
if(labels instanceof Array) {
const isValidLabels = labels.reduce((acc, l) => acc && typeof l === 'string', true)
if(isValidLabels) return t.success(labels)
}
const LabelsAsArray = (
labels:
| string
| string[]
| {
[x: string]: {
name: string
}[]
}
| null,
) => {
if (labels instanceof Array) {
const isValidLabels = labels.reduce(
(acc, l) => acc && typeof l === "string",
true,
)
if (isValidLabels) return t.success(labels)
}
return
}
const LabelsAsString = (labels: string | string[] | {
[x: string]: {
name: string;
}[];
} | null) => {
if(typeof labels === 'string') {
return t.success([labels])
}
const LabelsAsString = (
labels:
| string
| string[]
| {
[x: string]: {
name: string
}[]
}
| null,
) => {
if (typeof labels === "string") {
return t.success([labels])
}
return
}
const RichTextLabels = new t.Type<Array<string>, object, unknown>(
'RichTextLabels',
(u: unknown): u is any => {
return u instanceof Array
},
(u: unknown, context: t.Context) => {
const legacyValidator = t.record(t.string, t.array(t.record(t.literal("name"), t.string)))
const validator = t.array(t.string)
"RichTextLabels",
(u: unknown): u is Array<string> => {
return u instanceof Array
},
(u: unknown, context: t.Context) => {
const legacyValidator = t.record(
t.string,
t.array(t.record(t.literal("name"), t.string)),
)
const validator = t.array(t.string)
return either.chain(
t.union([
legacyValidator,
validator,
t.string,
t.null,
]).validate(u, context), (labels) => {
return (
NoLabels(labels) ||
LabelsAsArray(labels) ||
LabelsAsObject(labels) ||
LabelsAsString(labels) ||
t.failure(u, context)
)
}
)
},
res => res
return either.chain(
t
.union([legacyValidator, validator, t.string, t.null])
.validate(u, context),
(labels) => {
return (
NoLabels(labels) ||
LabelsAsArray(labels) ||
LabelsAsObject(labels) ||
LabelsAsString(labels) ||
t.failure(u, context)
)
},
)
},
(res) => res,
)
const RichTextConfig = t.exact(
t.partial({
label: StringOrNull,
placeholder: t.string,
useAsTitle: t.boolean,
single: RichTextOptions,
multi: RichTextOptions,
imageConstraint: ImageConstraint,
labels: RichTextLabels,
allowTargetBlank: t.boolean
})
t.partial({
label: StringOrNull,
placeholder: t.string,
useAsTitle: t.boolean,
single: RichTextOptions,
multi: RichTextOptions,
imageConstraint: ImageConstraint,
labels: RichTextLabels,
allowTargetBlank: t.boolean,
}),
)

@@ -148,11 +178,11 @@ type RichTextConfig = t.TypeOf<typeof RichTextConfig>

const RichText = t.exact(
t.intersection([
t.type({
type: t.literal(WidgetTypes.RichText)
}),
t.partial({
fieldset: StringOrNull,
config: RichTextConfig
})
])
t.intersection([
t.type({
type: t.literal(WidgetTypes.RichText),
}),
t.partial({
fieldset: StringOrNull,
config: RichTextConfig,
}),
]),
)

@@ -159,0 +189,0 @@ type RichText = t.TypeOf<typeof RichText>

@@ -1,15 +0,17 @@

import * as t from 'io-ts'
import { StringOrNull } from '../../../validators/StringOrNull'
import { StringFromBoolean } from '../../../validators/StringFromBoolean'
import WidgetTypes from '../WidgetTypes'
import * as t from "io-ts"
import { StringFromNumber } from '../../../validators/StringFromNumber'
import {
StringFromBoolean,
StringFromNumber,
StringOrNull,
} from "../../../validators"
import WidgetTypes from "../WidgetTypes"
const SelectConfig = t.exact(
t.partial({
label: StringOrNull,
placeholder: t.string,
default_value: t.string,
options: t.array(t.union([t.string, StringFromNumber, StringFromBoolean]))
})
t.partial({
label: StringOrNull,
placeholder: t.string,
default_value: t.string,
options: t.array(t.union([t.string, StringFromNumber, StringFromBoolean])),
}),
)

@@ -19,11 +21,11 @@ type SelectConfig = t.TypeOf<typeof SelectConfig>

const Select = t.exact(
t.intersection([
t.type({
type: t.literal(WidgetTypes.Select)
}),
t.partial({
fieldset: StringOrNull,
config: SelectConfig
})
])
t.intersection([
t.type({
type: t.literal(WidgetTypes.Select),
}),
t.partial({
fieldset: StringOrNull,
config: SelectConfig,
}),
]),
)

@@ -33,2 +35,1 @@ type Select = t.TypeOf<typeof Select>

export default Select

@@ -1,9 +0,10 @@

import * as t from 'io-ts'
import { StringOrNull } from '../../../validators/StringOrNull'
import WidgetTypes from '../WidgetTypes'
import * as t from "io-ts"
import { StringOrNull } from "../../../validators"
import WidgetTypes from "../WidgetTypes"
const SeparatorConfig = t.exact(
t.partial({
label: StringOrNull
})
t.partial({
label: StringOrNull,
}),
)

@@ -13,10 +14,10 @@ type SeparatorConfig = t.TypeOf<typeof SeparatorConfig>

const Separator = t.exact(
t.intersection([
t.type({
type: t.literal(WidgetTypes.Separator)
}),
t.partial({
config: SeparatorConfig
})
])
t.intersection([
t.type({
type: t.literal(WidgetTypes.Separator),
}),
t.partial({
config: SeparatorConfig,
}),
]),
)

@@ -23,0 +24,0 @@ type Separator = t.TypeOf<typeof Separator>

@@ -1,11 +0,12 @@

import * as t from 'io-ts'
import { StringOrNull } from '../../../validators/StringOrNull'
import WidgetTypes from '../WidgetTypes'
import * as t from "io-ts"
import { StringOrNull } from "../../../validators"
import WidgetTypes from "../WidgetTypes"
const TextConfig = t.exact(
t.partial({
label: StringOrNull,
useAsTitle: t.boolean,
placeholder: t.string
})
t.partial({
label: StringOrNull,
useAsTitle: t.boolean,
placeholder: t.string,
}),
)

@@ -15,11 +16,11 @@ type TextConfig = t.TypeOf<typeof TextConfig>

const Text = t.exact(
t.intersection([
t.type({
type: t.literal(WidgetTypes.Text)
}),
t.partial({
fieldset: StringOrNull,
config: TextConfig
})
])
t.intersection([
t.type({
type: t.literal(WidgetTypes.Text),
}),
t.partial({
fieldset: StringOrNull,
config: TextConfig,
}),
]),
)

@@ -26,0 +27,0 @@ type Text = t.TypeOf<typeof Text>

@@ -1,11 +0,12 @@

import * as t from 'io-ts'
import { StringOrNull } from '../../../validators/StringOrNull'
import WidgetTypes from '../WidgetTypes'
import * as t from "io-ts"
import { StringOrNull } from "../../../validators"
import WidgetTypes from "../WidgetTypes"
const TimestampConfig = t.exact(
t.partial({
label: StringOrNull,
placeholder: t.string,
default: t.string
})
t.partial({
label: StringOrNull,
placeholder: t.string,
default: t.string,
}),
)

@@ -15,14 +16,14 @@ type TimestampConfig = t.TypeOf<typeof TimestampConfig>

const Timestamp = t.exact(
t.intersection([
t.type({
type: t.literal(WidgetTypes.Timestamp)
}),
t.partial({
fieldset: StringOrNull,
config: TimestampConfig
})
])
t.intersection([
t.type({
type: t.literal(WidgetTypes.Timestamp),
}),
t.partial({
fieldset: StringOrNull,
config: TimestampConfig,
}),
]),
)
type Timestamp = t.TypeOf<typeof Timestamp>
export default Timestamp
export default Timestamp

@@ -1,35 +0,37 @@

import * as t from 'io-ts'
import { either } from 'fp-ts/lib/Either'
import { IntFromString } from 'io-ts-types/lib/IntFromString'
import { either } from "fp-ts/lib/Either"
import * as t from "io-ts"
import { IntFromString } from "io-ts-types/lib/IntFromString"
import { IntFromNumber } from '../../../validators/IntFromNumber'
import { IntFromPixels } from '../../../validators/IntFromPixels'
import { IntFromNumber, IntFromPixels } from "../../../validators"
const SideConstraint = new t.Type<number | null, any, unknown>(
'SideConstraints',
(u: unknown): u is any => {
return !u || typeof u === 'number'
},
(u: unknown, context: t.Context) => {
return either.chain(
t.union([
t.literal('auto'),
t.literal(''),
t.Int,
IntFromString,
IntFromNumber,
IntFromPixels,
t.null
]).validate(u, context), (constraint) => {
if(constraint === 'auto' || constraint === '') return t.success(null)
return t.success(constraint)
}
)
},
res => res
const SideConstraint = new t.Type<number | null, unknown, unknown>(
"SideConstraints",
(u: unknown): u is number | null => {
return !u || typeof u === "number"
},
(u: unknown, context: t.Context) => {
return either.chain(
t
.union([
t.literal("auto"),
t.literal(""),
t.Int,
IntFromString,
IntFromNumber,
IntFromPixels,
t.null,
])
.validate(u, context),
(constraint) => {
if (constraint === "auto" || constraint === "") return t.success(null)
return t.success(constraint)
},
)
},
(res) => res,
)
const ImageConstraint = t.partial({
width: SideConstraint,
height: SideConstraint
width: SideConstraint,
height: SideConstraint,
})

@@ -36,0 +38,0 @@

@@ -1,1 +0,1 @@

export { default as ImageConstraint } from './ImageConstraint'
export { default as ImageConstraint } from "./ImageConstraint"

@@ -1,11 +0,11 @@

import * as t from 'io-ts'
import * as t from "io-ts"
import SlicesTypes from './SlicesTypes'
import { StringOrNull } from "../../../validators"
import NestableWidget from "../nestable/NestableWidget"
import { StringOrNull } from '../../../validators/StringOrNull'
import SlicesTypes from "./SlicesTypes"
const CompositeSliceConfig = t.exact(
t.partial({
label: StringOrNull
})
t.partial({
label: StringOrNull,
}),
)

@@ -15,19 +15,19 @@ type CompositeSliceConfig = t.TypeOf<typeof CompositeSliceConfig>

const CompositeSlice = t.exact(
t.intersection([
t.type({
type: t.literal(SlicesTypes.Slice)
}),
t.partial({
fieldset: StringOrNull,
description: t.string,
icon: t.string,
display: t.string,
'non-repeat': t.record(t.string, NestableWidget),
repeat: t.record(t.string, NestableWidget),
config: CompositeSliceConfig
})
])
t.intersection([
t.type({
type: t.literal(SlicesTypes.Slice),
}),
t.partial({
fieldset: StringOrNull,
description: t.string,
icon: t.string,
display: t.string,
"non-repeat": t.record(t.string, NestableWidget),
repeat: t.record(t.string, NestableWidget),
config: CompositeSliceConfig,
}),
]),
)
type CompositeSlice = t.TypeOf<typeof CompositeSlice>
export default CompositeSlice
export default CompositeSlice

@@ -1,7 +0,7 @@

export { default as CompositeSlice } from './CompositeSlice'
export { default as LegacySlice } from './LegacySlice'
export { default as SharedSlice } from './SharedSlice'
export { default as SharedSliceRef } from './SharedSliceRef'
export { default as SlicesTypes } from './SlicesTypes'
export * as Slice from './Slice'
export * as SliceZone from './Slices'
export { default as CompositeSlice } from "./CompositeSlice"
export { default as LegacySlice } from "./LegacySlice"
export { default as SharedSlice } from "./SharedSlice"
export { default as SharedSliceRef } from "./SharedSliceRef"
export * as Slice from "./Slice"
export * as SliceZone from "./Slices"
export { default as SlicesTypes } from "./SlicesTypes"

@@ -1,15 +0,11 @@

import * as t from 'io-ts'
import * as t from "io-ts"
import UID from '../UID'
import NestableWidget from '../nestable/NestableWidget'
import Group from '../Group'
import Group from "../Group"
import NestableWidget from "../nestable/NestableWidget"
import UID from "../UID"
const LegacySlice = t.union([
UID,
NestableWidget,
Group
])
const LegacySlice = t.union([UID, NestableWidget, Group])
type LegacySlice = t.TypeOf<typeof LegacySlice>
export default LegacySlice
export default LegacySlice

@@ -1,24 +0,26 @@

import * as t from 'io-ts'
import { withFallback } from 'io-ts-types/lib/withFallback'
import NestableWidget from '../nestable/NestableWidget'
import SlicesTypes from './SlicesTypes'
import * as t from "io-ts"
import { withFallback } from "io-ts-types/lib/withFallback"
const IMAGE_PLACEHOLDER_URL = 'https://images.prismic.io/slice-machine/621a5ec4-0387-4bc5-9860-2dd46cbc07cd_default_ss.png?auto=compress,format'
import NestableWidget from "../nestable/NestableWidget"
import SlicesTypes from "./SlicesTypes"
const IMAGE_PLACEHOLDER_URL =
"https://images.prismic.io/slice-machine/621a5ec4-0387-4bc5-9860-2dd46cbc07cd_default_ss.png?auto=compress,format"
const Variation = t.exact(
t.intersection([
t.type({
id: t.string,
name: t.string,
description: t.string,
imageUrl: withFallback(t.string, IMAGE_PLACEHOLDER_URL),
docURL: t.string,
version: t.string
}),
t.partial({
display: t.string,
primary: t.record(t.string, NestableWidget),
items: t.record(t.string, NestableWidget)
})
])
t.intersection([
t.type({
id: t.string,
name: t.string,
description: t.string,
imageUrl: withFallback(t.string, IMAGE_PLACEHOLDER_URL),
docURL: t.string,
version: t.string,
}),
t.partial({
display: t.string,
primary: t.record(t.string, NestableWidget),
items: t.record(t.string, NestableWidget),
}),
]),
)

@@ -29,13 +31,13 @@

const SharedSlice = t.exact(
t.intersection([
t.type({
id: t.string,
type: t.literal(SlicesTypes.SharedSlice),
name: t.string,
variations: t.array(Variation)
}),
t.partial({
description: t.string
})
])
t.intersection([
t.type({
id: t.string,
type: t.literal(SlicesTypes.SharedSlice),
name: t.string,
variations: t.array(Variation),
}),
t.partial({
description: t.string,
}),
]),
)

@@ -42,0 +44,0 @@

@@ -1,12 +0,12 @@

import * as t from 'io-ts'
import * as t from "io-ts"
import SlicesTypes from './SlicesTypes'
import SlicesTypes from "./SlicesTypes"
const SharedSliceRef = t.exact(
t.type({
type: t.literal(SlicesTypes.SharedSlice)
})
t.type({
type: t.literal(SlicesTypes.SharedSlice),
}),
)
type SharedSliceRef = t.TypeOf<typeof SharedSliceRef>
export default SharedSliceRef
export default SharedSliceRef

@@ -1,7 +0,7 @@

import SharedSlice from "./SharedSlice";
import CompositeSlice from "./CompositeSlice";
import LegacySlice from "./LegacySlice";
import SharedSliceRef from "./SharedSliceRef";
import type CompositeSlice from "./CompositeSlice"
import type LegacySlice from "./LegacySlice"
import type SharedSlice from "./SharedSlice"
import type SharedSliceRef from "./SharedSliceRef"
export type DynamicSlice = CompositeSlice | LegacySlice | SharedSliceRef
export type StaticSlice = CompositeSlice | LegacySlice | SharedSlice

@@ -1,28 +0,29 @@

import * as t from 'io-ts'
import { StringOrNull } from '../../../validators/StringOrNull'
import WidgetTypes from '../WidgetTypes'
import { Format } from '../../Format'
import LegacySlice from './LegacySlice'
import CompositeSlice from './CompositeSlice'
import SharedSliceRef from './SharedSliceRef'
import SharedSlice from './SharedSlice'
import SlicesTypes from './SlicesTypes'
import * as t from "io-ts"
import { StringOrNull } from "../../../validators"
import { Format } from "../../Format"
import WidgetTypes from "../WidgetTypes"
import CompositeSlice from "./CompositeSlice"
import LegacySlice from "./LegacySlice"
import SharedSlice from "./SharedSlice"
import SharedSliceRef from "./SharedSliceRef"
import SlicesTypes from "./SlicesTypes"
const SlicesLabels = t.union([
t.record(
t.string,
t.array(
t.exact(
t.intersection([
t.type({
name: t.string
}),
t.partial({
display: t.string
})
])
)
)
),
t.null
t.record(
t.string,
t.array(
t.exact(
t.intersection([
t.type({
name: t.string,
}),
t.partial({
display: t.string,
}),
]),
),
),
),
t.null,
])

@@ -32,19 +33,27 @@ type SlicesLabels = t.TypeOf<typeof SlicesLabels>

export function slicesConfigReader<F extends Format>(format: F) {
return t.exact(
t.partial({
label: StringOrNull,
labels: SlicesLabels,
choices: t.record(t.string, t.union([
LegacySlice,
CompositeSlice,
(() => {
switch(format) {
case Format.Static: return SharedSlice
case Format.Dynamic: return SharedSliceRef
default: throw new Error(`Invalid Format Exception: ${format} doesn't exist`)
}
})()
]))
})
)
return t.exact(
t.partial({
label: StringOrNull,
labels: SlicesLabels,
choices: t.record(
t.string,
t.union([
LegacySlice,
CompositeSlice,
(() => {
switch (format) {
case Format.Static:
return SharedSlice
case Format.Dynamic:
return SharedSliceRef
default:
throw new Error(
`Invalid Format Exception: ${format} doesn't exist`,
)
}
})(),
]),
),
}),
)
}

@@ -58,30 +67,37 @@ export const StaticSlicesConfig = slicesConfigReader(Format.Static)

const SlicesConfig = {
toStatic(config: DynamicSlicesConfig, sharedSlices: Map<string, SharedSlice>): StaticSlicesConfig {
const choices: {[key: string]: LegacySlice | CompositeSlice | SharedSlice } = Object.entries(config.choices || {})
.reduce((acc, [ref, slice]) => {
if(slice.type === SlicesTypes.SharedSlice) {
const sharedSlice = sharedSlices.get(ref)
if(sharedSlice) return { ...acc, [ref]: sharedSlice }
else return acc
} else {
return { ...acc, [ref]: slice }
}
}, {})
return { ...config, choices } as StaticSlicesConfig
}
toStatic(
config: DynamicSlicesConfig,
sharedSlices: Map<string, SharedSlice>,
): StaticSlicesConfig {
const choices: {
[key: string]: LegacySlice | CompositeSlice | SharedSlice
} = Object.entries(config.choices || {}).reduce((acc, [ref, slice]) => {
if (slice.type === SlicesTypes.SharedSlice) {
const sharedSlice = sharedSlices.get(ref)
if (sharedSlice) return { ...acc, [ref]: sharedSlice }
else return acc
} else {
return { ...acc, [ref]: slice }
}
}, {})
return { ...config, choices } as StaticSlicesConfig
},
}
export function slicesReader<F extends Format>(format: F) {
return t.exact(
t.intersection([
t.type({
type: t.union([t.literal(WidgetTypes.Slices), t.literal(WidgetTypes.LegacySlices)])
}),
t.partial({
fieldset: StringOrNull,
config: slicesConfigReader(format)
})
])
)
return t.exact(
t.intersection([
t.type({
type: t.union([
t.literal(WidgetTypes.Slices),
t.literal(WidgetTypes.LegacySlices),
]),
}),
t.partial({
fieldset: StringOrNull,
config: slicesConfigReader(format),
}),
]),
)
}

@@ -96,8 +112,14 @@

export const Slices = {
toStatic(slices: DynamicSlices, sharedSlices: Map<string, SharedSlice>): StaticSlices {
if(!slices.config) return slices as StaticSlices
else {
return { ...slices, config: SlicesConfig.toStatic(slices.config, sharedSlices) }
}
}
toStatic(
slices: DynamicSlices,
sharedSlices: Map<string, SharedSlice>,
): StaticSlices {
if (!slices.config) return slices as StaticSlices
else {
return {
...slices,
config: SlicesConfig.toStatic(slices.config, sharedSlices),
}
}
},
}
enum SlicesTypes {
Slice = 'Slice',
SharedSlice = 'SharedSlice'
Slice = "Slice",
SharedSlice = "SharedSlice",
}
export default SlicesTypes
export default SlicesTypes

@@ -1,11 +0,12 @@

import * as t from 'io-ts'
import { StringOrNull } from '../../validators/StringOrNull'
import WidgetTypes from './WidgetTypes'
import * as t from "io-ts"
import { StringOrNull } from "../../validators"
import WidgetTypes from "./WidgetTypes"
const UIDConfig = t.exact(
t.partial({
label: StringOrNull,
useAsTitle: t.boolean,
placeholder: t.string
})
t.partial({
label: StringOrNull,
useAsTitle: t.boolean,
placeholder: t.string,
}),
)

@@ -15,11 +16,11 @@ type UIDConfig = t.TypeOf<typeof UIDConfig>

const UID = t.exact(
t.intersection([
t.type({
type: t.literal(WidgetTypes.UID)
}),
t.partial({
fieldset: StringOrNull,
config: UIDConfig
})
])
t.intersection([
t.type({
type: t.literal(WidgetTypes.UID),
}),
t.partial({
fieldset: StringOrNull,
config: UIDConfig,
}),
]),
)

@@ -26,0 +27,0 @@ type UID = t.TypeOf<typeof UID>

@@ -1,18 +0,13 @@

import * as t from 'io-ts'
import * as t from "io-ts"
import UID from './UID'
import NestableWidget from './nestable/NestableWidget'
import { slicesReader, Slices } from './slices/Slices'
import SharedSlice from './slices/SharedSlice'
import { Format } from '../Format'
import Group from './Group'
import WidgetTypes from './WidgetTypes'
import { Format } from "../Format"
import Group from "./Group"
import NestableWidget from "./nestable/NestableWidget"
import type SharedSlice from "./slices/SharedSlice"
import { Slices, slicesReader } from "./slices/Slices"
import UID from "./UID"
import WidgetTypes from "./WidgetTypes"
export function widgetReader<F extends Format>(format: F){
return t.union([
UID,
NestableWidget,
Group,
slicesReader(format)
])
export function widgetReader<F extends Format>(format: F) {
return t.union([UID, NestableWidget, Group, slicesReader(format)])
}

@@ -25,10 +20,14 @@ export const StaticWidget = widgetReader(Format.Static)

export const Widgets = {
toStatic(widget: DynamicWidget, sharedSlices: Map<string, SharedSlice>): StaticWidget {
switch(widget.type) {
case WidgetTypes.Slices: return Slices.toStatic(widget, sharedSlices)
default: return widget as StaticWidget
}
}
}
toStatic(
widget: DynamicWidget,
sharedSlices: Map<string, SharedSlice>,
): StaticWidget {
switch (widget.type) {
case WidgetTypes.Slices:
return Slices.toStatic(widget, sharedSlices)
default:
return widget as StaticWidget
}
},
}
enum WidgetTypes {
Text = 'Text',
RichText = 'StructuredText',
Color = 'Color',
Image = 'Image',
Date = 'Date',
Timestamp = 'Timestamp',
Number = 'Number',
Range = 'Range',
Select = 'Select',
Link = 'Link',
Embed = 'Embed',
GeoPoint = 'GeoPoint',
Separator = 'Separator',
UID = 'UID',
BooleanField = 'Boolean',
IntegrationField = 'IntegrationFields',
Group = 'Group',
Slices = 'Slices',
// Legacy type for slices
LegacySlices = 'Choice'
Text = "Text",
RichText = "StructuredText",
Color = "Color",
Image = "Image",
Date = "Date",
Timestamp = "Timestamp",
Number = "Number",
Range = "Range",
Select = "Select",
Link = "Link",
Embed = "Embed",
GeoPoint = "GeoPoint",
Separator = "Separator",
UID = "UID",
BooleanField = "Boolean",
IntegrationField = "IntegrationFields",
Group = "Group",
Slices = "Slices",
// Legacy type for slices
LegacySlices = "Choice",
}
export default WidgetTypes
export default WidgetTypes

@@ -1,1 +0,3 @@

export * as CustomTypes from './customtypes'
export * as CustomTypes from "./customtypes"
export * as Documents from "./documents"
export * as Validators from "./validators"

@@ -1,24 +0,22 @@

import * as t from 'io-ts'
import { pipe } from 'fp-ts/lib/pipeable'
import { chain } from 'fp-ts/lib/Either'
export interface IntFromNumberC extends t.Type<t.Int, number, unknown> {}
/**
* A codec that succeeds if a number can be parsed to an integer
*/
export const IntFromNumber: IntFromNumberC = new t.Type<t.Int, number, unknown>(
'IntFromNumber',
t.Int.is,
(u, c) =>
pipe(
t.number.validate(u, c),
chain(n => {
if(t.Int.is(n)) return t.success(n)
else {
return t.success(Math.round(n) as t.Int)
}
})
),
t.Int.encode
)
import { chain } from "fp-ts/Either"
import { pipe } from "fp-ts/function"
import * as t from "io-ts"
export type IntFromNumberC = t.Type<t.Int, number, unknown>
/** A codec that succeeds if a number can be parsed to an integer */
export default new t.Type<t.Int, number, unknown>(
"IntFromNumber",
t.Int.is,
(u, c) =>
pipe(
t.number.validate(u, c),
chain((n) => {
if (t.Int.is(n)) return t.success(n)
else {
return t.success(Math.round(n) as t.Int)
}
}),
),
t.Int.encode,
)

@@ -1,31 +0,32 @@

import * as t from 'io-ts'
import { pipe } from 'fp-ts/lib/pipeable'
import { chain } from 'fp-ts/lib/Either'
import { chain } from "fp-ts/Either"
import { pipe } from "fp-ts/function"
import * as t from "io-ts"
export interface IntFromPixelsC extends t.Type<t.Int, string, unknown> {}
export type IntFromPixelsC = t.Type<t.Int, string, unknown>
const PixelsRegex = /^([0-9]+)px$/
/**
* A codec that succeeds if a string representing pixels (eg: "200px") can be parsed to an integer
* A codec that succeeds if a string representing pixels (eg: "200px") can be
* parsed to an integer
*/
export const IntFromPixels: IntFromPixelsC = new t.Type<t.Int, string, unknown>(
'IntFromPixels',
t.Int.is,
(u, c) =>
pipe(
t.string.validate(u, c),
chain(strPixels => {
try {
const matched = strPixels.match(PixelsRegex)
if(!matched) return t.failure(u, c)
else {
const parsed = parseInt(matched[1]) as t.Int
return t.success(parsed)
}
} catch {
return t.failure(u, c)
}
})
),
String
)
export default new t.Type<t.Int, string, unknown>(
"IntFromPixels",
t.Int.is,
(u, c) =>
pipe(
t.string.validate(u, c),
chain((strPixels) => {
try {
const matched = strPixels.match(PixelsRegex)
if (!matched) return t.failure(u, c)
/* eslint-disable @typescript-eslint/no-non-null-assertion */
const parsed = parseInt(matched[1]!) as t.Int
return t.success(parsed)
} catch {
return t.failure(u, c)
}
}),
),
String,
)

@@ -1,21 +0,19 @@

import * as t from 'io-ts'
import { pipe } from 'fp-ts/lib/pipeable'
import { chain } from 'fp-ts/lib/Either'
import { chain } from "fp-ts/Either"
import { pipe } from "fp-ts/function"
import * as t from "io-ts"
export interface StringFromBooleanC extends t.Type<string, string, unknown> {}
export type StringFromBooleanC = t.Type<string, string, unknown>
/**
* A codec that validates a Boolean and convert it as a string
*/
export const StringFromBoolean: StringFromBooleanC = new t.Type<string, string, unknown>(
'StringFromInt',
t.string.is,
(u, c) =>
pipe(
t.boolean.validate(u, c),
chain(i => {
return t.success(i.toString())
})
),
i => i
)
/** A codec that validates a Boolean and convert it as a string */
export default new t.Type<string, string, unknown>(
"StringFromInt",
t.string.is,
(u, c) =>
pipe(
t.boolean.validate(u, c),
chain((i) => {
return t.success(i.toString())
}),
),
(i) => i,
)

@@ -1,21 +0,19 @@

import * as t from 'io-ts'
import { pipe } from 'fp-ts/lib/pipeable'
import { chain } from 'fp-ts/lib/Either'
import { chain } from "fp-ts/Either"
import { pipe } from "fp-ts/function"
import * as t from "io-ts"
export interface StringFromNumberC extends t.Type<string, string, unknown> {}
export type StringFromNumberC = t.Type<string, string, unknown>
/**
* A codec that validates a number and convert it as a string
*/
export const StringFromNumber: StringFromNumberC = new t.Type<string, string, unknown>(
'StringFromInt',
t.string.is,
(u, c) =>
pipe(
t.number.validate(u, c),
chain(i => {
return t.success(i.toString())
})
),
i => i
)
/** A codec that validates a number and convert it as a string */
export default new t.Type<string, string, unknown>(
"StringFromInt",
t.string.is,
(u, c) =>
pipe(
t.number.validate(u, c),
chain((i) => {
return t.success(i.toString())
}),
),
(i) => i,
)

@@ -1,3 +0,5 @@

import * as t from 'io-ts'
import * as t from "io-ts"
export const StringOrNull = t.union([ t.string, t.null, t.undefined ])
import { nullable } from "./function"
export default nullable(t.string)
SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc