@nexussdk/contracts 0.0.1 → 0.0.4

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/src/auth.ts DELETED
@@ -1,224 +0,0 @@
1
- /**
2
- * @fileoverview Authentication, Organization, Project, and API Key contracts.
3
- * Governs multi-tenant B2B2C security and quota boundaries.
4
- * @module @nexus/contracts/auth
5
- */
6
-
7
- /**
8
- * Subscription plan tiers determining rate limits and feature entitlements.
9
- * @example
10
- * const tier: PlanTier = 'PRO';
11
- */
12
- export type PlanTier = 'FREE' | 'PRO' | 'ENTERPRISE';
13
-
14
- /**
15
- * Operational status of a tenant account.
16
- * @example
17
- * const status: AccountStatus = 'ACTIVE';
18
- */
19
- export type AccountStatus = 'ACTIVE' | 'SUSPENDED' | 'CANCELLED';
20
-
21
- /**
22
- * Deployment environments for project isolation.
23
- * @example
24
- * const env: Environment = 'production';
25
- */
26
- export type Environment = 'development' | 'staging' | 'production';
27
-
28
- /**
29
- * Cryptographic API Key permission scope.
30
- * - `PUBLIC`: Embedded in client browsers. Permitted only for flag evaluation,
31
- * SSE subscriptions, and error ingestion.
32
- * - `SECRET`: Secure server-side only. Full administrative CRUD operations.
33
- * @example
34
- * const keyType: ApiKeyType = 'PUBLIC';
35
- */
36
- export type ApiKeyType = 'PUBLIC' | 'SECRET';
37
-
38
- /**
39
- * Represents a developer or organization account (Tenant).
40
- *
41
- * @example
42
- * const account: Account = {
43
- * id: 'uuid-v4',
44
- * name: 'Acme Corp',
45
- * email: 'admin@acme.com',
46
- * planTier: 'PRO',
47
- * status: 'ACTIVE',
48
- * createdAt: '2024-01-01T00:00:00Z',
49
- * updatedAt: '2024-06-01T00:00:00Z',
50
- * };
51
- */
52
- export interface Account {
53
- /** Unique UUID v4 identifier. */
54
- id: string;
55
- /** Organization or developer display name. */
56
- name: string;
57
- /** Primary contact and authentication email. */
58
- email: string;
59
- /** Current billing entitlement tier. */
60
- planTier: PlanTier;
61
- /** Current operational state. */
62
- status: AccountStatus;
63
- /** Arbitrary organizational metadata. */
64
- metadata?: Record<string, unknown>;
65
- /** Timestamp when account was created. */
66
- createdAt: string;
67
- /** Timestamp when account was last modified. */
68
- updatedAt: string;
69
- }
70
-
71
- /**
72
- * Represents an isolated application owned by an Account.
73
- *
74
- * @example
75
- * const project: Project = {
76
- * id: 'uuid-v4',
77
- * accountId: 'account-uuid-v4',
78
- * name: 'My App',
79
- * slug: 'my-app',
80
- * createdAt: '2024-01-01T00:00:00Z',
81
- * updatedAt: '2024-06-01T00:00:00Z',
82
- * };
83
- */
84
- export interface Project {
85
- /** Unique UUID v4 identifier. */
86
- id: string;
87
- /** Owning Account UUID v4 identifier. */
88
- accountId: string;
89
- /** Human-readable project name. */
90
- name: string;
91
- /** URL-friendly unique slug under the parent account. */
92
- slug: string;
93
- /** Project description. */
94
- description?: string;
95
- /** Timestamp of project creation. */
96
- createdAt: string;
97
- /** Timestamp of last modification. */
98
- updatedAt: string;
99
- }
100
-
101
- /**
102
- * Public or Secret API Key metadata used by Go-Gin and NestJS guards.
103
- *
104
- * @example
105
- * const apiKey: ApiKey = {
106
- * id: 'uuid-v4',
107
- * projectId: 'project-uuid-v4',
108
- * environment: 'production',
109
- * keyType: 'PUBLIC',
110
- * keyPrefix: 'pk_live_a1b2',
111
- * keyHash: 'sha256hexstring...',
112
- * allowedDomains: ['https://mybrand.com'],
113
- * rateLimitPerMin: 1000,
114
- * monthlyEventsLimit: 100000,
115
- * currentMonthUsage: 4250,
116
- * usageResetAt: '2024-07-01T00:00:00Z',
117
- * isActive: true,
118
- * createdAt: '2024-01-01T00:00:00Z',
119
- * };
120
- */
121
- export interface ApiKey {
122
- /** Unique UUID v4 identifier. */
123
- id: string;
124
- /** Parent Project identifier. */
125
- projectId: string;
126
- /** Target deployment environment. */
127
- environment: Environment;
128
- /** Key capability level. */
129
- keyType: ApiKeyType;
130
- /** Public preview prefix (e.g. "pk_live_abcd1234"). Raw secret is never persisted. */
131
- keyPrefix: string;
132
- /** SHA-256 hash string (64 chars) matching stored database records. */
133
- keyHash: string;
134
- /** Whitelisted Origin domains for browser CORS security (e.g. ["https://mybrand.com"]). */
135
- allowedDomains: string[];
136
- /** Maximum allowed HTTP requests per minute. */
137
- rateLimitPerMin: number;
138
- /** Hard cap for error and event ingestion per calendar month. */
139
- monthlyEventsLimit: number;
140
- /** Current count of events processed in the active billing window. */
141
- currentMonthUsage: number;
142
- /** Timestamp when the current billing usage cycle resets. */
143
- usageResetAt: string;
144
- /** Flag toggle allowing immediate key revocation. */
145
- isActive: boolean;
146
- /** Timestamp when the key was last used in any API request. */
147
- lastUsedAt?: string;
148
- /** Creation timestamp. */
149
- createdAt: string;
150
- }
151
-
152
- /**
153
- * Payload returned to the developer upon key generation.
154
- * This is the ONLY time the raw token is made visible.
155
- *
156
- * @example
157
- * const response: GeneratedApiKeyResponse = {
158
- * apiKey: { ... },
159
- * rawKey: 'pk_live_a1b2c3d4e5f6...',
160
- * };
161
- */
162
- export interface GeneratedApiKeyResponse {
163
- /** Public or Secret key metadata entity. */
164
- apiKey: ApiKey;
165
- /**
166
- * Plaintext unhashed API key string (e.g., 'pk_live_a1b2c3...').
167
- * Must be securely copied by developer; cannot be recovered after this response.
168
- */
169
- rawKey: string;
170
- }
171
-
172
- /**
173
- * DTO for account registration requests.
174
- *
175
- * @example
176
- * const dto: RegisterAccountDto = {
177
- * name: 'Acme Corp',
178
- * email: 'admin@acme.com',
179
- * password: 'S3cur3P@ssw0rd!',
180
- * };
181
- */
182
- export interface RegisterAccountDto {
183
- /** Organization display name. */
184
- name: string;
185
- /** Primary contact email. */
186
- email: string;
187
- /** Plaintext password (hashed server-side with bcrypt). */
188
- password: string;
189
- }
190
-
191
- /**
192
- * DTO for login requests.
193
- *
194
- * @example
195
- * const dto: LoginDto = {
196
- * email: 'admin@acme.com',
197
- * password: 'S3cur3P@ssw0rd!',
198
- * };
199
- */
200
- export interface LoginDto {
201
- /** Registered email address. */
202
- email: string;
203
- /** Plaintext password to verify against stored bcrypt hash. */
204
- password: string;
205
- }
206
-
207
- /**
208
- * Session payload embedded in JWT and HttpOnly cookies.
209
- *
210
- * @example
211
- * const session: SessionPayload = {
212
- * accountId: 'uuid-v4',
213
- * email: 'admin@acme.com',
214
- * planTier: 'PRO',
215
- * };
216
- */
217
- export interface SessionPayload {
218
- /** Authenticated account's UUID. */
219
- accountId: string;
220
- /** Authenticated account's email. */
221
- email: string;
222
- /** Plan tier for feature entitlement checks. */
223
- planTier: PlanTier;
224
- }
package/src/flags.ts DELETED
@@ -1,255 +0,0 @@
1
- /**
2
- * @fileoverview Feature Flagging, Dynamic Configuration, and ABAC Targeting contracts.
3
- * @module @nexus/contracts/flags
4
- */
5
-
6
- import type { Environment } from './auth.js';
7
-
8
- /**
9
- * Attribute evaluation operators for Attribute-Based Access Control (ABAC).
10
- * Used in {@link TargetingRule} to compare user context values against flag targets.
11
- *
12
- * @example
13
- * const op: RuleOperator = 'IN';
14
- */
15
- export type RuleOperator =
16
- | 'EQUALS'
17
- | 'NOT_EQUALS'
18
- | 'CONTAINS'
19
- | 'NOT_CONTAINS'
20
- | 'IN'
21
- | 'NOT_IN'
22
- | 'STARTS_WITH'
23
- | 'ENDS_WITH'
24
- | 'GREATER_THAN'
25
- | 'LESS_THAN'
26
- | 'SEMVER_GTE'
27
- | 'SEMVER_LTE';
28
-
29
- /**
30
- * Atomic rule evaluating a single user attribute against target values.
31
- *
32
- * @example
33
- * const rule: TargetingRule = {
34
- * attribute: 'country',
35
- * operator: 'IN',
36
- * values: ['VN', 'SG', 'TH'],
37
- * };
38
- */
39
- export interface TargetingRule {
40
- /** Attribute path in UserContext (e.g. "country", "tier", "appVersion"). */
41
- attribute: string;
42
- /** Logical operator applied to the attribute. */
43
- operator: RuleOperator;
44
- /** Comparison targets (strings, numbers, or arrays). */
45
- values: Array<string | number | boolean>;
46
- }
47
-
48
- /**
49
- * Primitive types permissible inside dynamic configuration variants.
50
- */
51
- export type VariantValue = string | number | boolean | Record<string, unknown> | unknown[];
52
-
53
- /**
54
- * Remote Configuration variants dictionary.
55
- *
56
- * @example
57
- * const variants: FlagVariants = {
58
- * button_color: '#FF0055',
59
- * max_items: 25,
60
- * theme: 'dark',
61
- * };
62
- */
63
- export type FlagVariants = Record<string, VariantValue>;
64
-
65
- /**
66
- * Represents a Feature Flag entity stored in the platform.
67
- *
68
- * @example
69
- * const flag: FeatureFlag = {
70
- * id: 'uuid-v4',
71
- * projectId: 'project-uuid',
72
- * environment: 'production',
73
- * key: 'checkout_v2',
74
- * name: 'Checkout Redesign V2',
75
- * isEnabled: true,
76
- * rolloutPercentage: 50,
77
- * targetingRules: [],
78
- * variants: { show_express: true },
79
- * version: 3,
80
- * createdAt: '2024-01-01T00:00:00Z',
81
- * updatedAt: '2024-06-01T00:00:00Z',
82
- * };
83
- */
84
- export interface FeatureFlag {
85
- /** Unique UUID v4 identifier. */
86
- id: string;
87
- /** Owning Project UUID v4 identifier. */
88
- projectId: string;
89
- /** Deployment environment. */
90
- environment: Environment;
91
- /** Unique programmatic identifier (e.g. "checkout_v2"). */
92
- key: string;
93
- /** Human-readable flag name. */
94
- name: string;
95
- /** Optional purpose explanation. */
96
- description?: string;
97
- /** Master kill-switch. When false, flag immediately resolves to fallback/false. */
98
- isEnabled: boolean;
99
- /**
100
- * Percentage rollout integer (0 to 100).
101
- * Computed deterministically via MurmurHash3(userId + flagKey).
102
- */
103
- rolloutPercentage: number;
104
- /** Ordered list of targeting rules. Must satisfy all rules for flag to apply. */
105
- targetingRules: TargetingRule[];
106
- /** Remote dynamic configuration key-value pairs attached to this flag. */
107
- variants: FlagVariants;
108
- /** Monotonically increasing schema version for cache invalidation. */
109
- version: number;
110
- /** Creation timestamp. */
111
- createdAt: string;
112
- /** Last modification timestamp. */
113
- updatedAt: string;
114
- }
115
-
116
- /**
117
- * End-user contextual data supplied by Client SDK for rule evaluation.
118
- *
119
- * @example
120
- * const user: UserContext = {
121
- * id: 'usr_12345',
122
- * email: 'john@example.com',
123
- * country: 'VN',
124
- * appVersion: '2.4.1',
125
- * custom: { tier: 'premium', vipMember: true },
126
- * };
127
- */
128
- export interface UserContext {
129
- /**
130
- * Unique user identifier (e.g. "usr_12345").
131
- * Crucial for consistent percentage rollout bucketing.
132
- * If omitted, SDK must fallback to anonymous persistent device UUID.
133
- */
134
- id?: string;
135
- /** User email (commonly used for beta targeting). */
136
- email?: string;
137
- /** Two-letter ISO country code (e.g. "VN", "US"). */
138
- country?: string;
139
- /** Client application version (e.g. "2.4.1") for semver targeting. */
140
- appVersion?: string;
141
- /** Arbitrary custom attributes for ABAC rules. */
142
- custom?: Record<string, string | number | boolean>;
143
- }
144
-
145
- /**
146
- * Evaluation output generated for a single flag.
147
- *
148
- * @example
149
- * const result: FlagEvaluationResult = {
150
- * key: 'checkout_v2',
151
- * enabled: true,
152
- * variants: { show_express: true },
153
- * reason: 'ROLLOUT_MATCH',
154
- * version: 3,
155
- * };
156
- */
157
- export interface FlagEvaluationResult {
158
- /** Flag unique key. */
159
- key: string;
160
- /** Final boolean active status. */
161
- enabled: boolean;
162
- /** Selected dynamic configuration variants (empty if disabled). */
163
- variants: FlagVariants;
164
- /** Explanation string of evaluation outcome. */
165
- reason: 'TARGETING_MATCH' | 'ROLLOUT_MATCH' | 'DEFAULT_ENABLED' | 'KILL_SWITCH' | 'FALLBACK';
166
- /** Schema version of the flag when evaluated. */
167
- version: number;
168
- }
169
-
170
- /**
171
- * Map of multiple evaluated flags returned in single batch request.
172
- *
173
- * @example
174
- * const batch: BatchFlagEvaluation = {
175
- * checkout_v2: { key: 'checkout_v2', enabled: true, variants: {}, reason: 'ROLLOUT_MATCH', version: 1 },
176
- * dark_mode: { key: 'dark_mode', enabled: false, variants: {}, reason: 'KILL_SWITCH', version: 2 },
177
- * };
178
- */
179
- export type BatchFlagEvaluation = Record<string, FlagEvaluationResult>;
180
-
181
- /**
182
- * Real-time SSE payload pushed from Go-Gin to Client SDKs when a flag is updated.
183
- *
184
- * @example
185
- * const event: FlagStreamEvent = {
186
- * type: 'FLAG_UPDATE',
187
- * key: 'checkout_v2',
188
- * data: { key: 'checkout_v2', enabled: true, variants: {}, reason: 'DEFAULT_ENABLED', version: 4 },
189
- * timestamp: 1704067200000,
190
- * };
191
- */
192
- export interface FlagStreamEvent {
193
- /** Event classification. */
194
- type: 'FLAG_UPDATE' | 'FLAG_DELETE' | 'HEARTBEAT';
195
- /** Flag key modified. */
196
- key: string;
197
- /** Fresh evaluation payload or null on deletion. */
198
- data?: FlagEvaluationResult;
199
- /** Server timestamp of dispatch in milliseconds epoch. */
200
- timestamp: number;
201
- }
202
-
203
- /**
204
- * DTO for creating a new feature flag.
205
- *
206
- * @example
207
- * const dto: CreateFlagDto = {
208
- * key: 'new_checkout',
209
- * name: 'New Checkout',
210
- * environment: 'development',
211
- * rolloutPercentage: 0,
212
- * variants: {},
213
- * targetingRules: [],
214
- * };
215
- */
216
- export interface CreateFlagDto {
217
- /** Unique programmatic identifier. */
218
- key: string;
219
- /** Human-readable display name. */
220
- name: string;
221
- /** Target environment. */
222
- environment: Environment;
223
- /** Optional description. */
224
- description?: string;
225
- /** Initial rollout percentage. */
226
- rolloutPercentage: number;
227
- /** Initial variants. */
228
- variants: FlagVariants;
229
- /** Initial targeting rules. */
230
- targetingRules: TargetingRule[];
231
- }
232
-
233
- /**
234
- * DTO for updating an existing feature flag (all fields optional).
235
- *
236
- * @example
237
- * const dto: UpdateFlagDto = {
238
- * isEnabled: true,
239
- * rolloutPercentage: 75,
240
- * };
241
- */
242
- export interface UpdateFlagDto {
243
- /** Optional new display name. */
244
- name?: string;
245
- /** Optional new description. */
246
- description?: string;
247
- /** Toggle kill-switch state. */
248
- isEnabled?: boolean;
249
- /** New rollout percentage (0–100). */
250
- rolloutPercentage?: number;
251
- /** Updated targeting rules array. */
252
- targetingRules?: TargetingRule[];
253
- /** Updated variants map. */
254
- variants?: FlagVariants;
255
- }
package/src/index.ts DELETED
@@ -1,12 +0,0 @@
1
- /**
2
- * @fileoverview Main entry point for @nexussdk/contracts.
3
- * Re-exports all contract modules: flags, tracker, auth, and RFC 7807 problem details.
4
- *
5
- * @example
6
- * import { FeatureFlag, ProblemDetails, ErrorEventPayload } from '@nexussdk/contracts';
7
- */
8
-
9
- export * from './auth.js';
10
- export * from './flags.js';
11
- export * from './tracker.js';
12
- export * from './rfc7807.js';
package/src/rfc7807.ts DELETED
@@ -1,76 +0,0 @@
1
- /**
2
- * @fileoverview Problem Details for HTTP APIs Specification (RFC 7807).
3
- * Standardized error format across Go-Gin and NestJS error responses.
4
- * @see {@link https://www.rfc-editor.org/rfc/rfc7807}
5
- * @module @nexus/contracts/rfc7807
6
- */
7
-
8
- /**
9
- * RFC 7807 Compliant Error Schema.
10
- * Ensures consistent machine-readable error diagnostics across all Nexus services.
11
- *
12
- * @example
13
- * const problem: ProblemDetails = {
14
- * type: 'https://nexus.dev/errors/quota-exceeded',
15
- * title: 'Monthly Quota Exceeded',
16
- * status: 429,
17
- * detail: "API Key 'pk_live_...' has exhausted its limit of 50,000 monthly events.",
18
- * instance: '/api/v1/telemetry/errors',
19
- * timestamp: '2024-06-01T12:00:00Z',
20
- * };
21
- */
22
- export interface ProblemDetails {
23
- /**
24
- * URI reference identifying the problem type.
25
- * Should be a stable, documented URI that clients can bookmark.
26
- * @example 'https://nexus.dev/errors/rate-limit-exceeded'
27
- */
28
- type: string;
29
- /**
30
- * Short, human-readable summary of problem type.
31
- * Must be invariant across occurrences of the same problem type.
32
- * @example 'Too Many Requests'
33
- */
34
- title: string;
35
- /**
36
- * HTTP status code generated by origin server.
37
- * @example 429
38
- */
39
- status: number;
40
- /**
41
- * Human-readable explanation specific to this occurrence of the problem.
42
- * May differ across occurrences of the same problem type.
43
- * @example "API Key 'pk_live_a1b2...' has exhausted its monthly event limit."
44
- */
45
- detail: string;
46
- /**
47
- * URI reference identifying specific occurrence of problem.
48
- * Typically the request path that triggered the error.
49
- * @example '/api/v1/telemetry/errors'
50
- */
51
- instance?: string;
52
- /**
53
- * Additional diagnostic error parameters for validation failures.
54
- * @example [{ name: 'email', reason: 'Must be a valid email address.' }]
55
- */
56
- invalidParams?: Array<{
57
- /** Field name that caused the validation error. */
58
- name: string;
59
- /** Human-readable reason for the validation failure. */
60
- reason: string;
61
- }>;
62
- /**
63
- * ISO 8601 timestamp when error was produced.
64
- * @example '2024-06-01T12:00:00.000Z'
65
- */
66
- timestamp?: string;
67
- }
68
-
69
- /**
70
- * Standard Nexus error type URI prefix.
71
- * All RFC 7807 type values should use this base to ensure namespacing consistency.
72
- *
73
- * @example
74
- * const type = `${NEXUS_ERROR_BASE}/rate-limit-exceeded`;
75
- */
76
- export const NEXUS_ERROR_BASE = 'https://nexus.dev/errors' as const;