@venizia/ignis-kernel 0.2.1-3 → 0.2.1-5
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/dist/cjs/base/controllers/factory/controller.d.ts +56 -2
- package/dist/cjs/base/controllers/factory/controller.d.ts.map +1 -1
- package/dist/cjs/base/controllers/rest/base.d.ts +70 -3
- package/dist/cjs/base/controllers/rest/base.d.ts.map +1 -1
- package/dist/cjs/base/controllers/rest/base.js +30 -3
- package/dist/cjs/base/controllers/rest/base.js.map +1 -1
- package/dist/cjs/base/controllers/rest/extras.d.ts +49 -0
- package/dist/cjs/base/controllers/rest/extras.d.ts.map +1 -0
- package/dist/cjs/base/controllers/rest/extras.js +153 -0
- package/dist/cjs/base/controllers/rest/extras.js.map +1 -0
- package/dist/cjs/base/controllers/rest/index.d.ts +1 -0
- package/dist/cjs/base/controllers/rest/index.d.ts.map +1 -1
- package/dist/cjs/base/controllers/rest/index.js +1 -0
- package/dist/cjs/base/controllers/rest/index.js.map +1 -1
- package/dist/cjs/base/repositories/common/extra-request.d.ts +26 -0
- package/dist/cjs/base/repositories/common/extra-request.d.ts.map +1 -0
- package/dist/cjs/base/repositories/common/extra-request.js +21 -0
- package/dist/cjs/base/repositories/common/extra-request.js.map +1 -0
- package/dist/cjs/base/repositories/common/response-reader.d.ts +53 -0
- package/dist/cjs/base/repositories/common/response-reader.d.ts.map +1 -0
- package/dist/cjs/base/repositories/common/response-reader.js +100 -0
- package/dist/cjs/base/repositories/common/response-reader.js.map +1 -0
- package/dist/cjs/base/repositories/common/types/results.d.ts +2 -1
- package/dist/cjs/base/repositories/common/types/results.d.ts.map +1 -1
- package/dist/cjs/repository.d.ts +3 -0
- package/dist/cjs/repository.d.ts.map +1 -1
- package/dist/cjs/repository.js +7 -1
- package/dist/cjs/repository.js.map +1 -1
- package/dist/esm/base/controllers/factory/controller.d.ts +56 -2
- package/dist/esm/base/controllers/factory/controller.d.ts.map +1 -1
- package/dist/esm/base/controllers/rest/base.d.ts +70 -3
- package/dist/esm/base/controllers/rest/base.d.ts.map +1 -1
- package/dist/esm/base/controllers/rest/base.js +30 -3
- package/dist/esm/base/controllers/rest/base.js.map +1 -1
- package/dist/esm/base/controllers/rest/extras.d.ts +49 -0
- package/dist/esm/base/controllers/rest/extras.d.ts.map +1 -0
- package/dist/esm/base/controllers/rest/extras.js +149 -0
- package/dist/esm/base/controllers/rest/extras.js.map +1 -0
- package/dist/esm/base/controllers/rest/index.d.ts +1 -0
- package/dist/esm/base/controllers/rest/index.d.ts.map +1 -1
- package/dist/esm/base/controllers/rest/index.js +1 -0
- package/dist/esm/base/controllers/rest/index.js.map +1 -1
- package/dist/esm/base/repositories/common/extra-request.d.ts +26 -0
- package/dist/esm/base/repositories/common/extra-request.d.ts.map +1 -0
- package/dist/esm/base/repositories/common/extra-request.js +17 -0
- package/dist/esm/base/repositories/common/extra-request.js.map +1 -0
- package/dist/esm/base/repositories/common/response-reader.d.ts +53 -0
- package/dist/esm/base/repositories/common/response-reader.d.ts.map +1 -0
- package/dist/esm/base/repositories/common/response-reader.js +96 -0
- package/dist/esm/base/repositories/common/response-reader.js.map +1 -0
- package/dist/esm/base/repositories/common/types/results.d.ts +2 -1
- package/dist/esm/base/repositories/common/types/results.d.ts.map +1 -1
- package/dist/esm/repository.d.ts +3 -0
- package/dist/esm/repository.d.ts.map +1 -1
- package/dist/esm/repository.js +4 -0
- package/dist/esm/repository.js.map +1 -1
- package/package.json +2 -2
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
import { HTTP } from '@venizia/ignis-helpers/common';
|
|
2
|
+
import { getError } from '@venizia/ignis-helpers/core';
|
|
3
|
+
/** A name or a key: letters, digits, `_`, `.` and `-` inside. Anything else is refused, never evaluated. */
|
|
4
|
+
const IDENTIFIER = /^[A-Za-z_][\w.-]*$/;
|
|
5
|
+
const ENTRY = /^(-?)([^()\s]+)(?:\(([^()]*)\))?$/;
|
|
6
|
+
/** `-*`: every default off - for a read that wants the rows alone. */
|
|
7
|
+
const ALL_DEFAULTS = '*';
|
|
8
|
+
/** Parses `x-request-extra` and resolves it against what a route offers. */
|
|
9
|
+
export class ResponseExtras {
|
|
10
|
+
/** The entries of the header, in the order written. Malformed input is a 400 naming it. */
|
|
11
|
+
static parse(opts) {
|
|
12
|
+
const header = opts.header?.trim() ?? '';
|
|
13
|
+
if (header === '') {
|
|
14
|
+
return [];
|
|
15
|
+
}
|
|
16
|
+
const entries = [];
|
|
17
|
+
for (const raw of ResponseExtras.splitTopLevel({ header })) {
|
|
18
|
+
const match = raw.trim().match(ENTRY);
|
|
19
|
+
const name = match?.[2];
|
|
20
|
+
const isAllDefaultsOff = match?.[1] === '-' && name === ALL_DEFAULTS && match[3] === undefined;
|
|
21
|
+
if (!match || !name || (!isAllDefaultsOff && !IDENTIFIER.test(name))) {
|
|
22
|
+
throw ResponseExtras.badRequest({ message: `Malformed extra '${raw.trim()}'` });
|
|
23
|
+
}
|
|
24
|
+
const keys = match[3] === undefined
|
|
25
|
+
? undefined
|
|
26
|
+
: match[3]
|
|
27
|
+
.split(',')
|
|
28
|
+
.map(key => key.trim())
|
|
29
|
+
.filter(key => key.length > 0);
|
|
30
|
+
if (keys?.some(key => !IDENTIFIER.test(key))) {
|
|
31
|
+
throw ResponseExtras.badRequest({ message: `Malformed key in extra '${raw.trim()}'` });
|
|
32
|
+
}
|
|
33
|
+
entries.push({ name, isExcluded: match[1] === '-', keys });
|
|
34
|
+
}
|
|
35
|
+
return entries;
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* What to compute: the asked-for extras and the defaults, minus the ones switched off - each with the
|
|
39
|
+
* keys asked for, de-duplicated in the order asked. Every name and key is checked against `offered`.
|
|
40
|
+
*/
|
|
41
|
+
static resolve(opts) {
|
|
42
|
+
const { requested, offered } = opts;
|
|
43
|
+
const offeredNames = Object.keys(offered).join(', ') || 'none';
|
|
44
|
+
const plan = new Map();
|
|
45
|
+
const excluded = new Set();
|
|
46
|
+
let isEveryDefaultOff = false;
|
|
47
|
+
for (const entry of requested) {
|
|
48
|
+
if (entry.isExcluded && entry.name === ALL_DEFAULTS) {
|
|
49
|
+
isEveryDefaultOff = true;
|
|
50
|
+
continue;
|
|
51
|
+
}
|
|
52
|
+
if (!Object.hasOwn(offered, entry.name)) {
|
|
53
|
+
throw ResponseExtras.badRequest({
|
|
54
|
+
message: `Unknown extra requested: ${entry.name} | This route offers: ${offeredNames}`,
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
if (entry.isExcluded) {
|
|
58
|
+
if (entry.keys !== undefined) {
|
|
59
|
+
throw ResponseExtras.badRequest({
|
|
60
|
+
message: `Switching '${entry.name}' off takes no keys`,
|
|
61
|
+
});
|
|
62
|
+
}
|
|
63
|
+
excluded.add(entry.name);
|
|
64
|
+
continue;
|
|
65
|
+
}
|
|
66
|
+
const definition = offered[entry.name];
|
|
67
|
+
const isGroup = typeof definition !== 'function' && definition.keys !== undefined;
|
|
68
|
+
if (!isGroup) {
|
|
69
|
+
if (entry.keys !== undefined) {
|
|
70
|
+
throw ResponseExtras.badRequest({ message: `Extra '${entry.name}' takes no keys` });
|
|
71
|
+
}
|
|
72
|
+
plan.set(entry.name, undefined);
|
|
73
|
+
continue;
|
|
74
|
+
}
|
|
75
|
+
if (!entry.keys?.length) {
|
|
76
|
+
throw ResponseExtras.badRequest({
|
|
77
|
+
message: `Extra '${entry.name}' needs keys: ${definition.keys.join(', ')} | Name them as ${entry.name}(key,key)`,
|
|
78
|
+
});
|
|
79
|
+
}
|
|
80
|
+
const unknown = entry.keys.filter(key => !definition.keys.includes(key));
|
|
81
|
+
if (unknown.length > 0) {
|
|
82
|
+
throw ResponseExtras.badRequest({
|
|
83
|
+
message: `Unknown key for extra '${entry.name}': ${unknown.join(', ')} | It offers: ${definition.keys.join(', ')}`,
|
|
84
|
+
});
|
|
85
|
+
}
|
|
86
|
+
plan.set(entry.name, [...new Set([...(plan.get(entry.name) ?? []), ...entry.keys])]);
|
|
87
|
+
}
|
|
88
|
+
for (const [name, definition] of Object.entries(offered)) {
|
|
89
|
+
// A group needs keys, so it never runs unasked, whatever its declaration claims.
|
|
90
|
+
const isDefault = typeof definition !== 'function' &&
|
|
91
|
+
definition.keys === undefined &&
|
|
92
|
+
definition.isDefault === true;
|
|
93
|
+
if (isDefault && !isEveryDefaultOff && !plan.has(name)) {
|
|
94
|
+
plan.set(name, undefined);
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
for (const name of excluded) {
|
|
98
|
+
plan.delete(name);
|
|
99
|
+
}
|
|
100
|
+
return plan;
|
|
101
|
+
}
|
|
102
|
+
/** Runs the plan in parallel; each value under its name. */
|
|
103
|
+
static async compute(opts) {
|
|
104
|
+
const { plan, offered } = opts;
|
|
105
|
+
const names = [...plan.keys()];
|
|
106
|
+
// Async, so an extra that throws synchronously becomes a rejection Promise.all owns, never an
|
|
107
|
+
// unhandled one left behind by a sibling already running.
|
|
108
|
+
const values = await Promise.all(names.map(async (name) => {
|
|
109
|
+
const definition = offered[name];
|
|
110
|
+
if (typeof definition === 'function') {
|
|
111
|
+
return definition();
|
|
112
|
+
}
|
|
113
|
+
if (definition.keys !== undefined) {
|
|
114
|
+
return definition.compute({ keys: plan.get(name) ?? [] });
|
|
115
|
+
}
|
|
116
|
+
return definition.compute();
|
|
117
|
+
}));
|
|
118
|
+
return Object.fromEntries(names.map((name, index) => [name, values[index]]));
|
|
119
|
+
}
|
|
120
|
+
/** Commas inside `( )` belong to the keys, not to the list of extras. */
|
|
121
|
+
static splitTopLevel(opts) {
|
|
122
|
+
const parts = [];
|
|
123
|
+
let depth = 0;
|
|
124
|
+
let current = '';
|
|
125
|
+
for (const character of opts.header) {
|
|
126
|
+
if (character === '(') {
|
|
127
|
+
depth++;
|
|
128
|
+
}
|
|
129
|
+
else if (character === ')') {
|
|
130
|
+
depth--;
|
|
131
|
+
}
|
|
132
|
+
if (character === ',' && depth === 0) {
|
|
133
|
+
parts.push(current);
|
|
134
|
+
current = '';
|
|
135
|
+
continue;
|
|
136
|
+
}
|
|
137
|
+
current += character;
|
|
138
|
+
}
|
|
139
|
+
parts.push(current);
|
|
140
|
+
return parts.filter(part => part.trim().length > 0);
|
|
141
|
+
}
|
|
142
|
+
static badRequest(opts) {
|
|
143
|
+
return getError({
|
|
144
|
+
statusCode: HTTP.ResultCodes.RS_4.BadRequest,
|
|
145
|
+
message: `[x-request-extra] ${opts.message}`,
|
|
146
|
+
});
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
//# sourceMappingURL=extras.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"extras.js","sourceRoot":"","sources":["../../../../../src/base/controllers/rest/extras.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../src/base/controllers/rest/index.ts"],"names":[],"mappings":"AAAA,cAAc,YAAY,CAAC;AAC3B,cAAc,QAAQ,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../src/base/controllers/rest/index.ts"],"names":[],"mappings":"AAAA,cAAc,YAAY,CAAC;AAC3B,cAAc,QAAQ,CAAC;AACvB,cAAc,UAAU,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../src/base/controllers/rest/index.ts"],"names":[],"mappings":"AAAA,cAAc,YAAY,CAAC;AAC3B,cAAc,QAAQ,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../src/base/controllers/rest/index.ts"],"names":[],"mappings":"AAAA,cAAc,YAAY,CAAC;AAC3B,cAAc,QAAQ,CAAC;AACvB,cAAc,UAAU,CAAC"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The extras a client asks for, by name: `true` asks for a plain extra, a list of keys asks for a
|
|
3
|
+
* group (`facets: ['status', 'tag']`), `false` switches a default off.
|
|
4
|
+
*/
|
|
5
|
+
export type TExtraRequest = Record<string, boolean | ReadonlyArray<string>>;
|
|
6
|
+
/**
|
|
7
|
+
* What may come back for `Extra`: a group keyed by the keys asked for. Every entry is optional - a
|
|
8
|
+
* route that offers no extras, or an older server, answers none - and the route may add defaults.
|
|
9
|
+
*/
|
|
10
|
+
export type TExtraResult<Extra extends TExtraRequest> = {
|
|
11
|
+
[K in keyof Extra as Extra[K] extends false ? never : K]?: Extra[K] extends ReadonlyArray<infer Key extends string> ? Record<Key, unknown> : unknown;
|
|
12
|
+
} & Record<string, unknown>;
|
|
13
|
+
/** The client half of the list-extras contract: what goes in `x-request-extra`. */
|
|
14
|
+
export declare class HttpExtraRequest {
|
|
15
|
+
/**
|
|
16
|
+
* The header value for what a call asks for - `name`, `-name`, `name(key,key)` - led by `-*` when
|
|
17
|
+
* the call wants the rows alone, every default off. `undefined` when it asks for nothing.
|
|
18
|
+
*/
|
|
19
|
+
static toHeader(opts: {
|
|
20
|
+
extra?: TExtraRequest;
|
|
21
|
+
isEveryDefaultOff?: boolean;
|
|
22
|
+
}): string | undefined;
|
|
23
|
+
/** The header name, for a client that sets headers itself. */
|
|
24
|
+
static readonly HEADER: "x-request-extra";
|
|
25
|
+
}
|
|
26
|
+
//# sourceMappingURL=extra-request.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"extra-request.d.ts","sourceRoot":"","sources":["../../../../../src/base/repositories/common/extra-request.ts"],"names":[],"mappings":"AAEA;;;GAGG;AACH,MAAM,MAAM,aAAa,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,GAAG,aAAa,CAAC,MAAM,CAAC,CAAC,CAAC;AAE5E;;;GAGG;AACH,MAAM,MAAM,YAAY,CAAC,KAAK,SAAS,aAAa,IAAI;KACrD,CAAC,IAAI,MAAM,KAAK,IAAI,KAAK,CAAC,CAAC,CAAC,SAAS,KAAK,GAAG,KAAK,GAAG,CAAC,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,CAAC,SAAS,aAAa,CACvF,MAAM,GAAG,SAAS,MAAM,CACzB,GACG,MAAM,CAAC,GAAG,EAAE,OAAO,CAAC,GACpB,OAAO;CACZ,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;AAE5B,mFAAmF;AACnF,qBAAa,gBAAgB;IAC3B;;;OAGG;IACH,MAAM,CAAC,QAAQ,CAAC,IAAI,EAAE;QACpB,KAAK,CAAC,EAAE,aAAa,CAAC;QACtB,iBAAiB,CAAC,EAAE,OAAO,CAAC;KAC7B,GAAG,MAAM,GAAG,SAAS;IAWtB,8DAA8D;IAC9D,MAAM,CAAC,QAAQ,CAAC,MAAM,oBAA8B;CACrD"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { HTTP } from '@venizia/ignis-helpers/common';
|
|
2
|
+
/** The client half of the list-extras contract: what goes in `x-request-extra`. */
|
|
3
|
+
export class HttpExtraRequest {
|
|
4
|
+
/**
|
|
5
|
+
* The header value for what a call asks for - `name`, `-name`, `name(key,key)` - led by `-*` when
|
|
6
|
+
* the call wants the rows alone, every default off. `undefined` when it asks for nothing.
|
|
7
|
+
*/
|
|
8
|
+
static toHeader(opts) {
|
|
9
|
+
const { extra = {}, isEveryDefaultOff = false } = opts;
|
|
10
|
+
const entries = Object.entries(extra).map(([name, value]) => value === true ? name : value === false ? `-${name}` : `${name}(${value.join(',')})`);
|
|
11
|
+
const tokens = isEveryDefaultOff ? ['-*', ...entries] : entries;
|
|
12
|
+
return tokens.length > 0 ? tokens.join(',') : undefined;
|
|
13
|
+
}
|
|
14
|
+
/** The header name, for a client that sets headers itself. */
|
|
15
|
+
static { this.HEADER = HTTP.Headers.REQUEST_EXTRA; }
|
|
16
|
+
}
|
|
17
|
+
//# sourceMappingURL=extra-request.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"extra-request.js","sourceRoot":"","sources":["../../../../../src/base/repositories/common/extra-request.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,+BAA+B,CAAC;AAoBrD,mFAAmF;AACnF,MAAM,OAAO,gBAAgB;IAC3B;;;OAGG;IACH,MAAM,CAAC,QAAQ,CAAC,IAGf;QACC,MAAM,EAAE,KAAK,GAAG,EAAE,EAAE,iBAAiB,GAAG,KAAK,EAAE,GAAG,IAAI,CAAC;QAEvD,MAAM,OAAO,GAAG,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,EAAE,KAAK,CAAC,EAAE,EAAE,CAC1D,KAAK,KAAK,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,KAAK,KAAK,CAAC,CAAC,CAAC,IAAI,IAAI,EAAE,CAAC,CAAC,CAAC,GAAG,IAAI,IAAI,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,CACrF,CAAC;QACF,MAAM,MAAM,GAAG,iBAAiB,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC;QAEhE,OAAO,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;IAC1D,CAAC;IAED,8DAA8D;aAC9C,WAAM,GAAG,IAAI,CAAC,OAAO,CAAC,aAAa,CAAC"}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import type { TResponsedError } from '@venizia/ignis-helpers/core';
|
|
2
|
+
/**
|
|
3
|
+
* What an IGNIS server answers - `Content-Range`, the error envelope - read once, here, for every
|
|
4
|
+
* client of that server: the http connector, and a client that reads it without the connector.
|
|
5
|
+
*/
|
|
6
|
+
export declare class HttpResponseReader {
|
|
7
|
+
static isPlainObject(value: unknown): value is Record<string, unknown>;
|
|
8
|
+
/** An empty string reads as absent, so a fallback still applies. */
|
|
9
|
+
static toText(value: unknown): string | undefined;
|
|
10
|
+
/**
|
|
11
|
+
* A `Content-Range` header as the IGNIS server writes it: `records 0-24/137` -> skip 0, total 137;
|
|
12
|
+
* an empty page, `records *\/137` -> total 137. Anything else, including an absent header or an
|
|
13
|
+
* unknown total, is `undefined`.
|
|
14
|
+
*/
|
|
15
|
+
static parseContentRange(opts: {
|
|
16
|
+
header?: string | null;
|
|
17
|
+
}): {
|
|
18
|
+
skip?: number;
|
|
19
|
+
total: number;
|
|
20
|
+
} | undefined;
|
|
21
|
+
/**
|
|
22
|
+
* The IGNIS error envelope - `{ message, statusCode, normalized: { text, code, args }, requestId,
|
|
23
|
+
* extra, details }` - read off a parsed response body. A server configured with `error.rootKey`
|
|
24
|
+
* wraps it under that key; pass the same `rootKey` to unwrap it. A body without that key, or with a
|
|
25
|
+
* non-object under it (a proxy's `{ error: 'Bad Gateway' }`), is read as it stands.
|
|
26
|
+
*
|
|
27
|
+
* A body that is not a plain object yields `{}`; any other body yields its known fields, each
|
|
28
|
+
* `undefined` when absent or mistyped. An empty string reads as absent.
|
|
29
|
+
*/
|
|
30
|
+
static readErrorEnvelope(opts: {
|
|
31
|
+
body: unknown;
|
|
32
|
+
rootKey?: string;
|
|
33
|
+
}): TResponsedError;
|
|
34
|
+
/** A failed response's envelope. A body that is not JSON yields `{}`, and the status alone still describes it. */
|
|
35
|
+
static readError(opts: {
|
|
36
|
+
response: Response;
|
|
37
|
+
rootKey?: string;
|
|
38
|
+
}): Promise<TResponsedError>;
|
|
39
|
+
/**
|
|
40
|
+
* A body the server marked with `x-response-extra` carries `extra` beside its rows. `body` is what
|
|
41
|
+
* the route answers without extras: the `{ count, data }` envelope when the count was asked for in
|
|
42
|
+
* the body, the rows otherwise. Any other body is returned as it stands - an unmarked object is
|
|
43
|
+
* never unwrapped, so a row that has `data` and `extra` columns of its own is never misread.
|
|
44
|
+
*/
|
|
45
|
+
static readExtra(opts: {
|
|
46
|
+
body: unknown;
|
|
47
|
+
headers: Pick<Headers, 'has'>;
|
|
48
|
+
}): {
|
|
49
|
+
body: unknown;
|
|
50
|
+
extra?: Record<string, unknown>;
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
//# sourceMappingURL=response-reader.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"response-reader.d.ts","sourceRoot":"","sources":["../../../../../src/base/repositories/common/response-reader.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,6BAA6B,CAAC;AAEnE;;;GAGG;AACH,qBAAa,kBAAkB;IAC7B,MAAM,CAAC,aAAa,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;IAMtE,oEAAoE;IACpE,MAAM,CAAC,MAAM,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,GAAG,SAAS;IAIjD;;;;OAIG;IACH,MAAM,CAAC,iBAAiB,CAAC,IAAI,EAAE;QAC7B,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;KACxB,GAAG;QAAE,IAAI,CAAC,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,GAAG,SAAS;IAoBhD;;;;;;;;OAQG;IACH,MAAM,CAAC,iBAAiB,CAAC,IAAI,EAAE;QAAE,IAAI,EAAE,OAAO,CAAC;QAAC,OAAO,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,eAAe;IA4BpF,kHAAkH;WACrG,SAAS,CAAC,IAAI,EAAE;QAAE,QAAQ,EAAE,QAAQ,CAAC;QAAC,OAAO,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,eAAe,CAAC;IAahG;;;;;OAKG;IACH,MAAM,CAAC,SAAS,CAAC,IAAI,EAAE;QAAE,IAAI,EAAE,OAAO,CAAC;QAAC,OAAO,EAAE,IAAI,CAAC,OAAO,EAAE,KAAK,CAAC,CAAA;KAAE,GAAG;QACxE,IAAI,EAAE,OAAO,CAAC;QACd,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;KACjC;CAeF"}
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
import { HTTP } from '@venizia/ignis-helpers/common';
|
|
2
|
+
/**
|
|
3
|
+
* What an IGNIS server answers - `Content-Range`, the error envelope - read once, here, for every
|
|
4
|
+
* client of that server: the http connector, and a client that reads it without the connector.
|
|
5
|
+
*/
|
|
6
|
+
export class HttpResponseReader {
|
|
7
|
+
static isPlainObject(value) {
|
|
8
|
+
return (!!value && typeof value === 'object' && Object.getPrototypeOf(value) === Object.prototype);
|
|
9
|
+
}
|
|
10
|
+
/** An empty string reads as absent, so a fallback still applies. */
|
|
11
|
+
static toText(value) {
|
|
12
|
+
return typeof value === 'string' && value !== '' ? value : undefined;
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* A `Content-Range` header as the IGNIS server writes it: `records 0-24/137` -> skip 0, total 137;
|
|
16
|
+
* an empty page, `records *\/137` -> total 137. Anything else, including an absent header or an
|
|
17
|
+
* unknown total, is `undefined`.
|
|
18
|
+
*/
|
|
19
|
+
static parseContentRange(opts) {
|
|
20
|
+
const { header } = opts;
|
|
21
|
+
if (!header) {
|
|
22
|
+
return undefined;
|
|
23
|
+
}
|
|
24
|
+
const range = header.match(/(\d+)\s*-\s*(\d+)\s*\/\s*(\d+)/);
|
|
25
|
+
if (range) {
|
|
26
|
+
return { skip: Number(range[1]), total: Number(range[3]) };
|
|
27
|
+
}
|
|
28
|
+
const unsatisfied = header.match(/\*\s*\/\s*(\d+)/);
|
|
29
|
+
if (unsatisfied) {
|
|
30
|
+
return { total: Number(unsatisfied[1]) };
|
|
31
|
+
}
|
|
32
|
+
return undefined;
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* The IGNIS error envelope - `{ message, statusCode, normalized: { text, code, args }, requestId,
|
|
36
|
+
* extra, details }` - read off a parsed response body. A server configured with `error.rootKey`
|
|
37
|
+
* wraps it under that key; pass the same `rootKey` to unwrap it. A body without that key, or with a
|
|
38
|
+
* non-object under it (a proxy's `{ error: 'Bad Gateway' }`), is read as it stands.
|
|
39
|
+
*
|
|
40
|
+
* A body that is not a plain object yields `{}`; any other body yields its known fields, each
|
|
41
|
+
* `undefined` when absent or mistyped. An empty string reads as absent.
|
|
42
|
+
*/
|
|
43
|
+
static readErrorEnvelope(opts) {
|
|
44
|
+
const { body, rootKey } = opts;
|
|
45
|
+
const wrapped = rootKey && HttpResponseReader.isPlainObject(body) ? body[rootKey] : undefined;
|
|
46
|
+
const envelope = HttpResponseReader.isPlainObject(wrapped) ? wrapped : body;
|
|
47
|
+
if (!HttpResponseReader.isPlainObject(envelope)) {
|
|
48
|
+
return {};
|
|
49
|
+
}
|
|
50
|
+
const { message, statusCode, normalized, requestId, extra, details } = envelope;
|
|
51
|
+
const normalizedRecord = HttpResponseReader.isPlainObject(normalized) ? normalized : {};
|
|
52
|
+
const { text, code, args } = normalizedRecord;
|
|
53
|
+
return {
|
|
54
|
+
message: HttpResponseReader.toText(message),
|
|
55
|
+
statusCode: typeof statusCode === 'number' ? statusCode : undefined,
|
|
56
|
+
normalized: {
|
|
57
|
+
text: HttpResponseReader.toText(text),
|
|
58
|
+
code: HttpResponseReader.toText(code),
|
|
59
|
+
args: HttpResponseReader.isPlainObject(args) ? { ...args } : undefined,
|
|
60
|
+
},
|
|
61
|
+
requestId: HttpResponseReader.toText(requestId),
|
|
62
|
+
extra: HttpResponseReader.isPlainObject(extra) ? { ...extra } : undefined,
|
|
63
|
+
details: HttpResponseReader.isPlainObject(details) ? { ...details } : undefined,
|
|
64
|
+
};
|
|
65
|
+
}
|
|
66
|
+
/** A failed response's envelope. A body that is not JSON yields `{}`, and the status alone still describes it. */
|
|
67
|
+
static async readError(opts) {
|
|
68
|
+
const text = await opts.response.text().catch(() => '');
|
|
69
|
+
let body;
|
|
70
|
+
try {
|
|
71
|
+
body = text ? JSON.parse(text) : undefined;
|
|
72
|
+
}
|
|
73
|
+
catch {
|
|
74
|
+
return {};
|
|
75
|
+
}
|
|
76
|
+
return HttpResponseReader.readErrorEnvelope({ body, rootKey: opts.rootKey });
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* A body the server marked with `x-response-extra` carries `extra` beside its rows. `body` is what
|
|
80
|
+
* the route answers without extras: the `{ count, data }` envelope when the count was asked for in
|
|
81
|
+
* the body, the rows otherwise. Any other body is returned as it stands - an unmarked object is
|
|
82
|
+
* never unwrapped, so a row that has `data` and `extra` columns of its own is never misread.
|
|
83
|
+
*/
|
|
84
|
+
static readExtra(opts) {
|
|
85
|
+
const { body, headers } = opts;
|
|
86
|
+
const isMarked = headers.has(HTTP.Headers.RESPONSE_EXTRA);
|
|
87
|
+
if (!isMarked ||
|
|
88
|
+
!HttpResponseReader.isPlainObject(body) ||
|
|
89
|
+
!HttpResponseReader.isPlainObject(body.extra)) {
|
|
90
|
+
return { body };
|
|
91
|
+
}
|
|
92
|
+
const { extra, ...envelope } = body;
|
|
93
|
+
return { body: 'count' in envelope ? envelope : envelope.data, extra: { ...extra } };
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
//# sourceMappingURL=response-reader.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"response-reader.js","sourceRoot":"","sources":["../../../../../src/base/repositories/common/response-reader.ts"],"names":[],"mappings":"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"}
|
|
@@ -15,9 +15,10 @@ export declare const buildDataRange: (opts: {
|
|
|
15
15
|
dataLength: number;
|
|
16
16
|
total: number;
|
|
17
17
|
}) => TDataRange;
|
|
18
|
-
/** The `shouldQueryRange: true` result envelope
|
|
18
|
+
/** The `shouldQueryRange: true` result envelope; `extra` carries what a list answered beside its rows - see `x-request-extra`. */
|
|
19
19
|
export type TDataWithRange<R> = {
|
|
20
20
|
data: Array<R>;
|
|
21
21
|
range: TDataRange;
|
|
22
|
+
extra?: Record<string, unknown>;
|
|
22
23
|
};
|
|
23
24
|
//# sourceMappingURL=results.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"results.d.ts","sourceRoot":"","sources":["../../../../../../src/base/repositories/common/types/results.ts"],"names":[],"mappings":"AAAA,uLAAuL;AACvL,MAAM,MAAM,MAAM,GAAG;IAAE,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC;AAEvC,yFAAyF;AACzF,MAAM,MAAM,UAAU,GAAG;IACvB,KAAK,EAAE,MAAM,CAAC;IACd,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,MAAM,CAAC;CACf,CAAC;AAEF,mGAAmG;AACnG,eAAO,MAAM,cAAc,GAAI,MAAM;IACnC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,EAAE,MAAM,CAAC;CACf,KAAG,UAKH,CAAC;AAEF,
|
|
1
|
+
{"version":3,"file":"results.d.ts","sourceRoot":"","sources":["../../../../../../src/base/repositories/common/types/results.ts"],"names":[],"mappings":"AAAA,uLAAuL;AACvL,MAAM,MAAM,MAAM,GAAG;IAAE,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC;AAEvC,yFAAyF;AACzF,MAAM,MAAM,UAAU,GAAG;IACvB,KAAK,EAAE,MAAM,CAAC;IACd,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,MAAM,CAAC;CACf,CAAC;AAEF,mGAAmG;AACnG,eAAO,MAAM,cAAc,GAAI,MAAM;IACnC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,EAAE,MAAM,CAAC;CACf,KAAG,UAKH,CAAC;AAEF,kIAAkI;AAClI,MAAM,MAAM,cAAc,CAAC,CAAC,IAAI;IAC9B,IAAI,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC;IACf,KAAK,EAAE,UAAU,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACjC,CAAC"}
|
package/dist/esm/repository.d.ts
CHANGED
|
@@ -16,6 +16,9 @@ export { AbstractRepository } from './base/repositories/core/abstract.js';
|
|
|
16
16
|
export { AbstractDataSource } from './base/datasources/abstract.js';
|
|
17
17
|
export type { ICreatableRepository, ICrudRepository, IDeletableRepository, IPersistableRepository, IReadableRepository, IRepository, IUpdatableRepository, } from './base/repositories/common/types/contracts.js';
|
|
18
18
|
export { buildDataRange } from './base/repositories/common/types/results.js';
|
|
19
|
+
export { HttpResponseReader } from './base/repositories/common/response-reader.js';
|
|
20
|
+
export { HttpExtraRequest } from './base/repositories/common/extra-request.js';
|
|
21
|
+
export type { TExtraRequest, TExtraResult } from './base/repositories/common/extra-request.js';
|
|
19
22
|
export { DEFAULT_LIMIT, DEFAULT_MAX_LIMIT, RepositoryOperationScopes, RepositoryTypes, } from './base/repositories/common/constants.js';
|
|
20
23
|
export type { TRepositoryType } from './base/repositories/common/constants.js';
|
|
21
24
|
export { CoreErrorCodes, SearchErrorCodes } from './common/error-codes.js';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"repository.d.ts","sourceRoot":"","sources":["../../src/repository.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,OAAO,EAAE,kBAAkB,EAAE,MAAM,mCAAmC,CAAC;AACvE,OAAO,EAAE,kBAAkB,EAAE,MAAM,6BAA6B,CAAC;AAEjE,YAAY,EACV,oBAAoB,EACpB,eAAe,EACf,oBAAoB,EACpB,sBAAsB,EACtB,mBAAmB,EACnB,WAAW,EACX,oBAAoB,GACrB,MAAM,4CAA4C,CAAC;AAEpD,OAAO,EAAE,cAAc,EAAE,MAAM,0CAA0C,CAAC;AAI1E,OAAO,EACL,aAAa,EACb,iBAAiB,EACjB,yBAAyB,EACzB,eAAe,GAChB,MAAM,sCAAsC,CAAC;AAC9C,YAAY,EAAE,eAAe,EAAE,MAAM,sCAAsC,CAAC;AAC5E,OAAO,EAAE,cAAc,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AACxE,OAAO,EAAE,iBAAiB,EAAE,MAAM,2BAA2B,CAAC;AAC9D,YAAY,EAAE,MAAM,EAAE,UAAU,EAAE,cAAc,EAAE,MAAM,0CAA0C,CAAC;AAEnG,YAAY,EAAE,WAAW,EAAE,MAAM,iCAAiC,CAAC;AAInE,OAAO,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AACpD,OAAO,EAAE,WAAW,EAAE,MAAM,gCAAgC,CAAC;AAC7D,YAAY,EAAE,aAAa,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AAGvE,YAAY,EAAE,OAAO,EAAE,UAAU,EAAE,MAAM,EAAE,MAAM,uBAAuB,CAAC"}
|
|
1
|
+
{"version":3,"file":"repository.d.ts","sourceRoot":"","sources":["../../src/repository.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,OAAO,EAAE,kBAAkB,EAAE,MAAM,mCAAmC,CAAC;AACvE,OAAO,EAAE,kBAAkB,EAAE,MAAM,6BAA6B,CAAC;AAEjE,YAAY,EACV,oBAAoB,EACpB,eAAe,EACf,oBAAoB,EACpB,sBAAsB,EACtB,mBAAmB,EACnB,WAAW,EACX,oBAAoB,GACrB,MAAM,4CAA4C,CAAC;AAEpD,OAAO,EAAE,cAAc,EAAE,MAAM,0CAA0C,CAAC;AAI1E,OAAO,EAAE,kBAAkB,EAAE,MAAM,4CAA4C,CAAC;AAChF,OAAO,EAAE,gBAAgB,EAAE,MAAM,0CAA0C,CAAC;AAC5E,YAAY,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,0CAA0C,CAAC;AAI5F,OAAO,EACL,aAAa,EACb,iBAAiB,EACjB,yBAAyB,EACzB,eAAe,GAChB,MAAM,sCAAsC,CAAC;AAC9C,YAAY,EAAE,eAAe,EAAE,MAAM,sCAAsC,CAAC;AAC5E,OAAO,EAAE,cAAc,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AACxE,OAAO,EAAE,iBAAiB,EAAE,MAAM,2BAA2B,CAAC;AAC9D,YAAY,EAAE,MAAM,EAAE,UAAU,EAAE,cAAc,EAAE,MAAM,0CAA0C,CAAC;AAEnG,YAAY,EAAE,WAAW,EAAE,MAAM,iCAAiC,CAAC;AAInE,OAAO,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AACpD,OAAO,EAAE,WAAW,EAAE,MAAM,gCAAgC,CAAC;AAC7D,YAAY,EAAE,aAAa,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AAGvE,YAAY,EAAE,OAAO,EAAE,UAAU,EAAE,MAAM,EAAE,MAAM,uBAAuB,CAAC"}
|
package/dist/esm/repository.js
CHANGED
|
@@ -15,6 +15,10 @@
|
|
|
15
15
|
export { AbstractRepository } from './base/repositories/core/abstract.js';
|
|
16
16
|
export { AbstractDataSource } from './base/datasources/abstract.js';
|
|
17
17
|
export { buildDataRange } from './base/repositories/common/types/results.js';
|
|
18
|
+
// How a client reads what an IGNIS server answers - shared by the http connector and any client
|
|
19
|
+
// that reads the same server without it.
|
|
20
|
+
export { HttpResponseReader } from './base/repositories/common/response-reader.js';
|
|
21
|
+
export { HttpExtraRequest } from './base/repositories/common/extra-request.js';
|
|
18
22
|
// What a repository on any transport raises and bounds itself by - the constants, the error codes,
|
|
19
23
|
// and the helper an engine that lacks an operation throws through.
|
|
20
24
|
export { DEFAULT_LIMIT, DEFAULT_MAX_LIMIT, RepositoryOperationScopes, RepositoryTypes, } from './base/repositories/common/constants.js';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"repository.js","sourceRoot":"","sources":["../../src/repository.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,OAAO,EAAE,kBAAkB,EAAE,MAAM,mCAAmC,CAAC;AACvE,OAAO,EAAE,kBAAkB,EAAE,MAAM,6BAA6B,CAAC;AAYjE,OAAO,EAAE,cAAc,EAAE,MAAM,0CAA0C,CAAC;AAE1E,mGAAmG;AACnG,mEAAmE;AACnE,OAAO,EACL,aAAa,EACb,iBAAiB,EACjB,yBAAyB,EACzB,eAAe,GAChB,MAAM,sCAAsC,CAAC;AAE9C,OAAO,EAAE,cAAc,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AACxE,OAAO,EAAE,iBAAiB,EAAE,MAAM,2BAA2B,CAAC;AAK9D,mGAAmG;AACnG,qFAAqF;AACrF,OAAO,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AACpD,OAAO,EAAE,WAAW,EAAE,MAAM,gCAAgC,CAAC"}
|
|
1
|
+
{"version":3,"file":"repository.js","sourceRoot":"","sources":["../../src/repository.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,OAAO,EAAE,kBAAkB,EAAE,MAAM,mCAAmC,CAAC;AACvE,OAAO,EAAE,kBAAkB,EAAE,MAAM,6BAA6B,CAAC;AAYjE,OAAO,EAAE,cAAc,EAAE,MAAM,0CAA0C,CAAC;AAE1E,gGAAgG;AAChG,yCAAyC;AACzC,OAAO,EAAE,kBAAkB,EAAE,MAAM,4CAA4C,CAAC;AAChF,OAAO,EAAE,gBAAgB,EAAE,MAAM,0CAA0C,CAAC;AAG5E,mGAAmG;AACnG,mEAAmE;AACnE,OAAO,EACL,aAAa,EACb,iBAAiB,EACjB,yBAAyB,EACzB,eAAe,GAChB,MAAM,sCAAsC,CAAC;AAE9C,OAAO,EAAE,cAAc,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AACxE,OAAO,EAAE,iBAAiB,EAAE,MAAM,2BAA2B,CAAC;AAK9D,mGAAmG;AACnG,qFAAqF;AACrF,OAAO,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AACpD,OAAO,EAAE,WAAW,EAAE,MAAM,gCAAgC,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@venizia/ignis-kernel",
|
|
3
|
-
"version": "0.2.1-
|
|
3
|
+
"version": "0.2.1-5",
|
|
4
4
|
"description": "Browser-pure kernel of the IGNIS framework: dependency injection, lifecycle, REST controllers, repository and datasource abstractions, and the authentication and authorization seams. No node builtin and no server-only peer, so the same kernel serves a Bun server and a browser Worker.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"authentication",
|
|
@@ -92,7 +92,7 @@
|
|
|
92
92
|
},
|
|
93
93
|
"dependencies": {
|
|
94
94
|
"@venizia/ignis-filter": "^0.2.1-1",
|
|
95
|
-
"@venizia/ignis-helpers": "^0.2.1-
|
|
95
|
+
"@venizia/ignis-helpers": "^0.2.1-2",
|
|
96
96
|
"@venizia/ignis-inversion": "^0.2.1-0",
|
|
97
97
|
"reflect-metadata": "^0.2.2",
|
|
98
98
|
"zod": "^4.5.4"
|