@cdklabs/eslint-plugin 0.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.
@@ -0,0 +1,134 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.create = create;
4
+ const type_checkers_1 = require("../private/type-checkers");
5
+ let namespaceImports = {};
6
+ function create(context) {
7
+ // The format of Cfn imports only matters for alpha packages, so that they can be
8
+ // formatted correctly when released separately for V2. The linter rule should only be
9
+ // applied if the file is in an alpha package, or it is a test file.
10
+ const filename = context.getFilename();
11
+ if (!currentFileIsInAlphaPackage(filename) && !filename.match('test/rules/fixtures')) {
12
+ return {};
13
+ }
14
+ return {
15
+ ImportDeclaration: node => {
16
+ const location = node.source.value;
17
+ // Store all of the 'import * as name from location' imports, so that we can check the location when
18
+ // we find name.CfnXXX references.
19
+ node.specifiers.forEach(e => {
20
+ if (e.type === 'ImportNamespaceSpecifier') {
21
+ namespaceImports[e.local.name] = location;
22
+ }
23
+ });
24
+ if (location.endsWith('generated') || location === '@aws-cdk/core') {
25
+ // If importing directly from a generated file, this is fine. Also we know that aws-cdk/core is not experimental, so that is fine as well.
26
+ return;
27
+ }
28
+ const cfnImports = [];
29
+ const otherImports = [];
30
+ node.specifiers.forEach(e => {
31
+ if (e.type === 'ImportSpecifier' && (0, type_checkers_1.isIdentifier)(e.imported)) {
32
+ if (e.imported.name.startsWith('Cfn')) {
33
+ cfnImports.push(e);
34
+ }
35
+ else {
36
+ otherImports.push(e);
37
+ }
38
+ }
39
+ });
40
+ if (cfnImports.length > 0 && otherImports.length > 0 && location.startsWith('.')) {
41
+ // import { CfnXXX, SomethingElse, AnotherThing } from './some/relative/path/not/ending/in/generated';
42
+ context.report({
43
+ message: 'To allow rewriting imports when generating v2 experimental packages, import of `' + cfnImports.map(e => e.imported.name).join(', ') + '` must be separate from import of `' + otherImports.map(e => e.imported.name).join(', ') + '`, and imported from its specific .generated location.',
44
+ node: node,
45
+ });
46
+ }
47
+ else if (cfnImports.length > 0 && location.startsWith('.')) {
48
+ // import { CfnXXX } from './some/relative/path/not/ending/in/generated';
49
+ context.report({
50
+ message: 'To allow rewriting imports when generating v2 experimental packages, import of `' + cfnImports.map(e => e.imported.name).join(', ') + '` must be imported from its specific .generated location.',
51
+ node: node,
52
+ });
53
+ }
54
+ else if (cfnImports.length > 0 && otherImports.length > 0 && checkIfImportedLocationIsAnAlphaPackage(location)) {
55
+ // import { CfnXXX, SomethingElse, AnotherThing } from '@aws-cdk/another-alpha-package';
56
+ context.report({
57
+ message: 'To allow rewriting imports when generating v2 experimental packages, import of `' + cfnImports.map(e => e.imported.name).join(', ') + '` must be separate from import of `' + otherImports.map(e => e.imported.name).join(', ') + '`',
58
+ node: node,
59
+ });
60
+ }
61
+ },
62
+ // This captures using `xxx.CfnConstruct` as an identifier
63
+ Identifier: node => {
64
+ var _a;
65
+ const typeAnnotation = (_a = node.typeAnnotation) === null || _a === void 0 ? void 0 : _a.typeAnnotation;
66
+ const type = typeAnnotation === null || typeAnnotation === void 0 ? void 0 : typeAnnotation.typeName;
67
+ if ((type === null || type === void 0 ? void 0 : type.type) === 'TSQualifiedName') {
68
+ const result = checkLeftAndRightForCfn(type);
69
+ if (result) {
70
+ reportErrorIfImportedLocationIsNotValid(context, node, result.name, result.location);
71
+ }
72
+ }
73
+ if (node.name.startsWith('Cfn') && node.parent.type === 'MemberExpression' && node.parent.object.type === 'Identifier') {
74
+ // new xxx.CfnConstruct();
75
+ reportErrorIfImportedLocationIsNotValid(context, node, node.name, node.parent.object.name);
76
+ }
77
+ },
78
+ };
79
+ }
80
+ function reportErrorIfImportedLocationIsNotValid(context, node, name, barrelImportName) {
81
+ const location = namespaceImports[barrelImportName];
82
+ if (!location) {
83
+ // This scenario should not happen, but if it does, we don't want users to run into weird runtime errors from the linter.
84
+ return;
85
+ }
86
+ if (location.endsWith('generated') || location === '@aws-cdk/core') {
87
+ return;
88
+ }
89
+ if (location.startsWith('.')) {
90
+ // import * as name from './some/relative/path/not/ending/in/generated'; name.CfnConstruct();
91
+ context.report({
92
+ message: 'To allow rewriting imports when generating v2 experimental packages, `' + name + '` must be imported by name from its specific .generated location.',
93
+ node: node,
94
+ });
95
+ }
96
+ else if (checkIfImportedLocationIsAnAlphaPackage(location)) {
97
+ // import * as name from '@aws-cdk/another-alpha-package'; name.CfnConstruct();
98
+ context.report({
99
+ message: 'To allow rewriting imports when generating v2 experimental packages, `' + name + '` must be imported by name and separate from non-L1 imports, since it is being imported from an experimental package: ' + location,
100
+ node: node,
101
+ });
102
+ }
103
+ }
104
+ const ALPHA_RE = /@aws-cdk(\/|\\)[a-z0-9-]+-alpha/i;
105
+ function currentFileIsInAlphaPackage(filename) {
106
+ return ALPHA_RE.test(filename);
107
+ }
108
+ function checkIfImportedLocationIsAnAlphaPackage(location) {
109
+ return ALPHA_RE.test(location);
110
+ }
111
+ function checkLeftAndRightForCfn(node) {
112
+ var _a, _b;
113
+ // Checking the left and right allows capturing the CfnConstruct name even if the TSQualifiedName references a subtype like:
114
+ // xxx.CfnConstruct.subtype
115
+ // xxx.CfnConstruct.subtype.anothersubtype
116
+ if (!node) {
117
+ return undefined;
118
+ }
119
+ if ((_a = node.name) === null || _a === void 0 ? void 0 : _a.startsWith('Cfn')) {
120
+ if (node.name === node.parent.left.name) {
121
+ // This is the scenario for a reference to CfnConstruct.subtype
122
+ // In this case, it is not qualified with a barrel import, so we don't need to do anything.
123
+ return undefined;
124
+ }
125
+ return {
126
+ name: node.name,
127
+ location: node.parent.left.name,
128
+ };
129
+ }
130
+ const right = checkLeftAndRightForCfn(node.right);
131
+ const left = checkLeftAndRightForCfn(node.left);
132
+ return (_b = right !== null && right !== void 0 ? right : left) !== null && _b !== void 0 ? _b : undefined;
133
+ }
134
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW52YWxpZC1jZm4taW1wb3J0cy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9ydWxlcy9pbnZhbGlkLWNmbi1pbXBvcnRzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7O0FBUUEsd0JBNkVDO0FBbkZELDREQUF3RDtBQUV4RCxJQUFJLGdCQUFnQixHQUVoQixFQUFFLENBQUM7QUFFUCxTQUFnQixNQUFNLENBQUMsT0FBeUI7SUFDOUMsaUZBQWlGO0lBQ2pGLHNGQUFzRjtJQUN0RixvRUFBb0U7SUFDcEUsTUFBTSxRQUFRLEdBQUcsT0FBTyxDQUFDLFdBQVcsRUFBRSxDQUFDO0lBQ3ZDLElBQUksQ0FBQywyQkFBMkIsQ0FBQyxRQUFRLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxLQUFLLENBQUMscUJBQXFCLENBQUMsRUFBRSxDQUFDO1FBQ3JGLE9BQU8sRUFBRSxDQUFDO0lBQ1osQ0FBQztJQUVELE9BQU87UUFDTCxpQkFBaUIsRUFBRSxJQUFJLENBQUMsRUFBRTtZQUN4QixNQUFNLFFBQVEsR0FBRyxJQUFJLENBQUMsTUFBTSxDQUFDLEtBQWUsQ0FBQztZQUM3QyxvR0FBb0c7WUFDcEcsa0NBQWtDO1lBQ2xDLElBQUksQ0FBQyxVQUFVLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxFQUFFO2dCQUMxQixJQUFJLENBQUMsQ0FBQyxJQUFJLEtBQUssMEJBQTBCLEVBQUUsQ0FBQztvQkFDMUMsZ0JBQWdCLENBQUMsQ0FBQyxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsR0FBRyxRQUFRLENBQUM7Z0JBQzVDLENBQUM7WUFDSCxDQUFDLENBQUMsQ0FBQztZQUVILElBQUksUUFBUSxDQUFDLFFBQVEsQ0FBQyxXQUFXLENBQUMsSUFBSSxRQUFRLEtBQUssZUFBZSxFQUFFLENBQUM7Z0JBQ25FLDBJQUEwSTtnQkFDMUksT0FBTztZQUNULENBQUM7WUFLRCxNQUFNLFVBQVUsR0FBaUMsRUFBRSxDQUFDO1lBQ3BELE1BQU0sWUFBWSxH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QUcsdUJBQXVCLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDO0lBQ2xELE1BQU0sSUFBSSxHQUFHLHVCQUF1QixDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQztJQUVoRCxPQUFPLE1BQUEsS0FBSyxhQUFMLEtBQUssY0FBTCxLQUFLLEdBQUksSUFBSSxtQ0FBSSxTQUFTLENBQUM7QUFDcEMsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IFJ1bGUgfSBmcm9tICdlc2xpbnQnO1xuaW1wb3J0IHR5cGUgeyBJZGVudGlmaWVyLCBJbXBvcnRTcGVjaWZpZXIgfSBmcm9tICdlc3RyZWUnO1xuaW1wb3J0IHsgaXNJZGVudGlmaWVyIH0gZnJvbSAnLi4vcHJpdmF0ZS90eXBlLWNoZWNrZXJzJztcblxubGV0IG5hbWVzcGFjZUltcG9ydHM6IHtcbiAgW2tleTogc3RyaW5nXTogc3RyaW5nO1xufSA9IHt9O1xuXG5leHBvcnQgZnVuY3Rpb24gY3JlYXRlKGNvbnRleHQ6IFJ1bGUuUnVsZUNvbnRleHQpOiBSdWxlLk5vZGVMaXN0ZW5lciB7XG4gIC8vIFRoZSBmb3JtYXQgb2YgQ2ZuIGltcG9ydHMgb25seSBtYXR0ZXJzIGZvciBhbHBoYSBwYWNrYWdlcywgc28gdGhhdCB0aGV5IGNhbiBiZVxuICAvLyBmb3JtYXR0ZWQgY29ycmVjdGx5IHdoZW4gcmVsZWFzZWQgc2VwYXJhdGVseSBmb3IgVjIuIFRoZSBsaW50ZXIgcnVsZSBzaG91bGQgb25seSBiZVxuICAvLyBhcHBsaWVkIGlmIHRoZSBmaWxlIGlzIGluIGFuIGFscGhhIHBhY2thZ2UsIG9yIGl0IGlzIGEgdGVzdCBmaWxlLlxuICBjb25zdCBmaWxlbmFtZSA9IGNvbnRleHQuZ2V0RmlsZW5hbWUoKTtcbiAgaWYgKCFjdXJyZW50RmlsZUlzSW5BbHBoYVBhY2thZ2UoZmlsZW5hbWUpICYmICFmaWxlbmFtZS5tYXRjaCgndGVzdC9ydWxlcy9maXh0dXJlcycpKSB7XG4gICAgcmV0dXJuIHt9O1xuICB9XG5cbiAgcmV0dXJuIHtcbiAgICBJbXBvcnREZWNsYXJhdGlvbjogbm9kZSA9PiB7XG4gICAgICBjb25zdCBsb2NhdGlvbiA9IG5vZGUuc291cmNlLnZhbHVlIGFzIHN0cmluZztcbiAgICAgIC8vIFN0b3JlIGFsbCBvZiB0aGUgJ2ltcG9ydCAqIGFzIG5hbWUgZnJvbSBsb2NhdGlvbicgaW1wb3J0cywgc28gdGhhdCB3ZSBjYW4gY2hlY2sgdGhlIGxvY2F0aW9uIHdoZW5cbiAgICAgIC8vIHdlIGZpbmQgbmFtZS5DZm5YWFggcmVmZXJlbmNlcy5cbiAgICAgIG5vZGUuc3BlY2lmaWVycy5mb3JFYWNoKGUgPT4ge1xuICAgICAgICBpZiAoZS50eXBlID09PSAnSW1wb3J0TmFtZXNwYWNlU3BlY2lmaWVyJykge1xuICAgICAgICAgIG5hbWVzcGFjZUltcG9ydHNbZS5sb2NhbC5uYW1lXSA9IGxvY2F0aW9uO1xuICAgICAgICB9XG4gICAgICB9KTtcblxuICAgICAgaWYgKGxvY2F0aW9uLmVuZHNXaXRoKCdnZW5lcmF0ZWQnKSB8fCBsb2NhdGlvbiA9PT0gJ0Bhd3MtY2RrL2NvcmUnKSB7XG4gICAgICAgIC8vIElmIGltcG9ydGluZyBkaXJlY3RseSBmcm9tIGEgZ2VuZXJhdGVkIGZpbGUsIHRoaXMgaXMgZmluZS4gQWxzbyB3ZSBrbm93IHRoYXQgYXdzLWNkay9jb3JlIGlzIG5vdCBleHBlcmltZW50YWwsIHNvIHRoYXQgaXMgZmluZSBhcyB3ZWxsLlxuICAgICAgICByZXR1cm47XG4gICAgICB9XG5cbiAgICAgIC8vIEltcG9ydFNwZWNpZmllcnMgY2FuIGFsc28gY29udGFpbiBsaXRlcmFscy5cbiAgICAgIHR5cGUgSW1wb3J0U3BlY2lmaWVyV0lkZW50aWZpZXIgPSBPbWl0PEltcG9ydFNwZWNpZmllciwgJ2ltcG9ydGVkJz4gJiB7IGltcG9ydGVkOiBJZGVudGlmaWVyIH07XG5cbiAgICAgIGNvbnN0IGNmbkltcG9ydHM6IEltcG9ydFNwZWNpZmllcldJZGVudGlmaWVyW10gPSBbXTtcbiAgICAgIGNvbnN0IG90aGVySW1wb3J0czogSW1wb3J0U3BlY2lmaWVyV0lkZW50aWZpZXJbXSA9IFtdO1xuICAgICAgbm9kZS5zcGVjaWZpZXJzLmZvckVhY2goZSA9PiB7XG4gICAgICAgIGlmIChlLnR5cGUgPT09ICdJbXBvcnRTcGVjaWZpZXInICYmIGlzSWRlbnRpZmllcihlLmltcG9ydGVkKSkge1xuICAgICAgICAgIGlmIChlLmltcG9ydGVkLm5hbWUuc3RhcnRzV2l0aCgnQ2ZuJykpIHtcbiAgICAgICAgICAgIGNmbkltcG9ydHMucHVzaChlIGFzIGFueSk7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIG90aGVySW1wb3J0cy5wdXNoKGUgYXMgYW55KTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH0pO1xuXG4gICAgICBpZiAoY2ZuSW1wb3J0cy5sZW5ndGggPiAwICYmIG90aGVySW1wb3J0cy5sZW5ndGggPiAwICYmIGxvY2F0aW9uLnN0YXJ0c1dpdGgoJy4nKSkge1xuICAgICAgICAvLyBpbXBvcnQgeyBDZm5YWFgsIFNvbWV0aGluZ0Vsc2UsIEFub3RoZXJUaGluZyB9IGZyb20gJy4vc29tZS9yZWxhdGl2ZS9wYXRoL25vdC9lbmRpbmcvaW4vZ2VuZXJhdGVkJztcbiAgICAgICAgY29udGV4dC5yZXBvcnQoe1xuICAgICAgICAgIG1lc3NhZ2U6ICdUbyBhbGxvdyByZXdyaXRpbmcgaW1wb3J0cyB3aGVuIGdlbmVyYXRpbmcgdjIgZXhwZXJpbWVudGFsIHBhY2thZ2VzLCBpbXBvcnQgb2YgYCcgKyBjZm5JbXBvcnRzLm1hcChlID0+IGUuaW1wb3J0ZWQubmFtZSkuam9pbignLCAnKSArICdgIG11c3QgYmUgc2VwYXJhdGUgZnJvbSBpbXBvcnQgb2YgYCcgKyBvdGhlckltcG9ydHMubWFwKGUgPT4gZS5pbXBvcnRlZC5uYW1lKS5qb2luKCcsICcpICsgJ2AsIGFuZCBpbXBvcnRlZCBmcm9tIGl0cyBzcGVjaWZpYyAuZ2VuZXJhdGVkIGxvY2F0aW9uLicsXG4gICAgICAgICAgbm9kZTogbm9kZSxcbiAgICAgICAgfSk7XG4gICAgICB9IGVsc2UgaWYgKGNmbkltcG9ydHMubGVuZ3RoID4gMCAmJiBsb2NhdGlvbi5zdGFydHNXaXRoKCcuJykpIHtcbiAgICAgICAgLy8gaW1wb3J0IHsgQ2ZuWFhYIH0gZnJvbSAnLi9zb21lL3JlbGF0aXZlL3BhdGgvbm90L2VuZGluZy9pbi9nZW5lcmF0ZWQnO1xuICAgICAgICBjb250ZXh0LnJlcG9ydCh7XG4gICAgICAgICAgbWVzc2FnZTogJ1RvIGFsbG93IHJld3JpdGluZyBpbXBvcnRzIHdoZW4gZ2VuZXJhdGluZyB2MiBleHBlcmltZW50YWwgcGFja2FnZXMsIGltcG9ydCBvZiBgJyArIGNmbkltcG9ydHMubWFwKGUgPT4gZS5pbXBvcnRlZC5uYW1lKS5qb2luKCcsICcpICsgJ2AgbXVzdCBiZSBpbXBvcnRlZCBmcm9tIGl0cyBzcGVjaWZpYyAuZ2VuZXJhdGVkIGxvY2F0aW9uLicsXG4gICAgICAgICAgbm9kZTogbm9kZSxcbiAgICAgICAgfSk7XG4gICAgICB9IGVsc2UgaWYgKGNmbkltcG9ydHMubGVuZ3RoID4gMCAmJiBvdGhlckltcG9ydHMubGVuZ3RoID4gMCAmJiBjaGVja0lmSW1wb3J0ZWRMb2NhdGlvbklzQW5BbHBoYVBhY2thZ2UobG9jYXRpb24pKSB7XG4gICAgICAgIC8vIGltcG9ydCB7IENmblhYWCwgU29tZXRoaW5nRWxzZSwgQW5vdGhlclRoaW5nIH0gZnJvbSAnQGF3cy1jZGsvYW5vdGhlci1hbHBoYS1wYWNrYWdlJztcbiAgICAgICAgY29udGV4dC5yZXBvcnQoe1xuICAgICAgICAgIG1lc3NhZ2U6ICdUbyBhbGxvdyByZXdyaXRpbmcgaW1wb3J0cyB3aGVuIGdlbmVyYXRpbmcgdjIgZXhwZXJpbWVudGFsIHBhY2thZ2VzLCBpbXBvcnQgb2YgYCcgKyBjZm5JbXBvcnRzLm1hcChlID0+IGUuaW1wb3J0ZWQubmFtZSkuam9pbignLCAnKSArICdgIG11c3QgYmUgc2VwYXJhdGUgZnJvbSBpbXBvcnQgb2YgYCcgKyBvdGhlckltcG9ydHMubWFwKGUgPT4gZS5pbXBvcnRlZC5uYW1lKS5qb2luKCcsICcpICsgJ2AnLFxuICAgICAgICAgIG5vZGU6IG5vZGUsXG4gICAgICAgIH0pO1xuICAgICAgfVxuICAgIH0sXG5cbiAgICAvLyBUaGlzIGNhcHR1cmVzIHVzaW5nIGB4eHguQ2ZuQ29uc3RydWN0YCBhcyBhbiBpZGVudGlmaWVyXG4gICAgSWRlbnRpZmllcjogbm9kZSA9PiB7XG4gICAgICBjb25zdCB0eXBlQW5ub3RhdGlvbiA9IChub2RlIGFzIGFueSkudHlwZUFubm90YXRpb24/LnR5cGVBbm5vdGF0aW9uO1xuICAgICAgY29uc3QgdHlwZSA9IHR5cGVBbm5vdGF0aW9uPy50eXBlTmFtZTtcbiAgICAgIGlmICh0eXBlPy50eXBlID09PSAnVFNRdWFsaWZpZWROYW1lJykge1xuICAgICAgICBjb25zdCByZXN1bHQgPSBjaGVja0xlZnRBbmRSaWdodEZvckNmbih0eXBlKTtcbiAgICAgICAgaWYgKHJlc3VsdCkge1xuICAgICAgICAgIHJlcG9ydEVycm9ySWZJbXBvcnRlZExvY2F0aW9uSXNOb3RWYWxpZChjb250ZXh0LCBub2RlLCByZXN1bHQubmFtZSwgcmVzdWx0LmxvY2F0aW9uKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgaWYgKG5vZGUubmFtZS5zdGFydHNXaXRoKCdDZm4nKSAmJiBub2RlLnBhcmVudC50eXBlID09PSAnTWVtYmVyRXhwcmVzc2lvbicgJiYgbm9kZS5wYXJlbnQub2JqZWN0LnR5cGUgPT09ICdJZGVudGlmaWVyJykge1xuICAgICAgICAvLyBuZXcgeHh4LkNmbkNvbnN0cnVjdCgpO1xuICAgICAgICByZXBvcnRFcnJvcklmSW1wb3J0ZWRMb2NhdGlvbklzTm90VmFsaWQoY29udGV4dCwgbm9kZSwgbm9kZS5uYW1lLCBub2RlLnBhcmVudC5vYmplY3QubmFtZSk7XG4gICAgICB9XG4gICAgfSxcbiAgfTtcbn1cblxuZnVuY3Rpb24gcmVwb3J0RXJyb3JJZkltcG9ydGVkTG9jYXRpb25Jc05vdFZhbGlkKGNvbnRleHQ6IFJ1bGUuUnVsZUNvbnRleHQsIG5vZGU6IElkZW50aWZpZXIsIG5hbWU6IHN0cmluZywgYmFycmVsSW1wb3J0TmFtZTogc3RyaW5nKSB7XG4gIGNvbnN0IGxvY2F0aW9uID0gbmFtZXNwYWNlSW1wb3J0c1tiYXJyZWxJbXBvcnROYW1lXTtcbiAgaWYgKCFsb2NhdGlvbikge1xuICAgIC8vIFRoaXMgc2NlbmFyaW8gc2hvdWxkIG5vdCBoYXBwZW4sIGJ1dCBpZiBpdCBkb2VzLCB3ZSBkb24ndCB3YW50IHVzZXJzIHRvIHJ1biBpbnRvIHdlaXJkIHJ1bnRpbWUgZXJyb3JzIGZyb20gdGhlIGxpbnRlci5cbiAgICByZXR1cm47XG4gIH1cbiAgaWYgKGxvY2F0aW9uLmVuZHNXaXRoKCdnZW5lcmF0ZWQnKSB8fCBsb2NhdGlvbiA9PT0gJ0Bhd3MtY2RrL2NvcmUnKSB7XG4gICAgcmV0dXJuO1xuICB9XG4gIGlmIChsb2NhdGlvbi5zdGFydHNXaXRoKCcuJykpIHtcbiAgICAvLyBpbXBvcnQgKiBhcyBuYW1lIGZyb20gJy4vc29tZS9yZWxhdGl2ZS9wYXRoL25vdC9lbmRpbmcvaW4vZ2VuZXJhdGVkJzsgbmFtZS5DZm5Db25zdHJ1Y3QoKTtcbiAgICBjb250ZXh0LnJlcG9ydCh7XG4gICAgICBtZXNzYWdlOiAnVG8gYWxsb3cgcmV3cml0aW5nIGltcG9ydHMgd2hlbiBnZW5lcmF0aW5nIHYyIGV4cGVyaW1lbnRhbCBwYWNrYWdlcywgYCcgKyBuYW1lICsgJ2AgbXVzdCBiZSBpbXBvcnRlZCBieSBuYW1lIGZyb20gaXRzIHNwZWNpZmljIC5nZW5lcmF0ZWQgbG9jYXRpb24uJyxcbiAgICAgIG5vZGU6IG5vZGUsXG4gICAgfSk7XG4gIH0gZWxzZSBpZiAoY2hlY2tJZkltcG9ydGVkTG9jYXRpb25Jc0FuQWxwaGFQYWNrYWdlKGxvY2F0aW9uKSkge1xuICAgIC8vIGltcG9ydCAqIGFzIG5hbWUgZnJvbSAnQGF3cy1jZGsvYW5vdGhlci1hbHBoYS1wYWNrYWdlJzsgbmFtZS5DZm5Db25zdHJ1Y3QoKTtcbiAgICBjb250ZXh0LnJlcG9ydCh7XG4gICAgICBtZXNzYWdlOiAnVG8gYWxsb3cgcmV3cml0aW5nIGltcG9ydHMgd2hlbiBnZW5lcmF0aW5nIHYyIGV4cGVyaW1lbnRhbCBwYWNrYWdlcywgYCcgKyBuYW1lICsgJ2AgbXVzdCBiZSBpbXBvcnRlZCBieSBuYW1lIGFuZCBzZXBhcmF0ZSBmcm9tIG5vbi1MMSBpbXBvcnRzLCBzaW5jZSBpdCBpcyBiZWluZyBpbXBvcnRlZCBmcm9tIGFuIGV4cGVyaW1lbnRhbCBwYWNrYWdlOiAnICsgbG9jYXRpb24sXG4gICAgICBub2RlOiBub2RlLFxuICAgIH0pO1xuICB9XG59XG5cbmNvbnN0IEFMUEhBX1JFID0gL0Bhd3MtY2RrKFxcL3xcXFxcKVthLXowLTktXSstYWxwaGEvaTtcblxuZnVuY3Rpb24gY3VycmVudEZpbGVJc0luQWxwaGFQYWNrYWdlKGZpbGVuYW1lOiBzdHJpbmcpOiBib29sZWFuIHtcbiAgcmV0dXJuIEFMUEhBX1JFLnRlc3QoZmlsZW5hbWUpO1xufVxuXG5mdW5jdGlvbiBjaGVja0lmSW1wb3J0ZWRMb2NhdGlvbklzQW5BbHBoYVBhY2thZ2UobG9jYXRpb246IHN0cmluZyk6IGJvb2xlYW4ge1xuICByZXR1cm4gQUxQSEFfUkUudGVzdChsb2NhdGlvbik7XG59XG5cbmZ1bmN0aW9uIGNoZWNrTGVmdEFuZFJpZ2h0Rm9yQ2ZuKG5vZGU6IGFueSk6IHsgbmFtZTogc3RyaW5nOyBsb2NhdGlvbjogc3RyaW5nIH0gfCB1bmRlZmluZWQge1xuICAvLyBDaGVja2luZyB0aGUgbGVmdCBhbmQgcmlnaHQgYWxsb3dzIGNhcHR1cmluZyB0aGUgQ2ZuQ29uc3RydWN0IG5hbWUgZXZlbiBpZiB0aGUgVFNRdWFsaWZpZWROYW1lIHJlZmVyZW5jZXMgYSBzdWJ0eXBlIGxpa2U6XG4gIC8vICAgIHh4eC5DZm5Db25zdHJ1Y3Quc3VidHlwZVxuICAvLyAgICB4eHguQ2ZuQ29uc3RydWN0LnN1YnR5cGUuYW5vdGhlcnN1YnR5cGVcbiAgaWYgKCFub2RlKSB7XG4gICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgfVxuICBpZiAobm9kZS5uYW1lPy5zdGFydHNXaXRoKCdDZm4nKSkge1xuICAgIGlmIChub2RlLm5hbWUgPT09IG5vZGUucGFyZW50LmxlZnQubmFtZSkge1xuICAgICAgLy8gVGhpcyBpcyB0aGUgc2NlbmFyaW8gZm9yIGEgcmVmZXJlbmNlIHRvIENmbkNvbnN0cnVjdC5zdWJ0eXBlXG4gICAgICAvLyBJbiB0aGlzIGNhc2UsIGl0IGlzIG5vdCBxdWFsaWZpZWQgd2l0aCBhIGJhcnJlbCBpbXBvcnQsIHNvIHdlIGRvbid0IG5lZWQgdG8gZG8gYW55dGhpbmcuXG4gICAgICByZXR1cm4gdW5kZWZpbmVkO1xuICAgIH1cbiAgICByZXR1cm4ge1xuICAgICAgbmFtZTogbm9kZS5uYW1lLFxuICAgICAgbG9jYXRpb246IG5vZGUucGFyZW50LmxlZnQubmFtZSxcbiAgICB9O1xuICB9XG5cbiAgY29uc3QgcmlnaHQgPSBjaGVja0xlZnRBbmRSaWdodEZvckNmbihub2RlLnJpZ2h0KTtcbiAgY29uc3QgbGVmdCA9IGNoZWNrTGVmdEFuZFJpZ2h0Rm9yQ2ZuKG5vZGUubGVmdCk7XG5cbiAgcmV0dXJuIHJpZ2h0ID8/IGxlZnQgPz8gdW5kZWZpbmVkO1xufVxuIl19
@@ -0,0 +1,5 @@
1
+ import { Rule } from 'eslint';
2
+ export declare const meta: {
3
+ fixable: boolean;
4
+ };
5
+ export declare function create(context: Rule.RuleContext): Rule.NodeListener;
@@ -0,0 +1,155 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.meta = void 0;
4
+ exports.create = create;
5
+ const import_cache_1 = require("../private/import-cache");
6
+ let importCache;
7
+ let importsFixed;
8
+ const BANNED_TYPES = ['IConstruct', 'Construct'];
9
+ exports.meta = {
10
+ fixable: true,
11
+ };
12
+ function create(context) {
13
+ return {
14
+ // `node` is a type from @typescript-eslint/typescript-estree, but using 'any' for now
15
+ // since it's incompatible with eslint.Rule namespace. Waiting for better compatibility in
16
+ // https://github.com/typescript-eslint/typescript-eslint/tree/1765a178e456b152bd48192eb5db7e8541e2adf2/packages/experimental-utils#note
17
+ // Meanwhile, use a debugger to explore the AST node.
18
+ Program(_node) {
19
+ if (!isTestFile(context.getFilename())) {
20
+ return;
21
+ }
22
+ importCache = new import_cache_1.ImportCache();
23
+ importsFixed = false;
24
+ },
25
+ ImportDeclaration(node) {
26
+ if (!isTestFile(context.getFilename())) {
27
+ return;
28
+ }
29
+ if (node.source.value === '@aws-cdk/core') {
30
+ node.specifiers.forEach((s) => {
31
+ if (s.type === 'ImportSpecifier' && BANNED_TYPES.includes(s.imported.name)) {
32
+ // named import
33
+ importCache.record({
34
+ fileName: context.getFilename(),
35
+ typeName: s.imported.name,
36
+ importNode: node,
37
+ localName: s.local.name,
38
+ });
39
+ }
40
+ else if (s.type === 'ImportNamespaceSpecifier') {
41
+ // barrel import
42
+ BANNED_TYPES.forEach(typeName => {
43
+ importCache.record({
44
+ fileName: context.getFilename(),
45
+ typeName,
46
+ importNode: node,
47
+ localName: `${s.local.name}.${typeName}`,
48
+ });
49
+ });
50
+ }
51
+ });
52
+ }
53
+ },
54
+ Identifier(node) {
55
+ var _a;
56
+ if (!isTestFile(context.getFilename())) {
57
+ return;
58
+ }
59
+ // Only apply rule to bindings (variables and function parameters)
60
+ const typeAnnotation = (_a = node.typeAnnotation) === null || _a === void 0 ? void 0 : _a.typeAnnotation;
61
+ if (!typeAnnotation) {
62
+ return;
63
+ }
64
+ const type = typeAnnotation.typeName;
65
+ if (!type) {
66
+ return;
67
+ }
68
+ const message = 'Use Construct and IConstruct from the "constructs" module in variable declarations (not "@aws-cdk/core")';
69
+ if (type.type === 'TSQualifiedName') {
70
+ // barrel import
71
+ const qualifier = type.left.name;
72
+ const typename = type.right.name;
73
+ const importNode = findImportNode(`${qualifier}.${typename}`);
74
+ if (!importNode) {
75
+ return;
76
+ }
77
+ context.report({
78
+ node,
79
+ message,
80
+ fix: (fixer) => {
81
+ const fixes = [];
82
+ if (!importsFixed) {
83
+ fixes.push(fixer.insertTextAfter(importNode, "\nimport * as constructs from 'constructs';"));
84
+ importsFixed = true;
85
+ }
86
+ fixes.push(fixer.replaceTextRange(typeAnnotation.range, `constructs.${typename}`));
87
+ return fixes;
88
+ },
89
+ });
90
+ }
91
+ else if (type.type === 'Identifier') {
92
+ // named imports
93
+ const importNode = findImportNode(type.name);
94
+ if (!importNode) {
95
+ return;
96
+ }
97
+ context.report({
98
+ node,
99
+ message,
100
+ fix: (fixer) => {
101
+ const fixes = [];
102
+ if (!importsFixed) {
103
+ const typesToImport = BANNED_TYPES.map(typeName => {
104
+ const val = importCache.find({ fileName: context.getFilename(), typeName });
105
+ if (!val) {
106
+ return undefined;
107
+ }
108
+ if (typeName === val.localName) {
109
+ return typeName;
110
+ }
111
+ return `${typeName} as ${val.localName}`;
112
+ }).filter(x => x !== undefined);
113
+ fixes.push(fixer.insertTextAfter(importNode, `\nimport { ${typesToImport.join(', ')} } from 'constructs';`));
114
+ const specifiers = importNode.specifiers;
115
+ if (specifiers.length === typesToImport.length) {
116
+ fixes.push(fixer.removeRange(importNode.range));
117
+ }
118
+ else {
119
+ for (let i = 0; i < specifiers.length; i++) {
120
+ const s = specifiers[i];
121
+ if (typesToImport.includes(s.imported.name)) {
122
+ if (i === specifiers.length - 1) {
123
+ fixes.push(fixer.removeRange([s.range[0] - 2, s.range[1]])); // include the leading comma
124
+ }
125
+ else {
126
+ fixes.push(fixer.removeRange([s.range[0], s.range[1] + 2])); // include the trailing comma
127
+ }
128
+ }
129
+ }
130
+ }
131
+ importsFixed = true;
132
+ }
133
+ return fixes;
134
+ },
135
+ });
136
+ }
137
+ else {
138
+ return;
139
+ }
140
+ function findImportNode(locaName) {
141
+ return BANNED_TYPES.map(typeName => {
142
+ const val = importCache.find({ fileName: context.getFilename(), typeName });
143
+ if (val && val.localName === locaName) {
144
+ return val.importNode;
145
+ }
146
+ return undefined;
147
+ }).find(x => x !== undefined);
148
+ }
149
+ },
150
+ };
151
+ }
152
+ function isTestFile(filename) {
153
+ return new RegExp(/\/test\//).test(filename);
154
+ }
155
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibm8tY29yZS1jb25zdHJ1Y3QuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvcnVsZXMvbm8tY29yZS1jb25zdHJ1Y3QudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBWUEsd0JBdUlDO0FBbEpELDBEQUE0RDtBQUU1RCxJQUFJLFdBQXdCLENBQUM7QUFDN0IsSUFBSSxZQUFxQixDQUFDO0FBRTFCLE1BQU0sWUFBWSxHQUFHLENBQUMsWUFBWSxFQUFFLFdBQVcsQ0FBQyxDQUFDO0FBRXBDLFFBQUEsSUFBSSxHQUFHO0lBQ2xCLE9BQU8sRUFBRSxJQUFJO0NBQ2QsQ0FBQztBQUVGLFNBQWdCLE1BQU0sQ0FBQyxPQUF5QjtJQUM5QyxPQUFPO1FBRUwsc0ZBQXNGO1FBQ3RGLDBGQUEwRjtRQUMxRix3SUFBd0k7UUFDeEkscURBQXFEO1FBRXJELE9BQU8sQ0FBQyxLQUFVO1lBQ2hCLElBQUksQ0FBQyxVQUFVLENBQUMsT0FBTyxDQUFDLFdBQVcsRUFBRSxDQUFDLEVBQUUsQ0FBQztnQkFDdkMsT0FBTztZQUNULENBQUM7WUFDRCxXQUFXLEdBQUcsSUFBSSwwQkFBVyxFQUFFLENBQUM7WUFDaEMsWUFBWSxHQUFHLEtBQUssQ0FBQztRQUN2QixDQUFDO1FBRUQsaUJBQWlCLENBQUMsSUFBUztZQUN6QixJQUFJLENBQUMsVUFBVSxDQUFDLE9BQU8sQ0FBQyxXQUFXLEVBQUUsQ0FBQyxFQUFFLENBQUM7Z0JBQ3ZDLE9BQU87WUFDVCxDQUFDO1lBQ0QsSUFBSSxJQUFJLENBQUMsTUFBTSxDQUFDLEtBQUssS0FBSyxlQUFlLEVBQUUsQ0FBQztnQkFDMUMsSUFBSSxDQUFDLFVBQVUsQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFNLEVBQUUsRUFBRTtvQkFDakMsSUFBSSxDQUFDLENBQUMsSUFBSSxLQUFLLGlCQUFpQixJQUFJLFlBQVksQ0FBQyxRQUFRLENBQUMsQ0FBQyxDQUFDLFFBQVEsQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDO3dCQUMz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V0FBVyxFQUFFLEVBQUUsUUFBUSxFQUFFLENBQUMsQ0FBQztvQkFDNUUsSUFBSSxHQUFHLElBQUksR0FBRyxDQUFDLFNBQVMsS0FBSyxRQUFRLEVBQUUsQ0FBQzt3QkFDdEMsT0FBTyxHQUFHLENBQUMsVUFBVSxDQUFDO29CQUN4QixDQUFDO29CQUNELE9BQU8sU0FBUyxDQUFDO2dCQUNuQixDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLEtBQUssU0FBUyxDQUFDLENBQUM7WUFDaEMsQ0FBQztRQUNILENBQUM7S0FDRixDQUFDO0FBQ0osQ0FBQztBQUVELFNBQVMsVUFBVSxDQUFDLFFBQWdCO0lBQ2xDLE9BQU8sSUFBSSxNQUFNLENBQUMsVUFBVSxDQUFDLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxDQUFDO0FBQy9DLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBSdWxlIH0gZnJvbSAnZXNsaW50JztcbmltcG9ydCB7IEltcG9ydENhY2hlLCBOb2RlIH0gZnJvbSAnLi4vcHJpdmF0ZS9pbXBvcnQtY2FjaGUnO1xuXG5sZXQgaW1wb3J0Q2FjaGU6IEltcG9ydENhY2hlO1xubGV0IGltcG9ydHNGaXhlZDogYm9vbGVhbjtcblxuY29uc3QgQkFOTkVEX1RZUEVTID0gWydJQ29uc3RydWN0JywgJ0NvbnN0cnVjdCddO1xuXG5leHBvcnQgY29uc3QgbWV0YSA9IHtcbiAgZml4YWJsZTogdHJ1ZSxcbn07XG5cbmV4cG9ydCBmdW5jdGlvbiBjcmVhdGUoY29udGV4dDogUnVsZS5SdWxlQ29udGV4dCk6IFJ1bGUuTm9kZUxpc3RlbmVyIHtcbiAgcmV0dXJuIHtcblxuICAgIC8vIGBub2RlYCBpcyBhIHR5cGUgZnJvbSBAdHlwZXNjcmlwdC1lc2xpbnQvdHlwZXNjcmlwdC1lc3RyZWUsIGJ1dCB1c2luZyAnYW55JyBmb3Igbm93XG4gICAgLy8gc2luY2UgaXQncyBpbmNvbXBhdGlibGUgd2l0aCBlc2xpbnQuUnVsZSBuYW1lc3BhY2UuIFdhaXRpbmcgZm9yIGJldHRlciBjb21wYXRpYmlsaXR5IGluXG4gICAgLy8gaHR0cHM6Ly9naXRodWIuY29tL3R5cGVzY3JpcHQtZXNsaW50L3R5cGVzY3JpcHQtZXNsaW50L3RyZWUvMTc2NWExNzhlNDU2YjE1MmJkNDgxOTJlYjVkYjdlODU0MWUyYWRmMi9wYWNrYWdlcy9leHBlcmltZW50YWwtdXRpbHMjbm90ZVxuICAgIC8vIE1lYW53aGlsZSwgdXNlIGEgZGVidWdnZXIgdG8gZXhwbG9yZSB0aGUgQVNUIG5vZGUuXG5cbiAgICBQcm9ncmFtKF9ub2RlOiBhbnkpIHtcbiAgICAgIGlmICghaXNUZXN0RmlsZShjb250ZXh0LmdldEZpbGVuYW1lKCkpKSB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICAgIGltcG9ydENhY2hlID0gbmV3IEltcG9ydENhY2hlKCk7XG4gICAgICBpbXBvcnRzRml4ZWQgPSBmYWxzZTtcbiAgICB9LFxuXG4gICAgSW1wb3J0RGVjbGFyYXRpb24obm9kZTogYW55KSB7XG4gICAgICBpZiAoIWlzVGVzdEZpbGUoY29udGV4dC5nZXRGaWxlbmFtZSgpKSkge1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgICBpZiAobm9kZS5zb3VyY2UudmFsdWUgPT09ICdAYXdzLWNkay9jb3JlJykge1xuICAgICAgICBub2RlLnNwZWNpZmllcnMuZm9yRWFjaCgoczogYW55KSA9PiB7XG4gICAgICAgICAgaWYgKHMudHlwZSA9PT0gJ0ltcG9ydFNwZWNpZmllcicgJiYgQkFOTkVEX1RZUEVTLmluY2x1ZGVzKHMuaW1wb3J0ZWQubmFtZSkpIHtcbiAgICAgICAgICAgIC8vIG5hbWVkIGltcG9ydFxuICAgICAgICAgICAgaW1wb3J0Q2FjaGUucmVjb3JkKHtcbiAgICAgICAgICAgICAgZmlsZU5hbWU6IGNvbnRleHQuZ2V0RmlsZW5hbWUoKSxcbiAgICAgICAgICAgICAgdHlwZU5hbWU6IHMuaW1wb3J0ZWQubmFtZSxcbiAgICAgICAgICAgICAgaW1wb3J0Tm9kZTogbm9kZSxcbiAgICAgICAgICAgICAgbG9jYWxOYW1lOiBzLmxvY2FsLm5hbWUsXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICB9IGVsc2UgaWYgKHMudHlwZSA9PT0gJ0ltcG9ydE5hbWVzcGFjZVNwZWNpZmllcicpIHtcbiAgICAgICAgICAgIC8vIGJhcnJlbCBpbXBvcnRcbiAgICAgICAgICAgIEJBTk5FRF9UWVBFUy5mb3JFYWNoKHR5cGVOYW1lID0+IHtcbiAgICAgICAgICAgICAgaW1wb3J0Q2FjaGUucmVjb3JkKHtcbiAgICAgICAgICAgICAgICBmaWxlTmFtZTogY29udGV4dC5nZXRGaWxlbmFtZSgpLFxuICAgICAgICAgICAgICAgIHR5cGVOYW1lLFxuICAgICAgICAgICAgICAgIGltcG9ydE5vZGU6IG5vZGUsXG4gICAgICAgICAgICAgICAgbG9jYWxOYW1lOiBgJHtzLmxvY2FsLm5hbWV9LiR7dHlwZU5hbWV9YCxcbiAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgICAgfVxuICAgIH0sXG5cbiAgICBJZGVudGlmaWVyKG5vZGU6IGFueSkge1xuICAgICAgaWYgKCFpc1Rlc3RGaWxlKGNvbnRleHQuZ2V0RmlsZW5hbWUoKSkpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgICAgLy8gT25seSBhcHBseSBydWxlIHRvIGJpbmRpbmdzICh2YXJpYWJsZXMgYW5kIGZ1bmN0aW9uIHBhcmFtZXRlcnMpXG4gICAgICBjb25zdCB0eXBlQW5ub3RhdGlvbiA9IG5vZGUudHlwZUFubm90YXRpb24/LnR5cGVBbm5vdGF0aW9uO1xuICAgICAgaWYgKCF0eXBlQW5ub3RhdGlvbikge1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgICBjb25zdCB0eXBlID0gdHlwZUFubm90YXRpb24udHlwZU5hbWU7XG4gICAgICBpZiAoIXR5cGUpIHsgcmV0dXJuOyB9XG5cbiAgICAgIGNvbnN0IG1lc3NhZ2UgPSAnVXNlIENvbnN0cnVjdCBhbmQgSUNvbnN0cnVjdCBmcm9tIHRoZSBcImNvbnN0cnVjdHNcIiBtb2R1bGUgaW4gdmFyaWFibGUgZGVjbGFyYXRpb25zIChub3QgXCJAYXdzLWNkay9jb3JlXCIpJztcblxuICAgICAgaWYgKHR5cGUudHlwZSA9PT0gJ1RTUXVhbGlmaWVkTmFtZScpIHtcbiAgICAgICAgLy8gYmFycmVsIGltcG9ydFxuICAgICAgICBjb25zdCBxdWFsaWZpZXIgPSB0eXBlLmxlZnQubmFtZTtcbiAgICAgICAgY29uc3QgdHlwZW5hbWUgPSB0eXBlLnJpZ2h0Lm5hbWU7XG4gICAgICAgIGNvbnN0IGltcG9ydE5vZGUgPSBmaW5kSW1wb3J0Tm9kZShgJHtxdWFsaWZpZXJ9LiR7dHlwZW5hbWV9YCk7XG4gICAgICAgIGlmICghaW1wb3J0Tm9kZSkge1xuICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICBjb250ZXh0LnJlcG9ydCh7XG4gICAgICAgICAgbm9kZSxcbiAgICAgICAgICBtZXNzYWdlLFxuICAgICAgICAgIGZpeDogKGZpeGVyOiBSdWxlLlJ1bGVGaXhlcikgPT4ge1xuICAgICAgICAgICAgY29uc3QgZml4ZXM6IFJ1bGUuRml4W10gPSBbXTtcbiAgICAgICAgICAgIGlmICghaW1wb3J0c0ZpeGVkKSB7XG4gICAgICAgICAgICAgIGZpeGVzLnB1c2goZml4ZXIuaW5zZXJ0VGV4dEFmdGVyKGltcG9ydE5vZGUsIFwiXFxuaW1wb3J0ICogYXMgY29uc3RydWN0cyBmcm9tICdjb25zdHJ1Y3RzJztcIikpO1xuICAgICAgICAgICAgICBpbXBvcnRzRml4ZWQgPSB0cnVlO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZml4ZXMucHVzaChmaXhlci5yZXBsYWNlVGV4dFJhbmdlKHR5cGVBbm5vdGF0aW9uLnJhbmdlLCBgY29uc3RydWN0cy4ke3R5cGVuYW1lfWApKTtcbiAgICAgICAgICAgIHJldHVybiBmaXhlcztcbiAgICAgICAgICB9LFxuICAgICAgICB9KTtcbiAgICAgIH0gZWxzZSBpZiAodHlwZS50eXBlID09PSAnSWRlbnRpZmllcicpIHtcbiAgICAgICAgLy8gbmFtZWQgaW1wb3J0c1xuICAgICAgICBjb25zdCBpbXBvcnROb2RlID0gZmluZEltcG9ydE5vZGUodHlwZS5uYW1lKTtcbiAgICAgICAgaWYgKCFpbXBvcnROb2RlKSB7XG4gICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIGNvbnRleHQucmVwb3J0KHtcbiAgICAgICAgICBub2RlLFxuICAgICAgICAgIG1lc3NhZ2UsXG4gICAgICAgICAgZml4OiAoZml4ZXI6IFJ1bGUuUnVsZUZpeGVyKSA9PiB7XG4gICAgICAgICAgICBjb25zdCBmaXhlczogUnVsZS5GaXhbXSA9IFtdO1xuICAgICAgICAgICAgaWYgKCFpbXBvcnRzRml4ZWQpIHtcbiAgICAgICAgICAgICAgY29uc3QgdHlwZXNUb0ltcG9ydCA9IEJBTk5FRF9UWVBFUy5tYXAodHlwZU5hbWUgPT4ge1xuICAgICAgICAgICAgICAgIGNvbnN0IHZhbCA9IGltcG9ydENhY2hlLmZpbmQoeyBmaWxlTmFtZTogY29udGV4dC5nZXRGaWxlbmFtZSgpLCB0eXBlTmFtZSB9KTtcbiAgICAgICAgICAgICAgICBpZiAoIXZhbCkgeyByZXR1cm4gdW5kZWZpbmVkOyB9XG4gICAgICAgICAgICAgICAgaWYgKHR5cGVOYW1lID09PSB2YWwubG9jYWxOYW1lKSB7IHJldHVybiB0eXBlTmFtZTsgfVxuICAgICAgICAgICAgICAgIHJldHVybiBgJHt0eXBlTmFtZX0gYXMgJHt2YWwubG9jYWxOYW1lfWA7XG4gICAgICAgICAgICAgIH0pLmZpbHRlcih4ID0+IHggIT09IHVuZGVmaW5lZCk7XG4gICAgICAgICAgICAgIGZpeGVzLnB1c2goZml4ZXIuaW5zZXJ0VGV4dEFmdGVyKGltcG9ydE5vZGUsIGBcXG5pbXBvcnQgeyAke3R5cGVzVG9JbXBvcnQuam9pbignLCAnKX0gfSBmcm9tICdjb25zdHJ1Y3RzJztgKSk7XG5cbiAgICAgICAgICAgICAgY29uc3Qgc3BlY2lmaWVycyA9IGltcG9ydE5vZGUuc3BlY2lmaWVycztcbiAgICAgICAgICAgICAgaWYgKHNwZWNpZmllcnMubGVuZ3RoID09PSB0eXBlc1RvSW1wb3J0Lmxlbmd0aCkge1xuICAgICAgICAgICAgICAgIGZpeGVzLnB1c2goZml4ZXIucmVtb3ZlUmFuZ2UoaW1wb3J0Tm9kZS5yYW5nZSkpO1xuICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgc3BlY2lmaWVycy5sZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgICAgICAgY29uc3QgcyA9IHNwZWNpZmllcnNbaV07XG4gICAgICAgICAgICAgICAgICBpZiAodHlwZXNUb0ltcG9ydC5pbmNsdWRlcyhzLmltcG9ydGVkLm5hbWUpKSB7XG4gICAgICAgICAgICAgICAgICAgIGlmIChpID09PSBzcGVjaWZpZXJzLmxlbmd0aCAtIDEpIHtcbiAgICAgICAgICAgICAgICAgICAgICBmaXhlcy5wdXNoKGZpeGVyLnJlbW92ZVJhbmdlKFtzLnJhbmdlWzBdIC0gMiwgcy5yYW5nZVsxXV0pKTsgLy8gaW5jbHVkZSB0aGUgbGVhZGluZyBjb21tYVxuICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgIGZpeGVzLnB1c2goZml4ZXIucmVtb3ZlUmFuZ2UoW3MucmFuZ2VbMF0sIHMucmFuZ2VbMV0gKyAyXSkpOyAvLyBpbmNsdWRlIHRoZSB0cmFpbGluZyBjb21tYVxuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIGltcG9ydHNGaXhlZCA9IHRydWU7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gZml4ZXM7XG4gICAgICAgICAgfSxcbiAgICAgICAgfSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG5cbiAgICAgIGZ1bmN0aW9uIGZpbmRJbXBvcnROb2RlKGxvY2FOYW1lOiBzdHJpbmcpOiBOb2RlIHwgdW5kZWZpbmVkIHtcbiAgICAgICAgcmV0dXJuIEJBTk5FRF9UWVBFUy5tYXAodHlwZU5hbWUgPT4ge1xuICAgICAgICAgIGNvbnN0IHZhbCA9IGltcG9ydENhY2hlLmZpbmQoeyBmaWxlTmFtZTogY29udGV4dC5nZXRGaWxlbmFtZSgpLCB0eXBlTmFtZSB9KTtcbiAgICAgICAgICBpZiAodmFsICYmIHZhbC5sb2NhbE5hbWUgPT09IGxvY2FOYW1lKSB7XG4gICAgICAgICAgICByZXR1cm4gdmFsLmltcG9ydE5vZGU7XG4gICAgICAgICAgfVxuICAgICAgICAgIHJldHVybiB1bmRlZmluZWQ7XG4gICAgICAgIH0pLmZpbmQoeCA9PiB4ICE9PSB1bmRlZmluZWQpO1xuICAgICAgfVxuICAgIH0sXG4gIH07XG59XG5cbmZ1bmN0aW9uIGlzVGVzdEZpbGUoZmlsZW5hbWU6IHN0cmluZykge1xuICByZXR1cm4gbmV3IFJlZ0V4cCgvXFwvdGVzdFxcLy8pLnRlc3QoZmlsZW5hbWUpO1xufSJdfQ==
@@ -0,0 +1,2 @@
1
+ import { Rule } from 'eslint';
2
+ export declare function create(context: Rule.RuleContext): Rule.NodeListener;
@@ -0,0 +1,102 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || function (mod) {
19
+ if (mod && mod.__esModule) return mod;
20
+ var result = {};
21
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
22
+ __setModuleDefault(result, mod);
23
+ return result;
24
+ };
25
+ Object.defineProperty(exports, "__esModule", { value: true });
26
+ exports.create = create;
27
+ const fs = __importStar(require("fs"));
28
+ const path = __importStar(require("path"));
29
+ function isPathJoinFuncCall(node) {
30
+ var _a, _b, _c, _d, _e, _f, _g, _h;
31
+ return (((_b = (_a = node.callee) === null || _a === void 0 ? void 0 : _a.property) === null || _b === void 0 ? void 0 : _b.name) === 'join' &&
32
+ (((_f = (_e = (_d = (_c = node.parent) === null || _c === void 0 ? void 0 : _c.expression) === null || _d === void 0 ? void 0 : _d.callee) === null || _e === void 0 ? void 0 : _e.object) === null || _f === void 0 ? void 0 : _f.name) === 'path' ||
33
+ ((_h = (_g = node.parent) === null || _g === void 0 ? void 0 : _g.arguments) === null || _h === void 0 ? void 0 : _h.some((a) => { var _a, _b; return ((_b = (_a = a.callee) === null || _a === void 0 ? void 0 : _a.object) === null || _b === void 0 ? void 0 : _b.name) === 'path'; }))));
34
+ }
35
+ function noArgumentVariables(node) {
36
+ // Outside of the first argument, all arguments should be strings
37
+ const components = node.arguments.slice(1);
38
+ return components.every((a) => a.value !== undefined);
39
+ }
40
+ function hasSlashes(args) {
41
+ return args.some((a) => a.includes('/'));
42
+ }
43
+ function firstArgIsDirname(node) {
44
+ return node.arguments[0].name && node.arguments[0].name === '__dirname';
45
+ }
46
+ function argumentList(node) {
47
+ // Already confirmed that first argument is '__dirname', so can safely remove it
48
+ const args = node.arguments.slice(1).map((a) => { return a.value; });
49
+ return args;
50
+ }
51
+ function recreatePath(args) {
52
+ return `path.join(__dirname, '${args.join('\', \'')}')`;
53
+ }
54
+ function create(context) {
55
+ return {
56
+ CallExpression(node) {
57
+ if (isPathJoinFuncCall(node)) {
58
+ if (node.arguments.length === 0) {
59
+ // ERROR: this is 'path.join()'
60
+ context.report({ node, message: '\'path.join()\' is not a valid path. You must specify arguments into the function.' });
61
+ return;
62
+ }
63
+ if (!noArgumentVariables(node)) {
64
+ // WARNING: unexpected non-string in the argument list. This happens if part of the argument list is a variable, i.e. `path.join(__dirname, myPath)`.
65
+ // We may be able to do something about this, but we currently are just going to let it pass.
66
+ return;
67
+ }
68
+ // We currently do not lint any path.join without '__dirname' as the first argument
69
+ if (!firstArgIsDirname(node)) {
70
+ return;
71
+ }
72
+ const args = argumentList(node);
73
+ if (hasSlashes(args)) {
74
+ // ERROR: This path looks like 'path.join(__dirname, 'a/b')' and should be changed to 'path.join(__dirname, 'a', 'b')'
75
+ context.report({ node, message: `${recreatePath(args)} is not a valid path. It has '/' in the arguments which is not allowed. Each directory should be its own separate argument.` });
76
+ return;
77
+ }
78
+ const firstDownDir = args.findIndex((p) => p !== '..');
79
+ // Confirm path does not have any unnecessary '..' paths
80
+ // This allows us to validate subsequent checks
81
+ if (firstDownDir > 0 && args.some((p, i) => p === '..' && i > firstDownDir)) {
82
+ // ERROR: This path oscillates between up and down commands
83
+ context.report({ node, message: `${recreatePath(args)} is not a valid path. It goes backwards and forwards and backwards again, and can be simplified.` });
84
+ return;
85
+ }
86
+ // Exclude the case where there are no '..' at all in the path -- those are never invalid
87
+ const currentFile = context.getFilename();
88
+ if (firstDownDir > 0) {
89
+ for (let i = 0; i < firstDownDir; i++) {
90
+ const pjFile = path.join(...[path.dirname(currentFile), ...args.slice(0, i), 'package.json']);
91
+ if (fs.existsSync(pjFile)) {
92
+ // ERROR: this path will end up going out of the package.json directory
93
+ context.report({ node, message: `${recreatePath(args)} is not a valid path. It goes beyond the parent library's package.json file so the file it points to will not be available after the library is packaged.` });
94
+ return;
95
+ }
96
+ }
97
+ }
98
+ }
99
+ },
100
+ };
101
+ }
102
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibm8taW52YWxpZC1wYXRoLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL3J1bGVzL25vLWludmFsaWQtcGF0aC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FBb0NBLHdCQXNEQztBQTFGRCx1Q0FBeUI7QUFDekIsMkNBQTZCO0FBRzdCLFNBQVMsa0JBQWtCLENBQUMsSUFBUzs7SUFDbkMsT0FBTyxDQUNMLENBQUEsTUFBQSxNQUFBLElBQUksQ0FBQyxNQUFNLDBDQUFFLFFBQVEsMENBQUUsSUFBSSxNQUFLLE1BQU07UUFDdEMsQ0FBQyxDQUFBLE1BQUEsTUFBQSxNQUFBLE1BQUEsSUFBSSxDQUFDLE1BQU0sMENBQUUsVUFBVSwwQ0FBRSxNQUFNLDBDQUFFLE1BQU0sMENBQUUsSUFBSSxNQUFLLE1BQU07YUFDekQsTUFBQSxNQUFBLElBQUksQ0FBQyxNQUFNLDBDQUFFLFNBQVMsMENBQUUsSUFBSSxDQUFDLENBQUMsQ0FBTSxFQUFFLEVBQUUsZUFBQyxPQUFBLENBQUEsTUFBQSxNQUFBLENBQUMsQ0FBQyxNQUFNLDBDQUFFLE1BQU0sMENBQUUsSUFBSSxNQUFLLE1BQU0sQ0FBQSxFQUFBLENBQUMsQ0FBQSxDQUFDLENBQzdFLENBQUM7QUFDSixDQUFDO0FBRUQsU0FBUyxtQkFBbUIsQ0FBQyxJQUFTO0lBQ3BDLGlFQUFpRTtJQUNqRSxNQUFNLFVBQVUsR0FBRyxJQUFJLENBQUMsU0FBUyxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQztJQUMzQyxPQUFPLFVBQVUsQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFNLEVBQUUsRUFBRSxDQUFDLENBQUMsQ0FBQyxLQUFLLEtBQUssU0FBUyxDQUFDLENBQUM7QUFDN0QsQ0FBQztBQUVELFNBQVMsVUFBVSxDQUFDLElBQWM7SUFDaEMsT0FBTyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUMs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QUFDLE9BQU8sQ0FBQyxXQUFXLENBQUMsRUFBRSxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUFFLGNBQWMsQ0FBQyxDQUFDLENBQUM7d0JBQzlGLElBQUksRUFBRSxDQUFDLFVBQVUsQ0FBQyxNQUFNLENBQUMsRUFBRSxDQUFDOzRCQUMxQix1RUFBdUU7NEJBQ3ZFLE9BQU8sQ0FBQyxNQUFNLENBQUMsRUFBRSxJQUFJLEVBQUUsT0FBTyxFQUFFLEdBQUcsWUFBWSxDQUFDLElBQUksQ0FBQywySkFBMkosRUFBRSxDQUFDLENBQUM7NEJBQ3BOLE9BQU87d0JBQ1QsQ0FBQztvQkFDSCxDQUFDO2dCQUNILENBQUM7WUFDSCxDQUFDO1FBQ0gsQ0FBQztLQUNGLENBQUM7QUFDSixDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0ICogYXMgZnMgZnJvbSAnZnMnO1xuaW1wb3J0ICogYXMgcGF0aCBmcm9tICdwYXRoJztcbmltcG9ydCB7IFJ1bGUgfSBmcm9tICdlc2xpbnQnO1xuXG5mdW5jdGlvbiBpc1BhdGhKb2luRnVuY0NhbGwobm9kZTogYW55KTogYm9vbGVhbiB7XG4gIHJldHVybiAoXG4gICAgbm9kZS5jYWxsZWU/LnByb3BlcnR5Py5uYW1lID09PSAnam9pbicgJiZcbiAgICAobm9kZS5wYXJlbnQ/LmV4cHJlc3Npb24/LmNhbGxlZT8ub2JqZWN0Py5uYW1lID09PSAncGF0aCcgfHxcbiAgICBub2RlLnBhcmVudD8uYXJndW1lbnRzPy5zb21lKChhOiBhbnkpID0+IGEuY2FsbGVlPy5vYmplY3Q/Lm5hbWUgPT09ICdwYXRoJykpXG4gICk7XG59XG5cbmZ1bmN0aW9uIG5vQXJndW1lbnRWYXJpYWJsZXMobm9kZTogYW55KTogYm9vbGVhbiB7XG4gIC8vIE91dHNpZGUgb2YgdGhlIGZpcnN0IGFyZ3VtZW50LCBhbGwgYXJndW1lbnRzIHNob3VsZCBiZSBzdHJpbmdzXG4gIGNvbnN0IGNvbXBvbmVudHMgPSBub2RlLmFyZ3VtZW50cy5zbGljZSgxKTtcbiAgcmV0dXJuIGNvbXBvbmVudHMuZXZlcnkoKGE6IGFueSkgPT4gYS52YWx1ZSAhPT0gdW5kZWZpbmVkKTtcbn1cblxuZnVuY3Rpb24gaGFzU2xhc2hlcyhhcmdzOiBzdHJpbmdbXSk6IGJvb2xlYW4ge1xuICByZXR1cm4gYXJncy5zb21lKChhKSA9PiBhLmluY2x1ZGVzKCcvJykpO1xufVxuXG5mdW5jdGlvbiBmaXJzdEFyZ0lzRGlybmFtZShub2RlOiBhbnkpOiBib29sZWFuIHtcbiAgcmV0dXJuIG5vZGUuYXJndW1lbnRzWzBdLm5hbWUgJiYgbm9kZS5hcmd1bWVudHNbMF0ubmFtZSA9PT0gJ19fZGlybmFtZSc7XG59XG5cbmZ1bmN0aW9uIGFyZ3VtZW50TGlzdChub2RlOiBhbnkpOiBzdHJpbmdbXSB7XG4gIC8vIEFscmVhZHkgY29uZmlybWVkIHRoYXQgZmlyc3QgYXJndW1lbnQgaXMgJ19fZGlybmFtZScsIHNvIGNhbiBzYWZlbHkgcmVtb3ZlIGl0XG4gIGNvbnN0IGFyZ3M6IHN0cmluZ1tdID0gbm9kZS5hcmd1bWVudHMuc2xpY2UoMSkubWFwKChhOiBhbnkpID0+IHsgcmV0dXJuIGEudmFsdWU7IH0pO1xuICByZXR1cm4gYXJncztcbn1cblxuZnVuY3Rpb24gcmVjcmVhdGVQYXRoKGFyZ3M6IHN0cmluZ1tdKTogc3RyaW5nIHtcbiAgcmV0dXJuIGBwYXRoLmpvaW4oX19kaXJuYW1lLCAnJHthcmdzLmpvaW4oJ1xcJywgXFwnJyl9JylgO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gY3JlYXRlKGNvbnRleHQ6IFJ1bGUuUnVsZUNvbnRleHQpOiBSdWxlLk5vZGVMaXN0ZW5lciB7XG4gIHJldHVybiB7XG4gICAgQ2FsbEV4cHJlc3Npb24obm9kZTogYW55KSB7XG4gICAgICBpZiAoaXNQYXRoSm9pbkZ1bmNDYWxsKG5vZGUpKSB7XG4gICAgICAgIGlmIChub2RlLmFyZ3VtZW50cy5sZW5ndGggPT09IDApIHtcbiAgICAgICAgICAvLyBFUlJPUjogdGhpcyBpcyAncGF0aC5qb2luKCknXG4gICAgICAgICAgY29udGV4dC5yZXBvcnQoeyBub2RlLCBtZXNzYWdlOiAnXFwncGF0aC5qb2luKClcXCcgaXMgbm90IGEgdmFsaWQgcGF0aC4gWW91IG11c3Qgc3BlY2lmeSBhcmd1bWVudHMgaW50byB0aGUgZnVuY3Rpb24uJyB9KTtcbiAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoIW5vQXJndW1lbnRWYXJpYWJsZXMobm9kZSkpIHtcbiAgICAgICAgICAvLyBXQVJOSU5HOiB1bmV4cGVjdGVkIG5vbi1zdHJpbmcgaW4gdGhlIGFyZ3VtZW50IGxpc3QuIFRoaXMgaGFwcGVucyBpZiBwYXJ0IG9mIHRoZSBhcmd1bWVudCBsaXN0IGlzIGEgdmFyaWFibGUsIGkuZS4gYHBhdGguam9pbihfX2Rpcm5hbWUsIG15UGF0aClgLlxuICAgICAgICAgIC8vIFdlIG1heSBiZSBhYmxlIHRvIGRvIHNvbWV0aGluZyBhYm91dCB0aGlzLCBidXQgd2UgY3VycmVudGx5IGFyZSBqdXN0IGdvaW5nIHRvIGxldCBpdCBwYXNzLlxuICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIFdlIGN1cnJlbnRseSBkbyBub3QgbGludCBhbnkgcGF0aC5qb2luIHdpdGhvdXQgJ19fZGlybmFtZScgYXMgdGhlIGZpcnN0IGFyZ3VtZW50XG4gICAgICAgIGlmICghZmlyc3RBcmdJc0Rpcm5hbWUobm9kZSkpIHtcbiAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCBhcmdzID0gYXJndW1lbnRMaXN0KG5vZGUpO1xuXG4gICAgICAgIGlmIChoYXNTbGFzaGVzKGFyZ3MpKSB7XG4gICAgICAgICAgLy8gRVJST1I6IFRoaXMgcGF0aCBsb29rcyBsaWtlICdwYXRoLmpvaW4oX19kaXJuYW1lLCAnYS9iJyknIGFuZCBzaG91bGQgYmUgY2hhbmdlZCB0byAncGF0aC5qb2luKF9fZGlybmFtZSwgJ2EnLCAnYicpJ1xuICAgICAgICAgIGNvbnRleHQucmVwb3J0KHsgbm9kZSwgbWVzc2FnZTogYCR7cmVjcmVhdGVQYXRoKGFyZ3MpfSBpcyBub3QgYSB2YWxpZCBwYXRoLiBJdCBoYXMgJy8nIGluIHRoZSBhcmd1bWVudHMgd2hpY2ggaXMgbm90IGFsbG93ZWQuIEVhY2ggZGlyZWN0b3J5IHNob3VsZCBiZSBpdHMgb3duIHNlcGFyYXRlIGFyZ3VtZW50LmAgfSk7XG4gICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgZmlyc3REb3duRGlyID0gYXJncy5maW5kSW5kZXgoKHApID0+IHAgIT09ICcuLicpO1xuXG4gICAgICAgIC8vIENvbmZpcm0gcGF0aCBkb2VzIG5vdCBoYXZlIGFueSB1bm5lY2Vzc2FyeSAnLi4nIHBhdGhzXG4gICAgICAgIC8vIFRoaXMgYWxsb3dzIHVzIHRvIHZhbGlkYXRlIHN1YnNlcXVlbnQgY2hlY2tzXG4gICAgICAgIGlmIChmaXJzdERvd25EaXIgPiAwICYmIGFyZ3Muc29tZSgocCwgaSkgPT4gcCA9PT0gJy4uJyAmJiBpID4gZmlyc3REb3duRGlyKSkge1xuICAgICAgICAgIC8vIEVSUk9SOiBUaGlzIHBhdGggb3NjaWxsYXRlcyBiZXR3ZWVuIHVwIGFuZCBkb3duIGNvbW1hbmRzXG4gICAgICAgICAgY29udGV4dC5yZXBvcnQoeyBub2RlLCBtZXNzYWdlOiBgJHtyZWNyZWF0ZVBhdGgoYXJncyl9IGlzIG5vdCBhIHZhbGlkIHBhdGguIEl0IGdvZXMgYmFja3dhcmRzIGFuZCBmb3J3YXJkcyBhbmQgYmFja3dhcmRzIGFnYWluLCBhbmQgY2FuIGJlIHNpbXBsaWZpZWQuYCB9KTtcbiAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICAvLyBFeGNsdWRlIHRoZSBjYXNlIHdoZXJlIHRoZXJlIGFyZSBubyAnLi4nIGF0IGFsbCBpbiB0aGUgcGF0aCAtLSB0aG9zZSBhcmUgbmV2ZXIgaW52YWxpZFxuICAgICAgICBjb25zdCBjdXJyZW50RmlsZSA9IGNvbnRleHQuZ2V0RmlsZW5hbWUoKTtcbiAgICAgICAgaWYgKGZpcnN0RG93bkRpciA+IDApIHtcbiAgICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IGZpcnN0RG93bkRpcjsgaSsrKSB7XG4gICAgICAgICAgICBjb25zdCBwakZpbGUgPSBwYXRoLmpvaW4oLi4uW3BhdGguZGlybmFtZShjdXJyZW50RmlsZSksIC4uLmFyZ3Muc2xpY2UoMCwgaSksICdwYWNrYWdlLmpzb24nXSk7XG4gICAgICAgICAgICBpZiAoZnMuZXhpc3RzU3luYyhwakZpbGUpKSB7XG4gICAgICAgICAgICAgIC8vIEVSUk9SOiB0aGlzIHBhdGggd2lsbCBlbmQgdXAgZ29pbmcgb3V0IG9mIHRoZSBwYWNrYWdlLmpzb24gZGlyZWN0b3J5XG4gICAgICAgICAgICAgIGNvbnRleHQucmVwb3J0KHsgbm9kZSwgbWVzc2FnZTogYCR7cmVjcmVhdGVQYXRoKGFyZ3MpfSBpcyBub3QgYSB2YWxpZCBwYXRoLiBJdCBnb2VzIGJleW9uZCB0aGUgcGFyZW50IGxpYnJhcnkncyBwYWNrYWdlLmpzb24gZmlsZSBzbyB0aGUgZmlsZSBpdCBwb2ludHMgdG8gd2lsbCBub3QgYmUgYXZhaWxhYmxlIGFmdGVyIHRoZSBsaWJyYXJ5IGlzIHBhY2thZ2VkLmAgfSk7XG4gICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9LFxuICB9O1xufVxuIl19
@@ -0,0 +1,7 @@
1
+ import { Rule } from 'eslint';
2
+ export declare const meta: {
3
+ messages: {
4
+ hardcodedArn: string;
5
+ };
6
+ };
7
+ export declare function create(context: Rule.RuleContext): Rule.NodeListener;
@@ -0,0 +1,38 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.meta = void 0;
4
+ exports.create = create;
5
+ const is_prod_file_1 = require("../private/is-prod-file");
6
+ exports.meta = {
7
+ messages: {
8
+ hardcodedArn: 'There are more partitions than just \'aws\'. Silence this message if you are sure this is safe, or switch to using \'Aws.PARTITION\'',
9
+ },
10
+ };
11
+ function create(context) {
12
+ return {
13
+ // `node` is a type from @typescript-eslint/typescript-estree, but using 'any' for now
14
+ // since it's incompatible with eslint.Rule namespace. Waiting for better compatibility in
15
+ // https://github.com/typescript-eslint/typescript-eslint/tree/1765a178e456b152bd48192eb5db7e8541e2adf2/packages/experimental-utils#note
16
+ // Meanwhile, use a debugger to explore the AST node.
17
+ Literal(node) {
18
+ if (!(0, is_prod_file_1.isProdFile)(context.getFilename())) {
19
+ return;
20
+ }
21
+ if (typeof node.value === 'string' && node.value.includes('arn:aws:')) {
22
+ context.report({ node, messageId: 'hardcodedArn' });
23
+ }
24
+ },
25
+ TemplateLiteral(node) {
26
+ if (!(0, is_prod_file_1.isProdFile)(context.getFilename())) {
27
+ return;
28
+ }
29
+ for (const quasi of node.quasis) {
30
+ const value = quasi.value.cooked;
31
+ if (typeof value === 'string' && value.includes('arn:aws:')) {
32
+ context.report({ node: quasi, messageId: 'hardcodedArn' });
33
+ }
34
+ }
35
+ },
36
+ };
37
+ }
38
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibm8tbGl0ZXJhbC1wYXJ0aXRpb24uanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvcnVsZXMvbm8tbGl0ZXJhbC1wYXJ0aXRpb24udHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBU0Esd0JBK0JDO0FBdkNELDBEQUFxRDtBQUV4QyxRQUFBLElBQUksR0FBRztJQUNsQixRQUFRLEVBQUU7UUFDUixZQUFZLEVBQUUsc0lBQXNJO0tBQ3JKO0NBQ0YsQ0FBQztBQUVGLFNBQWdCLE1BQU0sQ0FBQyxPQUF5QjtJQUM5QyxPQUFPO1FBRUwsc0ZBQXNGO1FBQ3RGLDBGQUEwRjtRQUMxRix3SUFBd0k7UUFDeEkscURBQXFEO1FBRXJELE9BQU8sQ0FBQyxJQUFTO1lBQ2YsSUFBSSxDQUFDLElBQUEseUJBQVUsRUFBQyxPQUFPLENBQUMsV0FBVyxFQUFFLENBQUMsRUFBRSxDQUFDO2dCQUN2QyxPQUFPO1lBQ1QsQ0FBQztZQUVELElBQUksT0FBTyxJQUFJLENBQUMsS0FBSyxLQUFLLFFBQVEsSUFBSSxJQUFJLENBQUMsS0FBSyxDQUFDLFFBQVEsQ0FBQyxVQUFVLENBQUMsRUFBRSxDQUFDO2dCQUN0RSxPQUFPLENBQUMsTUFBTSxDQUFDLEVBQUUsSUFBSSxFQUFFLFNBQVMsRUFBRSxjQUFjLEVBQUUsQ0FBQyxDQUFDO1lBQ3RELENBQUM7UUFDSCxDQUFDO1FBRUQsZUFBZSxDQUFDLElBQVM7WUFDdkIsSUFBSSxDQUFDLElBQUEseUJBQVUsRUFBQyxPQUFPLENBQUMsV0FBVyxFQUFFLENBQUMsRUFBRSxDQUFDO2dCQUN2QyxPQUFPO1lBQ1QsQ0FBQztZQUNELEtBQUssTUFBTSxLQUFLLElBQUksSUFBSSxDQUFDLE1BQU0sRUFBRSxDQUFDO2dCQUNoQyxNQUFNLEtBQUssR0FBRyxLQUFLLENBQUMsS0FBSyxDQUFDLE1BQU0sQ0FBQztnQkFFakMsSUFBSSxPQUFPLEtBQUssS0FBSyxRQUFRLElBQUksS0FBSyxDQUFDLFFBQVEsQ0FBQyxVQUFVLENBQUMsRUFBRSxDQUFDO29CQUM1RCxPQUFPLENBQUMsTUFBTSxDQUFDLEVBQUUsSUFBSSxFQUFFLEtBQUssRUFBRSxTQUFTLEVBQUUsY0FBYyxFQUFFLENBQUMsQ0FBQztnQkFDN0QsQ0FBQztZQUNILENBQUM7UUFDSCxDQUFDO0tBQ0YsQ0FBQztBQUNKLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBSdWxlIH0gZnJvbSAnZXNsaW50JztcbmltcG9ydCB7IGlzUHJvZEZpbGUgfSBmcm9tICcuLi9wcml2YXRlL2lzLXByb2QtZmlsZSc7XG5cbmV4cG9ydCBjb25zdCBtZXRhID0ge1xuICBtZXNzYWdlczoge1xuICAgIGhhcmRjb2RlZEFybjogJ1RoZXJlIGFyZSBtb3JlIHBhcnRpdGlvbnMgdGhhbiBqdXN0IFxcJ2F3c1xcJy4gU2lsZW5jZSB0aGlzIG1lc3NhZ2UgaWYgeW91IGFyZSBzdXJlIHRoaXMgaXMgc2FmZSwgb3Igc3dpdGNoIHRvIHVzaW5nIFxcJ0F3cy5QQVJUSVRJT05cXCcnLFxuICB9LFxufTtcblxuZXhwb3J0IGZ1bmN0aW9uIGNyZWF0ZShjb250ZXh0OiBSdWxlLlJ1bGVDb250ZXh0KTogUnVsZS5Ob2RlTGlzdGVuZXIge1xuICByZXR1cm4ge1xuXG4gICAgLy8gYG5vZGVgIGlzIGEgdHlwZSBmcm9tIEB0eXBlc2NyaXB0LWVzbGludC90eXBlc2NyaXB0LWVzdHJlZSwgYnV0IHVzaW5nICdhbnknIGZvciBub3dcbiAgICAvLyBzaW5jZSBpdCdzIGluY29tcGF0aWJsZSB3aXRoIGVzbGludC5SdWxlIG5hbWVzcGFjZS4gV2FpdGluZyBmb3IgYmV0dGVyIGNvbXBhdGliaWxpdHkgaW5cbiAgICAvLyBodHRwczovL2dpdGh1Yi5jb20vdHlwZXNjcmlwdC1lc2xpbnQvdHlwZXNjcmlwdC1lc2xpbnQvdHJlZS8xNzY1YTE3OGU0NTZiMTUyYmQ0ODE5MmViNWRiN2U4NTQxZTJhZGYyL3BhY2thZ2VzL2V4cGVyaW1lbnRhbC11dGlscyNub3RlXG4gICAgLy8gTWVhbndoaWxlLCB1c2UgYSBkZWJ1Z2dlciB0byBleHBsb3JlIHRoZSBBU1Qgbm9kZS5cblxuICAgIExpdGVyYWwobm9kZTogYW55KSB7XG4gICAgICBpZiAoIWlzUHJvZEZpbGUoY29udGV4dC5nZXRGaWxlbmFtZSgpKSkge1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG5cbiAgICAgIGlmICh0eXBlb2Ygbm9kZS52YWx1ZSA9PT0gJ3N0cmluZycgJiYgbm9kZS52YWx1ZS5pbmNsdWRlcygnYXJuOmF3czonKSkge1xuICAgICAgICBjb250ZXh0LnJlcG9ydCh7IG5vZGUsIG1lc3NhZ2VJZDogJ2hhcmRjb2RlZEFybicgfSk7XG4gICAgICB9XG4gICAgfSxcblxuICAgIFRlbXBsYXRlTGl0ZXJhbChub2RlOiBhbnkpIHtcbiAgICAgIGlmICghaXNQcm9kRmlsZShjb250ZXh0LmdldEZpbGVuYW1lKCkpKSB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICAgIGZvciAoY29uc3QgcXVhc2kgb2Ygbm9kZS5xdWFzaXMpIHtcbiAgICAgICAgY29uc3QgdmFsdWUgPSBxdWFzaS52YWx1ZS5jb29rZWQ7XG5cbiAgICAgICAgaWYgKHR5cGVvZiB2YWx1ZSA9PT0gJ3N0cmluZycgJiYgdmFsdWUuaW5jbHVkZXMoJ2Fybjphd3M6JykpIHtcbiAgICAgICAgICBjb250ZXh0LnJlcG9ydCh7IG5vZGU6IHF1YXNpLCBtZXNzYWdlSWQ6ICdoYXJkY29kZWRBcm4nIH0pO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfSxcbiAgfTtcbn1cbiJdfQ==
@@ -0,0 +1,24 @@
1
+ import { Rule } from 'eslint';
2
+ /**
3
+ * Get the programmer to acknowledge that `Promise.all()` is potentially dangerous.
4
+ *
5
+ * Since JavaScript is single-threaded, `Promise.all()` will only ever be used for
6
+ * I/O-bound tasks. However, I/O-parallelism isn't free either. Every async I/O-performing
7
+ * task launched will consume some FDs, and their amount is limited. If the amount
8
+ * of promises launched is a function of the input the program runs on, the system
9
+ * FDs might be exhausted. Some concurrency limit must be introduced.
10
+ *
11
+ * This linter rule exists to remind the programmer of that fact. It triggers
12
+ * on every `Promise.all()` invocation and cannot be resolved; the only solution
13
+ * is to think about it, and then silence this rule as proof that you thought about it.
14
+ *
15
+ * In summary, it's fine if:
16
+ *
17
+ * - The arguments to `Promise.all()` is a fixed set of promises; OR
18
+ * - The arguments to `Promise.all()` is throttled by a mechanism like 'p-limit' or
19
+ * similar.
20
+ *
21
+ * (This check is currently only in the CDK repo; it can benefit all TypeScript repos,
22
+ * we should introduce and publish a global lint rules package).
23
+ */
24
+ export declare function create(context: Rule.RuleContext): Rule.NodeListener;
@@ -0,0 +1,43 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.create = create;
4
+ const match_ast_1 = require("../private/match-ast");
5
+ const type_checkers_1 = require("../private/type-checkers");
6
+ /**
7
+ * Get the programmer to acknowledge that `Promise.all()` is potentially dangerous.
8
+ *
9
+ * Since JavaScript is single-threaded, `Promise.all()` will only ever be used for
10
+ * I/O-bound tasks. However, I/O-parallelism isn't free either. Every async I/O-performing
11
+ * task launched will consume some FDs, and their amount is limited. If the amount
12
+ * of promises launched is a function of the input the program runs on, the system
13
+ * FDs might be exhausted. Some concurrency limit must be introduced.
14
+ *
15
+ * This linter rule exists to remind the programmer of that fact. It triggers
16
+ * on every `Promise.all()` invocation and cannot be resolved; the only solution
17
+ * is to think about it, and then silence this rule as proof that you thought about it.
18
+ *
19
+ * In summary, it's fine if:
20
+ *
21
+ * - The arguments to `Promise.all()` is a fixed set of promises; OR
22
+ * - The arguments to `Promise.all()` is throttled by a mechanism like 'p-limit' or
23
+ * similar.
24
+ *
25
+ * (This check is currently only in the CDK repo; it can benefit all TypeScript repos,
26
+ * we should introduce and publish a global lint rules package).
27
+ */
28
+ function create(context) {
29
+ return {
30
+ CallExpression: node => {
31
+ if ((0, match_ast_1.match)(node.callee, (0, type_checkers_1.matchMemberExpression)({
32
+ object: (0, type_checkers_1.matchIdentifier)('Promise'),
33
+ property: (0, type_checkers_1.matchIdentifier)('all'),
34
+ }))) {
35
+ context.report({
36
+ message: 'Ensure the number of awaited promises does not depend on program input, or their parallelism is limited using something like \'p-limit\' or similar. Acknowledge this message using \'// eslint-disable-next-line @cdklabs/promiseall-no-unbounded-parallelism\'',
37
+ node,
38
+ });
39
+ }
40
+ },
41
+ };
42
+ }
43
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicHJvbWlzZWFsbC1uby11bmJvdW5kZWQtcGFyYWxsZWxpc20uanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvcnVsZXMvcHJvbWlzZWFsbC1uby11bmJvdW5kZWQtcGFyYWxsZWxpc20udHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7QUEwQkEsd0JBY0M7QUF2Q0Qsb0RBQTZDO0FBQzdDLDREQUFrRjtBQUVsRjs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0dBcUJHO0FBQ0gsU0FBZ0IsTUFBTSxDQUFDLE9BQXlCO0lBQzlDLE9BQU87UUFDTCxjQUFjLEVBQUUsSUFBSSxDQUFDLEVBQUU7WUFDckIsSUFBSSxJQUFBLGlCQUFLLEVBQUMsSUFBSSxDQUFDLE1BQU0sRUFBRSxJQUFBLHFDQUFxQixFQUFDO2dCQUMzQyxNQUFNLEVBQUUsSUFBQSwrQkFBZSxFQUFDLFNBQVMsQ0FBQztnQkFDbEMsUUFBUSxFQUFFLElBQUEsK0JBQWUsRUFBQyxLQUFLLENBQUM7YUFDakMsQ0FBQyxDQUFDLEVBQUUsQ0FBQztnQkFDSixPQUFPLENBQUMsTUFBTSxDQUFDO29CQUNiLE9BQU8sRUFBRSxrUUFBa1E7b0JBQzNRLElBQUk7aUJBQ0wsQ0FBQyxDQUFDO1lBQ0wsQ0FBQztRQUNILENBQUM7S0FDRixDQUFDO0FBQ0osQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IFJ1bGUgfSBmcm9tICdlc2xpbnQnO1xuaW1wb3J0IHsgbWF0Y2ggfSBmcm9tICcuLi9wcml2YXRlL21hdGNoLWFzdCc7XG5pbXBvcnQgeyBtYXRjaElkZW50aWZpZXIsIG1hdGNoTWVtYmVyRXhwcmVzc2lvbiB9IGZyb20gJy4uL3ByaXZhdGUvdHlwZS1jaGVja2Vycyc7XG5cbi8qKlxuICogR2V0IHRoZSBwcm9ncmFtbWVyIHRvIGFja25vd2xlZGdlIHRoYXQgYFByb21pc2UuYWxsKClgIGlzIHBvdGVudGlhbGx5IGRhbmdlcm91cy5cbiAqXG4gKiBTaW5jZSBKYXZhU2NyaXB0IGlzIHNpbmdsZS10aHJlYWRlZCwgYFByb21pc2UuYWxsKClgIHdpbGwgb25seSBldmVyIGJlIHVzZWQgZm9yXG4gKiBJL08tYm91bmQgdGFza3MuIEhvd2V2ZXIsIEkvTy1wYXJhbGxlbGlzbSBpc24ndCBmcmVlIGVpdGhlci4gRXZlcnkgYXN5bmMgSS9PLXBlcmZvcm1pbmdcbiAqIHRhc2sgbGF1bmNoZWQgd2lsbCBjb25zdW1lIHNvbWUgRkRzLCBhbmQgdGhlaXIgYW1vdW50IGlzIGxpbWl0ZWQuIElmIHRoZSBhbW91bnRcbiAqIG9mIHByb21pc2VzIGxhdW5jaGVkIGlzIGEgZnVuY3Rpb24gb2YgdGhlIGlucHV0IHRoZSBwcm9ncmFtIHJ1bnMgb24sIHRoZSBzeXN0ZW1cbiAqIEZEcyBtaWdodCBiZSBleGhhdXN0ZWQuIFNvbWUgY29uY3VycmVuY3kgbGltaXQgbXVzdCBiZSBpbnRyb2R1Y2VkLlxuICpcbiAqIFRoaXMgbGludGVyIHJ1bGUgZXhpc3RzIHRvIHJlbWluZCB0aGUgcHJvZ3JhbW1lciBvZiB0aGF0IGZhY3QuIEl0IHRyaWdnZXJzXG4gKiBvbiBldmVyeSBgUHJvbWlzZS5hbGwoKWAgaW52b2NhdGlvbiBhbmQgY2Fubm90IGJlIHJlc29sdmVkOyB0aGUgb25seSBzb2x1dGlvblxuICogaXMgdG8gdGhpbmsgYWJvdXQgaXQsIGFuZCB0aGVuIHNpbGVuY2UgdGhpcyBydWxlIGFzIHByb29mIHRoYXQgeW91IHRob3VnaHQgYWJvdXQgaXQuXG4gKlxuICogSW4gc3VtbWFyeSwgaXQncyBmaW5lIGlmOlxuICpcbiAqIC0gVGhlIGFyZ3VtZW50cyB0byBgUHJvbWlzZS5hbGwoKWAgaXMgYSBmaXhlZCBzZXQgb2YgcHJvbWlzZXM7IE9SXG4gKiAtIFRoZSBhcmd1bWVudHMgdG8gYFByb21pc2UuYWxsKClgIGlzIHRocm90dGxlZCBieSBhIG1lY2hhbmlzbSBsaWtlICdwLWxpbWl0JyBvclxuICogICBzaW1pbGFyLlxuICpcbiAqIChUaGlzIGNoZWNrIGlzIGN1cnJlbnRseSBvbmx5IGluIHRoZSBDREsgcmVwbzsgaXQgY2FuIGJlbmVmaXQgYWxsIFR5cGVTY3JpcHQgcmVwb3MsXG4gKiB3ZSBzaG91bGQgaW50cm9kdWNlIGFuZCBwdWJsaXNoIGEgZ2xvYmFsIGxpbnQgcnVsZXMgcGFja2FnZSkuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBjcmVhdGUoY29udGV4dDogUnVsZS5SdWxlQ29udGV4dCk6IFJ1bGUuTm9kZUxpc3RlbmVyIHtcbiAgcmV0dXJuIHtcbiAgICBDYWxsRXhwcmVzc2lvbjogbm9kZSA9PiB7XG4gICAgICBpZiAobWF0Y2gobm9kZS5jYWxsZWUsIG1hdGNoTWVtYmVyRXhwcmVzc2lvbih7XG4gICAgICAgIG9iamVjdDogbWF0Y2hJZGVudGlmaWVyKCdQcm9taXNlJyksXG4gICAgICAgIHByb3BlcnR5OiBtYXRjaElkZW50aWZpZXIoJ2FsbCcpLFxuICAgICAgfSkpKSB7XG4gICAgICAgIGNvbnRleHQucmVwb3J0KHtcbiAgICAgICAgICBtZXNzYWdlOiAnRW5zdXJlIHRoZSBudW1iZXIgb2YgYXdhaXRlZCBwcm9taXNlcyBkb2VzIG5vdCBkZXBlbmQgb24gcHJvZ3JhbSBpbnB1dCwgb3IgdGhlaXIgcGFyYWxsZWxpc20gaXMgbGltaXRlZCB1c2luZyBzb21ldGhpbmcgbGlrZSBcXCdwLWxpbWl0XFwnIG9yIHNpbWlsYXIuIEFja25vd2xlZGdlIHRoaXMgbWVzc2FnZSB1c2luZyBcXCcvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQGNka2xhYnMvcHJvbWlzZWFsbC1uby11bmJvdW5kZWQtcGFyYWxsZWxpc21cXCcnLFxuICAgICAgICAgIG5vZGUsXG4gICAgICAgIH0pO1xuICAgICAgfVxuICAgIH0sXG4gIH07XG59XG4iXX0=