@bernierllc/nevar-operator-registry 0.0.1 → 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/LICENSE ADDED
@@ -0,0 +1,5 @@
1
+ Copyright (c) 2025 Bernier LLC
2
+
3
+ This software is licensed to the client under a limited-use license.
4
+ The client may use and modify this code *only within the scope of the project it was delivered for*.
5
+ Redistribution or use in other products or commercial offerings is not permitted without written consent from Bernier LLC.
package/README.md CHANGED
@@ -1,45 +1,86 @@
1
1
  # @bernierllc/nevar-operator-registry
2
2
 
3
- ## ⚠️ IMPORTANT NOTICE ⚠️
3
+ Operator registry with 12 built-in operators for the Nevar rules engine.
4
4
 
5
- **This package is created solely for the purpose of setting up OIDC (OpenID Connect) trusted publishing with npm.**
5
+ ## Installation
6
6
 
7
- This is **NOT** a functional package and contains **NO** code or functionality beyond the OIDC setup configuration.
7
+ ```bash
8
+ npm install @bernierllc/nevar-operator-registry
9
+ ```
8
10
 
9
- ## Purpose
11
+ ## Usage
10
12
 
11
- This package exists to:
12
- 1. Configure OIDC trusted publishing for the package name `@bernierllc/nevar-operator-registry`
13
- 2. Enable secure, token-less publishing from CI/CD workflows
14
- 3. Establish provenance for packages published under this name
13
+ ```typescript
14
+ import { OperatorRegistry } from '@bernierllc/nevar-operator-registry';
15
15
 
16
- ## What is OIDC Trusted Publishing?
16
+ const registry = new OperatorRegistry();
17
17
 
18
- OIDC trusted publishing allows package maintainers to publish packages directly from their CI/CD workflows without needing to manage npm access tokens. Instead, it uses OpenID Connect to establish trust between the CI/CD provider (like GitHub Actions) and npm.
18
+ // All 12 built-in operators are pre-registered
19
+ registry.evaluate('eq', 'hello', 'hello'); // true
20
+ registry.evaluate('gt', 10, 5); // true
21
+ registry.evaluate('in', 'a', ['a', 'b']); // true
22
+ registry.evaluate('is_true', true, null); // true
19
23
 
20
- ## Setup Instructions
24
+ // List all operators
25
+ const operators = registry.list();
21
26
 
22
- To properly configure OIDC trusted publishing for this package:
27
+ // Filter by category
28
+ const comparisons = registry.getByCategory('comparison');
23
29
 
24
- 1. Go to [npmjs.com](https://www.npmjs.com/) and navigate to your package settings
25
- 2. Configure the trusted publisher (e.g., GitHub Actions)
26
- 3. Specify the repository and workflow that should be allowed to publish
27
- 4. Use the configured workflow to publish your actual package
30
+ // Register custom operators
31
+ registry.register('starts_with', {
32
+ label: 'Starts With',
33
+ category: 'string',
34
+ evaluate: (field, target) => String(field).startsWith(String(target)),
35
+ schema: z.string(),
36
+ fieldTypes: ['string'],
37
+ });
38
+ ```
28
39
 
29
- ## DO NOT USE THIS PACKAGE
40
+ ## Built-in Operators
30
41
 
31
- This package is a placeholder for OIDC configuration only. It:
32
- - Contains no executable code
33
- - Provides no functionality
34
- - Should not be installed as a dependency
35
- - Exists only for administrative purposes
42
+ | Operator | Category | Description |
43
+ |----------|----------|-------------|
44
+ | eq | comparison | Equal to |
45
+ | neq | comparison | Not equal to |
46
+ | gt | comparison | Greater than |
47
+ | gte | comparison | Greater than or equal |
48
+ | lt | comparison | Less than |
49
+ | lte | comparison | Less than or equal |
50
+ | in | membership | Value is in array |
51
+ | not_in | membership | Value is not in array |
52
+ | contains | membership | Array/string contains value |
53
+ | not_contains | membership | Array/string does not contain value |
54
+ | is_true | boolean | Value is truthy |
55
+ | is_false | boolean | Value is falsy |
36
56
 
37
- ## More Information
57
+ ## API
38
58
 
39
- For more details about npm's trusted publishing feature, see:
40
- - [npm Trusted Publishing Documentation](https://docs.npmjs.com/generating-provenance-statements)
41
- - [GitHub Actions OIDC Documentation](https://docs.github.com/en/actions/deployment/security-hardening-your-deployments/about-security-hardening-with-openid-connect)
59
+ ### `OperatorRegistry`
42
60
 
43
- ---
61
+ Registry for managing built-in and custom operators. All 12 built-in operators are pre-registered on construction.
44
62
 
45
- **Maintained for OIDC setup purposes only**
63
+ **Constructor:** `new OperatorRegistry()`
64
+
65
+ - `register(name, definition)` - Registers a custom operator. Throws `NevarValidationError` if the name is already registered
66
+ - `get(name)` - Returns the `OperatorDefinition` for the given name, or `undefined`
67
+ - `has(name)` - Returns `true` if the operator is registered
68
+ - `list()` - Returns all operators as serializable `OperatorInfo[]` (without evaluate functions)
69
+ - `getByCategory(category)` - Returns operators filtered by category
70
+ - `evaluate(name, fieldValue, targetValue)` - Evaluates a field value against a target using the named operator. Throws `NevarEvaluationError` for unknown operators
71
+
72
+ ### `builtInOperators`
73
+
74
+ Exported map of the 12 built-in operator definitions, useful for inspection or testing.
75
+
76
+ ## Integration Documentation
77
+
78
+ ### Logger Integration
79
+ This package does not integrate with `@bernierllc/logger`. As a core package, logger integration is optional and not included by default. Consumers should handle logging at the service layer.
80
+
81
+ ### NeverHub Integration
82
+ This package does not integrate with `@bernierllc/neverhub-adapter`. As a core package, NeverHub integration is not applicable. NeverHub registration should be handled by service-layer packages that compose this package.
83
+
84
+ ## License
85
+
86
+ Copyright (c) 2025 Bernier LLC. All rights reserved.
@@ -0,0 +1,6 @@
1
+ import type { OperatorDefinition } from '@bernierllc/nevar-types';
2
+ /**
3
+ * All 12 built-in operators for the Nevar rules engine.
4
+ * Grouped by category: comparison, membership, boolean.
5
+ */
6
+ export declare const builtInOperators: Record<string, OperatorDefinition>;
@@ -0,0 +1,158 @@
1
+ "use strict";
2
+ /*
3
+ Copyright (c) 2025 Bernier LLC
4
+
5
+ This file is licensed to the client under a limited-use license.
6
+ The client may use and modify this code *only within the scope of the project it was delivered for*.
7
+ Redistribution or use in other products or commercial offerings is not permitted without written consent from Bernier LLC.
8
+ */
9
+ Object.defineProperty(exports, "__esModule", { value: true });
10
+ exports.builtInOperators = void 0;
11
+ const zod_1 = require("zod");
12
+ /**
13
+ * All 12 built-in operators for the Nevar rules engine.
14
+ * Grouped by category: comparison, membership, boolean.
15
+ */
16
+ exports.builtInOperators = {
17
+ // --- Comparison operators ---
18
+ eq: {
19
+ label: 'Equal',
20
+ category: 'comparison',
21
+ evaluate: (fieldValue, targetValue) => {
22
+ return fieldValue === targetValue;
23
+ },
24
+ schema: zod_1.z.unknown(),
25
+ fieldTypes: ['string', 'number', 'boolean'],
26
+ },
27
+ neq: {
28
+ label: 'Not Equal',
29
+ category: 'comparison',
30
+ evaluate: (fieldValue, targetValue) => {
31
+ return fieldValue !== targetValue;
32
+ },
33
+ schema: zod_1.z.unknown(),
34
+ fieldTypes: ['string', 'number', 'boolean'],
35
+ },
36
+ gt: {
37
+ label: 'Greater Than',
38
+ category: 'comparison',
39
+ evaluate: (fieldValue, targetValue) => {
40
+ if (typeof fieldValue !== 'number' || typeof targetValue !== 'number') {
41
+ return false;
42
+ }
43
+ return fieldValue > targetValue;
44
+ },
45
+ schema: zod_1.z.number(),
46
+ fieldTypes: ['number'],
47
+ },
48
+ gte: {
49
+ label: 'Greater Than or Equal',
50
+ category: 'comparison',
51
+ evaluate: (fieldValue, targetValue) => {
52
+ if (typeof fieldValue !== 'number' || typeof targetValue !== 'number') {
53
+ return false;
54
+ }
55
+ return fieldValue >= targetValue;
56
+ },
57
+ schema: zod_1.z.number(),
58
+ fieldTypes: ['number'],
59
+ },
60
+ lt: {
61
+ label: 'Less Than',
62
+ category: 'comparison',
63
+ evaluate: (fieldValue, targetValue) => {
64
+ if (typeof fieldValue !== 'number' || typeof targetValue !== 'number') {
65
+ return false;
66
+ }
67
+ return fieldValue < targetValue;
68
+ },
69
+ schema: zod_1.z.number(),
70
+ fieldTypes: ['number'],
71
+ },
72
+ lte: {
73
+ label: 'Less Than or Equal',
74
+ category: 'comparison',
75
+ evaluate: (fieldValue, targetValue) => {
76
+ if (typeof fieldValue !== 'number' || typeof targetValue !== 'number') {
77
+ return false;
78
+ }
79
+ return fieldValue <= targetValue;
80
+ },
81
+ schema: zod_1.z.number(),
82
+ fieldTypes: ['number'],
83
+ },
84
+ // --- Membership operators ---
85
+ in: {
86
+ label: 'In',
87
+ category: 'membership',
88
+ evaluate: (fieldValue, targetValue) => {
89
+ if (!Array.isArray(targetValue)) {
90
+ return false;
91
+ }
92
+ return targetValue.includes(fieldValue);
93
+ },
94
+ schema: zod_1.z.array(zod_1.z.unknown()),
95
+ fieldTypes: ['string', 'number'],
96
+ },
97
+ not_in: {
98
+ label: 'Not In',
99
+ category: 'membership',
100
+ evaluate: (fieldValue, targetValue) => {
101
+ if (!Array.isArray(targetValue)) {
102
+ return true;
103
+ }
104
+ return !targetValue.includes(fieldValue);
105
+ },
106
+ schema: zod_1.z.array(zod_1.z.unknown()),
107
+ fieldTypes: ['string', 'number'],
108
+ },
109
+ contains: {
110
+ label: 'Contains',
111
+ category: 'membership',
112
+ evaluate: (fieldValue, targetValue) => {
113
+ if (Array.isArray(fieldValue)) {
114
+ return fieldValue.includes(targetValue);
115
+ }
116
+ if (typeof fieldValue === 'string' && typeof targetValue === 'string') {
117
+ return fieldValue.includes(targetValue);
118
+ }
119
+ return false;
120
+ },
121
+ schema: zod_1.z.unknown(),
122
+ fieldTypes: ['string', 'array'],
123
+ },
124
+ not_contains: {
125
+ label: 'Not Contains',
126
+ category: 'membership',
127
+ evaluate: (fieldValue, targetValue) => {
128
+ if (Array.isArray(fieldValue)) {
129
+ return !fieldValue.includes(targetValue);
130
+ }
131
+ if (typeof fieldValue === 'string' && typeof targetValue === 'string') {
132
+ return !fieldValue.includes(targetValue);
133
+ }
134
+ return true;
135
+ },
136
+ schema: zod_1.z.unknown(),
137
+ fieldTypes: ['string', 'array'],
138
+ },
139
+ // --- Boolean operators ---
140
+ is_true: {
141
+ label: 'Is True',
142
+ category: 'boolean',
143
+ evaluate: (fieldValue, _targetValue) => {
144
+ return Boolean(fieldValue);
145
+ },
146
+ schema: zod_1.z.unknown().optional(),
147
+ fieldTypes: ['boolean'],
148
+ },
149
+ is_false: {
150
+ label: 'Is False',
151
+ category: 'boolean',
152
+ evaluate: (fieldValue, _targetValue) => {
153
+ return !fieldValue;
154
+ },
155
+ schema: zod_1.z.unknown().optional(),
156
+ fieldTypes: ['boolean'],
157
+ },
158
+ };
@@ -0,0 +1,2 @@
1
+ export { OperatorRegistry } from './operator-registry';
2
+ export { builtInOperators } from './built-in-operators';
package/dist/index.js ADDED
@@ -0,0 +1,14 @@
1
+ "use strict";
2
+ /*
3
+ Copyright (c) 2025 Bernier LLC
4
+
5
+ This file is licensed to the client under a limited-use license.
6
+ The client may use and modify this code *only within the scope of the project it was delivered for*.
7
+ Redistribution or use in other products or commercial offerings is not permitted without written consent from Bernier LLC.
8
+ */
9
+ Object.defineProperty(exports, "__esModule", { value: true });
10
+ exports.builtInOperators = exports.OperatorRegistry = void 0;
11
+ var operator_registry_1 = require("./operator-registry");
12
+ Object.defineProperty(exports, "OperatorRegistry", { enumerable: true, get: function () { return operator_registry_1.OperatorRegistry; } });
13
+ var built_in_operators_1 = require("./built-in-operators");
14
+ Object.defineProperty(exports, "builtInOperators", { enumerable: true, get: function () { return built_in_operators_1.builtInOperators; } });
@@ -0,0 +1,35 @@
1
+ import type { OperatorDefinition, OperatorInfo } from '@bernierllc/nevar-types';
2
+ /**
3
+ * Registry for managing built-in and custom operators.
4
+ * Provides registration, lookup, discovery, and evaluation capabilities.
5
+ */
6
+ export declare class OperatorRegistry {
7
+ private readonly operators;
8
+ constructor();
9
+ /**
10
+ * Register a new operator. Throws NevarValidationError on duplicate name.
11
+ */
12
+ register(name: string, definition: OperatorDefinition): void;
13
+ /**
14
+ * Get an operator definition by name.
15
+ */
16
+ get(name: string): OperatorDefinition | undefined;
17
+ /**
18
+ * Check if an operator is registered.
19
+ */
20
+ has(name: string): boolean;
21
+ /**
22
+ * List all registered operators as serializable OperatorInfo objects.
23
+ * Excludes the evaluate function.
24
+ */
25
+ list(): OperatorInfo[];
26
+ /**
27
+ * Get all operators in a given category.
28
+ */
29
+ getByCategory(category: string): OperatorInfo[];
30
+ /**
31
+ * Evaluate a field value against a target value using the named operator.
32
+ * Throws NevarEvaluationError for unknown operators.
33
+ */
34
+ evaluate(name: string, fieldValue: unknown, targetValue: unknown): boolean;
35
+ }
@@ -0,0 +1,80 @@
1
+ "use strict";
2
+ /*
3
+ Copyright (c) 2025 Bernier LLC
4
+
5
+ This file is licensed to the client under a limited-use license.
6
+ The client may use and modify this code *only within the scope of the project it was delivered for*.
7
+ Redistribution or use in other products or commercial offerings is not permitted without written consent from Bernier LLC.
8
+ */
9
+ Object.defineProperty(exports, "__esModule", { value: true });
10
+ exports.OperatorRegistry = void 0;
11
+ const nevar_types_1 = require("@bernierllc/nevar-types");
12
+ const built_in_operators_1 = require("./built-in-operators");
13
+ /**
14
+ * Registry for managing built-in and custom operators.
15
+ * Provides registration, lookup, discovery, and evaluation capabilities.
16
+ */
17
+ class OperatorRegistry {
18
+ operators = new Map();
19
+ constructor() {
20
+ // Pre-register all 12 built-in operators
21
+ for (const [name, definition] of Object.entries(built_in_operators_1.builtInOperators)) {
22
+ this.operators.set(name, definition);
23
+ }
24
+ }
25
+ /**
26
+ * Register a new operator. Throws NevarValidationError on duplicate name.
27
+ */
28
+ register(name, definition) {
29
+ if (this.operators.has(name)) {
30
+ throw new nevar_types_1.NevarValidationError(`Operator "${name}" is already registered`, { code: 'OPERATOR_DUPLICATE', context: { name } });
31
+ }
32
+ this.operators.set(name, definition);
33
+ }
34
+ /**
35
+ * Get an operator definition by name.
36
+ */
37
+ get(name) {
38
+ return this.operators.get(name);
39
+ }
40
+ /**
41
+ * Check if an operator is registered.
42
+ */
43
+ has(name) {
44
+ return this.operators.has(name);
45
+ }
46
+ /**
47
+ * List all registered operators as serializable OperatorInfo objects.
48
+ * Excludes the evaluate function.
49
+ */
50
+ list() {
51
+ const result = [];
52
+ for (const [name, def] of this.operators) {
53
+ result.push({
54
+ name,
55
+ label: def.label,
56
+ category: def.category,
57
+ fieldTypes: def.fieldTypes,
58
+ });
59
+ }
60
+ return result;
61
+ }
62
+ /**
63
+ * Get all operators in a given category.
64
+ */
65
+ getByCategory(category) {
66
+ return this.list().filter((op) => op.category === category);
67
+ }
68
+ /**
69
+ * Evaluate a field value against a target value using the named operator.
70
+ * Throws NevarEvaluationError for unknown operators.
71
+ */
72
+ evaluate(name, fieldValue, targetValue) {
73
+ const definition = this.operators.get(name);
74
+ if (!definition) {
75
+ throw new nevar_types_1.NevarEvaluationError(`Unknown operator "${name}"`, { code: 'OPERATOR_NOT_FOUND', context: { name } });
76
+ }
77
+ return definition.evaluate(fieldValue, targetValue);
78
+ }
79
+ }
80
+ exports.OperatorRegistry = OperatorRegistry;
package/package.json CHANGED
@@ -1,10 +1,39 @@
1
1
  {
2
2
  "name": "@bernierllc/nevar-operator-registry",
3
- "version": "0.0.1",
4
- "description": "OIDC trusted publishing setup package for @bernierllc/nevar-operator-registry",
5
- "keywords": [
6
- "oidc",
7
- "trusted-publishing",
8
- "setup"
9
- ]
10
- }
3
+ "version": "0.1.0",
4
+ "description": "Operator registry with 12 built-in operators for the Nevar rules engine",
5
+ "main": "dist/index.js",
6
+ "types": "dist/index.d.ts",
7
+ "files": [
8
+ "dist/**/*",
9
+ "README.md",
10
+ "LICENSE"
11
+ ],
12
+ "author": "Bernier LLC",
13
+ "license": "SEE LICENSE IN LICENSE",
14
+ "publishConfig": {
15
+ "access": "public",
16
+ "registry": "https://registry.npmjs.org/"
17
+ },
18
+ "engines": {
19
+ "node": ">=16.0.0"
20
+ },
21
+ "repository": {
22
+ "type": "git",
23
+ "url": "git+https://github.com/bernierllc/tools.git",
24
+ "directory": "packages/core/nevar-operator-registry"
25
+ },
26
+ "dependencies": {
27
+ "zod": "^3.22.0",
28
+ "@bernierllc/nevar-types": "0.1.0"
29
+ },
30
+ "scripts": {
31
+ "build": "tsc",
32
+ "prebuild": "npm run clean",
33
+ "clean": "rimraf dist",
34
+ "test": "jest --watch",
35
+ "test:run": "jest",
36
+ "test:coverage": "jest --coverage",
37
+ "lint": "eslint src __tests__ --ext .ts"
38
+ }
39
+ }