@oak-digital/types-4-strapi-2 0.2.10 → 0.3.1

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
@@ -57,11 +57,54 @@ This can be done with the `--out` flag like in the following example.
57
57
  |-----------------------------|--------------------------------------------------------------------------------------|-------------|
58
58
  | -i, --in <dir> | The src directory for strapi | `./src` |
59
59
  | -o, --out <dir> | The output directory to output the types to | `./types` |
60
- | -prefix | A prefix for all generated interfaces | `I` |
60
+ | --prefix <prefix> | A prefix for all generated interfaces | `I` |
61
61
  | --component-prefix <prefix> | A prefix for components | none |
62
62
  | -D, --delete-old | CAUTION: This option is equivalent to running `rm -rf` on the output directory first | `false` |
63
63
  | --prettier <file> | The prettier config file to use for formatting TypeScript interfaces | none |
64
64
 
65
+ ## Tips and tricks
66
+
67
+ ### Generate interfaces as soon as you create/modify/delete new components or content types
68
+
69
+ You can make an extension for your strapi project to generate the new typescript interfaces as soon as they are created with strapi.
70
+ 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`.
71
+ An example of how this can be done is shown in the following snippet.
72
+
73
+ ```typescript
74
+ // src/extensions/content-type-builder/strapi-server.ts
75
+ import { exec } from "child_process";
76
+
77
+ export default (plugin: any) => {
78
+ const componentRunAfter = [
79
+ "createComponent",
80
+ "deleteComponent",
81
+ "updateComponent",
82
+ ];
83
+ const contentTypesRunAfter = [
84
+ "createContentType",
85
+ "updateContentType",
86
+ "deleteContentType",
87
+ ];
88
+ componentRunAfter.forEach((name) => {
89
+ const oldFunc = plugin.controllers.components[name];
90
+ plugin.controllers.components[name] = async (ctx: any) => {
91
+ await oldFunc(ctx);
92
+ exec("npm run types");
93
+ return ctx
94
+ }
95
+ })
96
+ contentTypesRunAfter.forEach((name) => {
97
+ const oldFunc = plugin.controllers['content-types'][name];
98
+ plugin.controllers["content-types"][name] = async (ctx: any) => {
99
+ await oldFunc(ctx);
100
+ exec("npm run types");
101
+ return ctx
102
+ }
103
+ })
104
+ return plugin;
105
+ }
106
+ ```
107
+
65
108
  ## Building
66
109
 
67
110
  To build this project, use the following command
@@ -39,6 +39,9 @@ var Attributes = /** @class */ (function () {
39
39
  case 'media':
40
40
  dependencyNames.push('builtins::Media');
41
41
  break;
42
+ case 'dynamiczone':
43
+ dependencyNames.push.apply(dependencyNames, attr.components);
44
+ break;
42
45
  default:
43
46
  continue;
44
47
  }
@@ -55,8 +58,11 @@ var Attributes = /** @class */ (function () {
55
58
  return dependencies;
56
59
  };
57
60
  Attributes.prototype.attributeToString = function (attrName, attr) {
61
+ var _this = this;
58
62
  var _a, _b, _c, _d;
59
63
  var optionalString = this.isAttributeOptional(attr) ? '?' : '';
64
+ var orNull = ' | null';
65
+ var requiredString = attr.required !== true ? orNull : '';
60
66
  var str = " ".concat(attrName).concat(optionalString, ": ");
61
67
  var isArray = false;
62
68
  switch (attr.type) {
@@ -72,7 +78,7 @@ var Attributes = /** @class */ (function () {
72
78
  var apiName = attr.target;
73
79
  // console.log(this.RelationNames, apiName)
74
80
  var dependencyName = (_c = (_b = this.RelationNames[apiName]) === null || _b === void 0 ? void 0 : _b.name) !== null && _c !== void 0 ? _c : 'any';
75
- var relationMultipleString = attr.relation.endsWith('ToMany') ? '[]' : ' | null';
81
+ var relationMultipleString = attr.relation.endsWith('ToMany') ? '[]' : orNull;
76
82
  str += "{ data: ".concat(dependencyName).concat(relationMultipleString, "; }");
77
83
  break;
78
84
  case 'component':
@@ -83,8 +89,7 @@ var Attributes = /** @class */ (function () {
83
89
  str += dependencyComponentName;
84
90
  break;
85
91
  case 'media':
86
- var mediaOptional = attr.required !== true ? ' | null' : '';
87
- var mediaMultipleString = attr.multiple ? '[]' : mediaOptional;
92
+ var mediaMultipleString = attr.multiple ? '[]' : requiredString;
88
93
  str += "{ data: ".concat(this.RelationNames['builtins::Media'].name).concat(mediaMultipleString, "; }");
89
94
  break;
90
95
  case 'password':
@@ -96,26 +101,39 @@ var Attributes = /** @class */ (function () {
96
101
  var typeString = enums.join(' | ');
97
102
  str += typeString;
98
103
  break;
104
+ case 'dynamiczone':
105
+ // console.log(attr.components);
106
+ var relations = attr.components
107
+ .map(function (componentName) { return _this.RelationNames[componentName].name; });
108
+ // console.log(relations);
109
+ var relationsString = relations.join(' | ');
110
+ // console.log(relationsString);
111
+ str += "Array<".concat(relationsString, ">");
112
+ break;
99
113
  case 'string':
100
114
  case 'text':
101
115
  case 'richtext':
102
116
  case 'email':
103
117
  case 'uid':
104
118
  str += 'string';
119
+ str += requiredString;
105
120
  break;
106
121
  case 'integer':
107
122
  case 'biginteger':
108
123
  case 'decimal':
109
124
  case 'float':
110
125
  str += 'number';
126
+ str += requiredString;
111
127
  break;
112
128
  case 'date':
113
129
  case 'datetime':
114
130
  case 'time':
115
131
  str += 'Date';
132
+ str += requiredString;
116
133
  break;
117
134
  case 'boolean':
118
135
  str += attr.type;
136
+ str += requiredString;
119
137
  break;
120
138
  case 'json':
121
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 = {};
@@ -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();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@oak-digital/types-4-strapi-2",
3
- "version": "0.2.10",
3
+ "version": "0.3.1",
4
4
  "description": "Typescript interface generator for Strapi 4 models",
5
5
  "bin": {
6
6
  "t4s": "./bin/index.js"