Skip to content

Commit d2cbc22

Browse files
committed
refactor: update GObject import handling and enhance build process for better compatibility
1 parent 8685a65 commit d2cbc22

15 files changed

Lines changed: 149 additions & 156 deletions

build/plugins/gobject-decorator.ts

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,18 @@ export const gobjectDecorator: Plugin = {
88
name: 'gobject-decorator',
99
setup(ctx) {
1010
ctx.onLoad({ filter: /\.ts$/ }, (args) => {
11-
const source = readFileSync(args.path, 'utf8');
12-
if (!source.includes('@GObject.registerClass')) return undefined;
11+
const original = readFileSync(args.path, 'utf8');
12+
let source = original;
13+
14+
// GJS requires a default import for GObject, but Aurora often uses namespace import.
15+
// Rewrite "import * as GObject" to "import GObject" to ensure clean output.
16+
if (source.includes('@girs/gobject-2.0')) {
17+
source = source.replace(/import\s+\*\s+as\s+GObject\s+from\s+['"]@girs\/gobject-2\.0['"];?/g, "import GObject from '@girs/gobject-2.0';");
18+
}
19+
20+
if (!source.includes('@GObject.registerClass')) {
21+
return source !== original ? { contents: source, loader: 'ts' } : undefined;
22+
}
1323
return { contents: transformGObjectDecorators(source), loader: 'ts' };
1424
});
1525
},

esbuild.ts

Lines changed: 41 additions & 88 deletions
Original file line numberDiff line numberDiff line change
@@ -1,108 +1,61 @@
11
import { build } from 'esbuild';
2-
import {
3-
copyFileSync,
4-
readFileSync,
5-
readdirSync,
6-
writeFileSync,
7-
existsSync,
8-
} from 'node:fs';
2+
import { copyFileSync, readFileSync, readdirSync, writeFileSync } from 'node:fs';
93
import { dirname, join, resolve } from 'node:path';
104
import { fileURLToPath } from 'node:url';
11-
import AdmZip from 'adm-zip';
12-
import { format } from 'prettier';
5+
import { format, resolveConfig } from 'prettier';
136

147
import { localExternals } from './build/plugins/local-externals.ts';
158
import { createGirsResolver } from './build/plugins/girs-resolver.ts';
169
import { gobjectDecorator } from './build/plugins/gobject-decorator.ts';
1710
import { addBlankLinesBetweenMembers } from './build/formatting.ts';
1811

19-
interface ExtensionMetadata {
20-
name: string;
21-
version: string;
22-
uuid: string;
23-
}
24-
2512
const currentDir = dirname(fileURLToPath(import.meta.url));
26-
const metadataPath = resolve(currentDir, 'metadata.json');
27-
const metadata = JSON.parse(readFileSync(metadataPath, 'utf8')) as ExtensionMetadata;
2813

2914
const srcDir = resolve(currentDir, 'src');
3015
const entryPoints = (readdirSync(srcDir, { recursive: true }) as string[])
3116
.filter((file) => file.endsWith('.ts') && !file.endsWith('.d.ts'))
3217
.map((file) => join('src', file));
3318

34-
console.debug(`Building ${metadata.name} v${metadata.version}...`);
35-
36-
const sharedOptions = {
37-
outdir: 'dist',
38-
outbase: 'src',
39-
bundle: true,
40-
plugins: [gobjectDecorator, localExternals, createGirsResolver(currentDir)],
41-
// Do not remove the functions `enable()`, `disable()` and `init()`
42-
treeShaking: false,
43-
// firefox60 // Since GJS 1.53.90
44-
// firefox68 // Since GJS 1.63.90
45-
// firefox78 // Since GJS 1.65.90
46-
// firefox91 // Since GJS 1.71.1
47-
// firefox102 // Since GJS 1.73.2
48-
target: 'firefox102' as const,
49-
format: 'esm' as const,
50-
external: ['gi://*', 'resource://*', 'system', 'gettext', 'cairo'],
51-
};
52-
53-
Promise.all(
54-
entryPoints.map((entryPoint) =>
55-
build({ ...sharedOptions, entryPoints: [entryPoint] }),
56-
),
57-
)
58-
.then(async () => {
59-
const distDir = resolve(currentDir, 'dist');
60-
const metaDist = resolve(distDir, 'metadata.json');
61-
const schemasSrc = resolve(currentDir, 'schemas');
62-
const styleFiles = [
63-
'stylesheet.css',
64-
'stylesheet-light.css',
65-
'stylesheet-dark.css',
66-
];
67-
const zipFilename = `${metadata.uuid}.zip`;
68-
const zipDist = resolve(distDir, zipFilename);
69-
70-
// Format output files with prettier
71-
const jsFiles = (readdirSync(distDir, { recursive: true }) as string[])
72-
.filter((file) => file.endsWith('.js'));
73-
74-
for (const file of jsFiles) {
75-
const filePath = resolve(distDir, file);
76-
const content = readFileSync(filePath, 'utf8');
77-
const formatted = await format(content, { parser: 'babel', filepath: filePath });
78-
writeFileSync(filePath, addBlankLinesBetweenMembers(formatted));
79-
}
19+
console.debug('Building extension...');
20+
21+
try {
22+
await build({
23+
entryPoints,
24+
outdir: 'dist',
25+
outbase: 'src',
26+
bundle: true,
27+
plugins: [gobjectDecorator, localExternals, createGirsResolver(currentDir)],
28+
treeShaking: false,
29+
target: 'firefox102',
30+
format: 'esm',
31+
external: ['gi://*', 'resource://*', 'system', 'gettext', 'cairo'],
32+
});
8033

81-
copyFileSync(metadataPath, metaDist);
34+
const distDir = resolve(currentDir, 'dist');
35+
const jsFiles = (readdirSync(distDir, { recursive: true }) as string[])
36+
.filter((file) => file.endsWith('.js'));
37+
38+
console.debug('Formatting output files...');
39+
40+
for (const file of jsFiles) {
41+
const filePath = resolve(distDir, file);
42+
const content = readFileSync(filePath, 'utf8');
43+
44+
const prettierConfig = await resolveConfig(filePath) || {};
45+
46+
const formatted = await format(content, {
47+
...prettierConfig,
48+
parser: 'babel',
49+
filepath: filePath
50+
});
8251

83-
const zip: AdmZip = new AdmZip();
52+
writeFileSync(filePath, addBlankLinesBetweenMembers(formatted));
53+
}
8454

85-
for (const file of jsFiles) {
86-
const filePath = resolve(distDir, file);
87-
const dir = dirname(file);
88-
zip.addLocalFile(filePath, dir === '.' ? '' : dir);
89-
}
55+
copyFileSync(resolve(currentDir, 'metadata.json'), resolve(distDir, 'metadata.json'));
9056

91-
styleFiles.forEach((styleFile) => {
92-
const stylePath = resolve(distDir, styleFile);
93-
if (existsSync(stylePath)) {
94-
zip.addLocalFile(stylePath);
95-
}
96-
});
97-
zip.addLocalFile(metaDist);
98-
if (existsSync(schemasSrc)) {
99-
zip.addLocalFolder(schemasSrc, 'schemas');
100-
}
101-
zip.writeZip(zipDist);
102-
103-
console.debug(`Build complete. Zip file: ${zipFilename}`);
104-
})
105-
.catch((error: unknown) => {
106-
console.error('Build failed:', error);
107-
process.exit(1);
108-
});
57+
console.debug('Build complete.');
58+
} catch (error) {
59+
console.error('Build failed:', error);
60+
process.exit(1);
61+
}

eslint.config.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ export default [
1717
process: 'readonly',
1818
imports: 'readonly',
1919
globalThis: 'readonly',
20+
global: 'readonly',
2021
},
2122
parserOptions: {
2223
tsconfigRootDir: import.meta.dirname,

justfile

Lines changed: 10 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -3,68 +3,62 @@ ext_dir := env("HOME") / ".local/share/gnome-shell/extensions" / uuid
33
toolbox_name := "gnome-shell-devel"
44
toolbox_image := "registry.fedoraproject.org/fedora-toolbox:42"
55

6-
# List available commands
76
default:
87
@just --list
98

10-
# Install dependencies
119
deps:
1210
yarn install
1311

14-
# Build everything (CSS + TypeScript + zip)
1512
build: deps
1613
yarn build
1714

18-
# Type-check without emitting
15+
package:
16+
mkdir -p dist/target
17+
cp metadata.json dist/metadata.json
18+
cd dist && \
19+
zip -r "target/{{ uuid }}.zip" . \
20+
-x "target/*" \
21+
-x "*.zip"
22+
1923
validate:
2024
yarn validate
2125

22-
# Lint the codebase
2326
lint:
2427
yarn lint
2528

26-
# Watch SCSS files for changes
2729
watch:
2830
yarn watch:css
2931

30-
# Install extension to GNOME Shell
31-
install: build
32+
install: build package
3233
mkdir -p {{ ext_dir }}
3334
rsync -a --exclude='*.zip' dist/ {{ ext_dir }}/
3435
cp -r schemas {{ ext_dir }}/ 2>/dev/null || true
3536
glib-compile-schemas {{ ext_dir }}/schemas/ 2>/dev/null || true
3637
@echo "Installed at: {{ ext_dir }}"
3738

38-
# Uninstall extension
3939
uninstall:
4040
gnome-extensions disable {{ uuid }} 2>/dev/null || true
4141
rm -rf {{ ext_dir }}
4242
@echo "Uninstalled."
4343

44-
# Quick update (rebuild + copy files, no full install)
4544
quick: build
4645
rsync -a --exclude='*.zip' dist/ {{ ext_dir }}/
4746
cp -r schemas {{ ext_dir }}/ 2>/dev/null || true
4847
glib-compile-schemas {{ ext_dir }}/schemas/ 2>/dev/null || true
4948
@echo "Files updated. Log out and back in to apply."
5049

51-
# Show recent extension logs
5250
logs:
53-
journalctl -b 0 /usr/bin/gnome-shell | grep "Aurora Shell" | tail -n 20
51+
journalctl -b 0 /usr/bin/gnome-shell | grep "aurora"
5452

55-
# Clean build artifacts
5653
clean:
5754
rm -rf dist
5855

59-
# Full clean (artifacts + dependencies)
6056
distclean: clean
6157
rm -rf node_modules
6258

63-
# Clean build + install
6459
all: clean build install
6560
@echo "Complete installation finished."
6661

67-
# Run GNOME Shell with the extension (auto-detects --devkit or --nested)
6862
run: install
6963
#!/usr/bin/env bash
7064
set -e
@@ -78,7 +72,6 @@ run: install
7872
fi
7973
env XDG_CURRENT_DESKTOP=GNOME dbus-run-session gnome-shell "$mode"
8074
81-
# Run GNOME Shell with the extension inside a toolbox (auto-detects --devkit or --nested)
8275
toolbox-run: install
8376
#!/usr/bin/env bash
8477
set -e
@@ -93,7 +86,6 @@ toolbox-run: install
9386
toolbox --container {{ toolbox_name }} run \
9487
env XDG_CURRENT_DESKTOP=GNOME dbus-run-session gnome-shell "$mode"
9588
96-
# Create development toolbox for testing
9789
create-toolbox:
9890
toolbox create --image {{ toolbox_image }} {{ toolbox_name }}
9991
toolbox run --container {{ toolbox_name }} sudo dnf install -y gnome-shell glib2-devel

metadata.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"name": "Aurora Shell",
33
"description": "A customizable GNOME Shell extension that enhances the user experience with various modules and features.",
4-
"version": "49",
4+
"version": "49.2",
55
"uuid": "aurora-shell@luminusos.github.io",
66
"url": "https://github.com/luminusOS/aurora-shell",
77
"settings-schema": "org.gnome.shell.extensions.aurora-shell",

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
"private": true,
88
"scripts": {
99
"clear": "rm -rf dist",
10-
"build:ts": "tsx esbuild.ts",
10+
"build:ts": "npx tsc --noEmit && npx eslint src/ && tsx esbuild.ts",
1111
"build:css": "tsx sass.config.ts",
1212
"build": "yarn clear && yarn build:css && yarn build:ts",
1313
"lint": "cross-env NODE_OPTIONS=--import=tsx/esm eslint .",

src/extension.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11

22
import '@girs/gjs';
33

4-
import Gio from "@girs/gio-2.0";
4+
import type Gio from "@girs/gio-2.0";
55
import { Extension } from "@girs/gnome-shell/extensions/extension";
66

77
import type { Module } from "./module.ts";
@@ -41,6 +41,7 @@ export default class AuroraShellExtension extends Extension {
4141
private _initializeModules(): void {
4242
for (const def of MODULE_REGISTRY) {
4343
if (this._settings?.get_boolean(def.settingsKey)) {
44+
// @ts-ignore
4445
this._modules.set(def.key, MODULE_FACTORIES[def.key]());
4546
}
4647
}
@@ -67,6 +68,7 @@ export default class AuroraShellExtension extends Extension {
6768
}
6869
args.push(this);
6970

71+
// @ts-ignore
7072
this._settings.connectObject(...args);
7173
}
7274

@@ -77,6 +79,7 @@ export default class AuroraShellExtension extends Extension {
7779
if (enabled && !existing) {
7880
console.log(`Aurora Shell: Enabling module ${def.key}`);
7981
try {
82+
// @ts-ignore
8083
const module = MODULE_FACTORIES[def.key]();
8184
module.enable();
8285
this._modules.set(def.key, module);
@@ -97,6 +100,7 @@ export default class AuroraShellExtension extends Extension {
97100
override disable(): void {
98101
console.log('Aurora Shell: Disabling extension');
99102

103+
// @ts-ignore
100104
this._settings?.disconnectObject(this);
101105

102106
for (const [name, module] of this._modules) {

0 commit comments

Comments
 (0)