@cmmn/tools 1.8.1 → 1.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,11 +1,21 @@
1
- import ts from "typescript/lib/typescript.js";
2
- import {resolve, relative} from 'path';
3
- import fs from "fs";
1
+ import ts from "typescript";
2
+ import {resolve, relative} from 'node:path';
3
+ import fs from "node:fs";
4
+ import { tsResolvePlugin } from "./ts-resolve-plugin.js";
5
+
4
6
  const rootDir = process.cwd();
5
7
 
6
8
  export function compile(...flags) {
7
9
 
8
10
  const host = ts.createSolutionBuilderWithWatchHost(ts.sys, createProgram);
11
+ host.getCustomTransformers = (pkg) => ({
12
+ before: [
13
+ tsResolvePlugin
14
+ ],
15
+ afterDeclarations: [
16
+ tsResolvePlugin
17
+ ]
18
+ });
9
19
  host.useCaseSensitiveFileNames();
10
20
 
11
21
  const builderFactory = flags.includes('--watch') ?
@@ -0,0 +1,231 @@
1
+ import ts from "typescript";
2
+ import path from "path";
3
+ import fs from "fs";
4
+ import { ImportPathsResolver } from '@zerollup/ts-helpers'
5
+
6
+ class Visitor {
7
+ /**
8
+ * @type {ImportPathsResolver}
9
+ */
10
+ resolver;
11
+ /**
12
+ * @type {ts.TransformationContext}
13
+ */
14
+ context;
15
+ /**
16
+ * @type {ts.CompilerOptions}
17
+ */
18
+ options;
19
+ /**
20
+ * @type {{
21
+ * copy: RegExp;
22
+ * import: RegExp;
23
+ * }}
24
+ */
25
+ config;
26
+ /**
27
+ *
28
+ * @param context {ts.TransformationContext}
29
+ */
30
+ constructor(context, config) {
31
+ this.context = context;
32
+ this.options = context.getCompilerOptions();
33
+ this.resolver = new ImportPathsResolver({
34
+ paths: this.options.paths,
35
+ baseUrl: this.options.baseUrl,
36
+ exclude: []
37
+ });
38
+ this.config = {
39
+ copy: /\.(less|css|scss|sass|svg|png|html|txt)$/g,
40
+ import: /\.(txt|sql)$/g,
41
+ ...config
42
+ }
43
+ }
44
+
45
+ /**
46
+ * @param file {string}
47
+ * @param sourceFile {ts.SourceFile}
48
+ */
49
+ resolve(file, sourceFile){
50
+ const sourceFileDir = path.dirname(sourceFile.path);
51
+ const suggestions = this.resolver.getImportSuggestions(file, sourceFileDir) ?? [];
52
+ for (let suggestion of suggestions) {
53
+ if (!fs.existsSync(path.join(sourceFileDir, suggestion))) {
54
+ continue;
55
+ }
56
+ file = suggestion;
57
+ break;
58
+ }
59
+ const caseSensitiveFileNames = this.context.getEmitHost().useCaseSensitiveFileNames();
60
+ const formatPath = caseSensitiveFileNames ? x => x : x => x.toLowerCase();
61
+ const absSource = path.join(this.options.outDir, path.relative(this.options.baseUrl, sourceFileDir));
62
+ const abs = path.resolve(sourceFileDir, file);
63
+ if (this.config.copy.test(file)) {
64
+ const outFile = path.resolve(absSource, file).replaceAll(path.sep, '/');
65
+ fs.cpSync(path.resolve(sourceFileDir, file), outFile);
66
+ return file;
67
+ }
68
+ if (this.config.import.test(file)) {
69
+ const content = fs.readFileSync(path.resolve(sourceFileDir, file), 'utf-8');
70
+ const outFile = path.resolve(absSource, file).replaceAll(path.sep, '/') + '.js';
71
+ fs.mkdirSync(path.dirname(outFile), {recursive: true});
72
+ fs.writeFileSync(outFile, 'export default `'+content.replaceAll('`','\\`')+'`', 'utf-8');
73
+ return outFile;
74
+ }
75
+ if (fs.existsSync(abs)){
76
+ return file.replace(/\.ts$/,'.js');
77
+ }
78
+ if (fs.existsSync(abs + '.ts') || fs.existsSync(abs + '.tsx')) {
79
+ return `${file}.js`;
80
+ }
81
+ if (fs.existsSync(abs + '/')) {
82
+ return `${file}/index.js`;
83
+ }
84
+ return file;
85
+ }
86
+
87
+ visitSourceFile = sourceFile => ts.visitEachChild(sourceFile, node => this.visit(node,sourceFile), this.context);
88
+
89
+ /**
90
+ * @param node {ts.Node}
91
+ * @param sourceFile {ts.SourceFile}
92
+ */
93
+ visit(node,sourceFile){
94
+ // if (node && node.kind == SyntaxKind.ImportDeclaration) {
95
+ // return visitImportNode(node as ts.ImportDeclaration);
96
+ // }
97
+ if (!node)
98
+ return ts.visitEachChild(node, this.visit, this.context);
99
+ if (ts.isCallExpression(node)) {
100
+ const result = this.visitRequireNode(node, sourceFile);
101
+ if (result)
102
+ return result;
103
+ }
104
+ if (ts.isImportDeclaration(node)) {
105
+ const result = this.visitImportNode(node, sourceFile);
106
+ if (result)
107
+ return result;
108
+ }
109
+ if (ts.isExportDeclaration(node)) {
110
+ const result = this.visitExportNode(node, sourceFile);
111
+ if (result)
112
+ return result;
113
+ }
114
+ return ts.visitEachChild(node, node => this.visit(node, sourceFile), this.context);
115
+ }
116
+
117
+
118
+ /**
119
+ * @param exportNode {ts.ExportDeclaration}
120
+ * @param sourceFile {ts.SourceFile}
121
+ */
122
+ visitExportNode(exportNode, sourceFile) {
123
+ if (exportNode.typeOnly){
124
+ console.log('type olnly')
125
+ return ;
126
+ }
127
+ const file = exportNode.moduleSpecifier?.text ?? exportNode.text;
128
+ if (!file)
129
+ return;
130
+
131
+ const resolved = this.resolve(file, sourceFile);
132
+
133
+ const newNode = this.context.factory.updateExportDeclaration(
134
+ exportNode,
135
+ exportNode.decorators,
136
+ exportNode.modifiers,
137
+ exportNode.exportClause,
138
+ this.context.factory.createStringLiteral(resolved),
139
+ exportNode.typeOnly
140
+ );
141
+ if (newNode.flags !== exportNode.flags) {
142
+ newNode.flags = exportNode.flags
143
+ }
144
+ return newNode;
145
+ }
146
+
147
+ /**
148
+ * @param importNode {ts.ImportDeclaration}
149
+ * @param sourceFile {ts.SourceFile}
150
+ */
151
+ visitImportNode(importNode, sourceFile) {
152
+ const file = importNode.moduleSpecifier?.text;
153
+ if (!file)
154
+ return;
155
+ const resolved = this.resolve(file, sourceFile);
156
+
157
+ const newNode = this.context.factory.updateImportDeclaration(
158
+ importNode,
159
+ importNode.modifiers,
160
+ importNode.importClause,
161
+ this.context.factory.createStringLiteral(resolved),
162
+ importNode.assertClause,
163
+ );
164
+ newNode.flags = importNode.flags;
165
+ return newNode;
166
+ // const caseSensitiveFileNames = this.context.getEmitHost().useCaseSensitiveFileNames();
167
+ // const formatPath = caseSensitiveFileNames ? x => x : x => x.toLowerCase();
168
+ // const sourceFileDir = path.dirname(sourceFile.path);
169
+ // const abs = formatPath(path.resolve(sourceFileDir, formatPath(file)));
170
+ // if (/\.(less|css|scss|sass|svg|png|html)$/.test(file)) {
171
+ // const absSource = formatPath(path.join(this.options.outDir, formatPath(path.relative(this.options.baseUrl, sourceFileDir))));
172
+ // const relFile = path.relative(absSource, abs).replaceAll(path.sep, '/');
173
+ // return this.context.factory.updateImportDeclaration(
174
+ // importNode,
175
+ // importNode.decorators,
176
+ // importNode.modifiers,
177
+ // importNode.importClause,
178
+ // importNode.assertClause,
179
+ // this.context.factory.createStringLiteral(relFile)
180
+ // );
181
+ // }
182
+ // if (/\.(json|tsx?|jsx?)$/.test(file))
183
+ // return;
184
+ // if (fs.existsSync(abs + '.ts') || fs.existsSync(abs + '.tsx')) {
185
+ // return this.context.factory.updateImportDeclaration(
186
+ // importNode,
187
+ // importNode.decorators,
188
+ // importNode.modifiers,
189
+ // importNode.importClause,
190
+ // importNode.assertClause,
191
+ // this.context.factory.createStringLiteral(file + '.js')
192
+ // );
193
+ // }
194
+ // if (fs.existsSync(abs + '/')) {
195
+ // const indexFile = `${file}/index.js`;
196
+ // return this.context.factory.updateImportDeclaration(
197
+ // importNode,
198
+ // importNode.decorators,
199
+ // importNode.modifiers,
200
+ // importNode.importClause,
201
+ // importNode.assertClause,
202
+ // this.context.factory.createStringLiteral(indexFile)
203
+ // );
204
+ // }
205
+ }
206
+
207
+ /**
208
+ * @param importNode {ts.Node}
209
+ * @param sourceFile {ts.SourceFile}
210
+ */
211
+ visitRequireNode(importNode, sourceFile) {
212
+ if (importNode.expression.kind !== ts.SyntaxKind.Identifier ||
213
+ importNode.expression.escapedText !== "require") {
214
+ return;
215
+ }
216
+ const file = importNode.arguments[0].text;
217
+ const resolved = this.resolve(file, sourceFile);
218
+ return this.context.factory.updateCallExpression(
219
+ importNode,
220
+ importNode.expression,
221
+ undefined,
222
+ [this.context.factory.createStringLiteral(resolved)]
223
+ );
224
+ }
225
+ }
226
+
227
+ export const tsResolvePlugin = function (contextOrOptions) {
228
+ if(!contextOrOptions.getCompilerOptions)
229
+ return context => new Visitor(context, contextOrOptions).visitSourceFile;
230
+ return new Visitor(contextOrOptions).visitSourceFile;
231
+ };
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "compilerOptions": {
3
- "module": "NodeNext",
4
- "moduleResolution": "NodeNext",
3
+ "module": "esnext",
4
+ "moduleResolution": "bundler",
5
5
  "target": "ESNext",
6
6
  "composite": true,
7
7
  "sourceMap": false,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cmmn/tools",
3
- "version": "1.8.1",
3
+ "version": "1.9.0",
4
4
  "description": "Compilation, bundling, code generator, testing.",
5
5
  "main": "dist/rollup.config.js",
6
6
  "type": "module",
@@ -56,6 +56,7 @@
56
56
  "@types/jest": "27.x.x",
57
57
  "@types/sinon": "10.x.x",
58
58
  "@web/rollup-plugin-html": "^1.10.1",
59
+ "@zerollup/ts-helpers": "1.7.18",
59
60
  "fast-glob": "^3.2.11",
60
61
  "file-uri-to-path": "2.x.x",
61
62
  "import-meta-resolve": "2",
@@ -83,5 +84,5 @@
83
84
  },
84
85
  "author": "",
85
86
  "license": "ISC",
86
- "gitHead": "6c114c08370cc1eeb81338f78df5feef6531bfed"
87
+ "gitHead": "ec757aa138e112b23716de079c593b509a522c57"
87
88
  }
@@ -18,7 +18,7 @@ export default {
18
18
  decoratorMetadata: true,
19
19
  },
20
20
  paths: options.paths,
21
- baseUrl: '.'
21
+ baseUrl: process.cwd()
22
22
  },
23
23
  }],
24
24
  },
@@ -1,101 +0,0 @@
1
- const ts = require("typescript");
2
- const path = require("path");
3
- const fs = require("fs");
4
-
5
- function visitExportNode(exportNode, sourceFile) {
6
- if (exportNode.typeOnly){
7
- console.log('type olnly')
8
- return ;
9
- }
10
- const file = exportNode.moduleSpecifier?.text ?? exportNode.test;
11
- if (!file || !file.startsWith('.'))
12
- return;
13
- const sourceFileDir = path.dirname(sourceFile.path);
14
- const abs = path.resolve(sourceFileDir, file);
15
- if (/\.(less|css|scss|sass|svg|png|html)$/.test(file)) {
16
- const absSource = path.join(options.outDir, path.relative(options.baseUrl, sourceFileDir));
17
- const relFile = path.relative(absSource, abs).replaceAll(path.sep, '/');
18
- return ts.updateExportDeclaration(exportNode, exportNode.decorators, exportNode.modifiers, exportNode.exportClause, ts.createStringLiteral(relFile), exportNode.typeOnly);
19
- }
20
- if (fs.existsSync(abs + '.ts') || fs.existsSync(abs + '.tsx')) {
21
- return ts.updateExportDeclaration(exportNode, exportNode.decorators, exportNode.modifiers, exportNode.exportClause, ts.createStringLiteral(file + '.js'), exportNode.typeOnly);
22
- }
23
- if (fs.existsSync(abs + '/')) {
24
- const indexFile = `${file}/index.js`;
25
- return ts.updateExportDeclaration(exportNode, exportNode.decorators, exportNode.modifiers, exportNode.exportClause, ts.createStringLiteral(indexFile), exportNode.typeOnly);
26
- }
27
- }
28
-
29
- function visitImportNode(importNode, sourceFile, options, context) {
30
- const file = importNode.moduleSpecifier?.text;
31
- if (!file || !file.startsWith('.'))
32
- return;
33
- const caseSensitiveFileNames = context.getEmitHost().useCaseSensitiveFileNames();
34
- const formatPath = caseSensitiveFileNames ? x => x : x => x.toLowerCase();
35
- const sourceFileDir = path.dirname(sourceFile.path);
36
- const abs = formatPath(path.resolve(sourceFileDir, formatPath(file)));
37
- if (/\.(less|css|scss|sass|svg|png|html)$/.test(file)) {
38
- const absSource = formatPath(path.join(options.outDir, formatPath(path.relative(options.baseUrl, sourceFileDir))));
39
- const relFile = path.relative(absSource, abs).replaceAll(path.sep, '/');
40
- return ts.updateImportDeclaration(importNode, importNode.decorators, importNode.modifiers, importNode.importClause, ts.createStringLiteral(relFile));
41
- }
42
- if (/\.(json|tsx?|jsx?)$/.test(file))
43
- return;
44
- if (fs.existsSync(abs + '.ts') || fs.existsSync(abs + '.tsx')) {
45
- return ts.updateImportDeclaration(importNode, importNode.decorators, importNode.modifiers, importNode.importClause, ts.createStringLiteral(file + '.js'));
46
- }
47
- if (fs.existsSync(abs + '/')) {
48
- const indexFile = `${file}/index.js`;
49
- return ts.updateImportDeclaration(importNode, importNode.decorators, importNode.modifiers, importNode.importClause, ts.createStringLiteral(indexFile));
50
- }
51
- }
52
-
53
- function visitRequireNode(importNode, sourceFile) {
54
- if (!(importNode.expression.kind == ts.SyntaxKind.Identifier &&
55
- importNode.expression.escapedText == "require")) {
56
- return;
57
- }
58
- const file = importNode.arguments[0].text;
59
- if (/\.(less|css|scss|sass|svg|png|html)/.test(file)) {
60
- const sourceFileDir = path.dirname(sourceFile.path);
61
- const abs = path.join(sourceFileDir, file);
62
- const absSource = path.join(options.outDir, path.relative(options.baseUrl, sourceFileDir));
63
- const relFile = path.relative(absSource, abs).replaceAll(path.sep, '/');
64
- return ts.updateCall(importNode, importNode.expression, undefined, [ts.createStringLiteral(relFile)]);
65
- }
66
- }
67
-
68
- const lessToStringTransformer = function (context) {
69
- const options = context.getCompilerOptions();
70
- console.log(context);
71
- return (sourceFile) => {
72
- function visitor(node) {
73
- // if (node && node.kind == ts.SyntaxKind.ImportDeclaration) {
74
- // return visitImportNode(node as ts.ImportDeclaration);
75
- // }
76
- if (!node)
77
- return ts.visitEachChild(node, visitor, context);
78
- if (ts.isCallExpression(node)) {
79
- const result = visitRequireNode(node, sourceFile);
80
- if (result)
81
- return result;
82
- }
83
- if (ts.isImportDeclaration(node)) {
84
- const result = visitImportNode(node, sourceFile, options, context);
85
- if (result)
86
- return result;
87
- }
88
- if (ts.isExportDeclaration(node)) {
89
- const result = visitExportNode(node, sourceFile);
90
- if (result)
91
- return result;
92
- }
93
- return ts.visitEachChild(node, visitor, context);
94
- }
95
-
96
- return ts.visitEachChild(sourceFile, visitor, context);
97
- };
98
- };
99
- exports.default = function (program, pluginOptions) {
100
- return lessToStringTransformer;
101
- }