@memlab/cli 2.0.4 → 2.0.5

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.
@@ -0,0 +1,21 @@
1
+ /**
2
+ * Copyright (c) Meta Platforms, Inc. and affiliates.
3
+ *
4
+ * This source code is licensed under the MIT license found in the
5
+ * LICENSE file in the root directory of this source tree.
6
+ *
7
+ * @format
8
+ * @oncall memory_lab
9
+ */
10
+ import type { CLIOptions } from '@memlab/core';
11
+ import { BaseOption } from '@memlab/core';
12
+ import BaseCommand, { CommandCategory } from '../../BaseCommand';
13
+ export default class AnonymizeSnapshotCommand extends BaseCommand {
14
+ getCommandName(): string;
15
+ getDescription(): string;
16
+ getCategory(): CommandCategory;
17
+ getExamples(): string[];
18
+ getOptions(): BaseOption[];
19
+ run(options: CLIOptions): Promise<void>;
20
+ }
21
+ //# sourceMappingURL=AnonymizeSnapshotCommand.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"AnonymizeSnapshotCommand.d.ts","sourceRoot":"","sources":["../../../src/commands/heap/AnonymizeSnapshotCommand.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAkB,UAAU,EAAC,MAAM,cAAc,CAAC;AAE9D,OAAO,EAGL,UAAU,EAIX,MAAM,cAAc,CAAC;AACtB,OAAO,WAAW,EAAE,EAAC,eAAe,EAAC,MAAM,mBAAmB,CAAC;AA0C/D,MAAM,CAAC,OAAO,OAAO,wBAAyB,SAAQ,WAAW;IAC/D,cAAc,IAAI,MAAM;IAIxB,cAAc,IAAI,MAAM;IAIxB,WAAW,IAAI,eAAe;IAI9B,WAAW,IAAI,MAAM,EAAE;IAQvB,UAAU,IAAI,UAAU,EAAE;IAWpB,GAAG,CAAC,OAAO,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC;CA4D9C"}
@@ -0,0 +1,170 @@
1
+ "use strict";
2
+ /**
3
+ * Copyright (c) Meta Platforms, Inc. and affiliates.
4
+ *
5
+ * This source code is licensed under the MIT license found in the
6
+ * LICENSE file in the root directory of this source tree.
7
+ *
8
+ * @format
9
+ * @oncall memory_lab
10
+ */
11
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
12
+ if (k2 === undefined) k2 = k;
13
+ var desc = Object.getOwnPropertyDescriptor(m, k);
14
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
15
+ desc = { enumerable: true, get: function() { return m[k]; } };
16
+ }
17
+ Object.defineProperty(o, k2, desc);
18
+ }) : (function(o, m, k, k2) {
19
+ if (k2 === undefined) k2 = k;
20
+ o[k2] = m[k];
21
+ }));
22
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
23
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
24
+ }) : function(o, v) {
25
+ o["default"] = v;
26
+ });
27
+ var __importStar = (this && this.__importStar) || (function () {
28
+ var ownKeys = function(o) {
29
+ ownKeys = Object.getOwnPropertyNames || function (o) {
30
+ var ar = [];
31
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
32
+ return ar;
33
+ };
34
+ return ownKeys(o);
35
+ };
36
+ return function (mod) {
37
+ if (mod && mod.__esModule) return mod;
38
+ var result = {};
39
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
40
+ __setModuleDefault(result, mod);
41
+ return result;
42
+ };
43
+ })();
44
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
45
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
46
+ return new (P || (P = Promise))(function (resolve, reject) {
47
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
48
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
49
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
50
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
51
+ });
52
+ };
53
+ var __importDefault = (this && this.__importDefault) || function (mod) {
54
+ return (mod && mod.__esModule) ? mod : { "default": mod };
55
+ };
56
+ Object.defineProperty(exports, "__esModule", { value: true });
57
+ const core_1 = require("@memlab/core");
58
+ const BaseCommand_1 = __importStar(require("../../BaseCommand"));
59
+ const AnonymizeAuditOnlyOption_1 = __importDefault(require("../../options/heap/AnonymizeAuditOnlyOption"));
60
+ const AnonymizeModeOption_1 = __importDefault(require("../../options/heap/AnonymizeModeOption"));
61
+ const AnonymizeOutputOption_1 = __importDefault(require("../../options/heap/AnonymizeOutputOption"));
62
+ const AnonymizeSaltOption_1 = __importDefault(require("../../options/heap/AnonymizeSaltOption"));
63
+ const OptionConstant_1 = __importDefault(require("../../options/lib/OptionConstant"));
64
+ const SnapshotDirectoryOption_1 = __importDefault(require("../../options/heap/SnapshotDirectoryOption"));
65
+ const SnapshotFileOption_1 = __importDefault(require("../../options/heap/SnapshotFileOption"));
66
+ function printReport(report, wrote) {
67
+ core_1.info.topLevel(wrote != null ? `Anonymized snapshot written to ${wrote}` : 'Audit only');
68
+ core_1.info.lowLevel(` mode: ${report.mode}${report.salted ? ' (salted)' : ''}`);
69
+ core_1.info.lowLevel(` string table entries: ${report.stringTableSize}`);
70
+ core_1.info.lowLevel(` heap string values redacted: ${report.valuesRedacted}`);
71
+ core_1.info.lowLevel(` entries split to keep a label: ${report.entriesSplit}`);
72
+ core_1.info.lowLevel(` entries redacted by content: ${report.contentRedacted}`);
73
+ for (const rule of report.contentRedactedByRule) {
74
+ core_1.info.lowLevel(` ${rule.rule}: ${rule.count}`);
75
+ }
76
+ // Printed even when it is empty, and printed last, because it is the part a
77
+ // reader has to act on. A tool that only lists what it removed invites the
78
+ // reader to assume the rest was safe.
79
+ core_1.info.topLevel('Still in the clear — review before sharing:');
80
+ if (report.unclassifiedLabelFamilies.length === 0) {
81
+ core_1.info.lowLevel(' (no machine-generated-looking labels remain)');
82
+ return;
83
+ }
84
+ for (const family of report.unclassifiedLabelFamilies) {
85
+ const examples = family.examples
86
+ .map(e => (e.length > 40 ? `${e.slice(0, 37)}...` : e))
87
+ .join(', ');
88
+ core_1.info.lowLevel(` ${family.count} x ${family.shape} e.g. ${examples}`);
89
+ }
90
+ core_1.info.lowLevel(' Any of these that is an identifier in YOUR application is a residual; ' +
91
+ 'anonymize again from the API with a `shouldRedact` callback to remove it.');
92
+ }
93
+ class AnonymizeSnapshotCommand extends BaseCommand_1.default {
94
+ getCommandName() {
95
+ return 'anonymize';
96
+ }
97
+ getDescription() {
98
+ return 'remove user data from a heap snapshot so it can be shared';
99
+ }
100
+ getCategory() {
101
+ return BaseCommand_1.CommandCategory.COMMON;
102
+ }
103
+ getExamples() {
104
+ return [
105
+ '--snapshot <HEAP_SNAPSHOT_FILE> --output <OUTPUT_FILE>',
106
+ '--snapshot <HEAP_SNAPSHOT_FILE> --output <OUTPUT_FILE> --anonymize-salt <SALT>',
107
+ '--snapshot <HEAP_SNAPSHOT_FILE> --audit-only',
108
+ ];
109
+ }
110
+ getOptions() {
111
+ return [
112
+ new SnapshotFileOption_1.default(),
113
+ new SnapshotDirectoryOption_1.default(),
114
+ new AnonymizeOutputOption_1.default(),
115
+ new AnonymizeModeOption_1.default(),
116
+ new AnonymizeSaltOption_1.default(),
117
+ new AnonymizeAuditOnlyOption_1.default(),
118
+ ];
119
+ }
120
+ run(options) {
121
+ return __awaiter(this, void 0, void 0, function* () {
122
+ const args = options.cliArgs;
123
+ const names = OptionConstant_1.default.optionNames;
124
+ const input = core_1.utils.getSingleSnapshotFileForAnalysis();
125
+ const output = args[names.ANONYMIZE_OUTPUT];
126
+ const auditOnly = Boolean(args[names.ANONYMIZE_AUDIT_ONLY]);
127
+ const anonymizeOptions = {
128
+ mode: args[names.ANONYMIZE_MODE],
129
+ salt: args[names.ANONYMIZE_SALT],
130
+ };
131
+ if (auditOnly) {
132
+ if (output) {
133
+ // Said out loud rather than ignored. The whole point of this command is
134
+ // that the caller knows exactly what did and did not happen to their
135
+ // capture; silently dropping the output path leaves them looking for a
136
+ // file that was never written.
137
+ core_1.info.warning(`--${names.ANONYMIZE_AUDIT_ONLY} writes nothing, so ` +
138
+ `--${names.ANONYMIZE_OUTPUT}=${output} is ignored. Re-run without ` +
139
+ `--${names.ANONYMIZE_AUDIT_ONLY} to produce that file.`);
140
+ }
141
+ printReport(yield (0, core_1.auditHeapSnapshotFile)(input, anonymizeOptions), null);
142
+ return;
143
+ }
144
+ if (!output) {
145
+ // Refusing rather than defaulting to a path next to the input: writing an
146
+ // anonymized copy somewhere the caller did not name is how a file ends up
147
+ // shared by accident, and overwriting the original would destroy the only
148
+ // unredacted copy.
149
+ core_1.utils.haltOrThrow(`Specify --${names.ANONYMIZE_OUTPUT} <FILE> to write the anonymized ` +
150
+ `snapshot to, or --${names.ANONYMIZE_AUDIT_ONLY} to only report ` +
151
+ `what would be redacted.`);
152
+ return;
153
+ }
154
+ // Compared canonically, not as strings. `input` arrives already resolved
155
+ // from `getSingleSnapshotFileForAnalysis`, while `output` is whatever the
156
+ // user typed, so `./capture.heapsnapshot`, a relative path, or a symlink to
157
+ // the input are all spellings this guard has to catch — missing one
158
+ // overwrites the only unredacted copy, which is the thing it exists to
159
+ // prevent. The API refuses too; this is here to fail with a CLI-shaped
160
+ // message before any work starts.
161
+ if ((0, core_1.resolveForComparison)(output) === (0, core_1.resolveForComparison)(input)) {
162
+ core_1.utils.haltOrThrow(`--${names.ANONYMIZE_OUTPUT} resolves to the same file as the input ` +
163
+ `snapshot; anonymizing in place would destroy the original capture.`);
164
+ return;
165
+ }
166
+ printReport(yield (0, core_1.anonymizeHeapSnapshotFile)(input, output, anonymizeOptions), output);
167
+ });
168
+ }
169
+ }
170
+ exports.default = AnonymizeSnapshotCommand;
@@ -0,0 +1,18 @@
1
+ /**
2
+ * Copyright (c) Meta Platforms, Inc. and affiliates.
3
+ *
4
+ * This source code is licensed under the MIT license found in the
5
+ * LICENSE file in the root directory of this source tree.
6
+ *
7
+ * @format
8
+ * @oncall memory_lab
9
+ */
10
+ import type { ParsedArgs } from 'minimist';
11
+ import type { MemLabConfig } from '@memlab/core';
12
+ import { BaseOption } from '@memlab/core';
13
+ export default class AnonymizeAuditOnlyOption extends BaseOption {
14
+ getOptionName(): string;
15
+ getDescription(): string;
16
+ parse(config: MemLabConfig, args: ParsedArgs): Promise<void>;
17
+ }
18
+ //# sourceMappingURL=AnonymizeAuditOnlyOption.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"AnonymizeAuditOnlyOption.d.ts","sourceRoot":"","sources":["../../../src/options/heap/AnonymizeAuditOnlyOption.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAC,UAAU,EAAC,MAAM,UAAU,CAAC;AACzC,OAAO,KAAK,EAAC,YAAY,EAAC,MAAM,cAAc,CAAC;AAC/C,OAAO,EAAC,UAAU,EAAQ,MAAM,cAAc,CAAC;AAG/C,MAAM,CAAC,OAAO,OAAO,wBAAyB,SAAQ,UAAU;IAC9D,aAAa,IAAI,MAAM;IAIvB,cAAc,IAAI,MAAM;IAQlB,KAAK,CAAC,MAAM,EAAE,YAAY,EAAE,IAAI,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC;CAQnE"}
@@ -0,0 +1,44 @@
1
+ "use strict";
2
+ /**
3
+ * Copyright (c) Meta Platforms, Inc. and affiliates.
4
+ *
5
+ * This source code is licensed under the MIT license found in the
6
+ * LICENSE file in the root directory of this source tree.
7
+ *
8
+ * @format
9
+ * @oncall memory_lab
10
+ */
11
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
12
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
13
+ return new (P || (P = Promise))(function (resolve, reject) {
14
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
15
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
16
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
17
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
18
+ });
19
+ };
20
+ var __importDefault = (this && this.__importDefault) || function (mod) {
21
+ return (mod && mod.__esModule) ? mod : { "default": mod };
22
+ };
23
+ Object.defineProperty(exports, "__esModule", { value: true });
24
+ const core_1 = require("@memlab/core");
25
+ const OptionConstant_1 = __importDefault(require("../lib/OptionConstant"));
26
+ class AnonymizeAuditOnlyOption extends core_1.BaseOption {
27
+ getOptionName() {
28
+ return OptionConstant_1.default.optionNames.ANONYMIZE_AUDIT_ONLY;
29
+ }
30
+ getDescription() {
31
+ return ('report what would be redacted and what would be left in the clear, ' +
32
+ 'without writing a file. Use it on a capture someone already ' +
33
+ 'anonymized to check whether anything was missed');
34
+ }
35
+ parse(config, args) {
36
+ return __awaiter(this, void 0, void 0, function* () {
37
+ const value = args[this.getOptionName()];
38
+ if (value != null && typeof value !== 'boolean') {
39
+ core_1.utils.haltOrThrow(`--${this.getOptionName()} is a flag and takes no value, got: ${value}`);
40
+ }
41
+ });
42
+ }
43
+ }
44
+ exports.default = AnonymizeAuditOnlyOption;
@@ -0,0 +1,19 @@
1
+ /**
2
+ * Copyright (c) Meta Platforms, Inc. and affiliates.
3
+ *
4
+ * This source code is licensed under the MIT license found in the
5
+ * LICENSE file in the root directory of this source tree.
6
+ *
7
+ * @format
8
+ * @oncall memory_lab
9
+ */
10
+ import type { ParsedArgs } from 'minimist';
11
+ import type { MemLabConfig } from '@memlab/core';
12
+ import { BaseOption } from '@memlab/core';
13
+ export default class AnonymizeModeOption extends BaseOption {
14
+ getOptionName(): string;
15
+ getDescription(): string;
16
+ getExampleValues(): string[];
17
+ parse(config: MemLabConfig, args: ParsedArgs): Promise<void>;
18
+ }
19
+ //# sourceMappingURL=AnonymizeModeOption.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"AnonymizeModeOption.d.ts","sourceRoot":"","sources":["../../../src/options/heap/AnonymizeModeOption.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAC,UAAU,EAAC,MAAM,UAAU,CAAC;AACzC,OAAO,KAAK,EAAC,YAAY,EAAC,MAAM,cAAc,CAAC;AAC/C,OAAO,EAAC,UAAU,EAAQ,MAAM,cAAc,CAAC;AAK/C,MAAM,CAAC,OAAO,OAAO,mBAAoB,SAAQ,UAAU;IACzD,aAAa,IAAI,MAAM;IAIvB,cAAc,IAAI,MAAM;IAQxB,gBAAgB,IAAI,MAAM,EAAE;IAOtB,KAAK,CAAC,MAAM,EAAE,YAAY,EAAE,IAAI,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC;CAQnE"}
@@ -0,0 +1,51 @@
1
+ "use strict";
2
+ /**
3
+ * Copyright (c) Meta Platforms, Inc. and affiliates.
4
+ *
5
+ * This source code is licensed under the MIT license found in the
6
+ * LICENSE file in the root directory of this source tree.
7
+ *
8
+ * @format
9
+ * @oncall memory_lab
10
+ */
11
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
12
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
13
+ return new (P || (P = Promise))(function (resolve, reject) {
14
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
15
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
16
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
17
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
18
+ });
19
+ };
20
+ var __importDefault = (this && this.__importDefault) || function (mod) {
21
+ return (mod && mod.__esModule) ? mod : { "default": mod };
22
+ };
23
+ Object.defineProperty(exports, "__esModule", { value: true });
24
+ const core_1 = require("@memlab/core");
25
+ const OptionConstant_1 = __importDefault(require("../lib/OptionConstant"));
26
+ const MODES = ['stable', 'uniform'];
27
+ class AnonymizeModeOption extends core_1.BaseOption {
28
+ getOptionName() {
29
+ return OptionConstant_1.default.optionNames.ANONYMIZE_MODE;
30
+ }
31
+ getDescription() {
32
+ return ('set how redacted text is generated: ' +
33
+ '`stable` (default) keeps distinct values distinct so duplication ' +
34
+ 'analysis stays accurate, `uniform` replaces every character with ?');
35
+ }
36
+ getExampleValues() {
37
+ // A copy: the same array backs the validation in `parse`, so handing the
38
+ // live reference to a caller lets a mutation there decide what this option
39
+ // accepts.
40
+ return [...MODES];
41
+ }
42
+ parse(config, args) {
43
+ return __awaiter(this, void 0, void 0, function* () {
44
+ const value = args[this.getOptionName()];
45
+ if (value != null && !MODES.includes(String(value))) {
46
+ core_1.utils.haltOrThrow(`Invalid --${this.getOptionName()}: ${value}. Expected one of: ${MODES.join(', ')}`);
47
+ }
48
+ });
49
+ }
50
+ }
51
+ exports.default = AnonymizeModeOption;
@@ -0,0 +1,19 @@
1
+ /**
2
+ * Copyright (c) Meta Platforms, Inc. and affiliates.
3
+ *
4
+ * This source code is licensed under the MIT license found in the
5
+ * LICENSE file in the root directory of this source tree.
6
+ *
7
+ * @format
8
+ * @oncall memory_lab
9
+ */
10
+ import type { ParsedArgs } from 'minimist';
11
+ import type { MemLabConfig } from '@memlab/core';
12
+ import { BaseOption } from '@memlab/core';
13
+ export default class AnonymizeOutputOption extends BaseOption {
14
+ getOptionName(): string;
15
+ getDescription(): string;
16
+ getExampleValues(): string[];
17
+ parse(config: MemLabConfig, args: ParsedArgs): Promise<void>;
18
+ }
19
+ //# sourceMappingURL=AnonymizeOutputOption.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"AnonymizeOutputOption.d.ts","sourceRoot":"","sources":["../../../src/options/heap/AnonymizeOutputOption.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAC,UAAU,EAAC,MAAM,UAAU,CAAC;AACzC,OAAO,KAAK,EAAC,YAAY,EAAC,MAAM,cAAc,CAAC;AAC/C,OAAO,EAAC,UAAU,EAAQ,MAAM,cAAc,CAAC;AAG/C,MAAM,CAAC,OAAO,OAAO,qBAAsB,SAAQ,UAAU;IAC3D,aAAa,IAAI,MAAM;IAIvB,cAAc,IAAI,MAAM;IAIxB,gBAAgB,IAAI,MAAM,EAAE;IAItB,KAAK,CAAC,MAAM,EAAE,YAAY,EAAE,IAAI,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC;CAMnE"}
@@ -0,0 +1,45 @@
1
+ "use strict";
2
+ /**
3
+ * Copyright (c) Meta Platforms, Inc. and affiliates.
4
+ *
5
+ * This source code is licensed under the MIT license found in the
6
+ * LICENSE file in the root directory of this source tree.
7
+ *
8
+ * @format
9
+ * @oncall memory_lab
10
+ */
11
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
12
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
13
+ return new (P || (P = Promise))(function (resolve, reject) {
14
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
15
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
16
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
17
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
18
+ });
19
+ };
20
+ var __importDefault = (this && this.__importDefault) || function (mod) {
21
+ return (mod && mod.__esModule) ? mod : { "default": mod };
22
+ };
23
+ Object.defineProperty(exports, "__esModule", { value: true });
24
+ const core_1 = require("@memlab/core");
25
+ const OptionConstant_1 = __importDefault(require("../lib/OptionConstant"));
26
+ class AnonymizeOutputOption extends core_1.BaseOption {
27
+ getOptionName() {
28
+ return OptionConstant_1.default.optionNames.ANONYMIZE_OUTPUT;
29
+ }
30
+ getDescription() {
31
+ return 'set file path to write the anonymized heap snapshot to';
32
+ }
33
+ getExampleValues() {
34
+ return ['/tmp/shareable.heapsnapshot'];
35
+ }
36
+ parse(config, args) {
37
+ return __awaiter(this, void 0, void 0, function* () {
38
+ const value = args[this.getOptionName()];
39
+ if (value != null && typeof value !== 'string') {
40
+ core_1.utils.haltOrThrow(`Invalid --${this.getOptionName()} value: ${value}`);
41
+ }
42
+ });
43
+ }
44
+ }
45
+ exports.default = AnonymizeOutputOption;
@@ -0,0 +1,19 @@
1
+ /**
2
+ * Copyright (c) Meta Platforms, Inc. and affiliates.
3
+ *
4
+ * This source code is licensed under the MIT license found in the
5
+ * LICENSE file in the root directory of this source tree.
6
+ *
7
+ * @format
8
+ * @oncall memory_lab
9
+ */
10
+ import type { ParsedArgs } from 'minimist';
11
+ import type { MemLabConfig } from '@memlab/core';
12
+ import { BaseOption } from '@memlab/core';
13
+ export default class AnonymizeSaltOption extends BaseOption {
14
+ getOptionName(): string;
15
+ getDescription(): string;
16
+ getExampleValues(): string[];
17
+ parse(config: MemLabConfig, args: ParsedArgs): Promise<void>;
18
+ }
19
+ //# sourceMappingURL=AnonymizeSaltOption.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"AnonymizeSaltOption.d.ts","sourceRoot":"","sources":["../../../src/options/heap/AnonymizeSaltOption.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAC,UAAU,EAAC,MAAM,UAAU,CAAC;AACzC,OAAO,KAAK,EAAC,YAAY,EAAC,MAAM,cAAc,CAAC;AAC/C,OAAO,EAAC,UAAU,EAAQ,MAAM,cAAc,CAAC;AAG/C,MAAM,CAAC,OAAO,OAAO,mBAAoB,SAAQ,UAAU;IACzD,aAAa,IAAI,MAAM;IAIvB,cAAc,IAAI,MAAM;IASxB,gBAAgB,IAAI,MAAM,EAAE;IAItB,KAAK,CAAC,MAAM,EAAE,YAAY,EAAE,IAAI,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC;CAMnE"}
@@ -0,0 +1,48 @@
1
+ "use strict";
2
+ /**
3
+ * Copyright (c) Meta Platforms, Inc. and affiliates.
4
+ *
5
+ * This source code is licensed under the MIT license found in the
6
+ * LICENSE file in the root directory of this source tree.
7
+ *
8
+ * @format
9
+ * @oncall memory_lab
10
+ */
11
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
12
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
13
+ return new (P || (P = Promise))(function (resolve, reject) {
14
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
15
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
16
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
17
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
18
+ });
19
+ };
20
+ var __importDefault = (this && this.__importDefault) || function (mod) {
21
+ return (mod && mod.__esModule) ? mod : { "default": mod };
22
+ };
23
+ Object.defineProperty(exports, "__esModule", { value: true });
24
+ const core_1 = require("@memlab/core");
25
+ const OptionConstant_1 = __importDefault(require("../lib/OptionConstant"));
26
+ class AnonymizeSaltOption extends core_1.BaseOption {
27
+ getOptionName() {
28
+ return OptionConstant_1.default.optionNames.ANONYMIZE_SALT;
29
+ }
30
+ getDescription() {
31
+ return ('set a salt for the replacement text. Without one the mapping is the ' +
32
+ 'same in every capture, which keeps a set of snapshots comparable but ' +
33
+ 'lets anyone holding a candidate value confirm it. Use the SAME salt ' +
34
+ 'for every file in a set');
35
+ }
36
+ getExampleValues() {
37
+ return ['my-team-salt'];
38
+ }
39
+ parse(config, args) {
40
+ return __awaiter(this, void 0, void 0, function* () {
41
+ const value = args[this.getOptionName()];
42
+ if (value != null && typeof value !== 'string') {
43
+ core_1.utils.haltOrThrow(`Invalid --${this.getOptionName()} value: ${value}`);
44
+ }
45
+ });
46
+ }
47
+ }
48
+ exports.default = AnonymizeSaltOption;
@@ -9,6 +9,10 @@
9
9
  */
10
10
  declare const optionConstants: {
11
11
  optionNames: {
12
+ ANONYMIZE_AUDIT_ONLY: string;
13
+ ANONYMIZE_MODE: string;
14
+ ANONYMIZE_OUTPUT: string;
15
+ ANONYMIZE_SALT: string;
12
16
  APP: string;
13
17
  BASELINE: string;
14
18
  CLEAN_UP_SNAPSHOT: string;
@@ -75,6 +79,10 @@ declare const optionConstants: {
75
79
  export type OptionConstants = typeof optionConstants;
76
80
  declare const _default: {
77
81
  optionNames: {
82
+ ANONYMIZE_AUDIT_ONLY: string;
83
+ ANONYMIZE_MODE: string;
84
+ ANONYMIZE_OUTPUT: string;
85
+ ANONYMIZE_SALT: string;
78
86
  APP: string;
79
87
  BASELINE: string;
80
88
  CLEAN_UP_SNAPSHOT: string;
@@ -1 +1 @@
1
- {"version":3,"file":"OptionConstant.d.ts","sourceRoot":"","sources":["../../../src/options/lib/OptionConstant.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAqEH,QAAA,MAAM,eAAe;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAGpB,CAAC;AACF,MAAM,MAAM,eAAe,GAAG,OAAO,eAAe,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AACrD,wBAIE"}
1
+ {"version":3,"file":"OptionConstant.d.ts","sourceRoot":"","sources":["../../../src/options/lib/OptionConstant.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAyEH,QAAA,MAAM,eAAe;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAGpB,CAAC;AACF,MAAM,MAAM,eAAe,GAAG,OAAO,eAAe,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AACrD,wBAIE"}
@@ -11,6 +11,10 @@
11
11
  Object.defineProperty(exports, "__esModule", { value: true });
12
12
  const core_1 = require("@memlab/core");
13
13
  const optionNames = {
14
+ ANONYMIZE_AUDIT_ONLY: 'audit-only',
15
+ ANONYMIZE_MODE: 'anonymize-mode',
16
+ ANONYMIZE_OUTPUT: 'output',
17
+ ANONYMIZE_SALT: 'anonymize-salt',
14
18
  APP: 'app',
15
19
  BASELINE: 'baseline',
16
20
  CLEAN_UP_SNAPSHOT: 'clean-up-snapshot',
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@memlab/cli",
3
- "version": "2.0.4",
3
+ "version": "2.0.5",
4
4
  "license": "MIT",
5
5
  "description": "command line interface for memlab",
6
6
  "author": "Liang Gong <lgong@meta.com>",
@@ -26,10 +26,10 @@
26
26
  "access": "public"
27
27
  },
28
28
  "dependencies": {
29
- "@memlab/api": "^2.0.4",
30
- "@memlab/core": "^2.0.4",
31
- "@memlab/e2e": "^2.0.4",
32
- "@memlab/heap-analysis": "^2.0.4",
29
+ "@memlab/api": "^2.0.5",
30
+ "@memlab/core": "^2.0.5",
31
+ "@memlab/e2e": "^2.0.5",
32
+ "@memlab/heap-analysis": "^2.0.5",
33
33
  "ansi": "^0.3.1",
34
34
  "babar": "^0.2.0",
35
35
  "blessed": "^0.1.81",