@gtkx/config 1.6.0 → 2.0.0-beta.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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 +26 -46
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +47 -92
- 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 +1 -3
- package/dist/loader.d.ts.map +1 -1
- package/dist/loader.js +20 -9
- 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 +59 -165
- package/src/deploy.ts +1 -1
- package/src/index.ts +0 -2
- package/src/internal.ts +1 -3
- package/src/loader.ts +32 -9
- package/src/schema-text.ts +1 -1
- package/src/virtual.ts +1 -4
- package/dist/deprecations.d.ts +0 -5
- package/dist/deprecations.d.ts.map +0 -1
- package/dist/deprecations.js +0 -97
- package/dist/deprecations.js.map +0 -1
- package/src/deprecations.ts +0 -130
package/src/config.ts
CHANGED
|
@@ -2,23 +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 {
|
|
8
|
-
import { isGirLibrary, text } from "./schema-text.ts";
|
|
7
|
+
import { girLibrary, text } from "./schema-text.ts";
|
|
9
8
|
import { resolveUserEventSignals } from "./user-event-signals.ts";
|
|
10
9
|
|
|
11
|
-
/**
|
|
12
|
-
type ReactCompilerCompilationMode = (typeof COMPILATION_MODES)[number];
|
|
13
|
-
/** Accepted `reactCompiler.panicThreshold` values, choosing which compiler diagnostics fail the build. */
|
|
14
|
-
type ReactCompilerPanicThreshold = (typeof PANIC_THRESHOLDS)[number];
|
|
15
|
-
|
|
16
|
-
/** 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`. */
|
|
17
11
|
type ReactCompilerOptions = {
|
|
18
|
-
/** Which functions the compiler processes
|
|
19
|
-
compilationMode?:
|
|
20
|
-
/** Which compiler diagnostics fail the build
|
|
21
|
-
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];
|
|
22
16
|
};
|
|
23
17
|
|
|
24
18
|
/**
|
|
@@ -33,9 +27,8 @@ type ResolvedReactCompilerOptions = ReactCompilerOptions & {
|
|
|
33
27
|
/**
|
|
34
28
|
* User-facing configuration for a GTKX project, as authored in `gtkx.config.ts`: the GIR libraries
|
|
35
29
|
* to bind and where to find them, the GApplication id, per-element configuration, the React
|
|
36
|
-
* Compiler, codegen, and user event signal settings, the `agents` and `mcp` blocks controlling
|
|
37
|
-
* coding agents are given
|
|
38
|
-
* next major version, and the `deprecations` block silencing the warnings about flags left unset.
|
|
30
|
+
* Compiler, codegen, and user event signal settings, and the `agents` and `mcp` blocks controlling
|
|
31
|
+
* what coding agents are given.
|
|
39
32
|
*/
|
|
40
33
|
type Config = z.infer<typeof configSchema>;
|
|
41
34
|
type ModuleExport = z.infer<typeof moduleExportSchema>;
|
|
@@ -46,16 +39,6 @@ type McpSettings = {
|
|
|
46
39
|
isReadOnly: boolean;
|
|
47
40
|
};
|
|
48
41
|
|
|
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
|
-
|
|
59
42
|
/** Configuration reduced to the values the app runtime and the build need, with paths already resolved. */
|
|
60
43
|
type ResolvedConfig = {
|
|
61
44
|
/** The GApplication identifier the app registers under. */
|
|
@@ -73,92 +56,35 @@ type ResolvedConfig = {
|
|
|
73
56
|
lazyElements: string[];
|
|
74
57
|
};
|
|
75
58
|
|
|
76
|
-
const LIBRARIES_WILDCARD = "*";
|
|
77
59
|
const APPLICATION_ID_PATTERN = /^[A-Za-z_][A-Za-z0-9_-]*(\.[A-Za-z_][A-Za-z0-9_-]*)+$/;
|
|
78
60
|
const APPLICATION_ID_MAX_LENGTH = 255;
|
|
61
|
+
const DEFAULT_LIBRARIES: Set<string> = new Set(["Gtk-4.0", "Adw-1"]);
|
|
79
62
|
/** Compilation modes `babel-plugin-react-compiler` accepts. */
|
|
80
63
|
const COMPILATION_MODES = ["infer", "syntax", "annotation", "all"] as const;
|
|
81
64
|
/** Panic thresholds `babel-plugin-react-compiler` accepts. */
|
|
82
65
|
const PANIC_THRESHOLDS = ["none", "critical_errors", "all_errors"] as const;
|
|
83
66
|
const REACT_COMPILER_TARGET = "19";
|
|
84
|
-
const COMPILATION_MODE_SET: Set<string> = new Set(COMPILATION_MODES);
|
|
85
|
-
const PANIC_THRESHOLD_SET: Set<string> = new Set(PANIC_THRESHOLDS);
|
|
86
|
-
|
|
87
|
-
const librariesSchema = z.custom<typeof LIBRARIES_WILDCARD | string[]>().check((ctx) => {
|
|
88
|
-
const value = ctx.value;
|
|
89
|
-
|
|
90
|
-
if (value === LIBRARIES_WILDCARD) {
|
|
91
|
-
return;
|
|
92
|
-
}
|
|
93
67
|
|
|
94
|
-
|
|
95
|
-
|
|
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" });
|
|
96
70
|
|
|
97
|
-
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
for (const [index, entry] of value.entries()) {
|
|
101
|
-
ctx.issues.push(...libraryEntryIssues(value, index, entry));
|
|
102
|
-
}
|
|
103
|
-
});
|
|
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" });
|
|
104
74
|
|
|
105
|
-
const applicationIdSchema = z
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
rawIssue(
|
|
111
|
-
value,
|
|
112
|
-
[],
|
|
113
|
-
`invalid \`applicationId\` "${value}", must satisfy g_application_id_is_valid ` +
|
|
114
|
-
'(e.g. "org.example.MyApp")',
|
|
115
|
-
true,
|
|
116
|
-
),
|
|
117
|
-
);
|
|
118
|
-
}
|
|
119
|
-
});
|
|
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
|
+
});
|
|
120
80
|
|
|
121
|
-
const reactCompilerSchema = z.
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
if (!isRecord(value)) {
|
|
129
|
-
ctx.issues.push(rawIssue(value, [], "must be a boolean or an options object"));
|
|
130
|
-
|
|
131
|
-
return;
|
|
132
|
-
}
|
|
133
|
-
|
|
134
|
-
const compilationMode = value.compilationMode;
|
|
135
|
-
|
|
136
|
-
if (!isValidReactCompilerOption(compilationMode, COMPILATION_MODE_SET)) {
|
|
137
|
-
ctx.issues.push(
|
|
138
|
-
rawIssue(
|
|
139
|
-
value,
|
|
140
|
-
[],
|
|
141
|
-
`invalid \`reactCompiler.compilationMode\` "${String(compilationMode)}", ` +
|
|
142
|
-
`must be one of ${COMPILATION_MODES.join(", ")}`,
|
|
143
|
-
true,
|
|
144
|
-
),
|
|
145
|
-
);
|
|
146
|
-
}
|
|
147
|
-
|
|
148
|
-
const panicThreshold = value.panicThreshold;
|
|
149
|
-
|
|
150
|
-
if (!isValidReactCompilerOption(panicThreshold, PANIC_THRESHOLD_SET)) {
|
|
151
|
-
ctx.issues.push(
|
|
152
|
-
rawIssue(
|
|
153
|
-
value,
|
|
154
|
-
[],
|
|
155
|
-
`invalid \`reactCompiler.panicThreshold\` "${String(panicThreshold)}", ` +
|
|
156
|
-
`must be one of ${PANIC_THRESHOLDS.join(", ")}`,
|
|
157
|
-
true,
|
|
158
|
-
),
|
|
159
|
-
);
|
|
160
|
-
}
|
|
161
|
-
});
|
|
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
|
+
]);
|
|
162
88
|
|
|
163
89
|
const userEventSignalsSchema = z.record(
|
|
164
90
|
z.string(),
|
|
@@ -215,30 +141,28 @@ const mcpSchema = z.object({
|
|
|
215
141
|
readOnly: z.boolean({ error: "must be a boolean" }).optional(),
|
|
216
142
|
});
|
|
217
143
|
|
|
218
|
-
const
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
})
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
const DEPRECATION_ID_ERROR = `must be one of ${DEPRECATION_IDS.join(", ")}`;
|
|
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();
|
|
230
155
|
|
|
231
156
|
const deprecationsSchema = z.object({
|
|
232
157
|
silence: z
|
|
233
|
-
.array(z.
|
|
234
|
-
error: "must be an array of deprecation ids",
|
|
158
|
+
.array(z.never({ error: "does not name a current deprecation" }), {
|
|
159
|
+
error: "must be an array of current deprecation ids",
|
|
235
160
|
})
|
|
236
161
|
.optional(),
|
|
237
162
|
});
|
|
238
163
|
|
|
239
164
|
/** Schema every `gtkx.config.ts` is validated against, and the source of the {@link Config} type. */
|
|
240
165
|
const configSchema = z.object({
|
|
241
|
-
future: futureSchema.optional(),
|
|
242
166
|
libraries: librariesSchema.optional(),
|
|
243
167
|
girPath: z.array(z.string(), { error: "must be an array of strings if provided" }).optional(),
|
|
244
168
|
applicationId: applicationIdSchema,
|
|
@@ -258,34 +182,10 @@ const configSchema = z.object({
|
|
|
258
182
|
* autocompletion and type checking.
|
|
259
183
|
*/
|
|
260
184
|
const defineConfig: DefineConfig<Config> = createDefineConfig<Config>();
|
|
185
|
+
const validationSchema = configSchema.extend({ future: graduatedFutureSchema.optional() });
|
|
261
186
|
|
|
262
|
-
const
|
|
263
|
-
|
|
264
|
-
return [];
|
|
265
|
-
}
|
|
266
|
-
|
|
267
|
-
if (entry === LIBRARIES_WILDCARD) {
|
|
268
|
-
const message =
|
|
269
|
-
`to generate every library, set \`libraries: "${LIBRARIES_WILDCARD}"\` as a bare string, ` +
|
|
270
|
-
"not an array entry";
|
|
271
|
-
|
|
272
|
-
return [rawIssue(value, [index], message, true)];
|
|
273
|
-
}
|
|
274
|
-
|
|
275
|
-
const message =
|
|
276
|
-
`invalid library identifier "${String(entry)}", must be of the form "Name-Version" ` +
|
|
277
|
-
'(e.g. "Gtk-4.0")';
|
|
278
|
-
|
|
279
|
-
return [rawIssue(value, [index], message, true)];
|
|
280
|
-
};
|
|
281
|
-
|
|
282
|
-
const isValidApplicationId = (applicationId: string): boolean => {
|
|
283
|
-
if (applicationId.length === 0 || applicationId.length > APPLICATION_ID_MAX_LENGTH) {
|
|
284
|
-
return false;
|
|
285
|
-
}
|
|
286
|
-
|
|
287
|
-
return APPLICATION_ID_PATTERN.test(applicationId);
|
|
288
|
-
};
|
|
187
|
+
const isValidApplicationId = (applicationId: string): boolean =>
|
|
188
|
+
applicationId.length <= APPLICATION_ID_MAX_LENGTH && APPLICATION_ID_PATTERN.test(applicationId);
|
|
289
189
|
|
|
290
190
|
const resolveReactCompilerOptions = (setting: Config["reactCompiler"]): ResolvedReactCompilerOptions | null => {
|
|
291
191
|
if (setting === false) {
|
|
@@ -294,20 +194,29 @@ const resolveReactCompilerOptions = (setting: Config["reactCompiler"]): Resolved
|
|
|
294
194
|
|
|
295
195
|
const overrides = setting === undefined || setting === true ? {} : setting;
|
|
296
196
|
|
|
297
|
-
return {
|
|
197
|
+
return {
|
|
198
|
+
...(overrides.compilationMode !== undefined && { compilationMode: overrides.compilationMode }),
|
|
199
|
+
...(overrides.panicThreshold !== undefined && { panicThreshold: overrides.panicThreshold }),
|
|
200
|
+
target: REACT_COMPILER_TARGET,
|
|
201
|
+
};
|
|
298
202
|
};
|
|
299
203
|
|
|
300
|
-
const
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
const validateConfig = (config: Config): void => {
|
|
304
|
-
const result = configSchema.safeParse(config);
|
|
204
|
+
const validateConfig = (config: unknown): void => {
|
|
205
|
+
const result = validationSchema.safeParse(config);
|
|
305
206
|
|
|
306
207
|
if (!result.success) {
|
|
307
208
|
throw configError(result.error);
|
|
308
209
|
}
|
|
309
210
|
};
|
|
310
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
|
+
|
|
311
220
|
/**
|
|
312
221
|
* Deep-merges a configuration over a base. `override` wins over `base` on conflicting scalar and object keys, while
|
|
313
222
|
* arrays are concatenated with the `override` entries first.
|
|
@@ -356,19 +265,6 @@ const resolveMcpSettings = (config: Config): McpSettings => ({
|
|
|
356
265
|
isReadOnly: config.mcp?.readOnly === true,
|
|
357
266
|
});
|
|
358
267
|
|
|
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
|
-
|
|
372
268
|
const resolveConfig = (config: Config, root?: string): ResolvedConfig => ({
|
|
373
269
|
applicationId: config.applicationId,
|
|
374
270
|
reactCompiler: resolveReactCompilerOptions(config.reactCompiler),
|
|
@@ -383,6 +279,7 @@ export {
|
|
|
383
279
|
isAgentReferenceEnabled,
|
|
384
280
|
isAgentRulesEnabled,
|
|
385
281
|
isValidApplicationId,
|
|
282
|
+
graduatedFutureKeys,
|
|
386
283
|
validateConfig,
|
|
387
284
|
mergeConfig,
|
|
388
285
|
resolveLazyElements,
|
|
@@ -391,11 +288,8 @@ export {
|
|
|
391
288
|
resolveMcpSettings,
|
|
392
289
|
resolveOmittedProps,
|
|
393
290
|
resolveConfig,
|
|
394
|
-
resolveFuture,
|
|
395
|
-
unknownFutureKeys,
|
|
396
291
|
type McpSettings,
|
|
397
292
|
type ResolvedReactCompilerOptions,
|
|
398
293
|
type Config,
|
|
399
294
|
type ResolvedConfig,
|
|
400
|
-
type ResolvedFuture,
|
|
401
295
|
};
|
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,4 +1,4 @@
|
|
|
1
|
-
export type { McpSettings,
|
|
1
|
+
export type { McpSettings, ResolvedReactCompilerOptions } from "./config.ts";
|
|
2
2
|
export {
|
|
3
3
|
APPLICATION_ID_MAX_LENGTH,
|
|
4
4
|
isAgentReferenceEnabled,
|
|
@@ -6,11 +6,9 @@ export {
|
|
|
6
6
|
isValidApplicationId,
|
|
7
7
|
resolveElementComponents,
|
|
8
8
|
resolveElementProps,
|
|
9
|
-
resolveFuture,
|
|
10
9
|
resolveLazyElements,
|
|
11
10
|
resolveMcpSettings,
|
|
12
11
|
resolveOmittedProps,
|
|
13
|
-
unknownFutureKeys,
|
|
14
12
|
} from "./config.ts";
|
|
15
13
|
export { createConfigLoader } from "./loader.ts";
|
|
16
14
|
export { resourceBasePath } from "./resource-base-path.ts";
|
package/src/loader.ts
CHANGED
|
@@ -1,10 +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 {
|
|
7
|
-
|
|
6
|
+
import {
|
|
7
|
+
type Config,
|
|
8
|
+
graduatedFutureKeys,
|
|
9
|
+
resolveConfig,
|
|
10
|
+
type ResolvedConfig,
|
|
11
|
+
validateConfig,
|
|
12
|
+
} from "./config.ts";
|
|
8
13
|
|
|
9
14
|
/** Result of loading a project's `gtkx.config.ts` file. */
|
|
10
15
|
type LoadedConfig = {
|
|
@@ -33,10 +38,28 @@ type ConfigLoader = {
|
|
|
33
38
|
resolve: (cwd: string) => Promise<ResolvedConfig>;
|
|
34
39
|
};
|
|
35
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
|
+
|
|
36
61
|
/**
|
|
37
|
-
* Loads and validates the `gtkx.config.ts` file for a project.
|
|
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.
|
|
62
|
+
* Loads and validates the `gtkx.config.ts` file for a project.
|
|
40
63
|
* @param cwd Directory the configuration file is looked up in; parent directories are not searched.
|
|
41
64
|
* @param options Loading options, such as the environment mode whose overrides are applied.
|
|
42
65
|
* @throws When that directory holds no configuration file, or when the configuration fails validation.
|
|
@@ -63,7 +86,7 @@ const loadConfig = async (cwd: string, options: LoadConfigOptions = {}): Promise
|
|
|
63
86
|
const config = result.config;
|
|
64
87
|
const root = result.cwd ?? searched;
|
|
65
88
|
validateConfig(config);
|
|
66
|
-
|
|
89
|
+
warnGraduatedFuture(config, root);
|
|
67
90
|
|
|
68
91
|
return {
|
|
69
92
|
config,
|
|
@@ -77,7 +100,7 @@ const createConfigLoader = (options: LoadConfigOptions = {}): ConfigLoader => {
|
|
|
77
100
|
const resolved: Map<string, Promise<ResolvedConfig>> = new Map();
|
|
78
101
|
|
|
79
102
|
const load = (cwd: string): Promise<LoadedConfig> =>
|
|
80
|
-
|
|
103
|
+
loaded.getOrInsertComputed(resolve(cwd), (root) => loadConfig(root, options));
|
|
81
104
|
|
|
82
105
|
const resolveAt = async (root: string): Promise<ResolvedConfig> => {
|
|
83
106
|
const { config, root: configRoot } = await load(root);
|
|
@@ -87,7 +110,7 @@ const createConfigLoader = (options: LoadConfigOptions = {}): ConfigLoader => {
|
|
|
87
110
|
|
|
88
111
|
return {
|
|
89
112
|
load,
|
|
90
|
-
resolve: (cwd: string): Promise<ResolvedConfig> =>
|
|
113
|
+
resolve: (cwd: string): Promise<ResolvedConfig> => resolved.getOrInsertComputed(resolve(cwd), resolveAt),
|
|
91
114
|
};
|
|
92
115
|
};
|
|
93
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
|
package/dist/deprecations.d.ts
DELETED
|
@@ -1,5 +0,0 @@
|
|
|
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
|
|
@@ -1 +0,0 @@
|
|
|
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"}
|
package/dist/deprecations.js
DELETED
|
@@ -1,97 +0,0 @@
|
|
|
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
|
package/dist/deprecations.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
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"]}
|