Content Source Interface Generics

CSI generic types for extending the cached data

The Content Source Interface provides four generic types that can be used to extend the content cached by Netlify Create:

UserContext

This generic type contains user OAuth tokens to update content in the underlying content source. To use UserContext, you need to create an OAuth integration between Netlify Create and the underlying content source. For more information, please contact support.

SchemaContext

This generic type allows the content source module to store custom data in the context property of the Schema object returned by the getSchema() method. Netlify Create caches this custom data with the rest of the Schema data. You can retrieve the cached Schema using the cache.getSchema method passed to the init method.

DocumentContext

This generic type allows the content source module to store custom data in the context property of the Document object returned by the getDocuments() method. Netlify Create caches this custom data with the rest of the Document data. You can retrieve the cached Document using the cache.getDocuments method passed to the init method.

AssetContext

This generic type allows the content source instance to store custom data in the context property of the Asset object returned by the getAssets() method. Netlify Create caches this custom data with the rest of the Asset data. You can retrieve the cached Asset using the cache.getAssets method passed to the init method.

Example

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
import type {
  ContentSourceInterface,
  InitOptions,
  Schema,
  Document,
} from '@stackbit/types'

interface UserContext {
  accessToken: string
}

interface SchemaContext {
  customSchemaProperty: string
}

interface DocumentContext {
  customDocumentProperty: string
}

interface AssetContext {
  customAssetProperty: string
}

export class MyContentSource
  implements
    ContentSourceInterface<
      UserContext,
      SchemaContext,
      DocumentContext,
      AssetContext
    >
{
  async init(
    options: InitOptions<SchemaContext, DocumentContext, AssetContext>,
  ): Promise<void> {
    this.cache = options.cache
  }

  async getSchema(): Promise<Schema<SchemaContext>> {
    const sourceModels = await this.apiClient.getModels()
    const stackbitModels = convertToStackbitModels(sourceModels)
    return {
      models: stackbitModels,
      locales: [],
      context: {
        customSchemaProperty: 'foo',
      },
    }
  }

  async getDocuments(): Promise<Document<DocumentContext>[]> {
    const sourceDocuments = await this.apiClient.getDocuments()
    const stackbitDocuments = convertToStackbitDocuments(sourceDocuments)
    return stackbitDocuments.map((stackbitDocument) => {
      stackbitDocument.context = {
        customDocumentProperty: 'bar',
      }
      return stackbitDocument
    })
  }

  async updateDocument(options): Promise<void> {
    const stackbitSchema = this.cache.getSchema()
    // the customSchemaProperty is available under the context property
    // stackbitSchema.context.customSchemaProperty

    // the customDocumentProperty is available under the context property
    // options.document.context.customDocumentProperty

    await this.apiClient.updateDocument({
      token: options.userContext.accessToken,
      document: convertOperationsToAPIDocument(
        options.document,
        options.operations,
      ),
    })
  }
}