@speedkit/cli 4.27.0 → 4.27.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.
Files changed (42) hide show
  1. package/CHANGELOG.md +14 -0
  2. package/README.md +46 -14
  3. package/dist/commands/auto-prewarm.d.ts +8 -3
  4. package/dist/commands/auto-prewarm.js +16 -7
  5. package/dist/commands/query/parameter.d.ts +2 -0
  6. package/dist/commands/query/parameter.js +2 -1
  7. package/dist/commands/query/prewarm.d.ts +2 -0
  8. package/dist/commands/query/prewarm.js +2 -1
  9. package/dist/helpers/clipboard.d.ts +6 -0
  10. package/dist/helpers/clipboard.js +7 -1
  11. package/dist/models/cli-parameters.d.ts +40 -1
  12. package/dist/models/cli-parameters.js +51 -7
  13. package/dist/services/athena/athena-service-factory.d.ts +8 -1
  14. package/dist/services/athena/athena-service-factory.js +15 -4
  15. package/dist/services/athena/athena-service-model.d.ts +17 -0
  16. package/dist/services/athena/athena-service-model.js +19 -0
  17. package/dist/services/athena/athena-service.d.ts +21 -1
  18. package/dist/services/athena/athena-service.js +21 -3
  19. package/dist/services/athena/athena-service.spec.js +36 -1
  20. package/dist/services/athena/baqend-athena-service.d.ts +13 -4
  21. package/dist/services/athena/baqend-athena-service.js +25 -10
  22. package/dist/services/athena/baqend-athena-service.spec.d.ts +1 -0
  23. package/dist/services/athena/baqend-athena-service.spec.js +51 -0
  24. package/dist/services/cli/cli-service.d.ts +9 -0
  25. package/dist/services/cli/cli-service.js +57 -3
  26. package/dist/services/cli/cli-service.spec.d.ts +1 -0
  27. package/dist/services/cli/cli-service.spec.js +67 -0
  28. package/dist/services/prewarm/auto-pre-warm-factory.d.ts +10 -0
  29. package/dist/services/prewarm/auto-pre-warm-factory.js +5 -0
  30. package/dist/services/query-builder/queries/page-source.d.ts +11 -2
  31. package/dist/services/query-builder/queries/page-source.js +15 -3
  32. package/dist/services/query-builder/queries/query-model.d.ts +2 -0
  33. package/dist/services/query-builder/queries/spec/queries.spec.js +17 -0
  34. package/dist/services/query-builder/query-builder-factory.js +2 -1
  35. package/dist/services/query-builder/query-builder-model.d.ts +6 -0
  36. package/dist/services/query-builder/query-builder-service.js +12 -7
  37. package/dist/services/query-builder/query-builder-service.spec.d.ts +1 -0
  38. package/dist/services/query-builder/query-builder-service.spec.js +65 -0
  39. package/dist/services/query-builder/query-command.d.ts +2 -0
  40. package/dist/services/query-builder/query-command.js +2 -0
  41. package/oclif.manifest.json +100 -19
  42. package/package.json +1 -1
package/CHANGELOG.md CHANGED
@@ -1,3 +1,17 @@
1
+ ## [4.27.2](https://gitlab.orestes.info/baqend/speed-kit-cli/compare/v4.27.1...v4.27.2) (2026-09-11)
2
+
3
+
4
+ ### Bug Fixes
5
+
6
+ * query define awsCatalog via --catalog, disable spinners while CI or not a tty ([e949dbb](https://gitlab.orestes.info/baqend/speed-kit-cli/commit/e949dbbaf73521267e03c4c043b393e76e174ece))
7
+
8
+ ## [4.27.1](https://gitlab.orestes.info/baqend/speed-kit-cli/compare/v4.27.0...v4.27.1) (2026-09-11)
9
+
10
+
11
+ ### Bug Fixes
12
+
13
+ * transfer flags from query:prewarm to auto-prewarm ([0dc4179](https://gitlab.orestes.info/baqend/speed-kit-cli/commit/0dc41795018edd86fdad4215e66218be28b91654))
14
+
1
15
  # [4.27.0](https://gitlab.orestes.info/baqend/speed-kit-cli/compare/v4.26.0...v4.27.0) (2026-09-11)
2
16
 
3
17
 
package/README.md CHANGED
@@ -21,7 +21,7 @@ $ npm install -g @speedkit/cli
21
21
  $ sk COMMAND
22
22
  running command...
23
23
  $ sk (--version)
24
- @speedkit/cli/4.27.0 linux-x64 node-v22.23.2
24
+ @speedkit/cli/4.27.2 linux-x64 node-v22.23.2
25
25
  $ sk --help [COMMAND]
26
26
  USAGE
27
27
  $ sk COMMAND
@@ -103,9 +103,10 @@ Build and execute the prewarm query for a customer config and start a prewarm jo
103
103
 
104
104
  ```
105
105
  USAGE
106
- $ sk auto-prewarm CUSTOMERPATH [-c <value>] [-d <value>] [--excludeNoindex] [--excludeSuspicious] [--explain]
107
- [--hardNavigationsOnly] [--match <value>...] [-p <value> | [--device desktop|mobile|tablet... | -v <value>...] | ]
108
- [-k] [-q] [--verbose]
106
+ $ sk auto-prewarm CUSTOMERPATH [--catalog <value>] [--workgroup <value>] [-c <value>] [-d <value>]
107
+ [--excludeNoindex] [--excludeSuspicious] [--explain] [--hardNavigationsOnly] [--excludeNotFound] [--limit <value>]
108
+ [--match <value>...] [--minHits <value>] [-p <value> | [--device desktop|mobile|tablet... | -v <value>...] | ] [-k]
109
+ [-q] [--verbose]
109
110
 
110
111
  ARGUMENTS
111
112
  CUSTOMERPATH The customer config path
@@ -118,18 +119,25 @@ FLAGS
118
119
  -q, --quiet less output non interactive
119
120
  -v, --variation=<value>... Pair every url of the list with each of these variations. For the custom variations no
120
121
  traffic can reveal, e.g. 'desktop-pdp-a,mobile-pdp-a'
122
+ --catalog=<value> [default: live, env: SK_ATHENA_CATALOG] Athena data catalog holding the rum tables. Names
123
+ the catalog both in the query and in the context it runs in, so the two always agree
121
124
  --device=<option>... Split the list by device class, so every url is warmed in the variations it was actually
122
125
  requested in. A class not named is left out
123
126
  <options: desktop|mobile|tablet>
124
127
  --excludeNoindex Exclude page impressions of pages marked noindex
128
+ --excludeNotFound Leave out urls the origin answers with a 404 more often than not
125
129
  --excludeSuspicious Exclude page impressions Speed Kit classified as suspicious
126
130
  --explain Account for every rule the query leaves out, reduces or approximates
127
131
  --hardNavigationsOnly Exclude soft (SPA) navigations
132
+ --limit=<value> Keep only the most requested urls
128
133
  --match=<value>... Keep only urls whose path matches this regular expression, e.g. '^/p/'. The path is
129
134
  matched with its query string, the way a version 1 pathname rule matches it, so
130
135
  '[?&]size=' works too. Repeat the flag to keep the urls matching any of several patterns,
131
136
  and start a pattern with (?i) to match case-insensitively
137
+ --minHits=<value> Keep only urls requested at least this often in the window
132
138
  --verbose Log information about failed requests
139
+ --workgroup=<value> [env: SK_ATHENA_WORKGROUP] Athena workgroup to run the query in, e.g. 'prewarming'.
140
+ Defaults to the account's default workgroup
133
141
 
134
142
  DESCRIPTION
135
143
  Build and execute the prewarm query for a customer config and start a prewarm job from the resulting URLs — no CSV
@@ -143,6 +151,10 @@ EXAMPLES
143
151
  $ sk auto-prewarm customers/decathlon.de --device desktop,mobile
144
152
 
145
153
  $ sk auto-prewarm customers/decathlon.de -v MOBILE,DESKTOP
154
+
155
+ $ sk auto-prewarm customers/decathlon.de --limit 5000 --minHits 5
156
+
157
+ $ sk auto-prewarm customers/decathlon.de --workgroup prewarming
146
158
  ```
147
159
 
148
160
  ## `sk autocomplete [SHELL]`
@@ -252,8 +264,9 @@ Build a parameter query that can be executed in Athena
252
264
 
253
265
  ```
254
266
  USAGE
255
- $ sk build-parameter-query CUSTOMERPATH [-c <value>] [-d <value>] [--excludeNoindex] [--excludeSuspicious] [--explain]
256
- [--hardNavigationsOnly] [-e] [-q] [--bySet] [--minImpressions <value>]
267
+ $ sk build-parameter-query CUSTOMERPATH [--catalog <value>] [--workgroup <value>] [-c <value>] [-d <value>]
268
+ [--excludeNoindex] [--excludeSuspicious] [--explain] [--hardNavigationsOnly] [-e] [-q] [--bySet] [--minImpressions
269
+ <value>]
257
270
 
258
271
  ARGUMENTS
259
272
  CUSTOMERPATH The customer config path
@@ -265,11 +278,16 @@ FLAGS
265
278
  -q, --quiet Output only the raw query without clipboard copy or styling
266
279
  --bySet Rank whole sets of parameters instead of single parameters, to see which ones travel
267
280
  together
281
+ --catalog=<value> [default: live, env: SK_ATHENA_CATALOG] Athena data catalog holding the rum tables.
282
+ Names the catalog both in the query and in the context it runs in, so the two always
283
+ agree
268
284
  --excludeNoindex Exclude page impressions of pages marked noindex
269
285
  --excludeSuspicious Exclude page impressions Speed Kit classified as suspicious
270
286
  --explain Account for every rule the query leaves out, reduces or approximates
271
287
  --hardNavigationsOnly Exclude soft (SPA) navigations
272
288
  --minImpressions=<value> Leave out parameters seen on fewer page impressions than this
289
+ --workgroup=<value> [env: SK_ATHENA_WORKGROUP] Athena workgroup to run the query in, e.g. 'prewarming'.
290
+ Defaults to the account's default workgroup
273
291
 
274
292
  DESCRIPTION
275
293
  Build a parameter query that can be executed in Athena
@@ -291,9 +309,9 @@ Build a prewarm query that can be executed in Athena
291
309
 
292
310
  ```
293
311
  USAGE
294
- $ sk build-prewarm-query CUSTOMERPATH [-c <value>] [-d <value>] [--excludeNoindex] [--excludeSuspicious] [--explain]
295
- [--hardNavigationsOnly] [-q] [--device desktop|mobile|tablet... | -v <value>...] [--count | -e] [--excludeNotFound]
296
- [--limit <value>] [--match <value>...] [--minHits <value>]
312
+ $ sk build-prewarm-query CUSTOMERPATH [--catalog <value>] [--workgroup <value>] [-c <value>] [-d <value>]
313
+ [--excludeNoindex] [--excludeSuspicious] [--explain] [--hardNavigationsOnly] [-q] [--device desktop|mobile|tablet...
314
+ | -v <value>...] [--excludeNotFound] [--limit <value>] [--match <value>...] [--minHits <value>] [--count | -e]
297
315
 
298
316
  ARGUMENTS
299
317
  CUSTOMERPATH The customer config path
@@ -305,6 +323,8 @@ FLAGS
305
323
  -q, --quiet Output only the raw query without clipboard copy or styling
306
324
  -v, --variation=<value>... Pair every url of the list with each of these variations. For the custom variations no
307
325
  traffic can reveal, e.g. 'desktop-pdp-a,mobile-pdp-a'
326
+ --catalog=<value> [default: live, env: SK_ATHENA_CATALOG] Athena data catalog holding the rum tables. Names
327
+ the catalog both in the query and in the context it runs in, so the two always agree
308
328
  --count Run the query and report how large the list is instead of what is in it: urls, the
309
329
  impressions they stand for, and a row per variation where the list carries variations.
310
330
  Every other flag still applies, so this counts the list the same command would produce
@@ -322,6 +342,8 @@ FLAGS
322
342
  '[?&]size=' works too. Repeat the flag to keep the urls matching any of several patterns,
323
343
  and start a pattern with (?i) to match case-insensitively
324
344
  --minHits=<value> Keep only urls requested at least this often in the window
345
+ --workgroup=<value> [env: SK_ATHENA_WORKGROUP] Athena workgroup to run the query in, e.g. 'prewarming'.
346
+ Defaults to the account's default workgroup
325
347
 
326
348
  DESCRIPTION
327
349
  Build a prewarm query that can be executed in Athena
@@ -825,8 +847,9 @@ Build a parameter query that can be executed in Athena
825
847
 
826
848
  ```
827
849
  USAGE
828
- $ sk query parameter CUSTOMERPATH [-c <value>] [-d <value>] [--excludeNoindex] [--excludeSuspicious] [--explain]
829
- [--hardNavigationsOnly] [-e] [-q] [--bySet] [--minImpressions <value>]
850
+ $ sk query parameter CUSTOMERPATH [--catalog <value>] [--workgroup <value>] [-c <value>] [-d <value>]
851
+ [--excludeNoindex] [--excludeSuspicious] [--explain] [--hardNavigationsOnly] [-e] [-q] [--bySet] [--minImpressions
852
+ <value>]
830
853
 
831
854
  ARGUMENTS
832
855
  CUSTOMERPATH The customer config path
@@ -838,11 +861,16 @@ FLAGS
838
861
  -q, --quiet Output only the raw query without clipboard copy or styling
839
862
  --bySet Rank whole sets of parameters instead of single parameters, to see which ones travel
840
863
  together
864
+ --catalog=<value> [default: live, env: SK_ATHENA_CATALOG] Athena data catalog holding the rum tables.
865
+ Names the catalog both in the query and in the context it runs in, so the two always
866
+ agree
841
867
  --excludeNoindex Exclude page impressions of pages marked noindex
842
868
  --excludeSuspicious Exclude page impressions Speed Kit classified as suspicious
843
869
  --explain Account for every rule the query leaves out, reduces or approximates
844
870
  --hardNavigationsOnly Exclude soft (SPA) navigations
845
871
  --minImpressions=<value> Leave out parameters seen on fewer page impressions than this
872
+ --workgroup=<value> [env: SK_ATHENA_WORKGROUP] Athena workgroup to run the query in, e.g. 'prewarming'.
873
+ Defaults to the account's default workgroup
846
874
 
847
875
  DESCRIPTION
848
876
  Build a parameter query that can be executed in Athena
@@ -864,9 +892,9 @@ Build a prewarm query that can be executed in Athena
864
892
 
865
893
  ```
866
894
  USAGE
867
- $ sk query prewarm CUSTOMERPATH [-c <value>] [-d <value>] [--excludeNoindex] [--excludeSuspicious] [--explain]
868
- [--hardNavigationsOnly] [-q] [--device desktop|mobile|tablet... | -v <value>...] [--count | -e] [--excludeNotFound]
869
- [--limit <value>] [--match <value>...] [--minHits <value>]
895
+ $ sk query prewarm CUSTOMERPATH [--catalog <value>] [--workgroup <value>] [-c <value>] [-d <value>]
896
+ [--excludeNoindex] [--excludeSuspicious] [--explain] [--hardNavigationsOnly] [-q] [--device desktop|mobile|tablet...
897
+ | -v <value>...] [--excludeNotFound] [--limit <value>] [--match <value>...] [--minHits <value>] [--count | -e]
870
898
 
871
899
  ARGUMENTS
872
900
  CUSTOMERPATH The customer config path
@@ -878,6 +906,8 @@ FLAGS
878
906
  -q, --quiet Output only the raw query without clipboard copy or styling
879
907
  -v, --variation=<value>... Pair every url of the list with each of these variations. For the custom variations no
880
908
  traffic can reveal, e.g. 'desktop-pdp-a,mobile-pdp-a'
909
+ --catalog=<value> [default: live, env: SK_ATHENA_CATALOG] Athena data catalog holding the rum tables. Names
910
+ the catalog both in the query and in the context it runs in, so the two always agree
881
911
  --count Run the query and report how large the list is instead of what is in it: urls, the
882
912
  impressions they stand for, and a row per variation where the list carries variations.
883
913
  Every other flag still applies, so this counts the list the same command would produce
@@ -895,6 +925,8 @@ FLAGS
895
925
  '[?&]size=' works too. Repeat the flag to keep the urls matching any of several patterns,
896
926
  and start a pattern with (?i) to match case-insensitively
897
927
  --minHits=<value> Keep only urls requested at least this often in the window
928
+ --workgroup=<value> [env: SK_ATHENA_WORKGROUP] Athena workgroup to run the query in, e.g. 'prewarming'.
929
+ Defaults to the account's default workgroup
898
930
 
899
931
  DESCRIPTION
900
932
  Build a prewarm query that can be executed in Athena
@@ -8,19 +8,24 @@ export default class AutoPrewarm extends Command {
8
8
  static description: string;
9
9
  static examples: string[];
10
10
  static flags: {
11
- match: import("@oclif/core/interfaces").OptionFlag<string[], import("@oclif/core/interfaces").CustomOptions>;
12
- device: import("@oclif/core/interfaces").OptionFlag<string[], import("@oclif/core/interfaces").CustomOptions>;
13
- variation: import("@oclif/core/interfaces").OptionFlag<string[], import("@oclif/core/interfaces").CustomOptions>;
14
11
  variationPath: import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
15
12
  keepParameterSorting: import("@oclif/core/interfaces").BooleanFlag<boolean>;
16
13
  quiet: import("@oclif/core/interfaces").BooleanFlag<boolean>;
17
14
  verbose: import("@oclif/core/interfaces").BooleanFlag<boolean>;
15
+ excludeNotFound: import("@oclif/core/interfaces").BooleanFlag<boolean>;
16
+ limit: import("@oclif/core/interfaces").OptionFlag<number, import("@oclif/core/interfaces").CustomOptions>;
17
+ match: import("@oclif/core/interfaces").OptionFlag<string[], import("@oclif/core/interfaces").CustomOptions>;
18
+ minHits: import("@oclif/core/interfaces").OptionFlag<number, import("@oclif/core/interfaces").CustomOptions>;
19
+ device: import("@oclif/core/interfaces").OptionFlag<string[], import("@oclif/core/interfaces").CustomOptions>;
20
+ variation: import("@oclif/core/interfaces").OptionFlag<string[], import("@oclif/core/interfaces").CustomOptions>;
18
21
  excludeNoindex: import("@oclif/core/interfaces").BooleanFlag<boolean>;
19
22
  excludeSuspicious: import("@oclif/core/interfaces").BooleanFlag<boolean>;
20
23
  explain: import("@oclif/core/interfaces").BooleanFlag<boolean>;
21
24
  hardNavigationsOnly: import("@oclif/core/interfaces").BooleanFlag<boolean>;
22
25
  days: import("@oclif/core/interfaces").OptionFlag<number, import("@oclif/core/interfaces").CustomOptions>;
23
26
  configName: import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
27
+ catalog: import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
28
+ workgroup: import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
24
29
  };
25
30
  run(): Promise<void>;
26
31
  }
@@ -1,5 +1,5 @@
1
1
  import { Command, Flags } from "@oclif/core";
2
- import { CLI_CONFIG_NAME, CLI_CUSTOMER_CONFIG, CLI_QUERY_DAYS, CLI_QUERY_FILTERS, CLI_QUERY_PREWARM, CLI_QUERY_VARIATIONS, CLIParameters, CLIParametersChar, CLIParametersExample, } from "../models/cli-parameters.js";
2
+ import { CLI_ATHENA, CLI_CONFIG_NAME, CLI_CUSTOMER_CONFIG, CLI_QUERY_DAYS, CLI_QUERY_FILTERS, CLI_QUERY_PREWARM_LIST, CLIParameters, CLIParametersChar, CLIParametersExample, } from "../models/cli-parameters.js";
3
3
  import { CliConfig } from "../helpers/cli-config.js";
4
4
  import { AutoPreWarmFactory } from "../services/prewarm/index.js";
5
5
  export default class AutoPrewarm extends Command {
@@ -10,16 +10,20 @@ export default class AutoPrewarm extends Command {
10
10
  `$ sk auto-prewarm ${CLIParametersExample.CustomerPath} -${CLIParametersChar.ConfigName} ${CLIParametersExample.ConfigName}`,
11
11
  `$ sk auto-prewarm ${CLIParametersExample.CustomerPath} --${CLIParameters.Device} ${CLIParametersExample.Devices}`,
12
12
  `$ sk auto-prewarm ${CLIParametersExample.CustomerPath} -${CLIParametersChar.Variation} ${CLIParametersExample.Variations}`,
13
+ `$ sk auto-prewarm ${CLIParametersExample.CustomerPath} --${CLIParameters.Limit} 5000 --${CLIParameters.MinHits} 5`,
14
+ `$ sk auto-prewarm ${CLIParametersExample.CustomerPath} --${CLIParameters.Workgroup} prewarming`,
13
15
  ];
14
16
  static flags = {
17
+ ...CLI_ATHENA,
15
18
  ...CLI_CONFIG_NAME,
16
19
  ...CLI_QUERY_DAYS,
17
20
  ...CLI_QUERY_FILTERS,
18
- // The same narrowing and the same splitting the query command offers; the
19
- // rest of the pre-warm flags shape a list this command does not write.
20
- [CLIParameters.Match]: CLI_QUERY_PREWARM[CLIParameters.Match],
21
- [CLIParameters.Device]: CLI_QUERY_VARIATIONS[CLIParameters.Device],
22
- [CLIParameters.Variation]: CLI_QUERY_VARIATIONS[CLIParameters.Variation],
21
+ // Every flag that shapes the pre-warm list, not a subset of them: this
22
+ // command builds the same query `sk query prewarm` does, and a list it
23
+ // could not narrow the same way could not be counted by that command
24
+ // either — the two would describe different runs. `--count` is not among
25
+ // them: this command warms the list rather than reporting its size.
26
+ ...CLI_QUERY_PREWARM_LIST,
23
27
  // A variations file says what `--variation` says, read from disk.
24
28
  [CLIParameters.VariationPath]: Flags.file({
25
29
  char: CLIParametersChar.VariationPath,
@@ -42,21 +46,26 @@ export default class AutoPrewarm extends Command {
42
46
  }),
43
47
  };
44
48
  async run() {
45
- const { args: { customerPath }, flags: { configName, days, device, excludeNoindex, excludeSuspicious, hardNavigationsOnly, keepParameterSorting, match, quiet, variation, variationPath, verbose, }, } = await this.parse(AutoPrewarm);
49
+ const { args: { customerPath }, flags: { configName, days, device, excludeNoindex, excludeNotFound, excludeSuspicious, hardNavigationsOnly, keepParameterSorting, limit, match, minHits, quiet, variation, variationPath, verbose, workgroup, catalog, }, } = await this.parse(AutoPrewarm);
46
50
  const service = await new AutoPreWarmFactory({
47
51
  customerPath,
48
52
  configName,
49
53
  days,
50
54
  device,
51
55
  excludeNoindex,
56
+ excludeNotFound,
52
57
  excludeSuspicious,
53
58
  hardNavigationsOnly,
59
+ limit,
54
60
  match,
61
+ minHits,
55
62
  variation,
56
63
  variationPath,
57
64
  sortParameters: !keepParameterSorting,
58
65
  quiet,
59
66
  verbose,
67
+ workgroup,
68
+ catalog,
60
69
  isWindows: this.config.windows,
61
70
  }, new CliConfig(this.config).load()).getService();
62
71
  await service.run();
@@ -21,6 +21,8 @@ export default class QueryParameter extends Command {
21
21
  hardNavigationsOnly: import("@oclif/core/interfaces").BooleanFlag<boolean>;
22
22
  days: import("@oclif/core/interfaces").OptionFlag<number, import("@oclif/core/interfaces").CustomOptions>;
23
23
  configName: import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
24
+ catalog: import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
25
+ workgroup: import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
24
26
  };
25
27
  run(): Promise<void>;
26
28
  }
@@ -1,5 +1,5 @@
1
1
  import { Command } from "@oclif/core";
2
- import { CLI_CONFIG_NAME, CLI_CUSTOMER_CONFIG, CLI_QUERY_DAYS, CLI_QUERY_FILTERS, CLI_QUERY_OUTPUT, CLI_QUERY_PARAMETER, CLIParameters, CLIParametersChar, CLIParametersExample, } from "../../models/cli-parameters.js";
2
+ import { CLI_ATHENA, CLI_CONFIG_NAME, CLI_CUSTOMER_CONFIG, CLI_QUERY_DAYS, CLI_QUERY_FILTERS, CLI_QUERY_OUTPUT, CLI_QUERY_PARAMETER, CLIParameters, CLIParametersChar, CLIParametersExample, } from "../../models/cli-parameters.js";
3
3
  import { QueryType } from "../../services/query-builder/query-builder-model.js";
4
4
  import { runQuery } from "../../services/query-builder/query-command.js";
5
5
  export default class QueryParameter extends Command {
@@ -14,6 +14,7 @@ export default class QueryParameter extends Command {
14
14
  `$ sk query parameter ${CLIParametersExample.CustomerPath} --${CLIParameters.Explain}`,
15
15
  ];
16
16
  static flags = {
17
+ ...CLI_ATHENA,
17
18
  ...CLI_CONFIG_NAME,
18
19
  ...CLI_QUERY_DAYS,
19
20
  ...CLI_QUERY_FILTERS,
@@ -26,6 +26,8 @@ export default class QueryPrewarm extends Command {
26
26
  hardNavigationsOnly: import("@oclif/core/interfaces").BooleanFlag<boolean>;
27
27
  days: import("@oclif/core/interfaces").OptionFlag<number, import("@oclif/core/interfaces").CustomOptions>;
28
28
  configName: import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
29
+ catalog: import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
30
+ workgroup: import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
29
31
  };
30
32
  run(): Promise<void>;
31
33
  }
@@ -1,5 +1,5 @@
1
1
  import { Command } from "@oclif/core";
2
- import { CLI_CONFIG_NAME, CLI_CUSTOMER_CONFIG, CLI_QUERY_DAYS, CLI_QUERY_FILTERS, CLI_QUERY_OUTPUT, CLI_QUERY_PREWARM, CLIParameters, CLIParametersChar, CLIParametersExample, } from "../../models/cli-parameters.js";
2
+ import { CLI_ATHENA, CLI_CONFIG_NAME, CLI_CUSTOMER_CONFIG, CLI_QUERY_DAYS, CLI_QUERY_FILTERS, CLI_QUERY_OUTPUT, CLI_QUERY_PREWARM, CLIParameters, CLIParametersChar, CLIParametersExample, } from "../../models/cli-parameters.js";
3
3
  import { QueryType } from "../../services/query-builder/query-builder-model.js";
4
4
  import { runQuery } from "../../services/query-builder/query-command.js";
5
5
  export default class QueryPrewarm extends Command {
@@ -18,6 +18,7 @@ export default class QueryPrewarm extends Command {
18
18
  `$ sk query prewarm ${CLIParametersExample.CustomerPath} --${CLIParameters.Count}`,
19
19
  ];
20
20
  static flags = {
21
+ ...CLI_ATHENA,
21
22
  ...CLI_CONFIG_NAME,
22
23
  ...CLI_QUERY_DAYS,
23
24
  ...CLI_QUERY_FILTERS,
@@ -14,6 +14,12 @@
14
14
  * behind a timeout, so no clipboard tool can ever be the reason a command
15
15
  * appears to do nothing.
16
16
  *
17
+ * `clipboardy` is loaded here rather than at module scope so that importing
18
+ * anything that can copy does not drag it in. It pulls a dependency that some
19
+ * Node/loader combinations refuse to resolve, which made every module on this
20
+ * path impossible to import from a test — and a clipboard that cannot load is
21
+ * already the case this function answers with `false`.
22
+ *
17
23
  * @returns whether the text reached the clipboard.
18
24
  */
19
25
  export declare function copyToClipboard(text: string): Promise<boolean>;
@@ -1,5 +1,4 @@
1
1
  import { spawn } from "node:child_process";
2
- import clipboardy from "clipboardy";
3
2
  /** How long a clipboard tool may take before the CLI stops waiting for it. */
4
3
  const TIMEOUT_IN_MS = 2000;
5
4
  /**
@@ -18,6 +17,12 @@ const TIMEOUT_IN_MS = 2000;
18
17
  * behind a timeout, so no clipboard tool can ever be the reason a command
19
18
  * appears to do nothing.
20
19
  *
20
+ * `clipboardy` is loaded here rather than at module scope so that importing
21
+ * anything that can copy does not drag it in. It pulls a dependency that some
22
+ * Node/loader combinations refuse to resolve, which made every module on this
23
+ * path impossible to import from a test — and a clipboard that cannot load is
24
+ * already the case this function answers with `false`.
25
+ *
21
26
  * @returns whether the text reached the clipboard.
22
27
  */
23
28
  export async function copyToClipboard(text) {
@@ -28,6 +33,7 @@ export async function copyToClipboard(text) {
28
33
  }
29
34
  }
30
35
  try {
36
+ const { default: clipboardy } = await import("clipboardy");
31
37
  return await withTimeout(clipboardy.write(text).then(() => true));
32
38
  }
33
39
  catch {
@@ -3,6 +3,7 @@ export declare enum CLIParameters {
3
3
  Artifacts = "artifacts",
4
4
  ConfigName = "configName",
5
5
  ContentTypes = "contentTypes",
6
+ Catalog = "catalog",
6
7
  Cookies = "cookies",
7
8
  Count = "count",
8
9
  CreateTests = "CreateTests",
@@ -38,6 +39,7 @@ export declare enum CLIParameters {
38
39
  Variation = "variation",
39
40
  VariationPath = "variationPath",
40
41
  Verbose = "verbose",
42
+ Workgroup = "workgroup",
41
43
  useTestConfig = "useTestConfig"
42
44
  }
43
45
  export declare enum CLIParametersChar {
@@ -136,7 +138,27 @@ export declare const CLI_QUERY_VARIATIONS: {
136
138
  device: import("@oclif/core/interfaces").OptionFlag<string[], import("@oclif/core/interfaces").CustomOptions>;
137
139
  variation: import("@oclif/core/interfaces").OptionFlag<string[], import("@oclif/core/interfaces").CustomOptions>;
138
140
  };
139
- /** What the pre-warm query keeps of a long tail that is mostly seen once. */
141
+ /**
142
+ * What the pre-warm query keeps of a long tail that is mostly seen once.
143
+ *
144
+ * Every flag here shapes the list itself, so a command that builds that list
145
+ * takes all of them — `sk auto-prewarm` included, or a count could describe a
146
+ * list the pre-warmer would never produce.
147
+ */
148
+ export declare const CLI_QUERY_PREWARM_LIST: {
149
+ excludeNotFound: import("@oclif/core/interfaces").BooleanFlag<boolean>;
150
+ limit: import("@oclif/core/interfaces").OptionFlag<number, import("@oclif/core/interfaces").CustomOptions>;
151
+ match: import("@oclif/core/interfaces").OptionFlag<string[], import("@oclif/core/interfaces").CustomOptions>;
152
+ minHits: import("@oclif/core/interfaces").OptionFlag<number, import("@oclif/core/interfaces").CustomOptions>;
153
+ device: import("@oclif/core/interfaces").OptionFlag<string[], import("@oclif/core/interfaces").CustomOptions>;
154
+ variation: import("@oclif/core/interfaces").OptionFlag<string[], import("@oclif/core/interfaces").CustomOptions>;
155
+ };
156
+ /**
157
+ * The pre-warm query flags in full: the list-shaping ones plus `--count`, which
158
+ * reports the list's size instead of returning it. Only a command that can
159
+ * answer with a count takes this one — `sk auto-prewarm` warms the list, so it
160
+ * takes {@link CLI_QUERY_PREWARM_LIST} instead.
161
+ */
140
162
  export declare const CLI_QUERY_PREWARM: {
141
163
  count: import("@oclif/core/interfaces").BooleanFlag<boolean>;
142
164
  excludeNotFound: import("@oclif/core/interfaces").BooleanFlag<boolean>;
@@ -146,6 +168,23 @@ export declare const CLI_QUERY_PREWARM: {
146
168
  device: import("@oclif/core/interfaces").OptionFlag<string[], import("@oclif/core/interfaces").CustomOptions>;
147
169
  variation: import("@oclif/core/interfaces").OptionFlag<string[], import("@oclif/core/interfaces").CustomOptions>;
148
170
  };
171
+ /**
172
+ * Where a query that is executed actually runs.
173
+ *
174
+ * The catalog is the account's, not the query's: our own logins reach the rum
175
+ * tables under `live`, while a role scoped to one account reaches the same
176
+ * tables under `AwsDataCatalog`. `SK_ATHENA_CATALOG` lets a CI job say so once.
177
+ *
178
+ * Athena resolves the account's default workgroup when none is named, which is
179
+ * only right where the credentials are allowed to use it — a role scoped to one
180
+ * workgroup is refused on any other, and the result location is a workgroup
181
+ * setting too. `SK_ATHENA_WORKGROUP` lets a CI job set it once for every
182
+ * command in the job.
183
+ */
184
+ export declare const CLI_ATHENA: {
185
+ catalog: import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
186
+ workgroup: import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
187
+ };
149
188
  /** How the parameter query presents what it found. */
150
189
  export declare const CLI_QUERY_PARAMETER: {
151
190
  bySet: import("@oclif/core/interfaces").BooleanFlag<boolean>;
@@ -4,12 +4,14 @@ import { Args, Flags } from "@oclif/core";
4
4
  // library.
5
5
  import { parseMatchPattern } from "../services/query-builder/rules/match-pattern.js";
6
6
  import { DEVICE_VARIATIONS } from "../services/query-builder/queries/device.js";
7
+ import { DEFAULT_ATHENA_CATALOG } from "../services/athena/athena-service-model.js";
7
8
  export var CLIParameters;
8
9
  (function (CLIParameters) {
9
10
  CLIParameters["AppName"] = "app";
10
11
  CLIParameters["Artifacts"] = "artifacts";
11
12
  CLIParameters["ConfigName"] = "configName";
12
13
  CLIParameters["ContentTypes"] = "contentTypes";
14
+ CLIParameters["Catalog"] = "catalog";
13
15
  CLIParameters["Cookies"] = "cookies";
14
16
  CLIParameters["Count"] = "count";
15
17
  CLIParameters["CreateTests"] = "CreateTests";
@@ -45,6 +47,7 @@ export var CLIParameters;
45
47
  CLIParameters["Variation"] = "variation";
46
48
  CLIParameters["VariationPath"] = "variationPath";
47
49
  CLIParameters["Verbose"] = "verbose";
50
+ CLIParameters["Workgroup"] = "workgroup";
48
51
  CLIParameters["useTestConfig"] = "useTestConfig";
49
52
  })(CLIParameters || (CLIParameters = {}));
50
53
  /* eslint-disable @typescript-eslint/no-duplicate-enum-values */
@@ -197,14 +200,15 @@ export const CLI_QUERY_VARIATIONS = {
197
200
  required: false,
198
201
  }),
199
202
  };
200
- /** What the pre-warm query keeps of a long tail that is mostly seen once. */
201
- export const CLI_QUERY_PREWARM = {
203
+ /**
204
+ * What the pre-warm query keeps of a long tail that is mostly seen once.
205
+ *
206
+ * Every flag here shapes the list itself, so a command that builds that list
207
+ * takes all of them — `sk auto-prewarm` included, or a count could describe a
208
+ * list the pre-warmer would never produce.
209
+ */
210
+ export const CLI_QUERY_PREWARM_LIST = {
202
211
  ...CLI_QUERY_VARIATIONS,
203
- [CLIParameters.Count]: Flags.boolean({
204
- default: false,
205
- description: "Run the query and report how large the list is instead of what is in it: urls, the impressions they stand for, and a row per variation where the list carries variations. Every other flag still applies, so this counts the list the same command would produce",
206
- exclusive: [CLIParameters.Execute],
207
- }),
208
212
  [CLIParameters.ExcludeNotFound]: Flags.boolean({
209
213
  default: false,
210
214
  description: "Leave out urls the origin answers with a 404 more often than not",
@@ -234,6 +238,46 @@ export const CLI_QUERY_PREWARM = {
234
238
  required: false,
235
239
  }),
236
240
  };
241
+ /**
242
+ * The pre-warm query flags in full: the list-shaping ones plus `--count`, which
243
+ * reports the list's size instead of returning it. Only a command that can
244
+ * answer with a count takes this one — `sk auto-prewarm` warms the list, so it
245
+ * takes {@link CLI_QUERY_PREWARM_LIST} instead.
246
+ */
247
+ export const CLI_QUERY_PREWARM = {
248
+ ...CLI_QUERY_PREWARM_LIST,
249
+ [CLIParameters.Count]: Flags.boolean({
250
+ default: false,
251
+ description: "Run the query and report how large the list is instead of what is in it: urls, the impressions they stand for, and a row per variation where the list carries variations. Every other flag still applies, so this counts the list the same command would produce",
252
+ exclusive: [CLIParameters.Execute],
253
+ }),
254
+ };
255
+ /**
256
+ * Where a query that is executed actually runs.
257
+ *
258
+ * The catalog is the account's, not the query's: our own logins reach the rum
259
+ * tables under `live`, while a role scoped to one account reaches the same
260
+ * tables under `AwsDataCatalog`. `SK_ATHENA_CATALOG` lets a CI job say so once.
261
+ *
262
+ * Athena resolves the account's default workgroup when none is named, which is
263
+ * only right where the credentials are allowed to use it — a role scoped to one
264
+ * workgroup is refused on any other, and the result location is a workgroup
265
+ * setting too. `SK_ATHENA_WORKGROUP` lets a CI job set it once for every
266
+ * command in the job.
267
+ */
268
+ export const CLI_ATHENA = {
269
+ [CLIParameters.Catalog]: Flags.string({
270
+ default: DEFAULT_ATHENA_CATALOG,
271
+ description: "Athena data catalog holding the rum tables. Names the catalog both in the query and in the context it runs in, so the two always agree",
272
+ env: "SK_ATHENA_CATALOG",
273
+ required: false,
274
+ }),
275
+ [CLIParameters.Workgroup]: Flags.string({
276
+ description: "Athena workgroup to run the query in, e.g. 'prewarming'. Defaults to the account's default workgroup",
277
+ env: "SK_ATHENA_WORKGROUP",
278
+ required: false,
279
+ }),
280
+ };
237
281
  /** How the parameter query presents what it found. */
238
282
  export const CLI_QUERY_PARAMETER = {
239
283
  [CLIParameters.BySet]: Flags.boolean({
@@ -1,13 +1,20 @@
1
1
  import { AthenaService } from "./athena-query-service.js";
2
2
  export declare class AthenaServiceFactory {
3
3
  private app?;
4
+ private workgroup?;
5
+ private catalog?;
4
6
  service?: AthenaService;
5
7
  /**
6
8
  * @param app - the app to query. Enables the Baqend native query path (app
7
9
  * token only) as a fallback when no AWS login is present. Without it, only
8
10
  * the AWS path is available.
11
+ * @param workgroup - Athena workgroup for the AWS path. The Baqend path has
12
+ * no such notion, so it is ignored there.
13
+ * @param catalog - the data catalog the tables live in. The Baqend path is
14
+ * told so it can recognise the prefix, not so it can use it: the server
15
+ * resolves the catalog itself.
9
16
  */
10
- constructor(app?: string);
17
+ constructor(app?: string, workgroup?: string, catalog?: string);
11
18
  getService(): Promise<AthenaService>;
12
19
  /**
13
20
  * Prefer direct AWS Athena whenever AWS credentials are present — they
@@ -8,14 +8,23 @@ import { BaqendAthenaService } from "./baqend-athena-service.js";
8
8
  import { EntityManagerFactory } from "../config-api/entity-manager-factory.js";
9
9
  export class AthenaServiceFactory {
10
10
  app;
11
+ workgroup;
12
+ catalog;
11
13
  service;
12
14
  /**
13
15
  * @param app - the app to query. Enables the Baqend native query path (app
14
16
  * token only) as a fallback when no AWS login is present. Without it, only
15
17
  * the AWS path is available.
18
+ * @param workgroup - Athena workgroup for the AWS path. The Baqend path has
19
+ * no such notion, so it is ignored there.
20
+ * @param catalog - the data catalog the tables live in. The Baqend path is
21
+ * told so it can recognise the prefix, not so it can use it: the server
22
+ * resolves the catalog itself.
16
23
  */
17
- constructor(app) {
24
+ constructor(app, workgroup, catalog) {
18
25
  this.app = app;
26
+ this.workgroup = workgroup;
27
+ this.catalog = catalog;
19
28
  }
20
29
  async getService() {
21
30
  if (!this.service) {
@@ -33,11 +42,13 @@ export class AthenaServiceFactory {
33
42
  const cli = new CliServiceFactory().getService();
34
43
  const client = await this.tryGetAthenaClient();
35
44
  if (client) {
36
- cli.comment("Using AWS credentials for Athena queries.");
37
- return new AwsAthenaService(client, cli);
45
+ cli.comment(this.workgroup
46
+ ? `Using AWS credentials for Athena queries, workgroup ${this.workgroup}.`
47
+ : "Using AWS credentials for Athena queries.");
48
+ return new AwsAthenaService(client, cli, this.workgroup, this.catalog);
38
49
  }
39
50
  if (this.app) {
40
- return new BaqendAthenaService(this.app, new EntityManagerFactory(), cli);
51
+ return new BaqendAthenaService(this.app, new EntityManagerFactory(), cli, this.catalog);
41
52
  }
42
53
  throw new FetchCredentialsError("Cannot send Athena queries: no AWS credentials found and no app given for the Baqend API.");
43
54
  }
@@ -1,4 +1,21 @@
1
1
  export declare const DEFAULT_MAX_AGE_IN_MINUTES = 60;
2
+ /**
3
+ * The Athena data catalog holding the Speed Kit tables.
4
+ *
5
+ * Which catalog that is depends on the credentials: the name below is the one
6
+ * our own logins see, while a role scoped to one account reaches the same
7
+ * tables under `AwsDataCatalog`. It is therefore a default, not a constant —
8
+ * see the `--catalog` flag.
9
+ */
10
+ export declare const DEFAULT_ATHENA_CATALOG = "live";
11
+ /**
12
+ * The catalog to use, given what a caller asked for.
13
+ *
14
+ * A blank name is the default rather than an error: it reaches here from an
15
+ * unset environment variable in a CI file as easily as from a typo, and a
16
+ * query that reads `from .rum.pi` is no way to report it.
17
+ */
18
+ export declare function athenaCatalog(catalog?: string): string;
2
19
  export declare const ATHENA_CONFIG: {
3
20
  region: string;
4
21
  };