Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit b8f1c9f

Browse files
Migrate tools and configs to typescript, require node.js >= 22.18.0 (#35421)
Migrate all JS config and tools to TS and fix a number of type issues. This required Node.js 22.18.0 or greater where [type-stripping was enabled](https://nodejs.org/en/blog/release/v22.18.0) by default. Given that Node 22 is the current LTS, I think it's ok to assume that the user has a recent version of it. Webpack currently requires the `--disable-interpret` flag to work, should be fixed eventually with webpack/webpack-cli#4525. `fast-glob` is replaced by `fs.globSync`, available in Node 22.0.0 or greater.
1 parent 1640e9a commit b8f1c9f

14 files changed

+89
-99
lines changed

‎Dockerfile

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,9 @@ RUN apk --no-cache add \
1818
&& npm install -g pnpm@10 \
1919
&& rm -rf /var/cache/apk/*
2020

21+
# workaround for node >= 22.18.0 on alpine 3.22. Remove when upgrading to alpine 3.23
22+
COPY --from=docker.io/node:22-alpine3.22 /usr/local/bin/node /usr/local/bin/node
23+
2124
# Setup repo
2225
COPY . ${GOPATH}/src/code.gitea.io/gitea
2326
WORKDIR ${GOPATH}/src/code.gitea.io/gitea

‎Dockerfile.rootless

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,9 @@ RUN apk --no-cache add \
1818
&& npm install -g pnpm@10 \
1919
&& rm -rf /var/cache/apk/*
2020

21+
# workaround for node >= 22.18.0 on alpine 3.22. Remove when upgrading to alpine 3.23
22+
COPY --from=docker.io/node:22-alpine3.22 /usr/local/bin/node /usr/local/bin/node
23+
2124
# Setup repo
2225
COPY . ${GOPATH}/src/code.gitea.io/gitea
2326
WORKDIR ${GOPATH}/src/code.gitea.io/gitea

‎Makefile

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -127,7 +127,7 @@ GO_TEST_PACKAGES ?= $(filter-out $(shell $(GO) list code.gitea.io/gitea/models/m
127127
MIGRATE_TEST_PACKAGES ?= $(shell $(GO) list code.gitea.io/gitea/models/migrations/...)
128128

129129
WEBPACK_SOURCES := $(shell find web_src/js web_src/css -type f)
130-
WEBPACK_CONFIGS := webpack.config.js tailwind.config.js
130+
WEBPACK_CONFIGS := webpack.config.ts tailwind.config.ts
131131
WEBPACK_DEST := public/assets/js/index.js public/assets/css/index.css
132132
WEBPACK_DEST_ENTRIES := public/assets/js public/assets/css public/assets/fonts
133133

@@ -153,9 +153,9 @@ TAR_EXCLUDES := .git data indexers queues log node_modules $(EXECUTABLE) $(DIST)
153153
GO_DIRS := build cmd models modules routers services tests
154154
WEB_DIRS := web_src/js web_src/css
155155

156-
ESLINT_FILES := web_src/js tools *.js *.ts *.cjs tests/e2e
156+
ESLINT_FILES := web_src/js tools *.ts *.cjs tests/e2e
157157
STYLELINT_FILES := web_src/css web_src/js/components/*.vue
158-
SPELLCHECK_FILES := $(GO_DIRS) $(WEB_DIRS) templates options/locale/locale_en-US.ini .github $(filter-out CHANGELOG.md, $(wildcard *.go *.js *.md *.yml *.yaml *.toml)) $(filter-out tools/misspellings.csv, $(wildcard tools/*))
158+
SPELLCHECK_FILES := $(GO_DIRS) $(WEB_DIRS) templates options/locale/locale_en-US.ini .github $(filter-out CHANGELOG.md, $(wildcard *.go *.md *.yml *.yaml *.toml)) $(filter-out tools/misspellings.csv, $(wildcard tools/*))
159159
EDITORCONFIG_FILES := templates .github/workflows options/locale/locale_en-US.ini
160160

161161
GO_SOURCES := $(wildcard *.go)
@@ -407,7 +407,7 @@ lint-actions: ## lint action workflow files
407407

408408
.PHONY: lint-templates
409409
lint-templates: .venv node_modules ## lint template files
410-
@node tools/lint-templates-svg.js
410+
@node tools/lint-templates-svg.ts
411411
@uv run --frozen djlint $(shell find templates -type f -iname '*.tmpl')
412412

413413
.PHONY: lint-yaml
@@ -421,7 +421,7 @@ watch: ## watch everything and continuously rebuild
421421
.PHONY: watch-frontend
422422
watch-frontend: node-check node_modules ## watch frontend files and continuously rebuild
423423
@rm -rf $(WEBPACK_DEST_ENTRIES)
424-
NODE_ENV=development pnpm exec webpack --watch --progress
424+
NODE_ENV=development pnpm exec webpack --watch --progress --disable-interpret
425425

426426
.PHONY: watch-backend
427427
watch-backend: go-check ## watch backend files and continuously rebuild
@@ -877,13 +877,13 @@ $(WEBPACK_DEST): $(WEBPACK_SOURCES) $(WEBPACK_CONFIGS) pnpm-lock.yaml
877877
@$(MAKE) -s node-check node_modules
878878
@rm -rf $(WEBPACK_DEST_ENTRIES)
879879
@echo "Running webpack..."
880-
@BROWSERSLIST_IGNORE_OLD_DATA=true pnpm exec webpack
880+
@BROWSERSLIST_IGNORE_OLD_DATA=true pnpm exec webpack --disable-interpret
881881
@touch $(WEBPACK_DEST)
882882

883883
.PHONY: svg
884884
svg: node-check | node_modules ## build svg files
885885
rm -rf $(SVG_DEST_DIR)
886-
node tools/generate-svg.js
886+
node tools/generate-svg.ts
887887

888888
.PHONY: svg-check
889889
svg-check: svg
@@ -922,7 +922,7 @@ generate-gitignore: ## update gitignore files
922922

923923
.PHONY: generate-images
924924
generate-images: | node_modules ## generate images
925-
cd tools && node generate-images.js $(TAGS)
925+
cd tools && node generate-images.ts $(TAGS)
926926

927927
.PHONY: generate-manpage
928928
generate-manpage: ## generate manpage

‎package.json

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,8 @@
22
"type": "module",
33
"packageManager": "pnpm@10.0.0",
44
"engines": {
5-
"node": ">= 20.0.0",
6-
"pnpm": ">=10.0.0"
5+
"node": ">= 22.18.0",
6+
"pnpm": ">=10.0.0"
77
},
88
"dependencies": {
99
"@citation-js/core": "0.7.18",
@@ -31,7 +31,6 @@
3131
"dropzone": "6.0.0-beta.2",
3232
"easymde": "2.20.0",
3333
"esbuild-loader": "4.3.0",
34-
"fast-glob": "3.3.3",
3534
"htmx.org": "2.0.6",
3635
"idiomorph": "0.7.3",
3736
"jquery": "3.7.1",
@@ -110,7 +109,6 @@
110109
"stylelint-config-recommended": "17.0.0",
111110
"stylelint-declaration-block-no-ignored-properties": "2.8.0",
112111
"stylelint-declaration-strict-value": "1.10.11",
113-
"stylelint-define-config": "16.22.0",
114112
"stylelint-value-no-unknown-custom-properties": "6.0.1",
115113
"svgo": "4.0.0",
116114
"type-fest": "4.41.0",

‎pnpm-lock.yaml

Lines changed: 0 additions & 17 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

‎stylelint.config.js renamed to ‎stylelint.config.ts

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,13 @@
1-
// @ts-check
2-
import {defineConfig} from 'stylelint-define-config';
31
import {fileURLToPath} from 'node:url';
2+
import type {Config} from 'stylelint';
43

54
const cssVarFiles = [
65
fileURLToPath(new URL('web_src/css/base.css', import.meta.url)),
76
fileURLToPath(new URL('web_src/css/themes/theme-gitea-light.css', import.meta.url)),
87
fileURLToPath(new URL('web_src/css/themes/theme-gitea-dark.css', import.meta.url)),
98
];
109

11-
export default defineConfig({
10+
export default {
1211
extends: 'stylelint-config-recommended',
1312
reportUnscopedDisables: true,
1413
reportNeedlessDisables: true,
@@ -124,7 +123,6 @@ export default defineConfig({
124123
'csstools/value-no-unknown-custom-properties': [true, {importFrom: cssVarFiles}],
125124
'declaration-block-no-duplicate-properties': [true, {ignore: ['consecutive-duplicates-with-different-values']}],
126125
'declaration-block-no-redundant-longhand-properties': [true, {ignoreShorthands: ['flex-flow', 'overflow', 'grid-template']}],
127-
// @ts-expect-error - https://github.com/stylelint-types/stylelint-define-config/issues/1
128126
'declaration-property-unit-disallowed-list': {'line-height': ['em']},
129127
'declaration-property-value-disallowed-list': {'word-break': ['break-word']},
130128
'font-family-name-quotes': 'always-where-recommended',
@@ -148,4 +146,4 @@ export default defineConfig({
148146
'shorthand-property-no-redundant-values': true,
149147
'value-no-vendor-prefix': [true, {ignoreValues: ['box', 'inline-box']}],
150148
},
151-
});
149+
}satisfiesConfig;

‎tailwind.config.js renamed to ‎tailwind.config.ts

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,17 +2,18 @@ import {readFileSync} from 'node:fs';
22
import {env} from 'node:process';
33
import {parse} from 'postcss';
44
import plugin from 'tailwindcss/plugin.js';
5+
import type {Config} from 'tailwindcss';
56

67
const isProduction = env.NODE_ENV !== 'development';
78

8-
function extractRootVars(css) {
9+
function extractRootVars(css: string) {
910
const root = parse(css);
10-
const vars = new Set();
11+
const vars = new Set<string>();
1112
root.walkRules((rule) => {
1213
if (rule.selector !== ':root') return;
13-
rule.each((decl) => {
14-
if (decl.value && decl.prop.startsWith('--')) {
15-
vars.add(decl.prop.substring(2));
14+
rule.each((node) => {
15+
if (node.type==='decl'&&node.value && node.prop.startsWith('--')) {
16+
vars.add(node.prop.substring(2));
1617
}
1718
});
1819
});
@@ -120,4 +121,4 @@ export default {
120121
});
121122
}),
122123
],
123-
};
124+
}satisfiesConfig;

‎tools/generate-images.js renamed to ‎tools/generate-images.ts

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,7 @@ import {optimize} from 'svgo';
44
import {readFile, writeFile} from 'node:fs/promises';
55
import {argv, exit} from 'node:process';
66

7-
function doExit(err) {
8-
if (err) console.error(err);
9-
exit(err ? 1 : 0);
10-
}
11-
12-
async function generate(svg, path, {size, bg}) {
7+
async function generate(svg: string, path: string, {size, bg}: {size: number, bg?: boolean}) {
138
const outputFile = new URL(path, import.meta.url);
149

1510
if (String(outputFile).endsWith('.svg')) {
@@ -19,7 +14,9 @@ async function generate(svg, path, {size, bg}) {
1914
'removeDimensions',
2015
{
2116
name: 'addAttributesToSVGElement',
22-
params: {attributes: [{width: size}, {height: size}]},
17+
params: {
18+
attributes: [{width: String(size)}, {height: String(size)}],
19+
},
2320
},
2421
],
2522
});
@@ -57,7 +54,8 @@ async function main() {
5754
}
5855

5956
try {
60-
doExit(await main());
57+
await main();
6158
} catch (err) {
62-
doExit(err);
59+
console.error(err);
60+
exit(1);
6361
}

‎tools/generate-svg.js renamed to ‎tools/generate-svg.ts

Lines changed: 25 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,29 @@
11
#!/usr/bin/env node
2-
import fastGlob from 'fast-glob';
32
import {optimize} from 'svgo';
4-
import {parse} from 'node:path';
3+
import {dirname, parse} from 'node:path';
4+
import {globSync, writeFileSync} from 'node:fs';
55
import {readFile, writeFile, mkdir} from 'node:fs/promises';
66
import {fileURLToPath} from 'node:url';
77
import {exit} from 'node:process';
8-
import *asfsfrom 'node:fs';
8+
import type{Manifest}from 'material-icon-theme';
99

10-
const glob = (pattern) => fastGlob.sync(pattern, {
11-
cwd: fileURLToPath(new URL('..', import.meta.url)),
12-
absolute: true,
13-
});
10+
const glob = (pattern: string) => globSync(pattern, {cwd: dirname(import.meta.dirname)});
1411

15-
async function processAssetsSvgFile(file, {prefix, fullName} = {}) {
12+
type Opts = {
13+
prefix?: string,
14+
fullName?: string,
15+
};
16+
17+
async function processAssetsSvgFile(path: string, {prefix, fullName}: Opts = {}) {
1618
let name = fullName;
1719
if (!name) {
18-
name = parse(file).name;
20+
name = parse(path).name;
1921
if (prefix) name = `${prefix}-${name}`;
2022
if (prefix === 'octicon') name = name.replace(/-[0-9]+$/, ''); // chop of '-16' on octicons
2123
}
2224
// Set the `xmlns` attribute so that the files are displayable in standalone documents
2325
// The svg backend module will strip the attribute during startup for inline display
24-
const {data} = optimize(await readFile(file, 'utf8'), {
26+
const {data} = optimize(await readFile(path, 'utf8'), {
2527
plugins: [
2628
{name: 'preset-default'},
2729
{name: 'removeDimensions'},
@@ -41,33 +43,33 @@ async function processAssetsSvgFile(file, {prefix, fullName} = {}) {
4143
await writeFile(fileURLToPath(new URL(`../public/assets/img/svg/${name}.svg`, import.meta.url)), data);
4244
}
4345

44-
function processAssetsSvgFiles(pattern, opts) {
45-
return glob(pattern).map((file) => processAssetsSvgFile(file, opts));
46+
function processAssetsSvgFiles(pattern: string, opts: Opts={}) {
47+
return glob(pattern).map((path) => processAssetsSvgFile(path, opts));
4648
}
4749

4850
async function processMaterialFileIcons() {
49-
const files = glob('node_modules/material-icon-theme/icons/*.svg');
50-
const svgSymbols = {};
51-
for (const file of files) {
51+
const paths = glob('node_modules/material-icon-theme/icons/*.svg');
52+
const svgSymbols: Record<string,string> = {};
53+
for (const path of paths) {
5254
// remove all unnecessary attributes, only keep "viewBox"
53-
const {data} = optimize(await readFile(file, 'utf8'), {
55+
const {data} = optimize(await readFile(path, 'utf8'), {
5456
plugins: [
5557
{name: 'preset-default'},
5658
{name: 'removeDimensions'},
5759
{name: 'removeXMLNS'},
5860
{name: 'removeAttrs', params: {attrs: 'xml:space', elemSeparator: ','}},
5961
],
6062
});
61-
const svgName = parse(file).name;
63+
const svgName = parse(path).name;
6264
// intentionally use single quote here to avoid escaping
6365
svgSymbols[svgName] = data.replace(/"/g, `'`);
6466
}
65-
fs.writeFileSync(fileURLToPath(new URL(`../options/fileicon/material-icon-svgs.json`, import.meta.url)), JSON.stringify(svgSymbols, null, 2));
67+
writeFileSync(fileURLToPath(new URL(`../options/fileicon/material-icon-svgs.json`, import.meta.url)), JSON.stringify(svgSymbols, null, 2));
6668

67-
const vscodeExtensionsJson = await readFile(fileURLToPath(new URL(`generate-svg-vscode-extensions.json`, import.meta.url)));
68-
const vscodeExtensions = JSON.parse(vscodeExtensionsJson);
69-
const iconRulesJson = await readFile(fileURLToPath(new URL(`../node_modules/material-icon-theme/dist/material-icons.json`, import.meta.url)));
70-
const iconRules = JSON.parse(iconRulesJson);
69+
const vscodeExtensionsJson = await readFile(fileURLToPath(new URL(`generate-svg-vscode-extensions.json`, import.meta.url)),'utf8');
70+
const vscodeExtensions = JSON.parse(vscodeExtensionsJson)asRecord<string,string>;
71+
const iconRulesJson = await readFile(fileURLToPath(new URL(`../node_modules/material-icon-theme/dist/material-icons.json`, import.meta.url)),'utf8');
72+
const iconRules = JSON.parse(iconRulesJson)asManifest;
7173
// The rules are from VSCode material-icon-theme, we need to adjust them to our needs
7274
// 1. We only use lowercase filenames to match (it should be good enough for most cases and more efficient)
7375
// 2. We do not have a "Language ID" system:
@@ -91,7 +93,7 @@ async function processMaterialFileIcons() {
9193
}
9294
}
9395
const iconRulesPretty = JSON.stringify(iconRules, null, 2);
94-
fs.writeFileSync(fileURLToPath(new URL(`../options/fileicon/material-icon-rules.json`, import.meta.url)), iconRulesPretty);
96+
writeFileSync(fileURLToPath(new URL(`../options/fileicon/material-icon-rules.json`, import.meta.url)), iconRulesPretty);
9597
}
9698

9799
async function main() {

‎tools/lint-templates-svg.js renamed to ‎tools/lint-templates-svg.ts

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,18 @@
11
#!/usr/bin/env node
2-
import {readdirSync, readFileSync} from 'node:fs';
2+
import {readdirSync, readFileSync,globSync} from 'node:fs';
33
import {parse, relative} from 'node:path';
44
import {fileURLToPath} from 'node:url';
55
import {exit} from 'node:process';
6-
import fastGlob from 'fast-glob';
76

8-
const knownSvgs = new Set();
7+
const knownSvgs = new Set<string>();
98
for (const file of readdirSync(new URL('../public/assets/img/svg', import.meta.url))) {
109
knownSvgs.add(parse(file).name);
1110
}
1211

1312
const rootPath = fileURLToPath(new URL('..', import.meta.url));
1413
let hadErrors = false;
1514

16-
for (const file of fastGlob.sync(fileURLToPath(new URL('../templates/**/*.tmpl', import.meta.url)))) {
15+
for (const file of globSync(fileURLToPath(new URL('../templates/**/*.tmpl', import.meta.url)))) {
1716
const content = readFileSync(file, 'utf8');
1817
for (const [_, name] of content.matchAll(/svg["'`]([^"'`]+)["'`]/g)) {
1918
if (!knownSvgs.has(name)) {

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /