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

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 (127) hide show
  1. package/README.md +43 -40
  2. package/dist/builder.d.ts.map +1 -1
  3. package/dist/builder.js +28 -8
  4. package/dist/builder.js.map +1 -1
  5. package/dist/cli.js +1 -1
  6. package/dist/cli.js.map +1 -1
  7. package/dist/codegen/freshness.d.ts.map +1 -1
  8. package/dist/codegen/freshness.js +5 -1
  9. package/dist/codegen/freshness.js.map +1 -1
  10. package/dist/deploy/freedesktop/validate.d.ts.map +1 -1
  11. package/dist/deploy/freedesktop/validate.js +6 -1
  12. package/dist/deploy/freedesktop/validate.js.map +1 -1
  13. package/dist/deploy/settings/libraries.d.ts.map +1 -1
  14. package/dist/deploy/settings/libraries.js +2 -1
  15. package/dist/deploy/settings/libraries.js.map +1 -1
  16. package/dist/deploy/targets/flatpak-source.d.ts.map +1 -1
  17. package/dist/deploy/targets/flatpak-source.js +2 -0
  18. package/dist/deploy/targets/flatpak-source.js.map +1 -1
  19. package/dist/dev/font-dir.d.ts +3 -0
  20. package/dist/dev/font-dir.d.ts.map +1 -0
  21. package/dist/dev/font-dir.js +12 -0
  22. package/dist/dev/font-dir.js.map +1 -0
  23. package/dist/dev/runner-main.d.ts.map +1 -1
  24. package/dist/dev/runner-main.js +2 -0
  25. package/dist/dev/runner-main.js.map +1 -1
  26. package/dist/internal/agent-rules.d.ts.map +1 -1
  27. package/dist/internal/agent-rules.js +7 -2
  28. package/dist/internal/agent-rules.js.map +1 -1
  29. package/dist/internal/banner.d.ts +4 -2
  30. package/dist/internal/banner.d.ts.map +1 -1
  31. package/dist/internal/banner.js +19 -5
  32. package/dist/internal/banner.js.map +1 -1
  33. package/dist/internal/font-path.d.ts +4 -0
  34. package/dist/internal/font-path.d.ts.map +1 -0
  35. package/dist/internal/font-path.js +12 -0
  36. package/dist/internal/font-path.js.map +1 -0
  37. package/dist/internal/font-staging.d.ts +3 -0
  38. package/dist/internal/font-staging.d.ts.map +1 -0
  39. package/dist/internal/font-staging.js +43 -0
  40. package/dist/internal/font-staging.js.map +1 -0
  41. package/dist/internal/source-imports.d.ts +2 -1
  42. package/dist/internal/source-imports.d.ts.map +1 -1
  43. package/dist/internal/source-imports.js +7 -2
  44. package/dist/internal/source-imports.js.map +1 -1
  45. package/dist/internal/xdg-banner.d.ts +4 -0
  46. package/dist/internal/xdg-banner.d.ts.map +1 -0
  47. package/dist/internal/xdg-banner.js +11 -0
  48. package/dist/internal/xdg-banner.js.map +1 -0
  49. package/dist/internal/xdg-data-dirs.d.ts +2 -1
  50. package/dist/internal/xdg-data-dirs.d.ts.map +1 -1
  51. package/dist/internal/xdg-data-dirs.js +1 -1
  52. package/dist/internal/xdg-data-dirs.js.map +1 -1
  53. package/dist/settings/schema.d.ts.map +1 -1
  54. package/dist/settings/schema.js +1 -6
  55. package/dist/settings/schema.js.map +1 -1
  56. package/dist/vite-plugins/asset-extensions.d.ts.map +1 -1
  57. package/dist/vite-plugins/asset-extensions.js +2 -0
  58. package/dist/vite-plugins/asset-extensions.js.map +1 -1
  59. package/dist/vite-plugins/asset-imports.d.ts.map +1 -1
  60. package/dist/vite-plugins/asset-imports.js +7 -2
  61. package/dist/vite-plugins/asset-imports.js.map +1 -1
  62. package/dist/vite-plugins/asset-specifier.d.ts +5 -1
  63. package/dist/vite-plugins/asset-specifier.d.ts.map +1 -1
  64. package/dist/vite-plugins/asset-specifier.js +10 -1
  65. package/dist/vite-plugins/asset-specifier.js.map +1 -1
  66. package/dist/vite-plugins/css.d.ts.map +1 -1
  67. package/dist/vite-plugins/css.js +3 -2
  68. package/dist/vite-plugins/css.js.map +1 -1
  69. package/dist/vite-plugins/font-name.d.ts +3 -0
  70. package/dist/vite-plugins/font-name.d.ts.map +1 -0
  71. package/dist/vite-plugins/font-name.js +406 -0
  72. package/dist/vite-plugins/font-name.js.map +1 -0
  73. package/dist/vite-plugins/font-worker-env.d.ts +4 -0
  74. package/dist/vite-plugins/font-worker-env.d.ts.map +1 -0
  75. package/dist/vite-plugins/font-worker-env.js +22 -0
  76. package/dist/vite-plugins/font-worker-env.js.map +1 -0
  77. package/dist/vite-plugins/font.d.ts +4 -0
  78. package/dist/vite-plugins/font.d.ts.map +1 -0
  79. package/dist/vite-plugins/font.js +87 -0
  80. package/dist/vite-plugins/font.js.map +1 -0
  81. package/dist/vite-plugins/icons.d.ts.map +1 -1
  82. package/dist/vite-plugins/icons.js +2 -7
  83. package/dist/vite-plugins/icons.js.map +1 -1
  84. package/dist/vite-plugins/index.d.ts.map +1 -1
  85. package/dist/vite-plugins/index.js +2 -0
  86. package/dist/vite-plugins/index.js.map +1 -1
  87. package/dist/vite-plugins/resources.js +1 -1
  88. package/dist/vite-plugins/resources.js.map +1 -1
  89. package/dist/vite-plugins/settings.d.ts.map +1 -1
  90. package/dist/vite-plugins/settings.js +6 -6
  91. package/dist/vite-plugins/settings.js.map +1 -1
  92. package/dist/vite-plugins/undeclared-library.js +3 -3
  93. package/dist/vite-plugins/undeclared-library.js.map +1 -1
  94. package/dist/vitest-plugin.d.ts.map +1 -1
  95. package/dist/vitest-plugin.js +2 -0
  96. package/dist/vitest-plugin.js.map +1 -1
  97. package/env.d.ts +9 -0
  98. package/package.json +14 -12
  99. package/src/builder.ts +28 -8
  100. package/src/cli.ts +1 -1
  101. package/src/codegen/freshness.ts +5 -1
  102. package/src/deploy/freedesktop/validate.ts +8 -1
  103. package/src/deploy/settings/libraries.ts +2 -1
  104. package/src/deploy/targets/flatpak-source.ts +2 -0
  105. package/src/dev/font-dir.ts +16 -0
  106. package/src/dev/runner-main.ts +2 -0
  107. package/src/internal/agent-rules.ts +7 -2
  108. package/src/internal/banner.ts +27 -6
  109. package/src/internal/font-path.ts +15 -0
  110. package/src/internal/font-staging.ts +57 -0
  111. package/src/internal/source-imports.ts +17 -2
  112. package/src/internal/xdg-banner.ts +13 -0
  113. package/src/internal/xdg-data-dirs.ts +1 -1
  114. package/src/settings/schema.ts +1 -8
  115. package/src/vite-plugins/asset-extensions.ts +2 -0
  116. package/src/vite-plugins/asset-imports.ts +9 -1
  117. package/src/vite-plugins/asset-specifier.ts +17 -0
  118. package/src/vite-plugins/css.ts +4 -2
  119. package/src/vite-plugins/font-name.ts +582 -0
  120. package/src/vite-plugins/font-worker-env.ts +29 -0
  121. package/src/vite-plugins/font.ts +147 -0
  122. package/src/vite-plugins/icons.ts +2 -8
  123. package/src/vite-plugins/index.ts +2 -0
  124. package/src/vite-plugins/resources.ts +1 -1
  125. package/src/vite-plugins/settings.ts +7 -7
  126. package/src/vite-plugins/undeclared-library.ts +3 -3
  127. package/src/vitest-plugin.ts +2 -0
@@ -1 +1 @@
1
- {"version":3,"file":"settings.js","sourceRoot":"","sources":["../../src/vite-plugins/settings.ts"],"names":[],"mappings":"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","sourcesContent":["import type { ModuleNode, Plugin, ResolvedConfig, ViteDevServer } from \"vite\";\nimport { error, errorMessage, info, sortStrings } from \"@gtkx/utils\";\nimport { readFileSync } from \"node:fs\";\nimport { basename, join } from \"node:path\";\nimport type { BuildManifestCollector } from \"../internal/build-manifest.js\";\nimport type { AssetEmitter } from \"./asset-emitter.js\";\nimport { prependBanner } from \"../internal/banner.js\";\nimport { createRetainedStagingDir, type RetainedStagingDir, withStagingDir } from \"../internal/staging-dir.js\";\nimport { compileSchemas } from \"../settings/compile.js\";\nimport { parseSchemaXml, SchemaParseError } from \"../settings/parser.js\";\nimport { renderRuntimeModule } from \"../settings/render.js\";\nimport {\n assertUniqueSchemaBasenames,\n emitSchemaEnv,\n prependSchemaDir,\n projectRelativeSchemaPath,\n SCHEMA_SUFFIX,\n stageSchema,\n} from \"../settings/schema.js\";\nimport { createVirtualNamespace } from \"./virtual-module.js\";\n\ntype PluginState = {\n schemaDir: RetainedStagingDir;\n rootDir: string | null;\n isBuild: boolean;\n schemaEnvTimer: ReturnType<typeof setTimeout> | null;\n trackedSchemas: Map<string, string>;\n buildSchemas: Set<string>;\n};\n\ntype PluginContext = AssetEmitter & {\n error: (message: string) => never;\n};\n\nconst VIRTUAL_PREFIX = \"\\0gtkx-settings:\";\nconst SCHEMA_STAGING_PREFIX = \"schemas\";\nconst SOURCE_MODULE_RE = /\\.[cm]?[jt]sx?$/;\nconst SCHEMA_ENV_DEBOUNCE_MS = 50;\nconst { isVirtual, fromVirtualId, resolveToVirtual } = createVirtualNamespace(VIRTUAL_PREFIX);\n\nconst SCHEMA_ENV_BANNER = [\n \"process.env.GSETTINGS_SCHEMA_DIR = [\",\n \" decodeURIComponent(new URL(\\\".\\\", import.meta.url).pathname),\",\n \" process.env.GSETTINGS_SCHEMA_DIR,\",\n \"]\",\n \" .filter(Boolean)\",\n \" .join(\\\":\\\");\",\n].join(\"\\n\");\n\nconst ensureSchemaDir = (state: PluginState): string => {\n const existing = state.schemaDir.getPath();\n\n if (existing !== null) {\n return existing;\n }\n\n const runnerDir = process.env.GTKX_DEV_SCHEMA_DIR;\n\n return runnerDir ? state.schemaDir.adopt(runnerDir) : state.schemaDir.retain();\n};\n\nconst compileSchemaDir = (state: PluginState): void => {\n const dir = state.schemaDir.getPath();\n\n if (dir === null) {\n return;\n }\n\n compileSchemas(dir);\n process.env.GSETTINGS_SCHEMA_DIR = prependSchemaDir(dir, process.env.GSETTINGS_SCHEMA_DIR);\n};\n\nconst syncSchemaEnv = (state: PluginState): void => {\n if (state.rootDir === null) {\n return;\n }\n\n try {\n emitSchemaEnv(state.rootDir);\n } catch (error_) {\n error(`Failed to generate GSettings schema types: ${errorMessage(error_)}`);\n }\n};\n\nconst cancelSchemaEnvSync = (state: PluginState): void => {\n if (state.schemaEnvTimer === null) {\n return;\n }\n\n clearTimeout(state.schemaEnvTimer);\n state.schemaEnvTimer = null;\n};\n\nconst scheduleSchemaEnvSync = (state: PluginState): void => {\n cancelSchemaEnvSync(state);\n\n state.schemaEnvTimer = setTimeout(() => {\n state.schemaEnvTimer = null;\n syncSchemaEnv(state);\n }, SCHEMA_ENV_DEBOUNCE_MS);\n};\n\nconst applyResolvedConfig = (state: PluginState, config: ResolvedConfig): void => {\n state.isBuild = config.command === \"build\";\n state.rootDir = typeof config.root === \"string\" ? config.root : null;\n syncSchemaEnv(state);\n};\n\nconst registerSchemaForMode = (state: PluginState, filePath: string, id: string): void => {\n const fileName = basename(filePath);\n\n if (state.isBuild) {\n state.buildSchemas.add(filePath);\n info(`Queued GSettings schema: ${fileName}`);\n\n return;\n }\n\n state.trackedSchemas.set(filePath, id);\n const dir = ensureSchemaDir(state);\n stageSchema(dir, filePath);\n compileSchemaDir(state);\n info(`Compiled GSettings schema: ${fileName}`);\n};\n\nconst loadSchemaModule = (ctx: PluginContext, state: PluginState, id: string): string | undefined => {\n if (!isVirtual(id)) {\n return undefined;\n }\n\n const filePath = fromVirtualId(id);\n const xml = readFileSync(filePath, \"utf8\");\n const fileName = basename(filePath);\n registerSchemaForMode(state, filePath, id);\n let parsed: ReturnType<typeof parseSchemaXml>;\n\n try {\n parsed = parseSchemaXml(xml, fileName);\n } catch (error) {\n if (!(error instanceof SchemaParseError)) {\n throw error;\n }\n\n ctx.error(error.message);\n }\n\n if (parsed.schemas.length === 0) {\n ctx.error(`No <schema id=\"...\"> found in ${fileName}`);\n }\n\n return renderRuntimeModule(parsed);\n};\n\nconst compileBuildSchemas = (schemaFiles: string[]): Buffer =>\n withStagingDir(\"schemas-build\", (dir) => {\n for (const filePath of schemaFiles) {\n stageSchema(dir, filePath);\n }\n\n compileSchemas(dir);\n\n return readFileSync(join(dir, \"gschemas.compiled\"));\n });\n\nconst rejectLegacySchemaSpecifier = (source: string): void => {\n if (source.startsWith(\"#data/\")) {\n throw new Error(`${JSON.stringify(source)} uses the legacy #data schema form`);\n }\n};\n\nconst buildSchemaPaths = (rootDir: string, schemaFiles: string[]): string[] =>\n schemaFiles.map((filePath) => {\n const rel = projectRelativeSchemaPath(rootDir, filePath);\n\n if (rel === null) {\n throw new Error(`Cannot package the GSettings schema ${filePath}: it is outside ${rootDir}`);\n }\n\n return rel;\n });\n\nconst emitBuildSchemas = (\n ctx: PluginContext,\n state: PluginState,\n buildManifest: BuildManifestCollector | undefined,\n): void => {\n if (!state.isBuild || state.rootDir === null) {\n return;\n }\n\n const rootDir = state.rootDir;\n const schemaFiles = sortStrings(state.buildSchemas);\n assertUniqueSchemaBasenames(schemaFiles);\n const schemas = buildSchemaPaths(rootDir, schemaFiles);\n\n if (buildManifest !== undefined) {\n buildManifest.schemas = schemas;\n }\n\n if (schemaFiles.length === 0) {\n return;\n }\n\n const compiled = compileBuildSchemas(schemaFiles);\n\n ctx.emitFile({\n type: \"asset\",\n fileName: \"gschemas.compiled\",\n source: compiled,\n });\n\n info(`Compiled ${String(schemaFiles.length)} GSettings schema(s)`);\n};\n\nconst handleSchemaHotUpdate = (state: PluginState, file: string, server: ViteDevServer): ModuleNode[] | undefined => {\n if (file.endsWith(SCHEMA_SUFFIX) || SOURCE_MODULE_RE.test(file)) {\n scheduleSchemaEnvSync(state);\n }\n\n const virtualId = state.trackedSchemas.get(file);\n\n if (!virtualId) {\n return;\n }\n\n const dir = ensureSchemaDir(state);\n stageSchema(dir, file);\n compileSchemaDir(state);\n info(`Recompiled GSettings schema: ${basename(file)}`);\n const mod = server.moduleGraph.getModuleById(virtualId);\n\n if (mod) {\n server.moduleGraph.invalidateModule(mod);\n\n return [mod];\n }\n\n return undefined;\n};\n\nconst watchSchemaFiles = (state: PluginState, server: ViteDevServer): void => {\n const onClose = (): void => {\n cancelSchemaEnvSync(state);\n state.schemaDir.release();\n };\n\n server.httpServer?.once(\"close\", onClose);\n server.watcher.once(\"close\", onClose);\n\n const refreshSchemaTypes = (file: string): void => {\n if (file.endsWith(SCHEMA_SUFFIX) || SOURCE_MODULE_RE.test(file)) {\n scheduleSchemaEnvSync(state);\n }\n };\n\n server.watcher.on(\"add\", refreshSchemaTypes);\n server.watcher.on(\"unlink\", refreshSchemaTypes);\n};\n\nfunction gtkxSettings(buildManifest?: BuildManifestCollector): Plugin {\n const state: PluginState = {\n schemaDir: createRetainedStagingDir(SCHEMA_STAGING_PREFIX),\n rootDir: null,\n isBuild: false,\n schemaEnvTimer: null,\n trackedSchemas: new Map(),\n buildSchemas: new Set(),\n };\n\n return {\n name: \"gtkx:settings\",\n enforce: \"pre\",\n\n configResolved(config) {\n applyResolvedConfig(state, config);\n },\n\n configureServer(server) {\n watchSchemaFiles(state, server);\n },\n\n outputOptions(options) {\n if (!state.isBuild) {\n return;\n }\n\n return prependBanner(options, SCHEMA_ENV_BANNER);\n },\n\n async resolveId(source, importer, options) {\n if (!source.endsWith(SCHEMA_SUFFIX)) {\n return;\n }\n\n rejectLegacySchemaSpecifier(source);\n\n return resolveToVirtual(this, { source, importer, options });\n },\n\n load(id) {\n return loadSchemaModule(this, state, id);\n },\n\n buildEnd() {\n emitBuildSchemas(this, state, buildManifest);\n },\n\n closeBundle() {\n cancelSchemaEnvSync(state);\n state.schemaDir.release();\n },\n\n handleHotUpdate({ file, server }) {\n return handleSchemaHotUpdate(state, file, server);\n },\n };\n}\n\nexport { gtkxSettings };\n"]}
1
+ {"version":3,"file":"settings.js","sourceRoot":"","sources":["../../src/vite-plugins/settings.ts"],"names":[],"mappings":"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","sourcesContent":["import type { ModuleNode, Plugin, ResolvedConfig, Rollup, ViteDevServer } from \"vite\";\nimport { error, errorMessage, info, sortStrings } from \"@gtkx/utils\";\nimport { readFileSync } from \"node:fs\";\nimport { basename, join } from \"node:path\";\nimport type { BuildManifestCollector } from \"../internal/build-manifest.js\";\nimport type { AssetEmitter } from \"./asset-emitter.js\";\nimport { outputRootUrlExpression, prependBanner } from \"../internal/banner.js\";\nimport { createRetainedStagingDir, type RetainedStagingDir, withStagingDir } from \"../internal/staging-dir.js\";\nimport { compileSchemas } from \"../settings/compile.js\";\nimport { parseSchemaXml, SchemaParseError } from \"../settings/parser.js\";\nimport { renderRuntimeModule } from \"../settings/render.js\";\nimport {\n assertUniqueSchemaBasenames,\n emitSchemaEnv,\n prependSchemaDir,\n projectRelativeSchemaPath,\n SCHEMA_SUFFIX,\n stageSchema,\n} from \"../settings/schema.js\";\nimport { createVirtualNamespace } from \"./virtual-module.js\";\n\ntype PluginState = {\n schemaDir: RetainedStagingDir;\n rootDir: string | null;\n isBuild: boolean;\n schemaEnvTimer: ReturnType<typeof setTimeout> | null;\n trackedSchemas: Map<string, string>;\n buildSchemas: Set<string>;\n};\n\ntype PluginContext = AssetEmitter & {\n error: (message: string) => never;\n};\n\nconst VIRTUAL_PREFIX = \"\\0gtkx-settings:\";\nconst SCHEMA_STAGING_PREFIX = \"schemas\";\nconst SOURCE_MODULE_RE = /\\.[cm]?[jt]sx?$/;\nconst SCHEMA_ENV_DEBOUNCE_MS = 50;\nconst { isVirtual, fromVirtualId, resolveToVirtual } = createVirtualNamespace(VIRTUAL_PREFIX);\n\nconst schemaEnvBanner = (chunk: Rollup.RenderedChunk): string => [\n \"globalThis.process.env.GSETTINGS_SCHEMA_DIR = [\",\n ` ${outputRootUrlExpression(chunk)},`,\n \" globalThis.process.env.GSETTINGS_SCHEMA_DIR,\",\n \"]\",\n \" .filter(Boolean)\",\n \" .join(\\\":\\\");\",\n].join(\"\\n\");\n\nconst ensureSchemaDir = (state: PluginState): string => {\n const existing = state.schemaDir.getPath();\n\n if (existing !== null) {\n return existing;\n }\n\n const runnerDir = process.env.GTKX_DEV_SCHEMA_DIR;\n\n return runnerDir ? state.schemaDir.adopt(runnerDir) : state.schemaDir.retain();\n};\n\nconst compileSchemaDir = (state: PluginState): void => {\n const dir = state.schemaDir.getPath();\n\n if (dir === null) {\n return;\n }\n\n compileSchemas(dir);\n process.env.GSETTINGS_SCHEMA_DIR = prependSchemaDir(dir, process.env.GSETTINGS_SCHEMA_DIR);\n};\n\nconst syncSchemaEnv = (state: PluginState): void => {\n if (state.rootDir === null) {\n return;\n }\n\n try {\n emitSchemaEnv(state.rootDir);\n } catch (error_) {\n error(`Failed to generate GSettings schema types: ${errorMessage(error_)}`);\n }\n};\n\nconst cancelSchemaEnvSync = (state: PluginState): void => {\n if (state.schemaEnvTimer === null) {\n return;\n }\n\n clearTimeout(state.schemaEnvTimer);\n state.schemaEnvTimer = null;\n};\n\nconst scheduleSchemaEnvSync = (state: PluginState): void => {\n cancelSchemaEnvSync(state);\n\n state.schemaEnvTimer = setTimeout(() => {\n state.schemaEnvTimer = null;\n syncSchemaEnv(state);\n }, SCHEMA_ENV_DEBOUNCE_MS);\n};\n\nconst applyResolvedConfig = (state: PluginState, config: ResolvedConfig): void => {\n state.isBuild = config.command === \"build\";\n state.rootDir = typeof config.root === \"string\" ? config.root : null;\n syncSchemaEnv(state);\n};\n\nconst registerSchemaForMode = (state: PluginState, filePath: string, id: string): void => {\n const fileName = basename(filePath);\n\n if (state.isBuild) {\n state.buildSchemas.add(filePath);\n info(`Queued GSettings schema: ${fileName}`);\n\n return;\n }\n\n state.trackedSchemas.set(filePath, id);\n const dir = ensureSchemaDir(state);\n stageSchema(dir, filePath);\n compileSchemaDir(state);\n info(`Compiled GSettings schema: ${fileName}`);\n};\n\nconst loadSchemaModule = (ctx: PluginContext, state: PluginState, id: string): string | undefined => {\n if (!isVirtual(id)) {\n return undefined;\n }\n\n const filePath = fromVirtualId(id);\n const xml = readFileSync(filePath, \"utf8\");\n const fileName = basename(filePath);\n registerSchemaForMode(state, filePath, id);\n let parsed: ReturnType<typeof parseSchemaXml>;\n\n try {\n parsed = parseSchemaXml(xml, fileName);\n } catch (error) {\n if (!(error instanceof SchemaParseError)) {\n throw error;\n }\n\n ctx.error(error.message);\n }\n\n if (parsed.schemas.length === 0) {\n ctx.error(`No <schema id=\"...\"> found in ${fileName}`);\n }\n\n return renderRuntimeModule(parsed);\n};\n\nconst compileBuildSchemas = (schemaFiles: string[]): Buffer =>\n withStagingDir(\"schemas-build\", (dir) => {\n for (const filePath of schemaFiles) {\n stageSchema(dir, filePath);\n }\n\n compileSchemas(dir);\n\n return readFileSync(join(dir, \"gschemas.compiled\"));\n });\n\nconst rejectLegacySchemaSpecifier = (source: string): void => {\n if (source.startsWith(\"#data/\")) {\n throw new Error(`${JSON.stringify(source)} uses the legacy #data schema form`);\n }\n};\n\nconst buildSchemaPaths = (rootDir: string, schemaFiles: string[]): string[] =>\n schemaFiles.map((filePath) => {\n const rel = projectRelativeSchemaPath(rootDir, filePath);\n\n if (rel === null) {\n throw new Error(`Cannot package the GSettings schema ${filePath}: it is outside ${rootDir}`);\n }\n\n return rel;\n });\n\nconst emitBuildSchemas = (\n ctx: PluginContext,\n state: PluginState,\n buildManifest: BuildManifestCollector | undefined,\n): void => {\n if (!state.isBuild || state.rootDir === null) {\n return;\n }\n\n const rootDir = state.rootDir;\n const schemaFiles = sortStrings(state.buildSchemas);\n assertUniqueSchemaBasenames(schemaFiles);\n const schemas = buildSchemaPaths(rootDir, schemaFiles);\n\n if (buildManifest !== undefined) {\n buildManifest.schemas = schemas;\n }\n\n if (schemaFiles.length === 0) {\n return;\n }\n\n const compiled = compileBuildSchemas(schemaFiles);\n\n ctx.emitFile({\n type: \"asset\",\n fileName: \"gschemas.compiled\",\n source: compiled,\n });\n\n info(`Compiled ${String(schemaFiles.length)} GSettings schema(s)`);\n};\n\nconst handleSchemaHotUpdate = (state: PluginState, file: string, server: ViteDevServer): ModuleNode[] | undefined => {\n if (file.endsWith(SCHEMA_SUFFIX) || SOURCE_MODULE_RE.test(file)) {\n scheduleSchemaEnvSync(state);\n }\n\n const virtualId = state.trackedSchemas.get(file);\n\n if (!virtualId) {\n return;\n }\n\n const dir = ensureSchemaDir(state);\n stageSchema(dir, file);\n compileSchemaDir(state);\n info(`Recompiled GSettings schema: ${basename(file)}`);\n const mod = server.moduleGraph.getModuleById(virtualId);\n\n if (mod) {\n server.moduleGraph.invalidateModule(mod);\n\n return [mod];\n }\n\n return undefined;\n};\n\nconst watchSchemaFiles = (state: PluginState, server: ViteDevServer): void => {\n const onClose = (): void => {\n cancelSchemaEnvSync(state);\n state.schemaDir.release();\n };\n\n server.httpServer?.once(\"close\", onClose);\n server.watcher.once(\"close\", onClose);\n\n const refreshSchemaTypes = (file: string): void => {\n if (file.endsWith(SCHEMA_SUFFIX) || SOURCE_MODULE_RE.test(file)) {\n scheduleSchemaEnvSync(state);\n }\n };\n\n server.watcher.on(\"add\", refreshSchemaTypes);\n server.watcher.on(\"unlink\", refreshSchemaTypes);\n};\n\nfunction gtkxSettings(buildManifest?: BuildManifestCollector): Plugin {\n const state: PluginState = {\n schemaDir: createRetainedStagingDir(SCHEMA_STAGING_PREFIX),\n rootDir: null,\n isBuild: false,\n schemaEnvTimer: null,\n trackedSchemas: new Map(),\n buildSchemas: new Set(),\n };\n\n return {\n name: \"gtkx:settings\",\n enforce: \"pre\",\n\n configResolved(config) {\n applyResolvedConfig(state, config);\n },\n\n configureServer(server) {\n watchSchemaFiles(state, server);\n },\n\n outputOptions(options) {\n if (!state.isBuild) {\n return;\n }\n\n return prependBanner(options, schemaEnvBanner);\n },\n\n async resolveId(source, importer, options) {\n if (!source.endsWith(SCHEMA_SUFFIX)) {\n return;\n }\n\n rejectLegacySchemaSpecifier(source);\n\n return resolveToVirtual(this, { source, importer, options });\n },\n\n load(id) {\n return loadSchemaModule(this, state, id);\n },\n\n buildEnd() {\n emitBuildSchemas(this, state, buildManifest);\n },\n\n closeBundle() {\n cancelSchemaEnvSync(state);\n state.schemaDir.release();\n },\n\n handleHotUpdate({ file, server }) {\n return handleSchemaHotUpdate(state, file, server);\n },\n };\n}\n\nexport { gtkxSettings };\n"]}
@@ -3,7 +3,7 @@ import { createConfigLoader } from "@gtkx/config/internal";
3
3
  import { existsSync, readFileSync } from "node:fs";
4
4
  import { join } from "node:path";
5
5
  const GENERATED_MODULE_PATTERN = /^@gtkx\/(gi|jsx)\/([a-z0-9]+)$/;
6
- const DEFAULT_LIBRARY_NAMESPACES = new Set(["gtk", "adw"]);
6
+ const DEFAULT_LIBRARY_NAMESPACES = new Set(["adw", "gtk"]);
7
7
  const girSearchPaths = async (state) => {
8
8
  if (state.girPath === null) {
9
9
  const { config } = await state.loadConfig.load(state.root);
@@ -51,12 +51,12 @@ const undeclaredLibraryError = (source, namespace, girPath) => {
51
51
  if (identifier === undefined) {
52
52
  return new Error(`Cannot resolve "${source}": the binding store has no "${namespace}" module, and no ` +
53
53
  `GIR data for it was found in [${girPath.join(", ")}]. If "${namespace}" is a library, install ` +
54
- "its gobject-introspection data package. Gtk-4.0 and Adw-1 are bound by default; add only other " +
54
+ "its gobject-introspection data package. Adw-1 is bound by default and pulls in Gtk-4.0; add only other " +
55
55
  "GIR identifiers to `libraries` in gtkx.config.ts. Otherwise run gtkx codegen to regenerate the store.");
56
56
  }
57
57
  if (DEFAULT_LIBRARY_NAMESPACES.has(namespace)) {
58
58
  return new Error(`Cannot resolve "${source}": the "${identifier}" bindings have not been generated. ` +
59
- "The Gtk and Adwaita namespaces are bound by default; run gtkx dev or gtkx build again.");
59
+ "The Adwaita and GTK namespaces are generated implicitly; run gtkx dev or gtkx build again.");
60
60
  }
61
61
  return new Error(`Cannot resolve "${source}": the "${identifier}" bindings have not been generated. ` +
62
62
  `Add "${identifier}" to \`libraries\` in gtkx.config.ts, then run gtkx dev or gtkx build again.`);
@@ -1 +1 @@
1
- {"version":3,"file":"undeclared-library.js","sourceRoot":"","sources":["../../src/vite-plugins/undeclared-library.ts"],"names":[],"mappings":"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","sourcesContent":["import type { StoreOptions } from \"@gtkx/codegen\";\nimport type { ConfigLoader } from \"@gtkx/config\";\nimport type { Plugin, UserConfig } from \"vite\";\nimport { discoverGirNamespaces, resolveGirPath, resolveStore } from \"@gtkx/codegen\";\nimport { createConfigLoader } from \"@gtkx/config/internal\";\nimport { existsSync, readFileSync } from \"node:fs\";\nimport { join } from \"node:path\";\n\ntype PluginState = {\n root: string;\n loadConfig: ConfigLoader;\n girPath: string[] | null;\n};\n\ntype GeneratedModule = {\n source: string;\n kind: string;\n namespace: string;\n importer: string;\n};\n\nconst GENERATED_MODULE_PATTERN = /^@gtkx\\/(gi|jsx)\\/([a-z0-9]+)$/;\nconst DEFAULT_LIBRARY_NAMESPACES: Set<string> = new Set([\"gtk\", \"adw\"]);\n\nconst girSearchPaths = async (state: PluginState): Promise<string[]> => {\n if (state.girPath === null) {\n const { config } = await state.loadConfig.load(state.root);\n state.girPath = resolveGirPath(config.girPath);\n }\n\n return state.girPath;\n};\n\nconst getNamespace = (identifier: string): string => identifier.slice(0, identifier.indexOf(\"-\")).toLowerCase();\n\nconst findGirIdentifier = (girPath: string[], namespace: string): string | undefined =>\n discoverGirNamespaces(girPath).find((identifier) => getNamespace(identifier) === namespace);\n\nconst parseGeneratedModule = (source: string, importer: string | undefined): GeneratedModule | null => {\n const matched = GENERATED_MODULE_PATTERN.exec(source);\n const kind = matched?.[1];\n const namespace = matched?.[2];\n\n if (kind === undefined || namespace === undefined) {\n return null;\n }\n\n return { source, kind, namespace, importer: importer ?? \"the project's sources\" };\n};\n\nconst getStoreOptions = (root: string, kind: string): StoreOptions | null => {\n try {\n const store = resolveStore(root);\n\n return kind === \"gi\" ? store.gi : store.jsx;\n } catch {\n return null;\n }\n};\n\nconst hasStoreModule = (storeDir: string, exportKey: string): boolean => {\n const manifest = join(storeDir, \"package.json\");\n\n if (!existsSync(manifest)) {\n return false;\n }\n\n const { exports } = JSON.parse(readFileSync(manifest, \"utf8\")) as { exports?: Record<string, unknown> };\n\n return exports?.[exportKey] !== undefined;\n};\n\nconst unreachableStoreError = (generated: GeneratedModule, options: StoreOptions): Error => {\n const provided = `\"${generated.namespace}\"`;\n\n return new Error(\n `Cannot resolve \"${generated.source}\": the generated store in ${options.storeDir} does provide ` +\n `${provided}, but its link at ${options.linkDir} is not on the module resolution path of ` +\n `${generated.importer}. Codegen writes the store into the node_modules the installed @gtkx packages ` +\n \"resolve from; install them where the importing file reaches them, then run gtkx codegen again.\",\n );\n};\n\nconst undeclaredLibraryError = (source: string, namespace: string, girPath: string[]): Error => {\n const identifier = findGirIdentifier(girPath, namespace);\n\n if (identifier === undefined) {\n return new Error(\n `Cannot resolve \"${source}\": the binding store has no \"${namespace}\" module, and no ` +\n `GIR data for it was found in [${girPath.join(\", \")}]. If \"${namespace}\" is a library, install ` +\n \"its gobject-introspection data package. Gtk-4.0 and Adw-1 are bound by default; add only other \" +\n \"GIR identifiers to `libraries` in gtkx.config.ts. Otherwise run gtkx codegen to regenerate the store.\",\n );\n }\n\n if (DEFAULT_LIBRARY_NAMESPACES.has(namespace)) {\n return new Error(\n `Cannot resolve \"${source}\": the \"${identifier}\" bindings have not been generated. ` +\n \"The Gtk and Adwaita namespaces are bound by default; run gtkx dev or gtkx build again.\",\n );\n }\n\n return new Error(\n `Cannot resolve \"${source}\": the \"${identifier}\" bindings have not been generated. ` +\n `Add \"${identifier}\" to \\`libraries\\` in gtkx.config.ts, then run gtkx dev or gtkx build again.`,\n );\n};\n\nconst unresolvedModuleError = async (state: PluginState, generated: GeneratedModule): Promise<Error> => {\n const options = getStoreOptions(state.root, generated.kind);\n const exportKey = `./${generated.namespace}`;\n\n if (options !== null && hasStoreModule(options.storeDir, exportKey)) {\n return unreachableStoreError(generated, options);\n }\n\n return undeclaredLibraryError(generated.source, generated.namespace, await girSearchPaths(state));\n};\n\nfunction gtkxUndeclaredLibrary(loadConfig: ConfigLoader = createConfigLoader()): Plugin {\n const state: PluginState = {\n root: \"\",\n loadConfig,\n girPath: null,\n };\n\n return {\n name: \"gtkx:undeclared-library\",\n enforce: \"pre\",\n\n config(config: UserConfig) {\n state.root = config.root ?? process.cwd();\n },\n\n async resolveId(source, importer, options) {\n const generated = parseGeneratedModule(source, importer);\n\n if (generated === null) {\n return;\n }\n\n const resolved = await this.resolve(source, importer, { ...options, skipSelf: true });\n\n if (resolved !== null) {\n return;\n }\n\n throw await unresolvedModuleError(state, generated);\n },\n };\n}\n\nexport { gtkxUndeclaredLibrary };\n"]}
1
+ {"version":3,"file":"undeclared-library.js","sourceRoot":"","sources":["../../src/vite-plugins/undeclared-library.ts"],"names":[],"mappings":"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","sourcesContent":["import type { StoreOptions } from \"@gtkx/codegen\";\nimport type { ConfigLoader } from \"@gtkx/config\";\nimport type { Plugin, UserConfig } from \"vite\";\nimport { discoverGirNamespaces, resolveGirPath, resolveStore } from \"@gtkx/codegen\";\nimport { createConfigLoader } from \"@gtkx/config/internal\";\nimport { existsSync, readFileSync } from \"node:fs\";\nimport { join } from \"node:path\";\n\ntype PluginState = {\n root: string;\n loadConfig: ConfigLoader;\n girPath: string[] | null;\n};\n\ntype GeneratedModule = {\n source: string;\n kind: string;\n namespace: string;\n importer: string;\n};\n\nconst GENERATED_MODULE_PATTERN = /^@gtkx\\/(gi|jsx)\\/([a-z0-9]+)$/;\nconst DEFAULT_LIBRARY_NAMESPACES: Set<string> = new Set([\"adw\", \"gtk\"]);\n\nconst girSearchPaths = async (state: PluginState): Promise<string[]> => {\n if (state.girPath === null) {\n const { config } = await state.loadConfig.load(state.root);\n state.girPath = resolveGirPath(config.girPath);\n }\n\n return state.girPath;\n};\n\nconst getNamespace = (identifier: string): string => identifier.slice(0, identifier.indexOf(\"-\")).toLowerCase();\n\nconst findGirIdentifier = (girPath: string[], namespace: string): string | undefined =>\n discoverGirNamespaces(girPath).find((identifier) => getNamespace(identifier) === namespace);\n\nconst parseGeneratedModule = (source: string, importer: string | undefined): GeneratedModule | null => {\n const matched = GENERATED_MODULE_PATTERN.exec(source);\n const kind = matched?.[1];\n const namespace = matched?.[2];\n\n if (kind === undefined || namespace === undefined) {\n return null;\n }\n\n return { source, kind, namespace, importer: importer ?? \"the project's sources\" };\n};\n\nconst getStoreOptions = (root: string, kind: string): StoreOptions | null => {\n try {\n const store = resolveStore(root);\n\n return kind === \"gi\" ? store.gi : store.jsx;\n } catch {\n return null;\n }\n};\n\nconst hasStoreModule = (storeDir: string, exportKey: string): boolean => {\n const manifest = join(storeDir, \"package.json\");\n\n if (!existsSync(manifest)) {\n return false;\n }\n\n const { exports } = JSON.parse(readFileSync(manifest, \"utf8\")) as { exports?: Record<string, unknown> };\n\n return exports?.[exportKey] !== undefined;\n};\n\nconst unreachableStoreError = (generated: GeneratedModule, options: StoreOptions): Error => {\n const provided = `\"${generated.namespace}\"`;\n\n return new Error(\n `Cannot resolve \"${generated.source}\": the generated store in ${options.storeDir} does provide ` +\n `${provided}, but its link at ${options.linkDir} is not on the module resolution path of ` +\n `${generated.importer}. Codegen writes the store into the node_modules the installed @gtkx packages ` +\n \"resolve from; install them where the importing file reaches them, then run gtkx codegen again.\",\n );\n};\n\nconst undeclaredLibraryError = (source: string, namespace: string, girPath: string[]): Error => {\n const identifier = findGirIdentifier(girPath, namespace);\n\n if (identifier === undefined) {\n return new Error(\n `Cannot resolve \"${source}\": the binding store has no \"${namespace}\" module, and no ` +\n `GIR data for it was found in [${girPath.join(\", \")}]. If \"${namespace}\" is a library, install ` +\n \"its gobject-introspection data package. Adw-1 is bound by default and pulls in Gtk-4.0; add only other \" +\n \"GIR identifiers to `libraries` in gtkx.config.ts. Otherwise run gtkx codegen to regenerate the store.\",\n );\n }\n\n if (DEFAULT_LIBRARY_NAMESPACES.has(namespace)) {\n return new Error(\n `Cannot resolve \"${source}\": the \"${identifier}\" bindings have not been generated. ` +\n \"The Adwaita and GTK namespaces are generated implicitly; run gtkx dev or gtkx build again.\",\n );\n }\n\n return new Error(\n `Cannot resolve \"${source}\": the \"${identifier}\" bindings have not been generated. ` +\n `Add \"${identifier}\" to \\`libraries\\` in gtkx.config.ts, then run gtkx dev or gtkx build again.`,\n );\n};\n\nconst unresolvedModuleError = async (state: PluginState, generated: GeneratedModule): Promise<Error> => {\n const options = getStoreOptions(state.root, generated.kind);\n const exportKey = `./${generated.namespace}`;\n\n if (options !== null && hasStoreModule(options.storeDir, exportKey)) {\n return unreachableStoreError(generated, options);\n }\n\n return undeclaredLibraryError(generated.source, generated.namespace, await girSearchPaths(state));\n};\n\nfunction gtkxUndeclaredLibrary(loadConfig: ConfigLoader = createConfigLoader()): Plugin {\n const state: PluginState = {\n root: \"\",\n loadConfig,\n girPath: null,\n };\n\n return {\n name: \"gtkx:undeclared-library\",\n enforce: \"pre\",\n\n config(config: UserConfig) {\n state.root = config.root ?? process.cwd();\n },\n\n async resolveId(source, importer, options) {\n const generated = parseGeneratedModule(source, importer);\n\n if (generated === null) {\n return;\n }\n\n const resolved = await this.resolve(source, importer, { ...options, skipSelf: true });\n\n if (resolved !== null) {\n return;\n }\n\n throw await unresolvedModuleError(state, generated);\n },\n };\n}\n\nexport { gtkxUndeclaredLibrary };\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"vitest-plugin.d.ts","sourceRoot":"","sources":["../src/vitest-plugin.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,MAAM,CAAC;AACnC,OAAmB,EAAE,KAAK,aAAa,EAAE,MAAM,cAAc,CAAC;AAK9D;;;;;;GAMG;AACH,QAAA,MAAM,IAAI,GAAI,UAAS,aAAkB,KAAG,MAAM,EAKjD,CAAC;AAEF,eAAe,IAAI,CAAC"}
1
+ {"version":3,"file":"vitest-plugin.d.ts","sourceRoot":"","sources":["../src/vitest-plugin.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,MAAM,CAAC;AACnC,OAAmB,EAAE,KAAK,aAAa,EAAE,MAAM,cAAc,CAAC;AAM9D;;;;;;GAMG;AACH,QAAA,MAAM,IAAI,GAAI,UAAS,aAAkB,KAAG,MAAM,EAMjD,CAAC;AAEF,eAAe,IAAI,CAAC"}
@@ -1,5 +1,6 @@
1
1
  import gtkxVitest, {} from "@gtkx/vitest";
2
2
  import { gtkxEnsureStore } from "./vite-plugins/ensure-store.js";
3
+ import { gtkxFontWorkerEnv } from "./vite-plugins/font-worker-env.js";
3
4
  import { gtkxVitePlugins } from "./vite-plugins/index.js";
4
5
  import { gtkxSettingsWorkerEnv } from "./vite-plugins/settings-worker-env.js";
5
6
  /**
@@ -13,6 +14,7 @@ const gtkx = (options = {}) => [
13
14
  gtkxEnsureStore(options.configFile),
14
15
  ...gtkxVitePlugins({ configFile: options.configFile }),
15
16
  gtkxSettingsWorkerEnv(options.configFile),
17
+ gtkxFontWorkerEnv(options.configFile),
16
18
  gtkxVitest(options),
17
19
  ];
18
20
  export default gtkx;
@@ -1 +1 @@
1
- {"version":3,"file":"vitest-plugin.js","sourceRoot":"","sources":["../src/vitest-plugin.ts"],"names":[],"mappings":"AACA,OAAO,UAAU,EAAE,EAAsB,MAAM,cAAc,CAAC;AAC9D,OAAO,EAAE,eAAe,EAAE,MAAM,gCAAgC,CAAC;AACjE,OAAO,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAC;AAC1D,OAAO,EAAE,qBAAqB,EAAE,MAAM,uCAAuC,CAAC;AAE9E;;;;;;GAMG;AACH,MAAM,IAAI,GAAG,CAAC,UAAyB,EAAE,EAAY,EAAE,CAAC;IACpD,eAAe,CAAC,OAAO,CAAC,UAAU,CAAC;IACnC,GAAG,eAAe,CAAC,EAAE,UAAU,EAAE,OAAO,CAAC,UAAU,EAAE,CAAC;IACtD,qBAAqB,CAAC,OAAO,CAAC,UAAU,CAAC;IACzC,UAAU,CAAC,OAAO,CAAC;CACtB,CAAC;AAEF,eAAe,IAAI,CAAC","sourcesContent":["import type { Plugin } from \"vite\";\nimport gtkxVitest, { type PluginOptions } from \"@gtkx/vitest\";\nimport { gtkxEnsureStore } from \"./vite-plugins/ensure-store.js\";\nimport { gtkxVitePlugins } from \"./vite-plugins/index.js\";\nimport { gtkxSettingsWorkerEnv } from \"./vite-plugins/settings-worker-env.js\";\n\n/**\n * Vite plugin stack for testing a GTKX application: the generated bindings the tests import,\n * the plugins the app is built with, the project's compiled GSettings schemas exposed to every\n * test worker, and a headless display per worker.\n *\n * @returns The plugins to spread into a Vitest config.\n */\nconst gtkx = (options: PluginOptions = {}): Plugin[] => [\n gtkxEnsureStore(options.configFile),\n ...gtkxVitePlugins({ configFile: options.configFile }),\n gtkxSettingsWorkerEnv(options.configFile),\n gtkxVitest(options),\n];\n\nexport default gtkx;\n"]}
1
+ {"version":3,"file":"vitest-plugin.js","sourceRoot":"","sources":["../src/vitest-plugin.ts"],"names":[],"mappings":"AACA,OAAO,UAAU,EAAE,EAAsB,MAAM,cAAc,CAAC;AAC9D,OAAO,EAAE,eAAe,EAAE,MAAM,gCAAgC,CAAC;AACjE,OAAO,EAAE,iBAAiB,EAAE,MAAM,mCAAmC,CAAC;AACtE,OAAO,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAC;AAC1D,OAAO,EAAE,qBAAqB,EAAE,MAAM,uCAAuC,CAAC;AAE9E;;;;;;GAMG;AACH,MAAM,IAAI,GAAG,CAAC,UAAyB,EAAE,EAAY,EAAE,CAAC;IACpD,eAAe,CAAC,OAAO,CAAC,UAAU,CAAC;IACnC,GAAG,eAAe,CAAC,EAAE,UAAU,EAAE,OAAO,CAAC,UAAU,EAAE,CAAC;IACtD,qBAAqB,CAAC,OAAO,CAAC,UAAU,CAAC;IACzC,iBAAiB,CAAC,OAAO,CAAC,UAAU,CAAC;IACrC,UAAU,CAAC,OAAO,CAAC;CACtB,CAAC;AAEF,eAAe,IAAI,CAAC","sourcesContent":["import type { Plugin } from \"vite\";\nimport gtkxVitest, { type PluginOptions } from \"@gtkx/vitest\";\nimport { gtkxEnsureStore } from \"./vite-plugins/ensure-store.js\";\nimport { gtkxFontWorkerEnv } from \"./vite-plugins/font-worker-env.js\";\nimport { gtkxVitePlugins } from \"./vite-plugins/index.js\";\nimport { gtkxSettingsWorkerEnv } from \"./vite-plugins/settings-worker-env.js\";\n\n/**\n * Vite plugin stack for testing a GTKX application: the generated bindings the tests import,\n * the plugins the app is built with, the project's compiled GSettings schemas exposed to every\n * test worker, and a headless display per worker.\n *\n * @returns The plugins to spread into a Vitest config.\n */\nconst gtkx = (options: PluginOptions = {}): Plugin[] => [\n gtkxEnsureStore(options.configFile),\n ...gtkxVitePlugins({ configFile: options.configFile }),\n gtkxSettingsWorkerEnv(options.configFile),\n gtkxFontWorkerEnv(options.configFile),\n gtkxVitest(options),\n];\n\nexport default gtkx;\n"]}
package/env.d.ts CHANGED
@@ -14,6 +14,15 @@ declare module "*?icon" {
14
14
  export default iconName;
15
15
  }
16
16
 
17
+ declare module "*?font" {
18
+ /**
19
+ * Font family name of the bundled font. Importing the module bundles the font file with the application and
20
+ * puts it where fontconfig finds it, so the family is available to Pango without any runtime registration.
21
+ */
22
+ const fontFamily: string;
23
+ export default fontFamily;
24
+ }
25
+
17
26
  declare module "*.css?url" {
18
27
  /**
19
28
  * Absolute filesystem path of the source stylesheet under `gtkx dev` or the emitted stylesheet once built,
package/package.json CHANGED
@@ -1,11 +1,13 @@
1
1
  {
2
2
  "name": "@gtkx/cli",
3
- "version": "2.0.0-beta.5",
4
- "description": "GTK app toolchain for React: scaffold, dev server, build, docs.",
3
+ "version": "2.0.0-beta.7",
4
+ "description": "Adwaita-first GNOME app toolchain for React and TypeScript.",
5
5
  "keywords": [
6
6
  "gtkx",
7
7
  "gtk",
8
8
  "gtk4",
9
+ "adwaita",
10
+ "gnome",
9
11
  "react",
10
12
  "typescript",
11
13
  "native",
@@ -70,18 +72,18 @@
70
72
  "dependencies": {
71
73
  "@babel/core": "^8.0.1",
72
74
  "@babel/preset-typescript": "^8.0.1",
73
- "@gtkx/codegen": "2.0.0-beta.5",
74
- "@gtkx/config": "2.0.0-beta.5",
75
- "@gtkx/mcp": "2.0.0-beta.5",
76
- "@gtkx/native": "2.0.0-beta.5",
77
- "@gtkx/runtime": "2.0.0-beta.5",
78
- "@gtkx/utils": "2.0.0-beta.5",
79
- "@gtkx/vitest": "2.0.0-beta.5",
80
- "@swc/core": "^1.16.1",
75
+ "@gtkx/codegen": "2.0.0-beta.7",
76
+ "@gtkx/config": "2.0.0-beta.7",
77
+ "@gtkx/mcp": "2.0.0-beta.7",
78
+ "@gtkx/native": "2.0.0-beta.7",
79
+ "@gtkx/runtime": "2.0.0-beta.7",
80
+ "@gtkx/utils": "2.0.0-beta.7",
81
+ "@gtkx/vitest": "2.0.0-beta.7",
82
+ "@swc/core": "^1.16.2",
81
83
  "babel-plugin-react-compiler": "^1.0.0",
82
84
  "citty": "^0.2.2",
83
85
  "confbox": "^0.2.4",
84
- "create-gtkx": "2.0.0-beta.5",
86
+ "create-gtkx": "2.0.0-beta.7",
85
87
  "fast-xml-builder": "^1.3.1",
86
88
  "fast-xml-parser": "^5.11.1",
87
89
  "hosted-git-info": "^10.1.1",
@@ -92,7 +94,7 @@
92
94
  "yaml": "^2.9.0"
93
95
  },
94
96
  "devDependencies": {
95
- "@gtkx/testing": "2.0.0-beta.5",
97
+ "@gtkx/testing": "2.0.0-beta.7",
96
98
  "@types/babel__core": "^7.20.5",
97
99
  "@types/hosted-git-info": "^3.0.5",
98
100
  "@types/react-refresh": "^0.14.7",
package/src/builder.ts CHANGED
@@ -29,15 +29,10 @@ const buildDefaults: InlineConfig = {
29
29
  minify: true,
30
30
  cssMinify: false,
31
31
  },
32
- define: {
33
- "process.env.NODE_ENV": JSON.stringify(BUILD_MODE),
34
- },
35
32
  };
36
33
 
37
- const build = async (options: BuildOptions): Promise<string> => {
38
- const { entry, shouldPreserveI18nMetadata = true, vite: viteConfig } = options;
39
- const root = resolve(viteConfig?.root ?? process.cwd());
40
- const assetsDir = viteConfig?.build?.assetsDir ?? DEFAULT_ASSETS_DIR;
34
+ const forcedConfig = async (options: BuildOptions, root: string, assetsDir: string): Promise<InlineConfig> => {
35
+ const { entry, shouldPreserveI18nMetadata = true } = options;
41
36
  const buildManifest = createBuildManifestCollector();
42
37
  const loadedConfig = await loadConfig(root, { mode: BUILD_MODE, configFile: options.configFile });
43
38
  const buildConfigIdentity = {
@@ -45,7 +40,11 @@ const build = async (options: BuildOptions): Promise<string> => {
45
40
  configDigest: configDigest(loadedConfig.config),
46
41
  };
47
42
 
48
- const forced: InlineConfig = {
43
+ return {
44
+ mode: BUILD_MODE,
45
+ define: {
46
+ "process.env.NODE_ENV": JSON.stringify(BUILD_MODE),
47
+ },
49
48
  plugins: [
50
49
  ...gtkxVitePlugins({
51
50
  mode: BUILD_MODE,
@@ -71,11 +70,32 @@ const build = async (options: BuildOptions): Promise<string> => {
71
70
  },
72
71
  },
73
72
  };
73
+ };
74
74
 
75
+ const buildProduction = async (options: BuildOptions): Promise<string> => {
76
+ const viteConfig = options.vite;
77
+ const root = resolve(viteConfig?.root ?? process.cwd());
78
+ const assetsDir = viteConfig?.build?.assetsDir ?? DEFAULT_ASSETS_DIR;
79
+ const forced = await forcedConfig(options, root, assetsDir);
75
80
  const merged: InlineConfig = mergeConfig(mergeConfig(buildDefaults, viteConfig ?? {}), forced);
76
81
  await viteBuild({ ...merged, ssr: { ...merged.ssr, noExternal: true } });
77
82
 
78
83
  return join(merged.build?.outDir ?? DEFAULT_OUT_DIR, ENTRY_FILE_NAMES);
79
84
  };
80
85
 
86
+ const build = async (options: BuildOptions): Promise<string> => {
87
+ const callerNodeEnv = process.env.NODE_ENV;
88
+ process.env.NODE_ENV = BUILD_MODE;
89
+
90
+ try {
91
+ return await buildProduction(options);
92
+ } finally {
93
+ if (callerNodeEnv === undefined) {
94
+ delete process.env.NODE_ENV;
95
+ } else {
96
+ process.env.NODE_ENV = callerNodeEnv;
97
+ }
98
+ }
99
+ };
100
+
81
101
  export { build };
package/src/cli.ts CHANGED
@@ -18,7 +18,7 @@ const main = defineCommand({
18
18
  meta: {
19
19
  name: "gtkx",
20
20
  version,
21
- description: "CLI for GTKX: create and develop GTK4 React applications",
21
+ description: "CLI for GTKX: create and develop Adwaita-first GNOME applications",
22
22
  },
23
23
  subCommands: {
24
24
  dev: async () => {
@@ -1,5 +1,6 @@
1
1
  import type { Config } from "@gtkx/config";
2
2
  import { resolveGirPath, resolveLibraries } from "@gtkx/codegen";
3
+ import { resolveBoundLibraries } from "@gtkx/codegen/internal";
3
4
  import { existsSync, readFileSync } from "node:fs";
4
5
  import { basename, dirname, join } from "node:path";
5
6
  import { type CodegenStore, resolveCodegenStore } from "./store-resolver.js";
@@ -86,7 +87,10 @@ const hasStoreExports = (storeDir: string, required: string[], forbidden: string
86
87
  };
87
88
 
88
89
  const isGiStoreStale = (store: CodegenStore, libraries: string[]): boolean => {
89
- const required = [PACKAGE_EXPORT, ...libraries.map((library) => namespaceExport(library))];
90
+ const required = [
91
+ PACKAGE_EXPORT,
92
+ ...resolveBoundLibraries(libraries).map((library) => namespaceExport(library)),
93
+ ];
90
94
 
91
95
  return !hasStoreExports(store.giStoreDir, required);
92
96
  };
@@ -35,6 +35,7 @@ const ERROR_SEVERITY = "E";
35
35
  const WARNING_SEVERITY = "W";
36
36
  const INFO_SEVERITY = "I";
37
37
  const FATAL_WARNING_RULES: Set<string> = new Set(["unknown-tag"]);
38
+ const DESKTOP_ERROR = /(?:^|:\s)error:/iu;
38
39
 
39
40
  const FATAL_RULE_NOTES: Record<string, (detail: string) => string> = {
40
41
  "unknown-tag": (element) =>
@@ -146,9 +147,15 @@ const validateDesktopEntry = (path: string): void => {
146
147
  subject: "The desktop entry",
147
148
  });
148
149
 
149
- if (status !== 0 || output.length > 0) {
150
+ const diagnostics = output.split("\n").filter((line) => line.length > 0);
151
+
152
+ if (status !== 0 || diagnostics.some((line) => DESKTOP_ERROR.test(line))) {
150
153
  throw invalid("The desktop entry", output, [], []);
151
154
  }
155
+
156
+ for (const diagnostic of diagnostics) {
157
+ warn(diagnostic);
158
+ }
152
159
  };
153
160
 
154
161
  const validateMetainfo = (path: string, areWarningsFatal: boolean): void => {
@@ -5,6 +5,7 @@ import {
5
5
  readGeneratedLibraries,
6
6
  resolveStore,
7
7
  } from "@gtkx/codegen";
8
+ import { resolveBoundLibraries } from "@gtkx/codegen/internal";
8
9
 
9
10
  type ResolvedLibraries = {
10
11
  libraries: string[];
@@ -21,7 +22,7 @@ const generatedLibraries = (root: string): GeneratedLibraries | null => {
21
22
 
22
23
  const resolveLibraries = (root: string, config: Config): ResolvedLibraries => {
23
24
  const generated = generatedLibraries(root);
24
- const libraries = generated?.libraries ?? expandLibraries(config.libraries);
25
+ const libraries = resolveBoundLibraries(generated?.libraries ?? expandLibraries(config.libraries));
25
26
  const deploy = config.deploy ?? {};
26
27
 
27
28
  return {
@@ -3,6 +3,7 @@ import { existsSync, readFileSync, realpathSync } from "node:fs";
3
3
  import { posix, relative, resolve } from "node:path";
4
4
  import type { DeployPayload, DeploySettings } from "../types.js";
5
5
  import { LOCALE_DIRNAME } from "../../i18n/catalogs.js";
6
+ import { FONTS_DIR } from "../../internal/font-path.js";
6
7
  import { listFilesRecursive } from "../../internal/list-files.js";
7
8
  import { BUNDLE_FILENAME } from "../../vite-plugins/esm-extension.js";
8
9
  import { renderDbusService } from "../freedesktop/dbus-service.js";
@@ -68,6 +69,7 @@ const runtimeInstallCommands = (settings: DeploySettings, nodeExtensionPath: str
68
69
  "test ! -f dist/gschemas.compiled || " +
69
70
  installCommand("dist/gschemas.compiled", `${lib}/gschemas.compiled`, "m644"),
70
71
  `test ! -d dist/assets || cp -a dist/assets ${lib}/assets`,
72
+ `test ! -d dist/${FONTS_DIR} || cp -a dist/${FONTS_DIR} ${lib}/${FONTS_DIR}`,
71
73
  `test ! -d dist/${LOCALE_DIRNAME} || { mkdir -p ${locale} && cp -a dist/${LOCALE_DIRNAME}/. ${locale}/; }`,
72
74
  installCommand(LAUNCHER_FILENAME, `${DESTINATION}/bin/${settings.binaryName}`, "m755"),
73
75
  ];
@@ -0,0 +1,16 @@
1
+ import { stageProjectFonts } from "../internal/font-staging.js";
2
+ import { prependXdgDataDir } from "../internal/xdg-data-dirs.js";
3
+
4
+ const prepareDevFontDir = (root: string): string | null => {
5
+ const shareDir = stageProjectFonts(root);
6
+
7
+ if (shareDir === null) {
8
+ return null;
9
+ }
10
+
11
+ process.env.XDG_DATA_DIRS = prependXdgDataDir(shareDir, process.env.XDG_DATA_DIRS);
12
+
13
+ return shareDir;
14
+ };
15
+
16
+ export { prepareDevFontDir };
@@ -2,6 +2,7 @@ import { loadConfig } from "@gtkx/config";
2
2
  import { error } from "@gtkx/utils";
3
3
  import { resolve } from "node:path";
4
4
  import { DEV_CONFIG_ENV, DEV_ENTRY_ENV } from "./entry-env.js";
5
+ import { prepareDevFontDir } from "./font-dir.js";
5
6
  import { prepareDevIconDir } from "./icon-dir.js";
6
7
  import { prepareDevLocaleDir } from "./locale-dir.js";
7
8
  import { createDevRunner } from "./runner.js";
@@ -33,6 +34,7 @@ const main = async (): Promise<void> => {
33
34
  prepareDevLocaleDir(root, config.applicationId);
34
35
  prepareDevSchemaDir(root);
35
36
  prepareDevIconDir(root, config.applicationId, config.applicationIcon);
37
+ prepareDevFontDir(root);
36
38
  const entryPath = resolve(cwd, entryArg);
37
39
  const { defaultDevRunnerDeps } = await import("./runner-deps.js");
38
40
  const runner = createDevRunner(defaultDevRunnerDeps(configFile));
@@ -18,9 +18,13 @@ const TOP_LEVEL_HEADING = /^# /m;
18
18
  const rulesBody = (heading: string): string[] => [
19
19
  `${heading} GTKX`,
20
20
  "",
21
- "This is not the GTK you have seen before. Most GTK code in your training data is C, PyGObject, Vala or " +
22
- "GJS, and almost none of it is valid here. Check the rules below against what you are about to write.",
21
+ "GTKX applications are Adwaita-first, with GTK4 underneath. Most GNOME UI code in your training data is C, " +
22
+ "PyGObject, Vala or GJS, and almost none of it is valid here. Check the rules below against what you are " +
23
+ "about to write.",
23
24
  "",
25
+ "- Start application shells with `AdwApplication` and `AdwApplicationWindow`. Freeform windows normally use " +
26
+ "`AdwToolbarView` and `AdwHeaderBar`; navigation containers own their Adwaita chrome. Prefer Adwaita for " +
27
+ "structure, navigation, dialogs, rows, and adaptive patterns; use GTK4 for lower-level primitives.",
24
28
  "- Children are JSX, never `.append()`, `pack_start()`, `set_child()` or `add()`.",
25
29
  '- Signals are props: `onClicked`, not `widget.connect("clicked", ...)`.',
26
30
  "- Props are camelCase: `marginTop`, not `margin-top` or `margin_top`.",
@@ -37,6 +41,7 @@ const rulesBody = (heading: string): string[] => [
37
41
  "| --- | --- |",
38
42
  "| `gtkx dev` | Run the app with fast refresh |",
39
43
  "| `gtkx codegen` | Regenerate bindings and this reference |",
44
+ "| `gtkx cleanup` | Remove stale headless runtime directories |",
40
45
  "| `tsc --noEmit` | Typecheck |",
41
46
  "| `vitest run` | Run the tests |",
42
47
  "",
@@ -1,13 +1,34 @@
1
1
  import type { Rollup } from "vite";
2
+ import { posix } from "node:path";
2
3
 
3
- const prependBanner = (options: Rollup.OutputOptions, banner: string): Rollup.OutputOptions => {
4
+ type Banner = string | Rollup.AddonFunction;
5
+
6
+ const renderBanner = async (banner: Banner, chunk: Rollup.RenderedChunk): Promise<string> =>
7
+ typeof banner === "function" ? banner(chunk) : banner;
8
+
9
+ const prependBanner = (options: Rollup.OutputOptions, banner: Banner): Rollup.OutputOptions => {
4
10
  const existing = options.banner;
5
11
 
6
- if (typeof existing === "function") {
7
- return { ...options, banner: async (chunk) => `${banner}\n${await existing(chunk)}` };
8
- }
12
+ return {
13
+ ...options,
14
+ banner: async (chunk) => {
15
+ const prefix = await renderBanner(banner, chunk);
16
+ const suffix = existing === undefined ? "" : await renderBanner(existing, chunk);
17
+
18
+ if (prefix.length === 0) {
19
+ return suffix;
20
+ }
21
+
22
+ return suffix.length === 0 ? prefix : `${prefix}\n${suffix}`;
23
+ },
24
+ };
25
+ };
26
+
27
+ const outputRootUrlExpression = (chunk: Rollup.RenderedChunk): string => {
28
+ const relativeRoot = posix.relative(posix.dirname(chunk.fileName), ".");
29
+ const specifier = relativeRoot.length === 0 ? "./" : `${relativeRoot}/`;
9
30
 
10
- return { ...options, banner: existing ? `${banner}\n${existing}` : banner };
31
+ return `decodeURIComponent(new URL(${JSON.stringify(specifier)}, import.meta.url).pathname)`;
11
32
  };
12
33
 
13
- export { prependBanner };
34
+ export { outputRootUrlExpression, prependBanner };
@@ -0,0 +1,15 @@
1
+ import { createHash } from "node:crypto";
2
+ import { basename, extname } from "node:path";
3
+
4
+ const FONTS_DIR = "fonts";
5
+ const DIGEST_LENGTH = 8;
6
+
7
+ const fontFileName = (sourcePath: string, content: Buffer): string => {
8
+ const extension = extname(sourcePath).toLowerCase();
9
+ const stem = basename(sourcePath, extname(sourcePath));
10
+ const digest = createHash("sha1").update(content).digest("hex").slice(0, DIGEST_LENGTH);
11
+
12
+ return `${stem}-${digest}${extension}`;
13
+ };
14
+
15
+ export { fontFileName, FONTS_DIR };
@@ -0,0 +1,57 @@
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";
5
+ import { parseFontSpecifier } from "../vite-plugins/asset-specifier.js";
6
+ import { fontFileName, FONTS_DIR } from "./font-path.js";
7
+ import { discoverSourceImports, sourceDirFor, type SourceImport } from "./source-imports.js";
8
+ import { removeTempDir } from "./staging-dir.js";
9
+
10
+ const FONT_STAGING_PREFIX = "gtkx-fonts-";
11
+
12
+ const isRelativeImport = (source: string): boolean => source.startsWith("./") || source.startsWith("../");
13
+
14
+ const fontFileFor = ({ importer, source }: SourceImport): string | null => {
15
+ const specifier = parseFontSpecifier(source);
16
+
17
+ return specifier === null || !isRelativeImport(source)
18
+ ? null
19
+ : resolve(dirname(importer), specifier.assetSource);
20
+ };
21
+
22
+ const findImportedFontFiles = (imports: SourceImport[]): string[] => {
23
+ const files = imports
24
+ .map((entry) => fontFileFor(entry))
25
+ .filter((path): path is string => path !== null);
26
+
27
+ return sortStrings(new Set(files));
28
+ };
29
+
30
+ const stageFont = (fontsDir: string, sourcePath: string): void => {
31
+ const fileName = fontFileName(sourcePath, readFileSync(sourcePath));
32
+
33
+ symlinkSync(sourcePath, join(fontsDir, fileName), "file");
34
+ };
35
+
36
+ const stageProjectFonts = (root: string): string | null => {
37
+ const fontFiles = findImportedFontFiles(discoverSourceImports(sourceDirFor(root)));
38
+
39
+ if (fontFiles.length === 0) {
40
+ return null;
41
+ }
42
+
43
+ const shareDir = mkdtempSync(join(tmpdir(), FONT_STAGING_PREFIX));
44
+ mkdirSync(join(shareDir, FONTS_DIR));
45
+
46
+ for (const sourcePath of fontFiles) {
47
+ stageFont(join(shareDir, FONTS_DIR), sourcePath);
48
+ }
49
+
50
+ process.once("exit", () => {
51
+ removeTempDir(shareDir);
52
+ });
53
+
54
+ return shareDir;
55
+ };
56
+
57
+ export { stageProjectFonts };
@@ -1,6 +1,6 @@
1
1
  import type { ESTree, ParseResult, ParserOptions } from "vite";
2
2
  import { sortStringsBy } from "@gtkx/utils";
3
- import { globSync, readFileSync } from "node:fs";
3
+ import { existsSync, globSync, readFileSync } from "node:fs";
4
4
  import { extname, join } from "node:path";
5
5
  import { parseSync, Visitor } from "vite";
6
6
 
@@ -29,6 +29,14 @@ const sourceLanguage = (path: string): SourceLanguage | undefined => {
29
29
  return SOURCE_LANGUAGES.get(extname(path).toLowerCase());
30
30
  };
31
31
 
32
+ const SOURCE_DIR = "src";
33
+
34
+ const sourceDirFor = (root: string): string => {
35
+ const sourceDir = join(root, SOURCE_DIR);
36
+
37
+ return existsSync(sourceDir) ? sourceDir : root;
38
+ };
39
+
32
40
  const discoverSourceFiles = (dir: string): string[] =>
33
41
  sortStringsBy(
34
42
  globSync("**/{*,.*}", {
@@ -132,4 +140,11 @@ const discoverSourceImports = (dir: string): SourceImport[] => {
132
140
  return sortStringsBy(imports, importKey);
133
141
  };
134
142
 
135
- export { discoverSourceFiles, discoverSourceImports, parseRuntimeImportsIn, type SourceImport, sourceLanguage };
143
+ export {
144
+ discoverSourceFiles,
145
+ discoverSourceImports,
146
+ parseRuntimeImportsIn,
147
+ sourceDirFor,
148
+ sourceLanguage,
149
+ type SourceImport,
150
+ };