@forge/lint
6.0.2-next.5-experimental-a1600ff6.0.2-next.3-experimental-fda9df6
+
Added (3 files)
~
Modified (8 files)
Index: package/out/lint/lint.js
===================================================================
--- package/out/lint/lint.js
+++ package/out/lint/lint.js
@@ -22,24 +22,29 @@
const llm_module_linter_1 = require("./linters/llm-module-linter/llm-module-linter");
const deprecated_api_module_linter_1 = require("./linters/deprecated-api-module-linter/deprecated-api-module-linter");
const app_managed_permissions_sdk_linter_1 = require("./linters/app-managed-permissions-sdk-linter/app-managed-permissions-sdk-linter");
const function_timeout_linter_1 = require("./linters/function-timeout-linter/function-timeout-linter");
+const server_side_linter_1 = require("./linters/server-side-linter/server-side-linter");
const reportLintResults = (logger, lintResults, showSummary = true) => {
- let numErrors = 0, numWarnings = 0;
+ let numErrors = 0, numWarnings = 0, numApprovals = 0;
let noProblemsFound = true;
if (lintResults.length) {
lintResults.forEach((lintResult) => {
if (lintResult.size()) {
noProblemsFound = false;
numErrors += lintResult.errors.length;
numWarnings += lintResult.warnings.length;
+ numApprovals += lintResult.approvals.length;
logger.info(cli_shared_1.Text.lint.filename(path_1.default.resolve(lintResult.file)));
lintResult.errors.forEach(({ line, column, message, reference }) => {
logger.info(cli_shared_1.Text.lint.error(line, column, message, reference));
});
lintResult.warnings.forEach(({ line, column, message, reference }) => {
logger.info(cli_shared_1.Text.lint.warning(line, column, message, reference));
});
+ lintResult.approvals.forEach(({ line, column, message, reference }) => {
+ logger.info(cli_shared_1.Text.lint.approval(line, column, message, reference));
+ });
}
});
}
if (noProblemsFound) {
@@ -50,30 +55,34 @@
const resultsWithFixers = lintResults.filter((result) => result.hasFixer());
const numFixableErrors = resultsWithFixers.reduce((count, result) => count + result.errors.length, 0);
const numFixableWarnings = resultsWithFixers.reduce((count, result) => count + result.warnings.length, 0);
if (showSummary) {
- logger.info(cli_shared_1.Text.lint.summary(numErrors, numWarnings, numFixableErrors, numFixableWarnings));
+ logger.info(cli_shared_1.Text.lint.summary(numErrors, numWarnings, numApprovals, numFixableErrors, numFixableWarnings));
if (numFixableErrors + numFixableWarnings > 0) {
logger.info(cli_shared_1.Text.lint.fixSummary(numErrors, numFixableErrors, numFixableWarnings));
}
else if (numErrors + numWarnings === 1) {
logger.info(cli_shared_1.Text.lint.noFixableProblem);
}
+ else if (numApprovals > 0) {
+ logger.info(cli_shared_1.Text.lint.noFixableProblem);
+ }
else {
logger.info(cli_shared_1.Text.lint.noFixableProblems);
}
}
- if (numErrors) {
+ if (numErrors || numApprovals) {
process.exitCode = 1;
}
}
};
exports.reportLintResults = reportLintResults;
const problemCount = (lintResults) => {
return lintResults.reduce((prev, curr) => ({
errors: prev.errors + curr.errors.length,
- warnings: prev.warnings + curr.warnings.length
- }), { errors: 0, warnings: 0 });
+ warnings: prev.warnings + curr.warnings.length,
+ approvals: prev.approvals + curr.approvals.length
+ }), { errors: 0, warnings: 0, approvals: 0 });
};
exports.problemCount = problemCount;
const parseSourceFile = async (filepath, parser, readFilePromise = (0, util_1.promisify)(fs_1.default.readFile)) => {
const code = await readFilePromise(filepath, { encoding: 'utf-8' });
@@ -83,10 +92,11 @@
filepath
};
};
exports.parseSourceFile = parseSourceFile;
-const lint = async (filesToLint, manifest, environment, logger, statsigService, parseFunction = exports.parseSourceFile, linters = [
+const getDefaultLinters = async (manifest, environment, logger, statsigService, graphqlClient, approveRules) => [
new permission_linter_1.PermissionLinter(environment, manifest, logger),
+ await server_side_linter_1.ServerSideLinter.instance(environment, manifest, graphqlClient, logger, approveRules),
new permissions_manifest_linter_1.PermissionsManifestLinter(logger, statsigService),
new agent_product_context_permissions_manifest_linter_1.AgentProductContextPermissionsManifestLinter(logger, statsigService),
new deprecated_csp_permissions_manifest_linter_1.DeprecatedCspPermissionsManifestLinter(logger, statsigService),
new full_manifest_linter_1.FullManifestLinter(logger, statsigService),
@@ -99,9 +109,13 @@
new deprecated_api_module_linter_1.DeprecatedApiModuleLinter(environment, manifest, logger),
new deprecated_egress_permissions_manifest_linter_1.DeprecatedEgressPermissionsManifestLinter(logger, statsigService),
new app_managed_permissions_sdk_linter_1.AppManagedPermissionsSdkLinter(manifest, logger),
new function_timeout_linter_1.FunctionTimeoutLinter(manifest, logger)
-]) => {
+];
+const lint = async (filesToLint, manifest, environment, logger, statsigService, graphqlClient, approveRules, parseFunction = exports.parseSourceFile, lintersOverride = []) => {
+ const linters = lintersOverride.length > 0
+ ? lintersOverride
+ : await getDefaultLinters(manifest, environment, logger, statsigService, graphqlClient, approveRules);
const { include, exclude } = await (0, cli_shared_1.listTSConfigIncludeExclude)(new cli_shared_1.FileSystemReader());
const tsInclude = new Set(include);
const tsExclude = new Set(exclude);
try {
@@ -125,8 +139,9 @@
return results.map((result) => {
const comparator = (a, b) => a.line === b.line ? a.column - b.column : a.line - b.line;
result.errors = result.errors.sort(comparator);
result.warnings = result.warnings.sort(comparator);
+ result.approvals = result.approvals.sort(comparator);
return result;
});
}
catch (e) { Index: package/out/lint/linter-interface.js
===================================================================
--- package/out/lint/linter-interface.js
+++ package/out/lint/linter-interface.js
@@ -4,14 +4,16 @@
var LintClass;
(function (LintClass) {
LintClass["Error"] = "error";
LintClass["Warning"] = "warning";
+ LintClass["Approval"] = "approval";
})(LintClass || (exports.LintClass = LintClass = {}));
class LintResult {
file;
fixer;
errors = [];
warnings = [];
+ approvals = [];
constructor(file, fixer) {
this.file = file;
this.fixer = fixer;
}
@@ -19,8 +21,11 @@
switch (rule.class) {
case LintClass.Error:
this.errors.push(rule);
break;
+ case LintClass.Approval:
+ this.approvals.push(rule);
+ break;
default:
this.warnings.push(rule);
break;
}
@@ -28,9 +33,9 @@
batchAdd(...rules) {
rules.forEach(this.add, this);
}
size() {
- return this.errors.length + this.warnings.length;
+ return this.errors.length + this.warnings.length + this.approvals.length;
}
hasFixer() {
return !!this.fixer;
} Index: package/package.json
===================================================================
--- package/package.json
+++ package/package.json
@@ -1,7 +1,7 @@
{
"name": "@forge/lint",
- "version": "6.0.2-next.5-experimental-a1600ff",
+ "version": "6.0.2-next.3-experimental-fda9df6",
"description": "Linting for forge apps",
"main": "out/index.js",
"license": "SEE LICENSE IN LICENSE.txt",
"scripts": {
@@ -10,25 +10,27 @@
"clean": "rm -rf ./out && rm -f tsconfig.tsbuildinfo"
},
"devDependencies": {
"@atlassian/xen-test-util": "^4.2.0",
- "@forge/api": "^8.0.2-next.0-experimental-a1600ff",
+ "@forge/api": "^8.0.2-next.0-experimental-fda9df6",
"@types/array.prototype.flatmap": "^1.2.6",
"@types/cross-spawn": "^6.0.6",
"@types/eslint": "8.56.12",
"@types/node-fetch": "^2.6.12",
"eslint-plugin-import": "^2.29.1"
},
"dependencies": {
- "@forge/cli-shared": "9.2.0-next.5-experimental-a1600ff",
- "@forge/csp": "6.1.0-experimental-a1600ff",
+ "@forge/cli-shared": "9.2.0-next.3-experimental-fda9df6",
+ "@forge/csp": "6.1.0-experimental-fda9df6",
"@forge/egress": "3.0.0",
- "@forge/manifest": "13.1.1-next.2-experimental-a1600ff",
+ "@forge/manifest": "13.1.1-next.2-experimental-fda9df6",
"@typescript-eslint/typescript-estree": "^5.62.0",
+ "archiver": "^8.0.0",
"array.prototype.flatmap": "^1.3.3",
"@atlassian/atlassian-openapi": "^1.0.6",
"cross-spawn": "^7.0.6",
"node-fetch": "2.7.0",
+ "tmp": "^0.2.3",
"typescript": "5.9.2"
},
"publishConfig": {
"registry": "https://packages.atlassian.com/api/npm/npm-public/" Index: package/out/lint/lint.d.ts.map
===================================================================
--- package/out/lint/lint.d.ts.map
+++ package/out/lint/lint.d.ts.map
@@ -1,1 +1,1 @@
-{"version":3,"file":"lint.d.ts","sourceRoot":"","sources":["../../src/lint/lint.ts"],"names":[],"mappings":"AAAA,OAAO,EAOL,cAAc,EACf,MAAM,mBAAmB,CAAC;AAC3B,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;AAkBxG,MAAM,WAAW,YAAY;IAC3B,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,eAAO,MAAM,iBAAiB,GAAI,QAAQ,UAAU,EAAE,aAAa,UAAU,EAAE,EAAE,qBAAkB,KAAG,IA+CrG,CAAC;AAEF,eAAO,MAAM,YAAY,GAAI,aAAa,UAAU,EAAE,KAAG,YAQxD,CAAC;AAEF,eAAO,MAAM,eAAe,GAC1B,UAAU,MAAM,EAChB,QAAQ,OAAO,QAAQ,EACvB,kBAAiB,OAAO,EAAE,CAAC,QAAQ,CAAC,aAAsC,KACzE,OAAO,CAAC,SAAS,CAOnB,CAAC;AAEF,eAAO,MAAM,IAAI,GACf,aAAa,MAAM,EAAE,EACrB,UAAU,QAAQ,EAClB,aAAa,MAAM,EACnB,QAAQ,UAAU,EAClB,gBAAgB,cAAc,EAC9B,2BAlBU,MAAM,UACR,OAAO,QAAQ,oBACN,OAAO,EAAE,CAAC,QAAQ,CAAC,aAAa,KAChD,OAAO,CAAC,SAAS,CAea,EAC/B,UAAS,eAAe,EAgBvB,KACA,OAAO,CAAC,UAAU,EAAE,CAyCtB,CAAC;AAwBF,eAAO,MAAM,QAAQ,GACnB,QAAQ,UAAU,EAClB,gBAAgB,cAAc,EAC9B,SAAQ,eAAiE,KACxE,OAAO,CAAC,UAAU,EAAE,CAGtB,CAAC"}
\ No newline at end of file
+{"version":3,"file":"lint.d.ts","sourceRoot":"","sources":["../../src/lint/lint.ts"],"names":[],"mappings":"AAAA,OAAO,EAOL,cAAc,EACd,aAAa,EACd,MAAM,mBAAmB,CAAC;AAC3B,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;AAmBxG,MAAM,WAAW,YAAY;IAC3B,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,eAAO,MAAM,iBAAiB,GAAI,QAAQ,UAAU,EAAE,aAAa,UAAU,EAAE,EAAE,qBAAkB,KAAG,IAuDrG,CAAC;AAEF,eAAO,MAAM,YAAY,GAAI,aAAa,UAAU,EAAE,KAAG,YASxD,CAAC;AAEF,eAAO,MAAM,eAAe,GAC1B,UAAU,MAAM,EAChB,QAAQ,OAAO,QAAQ,EACvB,kBAAiB,OAAO,EAAE,CAAC,QAAQ,CAAC,aAAsC,KACzE,OAAO,CAAC,SAAS,CAOnB,CAAC;AA4BF,eAAO,MAAM,IAAI,GACf,aAAa,MAAM,EAAE,EACrB,UAAU,QAAQ,EAClB,aAAa,MAAM,EACnB,QAAQ,UAAU,EAClB,gBAAgB,cAAc,EAC9B,eAAe,aAAa,EAC5B,eAAe,MAAM,EAAE,EACvB,2BA9CU,MAAM,UACR,OAAO,QAAQ,oBACN,OAAO,EAAE,CAAC,QAAQ,CAAC,aAAa,KAChD,OAAO,CAAC,SAAS,CA2Ca,EAC/B,kBAAiB,eAAe,EAAO,KACtC,OAAO,CAAC,UAAU,EAAE,CA+CtB,CAAC;AAwBF,eAAO,MAAM,QAAQ,GACnB,QAAQ,UAAU,EAClB,gBAAgB,cAAc,EAC9B,SAAQ,eAAiE,KACxE,OAAO,CAAC,UAAU,EAAE,CAGtB,CAAC"}
\ No newline at end of file Index: package/out/lint/linter-interface.d.ts.map
===================================================================
--- package/out/lint/linter-interface.d.ts.map
+++ package/out/lint/linter-interface.d.ts.map
@@ -1,1 +1,1 @@
-{"version":3,"file":"linter-interface.d.ts","sourceRoot":"","sources":["../../src/lint/linter-interface.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,UAAU,CAAC;AAE1C,OAAO,EAAE,UAAU,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC;AAEvD,oBAAY,SAAS;IACnB,KAAK,UAAU;IACf,OAAO,YAAY;CACpB;AAED,MAAM,MAAM,UAAU,GAAG,IAAI,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;AAE9C,MAAM,MAAM,SAAS,GAAG,CACtB,MAAM,EAAE,cAAc,EAAE,EACxB,QAAQ,EAAE,cAAc,EAAE,EAC1B,KAAK,EAAE,YAAY,KAChB,OAAO,CAAC,YAAY,CAAC,CAAC;AAE3B,MAAM,WAAW,YAAY;IAC3B,WAAW,EAAE,MAAM,CAAC;IACpB,aAAa,EAAE,MAAM,CAAC;IACtB,UAAU,EAAE,UAAU,CAAC;CACxB;AAED,qBAAa,UAAU;IAKZ,IAAI,EAAE,MAAM;IACnB,OAAO,CAAC,KAAK,CAAC;IALT,MAAM,EAAE,cAAc,EAAE,CAAM;IAC9B,QAAQ,EAAE,cAAc,EAAE,CAAM;gBAG9B,IAAI,EAAE,MAAM,EACX,KAAK,CAAC,EAAE,SAAS,YAAA;IAGpB,GAAG,CAAC,IAAI,EAAE,cAAc,GAAG,IAAI;IAW/B,QAAQ,CAAC,GAAG,KAAK,EAAE,cAAc,EAAE,GAAG,IAAI;IAI1C,IAAI,IAAI,MAAM;IAId,QAAQ,IAAI,OAAO;IAIb,QAAQ,CAAC,KAAK,EAAE,YAAY,GAAG,OAAO,CAAC,YAAY,CAAC;CAMlE;AAED,MAAM,WAAW,cAAc;IAC7B,KAAK,EAAE,SAAS,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;CAChC;AAED,MAAM,WAAW,SAAS;IACxB,GAAG,EAAE,cAAc,GAAG,IAAI,CAAC;IAC3B,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,eAAe;IAC9B,SAAS,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IAC3B,YAAY,CAAC,IAAI,CAAC,EAAE,SAAS,EAAE,GAAG,OAAO,CAAC,UAAU,EAAE,CAAC,CAAC;CACzD;AAED,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;CAChB"}
\ No newline at end of file
+{"version":3,"file":"linter-interface.d.ts","sourceRoot":"","sources":["../../src/lint/linter-interface.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,UAAU,CAAC;AAE1C,OAAO,EAAE,UAAU,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC;AAEvD,oBAAY,SAAS;IACnB,KAAK,UAAU;IACf,OAAO,YAAY;IACnB,QAAQ,aAAa;CACtB;AAED,MAAM,MAAM,UAAU,GAAG,IAAI,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;AAE9C,MAAM,MAAM,SAAS,GAAG,CACtB,MAAM,EAAE,cAAc,EAAE,EACxB,QAAQ,EAAE,cAAc,EAAE,EAC1B,KAAK,EAAE,YAAY,KAChB,OAAO,CAAC,YAAY,CAAC,CAAC;AAE3B,MAAM,WAAW,YAAY;IAC3B,WAAW,EAAE,MAAM,CAAC;IACpB,aAAa,EAAE,MAAM,CAAC;IACtB,UAAU,EAAE,UAAU,CAAC;CACxB;AAED,qBAAa,UAAU;IAMZ,IAAI,EAAE,MAAM;IACnB,OAAO,CAAC,KAAK,CAAC;IANT,MAAM,EAAE,cAAc,EAAE,CAAM;IAC9B,QAAQ,EAAE,cAAc,EAAE,CAAM;IAChC,SAAS,EAAE,cAAc,EAAE,CAAM;gBAG/B,IAAI,EAAE,MAAM,EACX,KAAK,CAAC,EAAE,SAAS,YAAA;IAGpB,GAAG,CAAC,IAAI,EAAE,cAAc,GAAG,IAAI;IAc/B,QAAQ,CAAC,GAAG,KAAK,EAAE,cAAc,EAAE,GAAG,IAAI;IAI1C,IAAI,IAAI,MAAM;IAId,QAAQ,IAAI,OAAO;IAIb,QAAQ,CAAC,KAAK,EAAE,YAAY,GAAG,OAAO,CAAC,YAAY,CAAC;CAMlE;AAED,MAAM,WAAW,cAAc;IAC7B,KAAK,EAAE,SAAS,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;CAChC;AAED,MAAM,WAAW,SAAS;IACxB,GAAG,EAAE,cAAc,GAAG,IAAI,CAAC;IAC3B,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,eAAe;IAC9B,SAAS,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IAC3B,YAAY,CAAC,IAAI,CAAC,EAAE,SAAS,EAAE,GAAG,OAAO,CAAC,UAAU,EAAE,CAAC,CAAC;CACzD;AAED,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;CAChB"}
\ No newline at end of file File too large for inline diff
Index: package/out/lint/lint.d.ts
===================================================================
--- package/out/lint/lint.d.ts
+++ package/out/lint/lint.d.ts
@@ -1,15 +1,16 @@
-import { StatsigService } from '@forge/cli-shared';
+import { StatsigService, GraphQLClient } from '@forge/cli-shared';
import { ManifestSchema as Manifest } from '@forge/manifest';
import fs from 'fs';
import { tsParser } from '../parse';
import { LinterInterface, LintInput, LintLogger, LintResult } from './linter-interface';
export interface ProblemCount {
errors: number;
warnings: number;
+ approvals: number;
}
export declare const reportLintResults: (logger: LintLogger, lintResults: LintResult[], showSummary?: boolean) => void;
export declare const problemCount: (lintResults: LintResult[]) => ProblemCount;
export declare const parseSourceFile: (filepath: string, parser: typeof tsParser, readFilePromise?: typeof fs.readFile.__promisify__) => Promise<LintInput>;
-export declare const lint: (filesToLint: string[], manifest: Manifest, environment: string, logger: LintLogger, statsigService: StatsigService, parseFunction?: (filepath: string, parser: typeof tsParser, readFilePromise?: typeof fs.readFile.__promisify__) => Promise<LintInput>, linters?: LinterInterface[]) => Promise<LintResult[]>;
+export declare const lint: (filesToLint: string[], manifest: Manifest, environment: string, logger: LintLogger, statsigService: StatsigService, graphqlClient: GraphQLClient, approveRules?: string[], parseFunction?: (filepath: string, parser: typeof tsParser, readFilePromise?: typeof fs.readFile.__promisify__) => Promise<LintInput>, lintersOverride?: LinterInterface[]) => Promise<LintResult[]>;
export declare const litelint: (logger: LintLogger, statsigService: StatsigService, linter?: LinterInterface) => Promise<LintResult[]>;
//# sourceMappingURL=lint.d.ts.map
\ No newline at end of file Index: package/out/lint/linter-interface.d.ts
===================================================================
--- package/out/lint/linter-interface.d.ts
+++ package/out/lint/linter-interface.d.ts
@@ -1,9 +1,10 @@
import { ASTParseResult } from '../parse';
import { ConfigFile, Logger } from '@forge/cli-shared';
export declare enum LintClass {
Error = "error",
- Warning = "warning"
+ Warning = "warning",
+ Approval = "approval"
}
export type LintLogger = Pick<Logger, 'info'>;
export type LintFixer = (errors: LintResultRule[], warnings: LintResultRule[], state: LintFixState) => Promise<LintFixState>;
export interface LintFixState {
@@ -15,8 +16,9 @@
file: string;
private fixer?;
errors: LintResultRule[];
warnings: LintResultRule[];
+ approvals: LintResultRule[];
constructor(file: string, fixer?: LintFixer | undefined);
add(rule: LintResultRule): void;
batchAdd(...rules: LintResultRule[]): void;
size(): number;