java-bridge 2.1.1 → 2.1.4

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/package.json CHANGED
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "name": "java-bridge",
3
- "version": "2.1.1",
3
+ "version": "2.1.4",
4
4
  "main": "dist/index.prod.min.js",
5
- "typings": "ts-src/index.ts",
5
+ "types": "dist/ts-src/index.d.ts",
6
6
  "description": "A bridge between Node.js and Java APIs",
7
7
  "repository": {
8
8
  "type": "git",
@@ -14,8 +14,9 @@
14
14
  },
15
15
  "homepage": "https://github.com/MarkusJx/node-java-bridge#readme",
16
16
  "files": [
17
- "ts-src",
18
17
  "dist/*.js",
18
+ "dist/*.map",
19
+ "dist/**/*.d.ts",
19
20
  "java-src/build/libs/*.jar"
20
21
  ],
21
22
  "napi": {
@@ -48,12 +49,13 @@
48
49
  "postbuild": "npm run build:ts && npm run build:java",
49
50
  "build:napi": "napi build --platform --release --js native.js --dts native.d.ts",
50
51
  "build:napi:debug": "napi build --platform --js native.js --dts native.d.ts",
51
- "build:ts": "webpack build",
52
+ "build:ts": "webpack build && cpy native.d.ts dist",
52
53
  "build:java": "run-script-os",
53
54
  "build:java:darwin:linux": "cd java-src && chmod +x gradlew && ./gradlew shadowJar",
54
55
  "build:java:win32": "cd java-src && .\\gradlew.bat shadowJar",
55
56
  "prepublishOnly": "napi prepublish -t npm",
56
57
  "test": "mocha -r ts-node/register test/**/*.test.ts",
58
+ "testOnly": "mocha -r ts-node/register test/**/*.test.ts",
57
59
  "pretest": "npm run build",
58
60
  "version": "napi version",
59
61
  "prettier": "prettier --write .",
@@ -75,11 +77,12 @@
75
77
  "@types/chai": "^4.3.3",
76
78
  "@types/glob": "^8.0.0",
77
79
  "@types/mocha": "^9.1.1",
78
- "@types/node": "^18.7.14",
80
+ "@types/node": "^18.7.15",
79
81
  "@types/semver": "^7.3.12",
80
82
  "@types/webpack-node-externals": "^2.5.3",
81
83
  "@types/yargs": "^17.0.12",
82
84
  "chai": "^4.3.6",
85
+ "cpy-cli": "^4.2.0",
83
86
  "expose-gc": "^1.0.0",
84
87
  "mocha": "^10.0.0",
85
88
  "nanobench": "^3.0.0",
@@ -92,16 +95,16 @@
92
95
  "ts-loader": "^9.3.1",
93
96
  "ts-node": "^10.9.1",
94
97
  "tslib": "^2.4.0",
95
- "typedoc": "^0.23.13",
98
+ "typedoc": "^0.23.14",
96
99
  "webpack": "^5.74.0",
97
100
  "webpack-cli": "^4.10.0",
98
101
  "webpack-node-externals": "^3.0.0"
99
102
  },
100
103
  "optionalDependencies": {
101
- "java-bridge-win32-x64-msvc": "2.1.1",
102
- "java-bridge-darwin-x64": "2.1.1",
103
- "java-bridge-linux-x64-gnu": "2.1.1",
104
- "java-bridge-darwin-arm64": "2.1.1",
105
- "java-bridge-win32-ia32-msvc": "2.1.1"
104
+ "java-bridge-win32-x64-msvc": "2.1.4",
105
+ "java-bridge-darwin-x64": "2.1.4",
106
+ "java-bridge-linux-x64-gnu": "2.1.4",
107
+ "java-bridge-darwin-arm64": "2.1.4",
108
+ "java-bridge-win32-ia32-msvc": "2.1.4"
106
109
  }
107
110
  }
@@ -1,600 +0,0 @@
1
- import ts, { SyntaxKind } from 'typescript';
2
- import { importClass, importClassAsync, JavaClassInstance } from './.';
3
- import fs from 'fs';
4
- import path from 'path';
5
-
6
- const sourceFile = ts.createSourceFile(
7
- 'source.ts',
8
- '',
9
- ts.ScriptTarget.Latest,
10
- false,
11
- ts.ScriptKind.TS
12
- );
13
-
14
- interface MethodDeclaration {
15
- returnType: string;
16
- parameters: string[];
17
- isStatic: boolean;
18
- }
19
-
20
- interface ModuleDeclaration {
21
- name: string;
22
- contents: string;
23
- }
24
-
25
- type ProgressCallback = (classname: string) => void;
26
-
27
- declare class ModifierClass extends JavaClassInstance {
28
- public static isPublic(val: number): Promise<boolean>;
29
- public static isStatic(val: number): Promise<boolean>;
30
- }
31
-
32
- declare class TypeClass extends JavaClassInstance {
33
- public getTypeName(): Promise<string>;
34
- }
35
-
36
- declare class DeclaredMethodClass extends JavaClassInstance {
37
- public getModifiers(): Promise<number>;
38
- public getName(): Promise<string>;
39
- public getReturnType(): Promise<TypeClass>;
40
- public getParameterTypes(): Promise<TypeClass[]>;
41
- }
42
-
43
- declare class DeclaredConstructorClass extends JavaClassInstance {
44
- public getModifiers(): Promise<number>;
45
- public getParameterTypes(): Promise<TypeClass[]>;
46
- }
47
-
48
- declare class ClassClass extends JavaClassInstance {
49
- public getDeclaredMethods(): Promise<DeclaredMethodClass[]>;
50
- public getDeclaredConstructors(): Promise<DeclaredConstructorClass[]>;
51
- }
52
-
53
- export default class TypescriptDefinitionGenerator {
54
- private usesBasicOrJavaType: boolean = false;
55
- private readonly additionalImports: string[] = [];
56
- private readonly importsToResolve: string[] = [];
57
-
58
- public constructor(
59
- private readonly classname: string,
60
- private readonly progressCallback: ProgressCallback | null = null,
61
- private readonly resolvedImports: string[] = []
62
- ) {}
63
-
64
- private static async convertMethods(
65
- methods: DeclaredMethodClass[]
66
- ): Promise<Record<string, MethodDeclaration[]>> {
67
- const Modifier = await importClassAsync<typeof ModifierClass>(
68
- 'java.lang.reflect.Modifier'
69
- );
70
-
71
- const result: Record<string, MethodDeclaration[]> = {};
72
- for (const method of methods) {
73
- const modifiers = await method.getModifiers();
74
- if (await Modifier.isPublic(modifiers)) {
75
- const name = await method.getName();
76
- const returnType = await method.getReturnType();
77
- const parameterTypes = await method.getParameterTypes();
78
-
79
- const data: MethodDeclaration = {
80
- returnType: await returnType.getTypeName(),
81
- parameters: await Promise.all(
82
- parameterTypes.map((p) => p.getTypeName())
83
- ),
84
- isStatic: await Modifier.isStatic(modifiers),
85
- };
86
-
87
- if (Object.hasOwn(result, name)) {
88
- result[name].push(data);
89
- } else {
90
- result[name] = [data];
91
- }
92
- }
93
- }
94
-
95
- return result;
96
- }
97
-
98
- private async convertConstructors(
99
- constructors: DeclaredConstructorClass[]
100
- ): Promise<ts.ClassElement[]> {
101
- const Modifier = await importClassAsync<typeof ModifierClass>(
102
- 'java.lang.reflect.Modifier'
103
- );
104
- const types: string[][] = [];
105
-
106
- for (const constructor of constructors) {
107
- const modifiers = await constructor.getModifiers();
108
- if (await Modifier.isPublic(modifiers)) {
109
- const parameterTypes = await constructor.getParameterTypes();
110
- types.push(
111
- await Promise.all(
112
- parameterTypes.map((p) => p.getTypeName())
113
- )
114
- );
115
- }
116
- }
117
-
118
- const tsConstructors = types.map((t, i) => {
119
- const params = t.map(this.convertParameter.bind(this));
120
- let declaration = ts.factory.createConstructorDeclaration(
121
- undefined,
122
- [ts.factory.createModifier(ts.SyntaxKind.PublicKeyword)],
123
- params,
124
- undefined
125
- );
126
- if (i === 0) {
127
- declaration = ts.addSyntheticLeadingComment(
128
- declaration,
129
- ts.SyntaxKind.SingleLineCommentTrivia,
130
- ` ================== Constructors ==================`,
131
- true
132
- );
133
- }
134
-
135
- if (t.length > 0) {
136
- declaration = ts.addSyntheticLeadingComment(
137
- declaration,
138
- ts.SyntaxKind.MultiLineCommentTrivia,
139
- '*\n' +
140
- t
141
- .map(
142
- (p, i) =>
143
- ` * @param var${i} original type: '${p}'\n`
144
- )
145
- .join('') +
146
- ' ',
147
- true
148
- );
149
- }
150
-
151
- return declaration;
152
- });
153
-
154
- const newInstanceMethods = types.map((t, i) => {
155
- return this.createMethod(
156
- {
157
- returnType: this.classname,
158
- parameters: t,
159
- isStatic: true,
160
- },
161
- 'newInstance',
162
- i,
163
- false
164
- );
165
- });
166
-
167
- return [...newInstanceMethods, ...tsConstructors];
168
- }
169
-
170
- private javaTypeToTypescriptType(
171
- javaType: string,
172
- isParam: boolean
173
- ): ts.TypeNode {
174
- switch (javaType) {
175
- case 'byte[]':
176
- case 'java.lang.Byte[]':
177
- return {
178
- ...ts.factory.createIdentifier('Buffer'),
179
- _typeNodeBrand: '',
180
- };
181
- }
182
-
183
- if (javaType.endsWith('[]')) {
184
- return ts.factory.createArrayTypeNode(
185
- this.javaTypeToTypescriptType(
186
- javaType.substring(0, javaType.length - 2),
187
- isParam
188
- )
189
- );
190
- }
191
-
192
- switch (javaType) {
193
- case 'int':
194
- case 'java.lang.Integer':
195
- case 'long':
196
- case 'java.lang.Long':
197
- case 'float':
198
- case 'java.lang.Float':
199
- case 'double':
200
- case 'java.lang.Double':
201
- case 'byte':
202
- case 'java.lang.Byte':
203
- case 'short':
204
- case 'java.lang.Short':
205
- return ts.factory.createKeywordTypeNode(
206
- ts.SyntaxKind.NumberKeyword
207
- );
208
- case 'char':
209
- case 'java.lang.Character':
210
- case 'java.lang.String':
211
- return ts.factory.createKeywordTypeNode(
212
- ts.SyntaxKind.StringKeyword
213
- );
214
- case 'boolean':
215
- case 'java.lang.Boolean':
216
- return ts.factory.createKeywordTypeNode(
217
- ts.SyntaxKind.BooleanKeyword
218
- );
219
- case 'void':
220
- case 'java.lang.Void':
221
- return ts.factory.createKeywordTypeNode(
222
- ts.SyntaxKind.VoidKeyword
223
- );
224
- case 'java.lang.Object':
225
- this.usesBasicOrJavaType = true;
226
- return {
227
- ...ts.factory.createIdentifier('BasicOrJavaType'),
228
- _typeNodeBrand: '',
229
- };
230
- default:
231
- if (!this.resolvedImports.includes(javaType)) {
232
- this.additionalImports.push(javaType);
233
- }
234
-
235
- this.importsToResolve.push(javaType);
236
- const isSelf = javaType === this.classname && isParam;
237
-
238
- return {
239
- ...ts.factory.createIdentifier(
240
- javaType === this.classname
241
- ? javaType.substring(
242
- javaType.lastIndexOf('.') + 1
243
- ) + (isSelf ? 'Class' : '')
244
- : javaType.replaceAll('.', '_')
245
- ),
246
- _typeNodeBrand: '',
247
- };
248
- }
249
- }
250
-
251
- private convertParameter(
252
- param: string,
253
- index: number
254
- ): ts.ParameterDeclaration {
255
- const name = 'var' + index;
256
- const type = this.javaTypeToTypescriptType(param, true);
257
- return ts.factory.createParameterDeclaration(
258
- undefined,
259
- undefined,
260
- undefined,
261
- name,
262
- undefined,
263
- type
264
- );
265
- }
266
-
267
- private convertParameters(params: MethodDeclaration) {
268
- return params.parameters.map(this.convertParameter.bind(this));
269
- }
270
-
271
- private static createMethodComment(declaration: MethodDeclaration) {
272
- return (
273
- '*\n' +
274
- declaration.parameters
275
- .map((p, i) => ` * @param var${i} original type: '${p}'\n`)
276
- .join('') +
277
- ` * @return original return type: '${declaration.returnType}'\n `
278
- );
279
- }
280
-
281
- private createMethod(
282
- m: MethodDeclaration,
283
- name: string,
284
- i: number,
285
- isSync: boolean
286
- ): ts.MethodDeclaration {
287
- const publicMod = ts.factory.createModifier(
288
- ts.SyntaxKind.PublicKeyword
289
- );
290
- const staticMod = ts.factory.createModifier(
291
- ts.SyntaxKind.StaticKeyword
292
- );
293
-
294
- const modifiers: ts.Modifier[] = [publicMod];
295
- if (m.isStatic) {
296
- modifiers.push(staticMod);
297
- }
298
-
299
- let returnType = this.javaTypeToTypescriptType(m.returnType, false);
300
- if (!isSync) {
301
- returnType = ts.factory.createTypeReferenceNode(
302
- ts.factory.createIdentifier('Promise'),
303
- [returnType]
304
- );
305
- }
306
-
307
- let declaration = ts.factory.createMethodDeclaration(
308
- undefined,
309
- modifiers,
310
- undefined,
311
- name + (isSync ? 'Sync' : ''),
312
- undefined,
313
- undefined,
314
- this.convertParameters(m),
315
- returnType,
316
- undefined
317
- );
318
-
319
- if (i === 0) {
320
- declaration = ts.addSyntheticLeadingComment(
321
- declaration,
322
- ts.SyntaxKind.SingleLineCommentTrivia,
323
- ` ================== Method ${name} ==================`,
324
- true
325
- );
326
- }
327
-
328
- return ts.addSyntheticLeadingComment(
329
- declaration,
330
- ts.SyntaxKind.MultiLineCommentTrivia,
331
- TypescriptDefinitionGenerator.createMethodComment(m),
332
- true
333
- );
334
- }
335
-
336
- private convertMethod(
337
- method: MethodDeclaration[],
338
- name: string
339
- ): ts.MethodDeclaration[] {
340
- const res: ts.MethodDeclaration[] = [];
341
-
342
- for (let i = 0; i < method.length; i++) {
343
- const m = method[i];
344
-
345
- res.push(
346
- this.createMethod(m, name, i, false),
347
- this.createMethod(m, name, i, true)
348
- );
349
- }
350
-
351
- return res;
352
- }
353
-
354
- private getAdditionalImports() {
355
- const getPath = (i: string) => {
356
- const thisSplit: (string | null)[] = this.classname.split('.');
357
- const importSplit: (string | null)[] = i.split('.');
358
-
359
- for (let j = 0; j < thisSplit.length; j++) {
360
- if (importSplit[j] === thisSplit[j]) {
361
- thisSplit[j] = null;
362
- importSplit[j] = null;
363
- } else {
364
- break;
365
- }
366
- }
367
-
368
- return (
369
- './' +
370
- thisSplit
371
- .filter((e) => !!e)
372
- .map(() => '')
373
- .join('../') +
374
- importSplit.filter((e) => !!e).join('/')
375
- );
376
- };
377
-
378
- const unique = <T>(value: T, index: number, self: T[]) => {
379
- return self.indexOf(value) === index;
380
- };
381
-
382
- return this.importsToResolve
383
- .filter((i) => i != this.classname)
384
- .filter(unique)
385
- .map((i) =>
386
- ts.factory.createImportDeclaration(
387
- undefined,
388
- undefined,
389
- ts.factory.createImportClause(
390
- false,
391
- undefined,
392
- ts.factory.createNamedImports([
393
- ts.factory.createImportSpecifier(
394
- false,
395
- ts.factory.createIdentifier(
396
- i.substring(i.lastIndexOf('.') + 1)
397
- ),
398
- ts.factory.createIdentifier(
399
- i.replaceAll('.', '_')
400
- )
401
- ),
402
- ])
403
- ),
404
- ts.factory.createStringLiteral(getPath(i))
405
- )
406
- );
407
- }
408
-
409
- private getImports(): ts.ImportDeclaration {
410
- const importElements = [
411
- ts.factory.createImportSpecifier(
412
- false,
413
- undefined,
414
- ts.factory.createIdentifier('importClass')
415
- ),
416
- ts.factory.createImportSpecifier(
417
- false,
418
- undefined,
419
- ts.factory.createIdentifier('JavaClassInstance')
420
- ),
421
- ];
422
-
423
- if (this.usesBasicOrJavaType) {
424
- importElements.push(
425
- ts.factory.createImportSpecifier(
426
- false,
427
- undefined,
428
- ts.factory.createIdentifier('BasicOrJavaType')
429
- )
430
- );
431
- }
432
-
433
- const imports = ts.factory.createNamedImports(importElements);
434
- return ts.factory.createImportDeclaration(
435
- undefined,
436
- undefined,
437
- ts.factory.createImportClause(false, undefined, imports),
438
- ts.factory.createStringLiteral('java-bridge')
439
- );
440
- }
441
-
442
- private getExportStatement(simpleName: string) {
443
- const statement = ts.factory.createClassDeclaration(
444
- undefined,
445
- [ts.factory.createModifier(ts.SyntaxKind.ExportKeyword)],
446
- simpleName,
447
- undefined,
448
- [
449
- ts.factory.createHeritageClause(ts.SyntaxKind.ExtendsKeyword, [
450
- ts.factory.createExpressionWithTypeArguments(
451
- ts.factory.createIdentifier(
452
- `importClass<typeof ${simpleName}Class>("${this.classname}")`
453
- ),
454
- undefined
455
- ),
456
- ]),
457
- ],
458
- []
459
- );
460
-
461
- return [
462
- ts.addSyntheticLeadingComment(
463
- statement,
464
- SyntaxKind.MultiLineCommentTrivia,
465
- `*\n * Class ${this.classname}.\n *\n` +
466
- ' * This actually imports the java class for further use.\n' +
467
- ` * The class ${simpleName}Class only defines types, this is the class you should actually import.\n` +
468
- ' * Please note that this statement imports the underlying java class at runtime, which may take a while.\n' +
469
- ' * This was generated by java-bridge.\n * You should probably not edit this.\n ',
470
- true
471
- ),
472
- ts.factory.createExportDefault(
473
- ts.factory.createIdentifier(simpleName)
474
- ),
475
- ];
476
- }
477
-
478
- private getText(nodes: (ts.Node | null)[]) {
479
- return nodes
480
- .map(
481
- (n) =>
482
- (n &&
483
- ts
484
- .createPrinter({ newLine: ts.NewLineKind.LineFeed })
485
- .printNode(
486
- ts.EmitHint.Unspecified,
487
- n,
488
- sourceFile
489
- )) ||
490
- ''
491
- )
492
- .join('\n');
493
- }
494
-
495
- public async generate(): Promise<ModuleDeclaration[]> {
496
- if (this.resolvedImports.includes(this.classname)) {
497
- return [];
498
- }
499
-
500
- this.resolvedImports.push(this.classname);
501
- if (this.progressCallback) {
502
- this.progressCallback(this.classname);
503
- }
504
-
505
- const Class = await importClassAsync(this.classname);
506
- const cls = Class.class as ClassClass;
507
-
508
- const simpleName = this.classname.substring(
509
- this.classname.lastIndexOf('.') + 1
510
- );
511
- const methods = await cls.getDeclaredMethods();
512
-
513
- const classMembers: ts.ClassElement[] = [];
514
-
515
- const convertedMethods =
516
- await TypescriptDefinitionGenerator.convertMethods(methods);
517
- for (const key of Object.keys(convertedMethods)) {
518
- const m = convertedMethods[key];
519
- classMembers.push(...this.convertMethod(m, key));
520
- }
521
-
522
- const constructors = await cls.getDeclaredConstructors();
523
- const convertedConstructors = await this.convertConstructors(
524
- constructors
525
- );
526
- classMembers.push(...convertedConstructors);
527
-
528
- let tsClass = ts.factory.createClassDeclaration(
529
- undefined,
530
- [
531
- ts.factory.createModifier(ts.SyntaxKind.ExportKeyword),
532
- ts.factory.createModifier(ts.SyntaxKind.DeclareKeyword),
533
- ],
534
- simpleName + 'Class',
535
- undefined,
536
- [
537
- ts.factory.createHeritageClause(ts.SyntaxKind.ExtendsKeyword, [
538
- ts.factory.createExpressionWithTypeArguments(
539
- ts.factory.createIdentifier('JavaClassInstance'),
540
- undefined
541
- ),
542
- ]),
543
- ],
544
- classMembers
545
- );
546
-
547
- tsClass = ts.addSyntheticLeadingComment(
548
- tsClass,
549
- ts.SyntaxKind.MultiLineCommentTrivia,
550
- `*\n * This class just defines types, you should import ${simpleName} instead of this.\n` +
551
- ' * This was generated by java-bridge.\n * You should probably not edit this.\n ',
552
- true
553
- );
554
-
555
- const sourceText = this.getText([
556
- this.getImports(),
557
- ...this.getAdditionalImports(),
558
- null,
559
- tsClass,
560
- null,
561
- ...this.getExportStatement(simpleName),
562
- ]);
563
-
564
- const res: ModuleDeclaration[] = [];
565
- for (const imported of this.additionalImports) {
566
- const generator = new TypescriptDefinitionGenerator(
567
- imported,
568
- this.progressCallback,
569
- this.resolvedImports
570
- );
571
- const generated = await generator.generate();
572
- res.push(...generated);
573
- }
574
-
575
- res.push({
576
- name: this.classname,
577
- contents: sourceText,
578
- });
579
-
580
- return res;
581
- }
582
-
583
- public static async save(
584
- declarations: ModuleDeclaration[],
585
- sourceDir: string
586
- ): Promise<void> {
587
- for (const declaration of declarations) {
588
- const p = declaration.name.split('.');
589
- p[p.length - 1] = p[p.length - 1] + '.ts';
590
-
591
- const filePath = path.join(sourceDir, ...p);
592
- await fs.promises.mkdir(path.dirname(filePath), {
593
- recursive: true,
594
- });
595
- await fs.promises.writeFile(filePath, declaration.contents, {
596
- encoding: 'utf8',
597
- });
598
- }
599
- }
600
- }
package/ts-src/index.ts DELETED
@@ -1,24 +0,0 @@
1
- export {
2
- JavaVersion,
3
- JavaObject,
4
- JavaClassInstance,
5
- JavaClassProxy,
6
- JavaType,
7
- JavaConstructor,
8
- BasicOrJavaType,
9
- BasicType,
10
- ImportedMembers,
11
- JavaClassType,
12
- Constructor,
13
- } from './definitions';
14
- import type * as internal from '../native';
15
- /**
16
- * A namespace containing any internal type definitions.
17
- * Do not actually use anything from this namespace
18
- * as it only exports types.
19
- */
20
- export type { internal };
21
- export * from './java';
22
- import * as java from './java';
23
- export default java;
24
- export { getJavaLibPath } from '../native';