@f3liz/rescript-autogen-openapi 0.5.4 → 0.6.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.
@@ -47,22 +47,29 @@ let generateMethodSignature = (~endpoint: endpoint, ~functionName) => {
47
47
  ? `client: MisskeyClient, request: ${CodegenUtils.toPascalCase(functionName)}Request`
48
48
  : "client: MisskeyClient"
49
49
 
50
- let docLines = endpoint.summary->Option.mapOr([], summary => {
51
- let lines = [" /**", ` * ${summary}`]
52
- endpoint.description->Option.forEach(description => {
53
- if description != summary {
54
- lines->Array.push(` * ${description}`)
55
- }
56
- })
57
- lines->Array.push(" */")
58
- lines
59
- })
60
-
61
- let code = `
62
- |${docLines->Array.join("\n")}
63
- | ${functionName}(${params}): Promise<${CodegenUtils.toPascalCase(functionName)}Response>;`
64
-
65
- code->CodegenUtils.trimMargin
50
+ let docLines = switch (endpoint.summary, endpoint.description) {
51
+ | (None, None) => ""
52
+ | (Some(summary), None) => ` /** ${summary} */`
53
+ | (None, Some(desc)) => {
54
+ let lines = desc->String.split("\n")->Array.map(line => line == "" ? " *" : ` * ${line}`)
55
+ ` /**\n${lines->Array.join("\n")}\n */`
56
+ }
57
+ | (Some(summary), Some(desc)) if summary == desc => ` /** ${summary} */`
58
+ | (Some(summary), Some(desc)) => {
59
+ let descLines = desc->String.split("\n")->Array.map(line => line == "" ? " *" : ` * ${line}`)
60
+ ` /**\n * ${summary}\n *\n${descLines->Array.join("\n")}\n */`
61
+ }
62
+ }
63
+
64
+ Handlebars.render(
65
+ Templates.methodSignature,
66
+ {
67
+ "docLines": docLines,
68
+ "functionName": functionName,
69
+ "params": params,
70
+ "responsePascalName": CodegenUtils.toPascalCase(functionName),
71
+ },
72
+ )
66
73
  }
67
74
 
68
75
  // Generate .d.ts file for a module (grouped by tag)
@@ -96,26 +103,14 @@ let generateModuleDts = (~moduleName, ~endpoints: array<endpoint>) => {
96
103
  )
97
104
  ->Array.join("\n")
98
105
 
99
- let header = `
100
- |// TypeScript definitions for ${moduleName}
101
- |// Generated by @f3liz/rescript-autogen-openapi
102
- |// DO NOT EDIT
103
- |
104
- |import { MisskeyClient } from './index';
105
- |import * as ComponentSchemas from './ComponentSchemas';
106
- |`->CodegenUtils.trimMargin
107
-
108
- `
109
- |${header}
110
- |
111
- |${interfaces}
112
- |
113
- |export interface ${moduleName}Module {
114
- |${methodSignatures}
115
- |}
116
- |
117
- |export const ${moduleName}: ${moduleName}Module;
118
- |`->CodegenUtils.trimMargin
106
+ Handlebars.render(
107
+ Templates.moduleDts,
108
+ {
109
+ "moduleName": moduleName,
110
+ "interfaces": interfaces,
111
+ "methodSignatures": methodSignatures,
112
+ },
113
+ )
119
114
  }
120
115
 
121
116
  // Generate ComponentSchemas.d.ts
@@ -125,35 +120,20 @@ let generateComponentSchemasDts = (~schemas: Dict.t<jsonSchema>) => {
125
120
  ->Array.map(((name, schema)) => generateTypeScriptType(name, schema.description, schema))
126
121
  ->Array.join("\n\n")
127
122
 
128
- `
129
- |// TypeScript definitions for ComponentSchemas
130
- |// Generated by @f3liz/rescript-autogen-openapi
131
- |// DO NOT EDIT
132
- |
133
- |${content}
134
- |`->CodegenUtils.trimMargin
123
+ Handlebars.render(
124
+ Templates.componentSchemasDts,
125
+ {"content": content},
126
+ )
135
127
  }
136
128
 
137
129
  // Generate main index.d.ts with MisskeyClient class
138
130
  let generateIndexDts = (~moduleNames) => {
139
- let imports = moduleNames->Array.map(m => `import { ${m}Module } from './${m}';`)->Array.join("\n")
140
- let exports = moduleNames->Array.map(m => `export const ${m}: ${m}Module;`)->Array.join("\n")
141
-
142
- `
143
- |// TypeScript definitions
144
- |// Generated by @f3liz/rescript-autogen-openapi
145
- |// DO NOT EDIT
146
- |
147
- |${imports}
148
- |
149
- |export class MisskeyClient {
150
- | constructor(baseUrl: string, token?: string);
151
- | readonly baseUrl: string;
152
- | readonly token?: string;
153
- |}
154
- |
155
- |${exports}
156
- |`->CodegenUtils.trimMargin
131
+ let modules = moduleNames->Array.map(m => {
132
+ "importLine": `import { ${m}Module } from './${m}';`,
133
+ "exportLine": `export const ${m}: ${m}Module;`,
134
+ })
135
+
136
+ Handlebars.render(Templates.indexDts, {"modules": modules})
157
137
  }
158
138
 
159
139
  // Generate all .d.ts files for a spec
@@ -3,43 +3,22 @@
3
3
  // TypeScriptWrapperGenerator.res - Generate TypeScript/JavaScript wrapper
4
4
  open Types
5
5
 
6
- let misskeyClientJsCode = `
7
- |export class MisskeyClient {
8
- | constructor(baseUrl, token) {
9
- | this.baseUrl = baseUrl;
10
- | this.token = token;
11
- | }
12
- |
13
- | async _fetch(url, method, body) {
14
- | const headers = { 'Content-Type': 'application/json' };
15
- | if (this.token) {
16
- | headers['Authorization'] = \`Bearer \${this.token}\`;
17
- | }
18
- | const response = await fetch(this.baseUrl + url, {
19
- | method,
20
- | headers,
21
- | body: body ? JSON.stringify(body) : undefined,
22
- | });
23
- | return response.json();
24
- | }
25
- |}`->CodegenUtils.trimMargin
6
+ let misskeyClientJsCode = {
7
+ let body: string = %raw(`
8
+ "export class MisskeyClient {\n constructor(baseUrl, token) {\n this.baseUrl = baseUrl;\n this.token = token;\n }\n\n async _fetch(url, method, body) {\n const headers = { 'Content-Type': 'application/json' };\n if (this.token) {\n headers['Authorization'] = \x60Bearer \x24{this.token}\x60;\n }\n const response = await fetch(this.baseUrl + url, {\n method,\n headers,\n body: body ? JSON.stringify(body) : undefined,\n });\n return response.json();\n }\n}"
9
+ `)
10
+ body
11
+ }
26
12
 
27
13
  let generateWrapperMjs = (~endpoints, ~generatedModulePath) => {
28
14
  let endpointsByTag = OpenAPIParser.groupByTag(endpoints)
29
15
  let tags = Dict.keysToArray(endpointsByTag)
30
16
 
31
- let imports =
32
- tags
33
- ->Array.map(tag => {
34
- let moduleName = CodegenUtils.toPascalCase(tag)
35
- `import * as ${moduleName} from '${generatedModulePath}/${moduleName}.mjs';`
36
- })
37
- ->Array.join("\n")
38
-
39
- let wrappers =
17
+ let tagData =
40
18
  tags
41
19
  ->Array.map(tag => {
42
20
  let moduleName = CodegenUtils.toPascalCase(tag)
21
+ let importLine = `import * as ${moduleName} from '${generatedModulePath}/${moduleName}.mjs';`
43
22
  let methods =
44
23
  Dict.get(endpointsByTag, tag)
45
24
  ->Option.getOr([])
@@ -50,37 +29,36 @@ let generateWrapperMjs = (~endpoints, ~generatedModulePath) => {
50
29
  endpoint.method,
51
30
  )
52
31
  let hasRequestBody = endpoint.requestBody->Option.isSome
53
- let bodyArg = hasRequestBody ? "body: request, " : ""
54
- `
55
- | async ${functionName}(client${hasRequestBody ? ", request" : ""}) {
56
- | return ${moduleName}.${functionName}({
57
- | ${bodyArg}fetch: (url, method, body) => client._fetch(url, method, body)
58
- | });
59
- | },`
32
+ Handlebars.render(
33
+ Templates.wrapperMjsMethod,
34
+ {
35
+ "functionName": functionName,
36
+ "moduleName": moduleName,
37
+ "requestArg": hasRequestBody ? ", request" : "",
38
+ "bodyArg": hasRequestBody ? "body: request, " : "",
39
+ },
40
+ )
60
41
  })
61
42
  ->Array.join("\n")
62
- `
63
- |export const ${moduleName} = {
64
- |${methods}
65
- |};`
43
+
44
+ let namespace = Handlebars.render(
45
+ Templates.wrapperMjsNamespace,
46
+ {"moduleName": moduleName, "methods": methods},
47
+ )
48
+ {"importLine": importLine, "namespace": namespace}
66
49
  })
67
- ->Array.join("\n\n")
68
50
 
69
- `
70
- |// Generated wrapper
71
- |${imports}
72
- |
73
- |${misskeyClientJsCode}
74
- |
75
- |${wrappers}
76
- |`->CodegenUtils.trimMargin
51
+ Handlebars.render(
52
+ Templates.wrapperMjs,
53
+ {"tags": tagData, "clientCode": misskeyClientJsCode},
54
+ )
77
55
  }
78
56
 
79
57
  let generateWrapperDts = (~endpoints) => {
80
58
  let endpointsByTag = OpenAPIParser.groupByTag(endpoints)
81
59
  let tags = Dict.keysToArray(endpointsByTag)
82
60
 
83
- let imports =
61
+ let tagData =
84
62
  tags
85
63
  ->Array.map(tag => {
86
64
  let moduleName = CodegenUtils.toPascalCase(tag)
@@ -98,16 +76,8 @@ let generateWrapperDts = (~endpoints) => {
98
76
  }
99
77
  })
100
78
  ->Array.join("\n")
101
- `import type {
102
- ${typesToImport}
103
- } from '../types/${moduleName}.d.ts';`
104
- })
105
- ->Array.join("\n")
79
+ let importBlock = `import type {\n${typesToImport}\n} from '../types/${moduleName}.d.ts';`
106
80
 
107
- let namespaces =
108
- tags
109
- ->Array.map(tag => {
110
- let moduleName = CodegenUtils.toPascalCase(tag)
111
81
  let functions =
112
82
  Dict.get(endpointsByTag, tag)
113
83
  ->Option.getOr([])
@@ -118,35 +88,40 @@ ${typesToImport}
118
88
  endpoint.method,
119
89
  )
120
90
  let pascalName = CodegenUtils.toPascalCase(functionName)
121
- let docComment = endpoint.summary->Option.mapOr("", summary => {
122
- let descriptionPart = endpoint.description->Option.mapOr("", description =>
123
- description == summary ? "" : " - " ++ description
124
- )
125
- ` /** ${summary}${descriptionPart} */\n`
126
- })
91
+ let docComment = switch (endpoint.summary, endpoint.description) {
92
+ | (None, None) => ""
93
+ | (Some(summary), None) => ` /** ${summary} */\n`
94
+ | (None, Some(desc)) => {
95
+ let lines = desc->String.split("\n")->Array.map(line => line == "" ? " *" : ` * ${line}`)
96
+ ` /**\n${lines->Array.join("\n")}\n */\n`
97
+ }
98
+ | (Some(summary), Some(desc)) if summary == desc => ` /** ${summary} */\n`
99
+ | (Some(summary), Some(desc)) => {
100
+ let descLines = desc->String.split("\n")->Array.map(line => line == "" ? " *" : ` * ${line}`)
101
+ ` /**\n * ${summary}\n *\n${descLines->Array.join("\n")}\n */\n`
102
+ }
103
+ }
127
104
  let requestParam = endpoint.requestBody->Option.isSome ? `, request: ${pascalName}Request` : ""
128
- `${docComment} export function ${functionName}(client: MisskeyClient${requestParam}): Promise<${pascalName}Response>;`
105
+ Handlebars.render(
106
+ Templates.wrapperDtsFunction,
107
+ {
108
+ "docComment": docComment,
109
+ "functionName": functionName,
110
+ "requestParam": requestParam,
111
+ "pascalName": pascalName,
112
+ },
113
+ )
129
114
  })
130
115
  ->Array.join("\n")
131
- `
132
- |export namespace ${moduleName} {
133
- |${functions}
134
- |}`
116
+
117
+ let namespace = Handlebars.render(
118
+ Templates.wrapperDtsNamespace,
119
+ {"moduleName": moduleName, "functions": functions},
120
+ )
121
+ {"importBlock": importBlock, "namespace": namespace}
135
122
  })
136
- ->Array.join("\n\n")
137
123
 
138
- `
139
- |// Generated TypeScript definitions for wrapper
140
- |${imports}
141
- |
142
- |export class MisskeyClient {
143
- | constructor(baseUrl: string, token?: string);
144
- | readonly baseUrl: string;
145
- | readonly token?: string;
146
- |}
147
- |
148
- |${namespaces}
149
- |`->CodegenUtils.trimMargin
124
+ Handlebars.render(Templates.wrapperDts, {"tags": tagData})
150
125
  }
151
126
 
152
127
  let generate = (~endpoints, ~outputDir, ~generatedModulePath="../generated") => {