@azure-tools/rlc-common 1.0.0-beta.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 (209) hide show
  1. package/.rush/temp/package-deps_build.json +45 -0
  2. package/.rush/temp/shrinkwrap-deps.json +72 -0
  3. package/CHANGELOG.md +3 -0
  4. package/dist/buildClient.js +198 -0
  5. package/dist/buildClient.js.map +1 -0
  6. package/dist/buildClientDefinitions.js +160 -0
  7. package/dist/buildClientDefinitions.js.map +1 -0
  8. package/dist/buildIndexFile.js +150 -0
  9. package/dist/buildIndexFile.js.map +1 -0
  10. package/dist/buildIsUnexpectedHelper.js +219 -0
  11. package/dist/buildIsUnexpectedHelper.js.map +1 -0
  12. package/dist/buildMethodShortcuts.js +50 -0
  13. package/dist/buildMethodShortcuts.js.map +1 -0
  14. package/dist/buildObjectTypes.js +250 -0
  15. package/dist/buildObjectTypes.js.map +1 -0
  16. package/dist/buildPaginateHelper.js +30 -0
  17. package/dist/buildPaginateHelper.js.map +1 -0
  18. package/dist/buildParameterTypes.js +287 -0
  19. package/dist/buildParameterTypes.js.map +1 -0
  20. package/dist/buildPollingHelper.js +21 -0
  21. package/dist/buildPollingHelper.js.map +1 -0
  22. package/dist/buildResponseTypes.js +122 -0
  23. package/dist/buildResponseTypes.js.map +1 -0
  24. package/dist/buildSchemaType.js +44 -0
  25. package/dist/buildSchemaType.js.map +1 -0
  26. package/dist/buildTopLevelIndexFile.js +45 -0
  27. package/dist/buildTopLevelIndexFile.js.map +1 -0
  28. package/dist/helpers/nameConstructors.js +41 -0
  29. package/dist/helpers/nameConstructors.js.map +1 -0
  30. package/dist/helpers/nameUtils.js +196 -0
  31. package/dist/helpers/nameUtils.js.map +1 -0
  32. package/dist/helpers/operationHelpers.js +83 -0
  33. package/dist/helpers/operationHelpers.js.map +1 -0
  34. package/dist/helpers/schemaHelpers.js +27 -0
  35. package/dist/helpers/schemaHelpers.js.map +1 -0
  36. package/dist/helpers/shortcutMethods.js +46 -0
  37. package/dist/helpers/shortcutMethods.js.map +1 -0
  38. package/dist/index.js +44 -0
  39. package/dist/index.js.map +1 -0
  40. package/dist/interfaces.js +18 -0
  41. package/dist/interfaces.js.map +1 -0
  42. package/dist/metadata/buildApiExtractorConfig.js +56 -0
  43. package/dist/metadata/buildApiExtractorConfig.js.map +1 -0
  44. package/dist/metadata/buildESLintConfig.js +33 -0
  45. package/dist/metadata/buildESLintConfig.js.map +1 -0
  46. package/dist/metadata/buildLicenseFile.js +41 -0
  47. package/dist/metadata/buildLicenseFile.js.map +1 -0
  48. package/dist/metadata/buildPackageFile.js +232 -0
  49. package/dist/metadata/buildPackageFile.js.map +1 -0
  50. package/dist/metadata/buildReadmeFile.js +170 -0
  51. package/dist/metadata/buildReadmeFile.js.map +1 -0
  52. package/dist/metadata/buildRollupConfig.js +144 -0
  53. package/dist/metadata/buildRollupConfig.js.map +1 -0
  54. package/dist/metadata/buildTsConfig.js +72 -0
  55. package/dist/metadata/buildTsConfig.js.map +1 -0
  56. package/dist/package.json +1 -0
  57. package/dist/static/paginateContent.js +214 -0
  58. package/dist/static/paginateContent.js.map +1 -0
  59. package/dist/static/pollingContent.js +78 -0
  60. package/dist/static/pollingContent.js.map +1 -0
  61. package/dist/test/buildEnvFile.js +31 -0
  62. package/dist/test/buildEnvFile.js.map +1 -0
  63. package/dist/test/buildKarmaConfig.js +19 -0
  64. package/dist/test/buildKarmaConfig.js.map +1 -0
  65. package/dist/test/buildRecordedClient.js +22 -0
  66. package/dist/test/buildRecordedClient.js.map +1 -0
  67. package/dist/test/buildSampleTest.js +19 -0
  68. package/dist/test/buildSampleTest.js.map +1 -0
  69. package/dist/test/template.js +192 -0
  70. package/dist/test/template.js.map +1 -0
  71. package/dist-esm/buildClient.js +191 -0
  72. package/dist-esm/buildClient.js.map +1 -0
  73. package/dist-esm/buildClientDefinitions.js +155 -0
  74. package/dist-esm/buildClientDefinitions.js.map +1 -0
  75. package/dist-esm/buildIndexFile.js +145 -0
  76. package/dist-esm/buildIndexFile.js.map +1 -0
  77. package/dist-esm/buildIsUnexpectedHelper.js +215 -0
  78. package/dist-esm/buildIsUnexpectedHelper.js.map +1 -0
  79. package/dist-esm/buildMethodShortcuts.js +46 -0
  80. package/dist-esm/buildMethodShortcuts.js.map +1 -0
  81. package/dist-esm/buildObjectTypes.js +249 -0
  82. package/dist-esm/buildObjectTypes.js.map +1 -0
  83. package/dist-esm/buildPaginateHelper.js +26 -0
  84. package/dist-esm/buildPaginateHelper.js.map +1 -0
  85. package/dist-esm/buildParameterTypes.js +288 -0
  86. package/dist-esm/buildParameterTypes.js.map +1 -0
  87. package/dist-esm/buildPollingHelper.js +17 -0
  88. package/dist-esm/buildPollingHelper.js.map +1 -0
  89. package/dist-esm/buildResponseTypes.js +127 -0
  90. package/dist-esm/buildResponseTypes.js.map +1 -0
  91. package/dist-esm/buildSchemaType.js +39 -0
  92. package/dist-esm/buildSchemaType.js.map +1 -0
  93. package/dist-esm/buildTopLevelIndexFile.js +41 -0
  94. package/dist-esm/buildTopLevelIndexFile.js.map +1 -0
  95. package/dist-esm/helpers/nameConstructors.js +34 -0
  96. package/dist-esm/helpers/nameConstructors.js.map +1 -0
  97. package/dist-esm/helpers/nameUtils.js +187 -0
  98. package/dist-esm/helpers/nameUtils.js.map +1 -0
  99. package/dist-esm/helpers/operationHelpers.js +72 -0
  100. package/dist-esm/helpers/operationHelpers.js.map +1 -0
  101. package/dist-esm/helpers/schemaHelpers.js +21 -0
  102. package/dist-esm/helpers/schemaHelpers.js.map +1 -0
  103. package/dist-esm/helpers/shortcutMethods.js +42 -0
  104. package/dist-esm/helpers/shortcutMethods.js.map +1 -0
  105. package/dist-esm/index.js +28 -0
  106. package/dist-esm/index.js.map +1 -0
  107. package/dist-esm/interfaces.js +15 -0
  108. package/dist-esm/interfaces.js.map +1 -0
  109. package/dist-esm/metadata/buildApiExtractorConfig.js +51 -0
  110. package/dist-esm/metadata/buildApiExtractorConfig.js.map +1 -0
  111. package/dist-esm/metadata/buildESLintConfig.js +28 -0
  112. package/dist-esm/metadata/buildESLintConfig.js.map +1 -0
  113. package/dist-esm/metadata/buildLicenseFile.js +36 -0
  114. package/dist-esm/metadata/buildLicenseFile.js.map +1 -0
  115. package/dist-esm/metadata/buildPackageFile.js +234 -0
  116. package/dist-esm/metadata/buildPackageFile.js.map +1 -0
  117. package/dist-esm/metadata/buildReadmeFile.js +167 -0
  118. package/dist-esm/metadata/buildReadmeFile.js.map +1 -0
  119. package/dist-esm/metadata/buildRollupConfig.js +139 -0
  120. package/dist-esm/metadata/buildRollupConfig.js.map +1 -0
  121. package/dist-esm/metadata/buildTsConfig.js +67 -0
  122. package/dist-esm/metadata/buildTsConfig.js.map +1 -0
  123. package/dist-esm/package.json +1 -0
  124. package/dist-esm/static/paginateContent.js +211 -0
  125. package/dist-esm/static/paginateContent.js.map +1 -0
  126. package/dist-esm/static/pollingContent.js +75 -0
  127. package/dist-esm/static/pollingContent.js.map +1 -0
  128. package/dist-esm/test/buildEnvFile.js +24 -0
  129. package/dist-esm/test/buildEnvFile.js.map +1 -0
  130. package/dist-esm/test/buildKarmaConfig.js +14 -0
  131. package/dist-esm/test/buildKarmaConfig.js.map +1 -0
  132. package/dist-esm/test/buildRecordedClient.js +17 -0
  133. package/dist-esm/test/buildRecordedClient.js.map +1 -0
  134. package/dist-esm/test/buildSampleTest.js +14 -0
  135. package/dist-esm/test/buildSampleTest.js.map +1 -0
  136. package/dist-esm/test/template.js +189 -0
  137. package/dist-esm/test/template.js.map +1 -0
  138. package/package.json +40 -0
  139. package/publishPackage.js +11 -0
  140. package/rlc-common.build.log +2 -0
  141. package/src/buildClient.ts +251 -0
  142. package/src/buildClientDefinitions.ts +231 -0
  143. package/src/buildIndexFile.ts +172 -0
  144. package/src/buildIsUnexpectedHelper.ts +240 -0
  145. package/src/buildMethodShortcuts.ts +75 -0
  146. package/src/buildObjectTypes.ts +393 -0
  147. package/src/buildPaginateHelper.ts +33 -0
  148. package/src/buildParameterTypes.ts +435 -0
  149. package/src/buildPollingHelper.ts +18 -0
  150. package/src/buildResponseTypes.ts +169 -0
  151. package/src/buildSchemaType.ts +56 -0
  152. package/src/buildTopLevelIndexFile.ts +46 -0
  153. package/src/helpers/nameConstructors.ts +93 -0
  154. package/src/helpers/nameUtils.ts +227 -0
  155. package/src/helpers/operationHelpers.ts +103 -0
  156. package/src/helpers/schemaHelpers.ts +25 -0
  157. package/src/helpers/shortcutMethods.ts +60 -0
  158. package/src/index.ts +28 -0
  159. package/src/interfaces.ts +212 -0
  160. package/src/metadata/buildApiExtractorConfig.ts +59 -0
  161. package/src/metadata/buildESLintConfig.ts +34 -0
  162. package/src/metadata/buildLicenseFile.ts +39 -0
  163. package/src/metadata/buildPackageFile.ts +271 -0
  164. package/src/metadata/buildReadmeFile.ts +231 -0
  165. package/src/metadata/buildRollupConfig.ts +147 -0
  166. package/src/metadata/buildTsConfig.ts +79 -0
  167. package/src/static/paginateContent.ts +210 -0
  168. package/src/static/pollingContent.ts +74 -0
  169. package/src/test/buildEnvFile.ts +26 -0
  170. package/src/test/buildKarmaConfig.ts +15 -0
  171. package/src/test/buildRecordedClient.ts +18 -0
  172. package/src/test/buildSampleTest.ts +15 -0
  173. package/src/test/template.ts +192 -0
  174. package/tsconfig-cjs.json +9 -0
  175. package/tsconfig-common.json +13 -0
  176. package/tsconfig.json +13 -0
  177. package/types/buildClient.d.ts +2 -0
  178. package/types/buildClientDefinitions.d.ts +5 -0
  179. package/types/buildIndexFile.d.ts +5 -0
  180. package/types/buildIsUnexpectedHelper.d.ts +5 -0
  181. package/types/buildMethodShortcuts.d.ts +4 -0
  182. package/types/buildObjectTypes.d.ts +14 -0
  183. package/types/buildPaginateHelper.d.ts +5 -0
  184. package/types/buildParameterTypes.d.ts +5 -0
  185. package/types/buildPollingHelper.d.ts +5 -0
  186. package/types/buildResponseTypes.d.ts +5 -0
  187. package/types/buildSchemaType.d.ts +19 -0
  188. package/types/buildTopLevelIndexFile.d.ts +5 -0
  189. package/types/helpers/nameConstructors.d.ts +28 -0
  190. package/types/helpers/nameUtils.d.ts +25 -0
  191. package/types/helpers/operationHelpers.d.ts +9 -0
  192. package/types/helpers/schemaHelpers.d.ts +4 -0
  193. package/types/helpers/shortcutMethods.d.ts +3 -0
  194. package/types/index.d.ts +25 -0
  195. package/types/interfaces.d.ts +186 -0
  196. package/types/metadata/buildApiExtractorConfig.d.ts +5 -0
  197. package/types/metadata/buildESLintConfig.d.ts +5 -0
  198. package/types/metadata/buildLicenseFile.d.ts +5 -0
  199. package/types/metadata/buildPackageFile.d.ts +5 -0
  200. package/types/metadata/buildReadmeFile.d.ts +5 -0
  201. package/types/metadata/buildRollupConfig.d.ts +5 -0
  202. package/types/metadata/buildTsConfig.d.ts +5 -0
  203. package/types/static/paginateContent.d.ts +1 -0
  204. package/types/static/pollingContent.d.ts +1 -0
  205. package/types/test/buildEnvFile.d.ts +9 -0
  206. package/types/test/buildKarmaConfig.d.ts +5 -0
  207. package/types/test/buildRecordedClient.d.ts +5 -0
  208. package/types/test/buildSampleTest.d.ts +5 -0
  209. package/types/test/template.d.ts +5 -0
@@ -0,0 +1,46 @@
1
+ // Copyright (c) Microsoft Corporation.
2
+ // Licensed under the MIT License.
3
+
4
+ import { NameType, normalizeName } from "./helpers/nameUtils.js";
5
+ import { RLCModel } from "./interfaces.js";
6
+ import { Project } from "ts-morph";
7
+
8
+ const batchOutputFolder: [string, string, string][] = [];
9
+
10
+ export function buildTopLevelIndex(model: RLCModel) {
11
+ if (!model.options) {
12
+ return undefined;
13
+ }
14
+ const project = new Project();
15
+ const { srcPath } = model;
16
+ const { multiClient, batch } = model.options;
17
+ if (srcPath) {
18
+ const clientName = model.libraryName;
19
+ const moduleName = normalizeName(clientName, NameType.File);
20
+ const relativePath = srcPath.replace("/src", "");
21
+ batchOutputFolder.push([relativePath, clientName, moduleName]);
22
+ }
23
+ if (
24
+ multiClient &&
25
+ batch &&
26
+ batch.length > 1 &&
27
+ batchOutputFolder.length === batch.length
28
+ ) {
29
+ const indexFile = project.createSourceFile("index.ts", undefined, {
30
+ overwrite: true
31
+ });
32
+ const allModules: string[] = [];
33
+ batchOutputFolder.forEach((item) => {
34
+ indexFile.addImportDeclaration({
35
+ namespaceImport: item[1],
36
+ moduleSpecifier: `${item[0]}`
37
+ });
38
+ allModules.push(item[1]);
39
+ });
40
+ indexFile.addExportDeclaration({
41
+ namedExports: [...allModules]
42
+ });
43
+ // TODO handle multi-client path issue in cald
44
+ return { path: "", content: indexFile.getFullText() };
45
+ }
46
+ }
@@ -0,0 +1,93 @@
1
+ // Copyright (c) Microsoft Corporation.
2
+ // Licensed under the MIT License.
3
+
4
+ import { NameType, normalizeName } from "./nameUtils.js";
5
+
6
+ /**
7
+ * Get the response type name by baseName or operatioName & statusCode
8
+ * @param baseResponseName
9
+ */
10
+ export function getResponseTypeName(baseResponseName: string): string;
11
+ export function getResponseTypeName(
12
+ operationGroup: string,
13
+ operationName: string,
14
+ statusCode: string
15
+ ): string;
16
+ export function getResponseTypeName(
17
+ baseNameOrOperationGroup: string,
18
+ operationName?: string,
19
+ statusCode?: string
20
+ ): string {
21
+ if (Boolean(operationName)) {
22
+ baseNameOrOperationGroup = getResponseBaseName(
23
+ baseNameOrOperationGroup,
24
+ operationName!,
25
+ statusCode || ""
26
+ );
27
+ }
28
+ return normalizeName(
29
+ `${baseNameOrOperationGroup}Response`,
30
+ NameType.Interface
31
+ );
32
+ }
33
+
34
+ /**
35
+ * The prefix of all response types
36
+ * @param operationGroup operation group name e.g string_PutEmpty
37
+ * @param operationName operation name D e.g string_PutEmpty
38
+ * @param statusCode 2XX, 4XX, 5XX, default etc.
39
+ * @returns normolized base name e.g StringPutEmpty200
40
+ */
41
+ export function getResponseBaseName(
42
+ operationGroup: string,
43
+ operationName: string,
44
+ statusCode: string
45
+ ) {
46
+ return normalizeName(
47
+ `${operationGroup}_${operationName}_${statusCode}`,
48
+ NameType.Interface
49
+ );
50
+ }
51
+
52
+ /**
53
+ * The prefix of all parameter relevant types
54
+ * @param operationName is composed with operationGroup and operationID e.g string_PutEmpty
55
+ * @returns
56
+ */
57
+ export function getParameterBaseName(
58
+ operationGroup: string,
59
+ operationName: string
60
+ ) {
61
+ return normalizeName(
62
+ `${operationGroup}_${operationName}`,
63
+ NameType.Interface
64
+ );
65
+ }
66
+
67
+ /**
68
+ * Get the top-layer parameter name
69
+ * @param operationGroup operation group name
70
+ * @param operationName is composed with operationGroup and operationID e.g string_PutEmpty
71
+ * @returns top-layer parameter name e.g StringPutEmptParameters
72
+ */
73
+ export function getParameterTypeName(baseName: string): string;
74
+ export function getParameterTypeName(
75
+ operationGroup: string,
76
+ operationName: string
77
+ ): string;
78
+ export function getParameterTypeName(
79
+ baseNameOrOperationGroup: string,
80
+ operationName?: string
81
+ ) {
82
+ if (Boolean(operationName)) {
83
+ baseNameOrOperationGroup = getParameterBaseName(
84
+ baseNameOrOperationGroup,
85
+ operationName!
86
+ );
87
+ }
88
+
89
+ return normalizeName(
90
+ `${baseNameOrOperationGroup}_Parameters`,
91
+ NameType.Interface
92
+ );
93
+ }
@@ -0,0 +1,227 @@
1
+ // Copyright (c) Microsoft Corporation.
2
+ // Licensed under the MIT License.
3
+
4
+ export interface ReservedName {
5
+ name: string;
6
+ reservedFor: NameType[];
7
+ }
8
+
9
+ export enum NameType {
10
+ Class,
11
+ File,
12
+ Interface,
13
+ Property,
14
+ Parameter,
15
+ Operation,
16
+ OperationGroup
17
+ }
18
+
19
+ const Newable = [NameType.Class, NameType.Interface, NameType.OperationGroup];
20
+
21
+ const ReservedModelNames: ReservedName[] = [
22
+ { name: "any", reservedFor: [NameType.Parameter] },
23
+ { name: "as", reservedFor: [NameType.Parameter] },
24
+ { name: "boolean", reservedFor: [NameType.Parameter, ...Newable] },
25
+ { name: "break", reservedFor: [NameType.Parameter] },
26
+ { name: "case", reservedFor: [NameType.Parameter] },
27
+ { name: "catch", reservedFor: [NameType.Parameter] },
28
+ { name: "class", reservedFor: [NameType.Parameter] },
29
+ { name: "const", reservedFor: [NameType.Parameter] },
30
+ { name: "constructor", reservedFor: [NameType.Parameter] },
31
+ { name: "continue", reservedFor: [NameType.Parameter] },
32
+ { name: "date", reservedFor: [NameType.Parameter, ...Newable] },
33
+ { name: "debugger", reservedFor: [NameType.Parameter] },
34
+ { name: "declare", reservedFor: [NameType.Parameter] },
35
+ { name: "default", reservedFor: [NameType.Parameter] },
36
+ { name: "delete", reservedFor: [NameType.Parameter] },
37
+ { name: "do", reservedFor: [NameType.Parameter] },
38
+ { name: "else", reservedFor: [NameType.Parameter] },
39
+ { name: "enum", reservedFor: [NameType.Parameter] },
40
+ { name: "error", reservedFor: [NameType.Parameter, ...Newable] },
41
+ { name: "export", reservedFor: [NameType.Parameter] },
42
+ { name: "extends", reservedFor: [NameType.Parameter] },
43
+ { name: "false", reservedFor: [NameType.Parameter] },
44
+ { name: "finally", reservedFor: [NameType.Parameter] },
45
+ { name: "for", reservedFor: [NameType.Parameter] },
46
+ { name: "from", reservedFor: [NameType.Parameter] },
47
+ { name: "function", reservedFor: [NameType.Parameter, ...Newable] },
48
+ { name: "get", reservedFor: [NameType.Parameter] },
49
+ { name: "if", reservedFor: [NameType.Parameter] },
50
+ { name: "implements", reservedFor: [NameType.Parameter] },
51
+ { name: "import", reservedFor: [NameType.Parameter] },
52
+ { name: "in", reservedFor: [NameType.Parameter] },
53
+ { name: "instanceof", reservedFor: [NameType.Parameter] },
54
+ { name: "interface", reservedFor: [NameType.Parameter] },
55
+ { name: "let", reservedFor: [NameType.Parameter] },
56
+ { name: "module", reservedFor: [NameType.Parameter] },
57
+ { name: "new", reservedFor: [NameType.Parameter] },
58
+ { name: "null", reservedFor: [NameType.Parameter] },
59
+ { name: "number", reservedFor: [NameType.Parameter, ...Newable] },
60
+ { name: "of", reservedFor: [NameType.Parameter] },
61
+ { name: "package", reservedFor: [NameType.Parameter] },
62
+ { name: "private", reservedFor: [NameType.Parameter] },
63
+ { name: "protected", reservedFor: [NameType.Parameter] },
64
+ { name: "public", reservedFor: [NameType.Parameter] },
65
+ { name: "requestoptions", reservedFor: [NameType.Parameter] },
66
+ { name: "require", reservedFor: [NameType.Parameter] },
67
+ { name: "return", reservedFor: [NameType.Parameter] },
68
+ { name: "set", reservedFor: [NameType.Parameter, ...Newable] },
69
+ { name: "static", reservedFor: [NameType.Parameter] },
70
+ { name: "string", reservedFor: [NameType.Parameter, ...Newable] },
71
+ { name: "super", reservedFor: [NameType.Parameter] },
72
+ { name: "switch", reservedFor: [NameType.Parameter] },
73
+ { name: "symbol", reservedFor: [NameType.Parameter, ...Newable] },
74
+ { name: "this", reservedFor: [NameType.Parameter] },
75
+ { name: "throw", reservedFor: [NameType.Parameter] },
76
+ { name: "true", reservedFor: [NameType.Parameter] },
77
+ { name: "try", reservedFor: [NameType.Parameter] },
78
+ { name: "type", reservedFor: [NameType.Parameter] },
79
+ { name: "typeof", reservedFor: [NameType.Parameter] },
80
+ { name: "var", reservedFor: [NameType.Parameter] },
81
+ { name: "void", reservedFor: [NameType.Parameter] },
82
+ { name: "while", reservedFor: [NameType.Parameter] },
83
+ { name: "with", reservedFor: [NameType.Parameter] },
84
+ { name: "yield", reservedFor: [NameType.Parameter] },
85
+ { name: "arguments", reservedFor: [NameType.Parameter] }
86
+ ];
87
+
88
+ export enum CasingConvention {
89
+ Pascal,
90
+ Camel
91
+ }
92
+
93
+ export function guardReservedNames(
94
+ name: string,
95
+ nameType: NameType,
96
+ customReservedNames: ReservedName[] = []
97
+ ): string {
98
+ const suffix = getSuffix(nameType);
99
+ return [...ReservedModelNames, ...customReservedNames]
100
+ .filter((r) => r.reservedFor.includes(nameType))
101
+ .find((r) => r.name === name.toLowerCase())
102
+ ? `${name}${suffix}`
103
+ : name;
104
+ }
105
+
106
+ function getSuffix(nameType?: NameType) {
107
+ switch (nameType) {
108
+ case NameType.File:
109
+ case NameType.Operation:
110
+ case NameType.Property:
111
+ return "";
112
+ case NameType.OperationGroup:
113
+ return "Operations";
114
+ case NameType.Parameter:
115
+ return "Param";
116
+ case NameType.Class:
117
+ case NameType.Interface:
118
+ default:
119
+ return "Model";
120
+ }
121
+ }
122
+
123
+ export function normalizeName(
124
+ name: string,
125
+ nameType: NameType,
126
+ shouldGuard?: boolean,
127
+ customReservedNames: ReservedName[] = [],
128
+ casingOverride?: CasingConvention
129
+ ): string {
130
+ if (name.startsWith("$DO_NOT_NORMALIZE$")) {
131
+ return name.replace("$DO_NOT_NORMALIZE$", "");
132
+ }
133
+ const casingConvention = casingOverride ?? getCasingConvention(nameType);
134
+ const sanitizedName = sanitizeName(name);
135
+ const parts = getNameParts(sanitizedName);
136
+ const [firstPart, ...otherParts] = parts;
137
+ const normalizedFirstPart = toCasing(firstPart, casingConvention);
138
+ const normalizedParts = (otherParts || [])
139
+ .map((part) =>
140
+ part === "null" ? part : toCasing(part, CasingConvention.Pascal)
141
+ )
142
+ .join("");
143
+
144
+ const normalized = checkBeginning(`${normalizedFirstPart}${normalizedParts}`);
145
+ return shouldGuard
146
+ ? guardReservedNames(normalized, nameType, customReservedNames)
147
+ : normalized;
148
+ }
149
+
150
+ function checkBeginning(name: string): string {
151
+ if (name.startsWith("@")) {
152
+ return name.substring(1);
153
+ }
154
+ return name;
155
+ }
156
+
157
+ function sanitizeName(name: string): string {
158
+ // Remove \, " and ' from name string
159
+ return name.replace(/["'\\]+/g, "");
160
+ }
161
+
162
+ export function getModelsName(title: string): string {
163
+ const spaceRemovedTitle = title.replace(/ /g, "");
164
+ return `${spaceRemovedTitle.replace("Client", "")}Models`;
165
+ }
166
+
167
+ export function getMappersName(title: string): string {
168
+ const spaceRemovedTitle = title.replace(/ /g, "");
169
+ return `${spaceRemovedTitle.replace("Client", "")}Mappers`;
170
+ }
171
+
172
+ function getCasingConvention(nameType: NameType) {
173
+ switch (nameType) {
174
+ case NameType.Class:
175
+ case NameType.Interface:
176
+ case NameType.OperationGroup:
177
+ return CasingConvention.Pascal;
178
+ case NameType.File:
179
+ case NameType.Property:
180
+ case NameType.Operation:
181
+ case NameType.Parameter:
182
+ return CasingConvention.Camel;
183
+ }
184
+ }
185
+
186
+ /**
187
+ * TODO: Improve this function to handle cases such as TEST -> test. Current basic implementation
188
+ * results in TEST -> test or Test (depending on the CasingConvention). We should switch to relay
189
+ * on Modeler four namer for this once it is stable
190
+ */
191
+ function toCasing(str: string, casing: CasingConvention): string {
192
+ let value = str;
193
+ if (value === value.toUpperCase()) {
194
+ value = str.toLowerCase();
195
+ }
196
+
197
+ const firstChar =
198
+ casing === CasingConvention.Pascal
199
+ ? value.charAt(0).toUpperCase()
200
+ : value.charAt(0).toLocaleLowerCase();
201
+ return `${firstChar}${value.substring(1)}`;
202
+ }
203
+
204
+ function getNameParts(name: string) {
205
+ let parts = name.split(/[-._ ]+/);
206
+
207
+ return parts.length > 0 ? parts : [name];
208
+ }
209
+
210
+ export function pascalCase(str: string) {
211
+ return str.charAt(0).toUpperCase() + str.slice(1);
212
+ }
213
+
214
+ export function camelCase(
215
+ str: string,
216
+ options: { uppercaseThreshold?: number } = {}
217
+ ) {
218
+ const { uppercaseThreshold = 4 } = options;
219
+ const thresholdRegex = new RegExp(
220
+ `^(?<![A-Z])[A-Z]{1,${uppercaseThreshold}}(?![A-Z])`
221
+ );
222
+ if (!thresholdRegex.test(str)) {
223
+ return str;
224
+ }
225
+
226
+ return str.charAt(0).toLocaleLowerCase() + str.slice(1);
227
+ }
@@ -0,0 +1,103 @@
1
+ // Copyright (c) Microsoft Corporation.
2
+ // Licensed under the MIT License.
3
+
4
+ import {
5
+ MethodSignatureStructure,
6
+ OptionalKind,
7
+ ParameterDeclarationStructure
8
+ } from "ts-morph";
9
+ import {
10
+ Methods,
11
+ ObjectSchema,
12
+ PathParameter,
13
+ RLCModel,
14
+ SchemaContext
15
+ } from "../interfaces.js";
16
+ import { pascalCase } from "./nameUtils.js";
17
+ import { isObjectSchema } from "./schemaHelpers.js";
18
+
19
+ export function buildMethodDefinitions(
20
+ methods: Methods,
21
+ pathParams: PathParameter[] = []
22
+ ): OptionalKind<MethodSignatureStructure>[] {
23
+ const methodDefinitions: OptionalKind<MethodSignatureStructure>[] = [];
24
+ for (const key of Object.keys(methods)) {
25
+ const verbMethods = methods[key];
26
+
27
+ for (const method of verbMethods) {
28
+ const description = method.description;
29
+ let areAllOptional = method.hasOptionalOptions;
30
+
31
+ methodDefinitions.push({
32
+ name: key,
33
+ ...(description && { docs: [{ description }] }),
34
+ parameters: [
35
+ ...getPathParamDefinitions(pathParams),
36
+ {
37
+ name: "options",
38
+ hasQuestionToken: areAllOptional,
39
+ type: pascalCase(method.optionsName)
40
+ }
41
+ ],
42
+ returnType: `StreamableMethod<${method.returnType}>`
43
+ });
44
+ }
45
+ }
46
+
47
+ return methodDefinitions;
48
+ }
49
+
50
+ export function getPathParamDefinitions(
51
+ pathParams: PathParameter[]
52
+ ): OptionalKind<ParameterDeclarationStructure>[] {
53
+ return pathParams.map(({ name, type, description }) => {
54
+ return {
55
+ name,
56
+ type,
57
+ description
58
+ };
59
+ });
60
+ }
61
+
62
+ export function hasPagingOperations(model: RLCModel) {
63
+ return Boolean(model.annotations?.hasPaging);
64
+ }
65
+
66
+ export function hasPollingOperations(model: RLCModel) {
67
+ return Boolean(model.annotations?.hasLongRunning);
68
+ }
69
+
70
+ export function hasUnexpectedHelper(model: RLCModel) {
71
+ const pathDictionary = model.paths;
72
+ for (const details of Object.values(pathDictionary)) {
73
+ for (const methodDetails of Object.values(details.methods)) {
74
+ const successTypes = methodDetails[0].responseTypes.success;
75
+ const errorTypes = methodDetails[0].responseTypes.error;
76
+
77
+ if (successTypes.length > 0 && errorTypes.length > 0 && !!errorTypes[0]) {
78
+ return true;
79
+ }
80
+ }
81
+ }
82
+ return false;
83
+ }
84
+
85
+ export function hasInputModels(model: RLCModel) {
86
+ return hasSchemaContextObject(model, [SchemaContext.Input]);
87
+ }
88
+ export function hasOutputModels(model: RLCModel) {
89
+ return hasSchemaContextObject(model, [
90
+ SchemaContext.Output,
91
+ SchemaContext.Exception
92
+ ]);
93
+ }
94
+
95
+ function hasSchemaContextObject(model: RLCModel, schemaUsage: SchemaContext[]) {
96
+ const objectSchemas: ObjectSchema[] = (model.schemas ?? []).filter(
97
+ (o) =>
98
+ isObjectSchema(o) &&
99
+ (o as ObjectSchema).usage?.some((u) => schemaUsage.includes(u))
100
+ );
101
+
102
+ return objectSchemas.length > 0;
103
+ }
@@ -0,0 +1,25 @@
1
+ // Copyright (c) Microsoft Corporation.
2
+ // Licensed under the MIT License.
3
+
4
+ import { Schema } from "../interfaces.js";
5
+
6
+ export function isDictionarySchema(schema: Schema) {
7
+ if (schema.type === "dictionary") {
8
+ return true;
9
+ }
10
+ return false;
11
+ }
12
+
13
+ export function isObjectSchema(schema: Schema) {
14
+ if (schema.type === "object") {
15
+ return true;
16
+ }
17
+ return false;
18
+ }
19
+
20
+ export function isConstantSchema(schema: Schema) {
21
+ if (schema.type === "constant") {
22
+ return true;
23
+ }
24
+ return false;
25
+ }
@@ -0,0 +1,60 @@
1
+ // Copyright (c) Microsoft Corporation.
2
+ // Licensed under the MIT License.
3
+
4
+ import {
5
+ OptionalKind,
6
+ MethodSignatureStructure,
7
+ InterfaceDeclarationStructure
8
+ } from "ts-morph";
9
+ import { PathMetadata, Paths } from "../interfaces.js";
10
+ import { buildMethodDefinitions } from "./operationHelpers.js";
11
+ import { NameType, normalizeName } from "./nameUtils.js";
12
+
13
+ export function generateMethodShortcuts(
14
+ paths: Paths
15
+ ): OptionalKind<InterfaceDeclarationStructure>[] {
16
+ let keys: Record<string, OptionalKind<MethodSignatureStructure>[]> = {};
17
+ for (const path in paths) {
18
+ const groupName = paths[path].operationGroupName;
19
+ const definitions = buildOperationDefinitions(paths[path]);
20
+ if (!keys[groupName]) {
21
+ keys[groupName] = definitions;
22
+ } else {
23
+ keys[groupName] = [...keys[groupName], ...definitions];
24
+ }
25
+ }
26
+
27
+ const interfaces: OptionalKind<InterfaceDeclarationStructure>[] = [];
28
+
29
+ for (const interfaceName in keys) {
30
+ const methods = keys[interfaceName];
31
+ interfaces.push({
32
+ name: `${interfaceName}Operations`,
33
+ methods: methods,
34
+ isExported: true,
35
+ docs: [`Contains operations for ${interfaceName} operations`]
36
+ });
37
+ }
38
+
39
+ return interfaces;
40
+ }
41
+
42
+ function buildOperationDefinitions(
43
+ path: PathMetadata
44
+ ): OptionalKind<MethodSignatureStructure>[] {
45
+ let ops: OptionalKind<MethodSignatureStructure>[] = [];
46
+
47
+ for (const verb in path.methods) {
48
+ const methods = path.methods[verb];
49
+ for (const method of methods) {
50
+ const name = normalizeName(method.operationName, NameType.Property);
51
+ const pathParams = path.pathParameters;
52
+ const methodDefinitions = buildMethodDefinitions(
53
+ { [name]: [method] },
54
+ pathParams
55
+ );
56
+ ops = [...ops, ...methodDefinitions];
57
+ }
58
+ }
59
+ return ops;
60
+ }
package/src/index.ts ADDED
@@ -0,0 +1,28 @@
1
+ // Copyright (c) Microsoft Corporation.
2
+ // Licensed under the MIT License.
3
+
4
+ export * from "./interfaces.js";
5
+ export * from "./buildClientDefinitions.js";
6
+ export * from "./buildSchemaType.js";
7
+ export * from "./buildClient.js";
8
+ export * from "./helpers/nameConstructors.js";
9
+ export * from "./buildResponseTypes.js";
10
+ export * from "./helpers/shortcutMethods.js";
11
+ export * from "./helpers/nameUtils.js";
12
+ export * from "./buildParameterTypes.js";
13
+ export * from "./buildIsUnexpectedHelper.js";
14
+ export * from "./buildTopLevelIndexFile.js";
15
+ export * from "./buildIndexFile.js";
16
+ export * from "./buildPaginateHelper.js";
17
+ export * from "./buildPollingHelper.js";
18
+ export * from "./test/buildKarmaConfig.js";
19
+ export * from "./test/buildEnvFile.js";
20
+ export * from "./test/buildRecordedClient.js";
21
+ export * from "./test/buildSampleTest.js";
22
+ export * from "./metadata/buildReadmeFile.js";
23
+ export * from "./metadata/buildApiExtractorConfig.js";
24
+ export * from "./metadata/buildPackageFile.js";
25
+ export * from "./metadata/buildRollupConfig.js";
26
+ export * from "./metadata/buildTsConfig.js";
27
+ export * from "./metadata/buildESLintConfig.js";
28
+ export * from "./metadata/buildLicenseFile.js";