@oak-digital/types-4-strapi-2 0.3.0 → 0.3.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -5,6 +5,10 @@ This can be useful if you have a frontend written with TypeScript to make sure y
5
5
 
6
6
  types-4-strapi-2 is a rewrite of [francescolorenzetti/types-4-strapi](https://github.com/francescolorenzetti/types-4-strapi) written in TypeScript, with the goal of being much easier to extend and maintain.
7
7
 
8
+ ## Requirements
9
+
10
+ * Node `>=v16`
11
+
8
12
  ## Getting started
9
13
 
10
14
  Install the script for your project:
@@ -57,11 +61,54 @@ This can be done with the `--out` flag like in the following example.
57
61
  |-----------------------------|--------------------------------------------------------------------------------------|-------------|
58
62
  | -i, --in <dir> | The src directory for strapi | `./src` |
59
63
  | -o, --out <dir> | The output directory to output the types to | `./types` |
60
- | -prefix | A prefix for all generated interfaces | `I` |
64
+ | --prefix <prefix> | A prefix for all generated interfaces | `I` |
61
65
  | --component-prefix <prefix> | A prefix for components | none |
62
66
  | -D, --delete-old | CAUTION: This option is equivalent to running `rm -rf` on the output directory first | `false` |
63
67
  | --prettier <file> | The prettier config file to use for formatting TypeScript interfaces | none |
64
68
 
69
+ ## Tips and tricks
70
+
71
+ ### Generate interfaces as soon as you create/modify/delete new components or content types
72
+
73
+ You can make an extension for your strapi project to generate the new typescript interfaces as soon as they are created with strapi.
74
+ If you followed the step of adding a script to your `package.json`, you can easily make an extension that just calls `npm run types`.
75
+ An example of how this can be done is shown in the following snippet.
76
+
77
+ ```typescript
78
+ // src/extensions/content-type-builder/strapi-server.ts
79
+ import { exec } from "child_process";
80
+
81
+ export default (plugin: any) => {
82
+ const componentRunAfter = [
83
+ "createComponent",
84
+ "deleteComponent",
85
+ "updateComponent",
86
+ ];
87
+ const contentTypesRunAfter = [
88
+ "createContentType",
89
+ "updateContentType",
90
+ "deleteContentType",
91
+ ];
92
+ componentRunAfter.forEach((name) => {
93
+ const oldFunc = plugin.controllers.components[name];
94
+ plugin.controllers.components[name] = async (ctx: any) => {
95
+ await oldFunc(ctx);
96
+ exec("npm run types");
97
+ return ctx
98
+ }
99
+ })
100
+ contentTypesRunAfter.forEach((name) => {
101
+ const oldFunc = plugin.controllers['content-types'][name];
102
+ plugin.controllers["content-types"][name] = async (ctx: any) => {
103
+ await oldFunc(ctx);
104
+ exec("npm run types");
105
+ return ctx
106
+ }
107
+ })
108
+ return plugin;
109
+ }
110
+ ```
111
+
65
112
  ## Building
66
113
 
67
114
  To build this project, use the following command
@@ -61,6 +61,8 @@ var Attributes = /** @class */ (function () {
61
61
  var _this = this;
62
62
  var _a, _b, _c, _d;
63
63
  var optionalString = this.isAttributeOptional(attr) ? '?' : '';
64
+ var orNull = ' | null';
65
+ var requiredString = attr.required !== true ? orNull : '';
64
66
  var str = " ".concat(attrName).concat(optionalString, ": ");
65
67
  var isArray = false;
66
68
  switch (attr.type) {
@@ -76,7 +78,7 @@ var Attributes = /** @class */ (function () {
76
78
  var apiName = attr.target;
77
79
  // console.log(this.RelationNames, apiName)
78
80
  var dependencyName = (_c = (_b = this.RelationNames[apiName]) === null || _b === void 0 ? void 0 : _b.name) !== null && _c !== void 0 ? _c : 'any';
79
- var relationMultipleString = attr.relation.endsWith('ToMany') ? '[]' : ' | null';
81
+ var relationMultipleString = attr.relation.endsWith('ToMany') ? '[]' : orNull;
80
82
  str += "{ data: ".concat(dependencyName).concat(relationMultipleString, "; }");
81
83
  break;
82
84
  case 'component':
@@ -87,8 +89,7 @@ var Attributes = /** @class */ (function () {
87
89
  str += dependencyComponentName;
88
90
  break;
89
91
  case 'media':
90
- var mediaOptional = attr.required !== true ? ' | null' : '';
91
- var mediaMultipleString = attr.multiple ? '[]' : mediaOptional;
92
+ var mediaMultipleString = attr.multiple ? '[]' : requiredString;
92
93
  str += "{ data: ".concat(this.RelationNames['builtins::Media'].name).concat(mediaMultipleString, "; }");
93
94
  break;
94
95
  case 'password':
@@ -115,20 +116,24 @@ var Attributes = /** @class */ (function () {
115
116
  case 'email':
116
117
  case 'uid':
117
118
  str += 'string';
119
+ str += requiredString;
118
120
  break;
119
121
  case 'integer':
120
122
  case 'biginteger':
121
123
  case 'decimal':
122
124
  case 'float':
123
125
  str += 'number';
126
+ str += requiredString;
124
127
  break;
125
128
  case 'date':
126
129
  case 'datetime':
127
130
  case 'time':
128
131
  str += 'Date';
132
+ str += requiredString;
129
133
  break;
130
134
  case 'boolean':
131
135
  str += attr.type;
136
+ str += requiredString;
132
137
  break;
133
138
  case 'json':
134
139
  default:
@@ -10,7 +10,7 @@ var Attributes_1 = __importDefault(require("./Attributes"));
10
10
  var change_case_1 = require("change-case");
11
11
  var Interface = /** @class */ (function () {
12
12
  function Interface(baseName, attributes, relativeDirectoryPath, fileCaseType, prefix) {
13
- if (fileCaseType === void 0) { fileCaseType = "pascal"; }
13
+ if (fileCaseType === void 0) { fileCaseType = 'pascal'; }
14
14
  if (prefix === void 0) { prefix = ''; }
15
15
  this.Relations = []; // Components and relations
16
16
  this.RelationNames = {};
@@ -7,7 +7,7 @@ exports.createMediaFormatInterface = exports.createMediaInterface = void 0;
7
7
  var BuiltinComponentInterface_1 = __importDefault(require("./BuiltinComponentInterface"));
8
8
  var BuiltinInterface_1 = __importDefault(require("./BuiltinInterface"));
9
9
  function createMediaInterface(directory, caseTypeName, prefix) {
10
- var stringFields = [
10
+ var stringRequiredFields = [
11
11
  'name',
12
12
  'alternativeText',
13
13
  'caption',
@@ -15,14 +15,13 @@ function createMediaInterface(directory, caseTypeName, prefix) {
15
15
  'ext',
16
16
  'mime',
17
17
  'url',
18
- 'previewUrl',
19
18
  'provider',
20
19
  ];
21
- var numberFields = [
22
- 'width',
23
- 'height',
24
- 'size',
20
+ var stringFields = [
21
+ 'previewUrl',
22
+ 'provider_metadata',
25
23
  ];
24
+ var numberFields = ['width', 'height', 'size'];
26
25
  var mediaFormat = {
27
26
  type: 'component',
28
27
  repeatable: false,
@@ -41,11 +40,14 @@ function createMediaInterface(directory, caseTypeName, prefix) {
41
40
  },
42
41
  },
43
42
  };
43
+ stringRequiredFields.forEach(function (s) {
44
+ mediaAttrs[s] = { type: 'string', required: true };
45
+ });
44
46
  stringFields.forEach(function (s) {
45
47
  mediaAttrs[s] = { type: 'string' };
46
48
  });
47
49
  numberFields.forEach(function (s) {
48
- mediaAttrs[s] = { type: 'integer' };
50
+ mediaAttrs[s] = { type: 'integer', required: true };
49
51
  });
50
52
  // const dataAttrs = {
51
53
  // data: {
@@ -58,19 +60,8 @@ function createMediaInterface(directory, caseTypeName, prefix) {
58
60
  }
59
61
  exports.createMediaInterface = createMediaInterface;
60
62
  function createMediaFormatInterface(directory, caseTypeName, prefix) {
61
- var stringFields = [
62
- 'name',
63
- 'hash',
64
- 'ext',
65
- 'mime',
66
- 'path',
67
- 'url',
68
- ];
69
- var numberFields = [
70
- 'width',
71
- 'height',
72
- 'size',
73
- ];
63
+ var stringFields = ['name', 'hash', 'ext', 'mime', 'path', 'url'];
64
+ var numberFields = ['width', 'height', 'size'];
74
65
  var mediaAttrs = {};
75
66
  stringFields.forEach(function (s) {
76
67
  mediaAttrs[s] = { type: 'string' };
@@ -37,6 +37,7 @@ var __generator = (this && this.__generator) || function (thisArg, body) {
37
37
  };
38
38
  Object.defineProperty(exports, "__esModule", { value: true });
39
39
  exports.getApiSchemas = exports.getComponentSchemas = exports.getComponentCategoryFolders = exports.getApiFolders = exports.readSchema = void 0;
40
+ var node_fs_1 = require("node:fs");
40
41
  var promises_1 = require("node:fs/promises");
41
42
  var posix_1 = require("node:path/posix");
42
43
  var utils_1 = require("../utils");
@@ -83,6 +84,10 @@ function getComponentCategoryFolders(strapiSrcRoot) {
83
84
  switch (_a.label) {
84
85
  case 0:
85
86
  path = (0, posix_1.join)(strapiSrcRoot, 'components');
87
+ // If there exists no components, just fallback to an empty array.
88
+ if (!(0, node_fs_1.existsSync)(path)) {
89
+ return [2 /*return*/, []];
90
+ }
86
91
  return [4 /*yield*/, (0, utils_1.readDirFiltered)(path)];
87
92
  case 1:
88
93
  folders = _a.sent();
File without changes
File without changes
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@oak-digital/types-4-strapi-2",
3
- "version": "0.3.0",
3
+ "version": "0.3.2",
4
4
  "description": "Typescript interface generator for Strapi 4 models",
5
5
  "bin": {
6
6
  "t4s": "./bin/index.js"