or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

assets.mdclient.mdentries.mdindex.mdquerying.mdspace-content-types.mdsync.mdtags-taxonomy.md
tile.json

space-content-types.mddocs/

Space and Content Type Management

Access to space metadata, content types, locales, tags, concepts, and other Contentful configuration information for understanding and working with your Contentful space structure.

Capabilities

Space Information

Fetches metadata about the current Contentful space.

/**
 * Fetches the space which the client is currently configured to use
 * @returns Promise for the space
 */
getSpace(): Promise<Space>;

interface Space {
  sys: {
    type: 'Space';
    id: string;
    version: number;
    createdAt: string;
    updatedAt: string;
  };
  name: string;
  locales: LocaleDefinition[];
  defaultLocale: string;
}

interface LocaleDefinition {
  code: string;
  name: string;
  default: boolean;
  fallbackCode?: string;
  optional: boolean;
}

Usage Example:

// Get space information
const space = await client.getSpace();

console.log(`Space: ${space.name} (${space.sys.id})`);
console.log(`Default locale: ${space.defaultLocale}`);
console.log('Available locales:');
space.locales.forEach(locale => {
  console.log(`- ${locale.name} (${locale.code})${locale.default ? ' [default]' : ''}`);
});

Locale Management

Fetches available locales for the space.

/**
 * Fetches a collection of locales
 * @returns Promise for a collection of locales
 */
getLocales(): Promise<LocaleCollection>;

type LocaleCollection = ContentfulCollection<Locale>;

interface Locale {
  sys: {
    type: 'Locale';
    id: string;
    version: number;
    createdAt: string;
    updatedAt: string;
  };
  code: string;
  name: string;
  default: boolean;
  fallbackCode?: string;
  optional: boolean;
}

Usage Example:

// Get all locales
const locales = await client.getLocales();

console.log(`Total locales: ${locales.total}`);
locales.items.forEach(locale => {
  console.log(`${locale.name} (${locale.code})`);
  if (locale.fallbackCode) {
    console.log(`  Fallback: ${locale.fallbackCode}`);
  }
});

Content Type Management

Retrieve content type definitions and metadata.

/**
 * Fetches a content type by ID
 * @param id - The content type's ID
 * @returns Promise for a content type
 */
getContentType(id: string): Promise<ContentType>;

/**
 * Fetches a collection of content types
 * @param query - Optional query parameters
 * @returns Promise for a collection of content types
 */
getContentTypes(query?: { query?: string }): Promise<ContentTypeCollection>;

interface ContentType {
  sys: {
    type: 'ContentType';
    id: string;
    version: number;
    space: { sys: { type: 'Link'; linkType: 'Space'; id: string } };
    environment: { sys: { type: 'Link'; linkType: 'Environment'; id: string } };
    createdAt: string;
    updatedAt: string;
  };
  name: string;
  description?: string;
  displayField?: string;
  fields: ContentTypeField[];
}

interface ContentTypeField {
  id: string;
  name: string;
  type: FieldType;
  localized: boolean;
  required: boolean;
  validations: FieldValidation[];
  disabled: boolean;
  omitted: boolean;
  linkType?: 'Asset' | 'Entry';
  items?: {
    type: FieldType;
    linkType?: 'Asset' | 'Entry';
    validations: FieldValidation[];
  };
}

type FieldType = 
  | 'Symbol'
  | 'Text'
  | 'Integer'
  | 'Number'
  | 'Date'
  | 'Boolean'
  | 'Object'
  | 'Location'
  | 'RichText'
  | 'Array'
  | 'Link'
  | 'ResourceLink';

type ContentTypeCollection = ContentfulCollection<ContentType>;

Usage Examples:

// Get specific content type
const blogPostType = await client.getContentType('blogPost');

console.log(`Content Type: ${blogPostType.name}`);
console.log(`Description: ${blogPostType.description}`);
console.log(`Display Field: ${blogPostType.displayField}`);

// Analyze fields
blogPostType.fields.forEach(field => {
  console.log(`Field: ${field.name} (${field.id})`);
  console.log(`  Type: ${field.type}`);
  console.log(`  Required: ${field.required}`);
  console.log(`  Localized: ${field.localized}`);
  
  if (field.linkType) {
    console.log(`  Links to: ${field.linkType}`);
  }
});

// Get all content types
const allContentTypes = await client.getContentTypes();

console.log(`Total content types: ${allContentTypes.total}`);
allContentTypes.items.forEach(contentType => {
  console.log(`- ${contentType.name} (${contentType.sys.id})`);
});

// Search content types
const searchResults = await client.getContentTypes({
  query: 'blog'
});

Tag Management

Retrieve and work with content tags.

/**
 * Fetches a tag by ID
 * @param id - The tag's ID
 * @returns Promise for a tag
 */
getTag(id: string): Promise<Tag>;

/**
 * Gets a collection of tags
 * @param query - Optional query parameters
 * @returns Promise for a collection of tags
 */
getTags(query?: TagQueries): Promise<TagCollection>;

interface Tag {
  sys: {
    type: 'Tag';
    id: string;
    version: number;
    space: { sys: { type: 'Link'; linkType: 'Space'; id: string } };
    environment: { sys: { type: 'Link'; linkType: 'Environment'; id: string } };
    createdAt: string;
    updatedAt: string;
  };
  name: string;
}

interface TagQueries {
  /** Search tag names */
  name?: string;
  /** Limit results */
  limit?: number;
  /** Skip results for pagination */
  skip?: number;
}

type TagCollection = ContentfulCollection<Tag>;

Usage Examples:

// Get specific tag
const tag = await client.getTag('tag-id');
console.log(`Tag: ${tag.name}`);

// Get all tags
const allTags = await client.getTags();
console.log(`Total tags: ${allTags.total}`);

// Search tags by name
const searchTags = await client.getTags({
  name: 'javascript'
});

// Paginate through tags
const tagPage = await client.getTags({
  limit: 10,
  skip: 20
});

Concept Management

Retrieve concepts for taxonomy and content organization.

/**
 * Fetches a concept by ID
 * @param id - The concept's ID
 * @returns Promise for a concept
 */
getConcept(id: string): Promise<Concept<'en-US'>>;

/**
 * Fetches a collection of concepts
 * @param query - Optional query parameters
 * @returns Promise for a collection of concepts
 */
getConcepts(query?: ConceptsQueries): Promise<ConceptCollection<'en-US'>>;

interface Concept<Locales extends LocaleCode> {
  sys: {
    type: 'TaxonomyConcept';
    id: string;
    version: number;
    space: { sys: { type: 'Link'; linkType: 'Space'; id: string } };
    environment: { sys: { type: 'Link'; linkType: 'Environment'; id: string } };
    createdAt: string;
    updatedAt: string;
  };
  prefLabel: LocalizedField<Locales>;
  altLabels?: LocalizedField<Locales>[];
  hiddenLabels?: LocalizedField<Locales>[];
  definition?: LocalizedField<Locales>;
  editorialNote?: LocalizedField<Locales>;
  notation?: string;
  broader?: ConceptLink[];
  narrower?: ConceptLink[];
  related?: ConceptLink[];
}

interface ConceptsQueries {
  /** Search concepts */
  query?: string;
  /** Limit results */
  limit?: number;
  /** Skip results for pagination */
  skip?: number;
}

type ConceptCollection<Locales extends LocaleCode> = ContentfulCollection<Concept<Locales>>;

Usage Examples:

// Get specific concept
const concept = await client.getConcept('concept-id');
console.log(`Concept: ${concept.prefLabel['en-US']}`);

if (concept.definition) {
  console.log(`Definition: ${concept.definition['en-US']}`);
}

// Get all concepts
const allConcepts = await client.getConcepts();
console.log(`Total concepts: ${allConcepts.total}`);

// Search concepts
const searchResults = await client.getConcepts({
  query: 'technology'
});

Concept Scheme Management

Retrieve concept schemes for organizing taxonomies.

/**
 * Fetches a concept scheme by ID
 * @param id - The concept scheme's ID
 * @returns Promise for a concept scheme
 */
getConceptScheme(id: string): Promise<ConceptScheme<'en-US'>>;

/**
 * Fetches a collection of concept schemes
 * @param query - Optional query parameters
 * @returns Promise for a collection of concept schemes
 */
getConceptSchemes(query?: ConceptSchemesQueries): Promise<ConceptSchemeCollection<'en-US'>>;

interface ConceptScheme<Locales extends LocaleCode> {
  sys: {
    type: 'TaxonomyConceptScheme';
    id: string;
    version: number;
    space: { sys: { type: 'Link'; linkType: 'Space'; id: string } };
    environment: { sys: { type: 'Link'; linkType: 'Environment'; id: string } };
    createdAt: string;
    updatedAt: string;
  };
  prefLabel: LocalizedField<Locales>;
  definition?: LocalizedField<Locales>;
  topConcepts?: ConceptLink[];
}

interface ConceptSchemesQueries {
  /** Search concept schemes */
  query?: string;
  /** Limit results */
  limit?: number;
  /** Skip results for pagination */
  skip?: number;
}

type ConceptSchemeCollection<Locales extends LocaleCode> = ContentfulCollection<ConceptScheme<Locales>>;

Usage Example:

// Get specific concept scheme
const scheme = await client.getConceptScheme('scheme-id');
console.log(`Scheme: ${scheme.prefLabel['en-US']}`);

// Get all concept schemes
const allSchemes = await client.getConceptSchemes();
console.log(`Total schemes: ${allSchemes.total}`);

Supporting Types

Links and References

interface ConceptLink {
  sys: {
    type: 'Link';
    linkType: 'TaxonomyConcept';
    id: string;
  };
}

interface LocalizedField<Locales extends LocaleCode> {
  [locale: string]: string;
}

interface ContentTypeLink {
  type: 'Link';
  linkType: 'ContentType';
  id: string;
}

Field Validations

interface FieldValidation {
  /** Link validation */
  linkContentType?: string[];
  /** In validation for predefined values */
  in?: (string | number)[];
  /** Link validation for mime type groups */
  linkMimetypeGroup?: string[];
  /** Size validation */
  size?: {
    min?: number;
    max?: number;
  };
  /** Range validation */
  range?: {
    min?: number;
    max?: number;
  };
  /** Regex validation */
  regexp?: {
    pattern: string;
    flags?: string;
  };
  /** Prohibit regex validation */
  prohibitRegexp?: {
    pattern: string;
    flags?: string;
  };
  /** Unique validation */
  unique?: boolean;
  /** Date range validation */
  dateRange?: {
    min?: string;
    max?: string;
  };
  /** Asset file size validation */
  assetFileSize?: {
    min?: number;
    max?: number;
  };
  /** Asset image dimensions validation */
  assetImageDimensions?: {
    width?: {
      min?: number;
      max?: number;
    };
    height?: {
      min?: number;
      max?: number;
    };
  };
}

Working with Content Type Information

Dynamic Form Generation

// Generate form fields based on content type
async function generateFormFields(contentTypeId: string) {
  const contentType = await client.getContentType(contentTypeId);
  
  const formFields = contentType.fields.map(field => {
    const fieldConfig = {
      id: field.id,
      name: field.name,
      type: field.type,
      required: field.required,
      localized: field.localized
    };

    // Add validation rules
    const validations = field.validations || [];
    validations.forEach(validation => {
      if (validation.size) {
        fieldConfig.minLength = validation.size.min;
        fieldConfig.maxLength = validation.size.max;
      }
      if (validation.range) {
        fieldConfig.min = validation.range.min;
        fieldConfig.max = validation.range.max;
      }
      if (validation.in) {
        fieldConfig.options = validation.in;
      }
    });

    return fieldConfig;
  });

  return formFields;
}

Content Type Analysis

// Analyze content type usage and complexity
async function analyzeContentTypes() {
  const contentTypes = await client.getContentTypes();
  
  const analysis = contentTypes.items.map(contentType => {
    const fieldCount = contentType.fields.length;
    const requiredFields = contentType.fields.filter(f => f.required).length;
    const localizedFields = contentType.fields.filter(f => f.localized).length;
    const linkFields = contentType.fields.filter(f => f.type === 'Link').length;
    
    return {
      id: contentType.sys.id,
      name: contentType.name,
      complexity: {
        totalFields: fieldCount,
        requiredFields,
        localizedFields,
        linkFields,
        complexity: fieldCount > 10 ? 'high' : fieldCount > 5 ? 'medium' : 'low'
      }
    };
  });

  return analysis;
}

Locale Fallback Resolution

// Implement locale fallback logic
function resolveLocalizedValue<T>(
  localizedField: Record<string, T>, 
  requestedLocale: string, 
  locales: Locale[]
): T | null {
  // Try requested locale first
  if (localizedField[requestedLocale]) {
    return localizedField[requestedLocale];
  }

  // Find locale configuration
  const localeConfig = locales.find(l => l.code === requestedLocale);
  
  // Try fallback locale
  if (localeConfig?.fallbackCode && localizedField[localeConfig.fallbackCode]) {
    return localizedField[localeConfig.fallbackCode];
  }

  // Try default locale
  const defaultLocale = locales.find(l => l.default);
  if (defaultLocale && localizedField[defaultLocale.code]) {
    return localizedField[defaultLocale.code];
  }

  // Return first available value
  const availableLocales = Object.keys(localizedField);
  if (availableLocales.length > 0) {
    return localizedField[availableLocales[0]];
  }

  return null;
}

// Usage
const locales = await client.getLocales();
const entry = await client.withAllLocales.getEntry('entry-id');

const title = resolveLocalizedValue(
  entry.fields.title, 
  'fr-FR', 
  locales.items
);