@swizzyweb/swerve-manager 0.1.5 → 0.1.7
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/README.md +11 -1
- package/dist/swerve.d.ts +6 -1
- package/dist/swerve.js +36 -12
- package/dist/utils/getFullImportPath.d.ts +1 -0
- package/dist/utils/getFullImportPath.js +29 -0
- package/package.json +4 -5
- package/src/swerve.ts +46 -15
- package/src/utils/getFullImportPath.ts +31 -0
- package/test/getArgs.spec.ts +253 -255
package/README.md
CHANGED
|
@@ -3,6 +3,10 @@
|
|
|
3
3
|
swizzy-swerve is a bootstrapper for swizzy web services. This package will bootstrap and run
|
|
4
4
|
independent swizzy web services.
|
|
5
5
|
|
|
6
|
+
## Docs
|
|
7
|
+
|
|
8
|
+
https://swizzyweb.github.io/swerve-manager/
|
|
9
|
+
|
|
6
10
|
### Supported commands
|
|
7
11
|
|
|
8
12
|
swerve: synonym for swerven
|
|
@@ -201,7 +205,7 @@ appDataPath: "/appDataRoot/appdata/serviceName/"
|
|
|
201
205
|
},
|
|
202
206
|
"friendlyImportServiceName": {
|
|
203
207
|
"port": 3002,
|
|
204
|
-
"
|
|
208
|
+
"packageName": "@swizzyweb/dyn-serve-web-service" // running installed web service package
|
|
205
209
|
},
|
|
206
210
|
"friendlyNeighborServiceName": {
|
|
207
211
|
"port": 3002,
|
|
@@ -217,3 +221,9 @@ appDataPath: "/appDataRoot/appdata/serviceName/"
|
|
|
217
221
|
```
|
|
218
222
|
swerve --config my-web-service-config.json
|
|
219
223
|
```
|
|
224
|
+
|
|
225
|
+
# Generate Docs
|
|
226
|
+
|
|
227
|
+
```
|
|
228
|
+
npx typedoc
|
|
229
|
+
```
|
package/dist/swerve.d.ts
CHANGED
|
@@ -50,6 +50,8 @@ export type Apps = {
|
|
|
50
50
|
export interface SwerveManagerProps {
|
|
51
51
|
apps?: Apps;
|
|
52
52
|
webServices?: WebService<any>[];
|
|
53
|
+
nodeModulesPath?: string;
|
|
54
|
+
logger?: ILogger<any> | undefined;
|
|
53
55
|
}
|
|
54
56
|
export interface WebServiceConfiguration {
|
|
55
57
|
}
|
|
@@ -60,13 +62,15 @@ export declare class SwerveManager implements ISwerveManager {
|
|
|
60
62
|
apps: Apps;
|
|
61
63
|
webServices: WebService<any>[];
|
|
62
64
|
configurations: WebServiceConfigurations;
|
|
65
|
+
nodeModulesPath: string;
|
|
66
|
+
logger: ILogger<any>;
|
|
63
67
|
constructor(props: SwerveManagerProps);
|
|
64
68
|
run(request: RunRequest): Promise<RunResponse>;
|
|
65
69
|
runWithArgs(request: RunRequest): Promise<WebService<any>[]>;
|
|
66
70
|
private runWithApp;
|
|
67
71
|
installWebService(props: {
|
|
68
72
|
serviceKey: string;
|
|
69
|
-
|
|
73
|
+
servicePath: string;
|
|
70
74
|
app: Application;
|
|
71
75
|
appDataRoot: string;
|
|
72
76
|
packageName: string;
|
|
@@ -76,6 +80,7 @@ export declare class SwerveManager implements ISwerveManager {
|
|
|
76
80
|
[key: string]: any;
|
|
77
81
|
};
|
|
78
82
|
}): Promise<any>;
|
|
83
|
+
getImportName(packageName: string, servicePath: string): Promise<string>;
|
|
79
84
|
stop(request: StopRequest): Promise<void>;
|
|
80
85
|
getRunningWebServices(props: GetRunningWebServiceRequest): Promise<GetRunningWebServiceResponse>;
|
|
81
86
|
}
|
package/dist/swerve.js
CHANGED
|
@@ -6,7 +6,7 @@ import os from "node:os";
|
|
|
6
6
|
import process from "node:process";
|
|
7
7
|
import path from "node:path";
|
|
8
8
|
import { mkdirSync } from "node:fs";
|
|
9
|
-
import { getFullImportPath } from "./utils/getFullImportPath.js";
|
|
9
|
+
import { getFullImportPath, resolvePackageEntry, } from "./utils/getFullImportPath.js";
|
|
10
10
|
export var InstanceType;
|
|
11
11
|
(function (InstanceType) {
|
|
12
12
|
InstanceType["webservice"] = "webservice";
|
|
@@ -16,9 +16,19 @@ export class SwerveManager {
|
|
|
16
16
|
apps;
|
|
17
17
|
webServices;
|
|
18
18
|
configurations;
|
|
19
|
+
nodeModulesPath;
|
|
20
|
+
logger;
|
|
19
21
|
constructor(props) {
|
|
20
22
|
this.apps = props.apps ?? {};
|
|
21
23
|
this.webServices = props.webServices ?? [];
|
|
24
|
+
this.nodeModulesPath = props.nodeModulesPath;
|
|
25
|
+
this.logger =
|
|
26
|
+
props.logger ??
|
|
27
|
+
new SwizzyWinstonLogger({
|
|
28
|
+
appName: "swerve-manager",
|
|
29
|
+
port: -1,
|
|
30
|
+
hostName: os.hostname(),
|
|
31
|
+
});
|
|
22
32
|
}
|
|
23
33
|
async run(request) {
|
|
24
34
|
const { args } = request;
|
|
@@ -53,17 +63,16 @@ export class SwerveManager {
|
|
|
53
63
|
const service = serviceEntry[1];
|
|
54
64
|
const serviceName = serviceEntry[0];
|
|
55
65
|
const packageName = service.packageName;
|
|
56
|
-
|
|
57
|
-
gLogger.debug(`importPathOrName ${importPathOrName}`);
|
|
66
|
+
gLogger.debug(`servicePath: ${service.servicePath}`);
|
|
58
67
|
const serviceArgs = {
|
|
59
68
|
...service,
|
|
60
69
|
...service.serviceConfiguration,
|
|
61
70
|
...args.serviceArgs,
|
|
62
71
|
};
|
|
63
72
|
const webservice = await this.installWebService({
|
|
64
|
-
serviceKey:
|
|
73
|
+
serviceKey: serviceName,
|
|
65
74
|
packageName,
|
|
66
|
-
|
|
75
|
+
servicePath: service.servicePath,
|
|
67
76
|
port,
|
|
68
77
|
app,
|
|
69
78
|
appDataRoot: args.appDataRoot,
|
|
@@ -120,11 +129,10 @@ export class SwerveManager {
|
|
|
120
129
|
for (const serviceEntry of Object.entries(args.services)) {
|
|
121
130
|
const service = serviceEntry[1];
|
|
122
131
|
const packageName = service.packageName;
|
|
123
|
-
const importPathOrName = service.servicePath ?? service.serviceArgs.servicePath ?? packageName;
|
|
124
132
|
const webservice = await this.installWebService({
|
|
125
133
|
serviceKey: serviceEntry[0],
|
|
126
134
|
packageName,
|
|
127
|
-
|
|
135
|
+
servicePath: service.servicePath,
|
|
128
136
|
port: PORT,
|
|
129
137
|
app,
|
|
130
138
|
appDataRoot: args.appDataRoot,
|
|
@@ -144,18 +152,17 @@ export class SwerveManager {
|
|
|
144
152
|
}
|
|
145
153
|
}
|
|
146
154
|
async installWebService(props) {
|
|
147
|
-
|
|
148
|
-
const { app, appDataRoot, packageName, port, gLogger, serviceArgs, importPathOrName, serviceKey, } = props;
|
|
155
|
+
const { app, appDataRoot, packageName, port, gLogger, serviceArgs, servicePath, serviceKey, } = props;
|
|
149
156
|
try {
|
|
150
157
|
gLogger.info(`Getting webservice package ${packageName} and will run on port ${port}`);
|
|
151
158
|
if (packageName) {
|
|
152
159
|
gLogger.debug(`Getting web service with name ${packageName}`);
|
|
153
160
|
}
|
|
154
161
|
else {
|
|
155
|
-
gLogger.debug(`Getting webservice with path: ${
|
|
162
|
+
gLogger.debug(`Getting webservice with path: ${servicePath}`);
|
|
156
163
|
}
|
|
157
|
-
const fullPath =
|
|
158
|
-
const tool = await import(fullPath);
|
|
164
|
+
const fullPath = await this.getImportName(packageName, servicePath);
|
|
165
|
+
const tool = await import(fullPath);
|
|
159
166
|
gLogger.debug(`Got service with require: ${JSON.stringify(tool)}`);
|
|
160
167
|
gLogger.debug(`Getting web service from tool...`);
|
|
161
168
|
const appDataPath = path.join(appDataRoot, "appdata", serviceKey);
|
|
@@ -168,6 +175,7 @@ export class SwerveManager {
|
|
|
168
175
|
port,
|
|
169
176
|
app,
|
|
170
177
|
packageName,
|
|
178
|
+
servicePath,
|
|
171
179
|
serviceArgs: { ...serviceArgs },
|
|
172
180
|
logger,
|
|
173
181
|
});
|
|
@@ -191,6 +199,22 @@ Failed to install web service, is it installed with NPM? Check package exists in
|
|
|
191
199
|
throw e; //new Error(exceptionMessage);
|
|
192
200
|
}
|
|
193
201
|
}
|
|
202
|
+
async getImportName(packageName, servicePath) {
|
|
203
|
+
const nodeModulesPath = this.nodeModulesPath;
|
|
204
|
+
this.logger.debug(`getImportPathName: modulesPath: ${nodeModulesPath}`);
|
|
205
|
+
if (servicePath) {
|
|
206
|
+
return await getFullImportPath(servicePath);
|
|
207
|
+
}
|
|
208
|
+
else {
|
|
209
|
+
if (nodeModulesPath) {
|
|
210
|
+
this.logger.debug(`Getting path with nodeModulesPath and packageName ${nodeModulesPath} ${packageName}`);
|
|
211
|
+
return await resolvePackageEntry(path.join(nodeModulesPath, packageName));
|
|
212
|
+
}
|
|
213
|
+
else {
|
|
214
|
+
return packageName;
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
}
|
|
194
218
|
async stop(request) {
|
|
195
219
|
const { instanceDetails } = request;
|
|
196
220
|
const { instanceId, instanceType } = instanceDetails;
|
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
// cross-runtime getFullImportPath.ts
|
|
2
|
+
import { promises as fs } from "node:fs";
|
|
3
|
+
import { pathToFileURL } from "node:url";
|
|
2
4
|
// Runtime detection
|
|
3
5
|
// @ts-ignore
|
|
4
6
|
const isDeno = typeof Deno !== "undefined" && "cwd" in Deno;
|
|
@@ -51,3 +53,30 @@ export async function getFullImportPath(importPathOrName) {
|
|
|
51
53
|
}
|
|
52
54
|
return importPath;
|
|
53
55
|
}
|
|
56
|
+
export async function resolvePackageEntry(pkgDir) {
|
|
57
|
+
const pkgJsonPath = join(pkgDir, "package.json");
|
|
58
|
+
let entry;
|
|
59
|
+
try {
|
|
60
|
+
const pkgJsonRaw = await fs.readFile(pkgJsonPath, "utf-8");
|
|
61
|
+
const pkgJson = JSON.parse(pkgJsonRaw);
|
|
62
|
+
if (pkgJson.exports && typeof pkgJson.exports === "string") {
|
|
63
|
+
// Simple "exports": "./esm/index.js"
|
|
64
|
+
entry = pkgJson.exports;
|
|
65
|
+
}
|
|
66
|
+
else if (pkgJson.module) {
|
|
67
|
+
entry = pkgJson.module;
|
|
68
|
+
}
|
|
69
|
+
else if (pkgJson.main) {
|
|
70
|
+
entry = pkgJson.main;
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
catch {
|
|
74
|
+
// no package.json, fallback below
|
|
75
|
+
}
|
|
76
|
+
if (!entry) {
|
|
77
|
+
// fallback to index.js
|
|
78
|
+
entry = "index.js";
|
|
79
|
+
}
|
|
80
|
+
const absPath = join(pkgDir, entry);
|
|
81
|
+
return pathToFileURL(absPath).href; // usable in await import()
|
|
82
|
+
}
|
package/package.json
CHANGED
|
@@ -1,13 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@swizzyweb/swerve-manager",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.7",
|
|
4
4
|
"description": "swizzy-swerve is a bootstrapper for swizzy web services. This package will bootstrap and run independent swizzy web services.",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
7
7
|
"type": "module",
|
|
8
8
|
"scripts": {
|
|
9
9
|
"build": "tsc",
|
|
10
|
-
"server:ts": "ts-node ./src/bootstrap.ts",
|
|
11
10
|
"server": "node dist/bootstrap.js",
|
|
12
11
|
"test": "npm run test:node && npm run test:bun && npm run test:deno",
|
|
13
12
|
"test:node": "node --test ./test**/*.spec.ts",
|
|
@@ -30,7 +29,7 @@
|
|
|
30
29
|
},
|
|
31
30
|
"repository": {
|
|
32
31
|
"type": "git",
|
|
33
|
-
"url": "git+https://github.com/swizzyweb/swerve.git"
|
|
32
|
+
"url": "git+https://github.com/swizzyweb/swerve-manager.git"
|
|
34
33
|
},
|
|
35
34
|
"keywords": [
|
|
36
35
|
"swizzy",
|
|
@@ -42,7 +41,7 @@
|
|
|
42
41
|
"runner"
|
|
43
42
|
],
|
|
44
43
|
"bugs": {
|
|
45
|
-
"url": "https://github.com/swizzyweb/swerve/issues"
|
|
44
|
+
"url": "https://github.com/swizzyweb/swerve-manager/issues"
|
|
46
45
|
},
|
|
47
|
-
"homepage": "https://github.com/swizzyweb/swerve#readme"
|
|
46
|
+
"homepage": "https://github.com/swizzyweb/swerve-manager#readme"
|
|
48
47
|
}
|
package/src/swerve.ts
CHANGED
|
@@ -16,7 +16,10 @@ import process from "node:process";
|
|
|
16
16
|
import { ILogger } from "@swizzyweb/swizzy-common";
|
|
17
17
|
import path from "node:path";
|
|
18
18
|
import { mkdirSync } from "node:fs";
|
|
19
|
-
import {
|
|
19
|
+
import {
|
|
20
|
+
getFullImportPath,
|
|
21
|
+
resolvePackageEntry,
|
|
22
|
+
} from "./utils/getFullImportPath.js";
|
|
20
23
|
|
|
21
24
|
export interface ISwerveManager {
|
|
22
25
|
run(request: RunRequest): Promise<RunResponse>;
|
|
@@ -74,6 +77,8 @@ export type Apps = {
|
|
|
74
77
|
export interface SwerveManagerProps {
|
|
75
78
|
apps?: Apps;
|
|
76
79
|
webServices?: WebService<any>[];
|
|
80
|
+
nodeModulesPath?: string;
|
|
81
|
+
logger?: ILogger<any> | undefined;
|
|
77
82
|
}
|
|
78
83
|
|
|
79
84
|
export interface WebServiceConfiguration {}
|
|
@@ -86,9 +91,19 @@ export class SwerveManager implements ISwerveManager {
|
|
|
86
91
|
apps: Apps;
|
|
87
92
|
webServices: WebService<any>[];
|
|
88
93
|
configurations: WebServiceConfigurations;
|
|
94
|
+
nodeModulesPath: string;
|
|
95
|
+
logger: ILogger<any>;
|
|
89
96
|
constructor(props: SwerveManagerProps) {
|
|
90
97
|
this.apps = props.apps ?? {};
|
|
91
98
|
this.webServices = props.webServices ?? [];
|
|
99
|
+
this.nodeModulesPath = props.nodeModulesPath;
|
|
100
|
+
this.logger =
|
|
101
|
+
props.logger ??
|
|
102
|
+
new SwizzyWinstonLogger({
|
|
103
|
+
appName: "swerve-manager",
|
|
104
|
+
port: -1,
|
|
105
|
+
hostName: os.hostname(),
|
|
106
|
+
});
|
|
92
107
|
}
|
|
93
108
|
|
|
94
109
|
async run(request: RunRequest): Promise<RunResponse> {
|
|
@@ -128,8 +143,7 @@ export class SwerveManager implements ISwerveManager {
|
|
|
128
143
|
const service = serviceEntry[1];
|
|
129
144
|
const serviceName = serviceEntry[0];
|
|
130
145
|
const packageName = service.packageName;
|
|
131
|
-
|
|
132
|
-
gLogger.debug(`importPathOrName ${importPathOrName}`);
|
|
146
|
+
gLogger.debug(`servicePath: ${service.servicePath}`);
|
|
133
147
|
const serviceArgs: SwerveArgs = {
|
|
134
148
|
...service,
|
|
135
149
|
...service.serviceConfiguration,
|
|
@@ -137,9 +151,9 @@ export class SwerveManager implements ISwerveManager {
|
|
|
137
151
|
};
|
|
138
152
|
|
|
139
153
|
const webservice = await this.installWebService({
|
|
140
|
-
serviceKey:
|
|
154
|
+
serviceKey: serviceName,
|
|
141
155
|
packageName,
|
|
142
|
-
|
|
156
|
+
servicePath: service.servicePath,
|
|
143
157
|
port,
|
|
144
158
|
app,
|
|
145
159
|
appDataRoot: args.appDataRoot,
|
|
@@ -204,12 +218,10 @@ export class SwerveManager implements ISwerveManager {
|
|
|
204
218
|
for (const serviceEntry of Object.entries(args.services)) {
|
|
205
219
|
const service = serviceEntry[1];
|
|
206
220
|
const packageName = service.packageName;
|
|
207
|
-
const importPathOrName =
|
|
208
|
-
service.servicePath ?? service.serviceArgs.servicePath ?? packageName;
|
|
209
221
|
const webservice = await this.installWebService({
|
|
210
222
|
serviceKey: serviceEntry[0],
|
|
211
223
|
packageName,
|
|
212
|
-
|
|
224
|
+
servicePath: service.servicePath,
|
|
213
225
|
port: PORT,
|
|
214
226
|
app,
|
|
215
227
|
appDataRoot: args.appDataRoot,
|
|
@@ -233,7 +245,7 @@ export class SwerveManager implements ISwerveManager {
|
|
|
233
245
|
async installWebService(props: {
|
|
234
246
|
//
|
|
235
247
|
serviceKey: string;
|
|
236
|
-
|
|
248
|
+
servicePath: string;
|
|
237
249
|
app: Application;
|
|
238
250
|
appDataRoot: string;
|
|
239
251
|
packageName: string;
|
|
@@ -241,7 +253,6 @@ export class SwerveManager implements ISwerveManager {
|
|
|
241
253
|
gLogger: ILogger<any>;
|
|
242
254
|
serviceArgs: { [key: string]: any };
|
|
243
255
|
}) {
|
|
244
|
-
// const packageName = importPathOrName;
|
|
245
256
|
const {
|
|
246
257
|
app,
|
|
247
258
|
appDataRoot,
|
|
@@ -249,7 +260,7 @@ export class SwerveManager implements ISwerveManager {
|
|
|
249
260
|
port,
|
|
250
261
|
gLogger,
|
|
251
262
|
serviceArgs,
|
|
252
|
-
|
|
263
|
+
servicePath,
|
|
253
264
|
serviceKey,
|
|
254
265
|
} = props;
|
|
255
266
|
|
|
@@ -261,11 +272,11 @@ export class SwerveManager implements ISwerveManager {
|
|
|
261
272
|
if (packageName) {
|
|
262
273
|
gLogger.debug(`Getting web service with name ${packageName}`);
|
|
263
274
|
} else {
|
|
264
|
-
gLogger.debug(`Getting webservice with path: ${
|
|
275
|
+
gLogger.debug(`Getting webservice with path: ${servicePath}`);
|
|
265
276
|
}
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
const tool = await import(fullPath);
|
|
277
|
+
|
|
278
|
+
const fullPath = await this.getImportName(packageName, servicePath);
|
|
279
|
+
const tool = await import(fullPath);
|
|
269
280
|
|
|
270
281
|
gLogger.debug(`Got service with require: ${JSON.stringify(tool)}`);
|
|
271
282
|
gLogger.debug(`Getting web service from tool...`);
|
|
@@ -286,6 +297,7 @@ export class SwerveManager implements ISwerveManager {
|
|
|
286
297
|
port,
|
|
287
298
|
app,
|
|
288
299
|
packageName,
|
|
300
|
+
servicePath,
|
|
289
301
|
serviceArgs: { ...serviceArgs },
|
|
290
302
|
logger,
|
|
291
303
|
});
|
|
@@ -314,6 +326,25 @@ Failed to install web service, is it installed with NPM? Check package exists in
|
|
|
314
326
|
}
|
|
315
327
|
}
|
|
316
328
|
|
|
329
|
+
async getImportName(packageName: string, servicePath: string) {
|
|
330
|
+
const nodeModulesPath = this.nodeModulesPath;
|
|
331
|
+
this.logger.debug(`getImportPathName: modulesPath: ${nodeModulesPath}`);
|
|
332
|
+
if (servicePath) {
|
|
333
|
+
return await getFullImportPath(servicePath);
|
|
334
|
+
} else {
|
|
335
|
+
if (nodeModulesPath) {
|
|
336
|
+
this.logger.debug(
|
|
337
|
+
`Getting path with nodeModulesPath and packageName ${nodeModulesPath} ${packageName}`,
|
|
338
|
+
);
|
|
339
|
+
return await resolvePackageEntry(
|
|
340
|
+
path.join(nodeModulesPath, packageName),
|
|
341
|
+
);
|
|
342
|
+
} else {
|
|
343
|
+
return packageName;
|
|
344
|
+
}
|
|
345
|
+
}
|
|
346
|
+
}
|
|
347
|
+
|
|
317
348
|
async stop(request: StopRequest) {
|
|
318
349
|
const { instanceDetails } = request;
|
|
319
350
|
const { instanceId, instanceType } = instanceDetails;
|
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
// cross-runtime getFullImportPath.ts
|
|
2
|
+
import { promises as fs } from "node:fs";
|
|
3
|
+
import { pathToFileURL } from "node:url";
|
|
2
4
|
|
|
3
5
|
// Runtime detection
|
|
4
6
|
// @ts-ignore
|
|
@@ -58,3 +60,32 @@ export async function getFullImportPath(
|
|
|
58
60
|
|
|
59
61
|
return importPath;
|
|
60
62
|
}
|
|
63
|
+
|
|
64
|
+
export async function resolvePackageEntry(pkgDir: string): Promise<string> {
|
|
65
|
+
const pkgJsonPath = join(pkgDir, "package.json");
|
|
66
|
+
let entry: string | undefined;
|
|
67
|
+
|
|
68
|
+
try {
|
|
69
|
+
const pkgJsonRaw = await fs.readFile(pkgJsonPath, "utf-8");
|
|
70
|
+
const pkgJson = JSON.parse(pkgJsonRaw);
|
|
71
|
+
|
|
72
|
+
if (pkgJson.exports && typeof pkgJson.exports === "string") {
|
|
73
|
+
// Simple "exports": "./esm/index.js"
|
|
74
|
+
entry = pkgJson.exports;
|
|
75
|
+
} else if (pkgJson.module) {
|
|
76
|
+
entry = pkgJson.module;
|
|
77
|
+
} else if (pkgJson.main) {
|
|
78
|
+
entry = pkgJson.main;
|
|
79
|
+
}
|
|
80
|
+
} catch {
|
|
81
|
+
// no package.json, fallback below
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
if (!entry) {
|
|
85
|
+
// fallback to index.js
|
|
86
|
+
entry = "index.js";
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
const absPath = join(pkgDir, entry);
|
|
90
|
+
return pathToFileURL(absPath).href; // usable in await import()
|
|
91
|
+
}
|
package/test/getArgs.spec.ts
CHANGED
|
@@ -15,67 +15,95 @@ const logger = new SwizzyWinstonLogger({
|
|
|
15
15
|
pid: process.pid,
|
|
16
16
|
});
|
|
17
17
|
|
|
18
|
-
test("
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
});
|
|
18
|
+
test.it("Sets port and custom arg", async () => {
|
|
19
|
+
const args = [
|
|
20
|
+
"/path/to/package/",
|
|
21
|
+
"run.js",
|
|
22
|
+
"--port",
|
|
23
|
+
"80",
|
|
24
|
+
//"--appDataRoot",
|
|
25
|
+
// ".",
|
|
26
|
+
"--someCustomArg",
|
|
27
|
+
"JasonIsTheBest",
|
|
28
|
+
];
|
|
29
|
+
let result: any = await getArgs(args, logger);
|
|
30
|
+
assert.equal(result.port, 80);
|
|
31
|
+
assert.equal(result.serviceArgs?.someCustomArg, "JasonIsTheBest");
|
|
32
|
+
});
|
|
34
33
|
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
34
|
+
test.it("sets appDataRoot", async () => {
|
|
35
|
+
const args = [
|
|
36
|
+
"/path/to/package/",
|
|
37
|
+
"run.js",
|
|
38
|
+
"--port",
|
|
39
|
+
"80",
|
|
40
|
+
"--appDataRoot",
|
|
41
|
+
".",
|
|
42
|
+
"--someCustomArg",
|
|
43
|
+
"JasonIsTheBest",
|
|
44
|
+
];
|
|
45
|
+
let result: any = await getArgs(args, logger);
|
|
46
|
+
assert.equal(result.port, 80);
|
|
47
|
+
assert.equal(result.serviceArgs?.someCustomArg, "JasonIsTheBest");
|
|
48
|
+
});
|
|
50
49
|
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
50
|
+
test.it("Throws on invalid config file path", async () => {
|
|
51
|
+
const configPath = "/some/invalid/path";
|
|
52
|
+
const args = [
|
|
53
|
+
"/path/to/package/",
|
|
54
|
+
"run.js",
|
|
55
|
+
"--port",
|
|
56
|
+
"80",
|
|
57
|
+
"--appDataRoot",
|
|
58
|
+
".",
|
|
59
|
+
"--someCustomArg",
|
|
60
|
+
"JasonIsTheBest",
|
|
61
|
+
"--config",
|
|
62
|
+
configPath,
|
|
63
|
+
];
|
|
64
|
+
try {
|
|
65
|
+
let result: any = await getArgs(args, logger);
|
|
66
|
+
} catch (e: any) {
|
|
67
|
+
assert.deepEqual(
|
|
68
|
+
{ message: e?.message, configFilePath: configPath },
|
|
69
|
+
{
|
|
70
|
+
message:
|
|
71
|
+
"Unexpected error occurred when attempting to read serviceConfiguration file",
|
|
72
|
+
configFilePath: configPath,
|
|
73
|
+
},
|
|
74
|
+
);
|
|
75
|
+
}
|
|
76
|
+
});
|
|
77
|
+
test.it("Should read config values from config", async () => {
|
|
78
|
+
const configPath = path.join(__dirname, "./config/serviceConfig.json");
|
|
79
|
+
const args = [
|
|
80
|
+
"/path/to/package/",
|
|
81
|
+
"run.js",
|
|
82
|
+
"--port",
|
|
83
|
+
"80",
|
|
84
|
+
"--appDataRoot",
|
|
85
|
+
".",
|
|
86
|
+
"--someCustomArg",
|
|
87
|
+
"JasonIsTheBest",
|
|
88
|
+
"--config",
|
|
89
|
+
configPath,
|
|
90
|
+
];
|
|
91
|
+
let result: any = await getArgs(args, logger);
|
|
92
|
+
assert.equal(result.port, 3000);
|
|
93
|
+
const service = result.services["my-first-web-service1"];
|
|
94
|
+
assert.equal(result.serviceArgs?.someCustomArg, "JasonIsTheBest");
|
|
95
|
+
|
|
96
|
+
assert.equal(service.someOtherArgFromConfig, "ThisIsTheArgValue");
|
|
97
|
+
assert.equal(service.shouldTimeout, true);
|
|
98
|
+
assert.deepEqual(service.nestedJson, {
|
|
99
|
+
hello: "world",
|
|
100
|
+
none: false,
|
|
77
101
|
});
|
|
78
|
-
|
|
102
|
+
});
|
|
103
|
+
|
|
104
|
+
test.it(
|
|
105
|
+
"Should override parameters in order of args, config file last",
|
|
106
|
+
async () => {
|
|
79
107
|
const configPath = path.join(__dirname, "./config/serviceConfig.json");
|
|
80
108
|
const args = [
|
|
81
109
|
"/path/to/package/",
|
|
@@ -86,246 +114,216 @@ test("getArgs", () => {
|
|
|
86
114
|
".",
|
|
87
115
|
"--someCustomArg",
|
|
88
116
|
"JasonIsTheBest",
|
|
117
|
+
"--someNumberINeed",
|
|
118
|
+
"1000",
|
|
89
119
|
"--config",
|
|
90
120
|
configPath,
|
|
91
121
|
];
|
|
92
|
-
let result = await getArgs(args, logger);
|
|
93
|
-
|
|
122
|
+
let result: any = await getArgs(args, logger);
|
|
123
|
+
|
|
94
124
|
const service = result.services["my-first-web-service1"];
|
|
125
|
+
assert.equal(service.someOtherArgFromConfig, "ThisIsTheArgValue");
|
|
126
|
+
|
|
127
|
+
assert.equal(result.port, 3000);
|
|
95
128
|
assert.equal(result.serviceArgs?.someCustomArg, "JasonIsTheBest");
|
|
96
129
|
|
|
97
|
-
assert.equal(
|
|
130
|
+
assert.equal(result.serviceArgs?.someNumberINeed, 1000);
|
|
98
131
|
assert.equal(service.shouldTimeout, true);
|
|
99
132
|
assert.deepEqual(service.nestedJson, {
|
|
100
133
|
hello: "world",
|
|
101
134
|
none: false,
|
|
102
135
|
});
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
test.it(
|
|
106
|
-
"Should override parameters in order of args, config file last",
|
|
107
|
-
async () => {
|
|
108
|
-
const configPath = path.join(__dirname, "./config/serviceConfig.json");
|
|
109
|
-
const args = [
|
|
110
|
-
"/path/to/package/",
|
|
111
|
-
"run.js",
|
|
112
|
-
"--port",
|
|
113
|
-
"80",
|
|
114
|
-
"--appDataRoot",
|
|
115
|
-
".",
|
|
116
|
-
"--someCustomArg",
|
|
117
|
-
"JasonIsTheBest",
|
|
118
|
-
"--someNumberINeed",
|
|
119
|
-
"1000",
|
|
120
|
-
"--config",
|
|
121
|
-
configPath,
|
|
122
|
-
];
|
|
123
|
-
let result = await getArgs(args, logger);
|
|
124
|
-
|
|
125
|
-
const service = result.services["my-first-web-service1"];
|
|
126
|
-
assert.equal(service.someOtherArgFromConfig, "ThisIsTheArgValue");
|
|
127
|
-
|
|
128
|
-
assert.equal(result.port, 3000);
|
|
129
|
-
assert.equal(result.serviceArgs?.someCustomArg, "JasonIsTheBest");
|
|
136
|
+
},
|
|
137
|
+
);
|
|
130
138
|
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
none: false,
|
|
136
|
-
});
|
|
137
|
-
},
|
|
138
|
-
);
|
|
139
|
-
|
|
140
|
-
test.it(
|
|
141
|
-
"Should override parameters in order of args, config file first",
|
|
142
|
-
async () => {
|
|
143
|
-
const configPath = path.join(__dirname, "./config/serviceConfig.json");
|
|
144
|
-
const args = [
|
|
145
|
-
"/path/to/package/",
|
|
146
|
-
"run.js",
|
|
147
|
-
"--port",
|
|
148
|
-
"80",
|
|
149
|
-
"--appDataRoot",
|
|
150
|
-
".",
|
|
151
|
-
"--someCustomArg",
|
|
152
|
-
"JasonIsTheBest",
|
|
153
|
-
"--config",
|
|
154
|
-
configPath,
|
|
155
|
-
"--someNumberINeed",
|
|
156
|
-
"1000",
|
|
157
|
-
];
|
|
158
|
-
let result = await getArgs(args, logger);
|
|
159
|
-
const service = result.services["my-first-web-service1"];
|
|
160
|
-
assert.equal(service.someOtherArgFromConfig, "ThisIsTheArgValue");
|
|
161
|
-
assert.equal(result.port, 3000);
|
|
162
|
-
assert.equal(result.appDataRoot, path.join(__dirname, ".."));
|
|
163
|
-
assert.equal(result.appDataRoot, path.join(__dirname, ".."));
|
|
164
|
-
assert.equal(result.serviceArgs?.someCustomArg, "JasonIsTheBest");
|
|
165
|
-
|
|
166
|
-
assert.equal(result.serviceArgs?.someNumberINeed, 1000);
|
|
167
|
-
assert.equal(service.shouldTimeout, true);
|
|
168
|
-
assert.deepEqual(service.nestedJson, {
|
|
169
|
-
hello: "world",
|
|
170
|
-
none: false,
|
|
171
|
-
});
|
|
172
|
-
},
|
|
173
|
-
);
|
|
174
|
-
|
|
175
|
-
test.it("Should getService from args", async () => {
|
|
139
|
+
test.it(
|
|
140
|
+
"Should override parameters in order of args, config file first",
|
|
141
|
+
async () => {
|
|
142
|
+
const configPath = path.join(__dirname, "./config/serviceConfig.json");
|
|
176
143
|
const args = [
|
|
177
144
|
"/path/to/package/",
|
|
178
145
|
"run.js",
|
|
179
|
-
path.join(__dirname, "../package.json"),
|
|
180
146
|
"--port",
|
|
181
147
|
"80",
|
|
182
148
|
"--appDataRoot",
|
|
183
149
|
".",
|
|
184
150
|
"--someCustomArg",
|
|
185
151
|
"JasonIsTheBest",
|
|
152
|
+
"--config",
|
|
153
|
+
configPath,
|
|
154
|
+
"--someNumberINeed",
|
|
155
|
+
"1000",
|
|
186
156
|
];
|
|
187
|
-
let result = await getArgs(args, logger);
|
|
188
|
-
assert.equal(result.port, 80);
|
|
189
|
-
|
|
157
|
+
let result: any = await getArgs(args, logger);
|
|
190
158
|
const service = result.services["my-first-web-service1"];
|
|
191
|
-
|
|
159
|
+
assert.equal(service.someOtherArgFromConfig, "ThisIsTheArgValue");
|
|
160
|
+
assert.equal(result.port, 3000);
|
|
161
|
+
assert.equal(result.appDataRoot, path.join(__dirname, ".."));
|
|
162
|
+
assert.equal(result.appDataRoot, path.join(__dirname, ".."));
|
|
192
163
|
assert.equal(result.serviceArgs?.someCustomArg, "JasonIsTheBest");
|
|
193
|
-
});
|
|
194
164
|
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
"80",
|
|
204
|
-
"--someCustomArg",
|
|
205
|
-
"JasonIsTheBest",
|
|
206
|
-
"--config",
|
|
207
|
-
configPath,
|
|
208
|
-
"--someNumberINeed",
|
|
209
|
-
"1000",
|
|
210
|
-
];
|
|
211
|
-
let result = await getArgs(args, logger);
|
|
165
|
+
assert.equal(result.serviceArgs?.someNumberINeed, 1000);
|
|
166
|
+
assert.equal(service.shouldTimeout, true);
|
|
167
|
+
assert.deepEqual(service.nestedJson, {
|
|
168
|
+
hello: "world",
|
|
169
|
+
none: false,
|
|
170
|
+
});
|
|
171
|
+
},
|
|
172
|
+
);
|
|
212
173
|
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
174
|
+
test.it("Should getService from args", async () => {
|
|
175
|
+
const args = [
|
|
176
|
+
"/path/to/package/",
|
|
177
|
+
"run.js",
|
|
178
|
+
path.join(__dirname, "../package.json"),
|
|
179
|
+
"--port",
|
|
180
|
+
"80",
|
|
181
|
+
"--appDataRoot",
|
|
182
|
+
".",
|
|
183
|
+
"--someCustomArg",
|
|
184
|
+
"JasonIsTheBest",
|
|
185
|
+
];
|
|
186
|
+
let result: any = await getArgs(args, logger);
|
|
187
|
+
assert.equal(result.port, 80);
|
|
218
188
|
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
)
|
|
227
|
-
test.it("Should create multiple services", async () => {
|
|
189
|
+
const service = result.services["my-first-web-service1"];
|
|
190
|
+
// expect(result.serviceArgs.appDataRoot, ".");
|
|
191
|
+
assert.equal(result.serviceArgs?.someCustomArg, "JasonIsTheBest");
|
|
192
|
+
});
|
|
193
|
+
|
|
194
|
+
test.it(
|
|
195
|
+
"Should set appDataRoot to current package root by default",
|
|
196
|
+
async () => {
|
|
228
197
|
const configPath = path.join(__dirname, "./config/serviceConfig.json");
|
|
229
198
|
const args = [
|
|
230
199
|
"/path/to/package/",
|
|
231
200
|
"run.js",
|
|
232
|
-
".",
|
|
233
201
|
"--port",
|
|
234
202
|
"80",
|
|
235
203
|
"--someCustomArg",
|
|
236
204
|
"JasonIsTheBest",
|
|
237
|
-
|
|
238
|
-
|
|
205
|
+
"--config",
|
|
206
|
+
configPath,
|
|
239
207
|
"--someNumberINeed",
|
|
240
208
|
"1000",
|
|
241
|
-
".",
|
|
242
|
-
"--port",
|
|
243
|
-
"91",
|
|
244
209
|
];
|
|
245
|
-
let result = await getArgs(args, logger);
|
|
210
|
+
let result: any = await getArgs(args, logger);
|
|
246
211
|
|
|
247
212
|
const service = result.services["my-first-web-service1"];
|
|
248
|
-
assert.equal(
|
|
213
|
+
assert.equal(service.someOtherArgFromConfig, "ThisIsTheArgValue");
|
|
214
|
+
assert.equal(result.port, 3000);
|
|
249
215
|
assert.equal(result.appDataRoot, path.join(__dirname, ".."));
|
|
250
|
-
|
|
216
|
+
assert.equal(result.serviceArgs?.someCustomArg!, "JasonIsTheBest");
|
|
251
217
|
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
"
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
appDataRoot,
|
|
280
|
-
];
|
|
281
|
-
let result = await getArgs(args, logger);
|
|
282
|
-
assert.equal(result.appDataRoot, appDataRoot);
|
|
283
|
-
});
|
|
218
|
+
assert.equal(result.serviceArgs?.someNumberINeed!, 1000);
|
|
219
|
+
assert.equal(service.shouldTimeout, true);
|
|
220
|
+
assert.deepEqual(service.nestedJson, {
|
|
221
|
+
hello: "world",
|
|
222
|
+
none: false,
|
|
223
|
+
});
|
|
224
|
+
},
|
|
225
|
+
);
|
|
226
|
+
test.it("Should create multiple services", async () => {
|
|
227
|
+
const configPath = path.join(__dirname, "./config/serviceConfig.json");
|
|
228
|
+
const args = [
|
|
229
|
+
"/path/to/package/",
|
|
230
|
+
"run.js",
|
|
231
|
+
".",
|
|
232
|
+
"--port",
|
|
233
|
+
"80",
|
|
234
|
+
"--someCustomArg",
|
|
235
|
+
"JasonIsTheBest",
|
|
236
|
+
// "--config",
|
|
237
|
+
// configPath,
|
|
238
|
+
"--someNumberINeed",
|
|
239
|
+
"1000",
|
|
240
|
+
".",
|
|
241
|
+
"--port",
|
|
242
|
+
"91",
|
|
243
|
+
];
|
|
244
|
+
let result: any = await getArgs(args, logger);
|
|
284
245
|
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
config.services["@swizzyweb/swerve-manager"].packageJson.name,
|
|
290
|
-
"@swizzyweb/swerve-manager",
|
|
291
|
-
);
|
|
292
|
-
});
|
|
246
|
+
const service = result.services["my-first-web-service1"];
|
|
247
|
+
assert.equal(result.port, 91);
|
|
248
|
+
assert.equal(result.appDataRoot, path.join(__dirname, ".."));
|
|
249
|
+
// expect(service.someCustomArg, "JasonIsTheBest");
|
|
293
250
|
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
);
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
assert.equal(result.appDataRoot, path.join(__dirname, ".."));
|
|
327
|
-
assert.equal(result.serviceArgs?.someCustomArg, "JasonIsTheBest");
|
|
251
|
+
// expect(service.someNumberINeed, 1000);
|
|
252
|
+
// expect(service.shouldTimeout, true);
|
|
253
|
+
// expect(service.nestedJson, {
|
|
254
|
+
// hello: "world",
|
|
255
|
+
// none: false,
|
|
256
|
+
// });
|
|
257
|
+
// expect(result.services.length, 2);
|
|
258
|
+
});
|
|
259
|
+
test.it("Should create absolute path appdata directory", async () => {
|
|
260
|
+
const configPath = path.join(__dirname, "./config/serviceConfig.json");
|
|
261
|
+
const appDataRoot = "/tmp/swizzy-dyn-serve-web-service";
|
|
262
|
+
const args = [
|
|
263
|
+
"/path/to/package/",
|
|
264
|
+
"run.js",
|
|
265
|
+
".",
|
|
266
|
+
"--port",
|
|
267
|
+
"80",
|
|
268
|
+
"--someCustomArg",
|
|
269
|
+
"JasonIsTheBest",
|
|
270
|
+
//"--config",
|
|
271
|
+
//configPath,
|
|
272
|
+
"--someNumberINeed",
|
|
273
|
+
"1000",
|
|
274
|
+
".",
|
|
275
|
+
"--port",
|
|
276
|
+
"91",
|
|
277
|
+
"--appDataRoot",
|
|
278
|
+
appDataRoot,
|
|
279
|
+
];
|
|
280
|
+
let result: any = await getArgs(args, logger);
|
|
281
|
+
assert.equal(result.appDataRoot, appDataRoot);
|
|
282
|
+
});
|
|
328
283
|
|
|
329
|
-
|
|
330
|
-
|
|
284
|
+
test.it("Should resolve package.json from package name", async () => {
|
|
285
|
+
const config: any = await getArgs(["@swizzyweb/swerve-manager"], logger);
|
|
286
|
+
assert(config.services["@swizzyweb/swerve-manager"].packageJson);
|
|
287
|
+
assert.equal(
|
|
288
|
+
config.services["@swizzyweb/swerve-manager"].packageJson.name,
|
|
289
|
+
"@swizzyweb/swerve-manager",
|
|
290
|
+
);
|
|
291
|
+
});
|
|
292
|
+
|
|
293
|
+
test.it("Should resolve package.json from absolute path", async () => {
|
|
294
|
+
const config: any = await getArgs([path.join(__dirname, "..")], logger);
|
|
295
|
+
assert(config.services["@swizzyweb/swerve-manager"].packageJson);
|
|
296
|
+
assert.equal(
|
|
297
|
+
config.services["@swizzyweb/swerve-manager"].packageJson.name,
|
|
298
|
+
"@swizzyweb/swerve-manager",
|
|
299
|
+
);
|
|
300
|
+
});
|
|
301
|
+
test.it("Should not throw with no args", async () => {
|
|
302
|
+
const config: any = await getArgs([], logger);
|
|
303
|
+
assert(config.services["@swizzyweb/swerve-manager"].packageJson);
|
|
304
|
+
assert.equal(
|
|
305
|
+
config.services["@swizzyweb/swerve-manager"].packageJson.name,
|
|
306
|
+
"@swizzyweb/swerve-manager",
|
|
307
|
+
);
|
|
308
|
+
});
|
|
309
|
+
test.it("Should work with no port", async () => {
|
|
310
|
+
const configPath = path.join(__dirname, "./config/serviceConfig.json");
|
|
311
|
+
const args = [
|
|
312
|
+
"/path/to/package/",
|
|
313
|
+
"run.js",
|
|
314
|
+
"--appDataRoot",
|
|
315
|
+
".",
|
|
316
|
+
"--someCustomArg",
|
|
317
|
+
"JasonIsTheBest",
|
|
318
|
+
"--someNumberINeed",
|
|
319
|
+
"1000",
|
|
320
|
+
];
|
|
321
|
+
let result: any = await getArgs(args, logger);
|
|
322
|
+
const service = result.services["my-first-web-service1"];
|
|
323
|
+
assert.equal(result.port, 3005);
|
|
324
|
+
assert.equal(result.appDataRoot, path.join(__dirname, ".."));
|
|
325
|
+
assert.equal(result.appDataRoot, path.join(__dirname, ".."));
|
|
326
|
+
assert.equal(result.serviceArgs?.someCustomArg, "JasonIsTheBest");
|
|
327
|
+
|
|
328
|
+
assert.equal(result.serviceArgs?.someNumberINeed, 1000);
|
|
331
329
|
});
|