@ai0x0/utils 0.0.25 → 0.0.26
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
ADDED
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
# @ai0x0/utils
|
|
2
|
+
|
|
3
|
+
AI0x0 shared utilities — backend CRUD factories for Next.js App Router + drizzle-orm, and custom ESLint rules.
|
|
4
|
+
|
|
5
|
+
## Backend (`src/backend/`)
|
|
6
|
+
|
|
7
|
+
Declarative CRUD factories on top of `next-rest-framework`, `drizzle-orm/pg-core`, `drizzle-zod`, and `zod`. Each factory returns a `RouteOperationDefinition` that plugs directly into `route({ … })`.
|
|
8
|
+
|
|
9
|
+
| Export | HTTP | Description |
|
|
10
|
+
| ------------------------ | ------ | ---------------------------------------- |
|
|
11
|
+
| `createPostOperation` | POST | Create a record |
|
|
12
|
+
| `createGetOperation` | GET | Get one record by filters |
|
|
13
|
+
| `createGetListOperation` | GET | Paginated list with filters, sort, joins |
|
|
14
|
+
| `createPutOperation` | PUT | Update a record |
|
|
15
|
+
| `createDeleteOperation` | DELETE | Delete a record |
|
|
16
|
+
| `createTableSchema` | — | Generate pg table + 5 Zod schemas |
|
|
17
|
+
|
|
18
|
+
**Built-in conventions:** base fields (`id`, `creatorId`, `editorId`, `createdAt`, `updatedAt`, `accessedAt`), ownership checks via `byCreator`, automatic date coercion, pagination (`current`/`pageSize`/`orderBy`/`orderDir`), list filtering with `ILIKE`, `IN`, `jsonb` array matching, and relation joins.
|
|
19
|
+
|
|
20
|
+
See [SKILL.md](./SKILL.md) for detailed workflow, setup, and escape hatches.
|
|
21
|
+
|
|
22
|
+
## ESLint Rules (`eslint-rules/`)
|
|
23
|
+
|
|
24
|
+
Custom ESLint 9 flat-config rules ported from production projects. All enabled via `configs.recommended`:
|
|
25
|
+
|
|
26
|
+
```js
|
|
27
|
+
// eslint.config.js
|
|
28
|
+
import localPlugin from "./eslint-rules/index.js";
|
|
29
|
+
|
|
30
|
+
export default [
|
|
31
|
+
localPlugin.configs.recommended,
|
|
32
|
+
// ... other config
|
|
33
|
+
];
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
| Rule | Description |
|
|
37
|
+
| ------------------------- | --------------------------------------- |
|
|
38
|
+
| `no-hardcoded-style` | Forbid hardcoded style values |
|
|
39
|
+
| `no-one-letter-vars` | Forbid single-letter variable names |
|
|
40
|
+
| `no-then` | Prefer `async/await` over `.then()` |
|
|
41
|
+
| `no-antd-space` | Use `<Flex>` instead of `<Space>` |
|
|
42
|
+
| `require-pro-components` | Require ProComponents usage |
|
|
43
|
+
| `require-section-divider` | Large files need `===` comment dividers |
|
|
44
|
+
| `no-consecutive-setstate` | Merge consecutive `setState` calls |
|
|
45
|
+
| `no-use-request-run` | Forbid `useRequest.run()` |
|
|
46
|
+
| `require-use-form` | Use `useForm()` for form state |
|
|
47
|
+
| `require-form-convention` | Form naming conventions |
|
|
48
|
+
|
|
49
|
+
## Installation
|
|
50
|
+
|
|
51
|
+
```bash
|
|
52
|
+
pnpm add @ai0x0/utils
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
Peer dependencies: `drizzle-orm ^0.45.x`, `drizzle-zod ^0.8.x`, `zod ^4.x`.
|
|
56
|
+
|
|
57
|
+
## Docs
|
|
58
|
+
|
|
59
|
+
- [SKILL.md](./SKILL.md) — full backend CRUD workflow and API reference
|
|
@@ -84,8 +84,8 @@ export function getListQuery(_ref) {
|
|
|
84
84
|
}).map(function (_ref6) {
|
|
85
85
|
var table = _ref6.table;
|
|
86
86
|
return table;
|
|
87
|
-
})) || []).find(function (
|
|
88
|
-
return
|
|
87
|
+
})) || []).find(function (table) {
|
|
88
|
+
return table[key];
|
|
89
89
|
})) === null || _concat$find === void 0 ? void 0 : _concat$find[key];
|
|
90
90
|
}
|
|
91
91
|
|
|
@@ -96,8 +96,8 @@ export function getListQuery(_ref) {
|
|
|
96
96
|
if (typeof value === "string") {
|
|
97
97
|
if (value.includes(",")) {
|
|
98
98
|
// 处理多值
|
|
99
|
-
var values = value.split(",").map(function (
|
|
100
|
-
return
|
|
99
|
+
var values = value.split(",").map(function (val) {
|
|
100
|
+
return val.trim();
|
|
101
101
|
}).filter(Boolean);
|
|
102
102
|
if (values.length > 0) {
|
|
103
103
|
if (isJsonArray) {
|
|
@@ -106,8 +106,8 @@ export function getListQuery(_ref) {
|
|
|
106
106
|
} else if (isIdField) {
|
|
107
107
|
conditions.push(inArray(targetColumn, values));
|
|
108
108
|
} else {
|
|
109
|
-
conditions.push(or.apply(void 0, _toConsumableArray(values.map(function (
|
|
110
|
-
return ilike(targetColumn, "%".concat(
|
|
109
|
+
conditions.push(or.apply(void 0, _toConsumableArray(values.map(function (val) {
|
|
110
|
+
return ilike(targetColumn, "%".concat(val, "%"));
|
|
111
111
|
}))));
|
|
112
112
|
}
|
|
113
113
|
}
|
|
@@ -58,14 +58,14 @@ function getListQuery({
|
|
|
58
58
|
var _a;
|
|
59
59
|
return (_a = [table2].concat(
|
|
60
60
|
(relations2 == null ? void 0 : relations2.filter(({ table: table3 }) => table3).map(({ table: table3 }) => table3)) || []
|
|
61
|
-
).find((
|
|
61
|
+
).find((table3) => table3[key])) == null ? void 0 : _a[key];
|
|
62
62
|
}
|
|
63
63
|
function addCondition(conditions2, key, value, targetColumn) {
|
|
64
64
|
const isIdField = /id/i.test(key);
|
|
65
65
|
const isJsonArray = jsonArrayFields == null ? void 0 : jsonArrayFields.includes(key);
|
|
66
66
|
if (typeof value === "string") {
|
|
67
67
|
if (value.includes(",")) {
|
|
68
|
-
const values = value.split(",").map((
|
|
68
|
+
const values = value.split(",").map((val) => val.trim()).filter(Boolean);
|
|
69
69
|
if (values.length > 0) {
|
|
70
70
|
if (isJsonArray) {
|
|
71
71
|
conditions2.push(
|
|
@@ -81,7 +81,7 @@ function getListQuery({
|
|
|
81
81
|
} else {
|
|
82
82
|
conditions2.push(
|
|
83
83
|
(0, import_drizzle_orm.or)(
|
|
84
|
-
...values.map((
|
|
84
|
+
...values.map((val) => (0, import_drizzle_orm.ilike)(targetColumn, `%${val}%`))
|
|
85
85
|
)
|
|
86
86
|
);
|
|
87
87
|
}
|