@gtkx/config 1.5.0 → 2.0.0-beta.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +5 -5
- package/dist/config-error.d.ts +2 -13
- package/dist/config-error.d.ts.map +1 -1
- package/dist/config-error.js +3 -53
- package/dist/config-error.js.map +1 -1
- package/dist/config.d.ts +44 -24
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +73 -75
- package/dist/config.js.map +1 -1
- package/dist/deploy.js +1 -1
- package/dist/deploy.js.map +1 -1
- package/dist/index.d.ts +0 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +0 -2
- package/dist/index.js.map +1 -1
- package/dist/internal.d.ts +2 -2
- package/dist/internal.d.ts.map +1 -1
- package/dist/internal.js +1 -1
- package/dist/internal.js.map +1 -1
- package/dist/loader.d.ts.map +1 -1
- package/dist/loader.js +21 -5
- package/dist/loader.js.map +1 -1
- package/dist/schema-text.d.ts +1 -2
- package/dist/schema-text.d.ts.map +1 -1
- package/dist/schema-text.js +1 -1
- package/dist/schema-text.js.map +1 -1
- package/dist/virtual.d.ts.map +1 -1
- package/dist/virtual.js +1 -2
- package/dist/virtual.js.map +1 -1
- package/package.json +10 -4
- package/src/config-error.ts +3 -76
- package/src/config.ts +99 -130
- package/src/deploy.ts +1 -1
- package/src/index.ts +0 -2
- package/src/internal.ts +4 -1
- package/src/loader.ts +33 -5
- package/src/schema-text.ts +1 -1
- package/src/virtual.ts +1 -4
package/src/config.ts
CHANGED
|
@@ -2,22 +2,17 @@ import { createDefineConfig, type DefineConfig } from "c12";
|
|
|
2
2
|
import { defu } from "defu";
|
|
3
3
|
import { resolve } from "node:path";
|
|
4
4
|
import { z } from "zod";
|
|
5
|
-
import { configError, isRecord
|
|
5
|
+
import { configError, isRecord } from "./config-error.ts";
|
|
6
6
|
import { deploySchema } from "./deploy.ts";
|
|
7
|
-
import {
|
|
7
|
+
import { girLibrary, text } from "./schema-text.ts";
|
|
8
8
|
import { resolveUserEventSignals } from "./user-event-signals.ts";
|
|
9
9
|
|
|
10
|
-
/**
|
|
11
|
-
type ReactCompilerCompilationMode = (typeof COMPILATION_MODES)[number];
|
|
12
|
-
/** Accepted `reactCompiler.panicThreshold` values, choosing which compiler diagnostics fail the build. */
|
|
13
|
-
type ReactCompilerPanicThreshold = (typeof PANIC_THRESHOLDS)[number];
|
|
14
|
-
|
|
15
|
-
/** Object form of the `reactCompiler` config key, forwarded as-is to `babel-plugin-react-compiler`. */
|
|
10
|
+
/** Object form of the `reactCompiler` config key, forwarded to `babel-plugin-react-compiler`. */
|
|
16
11
|
type ReactCompilerOptions = {
|
|
17
|
-
/** Which functions the compiler processes
|
|
18
|
-
compilationMode?:
|
|
19
|
-
/** Which compiler diagnostics fail the build
|
|
20
|
-
panicThreshold?:
|
|
12
|
+
/** Which functions the compiler processes. */
|
|
13
|
+
compilationMode?: (typeof COMPILATION_MODES)[number];
|
|
14
|
+
/** Which compiler diagnostics fail the build. */
|
|
15
|
+
panicThreshold?: (typeof PANIC_THRESHOLDS)[number];
|
|
21
16
|
};
|
|
22
17
|
|
|
23
18
|
/**
|
|
@@ -32,13 +27,18 @@ type ResolvedReactCompilerOptions = ReactCompilerOptions & {
|
|
|
32
27
|
/**
|
|
33
28
|
* User-facing configuration for a GTKX project, as authored in `gtkx.config.ts`: the GIR libraries
|
|
34
29
|
* 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 `
|
|
36
|
-
*
|
|
30
|
+
* Compiler, codegen, and user event signal settings, and the `agents` and `mcp` blocks controlling
|
|
31
|
+
* what coding agents are given.
|
|
37
32
|
*/
|
|
38
33
|
type Config = z.infer<typeof configSchema>;
|
|
39
34
|
type ModuleExport = z.infer<typeof moduleExportSchema>;
|
|
40
35
|
type ElementConfigEntry = z.infer<typeof elementConfigSchema>;
|
|
41
36
|
|
|
37
|
+
type McpSettings = {
|
|
38
|
+
tools: string[];
|
|
39
|
+
isReadOnly: boolean;
|
|
40
|
+
};
|
|
41
|
+
|
|
42
42
|
/** Configuration reduced to the values the app runtime and the build need, with paths already resolved. */
|
|
43
43
|
type ResolvedConfig = {
|
|
44
44
|
/** The GApplication identifier the app registers under. */
|
|
@@ -56,92 +56,35 @@ type ResolvedConfig = {
|
|
|
56
56
|
lazyElements: string[];
|
|
57
57
|
};
|
|
58
58
|
|
|
59
|
-
const LIBRARIES_WILDCARD = "*";
|
|
60
59
|
const APPLICATION_ID_PATTERN = /^[A-Za-z_][A-Za-z0-9_-]*(\.[A-Za-z_][A-Za-z0-9_-]*)+$/;
|
|
61
60
|
const APPLICATION_ID_MAX_LENGTH = 255;
|
|
61
|
+
const DEFAULT_LIBRARIES: Set<string> = new Set(["Gtk-4.0", "Adw-1"]);
|
|
62
62
|
/** Compilation modes `babel-plugin-react-compiler` accepts. */
|
|
63
63
|
const COMPILATION_MODES = ["infer", "syntax", "annotation", "all"] as const;
|
|
64
64
|
/** Panic thresholds `babel-plugin-react-compiler` accepts. */
|
|
65
65
|
const PANIC_THRESHOLDS = ["none", "critical_errors", "all_errors"] as const;
|
|
66
66
|
const REACT_COMPILER_TARGET = "19";
|
|
67
|
-
const COMPILATION_MODE_SET: Set<string> = new Set(COMPILATION_MODES);
|
|
68
|
-
const PANIC_THRESHOLD_SET: Set<string> = new Set(PANIC_THRESHOLDS);
|
|
69
67
|
|
|
70
|
-
const
|
|
71
|
-
|
|
68
|
+
const librarySchema = girLibrary('must be of the form "Name-Version", such as "Gtk-4.0"')
|
|
69
|
+
.refine((library) => !DEFAULT_LIBRARIES.has(library), { error: "is bound by default; remove it" });
|
|
72
70
|
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
}
|
|
71
|
+
const librariesSchema = z
|
|
72
|
+
.array(librarySchema, { error: "must be a non-empty string array or omitted" })
|
|
73
|
+
.min(1, { error: "must be a non-empty string array or omitted" });
|
|
76
74
|
|
|
77
|
-
|
|
78
|
-
|
|
75
|
+
const applicationIdSchema = z
|
|
76
|
+
.string({ error: "must satisfy g_application_id_is_valid" })
|
|
77
|
+
.refine((value) => isValidApplicationId(value), {
|
|
78
|
+
error: 'must satisfy g_application_id_is_valid, such as "org.example.MyApp"',
|
|
79
|
+
});
|
|
79
80
|
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
const applicationIdSchema = z.custom<string>().check((ctx) => {
|
|
89
|
-
const value = ctx.value;
|
|
90
|
-
|
|
91
|
-
if (typeof value !== "string" || !isValidApplicationId(value)) {
|
|
92
|
-
ctx.issues.push(
|
|
93
|
-
rawIssue(
|
|
94
|
-
value,
|
|
95
|
-
[],
|
|
96
|
-
`invalid \`applicationId\` "${value}", must satisfy g_application_id_is_valid ` +
|
|
97
|
-
'(e.g. "org.example.MyApp")',
|
|
98
|
-
true,
|
|
99
|
-
),
|
|
100
|
-
);
|
|
101
|
-
}
|
|
102
|
-
});
|
|
103
|
-
|
|
104
|
-
const reactCompilerSchema = z.custom<boolean | ReactCompilerOptions>().check((ctx) => {
|
|
105
|
-
const value = ctx.value;
|
|
106
|
-
|
|
107
|
-
if (typeof value === "boolean") {
|
|
108
|
-
return;
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
if (!isRecord(value)) {
|
|
112
|
-
ctx.issues.push(rawIssue(value, [], "must be a boolean or an options object"));
|
|
113
|
-
|
|
114
|
-
return;
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
const compilationMode = value.compilationMode;
|
|
118
|
-
|
|
119
|
-
if (!isValidReactCompilerOption(compilationMode, COMPILATION_MODE_SET)) {
|
|
120
|
-
ctx.issues.push(
|
|
121
|
-
rawIssue(
|
|
122
|
-
value,
|
|
123
|
-
[],
|
|
124
|
-
`invalid \`reactCompiler.compilationMode\` "${String(compilationMode)}", ` +
|
|
125
|
-
`must be one of ${COMPILATION_MODES.join(", ")}`,
|
|
126
|
-
true,
|
|
127
|
-
),
|
|
128
|
-
);
|
|
129
|
-
}
|
|
130
|
-
|
|
131
|
-
const panicThreshold = value.panicThreshold;
|
|
132
|
-
|
|
133
|
-
if (!isValidReactCompilerOption(panicThreshold, PANIC_THRESHOLD_SET)) {
|
|
134
|
-
ctx.issues.push(
|
|
135
|
-
rawIssue(
|
|
136
|
-
value,
|
|
137
|
-
[],
|
|
138
|
-
`invalid \`reactCompiler.panicThreshold\` "${String(panicThreshold)}", ` +
|
|
139
|
-
`must be one of ${PANIC_THRESHOLDS.join(", ")}`,
|
|
140
|
-
true,
|
|
141
|
-
),
|
|
142
|
-
);
|
|
143
|
-
}
|
|
144
|
-
});
|
|
81
|
+
const reactCompilerSchema = z.union([
|
|
82
|
+
z.boolean(),
|
|
83
|
+
z.object({
|
|
84
|
+
compilationMode: z.enum(COMPILATION_MODES).optional(),
|
|
85
|
+
panicThreshold: z.enum(PANIC_THRESHOLDS).optional(),
|
|
86
|
+
}),
|
|
87
|
+
]);
|
|
145
88
|
|
|
146
89
|
const userEventSignalsSchema = z.record(
|
|
147
90
|
z.string(),
|
|
@@ -184,17 +127,42 @@ const elementsSchema = z.object({
|
|
|
184
127
|
config: z.record(z.string(), elementConfigSchema).optional(),
|
|
185
128
|
});
|
|
186
129
|
|
|
187
|
-
const
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
130
|
+
const agentsSchema = z.object({
|
|
131
|
+
rules: z.boolean({ error: "must be a boolean" }).optional(),
|
|
132
|
+
reference: z.boolean({ error: "must be a boolean" }).optional(),
|
|
133
|
+
});
|
|
134
|
+
|
|
135
|
+
const mcpSchema = z.object({
|
|
136
|
+
tools: z
|
|
137
|
+
.array(z.string({ error: "must be a tool name pattern" }).min(1, { error: "must be a tool name pattern" }), {
|
|
138
|
+
error: "must be an array of tool name patterns",
|
|
139
|
+
})
|
|
140
|
+
.optional(),
|
|
141
|
+
readOnly: z.boolean({ error: "must be a boolean" }).optional(),
|
|
142
|
+
});
|
|
143
|
+
|
|
144
|
+
const graduatedFutureSchema = z
|
|
145
|
+
.object({
|
|
146
|
+
v2ByteArrays: z.literal(true, { error: "can only be true; remove the flag" }).optional(),
|
|
147
|
+
v2ValueReturns: z.literal(true, { error: "can only be true; remove the flag" }).optional(),
|
|
148
|
+
v2FinishResults: z.literal(true, { error: "can only be true; remove the flag" }).optional(),
|
|
149
|
+
v2InoutReturns: z.literal(true, { error: "can only be true; remove the flag" }).optional(),
|
|
150
|
+
v2ResourceImports: z.literal(true, { error: "can only be true; remove the flag" }).optional(),
|
|
151
|
+
v2DefaultLibraries: z.literal(true, { error: "can only be true; remove the flag" }).optional(),
|
|
152
|
+
v2TreeShaking: z.literal(true, { error: "can only be true; remove the flag" }).optional(),
|
|
153
|
+
})
|
|
154
|
+
.strict();
|
|
155
|
+
|
|
156
|
+
const deprecationsSchema = z.object({
|
|
157
|
+
silence: z
|
|
158
|
+
.array(z.never({ error: "does not name a current deprecation" }), {
|
|
159
|
+
error: "must be an array of current deprecation ids",
|
|
160
|
+
})
|
|
161
|
+
.optional(),
|
|
193
162
|
});
|
|
194
163
|
|
|
195
164
|
/** Schema every `gtkx.config.ts` is validated against, and the source of the {@link Config} type. */
|
|
196
165
|
const configSchema = z.object({
|
|
197
|
-
future: futureSchema.optional(),
|
|
198
166
|
libraries: librariesSchema.optional(),
|
|
199
167
|
girPath: z.array(z.string(), { error: "must be an array of strings if provided" }).optional(),
|
|
200
168
|
applicationId: applicationIdSchema,
|
|
@@ -204,6 +172,9 @@ const configSchema = z.object({
|
|
|
204
172
|
elements: elementsSchema.optional(),
|
|
205
173
|
applicationIcon: text("must be a path to an icon theme directory or a single icon file").optional(),
|
|
206
174
|
deploy: deploySchema.optional(),
|
|
175
|
+
agents: agentsSchema.optional(),
|
|
176
|
+
mcp: mcpSchema.optional(),
|
|
177
|
+
deprecations: deprecationsSchema.optional(),
|
|
207
178
|
});
|
|
208
179
|
|
|
209
180
|
/**
|
|
@@ -211,34 +182,10 @@ const configSchema = z.object({
|
|
|
211
182
|
* autocompletion and type checking.
|
|
212
183
|
*/
|
|
213
184
|
const defineConfig: DefineConfig<Config> = createDefineConfig<Config>();
|
|
185
|
+
const validationSchema = configSchema.extend({ future: graduatedFutureSchema.optional() });
|
|
214
186
|
|
|
215
|
-
const
|
|
216
|
-
|
|
217
|
-
return [];
|
|
218
|
-
}
|
|
219
|
-
|
|
220
|
-
if (entry === LIBRARIES_WILDCARD) {
|
|
221
|
-
const message =
|
|
222
|
-
`to generate every library, set \`libraries: "${LIBRARIES_WILDCARD}"\` as a bare string, ` +
|
|
223
|
-
"not an array entry";
|
|
224
|
-
|
|
225
|
-
return [rawIssue(value, [index], message, true)];
|
|
226
|
-
}
|
|
227
|
-
|
|
228
|
-
const message =
|
|
229
|
-
`invalid library identifier "${String(entry)}", must be of the form "Name-Version" ` +
|
|
230
|
-
'(e.g. "Gtk-4.0")';
|
|
231
|
-
|
|
232
|
-
return [rawIssue(value, [index], message, true)];
|
|
233
|
-
};
|
|
234
|
-
|
|
235
|
-
const isValidApplicationId = (applicationId: string): boolean => {
|
|
236
|
-
if (applicationId.length === 0 || applicationId.length > APPLICATION_ID_MAX_LENGTH) {
|
|
237
|
-
return false;
|
|
238
|
-
}
|
|
239
|
-
|
|
240
|
-
return APPLICATION_ID_PATTERN.test(applicationId);
|
|
241
|
-
};
|
|
187
|
+
const isValidApplicationId = (applicationId: string): boolean =>
|
|
188
|
+
applicationId.length <= APPLICATION_ID_MAX_LENGTH && APPLICATION_ID_PATTERN.test(applicationId);
|
|
242
189
|
|
|
243
190
|
const resolveReactCompilerOptions = (setting: Config["reactCompiler"]): ResolvedReactCompilerOptions | null => {
|
|
244
191
|
if (setting === false) {
|
|
@@ -247,22 +194,31 @@ const resolveReactCompilerOptions = (setting: Config["reactCompiler"]): Resolved
|
|
|
247
194
|
|
|
248
195
|
const overrides = setting === undefined || setting === true ? {} : setting;
|
|
249
196
|
|
|
250
|
-
return {
|
|
197
|
+
return {
|
|
198
|
+
...(overrides.compilationMode !== undefined && { compilationMode: overrides.compilationMode }),
|
|
199
|
+
...(overrides.panicThreshold !== undefined && { panicThreshold: overrides.panicThreshold }),
|
|
200
|
+
target: REACT_COMPILER_TARGET,
|
|
201
|
+
};
|
|
251
202
|
};
|
|
252
203
|
|
|
253
|
-
const
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
const validateConfig = (config: Config): void => {
|
|
257
|
-
const result = configSchema.safeParse(config);
|
|
204
|
+
const validateConfig = (config: unknown): void => {
|
|
205
|
+
const result = validationSchema.safeParse(config);
|
|
258
206
|
|
|
259
207
|
if (!result.success) {
|
|
260
208
|
throw configError(result.error);
|
|
261
209
|
}
|
|
262
210
|
};
|
|
263
211
|
|
|
212
|
+
const graduatedFutureKeys = (config: unknown): string[] => {
|
|
213
|
+
if (!isRecord(config) || !isRecord(config.future)) {
|
|
214
|
+
return [];
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
return Object.keys(config.future).toSorted((first, second) => first.localeCompare(second));
|
|
218
|
+
};
|
|
219
|
+
|
|
264
220
|
/**
|
|
265
|
-
* Deep-merges
|
|
221
|
+
* Deep-merges a configuration over a base. `override` wins over `base` on conflicting scalar and object keys, while
|
|
266
222
|
* arrays are concatenated with the `override` entries first.
|
|
267
223
|
*/
|
|
268
224
|
const mergeConfig = (base: Config, override: Config): Config => defu(override, base);
|
|
@@ -301,6 +257,14 @@ const resolveElementProps = (elements: Config["elements"]): Record<string, Modul
|
|
|
301
257
|
const resolveOmittedProps = (elements: Config["elements"]): Record<string, string[]> =>
|
|
302
258
|
elementEntryValues(elements, (entry) => entry.omittedProps);
|
|
303
259
|
|
|
260
|
+
const isAgentRulesEnabled = (config: Config): boolean => config.agents?.rules !== false;
|
|
261
|
+
const isAgentReferenceEnabled = (config: Config): boolean => config.agents?.reference !== false;
|
|
262
|
+
|
|
263
|
+
const resolveMcpSettings = (config: Config): McpSettings => ({
|
|
264
|
+
tools: config.mcp?.tools ?? [],
|
|
265
|
+
isReadOnly: config.mcp?.readOnly === true,
|
|
266
|
+
});
|
|
267
|
+
|
|
304
268
|
const resolveConfig = (config: Config, root?: string): ResolvedConfig => ({
|
|
305
269
|
applicationId: config.applicationId,
|
|
306
270
|
reactCompiler: resolveReactCompilerOptions(config.reactCompiler),
|
|
@@ -312,14 +276,19 @@ const resolveConfig = (config: Config, root?: string): ResolvedConfig => ({
|
|
|
312
276
|
export {
|
|
313
277
|
APPLICATION_ID_MAX_LENGTH,
|
|
314
278
|
defineConfig,
|
|
279
|
+
isAgentReferenceEnabled,
|
|
280
|
+
isAgentRulesEnabled,
|
|
315
281
|
isValidApplicationId,
|
|
282
|
+
graduatedFutureKeys,
|
|
316
283
|
validateConfig,
|
|
317
284
|
mergeConfig,
|
|
318
285
|
resolveLazyElements,
|
|
319
286
|
resolveElementComponents,
|
|
320
287
|
resolveElementProps,
|
|
288
|
+
resolveMcpSettings,
|
|
321
289
|
resolveOmittedProps,
|
|
322
290
|
resolveConfig,
|
|
291
|
+
type McpSettings,
|
|
323
292
|
type ResolvedReactCompilerOptions,
|
|
324
293
|
type Config,
|
|
325
294
|
type ResolvedConfig,
|
package/src/deploy.ts
CHANGED
|
@@ -119,7 +119,7 @@ const extraFileEntrySchema = z.union([text(SOURCE_PATH_ERROR), extraFileSchema],
|
|
|
119
119
|
|
|
120
120
|
const nodeRuntimeSchema = z.strictObject({
|
|
121
121
|
source: z.enum(NODE_SOURCES, { error: "must be one of download, host, path" }).optional(),
|
|
122
|
-
version: text("must be a Node.js version such as
|
|
122
|
+
version: text("must be a Node.js version such as 26.7.0").optional(),
|
|
123
123
|
path: text("must be a path to a node binary").optional(),
|
|
124
124
|
shouldStrip: flag(BOOLEAN_ERROR).optional(),
|
|
125
125
|
shouldUseCompileCache: flag(BOOLEAN_ERROR).optional(),
|
package/src/index.ts
CHANGED
package/src/internal.ts
CHANGED
|
@@ -1,10 +1,13 @@
|
|
|
1
|
-
export type { ResolvedReactCompilerOptions } from "./config.ts";
|
|
1
|
+
export type { McpSettings, 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,
|
|
7
9
|
resolveLazyElements,
|
|
10
|
+
resolveMcpSettings,
|
|
8
11
|
resolveOmittedProps,
|
|
9
12
|
} from "./config.ts";
|
|
10
13
|
export { createConfigLoader } from "./loader.ts";
|
package/src/loader.ts
CHANGED
|
@@ -1,9 +1,15 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { warn } from "@gtkx/utils";
|
|
2
2
|
import { loadConfig as loadConfigFile } from "c12";
|
|
3
3
|
import { existsSync } from "node:fs";
|
|
4
4
|
import { resolve } from "node:path";
|
|
5
5
|
import { missingConfigFileError } from "./config-error.ts";
|
|
6
|
-
import {
|
|
6
|
+
import {
|
|
7
|
+
type Config,
|
|
8
|
+
graduatedFutureKeys,
|
|
9
|
+
resolveConfig,
|
|
10
|
+
type ResolvedConfig,
|
|
11
|
+
validateConfig,
|
|
12
|
+
} from "./config.ts";
|
|
7
13
|
|
|
8
14
|
/** Result of loading a project's `gtkx.config.ts` file. */
|
|
9
15
|
type LoadedConfig = {
|
|
@@ -32,6 +38,26 @@ type ConfigLoader = {
|
|
|
32
38
|
resolve: (cwd: string) => Promise<ResolvedConfig>;
|
|
33
39
|
};
|
|
34
40
|
|
|
41
|
+
const GRADUATED_FUTURE_ENV = "GTKX_GRADUATED_FUTURE_SHOWN";
|
|
42
|
+
const graduatedFutureWarnings: Map<string, string> = new Map();
|
|
43
|
+
|
|
44
|
+
const warnGraduatedFuture = (config: unknown, root: string): void => {
|
|
45
|
+
const keys = graduatedFutureKeys(config);
|
|
46
|
+
const signature = keys.join(",");
|
|
47
|
+
|
|
48
|
+
if (
|
|
49
|
+
keys.length === 0 ||
|
|
50
|
+
graduatedFutureWarnings.get(root) === signature ||
|
|
51
|
+
process.env[GRADUATED_FUTURE_ENV] === signature
|
|
52
|
+
) {
|
|
53
|
+
return;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
graduatedFutureWarnings.set(root, signature);
|
|
57
|
+
process.env[GRADUATED_FUTURE_ENV] = signature;
|
|
58
|
+
warn(`GTKX 2 ignores graduated future flags: ${keys.join(", ")}. Remove them from gtkx.config.ts.`);
|
|
59
|
+
};
|
|
60
|
+
|
|
35
61
|
/**
|
|
36
62
|
* Loads and validates the `gtkx.config.ts` file for a project.
|
|
37
63
|
* @param cwd Directory the configuration file is looked up in; parent directories are not searched.
|
|
@@ -58,12 +84,14 @@ const loadConfig = async (cwd: string, options: LoadConfigOptions = {}): Promise
|
|
|
58
84
|
}
|
|
59
85
|
|
|
60
86
|
const config = result.config;
|
|
87
|
+
const root = result.cwd ?? searched;
|
|
61
88
|
validateConfig(config);
|
|
89
|
+
warnGraduatedFuture(config, root);
|
|
62
90
|
|
|
63
91
|
return {
|
|
64
92
|
config,
|
|
65
93
|
configFile,
|
|
66
|
-
root
|
|
94
|
+
root,
|
|
67
95
|
};
|
|
68
96
|
};
|
|
69
97
|
|
|
@@ -72,7 +100,7 @@ const createConfigLoader = (options: LoadConfigOptions = {}): ConfigLoader => {
|
|
|
72
100
|
const resolved: Map<string, Promise<ResolvedConfig>> = new Map();
|
|
73
101
|
|
|
74
102
|
const load = (cwd: string): Promise<LoadedConfig> =>
|
|
75
|
-
|
|
103
|
+
loaded.getOrInsertComputed(resolve(cwd), (root) => loadConfig(root, options));
|
|
76
104
|
|
|
77
105
|
const resolveAt = async (root: string): Promise<ResolvedConfig> => {
|
|
78
106
|
const { config, root: configRoot } = await load(root);
|
|
@@ -82,7 +110,7 @@ const createConfigLoader = (options: LoadConfigOptions = {}): ConfigLoader => {
|
|
|
82
110
|
|
|
83
111
|
return {
|
|
84
112
|
load,
|
|
85
|
-
resolve: (cwd: string): Promise<ResolvedConfig> =>
|
|
113
|
+
resolve: (cwd: string): Promise<ResolvedConfig> => resolved.getOrInsertComputed(resolve(cwd), resolveAt),
|
|
86
114
|
};
|
|
87
115
|
};
|
|
88
116
|
|
package/src/schema-text.ts
CHANGED
|
@@ -40,4 +40,4 @@ const relativePathRecord = <Value extends z.ZodType>(
|
|
|
40
40
|
recordMessage: string,
|
|
41
41
|
): z.ZodRecord<z.ZodString, Value> => z.record(relativePath(keyMessage), value, { error: recordMessage });
|
|
42
42
|
|
|
43
|
-
export { fileExtension, flag, girLibrary,
|
|
43
|
+
export { fileExtension, flag, girLibrary, relativePathRecord, text, textList, textRecord, url };
|
package/src/virtual.ts
CHANGED
|
@@ -5,11 +5,8 @@ const GTKX_CONFIG_VIRTUAL_ID = "virtual:gtkx-config";
|
|
|
5
5
|
const RESOLVED_GTKX_CONFIG_VIRTUAL_ID = `\0${GTKX_CONFIG_VIRTUAL_ID}`;
|
|
6
6
|
const METADATA_SPECIFIER = "@gtkx/jsx/metadata";
|
|
7
7
|
|
|
8
|
-
const lazyElementConfig = (lazyElements: string[]): Record<string, { isLazy: boolean }> =>
|
|
9
|
-
Object.fromEntries(lazyElements.map((type) => [type, { isLazy: true }]));
|
|
10
|
-
|
|
11
8
|
const renderConfigModule = (config: ResolvedConfig): string => {
|
|
12
|
-
const lazyJson = JSON.stringify(
|
|
9
|
+
const lazyJson = JSON.stringify(Object.fromEntries(config.lazyElements.map((type) => [type, { isLazy: true }])));
|
|
13
10
|
|
|
14
11
|
const behaviorImports =
|
|
15
12
|
config.elements === null
|