Skip to content

Commit

Permalink
Fix types
Browse files Browse the repository at this point in the history
  • Loading branch information
stefanoverna committed Jun 6, 2024
1 parent 0a5daee commit 26485ea
Show file tree
Hide file tree
Showing 7 changed files with 88 additions and 38 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/node.js.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ jobs:

strategy:
matrix:
node-version: [10.x, 12.x, 14.x, 15.x]
node-version: [16.x, 18.x, 20.x]
# See supported Node.js release schedule at https://nodejs.org/en/about/releases/

steps:
Expand Down
2 changes: 2 additions & 0 deletions packages/to-dom-nodes/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import {
RenderResult,
RenderRule,
StructuredText as StructuredTextGraphQlResponse,
TypesafeStructured as TypesafeStructuredTextGraphQlResponse,
} from 'datocms-structured-text-utils';
import hyperscript from 'hyperscript';

Expand All @@ -30,6 +31,7 @@ export { renderNodeRule as renderRule };

export type {
StructuredTextDocument,
TypesafeStructuredTextGraphQlResponse,
StructuredTextGraphQlResponse,
StructuredTextGraphQlResponseRecord,
};
Expand Down
2 changes: 2 additions & 0 deletions packages/to-html-string/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import {
RenderResult,
RenderRule,
StructuredText as StructuredTextGraphQlResponse,
TypesafeStructuredText as TypesafeStructuredTextGraphQlResponse,
} from 'datocms-structured-text-utils';
import vhtml from 'vhtml';

Expand All @@ -30,6 +31,7 @@ export { renderNodeRule as renderRule };

export type {
StructuredTextDocument,
TypesafeStructuredTextGraphQlResponse,
StructuredTextGraphQlResponse,
StructuredTextGraphQlResponseRecord,
};
Expand Down
2 changes: 2 additions & 0 deletions packages/to-plain-text/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,13 +20,15 @@ import {
RenderResult,
RenderRule,
StructuredText as StructuredTextGraphQlResponse,
TypesafeStructuredText as TypesafeStructuredTextGraphQlResponse,
} from 'datocms-structured-text-utils';

export { renderNodeRule, renderMarkRule, RenderError };
// deprecated export
export { renderNodeRule as renderRule };
export type {
StructuredTextDocument,
TypesafeStructuredTextGraphQlResponse,
StructuredTextGraphQlResponse,
StructuredTextGraphQlResponseRecord,
};
Expand Down
59 changes: 38 additions & 21 deletions packages/utils/src/guards.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,14 @@ import {
WithChildrenNode,
InlineNode,
NodeType,
Record,
Record as DatoCmsRecord,
StructuredText,
ThematicBreak,
Document,
} from './types';

import {
allowedNodeTypes,
headingNodeType,
spanNodeType,
rootNodeType,
Expand Down Expand Up @@ -98,33 +99,50 @@ export function isThematicBreak(node: Node): node is ThematicBreak {
return node.type === thematicBreakNodeType;
}

export function isStructuredText<R1 extends Record, R2 extends Record = R1>(
// eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/explicit-module-boundary-types
obj: any,
): obj is StructuredText<R1, R2> {
return obj && 'value' in obj && isDocument(obj.value);
function isObject(obj: unknown): obj is Record<string, unknown> {
return Boolean(typeof obj === 'object' && obj);
}

export function isDocument(
// eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/explicit-module-boundary-types
obj: any,
): obj is Document {
return obj && 'schema' in obj && 'document' in obj;
export function isNodeType(value: string): value is NodeType {
return allowedNodeTypes.includes(value as NodeType);
}

export function isEmptyDocument(
// eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/explicit-module-boundary-types
obj: any,
): boolean {
export function isNode(obj: unknown): obj is Node {
return Boolean(
isObject(obj) &&
'type' in obj &&
typeof obj.type === 'string' &&
isNodeType(obj.type),
);
}

export function isStructuredText<
R1 extends DatoCmsRecord,
R2 extends DatoCmsRecord = R1
>(obj: unknown): obj is StructuredText<R1, R2> {
return Boolean(isObject(obj) && 'value' in obj && isDocument(obj.value));
}

export function isDocument(obj: unknown): obj is Document {
return Boolean(
isObject(obj) &&
'schema' in obj &&
'document' in obj &&
obj.schema === 'dast',
);
}

export function isEmptyDocument(obj: unknown): boolean {
if (!obj) {
return true;
}

const document = isStructuredText(obj)
? obj.value
: isDocument(obj)
? obj
: null;
const document =
isStructuredText(obj) && isDocument(obj.value)
? obj.value
: isDocument(obj)
? obj
: null;

if (!document) {
throw new Error(
Expand All @@ -133,7 +151,6 @@ export function isEmptyDocument(
}

return (
document.schema === 'dast' &&
document.document.children.length === 1 &&
document.document.children[0].type === 'paragraph' &&
document.document.children[0].children.length === 1 &&
Expand Down
32 changes: 18 additions & 14 deletions packages/utils/src/render.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { Node, Record, Document, StructuredText } from './types';
import { hasChildren, isDocument, isStructuredText } from './guards';
import { hasChildren, isDocument, isNode, isStructuredText } from './guards';
import { flatten } from 'array-flatten';

export class RenderError extends Error {
Expand Down Expand Up @@ -90,12 +90,11 @@ export function transformNode<

if (matchingTransform) {
return matchingTransform.apply({ adapter, node, children, key, ancestors });
} else {
throw new RenderError(
`Don't know how to render a node with type "${node.type}". Please specify a custom renderRule for it!`,
node,
);
}
throw new RenderError(
`Don't know how to render a node with type "${node.type}". Please specify a custom renderRule for it!`,
node,
);
}

export type Adapter<
Expand Down Expand Up @@ -128,18 +127,23 @@ export function render<
return null;
}

const result = transformNode(
adapter,
isStructuredText<R1, R2>(structuredTextOrNode)
const node =
isStructuredText<R1, R2>(structuredTextOrNode) &&
isDocument(structuredTextOrNode.value)
? structuredTextOrNode.value.document
: isDocument(structuredTextOrNode)
? structuredTextOrNode.document
: structuredTextOrNode,
: isNode(structuredTextOrNode)
? structuredTextOrNode
: undefined;

't-0',
[],
renderRules,
);
if (!node) {
throw new Error(
'Passed object is neither null, a Structured Text value, a DAST document or a DAST node',
);
}

const result = transformNode(adapter, node, 't-0', [], renderRules);

return result;
}
27 changes: 25 additions & 2 deletions packages/utils/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -440,8 +440,31 @@ export type NodeType =
* and embedded within the flow of the text.
*/

export type StructuredText<R1 extends Record = Record, R2 extends Record = R1> = {
/** A DatoCMS compatible document */
export type StructuredText<
R1 extends Record = Record,
R2 extends Record = R1
> = {
/**
* A DatoCMS "dast" document
*
* https://www.datocms.com/docs/structured-text/dast
*/
value: Document | unknown;
/** Blocks associated with the Structured Text */
blocks?: R1[];
/** Links associated with the Structured Text */
links?: R2[];
};

export type TypesafeStructuredText<
R1 extends Record = Record,
R2 extends Record = R1
> = {
/**
* A DatoCMS "dast" document
*
* https://www.datocms.com/docs/structured-text/dast
*/
value: Document;
/** Blocks associated with the Structured Text */
blocks?: R1[];
Expand Down

0 comments on commit 26485ea

Please sign in to comment.