Skip to content

Commit

Permalink
[types] Improve schema type typings with additional options
Browse files Browse the repository at this point in the history
  • Loading branch information
rexxars committed Oct 6, 2020
1 parent bf634e7 commit a863a07
Show file tree
Hide file tree
Showing 11 changed files with 118 additions and 30 deletions.
1 change: 1 addition & 0 deletions packages/@sanity/types/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
"description": "Type definitions for common Sanity data structures",
"main": "lib/index.js",
"types": "lib/index.d.ts",
"sideEffects": false,
"author": "Sanity.io <hello@sanity.io>",
"license": "MIT",
"scripts": {
Expand Down
10 changes: 9 additions & 1 deletion packages/@sanity/types/src/assets/types.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import {Reference, SanityDocument} from '../documents'
import {Reference} from '../reference'
import {SanityDocument} from '../documents'

export interface File {
[key: string]: unknown // We allow meta-fields on file
Expand Down Expand Up @@ -103,3 +104,10 @@ export interface AssetSourceSpec {
name: string
url?: string
}

export interface AssetSource {
name: string
title: string
component: React.ComponentType
icon?: React.ComponentType
}
11 changes: 2 additions & 9 deletions packages/@sanity/types/src/documents/asserters.ts
Original file line number Diff line number Diff line change
@@ -1,19 +1,12 @@
import {KeyedObject, Reference, SanityDocument, TypedObject} from './types'

function isObject(obj: unknown): obj is Record<string, unknown> {
return typeof obj === 'object' && obj !== null && !Array.isArray(obj)
}
import {isObject} from '../helpers'
import {KeyedObject, SanityDocument, TypedObject} from './types'

export function isSanityDocument(document: unknown): document is SanityDocument {
return (
isObject(document) && typeof document._id === 'string' && typeof document._type === 'string'
)
}

export function isReference(reference: unknown): reference is Reference {
return isObject(reference) && typeof reference._ref === 'string'
}

export function isTypedObject(obj: unknown): obj is TypedObject {
return isObject(obj) && typeof obj._type === 'string'
}
Expand Down
10 changes: 0 additions & 10 deletions packages/@sanity/types/src/documents/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,16 +7,6 @@ export interface SanityDocument {
_rev: string
}

export interface Reference {
_ref: string
_key?: string
_weak?: boolean
}

export interface WeakReference extends Reference {
_weak: true
}

export interface TypedObject {
[key: string]: unknown
_type: string
Expand Down
3 changes: 3 additions & 0 deletions packages/@sanity/types/src/helpers.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export function isObject(obj: unknown): obj is Record<string, unknown> {
return typeof obj === 'object' && obj !== null && !Array.isArray(obj)
}
1 change: 1 addition & 0 deletions packages/@sanity/types/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,4 @@ export * from './portableText'
export * from './assets'
export * from './markers'
export * from './validation'
export * from './reference'
6 changes: 6 additions & 0 deletions packages/@sanity/types/src/reference/asserters.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import {isObject} from '../helpers'
import {Reference} from './types'

export function isReference(reference: unknown): reference is Reference {
return isObject(reference) && typeof reference._ref === 'string'
}
2 changes: 2 additions & 0 deletions packages/@sanity/types/src/reference/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export * from './asserters'
export * from './types'
27 changes: 27 additions & 0 deletions packages/@sanity/types/src/reference/types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import {Path} from '../paths'
import {SanityDocument} from '../documents'

export interface Reference {
_ref: string
_key?: string
_weak?: boolean
}

export interface WeakReference extends Reference {
_weak: true
}

export type ReferenceFilterSearchOptions = {
filter?: string
params?: Record<string, unknown>
}

export type ReferenceFilterResolver = (options: {
document: SanityDocument
parent?: Record<string, unknown> | Record<string, unknown>[]
parentPath: Path
}) => ReferenceFilterSearchOptions

export type ReferenceOptions =
| {filter: ReferenceFilterResolver}
| {filter: string; filterParams?: Record<string, unknown>}
18 changes: 17 additions & 1 deletion packages/@sanity/types/src/schema/asserters.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,21 @@
import {ObjectSchemaType, SchemaType} from './types'
import {ObjectSchemaType, ReferenceSchemaType, SchemaType, TitledListValue} from './types'

export function isObjectSchemaType(type: SchemaType): type is ObjectSchemaType {
return type.jsonType === 'object'
}

export function isReferenceSchemaType(
type: SchemaType | ReferenceSchemaType
): type is ReferenceSchemaType {
return type.jsonType === 'object' && 'to' in type && Array.isArray(type.to)
}

export function isTitledListValue(item: unknown): item is TitledListValue {
return (
typeof item === 'object' &&
item !== null &&
'title' in item &&
'value' in item &&
Object.keys(item).length === 2
)
}
59 changes: 50 additions & 9 deletions packages/@sanity/types/src/schema/types.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
// Note: INCOMPLETE, but it's a start

import {ReferenceOptions} from '../reference'
import {AssetSource} from '../assets'
import {SlugOptions} from '../slug'

export interface Schema {
Expand All @@ -14,23 +15,43 @@ export interface BaseSchemaType {
title?: string
description?: string
type?: SchemaType
readOnly?: boolean
icon?: React.ComponentType

/**
* @deprecated
*/
placeholder?: string
}

export interface TitledListValue<V = unknown> {
_key?: string
title: string
value: V
}

interface EnumListProps<V = unknown> {
list?: TitledListValue<V>[] | V[]
layout?: 'radio' | 'dropdown'
direction?: 'horizontal' | 'vertical'
}

export interface StringSchemaType extends BaseSchemaType {
jsonType: 'string'
options?: {
list?: {title?: string; value: string}[]
layout?: 'radio' | 'dropdown'
direction?: 'horizontal' | 'vertical'

options?: EnumListProps<string> & {
// Actually just part of date time, but can't find a good way to differentiate
dateFormat?: string
timeFormat?: string
}
}

export interface TextSchemaType extends StringSchemaType {
rows?: number
}

export interface NumberSchemaType extends BaseSchemaType {
jsonType: 'number'
options?: EnumListProps<number>
}

export interface BooleanSchemaType extends BaseSchemaType {
Expand All @@ -42,16 +63,17 @@ export interface BooleanSchemaType extends BaseSchemaType {

export interface ArraySchemaType<V = unknown> extends BaseSchemaType {
jsonType: 'array'
of: Exclude<SchemaType, ArraySchemaType>[]
of: (Exclude<SchemaType, ArraySchemaType> | ReferenceSchemaType)[]
options?: {
list?: {title?: string; value: V}[] | V[]
list?: TitledListValue<V>[] | V[]
layout?: V extends string ? 'tags' : 'grid'
direction?: 'horizontal' | 'vertical'
sortable?: boolean

/**
* @deprecated
*/
editModal?: 'dialog' | 'fullscreen' | 'popover'
editModal?: 'dialog' | 'fullscreen' | 'popover' | 'fold'
}
}

Expand Down Expand Up @@ -100,6 +122,25 @@ export type Fieldset = SingleFieldSet | MultiFieldSet

export interface ReferenceSchemaType extends ObjectSchemaType {
to: SchemaType[]
weak?: boolean
options?: ReferenceOptions
}

export interface AssetSchemaTypeOptions {
accept?: string
storeOriginalFilename?: boolean
}

export interface FileSchemaType extends ObjectSchemaType {
options?: AssetSchemaTypeOptions
}

export interface ImageSchemaType extends ObjectSchemaType {
options?: AssetSchemaTypeOptions & {
hotspot?: boolean
metadata?: ('exif' | 'location' | 'lqip' | 'palette')[]
sources?: AssetSource[]
}
}

export type SchemaType =
Expand Down

0 comments on commit a863a07

Please sign in to comment.