@open-norantec/herbal 1.0.2-alpha.14 → 1.0.2-alpha.16

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.
@@ -7,6 +7,7 @@ var _ = require("lodash");
7
7
  var fs = require("fs-extra");
8
8
  var path = require("node:path");
9
9
  var requireFromString = require("require-from-string");
10
+ var reflect_declaration_1 = require("../transformers/reflect-declaration");
10
11
  var command = new commander_1.Command('herbal');
11
12
  var log = function (level) {
12
13
  var _a, _b;
@@ -159,6 +160,11 @@ command
159
160
  watch: false,
160
161
  executeAfterBuild: false,
161
162
  obfuscate: false,
163
+ customTransformers: function (program) {
164
+ return {
165
+ before: [(0, reflect_declaration_1.transformer)(program)],
166
+ };
167
+ },
162
168
  getWatcher: handleGetWatcher,
163
169
  onGetFileContent: handleGetFileContent,
164
170
  onOutputFile: createHandleOutputFile(false),
package/dist/core.d.ts CHANGED
@@ -3,7 +3,7 @@ import { HeaderUtil } from '@open-norantec/utilities/dist/header-util.class';
3
3
  import { z } from 'zod';
4
4
  import { Request } from './types/request.type';
5
5
  export * from '@nestjs/core';
6
- export interface MethodContext<IS extends z.Schema<any>> {
6
+ interface LegacyMethodContext<IS extends z.Schema<any>> {
7
7
  headers: ReturnType<typeof HeaderUtil.parse>;
8
8
  input: z.infer<IS>;
9
9
  request: Request;
@@ -13,6 +13,7 @@ export type MethodHandler<IS extends z.Schema<any>, OS extends z.Schema<any>> =
13
13
  response: z.infer<OS>;
14
14
  }>;
15
15
  export declare class HerbalController {
16
- protected registerMethod: <IS extends z.ZodType<any, z.ZodTypeDef, any>, OS extends z.ZodType<any, z.ZodTypeDef, any>>(inputSchema: IS, outputSchema: OS, callback: (context: MethodContext<IS>) => Promise<z.TypeOf<OS>>) => MethodHandler<IS, OS>;
17
- private handler;
16
+ protected registerMethod: <IS extends z.ZodType<any, z.ZodTypeDef, any>, OS extends z.ZodType<any, z.ZodTypeDef, any>>(inputSchema: IS, outputSchema: OS, callback: (context: LegacyMethodContext<IS>) => Promise<z.TypeOf<OS>>) => MethodHandler<IS, OS>;
17
+ private $handleRequest;
18
+ private $call;
18
19
  }
package/dist/core.js CHANGED
@@ -69,6 +69,8 @@ var header_util_class_1 = require("@open-norantec/utilities/dist/header-util.cla
69
69
  var zod_1 = require("zod");
70
70
  var _ = require("lodash");
71
71
  var string_util_class_1 = require("@open-norantec/utilities/dist/string-util.class");
72
+ var decorators_1 = require("./decorators");
73
+ var utilities_1 = require("@open-norantec/utilities");
72
74
  __exportStar(require("@nestjs/core"), exports);
73
75
  var HerbalController = exports.HerbalController = (function () {
74
76
  function HerbalController() {
@@ -101,54 +103,71 @@ var HerbalController = exports.HerbalController = (function () {
101
103
  }); };
102
104
  };
103
105
  }
104
- HerbalController.prototype.handler = function (request) {
105
- var _a, _b, _c, _d, _e, _f;
106
+ HerbalController.prototype.$handleRequest = function (request) {
107
+ var _a, _b, _c, _d;
106
108
  return __awaiter(this, void 0, void 0, function () {
107
- var methodHandler, parsedBody, result, _g, _h, error_1;
108
- var _j;
109
- return __generator(this, function (_k) {
110
- switch (_k.label) {
109
+ var result, error_1;
110
+ var _e;
111
+ var _this = this;
112
+ return __generator(this, function (_f) {
113
+ switch (_f.label) {
111
114
  case 0:
112
- methodHandler = this[request === null || request === void 0 ? void 0 : request.methodName];
113
- parsedBody = _.attempt(function () { return JSON.parse((request === null || request === void 0 ? void 0 : request.rawBody) || ''); });
114
- _k.label = 1;
115
+ _f.trys.push([0, 3, , 5]);
116
+ _e = {};
117
+ return [4, this.$call(request.methodName, {
118
+ authenticateResult: request.authenticateResult,
119
+ headers: header_util_class_1.HeaderUtil.parse((_a = request.headers) !== null && _a !== void 0 ? _a : {}),
120
+ methodName: request.methodName,
121
+ rawBody: request.rawBody,
122
+ traceId: request.traceId,
123
+ transaction: request.transaction,
124
+ url: request.originalUrl,
125
+ getProvider: function (token) { return request.moduleRef.get(token, { strict: false }); },
126
+ })];
115
127
  case 1:
116
- _k.trys.push([1, 12, , 13]);
117
- if (!(typeof methodHandler === 'function')) return [3, 7];
118
- _j = {};
119
- return [4, methodHandler(request, parsedBody instanceof Error ? undefined : parsedBody, header_util_class_1.HeaderUtil.parse((_a = request.headers) !== null && _a !== void 0 ? _a : {})).then(function (response) { return response === null || response === void 0 ? void 0 : response.response; })];
120
- case 2:
121
- result = (_j.data = _k.sent(),
122
- _j.token = string_util_class_1.StringUtil.isFalsyString((_b = request === null || request === void 0 ? void 0 : request.authenticateResult) === null || _b === void 0 ? void 0 : _b.nextToken)
128
+ result = (_e.data = _f.sent(),
129
+ _e.token = string_util_class_1.StringUtil.isFalsyString((_b = request === null || request === void 0 ? void 0 : request.authenticateResult) === null || _b === void 0 ? void 0 : _b.nextToken)
123
130
  ? null
124
131
  : request.authenticateResult.nextToken,
125
- _j);
126
- _k.label = 3;
127
- case 3:
128
- _k.trys.push([3, 5, , 6]);
132
+ _e);
129
133
  return [4, ((_d = (_c = request === null || request === void 0 ? void 0 : request.transaction) === null || _c === void 0 ? void 0 : _c.commit) === null || _d === void 0 ? void 0 : _d.call(_c))];
134
+ case 2:
135
+ _f.sent();
136
+ return [2, result];
137
+ case 3:
138
+ error_1 = _f.sent();
139
+ return [4, utilities_1.AttemptUtil.execPromise((function () { return __awaiter(_this, void 0, void 0, function () {
140
+ var _a, _b;
141
+ return __generator(this, function (_c) {
142
+ switch (_c.label) {
143
+ case 0: return [4, ((_b = (_a = request === null || request === void 0 ? void 0 : request.transaction) === null || _a === void 0 ? void 0 : _a.rollback) === null || _b === void 0 ? void 0 : _b.call(_a))];
144
+ case 1:
145
+ _c.sent();
146
+ return [2];
147
+ }
148
+ });
149
+ }); })())];
130
150
  case 4:
131
- _k.sent();
132
- return [3, 6];
133
- case 5:
134
- _g = _k.sent();
135
- return [3, 6];
136
- case 6: return [2, result];
137
- case 7:
138
- _k.trys.push([7, 9, , 10]);
139
- return [4, ((_f = (_e = request === null || request === void 0 ? void 0 : request.transaction) === null || _e === void 0 ? void 0 : _e.rollback) === null || _f === void 0 ? void 0 : _f.call(_e))];
140
- case 8:
141
- _k.sent();
142
- return [3, 10];
143
- case 9:
144
- _h = _k.sent();
145
- return [3, 10];
146
- case 10: throw new common_1.NotFoundException();
147
- case 11: return [3, 13];
148
- case 12:
149
- error_1 = _k.sent();
151
+ _f.sent();
150
152
  throw error_1;
151
- case 13: return [2];
153
+ case 5: return [2];
154
+ }
155
+ });
156
+ });
157
+ };
158
+ HerbalController.prototype.$call = function (name, context) {
159
+ var _a, _b;
160
+ return __awaiter(this, void 0, void 0, function () {
161
+ var methodConfig;
162
+ return __generator(this, function (_c) {
163
+ switch (_c.label) {
164
+ case 0:
165
+ methodConfig = (_b = (_a = decorators_1.Method.getPool(this)) === null || _a === void 0 ? void 0 : _a.getConfig) === null || _b === void 0 ? void 0 : _b.call(_a, name);
166
+ if (methodConfig === null || typeof methodConfig === 'undefined') {
167
+ throw new common_1.NotFoundException("Method ".concat(name, " not found"));
168
+ }
169
+ return [4, methodConfig.call(context)];
170
+ case 1: return [2, _c.sent()];
152
171
  }
153
172
  });
154
173
  });
@@ -159,6 +178,6 @@ var HerbalController = exports.HerbalController = (function () {
159
178
  __metadata("design:type", Function),
160
179
  __metadata("design:paramtypes", [Object]),
161
180
  __metadata("design:returntype", Promise)
162
- ], HerbalController.prototype, "handler", null);
181
+ ], HerbalController.prototype, "$handleRequest", null);
163
182
  return HerbalController;
164
183
  }());
@@ -1,3 +1,4 @@
1
1
  export * from './auth-adapter.decorator';
2
2
  export * from './client-groups.decorator';
3
3
  export * from './no-transaction.decorator';
4
+ export * from './method.decorator';
@@ -17,3 +17,4 @@ Object.defineProperty(exports, "__esModule", { value: true });
17
17
  __exportStar(require("./auth-adapter.decorator"), exports);
18
18
  __exportStar(require("./client-groups.decorator"), exports);
19
19
  __exportStar(require("./no-transaction.decorator"), exports);
20
+ __exportStar(require("./method.decorator"), exports);
@@ -0,0 +1,41 @@
1
+ import 'reflect-metadata';
2
+ import { z } from 'zod';
3
+ import { AuthAdapter } from '../abstracts';
4
+ import { GroupsFactory } from './client-groups.decorator';
5
+ import { HeaderUtil } from '@open-norantec/utilities/dist/header-util.class';
6
+ import { Constructor } from 'type-fest';
7
+ import { Type } from '@nestjs/common';
8
+ import { RequestContext } from '../types';
9
+ export interface MethodOptions<IS extends z.Schema<any>, OS extends z.Schema<any>> {
10
+ inputSchema: IS;
11
+ outputSchema: OS;
12
+ authAdapters?: AuthAdapter[];
13
+ clientGroups?: GroupsFactory | string[];
14
+ disableTransaction?: boolean;
15
+ }
16
+ export type DependencyGetter = <T>(dependency: Constructor<T>) => T;
17
+ export interface MethodContext<IS extends z.Schema<any>> extends Omit<RequestContext, 'moduleRef'> {
18
+ headers: ReturnType<typeof HeaderUtil.parse>;
19
+ input: z.infer<IS>;
20
+ url: string;
21
+ getProvider: <TInput = any, TResult = TInput>(typeOrToken: Type<TInput> | Function | string | symbol) => TResult;
22
+ }
23
+ export type MethodCallContext<IS extends z.Schema<any>> = Omit<MethodContext<IS>, 'input'>;
24
+ export type MethodCallback<IS extends z.Schema<any>, OS extends z.Schema<any>> = (context: MethodContext<IS>) => Promise<z.infer<OS>>;
25
+ declare class MethodConfig<IS extends z.Schema<any>, OS extends z.Schema<any>> {
26
+ readonly name: string;
27
+ protected readonly options: MethodOptions<IS, OS>;
28
+ protected readonly callback: MethodCallback<IS, OS>;
29
+ constructor(name: string, options: MethodOptions<IS, OS>, callback: MethodCallback<IS, OS>);
30
+ call(callContext: MethodCallContext<IS>): Promise<z.TypeOf<OS>>;
31
+ }
32
+ declare class MethodPool {
33
+ protected readonly methods: Map<string, MethodConfig<any, any>>;
34
+ registerMethod<IS extends z.Schema<any>, OS extends z.Schema<any>>(name: string, options: MethodOptions<IS, OS>, callback: MethodCallback<IS, OS>): void;
35
+ getConfig(name: string): MethodConfig<any, any> | null;
36
+ }
37
+ export declare function Method<IS extends z.Schema<any>, OS extends z.Schema<any>>(...parameters: Parameters<typeof MethodPool.prototype.registerMethod<IS, OS>>): ClassDecorator;
38
+ export declare namespace Method {
39
+ var getPool: (targetPrototype: object) => MethodPool | null;
40
+ }
41
+ export {};
@@ -0,0 +1,144 @@
1
+ "use strict";
2
+ var __assign = (this && this.__assign) || function () {
3
+ __assign = Object.assign || function(t) {
4
+ for (var s, i = 1, n = arguments.length; i < n; i++) {
5
+ s = arguments[i];
6
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
7
+ t[p] = s[p];
8
+ }
9
+ return t;
10
+ };
11
+ return __assign.apply(this, arguments);
12
+ };
13
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
14
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
15
+ return new (P || (P = Promise))(function (resolve, reject) {
16
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
17
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
18
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
19
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
20
+ });
21
+ };
22
+ var __generator = (this && this.__generator) || function (thisArg, body) {
23
+ var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
24
+ return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
25
+ function verb(n) { return function (v) { return step([n, v]); }; }
26
+ function step(op) {
27
+ if (f) throw new TypeError("Generator is already executing.");
28
+ while (g && (g = 0, op[0] && (_ = 0)), _) try {
29
+ 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;
30
+ if (y = 0, t) op = [op[0] & 2, t.value];
31
+ switch (op[0]) {
32
+ case 0: case 1: t = op; break;
33
+ case 4: _.label++; return { value: op[1], done: false };
34
+ case 5: _.label++; y = op[1]; op = [0]; continue;
35
+ case 7: op = _.ops.pop(); _.trys.pop(); continue;
36
+ default:
37
+ if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
38
+ if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
39
+ if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
40
+ if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
41
+ if (t[2]) _.ops.pop();
42
+ _.trys.pop(); continue;
43
+ }
44
+ op = body.call(thisArg, _);
45
+ } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
46
+ if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
47
+ }
48
+ };
49
+ Object.defineProperty(exports, "__esModule", { value: true });
50
+ exports.Method = void 0;
51
+ require("reflect-metadata");
52
+ var zod_1 = require("zod");
53
+ var utilities_1 = require("@open-norantec/utilities");
54
+ var common_1 = require("@nestjs/common");
55
+ var _ = require("lodash");
56
+ var METHOD_POOL = Symbol();
57
+ var MethodConfig = (function () {
58
+ function MethodConfig(name, options, callback) {
59
+ this.name = name;
60
+ this.options = options;
61
+ this.callback = callback;
62
+ }
63
+ MethodConfig.prototype.call = function (callContext) {
64
+ var _a, _b, _c, _d, _e, _f;
65
+ return __awaiter(this, void 0, void 0, function () {
66
+ var parsedBody_1, input, rawResponse_1, response, error_1;
67
+ var _this = this;
68
+ return __generator(this, function (_g) {
69
+ switch (_g.label) {
70
+ case 0:
71
+ _g.trys.push([0, 2, , 3]);
72
+ parsedBody_1 = _.attempt(function () { return JSON.parse((callContext === null || callContext === void 0 ? void 0 : callContext.rawBody) || ''); });
73
+ input = _.attempt(function () {
74
+ return parsedBody_1 instanceof Error ? undefined : _this.options.inputSchema.parse(parsedBody_1);
75
+ });
76
+ if (input instanceof zod_1.ZodError) {
77
+ throw new common_1.BadRequestException({
78
+ from: 'request',
79
+ invalidParams: (_c = (_b = (_a = input === null || input === void 0 ? void 0 : input.issues) === null || _a === void 0 ? void 0 : _a.map) === null || _b === void 0 ? void 0 : _b.call(_a, function (item) { var _a, _b; return (_b = (_a = item === null || item === void 0 ? void 0 : item.path) === null || _a === void 0 ? void 0 : _a.join) === null || _b === void 0 ? void 0 : _b.call(_a, '.'); })) !== null && _c !== void 0 ? _c : [],
80
+ });
81
+ }
82
+ else if (input instanceof Error)
83
+ throw input;
84
+ return [4, this.callback(__assign(__assign({}, callContext), { input: input }))];
85
+ case 1:
86
+ rawResponse_1 = _g.sent();
87
+ response = _.attempt(function () { return _this.options.outputSchema.parse(rawResponse_1); });
88
+ if (response instanceof zod_1.ZodError) {
89
+ throw new common_1.BadRequestException({
90
+ from: 'response',
91
+ invalidParams: (_f = (_e = (_d = response === null || response === void 0 ? void 0 : response.issues) === null || _d === void 0 ? void 0 : _d.map) === null || _e === void 0 ? void 0 : _e.call(_d, function (item) { var _a, _b; return (_b = (_a = item === null || item === void 0 ? void 0 : item.path) === null || _a === void 0 ? void 0 : _a.join) === null || _b === void 0 ? void 0 : _b.call(_a, '.'); })) !== null && _f !== void 0 ? _f : [],
92
+ });
93
+ }
94
+ else if (response instanceof Error)
95
+ throw response;
96
+ return [2, response];
97
+ case 2:
98
+ error_1 = _g.sent();
99
+ throw error_1;
100
+ case 3: return [2];
101
+ }
102
+ });
103
+ });
104
+ };
105
+ return MethodConfig;
106
+ }());
107
+ var MethodPool = (function () {
108
+ function MethodPool() {
109
+ this.methods = new Map();
110
+ }
111
+ MethodPool.prototype.registerMethod = function (name, options, callback) {
112
+ if (utilities_1.StringUtil.isFalsyString(name))
113
+ return;
114
+ if (name.includes('/'))
115
+ throw new Error("Method name cannot contain slashes: ".concat(name));
116
+ this.methods.set(name, new MethodConfig(name, options, callback));
117
+ };
118
+ MethodPool.prototype.getConfig = function (name) {
119
+ var config = this.methods.get(name);
120
+ return config instanceof MethodConfig ? config : null;
121
+ };
122
+ return MethodPool;
123
+ }());
124
+ function Method() {
125
+ var parameters = [];
126
+ for (var _i = 0; _i < arguments.length; _i++) {
127
+ parameters[_i] = arguments[_i];
128
+ }
129
+ return function (target) {
130
+ var pool = Reflect.getMetadata(METHOD_POOL, target.prototype);
131
+ if (!(pool instanceof MethodPool)) {
132
+ pool = new MethodPool();
133
+ Reflect.defineMetadata(METHOD_POOL, pool, target.prototype);
134
+ }
135
+ pool.registerMethod.apply(pool, parameters);
136
+ };
137
+ }
138
+ exports.Method = Method;
139
+ Method.getPool = function (targetPrototype) {
140
+ var pool = Reflect.getMetadata(METHOD_POOL, targetPrototype);
141
+ if (!(pool instanceof MethodPool))
142
+ return null;
143
+ return pool;
144
+ };
@@ -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,10 +1,13 @@
1
1
  import { Request as ExpressRequest } from 'express';
2
2
  import { AuthenticateResult } from '../abstracts/auth-adapter.abstract.class';
3
3
  import { Transaction } from 'sequelize';
4
- export type Request = ExpressRequest & {
4
+ import { ModuleRef } from '@nestjs/core';
5
+ export interface RequestContext {
5
6
  methodName: string;
7
+ moduleRef: ModuleRef;
6
8
  rawBody: string | null;
7
9
  traceId: string;
8
10
  authenticateResult?: AuthenticateResult;
9
11
  transaction?: Transaction;
10
- };
12
+ }
13
+ export type Request = ExpressRequest & RequestContext;
@@ -173,6 +173,7 @@ function HerbalGuard(options) {
173
173
  traceId = uuid_util_class_1.UUIDUtil.generateV4();
174
174
  request.traceId = traceId;
175
175
  request.methodName = request.url.split('/').pop();
176
+ request.moduleRef = this.ref;
176
177
  response.setHeader(headers_constant_1.HEADERS.TRACE_ID, traceId);
177
178
  chunks = [];
178
179
  _p.label = 1;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@open-norantec/herbal",
3
- "version": "1.0.2-alpha.14",
3
+ "version": "1.0.2-alpha.16",
4
4
  "description": "Herbal is a builder and toolchain for Nest.js applications",
5
5
  "main": "dist/index.js",
6
6
  "scripts": {
@@ -38,13 +38,14 @@
38
38
  "@nestjs/common": "^10.0.0",
39
39
  "@nestjs/core": "^10.4.19",
40
40
  "@nestjs/sequelize": "^10.0.1",
41
- "@open-norantec/forge": "^2.0.0-alpha.3",
41
+ "@open-norantec/forge": "^2.0.0-alpha.5",
42
42
  "@open-norantec/utilities": "latest",
43
43
  "commander": "^12.1.0",
44
44
  "fs-extra": "^11.3.4",
45
45
  "lodash": "^4.17.21",
46
46
  "nest-winston": "^1.10.2",
47
47
  "nj-request-scope": "^1.0.10",
48
+ "openapi-types": "^12.1.3",
48
49
  "patch-package": "^8.0.1",
49
50
  "reflect-metadata": "^0.2.2",
50
51
  "rxjs": "^7.8.2",
@@ -56,7 +57,6 @@
56
57
  "zod": "^3.25.67"
57
58
  },
58
59
  "devDependencies": {
59
- "@types/babel__core": "^7.20.5",
60
60
  "@types/express": "^5.0.3",
61
61
  "@types/fs-extra": "^11.0.4",
62
62
  "@types/lodash": "^4.17.16",
@@ -64,7 +64,6 @@
64
64
  "cross-env": "^7.0.3",
65
65
  "eslint": "^8.0.0",
66
66
  "express": "^4.21.2",
67
- "prettier": "^3.0.0",
68
67
  "rimraf": "^6.0.1",
69
68
  "ts-node": "^10.0.0"
70
69
  }