drizzle-graphql-plus 0.8.26 → 0.8.29

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
  });
@@ -2257,10 +2259,12 @@ var customScalars = /* @__PURE__ */ new Set();
2257
2259
  var enumDefinitions = /* @__PURE__ */ new Map();
2258
2260
  var requiredFieldFilters = /* @__PURE__ */ new Set();
2259
2261
  var foreignKeyTypes = /* @__PURE__ */ new Map();
2260
- var columnToSDL = (column, columnName, tableName, forceNullable = false) => {
2262
+ var columnToSDL = (column, columnName, tableName, forceNullable = false, isPrimaryKey = false) => {
2261
2263
  let baseType;
2262
2264
  if (column.customGraphqlType) {
2263
2265
  baseType = column.customGraphqlType;
2266
+ } else if (isPrimaryKey) {
2267
+ baseType = "ID";
2264
2268
  } else {
2265
2269
  const foreignKeyType = foreignKeyTypes.get(`${tableName}.${columnName}`);
2266
2270
  if (foreignKeyType) {
@@ -2392,11 +2396,16 @@ var generateTypeDefs = (tables, relations) => {
2392
2396
  continue;
2393
2397
  const referencedCustomType = referencedColumn.customGraphqlType;
2394
2398
  const foreignKeyHasCustomType = !!foreignKeyColumn.customGraphqlType;
2395
- if (referencedCustomType && !foreignKeyHasCustomType) {
2396
- foreignKeyTypes.set(
2397
- `${tableName}.${foreignKeyPropertyName}`,
2398
- referencedCustomType
2399
- );
2399
+ const referencedIsPrimaryKey = referencedColumn.primary || false;
2400
+ if (!foreignKeyHasCustomType) {
2401
+ if (referencedCustomType) {
2402
+ foreignKeyTypes.set(
2403
+ `${tableName}.${foreignKeyPropertyName}`,
2404
+ referencedCustomType
2405
+ );
2406
+ } else if (referencedIsPrimaryKey) {
2407
+ foreignKeyTypes.set(`${tableName}.${foreignKeyPropertyName}`, "ID");
2408
+ }
2400
2409
  }
2401
2410
  }
2402
2411
  }
@@ -2405,11 +2414,13 @@ var generateTypeDefs = (tables, relations) => {
2405
2414
  const typeName = capitalize(tableName);
2406
2415
  const fields = [];
2407
2416
  for (const [columnName, column] of Object.entries(tableInfo.columns)) {
2417
+ const isPrimaryKey = column.primary || false;
2408
2418
  const typeStr = columnToSDL(
2409
2419
  column,
2410
2420
  columnName,
2411
2421
  tableName,
2412
- false
2422
+ false,
2423
+ isPrimaryKey
2413
2424
  );
2414
2425
  const description = column.customGraphqlDescription;
2415
2426
  if (description) {
@@ -2441,11 +2452,13 @@ ${fields.join("\n")}
2441
2452
  }`);
2442
2453
  const insertFields = [];
2443
2454
  for (const [columnName, column] of Object.entries(tableInfo.columns)) {
2455
+ const isPrimaryKey = column.primary || false;
2444
2456
  const typeStr = columnToSDL(
2445
2457
  column,
2446
2458
  columnName,
2447
2459
  tableName,
2448
- false
2460
+ false,
2461
+ isPrimaryKey
2449
2462
  );
2450
2463
  const nullableType = typeStr.endsWith("!") ? typeStr.slice(0, -1) : typeStr;
2451
2464
  insertFields.push(` ${columnName}: ${nullableType}`);
@@ -2459,11 +2472,13 @@ ${insertFields.join("\n")}
2459
2472
  }
2460
2473
  const updateFields = [];
2461
2474
  for (const [columnName, column] of Object.entries(tableInfo.columns)) {
2475
+ const isPrimaryKey = column.primary || false;
2462
2476
  const typeStr = columnToSDL(
2463
2477
  column,
2464
2478
  columnName,
2465
2479
  tableName,
2466
- true
2480
+ true,
2481
+ isPrimaryKey
2467
2482
  );
2468
2483
  updateFields.push(` ${columnName}: ${typeStr}`);
2469
2484
  }
@@ -2474,11 +2489,13 @@ ${updateFields.join("\n")}
2474
2489
  );
2475
2490
  const whereFields = [];
2476
2491
  for (const [columnName, column] of Object.entries(tableInfo.columns)) {
2492
+ const isPrimaryKey = column.primary || false;
2477
2493
  const typeStr = columnToSDL(
2478
2494
  column,
2479
2495
  columnName,
2480
2496
  tableName,
2481
- true
2497
+ true,
2498
+ isPrimaryKey
2482
2499
  );
2483
2500
  const normalizedType = typeStr.replace(/[^a-zA-Z0-9]/g, "");
2484
2501
  const filterTypeName = `${normalizedType}FieldFilter`;
@@ -3106,6 +3123,268 @@ var buildSchemaSDL = (db, config) => {
3106
3123
  };
3107
3124
  };
3108
3125
 
3126
+ // src/export-tool/ExportStore.ts
3127
+ var ExportStore = class {
3128
+ store = /* @__PURE__ */ new Map();
3129
+ pending = /* @__PURE__ */ new Map();
3130
+ /**
3131
+ * Store a value for later retrieval
3132
+ * Resolves any pending promises waiting for this value
3133
+ */
3134
+ set(name, value) {
3135
+ this.store.set(name, value);
3136
+ const callbacks = this.pending.get(name);
3137
+ if (callbacks) {
3138
+ callbacks.forEach((resolve) => resolve(value));
3139
+ this.pending.delete(name);
3140
+ }
3141
+ }
3142
+ /**
3143
+ * Get a value if it exists, otherwise return undefined
3144
+ */
3145
+ get(name) {
3146
+ return this.store.get(name);
3147
+ }
3148
+ /**
3149
+ * Wait for a value to be available
3150
+ * Returns immediately if value already exists
3151
+ * Returns a Promise that resolves when value is set
3152
+ */
3153
+ async waitFor(name, timeout = 5e3) {
3154
+ if (this.store.has(name)) {
3155
+ return this.store.get(name);
3156
+ }
3157
+ return new Promise((resolve, reject) => {
3158
+ if (!this.pending.has(name)) {
3159
+ this.pending.set(name, []);
3160
+ }
3161
+ this.pending.get(name).push(resolve);
3162
+ setTimeout(() => {
3163
+ const callbacks = this.pending.get(name);
3164
+ if (callbacks) {
3165
+ const index = callbacks.indexOf(resolve);
3166
+ if (index > -1) {
3167
+ callbacks.splice(index, 1);
3168
+ reject(new Error(`Timeout waiting for export variable "${name}"`));
3169
+ }
3170
+ }
3171
+ }, timeout);
3172
+ });
3173
+ }
3174
+ /**
3175
+ * Check if a value has been set
3176
+ */
3177
+ has(name) {
3178
+ return this.store.has(name);
3179
+ }
3180
+ /**
3181
+ * Clear all stored values
3182
+ */
3183
+ clear() {
3184
+ this.store.clear();
3185
+ this.pending.clear();
3186
+ }
3187
+ /**
3188
+ * Get all stored values
3189
+ */
3190
+ getAll() {
3191
+ return Object.fromEntries(this.store.entries());
3192
+ }
3193
+ };
3194
+
3195
+ // src/export-tool/utils.ts
3196
+ function isExportVariable(value) {
3197
+ return typeof value === "string" && value.startsWith("$_") && value.length > 2;
3198
+ }
3199
+ function getVariableName(value) {
3200
+ if (!isExportVariable(value)) {
3201
+ return null;
3202
+ }
3203
+ return value.slice(2);
3204
+ }
3205
+ async function resolveExportVariables(args, exportStore, timeout) {
3206
+ if (isExportVariable(args)) {
3207
+ const varName = getVariableName(args);
3208
+ return await exportStore.waitFor(varName, timeout);
3209
+ }
3210
+ if (Array.isArray(args)) {
3211
+ const resolved = await Promise.all(
3212
+ args.map(async (item) => {
3213
+ if (isExportVariable(item)) {
3214
+ const varName = getVariableName(item);
3215
+ return await exportStore.waitFor(varName, timeout);
3216
+ } else if (typeof item === "object" && item !== null) {
3217
+ return await resolveExportVariables(item, exportStore, timeout);
3218
+ }
3219
+ return item;
3220
+ })
3221
+ );
3222
+ return resolved;
3223
+ }
3224
+ if (typeof args === "object" && args !== null) {
3225
+ const resolved = {};
3226
+ for (const [key, value] of Object.entries(args)) {
3227
+ if (isExportVariable(value)) {
3228
+ const varName = getVariableName(value);
3229
+ resolved[key] = await exportStore.waitFor(varName, timeout);
3230
+ } else if (Array.isArray(value)) {
3231
+ resolved[key] = await resolveExportVariables(
3232
+ value,
3233
+ exportStore,
3234
+ timeout
3235
+ );
3236
+ } else if (typeof value === "object" && value !== null) {
3237
+ resolved[key] = await resolveExportVariables(
3238
+ value,
3239
+ exportStore,
3240
+ timeout
3241
+ );
3242
+ } else {
3243
+ resolved[key] = value;
3244
+ }
3245
+ }
3246
+ return resolved;
3247
+ }
3248
+ return args;
3249
+ }
3250
+ function getExportDirective(fieldNode) {
3251
+ const node = fieldNode;
3252
+ if (!node || !node.directives) {
3253
+ return null;
3254
+ }
3255
+ const exportDirective = node.directives.find(
3256
+ (directive) => directive.name.value === "export"
3257
+ );
3258
+ if (!exportDirective) {
3259
+ return null;
3260
+ }
3261
+ const asArg = exportDirective.arguments?.find(
3262
+ (arg) => arg.name.value === "as"
3263
+ );
3264
+ if (!asArg || asArg.value.kind !== "StringValue") {
3265
+ return null;
3266
+ }
3267
+ return asArg.value.value;
3268
+ }
3269
+ function hasExportVariables(args) {
3270
+ if (isExportVariable(args)) {
3271
+ return true;
3272
+ }
3273
+ if (Array.isArray(args)) {
3274
+ return args.some((item) => hasExportVariables(item));
3275
+ }
3276
+ if (typeof args === "object" && args !== null) {
3277
+ for (const value of Object.values(args)) {
3278
+ if (hasExportVariables(value)) {
3279
+ return true;
3280
+ }
3281
+ }
3282
+ }
3283
+ return false;
3284
+ }
3285
+ function processExports(result, selectionSet, exportStore) {
3286
+ if (!result || !selectionSet)
3287
+ return;
3288
+ for (const selection of selectionSet.selections) {
3289
+ if (selection.kind !== "Field")
3290
+ continue;
3291
+ const resultKey = selection.alias?.value ?? selection.name.value;
3292
+ if (!(resultKey in result))
3293
+ continue;
3294
+ const value = result[resultKey];
3295
+ const exportName = getExportDirective(selection);
3296
+ if (exportName) {
3297
+ exportStore.set(exportName, value);
3298
+ }
3299
+ if (selection.selectionSet && value !== null && value !== void 0) {
3300
+ if (Array.isArray(value)) {
3301
+ value.forEach((item) => {
3302
+ if (item && typeof item === "object") {
3303
+ processExports(item, selection.selectionSet, exportStore);
3304
+ }
3305
+ });
3306
+ } else if (typeof value === "object") {
3307
+ processExports(value, selection.selectionSet, exportStore);
3308
+ }
3309
+ }
3310
+ }
3311
+ }
3312
+
3313
+ // src/export-tool/middleware.ts
3314
+ function createExportMiddleware() {
3315
+ return (next) => {
3316
+ return async (source, args, context, info) => {
3317
+ if (!context.exportStore) {
3318
+ context.exportStore = new ExportStore();
3319
+ }
3320
+ const exportStore = context.exportStore;
3321
+ let resolvedArgs = args;
3322
+ if (args && typeof args === "object" && hasExportVariables(args)) {
3323
+ try {
3324
+ resolvedArgs = await resolveExportVariables(args, exportStore);
3325
+ } catch (error) {
3326
+ throw new Error(
3327
+ `Failed to resolve export variables in ${info.parentType.name}.${info.fieldName}: ${error instanceof Error ? error.message : String(error)}`
3328
+ );
3329
+ }
3330
+ }
3331
+ const result = await next(source, resolvedArgs, context, info);
3332
+ const fieldNode = info.fieldNodes[0];
3333
+ if (!fieldNode)
3334
+ return result;
3335
+ const selfExportName = getExportDirective(fieldNode);
3336
+ if (selfExportName && result !== void 0 && result !== null) {
3337
+ exportStore.set(selfExportName, result);
3338
+ }
3339
+ if (fieldNode.selectionSet && result !== void 0 && result !== null) {
3340
+ if (Array.isArray(result)) {
3341
+ result.forEach((item) => {
3342
+ if (item && typeof item === "object") {
3343
+ processExports(item, fieldNode.selectionSet, exportStore);
3344
+ }
3345
+ });
3346
+ } else if (typeof result === "object") {
3347
+ processExports(result, fieldNode.selectionSet, exportStore);
3348
+ }
3349
+ }
3350
+ return result;
3351
+ };
3352
+ };
3353
+ }
3354
+
3355
+ // src/export-tool/makeScalarAcceptExports.ts
3356
+ var import_graphql11 = require("graphql");
3357
+ function makeScalarAcceptExports(originalScalar) {
3358
+ const config = originalScalar.toConfig();
3359
+ return new import_graphql11.GraphQLScalarType({
3360
+ ...config,
3361
+ name: config.name,
3362
+ // Keep original name to override it in schema
3363
+ description: `${config.description} (Wrapped with makeScalarAcceptExports to accept $_ export variables)`,
3364
+ serialize: config.serialize,
3365
+ parseValue(value) {
3366
+ if (typeof value === "string" && (value.startsWith("$_") || value === "")) {
3367
+ return value;
3368
+ }
3369
+ if (config.parseValue) {
3370
+ return config.parseValue(value);
3371
+ }
3372
+ return value;
3373
+ },
3374
+ parseLiteral(ast, variables) {
3375
+ if (ast.kind === import_graphql11.Kind.STRING) {
3376
+ if (ast.value.startsWith("$_") || ast.value === "") {
3377
+ return ast.value;
3378
+ }
3379
+ }
3380
+ if (config.parseLiteral) {
3381
+ return config.parseLiteral(ast, variables);
3382
+ }
3383
+ return void 0;
3384
+ }
3385
+ });
3386
+ }
3387
+
3109
3388
  // src/helpers.ts
3110
3389
  var import_drizzle_orm13 = require("drizzle-orm");
3111
3390
  function setCustomGraphQL(table, columnConfig) {
@@ -3137,6 +3416,8 @@ function setCustomGraphQLTypes(table, columnTypes) {
3137
3416
  0 && (module.exports = {
3138
3417
  buildSchema,
3139
3418
  buildSchemaSDL,
3419
+ createExportMiddleware,
3420
+ makeScalarAcceptExports,
3140
3421
  setCustomGraphQL,
3141
3422
  setCustomGraphQLTypes
3142
3423
  });