@nxgt/shared-graphql 2.1.0 → 3.0.1

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 (68) hide show
  1. package/README.md +112 -52
  2. package/dist/directives/authenticated.d.ts +42 -0
  3. package/dist/directives/authenticated.d.ts.map +1 -0
  4. package/dist/directives/federation.d.ts +6 -0
  5. package/dist/directives/federation.d.ts.map +1 -1
  6. package/dist/directives/index.d.ts +1 -2
  7. package/dist/directives/index.d.ts.map +1 -1
  8. package/dist/directives/permission.d.ts +20 -6
  9. package/dist/directives/permission.d.ts.map +1 -1
  10. package/dist/directives/removed-check.d.ts +15 -0
  11. package/dist/directives/removed-check.d.ts.map +1 -0
  12. package/dist/directives/scope.d.ts +3 -3
  13. package/dist/directives/scope.d.ts.map +1 -1
  14. package/dist/directives/sdl.d.ts +14 -4
  15. package/dist/directives/sdl.d.ts.map +1 -1
  16. package/dist/directives/validate.d.ts +8 -14
  17. package/dist/directives/validate.d.ts.map +1 -1
  18. package/dist/index.js +1037 -926
  19. package/dist/index.js.map +35 -31
  20. package/dist/integrations/hono.d.ts +2 -2
  21. package/dist/integrations/hono.d.ts.map +1 -1
  22. package/dist/plugins/apply-authenticated.d.ts +21 -0
  23. package/dist/plugins/apply-authenticated.d.ts.map +1 -0
  24. package/dist/plugins/apply-keto-checks.d.ts +10 -7
  25. package/dist/plugins/apply-keto-checks.d.ts.map +1 -1
  26. package/dist/plugins/auth.d.ts +17 -1
  27. package/dist/plugins/auth.d.ts.map +1 -1
  28. package/dist/plugins/authenticated.d.ts +14 -0
  29. package/dist/plugins/authenticated.d.ts.map +1 -0
  30. package/dist/plugins/extract-jwt.d.ts +19 -6
  31. package/dist/plugins/extract-jwt.d.ts.map +1 -1
  32. package/dist/plugins/field-guard.d.ts +30 -0
  33. package/dist/plugins/field-guard.d.ts.map +1 -0
  34. package/dist/plugins/gateway-trust.d.ts +15 -0
  35. package/dist/plugins/gateway-trust.d.ts.map +1 -0
  36. package/dist/plugins/index.d.ts +3 -0
  37. package/dist/plugins/index.d.ts.map +1 -1
  38. package/dist/plugins/keto-checks.d.ts +3 -2
  39. package/dist/plugins/keto-checks.d.ts.map +1 -1
  40. package/dist/plugins/keto-helpers.d.ts +1 -1
  41. package/dist/plugins/keto-helpers.d.ts.map +1 -1
  42. package/dist/plugins/ory-auth.d.ts +3 -3
  43. package/dist/shared.d.ts +1 -1
  44. package/dist/shared.d.ts.map +1 -1
  45. package/dist/utils/errors/denial.d.ts +20 -0
  46. package/dist/utils/errors/denial.d.ts.map +1 -0
  47. package/dist/utils/errors/format-error.d.ts +2 -1
  48. package/dist/utils/errors/format-error.d.ts.map +1 -1
  49. package/dist/utils/errors/index.d.ts +1 -0
  50. package/dist/utils/errors/index.d.ts.map +1 -1
  51. package/dist/utils/errors/mask-error.d.ts +2 -1
  52. package/dist/utils/errors/mask-error.d.ts.map +1 -1
  53. package/dist/utils/ws-context.d.ts +1 -1
  54. package/docs/README.md +8 -6
  55. package/docs/guide/authentication.md +187 -0
  56. package/docs/guide/errors.md +37 -5
  57. package/docs/guide/migrating-to-3.md +276 -0
  58. package/docs/guide/permissions.md +39 -50
  59. package/docs/roadmap.md +30 -29
  60. package/docs/troubleshooting.md +151 -48
  61. package/package.json +7 -11
  62. package/dist/directives/check.d.ts +0 -32
  63. package/dist/directives/check.d.ts.map +0 -1
  64. package/dist/directives/deprecation.d.ts +0 -7
  65. package/dist/directives/deprecation.d.ts.map +0 -1
  66. package/dist/directives/requirements.d.ts +0 -14
  67. package/dist/directives/requirements.d.ts.map +0 -1
  68. package/graphql/directives/check.graphqls +0 -90
package/dist/index.js.map CHANGED
@@ -1,46 +1,50 @@
1
1
  {
2
2
  "version": 3,
3
- "sources": ["../src/index.ts", "../src/directives/check.ts", "../src/directives/deprecation.ts", "../src/directives/paths.ts", "../src/directives/scope.ts", "../src/directives/validate.ts", "../src/directives/federation.ts", "../src/directives/permission.ts", "../src/directives/requirements.ts", "../src/directives/sdl.ts", "../src/integrations/hono.ts", "../src/utils/change-resolvers.utils.ts", "../src/utils/codegen.utils.ts", "../src/utils/data-loader.utils.ts", "../src/utils/errors/create-error.ts", "../src/utils/errors/format-error.ts", "../src/utils/errors/ory-unavailable.ts", "../src/utils/errors/mask-error.ts", "../src/utils/publish.ts", "../src/utils/sandbox.ts", "../src/utils/schema.utils.ts", "../src/utils/websocket.ts", "../src/utils/ws-context.ts", "../src/plugins/apply-keto-checks.ts", "../src/plugins/auth.ts", "../src/plugins/extract-jwt.ts", "../src/plugins/keto-checker.ts", "../src/plugins/keto-checks.ts", "../src/plugins/keto-helpers.ts", "../src/plugins/ory-auth.ts", "../src/scalars/any/any.scalars.ts", "../src/scalars/custom/custom.scalars.ts", "../src/scalars/custom/utils.ts", "../src/scalars/upload/upload.scalar.ts", "../src/scalars/index.ts", "../src/shared.ts", "../src/upload.ts"],
3
+ "sources": ["../src/index.ts", "../src/directives/authenticated.ts", "../src/directives/federation.ts", "../src/directives/paths.ts", "../src/directives/permission.ts", "../src/directives/scope.ts", "../src/directives/validate.ts", "../src/directives/sdl.ts", "../src/integrations/hono.ts", "../src/utils/sandbox.ts", "../src/plugins/apply-authenticated.ts", "../src/utils/errors/denial.ts", "../src/plugins/field-guard.ts", "../src/plugins/apply-keto-checks.ts", "../src/directives/removed-check.ts", "../src/plugins/gateway-trust.ts", "../src/plugins/auth.ts", "../src/plugins/authenticated.ts", "../src/plugins/extract-jwt.ts", "../src/plugins/keto-checker.ts", "../src/plugins/keto-checks.ts", "../src/plugins/keto-helpers.ts", "../src/plugins/ory-auth.ts", "../src/utils/errors/ory-unavailable.ts", "../src/scalars/any/any.scalars.ts", "../src/scalars/custom/custom.scalars.ts", "../src/scalars/custom/utils.ts", "../src/scalars/upload/upload.scalar.ts", "../src/scalars/index.ts", "../src/shared.ts", "../src/upload.ts", "../src/utils/change-resolvers.utils.ts", "../src/utils/codegen.utils.ts", "../src/utils/data-loader.utils.ts", "../src/utils/errors/create-error.ts", "../src/utils/errors/format-error.ts", "../src/utils/errors/mask-error.ts", "../src/utils/publish.ts", "../src/utils/schema.utils.ts", "../src/utils/websocket.ts", "../src/utils/ws-context.ts"],
4
4
  "sourcesContent": [
5
5
  "import DataLoader from 'dataloader';\n\nexport * from 'graphql-subscriptions';\nexport * from './directives';\nexport * from './integrations';\nexport * from './plugins';\nexport * from './scalars';\nexport * from './shared';\nexport * from './types';\nexport * from './upload';\nexport * from './utils';\n\nexport { DataLoader };\n",
6
- "import { getDirective } from '@graphql-tools/utils';\nimport type { PermissionRequirement, PermissionTerm } from '@nxgt/ory-sdk';\nimport type { GraphQLSchema } from 'graphql';\nimport { warnCheckMistake } from './deprecation';\nimport { DEFAULT_ID_PATH } from './paths';\nimport { type FieldNode, type ReadOptions, scopeOf } from './scope';\nimport { assertRequirementShape } from './validate';\n\n/**\n * `@check` — the list-of-lists form of `@permission`, deprecated in its\n * favour and kept working.\n *\n * The declaration itself is SDL, in `graphql/directives/check.graphqls`, so it\n * reaches every consumer of `SHARED_SCHEMA_PATH`; `CHECK_DIRECTIVE_SDL` is the\n * same text as a string, held equal by a spec. This module only reads it.\n */\nexport const CHECK_DIRECTIVE_NAME = 'check';\n\nexport type CheckDenial = 'NOT_FOUND' | 'FORBIDDEN';\n\nexport type CheckArgs = {\n\tpermissions: PermissionRequirement;\n\tonDeny: CheckDenial;\n\t/** i18n key; the shared `errors.*` one when the field does not say. */\n\tmessage?: string;\n};\n\n/**\n * Every `@check` on a field, in declaration order, validated.\n *\n * `@check` is repeatable, so this is a list and the order is load-bearing:\n * `view` then `edit` is what turns a denial into 404 for a stranger and 403\n * for a viewer.\n *\n * The `id` and `onDeny` defaults are applied here as well as in the SDL:\n * graphql 17 no longer hands an input field's default to `getDirective`, and a\n * term without an id would otherwise refuse the whole schema.\n */\nexport function readChecks(\n\tschema: GraphQLSchema,\n\tnode: FieldNode,\n\twhere: string,\n\toptions: ReadOptions = {},\n): CheckArgs[] {\n\tconst found = getDirective(schema, node, CHECK_DIRECTIVE_NAME) ?? [];\n\tconst scope = {\n\t\t...scopeOf(node, `@check on ${where}`, options),\n\t\tlenient: warnCheckMistake,\n\t};\n\n\treturn found.map((raw) => {\n\t\tconst permissions = withDefaultIds(raw.permissions);\n\t\tassertRequirementShape(permissions, scope);\n\t\treturn {\n\t\t\tpermissions,\n\t\t\tonDeny: (raw.onDeny ?? 'NOT_FOUND') as CheckDenial,\n\t\t\tmessage: raw.message ?? undefined,\n\t\t};\n\t});\n}\n\nfunction withDefaultIds(raw: unknown): PermissionRequirement {\n\tif (!Array.isArray(raw)) return raw as PermissionRequirement;\n\treturn raw.map((group) =>\n\t\tArray.isArray(group)\n\t\t\t? group.map((term: PermissionTerm) =>\n\t\t\t\t\tterm && typeof term === 'object'\n\t\t\t\t\t\t? { ...term, id: term.id ?? DEFAULT_ID_PATH }\n\t\t\t\t\t\t: term,\n\t\t\t\t)\n\t\t\t: group,\n\t);\n}\n",
7
- "import { logger } from '@nxgt/shared-logging';\n\n/**\n * How a `@check` mistake that 2.x let boot is reported: a warning at build,\n * naming the field, that says it becomes a refusal in the next major.\n * `@permission` is new, so the same mistake there throws.\n */\nexport function warnCheckMistake(message: string) {\n\tlogger.warn(\n\t\t`${message} — @check still boots with this; the next major refuses it, as @permission does`,\n\t);\n}\n",
6
+ "import { getDirective } from '@graphql-tools/utils';\nimport type { GraphQLSchema } from 'graphql';\nimport type { FieldNode } from './scope';\n\nexport const AUTHENTICATED_DIRECTIVE_NAME = 'authenticated';\n\n/**\n * The kinds of caller `@authenticated(type:)` can name by default: Ory's\n * `OryPrincipal.kind` — a Kratos `session`, or an OAuth2 access `token`\n * (introspected by Hydra, whether a person's or a `client_credentials` one).\n */\nexport const CALLER_TYPES = ['session', 'token'] as const;\n\nexport type AuthenticatedOptions = {\n\t/**\n\t * Every value a `type:` may name, when the caller's type is not Ory's\n\t * `kind` — `TokenPrincipal.tokenType` behind a gateway, say. A `type`\n\t * outside it is refused at build. `CALLER_TYPES` by default.\n\t */\n\ttypes?: readonly string[];\n};\n\n/**\n * What the `@authenticated`s that apply to one field demand together: a\n * caller, and — when `types` is set — one of those types. Every directive\n * that applies must hold, so `types` is their intersection.\n */\nexport type CallerRequirement = { types?: readonly string[] };\n\n/**\n * The `@authenticated` on a field, a type or an interface, read and\n * validated: `null` when there is none, `{}` for any caller, `{ types }` for\n * a caller of one of them.\n *\n * Federation declares `@authenticated` with no argument. A schema that\n * imports that declaration has no `type` to read, and every `@authenticated`\n * in it means \"any caller\" — the shape is accepted as it is.\n */\nexport function readAuthenticated(\n\tschema: GraphQLSchema,\n\tnode: FieldNode,\n\twhere: string,\n\tknown: readonly string[],\n): CallerRequirement | null {\n\tconst [found] =\n\t\tgetDirective(schema, node, AUTHENTICATED_DIRECTIVE_NAME) ?? [];\n\tif (!found) return null;\n\tconst types = found.type as unknown;\n\tif (types === undefined || types === null) return {};\n\tif (!Array.isArray(types) || types.length === 0) {\n\t\tthrow new TypeError(\n\t\t\t`@authenticated on ${where}: \\`type: []\\` admits no caller — name a type, or drop \\`type\\``,\n\t\t);\n\t}\n\tfor (const type of types) {\n\t\tif (!known.includes(type)) {\n\t\t\tthrow new TypeError(\n\t\t\t\t`@authenticated on ${where}: unknown type ${JSON.stringify(type)} — known: ${known.join(', ')}`,\n\t\t\t);\n\t\t}\n\t}\n\treturn { types };\n}\n\n/**\n * Every requirement that applies to one field, AND-ed: a caller when any\n * applies, and the types all of them admit. Refused at build when they admit\n * no type in common — no request could pass.\n */\nexport function combineRequirements(\n\tfound: readonly (CallerRequirement | null)[],\n\twhere: string,\n): CallerRequirement | null {\n\tconst applying = found.filter((one): one is CallerRequirement => !!one);\n\tif (applying.length === 0) return null;\n\tlet types: readonly string[] | undefined;\n\tfor (const { types: these } of applying) {\n\t\tif (!these) continue;\n\t\ttypes = types ? types.filter((type) => these.includes(type)) : these;\n\t}\n\tif (types?.length === 0) {\n\t\tthrow new TypeError(\n\t\t\t`@authenticated on ${where}: the field's, its type's and its interfaces' \\`type\\`s have none in common — no caller could pass`,\n\t\t);\n\t}\n\treturn types ? { types } : {};\n}\n",
7
+ "/**\n * Federation's own directive declarations, as a subgraph imports them.\n * `@authenticated` keeps federation's shape — no argument — which\n * `useAuthenticated` reads as \"any caller\". `AUTHENTICATED_DIRECTIVE_SDL`, in\n * `SHARED_TYPE_DEFS`, is the one with `type:`.\n */\nexport const FEDERATION_DIRECTIVES = `\ndirective @external on FIELD_DEFINITION | OBJECT\ndirective @requires(fields: FieldSet!) on FIELD_DEFINITION\ndirective @provides(fields: FieldSet!) on FIELD_DEFINITION\ndirective @key(fields: FieldSet!, resolvable: Boolean = true) repeatable on OBJECT | INTERFACE\ndirective @shareable repeatable on OBJECT | FIELD_DEFINITION\ndirective @inaccessible on FIELD_DEFINITION | OBJECT | INTERFACE | UNION | ARGUMENT_DEFINITION | SCALAR | ENUM | ENUM_VALUE | INPUT_OBJECT | INPUT_FIELD_DEFINITION\ndirective @tag(name: String!) repeatable on FIELD_DEFINITION | INTERFACE | OBJECT | UNION | ARGUMENT_DEFINITION | SCALAR | ENUM | ENUM_VALUE | INPUT_OBJECT | INPUT_FIELD_DEFINITION\ndirective @override(from: String!) on FIELD_DEFINITION\ndirective @composeDirective(name: String!) repeatable on SCHEMA\ndirective @interfaceObject on OBJECT\ndirective @authenticated on FIELD_DEFINITION | OBJECT | INTERFACE | SCALAR | ENUM\n`;\n",
8
8
  "import type { PermissionTerm } from '@nxgt/ory-sdk';\n\n/**\n * Where a term's object id is read from a resolver's inputs.\n *\n * `parent` and `source` are one root under two names: `source` is what\n * graphql-js calls a resolver's first argument, `parent` is what the rest of\n * the ecosystem — and `@nxgt/janus-graphql` — calls it. Both are accepted so a\n * schema moving between the two packages keeps its paths.\n */\nconst PATH = /^(args|parent|source)(\\.[A-Za-z0-9_]+)+$/;\n\n/** The id a term reads when it names none. */\nexport const DEFAULT_ID_PATH = 'args.id';\n\n/**\n * Validated when the schema is transformed, and not when a request arrives: a\n * path naming no root is a wiring mistake, and it should stop the server from\n * booting rather than 500 on the one query nobody tried.\n */\nexport function assertReadablePath(term: PermissionTerm, where: string) {\n\tif (!PATH.test(term.id)) {\n\t\tthrow new TypeError(\n\t\t\t`${where}: \\`id\\` must be \"args.<path>\", \"parent.<path>\" or \"source.<path>\", got ${JSON.stringify(term.id)}`,\n\t\t);\n\t}\n}\n\n/**\n * `args.<name>` must name an argument the field declares. Graphql-js never\n * puts an undeclared argument on `args`, so a typo here resolves no object on\n * every request — refused at build instead, naming the arguments there are.\n */\nexport function assertDeclaredArgument(\n\tterm: PermissionTerm,\n\targumentNames: readonly string[],\n\twhere: string,\n) {\n\tconst [root, name] = term.id.split('.');\n\tif (root !== 'args' || !name || argumentNames.includes(name)) return;\n\tconst declared = argumentNames.length\n\t\t? argumentNames.join(', ')\n\t\t: 'no arguments';\n\tthrow new TypeError(\n\t\t`${where}: \\`id\\` reads \"${term.id}\", but the field declares ${declared}`,\n\t);\n}\n\n/** Reads `args.x` / `parent.x.y` / `source.x.y` off a resolver's inputs. */\nexport function readPath(\n\tpath: string,\n\tsource: unknown,\n\targs: Record<string, unknown>,\n): unknown {\n\tconst [root, ...rest] = path.split('.');\n\tlet value: unknown = root === 'args' ? args : source;\n\tfor (const key of rest) {\n\t\tvalue = (value as Record<string, unknown> | null | undefined)?.[key];\n\t}\n\treturn value;\n}\n\n/** The ids one term has to clear: one value, or every element of a list. */\nexport function objectIds(value: unknown): string[] {\n\tconst values = Array.isArray(value) ? value : [value];\n\treturn values.filter(\n\t\t(item): item is string => typeof item === 'string' && item.length > 0,\n\t);\n}\n",
9
- "import type { getDirective } from '@graphql-tools/utils';\nimport type { RequirementScope } from './validate';\n\n/** A field definition or a field config — whatever `getDirective` reads. */\nexport type FieldNode = Parameters<typeof getDirective>[1];\n\n/** What a schema may add to the build-time checks of `@check` and `@permission`. */\nexport type ReadOptions = {\n\t/**\n\t * The namespaces of the stack's OPL document. When given, a `type` or\n\t * `namespace` outside it is refused at build.\n\t */\n\tnamespaces?: readonly string[];\n};\n\n/**\n * The scope a field's requirements are validated in: the message prefix, the\n * arguments the field declares — read from a field config's `args` map or a\n * definition node's `arguments` list — and the known namespaces.\n */\nexport function scopeOf(\n\tnode: FieldNode,\n\twhere: string,\n\toptions: ReadOptions,\n): RequirementScope {\n\treturn {\n\t\twhere,\n\t\targumentNames: argumentNamesOf(node),\n\t\tnamespaces: options.namespaces,\n\t};\n}\n\nfunction argumentNamesOf(node: FieldNode): string[] {\n\tconst field = node as {\n\t\targs?: Record<string, unknown> | { name: string }[];\n\t\targuments?: readonly { name: { value: string } }[];\n\t};\n\tif (Array.isArray(field.args)) return field.args.map((arg) => arg.name);\n\tif (field.args) return Object.keys(field.args);\n\treturn field.arguments?.map((arg) => arg.name.value) ?? [];\n}\n",
10
- "import { assertRequirement, type PermissionRequirement } from '@nxgt/ory-sdk';\nimport { assertDeclaredArgument, assertReadablePath } from './paths';\n\n/**\n * What a requirement is checked against when the schema is built.\n *\n * `namespaces` is optional: without it any namespace is taken on trust, as\n * before. With it — the namespaces of the stack's OPL document — a misspelt\n * `type` stops the server from booting instead of answering `false` for ever,\n * which Keto does, without an error, for a namespace it does not know.\n */\nexport type RequirementScope = {\n\t/** `@check on Query.note` — the directive and the field, for the message. */\n\twhere: string;\n\targumentNames: readonly string[];\n\tnamespaces?: readonly string[];\n\t/**\n\t * Set for `@check` alone: a mistake it used to let boot — an argument the\n\t * field does not declare — is reported here instead of thrown, so a 2.x\n\t * schema that booted still boots. It becomes a refusal in the next major.\n\t */\n\tlenient?: (message: string) => void;\n};\n\n/**\n * Every mistake a requirement can carry that is visible without a request, as\n * a `TypeError` naming the field: an empty requirement or group (`[[]]` admits\n * everyone), a path naming no root, an argument the field does not declare,\n * and a namespace the model does not have.\n */\nexport function assertRequirementShape(\n\tpermissions: PermissionRequirement,\n\tscope: RequirementScope,\n) {\n\tconst { where, argumentNames, namespaces } = scope;\n\ttry {\n\t\tassertRequirement(permissions, where);\n\t} catch (error) {\n\t\tthrow new TypeError((error as Error).message);\n\t}\n\tfor (const group of permissions) {\n\t\tfor (const term of group) {\n\t\t\tassertReadablePath(term, where);\n\t\t\tdeclaredOrReported(term, argumentNames, scope);\n\t\t\tif (namespaces && !namespaces.includes(term.namespace)) {\n\t\t\t\tthrow new TypeError(\n\t\t\t\t\t`${where}: unknown namespace ${JSON.stringify(term.namespace)} — known: ${namespaces.join(', ')}`,\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\t}\n}\n\nfunction declaredOrReported(\n\tterm: PermissionRequirement[number][number],\n\targumentNames: readonly string[],\n\tscope: RequirementScope,\n) {\n\tif (!scope.lenient) {\n\t\tassertDeclaredArgument(term, argumentNames, scope.where);\n\t\treturn;\n\t}\n\ttry {\n\t\tassertDeclaredArgument(term, argumentNames, scope.where);\n\t} catch (error) {\n\t\tscope.lenient((error as Error).message);\n\t}\n}\n",
11
- "export const FEDERATION_DIRECTIVES = `\ndirective @external on FIELD_DEFINITION | OBJECT\ndirective @requires(fields: FieldSet!) on FIELD_DEFINITION\ndirective @provides(fields: FieldSet!) on FIELD_DEFINITION\ndirective @key(fields: FieldSet!, resolvable: Boolean = true) repeatable on OBJECT | INTERFACE\ndirective @shareable repeatable on OBJECT | FIELD_DEFINITION\ndirective @inaccessible on FIELD_DEFINITION | OBJECT | INTERFACE | UNION | ARGUMENT_DEFINITION | SCALAR | ENUM | ENUM_VALUE | INPUT_OBJECT | INPUT_FIELD_DEFINITION\ndirective @tag(name: String!) repeatable on FIELD_DEFINITION | INTERFACE | OBJECT | UNION | ARGUMENT_DEFINITION | SCALAR | ENUM | ENUM_VALUE | INPUT_OBJECT | INPUT_FIELD_DEFINITION\ndirective @override(from: String!) on FIELD_DEFINITION\ndirective @composeDirective(name: String!) repeatable on SCHEMA\ndirective @interfaceObject on OBJECT\ndirective @authenticated on FIELD_DEFINITION | OBJECT | INTERFACE | SCALAR | ENUM\n`;\n",
12
- "import { getDirective } from '@graphql-tools/utils';\nimport type { GraphQLSchema } from 'graphql';\nimport type { CheckArgs, CheckDenial } from './check';\nimport { DEFAULT_ID_PATH } from './paths';\nimport { type FieldNode, type ReadOptions, scopeOf } from './scope';\nimport { assertRequirementShape } from './validate';\n\n/**\n * `@permission(name:, type:, id:, onDeny:, message:)` — one Keto question per\n * directive, the vocabulary `@nxgt/janus-graphql` uses. Declared in\n * `graphql/directives/permission.graphqls` and `PERMISSION_DIRECTIVE_SDL`.\n */\nexport const PERMISSION_DIRECTIVE_NAME = 'permission';\n\nexport type PermissionDenial = CheckDenial;\n\n/** One `@permission` as written, after its defaults. */\nexport type PermissionArgs = {\n\tname: string;\n\ttype: string;\n\tid: string;\n\tonDeny: PermissionDenial;\n\tmessage?: string;\n};\n\n/**\n * Every `@permission` on a field, in declaration order, validated, each as the\n * one-term requirement `@check` would spell `[[{ namespace: type, permit:\n * name, id }]]` — so the transform answers both through one path.\n */\nexport function readPermissions(\n\tschema: GraphQLSchema,\n\tnode: FieldNode,\n\twhere: string,\n\toptions: ReadOptions = {},\n): CheckArgs[] {\n\tif (!isOurs(schema)) return [];\n\tconst found = getDirective(schema, node, PERMISSION_DIRECTIVE_NAME) ?? [];\n\tconst scope = scopeOf(node, `@permission on ${where}`, options);\n\n\treturn found.map((raw) => {\n\t\tconst args = permissionArgs(raw);\n\t\tconst permissions = [\n\t\t\t[{ namespace: args.type, permit: args.name, id: args.id }],\n\t\t];\n\t\tassertRequirementShape(permissions, scope);\n\t\treturn { permissions, onDeny: args.onDeny, message: args.message };\n\t});\n}\n\nfunction permissionArgs(raw: Record<string, unknown>): PermissionArgs {\n\treturn {\n\t\tname: raw.name as string,\n\t\ttype: raw.type as string,\n\t\tid: (raw.id as string | null | undefined) ?? DEFAULT_ID_PATH,\n\t\tonDeny: (raw.onDeny ?? 'NOT_FOUND') as PermissionDenial,\n\t\tmessage: (raw.message as string | null | undefined) ?? undefined,\n\t};\n}\n\n/**\n * `@permission` is a common name. A schema that declares its own — without\n * `name` and `type` — keeps it: only the declaration this package ships (or\n * one of the same shape) is read as a Keto question.\n */\nfunction isOurs(schema: GraphQLSchema): boolean {\n\tconst declared = schema.getDirective(PERMISSION_DIRECTIVE_NAME);\n\tconst names = declared?.args.map((arg) => arg.name) ?? [];\n\treturn names.includes('name') && names.includes('type');\n}\n",
13
- "import type { DirectiveNode, GraphQLSchema } from 'graphql';\nimport { CHECK_DIRECTIVE_NAME, type CheckArgs, readChecks } from './check';\nimport { PERMISSION_DIRECTIVE_NAME, readPermissions } from './permission';\nimport type { FieldNode, ReadOptions } from './scope';\n\n/**\n * Every `@check` and `@permission` on a field, validated, in the order they\n * are written — across the two names, so a field migrating one directive at a\n * time keeps its 404-then-403 ladder.\n *\n * `getDirective` answers per name, so the interleaving is read back off the\n * field's AST. A field built without one (a schema made in code) has no order\n * to keep across names, and gets its `@check`s first.\n */\nexport function readRequirements(\n\tschema: GraphQLSchema,\n\tnode: FieldNode,\n\twhere: string,\n\toptions: ReadOptions = {},\n): CheckArgs[] {\n\tconst queues: Record<string, CheckArgs[]> = {\n\t\t[CHECK_DIRECTIVE_NAME]: readChecks(schema, node, where, options),\n\t\t[PERMISSION_DIRECTIVE_NAME]: readPermissions(schema, node, where, options),\n\t};\n\tconst ordered: CheckArgs[] = [];\n\tfor (const directive of directivesOf(node)) {\n\t\tconst next = queues[directive.name.value]?.shift();\n\t\tif (next) ordered.push(next);\n\t}\n\treturn [\n\t\t...ordered,\n\t\t...(queues[CHECK_DIRECTIVE_NAME] ?? []),\n\t\t...(queues[PERMISSION_DIRECTIVE_NAME] ?? []),\n\t];\n}\n\nfunction directivesOf(node: FieldNode): readonly DirectiveNode[] {\n\tconst field = node as {\n\t\tastNode?: { directives?: readonly DirectiveNode[] } | null;\n\t\tdirectives?: readonly DirectiveNode[];\n\t};\n\treturn field.astNode?.directives ?? field.directives ?? [];\n}\n",
14
- "/**\n * The directive declarations `graphql/directives/*.graphqls` ship, as strings,\n * for a schema assembled in code rather than loaded from `SHARED_SCHEMA_PATH`\n * — an edge runtime with no file system, or a test.\n *\n * The files are the source; these are copies of their declarations, without\n * the `#` comments, and `sdl.spec.ts` holds each equal to its file once both\n * are parsed and printed. Edit the file, then this.\n */\n\n/** `@check`, its `CheckPermission` input and its `CheckDenial` enum. */\nexport const CHECK_DIRECTIVE_SDL = `\"\"\"\nOne question, with the object left as a path instead of a value.\n\"\"\"\ninput CheckPermission {\n\t\"\"\"\n\tThe Keto namespace, e.g. \"Note\" — from the stack's OPL document.\n\t\"\"\"\n\tnamespace: String!\n\n\t\"\"\"\n\tThe permit asked of it, e.g. \"view\". A plain relation works too; Keto\n\tanswers \\`false\\`, not an error, for a name it does not know.\n\t\"\"\"\n\tpermit: String!\n\n\t\"\"\"\n\tWhere the object id is read: \\`args.<path>\\`, or \\`parent.<path>\\` /\n\t\\`source.<path>\\` (the same root under two names), dotted paths allowed. A value that turns out to be a LIST requires the permit on every\n\telement — that is what a mutation taking \\`ids: [ID!]!\\` means.\n\t\"\"\"\n\tid: String = \"args.id\"\n}\n\n\"\"\"\nWhat a denial looks like from outside.\n\"\"\"\nenum CheckDenial {\n\t\"\"\"\n\tThe same answer as for an id that never existed, so ids cannot be probed.\n\tThe default, and the one to keep unless the caller already knows the object\n\tis there.\n\t\"\"\"\n\tNOT_FOUND\n\n\t\"\"\"\n\tFor a second check on an object the caller can already see: a viewer asked\n\tto edit already knows it exists, and \"you may not change it\" is honest.\n\t\"\"\"\n\tFORBIDDEN\n}\n\n\"\"\"\nDeprecated: write \\`@permission(name:, type:)\\` in a new schema — one Keto\nquestion per directive, repeated for AND, with OR kept in the Keto model. This\nform keeps working and is evaluated in declaration order with @permission.\n\nThe permission a field requires, in disjunctive normal form: the OUTER list is\nOR, the INNER list is AND. \\`[[A, B], [C]]\\` reads \"(A and B) or C\" — the same\nshape \\`@policy(policies: [[\"ADMIN\"]])\\` uses.\n\nRepeatable, and evaluated in declaration order, each with its own \\`onDeny\\`.\nThat is how the 404-then-403 ladder is written:\n\n updateNote(id: ID!, input: UpdateNoteInput!): Note!\n @check(permissions: [[{ namespace: \"Note\", permit: \"view\" }]])\n @check(permissions: [[{ namespace: \"Note\", permit: \"edit\" }]], onDeny: FORBIDDEN)\n\nNOT for a field that answers a LIST the caller is entitled to. \"Which notes may\nI see\" is not a check, it is a Keto query folded into the database filter\nbefore the read. A directive there would have to fetch everything and filter\nafter, which makes \\`totalCount\\` and the cursors lie.\n\"\"\"\ndirective @check(\n\tpermissions: [[CheckPermission!]!]!\n\tonDeny: CheckDenial! = NOT_FOUND\n\n\t\"\"\"\n\tThe i18n key the denial carries, e.g. \"notes.errors.not-found\". Defaults to\n\t\\`errors.not-found\\` / \\`errors.insufficient-permissions\\`, the shared keys.\n\n\tSet it whenever the API's own service layer answers the same refusal with a\n\tdomain message. Two layers guard these fields — the directive, and the\n\t\\`require<M>Access\\` the service calls — and if they word the same 404\n\tdifferently, the wording tells a caller WHICH one refused: a generic message\n\tmeans \"you may not\", a domain one means \"it is gone\". That is precisely the\n\tdistinction NOT_FOUND exists to hide.\n\t\"\"\"\n\tmessage: String\n) repeatable on FIELD_DEFINITION\n`;\n\n/** `@permission` and its `PermissionDenial` enum. */\nexport const PERMISSION_DIRECTIVE_SDL = `\"\"\"\nWhat a refused @permission looks like from outside.\n\"\"\"\nenum PermissionDenial {\n\t\"\"\"\n\tThe same answer as for an id that never existed, so ids cannot be probed.\n\tThe default.\n\t\"\"\"\n\tNOT_FOUND\n\n\t\"\"\"\n\tFor a permission asked of an object the caller can already see: a viewer\n\tasked to edit already knows it exists, and \"you may not change it\" is\n\thonest.\n\t\"\"\"\n\tFORBIDDEN\n}\n\n\"\"\"\nThe permission a field requires: the caller must hold the permit \\`name\\` on the\n\\`type\\` object whose id \\`id\\` points at.\n\nRepeatable, and repeated ones are AND, evaluated in declaration order — the\n404-then-403 ladder:\n\n updateNote(id: ID!, input: UpdateNoteInput!): Note!\n @permission(name: \"view\", type: \"Note\")\n @permission(name: \"edit\", type: \"Note\", onDeny: FORBIDDEN)\n\nNOT for a field that answers a LIST the caller is entitled to: fold a Keto\nquery into the database filter before the read instead.\n\"\"\"\ndirective @permission(\n\t\"\"\"\n\tThe permit asked of Keto, e.g. \"view\". A plain relation works too; Keto\n\tanswers \\`false\\`, not an error, for a name it does not know.\n\t\"\"\"\n\tname: String!\n\n\t\"\"\"\n\tThe Keto namespace, e.g. \"Note\" — from the stack's OPL document.\n\t\"\"\"\n\ttype: String!\n\n\t\"\"\"\n\tWhere the object id is read: \\`args.<path>\\` or \\`parent.<path>\\`, dotted\n\tpaths allowed, \\`args.id\\` when omitted. A value that turns out to be a LIST\n\trequires the permit on every element.\n\t\"\"\"\n\tid: String\n\n\tonDeny: PermissionDenial! = NOT_FOUND\n\n\t\"\"\"\n\tThe i18n key the denial carries, e.g. \"notes.errors.not-found\". Defaults to\n\t\\`errors.not-found\\` / \\`errors.insufficient-permissions\\`, the shared keys.\n\tSet it when the service layer words the same refusal with a domain message,\n\tso the wording does not tell a caller which layer refused.\n\t\"\"\"\n\tmessage: String\n) repeatable on FIELD_DEFINITION\n`;\n\n/** Both, for `createSchema({ typeDefs: [KETO_DIRECTIVES_SDL, …] })`. */\nexport const KETO_DIRECTIVES_SDL = `${CHECK_DIRECTIVE_SDL}\\n${PERMISSION_DIRECTIVE_SDL}`;\n",
15
- "import type { YogaInitialContext, YogaServerInstance } from 'graphql-yoga';\nimport { Hono } from 'hono';\nimport { contextStorage } from 'hono/context-storage';\nimport { createMiddleware } from 'hono/factory';\nimport { languageDetector } from 'hono/language';\nimport { type RenderSandboxOptions, renderSandbox } from '../utils';\n\nexport function sandboxExpolorer(options: RenderSandboxOptions) {\n\treturn createMiddleware(async (ctx) => {\n\t\treturn ctx.html(renderSandbox(options));\n\t});\n}\n\ntype HonoYogaOptions = {\n\tsandbox?: RenderSandboxOptions & { endpoint?: string };\n};\n\nexport function honoYoga<\n\tServerContext extends Partial<YogaInitialContext>,\n\tUserContext extends {},\n>(yoga: YogaServerInstance<ServerContext, UserContext>) {\n\treturn createMiddleware(async (ctx) => {\n\t\tconst response = await yoga.fetch(ctx.req.raw);\n\n\t\treturn response;\n\t});\n}\n\nexport function createYogaHono<\n\tServerContext extends Partial<YogaInitialContext>,\n\tUserContext extends {},\n>(\n\tyoga: YogaServerInstance<ServerContext, UserContext>,\n\toptions?: HonoYogaOptions,\n) {\n\tconst app = new Hono();\n\n\tapp.use(contextStorage());\n\tapp.use(\n\t\tlanguageDetector({\n\t\t\torder: ['header'],\n\t\t\tsupportedLanguages: ['en', 'fr'],\n\t\t\tfallbackLanguage: 'en',\n\t\t\tcaches: [],\n\t\t}),\n\t);\n\n\tapp.get('/health', (ctx) => {\n\t\treturn ctx.json({ status: 'ok' }, 200);\n\t});\n\n\tapp.get(\n\t\toptions?.sandbox?.endpoint || 'sandbox',\n\t\tsandboxExpolorer(options?.sandbox || {}),\n\t);\n\n\tapp.use(yoga.graphqlEndpoint, honoYoga(yoga));\n\n\treturn app;\n}\n",
16
- "import {\n\tAUDIT_EVENT,\n\ttype Audit,\n\ttype AuditService,\n\tCommitType,\n} from '@nxgt/shared-mongo';\nimport { withFilter } from 'graphql-subscriptions';\n\n/**\n * Minimal structural shape of the app's pubsub instance. Kept structural so\n * this factory does not couple to a specific `graphql-yoga` `PubSub<...>`\n * instantiation.\n */\nexport type ChangeResolversPubSub = {\n\tsubscribe: (event: string) => any;\n};\n\n/**\n * Minimal structural shape of the context every subgraph builds: an\n * `AuditService` under `services.audit`, plus the module's own CRUD service\n * exposing `findById`.\n */\nexport type ChangeResolversContext = {\n\tservices: {\n\t\taudit: AuditService;\n\t\t[key: string]: any;\n\t};\n};\n\nexport type CreateChangeResolversConfig = {\n\t/**\n\t * Singular camelCase entity name used to build the resolver field names:\n\t * `bed` -> `bedChanges`, `bedChangesById`, `bedChanged`.\n\t */\n\tentity: string;\n\t/**\n\t * Mongo collection name, i.e. `BedModel.collection.collectionName`.\n\t */\n\tcollection: string;\n\t/**\n\t * Key of the module's CRUD service on `context.services`, i.e. `beds`.\n\t */\n\tservice: string;\n\t/**\n\t * The app's pubsub instance, or a getter returning it. Prefer the getter\n\t * form (`() => pubsub`) when the app can re-create its pubsub at runtime,\n\t * so the subscription always resolves against the current instance.\n\t */\n\tpubsub: ChangeResolversPubSub | (() => ChangeResolversPubSub);\n};\n\nexport type ChangeResolvers = {\n\tQuery: Record<string, any>;\n\tSubscription: Record<string, any>;\n};\n\n/**\n * Builds the audit change-stream resolver block that is otherwise repeated\n * verbatim in every module's `*.resolver.ts`: the two paginated `Changes`\n * queries and the `Changed` subscription.\n *\n * ```ts\n * const changes = createChangeResolvers({\n * entity: 'bed',\n * collection: BedModel.collection.collectionName,\n * service: 'beds',\n * pubsub: () => pubsub,\n * });\n *\n * export const beds: Resolvers = {\n * Query: { bed: ..., beds: ..., ...changes.Query },\n * Subscription: { ...changes.Subscription },\n * };\n * ```\n */\nexport function createChangeResolvers(\n\tconfig: CreateChangeResolversConfig,\n): ChangeResolvers {\n\tconst { entity, collection, service, pubsub } = config;\n\n\tconst resolvePubSub = () =>\n\t\ttypeof pubsub === 'function' ? pubsub() : pubsub;\n\n\treturn {\n\t\tQuery: {\n\t\t\t[`${entity}Changes`]: async (\n\t\t\t\t_parent: unknown,\n\t\t\t\targs: any,\n\t\t\t\tcontext: ChangeResolversContext,\n\t\t\t) =>\n\t\t\t\tcontext.services.audit.findChangesPaginatedByCollection(\n\t\t\t\t\tcollection,\n\t\t\t\t\targs,\n\t\t\t\t),\n\t\t\t[`${entity}ChangesById`]: async (\n\t\t\t\t_parent: unknown,\n\t\t\t\targs: any,\n\t\t\t\tcontext: ChangeResolversContext,\n\t\t\t) =>\n\t\t\t\tcontext.services.audit.findChangesPaginatedByCollectionAndOid(\n\t\t\t\t\targs.id,\n\t\t\t\t\tcollection,\n\t\t\t\t\targs,\n\t\t\t\t),\n\t\t},\n\t\tSubscription: {\n\t\t\t[`${entity}Changed`]: {\n\t\t\t\tresolve: async (\n\t\t\t\t\tpayload: Audit,\n\t\t\t\t\t_args: any,\n\t\t\t\t\tcontext: ChangeResolversContext,\n\t\t\t\t) => ({\n\t\t\t\t\tid: context.services.audit.extractId(payload),\n\t\t\t\t\tdata:\n\t\t\t\t\t\tpayload.type !== CommitType.TERMINAL\n\t\t\t\t\t\t\t? await context.services[service].findById(payload.state._id)\n\t\t\t\t\t\t\t: null,\n\t\t\t\t\ttype: payload.type,\n\t\t\t\t}),\n\t\t\t\tsubscribe: withFilter(\n\t\t\t\t\t() => resolvePubSub().subscribe(AUDIT_EVENT),\n\t\t\t\t\t(payload: any, _variables: any, context?: ChangeResolversContext) =>\n\t\t\t\t\t\tcontext\n\t\t\t\t\t\t\t? context.services.audit.matches(payload, { collection })\n\t\t\t\t\t\t\t: false,\n\t\t\t\t),\n\t\t\t},\n\t\t},\n\t};\n}\n",
17
- "export const SCALARS_MAPPING = {\n\tID: 'any',\n\tDateTime: 'any',\n\tDate: 'any',\n\tAny: 'any',\n\tBigInt: 'number',\n\tEmailAddress: 'string',\n\tGeoJSON: 'any',\n\tHSL: 'string',\n\tHSLA: 'string',\n\tHexColorCode: 'string',\n\tHexadecimal: 'string',\n\tIBAN: 'string',\n\tIP: 'string',\n\tTime: 'string',\n\tLocalTime: 'string',\n\tUUID: 'string',\n\tPositiveInt: 'number',\n\tNegativeInt: 'number',\n\tNonPositiveInt: 'number',\n\tNonNegativeInt: 'number',\n\tPositiveFloat: 'number',\n\tNegativeFloat: 'number',\n\tNonPositiveFloat: 'number',\n\tNonNegativeFloat: 'number',\n\tNonEmptyString: 'string',\n\tPostalCode: 'string',\n\tRGB: 'string',\n\tRGBA: 'string',\n\tSESSN: 'string',\n\tTimestamp: 'string',\n\tURL: 'string',\n\tUSCurrency: 'string',\n\tUTCOffset: 'string',\n\tLong: 'number',\n\tShort: 'number',\n\tByte: 'number',\n\tBigDecimal: 'string',\n\tBigInteger: 'string',\n\tChar: 'string',\n\tLocale: 'string',\n\tCountryCode: 'string',\n\tCountryName: 'string',\n\tAccountNumber: 'string',\n\tCurrencyCode: 'string',\n\tDuration: 'string',\n\tUrl: 'string',\n\tJSONObject: 'Record<string, any>',\n\tJSON: 'any',\n\tVoid: 'void',\n\tObjectID: 'any',\n\tUpload: 'File | Blob',\n\tEmail: 'string',\n\tPort: 'number',\n\tIPv4: 'string',\n\tIPv6: 'string',\n\tMAC: 'string',\n\tPassword: 'string',\n\tPhoneNumber: 'string',\n\tZIPCode: 'string',\n\tSSN: 'string',\n\tGUID: 'string',\n\tISBN: 'string',\n\tLatitude: 'number',\n\tLongitude: 'number',\n\tJWT: 'string',\n};\n",
18
- "import { cast } from '@nxgt/shared/helpers';\nimport {\n\ttype HydratedDocument,\n\ttype IConnection,\n\ttype Model,\n\ttype mongoose,\n\ttype PaginationOptions,\n\tpaginateList,\n\ttype QueryFilter,\n\ttype SimplePaginationOptions,\n} from '@nxgt/shared-mongo';\nimport DataLoader from 'dataloader';\nimport { isArray } from 'lodash';\n\nexport function createDataLoader<K, V>(\n\tbatchLoadFn: DataLoader.BatchLoadFn<K, V>,\n\toptions?: DataLoader.Options<K, V, K>,\n) {\n\treturn new DataLoader(batchLoadFn, options);\n}\n\nexport function createConnectionListDataLoader<K, V>(\n\tpath: keyof K,\n\tmodel: Model<V, any, any, any, any, any, any>,\n\toptions: PaginationOptions,\n) {\n\treturn createDataLoader<K, IConnection<HydratedDocument<V>>>(async (docs) => {\n\t\tconst data: HydratedDocument<V>[] = await model\n\t\t\t.find({\n\t\t\t\t...(options.filter ?? {}),\n\t\t\t\t_id: docs.flatMap((doc) => {\n\t\t\t\t\tconst ids = doc[path] ?? [];\n\t\t\t\t\treturn isArray(ids)\n\t\t\t\t\t\t? cast<mongoose.Schema.Types.ObjectId[]>(\n\t\t\t\t\t\t\t\tids.filter(\n\t\t\t\t\t\t\t\t\t(item) =>\n\t\t\t\t\t\t\t\t\t\t!!item &&\n\t\t\t\t\t\t\t\t\t\t!['undefined', 'null'].includes((item as any)?.toString()),\n\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\t: [];\n\t\t\t\t}),\n\t\t\t})\n\t\t\t.exec();\n\t\treturn cast(\n\t\t\tdocs.map((doc) =>\n\t\t\t\tmodel.paginateList(\n\t\t\t\t\tdata.filter((child) =>\n\t\t\t\t\t\tcast<mongoose.Schema.Types.ObjectId[]>(doc[path] ?? [])\n\t\t\t\t\t\t\t.map((item) => item.toString())\n\t\t\t\t\t\t\t.includes((child._id as any).toString()),\n\t\t\t\t\t),\n\t\t\t\t\toptions,\n\t\t\t\t),\n\t\t\t),\n\t\t);\n\t});\n}\n\nexport function createChildrenConnectionDataLoader<K, V>(\n\tpath: keyof V,\n\tmodel: Model<V, any, any, any, any, any, any>,\n\toptions: PaginationOptions,\n) {\n\treturn createDataLoader<\n\t\tHydratedDocument<K>,\n\t\tIConnection<HydratedDocument<V>>\n\t>(async (docs) => {\n\t\tconst filter = {} as any;\n\t\tfilter[path] = docs.map((doc) => doc._id);\n\t\tconst data: HydratedDocument<V>[] = await model.find(filter).exec();\n\t\treturn cast(\n\t\t\tdocs.map((doc) =>\n\t\t\t\tpaginateList(\n\t\t\t\t\tdata.filter(\n\t\t\t\t\t\t(child) => doc._id?.toString() === (child[path] as any)?.toString(),\n\t\t\t\t\t) as any,\n\t\t\t\t\toptions,\n\t\t\t\t),\n\t\t\t),\n\t\t);\n\t});\n}\n\nexport function createSimpleListDataLoader<K, V>(\n\tpath: keyof K,\n\tmodel: Model<V, any, any, any, any, any, any>,\n\toptions?: SimplePaginationOptions,\n) {\n\treturn createDataLoader<K, HydratedDocument<V>[]>(async (docs) => {\n\t\tconst filter: QueryFilter<any> = options?.filter ?? {};\n\t\tconst ids = docs.flatMap((doc) => {\n\t\t\tconst ids = doc[path] ?? [];\n\t\t\treturn isArray(ids) ? cast<mongoose.Schema.Types.ObjectId[]>(ids) : [];\n\t\t});\n\t\tfilter._id = ids;\n\t\tconst query = model.find(filter);\n\t\tconst data: HydratedDocument<V>[] = await query.exec();\n\t\treturn cast(\n\t\t\tdocs.map((doc) => {\n\t\t\t\tconst result = data.filter((child) =>\n\t\t\t\t\tcast<mongoose.Schema.Types.ObjectId[]>(doc[path] ?? [])\n\t\t\t\t\t\t.map((item) => item.toString())\n\t\t\t\t\t\t.includes((child._id as any).toString()),\n\t\t\t\t);\n\t\t\t\tif (options?.skip && options?.limit) {\n\t\t\t\t\treturn result.slice(options.skip, options.skip + options.limit);\n\t\t\t\t}\n\t\t\t\tif (options?.limit) {\n\t\t\t\t\treturn result.slice(0, options.limit);\n\t\t\t\t}\n\t\t\t\tif (options?.skip) {\n\t\t\t\t\treturn result.slice(options.skip);\n\t\t\t\t}\n\t\t\t\treturn result;\n\t\t\t}),\n\t\t);\n\t});\n}\n\nexport function createChildrenListDataLoader<K, V>(\n\tpath: keyof V,\n\tmodel: Model<V, any, any, any, any, any, any>,\n\toptions?: SimplePaginationOptions,\n) {\n\treturn createDataLoader<HydratedDocument<K>, HydratedDocument<V>[]>(\n\t\tasync (docs) => {\n\t\t\tconst filter: QueryFilter<any> = options?.filter ?? {};\n\t\t\tconst key = path as any;\n\t\t\tfilter[key] = docs.map((doc) => doc._id);\n\t\t\tconst query = model.find(filter);\n\t\t\tconst data: HydratedDocument<V>[] = await query.exec();\n\t\t\treturn cast(\n\t\t\t\tdocs.map((doc) => {\n\t\t\t\t\tconst result = data.filter(\n\t\t\t\t\t\t(child) => child[path]?.toString() === (doc._id as any).toString(),\n\t\t\t\t\t);\n\n\t\t\t\t\tif (options?.skip && options?.limit) {\n\t\t\t\t\t\treturn result.slice(options.skip, options.skip + options.limit);\n\t\t\t\t\t}\n\t\t\t\t\tif (options?.limit) {\n\t\t\t\t\t\treturn result.slice(0, options.limit);\n\t\t\t\t\t}\n\t\t\t\t\tif (options?.skip) {\n\t\t\t\t\t\treturn result.slice(options.skip);\n\t\t\t\t\t}\n\t\t\t\t\treturn result;\n\t\t\t\t}),\n\t\t\t);\n\t\t},\n\t);\n}\n\nexport function createSingleChildDataLoader<K, V extends { id: string }>(\n\tpath: keyof K,\n\tmodel: Model<V, any, any, any, any, any, any>,\n) {\n\treturn createDataLoader<K, HydratedDocument<V> | null>(async (docs) => {\n\t\tconst data: HydratedDocument<V>[] = await model\n\t\t\t.find({\n\t\t\t\t_id: docs\n\t\t\t\t\t.map((doc) => cast<mongoose.Schema.Types.ObjectId>(doc[path]))\n\t\t\t\t\t.filter(\n\t\t\t\t\t\t(item) =>\n\t\t\t\t\t\t\t!!item && !['undefined', 'null'].includes(item?.toString()),\n\t\t\t\t\t),\n\t\t\t})\n\t\t\t.exec();\n\n\t\tconst map = new Map<string, HydratedDocument<V>>(\n\t\t\tdata.map((doc) => [doc.id, doc]),\n\t\t);\n\t\treturn docs.map((doc) => map.get(doc[path]?.toString() ?? '') ?? null);\n\t});\n}\n\nexport function createEntitiesReferenceLoader<V extends { id: string }>(\n\tmodel: Model<V, any, any, any, any, any, any>,\n) {\n\treturn createDataLoader<string, HydratedDocument<V> | null>(async (ids) => {\n\t\tconst docs: HydratedDocument<V>[] = await model\n\t\t\t.find({\n\t\t\t\t_id: ids.filter(\n\t\t\t\t\t(item) => !!item && !['undefined', 'null'].includes(item?.toString()),\n\t\t\t\t),\n\t\t\t})\n\t\t\t.exec();\n\n\t\tconst map = new Map<string, HydratedDocument<V>>(\n\t\t\tdocs.map((doc) => [doc.id, doc]),\n\t\t);\n\n\t\treturn ids.map((id) => map.get(id) ?? null);\n\t}) as DataLoader<string, HydratedDocument<V> | null>;\n}\n",
19
- "import { GraphQLError, type GraphQLErrorOptions } from 'graphql';\n\nexport function createGraphQLError(\n\tmessage: string,\n\toptions?: GraphQLErrorOptions,\n): GraphQLError {\n\treturn new GraphQLError(message, options);\n}\n",
20
- "import type { ApolloServerOptions } from '@apollo/server';\nimport {\n\tApolloServerErrorCode,\n\tunwrapResolverError,\n} from '@apollo/server/errors';\nimport {\n\ttype LocaleKey,\n\ttype TranslationContext,\n\ttranslate as translateBase,\n} from '@nxgt/i18n';\nimport { CustomException, ErrorCode } from '@nxgt/shared-exceptions';\nimport { MONGO_UTILS, mongoose } from '@nxgt/shared-mongo';\nimport { kebabCase } from 'lodash';\nimport type { GraphQLBaseContext } from '../../types';\nimport { isOryUnavailable, serviceUnavailableError } from './ory-unavailable';\n\n/**\n * Apollo Server's `formatError`, taught this repo's exceptions — the Apollo\n * counterpart of `createMaskError`. `OryUnavailable` answers\n * `SERVICE_UNAVAILABLE`, never a denial and never an opaque\n * `INTERNAL_SERVER_ERROR`.\n */\nexport function createFormatError<\n\tK extends LocaleKey,\n\tC extends GraphQLBaseContext = GraphQLBaseContext,\n>(\n\ttranslate: (\n\t\tmessage: K,\n\t\tcontext?: TranslationContext,\n\t) => string = translateBase,\n\tproduction?: boolean,\n): ApolloServerOptions<C>['formatError'] {\n\treturn (formattedError, graphQLError) => {\n\t\tif (production && formattedError.extensions?.stacktrace) {\n\t\t\tformattedError.extensions.stacktrace = undefined;\n\t\t}\n\t\tconst error = unwrapResolverError(graphQLError);\n\t\tif (isOryUnavailable(error)) {\n\t\t\tconst unavailable = serviceUnavailableError(error);\n\t\t\treturn {\n\t\t\t\t...formattedError,\n\t\t\t\tmessage: unavailable.message,\n\t\t\t\textensions: { ...formattedError.extensions, ...unavailable.extensions },\n\t\t\t};\n\t\t}\n\t\tif (\n\t\t\terror instanceof CustomException ||\n\t\t\terror instanceof mongoose.MongooseError\n\t\t) {\n\t\t\tconst exception =\n\t\t\t\terror instanceof mongoose.MongooseError\n\t\t\t\t\t? MONGO_UTILS.castError(error)\n\t\t\t\t\t: (error as CustomException);\n\t\t\treturn {\n\t\t\t\t...formattedError,\n\t\t\t\tmessage:\n\t\t\t\t\texception.errorCode === ErrorCode.ValidationError\n\t\t\t\t\t\t? exception.message\n\t\t\t\t\t\t: translate(exception.message as K, exception.options),\n\t\t\t\textensions: {\n\t\t\t\t\t...formattedError.extensions,\n\t\t\t\t\tcode: exception.errorCode,\n\t\t\t\t\tdebugMessage: exception.debugMessage,\n\t\t\t\t},\n\t\t\t};\n\t\t}\n\t\tif (\n\t\t\t[\n\t\t\t\tApolloServerErrorCode.GRAPHQL_VALIDATION_FAILED,\n\t\t\t\tApolloServerErrorCode.BAD_REQUEST,\n\t\t\t\tApolloServerErrorCode.BAD_USER_INPUT,\n\t\t\t\tApolloServerErrorCode.GRAPHQL_PARSE_FAILED,\n\t\t\t\tApolloServerErrorCode.OPERATION_RESOLUTION_FAILURE,\n\t\t\t\tApolloServerErrorCode.PERSISTED_QUERY_NOT_FOUND,\n\t\t\t\tApolloServerErrorCode.PERSISTED_QUERY_NOT_SUPPORTED,\n\t\t\t].includes(formattedError.extensions?.code as any)\n\t\t) {\n\t\t\treturn {\n\t\t\t\t...formattedError,\n\t\t\t\tmessage: translate(\n\t\t\t\t\t`errors.${kebabCase(formattedError.extensions?.code as string)}` as K,\n\t\t\t\t\t{},\n\t\t\t\t),\n\t\t\t\textensions: {\n\t\t\t\t\t...formattedError.extensions,\n\t\t\t\t\tdebugMessage: formattedError.message,\n\t\t\t\t},\n\t\t\t};\n\t\t}\n\t\treturn formattedError;\n\t};\n}\n",
21
- "import type { OryUnavailable } from '@nxgt/ory-sdk';\nimport { ErrorCode } from '@nxgt/shared-exceptions';\nimport { GraphQLError } from 'graphql';\n\n/**\n * Whether an error is `@nxgt/ory-sdk`'s `OryUnavailable` — Kratos, Hydra or\n * Keto could not answer.\n *\n * By name and shape as well as by class: an install that resolves two copies\n * of `@nxgt/ory-sdk` (one under this package, one under the app) throws an\n * `OryUnavailable` this module's `instanceof` does not recognise, and an\n * outage that slips past here is masked as a 500 instead of answered as a 503.\n */\nexport function isOryUnavailable(error: unknown): error is OryUnavailable {\n\tif (!(error instanceof Error)) return false;\n\tconst service = (error as { service?: unknown }).service;\n\treturn error.name === 'OryUnavailable' && typeof service === 'string';\n}\n\n/**\n * A 503 the client can read as one — a real `GraphQLError` so Yoga's masking\n * leaves it alone, `extensions.http.status` so the transport says 503 too.\n * Never a denial: an outage must not read as \"not signed in\" or \"not allowed\".\n */\nexport function serviceUnavailableError(error: OryUnavailable): GraphQLError {\n\treturn new GraphQLError(`ory: ${error.service} is unavailable`, {\n\t\textensions: {\n\t\t\tcode: ErrorCode.ServiceUnavailable,\n\t\t\thttp: { status: 503 },\n\t\t\tdebugMessage: error.message,\n\t\t},\n\t});\n}\n",
22
- "import {\n\ttype LocaleKey,\n\ttype TranslationContext,\n\ttranslate as translateBase,\n} from '@nxgt/i18n';\nimport { CustomException, ErrorCode } from '@nxgt/shared-exceptions';\nimport { MONGO_UTILS, mongoose } from '@nxgt/shared-mongo';\nimport { GraphQLError } from 'graphql';\nimport type { MaskError } from 'graphql-yoga';\nimport { isOryUnavailable, serviceUnavailableError } from './ory-unavailable';\n\ntype Translate<K extends LocaleKey> = (\n\tmessage: K,\n\tcontext?: TranslationContext,\n) => string;\n\n/**\n * Yoga's `maskedErrors.maskError`, taught this repo's exceptions.\n *\n * Yoga masks anything that is not a `GraphQLError` as \"Unexpected error.\" —\n * and `CustomException` extends `Error`, so out of the box a service's\n * `notFound()` or `forbidden()` reaches the client as an opaque 500. This\n * turns one into a `GraphQLError` with the translated message, the\n * exception's `code` in `extensions`, and a matching HTTP status\n * (`UNAUTHENTICATED` 401, `FORBIDDEN` 403, `NOT_FOUND` 404); a Mongoose error\n * goes through `castError` first, as `createFormatError` does for Apollo.\n * `OryUnavailable` (@nxgt/ory-sdk) becomes a 503 `SERVICE_UNAVAILABLE`, never\n * a denial. Everything else is masked as Yoga's default masks it: a\n * `GraphQLError` thrown on purpose — or raised by validation — passes, and one\n * that only wraps a plain `Error` a resolver threw is replaced by `message`,\n * so an internal message never reaches the client.\n *\n * createYoga({ maskedErrors: { maskError: createMaskError(translate) } })\n */\nexport function createMaskError<K extends LocaleKey>(\n\ttranslate: Translate<K> = translateBase,\n): MaskError {\n\treturn (error, message, isDev) => {\n\t\tconst original =\n\t\t\terror instanceof GraphQLError && error.originalError\n\t\t\t\t? error.originalError\n\t\t\t\t: error;\n\n\t\tif (isOryUnavailable(original)) return serviceUnavailableError(original);\n\n\t\tif (\n\t\t\toriginal instanceof CustomException ||\n\t\t\toriginal instanceof mongoose.MongooseError\n\t\t) {\n\t\t\treturn exceptionError(original, translate);\n\t\t}\n\n\t\tif (isOriginalGraphQLError(error)) return error;\n\t\treturn new GraphQLError(message, {\n\t\t\t...locationOf(error),\n\t\t\textensions: isDev\n\t\t\t\t? {\n\t\t\t\t\t\tcode: ErrorCode.InternalServerError,\n\t\t\t\t\t\tdebugMessage: String(original),\n\t\t\t\t\t}\n\t\t\t\t: { code: ErrorCode.InternalServerError },\n\t\t});\n\t};\n}\n\nfunction exceptionError<K extends LocaleKey>(\n\toriginal: CustomException | mongoose.MongooseError,\n\ttranslate: Translate<K>,\n): GraphQLError {\n\tconst exception =\n\t\toriginal instanceof mongoose.MongooseError\n\t\t\t? MONGO_UTILS.castError(original)\n\t\t\t: original;\n\t// The exception carries the status itself.\n\tconst status = exception.code;\n\treturn new GraphQLError(\n\t\texception.errorCode === ErrorCode.ValidationError\n\t\t\t? exception.message\n\t\t\t: translate(exception.message as K, exception.options),\n\t\t{\n\t\t\textensions: {\n\t\t\t\tcode: exception.errorCode,\n\t\t\t\t...(status ? { http: { status } } : {}),\n\t\t\t\t...(exception.debugMessage\n\t\t\t\t\t? { debugMessage: exception.debugMessage }\n\t\t\t\t\t: {}),\n\t\t\t},\n\t\t},\n\t);\n}\n\n/**\n * Yoga's own test: a `GraphQLError` is \"original\" when it — or the error it\n * wraps, all the way down — was a `GraphQLError` to begin with. Graphql-js\n * wraps every resolver error in one, so `instanceof GraphQLError` alone lets\n * a plain `Error`'s message through.\n */\nfunction isOriginalGraphQLError(error: unknown): error is GraphQLError {\n\tif (!(error instanceof GraphQLError)) return false;\n\treturn error.originalError == null\n\t\t? true\n\t\t: isOriginalGraphQLError(error.originalError);\n}\n\n/** Where the masked error happened, kept so the client still sees a `path`. */\nfunction locationOf(error: unknown) {\n\tif (!(error instanceof GraphQLError)) return {};\n\treturn {\n\t\tnodes: error.nodes,\n\t\tsource: error.source,\n\t\tpositions: error.positions,\n\t\tpath: error.path,\n\t};\n}\n",
23
- "import { createRedisEventTarget } from '@graphql-yoga/redis-event-target';\nimport { createPubSub } from 'graphql-yoga';\nimport type { Redis } from 'ioredis';\n\nexport const createYogaPubSub = ({\n\tpublishClient,\n\tsubscribeClient,\n}: {\n\tpublishClient: Redis;\n\tsubscribeClient: Redis;\n}) => {\n\tconst eventTarget = createRedisEventTarget({\n\t\tpublishClient,\n\t\tsubscribeClient,\n\t});\n\n\treturn createPubSub({ eventTarget });\n};\n",
9
+ "import { getDirective } from '@graphql-tools/utils';\nimport type { PermissionRequirement } from '@nxgt/ory-sdk';\nimport type { GraphQLSchema } from 'graphql';\nimport { DEFAULT_ID_PATH } from './paths';\nimport { type FieldNode, type ReadOptions, scopeOf } from './scope';\nimport { assertRequirementShape } from './validate';\n\n/**\n * `@permission(name:, type:, id:, onDeny:, message:)` — one Keto question per\n * directive, the vocabulary `@nxgt/janus-graphql` uses. Declared in\n * `graphql/directives/permission.graphqls` and `PERMISSION_DIRECTIVE_SDL`.\n */\nexport const PERMISSION_DIRECTIVE_NAME = 'permission';\n\nexport type PermissionDenial = 'NOT_FOUND' | 'FORBIDDEN';\n\n/** One `@permission` as written, after its defaults. */\nexport type PermissionArgs = {\n\tname: string;\n\ttype: string;\n\tid: string;\n\tonDeny: PermissionDenial;\n\tmessage?: string;\n};\n\n/**\n * One `@permission` as the transform answers it: the one-term requirement\n * `[[{ namespace: type, permit: name, id }]]` that `evaluateRequirement`\n * takes, its denial, and its i18n key.\n */\nexport type FieldPermission = {\n\tpermissions: PermissionRequirement;\n\tonDeny: PermissionDenial;\n\t/** i18n key; the shared `errors.*` one when the field does not say. */\n\tmessage?: string;\n};\n\n/**\n * Every `@permission` on a field, in declaration order, validated.\n *\n * Repeatable, so this is a list and the order is load-bearing: `view` then\n * `edit` is what turns a denial into 404 for a stranger and 403 for a viewer.\n * The `id` and `onDeny` defaults are applied here as well as in the SDL, which\n * graphql 17 does not always hand to `getDirective`.\n */\nexport function readPermissions(\n\tschema: GraphQLSchema,\n\tnode: FieldNode,\n\twhere: string,\n\toptions: ReadOptions = {},\n): FieldPermission[] {\n\tif (!isOurs(schema)) return [];\n\tconst found = getDirective(schema, node, PERMISSION_DIRECTIVE_NAME) ?? [];\n\tconst scope = scopeOf(node, `@permission on ${where}`, options);\n\n\treturn found.map((raw) => {\n\t\tconst args = permissionArgs(raw);\n\t\tconst permissions = [\n\t\t\t[{ namespace: args.type, permit: args.name, id: args.id }],\n\t\t];\n\t\tassertRequirementShape(permissions, scope);\n\t\treturn { permissions, onDeny: args.onDeny, message: args.message };\n\t});\n}\n\nfunction permissionArgs(raw: Record<string, unknown>): PermissionArgs {\n\treturn {\n\t\tname: raw.name as string,\n\t\ttype: raw.type as string,\n\t\tid: (raw.id as string | null | undefined) ?? DEFAULT_ID_PATH,\n\t\tonDeny: (raw.onDeny ?? 'NOT_FOUND') as PermissionDenial,\n\t\tmessage: (raw.message as string | null | undefined) ?? undefined,\n\t};\n}\n\n/**\n * `@permission` is a common name. A schema that declares its own — without\n * `name` and `type` — keeps it: only the declaration this package ships (or\n * one of the same shape) is read as a Keto question.\n */\nfunction isOurs(schema: GraphQLSchema): boolean {\n\tconst declared = schema.getDirective(PERMISSION_DIRECTIVE_NAME);\n\tconst names = declared?.args.map((arg) => arg.name) ?? [];\n\treturn names.includes('name') && names.includes('type');\n}\n",
10
+ "import type { getDirective } from '@graphql-tools/utils';\nimport type { RequirementScope } from './validate';\n\n/** A field definition or a field config — whatever `getDirective` reads. */\nexport type FieldNode = Parameters<typeof getDirective>[1];\n\n/** What a schema may add to the build-time checks of `@permission`. */\nexport type ReadOptions = {\n\t/**\n\t * The namespaces of the stack's OPL document. When given, a `type`\n\t * outside it is refused at build.\n\t */\n\tnamespaces?: readonly string[];\n};\n\n/**\n * The scope a field's requirements are validated in: the message prefix, the\n * arguments the field declares — read from a field config's `args` map or a\n * definition node's `arguments` list — and the known namespaces.\n */\nexport function scopeOf(\n\tnode: FieldNode,\n\twhere: string,\n\toptions: ReadOptions,\n): RequirementScope {\n\treturn {\n\t\twhere,\n\t\targumentNames: argumentNamesOf(node),\n\t\tnamespaces: options.namespaces,\n\t};\n}\n\nfunction argumentNamesOf(node: FieldNode): string[] {\n\tconst field = node as {\n\t\targs?: Record<string, unknown> | { name: string }[];\n\t\targuments?: readonly { name: { value: string } }[];\n\t};\n\tif (Array.isArray(field.args)) return field.args.map((arg) => arg.name);\n\tif (field.args) return Object.keys(field.args);\n\treturn field.arguments?.map((arg) => arg.name.value) ?? [];\n}\n",
11
+ "import { assertRequirement, type PermissionRequirement } from '@nxgt/ory-sdk';\nimport { assertDeclaredArgument, assertReadablePath } from './paths';\n\n/**\n * What a requirement is checked against when the schema is built.\n *\n * `namespaces` is optional: without it any namespace is taken on trust. With\n * it — the namespaces of the stack's OPL document — a misspelt `type` stops\n * the server from booting instead of answering `false` for ever, which Keto\n * does, without an error, for a namespace it does not know.\n */\nexport type RequirementScope = {\n\t/** `@permission on Query.note` — the directive and the field, for the message. */\n\twhere: string;\n\targumentNames: readonly string[];\n\tnamespaces?: readonly string[];\n};\n\n/**\n * Every mistake a requirement can carry that is visible without a request, as\n * a `TypeError` naming the field: an empty name or type, a path naming no\n * root, an argument the field does not declare, and a namespace the model\n * does not have.\n */\nexport function assertRequirementShape(\n\tpermissions: PermissionRequirement,\n\tscope: RequirementScope,\n) {\n\tconst { where, argumentNames, namespaces } = scope;\n\ttry {\n\t\tassertRequirement(permissions, where);\n\t} catch (error) {\n\t\tthrow new TypeError((error as Error).message);\n\t}\n\tfor (const group of permissions) {\n\t\tfor (const term of group) {\n\t\t\tassertReadablePath(term, where);\n\t\t\tassertDeclaredArgument(term, argumentNames, where);\n\t\t\tif (namespaces && !namespaces.includes(term.namespace)) {\n\t\t\t\tthrow new TypeError(\n\t\t\t\t\t`${where}: unknown namespace ${JSON.stringify(term.namespace)} — known: ${namespaces.join(', ')}`,\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\t}\n}\n",
12
+ "/**\n * The directive declarations `graphql/directives/*.graphqls` ship, as strings,\n * for a schema assembled in code rather than loaded from `SHARED_SCHEMA_PATH`\n * — an edge runtime with no file system, or a test.\n *\n * The files are the source; these are copies of their declarations, without\n * the `#` comments, and `sdl.spec.ts` holds each equal to its file once both\n * are parsed and printed. Edit the file, then this.\n */\n\n/** `@permission` and its `PermissionDenial` enum. */\nexport const PERMISSION_DIRECTIVE_SDL = `\"\"\"\nWhat a refused @permission looks like from outside.\n\"\"\"\nenum PermissionDenial {\n\t\"\"\"\n\tThe same answer as for an id that never existed, so ids cannot be probed.\n\tThe default.\n\t\"\"\"\n\tNOT_FOUND\n\n\t\"\"\"\n\tFor a permission asked of an object the caller can already see: a viewer\n\tasked to edit already knows it exists, and \"you may not change it\" is\n\thonest.\n\t\"\"\"\n\tFORBIDDEN\n}\n\n\"\"\"\nThe permission a field requires: the caller must hold the permit \\`name\\` on the\n\\`type\\` object whose id \\`id\\` points at.\n\nRepeatable, and repeated ones are AND, evaluated in declaration order — the\n404-then-403 ladder:\n\n updateNote(id: ID!, input: UpdateNoteInput!): Note!\n @permission(name: \"view\", type: \"Note\")\n @permission(name: \"edit\", type: \"Note\", onDeny: FORBIDDEN)\n\nNOT for a field that answers a LIST the caller is entitled to: fold a Keto\nquery into the database filter before the read instead.\n\"\"\"\ndirective @permission(\n\t\"\"\"\n\tThe permit asked of Keto, e.g. \"view\". A plain relation works too; Keto\n\tanswers \\`false\\`, not an error, for a name it does not know.\n\t\"\"\"\n\tname: String!\n\n\t\"\"\"\n\tThe Keto namespace, e.g. \"Note\" — from the stack's OPL document.\n\t\"\"\"\n\ttype: String!\n\n\t\"\"\"\n\tWhere the object id is read: \\`args.<path>\\` or \\`parent.<path>\\`, dotted\n\tpaths allowed, \\`args.id\\` when omitted. A value that turns out to be a LIST\n\trequires the permit on every element.\n\t\"\"\"\n\tid: String\n\n\tonDeny: PermissionDenial! = NOT_FOUND\n\n\t\"\"\"\n\tThe i18n key the denial carries, e.g. \"notes.errors.not-found\". Defaults to\n\t\\`errors.not-found\\` / \\`errors.insufficient-permissions\\`, the shared keys.\n\tSet it when the service layer words the same refusal with a domain message,\n\tso the wording does not tell a caller which layer refused.\n\t\"\"\"\n\tmessage: String\n) repeatable on FIELD_DEFINITION\n`;\n\n/**\n * Every directive `useKetoChecks` answers, for\n * `createSchema({ typeDefs: [KETO_DIRECTIVES_SDL, …] })`. Since `@check` was\n * removed in 3.0, that is `@permission` alone.\n */\nexport const KETO_DIRECTIVES_SDL = PERMISSION_DIRECTIVE_SDL;\n\n/**\n * `@authenticated`, with the `type:` `useAuthenticated` reads: any caller\n * without it, a caller of one of the types with it. Part of\n * `SHARED_TYPE_DEFS`, and not in `graphql/`: a federation subgraph loads\n * `SHARED_SCHEMA_PATH` and imports federation's own `@authenticated`, which\n * takes no argument — a shape `useAuthenticated` reads as \"any caller\".\n */\nexport const AUTHENTICATED_DIRECTIVE_SDL = `\"\"\"\nA signed-in caller — of one of the types \\`type\\` names, when it names some.\n\"\"\"\ndirective @authenticated(\n\t\"\"\"\n\tThe kinds of caller admitted: \"session\" or \"token\" by default. Any caller\n\twhen omitted.\n\t\"\"\"\n\ttype: [String!]\n) on FIELD_DEFINITION | OBJECT | INTERFACE | SCALAR | ENUM\n`;\n",
13
+ "import type { YogaInitialContext, YogaServerInstance } from 'graphql-yoga';\nimport { Hono } from 'hono';\nimport { contextStorage } from 'hono/context-storage';\nimport { createMiddleware } from 'hono/factory';\nimport { languageDetector } from 'hono/language';\nimport { type RenderSandboxOptions, renderSandbox } from '../utils/sandbox';\n\nexport function sandboxExplorer(options: RenderSandboxOptions) {\n\treturn createMiddleware(async (ctx) => {\n\t\treturn ctx.html(renderSandbox(options));\n\t});\n}\n\ntype HonoYogaOptions = {\n\tsandbox?: RenderSandboxOptions & { endpoint?: string };\n};\n\nexport function honoYoga<\n\tServerContext extends Partial<YogaInitialContext>,\n\tUserContext extends {},\n>(yoga: YogaServerInstance<ServerContext, UserContext>) {\n\treturn createMiddleware(async (ctx) => {\n\t\tconst response = await yoga.fetch(ctx.req.raw);\n\n\t\treturn response;\n\t});\n}\n\nexport function createYogaHono<\n\tServerContext extends Partial<YogaInitialContext>,\n\tUserContext extends {},\n>(\n\tyoga: YogaServerInstance<ServerContext, UserContext>,\n\toptions?: HonoYogaOptions,\n) {\n\tconst app = new Hono();\n\n\tapp.use(contextStorage());\n\tapp.use(\n\t\tlanguageDetector({\n\t\t\torder: ['header'],\n\t\t\tsupportedLanguages: ['en', 'fr'],\n\t\t\tfallbackLanguage: 'en',\n\t\t\tcaches: [],\n\t\t}),\n\t);\n\n\tapp.get('/health', (ctx) => {\n\t\treturn ctx.json({ status: 'ok' }, 200);\n\t});\n\n\tapp.get(\n\t\toptions?.sandbox?.endpoint || 'sandbox',\n\t\tsandboxExplorer(options?.sandbox || {}),\n\t);\n\n\tapp.use(yoga.graphqlEndpoint, honoYoga(yoga));\n\n\treturn app;\n}\n",
24
14
  "import { html } from 'hono/html';\n\nexport type RenderSandboxOptions = {\n\tport?: number;\n\tgraphqlEndpoint?: string;\n\tprotocol?: string;\n\thostname?: string;\n\ttitle?: string;\n};\n\nexport const renderSandbox = ({\n\tport = 8080,\n\thostname = 'localhost',\n\tgraphqlEndpoint = 'graphql',\n\tprotocol = 'http',\n\ttitle = 'Sandbox Explorer',\n}: RenderSandboxOptions) => html`\n<title>${title}</title>\n<div id=\"sandbox\" style=\"position:absolute;top:0;right:0;bottom:0;left:0\"></div>\n<script src=\"https://embeddable-sandbox.cdn.apollographql.com/_latest/embeddable-sandbox.umd.production.min.js\"></script>\n<script>\n new window.EmbeddedSandbox({\n target: \"#sandbox\",\n // Pass through your server href if you are embedding on an endpoint.\n // Otherwise, you can pass whatever endpoint you want Sandbox to start up with here.\n initialEndpoint: \"${protocol}://${hostname}:${port}/${graphqlEndpoint}\",\n handleRequest: (endpointUrl, options) => {\n return fetch(endpointUrl, {\n ...options,\n headers: {\n ...options.headers\n },\n })\n },\n hideCookieToggle: true,\n });\n // advanced options: https://www.apollographql.com/docs/studio/explorer/sandbox#embedding-sandbox\n</script>\n\n`;\n",
25
- "import { existsSync } from 'node:fs';\nimport { dirname, join } from 'node:path';\nimport { fileURLToPath } from 'node:url';\nimport { buildSubgraphSchema as buildSubgraphSchemaBase } from '@apollo/subgraph';\nimport { loadFilesSync } from '@graphql-tools/load-files';\nimport { mergeTypeDefs } from '@graphql-tools/merge';\nimport { pruneSchema } from '@graphql-tools/utils';\nimport { printSchema } from 'graphql';\n\n/**\n * The `.graphqls` this package ships live in `graphql/` at its root, so that\n * they survive `bun pm pack` — the bundle in `dist/` carries no assets. Their\n * directory is not at a fixed depth from this file: it is `src/utils` in the\n * workspace and `dist` in the published bundle, which Bun flattens. Walking up\n * to the nearest `package.json` finds the package root in both.\n */\nfunction packageRoot() {\n\tlet dir = dirname(fileURLToPath(import.meta.url));\n\twhile (!existsSync(join(dir, 'package.json'))) {\n\t\tconst parent = dirname(dir);\n\t\tif (parent === dir)\n\t\t\tthrow new Error('@nxgt/shared-graphql: no package root');\n\t\tdir = parent;\n\t}\n\treturn dir;\n}\n\nexport const SHARED_SCHEMA_PATH = join(packageRoot(), 'graphql/**/*.graphqls');\n\nexport function loadTypeDefs(...paths: string[]) {\n\tconst typeDefs = mergeTypeDefs([\n\t\t...paths.flatMap((path) =>\n\t\t\tloadFilesSync(path, {\n\t\t\t\trecursive: true,\n\t\t\t}),\n\t\t),\n\t]);\n\n\treturn typeDefs;\n}\n\nexport function buildSubgraphSchema(\n\tmodulesOrSdl: Parameters<typeof buildSubgraphSchemaBase>[0],\n) {\n\treturn pruneSchema(buildSubgraphSchemaBase(modulesOrSdl), {\n\t\tskipUnusedTypesPruning: false,\n\t});\n}\n\n/**\n * Utility function to generate a GraphQL schema file from the provided type definitions.\n * @param output - The path where the generated schema file should be saved.\n * @param paths - An array of glob patterns to locate the GraphQL type definition files.\n */\nexport async function generateSchema(output: string, ...paths: string[]) {\n\tawait Bun.write(\n\t\toutput,\n\t\tprintSchema(buildSubgraphSchema(loadTypeDefs(...paths))),\n\t);\n}\n",
26
- "import { createServer } from 'node:http';\nimport type { ServerOptions } from 'graphql-ws';\nimport { useServer } from 'graphql-ws/use/ws';\nimport type { YogaServerInstance } from 'graphql-yoga';\nimport { WebSocketServer } from 'ws';\n\nexport function setupYogaWebSocketServer<\n\tServerContext extends {},\n\tUserContext extends {},\n>({\n\tyoga,\n\tcontext,\n}: {\n\tyoga: YogaServerInstance<ServerContext, UserContext>;\n\tcontext?: ServerOptions['context'];\n}) {\n\tconst httpServer = createServer(yoga);\n\tconst wsServer = new WebSocketServer({\n\t\tserver: httpServer,\n\t\tpath: yoga.graphqlEndpoint,\n\t});\n\n\t// biome-ignore lint/correctness/useHookAtTopLevel: Not react related\n\tuseServer(\n\t\t{\n\t\t\texecute: (args: any) => args.rootValue.execute(args),\n\t\t\tsubscribe: (args: any) => args.rootValue.subscribe(args),\n\t\t\tonSubscribe: async (ctx, _id, params) => {\n\t\t\t\tconst { schema, execute, subscribe, contextFactory, parse, validate } =\n\t\t\t\t\tyoga.getEnveloped({\n\t\t\t\t\t\t...ctx,\n\t\t\t\t\t\treq: ctx.extra.request,\n\t\t\t\t\t\tsocket: ctx.extra.socket,\n\t\t\t\t\t\tparams,\n\t\t\t\t\t});\n\n\t\t\t\tconst args = {\n\t\t\t\t\tschema,\n\t\t\t\t\toperationName: params.operationName,\n\t\t\t\t\tdocument: parse(params.query),\n\t\t\t\t\tvariableValues: params.variables,\n\t\t\t\t\tcontextValue: await contextFactory(),\n\t\t\t\t\trootValue: {\n\t\t\t\t\t\texecute,\n\t\t\t\t\t\tsubscribe,\n\t\t\t\t\t},\n\t\t\t\t};\n\n\t\t\t\tconst errors = validate(args.schema, args.document);\n\t\t\t\tif (errors.length) return errors;\n\t\t\t\treturn args;\n\t\t\t},\n\t\t\tcontext,\n\t\t},\n\t\twsServer,\n\t);\n\n\tconst startServer = (port: number) =>\n\t\tnew Promise<void>((resolve) => httpServer.listen({ port }, resolve));\n\treturn { yoga, httpServer, startServer };\n}\n",
27
- "import type { TokenPrincipal } from '@nxgt/shared';\nimport type { Context } from 'graphql-ws';\nimport type { createAuthClient } from 'stx-sdk/auth';\n\ntype AuthClient = ReturnType<typeof createAuthClient>;\n\nexport interface ResolvedWsUser {\n\tuser: TokenPrincipal | undefined;\n\ttoken: string | undefined;\n}\n\n/**\n * Resolves the authenticated TokenPrincipal for a `graphql-ws` connection - the\n * WS-transport equivalent of the HTTP-path `useAuth()`/`useGenericAuth()`\n * plugins. There is no gateway hop for WS connections, so each app performs\n * the OAuth introspection call itself using its own `auth` client.\n *\n * Reads the bearer token off `connectionParams.authorization` /\n * `connectionParams.Authorization` (both casings are used by existing\n * clients), strips the `Bearer ` prefix, and introspects it. Returns\n * `user: undefined` for a missing, invalid, or inactive token - callers\n * pass `user ?? null` into their own `services()` factory, exactly as the\n * HTTP-path plugins already do.\n */\nexport async function resolveWsUser(\n\tconnectionParams: Context['connectionParams'],\n\tauthClient: AuthClient,\n): Promise<ResolvedWsUser> {\n\tconst rawToken =\n\t\t(connectionParams?.authorization as string | undefined) ??\n\t\t(connectionParams?.Authorization as string | undefined);\n\tconst token = rawToken?.replace('Bearer ', '');\n\n\tconst { data } = token\n\t\t? await authClient.POST('/oauth/introspect', { body: { token } })\n\t\t: { data: null };\n\n\tconst user = data?.active\n\t\t? ({ ...(data as any), name: (data as any).sub } as TokenPrincipal)\n\t\t: undefined;\n\n\treturn { user, token };\n}\n",
28
- "import { getDirective, MapperKind, mapSchema } from '@graphql-tools/utils';\nimport { evaluateRequirement, type PermissionTerm } from '@nxgt/ory-sdk';\nimport { CustomException } from '@nxgt/shared-exceptions';\nimport {\n\tdefaultFieldResolver,\n\ttype GraphQLFieldConfig,\n\ttype GraphQLSchema,\n} from 'graphql';\nimport {\n\tCHECK_DIRECTIVE_NAME,\n\ttype CheckArgs,\n\tobjectIds,\n\ttype ReadOptions,\n\treadPath,\n\treadPermissions,\n\treadRequirements,\n} from '../directives';\nimport { warnCheckMistake } from '../directives/deprecation';\nimport type { KetoChecksContext } from './keto-checker';\nimport type { OryContext } from './ory-auth';\n\ntype FieldConfig = GraphQLFieldConfig<unknown, unknown>;\n\n/**\n * Wraps every field carrying `@check` or `@permission` so the permission is\n * answered before its resolver runs.\n *\n * Every requirement is read and validated here, when the schema is built: a\n * malformed path, an argument the field does not declare, an empty group, a\n * namespace outside `options.namespaces` — and a guard on an interface field,\n * which no resolver ever runs through — each throw a `TypeError` naming\n * `Type.field`, so the server does not boot.\n *\n * Modelled on `applyGraphqlPolicy` in `@nxgt/security`. Exported on its own\n * because a schema transform is far easier to test than a plugin.\n */\nexport function applyKetoChecks(\n\tschema: GraphQLSchema,\n\toptions: ReadOptions = {},\n): GraphQLSchema {\n\treturn mapSchema(schema, {\n\t\t[MapperKind.INTERFACE_FIELD]: (fieldConfig, fieldName, typeName) => {\n\t\t\trefuseOnInterface(schema, fieldConfig, `${typeName}.${fieldName}`);\n\t\t\treturn fieldConfig;\n\t\t},\n\t\t[MapperKind.OBJECT_FIELD]: (fieldConfig, fieldName, typeName) => {\n\t\t\tconst where = `${typeName}.${fieldName}`;\n\t\t\tconst requirements = readRequirements(\n\t\t\t\tschema,\n\t\t\t\tfieldConfig,\n\t\t\t\twhere,\n\t\t\t\toptions,\n\t\t\t);\n\t\t\tif (requirements.length === 0) return fieldConfig;\n\t\t\treturn guarded(fieldConfig, requirements, where);\n\t\t},\n\t});\n}\n\n/**\n * No resolver runs on an interface's field, so a guard there guards nothing.\n * `@permission` is refused; `@check`, which 2.x let boot, is warned about.\n */\nfunction refuseOnInterface(\n\tschema: GraphQLSchema,\n\tfieldConfig: FieldConfig,\n\twhere: string,\n) {\n\tconst message = `${where}: @check / @permission on an interface field guards nothing — no resolver runs there. Put it on each implementing type's field`;\n\tif (readPermissions(schema, fieldConfig, where).length > 0) {\n\t\tthrow new TypeError(message);\n\t}\n\t// Counted, not read: 2.x never looked at an interface's `@check`, so even\n\t// a malformed one booted, and must still.\n\tif (getDirective(schema, fieldConfig, CHECK_DIRECTIVE_NAME)?.length) {\n\t\twarnCheckMistake(message);\n\t}\n}\n\nfunction guarded(\n\tfieldConfig: FieldConfig,\n\trequirements: CheckArgs[],\n\twhere: string,\n): FieldConfig {\n\tconst resolve = fieldConfig.resolve ?? defaultFieldResolver;\n\n\treturn {\n\t\t...fieldConfig,\n\t\tresolve: async (source, args, context, info) => {\n\t\t\tconst ctx = context as KetoChecksContext & OryContext;\n\t\t\tconst subject = ctx.ory?.subject;\n\t\t\tif (!subject) {\n\t\t\t\tthrow CustomException.unauthenticated({\n\t\t\t\t\tmessage: 'errors.unauthenticated',\n\t\t\t\t});\n\t\t\t}\n\n\t\t\tconst check = ctx.ketoChecks;\n\t\t\tif (!check) {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t`${where}: no checker on the context — useKetoChecks(ory) is not registered`,\n\t\t\t\t);\n\t\t\t}\n\n\t\t\t// In declaration order, each with its own denial: `view` first\n\t\t\t// answers 404 for a stranger, `edit` next answers 403 for a viewer.\n\t\t\tfor (const { permissions, onDeny, message } of requirements) {\n\t\t\t\tconst allowed = await evaluateRequirement(\n\t\t\t\t\tpermissions,\n\t\t\t\t\t(term) => objectsOf(term, source, args, where),\n\t\t\t\t\tcheck,\n\t\t\t\t\tsubject,\n\t\t\t\t);\n\t\t\t\tif (!allowed) throw denial(onDeny, message);\n\t\t\t}\n\n\t\t\treturn resolve(source, args, context, info);\n\t\t},\n\t};\n}\n\n/**\n * A term that resolves no object is a wiring mistake — a nullable argument\n * nobody passed, a `parent` field that is not selected — and it must not read\n * as \"allowed\". `evaluateRequirement` throws on an empty list; this only makes\n * the message name the field.\n */\nfunction objectsOf(\n\tterm: PermissionTerm,\n\tsource: unknown,\n\targs: Record<string, unknown>,\n\twhere: string,\n): string[] {\n\tconst ids = objectIds(readPath(term.id, source, args));\n\tif (ids.length === 0) {\n\t\tthrow new Error(`${where}: \"${term.id}\" resolved no object id`);\n\t}\n\treturn ids;\n}\n\n/**\n * `message` is the field's own i18n key when it gave one. It exists so the\n * directive and the service layer can answer a refusal with the SAME words:\n * two different messages behind one 404 tell the caller which layer spoke, and\n * that is the difference NOT_FOUND is there to hide.\n */\nfunction denial(onDeny: CheckArgs['onDeny'], message?: string) {\n\treturn onDeny === 'FORBIDDEN'\n\t\t? CustomException.forbidden({\n\t\t\t\tmessage: message ?? 'errors.insufficient-permissions',\n\t\t\t})\n\t\t: CustomException.notFound({ message: message ?? 'errors.not-found' });\n}\n",
29
- "import type { Plugin } from 'graphql-yoga';\nimport type { GraphQLBaseContext } from '../types';\n\nexport function useAuth(): Plugin<GraphQLBaseContext> {\n\treturn {\n\t\tonContextBuilding: async ({ context, extendContext }) => {\n\t\t\textendContext({\n\t\t\t\tuser: context.params.extensions?.user,\n\t\t\t\ttoken: context.params.extensions?.token,\n\t\t\t});\n\t\t},\n\t};\n}\n",
30
- "import type { ApolloServerPlugin } from '@apollo/server';\nimport type { TokenPrincipal } from '@nxgt/shared';\nimport { logger } from '@nxgt/shared-logging';\n\nexport const extractJwtPlugin = {\n\tasync requestDidStart({ request, contextValue }) {\n\t\tlogger.info(\n\t\t\t`[${request.extensions?.subgraphName}] Extracting JWT from request extensions: ${request.extensions?.payload?.sub}`,\n\t\t\trequest.extensions,\n\t\t);\n\t\tcontextValue.jwt = {\n\t\t\tpayload: request.extensions?.payload,\n\t\t};\n\t},\n} satisfies ApolloServerPlugin<{\n\tjwt?: { payload: TokenPrincipal };\n}>;\n",
15
+ "import { MapperKind, mapSchema } from '@graphql-tools/utils';\nimport { ErrorCode } from '@nxgt/shared-exceptions';\nimport {\n\ttype GraphQLFieldConfig,\n\ttype GraphQLSchema,\n\tgetNamedType,\n\tisEnumType,\n\tisObjectType,\n\tisScalarType,\n} from 'graphql';\nimport {\n\ttype AuthenticatedOptions,\n\tCALLER_TYPES,\n\ttype CallerRequirement,\n\tcombineRequirements,\n\treadAuthenticated,\n} from '../directives/authenticated';\nimport type { PrincipalContext } from '../types';\nimport { denial } from '../utils/errors/denial';\nimport { guardField, isGuarded } from './field-guard';\nimport type { OryContext } from './ory-auth';\n\ntype FieldConfig = GraphQLFieldConfig<unknown, unknown>;\n\nconst MARK = '@nxgt/shared-graphql:authenticated';\n\n/**\n * Wraps every object field that an `@authenticated` applies to — on the field,\n * on its type, on one of its type's interfaces or on that interface's field,\n * or on the scalar or enum it returns — so the caller is checked before its\n * resolver (and a subscription's `subscribe`) runs: none is\n * `UNAUTHENTICATED` (401), one of a type no `type:` names is `FORBIDDEN`\n * (403). Every one that applies must hold.\n *\n * Read and validated when the schema is built: `type: []`, a type outside\n * `options.types` (`session`, `token` by default) and restrictions with no\n * type in common each throw a `TypeError` naming `Type.field`.\n *\n * The caller is `context.user`, which `useOryAuth` and `useAuth` set; its\n * type is `context.ory.kind`, or `context.user.tokenType` without Ory. A field\n * already guarded is left alone, and a schema with none left to guard is\n * returned as it is, so the plugin's `onSchemaChange` settles.\n */\nexport function applyAuthenticated(\n\tschema: GraphQLSchema,\n\toptions: AuthenticatedOptions = {},\n): GraphQLSchema {\n\tconst known = options.types ?? CALLER_TYPES;\n\tlet guardedNow = 0;\n\tconst mapped = mapSchema(schema, {\n\t\t[MapperKind.OBJECT_FIELD]: (fieldConfig, fieldName, typeName) => {\n\t\t\tconst where = `${typeName}.${fieldName}`;\n\t\t\tconst requirement = requirementOf(schema, fieldConfig, where, known);\n\t\t\tif (!requirement || isGuarded(fieldConfig, MARK)) return fieldConfig;\n\t\t\tguardedNow += 1;\n\t\t\treturn guarded(fieldConfig, requirement);\n\t\t},\n\t});\n\treturn guardedNow > 0 ? mapped : schema;\n}\n\n/** Every `@authenticated` that applies to `Type.field`, combined. */\nfunction requirementOf(\n\tschema: GraphQLSchema,\n\tfieldConfig: FieldConfig,\n\twhere: string,\n\tknown: readonly string[],\n): CallerRequirement | null {\n\tconst [typeName = '', fieldName = ''] = where.split('.');\n\tconst type = schema.getType(typeName);\n\tconst interfaces = isObjectType(type) ? type.getInterfaces() : [];\n\tconst read = (node: Parameters<typeof readAuthenticated>[1], at: string) =>\n\t\treadAuthenticated(schema, node, at, known);\n\treturn combineRequirements(\n\t\t[\n\t\t\tread(fieldConfig, where),\n\t\t\ttype ? read(type, typeName) : null,\n\t\t\t...interfaces.flatMap((iface) => {\n\t\t\t\tconst field = iface.getFields()[fieldName];\n\t\t\t\treturn [\n\t\t\t\t\tread(iface, iface.name),\n\t\t\t\t\tfield ? read(field, `${iface.name}.${fieldName}`) : null,\n\t\t\t\t];\n\t\t\t}),\n\t\t\tleafRequirement(schema, fieldConfig, read),\n\t\t],\n\t\twhere,\n\t);\n}\n\n/**\n * A scalar or an enum has no resolver of its own, so its `@authenticated`\n * guards every field that returns it — the reading federation's router gives\n * the same declaration.\n */\nfunction leafRequirement(\n\tschema: GraphQLSchema,\n\tfieldConfig: FieldConfig,\n\tread: (\n\t\tnode: Parameters<typeof readAuthenticated>[1],\n\t\tat: string,\n\t) => CallerRequirement | null,\n): CallerRequirement | null {\n\tconst leaf = schema.getType(getNamedType(fieldConfig.type).name);\n\tif (!leaf || !(isScalarType(leaf) || isEnumType(leaf))) return null;\n\treturn read(leaf, leaf.name);\n}\n\nfunction guarded(\n\tfieldConfig: FieldConfig,\n\t{ types }: CallerRequirement,\n): FieldConfig {\n\treturn guardField(fieldConfig, {\n\t\tmark: MARK,\n\t\trank: 0,\n\t\tonSubscribe: true,\n\t\tcheck: (_source, _args, context) => {\n\t\t\tconst ctx = (context ?? {}) as PrincipalContext & OryContext;\n\t\t\tif (!ctx.user) throw denial(ErrorCode.Unauthenticated);\n\t\t\tif (types && !types.includes(callerTypeOf(ctx) ?? '')) {\n\t\t\t\tthrow denial(ErrorCode.Forbidden);\n\t\t\t}\n\t\t},\n\t});\n}\n\nfunction callerTypeOf(ctx: PrincipalContext & OryContext): string | undefined {\n\treturn ctx.ory?.kind ?? ctx.user?.tokenType;\n}\n",
16
+ "import { type LocaleKey, translate } from '@nxgt/i18n';\nimport { ErrorCode } from '@nxgt/shared-exceptions';\nimport { GraphQLError } from 'graphql';\n\n/** The refusals a guard answers, each with its HTTP status. */\nexport type DenialCode =\n\t| ErrorCode.Unauthenticated\n\t| ErrorCode.Forbidden\n\t| ErrorCode.NotFound;\n\nconst STATUS: Record<DenialCode, number> = {\n\t[ErrorCode.Unauthenticated]: 401,\n\t[ErrorCode.Forbidden]: 403,\n\t[ErrorCode.NotFound]: 404,\n};\n\n/** The shared i18n keys a denial carries when it names none. */\nconst DEFAULT_MESSAGE: Record<DenialCode, string> = {\n\t[ErrorCode.Unauthenticated]: 'errors.unauthenticated',\n\t[ErrorCode.Forbidden]: 'errors.insufficient-permissions',\n\t[ErrorCode.NotFound]: 'errors.not-found',\n};\n\n/**\n * Where a denial keeps its i18n key. A registered symbol, so a denial from a\n * second copy of this package is still recognised, and never serialised: the\n * client reads `message`, not the key.\n */\nconst MESSAGE_KEY = Symbol.for('@nxgt/shared-graphql/denial-message');\n\n/**\n * A refusal, as the `GraphQLError` a client reads: `extensions.code` and\n * `extensions.http.status` — `UNAUTHENTICATED` 401, `FORBIDDEN` 403,\n * `NOT_FOUND` 404 — so any server answers it with its status, with or without\n * `createMaskError`. What `@permission`, `@authenticated`, `requireUser` and\n * `can` throw.\n *\n * `message` is an i18n key (the shared `errors.*` one by default). It is\n * translated here with `@nxgt/i18n`'s resources, in the request's language\n * when one is known; `createMaskError(translate)` and\n * `createFormatError(translate)` translate it again with yours.\n */\nexport function denial(code: DenialCode, message?: string): GraphQLError {\n\tconst key = message ?? DEFAULT_MESSAGE[code];\n\tconst error = new GraphQLError(translate(key as LocaleKey), {\n\t\textensions: { code, http: { status: STATUS[code] } },\n\t});\n\tObject.defineProperty(error, MESSAGE_KEY, { value: key });\n\treturn error;\n}\n\n/** The i18n key of a `denial()`, or `undefined` for any other error. */\nexport function denialMessageKey(error: unknown): string | undefined {\n\tif (!error || typeof error !== 'object') return undefined;\n\tconst key = (error as { [MESSAGE_KEY]?: unknown })[MESSAGE_KEY];\n\treturn typeof key === 'string' ? key : undefined;\n}\n",
17
+ "import {\n\tdefaultFieldResolver,\n\ttype GraphQLFieldConfig,\n\ttype GraphQLFieldResolver,\n} from 'graphql';\n\ntype FieldConfig = GraphQLFieldConfig<unknown, unknown>;\ntype Resolver = GraphQLFieldResolver<unknown, unknown>;\n\n/** What a guard asks before a field runs; it throws to refuse. */\nexport type FieldCheck = (\n\tsource: unknown,\n\targs: Record<string, unknown>,\n\tcontext: unknown,\n) => void | Promise<void>;\n\n/**\n * One transform's guard on one field: its mark, its rank (lower runs first),\n * its check, and whether the check can run before a subscription's stream is\n * opened — only when it reads nothing off an event (`parent.<path>`).\n */\nexport type FieldGuard = {\n\tmark: string;\n\trank: number;\n\tcheck: FieldCheck;\n\tonSubscribe: boolean;\n};\n\n/**\n * The guards on a field, kept on its own `extensions` — which `mapSchema` and\n * `mergeSchemas` carry over with the field — with the resolvers they wrap\n * and the wrappers built from them.\n */\ntype Guarded = {\n\tguards: FieldGuard[];\n\tresolve: Resolver;\n\tsubscribe?: Resolver;\n\twrapped: { resolve: Resolver; subscribe?: Resolver };\n};\n\nconst GUARDS = '@nxgt/shared-graphql:guards';\n\n/**\n * The field's guards while its resolvers are still the wrappers they built.\n * A resolver replaced since — `addResolversToSchema`, a merge with\n * resolvers — keeps the field's `extensions` but not its guards, so the\n * record no longer counts.\n */\nfunction intactGuards(config: FieldConfig): Guarded | undefined {\n\tconst record = config.extensions?.[GUARDS] as Guarded | undefined;\n\tif (!record || record.wrapped.resolve !== config.resolve) return undefined;\n\tif (record.wrapped.subscribe !== config.subscribe) return undefined;\n\treturn record;\n}\n\n/**\n * Whether the transform owning `mark` guards this field as it stands. A\n * merged schema's unguarded half, or a field whose resolver was replaced,\n * is not — so a transform run again wraps it, never one twice.\n */\nexport function isGuarded(config: FieldConfig, mark: string): boolean {\n\treturn !!intactGuards(config)?.guards.some((guard) => guard.mark === mark);\n}\n\n/**\n * The field with `guard` added. Every guard runs by rank — `@authenticated`\n * before `@permission`, whichever transform ran first — before the resolver;\n * those with `onSubscribe` also run before `subscribe`, so a refused\n * subscription opens no stream.\n */\nexport function guardField(\n\tconfig: FieldConfig,\n\tguard: FieldGuard,\n): FieldConfig {\n\tconst previous = intactGuards(config);\n\tconst base = previous\n\t\t? { resolve: previous.resolve, subscribe: previous.subscribe }\n\t\t: {\n\t\t\t\tresolve: config.resolve ?? defaultFieldResolver,\n\t\t\t\tsubscribe: config.subscribe,\n\t\t\t};\n\tconst guards = [...(previous?.guards ?? []), guard].sort(\n\t\t(a, b) => a.rank - b.rank,\n\t);\n\tconst wrapped = {\n\t\tresolve: checked(guards, base.resolve),\n\t\tsubscribe:\n\t\t\tbase.subscribe &&\n\t\t\tchecked(\n\t\t\t\tguards.filter((one) => one.onSubscribe),\n\t\t\t\tbase.subscribe,\n\t\t\t),\n\t};\n\treturn {\n\t\t...config,\n\t\textensions: {\n\t\t\t...config.extensions,\n\t\t\t[GUARDS]: { guards, ...base, wrapped } satisfies Guarded,\n\t\t},\n\t\tresolve: wrapped.resolve,\n\t\tsubscribe: wrapped.subscribe,\n\t};\n}\n\nfunction checked(guards: FieldGuard[], next: Resolver): Resolver {\n\treturn async (source, args, context, info) => {\n\t\tfor (const { check } of guards) await check(source, args, context);\n\t\treturn next(source, args, context, info);\n\t};\n}\n",
18
+ "import { MapperKind, mapSchema } from '@graphql-tools/utils';\nimport { evaluateRequirement, type PermissionTerm } from '@nxgt/ory-sdk';\nimport { ErrorCode } from '@nxgt/shared-exceptions';\nimport type { GraphQLFieldConfig, GraphQLSchema } from 'graphql';\nimport {\n\ttype FieldPermission,\n\tobjectIds,\n\ttype ReadOptions,\n\treadPath,\n\treadPermissions,\n} from '../directives';\nimport { refuseRemovedCheck } from '../directives/removed-check';\nimport { denial } from '../utils/errors/denial';\nimport { guardField, isGuarded } from './field-guard';\nimport type { KetoChecksContext } from './keto-checker';\nimport type { OryContext } from './ory-auth';\n\ntype FieldConfig = GraphQLFieldConfig<unknown, unknown>;\n\nconst MARK = '@nxgt/shared-graphql:keto-checks';\n\n/**\n * Wraps every field carrying `@permission` so the permission is answered\n * before its resolver runs.\n *\n * Every requirement is read and validated here, when the schema is built: a\n * malformed path, an argument the field does not declare, an empty group, a\n * namespace outside `options.namespaces`, a guard on an interface field,\n * which no resolver ever runs through, and a `@check` — removed in 3.0 — each\n * throw a `TypeError` naming `Type.field`, so the server does not boot.\n *\n * Modelled on `applyGraphqlPolicy` in `@nxgt/security`. Exported on its own\n * because a schema transform is far easier to test than a plugin. A field it\n * already guarded is left as it is, and a schema with no field left to guard\n * is returned as it is — so it never wraps a field twice, and the plugin's\n * `onSchemaChange` settles.\n */\nexport function applyKetoChecks(\n\tschema: GraphQLSchema,\n\toptions: ReadOptions = {},\n): GraphQLSchema {\n\tlet guardedNow = 0;\n\tconst mapped = mapSchema(schema, {\n\t\t[MapperKind.INTERFACE_FIELD]: (fieldConfig, fieldName, typeName) => {\n\t\t\trefuseOnInterface(schema, fieldConfig, `${typeName}.${fieldName}`);\n\t\t\treturn fieldConfig;\n\t\t},\n\t\t[MapperKind.OBJECT_FIELD]: (fieldConfig, fieldName, typeName) => {\n\t\t\tconst where = `${typeName}.${fieldName}`;\n\t\t\trefuseRemovedCheck(schema, fieldConfig, where);\n\t\t\tconst requirements = readPermissions(schema, fieldConfig, where, options);\n\t\t\tif (requirements.length === 0 || isGuarded(fieldConfig, MARK)) {\n\t\t\t\treturn fieldConfig;\n\t\t\t}\n\t\t\tguardedNow += 1;\n\t\t\treturn guarded(fieldConfig, requirements, where);\n\t\t},\n\t});\n\treturn guardedNow > 0 ? mapped : schema;\n}\n\n/** No resolver runs on an interface's field, so a guard there guards nothing. */\nfunction refuseOnInterface(\n\tschema: GraphQLSchema,\n\tfieldConfig: FieldConfig,\n\twhere: string,\n) {\n\trefuseRemovedCheck(schema, fieldConfig, where);\n\tif (readPermissions(schema, fieldConfig, where).length > 0) {\n\t\tthrow new TypeError(\n\t\t\t`${where}: @permission on an interface field guards nothing — no resolver runs there. Put it on each implementing type's field`,\n\t\t);\n\t}\n}\n\nfunction guarded(\n\tfieldConfig: FieldConfig,\n\trequirements: FieldPermission[],\n\twhere: string,\n): FieldConfig {\n\treturn guardField(fieldConfig, {\n\t\tmark: MARK,\n\t\trank: 1,\n\t\t// Before the stream opens only when no term reads the event.\n\t\tonSubscribe: requirements.every(({ permissions }) =>\n\t\t\tpermissions.every((group) =>\n\t\t\t\tgroup.every((term) => term.id.startsWith('args.')),\n\t\t\t),\n\t\t),\n\t\tcheck: async (source, args, context) => {\n\t\t\tconst ctx = context as KetoChecksContext & OryContext;\n\t\t\tconst subject = ctx.ory?.subject;\n\t\t\tif (!subject) throw denial(ErrorCode.Unauthenticated);\n\n\t\t\tconst check = ctx.ketoChecks;\n\t\t\tif (!check) {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t`${where}: no checker on the context — useKetoChecks(ory) is not registered`,\n\t\t\t\t);\n\t\t\t}\n\n\t\t\t// In declaration order, each with its own denial: `view` first\n\t\t\t// answers 404 for a stranger, `edit` next answers 403 for a viewer.\n\t\t\tfor (const { permissions, onDeny, message } of requirements) {\n\t\t\t\tconst allowed = await evaluateRequirement(\n\t\t\t\t\tpermissions,\n\t\t\t\t\t(term) => objectsOf(term, source, args, where),\n\t\t\t\t\tcheck,\n\t\t\t\t\tsubject,\n\t\t\t\t);\n\t\t\t\tif (!allowed) throw refusal(onDeny, message);\n\t\t\t}\n\t\t},\n\t});\n}\n\n/**\n * A term that resolves no object is a wiring mistake — a nullable argument\n * nobody passed, a `parent` field that is not selected — and it must not read\n * as \"allowed\". `evaluateRequirement` throws on an empty list; this only makes\n * the message name the field.\n */\nfunction objectsOf(\n\tterm: PermissionTerm,\n\tsource: unknown,\n\targs: Record<string, unknown>,\n\twhere: string,\n): string[] {\n\tconst ids = objectIds(readPath(term.id, source, args));\n\tif (ids.length === 0) {\n\t\tthrow new Error(`${where}: \"${term.id}\" resolved no object id`);\n\t}\n\treturn ids;\n}\n\n/**\n * `message` is the field's own i18n key when it gave one. It exists so the\n * directive and the service layer can answer a refusal with the SAME words:\n * two different messages behind one 404 tell the caller which layer spoke, and\n * that is the difference NOT_FOUND is there to hide.\n */\nfunction refusal(onDeny: FieldPermission['onDeny'], message?: string) {\n\treturn denial(\n\t\tonDeny === 'FORBIDDEN' ? ErrorCode.Forbidden : ErrorCode.NotFound,\n\t\tmessage,\n\t);\n}\n",
19
+ "import { getDirective } from '@graphql-tools/utils';\nimport type { GraphQLSchema } from 'graphql';\nimport type { FieldNode } from './scope';\n\n/**\n * `@check`, the list-of-lists form, was removed in 3.0. This package no longer\n * ships its declaration, so a schema that still writes one either fails to\n * build (`Unknown directive \"@check\"`) or declares it itself — and then the\n * transform, which no longer reads it, would leave the field open in silence.\n *\n * So a field carrying a `@check` whose declaration has `permissions` — the\n * shape 2.x shipped — is refused when the schema is built, naming the field\n * and the rewrite. A `@check` of another shape is the schema's own and is left\n * alone, as a foreign `@permission` is.\n */\nexport function refuseRemovedCheck(\n\tschema: GraphQLSchema,\n\tnode: FieldNode,\n\twhere: string,\n) {\n\tconst declared = schema.getDirective('check');\n\tif (!declared?.args.some((arg) => arg.name === 'permissions')) return;\n\tif (!getDirective(schema, node, 'check')?.length) return;\n\tthrow new TypeError(\n\t\t`@check on ${where}: @check was removed in @nxgt/shared-graphql 3.0 — write one @permission(name: \"<permit>\", type: \"<namespace>\") per term, and move an OR into the Keto model`,\n\t);\n}\n",
20
+ "import {\n\ttype GatewayTrust,\n\ttype GatewayTrustOptions,\n\trequireGatewayTrust as requireTrust,\n} from '@nxgt/security/gateway';\nimport type { TokenPrincipal } from '@nxgt/shared';\n\n// One definition, in `@nxgt/security`, shared with `@nxgt/shared-hono`'s\n// `currentUser()` — so a gateway's secret means the same thing to both.\nexport {\n\tGATEWAY_SECRET_HEADER,\n\ttype GatewaySecretOptions,\n\ttype GatewayTrust,\n\ttype GatewayTrustOptions,\n\tgatewaySecret,\n\ttype HeaderReader,\n} from '@nxgt/security/gateway';\n\n/**\n * The `trustedGateway` a plugin was given, or a `TypeError` naming the plugin:\n * without one there is no caller it could read, and a plugin that silently\n * reads none is a server whose every caller is anonymous.\n */\nexport function requireGatewayTrust(\n\toptions: Partial<GatewayTrustOptions> | undefined,\n\tplugin: string,\n): GatewayTrust {\n\treturn requireTrust(options, {\n\t\tcaller: plugin,\n\t\treads: \"the request's extensions\",\n\t\talternative: 'useOryAuth(ory)',\n\t});\n}\n\n/**\n * The caller a trusted gateway put in `extensions`, when it is shaped like\n * one: an object with a non-empty string `sub`. Anything else names nobody.\n */\nexport function principalOf(value: unknown): TokenPrincipal | undefined {\n\tif (!value || typeof value !== 'object') return undefined;\n\tconst sub = (value as { sub?: unknown }).sub;\n\treturn typeof sub === 'string' && sub.length > 0\n\t\t? (value as TokenPrincipal)\n\t\t: undefined;\n}\n",
21
+ "import type { Plugin } from 'graphql-yoga';\nimport type { GraphQLBaseContext } from '../types';\nimport {\n\ttype GatewayTrustOptions,\n\tprincipalOf,\n\trequireGatewayTrust,\n} from './gateway-trust';\n\nexport type UseAuthOptions = GatewayTrustOptions;\n\n/**\n * The caller a gateway resolved, read from the GraphQL request's `extensions`\n * — `user` and `token` — and ONLY for a request `trustedGateway` vouches for.\n *\n * `extensions` sits in the request body, which any client writes. A request\n * without the gateway's proof leaves the context as it was: no `user`, no\n * `token`, whatever its `extensions` claim. Without a `trustedGateway` this\n * throws when it is called, so a server cannot boot trusting the body.\n *\n * useAuth({ trustedGateway: gatewaySecret({ secret: env.GATEWAY_SECRET }) })\n *\n * An API that resolves its own callers — a Kratos session, a Hydra token —\n * uses `useOryAuth(ory)` instead.\n */\nexport function useAuth(options: UseAuthOptions): Plugin<GraphQLBaseContext> {\n\tconst trusted = requireGatewayTrust(options, 'useAuth()');\n\treturn {\n\t\tonContextBuilding: async ({ context, extendContext }) => {\n\t\t\t// Only a fetch Request can carry the proof. A WebSocket context holds\n\t\t\t// none, or a Node upgrade request whose headers are a plain record:\n\t\t\t// neither names a caller here — `resolveWsUser` does, per connection.\n\t\t\tconst headers = context.request?.headers;\n\t\t\tif (typeof headers?.get !== 'function') return;\n\t\t\tif (!(await trusted(headers))) return;\n\t\t\tconst user = principalOf(context.params?.extensions?.user);\n\t\t\tif (!user) return;\n\t\t\tconst token = context.params.extensions?.token;\n\t\t\textendContext({\n\t\t\t\tuser,\n\t\t\t\ttoken: typeof token === 'string' ? token : undefined,\n\t\t\t});\n\t\t},\n\t};\n}\n",
22
+ "import type { Plugin } from 'graphql-yoga';\nimport type { AuthenticatedOptions } from '../directives/authenticated';\nimport type { GraphQLBaseContext } from '../types';\nimport { applyAuthenticated } from './apply-authenticated';\nimport type { OryContext } from './ory-auth';\n\n/**\n * Enforces `@authenticated` and `@authenticated(type:)` on every schema the\n * server uses. Goes after the plugin that sets the caller — `useOryAuth(ory)`\n * or `useAuth({ trustedGateway })`.\n *\n * `applyAuthenticated` returns a schema with no field left to guard as it is,\n * so the replacement settles alongside `useKetoChecks` whatever their order.\n */\nexport function useAuthenticated(\n\toptions: AuthenticatedOptions = {},\n): Plugin<GraphQLBaseContext & OryContext> {\n\treturn {\n\t\tonSchemaChange: ({ schema, replaceSchema }) => {\n\t\t\tconst next = applyAuthenticated(schema, options);\n\t\t\tif (next !== schema) replaceSchema(next);\n\t\t},\n\t};\n}\n",
23
+ "import type { ApolloServerPlugin } from '@apollo/server';\nimport type { TokenPrincipal } from '@nxgt/shared';\nimport {\n\ttype GatewayTrustOptions,\n\tprincipalOf,\n\trequireGatewayTrust,\n} from './gateway-trust';\n\nexport type ExtractJwtOptions = GatewayTrustOptions;\n\n/** What `extractJwtPlugin()` sets on an Apollo context. */\nexport type JwtContext = {\n\tjwt?: { payload: TokenPrincipal };\n};\n\n/**\n * Apollo Server's counterpart of `useAuth()`: the JWT payload a gateway\n * verified and forwarded in `request.extensions.payload`, copied onto\n * `context.jwt` — ONLY for a request `trustedGateway` vouches for.\n *\n * A request without the gateway's proof leaves `context.jwt` as the context\n * function built it, whatever its `extensions` claim.\n *\n * plugins: [extractJwtPlugin({ trustedGateway: gatewaySecret({ secret }) })]\n */\nexport function extractJwtPlugin(\n\toptions: ExtractJwtOptions,\n): ApolloServerPlugin<JwtContext> {\n\tconst trusted = requireGatewayTrust(options, 'extractJwtPlugin()');\n\treturn {\n\t\tasync requestDidStart({ request, contextValue }) {\n\t\t\tconst headers = request.http?.headers;\n\t\t\tif (!headers || !(await trusted(headers))) return;\n\t\t\tconst payload = principalOf(request.extensions?.payload);\n\t\t\tif (payload) contextValue.jwt = { payload };\n\t\t},\n\t};\n}\n",
31
24
  "import { type Ory, type Permission, type Subject, tuple } from '@nxgt/ory-sdk';\nimport DataLoader from 'dataloader';\n\n/**\n * The per-request answer cache, and the reason `@check` / `@permission` cost\n * nothing on top of the access layer that already asks Keto.\n *\n * `DataLoader` here does two things: it **batches** distinct questions into\n * one `POST /relation-tuples/batch/check`, and it **memoises** identical ones\n * for the life of the request. So a field guarded by `@permission(view)` and a\n * service that then calls `require<M>Access` — which asks the same question —\n * pay for one round trip between them.\n *\n * A failed batch is not memoised: `DataLoader` clears the keys of a batch that\n * rejected, so an outage answers `OryUnavailable` to every question it touched\n * and the next ask goes back to Keto.\n *\n * The key is Keto's own notation, `Note:n1#view@idn-7`, so a cache hit is\n * legible in a log line.\n */\nexport type KetoChecker = (\n\tpermission: Permission,\n\tsubject: Subject,\n) => Promise<boolean>;\n\nexport type KetoChecksContext = {\n\tketoChecks?: KetoChecker;\n};\n\nexport function createKetoChecks(ory: Ory): KetoChecker {\n\tconst loader = new DataLoader<\n\t\t{ permission: Permission; subject: Subject },\n\t\tboolean,\n\t\tstring\n\t>((questions) => ory.checkMany([...questions]), {\n\t\tcacheKeyFn: ({ permission, subject }) => tuple(permission, subject),\n\t});\n\n\treturn (permission, subject) => loader.load({ permission, subject });\n}\n",
32
- "import type { Ory } from '@nxgt/ory-sdk';\nimport type { GraphQLSchema } from 'graphql';\nimport type { Plugin } from 'graphql-yoga';\nimport type { ReadOptions } from '../directives';\nimport type { GraphQLBaseContext } from '../types';\nimport { applyKetoChecks } from './apply-keto-checks';\nimport { createKetoChecks, type KetoChecksContext } from './keto-checker';\nimport type { OryContext } from './ory-auth';\n\n/** What `useKetoChecks` and `applyKetoChecks` take besides the `Ory` client. */\nexport type KetoChecksOptions = ReadOptions;\n\n/**\n * Registers the whole thing: the schema transform, and the per-request checker\n * the transform — and the app's own access layer, through `can` — read off the\n * context.\n *\n * Goes after `useOryAuth(ory)`, which is what puts `ory.subject` there.\n *\n * `replaceSchema` inside `onSchemaChange` re-enters this hook with the new\n * schema, so transformed schemas are remembered and passed through. Without\n * the guard this loops until the stack gives out.\n *\n * `OryUnavailable` is deliberately not caught anywhere here: a Keto outage is\n * a 503 through `createMaskError`, never a denial.\n */\nexport function useKetoChecks(\n\tory: Ory,\n\toptions: KetoChecksOptions = {},\n): Plugin<GraphQLBaseContext & OryContext & KetoChecksContext> {\n\tconst transformed = new WeakSet<GraphQLSchema>();\n\n\treturn {\n\t\tonSchemaChange: ({ schema, replaceSchema }) => {\n\t\t\tif (transformed.has(schema)) return;\n\t\t\tconst next = applyKetoChecks(schema, options);\n\t\t\ttransformed.add(next);\n\t\t\treplaceSchema(next);\n\t\t},\n\t\tonContextBuilding: ({ extendContext }) => {\n\t\t\textendContext({ ketoChecks: createKetoChecks(ory) });\n\t\t},\n\t};\n}\n",
33
- "import type { Permission } from '@nxgt/ory-sdk';\nimport type { TokenPrincipal } from '@nxgt/shared';\nimport { CustomException } from '@nxgt/shared-exceptions';\nimport type { GraphQLBaseContext } from '../types';\nimport type { KetoChecksContext } from './keto-checker';\nimport type { OryContext } from './ory-auth';\n\n/**\n * The context `useOryAuth(ory)` and `useKetoChecks(ory)` build together —\n * what a resolver of an Ory-native API receives.\n *\n * createYoga<{}, OryGraphQLContext>({ plugins: [useOryAuth(ory), useKetoChecks(ory)] })\n */\nexport type OryGraphQLContext = GraphQLBaseContext &\n\tOryContext &\n\tKetoChecksContext;\n\n/** The question `can` asks, in `@permission`'s words. */\nexport type CanQuestion = {\n\t/** The permit, e.g. `view`. */\n\tname: string;\n\t/** The Keto namespace, e.g. `Note`. */\n\ttype: string;\n\t/** The object id itself — a value, not a path. */\n\tid: string;\n};\n\n/**\n * The caller, or an `UNAUTHENTICATED` refusal (401 through `createMaskError`).\n * An absent caller is not an error to swallow in a resolver that needs one.\n */\nexport function requireUser(context: {\n\tuser?: TokenPrincipal | null;\n}): TokenPrincipal {\n\tif (!context.user) {\n\t\tthrow CustomException.unauthenticated({\n\t\t\tmessage: 'errors.unauthenticated',\n\t\t});\n\t}\n\treturn context.user;\n}\n\n/**\n * Asks Keto what `@permission` would, from a resolver — through the same\n * per-request memo, so a question the directive already asked is free.\n *\n * `true` or `false` is Keto's answer. Everything else throws: no caller is\n * `UNAUTHENTICATED`, a missing `useKetoChecks` is a wiring error, and an\n * outage is `OryUnavailable` (a 503) — never a `false` a caller could take\n * for a denial.\n */\nexport async function can(\n\tcontext: OryContext & KetoChecksContext,\n\tquestion: CanQuestion,\n): Promise<boolean> {\n\tconst subject = context.ory?.subject;\n\tif (!subject) {\n\t\tthrow CustomException.unauthenticated({\n\t\t\tmessage: 'errors.unauthenticated',\n\t\t});\n\t}\n\tif (!context.ketoChecks) {\n\t\tthrow new Error(\n\t\t\t'can(): no checker on the context — useKetoChecks(ory) is not registered',\n\t\t);\n\t}\n\tconst permission: Permission = {\n\t\tnamespace: question.type,\n\t\tobject: question.id,\n\t\trelation: question.name,\n\t};\n\treturn context.ketoChecks(permission, subject);\n}\n",
34
- "import {\n\tbearerOf,\n\ttype Ory,\n\ttype OryPrincipal,\n\ttype OryUnavailable,\n} from '@nxgt/ory-sdk';\nimport { claimsFromOryPrincipal } from '@nxgt/security/integrations/ory';\nimport type { PolicyClaims } from '@nxgt/security/policy';\nimport type { TokenPrincipal } from '@nxgt/shared';\nimport type { GraphQLError } from 'graphql';\nimport type { Plugin } from 'graphql-yoga';\nimport type { GraphQLBaseContext } from '../types';\nimport {\n\tisOryUnavailable,\n\tserviceUnavailableError,\n} from '../utils/errors/ory-unavailable';\n\n/**\n * What `useOryAuth()` adds to the context, next to `user` and `token`: the\n * Ory principal itself, or `null` when the request carried no honoured\n * credential. `user.sub === ory.subject` by construction; read `ory` when the\n * value is going to Keto, so the code says what it is.\n */\nexport type OryContext = {\n\tory?: OryPrincipal | null;\n\t/**\n\t * The caller in the vocabulary a rules document reads — what\n\t * `applyGraphqlPolicy`'s `getClaims` should return.\n\t *\n\t * It is NOT `user`. `TokenPrincipal` is the repo-wide principal shape and\n\t * carries what a service wants (`uid`, `name`, empty `authorities`); a\n\t * rule wants the OIDC claims, `email_verified`, `aal` and `aud` included,\n\t * and those have nowhere to live in a `TokenPrincipal`. Reading `user` as\n\t * claims is why `expression: \"claims.aal === 'aal2'\"` guarded a REST route\n\t * and silently guarded nothing here.\n\t *\n\t * Produced by the same `claimsFromOryPrincipal` the REST middleware uses,\n\t * so one rule reads the same on both transports.\n\t */\n\tclaims?: PolicyClaims;\n};\n\n/**\n * The repo-wide TokenPrincipal an Ory principal becomes.\n *\n * `sub` and `uid` are both the Ory subject — a Kratos identity id for a\n * session or a person's token, the client id for a `client_credentials`\n * token — so every service that reads `this.principal?.sub` (or `.uid`) keeps\n * working unchanged. `authorities` is EMPTY on purpose: Keto answers per\n * object, and an empty list is what keeps `@policy` / `useGenericAuth`'s\n * policy extraction from granting anything by accident.\n */\nexport function toPrincipal(ory: OryPrincipal): TokenPrincipal {\n\tconst email = ory.identity?.email;\n\treturn {\n\t\tsub: ory.subject,\n\t\tuid: ory.subject,\n\t\tname: email ?? ory.clientId ?? ory.subject,\n\t\tusername: email,\n\t\tclientId: ory.clientId,\n\t\tscope: ory.scopes.join(' ') || undefined,\n\t\ttokenType: ory.kind,\n\t\texp: ory.expiresAt ? Math.floor(ory.expiresAt.getTime() / 1000) : undefined,\n\t\tauthorities: [],\n\t\troles: [],\n\t};\n}\n\n/**\n * A 503 the client can read as one — a real `GraphQLError` so Yoga's masking\n * leaves it alone, `extensions.http.status` so the transport says 503 too.\n * Never a denial: `@nxgt/ory-sdk` throws `OryUnavailable` only when Kratos,\n * Hydra or Keto could not answer, and that must not read as \"not signed in\".\n */\nexport function oryUnavailableError(error: OryUnavailable): GraphQLError {\n\treturn serviceUnavailableError(error);\n}\n\n/**\n * The one introspection code path — `Bearer` first, then `X-Session-Token`,\n * then the Kratos cookie; the first credential present decides. Exported so\n * a REST route mounted beside the GraphQL endpoint (content-hub-api's\n * webhook shape) authenticates through the same function instead of a\n * second call.\n */\nexport async function resolveOryPrincipal(\n\tory: Ory,\n\theaders: Headers,\n): Promise<OryContext & { user?: TokenPrincipal; token?: string }> {\n\tlet principal: OryPrincipal | null;\n\ttry {\n\t\tprincipal = await ory.resolve(headers);\n\t} catch (error) {\n\t\tif (isOryUnavailable(error)) throw oryUnavailableError(error);\n\t\tthrow error;\n\t}\n\n\treturn {\n\t\tory: principal,\n\t\tuser: principal ? toPrincipal(principal) : undefined,\n\t\tclaims: principal ? claimsFromOryPrincipal(principal) : undefined,\n\t\ttoken: bearerOf(headers) ?? undefined,\n\t};\n}\n\n/**\n * `useAuth()` for an Ory-native API: resolves the caller through Kratos\n * (session cookie, session token) or Hydra (Bearer, introspected) and puts\n * `user`, `claims`, `token` and `ory` on the context. Wire it exactly where the\n * standalone APIs wire `useAuth()`, ahead of `useGenericAuth` — which then\n * enforces `@authenticated` from `context.user` unchanged.\n *\n * The `Ory` instance comes from the app's `createOry()` — one per process —\n * and is the same one the services use for `isAllowed`.\n */\nexport function useOryAuth(ory: Ory): Plugin<GraphQLBaseContext & OryContext> {\n\treturn {\n\t\tonContextBuilding: async ({ context, extendContext }) => {\n\t\t\textendContext(await resolveOryPrincipal(ory, context.request.headers));\n\t\t},\n\t};\n}\n",
25
+ "import type { Ory } from '@nxgt/ory-sdk';\nimport type { Plugin } from 'graphql-yoga';\nimport type { ReadOptions } from '../directives';\nimport type { GraphQLBaseContext } from '../types';\nimport { applyKetoChecks } from './apply-keto-checks';\nimport { createKetoChecks, type KetoChecksContext } from './keto-checker';\nimport type { OryContext } from './ory-auth';\n\n/** What `useKetoChecks` and `applyKetoChecks` take besides the `Ory` client. */\nexport type KetoChecksOptions = ReadOptions;\n\n/**\n * Registers the whole thing: the schema transform, and the per-request checker\n * the transform — and the app's own access layer, through `can` — read off the\n * context.\n *\n * Goes after `useOryAuth(ory)`, which is what puts `ory.subject` there.\n *\n * `replaceSchema` inside `onSchemaChange` re-enters this hook with the new\n * schema, and with every schema another plugin makes of it. `applyKetoChecks`\n * returns a schema with no field left to guard as it is, so the replacement settles\n * instead of looping, alongside `useAuthenticated` whatever their order.\n *\n * `OryUnavailable` is deliberately not caught anywhere here: a Keto outage is\n * a 503 through `createMaskError`, never a denial.\n */\nexport function useKetoChecks(\n\tory: Ory,\n\toptions: KetoChecksOptions = {},\n): Plugin<GraphQLBaseContext & OryContext & KetoChecksContext> {\n\treturn {\n\t\tonSchemaChange: ({ schema, replaceSchema }) => {\n\t\t\tconst next = applyKetoChecks(schema, options);\n\t\t\tif (next !== schema) replaceSchema(next);\n\t\t},\n\t\tonContextBuilding: ({ extendContext }) => {\n\t\t\textendContext({ ketoChecks: createKetoChecks(ory) });\n\t\t},\n\t};\n}\n",
26
+ "import type { Permission } from '@nxgt/ory-sdk';\nimport type { TokenPrincipal } from '@nxgt/shared';\nimport { ErrorCode } from '@nxgt/shared-exceptions';\nimport type { GraphQLBaseContext } from '../types';\nimport { denial } from '../utils/errors/denial';\nimport type { KetoChecksContext } from './keto-checker';\nimport type { OryContext } from './ory-auth';\n\n/**\n * The context `useOryAuth(ory)` and `useKetoChecks(ory)` build together —\n * what a resolver of an Ory-native API receives.\n *\n * createYoga<{}, OryGraphQLContext>({ plugins: [useOryAuth(ory), useKetoChecks(ory)] })\n */\nexport type OryGraphQLContext = GraphQLBaseContext &\n\tOryContext &\n\tKetoChecksContext;\n\n/** The question `can` asks, in `@permission`'s words. */\nexport type CanQuestion = {\n\t/** The permit, e.g. `view`. */\n\tname: string;\n\t/** The Keto namespace, e.g. `Note`. */\n\ttype: string;\n\t/** The object id itself — a value, not a path. */\n\tid: string;\n};\n\n/**\n * The caller, or an `UNAUTHENTICATED` refusal: a `GraphQLError` answered 401.\n * An absent caller is not an error to swallow in a resolver that needs one.\n */\nexport function requireUser(context: {\n\tuser?: TokenPrincipal | null;\n}): TokenPrincipal {\n\tif (!context.user) {\n\t\tthrow denial(ErrorCode.Unauthenticated);\n\t}\n\treturn context.user;\n}\n\n/**\n * Asks Keto what `@permission` would, from a resolver — through the same\n * per-request memo, so a question the directive already asked is free.\n *\n * `true` or `false` is Keto's answer. Everything else throws: no caller is\n * `UNAUTHENTICATED`, a missing `useKetoChecks` is a wiring error, and an\n * outage is `OryUnavailable` (a 503) — never a `false` a caller could take\n * for a denial.\n */\nexport async function can(\n\tcontext: OryContext & KetoChecksContext,\n\tquestion: CanQuestion,\n): Promise<boolean> {\n\tconst subject = context.ory?.subject;\n\tif (!subject) {\n\t\tthrow denial(ErrorCode.Unauthenticated);\n\t}\n\tif (!context.ketoChecks) {\n\t\tthrow new Error(\n\t\t\t'can(): no checker on the context — useKetoChecks(ory) is not registered',\n\t\t);\n\t}\n\tconst permission: Permission = {\n\t\tnamespace: question.type,\n\t\tobject: question.id,\n\t\trelation: question.name,\n\t};\n\treturn context.ketoChecks(permission, subject);\n}\n",
27
+ "import {\n\tbearerOf,\n\ttype Ory,\n\ttype OryPrincipal,\n\ttype OryUnavailable,\n} from '@nxgt/ory-sdk';\nimport { claimsFromOryPrincipal } from '@nxgt/security/integrations/ory';\nimport type { PolicyClaims } from '@nxgt/security/policy';\nimport type { TokenPrincipal } from '@nxgt/shared';\nimport type { GraphQLError } from 'graphql';\nimport type { Plugin } from 'graphql-yoga';\nimport type { GraphQLBaseContext } from '../types';\nimport {\n\tisOryUnavailable,\n\tserviceUnavailableError,\n} from '../utils/errors/ory-unavailable';\n\n/**\n * What `useOryAuth()` adds to the context, next to `user` and `token`: the\n * Ory principal itself, or `null` when the request carried no honoured\n * credential. `user.sub === ory.subject` by construction; read `ory` when the\n * value is going to Keto, so the code says what it is.\n */\nexport type OryContext = {\n\tory?: OryPrincipal | null;\n\t/**\n\t * The caller in the vocabulary a rules document reads — what\n\t * `applyGraphqlPolicy`'s `getClaims` should return.\n\t *\n\t * It is NOT `user`. `TokenPrincipal` is the repo-wide principal shape and\n\t * carries what a service wants (`uid`, `name`, empty `authorities`); a\n\t * rule wants the OIDC claims, `email_verified`, `aal` and `aud` included,\n\t * and those have nowhere to live in a `TokenPrincipal`. Reading `user` as\n\t * claims is why `expression: \"claims.aal === 'aal2'\"` guarded a REST route\n\t * and silently guarded nothing here.\n\t *\n\t * Produced by the same `claimsFromOryPrincipal` the REST middleware uses,\n\t * so one rule reads the same on both transports.\n\t */\n\tclaims?: PolicyClaims;\n};\n\n/**\n * The repo-wide TokenPrincipal an Ory principal becomes.\n *\n * `sub` and `uid` are both the Ory subject — a Kratos identity id for a\n * session or a person's token, the client id for a `client_credentials`\n * token — so every service that reads `this.principal?.sub` (or `.uid`) keeps\n * working unchanged. `authorities` is EMPTY on purpose: Keto answers per\n * object, and an empty list is what keeps `@policy` / `useGenericAuth`'s\n * policy extraction from granting anything by accident.\n */\nexport function toPrincipal(ory: OryPrincipal): TokenPrincipal {\n\tconst email = ory.identity?.email;\n\treturn {\n\t\tsub: ory.subject,\n\t\tuid: ory.subject,\n\t\tname: email ?? ory.clientId ?? ory.subject,\n\t\tusername: email,\n\t\tclientId: ory.clientId,\n\t\tscope: ory.scopes.join(' ') || undefined,\n\t\ttokenType: ory.kind,\n\t\texp: ory.expiresAt ? Math.floor(ory.expiresAt.getTime() / 1000) : undefined,\n\t\tauthorities: [],\n\t\troles: [],\n\t};\n}\n\n/**\n * A 503 the client can read as one — a real `GraphQLError` so Yoga's masking\n * leaves it alone, `extensions.http.status` so the transport says 503 too.\n * Never a denial: `@nxgt/ory-sdk` throws `OryUnavailable` only when Kratos,\n * Hydra or Keto could not answer, and that must not read as \"not signed in\".\n */\nexport function oryUnavailableError(error: OryUnavailable): GraphQLError {\n\treturn serviceUnavailableError(error);\n}\n\n/**\n * The one introspection code path — `Bearer` first, then `X-Session-Token`,\n * then the Kratos cookie; the first credential present decides. Exported so\n * a REST route mounted beside the GraphQL endpoint (content-hub-api's\n * webhook shape) authenticates through the same function instead of a\n * second call.\n */\nexport async function resolveOryPrincipal(\n\tory: Ory,\n\theaders: Headers,\n): Promise<OryContext & { user?: TokenPrincipal; token?: string }> {\n\tlet principal: OryPrincipal | null;\n\ttry {\n\t\tprincipal = await ory.resolve(headers);\n\t} catch (error) {\n\t\tif (isOryUnavailable(error)) throw oryUnavailableError(error);\n\t\tthrow error;\n\t}\n\n\treturn {\n\t\tory: principal,\n\t\tuser: principal ? toPrincipal(principal) : undefined,\n\t\tclaims: principal ? claimsFromOryPrincipal(principal) : undefined,\n\t\ttoken: bearerOf(headers) ?? undefined,\n\t};\n}\n\n/**\n * `useAuth()` for an Ory-native API: resolves the caller through Kratos\n * (session cookie, session token) or Hydra (Bearer, introspected) and puts\n * `user`, `claims`, `token` and `ory` on the context. Wire it ahead of\n * `useAuthenticated()`, which enforces `@authenticated` from `context.user`\n * and `context.ory.kind`.\n *\n * The `Ory` instance comes from the app's `createOry()` — one per process —\n * and is the same one the services use for `isAllowed`.\n */\nexport function useOryAuth(ory: Ory): Plugin<GraphQLBaseContext & OryContext> {\n\treturn {\n\t\tonContextBuilding: async ({ context, extendContext }) => {\n\t\t\textendContext(await resolveOryPrincipal(ory, context.request.headers));\n\t\t},\n\t};\n}\n",
28
+ "import type { OryUnavailable } from '@nxgt/ory-sdk';\nimport { ErrorCode } from '@nxgt/shared-exceptions';\nimport { GraphQLError } from 'graphql';\n\n/**\n * Whether an error is `@nxgt/ory-sdk`'s `OryUnavailable` — Kratos, Hydra or\n * Keto could not answer.\n *\n * By name and shape as well as by class: an install that resolves two copies\n * of `@nxgt/ory-sdk` (one under this package, one under the app) throws an\n * `OryUnavailable` this module's `instanceof` does not recognise, and an\n * outage that slips past here is masked as a 500 instead of answered as a 503.\n */\nexport function isOryUnavailable(error: unknown): error is OryUnavailable {\n\tif (!(error instanceof Error)) return false;\n\tconst service = (error as { service?: unknown }).service;\n\treturn error.name === 'OryUnavailable' && typeof service === 'string';\n}\n\n/**\n * A 503 the client can read as one — a real `GraphQLError` so Yoga's masking\n * leaves it alone, `extensions.http.status` so the transport says 503 too.\n * Never a denial: an outage must not read as \"not signed in\" or \"not allowed\".\n */\nexport function serviceUnavailableError(error: OryUnavailable): GraphQLError {\n\treturn new GraphQLError(`ory: ${error.service} is unavailable`, {\n\t\textensions: {\n\t\t\tcode: ErrorCode.ServiceUnavailable,\n\t\t\thttp: { status: 503 },\n\t\t\tdebugMessage: error.message,\n\t\t},\n\t});\n}\n",
35
29
  "import { GraphQLScalarType, Kind } from 'graphql';\n\nexport const ANY_SCALAR = {\n\tAny: new GraphQLScalarType<any, any>({\n\t\tname: 'Any',\n\t\tdescription: 'Generic scalar to represent any type',\n\t\tserialize(value) {\n\t\t\treturn value;\n\t\t},\n\t\tparseValue(value: any) {\n\t\t\treturn value;\n\t\t},\n\t\tparseLiteral(ast, variables) {\n\t\t\tswitch (ast.kind) {\n\t\t\t\tcase Kind.STRING:\n\t\t\t\tcase Kind.BOOLEAN:\n\t\t\t\t\treturn ast.value;\n\t\t\t\tcase Kind.INT:\n\t\t\t\tcase Kind.FLOAT:\n\t\t\t\t\treturn parseFloat(ast.value);\n\t\t\t\tcase Kind.OBJECT:\n\t\t\t\t\treturn Object.fromEntries(\n\t\t\t\t\t\tast.fields.map((field) => [field.name, field.value]),\n\t\t\t\t\t);\n\t\t\t\tcase Kind.LIST:\n\t\t\t\t\treturn ast.values.map((n) => this?.parseLiteral?.(n, variables));\n\t\t\t\tcase Kind.NULL:\n\t\t\t\t\treturn null;\n\t\t\t\tcase Kind.VARIABLE: {\n\t\t\t\t\tconst name = ast.name.value;\n\t\t\t\t\treturn variables ? variables[name] : undefined;\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t}),\n};\n",
36
30
  "import type { GraphQLScalarType } from 'graphql';\nimport {\n\tAccountNumberResolver,\n\tBigIntResolver,\n\tCountryCodeResolver,\n\tCountryNameResolver,\n\tCuidResolver,\n\tCurrencyResolver,\n\tDateResolver,\n\tDateTimeISOResolver,\n\tDurationResolver,\n\tEmailAddressResolver,\n\tGeoJSONResolver,\n\tGUIDResolver,\n\tHexadecimalResolver,\n\tHexColorCodeResolver,\n\tHSLAResolver,\n\tHSLResolver,\n\tIBANResolver,\n\tIPResolver,\n\tIPv4Resolver,\n\tIPv6Resolver,\n\tISBNResolver,\n\tJSONObjectResolver,\n\tJSONResolver,\n\tJWTResolver,\n\tLatitudeResolver,\n\tLocaleResolver,\n\tLongitudeResolver,\n\tLongResolver,\n\tMACResolver,\n\tNegativeFloatResolver,\n\tNegativeIntResolver,\n\tNonEmptyStringResolver,\n\tNonNegativeFloatResolver,\n\tNonNegativeIntResolver,\n\tNonPositiveFloatResolver,\n\tNonPositiveIntResolver,\n\tObjectIDResolver,\n\tPhoneNumberResolver,\n\tPortResolver,\n\tPositiveFloatResolver,\n\tPositiveIntResolver,\n\tPostalCodeResolver,\n\tRGBAResolver,\n\tRGBResolver,\n\tSESSNResolver,\n\tTimeResolver,\n\tTimestampResolver,\n\tURLResolver,\n\tUSCurrencyResolver,\n\tUtcOffsetResolver,\n\tUUIDResolver,\n\tVoidResolver,\n} from 'graphql-scalars';\nimport { createScalarFrom } from './utils';\n\nexport const CUSTOM_SCALARS: Record<string, GraphQLScalarType> = {\n\tAccountNumber: createScalarFrom(AccountNumberResolver, {\n\t\terrorMessage: 'validation.errors.invalid-account-number',\n\t}),\n\tBigInt: createScalarFrom(BigIntResolver, {\n\t\terrorMessage: 'validation.errors.invalid-big-int',\n\t}),\n\tCountryCode: createScalarFrom(CountryCodeResolver, {\n\t\terrorMessage: 'validation.errors.invalid-country-code',\n\t}),\n\tCountryName: createScalarFrom(CountryNameResolver, {\n\t\terrorMessage: 'validation.errors.invalid-country-name',\n\t}),\n\tCuid: createScalarFrom(CuidResolver, {\n\t\terrorMessage: 'validation.errors.invalid-cuid',\n\t}),\n\tCurrencyCode: createScalarFrom(CurrencyResolver, {\n\t\tname: 'CurrencyCode',\n\t\terrorMessage: 'validation.errors.invalid-currency',\n\t}),\n\tDate: createScalarFrom(DateResolver, {\n\t\terrorMessage: 'validation.errors.invalid-date',\n\t}),\n\tDateTime: createScalarFrom(DateTimeISOResolver, {\n\t\tname: 'DateTime',\n\t\terrorMessage: 'validation.errors.invalid-date-time',\n\t}),\n\tDuration: createScalarFrom(DurationResolver, {\n\t\terrorMessage: 'validation.errors.invalid-duration',\n\t}),\n\tEmailAddress: createScalarFrom(EmailAddressResolver, {\n\t\terrorMessage: 'validation.errors.invalid-email-address',\n\t}),\n\tGeoJSON: createScalarFrom(GeoJSONResolver, {\n\t\terrorMessage: 'validation.errors.invalid-geo-json',\n\t}),\n\tGUID: createScalarFrom(GUIDResolver, {\n\t\terrorMessage: 'validation.errors.invalid-guid',\n\t}),\n\tHexColorCode: createScalarFrom(HexColorCodeResolver, {\n\t\terrorMessage: 'validation.errors.invalid-hex-color-code',\n\t}),\n\tHexadecimal: createScalarFrom(HexadecimalResolver, {\n\t\terrorMessage: 'validation.errors.invalid-hexadecimal',\n\t}),\n\tHSL: createScalarFrom(HSLResolver, {\n\t\terrorMessage: 'validation.errors.invalid-hsl',\n\t}),\n\tHSLA: createScalarFrom(HSLAResolver, {\n\t\terrorMessage: 'validation.errors.invalid-hsla',\n\t}),\n\tIBAN: createScalarFrom(IBANResolver, {\n\t\terrorMessage: 'validation.errors.invalid-iban',\n\t}),\n\tIP: createScalarFrom(IPResolver, {\n\t\terrorMessage: 'validation.errors.invalid-ip',\n\t}),\n\tIPv4: createScalarFrom(IPv4Resolver, {\n\t\terrorMessage: 'validation.errors.invalid-ipv4',\n\t}),\n\tIPv6: createScalarFrom(IPv6Resolver, {\n\t\terrorMessage: 'validation.errors.invalid-ipv6',\n\t}),\n\tISBN: createScalarFrom(ISBNResolver, {\n\t\terrorMessage: 'validation.errors.invalid-isbn',\n\t}),\n\tJSON: createScalarFrom(JSONResolver, {\n\t\terrorMessage: 'validation.errors.invalid-json',\n\t}),\n\tJSONObject: createScalarFrom(JSONObjectResolver, {\n\t\terrorMessage: 'validation.errors.invalid-json-object',\n\t}),\n\tJWT: createScalarFrom(JWTResolver, {\n\t\terrorMessage: 'validation.errors.invalid-jwt',\n\t}),\n\tLatitude: createScalarFrom(LatitudeResolver, {\n\t\terrorMessage: 'validation.errors.invalid-latitude',\n\t}),\n\tLocale: createScalarFrom(LocaleResolver, {\n\t\terrorMessage: 'validation.errors.invalid-locale',\n\t}),\n\tLongitude: createScalarFrom(LongitudeResolver, {\n\t\terrorMessage: 'validation.errors.invalid-longitude',\n\t}),\n\tLong: createScalarFrom(LongResolver, {\n\t\terrorMessage: 'validation.errors.invalid-long',\n\t}),\n\tMAC: createScalarFrom(MACResolver, {\n\t\terrorMessage: 'validation.errors.invalid-mac',\n\t}),\n\tNegativeFloat: createScalarFrom(NegativeFloatResolver, {\n\t\terrorMessage: 'validation.errors.invalid-negative-float',\n\t}),\n\tNegativeInt: createScalarFrom(NegativeIntResolver, {\n\t\terrorMessage: 'validation.errors.invalid-negative-int',\n\t}),\n\tNonEmptyString: createScalarFrom(NonEmptyStringResolver, {\n\t\terrorMessage: 'validation.errors.invalid-non-empty-string',\n\t}),\n\tNonNegativeFloat: createScalarFrom(NonNegativeFloatResolver, {\n\t\terrorMessage: 'validation.errors.invalid-non-negative-float',\n\t}),\n\tNonNegativeInt: createScalarFrom(NonNegativeIntResolver, {\n\t\terrorMessage: 'validation.errors.invalid-non-negative-int',\n\t}),\n\tNonPositiveFloat: createScalarFrom(NonPositiveFloatResolver, {\n\t\terrorMessage: 'validation.errors.invalid-non-positive-float',\n\t}),\n\tNonPositiveInt: createScalarFrom(NonPositiveIntResolver, {\n\t\terrorMessage: 'validation.errors.invalid-non-positive-int',\n\t}),\n\tObjectID: createScalarFrom(ObjectIDResolver, {\n\t\terrorMessage: 'validation.errors.invalid-object-id',\n\t}),\n\tPhoneNumber: createScalarFrom(PhoneNumberResolver, {\n\t\terrorMessage: 'validation.errors.invalid-phone-number',\n\t}),\n\tPort: createScalarFrom(PortResolver, {\n\t\terrorMessage: 'validation.errors.invalid-port',\n\t}),\n\tPositiveFloat: createScalarFrom(PositiveFloatResolver, {\n\t\terrorMessage: 'validation.errors.invalid-positive-float',\n\t}),\n\tPositiveInt: createScalarFrom(PositiveIntResolver, {\n\t\terrorMessage: 'validation.errors.invalid-positive-int',\n\t}),\n\tPostalCode: createScalarFrom(PostalCodeResolver, {\n\t\terrorMessage: 'validation.errors.invalid-postal-code',\n\t}),\n\tRGB: createScalarFrom(RGBResolver, {\n\t\terrorMessage: 'validation.errors.invalid-rgb',\n\t}),\n\tRGBA: createScalarFrom(RGBAResolver, {\n\t\terrorMessage: 'validation.errors.invalid-rgba',\n\t}),\n\tSESSN: createScalarFrom(SESSNResolver, {\n\t\terrorMessage: 'validation.errors.invalid-sessn',\n\t}),\n\tTime: createScalarFrom(TimeResolver, {\n\t\terrorMessage: 'validation.errors.invalid-time',\n\t}),\n\tTimestamp: createScalarFrom(TimestampResolver, {\n\t\terrorMessage: 'validation.errors.invalid-timestamp',\n\t}),\n\tURL: createScalarFrom(URLResolver, {\n\t\terrorMessage: 'validation.errors.invalid-url',\n\t}),\n\tUSCurrency: createScalarFrom(USCurrencyResolver, {\n\t\terrorMessage: 'validation.errors.invalid-us-currency',\n\t}),\n\tUTCOffset: createScalarFrom(UtcOffsetResolver, {\n\t\terrorMessage: 'validation.errors.invalid-utc-offset',\n\t}),\n\tUUID: createScalarFrom(UUIDResolver, {\n\t\terrorMessage: 'validation.errors.invalid-uuid',\n\t}),\n\tVoid: createScalarFrom(VoidResolver, {\n\t\terrorMessage: 'validation.errors.invalid-void',\n\t}),\n};\n",
37
31
  "import type { LocaleKey } from '@nxgt/i18n';\nimport { CustomException } from '@nxgt/shared-exceptions';\nimport { logger } from '@nxgt/shared-logging';\nimport { GraphQLScalarType } from 'graphql';\n\nexport function createScalarFrom<T, R>(\n\tscalar: GraphQLScalarType<T, R>,\n\t{\n\t\tname,\n\t\tdescription,\n\t\terrorMessage,\n\t}: {\n\t\tname?: string;\n\t\tdescription?: string;\n\t\terrorMessage?: LocaleKey | string;\n\t},\n) {\n\tconst exception = CustomException.badRequest({\n\t\tmessage: errorMessage as LocaleKey,\n\t});\n\treturn new GraphQLScalarType<T, R>({\n\t\t...scalar,\n\t\tname: name ?? scalar.name,\n\t\tdescription: (description ?? scalar.description)?.replaceAll('`', \"'\"),\n\t\tserialize(value) {\n\t\t\tif (!errorMessage) {\n\t\t\t\treturn scalar.serialize(value);\n\t\t\t}\n\t\t\ttry {\n\t\t\t\treturn scalar.serialize(value);\n\t\t\t} catch (e) {\n\t\t\t\tlogger.error(e);\n\t\t\t\tthrow exception;\n\t\t\t}\n\t\t},\n\t\tparseValue(value) {\n\t\t\tif (!errorMessage) {\n\t\t\t\treturn scalar.parseValue(value);\n\t\t\t}\n\t\t\ttry {\n\t\t\t\treturn scalar.parseValue(value);\n\t\t\t} catch (e) {\n\t\t\t\tlogger.error(e);\n\t\t\t\tthrow exception;\n\t\t\t}\n\t\t},\n\t\t// Both arguments forwarded: graphql 17 declares `variables` required.\n\t\tparseLiteral(ast, variables) {\n\t\t\tif (!errorMessage) {\n\t\t\t\treturn scalar.parseLiteral(ast, variables);\n\t\t\t}\n\t\t\ttry {\n\t\t\t\treturn scalar.parseLiteral(ast, variables);\n\t\t\t} catch (e) {\n\t\t\t\tlogger.error(e);\n\t\t\t\tthrow exception;\n\t\t\t}\n\t\t},\n\t});\n}\n",
38
32
  "import GraphQLUpload from 'graphql-upload/GraphQLUpload.mjs';\nimport { createScalarFrom } from '../custom/utils';\n\nexport const UPLOAD_SCALAR = {\n\tUpload: createScalarFrom(GraphQLUpload as any, { name: 'Upload' }),\n};\n",
39
33
  "import type { GraphQLScalarType } from 'graphql';\nimport { ANY_SCALAR } from './any';\nimport { CUSTOM_SCALARS } from './custom';\nimport { UPLOAD_SCALAR } from './upload';\n\nexport const SCALAR_RESOLVERS: Record<string, GraphQLScalarType> = {\n\t...UPLOAD_SCALAR,\n\t...ANY_SCALAR,\n\t...CUSTOM_SCALARS,\n};\n",
40
- "export const SHARED_TYPE_DEFS = `\ntype Query {\n\t_empty: String\n}\ntype Mutation {\n\t_empty: String\n}\ntype Subscription {\n\t_empty: String\n}\n\ndirective @authenticated on FIELD_DEFINITION | OBJECT | INTERFACE | SCALAR | ENUM\n\ndirective @policy(policies: [[String!]!]!) on FIELD_DEFINITION | OBJECT | INTERFACE | SCALAR | ENUM\n\ndirective @shareable on OBJECT | FIELD_DEFINITION\n\ndirective @link(url: String!, import: [String!]) on SCHEMA\n\n`;\n",
41
- "import graphqlUploadExpress from 'graphql-upload/graphqlUploadExpress.mjs';\n\nexport { graphqlUploadExpress };\n"
34
+ "import { AUTHENTICATED_DIRECTIVE_SDL } from './directives/sdl';\n\nexport const SHARED_TYPE_DEFS = `\ntype Query {\n\t_empty: String\n}\ntype Mutation {\n\t_empty: String\n}\ntype Subscription {\n\t_empty: String\n}\n\n${AUTHENTICATED_DIRECTIVE_SDL}\ndirective @policy(policies: [[String!]!]!) on FIELD_DEFINITION | OBJECT | INTERFACE | SCALAR | ENUM\n\ndirective @shareable on OBJECT | FIELD_DEFINITION\n\ndirective @link(url: String!, import: [String!]) on SCHEMA\n\n`;\n",
35
+ "import graphqlUploadExpress from 'graphql-upload/graphqlUploadExpress.mjs';\n\nexport { graphqlUploadExpress };\n",
36
+ "import {\n\tAUDIT_EVENT,\n\ttype Audit,\n\ttype AuditService,\n\tCommitType,\n} from '@nxgt/shared-mongo';\nimport { withFilter } from 'graphql-subscriptions';\n\n/**\n * Minimal structural shape of the app's pubsub instance. Kept structural so\n * this factory does not couple to a specific `graphql-yoga` `PubSub<...>`\n * instantiation.\n */\nexport type ChangeResolversPubSub = {\n\tsubscribe: (event: string) => any;\n};\n\n/**\n * Minimal structural shape of the context every subgraph builds: an\n * `AuditService` under `services.audit`, plus the module's own CRUD service\n * exposing `findById`.\n */\nexport type ChangeResolversContext = {\n\tservices: {\n\t\taudit: AuditService;\n\t\t[key: string]: any;\n\t};\n};\n\nexport type CreateChangeResolversConfig = {\n\t/**\n\t * Singular camelCase entity name used to build the resolver field names:\n\t * `bed` -> `bedChanges`, `bedChangesById`, `bedChanged`.\n\t */\n\tentity: string;\n\t/**\n\t * Mongo collection name, i.e. `BedModel.collection.collectionName`.\n\t */\n\tcollection: string;\n\t/**\n\t * Key of the module's CRUD service on `context.services`, i.e. `beds`.\n\t */\n\tservice: string;\n\t/**\n\t * The app's pubsub instance, or a getter returning it. Prefer the getter\n\t * form (`() => pubsub`) when the app can re-create its pubsub at runtime,\n\t * so the subscription always resolves against the current instance.\n\t */\n\tpubsub: ChangeResolversPubSub | (() => ChangeResolversPubSub);\n};\n\nexport type ChangeResolvers = {\n\tQuery: Record<string, any>;\n\tSubscription: Record<string, any>;\n};\n\n/**\n * Builds the audit change-stream resolver block that is otherwise repeated\n * verbatim in every module's `*.resolver.ts`: the two paginated `Changes`\n * queries and the `Changed` subscription.\n *\n * ```ts\n * const changes = createChangeResolvers({\n * entity: 'bed',\n * collection: BedModel.collection.collectionName,\n * service: 'beds',\n * pubsub: () => pubsub,\n * });\n *\n * export const beds: Resolvers = {\n * Query: { bed: ..., beds: ..., ...changes.Query },\n * Subscription: { ...changes.Subscription },\n * };\n * ```\n */\nexport function createChangeResolvers(\n\tconfig: CreateChangeResolversConfig,\n): ChangeResolvers {\n\tconst { entity, collection, service, pubsub } = config;\n\n\tconst resolvePubSub = () =>\n\t\ttypeof pubsub === 'function' ? pubsub() : pubsub;\n\n\treturn {\n\t\tQuery: {\n\t\t\t[`${entity}Changes`]: async (\n\t\t\t\t_parent: unknown,\n\t\t\t\targs: any,\n\t\t\t\tcontext: ChangeResolversContext,\n\t\t\t) =>\n\t\t\t\tcontext.services.audit.findChangesPaginatedByCollection(\n\t\t\t\t\tcollection,\n\t\t\t\t\targs,\n\t\t\t\t),\n\t\t\t[`${entity}ChangesById`]: async (\n\t\t\t\t_parent: unknown,\n\t\t\t\targs: any,\n\t\t\t\tcontext: ChangeResolversContext,\n\t\t\t) =>\n\t\t\t\tcontext.services.audit.findChangesPaginatedByCollectionAndOid(\n\t\t\t\t\targs.id,\n\t\t\t\t\tcollection,\n\t\t\t\t\targs,\n\t\t\t\t),\n\t\t},\n\t\tSubscription: {\n\t\t\t[`${entity}Changed`]: {\n\t\t\t\tresolve: async (\n\t\t\t\t\tpayload: Audit,\n\t\t\t\t\t_args: any,\n\t\t\t\t\tcontext: ChangeResolversContext,\n\t\t\t\t) => ({\n\t\t\t\t\tid: context.services.audit.extractId(payload),\n\t\t\t\t\tdata:\n\t\t\t\t\t\tpayload.type !== CommitType.TERMINAL\n\t\t\t\t\t\t\t? await context.services[service].findById(payload.state._id)\n\t\t\t\t\t\t\t: null,\n\t\t\t\t\ttype: payload.type,\n\t\t\t\t}),\n\t\t\t\tsubscribe: withFilter(\n\t\t\t\t\t() => resolvePubSub().subscribe(AUDIT_EVENT),\n\t\t\t\t\t(payload: any, _variables: any, context?: ChangeResolversContext) =>\n\t\t\t\t\t\tcontext\n\t\t\t\t\t\t\t? context.services.audit.matches(payload, { collection })\n\t\t\t\t\t\t\t: false,\n\t\t\t\t),\n\t\t\t},\n\t\t},\n\t};\n}\n",
37
+ "export const SCALARS_MAPPING = {\n\tID: 'any',\n\tDateTime: 'any',\n\tDate: 'any',\n\tAny: 'any',\n\tBigInt: 'number',\n\tEmailAddress: 'string',\n\tGeoJSON: 'any',\n\tHSL: 'string',\n\tHSLA: 'string',\n\tHexColorCode: 'string',\n\tHexadecimal: 'string',\n\tIBAN: 'string',\n\tIP: 'string',\n\tTime: 'string',\n\tLocalTime: 'string',\n\tUUID: 'string',\n\tPositiveInt: 'number',\n\tNegativeInt: 'number',\n\tNonPositiveInt: 'number',\n\tNonNegativeInt: 'number',\n\tPositiveFloat: 'number',\n\tNegativeFloat: 'number',\n\tNonPositiveFloat: 'number',\n\tNonNegativeFloat: 'number',\n\tNonEmptyString: 'string',\n\tPostalCode: 'string',\n\tRGB: 'string',\n\tRGBA: 'string',\n\tSESSN: 'string',\n\tTimestamp: 'string',\n\tURL: 'string',\n\tUSCurrency: 'string',\n\tUTCOffset: 'string',\n\tLong: 'number',\n\tShort: 'number',\n\tByte: 'number',\n\tBigDecimal: 'string',\n\tBigInteger: 'string',\n\tChar: 'string',\n\tLocale: 'string',\n\tCountryCode: 'string',\n\tCountryName: 'string',\n\tAccountNumber: 'string',\n\tCurrencyCode: 'string',\n\tDuration: 'string',\n\tUrl: 'string',\n\tJSONObject: 'Record<string, any>',\n\tJSON: 'any',\n\tVoid: 'void',\n\tObjectID: 'any',\n\tUpload: 'File | Blob',\n\tEmail: 'string',\n\tPort: 'number',\n\tIPv4: 'string',\n\tIPv6: 'string',\n\tMAC: 'string',\n\tPassword: 'string',\n\tPhoneNumber: 'string',\n\tZIPCode: 'string',\n\tSSN: 'string',\n\tGUID: 'string',\n\tISBN: 'string',\n\tLatitude: 'number',\n\tLongitude: 'number',\n\tJWT: 'string',\n};\n",
38
+ "import { cast } from '@nxgt/shared/helpers';\nimport {\n\ttype HydratedDocument,\n\ttype IConnection,\n\ttype Model,\n\ttype mongoose,\n\ttype PaginationOptions,\n\tpaginateList,\n\ttype QueryFilter,\n\ttype SimplePaginationOptions,\n} from '@nxgt/shared-mongo';\nimport DataLoader from 'dataloader';\nimport { isArray } from 'lodash';\n\nexport function createDataLoader<K, V>(\n\tbatchLoadFn: DataLoader.BatchLoadFn<K, V>,\n\toptions?: DataLoader.Options<K, V, K>,\n) {\n\treturn new DataLoader(batchLoadFn, options);\n}\n\nexport function createConnectionListDataLoader<K, V>(\n\tpath: keyof K,\n\tmodel: Model<V, any, any, any, any, any, any>,\n\toptions: PaginationOptions,\n) {\n\treturn createDataLoader<K, IConnection<HydratedDocument<V>>>(async (docs) => {\n\t\tconst data: HydratedDocument<V>[] = await model\n\t\t\t.find({\n\t\t\t\t...(options.filter ?? {}),\n\t\t\t\t_id: docs.flatMap((doc) => {\n\t\t\t\t\tconst ids = doc[path] ?? [];\n\t\t\t\t\treturn isArray(ids)\n\t\t\t\t\t\t? cast<mongoose.Schema.Types.ObjectId[]>(\n\t\t\t\t\t\t\t\tids.filter(\n\t\t\t\t\t\t\t\t\t(item) =>\n\t\t\t\t\t\t\t\t\t\t!!item &&\n\t\t\t\t\t\t\t\t\t\t!['undefined', 'null'].includes((item as any)?.toString()),\n\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\t: [];\n\t\t\t\t}),\n\t\t\t})\n\t\t\t.exec();\n\t\treturn cast(\n\t\t\tdocs.map((doc) =>\n\t\t\t\tmodel.paginateList(\n\t\t\t\t\tdata.filter((child) =>\n\t\t\t\t\t\tcast<mongoose.Schema.Types.ObjectId[]>(doc[path] ?? [])\n\t\t\t\t\t\t\t.map((item) => item.toString())\n\t\t\t\t\t\t\t.includes((child._id as any).toString()),\n\t\t\t\t\t),\n\t\t\t\t\toptions,\n\t\t\t\t),\n\t\t\t),\n\t\t);\n\t});\n}\n\nexport function createChildrenConnectionDataLoader<K, V>(\n\tpath: keyof V,\n\tmodel: Model<V, any, any, any, any, any, any>,\n\toptions: PaginationOptions,\n) {\n\treturn createDataLoader<\n\t\tHydratedDocument<K>,\n\t\tIConnection<HydratedDocument<V>>\n\t>(async (docs) => {\n\t\tconst filter = {} as any;\n\t\tfilter[path] = docs.map((doc) => doc._id);\n\t\tconst data: HydratedDocument<V>[] = await model.find(filter).exec();\n\t\treturn cast(\n\t\t\tdocs.map((doc) =>\n\t\t\t\tpaginateList(\n\t\t\t\t\tdata.filter(\n\t\t\t\t\t\t(child) => doc._id?.toString() === (child[path] as any)?.toString(),\n\t\t\t\t\t) as any,\n\t\t\t\t\toptions,\n\t\t\t\t),\n\t\t\t),\n\t\t);\n\t});\n}\n\nexport function createSimpleListDataLoader<K, V>(\n\tpath: keyof K,\n\tmodel: Model<V, any, any, any, any, any, any>,\n\toptions?: SimplePaginationOptions,\n) {\n\treturn createDataLoader<K, HydratedDocument<V>[]>(async (docs) => {\n\t\tconst filter: QueryFilter<any> = options?.filter ?? {};\n\t\tconst ids = docs.flatMap((doc) => {\n\t\t\tconst ids = doc[path] ?? [];\n\t\t\treturn isArray(ids) ? cast<mongoose.Schema.Types.ObjectId[]>(ids) : [];\n\t\t});\n\t\tfilter._id = ids;\n\t\tconst query = model.find(filter);\n\t\tconst data: HydratedDocument<V>[] = await query.exec();\n\t\treturn cast(\n\t\t\tdocs.map((doc) => {\n\t\t\t\tconst result = data.filter((child) =>\n\t\t\t\t\tcast<mongoose.Schema.Types.ObjectId[]>(doc[path] ?? [])\n\t\t\t\t\t\t.map((item) => item.toString())\n\t\t\t\t\t\t.includes((child._id as any).toString()),\n\t\t\t\t);\n\t\t\t\tif (options?.skip && options?.limit) {\n\t\t\t\t\treturn result.slice(options.skip, options.skip + options.limit);\n\t\t\t\t}\n\t\t\t\tif (options?.limit) {\n\t\t\t\t\treturn result.slice(0, options.limit);\n\t\t\t\t}\n\t\t\t\tif (options?.skip) {\n\t\t\t\t\treturn result.slice(options.skip);\n\t\t\t\t}\n\t\t\t\treturn result;\n\t\t\t}),\n\t\t);\n\t});\n}\n\nexport function createChildrenListDataLoader<K, V>(\n\tpath: keyof V,\n\tmodel: Model<V, any, any, any, any, any, any>,\n\toptions?: SimplePaginationOptions,\n) {\n\treturn createDataLoader<HydratedDocument<K>, HydratedDocument<V>[]>(\n\t\tasync (docs) => {\n\t\t\tconst filter: QueryFilter<any> = options?.filter ?? {};\n\t\t\tconst key = path as any;\n\t\t\tfilter[key] = docs.map((doc) => doc._id);\n\t\t\tconst query = model.find(filter);\n\t\t\tconst data: HydratedDocument<V>[] = await query.exec();\n\t\t\treturn cast(\n\t\t\t\tdocs.map((doc) => {\n\t\t\t\t\tconst result = data.filter(\n\t\t\t\t\t\t(child) => child[path]?.toString() === (doc._id as any).toString(),\n\t\t\t\t\t);\n\n\t\t\t\t\tif (options?.skip && options?.limit) {\n\t\t\t\t\t\treturn result.slice(options.skip, options.skip + options.limit);\n\t\t\t\t\t}\n\t\t\t\t\tif (options?.limit) {\n\t\t\t\t\t\treturn result.slice(0, options.limit);\n\t\t\t\t\t}\n\t\t\t\t\tif (options?.skip) {\n\t\t\t\t\t\treturn result.slice(options.skip);\n\t\t\t\t\t}\n\t\t\t\t\treturn result;\n\t\t\t\t}),\n\t\t\t);\n\t\t},\n\t);\n}\n\nexport function createSingleChildDataLoader<K, V extends { id: string }>(\n\tpath: keyof K,\n\tmodel: Model<V, any, any, any, any, any, any>,\n) {\n\treturn createDataLoader<K, HydratedDocument<V> | null>(async (docs) => {\n\t\tconst data: HydratedDocument<V>[] = await model\n\t\t\t.find({\n\t\t\t\t_id: docs\n\t\t\t\t\t.map((doc) => cast<mongoose.Schema.Types.ObjectId>(doc[path]))\n\t\t\t\t\t.filter(\n\t\t\t\t\t\t(item) =>\n\t\t\t\t\t\t\t!!item && !['undefined', 'null'].includes(item?.toString()),\n\t\t\t\t\t),\n\t\t\t})\n\t\t\t.exec();\n\n\t\tconst map = new Map<string, HydratedDocument<V>>(\n\t\t\tdata.map((doc) => [doc.id, doc]),\n\t\t);\n\t\treturn docs.map((doc) => map.get(doc[path]?.toString() ?? '') ?? null);\n\t});\n}\n\nexport function createEntitiesReferenceLoader<V extends { id: string }>(\n\tmodel: Model<V, any, any, any, any, any, any>,\n) {\n\treturn createDataLoader<string, HydratedDocument<V> | null>(async (ids) => {\n\t\tconst docs: HydratedDocument<V>[] = await model\n\t\t\t.find({\n\t\t\t\t_id: ids.filter(\n\t\t\t\t\t(item) => !!item && !['undefined', 'null'].includes(item?.toString()),\n\t\t\t\t),\n\t\t\t})\n\t\t\t.exec();\n\n\t\tconst map = new Map<string, HydratedDocument<V>>(\n\t\t\tdocs.map((doc) => [doc.id, doc]),\n\t\t);\n\n\t\treturn ids.map((id) => map.get(id) ?? null);\n\t}) as DataLoader<string, HydratedDocument<V> | null>;\n}\n",
39
+ "import { GraphQLError, type GraphQLErrorOptions } from 'graphql';\n\nexport function createGraphQLError(\n\tmessage: string,\n\toptions?: GraphQLErrorOptions,\n): GraphQLError {\n\treturn new GraphQLError(message, options);\n}\n",
40
+ "import type { ApolloServerOptions } from '@apollo/server';\nimport {\n\tApolloServerErrorCode,\n\tunwrapResolverError,\n} from '@apollo/server/errors';\nimport {\n\ttype LocaleKey,\n\ttype TranslationContext,\n\ttranslate as translateBase,\n} from '@nxgt/i18n';\nimport { CustomException, ErrorCode } from '@nxgt/shared-exceptions';\nimport { MONGO_UTILS, mongoose } from '@nxgt/shared-mongo';\nimport { kebabCase } from 'lodash';\nimport type { GraphQLBaseContext } from '../../types';\nimport { denialMessageKey } from './denial';\nimport { isOryUnavailable, serviceUnavailableError } from './ory-unavailable';\n\n/**\n * Apollo Server's `formatError`, taught this repo's exceptions — the Apollo\n * counterpart of `createMaskError`. `OryUnavailable` answers\n * `SERVICE_UNAVAILABLE`, never a denial and never an opaque\n * `INTERNAL_SERVER_ERROR`; a `denial()` keeps its code, and its message is\n * translated with `translate`.\n */\nexport function createFormatError<\n\tK extends LocaleKey,\n\tC extends GraphQLBaseContext = GraphQLBaseContext,\n>(\n\ttranslate: (\n\t\tmessage: K,\n\t\tcontext?: TranslationContext,\n\t) => string = translateBase,\n\tproduction?: boolean,\n): ApolloServerOptions<C>['formatError'] {\n\treturn (formattedError, graphQLError) => {\n\t\tif (production && formattedError.extensions?.stacktrace) {\n\t\t\tformattedError.extensions.stacktrace = undefined;\n\t\t}\n\t\tconst error = unwrapResolverError(graphQLError);\n\t\tif (isOryUnavailable(error)) {\n\t\t\tconst unavailable = serviceUnavailableError(error);\n\t\t\treturn {\n\t\t\t\t...formattedError,\n\t\t\t\tmessage: unavailable.message,\n\t\t\t\textensions: { ...formattedError.extensions, ...unavailable.extensions },\n\t\t\t};\n\t\t}\n\t\tconst key = denialMessageKey(error);\n\t\tif (key !== undefined) {\n\t\t\treturn { ...formattedError, message: translate(key as K) };\n\t\t}\n\t\tif (\n\t\t\terror instanceof CustomException ||\n\t\t\terror instanceof mongoose.MongooseError\n\t\t) {\n\t\t\tconst exception =\n\t\t\t\terror instanceof mongoose.MongooseError\n\t\t\t\t\t? MONGO_UTILS.castError(error)\n\t\t\t\t\t: (error as CustomException);\n\t\t\treturn {\n\t\t\t\t...formattedError,\n\t\t\t\tmessage:\n\t\t\t\t\texception.errorCode === ErrorCode.ValidationError\n\t\t\t\t\t\t? exception.message\n\t\t\t\t\t\t: translate(exception.message as K, exception.options),\n\t\t\t\textensions: {\n\t\t\t\t\t...formattedError.extensions,\n\t\t\t\t\tcode: exception.errorCode,\n\t\t\t\t\tdebugMessage: exception.debugMessage,\n\t\t\t\t},\n\t\t\t};\n\t\t}\n\t\tif (\n\t\t\t[\n\t\t\t\tApolloServerErrorCode.GRAPHQL_VALIDATION_FAILED,\n\t\t\t\tApolloServerErrorCode.BAD_REQUEST,\n\t\t\t\tApolloServerErrorCode.BAD_USER_INPUT,\n\t\t\t\tApolloServerErrorCode.GRAPHQL_PARSE_FAILED,\n\t\t\t\tApolloServerErrorCode.OPERATION_RESOLUTION_FAILURE,\n\t\t\t\tApolloServerErrorCode.PERSISTED_QUERY_NOT_FOUND,\n\t\t\t\tApolloServerErrorCode.PERSISTED_QUERY_NOT_SUPPORTED,\n\t\t\t].includes(formattedError.extensions?.code as any)\n\t\t) {\n\t\t\treturn {\n\t\t\t\t...formattedError,\n\t\t\t\tmessage: translate(\n\t\t\t\t\t`errors.${kebabCase(formattedError.extensions?.code as string)}` as K,\n\t\t\t\t\t{},\n\t\t\t\t),\n\t\t\t\textensions: {\n\t\t\t\t\t...formattedError.extensions,\n\t\t\t\t\tdebugMessage: formattedError.message,\n\t\t\t\t},\n\t\t\t};\n\t\t}\n\t\treturn formattedError;\n\t};\n}\n",
41
+ "import {\n\ttype LocaleKey,\n\ttype TranslationContext,\n\ttranslate as translateBase,\n} from '@nxgt/i18n';\nimport { CustomException, ErrorCode } from '@nxgt/shared-exceptions';\nimport { MONGO_UTILS, mongoose } from '@nxgt/shared-mongo';\nimport { GraphQLError } from 'graphql';\nimport type { MaskError } from 'graphql-yoga';\nimport { denialMessageKey } from './denial';\nimport { isOryUnavailable, serviceUnavailableError } from './ory-unavailable';\n\ntype Translate<K extends LocaleKey> = (\n\tmessage: K,\n\tcontext?: TranslationContext,\n) => string;\n\n/**\n * Yoga's `maskedErrors.maskError`, taught this repo's exceptions.\n *\n * Yoga masks anything that is not a `GraphQLError` as \"Unexpected error.\" —\n * and `CustomException` extends `Error`, so out of the box a service's\n * `notFound()` or `forbidden()` reaches the client as an opaque 500. This\n * turns one into a `GraphQLError` with the translated message, the\n * exception's `code` in `extensions`, and a matching HTTP status\n * (`UNAUTHENTICATED` 401, `FORBIDDEN` 403, `NOT_FOUND` 404); a Mongoose error\n * goes through `castError` first, as `createFormatError` does for Apollo.\n * `OryUnavailable` (@nxgt/ory-sdk) becomes a 503 `SERVICE_UNAVAILABLE`, never\n * a denial. A `denial()` — what the directives, `requireUser` and `can` throw\n * — keeps its code and status, and its message is translated with `translate`. Everything else is masked as Yoga's default masks it: a\n * `GraphQLError` thrown on purpose — or raised by validation — passes, and one\n * that only wraps a plain `Error` a resolver threw is replaced by `message`,\n * so an internal message never reaches the client.\n *\n * createYoga({ maskedErrors: { maskError: createMaskError(translate) } })\n */\nexport function createMaskError<K extends LocaleKey>(\n\ttranslate: Translate<K> = translateBase,\n): MaskError {\n\treturn (error, message, isDev) => {\n\t\tconst original =\n\t\t\terror instanceof GraphQLError && error.originalError\n\t\t\t\t? error.originalError\n\t\t\t\t: error;\n\n\t\tif (isOryUnavailable(original)) return serviceUnavailableError(original);\n\n\t\tconst key = denialMessageKey(original);\n\t\tif (key !== undefined) {\n\t\t\treturn new GraphQLError(translate(key as K), {\n\t\t\t\t...locationOf(error),\n\t\t\t\textensions: (original as GraphQLError).extensions,\n\t\t\t});\n\t\t}\n\n\t\tif (\n\t\t\toriginal instanceof CustomException ||\n\t\t\toriginal instanceof mongoose.MongooseError\n\t\t) {\n\t\t\treturn exceptionError(original, translate);\n\t\t}\n\n\t\tif (isOriginalGraphQLError(error)) return error;\n\t\treturn new GraphQLError(message, {\n\t\t\t...locationOf(error),\n\t\t\textensions: isDev\n\t\t\t\t? {\n\t\t\t\t\t\tcode: ErrorCode.InternalServerError,\n\t\t\t\t\t\tdebugMessage: String(original),\n\t\t\t\t\t}\n\t\t\t\t: { code: ErrorCode.InternalServerError },\n\t\t});\n\t};\n}\n\nfunction exceptionError<K extends LocaleKey>(\n\toriginal: CustomException | mongoose.MongooseError,\n\ttranslate: Translate<K>,\n): GraphQLError {\n\tconst exception =\n\t\toriginal instanceof mongoose.MongooseError\n\t\t\t? MONGO_UTILS.castError(original)\n\t\t\t: original;\n\t// The exception carries the status itself.\n\tconst status = exception.code;\n\treturn new GraphQLError(\n\t\texception.errorCode === ErrorCode.ValidationError\n\t\t\t? exception.message\n\t\t\t: translate(exception.message as K, exception.options),\n\t\t{\n\t\t\textensions: {\n\t\t\t\tcode: exception.errorCode,\n\t\t\t\t...(status ? { http: { status } } : {}),\n\t\t\t\t...(exception.debugMessage\n\t\t\t\t\t? { debugMessage: exception.debugMessage }\n\t\t\t\t\t: {}),\n\t\t\t},\n\t\t},\n\t);\n}\n\n/**\n * Yoga's own test: a `GraphQLError` is \"original\" when it — or the error it\n * wraps, all the way down — was a `GraphQLError` to begin with. Graphql-js\n * wraps every resolver error in one, so `instanceof GraphQLError` alone lets\n * a plain `Error`'s message through.\n */\nfunction isOriginalGraphQLError(error: unknown): error is GraphQLError {\n\tif (!(error instanceof GraphQLError)) return false;\n\treturn error.originalError == null\n\t\t? true\n\t\t: isOriginalGraphQLError(error.originalError);\n}\n\n/** Where the masked error happened, kept so the client still sees a `path`. */\nfunction locationOf(error: unknown) {\n\tif (!(error instanceof GraphQLError)) return {};\n\treturn {\n\t\tnodes: error.nodes,\n\t\tsource: error.source,\n\t\tpositions: error.positions,\n\t\tpath: error.path,\n\t};\n}\n",
42
+ "import { createRedisEventTarget } from '@graphql-yoga/redis-event-target';\nimport { createPubSub } from 'graphql-yoga';\nimport type { Redis } from 'ioredis';\n\nexport const createYogaPubSub = ({\n\tpublishClient,\n\tsubscribeClient,\n}: {\n\tpublishClient: Redis;\n\tsubscribeClient: Redis;\n}) => {\n\tconst eventTarget = createRedisEventTarget({\n\t\tpublishClient,\n\t\tsubscribeClient,\n\t});\n\n\treturn createPubSub({ eventTarget });\n};\n",
43
+ "import { existsSync } from 'node:fs';\nimport { dirname, join } from 'node:path';\nimport { fileURLToPath } from 'node:url';\nimport { buildSubgraphSchema as buildSubgraphSchemaBase } from '@apollo/subgraph';\nimport { loadFilesSync } from '@graphql-tools/load-files';\nimport { mergeTypeDefs } from '@graphql-tools/merge';\nimport { pruneSchema } from '@graphql-tools/utils';\nimport { printSchema } from 'graphql';\n\n/**\n * The `.graphqls` this package ships live in `graphql/` at its root, so that\n * they survive `bun pm pack` — the bundle in `dist/` carries no assets. Their\n * directory is not at a fixed depth from this file: it is `src/utils` in the\n * workspace and `dist` in the published bundle, which Bun flattens. Walking up\n * to the nearest `package.json` finds the package root in both.\n */\nfunction packageRoot() {\n\tlet dir = dirname(fileURLToPath(import.meta.url));\n\twhile (!existsSync(join(dir, 'package.json'))) {\n\t\tconst parent = dirname(dir);\n\t\tif (parent === dir)\n\t\t\tthrow new Error('@nxgt/shared-graphql: no package root');\n\t\tdir = parent;\n\t}\n\treturn dir;\n}\n\nexport const SHARED_SCHEMA_PATH = join(packageRoot(), 'graphql/**/*.graphqls');\n\nexport function loadTypeDefs(...paths: string[]) {\n\tconst typeDefs = mergeTypeDefs([\n\t\t...paths.flatMap((path) =>\n\t\t\tloadFilesSync(path, {\n\t\t\t\trecursive: true,\n\t\t\t}),\n\t\t),\n\t]);\n\n\treturn typeDefs;\n}\n\nexport function buildSubgraphSchema(\n\tmodulesOrSdl: Parameters<typeof buildSubgraphSchemaBase>[0],\n) {\n\treturn pruneSchema(buildSubgraphSchemaBase(modulesOrSdl), {\n\t\tskipUnusedTypesPruning: false,\n\t});\n}\n\n/**\n * Utility function to generate a GraphQL schema file from the provided type definitions.\n * @param output - The path where the generated schema file should be saved.\n * @param paths - An array of glob patterns to locate the GraphQL type definition files.\n */\nexport async function generateSchema(output: string, ...paths: string[]) {\n\tawait Bun.write(\n\t\toutput,\n\t\tprintSchema(buildSubgraphSchema(loadTypeDefs(...paths))),\n\t);\n}\n",
44
+ "import { createServer } from 'node:http';\nimport type { ServerOptions } from 'graphql-ws';\nimport { useServer } from 'graphql-ws/use/ws';\nimport type { YogaServerInstance } from 'graphql-yoga';\nimport { WebSocketServer } from 'ws';\n\nexport function setupYogaWebSocketServer<\n\tServerContext extends {},\n\tUserContext extends {},\n>({\n\tyoga,\n\tcontext,\n}: {\n\tyoga: YogaServerInstance<ServerContext, UserContext>;\n\tcontext?: ServerOptions['context'];\n}) {\n\tconst httpServer = createServer(yoga);\n\tconst wsServer = new WebSocketServer({\n\t\tserver: httpServer,\n\t\tpath: yoga.graphqlEndpoint,\n\t});\n\n\t// biome-ignore lint/correctness/useHookAtTopLevel: Not react related\n\tuseServer(\n\t\t{\n\t\t\texecute: (args: any) => args.rootValue.execute(args),\n\t\t\tsubscribe: (args: any) => args.rootValue.subscribe(args),\n\t\t\tonSubscribe: async (ctx, _id, params) => {\n\t\t\t\tconst { schema, execute, subscribe, contextFactory, parse, validate } =\n\t\t\t\t\tyoga.getEnveloped({\n\t\t\t\t\t\t...ctx,\n\t\t\t\t\t\treq: ctx.extra.request,\n\t\t\t\t\t\tsocket: ctx.extra.socket,\n\t\t\t\t\t\tparams,\n\t\t\t\t\t});\n\n\t\t\t\tconst args = {\n\t\t\t\t\tschema,\n\t\t\t\t\toperationName: params.operationName,\n\t\t\t\t\tdocument: parse(params.query),\n\t\t\t\t\tvariableValues: params.variables,\n\t\t\t\t\tcontextValue: await contextFactory(),\n\t\t\t\t\trootValue: {\n\t\t\t\t\t\texecute,\n\t\t\t\t\t\tsubscribe,\n\t\t\t\t\t},\n\t\t\t\t};\n\n\t\t\t\tconst errors = validate(args.schema, args.document);\n\t\t\t\tif (errors.length) return errors;\n\t\t\t\treturn args;\n\t\t\t},\n\t\t\tcontext,\n\t\t},\n\t\twsServer,\n\t);\n\n\tconst startServer = (port: number) =>\n\t\tnew Promise<void>((resolve) => httpServer.listen({ port }, resolve));\n\treturn { yoga, httpServer, startServer };\n}\n",
45
+ "import type { TokenPrincipal } from '@nxgt/shared';\nimport type { Context } from 'graphql-ws';\nimport type { createAuthClient } from 'stx-sdk/auth';\n\ntype AuthClient = ReturnType<typeof createAuthClient>;\n\nexport interface ResolvedWsUser {\n\tuser: TokenPrincipal | undefined;\n\ttoken: string | undefined;\n}\n\n/**\n * Resolves the authenticated TokenPrincipal for a `graphql-ws` connection - the\n * WS-transport equivalent of the HTTP-path `useOryAuth()` / `useAuth()`\n * plugins. There is no gateway hop for WS connections, so each app performs\n * the OAuth introspection call itself using its own `auth` client.\n *\n * Reads the bearer token off `connectionParams.authorization` /\n * `connectionParams.Authorization` (both casings are used by existing\n * clients), strips the `Bearer ` prefix, and introspects it. Returns\n * `user: undefined` for a missing, invalid, or inactive token - callers\n * pass `user ?? null` into their own `services()` factory, exactly as the\n * HTTP-path plugins already do.\n */\nexport async function resolveWsUser(\n\tconnectionParams: Context['connectionParams'],\n\tauthClient: AuthClient,\n): Promise<ResolvedWsUser> {\n\tconst rawToken =\n\t\t(connectionParams?.authorization as string | undefined) ??\n\t\t(connectionParams?.Authorization as string | undefined);\n\tconst token = rawToken?.replace('Bearer ', '');\n\n\tconst { data } = token\n\t\t? await authClient.POST('/oauth/introspect', { body: { token } })\n\t\t: { data: null };\n\n\tconst user = data?.active\n\t\t? ({ ...(data as any), name: (data as any).sub } as TokenPrincipal)\n\t\t: undefined;\n\n\treturn { user, token };\n}\n"
42
46
  ],
43
- "mappings": "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",
44
- "debugId": "E72214B01404888264756E2164756E21",
47
+ "mappings": "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",
48
+ "debugId": "A1D566582D44C98864756E2164756E21",
45
49
  "names": []
46
50
  }