@nxgt/shared-graphql 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (79) hide show
  1. package/README.md +15 -0
  2. package/dist/directives/federation.d.ts +2 -0
  3. package/dist/directives/federation.d.ts.map +1 -0
  4. package/dist/directives/index.d.ts +2 -0
  5. package/dist/directives/index.d.ts.map +1 -0
  6. package/dist/index.d.ts +12 -0
  7. package/dist/index.d.ts.map +1 -0
  8. package/dist/index.js +907 -0
  9. package/dist/index.js.map +31 -0
  10. package/dist/integrations/hono.d.ts +13 -0
  11. package/dist/integrations/hono.d.ts.map +1 -0
  12. package/dist/integrations/index.d.ts +2 -0
  13. package/dist/integrations/index.d.ts.map +1 -0
  14. package/dist/plugins/auth.d.ts +4 -0
  15. package/dist/plugins/auth.d.ts.map +1 -0
  16. package/dist/plugins/extract-jwt.d.ts +9 -0
  17. package/dist/plugins/extract-jwt.d.ts.map +1 -0
  18. package/dist/plugins/index.d.ts +4 -0
  19. package/dist/plugins/index.d.ts.map +1 -0
  20. package/dist/plugins/ory-auth.d.ts +55 -0
  21. package/dist/plugins/ory-auth.d.ts.map +1 -0
  22. package/dist/scalars/any/any.scalars.d.ts +5 -0
  23. package/dist/scalars/any/any.scalars.d.ts.map +1 -0
  24. package/dist/scalars/any/index.d.ts +2 -0
  25. package/dist/scalars/any/index.d.ts.map +1 -0
  26. package/dist/scalars/custom/custom.scalars.d.ts +3 -0
  27. package/dist/scalars/custom/custom.scalars.d.ts.map +1 -0
  28. package/dist/scalars/custom/index.d.ts +2 -0
  29. package/dist/scalars/custom/index.d.ts.map +1 -0
  30. package/dist/scalars/custom/utils.d.ts +8 -0
  31. package/dist/scalars/custom/utils.d.ts.map +1 -0
  32. package/dist/scalars/index.d.ts +3 -0
  33. package/dist/scalars/index.d.ts.map +1 -0
  34. package/dist/scalars/upload/index.d.ts +2 -0
  35. package/dist/scalars/upload/index.d.ts.map +1 -0
  36. package/dist/scalars/upload/upload.scalar.d.ts +4 -0
  37. package/dist/scalars/upload/upload.scalar.d.ts.map +1 -0
  38. package/dist/security/index.d.ts +2 -0
  39. package/dist/security/index.d.ts.map +1 -0
  40. package/dist/security/index.js +28 -0
  41. package/dist/security/index.js.map +11 -0
  42. package/dist/security/policies/evaluation.service.d.ts +9 -0
  43. package/dist/security/policies/evaluation.service.d.ts.map +1 -0
  44. package/dist/security/policies/exaluation.utils.d.ts +4 -0
  45. package/dist/security/policies/exaluation.utils.d.ts.map +1 -0
  46. package/dist/security/policies/index.d.ts +3 -0
  47. package/dist/security/policies/index.d.ts.map +1 -0
  48. package/dist/security/policies/policy.types.d.ts +3 -0
  49. package/dist/security/policies/policy.types.d.ts.map +1 -0
  50. package/dist/shared.d.ts +2 -0
  51. package/dist/shared.d.ts.map +1 -0
  52. package/dist/types/context.d.ts +14 -0
  53. package/dist/types/context.d.ts.map +1 -0
  54. package/dist/types/graphql.d.ts +1 -0
  55. package/dist/types/index.d.ts +3 -0
  56. package/dist/types/index.d.ts.map +1 -0
  57. package/dist/upload.d.ts +3 -0
  58. package/dist/upload.d.ts.map +1 -0
  59. package/dist/utils/change-resolvers.utils.d.ts +66 -0
  60. package/dist/utils/change-resolvers.utils.d.ts.map +1 -0
  61. package/dist/utils/codegen.utils.d.ts +68 -0
  62. package/dist/utils/codegen.utils.d.ts.map +1 -0
  63. package/dist/utils/data-loader.utils.d.ts +14 -0
  64. package/dist/utils/data-loader.utils.d.ts.map +1 -0
  65. package/dist/utils/errors.utils.d.ts +23 -0
  66. package/dist/utils/errors.utils.d.ts.map +1 -0
  67. package/dist/utils/index.d.ts +10 -0
  68. package/dist/utils/index.d.ts.map +1 -0
  69. package/dist/utils/publish.d.ts +8 -0
  70. package/dist/utils/publish.d.ts.map +1 -0
  71. package/dist/utils/sandbox.d.ts +9 -0
  72. package/dist/utils/sandbox.d.ts.map +1 -0
  73. package/dist/utils/schema.utils.d.ts +11 -0
  74. package/dist/utils/schema.utils.d.ts.map +1 -0
  75. package/dist/utils/websocket.d.ts +11 -0
  76. package/dist/utils/websocket.d.ts.map +1 -0
  77. package/dist/utils/ws-context.d.ts +24 -0
  78. package/dist/utils/ws-context.d.ts.map +1 -0
  79. package/package.json +85 -0
package/dist/index.js ADDED
@@ -0,0 +1,907 @@
1
+ // src/index.ts
2
+ import DataLoader2 from "dataloader";
3
+
4
+ export * from "graphql-subscriptions";
5
+
6
+ // src/directives/federation.ts
7
+ var FEDERATION_DIRECTIVES = `
8
+ directive @external on FIELD_DEFINITION | OBJECT
9
+ directive @requires(fields: FieldSet!) on FIELD_DEFINITION
10
+ directive @provides(fields: FieldSet!) on FIELD_DEFINITION
11
+ directive @key(fields: FieldSet!, resolvable: Boolean = true) repeatable on OBJECT | INTERFACE
12
+ directive @shareable repeatable on OBJECT | FIELD_DEFINITION
13
+ directive @inaccessible on FIELD_DEFINITION | OBJECT | INTERFACE | UNION | ARGUMENT_DEFINITION | SCALAR | ENUM | ENUM_VALUE | INPUT_OBJECT | INPUT_FIELD_DEFINITION
14
+ directive @tag(name: String!) repeatable on FIELD_DEFINITION | INTERFACE | OBJECT | UNION | ARGUMENT_DEFINITION | SCALAR | ENUM | ENUM_VALUE | INPUT_OBJECT | INPUT_FIELD_DEFINITION
15
+ directive @override(from: String!) on FIELD_DEFINITION
16
+ directive @composeDirective(name: String!) repeatable on SCHEMA
17
+ directive @interfaceObject on OBJECT
18
+ directive @authenticated on FIELD_DEFINITION | OBJECT | INTERFACE | SCALAR | ENUM
19
+ `;
20
+ // src/integrations/hono.ts
21
+ import { Hono } from "hono";
22
+ import { contextStorage } from "hono/context-storage";
23
+ import { createMiddleware } from "hono/factory";
24
+ import { languageDetector } from "hono/language";
25
+
26
+ // src/utils/change-resolvers.utils.ts
27
+ import {
28
+ AUDIT_EVENT,
29
+ CommitType
30
+ } from "@nxgt/shared-mongo";
31
+ import { withFilter } from "graphql-subscriptions";
32
+ function createChangeResolvers(config) {
33
+ const { entity, collection, service, pubsub } = config;
34
+ const resolvePubSub = () => typeof pubsub === "function" ? pubsub() : pubsub;
35
+ return {
36
+ Query: {
37
+ [`${entity}Changes`]: async (_parent, args, context) => context.services.audit.findChangesPaginatedByCollection(collection, args),
38
+ [`${entity}ChangesById`]: async (_parent, args, context) => context.services.audit.findChangesPaginatedByCollectionAndOid(args.id, collection, args)
39
+ },
40
+ Subscription: {
41
+ [`${entity}Changed`]: {
42
+ resolve: async (payload, _args, context) => ({
43
+ id: context.services.audit.extractId(payload),
44
+ data: payload.type !== CommitType.TERMINAL ? await context.services[service].findById(payload.state._id) : null,
45
+ type: payload.type
46
+ }),
47
+ subscribe: withFilter(() => resolvePubSub().subscribe(AUDIT_EVENT), (payload, _variables, context) => context ? context.services.audit.matches(payload, { collection }) : false)
48
+ }
49
+ }
50
+ };
51
+ }
52
+ // src/utils/codegen.utils.ts
53
+ var SCALARS_MAPPING = {
54
+ ID: "any",
55
+ DateTime: "any",
56
+ Date: "any",
57
+ Any: "any",
58
+ BigInt: "number",
59
+ EmailAddress: "string",
60
+ GeoJSON: "any",
61
+ HSL: "string",
62
+ HSLA: "string",
63
+ HexColorCode: "string",
64
+ Hexadecimal: "string",
65
+ IBAN: "string",
66
+ IP: "string",
67
+ Time: "string",
68
+ LocalTime: "string",
69
+ UUID: "string",
70
+ PositiveInt: "number",
71
+ NegativeInt: "number",
72
+ NonPositiveInt: "number",
73
+ NonNegativeInt: "number",
74
+ PositiveFloat: "number",
75
+ NegativeFloat: "number",
76
+ NonPositiveFloat: "number",
77
+ NonNegativeFloat: "number",
78
+ NonEmptyString: "string",
79
+ PostalCode: "string",
80
+ RGB: "string",
81
+ RGBA: "string",
82
+ SESSN: "string",
83
+ Timestamp: "string",
84
+ URL: "string",
85
+ USCurrency: "string",
86
+ UTCOffset: "string",
87
+ Long: "number",
88
+ Short: "number",
89
+ Byte: "number",
90
+ BigDecimal: "string",
91
+ BigInteger: "string",
92
+ Char: "string",
93
+ Locale: "string",
94
+ CountryCode: "string",
95
+ CountryName: "string",
96
+ AccountNumber: "string",
97
+ CurrencyCode: "string",
98
+ Duration: "string",
99
+ Url: "string",
100
+ JSONObject: "Record<string, any>",
101
+ JSON: "any",
102
+ Void: "void",
103
+ ObjectID: "any",
104
+ Upload: "File | Blob",
105
+ Email: "string",
106
+ Port: "number",
107
+ IPv4: "string",
108
+ IPv6: "string",
109
+ MAC: "string",
110
+ Password: "string",
111
+ PhoneNumber: "string",
112
+ ZIPCode: "string",
113
+ SSN: "string",
114
+ GUID: "string",
115
+ ISBN: "string",
116
+ Latitude: "number",
117
+ Longitude: "number",
118
+ JWT: "string"
119
+ };
120
+ // src/utils/data-loader.utils.ts
121
+ import { cast } from "@nxgt/shared/helpers";
122
+ import {
123
+ paginateList
124
+ } from "@nxgt/shared-mongo";
125
+ import DataLoader from "dataloader";
126
+ import { isArray } from "lodash";
127
+ function createDataLoader(batchLoadFn, options) {
128
+ return new DataLoader(batchLoadFn, options);
129
+ }
130
+ function createConnectionListDataLoader(path, model, options) {
131
+ return createDataLoader(async (docs) => {
132
+ const data = await model.find({
133
+ ...options.filter ?? {},
134
+ _id: docs.flatMap((doc) => {
135
+ const ids = doc[path] ?? [];
136
+ return isArray(ids) ? cast(ids.filter((item) => !!item && !["undefined", "null"].includes(item?.toString()))) : [];
137
+ })
138
+ }).exec();
139
+ return cast(docs.map((doc) => model.paginateList(data.filter((child) => cast(doc[path] ?? []).map((item) => item.toString()).includes(child._id.toString())), options)));
140
+ });
141
+ }
142
+ function createChildrenConnectionDataLoader(path, model, options) {
143
+ return createDataLoader(async (docs) => {
144
+ const filter = {};
145
+ filter[path] = docs.map((doc) => doc._id);
146
+ const data = await model.find(filter).exec();
147
+ return cast(docs.map((doc) => paginateList(data.filter((child) => doc._id?.toString() === child[path]?.toString()), options)));
148
+ });
149
+ }
150
+ function createSimpleListDataLoader(path, model, options) {
151
+ return createDataLoader(async (docs) => {
152
+ const filter = options?.filter ?? {};
153
+ const ids = docs.flatMap((doc) => {
154
+ const ids2 = doc[path] ?? [];
155
+ return isArray(ids2) ? cast(ids2) : [];
156
+ });
157
+ filter._id = ids;
158
+ const query = model.find(filter);
159
+ const data = await query.exec();
160
+ return cast(docs.map((doc) => {
161
+ const result = data.filter((child) => cast(doc[path] ?? []).map((item) => item.toString()).includes(child._id.toString()));
162
+ if (options?.skip && options?.limit) {
163
+ return result.slice(options.skip, options.skip + options.limit);
164
+ }
165
+ if (options?.limit) {
166
+ return result.slice(0, options.limit);
167
+ }
168
+ if (options?.skip) {
169
+ return result.slice(options.skip);
170
+ }
171
+ return result;
172
+ }));
173
+ });
174
+ }
175
+ function createChildrenListDataLoader(path, model, options) {
176
+ return createDataLoader(async (docs) => {
177
+ const filter = options?.filter ?? {};
178
+ const key = path;
179
+ filter[key] = docs.map((doc) => doc._id);
180
+ const query = model.find(filter);
181
+ const data = await query.exec();
182
+ return cast(docs.map((doc) => {
183
+ const result = data.filter((child) => child[path]?.toString() === doc._id.toString());
184
+ if (options?.skip && options?.limit) {
185
+ return result.slice(options.skip, options.skip + options.limit);
186
+ }
187
+ if (options?.limit) {
188
+ return result.slice(0, options.limit);
189
+ }
190
+ if (options?.skip) {
191
+ return result.slice(options.skip);
192
+ }
193
+ return result;
194
+ }));
195
+ });
196
+ }
197
+ function createSingleChildDataLoader(path, model) {
198
+ return createDataLoader(async (docs) => {
199
+ const data = await model.find({
200
+ _id: docs.map((doc) => cast(doc[path])).filter((item) => !!item && !["undefined", "null"].includes(item?.toString()))
201
+ }).exec();
202
+ const map = new Map(data.map((doc) => [doc.id, doc]));
203
+ return docs.map((doc) => map.get(doc[path]?.toString() ?? "") ?? null);
204
+ });
205
+ }
206
+ function createEntitiesReferenceLoader(model) {
207
+ return createDataLoader(async (ids) => {
208
+ const docs = await model.find({
209
+ _id: ids.filter((item) => !!item && !["undefined", "null"].includes(item?.toString()))
210
+ }).exec();
211
+ const map = new Map(docs.map((doc) => [doc.id, doc]));
212
+ return ids.map((id) => map.get(id) ?? null);
213
+ });
214
+ }
215
+ // src/utils/errors.utils.ts
216
+ import {
217
+ ApolloServerErrorCode,
218
+ unwrapResolverError
219
+ } from "@apollo/server/errors";
220
+ import {
221
+ translate as translateBase
222
+ } from "@nxgt/i18n";
223
+ import { CustomException, ErrorCode } from "@nxgt/shared-exceptions";
224
+ import { MONGO_UTILS, mongoose } from "@nxgt/shared-mongo";
225
+ import { GraphQLError } from "graphql";
226
+ import { kebabCase } from "lodash";
227
+ import { OryUnavailable } from "stx-sdk/ory";
228
+ function createGraphQLError(message, options) {
229
+ return new GraphQLError(message, options);
230
+ }
231
+ function createFormatError(translate = translateBase, production) {
232
+ return (formattedError, graphQLError) => {
233
+ if (production && formattedError.extensions?.stacktrace) {
234
+ formattedError.extensions.stacktrace = undefined;
235
+ }
236
+ const error = unwrapResolverError(graphQLError);
237
+ if (error instanceof CustomException || error instanceof mongoose.MongooseError) {
238
+ const exception = error instanceof mongoose.MongooseError ? MONGO_UTILS.castError(error) : error;
239
+ return {
240
+ ...formattedError,
241
+ message: exception.errorCode === ErrorCode.ValidationError ? exception.message : translate(exception.message, exception.options),
242
+ extensions: {
243
+ ...formattedError.extensions,
244
+ code: exception.errorCode,
245
+ debugMessage: exception.debugMessage
246
+ }
247
+ };
248
+ }
249
+ if ([
250
+ ApolloServerErrorCode.GRAPHQL_VALIDATION_FAILED,
251
+ ApolloServerErrorCode.BAD_REQUEST,
252
+ ApolloServerErrorCode.BAD_USER_INPUT,
253
+ ApolloServerErrorCode.GRAPHQL_PARSE_FAILED,
254
+ ApolloServerErrorCode.OPERATION_RESOLUTION_FAILURE,
255
+ ApolloServerErrorCode.PERSISTED_QUERY_NOT_FOUND,
256
+ ApolloServerErrorCode.PERSISTED_QUERY_NOT_SUPPORTED
257
+ ].includes(formattedError.extensions?.code)) {
258
+ return {
259
+ ...formattedError,
260
+ message: translate(`errors.${kebabCase(formattedError.extensions?.code)}`, {}),
261
+ extensions: {
262
+ ...formattedError.extensions,
263
+ debugMessage: formattedError.message
264
+ }
265
+ };
266
+ }
267
+ return formattedError;
268
+ };
269
+ }
270
+ var HTTP_STATUS_BY_CODE = {
271
+ [ErrorCode.BadRequest]: 400,
272
+ [ErrorCode.ValidationError]: 400,
273
+ [ErrorCode.Unauthenticated]: 401,
274
+ [ErrorCode.Forbidden]: 403,
275
+ [ErrorCode.NotFound]: 404,
276
+ [ErrorCode.Conflict]: 409,
277
+ [ErrorCode.ServiceUnavailable]: 503
278
+ };
279
+ function createMaskError(translate = translateBase) {
280
+ return (error, message, isDev) => {
281
+ const original = error instanceof GraphQLError && error.originalError ? error.originalError : error;
282
+ if (original instanceof OryUnavailable) {
283
+ return new GraphQLError(`ory: ${original.service} is unavailable`, {
284
+ extensions: {
285
+ code: ErrorCode.ServiceUnavailable,
286
+ http: { status: 503 },
287
+ debugMessage: original.message
288
+ }
289
+ });
290
+ }
291
+ if (original instanceof CustomException || original instanceof mongoose.MongooseError) {
292
+ const exception = original instanceof mongoose.MongooseError ? MONGO_UTILS.castError(original) : original;
293
+ const status = exception.code;
294
+ return new GraphQLError(exception.errorCode === ErrorCode.ValidationError ? exception.message : translate(exception.message, exception.options), {
295
+ extensions: {
296
+ code: exception.errorCode,
297
+ ...status ? { http: { status } } : {},
298
+ ...exception.debugMessage ? { debugMessage: exception.debugMessage } : {}
299
+ }
300
+ });
301
+ }
302
+ if (error instanceof GraphQLError)
303
+ return error;
304
+ return new GraphQLError(message, {
305
+ extensions: isDev ? { code: ErrorCode.InternalServerError, debugMessage: String(error) } : { code: ErrorCode.InternalServerError }
306
+ });
307
+ };
308
+ }
309
+ // src/utils/publish.ts
310
+ import { createRedisEventTarget } from "@graphql-yoga/redis-event-target";
311
+ import { createPubSub } from "graphql-yoga";
312
+ var createYogaPubSub = ({
313
+ publishClient,
314
+ subscribeClient
315
+ }) => {
316
+ const eventTarget = createRedisEventTarget({
317
+ publishClient,
318
+ subscribeClient
319
+ });
320
+ return createPubSub({ eventTarget });
321
+ };
322
+ // src/utils/sandbox.ts
323
+ import { html } from "hono/html";
324
+ var renderSandbox = ({
325
+ port = 8080,
326
+ hostname = "localhost",
327
+ graphqlEndpoint = "graphql",
328
+ protocol = "http",
329
+ title = "Sandbox Explorer"
330
+ }) => html`
331
+ <title>${title}</title>
332
+ <div id="sandbox" style="position:absolute;top:0;right:0;bottom:0;left:0"></div>
333
+ <script src="https://embeddable-sandbox.cdn.apollographql.com/_latest/embeddable-sandbox.umd.production.min.js"></script>
334
+ <script>
335
+ new window.EmbeddedSandbox({
336
+ target: "#sandbox",
337
+ // Pass through your server href if you are embedding on an endpoint.
338
+ // Otherwise, you can pass whatever endpoint you want Sandbox to start up with here.
339
+ initialEndpoint: "${protocol}://${hostname}:${port}/${graphqlEndpoint}",
340
+ handleRequest: (endpointUrl, options) => {
341
+ return fetch(endpointUrl, {
342
+ ...options,
343
+ headers: {
344
+ ...options.headers
345
+ },
346
+ })
347
+ },
348
+ hideCookieToggle: true,
349
+ });
350
+ // advanced options: https://www.apollographql.com/docs/studio/explorer/sandbox#embedding-sandbox
351
+ </script>
352
+
353
+ `;
354
+ // src/utils/schema.utils.ts
355
+ import { join } from "node:path";
356
+ import { buildSubgraphSchema as buildSubgraphSchemaBase } from "@apollo/subgraph";
357
+ import { loadFilesSync } from "@graphql-tools/load-files";
358
+ import { mergeTypeDefs } from "@graphql-tools/merge";
359
+ import { pruneSchema } from "@graphql-tools/utils";
360
+ import { printSchema } from "graphql";
361
+ var __dirname = "/home/steve/workspace/dev/nxgt-core/packages/shared-graphql/src/utils";
362
+ var SHARED_SCHEMA_PATH = join(__dirname, "./**/*.graphqls");
363
+ function loadTypeDefs(...paths) {
364
+ const typeDefs = mergeTypeDefs([
365
+ ...paths.flatMap((path) => loadFilesSync(path, {
366
+ recursive: true
367
+ }))
368
+ ]);
369
+ return typeDefs;
370
+ }
371
+ function buildSubgraphSchema(modulesOrSdl) {
372
+ return pruneSchema(buildSubgraphSchemaBase(modulesOrSdl), {
373
+ skipUnusedTypesPruning: false
374
+ });
375
+ }
376
+ async function generateSchema(output, ...paths) {
377
+ await Bun.write(output, printSchema(buildSubgraphSchema(loadTypeDefs(...paths))));
378
+ }
379
+ // src/utils/websocket.ts
380
+ import { createServer } from "node:http";
381
+ import { useServer } from "graphql-ws/use/ws";
382
+ import { WebSocketServer } from "ws";
383
+ function setupYogaWebSocketServer({
384
+ yoga,
385
+ context
386
+ }) {
387
+ const httpServer = createServer(yoga);
388
+ const wsServer = new WebSocketServer({
389
+ server: httpServer,
390
+ path: yoga.graphqlEndpoint
391
+ });
392
+ useServer({
393
+ execute: (args) => args.rootValue.execute(args),
394
+ subscribe: (args) => args.rootValue.subscribe(args),
395
+ onSubscribe: async (ctx, _id, params) => {
396
+ const { schema, execute, subscribe, contextFactory, parse, validate } = yoga.getEnveloped({
397
+ ...ctx,
398
+ req: ctx.extra.request,
399
+ socket: ctx.extra.socket,
400
+ params
401
+ });
402
+ const args = {
403
+ schema,
404
+ operationName: params.operationName,
405
+ document: parse(params.query),
406
+ variableValues: params.variables,
407
+ contextValue: await contextFactory(),
408
+ rootValue: {
409
+ execute,
410
+ subscribe
411
+ }
412
+ };
413
+ const errors = validate(args.schema, args.document);
414
+ if (errors.length)
415
+ return errors;
416
+ return args;
417
+ },
418
+ context
419
+ }, wsServer);
420
+ const startServer = (port) => new Promise((resolve) => httpServer.listen({ port }, resolve));
421
+ return { yoga, httpServer, startServer };
422
+ }
423
+ // src/utils/ws-context.ts
424
+ async function resolveWsUser(connectionParams, authClient) {
425
+ const rawToken = connectionParams?.authorization ?? connectionParams?.Authorization;
426
+ const token = rawToken?.replace("Bearer ", "");
427
+ const { data } = token ? await authClient.POST("/oauth/introspect", { body: { token } }) : { data: null };
428
+ const user = data?.active ? { ...data, name: data.sub } : undefined;
429
+ return { user, token };
430
+ }
431
+ // src/integrations/hono.ts
432
+ function sandboxExpolorer(options) {
433
+ return createMiddleware(async (ctx) => {
434
+ return ctx.html(renderSandbox(options));
435
+ });
436
+ }
437
+ function honoYoga(yoga) {
438
+ return createMiddleware(async (ctx) => {
439
+ const response = await yoga.fetch(ctx.req.raw);
440
+ return response;
441
+ });
442
+ }
443
+ function createYogaHono(yoga, options) {
444
+ const app = new Hono;
445
+ app.use(contextStorage());
446
+ app.use(languageDetector({
447
+ order: ["header"],
448
+ supportedLanguages: ["en", "fr"],
449
+ fallbackLanguage: "en",
450
+ caches: []
451
+ }));
452
+ app.get("/health", (ctx) => {
453
+ return ctx.json({ status: "ok" }, 200);
454
+ });
455
+ app.get(options?.sandbox?.endpoint || "sandbox", sandboxExpolorer(options?.sandbox || {}));
456
+ app.use(yoga.graphqlEndpoint, honoYoga(yoga));
457
+ return app;
458
+ }
459
+ // src/plugins/auth.ts
460
+ function useAuth() {
461
+ return {
462
+ onContextBuilding: async ({ context, extendContext }) => {
463
+ extendContext({
464
+ user: context.params.extensions?.user,
465
+ token: context.params.extensions?.token
466
+ });
467
+ }
468
+ };
469
+ }
470
+ // src/plugins/extract-jwt.ts
471
+ import { logger } from "@nxgt/shared-logging";
472
+ var extractJwtPlugin = {
473
+ async requestDidStart({ request, contextValue }) {
474
+ logger.info(`[${request.extensions?.subgraphName}] Extracting JWT from request extensions: ${request.extensions?.payload?.sub}`, request.extensions);
475
+ contextValue.jwt = {
476
+ payload: request.extensions?.payload
477
+ };
478
+ }
479
+ };
480
+ // src/plugins/ory-auth.ts
481
+ import { GraphQLError as GraphQLError2 } from "graphql";
482
+ import {
483
+ bearerOf,
484
+ OryUnavailable as OryUnavailable2
485
+ } from "stx-sdk/ory";
486
+ function toPrincipal(ory) {
487
+ const email = ory.identity?.email;
488
+ return {
489
+ sub: ory.subject,
490
+ uid: ory.subject,
491
+ name: email ?? ory.clientId ?? ory.subject,
492
+ username: email,
493
+ clientId: ory.clientId,
494
+ scope: ory.scopes.join(" ") || undefined,
495
+ tokenType: ory.kind,
496
+ exp: ory.expiresAt ? Math.floor(ory.expiresAt.getTime() / 1000) : undefined,
497
+ authorities: [],
498
+ roles: []
499
+ };
500
+ }
501
+ function oryUnavailableError(error) {
502
+ return new GraphQLError2(`ory: ${error.service} is unavailable`, {
503
+ extensions: {
504
+ code: "SERVICE_UNAVAILABLE",
505
+ http: { status: 503 },
506
+ debugMessage: error.message
507
+ }
508
+ });
509
+ }
510
+ async function resolveOryPrincipal(ory, headers) {
511
+ let principal;
512
+ try {
513
+ principal = await ory.resolve(headers);
514
+ } catch (error) {
515
+ if (error instanceof OryUnavailable2)
516
+ throw oryUnavailableError(error);
517
+ throw error;
518
+ }
519
+ return {
520
+ ory: principal,
521
+ user: principal ? toPrincipal(principal) : undefined,
522
+ token: bearerOf(headers) ?? undefined
523
+ };
524
+ }
525
+ function useOryAuth(ory) {
526
+ return {
527
+ onContextBuilding: async ({ context, extendContext }) => {
528
+ extendContext(await resolveOryPrincipal(ory, context.request.headers));
529
+ }
530
+ };
531
+ }
532
+ // src/scalars/any/any.scalars.ts
533
+ import { GraphQLScalarType, Kind } from "graphql";
534
+ var ANY_SCALAR = {
535
+ Any: new GraphQLScalarType({
536
+ name: "Any",
537
+ description: "Generic scalar to represent any type",
538
+ serialize(value) {
539
+ return value;
540
+ },
541
+ parseValue(value) {
542
+ return value;
543
+ },
544
+ parseLiteral(ast, variables) {
545
+ switch (ast.kind) {
546
+ case Kind.STRING:
547
+ case Kind.BOOLEAN:
548
+ return ast.value;
549
+ case Kind.INT:
550
+ case Kind.FLOAT:
551
+ return parseFloat(ast.value);
552
+ case Kind.OBJECT:
553
+ return Object.fromEntries(ast.fields.map((field) => [field.name, field.value]));
554
+ case Kind.LIST:
555
+ return ast.values.map((n) => this?.parseLiteral?.(n, variables));
556
+ case Kind.NULL:
557
+ return null;
558
+ case Kind.VARIABLE: {
559
+ const name = ast.name.value;
560
+ return variables ? variables[name] : undefined;
561
+ }
562
+ }
563
+ }
564
+ })
565
+ };
566
+ // src/scalars/custom/custom.scalars.ts
567
+ import {
568
+ AccountNumberResolver,
569
+ BigIntResolver,
570
+ CountryCodeResolver,
571
+ CountryNameResolver,
572
+ CuidResolver,
573
+ CurrencyResolver,
574
+ DateResolver,
575
+ DateTimeISOResolver,
576
+ DurationResolver,
577
+ EmailAddressResolver,
578
+ GeoJSONResolver,
579
+ GUIDResolver,
580
+ HexadecimalResolver,
581
+ HexColorCodeResolver,
582
+ HSLAResolver,
583
+ HSLResolver,
584
+ IBANResolver,
585
+ IPResolver,
586
+ IPv4Resolver,
587
+ IPv6Resolver,
588
+ ISBNResolver,
589
+ JSONObjectResolver,
590
+ JSONResolver,
591
+ JWTResolver,
592
+ LatitudeResolver,
593
+ LocaleResolver,
594
+ LongitudeResolver,
595
+ LongResolver,
596
+ MACResolver,
597
+ NegativeFloatResolver,
598
+ NegativeIntResolver,
599
+ NonEmptyStringResolver,
600
+ NonNegativeFloatResolver,
601
+ NonNegativeIntResolver,
602
+ NonPositiveFloatResolver,
603
+ NonPositiveIntResolver,
604
+ ObjectIDResolver,
605
+ PhoneNumberResolver,
606
+ PortResolver,
607
+ PositiveFloatResolver,
608
+ PositiveIntResolver,
609
+ PostalCodeResolver,
610
+ RGBAResolver,
611
+ RGBResolver,
612
+ SESSNResolver,
613
+ TimeResolver,
614
+ TimestampResolver,
615
+ URLResolver,
616
+ USCurrencyResolver,
617
+ UtcOffsetResolver,
618
+ UUIDResolver,
619
+ VoidResolver
620
+ } from "graphql-scalars";
621
+
622
+ // src/scalars/custom/utils.ts
623
+ import { CustomException as CustomException2 } from "@nxgt/shared-exceptions";
624
+ import { logger as logger2 } from "@nxgt/shared-logging";
625
+ import { GraphQLScalarType as GraphQLScalarType2 } from "graphql";
626
+ function createScalarFrom(scalar, {
627
+ name,
628
+ description,
629
+ errorMessage
630
+ }) {
631
+ const exception = CustomException2.badRequest({
632
+ message: errorMessage
633
+ });
634
+ return new GraphQLScalarType2({
635
+ ...scalar,
636
+ name: name ?? scalar.name,
637
+ description: (description ?? scalar.description)?.replaceAll("`", "'"),
638
+ serialize(value) {
639
+ if (!errorMessage) {
640
+ return scalar.serialize(value);
641
+ }
642
+ try {
643
+ return scalar.serialize(value);
644
+ } catch (e) {
645
+ logger2.error(e);
646
+ throw exception;
647
+ }
648
+ },
649
+ parseValue(value) {
650
+ if (!errorMessage) {
651
+ return scalar.parseValue(value);
652
+ }
653
+ try {
654
+ return scalar.parseValue(value);
655
+ } catch (e) {
656
+ logger2.error(e);
657
+ throw exception;
658
+ }
659
+ },
660
+ parseLiteral(ast) {
661
+ if (!errorMessage) {
662
+ return scalar.parseLiteral(ast);
663
+ }
664
+ try {
665
+ return scalar.parseLiteral(ast);
666
+ } catch (e) {
667
+ logger2.error(e);
668
+ throw exception;
669
+ }
670
+ }
671
+ });
672
+ }
673
+
674
+ // src/scalars/custom/custom.scalars.ts
675
+ var CUSTOM_SCALARS = {
676
+ AccountNumber: createScalarFrom(AccountNumberResolver, {
677
+ errorMessage: "validation.errors.invalid-account-number"
678
+ }),
679
+ BigInt: createScalarFrom(BigIntResolver, {
680
+ errorMessage: "validation.errors.invalid-big-int"
681
+ }),
682
+ CountryCode: createScalarFrom(CountryCodeResolver, {
683
+ errorMessage: "validation.errors.invalid-country-code"
684
+ }),
685
+ CountryName: createScalarFrom(CountryNameResolver, {
686
+ errorMessage: "validation.errors.invalid-country-name"
687
+ }),
688
+ Cuid: createScalarFrom(CuidResolver, {
689
+ errorMessage: "validation.errors.invalid-cuid"
690
+ }),
691
+ CurrencyCode: createScalarFrom(CurrencyResolver, {
692
+ name: "CurrencyCode",
693
+ errorMessage: "validation.errors.invalid-currency"
694
+ }),
695
+ Date: createScalarFrom(DateResolver, {
696
+ errorMessage: "validation.errors.invalid-date"
697
+ }),
698
+ DateTime: createScalarFrom(DateTimeISOResolver, {
699
+ name: "DateTime",
700
+ errorMessage: "validation.errors.invalid-date-time"
701
+ }),
702
+ Duration: createScalarFrom(DurationResolver, {
703
+ errorMessage: "validation.errors.invalid-duration"
704
+ }),
705
+ EmailAddress: createScalarFrom(EmailAddressResolver, {
706
+ errorMessage: "validation.errors.invalid-email-address"
707
+ }),
708
+ GeoJSON: createScalarFrom(GeoJSONResolver, {
709
+ errorMessage: "validation.errors.invalid-geo-json"
710
+ }),
711
+ GUID: createScalarFrom(GUIDResolver, {
712
+ errorMessage: "validation.errors.invalid-guid"
713
+ }),
714
+ HexColorCode: createScalarFrom(HexColorCodeResolver, {
715
+ errorMessage: "validation.errors.invalid-hex-color-code"
716
+ }),
717
+ Hexadecimal: createScalarFrom(HexadecimalResolver, {
718
+ errorMessage: "validation.errors.invalid-hexadecimal"
719
+ }),
720
+ HSL: createScalarFrom(HSLResolver, {
721
+ errorMessage: "validation.errors.invalid-hsl"
722
+ }),
723
+ HSLA: createScalarFrom(HSLAResolver, {
724
+ errorMessage: "validation.errors.invalid-hsla"
725
+ }),
726
+ IBAN: createScalarFrom(IBANResolver, {
727
+ errorMessage: "validation.errors.invalid-iban"
728
+ }),
729
+ IP: createScalarFrom(IPResolver, {
730
+ errorMessage: "validation.errors.invalid-ip"
731
+ }),
732
+ IPv4: createScalarFrom(IPv4Resolver, {
733
+ errorMessage: "validation.errors.invalid-ipv4"
734
+ }),
735
+ IPv6: createScalarFrom(IPv6Resolver, {
736
+ errorMessage: "validation.errors.invalid-ipv6"
737
+ }),
738
+ ISBN: createScalarFrom(ISBNResolver, {
739
+ errorMessage: "validation.errors.invalid-isbn"
740
+ }),
741
+ JSON: createScalarFrom(JSONResolver, {
742
+ errorMessage: "validation.errors.invalid-json"
743
+ }),
744
+ JSONObject: createScalarFrom(JSONObjectResolver, {
745
+ errorMessage: "validation.errors.invalid-json-object"
746
+ }),
747
+ JWT: createScalarFrom(JWTResolver, {
748
+ errorMessage: "validation.errors.invalid-jwt"
749
+ }),
750
+ Latitude: createScalarFrom(LatitudeResolver, {
751
+ errorMessage: "validation.errors.invalid-latitude"
752
+ }),
753
+ Locale: createScalarFrom(LocaleResolver, {
754
+ errorMessage: "validation.errors.invalid-locale"
755
+ }),
756
+ Longitude: createScalarFrom(LongitudeResolver, {
757
+ errorMessage: "validation.errors.invalid-longitude"
758
+ }),
759
+ Long: createScalarFrom(LongResolver, {
760
+ errorMessage: "validation.errors.invalid-long"
761
+ }),
762
+ MAC: createScalarFrom(MACResolver, {
763
+ errorMessage: "validation.errors.invalid-mac"
764
+ }),
765
+ NegativeFloat: createScalarFrom(NegativeFloatResolver, {
766
+ errorMessage: "validation.errors.invalid-negative-float"
767
+ }),
768
+ NegativeInt: createScalarFrom(NegativeIntResolver, {
769
+ errorMessage: "validation.errors.invalid-negative-int"
770
+ }),
771
+ NonEmptyString: createScalarFrom(NonEmptyStringResolver, {
772
+ errorMessage: "validation.errors.invalid-non-empty-string"
773
+ }),
774
+ NonNegativeFloat: createScalarFrom(NonNegativeFloatResolver, {
775
+ errorMessage: "validation.errors.invalid-non-negative-float"
776
+ }),
777
+ NonNegativeInt: createScalarFrom(NonNegativeIntResolver, {
778
+ errorMessage: "validation.errors.invalid-non-negative-int"
779
+ }),
780
+ NonPositiveFloat: createScalarFrom(NonPositiveFloatResolver, {
781
+ errorMessage: "validation.errors.invalid-non-positive-float"
782
+ }),
783
+ NonPositiveInt: createScalarFrom(NonPositiveIntResolver, {
784
+ errorMessage: "validation.errors.invalid-non-positive-int"
785
+ }),
786
+ ObjectID: createScalarFrom(ObjectIDResolver, {
787
+ errorMessage: "validation.errors.invalid-object-id"
788
+ }),
789
+ PhoneNumber: createScalarFrom(PhoneNumberResolver, {
790
+ errorMessage: "validation.errors.invalid-phone-number"
791
+ }),
792
+ Port: createScalarFrom(PortResolver, {
793
+ errorMessage: "validation.errors.invalid-port"
794
+ }),
795
+ PositiveFloat: createScalarFrom(PositiveFloatResolver, {
796
+ errorMessage: "validation.errors.invalid-positive-float"
797
+ }),
798
+ PositiveInt: createScalarFrom(PositiveIntResolver, {
799
+ errorMessage: "validation.errors.invalid-positive-int"
800
+ }),
801
+ PostalCode: createScalarFrom(PostalCodeResolver, {
802
+ errorMessage: "validation.errors.invalid-postal-code"
803
+ }),
804
+ RGB: createScalarFrom(RGBResolver, {
805
+ errorMessage: "validation.errors.invalid-rgb"
806
+ }),
807
+ RGBA: createScalarFrom(RGBAResolver, {
808
+ errorMessage: "validation.errors.invalid-rgba"
809
+ }),
810
+ SESSN: createScalarFrom(SESSNResolver, {
811
+ errorMessage: "validation.errors.invalid-sessn"
812
+ }),
813
+ Time: createScalarFrom(TimeResolver, {
814
+ errorMessage: "validation.errors.invalid-time"
815
+ }),
816
+ Timestamp: createScalarFrom(TimestampResolver, {
817
+ errorMessage: "validation.errors.invalid-timestamp"
818
+ }),
819
+ URL: createScalarFrom(URLResolver, {
820
+ errorMessage: "validation.errors.invalid-url"
821
+ }),
822
+ USCurrency: createScalarFrom(USCurrencyResolver, {
823
+ errorMessage: "validation.errors.invalid-us-currency"
824
+ }),
825
+ UTCOffset: createScalarFrom(UtcOffsetResolver, {
826
+ errorMessage: "validation.errors.invalid-utc-offset"
827
+ }),
828
+ UUID: createScalarFrom(UUIDResolver, {
829
+ errorMessage: "validation.errors.invalid-uuid"
830
+ }),
831
+ Void: createScalarFrom(VoidResolver, {
832
+ errorMessage: "validation.errors.invalid-void"
833
+ })
834
+ };
835
+ // src/scalars/upload/upload.scalar.ts
836
+ import GraphQLUpload from "graphql-upload/GraphQLUpload.mjs";
837
+ var UPLOAD_SCALAR = {
838
+ Upload: createScalarFrom(GraphQLUpload, { name: "Upload" })
839
+ };
840
+ // src/scalars/index.ts
841
+ var SCALAR_RESOLVERS = {
842
+ ...UPLOAD_SCALAR,
843
+ ...ANY_SCALAR,
844
+ ...CUSTOM_SCALARS
845
+ };
846
+ // src/shared.ts
847
+ var SHARED_TYPE_DEFS = `
848
+ type Query {
849
+ _empty: String
850
+ }
851
+ type Mutation {
852
+ _empty: String
853
+ }
854
+ type Subscription {
855
+ _empty: String
856
+ }
857
+
858
+ directive @authenticated on FIELD_DEFINITION | OBJECT | INTERFACE | SCALAR | ENUM
859
+
860
+ directive @policy(policies: [[String!]!]!) on FIELD_DEFINITION | OBJECT | INTERFACE | SCALAR | ENUM
861
+
862
+ directive @shareable on OBJECT | FIELD_DEFINITION
863
+
864
+ directive @link(url: String!, import: [String!]) on SCHEMA
865
+
866
+ `;
867
+ // src/upload.ts
868
+ import graphqlUploadExpress from "graphql-upload/graphqlUploadExpress.mjs";
869
+ export {
870
+ DataLoader2 as DataLoader,
871
+ FEDERATION_DIRECTIVES,
872
+ SCALARS_MAPPING,
873
+ SCALAR_RESOLVERS,
874
+ SHARED_SCHEMA_PATH,
875
+ SHARED_TYPE_DEFS,
876
+ buildSubgraphSchema,
877
+ createChangeResolvers,
878
+ createChildrenConnectionDataLoader,
879
+ createChildrenListDataLoader,
880
+ createConnectionListDataLoader,
881
+ createDataLoader,
882
+ createEntitiesReferenceLoader,
883
+ createFormatError,
884
+ createGraphQLError,
885
+ createMaskError,
886
+ createSimpleListDataLoader,
887
+ createSingleChildDataLoader,
888
+ createYogaHono,
889
+ createYogaPubSub,
890
+ extractJwtPlugin,
891
+ generateSchema,
892
+ graphqlUploadExpress,
893
+ honoYoga,
894
+ loadTypeDefs,
895
+ oryUnavailableError,
896
+ renderSandbox,
897
+ resolveOryPrincipal,
898
+ resolveWsUser,
899
+ sandboxExpolorer,
900
+ setupYogaWebSocketServer,
901
+ toPrincipal,
902
+ useAuth,
903
+ useOryAuth
904
+ };
905
+
906
+ //# debugId=E74E2102AC1DAAFD64756E2164756E21
907
+ //# sourceMappingURL=index.js.map