@graphql-codegen/flutter-freezed 2.11.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.
Files changed (34) hide show
  1. package/cjs/config.js +2 -0
  2. package/cjs/freezed-declaration-blocks/class-block.js +221 -0
  3. package/cjs/freezed-declaration-blocks/factory-block.js +121 -0
  4. package/cjs/freezed-declaration-blocks/index.js +6 -0
  5. package/cjs/freezed-declaration-blocks/parameter-block.js +150 -0
  6. package/cjs/index.js +27 -0
  7. package/cjs/package.json +1 -0
  8. package/cjs/schema-visitor.js +15 -0
  9. package/cjs/utils.js +221 -0
  10. package/esm/config.js +1 -0
  11. package/esm/freezed-declaration-blocks/class-block.js +217 -0
  12. package/esm/freezed-declaration-blocks/factory-block.js +117 -0
  13. package/esm/freezed-declaration-blocks/index.js +3 -0
  14. package/esm/freezed-declaration-blocks/parameter-block.js +146 -0
  15. package/esm/index.js +23 -0
  16. package/esm/schema-visitor.js +11 -0
  17. package/esm/utils.js +209 -0
  18. package/package.json +46 -0
  19. package/typings/config.d.cts +453 -0
  20. package/typings/config.d.ts +453 -0
  21. package/typings/freezed-declaration-blocks/class-block.d.cts +36 -0
  22. package/typings/freezed-declaration-blocks/class-block.d.ts +36 -0
  23. package/typings/freezed-declaration-blocks/factory-block.d.cts +38 -0
  24. package/typings/freezed-declaration-blocks/factory-block.d.ts +38 -0
  25. package/typings/freezed-declaration-blocks/index.d.cts +3 -0
  26. package/typings/freezed-declaration-blocks/index.d.ts +3 -0
  27. package/typings/freezed-declaration-blocks/parameter-block.d.cts +45 -0
  28. package/typings/freezed-declaration-blocks/parameter-block.d.ts +45 -0
  29. package/typings/index.d.cts +3 -0
  30. package/typings/index.d.ts +3 -0
  31. package/typings/schema-visitor.d.cts +10 -0
  32. package/typings/schema-visitor.d.ts +10 -0
  33. package/typings/utils.d.cts +78 -0
  34. package/typings/utils.d.ts +78 -0
@@ -0,0 +1,146 @@
1
+ import { indent } from '@graphql-codegen/visitor-plugin-common';
2
+ import { camelCase } from 'change-case-all';
3
+ import { getCustomDecorators, transformCustomDecorators, FreezedConfigValue } from '../utils.js';
4
+ /**
5
+ * maps GraphQL scalar types to Dart's scalar types
6
+ */
7
+ export const DART_SCALARS = {
8
+ ID: 'String',
9
+ String: 'String',
10
+ Boolean: 'bool',
11
+ Int: 'int',
12
+ Float: 'double',
13
+ DateTime: 'DateTime',
14
+ };
15
+ export class FreezedParameterBlock {
16
+ constructor(_config, _appliesOn, _node, _field) {
17
+ this._config = _config;
18
+ this._appliesOn = _appliesOn;
19
+ this._node = _node;
20
+ this._field = _field;
21
+ /** document the property */
22
+ this._comment = '';
23
+ /** a list of decorators to copy paste to the generator */
24
+ this._decorators = [];
25
+ this.propertyType = (field, type, parentType) => {
26
+ if (this.isNonNullType(type)) {
27
+ return this.propertyType(field, type.type, type);
28
+ }
29
+ if (this.isListType(type)) {
30
+ const T = this.propertyType(field, type.type, type);
31
+ return `List<${T}>${this.isNonNullType(parentType) ? '' : '?'}`;
32
+ }
33
+ if (this.isNamedType(type)) {
34
+ return `${this.scalar(type.name.value)}${this.isNonNullType(parentType) ? '' : '?'}`;
35
+ }
36
+ return '';
37
+ };
38
+ this.isListType = (type) => (type === null || type === void 0 ? void 0 : type.kind) === 'ListType';
39
+ this.isNonNullType = (type) => (type === null || type === void 0 ? void 0 : type.kind) === 'NonNullType';
40
+ this.isNamedType = (type) => (type === null || type === void 0 ? void 0 : type.kind) === 'NamedType';
41
+ this._config = _config;
42
+ this._appliesOn = _appliesOn;
43
+ this._node = _node;
44
+ this._field = _field;
45
+ this._freezedConfigValue = new FreezedConfigValue(_config, _node.name.value);
46
+ }
47
+ init() {
48
+ this.setComment().setDecorators().setRequired().setType().setName().setShape().setBlock();
49
+ return this;
50
+ }
51
+ setComment() {
52
+ var _a;
53
+ const comment = (_a = this._field.description) === null || _a === void 0 ? void 0 : _a.value;
54
+ if (comment && comment !== null && comment !== '') {
55
+ this._comment = indent(`/// ${comment}\n`, 2);
56
+ }
57
+ return this;
58
+ }
59
+ setDecorators() {
60
+ var _a, _b, _c, _d, _e, _f, _g, _h;
61
+ const nodeName = this._node.name.value;
62
+ const fieldName = this._field.name.value;
63
+ // determine if should mark as deprecated
64
+ const isDeprecated = (_d = (_c = (_b = (_a = this._config.typeSpecificFreezedConfig) === null || _a === void 0 ? void 0 : _a[nodeName]) === null || _b === void 0 ? void 0 : _b.fields) === null || _c === void 0 ? void 0 : _c[fieldName]) === null || _d === void 0 ? void 0 : _d.deprecated;
65
+ const defaultValue = (_h = (_g = (_f = (_e = this._config.typeSpecificFreezedConfig) === null || _e === void 0 ? void 0 : _e[nodeName]) === null || _f === void 0 ? void 0 : _f.fields) === null || _g === void 0 ? void 0 : _g[fieldName]) === null || _h === void 0 ? void 0 : _h.defaultValue;
66
+ if (this._freezedConfigValue.get('alwaysUseJsonKeyName') || fieldName !== camelCase(fieldName)) {
67
+ this._decorators = [...this._decorators, `@JsonKey(name: '${fieldName}')`];
68
+ }
69
+ this._decorators = [
70
+ ...this._decorators,
71
+ ...transformCustomDecorators(getCustomDecorators(this._config, this._appliesOn, this._node.name.value, fieldName), this._node, this._field),
72
+ ];
73
+ // @deprecated
74
+ // if this._decorators doesn't include an @deprecated decorator but the field is marked as @deprecated...
75
+ if (!this._decorators.includes('@deprecated') && isDeprecated) {
76
+ this._decorators = [...this._decorators, '@deprecated'];
77
+ }
78
+ // @Default
79
+ if (defaultValue) {
80
+ //overwrite the customDecorator's defaultValue
81
+ this._decorators = this._decorators.filter(d => !d.startsWith('@Default'));
82
+ this._decorators = [...this._decorators, `@Default(value: ${defaultValue})`];
83
+ }
84
+ return this;
85
+ }
86
+ setRequired() {
87
+ this._required = this.isNonNullType(this._field.type);
88
+ return this;
89
+ }
90
+ setType() {
91
+ this._type = this.propertyType(this._field, this._field.type);
92
+ return this;
93
+ }
94
+ setName() {
95
+ this._name = camelCase(this._field.name.value);
96
+ return this;
97
+ }
98
+ /** compose the freezed constructor property */
99
+ setShape() {
100
+ var _a, _b, _c, _d;
101
+ let shape = '';
102
+ const nodeName = this._node.name.value;
103
+ const fieldName = this._field.name.value;
104
+ // determine if should mark as final
105
+ const isFinal = this._decorators.includes('final') ||
106
+ ((_d = (_c = (_b = (_a = this._config.typeSpecificFreezedConfig) === null || _a === void 0 ? void 0 : _a[nodeName]) === null || _b === void 0 ? void 0 : _b.fields) === null || _c === void 0 ? void 0 : _c[fieldName]) === null || _d === void 0 ? void 0 : _d.final);
107
+ //append comment
108
+ shape += this._comment;
109
+ // append the decorators
110
+ shape += this._decorators
111
+ .filter(d => d !== 'final')
112
+ .map(d => indent(`${d}\n`, 2))
113
+ .join('');
114
+ // append required for non-nullable types
115
+ shape += indent(this._required ? 'required ' : '', 2);
116
+ // append isFinal
117
+ shape += isFinal ? 'final ' : '';
118
+ // append the Dart Type, name and trailing comma
119
+ shape += `${this._type} ${this._name},\n`;
120
+ // store it in the shape
121
+ this._shape = shape;
122
+ return this;
123
+ }
124
+ /** composes the full block */
125
+ setBlock() {
126
+ this._block = this._shape;
127
+ return this;
128
+ }
129
+ scalar(_scalar) {
130
+ var _a, _b;
131
+ if ((_b = (_a = this._config) === null || _a === void 0 ? void 0 : _a.customScalars) === null || _b === void 0 ? void 0 : _b[_scalar]) {
132
+ return this._config.customScalars[_scalar];
133
+ }
134
+ if (DART_SCALARS[_scalar]) {
135
+ return DART_SCALARS[_scalar];
136
+ }
137
+ return _scalar;
138
+ }
139
+ /** returns the block */
140
+ toString() {
141
+ if (!this._block) {
142
+ throw new Error('FreezedParameterBlock: setShape must be called before calling toString()');
143
+ }
144
+ return this._block;
145
+ }
146
+ }
package/esm/index.js ADDED
@@ -0,0 +1,23 @@
1
+ import { oldVisit } from '@graphql-codegen/plugin-helpers';
2
+ import { transformSchemaAST } from '@graphql-codegen/schema-ast';
3
+ import { FreezedDeclarationBlock } from './freezed-declaration-blocks/index.js';
4
+ import { schemaVisitor } from './schema-visitor.js';
5
+ import { addFreezedImportStatements, DefaultFreezedPluginConfig } from './utils.js';
6
+ export const plugin = (schema, _documents, config) => {
7
+ // sets the defaults for the config
8
+ config = { ...new DefaultFreezedPluginConfig(config) };
9
+ const { schema: _schema, ast } = transformSchemaAST(schema, config);
10
+ const { freezedFactoryBlockRepository, ...visitor } = schemaVisitor(_schema, config);
11
+ const visitorResult = oldVisit(ast, { leave: visitor });
12
+ const generated = visitorResult.definitions.filter((def) => def instanceof FreezedDeclarationBlock);
13
+ return (addFreezedImportStatements(config.fileName) +
14
+ generated
15
+ .map(freezedDeclarationBlock => freezedDeclarationBlock.toString().replace(/==>factory==>.+/gm, s => {
16
+ const pattern = s.replace('==>factory==>', '').trim();
17
+ const [key, appliesOn, name, typeName] = pattern.split('==>');
18
+ return freezedFactoryBlockRepository.retrieve(key, appliesOn, name, typeName !== null && typeName !== void 0 ? typeName : null).toString();
19
+ }))
20
+ .join('')
21
+ .trim() +
22
+ '\n');
23
+ };
@@ -0,0 +1,11 @@
1
+ import { FreezedFactoryBlockRepository, transformDefinition } from './utils.js';
2
+ export const schemaVisitor = (_schema, config) => {
3
+ const freezedFactoryBlockRepository = new FreezedFactoryBlockRepository();
4
+ return {
5
+ freezedFactoryBlockRepository,
6
+ EnumTypeDefinition: (node) => transformDefinition(config, freezedFactoryBlockRepository, node),
7
+ UnionTypeDefinition: (node) => transformDefinition(config, freezedFactoryBlockRepository, node),
8
+ ObjectTypeDefinition: (node) => transformDefinition(config, freezedFactoryBlockRepository, node),
9
+ InputObjectTypeDefinition: (node) => transformDefinition(config, freezedFactoryBlockRepository, node),
10
+ };
11
+ };
package/esm/utils.js ADDED
@@ -0,0 +1,209 @@
1
+ import { FreezedDeclarationBlock } from './freezed-declaration-blocks/index.js';
2
+ export function transformDefinition(config, freezedFactoryBlockRepository, node) {
3
+ var _a;
4
+ // ignore these...
5
+ if (['Query', 'Mutation', 'Subscription', ...((_a = config === null || config === void 0 ? void 0 : config.ignoreTypes) !== null && _a !== void 0 ? _a : [])].includes(node.name.value)) {
6
+ return '';
7
+ }
8
+ return new FreezedDeclarationBlock(config, freezedFactoryBlockRepository, node).init();
9
+ }
10
+ /**
11
+ * returns the value of the FreezedConfig option
12
+ * for a specific type if given typeName
13
+ * or else fallback to the global FreezedConfig value
14
+ */
15
+ export function getFreezedConfigValue(option, config, typeName) {
16
+ var _a, _b, _c, _d, _e;
17
+ if (typeName) {
18
+ return (_d = (_c = (_b = (_a = config === null || config === void 0 ? void 0 : config.typeSpecificFreezedConfig) === null || _a === void 0 ? void 0 : _a[typeName]) === null || _b === void 0 ? void 0 : _b.config) === null || _c === void 0 ? void 0 : _c[option]) !== null && _d !== void 0 ? _d : getFreezedConfigValue(option, config);
19
+ }
20
+ return (_e = config === null || config === void 0 ? void 0 : config.globalFreezedConfig) === null || _e === void 0 ? void 0 : _e[option];
21
+ }
22
+ /**
23
+ * @description filters the customDirectives to return those that are applied on a list of blocks
24
+ */
25
+ export function getCustomDecorators(config, appliesOn, nodeName, fieldName) {
26
+ var _a, _b, _c, _d, _e, _f, _g, _h;
27
+ const filteredCustomDecorators = {};
28
+ const globalCustomDecorators = (_b = (_a = config === null || config === void 0 ? void 0 : config.globalFreezedConfig) === null || _a === void 0 ? void 0 : _a.customDecorators) !== null && _b !== void 0 ? _b : {};
29
+ let customDecorators = { ...globalCustomDecorators };
30
+ if (nodeName) {
31
+ const typeConfig = (_c = config === null || config === void 0 ? void 0 : config.typeSpecificFreezedConfig) === null || _c === void 0 ? void 0 : _c[nodeName];
32
+ const typeSpecificCustomDecorators = (_e = (_d = typeConfig === null || typeConfig === void 0 ? void 0 : typeConfig.config) === null || _d === void 0 ? void 0 : _d.customDecorators) !== null && _e !== void 0 ? _e : {};
33
+ customDecorators = { ...customDecorators, ...typeSpecificCustomDecorators };
34
+ if (fieldName) {
35
+ const fieldSpecificCustomDecorators = (_h = (_g = (_f = typeConfig === null || typeConfig === void 0 ? void 0 : typeConfig.fields) === null || _f === void 0 ? void 0 : _f[fieldName]) === null || _g === void 0 ? void 0 : _g.customDecorators) !== null && _h !== void 0 ? _h : {};
36
+ customDecorators = { ...customDecorators, ...fieldSpecificCustomDecorators };
37
+ }
38
+ }
39
+ Object.entries(customDecorators).forEach(([key, value]) => {
40
+ var _a;
41
+ return (_a = value === null || value === void 0 ? void 0 : value.applyOn) === null || _a === void 0 ? void 0 : _a.forEach(a => {
42
+ if (appliesOn.includes(a)) {
43
+ filteredCustomDecorators[key] = value;
44
+ }
45
+ });
46
+ });
47
+ return filteredCustomDecorators;
48
+ }
49
+ export function transformCustomDecorators(customDecorators, node, field) {
50
+ var _a, _b;
51
+ let result = [];
52
+ result = [
53
+ ...result,
54
+ ...((_a = node === null || node === void 0 ? void 0 : node.directives) !== null && _a !== void 0 ? _a : [])
55
+ .concat((_b = field === null || field === void 0 ? void 0 : field.directives) !== null && _b !== void 0 ? _b : [])
56
+ // extract only the directives whose names were specified as keys
57
+ // and have values that not undefined or null in the customDecorator record
58
+ .filter(d => {
59
+ var _a;
60
+ const key = d.name.value;
61
+ const value = (_a = customDecorators[key]) !== null && _a !== void 0 ? _a : customDecorators[`@${key}`];
62
+ if (value && value.mapsToFreezedAs !== 'custom') {
63
+ return true;
64
+ }
65
+ return false;
66
+ })
67
+ // transform each directive to string
68
+ .map(d => directiveToString(d, customDecorators)),
69
+ ];
70
+ // for decorators that mapsToFreezedAs === 'custom'
71
+ Object.entries(customDecorators).forEach(([key, value]) => {
72
+ if (value.mapsToFreezedAs === 'custom') {
73
+ const args = value === null || value === void 0 ? void 0 : value.arguments;
74
+ // if the custom directives have arguments,
75
+ if (args && args !== []) {
76
+ // join them with a comma in the parenthesis
77
+ result = [...result, `${key}(${args.join(', ')})`];
78
+ }
79
+ else {
80
+ // else return the customDecorator key just as it is
81
+ result = [...result, key];
82
+ }
83
+ }
84
+ });
85
+ return result;
86
+ }
87
+ /**
88
+ * transforms the directive into a decorator array
89
+ * this decorator array might contain a `final` string which would be filtered out
90
+ * and used to mark the parameter block as final
91
+ */
92
+ function directiveToString(directive, customDecorators) {
93
+ var _a, _b, _c, _d, _e;
94
+ const key = directive.name.value;
95
+ const value = customDecorators[key];
96
+ if (value.mapsToFreezedAs === 'directive') {
97
+ // get the directive's arguments
98
+ const directiveArgs = (_a = directive === null || directive === void 0 ? void 0 : directive.arguments) !== null && _a !== void 0 ? _a : [];
99
+ // extract the directive's argument using the template index: ["$0", "$1", ...]
100
+ // specified in the customDecorator.arguments array
101
+ const args = (_b = value === null || value === void 0 ? void 0 : value.arguments) === null || _b === void 0 ? void 0 : _b.filter(a => directiveArgs[argToInt(a)]).map(a => directiveArgs[argToInt(a)]).map(a => `${a.name}: ${a.value}`);
102
+ // if the args is not empty
103
+ if (args !== []) {
104
+ // returns "@directiveName(argName: argValue, argName: argValue ...)"
105
+ return `@${directive.name.value}(${args === null || args === void 0 ? void 0 : args.join(', ')})`;
106
+ }
107
+ }
108
+ else if (value.mapsToFreezedAs === '@Default') {
109
+ const defaultValue = (_c = directive === null || directive === void 0 ? void 0 : directive.arguments) === null || _c === void 0 ? void 0 : _c[argToInt((_e = (_d = value === null || value === void 0 ? void 0 : value.arguments) === null || _d === void 0 ? void 0 : _d[0]) !== null && _e !== void 0 ? _e : '0')];
110
+ if (defaultValue) {
111
+ return `@Default(value: ${defaultValue})`;
112
+ }
113
+ }
114
+ // returns either "@deprecated" || "final".
115
+ // `final` to be filtered from the decorators array when applying the decorators
116
+ return value.mapsToFreezedAs;
117
+ }
118
+ /** transforms string template: "$0" into an integer: 1 */
119
+ function argToInt(arg) {
120
+ var _a;
121
+ const parsedIndex = Number.parseInt((_a = arg.replace('$', '').trim()) !== null && _a !== void 0 ? _a : '0'); // '$1 => 1
122
+ return parsedIndex ? parsedIndex : 0;
123
+ }
124
+ /** returns freezed import statements */
125
+ export function addFreezedImportStatements(fileName) {
126
+ return [
127
+ "import 'package:freezed_annotation/freezed_annotation.dart';\n",
128
+ "import 'package:flutter/foundation.dart';\n\n",
129
+ `part ${fileName}.dart;\n`,
130
+ `part '${fileName}.g.dart';\n\n`,
131
+ ].join('');
132
+ }
133
+ /** a class variant of the getFreezedConfigValue helper function
134
+ *
135
+ * returns the value of the FreezedConfig option
136
+ * for a specific type if given typeName
137
+ * or else fallback to the global FreezedConfig value
138
+ */
139
+ export class FreezedConfigValue {
140
+ constructor(_config, _typeName) {
141
+ this._config = _config;
142
+ this._typeName = _typeName;
143
+ this._config = _config;
144
+ this._typeName = _typeName;
145
+ }
146
+ /**
147
+ * returns the value of the FreezedConfig option
148
+ * for a specific type if given typeName
149
+ * or else fallback to the global FreezedConfig value
150
+ */
151
+ get(option) {
152
+ return getFreezedConfigValue(option, this._config, this._typeName);
153
+ }
154
+ }
155
+ /**
156
+ * stores an instance of FreezedFactoryBlock using the node names as the key
157
+ * and returns that instance when replacing tokens
158
+ * */
159
+ export class FreezedFactoryBlockRepository {
160
+ constructor() {
161
+ this._store = {};
162
+ }
163
+ register(key, value) {
164
+ this._store[key] = value;
165
+ return value;
166
+ }
167
+ retrieve(key, appliesOn, name, typeName) {
168
+ return this._store[key]
169
+ .setDecorators(appliesOn, key)
170
+ .setKey(key)
171
+ .setName(name)
172
+ .setNamedConstructor(typeName)
173
+ .init();
174
+ }
175
+ }
176
+ /** initializes a FreezedPluginConfig with the defaults values */
177
+ export class DefaultFreezedPluginConfig {
178
+ constructor(config = {}) {
179
+ var _a, _b, _c, _d, _e, _f;
180
+ Object.assign(this, {
181
+ customScalars: (_a = config.customScalars) !== null && _a !== void 0 ? _a : {},
182
+ fileName: (_b = config.fileName) !== null && _b !== void 0 ? _b : 'app_models',
183
+ globalFreezedConfig: { ...new DefaultFreezedConfig(), ...((_c = config.globalFreezedConfig) !== null && _c !== void 0 ? _c : {}) },
184
+ typeSpecificFreezedConfig: (_d = config.typeSpecificFreezedConfig) !== null && _d !== void 0 ? _d : {},
185
+ ignoreTypes: (_e = config.ignoreTypes) !== null && _e !== void 0 ? _e : [],
186
+ lowercaseEnums: (_f = config.lowercaseEnums) !== null && _f !== void 0 ? _f : true,
187
+ });
188
+ }
189
+ }
190
+ /** initializes a FreezedConfig with the defaults values */
191
+ export class DefaultFreezedConfig {
192
+ constructor() {
193
+ Object.assign(this, {
194
+ alwaysUseJsonKeyName: false,
195
+ copyWith: undefined,
196
+ customDecorators: {},
197
+ defaultUnionConstructor: true,
198
+ equal: undefined,
199
+ fromJsonToJson: true,
200
+ immutable: true,
201
+ makeCollectionsUnmodifiable: undefined,
202
+ mergeInputs: [],
203
+ mutableInputs: true,
204
+ privateEmptyConstructor: true,
205
+ unionKey: undefined,
206
+ unionValueCase: undefined,
207
+ });
208
+ }
209
+ }
package/package.json ADDED
@@ -0,0 +1,46 @@
1
+ {
2
+ "name": "@graphql-codegen/flutter-freezed",
3
+ "version": "2.11.1",
4
+ "description": "GraphQL Code Generator plugin to generate Freezed models from your GraphQL schema",
5
+ "peerDependencies": {
6
+ "graphql": "^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0 || ^16.0.0"
7
+ },
8
+ "dependencies": {
9
+ "@graphql-codegen/plugin-helpers": "^2.6.0",
10
+ "@graphql-codegen/schema-ast": "^2.5.0",
11
+ "@graphql-codegen/visitor-plugin-common": "2.12.0",
12
+ "auto-bind": "~4.0.0",
13
+ "tslib": "~2.4.0",
14
+ "change-case-all": "1.0.14"
15
+ },
16
+ "repository": {
17
+ "type": "git",
18
+ "url": "https://github.com/dotansimha/graphql-code-generator.git",
19
+ "directory": "packages/plugins/typescript/typescript"
20
+ },
21
+ "license": "MIT",
22
+ "main": "cjs/index.js",
23
+ "module": "esm/index.js",
24
+ "typings": "typings/index.d.ts",
25
+ "typescript": {
26
+ "definition": "typings/index.d.ts"
27
+ },
28
+ "type": "module",
29
+ "exports": {
30
+ ".": {
31
+ "require": {
32
+ "types": "./typings/index.d.cts",
33
+ "default": "./cjs/index.js"
34
+ },
35
+ "import": {
36
+ "types": "./typings/index.d.ts",
37
+ "default": "./esm/index.js"
38
+ },
39
+ "default": {
40
+ "types": "./typings/index.d.ts",
41
+ "default": "./esm/index.js"
42
+ }
43
+ },
44
+ "./package.json": "./package.json"
45
+ }
46
+ }