@lsst/pik-core 0.8.1 → 0.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.ts CHANGED
@@ -2,6 +2,7 @@ export type { Option, BlockOption, ParseResult, PikPlugin } from './lib/types/in
2
2
  export { BaseSelector, Selector, BlockSelector } from './lib/types/index.js';
3
3
  export { CommentStyle } from './lib/types/index.js';
4
4
  export { defineConfig, loadConfig, findLocalConfig, isValidPlugin, type PikConfig, } from './lib/config.js';
5
+ export { defineGlobalConfig, loadGlobalConfig, expandHome, globalConfigDir, type GlobalConfig, type GlobalProjectEntry, } from './lib/global-config.js';
5
6
  export { Parser } from './lib/parser.js';
6
7
  export { Switcher } from './lib/switcher.js';
7
8
  export { SingleSwitcher } from './lib/single-switcher.js';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,YAAY,EAAE,MAAM,EAAE,WAAW,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAC;AACxF,OAAO,EAAE,YAAY,EAAE,QAAQ,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAC7E,OAAO,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AAGpD,OAAO,EACL,YAAY,EACZ,UAAU,EACV,eAAe,EACf,aAAa,EACb,KAAK,SAAS,GACf,MAAM,iBAAiB,CAAC;AAGzB,OAAO,EAAE,MAAM,EAAE,MAAM,iBAAiB,CAAC;AAGzC,OAAO,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AAC7C,OAAO,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAC1D,OAAO,EAAE,aAAa,EAAE,MAAM,yBAAyB,CAAC;AAGxD,OAAO,EAAE,kBAAkB,EAAE,MAAM,8BAA8B,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,YAAY,EAAE,MAAM,EAAE,WAAW,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAC;AACxF,OAAO,EAAE,YAAY,EAAE,QAAQ,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAC7E,OAAO,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AAGpD,OAAO,EACL,YAAY,EACZ,UAAU,EACV,eAAe,EACf,aAAa,EACb,KAAK,SAAS,GACf,MAAM,iBAAiB,CAAC;AAGzB,OAAO,EACL,kBAAkB,EAClB,gBAAgB,EAChB,UAAU,EACV,eAAe,EACf,KAAK,YAAY,EACjB,KAAK,kBAAkB,GACxB,MAAM,wBAAwB,CAAC;AAGhC,OAAO,EAAE,MAAM,EAAE,MAAM,iBAAiB,CAAC;AAGzC,OAAO,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AAC7C,OAAO,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAC1D,OAAO,EAAE,aAAa,EAAE,MAAM,yBAAyB,CAAC;AAGxD,OAAO,EAAE,kBAAkB,EAAE,MAAM,8BAA8B,CAAC"}
package/dist/index.js CHANGED
@@ -1,9 +1,19 @@
1
1
  import { cosmiconfig } from "cosmiconfig";
2
+ import { existsSync } from "fs";
3
+ import { readFile } from "fs/promises";
4
+ import { homedir } from "os";
5
+ import { join } from "path";
6
+ import { pathToFileURL } from "url";
2
7
  class BaseSelector {
3
8
  constructor(name, line) {
4
9
  this.name = name;
5
10
  this.line = line;
6
11
  }
12
+ /**
13
+ * Whether this selector is annotated with `@pik:global` and should be
14
+ * exposed across projects via the global config. Set by the parser.
15
+ */
16
+ isGlobal = false;
7
17
  /**
8
18
  * Get the name of the currently active option, or null if none is active
9
19
  */
@@ -318,11 +328,63 @@ function isValidPlugin(obj) {
318
328
  const plugin = obj;
319
329
  return typeof plugin.name === "string" && typeof plugin.description === "string" && typeof plugin.command === "string" && typeof plugin.register === "function";
320
330
  }
331
+ function defineGlobalConfig(config) {
332
+ return config;
333
+ }
334
+ function expandHome(filePath) {
335
+ if (filePath === "~") {
336
+ return homedir();
337
+ }
338
+ if (filePath.startsWith("~/")) {
339
+ return join(homedir(), filePath.slice(2));
340
+ }
341
+ return filePath;
342
+ }
343
+ function globalConfigDir() {
344
+ const base = process.env.XDG_CONFIG_HOME || join(homedir(), ".config");
345
+ return join(base, "pik");
346
+ }
347
+ const CONFIG_FILES = [
348
+ "config.js",
349
+ "config.mjs",
350
+ "config.cjs",
351
+ "config.json",
352
+ "config.ts",
353
+ "config.mts"
354
+ ];
355
+ async function loadGlobalConfig() {
356
+ const dir = globalConfigDir();
357
+ for (const file of CONFIG_FILES) {
358
+ const filePath = join(dir, file);
359
+ if (!existsSync(filePath)) {
360
+ continue;
361
+ }
362
+ let raw;
363
+ if (file.endsWith(".json")) {
364
+ raw = JSON.parse(await readFile(filePath, "utf-8"));
365
+ } else {
366
+ const mod = await import(pathToFileURL(filePath).href);
367
+ raw = mod.default ?? mod;
368
+ }
369
+ return normalize(raw);
370
+ }
371
+ return null;
372
+ }
373
+ function normalize(raw) {
374
+ if (!raw || typeof raw !== "object") {
375
+ return null;
376
+ }
377
+ const obj = raw;
378
+ const source = obj.global ?? obj;
379
+ const projects = Array.isArray(source.projects) ? source.projects : [];
380
+ return { projects };
381
+ }
321
382
  class Parser {
322
383
  constructor(commentStyle) {
323
384
  this.commentStyle = commentStyle;
324
385
  }
325
386
  static SELECT_REGEX = /@pik:select\s+(\S+)/;
387
+ static GLOBAL_REGEX = /@pik:global\b/;
326
388
  static OPTION_REGEX = /@pik:option\s+(\S+)/;
327
389
  static BLOCK_START_REGEX = /@pik:block-start\s+(\S+)/;
328
390
  static BLOCK_END_REGEX = /@pik:block-end/;
@@ -346,7 +408,11 @@ class Parser {
346
408
  const lineNumber = i + 1;
347
409
  const selectMatch = line.match(Parser.SELECT_REGEX);
348
410
  if (selectMatch) {
349
- pendingSelector = { name: selectMatch[1], line: lineNumber };
411
+ pendingSelector = {
412
+ name: selectMatch[1],
413
+ line: lineNumber,
414
+ isGlobal: Parser.GLOBAL_REGEX.test(line)
415
+ };
350
416
  currentSelector = null;
351
417
  continue;
352
418
  }
@@ -354,6 +420,7 @@ class Parser {
354
420
  if (blockStartMatch && (pendingSelector || currentSelector instanceof BlockSelector)) {
355
421
  if (!currentSelector && pendingSelector) {
356
422
  currentSelector = new BlockSelector(pendingSelector.name, pendingSelector.line);
423
+ currentSelector.isGlobal = pendingSelector.isGlobal;
357
424
  selectors.push(currentSelector);
358
425
  pendingSelector = null;
359
426
  }
@@ -386,6 +453,7 @@ class Parser {
386
453
  if (optionMatch && (pendingSelector || currentSelector instanceof Selector)) {
387
454
  if (!currentSelector && pendingSelector) {
388
455
  currentSelector = new Selector(pendingSelector.name, pendingSelector.line);
456
+ currentSelector.isGlobal = pendingSelector.isGlobal;
389
457
  selectors.push(currentSelector);
390
458
  pendingSelector = null;
391
459
  }
@@ -469,7 +537,11 @@ export {
469
537
  SingleSwitcher,
470
538
  Switcher,
471
539
  defineConfig,
540
+ defineGlobalConfig,
541
+ expandHome,
472
542
  findLocalConfig,
543
+ globalConfigDir,
473
544
  isValidPlugin,
474
- loadConfig
545
+ loadConfig,
546
+ loadGlobalConfig
475
547
  };
@@ -0,0 +1,45 @@
1
+ /**
2
+ * A project opted into cross-project ("global") switch visibility.
3
+ *
4
+ * - A bare string is a path to the project root; every selector in it becomes global.
5
+ * - An object form can restrict which selectors surface and override the display label.
6
+ */
7
+ export type GlobalProjectEntry = string | {
8
+ /** Absolute or `~`-relative path to the project root. */
9
+ path: string;
10
+ /** Label used to namespace this project's selectors. Defaults to the directory name. */
11
+ name?: string;
12
+ /**
13
+ * Restrict which selectors surface globally. When omitted, every selector in the
14
+ * project is global. When provided, only the named selectors are — plus any
15
+ * selector carrying an in-file `@pik:global` annotation (the two opt-ins compose).
16
+ */
17
+ selectors?: string[];
18
+ };
19
+ /**
20
+ * User-level global pik config, loaded from `~/.config/pik/config.*`.
21
+ */
22
+ export interface GlobalConfig {
23
+ /** Projects whose switches may be listed and set from any directory. */
24
+ projects?: GlobalProjectEntry[];
25
+ }
26
+ /**
27
+ * Helper for type-safe global config definition.
28
+ */
29
+ export declare function defineGlobalConfig(config: GlobalConfig): GlobalConfig;
30
+ /**
31
+ * Expand a leading `~` / `~/` to the user's home directory.
32
+ */
33
+ export declare function expandHome(filePath: string): string;
34
+ /**
35
+ * Directory holding the global config, honoring `$XDG_CONFIG_HOME` (default `~/.config/pik`).
36
+ */
37
+ export declare function globalConfigDir(): string;
38
+ /**
39
+ * Load the user-level global pik config (`~/.config/pik/config.*`).
40
+ *
41
+ * Accepts either a bare `{ projects: [...] }` or a wrapped `{ global: { projects: [...] } }`
42
+ * shape. Returns `null` when no global config exists.
43
+ */
44
+ export declare function loadGlobalConfig(): Promise<GlobalConfig | null>;
45
+ //# sourceMappingURL=global-config.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"global-config.d.ts","sourceRoot":"","sources":["../../src/lib/global-config.ts"],"names":[],"mappings":"AAMA;;;;;GAKG;AACH,MAAM,MAAM,kBAAkB,GAC1B,MAAM,GACN;IACE,yDAAyD;IACzD,IAAI,EAAE,MAAM,CAAC;IACb,wFAAwF;IACxF,IAAI,CAAC,EAAE,MAAM,CAAC;IACd;;;;OAIG;IACH,SAAS,CAAC,EAAE,MAAM,EAAE,CAAC;CACtB,CAAC;AAEN;;GAEG;AACH,MAAM,WAAW,YAAY;IAC3B,wEAAwE;IACxE,QAAQ,CAAC,EAAE,kBAAkB,EAAE,CAAC;CACjC;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,YAAY,GAAG,YAAY,CAErE;AAED;;GAEG;AACH,wBAAgB,UAAU,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAQnD;AAED;;GAEG;AACH,wBAAgB,eAAe,IAAI,MAAM,CAGxC;AAWD;;;;;GAKG;AACH,wBAAsB,gBAAgB,IAAI,OAAO,CAAC,YAAY,GAAG,IAAI,CAAC,CAuBrE"}
@@ -6,6 +6,7 @@ import { CommentStyle } from './types/index.js';
6
6
  export declare class Parser {
7
7
  private readonly commentStyle;
8
8
  private static readonly SELECT_REGEX;
9
+ private static readonly GLOBAL_REGEX;
9
10
  private static readonly OPTION_REGEX;
10
11
  private static readonly BLOCK_START_REGEX;
11
12
  private static readonly BLOCK_END_REGEX;
@@ -1 +1 @@
1
- {"version":3,"file":"parser.d.ts","sourceRoot":"","sources":["../../src/lib/parser.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAuB,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAEzE,OAAO,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAOhD;;GAEG;AACH,qBAAa,MAAM;IAML,OAAO,CAAC,QAAQ,CAAC,YAAY;IALzC,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,YAAY,CAAyB;IAC7D,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,YAAY,CAAyB;IAC7D,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,iBAAiB,CAA8B;IACvE,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,eAAe,CAAoB;gBAE9B,YAAY,EAAE,YAAY;IAEvD;;OAEG;IACH,MAAM,CAAC,WAAW,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM;IAI5C;;OAEG;IACH,KAAK,CAAC,OAAO,EAAE,MAAM,GAAG,WAAW;IA0GnC;;;OAGG;IACH,OAAO,CAAC,kBAAkB;IA6B1B;;OAEG;IACH,OAAO,CAAC,eAAe;CAkBxB"}
1
+ {"version":3,"file":"parser.d.ts","sourceRoot":"","sources":["../../src/lib/parser.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAuB,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAEzE,OAAO,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAQhD;;GAEG;AACH,qBAAa,MAAM;IAOL,OAAO,CAAC,QAAQ,CAAC,YAAY;IANzC,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,YAAY,CAAyB;IAC7D,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,YAAY,CAAmB;IACvD,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,YAAY,CAAyB;IAC7D,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,iBAAiB,CAA8B;IACvE,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,eAAe,CAAoB;gBAE9B,YAAY,EAAE,YAAY;IAEvD;;OAEG;IACH,MAAM,CAAC,WAAW,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM;IAI5C;;OAEG;IACH,KAAK,CAAC,OAAO,EAAE,MAAM,GAAG,WAAW;IAkHnC;;;OAGG;IACH,OAAO,CAAC,kBAAkB;IA6B1B;;OAEG;IACH,OAAO,CAAC,eAAe;CAkBxB"}
@@ -9,6 +9,11 @@ export declare abstract class BaseSelector {
9
9
  readonly line: number;
10
10
  /** Options for this selector */
11
11
  abstract readonly options: BaseOption[];
12
+ /**
13
+ * Whether this selector is annotated with `@pik:global` and should be
14
+ * exposed across projects via the global config. Set by the parser.
15
+ */
16
+ isGlobal: boolean;
12
17
  constructor(
13
18
  /** Selector name (e.g., "Environment") */
14
19
  name: string,
@@ -1 +1 @@
1
- {"version":3,"file":"base-selector.d.ts","sourceRoot":"","sources":["../../../src/lib/selector/base-selector.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAC;AAE1D;;GAEG;AACH,8BAAsB,YAAY;IAK9B,0CAA0C;aAC1B,IAAI,EAAE,MAAM;IAC5B,0DAA0D;aAC1C,IAAI,EAAE,MAAM;IAP9B,gCAAgC;IAChC,QAAQ,CAAC,QAAQ,CAAC,OAAO,EAAE,UAAU,EAAE,CAAC;;IAGtC,0CAA0C;IAC1B,IAAI,EAAE,MAAM;IAC5B,0DAA0D;IAC1C,IAAI,EAAE,MAAM;IAG9B;;OAEG;IACH,mBAAmB,IAAI,MAAM,GAAG,IAAI;IAIpC;;OAEG;IACH,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO;IAInC;;OAEG;IACH,QAAQ,CAAC,QAAQ,CAAC,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM;CACjF"}
1
+ {"version":3,"file":"base-selector.d.ts","sourceRoot":"","sources":["../../../src/lib/selector/base-selector.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAC;AAE1D;;GAEG;AACH,8BAAsB,YAAY;IAW9B,0CAA0C;aAC1B,IAAI,EAAE,MAAM;IAC5B,0DAA0D;aAC1C,IAAI,EAAE,MAAM;IAb9B,gCAAgC;IAChC,QAAQ,CAAC,QAAQ,CAAC,OAAO,EAAE,UAAU,EAAE,CAAC;IAExC;;;OAGG;IACH,QAAQ,UAAS;;IAGf,0CAA0C;IAC1B,IAAI,EAAE,MAAM;IAC5B,0DAA0D;IAC1C,IAAI,EAAE,MAAM;IAG9B;;OAEG;IACH,mBAAmB,IAAI,MAAM,GAAG,IAAI;IAIpC;;OAEG;IACH,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO;IAInC;;OAEG;IACH,QAAQ,CAAC,QAAQ,CAAC,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM;CACjF"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lsst/pik-core",
3
- "version": "0.8.1",
3
+ "version": "0.9.0",
4
4
  "description": "Core library for parsing and switching @pik config markers",
5
5
  "type": "module",
6
6
  "license": "MIT",