@prismicio/mock 0.0.8 → 0.1.0

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 (97) hide show
  1. package/dist/api/index.cjs +348 -236
  2. package/dist/api/index.cjs.map +1 -1
  3. package/dist/api/index.d.ts +52 -6
  4. package/dist/api/index.js +348 -236
  5. package/dist/api/index.js.map +1 -1
  6. package/dist/index.cjs +893 -543
  7. package/dist/index.cjs.map +1 -1
  8. package/dist/index.d.ts +247 -73
  9. package/dist/index.js +885 -542
  10. package/dist/index.js.map +1 -1
  11. package/dist/model/index.cjs +398 -134
  12. package/dist/model/index.cjs.map +1 -1
  13. package/dist/model/index.d.ts +114 -28
  14. package/dist/model/index.js +398 -134
  15. package/dist/model/index.js.map +1 -1
  16. package/dist/value/index.cjs +598 -468
  17. package/dist/value/index.cjs.map +1 -1
  18. package/dist/value/index.d.ts +96 -40
  19. package/dist/value/index.js +598 -468
  20. package/dist/value/index.js.map +1 -1
  21. package/package.json +22 -20
  22. package/src/api/createAPIMockFactory.ts +56 -0
  23. package/src/api/query.ts +4 -4
  24. package/src/api/ref.ts +6 -6
  25. package/src/api/repository.ts +12 -14
  26. package/src/api/tags.ts +5 -2
  27. package/src/createMockFactory.ts +52 -0
  28. package/src/index.ts +15 -0
  29. package/src/lib/buildEmbedField.ts +28 -30
  30. package/src/lib/buildImageFieldImage.ts +19 -7
  31. package/src/lib/createFaker.ts +99 -22
  32. package/src/lib/generateCustomTypeId.ts +13 -5
  33. package/src/lib/generateFieldId.ts +13 -7
  34. package/src/lib/generateTags.ts +17 -16
  35. package/src/lib/getMockEmbedData.ts +45 -16
  36. package/src/lib/getMockImageData.ts +13 -5
  37. package/src/lib/lorem.ts +112 -0
  38. package/src/lib/valueForModel.ts +47 -30
  39. package/src/lib/valueForModelMap.ts +24 -4
  40. package/src/model/boolean.ts +6 -6
  41. package/src/model/buildMockGroupFieldMap.ts +5 -5
  42. package/src/model/color.ts +4 -4
  43. package/src/model/contentRelationship.ts +4 -4
  44. package/src/model/createModelMockFactory.ts +213 -0
  45. package/src/model/customType.ts +6 -6
  46. package/src/model/date.ts +4 -4
  47. package/src/model/embed.ts +4 -4
  48. package/src/model/geoPoint.ts +3 -3
  49. package/src/model/group.ts +7 -7
  50. package/src/model/image.ts +8 -12
  51. package/src/model/index.ts +2 -0
  52. package/src/model/integrationFields.ts +4 -4
  53. package/src/model/keyText.ts +4 -4
  54. package/src/model/link.ts +6 -6
  55. package/src/model/linkToMedia.ts +5 -5
  56. package/src/model/number.ts +4 -4
  57. package/src/model/richText.ts +8 -8
  58. package/src/model/select.ts +5 -5
  59. package/src/model/sharedSlice.ts +5 -5
  60. package/src/model/sharedSliceVariation.ts +10 -10
  61. package/src/model/slice.ts +7 -7
  62. package/src/model/sliceZone.ts +7 -4
  63. package/src/model/timestamp.ts +4 -4
  64. package/src/model/title.ts +7 -7
  65. package/src/model/uid.ts +4 -4
  66. package/src/types.ts +70 -31
  67. package/src/value/boolean.ts +4 -6
  68. package/src/value/color.ts +3 -3
  69. package/src/value/contentRelationship.ts +21 -18
  70. package/src/value/createValueMockFactory.ts +236 -0
  71. package/src/value/customType.ts +12 -12
  72. package/src/value/date.ts +6 -2
  73. package/src/value/embed.ts +23 -7
  74. package/src/value/geoPoint.ts +4 -6
  75. package/src/value/group.ts +6 -11
  76. package/src/value/image.ts +26 -18
  77. package/src/value/integrationFields.ts +12 -26
  78. package/src/value/keyText.ts +3 -5
  79. package/src/value/link.ts +11 -9
  80. package/src/value/linkToMedia.ts +9 -8
  81. package/src/value/number.ts +3 -3
  82. package/src/value/richText/embed.ts +6 -3
  83. package/src/value/richText/heading.ts +32 -27
  84. package/src/value/richText/image.ts +9 -8
  85. package/src/value/richText/index.ts +71 -48
  86. package/src/value/richText/list.ts +6 -10
  87. package/src/value/richText/oList.ts +6 -10
  88. package/src/value/richText/paragraph.ts +10 -6
  89. package/src/value/richText/preformatted.ts +11 -7
  90. package/src/value/select.ts +11 -7
  91. package/src/value/sharedSlice.ts +5 -5
  92. package/src/value/sharedSliceVariation.ts +11 -16
  93. package/src/value/slice.ts +11 -15
  94. package/src/value/sliceZone.ts +14 -18
  95. package/src/value/timestamp.ts +31 -18
  96. package/src/value/title.ts +7 -3
  97. package/src/value/uid.ts +6 -4
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@prismicio/mock",
3
- "version": "0.0.8",
3
+ "version": "0.1.0",
4
4
  "description": "Generate mock Prismic documents, fields, Slices, and models for development and testing environments",
5
5
  "keywords": [
6
6
  "typescript",
@@ -16,7 +16,6 @@
16
16
  "license": "Apache-2.0",
17
17
  "author": "Prismic <contact@prismic.io> (https://prismic.io)",
18
18
  "sideEffects": false,
19
- "type": "module",
20
19
  "exports": {
21
20
  ".": {
22
21
  "require": "./dist/index.cjs",
@@ -49,34 +48,37 @@
49
48
  "format": "prettier --write .",
50
49
  "lint": "eslint --ext .js,.ts .",
51
50
  "prepare": "npm run build",
52
- "release": "npm run build && npm run test && standard-version && git push --follow-tags && npm run build && npm publish",
53
- "release:alpha": "npm run build && npm run test && standard-version --release-as major --prerelease alpha && git push --follow-tags && npm run build && npm publish --tag alpha",
51
+ "release": "npm run test && standard-version && git push --follow-tags && npm run build && npm publish",
52
+ "release:alpha": "npm run test && standard-version --release-as major --prerelease alpha && git push --follow-tags && npm run build && npm publish --tag alpha",
54
53
  "release:alpha:dry": "standard-version --release-as major --prerelease alpha --dry-run",
55
54
  "release:dry": "standard-version --dry-run",
56
- "test": "npm run lint && npm run unit",
55
+ "size": "size-limit",
56
+ "test": "npm run lint && npm run unit && npm run build && npm run size",
57
57
  "unit": "nyc --reporter=lcovonly --reporter=text --exclude-after-remap=false ava"
58
58
  },
59
59
  "dependencies": {
60
- "@prismicio/types": "^0.1.25",
60
+ "@prismicio/types": "^0.2.0",
61
61
  "change-case": "^4.1.2",
62
- "faker": "^5.5.3"
62
+ "rand-seed": "^1.0.1"
63
63
  },
64
64
  "devDependencies": {
65
- "@types/faker": "^5.5.8",
66
- "@typescript-eslint/eslint-plugin": "^5.12.0",
67
- "@typescript-eslint/parser": "^5.12.0",
68
- "ava": "^3.15.0",
69
- "eslint": "^8.9.0",
70
- "eslint-config-prettier": "^8.3.0",
71
- "eslint-plugin-prettier": "^4.0.0",
72
- "eslint-plugin-tsdoc": "^0.2.14",
65
+ "@size-limit/preset-small-lib": "^7.0.8",
66
+ "@typescript-eslint/eslint-plugin": "^5.30.5",
67
+ "@typescript-eslint/parser": "^5.30.5",
68
+ "ava": "^4.3.0",
69
+ "esbuild": "^0.14.48",
70
+ "esbuild-register": "^3.3.3",
71
+ "eslint": "^8.19.0",
72
+ "eslint-config-prettier": "^8.5.0",
73
+ "eslint-plugin-prettier": "^4.2.1",
74
+ "eslint-plugin-tsdoc": "^0.2.16",
73
75
  "nyc": "^15.1.0",
74
- "prettier": "^2.5.1",
75
- "prettier-plugin-jsdoc": "^0.3.30",
76
+ "prettier": "^2.7.1",
77
+ "prettier-plugin-jsdoc": "^0.3.38",
76
78
  "siroc": "^0.16.0",
77
- "standard-version": "^9.3.2",
78
- "ts-eager": "^2.0.2",
79
- "typescript": "^4.5.5"
79
+ "size-limit": "^7.0.8",
80
+ "standard-version": "^9.5.0",
81
+ "typescript": "^4.7.4"
80
82
  },
81
83
  "engines": {
82
84
  "node": ">=12.7.0"
@@ -0,0 +1,56 @@
1
+ import * as prismicT from "@prismicio/types";
2
+
3
+ import { createFaker, Faker } from "../lib/createFaker";
4
+
5
+ import { Seed, WithoutFakerConfig } from "../types";
6
+
7
+ import { query, MockRestApiQueryConfig } from "./query";
8
+ import { ref, MockRestApiRefConfig } from "./ref";
9
+ import { repository, MockRestApiRepositoryConfig } from "./repository";
10
+ import { tags, MockRestApiTagsConfig } from "./tags";
11
+
12
+ export const createAPIMockFactory = (
13
+ ...args: ConstructorParameters<typeof APIMockFactory>
14
+ ): APIMockFactory => {
15
+ return new APIMockFactory(...args);
16
+ };
17
+
18
+ type APIMockFactoryConfig =
19
+ | {
20
+ seed: Seed;
21
+ }
22
+ | {
23
+ faker: Faker;
24
+ };
25
+
26
+ export class APIMockFactory {
27
+ private faker: Faker;
28
+
29
+ constructor(config: APIMockFactoryConfig) {
30
+ this.faker = "faker" in config ? config.faker : createFaker(config.seed);
31
+ }
32
+
33
+ get seed() {
34
+ return this.faker.seed;
35
+ }
36
+
37
+ query<Document extends prismicT.PrismicDocument = prismicT.PrismicDocument>(
38
+ config?: WithoutFakerConfig<MockRestApiQueryConfig<Document>>,
39
+ ) {
40
+ return query({ ...config, faker: this.faker });
41
+ }
42
+
43
+ ref<IsScheduled extends boolean = false>(
44
+ config?: WithoutFakerConfig<MockRestApiRefConfig<IsScheduled>>,
45
+ ) {
46
+ return ref({ ...config, faker: this.faker });
47
+ }
48
+
49
+ repository(config?: WithoutFakerConfig<MockRestApiRepositoryConfig>) {
50
+ return repository({ ...config, faker: this.faker });
51
+ }
52
+
53
+ tags(config?: WithoutFakerConfig<MockRestApiTagsConfig>) {
54
+ return tags({ ...config, faker: this.faker });
55
+ }
56
+ }
package/src/api/query.ts CHANGED
@@ -15,9 +15,9 @@ export type MockRestApiQueryConfig<
15
15
  export const query = <
16
16
  Document extends prismicT.PrismicDocument = prismicT.PrismicDocument,
17
17
  >(
18
- config: MockRestApiQueryConfig<Document> = {},
18
+ config: MockRestApiQueryConfig<Document>,
19
19
  ): prismicT.Query<Document> => {
20
- const faker = createFaker(config.seed);
20
+ const faker = config.faker || createFaker(config.seed);
21
21
 
22
22
  const documents = config.documents || [];
23
23
  const page = Math.max(1, config.page ?? 1);
@@ -27,8 +27,8 @@ export const query = <
27
27
 
28
28
  return {
29
29
  page,
30
- next_page: page < totalPages ? faker.internet.url() : null,
31
- prev_page: page > 1 ? faker.internet.url() : null,
30
+ next_page: page < totalPages ? faker.url() : null,
31
+ prev_page: page > 1 ? faker.url() : null,
32
32
  total_pages: totalPages,
33
33
  results_size: results.length,
34
34
  results_per_page: pageSize,
package/src/api/ref.ts CHANGED
@@ -19,22 +19,22 @@ export type MockRestApiRefValue<IsScheduled extends boolean = false> = Omit<
19
19
  : { scheduledAt?: never });
20
20
 
21
21
  export const ref = <IsScheduled extends boolean = false>(
22
- config: MockRestApiRefConfig<IsScheduled> = {},
22
+ config: MockRestApiRefConfig<IsScheduled>,
23
23
  ): MockRestApiRefValue<IsScheduled> => {
24
- const faker = createFaker(config.seed);
24
+ const faker = config.faker || createFaker(config.seed);
25
25
 
26
26
  const value: prismicT.Ref = {
27
- id: faker.git.shortSha(),
28
- ref: faker.git.shortSha(),
27
+ id: faker.hash(16),
28
+ ref: faker.hash(16),
29
29
  isMasterRef: config.isMasterRef ?? false,
30
30
  label: config.isMasterRef
31
31
  ? "Master"
32
- : changeCase.capitalCase(faker.company.bsNoun()),
32
+ : changeCase.capitalCase(faker.words(faker.range(1, 3))),
33
33
  };
34
34
 
35
35
  if (config.isScheduled) {
36
36
  // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
37
- value.scheduledAt = timestamp({ seed: config.seed })!;
37
+ value.scheduledAt = timestamp({ faker })!;
38
38
  }
39
39
 
40
40
  return value as MockRestApiRefValue<IsScheduled>;
@@ -13,42 +13,40 @@ export type MockRestApiRepositoryConfig = {
13
13
  } & MockRestApiConfig;
14
14
 
15
15
  export const repository = (
16
- config: MockRestApiRepositoryConfig = {},
16
+ config: MockRestApiRepositoryConfig,
17
17
  ): prismicT.Repository => {
18
- const faker = createFaker(config.seed);
18
+ const faker = config.faker || createFaker(config.seed);
19
19
 
20
20
  const types = (config.customTypeModels || []).reduce((acc, model) => {
21
- acc[model.id] = model.label;
21
+ acc[model.id] = model.label || model.id;
22
22
 
23
23
  return acc;
24
24
  }, {} as prismicT.Repository["types"]);
25
25
 
26
26
  return {
27
27
  refs: [
28
- ref({ seed: config.seed, isMasterRef: true }),
29
- ...(config.withReleases
30
- ? [ref({ seed: config.seed }), ref({ seed: config.seed })]
31
- : []),
28
+ ref({ faker, isMasterRef: true }),
29
+ ...(config.withReleases ? [ref({ faker }), ref({ faker })] : []),
32
30
  ],
33
- integrationFieldsRef: ref({ seed: config.seed }).ref,
31
+ integrationFieldsRef: ref({ faker }).ref,
34
32
  types,
35
33
  languages: [
36
34
  {
37
- id: faker.lorem.word(),
38
- name: changeCase.capitalCase(faker.lorem.word()),
35
+ id: faker.word(),
36
+ name: changeCase.capitalCase(faker.word()),
39
37
  },
40
38
  ],
41
39
  tags: generateTags({
42
- seed: config.seed,
40
+ faker,
43
41
  min: 1,
44
42
  max: 10,
45
43
  }),
46
44
  forms: {},
47
45
  license: "All Rights Reserved",
48
- version: faker.git.shortSha(),
46
+ version: faker.hash(7),
49
47
  bookmarks: {},
50
48
  experiments: {},
51
- oauth_token: faker.internet.url(),
52
- oauth_initiate: faker.internet.url(),
49
+ oauth_token: faker.url(),
50
+ oauth_initiate: faker.url(),
53
51
  };
54
52
  };
package/src/api/tags.ts CHANGED
@@ -1,14 +1,17 @@
1
1
  import * as prismicT from "@prismicio/types";
2
2
 
3
+ import { createFaker } from "../lib/createFaker";
3
4
  import { generateTags } from "../lib/generateTags";
4
5
 
5
6
  import { MockRestApiConfig } from "../types";
6
7
 
7
8
  export type MockRestApiTagsConfig = MockRestApiConfig;
8
9
 
9
- export const tags = (config: MockRestApiTagsConfig = {}): prismicT.Tags => {
10
+ export const tags = (config: MockRestApiTagsConfig): prismicT.Tags => {
11
+ const faker = config.faker || createFaker(config.seed);
12
+
10
13
  return generateTags({
11
- seed: config.seed,
14
+ faker,
12
15
  min: 1,
13
16
  max: 10,
14
17
  });
@@ -0,0 +1,52 @@
1
+ import { createFaker, Faker } from "./lib/createFaker";
2
+
3
+ import { Seed } from "./types";
4
+
5
+ import {
6
+ createModelMockFactory,
7
+ ModelMockFactory,
8
+ } from "./model/createModelMockFactory";
9
+ import {
10
+ createValueMockFactory,
11
+ ValueMockFactory,
12
+ } from "./value/createValueMockFactory";
13
+ import {
14
+ createAPIMockFactory,
15
+ APIMockFactory,
16
+ } from "./api/createAPIMockFactory";
17
+
18
+ export const createMockFactory = (
19
+ ...args: ConstructorParameters<typeof MockFactory>
20
+ ): MockFactory => {
21
+ return new MockFactory(...args);
22
+ };
23
+
24
+ type PrismicMockConfig =
25
+ | {
26
+ seed: Seed;
27
+ faker?: never;
28
+ }
29
+ | {
30
+ faker: Faker;
31
+ seed?: never;
32
+ };
33
+
34
+ export class MockFactory {
35
+ private faker: Faker;
36
+
37
+ api: APIMockFactory;
38
+ model: ModelMockFactory;
39
+ value: ValueMockFactory;
40
+
41
+ constructor(config: PrismicMockConfig) {
42
+ this.faker = config.faker || createFaker(config.seed);
43
+
44
+ this.api = createAPIMockFactory({ faker: this.faker });
45
+ this.model = createModelMockFactory({ faker: this.faker });
46
+ this.value = createValueMockFactory({ faker: this.faker });
47
+ }
48
+
49
+ get seed() {
50
+ return this.faker.seed;
51
+ }
52
+ }
package/src/index.ts CHANGED
@@ -1,3 +1,18 @@
1
1
  export * as api from "./api";
2
2
  export * as model from "./model";
3
3
  export * as value from "./value";
4
+
5
+ export { createMockFactory, MockFactory } from "./createMockFactory";
6
+
7
+ export {
8
+ createAPIMockFactory,
9
+ APIMockFactory,
10
+ } from "./api/createAPIMockFactory";
11
+ export {
12
+ createModelMockFactory,
13
+ ModelMockFactory,
14
+ } from "./model/createModelMockFactory";
15
+ export {
16
+ createValueMockFactory,
17
+ ValueMockFactory,
18
+ } from "./value/createValueMockFactory";
@@ -1,38 +1,36 @@
1
1
  import * as prismicT from "@prismicio/types";
2
- import * as changeCase from "change-case";
3
2
 
4
- import { createFaker } from "../lib/createFaker";
3
+ import { createFaker, Faker } from "../lib/createFaker";
5
4
 
6
- import { MockEmbedData, MockValueConfig } from "../types";
5
+ import { Seed } from "../types";
7
6
 
8
- type BuildEmbedFieldConfig = {
9
- embedData: MockEmbedData;
10
- } & Pick<MockValueConfig, "seed">;
7
+ type BuildEmbedFieldConfig<
8
+ Data extends prismicT.AnyOEmbed = prismicT.AnyOEmbed,
9
+ > = {
10
+ url?: string;
11
+ html?: string;
12
+ data: Data;
13
+ } & (
14
+ | {
15
+ seed: Seed;
16
+ faker?: never;
17
+ }
18
+ | {
19
+ faker: Faker;
20
+ seed?: never;
21
+ }
22
+ );
11
23
 
12
- export const buildEmbedField = (
13
- config: BuildEmbedFieldConfig,
14
- ): prismicT.EmbedField<false> => {
15
- const faker = createFaker(config.seed);
24
+ export const buildEmbedField = <
25
+ Data extends prismicT.AnyOEmbed = prismicT.AnyOEmbed,
26
+ >(
27
+ config: BuildEmbedFieldConfig<Data>,
28
+ ): prismicT.EmbedField<Data, "filled"> => {
29
+ const faker = config.faker || createFaker(config.seed);
16
30
 
17
31
  return {
18
- type: faker.datatype.boolean()
19
- ? prismicT.EmbedType.Link
20
- : prismicT.EmbedType.Rich,
21
- url: config.embedData.url,
22
- html: config.embedData.html,
23
- title: changeCase.capitalCase(faker.lorem.words(3)),
24
- version: faker.datatype
25
- .number({ min: 1, max: 3, precision: 10 })
26
- .toString(),
27
- cache_age: faker.datatype.number(),
28
- embed_url: config.embedData.embed_url,
29
- author_url: faker.internet.url(),
30
- author_name: faker.company.companyName(),
31
- provider_name: faker.company.companyName(),
32
- thumbnail_width: config.embedData.thumbnail_width,
33
- thumbnail_height: config.embedData.thumbnail_height,
34
- thumbnail_url: config.embedData.thumbnail_url,
35
- width: faker.datatype.number({ min: 200, max: 500 }),
36
- height: faker.datatype.number({ min: 200, max: 500 }),
37
- };
32
+ embed_url: config.url ?? faker.url(),
33
+ html: `<div>embed html</div>`,
34
+ ...config.data,
35
+ } as prismicT.EmbedField<Data, "filled">;
38
36
  };
@@ -1,15 +1,27 @@
1
1
  import * as prismicT from "@prismicio/types";
2
+ import * as changeCase from "change-case";
2
3
 
3
- import { createFaker } from "../lib/createFaker";
4
+ import { createFaker, Faker } from "../lib/createFaker";
4
5
 
5
- import { MockValueStateConfig, MockImageData, MockValueConfig } from "../types";
6
+ import { MockValueStateConfig, MockImageData, Seed } from "../types";
6
7
 
7
8
  type BuildImageFieldConfig<
8
9
  State extends prismicT.FieldState = prismicT.FieldState,
9
10
  > = {
10
11
  imageData: MockImageData;
11
- constraint?: prismicT.CustomTypeModelImageField["config"]["constraint"];
12
- } & Pick<MockValueConfig, "seed"> &
12
+ constraint?: NonNullable<
13
+ prismicT.CustomTypeModelImageField["config"]
14
+ >["constraint"];
15
+ } & (
16
+ | {
17
+ seed: Seed;
18
+ faker?: never;
19
+ }
20
+ | {
21
+ faker: Faker;
22
+ seed?: never;
23
+ }
24
+ ) &
13
25
  Pick<MockValueStateConfig<State>, "state">;
14
26
 
15
27
  export const buildImageFieldImage = <
@@ -25,7 +37,7 @@ export const buildImageFieldImage = <
25
37
  copyright: null,
26
38
  } as prismicT.ImageFieldImage<State>;
27
39
  } else {
28
- const faker = createFaker(config.seed);
40
+ const faker = config.faker || createFaker(config.seed);
29
41
 
30
42
  const url = new URL(config.imageData.url);
31
43
 
@@ -41,8 +53,8 @@ export const buildImageFieldImage = <
41
53
  return {
42
54
  url: url.toString(),
43
55
  dimensions,
44
- alt: faker.lorem.sentence(),
45
- copyright: faker.lorem.sentence(),
56
+ alt: changeCase.sentenceCase(faker.words(faker.range(5, 15))),
57
+ copyright: changeCase.sentenceCase(faker.words(faker.range(5, 15))),
46
58
  } as prismicT.ImageFieldImage<State>;
47
59
  }
48
60
  };
@@ -1,31 +1,108 @@
1
- import * as fakerStatic from "faker";
2
- // @ts-expect-error - Missing .d.ts
3
- import * as fakerLocaleEN from "faker/lib/locales/en/index.js";
4
- // @ts-expect-error - Missing .d.ts
5
- import Faker from "faker/lib/index.js";
1
+ import Rand from "rand-seed";
6
2
 
7
- import { FAKER_SEED } from "../constants";
3
+ import { Seed } from "../types";
8
4
 
9
- export const createFaker = (seed = FAKER_SEED): typeof fakerStatic => {
10
- let normalizedSeed: number | number[];
11
- if (typeof seed === "string") {
12
- normalizedSeed = seed.split("").map((char) => char.charCodeAt(0));
13
- } else {
14
- normalizedSeed = seed;
5
+ import { lorem, loremWords } from "./lorem";
6
+
7
+ export const createFaker = (seed: Seed): Faker => {
8
+ return new Faker(seed);
9
+ };
10
+
11
+ const DAY_MS = 1000 * 60 * 60 * 24;
12
+ const YEAR_MS = DAY_MS * 365;
13
+ const YEAR_2022_MS = 52 * (YEAR_MS + DAY_MS / 4);
14
+
15
+ export class Faker {
16
+ seed: Seed;
17
+
18
+ private rand: Rand;
19
+
20
+ constructor(seed: Seed) {
21
+ this.seed = seed;
22
+
23
+ this.rand = new Rand(seed.toString());
15
24
  }
16
25
 
17
- const cacheKey = JSON.stringify(normalizedSeed);
26
+ boolean(): boolean {
27
+ return this.random() >= 0.5;
28
+ }
18
29
 
19
- if (createFaker.cache[cacheKey]) {
20
- return createFaker.cache[cacheKey];
30
+ random(): number {
31
+ return this.rand.next();
21
32
  }
22
33
 
23
- const fakerInstance = new Faker();
24
- fakerInstance.locales["en"] = fakerLocaleEN;
25
- fakerInstance.seed(normalizedSeed);
34
+ randomElement<T>(elements: readonly T[]): T {
35
+ return elements[this.range(0, elements.length)];
36
+ }
26
37
 
27
- createFaker.cache[cacheKey] = fakerInstance;
38
+ randomElements<T>(elements: readonly T[]): T[] {
39
+ const alwaysInclude = this.randomElement(elements);
28
40
 
29
- return fakerInstance;
30
- };
31
- createFaker.cache = {} as Record<string, typeof fakerStatic>;
41
+ return elements.filter(
42
+ (element) => element === alwaysInclude || this.boolean(),
43
+ );
44
+ }
45
+
46
+ range(min: number, max: number): number {
47
+ return Math.floor(this.rangeFloat(Math.ceil(min), Math.floor(max)));
48
+ }
49
+
50
+ rangeFloat(min: number, max: number): number {
51
+ return this.random() * (max - min) + min;
52
+ }
53
+
54
+ words(length: number, wordOffset = this.range(0, loremWords.length)): string {
55
+ return lorem(`${length}w`, wordOffset);
56
+ }
57
+
58
+ word(): string {
59
+ return this.randomElement(loremWords);
60
+ }
61
+
62
+ lorem(
63
+ length: Parameters<typeof lorem>[0],
64
+ wordOffset = this.range(0, loremWords.length),
65
+ ): string {
66
+ return lorem(length, wordOffset);
67
+ }
68
+
69
+ url(): string {
70
+ return `https://${this.word()}.example`;
71
+ }
72
+
73
+ hexColor(): string {
74
+ return `#${this.hash(6)}`;
75
+ }
76
+
77
+ hash(length: number): string {
78
+ let hash = "";
79
+
80
+ for (let i = 0; i < length; i++) {
81
+ const chars = this.boolean() ? "abcdef" : "0123456789";
82
+
83
+ hash += chars[this.range(0, chars.length)];
84
+ }
85
+
86
+ return hash;
87
+ }
88
+
89
+ date(): Date {
90
+ return new Date(YEAR_2022_MS + this.range(-YEAR_MS * 3, YEAR_MS * 3));
91
+ }
92
+
93
+ dateAfter(date: Date): Date {
94
+ const timestamp = date.getTime();
95
+
96
+ return new Date(this.range(timestamp, timestamp + YEAR_MS * 3));
97
+ }
98
+
99
+ dateBefore(date: Date): Date {
100
+ const timestamp = date.getTime();
101
+
102
+ return new Date(this.range(timestamp - YEAR_MS * 3, timestamp));
103
+ }
104
+
105
+ dateBetween(min: Date, max: Date): Date {
106
+ return new Date(this.range(min.getTime(), max.getTime()));
107
+ }
108
+ }
@@ -1,13 +1,21 @@
1
1
  import * as changeCase from "change-case";
2
2
 
3
- import { createFaker } from "../lib/createFaker";
3
+ import { createFaker, Faker } from "../lib/createFaker";
4
4
 
5
- import { MockModelConfig } from "../types";
5
+ import { Seed } from "../types";
6
6
 
7
- type GenerateFieldIdConfig = Pick<MockModelConfig, "seed">;
7
+ type GenerateFieldIdConfig =
8
+ | {
9
+ seed: Seed;
10
+ faker?: never;
11
+ }
12
+ | {
13
+ faker: Faker;
14
+ seed?: never;
15
+ };
8
16
 
9
17
  export const generateCustomTypeId = (config: GenerateFieldIdConfig): string => {
10
- const faker = createFaker(config.seed);
18
+ const faker = config.faker || createFaker(config.seed);
11
19
 
12
- return changeCase.snakeCase(faker.company.bsNoun());
20
+ return changeCase.snakeCase(faker.words(faker.range(1, 3)));
13
21
  };
@@ -1,15 +1,21 @@
1
1
  import * as changeCase from "change-case";
2
2
 
3
- import { createFaker } from "../lib/createFaker";
3
+ import { createFaker, Faker } from "../lib/createFaker";
4
4
 
5
- import { MockModelConfig } from "../types";
5
+ import { Seed } from "../types";
6
6
 
7
- type GenerateFieldIdConfig = Pick<MockModelConfig, "seed">;
7
+ type GenerateFieldIdConfig =
8
+ | {
9
+ seed: Seed;
10
+ faker?: never;
11
+ }
12
+ | {
13
+ faker: Faker;
14
+ seed?: never;
15
+ };
8
16
 
9
17
  export const generateFieldId = (config: GenerateFieldIdConfig): string => {
10
- const faker = createFaker(config.seed);
18
+ const faker = config.faker || createFaker(config.seed);
11
19
 
12
- return changeCase.snakeCase(
13
- faker.lorem.words(faker.datatype.number({ min: 1, max: 3 })),
14
- );
20
+ return changeCase.snakeCase(faker.words(faker.range(1, 3)));
15
21
  };