3
3
import * as fs from "fs-extra" ;
4
4
import * as path from "path" ;
5
5
import { CodeMaker } from "codemaker" ;
6
- import { mkdtemp } from "@cdktf/commons" ;
7
- import * as srcmak from "jsii-srcmak" ;
6
+ import { exec , mkdtemp } from "@cdktf/commons" ;
8
7
import {
9
8
TerraformDependencyConstraint ,
10
9
logger ,
@@ -22,9 +21,59 @@ import { ModuleGenerator } from "./generator/module-generator";
22
21
import { glob } from "glob" ;
23
22
import { readSchema } from "@cdktf/provider-schema" ;
24
23
24
+ const pacmakModule = require . resolve ( "jsii-pacmak/bin/jsii-pacmak" ) ;
25
+ const jsiiModule = require . resolve ( "jsii/bin/jsii" ) ;
26
+
27
+ export interface GenerateJSIIOptions {
28
+ entrypoint : string ;
29
+ deps : string [ ] ;
30
+ moduleKey : string ;
31
+ exports ?: Record < string , ExportDefinition | string > ;
32
+ jsii ?: JsiiOutputOptions ;
33
+ python ?: PythonOutputOptions ;
34
+ java ?: JavaOutputOptions ;
35
+ csharp ?: CSharpOutputOptions ;
36
+ golang ?: GoLangOutputOptions ;
37
+ }
38
+
39
+ export interface JsiiOutputOptions {
40
+ path : string ;
41
+ }
42
+
43
+ export interface PythonOutputOptions {
44
+ outdir : string ;
45
+ moduleName : string ;
46
+ }
47
+
48
+ export interface JavaOutputOptions {
49
+ outdir : string ;
50
+ package : string ;
51
+ }
52
+
53
+ export interface CSharpOutputOptions {
54
+ outdir : string ;
55
+ namespace : string ;
56
+ }
57
+
58
+ export interface GoLangOutputOptions {
59
+ outdir : string ;
60
+ moduleName : string ;
61
+ packageName : string ;
62
+ }
63
+
64
+ /**
65
+ * See https://nodejs.org/api/packages.html#conditional-exports for more information
66
+ */
67
+ export interface ExportDefinition {
68
+ node ?: string ;
69
+ import ?: string ;
70
+ require ?: string ;
71
+ default ?: string ;
72
+ }
73
+
25
74
export async function generateJsiiLanguage (
26
75
code : CodeMaker ,
27
- opts : srcmak . Options ,
76
+ opts : GenerateJSIIOptions ,
28
77
outputPath : string ,
29
78
disallowedFileGlobs : string [ ] = [ ]
30
79
) {
@@ -43,7 +92,139 @@ export async function generateJsiiLanguage(
43
92
filesToDelete . map ( ( file ) => fs . remove ( path . join ( staging , file ) ) )
44
93
) ;
45
94
46
- await srcmak . srcmak ( staging , opts ) ;
95
+ // Compile with JSII
96
+ const jsiiArgs = [ "--silence-warnings" , "reserved-word" ] ;
97
+ const jsiiEntrypoint = opts . entrypoint ;
98
+ const basepath = path . join (
99
+ path . dirname ( jsiiEntrypoint ) ,
100
+ path . basename ( jsiiEntrypoint , ".ts" )
101
+ ) ;
102
+
103
+ const moduleKey = opts . moduleKey . replace ( / \. / g, "" ) . replace ( / \/ / g, "" ) ;
104
+ const moduleDirs = opts . deps ;
105
+ const targets : Record < string , any > = { } ;
106
+ const deps : Record < string , string > = { } ;
107
+ for ( const dir of moduleDirs ) {
108
+ // read module metadata
109
+ const metadata = await fs . readJson ( path . join ( dir , "package.json" ) ) ;
110
+ const moduleName : string = metadata . name ;
111
+ const moduleVersion : string = metadata . version ;
112
+
113
+ const targetdir = path . join (
114
+ path . join ( staging , "node_modules" ) ,
115
+ moduleName
116
+ ) ;
117
+ await fs . mkdirp ( path . dirname ( targetdir ) ) ;
118
+ await fs . copy ( dir , targetdir ) ;
119
+
120
+ // add to "deps" and "peer deps"
121
+ if ( ! moduleName . startsWith ( "@types/" ) ) {
122
+ deps [ moduleName ] = moduleVersion ;
123
+ }
124
+ }
125
+ const pkg = {
126
+ name : moduleKey ,
127
+ version : "0.0.0" ,
128
+ author : "generated@generated.com" ,
129
+ main : `${ basepath } .js` ,
130
+ types : `${ basepath } .d.ts` ,
131
+ license : "UNLICENSED" ,
132
+ repository : { url : "http://generated" , type : "git" } ,
133
+ jsii : {
134
+ outdir : "dist" ,
135
+ targets : targets ,
136
+ } ,
137
+ dependencies : deps ,
138
+ peerDependencies : deps ,
139
+ } ;
140
+
141
+ if ( opts . exports ) {
142
+ ( pkg as Record < string , any > ) . exports = opts . exports ;
143
+ }
144
+ if ( opts . python ) {
145
+ targets . python = {
146
+ distName : "generated" ,
147
+ module : opts . python . moduleName ,
148
+ } ;
149
+ }
150
+
151
+ if ( opts . java ) {
152
+ targets . java = {
153
+ package : opts . java . package ,
154
+ maven : {
155
+ groupId : "generated" ,
156
+ artifactId : "generated" ,
157
+ } ,
158
+ } ;
159
+ }
160
+
161
+ if ( opts . csharp ) {
162
+ targets . dotnet = {
163
+ namespace : opts . csharp . namespace ,
164
+ packageId : opts . csharp . namespace ,
165
+ } ;
166
+ }
167
+
168
+ if ( opts . golang ) {
169
+ targets . go = {
170
+ moduleName : opts . golang . moduleName ,
171
+ packageName : opts . golang . packageName ,
172
+ } ;
173
+ }
174
+
175
+ await fs . writeFile (
176
+ path . join ( staging , "package.json" ) ,
177
+ JSON . stringify ( pkg , undefined , 2 )
178
+ ) ;
179
+
180
+ const endJsiiTimer = logTimespan ( "jsii" ) ;
181
+ await exec ( jsiiModule , jsiiArgs , {
182
+ cwd : staging ,
183
+ } ) ;
184
+ endJsiiTimer ( ) ;
185
+
186
+ // extract .jsii if requested
187
+ if ( opts . jsii ) {
188
+ await fs . copy ( path . join ( staging , ".jsii" ) , opts . jsii . path ) ;
189
+ }
190
+
191
+ // run pacmak to generate code
192
+ const endJsiiPacmakTimer = logTimespan ( "jsii-pacmak" ) ;
193
+ await exec ( pacmakModule , [ "--code-only" ] , { cwd : staging } ) ;
194
+ endJsiiPacmakTimer ( ) ;
195
+
196
+ if ( opts . python ) {
197
+ const reldir = opts . python . moduleName . replace ( / \. / g, "/" ) ; // jsii replaces "." with "/"
198
+ const source = path . resolve (
199
+ path . join ( staging , "dist/python/src" , reldir )
200
+ ) ;
201
+ const target = path . join ( opts . python . outdir , reldir ) ;
202
+ await fs . move ( source , target , { overwrite : true } ) ;
203
+ }
204
+
205
+ if ( opts . java ) {
206
+ const source = path . resolve ( path . join ( staging , "dist/java/src/" ) ) ;
207
+ const target = path . join ( opts . java . outdir , "src/" ) ;
208
+ await fs . mkdirp ( target ) ; // make sure target directory exists
209
+ await fs . copy ( source , target , { recursive : true , overwrite : false } ) ;
210
+ }
211
+
212
+ if ( opts . csharp ) {
213
+ const reldir = opts . csharp . namespace ;
214
+ const source = path . resolve ( path . join ( staging , "dist/dotnet/" , reldir ) ) ;
215
+ const target = path . join ( opts . csharp . outdir , reldir ) ;
216
+ await fs . move ( source , target , { overwrite : true } ) ;
217
+ }
218
+
219
+ if ( opts . golang ) {
220
+ const reldir = opts . golang . packageName ;
221
+ const source = path . resolve ( path . join ( staging , "dist/go/" , reldir ) ) ;
222
+ const target = path . join ( opts . golang . outdir , reldir ) ;
223
+ await fs . move ( source , target , { overwrite : true } ) ;
224
+ // remove go.mod as this would make it a submodule
225
+ await fs . remove ( path . join ( target , "go.mod" ) ) ;
226
+ }
227
+
47
228
[ "versions.json" , "constraints.json" ] . forEach ( ( file ) => {
48
229
try {
49
230
fs . copySync (
@@ -381,7 +562,7 @@ export class ConstructsMaker {
381
562
private async generateJsiiLanguage ( target : ConstructsMakerTarget ) {
382
563
// these are the module dependencies we compile against
383
564
const deps = [ "@types/node" , "constructs" , "cdktf" ] ;
384
- const opts : srcmak . Options = {
565
+ const opts : GenerateJSIIOptions = {
385
566
entrypoint : target . fileName ,
386
567
deps : deps . map ( ( dep ) =>
387
568
path . dirname ( require . resolve ( `${ dep } /package.json` ) )
0 commit comments