@gtkx/cli 1.6.0 → 2.0.0-beta.1

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.
Files changed (186) hide show
  1. package/README.md +5 -5
  2. package/dist/codegen/freshness.d.ts.map +1 -1
  3. package/dist/codegen/freshness.js +45 -16
  4. package/dist/codegen/freshness.js.map +1 -1
  5. package/dist/codegen/reference.d.ts.map +1 -1
  6. package/dist/codegen/reference.js +1 -7
  7. package/dist/codegen/reference.js.map +1 -1
  8. package/dist/codegen/report.d.ts.map +1 -1
  9. package/dist/codegen/report.js +5 -16
  10. package/dist/codegen/report.js.map +1 -1
  11. package/dist/codegen/run-codegen.d.ts +3 -5
  12. package/dist/codegen/run-codegen.d.ts.map +1 -1
  13. package/dist/codegen/run-codegen.js +23 -100
  14. package/dist/codegen/run-codegen.js.map +1 -1
  15. package/dist/codegen/store-resolver.d.ts +0 -1
  16. package/dist/codegen/store-resolver.d.ts.map +1 -1
  17. package/dist/codegen/store-resolver.js +8 -17
  18. package/dist/codegen/store-resolver.js.map +1 -1
  19. package/dist/commands/docs.d.ts.map +1 -1
  20. package/dist/commands/docs.js +5 -15
  21. package/dist/commands/docs.js.map +1 -1
  22. package/dist/deploy/freedesktop/copyright.d.ts.map +1 -1
  23. package/dist/deploy/freedesktop/copyright.js +2 -13
  24. package/dist/deploy/freedesktop/copyright.js.map +1 -1
  25. package/dist/deploy/freedesktop/xml.d.ts.map +1 -1
  26. package/dist/deploy/freedesktop/xml.js +21 -25
  27. package/dist/deploy/freedesktop/xml.js.map +1 -1
  28. package/dist/deploy/node-runtime/license.d.ts.map +1 -1
  29. package/dist/deploy/node-runtime/license.js +2 -9
  30. package/dist/deploy/node-runtime/license.js.map +1 -1
  31. package/dist/deploy/notices/packages.d.ts.map +1 -1
  32. package/dist/deploy/notices/packages.js +3 -10
  33. package/dist/deploy/notices/packages.js.map +1 -1
  34. package/dist/deploy/payload/copy-tree.d.ts.map +1 -1
  35. package/dist/deploy/payload/copy-tree.js +3 -3
  36. package/dist/deploy/payload/copy-tree.js.map +1 -1
  37. package/dist/deploy/payload/stage.d.ts.map +1 -1
  38. package/dist/deploy/payload/stage.js +1 -3
  39. package/dist/deploy/payload/stage.js.map +1 -1
  40. package/dist/deploy/settings/build-manifest.d.ts.map +1 -1
  41. package/dist/deploy/settings/build-manifest.js +4 -15
  42. package/dist/deploy/settings/build-manifest.js.map +1 -1
  43. package/dist/deploy/settings/libraries.d.ts.map +1 -1
  44. package/dist/deploy/settings/libraries.js +2 -19
  45. package/dist/deploy/settings/libraries.js.map +1 -1
  46. package/dist/deploy/settings/paths.d.ts +1 -2
  47. package/dist/deploy/settings/paths.d.ts.map +1 -1
  48. package/dist/deploy/settings/paths.js +5 -15
  49. package/dist/deploy/settings/paths.js.map +1 -1
  50. package/dist/deploy/settings/screenshots.d.ts.map +1 -1
  51. package/dist/deploy/settings/screenshots.js +6 -31
  52. package/dist/deploy/settings/screenshots.js.map +1 -1
  53. package/dist/deploy/targets/flatpak-pnpm.js +4 -4
  54. package/dist/deploy/targets/flatpak-pnpm.js.map +1 -1
  55. package/dist/deploy/targets/flatpak-source.d.ts.map +1 -1
  56. package/dist/deploy/targets/flatpak-source.js +4 -4
  57. package/dist/deploy/targets/flatpak-source.js.map +1 -1
  58. package/dist/deploy/targets/flatpak-sources.js +1 -1
  59. package/dist/deploy/targets/flatpak-sources.js.map +1 -1
  60. package/dist/dev/runner-main.d.ts.map +1 -1
  61. package/dist/dev/runner-main.js +1 -2
  62. package/dist/dev/runner-main.js.map +1 -1
  63. package/dist/dev/schema-dir.d.ts +1 -1
  64. package/dist/dev/schema-dir.d.ts.map +1 -1
  65. package/dist/dev/schema-dir.js +2 -4
  66. package/dist/dev/schema-dir.js.map +1 -1
  67. package/dist/i18n/catalogs.d.ts.map +1 -1
  68. package/dist/i18n/catalogs.js +2 -1
  69. package/dist/i18n/catalogs.js.map +1 -1
  70. package/dist/i18n/metadata-templates.d.ts.map +1 -1
  71. package/dist/i18n/metadata-templates.js +2 -1
  72. package/dist/i18n/metadata-templates.js.map +1 -1
  73. package/dist/i18n/source-messages.d.ts +3 -21
  74. package/dist/i18n/source-messages.d.ts.map +1 -1
  75. package/dist/i18n/source-messages.js +66 -85
  76. package/dist/i18n/source-messages.js.map +1 -1
  77. package/dist/i18n/types.d.ts +6 -7
  78. package/dist/i18n/types.d.ts.map +1 -1
  79. package/dist/i18n/types.js +83 -96
  80. package/dist/i18n/types.js.map +1 -1
  81. package/dist/internal/docs-elements.js +2 -2
  82. package/dist/internal/docs-elements.js.map +1 -1
  83. package/dist/internal/icon-path.d.ts.map +1 -1
  84. package/dist/internal/icon-path.js +5 -16
  85. package/dist/internal/icon-path.js.map +1 -1
  86. package/dist/internal/source-imports.d.ts.map +1 -1
  87. package/dist/internal/source-imports.js +10 -41
  88. package/dist/internal/source-imports.js.map +1 -1
  89. package/dist/settings/render.d.ts +0 -1
  90. package/dist/settings/render.d.ts.map +1 -1
  91. package/dist/settings/render.js +1 -11
  92. package/dist/settings/render.js.map +1 -1
  93. package/dist/settings/schema.d.ts +2 -2
  94. package/dist/settings/schema.d.ts.map +1 -1
  95. package/dist/settings/schema.js +21 -62
  96. package/dist/settings/schema.js.map +1 -1
  97. package/dist/vite-plugins/asset-imports.d.ts +1 -2
  98. package/dist/vite-plugins/asset-imports.d.ts.map +1 -1
  99. package/dist/vite-plugins/asset-imports.js +19 -32
  100. package/dist/vite-plugins/asset-imports.js.map +1 -1
  101. package/dist/vite-plugins/asset-specifier.d.ts +1 -3
  102. package/dist/vite-plugins/asset-specifier.d.ts.map +1 -1
  103. package/dist/vite-plugins/asset-specifier.js +1 -4
  104. package/dist/vite-plugins/asset-specifier.js.map +1 -1
  105. package/dist/vite-plugins/i18n.d.ts.map +1 -1
  106. package/dist/vite-plugins/i18n.js +2 -1
  107. package/dist/vite-plugins/i18n.js.map +1 -1
  108. package/dist/vite-plugins/index.d.ts.map +1 -1
  109. package/dist/vite-plugins/index.js +2 -4
  110. package/dist/vite-plugins/index.js.map +1 -1
  111. package/dist/vite-plugins/resources.d.ts.map +1 -1
  112. package/dist/vite-plugins/resources.js +32 -97
  113. package/dist/vite-plugins/resources.js.map +1 -1
  114. package/dist/vite-plugins/settings-worker-env.d.ts.map +1 -1
  115. package/dist/vite-plugins/settings-worker-env.js +2 -4
  116. package/dist/vite-plugins/settings-worker-env.js.map +1 -1
  117. package/dist/vite-plugins/settings.d.ts +1 -2
  118. package/dist/vite-plugins/settings.d.ts.map +1 -1
  119. package/dist/vite-plugins/settings.js +8 -14
  120. package/dist/vite-plugins/settings.js.map +1 -1
  121. package/dist/vite-plugins/undeclared-library.d.ts.map +1 -1
  122. package/dist/vite-plugins/undeclared-library.js +10 -13
  123. package/dist/vite-plugins/undeclared-library.js.map +1 -1
  124. package/dist/vite-plugins/worker.d.ts.map +1 -1
  125. package/dist/vite-plugins/worker.js +0 -1
  126. package/dist/vite-plugins/worker.js.map +1 -1
  127. package/package.json +21 -15
  128. package/src/codegen/freshness.ts +66 -17
  129. package/src/codegen/reference.ts +1 -8
  130. package/src/codegen/report.ts +5 -21
  131. package/src/codegen/run-codegen.ts +28 -145
  132. package/src/codegen/store-resolver.ts +8 -24
  133. package/src/commands/docs.ts +5 -17
  134. package/src/deploy/freedesktop/copyright.ts +2 -14
  135. package/src/deploy/freedesktop/xml.ts +24 -32
  136. package/src/deploy/node-runtime/license.ts +2 -8
  137. package/src/deploy/notices/packages.ts +3 -11
  138. package/src/deploy/payload/copy-tree.ts +3 -4
  139. package/src/deploy/payload/stage.ts +2 -6
  140. package/src/deploy/settings/build-manifest.ts +4 -16
  141. package/src/deploy/settings/libraries.ts +1 -22
  142. package/src/deploy/settings/paths.ts +6 -16
  143. package/src/deploy/settings/screenshots.ts +8 -46
  144. package/src/deploy/targets/flatpak-pnpm.ts +4 -4
  145. package/src/deploy/targets/flatpak-source.ts +4 -4
  146. package/src/deploy/targets/flatpak-sources.ts +1 -1
  147. package/src/dev/runner-main.ts +1 -2
  148. package/src/dev/schema-dir.ts +2 -4
  149. package/src/i18n/catalogs.ts +2 -1
  150. package/src/i18n/metadata-templates.ts +2 -1
  151. package/src/i18n/source-messages.ts +77 -115
  152. package/src/i18n/types.ts +97 -131
  153. package/src/internal/docs-elements.ts +2 -2
  154. package/src/internal/icon-path.ts +6 -19
  155. package/src/internal/source-imports.ts +14 -50
  156. package/src/settings/render.ts +1 -13
  157. package/src/settings/schema.ts +19 -81
  158. package/src/vite-plugins/asset-imports.ts +20 -44
  159. package/src/vite-plugins/asset-specifier.ts +0 -5
  160. package/src/vite-plugins/i18n.ts +2 -1
  161. package/src/vite-plugins/index.ts +2 -4
  162. package/src/vite-plugins/resources.ts +37 -140
  163. package/src/vite-plugins/settings-worker-env.ts +2 -4
  164. package/src/vite-plugins/settings.ts +11 -20
  165. package/src/vite-plugins/undeclared-library.ts +14 -20
  166. package/src/vite-plugins/worker.ts +0 -1
  167. package/dist/i18n/binding-extractor.d.ts +0 -30
  168. package/dist/i18n/binding-extractor.d.ts.map +0 -1
  169. package/dist/i18n/binding-extractor.js +0 -1324
  170. package/dist/i18n/binding-extractor.js.map +0 -1
  171. package/dist/i18n/extractor-plugin.d.ts +0 -8
  172. package/dist/i18n/extractor-plugin.d.ts.map +0 -1
  173. package/dist/i18n/extractor-plugin.js +0 -247
  174. package/dist/i18n/extractor-plugin.js.map +0 -1
  175. package/dist/internal/data-dir.d.ts +0 -4
  176. package/dist/internal/data-dir.d.ts.map +0 -1
  177. package/dist/internal/data-dir.js +0 -52
  178. package/dist/internal/data-dir.js.map +0 -1
  179. package/dist/vite-plugins/animated.d.ts +0 -5
  180. package/dist/vite-plugins/animated.d.ts.map +0 -1
  181. package/dist/vite-plugins/animated.js +0 -325
  182. package/dist/vite-plugins/animated.js.map +0 -1
  183. package/src/i18n/binding-extractor.ts +0 -1969
  184. package/src/i18n/extractor-plugin.ts +0 -413
  185. package/src/internal/data-dir.ts +0 -70
  186. package/src/vite-plugins/animated.ts +0 -486
@@ -1,5 +1,6 @@
1
- import { type Stats, statSync } from "node:fs";
2
- import { basename, extname, isAbsolute, join, relative, resolve } from "node:path";
1
+ import { isPathInside } from "@gtkx/utils";
2
+ import { statSync } from "node:fs";
3
+ import { basename, extname, isAbsolute, join, resolve } from "node:path";
3
4
 
4
5
  type ResolvedApplicationIcon = { kind: "file"; path: string } |
5
6
  { kind: "none" } |
@@ -10,20 +11,6 @@ const SCALABLE_DIR = "hicolor/scalable/apps";
10
11
  const SIZE_PATTERN = /^(?<width>[1-9]\d{0,3})x(?<height>[1-9]\d{0,3})$/;
11
12
  const SIZE_SEPARATORS = /[-_.]/;
12
13
 
13
- const isInside = (parent: string, candidate: string): boolean => {
14
- const rel = relative(parent, candidate);
15
-
16
- return rel.length > 0 && !rel.startsWith("..") && !isAbsolute(rel);
17
- };
18
-
19
- const getStats = (path: string): Stats | undefined => {
20
- try {
21
- return statSync(path, { throwIfNoEntry: false });
22
- } catch {
23
- return undefined;
24
- }
25
- };
26
-
27
14
  const iconExtension = (file: string): string => {
28
15
  const extension = extname(file).toLowerCase();
29
16
 
@@ -37,7 +24,7 @@ const iconExtension = (file: string): string => {
37
24
  const defaultIconFiles = (root: string, applicationId: string): string[] =>
38
25
  [...ICON_EXTENSIONS]
39
26
  .map((extension) => join(root, `${applicationId}${extension}`))
40
- .filter((path) => getStats(path)?.isFile() === true);
27
+ .filter((path) => statSync(path, { throwIfNoEntry: false })?.isFile() === true);
41
28
 
42
29
  const resolveDefaultApplicationIcon = (root: string, applicationId: string): ResolvedApplicationIcon => {
43
30
  const files = defaultIconFiles(root, applicationId);
@@ -76,11 +63,11 @@ const resolveApplicationIcon = (
76
63
 
77
64
  const path = resolve(root, configured);
78
65
 
79
- if (!isInside(root, path)) {
66
+ if (!isPathInside(root, path)) {
80
67
  throw new Error(`Cannot use "${configured}" as the application icon: it is outside ${root}`);
81
68
  }
82
69
 
83
- const stats = getStats(path);
70
+ const stats = statSync(path, { throwIfNoEntry: false });
84
71
 
85
72
  if (stats?.isDirectory() === true) {
86
73
  return { kind: "theme", path };
@@ -1,6 +1,6 @@
1
1
  import type { ESTree, ParseResult, ParserOptions } from "vite";
2
2
  import { sortStringsBy } from "@gtkx/utils";
3
- import { type Dirent, readdirSync, readFileSync } from "node:fs";
3
+ import { globSync, readFileSync } from "node:fs";
4
4
  import { extname, join } from "node:path";
5
5
  import { parseSync, Visitor } from "vite";
6
6
 
@@ -13,8 +13,6 @@ type SourceLanguage = NonNullable<ParserOptions["lang"]>;
13
13
  type ParsedModule = ParseResult["module"];
14
14
 
15
15
  const SOURCE_LANGUAGES: Map<string, SourceLanguage> = new Map([
16
- [".cjs", "jsx"],
17
- [".cts", "ts"],
18
16
  [".js", "jsx"],
19
17
  [".jsx", "jsx"],
20
18
  [".mjs", "jsx"],
@@ -23,60 +21,26 @@ const SOURCE_LANGUAGES: Map<string, SourceLanguage> = new Map([
23
21
  [".tsx", "tsx"],
24
22
  ]);
25
23
 
26
- const EXCLUDED_DIRECTORIES: Set<string> = new Set([
27
- "build",
28
- "coverage",
29
- "dist",
30
- "node_modules",
31
- "out-tsc",
32
- ]);
33
-
34
24
  const sourceLanguage = (path: string): SourceLanguage | undefined => {
35
- if (path.endsWith(".d.ts") || path.endsWith(".d.cts") || path.endsWith(".d.mts")) {
25
+ if (path.endsWith(".d.ts") || path.endsWith(".d.mts")) {
36
26
  return undefined;
37
27
  }
38
28
 
39
29
  return SOURCE_LANGUAGES.get(extname(path).toLowerCase());
40
30
  };
41
31
 
42
- const isWalkableDirectory = (name: string): boolean => !name.startsWith(".") && !EXCLUDED_DIRECTORIES.has(name);
43
-
44
- const collectSourceEntry = (dir: string, entry: Dirent, found: string[]): void => {
45
- const path = join(dir, entry.name);
46
-
47
- if (entry.isDirectory()) {
48
- if (isWalkableDirectory(entry.name)) {
49
- sourceFilesIn(path, found);
50
- }
51
-
52
- return;
53
- }
54
-
55
- if (entry.isFile() && sourceLanguage(path) !== undefined) {
56
- found.push(path);
57
- }
58
- };
59
-
60
- const sourceFilesIn = (dir: string, found: string[]): void => {
61
- let entries: Dirent[];
62
-
63
- try {
64
- entries = readdirSync(dir, { withFileTypes: true });
65
- } catch {
66
- return;
67
- }
68
-
69
- for (const entry of entries) {
70
- collectSourceEntry(dir, entry, found);
71
- }
72
- };
73
-
74
- const discoverSourceFiles = (dir: string): string[] => {
75
- const files: string[] = [];
76
- sourceFilesIn(dir, files);
77
-
78
- return sortStringsBy(files, (path) => path);
79
- };
32
+ const discoverSourceFiles = (dir: string): string[] =>
33
+ sortStringsBy(
34
+ globSync("**/{*,.*}", {
35
+ cwd: dir,
36
+ exclude: ["**/{build,coverage,dist,node_modules,out-tsc}/**"],
37
+ withFileTypes: true,
38
+ })
39
+ .filter((entry) => entry.isFile())
40
+ .map((entry) => join(entry.parentPath, entry.name))
41
+ .filter((path) => sourceLanguage(path) !== undefined),
42
+ (path) => path,
43
+ );
80
44
 
81
45
  const staticImportSources = (module: ParsedModule): string[] => [
82
46
  ...module.staticImports.map((statement) => statement.moduleRequest.value),
@@ -9,7 +9,6 @@ type NamedSchema = {
9
9
  type EnvAssetDeclarations = {
10
10
  blocked: string[];
11
11
  icons: string[];
12
- legacy: string[];
13
12
  resources: string[];
14
13
  };
15
14
 
@@ -209,15 +208,6 @@ const renderIconModule = (specifier: string): string => [
209
208
  "}",
210
209
  ].join("\n");
211
210
 
212
- const renderLegacyAssetModule = (specifier: string): string => [
213
- `declare module ${toJsStringLiteral(specifier)} {`,
214
- " const resourceUri: string;",
215
- " const path: string;",
216
- " export { path };",
217
- " export default resourceUri;",
218
- "}",
219
- ].join("\n");
220
-
221
211
  const renderBlockedAssetModule = (specifier: string): string => [
222
212
  `declare module ${toJsStringLiteral(specifier)} {`,
223
213
  " const assetImportRequiresResourceOrUrlQuery: {",
@@ -232,7 +222,7 @@ const renderEnvModule = (
232
222
  assetDeclarations?: EnvAssetDeclarations,
233
223
  options: EnvModuleOptions = {},
234
224
  ): string => {
235
- const assets = assetDeclarations ?? { blocked: [], icons: [], legacy: [], resources: [] };
225
+ const assets = assetDeclarations ?? { blocked: [], icons: [], resources: [] };
236
226
  const usedNames: Set<string> = new Set();
237
227
 
238
228
  const schemas = files
@@ -241,7 +231,6 @@ const renderEnvModule = (
241
231
 
242
232
  const blocked = assets.blocked.map((specifier) => renderBlockedAssetModule(specifier));
243
233
  const icons = assets.icons.map((specifier) => renderIconModule(specifier));
244
- const legacy = assets.legacy.map((specifier) => renderLegacyAssetModule(specifier));
245
234
  const resources = assets.resources.map((specifier) => renderResourceModule(specifier));
246
235
  const references = (options.references ?? []).map((path) => `/// <reference path=${JSON.stringify(path)} />`);
247
236
 
@@ -250,7 +239,6 @@ const renderEnvModule = (
250
239
  ...references,
251
240
  ...blocked,
252
241
  ...icons,
253
- ...legacy,
254
242
  ...resources,
255
243
  ...schemas,
256
244
  ].join("\n\n")}\n`;
@@ -1,25 +1,21 @@
1
- import { sortStrings, warn } from "@gtkx/utils";
1
+ import { isPathInside, sortStrings, toPosixPath, warn } from "@gtkx/utils";
2
2
  import { createHash } from "node:crypto";
3
3
  import {
4
4
  copyFileSync,
5
- type Dirent,
6
5
  existsSync,
7
6
  mkdirSync,
8
7
  mkdtempSync,
9
- readdirSync,
10
8
  readFileSync,
11
9
  realpathSync,
12
10
  writeFileSync,
13
11
  } from "node:fs";
14
12
  import { tmpdir } from "node:os";
15
- import { basename, dirname, isAbsolute, join, relative, resolve, sep } from "node:path";
13
+ import { basename, dirname, join, relative, resolve } from "node:path";
16
14
  import { I18N_TYPES_FILENAME, i18nTypesPath } from "../i18n/types.js";
17
- import { DATA_IMPORT_PREFIX } from "../internal/data-dir.js";
18
15
  import { discoverSourceImports, type SourceImport } from "../internal/source-imports.js";
19
16
  import { removeTempDir } from "../internal/staging-dir.js";
20
17
  import {
21
18
  isBareRelativeAsset,
22
- isDataAsset,
23
19
  parseIconSpecifier,
24
20
  parseResourceSpecifier,
25
21
  } from "../vite-plugins/asset-specifier.js";
@@ -57,27 +53,20 @@ const stageSchema = (dir: string, filePath: string): void => {
57
53
  copyFileSync(filePath, join(dir, stagedSchemaName(filePath)));
58
54
  };
59
55
 
60
- const toForwardSlashes = (value: string): string => value.replaceAll(/[/\\]/g, "/");
61
-
62
56
  const projectRelativeSchemaPath = (root: string, filePath: string): string | null => {
63
- let rel: string;
57
+ let projectRoot: string;
58
+ let path: string;
64
59
 
65
60
  try {
66
- rel = relative(realpathSync(root), realpathSync(filePath));
61
+ projectRoot = realpathSync(root);
62
+ path = realpathSync(filePath);
67
63
  } catch {
68
64
  return null;
69
65
  }
70
66
 
71
- if (rel === "" || rel === ".." || rel.startsWith(`..${sep}`) || isAbsolute(rel)) {
72
- return null;
73
- }
74
-
75
- return toForwardSlashes(rel);
67
+ return isPathInside(projectRoot, path) ? toPosixPath(relative(projectRoot, path)) : null;
76
68
  };
77
69
 
78
- const getModuleSpecifier = (dataDirAbs: string, filePath: string): string =>
79
- `${DATA_IMPORT_PREFIX}/${toForwardSlashes(relative(dataDirAbs, filePath))}`;
80
-
81
70
  const getRelativeModuleSpecifier = (filePath: string): string => `*/${basename(filePath)}`;
82
71
 
83
72
  const sourceDirFor = (root: string): string => {
@@ -99,9 +88,6 @@ const findImportedSchemaFiles = (imports: SourceImport[]): string[] => {
99
88
  return sortStrings(new Set(files));
100
89
  };
101
90
 
102
- const legacyAssetSpecifier = (source: string): string | null =>
103
- isDataAsset(source) ? source : null;
104
-
105
91
  const blockedAssetSpecifier = (source: string): string | null => {
106
92
  if (!isBareRelativeAsset(source)) {
107
93
  return null;
@@ -159,21 +145,15 @@ const iconModuleSpecifier = (source: string): string | null => {
159
145
 
160
146
  const findAssetModuleSpecifiers = (
161
147
  imports: SourceImport[],
162
- isV2ResourceImports: boolean,
163
- ): { blocked: string[]; icons: string[]; legacy: string[]; resources: string[] } => {
148
+ ): { blocked: string[]; icons: string[]; resources: string[] } => {
164
149
  const collect = (getSpecifier: (source: string) => string | null): string[] =>
165
150
  sortStrings(new Set(imports.map((entry) => getSpecifier(entry.source)).filter((value) => value !== null)));
166
151
 
167
- if (isV2ResourceImports) {
168
- return {
169
- blocked: collect(blockedAssetSpecifier),
170
- icons: collect(iconModuleSpecifier),
171
- legacy: [],
172
- resources: collect(resourceModuleSpecifier),
173
- };
174
- }
175
-
176
- return { blocked: [], icons: [], legacy: collect(legacyAssetSpecifier), resources: [] };
152
+ return {
153
+ blocked: collect(blockedAssetSpecifier),
154
+ icons: collect(iconModuleSpecifier),
155
+ resources: collect(resourceModuleSpecifier),
156
+ };
177
157
  };
178
158
 
179
159
  const canonicalPath = (path: string): string => {
@@ -203,41 +183,10 @@ const assertUniqueSchemaBasenames = (schemaFiles: string[]): void => {
203
183
  }
204
184
  };
205
185
 
206
- const readVisibleEntries = (dir: string): Dirent[] => {
207
- try {
208
- return readdirSync(dir, { withFileTypes: true }).filter((entry) => !entry.name.startsWith("."));
209
- } catch {
210
- return [];
211
- }
212
- };
213
-
214
- const isSchemaFile = (entry: Dirent): boolean => entry.isFile() && entry.name.endsWith(SCHEMA_SUFFIX);
215
-
216
- const collectSchemaFiles = (dir: string, found: string[]): void => {
217
- for (const entry of readVisibleEntries(dir)) {
218
- const full = join(dir, entry.name);
219
-
220
- if (entry.isDirectory()) {
221
- collectSchemaFiles(full, found);
222
- } else if (isSchemaFile(entry)) {
223
- found.push(full);
224
- }
225
- }
226
- };
227
-
228
- const findSchemaFiles = (dataDir: string): string[] => {
229
- const found: string[] = [];
230
- collectSchemaFiles(dataDir, found);
231
-
232
- return sortStrings(found);
233
- };
234
-
235
- const stageAndCompileProjectSchemas = (root: string, dataDir: string | null): string | null => {
186
+ const stageAndCompileProjectSchemas = (root: string): string | null => {
236
187
  const imports = discoverSourceImports(sourceDirFor(root));
237
- const imported = findImportedSchemaFiles(imports);
238
- assertUniqueSchemaBasenames(imported);
239
- const legacy = dataDir === null ? [] : findSchemaFiles(join(root, dataDir));
240
- const schemaFiles = sortStrings(new Set([...legacy, ...imported]));
188
+ const schemaFiles = findImportedSchemaFiles(imports);
189
+ assertUniqueSchemaBasenames(schemaFiles);
241
190
 
242
191
  if (schemaFiles.length === 0) {
243
192
  return null;
@@ -307,25 +256,14 @@ const didWriteChanges = (path: string, content: string): boolean => {
307
256
  return true;
308
257
  };
309
258
 
310
- const emitSchemaEnv = (
311
- rootDir: string,
312
- dataDir: string | null,
313
- isV2ResourceImports = false,
314
- ): SchemaEnvResult => {
315
- const dataDirAbs = dataDir === null ? null : join(rootDir, dataDir);
316
- const legacyFiles = dataDirAbs === null ? [] : findSchemaFiles(dataDirAbs);
259
+ const emitSchemaEnv = (rootDir: string): SchemaEnvResult => {
317
260
  const imports = discoverSourceImports(sourceDirFor(rootDir));
318
-
319
- const legacy = dataDirAbs === null
320
- ? []
321
- : parseProjectSchemas(legacyFiles, (filePath) => getModuleSpecifier(dataDirAbs, filePath));
322
-
323
261
  const importedFiles = findImportedSchemaFiles(imports);
324
262
  assertUniqueSchemaBasenames(importedFiles);
325
263
  const imported = parseProjectSchemas(importedFiles, getRelativeModuleSpecifier);
326
- const assets = findAssetModuleSpecifiers(imports, isV2ResourceImports);
264
+ const assets = findAssetModuleSpecifiers(imports);
327
265
  const references = existsSync(i18nTypesPath(rootDir)) ? [`./${I18N_TYPES_FILENAME}`] : [];
328
- const content = renderEnvModule([...legacy, ...imported], assets, { references });
266
+ const content = renderEnvModule(imported, assets, { references });
329
267
  const path = schemaEnvPath(rootDir);
330
268
  const isWritten = didWriteChanges(path, content);
331
269
 
@@ -1,13 +1,9 @@
1
- import type { ConfigLoader } from "@gtkx/config";
2
- import type { ParseResult, Plugin, UserConfig } from "vite";
3
- import { createConfigLoader, resolveFuture } from "@gtkx/config/internal";
1
+ import type { ParseResult, Plugin } from "vite";
4
2
  import { parseSync } from "vite";
5
3
  import { sourceLanguage } from "../internal/source-imports.js";
6
4
  import { ASSET_MENTION_RE } from "./asset-extensions.js";
7
5
  import {
8
- DATA_PREFIX,
9
6
  isAssetSpecifier,
10
- isDataAsset,
11
7
  isUrlSpecifier,
12
8
  parseIconSpecifier,
13
9
  parseResourceSpecifier,
@@ -21,18 +17,11 @@ type ExportStatement = ParsedModule["staticExports"][number];
21
17
  type ExportEntry = ExportStatement["entries"][number];
22
18
  type BindingEntry = { importName: { name: string | null }; isType: boolean };
23
19
  type NamedBinding = { name: string; source: string };
24
- type PluginState = { isV2: boolean };
25
20
 
26
21
  const NODE_MODULES = /(?:^|\/)node_modules\//;
27
22
  const VIRTUAL_PREFIX = "\0";
28
23
  const DEFAULT_BINDING = "default";
29
24
  const RESOURCE_BINDING = JSON.stringify(RESOURCE_PATH_EXPORT);
30
- const DATA_IMPORT_EXAMPLE = `"${DATA_PREFIX}<path>"`;
31
- const URL_FALLBACK = ", or import the default for the asset URL.";
32
-
33
- const BUNDLE_ADVICE =
34
- `An asset staged into the GResource bundle exports ${RESOURCE_BINDING} and a "resource://" default, and ` +
35
- "nothing else.";
36
25
 
37
26
  const QUERY_ADVICE =
38
27
  `A URL asset exports only its default filesystem path; import the default instead of ${RESOURCE_BINDING}.`;
@@ -43,9 +32,7 @@ const RESOURCE_ADVICE =
43
32
  const ICON_ADVICE = "An icon asset exports only its default icon-theme name, and nothing else.";
44
33
 
45
34
  const RELATIVE_ADVICE =
46
- `Only assets imported through "${DATA_PREFIX}" are staged into the GResource bundle and export ` +
47
- `${RESOURCE_BINDING}; move the file under the data directory and import it as ` +
48
- `${DATA_IMPORT_EXAMPLE}${URL_FALLBACK}`;
35
+ "Add ?resource for a GResource, ?icon for a themed icon, or ?url for an emitted file.";
49
36
 
50
37
  const boundName = (entry: BindingEntry): string | null => {
51
38
  const { name } = entry.importName;
@@ -78,50 +65,46 @@ const bindings = (parsed: ParsedModule): NamedBinding[] => [
78
65
  ...parsed.staticExports.flatMap((statement) => exportBindings(statement)),
79
66
  ];
80
67
 
81
- const isBacked = ({ name, source }: NamedBinding, isV2: boolean): boolean => {
68
+ const isBacked = ({ name, source }: NamedBinding): boolean => {
82
69
  if (name !== RESOURCE_PATH_EXPORT) {
83
70
  return false;
84
71
  }
85
72
 
86
- return isV2 ? parseResourceSpecifier(source) !== null : isDataAsset(source);
73
+ return parseResourceSpecifier(source) !== null;
87
74
  };
88
75
 
89
76
  const isCheckedSpecifier = (source: string): boolean => isAssetSpecifier(source) || isUrlSpecifier(source);
90
77
 
91
- const unbackedBinding = (parsed: ParsedModule, isV2: boolean): NamedBinding | undefined =>
92
- bindings(parsed).find((binding) => isCheckedSpecifier(binding.source) && !isBacked(binding, isV2));
93
-
94
- const isBundledResource = (source: string, isV2: boolean): boolean =>
95
- isV2
96
- ? parseResourceSpecifier(source) !== null || parseIconSpecifier(source) !== null
97
- : isDataAsset(source);
78
+ const unbackedBinding = (parsed: ParsedModule): NamedBinding | undefined =>
79
+ bindings(parsed).find((binding) => isCheckedSpecifier(binding.source) && !isBacked(binding));
98
80
 
99
- const v2BundleAdvice = (source: string): string =>
100
- parseIconSpecifier(source) === null ? RESOURCE_ADVICE : ICON_ADVICE;
81
+ const adviceFor = (source: string): string => {
82
+ if (parseResourceSpecifier(source) !== null) {
83
+ return RESOURCE_ADVICE;
84
+ }
101
85
 
102
- const bundleAdvice = (source: string, isV2: boolean): string => {
103
- if (isBundledResource(source, isV2)) {
104
- return isV2 ? v2BundleAdvice(source) : BUNDLE_ADVICE;
86
+ if (parseIconSpecifier(source) !== null) {
87
+ return ICON_ADVICE;
105
88
  }
106
89
 
107
90
  if (isUrlSpecifier(source)) {
108
91
  return QUERY_ADVICE;
109
92
  }
110
93
 
111
- return source.startsWith(DATA_PREFIX) ? QUERY_ADVICE : RELATIVE_ADVICE;
94
+ return RELATIVE_ADVICE;
112
95
  };
113
96
 
114
- const unbackedBindingError = (path: string, binding: NamedBinding, isV2: boolean): Error =>
97
+ const unbackedBindingError = (path: string, binding: NamedBinding): Error =>
115
98
  new Error(
116
99
  `${path}: ${JSON.stringify(binding.source)} does not export ${JSON.stringify(binding.name)}, which ` +
117
100
  "gtkx build rejects and gtkx dev would bind as undefined. " +
118
- bundleAdvice(binding.source, isV2),
101
+ adviceFor(binding.source),
119
102
  );
120
103
 
121
104
  const isCheckedSource = (path: string): boolean => !path.startsWith(VIRTUAL_PREFIX) && !NODE_MODULES.test(path);
122
105
  const hasCheckedAssetMention = (code: string): boolean => ASSET_MENTION_RE.test(code) || code.includes("?url");
123
106
 
124
- const checkAssetImports = (code: string, id: string, isV2: boolean): void => {
107
+ const checkAssetImports = (code: string, id: string): void => {
125
108
  const path = stripQuery(id);
126
109
  const lang = sourceLanguage(path);
127
110
 
@@ -135,27 +118,20 @@ const checkAssetImports = (code: string, id: string, isV2: boolean): void => {
135
118
  return;
136
119
  }
137
120
 
138
- const binding = unbackedBinding(parsed.module, isV2);
121
+ const binding = unbackedBinding(parsed.module);
139
122
 
140
123
  if (binding !== undefined) {
141
- throw unbackedBindingError(path, binding, isV2);
124
+ throw unbackedBindingError(path, binding);
142
125
  }
143
126
  };
144
127
 
145
- function gtkxAssetImports(loadConfig: ConfigLoader = createConfigLoader()): Plugin {
146
- const state: PluginState = { isV2: false };
147
-
128
+ function gtkxAssetImports(): Plugin {
148
129
  return {
149
130
  name: "gtkx:asset-imports",
150
131
  enforce: "pre",
151
132
 
152
- async config(config: UserConfig) {
153
- const loaded = await loadConfig.load(config.root ?? process.cwd());
154
- state.isV2 = resolveFuture(loaded.config.future).isResourceImported;
155
- },
156
-
157
133
  transform(code, id) {
158
- checkAssetImports(code, id, state.isV2);
134
+ checkAssetImports(code, id);
159
135
  },
160
136
  };
161
137
  }
@@ -1,4 +1,3 @@
1
- import { DATA_IMPORT_PREFIX } from "../internal/data-dir.js";
2
1
  import { ASSET_PATH_RE, ASSET_RE } from "./asset-extensions.js";
3
2
  import { stripQuery } from "./strip-query.js";
4
3
 
@@ -12,7 +11,6 @@ type IconSpecifier = {
12
11
  iconName: string | null;
13
12
  };
14
13
 
15
- const DATA_PREFIX = `${DATA_IMPORT_PREFIX}/`;
16
14
  const RELATIVE_PREFIX_RE = /^\.\.?(?:\/|$)/;
17
15
  const RESOURCE_QUERY_RE = /^resource(?:=([^&#]+))?$/;
18
16
  const ICON_QUERY_RE = /^icon(?:=([^&#]+))?$/;
@@ -25,7 +23,6 @@ const getQuery = (source: string): string | null => {
25
23
  };
26
24
 
27
25
  const isAssetSpecifier = (source: string): boolean => ASSET_PATH_RE.test(source);
28
- const isDataAsset = (source: string): boolean => source.startsWith(DATA_PREFIX) && ASSET_RE.test(source);
29
26
 
30
27
  const isBareRelativeAsset = (source: string): boolean =>
31
28
  getQuery(source) === null && RELATIVE_PREFIX_RE.test(source) && ASSET_RE.test(source);
@@ -71,10 +68,8 @@ const isUrlSpecifier = (source: string): boolean => {
71
68
  };
72
69
 
73
70
  export {
74
- DATA_PREFIX,
75
71
  isAssetSpecifier,
76
72
  isBareRelativeAsset,
77
- isDataAsset,
78
73
  isUrlSpecifier,
79
74
  parseIconSpecifier,
80
75
  parseResourceSpecifier,
@@ -1,6 +1,7 @@
1
1
  import type { ConfigLoader } from "@gtkx/config";
2
2
  import type { Plugin, ResolvedConfig } from "vite";
3
3
  import { createConfigLoader } from "@gtkx/config/internal";
4
+ import { toPosixPath } from "@gtkx/utils";
4
5
  import { existsSync, mkdirSync } from "node:fs";
5
6
  import { createRequire } from "node:module";
6
7
  import { dirname, join, posix, relative, resolve } from "node:path";
@@ -32,7 +33,7 @@ const isI18nLocaleModule = (state: I18nState, id: string): boolean => {
32
33
  return false;
33
34
  }
34
35
 
35
- const path = relative(state.i18nRoot, stripQuery(id)).replaceAll("\\", "/");
36
+ const path = toPosixPath(relative(state.i18nRoot, stripQuery(id)));
36
37
 
37
38
  return LOCALE_MODULE_PATHS.has(path);
38
39
  };
@@ -2,7 +2,6 @@ import type { Plugin } from "vite";
2
2
  import { createConfigLoader } from "@gtkx/config/internal";
3
3
  import createConfigPlugin from "@gtkx/config/vite-plugin";
4
4
  import type { BuildManifestCollector } from "../internal/build-manifest.js";
5
- import { gtkxAnimated } from "./animated.js";
6
5
  import { gtkxAssetImports } from "./asset-imports.js";
7
6
  import { gtkxBuiltUrl } from "./built-url.js";
8
7
  import { gtkxCss } from "./css.js";
@@ -27,13 +26,12 @@ const gtkxVitePlugins = (
27
26
  ...(entryPath === undefined ? [] : [gtkxI18n(entryPath, loadConfig, shouldPreserveI18nMetadata)]),
28
27
  gtkxStoreLinks(),
29
28
  gtkxUndeclaredLibrary(loadConfig),
30
- gtkxSettings(loadConfig, buildManifest),
29
+ gtkxSettings(buildManifest),
31
30
  gtkxIcons(loadConfig),
32
- gtkxAssetImports(loadConfig),
31
+ gtkxAssetImports(),
33
32
  gtkxBuiltUrl(),
34
33
  gtkxResources(loadConfig, entryPath),
35
34
  gtkxCss(),
36
- gtkxAnimated(loadConfig),
37
35
  gtkxReactCompiler(loadConfig),
38
36
  ];
39
37
  };