@vantreeseba/drizzle-graphql 7.8.0 → 7.9.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.
package/dist/index.d.cts CHANGED
@@ -300,6 +300,13 @@ type ResolvedLimitPolicy = {
300
300
  * `buildSchema`; `undefined` for a table the caller left unbounded.
301
301
  */
302
302
  type LimitPolicyFor = (tableName: string) => ResolvedLimitPolicy | undefined;
303
+ /**
304
+ * {@link BuildSchemaConfig.defaults} resolved for one table: the `orderBy` a read falls back
305
+ * to when the request passes none, already in the shape the generated argument has.
306
+ * `undefined` means the table declares no default and keeps whatever order the database
307
+ * returns.
308
+ */
309
+ type DefaultOrderByFor = (tableName: string) => Record<string, any> | undefined;
303
310
  /**
304
311
  * Compiles an `orderBy` argument into ORDER BY expressions, highest priority first.
305
312
  *
@@ -399,6 +406,8 @@ type TablePolicies = {
399
406
  softDelete?: SoftDeleteFor;
400
407
  /** See `BuildSchemaConfig.onWrite`. */
401
408
  onWrite?: WriteHookFor;
409
+ /** See `BuildSchemaConfig.defaults`. */
410
+ defaultOrderBy?: DefaultOrderByFor;
402
411
  };
403
412
  /**
404
413
  * Where a dialect's default sort places NULLs relative to non-NULL values:
@@ -915,6 +924,25 @@ type TableLimitPolicy = {
915
924
  */
916
925
  clampToMax?: boolean;
917
926
  };
927
+ /**
928
+ * One entry of a {@link TableDefaults} ordering: a direction, or a direction with the
929
+ * priority that decides where it sits among the other entries (higher first, as in the
930
+ * generated `orderBy` argument).
931
+ */
932
+ type DefaultOrderByEntry = 'asc' | 'desc' | {
933
+ direction: 'asc' | 'desc';
934
+ priority?: number;
935
+ };
936
+ /** {@link DefaultsConfig} — what one table falls back to when the request does not say. */
937
+ type TableDefaults = {
938
+ /**
939
+ * The ordering a read of this table runs with when the request passes no `orderBy`, keyed
940
+ * by column property name.
941
+ */
942
+ orderBy?: Record<string, DefaultOrderByEntry>;
943
+ };
944
+ /** {@link BuildSchemaConfig.defaults} — per-table defaults, keyed by the Drizzle schema key. */
945
+ type DefaultsConfig = Record<string, TableDefaults>;
918
946
  /** {@link BuildSchemaConfig.limits} — a global policy plus per-table overrides. */
919
947
  type LimitsConfig = TableLimitPolicy & {
920
948
  /** Per-table overrides, keyed by the table's key in the Drizzle schema. */
@@ -1213,6 +1241,38 @@ type BuildSchemaConfig = {
1213
1241
  * agree.
1214
1242
  */
1215
1243
  limits?: LimitsConfig;
1244
+ /**
1245
+ * Per-table defaults for arguments the request leaves out. Today that is `orderBy`: the
1246
+ * presentation order a table has, declared once on the server instead of repeated by every
1247
+ * client.
1248
+ *
1249
+ * ```ts
1250
+ * buildSchema(db, {
1251
+ * defaults: {
1252
+ * Todos: { orderBy: { priority: 'desc', createdAt: 'desc' } },
1253
+ * AuditLog: { orderBy: { createdAt: { direction: 'desc', priority: 10 } } },
1254
+ * },
1255
+ * });
1256
+ * ```
1257
+ *
1258
+ * - Applies to the table's list and single queries, and to every to-many relation field
1259
+ * that *targets* it — a relation is ordered by the default of the table it reads, so a
1260
+ * table presents the same way wherever it is reached from. Eagerly and lazily loaded
1261
+ * relations agree.
1262
+ * - Only a missing `orderBy` is replaced. `orderBy: {}` is a request for no ordering and
1263
+ * stays one, and any `orderBy` the client sends replaces the default outright rather than
1264
+ * merging with it.
1265
+ * - Cursor pagination is defined over the effective ordering, so a default `orderBy` is
1266
+ * what an `after`-only page is ordered by. Changing a table's default changes what its
1267
+ * existing cursors mean.
1268
+ * - Entries name column property names of that table; a direction alone is shorthand for
1269
+ * `{ direction }`. Unknown table or column names throw at build time.
1270
+ * - Aggregates and `groupBy` take their own ordering and are unaffected.
1271
+ *
1272
+ * Off by default: a table with no entry keeps returning rows in whatever order the database
1273
+ * gives them, tiebroken by primary key where an operation needs a total order.
1274
+ */
1275
+ defaults?: DefaultsConfig;
1216
1276
  /**
1217
1277
  * Row-level scoping: a predicate, derived from the GraphQL context, that every read and
1218
1278
  * write of a table is confined to. This is the multi-tenancy / ownership knob — the one
@@ -1812,4 +1872,4 @@ declare const resolveSelection: (info: GraphQLResolveInfo | ResolveTree, options
1812
1872
 
1813
1873
  declare const buildSchema: <TDbClient extends AnyDrizzleDB<any>>(db: TDbClient, config?: BuildSchemaConfig) => GeneratedData<TDbClient>;
1814
1874
 
1815
- export { type AggregateResolver, type AnyDrizzleDB, type BuildSchemaConfig, type ColumnDeprecator, type ColumnDescriber, type ColumnDocInfo, type ColumnTypeMapper, type ColumnTypeMapperInfo, type ComplexityConfig, type ContextValuesConfig, type DeleteResolver, type DeleteSingleResolver, type DrizzleExtension, type DrizzleFieldExtension, type DrizzleFieldKind, type DrizzleFieldOperation, type DrizzleTargetArg, type DrizzleTypeExtension, type EnumNameInfo, type EnumNameMapper, type ExtractRelations, type ExtractTableByName, type ExtractTableRelations, type ExtractTables, type FeatureSwitch, type GeneratedData, type GeneratedEntities, type GeneratedInputs, type GeneratedOutputs, GraphQLBigIntString, GraphQLDecimalString, type IdentifiedRows, type InsertArrResolver, type InsertResolver, type LimitsConfig, type MutationReturnlessResult, type MutationsCore, type OnWriteConfig, type QueriesCore, type RelationDescriber, type RelationResolverFactory, type ResolveSelectionOptions, type RowScope, type RowScopeFilter, type ScalarOverride, type ScalarOverridesConfig, type SchemaDocs, type SchemaExclusions, type SchemaFeatures, type ScopeConfig, type SelectResolver, type SelectSingleResolver, type SelectionOptions, type SoftDeleteColumn, type SoftDeleteConfig, type TableDescriber, type TableLimitPolicy, type TableNamedRelations, type UpdateManyArgs, type UpdateManyEntry, type UpdateManyResolver, type UpdateResolver, type UpdateSingleResolver, type UpsertArgs, type UpsertArrResolver, type UpsertConflictArgs, type UpsertResolver, type WriteHook, type WriteHookPayload, type WriteHookPositions, type WriteHooks, type WriteOperation, buildSchema, createRelationResolverFactory, defaultErrorMapper, drizzleExecutorKey, drizzleExtension, extractFilters, extractOrderBy, extractRelationJoinColumns, identifyRows, isDrizzleFieldExtension, resolveSelection, selectionToWith, singularizeMapper };
1875
+ export { type AggregateResolver, type AnyDrizzleDB, type BuildSchemaConfig, type ColumnDeprecator, type ColumnDescriber, type ColumnDocInfo, type ColumnTypeMapper, type ColumnTypeMapperInfo, type ComplexityConfig, type ContextValuesConfig, type DefaultOrderByEntry, type DefaultsConfig, type DeleteResolver, type DeleteSingleResolver, type DrizzleExtension, type DrizzleFieldExtension, type DrizzleFieldKind, type DrizzleFieldOperation, type DrizzleTargetArg, type DrizzleTypeExtension, type EnumNameInfo, type EnumNameMapper, type ExtractRelations, type ExtractTableByName, type ExtractTableRelations, type ExtractTables, type FeatureSwitch, type GeneratedData, type GeneratedEntities, type GeneratedInputs, type GeneratedOutputs, GraphQLBigIntString, GraphQLDecimalString, type IdentifiedRows, type InsertArrResolver, type InsertResolver, type LimitsConfig, type MutationReturnlessResult, type MutationsCore, type OnWriteConfig, type QueriesCore, type RelationDescriber, type RelationResolverFactory, type ResolveSelectionOptions, type RowScope, type RowScopeFilter, type ScalarOverride, type ScalarOverridesConfig, type SchemaDocs, type SchemaExclusions, type SchemaFeatures, type ScopeConfig, type SelectResolver, type SelectSingleResolver, type SelectionOptions, type SoftDeleteColumn, type SoftDeleteConfig, type TableDefaults, type TableDescriber, type TableLimitPolicy, type TableNamedRelations, type UpdateManyArgs, type UpdateManyEntry, type UpdateManyResolver, type UpdateResolver, type UpdateSingleResolver, type UpsertArgs, type UpsertArrResolver, type UpsertConflictArgs, type UpsertResolver, type WriteHook, type WriteHookPayload, type WriteHookPositions, type WriteHooks, type WriteOperation, buildSchema, createRelationResolverFactory, defaultErrorMapper, drizzleExecutorKey, drizzleExtension, extractFilters, extractOrderBy, extractRelationJoinColumns, identifyRows, isDrizzleFieldExtension, resolveSelection, selectionToWith, singularizeMapper };
package/dist/index.d.ts CHANGED
@@ -300,6 +300,13 @@ type ResolvedLimitPolicy = {
300
300
  * `buildSchema`; `undefined` for a table the caller left unbounded.
301
301
  */
302
302
  type LimitPolicyFor = (tableName: string) => ResolvedLimitPolicy | undefined;
303
+ /**
304
+ * {@link BuildSchemaConfig.defaults} resolved for one table: the `orderBy` a read falls back
305
+ * to when the request passes none, already in the shape the generated argument has.
306
+ * `undefined` means the table declares no default and keeps whatever order the database
307
+ * returns.
308
+ */
309
+ type DefaultOrderByFor = (tableName: string) => Record<string, any> | undefined;
303
310
  /**
304
311
  * Compiles an `orderBy` argument into ORDER BY expressions, highest priority first.
305
312
  *
@@ -399,6 +406,8 @@ type TablePolicies = {
399
406
  softDelete?: SoftDeleteFor;
400
407
  /** See `BuildSchemaConfig.onWrite`. */
401
408
  onWrite?: WriteHookFor;
409
+ /** See `BuildSchemaConfig.defaults`. */
410
+ defaultOrderBy?: DefaultOrderByFor;
402
411
  };
403
412
  /**
404
413
  * Where a dialect's default sort places NULLs relative to non-NULL values:
@@ -915,6 +924,25 @@ type TableLimitPolicy = {
915
924
  */
916
925
  clampToMax?: boolean;
917
926
  };
927
+ /**
928
+ * One entry of a {@link TableDefaults} ordering: a direction, or a direction with the
929
+ * priority that decides where it sits among the other entries (higher first, as in the
930
+ * generated `orderBy` argument).
931
+ */
932
+ type DefaultOrderByEntry = 'asc' | 'desc' | {
933
+ direction: 'asc' | 'desc';
934
+ priority?: number;
935
+ };
936
+ /** {@link DefaultsConfig} — what one table falls back to when the request does not say. */
937
+ type TableDefaults = {
938
+ /**
939
+ * The ordering a read of this table runs with when the request passes no `orderBy`, keyed
940
+ * by column property name.
941
+ */
942
+ orderBy?: Record<string, DefaultOrderByEntry>;
943
+ };
944
+ /** {@link BuildSchemaConfig.defaults} — per-table defaults, keyed by the Drizzle schema key. */
945
+ type DefaultsConfig = Record<string, TableDefaults>;
918
946
  /** {@link BuildSchemaConfig.limits} — a global policy plus per-table overrides. */
919
947
  type LimitsConfig = TableLimitPolicy & {
920
948
  /** Per-table overrides, keyed by the table's key in the Drizzle schema. */
@@ -1213,6 +1241,38 @@ type BuildSchemaConfig = {
1213
1241
  * agree.
1214
1242
  */
1215
1243
  limits?: LimitsConfig;
1244
+ /**
1245
+ * Per-table defaults for arguments the request leaves out. Today that is `orderBy`: the
1246
+ * presentation order a table has, declared once on the server instead of repeated by every
1247
+ * client.
1248
+ *
1249
+ * ```ts
1250
+ * buildSchema(db, {
1251
+ * defaults: {
1252
+ * Todos: { orderBy: { priority: 'desc', createdAt: 'desc' } },
1253
+ * AuditLog: { orderBy: { createdAt: { direction: 'desc', priority: 10 } } },
1254
+ * },
1255
+ * });
1256
+ * ```
1257
+ *
1258
+ * - Applies to the table's list and single queries, and to every to-many relation field
1259
+ * that *targets* it — a relation is ordered by the default of the table it reads, so a
1260
+ * table presents the same way wherever it is reached from. Eagerly and lazily loaded
1261
+ * relations agree.
1262
+ * - Only a missing `orderBy` is replaced. `orderBy: {}` is a request for no ordering and
1263
+ * stays one, and any `orderBy` the client sends replaces the default outright rather than
1264
+ * merging with it.
1265
+ * - Cursor pagination is defined over the effective ordering, so a default `orderBy` is
1266
+ * what an `after`-only page is ordered by. Changing a table's default changes what its
1267
+ * existing cursors mean.
1268
+ * - Entries name column property names of that table; a direction alone is shorthand for
1269
+ * `{ direction }`. Unknown table or column names throw at build time.
1270
+ * - Aggregates and `groupBy` take their own ordering and are unaffected.
1271
+ *
1272
+ * Off by default: a table with no entry keeps returning rows in whatever order the database
1273
+ * gives them, tiebroken by primary key where an operation needs a total order.
1274
+ */
1275
+ defaults?: DefaultsConfig;
1216
1276
  /**
1217
1277
  * Row-level scoping: a predicate, derived from the GraphQL context, that every read and
1218
1278
  * write of a table is confined to. This is the multi-tenancy / ownership knob — the one
@@ -1812,4 +1872,4 @@ declare const resolveSelection: (info: GraphQLResolveInfo | ResolveTree, options
1812
1872
 
1813
1873
  declare const buildSchema: <TDbClient extends AnyDrizzleDB<any>>(db: TDbClient, config?: BuildSchemaConfig) => GeneratedData<TDbClient>;
1814
1874
 
1815
- export { type AggregateResolver, type AnyDrizzleDB, type BuildSchemaConfig, type ColumnDeprecator, type ColumnDescriber, type ColumnDocInfo, type ColumnTypeMapper, type ColumnTypeMapperInfo, type ComplexityConfig, type ContextValuesConfig, type DeleteResolver, type DeleteSingleResolver, type DrizzleExtension, type DrizzleFieldExtension, type DrizzleFieldKind, type DrizzleFieldOperation, type DrizzleTargetArg, type DrizzleTypeExtension, type EnumNameInfo, type EnumNameMapper, type ExtractRelations, type ExtractTableByName, type ExtractTableRelations, type ExtractTables, type FeatureSwitch, type GeneratedData, type GeneratedEntities, type GeneratedInputs, type GeneratedOutputs, GraphQLBigIntString, GraphQLDecimalString, type IdentifiedRows, type InsertArrResolver, type InsertResolver, type LimitsConfig, type MutationReturnlessResult, type MutationsCore, type OnWriteConfig, type QueriesCore, type RelationDescriber, type RelationResolverFactory, type ResolveSelectionOptions, type RowScope, type RowScopeFilter, type ScalarOverride, type ScalarOverridesConfig, type SchemaDocs, type SchemaExclusions, type SchemaFeatures, type ScopeConfig, type SelectResolver, type SelectSingleResolver, type SelectionOptions, type SoftDeleteColumn, type SoftDeleteConfig, type TableDescriber, type TableLimitPolicy, type TableNamedRelations, type UpdateManyArgs, type UpdateManyEntry, type UpdateManyResolver, type UpdateResolver, type UpdateSingleResolver, type UpsertArgs, type UpsertArrResolver, type UpsertConflictArgs, type UpsertResolver, type WriteHook, type WriteHookPayload, type WriteHookPositions, type WriteHooks, type WriteOperation, buildSchema, createRelationResolverFactory, defaultErrorMapper, drizzleExecutorKey, drizzleExtension, extractFilters, extractOrderBy, extractRelationJoinColumns, identifyRows, isDrizzleFieldExtension, resolveSelection, selectionToWith, singularizeMapper };
1875
+ export { type AggregateResolver, type AnyDrizzleDB, type BuildSchemaConfig, type ColumnDeprecator, type ColumnDescriber, type ColumnDocInfo, type ColumnTypeMapper, type ColumnTypeMapperInfo, type ComplexityConfig, type ContextValuesConfig, type DefaultOrderByEntry, type DefaultsConfig, type DeleteResolver, type DeleteSingleResolver, type DrizzleExtension, type DrizzleFieldExtension, type DrizzleFieldKind, type DrizzleFieldOperation, type DrizzleTargetArg, type DrizzleTypeExtension, type EnumNameInfo, type EnumNameMapper, type ExtractRelations, type ExtractTableByName, type ExtractTableRelations, type ExtractTables, type FeatureSwitch, type GeneratedData, type GeneratedEntities, type GeneratedInputs, type GeneratedOutputs, GraphQLBigIntString, GraphQLDecimalString, type IdentifiedRows, type InsertArrResolver, type InsertResolver, type LimitsConfig, type MutationReturnlessResult, type MutationsCore, type OnWriteConfig, type QueriesCore, type RelationDescriber, type RelationResolverFactory, type ResolveSelectionOptions, type RowScope, type RowScopeFilter, type ScalarOverride, type ScalarOverridesConfig, type SchemaDocs, type SchemaExclusions, type SchemaFeatures, type ScopeConfig, type SelectResolver, type SelectSingleResolver, type SelectionOptions, type SoftDeleteColumn, type SoftDeleteConfig, type TableDefaults, type TableDescriber, type TableLimitPolicy, type TableNamedRelations, type UpdateManyArgs, type UpdateManyEntry, type UpdateManyResolver, type UpdateResolver, type UpdateSingleResolver, type UpsertArgs, type UpsertArrResolver, type UpsertConflictArgs, type UpsertResolver, type WriteHook, type WriteHookPayload, type WriteHookPositions, type WriteHooks, type WriteOperation, buildSchema, createRelationResolverFactory, defaultErrorMapper, drizzleExecutorKey, drizzleExtension, extractFilters, extractOrderBy, extractRelationJoinColumns, identifyRows, isDrizzleFieldExtension, resolveSelection, selectionToWith, singularizeMapper };
package/dist/index.js CHANGED
@@ -1195,14 +1195,8 @@ var createRelationResolverFactory = (db, tables, nullOrdering, filterCtx, limits
1195
1195
  if (localValue == null) {
1196
1196
  return isOne ? null : [];
1197
1197
  }
1198
- const {
1199
- where: whereArg,
1200
- orderBy: orderByArg,
1201
- limit: requestedLimit,
1202
- offset,
1203
- after,
1204
- deleted
1205
- } = args ?? {};
1198
+ const { where: whereArg, limit: requestedLimit, offset, after, deleted } = args ?? {};
1199
+ const orderByArg = isOne ? args?.orderBy : withDefaultOrderBy(args ?? {}, targetTableName, policies?.defaultOrderBy).orderBy;
1206
1200
  const limit = applyLimitPolicy(requestedLimit, limitPolicy, `${tableName}.${relationName}`);
1207
1201
  const distinct = (args ?? {}).distinct?.length ? (args ?? {}).distinct : void 0;
1208
1202
  const cursorSelected = !isOne && !!info && selectsCursorField(info, targetTable);
@@ -1334,6 +1328,13 @@ var inputFieldDocs = (docs, column, tableName, columnName, fieldType) => {
1334
1328
  }
1335
1329
  return resolved;
1336
1330
  };
1331
+ var withDefaultOrderBy = (args, tableName, defaults) => {
1332
+ if (!defaults || args?.orderBy != null) {
1333
+ return args;
1334
+ }
1335
+ const fallback = defaults(tableName);
1336
+ return fallback ? { ...args, orderBy: fallback } : args;
1337
+ };
1337
1338
  var applyLimitPolicy = (limit, policy, fieldName) => {
1338
1339
  if (!policy) {
1339
1340
  return limit ?? void 0;
@@ -2800,11 +2801,12 @@ var withScope = (scope, tableName, table, condition, mode) => {
2800
2801
  const predicate = scope?.on(tableName, table, mode);
2801
2802
  return predicate ? and(condition, predicate) : condition;
2802
2803
  };
2803
- var bindPolicies = (policies, filterCtx) => policies?.scope || policies?.contextValues || policies?.softDelete || policies?.onWrite ? {
2804
+ var bindPolicies = (policies, filterCtx) => policies?.scope || policies?.contextValues || policies?.softDelete || policies?.onWrite || policies?.defaultOrderBy ? {
2804
2805
  scope: policies.scope || policies.softDelete ? (context) => resolveScope(policies, context, filterCtx) : void 0,
2805
2806
  contextValues: policies.contextValues,
2806
2807
  softDelete: policies.softDelete,
2807
- onWrite: policies.onWrite
2808
+ onWrite: policies.onWrite,
2809
+ defaultOrderBy: policies.defaultOrderBy
2808
2810
  } : void 0;
2809
2811
  var applyContextValues = (values, hooks, context) => {
2810
2812
  if (!hooks) {
@@ -2833,7 +2835,7 @@ var stripContextValues = (values, hooks) => {
2833
2835
  }
2834
2836
  return values;
2835
2837
  };
2836
- var extractRelationsParamsInner = (relationMap, tables, tableName, typeName, originField, typeNameMapper, _isInitial = false, filterCtx, limits, scope) => {
2838
+ var extractRelationsParamsInner = (relationMap, tables, tableName, typeName, originField, typeNameMapper, _isInitial = false, filterCtx, limits, scope, defaultOrderBy) => {
2837
2839
  const relationsForTable = relationMap[tableName];
2838
2840
  if (!relationsForTable) {
2839
2841
  return void 0;
@@ -2875,7 +2877,7 @@ var extractRelationsParamsInner = (relationMap, tables, tableName, typeName, ori
2875
2877
  const thisRecord = {};
2876
2878
  thisRecord.columns = columns;
2877
2879
  const relationField = Object.values(baseField).find((e) => e.name === relName);
2878
- const relationArgs = relationField?.args;
2880
+ const relationArgs = is3(relEntry.relation, One2) ? relationField?.args : relationField && withDefaultOrderBy(relationField.args ?? {}, targetTableName, defaultOrderBy);
2879
2881
  const offset = relationArgs?.offset ?? void 0;
2880
2882
  const limit = is3(relEntry.relation, One2) ? relationArgs?.limit ?? void 0 : applyLimitPolicy(relationArgs?.limit, limits?.(targetTableName), `${tableName}.${relName}`);
2881
2883
  const relWhere = relationArgs?.where;
@@ -2904,14 +2906,15 @@ var extractRelationsParamsInner = (relationMap, tables, tableName, typeName, ori
2904
2906
  false,
2905
2907
  filterCtx,
2906
2908
  limits,
2907
- scope
2909
+ scope,
2910
+ defaultOrderBy
2908
2911
  ) : void 0;
2909
2912
  thisRecord.with = relWith;
2910
2913
  args[relName] = thisRecord;
2911
2914
  }
2912
2915
  return args;
2913
2916
  };
2914
- var extractRelationsParams = (relationMap, tables, tableName, info, typeName, typeNameMapper, filterCtx, limits, scope) => {
2917
+ var extractRelationsParams = (relationMap, tables, tableName, info, typeName, typeNameMapper, filterCtx, limits, scope, defaultOrderBy) => {
2915
2918
  if (!info) {
2916
2919
  return void 0;
2917
2920
  }
@@ -2925,7 +2928,8 @@ var extractRelationsParams = (relationMap, tables, tableName, info, typeName, ty
2925
2928
  true,
2926
2929
  filterCtx,
2927
2930
  limits,
2928
- scope
2931
+ scope,
2932
+ defaultOrderBy
2929
2933
  );
2930
2934
  };
2931
2935
  var pruneNonEagerRelations = (relationMap, shouldEagerLoad) => {
@@ -3336,7 +3340,8 @@ var prepareMutationRelationColumns = (params) => {
3336
3340
  typeNameMapper,
3337
3341
  void 0,
3338
3342
  params.limits,
3339
- params.scope
3343
+ params.scope,
3344
+ params.defaultOrderBy
3340
3345
  ) : void 0;
3341
3346
  const hasRelations = !!(withParams && Object.keys(withParams).length);
3342
3347
  const baseColumns = extractSelectedColumnsFromTreeSQLFormat(parsedInfo.fieldsByTypeName[typeName], table, {
@@ -3678,7 +3683,8 @@ var runRelationalSelect = async (opts) => {
3678
3683
  typeNameMapper,
3679
3684
  filterCtx,
3680
3685
  opts.limits,
3681
- scope
3686
+ scope,
3687
+ opts.defaultOrderBy
3682
3688
  ) : void 0
3683
3689
  };
3684
3690
  if (single) {
@@ -4316,7 +4322,8 @@ var generateSelectArray = (db, tableName, tables, relationMap, orderArgs, filter
4316
4322
  );
4317
4323
  return {
4318
4324
  name: fieldName,
4319
- resolver: async (_source, args, context, info) => {
4325
+ resolver: async (_source, rawArgs, context, info) => {
4326
+ const args = withDefaultOrderBy(rawArgs, tableName, policies?.defaultOrderBy);
4320
4327
  try {
4321
4328
  const parsedInfo = parseResolveInfo2(info, { deep: true });
4322
4329
  const { executor, queryBase: requestQueryBase } = resolveQueryExecutor(db, context, tableName, queryBase);
@@ -4334,6 +4341,7 @@ var generateSelectArray = (db, tableName, tables, relationMap, orderArgs, filter
4334
4341
  single: false,
4335
4342
  filterCtx,
4336
4343
  limits,
4344
+ defaultOrderBy: policies?.defaultOrderBy,
4337
4345
  scope: policies?.scope?.(context),
4338
4346
  pkNames,
4339
4347
  db: executor,
@@ -4359,7 +4367,8 @@ var generateSelectSingle = (db, tableName, tables, relationMap, orderArgs, filte
4359
4367
  const pkNames = mysqlPrimaryKeyPropNames(table);
4360
4368
  return {
4361
4369
  name: fieldName,
4362
- resolver: async (_source, args, context, info) => {
4370
+ resolver: async (_source, rawArgs, context, info) => {
4371
+ const args = withDefaultOrderBy(rawArgs, tableName, policies?.defaultOrderBy);
4363
4372
  try {
4364
4373
  const parsedInfo = parseResolveInfo2(info, { deep: true });
4365
4374
  const { executor, queryBase: requestQueryBase } = resolveQueryExecutor(db, context, tableName, queryBase);
@@ -4376,6 +4385,7 @@ var generateSelectSingle = (db, tableName, tables, relationMap, orderArgs, filte
4376
4385
  single: true,
4377
4386
  filterCtx,
4378
4387
  limits,
4388
+ defaultOrderBy: policies?.defaultOrderBy,
4379
4389
  scope: policies?.scope?.(context),
4380
4390
  pkNames,
4381
4391
  db: executor
@@ -5795,7 +5805,8 @@ var generateSelectArray2 = (db, tableName, tables, relationMap, orderArgs, filte
5795
5805
  );
5796
5806
  return {
5797
5807
  name: fieldName,
5798
- resolver: async (_source, args, context, info) => {
5808
+ resolver: async (_source, rawArgs, context, info) => {
5809
+ const args = withDefaultOrderBy(rawArgs, tableName, policies?.defaultOrderBy);
5799
5810
  try {
5800
5811
  const parsedInfo = parseResolveInfo3(info, { deep: true });
5801
5812
  const { executor, queryBase: requestQueryBase } = resolveQueryExecutor(db, context, tableName, queryBase);
@@ -5816,6 +5827,7 @@ var generateSelectArray2 = (db, tableName, tables, relationMap, orderArgs, filte
5816
5827
  single: false,
5817
5828
  filterCtx,
5818
5829
  limits,
5830
+ defaultOrderBy: policies?.defaultOrderBy,
5819
5831
  pkNames,
5820
5832
  db: executor,
5821
5833
  scope,
@@ -5925,7 +5937,8 @@ var generateSelectSingle2 = (db, tableName, tables, relationMap, orderArgs, filt
5925
5937
  const pkNames = pgPrimaryKeyPropNames(table);
5926
5938
  return {
5927
5939
  name: fieldName,
5928
- resolver: async (_source, args, context, info) => {
5940
+ resolver: async (_source, rawArgs, context, info) => {
5941
+ const args = withDefaultOrderBy(rawArgs, tableName, policies?.defaultOrderBy);
5929
5942
  try {
5930
5943
  const parsedInfo = parseResolveInfo3(info, { deep: true });
5931
5944
  const { executor, queryBase: requestQueryBase } = resolveQueryExecutor(db, context, tableName, queryBase);
@@ -5944,6 +5957,7 @@ var generateSelectSingle2 = (db, tableName, tables, relationMap, orderArgs, filt
5944
5957
  single: true,
5945
5958
  filterCtx,
5946
5959
  limits,
5960
+ defaultOrderBy: policies?.defaultOrderBy,
5947
5961
  pkNames,
5948
5962
  db: executor,
5949
5963
  scope
@@ -6037,7 +6051,8 @@ var generateInsertArray2 = (db, tableName, table, tables, relationMap, baseType,
6037
6051
  pkNames,
6038
6052
  parsedInfo,
6039
6053
  limits,
6040
- scope
6054
+ scope,
6055
+ defaultOrderBy: policies?.defaultOrderBy
6041
6056
  });
6042
6057
  const returning = nestedEntries ? nested.withJoinColumns(tableName, mergedOps(nestedEntries), { ...columns }, table) : columns;
6043
6058
  const runInsert = async (target, values) => {
@@ -6127,7 +6142,8 @@ var generateInsertSingle2 = (db, tableName, table, tables, relationMap, baseType
6127
6142
  pkNames,
6128
6143
  parsedInfo,
6129
6144
  limits,
6130
- scope
6145
+ scope,
6146
+ defaultOrderBy: policies?.defaultOrderBy
6131
6147
  });
6132
6148
  const returning = nestedEntry ? nested.withJoinColumns(tableName, nestedEntry.ops, { ...columns }, table) : columns;
6133
6149
  const runInsert = async (target, values) => {
@@ -6229,7 +6245,8 @@ var generateUpsert2 = (db, tableName, table, tables, relationMap, baseType, onCo
6229
6245
  pkNames,
6230
6246
  parsedInfo,
6231
6247
  limits,
6232
- scope
6248
+ scope,
6249
+ defaultOrderBy: policies?.defaultOrderBy
6233
6250
  });
6234
6251
  const returning = nestedEntries ? nested.withJoinColumns(tableName, mergedOps(nestedEntries), { ...columns }, table) : columns;
6235
6252
  const runUpsert = async (target, values) => {
@@ -6327,7 +6344,8 @@ var generateUpdate2 = (db, tableName, table, tables, relationMap, setArgs, filte
6327
6344
  pkNames,
6328
6345
  parsedInfo,
6329
6346
  limits,
6330
- scope
6347
+ scope,
6348
+ defaultOrderBy: policies?.defaultOrderBy
6331
6349
  });
6332
6350
  const entry = nested?.enabled(tableName) ? nested.split(tableName, set) : void 0;
6333
6351
  const nestedOps = entry && nested.hasOps(entry.ops) ? entry.ops : void 0;
@@ -6441,7 +6459,8 @@ var generateUpdateMany2 = (db, tableName, table, tables, relationMap, updateMany
6441
6459
  pkNames,
6442
6460
  parsedInfo,
6443
6461
  limits,
6444
- scope
6462
+ scope,
6463
+ defaultOrderBy: policies?.defaultOrderBy
6445
6464
  });
6446
6465
  const entries = updates.map(({ where, set }) => {
6447
6466
  const split = nested?.enabled(tableName) ? nested.split(tableName, set) : void 0;
@@ -7250,7 +7269,8 @@ var generateSelectArray3 = (db, tableName, tables, relationMap, orderArgs, filte
7250
7269
  );
7251
7270
  return {
7252
7271
  name: fieldName,
7253
- resolver: async (_source, args, context, info) => {
7272
+ resolver: async (_source, rawArgs, context, info) => {
7273
+ const args = withDefaultOrderBy(rawArgs, tableName, policies?.defaultOrderBy);
7254
7274
  try {
7255
7275
  const parsedInfo = parseResolveInfo4(info, { deep: true });
7256
7276
  const { executor, queryBase: requestQueryBase } = resolveQueryExecutor(db, context, tableName, queryBase);
@@ -7268,6 +7288,7 @@ var generateSelectArray3 = (db, tableName, tables, relationMap, orderArgs, filte
7268
7288
  single: false,
7269
7289
  filterCtx,
7270
7290
  limits,
7291
+ defaultOrderBy: policies?.defaultOrderBy,
7271
7292
  pkNames,
7272
7293
  db: executor,
7273
7294
  scope: policies?.scope?.(context),
@@ -7293,7 +7314,8 @@ var generateSelectSingle3 = (db, tableName, tables, relationMap, orderArgs, filt
7293
7314
  const pkNames = sqlitePrimaryKeyPropNames(table);
7294
7315
  return {
7295
7316
  name: fieldName,
7296
- resolver: async (_source, args, context, info) => {
7317
+ resolver: async (_source, rawArgs, context, info) => {
7318
+ const args = withDefaultOrderBy(rawArgs, tableName, policies?.defaultOrderBy);
7297
7319
  try {
7298
7320
  const parsedInfo = parseResolveInfo4(info, { deep: true });
7299
7321
  const { executor, queryBase: requestQueryBase } = resolveQueryExecutor(db, context, tableName, queryBase);
@@ -7310,6 +7332,7 @@ var generateSelectSingle3 = (db, tableName, tables, relationMap, orderArgs, filt
7310
7332
  single: true,
7311
7333
  filterCtx,
7312
7334
  limits,
7335
+ defaultOrderBy: policies?.defaultOrderBy,
7313
7336
  pkNames,
7314
7337
  db: executor,
7315
7338
  scope: policies?.scope?.(context)
@@ -7374,7 +7397,8 @@ var generateInsertArray3 = (db, tableName, table, tables, relationMap, baseType,
7374
7397
  pkNames,
7375
7398
  parsedInfo,
7376
7399
  limits,
7377
- scope
7400
+ scope,
7401
+ defaultOrderBy: policies?.defaultOrderBy
7378
7402
  });
7379
7403
  const returning = nestedEntries ? nested.withJoinColumns(tableName, mergedOps(nestedEntries), { ...columns }, table) : columns;
7380
7404
  const runInsert = async (target, values) => {
@@ -7464,7 +7488,8 @@ var generateInsertSingle3 = (db, tableName, table, tables, relationMap, baseType
7464
7488
  pkNames,
7465
7489
  parsedInfo,
7466
7490
  limits,
7467
- scope
7491
+ scope,
7492
+ defaultOrderBy: policies?.defaultOrderBy
7468
7493
  });
7469
7494
  const returning = nestedEntry ? nested.withJoinColumns(tableName, nestedEntry.ops, { ...columns }, table) : columns;
7470
7495
  const runInsert = async (target, values) => {
@@ -7566,7 +7591,8 @@ var generateUpsert3 = (db, tableName, table, tables, relationMap, baseType, onCo
7566
7591
  pkNames,
7567
7592
  parsedInfo,
7568
7593
  limits,
7569
- scope
7594
+ scope,
7595
+ defaultOrderBy: policies?.defaultOrderBy
7570
7596
  });
7571
7597
  const returning = nestedEntries ? nested.withJoinColumns(tableName, mergedOps(nestedEntries), { ...columns }, table) : columns;
7572
7598
  const runUpsert = async (target, values) => {
@@ -7664,7 +7690,8 @@ var generateUpdate3 = (db, tableName, table, tables, relationMap, setArgs, filte
7664
7690
  pkNames,
7665
7691
  parsedInfo,
7666
7692
  limits,
7667
- scope
7693
+ scope,
7694
+ defaultOrderBy: policies?.defaultOrderBy
7668
7695
  });
7669
7696
  const entry = nested?.enabled(tableName) ? nested.split(tableName, set) : void 0;
7670
7697
  const nestedOps = entry && nested.hasOps(entry.ops) ? entry.ops : void 0;
@@ -7778,7 +7805,8 @@ var generateUpdateMany3 = (db, tableName, table, tables, relationMap, updateMany
7778
7805
  pkNames,
7779
7806
  parsedInfo,
7780
7807
  limits,
7781
- scope
7808
+ scope,
7809
+ defaultOrderBy: policies?.defaultOrderBy
7782
7810
  });
7783
7811
  const entries = updates.map(({ where, set }) => {
7784
7812
  const split = nested?.enabled(tableName) ? nested.split(tableName, set) : void 0;
@@ -8793,6 +8821,46 @@ var buildSchema = (db, config) => {
8793
8821
  limitPolicyCache.set(tableName, resolved);
8794
8822
  return resolved;
8795
8823
  } : void 0;
8824
+ const defaultsConfig = config?.defaults;
8825
+ const defaultOrderByByTable = /* @__PURE__ */ new Map();
8826
+ if (defaultsConfig) {
8827
+ const defaultsTableNames = new Set(tableKeys);
8828
+ for (const [tableName, tableDefaults] of Object.entries(defaultsConfig)) {
8829
+ if (!defaultsTableNames.has(tableName)) {
8830
+ throw new Error(
8831
+ `Drizzle-GraphQL Error: config.defaults names '${tableName}', which is not a table in the Drizzle schema.`
8832
+ );
8833
+ }
8834
+ const orderBy = tableDefaults?.orderBy;
8835
+ if (!orderBy || !Object.keys(orderBy).length) {
8836
+ continue;
8837
+ }
8838
+ const columns = getColumns6(schema[tableName]);
8839
+ const normalized = {};
8840
+ for (const [columnName, entry] of Object.entries(orderBy)) {
8841
+ if (!columns[columnName]) {
8842
+ throw new Error(
8843
+ `Drizzle-GraphQL Error: config.defaults.${tableName}.orderBy names '${columnName}', which is not a column of '${tableName}'.`
8844
+ );
8845
+ }
8846
+ const direction = typeof entry === "string" ? entry : entry?.direction;
8847
+ if (direction !== "asc" && direction !== "desc") {
8848
+ throw new Error(
8849
+ `Drizzle-GraphQL Error: config.defaults.${tableName}.orderBy.${columnName} must be 'asc', 'desc', or { direction, priority? }.`
8850
+ );
8851
+ }
8852
+ const priority = typeof entry === "string" ? void 0 : entry?.priority;
8853
+ if (priority !== void 0 && !Number.isInteger(priority)) {
8854
+ throw new Error(
8855
+ `Drizzle-GraphQL Error: config.defaults.${tableName}.orderBy.${columnName}.priority must be an integer.`
8856
+ );
8857
+ }
8858
+ normalized[columnName] = priority === void 0 ? { direction } : { direction, priority };
8859
+ }
8860
+ defaultOrderByByTable.set(tableName, normalized);
8861
+ }
8862
+ }
8863
+ const defaultOrderBy = defaultOrderByByTable.size ? (tableName) => defaultOrderByByTable.get(tableName) : void 0;
8796
8864
  const scopeConfig = config?.scope;
8797
8865
  const contextValuesConfig = config?.contextValues;
8798
8866
  if (scopeConfig || contextValuesConfig) {
@@ -8873,11 +8941,12 @@ var buildSchema = (db, config) => {
8873
8941
  }
8874
8942
  }
8875
8943
  const onWrite = globalWriteHooks || writeHooks.size ? (tableName) => globalWriteHooks ?? writeHooks.get(tableName) : void 0;
8876
- const policies = scopeConfig || contextValuesConfig || softDeleteInfos.size || onWrite ? {
8944
+ const policies = scopeConfig || contextValuesConfig || softDeleteInfos.size || onWrite || defaultOrderBy ? {
8877
8945
  scope: scopeConfig ? (tableName) => scopeConfig[tableName] : void 0,
8878
8946
  contextValues: contextValuesConfig ? (tableName) => contextValuesConfig[tableName] : void 0,
8879
8947
  softDelete: softDeleteInfos.size ? (tableName) => softDeleteInfos.get(tableName) : void 0,
8880
- onWrite
8948
+ onWrite,
8949
+ defaultOrderBy
8881
8950
  } : void 0;
8882
8951
  const exclude = config?.exclude;
8883
8952
  if (exclude) {