simple-strapi 1.0.0-alpha.2 → 1.0.0-alpha.4

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/dist/client.d.ts CHANGED
@@ -1,7 +1,9 @@
1
1
  import { InferNumber, NumberField, NumberOptions } from "./fields/number";
2
2
  import { InferText, TextField, TextOptions } from "./fields/text";
3
- import { InferRelationHasMany, RelationHasManyField, RelationHasManyOptions } from "./fields/relation";
3
+ import { InferRelationHasMany, InferRelationHasOne, RelationHasManyField, RelationHasManyOptions, RelationHasOneField, RelationHasOneOptions } from "./fields/relation";
4
+ import z from "zod";
4
5
  import { DynamicField, DynamicOptions, InferDynamic } from "./fields/dynamic";
6
+ import { defaultStrapiFieldsSchema } from "./utils/schema";
5
7
  import { ComponentRepeatableField, ComponentRepeatableOptions, ComponentSingleField, ComponentSingleOptions, InferComponentRepeatable, InferComponentSingle } from "./fields/component";
6
8
  import { InferMediaSingle, MediaSingleField, MediaSingleOptions } from "./fields/media";
7
9
  import { EnumerationField, EnumerationOptions, InferEnumeration } from "./fields/enumeration";
@@ -11,7 +13,7 @@ type EntityRequest<P = {}> = {
11
13
  params?: RequestParams;
12
14
  headers?: Record<string, string>;
13
15
  } & P;
14
- export type SchemaField = TextField | NumberField | RelationHasManyField | DynamicField | ComponentSingleField | ComponentRepeatableField | MediaSingleField | EnumerationField | RichTextBlocksField;
16
+ export type SchemaField = TextField | NumberField | RelationHasManyField | RelationHasOneField | DynamicField | ComponentSingleField | ComponentRepeatableField | MediaSingleField | EnumerationField | RichTextBlocksField;
15
17
  export type Schema = Record<string, SchemaField>;
16
18
  export type InferSchema<S extends Schema> = {
17
19
  [K in keyof S]: S[K] extends ["text", infer O extends TextOptions] ? InferText<O> : S[K] extends ["number", infer O extends NumberOptions] ? InferNumber<O> : S[K] extends [
@@ -19,6 +21,10 @@ export type InferSchema<S extends Schema> = {
19
21
  infer R extends Schema,
20
22
  infer O extends RelationHasManyOptions
21
23
  ] ? InferRelationHasMany<R, O> : S[K] extends [
24
+ "relation.hasOne",
25
+ infer R extends Schema,
26
+ infer O extends RelationHasOneOptions
27
+ ] ? InferRelationHasOne<R, O> : S[K] extends [
22
28
  "component.single",
23
29
  infer R extends Schema,
24
30
  infer O extends ComponentSingleOptions
@@ -36,6 +42,7 @@ export type InferSchema<S extends Schema> = {
36
42
  infer O extends EnumerationOptions
37
43
  ] ? InferEnumeration<V, O> : S[K] extends ["richText.blocks", infer O extends RichTextBlocksOptions] ? InferRichTextBlocks<O> : never;
38
44
  };
45
+ export type InferSchemaWithDefaults<S extends Schema> = InferSchema<S> & z.output<typeof defaultStrapiFieldsSchema>;
39
46
  declare class Client {
40
47
  private options;
41
48
  private static headers;
@@ -69,7 +76,7 @@ declare class Client {
69
76
  schema: S;
70
77
  populate?: any;
71
78
  }>): Promise<{
72
- data: InferSchema<S>;
79
+ data: InferSchemaWithDefaults<S>;
73
80
  meta: any;
74
81
  }>;
75
82
  getSingle(pluralID: string, options: EntityRequest<{
@@ -86,7 +93,7 @@ declare class Client {
86
93
  };
87
94
  populate?: any;
88
95
  }>): Promise<{
89
- data: InferSchema<S>[];
96
+ data: InferSchemaWithDefaults<S>[];
90
97
  meta: any;
91
98
  }>;
92
99
  getCollection(pluralID: string, options: EntityRequest<{
package/dist/client.js CHANGED
@@ -1,9 +1,9 @@
1
- import { createSimpleException, isSimpleExceptionOrFallback } from "@hund-ernesto/simple-exception";
1
+ import { createSimpleException, ensureSimpleException } from "simple-exception";
2
2
  import { join } from "path";
3
3
  import fetch from "node-fetch";
4
4
  import qs from "qs";
5
5
  import z from "zod";
6
- import { schemaToParser } from "./utils/schema";
6
+ import { defaultStrapiFields, schemaToParser } from "./utils/schema";
7
7
  class Client {
8
8
  static async create(endpoint, { auth, ...options } = {}) {
9
9
  const endpointURL = new URL(endpoint);
@@ -50,7 +50,7 @@ class Client {
50
50
  return token;
51
51
  }
52
52
  catch (exception) {
53
- throw isSimpleExceptionOrFallback(exception);
53
+ throw ensureSimpleException(exception);
54
54
  }
55
55
  }
56
56
  constructor(options) {
@@ -68,6 +68,9 @@ class Client {
68
68
  const populateHasManyRelation = ([, shape]) => {
69
69
  return this.populateFromSchema(shape);
70
70
  };
71
+ const populateHasOneRelation = ([, shape]) => {
72
+ return this.populateFromSchema(shape);
73
+ };
71
74
  const populateComponentSingle = ([, shape]) => {
72
75
  return this.populateFromSchema(shape);
73
76
  };
@@ -91,6 +94,11 @@ class Client {
91
94
  if (!Object.keys(populate[key].populate)["length"])
92
95
  populate[key] = true;
93
96
  break;
97
+ case "relation.hasOne":
98
+ populate[key] = { populate: populateHasOneRelation(field) };
99
+ if (!Object.keys(populate[key].populate)["length"])
100
+ populate[key] = true;
101
+ break;
94
102
  case "component.single":
95
103
  populate[key] = { populate: populateComponentSingle(field) };
96
104
  if (!Object.keys(populate[key].populate)["length"])
@@ -161,13 +169,15 @@ class Client {
161
169
  source: "strapi-utils/client.ts",
162
170
  });
163
171
  }
164
- const { data: [data], meta, } = z.object({ data: z.array(z.any()), meta: z.any() }).parse(await response.json());
172
+ const { data, meta } = z
173
+ .object({ data: z.any(), meta: z.any() })
174
+ .parse(await response.json());
165
175
  if (!data)
166
176
  throw createSimpleException({ code: 404, type: "error", message: "Not found" });
167
177
  if ("schema" in options) {
168
178
  const { schema: shape } = options;
169
179
  if (shape) {
170
- const schema = z.object(schemaToParser(shape)).loose();
180
+ const schema = z.object(schemaToParser(shape)).extend(defaultStrapiFields).loose();
171
181
  const result = schema.safeParse(data);
172
182
  if (!result.success) {
173
183
  console.warn("⚠️ Single entity parsing error");
@@ -180,7 +190,7 @@ class Client {
180
190
  return { data, meta };
181
191
  }
182
192
  catch (exception) {
183
- throw isSimpleExceptionOrFallback(exception);
193
+ throw ensureSimpleException(exception);
184
194
  }
185
195
  }
186
196
  async getCollection(pluralID, { params = {}, headers = {}, pagination = { page: 1 }, ...options } = {}) {
@@ -237,7 +247,7 @@ class Client {
237
247
  if ("schema" in options) {
238
248
  const { schema: shape } = options;
239
249
  if (shape) {
240
- const schema = z.object(schemaToParser(shape)).loose();
250
+ const schema = z.object(schemaToParser(shape)).extend(defaultStrapiFields).loose();
241
251
  const parsedData = [];
242
252
  for (const entry of data) {
243
253
  const result = schema.safeParse(entry);
@@ -245,7 +255,7 @@ class Client {
245
255
  parsedData.push(result.data);
246
256
  }
247
257
  else {
248
- console.warn("⚠️ Collection parsing error on entry");
258
+ console.warn("⚠️ Collection parsing error on entry", entry);
249
259
  console.error("🚨 Error", result.error);
250
260
  }
251
261
  }
@@ -255,7 +265,7 @@ class Client {
255
265
  return { data, meta };
256
266
  }
257
267
  catch (exception) {
258
- throw isSimpleExceptionOrFallback(exception);
268
+ throw ensureSimpleException(exception);
259
269
  }
260
270
  }
261
271
  }
@@ -1,12 +1,12 @@
1
1
  import { ZodType } from "zod";
2
- import { InferSchema, Schema } from "../client";
2
+ import { InferSchemaWithDefaults, Schema } from "../client";
3
3
  /**
4
4
  * SINGLE
5
5
  */
6
6
  export type ComponentSingleOptions = {
7
7
  required?: boolean;
8
8
  };
9
- export type InferComponentSingle<S extends Schema, O extends ComponentSingleOptions> = O["required"] extends true ? InferSchema<S> : InferSchema<S> | null | undefined;
9
+ export type InferComponentSingle<S extends Schema, O extends ComponentSingleOptions> = O["required"] extends true ? InferSchemaWithDefaults<S> : InferSchemaWithDefaults<S> | null | undefined;
10
10
  export declare const singleSchema: (shape: Schema, opts: ComponentSingleOptions) => ZodType;
11
11
  export type ComponentSingleField = readonly ["component.single", Schema, ComponentSingleOptions];
12
12
  /**
@@ -15,7 +15,7 @@ export type ComponentSingleField = readonly ["component.single", Schema, Compone
15
15
  export type ComponentRepeatableOptions = {
16
16
  required?: boolean;
17
17
  };
18
- export type InferComponentRepeatable<S extends Schema, O extends ComponentRepeatableOptions> = O["required"] extends true ? InferSchema<S>[] : InferSchema<S>[] | null | undefined;
18
+ export type InferComponentRepeatable<S extends Schema, O extends ComponentRepeatableOptions> = O["required"] extends true ? InferSchemaWithDefaults<S>[] : InferSchemaWithDefaults<S>[] | null | undefined;
19
19
  export declare const repeatableSchema: (shape: Schema, opts: ComponentRepeatableOptions) => ZodType;
20
20
  export type ComponentRepeatableField = readonly [
21
21
  "component.repeatable",
@@ -1,10 +1,23 @@
1
- import { InferSchema, Schema } from "../client";
1
+ import { InferSchemaWithDefaults, Schema } from "../client";
2
+ /**
3
+ * HAS MANY
4
+ */
2
5
  export type RelationHasManyOptions = {
3
6
  nullable?: boolean;
4
7
  optional?: boolean;
5
8
  };
6
- export type InferRelationHasMany<S extends Schema, O extends RelationHasManyOptions> = O["nullable"] extends true ? O["optional"] extends true ? InferSchema<S>[] | null | undefined : InferSchema<S>[] | null : O["optional"] extends true ? InferSchema<S>[] | undefined : InferSchema<S>[];
9
+ export type InferRelationHasMany<S extends Schema, O extends RelationHasManyOptions> = O["nullable"] extends true ? O["optional"] extends true ? InferSchemaWithDefaults<S>[] | null | undefined : InferSchemaWithDefaults<S>[] | null : O["optional"] extends true ? InferSchemaWithDefaults<S>[] | undefined : InferSchemaWithDefaults<S>[];
7
10
  export type RelationHasManyField = readonly ["relation.hasMany", Schema, RelationHasManyOptions];
11
+ /**
12
+ * HAS ONE
13
+ */
14
+ export type RelationHasOneOptions = {
15
+ nullable?: boolean;
16
+ optional?: boolean;
17
+ };
18
+ export type InferRelationHasOne<S extends Schema, O extends RelationHasOneOptions> = O["nullable"] extends true ? O["optional"] extends true ? InferSchemaWithDefaults<S> | null | undefined : InferSchemaWithDefaults<S> | null : O["optional"] extends true ? InferSchemaWithDefaults<S> | undefined : InferSchemaWithDefaults<S>;
19
+ export type RelationHasOneField = readonly ["relation.hasOne", Schema, RelationHasOneOptions];
8
20
  export declare const relation: {
9
21
  hasMany: <S = any, O extends RelationHasManyOptions = {}>(shape: S, options?: O) => ["relation.hasMany", S, O];
22
+ hasOne: <S = any, O extends RelationHasOneOptions = {}>(shape: S, options?: O) => ["relation.hasOne", S, O];
10
23
  };
@@ -1,4 +1,7 @@
1
1
  const hasMany = (shape, options = {}) => {
2
2
  return ["relation.hasMany", shape, options];
3
3
  };
4
- export const relation = { hasMany };
4
+ const hasOne = (shape, options = {}) => {
5
+ return ["relation.hasOne", shape, options];
6
+ };
7
+ export const relation = { hasMany, hasOne };
@@ -18,8 +18,23 @@ export declare const paragraphChild: z.ZodType<ParagraphChild>;
18
18
  export declare const zodRichTextBlocksSchema: z.ZodArray<z.ZodUnion<readonly [z.ZodObject<{
19
19
  type: z.ZodLiteral<"paragraph">;
20
20
  children: z.ZodArray<z.ZodType<ParagraphChild, unknown, z.core.$ZodTypeInternals<ParagraphChild, unknown>>>;
21
+ }, z.core.$strip>, z.ZodObject<{
22
+ type: z.ZodLiteral<"heading">;
23
+ level: z.ZodNumber;
24
+ children: z.ZodArray<z.ZodType<ParagraphChild, unknown, z.core.$ZodTypeInternals<ParagraphChild, unknown>>>;
25
+ }, z.core.$strip>, z.ZodObject<{
26
+ type: z.ZodLiteral<"list">;
27
+ format: z.ZodEnum<{
28
+ ordered: "ordered";
29
+ unordered: "unordered";
30
+ }>;
31
+ children: z.ZodArray<z.ZodObject<{
32
+ type: z.ZodLiteral<"list-item">;
33
+ children: z.ZodArray<z.ZodType<ParagraphChild, unknown, z.core.$ZodTypeInternals<ParagraphChild, unknown>>>;
34
+ }, z.core.$strip>>;
21
35
  }, z.core.$strip>]>>;
22
36
  type ZodRichTextBlocksType = z.output<typeof zodRichTextBlocksSchema>;
37
+ export type RichTextBlocks = ZodRichTextBlocksType;
23
38
  export type RichTextBlocksOptions = {
24
39
  required?: boolean;
25
40
  };
@@ -19,7 +19,21 @@ const paragraphBlock = z.object({
19
19
  type: z.literal("paragraph"),
20
20
  children: z.array(paragraphChild),
21
21
  });
22
- export const zodRichTextBlocksSchema = z.array(z.union([paragraphBlock]));
22
+ const headingBlock = z.object({
23
+ type: z.literal("heading"),
24
+ level: z.number(),
25
+ children: z.array(paragraphChild),
26
+ });
27
+ const listItemBlock = z.object({
28
+ type: z.literal("list-item"),
29
+ children: z.array(paragraphChild),
30
+ });
31
+ const listBlock = z.object({
32
+ type: z.literal("list"),
33
+ format: z.enum(["ordered", "unordered"]),
34
+ children: z.array(listItemBlock),
35
+ });
36
+ export const zodRichTextBlocksSchema = z.array(z.union([paragraphBlock, headingBlock, listBlock]));
23
37
  const blocks = (options = {}) => {
24
38
  return ["richText.blocks", options];
25
39
  };
@@ -1,3 +1,17 @@
1
1
  import { Schema } from "../client";
2
2
  import z from "zod";
3
+ export declare const defaultStrapiFields: {
4
+ id: z.ZodNumber;
5
+ documentId: z.ZodOptional<z.ZodString>;
6
+ createdAt: z.ZodOptional<z.ZodISODateTime>;
7
+ updatedAt: z.ZodOptional<z.ZodISODateTime>;
8
+ publishedAt: z.ZodOptional<z.ZodNullable<z.ZodISODateTime>>;
9
+ };
10
+ export declare const defaultStrapiFieldsSchema: z.ZodObject<{
11
+ id: z.ZodNumber;
12
+ documentId: z.ZodOptional<z.ZodString>;
13
+ createdAt: z.ZodOptional<z.ZodISODateTime>;
14
+ updatedAt: z.ZodOptional<z.ZodISODateTime>;
15
+ publishedAt: z.ZodOptional<z.ZodNullable<z.ZodISODateTime>>;
16
+ }, z.core.$strip>;
3
17
  export declare const schemaToParser: (schema: Schema) => Record<string, z.ZodType<unknown, unknown, z.core.$ZodTypeInternals<unknown, unknown>>>;
@@ -6,6 +6,14 @@ import { textSchema } from "../fields/text";
6
6
  import z from "zod";
7
7
  import { enumerationSchema } from "../fields/enumeration";
8
8
  import { richTextBlocksSchema } from "../fields/richText";
9
+ export const defaultStrapiFields = {
10
+ id: z.number(),
11
+ documentId: z.string().optional(),
12
+ createdAt: z.iso.datetime().optional(),
13
+ updatedAt: z.iso.datetime().optional(),
14
+ publishedAt: z.iso.datetime().nullable().optional(),
15
+ };
16
+ export const defaultStrapiFieldsSchema = z.object(defaultStrapiFields);
9
17
  export const schemaToParser = (schema) => {
10
18
  const shape = {};
11
19
  for (const [key, field] of Object.entries(schema)) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "simple-strapi",
3
- "version": "1.0.0-alpha.2",
3
+ "version": "1.0.0-alpha.4",
4
4
  "type": "module",
5
5
  "main": "./dist/index.js",
6
6
  "types": "./dist/index.d.ts",