@rtorcato/repo-tooling 2.59.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/AGENTS.md +113 -0
- package/LICENSE +21 -0
- package/README.md +201 -0
- package/dist/cli/commands/doctor.js +336 -0
- package/dist/cli/commands/fix-targets.js +192 -0
- package/dist/cli/commands/fix.js +440 -0
- package/dist/cli/commands/setup-presets.js +281 -0
- package/dist/cli/commands/setup.js +501 -0
- package/dist/cli/generators/agent-rules.js +103 -0
- package/dist/cli/generators/badges.js +88 -0
- package/dist/cli/generators/build.js +216 -0
- package/dist/cli/generators/bun.js +25 -0
- package/dist/cli/generators/community-health.js +145 -0
- package/dist/cli/generators/docs-site.js +436 -0
- package/dist/cli/generators/git.js +164 -0
- package/dist/cli/generators/github-actions.js +35 -0
- package/dist/cli/generators/github-workflows.js +24 -0
- package/dist/cli/generators/gitlab-ci.js +10 -0
- package/dist/cli/generators/index.js +123 -0
- package/dist/cli/generators/linting.js +54 -0
- package/dist/cli/generators/misc.js +298 -0
- package/dist/cli/generators/nx.js +16 -0
- package/dist/cli/generators/package-json.js +317 -0
- package/dist/cli/generators/pnpm-workspace.js +126 -0
- package/dist/cli/generators/postcss.js +24 -0
- package/dist/cli/generators/readme.js +268 -0
- package/dist/cli/generators/security.js +156 -0
- package/dist/cli/generators/skills-install.js +70 -0
- package/dist/cli/generators/tailwind.js +34 -0
- package/dist/cli/generators/testing.js +88 -0
- package/dist/cli/generators/treeshake.js +148 -0
- package/dist/cli/generators/tsconfig.js +27 -0
- package/dist/cli/generators/turborepo.js +35 -0
- package/dist/cli/generators/typedoc.js +40 -0
- package/dist/cli/index.js +332 -0
- package/dist/cli/utils/copy-preset.js +98 -0
- package/dist/cli/utils/detect-language.js +22 -0
- package/dist/cli/utils/format.js +32 -0
- package/dist/cli/utils/install.js +28 -0
- package/dist/cli/utils/lockfile.js +84 -0
- package/dist/languages/js/checks.js +949 -0
- package/dist/languages/js/ci.js +251 -0
- package/dist/languages/js/fixers.js +735 -0
- package/dist/languages/registry.js +37 -0
- package/dist/languages/swift/checks.js +127 -0
- package/dist/languages/swift/ci.js +165 -0
- package/dist/languages/swift/fixers.js +102 -0
- package/dist/languages/swift/git-hooks.js +63 -0
- package/dist/languages/swift/gitignore.js +43 -0
- package/dist/languages/swift/scaffold.js +244 -0
- package/package.json +461 -0
- package/tooling/biome/README.md +90 -0
- package/tooling/biome/biome.json +63 -0
- package/tooling/bun/bunfig.toml +14 -0
- package/tooling/changesets/README.md +35 -0
- package/tooling/changesets/config.json +11 -0
- package/tooling/claude/repo-tooling.md +87 -0
- package/tooling/commitlint/commitlint.d.mts +4 -0
- package/tooling/commitlint/commitlint.mjs +40 -0
- package/tooling/cypress/cypress.config.d.mts +4 -0
- package/tooling/cypress/cypress.config.mjs +11 -0
- package/tooling/docusaurus/index.d.mts +17 -0
- package/tooling/docusaurus/index.mjs +38 -0
- package/tooling/docusaurus/sync-changelog.mjs +42 -0
- package/tooling/docusaurus/theme-tokens.css +79 -0
- package/tooling/docusaurus/theme.css +378 -0
- package/tooling/esbuild/index.d.mts +6 -0
- package/tooling/esbuild/index.mjs +102 -0
- package/tooling/eslint/base.d.mts +6 -0
- package/tooling/eslint/base.mjs +122 -0
- package/tooling/eslint/nextjs.d.mts +4 -0
- package/tooling/eslint/nextjs.mjs +22 -0
- package/tooling/eslint/types.d.ts +58 -0
- package/tooling/github-actions/workflows/cloudflare-pages.yml +42 -0
- package/tooling/github-actions/workflows/docker-publish.yml +44 -0
- package/tooling/github-actions/workflows/preview-deployments.yml +54 -0
- package/tooling/github-actions/workflows/vercel-deploy.yml +40 -0
- package/tooling/jest-presets/browser/jest-preset.d.mts +4 -0
- package/tooling/jest-presets/browser/jest-preset.mjs +14 -0
- package/tooling/jest-presets/node/jest-preset.d.mts +4 -0
- package/tooling/jest-presets/node/jest-preset.mjs +13 -0
- package/tooling/mcp/mcp.json.example +27 -0
- package/tooling/nx/nx.json +24 -0
- package/tooling/oxlint/README.md +25 -0
- package/tooling/oxlint/oxlintrc.json +28 -0
- package/tooling/playwright/playwright.config.d.mts +4 -0
- package/tooling/playwright/playwright.config.mjs +19 -0
- package/tooling/prettier/index.d.mts +4 -0
- package/tooling/prettier/index.mjs +36 -0
- package/tooling/release-please/.release-please-manifest.json +3 -0
- package/tooling/release-please/release-please-config.json +9 -0
- package/tooling/rolldown/rolldown.config.d.mts +18 -0
- package/tooling/rolldown/rolldown.config.mjs +59 -0
- package/tooling/rollup/rollup.config.d.mts +20 -0
- package/tooling/rollup/rollup.config.mjs +70 -0
- package/tooling/semantic-release/docker.d.mts +4 -0
- package/tooling/semantic-release/docker.mjs +59 -0
- package/tooling/semantic-release/github.d.mts +4 -0
- package/tooling/semantic-release/github.mjs +79 -0
- package/tooling/semantic-release/index.d.mts +4 -0
- package/tooling/semantic-release/index.mjs +80 -0
- package/tooling/swift/periphery.yml +4 -0
- package/tooling/swift/swiftlint.yml +23 -0
- package/tooling/tests/exports-resolution.d.mts +14 -0
- package/tooling/tests/exports-resolution.mjs +68 -0
- package/tooling/tests/ssr-safety.d.mts +14 -0
- package/tooling/tests/ssr-safety.mjs +53 -0
- package/tooling/tsup/index.d.mts +8 -0
- package/tooling/tsup/index.mjs +33 -0
- package/tooling/typedoc/typedoc.json +7 -0
- package/tooling/typescript/README.md +49 -0
- package/tooling/typescript/reset.d.ts +9 -0
- package/tooling/typescript/tsconfig.base.json +84 -0
- package/tooling/typescript/tsconfig.build.json +11 -0
- package/tooling/typescript/tsconfig.bun.json +9 -0
- package/tooling/typescript/tsconfig.express.json +9 -0
- package/tooling/typescript/tsconfig.next.json +20 -0
- package/tooling/typescript/tsconfig.node.json +9 -0
- package/tooling/typescript/tsconfig.react.json +15 -0
- package/tooling/typescript/tsconfig.test.json +8 -0
- package/tooling/typescript/v1/tsconfig.base.json +81 -0
- package/tooling/typescript/v1/tsconfig.express.json +9 -0
- package/tooling/typescript/v1/tsconfig.next.json +19 -0
- package/tooling/typescript/v1/tsconfig.node.json +9 -0
- package/tooling/typescript/v1/tsconfig.react.json +14 -0
- package/tooling/typescript/v1/tsconfig.test.json +8 -0
- package/tooling/vite/vite.config.d.mts +4 -0
- package/tooling/vite/vite.config.mjs +18 -0
- package/tooling/vitest/jsdom-shims.d.mts +1 -0
- package/tooling/vitest/jsdom-shims.mjs +58 -0
- package/tooling/vitest/vitest.config.d.mts +4 -0
- package/tooling/vitest/vitest.config.mjs +25 -0
- package/tooling/vitest/vitest.config.react.d.mts +4 -0
- package/tooling/vitest/vitest.config.react.mjs +27 -0
- package/tooling/vitest/vitest.setup.d.mts +1 -0
- package/tooling/vitest/vitest.setup.mjs +3 -0
|
@@ -0,0 +1,378 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared @rtorcato Docusaurus component theme (shipped by @rtorcato/repo-tooling —
|
|
3
|
+
* copy via `repo-tooling copy docusaurus-theme`).
|
|
4
|
+
*
|
|
5
|
+
* The accent-agnostic component-override sheet every sibling docs site shares:
|
|
6
|
+
* navbar, doc cards, sidebar, TOC, pagination, footer, code blocks, markdown
|
|
7
|
+
* tables, buttons, and the hardened navy dark surfaces. Every rule references
|
|
8
|
+
* the `--jt-*` / `--ifm-*` tokens from `_jt-tokens.css` (see
|
|
9
|
+
* `copy docusaurus-theme-tokens`) — it defines NO accent colours.
|
|
10
|
+
*
|
|
11
|
+
* Usage in your `src/css/custom.css`:
|
|
12
|
+
*
|
|
13
|
+
* @import "./_jt-tokens.css"; // shared design tokens
|
|
14
|
+
* @import "./theme.css"; // this file — shared component styling
|
|
15
|
+
* :root { --ifm-color-primary: #YOURHEX; --jt-accent: #YOURHEX; ... }
|
|
16
|
+
* [data-theme=dark]{ --ifm-color-primary: #YOURHEX; --jt-accent: #YOURHEX; ... }
|
|
17
|
+
* ::selection { background: rgba(R, G, B, 0.24); } // accent — keep local
|
|
18
|
+
*
|
|
19
|
+
* The single-flat mobile drawer (the `.navbar-sidebar__items` transform lock +
|
|
20
|
+
* the repo-namespaced `.xx-mobile-menu` rules) is NOT here — it ships with the
|
|
21
|
+
* Navbar/MobileSidebar swizzle files, since its class prefix is per-repo.
|
|
22
|
+
*/
|
|
23
|
+
|
|
24
|
+
/* ---------- Navbar ---------- */
|
|
25
|
+
.navbar {
|
|
26
|
+
border-bottom: 1px solid var(--jt-border);
|
|
27
|
+
box-shadow: none;
|
|
28
|
+
}
|
|
29
|
+
.navbar__link--active {
|
|
30
|
+
color: var(--jt-heading);
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
/* Configuration Reference / index cards (generated-index). Match the clean
|
|
34
|
+
"install box" look — near-page-bg fill + thin border instead of infima's dull
|
|
35
|
+
surface fill — with an accent-border hover. Full description (no one-line
|
|
36
|
+
`text--truncate` clamp) and equal card heights per row. */
|
|
37
|
+
.theme-doc-card-container {
|
|
38
|
+
height: 100%;
|
|
39
|
+
background: var(--jt-code-bg);
|
|
40
|
+
border: 1px solid var(--jt-border);
|
|
41
|
+
border-radius: 14px;
|
|
42
|
+
box-shadow: none;
|
|
43
|
+
transition:
|
|
44
|
+
border-color 0.15s ease,
|
|
45
|
+
background 0.15s ease,
|
|
46
|
+
transform 0.15s ease;
|
|
47
|
+
}
|
|
48
|
+
.theme-doc-card-container:hover {
|
|
49
|
+
background: var(--jt-surface2);
|
|
50
|
+
border-color: var(--jt-accent-border);
|
|
51
|
+
transform: translateY(-2px);
|
|
52
|
+
}
|
|
53
|
+
.theme-doc-card-description.text--truncate {
|
|
54
|
+
white-space: normal;
|
|
55
|
+
overflow: visible;
|
|
56
|
+
text-overflow: unset;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
/* ---------- Backgrounds ---------- */
|
|
60
|
+
html,
|
|
61
|
+
body,
|
|
62
|
+
#__docusaurus,
|
|
63
|
+
.main-wrapper {
|
|
64
|
+
background: var(--ifm-background-color);
|
|
65
|
+
}
|
|
66
|
+
/* Sidebar container: match page background, clean 1px right border, and
|
|
67
|
+
ensure a long sidebar list scrolls without clipping the page footer. The
|
|
68
|
+
sticky positioning + bounded height come from Infima defaults; the explicit
|
|
69
|
+
overflow rule here defends against any inner container with overflow: hidden. */
|
|
70
|
+
.theme-doc-sidebar-container {
|
|
71
|
+
background: var(--ifm-background-color) !important;
|
|
72
|
+
border-right: 1px solid var(--jt-border) !important;
|
|
73
|
+
}
|
|
74
|
+
.theme-doc-sidebar-container > div,
|
|
75
|
+
.theme-doc-sidebar-container nav,
|
|
76
|
+
.theme-doc-sidebar-menu,
|
|
77
|
+
.menu,
|
|
78
|
+
.menu__list {
|
|
79
|
+
background: var(--ifm-background-color);
|
|
80
|
+
}
|
|
81
|
+
/* The sticky inner wrapper that holds the scrollable menu list. */
|
|
82
|
+
.theme-doc-sidebar-container > div:first-child {
|
|
83
|
+
height: 100%;
|
|
84
|
+
overflow-y: auto;
|
|
85
|
+
overscroll-behavior: contain;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
/* ---------- Sidebar ---------- */
|
|
89
|
+
.menu {
|
|
90
|
+
font-size: 14px;
|
|
91
|
+
background: transparent;
|
|
92
|
+
padding: 16px 12px;
|
|
93
|
+
}
|
|
94
|
+
.menu__list .menu__list {
|
|
95
|
+
padding-left: 8px;
|
|
96
|
+
}
|
|
97
|
+
.menu__link {
|
|
98
|
+
border-radius: 8px;
|
|
99
|
+
color: var(--jt-muted);
|
|
100
|
+
line-height: 1.4;
|
|
101
|
+
}
|
|
102
|
+
.menu__link:hover {
|
|
103
|
+
background: var(--jt-surface2);
|
|
104
|
+
color: var(--jt-heading);
|
|
105
|
+
}
|
|
106
|
+
.menu__link--active:not(.menu__link--sublist) {
|
|
107
|
+
color: var(--jt-accent);
|
|
108
|
+
background: var(--jt-accent-soft);
|
|
109
|
+
font-weight: 600;
|
|
110
|
+
}
|
|
111
|
+
.menu__list-item-collapsible .menu__link {
|
|
112
|
+
font-weight: 600;
|
|
113
|
+
color: var(--jt-heading);
|
|
114
|
+
background: transparent;
|
|
115
|
+
}
|
|
116
|
+
.menu__list-item-collapsible .menu__link--active {
|
|
117
|
+
color: var(--jt-accent);
|
|
118
|
+
background: transparent;
|
|
119
|
+
}
|
|
120
|
+
.menu__list-item-collapsible:hover {
|
|
121
|
+
background: var(--jt-surface2);
|
|
122
|
+
border-radius: 8px;
|
|
123
|
+
}
|
|
124
|
+
.menu__caret:hover {
|
|
125
|
+
background: transparent;
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
/* ---------- Table of contents ---------- */
|
|
129
|
+
.table-of-contents__link--active {
|
|
130
|
+
color: var(--jt-accent);
|
|
131
|
+
font-weight: 600;
|
|
132
|
+
}
|
|
133
|
+
.table-of-contents .table-of-contents__link:hover {
|
|
134
|
+
color: var(--jt-heading);
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
/* ---------- Pagination ---------- */
|
|
138
|
+
.pagination-nav__link {
|
|
139
|
+
border: 1px solid var(--jt-border);
|
|
140
|
+
border-radius: 8px;
|
|
141
|
+
background: var(--jt-surface);
|
|
142
|
+
}
|
|
143
|
+
.pagination-nav__link:hover {
|
|
144
|
+
border-color: var(--jt-accent-border);
|
|
145
|
+
background: var(--jt-surface2);
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
/* ---------- Footer ---------- */
|
|
149
|
+
.footer,
|
|
150
|
+
.footer--dark {
|
|
151
|
+
--ifm-footer-background-color: var(--jt-bg2);
|
|
152
|
+
--ifm-footer-color: var(--jt-text);
|
|
153
|
+
--ifm-footer-link-color: var(--jt-text);
|
|
154
|
+
--ifm-footer-title-color: var(--jt-faint);
|
|
155
|
+
border-top: 1px solid var(--jt-border);
|
|
156
|
+
}
|
|
157
|
+
.footer__title {
|
|
158
|
+
font-size: 12px;
|
|
159
|
+
font-weight: 700;
|
|
160
|
+
letter-spacing: 0.08em;
|
|
161
|
+
text-transform: uppercase;
|
|
162
|
+
color: var(--jt-faint);
|
|
163
|
+
}
|
|
164
|
+
.footer__link-item {
|
|
165
|
+
color: var(--jt-text);
|
|
166
|
+
}
|
|
167
|
+
.footer__link-item:hover {
|
|
168
|
+
color: var(--jt-accent);
|
|
169
|
+
text-decoration: none;
|
|
170
|
+
}
|
|
171
|
+
.footer__copyright {
|
|
172
|
+
color: var(--jt-faint);
|
|
173
|
+
font-size: 13px;
|
|
174
|
+
text-align: left;
|
|
175
|
+
}
|
|
176
|
+
.footer__col {
|
|
177
|
+
font-size: 14px;
|
|
178
|
+
}
|
|
179
|
+
/* Hide the external-link "↗" SVG Docusaurus auto-appends to footer href links —
|
|
180
|
+
the design uses clean text labels only. The class is CSS-module hashed
|
|
181
|
+
(iconExternalLink_<hash>), so we target by attribute prefix. */
|
|
182
|
+
.footer__link-item svg,
|
|
183
|
+
.footer__link-item [class*="iconExternalLink"] {
|
|
184
|
+
display: none;
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
/* ---------- Code ----------
|
|
188
|
+
Prism is vsDark in both light & dark mode (to match the navy aesthetic),
|
|
189
|
+
so fenced code blocks must stay dark in BOTH themes — otherwise the pale
|
|
190
|
+
vsDark tokens wash out on a light background. Inline code (the `code` pills)
|
|
191
|
+
keeps the themed --ifm-code-background and stays readable. */
|
|
192
|
+
code {
|
|
193
|
+
background: var(--jt-code-bg);
|
|
194
|
+
border: 1px solid var(--jt-border);
|
|
195
|
+
border-radius: 4px;
|
|
196
|
+
padding: 1px 6px;
|
|
197
|
+
font-size: var(--ifm-code-font-size);
|
|
198
|
+
font-family: var(--ifm-font-family-monospace);
|
|
199
|
+
}
|
|
200
|
+
.theme-code-block,
|
|
201
|
+
div[class*="codeBlockContainer"],
|
|
202
|
+
pre[class*="language-"] {
|
|
203
|
+
border: 1px solid var(--jt-border);
|
|
204
|
+
border-radius: 12px;
|
|
205
|
+
background: #0c111b !important;
|
|
206
|
+
}
|
|
207
|
+
.theme-code-block code,
|
|
208
|
+
pre[class*="language-"] code {
|
|
209
|
+
background: transparent !important;
|
|
210
|
+
border: none !important;
|
|
211
|
+
color: #dfe5ee;
|
|
212
|
+
}
|
|
213
|
+
div[class*="codeBlockTitle"] {
|
|
214
|
+
background: #0a0e16 !important;
|
|
215
|
+
color: #94a1b4 !important;
|
|
216
|
+
border-bottom: 1px solid var(--jt-border);
|
|
217
|
+
}
|
|
218
|
+
[data-theme="light"] .theme-code-block,
|
|
219
|
+
[data-theme="light"] div[class*="codeBlockContainer"],
|
|
220
|
+
[data-theme="light"] pre[class*="language-"] {
|
|
221
|
+
border-color: rgba(12, 18, 28, 0.16);
|
|
222
|
+
box-shadow: 0 8px 24px -18px rgba(12, 18, 28, 0.5);
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
/* ---------- Markdown tables ----------
|
|
226
|
+
Rounded container, horizontal row dividers only (no heavy cell gridlines). */
|
|
227
|
+
.markdown table,
|
|
228
|
+
.theme-doc-markdown table,
|
|
229
|
+
article table {
|
|
230
|
+
display: table;
|
|
231
|
+
width: 100%;
|
|
232
|
+
border-collapse: separate;
|
|
233
|
+
border-spacing: 0;
|
|
234
|
+
margin: 22px 0;
|
|
235
|
+
border: 1px solid var(--jt-border);
|
|
236
|
+
border-radius: 12px;
|
|
237
|
+
overflow: hidden;
|
|
238
|
+
font-size: 14px;
|
|
239
|
+
}
|
|
240
|
+
.markdown table thead,
|
|
241
|
+
article table thead {
|
|
242
|
+
background: var(--jt-bg2);
|
|
243
|
+
}
|
|
244
|
+
.markdown table thead tr,
|
|
245
|
+
article table thead tr {
|
|
246
|
+
border: none;
|
|
247
|
+
background: transparent;
|
|
248
|
+
}
|
|
249
|
+
.markdown table th,
|
|
250
|
+
article table th {
|
|
251
|
+
text-align: left;
|
|
252
|
+
font-weight: 700;
|
|
253
|
+
font-size: 12px;
|
|
254
|
+
letter-spacing: 0.06em;
|
|
255
|
+
text-transform: uppercase;
|
|
256
|
+
color: var(--jt-faint);
|
|
257
|
+
border: none;
|
|
258
|
+
border-bottom: 1px solid var(--jt-border);
|
|
259
|
+
padding: 14px 18px;
|
|
260
|
+
}
|
|
261
|
+
.markdown table tbody tr,
|
|
262
|
+
article table tbody tr {
|
|
263
|
+
background: transparent !important;
|
|
264
|
+
border: none;
|
|
265
|
+
}
|
|
266
|
+
.markdown table td,
|
|
267
|
+
article table td {
|
|
268
|
+
border: none;
|
|
269
|
+
border-bottom: 1px solid var(--jt-border);
|
|
270
|
+
padding: 13px 18px;
|
|
271
|
+
vertical-align: middle;
|
|
272
|
+
color: var(--jt-text);
|
|
273
|
+
}
|
|
274
|
+
.markdown table tbody tr:last-child td,
|
|
275
|
+
article table tbody tr:last-child td {
|
|
276
|
+
border-bottom: none;
|
|
277
|
+
}
|
|
278
|
+
.markdown table td:first-child,
|
|
279
|
+
article table td:first-child {
|
|
280
|
+
font-weight: 600;
|
|
281
|
+
color: var(--jt-heading);
|
|
282
|
+
white-space: nowrap;
|
|
283
|
+
}
|
|
284
|
+
.markdown table td code,
|
|
285
|
+
.markdown table th code,
|
|
286
|
+
article table td code {
|
|
287
|
+
background: transparent !important;
|
|
288
|
+
border: none !important;
|
|
289
|
+
padding: 0 !important;
|
|
290
|
+
font-size: 13px;
|
|
291
|
+
}
|
|
292
|
+
.markdown table td:nth-child(2) code,
|
|
293
|
+
article table td:nth-child(2) code {
|
|
294
|
+
color: var(--jt-accent);
|
|
295
|
+
}
|
|
296
|
+
.markdown table td:nth-child(3),
|
|
297
|
+
article table td:nth-child(3) {
|
|
298
|
+
color: var(--jt-muted);
|
|
299
|
+
line-height: 1.9;
|
|
300
|
+
}
|
|
301
|
+
.markdown table td:nth-child(3) code,
|
|
302
|
+
article table td:nth-child(3) code {
|
|
303
|
+
color: var(--jt-muted);
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
/* ---------- Buttons ---------- */
|
|
307
|
+
.button--primary {
|
|
308
|
+
background: var(--jt-accent-fill);
|
|
309
|
+
border-color: var(--jt-accent-fill);
|
|
310
|
+
color: var(--jt-on-accent);
|
|
311
|
+
font-weight: 700;
|
|
312
|
+
}
|
|
313
|
+
.button--primary:hover {
|
|
314
|
+
background: var(--ifm-color-primary-light);
|
|
315
|
+
border-color: var(--ifm-color-primary-light);
|
|
316
|
+
color: var(--jt-on-accent);
|
|
317
|
+
}
|
|
318
|
+
.button--secondary {
|
|
319
|
+
background: transparent;
|
|
320
|
+
border-color: var(--jt-border2);
|
|
321
|
+
color: var(--jt-heading);
|
|
322
|
+
}
|
|
323
|
+
|
|
324
|
+
/* ============================================================
|
|
325
|
+
HARDENED DARK SURFACES
|
|
326
|
+
Infima's dark defaults are grey (#1b1b1d) and the footer is
|
|
327
|
+
slate. These explicit overrides force the navy palette even
|
|
328
|
+
if a default loads after this file.
|
|
329
|
+
============================================================ */
|
|
330
|
+
[data-theme="dark"] {
|
|
331
|
+
--ifm-background-color: #0a0e16;
|
|
332
|
+
--ifm-background-surface-color: #111824;
|
|
333
|
+
--ifm-navbar-background-color: #0a0e16;
|
|
334
|
+
--ifm-footer-background-color: #0b101a;
|
|
335
|
+
}
|
|
336
|
+
[data-theme="dark"],
|
|
337
|
+
[data-theme="dark"] body,
|
|
338
|
+
[data-theme="dark"] #__docusaurus,
|
|
339
|
+
[data-theme="dark"] .main-wrapper,
|
|
340
|
+
[data-theme="dark"] .navbar,
|
|
341
|
+
[data-theme="dark"] main {
|
|
342
|
+
background-color: #0a0e16;
|
|
343
|
+
}
|
|
344
|
+
/* Footer follows the theme: soft grey panel in light mode, page-matching navy
|
|
345
|
+
in dark mode. Selectors are theme-scoped so the config's `style: 'dark'`
|
|
346
|
+
(which adds .footer--dark in BOTH modes) can't drag the light-mode footer
|
|
347
|
+
into a dark slate. */
|
|
348
|
+
html[data-theme="light"] .footer,
|
|
349
|
+
html[data-theme="light"] .footer--dark {
|
|
350
|
+
background-color: var(--jt-bg2) !important;
|
|
351
|
+
border-top: 1px solid var(--jt-border);
|
|
352
|
+
}
|
|
353
|
+
html[data-theme="light"] .footer__link-item {
|
|
354
|
+
color: var(--jt-text) !important;
|
|
355
|
+
}
|
|
356
|
+
html[data-theme="light"] .footer__title {
|
|
357
|
+
color: var(--jt-faint) !important;
|
|
358
|
+
}
|
|
359
|
+
html[data-theme="light"] .footer__copyright {
|
|
360
|
+
color: var(--jt-faint) !important;
|
|
361
|
+
}
|
|
362
|
+
html[data-theme="dark"] .footer,
|
|
363
|
+
html[data-theme="dark"] .footer--dark {
|
|
364
|
+
background-color: #0a0e16 !important;
|
|
365
|
+
border-top: 1px solid var(--jt-border);
|
|
366
|
+
}
|
|
367
|
+
html[data-theme="dark"] .footer__link-item {
|
|
368
|
+
color: var(--jt-text) !important;
|
|
369
|
+
}
|
|
370
|
+
html[data-theme="dark"] .footer__title {
|
|
371
|
+
color: var(--jt-faint) !important;
|
|
372
|
+
}
|
|
373
|
+
html[data-theme="dark"] .footer__copyright {
|
|
374
|
+
color: var(--jt-faint) !important;
|
|
375
|
+
}
|
|
376
|
+
.footer__link-item:hover {
|
|
377
|
+
color: var(--jt-accent) !important;
|
|
378
|
+
}
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
import * as fs from 'node:fs/promises'
|
|
2
|
+
import * as path from 'node:path'
|
|
3
|
+
import * as esbuild from 'esbuild'
|
|
4
|
+
import { nodeExternalsPlugin } from 'esbuild-node-externals'
|
|
5
|
+
|
|
6
|
+
// EXAMPLE ENTRY POINTS
|
|
7
|
+
// const folders = await getEntrypointFolders('src')
|
|
8
|
+
// const libEntryPointsArrays = await Promise.all(folders.map((folder) => getEntryPoints(folder)))
|
|
9
|
+
// const libEntryPoints = libEntryPointsArrays.flat()
|
|
10
|
+
// const allEntryPoints = [
|
|
11
|
+
// 'src/index.ts', // Main entry point
|
|
12
|
+
// ...libEntryPoints,
|
|
13
|
+
// // ...exampleEntryPoints,
|
|
14
|
+
// ]
|
|
15
|
+
|
|
16
|
+
export async function buildCode(entryPoints = []) {
|
|
17
|
+
const isProduction = process.env['NODE_ENV'] === 'production'
|
|
18
|
+
console.log(`Building...${isProduction ? '(production)' : '(development)'}`)
|
|
19
|
+
console.log('All entry points:', entryPoints)
|
|
20
|
+
if (entryPoints && entryPoints.length > 0) {
|
|
21
|
+
const buildPrefs = {
|
|
22
|
+
entryPoints: entryPoints, // Array of entry points to build
|
|
23
|
+
outdir: 'dist', // Output directory
|
|
24
|
+
platform: 'node', // Use 'browser' for browser builds
|
|
25
|
+
// outbase: 'src', // Base directory for output files
|
|
26
|
+
sourcemap: !isProduction, // Generate sourcemaps in development mode
|
|
27
|
+
minify: isProduction, // Minify in production mode
|
|
28
|
+
logLevel: 'info', // Set log level to 'info'
|
|
29
|
+
splitting: true, // Enable code splitting
|
|
30
|
+
format: 'esm', // Use 'cjs' as 'cjs' for CommonJS format
|
|
31
|
+
target: ['esnext'], // Specify ECMAScript target version
|
|
32
|
+
bundle: true, // Bundle all dependencies into the output
|
|
33
|
+
chunkNames: 'chunks/[name]-[hash]', // Define chunk naming pattern
|
|
34
|
+
// external: ['react', 'react-dom'], // Add other external dependencies here
|
|
35
|
+
// plugins: [
|
|
36
|
+
// {
|
|
37
|
+
// name: 'make-all-packages-external',
|
|
38
|
+
// setup(build) {
|
|
39
|
+
// let filter = /^[^.\/]|^\.[^.\/]|^\.\.[^\/]/; // Must not start with "/" or "./" or "../"
|
|
40
|
+
// build.onResolve({ filter }, args => ({ path: args.path, external: true }));
|
|
41
|
+
// },
|
|
42
|
+
// },
|
|
43
|
+
// ],
|
|
44
|
+
plugins: [nodeExternalsPlugin()],
|
|
45
|
+
}
|
|
46
|
+
await esbuild.build(buildPrefs)
|
|
47
|
+
} else {
|
|
48
|
+
console.log('No entry points provided. Skipping build.')
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Returns a list of entry point files in a directory.
|
|
53
|
+
*
|
|
54
|
+
* Scans the given directory and returns all files that:
|
|
55
|
+
* - End with the specified file extension (default: ".ts")
|
|
56
|
+
* - Are not test files (by default, excludes files containing ".test.")
|
|
57
|
+
*
|
|
58
|
+
* @param {string} dir - The directory to search (e.g., 'src')
|
|
59
|
+
* @param {string} [fileExtension='.ts'] - The file extension to match (e.g., '.ts', '.tsx')
|
|
60
|
+
* @param {boolean} [excludeTestFiles=true] - Whether to exclude test files (files containing '.test.')
|
|
61
|
+
* @returns {Promise<string[]>} - Array of entry point file paths (e.g., ['src/arrays/index.ts', ...])
|
|
62
|
+
*/
|
|
63
|
+
export async function getEntryPoints(dir, fileExtension = '.ts', excludeTestFiles = true) {
|
|
64
|
+
try {
|
|
65
|
+
const entries = await fs.readdir(dir, { withFileTypes: true })
|
|
66
|
+
return entries
|
|
67
|
+
.filter(
|
|
68
|
+
(entry) =>
|
|
69
|
+
entry.isFile() &&
|
|
70
|
+
entry.name.endsWith(fileExtension) &&
|
|
71
|
+
(!excludeTestFiles || !entry.name.includes('.test.'))
|
|
72
|
+
)
|
|
73
|
+
.map((entry) => path.join(dir, entry.name))
|
|
74
|
+
} catch (error) {
|
|
75
|
+
// @ts-expect-error
|
|
76
|
+
if (error.code === 'ENOENT') {
|
|
77
|
+
console.warn(`Directory ${dir} does not exist.`)
|
|
78
|
+
return []
|
|
79
|
+
}
|
|
80
|
+
throw error
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* Returns a list of all subdirectories in the given directory that contain an index.ts file.
|
|
85
|
+
* @param {string} dir - The directory to search (e.g., 'src')
|
|
86
|
+
* @returns {Promise<string[]>} - Array of entrypoint folder paths (e.g., ['src/arrays', 'src/strings'])
|
|
87
|
+
*/
|
|
88
|
+
export async function getEntrypointFolders(dir) {
|
|
89
|
+
const entries = await fs.readdir(dir, { withFileTypes: true })
|
|
90
|
+
const folders = entries.filter((e) => e.isDirectory())
|
|
91
|
+
const entryFolders = []
|
|
92
|
+
for (const folder of folders) {
|
|
93
|
+
const indexPath = path.join(dir, folder.name, 'index.ts')
|
|
94
|
+
try {
|
|
95
|
+
await fs.access(indexPath)
|
|
96
|
+
entryFolders.push(path.join(dir, folder.name))
|
|
97
|
+
} catch {
|
|
98
|
+
// index.ts does not exist, skip
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
return entryFolders
|
|
102
|
+
}
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
/// <reference types="./types.d.ts" />
|
|
2
|
+
|
|
3
|
+
import eslint from '@eslint/js'
|
|
4
|
+
import tsPlugin from '@typescript-eslint/eslint-plugin'
|
|
5
|
+
import importPlugin from 'eslint-plugin-import'
|
|
6
|
+
import jestPlugin from 'eslint-plugin-jest'
|
|
7
|
+
import tseslint from 'typescript-eslint'
|
|
8
|
+
|
|
9
|
+
// import path from 'path';
|
|
10
|
+
// import url from 'url';
|
|
11
|
+
|
|
12
|
+
// const __filename = url.fileURLToPath(import.meta.url);
|
|
13
|
+
// const __dirname = path.dirname(__filename);
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* All packages that leverage t3-env should use this rule
|
|
17
|
+
*/
|
|
18
|
+
export const restrictEnvAccess = tseslint.config({
|
|
19
|
+
files: ['**/*.js', '**/*.ts', '**/*.tsx'],
|
|
20
|
+
rules: {
|
|
21
|
+
'no-restricted-properties': [
|
|
22
|
+
'error',
|
|
23
|
+
{
|
|
24
|
+
object: 'process',
|
|
25
|
+
property: 'env',
|
|
26
|
+
message: "Use `import { env } from '~/env'` instead to ensure validated types.",
|
|
27
|
+
},
|
|
28
|
+
],
|
|
29
|
+
'no-restricted-imports': [
|
|
30
|
+
'error',
|
|
31
|
+
{
|
|
32
|
+
name: 'process',
|
|
33
|
+
importNames: ['env'],
|
|
34
|
+
message: "Use `import { env } from '~/env'` instead to ensure validated types.",
|
|
35
|
+
},
|
|
36
|
+
],
|
|
37
|
+
},
|
|
38
|
+
})
|
|
39
|
+
|
|
40
|
+
export default tseslint.config(
|
|
41
|
+
{
|
|
42
|
+
// Globally ignored files
|
|
43
|
+
ignores: [
|
|
44
|
+
//
|
|
45
|
+
'**/*.config.js',
|
|
46
|
+
'.turbo',
|
|
47
|
+
'dist',
|
|
48
|
+
'build',
|
|
49
|
+
'.react-email',
|
|
50
|
+
'not-used',
|
|
51
|
+
'out', //for next js static builds
|
|
52
|
+
'.next',
|
|
53
|
+
'pnpm-lock.yaml',
|
|
54
|
+
'node_modules',
|
|
55
|
+
'.react-email',
|
|
56
|
+
],
|
|
57
|
+
},
|
|
58
|
+
{
|
|
59
|
+
files: ['**/*.js', '**/*.ts', '**/*.tsx'],
|
|
60
|
+
plugins: {
|
|
61
|
+
import: importPlugin,
|
|
62
|
+
'@typescript-eslint': tsPlugin,
|
|
63
|
+
jest: jestPlugin,
|
|
64
|
+
},
|
|
65
|
+
extends: [
|
|
66
|
+
//
|
|
67
|
+
eslint.configs.recommended,
|
|
68
|
+
...tseslint.configs.recommended,
|
|
69
|
+
...tseslint.configs.recommendedTypeChecked,
|
|
70
|
+
...tseslint.configs.stylisticTypeChecked,
|
|
71
|
+
// ...jestPlugin.configs['flat/recommended'],
|
|
72
|
+
// turbo,
|
|
73
|
+
// vitest,
|
|
74
|
+
// airbnb,
|
|
75
|
+
// "eslint:recommended",
|
|
76
|
+
// 'airbnb-typescript',
|
|
77
|
+
// 'plugin:jest/recommended',
|
|
78
|
+
//"plugin:prettier/recommended", // Enables eslint-plugin-prettier and eslint-config-prettier. This will display prettier errors as ESLint errors. Make sure this is always the last configuration in the extends array.
|
|
79
|
+
// eslintConfigPrettier,
|
|
80
|
+
],
|
|
81
|
+
rules: {
|
|
82
|
+
'no-console': 'warn',
|
|
83
|
+
'@typescript-eslint/no-unsafe-assignment': 'error',
|
|
84
|
+
'@typescript-eslint/no-explicit-any': 'off',
|
|
85
|
+
'@typescript-eslint/consistent-type-definitions': 'off',
|
|
86
|
+
'tailwindcss/no-custom-classname': 'off',
|
|
87
|
+
'@typescript-eslint/no-unsafe-return': 'off',
|
|
88
|
+
'@typescript-eslint/no-unsafe-call': 'off',
|
|
89
|
+
'@typescript-eslint/no-unsafe-member-access': 'off',
|
|
90
|
+
// "jest/no-disabled-tests": "warn",
|
|
91
|
+
// "jest/no-focused-tests": "error",
|
|
92
|
+
// "jest/no-identical-title": "error",
|
|
93
|
+
// "jest/prefer-to-have-length": "warn",
|
|
94
|
+
// "jest/valid-expect": "error"
|
|
95
|
+
//
|
|
96
|
+
'@typescript-eslint/no-unused-vars': [
|
|
97
|
+
'error',
|
|
98
|
+
{ argsIgnorePattern: '^_', varsIgnorePattern: '^_' },
|
|
99
|
+
],
|
|
100
|
+
'@typescript-eslint/consistent-type-imports': [
|
|
101
|
+
'warn',
|
|
102
|
+
{ prefer: 'type-imports', fixStyle: 'separate-type-imports' },
|
|
103
|
+
],
|
|
104
|
+
'@typescript-eslint/no-misused-promises': [2, { checksVoidReturn: { attributes: false } }],
|
|
105
|
+
'@typescript-eslint/no-unnecessary-condition': [
|
|
106
|
+
'error',
|
|
107
|
+
{
|
|
108
|
+
allowConstantLoopConditions: true,
|
|
109
|
+
},
|
|
110
|
+
],
|
|
111
|
+
'@typescript-eslint/no-non-null-assertion': 'error',
|
|
112
|
+
'import/consistent-type-specifier-style': ['error', 'prefer-top-level'],
|
|
113
|
+
},
|
|
114
|
+
},
|
|
115
|
+
{
|
|
116
|
+
linterOptions: { reportUnusedDisableDirectives: true },
|
|
117
|
+
// languageOptions: { parserOptions: { project: ['./tsconfig.json', './**/*/tsconfig.json'] } },
|
|
118
|
+
languageOptions: {
|
|
119
|
+
parserOptions: { project: true }, //, tsconfigRootDir: __dirname
|
|
120
|
+
},
|
|
121
|
+
}
|
|
122
|
+
)
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import nextPlugin from '@next/eslint-plugin-next'
|
|
2
|
+
|
|
3
|
+
/** @type {Awaited<import('typescript-eslint').Config>} */
|
|
4
|
+
export default [
|
|
5
|
+
{
|
|
6
|
+
files: ['**/*.ts', '**/*.tsx'],
|
|
7
|
+
plugins: {
|
|
8
|
+
'@next/next': nextPlugin,
|
|
9
|
+
},
|
|
10
|
+
rules: {
|
|
11
|
+
...nextPlugin.configs.recommended.rules,
|
|
12
|
+
...nextPlugin.configs['core-web-vitals'].rules,
|
|
13
|
+
// TypeError: context.getAncestors is not a function
|
|
14
|
+
'@next/next/no-duplicate-head': 'off',
|
|
15
|
+
'@next/next/no-page-custom-font': 'off',
|
|
16
|
+
//
|
|
17
|
+
'@next/next/no-img-element': 'off',
|
|
18
|
+
'@next/next/no-html-link-for-pages': 'off',
|
|
19
|
+
'react/jsx-key': 'off',
|
|
20
|
+
},
|
|
21
|
+
},
|
|
22
|
+
]
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Since the ecosystem hasn't fully migrated to ESLint's new FlatConfig system yet,
|
|
3
|
+
* we "need" to type some of the plugins manually :(
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
declare module '@eslint/js' {
|
|
7
|
+
// Why the hell doesn't eslint themselves export their types?
|
|
8
|
+
import type { Linter } from 'eslint'
|
|
9
|
+
|
|
10
|
+
export const configs: {
|
|
11
|
+
readonly recommended: { readonly rules: Readonly<Linter.RulesRecord> }
|
|
12
|
+
readonly all: { readonly rules: Readonly<Linter.RulesRecord> }
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
declare module 'eslint-plugin-import' {
|
|
17
|
+
import type { Linter, Rule } from 'eslint'
|
|
18
|
+
|
|
19
|
+
export const configs: {
|
|
20
|
+
recommended: { rules: Linter.RulesRecord }
|
|
21
|
+
}
|
|
22
|
+
export const rules: Record<string, Rule.RuleModule>
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
declare module 'eslint-plugin-react' {
|
|
26
|
+
import type { Linter, Rule } from 'eslint'
|
|
27
|
+
|
|
28
|
+
export const configs: {
|
|
29
|
+
recommended: { rules: Linter.RulesRecord }
|
|
30
|
+
all: { rules: Linter.RulesRecord }
|
|
31
|
+
'jsx-runtime': { rules: Linter.RulesRecord }
|
|
32
|
+
}
|
|
33
|
+
export const rules: Record<string, Rule.RuleModule>
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
declare module 'eslint-plugin-react-hooks' {
|
|
37
|
+
import type { Linter, Rule } from 'eslint'
|
|
38
|
+
|
|
39
|
+
export const configs: {
|
|
40
|
+
recommended: {
|
|
41
|
+
rules: {
|
|
42
|
+
'rules-of-hooks': Linter.RuleEntry
|
|
43
|
+
'exhaustive-deps': Linter.RuleEntry
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
export const rules: Record<string, Rule.RuleModule>
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
declare module '@next/eslint-plugin-next' {
|
|
51
|
+
import type { Linter, Rule } from 'eslint'
|
|
52
|
+
|
|
53
|
+
export const configs: {
|
|
54
|
+
recommended: { rules: Linter.RulesRecord }
|
|
55
|
+
'core-web-vitals': { rules: Linter.RulesRecord }
|
|
56
|
+
}
|
|
57
|
+
export const rules: Record<string, Rule.RuleModule>
|
|
58
|
+
}
|