Skip to content

Commit 005d234

Browse files
committed
override field types
1 parent c82ce45 commit 005d234

File tree

13 files changed

+95
-24
lines changed

13 files changed

+95
-24
lines changed

Diff for: packages/@contentlayer/cli/package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@contentlayer/cli",
3-
"version": "0.2.8-dev.9",
3+
"version": "0.2.8-dev.12",
44
"type": "module",
55
"exports": "./dist/index.js",
66
"types": "./dist/index.d.ts",

Diff for: packages/@contentlayer/client/package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@contentlayer/client",
3-
"version": "0.2.8-dev.9",
3+
"version": "0.2.8-dev.12",
44
"type": "module",
55
"exports": "./dist/index.js",
66
"types": "./dist/index.d.ts",

Diff for: packages/@contentlayer/core/package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@contentlayer/core",
3-
"version": "0.2.8-dev.9",
3+
"version": "0.2.8-dev.12",
44
"type": "module",
55
"exports": "./dist/index.js",
66
"types": "./dist/index.d.ts",

Diff for: packages/@contentlayer/experimental-source-files-stackbit/package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@contentlayer/experimental-source-files-stackbit",
3-
"version": "0.2.8-dev.9",
3+
"version": "0.2.8-dev.12",
44
"type": "module",
55
"exports": {
66
".": {

Diff for: packages/@contentlayer/experimental-source-files-stackbit/src/index.ts

+61-13
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,34 @@
1-
import type { GetDocumentTypeNamesGen } from '@contentlayer/core'
1+
import type * as core from '@contentlayer/core'
22
import type * as SourceFiles from '@contentlayer/source-files'
3-
import { defineDocumentType } from '@contentlayer/source-files'
4-
import { not, partition } from '@contentlayer/utils'
3+
import { defineDocumentType, defineNestedType } from '@contentlayer/source-files'
4+
import type { PartialDeep } from '@contentlayer/utils'
5+
import { mergeDeep, not, partition, pick } from '@contentlayer/utils'
56
import * as Stackbit from '@stackbit/sdk'
67
import { validateAndNormalizeConfig } from '@stackbit/sdk/dist/config/config-loader.js'
78

89
import type { SharedCtx } from './mapping.js'
910
import { stackbitDocumentLikeModelToDocumentType, stackbitObjectModelToDocumentType } from './mapping.js'
1011

12+
/** NOTE Overrides are currently not validated - use carefully */
1113
export type ContentlayerOverrideArgs<TDocumentTypeNames extends string> = {
12-
documentTypes: Partial<{
14+
documentTypes?: Partial<{
1315
[TDocumentTypeName in TDocumentTypeNames]: ContentlayerOverrideDocumentType<TDocumentTypeName>
1416
}>
17+
nestedTypes?: Partial<{
18+
[TDocumentTypeName in TDocumentTypeNames]: ContentlayerOverrideNestedType
19+
}>
1520
}
1621

1722
export type ContentlayerOverrideDocumentType<TDocumentTypeName extends string> = {
1823
filePathPattern?: string
24+
fields?: { [fieldName: string]: { type: SourceFiles.FieldDefType } }
1925
computedFields?: SourceFiles.ComputedFields<TDocumentTypeName>
2026
}
2127

28+
export type ContentlayerOverrideNestedType = {
29+
fields?: { [fieldName: string]: { type: SourceFiles.FieldDefType } }
30+
}
31+
2232
/**
2333
* @example
2434
* ```ts
@@ -32,9 +42,9 @@ export type ContentlayerOverrideDocumentType<TDocumentTypeName extends string> =
3242
* })
3343
* ```
3444
*/
35-
export const loadStackbitConfigAsDocumentTypes = <TDocumentTypeNames extends GetDocumentTypeNamesGen>(
45+
export const loadStackbitConfigAsDocumentTypes = <TDocumentTypeNames extends core.GetDocumentTypeNamesGen>(
3646
options: Stackbit.ConfigLoaderOptions = { dirPath: '' },
37-
overrideArgs: ContentlayerOverrideArgs<TDocumentTypeNames> = { documentTypes: {} },
47+
overrideArgs: ContentlayerOverrideArgs<TDocumentTypeNames> = { documentTypes: {}, nestedTypes: {} },
3848
): Promise<SourceFiles.DocumentType[]> =>
3949
Stackbit.loadConfig(options).then((configResult) => {
4050
if (configResult.errors.length > 0) {
@@ -58,9 +68,9 @@ export const loadStackbitConfigAsDocumentTypes = <TDocumentTypeNames extends Get
5868
* export default makeSource({ contentDirPath: 'content', documentTypes })
5969
* ```
6070
*/
61-
export const stackbitConfigToDocumentTypes = <TDocumentTypeNames extends GetDocumentTypeNamesGen>(
71+
export const stackbitConfigToDocumentTypes = <TDocumentTypeNames extends core.GetDocumentTypeNamesGen>(
6272
stackbitConfig: Stackbit.Config | Stackbit.YamlConfig,
63-
overrideArgs: ContentlayerOverrideArgs<TDocumentTypeNames> = { documentTypes: {} },
73+
overrideArgs: ContentlayerOverrideArgs<TDocumentTypeNames> = { documentTypes: {}, nestedTypes: {} },
6474
): SourceFiles.DocumentType[] => {
6575
const validatedStackbitConfig = validateStackbitConfig(stackbitConfig)
6676

@@ -76,15 +86,48 @@ export const stackbitConfigToDocumentTypes = <TDocumentTypeNames extends GetDocu
7686
objectModels.forEach((model) => {
7787
const nestedType = stackbitObjectModelToDocumentType(ctx)(model)
7888
ctx.nestedTypeMap[model.name] = nestedType
89+
90+
const nestedOverride = (overrideArgs.nestedTypes as any)?.[model.name] as ContentlayerOverrideNestedType | undefined
91+
const fields = nestedType.def().fields
92+
if (nestedOverride?.fields && fields) {
93+
for (const [fieldName, { type }] of Object.entries(nestedOverride.fields)) {
94+
const fieldDef = Array.isArray(fields)
95+
? fields.find((fieldDef) => fieldDef.name === fieldName)
96+
: fields[fieldName]
97+
98+
if (fieldDef) {
99+
fieldDef.type = type
100+
}
101+
}
102+
103+
patchNestedType(nestedType, { fields })
104+
}
79105
})
80106

81107
documentTypes.forEach((documentType) => {
82108
const documentTypeName = documentType.def().name
83109
ctx.documentTypeMap[documentTypeName] = documentType
84110

85-
const documentOverride = (overrideArgs.documentTypes as any)[documentTypeName]
86-
if (documentOverride) {
87-
patchDocumentType(documentType, documentOverride)
111+
const documentOverride = (overrideArgs.documentTypes as any)?.[documentTypeName] as
112+
| ContentlayerOverrideDocumentType<string>
113+
| undefined
114+
if (documentOverride?.filePathPattern !== undefined || documentOverride?.computedFields !== undefined) {
115+
patchDocumentType(documentType, pick(documentOverride, ['filePathPattern', 'computedFields']))
116+
}
117+
118+
const fields = documentType.def().fields
119+
if (documentOverride?.fields && fields) {
120+
for (const [fieldName, { type }] of Object.entries(documentOverride.fields)) {
121+
const fieldDef = Array.isArray(fields)
122+
? fields.find((fieldDef) => fieldDef.name === fieldName)
123+
: fields[fieldName]
124+
125+
if (fieldDef) {
126+
fieldDef.type = type
127+
}
128+
}
129+
130+
patchDocumentType(documentType, { fields })
88131
}
89132
})
90133

@@ -93,10 +136,15 @@ export const stackbitConfigToDocumentTypes = <TDocumentTypeNames extends GetDocu
93136

94137
const patchDocumentType = (
95138
documentType: SourceFiles.DocumentType,
96-
patch: Partial<SourceFiles.DocumentTypeDef>,
139+
patch: PartialDeep<SourceFiles.DocumentTypeDef>,
97140
): void => {
98141
const previousDef = documentType.def()
99-
documentType.def = defineDocumentType(() => ({ ...previousDef, ...patch })).def
142+
documentType.def = defineDocumentType(() => mergeDeep({ ...previousDef, ...patch })).def
143+
}
144+
145+
const patchNestedType = (nestedType: SourceFiles.NestedType, patch: PartialDeep<SourceFiles.NestedTypeDef>): void => {
146+
const previousDef = nestedType.def()
147+
nestedType.def = defineNestedType(() => mergeDeep({ ...previousDef, ...patch })).def
100148
}
101149

102150
const validateStackbitConfig = (stackbitConfig: Stackbit.Config | Stackbit.YamlConfig): Stackbit.Config => {

Diff for: packages/@contentlayer/source-contentful/package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@contentlayer/source-contentful",
3-
"version": "0.2.8-dev.9",
3+
"version": "0.2.8-dev.12",
44
"type": "module",
55
"exports": "./dist/index.js",
66
"types": "./dist/index.d.ts",

Diff for: packages/@contentlayer/source-files/package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@contentlayer/source-files",
3-
"version": "0.2.8-dev.9",
3+
"version": "0.2.8-dev.12",
44
"type": "module",
55
"exports": {
66
".": {

Diff for: packages/@contentlayer/utils/package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@contentlayer/utils",
3-
"version": "0.2.8-dev.9",
3+
"version": "0.2.8-dev.12",
44
"type": "module",
55
"exports": {
66
"./package.json": {

Diff for: packages/@contentlayer/utils/src/object/index.ts

+20
Original file line numberDiff line numberDiff line change
@@ -10,3 +10,23 @@ export const mapObjectValues = <O_In extends Record<any, any>, V_Out>(
1010
const mappedEntries = Object.entries(obj).map(([key, val]) => [key, mapValue(key as keyof O_In, val)] as const)
1111
return Object.fromEntries(mappedEntries) as any
1212
}
13+
14+
export const mergeDeep = <T extends Record<any, any>>(...objs: T[]): T => {
15+
const result = {} as T
16+
for (const obj of objs) {
17+
for (const [key, val] of Object.entries(obj)) {
18+
if (val && typeof val === 'object' && !Array.isArray(val)) {
19+
// @ts-expect-error TODO
20+
result[key] = mergeDeep(result[key] || {}, val)
21+
} else {
22+
// @ts-expect-error TODO
23+
result[key] = val
24+
}
25+
}
26+
}
27+
return result
28+
}
29+
30+
export type PartialDeep<T> = {
31+
[P in keyof T]?: T[P] extends Record<any, any> ? PartialDeep<T[P]> : T[P]
32+
}

Diff for: packages/@contentlayer/utils/src/object/pick.ts

+4-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,10 @@ type ConvertPick<T> = ConvertUndefined<T> & PickRequired<T>
55

66
export const pick = <Obj, Keys extends keyof Obj>(obj: Obj, keys: Keys[]): ConvertPick<{ [K in Keys]: Obj[K] }> => {
77
return keys.reduce((acc, key) => {
8-
acc[key] = obj[key]
8+
const val = obj[key]
9+
if (val !== undefined) {
10+
acc[key] = val
11+
}
912
return acc
1013
}, {} as any)
1114
}

Diff for: packages/contentlayer-stackbit-yaml-generator/package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "contentlayer-stackbit-yaml-generator",
3-
"version": "0.2.8-dev.9",
3+
"version": "0.2.8-dev.12",
44
"type": "module",
55
"bin": "./dist/cli/index.js",
66
"exports": "./dist/lib/index.js",

Diff for: packages/contentlayer/package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "contentlayer",
3-
"version": "0.2.8-dev.9",
3+
"version": "0.2.8-dev.12",
44
"bin": "./bin/cli.cjs",
55
"type": "module",
66
"engines": {

Diff for: packages/next-contentlayer/package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "next-contentlayer",
3-
"version": "0.2.8-dev.9",
3+
"version": "0.2.8-dev.12",
44
"type": "module",
55
"main": "./dist/index-cjs.cjs",
66
"sideEffects": false,

0 commit comments

Comments
 (0)