Skip to content
Draft
Show file tree
Hide file tree
Changes from 1 commit
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
Next Next commit
WIP stackbit extension
  • Loading branch information
schickling committed May 17, 2022
commit 2b8c39aeaa955d954ffe035b0f4bb947dbf300d8
2 changes: 1 addition & 1 deletion packages/@contentlayer/cli/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@contentlayer/cli",
"version": "0.2.5",
"version": "0.2.6-dev.7",
"type": "module",
"exports": "./dist/index.js",
"types": "./dist/index.d.ts",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ const generateTypes = ({
}

const { source, esbuildHash } = sourceEither.right
const schemaDef = yield* $(source.provideSchema(esbuildHash))
const schemaDef = yield* $(source.provideSchema({ esbuildHash }))

if (!indexDtsFileExists) {
yield* $(fs.writeFile(indexDtsFilePath, core.makeDataTypes({ schemaDef })))
Expand Down
2 changes: 1 addition & 1 deletion packages/@contentlayer/client/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@contentlayer/client",
"version": "0.2.5",
"version": "0.2.6-dev.7",
"type": "module",
"exports": "./dist/index.js",
"types": "./dist/index.d.ts",
Expand Down
2 changes: 1 addition & 1 deletion packages/@contentlayer/core/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@contentlayer/core",
"version": "0.2.5",
"version": "0.2.6-dev.7",
"type": "module",
"exports": "./dist/index.js",
"types": "./dist/index.d.ts",
Expand Down
16 changes: 16 additions & 0 deletions packages/@contentlayer/core/src/extensions.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
declare global {
// TODO docs
interface ContentlayerExtensions {
// [extensionName: string]: {
// root: never
// documentType: never
// nestedType: never
// field: never
// }
}
}

export type ExtensionsRoot = { [K in keyof ContentlayerExtensions]: ContentlayerExtensions[K]['root'] }
export type ExtensionsDocumentType = { [K in keyof ContentlayerExtensions]: ContentlayerExtensions[K]['documentType'] }
export type ExtensionsNestedType = { [K in keyof ContentlayerExtensions]: ContentlayerExtensions[K]['nestedType'] }
export type ExtensionsField = { [K in keyof ContentlayerExtensions]: ContentlayerExtensions[K]['field'] }
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ export const generateDotpkgStream = ({
const generationOptions = { sourcePluginType: config.source.type, options: config.source.options }
const resolveParams = pipe(
T.structPar({
schemaDef: config.source.provideSchema(config.esbuildHash),
schemaDef: config.source.provideSchema({ esbuildHash: config.esbuildHash }),
targetPath: ArtifactsDir.mkdir,
}),
T.either,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@ export const renderDocumentTypeDefOrNestedTypeDef = ({
const computedFields = (def._tag === 'DocumentTypeDef' ? def.computedFields : [])
.map((field) => `${field.description ? ` /** ${field.description} */\n` : ''} ${field.name}: ${field.type}`)
.join('\n')
const description = def.description ?? def.extensions.stackbit?.fields?.[def.name]?.label
const description = def.description

const rawType = renderRawType({ sourcePluginType })
const idJsdoc = renderIdJsdoc({ sourcePluginType })
Expand Down
1 change: 1 addition & 0 deletions packages/@contentlayer/core/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ export * from './generation/generate-types.js'
export * from './DataCache.js'
export * from './data-types.js'
export * from './cwd.js'
export * from './extensions.js'
export * from './gen.js'
export * from './errors.js'
export * from './getConfig/index.js'
Expand Down
25 changes: 10 additions & 15 deletions packages/@contentlayer/core/src/plugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,11 @@ import type * as unified from 'unified'
import type { HasCwd } from './cwd.js'
import type { DataCache } from './DataCache.js'
import type { SourceFetchDataError, SourceProvideSchemaError } from './errors.js'
import type { SchemaDef, StackbitExtension } from './schema/index.js'
import type { ExtensionsRoot } from './extensions.js'
import type { SchemaDef } from './schema/index.js'

export type SourcePluginType = LiteralUnion<'local' | 'contentful' | 'sanity', string>

export type PluginExtensions = {
// TODO decentralized extension definitions + logic
stackbit?: StackbitExtension.Config
}

export type PluginOptions = {
markdown: MarkdownOptions | MarkdownUnifiedBuilderCallback | undefined
mdx: MDXOptions | undefined
Expand Down Expand Up @@ -99,12 +95,13 @@ export type SourcePlugin = {
fetchData: FetchData
} & {
options: PluginOptions
extensions: PluginExtensions
extensions: Partial<ExtensionsRoot>
}

export type ProvideSchema = (
esbuildHash: string,
) => T.Effect<OT.HasTracer & HasConsole, SourceProvideSchemaError, SchemaDef>
export type ProvideSchema = (_: {
esbuildHash: string
extensionProperties?: string[]
}) => T.Effect<OT.HasTracer & HasConsole, SourceProvideSchemaError, SchemaDef>
export type FetchData = (_: {
schemaDef: SchemaDef
verbose: boolean
Expand All @@ -127,7 +124,6 @@ export type PartialArgs = {
mdx?: MarkdownOptions | undefined
date?: DateOptions | undefined
fieldOptions?: Partial<FieldOptions>
extensions?: PluginExtensions
disableImportAliasWarning?: boolean
}

Expand All @@ -139,11 +135,10 @@ export const defaultFieldOptions: FieldOptions = {
export const processArgs = async <TArgs extends PartialArgs>(
argsOrArgsThunk: TArgs | Thunk<TArgs> | Thunk<Promise<TArgs>>,
): Promise<{
extensions: PluginExtensions
options: PluginOptions
restArgs: Omit<TArgs, 'extensions' | 'fieldOptions' | 'markdown' | 'mdx' | 'date' | 'disableImportAliasWarning'>
restArgs: Omit<TArgs, 'fieldOptions' | 'markdown' | 'mdx' | 'date' | 'disableImportAliasWarning'>
}> => {
const { extensions, fieldOptions, markdown, mdx, date, disableImportAliasWarning, ...restArgs } =
const { fieldOptions, markdown, mdx, date, disableImportAliasWarning, ...restArgs } =
typeof argsOrArgsThunk === 'function' ? await argsOrArgsThunk() : argsOrArgsThunk

const options: PluginOptions = {
Expand All @@ -157,5 +152,5 @@ export const processArgs = async <TArgs extends PartialArgs>(
disableImportAliasWarning: disableImportAliasWarning ?? false,
}

return { extensions: extensions ?? {}, options, restArgs }
return { options, restArgs }
}
2 changes: 2 additions & 0 deletions packages/@contentlayer/core/src/schema/field.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import type { ExtensionsField } from '../extensions.js'
import type { NestedUnnamedTypeDef } from './index.js'

export type FieldDefType = FieldDef['type']
Expand Down Expand Up @@ -36,6 +37,7 @@ export interface FieldDefBase {
isRequired: boolean

isSystemField: boolean
extensions: Partial<ExtensionsField>
}

export interface ListFieldDef extends FieldDefBase {
Expand Down
13 changes: 4 additions & 9 deletions packages/@contentlayer/core/src/schema/index.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,8 @@
import type { Document } from '../data-types.js'
import type { ExtensionsDocumentType, ExtensionsNestedType } from '../extensions.js'
import type { FieldDef, FieldDefType } from './field.js'
import type { StackbitExtension } from './stackbit-extension.js'
export * from './field.js'
export * from './validate.js'
export * from './stackbit-extension.js'

export type TypeDefExtensions = {
stackbit?: StackbitExtension.TypeExtension
}

export type DocumentTypeDefMap = Record<string, DocumentTypeDef>
export type NestedTypeDefMap = Record<string, NestedTypeDef>
Expand All @@ -27,21 +22,21 @@ export type DocumentTypeDef = {
isSingleton: boolean
fieldDefs: FieldDef[]
computedFields: ComputedField[]
extensions: TypeDefExtensions
extensions: Partial<ExtensionsDocumentType>
}

export type NestedTypeDef = {
readonly _tag: 'NestedTypeDef'
name: string
description: string | undefined
fieldDefs: FieldDef[]
extensions: TypeDefExtensions
extensions: Partial<ExtensionsNestedType>
}

export type NestedUnnamedTypeDef = {
readonly _tag: 'NestedUnnamedTypeDef'
fieldDefs: FieldDef[]
extensions: TypeDefExtensions
extensions: Partial<ExtensionsNestedType>
}

export type ComputedField = {
Expand Down
20 changes: 10 additions & 10 deletions packages/@contentlayer/core/src/schema/validate.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,15 @@ export const validateSchema = (schema: SchemaDef): void => {
Object.values(schema.nestedTypeDefMap).forEach((def) => validateDocumentOrObjectDef({ def }))
}

const validateDocumentOrObjectDef = ({ def }: { def: DocumentTypeDef | NestedTypeDef }): void => {
const validateDocumentOrObjectDef = ({}: { def: DocumentTypeDef | NestedTypeDef }): void => {
// TODO move out this code to a new stackbit extension package
const stackbitExt = def.extensions.stackbit
if (stackbitExt?.labelField) {
const noFieldFoundForLabelField = !def.fieldDefs.some((_) => _.name === stackbitExt.labelField)
if (noFieldFoundForLabelField) {
throw new Error(
`There is no field with the name "${stackbitExt.labelField}" as specified for "labelField" in ${def._tag} with the name "${def.name}"`,
)
}
}
// const stackbitExt = def.extensions.stackbit
// if (stackbitExt?.labelField) {
// const noFieldFoundForLabelField = !def.fieldDefs.some((_) => _.name === stackbitExt.labelField)
// if (noFieldFoundForLabelField) {
// throw new Error(
// `There is no field with the name "${stackbitExt.labelField}" as specified for "labelField" in ${def._tag} with the name "${def.name}"`,
// )
// }
// }
}
2 changes: 1 addition & 1 deletion packages/@contentlayer/source-contentful/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@contentlayer/source-contentful",
"version": "0.2.5",
"version": "0.2.6-dev.7",
"type": "module",
"exports": "./dist/index.js",
"types": "./dist/index.d.ts",
Expand Down
3 changes: 1 addition & 2 deletions packages/@contentlayer/source-contentful/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,13 +26,12 @@ export type Args = {
export const makeSourcePlugin: core.MakeSourcePlugin<Args & PluginOptions> = async (args) => {
const {
options,
extensions,
restArgs: { accessToken, spaceId, environmentId = 'master', schemaOverrides = {} },
} = await processArgs(args)

return {
type: 'contentful',
extensions,
extensions: {},
options,
provideSchema: () => provideSchema({ accessToken, spaceId, environmentId, options, schemaOverrides }),
fetchData: ({ schemaDef }) =>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,7 @@ const toFieldDef = ({
default: undefined,
description: undefined,
isSystemField: false,
extensions: {},
}

if (fieldOverrides?.type) {
Expand Down
4 changes: 2 additions & 2 deletions packages/@contentlayer/source-files/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@contentlayer/source-files",
"version": "0.2.5",
"version": "0.2.6-dev.7",
"type": "module",
"exports": {
".": {
Expand Down Expand Up @@ -45,7 +45,7 @@
"micromatch": "^4.0.5",
"ts-pattern": "^4.0.2",
"unified": "^10.1.2",
"yaml": "^1.10.2"
"yaml": "^2.1.0"
},
"devDependencies": {
"@types/faker": "^5.5.8",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,7 @@ export const makeErrors = (
description: undefined,
isRequired: true,
isSystemField: false,
extensions: {},
}
errors.push(
new FetchDataError.MissingRequiredFieldsError({
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ export const runTest = async ({
const esbuildHash = 'not-important-for-this-test'

const source = yield* $(T.tryPromise(() => makeSource({ contentDirPath, documentTypes })))
const coreSchemaDef = yield* $(source.provideSchema(esbuildHash))
const coreSchemaDef = yield* $(source.provideSchema({ esbuildHash }))

const documentTypeDefs = (Array.isArray(documentTypes) ? documentTypes : Object.values(documentTypes)).map((_) =>
_.def(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ test('getDataForFieldDef', async () => {
isRequired: false,
default: undefined,
description: undefined,
extensions: {},
},
relativeFilePath: __unusedValue,
options: {
Expand Down Expand Up @@ -94,6 +95,7 @@ test('getDataForFieldDef error', async () => {
isRequired: false,
default: undefined,
description: undefined,
extensions: {},
},
relativeFilePath: unknownToPosixFilePath('some/path/doc.md'),
options: {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ const renderTypeSource = async (documentTypes: DocumentTypes) => {
const esbuildHash = 'not-important-for-this-test'
const schemaDef = await pipe(
T.tryPromise(() => makeSource({ documentTypes, contentDirPath: '' })),
T.chain((source) => source.provideSchema(esbuildHash)),
T.chain((source) => source.provideSchema({ esbuildHash })),
provideJaegerTracing('contentlayer-cli'),
provideConsole,
T.runPromise,
Expand Down
19 changes: 8 additions & 11 deletions packages/@contentlayer/source-files/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -63,20 +63,15 @@ export type Args = {
*/
contentDirExclude?: string[]
// NOTE https://github.com/parcel-bundler/watcher/issues/64

} & PluginOptions &
Partial<Flags> &
/**
* This is an experimental feature and should be ignored for now.
*/
extensions?: {
stackbit?: core.StackbitExtension.Config
}
} & PluginOptions &
Partial<Flags>
*/ Partial<core.ExtensionsRoot>

export const makeSource: core.MakeSourcePlugin<Args> = async (args) => {
const {
options,
extensions,
restArgs: {
documentTypes,
contentDirPath,
Expand All @@ -85,6 +80,7 @@ export const makeSource: core.MakeSourcePlugin<Args> = async (args) => {
onUnknownDocuments = 'skip-warn',
onMissingOrIncompatibleData = 'skip-warn',
onExtraFieldData = 'warn',
...restArgs
},
} = await processArgs(args)

Expand All @@ -96,11 +92,12 @@ export const makeSource: core.MakeSourcePlugin<Args> = async (args) => {

return {
type: 'local',
extensions: extensions ?? {},
// NOTE this is a pretty hacky solution that doesn't use the `extensionProperties` concept. We should revisit this.
extensions: { ...restArgs },
options,
provideSchema: (esbuildHash) =>
provideSchema: ({ esbuildHash, extensionProperties = [] }) =>
pipe(
makeCoreSchema({ documentTypeDefs, options, esbuildHash }),
makeCoreSchema({ documentTypeDefs, options, esbuildHash, extensionProperties }),
T.mapError((error) => new SourceProvideSchemaError({ error })),
),
fetchData: ({ schemaDef, verbose }) =>
Expand Down
4 changes: 3 additions & 1 deletion packages/@contentlayer/source-files/src/schema/defs/field.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import type { ExtensionsField } from '@contentlayer/core'

import type { DocumentType, NestedType } from './index.js'

export type FieldDefType = FieldDef['type']
Expand Down Expand Up @@ -25,7 +27,7 @@ export type FieldDef =
* Field name should contain only alphanumeric characters, underscore and a hyphen [A-Za-z0-9_].
* Must start with a letter. Must not end with an underscore or a hyphen.
*/
interface FieldDefBase {
interface FieldDefBase extends Partial<ExtensionsField> {
/** Short description to editors how the field is to be used */
description?: string

Expand Down
Loading