@gtkx/config 1.4.0 → 1.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -98,7 +98,7 @@ GTK4 is mature, and GtkBuilder XML can lay out a static interface, but nothing r
98
98
  - a React reconciler that exposes every GObject as a JSX element,
99
99
  - a CLI for scaffolding, development, and production builds,
100
100
  - a dev server with Fast Refresh that patches your running UI in place,
101
- - CSS-in-JS styling, React Spring animations, React Navigation stack, tab, drawer, and split view navigators, and high-level list, grid, and dialog components,
101
+ - CSS-in-JS styling, React Hook Form-powered Adwaita controls, gettext-backed react-i18next localization, React Spring animations, React Navigation stack, tab, drawer, and split view navigators, and high-level list, grid, and dialog components,
102
102
  - a Testing Library-style API for querying and driving your widgets in tests,
103
103
  - and a Model Context Protocol (MCP) server that exposes your live app to AI agents.
104
104
 
package/dist/config.d.ts CHANGED
@@ -22,11 +22,25 @@ type ResolvedReactCompilerOptions = ReactCompilerOptions & {
22
22
  /**
23
23
  * User-facing configuration for a GTKX project, as authored in `gtkx.config.ts`: the GIR libraries
24
24
  * to bind and where to find them, the GApplication id, per-element configuration, the React
25
- * Compiler, codegen, and user event signal settings, and the `future` block opting into behavior
26
- * that becomes the default in the next major version.
25
+ * Compiler, codegen, and user event signal settings, the `agents` and `mcp` blocks controlling what
26
+ * coding agents are given, the `future` block opting into behavior that becomes the default in the
27
+ * next major version, and the `deprecations` block silencing the warnings about flags left unset.
27
28
  */
28
29
  type Config = z.infer<typeof configSchema>;
29
30
  type ModuleExport = z.infer<typeof moduleExportSchema>;
31
+ type McpSettings = {
32
+ tools: string[];
33
+ isReadOnly: boolean;
34
+ };
35
+ type ResolvedFuture = {
36
+ isByteArrayTyped: boolean;
37
+ isValueUnwrapped: boolean;
38
+ isFinishTrimmed: boolean;
39
+ isInoutInPlace: boolean;
40
+ isResourceImported: boolean;
41
+ isAdwaitaDefault: boolean;
42
+ isTreeShaken: boolean;
43
+ };
30
44
  /** Configuration reduced to the values the app runtime and the build need, with paths already resolved. */
31
45
  type ResolvedConfig = {
32
46
  /** The GApplication identifier the app registers under. */
@@ -60,6 +74,8 @@ declare const configSchema: z.ZodObject<{
60
74
  v2FinishResults: z.ZodOptional<z.ZodBoolean>;
61
75
  v2InoutReturns: z.ZodOptional<z.ZodBoolean>;
62
76
  v2ResourceImports: z.ZodOptional<z.ZodBoolean>;
77
+ v2DefaultLibraries: z.ZodOptional<z.ZodBoolean>;
78
+ v2TreeShaking: z.ZodOptional<z.ZodBoolean>;
63
79
  }, z.core.$strip>>;
64
80
  libraries: z.ZodOptional<z.ZodCustom<string[] | "*", string[] | "*">>;
65
81
  girPath: z.ZodOptional<z.ZodArray<z.ZodString>>;
@@ -320,6 +336,25 @@ declare const configSchema: z.ZodObject<{
320
336
  prefixes: z.ZodOptional<z.ZodArray<z.ZodString>>;
321
337
  }, z.core.$strict>>;
322
338
  }, z.core.$strict>>;
339
+ agents: z.ZodOptional<z.ZodObject<{
340
+ rules: z.ZodOptional<z.ZodBoolean>;
341
+ reference: z.ZodOptional<z.ZodBoolean>;
342
+ }, z.core.$strip>>;
343
+ mcp: z.ZodOptional<z.ZodObject<{
344
+ tools: z.ZodOptional<z.ZodArray<z.ZodString>>;
345
+ readOnly: z.ZodOptional<z.ZodBoolean>;
346
+ }, z.core.$strip>>;
347
+ deprecations: z.ZodOptional<z.ZodObject<{
348
+ silence: z.ZodOptional<z.ZodArray<z.ZodEnum<{
349
+ "gtkx-v2-byte-arrays": "gtkx-v2-byte-arrays";
350
+ "gtkx-v2-value-returns": "gtkx-v2-value-returns";
351
+ "gtkx-v2-finish-results": "gtkx-v2-finish-results";
352
+ "gtkx-v2-inout-returns": "gtkx-v2-inout-returns";
353
+ "gtkx-v2-resource-imports": "gtkx-v2-resource-imports";
354
+ "gtkx-v2-default-libraries": "gtkx-v2-default-libraries";
355
+ "gtkx-v2-tree-shaking": "gtkx-v2-tree-shaking";
356
+ }>>>;
357
+ }, z.core.$strip>>;
323
358
  }, z.core.$strip>;
324
359
  /**
325
360
  * Returns the given configuration unchanged, typed as {@link Config}, so `gtkx.config.ts` gets
@@ -329,7 +364,7 @@ declare const defineConfig: DefineConfig<Config>;
329
364
  declare const isValidApplicationId: (applicationId: string) => boolean;
330
365
  declare const validateConfig: (config: Config) => void;
331
366
  /**
332
- * Deep-merges two configurations. `override` wins over `base` on conflicting scalar and object keys, while
367
+ * Deep-merges a configuration over a base. `override` wins over `base` on conflicting scalar and object keys, while
333
368
  * arrays are concatenated with the `override` entries first.
334
369
  */
335
370
  declare const mergeConfig: (base: Config, override: Config) => Config;
@@ -337,6 +372,11 @@ declare const resolveLazyElements: (elements: Config["elements"]) => string[];
337
372
  declare const resolveElementComponents: (elements: Config["elements"]) => Record<string, ModuleExport>;
338
373
  declare const resolveElementProps: (elements: Config["elements"]) => Record<string, ModuleExport>;
339
374
  declare const resolveOmittedProps: (elements: Config["elements"]) => Record<string, string[]>;
375
+ declare const isAgentRulesEnabled: (config: Config) => boolean;
376
+ declare const isAgentReferenceEnabled: (config: Config) => boolean;
377
+ declare const resolveMcpSettings: (config: Config) => McpSettings;
378
+ declare const resolveFuture: (future: Config["future"]) => ResolvedFuture;
379
+ declare const unknownFutureKeys: (future: Config["future"]) => string[];
340
380
  declare const resolveConfig: (config: Config, root?: string) => ResolvedConfig;
341
- export { APPLICATION_ID_MAX_LENGTH, defineConfig, isValidApplicationId, validateConfig, mergeConfig, resolveLazyElements, resolveElementComponents, resolveElementProps, resolveOmittedProps, resolveConfig, type ResolvedReactCompilerOptions, type Config, type ResolvedConfig, };
381
+ export { APPLICATION_ID_MAX_LENGTH, defineConfig, isAgentReferenceEnabled, isAgentRulesEnabled, isValidApplicationId, validateConfig, mergeConfig, resolveLazyElements, resolveElementComponents, resolveElementProps, resolveMcpSettings, resolveOmittedProps, resolveConfig, resolveFuture, unknownFutureKeys, type McpSettings, type ResolvedReactCompilerOptions, type Config, type ResolvedConfig, type ResolvedFuture, };
342
382
  //# sourceMappingURL=config.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"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"}
package/dist/config.js CHANGED
@@ -4,6 +4,7 @@ import { resolve } from "node:path";
4
4
  import { z } from "zod";
5
5
  import { configError, isRecord, rawIssue } from "./config-error.js";
6
6
  import { deploySchema } from "./deploy.js";
7
+ import { DEPRECATION_IDS } from "./deprecations.js";
7
8
  import { isGirLibrary, text } from "./schema-text.js";
8
9
  import { resolveUserEventSignals } from "./user-event-signals.js";
9
10
  const LIBRARIES_WILDCARD = "*";
@@ -80,12 +81,35 @@ const elementsSchema = z.object({
80
81
  .optional(),
81
82
  config: z.record(z.string(), elementConfigSchema).optional(),
82
83
  });
84
+ const agentsSchema = z.object({
85
+ rules: z.boolean({ error: "must be a boolean" }).optional(),
86
+ reference: z.boolean({ error: "must be a boolean" }).optional(),
87
+ });
88
+ const mcpSchema = z.object({
89
+ tools: z
90
+ .array(z.string({ error: "must be a tool name pattern" }).min(1, { error: "must be a tool name pattern" }), {
91
+ error: "must be an array of tool name patterns",
92
+ })
93
+ .optional(),
94
+ readOnly: z.boolean({ error: "must be a boolean" }).optional(),
95
+ });
83
96
  const futureSchema = z.object({
84
97
  v2ByteArrays: z.boolean({ error: "must be a boolean" }).optional(),
85
98
  v2ValueReturns: z.boolean({ error: "must be a boolean" }).optional(),
86
99
  v2FinishResults: z.boolean({ error: "must be a boolean" }).optional(),
87
100
  v2InoutReturns: z.boolean({ error: "must be a boolean" }).optional(),
88
101
  v2ResourceImports: z.boolean({ error: "must be a boolean" }).optional(),
102
+ v2DefaultLibraries: z.boolean({ error: "must be a boolean" }).optional(),
103
+ v2TreeShaking: z.boolean({ error: "must be a boolean" }).optional(),
104
+ });
105
+ const FUTURE_KEYS = new Set(Object.keys(futureSchema.shape));
106
+ const DEPRECATION_ID_ERROR = `must be one of ${DEPRECATION_IDS.join(", ")}`;
107
+ const deprecationsSchema = z.object({
108
+ silence: z
109
+ .array(z.enum(DEPRECATION_IDS, { error: DEPRECATION_ID_ERROR }), {
110
+ error: "must be an array of deprecation ids",
111
+ })
112
+ .optional(),
89
113
  });
90
114
  /** Schema every `gtkx.config.ts` is validated against, and the source of the {@link Config} type. */
91
115
  const configSchema = z.object({
@@ -99,6 +123,9 @@ const configSchema = z.object({
99
123
  elements: elementsSchema.optional(),
100
124
  applicationIcon: text("must be a path to an icon theme directory or a single icon file").optional(),
101
125
  deploy: deploySchema.optional(),
126
+ agents: agentsSchema.optional(),
127
+ mcp: mcpSchema.optional(),
128
+ deprecations: deprecationsSchema.optional(),
102
129
  });
103
130
  /**
104
131
  * Returns the given configuration unchanged, typed as {@link Config}, so `gtkx.config.ts` gets
@@ -139,7 +166,7 @@ const validateConfig = (config) => {
139
166
  }
140
167
  };
141
168
  /**
142
- * Deep-merges two configurations. `override` wins over `base` on conflicting scalar and object keys, while
169
+ * Deep-merges a configuration over a base. `override` wins over `base` on conflicting scalar and object keys, while
143
170
  * arrays are concatenated with the `override` entries first.
144
171
  */
145
172
  const mergeConfig = (base, override) => defu(override, base);
@@ -159,6 +186,22 @@ const elementEntryValues = (elements, pick) => Object.fromEntries(Object.entries
159
186
  const resolveElementComponents = (elements) => elementEntryValues(elements, (entry) => entry.component);
160
187
  const resolveElementProps = (elements) => elementEntryValues(elements, (entry) => entry.props);
161
188
  const resolveOmittedProps = (elements) => elementEntryValues(elements, (entry) => entry.omittedProps);
189
+ const isAgentRulesEnabled = (config) => config.agents?.rules !== false;
190
+ const isAgentReferenceEnabled = (config) => config.agents?.reference !== false;
191
+ const resolveMcpSettings = (config) => ({
192
+ tools: config.mcp?.tools ?? [],
193
+ isReadOnly: config.mcp?.readOnly === true,
194
+ });
195
+ const resolveFuture = (future) => ({
196
+ isByteArrayTyped: future?.v2ByteArrays === true,
197
+ isValueUnwrapped: future?.v2ValueReturns === true,
198
+ isFinishTrimmed: future?.v2FinishResults === true,
199
+ isInoutInPlace: future?.v2InoutReturns === true,
200
+ isResourceImported: future?.v2ResourceImports === true,
201
+ isAdwaitaDefault: future?.v2DefaultLibraries === true,
202
+ isTreeShaken: future?.v2TreeShaking === true,
203
+ });
204
+ const unknownFutureKeys = (future) => Object.keys(future ?? {}).filter((key) => !FUTURE_KEYS.has(key));
162
205
  const resolveConfig = (config, root) => ({
163
206
  applicationId: config.applicationId,
164
207
  reactCompiler: resolveReactCompilerOptions(config.reactCompiler),
@@ -166,5 +209,5 @@ const resolveConfig = (config, root) => ({
166
209
  elements: resolveElementsModule(config.elements?.behaviors, root),
167
210
  lazyElements: resolveLazyElements(config.elements),
168
211
  });
169
- export { APPLICATION_ID_MAX_LENGTH, defineConfig, isValidApplicationId, validateConfig, mergeConfig, resolveLazyElements, resolveElementComponents, resolveElementProps, resolveOmittedProps, resolveConfig, };
212
+ export { APPLICATION_ID_MAX_LENGTH, defineConfig, isAgentReferenceEnabled, isAgentRulesEnabled, isValidApplicationId, validateConfig, mergeConfig, resolveLazyElements, resolveElementComponents, resolveElementProps, resolveMcpSettings, resolveOmittedProps, resolveConfig, resolveFuture, unknownFutureKeys, };
170
213
  //# sourceMappingURL=config.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"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","sourcesContent":["import { createDefineConfig, type DefineConfig } from \"c12\";\nimport { defu } from \"defu\";\nimport { resolve } from \"node:path\";\nimport { z } from \"zod\";\nimport { configError, isRecord, rawIssue } from \"./config-error.ts\";\nimport { deploySchema } from \"./deploy.ts\";\nimport { isGirLibrary, text } from \"./schema-text.ts\";\nimport { resolveUserEventSignals } from \"./user-event-signals.ts\";\n\n/** Accepted `reactCompiler.compilationMode` values, choosing which functions the compiler processes. */\ntype ReactCompilerCompilationMode = (typeof COMPILATION_MODES)[number];\n/** Accepted `reactCompiler.panicThreshold` values, choosing which compiler diagnostics fail the build. */\ntype ReactCompilerPanicThreshold = (typeof PANIC_THRESHOLDS)[number];\n\n/** Object form of the `reactCompiler` config key, forwarded as-is to `babel-plugin-react-compiler`. */\ntype ReactCompilerOptions = {\n /** Which functions the compiler processes; left to the compiler's own default when omitted. */\n compilationMode?: ReactCompilerCompilationMode;\n /** Which compiler diagnostics fail the build; left to the compiler's own default when omitted. */\n panicThreshold?: ReactCompilerPanicThreshold;\n};\n\n/**\n * The React Compiler options the build hands to `babel-plugin-react-compiler`, with the React version\n * GTKX targets filled in.\n */\ntype ResolvedReactCompilerOptions = ReactCompilerOptions & {\n /** React major version the compiler emits for. */\n target: \"19\";\n};\n\n/**\n * User-facing configuration for a GTKX project, as authored in `gtkx.config.ts`: the GIR libraries\n * to bind and where to find them, the GApplication id, per-element configuration, the React\n * Compiler, codegen, and user event signal settings, and the `future` block opting into behavior\n * that becomes the default in the next major version.\n */\ntype Config = z.infer<typeof configSchema>;\ntype ModuleExport = z.infer<typeof moduleExportSchema>;\ntype ElementConfigEntry = z.infer<typeof elementConfigSchema>;\n\n/** Configuration reduced to the values the app runtime and the build need, with paths already resolved. */\ntype ResolvedConfig = {\n /** The GApplication identifier the app registers under. */\n applicationId: string;\n /** React Compiler options for the build, or `null` when the compiler is disabled. */\n reactCompiler: ResolvedReactCompilerOptions | null;\n /**\n * Signal names, keyed by GLib type name, that stay suppressed while a React commit writes to a widget.\n * `notify` stays suppressed only for the property being written.\n */\n userEventSignals: Record<string, string[]>;\n /** Path of the module exporting per-element configs, or `null` when none is configured. */\n elements: string | null;\n /** GLib type names of the elements marked `isLazy`, whose GObject their parent container creates. */\n lazyElements: string[];\n};\n\nconst LIBRARIES_WILDCARD = \"*\";\nconst APPLICATION_ID_PATTERN = /^[A-Za-z_][A-Za-z0-9_-]*(\\.[A-Za-z_][A-Za-z0-9_-]*)+$/;\nconst APPLICATION_ID_MAX_LENGTH = 255;\n/** Compilation modes `babel-plugin-react-compiler` accepts. */\nconst COMPILATION_MODES = [\"infer\", \"syntax\", \"annotation\", \"all\"] as const;\n/** Panic thresholds `babel-plugin-react-compiler` accepts. */\nconst PANIC_THRESHOLDS = [\"none\", \"critical_errors\", \"all_errors\"] as const;\nconst REACT_COMPILER_TARGET = \"19\";\nconst COMPILATION_MODE_SET: Set<string> = new Set(COMPILATION_MODES);\nconst PANIC_THRESHOLD_SET: Set<string> = new Set(PANIC_THRESHOLDS);\n\nconst librariesSchema = z.custom<typeof LIBRARIES_WILDCARD | string[]>().check((ctx) => {\n const value = ctx.value;\n\n if (value === LIBRARIES_WILDCARD) {\n return;\n }\n\n if (!Array.isArray(value) || value.length === 0) {\n ctx.issues.push(rawIssue(value, [], `must be \"${LIBRARIES_WILDCARD}\", a non-empty string array, or omitted`));\n\n return;\n }\n\n for (const [index, entry] of value.entries()) {\n ctx.issues.push(...libraryEntryIssues(value, index, entry));\n }\n});\n\nconst applicationIdSchema = z.custom<string>().check((ctx) => {\n const value = ctx.value;\n\n if (typeof value !== \"string\" || !isValidApplicationId(value)) {\n ctx.issues.push(\n rawIssue(\n value,\n [],\n `invalid \\`applicationId\\` \"${value}\", must satisfy g_application_id_is_valid ` +\n '(e.g. \"org.example.MyApp\")',\n true,\n ),\n );\n }\n});\n\nconst reactCompilerSchema = z.custom<boolean | ReactCompilerOptions>().check((ctx) => {\n const value = ctx.value;\n\n if (typeof value === \"boolean\") {\n return;\n }\n\n if (!isRecord(value)) {\n ctx.issues.push(rawIssue(value, [], \"must be a boolean or an options object\"));\n\n return;\n }\n\n const compilationMode = value.compilationMode;\n\n if (!isValidReactCompilerOption(compilationMode, COMPILATION_MODE_SET)) {\n ctx.issues.push(\n rawIssue(\n value,\n [],\n `invalid \\`reactCompiler.compilationMode\\` \"${String(compilationMode)}\", ` +\n `must be one of ${COMPILATION_MODES.join(\", \")}`,\n true,\n ),\n );\n }\n\n const panicThreshold = value.panicThreshold;\n\n if (!isValidReactCompilerOption(panicThreshold, PANIC_THRESHOLD_SET)) {\n ctx.issues.push(\n rawIssue(\n value,\n [],\n `invalid \\`reactCompiler.panicThreshold\\` \"${String(panicThreshold)}\", ` +\n `must be one of ${PANIC_THRESHOLDS.join(\", \")}`,\n true,\n ),\n );\n }\n});\n\nconst userEventSignalsSchema = z.record(\n z.string(),\n z.array(\n z.string({ error: \"must be a non-empty signal name\" }).min(1, { error: \"must be a non-empty signal name\" }),\n {\n error: \"must be an array of signal names\",\n },\n ),\n { error: \"must be a record of GLib type names to signal name arrays\" },\n);\n\nconst moduleExportSchema = z.object(\n {\n module: z.string({ error: \"must be a module specifier\" }).min(1, { error: \"must be a module specifier\" }),\n export: z.string({ error: \"must be an export name\" }).min(1, { error: \"must be an export name\" }),\n },\n { error: \"must be a { module, export } object\" },\n);\n\nconst elementConfigSchema = z.object({\n component: moduleExportSchema.optional(),\n props: moduleExportSchema.optional(),\n isLazy: z.boolean({ error: \"must be a boolean\" }).optional(),\n omittedProps: z\n .array(\n z.string({ error: \"must be a non-empty property name\" }).min(1, {\n error: \"must be a non-empty property name\",\n }),\n { error: \"must be an array of property names\" },\n )\n .optional(),\n});\n\nconst elementsSchema = z.object({\n behaviors: z\n .string({ error: \"must be a path to a module exporting element behaviors\" })\n .min(1, { error: \"must be a path to a module exporting element behaviors\" })\n .optional(),\n config: z.record(z.string(), elementConfigSchema).optional(),\n});\n\nconst futureSchema = z.object({\n v2ByteArrays: z.boolean({ error: \"must be a boolean\" }).optional(),\n v2ValueReturns: z.boolean({ error: \"must be a boolean\" }).optional(),\n v2FinishResults: z.boolean({ error: \"must be a boolean\" }).optional(),\n v2InoutReturns: z.boolean({ error: \"must be a boolean\" }).optional(),\n v2ResourceImports: z.boolean({ error: \"must be a boolean\" }).optional(),\n});\n\n/** Schema every `gtkx.config.ts` is validated against, and the source of the {@link Config} type. */\nconst configSchema = z.object({\n future: futureSchema.optional(),\n libraries: librariesSchema.optional(),\n girPath: z.array(z.string(), { error: \"must be an array of strings if provided\" }).optional(),\n applicationId: applicationIdSchema,\n reactCompiler: reactCompilerSchema.optional(),\n codegen: z.boolean({ error: \"must be a boolean\" }).optional(),\n userEventSignals: userEventSignalsSchema.optional(),\n elements: elementsSchema.optional(),\n applicationIcon: text(\"must be a path to an icon theme directory or a single icon file\").optional(),\n deploy: deploySchema.optional(),\n});\n\n/**\n * Returns the given configuration unchanged, typed as {@link Config}, so `gtkx.config.ts` gets\n * autocompletion and type checking.\n */\nconst defineConfig: DefineConfig<Config> = createDefineConfig<Config>();\n\nconst libraryEntryIssues = (value: unknown[], index: number, entry: unknown): ReturnType<typeof rawIssue>[] => {\n if (typeof entry === \"string\" && isGirLibrary(entry)) {\n return [];\n }\n\n if (entry === LIBRARIES_WILDCARD) {\n const message =\n `to generate every library, set \\`libraries: \"${LIBRARIES_WILDCARD}\"\\` as a bare string, ` +\n \"not an array entry\";\n\n return [rawIssue(value, [index], message, true)];\n }\n\n const message =\n `invalid library identifier \"${String(entry)}\", must be of the form \"Name-Version\" ` +\n '(e.g. \"Gtk-4.0\")';\n\n return [rawIssue(value, [index], message, true)];\n};\n\nconst isValidApplicationId = (applicationId: string): boolean => {\n if (applicationId.length === 0 || applicationId.length > APPLICATION_ID_MAX_LENGTH) {\n return false;\n }\n\n return APPLICATION_ID_PATTERN.test(applicationId);\n};\n\nconst resolveReactCompilerOptions = (setting: Config[\"reactCompiler\"]): ResolvedReactCompilerOptions | null => {\n if (setting === false) {\n return null;\n }\n\n const overrides = setting === undefined || setting === true ? {} : setting;\n\n return { ...overrides, target: REACT_COMPILER_TARGET };\n};\n\nconst isValidReactCompilerOption = (value: unknown, allowed: Set<string>): boolean =>\n value === undefined || (typeof value === \"string\" && allowed.has(value));\n\nconst validateConfig = (config: Config): void => {\n const result = configSchema.safeParse(config);\n\n if (!result.success) {\n throw configError(result.error);\n }\n};\n\n/**\n * Deep-merges two configurations. `override` wins over `base` on conflicting scalar and object keys, while\n * arrays are concatenated with the `override` entries first.\n */\nconst mergeConfig = (base: Config, override: Config): Config => defu(override, base);\n\nconst resolveElementsModule = (behaviors: string | undefined, root: string | undefined): string | null => {\n if (behaviors === undefined) {\n return null;\n }\n\n return root === undefined ? behaviors : resolve(root, behaviors);\n};\n\nconst resolveLazyElements = (elements: Config[\"elements\"]): string[] =>\n Object.entries(elements?.config ?? {})\n .filter(([, entry]) => entry.isLazy === true)\n .map(([type]) => type);\n\nconst elementEntryValues = <T>(\n elements: Config[\"elements\"],\n pick: (entry: ElementConfigEntry) => T | undefined,\n): Record<string, T> =>\n Object.fromEntries(\n Object.entries(elements?.config ?? {}).flatMap(([type, entry]) => {\n const value = pick(entry);\n\n return value === undefined ? [] : [[type, value] as const];\n }),\n );\n\nconst resolveElementComponents = (elements: Config[\"elements\"]): Record<string, ModuleExport> =>\n elementEntryValues(elements, (entry) => entry.component);\n\nconst resolveElementProps = (elements: Config[\"elements\"]): Record<string, ModuleExport> =>\n elementEntryValues(elements, (entry) => entry.props);\n\nconst resolveOmittedProps = (elements: Config[\"elements\"]): Record<string, string[]> =>\n elementEntryValues(elements, (entry) => entry.omittedProps);\n\nconst resolveConfig = (config: Config, root?: string): ResolvedConfig => ({\n applicationId: config.applicationId,\n reactCompiler: resolveReactCompilerOptions(config.reactCompiler),\n userEventSignals: resolveUserEventSignals(config.userEventSignals),\n elements: resolveElementsModule(config.elements?.behaviors, root),\n lazyElements: resolveLazyElements(config.elements),\n});\n\nexport {\n APPLICATION_ID_MAX_LENGTH,\n defineConfig,\n isValidApplicationId,\n validateConfig,\n mergeConfig,\n resolveLazyElements,\n resolveElementComponents,\n resolveElementProps,\n resolveOmittedProps,\n resolveConfig,\n type ResolvedReactCompilerOptions,\n type Config,\n type ResolvedConfig,\n};\n"]}
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"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","sourcesContent":["import { createDefineConfig, type DefineConfig } from \"c12\";\nimport { defu } from \"defu\";\nimport { resolve } from \"node:path\";\nimport { z } from \"zod\";\nimport { configError, isRecord, rawIssue } from \"./config-error.ts\";\nimport { deploySchema } from \"./deploy.ts\";\nimport { DEPRECATION_IDS } from \"./deprecations.ts\";\nimport { isGirLibrary, text } from \"./schema-text.ts\";\nimport { resolveUserEventSignals } from \"./user-event-signals.ts\";\n\n/** Accepted `reactCompiler.compilationMode` values, choosing which functions the compiler processes. */\ntype ReactCompilerCompilationMode = (typeof COMPILATION_MODES)[number];\n/** Accepted `reactCompiler.panicThreshold` values, choosing which compiler diagnostics fail the build. */\ntype ReactCompilerPanicThreshold = (typeof PANIC_THRESHOLDS)[number];\n\n/** Object form of the `reactCompiler` config key, forwarded as-is to `babel-plugin-react-compiler`. */\ntype ReactCompilerOptions = {\n /** Which functions the compiler processes; left to the compiler's own default when omitted. */\n compilationMode?: ReactCompilerCompilationMode;\n /** Which compiler diagnostics fail the build; left to the compiler's own default when omitted. */\n panicThreshold?: ReactCompilerPanicThreshold;\n};\n\n/**\n * The React Compiler options the build hands to `babel-plugin-react-compiler`, with the React version\n * GTKX targets filled in.\n */\ntype ResolvedReactCompilerOptions = ReactCompilerOptions & {\n /** React major version the compiler emits for. */\n target: \"19\";\n};\n\n/**\n * User-facing configuration for a GTKX project, as authored in `gtkx.config.ts`: the GIR libraries\n * to bind and where to find them, the GApplication id, per-element configuration, the React\n * Compiler, codegen, and user event signal settings, the `agents` and `mcp` blocks controlling what\n * coding agents are given, the `future` block opting into behavior that becomes the default in the\n * next major version, and the `deprecations` block silencing the warnings about flags left unset.\n */\ntype Config = z.infer<typeof configSchema>;\ntype ModuleExport = z.infer<typeof moduleExportSchema>;\ntype ElementConfigEntry = z.infer<typeof elementConfigSchema>;\n\ntype McpSettings = {\n tools: string[];\n isReadOnly: boolean;\n};\n\ntype ResolvedFuture = {\n isByteArrayTyped: boolean;\n isValueUnwrapped: boolean;\n isFinishTrimmed: boolean;\n isInoutInPlace: boolean;\n isResourceImported: boolean;\n isAdwaitaDefault: boolean;\n isTreeShaken: boolean;\n};\n\n/** Configuration reduced to the values the app runtime and the build need, with paths already resolved. */\ntype ResolvedConfig = {\n /** The GApplication identifier the app registers under. */\n applicationId: string;\n /** React Compiler options for the build, or `null` when the compiler is disabled. */\n reactCompiler: ResolvedReactCompilerOptions | null;\n /**\n * Signal names, keyed by GLib type name, that stay suppressed while a React commit writes to a widget.\n * `notify` stays suppressed only for the property being written.\n */\n userEventSignals: Record<string, string[]>;\n /** Path of the module exporting per-element configs, or `null` when none is configured. */\n elements: string | null;\n /** GLib type names of the elements marked `isLazy`, whose GObject their parent container creates. */\n lazyElements: string[];\n};\n\nconst LIBRARIES_WILDCARD = \"*\";\nconst APPLICATION_ID_PATTERN = /^[A-Za-z_][A-Za-z0-9_-]*(\\.[A-Za-z_][A-Za-z0-9_-]*)+$/;\nconst APPLICATION_ID_MAX_LENGTH = 255;\n/** Compilation modes `babel-plugin-react-compiler` accepts. */\nconst COMPILATION_MODES = [\"infer\", \"syntax\", \"annotation\", \"all\"] as const;\n/** Panic thresholds `babel-plugin-react-compiler` accepts. */\nconst PANIC_THRESHOLDS = [\"none\", \"critical_errors\", \"all_errors\"] as const;\nconst REACT_COMPILER_TARGET = \"19\";\nconst COMPILATION_MODE_SET: Set<string> = new Set(COMPILATION_MODES);\nconst PANIC_THRESHOLD_SET: Set<string> = new Set(PANIC_THRESHOLDS);\n\nconst librariesSchema = z.custom<typeof LIBRARIES_WILDCARD | string[]>().check((ctx) => {\n const value = ctx.value;\n\n if (value === LIBRARIES_WILDCARD) {\n return;\n }\n\n if (!Array.isArray(value) || value.length === 0) {\n ctx.issues.push(rawIssue(value, [], `must be \"${LIBRARIES_WILDCARD}\", a non-empty string array, or omitted`));\n\n return;\n }\n\n for (const [index, entry] of value.entries()) {\n ctx.issues.push(...libraryEntryIssues(value, index, entry));\n }\n});\n\nconst applicationIdSchema = z.custom<string>().check((ctx) => {\n const value = ctx.value;\n\n if (typeof value !== \"string\" || !isValidApplicationId(value)) {\n ctx.issues.push(\n rawIssue(\n value,\n [],\n `invalid \\`applicationId\\` \"${value}\", must satisfy g_application_id_is_valid ` +\n '(e.g. \"org.example.MyApp\")',\n true,\n ),\n );\n }\n});\n\nconst reactCompilerSchema = z.custom<boolean | ReactCompilerOptions>().check((ctx) => {\n const value = ctx.value;\n\n if (typeof value === \"boolean\") {\n return;\n }\n\n if (!isRecord(value)) {\n ctx.issues.push(rawIssue(value, [], \"must be a boolean or an options object\"));\n\n return;\n }\n\n const compilationMode = value.compilationMode;\n\n if (!isValidReactCompilerOption(compilationMode, COMPILATION_MODE_SET)) {\n ctx.issues.push(\n rawIssue(\n value,\n [],\n `invalid \\`reactCompiler.compilationMode\\` \"${String(compilationMode)}\", ` +\n `must be one of ${COMPILATION_MODES.join(\", \")}`,\n true,\n ),\n );\n }\n\n const panicThreshold = value.panicThreshold;\n\n if (!isValidReactCompilerOption(panicThreshold, PANIC_THRESHOLD_SET)) {\n ctx.issues.push(\n rawIssue(\n value,\n [],\n `invalid \\`reactCompiler.panicThreshold\\` \"${String(panicThreshold)}\", ` +\n `must be one of ${PANIC_THRESHOLDS.join(\", \")}`,\n true,\n ),\n );\n }\n});\n\nconst userEventSignalsSchema = z.record(\n z.string(),\n z.array(\n z.string({ error: \"must be a non-empty signal name\" }).min(1, { error: \"must be a non-empty signal name\" }),\n {\n error: \"must be an array of signal names\",\n },\n ),\n { error: \"must be a record of GLib type names to signal name arrays\" },\n);\n\nconst moduleExportSchema = z.object(\n {\n module: z.string({ error: \"must be a module specifier\" }).min(1, { error: \"must be a module specifier\" }),\n export: z.string({ error: \"must be an export name\" }).min(1, { error: \"must be an export name\" }),\n },\n { error: \"must be a { module, export } object\" },\n);\n\nconst elementConfigSchema = z.object({\n component: moduleExportSchema.optional(),\n props: moduleExportSchema.optional(),\n isLazy: z.boolean({ error: \"must be a boolean\" }).optional(),\n omittedProps: z\n .array(\n z.string({ error: \"must be a non-empty property name\" }).min(1, {\n error: \"must be a non-empty property name\",\n }),\n { error: \"must be an array of property names\" },\n )\n .optional(),\n});\n\nconst elementsSchema = z.object({\n behaviors: z\n .string({ error: \"must be a path to a module exporting element behaviors\" })\n .min(1, { error: \"must be a path to a module exporting element behaviors\" })\n .optional(),\n config: z.record(z.string(), elementConfigSchema).optional(),\n});\n\nconst agentsSchema = z.object({\n rules: z.boolean({ error: \"must be a boolean\" }).optional(),\n reference: z.boolean({ error: \"must be a boolean\" }).optional(),\n});\n\nconst mcpSchema = z.object({\n tools: z\n .array(z.string({ error: \"must be a tool name pattern\" }).min(1, { error: \"must be a tool name pattern\" }), {\n error: \"must be an array of tool name patterns\",\n })\n .optional(),\n readOnly: z.boolean({ error: \"must be a boolean\" }).optional(),\n});\n\nconst futureSchema = z.object({\n v2ByteArrays: z.boolean({ error: \"must be a boolean\" }).optional(),\n v2ValueReturns: z.boolean({ error: \"must be a boolean\" }).optional(),\n v2FinishResults: z.boolean({ error: \"must be a boolean\" }).optional(),\n v2InoutReturns: z.boolean({ error: \"must be a boolean\" }).optional(),\n v2ResourceImports: z.boolean({ error: \"must be a boolean\" }).optional(),\n v2DefaultLibraries: z.boolean({ error: \"must be a boolean\" }).optional(),\n v2TreeShaking: z.boolean({ error: \"must be a boolean\" }).optional(),\n});\n\nconst FUTURE_KEYS: Set<string> = new Set(Object.keys(futureSchema.shape));\nconst DEPRECATION_ID_ERROR = `must be one of ${DEPRECATION_IDS.join(\", \")}`;\n\nconst deprecationsSchema = z.object({\n silence: z\n .array(z.enum(DEPRECATION_IDS, { error: DEPRECATION_ID_ERROR }), {\n error: \"must be an array of deprecation ids\",\n })\n .optional(),\n});\n\n/** Schema every `gtkx.config.ts` is validated against, and the source of the {@link Config} type. */\nconst configSchema = z.object({\n future: futureSchema.optional(),\n libraries: librariesSchema.optional(),\n girPath: z.array(z.string(), { error: \"must be an array of strings if provided\" }).optional(),\n applicationId: applicationIdSchema,\n reactCompiler: reactCompilerSchema.optional(),\n codegen: z.boolean({ error: \"must be a boolean\" }).optional(),\n userEventSignals: userEventSignalsSchema.optional(),\n elements: elementsSchema.optional(),\n applicationIcon: text(\"must be a path to an icon theme directory or a single icon file\").optional(),\n deploy: deploySchema.optional(),\n agents: agentsSchema.optional(),\n mcp: mcpSchema.optional(),\n deprecations: deprecationsSchema.optional(),\n});\n\n/**\n * Returns the given configuration unchanged, typed as {@link Config}, so `gtkx.config.ts` gets\n * autocompletion and type checking.\n */\nconst defineConfig: DefineConfig<Config> = createDefineConfig<Config>();\n\nconst libraryEntryIssues = (value: unknown[], index: number, entry: unknown): ReturnType<typeof rawIssue>[] => {\n if (typeof entry === \"string\" && isGirLibrary(entry)) {\n return [];\n }\n\n if (entry === LIBRARIES_WILDCARD) {\n const message =\n `to generate every library, set \\`libraries: \"${LIBRARIES_WILDCARD}\"\\` as a bare string, ` +\n \"not an array entry\";\n\n return [rawIssue(value, [index], message, true)];\n }\n\n const message =\n `invalid library identifier \"${String(entry)}\", must be of the form \"Name-Version\" ` +\n '(e.g. \"Gtk-4.0\")';\n\n return [rawIssue(value, [index], message, true)];\n};\n\nconst isValidApplicationId = (applicationId: string): boolean => {\n if (applicationId.length === 0 || applicationId.length > APPLICATION_ID_MAX_LENGTH) {\n return false;\n }\n\n return APPLICATION_ID_PATTERN.test(applicationId);\n};\n\nconst resolveReactCompilerOptions = (setting: Config[\"reactCompiler\"]): ResolvedReactCompilerOptions | null => {\n if (setting === false) {\n return null;\n }\n\n const overrides = setting === undefined || setting === true ? {} : setting;\n\n return { ...overrides, target: REACT_COMPILER_TARGET };\n};\n\nconst isValidReactCompilerOption = (value: unknown, allowed: Set<string>): boolean =>\n value === undefined || (typeof value === \"string\" && allowed.has(value));\n\nconst validateConfig = (config: Config): void => {\n const result = configSchema.safeParse(config);\n\n if (!result.success) {\n throw configError(result.error);\n }\n};\n\n/**\n * Deep-merges a configuration over a base. `override` wins over `base` on conflicting scalar and object keys, while\n * arrays are concatenated with the `override` entries first.\n */\nconst mergeConfig = (base: Config, override: Config): Config => defu(override, base);\n\nconst resolveElementsModule = (behaviors: string | undefined, root: string | undefined): string | null => {\n if (behaviors === undefined) {\n return null;\n }\n\n return root === undefined ? behaviors : resolve(root, behaviors);\n};\n\nconst resolveLazyElements = (elements: Config[\"elements\"]): string[] =>\n Object.entries(elements?.config ?? {})\n .filter(([, entry]) => entry.isLazy === true)\n .map(([type]) => type);\n\nconst elementEntryValues = <T>(\n elements: Config[\"elements\"],\n pick: (entry: ElementConfigEntry) => T | undefined,\n): Record<string, T> =>\n Object.fromEntries(\n Object.entries(elements?.config ?? {}).flatMap(([type, entry]) => {\n const value = pick(entry);\n\n return value === undefined ? [] : [[type, value] as const];\n }),\n );\n\nconst resolveElementComponents = (elements: Config[\"elements\"]): Record<string, ModuleExport> =>\n elementEntryValues(elements, (entry) => entry.component);\n\nconst resolveElementProps = (elements: Config[\"elements\"]): Record<string, ModuleExport> =>\n elementEntryValues(elements, (entry) => entry.props);\n\nconst resolveOmittedProps = (elements: Config[\"elements\"]): Record<string, string[]> =>\n elementEntryValues(elements, (entry) => entry.omittedProps);\n\nconst isAgentRulesEnabled = (config: Config): boolean => config.agents?.rules !== false;\nconst isAgentReferenceEnabled = (config: Config): boolean => config.agents?.reference !== false;\n\nconst resolveMcpSettings = (config: Config): McpSettings => ({\n tools: config.mcp?.tools ?? [],\n isReadOnly: config.mcp?.readOnly === true,\n});\n\nconst resolveFuture = (future: Config[\"future\"]): ResolvedFuture => ({\n isByteArrayTyped: future?.v2ByteArrays === true,\n isValueUnwrapped: future?.v2ValueReturns === true,\n isFinishTrimmed: future?.v2FinishResults === true,\n isInoutInPlace: future?.v2InoutReturns === true,\n isResourceImported: future?.v2ResourceImports === true,\n isAdwaitaDefault: future?.v2DefaultLibraries === true,\n isTreeShaken: future?.v2TreeShaking === true,\n});\n\nconst unknownFutureKeys = (future: Config[\"future\"]): string[] =>\n Object.keys(future ?? {}).filter((key) => !FUTURE_KEYS.has(key));\n\nconst resolveConfig = (config: Config, root?: string): ResolvedConfig => ({\n applicationId: config.applicationId,\n reactCompiler: resolveReactCompilerOptions(config.reactCompiler),\n userEventSignals: resolveUserEventSignals(config.userEventSignals),\n elements: resolveElementsModule(config.elements?.behaviors, root),\n lazyElements: resolveLazyElements(config.elements),\n});\n\nexport {\n APPLICATION_ID_MAX_LENGTH,\n defineConfig,\n isAgentReferenceEnabled,\n isAgentRulesEnabled,\n isValidApplicationId,\n validateConfig,\n mergeConfig,\n resolveLazyElements,\n resolveElementComponents,\n resolveElementProps,\n resolveMcpSettings,\n resolveOmittedProps,\n resolveConfig,\n resolveFuture,\n unknownFutureKeys,\n type McpSettings,\n type ResolvedReactCompilerOptions,\n type Config,\n type ResolvedConfig,\n type ResolvedFuture,\n};\n"]}
@@ -0,0 +1,5 @@
1
+ import type { Config } from "./config.ts";
2
+ declare const DEPRECATION_IDS: readonly ["gtkx-v2-byte-arrays", "gtkx-v2-value-returns", "gtkx-v2-finish-results", "gtkx-v2-inout-returns", "gtkx-v2-resource-imports", "gtkx-v2-default-libraries", "gtkx-v2-tree-shaking"];
3
+ declare const warnDeprecations: (config: Config, root: string) => void;
4
+ export { DEPRECATION_IDS, warnDeprecations };
5
+ //# sourceMappingURL=deprecations.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"deprecations.d.ts","sourceRoot":"","sources":["../src/deprecations.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAkB1C,QAAA,MAAM,eAAe,+LAQX,CAAC;AAuFX,QAAA,MAAM,gBAAgB,GAAI,QAAQ,MAAM,EAAE,MAAM,MAAM,KAAG,IAaxD,CAAC;AAEF,OAAO,EAAE,eAAe,EAAE,gBAAgB,EAAE,CAAC"}
@@ -0,0 +1,97 @@
1
+ import { warn } from "@gtkx/utils";
2
+ const SHOWN_ENV = "GTKX_DEPRECATIONS_SHOWN";
3
+ const GUIDE_URL = "https://gtkx.dev/guide/upgrading-to-2";
4
+ const ENTRY_COLUMN = 30;
5
+ const BUILD_REPORTS = " The build, not tsc, reports the specifiers still to change.";
6
+ const NOTHING_REPORTS = " Nothing reports this one; check the app yourself.";
7
+ const SILENT_SITES = " `Array.isArray` and `JSON.stringify` change silently; grep for them.";
8
+ const DEPRECATION_IDS = [
9
+ "gtkx-v2-byte-arrays",
10
+ "gtkx-v2-value-returns",
11
+ "gtkx-v2-finish-results",
12
+ "gtkx-v2-inout-returns",
13
+ "gtkx-v2-resource-imports",
14
+ "gtkx-v2-default-libraries",
15
+ "gtkx-v2-tree-shaking",
16
+ ];
17
+ const FUTURE_DEPRECATIONS = [
18
+ {
19
+ id: "gtkx-v2-byte-arrays",
20
+ flag: "v2ByteArrays",
21
+ change: "Byte sequences come back as number[]. In 2.0 they come back as Uint8Array.",
22
+ unchecked: SILENT_SITES,
23
+ },
24
+ {
25
+ id: "gtkx-v2-value-returns",
26
+ flag: "v2ValueReturns",
27
+ change: "Bindings that return a GValue hand back the box. In 2.0 they hand back its contents, as unknown.",
28
+ },
29
+ {
30
+ id: "gtkx-v2-finish-results",
31
+ flag: "v2FinishResults",
32
+ change: "Async pairs with out parameters resolve with a leading success boolean. In 2.0 it is dropped.",
33
+ },
34
+ {
35
+ id: "gtkx-v2-inout-returns",
36
+ flag: "v2InoutReturns",
37
+ change: "Inout records repeat in the return value. In 2.0 the repeated entry is dropped.",
38
+ },
39
+ {
40
+ id: "gtkx-v2-resource-imports",
41
+ flag: "v2ResourceImports",
42
+ change: "Assets resolve through the #data/ import map. In 2.0 they resolve through ?resource imports.",
43
+ unchecked: BUILD_REPORTS,
44
+ },
45
+ {
46
+ id: "gtkx-v2-default-libraries",
47
+ flag: "v2DefaultLibraries",
48
+ change: "Only Gtk-4.0 is bound by default. In 2.0 Adw-1 is bound alongside it.",
49
+ unchecked: NOTHING_REPORTS,
50
+ },
51
+ {
52
+ id: "gtkx-v2-tree-shaking",
53
+ flag: "v2TreeShaking",
54
+ change: "The stores register every class eagerly. " +
55
+ "In 2.0 each class registers itself and unused ones drop from bundles.",
56
+ },
57
+ ];
58
+ const shownRoots = new Map();
59
+ const isSilenced = (config, id) => (config.deprecations?.silence ?? []).includes(id);
60
+ const unsetDeprecations = (config) => FUTURE_DEPRECATIONS.filter((deprecation) => config.future?.[deprecation.flag] !== true);
61
+ const formatSummary = (unset, silenced) => {
62
+ const note = silenced === 0 ? "" : ` ${String(silenced)} of them silenced here.`;
63
+ return (`${String(unset)} of ${String(FUTURE_DEPRECATIONS.length)} future flags are unset. ` +
64
+ `Their behavior becomes the default in GTKX 2.0.${note}`);
65
+ };
66
+ const formatDeprecation = (deprecation) => ` [${deprecation.id}]`.padEnd(ENTRY_COLUMN) +
67
+ `future: { ${deprecation.flag}: true }\n ${deprecation.change}` +
68
+ (deprecation.unchecked ?? "");
69
+ const formatAdvice = (pending) => {
70
+ if (pending.every((deprecation) => deprecation.unchecked === undefined)) {
71
+ return " Set one flag at a time and run tsc: every affected call site is a type error.";
72
+ }
73
+ return " Set one flag at a time and run tsc: it reports every affected call site except where noted above.";
74
+ };
75
+ const formatBlock = (unset, pending, first) => [
76
+ formatSummary(unset.length, unset.length - pending.length),
77
+ "",
78
+ ...pending.flatMap((deprecation) => [formatDeprecation(deprecation), ""]),
79
+ formatAdvice(pending),
80
+ ` Guide ${GUIDE_URL}`,
81
+ ` Silence deprecations: { silence: [${JSON.stringify(first.id)}] }`,
82
+ ].join("\n");
83
+ const hasShown = (root, signature) => shownRoots.get(root) === signature || process.env[SHOWN_ENV] === signature;
84
+ const warnDeprecations = (config, root) => {
85
+ const unset = unsetDeprecations(config);
86
+ const pending = unset.filter((deprecation) => !isSilenced(config, deprecation.id));
87
+ const [first] = pending;
88
+ const signature = pending.map((deprecation) => deprecation.id).join(",");
89
+ if (first === undefined || hasShown(root, signature)) {
90
+ return;
91
+ }
92
+ shownRoots.set(root, signature);
93
+ process.env[SHOWN_ENV] = signature;
94
+ warn(formatBlock(unset, pending, first));
95
+ };
96
+ export { DEPRECATION_IDS, warnDeprecations };
97
+ //# sourceMappingURL=deprecations.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"deprecations.js","sourceRoot":"","sources":["../src/deprecations.ts"],"names":[],"mappings":"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","sourcesContent":["import { warn } from \"@gtkx/utils\";\nimport type { Config } from \"./config.ts\";\n\ntype DeprecationId = (typeof DEPRECATION_IDS)[number];\n\ntype FutureDeprecation = {\n id: DeprecationId;\n flag: keyof NonNullable<Config[\"future\"]>;\n change: string;\n unchecked?: string;\n};\n\nconst SHOWN_ENV = \"GTKX_DEPRECATIONS_SHOWN\";\nconst GUIDE_URL = \"https://gtkx.dev/guide/upgrading-to-2\";\nconst ENTRY_COLUMN = 30;\nconst BUILD_REPORTS = \" The build, not tsc, reports the specifiers still to change.\";\nconst NOTHING_REPORTS = \" Nothing reports this one; check the app yourself.\";\nconst SILENT_SITES = \" `Array.isArray` and `JSON.stringify` change silently; grep for them.\";\n\nconst DEPRECATION_IDS = [\n \"gtkx-v2-byte-arrays\",\n \"gtkx-v2-value-returns\",\n \"gtkx-v2-finish-results\",\n \"gtkx-v2-inout-returns\",\n \"gtkx-v2-resource-imports\",\n \"gtkx-v2-default-libraries\",\n \"gtkx-v2-tree-shaking\",\n] as const;\n\nconst FUTURE_DEPRECATIONS: FutureDeprecation[] = [\n {\n id: \"gtkx-v2-byte-arrays\",\n flag: \"v2ByteArrays\",\n change: \"Byte sequences come back as number[]. In 2.0 they come back as Uint8Array.\",\n unchecked: SILENT_SITES,\n },\n {\n id: \"gtkx-v2-value-returns\",\n flag: \"v2ValueReturns\",\n change: \"Bindings that return a GValue hand back the box. In 2.0 they hand back its contents, as unknown.\",\n },\n {\n id: \"gtkx-v2-finish-results\",\n flag: \"v2FinishResults\",\n change: \"Async pairs with out parameters resolve with a leading success boolean. In 2.0 it is dropped.\",\n },\n {\n id: \"gtkx-v2-inout-returns\",\n flag: \"v2InoutReturns\",\n change: \"Inout records repeat in the return value. In 2.0 the repeated entry is dropped.\",\n },\n {\n id: \"gtkx-v2-resource-imports\",\n flag: \"v2ResourceImports\",\n change: \"Assets resolve through the #data/ import map. In 2.0 they resolve through ?resource imports.\",\n unchecked: BUILD_REPORTS,\n },\n {\n id: \"gtkx-v2-default-libraries\",\n flag: \"v2DefaultLibraries\",\n change: \"Only Gtk-4.0 is bound by default. In 2.0 Adw-1 is bound alongside it.\",\n unchecked: NOTHING_REPORTS,\n },\n {\n id: \"gtkx-v2-tree-shaking\",\n flag: \"v2TreeShaking\",\n change:\n \"The stores register every class eagerly. \" +\n \"In 2.0 each class registers itself and unused ones drop from bundles.\",\n },\n];\n\nconst shownRoots: Map<string, string> = new Map();\n\nconst isSilenced = (config: Config, id: DeprecationId): boolean => (config.deprecations?.silence ?? []).includes(id);\n\nconst unsetDeprecations = (config: Config): FutureDeprecation[] =>\n FUTURE_DEPRECATIONS.filter((deprecation) => config.future?.[deprecation.flag] !== true);\n\nconst formatSummary = (unset: number, silenced: number): string => {\n const note = silenced === 0 ? \"\" : ` ${String(silenced)} of them silenced here.`;\n\n return (\n `${String(unset)} of ${String(FUTURE_DEPRECATIONS.length)} future flags are unset. ` +\n `Their behavior becomes the default in GTKX 2.0.${note}`\n );\n};\n\nconst formatDeprecation = (deprecation: FutureDeprecation): string =>\n ` [${deprecation.id}]`.padEnd(ENTRY_COLUMN) +\n `future: { ${deprecation.flag}: true }\\n ${deprecation.change}` +\n (deprecation.unchecked ?? \"\");\n\nconst formatAdvice = (pending: FutureDeprecation[]): string => {\n if (pending.every((deprecation) => deprecation.unchecked === undefined)) {\n return \" Set one flag at a time and run tsc: every affected call site is a type error.\";\n }\n\n return \" Set one flag at a time and run tsc: it reports every affected call site except where noted above.\";\n};\n\nconst formatBlock = (unset: FutureDeprecation[], pending: FutureDeprecation[], first: FutureDeprecation): string =>\n [\n formatSummary(unset.length, unset.length - pending.length),\n \"\",\n ...pending.flatMap((deprecation) => [formatDeprecation(deprecation), \"\"]),\n formatAdvice(pending),\n ` Guide ${GUIDE_URL}`,\n ` Silence deprecations: { silence: [${JSON.stringify(first.id)}] }`,\n ].join(\"\\n\");\n\nconst hasShown = (root: string, signature: string): boolean =>\n shownRoots.get(root) === signature || process.env[SHOWN_ENV] === signature;\n\nconst warnDeprecations = (config: Config, root: string): void => {\n const unset = unsetDeprecations(config);\n const pending = unset.filter((deprecation) => !isSilenced(config, deprecation.id));\n const [first] = pending;\n const signature = pending.map((deprecation) => deprecation.id).join(\",\");\n\n if (first === undefined || hasShown(root, signature)) {\n return;\n }\n\n shownRoots.set(root, signature);\n process.env[SHOWN_ENV] = signature;\n warn(formatBlock(unset, pending, first));\n};\n\nexport { DEPRECATION_IDS, warnDeprecations };\n"]}
@@ -1,5 +1,5 @@
1
- export type { ResolvedReactCompilerOptions } from "./config.ts";
2
- export { APPLICATION_ID_MAX_LENGTH, isValidApplicationId, resolveElementComponents, resolveElementProps, resolveLazyElements, resolveOmittedProps, } from "./config.ts";
1
+ export type { McpSettings, ResolvedFuture, ResolvedReactCompilerOptions } from "./config.ts";
2
+ export { APPLICATION_ID_MAX_LENGTH, isAgentReferenceEnabled, isAgentRulesEnabled, isValidApplicationId, resolveElementComponents, resolveElementProps, resolveFuture, resolveLazyElements, resolveMcpSettings, resolveOmittedProps, unknownFutureKeys, } from "./config.ts";
3
3
  export { createConfigLoader } from "./loader.ts";
4
4
  export { resourceBasePath } from "./resource-base-path.ts";
5
5
  //# sourceMappingURL=internal.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"internal.d.ts","sourceRoot":"","sources":["../src/internal.ts"],"names":[],"mappings":"AAAA,YAAY,EAAE,4BAA4B,EAAE,MAAM,aAAa,CAAC;AAChE,OAAO,EACH,yBAAyB,EACzB,oBAAoB,EACpB,wBAAwB,EACxB,mBAAmB,EACnB,mBAAmB,EACnB,mBAAmB,GACtB,MAAM,aAAa,CAAC;AACrB,OAAO,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC;AACjD,OAAO,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC"}
1
+ {"version":3,"file":"internal.d.ts","sourceRoot":"","sources":["../src/internal.ts"],"names":[],"mappings":"AAAA,YAAY,EAAE,WAAW,EAAE,cAAc,EAAE,4BAA4B,EAAE,MAAM,aAAa,CAAC;AAC7F,OAAO,EACH,yBAAyB,EACzB,uBAAuB,EACvB,mBAAmB,EACnB,oBAAoB,EACpB,wBAAwB,EACxB,mBAAmB,EACnB,aAAa,EACb,mBAAmB,EACnB,kBAAkB,EAClB,mBAAmB,EACnB,iBAAiB,GACpB,MAAM,aAAa,CAAC;AACrB,OAAO,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC;AACjD,OAAO,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC"}
package/dist/internal.js CHANGED
@@ -1,4 +1,4 @@
1
- export { APPLICATION_ID_MAX_LENGTH, isValidApplicationId, resolveElementComponents, resolveElementProps, resolveLazyElements, resolveOmittedProps, } from "./config.js";
1
+ export { APPLICATION_ID_MAX_LENGTH, isAgentReferenceEnabled, isAgentRulesEnabled, isValidApplicationId, resolveElementComponents, resolveElementProps, resolveFuture, resolveLazyElements, resolveMcpSettings, resolveOmittedProps, unknownFutureKeys, } from "./config.js";
2
2
  export { createConfigLoader } from "./loader.js";
3
3
  export { resourceBasePath } from "./resource-base-path.js";
4
4
  //# sourceMappingURL=internal.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"internal.js","sourceRoot":"","sources":["../src/internal.ts"],"names":[],"mappings":"AACA,OAAO,EACH,yBAAyB,EACzB,oBAAoB,EACpB,wBAAwB,EACxB,mBAAmB,EACnB,mBAAmB,EACnB,mBAAmB,GACtB,MAAM,aAAa,CAAC;AACrB,OAAO,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC;AACjD,OAAO,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC","sourcesContent":["export type { ResolvedReactCompilerOptions } from \"./config.ts\";\nexport {\n APPLICATION_ID_MAX_LENGTH,\n isValidApplicationId,\n resolveElementComponents,\n resolveElementProps,\n resolveLazyElements,\n resolveOmittedProps,\n} from \"./config.ts\";\nexport { createConfigLoader } from \"./loader.ts\";\nexport { resourceBasePath } from \"./resource-base-path.ts\";\n"]}
1
+ {"version":3,"file":"internal.js","sourceRoot":"","sources":["../src/internal.ts"],"names":[],"mappings":"AACA,OAAO,EACH,yBAAyB,EACzB,uBAAuB,EACvB,mBAAmB,EACnB,oBAAoB,EACpB,wBAAwB,EACxB,mBAAmB,EACnB,aAAa,EACb,mBAAmB,EACnB,kBAAkB,EAClB,mBAAmB,EACnB,iBAAiB,GACpB,MAAM,aAAa,CAAC;AACrB,OAAO,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC;AACjD,OAAO,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC","sourcesContent":["export type { McpSettings, ResolvedFuture, ResolvedReactCompilerOptions } from \"./config.ts\";\nexport {\n APPLICATION_ID_MAX_LENGTH,\n isAgentReferenceEnabled,\n isAgentRulesEnabled,\n isValidApplicationId,\n resolveElementComponents,\n resolveElementProps,\n resolveFuture,\n resolveLazyElements,\n resolveMcpSettings,\n resolveOmittedProps,\n unknownFutureKeys,\n} from \"./config.ts\";\nexport { createConfigLoader } from \"./loader.ts\";\nexport { resourceBasePath } from \"./resource-base-path.ts\";\n"]}
package/dist/loader.d.ts CHANGED
@@ -24,7 +24,9 @@ type ConfigLoader = {
24
24
  resolve: (cwd: string) => Promise<ResolvedConfig>;
25
25
  };
26
26
  /**
27
- * Loads and validates the `gtkx.config.ts` file for a project.
27
+ * Loads and validates the `gtkx.config.ts` file for a project. Writes one deprecation notice to stderr the
28
+ * first time a configuration leaves a `future` flag unset, recording what it reported in the environment so
29
+ * a child process does not repeat it.
28
30
  * @param cwd Directory the configuration file is looked up in; parent directories are not searched.
29
31
  * @param options Loading options, such as the environment mode whose overrides are applied.
30
32
  * @throws When that directory holds no configuration file, or when the configuration fails validation.
@@ -1 +1 @@
1
- {"version":3,"file":"loader.d.ts","sourceRoot":"","sources":["../src/loader.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,KAAK,MAAM,EAAiB,KAAK,cAAc,EAAkB,MAAM,aAAa,CAAC;AAE9F,2DAA2D;AAC3D,KAAK,YAAY,GAAG;IAChB,8CAA8C;IAC9C,MAAM,EAAE,MAAM,CAAC;IACf,+DAA+D;IAC/D,UAAU,EAAE,MAAM,CAAC;IACnB,gFAAgF;IAChF,IAAI,EAAE,MAAM,CAAC;CAChB,CAAC;AAEF,+FAA+F;AAC/F,KAAK,iBAAiB,GAAG;IACrB;;;OAGG;IACH,IAAI,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CAC7B,CAAC;AAEF,sGAAsG;AACtG,KAAK,YAAY,GAAG;IAChB,gGAAgG;IAChG,IAAI,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC,YAAY,CAAC,CAAC;IAC7C,yGAAyG;IACzG,OAAO,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC,cAAc,CAAC,CAAC;CACrD,CAAC;AAEF;;;;;GAKG;AACH,QAAA,MAAM,UAAU,GAAU,KAAK,MAAM,EAAE,UAAS,iBAAsB,KAAG,OAAO,CAAC,YAAY,CA2B5F,CAAC;AAEF,QAAA,MAAM,kBAAkB,GAAI,UAAS,iBAAsB,KAAG,YAiB7D,CAAC;AAEF,OAAO,EAAE,UAAU,EAAE,kBAAkB,EAAE,KAAK,YAAY,EAAE,KAAK,YAAY,EAAE,CAAC"}
1
+ {"version":3,"file":"loader.d.ts","sourceRoot":"","sources":["../src/loader.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,KAAK,MAAM,EAAiB,KAAK,cAAc,EAAkB,MAAM,aAAa,CAAC;AAG9F,2DAA2D;AAC3D,KAAK,YAAY,GAAG;IAChB,8CAA8C;IAC9C,MAAM,EAAE,MAAM,CAAC;IACf,+DAA+D;IAC/D,UAAU,EAAE,MAAM,CAAC;IACnB,gFAAgF;IAChF,IAAI,EAAE,MAAM,CAAC;CAChB,CAAC;AAEF,+FAA+F;AAC/F,KAAK,iBAAiB,GAAG;IACrB;;;OAGG;IACH,IAAI,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CAC7B,CAAC;AAEF,sGAAsG;AACtG,KAAK,YAAY,GAAG;IAChB,gGAAgG;IAChG,IAAI,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC,YAAY,CAAC,CAAC;IAC7C,yGAAyG;IACzG,OAAO,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC,cAAc,CAAC,CAAC;CACrD,CAAC;AAEF;;;;;;;GAOG;AACH,QAAA,MAAM,UAAU,GAAU,KAAK,MAAM,EAAE,UAAS,iBAAsB,KAAG,OAAO,CAAC,YAAY,CA6B5F,CAAC;AAEF,QAAA,MAAM,kBAAkB,GAAI,UAAS,iBAAsB,KAAG,YAiB7D,CAAC;AAEF,OAAO,EAAE,UAAU,EAAE,kBAAkB,EAAE,KAAK,YAAY,EAAE,KAAK,YAAY,EAAE,CAAC"}
package/dist/loader.js CHANGED
@@ -4,8 +4,11 @@ import { existsSync } from "node:fs";
4
4
  import { resolve } from "node:path";
5
5
  import { missingConfigFileError } from "./config-error.js";
6
6
  import { resolveConfig, validateConfig } from "./config.js";
7
+ import { warnDeprecations } from "./deprecations.js";
7
8
  /**
8
- * Loads and validates the `gtkx.config.ts` file for a project.
9
+ * Loads and validates the `gtkx.config.ts` file for a project. Writes one deprecation notice to stderr the
10
+ * first time a configuration leaves a `future` flag unset, recording what it reported in the environment so
11
+ * a child process does not repeat it.
9
12
  * @param cwd Directory the configuration file is looked up in; parent directories are not searched.
10
13
  * @param options Loading options, such as the environment mode whose overrides are applied.
11
14
  * @throws When that directory holds no configuration file, or when the configuration fails validation.
@@ -26,11 +29,13 @@ const loadConfig = async (cwd, options = {}) => {
26
29
  throw missingConfigFileError(searched);
27
30
  }
28
31
  const config = result.config;
32
+ const root = result.cwd ?? searched;
29
33
  validateConfig(config);
34
+ warnDeprecations(config, root);
30
35
  return {
31
36
  config,
32
37
  configFile,
33
- root: result.cwd ?? searched,
38
+ root,
34
39
  };
35
40
  };
36
41
  const createConfigLoader = (options = {}) => {
@@ -1 +1 @@
1
- {"version":3,"file":"loader.js","sourceRoot":"","sources":["../src/loader.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAC1C,OAAO,EAAE,UAAU,IAAI,cAAc,EAAE,MAAM,KAAK,CAAC;AACnD,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AACrC,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,sBAAsB,EAAE,MAAM,mBAAmB,CAAC;AAC3D,OAAO,EAAe,aAAa,EAAuB,cAAc,EAAE,MAAM,aAAa,CAAC;AA6B9F;;;;;GAKG;AACH,MAAM,UAAU,GAAG,KAAK,EAAE,GAAW,EAAE,UAA6B,EAAE,EAAyB,EAAE;IAC7F,MAAM,QAAQ,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC;IAE9B,MAAM,MAAM,GAAG,MAAM,cAAc,CAAS;QACxC,IAAI,EAAE,MAAM;QACZ,GAAG,EAAE,QAAQ;QACb,MAAM,EAAE,KAAK;QACb,QAAQ,EAAE,KAAK;QACf,WAAW,EAAE,KAAK;QAClB,OAAO,EAAE,EAAE,IAAI,EAAE,OAAO,CAAC,IAAI,EAAE;QAC/B,GAAG,CAAC,CAAC,OAAO,CAAC,IAAI,KAAK,SAAS,CAAC,IAAI,EAAE,OAAO,EAAE,OAAO,CAAC,IAAI,EAAE,CAAC;KACjE,CAAC,CAAC;IAEH,MAAM,UAAU,GAAG,MAAM,CAAC,UAAU,CAAC;IAErC,IAAI,UAAU,KAAK,SAAS,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,QAAQ,EAAE,UAAU,CAAC,CAAC,EAAE,CAAC;QACzE,MAAM,sBAAsB,CAAC,QAAQ,CAAC,CAAC;IAC3C,CAAC;IAED,MAAM,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC;IAC7B,cAAc,CAAC,MAAM,CAAC,CAAC;IAEvB,OAAO;QACH,MAAM;QACN,UAAU;QACV,IAAI,EAAE,MAAM,CAAC,GAAG,IAAI,QAAQ;KAC/B,CAAC;AACN,CAAC,CAAC;AAEF,MAAM,kBAAkB,GAAG,CAAC,UAA6B,EAAE,EAAgB,EAAE;IACzE,MAAM,MAAM,GAAuC,IAAI,GAAG,EAAE,CAAC;IAC7D,MAAM,QAAQ,GAAyC,IAAI,GAAG,EAAE,CAAC;IAEjE,MAAM,IAAI,GAAG,CAAC,GAAW,EAAyB,EAAE,CAChD,WAAW,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,UAAU,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC,CAAC;IAE3E,MAAM,SAAS,GAAG,KAAK,EAAE,IAAY,EAA2B,EAAE;QAC9D,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,UAAU,EAAE,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,CAAC;QAEtD,OAAO,aAAa,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;IAC7C,CAAC,CAAC;IAEF,OAAO;QACH,IAAI;QACJ,OAAO,EAAE,CAAC,GAAW,EAA2B,EAAE,CAAC,WAAW,CAAC,QAAQ,EAAE,OAAO,CAAC,GAAG,CAAC,EAAE,SAAS,CAAC;KACpG,CAAC;AACN,CAAC,CAAC;AAEF,OAAO,EAAE,UAAU,EAAE,kBAAkB,EAAwC,CAAC","sourcesContent":["import { getOrInsert } from \"@gtkx/utils\";\nimport { loadConfig as loadConfigFile } from \"c12\";\nimport { existsSync } from \"node:fs\";\nimport { resolve } from \"node:path\";\nimport { missingConfigFileError } from \"./config-error.ts\";\nimport { type Config, resolveConfig, type ResolvedConfig, validateConfig } from \"./config.ts\";\n\n/** Result of loading a project's `gtkx.config.ts` file. */\ntype LoadedConfig = {\n /** The parsed and validated configuration. */\n config: Config;\n /** Absolute path of the configuration file that was loaded. */\n configFile: string;\n /** Absolute path of the project root the configuration was resolved against. */\n root: string;\n};\n\n/** How a configuration file is read, shared by {@link loadConfig} and `createConfigLoader`. */\ntype LoadConfigOptions = {\n /**\n * Environment name such as `development`: the config's matching `$<mode>` block is layered over the\n * top-level values, and the name is passed to a config authored as a function.\n */\n mode?: string | undefined;\n};\n\n/** Reads a project's configuration once per directory, caching what it loads and what it resolves. */\ntype ConfigLoader = {\n /** Loads the configuration file the given directory resolves to, as {@link loadConfig} does. */\n load: (cwd: string) => Promise<LoadedConfig>;\n /** Loads the configuration for the given directory and reduces it to what the build and the app need. */\n resolve: (cwd: string) => Promise<ResolvedConfig>;\n};\n\n/**\n * Loads and validates the `gtkx.config.ts` file for a project.\n * @param cwd Directory the configuration file is looked up in; parent directories are not searched.\n * @param options Loading options, such as the environment mode whose overrides are applied.\n * @throws When that directory holds no configuration file, or when the configuration fails validation.\n */\nconst loadConfig = async (cwd: string, options: LoadConfigOptions = {}): Promise<LoadedConfig> => {\n const searched = resolve(cwd);\n\n const result = await loadConfigFile<Config>({\n name: \"gtkx\",\n cwd: searched,\n rcFile: false,\n globalRc: false,\n packageJson: false,\n context: { mode: options.mode },\n ...((options.mode !== undefined) && { envName: options.mode }),\n });\n\n const configFile = result.configFile;\n\n if (configFile === undefined || !existsSync(resolve(searched, configFile))) {\n throw missingConfigFileError(searched);\n }\n\n const config = result.config;\n validateConfig(config);\n\n return {\n config,\n configFile,\n root: result.cwd ?? searched,\n };\n};\n\nconst createConfigLoader = (options: LoadConfigOptions = {}): ConfigLoader => {\n const loaded: Map<string, Promise<LoadedConfig>> = new Map();\n const resolved: Map<string, Promise<ResolvedConfig>> = new Map();\n\n const load = (cwd: string): Promise<LoadedConfig> =>\n getOrInsert(loaded, resolve(cwd), (root) => loadConfig(root, options));\n\n const resolveAt = async (root: string): Promise<ResolvedConfig> => {\n const { config, root: configRoot } = await load(root);\n\n return resolveConfig(config, configRoot);\n };\n\n return {\n load,\n resolve: (cwd: string): Promise<ResolvedConfig> => getOrInsert(resolved, resolve(cwd), resolveAt),\n };\n};\n\nexport { loadConfig, createConfigLoader, type LoadedConfig, type ConfigLoader };\n"]}
1
+ {"version":3,"file":"loader.js","sourceRoot":"","sources":["../src/loader.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAC1C,OAAO,EAAE,UAAU,IAAI,cAAc,EAAE,MAAM,KAAK,CAAC;AACnD,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AACrC,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,sBAAsB,EAAE,MAAM,mBAAmB,CAAC;AAC3D,OAAO,EAAe,aAAa,EAAuB,cAAc,EAAE,MAAM,aAAa,CAAC;AAC9F,OAAO,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AA6BrD;;;;;;;GAOG;AACH,MAAM,UAAU,GAAG,KAAK,EAAE,GAAW,EAAE,UAA6B,EAAE,EAAyB,EAAE;IAC7F,MAAM,QAAQ,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC;IAE9B,MAAM,MAAM,GAAG,MAAM,cAAc,CAAS;QACxC,IAAI,EAAE,MAAM;QACZ,GAAG,EAAE,QAAQ;QACb,MAAM,EAAE,KAAK;QACb,QAAQ,EAAE,KAAK;QACf,WAAW,EAAE,KAAK;QAClB,OAAO,EAAE,EAAE,IAAI,EAAE,OAAO,CAAC,IAAI,EAAE;QAC/B,GAAG,CAAC,CAAC,OAAO,CAAC,IAAI,KAAK,SAAS,CAAC,IAAI,EAAE,OAAO,EAAE,OAAO,CAAC,IAAI,EAAE,CAAC;KACjE,CAAC,CAAC;IAEH,MAAM,UAAU,GAAG,MAAM,CAAC,UAAU,CAAC;IAErC,IAAI,UAAU,KAAK,SAAS,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,QAAQ,EAAE,UAAU,CAAC,CAAC,EAAE,CAAC;QACzE,MAAM,sBAAsB,CAAC,QAAQ,CAAC,CAAC;IAC3C,CAAC;IAED,MAAM,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC;IAC7B,MAAM,IAAI,GAAG,MAAM,CAAC,GAAG,IAAI,QAAQ,CAAC;IACpC,cAAc,CAAC,MAAM,CAAC,CAAC;IACvB,gBAAgB,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;IAE/B,OAAO;QACH,MAAM;QACN,UAAU;QACV,IAAI;KACP,CAAC;AACN,CAAC,CAAC;AAEF,MAAM,kBAAkB,GAAG,CAAC,UAA6B,EAAE,EAAgB,EAAE;IACzE,MAAM,MAAM,GAAuC,IAAI,GAAG,EAAE,CAAC;IAC7D,MAAM,QAAQ,GAAyC,IAAI,GAAG,EAAE,CAAC;IAEjE,MAAM,IAAI,GAAG,CAAC,GAAW,EAAyB,EAAE,CAChD,WAAW,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,UAAU,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC,CAAC;IAE3E,MAAM,SAAS,GAAG,KAAK,EAAE,IAAY,EAA2B,EAAE;QAC9D,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,UAAU,EAAE,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,CAAC;QAEtD,OAAO,aAAa,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;IAC7C,CAAC,CAAC;IAEF,OAAO;QACH,IAAI;QACJ,OAAO,EAAE,CAAC,GAAW,EAA2B,EAAE,CAAC,WAAW,CAAC,QAAQ,EAAE,OAAO,CAAC,GAAG,CAAC,EAAE,SAAS,CAAC;KACpG,CAAC;AACN,CAAC,CAAC;AAEF,OAAO,EAAE,UAAU,EAAE,kBAAkB,EAAwC,CAAC","sourcesContent":["import { getOrInsert } from \"@gtkx/utils\";\nimport { loadConfig as loadConfigFile } from \"c12\";\nimport { existsSync } from \"node:fs\";\nimport { resolve } from \"node:path\";\nimport { missingConfigFileError } from \"./config-error.ts\";\nimport { type Config, resolveConfig, type ResolvedConfig, validateConfig } from \"./config.ts\";\nimport { warnDeprecations } from \"./deprecations.ts\";\n\n/** Result of loading a project's `gtkx.config.ts` file. */\ntype LoadedConfig = {\n /** The parsed and validated configuration. */\n config: Config;\n /** Absolute path of the configuration file that was loaded. */\n configFile: string;\n /** Absolute path of the project root the configuration was resolved against. */\n root: string;\n};\n\n/** How a configuration file is read, shared by {@link loadConfig} and `createConfigLoader`. */\ntype LoadConfigOptions = {\n /**\n * Environment name such as `development`: the config's matching `$<mode>` block is layered over the\n * top-level values, and the name is passed to a config authored as a function.\n */\n mode?: string | undefined;\n};\n\n/** Reads a project's configuration once per directory, caching what it loads and what it resolves. */\ntype ConfigLoader = {\n /** Loads the configuration file the given directory resolves to, as {@link loadConfig} does. */\n load: (cwd: string) => Promise<LoadedConfig>;\n /** Loads the configuration for the given directory and reduces it to what the build and the app need. */\n resolve: (cwd: string) => Promise<ResolvedConfig>;\n};\n\n/**\n * Loads and validates the `gtkx.config.ts` file for a project. Writes one deprecation notice to stderr the\n * first time a configuration leaves a `future` flag unset, recording what it reported in the environment so\n * a child process does not repeat it.\n * @param cwd Directory the configuration file is looked up in; parent directories are not searched.\n * @param options Loading options, such as the environment mode whose overrides are applied.\n * @throws When that directory holds no configuration file, or when the configuration fails validation.\n */\nconst loadConfig = async (cwd: string, options: LoadConfigOptions = {}): Promise<LoadedConfig> => {\n const searched = resolve(cwd);\n\n const result = await loadConfigFile<Config>({\n name: \"gtkx\",\n cwd: searched,\n rcFile: false,\n globalRc: false,\n packageJson: false,\n context: { mode: options.mode },\n ...((options.mode !== undefined) && { envName: options.mode }),\n });\n\n const configFile = result.configFile;\n\n if (configFile === undefined || !existsSync(resolve(searched, configFile))) {\n throw missingConfigFileError(searched);\n }\n\n const config = result.config;\n const root = result.cwd ?? searched;\n validateConfig(config);\n warnDeprecations(config, root);\n\n return {\n config,\n configFile,\n root,\n };\n};\n\nconst createConfigLoader = (options: LoadConfigOptions = {}): ConfigLoader => {\n const loaded: Map<string, Promise<LoadedConfig>> = new Map();\n const resolved: Map<string, Promise<ResolvedConfig>> = new Map();\n\n const load = (cwd: string): Promise<LoadedConfig> =>\n getOrInsert(loaded, resolve(cwd), (root) => loadConfig(root, options));\n\n const resolveAt = async (root: string): Promise<ResolvedConfig> => {\n const { config, root: configRoot } = await load(root);\n\n return resolveConfig(config, configRoot);\n };\n\n return {\n load,\n resolve: (cwd: string): Promise<ResolvedConfig> => getOrInsert(resolved, resolve(cwd), resolveAt),\n };\n};\n\nexport { loadConfig, createConfigLoader, type LoadedConfig, type ConfigLoader };\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gtkx/config",
3
- "version": "1.4.0",
3
+ "version": "1.6.0",
4
4
  "description": "Config schema, loader, and element-prop mapping for the GTK toolchain.",
5
5
  "keywords": [
6
6
  "gtkx",
@@ -62,7 +62,7 @@
62
62
  "defu": "^6.1.7",
63
63
  "vite": "^8.2.2",
64
64
  "zod": "^4.4.3",
65
- "@gtkx/utils": "1.4.0"
65
+ "@gtkx/utils": "1.6.0"
66
66
  },
67
67
  "scripts": {
68
68
  "release": "tsx ../../scripts/release-package.ts"
package/src/config.ts CHANGED
@@ -4,6 +4,7 @@ import { resolve } from "node:path";
4
4
  import { z } from "zod";
5
5
  import { configError, isRecord, rawIssue } from "./config-error.ts";
6
6
  import { deploySchema } from "./deploy.ts";
7
+ import { DEPRECATION_IDS } from "./deprecations.ts";
7
8
  import { isGirLibrary, text } from "./schema-text.ts";
8
9
  import { resolveUserEventSignals } from "./user-event-signals.ts";
9
10
 
@@ -32,13 +33,29 @@ type ResolvedReactCompilerOptions = ReactCompilerOptions & {
32
33
  /**
33
34
  * User-facing configuration for a GTKX project, as authored in `gtkx.config.ts`: the GIR libraries
34
35
  * to bind and where to find them, the GApplication id, per-element configuration, the React
35
- * Compiler, codegen, and user event signal settings, and the `future` block opting into behavior
36
- * that becomes the default in the next major version.
36
+ * Compiler, codegen, and user event signal settings, the `agents` and `mcp` blocks controlling what
37
+ * coding agents are given, the `future` block opting into behavior that becomes the default in the
38
+ * next major version, and the `deprecations` block silencing the warnings about flags left unset.
37
39
  */
38
40
  type Config = z.infer<typeof configSchema>;
39
41
  type ModuleExport = z.infer<typeof moduleExportSchema>;
40
42
  type ElementConfigEntry = z.infer<typeof elementConfigSchema>;
41
43
 
44
+ type McpSettings = {
45
+ tools: string[];
46
+ isReadOnly: boolean;
47
+ };
48
+
49
+ type ResolvedFuture = {
50
+ isByteArrayTyped: boolean;
51
+ isValueUnwrapped: boolean;
52
+ isFinishTrimmed: boolean;
53
+ isInoutInPlace: boolean;
54
+ isResourceImported: boolean;
55
+ isAdwaitaDefault: boolean;
56
+ isTreeShaken: boolean;
57
+ };
58
+
42
59
  /** Configuration reduced to the values the app runtime and the build need, with paths already resolved. */
43
60
  type ResolvedConfig = {
44
61
  /** The GApplication identifier the app registers under. */
@@ -184,12 +201,39 @@ const elementsSchema = z.object({
184
201
  config: z.record(z.string(), elementConfigSchema).optional(),
185
202
  });
186
203
 
204
+ const agentsSchema = z.object({
205
+ rules: z.boolean({ error: "must be a boolean" }).optional(),
206
+ reference: z.boolean({ error: "must be a boolean" }).optional(),
207
+ });
208
+
209
+ const mcpSchema = z.object({
210
+ tools: z
211
+ .array(z.string({ error: "must be a tool name pattern" }).min(1, { error: "must be a tool name pattern" }), {
212
+ error: "must be an array of tool name patterns",
213
+ })
214
+ .optional(),
215
+ readOnly: z.boolean({ error: "must be a boolean" }).optional(),
216
+ });
217
+
187
218
  const futureSchema = z.object({
188
219
  v2ByteArrays: z.boolean({ error: "must be a boolean" }).optional(),
189
220
  v2ValueReturns: z.boolean({ error: "must be a boolean" }).optional(),
190
221
  v2FinishResults: z.boolean({ error: "must be a boolean" }).optional(),
191
222
  v2InoutReturns: z.boolean({ error: "must be a boolean" }).optional(),
192
223
  v2ResourceImports: z.boolean({ error: "must be a boolean" }).optional(),
224
+ v2DefaultLibraries: z.boolean({ error: "must be a boolean" }).optional(),
225
+ v2TreeShaking: z.boolean({ error: "must be a boolean" }).optional(),
226
+ });
227
+
228
+ const FUTURE_KEYS: Set<string> = new Set(Object.keys(futureSchema.shape));
229
+ const DEPRECATION_ID_ERROR = `must be one of ${DEPRECATION_IDS.join(", ")}`;
230
+
231
+ const deprecationsSchema = z.object({
232
+ silence: z
233
+ .array(z.enum(DEPRECATION_IDS, { error: DEPRECATION_ID_ERROR }), {
234
+ error: "must be an array of deprecation ids",
235
+ })
236
+ .optional(),
193
237
  });
194
238
 
195
239
  /** Schema every `gtkx.config.ts` is validated against, and the source of the {@link Config} type. */
@@ -204,6 +248,9 @@ const configSchema = z.object({
204
248
  elements: elementsSchema.optional(),
205
249
  applicationIcon: text("must be a path to an icon theme directory or a single icon file").optional(),
206
250
  deploy: deploySchema.optional(),
251
+ agents: agentsSchema.optional(),
252
+ mcp: mcpSchema.optional(),
253
+ deprecations: deprecationsSchema.optional(),
207
254
  });
208
255
 
209
256
  /**
@@ -262,7 +309,7 @@ const validateConfig = (config: Config): void => {
262
309
  };
263
310
 
264
311
  /**
265
- * Deep-merges two configurations. `override` wins over `base` on conflicting scalar and object keys, while
312
+ * Deep-merges a configuration over a base. `override` wins over `base` on conflicting scalar and object keys, while
266
313
  * arrays are concatenated with the `override` entries first.
267
314
  */
268
315
  const mergeConfig = (base: Config, override: Config): Config => defu(override, base);
@@ -301,6 +348,27 @@ const resolveElementProps = (elements: Config["elements"]): Record<string, Modul
301
348
  const resolveOmittedProps = (elements: Config["elements"]): Record<string, string[]> =>
302
349
  elementEntryValues(elements, (entry) => entry.omittedProps);
303
350
 
351
+ const isAgentRulesEnabled = (config: Config): boolean => config.agents?.rules !== false;
352
+ const isAgentReferenceEnabled = (config: Config): boolean => config.agents?.reference !== false;
353
+
354
+ const resolveMcpSettings = (config: Config): McpSettings => ({
355
+ tools: config.mcp?.tools ?? [],
356
+ isReadOnly: config.mcp?.readOnly === true,
357
+ });
358
+
359
+ const resolveFuture = (future: Config["future"]): ResolvedFuture => ({
360
+ isByteArrayTyped: future?.v2ByteArrays === true,
361
+ isValueUnwrapped: future?.v2ValueReturns === true,
362
+ isFinishTrimmed: future?.v2FinishResults === true,
363
+ isInoutInPlace: future?.v2InoutReturns === true,
364
+ isResourceImported: future?.v2ResourceImports === true,
365
+ isAdwaitaDefault: future?.v2DefaultLibraries === true,
366
+ isTreeShaken: future?.v2TreeShaking === true,
367
+ });
368
+
369
+ const unknownFutureKeys = (future: Config["future"]): string[] =>
370
+ Object.keys(future ?? {}).filter((key) => !FUTURE_KEYS.has(key));
371
+
304
372
  const resolveConfig = (config: Config, root?: string): ResolvedConfig => ({
305
373
  applicationId: config.applicationId,
306
374
  reactCompiler: resolveReactCompilerOptions(config.reactCompiler),
@@ -312,15 +380,22 @@ const resolveConfig = (config: Config, root?: string): ResolvedConfig => ({
312
380
  export {
313
381
  APPLICATION_ID_MAX_LENGTH,
314
382
  defineConfig,
383
+ isAgentReferenceEnabled,
384
+ isAgentRulesEnabled,
315
385
  isValidApplicationId,
316
386
  validateConfig,
317
387
  mergeConfig,
318
388
  resolveLazyElements,
319
389
  resolveElementComponents,
320
390
  resolveElementProps,
391
+ resolveMcpSettings,
321
392
  resolveOmittedProps,
322
393
  resolveConfig,
394
+ resolveFuture,
395
+ unknownFutureKeys,
396
+ type McpSettings,
323
397
  type ResolvedReactCompilerOptions,
324
398
  type Config,
325
399
  type ResolvedConfig,
400
+ type ResolvedFuture,
326
401
  };
@@ -0,0 +1,130 @@
1
+ import { warn } from "@gtkx/utils";
2
+ import type { Config } from "./config.ts";
3
+
4
+ type DeprecationId = (typeof DEPRECATION_IDS)[number];
5
+
6
+ type FutureDeprecation = {
7
+ id: DeprecationId;
8
+ flag: keyof NonNullable<Config["future"]>;
9
+ change: string;
10
+ unchecked?: string;
11
+ };
12
+
13
+ const SHOWN_ENV = "GTKX_DEPRECATIONS_SHOWN";
14
+ const GUIDE_URL = "https://gtkx.dev/guide/upgrading-to-2";
15
+ const ENTRY_COLUMN = 30;
16
+ const BUILD_REPORTS = " The build, not tsc, reports the specifiers still to change.";
17
+ const NOTHING_REPORTS = " Nothing reports this one; check the app yourself.";
18
+ const SILENT_SITES = " `Array.isArray` and `JSON.stringify` change silently; grep for them.";
19
+
20
+ const DEPRECATION_IDS = [
21
+ "gtkx-v2-byte-arrays",
22
+ "gtkx-v2-value-returns",
23
+ "gtkx-v2-finish-results",
24
+ "gtkx-v2-inout-returns",
25
+ "gtkx-v2-resource-imports",
26
+ "gtkx-v2-default-libraries",
27
+ "gtkx-v2-tree-shaking",
28
+ ] as const;
29
+
30
+ const FUTURE_DEPRECATIONS: FutureDeprecation[] = [
31
+ {
32
+ id: "gtkx-v2-byte-arrays",
33
+ flag: "v2ByteArrays",
34
+ change: "Byte sequences come back as number[]. In 2.0 they come back as Uint8Array.",
35
+ unchecked: SILENT_SITES,
36
+ },
37
+ {
38
+ id: "gtkx-v2-value-returns",
39
+ flag: "v2ValueReturns",
40
+ change: "Bindings that return a GValue hand back the box. In 2.0 they hand back its contents, as unknown.",
41
+ },
42
+ {
43
+ id: "gtkx-v2-finish-results",
44
+ flag: "v2FinishResults",
45
+ change: "Async pairs with out parameters resolve with a leading success boolean. In 2.0 it is dropped.",
46
+ },
47
+ {
48
+ id: "gtkx-v2-inout-returns",
49
+ flag: "v2InoutReturns",
50
+ change: "Inout records repeat in the return value. In 2.0 the repeated entry is dropped.",
51
+ },
52
+ {
53
+ id: "gtkx-v2-resource-imports",
54
+ flag: "v2ResourceImports",
55
+ change: "Assets resolve through the #data/ import map. In 2.0 they resolve through ?resource imports.",
56
+ unchecked: BUILD_REPORTS,
57
+ },
58
+ {
59
+ id: "gtkx-v2-default-libraries",
60
+ flag: "v2DefaultLibraries",
61
+ change: "Only Gtk-4.0 is bound by default. In 2.0 Adw-1 is bound alongside it.",
62
+ unchecked: NOTHING_REPORTS,
63
+ },
64
+ {
65
+ id: "gtkx-v2-tree-shaking",
66
+ flag: "v2TreeShaking",
67
+ change:
68
+ "The stores register every class eagerly. " +
69
+ "In 2.0 each class registers itself and unused ones drop from bundles.",
70
+ },
71
+ ];
72
+
73
+ const shownRoots: Map<string, string> = new Map();
74
+
75
+ const isSilenced = (config: Config, id: DeprecationId): boolean => (config.deprecations?.silence ?? []).includes(id);
76
+
77
+ const unsetDeprecations = (config: Config): FutureDeprecation[] =>
78
+ FUTURE_DEPRECATIONS.filter((deprecation) => config.future?.[deprecation.flag] !== true);
79
+
80
+ const formatSummary = (unset: number, silenced: number): string => {
81
+ const note = silenced === 0 ? "" : ` ${String(silenced)} of them silenced here.`;
82
+
83
+ return (
84
+ `${String(unset)} of ${String(FUTURE_DEPRECATIONS.length)} future flags are unset. ` +
85
+ `Their behavior becomes the default in GTKX 2.0.${note}`
86
+ );
87
+ };
88
+
89
+ const formatDeprecation = (deprecation: FutureDeprecation): string =>
90
+ ` [${deprecation.id}]`.padEnd(ENTRY_COLUMN) +
91
+ `future: { ${deprecation.flag}: true }\n ${deprecation.change}` +
92
+ (deprecation.unchecked ?? "");
93
+
94
+ const formatAdvice = (pending: FutureDeprecation[]): string => {
95
+ if (pending.every((deprecation) => deprecation.unchecked === undefined)) {
96
+ return " Set one flag at a time and run tsc: every affected call site is a type error.";
97
+ }
98
+
99
+ return " Set one flag at a time and run tsc: it reports every affected call site except where noted above.";
100
+ };
101
+
102
+ const formatBlock = (unset: FutureDeprecation[], pending: FutureDeprecation[], first: FutureDeprecation): string =>
103
+ [
104
+ formatSummary(unset.length, unset.length - pending.length),
105
+ "",
106
+ ...pending.flatMap((deprecation) => [formatDeprecation(deprecation), ""]),
107
+ formatAdvice(pending),
108
+ ` Guide ${GUIDE_URL}`,
109
+ ` Silence deprecations: { silence: [${JSON.stringify(first.id)}] }`,
110
+ ].join("\n");
111
+
112
+ const hasShown = (root: string, signature: string): boolean =>
113
+ shownRoots.get(root) === signature || process.env[SHOWN_ENV] === signature;
114
+
115
+ const warnDeprecations = (config: Config, root: string): void => {
116
+ const unset = unsetDeprecations(config);
117
+ const pending = unset.filter((deprecation) => !isSilenced(config, deprecation.id));
118
+ const [first] = pending;
119
+ const signature = pending.map((deprecation) => deprecation.id).join(",");
120
+
121
+ if (first === undefined || hasShown(root, signature)) {
122
+ return;
123
+ }
124
+
125
+ shownRoots.set(root, signature);
126
+ process.env[SHOWN_ENV] = signature;
127
+ warn(formatBlock(unset, pending, first));
128
+ };
129
+
130
+ export { DEPRECATION_IDS, warnDeprecations };
package/src/internal.ts CHANGED
@@ -1,11 +1,16 @@
1
- export type { ResolvedReactCompilerOptions } from "./config.ts";
1
+ export type { McpSettings, ResolvedFuture, ResolvedReactCompilerOptions } from "./config.ts";
2
2
  export {
3
3
  APPLICATION_ID_MAX_LENGTH,
4
+ isAgentReferenceEnabled,
5
+ isAgentRulesEnabled,
4
6
  isValidApplicationId,
5
7
  resolveElementComponents,
6
8
  resolveElementProps,
9
+ resolveFuture,
7
10
  resolveLazyElements,
11
+ resolveMcpSettings,
8
12
  resolveOmittedProps,
13
+ unknownFutureKeys,
9
14
  } from "./config.ts";
10
15
  export { createConfigLoader } from "./loader.ts";
11
16
  export { resourceBasePath } from "./resource-base-path.ts";
package/src/loader.ts CHANGED
@@ -4,6 +4,7 @@ import { existsSync } from "node:fs";
4
4
  import { resolve } from "node:path";
5
5
  import { missingConfigFileError } from "./config-error.ts";
6
6
  import { type Config, resolveConfig, type ResolvedConfig, validateConfig } from "./config.ts";
7
+ import { warnDeprecations } from "./deprecations.ts";
7
8
 
8
9
  /** Result of loading a project's `gtkx.config.ts` file. */
9
10
  type LoadedConfig = {
@@ -33,7 +34,9 @@ type ConfigLoader = {
33
34
  };
34
35
 
35
36
  /**
36
- * Loads and validates the `gtkx.config.ts` file for a project.
37
+ * Loads and validates the `gtkx.config.ts` file for a project. Writes one deprecation notice to stderr the
38
+ * first time a configuration leaves a `future` flag unset, recording what it reported in the environment so
39
+ * a child process does not repeat it.
37
40
  * @param cwd Directory the configuration file is looked up in; parent directories are not searched.
38
41
  * @param options Loading options, such as the environment mode whose overrides are applied.
39
42
  * @throws When that directory holds no configuration file, or when the configuration fails validation.
@@ -58,12 +61,14 @@ const loadConfig = async (cwd: string, options: LoadConfigOptions = {}): Promise
58
61
  }
59
62
 
60
63
  const config = result.config;
64
+ const root = result.cwd ?? searched;
61
65
  validateConfig(config);
66
+ warnDeprecations(config, root);
62
67
 
63
68
  return {
64
69
  config,
65
70
  configFile,
66
- root: result.cwd ?? searched,
71
+ root,
67
72
  };
68
73
  };
69
74