@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/README.md CHANGED
@@ -945,6 +945,56 @@ supplies no `orderBy`:
945
945
  An explicit `orderBy` always takes precedence, composite primary keys are ordered by every
946
946
  key column, and an unpaginated list query is left unordered so no sort is paid for.
947
947
 
948
+ ## Default ordering
949
+
950
+ A table usually has one ordering that is right nearly every time it is read — newest first,
951
+ priority first, name alphabetical. `defaults` names that ordering once, and every query that
952
+ does not ask for its own gets it:
953
+
954
+ ```ts
955
+ buildSchema(db, {
956
+ defaults: {
957
+ Todos: { orderBy: { priority: 'desc', createdAt: 'desc' } },
958
+ Users: { orderBy: { name: 'asc' } },
959
+ },
960
+ });
961
+ ```
962
+
963
+ ```graphql
964
+ # ordered by priority desc, then createdAt desc — nothing in the query says so
965
+ { todos { id title } }
966
+ ```
967
+
968
+ Keys are the table's key in your Drizzle schema and the column's property name, so a typo in
969
+ either fails at `buildSchema` time rather than silently doing nothing. Each column takes
970
+ `'asc'`, `'desc'`, or a `{ direction, priority? }` object mirroring the `orderBy` argument.
971
+ Columns sort highest `priority` first, and the shorthand leaves it unset, so the shorthand
972
+ falls back to the order the keys are written in — the object form is there for when you would
973
+ rather state the precedence than depend on that:
974
+
975
+ ```ts
976
+ defaults: {
977
+ Todos: { orderBy: { createdAt: { direction: 'desc', priority: 1 }, priority: { direction: 'desc', priority: 2 } } },
978
+ }
979
+ ```
980
+
981
+ It applies to list queries, `<tableName>Single` queries, and to-many relation fields on both
982
+ the eager and the lazy relation paths — a relation takes the default of the table it *reads*,
983
+ not its parent's. To-one relation fields are a single row and take no ordering.
984
+
985
+ Two details worth stating plainly:
986
+
987
+ - **Any `orderBy` in the request wins outright.** The default is a fallback for a missing
988
+ argument, not a base that client ordering is appended to. To ask for *no* ordering, pass
989
+ `orderBy: {}` — an empty object is still an argument, so it suppresses the default.
990
+ - **A default ordering makes an unpaginated list query pay for a sort.** That is the point,
991
+ but it is a cost a table with no `defaults` entry does not pay; a build with no `defaults`
992
+ behaves exactly as before.
993
+
994
+ Cursor pagination composes with it: a default-ordered page is ordered by those columns plus
995
+ the primary key tiebreak, and its `cursor` values encode that same total order, so paging works
996
+ without the client restating the ordering.
997
+
948
998
  ## Cursor pagination
949
999
 
950
1000
  `OFFSET` pagination degrades linearly and shifts under concurrent writes. List queries also
package/dist/README.md CHANGED
@@ -945,6 +945,56 @@ supplies no `orderBy`:
945
945
  An explicit `orderBy` always takes precedence, composite primary keys are ordered by every
946
946
  key column, and an unpaginated list query is left unordered so no sort is paid for.
947
947
 
948
+ ## Default ordering
949
+
950
+ A table usually has one ordering that is right nearly every time it is read — newest first,
951
+ priority first, name alphabetical. `defaults` names that ordering once, and every query that
952
+ does not ask for its own gets it:
953
+
954
+ ```ts
955
+ buildSchema(db, {
956
+ defaults: {
957
+ Todos: { orderBy: { priority: 'desc', createdAt: 'desc' } },
958
+ Users: { orderBy: { name: 'asc' } },
959
+ },
960
+ });
961
+ ```
962
+
963
+ ```graphql
964
+ # ordered by priority desc, then createdAt desc — nothing in the query says so
965
+ { todos { id title } }
966
+ ```
967
+
968
+ Keys are the table's key in your Drizzle schema and the column's property name, so a typo in
969
+ either fails at `buildSchema` time rather than silently doing nothing. Each column takes
970
+ `'asc'`, `'desc'`, or a `{ direction, priority? }` object mirroring the `orderBy` argument.
971
+ Columns sort highest `priority` first, and the shorthand leaves it unset, so the shorthand
972
+ falls back to the order the keys are written in — the object form is there for when you would
973
+ rather state the precedence than depend on that:
974
+
975
+ ```ts
976
+ defaults: {
977
+ Todos: { orderBy: { createdAt: { direction: 'desc', priority: 1 }, priority: { direction: 'desc', priority: 2 } } },
978
+ }
979
+ ```
980
+
981
+ It applies to list queries, `<tableName>Single` queries, and to-many relation fields on both
982
+ the eager and the lazy relation paths — a relation takes the default of the table it *reads*,
983
+ not its parent's. To-one relation fields are a single row and take no ordering.
984
+
985
+ Two details worth stating plainly:
986
+
987
+ - **Any `orderBy` in the request wins outright.** The default is a fallback for a missing
988
+ argument, not a base that client ordering is appended to. To ask for *no* ordering, pass
989
+ `orderBy: {}` — an empty object is still an argument, so it suppresses the default.
990
+ - **A default ordering makes an unpaginated list query pay for a sort.** That is the point,
991
+ but it is a cost a table with no `defaults` entry does not pay; a build with no `defaults`
992
+ behaves exactly as before.
993
+
994
+ Cursor pagination composes with it: a default-ordered page is ordered by those columns plus
995
+ the primary key tiebreak, and its `cursor` values encode that same total order, so paging works
996
+ without the client restating the ordering.
997
+
948
998
  ## Cursor pagination
949
999
 
950
1000
  `OFFSET` pagination degrades linearly and shifts under concurrent writes. List queries also
package/dist/index.cjs CHANGED
@@ -1184,14 +1184,8 @@ var createRelationResolverFactory = (db, tables, nullOrdering, filterCtx, limits
1184
1184
  if (localValue == null) {
1185
1185
  return isOne ? null : [];
1186
1186
  }
1187
- const {
1188
- where: whereArg,
1189
- orderBy: orderByArg,
1190
- limit: requestedLimit,
1191
- offset,
1192
- after,
1193
- deleted
1194
- } = args ?? {};
1187
+ const { where: whereArg, limit: requestedLimit, offset, after, deleted } = args ?? {};
1188
+ const orderByArg = isOne ? args?.orderBy : withDefaultOrderBy(args ?? {}, targetTableName, policies?.defaultOrderBy).orderBy;
1195
1189
  const limit = applyLimitPolicy(requestedLimit, limitPolicy, `${tableName}.${relationName}`);
1196
1190
  const distinct = (args ?? {}).distinct?.length ? (args ?? {}).distinct : void 0;
1197
1191
  const cursorSelected = !isOne && !!info && selectsCursorField(info, targetTable);
@@ -1323,6 +1317,13 @@ var inputFieldDocs = (docs, column, tableName, columnName, fieldType) => {
1323
1317
  }
1324
1318
  return resolved;
1325
1319
  };
1320
+ var withDefaultOrderBy = (args, tableName, defaults) => {
1321
+ if (!defaults || args?.orderBy != null) {
1322
+ return args;
1323
+ }
1324
+ const fallback = defaults(tableName);
1325
+ return fallback ? { ...args, orderBy: fallback } : args;
1326
+ };
1326
1327
  var applyLimitPolicy = (limit, policy, fieldName) => {
1327
1328
  if (!policy) {
1328
1329
  return limit ?? void 0;
@@ -2789,11 +2790,12 @@ var withScope = (scope, tableName, table, condition, mode) => {
2789
2790
  const predicate = scope?.on(tableName, table, mode);
2790
2791
  return predicate ? (0, import_drizzle_orm4.and)(condition, predicate) : condition;
2791
2792
  };
2792
- var bindPolicies = (policies, filterCtx) => policies?.scope || policies?.contextValues || policies?.softDelete || policies?.onWrite ? {
2793
+ var bindPolicies = (policies, filterCtx) => policies?.scope || policies?.contextValues || policies?.softDelete || policies?.onWrite || policies?.defaultOrderBy ? {
2793
2794
  scope: policies.scope || policies.softDelete ? (context) => resolveScope(policies, context, filterCtx) : void 0,
2794
2795
  contextValues: policies.contextValues,
2795
2796
  softDelete: policies.softDelete,
2796
- onWrite: policies.onWrite
2797
+ onWrite: policies.onWrite,
2798
+ defaultOrderBy: policies.defaultOrderBy
2797
2799
  } : void 0;
2798
2800
  var applyContextValues = (values, hooks, context) => {
2799
2801
  if (!hooks) {
@@ -2822,7 +2824,7 @@ var stripContextValues = (values, hooks) => {
2822
2824
  }
2823
2825
  return values;
2824
2826
  };
2825
- var extractRelationsParamsInner = (relationMap, tables, tableName, typeName, originField, typeNameMapper, _isInitial = false, filterCtx, limits, scope) => {
2827
+ var extractRelationsParamsInner = (relationMap, tables, tableName, typeName, originField, typeNameMapper, _isInitial = false, filterCtx, limits, scope, defaultOrderBy) => {
2826
2828
  const relationsForTable = relationMap[tableName];
2827
2829
  if (!relationsForTable) {
2828
2830
  return void 0;
@@ -2864,7 +2866,7 @@ var extractRelationsParamsInner = (relationMap, tables, tableName, typeName, ori
2864
2866
  const thisRecord = {};
2865
2867
  thisRecord.columns = columns;
2866
2868
  const relationField = Object.values(baseField).find((e) => e.name === relName);
2867
- const relationArgs = relationField?.args;
2869
+ const relationArgs = (0, import_drizzle_orm4.is)(relEntry.relation, import_drizzle_orm4.One) ? relationField?.args : relationField && withDefaultOrderBy(relationField.args ?? {}, targetTableName, defaultOrderBy);
2868
2870
  const offset = relationArgs?.offset ?? void 0;
2869
2871
  const limit = (0, import_drizzle_orm4.is)(relEntry.relation, import_drizzle_orm4.One) ? relationArgs?.limit ?? void 0 : applyLimitPolicy(relationArgs?.limit, limits?.(targetTableName), `${tableName}.${relName}`);
2870
2872
  const relWhere = relationArgs?.where;
@@ -2893,14 +2895,15 @@ var extractRelationsParamsInner = (relationMap, tables, tableName, typeName, ori
2893
2895
  false,
2894
2896
  filterCtx,
2895
2897
  limits,
2896
- scope
2898
+ scope,
2899
+ defaultOrderBy
2897
2900
  ) : void 0;
2898
2901
  thisRecord.with = relWith;
2899
2902
  args[relName] = thisRecord;
2900
2903
  }
2901
2904
  return args;
2902
2905
  };
2903
- var extractRelationsParams = (relationMap, tables, tableName, info, typeName, typeNameMapper, filterCtx, limits, scope) => {
2906
+ var extractRelationsParams = (relationMap, tables, tableName, info, typeName, typeNameMapper, filterCtx, limits, scope, defaultOrderBy) => {
2904
2907
  if (!info) {
2905
2908
  return void 0;
2906
2909
  }
@@ -2914,7 +2917,8 @@ var extractRelationsParams = (relationMap, tables, tableName, info, typeName, ty
2914
2917
  true,
2915
2918
  filterCtx,
2916
2919
  limits,
2917
- scope
2920
+ scope,
2921
+ defaultOrderBy
2918
2922
  );
2919
2923
  };
2920
2924
  var pruneNonEagerRelations = (relationMap, shouldEagerLoad) => {
@@ -3325,7 +3329,8 @@ var prepareMutationRelationColumns = (params) => {
3325
3329
  typeNameMapper,
3326
3330
  void 0,
3327
3331
  params.limits,
3328
- params.scope
3332
+ params.scope,
3333
+ params.defaultOrderBy
3329
3334
  ) : void 0;
3330
3335
  const hasRelations = !!(withParams && Object.keys(withParams).length);
3331
3336
  const baseColumns = extractSelectedColumnsFromTreeSQLFormat(parsedInfo.fieldsByTypeName[typeName], table, {
@@ -3667,7 +3672,8 @@ var runRelationalSelect = async (opts) => {
3667
3672
  typeNameMapper,
3668
3673
  filterCtx,
3669
3674
  opts.limits,
3670
- scope
3675
+ scope,
3676
+ opts.defaultOrderBy
3671
3677
  ) : void 0
3672
3678
  };
3673
3679
  if (single) {
@@ -4273,7 +4279,8 @@ var generateSelectArray = (db, tableName, tables, relationMap, orderArgs, filter
4273
4279
  );
4274
4280
  return {
4275
4281
  name: fieldName,
4276
- resolver: async (_source, args, context, info) => {
4282
+ resolver: async (_source, rawArgs, context, info) => {
4283
+ const args = withDefaultOrderBy(rawArgs, tableName, policies?.defaultOrderBy);
4277
4284
  try {
4278
4285
  const parsedInfo = (0, import_graphql_parse_resolve_info2.parseResolveInfo)(info, { deep: true });
4279
4286
  const { executor, queryBase: requestQueryBase } = resolveQueryExecutor(db, context, tableName, queryBase);
@@ -4291,6 +4298,7 @@ var generateSelectArray = (db, tableName, tables, relationMap, orderArgs, filter
4291
4298
  single: false,
4292
4299
  filterCtx,
4293
4300
  limits,
4301
+ defaultOrderBy: policies?.defaultOrderBy,
4294
4302
  scope: policies?.scope?.(context),
4295
4303
  pkNames,
4296
4304
  db: executor,
@@ -4316,7 +4324,8 @@ var generateSelectSingle = (db, tableName, tables, relationMap, orderArgs, filte
4316
4324
  const pkNames = mysqlPrimaryKeyPropNames(table);
4317
4325
  return {
4318
4326
  name: fieldName,
4319
- resolver: async (_source, args, context, info) => {
4327
+ resolver: async (_source, rawArgs, context, info) => {
4328
+ const args = withDefaultOrderBy(rawArgs, tableName, policies?.defaultOrderBy);
4320
4329
  try {
4321
4330
  const parsedInfo = (0, import_graphql_parse_resolve_info2.parseResolveInfo)(info, { deep: true });
4322
4331
  const { executor, queryBase: requestQueryBase } = resolveQueryExecutor(db, context, tableName, queryBase);
@@ -4333,6 +4342,7 @@ var generateSelectSingle = (db, tableName, tables, relationMap, orderArgs, filte
4333
4342
  single: true,
4334
4343
  filterCtx,
4335
4344
  limits,
4345
+ defaultOrderBy: policies?.defaultOrderBy,
4336
4346
  scope: policies?.scope?.(context),
4337
4347
  pkNames,
4338
4348
  db: executor
@@ -5741,7 +5751,8 @@ var generateSelectArray2 = (db, tableName, tables, relationMap, orderArgs, filte
5741
5751
  );
5742
5752
  return {
5743
5753
  name: fieldName,
5744
- resolver: async (_source, args, context, info) => {
5754
+ resolver: async (_source, rawArgs, context, info) => {
5755
+ const args = withDefaultOrderBy(rawArgs, tableName, policies?.defaultOrderBy);
5745
5756
  try {
5746
5757
  const parsedInfo = (0, import_graphql_parse_resolve_info3.parseResolveInfo)(info, { deep: true });
5747
5758
  const { executor, queryBase: requestQueryBase } = resolveQueryExecutor(db, context, tableName, queryBase);
@@ -5762,6 +5773,7 @@ var generateSelectArray2 = (db, tableName, tables, relationMap, orderArgs, filte
5762
5773
  single: false,
5763
5774
  filterCtx,
5764
5775
  limits,
5776
+ defaultOrderBy: policies?.defaultOrderBy,
5765
5777
  pkNames,
5766
5778
  db: executor,
5767
5779
  scope,
@@ -5871,7 +5883,8 @@ var generateSelectSingle2 = (db, tableName, tables, relationMap, orderArgs, filt
5871
5883
  const pkNames = pgPrimaryKeyPropNames(table);
5872
5884
  return {
5873
5885
  name: fieldName,
5874
- resolver: async (_source, args, context, info) => {
5886
+ resolver: async (_source, rawArgs, context, info) => {
5887
+ const args = withDefaultOrderBy(rawArgs, tableName, policies?.defaultOrderBy);
5875
5888
  try {
5876
5889
  const parsedInfo = (0, import_graphql_parse_resolve_info3.parseResolveInfo)(info, { deep: true });
5877
5890
  const { executor, queryBase: requestQueryBase } = resolveQueryExecutor(db, context, tableName, queryBase);
@@ -5890,6 +5903,7 @@ var generateSelectSingle2 = (db, tableName, tables, relationMap, orderArgs, filt
5890
5903
  single: true,
5891
5904
  filterCtx,
5892
5905
  limits,
5906
+ defaultOrderBy: policies?.defaultOrderBy,
5893
5907
  pkNames,
5894
5908
  db: executor,
5895
5909
  scope
@@ -5983,7 +5997,8 @@ var generateInsertArray2 = (db, tableName, table, tables, relationMap, baseType,
5983
5997
  pkNames,
5984
5998
  parsedInfo,
5985
5999
  limits,
5986
- scope
6000
+ scope,
6001
+ defaultOrderBy: policies?.defaultOrderBy
5987
6002
  });
5988
6003
  const returning = nestedEntries ? nested.withJoinColumns(tableName, mergedOps(nestedEntries), { ...columns }, table) : columns;
5989
6004
  const runInsert = async (target, values) => {
@@ -6073,7 +6088,8 @@ var generateInsertSingle2 = (db, tableName, table, tables, relationMap, baseType
6073
6088
  pkNames,
6074
6089
  parsedInfo,
6075
6090
  limits,
6076
- scope
6091
+ scope,
6092
+ defaultOrderBy: policies?.defaultOrderBy
6077
6093
  });
6078
6094
  const returning = nestedEntry ? nested.withJoinColumns(tableName, nestedEntry.ops, { ...columns }, table) : columns;
6079
6095
  const runInsert = async (target, values) => {
@@ -6175,7 +6191,8 @@ var generateUpsert2 = (db, tableName, table, tables, relationMap, baseType, onCo
6175
6191
  pkNames,
6176
6192
  parsedInfo,
6177
6193
  limits,
6178
- scope
6194
+ scope,
6195
+ defaultOrderBy: policies?.defaultOrderBy
6179
6196
  });
6180
6197
  const returning = nestedEntries ? nested.withJoinColumns(tableName, mergedOps(nestedEntries), { ...columns }, table) : columns;
6181
6198
  const runUpsert = async (target, values) => {
@@ -6273,7 +6290,8 @@ var generateUpdate2 = (db, tableName, table, tables, relationMap, setArgs, filte
6273
6290
  pkNames,
6274
6291
  parsedInfo,
6275
6292
  limits,
6276
- scope
6293
+ scope,
6294
+ defaultOrderBy: policies?.defaultOrderBy
6277
6295
  });
6278
6296
  const entry = nested?.enabled(tableName) ? nested.split(tableName, set) : void 0;
6279
6297
  const nestedOps = entry && nested.hasOps(entry.ops) ? entry.ops : void 0;
@@ -6387,7 +6405,8 @@ var generateUpdateMany2 = (db, tableName, table, tables, relationMap, updateMany
6387
6405
  pkNames,
6388
6406
  parsedInfo,
6389
6407
  limits,
6390
- scope
6408
+ scope,
6409
+ defaultOrderBy: policies?.defaultOrderBy
6391
6410
  });
6392
6411
  const entries = updates.map(({ where, set }) => {
6393
6412
  const split = nested?.enabled(tableName) ? nested.split(tableName, set) : void 0;
@@ -7191,7 +7210,8 @@ var generateSelectArray3 = (db, tableName, tables, relationMap, orderArgs, filte
7191
7210
  );
7192
7211
  return {
7193
7212
  name: fieldName,
7194
- resolver: async (_source, args, context, info) => {
7213
+ resolver: async (_source, rawArgs, context, info) => {
7214
+ const args = withDefaultOrderBy(rawArgs, tableName, policies?.defaultOrderBy);
7195
7215
  try {
7196
7216
  const parsedInfo = (0, import_graphql_parse_resolve_info4.parseResolveInfo)(info, { deep: true });
7197
7217
  const { executor, queryBase: requestQueryBase } = resolveQueryExecutor(db, context, tableName, queryBase);
@@ -7209,6 +7229,7 @@ var generateSelectArray3 = (db, tableName, tables, relationMap, orderArgs, filte
7209
7229
  single: false,
7210
7230
  filterCtx,
7211
7231
  limits,
7232
+ defaultOrderBy: policies?.defaultOrderBy,
7212
7233
  pkNames,
7213
7234
  db: executor,
7214
7235
  scope: policies?.scope?.(context),
@@ -7234,7 +7255,8 @@ var generateSelectSingle3 = (db, tableName, tables, relationMap, orderArgs, filt
7234
7255
  const pkNames = sqlitePrimaryKeyPropNames(table);
7235
7256
  return {
7236
7257
  name: fieldName,
7237
- resolver: async (_source, args, context, info) => {
7258
+ resolver: async (_source, rawArgs, context, info) => {
7259
+ const args = withDefaultOrderBy(rawArgs, tableName, policies?.defaultOrderBy);
7238
7260
  try {
7239
7261
  const parsedInfo = (0, import_graphql_parse_resolve_info4.parseResolveInfo)(info, { deep: true });
7240
7262
  const { executor, queryBase: requestQueryBase } = resolveQueryExecutor(db, context, tableName, queryBase);
@@ -7251,6 +7273,7 @@ var generateSelectSingle3 = (db, tableName, tables, relationMap, orderArgs, filt
7251
7273
  single: true,
7252
7274
  filterCtx,
7253
7275
  limits,
7276
+ defaultOrderBy: policies?.defaultOrderBy,
7254
7277
  pkNames,
7255
7278
  db: executor,
7256
7279
  scope: policies?.scope?.(context)
@@ -7315,7 +7338,8 @@ var generateInsertArray3 = (db, tableName, table, tables, relationMap, baseType,
7315
7338
  pkNames,
7316
7339
  parsedInfo,
7317
7340
  limits,
7318
- scope
7341
+ scope,
7342
+ defaultOrderBy: policies?.defaultOrderBy
7319
7343
  });
7320
7344
  const returning = nestedEntries ? nested.withJoinColumns(tableName, mergedOps(nestedEntries), { ...columns }, table) : columns;
7321
7345
  const runInsert = async (target, values) => {
@@ -7405,7 +7429,8 @@ var generateInsertSingle3 = (db, tableName, table, tables, relationMap, baseType
7405
7429
  pkNames,
7406
7430
  parsedInfo,
7407
7431
  limits,
7408
- scope
7432
+ scope,
7433
+ defaultOrderBy: policies?.defaultOrderBy
7409
7434
  });
7410
7435
  const returning = nestedEntry ? nested.withJoinColumns(tableName, nestedEntry.ops, { ...columns }, table) : columns;
7411
7436
  const runInsert = async (target, values) => {
@@ -7507,7 +7532,8 @@ var generateUpsert3 = (db, tableName, table, tables, relationMap, baseType, onCo
7507
7532
  pkNames,
7508
7533
  parsedInfo,
7509
7534
  limits,
7510
- scope
7535
+ scope,
7536
+ defaultOrderBy: policies?.defaultOrderBy
7511
7537
  });
7512
7538
  const returning = nestedEntries ? nested.withJoinColumns(tableName, mergedOps(nestedEntries), { ...columns }, table) : columns;
7513
7539
  const runUpsert = async (target, values) => {
@@ -7605,7 +7631,8 @@ var generateUpdate3 = (db, tableName, table, tables, relationMap, setArgs, filte
7605
7631
  pkNames,
7606
7632
  parsedInfo,
7607
7633
  limits,
7608
- scope
7634
+ scope,
7635
+ defaultOrderBy: policies?.defaultOrderBy
7609
7636
  });
7610
7637
  const entry = nested?.enabled(tableName) ? nested.split(tableName, set) : void 0;
7611
7638
  const nestedOps = entry && nested.hasOps(entry.ops) ? entry.ops : void 0;
@@ -7719,7 +7746,8 @@ var generateUpdateMany3 = (db, tableName, table, tables, relationMap, updateMany
7719
7746
  pkNames,
7720
7747
  parsedInfo,
7721
7748
  limits,
7722
- scope
7749
+ scope,
7750
+ defaultOrderBy: policies?.defaultOrderBy
7723
7751
  });
7724
7752
  const entries = updates.map(({ where, set }) => {
7725
7753
  const split = nested?.enabled(tableName) ? nested.split(tableName, set) : void 0;
@@ -8734,6 +8762,46 @@ var buildSchema = (db, config) => {
8734
8762
  limitPolicyCache.set(tableName, resolved);
8735
8763
  return resolved;
8736
8764
  } : void 0;
8765
+ const defaultsConfig = config?.defaults;
8766
+ const defaultOrderByByTable = /* @__PURE__ */ new Map();
8767
+ if (defaultsConfig) {
8768
+ const defaultsTableNames = new Set(tableKeys);
8769
+ for (const [tableName, tableDefaults] of Object.entries(defaultsConfig)) {
8770
+ if (!defaultsTableNames.has(tableName)) {
8771
+ throw new Error(
8772
+ `Drizzle-GraphQL Error: config.defaults names '${tableName}', which is not a table in the Drizzle schema.`
8773
+ );
8774
+ }
8775
+ const orderBy = tableDefaults?.orderBy;
8776
+ if (!orderBy || !Object.keys(orderBy).length) {
8777
+ continue;
8778
+ }
8779
+ const columns = (0, import_drizzle_orm11.getColumns)(schema[tableName]);
8780
+ const normalized = {};
8781
+ for (const [columnName, entry] of Object.entries(orderBy)) {
8782
+ if (!columns[columnName]) {
8783
+ throw new Error(
8784
+ `Drizzle-GraphQL Error: config.defaults.${tableName}.orderBy names '${columnName}', which is not a column of '${tableName}'.`
8785
+ );
8786
+ }
8787
+ const direction = typeof entry === "string" ? entry : entry?.direction;
8788
+ if (direction !== "asc" && direction !== "desc") {
8789
+ throw new Error(
8790
+ `Drizzle-GraphQL Error: config.defaults.${tableName}.orderBy.${columnName} must be 'asc', 'desc', or { direction, priority? }.`
8791
+ );
8792
+ }
8793
+ const priority = typeof entry === "string" ? void 0 : entry?.priority;
8794
+ if (priority !== void 0 && !Number.isInteger(priority)) {
8795
+ throw new Error(
8796
+ `Drizzle-GraphQL Error: config.defaults.${tableName}.orderBy.${columnName}.priority must be an integer.`
8797
+ );
8798
+ }
8799
+ normalized[columnName] = priority === void 0 ? { direction } : { direction, priority };
8800
+ }
8801
+ defaultOrderByByTable.set(tableName, normalized);
8802
+ }
8803
+ }
8804
+ const defaultOrderBy = defaultOrderByByTable.size ? (tableName) => defaultOrderByByTable.get(tableName) : void 0;
8737
8805
  const scopeConfig = config?.scope;
8738
8806
  const contextValuesConfig = config?.contextValues;
8739
8807
  if (scopeConfig || contextValuesConfig) {
@@ -8814,11 +8882,12 @@ var buildSchema = (db, config) => {
8814
8882
  }
8815
8883
  }
8816
8884
  const onWrite = globalWriteHooks || writeHooks.size ? (tableName) => globalWriteHooks ?? writeHooks.get(tableName) : void 0;
8817
- const policies = scopeConfig || contextValuesConfig || softDeleteInfos.size || onWrite ? {
8885
+ const policies = scopeConfig || contextValuesConfig || softDeleteInfos.size || onWrite || defaultOrderBy ? {
8818
8886
  scope: scopeConfig ? (tableName) => scopeConfig[tableName] : void 0,
8819
8887
  contextValues: contextValuesConfig ? (tableName) => contextValuesConfig[tableName] : void 0,
8820
8888
  softDelete: softDeleteInfos.size ? (tableName) => softDeleteInfos.get(tableName) : void 0,
8821
- onWrite
8889
+ onWrite,
8890
+ defaultOrderBy
8822
8891
  } : void 0;
8823
8892
  const exclude = config?.exclude;
8824
8893
  if (exclude) {