comfy-pr 0.2.24 → 0.2.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.
Files changed (85) hide show
  1. package/README.md +247 -225
  2. package/index.ts +6 -0
  3. package/next-env.d.ts +5 -5
  4. package/package.json +52 -25
  5. package/src/Authors.ts +42 -48
  6. package/src/CMNodes.ts +60 -60
  7. package/src/CNRepos.ts +78 -74
  8. package/src/CRNodes.ts +27 -27
  9. package/src/CRPulls.ts +4 -4
  10. package/src/EmailTasks.ts +101 -0
  11. package/src/FORK_OWNER.ts +5 -5
  12. package/src/FORK_PREFIX.ts +5 -5
  13. package/src/FollowRules.ts +25 -25
  14. package/src/GIT_USEREMAIL.ts +5 -5
  15. package/src/GIT_USERNAME.ts +9 -9
  16. package/src/GithubIssueComments.ts +3 -3
  17. package/src/PushedBranch.ts +3 -3
  18. package/src/Totals.ts +24 -9
  19. package/src/TrackingPRs.ts +12 -12
  20. package/src/WorkerInstances.ts +89 -89
  21. package/src/addCommentAction.ts +73 -65
  22. package/src/analyzePullsStatus.ts +219 -170
  23. package/src/analyzeTotals.test.ts +5 -5
  24. package/src/analyzeTotals.ts +118 -118
  25. package/src/bypassRepos.spec.ts +10 -0
  26. package/src/bypassRepos.ts +8 -0
  27. package/src/checkComfyActivated.ts +39 -39
  28. package/src/checkPRsFailures.ts +18 -0
  29. package/src/cli.ts +40 -40
  30. package/src/clone_modify_push_Branches.ts +21 -21
  31. package/src/createComfyRegistryPRsFromCandidates.ts +55 -55
  32. package/src/createComfyRegistryPullRequests.ts +32 -22
  33. package/src/createGithubForkForRepo.ts +54 -37
  34. package/src/createGithubPullRequest.ts +157 -94
  35. package/src/createIssueComment.ts +34 -29
  36. package/src/fetchCMNodes.ts +22 -22
  37. package/src/fetchComfyRegistryNodes.ts +11 -11
  38. package/src/fetchCurrentGeoInfo.ts +6 -6
  39. package/src/fetchRelatedPullWithComments.ts +15 -15
  40. package/src/fetchRepoDescriptionMap.ts +15 -15
  41. package/src/followRuleSchema.ts +79 -76
  42. package/src/getActivatedShell.ts +18 -18
  43. package/src/getBranchWorkingDir.ts +16 -16
  44. package/src/getRepoWorkingDir.ts +5 -5
  45. package/src/ghUser.ts +9 -6
  46. package/src/index.ts +26 -22
  47. package/src/initializeFollowRules.ts +26 -26
  48. package/src/makePublishBranch.ts +58 -58
  49. package/src/makeTomlBranch.ts +53 -53
  50. package/src/makeUpdateTomlLicenseBranch.ts +245 -0
  51. package/src/matchRelatedPulls.ts +47 -60
  52. package/src/muteInstances.ts +16 -16
  53. package/src/parseIssueUrl.ts +6 -6
  54. package/src/parseOwnerRepo.ts +33 -33
  55. package/src/parsePullUrl.ts +6 -6
  56. package/src/parsePullsState.ts +6 -6
  57. package/src/parseTitleBodyOfMarkdown.ts +8 -8
  58. package/src/postSlackMessage.ts +21 -21
  59. package/src/preload.ts +30 -30
  60. package/src/pullStatusFollowSchema.ts +12 -12
  61. package/src/readTemplateTitle.ts +11 -11
  62. package/src/sendEmailAction.ts +56 -0
  63. package/src/sendGmail.ts +105 -0
  64. package/src/showFollowRuleSet.ts +12 -12
  65. package/src/summaryLastPullComment.ts +8 -8
  66. package/src/tomlFillDescription.ts +17 -17
  67. package/src/updateAuthors.ts +7 -7
  68. package/src/updateAuthorsForGithub.ts +54 -50
  69. package/src/updateAuthorsFromCNRepo.ts +30 -30
  70. package/src/updateCMNodesDuplicationWarnings.ts +56 -56
  71. package/src/updateCMRepos.ts +27 -27
  72. package/src/updateCNRepos.ts +58 -58
  73. package/src/updateCNReposCRPullsComments.ts +40 -40
  74. package/src/updateCNReposInfo.ts +58 -57
  75. package/src/updateCNReposPRCandidate.ts +85 -85
  76. package/src/updateCNReposPulls.ts +31 -28
  77. package/src/updateCNReposPullsDashboard.ts +49 -49
  78. package/src/updateCNReposRelatedPulls.ts +25 -25
  79. package/src/updateCRNodes.ts +50 -50
  80. package/src/updateCRRepos.ts +26 -26
  81. package/src/updateComfyTotals.ts +43 -43
  82. package/src/updateFollowRuleSet.ts +136 -127
  83. package/src/updateOutdatedPullsTemplates.ts +165 -160
  84. package/src/updateSlackMessages.ts +43 -43
  85. package/tailwind.config.ts +75 -20
@@ -1,160 +1,165 @@
1
- import { $elemMatch } from "@/packages/mongodb-pipeline-ts/$elemMatch";
2
- import DIE from "@snomiao/die";
3
- import pMap from "p-map";
4
- import { match } from "ts-pattern";
5
- import { $OK, TaskError, TaskOK, tsmatch } from "../packages/mongodb-pipeline-ts/Task";
6
- import { CNRepos, type CRPull } from "./CNRepos";
7
- import { $filaten, $fresh, $stale } from "./db";
8
- import { gh } from "./gh";
9
- import { parsePull } from "./gh/parsePull";
10
- import { ghUser } from "./ghUser";
11
- import { parseUrlRepoOwner } from "./parseOwnerRepo";
12
- import { readTemplate } from "./readTemplateTitle";
13
- import { notifySlackLinks } from "./slack/notifySlackLinks";
14
- import { tLog } from "./utils/tLog";
15
- if (import.meta.main) {
16
- await tLog("updateOutdatedPullsTemplates", updateOutdatedPullsTemplates);
17
- }
18
-
19
- export async function updateOutdatedPullsTemplates() {
20
- const pyproject = await readTemplate("add-toml.md");
21
- const publishcr = await readTemplate("add-action.md");
22
- const outdated_pyproject = await readTemplate("outdated/add-toml.md");
23
- const outdated_publishcr = await readTemplate("outdated/add-action.md");
24
- const outdated_pyproject_v2 = await readTemplate("outdated/add-toml-v2.md");
25
- const outdated_publishcr_v2 = await readTemplate("outdated/add-action-v2.md");
26
- const outdated_pyproject_v3 = await readTemplate("outdated/add-toml-v3.md");
27
- const outdated_publishcr_v3 = await readTemplate("outdated/add-action-v3.md");
28
- const outdated_pyproject_v4 = await readTemplate("outdated/add-toml-v4.md");
29
- const outdateTitles = [
30
- outdated_pyproject.title,
31
- outdated_publishcr.title,
32
- outdated_pyproject_v2.title,
33
- outdated_publishcr_v2.title,
34
- outdated_pyproject_v3.title,
35
- outdated_publishcr_v3.title,
36
- outdated_pyproject_v4.title,
37
- ];
38
- const outdateBodies = [
39
- outdated_pyproject.body,
40
- outdated_publishcr.body,
41
- outdated_pyproject_v2.body,
42
- outdated_publishcr_v2.body,
43
- outdated_pyproject_v3.body,
44
- outdated_publishcr_v3.body,
45
- outdated_pyproject_v4.body,
46
- ];
47
-
48
- // const templateOutdate = new Date("2024-06-13T09:02:56.630Z");
49
-
50
- await CNRepos.createIndex({
51
- "crPulls.mtime": -1,
52
- "crPulls.data.edited.error": -1,
53
- "crPulls.data.edited.mtime": -1,
54
- "crPulls.data.edited.state": -1,
55
- "crPulls.data.pull.body": -1,
56
- "crPulls.data.pull.title": -1,
57
- "crPulls.data.pull.user.login": -1,
58
- });
59
- return await pMap(
60
- CNRepos.find(
61
- $filaten({
62
- crPulls: {
63
- mtime: $fresh("1h"), // retry if update fails
64
- data: $elemMatch({
65
- edited: {
66
- mtime: $stale("30m"), // retry if update fails
67
- state: { $ne: "ok" },
68
- error: { $nin: ["up to date", "body mismatch"] },
69
- },
70
- pull: {
71
- user: { login: ghUser.login },
72
- title: { $in: outdateTitles },
73
- body: { $in: outdateBodies },
74
- },
75
- }),
76
- },
77
- }),
78
- // $filaten({
79
- // crPulls: {
80
- // data: $elemMatch({
81
- // edited: {
82
- // mtime: $stale("30m"), // retry if update fails
83
- // state: { $ne: "ok" },
84
- // error: { $nin: ["not editable", "up to date", "body mismatch"] },
85
- // },
86
- // pull: {
87
- // updated_at: {
88
- // $lte: new Date().toISOString().replace(/.\d\d\dZ/, "Z"),
89
- // },
90
- // },
91
- // }),
92
- // },
93
- // }),
94
- ),
95
- async (repo) => {
96
- const { repository } = repo;
97
- console.log("Updating PR templates for: " + repository);
98
- const crPulls = match(repo.crPulls)
99
- .with($OK, (e) => e.data)
100
- .otherwise(() => null)!;
101
-
102
- // edit CRPulls templates to latest
103
- const crPullsEdited = await pMap(
104
- crPulls,
105
- async (data, i): Promise<CRPull> => {
106
- const { pull, type } = data;
107
- const { number } = pull;
108
- if (pull.user.login !== ghUser.login) DIE("not editable");
109
- const replacement = match(pull)
110
- .with(pyproject, () => DIE("Is already latest, should never happen here"))
111
- .with(publishcr, () => DIE("Is already latest, should never happen here"))
112
- .with(outdated_pyproject, () => pyproject)
113
- .with(outdated_pyproject_v2, () => pyproject)
114
- .with(outdated_pyproject_v3, () => pyproject)
115
- .with(outdated_pyproject_v4, () => pyproject)
116
- .with(outdated_publishcr, () => publishcr)
117
- .with(outdated_publishcr_v2, () => publishcr)
118
- .with(outdated_publishcr_v3, () => publishcr)
119
- // in case author clicked some task as completed, body will be different, may cause template mismatch
120
- .otherwise(() => DIE("Template not found: " + pull.title));
121
- if (!replacement) return { ...data, edited: TaskError("Template mismatch") };
122
-
123
- const edited = await gh.issues
124
- .update({
125
- ...parseUrlRepoOwner(repository),
126
- issue_number: number,
127
- ...(pull.title === replacement.title ? {} : { title: replacement.title }),
128
- ...(pull.body === replacement.body ? {} : { body: replacement.body }),
129
- })
130
- .then(() => true as const)
131
- .then(TaskOK)
132
- .catch(TaskError);
133
- const updatedPull = (
134
- await gh.pulls.get({
135
- ...parseUrlRepoOwner(repository),
136
- pull_number: number,
137
- })
138
- ).data;
139
- await CNRepos.updateOne({ repository }, { $set: { [`crPulls.data.${i}.edited`]: edited } });
140
- return { pull: parsePull(updatedPull), type, edited };
141
- },
142
- { concurrency: 2 },
143
- )
144
- .then(TaskOK)
145
- .catch(TaskError);
146
- tsmatch(crPullsEdited)
147
- .with($OK, async ({ data }) => {
148
- await notifySlackLinks(
149
- `Updated PR body to latest template`,
150
- data.map((e) => e.pull.html_url),
151
- );
152
- })
153
- .otherwise(() => {});
154
- await CNRepos.updateOne({ repository }, { $set: { crPullsEdited } });
155
- // update outdated pr issue bodies
156
- return crPullsEdited;
157
- },
158
- { concurrency: 2 },
159
- );
160
- }
1
+ import { $elemMatch } from "@/packages/mongodb-pipeline-ts/$elemMatch";
2
+ import DIE from "@snomiao/die";
3
+ import pMap from "p-map";
4
+ import { match } from "ts-pattern";
5
+ import { $OK, TaskError, TaskOK, tsmatch } from "../packages/mongodb-pipeline-ts/Task";
6
+ import { CNRepos, type CRPull } from "./CNRepos";
7
+ import { $filaten, $fresh, $stale } from "./db";
8
+ import { gh } from "./gh";
9
+ import { parsePull } from "./gh/parsePull";
10
+ import { ghUser } from "./ghUser";
11
+ import { parseUrlRepoOwner } from "./parseOwnerRepo";
12
+ import { readTemplate } from "./readTemplateTitle";
13
+ import { notifySlackLinks } from "./slack/notifySlackLinks";
14
+ import { tLog } from "./utils/tLog";
15
+ if (import.meta.main) {
16
+ await tLog("updateOutdatedPullsTemplates", updateOutdatedPullsTemplates);
17
+ }
18
+
19
+ export async function updateOutdatedPullsTemplates() {
20
+ const pyproject = await readTemplate("add-toml.md");
21
+ const publishcr = await readTemplate("add-action.md");
22
+ const toml = await readTemplate("update-toml-license.md");
23
+ const outdated_toml = await readTemplate("outdated/update-toml-license.md");
24
+ const outdated_pyproject = await readTemplate("outdated/add-toml.md");
25
+ const outdated_publishcr = await readTemplate("outdated/add-action.md");
26
+ const outdated_pyproject_v2 = await readTemplate("outdated/add-toml-v2.md");
27
+ const outdated_publishcr_v2 = await readTemplate("outdated/add-action-v2.md");
28
+ const outdated_pyproject_v3 = await readTemplate("outdated/add-toml-v3.md");
29
+ const outdated_publishcr_v3 = await readTemplate("outdated/add-action-v3.md");
30
+ const outdated_pyproject_v4 = await readTemplate("outdated/add-toml-v4.md");
31
+ const outdateTitles = [
32
+ outdated_toml.title,
33
+ outdated_pyproject.title,
34
+ outdated_publishcr.title,
35
+ outdated_pyproject_v2.title,
36
+ outdated_publishcr_v2.title,
37
+ outdated_pyproject_v3.title,
38
+ outdated_publishcr_v3.title,
39
+ outdated_pyproject_v4.title,
40
+ ];
41
+ const outdateBodies = [
42
+ outdated_toml.body,
43
+ outdated_pyproject.body,
44
+ outdated_publishcr.body,
45
+ outdated_pyproject_v2.body,
46
+ outdated_publishcr_v2.body,
47
+ outdated_pyproject_v3.body,
48
+ outdated_publishcr_v3.body,
49
+ outdated_pyproject_v4.body,
50
+ ];
51
+
52
+ // const templateOutdate = new Date("2024-06-13T09:02:56.630Z");
53
+
54
+ await CNRepos.createIndex({
55
+ "crPulls.mtime": -1,
56
+ "crPulls.data.edited.error": -1,
57
+ "crPulls.data.edited.mtime": -1,
58
+ "crPulls.data.edited.state": -1,
59
+ "crPulls.data.pull.body": -1,
60
+ "crPulls.data.pull.title": -1,
61
+ "crPulls.data.pull.user.login": -1,
62
+ });
63
+ return await pMap(
64
+ CNRepos.find(
65
+ $filaten({
66
+ crPulls: {
67
+ mtime: $fresh("1h"), // retry if update fails
68
+ data: $elemMatch({
69
+ edited: {
70
+ mtime: $stale("30m"), // retry if update fails
71
+ state: { $ne: "ok" },
72
+ error: { $nin: ["up to date", "body mismatch"] },
73
+ },
74
+ pull: {
75
+ user: { login: ghUser.login },
76
+ title: { $in: outdateTitles },
77
+ body: { $in: outdateBodies },
78
+ },
79
+ }),
80
+ },
81
+ }),
82
+ // $filaten({
83
+ // crPulls: {
84
+ // data: $elemMatch({
85
+ // edited: {
86
+ // mtime: $stale("30m"), // retry if update fails
87
+ // state: { $ne: "ok" },
88
+ // error: { $nin: ["not editable", "up to date", "body mismatch"] },
89
+ // },
90
+ // pull: {
91
+ // updated_at: {
92
+ // $lte: new Date().toISOString().replace(/.\d\d\dZ/, "Z"),
93
+ // },
94
+ // },
95
+ // }),
96
+ // },
97
+ // }),
98
+ ),
99
+ async (repo) => {
100
+ const { repository } = repo;
101
+ console.log("Updating PR templates for: " + repository);
102
+ const crPulls = match(repo.crPulls)
103
+ .with($OK, (e) => e.data)
104
+ .otherwise(() => null)!;
105
+
106
+ // edit CRPulls templates to latest
107
+ const crPullsEdited = await pMap(
108
+ crPulls,
109
+ async (data, i): Promise<CRPull> => {
110
+ const { pull, type } = data;
111
+ const { number } = pull;
112
+ if (pull.user.login !== ghUser.login) DIE("not editable");
113
+ const replacement = match(pull)
114
+ .with(pyproject, () => DIE("Is already latest, should never happen here"))
115
+ .with(publishcr, () => DIE("Is already latest, should never happen here"))
116
+ .with(outdated_toml, () => toml)
117
+ .with(outdated_pyproject, () => pyproject)
118
+ .with(outdated_pyproject_v2, () => pyproject)
119
+ .with(outdated_pyproject_v3, () => pyproject)
120
+ .with(outdated_pyproject_v4, () => pyproject)
121
+ .with(outdated_publishcr, () => publishcr)
122
+ .with(outdated_publishcr_v2, () => publishcr)
123
+ .with(outdated_publishcr_v3, () => publishcr)
124
+ // in case author clicked some task as completed, body will be different, may cause template mismatch
125
+ .otherwise(() => DIE("Template not found: " + pull.title));
126
+ if (!replacement) return { ...data, edited: TaskError("Template mismatch") };
127
+
128
+ const edited = await gh.issues
129
+ .update({
130
+ ...parseUrlRepoOwner(repository),
131
+ issue_number: number,
132
+ ...(pull.title === replacement.title ? {} : { title: replacement.title }),
133
+ ...(pull.body === replacement.body ? {} : { body: replacement.body }),
134
+ })
135
+ .then(() => true as const)
136
+ .then(TaskOK)
137
+ .catch(TaskError);
138
+ const updatedPull = (
139
+ await gh.pulls.get({
140
+ ...parseUrlRepoOwner(repository),
141
+ pull_number: number,
142
+ })
143
+ ).data;
144
+ await CNRepos.updateOne({ repository }, { $set: { [`crPulls.data.${i}.edited`]: edited } });
145
+ return { pull: parsePull(updatedPull), type, edited };
146
+ },
147
+ { concurrency: 2 },
148
+ )
149
+ .then(TaskOK)
150
+ .catch(TaskError);
151
+ tsmatch(crPullsEdited)
152
+ .with($OK, async ({ data }) => {
153
+ await notifySlackLinks(
154
+ `Updated PR body to latest template`,
155
+ data.map((e) => e.pull.html_url),
156
+ );
157
+ })
158
+ .otherwise(() => {});
159
+ await CNRepos.updateOne({ repository }, { $set: { crPullsEdited } });
160
+ // update outdated pr issue bodies
161
+ return crPullsEdited;
162
+ },
163
+ { concurrency: 2 },
164
+ );
165
+ }
@@ -1,43 +1,43 @@
1
- import { $fresh, $stale } from "@/packages/mongodb-pipeline-ts";
2
- import { $filaten } from "@/packages/mongodb-pipeline-ts/$filaten";
3
- import pMap from "p-map";
4
- import { postSlackMessage } from "./postSlackMessage";
5
- import { SlackMsgs } from "./slack/SlackMsgs";
6
-
7
- export async function updateSlackMessages() {
8
- // send
9
- return await pMap(
10
- SlackMsgs.find(
11
- $filaten({
12
- $or: [
13
- { status: { $exists: false } },
14
- {
15
- status: { $in: ["pending last", "error"] },
16
- mtime: $stale("5m"), // try errors again after 5m
17
- },
18
- ],
19
- }),
20
- ),
21
- async ({ _id, text, last_id: last, silent }) => {
22
- await SlackMsgs.updateOne({ _id }, { $set: { status: "sending" } });
23
- // max 5 msg per 30s
24
- while (5 <= (await SlackMsgs.countDocuments({ mtime: $fresh("30s") })))
25
- await new Promise((r) => setTimeout(r, 1000));
26
- if (last) {
27
- // check if last succ
28
- const lastSent = await SlackMsgs.findOne({ _id: last });
29
- if (lastSent?.status !== "sent") {
30
- await SlackMsgs.updateOne({ _id }, { $set: { status: "pending last" } });
31
- return;
32
- }
33
- }
34
- console.log("SLACK POST MSG: " + JSON.stringify(text));
35
- if (silent) return await SlackMsgs.updateOne({ _id }, { $set: { status: "sent", mtime: new Date() } });
36
- const sent = await postSlackMessage(text)
37
- .then((e) => ({ ...e, error: undefined, status: "sent" as const }))
38
- .catch((e) => ({ error: e.message ?? String(e), status: "error" as const }));
39
- await SlackMsgs.updateOne({ _id }, { $set: { ...sent, mtime: new Date() } });
40
- },
41
- { concurrency: 2 },
42
- );
43
- }
1
+ import { $fresh, $stale } from "@/packages/mongodb-pipeline-ts";
2
+ import { $filaten } from "@/packages/mongodb-pipeline-ts/$filaten";
3
+ import pMap from "p-map";
4
+ import { postSlackMessage } from "./postSlackMessage";
5
+ import { SlackMsgs } from "./slack/SlackMsgs";
6
+
7
+ export async function updateSlackMessages() {
8
+ // send
9
+ return await pMap(
10
+ SlackMsgs.find(
11
+ $filaten({
12
+ $or: [
13
+ { status: { $exists: false } },
14
+ {
15
+ status: { $in: ["pending last", "error"] },
16
+ mtime: $stale("5m"), // try errors again after 5m
17
+ },
18
+ ],
19
+ }),
20
+ ),
21
+ async ({ _id, text, last_id: last, silent }) => {
22
+ await SlackMsgs.updateOne({ _id }, { $set: { status: "sending" } });
23
+ // max 5 msg per 30s
24
+ while (5 <= (await SlackMsgs.countDocuments({ mtime: $fresh("30s") })))
25
+ await new Promise((r) => setTimeout(r, 1000));
26
+ if (last) {
27
+ // check if last succ
28
+ const lastSent = await SlackMsgs.findOne({ _id: last });
29
+ if (lastSent?.status !== "sent") {
30
+ await SlackMsgs.updateOne({ _id }, { $set: { status: "pending last" } });
31
+ return;
32
+ }
33
+ }
34
+ console.log("SLACK POST MSG: " + JSON.stringify(text));
35
+ if (silent) return await SlackMsgs.updateOne({ _id }, { $set: { status: "sent", mtime: new Date() } });
36
+ const sent = await postSlackMessage(text)
37
+ .then((e) => ({ ...e, error: undefined, status: "sent" as const }))
38
+ .catch((e) => ({ error: e.message ?? String(e), status: "error" as const }));
39
+ await SlackMsgs.updateOne({ _id }, { $set: { ...sent, mtime: new Date() } });
40
+ },
41
+ { concurrency: 2 },
42
+ );
43
+ }
@@ -1,20 +1,75 @@
1
- import daisyui from "daisyui";
2
- import type { Config } from "tailwindcss";
3
- const config: Config = {
4
- content: [
5
- "./pages/**/*.{js,ts,jsx,tsx,mdx}",
6
- "./components/**/*.{js,ts,jsx,tsx,mdx}",
7
- "./app/**/*.{js,ts,jsx,tsx,mdx}",
8
- ],
9
- theme: {
10
- extend: {
11
- backgroundImage: {
12
- "gradient-radial": "radial-gradient(var(--tw-gradient-stops))",
13
- "gradient-conic": "conic-gradient(from 180deg at 50% 50%, var(--tw-gradient-stops))",
14
- },
15
- },
16
- },
17
- plugins: [daisyui],
18
- daisyui: { logs: false },
19
- };
20
- export default config;
1
+ import type { Config } from "tailwindcss";
2
+
3
+ const config = {
4
+ darkMode: ["class"],
5
+ content: ["./pages/**/*.{ts,tsx}", "./components/**/*.{ts,tsx}", "./app/**/*.{ts,tsx}", "./src/**/*.{ts,tsx}"],
6
+ prefix: "",
7
+ theme: {
8
+ container: {
9
+ center: true,
10
+ padding: "2rem",
11
+ screens: {
12
+ "2xl": "1400px",
13
+ },
14
+ },
15
+ extend: {
16
+ colors: {
17
+ border: "hsl(var(--border))",
18
+ input: "hsl(var(--input))",
19
+ ring: "hsl(var(--ring))",
20
+ background: "hsl(var(--background))",
21
+ foreground: "hsl(var(--foreground))",
22
+ primary: {
23
+ DEFAULT: "hsl(var(--primary))",
24
+ foreground: "hsl(var(--primary-foreground))",
25
+ },
26
+ secondary: {
27
+ DEFAULT: "hsl(var(--secondary))",
28
+ foreground: "hsl(var(--secondary-foreground))",
29
+ },
30
+ destructive: {
31
+ DEFAULT: "hsl(var(--destructive))",
32
+ foreground: "hsl(var(--destructive-foreground))",
33
+ },
34
+ muted: {
35
+ DEFAULT: "hsl(var(--muted))",
36
+ foreground: "hsl(var(--muted-foreground))",
37
+ },
38
+ accent: {
39
+ DEFAULT: "hsl(var(--accent))",
40
+ foreground: "hsl(var(--accent-foreground))",
41
+ },
42
+ popover: {
43
+ DEFAULT: "hsl(var(--popover))",
44
+ foreground: "hsl(var(--popover-foreground))",
45
+ },
46
+ card: {
47
+ DEFAULT: "hsl(var(--card))",
48
+ foreground: "hsl(var(--card-foreground))",
49
+ },
50
+ },
51
+ borderRadius: {
52
+ lg: "var(--radius)",
53
+ md: "calc(var(--radius) - 2px)",
54
+ sm: "calc(var(--radius) - 4px)",
55
+ },
56
+ keyframes: {
57
+ "accordion-down": {
58
+ from: { height: "0" },
59
+ to: { height: "var(--radix-accordion-content-height)" },
60
+ },
61
+ "accordion-up": {
62
+ from: { height: "var(--radix-accordion-content-height)" },
63
+ to: { height: "0" },
64
+ },
65
+ },
66
+ animation: {
67
+ "accordion-down": "accordion-down 0.2s ease-out",
68
+ "accordion-up": "accordion-up 0.2s ease-out",
69
+ },
70
+ },
71
+ },
72
+ plugins: [require("daisyui"), require("tailwindcss-animate")],
73
+ } satisfies Config;
74
+
75
+ export default config;