@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
package/cjs/utils.js ADDED
@@ -0,0 +1,221 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.DefaultFreezedConfig = exports.DefaultFreezedPluginConfig = exports.FreezedFactoryBlockRepository = exports.FreezedConfigValue = exports.addFreezedImportStatements = exports.transformCustomDecorators = exports.getCustomDecorators = exports.getFreezedConfigValue = exports.transformDefinition = void 0;
4
+ const index_js_1 = require("./freezed-declaration-blocks/index.js");
5
+ function transformDefinition(config, freezedFactoryBlockRepository, node) {
6
+ var _a;
7
+ // ignore these...
8
+ if (['Query', 'Mutation', 'Subscription', ...((_a = config === null || config === void 0 ? void 0 : config.ignoreTypes) !== null && _a !== void 0 ? _a : [])].includes(node.name.value)) {
9
+ return '';
10
+ }
11
+ return new index_js_1.FreezedDeclarationBlock(config, freezedFactoryBlockRepository, node).init();
12
+ }
13
+ exports.transformDefinition = transformDefinition;
14
+ /**
15
+ * returns the value of the FreezedConfig option
16
+ * for a specific type if given typeName
17
+ * or else fallback to the global FreezedConfig value
18
+ */
19
+ function getFreezedConfigValue(option, config, typeName) {
20
+ var _a, _b, _c, _d, _e;
21
+ if (typeName) {
22
+ 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);
23
+ }
24
+ return (_e = config === null || config === void 0 ? void 0 : config.globalFreezedConfig) === null || _e === void 0 ? void 0 : _e[option];
25
+ }
26
+ exports.getFreezedConfigValue = getFreezedConfigValue;
27
+ /**
28
+ * @description filters the customDirectives to return those that are applied on a list of blocks
29
+ */
30
+ function getCustomDecorators(config, appliesOn, nodeName, fieldName) {
31
+ var _a, _b, _c, _d, _e, _f, _g, _h;
32
+ const filteredCustomDecorators = {};
33
+ 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 : {};
34
+ let customDecorators = { ...globalCustomDecorators };
35
+ if (nodeName) {
36
+ const typeConfig = (_c = config === null || config === void 0 ? void 0 : config.typeSpecificFreezedConfig) === null || _c === void 0 ? void 0 : _c[nodeName];
37
+ 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 : {};
38
+ customDecorators = { ...customDecorators, ...typeSpecificCustomDecorators };
39
+ if (fieldName) {
40
+ 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 : {};
41
+ customDecorators = { ...customDecorators, ...fieldSpecificCustomDecorators };
42
+ }
43
+ }
44
+ Object.entries(customDecorators).forEach(([key, value]) => {
45
+ var _a;
46
+ return (_a = value === null || value === void 0 ? void 0 : value.applyOn) === null || _a === void 0 ? void 0 : _a.forEach(a => {
47
+ if (appliesOn.includes(a)) {
48
+ filteredCustomDecorators[key] = value;
49
+ }
50
+ });
51
+ });
52
+ return filteredCustomDecorators;
53
+ }
54
+ exports.getCustomDecorators = getCustomDecorators;
55
+ function transformCustomDecorators(customDecorators, node, field) {
56
+ var _a, _b;
57
+ let result = [];
58
+ result = [
59
+ ...result,
60
+ ...((_a = node === null || node === void 0 ? void 0 : node.directives) !== null && _a !== void 0 ? _a : [])
61
+ .concat((_b = field === null || field === void 0 ? void 0 : field.directives) !== null && _b !== void 0 ? _b : [])
62
+ // extract only the directives whose names were specified as keys
63
+ // and have values that not undefined or null in the customDecorator record
64
+ .filter(d => {
65
+ var _a;
66
+ const key = d.name.value;
67
+ const value = (_a = customDecorators[key]) !== null && _a !== void 0 ? _a : customDecorators[`@${key}`];
68
+ if (value && value.mapsToFreezedAs !== 'custom') {
69
+ return true;
70
+ }
71
+ return false;
72
+ })
73
+ // transform each directive to string
74
+ .map(d => directiveToString(d, customDecorators)),
75
+ ];
76
+ // for decorators that mapsToFreezedAs === 'custom'
77
+ Object.entries(customDecorators).forEach(([key, value]) => {
78
+ if (value.mapsToFreezedAs === 'custom') {
79
+ const args = value === null || value === void 0 ? void 0 : value.arguments;
80
+ // if the custom directives have arguments,
81
+ if (args && args !== []) {
82
+ // join them with a comma in the parenthesis
83
+ result = [...result, `${key}(${args.join(', ')})`];
84
+ }
85
+ else {
86
+ // else return the customDecorator key just as it is
87
+ result = [...result, key];
88
+ }
89
+ }
90
+ });
91
+ return result;
92
+ }
93
+ exports.transformCustomDecorators = transformCustomDecorators;
94
+ /**
95
+ * transforms the directive into a decorator array
96
+ * this decorator array might contain a `final` string which would be filtered out
97
+ * and used to mark the parameter block as final
98
+ */
99
+ function directiveToString(directive, customDecorators) {
100
+ var _a, _b, _c, _d, _e;
101
+ const key = directive.name.value;
102
+ const value = customDecorators[key];
103
+ if (value.mapsToFreezedAs === 'directive') {
104
+ // get the directive's arguments
105
+ const directiveArgs = (_a = directive === null || directive === void 0 ? void 0 : directive.arguments) !== null && _a !== void 0 ? _a : [];
106
+ // extract the directive's argument using the template index: ["$0", "$1", ...]
107
+ // specified in the customDecorator.arguments array
108
+ 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}`);
109
+ // if the args is not empty
110
+ if (args !== []) {
111
+ // returns "@directiveName(argName: argValue, argName: argValue ...)"
112
+ return `@${directive.name.value}(${args === null || args === void 0 ? void 0 : args.join(', ')})`;
113
+ }
114
+ }
115
+ else if (value.mapsToFreezedAs === '@Default') {
116
+ 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')];
117
+ if (defaultValue) {
118
+ return `@Default(value: ${defaultValue})`;
119
+ }
120
+ }
121
+ // returns either "@deprecated" || "final".
122
+ // `final` to be filtered from the decorators array when applying the decorators
123
+ return value.mapsToFreezedAs;
124
+ }
125
+ /** transforms string template: "$0" into an integer: 1 */
126
+ function argToInt(arg) {
127
+ var _a;
128
+ const parsedIndex = Number.parseInt((_a = arg.replace('$', '').trim()) !== null && _a !== void 0 ? _a : '0'); // '$1 => 1
129
+ return parsedIndex ? parsedIndex : 0;
130
+ }
131
+ /** returns freezed import statements */
132
+ function addFreezedImportStatements(fileName) {
133
+ return [
134
+ "import 'package:freezed_annotation/freezed_annotation.dart';\n",
135
+ "import 'package:flutter/foundation.dart';\n\n",
136
+ `part ${fileName}.dart;\n`,
137
+ `part '${fileName}.g.dart';\n\n`,
138
+ ].join('');
139
+ }
140
+ exports.addFreezedImportStatements = addFreezedImportStatements;
141
+ /** a class variant of the getFreezedConfigValue helper function
142
+ *
143
+ * returns the value of the FreezedConfig option
144
+ * for a specific type if given typeName
145
+ * or else fallback to the global FreezedConfig value
146
+ */
147
+ class FreezedConfigValue {
148
+ constructor(_config, _typeName) {
149
+ this._config = _config;
150
+ this._typeName = _typeName;
151
+ this._config = _config;
152
+ this._typeName = _typeName;
153
+ }
154
+ /**
155
+ * returns the value of the FreezedConfig option
156
+ * for a specific type if given typeName
157
+ * or else fallback to the global FreezedConfig value
158
+ */
159
+ get(option) {
160
+ return getFreezedConfigValue(option, this._config, this._typeName);
161
+ }
162
+ }
163
+ exports.FreezedConfigValue = FreezedConfigValue;
164
+ /**
165
+ * stores an instance of FreezedFactoryBlock using the node names as the key
166
+ * and returns that instance when replacing tokens
167
+ * */
168
+ class FreezedFactoryBlockRepository {
169
+ constructor() {
170
+ this._store = {};
171
+ }
172
+ register(key, value) {
173
+ this._store[key] = value;
174
+ return value;
175
+ }
176
+ retrieve(key, appliesOn, name, typeName) {
177
+ return this._store[key]
178
+ .setDecorators(appliesOn, key)
179
+ .setKey(key)
180
+ .setName(name)
181
+ .setNamedConstructor(typeName)
182
+ .init();
183
+ }
184
+ }
185
+ exports.FreezedFactoryBlockRepository = FreezedFactoryBlockRepository;
186
+ /** initializes a FreezedPluginConfig with the defaults values */
187
+ class DefaultFreezedPluginConfig {
188
+ constructor(config = {}) {
189
+ var _a, _b, _c, _d, _e, _f;
190
+ Object.assign(this, {
191
+ customScalars: (_a = config.customScalars) !== null && _a !== void 0 ? _a : {},
192
+ fileName: (_b = config.fileName) !== null && _b !== void 0 ? _b : 'app_models',
193
+ globalFreezedConfig: { ...new DefaultFreezedConfig(), ...((_c = config.globalFreezedConfig) !== null && _c !== void 0 ? _c : {}) },
194
+ typeSpecificFreezedConfig: (_d = config.typeSpecificFreezedConfig) !== null && _d !== void 0 ? _d : {},
195
+ ignoreTypes: (_e = config.ignoreTypes) !== null && _e !== void 0 ? _e : [],
196
+ lowercaseEnums: (_f = config.lowercaseEnums) !== null && _f !== void 0 ? _f : true,
197
+ });
198
+ }
199
+ }
200
+ exports.DefaultFreezedPluginConfig = DefaultFreezedPluginConfig;
201
+ /** initializes a FreezedConfig with the defaults values */
202
+ class DefaultFreezedConfig {
203
+ constructor() {
204
+ Object.assign(this, {
205
+ alwaysUseJsonKeyName: false,
206
+ copyWith: undefined,
207
+ customDecorators: {},
208
+ defaultUnionConstructor: true,
209
+ equal: undefined,
210
+ fromJsonToJson: true,
211
+ immutable: true,
212
+ makeCollectionsUnmodifiable: undefined,
213
+ mergeInputs: [],
214
+ mutableInputs: true,
215
+ privateEmptyConstructor: true,
216
+ unionKey: undefined,
217
+ unionValueCase: undefined,
218
+ });
219
+ }
220
+ }
221
+ exports.DefaultFreezedConfig = DefaultFreezedConfig;
package/esm/config.js ADDED
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,217 @@
1
+ import { indent } from '@graphql-codegen/visitor-plugin-common';
2
+ import { Kind } from 'graphql';
3
+ import { camelCase, pascalCase } from 'change-case-all';
4
+ import { getCustomDecorators, transformCustomDecorators, FreezedConfigValue, } from '../utils.js';
5
+ import { FreezedFactoryBlock } from './factory-block.js';
6
+ export class FreezedDeclarationBlock {
7
+ constructor(_config, _freezedFactoryBlockRepository, _node) {
8
+ this._config = _config;
9
+ this._freezedFactoryBlockRepository = _freezedFactoryBlockRepository;
10
+ this._node = _node;
11
+ /** document the class */
12
+ this._comment = '';
13
+ /** a list of decorators to copy paste to the generator */
14
+ this._decorators = [];
15
+ /** a list of default constructor and named Constructors used create a Freezed union/sealed class */
16
+ this._factoryBlocks = [];
17
+ this._config = _config;
18
+ this._freezedFactoryBlockRepository = _freezedFactoryBlockRepository;
19
+ this._node = _node;
20
+ this._freezedConfigValue = new FreezedConfigValue(this._config, this._node.name.value);
21
+ }
22
+ init() {
23
+ if (this._node.kind === Kind.ENUM_TYPE_DEFINITION) {
24
+ this.setDecorators().setName().setShape().setBlock();
25
+ return this;
26
+ }
27
+ this.setComment().setDecorators().setName().setFactoryBlocks().setShape().setBlock();
28
+ return this;
29
+ }
30
+ setComment() {
31
+ var _a;
32
+ const comment = (_a = this._node.description) === null || _a === void 0 ? void 0 : _a.value;
33
+ if (comment && comment !== null && comment !== '') {
34
+ this._comment = `/// ${comment} \n`;
35
+ }
36
+ return this;
37
+ }
38
+ getEnumComment(value) {
39
+ var _a;
40
+ const comment = (_a = value.description) === null || _a === void 0 ? void 0 : _a.value;
41
+ if (comment && comment !== null && comment !== '') {
42
+ return `/// ${comment} \n`;
43
+ }
44
+ return '';
45
+ }
46
+ setDecorators() {
47
+ var _a, _b;
48
+ const name = this._node.name.value;
49
+ // determine if should mark as deprecated
50
+ const isDeprecated = (_b = (_a = this._config.typeSpecificFreezedConfig) === null || _a === void 0 ? void 0 : _a[name]) === null || _b === void 0 ? void 0 : _b.deprecated;
51
+ this._decorators =
52
+ this._node.kind === Kind.ENUM_TYPE_DEFINITION
53
+ ? [...transformCustomDecorators(getCustomDecorators(this._config, ['enum'], name), this._node)]
54
+ : [
55
+ this.getFreezedDecorator(),
56
+ ...transformCustomDecorators(getCustomDecorators(this._config, ['class'], name), this._node),
57
+ ];
58
+ // @deprecated
59
+ // if this._decorators doesn't include an @deprecated decorator but the field is marked as @deprecated...
60
+ if (!this._decorators.includes('@deprecated') && isDeprecated) {
61
+ this._decorators = [...this._decorators, '@deprecated'];
62
+ }
63
+ return this;
64
+ }
65
+ getFreezedDecorator() {
66
+ const use_unfreezed = () => {
67
+ if (!this._freezedConfigValue.get('immutable') ||
68
+ (this._node.kind === Kind.INPUT_OBJECT_TYPE_DEFINITION && this._freezedConfigValue.get('mutableInputs'))) {
69
+ return '@unfreezed';
70
+ }
71
+ return use_Freezed_or_freezed();
72
+ };
73
+ const use_Freezed_or_freezed = () => {
74
+ // if any of these options is not null, use the @Freezed() decorator passing in that option
75
+ const [isCustomized, copyWith, equal, makeCollectionsUnmodifiable, unionKey, unionValueCase] = isCustomizedFreezed();
76
+ if (isCustomized) {
77
+ return `@Freezed(\n
78
+ ${copyWith ? indent(`copyWith: ${copyWith},\n`) : ''}
79
+ ${equal ? indent(`equal: ${equal},\n`) : ''}
80
+ ${makeCollectionsUnmodifiable ? indent(`makeCollectionsUnmodifiable: ${makeCollectionsUnmodifiable},\n`) : ''}
81
+ ${unionKey ? indent(`unionKey: ${unionKey},\n`) : ''}
82
+ ${unionValueCase ? indent(`unionValueCase: ${unionValueCase},\n`) : ''}
83
+ )`;
84
+ }
85
+ // else fallback to the normal @freezed decorator
86
+ return '@freezed';
87
+ };
88
+ const isCustomizedFreezed = () => {
89
+ const copyWith = this._freezedConfigValue.get('copyWith');
90
+ const equal = this._freezedConfigValue.get('equal');
91
+ const makeCollectionsUnmodifiable = this._freezedConfigValue.get('makeCollectionsUnmodifiable');
92
+ const unionKey = this._freezedConfigValue.get('unionKey');
93
+ const unionValueCase = this._freezedConfigValue.get('unionValueCase');
94
+ const isCustomized = copyWith || equal || makeCollectionsUnmodifiable || unionKey || unionValueCase;
95
+ return [isCustomized, copyWith, equal, makeCollectionsUnmodifiable, unionKey, unionValueCase];
96
+ };
97
+ // this is the start of the pipeline of decisions to determine which Freezed decorator to use
98
+ return use_unfreezed();
99
+ }
100
+ setName() {
101
+ this._name = pascalCase(this._node.name.value);
102
+ return this;
103
+ }
104
+ setFactoryBlocks() {
105
+ var _a, _b, _c, _d;
106
+ if (this._node.kind === Kind.UNION_TYPE_DEFINITION) {
107
+ this._factoryBlocks =
108
+ (_b = (_a = this._node.types) === null || _a === void 0 ? void 0 : _a.map((_type) => new FreezedFactoryBlock(this._config, this._node).init())) !== null && _b !== void 0 ? _b : [];
109
+ }
110
+ else if (this._node.kind !== Kind.ENUM_TYPE_DEFINITION) {
111
+ /*
112
+ for `ObjectTypeDefinitionNode` and `InputObjectTypeDefinitionNode` nodes,
113
+ we use the `ShapeRepository`
114
+ to register the `FreezedFactoryBlock` so that we can use it later
115
+ when we are merging inputs or generating freezed union/sealed classes
116
+ for GraphQL union types
117
+ */
118
+ this._factoryBlocks =
119
+ (_d = (_c = this._node.fields) === null || _c === void 0 ? void 0 : _c.map((_field) => this._freezedFactoryBlockRepository.register(this._node.name.value, new FreezedFactoryBlock(this._config, this._node).init()))) !== null && _d !== void 0 ? _d : [];
120
+ }
121
+ return this;
122
+ }
123
+ setShape() {
124
+ var _a, _b, _c;
125
+ let shape = '';
126
+ // some helper variables
127
+ const name = this._node.name.value;
128
+ let namedConstructor;
129
+ let factoryBlockKey;
130
+ // handle enums differently
131
+ if (this._node.kind === Kind.ENUM_TYPE_DEFINITION) {
132
+ this._shape = (_a = this._node.values) === null || _a === void 0 ? void 0 : _a.map((value) => {
133
+ var _a;
134
+ shape = indent(this.getEnumComment(value));
135
+ if ((_a = this._config.lowercaseEnums) !== null && _a !== void 0 ? _a : true) {
136
+ shape += `@JsonKey(name: ${value.name.value}) ${value.name.value.toLowerCase()}`;
137
+ }
138
+ else {
139
+ shape += value.name.value;
140
+ }
141
+ return `${shape}\n`;
142
+ }).join('');
143
+ return this;
144
+ }
145
+ // append private empty constructor
146
+ if (this._freezedConfigValue.get('privateEmptyConstructor')) {
147
+ shape += indent(`const ${this._name}._();\n\n`);
148
+ }
149
+ // decide whether to append an empty Union constructor
150
+ if (this._freezedConfigValue.get('defaultUnionConstructor') && this._node.kind === Kind.UNION_TYPE_DEFINITION) {
151
+ shape += indent(`const factory ${this._name}() = _${this._name};\n\n`);
152
+ }
153
+ // append tokens which will be used to retrieve the factory blocks
154
+ // from the FreezedFactoryBlockRepository
155
+ if (this._node.kind === Kind.UNION_TYPE_DEFINITION) {
156
+ (_c = (_b = this._node) === null || _b === void 0 ? void 0 : _b.types) === null || _c === void 0 ? void 0 : _c.forEach(type => {
157
+ namedConstructor = type.name.value;
158
+ factoryBlockKey = namedConstructor;
159
+ shape += `==>factory==>${factoryBlockKey}==>${'union_factory'}==>${name}==>${namedConstructor}\n`;
160
+ });
161
+ }
162
+ else {
163
+ factoryBlockKey = name;
164
+ // replace token for the ObjectType & InputType to be replaced with the default Freezed constructor
165
+ shape += `==>factory==>${factoryBlockKey}==>${'class_factory'}==>${name}\n`;
166
+ const mergeInputs = this._freezedConfigValue.get('mergeInputs');
167
+ if (this._node.kind === Kind.OBJECT_TYPE_DEFINITION && mergeInputs) {
168
+ // replace token for the InputTypes(a.k.a namedConstructors) as a union/sealed class
169
+ mergeInputs.forEach(input => {
170
+ namedConstructor = camelCase(input.split('$').join('_'));
171
+ factoryBlockKey = input.replace('$', name);
172
+ shape += `==>factory==>${factoryBlockKey}==>${'union_factory'}==>${name}==>${namedConstructor}\n`;
173
+ });
174
+ }
175
+ }
176
+ this._shape = shape;
177
+ return this;
178
+ }
179
+ /**
180
+ * returns the string output of the block
181
+ */
182
+ setBlock() {
183
+ let block = '';
184
+ //append comment
185
+ block += this._comment;
186
+ // append the decorators
187
+ block += this._decorators.join('\n');
188
+ if (this._decorators !== []) {
189
+ block += '\n';
190
+ }
191
+ // handle enums differently
192
+ if (this._node.kind === Kind.ENUM_TYPE_DEFINITION) {
193
+ block += `enum ${this._name}{\n${this._shape}}\n\n`;
194
+ this._block = block;
195
+ return this;
196
+ }
197
+ // append start of class definition
198
+ block += `class ${this._name} with _$${this._name} {\n`;
199
+ // append the shape
200
+ block += this._shape;
201
+ // append fromJson
202
+ if (this._freezedConfigValue.get('fromJsonToJson')) {
203
+ block += indent(`factory ${this._name}.fromJson(Map<String, Object?> json) => _${this._name}FromJson(json);\n`);
204
+ }
205
+ //append end of class definition
206
+ block += '}\n\n';
207
+ this._block = block;
208
+ return this;
209
+ }
210
+ /** returns the block */
211
+ toString() {
212
+ if (!this._block) {
213
+ throw new Error('setShape must be called before calling toString()');
214
+ }
215
+ return this._block;
216
+ }
217
+ }
@@ -0,0 +1,117 @@
1
+ import { indent } from '@graphql-codegen/visitor-plugin-common';
2
+ import { Kind } from 'graphql';
3
+ import { camelCase, pascalCase } from 'change-case-all';
4
+ import { FreezedParameterBlock } from './parameter-block.js';
5
+ import { FreezedConfigValue, getCustomDecorators, transformCustomDecorators } from '../utils.js';
6
+ export class FreezedFactoryBlock {
7
+ constructor(_config, _node) {
8
+ this._config = _config;
9
+ this._node = _node;
10
+ /** document the constructor */
11
+ this._comment = '';
12
+ /** a list of decorators to copy paste to the generator */
13
+ this._decorators = [];
14
+ /** a list of interfaces to implements */
15
+ // _implements: string[] = [];
16
+ /** a list of class to mixin with */
17
+ // _mixins: string[] = [];
18
+ /** the parameters of this factory constructor */
19
+ // TODO: handle other parameter types like positional parameters later.
20
+ // TODO: sticking to named parameters because GraphQL is a typed language
21
+ this._parameters = [];
22
+ this._config = _config;
23
+ this._node = _node;
24
+ this._freezedConfigValue = new FreezedConfigValue(_config, _node.name.value);
25
+ }
26
+ init() {
27
+ /*
28
+ setDecorators(), setName() and setType() will be called
29
+ when the factory is retrieved from the repository
30
+ */
31
+ this.setComment().setParameters().setShape().setBlock();
32
+ return this;
33
+ }
34
+ setComment() {
35
+ var _a;
36
+ const comment = (_a = this._node.description) === null || _a === void 0 ? void 0 : _a.value;
37
+ if (comment && comment !== null && comment !== '') {
38
+ this._comment = indent(`/// ${comment} \n`);
39
+ }
40
+ return this;
41
+ }
42
+ setDecorators(appliesOn, nodeName) {
43
+ this._decorators = [
44
+ ...transformCustomDecorators(getCustomDecorators(this._config, appliesOn.split(','), nodeName), this._node),
45
+ ];
46
+ return this;
47
+ }
48
+ setKey(key) {
49
+ this._key = pascalCase(key);
50
+ return this;
51
+ }
52
+ setName(name) {
53
+ this._name = pascalCase(name);
54
+ return this;
55
+ }
56
+ setNamedConstructor(namedConstructor) {
57
+ if (namedConstructor) {
58
+ this._namedConstructor = camelCase(namedConstructor);
59
+ }
60
+ return this;
61
+ }
62
+ setParameters() {
63
+ var _a, _b, _c;
64
+ const appliesOn = this._namedConstructor
65
+ ? ['union_factory_parameter']
66
+ : ['class_factory_parameter'];
67
+ if (this._node.kind !== Kind.UNION_TYPE_DEFINITION && this._node.kind !== Kind.ENUM_TYPE_DEFINITION) {
68
+ this._parameters =
69
+ (_c = (_b = (_a = this._node) === null || _a === void 0 ? void 0 : _a.fields) === null || _b === void 0 ? void 0 : _b.map((field) => new FreezedParameterBlock(this._config, appliesOn, this._node, field).init())) !== null && _c !== void 0 ? _c : [];
70
+ }
71
+ return this;
72
+ }
73
+ setShape() {
74
+ this._shape = this._parameters.map(p => p.toString()).join('');
75
+ return this;
76
+ }
77
+ setBlock() {
78
+ let block = '';
79
+ //append comment
80
+ block += this._comment;
81
+ // append the decorators
82
+ block += this._decorators.map(d => indent(`${d}\n`)).join('');
83
+ block += indent('');
84
+ // decide if to use const or not
85
+ if (this._freezedConfigValue.get('immutable')) {
86
+ block += 'const ';
87
+ }
88
+ // append the factory keyword and the name
89
+ block += `factory ${this._name}`;
90
+ // append .namedConstructor is not null
91
+ if (this._namedConstructor && this._namedConstructor !== '') {
92
+ block += `.${this._namedConstructor}`;
93
+ }
94
+ // append the parenthesis for the constructor and braces for the named parameters
95
+ block += '({\n';
96
+ //append the shape
97
+ block += this._shape;
98
+ // close the constructor and assign the key
99
+ block += indent(`}) = `);
100
+ // but first decide whether prefix the key with an underscore
101
+ if (!this._namedConstructor) {
102
+ block += '_';
103
+ }
104
+ // finally, append the key
105
+ block += `${this._key};\n`;
106
+ // store it in the shape
107
+ this._block = block;
108
+ return this;
109
+ }
110
+ /** returns the block */
111
+ toString() {
112
+ if (!this._block) {
113
+ throw new Error('FreezedFactoryBlock: setShape must be called before calling toString()');
114
+ }
115
+ return this._block;
116
+ }
117
+ }
@@ -0,0 +1,3 @@
1
+ export * from './parameter-block.js';
2
+ export * from './factory-block.js';
3
+ export * from './class-block.js';