@gtkx/cli 1.3.0 → 1.4.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/README.md +5 -4
- package/dist/builder.d.ts +0 -1
- package/dist/builder.d.ts.map +1 -1
- package/dist/builder.js +6 -6
- package/dist/builder.js.map +1 -1
- package/dist/codegen/run-codegen.d.ts +1 -2
- package/dist/codegen/run-codegen.d.ts.map +1 -1
- package/dist/codegen/run-codegen.js +11 -6
- package/dist/codegen/run-codegen.js.map +1 -1
- package/dist/commands/build.d.ts +0 -4
- package/dist/commands/build.d.ts.map +1 -1
- package/dist/commands/build.js +0 -5
- package/dist/commands/build.js.map +1 -1
- package/dist/commands/codegen.d.ts.map +1 -1
- package/dist/commands/codegen.js +1 -3
- package/dist/commands/codegen.js.map +1 -1
- package/dist/deploy/depends.d.ts +2 -2
- package/dist/deploy/depends.d.ts.map +1 -1
- package/dist/deploy/depends.js +30 -15
- package/dist/deploy/depends.js.map +1 -1
- package/dist/deploy/nfpm/config.js +1 -1
- package/dist/deploy/nfpm/config.js.map +1 -1
- package/dist/deploy/node-runtime/elf.d.ts +1 -1
- package/dist/deploy/node-runtime/elf.d.ts.map +1 -1
- package/dist/deploy/node-runtime/elf.js +2 -2
- package/dist/deploy/node-runtime/elf.js.map +1 -1
- package/dist/deploy/node-runtime/index.js +2 -2
- package/dist/deploy/node-runtime/index.js.map +1 -1
- package/dist/deploy/notices/collect.d.ts +3 -1
- package/dist/deploy/notices/collect.d.ts.map +1 -1
- package/dist/deploy/notices/collect.js +2 -2
- package/dist/deploy/notices/collect.js.map +1 -1
- package/dist/deploy/notices/packages.d.ts +2 -1
- package/dist/deploy/notices/packages.d.ts.map +1 -1
- package/dist/deploy/notices/packages.js +4 -27
- package/dist/deploy/notices/packages.js.map +1 -1
- package/dist/deploy/payload/icons.d.ts +7 -3
- package/dist/deploy/payload/icons.d.ts.map +1 -1
- package/dist/deploy/payload/icons.js +46 -28
- package/dist/deploy/payload/icons.js.map +1 -1
- package/dist/deploy/payload/stage.d.ts.map +1 -1
- package/dist/deploy/payload/stage.js +3 -2
- package/dist/deploy/payload/stage.js.map +1 -1
- package/dist/deploy/run-deploy.d.ts.map +1 -1
- package/dist/deploy/run-deploy.js +63 -11
- package/dist/deploy/run-deploy.js.map +1 -1
- package/dist/deploy/settings/build-manifest.d.ts +9 -0
- package/dist/deploy/settings/build-manifest.d.ts.map +1 -0
- package/dist/deploy/settings/build-manifest.js +80 -0
- package/dist/deploy/settings/build-manifest.js.map +1 -0
- package/dist/deploy/settings/index.d.ts.map +1 -1
- package/dist/deploy/settings/index.js +9 -3
- package/dist/deploy/settings/index.js.map +1 -1
- package/dist/deploy/settings/libraries.d.ts +8 -0
- package/dist/deploy/settings/libraries.d.ts.map +1 -0
- package/dist/deploy/settings/libraries.js +39 -0
- package/dist/deploy/settings/libraries.js.map +1 -0
- package/dist/deploy/settings/paths.d.ts +3 -0
- package/dist/deploy/settings/paths.d.ts.map +1 -1
- package/dist/deploy/settings/paths.js +6 -32
- package/dist/deploy/settings/paths.js.map +1 -1
- package/dist/deploy/targets/appimage.d.ts.map +1 -1
- package/dist/deploy/targets/appimage.js +19 -13
- package/dist/deploy/targets/appimage.js.map +1 -1
- package/dist/deploy/targets/flatpak-manifest.d.ts +2 -1
- package/dist/deploy/targets/flatpak-manifest.d.ts.map +1 -1
- package/dist/deploy/targets/flatpak-manifest.js +5 -1
- package/dist/deploy/targets/flatpak-manifest.js.map +1 -1
- package/dist/deploy/targets/flatpak-source.d.ts.map +1 -1
- package/dist/deploy/targets/flatpak-source.js +9 -6
- package/dist/deploy/targets/flatpak-source.js.map +1 -1
- package/dist/deploy/types.d.ts +4 -4
- package/dist/deploy/types.d.ts.map +1 -1
- package/dist/deploy/types.js.map +1 -1
- package/dist/dev/icon-dir.d.ts +1 -1
- package/dist/dev/icon-dir.d.ts.map +1 -1
- package/dist/dev/icon-dir.js +20 -7
- package/dist/dev/icon-dir.js.map +1 -1
- package/dist/dev/runner-deps.d.ts.map +1 -1
- package/dist/dev/runner-deps.js +5 -1
- package/dist/dev/runner-deps.js.map +1 -1
- package/dist/dev/runner-main.js +4 -4
- package/dist/dev/runner-main.js.map +1 -1
- package/dist/dev/runner.d.ts +1 -1
- package/dist/dev/runner.d.ts.map +1 -1
- package/dist/dev/runner.js +1 -1
- package/dist/dev/runner.js.map +1 -1
- package/dist/dev/schema-dir.d.ts +1 -1
- package/dist/dev/schema-dir.d.ts.map +1 -1
- package/dist/dev/schema-dir.js +3 -1
- package/dist/dev/schema-dir.js.map +1 -1
- package/dist/internal/build-manifest.d.ts +20 -0
- package/dist/internal/build-manifest.d.ts.map +1 -0
- package/dist/internal/build-manifest.js +6 -0
- package/dist/internal/build-manifest.js.map +1 -0
- package/dist/internal/icon-path.d.ts +13 -0
- package/dist/internal/icon-path.d.ts.map +1 -0
- package/dist/internal/icon-path.js +86 -0
- package/dist/internal/icon-path.js.map +1 -0
- package/dist/internal/source-imports.d.ts +8 -0
- package/dist/internal/source-imports.d.ts.map +1 -0
- package/dist/internal/source-imports.js +144 -0
- package/dist/internal/source-imports.js.map +1 -0
- package/dist/mcp/widget-properties.d.ts.map +1 -1
- package/dist/mcp/widget-properties.js +3 -12
- package/dist/mcp/widget-properties.js.map +1 -1
- package/dist/settings/render.d.ts +7 -1
- package/dist/settings/render.d.ts.map +1 -1
- package/dist/settings/render.js +69 -20
- package/dist/settings/render.js.map +1 -1
- package/dist/settings/schema.d.ts +4 -3
- package/dist/settings/schema.d.ts.map +1 -1
- package/dist/settings/schema.js +122 -15
- package/dist/settings/schema.js.map +1 -1
- package/dist/vite-plugins/asset-emitter.d.ts +1 -1
- package/dist/vite-plugins/asset-emitter.d.ts.map +1 -1
- package/dist/vite-plugins/asset-emitter.js.map +1 -1
- package/dist/vite-plugins/asset-extensions.d.ts.map +1 -1
- package/dist/vite-plugins/asset-extensions.js +1 -0
- package/dist/vite-plugins/asset-extensions.js.map +1 -1
- package/dist/vite-plugins/asset-imports.d.ts +2 -1
- package/dist/vite-plugins/asset-imports.d.ts.map +1 -1
- package/dist/vite-plugins/asset-imports.js +37 -16
- package/dist/vite-plugins/asset-imports.js.map +1 -1
- package/dist/vite-plugins/asset-specifier.d.ts +13 -1
- package/dist/vite-plugins/asset-specifier.d.ts.map +1 -1
- package/dist/vite-plugins/asset-specifier.js +39 -1
- package/dist/vite-plugins/asset-specifier.js.map +1 -1
- package/dist/vite-plugins/build-manifest.d.ts +5 -0
- package/dist/vite-plugins/build-manifest.d.ts.map +1 -0
- package/dist/vite-plugins/{bundled-packages.js → build-manifest.js} +20 -14
- package/dist/vite-plugins/build-manifest.js.map +1 -0
- package/dist/vite-plugins/built-url.d.ts +1 -1
- package/dist/vite-plugins/built-url.d.ts.map +1 -1
- package/dist/vite-plugins/built-url.js +37 -24
- package/dist/vite-plugins/built-url.js.map +1 -1
- package/dist/vite-plugins/icons.d.ts +2 -1
- package/dist/vite-plugins/icons.d.ts.map +1 -1
- package/dist/vite-plugins/icons.js +25 -12
- package/dist/vite-plugins/icons.js.map +1 -1
- package/dist/vite-plugins/index.d.ts +2 -1
- package/dist/vite-plugins/index.d.ts.map +1 -1
- package/dist/vite-plugins/index.js +7 -5
- package/dist/vite-plugins/index.js.map +1 -1
- package/dist/vite-plugins/native.d.ts.map +1 -1
- package/dist/vite-plugins/native.js +23 -4
- package/dist/vite-plugins/native.js.map +1 -1
- package/dist/vite-plugins/resource-init-module.d.ts +7 -3
- package/dist/vite-plugins/resource-init-module.d.ts.map +1 -1
- package/dist/vite-plugins/resource-init-module.js +39 -14
- package/dist/vite-plugins/resource-init-module.js.map +1 -1
- package/dist/vite-plugins/resource-shared.d.ts +3 -1
- package/dist/vite-plugins/resource-shared.d.ts.map +1 -1
- package/dist/vite-plugins/resource-shared.js +3 -1
- package/dist/vite-plugins/resource-shared.js.map +1 -1
- package/dist/vite-plugins/resources.d.ts +1 -1
- package/dist/vite-plugins/resources.d.ts.map +1 -1
- package/dist/vite-plugins/resources.js +922 -86
- package/dist/vite-plugins/resources.js.map +1 -1
- package/dist/vite-plugins/settings-worker-env.d.ts.map +1 -1
- package/dist/vite-plugins/settings-worker-env.js +6 -3
- package/dist/vite-plugins/settings-worker-env.js.map +1 -1
- package/dist/vite-plugins/settings.d.ts +3 -1
- package/dist/vite-plugins/settings.d.ts.map +1 -1
- package/dist/vite-plugins/settings.js +63 -23
- package/dist/vite-plugins/settings.js.map +1 -1
- package/env.d.ts +11 -192
- package/package.json +10 -10
- package/src/builder.ts +6 -7
- package/src/codegen/run-codegen.ts +10 -7
- package/src/commands/build.ts +0 -5
- package/src/commands/codegen.ts +1 -3
- package/src/deploy/depends.ts +47 -18
- package/src/deploy/nfpm/config.ts +1 -1
- package/src/deploy/node-runtime/elf.ts +3 -3
- package/src/deploy/node-runtime/index.ts +2 -2
- package/src/deploy/notices/collect.ts +4 -2
- package/src/deploy/notices/packages.ts +5 -43
- package/src/deploy/payload/icons.ts +64 -34
- package/src/deploy/payload/stage.ts +5 -2
- package/src/deploy/run-deploy.ts +87 -12
- package/src/deploy/settings/build-manifest.ts +122 -0
- package/src/deploy/settings/index.ts +9 -4
- package/src/deploy/settings/libraries.ts +57 -0
- package/src/deploy/settings/paths.ts +10 -47
- package/src/deploy/targets/appimage.ts +32 -15
- package/src/deploy/targets/flatpak-manifest.ts +7 -1
- package/src/deploy/targets/flatpak-source.ts +9 -10
- package/src/deploy/types.ts +4 -4
- package/src/dev/icon-dir.ts +31 -7
- package/src/dev/runner-deps.ts +5 -1
- package/src/dev/runner-main.ts +4 -4
- package/src/dev/runner.ts +2 -2
- package/src/dev/schema-dir.ts +3 -1
- package/src/internal/build-manifest.ts +32 -0
- package/src/internal/icon-path.ts +127 -0
- package/src/internal/source-imports.ts +200 -0
- package/src/mcp/widget-properties.ts +3 -14
- package/src/settings/render.ts +99 -21
- package/src/settings/schema.ts +190 -17
- package/src/vite-plugins/asset-emitter.ts +1 -1
- package/src/vite-plugins/asset-extensions.ts +1 -0
- package/src/vite-plugins/asset-imports.ts +60 -19
- package/src/vite-plugins/asset-specifier.ts +73 -1
- package/src/vite-plugins/{bundled-packages.ts → build-manifest.ts} +30 -19
- package/src/vite-plugins/built-url.ts +49 -28
- package/src/vite-plugins/icons.ts +33 -14
- package/src/vite-plugins/index.ts +12 -5
- package/src/vite-plugins/native.ts +31 -4
- package/src/vite-plugins/resource-init-module.ts +44 -15
- package/src/vite-plugins/resource-shared.ts +4 -0
- package/src/vite-plugins/resources.ts +1459 -100
- package/src/vite-plugins/settings-worker-env.ts +7 -3
- package/src/vite-plugins/settings.ts +89 -21
- package/dist/vite-plugins/bundled-packages.d.ts +0 -5
- package/dist/vite-plugins/bundled-packages.d.ts.map +0 -1
- package/dist/vite-plugins/bundled-packages.js.map +0 -1
|
@@ -6,13 +6,14 @@ import {
|
|
|
6
6
|
getHandle,
|
|
7
7
|
getInstanceType,
|
|
8
8
|
type Handle,
|
|
9
|
+
isReadableProperty,
|
|
9
10
|
TYPE_ENUM,
|
|
10
11
|
TYPE_FLAGS,
|
|
11
12
|
typeIsA,
|
|
12
13
|
typeName,
|
|
13
14
|
} from "@gtkx/runtime";
|
|
14
15
|
import { fromValue, getValueType } from "@gtkx/runtime/internal";
|
|
15
|
-
import {
|
|
16
|
+
import { errorMessage, kebabCase } from "@gtkx/utils";
|
|
16
17
|
import type { WidgetRegistry } from "./widget-registry.js";
|
|
17
18
|
|
|
18
19
|
type PropertyRepresentation = Omit<SerializedProperty, "type">;
|
|
@@ -39,18 +40,6 @@ function prototypesFor(widget: Gtk.Widget): object[] {
|
|
|
39
40
|
return prototypes;
|
|
40
41
|
}
|
|
41
42
|
|
|
42
|
-
function getAccessor(widget: Gtk.Widget, member: string): PropertyDescriptor | undefined {
|
|
43
|
-
for (const prototype of prototypesFor(widget)) {
|
|
44
|
-
const descriptor = Object.getOwnPropertyDescriptor(prototype, member);
|
|
45
|
-
|
|
46
|
-
if (descriptor !== undefined) {
|
|
47
|
-
return descriptor;
|
|
48
|
-
}
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
return undefined;
|
|
52
|
-
}
|
|
53
|
-
|
|
54
43
|
function getReadableNames(prototype: object): string[] {
|
|
55
44
|
const descriptors = Object.entries(Object.getOwnPropertyDescriptors(prototype));
|
|
56
45
|
|
|
@@ -64,7 +53,7 @@ function readablePropertyNames(widget: Gtk.Widget): string[] {
|
|
|
64
53
|
}
|
|
65
54
|
|
|
66
55
|
const requireReadableProperty = (widget: Gtk.Widget, property: string): void => {
|
|
67
|
-
if (
|
|
56
|
+
if (isReadableProperty(getInstanceType(widget), property)) {
|
|
68
57
|
return;
|
|
69
58
|
}
|
|
70
59
|
|
package/src/settings/render.ts
CHANGED
|
@@ -1,19 +1,56 @@
|
|
|
1
|
-
import { upperFirst } from "@gtkx/utils";
|
|
1
|
+
import { camelCase, sanitizeIdentifier, upperFirst } from "@gtkx/utils";
|
|
2
2
|
import type { ParsedKey, ParsedSchema, ParsedSchemaFile } from "./parser.js";
|
|
3
3
|
|
|
4
|
+
type NamedSchema = {
|
|
5
|
+
schema: ParsedSchema;
|
|
6
|
+
exportName: string;
|
|
7
|
+
};
|
|
8
|
+
|
|
9
|
+
type EnvAssetDeclarations = {
|
|
10
|
+
blocked: string[];
|
|
11
|
+
icons: string[];
|
|
12
|
+
legacy: string[];
|
|
13
|
+
resources: string[];
|
|
14
|
+
};
|
|
15
|
+
|
|
4
16
|
const GTKX_ENV_MODULE_HEADER = `/**
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
* \`gtkx build\`; do not edit.
|
|
17
|
+
* Project import declarations generated by GTKX. Regenerated by
|
|
18
|
+
* \`gtkx codegen\`, \`gtkx dev\`, and \`gtkx build\`; do not edit.
|
|
8
19
|
*/`;
|
|
9
20
|
|
|
10
21
|
const ENUM_KIND = "enum";
|
|
11
22
|
const FLAGS_KIND = "flags";
|
|
23
|
+
const ID_SEPARATOR = /[._]/;
|
|
24
|
+
const NAME_SEPARATOR = "_";
|
|
12
25
|
|
|
13
26
|
const toJsStringLiteral = (value: string): string =>
|
|
14
27
|
JSON.stringify(value).replaceAll("\u{2028}", String.raw`\u2028`).replaceAll("\u{2029}", String.raw`\u2029`);
|
|
15
28
|
|
|
16
|
-
const getExportName = (schemaId: string): string =>
|
|
29
|
+
const getExportName = (schemaId: string): string =>
|
|
30
|
+
sanitizeIdentifier(schemaId.split(ID_SEPARATOR).map((part) => camelCase(part)).join(NAME_SEPARATOR));
|
|
31
|
+
|
|
32
|
+
const collisionError = (file: ParsedSchemaFile, taken: string, schemaId: string, name: string): Error =>
|
|
33
|
+
new Error(
|
|
34
|
+
`${file.fileName} declares ${taken} and ${schemaId}, which both export \`${name}\`. ` +
|
|
35
|
+
"Rename one of the schema ids so that every schema in the file gets an export of its own.",
|
|
36
|
+
);
|
|
37
|
+
|
|
38
|
+
const getNamedSchemas = (file: ParsedSchemaFile): NamedSchema[] => {
|
|
39
|
+
const owners: Map<string, string> = new Map();
|
|
40
|
+
|
|
41
|
+
return file.schemas.map((schema) => {
|
|
42
|
+
const exportName = getExportName(schema.id);
|
|
43
|
+
const taken = owners.get(exportName);
|
|
44
|
+
|
|
45
|
+
if (taken !== undefined) {
|
|
46
|
+
throw collisionError(file, taken, schema.id, exportName);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
owners.set(exportName, schema.id);
|
|
50
|
+
|
|
51
|
+
return { schema, exportName };
|
|
52
|
+
});
|
|
53
|
+
};
|
|
17
54
|
|
|
18
55
|
const runtimeKindForKey = (key: ParsedKey): string => {
|
|
19
56
|
if (key.enumId !== null) {
|
|
@@ -37,26 +74,27 @@ const getRuntimeKeys = (schema: ParsedSchema): string => {
|
|
|
37
74
|
|
|
38
75
|
const renderRuntimeModule = (file: ParsedSchemaFile): string => {
|
|
39
76
|
const lines: string[] = [];
|
|
77
|
+
const named = getNamedSchemas(file);
|
|
40
78
|
|
|
41
|
-
for (const [index, schema] of
|
|
79
|
+
for (const [index, { schema, exportName }] of named.entries()) {
|
|
42
80
|
const keysName = `keys_${String(index)}`;
|
|
43
81
|
const id = toJsStringLiteral(schema.id);
|
|
44
82
|
lines.push(`const ${keysName} = ${getRuntimeKeys(schema)};`);
|
|
45
83
|
|
|
46
84
|
if (schema.path === null) {
|
|
47
85
|
lines.push(
|
|
48
|
-
`export const ${
|
|
86
|
+
`export const ${exportName} = { id: ${id}, keys: ${keysName}, ` +
|
|
49
87
|
`at: (path) => ({ id: ${id}, path, keys: ${keysName} }) };`,
|
|
50
88
|
);
|
|
51
89
|
} else {
|
|
52
|
-
lines.push(`export const ${
|
|
90
|
+
lines.push(`export const ${exportName} = { id: ${id}, path: null, keys: ${keysName} };`);
|
|
53
91
|
}
|
|
54
92
|
}
|
|
55
93
|
|
|
56
|
-
const first =
|
|
94
|
+
const first = named[0];
|
|
57
95
|
|
|
58
96
|
if (first !== undefined) {
|
|
59
|
-
lines.push(`export default ${
|
|
97
|
+
lines.push(`export default ${first.exportName};`);
|
|
60
98
|
}
|
|
61
99
|
|
|
62
100
|
return lines.join("\n");
|
|
@@ -106,9 +144,7 @@ const boundRefTypeLines = (interfaceName: string, indent: string): string[] => [
|
|
|
106
144
|
`${indent}keys: ${interfaceName};`,
|
|
107
145
|
];
|
|
108
146
|
|
|
109
|
-
const renderSchemaConst = (schema:
|
|
110
|
-
const exportName = getExportName(schema.id);
|
|
111
|
-
|
|
147
|
+
const renderSchemaConst = ({ schema, exportName }: NamedSchema, interfaceName: string): string[] => {
|
|
112
148
|
if (schema.path !== null) {
|
|
113
149
|
return [
|
|
114
150
|
` const ${exportName}: {`,
|
|
@@ -130,17 +166,17 @@ const renderSchemaConst = (schema: ParsedSchema, interfaceName: string): string[
|
|
|
130
166
|
};
|
|
131
167
|
|
|
132
168
|
const renderFileModule = (file: ParsedSchemaFile, usedNames: Set<string>): string[] => {
|
|
133
|
-
const lines = [`declare module
|
|
169
|
+
const lines = [`declare module ${toJsStringLiteral(file.fileName)} {`];
|
|
134
170
|
const exportNames: string[] = [];
|
|
135
171
|
|
|
136
|
-
for (const [index,
|
|
172
|
+
for (const [index, named] of getNamedSchemas(file).entries()) {
|
|
137
173
|
if (index > 0) {
|
|
138
174
|
lines.push("");
|
|
139
175
|
}
|
|
140
176
|
|
|
141
|
-
const interfaceName = allocateInterfaceName(schema.id, usedNames);
|
|
142
|
-
lines.push(...renderKeysType(interfaceName, schema), "", ...renderSchemaConst(
|
|
143
|
-
exportNames.push(
|
|
177
|
+
const interfaceName = allocateInterfaceName(named.schema.id, usedNames);
|
|
178
|
+
lines.push(...renderKeysType(interfaceName, named.schema), "", ...renderSchemaConst(named, interfaceName));
|
|
179
|
+
exportNames.push(named.exportName);
|
|
144
180
|
}
|
|
145
181
|
|
|
146
182
|
const [firstExport] = exportNames;
|
|
@@ -154,14 +190,56 @@ const renderFileModule = (file: ParsedSchemaFile, usedNames: Set<string>): strin
|
|
|
154
190
|
return lines;
|
|
155
191
|
};
|
|
156
192
|
|
|
157
|
-
const
|
|
193
|
+
const renderResourceModule = (specifier: string): string => [
|
|
194
|
+
`declare module ${toJsStringLiteral(specifier)} {`,
|
|
195
|
+
" const path: string;",
|
|
196
|
+
" export { path };",
|
|
197
|
+
" export default path;",
|
|
198
|
+
"}",
|
|
199
|
+
].join("\n");
|
|
200
|
+
|
|
201
|
+
const renderIconModule = (specifier: string): string => [
|
|
202
|
+
`declare module ${toJsStringLiteral(specifier)} {`,
|
|
203
|
+
" const iconName: string;",
|
|
204
|
+
" export default iconName;",
|
|
205
|
+
"}",
|
|
206
|
+
].join("\n");
|
|
207
|
+
|
|
208
|
+
const renderLegacyAssetModule = (specifier: string): string => [
|
|
209
|
+
`declare module ${toJsStringLiteral(specifier)} {`,
|
|
210
|
+
" const resourceUri: string;",
|
|
211
|
+
" const path: string;",
|
|
212
|
+
" export { path };",
|
|
213
|
+
" export default resourceUri;",
|
|
214
|
+
"}",
|
|
215
|
+
].join("\n");
|
|
216
|
+
|
|
217
|
+
const renderBlockedAssetModule = (specifier: string): string => [
|
|
218
|
+
`declare module ${toJsStringLiteral(specifier)} {`,
|
|
219
|
+
" const assetImportRequiresResourceOrUrlQuery: {",
|
|
220
|
+
" readonly __gtkxAssetImportRequiresResourceOrUrlQuery: unique symbol;",
|
|
221
|
+
" };",
|
|
222
|
+
" export default assetImportRequiresResourceOrUrlQuery;",
|
|
223
|
+
"}",
|
|
224
|
+
].join("\n");
|
|
225
|
+
|
|
226
|
+
const renderEnvModule = (
|
|
227
|
+
files: ParsedSchemaFile[],
|
|
228
|
+
assetDeclarations?: EnvAssetDeclarations,
|
|
229
|
+
): string => {
|
|
230
|
+
const assets = assetDeclarations ?? { blocked: [], icons: [], legacy: [], resources: [] };
|
|
158
231
|
const usedNames: Set<string> = new Set();
|
|
159
232
|
|
|
160
|
-
const
|
|
233
|
+
const schemas = files
|
|
161
234
|
.filter((file) => file.schemas.length > 0)
|
|
162
235
|
.map((file) => renderFileModule(file, usedNames).join("\n"));
|
|
163
236
|
|
|
164
|
-
|
|
237
|
+
const blocked = assets.blocked.map((specifier) => renderBlockedAssetModule(specifier));
|
|
238
|
+
const icons = assets.icons.map((specifier) => renderIconModule(specifier));
|
|
239
|
+
const legacy = assets.legacy.map((specifier) => renderLegacyAssetModule(specifier));
|
|
240
|
+
const resources = assets.resources.map((specifier) => renderResourceModule(specifier));
|
|
241
|
+
|
|
242
|
+
return `${[GTKX_ENV_MODULE_HEADER, ...blocked, ...icons, ...legacy, ...resources, ...schemas].join("\n\n")}\n`;
|
|
165
243
|
};
|
|
166
244
|
|
|
167
245
|
export { renderRuntimeModule, renderEnvModule };
|
package/src/settings/schema.ts
CHANGED
|
@@ -1,10 +1,27 @@
|
|
|
1
1
|
import { sortStrings, warn } from "@gtkx/utils";
|
|
2
2
|
import { createHash } from "node:crypto";
|
|
3
|
-
import {
|
|
3
|
+
import {
|
|
4
|
+
copyFileSync,
|
|
5
|
+
type Dirent,
|
|
6
|
+
existsSync,
|
|
7
|
+
mkdirSync,
|
|
8
|
+
mkdtempSync,
|
|
9
|
+
readdirSync,
|
|
10
|
+
readFileSync,
|
|
11
|
+
realpathSync,
|
|
12
|
+
writeFileSync,
|
|
13
|
+
} from "node:fs";
|
|
4
14
|
import { tmpdir } from "node:os";
|
|
5
|
-
import { dirname, join, relative } from "node:path";
|
|
15
|
+
import { basename, dirname, isAbsolute, join, relative, resolve, sep } from "node:path";
|
|
6
16
|
import { DATA_IMPORT_PREFIX } from "../internal/data-dir.js";
|
|
17
|
+
import { discoverSourceImports, type SourceImport } from "../internal/source-imports.js";
|
|
7
18
|
import { removeTempDir } from "../internal/staging-dir.js";
|
|
19
|
+
import {
|
|
20
|
+
isBareRelativeAsset,
|
|
21
|
+
isDataAsset,
|
|
22
|
+
parseIconSpecifier,
|
|
23
|
+
parseResourceSpecifier,
|
|
24
|
+
} from "../vite-plugins/asset-specifier.js";
|
|
8
25
|
import { compileSchemas } from "./compile.js";
|
|
9
26
|
import { type ParsedSchemaFile, parseSchemaXml, SchemaParseError } from "./parser.js";
|
|
10
27
|
import { renderEnvModule } from "./render.js";
|
|
@@ -16,6 +33,9 @@ type SchemaEnvResult = {
|
|
|
16
33
|
|
|
17
34
|
const SCHEMA_SUFFIX = ".gschema.xml";
|
|
18
35
|
const STAGED_NAME_LENGTH = 16;
|
|
36
|
+
const SOURCE_DIR = "src";
|
|
37
|
+
const RESOURCE_QUERY = "?resource=";
|
|
38
|
+
const ICON_QUERY = "?icon=";
|
|
19
39
|
|
|
20
40
|
const prependSchemaDir = (dir: string, existing: string | undefined): string => {
|
|
21
41
|
if (existing === undefined || existing.length === 0) {
|
|
@@ -38,9 +58,150 @@ const stageSchema = (dir: string, filePath: string): void => {
|
|
|
38
58
|
|
|
39
59
|
const toForwardSlashes = (value: string): string => value.replaceAll(/[/\\]/g, "/");
|
|
40
60
|
|
|
61
|
+
const projectRelativeSchemaPath = (root: string, filePath: string): string | null => {
|
|
62
|
+
let rel: string;
|
|
63
|
+
|
|
64
|
+
try {
|
|
65
|
+
rel = relative(realpathSync(root), realpathSync(filePath));
|
|
66
|
+
} catch {
|
|
67
|
+
return null;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
if (rel === "" || rel === ".." || rel.startsWith(`..${sep}`) || isAbsolute(rel)) {
|
|
71
|
+
return null;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
return toForwardSlashes(rel);
|
|
75
|
+
};
|
|
76
|
+
|
|
41
77
|
const getModuleSpecifier = (dataDirAbs: string, filePath: string): string =>
|
|
42
78
|
`${DATA_IMPORT_PREFIX}/${toForwardSlashes(relative(dataDirAbs, filePath))}`;
|
|
43
79
|
|
|
80
|
+
const getRelativeModuleSpecifier = (filePath: string): string => `*/${basename(filePath)}`;
|
|
81
|
+
|
|
82
|
+
const sourceDirFor = (root: string): string => {
|
|
83
|
+
const sourceDir = join(root, SOURCE_DIR);
|
|
84
|
+
|
|
85
|
+
return existsSync(sourceDir) ? sourceDir : root;
|
|
86
|
+
};
|
|
87
|
+
|
|
88
|
+
const isRelativeImport = (source: string): boolean => source.startsWith("./") || source.startsWith("../");
|
|
89
|
+
|
|
90
|
+
const schemaFileFor = ({ importer, source }: SourceImport): string | null =>
|
|
91
|
+
isRelativeImport(source) && source.endsWith(SCHEMA_SUFFIX) ? resolve(dirname(importer), source) : null;
|
|
92
|
+
|
|
93
|
+
const findImportedSchemaFiles = (imports: SourceImport[]): string[] => {
|
|
94
|
+
const files = imports
|
|
95
|
+
.map((entry) => schemaFileFor(entry))
|
|
96
|
+
.filter((path): path is string => path !== null);
|
|
97
|
+
|
|
98
|
+
return sortStrings(new Set(files));
|
|
99
|
+
};
|
|
100
|
+
|
|
101
|
+
const legacyAssetSpecifier = (source: string): string | null =>
|
|
102
|
+
isDataAsset(source) ? source : null;
|
|
103
|
+
|
|
104
|
+
const blockedAssetSpecifier = (source: string): string | null => {
|
|
105
|
+
if (!isBareRelativeAsset(source)) {
|
|
106
|
+
return null;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
const separator = source.lastIndexOf("/");
|
|
110
|
+
const name = source.slice(separator + 1);
|
|
111
|
+
|
|
112
|
+
if (name.includes("*")) {
|
|
113
|
+
throw new Error(
|
|
114
|
+
`Cannot generate an asset declaration for ${JSON.stringify(source)}: filenames cannot contain *`,
|
|
115
|
+
);
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
return `*/${name}`;
|
|
119
|
+
};
|
|
120
|
+
|
|
121
|
+
const resourceModuleSpecifier = (source: string): string | null => {
|
|
122
|
+
const parsed = parseResourceSpecifier(source);
|
|
123
|
+
const queryIndex = source.indexOf(RESOURCE_QUERY);
|
|
124
|
+
|
|
125
|
+
if (queryIndex === -1 || typeof parsed?.resourcePath !== "string") {
|
|
126
|
+
return null;
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
const query = source.slice(queryIndex);
|
|
130
|
+
|
|
131
|
+
if (query.includes("*")) {
|
|
132
|
+
throw new Error(
|
|
133
|
+
`Cannot generate an asset declaration for ${JSON.stringify(source)}: resource paths cannot contain *`,
|
|
134
|
+
);
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
return `*${query}`;
|
|
138
|
+
};
|
|
139
|
+
|
|
140
|
+
const iconModuleSpecifier = (source: string): string | null => {
|
|
141
|
+
const parsed = parseIconSpecifier(source);
|
|
142
|
+
const queryIndex = source.indexOf(ICON_QUERY);
|
|
143
|
+
|
|
144
|
+
if (queryIndex === -1 || typeof parsed?.iconName !== "string") {
|
|
145
|
+
return null;
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
const query = source.slice(queryIndex);
|
|
149
|
+
|
|
150
|
+
if (query.includes("*")) {
|
|
151
|
+
throw new Error(
|
|
152
|
+
`Cannot generate an asset declaration for ${JSON.stringify(source)}: icon names cannot contain *`,
|
|
153
|
+
);
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
return `*${query}`;
|
|
157
|
+
};
|
|
158
|
+
|
|
159
|
+
const findAssetModuleSpecifiers = (
|
|
160
|
+
imports: SourceImport[],
|
|
161
|
+
isV2ResourceImports: boolean,
|
|
162
|
+
): { blocked: string[]; icons: string[]; legacy: string[]; resources: string[] } => {
|
|
163
|
+
const collect = (getSpecifier: (source: string) => string | null): string[] =>
|
|
164
|
+
sortStrings(new Set(imports.map((entry) => getSpecifier(entry.source)).filter((value) => value !== null)));
|
|
165
|
+
|
|
166
|
+
if (isV2ResourceImports) {
|
|
167
|
+
return {
|
|
168
|
+
blocked: collect(blockedAssetSpecifier),
|
|
169
|
+
icons: collect(iconModuleSpecifier),
|
|
170
|
+
legacy: [],
|
|
171
|
+
resources: collect(resourceModuleSpecifier),
|
|
172
|
+
};
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
return { blocked: [], icons: [], legacy: collect(legacyAssetSpecifier), resources: [] };
|
|
176
|
+
};
|
|
177
|
+
|
|
178
|
+
const canonicalPath = (path: string): string => {
|
|
179
|
+
try {
|
|
180
|
+
return realpathSync(path);
|
|
181
|
+
} catch {
|
|
182
|
+
return resolve(path);
|
|
183
|
+
}
|
|
184
|
+
};
|
|
185
|
+
|
|
186
|
+
const assertUniqueSchemaBasenames = (schemaFiles: string[]): void => {
|
|
187
|
+
const owners: Map<string, string> = new Map();
|
|
188
|
+
const canonicalFiles = sortStrings(new Set(schemaFiles.map((path) => canonicalPath(path))));
|
|
189
|
+
|
|
190
|
+
for (const filePath of canonicalFiles) {
|
|
191
|
+
const name = basename(filePath);
|
|
192
|
+
const owner = owners.get(name);
|
|
193
|
+
|
|
194
|
+
if (owner !== undefined && owner !== filePath) {
|
|
195
|
+
throw new Error(
|
|
196
|
+
`Cannot generate types for both ${owner} and ${filePath}: relative GSettings schema imports are ` +
|
|
197
|
+
`typed by basename, and both files are named ${name}. Rename one of them.`,
|
|
198
|
+
);
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
owners.set(name, filePath);
|
|
202
|
+
}
|
|
203
|
+
};
|
|
204
|
+
|
|
44
205
|
const readVisibleEntries = (dir: string): Dirent[] => {
|
|
45
206
|
try {
|
|
46
207
|
return readdirSync(dir, { withFileTypes: true }).filter((entry) => !entry.name.startsWith("."));
|
|
@@ -71,11 +232,11 @@ const findSchemaFiles = (dataDir: string): string[] => {
|
|
|
71
232
|
};
|
|
72
233
|
|
|
73
234
|
const stageAndCompileProjectSchemas = (root: string, dataDir: string | null): string | null => {
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
const schemaFiles =
|
|
235
|
+
const imports = discoverSourceImports(sourceDirFor(root));
|
|
236
|
+
const imported = findImportedSchemaFiles(imports);
|
|
237
|
+
assertUniqueSchemaBasenames(imported);
|
|
238
|
+
const legacy = dataDir === null ? [] : findSchemaFiles(join(root, dataDir));
|
|
239
|
+
const schemaFiles = sortStrings(new Set([...legacy, ...imported]));
|
|
79
240
|
|
|
80
241
|
if (schemaFiles.length === 0) {
|
|
81
242
|
return null;
|
|
@@ -98,9 +259,7 @@ const stageAndCompileProjectSchemas = (root: string, dataDir: string | null): st
|
|
|
98
259
|
|
|
99
260
|
const schemaEnvPath = (rootDir: string): string => join(rootDir, "node_modules", ".gtkx", "env.d.ts");
|
|
100
261
|
|
|
101
|
-
const parseSchemaFileOrWarn = (filePath: string,
|
|
102
|
-
const specifier = getModuleSpecifier(dataDirAbs, filePath);
|
|
103
|
-
|
|
262
|
+
const parseSchemaFileOrWarn = (filePath: string, specifier: string): ParsedSchemaFile | null => {
|
|
104
263
|
try {
|
|
105
264
|
return parseSchemaXml(readFileSync(filePath, "utf8"), specifier);
|
|
106
265
|
} catch (error) {
|
|
@@ -114,11 +273,11 @@ const parseSchemaFileOrWarn = (filePath: string, dataDirAbs: string): ParsedSche
|
|
|
114
273
|
}
|
|
115
274
|
};
|
|
116
275
|
|
|
117
|
-
const parseProjectSchemas = (schemaFiles: string[],
|
|
276
|
+
const parseProjectSchemas = (schemaFiles: string[], specifierFor: (filePath: string) => string): ParsedSchemaFile[] => {
|
|
118
277
|
const parsed: ParsedSchemaFile[] = [];
|
|
119
278
|
|
|
120
279
|
for (const filePath of schemaFiles) {
|
|
121
|
-
const result = parseSchemaFileOrWarn(filePath,
|
|
280
|
+
const result = parseSchemaFileOrWarn(filePath, specifierFor(filePath));
|
|
122
281
|
|
|
123
282
|
if (result !== null) {
|
|
124
283
|
parsed.push(result);
|
|
@@ -147,11 +306,24 @@ const didWriteChanges = (path: string, content: string): boolean => {
|
|
|
147
306
|
return true;
|
|
148
307
|
};
|
|
149
308
|
|
|
150
|
-
const emitSchemaEnv = (
|
|
309
|
+
const emitSchemaEnv = (
|
|
310
|
+
rootDir: string,
|
|
311
|
+
dataDir: string | null,
|
|
312
|
+
isV2ResourceImports = false,
|
|
313
|
+
): SchemaEnvResult => {
|
|
151
314
|
const dataDirAbs = dataDir === null ? null : join(rootDir, dataDir);
|
|
152
|
-
const
|
|
153
|
-
const
|
|
154
|
-
|
|
315
|
+
const legacyFiles = dataDirAbs === null ? [] : findSchemaFiles(dataDirAbs);
|
|
316
|
+
const imports = discoverSourceImports(sourceDirFor(rootDir));
|
|
317
|
+
|
|
318
|
+
const legacy = dataDirAbs === null
|
|
319
|
+
? []
|
|
320
|
+
: parseProjectSchemas(legacyFiles, (filePath) => getModuleSpecifier(dataDirAbs, filePath));
|
|
321
|
+
|
|
322
|
+
const importedFiles = findImportedSchemaFiles(imports);
|
|
323
|
+
assertUniqueSchemaBasenames(importedFiles);
|
|
324
|
+
const imported = parseProjectSchemas(importedFiles, getRelativeModuleSpecifier);
|
|
325
|
+
const assets = findAssetModuleSpecifiers(imports, isV2ResourceImports);
|
|
326
|
+
const content = renderEnvModule([...legacy, ...imported], assets);
|
|
155
327
|
const path = schemaEnvPath(rootDir);
|
|
156
328
|
const isWritten = didWriteChanges(path, content);
|
|
157
329
|
|
|
@@ -162,7 +334,8 @@ export {
|
|
|
162
334
|
SCHEMA_SUFFIX,
|
|
163
335
|
prependSchemaDir,
|
|
164
336
|
stageSchema,
|
|
165
|
-
|
|
337
|
+
assertUniqueSchemaBasenames,
|
|
338
|
+
projectRelativeSchemaPath,
|
|
166
339
|
stageAndCompileProjectSchemas,
|
|
167
340
|
emitSchemaEnv,
|
|
168
341
|
};
|
|
@@ -1,8 +1,17 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { ConfigLoader } from "@gtkx/config";
|
|
2
|
+
import type { ParseResult, ParserOptions, Plugin, UserConfig } from "vite";
|
|
3
|
+
import { createConfigLoader } from "@gtkx/config/internal";
|
|
2
4
|
import { extname } from "node:path";
|
|
3
5
|
import { parseSync } from "vite";
|
|
4
6
|
import { ASSET_MENTION_RE } from "./asset-extensions.js";
|
|
5
|
-
import {
|
|
7
|
+
import {
|
|
8
|
+
DATA_PREFIX,
|
|
9
|
+
isAssetSpecifier,
|
|
10
|
+
isDataAsset,
|
|
11
|
+
isUrlSpecifier,
|
|
12
|
+
parseIconSpecifier,
|
|
13
|
+
parseResourceSpecifier,
|
|
14
|
+
} from "./asset-specifier.js";
|
|
6
15
|
import { RESOURCE_PATH_EXPORT } from "./resource-shared.js";
|
|
7
16
|
import { stripQuery } from "./strip-query.js";
|
|
8
17
|
|
|
@@ -13,6 +22,7 @@ type ExportStatement = ParsedModule["staticExports"][number];
|
|
|
13
22
|
type ExportEntry = ExportStatement["entries"][number];
|
|
14
23
|
type BindingEntry = { importName: { name: string | null }; isType: boolean };
|
|
15
24
|
type NamedBinding = { name: string; source: string };
|
|
25
|
+
type PluginState = { isV2: boolean };
|
|
16
26
|
|
|
17
27
|
const SOURCE_LANGUAGES: Map<string, SourceLanguage> = new Map([
|
|
18
28
|
[".cjs", "jsx"],
|
|
@@ -37,8 +47,12 @@ const BUNDLE_ADVICE =
|
|
|
37
47
|
"nothing else.";
|
|
38
48
|
|
|
39
49
|
const QUERY_ADVICE =
|
|
40
|
-
|
|
41
|
-
|
|
50
|
+
`A URL asset exports only its default filesystem path; import the default instead of ${RESOURCE_BINDING}.`;
|
|
51
|
+
|
|
52
|
+
const RESOURCE_ADVICE =
|
|
53
|
+
`A resource asset exports only its default GResource path and ${RESOURCE_BINDING}, and nothing else.`;
|
|
54
|
+
|
|
55
|
+
const ICON_ADVICE = "An icon asset exports only its default icon-theme name, and nothing else.";
|
|
42
56
|
|
|
43
57
|
const RELATIVE_ADVICE =
|
|
44
58
|
`Only assets imported through "${DATA_PREFIX}" are staged into the GResource bundle and export ` +
|
|
@@ -76,34 +90,54 @@ const bindings = (parsed: ParsedModule): NamedBinding[] => [
|
|
|
76
90
|
...parsed.staticExports.flatMap((statement) => exportBindings(statement)),
|
|
77
91
|
];
|
|
78
92
|
|
|
79
|
-
const isBacked = ({ name, source }: NamedBinding): boolean =>
|
|
80
|
-
|
|
93
|
+
const isBacked = ({ name, source }: NamedBinding, isV2: boolean): boolean => {
|
|
94
|
+
if (name !== RESOURCE_PATH_EXPORT) {
|
|
95
|
+
return false;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
return isV2 ? parseResourceSpecifier(source) !== null : isDataAsset(source);
|
|
99
|
+
};
|
|
100
|
+
|
|
101
|
+
const isCheckedSpecifier = (source: string): boolean => isAssetSpecifier(source) || isUrlSpecifier(source);
|
|
102
|
+
|
|
103
|
+
const unbackedBinding = (parsed: ParsedModule, isV2: boolean): NamedBinding | undefined =>
|
|
104
|
+
bindings(parsed).find((binding) => isCheckedSpecifier(binding.source) && !isBacked(binding, isV2));
|
|
81
105
|
|
|
82
|
-
const
|
|
83
|
-
|
|
106
|
+
const isBundledResource = (source: string, isV2: boolean): boolean =>
|
|
107
|
+
isV2
|
|
108
|
+
? parseResourceSpecifier(source) !== null || parseIconSpecifier(source) !== null
|
|
109
|
+
: isDataAsset(source);
|
|
84
110
|
|
|
85
|
-
const
|
|
86
|
-
|
|
87
|
-
|
|
111
|
+
const v2BundleAdvice = (source: string): string =>
|
|
112
|
+
parseIconSpecifier(source) === null ? RESOURCE_ADVICE : ICON_ADVICE;
|
|
113
|
+
|
|
114
|
+
const bundleAdvice = (source: string, isV2: boolean): string => {
|
|
115
|
+
if (isBundledResource(source, isV2)) {
|
|
116
|
+
return isV2 ? v2BundleAdvice(source) : BUNDLE_ADVICE;
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
if (isUrlSpecifier(source)) {
|
|
120
|
+
return QUERY_ADVICE;
|
|
88
121
|
}
|
|
89
122
|
|
|
90
123
|
return source.startsWith(DATA_PREFIX) ? QUERY_ADVICE : RELATIVE_ADVICE;
|
|
91
124
|
};
|
|
92
125
|
|
|
93
|
-
const unbackedBindingError = (path: string, binding: NamedBinding): Error =>
|
|
126
|
+
const unbackedBindingError = (path: string, binding: NamedBinding, isV2: boolean): Error =>
|
|
94
127
|
new Error(
|
|
95
128
|
`${path}: ${JSON.stringify(binding.source)} does not export ${JSON.stringify(binding.name)}, which ` +
|
|
96
129
|
"gtkx build rejects and gtkx dev would bind as undefined. " +
|
|
97
|
-
bundleAdvice(binding.source),
|
|
130
|
+
bundleAdvice(binding.source, isV2),
|
|
98
131
|
);
|
|
99
132
|
|
|
100
133
|
const isCheckedSource = (path: string): boolean => !path.startsWith(VIRTUAL_PREFIX) && !NODE_MODULES.test(path);
|
|
134
|
+
const hasCheckedAssetMention = (code: string): boolean => ASSET_MENTION_RE.test(code) || code.includes("?url");
|
|
101
135
|
|
|
102
|
-
const checkAssetImports = (code: string, id: string): void => {
|
|
136
|
+
const checkAssetImports = (code: string, id: string, isV2: boolean): void => {
|
|
103
137
|
const path = stripQuery(id);
|
|
104
138
|
const lang = SOURCE_LANGUAGES.get(extname(path).toLowerCase());
|
|
105
139
|
|
|
106
|
-
if (lang === undefined || !isCheckedSource(path) || !
|
|
140
|
+
if (lang === undefined || !isCheckedSource(path) || !hasCheckedAssetMention(code)) {
|
|
107
141
|
return;
|
|
108
142
|
}
|
|
109
143
|
|
|
@@ -113,20 +147,27 @@ const checkAssetImports = (code: string, id: string): void => {
|
|
|
113
147
|
return;
|
|
114
148
|
}
|
|
115
149
|
|
|
116
|
-
const binding = unbackedBinding(parsed.module);
|
|
150
|
+
const binding = unbackedBinding(parsed.module, isV2);
|
|
117
151
|
|
|
118
152
|
if (binding !== undefined) {
|
|
119
|
-
throw unbackedBindingError(path, binding);
|
|
153
|
+
throw unbackedBindingError(path, binding, isV2);
|
|
120
154
|
}
|
|
121
155
|
};
|
|
122
156
|
|
|
123
|
-
function gtkxAssetImports(): Plugin {
|
|
157
|
+
function gtkxAssetImports(loadConfig: ConfigLoader = createConfigLoader()): Plugin {
|
|
158
|
+
const state: PluginState = { isV2: false };
|
|
159
|
+
|
|
124
160
|
return {
|
|
125
161
|
name: "gtkx:asset-imports",
|
|
126
162
|
enforce: "pre",
|
|
127
163
|
|
|
164
|
+
async config(config: UserConfig) {
|
|
165
|
+
const loaded = await loadConfig.load(config.root ?? process.cwd());
|
|
166
|
+
state.isV2 = loaded.config.future?.v2ResourceImports === true;
|
|
167
|
+
},
|
|
168
|
+
|
|
128
169
|
transform(code, id) {
|
|
129
|
-
checkAssetImports(code, id);
|
|
170
|
+
checkAssetImports(code, id, state.isV2);
|
|
130
171
|
},
|
|
131
172
|
};
|
|
132
173
|
}
|