diff --git a/CLAUDE.md b/CLAUDE.md new file mode 100644 index 0000000..5f3b90f --- /dev/null +++ b/CLAUDE.md @@ -0,0 +1,21 @@ +# Flipper Expressions + +JSON Schema (`schemas/*.json`) and JS library for Flipper Expressions. The schemas are the canonical spec; the Ruby gem reimplements the expressions and vendors these schemas + examples for its tests. + +## Keep flipper in sync when schemas or examples change + +Any time `schemas/*.json` or `examples/*.json` change here, the vendored copies in the [flippercloud/flipper](https://github.com/flippercloud/flipper) gem must be re-synced and its specs re-run — otherwise Ruby and JS drift apart. + +In a flipper checkout: + +```sh +# Copies schemas/*.json and examples/*.json from this repo into flipper +# (lib/flipper/expression/schemas + spec/fixtures/expressions/examples). +# Defaults to a sibling ../expressions checkout; override with SOURCE. +rake expressions:vendor SOURCE=/path/to/expressions + +# Then run flipper's specs to confirm Ruby agrees with the schema/examples. +bundle exec rspec spec/flipper/expression/schema_spec.rb +``` + +See the README's "Adding a new expression" section for the full cross-repo workflow. diff --git a/examples/FeatureEnabled.json b/examples/FeatureEnabled.json new file mode 100644 index 0000000..816ce2a --- /dev/null +++ b/examples/FeatureEnabled.json @@ -0,0 +1,15 @@ +{ + "valid": [ + { + "expression": { "FeatureEnabled": ["other_feature"] } + }, + { + "expression": { "FeatureEnabled": [{ "Property": ["feature_name"] }] } + } + ], + "invalid": [ + { "FeatureEnabled": [] }, + { "FeatureEnabled": ["a", "b"] }, + { "FeatureEnabled": ["a"], "Any": [] } + ] +} diff --git a/package.json b/package.json index 45c2f6d..903041e 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { - "name": "@flippercloud.io/expressions", - "version": "1.0.0", + "name": "@flippercloud/expressions", + "version": "1.1.0", "description": "Library and Schema for evaluating Flipper Expressions", "type": "module", "files": [ @@ -16,7 +16,7 @@ "require": "./dist/expressions.umd.cjs" } }, - "repository": "https:://github.com/jnunemaker/flipper", + "repository": "https://github.com/flippercloud/expressions", "license": "MIT", "dependencies": { "ajv": "^8.12.0", diff --git a/schemas/FeatureEnabled.schema.json b/schemas/FeatureEnabled.schema.json new file mode 100644 index 0000000..f53a53b --- /dev/null +++ b/schemas/FeatureEnabled.schema.json @@ -0,0 +1,11 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "$id": "https://www.flippercloud.io/expressions/FeatureEnabled.schema.json", + "title": "FeatureEnabled", + "description": "Returns true if the named feature is enabled for the current actor.", + "category": "Value", + "type": "array", + "items": { "$ref": "schema.json#/definitions/string" }, + "minItems": 1, + "maxItems": 1 +} diff --git a/schemas/PercentageOfActors.schema.json b/schemas/PercentageOfActors.schema.json index e512104..92a60c4 100644 --- a/schemas/PercentageOfActors.schema.json +++ b/schemas/PercentageOfActors.schema.json @@ -2,7 +2,8 @@ "$schema": "http://json-schema.org/draft-07/schema#", "$id": "https://www.flippercloud.io/expressions/PercentageOfActors.schema.json", "title": "PercentageOfActors", - "description": "", + "description": "Returns true when the actor falls within the given percentage for the feature.", + "category": "Condition", "type": "array", "items": [ { "$ref": "schema.json#/definitions/string" }, diff --git a/schemas/Property.schema.json b/schemas/Property.schema.json index 0d564ad..f0c41ec 100644 --- a/schemas/Property.schema.json +++ b/schemas/Property.schema.json @@ -3,6 +3,7 @@ "$id": "https://www.flippercloud.io/expressions/Property.schema.json", "title": "Property", "description": "Extract a property from context[properties].", + "category": "Value", "type": "array", "items": { "$ref": "schema.json#/definitions/string" }, "minItems": 1, diff --git a/schemas/Random.schema.json b/schemas/Random.schema.json index dcdd89e..d719680 100644 --- a/schemas/Random.schema.json +++ b/schemas/Random.schema.json @@ -3,6 +3,7 @@ "$id": "https://www.flippercloud.io/expressions/Random.schema.json", "title": "Random", "description": "Return a random number", + "category": "Value", "type": "array", "items": { "title": "Maximum", diff --git a/schemas/Time.schema.json b/schemas/Time.schema.json index cc7bac7..4db6410 100644 --- a/schemas/Time.schema.json +++ b/schemas/Time.schema.json @@ -3,6 +3,7 @@ "$id": "https://www.flippercloud.io/expressions/Time.schema.json", "title": "Time", "description": "A time in ISO8601 format", + "category": "Value", "type": "array", "items": { "title": "Time", diff --git a/schemas/schema.json b/schemas/schema.json index f12d30a..682576a 100644 --- a/schemas/schema.json +++ b/schemas/schema.json @@ -44,6 +44,7 @@ "Divide": { "$ref": "Divide.schema.json" }, "Duration": { "$ref": "Duration.schema.json" }, "Equal": { "$ref": "Equal.schema.json" }, + "FeatureEnabled": { "$ref": "FeatureEnabled.schema.json" }, "GreaterThan": { "$ref": "GreaterThan.schema.json" }, "GreaterThanOrEqualTo": { "$ref": "GreaterThanOrEqualTo.schema.json" }, "LessThan": { "$ref": "LessThan.schema.json" }, diff --git a/vite.config.js b/vite.config.js index a4961e2..01820f0 100644 --- a/vite.config.js +++ b/vite.config.js @@ -7,7 +7,7 @@ export default defineConfig({ sourcemap: true, lib: { entry: resolve(__dirname, 'lib/index.js'), - name: '@flippercloud.io/expressions' + name: '@flippercloud/expressions' }, rollupOptions: { external: [