@malevich-studio/strapi-sdk-typescript 1.0.0 → 1.0.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.
@@ -32,20 +32,17 @@ var __importStar = (this && this.__importStar) || (function () {
32
32
  return result;
33
33
  };
34
34
  })();
35
- var __importDefault = (this && this.__importDefault) || function (mod) {
36
- return (mod && mod.__esModule) ? mod : { "default": mod };
37
- };
38
35
  Object.defineProperty(exports, "__esModule", { value: true });
39
36
  exports.generateStrapiTypes = generateStrapiTypes;
40
37
  const fs = __importStar(require("fs"));
41
38
  const path = __importStar(require("path"));
42
39
  require("dotenv/config");
43
- const main_1 = __importDefault(require("./main"));
44
- var ConfigTypeKind;
45
- (function (ConfigTypeKind) {
46
- ConfigTypeKind["CollectionType"] = "collectionType";
47
- ConfigTypeKind["SingleType"] = "singleType";
48
- })(ConfigTypeKind || (ConfigTypeKind = {}));
40
+ const main_1 = require("./main");
41
+ var ContentTypeKind;
42
+ (function (ContentTypeKind) {
43
+ ContentTypeKind["CollectionType"] = "collectionType";
44
+ ContentTypeKind["SingleType"] = "singleType";
45
+ })(ContentTypeKind || (ContentTypeKind = {}));
49
46
  var AttributeType;
50
47
  (function (AttributeType) {
51
48
  AttributeType["BigInteger"] = "biginteger";
@@ -63,6 +60,7 @@ var AttributeType;
63
60
  AttributeType["Relation"] = "relation";
64
61
  AttributeType["String"] = "string";
65
62
  AttributeType["Text"] = "text";
63
+ AttributeType["Float"] = "float";
66
64
  // RichText = 'richtext',
67
65
  })(AttributeType || (AttributeType = {}));
68
66
  var AttributeRelation;
@@ -74,7 +72,7 @@ var AttributeRelation;
74
72
  AttributeRelation["OneToOne"] = "oneToOne";
75
73
  })(AttributeRelation || (AttributeRelation = {}));
76
74
  function getComponentType(attribute) {
77
- const componentTypeName = getContentTypeName(attribute.component);
75
+ const componentTypeName = getComponentName(attribute.component);
78
76
  return attribute.repeatable ? `${componentTypeName}[]` : componentTypeName;
79
77
  }
80
78
  function getRelationType(attribute) {
@@ -150,16 +148,16 @@ function getContentTypeName(uid) {
150
148
  .map((s) => s.charAt(0).toUpperCase() + s.slice(1))
151
149
  .join('');
152
150
  }
151
+ function getContentTypeMethodName(uid) {
152
+ const typeName = getContentTypeName(uid);
153
+ return typeName.charAt(0).toLowerCase() + typeName.slice(1);
154
+ }
153
155
  /**
154
156
  * Generates a TS interface from a content type or component definition
155
157
  */
156
158
  function generateTypeCode(name, attributes) {
157
159
  const lines = [];
158
160
  lines.push(`export type ${name} = {`);
159
- // Strapi's default fields:
160
- lines.push(` id?: number;`);
161
- lines.push(` createdAt?: string;`);
162
- lines.push(` updatedAt?: string;`);
163
161
  for (const attributeName in attributes) {
164
162
  const attribute = attributes[attributeName];
165
163
  const typeName = getAttributeType(attribute);
@@ -173,7 +171,7 @@ function generateQueryTypeCode(name, attributes) {
173
171
  const fields = [];
174
172
  const sort = [];
175
173
  const filters = [];
176
- filters.push(`export type ${name}Filters = Filters<{`);
174
+ const populate = [];
177
175
  for (const attributeName in attributes) {
178
176
  const attribute = attributes[attributeName];
179
177
  fields.push(`'${attributeName}'`);
@@ -185,6 +183,7 @@ function generateQueryTypeCode(name, attributes) {
185
183
  AttributeType.Integer,
186
184
  AttributeType.BigInteger,
187
185
  AttributeType.Decimal,
186
+ AttributeType.Float,
188
187
  AttributeType.Boolean,
189
188
  AttributeType.DateTime,
190
189
  AttributeType.Enumeration,
@@ -197,8 +196,11 @@ function generateQueryTypeCode(name, attributes) {
197
196
  switch (attribute.type) {
198
197
  case AttributeType.Relation:
199
198
  filters.push(` ${attributeName}?: ${getContentTypeName(attribute.target)}Filters;`);
199
+ populate.push(` ${attributeName}?: ${getContentTypeName(attribute.target)}Query;`);
200
200
  break;
201
201
  case AttributeType.Component:
202
+ populate.push(` ${attributeName}?: ${getComponentName(attribute.component)}Query;`);
203
+ break;
202
204
  case AttributeType.Media:
203
205
  case AttributeType.Json:
204
206
  break;
@@ -206,40 +208,95 @@ function generateQueryTypeCode(name, attributes) {
206
208
  filters.push(` ${attributeName}?: FilterValue<${type}>;`);
207
209
  }
208
210
  }
209
- filters.push(`}>`);
210
- filters.push('');
211
211
  const lines = [];
212
+ lines.push(`export type ${name}Filters = Filters<{`);
212
213
  lines.push(...filters);
214
+ lines.push(`}>`);
215
+ lines.push('');
216
+ lines.push(`export type ${name}Populate = {`);
217
+ lines.push(...populate);
218
+ lines.push(`}`);
219
+ lines.push('');
213
220
  lines.push(`export type ${name}Query = Query<`);
214
221
  lines.push(` ${fields.join(' | ')},`);
215
222
  lines.push(` ${sort.join(' | ')},`);
216
- lines.push(` ${name}Filters`);
223
+ lines.push(` ${name}Filters,`);
224
+ lines.push(` ${name}Populate`);
217
225
  lines.push(`>`);
218
226
  return lines.join('\n');
219
227
  }
228
+ function generateMethodsCode(contentType) {
229
+ const methods = [];
230
+ const modelName = getContentTypeName(contentType.uid);
231
+ if (contentType.schema.kind === ContentTypeKind.CollectionType) {
232
+ methods.push([
233
+ ` public async ${getContentTypeMethodName(contentType.schema.pluralName)}(query?: ${modelName}Query, params?: RequestInit) {`,
234
+ ` return await this.getDocuments<${modelName}, ${modelName}Query>('${contentType.schema.pluralName}', query, params);`,
235
+ ' }',
236
+ ].join('\n'));
237
+ }
238
+ methods.push([
239
+ ` public async ${getContentTypeMethodName(contentType.schema.singularName)}(query?: ${modelName}Query, params?: RequestInit) {`,
240
+ ` return await this.getDocument<${modelName}, ${modelName}Query>('${contentType.schema.singularName}', query, params);`,
241
+ ' }',
242
+ ].join('\n'));
243
+ return methods;
244
+ }
220
245
  /**
221
246
  * Main function to fetch Strapi (v5) data and generate the d.ts file
222
247
  */
223
248
  async function generateStrapiTypes() {
224
- const strapi = new main_1.default(process.env.STRAPI_URL, process.env.STRAPI_TOKEN);
249
+ const strapi = new main_1.Strapi(process.env.STRAPI_URL, process.env.STRAPI_TOKEN);
225
250
  const contentTypes = (await strapi.request('content-type-builder/content-types')).data;
226
251
  const components = (await strapi.request('content-type-builder/components')).data;
227
252
  const allInterfaces = [];
253
+ const methods = [];
228
254
  for (const component of components) {
255
+ console.log(component.schema.attributes);
229
256
  const componentName = getComponentName(component.uid);
230
- const code = generateTypeCode(componentName, component.schema.attributes);
257
+ const attributes = {
258
+ id: {
259
+ type: AttributeType.Integer,
260
+ },
261
+ ...component.schema.attributes,
262
+ };
263
+ const code = generateTypeCode(componentName, attributes);
264
+ allInterfaces.push(generateQueryTypeCode(componentName, attributes));
231
265
  allInterfaces.push(code);
232
266
  }
233
267
  for (const contentType of contentTypes) {
234
- if (!contentType.uid.startsWith('api::')) {
268
+ // console.log(contentTypes);
269
+ if (!(contentType.uid.startsWith('api::') || contentType.uid.startsWith('plugin::users-permissions'))) {
235
270
  continue;
236
271
  }
272
+ methods.push(...generateMethodsCode(contentType));
237
273
  const modelName = getContentTypeName(contentType.uid);
238
- allInterfaces.push(generateTypeCode(modelName, contentType.schema.attributes));
239
- allInterfaces.push(generateQueryTypeCode(modelName, contentType.schema.attributes));
274
+ const attributes = {
275
+ id: {
276
+ type: AttributeType.Integer,
277
+ },
278
+ documentId: {
279
+ type: AttributeType.String,
280
+ },
281
+ createdAt: {
282
+ type: AttributeType.DateTime,
283
+ },
284
+ updatedAt: {
285
+ type: AttributeType.DateTime,
286
+ },
287
+ ...contentType.schema.attributes,
288
+ };
289
+ allInterfaces.push(generateTypeCode(modelName, attributes));
290
+ allInterfaces.push(generateQueryTypeCode(modelName, attributes));
240
291
  }
241
- const output = allInterfaces.join('\n\n');
242
- const outPath = path.join(process.cwd(), 'strapi-types.d.ts');
292
+ const output = [
293
+ 'import {Strapi as StrapiBase, Query, Filters, FilterValue} from "@malevich-studio/strapi-sdk-typescript";\n',
294
+ 'export default class Strapi extends StrapiBase {',
295
+ ...methods,
296
+ '}',
297
+ ...allInterfaces,
298
+ ].join('\n\n');
299
+ const outPath = path.join(process.cwd(), 'strapi.ts');
243
300
  fs.writeFileSync(outPath, output, 'utf-8');
244
- console.log(`✅ "strapi-types.d.ts" has been successfully generated!`);
301
+ console.log(`✅ "strapi.ts" has been successfully generated!`);
245
302
  }
package/dist/main.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  type Response<T> = {
2
- data: T[];
2
+ data: T;
3
3
  meta: {
4
4
  pagination: {
5
5
  total?: number;
@@ -56,12 +56,12 @@ export type Query<Fields, Sort, Filters, Populate> = {
56
56
  limit?: number;
57
57
  });
58
58
  };
59
- export default class Strapi {
59
+ export declare class Strapi {
60
60
  private readonly url;
61
61
  private readonly token;
62
62
  constructor(url: string, token: string);
63
63
  request<T>(endpoint: string, data?: object, params?: RequestInit): Promise<Response<T>>;
64
- getDocuments<T, Q extends object>(endpoint: string, data?: Q, params?: RequestInit): Promise<Response<T>>;
64
+ getDocuments<T, Q extends object>(endpoint: string, data?: Q, params?: RequestInit): Promise<Response<T[]>>;
65
65
  getDocument<T, Q extends object>(endpoint: string, data?: Q, params?: RequestInit): Promise<Response<T>>;
66
66
  create<T>(endpoint: string, data?: object, params?: RequestInit): Promise<Response<T>>;
67
67
  }
package/dist/main.js CHANGED
@@ -3,6 +3,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
3
3
  return (mod && mod.__esModule) ? mod : { "default": mod };
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.Strapi = void 0;
6
7
  const qs_1 = __importDefault(require("qs"));
7
8
  class Strapi {
8
9
  constructor(url, token) {
@@ -13,19 +14,6 @@ class Strapi {
13
14
  const baseUrl = `${this.url}/api/`;
14
15
  const queryString = params.method === 'GET' ? qs_1.default.stringify(data) : '';
15
16
  const url = queryString ? `${baseUrl}${endpoint}?${queryString}` : `${baseUrl}${endpoint}`;
16
- console.log({
17
- headers: {
18
- Authorization: `Bearer ${this.token}`,
19
- 'Content-Type': 'application/json',
20
- },
21
- cache: 'no-store',
22
- ...(params.method && params.method !== 'GET' ? {
23
- body: JSON.stringify({
24
- data,
25
- })
26
- } : {}),
27
- ...params
28
- });
29
17
  const response = await fetch(url, {
30
18
  headers: {
31
19
  Authorization: `Bearer ${this.token}`,
@@ -64,4 +52,4 @@ class Strapi {
64
52
  });
65
53
  }
66
54
  }
67
- exports.default = Strapi;
55
+ exports.Strapi = Strapi;
package/package.json CHANGED
@@ -1,7 +1,8 @@
1
1
  {
2
2
  "name": "@malevich-studio/strapi-sdk-typescript",
3
- "version": "1.0.0",
4
- "main": "dist/index.js",
3
+ "version": "1.0.1",
4
+ "main": "dist/main.js",
5
+ "types": "dist/main.d.ts",
5
6
  "bin": {
6
7
  "generate-strapi-types": "dist/cli.js"
7
8
  },