New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

@featurevisor/core

Package Overview
Dependencies
Maintainers
1
Versions
181
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@featurevisor/core - npm Package Compare versions

Comparing version 1.6.0 to 1.7.0

11

CHANGELOG.md

@@ -6,2 +6,13 @@ # Change Log

# [1.7.0](https://github.com/featurevisor/featurevisor/compare/v1.6.0...v1.7.0) (2024-02-14)
### Features
* lint by key pattern and entity type ([#261](https://github.com/featurevisor/featurevisor/issues/261)) ([f4ab707](https://github.com/featurevisor/featurevisor/commit/f4ab707abc32660765d72be64bec7bedf83fa94e))
# [1.6.0](https://github.com/featurevisor/featurevisor/compare/v1.5.1...v1.6.0) (2024-02-11)

@@ -8,0 +19,0 @@

6

lib/linter/lintProject.d.ts
import { Dependencies } from "../dependencies";
export declare function lintProject(deps: Dependencies): Promise<boolean>;
export interface LintProjectOptions {
keyPattern?: string;
entityType?: string;
}
export declare function lintProject(deps: Dependencies, options?: LintProjectOptions): Promise<boolean>;

89

lib/linter/lintProject.js

@@ -52,3 +52,4 @@ "use strict";

var cliFormat_1 = require("../tester/cliFormat");
function lintProject(deps) {
function lintProject(deps, options) {
if (options === void 0) { options = {}; }
return __awaiter(this, void 0, void 0, function () {

@@ -82,3 +83,3 @@ function getFullPathFromKey(type, key, relative) {

}
var projectConfig, datasource, hasError, availableAttributeKeys, availableSegmentKeys, availableFeatureKeys, attributes, attributeZodSchema, _i, attributes_1, key, fullPath, parsed, result, e_1, segments, conditionsZodSchema, segmentZodSchema, _a, segments_1, key, fullPath, parsed, result, e_2, features, featureZodSchema, _b, features_1, key, fullPath, parsed, result, e_3, e_4, groups, groupZodSchema, _c, groups_1, key, fullPath, parsed, result, e_5, e_6, tests, testsZodSchema, _d, tests_1, key, fullPath, parsed, result, e_7;
var projectConfig, datasource, hasError, keyPattern, attributes, attributeZodSchema, filteredKeys, _i, filteredKeys_1, key, fullPath, parsed, result, e_1, segments, conditionsZodSchema, segmentZodSchema, filteredKeys, _a, filteredKeys_2, key, fullPath, parsed, result, e_2, features, featureZodSchema, filteredKeys, _b, filteredKeys_3, key, fullPath, parsed, result, e_3, e_4, groups, groupZodSchema, filteredKeys, _c, filteredKeys_4, key, fullPath, parsed, result, e_5, e_6, tests, testsZodSchema, filteredKeys, _d, filteredKeys_5, key, fullPath, parsed, result, e_7;
return __generator(this, function (_e) {

@@ -89,15 +90,24 @@ switch (_e.label) {

hasError = false;
availableAttributeKeys = [];
availableSegmentKeys = [];
availableFeatureKeys = [];
keyPattern = options.keyPattern ? new RegExp(options.keyPattern) : null;
if (keyPattern) {
console.log("");
console.log("Linting only keys matching pattern: ".concat(keyPattern));
console.log("");
}
return [4 /*yield*/, datasource.listAttributes()];
case 1:
attributes = _e.sent();
console.log("Linting ".concat(attributes.length, " attributes...\n"));
attributeZodSchema = (0, attributeSchema_1.getAttributeZodSchema)();
_i = 0, attributes_1 = attributes;
if (!(!options.entityType || options.entityType === "attribute")) return [3 /*break*/, 7];
filteredKeys = !keyPattern
? attributes
: attributes.filter(function (key) { return keyPattern.test(key); });
if (filteredKeys.length > 0) {
console.log("Linting ".concat(filteredKeys.length, " attributes...\n"));
}
_i = 0, filteredKeys_1 = filteredKeys;
_e.label = 2;
case 2:
if (!(_i < attributes_1.length)) return [3 /*break*/, 7];
key = attributes_1[_i];
if (!(_i < filteredKeys_1.length)) return [3 /*break*/, 7];
key = filteredKeys_1[_i];
fullPath = getFullPathFromKey("attribute", key);

@@ -110,3 +120,2 @@ _e.label = 3;

parsed = _e.sent();
availableAttributeKeys.push(key);
result = attributeZodSchema.safeParse(parsed);

@@ -134,10 +143,14 @@ if (!result.success) {

segments = _e.sent();
console.log("\nLinting ".concat(segments.length, " segments...\n"));
conditionsZodSchema = (0, conditionSchema_1.getConditionsZodSchema)(projectConfig, availableAttributeKeys);
conditionsZodSchema = (0, conditionSchema_1.getConditionsZodSchema)(projectConfig, attributes);
segmentZodSchema = (0, segmentSchema_1.getSegmentZodSchema)(projectConfig, conditionsZodSchema);
_a = 0, segments_1 = segments;
if (!(!options.entityType || options.entityType === "segment")) return [3 /*break*/, 14];
filteredKeys = !keyPattern ? segments : segments.filter(function (key) { return keyPattern.test(key); });
if (filteredKeys.length > 0) {
console.log("Linting ".concat(filteredKeys.length, " segments...\n"));
}
_a = 0, filteredKeys_2 = filteredKeys;
_e.label = 9;
case 9:
if (!(_a < segments_1.length)) return [3 /*break*/, 14];
key = segments_1[_a];
if (!(_a < filteredKeys_2.length)) return [3 /*break*/, 14];
key = filteredKeys_2[_a];
fullPath = getFullPathFromKey("segment", key);

@@ -150,3 +163,2 @@ _e.label = 10;

parsed = _e.sent();
availableSegmentKeys.push(key);
result = segmentZodSchema.safeParse(parsed);

@@ -174,9 +186,13 @@ if (!result.success) {

features = _e.sent();
console.log("\nLinting ".concat(features.length, " features...\n"));
featureZodSchema = (0, featureSchema_1.getFeatureZodSchema)(projectConfig, conditionsZodSchema, availableAttributeKeys, availableSegmentKeys, features);
_b = 0, features_1 = features;
featureZodSchema = (0, featureSchema_1.getFeatureZodSchema)(projectConfig, conditionsZodSchema, attributes, segments, features);
if (!(!options.entityType || options.entityType === "feature")) return [3 /*break*/, 25];
filteredKeys = !keyPattern ? features : features.filter(function (key) { return keyPattern.test(key); });
if (filteredKeys.length > 0) {
console.log("Linting ".concat(filteredKeys.length, " features...\n"));
}
_b = 0, filteredKeys_3 = filteredKeys;
_e.label = 16;
case 16:
if (!(_b < features_1.length)) return [3 /*break*/, 25];
key = features_1[_b];
if (!(_b < filteredKeys_3.length)) return [3 /*break*/, 25];
key = filteredKeys_3[_b];
fullPath = getFullPathFromKey("feature", key);

@@ -190,3 +206,2 @@ parsed = void 0;

parsed = _e.sent();
availableFeatureKeys.push(key);
result = featureZodSchema.safeParse(parsed);

@@ -229,9 +244,13 @@ if (!result.success) {

groups = _e.sent();
console.log("\nLinting ".concat(groups.length, " groups...\n"));
groupZodSchema = (0, groupSchema_1.getGroupZodSchema)(projectConfig, datasource, availableFeatureKeys);
_c = 0, groups_1 = groups;
groupZodSchema = (0, groupSchema_1.getGroupZodSchema)(projectConfig, datasource, features);
if (!(!options.entityType || options.entityType === "group")) return [3 /*break*/, 36];
filteredKeys = !keyPattern ? groups : groups.filter(function (key) { return keyPattern.test(key); });
if (filteredKeys.length > 0) {
console.log("Linting ".concat(filteredKeys.length, " groups...\n"));
}
_c = 0, filteredKeys_4 = filteredKeys;
_e.label = 27;
case 27:
if (!(_c < groups_1.length)) return [3 /*break*/, 36];
key = groups_1[_c];
if (!(_c < filteredKeys_4.length)) return [3 /*break*/, 36];
key = filteredKeys_4[_c];
fullPath = getFullPathFromKey("group", key);

@@ -266,3 +285,3 @@ parsed = void 0;

_e.trys.push([32, 34, , 35]);
return [4 /*yield*/, (0, checkPercentageExceedingSlot_1.checkForFeatureExceedingGroupSlotPercentage)(datasource, parsed, availableFeatureKeys)];
return [4 /*yield*/, (0, checkPercentageExceedingSlot_1.checkForFeatureExceedingGroupSlotPercentage)(datasource, parsed, features)];
case 33:

@@ -283,9 +302,13 @@ _e.sent();

tests = _e.sent();
console.log("\nLinting ".concat(tests.length, " tests...\n"));
testsZodSchema = (0, testSchema_1.getTestsZodSchema)(projectConfig, availableFeatureKeys, availableSegmentKeys);
_d = 0, tests_1 = tests;
testsZodSchema = (0, testSchema_1.getTestsZodSchema)(projectConfig, features, segments);
if (!(!options.entityType || options.entityType === "test")) return [3 /*break*/, 43];
filteredKeys = !keyPattern ? tests : tests.filter(function (key) { return keyPattern.test(key); });
if (filteredKeys.length > 0) {
console.log("Linting ".concat(filteredKeys.length, " tests...\n"));
}
_d = 0, filteredKeys_5 = filteredKeys;
_e.label = 38;
case 38:
if (!(_d < tests_1.length)) return [3 /*break*/, 43];
key = tests_1[_d];
if (!(_d < filteredKeys_5.length)) return [3 /*break*/, 43];
key = filteredKeys_5[_d];
fullPath = getFullPathFromKey("test", key);

@@ -292,0 +315,0 @@ _e.label = 39;

{
"name": "@featurevisor/core",
"version": "1.6.0",
"version": "1.7.0",
"description": "Core package of Featurevisor for Node.js usage",

@@ -60,3 +60,3 @@ "main": "lib/index.js",

},
"gitHead": "9d9a317843b028cc68ec0ff4ce060fe1404368d8"
"gitHead": "c258fe5fd1c1ea78798a37a0866e574f5a29afdc"
}

@@ -17,3 +17,11 @@ // for use in node only

export async function lintProject(deps: Dependencies): Promise<boolean> {
export interface LintProjectOptions {
keyPattern?: string;
entityType?: string;
}
export async function lintProject(
deps: Dependencies,
options: LintProjectOptions = {},
): Promise<boolean> {
const { projectConfig, datasource } = deps;

@@ -23,6 +31,2 @@

const availableAttributeKeys: string[] = [];
const availableSegmentKeys: string[] = [];
const availableFeatureKeys: string[] = [];
function getFullPathFromKey(type: string, key: string, relative = false) {

@@ -53,32 +57,47 @@ const fileName = `${key}.${datasource.getExtension()}`;

const keyPattern = options.keyPattern ? new RegExp(options.keyPattern) : null;
if (keyPattern) {
console.log("");
console.log(`Linting only keys matching pattern: ${keyPattern}`);
console.log("");
}
// lint attributes
const attributes = await datasource.listAttributes();
console.log(`Linting ${attributes.length} attributes...\n`);
const attributeZodSchema = getAttributeZodSchema();
for (const key of attributes) {
const fullPath = getFullPathFromKey("attribute", key);
if (!options.entityType || options.entityType === "attribute") {
const filteredKeys = !keyPattern
? attributes
: attributes.filter((key) => keyPattern.test(key));
try {
const parsed = await datasource.readAttribute(key);
availableAttributeKeys.push(key);
if (filteredKeys.length > 0) {
console.log(`Linting ${filteredKeys.length} attributes...\n`);
}
const result = attributeZodSchema.safeParse(parsed);
for (const key of filteredKeys) {
const fullPath = getFullPathFromKey("attribute", key);
if (!result.success) {
console.log(CLI_FORMAT_UNDERLINE, fullPath);
try {
const parsed = await datasource.readAttribute(key);
if ("error" in result) {
printZodError(result.error);
const result = attributeZodSchema.safeParse(parsed);
if (!result.success) {
console.log(CLI_FORMAT_UNDERLINE, fullPath);
if ("error" in result) {
printZodError(result.error);
}
hasError = true;
}
} catch (e) {
console.log(CLI_FORMAT_UNDERLINE, fullPath);
console.log("");
console.log(e);
hasError = true;
}
} catch (e) {
console.log(CLI_FORMAT_UNDERLINE, fullPath);
console.log("");
console.log(e);
hasError = true;
}

@@ -89,34 +108,39 @@ }

const segments = await datasource.listSegments();
console.log(`\nLinting ${segments.length} segments...\n`);
const conditionsZodSchema = getConditionsZodSchema(
projectConfig,
availableAttributeKeys as [string, ...string[]],
attributes as [string, ...string[]],
);
const segmentZodSchema = getSegmentZodSchema(projectConfig, conditionsZodSchema);
for (const key of segments) {
const fullPath = getFullPathFromKey("segment", key);
if (!options.entityType || options.entityType === "segment") {
const filteredKeys = !keyPattern ? segments : segments.filter((key) => keyPattern.test(key));
try {
const parsed = await datasource.readSegment(key);
availableSegmentKeys.push(key);
if (filteredKeys.length > 0) {
console.log(`Linting ${filteredKeys.length} segments...\n`);
}
const result = segmentZodSchema.safeParse(parsed);
for (const key of filteredKeys) {
const fullPath = getFullPathFromKey("segment", key);
if (!result.success) {
console.log(CLI_FORMAT_UNDERLINE, fullPath);
try {
const parsed = await datasource.readSegment(key);
if ("error" in result) {
printZodError(result.error);
const result = segmentZodSchema.safeParse(parsed);
if (!result.success) {
console.log(CLI_FORMAT_UNDERLINE, fullPath);
if ("error" in result) {
printZodError(result.error);
}
hasError = true;
}
} catch (e) {
console.log(CLI_FORMAT_UNDERLINE, fullPath);
console.log("");
console.log(e);
hasError = true;
}
} catch (e) {
console.log(CLI_FORMAT_UNDERLINE, fullPath);
console.log("");
console.log(e);
hasError = true;
}

@@ -127,47 +151,52 @@ }

const features = await datasource.listFeatures();
console.log(`\nLinting ${features.length} features...\n`);
const featureZodSchema = getFeatureZodSchema(
projectConfig,
conditionsZodSchema,
availableAttributeKeys as [string, ...string[]],
availableSegmentKeys as [string, ...string[]],
attributes as [string, ...string[]],
segments as [string, ...string[]],
features as [string, ...string[]],
);
for (const key of features) {
const fullPath = getFullPathFromKey("feature", key);
let parsed;
if (!options.entityType || options.entityType === "feature") {
const filteredKeys = !keyPattern ? features : features.filter((key) => keyPattern.test(key));
try {
parsed = await datasource.readFeature(key);
availableFeatureKeys.push(key);
if (filteredKeys.length > 0) {
console.log(`Linting ${filteredKeys.length} features...\n`);
}
const result = featureZodSchema.safeParse(parsed);
for (const key of filteredKeys) {
const fullPath = getFullPathFromKey("feature", key);
let parsed;
if (!result.success) {
console.log(CLI_FORMAT_UNDERLINE, fullPath);
try {
parsed = await datasource.readFeature(key);
if ("error" in result) {
printZodError(result.error);
}
const result = featureZodSchema.safeParse(parsed);
hasError = true;
}
} catch (e) {
console.log(CLI_FORMAT_UNDERLINE, fullPath);
console.log("");
console.log(e);
if (!result.success) {
console.log(CLI_FORMAT_UNDERLINE, fullPath);
hasError = true;
}
if ("error" in result) {
printZodError(result.error);
}
if (parsed && parsed.required) {
try {
await checkForCircularDependencyInRequired(datasource, key, parsed.required);
hasError = true;
}
} catch (e) {
console.log(CLI_FORMAT_UNDERLINE, fullPath);
console.log(CLI_FORMAT_RED, ` => Error: ${e.message}`);
console.log("");
console.log(e);
hasError = true;
}
if (parsed && parsed.required) {
try {
await checkForCircularDependencyInRequired(datasource, key, parsed.required);
} catch (e) {
console.log(CLI_FORMAT_UNDERLINE, fullPath);
console.log(CLI_FORMAT_RED, ` => Error: ${e.message}`);
hasError = true;
}
}
}

@@ -178,41 +207,46 @@ }

const groups = await datasource.listGroups();
console.log(`\nLinting ${groups.length} groups...\n`);
const groupZodSchema = getGroupZodSchema(projectConfig, datasource, features);
// @TODO: feature it slots can be from availableFeatureKeys only
const groupZodSchema = getGroupZodSchema(projectConfig, datasource, availableFeatureKeys);
if (!options.entityType || options.entityType === "group") {
const filteredKeys = !keyPattern ? groups : groups.filter((key) => keyPattern.test(key));
for (const key of groups) {
const fullPath = getFullPathFromKey("group", key);
let parsed;
if (filteredKeys.length > 0) {
console.log(`Linting ${filteredKeys.length} groups...\n`);
}
try {
parsed = await datasource.readGroup(key);
for (const key of filteredKeys) {
const fullPath = getFullPathFromKey("group", key);
let parsed;
const result = groupZodSchema.safeParse(parsed);
try {
parsed = await datasource.readGroup(key);
if (!result.success) {
console.log(CLI_FORMAT_UNDERLINE, fullPath);
const result = groupZodSchema.safeParse(parsed);
if ("error" in result) {
printZodError(result.error);
}
if (!result.success) {
console.log(CLI_FORMAT_UNDERLINE, fullPath);
hasError = true;
}
} catch (e) {
console.log(CLI_FORMAT_UNDERLINE, fullPath);
console.log("");
console.log(e);
if ("error" in result) {
printZodError(result.error);
}
hasError = true;
}
if (parsed) {
try {
await checkForFeatureExceedingGroupSlotPercentage(datasource, parsed, availableFeatureKeys);
hasError = true;
}
} catch (e) {
console.log(CLI_FORMAT_UNDERLINE, fullPath);
console.log(CLI_FORMAT_RED, ` => Error: ${e.message}`);
console.log("");
console.log(e);
hasError = true;
}
if (parsed) {
try {
await checkForFeatureExceedingGroupSlotPercentage(datasource, parsed, features);
} catch (e) {
console.log(CLI_FORMAT_UNDERLINE, fullPath);
console.log(CLI_FORMAT_RED, ` => Error: ${e.message}`);
hasError = true;
}
}
}

@@ -225,35 +259,42 @@ }

const tests = await datasource.listTests();
console.log(`\nLinting ${tests.length} tests...\n`);
const testsZodSchema = getTestsZodSchema(
projectConfig,
availableFeatureKeys as [string, ...string[]],
availableSegmentKeys as [string, ...string[]],
features as [string, ...string[]],
segments as [string, ...string[]],
);
for (const key of tests) {
const fullPath = getFullPathFromKey("test", key);
if (!options.entityType || options.entityType === "test") {
const filteredKeys = !keyPattern ? tests : tests.filter((key) => keyPattern.test(key));
try {
const parsed = await datasource.readTest(key);
if (filteredKeys.length > 0) {
console.log(`Linting ${filteredKeys.length} tests...\n`);
}
const result = testsZodSchema.safeParse(parsed);
for (const key of filteredKeys) {
const fullPath = getFullPathFromKey("test", key);
if (!result.success) {
console.log(CLI_FORMAT_UNDERLINE, fullPath);
try {
const parsed = await datasource.readTest(key);
if ("error" in result) {
printZodError(result.error);
const result = testsZodSchema.safeParse(parsed);
process.exit(1);
if (!result.success) {
console.log(CLI_FORMAT_UNDERLINE, fullPath);
if ("error" in result) {
printZodError(result.error);
process.exit(1);
}
hasError = true;
}
} catch (e) {
console.log(CLI_FORMAT_UNDERLINE, fullPath);
console.log("");
console.log(e);
hasError = true;
}
} catch (e) {
console.log(CLI_FORMAT_UNDERLINE, fullPath);
console.log("");
console.log(e);
hasError = true;
}

@@ -260,0 +301,0 @@ }

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc