sb-mig 5.2.2 → 5.3.0-beta.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.
@@ -13,7 +13,15 @@ export const getAllComponents = (config) => {
13
13
  apiFn: ({ per_page, page }) => sbApi
14
14
  .get(`spaces/${spaceId}/components/`, { per_page, page })
15
15
  .then((res) => {
16
- Logger.log(`Amount of components: ${res.total}`);
16
+ /**
17
+ *
18
+ * Not every endpoint in storyblok give us pagination...
19
+ * so only for this who paginate we want to console log amount found.
20
+ *
21
+ * */
22
+ if (res.total) {
23
+ Logger.log(`Amount of components: ${res.total}`);
24
+ }
17
25
  return res;
18
26
  })
19
27
  .catch((err) => console.error(err)),
@@ -116,7 +124,15 @@ export const getAllComponentsGroups = async (config) => {
116
124
  apiFn: ({ per_page, page }) => sbApi
117
125
  .get(`spaces/${spaceId}/component_groups/`, { per_page, page })
118
126
  .then((res) => {
119
- Logger.log(`Amount of component groups: ${res.total}`);
127
+ /**
128
+ *
129
+ * Not every endpoint in storyblok give us pagination...
130
+ * so only for this who paginate we want to console log amount found.
131
+ *
132
+ * */
133
+ if (res.total) {
134
+ Logger.log(`Amount of component groups: ${res.total}`);
135
+ }
120
136
  return res;
121
137
  })
122
138
  .catch((err) => console.error(err)),
@@ -7,22 +7,27 @@ export const getAllDatasources = (config) => {
7
7
  const { sbApi, spaceId } = config;
8
8
  Logger.log("Trying to get all Datasources.");
9
9
  return getAllItemsWithPagination({
10
- apiFn: ({ per_page, page }) => sbApi
11
- .get(`spaces/${spaceId}/datasources/`, { per_page, page })
12
- .then((res) => {
13
- Logger.log(`Amount of datasources: ${res.total}`);
14
- return res;
15
- })
16
- .catch((err) => {
17
- if (err.response.status === 404) {
18
- Logger.error(`There is no datasources in your Storyblok ${spaceId} space.`);
19
- return true;
20
- }
21
- else {
22
- Logger.error(err);
23
- return false;
24
- }
25
- }),
10
+ // @ts-ignore
11
+ apiFn: ({ per_page, page }) => {
12
+ return sbApi
13
+ .get(`spaces/${spaceId}/datasources/`)
14
+ .then((res) => {
15
+ if (res.total) {
16
+ Logger.log(`Amount of datasources: ${res.total}`);
17
+ }
18
+ return res;
19
+ })
20
+ .catch((err) => {
21
+ if (err.response.status === 404) {
22
+ Logger.error(`There is no datasources in your Storyblok ${spaceId} space.`);
23
+ return true;
24
+ }
25
+ else {
26
+ Logger.error(err);
27
+ return false;
28
+ }
29
+ });
30
+ },
26
31
  params: {
27
32
  spaceId,
28
33
  },
@@ -1,5 +1,5 @@
1
1
  import { apiConfig } from "../cli/api-config.js";
2
- import { compare, discover, discoverMany, discoverManyByPackageName, discoverStories, LOOKUP_TYPE, SCOPE, } from "../cli/utils/discover.js";
2
+ import { compare, discover, discoverMany, discoverManyByPackageName, discoverResolvers, discoverStories, LOOKUP_TYPE, SCOPE, } from "../cli/utils/discover.js";
3
3
  import { dumpToFile } from "../utils/files.js";
4
4
  import Logger from "../utils/logger.js";
5
5
  import { getFileContentWithRequire, getFilesContentWithRequire, isObjectEmpty, } from "../utils/main.js";
@@ -10,11 +10,9 @@ import { backupStories } from "./stories/backup.js";
10
10
  import { getAllStories } from "./stories/stories.js";
11
11
  import { createTree, traverseAndCreate } from "./stories/tree.js";
12
12
  import { _uniqueValuesFrom } from "./utils/helper-functions.js";
13
+ import { resolverTransformations } from "./utils/resolverTransformations.js";
13
14
  const _checkAndPrepareGroups = async (groupsToCheck, config) => {
14
15
  const componentsGroups = await managementApi.components.getAllComponentsGroups(config);
15
- console.log("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@");
16
- console.log(componentsGroups);
17
- console.log("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@");
18
16
  const groupExist = (groupName) => componentsGroups.find((group) => group.name === groupName);
19
17
  groupsToCheck.forEach(async (groupName) => {
20
18
  if (!groupExist(groupName)) {
@@ -59,9 +57,22 @@ const _resolveGroups = async (component, existedGroups, remoteComponentsGroups)
59
57
  };
60
58
  export const syncComponents = async (specifiedComponents, presets, config) => {
61
59
  Logger.log("sync2Components: ");
62
- const specifiedComponentsContent = await Promise.all(specifiedComponents.map((component) => {
60
+ let specifiedComponentsContent = await Promise.all(specifiedComponents.map((component) => {
63
61
  return getFileContentWithRequire({ file: component.p });
64
62
  }));
63
+ const resolversFilenames = await discoverResolvers({
64
+ scope: SCOPE.local,
65
+ type: LOOKUP_TYPE.fileName,
66
+ });
67
+ /*
68
+ * if resolversFilenames exist, then do stuff if not, than follow with the old approach
69
+ * */
70
+ if (resolversFilenames.length !== 0) {
71
+ const resolverFilesContent = await Promise.all(resolversFilenames.map((filename) => {
72
+ return getFileContentWithRequire({ file: filename });
73
+ }));
74
+ specifiedComponentsContent = resolverTransformations(specifiedComponentsContent, resolverFilesContent);
75
+ }
65
76
  const groupsToCheck = _uniqueValuesFrom(specifiedComponentsContent
66
77
  .filter((component) => component.component_group_name)
67
78
  .map((component) => component.component_group_name));
@@ -10,11 +10,21 @@ export const getAllItemsWithPagination = async ({ apiFn, params, itemsKey, }) =>
10
10
  if (!totalPages) {
11
11
  totalPages = Math.ceil(response.total / response.perPage);
12
12
  }
13
- amountOfFetchedItems +=
14
- response.total - amountOfFetchedItems > per_page
15
- ? per_page
16
- : response.total - amountOfFetchedItems;
17
- Logger.success(`${amountOfFetchedItems} of ${response.total} items fetched.`);
13
+ /**
14
+ *
15
+ * Not every endpoint in storyblok give us pagination...
16
+ * so only for this who paginate we want to calculate values to show
17
+ *
18
+ * */
19
+ if (response.total) {
20
+ amountOfFetchedItems +=
21
+ response.total - amountOfFetchedItems > per_page
22
+ ? per_page
23
+ : response.total - amountOfFetchedItems;
24
+ if (amountOfFetchedItems && !Number.isNaN(amountOfFetchedItems)) {
25
+ Logger.success(`${amountOfFetchedItems} of ${response.total} items fetched.`);
26
+ }
27
+ }
18
28
  allItems.push(...response.data[itemsKey]);
19
29
  page++;
20
30
  } while (page <= totalPages);
@@ -0,0 +1 @@
1
+ export declare const resolverTransformations: (specifiedComponentsContent: any, resolverFilesContent: any) => any[];
@@ -0,0 +1,67 @@
1
+ const extendField = (obj, targetField, newValue) => {
2
+ if (typeof obj !== "object" || obj === null) {
3
+ return false;
4
+ }
5
+ if (obj.hasOwnProperty(targetField)) {
6
+ if (Array.isArray(obj[targetField])) {
7
+ for (const element of newValue) {
8
+ if (!obj[targetField].includes(element)) {
9
+ obj[targetField] = [...obj[targetField], element];
10
+ }
11
+ }
12
+ }
13
+ else if (typeof obj[targetField] === "object") {
14
+ // this is something i have to fix, comparing to object is stupid
15
+ obj[targetField] = { ...obj[targetField], ...newValue };
16
+ }
17
+ return true;
18
+ }
19
+ for (const key in obj) {
20
+ if (extendField(obj[key], targetField, newValue)) {
21
+ return true;
22
+ }
23
+ }
24
+ return false;
25
+ };
26
+ const resolveAll = (resolver, componentsContent) => {
27
+ if (!resolver.all)
28
+ return componentsContent;
29
+ return componentsContent;
30
+ };
31
+ const resolveComponentGroupNames = (resolver, componentsContent) => {
32
+ if (!resolver.componentGroupNames)
33
+ return componentsContent;
34
+ return componentsContent;
35
+ };
36
+ const resolveComponentNames = (resolver, componentsContent) => {
37
+ if (!resolver.componentNames)
38
+ return componentsContent;
39
+ const componentNamesResolver = resolver.componentNames;
40
+ componentsContent.map((component) => {
41
+ if (componentNamesResolver.names.includes(component.name)) {
42
+ const targetField = Object.keys(componentNamesResolver.methods.extend)[0];
43
+ console.log("This is target field ?");
44
+ console.log(targetField);
45
+ extendField(component, targetField, componentNamesResolver.methods.extend[targetField]);
46
+ }
47
+ return component;
48
+ });
49
+ return componentsContent;
50
+ };
51
+ export const resolverTransformations = (specifiedComponentsContent, resolverFilesContent) => {
52
+ let resolvedComponents = [];
53
+ console.log("#### Specified Components Content to Resolve ####");
54
+ console.log(specifiedComponentsContent);
55
+ console.log("#### Resolver Files Content ####");
56
+ console.log(resolverFilesContent);
57
+ const resolver = resolverFilesContent[0];
58
+ console.log("kjashdkjhaskjdh");
59
+ console.log(resolver);
60
+ // resolvedComponents = resolveAll(resolver, specifiedComponentsContent)
61
+ // resolvedComponents = resolveComponentGroupNames(resolver, resolvedComponents)
62
+ resolvedComponents = resolveComponentNames(resolver, specifiedComponentsContent);
63
+ console.log("@@@@@@@@");
64
+ console.log(resolvedComponents[0].schema);
65
+ console.log("@@@@@@@@");
66
+ return resolvedComponents;
67
+ };
@@ -7,4 +7,5 @@ export declare const migrationsDescription = "\n Usage\n $ sb-mig migr
7
7
  export declare const removeDescription = "\n Usage\n $ sb-mig remove [components|roles|datasources] [space separated file names] or --all \n \n Description\n Remove components or roles with Storyblok space.\n \n COMMANDS\n components - remove components\n roles - remove roles\n datasources - remove datasources\n \n FLAGS\n --all - Remove all components \n \n EXAMPLES\n $ sb-mig remove components --all\n $ sb-mig remove components accordion accordion-item\n $ sb-mig remove roles --all\n $ sb-mig remove datasources --all\n";
8
8
  export declare const backupDescription = "\n Usage\n $ sb-mig backup [components|component-groups|roles|datasources|presets|component-presets] component-name or --all\n Description\n Command for backing up anything related to Storyblok\n \n COMMANDS\n components - backup components\n component-groups - backup component-groups\n roles - backup components\n datasources - backup components\n presets - backup presets\n component-presets - backup component presets\n plugins - backup plugins\n stories - backup stories (only --all)\n\n \n FLAGS\n --all - Backup all \n \n EXAMPLES\n $ sb-mig backup components --all\n $ sb-mig backup components accordion \n $ sb-mig backup datasources --all\n $ sb-mig backup roles admin\n $ sb-mig backup plugins --all\n $ sb-mig backup plugins my-awesome-plugin\n $ sb-mig backup stories --all\n";
9
9
  export declare const debugDescription = "\n Usage\n $ sb-mig debug\n Description\n Output extra debugging information\n";
10
+ export declare const askDescription = "\n !! ALPHA !!!\n Usage\n $ sb-mig ask \"What sb-mig version am I using?\"\n $ sb-mig ask \"What is the schema type i should write?\"\n $ sb-mig ask \"Is debug mode turned on ?\"\n $ sb-mig ask \"What storyblok api urls I am using?\"\n Description\n Ask sb-mig about anything, especially stuff related to sb-mig and storyblok components.\n \n Needs OPENAI_API_KEY= environment set in your project. (Config will pick it up automatically, no need to modify\n storyblok.config.[c|m]js file\n \n Also, right now, you need to install @mrck-labs/anton-sdk in your project, since its not bundled.\n";
10
11
  export declare const initDescription = "\n Usage\n $ sb-mig init\n Description\n Init and update your project\n";
@@ -185,6 +185,21 @@ export const debugDescription = `
185
185
  Description
186
186
  Output extra debugging information
187
187
  `;
188
+ export const askDescription = `
189
+ !! ALPHA !!!
190
+ Usage
191
+ $ sb-mig ask "What sb-mig version am I using?"
192
+ $ sb-mig ask "What is the schema type i should write?"
193
+ $ sb-mig ask "Is debug mode turned on ?"
194
+ $ sb-mig ask "What storyblok api urls I am using?"
195
+ Description
196
+ Ask sb-mig about anything, especially stuff related to sb-mig and storyblok components.
197
+
198
+ Needs OPENAI_API_KEY= environment set in your project. (Config will pick it up automatically, no need to modify
199
+ storyblok.config.[c|m]js file
200
+
201
+ Also, right now, you need to install @mrck-labs/anton-sdk in your project, since its not bundled.
202
+ `;
188
203
  export const initDescription = `
189
204
  Usage
190
205
  $ sb-mig init
@@ -0,0 +1,2 @@
1
+ import type { CLIOptions } from "../../utils/interfaces.js";
2
+ export declare const ask: (props: CLIOptions) => Promise<void>;
@@ -0,0 +1,49 @@
1
+ import path from "path";
2
+ import { Anton } from "@mrck-labs/anton-sdk";
3
+ import config from "../../config/config.js";
4
+ import Logger from "../../utils/logger.js";
5
+ import { getFileContentWithRequire } from "../../utils/main.js";
6
+ export const ask = async (props) => {
7
+ const { input, flags } = props;
8
+ try {
9
+ const fileContent = await getFileContentWithRequire({
10
+ file: path.join("..", "..", "package.json"),
11
+ });
12
+ const anton = new Anton(config.openaiToken);
13
+ const question = input[1];
14
+ const cleanPackageJSON = {
15
+ ...fileContent,
16
+ };
17
+ const cleanStoryblokConfig = {
18
+ ...config,
19
+ oauthToken: "hidden",
20
+ openaiToken: "hidden",
21
+ };
22
+ Logger.warning("Got it! Thinking...");
23
+ const data = await anton.chatCompletion({
24
+ body: {
25
+ messages: [
26
+ {
27
+ role: "system",
28
+ content: `Giving below context which is json object, answer the question asked with ONLY on using the CONTEXT.
29
+ If u dont know the answet to question, simply say don't know. DO NOT try to generate answers at all cost if the context
30
+ doesnt give you the answer.
31
+ ### context start ###
32
+ ${JSON.stringify(cleanStoryblokConfig, null, 2)}
33
+ ${JSON.stringify(cleanPackageJSON, null, 2)}
34
+ ### context end ###
35
+ `,
36
+ },
37
+ {
38
+ role: "user",
39
+ content: question,
40
+ },
41
+ ],
42
+ },
43
+ });
44
+ Logger.success(data?.choices[0]?.message?.content);
45
+ }
46
+ catch (e) {
47
+ Logger.warning("Can't find package.json");
48
+ }
49
+ };
package/dist/cli/index.js CHANGED
@@ -1,7 +1,8 @@
1
1
  #! /usr/bin/env node
2
2
  import meow from "meow";
3
3
  import { pipe, prop } from "../utils/main.js";
4
- import { backupDescription, debugDescription, mainDescription, syncDescription, removeDescription, initDescription, discoverDescription, migrateDescription, revertDescription, migrationsDescription, } from "./cli-descriptions.js";
4
+ import { backupDescription, debugDescription, mainDescription, syncDescription, removeDescription, initDescription, discoverDescription, migrateDescription, revertDescription, migrationsDescription, askDescription, } from "./cli-descriptions.js";
5
+ import { ask } from "./commands/ask.js";
5
6
  import { backup } from "./commands/backup.js";
6
7
  import { debug } from "./commands/debug.js";
7
8
  import { discover } from "./commands/discover.js";
@@ -104,6 +105,15 @@ app.debug = () => ({
104
105
  debug();
105
106
  },
106
107
  });
108
+ app.ask = () => ({
109
+ cli: meow(askDescription, {
110
+ importMeta: import.meta,
111
+ booleanDefault: undefined,
112
+ }),
113
+ action: (cli) => {
114
+ ask(cli);
115
+ },
116
+ });
107
117
  app.init = () => ({
108
118
  cli: meow(initDescription, {
109
119
  importMeta: import.meta,
@@ -56,6 +56,7 @@ export declare const filesPattern: ({ mainDirectory, componentDirectories, ext,
56
56
  ext: string;
57
57
  }) => string;
58
58
  export declare const discover: (request: DiscoverRequest) => Promise<DiscoverResult>;
59
+ export declare const discoverResolvers: (request: DiscoverRequest) => Promise<DiscoverResult>;
59
60
  export declare const discoverRoles: (request: DiscoverRequest) => Promise<DiscoverResult>;
60
61
  export declare const discoverManyRoles: (request: DiscoverManyRequest) => Promise<DiscoverResult>;
61
62
  export declare const discoverAllComponents: () => Promise<{
@@ -525,6 +525,46 @@ export const discover = async (request) => {
525
525
  }
526
526
  return listOfFiles;
527
527
  };
528
+ export const discoverResolvers = async (request) => {
529
+ const rootDirectory = ".";
530
+ const directory = path.resolve(process.cwd(), rootDirectory);
531
+ let pattern;
532
+ let listOfFiles = [""];
533
+ switch (request.scope) {
534
+ case SCOPE.local:
535
+ // ### ALL - LOCAL - fileName ###
536
+ let listOFSchemaTSFilesCompiled = [];
537
+ const onlyLocalComponentsDirectories = storyblokConfig.componentsDirectories.filter((p) => !p.includes("node_modules"));
538
+ if (storyblokConfig.schemaType === SCHEMA.TS) {
539
+ pattern = filesPattern({
540
+ mainDirectory: directory,
541
+ componentDirectories: onlyLocalComponentsDirectories,
542
+ ext: "resolvers.schema.sb.ts",
543
+ });
544
+ const listOfFilesToCompile = glob.sync(pattern.replace(/\\/g, "/"), {
545
+ follow: true,
546
+ });
547
+ await buildOnTheFly({ files: listOfFilesToCompile });
548
+ pattern = path.join(directory, ".next", "cache", "sb-mig", "**", `[^_]*.resolvers.schema.sb.cjs`);
549
+ listOFSchemaTSFilesCompiled = glob.sync(pattern.replace(/\\/g, "/"), {
550
+ follow: true,
551
+ });
552
+ }
553
+ pattern = filesPattern({
554
+ mainDirectory: directory,
555
+ componentDirectories: onlyLocalComponentsDirectories,
556
+ ext: "resolvers.schema.sb.cjs",
557
+ });
558
+ listOfFiles = glob.sync(pattern.replace(/\\/g, "/"), {
559
+ follow: true,
560
+ });
561
+ listOfFiles = [...listOfFiles, ...listOFSchemaTSFilesCompiled];
562
+ break;
563
+ default:
564
+ break;
565
+ }
566
+ return listOfFiles;
567
+ };
528
568
  export const discoverRoles = async (request) => {
529
569
  const rootDirectory = ".";
530
570
  const directory = path.resolve(process.cwd(), rootDirectory);
@@ -25,6 +25,7 @@ export interface IStoryblokConfig {
25
25
  storyblokDeliveryApiUrl: string;
26
26
  storyblokGraphqlApiUrl: string;
27
27
  oauthToken: string;
28
+ openaiToken: string;
28
29
  spaceId: string;
29
30
  accessToken: string;
30
31
  boilerplateSpaceId: string;
@@ -2,20 +2,21 @@ export declare const SCHEMA: {
2
2
  readonly TS: "ts";
3
3
  readonly JS: "js";
4
4
  };
5
- export declare const storyblokApiMapping: {
5
+ export interface StoryblokApiMapping {
6
6
  eu: {
7
- managementApi: string;
8
- deliveryApi: string;
9
- graphql: string;
7
+ managementApi: "https://mapi.storyblok.com/v1";
8
+ deliveryApi: "https://api.storyblok.com/v2";
9
+ graphql: "https://gapi.storyblok.com/v1/api";
10
10
  };
11
11
  us: {
12
- managementApi: string;
13
- deliveryApi: string;
14
- graphql: string;
12
+ managementApi: "https://api-us.storyblok.com/v1";
13
+ deliveryApi: "https://api-us.storyblok.com/v2";
14
+ graphql: "https://gapi-us.storyblok.com/v1/api";
15
15
  };
16
16
  cn: {
17
- managementApi: string;
18
- deliveryApi: string;
19
- graphql: string;
17
+ managementApi: "https://app.storyblokchina.cn";
18
+ deliveryApi: "https://app.storyblokchina.cn";
19
+ graphql: "";
20
20
  };
21
- };
21
+ }
22
+ export declare const storyblokApiMapping: StoryblokApiMapping;
@@ -41,6 +41,7 @@ export const defaultConfig = (pkg, path, env) => {
41
41
  storyblokGraphqlApiUrl: env["NEXT_PUBLIC_STORYBLOK_GRAPHQL_API_URL"] ||
42
42
  "https://gapi.storyblok.com/v1/api",
43
43
  oauthToken: env["STORYBLOK_OAUTH_TOKEN"] ?? "",
44
+ openaiToken: env["OPENAI_API_KEY"] ?? "",
44
45
  spaceId: env["STORYBLOK_SPACE_ID"] ?? "",
45
46
  accessToken: env["GATSBY_STORYBLOK_ACCESS_TOKEN"] ||
46
47
  env["NEXT_PUBLIC_STORYBLOK_ACCESS_TOKEN"] ||
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "sb-mig",
3
- "version": "5.2.2",
3
+ "version": "5.3.0-beta.2",
4
4
  "description": "CLI to rule the world. (and handle stuff related to Storyblok CMS)",
5
5
  "author": "Marcin Krawczyk <marckraw@icloud.com>",
6
6
  "license": "MIT",
@@ -48,9 +48,11 @@
48
48
  "start": "yarn build && ./dist/cli/index.js",
49
49
  "debug": "yarn build && ./dist/cli/index.js sync components accordion accordion-item",
50
50
  "semantic-release": "semantic-release",
51
- "prepare": "husky install"
51
+ "prepare": "husky install",
52
+ "build:yalc": "yarn build && yalc push"
52
53
  },
53
54
  "dependencies": {
55
+ "@mrck-labs/anton-sdk": "^0.0.10",
54
56
  "@swc/core": "1.3.41",
55
57
  "@swc/helpers": "0.4.14",
56
58
  "chalk": "^5.3.0",
@@ -71,23 +73,23 @@
71
73
  "devDependencies": {
72
74
  "@commitlint/cli": "^17.7.1",
73
75
  "@commitlint/config-conventional": "^17.7.0",
74
- "@rollup/plugin-node-resolve": "^15.2.0",
76
+ "@rollup/plugin-node-resolve": "^15.2.3",
75
77
  "@ryansonshine/commitizen": "^4.2.8",
76
78
  "@ryansonshine/cz-conventional-changelog": "^3.3.4",
77
79
  "@semantic-release/changelog": "^6.0.3",
78
80
  "@semantic-release/git": "^10.0.1",
79
81
  "@sindresorhus/tsconfig": "^3.0.1",
80
- "@types/chai": "^4.3.5",
81
- "@types/fs-extra": "^11.0.1",
82
+ "@types/chai": "^4.3.10",
83
+ "@types/fs-extra": "^11.0.4",
82
84
  "@types/glob": "^8.1.0",
83
- "@types/mocha": "^10.0.1",
84
- "@types/ncp": "^2.0.5",
85
+ "@types/mocha": "^10.0.4",
86
+ "@types/ncp": "^2.0.8",
85
87
  "@types/node": "18.16.18",
86
88
  "@types/sinon": "^10.0.16",
87
- "@types/uuid": "^9.0.2",
89
+ "@types/uuid": "^9.0.7",
88
90
  "@typescript-eslint/eslint-plugin": "^6.4.1",
89
91
  "@typescript-eslint/parser": "^6.4.1",
90
- "chai": "^4.3.7",
92
+ "chai": "^4.3.10",
91
93
  "chokidar-cli": "^3.0.0",
92
94
  "eslint": "^8.47.0",
93
95
  "eslint-config-prettier": "^9.0.0",
@@ -96,7 +98,7 @@
96
98
  "husky": "^8.0.3",
97
99
  "lint-staged": "^13.2.3",
98
100
  "mocha": "^10.2.0",
99
- "prettier": "^3.0.2",
101
+ "prettier": "^3.0.3",
100
102
  "semantic-release": "^21.0.9",
101
103
  "semantic-release-slack-bot": "^4.0.1",
102
104
  "sinon": "^15.2.0",