@forge/lint
5.16.3-next.75.17.0-next.8
out/lint/linters/function-timeout-linter/function-timeout-linter.js+
out/lint/linters/function-timeout-linter/function-timeout-linter.jsNew file+103
Index: package/out/lint/linters/function-timeout-linter/function-timeout-linter.js
===================================================================
--- package/out/lint/linters/function-timeout-linter/function-timeout-linter.js
+++ package/out/lint/linters/function-timeout-linter/function-timeout-linter.js
@@ -0,0 +1,103 @@
+"use strict";
+Object.defineProperty(exports, "__esModule", { value: true });
+exports.FunctionTimeoutLinter = exports.LONG_RUNNING_MODULE_TYPES = void 0;
+const manifest_1 = require("@forge/manifest");
+const abstract_linter_1 = require("../../abstract-linter");
+const linter_interface_1 = require("../../linter-interface");
+const text_1 = require("../../text");
+exports.LONG_RUNNING_MODULE_TYPES = new Set(['consumer', 'scheduledTrigger']);
+const MAX_TIMEOUT_SECONDS = 25;
+const WEBTRIGGER_MAX_TIMEOUT_SECONDS = 55;
+const LONG_RUNNING_MAX_TIMEOUT_SECONDS = 900;
+const hasDirectFunction = (m) => typeof m.key === 'string' && typeof m.function === 'string';
+const hasResolverFunction = (m) => typeof m.key === 'string' &&
+ typeof m.resolver === 'object' &&
+ m.resolver !== null &&
+ 'function' in m.resolver &&
+ typeof m.resolver.function === 'string';
+function collectAllFunctionRefs(modules) {
+ const refs = new Map();
+ const addRef = (functionKey, moduleKey, moduleType) => {
+ const existing = refs.get(functionKey) ?? [];
+ existing.push({ moduleKey, moduleType });
+ refs.set(functionKey, existing);
+ };
+ for (const [moduleType, moduleArray] of Object.entries(modules)) {
+ if (!Array.isArray(moduleArray))
+ continue;
+ for (const m of moduleArray) {
+ if (hasDirectFunction(m))
+ addRef(m.function, m.key, moduleType);
+ if (hasResolverFunction(m))
+ addRef(m.resolver.function, m.key, moduleType);
+ }
+ }
+ return refs;
+}
+class FunctionTimeoutLinter extends abstract_linter_1.AbstractLinter {
+ manifest;
+ constructor(manifest, logger) {
+ super(logger);
+ this.manifest = manifest;
+ }
+ async bootstrap() {
+ }
+ async batchExecuteImpl() {
+ const lintResult = new linter_interface_1.LintResult(manifest_1.MANIFEST_FILE);
+ const modules = this.manifest.modules;
+ if (modules) {
+ lintResult.batchAdd(...this.findTimeoutViolations(modules));
+ }
+ return [lintResult];
+ }
+ getTimeoutLimit(ref) {
+ if (exports.LONG_RUNNING_MODULE_TYPES.has(ref.moduleType))
+ return LONG_RUNNING_MAX_TIMEOUT_SECONDS;
+ if (ref.moduleType === 'webtrigger')
+ return WEBTRIGGER_MAX_TIMEOUT_SECONDS;
+ return MAX_TIMEOUT_SECONDS;
+ }
+ makeError(msg) {
+ return { class: linter_interface_1.LintClass.Error, ...msg, line: 0, column: 0 };
+ }
+ getSharedViolationMessage(functionKey, ref) {
+ return {
+ message: text_1.messages.verifiers.functionTimeout.shared.message(functionKey, ref.moduleKey, ref.moduleType),
+ reference: text_1.messages.verifiers.functionTimeout.shared.reference
+ };
+ }
+ getExceededViolationMessage(functionKey, timeout, ref) {
+ return {
+ message: text_1.messages.verifiers.functionTimeout.exceeded.message(functionKey, timeout, ref.moduleKey, ref.moduleType),
+ reference: text_1.messages.verifiers.functionTimeout.exceeded.reference
+ };
+ }
+ findViolations(functionKey, timeout, refs) {
+ const consumerShared = refs.some((r) => exports.LONG_RUNNING_MODULE_TYPES.has(r.moduleType));
+ return refs
+ .filter((r) => {
+ const limit = this.getTimeoutLimit(r);
+ if (limit === LONG_RUNNING_MAX_TIMEOUT_SECONDS)
+ return false;
+ if (!consumerShared)
+ return true;
+ return timeout > limit;
+ })
+ .map((r) => this.makeError(consumerShared
+ ? this.getSharedViolationMessage(functionKey, r)
+ : this.getExceededViolationMessage(functionKey, timeout, r)));
+ }
+ findTimeoutViolations(modules) {
+ const allFunctionRefs = collectAllFunctionRefs(modules);
+ const functionTimeouts = new Map((modules.function ?? []).map((f) => [f.key, f.timeoutSeconds]));
+ const errors = [];
+ for (const [functionKey, refs] of allFunctionRefs) {
+ const timeout = functionTimeouts.get(functionKey);
+ if (timeout === undefined)
+ continue;
+ errors.push(...this.findViolations(functionKey, timeout, refs));
+ }
+ return errors;
+ }
+}
+exports.FunctionTimeoutLinter = FunctionTimeoutLinter;