@lobehub/lobehub 2.0.0-next.126 → 2.0.0-next.128
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/.env.example +23 -3
- package/.env.example.development +5 -0
- package/CHANGELOG.md +50 -0
- package/changelog/v1.json +18 -0
- package/docker-compose/local/docker-compose.yml +24 -1
- package/docker-compose/local/logto/docker-compose.yml +25 -2
- package/docker-compose.development.yml +6 -0
- package/locales/ar/auth.json +114 -1
- package/locales/bg-BG/auth.json +114 -1
- package/locales/de-DE/auth.json +114 -1
- package/locales/en-US/auth.json +42 -22
- package/locales/es-ES/auth.json +114 -1
- package/locales/fa-IR/auth.json +114 -1
- package/locales/fr-FR/auth.json +114 -1
- package/locales/it-IT/auth.json +114 -1
- package/locales/ja-JP/auth.json +114 -1
- package/locales/ko-KR/auth.json +114 -1
- package/locales/nl-NL/auth.json +114 -1
- package/locales/pl-PL/auth.json +114 -1
- package/locales/pt-BR/auth.json +114 -1
- package/locales/ru-RU/auth.json +114 -1
- package/locales/tr-TR/auth.json +114 -1
- package/locales/vi-VN/auth.json +114 -1
- package/locales/zh-CN/auth.json +36 -29
- package/locales/zh-TW/auth.json +114 -1
- package/package.json +4 -1
- package/packages/database/src/client/db.ts +21 -21
- package/packages/database/src/repositories/dataImporter/deprecated/index.ts +5 -5
- package/packages/database/src/repositories/dataImporter/index.ts +59 -59
- package/packages/database/src/schemas/generation.ts +16 -16
- package/packages/database/src/schemas/oidc.ts +36 -36
- package/packages/model-runtime/src/providers/newapi/index.ts +61 -18
- package/packages/model-runtime/src/runtimeMap.ts +1 -0
- package/src/app/[variants]/(main)/settings/provider/features/ProviderConfig/UpdateProviderInfo/SettingModal.tsx +10 -6
- package/src/envs/auth.test.ts +60 -0
- package/src/envs/auth.ts +3 -3
- package/src/envs/redis.ts +106 -0
- package/src/libs/redis/index.ts +5 -0
- package/src/libs/redis/manager.test.ts +107 -0
- package/src/libs/redis/manager.ts +56 -0
- package/src/libs/redis/redis.test.ts +158 -0
- package/src/libs/redis/redis.ts +117 -0
- package/src/libs/redis/types.ts +71 -0
- package/src/libs/redis/upstash.test.ts +154 -0
- package/src/libs/redis/upstash.ts +109 -0
- package/src/libs/redis/utils.test.ts +46 -0
- package/src/libs/redis/utils.ts +53 -0
- package/.github/workflows/check-console-log.yml +0 -117
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { describe, expect, it } from 'vitest';
|
|
2
|
+
|
|
3
|
+
import {
|
|
4
|
+
buildIORedisSetArgs,
|
|
5
|
+
buildUpstashSetOptions,
|
|
6
|
+
normalizeMsetValues,
|
|
7
|
+
normalizeRedisKey,
|
|
8
|
+
normalizeRedisKeys,
|
|
9
|
+
} from './utils';
|
|
10
|
+
|
|
11
|
+
describe('redis utils', () => {
|
|
12
|
+
it('normalizes single redis key to string', () => {
|
|
13
|
+
expect(normalizeRedisKey('foo')).toBe('foo');
|
|
14
|
+
expect(normalizeRedisKey(Buffer.from('bar'))).toBe('bar');
|
|
15
|
+
});
|
|
16
|
+
|
|
17
|
+
it('normalizes an array of redis keys', () => {
|
|
18
|
+
expect(normalizeRedisKeys(['foo', Buffer.from('bar')])).toEqual(['foo', 'bar']);
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
it('normalizes mset values from Map', () => {
|
|
22
|
+
const payload = normalizeMsetValues(
|
|
23
|
+
new Map<Buffer | string, number>([
|
|
24
|
+
[Buffer.from('a'), 1],
|
|
25
|
+
['b', 2],
|
|
26
|
+
]),
|
|
27
|
+
);
|
|
28
|
+
|
|
29
|
+
expect(payload).toEqual({ a: 1, b: 2 });
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
it('builds ioredis set arguments', () => {
|
|
33
|
+
const args = buildIORedisSetArgs({ ex: 1, nx: true, get: true });
|
|
34
|
+
|
|
35
|
+
expect(args).toEqual(['EX', 1, 'NX', 'GET']);
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
it('builds upstash set options', () => {
|
|
39
|
+
expect(buildUpstashSetOptions()).toBeUndefined();
|
|
40
|
+
expect(buildUpstashSetOptions({ ex: 10, nx: true, get: true })).toEqual({
|
|
41
|
+
ex: 10,
|
|
42
|
+
nx: true,
|
|
43
|
+
get: true,
|
|
44
|
+
});
|
|
45
|
+
});
|
|
46
|
+
});
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import type { SetCommandOptions } from '@upstash/redis';
|
|
2
|
+
|
|
3
|
+
import { RedisKey, RedisMSetArgument, RedisValue, SetOptions } from './types';
|
|
4
|
+
|
|
5
|
+
export const normalizeRedisKey = (key: RedisKey) =>
|
|
6
|
+
typeof key === 'string' ? key : key.toString();
|
|
7
|
+
|
|
8
|
+
export const normalizeRedisKeys = (keys: RedisKey[]) => keys.map(normalizeRedisKey);
|
|
9
|
+
|
|
10
|
+
export const normalizeMsetValues = (values: RedisMSetArgument): Record<string, RedisValue> => {
|
|
11
|
+
if (values instanceof Map) {
|
|
12
|
+
return Array.from(values.entries()).reduce<Record<string, RedisValue>>((acc, [key, value]) => {
|
|
13
|
+
acc[normalizeRedisKey(key)] = value;
|
|
14
|
+
return acc;
|
|
15
|
+
}, {});
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
return values;
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
export const buildIORedisSetArgs = (options?: SetOptions): Array<string | number> => {
|
|
22
|
+
if (!options) return [];
|
|
23
|
+
|
|
24
|
+
const args: Array<string | number> = [];
|
|
25
|
+
|
|
26
|
+
if (options.ex !== undefined) args.push('EX', options.ex);
|
|
27
|
+
if (options.px !== undefined) args.push('PX', options.px);
|
|
28
|
+
if (options.exat !== undefined) args.push('EXAT', options.exat);
|
|
29
|
+
if (options.pxat !== undefined) args.push('PXAT', options.pxat);
|
|
30
|
+
if (options.keepTtl) args.push('KEEPTTL');
|
|
31
|
+
if (options.nx) args.push('NX');
|
|
32
|
+
if (options.xx) args.push('XX');
|
|
33
|
+
if (options.get) args.push('GET');
|
|
34
|
+
|
|
35
|
+
return args;
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
export const buildUpstashSetOptions = (options?: SetOptions): SetCommandOptions | undefined => {
|
|
39
|
+
if (!options) return undefined;
|
|
40
|
+
|
|
41
|
+
const mapped: Partial<SetCommandOptions> = {};
|
|
42
|
+
|
|
43
|
+
if (options.ex !== undefined) mapped.ex = options.ex;
|
|
44
|
+
if (options.px !== undefined) mapped.px = options.px;
|
|
45
|
+
if (options.exat !== undefined) mapped.exat = options.exat;
|
|
46
|
+
if (options.pxat !== undefined) mapped.pxat = options.pxat;
|
|
47
|
+
if (options.keepTtl) mapped.keepTtl = true;
|
|
48
|
+
if (options.nx) mapped.nx = true;
|
|
49
|
+
if (options.xx) mapped.xx = true;
|
|
50
|
+
if (options.get) mapped.get = true;
|
|
51
|
+
|
|
52
|
+
return Object.keys(mapped).length ? (mapped as SetCommandOptions) : undefined;
|
|
53
|
+
};
|
|
@@ -1,117 +0,0 @@
|
|
|
1
|
-
name: Check Console Log (Warning)
|
|
2
|
-
|
|
3
|
-
on:
|
|
4
|
-
pull_request:
|
|
5
|
-
branches:
|
|
6
|
-
- main
|
|
7
|
-
- next
|
|
8
|
-
|
|
9
|
-
permissions:
|
|
10
|
-
contents: read
|
|
11
|
-
pull-requests: write
|
|
12
|
-
|
|
13
|
-
jobs:
|
|
14
|
-
check-console-log:
|
|
15
|
-
name: Check for console.log statements (non-blocking)
|
|
16
|
-
runs-on: ubuntu-latest
|
|
17
|
-
|
|
18
|
-
steps:
|
|
19
|
-
- uses: actions/checkout@v5
|
|
20
|
-
|
|
21
|
-
- name: Install bun
|
|
22
|
-
uses: oven-sh/setup-bun@v2
|
|
23
|
-
|
|
24
|
-
- name: Run console.log check
|
|
25
|
-
id: check
|
|
26
|
-
run: |
|
|
27
|
-
OUTPUT=$(bunx tsx scripts/checkConsoleLog.mts 2>&1)
|
|
28
|
-
echo "$OUTPUT"
|
|
29
|
-
|
|
30
|
-
# Save output to file for later use
|
|
31
|
-
echo "$OUTPUT" > /tmp/console-log-output.txt
|
|
32
|
-
|
|
33
|
-
# Check if violations were found
|
|
34
|
-
if echo "$OUTPUT" | grep -q "Total violations:"; then
|
|
35
|
-
echo "has_violations=true" >> $GITHUB_OUTPUT
|
|
36
|
-
TOTAL=$(echo "$OUTPUT" | grep -oP "Total violations: \K\d+")
|
|
37
|
-
echo "total=$TOTAL" >> $GITHUB_OUTPUT
|
|
38
|
-
else
|
|
39
|
-
echo "has_violations=false" >> $GITHUB_OUTPUT
|
|
40
|
-
fi
|
|
41
|
-
|
|
42
|
-
- name: Comment on PR
|
|
43
|
-
if: steps.check.outputs.has_violations == 'true'
|
|
44
|
-
uses: actions/github-script@v7
|
|
45
|
-
env:
|
|
46
|
-
VIOLATION_COUNT: ${{ steps.check.outputs.total }}
|
|
47
|
-
with:
|
|
48
|
-
script: |
|
|
49
|
-
const fs = require('fs');
|
|
50
|
-
const output = fs.readFileSync('/tmp/console-log-output.txt', 'utf8');
|
|
51
|
-
const total = process.env.VIOLATION_COUNT || '0';
|
|
52
|
-
|
|
53
|
-
// Parse violations from output (format: " file:line" followed by " content")
|
|
54
|
-
const lines = output.split('\n');
|
|
55
|
-
const violations = [];
|
|
56
|
-
for (let i = 0; i < lines.length; i++) {
|
|
57
|
-
const line = lines[i];
|
|
58
|
-
// Match lines like " packages/database/src/client/db.ts:258"
|
|
59
|
-
const fileMatch = line.match(/^\s{2}(\S+:\d+)\s*$/);
|
|
60
|
-
if (fileMatch) {
|
|
61
|
-
const file = fileMatch[1];
|
|
62
|
-
const content = lines[i + 1]?.trim() || '';
|
|
63
|
-
violations.push({ file, content });
|
|
64
|
-
i++;
|
|
65
|
-
}
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
// Build comment body
|
|
69
|
-
const maxDisplay = 30;
|
|
70
|
-
let body = `## ⚠️ Console.log Check Warning\n\n`;
|
|
71
|
-
body += `Found **${total}** \`console.log\` statement(s) in this PR.\n\n`;
|
|
72
|
-
|
|
73
|
-
if (violations.length > 0) {
|
|
74
|
-
body += `<details>\n<summary>📋 Click to see violations (${Math.min(violations.length, maxDisplay)} of ${total} shown)</summary>\n\n`;
|
|
75
|
-
body += `| File | Code |\n|------|------|\n`;
|
|
76
|
-
violations.slice(0, maxDisplay).forEach(v => {
|
|
77
|
-
const escapedContent = v.content
|
|
78
|
-
.substring(0, 60)
|
|
79
|
-
.replace(/\|/g, '\\|')
|
|
80
|
-
.replace(/`/g, "'");
|
|
81
|
-
body += `| \`${v.file}\` | \`${escapedContent}${v.content.length > 60 ? '...' : ''}\` |\n`;
|
|
82
|
-
});
|
|
83
|
-
if (parseInt(total) > maxDisplay) {
|
|
84
|
-
body += `\n*...and ${parseInt(total) - maxDisplay} more violations*\n`;
|
|
85
|
-
}
|
|
86
|
-
body += `\n</details>\n\n`;
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
body += `> 💡 **Tip:** Remove \`console.log\` or add files to \`.console-log-whitelist.json\`\n`;
|
|
90
|
-
body += `> ✅ This check is **non-blocking** and won't prevent merging.`;
|
|
91
|
-
|
|
92
|
-
// Find existing comment to update instead of creating duplicates
|
|
93
|
-
const { data: comments } = await github.rest.issues.listComments({
|
|
94
|
-
owner: context.repo.owner,
|
|
95
|
-
repo: context.repo.repo,
|
|
96
|
-
issue_number: context.issue.number,
|
|
97
|
-
});
|
|
98
|
-
|
|
99
|
-
const botComment = comments.find(c =>
|
|
100
|
-
c.user.type === 'Bot' && c.body.includes('Console.log Check Warning')
|
|
101
|
-
);
|
|
102
|
-
|
|
103
|
-
if (botComment) {
|
|
104
|
-
await github.rest.issues.updateComment({
|
|
105
|
-
owner: context.repo.owner,
|
|
106
|
-
repo: context.repo.repo,
|
|
107
|
-
comment_id: botComment.id,
|
|
108
|
-
body,
|
|
109
|
-
});
|
|
110
|
-
} else {
|
|
111
|
-
await github.rest.issues.createComment({
|
|
112
|
-
owner: context.repo.owner,
|
|
113
|
-
repo: context.repo.repo,
|
|
114
|
-
issue_number: context.issue.number,
|
|
115
|
-
body,
|
|
116
|
-
});
|
|
117
|
-
}
|