@ai0x0/utils 0.2.0 → 0.3.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.
@@ -48,7 +48,7 @@ export function createPostOperationFactory(_ref) {
48
48
  contentType: contentType
49
49
  }).outputs([{
50
50
  body: schemas.response || z.object({
51
- id: z.string()
51
+ id: z.string().describe("Id of the row created.")
52
52
  }),
53
53
  contentType: "application/json",
54
54
  status: 200
@@ -316,7 +316,7 @@ export function createPutOperationFactory(_ref5) {
316
316
  // ==============================================================================
317
317
 
318
318
  var defaultDeleteBodySchema = z.object({
319
- id: z.string()
319
+ id: z.string().describe("Id of the row to delete.")
320
320
  });
321
321
  export function createDeleteOperationFactory(_ref9) {
322
322
  var createAction = _ref9.createAction,
@@ -4,6 +4,12 @@ function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t =
4
4
  function _defineProperty(obj, key, value) { key = _toPropertyKey(key); if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
5
5
  function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == _typeof(i) ? i : String(i); }
6
6
  function _toPrimitive(t, r) { if ("object" != _typeof(t) || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != _typeof(i)) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
7
+ function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest(); }
8
+ function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
9
+ function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }
10
+ function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i]; return arr2; }
11
+ function _iterableToArrayLimit(r, l) { var t = null == r ? null : "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (null != t) { var e, n, i, u, a = [], f = !0, o = !1; try { if (i = (t = t.call(r)).next, 0 === l) { if (Object(t) !== t) return; f = !1; } else for (; !(f = (e = i.call(t)).done) && (a.push(e.value), a.length !== l); f = !0); } catch (r) { o = !0, n = r; } finally { try { if (!f && null != t.return && (u = t.return(), Object(u) !== u)) return; } finally { if (o) throw n; } } return a; } }
12
+ function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }
7
13
  import { z } from "zod";
8
14
  import { pgTable, timestamp, uuid } from "drizzle-orm/pg-core";
9
15
  import { createInsertSchema, createSelectSchema, createUpdateSchema } from "drizzle-zod";
@@ -72,19 +78,21 @@ export var BASIC_UPDATE_OMIT = {
72
78
  // =============================================================================
73
79
  // 列表查询字段
74
80
  // =============================================================================
81
+ // 说明写成 `.describe()` 而不是行末注释:注释只有读源码的人看得到,而这七个字段会出现在每一个
82
+ // list 端点的 OpenAPI spec 里,再从那里流进生成的 client 与 CLI 文档。写成注释的代价是下游只能
83
+ // 自己再手写一份 —— 那份必然会漂,而且漂了没有任何东西会报错。
84
+ //
85
+ // 类型是 string 而不是 number:query 参数在线上只有字符串,服务端收下之后才转数字。默认值也
86
+ // 因此是 "1" / "10"。
75
87
  export var queryListSchema = function queryListSchema(schema) {
76
88
  return z.object({
77
- current: z.string().optional().default("1"),
78
- // 默认页码为 1
79
- pageSize: z.string().optional().default("10"),
80
- // 默认每页条数为 10
81
- createdAtFrom: z.string().optional(),
82
- // 筛选开始日期
83
- createdAtTo: z.string().optional(),
84
- // 筛选结束日期
85
- orderBy: z.string().optional(),
86
- creatorId: z.string().optional(),
87
- orderDir: z.enum(["asc", "desc"]).optional()
89
+ current: z.string().optional().default("1").describe("Page number, starting at 1."),
90
+ pageSize: z.string().optional().default("10").describe("Rows per page. Omitting it yields only 10 — pass a larger value to get the whole set."),
91
+ createdAtFrom: z.string().optional().describe("Keep only rows created at or after this instant (ISO 8601, e.g. 2026-08-01T00:00:00Z)."),
92
+ createdAtTo: z.string().optional().describe("Keep only rows created at or before this instant."),
93
+ orderBy: z.string().optional().describe("Column to sort by — a column name of this resource (createdAt / updatedAt and the like)."),
94
+ creatorId: z.string().optional().describe("Keep only rows created by this user. Useful in shared spaces to filter down to one member."),
95
+ orderDir: z.enum(["asc", "desc"]).optional().describe("Sort ascending or descending.")
88
96
  }).merge(schema);
89
97
  };
90
98
 
@@ -98,6 +106,64 @@ export var listBodySchema = function listBodySchema(schema) {
98
106
  });
99
107
  };
100
108
 
109
+ // =============================================================================
110
+ // 给基础字段挂说明
111
+ // =============================================================================
112
+ // basicFields 是 drizzle 列,而 drizzle 列没有「描述」这个概念 —— 所以说明只能挂在
113
+ // drizzle-zod 出来的 schema 上。值得做是因为这六个字段出现在**每一张表**的 select schema 里:
114
+ // 一处写完,所有 list / get 端点的返回字段表都有了(在 do-tv 上是 173 行)。
115
+ //
116
+ // 一律只挂元数据,**不换类型**:`.describe()` / `.meta()` 返回的是带元数据的克隆,校验行为一模
117
+ // 一样。selectSchema 是有人拿去 safeParse 的(本包自己的测试就在用 Date 校验它),换类型等于改
118
+ // 这个包的契约。
119
+ //
120
+ // 时间戳那三列额外用 `.meta()` 补上 JSON Schema 表示,因为不补就是错的:drizzle-zod 给的是
121
+ // `z.date()`,而 `Date` 在 JSON Schema 里表达不出来,于是这三个字段在 spec 里是**空对象** ——
122
+ // 没有 `type`,照 spec 生成的 client / CLI 只能得到 `unknown`。而线上根本不可能是 Date:响应一经
123
+ // JSON 序列化就是 ISO 8601 字符串。
124
+ //
125
+ // `.meta({ type, format })` 恰好只改「怎么描述」不改「怎么校验」:spec 里成为
126
+ // `{"type":"string","format":"date-time"}`,而 `safeParse(new Date())` 照样通过。
127
+ // 不用 `z.iso.datetime()` 换掉它,是因为那既改了校验(不再收 Date),又会往 JSON Schema 里塞一条
128
+ // 380 字节的正则 —— 乘上每张表几十 KB,而 `format` 已经把「按日期时间解析」说清楚了。
129
+ var BASIC_FIELD_NOTES = {
130
+ creatorId: "User id of the creator. Stamped by the server; clients cannot send it.",
131
+ editorId: "User id of whoever changed this row last. Stamped by the server; clients cannot send it.",
132
+ id: "Primary key of this row (uuid)."
133
+ };
134
+ var BASIC_TIMESTAMP_NOTES = {
135
+ accessedAt: "When this row was last accessed.",
136
+ createdAt: "When this row was created.",
137
+ updatedAt: "When this row was last modified."
138
+ };
139
+ var describeBasicFields = function describeBasicFields(schema) {
140
+ var overlay = {};
141
+ for (var _i = 0, _Object$entries = Object.entries(BASIC_FIELD_NOTES); _i < _Object$entries.length; _i++) {
142
+ var _Object$entries$_i = _slicedToArray(_Object$entries[_i], 2),
143
+ field = _Object$entries$_i[0],
144
+ note = _Object$entries$_i[1];
145
+ var existing = schema.shape[field];
146
+ // 表里没这一列就跳过 —— 不给不存在的字段凭空造一个。
147
+ if (existing) {
148
+ overlay[field] = existing.describe(note);
149
+ }
150
+ }
151
+ for (var _i2 = 0, _Object$entries2 = Object.entries(BASIC_TIMESTAMP_NOTES); _i2 < _Object$entries2.length; _i2++) {
152
+ var _Object$entries2$_i = _slicedToArray(_Object$entries2[_i2], 2),
153
+ _field = _Object$entries2$_i[0],
154
+ _note = _Object$entries2$_i[1];
155
+ var _existing = schema.shape[_field];
156
+ if (_existing) {
157
+ overlay[_field] = _existing.meta({
158
+ description: _note,
159
+ format: "date-time",
160
+ type: "string"
161
+ });
162
+ }
163
+ }
164
+ return schema.extend(overlay);
165
+ };
166
+
101
167
  // =============================================================================
102
168
  // 建表 —— 表 + 5 份 zod schema
103
169
  // =============================================================================
@@ -112,16 +178,16 @@ export var createTableSchema = function createTableSchema(_ref) {
112
178
  extraConfig = _ref.extraConfig;
113
179
  var mergedColumns = _objectSpread(_objectSpread(_objectSpread({}, basicFields), serverColumns), columns);
114
180
  var table = pgTable(name, mergedColumns, extraConfig);
115
- var selectSchema = createSelectSchema(table);
181
+ var selectSchema = describeBasicFields(createSelectSchema(table));
116
182
  // 只从 columns 推 —— basicFields 与 serverColumns 都由服务端写,不该出现在请求体里。
117
183
  var insertSchema = createInsertSchema(pgTable(name, columns));
118
184
  var updateSchema = createUpdateSchema(pgTable(name, _objectSpread({
119
185
  id: uuid("id")
120
186
  }, columns))).extend({
121
- id: z.string()
187
+ id: z.string().describe("Id of the row to update.")
122
188
  });
123
189
  var querySchema = z.object({
124
- id: z.string()
190
+ id: z.string().describe("Id of the row to fetch.")
125
191
  });
126
192
  var queryListWithSchema = queryListSchema(z.object({}).catchall(z.unknown()));
127
193
  return {
@@ -4,6 +4,12 @@ function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t =
4
4
  function _defineProperty(obj, key, value) { key = _toPropertyKey(key); if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
5
5
  function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == _typeof(i) ? i : String(i); }
6
6
  function _toPrimitive(t, r) { if ("object" != _typeof(t) || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != _typeof(i)) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
7
+ function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest(); }
8
+ function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
9
+ function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }
10
+ function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i]; return arr2; }
11
+ function _iterableToArrayLimit(r, l) { var t = null == r ? null : "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (null != t) { var e, n, i, u, a = [], f = !0, o = !1; try { if (i = (t = t.call(r)).next, 0 === l) { if (Object(t) !== t) return; f = !1; } else for (; !(f = (e = i.call(t)).done) && (a.push(e.value), a.length !== l); f = !0); } catch (r) { o = !0, n = r; } finally { try { if (!f && null != t.return && (u = t.return(), Object(u) !== u)) return; } finally { if (o) throw n; } } return a; } }
12
+ function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }
7
13
  import { z } from "zod";
8
14
  import { integer, sqliteTable, text } from "drizzle-orm/sqlite-core";
9
15
  import { createInsertSchema, createSelectSchema, createUpdateSchema } from "drizzle-zod";
@@ -78,19 +84,21 @@ export var BASIC_UPDATE_OMIT = {
78
84
  // =============================================================================
79
85
  // 列表查询字段
80
86
  // =============================================================================
87
+ // 说明写成 `.describe()` 而不是行末注释:注释只有读源码的人看得到,而这七个字段会出现在每一个
88
+ // list 端点的 OpenAPI spec 里,再从那里流进生成的 client 与 CLI 文档。写成注释的代价是下游只能
89
+ // 自己再手写一份 —— 那份必然会漂,而且漂了没有任何东西会报错。
90
+ //
91
+ // 类型是 string 而不是 number:query 参数在线上只有字符串,服务端收下之后才转数字。默认值也
92
+ // 因此是 "1" / "10"。
81
93
  export var queryListSchema = function queryListSchema(schema) {
82
94
  return z.object({
83
- current: z.string().optional().default("1"),
84
- // 默认页码为 1
85
- pageSize: z.string().optional().default("10"),
86
- // 默认每页条数为 10
87
- createdAtFrom: z.string().optional(),
88
- // 筛选开始日期
89
- createdAtTo: z.string().optional(),
90
- // 筛选结束日期
91
- orderBy: z.string().optional(),
92
- creatorId: z.string().optional(),
93
- orderDir: z.enum(["asc", "desc"]).optional()
95
+ current: z.string().optional().default("1").describe("Page number, starting at 1."),
96
+ pageSize: z.string().optional().default("10").describe("Rows per page. Omitting it yields only 10 — pass a larger value to get the whole set."),
97
+ createdAtFrom: z.string().optional().describe("Keep only rows created at or after this instant (ISO 8601, e.g. 2026-08-01T00:00:00Z)."),
98
+ createdAtTo: z.string().optional().describe("Keep only rows created at or before this instant."),
99
+ orderBy: z.string().optional().describe("Column to sort by — a column name of this resource (createdAt / updatedAt and the like)."),
100
+ creatorId: z.string().optional().describe("Keep only rows created by this user. Useful in shared spaces to filter down to one member."),
101
+ orderDir: z.enum(["asc", "desc"]).optional().describe("Sort ascending or descending.")
94
102
  }).merge(schema);
95
103
  };
96
104
 
@@ -104,6 +112,64 @@ export var listBodySchema = function listBodySchema(schema) {
104
112
  });
105
113
  };
106
114
 
115
+ // =============================================================================
116
+ // 给基础字段挂说明
117
+ // =============================================================================
118
+ // basicFields 是 drizzle 列,而 drizzle 列没有「描述」这个概念 —— 所以说明只能挂在
119
+ // drizzle-zod 出来的 schema 上。值得做是因为这六个字段出现在**每一张表**的 select schema 里:
120
+ // 一处写完,所有 list / get 端点的返回字段都有说明了。
121
+ //
122
+ // 一律只挂元数据,**不换类型**:`.describe()` / `.meta()` 返回的是带元数据的克隆,校验行为一模
123
+ // 一样。selectSchema 是有人拿去 safeParse 的(本包自己的测试就在用 Date 校验它),换类型等于改
124
+ // 这个包的契约。
125
+ //
126
+ // 时间戳那三列额外用 `.meta()` 补上 JSON Schema 表示,因为不补就是错的:drizzle-zod 给的是
127
+ // `z.date()`,而 `Date` 在 JSON Schema 里表达不出来,于是这三个字段在 spec 里是**空对象** ——
128
+ // 没有 `type`,照 spec 生成的 client / CLI 只能得到 `unknown`。而线上根本不可能是 Date:响应一经
129
+ // JSON 序列化就是 ISO 8601 字符串。
130
+ //
131
+ // `.meta({ type, format })` 恰好只改「怎么描述」不改「怎么校验」:spec 里成为
132
+ // `{"type":"string","format":"date-time"}`,而 `safeParse(new Date())` 照样通过。
133
+ // 不用 `z.iso.datetime()` 换掉它,是因为那既改了校验(不再收 Date),又会往 JSON Schema 里塞一条
134
+ // 380 字节的正则 —— 乘上每张表几十 KB,而 `format` 已经把「按日期时间解析」说清楚了。
135
+ var BASIC_FIELD_NOTES = {
136
+ creatorId: "User id of the creator. Stamped by the server; clients cannot send it.",
137
+ editorId: "User id of whoever changed this row last. Stamped by the server; clients cannot send it.",
138
+ id: "Primary key of this row (uuid)."
139
+ };
140
+ var BASIC_TIMESTAMP_NOTES = {
141
+ accessedAt: "When this row was last accessed.",
142
+ createdAt: "When this row was created.",
143
+ updatedAt: "When this row was last modified."
144
+ };
145
+ var describeBasicFields = function describeBasicFields(schema) {
146
+ var overlay = {};
147
+ for (var _i = 0, _Object$entries = Object.entries(BASIC_FIELD_NOTES); _i < _Object$entries.length; _i++) {
148
+ var _Object$entries$_i = _slicedToArray(_Object$entries[_i], 2),
149
+ field = _Object$entries$_i[0],
150
+ note = _Object$entries$_i[1];
151
+ var existing = schema.shape[field];
152
+ // 表里没这一列就跳过 —— 不给不存在的字段凭空造一个。
153
+ if (existing) {
154
+ overlay[field] = existing.describe(note);
155
+ }
156
+ }
157
+ for (var _i2 = 0, _Object$entries2 = Object.entries(BASIC_TIMESTAMP_NOTES); _i2 < _Object$entries2.length; _i2++) {
158
+ var _Object$entries2$_i = _slicedToArray(_Object$entries2[_i2], 2),
159
+ _field = _Object$entries2$_i[0],
160
+ _note = _Object$entries2$_i[1];
161
+ var _existing = schema.shape[_field];
162
+ if (_existing) {
163
+ overlay[_field] = _existing.meta({
164
+ description: _note,
165
+ format: "date-time",
166
+ type: "string"
167
+ });
168
+ }
169
+ }
170
+ return schema.extend(overlay);
171
+ };
172
+
107
173
  // =============================================================================
108
174
  // 建表 —— 表 + 5 份 zod schema
109
175
  // =============================================================================
@@ -118,16 +184,16 @@ export var createTableSchema = function createTableSchema(_ref) {
118
184
  extraConfig = _ref.extraConfig;
119
185
  var mergedColumns = _objectSpread(_objectSpread(_objectSpread({}, basicFields), serverColumns), columns);
120
186
  var table = sqliteTable(name, mergedColumns, extraConfig);
121
- var selectSchema = createSelectSchema(table);
187
+ var selectSchema = describeBasicFields(createSelectSchema(table));
122
188
  // 只从 columns 推 —— basicFields 与 serverColumns 都由服务端写,不该出现在请求体里。
123
189
  var insertSchema = createInsertSchema(sqliteTable(name, columns));
124
190
  var updateSchema = createUpdateSchema(sqliteTable(name, _objectSpread({
125
191
  id: text("id")
126
192
  }, columns))).extend({
127
- id: z.string()
193
+ id: z.string().describe("Id of the row to update.")
128
194
  });
129
195
  var querySchema = z.object({
130
- id: z.string()
196
+ id: z.string().describe("Id of the row to fetch.")
131
197
  });
132
198
  var queryListWithSchema = queryListSchema(z.object({}).catchall(z.unknown()));
133
199
  return {
@@ -57,7 +57,7 @@ function createPostOperationFactory({
57
57
  contentType
58
58
  }).outputs([
59
59
  {
60
- body: schemas.response || import_zod.z.object({ id: import_zod.z.string() }),
60
+ body: schemas.response || import_zod.z.object({ id: import_zod.z.string().describe("Id of the row created.") }),
61
61
  contentType: "application/json",
62
62
  status: 200
63
63
  }
@@ -156,7 +156,7 @@ function createPutOperationFactory({
156
156
  });
157
157
  }
158
158
  var defaultDeleteBodySchema = import_zod.z.object({
159
- id: import_zod.z.string()
159
+ id: import_zod.z.string().describe("Id of the row to delete.")
160
160
  });
161
161
  function createDeleteOperationFactory({
162
162
  createAction,
@@ -58,22 +58,56 @@ var BASIC_UPDATE_OMIT = {
58
58
  updatedAt: true
59
59
  };
60
60
  var queryListSchema = (schema) => import_zod.z.object({
61
- current: import_zod.z.string().optional().default("1"),
62
- // 默认页码为 1
63
- pageSize: import_zod.z.string().optional().default("10"),
64
- // 默认每页条数为 10
65
- createdAtFrom: import_zod.z.string().optional(),
66
- // 筛选开始日期
67
- createdAtTo: import_zod.z.string().optional(),
68
- // 筛选结束日期
69
- orderBy: import_zod.z.string().optional(),
70
- creatorId: import_zod.z.string().optional(),
71
- orderDir: import_zod.z.enum(["asc", "desc"]).optional()
61
+ current: import_zod.z.string().optional().default("1").describe("Page number, starting at 1."),
62
+ pageSize: import_zod.z.string().optional().default("10").describe(
63
+ "Rows per page. Omitting it yields only 10 — pass a larger value to get the whole set."
64
+ ),
65
+ createdAtFrom: import_zod.z.string().optional().describe(
66
+ "Keep only rows created at or after this instant (ISO 8601, e.g. 2026-08-01T00:00:00Z)."
67
+ ),
68
+ createdAtTo: import_zod.z.string().optional().describe("Keep only rows created at or before this instant."),
69
+ orderBy: import_zod.z.string().optional().describe(
70
+ "Column to sort by — a column name of this resource (createdAt / updatedAt and the like)."
71
+ ),
72
+ creatorId: import_zod.z.string().optional().describe(
73
+ "Keep only rows created by this user. Useful in shared spaces to filter down to one member."
74
+ ),
75
+ orderDir: import_zod.z.enum(["asc", "desc"]).optional().describe("Sort ascending or descending.")
72
76
  }).merge(schema);
73
77
  var listBodySchema = (schema) => import_zod.z.object({
74
78
  total: import_zod.z.number(),
75
79
  data: import_zod.z.array(schema)
76
80
  });
81
+ var BASIC_FIELD_NOTES = {
82
+ creatorId: "User id of the creator. Stamped by the server; clients cannot send it.",
83
+ editorId: "User id of whoever changed this row last. Stamped by the server; clients cannot send it.",
84
+ id: "Primary key of this row (uuid)."
85
+ };
86
+ var BASIC_TIMESTAMP_NOTES = {
87
+ accessedAt: "When this row was last accessed.",
88
+ createdAt: "When this row was created.",
89
+ updatedAt: "When this row was last modified."
90
+ };
91
+ var describeBasicFields = (schema) => {
92
+ const overlay = {};
93
+ for (const [field, note] of Object.entries(BASIC_FIELD_NOTES)) {
94
+ const existing = schema.shape[field];
95
+ if (existing) {
96
+ overlay[field] = existing.describe(note);
97
+ }
98
+ }
99
+ for (const [field, note] of Object.entries(BASIC_TIMESTAMP_NOTES)) {
100
+ const existing = schema.shape[field];
101
+ if (existing) {
102
+ overlay[field] = existing.meta({
103
+ description: note,
104
+ format: "date-time",
105
+ type: "string"
106
+ });
107
+ }
108
+ }
109
+ return schema.extend(overlay);
110
+ };
77
111
  var createTableSchema = ({
78
112
  name,
79
113
  columns,
@@ -86,12 +120,14 @@ var createTableSchema = ({
86
120
  ...columns
87
121
  };
88
122
  const table = (0, import_pg_core.pgTable)(name, mergedColumns, extraConfig);
89
- const selectSchema = (0, import_drizzle_zod.createSelectSchema)(table);
123
+ const selectSchema = describeBasicFields((0, import_drizzle_zod.createSelectSchema)(table));
90
124
  const insertSchema = (0, import_drizzle_zod.createInsertSchema)((0, import_pg_core.pgTable)(name, columns));
91
125
  const updateSchema = (0, import_drizzle_zod.createUpdateSchema)(
92
126
  (0, import_pg_core.pgTable)(name, { id: (0, import_pg_core.uuid)("id"), ...columns })
93
- ).extend({ id: import_zod.z.string() });
94
- const querySchema = import_zod.z.object({ id: import_zod.z.string() });
127
+ ).extend({ id: import_zod.z.string().describe("Id of the row to update.") });
128
+ const querySchema = import_zod.z.object({
129
+ id: import_zod.z.string().describe("Id of the row to fetch.")
130
+ });
95
131
  const queryListWithSchema = queryListSchema(
96
132
  import_zod.z.object({}).catchall(import_zod.z.unknown())
97
133
  );
@@ -60,22 +60,56 @@ var BASIC_UPDATE_OMIT = {
60
60
  updatedAt: true
61
61
  };
62
62
  var queryListSchema = (schema) => import_zod.z.object({
63
- current: import_zod.z.string().optional().default("1"),
64
- // 默认页码为 1
65
- pageSize: import_zod.z.string().optional().default("10"),
66
- // 默认每页条数为 10
67
- createdAtFrom: import_zod.z.string().optional(),
68
- // 筛选开始日期
69
- createdAtTo: import_zod.z.string().optional(),
70
- // 筛选结束日期
71
- orderBy: import_zod.z.string().optional(),
72
- creatorId: import_zod.z.string().optional(),
73
- orderDir: import_zod.z.enum(["asc", "desc"]).optional()
63
+ current: import_zod.z.string().optional().default("1").describe("Page number, starting at 1."),
64
+ pageSize: import_zod.z.string().optional().default("10").describe(
65
+ "Rows per page. Omitting it yields only 10 — pass a larger value to get the whole set."
66
+ ),
67
+ createdAtFrom: import_zod.z.string().optional().describe(
68
+ "Keep only rows created at or after this instant (ISO 8601, e.g. 2026-08-01T00:00:00Z)."
69
+ ),
70
+ createdAtTo: import_zod.z.string().optional().describe("Keep only rows created at or before this instant."),
71
+ orderBy: import_zod.z.string().optional().describe(
72
+ "Column to sort by — a column name of this resource (createdAt / updatedAt and the like)."
73
+ ),
74
+ creatorId: import_zod.z.string().optional().describe(
75
+ "Keep only rows created by this user. Useful in shared spaces to filter down to one member."
76
+ ),
77
+ orderDir: import_zod.z.enum(["asc", "desc"]).optional().describe("Sort ascending or descending.")
74
78
  }).merge(schema);
75
79
  var listBodySchema = (schema) => import_zod.z.object({
76
80
  total: import_zod.z.number(),
77
81
  data: import_zod.z.array(schema)
78
82
  });
83
+ var BASIC_FIELD_NOTES = {
84
+ creatorId: "User id of the creator. Stamped by the server; clients cannot send it.",
85
+ editorId: "User id of whoever changed this row last. Stamped by the server; clients cannot send it.",
86
+ id: "Primary key of this row (uuid)."
87
+ };
88
+ var BASIC_TIMESTAMP_NOTES = {
89
+ accessedAt: "When this row was last accessed.",
90
+ createdAt: "When this row was created.",
91
+ updatedAt: "When this row was last modified."
92
+ };
93
+ var describeBasicFields = (schema) => {
94
+ const overlay = {};
95
+ for (const [field, note] of Object.entries(BASIC_FIELD_NOTES)) {
96
+ const existing = schema.shape[field];
97
+ if (existing) {
98
+ overlay[field] = existing.describe(note);
99
+ }
100
+ }
101
+ for (const [field, note] of Object.entries(BASIC_TIMESTAMP_NOTES)) {
102
+ const existing = schema.shape[field];
103
+ if (existing) {
104
+ overlay[field] = existing.meta({
105
+ description: note,
106
+ format: "date-time",
107
+ type: "string"
108
+ });
109
+ }
110
+ }
111
+ return schema.extend(overlay);
112
+ };
79
113
  var createTableSchema = ({ name, columns, serverColumns, extraConfig }) => {
80
114
  const mergedColumns = {
81
115
  ...basicFields,
@@ -87,12 +121,14 @@ var createTableSchema = ({ name, columns, serverColumns, extraConfig }) => {
87
121
  mergedColumns,
88
122
  extraConfig
89
123
  );
90
- const selectSchema = (0, import_drizzle_zod.createSelectSchema)(table);
124
+ const selectSchema = describeBasicFields((0, import_drizzle_zod.createSelectSchema)(table));
91
125
  const insertSchema = (0, import_drizzle_zod.createInsertSchema)((0, import_sqlite_core.sqliteTable)(name, columns));
92
126
  const updateSchema = (0, import_drizzle_zod.createUpdateSchema)(
93
127
  (0, import_sqlite_core.sqliteTable)(name, { id: (0, import_sqlite_core.text)("id"), ...columns })
94
- ).extend({ id: import_zod.z.string() });
95
- const querySchema = import_zod.z.object({ id: import_zod.z.string() });
128
+ ).extend({ id: import_zod.z.string().describe("Id of the row to update.") });
129
+ const querySchema = import_zod.z.object({
130
+ id: import_zod.z.string().describe("Id of the row to fetch.")
131
+ });
96
132
  const queryListWithSchema = queryListSchema(
97
133
  import_zod.z.object({}).catchall(import_zod.z.unknown())
98
134
  );
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ai0x0/utils",
3
- "version": "0.2.0",
3
+ "version": "0.3.0",
4
4
  "description": "AI0x0 utils",
5
5
  "keywords": [
6
6
  "ai0x0"