@open-norantec/herbal 1.0.2-alpha.13 → 1.0.2-alpha.15

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,58 +1,35 @@
1
1
  #!/usr/bin/env node
2
2
  "use strict";
3
- var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
4
- function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
5
- return new (P || (P = Promise))(function (resolve, reject) {
6
- function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
7
- function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
8
- function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
9
- step((generator = generator.apply(thisArg, _arguments || [])).next());
10
- });
11
- };
12
- var __generator = (this && this.__generator) || function (thisArg, body) {
13
- var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
14
- return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
15
- function verb(n) { return function (v) { return step([n, v]); }; }
16
- function step(op) {
17
- if (f) throw new TypeError("Generator is already executing.");
18
- while (g && (g = 0, op[0] && (_ = 0)), _) try {
19
- if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
20
- if (y = 0, t) op = [op[0] & 2, t.value];
21
- switch (op[0]) {
22
- case 0: case 1: t = op; break;
23
- case 4: _.label++; return { value: op[1], done: false };
24
- case 5: _.label++; y = op[1]; op = [0]; continue;
25
- case 7: op = _.ops.pop(); _.trys.pop(); continue;
26
- default:
27
- if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
28
- if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
29
- if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
30
- if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
31
- if (t[2]) _.ops.pop();
32
- _.trys.pop(); continue;
33
- }
34
- op = body.call(thisArg, _);
35
- } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
36
- if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
37
- }
38
- };
39
3
  Object.defineProperty(exports, "__esModule", { value: true });
40
4
  var commander_1 = require("commander");
41
5
  var forge_1 = require("@open-norantec/forge");
42
- var utilities_1 = require("../utilities");
43
6
  var _ = require("lodash");
44
7
  var fs = require("fs-extra");
45
8
  var path = require("node:path");
46
- var attempt_util_class_1 = require("@open-norantec/utilities/dist/attempt-util.class");
9
+ var requireFromString = require("require-from-string");
10
+ var reflect_declaration_1 = require("../transformers/reflect-declaration");
47
11
  var command = new commander_1.Command('herbal');
48
- var getEntryFileContent = function (_a) {
49
- var entryFilePath = _a.entryFilePath;
12
+ var log = function (level) {
13
+ var _a, _b;
14
+ var messages = [];
15
+ for (var _i = 1; _i < arguments.length; _i++) {
16
+ messages[_i - 1] = arguments[_i];
17
+ }
18
+ console.log("[".concat(new Date().toISOString(), "] -").concat(level, "- ").concat((_b = (_a = messages === null || messages === void 0 ? void 0 : messages.join) === null || _a === void 0 ? void 0 : _a.call(messages, ' ')) !== null && _b !== void 0 ? _b : ''));
19
+ switch (level) {
20
+ case 'error':
21
+ process.exit(1);
22
+ default:
23
+ break;
24
+ }
25
+ };
26
+ var handleGetVirtualEntryFileContent = function (buildEntryFilePath) {
50
27
  return [
51
28
  "import 'reflect-metadata';",
52
29
  "import { ModelUtil, NestFactory, isApplication } from '@open-norantec/herbal';",
53
30
  "import { LoggerService } from '@open-norantec/herbal/dist/modules/logger/logger.service';",
54
31
  "import { Worker, isMainThread, workerData } from 'node:worker_threads';",
55
- "import ENTRY from '".concat(entryFilePath, "';"),
32
+ "import ENTRY from '".concat(buildEntryFilePath, "';"),
56
33
  '\nasync function bootstrap() {',
57
34
  ' if (!isApplication(ENTRY)) {',
58
35
  ' console.log(`The entry file must export an application or a function that returns an application.`);',
@@ -112,69 +89,108 @@ var getEntryFileContent = function (_a) {
112
89
  '\nbootstrap();',
113
90
  ].join('\n');
114
91
  };
115
- var handleLog = function (level, message) {
116
- console.log("[".concat(new Date().toISOString(), "] [").concat(level, "] ").concat(message));
117
- switch (level) {
118
- case 'error':
119
- process.exit(1);
120
- default:
121
- break;
92
+ var handleGetFileContent = function (filePath) {
93
+ var content = _.attempt(function () { return fs.readFileSync(filePath, 'utf-8'); });
94
+ if (content instanceof Error) {
95
+ log('error', "Failed to read file content for ".concat(filePath, ":"), content.message);
96
+ return '';
122
97
  }
98
+ return content;
99
+ };
100
+ var handleGetWatcher = function (callback) {
101
+ var watcher = fs.watch(process.cwd(), { recursive: true }, function (eventType, filename) {
102
+ callback(path.resolve(filename));
103
+ });
104
+ return { close: watcher.close.bind(watcher) };
123
105
  };
106
+ var createHandleOutputFile = function (disableWriteFile) { return function (filePath, content) {
107
+ if (!disableWriteFile) {
108
+ var dir_1 = path.dirname(filePath);
109
+ if (!fs.existsSync(dir_1) || !fs.statSync(dir_1).isDirectory()) {
110
+ _.attempt(function () { return fs.removeSync(dir_1); });
111
+ _.attempt(function () { return fs.mkdirpSync(dir_1); });
112
+ }
113
+ _.attempt(function () { return fs.writeFileSync(filePath, content, 'utf-8'); });
114
+ log('info', "Generated file: ".concat(filePath));
115
+ }
116
+ }; };
124
117
  command
125
- .addCommand((0, forge_1.createForgeCommand)({
126
- onLog: handleLog,
127
- getEntryFileContent: getEntryFileContent,
128
- hideOptions: ['--after-emit-action', '--ts-compiler', '--mode'],
129
- mode: 'production',
130
- afterEmitAction: 'none',
131
- }).name('build'))
132
- .addCommand((0, forge_1.createForgeCommand)({
133
- onLog: handleLog,
134
- getEntryFileContent: getEntryFileContent,
135
- hideOptions: ['--after-emit-action', '--ts-compiler'],
136
- mode: 'development',
137
- afterEmitAction: 'watch',
138
- }).name('watch'))
139
- .addCommand((function () {
140
- var subCommand = new commander_1.Command('generate-client');
141
- subCommand
142
- .requiredOption('--entry <entry>', 'The entry file path of the application. It must export an instance generated with `createClient` to default.')
143
- .requiredOption('--output-file <path>', 'The output file path of the generated client source file.')
144
- .option('--group <group>', 'The group name of the generated client. It is used to distinguish different clients when there are multiple clients in the same application.')
145
- .action(function (options) { return __awaiter(void 0, void 0, void 0, function () {
146
- var clientUtil;
147
- return __generator(this, function (_a) {
148
- switch (_a.label) {
149
- case 0:
150
- clientUtil = _.attempt(function () {
151
- return new utilities_1.ClientUtil(options, function (absoluteOutputFile, content) {
152
- var absoluteOutputDir = path.dirname(absoluteOutputFile);
153
- if (!fs.existsSync(absoluteOutputDir) || !fs.statSync(absoluteOutputDir).isDirectory()) {
154
- _.attempt(function () { return fs.removeSync(absoluteOutputDir); });
155
- _.attempt(function () { return fs.mkdirpSync(absoluteOutputDir); });
156
- }
157
- var writeResult = attempt_util_class_1.AttemptUtil.exec(function () {
158
- return fs.writeFileSync(absoluteOutputFile, content, { encoding: 'utf-8' });
159
- });
160
- if (writeResult instanceof Error) {
161
- handleLog === null || handleLog === void 0 ? void 0 : handleLog('error', "Failed to write client code: ".concat(writeResult.message));
162
- return;
163
- }
164
- handleLog === null || handleLog === void 0 ? void 0 : handleLog('info', "Client code generated successfully at ".concat(absoluteOutputFile));
165
- }, handleLog);
166
- });
167
- if (clientUtil instanceof Error) {
168
- handleLog('error', "Failed to initialize the client utility: ".concat(clientUtil.message));
169
- return [2];
170
- }
171
- return [4, clientUtil.generateClientCode()];
172
- case 1:
173
- _a.sent();
174
- return [2];
118
+ .addCommand((0, forge_1.createCommand)({
119
+ name: 'build',
120
+ hiddenOptions: ['--watch', '--execute-after-build'],
121
+ onLog: log,
122
+ defaultOptions: function (source, output, options) { return ({
123
+ getWatcher: handleGetWatcher,
124
+ getVirtualEntryFileContent: handleGetVirtualEntryFileContent,
125
+ onGetFileContent: handleGetFileContent,
126
+ onOutputFile: createHandleOutputFile(!!(options === null || options === void 0 ? void 0 : options.disableWriteFile)),
127
+ }); },
128
+ }))
129
+ .addCommand((0, forge_1.createCommand)({
130
+ name: 'watch',
131
+ hiddenOptions: [
132
+ '--watch',
133
+ '--execute-after-build',
134
+ '--obfuscate',
135
+ '--obfuscator-config-file <string>',
136
+ '--disable-write-file',
137
+ ],
138
+ onLog: log,
139
+ defaultOptions: function () { return ({
140
+ watch: true,
141
+ executeAfterBuild: true,
142
+ obfuscate: false,
143
+ getWatcher: handleGetWatcher,
144
+ getVirtualEntryFileContent: handleGetVirtualEntryFileContent,
145
+ onGetFileContent: handleGetFileContent,
146
+ onOutputFile: createHandleOutputFile(true),
147
+ }); },
148
+ }))
149
+ .addCommand((0, forge_1.createCommand)({
150
+ name: 'generate-client',
151
+ onLog: log,
152
+ hiddenOptions: [
153
+ '--watch',
154
+ '--execute-after-build',
155
+ '--obfuscate',
156
+ '--obfuscator-config-file <string>',
157
+ '--disable-write-file',
158
+ ],
159
+ defaultOptions: function () { return ({
160
+ watch: false,
161
+ executeAfterBuild: false,
162
+ obfuscate: false,
163
+ customTransformers: function (program) {
164
+ return {
165
+ before: [(0, reflect_declaration_1.transformer)(program)],
166
+ };
167
+ },
168
+ getWatcher: handleGetWatcher,
169
+ onGetFileContent: handleGetFileContent,
170
+ onOutputFile: createHandleOutputFile(false),
171
+ getVirtualEntryFileContent: function (buildEntryFilePath) {
172
+ return [
173
+ "const entry = require('".concat(buildEntryFilePath, "')"),
174
+ "const { Client } = require(\'@open-norantec/herbal\')",
175
+ 'module.exports = () => {',
176
+ ' let client = entry;',
177
+ ' if (!(client instanceof Client)) { client = entry?.default; }',
178
+ " if (!(client instanceof Client)) return '';",
179
+ " try { return client?.generateClientSourceFile?.() ?? ''; } catch { return ''; }",
180
+ '};',
181
+ ].join('\n');
182
+ },
183
+ rewriteOutputFile: function (code) {
184
+ try {
185
+ var generateCodeMethod = requireFromString(code);
186
+ if (typeof generateCodeMethod !== 'function')
187
+ return '';
188
+ return generateCodeMethod();
189
+ }
190
+ catch (_a) {
191
+ return '';
175
192
  }
176
- });
177
- }); });
178
- return subCommand;
179
- })());
193
+ },
194
+ }); },
195
+ }));
180
196
  command.parse(process.argv);
package/dist/create.d.ts CHANGED
@@ -1,6 +1,7 @@
1
1
  import 'reflect-metadata';
2
2
  import { CorsOptions, CorsOptionsDelegate } from '@nestjs/common/interfaces/external/cors-options.interface';
3
3
  import { Constructor } from 'type-fest';
4
+ import { GroupsFactory } from './decorators/client-groups.decorator';
4
5
  import { CanActivate, ExceptionFilter, INestApplication, NestApplicationOptions, NestInterceptor, PipeTransform, WebSocketAdapter } from '@nestjs/common';
5
6
  export type Resolver = <T>(Class: Constructor<T>) => Promise<T>;
6
7
  export type TypeCustomizerFn = (dataTypeMapName: string, name: string, genericName: string) => string[];
@@ -21,7 +22,7 @@ export interface CreateApplicationOptions {
21
22
  }
22
23
  export interface CreateClientOptions {
23
24
  Module: Constructor<any>;
24
- allowedClientGroupsFactory?: (currentGroup: string | undefined, defaultGroupName: string) => string[] | null | undefined;
25
+ allowedClientGroupsFactory?: GroupsFactory;
25
26
  }
26
27
  declare class Application {
27
28
  readonly options: CreateApplicationOptions;
@@ -37,7 +38,7 @@ export declare abstract class Client {
37
38
  declare class TypeScriptClient extends Client implements Client {
38
39
  readonly options: CreateClientOptions;
39
40
  constructor(options: CreateClientOptions);
40
- generateClientSourceFile(currentGroup?: string): string;
41
+ generateClientSourceFile(): string;
41
42
  }
42
43
  export declare function isClient(input: any): boolean;
43
44
  export declare function createTypeScriptClient(options: CreateClientOptions): TypeScriptClient;
package/dist/create.js CHANGED
@@ -51,7 +51,7 @@ var TypeScriptClient = (function (_super) {
51
51
  _this.options = options;
52
52
  return _this;
53
53
  }
54
- TypeScriptClient.prototype.generateClientSourceFile = function (currentGroup) {
54
+ TypeScriptClient.prototype.generateClientSourceFile = function () {
55
55
  var options = this.options;
56
56
  if (!(options === null || options === void 0 ? void 0 : options.Module))
57
57
  throw new Error("Parameter 'Module' must be specified");
@@ -80,7 +80,7 @@ var TypeScriptClient = (function (_super) {
80
80
  !metadataName.startsWith(reflect_declaration_1.DECORATOR_NAME_PREFIX) ||
81
81
  !client_groups_decorator_1.ClientGroups.shouldShowInClient(Class, methodName, function (defaultGroupName) {
82
82
  var _a;
83
- return (_a = options.allowedClientGroupsFactory) === null || _a === void 0 ? void 0 : _a.call(options, currentGroup, defaultGroupName);
83
+ return (_a = options.allowedClientGroupsFactory) === null || _a === void 0 ? void 0 : _a.call(options, defaultGroupName);
84
84
  })) {
85
85
  return result;
86
86
  }
@@ -1,3 +1,3 @@
1
1
  import * as ts from 'typescript';
2
2
  export declare const DECORATOR_NAME_PREFIX = "\u03A6nt:method:";
3
- export default function transformer(program: ts.Program): ts.TransformerFactory<ts.SourceFile>;
3
+ export declare function transformer(program: ts.Program): ts.TransformerFactory<ts.SourceFile>;
@@ -9,7 +9,7 @@ var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) {
9
9
  return to.concat(ar || Array.prototype.slice.call(from));
10
10
  };
11
11
  Object.defineProperty(exports, "__esModule", { value: true });
12
- exports.DECORATOR_NAME_PREFIX = void 0;
12
+ exports.transformer = exports.DECORATOR_NAME_PREFIX = void 0;
13
13
  var ts = require("typescript");
14
14
  exports.DECORATOR_NAME_PREFIX = 'Φnt:method:';
15
15
  function transformer(program) {
@@ -60,4 +60,4 @@ function transformer(program) {
60
60
  };
61
61
  };
62
62
  }
63
- exports.default = transformer;
63
+ exports.transformer = transformer;
@@ -1,4 +1,3 @@
1
1
  export * from './controller-util.class';
2
2
  export * from './model-util.class';
3
3
  export * from './nest-util.class';
4
- export * from './client-util.class';
@@ -17,4 +17,3 @@ Object.defineProperty(exports, "__esModule", { value: true });
17
17
  __exportStar(require("./controller-util.class"), exports);
18
18
  __exportStar(require("./model-util.class"), exports);
19
19
  __exportStar(require("./nest-util.class"), exports);
20
- __exportStar(require("./client-util.class"), exports);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@open-norantec/herbal",
3
- "version": "1.0.2-alpha.13",
3
+ "version": "1.0.2-alpha.15",
4
4
  "description": "Herbal is a builder and toolchain for Nest.js applications",
5
5
  "main": "dist/index.js",
6
6
  "scripts": {
@@ -35,49 +35,34 @@
35
35
  "typescript": ">=5.1.0 <5.2.0"
36
36
  },
37
37
  "dependencies": {
38
- "@alcalzone/esm2cjs": "^1.4.2",
39
- "@babel/core": "^7.29.0",
40
- "@babel/plugin-transform-modules-commonjs": "^7.28.6",
41
38
  "@nestjs/common": "^10.0.0",
42
39
  "@nestjs/core": "^10.4.19",
43
40
  "@nestjs/sequelize": "^10.0.1",
44
- "@open-norantec/forge": "latest",
41
+ "@open-norantec/forge": "^2.0.0-alpha.5",
45
42
  "@open-norantec/utilities": "latest",
46
43
  "commander": "^12.1.0",
47
- "es-module-lexer": "^2.0.0",
48
- "esbuild": "^0.28.0",
49
44
  "fs-extra": "^11.3.4",
50
45
  "lodash": "^4.17.21",
51
46
  "nest-winston": "^1.10.2",
52
47
  "nj-request-scope": "^1.0.10",
53
48
  "patch-package": "^8.0.1",
54
49
  "reflect-metadata": "^0.2.2",
55
- "require-from-string": "^2.0.2",
56
50
  "rxjs": "^7.8.2",
57
51
  "sequelize": "6.37.7",
58
52
  "sequelize-typescript": "^2.1.5",
59
- "ts-patch": "^3.3.0",
60
53
  "type-fest": "^4.41.0",
61
54
  "typescript": ">=5.1.0 <5.2.0",
62
55
  "uuid": "^11.1.0",
63
56
  "zod": "^3.25.67"
64
57
  },
65
58
  "devDependencies": {
66
- "@stylistic/eslint-plugin": "^2.12.1",
67
- "@types/babel__core": "^7.20.5",
68
59
  "@types/express": "^5.0.3",
69
60
  "@types/fs-extra": "^11.0.4",
70
61
  "@types/lodash": "^4.17.16",
71
62
  "@types/node": "18.11.18",
72
- "@types/require-from-string": "^1.2.3",
73
- "@typescript-eslint/eslint-plugin": "^8.0.0",
74
- "@typescript-eslint/parser": "^8.0.0",
75
63
  "cross-env": "^7.0.3",
76
64
  "eslint": "^8.0.0",
77
- "eslint-config-prettier": "^9.0.0",
78
- "eslint-plugin-prettier": "^5.0.0",
79
65
  "express": "^4.21.2",
80
- "prettier": "^3.0.0",
81
66
  "rimraf": "^6.0.1",
82
67
  "ts-node": "^10.0.0"
83
68
  }
@@ -1,28 +0,0 @@
1
- import { Schema } from '@open-norantec/utilities/dist/schema-util.class';
2
- import { z } from 'zod';
3
- declare const OPTIONS_SCHEMA: z.ZodObject<{
4
- entry: z.ZodString;
5
- outputFile: z.ZodString;
6
- group: z.ZodOptional<z.ZodString>;
7
- }, "strip", z.ZodTypeAny, {
8
- entry: string;
9
- outputFile: string;
10
- group?: string | undefined;
11
- }, {
12
- entry: string;
13
- outputFile: string;
14
- group?: string | undefined;
15
- }>;
16
- export declare class ClientUtil {
17
- private readonly inputOptions;
18
- private readonly onFile;
19
- private readonly onLog;
20
- constructor(inputOptions: z.infer<typeof OPTIONS_SCHEMA>, onFile: (filePath: string, content: string) => void, onLog: (level: Schema.LogLevel, message?: string) => void);
21
- protected readonly options: {
22
- entry: string;
23
- outputFile: string;
24
- group?: string | undefined;
25
- };
26
- generateClientCode(): Promise<void>;
27
- }
28
- export {};
@@ -1,294 +0,0 @@
1
- "use strict";
2
- var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
- function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
- return new (P || (P = Promise))(function (resolve, reject) {
5
- function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
- function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
- function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
- step((generator = generator.apply(thisArg, _arguments || [])).next());
9
- });
10
- };
11
- var __generator = (this && this.__generator) || function (thisArg, body) {
12
- var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
13
- return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
14
- function verb(n) { return function (v) { return step([n, v]); }; }
15
- function step(op) {
16
- if (f) throw new TypeError("Generator is already executing.");
17
- while (g && (g = 0, op[0] && (_ = 0)), _) try {
18
- if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
19
- if (y = 0, t) op = [op[0] & 2, t.value];
20
- switch (op[0]) {
21
- case 0: case 1: t = op; break;
22
- case 4: _.label++; return { value: op[1], done: false };
23
- case 5: _.label++; y = op[1]; op = [0]; continue;
24
- case 7: op = _.ops.pop(); _.trys.pop(); continue;
25
- default:
26
- if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
27
- if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
28
- if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
29
- if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
30
- if (t[2]) _.ops.pop();
31
- _.trys.pop(); continue;
32
- }
33
- op = body.call(thisArg, _);
34
- } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
35
- if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
36
- }
37
- };
38
- var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) {
39
- if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
40
- if (ar || !(i in from)) {
41
- if (!ar) ar = Array.prototype.slice.call(from, 0, i);
42
- ar[i] = from[i];
43
- }
44
- }
45
- return to.concat(ar || Array.prototype.slice.call(from));
46
- };
47
- Object.defineProperty(exports, "__esModule", { value: true });
48
- exports.ClientUtil = void 0;
49
- var ts = require("typescript");
50
- var path = require("node:path");
51
- var fs = require("fs-extra");
52
- var _ = require("lodash");
53
- var reflect_declaration_1 = require("../transformers/reflect-declaration");
54
- var esbuild = require("esbuild");
55
- var requireFromString = require("require-from-string");
56
- var utilities_1 = require("@open-norantec/utilities");
57
- var create_1 = require("../create");
58
- var zod_1 = require("zod");
59
- var es_module_lexer_1 = require("es-module-lexer");
60
- var babel = require("@babel/core");
61
- var module = require("node:module");
62
- var OPTIONS_SCHEMA = zod_1.z.object({
63
- entry: zod_1.z.string(),
64
- outputFile: zod_1.z.string(),
65
- group: zod_1.z.string().optional(),
66
- });
67
- function maybeESModule(code) {
68
- return __awaiter(this, void 0, void 0, function () {
69
- var _a, imports, exports;
70
- return __generator(this, function (_b) {
71
- switch (_b.label) {
72
- case 0: return [4, es_module_lexer_1.init];
73
- case 1:
74
- _b.sent();
75
- _a = (0, es_module_lexer_1.parse)(code), imports = _a[0], exports = _a[1];
76
- return [2, imports.length > 0 || exports.length > 0];
77
- }
78
- });
79
- });
80
- }
81
- var ClientUtil = (function () {
82
- function ClientUtil(inputOptions, onFile, onLog) {
83
- this.inputOptions = inputOptions;
84
- this.onFile = onFile;
85
- this.onLog = onLog;
86
- this.options = OPTIONS_SCHEMA.parse(this.inputOptions);
87
- }
88
- ClientUtil.prototype.generateClientCode = function () {
89
- var _a, _b, _c, _d, _e, _f;
90
- return __awaiter(this, void 0, void 0, function () {
91
- var configPath, configFile, parsed, program, outputMap, outputFile, esbuildResult, text, client, requireResult, clientCode, absoluteOutputFile;
92
- var _this = this;
93
- return __generator(this, function (_g) {
94
- switch (_g.label) {
95
- case 0:
96
- configPath = ts.findConfigFile('.', ts.sys.fileExists, 'tsconfig.json');
97
- configFile = ts.readConfigFile(configPath, ts.sys.readFile);
98
- parsed = ts.parseJsonConfigFileContent(configFile.config, ts.sys, path.dirname(configPath));
99
- parsed.options.configFilePath = configPath;
100
- program = ts.createProgram({ rootNames: parsed.fileNames, options: parsed.options });
101
- outputMap = new Map();
102
- outputFile = _.attempt(function () {
103
- return ts
104
- .getOutputFileNames(parsed, path.relative(process.cwd(), path.resolve(_this.options.entry)), false)
105
- .find(function (filePath) { return filePath.endsWith('.js'); });
106
- });
107
- if (outputFile instanceof Error) {
108
- (_a = this.onLog) === null || _a === void 0 ? void 0 : _a.call(this, 'error', "Failed to determine output file: ".concat(outputFile.message));
109
- return [2];
110
- }
111
- if (typeof outputFile === 'undefined') {
112
- (_b = this.onLog) === null || _b === void 0 ? void 0 : _b.call(this, 'error', 'Failed to determine output file: No .js output file found');
113
- return [2];
114
- }
115
- program.emit(undefined, function (fileName, data) {
116
- var _a;
117
- var absolutePath = path.resolve(fileName);
118
- outputMap.set(absolutePath, data);
119
- (_a = _this.onLog) === null || _a === void 0 ? void 0 : _a.call(_this, 'info', "Compiled ".concat(absolutePath));
120
- }, undefined, false, {
121
- before: [(0, reflect_declaration_1.default)(program)],
122
- });
123
- return [4, utilities_1.AttemptUtil.execPromise(esbuild.build({
124
- entryPoints: [path.resolve(outputFile)],
125
- bundle: true,
126
- platform: 'node',
127
- loader: {
128
- '.node': 'base64',
129
- },
130
- logLevel: 'silent',
131
- packages: 'external',
132
- format: 'cjs',
133
- write: false,
134
- plugins: [
135
- {
136
- name: 'tsconfig-paths',
137
- setup: function (build) {
138
- build.onResolve({ filter: /.*/ }, function (args) {
139
- var _a, _b;
140
- var hasMatchingPath = Object.keys(((_a = parsed.options) === null || _a === void 0 ? void 0 : _a.paths) || {}).some(function (path) {
141
- return new RegExp(path.replace('*', '\\w*')).test(args.path);
142
- });
143
- if (!hasMatchingPath) {
144
- return null;
145
- }
146
- var resolvedModule = ts.nodeModuleNameResolver(args.path, args.importer, parsed.options || {}, ts.sys).resolvedModule;
147
- if (!resolvedModule)
148
- return null;
149
- var resolvedFileName = resolvedModule.resolvedFileName;
150
- if (!resolvedFileName || resolvedFileName.endsWith('.d.ts'))
151
- return null;
152
- var resolved = ts.sys.resolvePath(resolvedFileName);
153
- (_b = _this.onLog) === null || _b === void 0 ? void 0 : _b.call(_this, 'info', "Resolved file using TypeScript paths: ".concat(args.path, " -> ").concat(resolved, ")"));
154
- return { path: resolved };
155
- });
156
- },
157
- },
158
- {
159
- name: 'herbal',
160
- setup: function (build) {
161
- build.onResolve({ filter: /.*/ }, function (args) { return __awaiter(_this, void 0, void 0, function () {
162
- var targetPaths, absoluteImportPath, _i, targetPaths_1, targetPath, requiredPath;
163
- return __generator(this, function (_a) {
164
- if (args.path.startsWith('node:') ||
165
- module.builtinModules.some(function (moduleName) { return args.path.startsWith(moduleName) || args.path.startsWith("".concat(moduleName, "/")); })) {
166
- return [2, { path: args.path, external: true }];
167
- }
168
- if (outputMap.has(args.path))
169
- return [2, { path: args.path, namespace: 'vfs' }];
170
- if (outputMap.has(args.importer)) {
171
- targetPaths = [];
172
- absoluteImportPath = path.resolve(path.dirname(args.importer), args.path);
173
- if (!['.js', '.cjs'].includes(path.extname(absoluteImportPath))) {
174
- targetPaths.push(absoluteImportPath + '.js');
175
- targetPaths.push(absoluteImportPath + '.cjs');
176
- targetPaths.push(path.resolve(absoluteImportPath, 'index.js'));
177
- targetPaths.push(path.resolve(absoluteImportPath, 'index.cjs'));
178
- }
179
- else {
180
- targetPaths.push(absoluteImportPath);
181
- }
182
- for (_i = 0, targetPaths_1 = targetPaths; _i < targetPaths_1.length; _i++) {
183
- targetPath = targetPaths_1[_i];
184
- if (outputMap.has(targetPath)) {
185
- return [2, { path: targetPath, namespace: 'vfs' }];
186
- }
187
- }
188
- }
189
- requiredPath = _.attempt(function () {
190
- return require.resolve(args.path, {
191
- paths: __spreadArray(__spreadArray([], (function () {
192
- var result = [];
193
- var currentDir = path.dirname(args.importer);
194
- result.push(currentDir);
195
- while (currentDir !== path.dirname(currentDir)) {
196
- result.push(path.dirname(currentDir));
197
- currentDir = path.dirname(currentDir);
198
- }
199
- return result;
200
- })(), true), (require.resolve.paths('') || []), true),
201
- });
202
- });
203
- if (!(requiredPath instanceof Error)) {
204
- return [2, { path: requiredPath, namespace: outputMap.has(requiredPath) ? 'vfs' : undefined }];
205
- }
206
- return [2, { path: args.path, external: true }];
207
- });
208
- }); });
209
- build.onLoad({ filter: /.*/, namespace: 'vfs' }, function (args) {
210
- var contents = outputMap.get(args.path);
211
- return {
212
- contents: contents,
213
- loader: 'js',
214
- };
215
- });
216
- build.onLoad({ filter: /node_modules\/.*.(mjs|js)$/ }, function (args) { return __awaiter(_this, void 0, void 0, function () {
217
- var code, transformed;
218
- return __generator(this, function (_a) {
219
- switch (_a.label) {
220
- case 0:
221
- code = fs.readFileSync(args.path, { encoding: 'utf-8' });
222
- return [4, maybeESModule(code)];
223
- case 1:
224
- if (_a.sent()) {
225
- transformed = babel.transformSync(code, {
226
- plugins: [require.resolve('@babel/plugin-transform-modules-commonjs')],
227
- });
228
- return [2, {
229
- contents: (transformed === null || transformed === void 0 ? void 0 : transformed.code) || code,
230
- loader: 'js',
231
- }];
232
- }
233
- return [2, {
234
- contents: code,
235
- loader: 'js',
236
- }];
237
- }
238
- });
239
- }); });
240
- build.onLoad({ filter: /.*/, namespace: 'json' }, function (args) {
241
- var contents = fs.readJsonSync(args.path, { encoding: 'utf-8' });
242
- return {
243
- contents: "module.exports = ".concat(JSON.stringify(contents)),
244
- loader: 'js',
245
- };
246
- });
247
- },
248
- },
249
- ],
250
- }))];
251
- case 1:
252
- esbuildResult = _g.sent();
253
- if (esbuildResult instanceof Error) {
254
- (_c = this.onLog) === null || _c === void 0 ? void 0 : _c.call(this, 'error', "Failed to build client code: ".concat(esbuildResult.message));
255
- return [2];
256
- }
257
- if (esbuildResult.errors.length > 0) {
258
- this.onLog('error', "Builder built with error: ".concat(esbuildResult.errors[0].text));
259
- return [2];
260
- }
261
- text = esbuildResult.outputFiles[0].text;
262
- client = undefined;
263
- fs.writeFileSync(path.resolve('dist/test.js'), text, { encoding: 'utf-8' });
264
- try {
265
- requireResult = requireFromString(text, { appendPaths: [path.resolve(process.cwd())] });
266
- client = requireResult;
267
- if (!(client instanceof create_1.Client))
268
- client = client === null || client === void 0 ? void 0 : client.default;
269
- }
270
- catch (error) {
271
- if (error instanceof Error) {
272
- (_d = this.onLog) === null || _d === void 0 ? void 0 : _d.call(this, 'error', "Failed to load client code: ".concat(error.message));
273
- }
274
- }
275
- console.log('LENCONDA:test', client instanceof create_1.Client);
276
- if (!(typeof (client === null || client === void 0 ? void 0 : client.generateClientSourceFile) === 'function')) {
277
- (_e = this.onLog) === null || _e === void 0 ? void 0 : _e.call(this, 'error', 'Failed to load client code');
278
- return [2];
279
- }
280
- clientCode = _.attempt(function () { return client.generateClientSourceFile(_this.options.group); });
281
- if (clientCode instanceof Error) {
282
- (_f = this.onLog) === null || _f === void 0 ? void 0 : _f.call(this, 'error', "Failed to generate client code: ".concat(clientCode.message));
283
- return [2];
284
- }
285
- absoluteOutputFile = path.resolve(this.options.outputFile);
286
- this.onFile(absoluteOutputFile, clientCode);
287
- return [2];
288
- }
289
- });
290
- });
291
- };
292
- return ClientUtil;
293
- }());
294
- exports.ClientUtil = ClientUtil;