@beignet/core 0.0.12 → 0.0.14
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/CHANGELOG.md +21 -0
- package/README.md +159 -9
- package/dist/client/client.d.ts.map +1 -1
- package/dist/client/client.js +29 -1
- package/dist/client/client.js.map +1 -1
- package/dist/entitlements/index.d.ts +234 -0
- package/dist/entitlements/index.d.ts.map +1 -0
- package/dist/entitlements/index.js +172 -0
- package/dist/entitlements/index.js.map +1 -0
- package/dist/error-reporting/index.d.ts +131 -0
- package/dist/error-reporting/index.d.ts.map +1 -0
- package/dist/error-reporting/index.js +112 -0
- package/dist/error-reporting/index.js.map +1 -0
- package/dist/flags/index.d.ts +293 -0
- package/dist/flags/index.d.ts.map +1 -0
- package/dist/flags/index.js +204 -0
- package/dist/flags/index.js.map +1 -0
- package/dist/locks/index.d.ts +155 -0
- package/dist/locks/index.d.ts.map +1 -0
- package/dist/locks/index.js +248 -0
- package/dist/locks/index.js.map +1 -0
- package/dist/payments/index.d.ts +430 -0
- package/dist/payments/index.d.ts.map +1 -0
- package/dist/payments/index.js +230 -0
- package/dist/payments/index.js.map +1 -0
- package/dist/ports/index.d.ts +61 -1
- package/dist/ports/index.d.ts.map +1 -1
- package/dist/ports/index.js +33 -0
- package/dist/ports/index.js.map +1 -1
- package/dist/ports/policy.d.ts +104 -0
- package/dist/ports/policy.d.ts.map +1 -1
- package/dist/ports/policy.js +102 -7
- package/dist/ports/policy.js.map +1 -1
- package/dist/search/index.d.ts +175 -0
- package/dist/search/index.d.ts.map +1 -0
- package/dist/search/index.js +344 -0
- package/dist/search/index.js.map +1 -0
- package/dist/server/server.d.ts.map +1 -1
- package/dist/server/server.js +9 -1
- package/dist/server/server.js.map +1 -1
- package/dist/testing/index.d.ts +46 -1
- package/dist/testing/index.d.ts.map +1 -1
- package/dist/testing/index.js +33 -1
- package/dist/testing/index.js.map +1 -1
- package/package.json +25 -1
- package/src/client/client.ts +33 -1
- package/src/entitlements/index.ts +479 -0
- package/src/error-reporting/index.ts +273 -0
- package/src/flags/index.ts +608 -0
- package/src/locks/index.ts +440 -0
- package/src/payments/index.ts +699 -0
- package/src/ports/index.ts +194 -0
- package/src/ports/policy.ts +272 -7
- package/src/search/index.ts +632 -0
- package/src/server/server.ts +15 -0
- package/src/testing/index.ts +83 -1
package/dist/ports/policy.js
CHANGED
|
@@ -71,6 +71,7 @@ export function definePolicy(policies) {
|
|
|
71
71
|
*/
|
|
72
72
|
export function createGate(options) {
|
|
73
73
|
const registry = new Map();
|
|
74
|
+
const observeDecision = createDecisionObserver(options.onDecision);
|
|
74
75
|
for (const definition of options.policies) {
|
|
75
76
|
for (const [ability, resolver] of Object.entries(definition.policies)) {
|
|
76
77
|
if (registry.has(ability)) {
|
|
@@ -79,28 +80,73 @@ export function createGate(options) {
|
|
|
79
80
|
registry.set(ability, resolver);
|
|
80
81
|
}
|
|
81
82
|
}
|
|
82
|
-
async function
|
|
83
|
+
async function evaluate(ctx, ability, subject, source = "inspect", batchKey) {
|
|
84
|
+
const startedAt = policyNow();
|
|
83
85
|
const resolver = registry.get(ability);
|
|
84
86
|
if (!resolver) {
|
|
85
|
-
|
|
87
|
+
const decision = deny({
|
|
86
88
|
reason: `No policy registered for "${ability}".`,
|
|
87
89
|
code: "POLICY_NOT_FOUND",
|
|
88
90
|
});
|
|
91
|
+
observeDecision({
|
|
92
|
+
source,
|
|
93
|
+
batchKey,
|
|
94
|
+
ctx,
|
|
95
|
+
ability,
|
|
96
|
+
subject,
|
|
97
|
+
decision,
|
|
98
|
+
durationMs: policyNow() - startedAt,
|
|
99
|
+
});
|
|
100
|
+
return decision;
|
|
101
|
+
}
|
|
102
|
+
try {
|
|
103
|
+
const result = await resolver(ctx, subject);
|
|
104
|
+
const decision = normalizeDecision(result);
|
|
105
|
+
observeDecision({
|
|
106
|
+
source,
|
|
107
|
+
batchKey,
|
|
108
|
+
ctx,
|
|
109
|
+
ability,
|
|
110
|
+
subject,
|
|
111
|
+
decision,
|
|
112
|
+
durationMs: policyNow() - startedAt,
|
|
113
|
+
});
|
|
114
|
+
return decision;
|
|
115
|
+
}
|
|
116
|
+
catch (error) {
|
|
117
|
+
observeDecision({
|
|
118
|
+
source,
|
|
119
|
+
batchKey,
|
|
120
|
+
ctx,
|
|
121
|
+
ability,
|
|
122
|
+
subject,
|
|
123
|
+
error,
|
|
124
|
+
durationMs: policyNow() - startedAt,
|
|
125
|
+
});
|
|
126
|
+
throw error;
|
|
89
127
|
}
|
|
90
|
-
const result = await resolver(ctx, subject);
|
|
91
|
-
return normalizeDecision(result);
|
|
92
128
|
}
|
|
93
129
|
async function authorize(ctx, ability, subject) {
|
|
94
|
-
const decision = await
|
|
130
|
+
const decision = await evaluate(ctx, ability, subject, "authorize");
|
|
95
131
|
if (decision.allowed)
|
|
96
132
|
return decision;
|
|
97
133
|
const thrown = await options.onDeny?.(decision, { ctx, ability, subject });
|
|
98
134
|
throw thrown ?? new GateAuthorizationError(decision);
|
|
99
135
|
}
|
|
136
|
+
async function inspectMany(ctx, checks, source) {
|
|
137
|
+
const decisions = {};
|
|
138
|
+
for (const [batchKey, check] of Object.entries(checks)) {
|
|
139
|
+
const [ability, subject] = check;
|
|
140
|
+
decisions[batchKey] = await evaluate(ctx, ability, subject, source, batchKey);
|
|
141
|
+
}
|
|
142
|
+
return decisions;
|
|
143
|
+
}
|
|
100
144
|
function bind(ctx) {
|
|
101
145
|
return {
|
|
102
146
|
can: async (ability, ...subject) => gate.can(ctx, ability, ...subject),
|
|
147
|
+
canMany: async (checks) => gate.canMany(ctx, checks),
|
|
103
148
|
inspect: async (ability, ...subject) => gate.inspect(ctx, ability, ...subject),
|
|
149
|
+
inspectMany: async (checks) => gate.inspectMany(ctx, checks),
|
|
104
150
|
authorize: async (ability, ...subject) => gate.authorize(ctx, ability, ...subject),
|
|
105
151
|
};
|
|
106
152
|
}
|
|
@@ -118,9 +164,19 @@ export function createGate(options) {
|
|
|
118
164
|
bind,
|
|
119
165
|
attach,
|
|
120
166
|
async can(ctx, ability, ...subject) {
|
|
121
|
-
return (await
|
|
167
|
+
return (await evaluate(ctx, ability, firstSubject(subject), "can"))
|
|
168
|
+
.allowed;
|
|
169
|
+
},
|
|
170
|
+
async canMany(ctx, checks) {
|
|
171
|
+
const decisions = await inspectMany(ctx, checks, "canMany");
|
|
172
|
+
const result = {};
|
|
173
|
+
for (const [key, decision] of Object.entries(decisions)) {
|
|
174
|
+
result[key] = decision.allowed;
|
|
175
|
+
}
|
|
176
|
+
return result;
|
|
122
177
|
},
|
|
123
|
-
inspect: async (ctx, ability, ...subject) =>
|
|
178
|
+
inspect: async (ctx, ability, ...subject) => evaluate(ctx, ability, firstSubject(subject), "inspect"),
|
|
179
|
+
inspectMany: async (ctx, checks) => inspectMany(ctx, checks, "inspectMany"),
|
|
124
180
|
authorize: async (ctx, ability, ...subject) => authorize(ctx, ability, firstSubject(subject)),
|
|
125
181
|
};
|
|
126
182
|
return gate;
|
|
@@ -134,4 +190,43 @@ function normalizeDecision(result) {
|
|
|
134
190
|
function firstSubject(subject) {
|
|
135
191
|
return subject[0];
|
|
136
192
|
}
|
|
193
|
+
function policyNow() {
|
|
194
|
+
return typeof performance !== "undefined" ? performance.now() : Date.now();
|
|
195
|
+
}
|
|
196
|
+
function contextStringField(ctx, field) {
|
|
197
|
+
if (!ctx || typeof ctx !== "object")
|
|
198
|
+
return undefined;
|
|
199
|
+
const value = ctx[field];
|
|
200
|
+
return typeof value === "string" ? value : undefined;
|
|
201
|
+
}
|
|
202
|
+
function enrichObservation(observation) {
|
|
203
|
+
return {
|
|
204
|
+
...observation,
|
|
205
|
+
requestId: contextStringField(observation.ctx, "requestId"),
|
|
206
|
+
traceId: contextStringField(observation.ctx, "traceId"),
|
|
207
|
+
spanId: contextStringField(observation.ctx, "spanId"),
|
|
208
|
+
parentSpanId: contextStringField(observation.ctx, "parentSpanId"),
|
|
209
|
+
traceparent: contextStringField(observation.ctx, "traceparent"),
|
|
210
|
+
};
|
|
211
|
+
}
|
|
212
|
+
function isPromiseLike(value) {
|
|
213
|
+
return (value !== null &&
|
|
214
|
+
(typeof value === "object" || typeof value === "function") &&
|
|
215
|
+
typeof value.then === "function");
|
|
216
|
+
}
|
|
217
|
+
function createDecisionObserver(observer) {
|
|
218
|
+
return (observation) => {
|
|
219
|
+
if (!observer)
|
|
220
|
+
return;
|
|
221
|
+
try {
|
|
222
|
+
const result = observer(enrichObservation(observation));
|
|
223
|
+
if (isPromiseLike(result)) {
|
|
224
|
+
Promise.resolve(result).catch(() => undefined);
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
catch {
|
|
228
|
+
// Observers are diagnostic only and must not affect authorization.
|
|
229
|
+
}
|
|
230
|
+
};
|
|
231
|
+
}
|
|
137
232
|
//# sourceMappingURL=policy.js.map
|
package/dist/ports/policy.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"policy.js","sourceRoot":"","sources":["../../src/ports/policy.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"policy.js","sourceRoot":"","sources":["../../src/ports/policy.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,175 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @beignet/core/search
|
|
3
|
+
*
|
|
4
|
+
* Provider-neutral search primitives for Beignet applications.
|
|
5
|
+
*/
|
|
6
|
+
/**
|
|
7
|
+
* Primitive values accepted in indexed documents and provider-neutral filters.
|
|
8
|
+
*/
|
|
9
|
+
export type SearchPrimitive = null | boolean | number | string;
|
|
10
|
+
/**
|
|
11
|
+
* JSON-like values accepted in indexed documents.
|
|
12
|
+
*/
|
|
13
|
+
export type SearchValue = SearchPrimitive | readonly SearchValue[] | {
|
|
14
|
+
readonly [key: string]: SearchValue;
|
|
15
|
+
};
|
|
16
|
+
/**
|
|
17
|
+
* Minimal document shape accepted by search indexes.
|
|
18
|
+
*/
|
|
19
|
+
export type SearchDocumentBase = {
|
|
20
|
+
id: string;
|
|
21
|
+
};
|
|
22
|
+
/**
|
|
23
|
+
* General search document shape.
|
|
24
|
+
*/
|
|
25
|
+
export type SearchDocument = SearchDocumentBase & {
|
|
26
|
+
readonly [field: string]: SearchValue | undefined;
|
|
27
|
+
};
|
|
28
|
+
type SearchField<TDocument extends SearchDocumentBase> = Extract<keyof TDocument, string>;
|
|
29
|
+
/**
|
|
30
|
+
* Provider-neutral index definition.
|
|
31
|
+
*/
|
|
32
|
+
export type SearchIndexDef<TDocument extends SearchDocumentBase = SearchDocument> = {
|
|
33
|
+
name: string;
|
|
34
|
+
primaryKey: SearchField<TDocument>;
|
|
35
|
+
searchableAttributes?: readonly SearchField<TDocument>[];
|
|
36
|
+
filterableAttributes?: readonly SearchField<TDocument>[];
|
|
37
|
+
sortableAttributes?: readonly SearchField<TDocument>[];
|
|
38
|
+
displayedAttributes?: readonly SearchField<TDocument>[];
|
|
39
|
+
metadata?: Record<string, unknown>;
|
|
40
|
+
};
|
|
41
|
+
/**
|
|
42
|
+
* Options accepted when defining a search index.
|
|
43
|
+
*/
|
|
44
|
+
export type DefineSearchIndexOptions<TDocument extends SearchDocumentBase> = Omit<SearchIndexDef<TDocument>, "name" | "primaryKey"> & {
|
|
45
|
+
primaryKey?: SearchField<TDocument>;
|
|
46
|
+
};
|
|
47
|
+
/**
|
|
48
|
+
* Provider-neutral filter values.
|
|
49
|
+
*/
|
|
50
|
+
export type SearchFilterValue = SearchPrimitive | readonly Exclude<SearchPrimitive, null>[];
|
|
51
|
+
/**
|
|
52
|
+
* Provider-neutral exact-match filters.
|
|
53
|
+
*/
|
|
54
|
+
export type SearchFilters = Record<string, SearchFilterValue>;
|
|
55
|
+
/**
|
|
56
|
+
* Provider-neutral sort expression. Use `field:asc` or `field:desc`.
|
|
57
|
+
*/
|
|
58
|
+
export type SearchSort = `${string}:asc` | `${string}:desc` | (string & {});
|
|
59
|
+
/**
|
|
60
|
+
* Query accepted by search providers.
|
|
61
|
+
*/
|
|
62
|
+
export type SearchQuery = {
|
|
63
|
+
query?: string;
|
|
64
|
+
filters?: SearchFilters;
|
|
65
|
+
sort?: readonly SearchSort[];
|
|
66
|
+
facets?: readonly string[];
|
|
67
|
+
limit?: number;
|
|
68
|
+
offset?: number;
|
|
69
|
+
};
|
|
70
|
+
/**
|
|
71
|
+
* Page metadata returned from search providers.
|
|
72
|
+
*/
|
|
73
|
+
export type SearchResultPage = {
|
|
74
|
+
kind: "offset";
|
|
75
|
+
limit: number;
|
|
76
|
+
offset: number;
|
|
77
|
+
total?: number;
|
|
78
|
+
hasMore: boolean;
|
|
79
|
+
};
|
|
80
|
+
/**
|
|
81
|
+
* Search result payload.
|
|
82
|
+
*/
|
|
83
|
+
export type SearchResults<TDocument extends SearchDocumentBase> = {
|
|
84
|
+
hits: TDocument[];
|
|
85
|
+
query: string;
|
|
86
|
+
page: SearchResultPage;
|
|
87
|
+
processingTimeMs?: number;
|
|
88
|
+
facets?: Record<string, Record<string, number>>;
|
|
89
|
+
};
|
|
90
|
+
/**
|
|
91
|
+
* Result returned after indexing documents.
|
|
92
|
+
*/
|
|
93
|
+
export type SearchIndexResult = {
|
|
94
|
+
indexed: number;
|
|
95
|
+
taskId?: string | number;
|
|
96
|
+
};
|
|
97
|
+
/**
|
|
98
|
+
* Result returned after deleting indexed documents.
|
|
99
|
+
*/
|
|
100
|
+
export type SearchDeleteResult = {
|
|
101
|
+
deleted: number;
|
|
102
|
+
taskId?: string | number;
|
|
103
|
+
};
|
|
104
|
+
/**
|
|
105
|
+
* App-facing search port.
|
|
106
|
+
*/
|
|
107
|
+
export type SearchPort = {
|
|
108
|
+
configureIndex<TDocument extends SearchDocumentBase>(index: SearchIndexDef<TDocument>): Promise<void>;
|
|
109
|
+
indexDocuments<TDocument extends SearchDocumentBase>(index: SearchIndexDef<TDocument>, documents: TDocument | readonly TDocument[]): Promise<SearchIndexResult>;
|
|
110
|
+
deleteDocuments<TDocument extends SearchDocumentBase>(index: SearchIndexDef<TDocument>, ids: string | readonly string[]): Promise<SearchDeleteResult>;
|
|
111
|
+
clearIndex<TDocument extends SearchDocumentBase>(index: SearchIndexDef<TDocument>): Promise<SearchDeleteResult>;
|
|
112
|
+
search<TDocument extends SearchDocumentBase>(index: SearchIndexDef<TDocument>, query: SearchQuery): Promise<SearchResults<TDocument>>;
|
|
113
|
+
};
|
|
114
|
+
/**
|
|
115
|
+
* Captured memory index state exposed for tests.
|
|
116
|
+
*/
|
|
117
|
+
export type MemorySearchIndexState<TDocument extends SearchDocumentBase = SearchDocument> = {
|
|
118
|
+
definition?: SearchIndexDef<TDocument>;
|
|
119
|
+
documents: Map<string, TDocument>;
|
|
120
|
+
};
|
|
121
|
+
/**
|
|
122
|
+
* In-memory search port exposed for assertions in tests.
|
|
123
|
+
*/
|
|
124
|
+
export type MemorySearchPort = SearchPort & {
|
|
125
|
+
indexes: Map<string, MemorySearchIndexState>;
|
|
126
|
+
reset(index?: SearchIndexDef): void;
|
|
127
|
+
};
|
|
128
|
+
/**
|
|
129
|
+
* Options for the in-memory search adapter.
|
|
130
|
+
*/
|
|
131
|
+
export type CreateMemorySearchOptions = {
|
|
132
|
+
now?: () => Date;
|
|
133
|
+
};
|
|
134
|
+
/**
|
|
135
|
+
* Options for the in-memory search provider.
|
|
136
|
+
*/
|
|
137
|
+
export type MemorySearchProviderOptions = CreateMemorySearchOptions & {
|
|
138
|
+
name?: string;
|
|
139
|
+
};
|
|
140
|
+
/**
|
|
141
|
+
* Ports contributed by the memory search provider.
|
|
142
|
+
*/
|
|
143
|
+
export interface MemorySearchProviderPorts {
|
|
144
|
+
search: SearchPort;
|
|
145
|
+
}
|
|
146
|
+
/**
|
|
147
|
+
* Error thrown when search inputs are invalid.
|
|
148
|
+
*/
|
|
149
|
+
export declare class SearchOptionsError extends Error {
|
|
150
|
+
constructor(message: string);
|
|
151
|
+
}
|
|
152
|
+
/**
|
|
153
|
+
* Define a typed search index.
|
|
154
|
+
*/
|
|
155
|
+
export declare function defineSearchIndex<TDocument extends SearchDocumentBase = SearchDocument>(name: string, options?: DefineSearchIndexOptions<TDocument>): SearchIndexDef<TDocument>;
|
|
156
|
+
/**
|
|
157
|
+
* Index documents through any `SearchPort`.
|
|
158
|
+
*/
|
|
159
|
+
export declare function indexSearchDocuments<TDocument extends SearchDocumentBase>(search: SearchPort, index: SearchIndexDef<TDocument>, documents: TDocument | readonly TDocument[]): Promise<SearchIndexResult>;
|
|
160
|
+
/**
|
|
161
|
+
* Query documents through any `SearchPort`.
|
|
162
|
+
*/
|
|
163
|
+
export declare function searchDocuments<TDocument extends SearchDocumentBase>(search: SearchPort, index: SearchIndexDef<TDocument>, query: SearchQuery): Promise<SearchResults<TDocument>>;
|
|
164
|
+
/**
|
|
165
|
+
* Create an in-memory search port for tests and single-process development.
|
|
166
|
+
*/
|
|
167
|
+
export declare function createMemorySearch(_options?: CreateMemorySearchOptions): MemorySearchPort;
|
|
168
|
+
/**
|
|
169
|
+
* Create a provider that contributes an in-memory search port.
|
|
170
|
+
*/
|
|
171
|
+
export declare function createMemorySearchProvider(options?: MemorySearchProviderOptions): import("../providers/provider.js").ServiceProvider<unknown, import("@standard-schema/spec").StandardSchemaV1<void, void>, {
|
|
172
|
+
search: SearchPort;
|
|
173
|
+
}, unknown, void>;
|
|
174
|
+
export {};
|
|
175
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/search/index.ts"],"names":[],"mappings":"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"}
|