drizzle-graphql-plus 0.8.26 → 0.8.28

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/index.cjs CHANGED
@@ -22,6 +22,8 @@ var src_exports = {};
22
22
  __export(src_exports, {
23
23
  buildSchema: () => buildSchema,
24
24
  buildSchemaSDL: () => buildSchemaSDL,
25
+ createExportMiddleware: () => createExportMiddleware,
26
+ makeScalarAcceptExports: () => makeScalarAcceptExports,
25
27
  setCustomGraphQL: () => setCustomGraphQL,
26
28
  setCustomGraphQLTypes: () => setCustomGraphQLTypes
27
29
  });
@@ -3106,6 +3108,268 @@ var buildSchemaSDL = (db, config) => {
3106
3108
  };
3107
3109
  };
3108
3110
 
3111
+ // src/export-tool/ExportStore.ts
3112
+ var ExportStore = class {
3113
+ store = /* @__PURE__ */ new Map();
3114
+ pending = /* @__PURE__ */ new Map();
3115
+ /**
3116
+ * Store a value for later retrieval
3117
+ * Resolves any pending promises waiting for this value
3118
+ */
3119
+ set(name, value) {
3120
+ this.store.set(name, value);
3121
+ const callbacks = this.pending.get(name);
3122
+ if (callbacks) {
3123
+ callbacks.forEach((resolve) => resolve(value));
3124
+ this.pending.delete(name);
3125
+ }
3126
+ }
3127
+ /**
3128
+ * Get a value if it exists, otherwise return undefined
3129
+ */
3130
+ get(name) {
3131
+ return this.store.get(name);
3132
+ }
3133
+ /**
3134
+ * Wait for a value to be available
3135
+ * Returns immediately if value already exists
3136
+ * Returns a Promise that resolves when value is set
3137
+ */
3138
+ async waitFor(name, timeout = 5e3) {
3139
+ if (this.store.has(name)) {
3140
+ return this.store.get(name);
3141
+ }
3142
+ return new Promise((resolve, reject) => {
3143
+ if (!this.pending.has(name)) {
3144
+ this.pending.set(name, []);
3145
+ }
3146
+ this.pending.get(name).push(resolve);
3147
+ setTimeout(() => {
3148
+ const callbacks = this.pending.get(name);
3149
+ if (callbacks) {
3150
+ const index = callbacks.indexOf(resolve);
3151
+ if (index > -1) {
3152
+ callbacks.splice(index, 1);
3153
+ reject(new Error(`Timeout waiting for export variable "${name}"`));
3154
+ }
3155
+ }
3156
+ }, timeout);
3157
+ });
3158
+ }
3159
+ /**
3160
+ * Check if a value has been set
3161
+ */
3162
+ has(name) {
3163
+ return this.store.has(name);
3164
+ }
3165
+ /**
3166
+ * Clear all stored values
3167
+ */
3168
+ clear() {
3169
+ this.store.clear();
3170
+ this.pending.clear();
3171
+ }
3172
+ /**
3173
+ * Get all stored values
3174
+ */
3175
+ getAll() {
3176
+ return Object.fromEntries(this.store.entries());
3177
+ }
3178
+ };
3179
+
3180
+ // src/export-tool/utils.ts
3181
+ function isExportVariable(value) {
3182
+ return typeof value === "string" && value.startsWith("$_") && value.length > 2;
3183
+ }
3184
+ function getVariableName(value) {
3185
+ if (!isExportVariable(value)) {
3186
+ return null;
3187
+ }
3188
+ return value.slice(2);
3189
+ }
3190
+ async function resolveExportVariables(args, exportStore, timeout) {
3191
+ if (isExportVariable(args)) {
3192
+ const varName = getVariableName(args);
3193
+ return await exportStore.waitFor(varName, timeout);
3194
+ }
3195
+ if (Array.isArray(args)) {
3196
+ const resolved = await Promise.all(
3197
+ args.map(async (item) => {
3198
+ if (isExportVariable(item)) {
3199
+ const varName = getVariableName(item);
3200
+ return await exportStore.waitFor(varName, timeout);
3201
+ } else if (typeof item === "object" && item !== null) {
3202
+ return await resolveExportVariables(item, exportStore, timeout);
3203
+ }
3204
+ return item;
3205
+ })
3206
+ );
3207
+ return resolved;
3208
+ }
3209
+ if (typeof args === "object" && args !== null) {
3210
+ const resolved = {};
3211
+ for (const [key, value] of Object.entries(args)) {
3212
+ if (isExportVariable(value)) {
3213
+ const varName = getVariableName(value);
3214
+ resolved[key] = await exportStore.waitFor(varName, timeout);
3215
+ } else if (Array.isArray(value)) {
3216
+ resolved[key] = await resolveExportVariables(
3217
+ value,
3218
+ exportStore,
3219
+ timeout
3220
+ );
3221
+ } else if (typeof value === "object" && value !== null) {
3222
+ resolved[key] = await resolveExportVariables(
3223
+ value,
3224
+ exportStore,
3225
+ timeout
3226
+ );
3227
+ } else {
3228
+ resolved[key] = value;
3229
+ }
3230
+ }
3231
+ return resolved;
3232
+ }
3233
+ return args;
3234
+ }
3235
+ function getExportDirective(fieldNode) {
3236
+ const node = fieldNode;
3237
+ if (!node || !node.directives) {
3238
+ return null;
3239
+ }
3240
+ const exportDirective = node.directives.find(
3241
+ (directive) => directive.name.value === "export"
3242
+ );
3243
+ if (!exportDirective) {
3244
+ return null;
3245
+ }
3246
+ const asArg = exportDirective.arguments?.find(
3247
+ (arg) => arg.name.value === "as"
3248
+ );
3249
+ if (!asArg || asArg.value.kind !== "StringValue") {
3250
+ return null;
3251
+ }
3252
+ return asArg.value.value;
3253
+ }
3254
+ function hasExportVariables(args) {
3255
+ if (isExportVariable(args)) {
3256
+ return true;
3257
+ }
3258
+ if (Array.isArray(args)) {
3259
+ return args.some((item) => hasExportVariables(item));
3260
+ }
3261
+ if (typeof args === "object" && args !== null) {
3262
+ for (const value of Object.values(args)) {
3263
+ if (hasExportVariables(value)) {
3264
+ return true;
3265
+ }
3266
+ }
3267
+ }
3268
+ return false;
3269
+ }
3270
+ function processExports(result, selectionSet, exportStore) {
3271
+ if (!result || !selectionSet)
3272
+ return;
3273
+ for (const selection of selectionSet.selections) {
3274
+ if (selection.kind !== "Field")
3275
+ continue;
3276
+ const resultKey = selection.alias?.value ?? selection.name.value;
3277
+ if (!(resultKey in result))
3278
+ continue;
3279
+ const value = result[resultKey];
3280
+ const exportName = getExportDirective(selection);
3281
+ if (exportName) {
3282
+ exportStore.set(exportName, value);
3283
+ }
3284
+ if (selection.selectionSet && value !== null && value !== void 0) {
3285
+ if (Array.isArray(value)) {
3286
+ value.forEach((item) => {
3287
+ if (item && typeof item === "object") {
3288
+ processExports(item, selection.selectionSet, exportStore);
3289
+ }
3290
+ });
3291
+ } else if (typeof value === "object") {
3292
+ processExports(value, selection.selectionSet, exportStore);
3293
+ }
3294
+ }
3295
+ }
3296
+ }
3297
+
3298
+ // src/export-tool/middleware.ts
3299
+ function createExportMiddleware() {
3300
+ return (next) => {
3301
+ return async (source, args, context, info) => {
3302
+ if (!context.exportStore) {
3303
+ context.exportStore = new ExportStore();
3304
+ }
3305
+ const exportStore = context.exportStore;
3306
+ let resolvedArgs = args;
3307
+ if (args && typeof args === "object" && hasExportVariables(args)) {
3308
+ try {
3309
+ resolvedArgs = await resolveExportVariables(args, exportStore);
3310
+ } catch (error) {
3311
+ throw new Error(
3312
+ `Failed to resolve export variables in ${info.parentType.name}.${info.fieldName}: ${error instanceof Error ? error.message : String(error)}`
3313
+ );
3314
+ }
3315
+ }
3316
+ const result = await next(source, resolvedArgs, context, info);
3317
+ const fieldNode = info.fieldNodes[0];
3318
+ if (!fieldNode)
3319
+ return result;
3320
+ const selfExportName = getExportDirective(fieldNode);
3321
+ if (selfExportName && result !== void 0 && result !== null) {
3322
+ exportStore.set(selfExportName, result);
3323
+ }
3324
+ if (fieldNode.selectionSet && result !== void 0 && result !== null) {
3325
+ if (Array.isArray(result)) {
3326
+ result.forEach((item) => {
3327
+ if (item && typeof item === "object") {
3328
+ processExports(item, fieldNode.selectionSet, exportStore);
3329
+ }
3330
+ });
3331
+ } else if (typeof result === "object") {
3332
+ processExports(result, fieldNode.selectionSet, exportStore);
3333
+ }
3334
+ }
3335
+ return result;
3336
+ };
3337
+ };
3338
+ }
3339
+
3340
+ // src/export-tool/makeScalarAcceptExports.ts
3341
+ var import_graphql11 = require("graphql");
3342
+ function makeScalarAcceptExports(originalScalar) {
3343
+ const config = originalScalar.toConfig();
3344
+ return new import_graphql11.GraphQLScalarType({
3345
+ ...config,
3346
+ name: config.name,
3347
+ // Keep original name to override it in schema
3348
+ description: `${config.description} (Wrapped with makeScalarAcceptExports to accept $_ export variables)`,
3349
+ serialize: config.serialize,
3350
+ parseValue(value) {
3351
+ if (typeof value === "string" && (value.startsWith("$_") || value === "")) {
3352
+ return value;
3353
+ }
3354
+ if (config.parseValue) {
3355
+ return config.parseValue(value);
3356
+ }
3357
+ return value;
3358
+ },
3359
+ parseLiteral(ast, variables) {
3360
+ if (ast.kind === import_graphql11.Kind.STRING) {
3361
+ if (ast.value.startsWith("$_") || ast.value === "") {
3362
+ return ast.value;
3363
+ }
3364
+ }
3365
+ if (config.parseLiteral) {
3366
+ return config.parseLiteral(ast, variables);
3367
+ }
3368
+ return void 0;
3369
+ }
3370
+ });
3371
+ }
3372
+
3109
3373
  // src/helpers.ts
3110
3374
  var import_drizzle_orm13 = require("drizzle-orm");
3111
3375
  function setCustomGraphQL(table, columnConfig) {
@@ -3137,6 +3401,8 @@ function setCustomGraphQLTypes(table, columnTypes) {
3137
3401
  0 && (module.exports = {
3138
3402
  buildSchema,
3139
3403
  buildSchemaSDL,
3404
+ createExportMiddleware,
3405
+ makeScalarAcceptExports,
3140
3406
  setCustomGraphQL,
3141
3407
  setCustomGraphQLTypes
3142
3408
  });