@forge/lint 5.0.4-next.0 → 5.1.0-next.2

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/CHANGELOG.md CHANGED
@@ -1,5 +1,24 @@
1
1
  # @forge/lint
2
2
 
3
+ ## 5.1.0-next.2
4
+
5
+ ### Patch Changes
6
+
7
+ - Updated dependencies [8ace637]
8
+ - @forge/cli-shared@4.2.0-next.2
9
+
10
+ ## 5.1.0-next.1
11
+
12
+ ### Minor Changes
13
+
14
+ - 3e53438: Add lint rule for invokeRemote in @forge/api
15
+
16
+ ### Patch Changes
17
+
18
+ - Updated dependencies [6f17340]
19
+ - @forge/manifest@7.2.2-next.0
20
+ - @forge/cli-shared@4.2.0-next.1
21
+
3
22
  ## 5.0.4-next.0
4
23
 
5
24
  ### Patch Changes
@@ -1 +1 @@
1
- {"version":3,"file":"lint.d.ts","sourceRoot":"","sources":["../../src/lint/lint.ts"],"names":[],"mappings":"AAQA,OAAO,EAAE,cAAc,IAAI,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AAC7D,OAAO,EAAE,MAAM,IAAI,CAAC;AAIpB,OAAO,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAC;AACpC,OAAO,EAAE,eAAe,EAAE,SAAS,EAAE,UAAU,EAAE,UAAU,EAAkB,MAAM,oBAAoB,CAAC;AAUxG,MAAM,WAAW,YAAY;IAC3B,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,eAAO,MAAM,iBAAiB,WAAY,UAAU,eAAe,UAAU,EAAE,4BAAuB,IA+CrG,CAAC;AAEF,eAAO,MAAM,YAAY,gBAAiB,UAAU,EAAE,KAAG,YAQxD,CAAC;AAEF,eAAO,MAAM,eAAe,aAChB,MAAM,UACR,eAAe,oBACN,OAAO,GAAG,QAAQ,CAAC,aAAa,KAChD,QAAQ,SAAS,CAOnB,CAAC;AAEF,eAAO,MAAM,IAAI,gBACF,MAAM,EAAE,YACX,QAAQ,eACL,MAAM,UACX,UAAU,6BAhBR,MAAM,UACR,eAAe,oBACN,OAAO,GAAG,QAAQ,CAAC,aAAa,KAChD,QAAQ,SAAS,CAAC,YAeV,eAAe,EAAE,KASzB,QAAQ,UAAU,EAAE,CAyCtB,CAAC;AAEF,eAAO,MAAM,QAAQ,WACX,UAAU,WACV,eAAe,KACtB,QAAQ,UAAU,EAAE,CAGtB,CAAC"}
1
+ {"version":3,"file":"lint.d.ts","sourceRoot":"","sources":["../../src/lint/lint.ts"],"names":[],"mappings":"AAQA,OAAO,EAAE,cAAc,IAAI,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AAC7D,OAAO,EAAE,MAAM,IAAI,CAAC;AAIpB,OAAO,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAC;AACpC,OAAO,EAAE,eAAe,EAAE,SAAS,EAAE,UAAU,EAAE,UAAU,EAAkB,MAAM,oBAAoB,CAAC;AAWxG,MAAM,WAAW,YAAY;IAC3B,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,eAAO,MAAM,iBAAiB,WAAY,UAAU,eAAe,UAAU,EAAE,4BAAuB,IA+CrG,CAAC;AAEF,eAAO,MAAM,YAAY,gBAAiB,UAAU,EAAE,KAAG,YAQxD,CAAC;AAEF,eAAO,MAAM,eAAe,aAChB,MAAM,UACR,eAAe,oBACN,OAAO,GAAG,QAAQ,CAAC,aAAa,KAChD,QAAQ,SAAS,CAOnB,CAAC;AAEF,eAAO,MAAM,IAAI,gBACF,MAAM,EAAE,YACX,QAAQ,eACL,MAAM,UACX,UAAU,6BAhBR,MAAM,UACR,eAAe,oBACN,OAAO,GAAG,QAAQ,CAAC,aAAa,KAChD,QAAQ,SAAS,CAAC,YAeV,eAAe,EAAE,KAUzB,QAAQ,UAAU,EAAE,CAyCtB,CAAC;AAEF,eAAO,MAAM,QAAQ,WACX,UAAU,WACV,eAAe,KACtB,QAAQ,UAAU,EAAE,CAGtB,CAAC"}
package/out/lint/lint.js CHANGED
@@ -15,6 +15,7 @@ const permission_linter_1 = require("./linters/permission-linter/permission-lint
15
15
  const deprecated_csp_permissions_manifest_linter_1 = require("./linters/manifest-linter/deprecated-csp-permissions-manifest-linter");
16
16
  const dynamic_properties_permissions_linter_1 = require("./linters/dynamic-properties-linter/dynamic-properties-permissions-linter");
17
17
  const remote_compute_manifest_linter_1 = require("./linters/manifest-linter/remote-compute-manifest-linter");
18
+ const invoke_remote_linter_1 = require("./linters/remote-linter/invoke-remote-linter");
18
19
  const reportLintResults = (logger, lintResults, showSummary = true) => {
19
20
  let numErrors = 0, numWarnings = 0;
20
21
  let noProblemsFound = true;
@@ -83,7 +84,8 @@ const lint = async (filesToLint, manifest, environment, logger, parseFunction =
83
84
  new remote_compute_manifest_linter_1.RemoteComputeManifestLinter(logger),
84
85
  new full_manifest_linter_1.FullManifestLinter(logger),
85
86
  new handler_linter_1.HandlerLinter(environment, manifest, logger),
86
- new dynamic_properties_permissions_linter_1.DynamicPropertiesPermissionsLinter(environment, manifest, logger)
87
+ new dynamic_properties_permissions_linter_1.DynamicPropertiesPermissionsLinter(environment, manifest, logger),
88
+ new invoke_remote_linter_1.InvokeRemoteLinter(environment, manifest, logger)
87
89
  ]) => {
88
90
  const { include, exclude } = await (0, cli_shared_1.listTSConfigIncludeExclude)(new cli_shared_1.FileSystemReader());
89
91
  const tsInclude = new Set(include);
@@ -0,0 +1,34 @@
1
+ import { TSESTree } from '@typescript-eslint/typescript-estree';
2
+ import { LintCriteriaMatch } from '../../linter-interface';
3
+ export declare enum InvokeRemoteTypes {
4
+ DIRECT_CALL = 0,
5
+ MEMBER_CALL = 1,
6
+ IMPORT_LIST = 2
7
+ }
8
+ export declare const INVOKE_REMOTE_PACKAGE_NAME = "@forge/api";
9
+ export declare const INVOKE_REMOTE_FUNCTION_NAME = "invokeRemote";
10
+ export interface InvokeRemoteDirectCall extends LintCriteriaMatch {
11
+ type: InvokeRemoteTypes.DIRECT_CALL;
12
+ remoteKey: string;
13
+ calleeName: string;
14
+ }
15
+ export interface InvokeRemoteMemberCall extends LintCriteriaMatch {
16
+ type: InvokeRemoteTypes.MEMBER_CALL;
17
+ remoteKey: string;
18
+ objectName: string;
19
+ }
20
+ export interface InvokeRemoteImport extends LintCriteriaMatch {
21
+ type: TSESTree.ImportClause['type'];
22
+ alias: string;
23
+ }
24
+ export interface InvokeRemoteImportList extends LintCriteriaMatch {
25
+ type: InvokeRemoteTypes.IMPORT_LIST;
26
+ imports: InvokeRemoteImport[];
27
+ }
28
+ export declare type InvokeRemoteCall = InvokeRemoteDirectCall | InvokeRemoteMemberCall;
29
+ export declare type InvokeRemoteUsage = InvokeRemoteCall | InvokeRemoteImportList;
30
+ export interface InvokeRemoteVerifierInput {
31
+ invokeRemoteCalls: InvokeRemoteCall[];
32
+ imports: InvokeRemoteImport[];
33
+ }
34
+ //# sourceMappingURL=invoke-remote-interface.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"invoke-remote-interface.d.ts","sourceRoot":"","sources":["../../../../src/lint/linters/remote-linter/invoke-remote-interface.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,sCAAsC,CAAC;AAEhE,OAAO,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAE3D,oBAAY,iBAAiB;IAC3B,WAAW,IAAA;IACX,WAAW,IAAA;IACX,WAAW,IAAA;CACZ;AAED,eAAO,MAAM,0BAA0B,eAAe,CAAC;AACvD,eAAO,MAAM,2BAA2B,iBAAiB,CAAC;AAE1D,MAAM,WAAW,sBAAuB,SAAQ,iBAAiB;IAC/D,IAAI,EAAE,iBAAiB,CAAC,WAAW,CAAC;IACpC,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,sBAAuB,SAAQ,iBAAiB;IAC/D,IAAI,EAAE,iBAAiB,CAAC,WAAW,CAAC;IACpC,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,kBAAmB,SAAQ,iBAAiB;IAC3D,IAAI,EAAE,QAAQ,CAAC,YAAY,CAAC,MAAM,CAAC,CAAC;IACpC,KAAK,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,sBAAuB,SAAQ,iBAAiB;IAC/D,IAAI,EAAE,iBAAiB,CAAC,WAAW,CAAC;IACpC,OAAO,EAAE,kBAAkB,EAAE,CAAC;CAC/B;AAED,oBAAY,gBAAgB,GAAG,sBAAsB,GAAG,sBAAsB,CAAC;AAE/E,oBAAY,iBAAiB,GAAG,gBAAgB,GAAG,sBAAsB,CAAC;AAE1E,MAAM,WAAW,yBAAyB;IACxC,iBAAiB,EAAE,gBAAgB,EAAE,CAAC;IACtC,OAAO,EAAE,kBAAkB,EAAE,CAAC;CAC/B"}
@@ -0,0 +1,11 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.INVOKE_REMOTE_FUNCTION_NAME = exports.INVOKE_REMOTE_PACKAGE_NAME = exports.InvokeRemoteTypes = void 0;
4
+ var InvokeRemoteTypes;
5
+ (function (InvokeRemoteTypes) {
6
+ InvokeRemoteTypes[InvokeRemoteTypes["DIRECT_CALL"] = 0] = "DIRECT_CALL";
7
+ InvokeRemoteTypes[InvokeRemoteTypes["MEMBER_CALL"] = 1] = "MEMBER_CALL";
8
+ InvokeRemoteTypes[InvokeRemoteTypes["IMPORT_LIST"] = 2] = "IMPORT_LIST";
9
+ })(InvokeRemoteTypes = exports.InvokeRemoteTypes || (exports.InvokeRemoteTypes = {}));
10
+ exports.INVOKE_REMOTE_PACKAGE_NAME = '@forge/api';
11
+ exports.INVOKE_REMOTE_FUNCTION_NAME = 'invokeRemote';
@@ -0,0 +1,17 @@
1
+ import { ManifestSchema as Manifest } from '@forge/manifest';
2
+ import BaseLinter from '../../base-linter';
3
+ import { LintLogger } from '../../linter-interface';
4
+ import { InvokeRemoteUsage, InvokeRemoteVerifierInput } from './invoke-remote-interface';
5
+ interface InvokeRemoteMatches {
6
+ [key: string]: InvokeRemoteVerifierInput;
7
+ invokeRemote: InvokeRemoteVerifierInput;
8
+ }
9
+ export declare class InvokeRemoteLinter extends BaseLinter<InvokeRemoteUsage, InvokeRemoteMatches, InvokeRemoteVerifierInput> {
10
+ private manifest;
11
+ constructor(environment: string, manifest: Manifest, logger: LintLogger);
12
+ bootstrap(): Promise<void>;
13
+ protected addLintCriteriaMatch(usage: InvokeRemoteUsage, filepath: string): void;
14
+ protected setupMatchesMap(filePath: string): void;
15
+ }
16
+ export {};
17
+ //# sourceMappingURL=invoke-remote-linter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"invoke-remote-linter.d.ts","sourceRoot":"","sources":["../../../../src/lint/linters/remote-linter/invoke-remote-linter.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,IAAI,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AAE7D,OAAO,UAAU,MAAM,mBAAmB,CAAC;AAC3C,OAAO,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AAEpD,OAAO,EAAqB,iBAAiB,EAAE,yBAAyB,EAAE,MAAM,2BAA2B,CAAC;AAI5G,UAAU,mBAAmB;IAC3B,CAAC,GAAG,EAAE,MAAM,GAAG,yBAAyB,CAAC;IACzC,YAAY,EAAE,yBAAyB,CAAC;CACzC;AAED,qBAAa,kBAAmB,SAAQ,UAAU,CAAC,iBAAiB,EAAE,mBAAmB,EAAE,yBAAyB,CAAC;IAGjH,OAAO,CAAC,QAAQ;gBADhB,WAAW,EAAE,MAAM,EACX,QAAQ,EAAE,QAAQ,EAC1B,MAAM,EAAE,UAAU;IAKd,SAAS,IAAI,OAAO,CAAC,IAAI,CAAC;IAOhC,SAAS,CAAC,oBAAoB,CAAC,KAAK,EAAE,iBAAiB,EAAE,QAAQ,EAAE,MAAM,GAAG,IAAI;IAUhF,SAAS,CAAC,eAAe,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI;CAQlD"}
@@ -0,0 +1,38 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.InvokeRemoteLinter = void 0;
4
+ const tslib_1 = require("tslib");
5
+ const base_linter_1 = tslib_1.__importDefault(require("../../base-linter"));
6
+ const invoke_remote_interface_1 = require("./invoke-remote-interface");
7
+ const invoke_remote_verifier_1 = require("./verifiers/invoke-remote-verifier");
8
+ const invoke_remote_call_visitor_1 = require("./visitors/invoke-remote-call-visitor");
9
+ class InvokeRemoteLinter extends base_linter_1.default {
10
+ constructor(environment, manifest, logger) {
11
+ super(environment, logger);
12
+ this.manifest = manifest;
13
+ }
14
+ async bootstrap() {
15
+ this.nodeVisitors = [new invoke_remote_call_visitor_1.InvokeRemoteCallVisitor()];
16
+ this.verifiers = {
17
+ invokeRemote: new invoke_remote_verifier_1.InvokeRemoteVerifier(this.environment, this.manifest)
18
+ };
19
+ }
20
+ addLintCriteriaMatch(usage, filepath) {
21
+ const criteriaMatches = this.matches.get(filepath);
22
+ if (usage.type === invoke_remote_interface_1.InvokeRemoteTypes.DIRECT_CALL || usage.type === invoke_remote_interface_1.InvokeRemoteTypes.MEMBER_CALL) {
23
+ criteriaMatches.invokeRemote.invokeRemoteCalls.push(usage);
24
+ }
25
+ else if (usage.type === invoke_remote_interface_1.InvokeRemoteTypes.IMPORT_LIST) {
26
+ criteriaMatches.invokeRemote.imports.push(...usage.imports);
27
+ }
28
+ }
29
+ setupMatchesMap(filePath) {
30
+ this.matches.set(filePath, {
31
+ invokeRemote: {
32
+ invokeRemoteCalls: [],
33
+ imports: []
34
+ }
35
+ });
36
+ }
37
+ }
38
+ exports.InvokeRemoteLinter = InvokeRemoteLinter;
@@ -0,0 +1,10 @@
1
+ import { LintClass, LintResultRule } from '../../../linter-interface';
2
+ import { BaseLintIssueVerifier, LintIssueVerifier } from '../../verifier-interface';
3
+ import { InvokeRemoteVerifierInput } from '../invoke-remote-interface';
4
+ export declare class InvokeRemoteVerifier extends BaseLintIssueVerifier implements LintIssueVerifier<InvokeRemoteVerifierInput> {
5
+ protected getLintClass(): LintClass;
6
+ process(input: InvokeRemoteVerifierInput): Promise<LintResultRule[]>;
7
+ private isValidCall;
8
+ private isRemoteKeyValid;
9
+ }
10
+ //# sourceMappingURL=invoke-remote-verifier.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"invoke-remote-verifier.d.ts","sourceRoot":"","sources":["../../../../../src/lint/linters/remote-linter/verifiers/invoke-remote-verifier.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,SAAS,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAEtE,OAAO,EAAE,qBAAqB,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AACpF,OAAO,EAIL,yBAAyB,EAC1B,MAAM,4BAA4B,CAAC;AAEpC,qBAAa,oBACX,SAAQ,qBACR,YAAW,iBAAiB,CAAC,yBAAyB,CAAC;IAEvD,SAAS,CAAC,YAAY,IAAI,SAAS;IAItB,OAAO,CAAC,KAAK,EAAE,yBAAyB,GAAG,OAAO,CAAC,cAAc,EAAE,CAAC;IAgBjF,OAAO,CAAC,WAAW;IAYnB,OAAO,CAAC,gBAAgB;CASzB"}
@@ -0,0 +1,40 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.InvokeRemoteVerifier = void 0;
4
+ const typescript_estree_1 = require("@typescript-eslint/typescript-estree");
5
+ const linter_interface_1 = require("../../../linter-interface");
6
+ const text_1 = require("../../../text");
7
+ const verifier_interface_1 = require("../../verifier-interface");
8
+ const invoke_remote_interface_1 = require("../invoke-remote-interface");
9
+ class InvokeRemoteVerifier extends verifier_interface_1.BaseLintIssueVerifier {
10
+ getLintClass() {
11
+ return linter_interface_1.LintClass.Error;
12
+ }
13
+ async process(input) {
14
+ return input.invokeRemoteCalls
15
+ .filter((call) => this.isValidCall(call, input.imports))
16
+ .filter((call) => !this.isRemoteKeyValid(call))
17
+ .map((call) => ({
18
+ class: this.getLintClass(),
19
+ column: call.column,
20
+ line: call.line,
21
+ message: text_1.messages.verifiers.invokeRemote.message(call.remoteKey),
22
+ reference: text_1.messages.verifiers.invokeRemote.reference
23
+ }));
24
+ }
25
+ isValidCall(call, imports) {
26
+ if (call.type === invoke_remote_interface_1.InvokeRemoteTypes.DIRECT_CALL) {
27
+ return imports.some((imp) => imp.type === typescript_estree_1.AST_NODE_TYPES.ImportSpecifier && call.calleeName === imp.alias);
28
+ }
29
+ return imports.some((imp) => (imp.type === typescript_estree_1.AST_NODE_TYPES.ImportDefaultSpecifier || imp.type === typescript_estree_1.AST_NODE_TYPES.ImportNamespaceSpecifier) &&
30
+ call.objectName === imp.alias);
31
+ }
32
+ isRemoteKeyValid(call) {
33
+ const remotes = this.manifest.remotes;
34
+ if (!remotes) {
35
+ return false;
36
+ }
37
+ return remotes.some((remote) => remote.key === call.remoteKey);
38
+ }
39
+ }
40
+ exports.InvokeRemoteVerifier = InvokeRemoteVerifier;
@@ -0,0 +1,9 @@
1
+ import { TSESTree } from '@typescript-eslint/typescript-estree';
2
+ import { NodeVisitor } from '../../node-visitor-interface';
3
+ import { InvokeRemoteUsage } from '../invoke-remote-interface';
4
+ export declare class InvokeRemoteCallVisitor implements NodeVisitor<InvokeRemoteUsage> {
5
+ visit(node: TSESTree.Node, parent: TSESTree.Node | undefined, callback: (fetchCall: InvokeRemoteUsage) => void): void;
6
+ private remoteKeyCanBeChecked;
7
+ private transformArgsToInvokeRemoteCall;
8
+ }
9
+ //# sourceMappingURL=invoke-remote-call-visitor.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"invoke-remote-call-visitor.d.ts","sourceRoot":"","sources":["../../../../../src/lint/linters/remote-linter/visitors/invoke-remote-call-visitor.ts"],"names":[],"mappings":"AAAA,OAAO,EAAkB,QAAQ,EAAE,MAAM,sCAAsC,CAAC;AAEhF,OAAO,EAAE,WAAW,EAAE,MAAM,8BAA8B,CAAC;AAC3D,OAAO,EAOL,iBAAiB,EAClB,MAAM,4BAA4B,CAAC;AAEpC,qBAAa,uBAAwB,YAAW,WAAW,CAAC,iBAAiB,CAAC;IACrE,KAAK,CACV,IAAI,EAAE,QAAQ,CAAC,IAAI,EACnB,MAAM,EAAE,QAAQ,CAAC,IAAI,GAAG,SAAS,EACjC,QAAQ,EAAE,CAAC,SAAS,EAAE,iBAAiB,KAAK,IAAI,GAC/C,IAAI;IA0FP,OAAO,CAAC,qBAAqB;IAU7B,OAAO,CAAC,+BAA+B,CAIpC;CACJ"}
@@ -0,0 +1,66 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.InvokeRemoteCallVisitor = void 0;
4
+ const typescript_estree_1 = require("@typescript-eslint/typescript-estree");
5
+ const invoke_remote_interface_1 = require("../invoke-remote-interface");
6
+ class InvokeRemoteCallVisitor {
7
+ constructor() {
8
+ this.transformArgsToInvokeRemoteCall = (remoteKeyNode) => ({
9
+ remoteKey: remoteKeyNode.value,
10
+ line: remoteKeyNode.loc.start.line,
11
+ column: remoteKeyNode.loc.start.column
12
+ });
13
+ }
14
+ visit(node, parent, callback) {
15
+ switch (node.type) {
16
+ case typescript_estree_1.AST_NODE_TYPES.ImportDeclaration:
17
+ if (node.source.value === invoke_remote_interface_1.INVOKE_REMOTE_PACKAGE_NAME) {
18
+ const imports = node.specifiers
19
+ .filter((spec) => spec.type === typescript_estree_1.AST_NODE_TYPES.ImportDefaultSpecifier ||
20
+ spec.type === typescript_estree_1.AST_NODE_TYPES.ImportNamespaceSpecifier ||
21
+ (spec.type === typescript_estree_1.AST_NODE_TYPES.ImportSpecifier &&
22
+ spec.imported.name === invoke_remote_interface_1.INVOKE_REMOTE_FUNCTION_NAME))
23
+ .map((spec) => ({
24
+ type: spec.type,
25
+ alias: spec.local.name,
26
+ column: spec.local.loc.start.column,
27
+ line: spec.local.loc.start.line
28
+ }));
29
+ callback({
30
+ type: invoke_remote_interface_1.InvokeRemoteTypes.IMPORT_LIST,
31
+ imports,
32
+ line: 0,
33
+ column: 0
34
+ });
35
+ }
36
+ break;
37
+ case typescript_estree_1.AST_NODE_TYPES.CallExpression:
38
+ if (node.callee.type === typescript_estree_1.AST_NODE_TYPES.Identifier) {
39
+ const [remoteKeyNode] = node.arguments;
40
+ if (this.remoteKeyCanBeChecked(remoteKeyNode)) {
41
+ const invokeRemoteCall = Object.assign(Object.assign({}, this.transformArgsToInvokeRemoteCall(remoteKeyNode)), { type: invoke_remote_interface_1.InvokeRemoteTypes.DIRECT_CALL, calleeName: node.callee.name });
42
+ callback(invokeRemoteCall);
43
+ }
44
+ }
45
+ break;
46
+ case typescript_estree_1.AST_NODE_TYPES.MemberExpression:
47
+ if (node.property.type === typescript_estree_1.AST_NODE_TYPES.Identifier &&
48
+ node.object.type === typescript_estree_1.AST_NODE_TYPES.Identifier &&
49
+ node.property.name === invoke_remote_interface_1.INVOKE_REMOTE_FUNCTION_NAME &&
50
+ (parent === null || parent === void 0 ? void 0 : parent.type) === typescript_estree_1.AST_NODE_TYPES.CallExpression) {
51
+ const [remoteKeyNode] = parent.arguments;
52
+ if (this.remoteKeyCanBeChecked(remoteKeyNode)) {
53
+ const invokeRemoteMemberCall = Object.assign(Object.assign({}, this.transformArgsToInvokeRemoteCall(remoteKeyNode)), { type: invoke_remote_interface_1.InvokeRemoteTypes.MEMBER_CALL, objectName: node.object.name });
54
+ callback(invokeRemoteMemberCall);
55
+ }
56
+ }
57
+ break;
58
+ }
59
+ }
60
+ remoteKeyCanBeChecked(remoteKeyNode) {
61
+ return ((remoteKeyNode === null || remoteKeyNode === void 0 ? void 0 : remoteKeyNode.type) === typescript_estree_1.AST_NODE_TYPES.Literal &&
62
+ typeof (remoteKeyNode === null || remoteKeyNode === void 0 ? void 0 : remoteKeyNode.value) === 'string' &&
63
+ remoteKeyNode.value.trim() !== '');
64
+ }
65
+ }
66
+ exports.InvokeRemoteCallVisitor = InvokeRemoteCallVisitor;
@@ -17,6 +17,10 @@ export declare const messages: {
17
17
  message: (url: string) => string;
18
18
  reference: string;
19
19
  };
20
+ invokeRemote: {
21
+ message: (remoteKey: string) => string;
22
+ reference: string;
23
+ };
20
24
  handler: {
21
25
  message: (method: string, key: string) => string;
22
26
  reference: string;
@@ -1 +1 @@
1
- {"version":3,"file":"messages.d.ts","sourceRoot":"","sources":["../../../src/lint/text/messages.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,QAAQ;;;+BAGI,MAAM,UAAU,MAAM,SAAS,MAAM,KAAG,MAAM;;;;2BAKlD,MAAM;;;;2BAIN,MAAM;2BAER,MAAM;;;;2BAKJ,MAAM;;;;8BAKH,MAAM,OAAO,MAAM;;;;+BAKlB,MAAM,UAAU,MAAM,QAAQ,MAAM,GAAG,SAAS,SAAS,MAAM;;;;6BAKjE,MAAM;;;;+BAIJ,MAAM,QAAQ,MAAM,SAAS,MAAM;;;;CAK3D,CAAC"}
1
+ {"version":3,"file":"messages.d.ts","sourceRoot":"","sources":["../../../src/lint/text/messages.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,QAAQ;;;+BAGI,MAAM,UAAU,MAAM,SAAS,MAAM,KAAG,MAAM;;;;2BAKlD,MAAM;;;;2BAKN,MAAM;2BAER,MAAM;;;;2BAKJ,MAAM;;;;iCAKA,MAAM;;;;8BAKT,MAAM,OAAO,MAAM;;;;+BAKlB,MAAM,UAAU,MAAM,QAAQ,MAAM,GAAG,SAAS,SAAS,MAAM;;;;6BAKjE,MAAM;;;;+BAIJ,MAAM,QAAQ,MAAM,SAAS,MAAM;;;;CAK3D,CAAC"}
@@ -8,20 +8,24 @@ exports.messages = {
8
8
  reference: 'permission-scope-required'
9
9
  },
10
10
  externalFetch: {
11
- message: (url) => `The domain ${url} is not included in the external permissions of your app manifest`,
11
+ message: (url) => `The domain ${url} is not included in the "permissions.external.images" section of your app's manifest.yml file`,
12
12
  reference: 'egress-permission-required'
13
13
  },
14
14
  dynamicPropertiesIcon: {
15
- message: (url) => `The domain ${url} is not included in the external images permissions of your app manifest`,
16
- warning: () => `When using dynamic content properties along with icons, make sure to add the icon URL into the external images permissions of your app manifest. Otherwise, the icon will not be rendered.`,
15
+ message: (url) => `The domain ${url} is not included in the "permissions.external.images" section of your app's manifest.yml file`,
16
+ warning: () => `When using dynamic content properties along with icons, make sure to add the icon URL into the "permissions.external.images" section of your app's manifest.yml file. Otherwise, the icon will not be rendered.`,
17
17
  reference: 'egress-permission-required'
18
18
  },
19
19
  imageUrl: {
20
- message: (url) => `The domain ${url} is not included in the external images permissions of your app manifest`,
20
+ message: (url) => `The domain ${url} is not included in the "permissions.external.images" section of your app's manifest.yml file`,
21
21
  reference: 'egress-permission-required'
22
22
  },
23
+ invokeRemote: {
24
+ message: (remoteKey) => `The remote key "${remoteKey}" does not exist in the "remotes" section of your app's manifest.yml file`,
25
+ reference: 'missing-remote-key'
26
+ },
23
27
  handler: {
24
- message: (method, key) => `Cannot find exported function '${method}', which is required by module '${key}' handler defined in the manifest`,
28
+ message: (method, key) => `Cannot find exported function "${method}", which is required by module "${key}" handler defined in your app's manifest.yml file`,
25
29
  reference: 'valid-module-required'
26
30
  },
27
31
  product: {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@forge/lint",
3
- "version": "5.0.4-next.0",
3
+ "version": "5.1.0-next.2",
4
4
  "description": "Linting for forge apps",
5
5
  "main": "out/index.js",
6
6
  "license": "UNLICENSED",
@@ -14,12 +14,13 @@
14
14
  "@types/array.prototype.flatmap": "^1.2.6",
15
15
  "@types/cross-spawn": "^6.0.6",
16
16
  "@types/eslint": "8.56.2",
17
- "@types/node-fetch": "^2.6.11"
17
+ "@types/node-fetch": "^2.6.11",
18
+ "eslint-plugin-import": "^2.29.1"
18
19
  },
19
20
  "dependencies": {
20
- "@forge/cli-shared": "4.2.0-next.0",
21
+ "@forge/cli-shared": "4.2.0-next.2",
21
22
  "@forge/egress": "1.2.13",
22
- "@forge/manifest": "7.2.1",
23
+ "@forge/manifest": "7.2.2-next.0",
23
24
  "@typescript-eslint/typescript-estree": "^5.62.0",
24
25
  "array.prototype.flatmap": "^1.3.2",
25
26
  "atlassian-openapi": "^1.0.18",