@gjsify/rolldown-plugin-gjsify 0.3.14 → 0.3.15
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/lib/app/gjs.d.ts +7 -2
- package/lib/app/gjs.js +10 -5
- package/lib/index.d.ts +3 -1
- package/lib/index.js +2 -1
- package/lib/plugin.d.ts +7 -2
- package/lib/plugins/shebang.d.ts +22 -0
- package/lib/plugins/shebang.js +38 -0
- package/lib/plugins/text-loader.d.ts +10 -0
- package/lib/plugins/text-loader.js +41 -0
- package/package.json +5 -5
- package/src/app/gjs.ts +17 -7
- package/src/index.ts +3 -1
- package/src/plugin.ts +7 -2
- package/src/plugins/shebang.ts +36 -0
- package/src/plugins/text-loader.ts +54 -0
package/lib/app/gjs.d.ts
CHANGED
|
@@ -19,8 +19,13 @@ export interface GjsFactoryInput {
|
|
|
19
19
|
userBanner?: string;
|
|
20
20
|
/** User-supplied resolve.alias overrides. */
|
|
21
21
|
userAliases?: Record<string, string>;
|
|
22
|
-
/**
|
|
23
|
-
|
|
22
|
+
/**
|
|
23
|
+
* Shebang to prepend to the output bundle.
|
|
24
|
+
* `true` → default `#!/usr/bin/env -S gjs -m`
|
|
25
|
+
* `false` → no shebang
|
|
26
|
+
* `"…"` → custom line, supports `${env:NAME[:-default]}` placeholders
|
|
27
|
+
*/
|
|
28
|
+
shebang?: boolean | string;
|
|
24
29
|
/** Plugin options forwarded to sub-plugins (deepkit, css, …). */
|
|
25
30
|
pluginOptions: PluginOptions;
|
|
26
31
|
}
|
package/lib/app/gjs.js
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
//
|
|
3
3
|
// Mirrors the esbuild predecessor's `setupForGjs` exactly in terms of the
|
|
4
4
|
// effective build behaviour: same externals, same alias map, same target
|
|
5
|
-
// (
|
|
5
|
+
// (firefox140 for JS, firefox60 for CSS), same console-shim injection,
|
|
6
6
|
// same process-stub banner, same `random-access-file` fs-backed-fallback.
|
|
7
7
|
//
|
|
8
8
|
// Returns a partial `RolldownOptions` template plus the plugin array the
|
|
@@ -18,7 +18,7 @@ import { globToEntryPoints } from '../utils/entry-points.js';
|
|
|
18
18
|
import { nodeModulesPathRewritePlugin, getBundleDirFromOutput, } from '../plugins/rewrite-node-modules-paths.js';
|
|
19
19
|
import { processStubPlugin } from '../plugins/process-stub.js';
|
|
20
20
|
import { cssAsStringPlugin } from '../plugins/css-as-string.js';
|
|
21
|
-
import { shebangPlugin,
|
|
21
|
+
import { shebangPlugin, resolveShebangLine } from '../plugins/shebang.js';
|
|
22
22
|
const _shimDir = dirname(fileURLToPath(import.meta.url));
|
|
23
23
|
export const setupForGjs = async (input) => {
|
|
24
24
|
const userExternal = input.userExternal ?? [];
|
|
@@ -75,8 +75,8 @@ export const setupForGjs = async (input) => {
|
|
|
75
75
|
conditionNames: format === 'esm' ? ['browser', 'import'] : ['browser', 'require', 'import'],
|
|
76
76
|
},
|
|
77
77
|
transform: {
|
|
78
|
-
// Compile target: GJS 1.86 / SpiderMonkey
|
|
79
|
-
target: '
|
|
78
|
+
// Compile target: GJS 1.86 / SpiderMonkey 140 ≈ firefox140.
|
|
79
|
+
target: 'firefox140',
|
|
80
80
|
define: {
|
|
81
81
|
global: 'globalThis',
|
|
82
82
|
window: 'globalThis',
|
|
@@ -125,7 +125,12 @@ export const setupForGjs = async (input) => {
|
|
|
125
125
|
cssAsStringPlugin(),
|
|
126
126
|
nodeModulesPathRewritePlugin({ bundleDir }),
|
|
127
127
|
processStubPlugin({ userBanner: input.userBanner }),
|
|
128
|
-
|
|
128
|
+
// resolveShebangLine returns null when disabled (false/undefined) and
|
|
129
|
+
// the resolved line otherwise — also handles `${env:…}` expansion.
|
|
130
|
+
(() => {
|
|
131
|
+
const line = resolveShebangLine(input.shebang);
|
|
132
|
+
return shebangPlugin({ enabled: line !== null, line: line ?? undefined });
|
|
133
|
+
})(),
|
|
129
134
|
];
|
|
130
135
|
return { options, plugins };
|
|
131
136
|
};
|
package/lib/index.d.ts
CHANGED
|
@@ -7,7 +7,9 @@ export type { NodeModulesPathRewriteOptions, RewriteResult, } from './plugins/re
|
|
|
7
7
|
export { processStubPlugin, GJS_PROCESS_STUB, composeBanner } from './plugins/process-stub.js';
|
|
8
8
|
export type { ProcessStubPluginOptions } from './plugins/process-stub.js';
|
|
9
9
|
export { cssAsStringPlugin } from './plugins/css-as-string.js';
|
|
10
|
-
export {
|
|
10
|
+
export { textLoaderPlugin } from './plugins/text-loader.js';
|
|
11
|
+
export type { TextLoaderPluginOptions } from './plugins/text-loader.js';
|
|
12
|
+
export { shebangPlugin, GJS_SHEBANG, expandEnvTemplate, resolveShebangLine } from './plugins/shebang.js';
|
|
11
13
|
export type { ShebangPluginOptions } from './plugins/shebang.js';
|
|
12
14
|
export { gjsImportsEmptyPlugin } from './plugins/gjs-imports-empty.js';
|
|
13
15
|
export * from './plugin.js';
|
package/lib/index.js
CHANGED
|
@@ -6,7 +6,8 @@ export * from './library/index.js';
|
|
|
6
6
|
export { REWRITE_FILTER, getBundleDirFromOutput, rewriteContents, shouldRewrite, nodeModulesPathRewritePlugin, } from './plugins/rewrite-node-modules-paths.js';
|
|
7
7
|
export { processStubPlugin, GJS_PROCESS_STUB, composeBanner } from './plugins/process-stub.js';
|
|
8
8
|
export { cssAsStringPlugin } from './plugins/css-as-string.js';
|
|
9
|
-
export {
|
|
9
|
+
export { textLoaderPlugin } from './plugins/text-loader.js';
|
|
10
|
+
export { shebangPlugin, GJS_SHEBANG, expandEnvTemplate, resolveShebangLine } from './plugins/shebang.js';
|
|
10
11
|
export { gjsImportsEmptyPlugin } from './plugins/gjs-imports-empty.js';
|
|
11
12
|
export * from './plugin.js';
|
|
12
13
|
import { gjsifyPlugin } from './plugin.js';
|
package/lib/plugin.d.ts
CHANGED
|
@@ -13,8 +13,13 @@ export interface GjsifyPluginInput {
|
|
|
13
13
|
userExternal?: string[];
|
|
14
14
|
userBanner?: string;
|
|
15
15
|
userAliases?: Record<string, string>;
|
|
16
|
-
/**
|
|
17
|
-
|
|
16
|
+
/**
|
|
17
|
+
* Shebang to prepend to the GJS bundle.
|
|
18
|
+
* `true` → default `#!/usr/bin/env -S gjs -m`
|
|
19
|
+
* `false` → no shebang
|
|
20
|
+
* `"…"` → custom line, supports `${env:NAME[:-default]}` placeholders
|
|
21
|
+
*/
|
|
22
|
+
shebang?: boolean | string;
|
|
18
23
|
}
|
|
19
24
|
/**
|
|
20
25
|
* Build the Rolldown configuration template + plugin array for the given
|
package/lib/plugins/shebang.d.ts
CHANGED
|
@@ -6,3 +6,25 @@ export interface ShebangPluginOptions {
|
|
|
6
6
|
line?: string;
|
|
7
7
|
}
|
|
8
8
|
export declare function shebangPlugin(options?: ShebangPluginOptions): Plugin | null;
|
|
9
|
+
/**
|
|
10
|
+
* Expand `${env:NAME}` and `${env:NAME:-default}` placeholders against
|
|
11
|
+
* `process.env`. Missing without default → `''`. Used to let the shebang
|
|
12
|
+
* config field reference build-time env vars (e.g. `GJS_CONSOLE` set by
|
|
13
|
+
* meson-driven Flatpak builds where the GJS interpreter lives at
|
|
14
|
+
* `/usr/bin/gjs-console`).
|
|
15
|
+
*/
|
|
16
|
+
export declare function expandEnvTemplate(input: string, env?: Record<string, string | undefined>): string;
|
|
17
|
+
/**
|
|
18
|
+
* Normalize the user-facing `shebang` config value into the literal line
|
|
19
|
+
* that should be prepended to the bundle (without trailing newline), or
|
|
20
|
+
* `null` when shebang injection is disabled.
|
|
21
|
+
*
|
|
22
|
+
* `true` → default GJS shebang
|
|
23
|
+
* `false|undefined` → null (disabled)
|
|
24
|
+
* `"…"` → string with `${env:NAME[:-default]}` expanded
|
|
25
|
+
*
|
|
26
|
+
* If the resolved string does not start with `#!`, it is prefixed
|
|
27
|
+
* automatically so users can write `"shebang": "/usr/bin/gjs -m"` instead
|
|
28
|
+
* of `"#!/usr/bin/gjs -m"`.
|
|
29
|
+
*/
|
|
30
|
+
export declare function resolveShebangLine(value: boolean | string | undefined): string | null;
|
package/lib/plugins/shebang.js
CHANGED
|
@@ -24,3 +24,41 @@ export function shebangPlugin(options = {}) {
|
|
|
24
24
|
},
|
|
25
25
|
};
|
|
26
26
|
}
|
|
27
|
+
/**
|
|
28
|
+
* Expand `${env:NAME}` and `${env:NAME:-default}` placeholders against
|
|
29
|
+
* `process.env`. Missing without default → `''`. Used to let the shebang
|
|
30
|
+
* config field reference build-time env vars (e.g. `GJS_CONSOLE` set by
|
|
31
|
+
* meson-driven Flatpak builds where the GJS interpreter lives at
|
|
32
|
+
* `/usr/bin/gjs-console`).
|
|
33
|
+
*/
|
|
34
|
+
export function expandEnvTemplate(input, env = process.env) {
|
|
35
|
+
return input.replace(/\$\{env:([A-Za-z_][A-Za-z0-9_]*)(?::-([^}]*))?\}/g, (_match, name, fallback) => {
|
|
36
|
+
const value = env[name];
|
|
37
|
+
if (value !== undefined && value !== '')
|
|
38
|
+
return value;
|
|
39
|
+
return fallback ?? '';
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Normalize the user-facing `shebang` config value into the literal line
|
|
44
|
+
* that should be prepended to the bundle (without trailing newline), or
|
|
45
|
+
* `null` when shebang injection is disabled.
|
|
46
|
+
*
|
|
47
|
+
* `true` → default GJS shebang
|
|
48
|
+
* `false|undefined` → null (disabled)
|
|
49
|
+
* `"…"` → string with `${env:NAME[:-default]}` expanded
|
|
50
|
+
*
|
|
51
|
+
* If the resolved string does not start with `#!`, it is prefixed
|
|
52
|
+
* automatically so users can write `"shebang": "/usr/bin/gjs -m"` instead
|
|
53
|
+
* of `"#!/usr/bin/gjs -m"`.
|
|
54
|
+
*/
|
|
55
|
+
export function resolveShebangLine(value) {
|
|
56
|
+
if (value === undefined || value === false)
|
|
57
|
+
return null;
|
|
58
|
+
if (value === true)
|
|
59
|
+
return GJS_SHEBANG;
|
|
60
|
+
const expanded = expandEnvTemplate(value);
|
|
61
|
+
if (!expanded.trim())
|
|
62
|
+
return null;
|
|
63
|
+
return expanded.startsWith('#!') ? expanded : '#!' + expanded;
|
|
64
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { Plugin } from 'rolldown';
|
|
2
|
+
export interface TextLoaderPluginOptions {
|
|
3
|
+
/**
|
|
4
|
+
* Map of file extension (with leading `.`) → loader kind. Currently only
|
|
5
|
+
* `'text'` is implemented; the field is shaped this way to leave room
|
|
6
|
+
* for `'json'` / `'binary'` later without a config break.
|
|
7
|
+
*/
|
|
8
|
+
loaders?: Record<string, 'text'>;
|
|
9
|
+
}
|
|
10
|
+
export declare function textLoaderPlugin(options?: TextLoaderPluginOptions): Plugin | null;
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
// Generic "load file as JS string default export" plugin.
|
|
2
|
+
//
|
|
3
|
+
// Mirrors `css-as-string` but lets the user opt-in arbitrary extensions
|
|
4
|
+
// through `bundler.loaders` config, e.g.:
|
|
5
|
+
//
|
|
6
|
+
// "bundler": { "loaders": { ".ui": "text", ".asm": "text" } }
|
|
7
|
+
//
|
|
8
|
+
// — replaces the esbuild `loader: { '.ui': 'text' }` shorthand from the
|
|
9
|
+
// pre-Rolldown era. Rolldown does not classify unknown extensions as text
|
|
10
|
+
// by default; without a hook it tries to parse them as JS and fails.
|
|
11
|
+
import { readFile } from 'node:fs/promises';
|
|
12
|
+
export function textLoaderPlugin(options = {}) {
|
|
13
|
+
const exts = Object.entries(options.loaders ?? {})
|
|
14
|
+
.filter(([, kind]) => kind === 'text')
|
|
15
|
+
.map(([ext]) => ext);
|
|
16
|
+
if (exts.length === 0)
|
|
17
|
+
return null;
|
|
18
|
+
// Build a single regex matching any of the configured extensions:
|
|
19
|
+
// ['.ui', '.asm'] → /\.(ui|asm)$/
|
|
20
|
+
const escaped = exts.map((e) => e.replace(/^\./, '').replace(/[.*+?^${}()|[\]\\]/g, '\\$&'));
|
|
21
|
+
const filter = new RegExp(`\\.(?:${escaped.join('|')})$`);
|
|
22
|
+
// Use the function-form `load(id)` (Rollup-compatible) rather than the
|
|
23
|
+
// newer `load: { filter, handler }` shape. The newer shape was observed
|
|
24
|
+
// not to claim unknown-extension files reliably under Rolldown rc.18 —
|
|
25
|
+
// Rolldown's parser ran BEFORE the filtered handler fired and rejected
|
|
26
|
+
// `.ui`/`.asm` content as invalid JS/JSX. Using the function form (same
|
|
27
|
+
// as `@gjsify/vite-plugin-blueprint`'s `.blp` hook) intercepts during
|
|
28
|
+
// module-load lookup and works under both Vite and Rolldown.
|
|
29
|
+
return {
|
|
30
|
+
name: 'gjsify-text-loader',
|
|
31
|
+
async load(id) {
|
|
32
|
+
if (!filter.test(id))
|
|
33
|
+
return null;
|
|
34
|
+
const code = await readFile(id, 'utf8');
|
|
35
|
+
return {
|
|
36
|
+
code: `export default ${JSON.stringify(code)};`,
|
|
37
|
+
moduleType: 'js',
|
|
38
|
+
};
|
|
39
|
+
},
|
|
40
|
+
};
|
|
41
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@gjsify/rolldown-plugin-gjsify",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.15",
|
|
4
4
|
"description": "Rolldown / Rollup / Vite plugin orchestrator for GJS, Node, and Browser targets",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "lib/index.js",
|
|
@@ -42,10 +42,10 @@
|
|
|
42
42
|
],
|
|
43
43
|
"license": "MIT",
|
|
44
44
|
"dependencies": {
|
|
45
|
-
"@gjsify/resolve-npm": "^0.3.
|
|
46
|
-
"@gjsify/rolldown-plugin-deepkit": "^0.3.
|
|
47
|
-
"@gjsify/rolldown-plugin-pnp": "^0.3.
|
|
48
|
-
"@gjsify/vite-plugin-blueprint": "^0.3.
|
|
45
|
+
"@gjsify/resolve-npm": "^0.3.15",
|
|
46
|
+
"@gjsify/rolldown-plugin-deepkit": "^0.3.15",
|
|
47
|
+
"@gjsify/rolldown-plugin-pnp": "^0.3.15",
|
|
48
|
+
"@gjsify/vite-plugin-blueprint": "^0.3.15",
|
|
49
49
|
"@rollup/pluginutils": "^5.1.4",
|
|
50
50
|
"acorn": "^8.14.0",
|
|
51
51
|
"acorn-walk": "^8.3.4",
|
package/src/app/gjs.ts
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
//
|
|
3
3
|
// Mirrors the esbuild predecessor's `setupForGjs` exactly in terms of the
|
|
4
4
|
// effective build behaviour: same externals, same alias map, same target
|
|
5
|
-
// (
|
|
5
|
+
// (firefox140 for JS, firefox60 for CSS), same console-shim injection,
|
|
6
6
|
// same process-stub banner, same `random-access-file` fs-backed-fallback.
|
|
7
7
|
//
|
|
8
8
|
// Returns a partial `RolldownOptions` template plus the plugin array the
|
|
@@ -26,7 +26,7 @@ import {
|
|
|
26
26
|
} from '../plugins/rewrite-node-modules-paths.js';
|
|
27
27
|
import { processStubPlugin } from '../plugins/process-stub.js';
|
|
28
28
|
import { cssAsStringPlugin } from '../plugins/css-as-string.js';
|
|
29
|
-
import { shebangPlugin,
|
|
29
|
+
import { shebangPlugin, resolveShebangLine } from '../plugins/shebang.js';
|
|
30
30
|
|
|
31
31
|
const _shimDir = dirname(fileURLToPath(import.meta.url));
|
|
32
32
|
|
|
@@ -47,8 +47,13 @@ export interface GjsFactoryInput {
|
|
|
47
47
|
userBanner?: string;
|
|
48
48
|
/** User-supplied resolve.alias overrides. */
|
|
49
49
|
userAliases?: Record<string, string>;
|
|
50
|
-
/**
|
|
51
|
-
|
|
50
|
+
/**
|
|
51
|
+
* Shebang to prepend to the output bundle.
|
|
52
|
+
* `true` → default `#!/usr/bin/env -S gjs -m`
|
|
53
|
+
* `false` → no shebang
|
|
54
|
+
* `"…"` → custom line, supports `${env:NAME[:-default]}` placeholders
|
|
55
|
+
*/
|
|
56
|
+
shebang?: boolean | string;
|
|
52
57
|
/** Plugin options forwarded to sub-plugins (deepkit, css, …). */
|
|
53
58
|
pluginOptions: PluginOptions;
|
|
54
59
|
}
|
|
@@ -111,8 +116,8 @@ export const setupForGjs = async (input: GjsFactoryInput): Promise<GjsBuildConfi
|
|
|
111
116
|
conditionNames: format === 'esm' ? ['browser', 'import'] : ['browser', 'require', 'import'],
|
|
112
117
|
},
|
|
113
118
|
transform: {
|
|
114
|
-
// Compile target: GJS 1.86 / SpiderMonkey
|
|
115
|
-
target: '
|
|
119
|
+
// Compile target: GJS 1.86 / SpiderMonkey 140 ≈ firefox140.
|
|
120
|
+
target: 'firefox140',
|
|
116
121
|
define: {
|
|
117
122
|
global: 'globalThis',
|
|
118
123
|
window: 'globalThis',
|
|
@@ -163,7 +168,12 @@ export const setupForGjs = async (input: GjsFactoryInput): Promise<GjsBuildConfi
|
|
|
163
168
|
cssAsStringPlugin(),
|
|
164
169
|
nodeModulesPathRewritePlugin({ bundleDir }),
|
|
165
170
|
processStubPlugin({ userBanner: input.userBanner }),
|
|
166
|
-
|
|
171
|
+
// resolveShebangLine returns null when disabled (false/undefined) and
|
|
172
|
+
// the resolved line otherwise — also handles `${env:…}` expansion.
|
|
173
|
+
(() => {
|
|
174
|
+
const line = resolveShebangLine(input.shebang);
|
|
175
|
+
return shebangPlugin({ enabled: line !== null, line: line ?? undefined });
|
|
176
|
+
})(),
|
|
167
177
|
];
|
|
168
178
|
|
|
169
179
|
return { options, plugins };
|
package/src/index.ts
CHANGED
|
@@ -20,7 +20,9 @@ export type {
|
|
|
20
20
|
export { processStubPlugin, GJS_PROCESS_STUB, composeBanner } from './plugins/process-stub.js';
|
|
21
21
|
export type { ProcessStubPluginOptions } from './plugins/process-stub.js';
|
|
22
22
|
export { cssAsStringPlugin } from './plugins/css-as-string.js';
|
|
23
|
-
export {
|
|
23
|
+
export { textLoaderPlugin } from './plugins/text-loader.js';
|
|
24
|
+
export type { TextLoaderPluginOptions } from './plugins/text-loader.js';
|
|
25
|
+
export { shebangPlugin, GJS_SHEBANG, expandEnvTemplate, resolveShebangLine } from './plugins/shebang.js';
|
|
24
26
|
export type { ShebangPluginOptions } from './plugins/shebang.js';
|
|
25
27
|
export { gjsImportsEmptyPlugin } from './plugins/gjs-imports-empty.js';
|
|
26
28
|
|
package/src/plugin.ts
CHANGED
|
@@ -27,8 +27,13 @@ export interface GjsifyPluginInput {
|
|
|
27
27
|
userExternal?: string[];
|
|
28
28
|
userBanner?: string;
|
|
29
29
|
userAliases?: Record<string, string>;
|
|
30
|
-
/**
|
|
31
|
-
|
|
30
|
+
/**
|
|
31
|
+
* Shebang to prepend to the GJS bundle.
|
|
32
|
+
* `true` → default `#!/usr/bin/env -S gjs -m`
|
|
33
|
+
* `false` → no shebang
|
|
34
|
+
* `"…"` → custom line, supports `${env:NAME[:-default]}` placeholders
|
|
35
|
+
*/
|
|
36
|
+
shebang?: boolean | string;
|
|
32
37
|
}
|
|
33
38
|
|
|
34
39
|
/**
|
package/src/plugins/shebang.ts
CHANGED
|
@@ -31,3 +31,39 @@ export function shebangPlugin(options: ShebangPluginOptions = {}): Plugin | null
|
|
|
31
31
|
},
|
|
32
32
|
};
|
|
33
33
|
}
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Expand `${env:NAME}` and `${env:NAME:-default}` placeholders against
|
|
37
|
+
* `process.env`. Missing without default → `''`. Used to let the shebang
|
|
38
|
+
* config field reference build-time env vars (e.g. `GJS_CONSOLE` set by
|
|
39
|
+
* meson-driven Flatpak builds where the GJS interpreter lives at
|
|
40
|
+
* `/usr/bin/gjs-console`).
|
|
41
|
+
*/
|
|
42
|
+
export function expandEnvTemplate(input: string, env: Record<string, string | undefined> = process.env): string {
|
|
43
|
+
return input.replace(/\$\{env:([A-Za-z_][A-Za-z0-9_]*)(?::-([^}]*))?\}/g, (_match, name: string, fallback?: string) => {
|
|
44
|
+
const value = env[name];
|
|
45
|
+
if (value !== undefined && value !== '') return value;
|
|
46
|
+
return fallback ?? '';
|
|
47
|
+
});
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* Normalize the user-facing `shebang` config value into the literal line
|
|
52
|
+
* that should be prepended to the bundle (without trailing newline), or
|
|
53
|
+
* `null` when shebang injection is disabled.
|
|
54
|
+
*
|
|
55
|
+
* `true` → default GJS shebang
|
|
56
|
+
* `false|undefined` → null (disabled)
|
|
57
|
+
* `"…"` → string with `${env:NAME[:-default]}` expanded
|
|
58
|
+
*
|
|
59
|
+
* If the resolved string does not start with `#!`, it is prefixed
|
|
60
|
+
* automatically so users can write `"shebang": "/usr/bin/gjs -m"` instead
|
|
61
|
+
* of `"#!/usr/bin/gjs -m"`.
|
|
62
|
+
*/
|
|
63
|
+
export function resolveShebangLine(value: boolean | string | undefined): string | null {
|
|
64
|
+
if (value === undefined || value === false) return null;
|
|
65
|
+
if (value === true) return GJS_SHEBANG;
|
|
66
|
+
const expanded = expandEnvTemplate(value);
|
|
67
|
+
if (!expanded.trim()) return null;
|
|
68
|
+
return expanded.startsWith('#!') ? expanded : '#!' + expanded;
|
|
69
|
+
}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
// Generic "load file as JS string default export" plugin.
|
|
2
|
+
//
|
|
3
|
+
// Mirrors `css-as-string` but lets the user opt-in arbitrary extensions
|
|
4
|
+
// through `bundler.loaders` config, e.g.:
|
|
5
|
+
//
|
|
6
|
+
// "bundler": { "loaders": { ".ui": "text", ".asm": "text" } }
|
|
7
|
+
//
|
|
8
|
+
// — replaces the esbuild `loader: { '.ui': 'text' }` shorthand from the
|
|
9
|
+
// pre-Rolldown era. Rolldown does not classify unknown extensions as text
|
|
10
|
+
// by default; without a hook it tries to parse them as JS and fails.
|
|
11
|
+
|
|
12
|
+
import { readFile } from 'node:fs/promises';
|
|
13
|
+
import type { Plugin } from 'rolldown';
|
|
14
|
+
|
|
15
|
+
export interface TextLoaderPluginOptions {
|
|
16
|
+
/**
|
|
17
|
+
* Map of file extension (with leading `.`) → loader kind. Currently only
|
|
18
|
+
* `'text'` is implemented; the field is shaped this way to leave room
|
|
19
|
+
* for `'json'` / `'binary'` later without a config break.
|
|
20
|
+
*/
|
|
21
|
+
loaders?: Record<string, 'text'>;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export function textLoaderPlugin(options: TextLoaderPluginOptions = {}): Plugin | null {
|
|
25
|
+
const exts = Object.entries(options.loaders ?? {})
|
|
26
|
+
.filter(([, kind]) => kind === 'text')
|
|
27
|
+
.map(([ext]) => ext);
|
|
28
|
+
|
|
29
|
+
if (exts.length === 0) return null;
|
|
30
|
+
|
|
31
|
+
// Build a single regex matching any of the configured extensions:
|
|
32
|
+
// ['.ui', '.asm'] → /\.(ui|asm)$/
|
|
33
|
+
const escaped = exts.map((e) => e.replace(/^\./, '').replace(/[.*+?^${}()|[\]\\]/g, '\\$&'));
|
|
34
|
+
const filter = new RegExp(`\\.(?:${escaped.join('|')})$`);
|
|
35
|
+
|
|
36
|
+
// Use the function-form `load(id)` (Rollup-compatible) rather than the
|
|
37
|
+
// newer `load: { filter, handler }` shape. The newer shape was observed
|
|
38
|
+
// not to claim unknown-extension files reliably under Rolldown rc.18 —
|
|
39
|
+
// Rolldown's parser ran BEFORE the filtered handler fired and rejected
|
|
40
|
+
// `.ui`/`.asm` content as invalid JS/JSX. Using the function form (same
|
|
41
|
+
// as `@gjsify/vite-plugin-blueprint`'s `.blp` hook) intercepts during
|
|
42
|
+
// module-load lookup and works under both Vite and Rolldown.
|
|
43
|
+
return {
|
|
44
|
+
name: 'gjsify-text-loader',
|
|
45
|
+
async load(id: string) {
|
|
46
|
+
if (!filter.test(id)) return null;
|
|
47
|
+
const code = await readFile(id, 'utf8');
|
|
48
|
+
return {
|
|
49
|
+
code: `export default ${JSON.stringify(code)};`,
|
|
50
|
+
moduleType: 'js' as const,
|
|
51
|
+
};
|
|
52
|
+
},
|
|
53
|
+
};
|
|
54
|
+
}
|