GithubHelp home page GithubHelp logo

contentful-userland / cf-content-types-generator Goto Github PK

View Code? Open in Web Editor NEW
100.0 20.0 17.0 1.68 MB

Generate TS declarations for content types

License: MIT License

JavaScript 0.36% Batchfile 0.05% TypeScript 99.53% Shell 0.06%
type-tool typescript contentful cli builder generator

cf-content-types-generator's Introduction

TS contentful content types generator

A CLI to generate Typescript definitions based on JSON export generated with contentful CLI.

oclif Version Downloads/week License Coverage Status

Table of Contents

Installation

npm install cf-content-types-generator

Usage

Contentful Content Types (TS Definitions) Generator

USAGE
  $ cf-content-types-generator [FILE]

ARGUMENTS
  FILE  local export (.json)

OPTIONS
  -e, --environment=environment  environment
  -h, --help                     show CLI help
  -o, --out=out                  output directory
  -p, --preserve                 preserve output folder
  -X  --v10                      create contentful.js v10 types
  -r, --response                 add response types (only for v10 types)
  -l, --localized                add localized types
  -d, --jsdoc                    add JSDoc comments
  -g, --typeguard                add type guards
  -s, --spaceId=spaceId          space id
  -t, --token=token              management token
  -v, --version                  show CLI version
  -a, --host                     The Management API host

Example

Local

Use a local JSON file to load contentTypes. Flags for spaceId, token and environement will be ignored.

Will print result to console

cf-content-types-generator path/to/exported/file.json

in a real world scenario, you would pipe the result to a file.

Will store resulting files in target directory

cf-content-types-generator path/to/exported/file.json -o path/to/target/out/directory

existing directory content will be removed.

Remote

If no file arg provided, remote mode is enabled. spaceId and token flags need to be set.

cf-content-types-generator -s 2l3j7k267xxx  -t CFPAT-64FtZEIOruksuaE_Td0qBvHdELNWBCC0fZUWq1NFxxx

Input

As input a json file with a contentTypes field is expected:

{
  "contentTypes": [
    {
      "sys": {
        "id": "artist",
        "type": "ContentType"
      },
      "displayField": "name",
      "name": "Artist",
      "fields": [
        {
          "id": "name",
          "name": "Name",
          "type": "Symbol",
          "required": true,
          "validations": [
            {
              "unique": true
            }
          ]
        },
        {
          "id": "profilePicture",
          "name": "Profile Picture",
          "type": "Link",
          "required": false,
          "validations": [
            {
              "linkMimetypeGroup": ["image"]
            }
          ],
          "linkType": "Asset"
        },
        {
          "id": "bio",
          "name": "Bio",
          "type": "RichText",
          "required": false,
          "validations": [
            {
              "nodes": {}
            },
            {
              "enabledMarks": [],
              "message": "Marks are not allowed"
            },
            {
              "enabledNodeTypes": [],
              "message": "Nodes are not allowed"
            }
          ]
        }
      ]
    },
    {
      "sys": {
        "id": "artwork",
        "type": "ContentType"
      },
      "displayField": "name",
      "name": "Artwork",
      "fields": [
        {
          "id": "name",
          "name": "Name",
          "type": "Symbol",
          "required": true,
          "validations": []
        },
        {
          "id": "type",
          "name": "Type",
          "type": "Symbol",
          "required": false,
          "validations": [
            {
              "in": ["print", "drawing", "painting"],
              "message": "Hello - this is a custom error message."
            }
          ]
        },
        {
          "id": "preview",
          "name": "Preview",
          "type": "Array",
          "required": false,
          "validations": [],
          "items": {
            "type": "Link",
            "validations": [
              {
                "linkMimetypeGroup": ["image", "audio", "video"]
              }
            ],
            "linkType": "Asset"
          }
        },
        {
          "id": "artist",
          "name": "Artist",
          "type": "Link",
          "required": true,
          "validations": [
            {
              "linkContentType": ["artist"]
            }
          ],
          "linkType": "Entry"
        }
      ]
    }
  ]
}

This example shows a subset of the actual payload provided by contentful's cli export command.

Output

import * as CFRichTextTypes from '@contentful/rich-text-types';
import { Entry, EntryFields } from 'contentful';

export interface TypeArtistFields {
  name: Contentful.EntryFields.Symbol;
  profilePicture?: Contentful.Asset;
  bio?: EntryFields.RichText;
}

export type TypeArtist = Entry<TypeArtistFields>;

export interface TypeArtworkFields {
  name: EntryFields.Symbol;
  type?: 'print' | 'drawing' | 'painting';
  preview?: Asset[];
  artist: Entry<TypeArtistFields>;
}

export type TypeArtwork = Entry<TypeArtworkFields>;

This all only works if you add the contentful package to your target project to get all relevant type definitions.

Renderer

Extend the default BaseContentTypeRenderer class, or implement the ContentTypeRenderer interface for custom rendering.

Relevant methods to override:

Methods Description Override
render Enriches a SourceFile with all relevant nodes To control content type rendering (you should know what you're doing)
getContext Returns new render context object To define custom type renderer and custom module name function
addDefaultImports Define set of default imports added to every file To control default imported modules
renderField Returns a PropertySignatureStructure representing a field property To control Field property rendering
renderFieldType Returns a string representing a field type To control field type rendering (recommended)
renderEntry Returns a TypeAliasDeclarationStructure representing an entry type alias To control entry type alias rendering
renderEntryType Returns a string representing an entry type To control entry type rendering (recommended)

Table represents order of execution

Set content type renderers:

import {
  CFDefinitionsBuilder,
  DefaultContentTypeRenderer,
  LocalizedContentTypeRenderer,
} from 'cf-content-types-generator';

const builder = new CFDefinitionsBuilder([
  new DefaultContentTypeRenderer(),
  new LocalizedContentTypeRenderer(),
]);

DefaultContentTypeRenderer

A renderer to render type fields and entry definitions. For most scenarios, this renderer is sufficient. If no custom renderers given, CFDefinitionsBuilder creates a DefaultContentTypeRenderer by default.

Example Usage

import { CFDefinitionsBuilder, DefaultContentTypeRenderer } from 'cf-content-types-generator';

const builder = new CFDefinitionsBuilder([new DefaultContentTypeRenderer()]);

V10ContentTypeRenderer

A renderer to render type fields and entry definitions compatible with contentful.js v10.

import { CFDefinitionsBuilder, V10ContentTypeRenderer } from 'cf-content-types-generator';

const builder = new CFDefinitionsBuilder([new V10ContentTypeRenderer()]);

LocalizedContentTypeRenderer

Add additional types for localized fields. It adds utility types to transform fields into localized fields for given locales More details on the utility types can be found here: Issue 121 Note that these types are not needed when using V10ContentTypeRenderer as the v10 entry type already supports localization.

Example Usage

import {
  CFDefinitionsBuilder,
  DefaultContentTypeRenderer,
  LocalizedContentTypeRenderer,
} from 'cf-content-types-generator';

const builder = new CFDefinitionsBuilder([
  new DefaultContentTypeRenderer(),
  new LocalizedContentTypeRenderer(),
]);

Example output

export interface TypeCategoryFields {
  title: Contentful.EntryFields.Text;
  icon?: Contentful.Asset;
  categoryDescription?: Contentful.EntryFields.Text;
}

export type TypeCategory = Contentful.Entry<TypeCategoryFields>;

export type LocalizedTypeCategoryFields<Locales extends keyof any> = LocalizedFields<
  TypeCategoryFields,
  Locales
>;

export type LocalizedTypeCategory<Locales extends keyof any> = LocalizedEntry<
  TypeCategory,
  Locales
>;

Example output usage

const localizedCategory: LocalizedTypeCategory<'DE-de' | 'En-en'> = {
  fields: {
    categoryDescription: {
      'DE-de': 'german description',
      'En-en': 'english description',
    },
  },
};

JSDocRenderer

Adds JSDoc Comments to every Entry type and Field type (created by the default renderer, or a renderer that creates the same entry and field type names). This renderer can be customized through renderer options.

JSDocContentTypeRenderer can only render comments for already rendered types. It's essential to add it after the default renderer, or any renderer that creates entry and field types based on the context moduleName resolution.

Example Usage

import { CFDefinitionsBuilder, JsDocRenderer } from 'cf-content-types-generator';

const builder = new CFDefinitionsBuilder([new DefaultContentTypeRenderer(), new JsDocRenderer()]);

Example output

import * as Contentful from 'contentful';
/**
 * Fields type definition for content type 'TypeAnimal'
 * @name TypeAnimalFields
 * @type {TypeAnimalFields}
 * @memberof TypeAnimal
 */
export interface TypeAnimalFields {
  /**
   * Field type definition for field 'bread' (Bread)
   * @name Bread
   * @localized false
   */
  bread: Contentful.EntryFields.Symbol;
}

/**
 * Entry type definition for content type 'animal' (Animal)
 * @name TypeAnimal
 * @type {TypeAnimal}
 */
export type TypeAnimal = Contentful.Entry<TypeAnimalFields>;

TypeGuardRenderer

Adds type guard functions for every content type

Example Usage

import {
  CFDefinitionsBuilder,
  DefaultContentTypeRenderer,
  TypeGuardRenderer,
} from 'cf-content-types-generator';

const builder = new CFDefinitionsBuilder([
  new DefaultContentTypeRenderer(),
  new TypeGuardRenderer(),
]);

Example output

import { Entry, EntryFields } from 'contentful';
import type { WithContentTypeLink } from 'TypeGuardTypes';

export interface TypeAnimalFields {
  bread: EntryFields.Symbol;
}

export type TypeAnimal = Entry<TypeAnimalFields>;

export function isTypeAnimal(entry: WithContentTypeLink): entry is TypeAnimal {
  return entry.sys.contentType.sys.id === 'animal';
}

V10TypeGuardRenderer

Adds type guard functions for every content type which are compatible with contentful.js v10.

Example Usage

import {
  CFDefinitionsBuilder,
  V10ContentTypeRenderer,
  V10TypeGuardRenderer,
} from 'cf-content-types-generator';

const builder = new CFDefinitionsBuilder([
  new V10ContentTypeRenderer(),
  new V10TypeGuardRenderer(),
]);

Example output

import type {
  ChainModifiers,
  Entry,
  EntryFieldTypes,
  EntrySkeletonType,
  LocaleCode,
} from 'contentful';

export interface TypeAnimalFields {
  bread?: EntryFieldTypes.Symbol;
}

export type TypeAnimalSkeleton = EntrySkeletonType<TypeAnimalFields, 'animal'>;
export type TypeAnimal<Modifiers extends ChainModifiers, Locales extends LocaleCode> = Entry<
  TypeAnimalSkeleton,
  Modifiers,
  Locales
>;

export function isTypeAnimal<Modifiers extends ChainModifiers, Locales extends LocaleCode>(
  entry: Entry<EntrySkeletonType, Modifiers, Locales>,
): entry is TypeAnimal<Modifiers, Locales> {
  return entry.sys.contentType.sys.id === 'animal';
}

ResponseTypeRenderer

Adds response types for every content type which are compatible with contentful.js v10.

Example Usage

import {
  CFDefinitionsBuilder,
  V10ContentTypeRenderer,
  ResponseTypeRenderer,
} from 'cf-content-types-generator';

const builder = new CFDefinitionsBuilder([
  new V10ContentTypeRenderer(),
  new ResponseTypeRenderer(),
]);

Example output

import type {
  ChainModifiers,
  Entry,
  EntryFieldTypes,
  EntrySkeletonType,
  LocaleCode,
} from 'contentful';

export interface TypeAnimalFields {
  bread?: EntryFieldTypes.Symbol;
}

export type TypeAnimalSkeleton = EntrySkeletonType<TypeAnimalFields, 'animal'>;
export type TypeAnimal<Modifiers extends ChainModifiers, Locales extends LocaleCode> = Entry<
  TypeAnimalSkeleton,
  Modifiers,
  Locales
>;

export type TypeAnimalWithoutLinkResolutionResponse = TypeAnimal<'WITHOUT_LINK_RESOLUTION'>;
export type TypeAnimalWithoutUnresolvableLinksResponse = TypeAnimal<'WITHOUT_UNRESOLVABLE_LINKS'>;
export type TypeAnimalWithAllLocalesResponse<Locales extends LocaleCode = LocaleCode> =
  TypeAnimal<'WITH_ALL_LOCALES'>;
export type TypeAnimalWithAllLocalesAndWithoutLinkResolutionResponse<
  Locales extends LocaleCode = LocaleCode,
> = TypeAnimal<'WITH_ALL_LOCALES' | 'WITHOUT_LINK_RESOLUTION', Locales>;
export type TypeAnimalWithAllLocalesAndWithoutUnresolvableLinksResponse<
  Locales extends LocaleCode = LocaleCode,
> = TypeAnimal<'WITH_ALL_LOCALES' | 'WITHOUT_UNRESOLVABLE_LINKS', Locales>;

Direct Usage

If you're not a CLI person, or you want to integrate it with your tooling workflow, you can also directly use the CFDefinitionsBuilder from cf-definitions-builder.ts

import CFDefinitionsBuilder from 'cf-content-types-generator';

const stringContent = new CFDefinitionsBuilder()
  .appendType({
    name: 'My Entry',
    sys: {
      id: 'myEntry',
      type: 'ContentType',
    },
    fields: [
      {
        id: 'myField',
        name: 'My Field',
        type: 'Symbol',
        required: true,
        validations: [],
        disabled: false,
        localized: false,
        omitted: false,
      },
    ],
  })
  .toString();

console.log(stringContent);

// import { Entry, EntryFields } from "contentful";

//
// export interface TypeMyEntryFields {
//   myField: EntryFields.Symbol;
// }
//
// export type TypeMyEntry = Entry<TypeMyEntryFields>;

Browser Usage

You can use CFDefinitionsBuilder also in a browser environment.

Example: TS Content Types Generator App

cf-content-types-generator's People

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

cf-content-types-generator's Issues

TypeError: context.getFieldRenderer(...) is not a function

I am trying to generate types using the cli. I do not provide a JSON file but pass spaceId and token. This is the command I am using:

npx cf-content-types-generator --spaceId=XXX --token=XXX -o test-dir

This is the result:

  ✔ Initialize client (1s)
  ✔ Fetching data from space
    ✔ Connecting to space (1s)
    ✔ Fetching content types data (1s)
    ✔ Fetching tags data (1s)
    ↓ Fetching editor interfaces data [skipped]
    ↓ Fetching content entries data [skipped]
    ↓ Fetching assets data [skipped]
    ✔ Fetching locales data (1s)
    ↓ Fetching webhooks data [skipped]
    ↓ Fetching roles data [skipped]
  ↓ Download assets [skipped]
  ↓ Write export log file [skipped]
┌────────────────────┐
│ Exported entities  │
├───────────────┬────┤
│ Content Types │ 28 │
├───────────────┼────┤
│ Tags          │ 43 │
├───────────────┼────┤
│ Locales       │ 4  │
└───────────────┴────┘
The export took less than a minute (1s)
No errors or warnings occurred
The export was successful.
    TypeError: context.getFieldRenderer(...) is not a function

Nothing is written to disk.

Support EU Data Center

Contentful added the support to host an organisation within the EU, see https://www.contentful.com/developers/docs/infrastructure/eu-data-residency/

Therefore, the endpoints for the API in EU changed:

API URL
Content Management API https://api.eu.contentful.com
Content Delivery API https://cdn.eu.contentful.com
Content Preview API https://preview.eu.contentful.com
GraphQL API https://graphql.eu.contentful.com
Images API https://images.eu.ctfassets.net
User Management API https://api.eu.contentful.com

Suggestion:

  • Add an additional and optional flag where the endpoint is in "EU" or not.

Alternative:

Syntax error created from type generation

I'm having a problem with various apps that are using the cf-content-types-generator, specifically this app which I'm using in Contentful. The same thing is happening on Intercom's contentful-typescript-codegen.

What is happening is when I try to generate types, a clear syntax error is happening which comes from an extra semicolon and backslash at the end of the colorPalette line:

export interface TypeComponentTextBlockFields {
    internalName?: Contentful.EntryFields.Symbol;
    headline?: Contentful.EntryFields.Symbol;
    subline?: Contentful.EntryFields.Symbol;
    body?: CFRichTextTypes.Block | CFRichTextTypes.Inline;
    colorPalette?: "1. White (#FFFFFF)" | "2. White Smoke (#FCFCFC)" | "3. Light Gray (#F4F4F4)" | "4. Gray (#EAEAEA)" | "5. Steel Gray (#BBBBBB)" | "6. Dark Gray (#797979)" | "7. Black (#000000)\";;
}

I don't know why this is happening, but it means that I can't usefully use the package/script as a single command or as part of CI/CD, since linting stops it. Currently I have to use the Contentful app and then manually edit the file to allow the project to use the types correctly.

What could be causing this error? Let me know if I can provide more information.

Entry Link with no validations references non-existent type

When creating a definitions for a content type with a Link field to any Entry it tries to reference a type that is never created. I created a repro: https://repl.it/@AndrewLeedham56/cf-content-types-generator-repro

The outputted definitions are:

import * as Contentful from "contentful";

export interface TypeFooFields {
    contentfulTitle?: Contentful.EntryFields.Symbol;
    components?: Contentful.Entry<TypeComponentsFields>[];
}

export type TypeFoo = Contentful.Entry<TypeFooFields>;

It is referencing TypeComponentsFields which is never created, should it not just be Contentful.Entry with no generic if there is no specific validation?

typeError: validations.map is not a function: linkContentType can be a string or a string[]

The validations are failing for me because it thinks that linkContentType can only be an array of string values. Wrong assumption linkContentType can be a string or an array of strings

LinkContentType: ['entryRef', 'entryRefTwo']
or
LinkContentType: 'entryRef'

This may go against the official docs but it is allowed and is valid migration using contentfuls DSL.

Support a config file

it would be good if we could have something like cf-content-types-generator.config.js and cf-content-types-generator.config.ts to make it easier to maintain and track options.

Suggestions on how to do type narrowing?

This is just a question not directly tied to this library so feel very free to just close it.

Do you have suggestions on how to do type narrowing?

export interface TypeBlogFields {
  component: Contentful.Entry<Button | Image | Link | Text | Video>;
}
const blog: TypeBlogFields = getBlog();
const isButton = blog.component.sys.contentType.id === 'button'

In my eyes then ideally Sys was generic such that the contentTypeId was a constant value instead of a string. Then, if you check sys.contentType.id with an if statement TypeScript would be able to do type narrowing.

Not sure if you know of a better way 😊

Thoughts on adding some-sort of output customisation

I have been working on adding this package to one of our internal projects, and in order to facilitate the needs there I have forked this package and some modifications: AndrewLeedham@5a4c117. The main change is exporting to the type CMSEntry<ContentTypeId, Fields> instead of Entry<Fields>, as well as exporting a Union of all the types and some other minor tweaks. I am curious on your thoughts on a first class way of supporting something like this, ideas I have been considering:

  1. Put a PR in to the contentful.js repo to add the strongly typed Entry as an option, something like:
export interface Entry<Fields, ContentTypeID extends string = string> {
    sys: Sys<ContentTypeID>;
    fields: Fields;
    toPlainObject(): object;
    update(): Promise<Entry<T, ContentTypeID>>;
}

and extend this repo to export things in the format I am after.

  1. Add a method to the CFDefinitionsBuilder which exposes the ts-morph project, so it can be modified before generating the types.

  2. Integrate https://github.com/webpack/tapable into the package so the rendering can be modified as needed.

v10 typing includes EntryFieldTypes, but mismatches actual API response

Hi,
we would love to type our application with generated types from our contentful space.

When generating the types via CLI (with v10 flag activated), we get the following as a result

import type { ChainModifiers, Entry, EntryFieldTypes, EntrySkeletonType, LocaleCode } from 'contentful';
export interface TypeCeTextBlockFields {
  headline: EntryFieldTypes.Symbol;
  copy: EntryFieldTypes.Text;
  buttonText?: EntryFieldTypes.Symbol;
  buttonUrl?: EntryFieldTypes.Symbol;
}

export type TypeCeTextBlockSkeleton = EntrySkeletonType<TypeCeTextBlockFields, 'ceTextBlock'>;
export type TypeCeTextBlock<Modifiers extends ChainModifiers, Locales extends LocaleCode> = Entry<
  TypeCeTextBlockSkeleton,
  Modifiers,
  Locales
>;

But the actual API response (for the fields) looks somewhat like this:

{
 "headline": "test headline",
 "copy": "lorem ipsum dolor"
}

As far as I understand EntryFieldTypes is an extended Type which is an object with type and values, but the API returns the strings for example directly - so they mismatch.

Eventually I got a general misconception of how the type generation should work or do I need to adopt the API query? When Manually changing the Type from EntryFieldTypes.Symbol to EntryFields.Symbol I get the expected behavior, but of course that is not a proper solution for this use case.

CLI run command throws a TypeError

Description

The run command for ``cf-content-types-generator` no longer works as of the v2.1.0 release. This was working in v2.0.1.

Environment

Version: [email protected]
OS: macOS Monterey (12.3)
Shell: zsh

Last known working version: [email protected]

Reproduction Steps

Either:

  1. From your shell, run npx cf-content-types-generator -s YOUR_SPACE -e YOU_ENV -t YOUR_TOKEN -o __cf_generated__
  2. No files are generated and the following error is thrown:
    TypeError: (0 , contentful_export_1.default) is not a function
error Command failed with exit code 1.
info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command.

Or:

  1. Install cf-content-types-generator per README instructions.
  2. Have a run script in package.json with: cf-content-types-generator -s YOUR_SPACE -e YOU_ENV -t YOUR_TOKEN -o __cf_generated__
  3. Execute run script command. E.g., yarn get-cf-types in my case.
  4. No files are generated and the same error as above is thrown.

"Type does not satisfy the constraint 'EntrySkeletonType'."

When using generated types w/ contentful: ^10.2.3 (using cf-content-types-generator: ^2.12.2):

Type '<Generated Type>' does not satisfy the constraint 'EntrySkeletonType'. 
Type '<Generated Type>' is missing the following properties from type 'EntrySkeletonType': fields, contentTypeId

The automated release is failing 🚨

🚨 The automated release from the master branch failed. 🚨

I recommend you give this issue a high priority, so other packages depending on you could benefit from your bug fixes and new features.

You can find below the list of errors reported by semantic-release. Each one of them has to be resolved in order to automatically publish your package. I’m sure you can resolve this 💪.

Errors are usually caused by a misconfiguration or an authentication problem. With each error reported below you will find explanation and guidance to help you to resolve it.

Once all the errors are resolved, semantic-release will release your package the next time you push a commit to the master branch. You can also manually restart the failed CI job that runs semantic-release.

If you are not sure how to resolve this, here is some links that can help you:

If those don’t help, or if this issue is reporting something you think isn’t right, you can always ask the humans behind semantic-release.


Invalid npm token.

The npm token configured in the NPM_TOKEN environment variable must be a valid token allowing to publish to the registry https://registry.npmjs.org/.

If you are using Two-Factor Authentication, make configure the auth-only level is supported. semantic-release cannot publish with the default auth-and-writes level.

Please make sure to set the NPM_TOKEN environment variable in your CI with the exact value of the npm token.


Good luck with your project ✨

Your semantic-release bot 📦🚀

The automated release is failing 🚨

🚨 The automated release from the master branch failed. 🚨

I recommend you give this issue a high priority, so other packages depending on you can benefit from your bug fixes and new features again.

You can find below the list of errors reported by semantic-release. Each one of them has to be resolved in order to automatically publish your package. I’m sure you can fix this 💪.

Errors are usually caused by a misconfiguration or an authentication problem. With each error reported below you will find explanation and guidance to help you to resolve it.

Once all the errors are resolved, semantic-release will release your package the next time you push a commit to the master branch. You can also manually restart the failed CI job that runs semantic-release.

If you are not sure how to resolve this, here are some links that can help you:

If those don’t help, or if this issue is reporting something you think isn’t right, you can always ask the humans behind semantic-release.


Invalid npm token.

The npm token configured in the NPM_TOKEN environment variable must be a valid token allowing to publish to the registry https://registry.npmjs.org/.

If you are using Two Factor Authentication for your account, set its level to "Authorization only" in your account settings. semantic-release cannot publish with the default "
Authorization and writes" level.

Please make sure to set the NPM_TOKEN environment variable in your CI with the exact value of the npm token.


Good luck with your project ✨

Your semantic-release bot 📦🚀

generated type guards can not be used when imported from index

With the -g flag, type guards are generated nicely. But they are exported as type in the index, which makes then not usable through the index:

export type { isTypeAsset, TypeAsset, TypeAssetFields } from "./TypeAsset";

When trying to use:

'isTypeAsset' cannot be used as a value because it was exported using 'export type'.ts(1362)

Support custom prefixes of generics and interfaces

We have a convention that generics should either be a single letter or start with two uppercase letters e.g. either T or TKey; I also know some teams have the convention of prefixing their interfaces with I.

It would be great if we could pass something like --prefix-generics=T and --prefix-interface=I to facilitate this

Generated types don't seem to match those expected by Contentful v10

Hello,

Thank you for this library.

I installed the latest version (2.12.9) and the latest version of Contentful (10.6.12). When I run the generator, I get the following result:

Screenshot 2023-11-23 at 20 49 56

Dropping Contentful down to a pre v10 version seems to work. The documentation however seems to suggest that v10 is supported, so not sure if I'm doing something wrong, or if I should use an earlier version for now?

Thank you in advance.

Missing imports with --v10 and --out

Thanks for your work to support v10!

When using --v10 and generating multiple output files, the files don't seem to be importing from each other.

Using a command line like cf-content-types-generator --v10 contentful-export.json --out generated-output will produce output like this:

import type { ChainModifiers, Entry, EntryFieldTypes, EntrySkeletonType, LocaleCode } from "contentful";

export interface TypeArticleGroupFields {
    title?: EntryFieldTypes.Symbol;
    articles?: EntryFieldTypes.Array<EntryFieldTypes.EntryLink<TypeArticleSkeleton>>;
}

(with a squiggle on the TypeArticleSkeleton type)

Here's a minimized contentful-export.json that reproduces the issue:

{
  "contentTypes": [
    {
      "sys": {
        "id": "article",
        "type": "ContentType"
      },
      "displayField": "title",
      "name": "Article",
      "description": "",
      "fields": [
        {
          "id": "title",
          "name": "Title",
          "type": "Symbol",
          "localized": true,
          "required": true,
          "validations": [
            {
              "unique": true
            }
          ],
          "disabled": false,
          "omitted": false
        },
        {
          "id": "introduction",
          "name": "Introduction",
          "type": "Text",
          "localized": true,
          "required": false,
          "validations": [],
          "disabled": false,
          "omitted": false
        }
      ]
    },
    {
      "sys": {
        "id": "articleGroup",
        "type": "ContentType"
      },
      "displayField": "title",
      "name": "ArticleGroup",
      "description": "",
      "fields": [
        {
          "id": "title",
          "name": "Title",
          "type": "Symbol",
          "localized": true,
          "required": false,
          "validations": [],
          "disabled": false,
          "omitted": false
        },
        {
          "id": "articles",
          "name": "Articles",
          "type": "Array",
          "localized": false,
          "required": false,
          "validations": [],
          "disabled": false,
          "omitted": false,
          "items": {
            "type": "Link",
            "validations": [
              {
                "linkContentType": ["article"]
              }
            ],
            "linkType": "Entry"
          }
        }
      ]
    }
  ],
  "locales": [
    {
      "name": "English",
      "code": "en",
      "fallbackCode": null,
      "default": true,
      "contentManagementApi": true,
      "contentDeliveryApi": true,
      "optional": false
    },
    {
      "name": "Spanish",
      "code": "es",
      "fallbackCode": null,
      "default": false,
      "contentManagementApi": true,
      "contentDeliveryApi": true,
      "optional": true
    }
  ]
}

A workaround for now is to avoid --out, and produce only a single file with e.g. cf-content-types-generator --v10 contentful-export.json >generated-output/contentful-types.ts.

Request for LICENSE file

First of all, thanks for giving us the first and only type generator to support v10 types!

But as such, some projects (including one where I'm currently) have such license restrictions that the provided license should appear in a LICENSE file or otherwise it's a no-go, even though this project seems to be licensed under MIT based on the package.json#license field.

We would highly appreciate if you can add LICENSE file, so we could proceed in using your library in our project. Thanks!

🐛 TypeError: Cannot read property 'length' of undefined

Hi there!

I'm working on a Contentful project at the moment and was looking for a way to generate some simple types :) This project seems super helpful, but I had an issue getting started in that any call would result in
TypeError: Cannot read property 'length' of undefined

The error is coming from unguarded checks on the length of the validations property in a few places in code. It seems like either a) the contentful specification has been updated since this code was written and validations is no longer strictly required, or b) our content model is a bit off :)

Either way it seems like it would be nice to guard against this check for other users! I have a change ready if you are open to PRs

~Hanna

Use with Contentful GraphQL endpoint?

Is this intended to be used to type responses from a Contentful GraphQL endpoint?

The generated types seem to expect that my data will have a structure like this:

SomeType {
   sys: {
      id
   }
   fields {
      someField
      someOtherField
   }
}

But the GraphQL endpoint returns data structured like this?

SomeType { 
   sys: {  
      id
   }
   someField
   someOtherField
}

Unable to use CLI

After npm installing the package, I'm unable to use the cli. I've restarted terminal and no luck.

command not found: cf-content-types-generator

Locale Support

I came across this tool and it's really nice. However, I'm a bit confused at the typing on the fields, because as far as I can see, this isn't going to work for anyone, unless we have some special config here.

All our fields from Contentful always have the format:

fields: {
  field_name: {
    [LOCALE]: data
  }
}

and not

fields: {
  field_name: data
}

as this library generates.

We have typings for the locales, if you want them.

Recursive types introduce import errors

We have a content type that references itself through a field. When generating the typescript types for this, an import is generated at the top of the file which imports itself. This leads to a TypeScript build error.

Minimal Example

Given the content type

{
  "sys": {
    "id": "category"
    ...
  },
  "name": "Category",
  "fields": [
    {
      "id": "ancestor",
      "name": "Parent Category",
      "type": "Link",
      "linkType": "Entry"
      "validations": [
        {
          "linkContentType": [
            "category"
          ],
          "message": "Has to be of type category!"
        }
      ],
      ...
    },
...

the type generator outputs (note the import in line 2)

import * as Contentful from "contentful";
import { TypeCategoryFields } from "./TypeCategory";

export interface TypeCategoryFields {
    ancestor?: Contentful.Entry<TypeCategoryFields>;
}

export type TypeCategory = Contentful.Entry<TypeCategoryFields>;

where it should be (without the import)

import * as Contentful from "contentful";

export interface TypeCategoryFields {
    ancestor?: Contentful.Entry<TypeCategoryFields>;
}

export type TypeCategory = Contentful.Entry<TypeCategoryFields>;

Property does not exist on type {} | {}

I've recently tried upgrading the contentful library to version 10.6.1.
As a result, it seems like the Entry type has been changed to the point that all newly-generated types have the property field as a {} | {}, meaning that I cannot access any of the fields properties without casting each field prop as the approproate field type.
Is this a known issue, do you perhaps have an ETA on when it's going to be fixed?

Thanks in advance.

p.s. I'm attaching a screenshot with the typecheck error for clarity.
image

TypeStoryField certainly has the title property as well as a few others but is inaccessible

image

And this is from the automatically generated type

CFContentType is incompatible with ContentType type exported by contentful-management

import fs from 'node:fs';

import contentfulManagement from 'contentful-management';
import CFDefinitionsBuilder from 'cf-content-types-generator/lib/cf-definitions-builder';

const client = contentfulManagement.createClient({
  accessToken: CONTENTFUL_MANAGEMENT_TOKEN,
});

console.log('Importing content types…');
const space = await client.getSpace(CONTENTFUL_SPACE_ID);
const environment = await space.getEnvironment(CONTENTFUL_ENVIRONMENT || 'master');
const { items: contentTypes } = await environment.getContentTypes();

console.log('Extracting types…');
const stringContent = new CFDefinitionsBuilder();
contentTypes.forEach((contentType) => {
  stringContent.appendType(contentType);
});
const content = stringContent.toString();

// Save to file
fs.writeFileSync('cf-content-types.d.ts', content, 'utf8');
error TS2345: Argument of type 'ContentType' is not assignable to parameter of type 'CFContentType'.
  Property 'id' is missing in type 'ContentType' but required in type 'CFContentType'.

48     stringContent.appendType(contentType);
                                ~~~~~~~~~~~

  ../../node_modules/cf-content-types-generator/lib/types.d.ts:5:5
    5     id: string;
          ~~
    'id' is declared here.

Dev-only code pollutes production builds and causes warnings when installed using Yarn

Binary has this bit of code:

const dev = fs.existsSync(project);

if (dev) {
    // eslint-disable-next-line node/no-unpublished-require
    require('ts-node').register({project});
}

which does not get stripped out from production build.

This causes ts-node to be installed alongside cf-content-types-generator, despite not being used at all in production

This, in turn, causes warnings when installed using Yarn:

➤ YN0000: ┌ Resolution step
➤ YN0002: │ cf-content-types-generator@npm:2.2.3 doesn't provide @types/node (pcdbc9), requested by ts-node
➤ YN0002: │ cf-content-types-generator@npm:2.2.3 doesn't provide typescript (pfffe7), requested by ts-node
➤ YN0000: │ Some peer dependencies are incorrectly met; run yarn explain peer-requirements <hash> for details, where <hash> is the six-letter p-prefixed code
➤ YN0000: └ Completed

Recommendations:

  • Move ts-node to devDependencies
  • Strip out any dev-only code from production builds

Rendering of link arrays incorrect

https://github.com/contentful-labs/cf-content-types-generator/blob/master/src/renderer/cf-render-prop-array.ts#L13

Should be something more like this.

  return `(${renderPropLink(field.items)})[]`;

We've fixed it in our library fork but due to numerous other customisation in our fork it's not so easy to just generate a fix PR.

Before: pages?: EntryLink<PageCMSEntry> | EntryLink<ComponentCardCMSEntry>[];
After: pages?: (EntryLink<PageCMSEntry> | EntryLink<ComponentCardCMSEntry>)[];

How to correctly format CreateEntryProps with Link<Entry>

How can we leverage this Type definition to construct Entry Fields object?

Simplified Example:

export interface TypeMediaFields {
    type: "Audio" | "Video" | "Photo" ;
    homeArticle?: Contentful.Entry<TypeArticle>;
}

export type TypeMedia = Contentful.Entry<TypeMediaFields>;

export interface TypeArticleFields {
  articleKey?: Contentful.EntryFields.Symbol;
  type: 'Encyclopedia' | 'Special Report';
}
async function formatCreateMediaEntryFields(item: ExistDbMediaRecord): Promise<Partial<TypeMediaFields>> {
return {
    homeArticle: formatEntryLink(await resolveEntryIdByLegacyKey(item.homeArticleKey, CONTENT_TYPES.ARTICLE)),
    slugline: item.slugline,
  }  as TypeMediaFields;
}


function formatEntryLink(entryId: string): Link<'Entry'> {
  return {
    sys: {
      type: 'Link',
      linkType: 'Entry',
      id: entryId,
    },
  };
}

Typescript is giving the following message:

Conversion of type '{ homeArticle: Link<"Entry">; slugline: string; }' to type 'TypeMediaFields' may be a mistake because neither type sufficiently overlaps with the other. If this was intentional, convert the expression to 'unknown' first.   Property 'type' is missing in type '{ homeArticle: Link<"Entry">; slugline: string; }' but required in type 'TypeMediaFields'.

Why should I need to cast to unknown first?

Am I missing something here?

Command hangs after generating the export

Hello! I have been using this package for a bit now, and it works great :) however, I have been getting the following issue every so often.

I run the command (cf-content-types-generator -s ${spaceId} -t ${accessToken} -e ${environmentId} --v10 -o ./src/contentfulTypes (with the keys redacted) and it hands up after the types are generated:

image

It doesn't seem to do anything after this. But then sometimes it passes right away, less than a minute.
This happens both locally and in CI.

Has anybody ran into this before? My first thought is, we are getting rate limited, but there is no way to tell with the output.

Thanks!

TypeScript error: Generated type does not satisfy the constraint 'EntrySkeletonType'

Hi, I'm trying to use this for a Contentful-based project but the generated types have a TypeScript error.

I'm generating the types using the CLI:

cf-content-types-generator --spaceId $CONTENTFUL_SPACE_ID --token $CONTENTFUL_MANAGEMENT_TOKEN -o src/contentful-types

Which comes out with the following file:

import type { Asset, Entry, EntryFields } from "contentful";

export interface TypeHomePageFields {
    heroLogo: Asset;
    heroTitle: EntryFields.Symbol;
    heroDescription: EntryFields.RichText;
    descriptionText: EntryFields.RichText;
    descriptionImage?: Asset;
}

export type TypeHomePage = Entry<TypeHomePageFields>;

And this error:

Type 'TypeHomePageFields' does not satisfy the constraint 'EntrySkeletonType'.
  Type 'TypeHomePageFields' is missing the following properties from type 'EntrySkeletonType': fields, contentTypeIdts(2344)

I'm using [email protected] and [email protected].

Include description and help text in JSDoc comments?

Thank you for a very useful library! Would you consider adding support for including content type descriptions and field help texts in the JSDoc comments generated when using the --jsdoc option. For example:

/**
 * Article page.
 * @name Article
 * @type {TypeArticleFields}
 * @memberof TypeArticle
 */
export interface TypeArticleFields {
  /**
   * Page title, shown at the top of the browser window and in search results.
   * @name Title
   * @localized false
   */
  title: EntryFieldTypes.Symbol
}

I think this would be more useful than the current implementation:

/**
 * Fields type definition for content type 'TypeArticle'
 * @name Article
 * @type {TypeArticleFields}
 * @memberof TypeArticle
 */
export interface TypeArticleFields {
  /**
   * Field type definition for field 'title' (Title)
   * @name Title
   * @localized false
   */
  title: EntryFieldTypes.Symbol
}

How to actually use fields?

Hi all,

I know it's a dummy question, but I still need some help.

So I created a custom generic useContentful hook in React that returns the fields property of a ContentfulCollection.

Looks something like this:

const useContentful = <T extends EntrySkeletonType>() => {
...
return {fields}
}

This object however contains optional values like

heroContent?: EntryFieldTypes.Text;

How do I use them inside an actual component without the error

Type 'string | { [x: string]: string | undefined; } | undefined' is not assignable to type 'ReactNode'.
Type '{ [x: string]: string | undefined; }' is not assignable to type 'ReactNode'.
Type '{ [x: string]: string | undefined; }' is missing the following properties from type 'ReactPortal': key, children, type, propsts(2322)

Thank you in advance

`import * as Contentful from "contentful";` produces error

This import is never used as a value and must use 'import type' because 'importsNotUsedAsValues' is set to 'error'.ts(1371)

In the generated files it should import contentful only as a type because if 'importsNotUsedAsValues' is set to error then it produces an error.

Should be: import type * as Contentful from "contentful";

Generated field interface does not satisfy the constraint 'EntrySkeletonType'

I've generated field interface from the Contentful json export:

import type { Asset, Entry, EntryFields } from "contentful";

export interface TypeAuthorFields {
    firstName?: EntryFields.Symbol;
    lastName?: EntryFields.Symbol;
    img?: Asset;
    bornPlace?: EntryFields.Symbol;
    diedPlace?: EntryFields.Symbol;
    nationality?: EntryFields.Symbol;
    bornDate?: EntryFields.Symbol;
    diedDate?: EntryFields.Symbol;
    slug?: EntryFields.Symbol;
}

export type TypeAuthor = Entry<TypeAuthorFields>;

but TypeAuthorFields throws me an error in the last line:

Type 'TypeAuthorFields' does not satisfy the constraint 'EntrySkeletonType'.
Type 'TypeAuthorFields' is missing the following properties from type 'EntrySkeletonType': fields, contentTypeId

Fields not typed correctly

Hello, I'm currently in the process of migrating a project to TypeScript, and have encountered some problems with nested linked content.

When formatting the data received from Contentful I map over the results and do some serialization of the data. But sometimes (I haven't figured out when) I don't get correct typings for the fields of a linked object.

In the following screenshot I've added prints of the types of different variables using the Two Slash Queries plugin.

  1. I get an array of ApiReferenceSubsection into my function
  2. I loop over them with a map, and the subsection is indeed typed correctly
  3. I extract the table property from the fields of that subsection, and get the correct typing
  4. But suddenly, when I try to access the fields of the table, I get a very generic type ([x: string]: string | number | boolean | JsonObject | JsonArray | Document | (string | Entry<EntrySkeletonType, "WITHOUT_UNRESOLVABLE_LINKS", string> | Asset<...> | undefined)[] | ... 4 more ... | undefined;)

CleanShot 2023-10-31 at 09 59 07

I'm using contentful 10.6.5, and cf-content-types-generator 2.12.9.

I'm generating the types with cf-content-types-generator -g -s $CONTENTFUL_SPACE_ID -t $CONTENTFUL_MANAGEMENT_API_KEY -e $CONTENTFUL_ENV -X -o ./types/generated/contentful

The generated files for subsection and table are as follows:

import type { ChainModifiers, Entry, EntryFieldTypes, EntrySkeletonType, LocaleCode } from "contentful";
import type { TypeApiObjectPropertySkeleton } from "./TypeApiObjectProperty";
import type { TypeTableSkeleton } from "./TypeTable";

export interface TypeApiReferenceSubsectionFields {
    heading?: EntryFieldTypes.Symbol;
    text?: EntryFieldTypes.RichText;
    properties?: EntryFieldTypes.Array<EntryFieldTypes.EntryLink<TypeApiObjectPropertySkeleton>>;
    table?: EntryFieldTypes.EntryLink<TypeTableSkeleton>;
}

export type TypeApiReferenceSubsectionSkeleton = EntrySkeletonType<TypeApiReferenceSubsectionFields, "apiReferenceSubsection">;
export type TypeApiReferenceSubsection<Modifiers extends ChainModifiers, Locales extends LocaleCode> = Entry<TypeApiReferenceSubsectionSkeleton, Modifiers, Locales>;

export function isTypeApiReferenceSubsection<Modifiers extends ChainModifiers, Locales extends LocaleCode>(entry: Entry<EntrySkeletonType, Modifiers, Locales>): entry is TypeApiReferenceSubsection<Modifiers, Locales> {
    return entry.sys.contentType.sys.id === 'apiReferenceSubsection'
}
import type { ChainModifiers, Entry, EntryFieldTypes, EntrySkeletonType, LocaleCode } from "contentful";

export interface TypeTableFields {
    title: EntryFieldTypes.Symbol;
    data?: EntryFieldTypes.Object;
}

export type TypeTableSkeleton = EntrySkeletonType<TypeTableFields, "table">;
export type TypeTable<Modifiers extends ChainModifiers, Locales extends LocaleCode> = Entry<TypeTableSkeleton, Modifiers, Locales>;

export function isTypeTable<Modifiers extends ChainModifiers, Locales extends LocaleCode>(entry: Entry<EntrySkeletonType, Modifiers, Locales>): entry is TypeTable<Modifiers, Locales> {
    return entry.sys.contentType.sys.id === 'table'
}

Generated TypeScript Models Lack File Extensions in Import Statements When Using Node 16 Module Resolution

Hello,

first, thanks for this library and the efforts to maintain it!

I've encountered an issue using it in a TypeScript project with Node 16 and moduleResolution set to node16 (or nodenext) in the tsconfig.json.

When the TypeScript models are generated, the import statements in the generated files lack the .js extension for relative file paths. This is problematic because Node 16 requires explicit file extensions in ES module imports: https://nodejs.org/api/esm.html#mandatory-file-extensions

Example Error:

models/contentful-schemes/TypeDiscoverLandingPage.ts:3:48 - error TS2835: Relative import paths need explicit file extensions in EcmaScript imports when '--moduleResolution' is 'node16' or 'nodenext'. Did you mean './TypeBrandCarousel.js'?

Incorrect Import Statement:

export { isTypeArticleCarousel } from "./TypeArticleCarousel";

Expected Import Statement:

export { isTypeArticleCarousel } from "./TypeArticleCarousel.js";

tsconfig.json Configuration:

{
    "module": "Node16",
    "moduleResolution": "node16"
}

Questions and Offer to Contribute:

  • Might this be a configurational problem on my end? Unfortunately, I am not able to change module or moduleResolution in my project, but maybe I missed a flag in the library to configure the module compatibility?
  • Is this a known issue? If so, is there a planned fix?
  • I'd like to contribute a fix for this issue. For that, could you guide me to the part of the codebase where the import statements are generated?

Thank you!

Release a new version with updated contentful and allow minor version differences if possible

Contentful up to version 10.3.7 has the following vulnurability: Axios Cross-Site Request Forgery Vulnerability - GHSA-wf5p-g6vw-rhxx

I can see a patch was committed here. Can you please release a new version of this library with the fix?

This wouldn't be necessary, if the dependency wasn't pinned to a specific version. Please consider allowing minor or at least patch version differences (i.e. ^10.6.1 or ~10.6.1). This way we can run npm audit fix and a new release is not needed.

Property 'fields' does not exist on type 'EntryLink'

Hello!

I was trying to migrate from contentful-typescript-codegen to this library since it supports v10 of contentful's sdk and I have come across the following issue:

const siteSettingsA: TypeSiteSettings<null, null>;
siteSettingsA?.fields?.mainNavigation?.fields?.navigationItems;
Property 'fields' does not exist on type 'Entry<TypeNavigationSkeleton, null, null> | { sys: Link<"Entry">; }'.
Property 'fields' does not exist on type '{ sys: Link<"Entry">; }'.ts(2339)
// TypeSiteSettings.ts
export interface TypeSiteSettingsFields {
    internalName: EntryFieldTypes.Symbol;
    seoMetadata: EntryFieldTypes.EntryLink<TypeSeoMetadataSkeleton>;
    footer: EntryFieldTypes.EntryLink<TypeFooterSkeleton>;
    mainNavigation: EntryFieldTypes.EntryLink<TypeNavigationSkeleton>;
    uspBanner?: EntryFieldTypes.EntryLink<TypeModuleUspBannerSkeleton>;
    policiesAgreementTerms?: EntryFieldTypes.RichText;
    offerToLogIn?: EntryFieldTypes.RichText;
    offerToCreateAnAccount?: EntryFieldTypes.RichText;
    wishlistAuthorizationInvitation?: EntryFieldTypes.RichText;
    profileLinkCollection?: EntryFieldTypes.EntryLink<TypeLinksCollectionSkeleton>;
}

export type TypeSiteSettingsSkeleton = EntrySkeletonType<TypeSiteSettingsFields, "siteSettings">;
export type TypeSiteSettings<Modifiers extends ChainModifiers, Locales extends LocaleCode> = Entry<TypeSiteSettingsSkeleton, Modifiers, Locales>;

mainNavigation is a link entry and I'm having this same issue for all the other link entries inside another entries. With the other library I was able to reference as many levels of links as there were in the entry. I'm also adding a video so you can properly see the comparison between both libraries.

Screen.Recording.2023-05-08.at.10.53.58.mov
  • TypeSettings types generated by cf-content-types-generator library
  • ISiteSettingstypes generated by contentful-typescript-codegen library

Is there any possibility to fix this type problem without having to use type casting? i.e. :

(siteSettingsA?.fields?.mainNavigation as TypeNavigation<null, null>)?.fields?.navigationItems

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.