@znight/core 0.1.3 → 0.2.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/README.md +17 -9
- package/dist/index.d.mts +82 -2
- package/dist/index.mjs +36 -3
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
- package/src/errors.ts +36 -1
- package/src/hooks.ts +59 -0
- package/src/index.ts +5 -0
package/README.md
CHANGED
|
@@ -338,12 +338,13 @@ return what is known (`[]`).
|
|
|
338
338
|
declared in core, so producers and observers (`@znight/observability`, your plugins) share them
|
|
339
339
|
without depending on each other:
|
|
340
340
|
|
|
341
|
-
| Hook | Event
|
|
342
|
-
| ------------------- |
|
|
343
|
-
| `http:request` | `HttpRequestEvent`
|
|
344
|
-
| `messaging:message` | `MessageDeliveryEvent`
|
|
345
|
-
| `messaging:publish` | `MessagePublishEvent`
|
|
346
|
-
| `schedule:run` | `ScheduledRunEvent`
|
|
341
|
+
| Hook | Event | Produced by |
|
|
342
|
+
| ------------------- | ----------------------- | ---------------------------------------------------------------------------- |
|
|
343
|
+
| `http:request` | `HttpRequestEvent` | `@znight/http`, one request |
|
|
344
|
+
| `messaging:message` | `MessageDeliveryEvent` | `@znight/messaging`, one delivery |
|
|
345
|
+
| `messaging:publish` | `MessagePublishEvent` | `@znight/messaging`, one `MessageBroker` publication |
|
|
346
|
+
| `schedule:run` | `ScheduledRunEvent` | `@znight/schedule`, one occurrence of a job (executed or not, see `outcome`) |
|
|
347
|
+
| `graphql:operation` | `GraphQLOperationEvent` | `@znight/graphql` (planned, RFC 0005), one GraphQL operation |
|
|
347
348
|
|
|
348
349
|
`ScheduledRunEvent` carries `job`, `kind` (`cron` / `interval` / `timeout`), `host`, `method`,
|
|
349
350
|
`runId`, `trigger` (`schedule` / `start` / `manual` / `queued`), `scheduledAt` (epoch ms),
|
|
@@ -358,6 +359,13 @@ wrappers waited (job removed or paused, scheduler stopping), or a wrapper threw
|
|
|
358
359
|
rejects). The producer settles it after `hooks.run` (`skipped`, or `failed` for a wrapper that
|
|
359
360
|
threw), so a wrapper that reports it reads `event.outcome ?? (nextRejected ? 'failed' : 'skipped')`.
|
|
360
361
|
|
|
362
|
+
`GraphQLOperationEvent` carries `operationType` (`query` / `mutation` / `subscription`, `undefined`
|
|
363
|
+
when the request was rejected before an operation was selected), `operationName`, `documentId`
|
|
364
|
+
(SHA-256 of the query text), `transport` (`http` / `sse` / `direct`), `requestId`, `context` (the
|
|
365
|
+
`GraphQLContext`), `startTime`, and, once settled, `outcome` (`success` / `partial` / `error` /
|
|
366
|
+
`rejected`) and `errors` (`{ message, code, path? }`, as sent to the client). A subscription is one
|
|
367
|
+
operation from its start to its end.
|
|
368
|
+
|
|
361
369
|
Other packages declare their hooks by augmenting `ZnightHooks`:
|
|
362
370
|
|
|
363
371
|
```ts
|
|
@@ -421,6 +429,6 @@ the [architecture specification](../../docs/internals/architecture.md#48-validat
|
|
|
421
429
|
The catalogue is shared by the compiler and every first-party package. `ZNIGHT001`–`ZNIGHT029`
|
|
422
430
|
belong to the core, the compiler and the features of the first release (`ZNIGHT023`, a missing
|
|
423
431
|
route decision, is reported by `@znight/http`). From `ZNIGHT030`, each package owns a block of ten:
|
|
424
|
-
`ZNIGHT030`–`039` `@znight/openapi`, `ZNIGHT040`–`049` `@znight/schedule
|
|
425
|
-
`
|
|
426
|
-
block, codes are allocated in order; third-party packages get no `ZNIGHT` code.
|
|
432
|
+
`ZNIGHT030`–`039` `@znight/openapi`, `ZNIGHT040`–`049` `@znight/schedule`, `ZNIGHT060`–`069`
|
|
433
|
+
`@znight/graphql` (RFC 0005, planned for v0.2; `050`–`059` are reserved for `@znight/websocket`).
|
|
434
|
+
Inside a block, codes are allocated in order; third-party packages get no `ZNIGHT` code.
|
package/dist/index.d.mts
CHANGED
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
* messaging, config, observability).
|
|
8
8
|
* - From `ZNIGHT030`, each first-party package reserves a block of ten: `ZNIGHT030`–`039`
|
|
9
9
|
* `@znight/openapi`, `ZNIGHT040`–`049` `@znight/schedule`, `ZNIGHT050`–`059` `@znight/websocket`
|
|
10
|
-
* (reserved), `ZNIGHT060`–`069` `@znight/graphql
|
|
10
|
+
* (reserved), `ZNIGHT060`–`069` `@znight/graphql`.
|
|
11
11
|
*
|
|
12
12
|
* Within a range, codes are allocated in order without gaps. A package uses its block for its own
|
|
13
13
|
* failure modes, with one catch-all code for invalid usage and options, and reuses a lower code
|
|
@@ -96,6 +96,32 @@ export declare const ErrorCode: {
|
|
|
96
96
|
readonly MissingLockStore: "ZNIGHT043";
|
|
97
97
|
/** A scheduled run was aborted (`ctx.signal.reason`, `JobAbortedError`); never thrown by the framework. */
|
|
98
98
|
readonly JobAborted: "ZNIGHT044";
|
|
99
|
+
/** A TypeScript type cannot be mapped to a GraphQL type, or a resolver lacks the annotation it needs. */
|
|
100
|
+
readonly InvalidGraphQLType: "ZNIGHT060";
|
|
101
|
+
/** Two declarations or root fields share a GraphQL name, or a name is invalid or reserved. */
|
|
102
|
+
readonly GraphQLNameConflict: "ZNIGHT061";
|
|
103
|
+
/**
|
|
104
|
+
* Invalid resolver structure: `@ResolveField` without `@Parent()`, a subscription not returning an
|
|
105
|
+
* async iterable, no `@Query`, inherited handlers, resolvers in a compiled library.
|
|
106
|
+
*/
|
|
107
|
+
readonly InvalidResolver: "ZNIGHT062";
|
|
108
|
+
/**
|
|
109
|
+
* Invalid input position: a type used as input and output, a getter, a union, a cycle of non-null
|
|
110
|
+
* input fields, a default value not matching its type.
|
|
111
|
+
*/
|
|
112
|
+
readonly InvalidGraphQLInput: "ZNIGHT063";
|
|
113
|
+
/** The members of a GraphQL union cannot be told apart at runtime. */
|
|
114
|
+
readonly UnresolvableAbstractType: "ZNIGHT064";
|
|
115
|
+
/**
|
|
116
|
+
* Invalid loader: `@Loader()` on a type that is not `Loader<L>`, `L` not a `BatchLoad`; at runtime,
|
|
117
|
+
* a batch function returning another number of values than keys.
|
|
118
|
+
*/
|
|
119
|
+
readonly InvalidLoader: "ZNIGHT065";
|
|
120
|
+
/**
|
|
121
|
+
* Invalid GraphQL setup at boot: malformed or version-skewed metadata, invalid schema, invalid
|
|
122
|
+
* `GraphQLPlugin` options, missing `HttpPlugin`, scalar name mismatch.
|
|
123
|
+
*/
|
|
124
|
+
readonly InvalidGraphQLSetup: "ZNIGHT066";
|
|
99
125
|
};
|
|
100
126
|
export type ErrorCode = (typeof ErrorCode)[keyof typeof ErrorCode];
|
|
101
127
|
/** Short human readable description of every error code. */
|
|
@@ -610,6 +636,12 @@ interface ZnightHooks {
|
|
|
610
636
|
* drop, a wrapper that threw first): see `ScheduledRunEvent.outcome`.
|
|
611
637
|
*/
|
|
612
638
|
"schedule:run": ScheduledRunEvent;
|
|
639
|
+
/**
|
|
640
|
+
* One GraphQL operation handled by `@znight/graphql` (RFC 0005): a query or a mutation, or a whole
|
|
641
|
+
* subscription from its start to its end. Wrapped with `hooks.run` when wrappers exist, then
|
|
642
|
+
* emitted when listeners exist.
|
|
643
|
+
*/
|
|
644
|
+
"graphql:operation": GraphQLOperationEvent;
|
|
613
645
|
}
|
|
614
646
|
/**
|
|
615
647
|
* Instrumentation event of the `http:request` hook. Defined in core so that producers
|
|
@@ -737,6 +769,54 @@ interface ScheduledRunEvent {
|
|
|
737
769
|
/** Set when the run's signal was aborted. */
|
|
738
770
|
aborted?: ScheduledRunAbortReason;
|
|
739
771
|
}
|
|
772
|
+
/** Type of a GraphQL operation (`GraphQLOperationEvent.operationType`). */
|
|
773
|
+
type GraphQLOperationType = "query" | "mutation" | "subscription";
|
|
774
|
+
/**
|
|
775
|
+
* How a GraphQL operation reached the server (`GraphQLOperationEvent.transport`): GraphQL over HTTP,
|
|
776
|
+
* GraphQL over Server-Sent Events, or a direct call (`execute()` / `subscribe()` of the plugin).
|
|
777
|
+
*/
|
|
778
|
+
type GraphQLOperationTransport = "http" | "sse" | "direct";
|
|
779
|
+
/**
|
|
780
|
+
* Outcome of a GraphQL operation (`GraphQLOperationEvent.outcome`):
|
|
781
|
+
*
|
|
782
|
+
* - `'success'`: executed, no error;
|
|
783
|
+
* - `'partial'`: executed, with data and field errors;
|
|
784
|
+
* - `'error'`: executed, without data (a non-null root field failed, or the execution threw);
|
|
785
|
+
* - `'rejected'`: never executed (parse, validation, variable coercion or limit errors).
|
|
786
|
+
*/
|
|
787
|
+
type GraphQLOperationOutcome = "success" | "partial" | "error" | "rejected";
|
|
788
|
+
/** One error of a GraphQL response, as sent to the client (masked when it is unexpected). */
|
|
789
|
+
interface GraphQLOperationError {
|
|
790
|
+
readonly message: string;
|
|
791
|
+
/** `extensions.code` of the error (`FORBIDDEN`, `GRAPHQL_PARSE_FAILED`...). */
|
|
792
|
+
readonly code: string | undefined;
|
|
793
|
+
/** Response path of the field that failed; absent for request errors. */
|
|
794
|
+
readonly path?: readonly (string | number)[];
|
|
795
|
+
}
|
|
796
|
+
/**
|
|
797
|
+
* Instrumentation event of the `graphql:operation` hook, produced by `@znight/graphql` (RFC 0005)
|
|
798
|
+
* once per operation. For a subscription, it covers its whole life: wrappers see it start, and
|
|
799
|
+
* `outcome` is set when it ends. Mutable fields are filled in by the producer before `hooks.run`
|
|
800
|
+
* resolves; listeners see the final values.
|
|
801
|
+
*/
|
|
802
|
+
interface GraphQLOperationEvent {
|
|
803
|
+
/** `undefined` when the request was rejected before an operation was selected (parse error...). */
|
|
804
|
+
readonly operationType: GraphQLOperationType | undefined;
|
|
805
|
+
/** `undefined` for an anonymous operation, or when none was selected. */
|
|
806
|
+
readonly operationName: string | undefined;
|
|
807
|
+
/** SHA-256 (hex) of the query text, cached with the parsed document; `undefined` without a query. */
|
|
808
|
+
readonly documentId: string | undefined;
|
|
809
|
+
readonly transport: GraphQLOperationTransport;
|
|
810
|
+
readonly requestId: string;
|
|
811
|
+
/** `GraphQLContext` from `@znight/graphql`. */
|
|
812
|
+
readonly context: unknown;
|
|
813
|
+
/** `performance.now()` when the operation started. */
|
|
814
|
+
readonly startTime: number;
|
|
815
|
+
/** Outcome, set before `hooks.run` resolves. */
|
|
816
|
+
outcome?: GraphQLOperationOutcome;
|
|
817
|
+
/** Errors of the response (field and request errors), set before `hooks.run` resolves. */
|
|
818
|
+
errors?: readonly GraphQLOperationError[];
|
|
819
|
+
}
|
|
740
820
|
/** Name of a declared hook. */
|
|
741
821
|
type HookName = keyof ZnightHooks;
|
|
742
822
|
/** Event type of hook `K`. */
|
|
@@ -1094,5 +1174,5 @@ export declare class ZnightAggregateError extends ZnightError {
|
|
|
1094
1174
|
* that were attached to it instead of being thrown. Empty when there are none.
|
|
1095
1175
|
*/
|
|
1096
1176
|
export declare function getSuppressedErrors(error: unknown): readonly unknown[];
|
|
1097
|
-
export type { ApplicationOptions, ApplicationState, ClassKey, ClassMarker, ConsoleLike, ConsoleLoggerOptions, CoreLogger, HookEvent, HookListener, HookName, HookWrapper, HooksOptions, HotContext, HttpRequestEvent, InitOptions, InjectableOptions, InterceptMethodOptions, InterceptOptionsArgs, InterceptorClass, InterceptorLink, LogContext, LogLevel, ManagedInstance, MessageDeliveryEvent, MessagePublishEvent, MethodInterceptor, MethodInvocation, MethodMarker, OnReady, OnStart, OnStop, OpenedScope, ParameterMarker, Plugin, PluginContext, PluginHook, PluginOptions, PluginRootsContext, ProcessLike, ProviderKey, ProviderValues, ProvidesOptions, ScheduledRunAbortReason, ScheduledRunEvent, ScheduledRunOutcome, ScheduledRunTrigger, ScopeContext, ScopeValues, ShutdownOptions, ShutdownSignal, TypedToken, ZnightHooks };
|
|
1177
|
+
export type { ApplicationOptions, ApplicationState, ClassKey, ClassMarker, ConsoleLike, ConsoleLoggerOptions, CoreLogger, GraphQLOperationError, GraphQLOperationEvent, GraphQLOperationOutcome, GraphQLOperationTransport, GraphQLOperationType, HookEvent, HookListener, HookName, HookWrapper, HooksOptions, HotContext, HttpRequestEvent, InitOptions, InjectableOptions, InterceptMethodOptions, InterceptOptionsArgs, InterceptorClass, InterceptorLink, LogContext, LogLevel, ManagedInstance, MessageDeliveryEvent, MessagePublishEvent, MethodInterceptor, MethodInvocation, MethodMarker, OnReady, OnStart, OnStop, OpenedScope, ParameterMarker, Plugin, PluginContext, PluginHook, PluginOptions, PluginRootsContext, ProcessLike, ProviderKey, ProviderValues, ProvidesOptions, ScheduledRunAbortReason, ScheduledRunEvent, ScheduledRunOutcome, ScheduledRunTrigger, ScopeContext, ScopeValues, ShutdownOptions, ShutdownSignal, TypedToken, ZnightHooks };
|
|
1098
1178
|
//# sourceMappingURL=index.d.mts.map
|
package/dist/index.mjs
CHANGED
|
@@ -9,7 +9,7 @@ import { AsyncLocalStorage } from "node:async_hooks";
|
|
|
9
9
|
* messaging, config, observability).
|
|
10
10
|
* - From `ZNIGHT030`, each first-party package reserves a block of ten: `ZNIGHT030`–`039`
|
|
11
11
|
* `@znight/openapi`, `ZNIGHT040`–`049` `@znight/schedule`, `ZNIGHT050`–`059` `@znight/websocket`
|
|
12
|
-
* (reserved), `ZNIGHT060`–`069` `@znight/graphql
|
|
12
|
+
* (reserved), `ZNIGHT060`–`069` `@znight/graphql`.
|
|
13
13
|
*
|
|
14
14
|
* Within a range, codes are allocated in order without gaps. A package uses its block for its own
|
|
15
15
|
* failure modes, with one catch-all code for invalid usage and options, and reuses a lower code
|
|
@@ -97,7 +97,33 @@ const ErrorCode = {
|
|
|
97
97
|
/** A job requires a lock but `SchedulePlugin` has no lock store. */
|
|
98
98
|
MissingLockStore: "ZNIGHT043",
|
|
99
99
|
/** A scheduled run was aborted (`ctx.signal.reason`, `JobAbortedError`); never thrown by the framework. */
|
|
100
|
-
JobAborted: "ZNIGHT044"
|
|
100
|
+
JobAborted: "ZNIGHT044",
|
|
101
|
+
/** A TypeScript type cannot be mapped to a GraphQL type, or a resolver lacks the annotation it needs. */
|
|
102
|
+
InvalidGraphQLType: "ZNIGHT060",
|
|
103
|
+
/** Two declarations or root fields share a GraphQL name, or a name is invalid or reserved. */
|
|
104
|
+
GraphQLNameConflict: "ZNIGHT061",
|
|
105
|
+
/**
|
|
106
|
+
* Invalid resolver structure: `@ResolveField` without `@Parent()`, a subscription not returning an
|
|
107
|
+
* async iterable, no `@Query`, inherited handlers, resolvers in a compiled library.
|
|
108
|
+
*/
|
|
109
|
+
InvalidResolver: "ZNIGHT062",
|
|
110
|
+
/**
|
|
111
|
+
* Invalid input position: a type used as input and output, a getter, a union, a cycle of non-null
|
|
112
|
+
* input fields, a default value not matching its type.
|
|
113
|
+
*/
|
|
114
|
+
InvalidGraphQLInput: "ZNIGHT063",
|
|
115
|
+
/** The members of a GraphQL union cannot be told apart at runtime. */
|
|
116
|
+
UnresolvableAbstractType: "ZNIGHT064",
|
|
117
|
+
/**
|
|
118
|
+
* Invalid loader: `@Loader()` on a type that is not `Loader<L>`, `L` not a `BatchLoad`; at runtime,
|
|
119
|
+
* a batch function returning another number of values than keys.
|
|
120
|
+
*/
|
|
121
|
+
InvalidLoader: "ZNIGHT065",
|
|
122
|
+
/**
|
|
123
|
+
* Invalid GraphQL setup at boot: malformed or version-skewed metadata, invalid schema, invalid
|
|
124
|
+
* `GraphQLPlugin` options, missing `HttpPlugin`, scalar name mismatch.
|
|
125
|
+
*/
|
|
126
|
+
InvalidGraphQLSetup: "ZNIGHT066"
|
|
101
127
|
};
|
|
102
128
|
/** Short human readable description of every error code. */
|
|
103
129
|
const ERROR_DESCRIPTIONS = {
|
|
@@ -136,7 +162,14 @@ const ERROR_DESCRIPTIONS = {
|
|
|
136
162
|
ZNIGHT041: "Duplicate job: two jobs share a name",
|
|
137
163
|
ZNIGHT042: "Unknown job: no job has this name",
|
|
138
164
|
ZNIGHT043: "Missing lock store: a job requires a lock but SchedulePlugin has no store",
|
|
139
|
-
ZNIGHT044: "Job aborted: a scheduled run was aborted (timeout, lost lock, removal or shutdown)"
|
|
165
|
+
ZNIGHT044: "Job aborted: a scheduled run was aborted (timeout, lost lock, removal or shutdown)",
|
|
166
|
+
ZNIGHT060: "Invalid GraphQL type: a TypeScript type cannot be mapped to a GraphQL type",
|
|
167
|
+
ZNIGHT061: "GraphQL name conflict: two types or root fields share a name, or a name is invalid or reserved",
|
|
168
|
+
ZNIGHT062: "Invalid resolver: the structure of a GraphQL resolver is invalid",
|
|
169
|
+
ZNIGHT063: "Invalid GraphQL input: a type cannot be used in an input position",
|
|
170
|
+
ZNIGHT064: "Unresolvable abstract type: the members of a GraphQL union cannot be told apart at runtime",
|
|
171
|
+
ZNIGHT065: "Invalid loader: not a Loader of a BatchLoad provider, or a batch returning the wrong number of values",
|
|
172
|
+
ZNIGHT066: "Invalid GraphQL setup: metadata, schema, GraphQLPlugin options or HttpPlugin missing"
|
|
140
173
|
};
|
|
141
174
|
/** Base class of every error thrown by Znight at runtime. */
|
|
142
175
|
var ZnightError = class extends Error {
|