@nxgt/janus-graphql 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.
Files changed (50) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +248 -0
  3. package/dist/context.d.ts +63 -0
  4. package/dist/context.d.ts.map +1 -0
  5. package/dist/directives/apply.d.ts +46 -0
  6. package/dist/directives/apply.d.ts.map +1 -0
  7. package/dist/directives/guard.d.ts +21 -0
  8. package/dist/directives/guard.d.ts.map +1 -0
  9. package/dist/directives/permission/enforce.d.ts +24 -0
  10. package/dist/directives/permission/enforce.d.ts.map +1 -0
  11. package/dist/directives/permission/model.d.ts +35 -0
  12. package/dist/directives/permission/model.d.ts.map +1 -0
  13. package/dist/directives/permission/path.d.ts +31 -0
  14. package/dist/directives/permission/path.d.ts.map +1 -0
  15. package/dist/directives/permission/validate.d.ts +42 -0
  16. package/dist/directives/permission/validate.d.ts.map +1 -0
  17. package/dist/directives/read.d.ts +35 -0
  18. package/dist/directives/read.d.ts.map +1 -0
  19. package/dist/directives/validate.d.ts +33 -0
  20. package/dist/directives/validate.d.ts.map +1 -0
  21. package/dist/directives/words.d.ts +7 -0
  22. package/dist/directives/words.d.ts.map +1 -0
  23. package/dist/errors.d.ts +44 -0
  24. package/dist/errors.d.ts.map +1 -0
  25. package/dist/helpers.d.ts +56 -0
  26. package/dist/helpers.d.ts.map +1 -0
  27. package/dist/index.d.ts +27 -0
  28. package/dist/index.d.ts.map +1 -0
  29. package/dist/index.js +645 -0
  30. package/dist/index.js.map +24 -0
  31. package/dist/memo.d.ts +16 -0
  32. package/dist/memo.d.ts.map +1 -0
  33. package/dist/plugin.d.ts +32 -0
  34. package/dist/plugin.d.ts.map +1 -0
  35. package/dist/sdl.d.ts +12 -0
  36. package/dist/sdl.d.ts.map +1 -0
  37. package/dist/types.d.ts +64 -0
  38. package/dist/types.d.ts.map +1 -0
  39. package/dist/wiring.d.ts +56 -0
  40. package/dist/wiring.d.ts.map +1 -0
  41. package/docs/README.md +18 -0
  42. package/docs/guide/context.md +156 -0
  43. package/docs/guide/directives.md +312 -0
  44. package/docs/guide/errors.md +138 -0
  45. package/docs/guide/federation.md +70 -0
  46. package/docs/guide/telemetry.md +45 -0
  47. package/docs/roadmap.md +59 -0
  48. package/docs/troubleshooting.md +471 -0
  49. package/graphql/janus.graphqls +36 -0
  50. package/package.json +71 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"validate.d.ts","sourceRoot":"","sources":["../../src/directives/validate.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EACN,KAAK,UAAU,EACf,KAAK,eAAe,EACpB,KAAK,gBAAgB,EAErB,MAAM,uBAAuB,CAAC;AAC/B,OAAO,KAAK,EAAoB,eAAe,EAAE,MAAM,QAAQ,CAAC;AAGhE,sDAAsD;AACtD,MAAM,WAAW,WAAW;IAC3B,sCAAsC;IACtC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,+DAA+D;IAC/D,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB;;;OAGG;IACH,QAAQ,CAAC,KAAK,EAAE,WAAW,CAAC,MAAM,CAAC,GAAG,IAAI,CAAC;IAC3C,uEAAuE;IACvE,QAAQ,CAAC,WAAW,EAAE,SAAS,eAAe,EAAE,CAAC;CACjD;AAED,6FAA6F;AAC7F,MAAM,WAAW,KAAK;IACrB,QAAQ,CAAC,KAAK,EAAE,SAAS,MAAM,EAAE,CAAC;CAClC;AAED;;;GAGG;AACH,wBAAgB,aAAa,CAC5B,KAAK,EAAE,UAAU,EACjB,UAAU,EAAE,eAAe,EAC3B,KAAK,EAAE,KAAK,EACZ,MAAM,EAAE,gBAAgB,GACtB,WAAW,GAAG,IAAI,CAWpB"}
@@ -0,0 +1,7 @@
1
+ /** The phrases the schema-time refusals share. */
2
+ export declare const PREFIX = "applyJanusDirectives()";
3
+ /** `Query.me`, or `Record (read by Record.title)` for a type's directive. */
4
+ export declare function on(where: string, field: string): string;
5
+ /** `'a', 'b'`. */
6
+ export declare function list(names: readonly string[]): string;
7
+ //# sourceMappingURL=words.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"words.d.ts","sourceRoot":"","sources":["../../src/directives/words.ts"],"names":[],"mappings":"AAAA,kDAAkD;AAElD,eAAO,MAAM,MAAM,2BAA2B,CAAC;AAE/C,6EAA6E;AAC7E,wBAAgB,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,CAEvD;AAED,kBAAkB;AAClB,wBAAgB,IAAI,CAAC,KAAK,EAAE,SAAS,MAAM,EAAE,GAAG,MAAM,CAErD"}
@@ -0,0 +1,44 @@
1
+ /**
2
+ * Every refusal as a `GraphQLError` whose `extensions` carry a `code` and the
3
+ * HTTP status Yoga answers with: `{ code, http: { status } }`. This package
4
+ * defines no error class of its own — a denial is a `GraphQLError`, and what
5
+ * `@nxgt/janus` throws stays its own until `janusMaskError()` reads it.
6
+ */
7
+ import { JanusError } from '@nxgt/janus';
8
+ import { GraphQLError } from 'graphql';
9
+ /** What a guard answers without asking `@nxgt/janus`: no user, or not this one. */
10
+ export type DenialCode = 'UNAUTHENTICATED' | 'FORBIDDEN' | 'NOT_FOUND';
11
+ /** A denial: `UNAUTHENTICATED` 401, `FORBIDDEN` 403 or `NOT_FOUND` 404. */
12
+ export declare function denial(code: DenialCode, message?: string): GraphQLError;
13
+ /**
14
+ * A `JanusError` as the client may read it: its code and status, and only
15
+ * what the client can act on — `issues`, `minLength`, `attemptsLeft`. Never
16
+ * `reason`, `login`, `slot` or a cause: those are for your logs.
17
+ *
18
+ * `STORE_FAILED` is `SERVICE_UNAVAILABLE` 503 — **an outage is never a
19
+ * denial** — and no message of the core's reaches the client.
20
+ */
21
+ export declare function janusGraphQLError(error: JanusError): GraphQLError;
22
+ /**
23
+ * A rejection handler: a `JanusError` becomes its `GraphQLError`, anything
24
+ * else goes on as it is. `.then(undefined, rethrown)`.
25
+ */
26
+ export declare function rethrown(error: unknown): never;
27
+ /** Yoga's and envelop's `maskError` signature. */
28
+ export type MaskError = (error: unknown, message: string, isDev?: boolean) => Error;
29
+ /**
30
+ * Yoga's `maskedErrors.maskError`: a `JanusError` a resolver let through is
31
+ * answered with its code and status — `STORE_FAILED` as 503, never masked
32
+ * into a 500 and never a denial — and every other error goes to `fallback`.
33
+ *
34
+ * Without a `fallback`, a `GraphQLError` is kept and anything else becomes
35
+ * `message`, with no detail. Pass Yoga's own `maskError` to keep its
36
+ * development-mode details:
37
+ *
38
+ * ```ts
39
+ * import { createYoga, maskError } from 'graphql-yoga';
40
+ * createYoga({ schema, plugins, maskedErrors: { maskError: janusMaskError(maskError) } });
41
+ * ```
42
+ */
43
+ export declare function janusMaskError(fallback?: MaskError): MaskError;
44
+ //# sourceMappingURL=errors.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,UAAU,EAAmC,MAAM,aAAa,CAAC;AAC1E,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAEvC,mFAAmF;AACnF,MAAM,MAAM,UAAU,GAAG,iBAAiB,GAAG,WAAW,GAAG,WAAW,CAAC;AAEvE,2EAA2E;AAC3E,wBAAgB,MAAM,CAAC,IAAI,EAAE,UAAU,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG,YAAY,CAKvE;AAaD;;;;;;;GAOG;AACH,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,UAAU,GAAG,YAAY,CAQjE;AA4CD;;;GAGG;AACH,wBAAgB,QAAQ,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,CAE9C;AAED,kDAAkD;AAClD,MAAM,MAAM,SAAS,GAAG,CACvB,KAAK,EAAE,OAAO,EACd,OAAO,EAAE,MAAM,EACf,KAAK,CAAC,EAAE,OAAO,KACX,KAAK,CAAC;AAEX;;;;;;;;;;;;;GAaG;AACH,wBAAgB,cAAc,CAAC,QAAQ,GAAE,SAAkB,GAAG,SAAS,CAiBtE"}
@@ -0,0 +1,56 @@
1
+ /**
2
+ * The two calls a resolver makes itself: `requireUser` where a directive
3
+ * would not do, and `can` for a check the schema cannot express.
4
+ */
5
+ import type { CheckArgs, CheckableOf, ModelConfig, ObjectRef, ObjectTypeOf, Permissions } from '@nxgt/janus/permissions';
6
+ /** What `requireUser()` takes. */
7
+ export interface RequireUserOptions<T extends string> {
8
+ /**
9
+ * Only a user of this type, or of one of these — never an empty list,
10
+ * which no user could pass: any other is `FORBIDDEN`.
11
+ */
12
+ readonly type?: T | readonly [T, ...T[]];
13
+ }
14
+ /**
15
+ * The signed-in user, narrowed to `type` when it is given — or a denial:
16
+ * `UNAUTHENTICATED` 401 for an anonymous request, `FORBIDDEN` 403 for a user
17
+ * of another type. A store that cannot answer is `SERVICE_UNAVAILABLE` 503,
18
+ * never either of them.
19
+ *
20
+ * ```ts
21
+ * const staff = await requireUser(ctx, { type: 'staff' });
22
+ * staff.username; // typed: a staff member
23
+ * ```
24
+ */
25
+ export declare function requireUser<U extends {
26
+ readonly type: string;
27
+ }, const T extends U['type'] = U['type']>(ctx: {
28
+ readonly janus: {
29
+ user(): Promise<U | null>;
30
+ };
31
+ }, options?: RequireUserOptions<T>): Promise<Extract<U, {
32
+ readonly type: T;
33
+ }>>;
34
+ /**
35
+ * Whether the request's user holds `permission` on `object`, typed as
36
+ * `access.can` is: the permission must be one the object's type declares,
37
+ * the object must carry every field its `fromField`s read, and `{ ctx }` is
38
+ * required exactly when a condition is reachable. Anonymous answers `false`.
39
+ *
40
+ * **A failure throws**: a store that cannot answer is `SERVICE_UNAVAILABLE`
41
+ * 503, never `false`.
42
+ *
43
+ * ```ts
44
+ * if (!(await can(ctx, 'edit', { type: 'record', ...record }))) return null;
45
+ * ```
46
+ */
47
+ export declare function can<C extends ModelConfig, const T extends ObjectTypeOf<C>, const P extends CheckableOf<C, T>>(ctx: {
48
+ readonly janus: {
49
+ user(): Promise<{
50
+ readonly type: string;
51
+ readonly id: string;
52
+ } | null>;
53
+ readonly access: Pick<Permissions<C>, 'can'>;
54
+ };
55
+ }, permission: P, object: ObjectRef<C, T>, ...options: CheckArgs<C, T, P>): Promise<boolean>;
56
+ //# sourceMappingURL=helpers.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"helpers.d.ts","sourceRoot":"","sources":["../src/helpers.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EACX,SAAS,EACT,WAAW,EACX,WAAW,EACX,SAAS,EACT,YAAY,EACZ,WAAW,EACX,MAAM,yBAAyB,CAAC;AAIjC,kCAAkC;AAClC,MAAM,WAAW,kBAAkB,CAAC,CAAC,SAAS,MAAM;IACnD;;;OAGG;IACH,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC,GAAG,SAAS,CAAC,CAAC,EAAE,GAAG,CAAC,EAAE,CAAC,CAAC;CACzC;AAED;;;;;;;;;;GAUG;AACH,wBAAsB,WAAW,CAChC,CAAC,SAAS;IAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;CAAE,EACnC,KAAK,CAAC,CAAC,SAAS,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,EAErC,GAAG,EAAE;IAAE,QAAQ,CAAC,KAAK,EAAE;QAAE,IAAI,IAAI,OAAO,CAAC,CAAC,GAAG,IAAI,CAAC,CAAA;KAAE,CAAA;CAAE,EACtD,OAAO,GAAE,kBAAkB,CAAC,CAAC,CAAM,GACjC,OAAO,CAAC,OAAO,CAAC,CAAC,EAAE;IAAE,QAAQ,CAAC,IAAI,EAAE,CAAC,CAAA;CAAE,CAAC,CAAC,CAiB3C;AAED;;;;;;;;;;;;GAYG;AACH,wBAAsB,GAAG,CACxB,CAAC,SAAS,WAAW,EACrB,KAAK,CAAC,CAAC,SAAS,YAAY,CAAC,CAAC,CAAC,EAC/B,KAAK,CAAC,CAAC,SAAS,WAAW,CAAC,CAAC,EAAE,CAAC,CAAC,EAEjC,GAAG,EAAE;IACJ,QAAQ,CAAC,KAAK,EAAE;QACf,IAAI,IAAI,OAAO,CAAC;YAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;YAAC,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAA;SAAE,GAAG,IAAI,CAAC,CAAC;QACvE,QAAQ,CAAC,MAAM,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC;KAC7C,CAAC;CACF,EACD,UAAU,EAAE,CAAC,EACb,MAAM,EAAE,SAAS,CAAC,CAAC,EAAE,CAAC,CAAC,EACvB,GAAG,OAAO,EAAE,SAAS,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,GAC5B,OAAO,CAAC,OAAO,CAAC,CAalB"}
@@ -0,0 +1,27 @@
1
+ /**
2
+ * `@nxgt/janus-graphql` — `@nxgt/janus` in a GraphQL server.
3
+ *
4
+ * - `useJanus({ auth, access?, type?, loaders?, conditions? })` — the
5
+ * envelop plugin: `ctx.janus` on every request, and the directives —
6
+ * `@authenticated`, `@permission` — applied to the schema;
7
+ * - `janusTypeDefs` — the directives' SDL, also shipped as
8
+ * `graphql/janus.graphqls`;
9
+ * - `applyJanusDirectives(schema, { auth })` — the schema transform alone;
10
+ * - `requireUser(ctx, { type? })` and `can(ctx, permission, object)` — the
11
+ * calls a resolver makes itself;
12
+ * - `janusMaskError(fallback?)` — Yoga's `maskError`: a `JanusError` as its
13
+ * code and status, `STORE_FAILED` as 503 and never as 401 or 403.
14
+ * - `janusGraphQLError(error)` — a `JanusError` as the `GraphQLError` the
15
+ * client reads, and `denial(code, message?)` — a denial of your own.
16
+ *
17
+ * It defines no error class: a denial is a `GraphQLError`, and what it lets
18
+ * through is `@nxgt/janus`'s own.
19
+ */
20
+ export { applyJanusDirectives, type JanusDirectivesOptions, } from './directives/apply';
21
+ export { type DenialCode, denial, janusGraphQLError, janusMaskError, type MaskError, } from './errors';
22
+ export { can, type RequireUserOptions, requireUser } from './helpers';
23
+ export { useJanus } from './plugin';
24
+ export { janusTypeDefs } from './sdl';
25
+ export type { Auth, JanusContext, JanusOnContext, JanusOptions, UserOfAuth, } from './types';
26
+ export type { Conditions, LoadedObject, Loaders } from './wiring';
27
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAEH,OAAO,EACN,oBAAoB,EACpB,KAAK,sBAAsB,GAC3B,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EACN,KAAK,UAAU,EACf,MAAM,EACN,iBAAiB,EACjB,cAAc,EACd,KAAK,SAAS,GACd,MAAM,UAAU,CAAC;AAClB,OAAO,EAAE,GAAG,EAAE,KAAK,kBAAkB,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AACtE,OAAO,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAC;AACpC,OAAO,EAAE,aAAa,EAAE,MAAM,OAAO,CAAC;AACtC,YAAY,EACX,IAAI,EACJ,YAAY,EACZ,cAAc,EACd,YAAY,EACZ,UAAU,GACV,MAAM,SAAS,CAAC;AACjB,YAAY,EAAE,UAAU,EAAE,YAAY,EAAE,OAAO,EAAE,MAAM,UAAU,CAAC"}