@fluidframework/fluid-runner 2.0.0-internal.1.0.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.
- package/.eslintrc.js +18 -0
- package/LICENSE +21 -0
- package/README.md +16 -0
- package/bin/fluidRunner +2 -0
- package/dist/codeLoaderBundle.d.ts +44 -0
- package/dist/codeLoaderBundle.d.ts.map +1 -0
- package/dist/codeLoaderBundle.js +17 -0
- package/dist/codeLoaderBundle.js.map +1 -0
- package/dist/exportFile.d.ts +20 -0
- package/dist/exportFile.d.ts.map +1 -0
- package/dist/exportFile.js +84 -0
- package/dist/exportFile.js.map +1 -0
- package/dist/fakeUrlResolver.d.ts +14 -0
- package/dist/fakeUrlResolver.d.ts.map +1 -0
- package/dist/fakeUrlResolver.js +42 -0
- package/dist/fakeUrlResolver.js.map +1 -0
- package/dist/fluidRunner.d.ts +6 -0
- package/dist/fluidRunner.d.ts.map +1 -0
- package/dist/fluidRunner.js +88 -0
- package/dist/fluidRunner.js.map +1 -0
- package/dist/getArgsValidationError.d.ts +6 -0
- package/dist/getArgsValidationError.d.ts.map +1 -0
- package/dist/getArgsValidationError.js +54 -0
- package/dist/getArgsValidationError.js.map +1 -0
- package/dist/index.d.ts +7 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +19 -0
- package/dist/index.js.map +1 -0
- package/dist/logger/FileLogger.d.ts +23 -0
- package/dist/logger/FileLogger.d.ts.map +1 -0
- package/dist/logger/FileLogger.js +58 -0
- package/dist/logger/FileLogger.js.map +1 -0
- package/dist/packageVersion.d.ts +9 -0
- package/dist/packageVersion.d.ts.map +1 -0
- package/dist/packageVersion.js +12 -0
- package/dist/packageVersion.js.map +1 -0
- package/lib/codeLoaderBundle.d.ts +44 -0
- package/lib/codeLoaderBundle.d.ts.map +1 -0
- package/lib/codeLoaderBundle.js +13 -0
- package/lib/codeLoaderBundle.js.map +1 -0
- package/lib/exportFile.d.ts +20 -0
- package/lib/exportFile.d.ts.map +1 -0
- package/lib/exportFile.js +57 -0
- package/lib/exportFile.js.map +1 -0
- package/lib/fakeUrlResolver.d.ts +14 -0
- package/lib/fakeUrlResolver.d.ts.map +1 -0
- package/lib/fakeUrlResolver.js +38 -0
- package/lib/fakeUrlResolver.js.map +1 -0
- package/lib/fluidRunner.d.ts +6 -0
- package/lib/fluidRunner.d.ts.map +1 -0
- package/lib/fluidRunner.js +67 -0
- package/lib/fluidRunner.js.map +1 -0
- package/lib/getArgsValidationError.d.ts +6 -0
- package/lib/getArgsValidationError.d.ts.map +1 -0
- package/lib/getArgsValidationError.js +31 -0
- package/lib/getArgsValidationError.js.map +1 -0
- package/lib/index.d.ts +7 -0
- package/lib/index.d.ts.map +1 -0
- package/lib/index.js +7 -0
- package/lib/index.js.map +1 -0
- package/lib/logger/FileLogger.d.ts +23 -0
- package/lib/logger/FileLogger.d.ts.map +1 -0
- package/lib/logger/FileLogger.js +35 -0
- package/lib/logger/FileLogger.js.map +1 -0
- package/lib/packageVersion.d.ts +9 -0
- package/lib/packageVersion.d.ts.map +1 -0
- package/lib/packageVersion.js +9 -0
- package/lib/packageVersion.js.map +1 -0
- package/package.json +86 -0
- package/src/codeLoaderBundle.ts +52 -0
- package/src/exportFile.ts +94 -0
- package/src/fakeUrlResolver.ts +49 -0
- package/src/fluidRunner.ts +83 -0
- package/src/getArgsValidationError.ts +36 -0
- package/src/index.ts +7 -0
- package/src/logger/FileLogger.ts +44 -0
- package/src/packageVersion.ts +9 -0
- package/tsconfig.esnext.json +7 -0
- package/tsconfig.json +14 -0
package/package.json
ADDED
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@fluidframework/fluid-runner",
|
|
3
|
+
"version": "2.0.0-internal.1.0.0",
|
|
4
|
+
"description": "Utility for running various functionality inside a Fluid Framework environment",
|
|
5
|
+
"homepage": "https://fluidframework.com",
|
|
6
|
+
"repository": {
|
|
7
|
+
"type": "git",
|
|
8
|
+
"url": "https://github.com/microsoft/FluidFramework.git",
|
|
9
|
+
"directory": "packages/tools/fluid-runner"
|
|
10
|
+
},
|
|
11
|
+
"license": "MIT",
|
|
12
|
+
"author": "Microsoft and contributors",
|
|
13
|
+
"main": "dist/index.js",
|
|
14
|
+
"types": "dist/index.d.ts",
|
|
15
|
+
"bin": {
|
|
16
|
+
"fluid-runner": "bin/fluidRunner"
|
|
17
|
+
},
|
|
18
|
+
"scripts": {
|
|
19
|
+
"build": "concurrently npm:build:compile npm:lint",
|
|
20
|
+
"build:commonjs": "npm run tsc && npm run build:test",
|
|
21
|
+
"build:compile": "concurrently npm:build:commonjs npm:build:esnext",
|
|
22
|
+
"build:esnext": "tsc --project ./tsconfig.esnext.json",
|
|
23
|
+
"build:full": "npm run build",
|
|
24
|
+
"build:full:compile": "npm run build:compile",
|
|
25
|
+
"build:test": "tsc --project ./src/test/tsconfig.json",
|
|
26
|
+
"clean": "rimraf dist lib *.tsbuildinfo *.build.log",
|
|
27
|
+
"eslint": "eslint --format stylish src",
|
|
28
|
+
"eslint:fix": "eslint --format stylish src --fix --fix-type problem,suggestion,layout",
|
|
29
|
+
"lint": "npm run eslint",
|
|
30
|
+
"lint:fix": "npm run eslint:fix",
|
|
31
|
+
"test": "npm run test:mocha",
|
|
32
|
+
"test:coverage": "nyc npm test -- --reporter xunit --reporter-option output=nyc/junit-report.xml",
|
|
33
|
+
"test:mocha": "mocha --ignore 'dist/test/types/*' --recursive dist/test -r node_modules/@fluidframework/mocha-test-setup --unhandled-rejections=strict",
|
|
34
|
+
"test:mocha:verbose": "cross-env FLUID_TEST_VERBOSE=1 npm run test:mocha",
|
|
35
|
+
"tsc": "tsc",
|
|
36
|
+
"tsfmt": "tsfmt --verify",
|
|
37
|
+
"tsfmt:fix": "tsfmt --replace"
|
|
38
|
+
},
|
|
39
|
+
"nyc": {
|
|
40
|
+
"all": true,
|
|
41
|
+
"cache-dir": "nyc/.cache",
|
|
42
|
+
"exclude": [
|
|
43
|
+
"src/test/**/*.ts",
|
|
44
|
+
"dist/test/**/*.js"
|
|
45
|
+
],
|
|
46
|
+
"exclude-after-remap": false,
|
|
47
|
+
"include": [
|
|
48
|
+
"src/**/*.ts",
|
|
49
|
+
"dist/**/*.js"
|
|
50
|
+
],
|
|
51
|
+
"report-dir": "nyc/report",
|
|
52
|
+
"reporter": [
|
|
53
|
+
"cobertura",
|
|
54
|
+
"html",
|
|
55
|
+
"text"
|
|
56
|
+
],
|
|
57
|
+
"temp-directory": "nyc/.nyc_output"
|
|
58
|
+
},
|
|
59
|
+
"dependencies": {
|
|
60
|
+
"@fluidframework/aqueduct": "^2.0.0-internal.1.0.0",
|
|
61
|
+
"@fluidframework/common-definitions": "^0.20.1",
|
|
62
|
+
"@fluidframework/container-definitions": "^2.0.0-internal.1.0.0",
|
|
63
|
+
"@fluidframework/container-loader": "^2.0.0-internal.1.0.0",
|
|
64
|
+
"@fluidframework/core-interfaces": "^2.0.0-internal.1.0.0",
|
|
65
|
+
"@fluidframework/driver-definitions": "^2.0.0-internal.1.0.0",
|
|
66
|
+
"@fluidframework/odsp-driver": "^2.0.0-internal.1.0.0",
|
|
67
|
+
"@fluidframework/odsp-driver-definitions": "^2.0.0-internal.1.0.0",
|
|
68
|
+
"@fluidframework/telemetry-utils": "^2.0.0-internal.1.0.0",
|
|
69
|
+
"yargs": "13.2.2"
|
|
70
|
+
},
|
|
71
|
+
"devDependencies": {
|
|
72
|
+
"@fluidframework/build-common": "^0.24.0",
|
|
73
|
+
"@fluidframework/eslint-config-fluid": "^0.28.2000",
|
|
74
|
+
"@fluidframework/mocha-test-setup": "^2.0.0-internal.1.0.0",
|
|
75
|
+
"@rushstack/eslint-config": "^2.5.1",
|
|
76
|
+
"@types/mocha": "^9.1.1",
|
|
77
|
+
"@types/node": "^14.18.0",
|
|
78
|
+
"concurrently": "^6.2.0",
|
|
79
|
+
"cross-env": "^7.0.2",
|
|
80
|
+
"eslint": "~8.6.0",
|
|
81
|
+
"mocha": "^10.0.0",
|
|
82
|
+
"nyc": "^15.0.0",
|
|
83
|
+
"rimraf": "^2.6.2",
|
|
84
|
+
"typescript": "~4.5.5"
|
|
85
|
+
}
|
|
86
|
+
}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
/*!
|
|
2
|
+
* Copyright (c) Microsoft Corporation and contributors. All rights reserved.
|
|
3
|
+
* Licensed under the MIT License.
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import { ITelemetryBaseLogger } from "@fluidframework/common-definitions";
|
|
7
|
+
import { ICodeDetailsLoader, IContainer } from "@fluidframework/container-definitions";
|
|
8
|
+
import { FluidObject } from "@fluidframework/core-interfaces";
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Contract that defines the necessary exports for the bundle provided at runtime
|
|
12
|
+
* For an example, see "src/test/sampleCodeLoader.ts"
|
|
13
|
+
*/
|
|
14
|
+
export interface ICodeLoaderBundle {
|
|
15
|
+
/**
|
|
16
|
+
* Fluid export of all the required objects and functions
|
|
17
|
+
*/
|
|
18
|
+
fluidExport: Promise<IFluidFileConverter>;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* Instance that holds all the details for Fluid file conversion
|
|
23
|
+
*/
|
|
24
|
+
export interface IFluidFileConverter {
|
|
25
|
+
/**
|
|
26
|
+
* Code loader details to provide at Loader creation
|
|
27
|
+
*/
|
|
28
|
+
codeLoader: ICodeDetailsLoader;
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Scope object to provide at Loader creation
|
|
32
|
+
*/
|
|
33
|
+
scope?: FluidObject;
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Execute code and return the results
|
|
37
|
+
* @param container - container created by this application
|
|
38
|
+
* @param scenario - scenario this execution is related to
|
|
39
|
+
* @param logger - passed through logger object
|
|
40
|
+
* @returns - object containing file names as property keys and file content as values
|
|
41
|
+
*/
|
|
42
|
+
execute(container: IContainer, scenario: string, logger: ITelemetryBaseLogger): Promise<Record<string, string>>;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* Type cast to ensure necessary methods are present in the provided bundle
|
|
47
|
+
* @param bundle - bundle provided to this application
|
|
48
|
+
*/
|
|
49
|
+
export function isCodeLoaderBundle(bundle: any): bundle is ICodeLoaderBundle {
|
|
50
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-return
|
|
51
|
+
return bundle?.fluidExport && typeof bundle.fluidExport === "object";
|
|
52
|
+
}
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
/*!
|
|
2
|
+
* Copyright (c) Microsoft Corporation and contributors. All rights reserved.
|
|
3
|
+
* Licensed under the MIT License.
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import * as fs from "fs";
|
|
7
|
+
import path from "path";
|
|
8
|
+
import { ITelemetryLogger } from "@fluidframework/common-definitions";
|
|
9
|
+
import { LoaderHeader } from "@fluidframework/container-definitions";
|
|
10
|
+
import { Loader } from "@fluidframework/container-loader";
|
|
11
|
+
import { createLocalOdspDocumentServiceFactory } from "@fluidframework/odsp-driver";
|
|
12
|
+
import { PerformanceEvent } from "@fluidframework/telemetry-utils";
|
|
13
|
+
import { getArgsValidationError } from "./getArgsValidationError";
|
|
14
|
+
import { IFluidFileConverter, isCodeLoaderBundle } from "./codeLoaderBundle";
|
|
15
|
+
import { FakeUrlResolver } from "./fakeUrlResolver";
|
|
16
|
+
|
|
17
|
+
export type IExportFileResponse = IExportFileResponseSuccess | IExportFileResponseFailure;
|
|
18
|
+
|
|
19
|
+
interface IExportFileResponseSuccess {
|
|
20
|
+
success: true;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
interface IExportFileResponseFailure {
|
|
24
|
+
success: false;
|
|
25
|
+
eventName: string;
|
|
26
|
+
errorMessage: string;
|
|
27
|
+
error?: any;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
const clientArgsValidationError = "Client_ArgsValidationError";
|
|
31
|
+
|
|
32
|
+
export async function exportFile(
|
|
33
|
+
codeLoader: string,
|
|
34
|
+
inputFile: string,
|
|
35
|
+
outputFolder: string,
|
|
36
|
+
scenario: string,
|
|
37
|
+
logger: ITelemetryLogger,
|
|
38
|
+
): Promise<IExportFileResponse> {
|
|
39
|
+
try {
|
|
40
|
+
return await PerformanceEvent.timedExecAsync(logger, { eventName: "ExportFile" }, async () => {
|
|
41
|
+
// eslint-disable-next-line @typescript-eslint/no-require-imports, @typescript-eslint/no-var-requires
|
|
42
|
+
const codeLoaderBundle = require(codeLoader);
|
|
43
|
+
if (!isCodeLoaderBundle(codeLoaderBundle)) {
|
|
44
|
+
const eventName = clientArgsValidationError;
|
|
45
|
+
const message = "Code loader bundle is not of type CodeLoaderBundle";
|
|
46
|
+
return { success: false, eventName, errorMessage: message };
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
const argsValidationError = getArgsValidationError(inputFile, outputFolder, scenario);
|
|
50
|
+
if (argsValidationError) {
|
|
51
|
+
const eventName = clientArgsValidationError;
|
|
52
|
+
return { success: false, eventName, errorMessage: argsValidationError };
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
// TODO: read file stream
|
|
56
|
+
const inputFileContent = fs.readFileSync(inputFile, { encoding: "utf-8" });
|
|
57
|
+
|
|
58
|
+
const results = await createContainerAndExecute(
|
|
59
|
+
inputFileContent,
|
|
60
|
+
await codeLoaderBundle.fluidExport,
|
|
61
|
+
scenario,
|
|
62
|
+
logger,
|
|
63
|
+
);
|
|
64
|
+
// eslint-disable-next-line guard-for-in, no-restricted-syntax
|
|
65
|
+
for (const key in results) {
|
|
66
|
+
fs.appendFileSync(path.join(outputFolder, key), results[key]);
|
|
67
|
+
}
|
|
68
|
+
return { success: true };
|
|
69
|
+
});
|
|
70
|
+
} catch (error) {
|
|
71
|
+
const eventName = "Client_UnexpectedError";
|
|
72
|
+
return { success: false, eventName, errorMessage: "Unexpected error", error };
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
export async function createContainerAndExecute(
|
|
77
|
+
localOdspSnapshot: string,
|
|
78
|
+
fluidFileConverter: IFluidFileConverter,
|
|
79
|
+
scenario: string,
|
|
80
|
+
logger: ITelemetryLogger,
|
|
81
|
+
): Promise<Record<string, string>> {
|
|
82
|
+
const loader = new Loader({
|
|
83
|
+
urlResolver: new FakeUrlResolver(),
|
|
84
|
+
documentServiceFactory: createLocalOdspDocumentServiceFactory(localOdspSnapshot),
|
|
85
|
+
codeLoader: fluidFileConverter.codeLoader,
|
|
86
|
+
scope: fluidFileConverter.scope,
|
|
87
|
+
});
|
|
88
|
+
|
|
89
|
+
const container = await loader.resolve({ url: "/fakeUrl/", headers: {
|
|
90
|
+
[LoaderHeader.loadMode]: { opsBeforeReturn: "cached" } } });
|
|
91
|
+
|
|
92
|
+
return PerformanceEvent.timedExecAsync(logger, { eventName: "ExportFile" }, async () =>
|
|
93
|
+
fluidFileConverter.execute(container, scenario, logger));
|
|
94
|
+
}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
/*!
|
|
2
|
+
* Copyright (c) Microsoft Corporation and contributors. All rights reserved.
|
|
3
|
+
* Licensed under the MIT License.
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import { IRequest } from "@fluidframework/core-interfaces";
|
|
7
|
+
import { IContainerPackageInfo, IResolvedUrl, IUrlResolver } from "@fluidframework/driver-definitions";
|
|
8
|
+
import { IOdspResolvedUrl } from "@fluidframework/odsp-driver-definitions";
|
|
9
|
+
|
|
10
|
+
const fakeId = "FakeUrlResolver";
|
|
11
|
+
const fakeUrl = "/FakeUrlResolver/";
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Fake URL resolver that returns hard coded values on every request
|
|
15
|
+
*/
|
|
16
|
+
export class FakeUrlResolver implements IUrlResolver {
|
|
17
|
+
public async resolve(_request: IRequest): Promise<IResolvedUrl | undefined> {
|
|
18
|
+
const fakeOdspResolvedUrl: IOdspResolvedUrl = {
|
|
19
|
+
type: "fluid",
|
|
20
|
+
odspResolvedUrl: true,
|
|
21
|
+
id: fakeId,
|
|
22
|
+
siteUrl: fakeUrl,
|
|
23
|
+
driveId: fakeId,
|
|
24
|
+
itemId: fakeId,
|
|
25
|
+
url: fakeUrl,
|
|
26
|
+
hashedDocumentId: fakeId,
|
|
27
|
+
endpoints: {
|
|
28
|
+
snapshotStorageUrl: fakeUrl,
|
|
29
|
+
attachmentPOSTStorageUrl: fakeUrl,
|
|
30
|
+
attachmentGETStorageUrl: fakeUrl,
|
|
31
|
+
deltaStorageUrl: fakeUrl,
|
|
32
|
+
},
|
|
33
|
+
tokens: {},
|
|
34
|
+
fileName: fakeId,
|
|
35
|
+
summarizer: false,
|
|
36
|
+
fileVersion: fakeId,
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
return fakeOdspResolvedUrl;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
public async getAbsoluteUrl(
|
|
43
|
+
_resolvedUrl: IResolvedUrl,
|
|
44
|
+
_relativeUrl: string,
|
|
45
|
+
_packageInfoSource?: IContainerPackageInfo,
|
|
46
|
+
): Promise<string> {
|
|
47
|
+
return "";
|
|
48
|
+
}
|
|
49
|
+
}
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
/*!
|
|
2
|
+
* Copyright (c) Microsoft Corporation and contributors. All rights reserved.
|
|
3
|
+
* Licensed under the MIT License.
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import * as fs from "fs";
|
|
7
|
+
import * as yargs from "yargs";
|
|
8
|
+
import { ChildLogger } from "@fluidframework/telemetry-utils";
|
|
9
|
+
import { exportFile } from "./exportFile";
|
|
10
|
+
// eslint-disable-next-line import/no-internal-modules
|
|
11
|
+
import { FileLogger } from "./logger/FileLogger";
|
|
12
|
+
|
|
13
|
+
function fluidRunner() {
|
|
14
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-expressions
|
|
15
|
+
yargs
|
|
16
|
+
.strict()
|
|
17
|
+
.version(false)
|
|
18
|
+
.command(
|
|
19
|
+
"exportFile",
|
|
20
|
+
"Generate an output for a local snapshot",
|
|
21
|
+
// eslint-disable-next-line @typescript-eslint/no-shadow
|
|
22
|
+
(yargs) =>
|
|
23
|
+
yargs
|
|
24
|
+
.option("codeLoader", {
|
|
25
|
+
describe: "Name of the code loader bundle",
|
|
26
|
+
type: "string",
|
|
27
|
+
demandOption: true,
|
|
28
|
+
})
|
|
29
|
+
.option("inputFile", {
|
|
30
|
+
describe: "Name of the file containing local ODSP snapshot",
|
|
31
|
+
type: "string",
|
|
32
|
+
demandOption: true,
|
|
33
|
+
})
|
|
34
|
+
.option("outputFolder", {
|
|
35
|
+
describe: "Name of the output file",
|
|
36
|
+
type: "string",
|
|
37
|
+
demandOption: true,
|
|
38
|
+
})
|
|
39
|
+
.option("scenario", {
|
|
40
|
+
describe: "Name of scenario to invoke",
|
|
41
|
+
type: "string",
|
|
42
|
+
demandOption: true,
|
|
43
|
+
})
|
|
44
|
+
.option("telemetryFile", {
|
|
45
|
+
describe: "Config and session data for telemetry",
|
|
46
|
+
type: "string",
|
|
47
|
+
demandOption: true,
|
|
48
|
+
}),
|
|
49
|
+
// eslint-disable-next-line @typescript-eslint/no-misused-promises
|
|
50
|
+
async (argv) => {
|
|
51
|
+
if (fs.existsSync(argv.telemetryFile)) {
|
|
52
|
+
console.error(`Telemetry file already exists [${argv.telemetryFile}]`);
|
|
53
|
+
process.exit(1);
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
const fileLogger = new FileLogger(argv.telemetryFile);
|
|
57
|
+
|
|
58
|
+
const logger = ChildLogger.create(fileLogger, "LocalSnapshotRunnerApp",
|
|
59
|
+
{ all: { Event_Time: () => Date.now() } });
|
|
60
|
+
|
|
61
|
+
const result = await exportFile(
|
|
62
|
+
argv.codeLoader,
|
|
63
|
+
argv.inputFile,
|
|
64
|
+
argv.outputFolder,
|
|
65
|
+
argv.scenario,
|
|
66
|
+
logger,
|
|
67
|
+
);
|
|
68
|
+
|
|
69
|
+
if (!result.success) {
|
|
70
|
+
console.error(`${result.eventName}: ${result.errorMessage}`);
|
|
71
|
+
logger.sendErrorEvent({ eventName: result.eventName, message: result.errorMessage }, result.error);
|
|
72
|
+
await fileLogger.flush();
|
|
73
|
+
process.exit(1);
|
|
74
|
+
} else {
|
|
75
|
+
await fileLogger.flush();
|
|
76
|
+
}
|
|
77
|
+
},
|
|
78
|
+
)
|
|
79
|
+
.help()
|
|
80
|
+
.demandCommand().argv;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
fluidRunner();
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
/*!
|
|
2
|
+
* Copyright (c) Microsoft Corporation and contributors. All rights reserved.
|
|
3
|
+
* Licensed under the MIT License.
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import * as fs from "fs";
|
|
7
|
+
|
|
8
|
+
export function getArgsValidationError(
|
|
9
|
+
inputFile: string,
|
|
10
|
+
outputFolder: string,
|
|
11
|
+
scenario: string,
|
|
12
|
+
): string | undefined {
|
|
13
|
+
// Validate input file
|
|
14
|
+
if (!inputFile) {
|
|
15
|
+
// TODO: Do not log file name. It can be customer content
|
|
16
|
+
return "Input file name is missing.";
|
|
17
|
+
} else if (!fs.existsSync(inputFile)) {
|
|
18
|
+
return "Input file does not exist.";
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
// Validate output file
|
|
22
|
+
if (!outputFolder) {
|
|
23
|
+
return "Output folder name is missing.";
|
|
24
|
+
} else if (!fs.existsSync(outputFolder)) {
|
|
25
|
+
return "Output folder does not exist.";
|
|
26
|
+
} else if (fs.existsSync(`${outputFolder}/index.html`)) {
|
|
27
|
+
return "Output file already exists.";
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
// Validate scenario name
|
|
31
|
+
if (!scenario) {
|
|
32
|
+
return "Scenario name is missing.";
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
return undefined;
|
|
36
|
+
}
|
package/src/index.ts
ADDED
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/*!
|
|
2
|
+
* Copyright (c) Microsoft Corporation and contributors. All rights reserved.
|
|
3
|
+
* Licensed under the MIT License.
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import * as fs from "fs";
|
|
7
|
+
import { ITelemetryBaseEvent, ITelemetryBaseLogger } from "@fluidframework/common-definitions";
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Logger that writes events into a defined file
|
|
11
|
+
*/
|
|
12
|
+
export class FileLogger implements ITelemetryBaseLogger {
|
|
13
|
+
public supportsTags?: true | undefined;
|
|
14
|
+
|
|
15
|
+
/** Hold events in memory until flushed */
|
|
16
|
+
private events: string[] = [];
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* @param filePath - file path to write logs to
|
|
20
|
+
* @param eventsPerFlush - number of events per flush
|
|
21
|
+
*/
|
|
22
|
+
public constructor(
|
|
23
|
+
private readonly filePath: string,
|
|
24
|
+
private readonly eventsPerFlush: number = 50,
|
|
25
|
+
) { }
|
|
26
|
+
|
|
27
|
+
public async flush(): Promise<void> {
|
|
28
|
+
if (this.events.length > 0) {
|
|
29
|
+
fs.appendFileSync(this.filePath, this.events.join("\n"));
|
|
30
|
+
this.events = [];
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
public send(event: ITelemetryBaseEvent): void {
|
|
35
|
+
const logEvent = JSON.stringify(event);
|
|
36
|
+
|
|
37
|
+
this.events.push(logEvent);
|
|
38
|
+
|
|
39
|
+
if (this.events.length >= this.eventsPerFlush || event.category === "error") {
|
|
40
|
+
// eslint-disable-next-line @typescript-eslint/no-floating-promises
|
|
41
|
+
this.flush();
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/*!
|
|
2
|
+
* Copyright (c) Microsoft Corporation and contributors. All rights reserved.
|
|
3
|
+
* Licensed under the MIT License.
|
|
4
|
+
*
|
|
5
|
+
* THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
export const pkgName = "@fluidframework/fluid-runner";
|
|
9
|
+
export const pkgVersion = "1.2.0";
|
package/tsconfig.json
ADDED