@gtkx/cli 2.0.0-beta.7 → 2.0.0-beta.8

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 (122) hide show
  1. package/dist/commands/deploy.d.ts +4 -0
  2. package/dist/commands/deploy.d.ts.map +1 -1
  3. package/dist/commands/deploy.js +6 -0
  4. package/dist/commands/deploy.js.map +1 -1
  5. package/dist/deploy/download.d.ts +7 -3
  6. package/dist/deploy/download.d.ts.map +1 -1
  7. package/dist/deploy/download.js +19 -15
  8. package/dist/deploy/download.js.map +1 -1
  9. package/dist/deploy/native-addon.d.ts +5 -0
  10. package/dist/deploy/native-addon.d.ts.map +1 -0
  11. package/dist/deploy/native-addon.js +134 -0
  12. package/dist/deploy/native-addon.js.map +1 -0
  13. package/dist/deploy/node-runtime/download.js +2 -2
  14. package/dist/deploy/node-runtime/download.js.map +1 -1
  15. package/dist/deploy/node-runtime/elf.d.ts +3 -1
  16. package/dist/deploy/node-runtime/elf.d.ts.map +1 -1
  17. package/dist/deploy/node-runtime/elf.js +3 -1
  18. package/dist/deploy/node-runtime/elf.js.map +1 -1
  19. package/dist/deploy/node-runtime/index.d.ts.map +1 -1
  20. package/dist/deploy/node-runtime/index.js +14 -2
  21. package/dist/deploy/node-runtime/index.js.map +1 -1
  22. package/dist/deploy/payload/stage.d.ts +2 -1
  23. package/dist/deploy/payload/stage.d.ts.map +1 -1
  24. package/dist/deploy/payload/stage.js +22 -2
  25. package/dist/deploy/payload/stage.js.map +1 -1
  26. package/dist/deploy/run-deploy.d.ts +1 -0
  27. package/dist/deploy/run-deploy.d.ts.map +1 -1
  28. package/dist/deploy/run-deploy.js +135 -79
  29. package/dist/deploy/run-deploy.js.map +1 -1
  30. package/dist/deploy/settings/arch.d.ts +9 -3
  31. package/dist/deploy/settings/arch.d.ts.map +1 -1
  32. package/dist/deploy/settings/arch.js +27 -6
  33. package/dist/deploy/settings/arch.js.map +1 -1
  34. package/dist/deploy/settings/index.d.ts +2 -1
  35. package/dist/deploy/settings/index.d.ts.map +1 -1
  36. package/dist/deploy/settings/index.js +2 -1
  37. package/dist/deploy/settings/index.js.map +1 -1
  38. package/dist/deploy/settings/paths.d.ts +2 -1
  39. package/dist/deploy/settings/paths.d.ts.map +1 -1
  40. package/dist/deploy/settings/paths.js +6 -5
  41. package/dist/deploy/settings/paths.js.map +1 -1
  42. package/dist/deploy/targets/appimage.d.ts.map +1 -1
  43. package/dist/deploy/targets/appimage.js +1 -0
  44. package/dist/deploy/targets/appimage.js.map +1 -1
  45. package/dist/deploy/targets/flatpak-pnpm.js +4 -4
  46. package/dist/deploy/targets/flatpak-pnpm.js.map +1 -1
  47. package/dist/deploy/targets/flatpak.d.ts.map +1 -1
  48. package/dist/deploy/targets/flatpak.js +1 -0
  49. package/dist/deploy/targets/flatpak.js.map +1 -1
  50. package/dist/deploy/targets/nfpm-target.d.ts.map +1 -1
  51. package/dist/deploy/targets/nfpm-target.js +1 -0
  52. package/dist/deploy/targets/nfpm-target.js.map +1 -1
  53. package/dist/deploy/types.d.ts +4 -2
  54. package/dist/deploy/types.d.ts.map +1 -1
  55. package/dist/deploy/types.js.map +1 -1
  56. package/dist/deploy/vendored/appimagetool.js +2 -2
  57. package/dist/deploy/vendored/appimagetool.js.map +1 -1
  58. package/dist/deploy/vendored/nfpm.js +1 -1
  59. package/dist/deploy/vendored/nfpm.js.map +1 -1
  60. package/dist/dev/font-dir.d.ts +1 -1
  61. package/dist/dev/font-dir.d.ts.map +1 -1
  62. package/dist/dev/font-dir.js +0 -3
  63. package/dist/dev/font-dir.js.map +1 -1
  64. package/dist/dev/runner.d.ts.map +1 -1
  65. package/dist/dev/runner.js +19 -6
  66. package/dist/dev/runner.js.map +1 -1
  67. package/dist/internal/font-staging.d.ts +5 -2
  68. package/dist/internal/font-staging.d.ts.map +1 -1
  69. package/dist/internal/font-staging.js +76 -27
  70. package/dist/internal/font-staging.js.map +1 -1
  71. package/dist/internal/source-imports.js +1 -1
  72. package/dist/internal/source-imports.js.map +1 -1
  73. package/dist/vite-plugins/font-worker-env.d.ts.map +1 -1
  74. package/dist/vite-plugins/font-worker-env.js +2 -5
  75. package/dist/vite-plugins/font-worker-env.js.map +1 -1
  76. package/dist/vite-plugins/font.d.ts.map +1 -1
  77. package/dist/vite-plugins/font.js +16 -4
  78. package/dist/vite-plugins/font.js.map +1 -1
  79. package/dist/vite-plugins/icons.js +2 -2
  80. package/dist/vite-plugins/icons.js.map +1 -1
  81. package/dist/vite-plugins/react-compiler.js +2 -2
  82. package/dist/vite-plugins/react-compiler.js.map +1 -1
  83. package/dist/vite-plugins/resources.js +2 -2
  84. package/dist/vite-plugins/resources.js.map +1 -1
  85. package/dist/vite-plugins/settings-worker-env.js +2 -2
  86. package/dist/vite-plugins/settings-worker-env.js.map +1 -1
  87. package/dist/vite-plugins/store-links.d.ts.map +1 -1
  88. package/dist/vite-plugins/store-links.js +2 -1
  89. package/dist/vite-plugins/store-links.js.map +1 -1
  90. package/dist/vite-plugins/undeclared-library.js +2 -2
  91. package/dist/vite-plugins/undeclared-library.js.map +1 -1
  92. package/package.json +13 -13
  93. package/src/commands/deploy.ts +6 -0
  94. package/src/deploy/download.ts +33 -17
  95. package/src/deploy/native-addon.ts +183 -0
  96. package/src/deploy/node-runtime/download.ts +2 -2
  97. package/src/deploy/node-runtime/elf.ts +4 -1
  98. package/src/deploy/node-runtime/index.ts +24 -4
  99. package/src/deploy/payload/stage.ts +34 -2
  100. package/src/deploy/run-deploy.ts +203 -93
  101. package/src/deploy/settings/arch.ts +40 -8
  102. package/src/deploy/settings/index.ts +4 -1
  103. package/src/deploy/settings/paths.ts +8 -6
  104. package/src/deploy/targets/appimage.ts +1 -0
  105. package/src/deploy/targets/flatpak-pnpm.ts +4 -4
  106. package/src/deploy/targets/flatpak.ts +1 -0
  107. package/src/deploy/targets/nfpm-target.ts +1 -0
  108. package/src/deploy/types.ts +4 -1
  109. package/src/deploy/vendored/appimagetool.ts +2 -2
  110. package/src/deploy/vendored/nfpm.ts +1 -1
  111. package/src/dev/font-dir.ts +1 -6
  112. package/src/dev/runner.ts +24 -6
  113. package/src/internal/font-staging.ts +99 -27
  114. package/src/internal/source-imports.ts +1 -1
  115. package/src/vite-plugins/font-worker-env.ts +2 -6
  116. package/src/vite-plugins/font.ts +21 -3
  117. package/src/vite-plugins/icons.ts +2 -2
  118. package/src/vite-plugins/react-compiler.ts +2 -2
  119. package/src/vite-plugins/resources.ts +2 -2
  120. package/src/vite-plugins/settings-worker-env.ts +2 -2
  121. package/src/vite-plugins/store-links.ts +2 -1
  122. package/src/vite-plugins/undeclared-library.ts +2 -2
@@ -1,43 +1,92 @@
1
1
  import { sortStrings } from "@gtkx/utils";
2
- import { mkdirSync, mkdtempSync, readFileSync, symlinkSync } from "node:fs";
3
- import { tmpdir } from "node:os";
4
- import { dirname, join, resolve } from "node:path";
2
+ import { lstatSync, mkdirSync, readFileSync, symlinkSync } from "node:fs";
3
+ import { createRequire } from "node:module";
4
+ import { dirname, isAbsolute, join, resolve } from "node:path";
5
5
  import { parseFontSpecifier } from "../vite-plugins/asset-specifier.js";
6
6
  import { fontFileName, FONTS_DIR } from "./font-path.js";
7
- import { discoverSourceImports, sourceDirFor } from "./source-imports.js";
8
- import { removeTempDir } from "./staging-dir.js";
9
- const FONT_STAGING_PREFIX = "gtkx-fonts-";
7
+ import { discoverSourceImports, sourceLanguage } from "./source-imports.js";
8
+ import { createRetainedStagingDir } from "./staging-dir.js";
9
+ const FONT_DIR_ENV = "GTKX_DEV_FONT_DIR";
10
+ const FONT_QUERY = "?font";
11
+ const fontStaging = createRetainedStagingDir("fonts");
10
12
  const isRelativeImport = (source) => source.startsWith("./") || source.startsWith("../");
11
- const fontFileFor = ({ importer, source }) => {
13
+ const existingPath = (path) => lstatSync(path, { throwIfNoEntry: false }) === undefined ? null : path;
14
+ const resolveRelativeImport = (importer, assetSource) => existingPath(resolve(dirname(importer), assetSource));
15
+ const resolveAbsoluteImport = (root, assetSource) => existingPath(assetSource) ?? existingPath(join(root, assetSource));
16
+ const resolvePackageImport = (importer, assetSource) => {
17
+ try {
18
+ return createRequire(importer).resolve(assetSource);
19
+ }
20
+ catch {
21
+ return null;
22
+ }
23
+ };
24
+ const resolveFontImport = (root, importer, assetSource) => {
25
+ if (isRelativeImport(assetSource)) {
26
+ return resolveRelativeImport(importer, assetSource);
27
+ }
28
+ if (isAbsolute(assetSource)) {
29
+ return resolveAbsoluteImport(root, assetSource);
30
+ }
31
+ return resolvePackageImport(importer, assetSource);
32
+ };
33
+ const fontFileFor = (root, { importer, source }) => {
12
34
  const specifier = parseFontSpecifier(source);
13
- return specifier === null || !isRelativeImport(source)
14
- ? null
15
- : resolve(dirname(importer), specifier.assetSource);
35
+ return specifier === null ? null : resolveFontImport(root, importer, specifier.assetSource);
16
36
  };
17
- const findImportedFontFiles = (imports) => {
18
- const files = imports
19
- .map((entry) => fontFileFor(entry))
37
+ const projectFontFiles = (root) => {
38
+ const files = discoverSourceImports(root)
39
+ .map((entry) => fontFileFor(root, entry))
20
40
  .filter((path) => path !== null);
21
41
  return sortStrings(new Set(files));
22
42
  };
43
+ const stagedPath = (fontsDir, sourcePath, content) => join(fontsDir, fontFileName(sourcePath, content));
23
44
  const stageFont = (fontsDir, sourcePath) => {
24
- const fileName = fontFileName(sourcePath, readFileSync(sourcePath));
25
- symlinkSync(sourcePath, join(fontsDir, fileName), "file");
45
+ const target = stagedPath(fontsDir, sourcePath, readFileSync(sourcePath));
46
+ if (existingPath(target) !== null) {
47
+ return;
48
+ }
49
+ symlinkSync(sourcePath, target, "file");
26
50
  };
27
- const stageProjectFonts = (root) => {
28
- const fontFiles = findImportedFontFiles(discoverSourceImports(sourceDirFor(root)));
29
- if (fontFiles.length === 0) {
30
- return null;
51
+ const stagedFontsDir = () => {
52
+ const shareDir = process.env[FONT_DIR_ENV];
53
+ return shareDir === undefined || shareDir.length === 0 ? null : join(shareDir, FONTS_DIR);
54
+ };
55
+ const stagedFontStatus = (sourcePath, content) => {
56
+ const fontsDir = stagedFontsDir();
57
+ if (fontsDir === null) {
58
+ return "unmanaged";
59
+ }
60
+ return existingPath(stagedPath(fontsDir, sourcePath, content)) === null ? "absent" : "staged";
61
+ };
62
+ const hasFontImportMention = (filePath) => {
63
+ if (sourceLanguage(filePath) === undefined) {
64
+ return false;
65
+ }
66
+ try {
67
+ return readFileSync(filePath, "utf8").includes(FONT_QUERY);
68
+ }
69
+ catch {
70
+ return false;
31
71
  }
32
- const shareDir = mkdtempSync(join(tmpdir(), FONT_STAGING_PREFIX));
33
- mkdirSync(join(shareDir, FONTS_DIR));
34
- for (const sourcePath of fontFiles) {
35
- stageFont(join(shareDir, FONTS_DIR), sourcePath);
72
+ };
73
+ const isUnstagedFont = (fontsDir, sourcePath) => existingPath(stagedPath(fontsDir, sourcePath, readFileSync(sourcePath))) === null;
74
+ const hasUnstagedFontImport = (root, filePath) => {
75
+ const fontsDir = stagedFontsDir();
76
+ if (fontsDir === null || !hasFontImportMention(filePath)) {
77
+ return false;
78
+ }
79
+ return projectFontFiles(root).some((sourcePath) => isUnstagedFont(fontsDir, sourcePath));
80
+ };
81
+ const stageProjectFonts = (root) => {
82
+ const shareDir = fontStaging.retain();
83
+ const fontsDir = join(shareDir, FONTS_DIR);
84
+ mkdirSync(fontsDir, { recursive: true });
85
+ for (const sourcePath of projectFontFiles(root)) {
86
+ stageFont(fontsDir, sourcePath);
36
87
  }
37
- process.once("exit", () => {
38
- removeTempDir(shareDir);
39
- });
88
+ process.env[FONT_DIR_ENV] = shareDir;
40
89
  return shareDir;
41
90
  };
42
- export { stageProjectFonts };
91
+ export { hasUnstagedFontImport, stagedFontStatus, stageProjectFonts };
43
92
  //# sourceMappingURL=font-staging.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"font-staging.js","sourceRoot":"","sources":["../../src/internal/font-staging.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAC1C,OAAO,EAAE,SAAS,EAAE,WAAW,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC;AAC5E,OAAO,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AACjC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACnD,OAAO,EAAE,kBAAkB,EAAE,MAAM,oCAAoC,CAAC;AACxE,OAAO,EAAE,YAAY,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AACzD,OAAO,EAAE,qBAAqB,EAAE,YAAY,EAAqB,MAAM,qBAAqB,CAAC;AAC7F,OAAO,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAEjD,MAAM,mBAAmB,GAAG,aAAa,CAAC;AAE1C,MAAM,gBAAgB,GAAG,CAAC,MAAc,EAAW,EAAE,CAAC,MAAM,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,MAAM,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC;AAE1G,MAAM,WAAW,GAAG,CAAC,EAAE,QAAQ,EAAE,MAAM,EAAgB,EAAiB,EAAE;IACtE,MAAM,SAAS,GAAG,kBAAkB,CAAC,MAAM,CAAC,CAAC;IAE7C,OAAO,SAAS,KAAK,IAAI,IAAI,CAAC,gBAAgB,CAAC,MAAM,CAAC;QAClD,CAAC,CAAC,IAAI;QACN,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE,SAAS,CAAC,WAAW,CAAC,CAAC;AAC5D,CAAC,CAAC;AAEF,MAAM,qBAAqB,GAAG,CAAC,OAAuB,EAAY,EAAE;IAChE,MAAM,KAAK,GAAG,OAAO;SAChB,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC;SAClC,MAAM,CAAC,CAAC,IAAI,EAAkB,EAAE,CAAC,IAAI,KAAK,IAAI,CAAC,CAAC;IAErD,OAAO,WAAW,CAAC,IAAI,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC;AACvC,CAAC,CAAC;AAEF,MAAM,SAAS,GAAG,CAAC,QAAgB,EAAE,UAAkB,EAAQ,EAAE;IAC7D,MAAM,QAAQ,GAAG,YAAY,CAAC,UAAU,EAAE,YAAY,CAAC,UAAU,CAAC,CAAC,CAAC;IAEpE,WAAW,CAAC,UAAU,EAAE,IAAI,CAAC,QAAQ,EAAE,QAAQ,CAAC,EAAE,MAAM,CAAC,CAAC;AAC9D,CAAC,CAAC;AAEF,MAAM,iBAAiB,GAAG,CAAC,IAAY,EAAiB,EAAE;IACtD,MAAM,SAAS,GAAG,qBAAqB,CAAC,qBAAqB,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAEnF,IAAI,SAAS,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACzB,OAAO,IAAI,CAAC;IAChB,CAAC;IAED,MAAM,QAAQ,GAAG,WAAW,CAAC,IAAI,CAAC,MAAM,EAAE,EAAE,mBAAmB,CAAC,CAAC,CAAC;IAClE,SAAS,CAAC,IAAI,CAAC,QAAQ,EAAE,SAAS,CAAC,CAAC,CAAC;IAErC,KAAK,MAAM,UAAU,IAAI,SAAS,EAAE,CAAC;QACjC,SAAS,CAAC,IAAI,CAAC,QAAQ,EAAE,SAAS,CAAC,EAAE,UAAU,CAAC,CAAC;IACrD,CAAC;IAED,OAAO,CAAC,IAAI,CAAC,MAAM,EAAE,GAAG,EAAE;QACtB,aAAa,CAAC,QAAQ,CAAC,CAAC;IAC5B,CAAC,CAAC,CAAC;IAEH,OAAO,QAAQ,CAAC;AACpB,CAAC,CAAC;AAEF,OAAO,EAAE,iBAAiB,EAAE,CAAC","sourcesContent":["import { sortStrings } from \"@gtkx/utils\";\nimport { mkdirSync, mkdtempSync, readFileSync, symlinkSync } from \"node:fs\";\nimport { tmpdir } from \"node:os\";\nimport { dirname, join, resolve } from \"node:path\";\nimport { parseFontSpecifier } from \"../vite-plugins/asset-specifier.js\";\nimport { fontFileName, FONTS_DIR } from \"./font-path.js\";\nimport { discoverSourceImports, sourceDirFor, type SourceImport } from \"./source-imports.js\";\nimport { removeTempDir } from \"./staging-dir.js\";\n\nconst FONT_STAGING_PREFIX = \"gtkx-fonts-\";\n\nconst isRelativeImport = (source: string): boolean => source.startsWith(\"./\") || source.startsWith(\"../\");\n\nconst fontFileFor = ({ importer, source }: SourceImport): string | null => {\n const specifier = parseFontSpecifier(source);\n\n return specifier === null || !isRelativeImport(source)\n ? null\n : resolve(dirname(importer), specifier.assetSource);\n};\n\nconst findImportedFontFiles = (imports: SourceImport[]): string[] => {\n const files = imports\n .map((entry) => fontFileFor(entry))\n .filter((path): path is string => path !== null);\n\n return sortStrings(new Set(files));\n};\n\nconst stageFont = (fontsDir: string, sourcePath: string): void => {\n const fileName = fontFileName(sourcePath, readFileSync(sourcePath));\n\n symlinkSync(sourcePath, join(fontsDir, fileName), \"file\");\n};\n\nconst stageProjectFonts = (root: string): string | null => {\n const fontFiles = findImportedFontFiles(discoverSourceImports(sourceDirFor(root)));\n\n if (fontFiles.length === 0) {\n return null;\n }\n\n const shareDir = mkdtempSync(join(tmpdir(), FONT_STAGING_PREFIX));\n mkdirSync(join(shareDir, FONTS_DIR));\n\n for (const sourcePath of fontFiles) {\n stageFont(join(shareDir, FONTS_DIR), sourcePath);\n }\n\n process.once(\"exit\", () => {\n removeTempDir(shareDir);\n });\n\n return shareDir;\n};\n\nexport { stageProjectFonts };\n"]}
1
+ {"version":3,"file":"font-staging.js","sourceRoot":"","sources":["../../src/internal/font-staging.ts"],"names":[],"mappings":"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","sourcesContent":["import { sortStrings } from \"@gtkx/utils\";\nimport { lstatSync, mkdirSync, readFileSync, symlinkSync } from \"node:fs\";\nimport { createRequire } from \"node:module\";\nimport { dirname, isAbsolute, join, resolve } from \"node:path\";\nimport { parseFontSpecifier } from \"../vite-plugins/asset-specifier.js\";\nimport { fontFileName, FONTS_DIR } from \"./font-path.js\";\nimport { discoverSourceImports, type SourceImport, sourceLanguage } from \"./source-imports.js\";\nimport { createRetainedStagingDir } from \"./staging-dir.js\";\n\ntype FontStagingStatus = \"absent\" | \"staged\" | \"unmanaged\";\n\nconst FONT_DIR_ENV = \"GTKX_DEV_FONT_DIR\";\nconst FONT_QUERY = \"?font\";\nconst fontStaging = createRetainedStagingDir(\"fonts\");\n\nconst isRelativeImport = (source: string): boolean => source.startsWith(\"./\") || source.startsWith(\"../\");\n\nconst existingPath = (path: string): string | null =>\n lstatSync(path, { throwIfNoEntry: false }) === undefined ? null : path;\n\nconst resolveRelativeImport = (importer: string, assetSource: string): string | null =>\n existingPath(resolve(dirname(importer), assetSource));\n\nconst resolveAbsoluteImport = (root: string, assetSource: string): string | null =>\n existingPath(assetSource) ?? existingPath(join(root, assetSource));\n\nconst resolvePackageImport = (importer: string, assetSource: string): string | null => {\n try {\n return createRequire(importer).resolve(assetSource);\n } catch {\n return null;\n }\n};\n\nconst resolveFontImport = (root: string, importer: string, assetSource: string): string | null => {\n if (isRelativeImport(assetSource)) {\n return resolveRelativeImport(importer, assetSource);\n }\n\n if (isAbsolute(assetSource)) {\n return resolveAbsoluteImport(root, assetSource);\n }\n\n return resolvePackageImport(importer, assetSource);\n};\n\nconst fontFileFor = (root: string, { importer, source }: SourceImport): string | null => {\n const specifier = parseFontSpecifier(source);\n\n return specifier === null ? null : resolveFontImport(root, importer, specifier.assetSource);\n};\n\nconst projectFontFiles = (root: string): string[] => {\n const files = discoverSourceImports(root)\n .map((entry) => fontFileFor(root, entry))\n .filter((path): path is string => path !== null);\n\n return sortStrings(new Set(files));\n};\n\nconst stagedPath = (fontsDir: string, sourcePath: string, content: Buffer): string =>\n join(fontsDir, fontFileName(sourcePath, content));\n\nconst stageFont = (fontsDir: string, sourcePath: string): void => {\n const target = stagedPath(fontsDir, sourcePath, readFileSync(sourcePath));\n\n if (existingPath(target) !== null) {\n return;\n }\n\n symlinkSync(sourcePath, target, \"file\");\n};\n\nconst stagedFontsDir = (): string | null => {\n const shareDir = process.env[FONT_DIR_ENV];\n\n return shareDir === undefined || shareDir.length === 0 ? null : join(shareDir, FONTS_DIR);\n};\n\nconst stagedFontStatus = (sourcePath: string, content: Buffer): FontStagingStatus => {\n const fontsDir = stagedFontsDir();\n\n if (fontsDir === null) {\n return \"unmanaged\";\n }\n\n return existingPath(stagedPath(fontsDir, sourcePath, content)) === null ? \"absent\" : \"staged\";\n};\n\nconst hasFontImportMention = (filePath: string): boolean => {\n if (sourceLanguage(filePath) === undefined) {\n return false;\n }\n\n try {\n return readFileSync(filePath, \"utf8\").includes(FONT_QUERY);\n } catch {\n return false;\n }\n};\n\nconst isUnstagedFont = (fontsDir: string, sourcePath: string): boolean =>\n existingPath(stagedPath(fontsDir, sourcePath, readFileSync(sourcePath))) === null;\n\nconst hasUnstagedFontImport = (root: string, filePath: string): boolean => {\n const fontsDir = stagedFontsDir();\n\n if (fontsDir === null || !hasFontImportMention(filePath)) {\n return false;\n }\n\n return projectFontFiles(root).some((sourcePath) => isUnstagedFont(fontsDir, sourcePath));\n};\n\nconst stageProjectFonts = (root: string): string => {\n const shareDir = fontStaging.retain();\n const fontsDir = join(shareDir, FONTS_DIR);\n mkdirSync(fontsDir, { recursive: true });\n\n for (const sourcePath of projectFontFiles(root)) {\n stageFont(fontsDir, sourcePath);\n }\n\n process.env[FONT_DIR_ENV] = shareDir;\n\n return shareDir;\n};\n\nexport { hasUnstagedFontImport, stagedFontStatus, stageProjectFonts };\n"]}
@@ -23,7 +23,7 @@ const sourceDirFor = (root) => {
23
23
  };
24
24
  const discoverSourceFiles = (dir) => sortStringsBy(globSync("**/{*,.*}", {
25
25
  cwd: dir,
26
- exclude: ["**/{build,coverage,dist,node_modules,out-tsc}/**", "**/.gtkx-output-*/**"],
26
+ exclude: ["**/{build,coverage,dist,node_modules,out-tsc}/**", "**/.gtkx-output-*/**", "**/.git/**"],
27
27
  withFileTypes: true,
28
28
  })
29
29
  .filter((entry) => entry.isFile())
@@ -1 +1 @@
1
- {"version":3,"file":"source-imports.js","sourceRoot":"","sources":["../../src/internal/source-imports.ts"],"names":[],"mappings":"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","sourcesContent":["import type { ESTree, ParseResult, ParserOptions } from \"vite\";\nimport { sortStringsBy } from \"@gtkx/utils\";\nimport { existsSync, globSync, readFileSync } from \"node:fs\";\nimport { extname, join } from \"node:path\";\nimport { parseSync, Visitor } from \"vite\";\n\ntype SourceImport = {\n importer: string;\n source: string;\n};\n\ntype SourceLanguage = NonNullable<ParserOptions[\"lang\"]>;\ntype ParsedModule = ParseResult[\"module\"];\n\nconst SOURCE_LANGUAGES: Map<string, SourceLanguage> = new Map([\n [\".js\", \"jsx\"],\n [\".jsx\", \"jsx\"],\n [\".mjs\", \"jsx\"],\n [\".mts\", \"ts\"],\n [\".ts\", \"ts\"],\n [\".tsx\", \"tsx\"],\n]);\n\nconst sourceLanguage = (path: string): SourceLanguage | undefined => {\n if (path.endsWith(\".d.ts\") || path.endsWith(\".d.mts\")) {\n return undefined;\n }\n\n return SOURCE_LANGUAGES.get(extname(path).toLowerCase());\n};\n\nconst SOURCE_DIR = \"src\";\n\nconst sourceDirFor = (root: string): string => {\n const sourceDir = join(root, SOURCE_DIR);\n\n return existsSync(sourceDir) ? sourceDir : root;\n};\n\nconst discoverSourceFiles = (dir: string): string[] =>\n sortStringsBy(\n globSync(\"**/{*,.*}\", {\n cwd: dir,\n exclude: [\"**/{build,coverage,dist,node_modules,out-tsc}/**\", \"**/.gtkx-output-*/**\"],\n withFileTypes: true,\n })\n .filter((entry) => entry.isFile())\n .map((entry) => join(entry.parentPath, entry.name))\n .filter((path) => sourceLanguage(path) !== undefined),\n (path) => path,\n );\n\nconst staticImportSources = (module: ParsedModule): string[] => [\n ...module.staticImports.map((statement) => statement.moduleRequest.value),\n ...module.staticExports.flatMap((statement) =>\n statement.entries\n .map((entry) => entry.moduleRequest?.value)\n .filter((source): source is string => source !== undefined),\n ),\n];\n\nconst staticRuntimeImportSources = (module: ParsedModule): string[] => [\n ...module.staticImports\n .filter((statement) => statement.entries.length === 0 || statement.entries.some((entry) => !entry.isType))\n .map((statement) => statement.moduleRequest.value),\n ...module.staticExports.flatMap((statement) =>\n statement.entries\n .filter((entry) => !entry.isType)\n .map((entry) => entry.moduleRequest?.value)\n .filter((source): source is string => source !== undefined),\n ),\n];\n\nconst templateImportSource = (node: ESTree.TemplateLiteral): string | null => {\n const [quasi] = node.quasis;\n\n return quasi === undefined || node.expressions.length > 0 ? null : quasi.value.cooked;\n};\n\nconst literalImportSource = (node: ESTree.Expression): string | null => {\n if (node.type === \"TemplateLiteral\") {\n return templateImportSource(node);\n }\n\n return node.type === \"Literal\" && typeof node.value === \"string\" ? node.value : null;\n};\n\nconst collectDynamicImportSources = (program: ESTree.Program, found: string[]): void => {\n new Visitor({\n ImportExpression: (node) => {\n const source = literalImportSource(node.source);\n\n if (source !== null) {\n found.push(source);\n }\n },\n }).visit(program);\n};\n\nconst parseImportsInWith = (\n path: string,\n staticSources: (module: ParsedModule) => string[],\n): SourceImport[] | null => {\n const lang = sourceLanguage(path);\n\n if (lang === undefined) {\n return [];\n }\n\n let parsed: ParseResult;\n\n try {\n parsed = parseSync(path, readFileSync(path, \"utf8\"), { lang });\n } catch {\n return null;\n }\n\n if (parsed.errors.length > 0) {\n return null;\n }\n\n const sources = staticSources(parsed.module);\n collectDynamicImportSources(parsed.program, sources);\n\n return [...new Set(sources)].map((source) => ({ importer: path, source }));\n};\n\nconst parseImportsIn = (path: string): SourceImport[] | null => parseImportsInWith(path, staticImportSources);\n\nconst parseRuntimeImportsIn = (path: string): SourceImport[] | null =>\n parseImportsInWith(path, staticRuntimeImportSources);\n\nconst importsIn = (path: string): SourceImport[] => parseImportsIn(path) ?? [];\nconst importKey = (entry: SourceImport): string => `${entry.importer}\\0${entry.source}`;\n\nconst discoverSourceImports = (dir: string): SourceImport[] => {\n const files = discoverSourceFiles(dir);\n const imports = files.flatMap((path) => importsIn(path));\n\n return sortStringsBy(imports, importKey);\n};\n\nexport {\n discoverSourceFiles,\n discoverSourceImports,\n parseRuntimeImportsIn,\n sourceDirFor,\n sourceLanguage,\n type SourceImport,\n};\n"]}
1
+ {"version":3,"file":"source-imports.js","sourceRoot":"","sources":["../../src/internal/source-imports.ts"],"names":[],"mappings":"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","sourcesContent":["import type { ESTree, ParseResult, ParserOptions } from \"vite\";\nimport { sortStringsBy } from \"@gtkx/utils\";\nimport { existsSync, globSync, readFileSync } from \"node:fs\";\nimport { extname, join } from \"node:path\";\nimport { parseSync, Visitor } from \"vite\";\n\ntype SourceImport = {\n importer: string;\n source: string;\n};\n\ntype SourceLanguage = NonNullable<ParserOptions[\"lang\"]>;\ntype ParsedModule = ParseResult[\"module\"];\n\nconst SOURCE_LANGUAGES: Map<string, SourceLanguage> = new Map([\n [\".js\", \"jsx\"],\n [\".jsx\", \"jsx\"],\n [\".mjs\", \"jsx\"],\n [\".mts\", \"ts\"],\n [\".ts\", \"ts\"],\n [\".tsx\", \"tsx\"],\n]);\n\nconst sourceLanguage = (path: string): SourceLanguage | undefined => {\n if (path.endsWith(\".d.ts\") || path.endsWith(\".d.mts\")) {\n return undefined;\n }\n\n return SOURCE_LANGUAGES.get(extname(path).toLowerCase());\n};\n\nconst SOURCE_DIR = \"src\";\n\nconst sourceDirFor = (root: string): string => {\n const sourceDir = join(root, SOURCE_DIR);\n\n return existsSync(sourceDir) ? sourceDir : root;\n};\n\nconst discoverSourceFiles = (dir: string): string[] =>\n sortStringsBy(\n globSync(\"**/{*,.*}\", {\n cwd: dir,\n exclude: [\"**/{build,coverage,dist,node_modules,out-tsc}/**\", \"**/.gtkx-output-*/**\", \"**/.git/**\"],\n withFileTypes: true,\n })\n .filter((entry) => entry.isFile())\n .map((entry) => join(entry.parentPath, entry.name))\n .filter((path) => sourceLanguage(path) !== undefined),\n (path) => path,\n );\n\nconst staticImportSources = (module: ParsedModule): string[] => [\n ...module.staticImports.map((statement) => statement.moduleRequest.value),\n ...module.staticExports.flatMap((statement) =>\n statement.entries\n .map((entry) => entry.moduleRequest?.value)\n .filter((source): source is string => source !== undefined),\n ),\n];\n\nconst staticRuntimeImportSources = (module: ParsedModule): string[] => [\n ...module.staticImports\n .filter((statement) => statement.entries.length === 0 || statement.entries.some((entry) => !entry.isType))\n .map((statement) => statement.moduleRequest.value),\n ...module.staticExports.flatMap((statement) =>\n statement.entries\n .filter((entry) => !entry.isType)\n .map((entry) => entry.moduleRequest?.value)\n .filter((source): source is string => source !== undefined),\n ),\n];\n\nconst templateImportSource = (node: ESTree.TemplateLiteral): string | null => {\n const [quasi] = node.quasis;\n\n return quasi === undefined || node.expressions.length > 0 ? null : quasi.value.cooked;\n};\n\nconst literalImportSource = (node: ESTree.Expression): string | null => {\n if (node.type === \"TemplateLiteral\") {\n return templateImportSource(node);\n }\n\n return node.type === \"Literal\" && typeof node.value === \"string\" ? node.value : null;\n};\n\nconst collectDynamicImportSources = (program: ESTree.Program, found: string[]): void => {\n new Visitor({\n ImportExpression: (node) => {\n const source = literalImportSource(node.source);\n\n if (source !== null) {\n found.push(source);\n }\n },\n }).visit(program);\n};\n\nconst parseImportsInWith = (\n path: string,\n staticSources: (module: ParsedModule) => string[],\n): SourceImport[] | null => {\n const lang = sourceLanguage(path);\n\n if (lang === undefined) {\n return [];\n }\n\n let parsed: ParseResult;\n\n try {\n parsed = parseSync(path, readFileSync(path, \"utf8\"), { lang });\n } catch {\n return null;\n }\n\n if (parsed.errors.length > 0) {\n return null;\n }\n\n const sources = staticSources(parsed.module);\n collectDynamicImportSources(parsed.program, sources);\n\n return [...new Set(sources)].map((source) => ({ importer: path, source }));\n};\n\nconst parseImportsIn = (path: string): SourceImport[] | null => parseImportsInWith(path, staticImportSources);\n\nconst parseRuntimeImportsIn = (path: string): SourceImport[] | null =>\n parseImportsInWith(path, staticRuntimeImportSources);\n\nconst importsIn = (path: string): SourceImport[] => parseImportsIn(path) ?? [];\nconst importKey = (entry: SourceImport): string => `${entry.importer}\\0${entry.source}`;\n\nconst discoverSourceImports = (dir: string): SourceImport[] => {\n const files = discoverSourceFiles(dir);\n const imports = files.flatMap((path) => importsIn(path));\n\n return sortStringsBy(imports, importKey);\n};\n\nexport {\n discoverSourceFiles,\n discoverSourceImports,\n parseRuntimeImportsIn,\n sourceDirFor,\n sourceLanguage,\n type SourceImport,\n};\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"font-worker-env.d.ts","sourceRoot":"","sources":["../../src/vite-plugins/font-worker-env.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,eAAe,CAAC;AAK5C,iBAAS,iBAAiB,CAAC,UAAU,CAAC,EAAE,MAAM,GAAG,MAAM,CAoBtD;AAED,OAAO,EAAE,iBAAiB,EAAE,CAAC"}
1
+ {"version":3,"file":"font-worker-env.d.ts","sourceRoot":"","sources":["../../src/vite-plugins/font-worker-env.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,eAAe,CAAC;AAK5C,iBAAS,iBAAiB,CAAC,UAAU,CAAC,EAAE,MAAM,GAAG,MAAM,CAgBtD;AAED,OAAO,EAAE,iBAAiB,EAAE,CAAC"}
@@ -1,4 +1,4 @@
1
- import { createConfigLoader } from "@gtkx/config/internal";
1
+ import { createConfigLoader, viteProjectRoot } from "@gtkx/config/internal";
2
2
  import { stageProjectFonts } from "../internal/font-staging.js";
3
3
  import { prependXdgDataDir } from "../internal/xdg-data-dirs.js";
4
4
  function gtkxFontWorkerEnv(configFile) {
@@ -7,11 +7,8 @@ function gtkxFontWorkerEnv(configFile) {
7
7
  name: "gtkx:font-worker-env",
8
8
  enforce: "pre",
9
9
  async config(config) {
10
- const loaded = await loadConfig.load(config.root ?? process.cwd());
10
+ const loaded = await loadConfig.load(viteProjectRoot(config));
11
11
  const shareDir = stageProjectFonts(loaded.root);
12
- if (shareDir === null) {
13
- return;
14
- }
15
12
  return {
16
13
  test: { env: { XDG_DATA_DIRS: prependXdgDataDir(shareDir, process.env.XDG_DATA_DIRS) } },
17
14
  };
@@ -1 +1 @@
1
- {"version":3,"file":"font-worker-env.js","sourceRoot":"","sources":["../../src/vite-plugins/font-worker-env.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,kBAAkB,EAAE,MAAM,uBAAuB,CAAC;AAC3D,OAAO,EAAE,iBAAiB,EAAE,MAAM,6BAA6B,CAAC;AAChE,OAAO,EAAE,iBAAiB,EAAE,MAAM,8BAA8B,CAAC;AAEjE,SAAS,iBAAiB,CAAC,UAAmB;IAC1C,MAAM,UAAU,GAAG,kBAAkB,CAAC,EAAE,UAAU,EAAE,CAAC,CAAC;IAEtD,OAAO;QACH,IAAI,EAAE,sBAAsB;QAC5B,OAAO,EAAE,KAAK;QAEd,KAAK,CAAC,MAAM,CAAC,MAAkB;YAC3B,MAAM,MAAM,GAAG,MAAM,UAAU,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,IAAI,OAAO,CAAC,GAAG,EAAE,CAAC,CAAC;YACnE,MAAM,QAAQ,GAAG,iBAAiB,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;YAEhD,IAAI,QAAQ,KAAK,IAAI,EAAE,CAAC;gBACpB,OAAO;YACX,CAAC;YAED,OAAO;gBACH,IAAI,EAAE,EAAE,GAAG,EAAE,EAAE,aAAa,EAAE,iBAAiB,CAAC,QAAQ,EAAE,OAAO,CAAC,GAAG,CAAC,aAAa,CAAC,EAAE,EAAE;aAC3F,CAAC;QACN,CAAC;KACJ,CAAC;AACN,CAAC;AAED,OAAO,EAAE,iBAAiB,EAAE,CAAC","sourcesContent":["import type { UserConfig } from \"vite\";\nimport type { Plugin } from \"vitest/config\";\nimport { createConfigLoader } from \"@gtkx/config/internal\";\nimport { stageProjectFonts } from \"../internal/font-staging.js\";\nimport { prependXdgDataDir } from \"../internal/xdg-data-dirs.js\";\n\nfunction gtkxFontWorkerEnv(configFile?: string): Plugin {\n const loadConfig = createConfigLoader({ configFile });\n\n return {\n name: \"gtkx:font-worker-env\",\n enforce: \"pre\",\n\n async config(config: UserConfig) {\n const loaded = await loadConfig.load(config.root ?? process.cwd());\n const shareDir = stageProjectFonts(loaded.root);\n\n if (shareDir === null) {\n return;\n }\n\n return {\n test: { env: { XDG_DATA_DIRS: prependXdgDataDir(shareDir, process.env.XDG_DATA_DIRS) } },\n };\n },\n };\n}\n\nexport { gtkxFontWorkerEnv };\n"]}
1
+ {"version":3,"file":"font-worker-env.js","sourceRoot":"","sources":["../../src/vite-plugins/font-worker-env.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,kBAAkB,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAC5E,OAAO,EAAE,iBAAiB,EAAE,MAAM,6BAA6B,CAAC;AAChE,OAAO,EAAE,iBAAiB,EAAE,MAAM,8BAA8B,CAAC;AAEjE,SAAS,iBAAiB,CAAC,UAAmB;IAC1C,MAAM,UAAU,GAAG,kBAAkB,CAAC,EAAE,UAAU,EAAE,CAAC,CAAC;IAEtD,OAAO;QACH,IAAI,EAAE,sBAAsB;QAC5B,OAAO,EAAE,KAAK;QAEd,KAAK,CAAC,MAAM,CAAC,MAAkB;YAC3B,MAAM,MAAM,GAAG,MAAM,UAAU,CAAC,IAAI,CAAC,eAAe,CAAC,MAAM,CAAC,CAAC,CAAC;YAC9D,MAAM,QAAQ,GAAG,iBAAiB,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;YAEhD,OAAO;gBACH,IAAI,EAAE,EAAE,GAAG,EAAE,EAAE,aAAa,EAAE,iBAAiB,CAAC,QAAQ,EAAE,OAAO,CAAC,GAAG,CAAC,aAAa,CAAC,EAAE,EAAE;aAC3F,CAAC;QACN,CAAC;KACJ,CAAC;AACN,CAAC;AAED,OAAO,EAAE,iBAAiB,EAAE,CAAC","sourcesContent":["import type { UserConfig } from \"vite\";\nimport type { Plugin } from \"vitest/config\";\nimport { createConfigLoader, viteProjectRoot } from \"@gtkx/config/internal\";\nimport { stageProjectFonts } from \"../internal/font-staging.js\";\nimport { prependXdgDataDir } from \"../internal/xdg-data-dirs.js\";\n\nfunction gtkxFontWorkerEnv(configFile?: string): Plugin {\n const loadConfig = createConfigLoader({ configFile });\n\n return {\n name: \"gtkx:font-worker-env\",\n enforce: \"pre\",\n\n async config(config: UserConfig) {\n const loaded = await loadConfig.load(viteProjectRoot(config));\n const shareDir = stageProjectFonts(loaded.root);\n\n return {\n test: { env: { XDG_DATA_DIRS: prependXdgDataDir(shareDir, process.env.XDG_DATA_DIRS) } },\n };\n },\n };\n}\n\nexport { gtkxFontWorkerEnv };\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"font.d.ts","sourceRoot":"","sources":["../../src/vite-plugins/font.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAU,MAAM,MAAM,CAAC;AAiH3C,iBAAS,QAAQ,IAAI,MAAM,CA+B1B;AAED,OAAO,EAAE,QAAQ,EAAE,CAAC"}
1
+ {"version":3,"file":"font.d.ts","sourceRoot":"","sources":["../../src/vite-plugins/font.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAU,MAAM,MAAM,CAAC;AAkI3C,iBAAS,QAAQ,IAAI,MAAM,CAgC1B;AAED,OAAO,EAAE,QAAQ,EAAE,CAAC"}
@@ -2,6 +2,7 @@ import { readFileSync } from "node:fs";
2
2
  import { parseSync } from "vite";
3
3
  import { prependBanner } from "../internal/banner.js";
4
4
  import { fontFileName, FONTS_DIR } from "../internal/font-path.js";
5
+ import { stagedFontStatus } from "../internal/font-staging.js";
5
6
  import { sourceLanguage } from "../internal/source-imports.js";
6
7
  import { xdgDataDirsBanner } from "../internal/xdg-banner.js";
7
8
  import { parseFontSpecifier } from "./asset-specifier.js";
@@ -12,12 +13,19 @@ const VIRTUAL_PREFIX = "\0gtkx-font:";
12
13
  const { isVirtual, fromVirtualId, resolveToVirtual } = createVirtualNamespace(VIRTUAL_PREFIX);
13
14
  const unreadableFontError = (filePath) => `Cannot read a font family name from ${filePath}; ?font expects a TrueType, OpenType, ` +
14
15
  "TrueType Collection, WOFF, or WOFF2 font";
15
- const resolveFontId = async (ctx, request) => {
16
+ const unstagedFontError = (filePath, importer) => `${filePath} was not staged before the toolkit started, so ${importer} would resolve its family to a ` +
17
+ "fallback font. Fonts are staged from ?font imports found in source files under the project root; move " +
18
+ "the import there, or restart to pick it up.";
19
+ const resolveFontId = async (ctx, state, request) => {
16
20
  if (parseFontSpecifier(request.source) === null) {
17
21
  return undefined;
18
22
  }
19
23
  const virtualId = await resolveToVirtual(ctx, request);
20
- return virtualId === undefined ? undefined : { id: virtualId, moduleSideEffects: true };
24
+ if (virtualId === undefined) {
25
+ return undefined;
26
+ }
27
+ state.importers.set(virtualId, request.importer ?? state.root);
28
+ return { id: virtualId, moduleSideEffects: true };
21
29
  };
22
30
  const emitFont = (ctx, state, filePath, content) => {
23
31
  const fileName = `${FONTS_DIR}/${fontFileName(filePath, content)}`;
@@ -41,6 +49,9 @@ const loadFontModule = (ctx, state, id) => {
41
49
  if (state.isBuild) {
42
50
  emitFont(ctx, state, filePath, content);
43
51
  }
52
+ else if (stagedFontStatus(filePath, content) === "absent") {
53
+ return ctx.error(unstagedFontError(filePath, state.importers.get(id) ?? state.root));
54
+ }
44
55
  return `export default ${JSON.stringify(family)};`;
45
56
  };
46
57
  const hasSideEffectFontImport = (code, id) => {
@@ -59,15 +70,16 @@ const retainSideEffectFontImport = (code, id) => hasSideEffectFontImport(code, i
59
70
  : null;
60
71
  const fontBanner = (state) => (chunk) => state.emitted.size === 0 ? "" : xdgDataDirsBanner(chunk);
61
72
  function gtkxFont() {
62
- const state = { isBuild: false, emitted: new Set() };
73
+ const state = { isBuild: false, root: "", emitted: new Set(), importers: new Map() };
63
74
  return {
64
75
  name: "gtkx:font",
65
76
  enforce: "pre",
66
77
  configResolved(config) {
67
78
  state.isBuild = config.command === "build";
79
+ state.root = config.root;
68
80
  },
69
81
  resolveId(source, importer, options) {
70
- return resolveFontId(this, { source, importer, options });
82
+ return resolveFontId(this, state, { source, importer, options });
71
83
  },
72
84
  load(id) {
73
85
  return loadFontModule(this, state, id);
@@ -1 +1 @@
1
- {"version":3,"file":"font.js","sourceRoot":"","sources":["../../src/vite-plugins/font.ts"],"names":[],"mappings":"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","sourcesContent":["import type { Plugin, Rollup } from \"vite\";\nimport { readFileSync } from \"node:fs\";\nimport { parseSync } from \"vite\";\nimport type { AssetEmitter } from \"./asset-emitter.js\";\nimport { prependBanner } from \"../internal/banner.js\";\nimport { fontFileName, FONTS_DIR } from \"../internal/font-path.js\";\nimport { sourceLanguage } from \"../internal/source-imports.js\";\nimport { xdgDataDirsBanner } from \"../internal/xdg-banner.js\";\nimport { parseFontSpecifier } from \"./asset-specifier.js\";\nimport { fontFamilyNames } from \"./font-name.js\";\nimport { stripQuery } from \"./strip-query.js\";\nimport { createVirtualNamespace } from \"./virtual-module.js\";\n\ntype PluginState = {\n isBuild: boolean;\n emitted: Set<string>;\n};\n\ntype ResolveContext = Parameters<typeof resolveToVirtual>[0];\ntype ResolveRequest = Parameters<typeof resolveToVirtual>[1];\n\ntype RetainedFontModuleId = {\n id: string;\n moduleSideEffects: true;\n};\n\ntype LoadContext = AssetEmitter & {\n addWatchFile: (file: string) => void;\n error: (message: string) => never;\n};\n\nconst VIRTUAL_PREFIX = \"\\0gtkx-font:\";\nconst { isVirtual, fromVirtualId, resolveToVirtual } = createVirtualNamespace(VIRTUAL_PREFIX);\n\nconst unreadableFontError = (filePath: string): string =>\n `Cannot read a font family name from ${filePath}; ?font expects a TrueType, OpenType, ` +\n \"TrueType Collection, WOFF, or WOFF2 font\";\n\nconst resolveFontId = async (\n ctx: ResolveContext,\n request: ResolveRequest,\n): Promise<RetainedFontModuleId | undefined> => {\n if (parseFontSpecifier(request.source) === null) {\n return undefined;\n }\n\n const virtualId = await resolveToVirtual(ctx, request);\n\n return virtualId === undefined ? undefined : { id: virtualId, moduleSideEffects: true };\n};\n\nconst emitFont = (ctx: LoadContext, state: PluginState, filePath: string, content: Buffer): void => {\n const fileName = `${FONTS_DIR}/${fontFileName(filePath, content)}`;\n\n if (state.emitted.has(fileName)) {\n return;\n }\n\n state.emitted.add(fileName);\n ctx.emitFile({ type: \"asset\", fileName, source: content });\n};\n\nconst loadFontModule = (ctx: LoadContext, state: PluginState, id: string): string | undefined => {\n if (!isVirtual(id)) {\n return undefined;\n }\n\n const filePath = stripQuery(fromVirtualId(id));\n const content = readFileSync(filePath);\n const [family] = fontFamilyNames(content);\n\n if (family === undefined) {\n return ctx.error(unreadableFontError(filePath));\n }\n\n ctx.addWatchFile(filePath);\n\n if (state.isBuild) {\n emitFont(ctx, state, filePath, content);\n }\n\n return `export default ${JSON.stringify(family)};`;\n};\n\nconst hasSideEffectFontImport = (code: string, id: string): boolean => {\n const lang = sourceLanguage(stripQuery(id));\n\n if (lang === undefined || !code.includes(\"?font\")) {\n return false;\n }\n\n const parsed = parseSync(id, code, { lang });\n\n if (parsed.errors.length > 0) {\n return false;\n }\n\n return parsed.module.staticImports.some(\n (statement) => statement.entries.length === 0 && parseFontSpecifier(statement.moduleRequest.value) !== null,\n );\n};\n\nconst retainSideEffectFontImport = (\n code: string,\n id: string,\n): { code: string; moduleSideEffects: true } | null =>\n hasSideEffectFontImport(code, id)\n ? { code, moduleSideEffects: true }\n : null;\n\nconst fontBanner = (state: PluginState) => (chunk: Rollup.RenderedChunk): string =>\n state.emitted.size === 0 ? \"\" : xdgDataDirsBanner(chunk);\n\nfunction gtkxFont(): Plugin {\n const state: PluginState = { isBuild: false, emitted: new Set() };\n\n return {\n name: \"gtkx:font\",\n enforce: \"pre\",\n\n configResolved(config) {\n state.isBuild = config.command === \"build\";\n },\n\n resolveId(source, importer, options) {\n return resolveFontId(this, { source, importer, options });\n },\n\n load(id) {\n return loadFontModule(this, state, id);\n },\n\n transform(code, id) {\n return retainSideEffectFontImport(code, id);\n },\n\n outputOptions(options) {\n if (!state.isBuild) {\n return;\n }\n\n return prependBanner(options, fontBanner(state));\n },\n };\n}\n\nexport { gtkxFont };\n"]}
1
+ {"version":3,"file":"font.js","sourceRoot":"","sources":["../../src/vite-plugins/font.ts"],"names":[],"mappings":"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","sourcesContent":["import type { Plugin, Rollup } from \"vite\";\nimport { readFileSync } from \"node:fs\";\nimport { parseSync } from \"vite\";\nimport type { AssetEmitter } from \"./asset-emitter.js\";\nimport { prependBanner } from \"../internal/banner.js\";\nimport { fontFileName, FONTS_DIR } from \"../internal/font-path.js\";\nimport { stagedFontStatus } from \"../internal/font-staging.js\";\nimport { sourceLanguage } from \"../internal/source-imports.js\";\nimport { xdgDataDirsBanner } from \"../internal/xdg-banner.js\";\nimport { parseFontSpecifier } from \"./asset-specifier.js\";\nimport { fontFamilyNames } from \"./font-name.js\";\nimport { stripQuery } from \"./strip-query.js\";\nimport { createVirtualNamespace } from \"./virtual-module.js\";\n\ntype PluginState = {\n isBuild: boolean;\n root: string;\n emitted: Set<string>;\n importers: Map<string, string>;\n};\n\ntype ResolveContext = Parameters<typeof resolveToVirtual>[0];\ntype ResolveRequest = Parameters<typeof resolveToVirtual>[1];\n\ntype RetainedFontModuleId = {\n id: string;\n moduleSideEffects: true;\n};\n\ntype LoadContext = AssetEmitter & {\n addWatchFile: (file: string) => void;\n error: (message: string) => never;\n};\n\nconst VIRTUAL_PREFIX = \"\\0gtkx-font:\";\nconst { isVirtual, fromVirtualId, resolveToVirtual } = createVirtualNamespace(VIRTUAL_PREFIX);\n\nconst unreadableFontError = (filePath: string): string =>\n `Cannot read a font family name from ${filePath}; ?font expects a TrueType, OpenType, ` +\n \"TrueType Collection, WOFF, or WOFF2 font\";\n\nconst unstagedFontError = (filePath: string, importer: string): string =>\n `${filePath} was not staged before the toolkit started, so ${importer} would resolve its family to a ` +\n \"fallback font. Fonts are staged from ?font imports found in source files under the project root; move \" +\n \"the import there, or restart to pick it up.\";\n\nconst resolveFontId = async (\n ctx: ResolveContext,\n state: PluginState,\n request: ResolveRequest,\n): Promise<RetainedFontModuleId | undefined> => {\n if (parseFontSpecifier(request.source) === null) {\n return undefined;\n }\n\n const virtualId = await resolveToVirtual(ctx, request);\n\n if (virtualId === undefined) {\n return undefined;\n }\n\n state.importers.set(virtualId, request.importer ?? state.root);\n\n return { id: virtualId, moduleSideEffects: true };\n};\n\nconst emitFont = (ctx: LoadContext, state: PluginState, filePath: string, content: Buffer): void => {\n const fileName = `${FONTS_DIR}/${fontFileName(filePath, content)}`;\n\n if (state.emitted.has(fileName)) {\n return;\n }\n\n state.emitted.add(fileName);\n ctx.emitFile({ type: \"asset\", fileName, source: content });\n};\n\nconst loadFontModule = (ctx: LoadContext, state: PluginState, id: string): string | undefined => {\n if (!isVirtual(id)) {\n return undefined;\n }\n\n const filePath = stripQuery(fromVirtualId(id));\n const content = readFileSync(filePath);\n const [family] = fontFamilyNames(content);\n\n if (family === undefined) {\n return ctx.error(unreadableFontError(filePath));\n }\n\n ctx.addWatchFile(filePath);\n\n if (state.isBuild) {\n emitFont(ctx, state, filePath, content);\n } else if (stagedFontStatus(filePath, content) === \"absent\") {\n return ctx.error(unstagedFontError(filePath, state.importers.get(id) ?? state.root));\n }\n\n return `export default ${JSON.stringify(family)};`;\n};\n\nconst hasSideEffectFontImport = (code: string, id: string): boolean => {\n const lang = sourceLanguage(stripQuery(id));\n\n if (lang === undefined || !code.includes(\"?font\")) {\n return false;\n }\n\n const parsed = parseSync(id, code, { lang });\n\n if (parsed.errors.length > 0) {\n return false;\n }\n\n return parsed.module.staticImports.some(\n (statement) => statement.entries.length === 0 && parseFontSpecifier(statement.moduleRequest.value) !== null,\n );\n};\n\nconst retainSideEffectFontImport = (\n code: string,\n id: string,\n): { code: string; moduleSideEffects: true } | null =>\n hasSideEffectFontImport(code, id)\n ? { code, moduleSideEffects: true }\n : null;\n\nconst fontBanner = (state: PluginState) => (chunk: Rollup.RenderedChunk): string =>\n state.emitted.size === 0 ? \"\" : xdgDataDirsBanner(chunk);\n\nfunction gtkxFont(): Plugin {\n const state: PluginState = { isBuild: false, root: \"\", emitted: new Set(), importers: new Map() };\n\n return {\n name: \"gtkx:font\",\n enforce: \"pre\",\n\n configResolved(config) {\n state.isBuild = config.command === \"build\";\n state.root = config.root;\n },\n\n resolveId(source, importer, options) {\n return resolveFontId(this, state, { source, importer, options });\n },\n\n load(id) {\n return loadFontModule(this, state, id);\n },\n\n transform(code, id) {\n return retainSideEffectFontImport(code, id);\n },\n\n outputOptions(options) {\n if (!state.isBuild) {\n return;\n }\n\n return prependBanner(options, fontBanner(state));\n },\n };\n}\n\nexport { gtkxFont };\n"]}
@@ -1,4 +1,4 @@
1
- import { createConfigLoader } from "@gtkx/config/internal";
1
+ import { createConfigLoader, viteProjectRoot } from "@gtkx/config/internal";
2
2
  import { info } from "@gtkx/utils";
3
3
  import { readFileSync } from "node:fs";
4
4
  import { join } from "node:path";
@@ -20,7 +20,7 @@ const findIconFiles = (state) => {
20
20
  }];
21
21
  };
22
22
  const applyUserConfig = async (state, config, loadConfig) => {
23
- const { config: gtkxConfig, root } = await loadConfig.load(config.root ?? process.cwd());
23
+ const { config: gtkxConfig, root } = await loadConfig.load(viteProjectRoot(config));
24
24
  state.applicationId = gtkxConfig.applicationId;
25
25
  state.source = resolveApplicationIcon(root, gtkxConfig.applicationId, gtkxConfig.applicationIcon);
26
26
  };
@@ -1 +1 @@
1
- {"version":3,"file":"icons.js","sourceRoot":"","sources":["../../src/vite-plugins/icons.ts"],"names":[],"mappings":"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","sourcesContent":["import type { ConfigLoader } from \"@gtkx/config\";\nimport type { Plugin, UserConfig } from \"vite\";\nimport { createConfigLoader } from \"@gtkx/config/internal\";\nimport { info } from \"@gtkx/utils\";\nimport { readFileSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport type { AssetEmitter } from \"./asset-emitter.js\";\nimport { prependBanner } from \"../internal/banner.js\";\nimport {\n relativeIconPath,\n resolveApplicationIcon,\n type ResolvedApplicationIcon,\n} from \"../internal/icon-path.js\";\nimport { type ListedFile, listFilesRecursive } from \"../internal/list-files.js\";\nimport { xdgDataDirsBanner } from \"../internal/xdg-banner.js\";\n\ntype PluginState = {\n applicationId: string;\n source: ResolvedApplicationIcon;\n};\n\nconst ICONS_DIR = \"icons\";\n\nconst findIconFiles = (state: PluginState): ListedFile[] => {\n if (state.source.kind === \"theme\") {\n return listFilesRecursive(state.source.path);\n }\n\n if (state.source.kind === \"none\") {\n return [];\n }\n\n return [{\n absPath: state.source.path,\n rel: relativeIconPath(state.applicationId, state.source.path),\n }];\n};\n\nconst applyUserConfig = async (state: PluginState, config: UserConfig, loadConfig: ConfigLoader): Promise<void> => {\n const { config: gtkxConfig, root } = await loadConfig.load(config.root ?? process.cwd());\n state.applicationId = gtkxConfig.applicationId;\n state.source = resolveApplicationIcon(root, gtkxConfig.applicationId, gtkxConfig.applicationIcon);\n};\n\nconst emitIcons = (ctx: AssetEmitter, icons: ListedFile[]): void => {\n for (const { absPath, rel } of icons) {\n ctx.emitFile({ type: \"asset\", fileName: join(ICONS_DIR, rel), source: readFileSync(absPath) });\n }\n\n if (icons.length > 0) {\n info(`Copied ${String(icons.length)} icon(s) into ${ICONS_DIR}/`);\n }\n};\n\nfunction gtkxIcons(loadConfig: ConfigLoader = createConfigLoader()): Plugin {\n const state: PluginState = {\n applicationId: \"\",\n source: { kind: \"none\" },\n };\n\n return {\n name: \"gtkx:icons\",\n enforce: \"pre\",\n apply: \"build\",\n\n async config(config: UserConfig) {\n await applyUserConfig(state, config, loadConfig);\n },\n\n outputOptions(options) {\n if (findIconFiles(state).length === 0) {\n return;\n }\n\n return prependBanner(options, xdgDataDirsBanner);\n },\n\n buildEnd() {\n emitIcons(this, findIconFiles(state));\n },\n };\n}\n\nexport { gtkxIcons };\n"]}
1
+ {"version":3,"file":"icons.js","sourceRoot":"","sources":["../../src/vite-plugins/icons.ts"],"names":[],"mappings":"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","sourcesContent":["import type { ConfigLoader } from \"@gtkx/config\";\nimport type { Plugin, UserConfig } from \"vite\";\nimport { createConfigLoader, viteProjectRoot } from \"@gtkx/config/internal\";\nimport { info } from \"@gtkx/utils\";\nimport { readFileSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport type { AssetEmitter } from \"./asset-emitter.js\";\nimport { prependBanner } from \"../internal/banner.js\";\nimport {\n relativeIconPath,\n resolveApplicationIcon,\n type ResolvedApplicationIcon,\n} from \"../internal/icon-path.js\";\nimport { type ListedFile, listFilesRecursive } from \"../internal/list-files.js\";\nimport { xdgDataDirsBanner } from \"../internal/xdg-banner.js\";\n\ntype PluginState = {\n applicationId: string;\n source: ResolvedApplicationIcon;\n};\n\nconst ICONS_DIR = \"icons\";\n\nconst findIconFiles = (state: PluginState): ListedFile[] => {\n if (state.source.kind === \"theme\") {\n return listFilesRecursive(state.source.path);\n }\n\n if (state.source.kind === \"none\") {\n return [];\n }\n\n return [{\n absPath: state.source.path,\n rel: relativeIconPath(state.applicationId, state.source.path),\n }];\n};\n\nconst applyUserConfig = async (state: PluginState, config: UserConfig, loadConfig: ConfigLoader): Promise<void> => {\n const { config: gtkxConfig, root } = await loadConfig.load(viteProjectRoot(config));\n state.applicationId = gtkxConfig.applicationId;\n state.source = resolveApplicationIcon(root, gtkxConfig.applicationId, gtkxConfig.applicationIcon);\n};\n\nconst emitIcons = (ctx: AssetEmitter, icons: ListedFile[]): void => {\n for (const { absPath, rel } of icons) {\n ctx.emitFile({ type: \"asset\", fileName: join(ICONS_DIR, rel), source: readFileSync(absPath) });\n }\n\n if (icons.length > 0) {\n info(`Copied ${String(icons.length)} icon(s) into ${ICONS_DIR}/`);\n }\n};\n\nfunction gtkxIcons(loadConfig: ConfigLoader = createConfigLoader()): Plugin {\n const state: PluginState = {\n applicationId: \"\",\n source: { kind: \"none\" },\n };\n\n return {\n name: \"gtkx:icons\",\n enforce: \"pre\",\n apply: \"build\",\n\n async config(config: UserConfig) {\n await applyUserConfig(state, config, loadConfig);\n },\n\n outputOptions(options) {\n if (findIconFiles(state).length === 0) {\n return;\n }\n\n return prependBanner(options, xdgDataDirsBanner);\n },\n\n buildEnd() {\n emitIcons(this, findIconFiles(state));\n },\n };\n}\n\nexport { gtkxIcons };\n"]}
@@ -1,6 +1,6 @@
1
1
  import { transformAsync } from "@babel/core";
2
2
  import babelPresetTypescriptNs from "@babel/preset-typescript";
3
- import { createConfigLoader } from "@gtkx/config/internal";
3
+ import { createConfigLoader, viteProjectRoot } from "@gtkx/config/internal";
4
4
  import babelPluginReactCompilerNs from "babel-plugin-react-compiler";
5
5
  const babelPresetTypescript = babelPresetTypescriptNs.default ?? babelPresetTypescriptNs;
6
6
  const babelPluginReactCompiler = babelPluginReactCompilerNs.default ?? babelPluginReactCompilerNs;
@@ -43,7 +43,7 @@ function gtkxReactCompiler(loadConfig = createConfigLoader()) {
43
43
  name: "gtkx:react-compiler",
44
44
  enforce: "pre",
45
45
  async config(config) {
46
- const resolved = await loadConfig.resolve(config.root ?? process.cwd());
46
+ const resolved = await loadConfig.resolve(viteProjectRoot(config));
47
47
  state.options = resolved.reactCompiler;
48
48
  },
49
49
  configResolved(config) {
@@ -1 +1 @@
1
- {"version":3,"file":"react-compiler.js","sourceRoot":"","sources":["../../src/vite-plugins/react-compiler.ts"],"names":[],"mappings":"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","sourcesContent":["import type { ConfigLoader } from \"@gtkx/config\";\nimport type { ResolvedReactCompilerOptions } from \"@gtkx/config/internal\";\nimport type { Plugin, ResolvedConfig, UserConfig } from \"vite\";\nimport { transformAsync } from \"@babel/core\";\nimport babelPresetTypescriptNs from \"@babel/preset-typescript\";\nimport { createConfigLoader } from \"@gtkx/config/internal\";\nimport babelPluginReactCompilerNs from \"babel-plugin-react-compiler\";\n\ntype ReactCompilerState = {\n root: string;\n options: ResolvedReactCompilerOptions | null;\n};\n\nconst babelPresetTypescript = babelPresetTypescriptNs.default ?? babelPresetTypescriptNs;\nconst babelPluginReactCompiler = babelPluginReactCompilerNs.default ?? babelPluginReactCompilerNs;\nconst SOURCE_EXTENSION = /\\.[jt]sx?$/;\nconst TYPESCRIPT_EXTENSION = /\\.tsx?$/;\nconst NODE_MODULES = /(?:^|\\/)node_modules\\//;\n\nconst isProjectSource = (root: string, id: string): boolean => {\n if (!SOURCE_EXTENSION.test(id)) {\n return false;\n }\n\n if (NODE_MODULES.test(id)) {\n return false;\n }\n\n if (root !== \"\" && !id.startsWith(`${root}/`)) {\n return false;\n }\n\n return true;\n};\n\nconst compileSource = async (code: string, id: string, options: ResolvedReactCompilerOptions) => {\n const result = await transformAsync(code, {\n filename: id,\n babelrc: false,\n configFile: false,\n sourceMaps: true,\n parserOpts: { plugins: id.endsWith(\".ts\") ? [] : [\"jsx\"] },\n presets: TYPESCRIPT_EXTENSION.test(id) ? [babelPresetTypescript] : [],\n plugins: [[babelPluginReactCompiler, options]],\n });\n\n if (!result?.code) {\n return;\n }\n\n return result.map == null ? { code: result.code } : { code: result.code, map: JSON.stringify(result.map) };\n};\n\nfunction gtkxReactCompiler(loadConfig: ConfigLoader = createConfigLoader()): Plugin {\n const state: ReactCompilerState = {\n root: \"\",\n options: null,\n };\n\n return {\n name: \"gtkx:react-compiler\",\n enforce: \"pre\",\n\n async config(config: UserConfig) {\n const resolved = await loadConfig.resolve(config.root ?? process.cwd());\n state.options = resolved.reactCompiler;\n },\n\n configResolved(config: ResolvedConfig) {\n state.root = config.root;\n },\n\n async transform(code, id) {\n const options = state.options;\n\n if (options === null || !isProjectSource(state.root, id)) {\n return;\n }\n\n return compileSource(code, id, options);\n },\n };\n}\n\nexport { gtkxReactCompiler };\n"]}
1
+ {"version":3,"file":"react-compiler.js","sourceRoot":"","sources":["../../src/vite-plugins/react-compiler.ts"],"names":[],"mappings":"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","sourcesContent":["import type { ConfigLoader } from \"@gtkx/config\";\nimport type { ResolvedReactCompilerOptions } from \"@gtkx/config/internal\";\nimport type { Plugin, ResolvedConfig, UserConfig } from \"vite\";\nimport { transformAsync } from \"@babel/core\";\nimport babelPresetTypescriptNs from \"@babel/preset-typescript\";\nimport { createConfigLoader, viteProjectRoot } from \"@gtkx/config/internal\";\nimport babelPluginReactCompilerNs from \"babel-plugin-react-compiler\";\n\ntype ReactCompilerState = {\n root: string;\n options: ResolvedReactCompilerOptions | null;\n};\n\nconst babelPresetTypescript = babelPresetTypescriptNs.default ?? babelPresetTypescriptNs;\nconst babelPluginReactCompiler = babelPluginReactCompilerNs.default ?? babelPluginReactCompilerNs;\nconst SOURCE_EXTENSION = /\\.[jt]sx?$/;\nconst TYPESCRIPT_EXTENSION = /\\.tsx?$/;\nconst NODE_MODULES = /(?:^|\\/)node_modules\\//;\n\nconst isProjectSource = (root: string, id: string): boolean => {\n if (!SOURCE_EXTENSION.test(id)) {\n return false;\n }\n\n if (NODE_MODULES.test(id)) {\n return false;\n }\n\n if (root !== \"\" && !id.startsWith(`${root}/`)) {\n return false;\n }\n\n return true;\n};\n\nconst compileSource = async (code: string, id: string, options: ResolvedReactCompilerOptions) => {\n const result = await transformAsync(code, {\n filename: id,\n babelrc: false,\n configFile: false,\n sourceMaps: true,\n parserOpts: { plugins: id.endsWith(\".ts\") ? [] : [\"jsx\"] },\n presets: TYPESCRIPT_EXTENSION.test(id) ? [babelPresetTypescript] : [],\n plugins: [[babelPluginReactCompiler, options]],\n });\n\n if (!result?.code) {\n return;\n }\n\n return result.map == null ? { code: result.code } : { code: result.code, map: JSON.stringify(result.map) };\n};\n\nfunction gtkxReactCompiler(loadConfig: ConfigLoader = createConfigLoader()): Plugin {\n const state: ReactCompilerState = {\n root: \"\",\n options: null,\n };\n\n return {\n name: \"gtkx:react-compiler\",\n enforce: \"pre\",\n\n async config(config: UserConfig) {\n const resolved = await loadConfig.resolve(viteProjectRoot(config));\n state.options = resolved.reactCompiler;\n },\n\n configResolved(config: ResolvedConfig) {\n state.root = config.root;\n },\n\n async transform(code, id) {\n const options = state.options;\n\n if (options === null || !isProjectSource(state.root, id)) {\n return;\n }\n\n return compileSource(code, id, options);\n },\n };\n}\n\nexport { gtkxReactCompiler };\n"]}
@@ -1,4 +1,4 @@
1
- import { createConfigLoader, resourceBasePath } from "@gtkx/config/internal";
1
+ import { createConfigLoader, resourceBasePath, viteProjectRoot } from "@gtkx/config/internal";
2
2
  import { error, info, isPathInside, isRecord, sortStrings, toPosixPath } from "@gtkx/utils";
3
3
  import { copyFileSync, existsSync, mkdirSync, readFileSync, rmSync, writeFileSync } from "node:fs";
4
4
  import { basename, dirname, extname, isAbsolute, join, posix, relative, sep } from "node:path";
@@ -781,7 +781,7 @@ const reconcileImporter = async (ctx, state, id) => {
781
781
  }
782
782
  };
783
783
  const resolveResourceConfig = async (state, config, loadConfig) => {
784
- const loaded = await loadConfig.load(config.root ?? process.cwd());
784
+ const loaded = await loadConfig.load(viteProjectRoot(config));
785
785
  state.prefix = resourceBasePath(loaded.config.applicationId);
786
786
  state.root = loaded.root;
787
787
  return {