susee 0.1.3 → 0.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/dist/index.mjs CHANGED
@@ -5,1949 +5,4 @@ Licensed under the Apache License, Version 2.0 (the "License"); you may not use
5
5
  this file except in compliance with the License. You may obtain a copy of the
6
6
  License at http://www.apache.org/licenses/LICENSE-2.0
7
7
  ***************************************************************************** */
8
- import TsConfig from "@suseejs/tsconfig";
9
- import dependencies from "@suseejs/dependencies";
10
- import fs from "node:fs";
11
- import path from "node:path";
12
- import resolves from "@phothinmaung/resolves";
13
- import tcolor from "@suseejs/tcolor";
14
- import transformFunction from "@suseejs/transformer";
15
- import ts from "typescript";
16
- import utilities from "@suseejs/utils";
17
- import { Buffer } from "node:buffer";
18
- //src/lib/bundle/bundleCreator.ts
19
- /**
20
- * Creates a BundleCreator function that transforms a DepsFile with a given BundleVisitor and typescript compiler options.
21
- * @param {BundleVisitor} bundleVisitor - a BundleVisitor function that takes a context, depsTree, sourceFile, and any number of arguments.
22
- * @param {ts.CompilerOptions} compilerOptions - typescript compiler options.
23
- * @param {...any} args - any number of arguments to pass to the BundleVisitor function.
24
- * @returns {BundleCreator} a BundleCreator function that takes a DepsFile and returns a transformed DepsFile.
25
- */
26
- const bundleCreator = (bundleVisitor, compilerOptions, ...args) => {
27
- return (depsTree) => {
28
- const sourceFile = ts.createSourceFile(depsTree.file, depsTree.content, ts.ScriptTarget.Latest, true);
29
- const transformer = (context) => {
30
- const visitor = bundleVisitor(context, depsTree, sourceFile, ...args);
31
- return (rootNode) => ts.visitNode(rootNode, visitor);
32
- };
33
- let _content = transformFunction(transformer, sourceFile, compilerOptions);
34
- _content = _content.replace(/^s*;\s*$/gm, "").trim();
35
- const { content, ...rest } = depsTree;
36
- return { content: _content, ...rest };
37
- };
38
- };
39
- //src/lib/bundle/mergeImportsStatement.ts
40
- function mergeImportsStatement(imports) {
41
- const importMap = new Map();
42
- const typeImportMap = new Map();
43
- const defaultImports = new Map();
44
- const typeDefaultImports = new Map();
45
- const namespaceImports = new Map();
46
- // Parse each import statement
47
- for (const importStr of imports) {
48
- const importMatch = importStr.match(/import\s+(?:type\s+)?(?:(.*?)\s+from\s+)?["']([^"']+)["'];?/);
49
- if (!importMatch)
50
- continue;
51
- const [, importClause, _modulePath] = importMatch;
52
- const isTypeImport = importStr.includes("import type");
53
- const modulePath = _modulePath;
54
- if (!importClause) {
55
- // Default import or side-effect import
56
- const defaultMatch = importStr.match(/import\s+(?:type\s+)?(\w+)/);
57
- if (defaultMatch) {
58
- const importName = defaultMatch[1];
59
- const targetMap = isTypeImport ? typeDefaultImports : defaultImports;
60
- if (!targetMap.has(modulePath))
61
- targetMap.set(modulePath, new Set());
62
- targetMap.get(modulePath)?.add(importName);
63
- }
64
- continue;
65
- }
66
- if (importClause.startsWith("{")) {
67
- // Named imports: import { a, b } from 'module'
68
- const targetMap = isTypeImport ? typeImportMap : importMap;
69
- if (!targetMap.has(modulePath))
70
- targetMap.set(modulePath, new Set());
71
- const names = importClause
72
- .replace(/[{}]/g, "")
73
- .split(",")
74
- .map((s) => s.trim())
75
- .filter(Boolean);
76
- // biome-ignore lint/suspicious/useIterableCallbackReturn : just add name for names each
77
- names.forEach((name) => targetMap.get(modulePath)?.add(name));
78
- }
79
- else if (importClause.startsWith("* as")) {
80
- // Namespace import: import * as name from 'module'
81
- const namespaceMatch = importClause.match(/\*\s+as\s+(\w+)/);
82
- if (namespaceMatch) {
83
- const namespaceName = namespaceMatch[1];
84
- if (!namespaceImports.has(modulePath))
85
- namespaceImports.set(modulePath, new Set());
86
- namespaceImports.get(modulePath)?.add(namespaceName);
87
- }
88
- }
89
- else {
90
- // Default import: import name from 'module'
91
- const targetMap = isTypeImport ? typeDefaultImports : defaultImports;
92
- if (!targetMap.has(modulePath))
93
- targetMap.set(modulePath, new Set());
94
- targetMap.get(modulePath)?.add(importClause.trim());
95
- }
96
- }
97
- const mergedImports = [];
98
- // Process named imports - remove type imports that have regular imports
99
- for (const [modulePath, regularNames] of importMap) {
100
- const typeNames = typeImportMap.get(modulePath) || new Set();
101
- // Only include type names that don't have regular imports
102
- const finalNames = new Set([...regularNames]);
103
- for (const typeName of typeNames) {
104
- if (!regularNames.has(typeName)) {
105
- finalNames.add(typeName);
106
- }
107
- }
108
- if (finalNames.size > 0) {
109
- const importNames = Array.from(finalNames).sort().join(", ");
110
- mergedImports.push(`import { ${importNames} } from "${modulePath}";`);
111
- }
112
- }
113
- // Add remaining type-only imports (where no regular imports exist for the module)
114
- for (const [modulePath, typeNames] of typeImportMap) {
115
- if (!importMap.has(modulePath) && typeNames.size > 0) {
116
- const importNames = Array.from(typeNames).sort().join(", ");
117
- mergedImports.push(`import type { ${importNames} } from "${modulePath}";`);
118
- }
119
- }
120
- // Process default imports - remove type default imports that have regular default imports
121
- for (const [modulePath, regularDefaultNames] of defaultImports) {
122
- const typeDefaultNames = typeDefaultImports.get(modulePath) || new Set();
123
- // Only include type default names that don't have regular default imports
124
- const finalNames = new Set([...regularDefaultNames]);
125
- for (const typeName of typeDefaultNames) {
126
- if (!regularDefaultNames.has(typeName)) {
127
- finalNames.add(typeName);
128
- }
129
- }
130
- if (finalNames.size > 0) {
131
- const importNames = Array.from(finalNames).join(", ");
132
- mergedImports.push(`import ${importNames} from "${modulePath}";`);
133
- }
134
- }
135
- // Add remaining type-only default imports
136
- for (const [modulePath, typeDefaultNames] of typeDefaultImports) {
137
- if (!defaultImports.has(modulePath) && typeDefaultNames.size > 0) {
138
- const importNames = Array.from(typeDefaultNames).join(", ");
139
- mergedImports.push(`import type ${importNames} from "${modulePath}";`);
140
- }
141
- }
142
- // Process namespace imports
143
- for (const [modulePath, names] of namespaceImports) {
144
- if (names.size > 0) {
145
- const importNames = Array.from(names).join(", ");
146
- mergedImports.push(`import * as ${importNames} from "${modulePath}";`);
147
- }
148
- }
149
- return mergedImports.sort();
150
- }
151
- //src/lib/bundle/visitors/anonymousCallExpression.ts
152
- /**
153
- * A BundleVisitor that updates the call expression, property access expression, and new expression
154
- * with the anonymous default import name.
155
- */
156
- const anonymousCallExpressionVisitor = (context, depsTree, _sourceFile, exportDefaultImportNameMap) => {
157
- const { factory } = context;
158
- const visit = (node) => {
159
- if (ts.isCallExpression(node)) {
160
- if (ts.isIdentifier(node.expression)) {
161
- const base = node.expression.text;
162
- const mapping = exportDefaultImportNameMap.find((m) => m.base === base && m.file === depsTree.file);
163
- if (mapping) {
164
- return factory.updateCallExpression(node, factory.createIdentifier(mapping.newName), node.typeArguments, node.arguments);
165
- }
166
- }
167
- }
168
- else if (ts.isPropertyAccessExpression(node)) {
169
- if (ts.isIdentifier(node.expression)) {
170
- const base = node.expression.text;
171
- const mapping = exportDefaultImportNameMap.find((m) => m.base === base && m.file === depsTree.file);
172
- if (mapping) {
173
- return factory.updatePropertyAccessExpression(node, factory.createIdentifier(mapping.newName), node.name);
174
- }
175
- }
176
- }
177
- else if (ts.isNewExpression(node)) {
178
- if (ts.isIdentifier(node.expression)) {
179
- const base = node.expression.text;
180
- const mapping = exportDefaultImportNameMap.find((m) => m.base === base && m.file === depsTree.file);
181
- if (mapping) {
182
- return factory.updateNewExpression(node, factory.createIdentifier(mapping.newName), node.typeArguments, node.arguments);
183
- }
184
- }
185
- // for export specifier it is focus on entry file
186
- }
187
- else if (ts.isExportSpecifier(node)) {
188
- if (ts.isIdentifier(node.name)) {
189
- const base = node.name.text;
190
- const mapping = exportDefaultImportNameMap.find((m) => m.base === base && m.file === depsTree.file);
191
- if (mapping) {
192
- return factory.updateExportSpecifier(node, node.isTypeOnly, node.propertyName, factory.createIdentifier(mapping.newName));
193
- }
194
- }
195
- }
196
- return ts.visitEachChild(node, visit, context);
197
- };
198
- return visit;
199
- };
200
- //src/lib/bundle/visitors/visitorHelpers.ts
201
- const normalizePathKey = (filePath) => {
202
- const parsed = path.parse(filePath);
203
- let noExt = path.join(parsed.dir, parsed.name);
204
- if (parsed.name === "index") {
205
- noExt = parsed.dir;
206
- }
207
- return path.normalize(noExt);
208
- };
209
- const getFileKey = (filePath) => normalizePathKey(filePath);
210
- const getModuleKeyFromSpecifier = (moduleSpecifier, sourceFile, containingFile) => {
211
- let spec = "";
212
- if (ts.isStringLiteral(moduleSpecifier)) {
213
- spec = moduleSpecifier.text;
214
- }
215
- else {
216
- spec = moduleSpecifier.getText(sourceFile).replace(/^['"]|['"]$/g, "");
217
- }
218
- if (spec.startsWith(".") || spec.startsWith("/")) {
219
- const baseDir = path.dirname(containingFile);
220
- return normalizePathKey(path.resolve(baseDir, spec));
221
- }
222
- return spec;
223
- };
224
- function uniqueName() {
225
- const storedPrefix = new Map();
226
- const obj = {
227
- setPrefix({ key, value }) {
228
- const names = [];
229
- let _fix;
230
- if (storedPrefix.has(key)) {
231
- console.warn(`${key} already exist`);
232
- throw new Error();
233
- }
234
- else {
235
- _fix = value;
236
- storedPrefix.set(key, value);
237
- }
238
- function getName(input) {
239
- const length = names.length;
240
- const _name = _fix
241
- ? `${_fix}${input}_${length + 1}`
242
- : `$nyein${input}_${length + 1}`;
243
- names.push(_name);
244
- return _name;
245
- }
246
- return { getName };
247
- },
248
- getPrefix(key) {
249
- if (storedPrefix.has(key)) {
250
- return storedPrefix.get(key);
251
- }
252
- },
253
- };
254
- return obj;
255
- }
256
- //src/lib/bundle/visitors/anonymousExport.ts
257
- const prefixKey = "AnonymousName";
258
- const genName = uniqueName().setPrefix({ key: prefixKey, value: "a_" });
259
- /**
260
- * A BundleVisitor that updates the call expression, property access expression, and new expression
261
- * with the anonymous default import name.
262
- */
263
- const anonymousExportVisitor = (context, depsTree, sourceFile, exportDefaultExportNameMap) => {
264
- const { factory } = context;
265
- const visit = (node) => {
266
- const fileName = path.basename(depsTree.file).split(".")[0];
267
- if ((ts.isFunctionDeclaration(node) || ts.isClassDeclaration(node)) &&
268
- node.name === undefined) {
269
- let exp = false;
270
- let def = false;
271
- node.modifiers?.forEach((mod) => {
272
- if (mod.kind === ts.SyntaxKind.ExportKeyword) {
273
- exp = true;
274
- }
275
- if (mod.kind === ts.SyntaxKind.DefaultKeyword) {
276
- def = true;
277
- }
278
- });
279
- if (exp && def) {
280
- const base = genName.getName(fileName);
281
- exportDefaultExportNameMap.push({
282
- base,
283
- file: fileName,
284
- newName: base,
285
- isEd: true,
286
- });
287
- if (ts.isFunctionDeclaration(node)) {
288
- return factory.updateFunctionDeclaration(node, node.modifiers, node.asteriskToken, factory.createIdentifier(base), node.typeParameters, node.parameters, node.type, node.body);
289
- }
290
- else if (ts.isClassDeclaration(node)) {
291
- return factory.updateClassDeclaration(node, node.modifiers, factory.createIdentifier(base), node.typeParameters, node.heritageClauses, node.members);
292
- }
293
- }
294
- }
295
- else if (ts.isExportAssignment(node) &&
296
- !node.name &&
297
- !node.isExportEquals) {
298
- if (ts.isArrowFunction(node.expression)) {
299
- const base = genName.getName(fileName);
300
- const arrowFunctionNode = factory.createArrowFunction(node.expression.modifiers, node.expression.typeParameters, node.expression.parameters, node.expression.type, node.expression.equalsGreaterThanToken, node.expression.body);
301
- const variableDeclarationNode = factory.createVariableDeclaration(factory.createIdentifier(base), node.expression.exclamationToken, node.expression.type, arrowFunctionNode);
302
- const variableDeclarationListNode = factory.createVariableDeclarationList([variableDeclarationNode], ts.NodeFlags.Const);
303
- const variableStatementNode = factory.createVariableStatement(node.expression.modifiers, variableDeclarationListNode);
304
- const exportAssignmentNode = factory.createExportAssignment(undefined, undefined, factory.createIdentifier(base));
305
- exportDefaultExportNameMap.push({
306
- base,
307
- file: fileName,
308
- newName: base,
309
- isEd: true,
310
- });
311
- return factory.updateSourceFile(sourceFile, [variableStatementNode, exportAssignmentNode], sourceFile.isDeclarationFile, sourceFile.referencedFiles, sourceFile.typeReferenceDirectives, sourceFile.hasNoDefaultLib, sourceFile.libReferenceDirectives);
312
- }
313
- else if (ts.isObjectLiteralExpression(node.expression)) {
314
- const base = genName.getName(fileName);
315
- const variableDeclarationNode = factory.createVariableDeclaration(factory.createIdentifier(base), undefined, undefined, node.expression);
316
- const variableDeclarationListNode = factory.createVariableDeclarationList([variableDeclarationNode], ts.NodeFlags.Const);
317
- const variableStatementNode = factory.createVariableStatement(undefined, variableDeclarationListNode);
318
- const exportAssignmentNode = factory.createExportAssignment(undefined, undefined, factory.createIdentifier(base));
319
- exportDefaultExportNameMap.push({
320
- base,
321
- file: fileName,
322
- newName: base,
323
- isEd: true,
324
- });
325
- return factory.updateSourceFile(sourceFile, [variableStatementNode, exportAssignmentNode], sourceFile.isDeclarationFile, sourceFile.referencedFiles, sourceFile.typeReferenceDirectives, sourceFile.hasNoDefaultLib, sourceFile.libReferenceDirectives);
326
- }
327
- else if (ts.isArrayLiteralExpression(node.expression)) {
328
- const base = genName.getName(fileName);
329
- const arrayLiteralExpressionNode = factory.createArrayLiteralExpression(node.expression.elements, true);
330
- const variableDeclarationNode = factory.createVariableDeclaration(factory.createIdentifier(base), undefined, undefined, arrayLiteralExpressionNode);
331
- const variableDeclarationListNode = factory.createVariableDeclarationList([variableDeclarationNode], ts.NodeFlags.Const);
332
- const variableStatementNode = factory.createVariableStatement(undefined, variableDeclarationListNode);
333
- const exportAssignmentNode = factory.createExportAssignment(undefined, undefined, factory.createIdentifier(base));
334
- exportDefaultExportNameMap.push({
335
- base,
336
- file: fileName,
337
- newName: base,
338
- isEd: true,
339
- });
340
- return factory.updateSourceFile(sourceFile, [variableStatementNode, exportAssignmentNode], sourceFile.isDeclarationFile, sourceFile.referencedFiles, sourceFile.typeReferenceDirectives, sourceFile.hasNoDefaultLib, sourceFile.libReferenceDirectives);
341
- }
342
- else if (ts.isStringLiteral(node.expression)) {
343
- const base = genName.getName(fileName);
344
- const stringLiteralNode = factory.createStringLiteral(node.expression.text);
345
- const variableDeclarationNode = factory.createVariableDeclaration(factory.createIdentifier(base), undefined, undefined, stringLiteralNode);
346
- const variableDeclarationListNode = factory.createVariableDeclarationList([variableDeclarationNode], ts.NodeFlags.Const);
347
- const variableStatementNode = factory.createVariableStatement(undefined, variableDeclarationListNode);
348
- const exportAssignmentNode = factory.createExportAssignment(undefined, undefined, factory.createIdentifier(base));
349
- exportDefaultExportNameMap.push({
350
- base,
351
- file: fileName,
352
- newName: base,
353
- isEd: true,
354
- });
355
- return factory.updateSourceFile(sourceFile, [variableStatementNode, exportAssignmentNode], sourceFile.isDeclarationFile, sourceFile.referencedFiles, sourceFile.typeReferenceDirectives, sourceFile.hasNoDefaultLib, sourceFile.libReferenceDirectives);
356
- }
357
- else if (ts.isNumericLiteral(node.expression)) {
358
- const base = genName.getName(fileName);
359
- const numericLiteralNode = factory.createNumericLiteral(node.expression.text);
360
- const variableDeclarationNode = factory.createVariableDeclaration(factory.createIdentifier(base), undefined, undefined, numericLiteralNode);
361
- const variableDeclarationListNode = factory.createVariableDeclarationList([variableDeclarationNode], ts.NodeFlags.Const);
362
- const variableStatementNode = factory.createVariableStatement(undefined, variableDeclarationListNode);
363
- const exportAssignmentNode = factory.createExportAssignment(undefined, undefined, factory.createIdentifier(base));
364
- exportDefaultExportNameMap.push({
365
- base,
366
- file: fileName,
367
- newName: base,
368
- isEd: true,
369
- });
370
- return factory.updateSourceFile(sourceFile, [variableStatementNode, exportAssignmentNode], sourceFile.isDeclarationFile, sourceFile.referencedFiles, sourceFile.typeReferenceDirectives, sourceFile.hasNoDefaultLib, sourceFile.libReferenceDirectives);
371
- }
372
- } //
373
- return ts.visitEachChild(node, visit, context);
374
- };
375
- return visit;
376
- };
377
- //src/lib/bundle/visitors/anonymousImport.ts
378
- /**
379
- * A BundleVisitor that updates the import declaration, property access expression, and new expression
380
- * with the anonymous default import name.
381
- */
382
- const anonymousImportVisitor = (context, depsTree, sourceFile, exportDefaultExportNameMap, exportDefaultImportNameMap) => {
383
- const { factory } = context;
384
- const visit = (node) => {
385
- if (ts.isImportDeclaration(node)) {
386
- const fileName = node.moduleSpecifier.getText(sourceFile);
387
- const _name = path.basename(fileName).split(".")[0].trim();
388
- // check only import default expression
389
- if (node.importClause?.name && ts.isIdentifier(node.importClause.name)) {
390
- const base = node.importClause.name.text.trim();
391
- const mapping = exportDefaultExportNameMap.find((v) => v.file === _name);
392
- if (mapping) {
393
- exportDefaultImportNameMap.push({
394
- base,
395
- file: depsTree.file,
396
- newName: mapping.newName,
397
- isEd: true,
398
- });
399
- const newImportClause = factory.updateImportClause(node.importClause, node.importClause.phaseModifier, factory.createIdentifier(mapping.newName), node.importClause.namedBindings);
400
- return factory.updateImportDeclaration(node, node.modifiers, newImportClause, node.moduleSpecifier, node.attributes);
401
- }
402
- }
403
- }
404
- return ts.visitEachChild(node, visit, context);
405
- };
406
- return visit;
407
- };
408
- //src/lib/bundle/visitors/duplicateCallExpression.ts
409
- /**
410
- * A BundleVisitor that updates the call expression, property access expression, and new expression
411
- * with the anonymous default import name.
412
- */
413
- const duplicateCallExpressionVisitor = (context, depsTree, _sourceFile, callNameMap, importNameMap) => {
414
- const { factory } = context;
415
- const visit = (node) => {
416
- if (ts.isCallExpression(node)) {
417
- if (ts.isIdentifier(node.expression)) {
418
- const base = node.expression.text;
419
- let new_name = null;
420
- const mapping = callNameMap.find((m) => m.base === base && m.file === depsTree.file);
421
- const importMapping = importNameMap.find((m) => m.base === base && m.file === depsTree.file);
422
- if (mapping) {
423
- new_name = mapping.newName;
424
- }
425
- else if (importMapping) {
426
- new_name = importMapping.newName;
427
- //flag.push(new_name);
428
- }
429
- if (new_name) {
430
- return factory.updateCallExpression(node, factory.createIdentifier(new_name), node.typeArguments, node.arguments);
431
- }
432
- }
433
- }
434
- else if (ts.isPropertyAccessExpression(node)) {
435
- if (ts.isIdentifier(node.expression)) {
436
- const base = node.expression.text;
437
- let new_name = null;
438
- const mapping = callNameMap.find((m) => m.base === base && m.file === depsTree.file);
439
- const importMapping = importNameMap.find((m) => m.base === base && m.file === depsTree.file);
440
- if (mapping) {
441
- new_name = mapping.newName;
442
- }
443
- else if (importMapping) {
444
- new_name = importMapping.newName;
445
- }
446
- if (new_name) {
447
- return factory.updatePropertyAccessExpression(node, factory.createIdentifier(new_name), node.name);
448
- }
449
- }
450
- }
451
- else if (ts.isNewExpression(node)) {
452
- if (ts.isIdentifier(node.expression)) {
453
- const base = node.expression.text;
454
- let new_name = null;
455
- const mapping = callNameMap.find((m) => m.base === base && m.file === depsTree.file);
456
- const importMapping = importNameMap.find((m) => m.base === base && m.file === depsTree.file);
457
- if (mapping) {
458
- new_name = mapping.newName;
459
- }
460
- else if (importMapping) {
461
- new_name = importMapping.newName;
462
- }
463
- if (new_name) {
464
- return factory.updateNewExpression(node, factory.createIdentifier(new_name), node.typeArguments, node.arguments);
465
- }
466
- }
467
- }
468
- /* ----------------------Returns for visitor function------------------------------- */
469
- return ts.visitEachChild(node, visit, context);
470
- };
471
- return visit;
472
- };
473
- //src/lib/bundle/visitors/duplicateCollection.ts
474
- /**
475
- * A BundleVisitor that updates the collection (variable, function, class, etc)
476
- * declaration with the anonymous default import name.
477
- *
478
- * @param {BundleVisitor} context - The BundleVisitor context.
479
- * @param {DepsTree} depsTree - The deps tree object.
480
- * @param {SourceFile} sourceFile - The source file object.
481
- * @param {DuplicatesNameMap} namesMap - The DuplicatesNameMap object.
482
- * @return {NodeVisit} visit - The NodeVisit function.
483
- */
484
- const duplicateCollectionVisitor = (context, depsTree, _sourceFile, namesMap) => {
485
- //const { factory } = context;
486
- const visit = (node, isGlobalScope = true) => {
487
- // Global declarations များကိုသာ collect လုပ်မယ်
488
- if (isGlobalScope) {
489
- // Variable statements (const, let, var)
490
- if (ts.isVariableStatement(node)) {
491
- node.declarationList.declarations.forEach((decl) => {
492
- if (ts.isIdentifier(decl.name)) {
493
- const $name = decl.name.text;
494
- if (!namesMap.has($name)) {
495
- namesMap.set($name, new Set([{ file: depsTree.file }]));
496
- }
497
- else {
498
- // biome-ignore lint/style/noNonNullAssertion : !namesMap.has($name) before
499
- namesMap.get($name).add({ file: depsTree.file });
500
- }
501
- }
502
- });
503
- }
504
- // Function, Class, Enum, Interface, Type declarations
505
- else if (ts.isFunctionDeclaration(node) ||
506
- ts.isClassDeclaration(node) ||
507
- ts.isEnumDeclaration(node) ||
508
- ts.isInterfaceDeclaration(node) ||
509
- ts.isTypeAliasDeclaration(node)) {
510
- const $name = node.name?.text;
511
- if ($name) {
512
- if (!namesMap.has($name)) {
513
- namesMap.set($name, new Set([{ file: depsTree.file }]));
514
- }
515
- else {
516
- // biome-ignore lint/style/noNonNullAssertion : !namesMap.has($name) before
517
- namesMap.get($name).add({ file: depsTree.file });
518
- }
519
- }
520
- }
521
- }
522
- // Local scope ထဲရောက်သွားတဲ့ node တွေအတွက် recursive visit
523
- if (ts.isBlock(node) ||
524
- ts.isFunctionDeclaration(node) ||
525
- ts.isFunctionExpression(node) ||
526
- ts.isArrowFunction(node) ||
527
- ts.isMethodDeclaration(node) ||
528
- ts.isClassDeclaration(node)) {
529
- // Local scope ထဲကို ဝင်သွားပြီဆိုတာနဲ့ isGlobalScope = false
530
- if (ts.isBlock(node)) {
531
- ts.visitNodes(node.statements, (child) => visit(child, false));
532
- }
533
- else {
534
- ts.forEachChild(node, (child) => {
535
- visit(child, false);
536
- });
537
- }
538
- }
539
- else {
540
- // Global scope ထဲဆက်ရှိနေတဲ့ node တွေအတွက်
541
- return ts.visitEachChild(node, (child) => visit(child, isGlobalScope), context);
542
- }
543
- /* ----------------------Returns for visitNode function------------------------------- */
544
- return node;
545
- };
546
- return visit;
547
- };
548
- //src/lib/bundle/visitors/duplicateExportExpression.ts
549
- /**
550
- * A BundleVisitor that updates the call expression, property access expression, and new expression
551
- * with the anonymous default import name.
552
- */
553
- const duplicateExportExpressionVisitor = (context, depsTree, _sourceFile, callNameMap, importNameMap, exportNameMap) => {
554
- const { factory } = context;
555
- const visit = (node) => {
556
- if (ts.isExportSpecifier(node)) {
557
- if (ts.isIdentifier(node.name)) {
558
- const base = node.name.text;
559
- let new_name = null;
560
- const mapping = callNameMap.find((m) => m.base === base && m.file === depsTree.file);
561
- const importMapping = importNameMap.find((m) => m.base === base && m.file === depsTree.file);
562
- if (mapping) {
563
- exportNameMap.push({
564
- base,
565
- file: getFileKey(depsTree.file),
566
- newName: mapping.newName,
567
- });
568
- new_name = mapping.newName;
569
- }
570
- else if (importMapping) {
571
- new_name = importMapping.newName;
572
- }
573
- if (new_name) {
574
- return factory.updateExportSpecifier(node, node.isTypeOnly, node.propertyName, factory.createIdentifier(new_name));
575
- }
576
- }
577
- }
578
- else if (ts.isExportAssignment(node)) {
579
- const expr = node.expression;
580
- if (ts.isIdentifier(expr)) {
581
- const base = expr.text;
582
- let new_name = null;
583
- const mapping = callNameMap.find((m) => m.base === base && m.file === depsTree.file);
584
- const importMapping = importNameMap.find((m) => m.base === base && m.file === depsTree.file);
585
- if (mapping) {
586
- exportNameMap.push({
587
- base,
588
- file: getFileKey(depsTree.file),
589
- newName: mapping.newName,
590
- });
591
- new_name = mapping.newName;
592
- }
593
- else if (importMapping) {
594
- new_name = importMapping.newName;
595
- }
596
- if (new_name) {
597
- return factory.updateExportAssignment(node, node.modifiers, factory.createIdentifier(new_name));
598
- }
599
- }
600
- }
601
- /* ----------------------Returns for visitor function------------------------------- */
602
- return ts.visitEachChild(node, visit, context);
603
- };
604
- return visit;
605
- };
606
- //src/lib/bundle/visitors/duplicateImportExpression.ts
607
- /**
608
- * A BundleVisitor that updates the import declaration, property access expression, and new expression
609
- * with the anonymous default import name.
610
- *
611
- * @param {BundleVisitor} context - The BundleVisitor context.
612
- * @param {DepsTree} depsTree - The deps tree object.
613
- * @param {SourceFile} sourceFile - The source file object.
614
- * @param {NamesSets} exportNameMap - The export name map object.
615
- * @param {NamesSets} importNameMap - The import name map object.
616
- * @return {NodeVisit} visit - The NodeVisit function.
617
- */
618
- const duplicateImportExpressionVisitor = (context, depsTree, sourceFile, exportNameMap, importNameMap) => {
619
- const { factory } = context;
620
- const visit = (node) => {
621
- if (ts.isImportDeclaration(node)) {
622
- const moduleKey = getModuleKeyFromSpecifier(node.moduleSpecifier, sourceFile, depsTree.file);
623
- let baseNames = [];
624
- if (node.importClause?.namedBindings &&
625
- ts.isNamedImports(node.importClause.namedBindings)) {
626
- baseNames = node.importClause.namedBindings.elements.map((el) => el.name.text.trim());
627
- }
628
- // import default expression
629
- if (node.importClause?.name && ts.isIdentifier(node.importClause.name)) {
630
- const base = node.importClause.name.text.trim();
631
- const mapping = exportNameMap.find((m) => m.base === base && m.file === moduleKey);
632
- if (mapping) {
633
- importNameMap.push({
634
- base: mapping.base,
635
- file: depsTree.file,
636
- newName: mapping.newName,
637
- });
638
- const newImportClause = factory.updateImportClause(node.importClause, node.importClause.phaseModifier, factory.createIdentifier(mapping.newName), node.importClause.namedBindings);
639
- return factory.updateImportDeclaration(node, node.modifiers, newImportClause, node.moduleSpecifier, node.attributes);
640
- }
641
- }
642
- // import name , `import{ ... }`
643
- if (baseNames.length > 0 &&
644
- node.importClause &&
645
- node.importClause.namedBindings &&
646
- ts.isNamedImports(node.importClause.namedBindings)) {
647
- const updatedElements = node.importClause.namedBindings.elements.map((el) => {
648
- const mapping = exportNameMap.find((m) => m.base === el.name.text.trim() && m.file === moduleKey);
649
- if (mapping) {
650
- importNameMap.push({
651
- base: mapping.base,
652
- file: depsTree.file,
653
- newName: mapping.newName,
654
- });
655
- return factory.updateImportSpecifier(el, el.isTypeOnly, el.propertyName, factory.createIdentifier(mapping.newName));
656
- }
657
- return el;
658
- });
659
- const newNamedImports = factory.updateNamedImports(node.importClause.namedBindings, updatedElements);
660
- const newImportClause = factory.updateImportClause(node.importClause, node.importClause.phaseModifier, node.importClause.name, newNamedImports);
661
- return factory.updateImportDeclaration(node, node.modifiers, newImportClause, node.moduleSpecifier, node.attributes);
662
- }
663
- } //&&
664
- /* ----------------------Returns for visitor function------------------------------- */
665
- return ts.visitEachChild(node, visit, context);
666
- };
667
- return visit;
668
- };
669
- //src/lib/bundle/visitors/duplicateUpdate.ts
670
- const dupName = uniqueName().setPrefix({
671
- key: "DuplicatesNames",
672
- value: "d_",
673
- });
674
- /**
675
- * A BundleVisitor that updates the variable declaration, function declaration, and class declaration
676
- * with the duplicates name.
677
- *
678
- * @param {BundleVisitor} context - The BundleVisitor context.
679
- * @param {DepsTree} depsTree - The deps tree object.
680
- * @param {SourceFile} sourceFile - The source file object.
681
- * @param {DuplicatesNameMap} namesMap - The DuplicatesNameMap object.
682
- * @param {NamesSets} callNameMap - The NamesSets object.
683
- * @return {NodeVisit} visit - The NodeVisit function.
684
- */
685
- const duplicateUpdateVisitor = (context, depsTree, _sourceFile, namesMap, callNameMap) => {
686
- const { factory } = context;
687
- const visit = (node) => {
688
- if (ts.isVariableStatement(node)) {
689
- const newDeclarations = node.declarationList.declarations.map((decl) => {
690
- if (ts.isIdentifier(decl.name)) {
691
- const base = decl.name.text;
692
- // biome-ignore lint/style/noNonNullAssertion : namesMap.has(base) before that get just only size
693
- if (namesMap.has(base) && namesMap.get(base).size > 1) {
694
- const newName = dupName.getName(base);
695
- callNameMap.push({ base, file: depsTree.file, newName });
696
- return factory.updateVariableDeclaration(decl, factory.createIdentifier(newName), decl.exclamationToken, decl.type, decl.initializer);
697
- }
698
- }
699
- return decl;
700
- });
701
- const newDeclList = factory.updateVariableDeclarationList(node.declarationList, newDeclarations);
702
- return factory.updateVariableStatement(node, node.modifiers, newDeclList);
703
- }
704
- else if (ts.isFunctionDeclaration(node)) {
705
- if (node.name && ts.isIdentifier(node.name)) {
706
- const base = node.name.text;
707
- // biome-ignore lint/style/noNonNullAssertion : namesMap.has(base) before that get just only size
708
- if (namesMap.has(base) && namesMap.get(base).size > 1) {
709
- const newName = dupName.getName(base);
710
- callNameMap.push({ base, file: depsTree.file, newName });
711
- return factory.updateFunctionDeclaration(node, node.modifiers, node.asteriskToken, factory.createIdentifier(newName), node.typeParameters, node.parameters, node.type, node.body);
712
- }
713
- }
714
- }
715
- else if (ts.isClassDeclaration(node)) {
716
- if (node.name && ts.isIdentifier(node.name)) {
717
- const base = node.name.text;
718
- // biome-ignore lint/style/noNonNullAssertion : namesMap.has(base) before that get just only size
719
- if (namesMap.has(base) && namesMap.get(base).size > 1) {
720
- const newName = dupName.getName(base);
721
- callNameMap.push({ base, file: depsTree.file, newName });
722
- return factory.updateClassDeclaration(node, node.modifiers, factory.createIdentifier(newName), node.typeParameters, node.heritageClauses, node.members);
723
- }
724
- }
725
- }
726
- /* ----------------------Returns for visitor function------------------------------- */
727
- return ts.visitEachChild(node, visit, context);
728
- };
729
- return visit;
730
- };
731
- //src/lib/bundle/visitors/removeExports.ts
732
- /**
733
- * A BundleVisitor that removes all exports from the given source file.
734
- * It does so by stripping "export" modifiers from function, class, interface, type alias, enum, and variable declarations,
735
- * and by removing "export { foo }" and "export default" declarations entirely.
736
- */
737
- const removeExportsVisitor = (context) => {
738
- const { factory } = context;
739
- const visit = (node) => {
740
- // --- Case 1: Strip "export" modifiers ---
741
- const inside_nameSpace = utilities.isInsideNamespace(node);
742
- if (!inside_nameSpace) {
743
- if (ts.isFunctionDeclaration(node) ||
744
- ts.isClassDeclaration(node) ||
745
- ts.isInterfaceDeclaration(node) ||
746
- ts.isTypeAliasDeclaration(node) ||
747
- ts.isEnumDeclaration(node) ||
748
- ts.isVariableStatement(node)) {
749
- const modifiers = node.modifiers?.filter((m) => m.kind !== ts.SyntaxKind.ExportKeyword &&
750
- m.kind !== ts.SyntaxKind.DefaultKeyword);
751
- if (modifiers?.length !== node.modifiers?.length) {
752
- // If the node has an export modifier, remove it.
753
- // If the node is a function, class, interface, type alias, enum or variable declaration,
754
- // update the declaration by removing the export modifier.
755
- if (ts.isFunctionDeclaration(node)) {
756
- return factory.updateFunctionDeclaration(node, modifiers, node.asteriskToken, node.name, node.typeParameters, node.parameters, node.type, node.body);
757
- } // function
758
- if (ts.isClassDeclaration(node)) {
759
- return factory.updateClassDeclaration(node, modifiers, node.name, node.typeParameters, node.heritageClauses, node.members);
760
- } // class
761
- if (ts.isInterfaceDeclaration(node)) {
762
- return factory.updateInterfaceDeclaration(node, modifiers, node.name, node.typeParameters, node.heritageClauses, node.members);
763
- } // interface
764
- if (ts.isTypeAliasDeclaration(node)) {
765
- return factory.updateTypeAliasDeclaration(node, modifiers, node.name, node.typeParameters, node.type);
766
- } // types
767
- if (ts.isEnumDeclaration(node)) {
768
- return factory.updateEnumDeclaration(node, modifiers, node.name, node.members);
769
- } //enum
770
- if (ts.isVariableStatement(node)) {
771
- return factory.updateVariableStatement(node, modifiers, node.declarationList);
772
- } // vars
773
- } //--
774
- } // --- Case 1
775
- }
776
- // --- Case 2: Remove "export { foo }" entirely ---
777
- if (ts.isExportDeclaration(node)) {
778
- // If the node is an export declaration, remove it.
779
- return factory.createEmptyStatement();
780
- }
781
- // --- Case 3: Handle "export default ..." ---
782
- if (ts.isExportAssignment(node)) {
783
- const expr = node.expression;
784
- // export default Foo; -> remove line
785
- if (ts.isIdentifier(expr)) {
786
- return factory.createEmptyStatement();
787
- }
788
- }
789
- // --------- Visitor Return ------------------//
790
- return ts.visitEachChild(node, visit, context);
791
- };
792
- return visit;
793
- };
794
- //src/lib/bundle/visitors/removeImports.ts
795
- let properties = [];
796
- const typeObj = {};
797
- const typesNames = [];
798
- function findProperty(node) {
799
- const properties = [];
800
- if (ts.isPropertyAccessExpression(node) && ts.isIdentifier(node.expression)) {
801
- properties.push(node.expression.text);
802
- }
803
- node.forEachChild((n) => findProperty(n));
804
- return properties;
805
- }
806
- /**
807
- * A BundleVisitor that removes import declarations and import equals declarations from a TypeScript program.
808
- * The visitor collects the names of type-only import-equals and emits a named/default type import if the type-only import-equals is not a namespace-type alias.
809
- * The visitor also collects the names of type-only imports of namespace-type aliases and emits a namespace type import if the type-only import-equals is not a namespace-type alias.
810
- */
811
- const removeImportsVisitor = (context, depsTree, sourceFile, removedStatements) => {
812
- // Pre-scan: collect names of type-only import-equals (these are namespace-type aliases)
813
- // import type NameSpace = require("foo")
814
- const typeOnlyImportEquals = new Set();
815
- for (const stmt of sourceFile.statements) {
816
- if (ts.isImportEqualsDeclaration(stmt) && stmt.isTypeOnly) {
817
- const moduleReference = stmt.moduleReference;
818
- if (ts.isExternalModuleReference(moduleReference) &&
819
- ts.isStringLiteral(moduleReference.expression)) {
820
- typeOnlyImportEquals.add(stmt.name.text);
821
- }
822
- }
823
- }
824
- const { factory } = context;
825
- const visit = (node) => {
826
- properties = [...properties, ...findProperty(node)];
827
- const obj = {
828
- isNamespace: false,
829
- isTypeOnly: false,
830
- isTypeNamespace: false,
831
- source: "",
832
- importedString: undefined,
833
- importedObject: undefined,
834
- };
835
- // --- Case: TypeReference with QualifiedName (collect type usage)
836
- if (ts.isTypeReferenceNode(node) &&
837
- ts.isQualifiedName(node.typeName) &&
838
- ts.isIdentifier(node.typeName.left) &&
839
- ts.isIdentifier(node.typeName.right)) {
840
- const left = node.typeName.left.text;
841
- const right = node.typeName.right.text;
842
- typesNames.push(left);
843
- if (left in typeObj) {
844
- typeObj[left]?.push(right);
845
- }
846
- else {
847
- typeObj[left] = [right];
848
- }
849
- // If this qualified name refers to a type-only import-equals alias, DO NOT rewrite.
850
- // Rewriting (Foo.Bar -> Bar) was intended to support converting to named imports,
851
- // but for type-only namespace imports we will emit `import type * as Foo from "..."`.
852
- if (utilities.checkModuleType(sourceFile, depsTree.file).isCommonJs) {
853
- if (left !== "ts" && !typeOnlyImportEquals.has(left)) {
854
- return factory.updateTypeReferenceNode(node, factory.createIdentifier(right), undefined);
855
- }
856
- }
857
- }
858
- // ------------------------
859
- if (ts.isImportDeclaration(node)) {
860
- // --- Case 1: Import declarations
861
- const text = node.getText(sourceFile);
862
- removedStatements.push(text);
863
- return factory.createEmptyStatement();
864
- }
865
- //--- Case 2: Import equals declarations
866
- if (ts.isImportEqualsDeclaration(node)) {
867
- const name = node.name.text;
868
- const moduleReference = node.moduleReference;
869
- if (node.isTypeOnly) {
870
- obj.isTypeOnly = true;
871
- }
872
- obj.importedString = name;
873
- if (!obj.isTypeOnly) {
874
- if (properties.includes(name)) {
875
- obj.isNamespace = true;
876
- }
877
- }
878
- if (ts.isExternalModuleReference(moduleReference) &&
879
- ts.isStringLiteral(moduleReference.expression)) {
880
- obj.source = moduleReference.expression.text;
881
- }
882
- let t;
883
- if (obj.importedString && !obj.importedObject) {
884
- if (obj.isTypeOnly) {
885
- // If this import-equals was a type-only namespace alias, emit a namespace type import
886
- if (typeOnlyImportEquals.has(obj.importedString)) {
887
- t = `import type * as ${obj.importedString} from "${obj.source}";`;
888
- }
889
- else {
890
- // otherwise try to emit a named/default type import (existing behavior)
891
- if (typesNames.includes(obj.importedString)) {
892
- t = `import type { ${typeObj[obj.importedString]?.join(",")} } from "${obj.source}";`;
893
- }
894
- else {
895
- t = `import type ${obj.importedString} from "${obj.source}";`;
896
- }
897
- }
898
- }
899
- else {
900
- if (obj.isNamespace && obj.source && obj.source !== "typescript") {
901
- t = `import * as ${obj.importedString} from "${obj.source}";`;
902
- }
903
- else {
904
- t = `import ${obj.importedString} from "${obj.source}";`;
905
- }
906
- }
907
- }
908
- if (!obj.importedString && obj.importedObject) {
909
- t = `import { ${obj.importedObject.join(", ")} } from "${obj.source}";`;
910
- }
911
- // removed
912
- if (t) {
913
- removedStatements.push(t);
914
- return factory.createEmptyStatement();
915
- }
916
- }
917
- // --- Case 3: Require imports
918
- if (ts.isVariableStatement(node)) {
919
- const decls = node.declarationList.declarations;
920
- if (decls.length === 1) {
921
- const decl = decls[0];
922
- if (decl.initializer &&
923
- ts.isCallExpression(decl.initializer) &&
924
- ts.isIdentifier(decl.initializer.expression) &&
925
- decl.initializer.expression.escapedText === "require") {
926
- // imported from
927
- const arg = decl.initializer.arguments[0];
928
- if (ts.isStringLiteral(arg)) {
929
- obj.source = arg.text;
930
- }
931
- if (ts.isIdentifier(decl.name)) {
932
- const _n = decl.name.text;
933
- obj.importedString = _n;
934
- if (properties.includes(_n)) {
935
- obj.isNamespace = true;
936
- }
937
- }
938
- else if (ts.isObjectBindingPattern(decl.name)) {
939
- const _names = [];
940
- for (const ele of decl.name.elements) {
941
- if (ts.isIdentifier(ele.name)) {
942
- _names.push(ele.name.text);
943
- }
944
- }
945
- if (_names.length > 0) {
946
- obj.importedObject = _names;
947
- }
948
- }
949
- let tt;
950
- if (obj.importedString && !obj.importedObject) {
951
- if (obj.isNamespace) {
952
- tt = `import * as ${obj.importedString} from "${obj.source}";`;
953
- }
954
- else {
955
- tt = `import ${obj.importedString} from "${obj.source}";`;
956
- }
957
- }
958
- if (!obj.importedString && obj.importedObject) {
959
- tt = `import { ${obj.importedObject.join(", ")} } from "${obj.source}";`;
960
- }
961
- if (tt) {
962
- removedStatements.push(tt);
963
- return factory.createEmptyStatement();
964
- }
965
- }
966
- }
967
- }
968
- // --------- Visitor Return ------------------//
969
- return ts.visitEachChild(node, visit, context);
970
- };
971
- return visit;
972
- };
973
- //src/lib/bundle/index.ts
974
- // ------------------------------------------------------------------------------------//
975
- /**
976
- * Bundles a TypeScript project into a single file.
977
- * This function takes a {@link CollatedPoint} object as input and returns a {@link BundleResultPoint} object.
978
- * The function applies the following steps:
979
- * 1. Call dependency plugins.
980
- * 2. Handle duplicates.
981
- * 3. Handling anonymous imports and exports.
982
- * 4. Remove Imports.
983
- * 5. Remove Exports from dependencies only.
984
- * 6. Handle imported statements.
985
- * 7. Create final content.
986
- * 8. Call pre-process plugins.
987
- * 9. Returns.
988
- * @param {CollatedPoint} point - A {@link CollatedPoint} object.
989
- * @returns {Promise<BundleResultPoint>} - A promise resolves with a {@link BundleResultPoint} object.
990
- */
991
- async function bundler(point) {
992
- let depsFiles = point.depFiles;
993
- const reName = point.rename;
994
- const compilerOptions = point.tsOptions.default;
995
- const plugins = point.plugins;
996
- // construct maps
997
- const namesMap = new Map();
998
- const callNameMap = [];
999
- const importNameMap = [];
1000
- const exportNameMap = [];
1001
- const exportDefaultExportNameMap = [];
1002
- const exportDefaultImportNameMap = [];
1003
- let removedStatements = [];
1004
- const duplicate = async (reName) => {
1005
- if (reName) {
1006
- // order is important here
1007
- const re_name = resolves([
1008
- // collector
1009
- [bundleCreator, duplicateCollectionVisitor, compilerOptions, namesMap],
1010
- // update
1011
- [
1012
- bundleCreator,
1013
- duplicateUpdateVisitor,
1014
- compilerOptions,
1015
- namesMap,
1016
- callNameMap,
1017
- ],
1018
- // call exp
1019
- [
1020
- bundleCreator,
1021
- duplicateCallExpressionVisitor,
1022
- compilerOptions,
1023
- callNameMap,
1024
- importNameMap,
1025
- ],
1026
- // export exp
1027
- [
1028
- bundleCreator,
1029
- duplicateExportExpressionVisitor,
1030
- compilerOptions,
1031
- importNameMap,
1032
- exportNameMap,
1033
- ],
1034
- // import exp
1035
- [
1036
- bundleCreator,
1037
- duplicateImportExpressionVisitor,
1038
- compilerOptions,
1039
- exportNameMap,
1040
- importNameMap,
1041
- ],
1042
- // export exp again
1043
- [
1044
- bundleCreator,
1045
- duplicateExportExpressionVisitor,
1046
- compilerOptions,
1047
- importNameMap,
1048
- exportNameMap,
1049
- ],
1050
- // export exp again
1051
- [
1052
- bundleCreator,
1053
- duplicateExportExpressionVisitor,
1054
- compilerOptions,
1055
- importNameMap,
1056
- exportNameMap,
1057
- ],
1058
- ]); // re_name
1059
- const re_name_call = await re_name.concurrent();
1060
- for (const call of re_name_call) {
1061
- await utilities.wait(500);
1062
- depsFiles = depsFiles.map(call);
1063
- }
1064
- }
1065
- else {
1066
- let _err = false;
1067
- const un_rename = resolves([
1068
- // collector
1069
- [bundleCreator, duplicateCollectionVisitor, compilerOptions, namesMap],
1070
- ]);
1071
- const un_rename_call = await un_rename.concurrent();
1072
- depsFiles.map(un_rename_call[0]);
1073
- await utilities.wait(1000);
1074
- namesMap.forEach((files, name) => {
1075
- if (files.size > 1) {
1076
- _err = true;
1077
- console.warn(`Name -> ${name} declared in multiple files :`);
1078
- // biome-ignore lint/suspicious/useIterableCallbackReturn : just log warn
1079
- files.forEach((f) => console.warn(` - ${f.file}`));
1080
- }
1081
- });
1082
- await utilities.wait(1000);
1083
- if (_err) {
1084
- process.exit(1);
1085
- }
1086
- }
1087
- };
1088
- // 1. Call dependency plugins
1089
- if (plugins.length) {
1090
- for (let plugin of plugins) {
1091
- plugin = typeof plugin === "function" ? plugin() : plugin;
1092
- if (plugin.type === "dependency") {
1093
- if (plugin.async) {
1094
- depsFiles = await plugin.func(depsFiles);
1095
- }
1096
- else {
1097
- depsFiles = plugin.func(depsFiles);
1098
- }
1099
- }
1100
- }
1101
- } //--
1102
- await utilities.wait(1000);
1103
- // 2. Handle duplicates
1104
- await duplicate(reName);
1105
- // 3. Handling anonymous imports and exports
1106
- const anonymous = resolves([
1107
- [
1108
- bundleCreator,
1109
- anonymousExportVisitor,
1110
- compilerOptions,
1111
- exportDefaultExportNameMap,
1112
- ],
1113
- [
1114
- bundleCreator,
1115
- anonymousImportVisitor,
1116
- compilerOptions,
1117
- exportDefaultImportNameMap,
1118
- exportDefaultImportNameMap,
1119
- ],
1120
- [
1121
- bundleCreator,
1122
- anonymousCallExpressionVisitor,
1123
- compilerOptions,
1124
- exportDefaultImportNameMap,
1125
- ],
1126
- ]);
1127
- const anonymousCall = await anonymous.concurrent();
1128
- for (const call of anonymousCall) {
1129
- depsFiles = depsFiles.map(call);
1130
- }
1131
- await utilities.wait(1000);
1132
- // 4. Remove Imports
1133
- const removeImports = resolves([
1134
- [bundleCreator, removeImportsVisitor, compilerOptions, removedStatements],
1135
- ]);
1136
- const removeImport = await removeImports.concurrent();
1137
- depsFiles = depsFiles.map(removeImport[0]);
1138
- await utilities.wait(500);
1139
- // 5. Remove Exports from dependencies only
1140
- const removeExports = resolves([
1141
- [bundleCreator, removeExportsVisitor, compilerOptions],
1142
- ]);
1143
- const removeExport = await removeExports.concurrent();
1144
- // not remove exports from entry file
1145
- const deps_files = depsFiles.slice(0, -1).map(removeExport[0]);
1146
- const mainFile = depsFiles.slice(-1);
1147
- // 6. Handle imported statements
1148
- // filter removed statements , that not from local like `./` or `../`
1149
- const regexp = /["']((?!\.\/|\.\.\/)[^"']+)["']/;
1150
- removedStatements = removedStatements.filter((i) => regexp.test(i));
1151
- removedStatements = mergeImportsStatement(removedStatements);
1152
- // 7. Create final content
1153
- // make sure all imports are at the top of file
1154
- const importStatements = removedStatements.join("\n").trim();
1155
- const depFilesContent = deps_files
1156
- .map((i) => {
1157
- const file = `//${path.relative(process.cwd(), i.file)}`;
1158
- return `${file}\n${i.content}`;
1159
- })
1160
- .join("\n")
1161
- .trim();
1162
- const mainFileContent = mainFile
1163
- .map((i) => {
1164
- const file = `//${path.relative(process.cwd(), i.file)}`;
1165
- return `${file}\n${i.content}`;
1166
- })
1167
- .join("\n")
1168
- .trim();
1169
- await utilities.wait(1000);
1170
- // text join order is important here
1171
- let content = `${importStatements}\n${depFilesContent}\n${mainFileContent}`;
1172
- // 8. Call pre-process plugins
1173
- if (plugins.length) {
1174
- for (let plugin of plugins) {
1175
- plugin = typeof plugin === "function" ? plugin() : plugin;
1176
- if (plugin.type === "pre-process") {
1177
- if (plugin.async) {
1178
- content = await plugin.func(content);
1179
- }
1180
- else {
1181
- content = plugin.func(content);
1182
- }
1183
- }
1184
- }
1185
- } //--
1186
- // 9. Returns
1187
- return { bundledContent: content, ...point };
1188
- }
1189
- async function bundle(object) {
1190
- const points = [];
1191
- for (const point of object.points) {
1192
- const _point = await bundler(point);
1193
- points.push(_point);
1194
- }
1195
- return {
1196
- points,
1197
- allowUpdatePackageJson: object.allowUpdatePackageJson,
1198
- };
1199
- }
1200
- //src/lib/compile/host.ts
1201
- /**
1202
- * Creates a ts.CompilerHost that can be used with the typescript compiler.
1203
- * This host is designed to be used with in-memory compilation and will
1204
- * return the source file for the given fileName and will write all output
1205
- * files to the createdFiles object.
1206
- * @param {string} sourceCode - the source code to compile
1207
- * @param {string} fileName - the name of the file to compile
1208
- * @returns {{createdFiles: Record<string, string>, host: ts.CompilerHost}}
1209
- */
1210
- function createHost(sourceCode, fileName) {
1211
- const createdFiles = {};
1212
- const host = {
1213
- getSourceFile: (file, languageVersion) => {
1214
- if (file === fileName) {
1215
- return ts.createSourceFile(file, sourceCode, languageVersion);
1216
- }
1217
- return undefined;
1218
- },
1219
- writeFile: (fileName, contents) => {
1220
- createdFiles[fileName] = contents;
1221
- },
1222
- getDefaultLibFileName: (options) => ts.getDefaultLibFilePath(options),
1223
- getCurrentDirectory: () => "",
1224
- getDirectories: () => [],
1225
- fileExists: (file) => file === fileName,
1226
- readFile: (file) => (file === fileName ? sourceCode : undefined),
1227
- getCanonicalFileName: (file) => file,
1228
- useCaseSensitiveFileNames: () => true,
1229
- getNewLine: () => "\n",
1230
- };
1231
- return { createdFiles, host };
1232
- }
1233
- //src/lib/compile/package.ts
1234
- const isCjs = (files) => files.commonjs && files.commonjsTypes;
1235
- const isEsm = (files) => files.esm && files.esmTypes;
1236
- /**
1237
- * Builds a package exports mapping for the given output files and export path.
1238
- *
1239
- * Produces the appropriate export shape based on whether CommonJS and/or ESM
1240
- * artifacts are present, including their default entry points and type
1241
- * definitions. If neither format is available, returns an empty object.
1242
- *
1243
- * @param files - The build output file paths for CommonJS/ESM and their types.
1244
- * @param exportPath - The subpath export key (e.g. "." or "./feature").
1245
- * @returns A {@link Exports} object describing the package exports map.
1246
- */
1247
- function getExports(files, exportPath) {
1248
- return isCjs(files) && isEsm(files)
1249
- ? {
1250
- [exportPath]: {
1251
- import: {
1252
- types: `./${path.relative(process.cwd(), files.esmTypes)}`,
1253
- default: `./${path.relative(process.cwd(), files.esm)}`,
1254
- },
1255
- require: {
1256
- types: `./${path.relative(process.cwd(), files.commonjsTypes)}`,
1257
- default: `./${path.relative(process.cwd(), files.commonjs)}`,
1258
- },
1259
- },
1260
- }
1261
- : isCjs(files) && !isEsm(files)
1262
- ? {
1263
- [exportPath]: {
1264
- require: {
1265
- types: `./${path.relative(process.cwd(), files.commonjsTypes)}`,
1266
- default: `./${path.relative(process.cwd(), files.commonjs)}`,
1267
- },
1268
- },
1269
- }
1270
- : !isCjs(files) && isEsm(files)
1271
- ? {
1272
- [exportPath]: {
1273
- import: {
1274
- types: `./${path.relative(process.cwd(), files.esmTypes)}`,
1275
- default: `./${path.relative(process.cwd(), files.esm)}`,
1276
- },
1277
- },
1278
- }
1279
- : {};
1280
- }
1281
- /**
1282
- * Writes an updated `package.json` based on output files and export path.
1283
- *
1284
- * Determines module type (ESM/CommonJS), adjusts `main`, `module`, `types`,
1285
- * and `exports` fields, and preserves other existing fields from the
1286
- * current `package.json`.
1287
- *
1288
- * @param files - The generated output files used to populate entry points.
1289
- * @param exportPath - The export path for subpath exports; "." denotes main export.
1290
- */
1291
- async function writePackage(files, exportPath) {
1292
- let isMain = true;
1293
- if (exportPath !== ".") {
1294
- isMain = false;
1295
- }
1296
- const pkgFile = ts.sys.resolvePath("package.json");
1297
- const _pkgtext = fs.readFileSync(pkgFile, "utf8");
1298
- const pkgtext = JSON.parse(_pkgtext);
1299
- let { name, version, description, main, module, type, types, exports, ...rest } = pkgtext;
1300
- await utilities.wait(500);
1301
- type = "module";
1302
- let _main = {};
1303
- let _module = {};
1304
- let _types = {};
1305
- let _exports = {};
1306
- if (isMain) {
1307
- _main = files.main
1308
- ? { main: path.relative(process.cwd(), files.main) }
1309
- : {};
1310
- _module = files.module
1311
- ? { module: path.relative(process.cwd(), files.module) }
1312
- : {};
1313
- _types = files.types
1314
- ? { types: path.relative(process.cwd(), files.types) }
1315
- : {};
1316
- _exports = { exports: { ...getExports(files, exportPath) } };
1317
- }
1318
- else {
1319
- _main = main ? { main: main } : {};
1320
- _module = module ? { module: module } : {};
1321
- _types = types ? { types: types } : {};
1322
- const normalizedExports = exports && typeof exports === "object" && !Array.isArray(exports)
1323
- ? { ...exports }
1324
- : {};
1325
- _exports = {
1326
- exports: { ...normalizedExports, ...getExports(files, exportPath) },
1327
- };
1328
- }
1329
- await utilities.wait(1000);
1330
- const pkgJson = {
1331
- name,
1332
- version,
1333
- description,
1334
- type,
1335
- ..._main,
1336
- ..._types,
1337
- ..._module,
1338
- ..._exports,
1339
- ...rest,
1340
- };
1341
- utilities.writeCompileFile(pkgFile, JSON.stringify(pkgJson, null, 2));
1342
- }
1343
- //src/lib/compile/index.ts
1344
- function splitCamelCase(str) {
1345
- const splitString = str
1346
- .replace(/([a-z])([A-Z])/g, "$1 $2")
1347
- .replace(/(_|-|\/)([a-z] || [A-Z])/g, " ")
1348
- .replace(/([A-Z])/g, (match) => match.toLowerCase())
1349
- .replace(/^([a-z])/, (match) => match.toUpperCase());
1350
- return splitString;
1351
- }
1352
- class Compiler {
1353
- constructor(object) {
1354
- this.object = object;
1355
- this.files = {
1356
- commonjs: undefined,
1357
- commonjsTypes: undefined,
1358
- esm: undefined,
1359
- esmTypes: undefined,
1360
- main: undefined,
1361
- module: undefined,
1362
- types: undefined,
1363
- };
1364
- }
1365
- _isUpdate() {
1366
- return this.object.allowUpdatePackageJson;
1367
- }
1368
- async _commonjs(point) {
1369
- const isMain = point.exportPath === ".";
1370
- const _name = isMain ? "Main" : splitCamelCase(point.exportPath.slice(2));
1371
- console.time(tcolor.cyan(`Compiled commonjs for ${_name} export path`));
1372
- // init
1373
- const fileName = point.fileName;
1374
- const sourceCode = point.bundledContent;
1375
- const format = point.format;
1376
- const plugins = point.plugins;
1377
- const compilerOptions = point.tsOptions.cjs;
1378
- // create host
1379
- const _host = createHost(sourceCode, fileName);
1380
- const createdFiles = _host.createdFiles;
1381
- const host = _host.host;
1382
- const program = ts.createProgram([fileName], compilerOptions, host);
1383
- program.emit();
1384
- Object.entries(createdFiles).map(async ([outName, content]) => {
1385
- // ------------------------------------
1386
- if (plugins.length) {
1387
- for (let plugin of plugins) {
1388
- plugin = typeof plugin === "function" ? plugin() : plugin;
1389
- if (plugin.type === "post-process") {
1390
- if (plugin.async) {
1391
- content = await plugin.func(content, outName);
1392
- }
1393
- else {
1394
- content = plugin.func(content, outName);
1395
- }
1396
- }
1397
- }
1398
- }
1399
- if (this._isUpdate()) {
1400
- if (outName.match(/.js/g)) {
1401
- this.files.commonjs = outName.replace(/.js/g, ".cjs");
1402
- }
1403
- if (outName.match(/.d.ts/g)) {
1404
- this.files.commonjsTypes = outName.replace(/.d.ts/g, ".d.cts");
1405
- }
1406
- if (isMain && (format === "both" || format === "commonjs")) {
1407
- if (this.files.commonjs)
1408
- this.files.main = this.files.commonjs;
1409
- if (this.files.commonjsTypes)
1410
- this.files.types = this.files.commonjsTypes;
1411
- }
1412
- }
1413
- outName = outName.replace(/.js/g, ".cjs");
1414
- outName = outName.replace(/.map.js/g, ".map.cjs");
1415
- outName = outName.replace(/.d.ts/g, ".d.cts");
1416
- await utilities.wait(500);
1417
- if (format === "commonjs") {
1418
- await utilities.clearFolder(path.dirname(outName));
1419
- }
1420
- await utilities.writeCompileFile(outName, content);
1421
- });
1422
- console.timeEnd(tcolor.cyan(`Compiled commonjs for ${_name} export path`));
1423
- }
1424
- async _esm(point) {
1425
- const isMain = point.exportPath === ".";
1426
- const _name = isMain ? "Main" : splitCamelCase(point.exportPath.slice(2));
1427
- console.time(tcolor.cyan(`Compiled esm for ${_name} export path`));
1428
- // init
1429
- const fileName = point.fileName;
1430
- const sourceCode = point.bundledContent;
1431
- const format = point.format;
1432
- const plugins = point.plugins;
1433
- const compilerOptions = point.tsOptions.esm;
1434
- // create host
1435
- const _host = createHost(sourceCode, fileName);
1436
- const createdFiles = _host.createdFiles;
1437
- const host = _host.host;
1438
- const program = ts.createProgram([fileName], compilerOptions, host);
1439
- program.emit();
1440
- Object.entries(createdFiles).map(async ([outName, content]) => {
1441
- if (plugins.length) {
1442
- for (let plugin of plugins) {
1443
- plugin = typeof plugin === "function" ? plugin() : plugin;
1444
- if (plugin.type === "post-process") {
1445
- if (plugin.async) {
1446
- content = await plugin.func(content, outName);
1447
- }
1448
- else {
1449
- content = plugin.func(content, outName);
1450
- }
1451
- }
1452
- }
1453
- }
1454
- // ------------------------------------------
1455
- if (this._isUpdate()) {
1456
- if (outName.match(/.js/g)) {
1457
- this.files.esm = outName.replace(/.js/g, ".mjs");
1458
- }
1459
- if (outName.match(/.d.ts/g)) {
1460
- this.files.esmTypes = outName.replace(/.d.ts/g, ".d.mts");
1461
- }
1462
- if (isMain && format === "both" && this.files.esm) {
1463
- this.files.module = this.files.esm;
1464
- }
1465
- }
1466
- outName = outName.replace(/.js/g, ".mjs");
1467
- outName = outName.replace(/.map.js/g, ".map.mjs");
1468
- outName = outName.replace(/.d.ts/g, ".d.mts");
1469
- await utilities.wait(500);
1470
- if (format !== "commonjs") {
1471
- await utilities.clearFolder(path.dirname(outName));
1472
- }
1473
- await utilities.writeCompileFile(outName, content);
1474
- });
1475
- console.timeEnd(tcolor.cyan(`Compiled esm for ${_name} export path`));
1476
- }
1477
- /**
1478
- * Compile bundled code for each entry point.
1479
- * This function will iterate through each entry point and compile code according to the format specified.
1480
- * If the format is "commonjs", it will compile the code into commonjs format.
1481
- * If the format is "esm", it will compile the code into esm format.
1482
- * If the format is "both", it will compile the code into both commonjs and esm formats.
1483
- * If the allowUpdatePackageJson flag is set to true, it will update the package.json according to the compiled file paths.
1484
- */
1485
- async compile() {
1486
- for (const point of this.object.points) {
1487
- await utilities.wait(500);
1488
- switch (point.format) {
1489
- case "commonjs":
1490
- await this._commonjs(point);
1491
- if (this._isUpdate()) {
1492
- await writePackage(this.files, point.exportPath);
1493
- }
1494
- break;
1495
- case "esm":
1496
- await this._esm(point);
1497
- if (this._isUpdate()) {
1498
- await writePackage(this.files, point.exportPath);
1499
- }
1500
- break;
1501
- case "both":
1502
- await this._esm(point);
1503
- await utilities.wait(1000);
1504
- await this._commonjs(point);
1505
- if (this._isUpdate()) {
1506
- await writePackage(this.files, point.exportPath);
1507
- }
1508
- break;
1509
- }
1510
- await utilities.wait(500);
1511
- }
1512
- }
1513
- }
1514
- //src/lib/init/checks.ts
1515
- var checks;
1516
- (function (checks) {
1517
- /**
1518
- * Checks the given dependencies for type errors. If any type errors are found,
1519
- * an error message is printed to the console and the process exits with a code of 1.
1520
- * @param dep The dependencies to check for type errors
1521
- * @param compilerOptions The compiler options to use when checking for type errors
1522
- * @returns true if no type errors are found, false otherwise
1523
- */
1524
- function typesCheck(dep, compilerOptions) {
1525
- if (!compilerOptions.noCheck) {
1526
- const filePaths = dep.map((i) => i.file);
1527
- let _err = false;
1528
- // Create program
1529
- const program = ts.createProgram(filePaths, compilerOptions);
1530
- // Check each file individually for immediate feedback
1531
- for (const filePath of filePaths) {
1532
- const sourceFile = program.getSourceFile(filePath);
1533
- if (!sourceFile) {
1534
- console.error(tcolor.magenta(`File not found: ${filePath}`));
1535
- ts.sys.exit(1);
1536
- }
1537
- const diagnostics = [
1538
- ...program.getSyntacticDiagnostics(sourceFile),
1539
- ...program.getSemanticDiagnostics(sourceFile),
1540
- ...program.getDeclarationDiagnostics(sourceFile),
1541
- ];
1542
- if (diagnostics.length > 0) {
1543
- const formatHost = {
1544
- getCurrentDirectory: () => process.cwd(),
1545
- getCanonicalFileName: (fileName) => fileName,
1546
- getNewLine: () => ts.sys.newLine,
1547
- };
1548
- console.error(ts.formatDiagnosticsWithColorAndContext(diagnostics, formatHost));
1549
- _err = true;
1550
- }
1551
- }
1552
- if (_err) {
1553
- ts.sys.exit(1);
1554
- }
1555
- else {
1556
- return true;
1557
- }
1558
- }
1559
- }
1560
- /**
1561
- * Check the module type of the given dependencies.
1562
- * @param _dep The dependencies to check for module type
1563
- * @returns true if all dependencies are ESM, false otherwise
1564
- */
1565
- function moduleType(_dep) {
1566
- let _esmCount = 0;
1567
- let cjsCount = 0;
1568
- let unknownCount = 0;
1569
- for (const dep of _dep) {
1570
- try {
1571
- // Create a TypeScript source file
1572
- const sourceFile = ts.createSourceFile(dep.file, dep.content, ts.ScriptTarget.Latest, true);
1573
- let hasESMImports = false;
1574
- let hasCommonJS = false;
1575
- // Walk through the AST to detect module syntax
1576
- function walk(node) {
1577
- // Check for ESM import/export syntax
1578
- if (ts.isImportDeclaration(node) ||
1579
- ts.isImportEqualsDeclaration(node) ||
1580
- ts.isExportDeclaration(node) ||
1581
- ts.isExportSpecifier(node) ||
1582
- ts.isExportAssignment(node)) {
1583
- hasESMImports = true;
1584
- }
1585
- // Check for export modifier on declarations
1586
- if ((ts.isVariableStatement(node) ||
1587
- ts.isFunctionDeclaration(node) ||
1588
- ts.isInterfaceDeclaration(node) ||
1589
- ts.isTypeAliasDeclaration(node) ||
1590
- ts.isEnumDeclaration(node) ||
1591
- ts.isClassDeclaration(node)) &&
1592
- node.modifiers?.some((mod) => mod.kind === ts.SyntaxKind.ExportKeyword)) {
1593
- hasESMImports = true;
1594
- }
1595
- // Check for CommonJS require/exports
1596
- if (ts.isCallExpression(node)) {
1597
- if (ts.isIdentifier(node.expression) &&
1598
- node.expression.text === "require" &&
1599
- node.arguments.length > 0) {
1600
- hasCommonJS = true;
1601
- }
1602
- }
1603
- // Check for module.exports or exports.xxx
1604
- if (ts.isPropertyAccessExpression(node)) {
1605
- const text = node.getText(sourceFile);
1606
- if (text.startsWith("module.exports") ||
1607
- text.startsWith("exports.")) {
1608
- hasCommonJS = true;
1609
- }
1610
- }
1611
- // Continue walking the AST
1612
- ts.forEachChild(node, walk);
1613
- }
1614
- walk(sourceFile);
1615
- // Determine the module format based on what we found
1616
- if (hasESMImports && !hasCommonJS) {
1617
- _esmCount++;
1618
- }
1619
- else if (hasCommonJS && !hasESMImports) {
1620
- cjsCount++;
1621
- }
1622
- else if (hasESMImports && hasCommonJS) {
1623
- // Mixed - probably ESM with dynamic imports or similar
1624
- _esmCount++;
1625
- }
1626
- }
1627
- catch (error) {
1628
- console.error(tcolor.magenta(`Error checking module format for ${dep.file} : \n ${error}`));
1629
- unknownCount++;
1630
- }
1631
- }
1632
- if (unknownCount) {
1633
- console.error(tcolor.magenta("Unknown error when checking module types in the dependencies tree."));
1634
- ts.sys.exit(1);
1635
- }
1636
- if (cjsCount) {
1637
- console.error(tcolor.magenta("The package detects CommonJs format in the dependencies tree, that unsupported."));
1638
- ts.sys.exit(1);
1639
- }
1640
- return true;
1641
- }
1642
- function ext(_dep) {
1643
- const tsExt = new Set([".ts", ".mts", ".cts", ".tsx"]);
1644
- for (const dep of _dep) {
1645
- const ext = path.extname(dep.file);
1646
- if (!tsExt.has(ext)) {
1647
- console.error(tcolor.magenta(`${dep.file} has no valid TypeScript extension`));
1648
- ts.sys.exit(1);
1649
- }
1650
- }
1651
- return true;
1652
- }
1653
- async function init(_dep, options) {
1654
- const res = resolves([
1655
- [ext, _dep],
1656
- [moduleType, _dep],
1657
- [typesCheck, _dep, options],
1658
- ]);
1659
- const results = await res.concurrent();
1660
- return results.every((r) => r === true);
1661
- }
1662
- checks.init = init;
1663
- })(checks || (checks = {}));
1664
- //src/lib/init/config.ts
1665
- // -------------
1666
- const getConfigPath = () => {
1667
- const fileNames = ["susee.config.ts", "susee.config.js", "susee.config.mjs"];
1668
- let configFile;
1669
- for (const file of fileNames) {
1670
- const _file = ts.sys.resolvePath(file);
1671
- if (ts.sys.fileExists(_file)) {
1672
- configFile = _file;
1673
- break;
1674
- }
1675
- }
1676
- return configFile;
1677
- };
1678
- //---------
1679
- function checkEntries(entries) {
1680
- if (entries.length < 1) {
1681
- console.error(tcolor.magenta(`No entry found in susee.config file, at least one entry required`));
1682
- ts.sys.exit(1);
1683
- }
1684
- const objectStore = {};
1685
- const duplicateExportPaths = [];
1686
- for (const obj of entries) {
1687
- const value = obj.exportPath;
1688
- if (objectStore[value]) {
1689
- duplicateExportPaths.push(`"${value}"`);
1690
- }
1691
- else {
1692
- objectStore[value] = true;
1693
- }
1694
- }
1695
- if (duplicateExportPaths.length > 0) {
1696
- console.error(tcolor.magenta(`Duplicate export paths/path (${duplicateExportPaths.join(",")}) found in your susee.config file , that will error for bundled output`));
1697
- ts.sys.exit(1);
1698
- }
1699
- for (const obj of entries) {
1700
- if (!ts.sys.fileExists(ts.sys.resolvePath(obj.entry))) {
1701
- console.error(tcolor.magenta(`Entry file ${obj.entry} dose not exists.`));
1702
- ts.sys.exit(1);
1703
- }
1704
- }
1705
- }
1706
- /**
1707
- * Get SuSee configuration from susee.config file (susee.config.ts, susee.config.js, susee.config.mjs)
1708
- * @returns {Promise<ConfigReturns>} - SuSee configuration
1709
- * @throws {Error} - when no susee.config file found
1710
- */
1711
- async function getConfig() {
1712
- const configPath = getConfigPath();
1713
- if (configPath === undefined) {
1714
- console.error(tcolor.magenta(`No susee.config file ("susee.config.ts", "susee.config.js", "susee.config.mjs") found`));
1715
- ts.sys.exit(1);
1716
- }
1717
- const _default = await import(configPath);
1718
- const config = _default.default;
1719
- const entryCheck = resolves([[checkEntries, config.entryPoints]]);
1720
- await entryCheck.series();
1721
- await utilities.wait(1000);
1722
- const points = [];
1723
- for (const ent of config.entryPoints) {
1724
- const point = {
1725
- entry: ent.entry,
1726
- exportPath: ent.exportPath,
1727
- format: ent.format ?? "esm",
1728
- tsconfigFilePath: ent.tsconfigFilePath ?? undefined,
1729
- renameDuplicates: ent.renameDuplicates ?? true,
1730
- // TODO check for defined out dir here or in config.ts
1731
- outDir: config.outDir ?? "dist",
1732
- };
1733
- points.push(point);
1734
- }
1735
- return {
1736
- points,
1737
- plugins: config.plugins ?? [],
1738
- allowUpdatePackageJson: config.allowUpdatePackageJson ?? true,
1739
- };
1740
- }
1741
- //src/lib/init/deps.ts
1742
- //---------------
1743
- async function fileSizes(path) {
1744
- const s = await fs.promises.stat(path);
1745
- const logical = s.size; // bytes in file
1746
- const allocated = s.blocks !== null ? s.blocks * 512 : null; // bytes actually allocated (POSIX)
1747
- return { logical, allocated };
1748
- }
1749
- const checkExport = (str, file) => {
1750
- const esmRex = /export default .*/gm;
1751
- const cjsRex = /export = .*/gm;
1752
- const ctsRex = /.cts/g;
1753
- if (str.match(esmRex) || (str.match(cjsRex) && file.match(ctsRex))) {
1754
- return true;
1755
- }
1756
- else {
1757
- return false;
1758
- }
1759
- };
1760
- /**
1761
- * Generate dependencies graph for given entry file.
1762
- *
1763
- * This function will return an array of dependencies file objects.
1764
- * Each object will contain the following properties:
1765
- * - file: path to the file
1766
- * - content: content of the file
1767
- * - length: length of the content in bytes
1768
- * - includeDefExport: whether the file includes export default or export = statement
1769
- * - size: an object containing the following properties:
1770
- * - logical: size of the file in bytes
1771
- * - allocated: size of the file in bytes on disk
1772
- * - utf8: size of the file in bytes when encoded in utf8
1773
- * - buffBytes: size of the file in bytes when encoded in buffer
1774
- *
1775
- * @param {string} entryFile - path to the entry file
1776
- * @param {SuseePlugins} plugins - array of plugins
1777
- * @returns {Promise<DepsFiles>}
1778
- */
1779
- async function generateDependencies(entryFile, plugins) {
1780
- const deps = await dependencies(entryFile);
1781
- const sorted = deps.sort(); // get dependencies graph
1782
- let depsFiles = [];
1783
- await utilities.wait(1000);
1784
- for (const dep of sorted) {
1785
- const file = ts.sys.resolvePath(dep);
1786
- const content = await fs.promises.readFile(file, "utf8");
1787
- const s = await fileSizes(file);
1788
- const length = content.length;
1789
- const includeDefExport = checkExport(content, file);
1790
- const _files = {
1791
- file,
1792
- content,
1793
- length,
1794
- includeDefExport,
1795
- size: {
1796
- logical: s.logical,
1797
- allocated: s.allocated,
1798
- utf8: new TextEncoder().encode(content).length,
1799
- buffBytes: Buffer.byteLength(content, "utf8"),
1800
- },
1801
- };
1802
- depsFiles.push(_files);
1803
- }
1804
- // call dependency plugins
1805
- if (plugins.length) {
1806
- for (const plugin of plugins) {
1807
- const _plug = typeof plugin === "function" ? plugin() : plugin;
1808
- if (_plug.type === "dependency") {
1809
- if (_plug.async) {
1810
- depsFiles = await _plug.func(depsFiles);
1811
- }
1812
- else {
1813
- depsFiles = _plug.func(depsFiles);
1814
- }
1815
- await utilities.wait(1000);
1816
- }
1817
- }
1818
- }
1819
- return depsFiles;
1820
- }
1821
- //src/lib/init/tsCompilerOptions.ts
1822
- class GetOptions {
1823
- constructor(point) {
1824
- this._point = point;
1825
- this._options = {};
1826
- }
1827
- __init() {
1828
- const __opts = new TsConfig(this._point.tsconfigFilePath);
1829
- const __outDir = this._point.exportPath === "."
1830
- ? this._point.outDir
1831
- : `${this._point.outDir}/${this._point.exportPath.slice(2)}`;
1832
- __opts.removeCompilerOption("rootDir");
1833
- __opts.removeCompilerOption("module");
1834
- __opts.editCompilerOptions({
1835
- moduleResolution: ts.ModuleResolutionKind.NodeNext,
1836
- outDir: __outDir,
1837
- });
1838
- this._options = __opts.getCompilerOptions();
1839
- }
1840
- __init2() {
1841
- this.__init();
1842
- let { types, lib, ...restOptions } = this._options;
1843
- // normalize types into an array
1844
- if (types) {
1845
- if (!types.includes("node")) {
1846
- types = ["node", ...types];
1847
- }
1848
- }
1849
- else {
1850
- types = ["node"];
1851
- }
1852
- if (lib) {
1853
- lib = [...new Set(["ESNext", ...lib])];
1854
- }
1855
- else {
1856
- lib = ["ESNext"];
1857
- }
1858
- return { types, lib, ...restOptions };
1859
- }
1860
- get commonjs() {
1861
- const opts = this.__init2();
1862
- const { module, ...rest } = opts;
1863
- return { module: ts.ModuleKind.CommonJS, ...rest };
1864
- }
1865
- get esm() {
1866
- const opts = this.__init2();
1867
- const { module, ...rest } = opts;
1868
- return { module: ts.ModuleKind.ES2020, ...rest };
1869
- }
1870
- get default() {
1871
- return this.__init2();
1872
- }
1873
- }
1874
- /**
1875
- * Returns an instance of GetOptions, which provides various methods
1876
- * to generate different sets of compiler options based on the
1877
- * given Point.
1878
- *
1879
- * @param {Point} point - The point to generate compiler options for.
1880
- * @returns {GetOptions}
1881
- */
1882
- function getOptions(point) {
1883
- return new GetOptions(point);
1884
- }
1885
- //src/lib/init/index.ts
1886
- /**
1887
- * This function takes a susee configuration object and returns a promise that resolves with a `CollatedReturn` object.
1888
- * The function iterates over the `points` array in the susee configuration object.
1889
- * For each point, it generates the dependencies using the `generateDependencies` function.
1890
- * It then checks if the dependencies are valid using the `checks.init` function.
1891
- * If the dependencies are invalid, it exits the process with code 1.
1892
- * If the dependencies are valid, it constructs a `CollatedPoint` object and adds it to the result array.
1893
- * Finally, it returns a `CollatedReturn` object with the result array and the `allowUpdatePackageJson` flag.
1894
- */
1895
- async function collections() {
1896
- const __config = await getConfig();
1897
- const points = __config.points;
1898
- const result = [];
1899
- for (const point of points) {
1900
- const __opts = getOptions(point);
1901
- const __deps = await generateDependencies(point.entry, __config.plugins);
1902
- const checked = await checks.init(__deps, __opts.esm);
1903
- if (!checked) {
1904
- ts.sys.exit(1);
1905
- }
1906
- const c = {
1907
- fileName: point.entry,
1908
- exportPath: point.exportPath,
1909
- format: point.format,
1910
- rename: point.renameDuplicates,
1911
- outDir: point.outDir,
1912
- tsOptions: {
1913
- cjs: __opts.commonjs,
1914
- esm: __opts.esm,
1915
- default: __opts.default,
1916
- },
1917
- depFiles: __deps,
1918
- plugins: __config.plugins,
1919
- };
1920
- result.push(c);
1921
- }
1922
- return {
1923
- points: result,
1924
- allowUpdatePackageJson: __config.allowUpdatePackageJson,
1925
- };
1926
- }
1927
- //src/index.ts
1928
- /**
1929
- * Bundles a TypeScript project into a single file.
1930
- * The function takes a {@link SuSeeConfig} object as input and returns a promise resolves with a bundled result.
1931
- * The function applies the following steps:
1932
- * 1. Call dependency plugins.
1933
- * 2. Handle duplicates.
1934
- * 3. Handling anonymous imports and exports.
1935
- * 4. Remove Imports.
1936
- * 5. Remove Exports from dependencies only.
1937
- * 6. Handle imported statements.
1938
- * 7. Create final content.
1939
- * 8. Call pre-process plugins.
1940
- * 9. Returns.
1941
- */
1942
- async function susee() {
1943
- console.info(`${tcolor.green("Start")} : ${tcolor.cyan("bundling")}`);
1944
- const collected = await collections();
1945
- await utilities.wait(1000);
1946
- const bundled = await bundle(collected);
1947
- await utilities.wait(1000);
1948
- const compiler = new Compiler(bundled);
1949
- await compiler.compile();
1950
- console.info(`${tcolor.green("End")} : ${tcolor.cyan("bundling")}`);
1951
- }
1952
- export { susee };
1953
- //# sourceMappingURL=index.js.map
8
+ import TsConfig from"@suseejs/tsconfig";import dependencies from"@suseejs/dependencies";import fs from"node:fs";import path from"node:path";import resolves from"@phothinmaung/resolves";import tcolor from"@suseejs/tcolor";import transformFunction from"@suseejs/transformer";import ts from"typescript";import utilities from"@suseejs/utils";import{Buffer}from"node:buffer";function splitCamelCase(e){return e.replace(/([a-z])([A-Z])/g,"$1 $2").replace(/(_|-|\/)([a-z] || [A-Z])/g," ").replace(/([A-Z])/g,e=>e.toLowerCase()).replace(/^([a-z])/,e=>e.toUpperCase())}function uniqueName(){const e=new Map,t={setPrefix({key:s,value:i}){if(e.has(s))throw console.warn(`${s} already exist`),new Error;return e.set(s,[i,0]),t},getName(t,s){const[i,n]=e.get(t)||[],a=i?`${i}${s}_${(n??0)+1}`:`$nyein${s}_${(n??0)+1}`;return e.set(t,[i??"$nyein",(n??0)+1]),a},getPrefix(t){const[s]=e.get(t)||[];return s}};return t}const exportDefaultExportNameMap=[],exportDefaultImportNameMap=[],prefixKey="AnonymousName",genName=uniqueName().setPrefix({key:prefixKey,value:"__anonymous__"});function anonymousCallExpressionHandler(e){return({file:t,content:s,...i})=>{const n=ts.createSourceFile(t,s,ts.ScriptTarget.Latest,!0),a=transformFunction(e=>{const{factory:s}=e,i=n=>{if(ts.isCallExpression(n)){if(ts.isIdentifier(n.expression)){const e=n.expression.text,i=exportDefaultImportNameMap.find(s=>s.base===e&&s.file===t);if(i)return s.updateCallExpression(n,s.createIdentifier(i.newName),n.typeArguments,n.arguments)}}else if(ts.isPropertyAccessExpression(n)){if(ts.isIdentifier(n.expression)){const e=n.expression.text,i=exportDefaultImportNameMap.find(s=>s.base===e&&s.file===t);if(i)return s.updatePropertyAccessExpression(n,s.createIdentifier(i.newName),n.name)}}else if(ts.isNewExpression(n)){if(ts.isIdentifier(n.expression)){const e=n.expression.text,i=exportDefaultImportNameMap.find(s=>s.base===e&&s.file===t);if(i)return s.updateNewExpression(n,s.createIdentifier(i.newName),n.typeArguments,n.arguments)}}else if(ts.isExportSpecifier(n)&&ts.isIdentifier(n.name)){const e=n.name.text,i=exportDefaultImportNameMap.find(s=>s.base===e&&s.file===t);if(i)return s.updateExportSpecifier(n,n.isTypeOnly,n.propertyName,s.createIdentifier(i.newName))}return ts.visitEachChild(n,i,e)};return e=>ts.visitNode(e,i)},n,e);return{file:t,content:a,...i}}}function anonymousExportHandler(e){return({file:t,content:s,...i})=>{const n=ts.createSourceFile(t,s,ts.ScriptTarget.Latest,!0),a=transformFunction(e=>{const{factory:s}=e,i=a=>{const r=path.basename(t).split(".")[0];if((ts.isFunctionDeclaration(a)||ts.isClassDeclaration(a))&&void 0===a.name){let e=!1,t=!1;if(a.modifiers?.forEach(s=>{s.kind===ts.SyntaxKind.ExportKeyword&&(e=!0),s.kind===ts.SyntaxKind.DefaultKeyword&&(t=!0)}),e&&t){const e=genName.getName(prefixKey,r);if(exportDefaultExportNameMap.push({base:e,file:r,newName:e,isEd:!0}),ts.isFunctionDeclaration(a))return s.updateFunctionDeclaration(a,a.modifiers,a.asteriskToken,s.createIdentifier(e),a.typeParameters,a.parameters,a.type,a.body);if(ts.isClassDeclaration(a))return s.updateClassDeclaration(a,a.modifiers,s.createIdentifier(e),a.typeParameters,a.heritageClauses,a.members)}}else if(ts.isExportAssignment(a)&&!a.name&&!a.isExportEquals){if(ts.isArrowFunction(a.expression)){const e=genName.getName(prefixKey,r),t=s.createArrowFunction(a.expression.modifiers,a.expression.typeParameters,a.expression.parameters,a.expression.type,a.expression.equalsGreaterThanToken,a.expression.body),i=s.createVariableDeclaration(s.createIdentifier(e),a.expression.exclamationToken,a.expression.type,t),o=s.createVariableDeclarationList([i],ts.NodeFlags.Const),c=s.createVariableStatement(a.expression.modifiers,o),l=s.createExportAssignment(void 0,void 0,s.createIdentifier(e));return exportDefaultExportNameMap.push({base:e,file:r,newName:e,isEd:!0}),s.updateSourceFile(n,[c,l],n.isDeclarationFile,n.referencedFiles,n.typeReferenceDirectives,n.hasNoDefaultLib,n.libReferenceDirectives)}if(ts.isObjectLiteralExpression(a.expression)){const e=genName.getName(prefixKey,r),t=s.createVariableDeclaration(s.createIdentifier(e),void 0,void 0,a.expression),i=s.createVariableDeclarationList([t],ts.NodeFlags.Const),o=s.createVariableStatement(void 0,i),c=s.createExportAssignment(void 0,void 0,s.createIdentifier(e));return exportDefaultExportNameMap.push({base:e,file:r,newName:e,isEd:!0}),s.updateSourceFile(n,[o,c],n.isDeclarationFile,n.referencedFiles,n.typeReferenceDirectives,n.hasNoDefaultLib,n.libReferenceDirectives)}if(ts.isArrayLiteralExpression(a.expression)){const e=genName.getName(prefixKey,r),t=s.createArrayLiteralExpression(a.expression.elements,!0),i=s.createVariableDeclaration(s.createIdentifier(e),void 0,void 0,t),o=s.createVariableDeclarationList([i],ts.NodeFlags.Const),c=s.createVariableStatement(void 0,o),l=s.createExportAssignment(void 0,void 0,s.createIdentifier(e));return exportDefaultExportNameMap.push({base:e,file:r,newName:e,isEd:!0}),s.updateSourceFile(n,[c,l],n.isDeclarationFile,n.referencedFiles,n.typeReferenceDirectives,n.hasNoDefaultLib,n.libReferenceDirectives)}if(ts.isStringLiteral(a.expression)){const e=genName.getName(prefixKey,r),t=s.createStringLiteral(a.expression.text),i=s.createVariableDeclaration(s.createIdentifier(e),void 0,void 0,t),o=s.createVariableDeclarationList([i],ts.NodeFlags.Const),c=s.createVariableStatement(void 0,o),l=s.createExportAssignment(void 0,void 0,s.createIdentifier(e));return exportDefaultExportNameMap.push({base:e,file:r,newName:e,isEd:!0}),s.updateSourceFile(n,[c,l],n.isDeclarationFile,n.referencedFiles,n.typeReferenceDirectives,n.hasNoDefaultLib,n.libReferenceDirectives)}if(ts.isNumericLiteral(a.expression)){const e=genName.getName(prefixKey,r),t=s.createNumericLiteral(a.expression.text),i=s.createVariableDeclaration(s.createIdentifier(e),void 0,void 0,t),o=s.createVariableDeclarationList([i],ts.NodeFlags.Const),c=s.createVariableStatement(void 0,o),l=s.createExportAssignment(void 0,void 0,s.createIdentifier(e));return exportDefaultExportNameMap.push({base:e,file:r,newName:e,isEd:!0}),s.updateSourceFile(n,[c,l],n.isDeclarationFile,n.referencedFiles,n.typeReferenceDirectives,n.hasNoDefaultLib,n.libReferenceDirectives)}}return ts.visitEachChild(a,i,e)};return e=>ts.visitNode(e,i)},n,e);return{file:t,content:a,...i}}}function anonymousImportHandler(e){return({file:t,content:s,...i})=>{const n=ts.createSourceFile(t,s,ts.ScriptTarget.Latest,!0),a=transformFunction(e=>{const{factory:s}=e,i=a=>{if(ts.isImportDeclaration(a)){const e=a.moduleSpecifier.getText(n),i=path.basename(e).split(".")[0].trim();if(a.importClause?.name&&ts.isIdentifier(a.importClause.name)){const e=a.importClause.name.text.trim(),n=exportDefaultExportNameMap.find(e=>e.file===i);if(n){exportDefaultImportNameMap.push({base:e,file:t,newName:n.newName,isEd:!0});const i=s.updateImportClause(a.importClause,a.importClause.phaseModifier,s.createIdentifier(n.newName),a.importClause.namedBindings);return s.updateImportDeclaration(a,a.modifiers,i,a.moduleSpecifier,a.attributes)}}}return ts.visitEachChild(a,i,e)};return e=>ts.visitNode(e,i)},n,e);return{file:t,content:a,...i}}}const anonymousHandler=async(e,t)=>{const s=resolves([[anonymousExportHandler,t],[anonymousImportHandler,t],[anonymousCallExpressionHandler,t]]),i=await s.concurrent();for(const t of i)e=e.map(t);return e},namesMap=new Map,callNameMap=[],importNameMap=[],exportNameMap=[];function __uniqueName(){const e=new Map;return{setPrefix({key:t,value:s}){const i=[];let n;if(e.has(t))throw console.warn(`${t} already exist`),new Error;return n=s,e.set(t,s),{getName:function(e){const t=i.length,s=n?`${n}${e}_${t+1}`:`$nyein${e}_${t+1}`;return i.push(s),s}}},getPrefix(t){if(e.has(t))return e.get(t)}}}const dupName=__uniqueName().setPrefix({key:"DuplicatesNames",value:"__duplicatesNames__"}),normalizePathKey=e=>{const t=path.parse(e);let s=path.join(t.dir,t.name);return"index"===t.name&&(s=t.dir),path.normalize(s)},getFileKey=e=>normalizePathKey(e),getModuleKeyFromSpecifier=(e,t,s)=>{let i="";if(i=ts.isStringLiteral(e)?e.text:e.getText(t).replace(/^['"]|['"]$/g,""),i.startsWith(".")||i.startsWith("/")){const e=path.dirname(s);return normalizePathKey(path.resolve(e,i))}return i},callExpression=e=>({file:t,content:s,...i})=>{const n=ts.createSourceFile(t,s,ts.ScriptTarget.Latest,!0),a=transformFunction(e=>{const{factory:s}=e,i=n=>{if(ts.isCallExpression(n)){if(ts.isIdentifier(n.expression)){const e=n.expression.text;let i=null;const a=callNameMap.find(s=>s.base===e&&s.file===t),r=importNameMap.find(s=>s.base===e&&s.file===t);if(a?i=a.newName:r&&(i=r.newName),i)return s.updateCallExpression(n,s.createIdentifier(i),n.typeArguments,n.arguments)}}else if(ts.isPropertyAccessExpression(n)){if(ts.isIdentifier(n.expression)){const e=n.expression.text;let i=null;const a=callNameMap.find(s=>s.base===e&&s.file===t),r=importNameMap.find(s=>s.base===e&&s.file===t);if(a?i=a.newName:r&&(i=r.newName),i)return s.updatePropertyAccessExpression(n,s.createIdentifier(i),n.name)}}else if(ts.isNewExpression(n)&&ts.isIdentifier(n.expression)){const e=n.expression.text;let i=null;const a=callNameMap.find(s=>s.base===e&&s.file===t),r=importNameMap.find(s=>s.base===e&&s.file===t);if(a?i=a.newName:r&&(i=r.newName),i)return s.updateNewExpression(n,s.createIdentifier(i),n.typeArguments,n.arguments)}return ts.visitEachChild(n,i,e)};return e=>ts.visitNode(e,i)},n,e);return{file:t,content:a,...i}},exportExpression=e=>({file:t,content:s,...i})=>{const n=ts.createSourceFile(t,s,ts.ScriptTarget.Latest,!0),a=transformFunction(e=>{const{factory:s}=e,i=n=>{if(ts.isExportSpecifier(n)){if(ts.isIdentifier(n.name)){const e=n.name.text;let i=null;const a=callNameMap.find(s=>s.base===e&&s.file===t),r=importNameMap.find(s=>s.base===e&&s.file===t);if(a?(exportNameMap.push({base:e,file:getFileKey(t),newName:a.newName}),i=a.newName):r&&(i=r.newName),i)return s.updateExportSpecifier(n,n.isTypeOnly,n.propertyName,s.createIdentifier(i))}}else if(ts.isExportAssignment(n)){const e=n.expression;if(ts.isIdentifier(e)){const i=e.text;let a=null;const r=callNameMap.find(e=>e.base===i&&e.file===t),o=importNameMap.find(e=>e.base===i&&e.file===t);if(r?(exportNameMap.push({base:i,file:getFileKey(t),newName:r.newName}),a=r.newName):o&&(a=o.newName),a)return s.updateExportAssignment(n,n.modifiers,s.createIdentifier(a))}}return ts.visitEachChild(n,i,e)};return e=>ts.visitNode(e,i)},n,e);return{file:t,content:a,...i}},importExpression=e=>({file:t,content:s,...i})=>{const n=ts.createSourceFile(t,s,ts.ScriptTarget.Latest,!0),a=transformFunction(e=>{const{factory:s}=e,i=a=>{if(ts.isImportDeclaration(a)){const e=getModuleKeyFromSpecifier(a.moduleSpecifier,n,t);let i=[];if(a.importClause?.namedBindings&&ts.isNamedImports(a.importClause.namedBindings)&&(i=a.importClause.namedBindings.elements.map(e=>e.name.text.trim())),a.importClause?.name&&ts.isIdentifier(a.importClause.name)){const i=a.importClause.name.text.trim(),n=exportNameMap.find(t=>t.base===i&&t.file===e);if(n){importNameMap.push({base:n.base,file:t,newName:n.newName});const e=s.updateImportClause(a.importClause,a.importClause.phaseModifier,s.createIdentifier(n.newName),a.importClause.namedBindings);return s.updateImportDeclaration(a,a.modifiers,e,a.moduleSpecifier,a.attributes)}}if(i.length>0&&a.importClause&&a.importClause.namedBindings&&ts.isNamedImports(a.importClause.namedBindings)){const i=a.importClause.namedBindings.elements.map(i=>{const n=exportNameMap.find(t=>t.base===i.name.text.trim()&&t.file===e);return n?(importNameMap.push({base:n.base,file:t,newName:n.newName}),s.updateImportSpecifier(i,i.isTypeOnly,i.propertyName,s.createIdentifier(n.newName))):i}),n=s.updateNamedImports(a.importClause.namedBindings,i),r=s.updateImportClause(a.importClause,a.importClause.phaseModifier,a.importClause.name,n);return s.updateImportDeclaration(a,a.modifiers,r,a.moduleSpecifier,a.attributes)}}return ts.visitEachChild(a,i,e)};return e=>ts.visitNode(e,i)},n,e);return{file:t,content:a,...i}},collector=e=>({file:t,content:s,...i})=>{const n=ts.createSourceFile(t,s,ts.ScriptTarget.Latest,!0),a=transformFunction(e=>{function s(i,n=!0){if(n)if(ts.isVariableStatement(i))i.declarationList.declarations.forEach(e=>{if(ts.isIdentifier(e.name)){const s=e.name.text;namesMap.has(s)?namesMap.get(s).add({file:t}):namesMap.set(s,new Set([{file:t}]))}});else if(ts.isFunctionDeclaration(i)||ts.isClassDeclaration(i)||ts.isEnumDeclaration(i)||ts.isInterfaceDeclaration(i)||ts.isTypeAliasDeclaration(i)){const e=i.name?.text;e&&(namesMap.has(e)?namesMap.get(e).add({file:t}):namesMap.set(e,new Set([{file:t}])))}return ts.isBlock(i)||ts.isFunctionDeclaration(i)||ts.isFunctionExpression(i)||ts.isArrowFunction(i)||ts.isMethodDeclaration(i)||ts.isClassDeclaration(i)?(ts.isBlock(i)?ts.visitNodes(i.statements,e=>s(e,!1)):ts.forEachChild(i,e=>{s(e,!1)}),i):ts.visitEachChild(i,e=>s(e,n),e)}return e=>s(e,!0)},n,e);return{file:t,content:a,...i}},updater=e=>({file:t,content:s,...i})=>{const n=ts.createSourceFile(t,s,ts.ScriptTarget.Latest,!0),a=transformFunction(e=>{const{factory:s}=e,i=n=>{if(ts.isVariableStatement(n)){const e=n.declarationList.declarations.map(e=>{if(ts.isIdentifier(e.name)){const i=e.name.text;if(namesMap.has(i)&&namesMap.get(i).size>1){const n=dupName.getName(i);return callNameMap.push({base:i,file:t,newName:n}),s.updateVariableDeclaration(e,s.createIdentifier(n),e.exclamationToken,e.type,e.initializer)}}return e}),i=s.updateVariableDeclarationList(n.declarationList,e);return s.updateVariableStatement(n,n.modifiers,i)}if(ts.isFunctionDeclaration(n)){if(n.name&&ts.isIdentifier(n.name)){const e=n.name.text;if(namesMap.has(e)&&namesMap.get(e).size>1){const i=dupName.getName(e);return callNameMap.push({base:e,file:t,newName:i}),s.updateFunctionDeclaration(n,n.modifiers,n.asteriskToken,s.createIdentifier(i),n.typeParameters,n.parameters,n.type,n.body)}}}else if(ts.isClassDeclaration(n)&&n.name&&ts.isIdentifier(n.name)){const e=n.name.text;if(namesMap.has(e)&&namesMap.get(e).size>1){const i=dupName.getName(e);return callNameMap.push({base:e,file:t,newName:i}),s.updateClassDeclaration(n,n.modifiers,s.createIdentifier(i),n.typeParameters,n.heritageClauses,n.members)}}return ts.visitEachChild(n,i,e)};return e=>ts.visitNode(e,i)},n,e);return{file:t,content:a,...i}},duplicateHandlers={renamed:async(e,t)=>{const s=resolves([[collector,t],[updater,t],[callExpression,t],[exportExpression,t],[importExpression,t],[callExpression,t],[exportExpression,t]]),i=await s.concurrent();for(const t of i)e=e.map(t);return e},notRenamed:async(e,t)=>{let s=!1;const i=resolves([[collector,namesMap,t]]),n=await i.concurrent();return e.map(n[0]),await utilities.wait(1e3),namesMap.forEach((e,t)=>{e.size>1&&(s=!0,console.warn(`Name -> ${t} declared in multiple files :`),e.forEach(e=>console.warn(` - ${e.file}`)))}),await utilities.wait(500),s&&process.exit(1),e}};function mergeImportsStatement(e){const t=new Map,s=new Map,i=new Map,n=new Map,a=new Map;for(const r of e){const e=r.match(/import\s+(?:type\s+)?(?:(.*?)\s+from\s+)?["']([^"']+)["'];?/);if(!e)continue;const[,o,c]=e,l=r.includes("import type"),p=c;if(!o){const e=r.match(/import\s+(?:type\s+)?(\w+)/);if(e){const t=e[1],s=l?n:i;s.has(p)||s.set(p,new Set),s.get(p)?.add(t)}continue}if(o.startsWith("{")){const e=l?s:t;e.has(p)||e.set(p,new Set);o.replace(/[{}]/g,"").split(",").map(e=>e.trim()).filter(Boolean).forEach(t=>e.get(p)?.add(t))}else if(o.startsWith("* as")){const e=o.match(/\*\s+as\s+(\w+)/);if(e){const t=e[1];a.has(p)||a.set(p,new Set),a.get(p)?.add(t)}}else{const e=l?n:i;e.has(p)||e.set(p,new Set),e.get(p)?.add(o.trim())}}const r=[];for(const[e,i]of t){const t=s.get(e)||new Set,n=new Set([...i]);for(const e of t)i.has(e)||n.add(e);if(n.size>0){const t=Array.from(n).sort().join(", ");r.push(`import { ${t} } from "${e}";`)}}for(const[e,i]of s)if(!t.has(e)&&i.size>0){const t=Array.from(i).sort().join(", ");r.push(`import type { ${t} } from "${e}";`)}for(const[e,t]of i){const s=n.get(e)||new Set,i=new Set([...t]);for(const e of s)t.has(e)||i.add(e);if(i.size>0){const t=Array.from(i).join(", ");r.push(`import ${t} from "${e}";`)}}for(const[e,t]of n)if(!i.has(e)&&t.size>0){const s=Array.from(t).join(", ");r.push(`import type ${s} from "${e}";`)}for(const[e,t]of a)if(t.size>0){const s=Array.from(t).join(", ");r.push(`import * as ${s} from "${e}";`)}return r.sort()}function esmExportRemoveHandler(e){return({file:t,content:s,...i})=>{const n=ts.createSourceFile(t,s,ts.ScriptTarget.Latest,!0);return{file:t,content:transformFunction(e=>{const{factory:t}=e,s=i=>{if(!utilities.isInsideNamespace(i)&&(ts.isFunctionDeclaration(i)||ts.isClassDeclaration(i)||ts.isInterfaceDeclaration(i)||ts.isTypeAliasDeclaration(i)||ts.isEnumDeclaration(i)||ts.isVariableStatement(i))){const e=i.modifiers?.filter(e=>e.kind!==ts.SyntaxKind.ExportKeyword&&e.kind!==ts.SyntaxKind.DefaultKeyword);if(e?.length!==i.modifiers?.length){if(ts.isFunctionDeclaration(i))return t.updateFunctionDeclaration(i,e,i.asteriskToken,i.name,i.typeParameters,i.parameters,i.type,i.body);if(ts.isClassDeclaration(i))return t.updateClassDeclaration(i,e,i.name,i.typeParameters,i.heritageClauses,i.members);if(ts.isInterfaceDeclaration(i))return t.updateInterfaceDeclaration(i,e,i.name,i.typeParameters,i.heritageClauses,i.members);if(ts.isTypeAliasDeclaration(i))return t.updateTypeAliasDeclaration(i,e,i.name,i.typeParameters,i.type);if(ts.isEnumDeclaration(i))return t.updateEnumDeclaration(i,e,i.name,i.members);if(ts.isVariableStatement(i))return t.updateVariableStatement(i,e,i.declarationList)}}if(ts.isExportDeclaration(i))return t.createEmptyStatement();if(ts.isExportAssignment(i)){const e=i.expression;if(ts.isIdentifier(e))return t.createEmptyStatement()}return ts.visitEachChild(i,s,e)};return e=>ts.visitNode(e,s)},n,e),...i}}}let properties=[];const typeObj={},typesNames=[];function findProperty(e){const t=[];return ts.isPropertyAccessExpression(e)&&ts.isIdentifier(e.expression)&&t.push(e.expression.text),e.forEachChild(e=>findProperty(e)),t}function importAllRemoveHandler(e,t){return({file:s,content:i,...n})=>{const a=ts.createSourceFile(s,i,ts.ScriptTarget.Latest,!0),r=new Set;for(const e of a.statements)if(ts.isImportEqualsDeclaration(e)&&e.isTypeOnly){const t=e.moduleReference;ts.isExternalModuleReference(t)&&ts.isStringLiteral(t.expression)&&r.add(e.name.text)}const o=transformFunction(t=>{const{factory:i}=t,n=o=>{properties=[...properties,...findProperty(o)];const c={isNamespace:!1,isTypeOnly:!1,isTypeNamespace:!1,source:"",importedString:void 0,importedObject:void 0};if(ts.isTypeReferenceNode(o)&&ts.isQualifiedName(o.typeName)&&ts.isIdentifier(o.typeName.left)&&ts.isIdentifier(o.typeName.right)){const e=o.typeName.left.text,t=o.typeName.right.text;if(typesNames.push(e),e in typeObj?typeObj[e]?.push(t):typeObj[e]=[t],utilities.checkModuleType(a,s).isCommonJs&&"ts"!==e&&!r.has(e))return i.updateTypeReferenceNode(o,i.createIdentifier(t),void 0)}if(ts.isImportDeclaration(o)){const t=o.getText(a);return e.push(t),i.createEmptyStatement()}if(ts.isImportEqualsDeclaration(o)){const t=o.name.text,s=o.moduleReference;let n;if(o.isTypeOnly&&(c.isTypeOnly=!0),c.importedString=t,c.isTypeOnly||properties.includes(t)&&(c.isNamespace=!0),ts.isExternalModuleReference(s)&&ts.isStringLiteral(s.expression)&&(c.source=s.expression.text),c.importedString&&!c.importedObject&&(n=c.isTypeOnly?r.has(c.importedString)?`import type * as ${c.importedString} from "${c.source}";`:typesNames.includes(c.importedString)?`import type { ${typeObj[c.importedString]?.join(",")} } from "${c.source}";`:`import type ${c.importedString} from "${c.source}";`:c.isNamespace&&c.source&&"typescript"!==c.source?`import * as ${c.importedString} from "${c.source}";`:`import ${c.importedString} from "${c.source}";`),!c.importedString&&c.importedObject&&(n=`import { ${c.importedObject.join(", ")} } from "${c.source}";`),n)return e.push(n),i.createEmptyStatement()}if(ts.isVariableStatement(o)){const t=o.declarationList.declarations;if(1===t.length){const s=t[0];if(s.initializer&&ts.isCallExpression(s.initializer)&&ts.isIdentifier(s.initializer.expression)&&"require"===s.initializer.expression.escapedText){const t=s.initializer.arguments[0];if(ts.isStringLiteral(t)&&(c.source=t.text),ts.isIdentifier(s.name)){const e=s.name.text;c.importedString=e,properties.includes(e)&&(c.isNamespace=!0)}else if(ts.isObjectBindingPattern(s.name)){const e=[];for(const t of s.name.elements)ts.isIdentifier(t.name)&&e.push(t.name.text);e.length>0&&(c.importedObject=e)}let n;if(c.importedString&&!c.importedObject&&(n=c.isNamespace?`import * as ${c.importedString} from "${c.source}";`:`import ${c.importedString} from "${c.source}";`),!c.importedString&&c.importedObject&&(n=`import { ${c.importedObject.join(", ")} } from "${c.source}";`),n)return e.push(n),i.createEmptyStatement()}}}return ts.visitEachChild(o,n,t)};return e=>ts.visitNode(e,n)},a,t);return{file:s,content:o,...n}}}const removeHandlers=async(e,t)=>{const s=resolves([[importAllRemoveHandler,e,t],[esmExportRemoveHandler,t]]);return await s.series()};function collectBindingNames(e,t){ts.isIdentifier(e)?t.push(e.text):(ts.isObjectBindingPattern(e)||ts.isArrayBindingPattern(e))&&e.elements.forEach(e=>{ts.isBindingElement(e)&&e.name&&collectBindingNames(e.name,t)})}function clearUnusedCode(e,t,s,i={treatExportsAsUsed:!0}){const n=ts.createSourceFile(t,e,ts.ScriptTarget.Latest,!0),a=new Map,r=new Set,o=(e,t=!1)=>{const s=a.get(e);a.set(e,{exported:!!s?.exported||t})},c=e=>{if(ts.isImportDeclaration(e)&&e.importClause){const t=e.importClause;t.name&&ts.isIdentifier(t.name)&&o(t.name.text,!1),t.namedBindings&&(ts.isNamedImports(t.namedBindings)?t.namedBindings.elements.forEach(e=>{ts.isImportSpecifier(e)&&ts.isIdentifier(e.name)&&o(e.name.text,!1)}):ts.isNamespaceImport(t.namedBindings)&&ts.isIdentifier(t.namedBindings.name)&&o(t.namedBindings.name.text,!1))}else if(ts.isImportEqualsDeclaration(e)&&ts.isIdentifier(e.name))o(e.name.text,!1);else if(ts.isVariableStatement(e)){const t=e.modifiers?.some(e=>e.kind===ts.SyntaxKind.ExportKeyword)??!1;e.declarationList.declarations.forEach(e=>{collectBindingNames(e.name,[]);const s=[];collectBindingNames(e.name,s),s.forEach(e=>o(e,t))})}else if(ts.isFunctionDeclaration(e)&&e.name&&ts.isIdentifier(e.name)){const t=e.modifiers?.some(e=>e.kind===ts.SyntaxKind.ExportKeyword)??!1;o(e.name.text,t)}else if(ts.isClassDeclaration(e)&&e.name&&ts.isIdentifier(e.name)){const t=e.modifiers?.some(e=>e.kind===ts.SyntaxKind.ExportKeyword)??!1;o(e.name.text,t)}if(ts.isIdentifier(e)){const t=e.parent;ts.isVariableDeclaration(t)&&t.name===e||ts.isFunctionDeclaration(t)&&t.name===e||ts.isClassDeclaration(t)&&t.name===e||ts.isImportClause(t)&&t.name===e||ts.isImportSpecifier(t)&&t.name===e||ts.isNamespaceImport(t)&&t.name===e||ts.isBindingElement(t)&&t.name===e||ts.isParameter(t)&&t.name===e||r.add(e.text)}ts.forEachChild(e,c)};c(n);const l=new Set;a.forEach((e,t)=>{r.has(t)||i.treatExportsAsUsed&&e.exported||l.add(t)});return transformFunction(e=>{const t=s=>{if(ts.isImportDeclaration(s)&&s.importClause){const e=s.importClause,t=e.name&&ts.isIdentifier(e.name)?e.name.text:void 0;let i;const n=[];e.namedBindings&&(ts.isNamedImports(e.namedBindings)?e.namedBindings.elements.forEach(e=>{ts.isImportSpecifier(e)&&ts.isIdentifier(e.name)&&n.push(e)}):ts.isNamespaceImport(e.namedBindings)&&ts.isIdentifier(e.namedBindings.name)&&(i=e.namedBindings.name.text));const a=!!t&&!l.has(t),r=!!i&&!l.has(i),o=n.filter(e=>!l.has(e.name.text));if(!a&&!r&&0===o.length)return ts.factory.createNotEmittedStatement(s);if(!a&&!!e.name||void 0!==i&&!r||o.length!==n.length){let e;e=o.length>0?ts.factory.createNamedImports(o):r&&i?ts.factory.createNamespaceImport(ts.factory.createIdentifier(i)):void 0;const n=a&&t?ts.factory.createIdentifier(t):void 0,c=ts.factory.createImportClause(!1,n,e);return ts.factory.updateImportDeclaration(s,s.modifiers,c,s.moduleSpecifier,s.assertClause)}return s}if((ts.isFunctionDeclaration(s)||ts.isClassDeclaration(s))&&s.name&&ts.isIdentifier(s.name))return l.has(s.name.text)?ts.factory.createNotEmittedStatement(s):s;if(ts.isVariableStatement(s)){const e=[];s.declarationList.declarations.forEach(t=>collectBindingNames(t.name,e));return e.some(e=>!l.has(e))?s:ts.factory.createNotEmittedStatement(s)}return ts.visitEachChild(s,t,e)};return e=>ts.visitNode(e,t)},n,s)}async function bundler(e){const t="."===e.exportPath?"Main":splitCamelCase(e.exportPath.slice(2));console.time(`${tcolor.cyan("Bundled")} -> ${tcolor.brightCyan(t)} ${tcolor.cyan("export path")}`);let s=e.depFiles;const i=e.rename,n=e.tsOptions.default,a=e.plugins;let r=[];if(a.length)for(let e of a)e="function"==typeof e?e():e,"dependency"===e.type&&(s=e.async?await e.func(s):e.func(s));s=i?await duplicateHandlers.renamed(s,n):await duplicateHandlers.notRenamed(s,n),s=await anonymousHandler(s,n);const o=await removeHandlers(r,n);s=s.map(o[0]);const c=s.slice(0,-1).map(o[1]),l=s.slice(-1),p=/["']((?!\.\/|\.\.\/)[^"']+)["']/;r=r.filter(e=>p.test(e)),r=mergeImportsStatement(r);let m=`${r.join("\n").trim()}\n${c.map(e=>`${`//${path.relative(process.cwd(),e.file)}`}\n${e.content}`).join("\n").trim()}\n${l.map(e=>`${`//${path.relative(process.cwd(),e.file)}`}\n${e.content}`).join("\n").trim()}`;if(m=m.replace(/^s*;\s*$/gm,"").trim(),m=clearUnusedCode(m,e.fileName,n),a.length)for(let e of a)e="function"==typeof e?e():e,"pre-process"===e.type&&(m=e.async?await e.func(m):e.func(m));return console.timeEnd(`${tcolor.cyan("Bundled")} -> ${tcolor.brightCyan(t)} ${tcolor.cyan("export path")}`),{bundledContent:m,...e}}async function bundle(e){const t=[];for(const s of e.points){const e=await bundler(s);t.push(e)}return{points:t,allowUpdatePackageJson:e.allowUpdatePackageJson}}function createHost(e,t){const s={},i={getSourceFile:(s,i)=>{if(s===t)return ts.createSourceFile(s,e,i)},writeFile:(e,t)=>{s[e]=t},getDefaultLibFileName:e=>ts.getDefaultLibFilePath(e),getCurrentDirectory:()=>"",getDirectories:()=>[],fileExists:e=>e===t,readFile:s=>s===t?e:void 0,getCanonicalFileName:e=>e,useCaseSensitiveFileNames:()=>!0,getNewLine:()=>"\n"};return{createdFiles:s,host:i}}const isCjs=e=>e.commonjs&&e.commonjsTypes,isEsm=e=>e.esm&&e.esmTypes;function getExports(e,t){return isCjs(e)&&isEsm(e)?{[t]:{import:{types:`./${path.relative(process.cwd(),e.esmTypes)}`,default:`./${path.relative(process.cwd(),e.esm)}`},require:{types:`./${path.relative(process.cwd(),e.commonjsTypes)}`,default:`./${path.relative(process.cwd(),e.commonjs)}`}}}:isCjs(e)&&!isEsm(e)?{[t]:{require:{types:`./${path.relative(process.cwd(),e.commonjsTypes)}`,default:`./${path.relative(process.cwd(),e.commonjs)}`}}}:!isCjs(e)&&isEsm(e)?{[t]:{import:{types:`./${path.relative(process.cwd(),e.esmTypes)}`,default:`./${path.relative(process.cwd(),e.esm)}`}}}:{}}async function writePackage(e,t){let s=!0;"."!==t&&(s=!1);const i=ts.sys.resolvePath("package.json"),n=fs.readFileSync(i,"utf8"),a=JSON.parse(n);let{name:r,version:o,description:c,main:l,module:p,type:m,types:f,exports:d,...u}=a;await utilities.wait(500),m="module";let y={},h={},g={},x={};if(s)y=e.main?{main:path.relative(process.cwd(),e.main)}:{},h=e.module?{module:path.relative(process.cwd(),e.module)}:{},g=e.types?{types:path.relative(process.cwd(),e.types)}:{},x={exports:{...getExports(e,t)}};else{y=l?{main:l}:{},h=p?{module:p}:{},g=f?{types:f}:{};x={exports:{...d&&"object"==typeof d&&!Array.isArray(d)?{...d}:{},...getExports(e,t)}}}await utilities.wait(1e3);const w={name:r,version:o,description:c,type:m,...y,...g,...h,...x,...u};utilities.writeCompileFile(i,JSON.stringify(w,null,2))}class Compiler{constructor(e){this.object=e,this.files={commonjs:void 0,commonjsTypes:void 0,esm:void 0,esmTypes:void 0,main:void 0,module:void 0,types:void 0}}_isUpdate(){return this.object.allowUpdatePackageJson}async _commonjs(e){const t="."===e.exportPath,s=t?"Main":splitCamelCase(e.exportPath.slice(2));console.time(`${tcolor.cyan("Compiled CJS")} -> ${tcolor.brightCyan(s)} ${tcolor.cyan("export path")}`);const i=e.fileName,n=e.bundledContent,a=e.format,r=e.plugins,o=e.tsOptions.cjs,c=createHost(n,i),l=c.createdFiles,p=c.host;ts.createProgram([i],o,p).emit(),Object.entries(l).map(async([e,s])=>{if(".js"===path.extname(e)&&r.length)for(let t of r)t="function"==typeof t?t():t,"post-process"===t.type&&(s=t.async?await t.func(s,e):t.func(s,e));this._isUpdate()&&(e.match(/.js/g)&&(this.files.commonjs=e.replace(/.js/g,".cjs")),e.match(/.d.ts/g)&&(this.files.commonjsTypes=e.replace(/.d.ts/g,".d.cts")),!t||"both"!==a&&"commonjs"!==a||(this.files.commonjs&&(this.files.main=this.files.commonjs),this.files.commonjsTypes&&(this.files.types=this.files.commonjsTypes))),e=(e=(e=e.replace(/.js/g,".cjs")).replace(/.map.js/g,".map.cjs")).replace(/.d.ts/g,".d.cts"),await utilities.wait(500),"commonjs"===a&&await utilities.clearFolder(path.dirname(e)),await utilities.writeCompileFile(e,s)}),console.timeEnd(`${tcolor.cyan("Compiled CJS")} -> ${tcolor.brightCyan(s)} ${tcolor.cyan("export path")}`)}async _esm(e){const t="."===e.exportPath,s=t?"Main":splitCamelCase(e.exportPath.slice(2));console.time(`${tcolor.cyan("Compiled ESM")} -> ${tcolor.brightCyan(s)} ${tcolor.cyan("export path")}`);const i=e.fileName,n=e.bundledContent,a=e.format,r=e.plugins,o=e.tsOptions.esm,c=createHost(n,i),l=c.createdFiles,p=c.host;ts.createProgram([i],o,p).emit(),Object.entries(l).map(async([e,s])=>{if(".js"===path.extname(e)&&r.length)for(let t of r)t="function"==typeof t?t():t,"post-process"===t.type&&(s=t.async?await t.func(s,e):t.func(s,e));this._isUpdate()&&(e.match(/.js/g)&&(this.files.esm=e.replace(/.js/g,".mjs")),e.match(/.d.ts/g)&&(this.files.esmTypes=e.replace(/.d.ts/g,".d.mts")),t&&"both"===a&&this.files.esm&&(this.files.module=this.files.esm)),e=(e=(e=e.replace(/.js/g,".mjs")).replace(/.map.js/g,".map.mjs")).replace(/.d.ts/g,".d.mts"),await utilities.wait(500),"commonjs"!==a&&await utilities.clearFolder(path.dirname(e)),await utilities.writeCompileFile(e,s)}),console.timeEnd(`${tcolor.cyan("Compiled ESM")} -> ${tcolor.brightCyan(s)} ${tcolor.cyan("export path")}`)}async compile(){for(const e of this.object.points){switch(await utilities.wait(500),e.format){case"commonjs":await this._commonjs(e),this._isUpdate()&&await writePackage(this.files,e.exportPath);break;case"esm":await this._esm(e),this._isUpdate()&&await writePackage(this.files,e.exportPath);break;case"both":await this._esm(e),await utilities.wait(1e3),await this._commonjs(e),this._isUpdate()&&await writePackage(this.files,e.exportPath)}await utilities.wait(500)}}}var checks;!function(e){function t(e,t){if(!t.noCheck){const s=e.map(e=>e.file);let i=!1;const n=ts.createProgram(s,t);for(const e of s){const t=n.getSourceFile(e);t||(console.error(tcolor.magenta(`File not found: ${e}`)),ts.sys.exit(1));const s=[...n.getSyntacticDiagnostics(t),...n.getSemanticDiagnostics(t),...n.getDeclarationDiagnostics(t)];if(s.length>0){const e={getCurrentDirectory:()=>process.cwd(),getCanonicalFileName:e=>e,getNewLine:()=>ts.sys.newLine};console.error(ts.formatDiagnosticsWithColorAndContext(s,e)),i=!0}}if(!i)return!0;ts.sys.exit(1)}}function s(e){let t=0,s=0;for(const n of e)try{const a=ts.createSourceFile(n.file,n.content,ts.ScriptTarget.Latest,!0);let r=!1,o=!1;function i(e){if((ts.isImportDeclaration(e)||ts.isImportEqualsDeclaration(e)||ts.isExportDeclaration(e)||ts.isExportSpecifier(e)||ts.isExportAssignment(e))&&(r=!0),(ts.isVariableStatement(e)||ts.isFunctionDeclaration(e)||ts.isInterfaceDeclaration(e)||ts.isTypeAliasDeclaration(e)||ts.isEnumDeclaration(e)||ts.isClassDeclaration(e))&&e.modifiers?.some(e=>e.kind===ts.SyntaxKind.ExportKeyword)&&(r=!0),ts.isCallExpression(e)&&ts.isIdentifier(e.expression)&&"require"===e.expression.text&&e.arguments.length>0&&(o=!0),ts.isPropertyAccessExpression(e)){const t=e.getText(a);(t.startsWith("module.exports")||t.startsWith("exports."))&&(o=!0)}ts.forEachChild(e,i)}i(a),r&&!o?0:o&&!r?t++:r&&o&&0}catch(c){console.error(tcolor.magenta(`Error checking module format for ${n.file} : \n ${c}`)),s++}return s&&(console.error(tcolor.magenta("Unknown error when checking module types in the dependencies tree.")),ts.sys.exit(1)),t&&(console.error(tcolor.magenta("The package detects CommonJs format in the dependencies tree, that unsupported.")),ts.sys.exit(1)),!0}function i(e){const t=new Set([".ts",".mts",".cts",".tsx"]);for(const s of e){const e=path.extname(s.file);t.has(e)||(console.error(tcolor.magenta(`${s.file} has no valid TypeScript extension`)),ts.sys.exit(1))}return!0}e.types=async function(e,s){const i=resolves([[t,e,s]]);return(await i.series())[0]},e.moduleAndExtension=async function(e){const t=resolves([[s,e],[i,e]]);return(await t.concurrent()).every(e=>!0===e)}}(checks||(checks={}));const getConfigPath=()=>{const e=["susee.config.ts","susee.config.js","susee.config.mjs"];let t;for(const s of e){const e=ts.sys.resolvePath(s);if(ts.sys.fileExists(e)){t=e;break}}return t};function checkEntries(e){e.length<1&&(console.error(tcolor.magenta("No entry found in susee.config file, at least one entry required")),ts.sys.exit(1));const t={},s=[];for(const i of e){const e=i.exportPath;t[e]?s.push(`"${e}"`):t[e]=!0}s.length>0&&(console.error(tcolor.magenta(`Duplicate export paths/path (${s.join(",")}) found in your susee.config file , that will error for bundled output`)),ts.sys.exit(1));for(const t of e)ts.sys.fileExists(ts.sys.resolvePath(t.entry))||(console.error(tcolor.magenta(`Entry file ${t.entry} dose not exists.`)),ts.sys.exit(1))}async function getConfig(){const e=getConfigPath();void 0===e&&(console.error(tcolor.magenta('No susee.config file ("susee.config.ts", "susee.config.js", "susee.config.mjs") found')),ts.sys.exit(1));const t=(await import(e)).default,s=resolves([[checkEntries,t.entryPoints]]);await s.series(),await utilities.wait(1e3);const i=[];for(const e of t.entryPoints){const s={entry:e.entry,exportPath:e.exportPath,format:e.format??"esm",tsconfigFilePath:e.tsconfigFilePath??void 0,renameDuplicates:e.renameDuplicates??!0,outDir:t.outDir??"dist"};i.push(s)}return{points:i,plugins:t.plugins??[],allowUpdatePackageJson:t.allowUpdatePackageJson??!0}}async function fileSizes(e){const t=await fs.promises.stat(e);return{logical:t.size,allocated:null!==t.blocks?512*t.blocks:null}}const checkExport=(e,t)=>!!(e.match(/export default .*/gm)||e.match(/export = .*/gm)&&t.match(/.cts/g));async function generateDependencies(e){const t=(await dependencies(e)).sort(),s=[];await utilities.wait(1e3);for(const e of t){const t=ts.sys.resolvePath(e),i=await fs.promises.readFile(t,"utf8"),n=await fileSizes(t),a=i.length,r=checkExport(i,t),o=ts.createSourceFile(t,i,ts.ScriptTarget.Latest,!0),c=utilities.checkModuleType(o,t).isCommonJs?"cjs":"esm",l={file:t,content:i,length:a,includeDefExport:r,size:{logical:n.logical,allocated:n.allocated,utf8:(new TextEncoder).encode(i).length,buffBytes:Buffer.byteLength(i,"utf8")},type:c};s.push(l)}return s}class GetOptions{constructor(e){this._point=e,this._options={}}__init(){const e=new TsConfig(this._point.tsconfigFilePath),t="."===this._point.exportPath?this._point.outDir:`${this._point.outDir}/${this._point.exportPath.slice(2)}`;e.removeCompilerOption("rootDir"),e.removeCompilerOption("module"),e.editCompilerOptions({moduleResolution:ts.ModuleResolutionKind.NodeNext,outDir:t}),this._options=e.getCompilerOptions()}__init2(){this.__init();let{types:e,lib:t,...s}=this._options;return e?e.includes("node")||(e=["node",...e]):e=["node"],t=t?[...new Set(["ESNext",...t])]:["ESNext"],{types:e,lib:t,...s}}get commonjs(){const e=this.__init2(),{module:t,...s}=e;return{module:ts.ModuleKind.CommonJS,...s}}get esm(){const e=this.__init2(),{module:t,...s}=e;return{module:ts.ModuleKind.ES2020,...s}}get default(){return this.__init2()}}function getOptions(e){return new GetOptions(e)}async function collections(){console.time(`${tcolor.cyan("Collected Data")} :`);const e=await getConfig(),t=e.points,s=e.plugins,i=[];for(const e of t){const t=getOptions(e);let n=await generateDependencies(e.entry);await checks.types(n,t.esm)||ts.sys.exit(1);let a=!1;if(s.length)for(const e of s){const t="function"==typeof e?e():e;"dependency"===t.type&&(t.name&&"@suseejs/plugin-commonjs"===t.name&&(a=!0),n=t.async?await t.func(n):t.func(n))}if(!a){await checks.moduleAndExtension(n)||ts.sys.exit(1)}const r={fileName:e.entry,exportPath:e.exportPath,format:e.format,rename:e.renameDuplicates,outDir:e.outDir,tsOptions:{cjs:t.commonjs,esm:t.esm,default:t.default},depFiles:n,plugins:s};i.push(r)}return console.timeEnd(`${tcolor.cyan("Collected Data")} :`),{points:i,allowUpdatePackageJson:e.allowUpdatePackageJson}}async function susee(){console.info(`${tcolor.cyan("Started")} : `),console.time(`${tcolor.cyan("Done")}`);const e=await collections();await utilities.wait(1e3);const t=await bundle(e);await utilities.wait(1e3);const s=new Compiler(t);await s.compile(),console.timeEnd(`${tcolor.cyan("Done")}`)}export{susee};