@treatwell/moleculer-call-wrapper 1.0.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.
package/dist/index.mjs ADDED
@@ -0,0 +1,694 @@
1
+ import { readFile, writeFile } from 'node:fs/promises';
2
+ import { isTypeReferenceNode, isQualifiedName, isImportDeclaration, isNamedImports, factory, createSourceFile, ScriptTarget, isMethodDeclaration, isPropertyAssignment, SyntaxKind, createPrinter, NewLineKind, NodeFlags, isCallExpression } from 'typescript';
3
+ import { readFileSync } from 'node:fs';
4
+ import { relative, dirname, resolve } from 'node:path';
5
+ import crypto from 'node:crypto';
6
+ import { cloneNode } from 'ts-clone-node';
7
+
8
+ const MOLECULER_NAME = "m";
9
+ function fillImports(context, sourceFile, node) {
10
+ node.forEachChild((n) => fillImports(context, sourceFile, n));
11
+ if (!isTypeReferenceNode(node)) {
12
+ return;
13
+ }
14
+ let nodeName = node.typeName.getText();
15
+ if (isQualifiedName(node.typeName)) {
16
+ nodeName = node.typeName.left.getText();
17
+ }
18
+ let importName = node.typeName.getText();
19
+ const importDeclaration = sourceFile.statements.filter(isImportDeclaration).find((n) => {
20
+ if (n.importClause?.namedBindings && isNamedImports(n.importClause.namedBindings)) {
21
+ const importIdentifier = n.importClause.namedBindings.elements.find(
22
+ (c) => c.name.getText() === nodeName
23
+ );
24
+ if (importIdentifier?.propertyName) {
25
+ importName = importIdentifier.propertyName.getText();
26
+ }
27
+ return !!importIdentifier;
28
+ }
29
+ return false;
30
+ });
31
+ if (importDeclaration) {
32
+ let key = importDeclaration.moduleSpecifier.getText().slice(1, -1);
33
+ if (key.startsWith(".")) {
34
+ key = `./${relative(
35
+ dirname(context.wrapperPath),
36
+ resolve(dirname(context.currentFilePath), key)
37
+ ).replace(/\\/g, "/")}`;
38
+ }
39
+ const name = addDepToImports(context.imports, key);
40
+ context.importMapping.set(node, `${name}.${importName}`);
41
+ }
42
+ }
43
+ function getUniqueNameFromKey(key) {
44
+ switch (key) {
45
+ case "@wavyapp/wavy-sdk":
46
+ return "sdk";
47
+ case "moleculer":
48
+ return MOLECULER_NAME;
49
+ default:
50
+ if (/^[a-zA-Z]\w+$/.test(key)) {
51
+ return key;
52
+ }
53
+ return `s${crypto.createHash("sha1").update(key).digest("hex").slice(0, 7)}`;
54
+ }
55
+ }
56
+ function addDepToImports(imports, key) {
57
+ let name = imports.get(key);
58
+ if (!name) {
59
+ name = getUniqueNameFromKey(key);
60
+ imports.set(key, name);
61
+ }
62
+ return name;
63
+ }
64
+ function importMappingCloneHook(importMapping) {
65
+ return (n) => {
66
+ if (isTypeReferenceNode(n) && importMapping.has(n)) {
67
+ return {
68
+ typeName: () => factory.createIdentifier(importMapping.get(n))
69
+ };
70
+ }
71
+ return void 0;
72
+ };
73
+ }
74
+
75
+ function parseService(context, service) {
76
+ const actions = [];
77
+ const sourceFile = createSourceFile(
78
+ "service.ts",
79
+ readFileSync(context.currentFilePath, "utf8"),
80
+ ScriptTarget.ESNext,
81
+ true
82
+ );
83
+ const handlers = findActionsTypes(context, sourceFile);
84
+ const version = service.version ? `v${service.version}.` : "";
85
+ Object.entries(service.schema.actions || {}).forEach(
86
+ ([actionName, action]) => {
87
+ if (action === false || typeof action === "object" && action.visibility === "private") {
88
+ return;
89
+ }
90
+ const { params, returnType, typeParameters } = handlers.get(actionName) || {};
91
+ if (typeParameters) {
92
+ typeParameters.forEach((tp) => fillImports(context, sourceFile, tp));
93
+ }
94
+ if (returnType) {
95
+ fillImports(context, sourceFile, returnType);
96
+ }
97
+ if (params) {
98
+ fillImports(context, sourceFile, params);
99
+ }
100
+ actions.push({
101
+ actionName: `${version}${service.name}.${actionName}`,
102
+ params,
103
+ returnType,
104
+ typeParameters
105
+ });
106
+ }
107
+ );
108
+ context.builtins.forEach(
109
+ (injectBuiltin) => injectBuiltin(context, actions, service, sourceFile)
110
+ );
111
+ return actions;
112
+ }
113
+ function findActionsTypes(context, sourceFile) {
114
+ const handlers = /* @__PURE__ */ new Map();
115
+ function visit(n) {
116
+ if (!isMethodDeclaration(n) || n.name.getText() !== "handler" || n.parameters.length !== 1) {
117
+ return n.forEachChild(visit);
118
+ }
119
+ if (!isPropertyAssignment(n.parent.parent)) {
120
+ return n.forEachChild(visit);
121
+ }
122
+ const ctxType = n.parameters[0].type;
123
+ if (!ctxType || !isTypeReferenceNode(ctxType)) {
124
+ return n.forEachChild(visit);
125
+ }
126
+ let paramsType;
127
+ if (ctxType.typeArguments?.length && ctxType.typeArguments[0].getText() !== "never") {
128
+ [paramsType] = ctxType.typeArguments;
129
+ }
130
+ handlers.set(n.parent.parent.name.getText(), {
131
+ params: paramsType,
132
+ returnType: n.type,
133
+ typeParameters: n.typeParameters
134
+ });
135
+ return void 0;
136
+ }
137
+ sourceFile.forEachChild(visit);
138
+ return handlers;
139
+ }
140
+
141
+ const ParamsActions = "Actions";
142
+ const NoParamsActions = "ActionsU";
143
+ function createWrapperParameters(action, importMapping, actionTypeGenericName) {
144
+ let actionParamType;
145
+ if (actionTypeGenericName) {
146
+ actionParamType = factory.createTypeReferenceNode(
147
+ factory.createIdentifier(actionTypeGenericName),
148
+ void 0
149
+ );
150
+ } else if (action.actionName) {
151
+ actionParamType = factory.createLiteralTypeNode(
152
+ factory.createStringLiteral(action.actionName, true)
153
+ );
154
+ } else {
155
+ actionParamType = factory.createKeywordTypeNode(SyntaxKind.StringKeyword);
156
+ }
157
+ return [
158
+ factory.createParameterDeclaration(
159
+ void 0,
160
+ void 0,
161
+ "ctx",
162
+ void 0,
163
+ factory.createTypeReferenceNode(`${MOLECULER_NAME}.Context`)
164
+ ),
165
+ factory.createParameterDeclaration(
166
+ void 0,
167
+ void 0,
168
+ "action",
169
+ void 0,
170
+ actionParamType
171
+ ),
172
+ factory.createParameterDeclaration(
173
+ void 0,
174
+ void 0,
175
+ "params",
176
+ action.params ? void 0 : factory.createToken(SyntaxKind.QuestionToken),
177
+ cloneNode(action.params, {
178
+ hook: importMappingCloneHook(importMapping)
179
+ }) || factory.createKeywordTypeNode(SyntaxKind.UndefinedKeyword)
180
+ ),
181
+ factory.createParameterDeclaration(
182
+ void 0,
183
+ void 0,
184
+ "meta",
185
+ factory.createToken(SyntaxKind.QuestionToken),
186
+ factory.createTypeReferenceNode(`${MOLECULER_NAME}.CallingOptions`)
187
+ )
188
+ ];
189
+ }
190
+ function createWrapperReturnType(action, importMapping) {
191
+ if (!action.returnType) {
192
+ return factory.createTypeReferenceNode("Promise", [
193
+ factory.createKeywordTypeNode(SyntaxKind.VoidKeyword)
194
+ ]);
195
+ }
196
+ if (isTypeReferenceNode(action.returnType) && action.returnType.getSourceFile() && action.returnType.typeName.getText() === "Promise") {
197
+ return cloneNode(action.returnType, {
198
+ hook: importMappingCloneHook(importMapping)
199
+ });
200
+ }
201
+ return factory.createTypeReferenceNode("Promise", [
202
+ cloneNode(action.returnType, {
203
+ hook: importMappingCloneHook(importMapping)
204
+ })
205
+ ]);
206
+ }
207
+ function createUnwrapReturnType(action, importMapping) {
208
+ if (!action.returnType) {
209
+ return factory.createKeywordTypeNode(SyntaxKind.VoidKeyword);
210
+ }
211
+ if (isTypeReferenceNode(action.returnType) && action.returnType.getSourceFile() && action.returnType.typeName.getText() === "Promise" && action.returnType.typeArguments?.length) {
212
+ return cloneNode(action.returnType.typeArguments[0], {
213
+ hook: importMappingCloneHook(importMapping)
214
+ });
215
+ }
216
+ return cloneNode(action.returnType, {
217
+ hook: importMappingCloneHook(importMapping)
218
+ });
219
+ }
220
+ function createWrapperTypeParameters(action, importMapping) {
221
+ if (!action.typeParameters) {
222
+ return [];
223
+ }
224
+ return action.typeParameters.map(
225
+ (tp) => cloneNode(tp, { hook: importMappingCloneHook(importMapping) })
226
+ );
227
+ }
228
+ function createWrapperFunctionOverload(action, importMapping, name, actionTypeGenericName, block) {
229
+ return factory.createFunctionDeclaration(
230
+ [factory.createModifier(SyntaxKind.ExportKeyword)],
231
+ void 0,
232
+ name,
233
+ createWrapperTypeParameters(action, importMapping),
234
+ createWrapperParameters(action, importMapping, actionTypeGenericName),
235
+ createWrapperReturnType(action, importMapping),
236
+ block
237
+ );
238
+ }
239
+ function findUnusedTemplateName(action) {
240
+ const typeNames = new Set(action.typeParameters?.map((t) => t.name.getText()));
241
+ let actionTemplateName = "N";
242
+ while (typeNames.has(actionTemplateName)) {
243
+ actionTemplateName += "N";
244
+ }
245
+ return actionTemplateName;
246
+ }
247
+ function buildCallWrapperFile(actions, imports, importMapping) {
248
+ const stmts = [];
249
+ let sortedImports = [...imports.keys()].sort();
250
+ sortedImports = [
251
+ ...sortedImports.filter((d) => d.startsWith("@")),
252
+ ...sortedImports.filter((d) => !d.startsWith(".") && !d.startsWith("@")),
253
+ ...sortedImports.filter((d) => d.startsWith("."))
254
+ ];
255
+ for (const importPath of sortedImports) {
256
+ const importName = imports.get(importPath);
257
+ stmts.push(
258
+ factory.createImportDeclaration(
259
+ void 0,
260
+ factory.createImportClause(
261
+ true,
262
+ void 0,
263
+ factory.createNamespaceImport(factory.createIdentifier(importName))
264
+ ),
265
+ factory.createStringLiteral(importPath, true)
266
+ )
267
+ );
268
+ }
269
+ const sortedActions = actions.sort(
270
+ (a, b) => (a.actionName || "").localeCompare(b.actionName || "")
271
+ );
272
+ const actionsProperties = [];
273
+ const actionsNoParamsProperties = [];
274
+ stmts.push(
275
+ factory.createInterfaceDeclaration(
276
+ void 0,
277
+ factory.createIdentifier(ParamsActions),
278
+ void 0,
279
+ void 0,
280
+ actionsProperties
281
+ )
282
+ );
283
+ stmts.push(
284
+ factory.createInterfaceDeclaration(
285
+ void 0,
286
+ factory.createIdentifier(NoParamsActions),
287
+ void 0,
288
+ void 0,
289
+ actionsNoParamsProperties
290
+ )
291
+ );
292
+ const callTStmts = [];
293
+ const callStmts = [];
294
+ for (const action of sortedActions) {
295
+ if (action.typeParameters?.length) {
296
+ const templateTypes = createWrapperTypeParameters(action, importMapping);
297
+ if (action.params) {
298
+ const actionTemplateName = findUnusedTemplateName(action);
299
+ action.params = factory.createConditionalTypeNode(
300
+ factory.createTypeReferenceNode(
301
+ factory.createIdentifier(actionTemplateName),
302
+ void 0
303
+ ),
304
+ factory.createLiteralTypeNode(
305
+ factory.createStringLiteral(action.actionName || "", true)
306
+ ),
307
+ action.params,
308
+ factory.createKeywordTypeNode(SyntaxKind.NeverKeyword)
309
+ );
310
+ action.typeParameters = factory.createNodeArray([
311
+ ...templateTypes,
312
+ factory.createTypeParameterDeclaration(
313
+ void 0,
314
+ factory.createIdentifier(actionTemplateName),
315
+ factory.createKeywordTypeNode(SyntaxKind.StringKeyword),
316
+ factory.createLiteralTypeNode(
317
+ factory.createStringLiteral(action.actionName || "", true)
318
+ )
319
+ )
320
+ ]);
321
+ callTStmts.push(
322
+ createWrapperFunctionOverload(
323
+ action,
324
+ importMapping,
325
+ "callT",
326
+ actionTemplateName
327
+ )
328
+ );
329
+ } else {
330
+ callStmts.push(
331
+ createWrapperFunctionOverload(action, importMapping, "call")
332
+ );
333
+ }
334
+ } else if (action.params) {
335
+ actionsProperties.push(
336
+ factory.createPropertySignature(
337
+ void 0,
338
+ factory.createStringLiteral(action.actionName || "", true),
339
+ void 0,
340
+ factory.createTupleTypeNode([
341
+ cloneNode(action.params, {
342
+ hook: importMappingCloneHook(importMapping)
343
+ }),
344
+ createUnwrapReturnType(action, importMapping)
345
+ ])
346
+ )
347
+ );
348
+ } else {
349
+ actionsNoParamsProperties.push(
350
+ factory.createPropertySignature(
351
+ void 0,
352
+ factory.createStringLiteral(action.actionName || "", true),
353
+ void 0,
354
+ createUnwrapReturnType(action, importMapping)
355
+ )
356
+ );
357
+ }
358
+ }
359
+ callStmts.push(
360
+ createWrapperFunctionOverload(
361
+ {
362
+ typeParameters: factory.createNodeArray([
363
+ factory.createTypeParameterDeclaration(
364
+ void 0,
365
+ factory.createIdentifier("N"),
366
+ factory.createTypeOperatorNode(
367
+ SyntaxKind.KeyOfKeyword,
368
+ factory.createTypeReferenceNode(
369
+ factory.createIdentifier(ParamsActions),
370
+ void 0
371
+ )
372
+ )
373
+ )
374
+ ]),
375
+ params: factory.createIndexedAccessTypeNode(
376
+ factory.createIndexedAccessTypeNode(
377
+ factory.createTypeReferenceNode(
378
+ factory.createIdentifier(ParamsActions)
379
+ ),
380
+ factory.createTypeReferenceNode(factory.createIdentifier("N"))
381
+ ),
382
+ factory.createLiteralTypeNode(factory.createNumericLiteral("0"))
383
+ ),
384
+ returnType: factory.createIndexedAccessTypeNode(
385
+ factory.createIndexedAccessTypeNode(
386
+ factory.createTypeReferenceNode(
387
+ factory.createIdentifier(ParamsActions),
388
+ void 0
389
+ ),
390
+ factory.createTypeReferenceNode(
391
+ factory.createIdentifier("N"),
392
+ void 0
393
+ )
394
+ ),
395
+ factory.createLiteralTypeNode(factory.createNumericLiteral("1"))
396
+ )
397
+ },
398
+ importMapping,
399
+ "call",
400
+ "N"
401
+ )
402
+ );
403
+ callStmts.push(
404
+ createWrapperFunctionOverload(
405
+ {
406
+ typeParameters: factory.createNodeArray([
407
+ factory.createTypeParameterDeclaration(
408
+ void 0,
409
+ factory.createIdentifier("N"),
410
+ factory.createTypeOperatorNode(
411
+ SyntaxKind.KeyOfKeyword,
412
+ factory.createTypeReferenceNode(
413
+ factory.createIdentifier(NoParamsActions),
414
+ void 0
415
+ )
416
+ )
417
+ )
418
+ ]),
419
+ returnType: factory.createIndexedAccessTypeNode(
420
+ factory.createTypeReferenceNode(
421
+ factory.createIdentifier(NoParamsActions),
422
+ void 0
423
+ ),
424
+ factory.createTypeReferenceNode(
425
+ factory.createIdentifier("N"),
426
+ void 0
427
+ )
428
+ )
429
+ },
430
+ importMapping,
431
+ "call",
432
+ "N"
433
+ )
434
+ );
435
+ callStmts.push(
436
+ createWrapperFunctionOverload(
437
+ {
438
+ params: factory.createKeywordTypeNode(SyntaxKind.UnknownKeyword),
439
+ returnType: factory.createKeywordTypeNode(SyntaxKind.UnknownKeyword)
440
+ },
441
+ importMapping,
442
+ "call",
443
+ void 0,
444
+ factory.createBlock(
445
+ [
446
+ factory.createReturnStatement(
447
+ factory.createCallExpression(
448
+ factory.createPropertyAccessExpression(
449
+ factory.createIdentifier("ctx"),
450
+ factory.createIdentifier("call")
451
+ ),
452
+ void 0,
453
+ [
454
+ factory.createIdentifier("action"),
455
+ factory.createIdentifier("params"),
456
+ factory.createIdentifier("meta")
457
+ ]
458
+ )
459
+ )
460
+ ],
461
+ true
462
+ )
463
+ )
464
+ );
465
+ callTStmts.push(
466
+ createWrapperFunctionOverload(
467
+ {
468
+ params: factory.createKeywordTypeNode(SyntaxKind.UnknownKeyword),
469
+ returnType: factory.createKeywordTypeNode(SyntaxKind.UnknownKeyword)
470
+ },
471
+ importMapping,
472
+ "callT",
473
+ void 0,
474
+ factory.createBlock(
475
+ [
476
+ factory.createReturnStatement(
477
+ factory.createCallExpression(
478
+ factory.createPropertyAccessExpression(
479
+ factory.createIdentifier("ctx"),
480
+ factory.createIdentifier("call")
481
+ ),
482
+ void 0,
483
+ [
484
+ factory.createIdentifier("action"),
485
+ factory.createIdentifier("params"),
486
+ factory.createIdentifier("meta")
487
+ ]
488
+ )
489
+ )
490
+ ],
491
+ true
492
+ )
493
+ )
494
+ );
495
+ const printer = createPrinter({ newLine: NewLineKind.LineFeed });
496
+ const sourceFile = factory.createSourceFile(
497
+ [...stmts, ...callStmts, ...callTStmts],
498
+ factory.createToken(SyntaxKind.EndOfFileToken),
499
+ NodeFlags.Const
500
+ );
501
+ let res = printer.printFile(sourceFile);
502
+ res = res.replace(/interface Actions/, "\ninterface Actions").replace(/export function call/, "\nexport function call").replace(/export function callT/, "\nexport function callT");
503
+ const eslintIgnoreRules = [
504
+ "@typescript-eslint/no-explicit-any",
505
+ "@typescript-eslint/no-unused-vars"
506
+ ];
507
+ res = `/* eslint-disable ${eslintIgnoreRules.join(",")} */
508
+ ${res}`;
509
+ return res;
510
+ }
511
+
512
+ function injectDatabaseMixinV2Builtins(context, actions, service, sourceFile) {
513
+ const dbMixin = service.originalSchema.mixins?.find(
514
+ (m) => m.methods?._getDatabaseMixinCollection
515
+ );
516
+ if (!dbMixin) {
517
+ return;
518
+ }
519
+ const types = findDatabaseMixinTypes(context, sourceFile);
520
+ if (!types) {
521
+ return;
522
+ }
523
+ const typeArguments = types.tenantField ? [types.entityType, types.tenantField] : [types.entityType];
524
+ const version = service.version ? `v${service.version}.` : "";
525
+ const dbActions = actions.filter((a) => a.actionName?.startsWith(`${version}${service.name}.`)).filter((a) => !a.params || !a.returnType);
526
+ const importName = addDepToImports(
527
+ context.imports,
528
+ "@treatwell/moleculer-essentials"
529
+ );
530
+ for (const action of dbActions) {
531
+ const actionName = action.actionName?.replace(
532
+ `${version}${service.name}.`,
533
+ ""
534
+ );
535
+ if (!action.params) {
536
+ switch (actionName) {
537
+ case "find":
538
+ case "findStream": {
539
+ action.params = factory.createTypeReferenceNode(
540
+ `${importName}.DatabaseActionFindParams`,
541
+ typeArguments
542
+ );
543
+ break;
544
+ }
545
+ case "getInternal": {
546
+ action.params = factory.createTypeReferenceNode(
547
+ `${importName}.DatabaseActionGetInternalParams`,
548
+ typeArguments
549
+ );
550
+ break;
551
+ }
552
+ case "get": {
553
+ action.params = factory.createTypeReferenceNode(
554
+ `${importName}.DatabaseActionGetParams`,
555
+ typeArguments
556
+ );
557
+ break;
558
+ }
559
+ case "countInternal": {
560
+ action.params = factory.createTypeReferenceNode(
561
+ `${importName}.DatabaseActionCountInternalParams`,
562
+ typeArguments
563
+ );
564
+ break;
565
+ }
566
+ case "count": {
567
+ action.params = factory.createTypeReferenceNode(
568
+ `${importName}.DatabaseActionCountParams`,
569
+ typeArguments
570
+ );
571
+ break;
572
+ }
573
+ case "list": {
574
+ action.params = factory.createTypeReferenceNode(
575
+ `${importName}.DatabaseActionListParams`,
576
+ typeArguments
577
+ );
578
+ break;
579
+ }
580
+ case "create": {
581
+ action.params = factory.createTypeReferenceNode(
582
+ `${importName}.DatabaseActionCreateParams`,
583
+ [types.entityType]
584
+ );
585
+ break;
586
+ }
587
+ case "update": {
588
+ action.params = factory.createTypeReferenceNode(
589
+ `${importName}.DatabaseActionUpdateParams`,
590
+ typeArguments
591
+ );
592
+ break;
593
+ }
594
+ case "remove": {
595
+ action.params = factory.createTypeReferenceNode(
596
+ `${importName}.DatabaseActionRemoveParams`,
597
+ typeArguments
598
+ );
599
+ break;
600
+ }
601
+ }
602
+ }
603
+ if (!action.returnType) {
604
+ switch (actionName) {
605
+ case "find": {
606
+ action.returnType = factory.createTypeReferenceNode(
607
+ `${importName}.DatabaseActionFindResult`,
608
+ [types.entityType]
609
+ );
610
+ break;
611
+ }
612
+ case "findStream": {
613
+ const streamImportName = addDepToImports(context.imports, "stream");
614
+ action.returnType = factory.createTypeReferenceNode(
615
+ `${streamImportName}.Readable`
616
+ );
617
+ break;
618
+ }
619
+ case "countInternal":
620
+ case "count": {
621
+ action.returnType = factory.createKeywordTypeNode(
622
+ SyntaxKind.NumberKeyword
623
+ );
624
+ break;
625
+ }
626
+ case "list": {
627
+ action.returnType = factory.createTypeReferenceNode(
628
+ `${importName}.DatabaseActionListResult`,
629
+ [types.entityType]
630
+ );
631
+ break;
632
+ }
633
+ case "create":
634
+ case "update":
635
+ case "remove":
636
+ case "getInternal":
637
+ case "get": {
638
+ action.returnType = factory.createTypeReferenceNode(
639
+ `${importName}.DatabaseActionEntityResult`,
640
+ [types.entityType]
641
+ );
642
+ break;
643
+ }
644
+ }
645
+ }
646
+ }
647
+ }
648
+ function findDatabaseMixinTypes(context, sourceFile) {
649
+ let res;
650
+ function visit(n) {
651
+ if (!isCallExpression(n) || n.expression.getText() !== "DatabaseMethodsMixin") {
652
+ n.forEachChild(visit);
653
+ return;
654
+ }
655
+ if (!n.typeArguments?.length) {
656
+ return;
657
+ }
658
+ res = { entityType: n.typeArguments[0], tenantField: n.typeArguments[1] };
659
+ }
660
+ visit(sourceFile);
661
+ if (res) {
662
+ fillImports(context, sourceFile, res.entityType);
663
+ if (res.tenantField) {
664
+ fillImports(context, sourceFile, res.tenantField);
665
+ }
666
+ }
667
+ return res;
668
+ }
669
+
670
+ async function createWrapperCall(wrapperPath, services, svcFiles, additionalBuiltins) {
671
+ const currentContent = await readFile(wrapperPath, "utf8");
672
+ const importMapping = /* @__PURE__ */ new Map();
673
+ const imports = /* @__PURE__ */ new Map();
674
+ addDepToImports(imports, "moleculer");
675
+ const builtins = [injectDatabaseMixinV2Builtins, ...additionalBuiltins];
676
+ const actions = services.flatMap(
677
+ (svc, idx) => parseService(
678
+ {
679
+ imports,
680
+ currentFilePath: svcFiles[idx],
681
+ wrapperPath,
682
+ importMapping,
683
+ builtins
684
+ },
685
+ svc
686
+ )
687
+ );
688
+ const wrapper = buildCallWrapperFile(actions, imports, importMapping);
689
+ if (currentContent !== wrapper && wrapper.trim()) {
690
+ await writeFile(wrapperPath, wrapper);
691
+ }
692
+ }
693
+
694
+ export { addDepToImports, createWrapperCall, fillImports };