tangled
alpha
login
or
join now
mokkenstorm.dev
/
openapi-ts
0
fork
atom
fork of hey-api/openapi-ts because I need some additional things
0
fork
atom
overview
issues
pulls
pipelines
chore: support thunks in doc methods
Lubos
3 months ago
99be2403
1cbb8262
+81
-69
10 changed files
expand all
collapse all
unified
split
dev
openapi-ts.config.ts
packages
openapi-ts
src
plugins
@hey-api
sdk
shared
class.ts
ts-dsl
decl
class.ts
field.ts
layout
doc.ts
hint.ts
note.ts
mixins
doc.ts
hint.ts
note.ts
+2
-2
dev/openapi-ts.config.ts
···
47
47
// 'full.yaml',
48
48
// 'sdk-method-class-conflict.yaml',
49
49
// 'object-property-names.yaml',
50
50
-
'openai.yaml',
51
51
-
// 'opencode.yaml',
50
50
+
// 'openai.yaml',
51
51
+
'opencode.yaml',
52
52
// 'pagination-ref.yaml',
53
53
// 'sdk-instance.yaml',
54
54
// 'sdk-nested-classes.yaml',
+9
-8
packages/openapi-ts/src/plugins/@hey-api/sdk/shared/class.ts
···
47
47
export const registryName = '__registry';
48
48
49
49
const createRegistryClass = ({
50
50
+
plugin,
50
51
sdkSymbol,
51
52
symbol,
52
53
}: {
···
54
55
sdkSymbol: Symbol;
55
56
symbol: Symbol;
56
57
}): TsDsl => {
57
57
-
const defaultKey = 'defaultKey';
58
58
-
const instances = 'instances';
58
58
+
const symbolDefaultKey = plugin.symbol('defaultKey');
59
59
+
const symbolInstances = plugin.symbol('instances');
59
60
return $.class(symbol)
60
61
.generic('T')
61
61
-
.field(defaultKey, (f) =>
62
62
+
.field(symbolDefaultKey, (f) =>
62
63
f.private().readonly().assign($.literal('default')),
63
64
)
64
65
.newline()
65
65
-
.field(instances, (f) =>
66
66
+
.field(symbolInstances, (f) =>
66
67
f
67
68
.private()
68
69
.readonly()
···
77
78
.do(
78
79
$.const('instance').assign(
79
80
$('this')
80
80
-
.attr('instances')
81
81
+
.attr(symbolInstances)
81
82
.attr('get')
82
82
-
.call($('key').coalesce($('this').attr(defaultKey))),
83
83
+
.call($('key').coalesce($('this').attr(symbolDefaultKey))),
83
84
),
84
85
$.if($.not('instance')).do(
85
86
$.throw('Error').message(
···
99
100
.param('key', (p) => p.type('string').optional())
100
101
.do(
101
102
$('this')
102
102
-
.attr(instances)
103
103
+
.attr(symbolInstances)
103
104
.attr('set')
104
104
-
.call($('key').coalesce($('this').attr(defaultKey)), 'value'),
105
105
+
.call($('key').coalesce($('this').attr(symbolDefaultKey)), 'value'),
105
106
),
106
107
);
107
108
};
+2
-1
packages/openapi-ts/src/ts-dsl/decl/class.ts
···
10
10
import { AbstractMixin, DefaultMixin, ExportMixin } from '../mixins/modifiers';
11
11
import { TypeParamsMixin } from '../mixins/type-params';
12
12
import { safeRuntimeName } from '../utils/name';
13
13
+
import type { FieldName } from './field';
13
14
import { FieldTsDsl } from './field';
14
15
import { InitTsDsl } from './init';
15
16
import { MethodTsDsl } from './method';
···
70
71
}
71
72
72
73
/** Adds a class field. */
73
73
-
field(name: string, fn?: (f: FieldTsDsl) => void): this {
74
74
+
field(name: FieldName, fn?: (f: FieldTsDsl) => void): this {
74
75
const f = new FieldTsDsl(name, fn);
75
76
this.body.push(f);
76
77
return this;
+5
-4
packages/openapi-ts/src/ts-dsl/decl/field.ts
···
1
1
-
import type { AnalysisContext } from '@hey-api/codegen-core';
1
1
+
import type { AnalysisContext, Symbol } from '@hey-api/codegen-core';
2
2
import ts from 'typescript';
3
3
4
4
import { TsDsl, TypeTsDsl } from '../base';
···
15
15
import type { TypeExprName } from '../type/expr';
16
16
import { TypeExprTsDsl } from '../type/expr';
17
17
18
18
+
export type FieldName = Symbol | string;
18
19
export type FieldType = TypeExprName | TypeTsDsl;
19
20
20
21
const Mixed = DecoratorMixin(
···
32
33
export class FieldTsDsl extends Mixed {
33
34
readonly '~dsl' = 'FieldTsDsl';
34
35
35
35
-
protected name: string;
36
36
+
protected name: FieldName;
36
37
protected _type?: TypeTsDsl;
37
38
38
38
-
constructor(name: string, fn?: (f: FieldTsDsl) => void) {
39
39
+
constructor(name: FieldName, fn?: (f: FieldTsDsl) => void) {
39
40
super();
40
41
this.name = name;
41
42
fn?.(this);
···
55
56
override toAst() {
56
57
const node = ts.factory.createPropertyDeclaration(
57
58
[...this.$decorators(), ...this.modifiers],
58
58
-
this.name,
59
59
+
this.$node(this.name) as ts.PropertyName,
59
60
undefined,
60
61
this.$type(this._type),
61
62
this.$value(),
+16
-12
packages/openapi-ts/src/ts-dsl/layout/doc.ts
···
5
5
import { TsDsl } from '../base';
6
6
import { IdTsDsl } from '../expr/id';
7
7
8
8
+
type DocMaybeLazy<T> = (() => T) | T;
9
9
+
export type DocFn = (d: DocTsDsl) => void;
10
10
+
export type DocLines = DocMaybeLazy<MaybeArray<string>>;
11
11
+
8
12
export class DocTsDsl extends TsDsl<ts.Node> {
9
13
readonly '~dsl' = 'DocTsDsl';
10
14
11
11
-
protected _lines: Array<string> = [];
15
15
+
protected _lines: Array<DocLines> = [];
12
16
13
13
-
constructor(lines?: MaybeArray<string>, fn?: (d: DocTsDsl) => void) {
17
17
+
constructor(lines?: DocLines, fn?: DocFn) {
14
18
super();
15
15
-
if (lines) {
16
16
-
if (typeof lines === 'string') {
17
17
-
this.add(lines);
18
18
-
} else {
19
19
-
this.add(...lines);
20
20
-
}
21
21
-
}
19
19
+
if (lines) this.add(lines);
22
20
fn?.(this);
23
21
}
24
22
···
26
24
super.analyze(ctx);
27
25
}
28
26
29
29
-
add(...lines: ReadonlyArray<string>): this {
30
30
-
this._lines.push(...lines);
27
27
+
add(lines: DocLines): this {
28
28
+
this._lines.push(lines);
31
29
return this;
32
30
}
33
31
34
32
apply<T extends ts.Node>(node: T): T {
35
35
-
const lines = this._lines.filter((line) => Boolean(line) || line === '');
33
33
+
const lines = this._lines.reduce((lines: Array<string>, line: DocLines) => {
34
34
+
if (typeof line === 'function') line = line();
35
35
+
for (const l of typeof line === 'string' ? [line] : line) {
36
36
+
if (l || l === '') lines.push(l);
37
37
+
}
38
38
+
return lines;
39
39
+
}, []);
36
40
if (!lines.length) return node;
37
41
38
42
const jsdocTexts = lines.map((line) =>
+19
-12
packages/openapi-ts/src/ts-dsl/layout/hint.ts
···
5
5
import { TsDsl } from '../base';
6
6
import { IdTsDsl } from '../expr/id';
7
7
8
8
+
type HintMaybeLazy<T> = (() => T) | T;
9
9
+
export type HintFn = (d: HintTsDsl) => void;
10
10
+
export type HintLines = HintMaybeLazy<MaybeArray<string>>;
11
11
+
8
12
export class HintTsDsl extends TsDsl<ts.Node> {
9
13
readonly '~dsl' = 'HintTsDsl';
10
14
11
11
-
protected _lines: Array<string> = [];
15
15
+
protected _lines: Array<HintLines> = [];
12
16
13
13
-
constructor(lines?: MaybeArray<string>, fn?: (d: HintTsDsl) => void) {
17
17
+
constructor(lines?: HintLines, fn?: HintFn) {
14
18
super();
15
15
-
if (lines) {
16
16
-
if (typeof lines === 'string') {
17
17
-
this.add(lines);
18
18
-
} else {
19
19
-
this.add(...lines);
20
20
-
}
21
21
-
}
19
19
+
if (lines) this.add(lines);
22
20
fn?.(this);
23
21
}
24
22
···
26
24
super.analyze(ctx);
27
25
}
28
26
29
29
-
add(...lines: ReadonlyArray<string>): this {
30
30
-
this._lines.push(...lines);
27
27
+
add(lines: HintLines): this {
28
28
+
this._lines.push(lines);
31
29
return this;
32
30
}
33
31
34
32
apply<T extends ts.Node>(node: T): T {
35
35
-
const lines = this._lines.filter((line) => Boolean(line) || line === '');
33
33
+
const lines = this._lines.reduce(
34
34
+
(lines: Array<string>, line: HintLines) => {
35
35
+
if (typeof line === 'function') line = line();
36
36
+
for (const l of typeof line === 'string' ? [line] : line) {
37
37
+
if (l || l === '') lines.push(l);
38
38
+
}
39
39
+
return lines;
40
40
+
},
41
41
+
[],
42
42
+
);
36
43
if (!lines.length) return node;
37
44
38
45
for (const line of lines) {
+19
-12
packages/openapi-ts/src/ts-dsl/layout/note.ts
···
5
5
import { TsDsl } from '../base';
6
6
import { IdTsDsl } from '../expr/id';
7
7
8
8
+
type NoteMaybeLazy<T> = (() => T) | T;
9
9
+
export type NoteFn = (d: NoteTsDsl) => void;
10
10
+
export type NoteLines = NoteMaybeLazy<MaybeArray<string>>;
11
11
+
8
12
export class NoteTsDsl extends TsDsl<ts.Node> {
9
13
readonly '~dsl' = 'NoteTsDsl';
10
14
11
11
-
protected _lines: Array<string> = [];
15
15
+
protected _lines: Array<NoteLines> = [];
12
16
13
13
-
constructor(lines?: MaybeArray<string>, fn?: (d: NoteTsDsl) => void) {
17
17
+
constructor(lines?: NoteLines, fn?: NoteFn) {
14
18
super();
15
15
-
if (lines) {
16
16
-
if (typeof lines === 'string') {
17
17
-
this.add(lines);
18
18
-
} else {
19
19
-
this.add(...lines);
20
20
-
}
21
21
-
}
19
19
+
if (lines) this.add(lines);
22
20
fn?.(this);
23
21
}
24
22
···
26
24
super.analyze(ctx);
27
25
}
28
26
29
29
-
add(...lines: ReadonlyArray<string>): this {
30
30
-
this._lines.push(...lines);
27
27
+
add(lines: NoteLines): this {
28
28
+
this._lines.push(lines);
31
29
return this;
32
30
}
33
31
34
32
apply<T extends ts.Node>(node: T): T {
35
35
-
const lines = this._lines.filter((line) => Boolean(line) || line === '');
33
33
+
const lines = this._lines.reduce(
34
34
+
(lines: Array<string>, line: NoteLines) => {
35
35
+
if (typeof line === 'function') line = line();
36
36
+
for (const l of typeof line === 'string' ? [line] : line) {
37
37
+
if (l || l === '') lines.push(l);
38
38
+
}
39
39
+
return lines;
40
40
+
},
41
41
+
[],
42
42
+
);
36
43
if (!lines.length) return node;
37
44
38
45
ts.addSyntheticLeadingComment(
+3
-6
packages/openapi-ts/src/ts-dsl/mixins/doc.ts
···
1
1
import type { AnalysisContext, Node } from '@hey-api/codegen-core';
2
2
import type ts from 'typescript';
3
3
4
4
-
import type { MaybeArray } from '../base';
4
4
+
import type { DocFn, DocLines } from '../layout/doc';
5
5
import { DocTsDsl } from '../layout/doc';
6
6
import type { BaseCtor, MixinCtor } from './types';
7
7
8
8
export interface DocMethods extends Node {
9
9
$docs<T extends ts.Node>(node: T): T;
10
10
-
doc(lines?: MaybeArray<string>, fn?: (d: DocTsDsl) => void): this;
10
10
+
doc(lines?: DocLines, fn?: DocFn): this;
11
11
}
12
12
13
13
export function DocMixin<T extends ts.Node, TBase extends BaseCtor<T>>(
···
20
20
super.analyze(ctx);
21
21
}
22
22
23
23
-
protected doc(
24
24
-
lines?: MaybeArray<string>,
25
25
-
fn?: (d: DocTsDsl) => void,
26
26
-
): this {
23
23
+
protected doc(lines?: DocLines, fn?: DocFn): this {
27
24
this._doc = new DocTsDsl(lines, fn);
28
25
return this;
29
26
}
+3
-6
packages/openapi-ts/src/ts-dsl/mixins/hint.ts
···
1
1
import type { AnalysisContext, Node } from '@hey-api/codegen-core';
2
2
import type ts from 'typescript';
3
3
4
4
-
import type { MaybeArray } from '../base';
4
4
+
import type { HintFn, HintLines } from '../layout/hint';
5
5
import { HintTsDsl } from '../layout/hint';
6
6
import type { BaseCtor, MixinCtor } from './types';
7
7
8
8
export interface HintMethods extends Node {
9
9
$hint<T extends ts.Node>(node: T): T;
10
10
-
hint(lines?: MaybeArray<string>, fn?: (h: HintTsDsl) => void): this;
10
10
+
hint(lines?: HintLines, fn?: HintFn): this;
11
11
}
12
12
13
13
export function HintMixin<T extends ts.Node, TBase extends BaseCtor<T>>(
···
20
20
super.analyze(ctx);
21
21
}
22
22
23
23
-
protected hint(
24
24
-
lines?: MaybeArray<string>,
25
25
-
fn?: (h: HintTsDsl) => void,
26
26
-
): this {
23
23
+
protected hint(lines?: HintLines, fn?: HintFn): this {
27
24
this._hint = new HintTsDsl(lines, fn);
28
25
return this;
29
26
}
+3
-6
packages/openapi-ts/src/ts-dsl/mixins/note.ts
···
1
1
import type { AnalysisContext, Node } from '@hey-api/codegen-core';
2
2
import type ts from 'typescript';
3
3
4
4
-
import type { MaybeArray } from '../base';
4
4
+
import type { NoteFn, NoteLines } from '../layout/note';
5
5
import { NoteTsDsl } from '../layout/note';
6
6
import type { BaseCtor, MixinCtor } from './types';
7
7
8
8
export interface NoteMethods extends Node {
9
9
$note<T extends ts.Node>(node: T): T;
10
10
-
note(lines?: MaybeArray<string>, fn?: (h: NoteTsDsl) => void): this;
10
10
+
note(lines?: NoteLines, fn?: NoteFn): this;
11
11
}
12
12
13
13
export function NoteMixin<T extends ts.Node, TBase extends BaseCtor<T>>(
···
20
20
super.analyze(ctx);
21
21
}
22
22
23
23
-
protected note(
24
24
-
lines?: MaybeArray<string>,
25
25
-
fn?: (h: NoteTsDsl) => void,
26
26
-
): this {
23
23
+
protected note(lines?: NoteLines, fn?: NoteFn): this {
27
24
this._note = new NoteTsDsl(lines, fn);
28
25
return this;
29
26
}