@taqueria/plugin-contract-types 0.3.0 → 0.4.0-rc2

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.
@@ -2,116 +2,116 @@ import * as M from '@taquito/michel-codec';
2
2
  import { assertExhaustive, GenerateApiError, reduceFlatMap } from './common';
3
3
 
4
4
  export type TypedStorage = {
5
- storage: TypedType;
5
+ storage: TypedType;
6
6
  };
7
7
  export type TypedParameter = {
8
- methods: TypedMethod[];
8
+ methods: TypedMethod[];
9
9
  };
10
10
  export type TypedMethod = {
11
- name: string;
12
- args: TypedVar[];
11
+ name: string;
12
+ args: TypedVar[];
13
13
  };
14
14
  export type TypedVar = {
15
- name?: string;
16
- type: TypedType;
15
+ name?: string;
16
+ type: TypedType;
17
17
  };
18
- export type TypedType = {
19
- raw: M.MichelsonType;
20
- optional?: boolean;
21
- } & (
22
- {
23
- kind: 'unit';
24
- } | {
25
- kind: 'never';
26
- } | {
27
- kind: 'unknown';
28
- } | {
29
- kind: 'value';
30
- value: string;
31
- typescriptType: 'string' | 'boolean' | 'number' | 'Date';
32
- } | {
33
- kind: 'union';
34
- union: TypedVar[];
35
- } | {
36
- kind: 'object';
37
- fields: TypedVar[];
38
- } | {
39
- kind: 'array';
40
- array: { item: TypedType };
41
- } | {
42
- kind: 'map';
43
- map: { key: TypedType, value: TypedType, isBigMap: boolean };
44
- }
45
- );
18
+ export type TypedType =
19
+ & {
20
+ raw: M.MichelsonType;
21
+ optional?: boolean;
22
+ }
23
+ & (
24
+ {
25
+ kind: 'unit';
26
+ } | {
27
+ kind: 'never';
28
+ } | {
29
+ kind: 'unknown';
30
+ } | {
31
+ kind: 'value';
32
+ value: string;
33
+ typescriptType: 'string' | 'boolean' | 'number' | 'Date';
34
+ } | {
35
+ kind: 'union';
36
+ union: TypedVar[];
37
+ } | {
38
+ kind: 'object';
39
+ fields: TypedVar[];
40
+ } | {
41
+ kind: 'array';
42
+ array: { item: TypedType };
43
+ } | {
44
+ kind: 'map';
45
+ map: { key: TypedType; value: TypedType; isBigMap: boolean };
46
+ }
47
+ );
46
48
 
47
49
  const toDebugSource = (node: M.MichelsonType) => {
48
- return JSON.stringify(node);
50
+ return JSON.stringify(node);
49
51
  };
50
52
 
51
53
  export const parseContractStorage = (storage: M.MichelsonContractStorage): TypedStorage => {
52
- const fields = storage.args
53
- .map(x => visitVar(x))
54
- .reduce(reduceFlatMap, []);
55
-
56
- if(fields.length === 1 && !fields[0].name){
57
- return {
58
- storage: fields[0].type
59
- };
60
- }
61
-
62
- return {
63
- storage: {
64
- kind: `object` as const,
65
- raw: storage as unknown as M.MichelsonType,
66
- fields,
67
- },
68
- };
54
+ const fields = storage.args
55
+ .map(x => visitVar(x))
56
+ .reduce(reduceFlatMap, []);
57
+
58
+ if (fields.length === 1 && !fields[0].name) {
59
+ return {
60
+ storage: fields[0].type,
61
+ };
62
+ }
63
+
64
+ return {
65
+ storage: {
66
+ kind: `object` as const,
67
+ raw: storage as unknown as M.MichelsonType,
68
+ fields,
69
+ },
70
+ };
69
71
  };
70
72
 
71
73
  export const parseContractParameter = (parameter: M.MichelsonContractParameter): TypedParameter => {
72
- return {
73
- methods: parameter.args
74
- .map(x => visitContractParameterEndpoint(x as MMethod))
75
- .reduce(reduceFlatMap, []),
76
- };
74
+ return {
75
+ methods: parameter.args
76
+ .map(x => visitContractParameterEndpoint(x as MMethod))
77
+ .reduce(reduceFlatMap, []),
78
+ };
77
79
  };
78
80
 
79
-
80
81
  type MMethod = M.MichelsonTypeOr<[M.MichelsonType, M.MichelsonType]>;
81
82
  const visitContractParameterEndpoint = (node: MMethod): TypedMethod[] => {
82
-
83
- // console.log('visitContractParameterEndpoint', { node });
84
-
85
- // Sub endpoints (i.e. admin endpoints that are imported)
86
- if (node.prim === `or`) {
87
- return node.args.map(x => visitContractParameterEndpoint(x as MMethod)).reduce(reduceFlatMap, []);
88
- }
89
-
90
- // Sub endpoints as a list with a single or (i.e. admin endpoints that are imported)
91
- if (node.prim === `list` && node.args.length as number === 1 && (node.args[0] as MMethod)?.prim === `or`) {
92
- return node.args.map(x => visitContractParameterEndpoint(x as MMethod)).reduce(reduceFlatMap, []);
93
- }
94
-
95
- const nameRaw = node.annots?.[0];
96
- const name = nameRaw?.startsWith('%') ? nameRaw.substr(1) : null;
97
-
98
- if (!name) {
99
- console.warn(`Unknown method: ${node.prim as string}`, { node, args: node.args });
100
- return [];
101
- }
102
-
103
- const nodeType = visitType(node, { ignorePairName: node.prim === 'pair' });
104
-
105
- // Method args are usually objects
106
- if (nodeType.kind === 'object') {
107
- return [{ name, args: nodeType.fields }];
108
- }
109
-
110
- // Simple methods can have a single unnamed argument
111
- return [{
112
- name,
113
- args: [{ type: nodeType }],
114
- }];
83
+ // console.log('visitContractParameterEndpoint', { node });
84
+
85
+ // Sub endpoints (i.e. admin endpoints that are imported)
86
+ if (node.prim === `or`) {
87
+ return node.args.map(x => visitContractParameterEndpoint(x as MMethod)).reduce(reduceFlatMap, []);
88
+ }
89
+
90
+ // Sub endpoints as a list with a single or (i.e. admin endpoints that are imported)
91
+ if (node.prim === `list` && node.args.length as number === 1 && (node.args[0] as MMethod)?.prim === `or`) {
92
+ return node.args.map(x => visitContractParameterEndpoint(x as MMethod)).reduce(reduceFlatMap, []);
93
+ }
94
+
95
+ const nameRaw = node.annots?.[0];
96
+ const name = nameRaw?.startsWith('%') ? nameRaw.substr(1) : null;
97
+
98
+ if (!name) {
99
+ console.warn(`Unknown method: ${node.prim as string}`, { node, args: node.args });
100
+ return [];
101
+ }
102
+
103
+ const nodeType = visitType(node, { ignorePairName: node.prim === 'pair' });
104
+
105
+ // Method args are usually objects
106
+ if (nodeType.kind === 'object') {
107
+ return [{ name, args: nodeType.fields }];
108
+ }
109
+
110
+ // Simple methods can have a single unnamed argument
111
+ return [{
112
+ name,
113
+ args: [{ type: nodeType }],
114
+ }];
115
115
  };
116
116
 
117
117
  // type PrimOf<T extends M.MichelsonType> = T extends { prim: infer U } ? U : never;
@@ -122,238 +122,242 @@ const visitContractParameterEndpoint = (node: MMethod): TypedMethod[] => {
122
122
 
123
123
  type MVarArgs = M.MichelsonType;
124
124
  const visitVar = (node: MVarArgs): TypedVar[] => {
125
- const name = `annots` in node && node.annots?.length === 1 ? node.annots[0].substr(1) : undefined;
126
- const type = visitType(node);
125
+ const name = `annots` in node && node.annots?.length === 1 ? node.annots[0].substr(1) : undefined;
126
+ const type = visitType(node);
127
127
 
128
- return [{
129
- name,
130
- type,
131
- }];
128
+ return [{
129
+ name,
130
+ type,
131
+ }];
132
132
  };
133
133
 
134
134
  type MType = M.MichelsonType;
135
135
  const visitType = (node: MType, options?: { ignorePairName?: boolean }): TypedType => {
136
- // console.log('visitType', { node });
137
- // const debug_source = toDebugSource(node);
138
-
139
- // if (typeof node === `string`) {
140
- // return { kind: `value`, raw: node, value: node, typescriptType: `string` };
141
- // }
142
-
143
- if (!(`prim` in node)) {
144
- // Unknown
145
- console.error(`visitType no prim`, { node });
146
- return { kind: `unknown`, raw: node };
147
- }
148
-
149
- // Union
150
- if (node.prim === `or`) {
151
- const unionVars = node.args.map(x => visitVar(x)).reduce(reduceFlatMap, []).map(x => x);
152
-
153
- // Flatten with child unions
154
- const union = unionVars.map(x => !x.name && x.type.kind === 'union' ? x.type.union : [x]).reduce(reduceFlatMap, []);
155
- // const union = unionVars.map(x=>x.type);
156
-
157
- // const union = unionVars.map(x => x.type);
158
-
159
- // Flatten with child unions
160
-
161
- // const rightSide = union[1];
162
- // if (rightSide.kind === `union`) {
163
- // union.pop();
164
- // union.push(...rightSide.union);
165
- // }
166
-
167
- if (union.some(x => !x)) {
168
- throw new GenerateApiError(`or: Some fields are null`, { node });
169
- }
170
- return {
171
- kind: `union`,
172
- raw: node,
173
- union,
174
- };
175
- }
176
-
177
- // Intersect
178
- if (node.prim === `pair`) {
179
- const fields = node.args.map(x => visitVar(x)).reduce(reduceFlatMap, []);
180
- if (fields.some(x => !x)) {
181
- throw new GenerateApiError(`pair: Some fields are null`, { node, args: node.args, fields });
182
- }
183
- // Disabled Check: Apparently pairs can have more than 2 items
184
- // if (fields.length !== 2) {
185
- // throw new GenerateApiError(`pair: Expected 2 items`, { node, length: fields.length, fields });
186
- // }
187
-
188
- // Flatten with unnamed child pairs
189
- const fieldsFlat = fields.map(x => (!x.name || options?.ignorePairName) && x.type.kind === 'object' ? x.type.fields : [x]).reduce(reduceFlatMap, []);
190
-
191
- return {
192
- kind: `object`,
193
- raw: node,
194
- fields: fieldsFlat,
195
- };
196
- }
197
-
198
- // list
199
- if (node.prim === `list`
200
- || node.prim === `set`
201
- ) {
202
- if (node.args.length !== 1) {
203
- throw new GenerateApiError(`list does not have 1 arg`, { node, args: node.args });
204
- }
205
-
206
- const arrayItem = visitType(node.args[0]);
207
- if (!arrayItem) {
208
- throw new GenerateApiError(`arrayItem are null`, { node, args: node.args, arrayItem });
209
- }
210
- return {
211
- kind: `array`,
212
- raw: node,
213
- array: { item: arrayItem },
214
- };
215
- }
216
-
217
- // map
218
- if (node.prim === `map`
219
- || node.prim === `big_map`
220
- ) {
221
- if (node.args.length !== 2) {
222
- throw new GenerateApiError(`map does not have 2 args`, { node, args: node.args });
223
- }
224
-
225
- const mapKey = visitType(node.args[0]);
226
- const mapValue = visitType(node.args[1]);
227
- if (!mapKey || !mapValue) {
228
- throw new GenerateApiError(`map is missing key or value`, { node, args: node.args, mapKey, mapValue });
229
- }
230
- return {
231
- kind: `map`,
232
- raw: node,
233
- map: {
234
- key: mapKey,
235
- value: mapValue,
236
- isBigMap: node.prim === `big_map`,
237
- },
238
- };
239
- }
240
-
241
- // option
242
- if (node.prim === `option`) {
243
- return {
244
- ...visitType(node.args[0]),
245
- optional: true,
246
- };
247
- }
248
-
249
- // boolean
250
- if (node.prim === `bool`) {
251
- return {
252
- kind: `value`,
253
- raw: node,
254
- value: node.prim,
255
- typescriptType: `boolean`,
256
- };
257
- }
258
-
259
- // numbers
260
- if (node.prim === `nat`
261
- || node.prim === `int`
262
- || node.prim === `mutez`
263
- ) {
264
- return {
265
- kind: `value`,
266
- raw: node,
267
- value: node.prim,
268
- typescriptType: `number`,
269
- };
270
- }
271
-
272
- // Date
273
- if (node.prim === `timestamp`
274
-
275
- ) {
276
- return {
277
- kind: `value`,
278
- raw: node,
279
- value: node.prim,
280
- typescriptType: `Date`,
281
- };
282
- }
283
-
284
- // strings
285
- if (node.prim === `address`
286
- || node.prim === `key`
287
- || node.prim === `key_hash`
288
- || node.prim === `chain_id`
289
- || node.prim === `string`
290
- || node.prim === `signature`
291
- || node.prim === `ticket`
292
- || node.prim === `bls12_381_fr`
293
- || node.prim === `bls12_381_g1`
294
- || node.prim === `bls12_381_g2`
295
- || node.prim === `sapling_state`
296
- || node.prim === `sapling_transaction`
297
- || node.prim === `contract`
298
- ) {
299
- return {
300
- kind: `value`,
301
- raw: node,
302
- value: node.prim,
303
- typescriptType: `string`,
304
- };
305
- }
306
-
307
-
308
- // void
309
- if (node.prim === `unit`) {
310
- return {
311
- kind: `unit`,
312
- raw: node,
313
- };
314
- }
315
-
316
- // bytes?
317
- if (node.prim === `bytes`) {
318
- return {
319
- kind: `value`,
320
- raw: node,
321
- value: node.prim,
322
- typescriptType: `string`,
323
- };
324
- }
325
-
326
- // misc?
327
- if (node.prim === `lambda`
328
- || node.prim === `operation`
329
- ) {
330
- return {
331
- kind: `value`,
332
- raw: node,
333
- value: node.prim,
334
- typescriptType: `string`,
335
- };
336
- }
337
-
338
- // chest
339
- if(node.prim === 'chest'){
340
- throw new Error('Not Implemented: chest');
341
- }
342
- if(node.prim === 'chest_key'){
343
- throw new Error('Not Implemented: chest_key');
344
- }
345
-
346
- // never
347
- if (node.prim === `never`
348
- ) {
349
- return {
350
- kind: `never`,
351
- raw: node,
352
- };
353
- }
354
-
355
-
356
- // Unknown
357
- assertExhaustive(node, `Unknown type`);
358
- throw new GenerateApiError(`Unknown type`, { node });
136
+ // console.log('visitType', { node });
137
+ // const debug_source = toDebugSource(node);
138
+
139
+ // if (typeof node === `string`) {
140
+ // return { kind: `value`, raw: node, value: node, typescriptType: `string` };
141
+ // }
142
+
143
+ if (!(`prim` in node)) {
144
+ // Unknown
145
+ console.error(`visitType no prim`, { node });
146
+ return { kind: `unknown`, raw: node };
147
+ }
148
+
149
+ // Union
150
+ if (node.prim === `or`) {
151
+ const unionVars = node.args.map(x => visitVar(x)).reduce(reduceFlatMap, []).map(x => x);
152
+
153
+ // Flatten with child unions
154
+ const union = unionVars.map(x => !x.name && x.type.kind === 'union' ? x.type.union : [x]).reduce(reduceFlatMap, []);
155
+ // const union = unionVars.map(x=>x.type);
156
+
157
+ // const union = unionVars.map(x => x.type);
158
+
159
+ // Flatten with child unions
160
+
161
+ // const rightSide = union[1];
162
+ // if (rightSide.kind === `union`) {
163
+ // union.pop();
164
+ // union.push(...rightSide.union);
165
+ // }
166
+
167
+ if (union.some(x => !x)) {
168
+ throw new GenerateApiError(`or: Some fields are null`, { node });
169
+ }
170
+ return {
171
+ kind: `union`,
172
+ raw: node,
173
+ union,
174
+ };
175
+ }
176
+
177
+ // Intersect
178
+ if (node.prim === `pair`) {
179
+ const fields = node.args.map(x => visitVar(x)).reduce(reduceFlatMap, []);
180
+ if (fields.some(x => !x)) {
181
+ throw new GenerateApiError(`pair: Some fields are null`, { node, args: node.args, fields });
182
+ }
183
+ // Disabled Check: Apparently pairs can have more than 2 items
184
+ // if (fields.length !== 2) {
185
+ // throw new GenerateApiError(`pair: Expected 2 items`, { node, length: fields.length, fields });
186
+ // }
187
+
188
+ // Flatten with unnamed child pairs
189
+ const fieldsFlat = fields.map(x =>
190
+ (!x.name || options?.ignorePairName) && x.type.kind === 'object' ? x.type.fields : [x]
191
+ ).reduce(reduceFlatMap, []);
192
+
193
+ return {
194
+ kind: `object`,
195
+ raw: node,
196
+ fields: fieldsFlat,
197
+ };
198
+ }
199
+
200
+ // list
201
+ if (
202
+ node.prim === `list`
203
+ || node.prim === `set`
204
+ ) {
205
+ if (node.args.length !== 1) {
206
+ throw new GenerateApiError(`list does not have 1 arg`, { node, args: node.args });
207
+ }
208
+
209
+ const arrayItem = visitType(node.args[0]);
210
+ if (!arrayItem) {
211
+ throw new GenerateApiError(`arrayItem are null`, { node, args: node.args, arrayItem });
212
+ }
213
+ return {
214
+ kind: `array`,
215
+ raw: node,
216
+ array: { item: arrayItem },
217
+ };
218
+ }
219
+
220
+ // map
221
+ if (
222
+ node.prim === `map`
223
+ || node.prim === `big_map`
224
+ ) {
225
+ if (node.args.length !== 2) {
226
+ throw new GenerateApiError(`map does not have 2 args`, { node, args: node.args });
227
+ }
228
+
229
+ const mapKey = visitType(node.args[0]);
230
+ const mapValue = visitType(node.args[1]);
231
+ if (!mapKey || !mapValue) {
232
+ throw new GenerateApiError(`map is missing key or value`, { node, args: node.args, mapKey, mapValue });
233
+ }
234
+ return {
235
+ kind: `map`,
236
+ raw: node,
237
+ map: {
238
+ key: mapKey,
239
+ value: mapValue,
240
+ isBigMap: node.prim === `big_map`,
241
+ },
242
+ };
243
+ }
244
+
245
+ // option
246
+ if (node.prim === `option`) {
247
+ return {
248
+ ...visitType(node.args[0]),
249
+ optional: true,
250
+ };
251
+ }
252
+
253
+ // boolean
254
+ if (node.prim === `bool`) {
255
+ return {
256
+ kind: `value`,
257
+ raw: node,
258
+ value: node.prim,
259
+ typescriptType: `boolean`,
260
+ };
261
+ }
262
+
263
+ // numbers
264
+ if (
265
+ node.prim === `nat`
266
+ || node.prim === `int`
267
+ || node.prim === `mutez`
268
+ ) {
269
+ return {
270
+ kind: `value`,
271
+ raw: node,
272
+ value: node.prim,
273
+ typescriptType: `number`,
274
+ };
275
+ }
276
+
277
+ // Date
278
+ if (node.prim === `timestamp`) {
279
+ return {
280
+ kind: `value`,
281
+ raw: node,
282
+ value: node.prim,
283
+ typescriptType: `Date`,
284
+ };
285
+ }
286
+
287
+ // strings
288
+ if (
289
+ node.prim === `address`
290
+ || node.prim === `key`
291
+ || node.prim === `key_hash`
292
+ || node.prim === `chain_id`
293
+ || node.prim === `string`
294
+ || node.prim === `signature`
295
+ || node.prim === `ticket`
296
+ || node.prim === `bls12_381_fr`
297
+ || node.prim === `bls12_381_g1`
298
+ || node.prim === `bls12_381_g2`
299
+ || node.prim === `sapling_state`
300
+ || node.prim === `sapling_transaction`
301
+ || node.prim === `contract`
302
+ ) {
303
+ return {
304
+ kind: `value`,
305
+ raw: node,
306
+ value: node.prim,
307
+ typescriptType: `string`,
308
+ };
309
+ }
310
+
311
+ // void
312
+ if (node.prim === `unit`) {
313
+ return {
314
+ kind: `unit`,
315
+ raw: node,
316
+ };
317
+ }
318
+
319
+ // bytes?
320
+ if (node.prim === `bytes`) {
321
+ return {
322
+ kind: `value`,
323
+ raw: node,
324
+ value: node.prim,
325
+ typescriptType: `string`,
326
+ };
327
+ }
328
+
329
+ // misc?
330
+ if (
331
+ node.prim === `lambda`
332
+ || node.prim === `operation`
333
+ ) {
334
+ return {
335
+ kind: `value`,
336
+ raw: node,
337
+ value: node.prim,
338
+ typescriptType: `string`,
339
+ };
340
+ }
341
+
342
+ // chest
343
+ if (node.prim === 'chest' || node.prim === 'chest_key') {
344
+ return {
345
+ kind: `value`,
346
+ raw: node,
347
+ value: node.prim,
348
+ typescriptType: `string`,
349
+ };
350
+ }
351
+
352
+ // never
353
+ if (node.prim === `never`) {
354
+ return {
355
+ kind: `never`,
356
+ raw: node,
357
+ };
358
+ }
359
+
360
+ // Unknown
361
+ assertExhaustive(node, `Unknown type`);
362
+ throw new GenerateApiError(`Unknown type`, { node });
359
363
  };