Skip to content

digisquad-io/strapi-v4-types

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

11 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Strapi V4 - @strapi/types package proposal

This package is a proposal to be part of @strapi packages as @strapi/types

Goal

Typescript empower javscript with static code analysis, which leads us with more robust code. Even if strapi core is not written in Typescript we can expose the Developer API declaration (Plugins / ContentType / etc...)

Implements:

See also plugin example here: https://github.com/digisquad-io/strapi-plugin-typescript-template

How to test this feature _Tested on next.11_
  1. Create @strapi/types package:

    1. clone this repository
    2. run yarn install
    3. run yarn run build
    4. run yarn link
  2. Build strapi-plugin-typescript-template

    1. clone strapi-plugin-typescript-template repository
    2. run yarn install AND yarn link "@strapi/types"
    3. code the plugin in src/strapi-server.ts 😄
    4. run yarn run build
    5. run yarn link
  3. Test on next.11

    1. create strapi app
    2. run yarn install
    3. add "strapi-plugin-typescript-template": "latest"
    4. run yarn link "strapi-plugin-typescript-template" in your package.json
    5. update loadJsFile from @strapi/strapi (see diff below)
    6. yay your typescript plugin is loaded 😄

edit loadJsFile

A small hack is needed in @strapi/strapi/lib/core/app-configuration/load-config-file.js

const loadJsFile = file => {
  try {
    const jsModule = require(file);

    // call if function
    if (typeof jsModule === 'function') {
      return jsModule({ env });
    }

+    // use export.default from ESM or Typescript 
+    if (jsModule && typeof jsModule.default === 'function') {
+      return jsModule.default({ env });
+    } else if (jsModule && typeof jsModule.default === 'object') {
+      return jsModule.default
+    }

    return jsModule;
  } catch (error) {
    throw new Error(`Could not load js config file ${file}: ${error.message}`);
  }
};

Usage

see full example plugin here

// src/server/bootstrap.ts
import { 
  withStrapi,
} from '@strapi/types'

export function bootstrap() {
  return withStrapi(async (strapi) => {
    // withStrapi is an empty function, 
    // it's here only to decalre the type for us

    const entityService = strapi.service('entityService')
    
    const articles = await entityService.query("article").findMany({
      select: ["title", "description"],
      where: { title: "Hello World" },
      orderBy: { title: "DESC" },
      populate: { category: true },
    })
  })
}
// src/server/config.ts
import { 
  defineConfig,
} from '@strapi/types'

export interface CustomPluginOption {
  mode: 'default' | 'typescript'
}
export const config = defineConfig(() => ({
  default: ({ env }) => ({
    mode: env('STRAPI_PLUGIN_CONFIG_MODE', 'default')
  } as CustomPluginOption),
  validator: () => true,
}))
// src/server/contentType/restaurants.ts
import { 
  defineContentType,
} from '@strapi/types'

export const restaurants = defineContentType(() => ({
  schema: {
    kind: 'collectionType',
    collectionName: 'restaurants',
    info: {
      name: 'restaurant',
      singularName: 'restaurant',
      pluralName: 'restaurants',
      displayName: 'Restaurants',
    },
    options: {},
    attributes: {
      name: {
        type: "string"
      }
    }
  },
}))
// src/strapi-server.ts
import { 
  defineServerPlugin, 
} from '@strapi/types'
import { bootstrap } from './server/bootstrap'
import { config } from './server/bootstrap'
import { restaurants } from './server/contentType/restaurants'

export default defineServerPlugin((strapi) => ({
  bootstrap,
  config,
  contentTypes: {
    restaurants,
  }
})) 

About

Proposal to be part of @strapi packages as @strapi/types

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published