@gtkx/config 1.6.0 → 2.0.0-beta.2
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 +29 -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.d.ts +3 -0
- package/dist/deploy.d.ts.map +1 -1
- package/dist/deploy.js +22 -3
- 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 +3 -2
- package/dist/internal.d.ts.map +1 -1
- package/dist/internal.js +2 -1
- package/dist/internal.js.map +1 -1
- package/dist/loader.d.ts +2 -4
- package/dist/loader.d.ts.map +1 -1
- package/dist/loader.js +35 -9
- package/dist/loader.js.map +1 -1
- package/dist/node-version.d.ts +4 -0
- package/dist/node-version.d.ts.map +1 -0
- package/dist/node-version.js +12 -0
- package/dist/node-version.js.map +1 -0
- 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 +31 -3
- package/src/index.ts +0 -2
- package/src/internal.ts +2 -3
- package/src/loader.ts +52 -10
- package/src/node-version.ts +16 -0
- 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/loader.ts
CHANGED
|
@@ -1,10 +1,16 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { isPathInside, 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";
|
|
13
|
+
import { assertSupportedNodeVersion } from "./node-version.ts";
|
|
8
14
|
|
|
9
15
|
/** Result of loading a project's `gtkx.config.ts` file. */
|
|
10
16
|
type LoadedConfig = {
|
|
@@ -23,7 +29,7 @@ type LoadConfigOptions = {
|
|
|
23
29
|
* top-level values, and the name is passed to a config authored as a function.
|
|
24
30
|
*/
|
|
25
31
|
mode?: string | undefined;
|
|
26
|
-
}
|
|
32
|
+
} & Partial<Record<"configFile", string | undefined>>;
|
|
27
33
|
|
|
28
34
|
/** Reads a project's configuration once per directory, caching what it loads and what it resolves. */
|
|
29
35
|
type ConfigLoader = {
|
|
@@ -33,16 +39,50 @@ type ConfigLoader = {
|
|
|
33
39
|
resolve: (cwd: string) => Promise<ResolvedConfig>;
|
|
34
40
|
};
|
|
35
41
|
|
|
42
|
+
const GRADUATED_FUTURE_ENV = "GTKX_GRADUATED_FUTURE_SHOWN";
|
|
43
|
+
const graduatedFutureWarnings: Map<string, string> = new Map();
|
|
44
|
+
|
|
45
|
+
const selectedConfigFile = (root: string, configured: string | undefined): string | undefined => {
|
|
46
|
+
if (configured === undefined) {
|
|
47
|
+
return undefined;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
const path = resolve(root, configured);
|
|
51
|
+
|
|
52
|
+
if (!isPathInside(root, path)) {
|
|
53
|
+
throw new Error(`Configuration file ${configured} must be inside the project root ${root}`);
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
return path;
|
|
57
|
+
};
|
|
58
|
+
|
|
59
|
+
const warnGraduatedFuture = (config: unknown, root: string): void => {
|
|
60
|
+
const keys = graduatedFutureKeys(config);
|
|
61
|
+
const signature = keys.join(",");
|
|
62
|
+
|
|
63
|
+
if (
|
|
64
|
+
keys.length === 0 ||
|
|
65
|
+
graduatedFutureWarnings.get(root) === signature ||
|
|
66
|
+
process.env[GRADUATED_FUTURE_ENV] === signature
|
|
67
|
+
) {
|
|
68
|
+
return;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
graduatedFutureWarnings.set(root, signature);
|
|
72
|
+
process.env[GRADUATED_FUTURE_ENV] = signature;
|
|
73
|
+
warn(`GTKX 2 ignores graduated future flags: ${keys.join(", ")}. Remove them from gtkx.config.ts.`);
|
|
74
|
+
};
|
|
75
|
+
|
|
36
76
|
/**
|
|
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.
|
|
77
|
+
* Loads and validates the `gtkx.config.ts` file for a project.
|
|
40
78
|
* @param cwd Directory the configuration file is looked up in; parent directories are not searched.
|
|
41
79
|
* @param options Loading options, such as the environment mode whose overrides are applied.
|
|
42
80
|
* @throws When that directory holds no configuration file, or when the configuration fails validation.
|
|
43
81
|
*/
|
|
44
82
|
const loadConfig = async (cwd: string, options: LoadConfigOptions = {}): Promise<LoadedConfig> => {
|
|
83
|
+
assertSupportedNodeVersion();
|
|
45
84
|
const searched = resolve(cwd);
|
|
85
|
+
const requestedConfigFile = selectedConfigFile(searched, options.configFile);
|
|
46
86
|
|
|
47
87
|
const result = await loadConfigFile<Config>({
|
|
48
88
|
name: "gtkx",
|
|
@@ -51,6 +91,7 @@ const loadConfig = async (cwd: string, options: LoadConfigOptions = {}): Promise
|
|
|
51
91
|
globalRc: false,
|
|
52
92
|
packageJson: false,
|
|
53
93
|
context: { mode: options.mode },
|
|
94
|
+
...(requestedConfigFile !== undefined && { configFile: requestedConfigFile }),
|
|
54
95
|
...((options.mode !== undefined) && { envName: options.mode }),
|
|
55
96
|
});
|
|
56
97
|
|
|
@@ -63,7 +104,7 @@ const loadConfig = async (cwd: string, options: LoadConfigOptions = {}): Promise
|
|
|
63
104
|
const config = result.config;
|
|
64
105
|
const root = result.cwd ?? searched;
|
|
65
106
|
validateConfig(config);
|
|
66
|
-
|
|
107
|
+
warnGraduatedFuture(config, root);
|
|
67
108
|
|
|
68
109
|
return {
|
|
69
110
|
config,
|
|
@@ -73,11 +114,12 @@ const loadConfig = async (cwd: string, options: LoadConfigOptions = {}): Promise
|
|
|
73
114
|
};
|
|
74
115
|
|
|
75
116
|
const createConfigLoader = (options: LoadConfigOptions = {}): ConfigLoader => {
|
|
117
|
+
assertSupportedNodeVersion();
|
|
76
118
|
const loaded: Map<string, Promise<LoadedConfig>> = new Map();
|
|
77
119
|
const resolved: Map<string, Promise<ResolvedConfig>> = new Map();
|
|
78
120
|
|
|
79
121
|
const load = (cwd: string): Promise<LoadedConfig> =>
|
|
80
|
-
|
|
122
|
+
loaded.getOrInsertComputed(resolve(cwd), (root) => loadConfig(root, options));
|
|
81
123
|
|
|
82
124
|
const resolveAt = async (root: string): Promise<ResolvedConfig> => {
|
|
83
125
|
const { config, root: configRoot } = await load(root);
|
|
@@ -87,7 +129,7 @@ const createConfigLoader = (options: LoadConfigOptions = {}): ConfigLoader => {
|
|
|
87
129
|
|
|
88
130
|
return {
|
|
89
131
|
load,
|
|
90
|
-
resolve: (cwd: string): Promise<ResolvedConfig> =>
|
|
132
|
+
resolve: (cwd: string): Promise<ResolvedConfig> => resolved.getOrInsertComputed(resolve(cwd), resolveAt),
|
|
91
133
|
};
|
|
92
134
|
};
|
|
93
135
|
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
const MINIMUM_NODE_MAJOR = 26;
|
|
2
|
+
const MINIMUM_NODE_MINOR = 7;
|
|
3
|
+
const MINIMUM_NODE_VERSION = "26.7.0";
|
|
4
|
+
|
|
5
|
+
const assertSupportedNodeVersion = (): void => {
|
|
6
|
+
const [major = 0, minor = 0] = process.versions.node.split(".").map(Number);
|
|
7
|
+
const isSupported = major > MINIMUM_NODE_MAJOR || (major === MINIMUM_NODE_MAJOR && minor >= MINIMUM_NODE_MINOR);
|
|
8
|
+
|
|
9
|
+
if (!isSupported) {
|
|
10
|
+
throw new Error(
|
|
11
|
+
`GTKX requires Node.js ${MINIMUM_NODE_VERSION} or newer. Current version: ${process.versions.node}.`,
|
|
12
|
+
);
|
|
13
|
+
}
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
export { assertSupportedNodeVersion, MINIMUM_NODE_VERSION };
|
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":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,aAAa,CAAC;AAYnC,MAAM,SAAS,GAAG,yBAAyB,CAAC;AAC5C,MAAM,SAAS,GAAG,uCAAuC,CAAC;AAC1D,MAAM,YAAY,GAAG,EAAE,CAAC;AACxB,MAAM,aAAa,GAAG,8DAA8D,CAAC;AACrF,MAAM,eAAe,GAAG,oDAAoD,CAAC;AAC7E,MAAM,YAAY,GAAG,uEAAuE,CAAC;AAE7F,MAAM,eAAe,GAAG;IACpB,qBAAqB;IACrB,uBAAuB;IACvB,wBAAwB;IACxB,uBAAuB;IACvB,0BAA0B;IAC1B,2BAA2B;IAC3B,sBAAsB;CAChB,CAAC;AAEX,MAAM,mBAAmB,GAAwB;IAC7C;QACI,EAAE,EAAE,qBAAqB;QACzB,IAAI,EAAE,cAAc;QACpB,MAAM,EAAE,4EAA4E;QACpF,SAAS,EAAE,YAAY;KAC1B;IACD;QACI,EAAE,EAAE,uBAAuB;QAC3B,IAAI,EAAE,gBAAgB;QACtB,MAAM,EAAE,kGAAkG;KAC7G;IACD;QACI,EAAE,EAAE,wBAAwB;QAC5B,IAAI,EAAE,iBAAiB;QACvB,MAAM,EAAE,+FAA+F;KAC1G;IACD;QACI,EAAE,EAAE,uBAAuB;QAC3B,IAAI,EAAE,gBAAgB;QACtB,MAAM,EAAE,iFAAiF;KAC5F;IACD;QACI,EAAE,EAAE,0BAA0B;QAC9B,IAAI,EAAE,mBAAmB;QACzB,MAAM,EAAE,8FAA8F;QACtG,SAAS,EAAE,aAAa;KAC3B;IACD;QACI,EAAE,EAAE,2BAA2B;QAC/B,IAAI,EAAE,oBAAoB;QAC1B,MAAM,EAAE,uEAAuE;QAC/E,SAAS,EAAE,eAAe;KAC7B;IACD;QACI,EAAE,EAAE,sBAAsB;QAC1B,IAAI,EAAE,eAAe;QACrB,MAAM,EACF,2CAA2C;YAC3C,uEAAuE;KAC9E;CACJ,CAAC;AAEF,MAAM,UAAU,GAAwB,IAAI,GAAG,EAAE,CAAC;AAElD,MAAM,UAAU,GAAG,CAAC,MAAc,EAAE,EAAiB,EAAW,EAAE,CAAC,CAAC,MAAM,CAAC,YAAY,EAAE,OAAO,IAAI,EAAE,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;AAErH,MAAM,iBAAiB,GAAG,CAAC,MAAc,EAAuB,EAAE,CAC9D,mBAAmB,CAAC,MAAM,CAAC,CAAC,WAAW,EAAE,EAAE,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC,WAAW,CAAC,IAAI,CAAC,KAAK,IAAI,CAAC,CAAC;AAE5F,MAAM,aAAa,GAAG,CAAC,KAAa,EAAE,QAAgB,EAAU,EAAE;IAC9D,MAAM,IAAI,GAAG,QAAQ,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,MAAM,CAAC,QAAQ,CAAC,yBAAyB,CAAC;IAEjF,OAAO,CACH,GAAG,MAAM,CAAC,KAAK,CAAC,OAAO,MAAM,CAAC,mBAAmB,CAAC,MAAM,CAAC,2BAA2B;QACpF,kDAAkD,IAAI,EAAE,CAC3D,CAAC;AACN,CAAC,CAAC;AAEF,MAAM,iBAAiB,GAAG,CAAC,WAA8B,EAAU,EAAE,CACjE,MAAM,WAAW,CAAC,EAAE,GAAG,CAAC,MAAM,CAAC,YAAY,CAAC;IAC5C,aAAa,WAAW,CAAC,IAAI,iBAAiB,WAAW,CAAC,MAAM,EAAE;IAClE,CAAC,WAAW,CAAC,SAAS,IAAI,EAAE,CAAC,CAAC;AAElC,MAAM,YAAY,GAAG,CAAC,OAA4B,EAAU,EAAE;IAC1D,IAAI,OAAO,CAAC,KAAK,CAAC,CAAC,WAAW,EAAE,EAAE,CAAC,WAAW,CAAC,SAAS,KAAK,SAAS,CAAC,EAAE,CAAC;QACtE,OAAO,iFAAiF,CAAC;IAC7F,CAAC;IAED,OAAO,qGAAqG,CAAC;AACjH,CAAC,CAAC;AAEF,MAAM,WAAW,GAAG,CAAC,KAA0B,EAAE,OAA4B,EAAE,KAAwB,EAAU,EAAE,CAC/G;IACI,aAAa,CAAC,KAAK,CAAC,MAAM,EAAE,KAAK,CAAC,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAC1D,EAAE;IACF,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC,WAAW,EAAE,EAAE,CAAC,CAAC,iBAAiB,CAAC,WAAW,CAAC,EAAE,EAAE,CAAC,CAAC;IACzE,YAAY,CAAC,OAAO,CAAC;IACrB,cAAc,SAAS,EAAE;IACzB,wCAAwC,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,EAAE,CAAC,KAAK;CACxE,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAEjB,MAAM,QAAQ,GAAG,CAAC,IAAY,EAAE,SAAiB,EAAW,EAAE,CAC1D,UAAU,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,SAAS,IAAI,OAAO,CAAC,GAAG,CAAC,SAAS,CAAC,KAAK,SAAS,CAAC;AAE/E,MAAM,gBAAgB,GAAG,CAAC,MAAc,EAAE,IAAY,EAAQ,EAAE;IAC5D,MAAM,KAAK,GAAG,iBAAiB,CAAC,MAAM,CAAC,CAAC;IACxC,MAAM,OAAO,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,WAAW,EAAE,EAAE,CAAC,CAAC,UAAU,CAAC,MAAM,EAAE,WAAW,CAAC,EAAE,CAAC,CAAC,CAAC;IACnF,MAAM,CAAC,KAAK,CAAC,GAAG,OAAO,CAAC;IACxB,MAAM,SAAS,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC,WAAW,EAAE,EAAE,CAAC,WAAW,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IAEzE,IAAI,KAAK,KAAK,SAAS,IAAI,QAAQ,CAAC,IAAI,EAAE,SAAS,CAAC,EAAE,CAAC;QACnD,OAAO;IACX,CAAC;IAED,UAAU,CAAC,GAAG,CAAC,IAAI,EAAE,SAAS,CAAC,CAAC;IAChC,OAAO,CAAC,GAAG,CAAC,SAAS,CAAC,GAAG,SAAS,CAAC;IACnC,IAAI,CAAC,WAAW,CAAC,KAAK,EAAE,OAAO,EAAE,KAAK,CAAC,CAAC,CAAC;AAC7C,CAAC,CAAC;AAEF,OAAO,EAAE,eAAe,EAAE,gBAAgB,EAAE,CAAC","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"]}
|
package/src/deprecations.ts
DELETED
|
@@ -1,130 +0,0 @@
|
|
|
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 };
|