@atproto/lex-cli 0.4.0 → 0.5.0-rc.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.
package/dist/index.js CHANGED
@@ -39,24 +39,19 @@ program.name('lex').description('Lexicon CLI').version('0.0.0');
39
39
  program
40
40
  .command('gen-md')
41
41
  .description('Generate markdown documentation')
42
+ .option('--yes', 'skip confirmation')
42
43
  .argument('<outfile>', 'path of the file to write to', toPath)
43
44
  .argument('<lexicons...>', 'paths of the lexicon files to include', toPaths)
44
- .action(async (outFilePath, lexiconPaths) => {
45
- if (!outFilePath.endsWith('.md')) {
45
+ .action(async (outFile, lexiconPaths, o) => {
46
+ if (!outFile.endsWith('.md')) {
46
47
  console.error('Must supply the path to a .md file as the first parameter');
47
48
  process.exit(1);
48
49
  }
49
- console.log('Writing', outFilePath);
50
- const ok = await (0, yesno_1.default)({
51
- question: 'Are you sure you want to continue? [y/N]',
52
- defaultValue: false,
53
- });
54
- if (!ok) {
55
- console.log('Aborted.');
56
- process.exit(0);
57
- }
50
+ if (!o?.yes)
51
+ await confirmOrExit();
52
+ console.log('Writing', outFile);
58
53
  const lexicons = (0, util_1.readAllLexicons)(lexiconPaths);
59
- await mdGen.process(outFilePath, lexicons);
54
+ await mdGen.process(outFile, lexicons);
60
55
  });
61
56
  program
62
57
  .command('gen-ts-obj')
@@ -69,44 +64,34 @@ program
69
64
  program
70
65
  .command('gen-api')
71
66
  .description('Generate a TS client API')
67
+ .option('--yes', 'skip confirmation')
72
68
  .argument('<outdir>', 'path of the directory to write to', toPath)
73
69
  .argument('<lexicons...>', 'paths of the lexicon files to include', toPaths)
74
- .action(async (outDir, lexiconPaths) => {
70
+ .action(async (outDir, lexiconPaths, o) => {
75
71
  const lexicons = (0, util_1.readAllLexicons)(lexiconPaths);
76
72
  const api = await (0, client_1.genClientApi)(lexicons);
77
73
  const diff = (0, util_1.genFileDiff)(outDir, api);
78
74
  console.log('This will write the following files:');
79
75
  (0, util_1.printFileDiff)(diff);
80
- const ok = await (0, yesno_1.default)({
81
- question: 'Are you sure you want to continue? [y/N]',
82
- defaultValue: false,
83
- });
84
- if (!ok) {
85
- console.log('Aborted.');
86
- process.exit(0);
87
- }
76
+ if (!o?.yes)
77
+ await confirmOrExit();
88
78
  (0, util_1.applyFileDiff)(diff);
89
79
  console.log('API generated.');
90
80
  });
91
81
  program
92
82
  .command('gen-server')
93
83
  .description('Generate a TS server API')
84
+ .option('--yes', 'skip confirmation')
94
85
  .argument('<outdir>', 'path of the directory to write to', toPath)
95
86
  .argument('<lexicons...>', 'paths of the lexicon files to include', toPaths)
96
- .action(async (outDir, lexiconPaths) => {
87
+ .action(async (outDir, lexiconPaths, o) => {
97
88
  const lexicons = (0, util_1.readAllLexicons)(lexiconPaths);
98
89
  const api = await (0, server_1.genServerApi)(lexicons);
99
90
  const diff = (0, util_1.genFileDiff)(outDir, api);
100
91
  console.log('This will write the following files:');
101
92
  (0, util_1.printFileDiff)(diff);
102
- const ok = await (0, yesno_1.default)({
103
- question: 'Are you sure you want to continue? [y/N]',
104
- defaultValue: false,
105
- });
106
- if (!ok) {
107
- console.log('Aborted.');
108
- process.exit(0);
109
- }
93
+ if (!o?.yes)
94
+ await confirmOrExit();
110
95
  (0, util_1.applyFileDiff)(diff);
111
96
  console.log('API generated.');
112
97
  });
@@ -119,4 +104,14 @@ function toPaths(v, acc) {
119
104
  acc.push(path_1.default.resolve(v));
120
105
  return acc;
121
106
  }
107
+ async function confirmOrExit() {
108
+ const ok = await (0, yesno_1.default)({
109
+ question: 'Are you sure you want to continue? [y/N]',
110
+ defaultValue: false,
111
+ });
112
+ if (!ok) {
113
+ console.log('Aborted.');
114
+ process.exit(0);
115
+ }
116
+ }
122
117
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@atproto/lex-cli",
3
- "version": "0.4.0",
3
+ "version": "0.5.0-rc.0",
4
4
  "license": "MIT",
5
5
  "description": "TypeScript codegen tool for atproto Lexicon schemas",
6
6
  "keywords": [
@@ -21,10 +21,11 @@
21
21
  "dependencies": {
22
22
  "chalk": "^4.1.2",
23
23
  "commander": "^9.4.0",
24
+ "prettier": "^3.2.5",
24
25
  "ts-morph": "^16.0.0",
25
26
  "yesno": "^0.4.0",
26
- "zod": "^3.21.4",
27
- "@atproto/lexicon": "^0.4.0",
27
+ "zod": "^3.23.8",
28
+ "@atproto/lexicon": "^0.4.1-rc.0",
28
29
  "@atproto/syntax": "^0.3.0"
29
30
  },
30
31
  "scripts": {
@@ -61,13 +61,14 @@ const indexTs = (
61
61
  nsidTokens: Record<string, string[]>,
62
62
  ) =>
63
63
  gen(project, '/index.ts', async (file) => {
64
- //= import {Client as XrpcClient, AtpServiceClient as XrpcServiceClient} from '@atproto/xrpc'
64
+ //= import { XrpcClient, FetchHandler, FetchHandlerOptions } from '@atproto/xrpc'
65
65
  const xrpcImport = file.addImportDeclaration({
66
66
  moduleSpecifier: '@atproto/xrpc',
67
67
  })
68
68
  xrpcImport.addNamedImports([
69
- { name: 'Client', alias: 'XrpcClient' },
70
- { name: 'ServiceClient', alias: 'XrpcServiceClient' },
69
+ { name: 'XrpcClient' },
70
+ { name: 'FetchHandler' },
71
+ { name: 'FetchHandlerOptions' },
71
72
  ])
72
73
  //= import {schemas} from './lexicons'
73
74
  file
@@ -119,87 +120,44 @@ const indexTs = (
119
120
  const clientCls = file.addClass({
120
121
  name: 'AtpBaseClient',
121
122
  isExported: true,
123
+ extends: 'XrpcClient',
122
124
  })
123
- //= xrpc: XrpcClient = new XrpcClient()
124
- clientCls.addProperty({
125
- name: 'xrpc',
126
- type: 'XrpcClient',
127
- initializer: 'new XrpcClient()',
128
- })
129
- //= constructor () {
130
- //= this.xrpc.addLexicons(schemas)
131
- //= }
132
- clientCls.addConstructor().setBodyText(`this.xrpc.addLexicons(schemas)`)
133
- //= service(serviceUri: string | URL): AtpServiceClient {
134
- //= return new AtpServiceClient(this, this.xrpc.service(serviceUri))
135
- //= }
136
- clientCls
137
- .addMethod({
138
- name: 'service',
139
- parameters: [{ name: 'serviceUri', type: 'string | URL' }],
140
- returnType: 'AtpServiceClient',
141
- })
142
- .setBodyText(
143
- `return new AtpServiceClient(this, this.xrpc.service(serviceUri))`,
144
- )
145
125
 
146
- //= export class AtpServiceClient {...}
147
- const serviceClientCls = file.addClass({
148
- name: 'AtpServiceClient',
149
- isExported: true,
150
- })
151
- //= _baseClient: AtpBaseClient
152
- serviceClientCls.addProperty({ name: '_baseClient', type: 'AtpBaseClient' })
153
- //= xrpc: XrpcServiceClient
154
- serviceClientCls.addProperty({
155
- name: 'xrpc',
156
- type: 'XrpcServiceClient',
157
- })
158
126
  for (const ns of nsidTree) {
159
127
  //= ns: NS
160
- serviceClientCls.addProperty({
128
+ clientCls.addProperty({
161
129
  name: ns.propName,
162
130
  type: ns.className,
163
131
  })
164
132
  }
165
- //= constructor (baseClient: AtpBaseClient, xrpcService: XrpcServiceClient) {
166
- //= this.baseClient = baseClient
167
- //= this.xrpcService = xrpcService
133
+
134
+ //= constructor (options: FetchHandler | FetchHandlerOptions) {
135
+ //= super(options, schemas)
168
136
  //= {namespace declarations}
169
137
  //= }
170
- serviceClientCls
171
- .addConstructor({
172
- parameters: [
173
- { name: 'baseClient', type: 'AtpBaseClient' },
174
- { name: 'xrpcService', type: 'XrpcServiceClient' },
175
- ],
176
- })
177
- .setBodyText(
178
- [
179
- `this._baseClient = baseClient`,
180
- `this.xrpc = xrpcService`,
181
- ...nsidTree.map(
182
- (ns) => `this.${ns.propName} = new ${ns.className}(this)`,
183
- ),
184
- ].join('\n'),
185
- )
138
+ clientCls.addConstructor({
139
+ parameters: [
140
+ { name: 'options', type: 'FetchHandler | FetchHandlerOptions' },
141
+ ],
142
+ statements: [
143
+ 'super(options, schemas)',
144
+ ...nsidTree.map(
145
+ (ns) => `this.${ns.propName} = new ${ns.className}(this)`,
146
+ ),
147
+ ],
148
+ })
186
149
 
187
- //= setHeader(key: string, value: string): void {
188
- //= this.xrpc.setHeader(key, value)
150
+ //= /** @deprecated use `this` instead */
151
+ //= get xrpc(): XrpcClient {
152
+ //= return this
189
153
  //= }
190
- const setHeaderMethod = serviceClientCls.addMethod({
191
- name: 'setHeader',
192
- returnType: 'void',
193
- })
194
- setHeaderMethod.addParameter({
195
- name: 'key',
196
- type: 'string',
197
- })
198
- setHeaderMethod.addParameter({
199
- name: 'value',
200
- type: 'string',
201
- })
202
- setHeaderMethod.setBodyText('this.xrpc.setHeader(key, value)')
154
+ clientCls
155
+ .addGetAccessor({
156
+ name: 'xrpc',
157
+ returnType: 'XrpcClient',
158
+ statements: ['return this'],
159
+ })
160
+ .addJsDoc('@deprecated use `this` instead')
203
161
 
204
162
  // generate classes for the schemas
205
163
  for (const ns of nsidTree) {
@@ -213,10 +171,10 @@ function genNamespaceCls(file: SourceFile, ns: DefTreeNode) {
213
171
  name: ns.className,
214
172
  isExported: true,
215
173
  })
216
- //= _service: AtpServiceClient
174
+ //= _client: XrpcClient
217
175
  cls.addProperty({
218
- name: '_service',
219
- type: 'AtpServiceClient',
176
+ name: '_client',
177
+ type: 'XrpcClient',
220
178
  })
221
179
 
222
180
  for (const userType of ns.userTypes) {
@@ -242,21 +200,22 @@ function genNamespaceCls(file: SourceFile, ns: DefTreeNode) {
242
200
  genNamespaceCls(file, child)
243
201
  }
244
202
 
245
- //= constructor(service: AtpServiceClient) {
246
- //= this._service = service
203
+ //= constructor(public client: XrpcClient) {
204
+ //= this._client = client
247
205
  //= {child namespace prop declarations}
248
206
  //= {record prop declarations}
249
207
  //= }
250
- const cons = cls.addConstructor()
251
- cons.addParameter({
252
- name: 'service',
253
- type: 'AtpServiceClient',
254
- })
255
- cons.setBodyText(
256
- [
257
- `this._service = service`,
208
+ cls.addConstructor({
209
+ parameters: [
210
+ {
211
+ name: 'client',
212
+ type: 'XrpcClient',
213
+ },
214
+ ],
215
+ statements: [
216
+ `this._client = client`,
258
217
  ...ns.children.map(
259
- (ns) => `this.${ns.propName} = new ${ns.className}(service)`,
218
+ (ns) => `this.${ns.propName} = new ${ns.className}(client)`,
260
219
  ),
261
220
  ...ns.userTypes
262
221
  .filter((ut) => ut.def.type === 'record')
@@ -264,10 +223,10 @@ function genNamespaceCls(file: SourceFile, ns: DefTreeNode) {
264
223
  const name = NSID.parse(ut.nsid).name || ''
265
224
  return `this.${toCamelCase(name)} = new ${toTitleCase(
266
225
  name,
267
- )}Record(service)`
226
+ )}Record(client)`
268
227
  }),
269
- ].join('\n'),
270
- )
228
+ ],
229
+ })
271
230
 
272
231
  // methods
273
232
  for (const userType of ns.userTypes) {
@@ -298,13 +257,14 @@ function genNamespaceCls(file: SourceFile, ns: DefTreeNode) {
298
257
  })
299
258
  method.setBodyText(
300
259
  [
301
- `return this._service.xrpc`,
260
+ `return this._client`,
302
261
  isGetReq
303
262
  ? `.call('${userType.nsid}', params, undefined, opts)`
304
263
  : `.call('${userType.nsid}', opts?.qp, data, opts)`,
305
- ` .catch((e) => {`,
306
- ` throw ${moduleName}.toKnownErr(e)`,
307
- ` })`,
264
+ userType.def.errors?.length
265
+ ? // Only add a catch block if there are custom errors
266
+ ` .catch((e) => { throw ${moduleName}.toKnownErr(e) })`
267
+ : '',
308
268
  ].join('\n'),
309
269
  )
310
270
  }
@@ -325,21 +285,21 @@ function genRecordCls(file: SourceFile, nsid: string, lexRecord: LexRecord) {
325
285
  name: `${toTitleCase(name)}Record`,
326
286
  isExported: true,
327
287
  })
328
- //= _service: AtpServiceClient
288
+ //= _client: XrpcClient
329
289
  cls.addProperty({
330
- name: '_service',
331
- type: 'AtpServiceClient',
290
+ name: '_client',
291
+ type: 'XrpcClient',
332
292
  })
333
293
 
334
- //= constructor(service: AtpServiceClient) {
335
- //= this._service = service
294
+ //= constructor(client: XrpcClient) {
295
+ //= this._client = client
336
296
  //= }
337
297
  const cons = cls.addConstructor()
338
298
  cons.addParameter({
339
- name: 'service',
340
- type: 'AtpServiceClient',
299
+ name: 'client',
300
+ type: 'XrpcClient',
341
301
  })
342
- cons.setBodyText(`this._service = service`)
302
+ cons.setBodyText(`this._client = client`)
343
303
 
344
304
  // methods
345
305
  const typeModule = toTitleCase(nsid)
@@ -356,7 +316,7 @@ function genRecordCls(file: SourceFile, nsid: string, lexRecord: LexRecord) {
356
316
  })
357
317
  method.setBodyText(
358
318
  [
359
- `const res = await this._service.xrpc.call('${ATP_METHODS.list}', { collection: '${nsid}', ...params })`,
319
+ `const res = await this._client.call('${ATP_METHODS.list}', { collection: '${nsid}', ...params })`,
360
320
  `return res.data`,
361
321
  ].join('\n'),
362
322
  )
@@ -374,7 +334,7 @@ function genRecordCls(file: SourceFile, nsid: string, lexRecord: LexRecord) {
374
334
  })
375
335
  method.setBodyText(
376
336
  [
377
- `const res = await this._service.xrpc.call('${ATP_METHODS.get}', { collection: '${nsid}', ...params })`,
337
+ `const res = await this._client.call('${ATP_METHODS.get}', { collection: '${nsid}', ...params })`,
378
338
  `return res.data`,
379
339
  ].join('\n'),
380
340
  )
@@ -406,7 +366,7 @@ function genRecordCls(file: SourceFile, nsid: string, lexRecord: LexRecord) {
406
366
  method.setBodyText(
407
367
  [
408
368
  `record.$type = '${nsid}'`,
409
- `const res = await this._service.xrpc.call('${ATP_METHODS.create}', undefined, { collection: '${nsid}', ${maybeRkeyPart}...params, record }, {encoding: 'application/json', headers })`,
369
+ `const res = await this._client.call('${ATP_METHODS.create}', undefined, { collection: '${nsid}', ${maybeRkeyPart}...params, record }, {encoding: 'application/json', headers })`,
410
370
  `return res.data`,
411
371
  ].join('\n'),
412
372
  )
@@ -433,7 +393,7 @@ function genRecordCls(file: SourceFile, nsid: string, lexRecord: LexRecord) {
433
393
  // method.setBodyText(
434
394
  // [
435
395
  // `record.$type = '${userType.nsid}'`,
436
- // `const res = await this._service.xrpc.call('${ATP_METHODS.put}', undefined, { collection: '${userType.nsid}', record, ...params }, {encoding: 'application/json', headers})`,
396
+ // `const res = await this._client.call('${ATP_METHODS.put}', undefined, { collection: '${userType.nsid}', record, ...params }, {encoding: 'application/json', headers})`,
437
397
  // `return res.data`,
438
398
  // ].join('\n'),
439
399
  // )
@@ -458,7 +418,7 @@ function genRecordCls(file: SourceFile, nsid: string, lexRecord: LexRecord) {
458
418
 
459
419
  method.setBodyText(
460
420
  [
461
- `await this._service.xrpc.call('${ATP_METHODS.delete}', undefined, { collection: '${nsid}', ...params }, { headers })`,
421
+ `await this._client.call('${ATP_METHODS.delete}', undefined, { collection: '${nsid}', ...params }, { headers })`,
462
422
  ].join('\n'),
463
423
  )
464
424
  }
@@ -477,11 +437,14 @@ const lexiconTs = (project, lexicons: Lexicons, lexiconDoc: LexiconDoc) =>
477
437
  main?.type === 'subscription' ||
478
438
  main?.type === 'procedure'
479
439
  ) {
480
- //= import {Headers, XRPCError} from '@atproto/xrpc'
440
+ //= import {HeadersMap, XRPCError} from '@atproto/xrpc'
481
441
  const xrpcImport = file.addImportDeclaration({
482
442
  moduleSpecifier: '@atproto/xrpc',
483
443
  })
484
- xrpcImport.addNamedImports([{ name: 'Headers' }, { name: 'XRPCError' }])
444
+ xrpcImport.addNamedImports([
445
+ { name: 'HeadersMap' },
446
+ { name: 'XRPCError' },
447
+ ])
485
448
  }
486
449
  //= import {ValidationResult, BlobRef} from '@atproto/lexicon'
487
450
  file
@@ -550,7 +513,8 @@ function genClientXrpcCommon(
550
513
  name: 'CallOptions',
551
514
  isExported: true,
552
515
  })
553
- opts.addProperty({ name: 'headers?', type: 'Headers' })
516
+ opts.addProperty({ name: 'signal?', type: 'AbortSignal' })
517
+ opts.addProperty({ name: 'headers?', type: 'HeadersMap' })
554
518
  if (def.type === 'procedure') {
555
519
  opts.addProperty({ name: 'qp?', type: 'QueryParams' })
556
520
  }
@@ -563,7 +527,7 @@ function genClientXrpcCommon(
563
527
  .join(' | ')
564
528
  }
565
529
  opts.addProperty({
566
- name: 'encoding',
530
+ name: 'encoding?',
567
531
  type: encodingType,
568
532
  })
569
533
  }
@@ -574,7 +538,7 @@ function genClientXrpcCommon(
574
538
  isExported: true,
575
539
  })
576
540
  res.addProperty({ name: 'success', type: 'boolean' })
577
- res.addProperty({ name: 'headers', type: 'Headers' })
541
+ res.addProperty({ name: 'headers', type: 'HeadersMap' })
578
542
  if (def.output?.schema) {
579
543
  if (def.output.encoding?.includes(',')) {
580
544
  res.addProperty({ name: 'data', type: 'OutputSchema | Uint8Array' })
@@ -595,30 +559,32 @@ function genClientXrpcCommon(
595
559
  extends: 'XRPCError',
596
560
  isExported: true,
597
561
  })
598
- errCls
599
- .addConstructor({
600
- parameters: [{ name: 'src', type: 'XRPCError' }],
601
- })
602
- .setBodyText(`super(src.status, src.error, src.message, src.headers)`)
562
+ errCls.addConstructor({
563
+ parameters: [{ name: 'src', type: 'XRPCError' }],
564
+ statements: [
565
+ 'super(src.status, src.error, src.message, src.headers, { cause: src })',
566
+ ],
567
+ })
568
+
603
569
  customErrors.push({ name: error.name, cls: name })
604
570
  }
605
571
 
606
572
  // export function toKnownErr(err: any) {...}
607
- const toKnownErrFn = file.addFunction({
573
+ file.addFunction({
608
574
  name: 'toKnownErr',
609
575
  isExported: true,
576
+ parameters: [{ name: 'e', type: 'any' }],
577
+ statements: customErrors.length
578
+ ? [
579
+ 'if (e instanceof XRPCError) {',
580
+ ...customErrors.map(
581
+ (err) => `if (e.error === '${err.name}') return new ${err.cls}(e)`,
582
+ ),
583
+ '}',
584
+ 'return e',
585
+ ]
586
+ : ['return e'],
610
587
  })
611
- toKnownErrFn.addParameter({ name: 'e', type: 'any' })
612
- toKnownErrFn.setBodyText(
613
- [
614
- `if (e instanceof XRPCError) {`,
615
- ...customErrors.map(
616
- (err) => `if (e.error === '${err.name}') return new ${err.cls}(e)`,
617
- ),
618
- `}`,
619
- `return e`,
620
- ].join('\n'),
621
- )
622
588
  }
623
589
 
624
590
  function genClientRecord(
@@ -4,7 +4,7 @@ import prettier from 'prettier'
4
4
  import { GeneratedFile } from '../types'
5
5
 
6
6
  const PRETTIER_OPTS = {
7
- parser: 'babel-ts',
7
+ parser: 'typescript',
8
8
  tabWidth: 2,
9
9
  semi: false,
10
10
  singleQuote: true,
@@ -14,17 +14,17 @@ const PRETTIER_OPTS = {
14
14
  export const utilTs = (project) =>
15
15
  gen(project, '/util.ts', async (file) => {
16
16
  file.replaceWithText(`
17
- export function isObj(v: unknown): v is Record<string, unknown> {
18
- return typeof v === 'object' && v !== null
19
- }
20
-
21
- export function hasProp<K extends PropertyKey>(
22
- data: object,
23
- prop: K,
24
- ): data is Record<K, unknown> {
25
- return prop in data
26
- }
27
- `)
17
+ export function isObj(v: unknown): v is Record<string, unknown> {
18
+ return typeof v === 'object' && v !== null
19
+ }
20
+
21
+ export function hasProp<K extends PropertyKey>(
22
+ data: object,
23
+ prop: K,
24
+ ): data is Record<K, unknown> {
25
+ return prop in data
26
+ }
27
+ `)
28
28
  })
29
29
 
30
30
  export const lexiconsTs = (project, lexicons: LexiconDoc[]) =>
@@ -122,7 +122,7 @@ export async function gen(
122
122
  const src = project.getFileSystem().readFileSync(path)
123
123
  return {
124
124
  path: path,
125
- content: `${banner()}${prettier.format(src, PRETTIER_OPTS)}`,
125
+ content: `${banner()}${await prettier.format(src, PRETTIER_OPTS)}`,
126
126
  }
127
127
  }
128
128
 
@@ -335,11 +335,11 @@ export function genXrpcInput(
335
335
  )
336
336
  }
337
337
  } else if (def.type === 'procedure' && def.input?.encoding) {
338
- //= export type InputSchema = string | Uint8Array
338
+ //= export type InputSchema = string | Uint8Array | Blob
339
339
  file.addTypeAlias({
340
340
  isExported: true,
341
341
  name: 'InputSchema',
342
- type: 'string | Uint8Array',
342
+ type: 'string | Uint8Array | Blob',
343
343
  })
344
344
  } else {
345
345
  //= export type InputSchema = undefined