Repository: stoplightio/spectral
Pull request #1051 (2020-04-01 14:13:18)

chore: migrate typed-enum function
Closes https://github.com/stoplightio/spectral/issues/924

**Checklist**

- [x] Tests added / updated
- [x] Docs added / updated

**Does this PR introduce a breaking change?**

- [ ] Yes
- [x] No





Patch:
diff --git a/src/functions/index.ts b/src/functions/index.ts
index 8ae274d7..8544be8e 100644
--- a/src/functions/index.ts
+++ b/src/functions/index.ts
@@ -7,7 +7,6 @@ import { pattern } from './pattern';
 import { schema } from './schema';
 import { schemaPath } from './schema-path';
 import { truthy } from './truthy';
-import { typedEnum } from './typedEnum';
 import { undefined } from './undefined';
 import { unreferencedReusableObject } from './unreferencedReusableObject';
 import { xor } from './xor';
@@ -25,7 +24,6 @@ export const functions = {
   undefined,
   xor,
   unreferencedReusableObject,
-  typedEnum,
 };
 
 export type CoreFunctions = typeof functions;
diff --git a/src/functions/typedEnum.ts b/src/rulesets/oas/functions/typedEnum.ts
similarity index 54%
rename from src/functions/typedEnum.ts
rename to src/rulesets/oas/functions/typedEnum.ts
index 4fee0707..397a3d9e 100644
--- a/src/functions/typedEnum.ts
+++ b/src/rulesets/oas/functions/typedEnum.ts
@@ -1,10 +1,11 @@
-import { IFunction, IFunctionResult, IRule, RuleFunction } from '../types';
-import { schema } from './schema';
+import { IFunction, IFunctionContext } from '../../../types';
 
-export type TypedEnumRule = IRule<RuleFunction.TYPED_ENUM>;
-
-export const typedEnum: IFunction = (targetVal, opts, paths, otherValues): void | IFunctionResult[] => {
-  const { enum: enumValues, ...initialSchema } = targetVal;
+export const typedEnum: IFunction = function(this: IFunctionContext, targetVal, opts, paths, otherValues) {
+  // do not use rest spread operator here, as this causes the whole tslib gets injected despite proper target set...
+  // obviously, having tslib inlined makes the code size quite larger (around 4x after compression - 1.8K vs 7.4K).
+  const { enum: enumValues } = targetVal;
+  const initialSchema = Object.assign({}, targetVal);
+  delete initialSchema.enum;
 
   if (!Array.isArray(enumValues)) {
     return;
@@ -16,7 +17,7 @@ export const typedEnum: IFunction = (targetVal, opts, paths, otherValues): void
   const incorrectValues: Array<{ index: number; val: unknown }> = [];
 
   enumValues.forEach((val, index) => {
-    const res = schema(val, schemaObject, paths, otherValues);
+    const res = this.functions.schema(val, schemaObject, paths, otherValues);
 
     if (res !== undefined && res.length !== 0) {
       incorrectValues.push({ index, val });
@@ -38,3 +39,5 @@ export const typedEnum: IFunction = (targetVal, opts, paths, otherValues): void
     };
   });
 };
+
+export default typedEnum;
diff --git a/src/rulesets/oas/index.json b/src/rulesets/oas/index.json
index e6e9e5bd..8f8caa75 100644
--- a/src/rulesets/oas/index.json
+++ b/src/rulesets/oas/index.json
@@ -8,6 +8,7 @@
     "oasOpSecurityDefined",
     "oasPathParam",
     "oasTagDefined",
+    "typedEnum",
     "refSiblings"
   ],
   "rules": {
diff --git a/src/types/rule.ts b/src/types/rule.ts
index 600ef1a4..2d2ea760 100644
--- a/src/types/rule.ts
+++ b/src/types/rule.ts
@@ -6,7 +6,6 @@ import { PatternRule } from '../functions/pattern';
 import { SchemaRule } from '../functions/schema';
 import { SchemaPathRule } from '../functions/schema-path';
 import { TruthyRule } from '../functions/truthy';
-import { TypedEnumRule } from '../functions/typedEnum';
 import { XorRule } from '../functions/xor';
 import { RuleType } from './enums';
 
@@ -19,8 +18,7 @@ export type Rule =
   | PatternRule
   | CasingRule
   | SchemaRule
-  | SchemaPathRule
-  | TypedEnumRule;
+  | SchemaPathRule;
 
 export interface IRule<T = string, O = any> {
   type?: RuleType;
diff --git a/tsconfig.rollup.json b/tsconfig.rollup.json
index c944d0fc..90b549c9 100644
--- a/tsconfig.rollup.json
+++ b/tsconfig.rollup.json
@@ -4,6 +4,7 @@
   "exclude": ["**/__*__/**"],
   "compilerOptions": {
     "outDir": "dist",
+    "target": "es2017",
     "module": "ESNext"
   }
 }


Test patch:
diff --git a/src/rulesets/oas/__tests__/typed-enum.ts b/src/rulesets/oas/__tests__/typed-enum.ts
index 5d8b9038..4b48bf78 100644
--- a/src/rulesets/oas/__tests__/typed-enum.ts
+++ b/src/rulesets/oas/__tests__/typed-enum.ts
@@ -1,11 +1,13 @@
 import { DiagnosticSeverity } from '@stoplight/types';
-import { typedEnum } from '../../../functions/typedEnum';
+import { functions } from '../../../functions';
 import { RuleType, Spectral } from '../../../index';
+import { setFunctionContext } from '../../evaluators';
+import { typedEnum } from '../functions/typedEnum';
 import { rules } from '../index.json';
 
 describe('typed-enum', () => {
   const s = new Spectral();
-  s.setFunctions({ typedEnum });
+  s.setFunctions({ typedEnum: setFunctionContext({ functions }, typedEnum) });
   s.setRules({
     'typed-enum': Object.assign(rules['typed-enum'], {
       recommended: true,
diff --git a/src/functions/__tests__/typedEnum.test.ts b/src/rulesets/oas/functions/__tests__/typedEnum.test.ts
similarity index 97%
rename from src/functions/__tests__/typedEnum.test.ts
rename to src/rulesets/oas/functions/__tests__/typedEnum.test.ts
index 9b3578f3..4155c44a 100644
--- a/src/functions/__tests__/typedEnum.test.ts
+++ b/src/rulesets/oas/functions/__tests__/typedEnum.test.ts
@@ -1,9 +1,11 @@
+import { functions } from '../../../../functions';
 import { typedEnum } from '../typedEnum';
 
 const defaultReportingThreshold = 3;
 
 function runTypedEnum(targetVal: any, reportingThreshold: any) {
-  return typedEnum(
+  return typedEnum.call(
+    { functions },
     targetVal,
     { reportingThreshold },
     { given: ['$'] },