@oak-digital/types-4-strapi-2 0.1.2 → 0.2.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.
Files changed (41) hide show
  1. package/.editorconfig +9 -0
  2. package/.eslintrc.json +52 -0
  3. package/.prettierrc.json +7 -0
  4. package/README.md +67 -0
  5. package/lib/.prettierrc.json +7 -0
  6. package/lib/index.js +9 -4
  7. package/lib/interface/Attributes.d.ts +3 -3
  8. package/lib/interface/Attributes.js +34 -9
  9. package/lib/interface/BuiltinComponentInterface.d.ts +5 -0
  10. package/lib/interface/BuiltinComponentInterface.js +36 -0
  11. package/lib/interface/BuiltinInterface.d.ts +5 -0
  12. package/lib/interface/BuiltinInterface.js +33 -0
  13. package/lib/interface/ComponentInterface.d.ts +2 -1
  14. package/lib/interface/ComponentInterface.js +14 -3
  15. package/lib/interface/Interface.d.ts +4 -0
  16. package/lib/interface/Interface.js +4 -4
  17. package/lib/interface/InterfaceManager.d.ts +6 -0
  18. package/lib/interface/InterfaceManager.js +65 -15
  19. package/lib/interface/builtinInterfaces.d.ts +4 -0
  20. package/lib/interface/builtinInterfaces.js +73 -0
  21. package/lib/src/index.d.ts +1 -0
  22. package/lib/src/index.js +25 -0
  23. package/lib/src/interface/Attributes.d.ts +11 -0
  24. package/lib/src/interface/Attributes.js +148 -0
  25. package/lib/src/interface/BuiltinComponentInterface.d.ts +5 -0
  26. package/lib/src/interface/BuiltinComponentInterface.js +36 -0
  27. package/lib/src/interface/BuiltinInterface.d.ts +5 -0
  28. package/lib/src/interface/BuiltinInterface.js +33 -0
  29. package/lib/src/interface/ComponentInterface.d.ts +8 -0
  30. package/lib/src/interface/ComponentInterface.js +58 -0
  31. package/lib/src/interface/Interface.d.ts +31 -0
  32. package/lib/src/interface/Interface.js +112 -0
  33. package/lib/src/interface/InterfaceManager.d.ts +25 -0
  34. package/lib/src/interface/InterfaceManager.js +288 -0
  35. package/lib/src/interface/builtinInterfaces.d.ts +4 -0
  36. package/lib/src/interface/builtinInterfaces.js +81 -0
  37. package/lib/src/interface/schemaReader.d.ts +14 -0
  38. package/lib/src/interface/schemaReader.js +172 -0
  39. package/lib/src/utils/index.d.ts +3 -0
  40. package/lib/src/utils/index.js +67 -0
  41. package/package.json +8 -2
package/.editorconfig ADDED
@@ -0,0 +1,9 @@
1
+ root = true
2
+
3
+ # Unix-style newlines with a newline ending every file
4
+ [*]
5
+ end_of_line = lf
6
+ insert_final_newline = true
7
+ indent_style = space
8
+ indent_size = 4
9
+ trim_trailing_whitespace = true
package/.eslintrc.json ADDED
@@ -0,0 +1,52 @@
1
+ {
2
+ "env": {
3
+ "es2021": true,
4
+ "node": true
5
+ },
6
+ "extends": [
7
+ "eslint:recommended",
8
+ "plugin:@typescript-eslint/recommended"
9
+ ],
10
+ "overrides": [
11
+ ],
12
+ "parser": "@typescript-eslint/parser",
13
+ "parserOptions": {
14
+ "ecmaVersion": "latest",
15
+ "sourceType": "module"
16
+ },
17
+ "plugins": [
18
+ "@typescript-eslint"
19
+ ],
20
+ "rules": {
21
+ "@typescript-eslint/no-explicit-any": "off",
22
+ "no-case-declarations": "off",
23
+ "@typescript-eslint/no-unused-vars": "off",
24
+ "default-case-last": ["error"],
25
+ "eqeqeq": ["error", "always"],
26
+ "no-lonely-if": ["error"],
27
+ "no-magic-numbers": ["warn", {
28
+ "ignoreArrayIndexes": true,
29
+ "ignore": [-1, 0, 1]
30
+ }],
31
+ "no-return-assign": ["error", "always"],
32
+ "no-return-await": ["error"],
33
+ "no-var": ["error"],
34
+ "no-cond-assign": ["error", "always"],
35
+ "indent": [
36
+ "error",
37
+ 4
38
+ ],
39
+ "linebreak-style": [
40
+ "error",
41
+ "unix"
42
+ ],
43
+ "quotes": [
44
+ "error",
45
+ "single"
46
+ ],
47
+ "semi": [
48
+ "error",
49
+ "always"
50
+ ]
51
+ }
52
+ }
@@ -0,0 +1,7 @@
1
+ {
2
+ "parser": "typescript",
3
+ "semi": true,
4
+ "singleQuote": true,
5
+ "bracketSameLine": false,
6
+ "trailingComma": "es5"
7
+ }
package/README.md ADDED
@@ -0,0 +1,67 @@
1
+ # types-4-strapi-2
2
+
3
+ types-4-strapi-2 is a typescript program that will generate typescript types for your strapi projects.
4
+ This can be useful if you have a frontend written with typescript to make sure you are using the correct types and can help report errors at compile time.
5
+
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
+
8
+ ## Getting started
9
+
10
+ Install the script for your project:
11
+
12
+ ```bash
13
+ npm install --save-dev @oak-digital/types-4-strapi-2
14
+ ```
15
+
16
+ Then set up a script in your `package.json`
17
+
18
+ ```jsonc
19
+ // package.json
20
+ {
21
+ "scripts": {
22
+ "types": "t4s"
23
+ }
24
+ }
25
+ ```
26
+
27
+ In some cases it is desirable to change the output directory which is `./types` by default.
28
+ This can be done with the `--out` flag like in the following example.
29
+
30
+ ```jsonc
31
+ // package.json
32
+ {
33
+ "scripts": {
34
+ "types": "t4s --out ../frontend/src/lib/types"
35
+ }
36
+ }
37
+ ```
38
+
39
+ ## Features
40
+
41
+ * Generate typescript interfaces for all your api content-types and components
42
+ * Generate typescript interfaces for builtin types such as `Media` and `MediaFormat`
43
+ * Select input and output directory
44
+ * Prettier formatting and ability to use your own `.prettierrc`.
45
+
46
+ ### Planned features
47
+
48
+ * Support if you are using other plugins, such as `url-alias`, which should add extra fields for some interfaces.
49
+
50
+ ## Help
51
+
52
+ use `t4s --help` to display which options are available for you
53
+
54
+ ## Building
55
+
56
+ To build this project, use the following command
57
+
58
+ ```bash
59
+ npm run build
60
+ ```
61
+
62
+ ## Publihsing
63
+
64
+ ```bash
65
+ npm run build
66
+ npm publish
67
+ ```
@@ -0,0 +1,7 @@
1
+ {
2
+ "parser": "typescript",
3
+ "semi": true,
4
+ "singleQuote": true,
5
+ "bracketSameLine": false,
6
+ "trailingComma": "es5"
7
+ }
package/lib/index.js CHANGED
@@ -6,14 +6,19 @@ Object.defineProperty(exports, "__esModule", { value: true });
6
6
  var commander_1 = require("commander");
7
7
  var InterfaceManager_1 = __importDefault(require("./interface/InterfaceManager"));
8
8
  commander_1.program
9
- .name("t4s");
9
+ .name('t4s');
10
10
  commander_1.program
11
11
  .option('-i, --in <dir>', 'The src directory for strapi', './src')
12
- .option('-o, --out <dir>', 'The output directory to output the types to', './types');
12
+ .option('-o, --out <dir>', 'The output directory to output the types to', './types')
13
+ .option('--component-prefix <prefix>', 'A prefix for components', '')
14
+ .option('--prettier <file>', 'The prettier config file to use for formatting typescript interfaces');
13
15
  commander_1.program.parse();
14
16
  var options = commander_1.program.opts();
15
- var input = options.in, out = options.out;
16
- var manager = new InterfaceManager_1.default(out, input);
17
+ var input = options.in, out = options.out, componentPrefix = options.componentPrefix, prettierFile = options.prettier;
18
+ var manager = new InterfaceManager_1.default(out, input, {
19
+ componentPrefix: componentPrefix,
20
+ prettierFile: prettierFile,
21
+ });
17
22
  manager.run().catch(function (err) {
18
23
  console.error(err);
19
24
  });
@@ -1,10 +1,10 @@
1
- import Interface from "./Interface";
1
+ import { RelationNames } from "./Interface";
2
2
  export default class Attributes {
3
3
  Attrs: Record<string, Record<string, any>>;
4
4
  private RelationNames;
5
- constructor(attr: Record<string, Record<string, any>>, relationNames: Record<string, [string, Interface]>);
5
+ constructor(attr: Record<string, Record<string, any>>, relationNames: RelationNames);
6
6
  isAttributeOptional(attr: any): boolean;
7
- getDependencies(strapiName: string): any[];
7
+ getDependencies(): any[];
8
8
  attributeToString(attrName: string, attr: any): string;
9
9
  toFieldsString(): string;
10
10
  toString(): string;
@@ -9,6 +9,8 @@ var Attributes = /** @class */ (function () {
9
9
  Attributes.prototype.isAttributeOptional = function (attr) {
10
10
  // If it is a component / relation / dynamiczone it is always optional due to population
11
11
  switch (attr.type) {
12
+ case "nested":
13
+ return attr.nullable === true;
12
14
  case "component":
13
15
  case "dynamiczone":
14
16
  case "relation":
@@ -18,17 +20,24 @@ var Attributes = /** @class */ (function () {
18
20
  }
19
21
  return false;
20
22
  };
21
- Attributes.prototype.getDependencies = function (strapiName) {
23
+ Attributes.prototype.getDependencies = function () {
22
24
  var dependencies = [];
23
25
  for (var attrName in this.Attrs) {
24
26
  var attr = this.Attrs[attrName];
25
- var dependencyName = void 0;
27
+ var dependencyNames = [];
26
28
  switch (attr.type) {
29
+ case "nested":
30
+ var attrs = new Attributes(attr.fields, this.RelationNames);
31
+ dependencyNames.push.apply(dependencyNames, attrs.getDependencies());
32
+ break;
27
33
  case "relation":
28
- dependencyName = attr.target;
34
+ dependencyNames.push(attr.target);
29
35
  break;
30
36
  case "component":
31
- dependencyName = attr.component;
37
+ dependencyNames.push(attr.component);
38
+ break;
39
+ case "media":
40
+ dependencyNames.push("builtins::Media");
32
41
  break;
33
42
  default:
34
43
  continue;
@@ -37,30 +46,46 @@ var Attributes = /** @class */ (function () {
37
46
  // if (dependencyName === strapiName) {
38
47
  // continue;
39
48
  // }
40
- dependencies.push(dependencyName);
49
+ dependencyNames.forEach(function (dependencyName) {
50
+ if (!dependencies.includes(dependencyName)) {
51
+ dependencies.push(dependencyName);
52
+ }
53
+ });
41
54
  }
42
55
  return dependencies;
43
56
  };
44
57
  Attributes.prototype.attributeToString = function (attrName, attr) {
45
- var _a;
58
+ var _a, _b;
46
59
  var optionalString = this.isAttributeOptional(attr) ? '?' : '';
47
60
  var str = " ".concat(attrName).concat(optionalString, ": ");
48
61
  var isArray = false;
49
62
  switch (attr.type) {
63
+ // types-4-strapi-2 specific, used for builtin types
64
+ case "nested":
65
+ // Be careful with recursion
66
+ // console.log(attr);
67
+ var newAttrs = new Attributes(attr.fields, this.RelationNames);
68
+ str += newAttrs.toString();
69
+ break;
50
70
  case "relation":
51
71
  var apiName = attr.target;
52
- // console.log(attrName)
53
72
  // console.log(this.RelationNames, apiName)
54
- var dependencyName = this.RelationNames[apiName][0];
73
+ var dependencyName = this.RelationNames[apiName].name;
55
74
  isArray = attr.relation.endsWith("ToMany");
56
75
  str += dependencyName;
57
76
  break;
58
77
  case "component":
59
78
  var componentName = attr.component;
60
- var dependencyComponentName = this.RelationNames[componentName][0];
79
+ var relationNameObj = this.RelationNames[componentName];
80
+ var dependencyComponentName = relationNameObj.name;
61
81
  isArray = (_a = attr.repeatable) !== null && _a !== void 0 ? _a : false;
62
82
  str += dependencyComponentName;
63
83
  break;
84
+ case "media":
85
+ var mediaOptional = attr.required !== true ? "?" : "";
86
+ str += "{ data".concat(mediaOptional, ": ").concat(this.RelationNames["builtins::Media"].name, "; }");
87
+ isArray = (_b = attr.multiple) !== null && _b !== void 0 ? _b : false;
88
+ break;
64
89
  case "password":
65
90
  return null;
66
91
  case "enumeration":
@@ -0,0 +1,5 @@
1
+ import ComponentInterface from "./ComponentInterface";
2
+ export default class BuiltinComponentInterface extends ComponentInterface {
3
+ constructor(baseName: string, attributes: any, relativeDirectoryPath: string, prefix?: string);
4
+ updateStrapiName(): void;
5
+ }
@@ -0,0 +1,36 @@
1
+ "use strict";
2
+ var __extends = (this && this.__extends) || (function () {
3
+ var extendStatics = function (d, b) {
4
+ extendStatics = Object.setPrototypeOf ||
5
+ ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
6
+ function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
7
+ return extendStatics(d, b);
8
+ };
9
+ return function (d, b) {
10
+ if (typeof b !== "function" && b !== null)
11
+ throw new TypeError("Class extends value " + String(b) + " is not a constructor or null");
12
+ extendStatics(d, b);
13
+ function __() { this.constructor = d; }
14
+ d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
15
+ };
16
+ })();
17
+ var __importDefault = (this && this.__importDefault) || function (mod) {
18
+ return (mod && mod.__esModule) ? mod : { "default": mod };
19
+ };
20
+ Object.defineProperty(exports, "__esModule", { value: true });
21
+ var ComponentInterface_1 = __importDefault(require("./ComponentInterface"));
22
+ var BuiltinComponentInterface = /** @class */ (function (_super) {
23
+ __extends(BuiltinComponentInterface, _super);
24
+ function BuiltinComponentInterface(baseName, attributes, relativeDirectoryPath, prefix) {
25
+ if (prefix === void 0) { prefix = ""; }
26
+ return _super.call(this, baseName, attributes, relativeDirectoryPath, "builtins", prefix, {
27
+ hasId: false,
28
+ hasComponent: false,
29
+ }) || this;
30
+ }
31
+ BuiltinComponentInterface.prototype.updateStrapiName = function () {
32
+ this.StrapiName = "builtins::".concat(this.BaseName);
33
+ };
34
+ return BuiltinComponentInterface;
35
+ }(ComponentInterface_1.default));
36
+ exports.default = BuiltinComponentInterface;
@@ -0,0 +1,5 @@
1
+ import Interface from "./Interface";
2
+ export default class BuiltinInterface extends Interface {
3
+ constructor(baseName: string, attributes: any, relativeDirectoryPath: string, prefix?: string);
4
+ updateStrapiName(): void;
5
+ }
@@ -0,0 +1,33 @@
1
+ "use strict";
2
+ var __extends = (this && this.__extends) || (function () {
3
+ var extendStatics = function (d, b) {
4
+ extendStatics = Object.setPrototypeOf ||
5
+ ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
6
+ function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
7
+ return extendStatics(d, b);
8
+ };
9
+ return function (d, b) {
10
+ if (typeof b !== "function" && b !== null)
11
+ throw new TypeError("Class extends value " + String(b) + " is not a constructor or null");
12
+ extendStatics(d, b);
13
+ function __() { this.constructor = d; }
14
+ d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
15
+ };
16
+ })();
17
+ var __importDefault = (this && this.__importDefault) || function (mod) {
18
+ return (mod && mod.__esModule) ? mod : { "default": mod };
19
+ };
20
+ Object.defineProperty(exports, "__esModule", { value: true });
21
+ var Interface_1 = __importDefault(require("./Interface"));
22
+ var BuiltinInterface = /** @class */ (function (_super) {
23
+ __extends(BuiltinInterface, _super);
24
+ function BuiltinInterface(baseName, attributes, relativeDirectoryPath, prefix) {
25
+ if (prefix === void 0) { prefix = ""; }
26
+ return _super.call(this, baseName, attributes, relativeDirectoryPath, prefix) || this;
27
+ }
28
+ BuiltinInterface.prototype.updateStrapiName = function () {
29
+ this.StrapiName = "builtins::".concat(this.BaseName);
30
+ };
31
+ return BuiltinInterface;
32
+ }(Interface_1.default));
33
+ exports.default = BuiltinInterface;
@@ -1,7 +1,8 @@
1
1
  import Interface from "./Interface";
2
2
  export default class ComponentInterface extends Interface {
3
3
  protected Category: string;
4
- constructor(baseName: string, attributes: any, relativeDirectoryPath: string, category: string, prefix?: string);
4
+ protected Options: Record<string, any>;
5
+ constructor(baseName: string, attributes: any, relativeDirectoryPath: string, category: string, prefix?: string, options?: Record<string, any>);
5
6
  updateStrapiName(): void;
6
7
  getInterfaceFieldsString(): string;
7
8
  }
@@ -21,15 +21,21 @@ Object.defineProperty(exports, "__esModule", { value: true });
21
21
  var Interface_1 = __importDefault(require("./Interface"));
22
22
  var ComponentInterface = /** @class */ (function (_super) {
23
23
  __extends(ComponentInterface, _super);
24
- function ComponentInterface(baseName, attributes, relativeDirectoryPath, category, prefix) {
24
+ function ComponentInterface(baseName, attributes, relativeDirectoryPath, category, prefix, options) {
25
25
  if (prefix === void 0) { prefix = ""; }
26
+ if (options === void 0) { options = {}; }
26
27
  var _this = _super.call(this, baseName, attributes, relativeDirectoryPath, prefix) || this;
28
+ _this.Options = {
29
+ hasId: true,
30
+ hasComponent: true,
31
+ };
27
32
  _this.Category = category;
28
33
  // this.Attributes.id = {
29
34
  // type: "number", // Components have a id field with a number
30
35
  // required: true,
31
36
  // };
32
37
  _this.updateStrapiName();
38
+ Object.assign(_this.Options, options);
33
39
  return _this;
34
40
  }
35
41
  ComponentInterface.prototype.updateStrapiName = function () {
@@ -38,8 +44,13 @@ var ComponentInterface = /** @class */ (function (_super) {
38
44
  ComponentInterface.prototype.getInterfaceFieldsString = function () {
39
45
  var attrs = this.getAttributes();
40
46
  var str = '';
41
- str += " id: number;\n";
42
- str += " __component: \"".concat(this.getStrapiName(), "\";\n");
47
+ var _a = this.Options, hasId = _a.hasId, hasComponent = _a.hasComponent;
48
+ if (hasId) {
49
+ str += " id: number;\n";
50
+ }
51
+ if (hasComponent) {
52
+ str += " __component: \"".concat(this.getStrapiName(), "\";\n");
53
+ }
43
54
  return str + attrs.toFieldsString();
44
55
  };
45
56
  return ComponentInterface;
@@ -1,4 +1,8 @@
1
1
  import Attributes from "./Attributes";
2
+ export declare type RelationNames = Record<string, {
3
+ name: string;
4
+ inter: Interface;
5
+ }>;
2
6
  export default class Interface {
3
7
  protected BaseName: string;
4
8
  private Relations;
@@ -30,7 +30,7 @@ var Interface = /** @class */ (function () {
30
30
  };
31
31
  Interface.prototype.getDependencies = function () {
32
32
  var attrs = new Attributes_1.default(this.Attributes, this.RelationNames);
33
- return attrs.getDependencies(this.getStrapiName());
33
+ return attrs.getDependencies();
34
34
  };
35
35
  Interface.prototype.getFullInterfaceName = function () {
36
36
  var pascalName = (0, utils_1.pascalCase)(this.BaseName);
@@ -66,7 +66,7 @@ var Interface = /** @class */ (function () {
66
66
  _this.RelationNamesCounter[name] = 0;
67
67
  }
68
68
  }
69
- _this.RelationNames[inter.getStrapiName()] = [name, inter];
69
+ _this.RelationNames[inter.getStrapiName()] = { name: name, inter: inter };
70
70
  });
71
71
  };
72
72
  Interface.prototype.getTsImports = function () {
@@ -75,8 +75,8 @@ var Interface = /** @class */ (function () {
75
75
  if (strapiName === _this.getStrapiName()) {
76
76
  return "";
77
77
  }
78
- var relationName = _this.RelationNames[strapiName][0];
79
- var inter = _this.RelationNames[strapiName][1];
78
+ var relationName = _this.RelationNames[strapiName].name;
79
+ var inter = _this.RelationNames[strapiName].inter;
80
80
  var importPath = (0, utils_1.prefixDotSlash)((0, path_1.relative)(_this.getRelativeRootDir(), inter.getRelativeRootPath()));
81
81
  var fullName = inter.getFullInterfaceName();
82
82
  var importNameString = fullName === relationName ? fullName : "".concat(fullName, " as ").concat(relationName);
@@ -3,14 +3,20 @@ export default class InterfaceManager {
3
3
  private OutRoot;
4
4
  private StrapiSrcRoot;
5
5
  private Options;
6
+ private PrettierOptions;
6
7
  static BaseOptions: {
7
8
  prefix: string;
8
9
  useCategoryPrefix: boolean;
9
10
  componentPrefix: string;
10
11
  componentPrefixOverridesPrefix: boolean;
12
+ builtinsPrefix: string;
13
+ builtinsPrefixOverridesPrefix: boolean;
14
+ prettierFile: any;
11
15
  };
12
16
  constructor(outRoot: string, strapiSrcRoot: string, options?: any);
17
+ loadPrettierConfig(): Promise<void>;
13
18
  createInterfaces(): Promise<void>;
19
+ createBuiltinInterfaces(): void;
14
20
  injectDependencies(): void;
15
21
  makeFolders(): Promise<void>;
16
22
  writeInterfaces(): Promise<void>;