@lsst/pik-core 0.0.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 ADDED
@@ -0,0 +1,86 @@
1
+ # @lsst/pik-core
2
+
3
+ Core library for parsing and switching `@pik` config markers in source files.
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ npm install @lsst/pik-core
9
+ ```
10
+
11
+ ## Usage
12
+
13
+ ```typescript
14
+ import { Parser, SingleSwitcher } from '@lsst25/pik-core';
15
+
16
+ const content = `
17
+ // @pik:select Environment
18
+ // const env = 'DEV'; // @pik:option DEV
19
+ const env = 'LOCAL'; // @pik:option LOCAL
20
+ `;
21
+
22
+ // Parse content
23
+ const parser = Parser.forExtension('ts');
24
+ const { selectors } = parser.parse(content);
25
+
26
+ // Switch option
27
+ const switcher = SingleSwitcher.forExtension('ts');
28
+ const newContent = switcher.switch(content, selectors[0], 'DEV');
29
+ ```
30
+
31
+ ## API
32
+
33
+ ### Parser
34
+
35
+ ```typescript
36
+ // Create parser for file extension
37
+ const parser = Parser.forExtension('ts');
38
+
39
+ // Parse content
40
+ const result = parser.parse(content);
41
+ // result.selectors: Selector[]
42
+ // result.content: string
43
+ ```
44
+
45
+ ### SingleSwitcher
46
+
47
+ ```typescript
48
+ // Create switcher for file extension
49
+ const switcher = SingleSwitcher.forExtension('ts');
50
+
51
+ // Switch to option (deactivates all others)
52
+ const newContent = switcher.switch(content, selector, 'optionName');
53
+ ```
54
+
55
+ ### CommentStyle
56
+
57
+ ```typescript
58
+ import { CommentStyle } from '@lsst25/pik-core';
59
+
60
+ // Get comment style for extension
61
+ const style = CommentStyle.fromExtension('py'); // { lineComment: '#' }
62
+
63
+ // Register custom style
64
+ CommentStyle.register('custom', new CommentStyle(';;'));
65
+ ```
66
+
67
+ ## Types
68
+
69
+ ```typescript
70
+ interface Selector {
71
+ name: string;
72
+ line: number;
73
+ options: Option[];
74
+ }
75
+
76
+ interface Option {
77
+ name: string;
78
+ line: number;
79
+ content: string;
80
+ isActive: boolean;
81
+ }
82
+ ```
83
+
84
+ ## License
85
+
86
+ MIT
@@ -0,0 +1,7 @@
1
+ export type { Option, Selector, ParseResult } from './lib/types/index.js';
2
+ export { CommentStyle } from './lib/types/index.js';
3
+ export { Parser } from './lib/parser.js';
4
+ export { Switcher } from './lib/switcher.js';
5
+ export { SingleSwitcher } from './lib/single-switcher.js';
6
+ export { CommentManipulator } from './lib/comment-manipulator.js';
7
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,YAAY,EAAE,MAAM,EAAE,QAAQ,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AAC1E,OAAO,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AAGpD,OAAO,EAAE,MAAM,EAAE,MAAM,iBAAiB,CAAC;AAGzC,OAAO,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AAC7C,OAAO,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAG1D,OAAO,EAAE,kBAAkB,EAAE,MAAM,8BAA8B,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,157 @@
1
+ class e {
2
+ constructor(t) {
3
+ this.lineComment = t;
4
+ }
5
+ static styles = {
6
+ // JavaScript/TypeScript
7
+ js: new e("//"),
8
+ ts: new e("//"),
9
+ jsx: new e("//"),
10
+ tsx: new e("//"),
11
+ mjs: new e("//"),
12
+ mts: new e("//"),
13
+ // Config files
14
+ yaml: new e("#"),
15
+ yml: new e("#"),
16
+ // Shell
17
+ sh: new e("#"),
18
+ bash: new e("#"),
19
+ zsh: new e("#"),
20
+ // Python
21
+ py: new e("#"),
22
+ // Env files
23
+ env: new e("#")
24
+ };
25
+ static defaultStyle = new e("//");
26
+ /**
27
+ * Get comment style for a file extension
28
+ */
29
+ static fromExtension(t) {
30
+ const n = t.replace(/^\./, "").toLowerCase();
31
+ return e.styles[n] ?? e.defaultStyle;
32
+ }
33
+ /**
34
+ * Register a custom comment style for an extension
35
+ */
36
+ static register(t, n) {
37
+ const i = t.replace(/^\./, "").toLowerCase();
38
+ e.styles[i] = n;
39
+ }
40
+ }
41
+ class a {
42
+ constructor(t) {
43
+ this.commentStyle = t;
44
+ }
45
+ static SELECT_REGEX = /@pik:select\s+(\S+)/;
46
+ static OPTION_REGEX = /@pik:option\s+(\S+)/;
47
+ /**
48
+ * Create a parser for a specific file extension
49
+ */
50
+ static forExtension(t) {
51
+ return new a(e.fromExtension(t));
52
+ }
53
+ /**
54
+ * Parse content string for pik selectors and options
55
+ */
56
+ parse(t) {
57
+ const n = t.split(`
58
+ `), i = [];
59
+ let s = null;
60
+ for (let o = 0; o < n.length; o++) {
61
+ const c = n[o], r = o + 1, l = c.match(a.SELECT_REGEX);
62
+ if (l) {
63
+ s = {
64
+ name: l[1],
65
+ line: r,
66
+ options: []
67
+ }, i.push(s);
68
+ continue;
69
+ }
70
+ const h = c.match(a.OPTION_REGEX);
71
+ if (h && s) {
72
+ const p = {
73
+ name: h[1],
74
+ line: r,
75
+ content: c,
76
+ isActive: !this.isLineCommented(c)
77
+ };
78
+ s.options.push(p);
79
+ }
80
+ }
81
+ return { selectors: i, content: t };
82
+ }
83
+ /**
84
+ * Check if a line is commented out
85
+ */
86
+ isLineCommented(t) {
87
+ return t.trimStart().startsWith(this.commentStyle.lineComment);
88
+ }
89
+ }
90
+ class w {
91
+ constructor(t) {
92
+ this.commentStyle = t;
93
+ }
94
+ /**
95
+ * Check if a line is commented out
96
+ */
97
+ isLineCommented(t) {
98
+ return t.trimStart().startsWith(this.commentStyle.lineComment);
99
+ }
100
+ /**
101
+ * Comment out a line if not already commented
102
+ */
103
+ commentLine(t) {
104
+ const n = t.trimStart();
105
+ return n.startsWith(this.commentStyle.lineComment) ? t : `${t.slice(0, t.length - n.length)}${this.commentStyle.lineComment} ${n}`;
106
+ }
107
+ /**
108
+ * Uncomment a line if commented
109
+ */
110
+ uncommentLine(t) {
111
+ const n = t.trimStart();
112
+ if (!n.startsWith(this.commentStyle.lineComment))
113
+ return t;
114
+ const i = t.slice(0, t.length - n.length), s = n.slice(this.commentStyle.lineComment.length), o = s.startsWith(" ") ? s.slice(1) : s;
115
+ return `${i}${o}`;
116
+ }
117
+ }
118
+ class f extends w {
119
+ /**
120
+ * Validate that the option exists in the selector
121
+ */
122
+ validateOption(t, n) {
123
+ if (!t.options.find((s) => s.name === n))
124
+ throw new Error(
125
+ `Option "${n}" not found in selector "${t.name}"`
126
+ );
127
+ }
128
+ }
129
+ class m extends f {
130
+ /**
131
+ * Create a switcher for a specific file extension
132
+ */
133
+ static forExtension(t) {
134
+ return new m(e.fromExtension(t));
135
+ }
136
+ /**
137
+ * Switch to a specific option, deactivating all others
138
+ */
139
+ switch(t, n, i) {
140
+ this.validateOption(n, i);
141
+ const s = t.split(`
142
+ `);
143
+ for (const o of n.options) {
144
+ const c = o.line - 1, r = s[c];
145
+ o.name === i ? s[c] = this.uncommentLine(r) : s[c] = this.commentLine(r);
146
+ }
147
+ return s.join(`
148
+ `);
149
+ }
150
+ }
151
+ export {
152
+ w as CommentManipulator,
153
+ e as CommentStyle,
154
+ a as Parser,
155
+ m as SingleSwitcher,
156
+ f as Switcher
157
+ };
@@ -0,0 +1,21 @@
1
+ import { CommentStyle } from './types/index.js';
2
+ /**
3
+ * Base class for manipulating comments in source files
4
+ */
5
+ export declare abstract class CommentManipulator {
6
+ protected readonly commentStyle: CommentStyle;
7
+ constructor(commentStyle: CommentStyle);
8
+ /**
9
+ * Check if a line is commented out
10
+ */
11
+ protected isLineCommented(line: string): boolean;
12
+ /**
13
+ * Comment out a line if not already commented
14
+ */
15
+ protected commentLine(line: string): string;
16
+ /**
17
+ * Uncomment a line if commented
18
+ */
19
+ protected uncommentLine(line: string): string;
20
+ }
21
+ //# sourceMappingURL=comment-manipulator.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"comment-manipulator.d.ts","sourceRoot":"","sources":["../../src/lib/comment-manipulator.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAEhD;;GAEG;AACH,8BAAsB,kBAAkB;IAC1B,SAAS,CAAC,QAAQ,CAAC,YAAY,EAAE,YAAY;gBAA1B,YAAY,EAAE,YAAY;IAEzD;;OAEG;IACH,SAAS,CAAC,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO;IAIhD;;OAEG;IACH,SAAS,CAAC,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM;IAU3C;;OAEG;IACH,SAAS,CAAC,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM;CAe9C"}
@@ -0,0 +1,24 @@
1
+ import type { ParseResult } from './types/index.js';
2
+ import { CommentStyle } from './types/index.js';
3
+ /**
4
+ * Parser for pik selectors and options in source files
5
+ */
6
+ export declare class Parser {
7
+ private readonly commentStyle;
8
+ private static readonly SELECT_REGEX;
9
+ private static readonly OPTION_REGEX;
10
+ constructor(commentStyle: CommentStyle);
11
+ /**
12
+ * Create a parser for a specific file extension
13
+ */
14
+ static forExtension(extension: string): Parser;
15
+ /**
16
+ * Parse content string for pik selectors and options
17
+ */
18
+ parse(content: string): ParseResult;
19
+ /**
20
+ * Check if a line is commented out
21
+ */
22
+ private isLineCommented;
23
+ }
24
+ //# sourceMappingURL=parser.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"parser.d.ts","sourceRoot":"","sources":["../../src/lib/parser.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAU,WAAW,EAAY,MAAM,kBAAkB,CAAC;AACtE,OAAO,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAEhD;;GAEG;AACH,qBAAa,MAAM;IAIL,OAAO,CAAC,QAAQ,CAAC,YAAY;IAHzC,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,YAAY,CAAyB;IAC7D,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,YAAY,CAAyB;gBAEhC,YAAY,EAAE,YAAY;IAEvD;;OAEG;IACH,MAAM,CAAC,YAAY,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM;IAI9C;;OAEG;IACH,KAAK,CAAC,OAAO,EAAE,MAAM,GAAG,WAAW;IAqCnC;;OAEG;IACH,OAAO,CAAC,eAAe;CAGxB"}
@@ -0,0 +1,16 @@
1
+ import type { Selector } from './types/index.js';
2
+ import { Switcher } from './switcher.js';
3
+ /**
4
+ * Switcher that allows only one option to be active at a time
5
+ */
6
+ export declare class SingleSwitcher extends Switcher {
7
+ /**
8
+ * Create a switcher for a specific file extension
9
+ */
10
+ static forExtension(extension: string): SingleSwitcher;
11
+ /**
12
+ * Switch to a specific option, deactivating all others
13
+ */
14
+ switch(content: string, selector: Selector, optionName: string): string;
15
+ }
16
+ //# sourceMappingURL=single-switcher.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"single-switcher.d.ts","sourceRoot":"","sources":["../../src/lib/single-switcher.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAEjD,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAEzC;;GAEG;AACH,qBAAa,cAAe,SAAQ,QAAQ;IAC1C;;OAEG;IACH,MAAM,CAAC,YAAY,CAAC,SAAS,EAAE,MAAM,GAAG,cAAc;IAItD;;OAEG;IACH,MAAM,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,QAAQ,EAAE,UAAU,EAAE,MAAM,GAAG,MAAM;CAkBxE"}
@@ -0,0 +1,17 @@
1
+ import type { Selector } from './types/index.js';
2
+ import { CommentManipulator } from './comment-manipulator.js';
3
+ /**
4
+ * Abstract base class for switching pik options
5
+ */
6
+ export declare abstract class Switcher extends CommentManipulator {
7
+ /**
8
+ * Switch options within a selector
9
+ * Returns the modified content
10
+ */
11
+ abstract switch(content: string, selector: Selector, optionName: string): string;
12
+ /**
13
+ * Validate that the option exists in the selector
14
+ */
15
+ protected validateOption(selector: Selector, optionName: string): void;
16
+ }
17
+ //# sourceMappingURL=switcher.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"switcher.d.ts","sourceRoot":"","sources":["../../src/lib/switcher.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AACjD,OAAO,EAAE,kBAAkB,EAAE,MAAM,0BAA0B,CAAC;AAE9D;;GAEG;AACH,8BAAsB,QAAS,SAAQ,kBAAkB;IACvD;;;OAGG;IACH,QAAQ,CAAC,MAAM,CACb,OAAO,EAAE,MAAM,EACf,QAAQ,EAAE,QAAQ,EAClB,UAAU,EAAE,MAAM,GACjB,MAAM;IAET;;OAEG;IACH,SAAS,CAAC,cAAc,CAAC,QAAQ,EAAE,QAAQ,EAAE,UAAU,EAAE,MAAM,GAAG,IAAI;CAQvE"}
@@ -0,0 +1,21 @@
1
+ /**
2
+ * Comment style configuration for different file types
3
+ */
4
+ export declare class CommentStyle {
5
+ /** Line comment prefix (e.g., "//", "#") */
6
+ readonly lineComment: string;
7
+ private static readonly styles;
8
+ private static readonly defaultStyle;
9
+ constructor(
10
+ /** Line comment prefix (e.g., "//", "#") */
11
+ lineComment: string);
12
+ /**
13
+ * Get comment style for a file extension
14
+ */
15
+ static fromExtension(extension: string): CommentStyle;
16
+ /**
17
+ * Register a custom comment style for an extension
18
+ */
19
+ static register(extension: string, style: CommentStyle): void;
20
+ }
21
+ //# sourceMappingURL=comment-style.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"comment-style.d.ts","sourceRoot":"","sources":["../../../src/lib/types/comment-style.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,qBAAa,YAAY;IAyBrB,4CAA4C;aAC5B,WAAW,EAAE,MAAM;IAzBrC,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,MAAM,CAmB5B;IAEF,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,YAAY,CAA0B;;IAG5D,4CAA4C;IAC5B,WAAW,EAAE,MAAM;IAGrC;;OAEG;IACH,MAAM,CAAC,aAAa,CAAC,SAAS,EAAE,MAAM,GAAG,YAAY;IAKrD;;OAEG;IACH,MAAM,CAAC,QAAQ,CAAC,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,YAAY,GAAG,IAAI;CAI9D"}
@@ -0,0 +1,5 @@
1
+ export type { Option } from './option.js';
2
+ export type { Selector } from './selector.js';
3
+ export type { ParseResult } from './parse-result.js';
4
+ export { CommentStyle } from './comment-style.js';
5
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/lib/types/index.ts"],"names":[],"mappings":"AAAA,YAAY,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAC1C,YAAY,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAC9C,YAAY,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AACrD,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC"}
@@ -0,0 +1,14 @@
1
+ /**
2
+ * Represents a single option within a selector
3
+ */
4
+ export interface Option {
5
+ /** Option name (e.g., "DEV", "LOCAL") */
6
+ name: string;
7
+ /** Line number (1-based) */
8
+ line: number;
9
+ /** Full content of the line */
10
+ content: string;
11
+ /** Whether this option is currently active (not commented out) */
12
+ isActive: boolean;
13
+ }
14
+ //# sourceMappingURL=option.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"option.d.ts","sourceRoot":"","sources":["../../../src/lib/types/option.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,MAAM,WAAW,MAAM;IACrB,yCAAyC;IACzC,IAAI,EAAE,MAAM,CAAC;IACb,4BAA4B;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,+BAA+B;IAC/B,OAAO,EAAE,MAAM,CAAC;IAChB,kEAAkE;IAClE,QAAQ,EAAE,OAAO,CAAC;CACnB"}
@@ -0,0 +1,11 @@
1
+ import type { Selector } from './selector.js';
2
+ /**
3
+ * Result of parsing a file or content string
4
+ */
5
+ export interface ParseResult {
6
+ /** All selectors found in the content */
7
+ selectors: Selector[];
8
+ /** Original content that was parsed */
9
+ content: string;
10
+ }
11
+ //# sourceMappingURL=parse-result.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"parse-result.d.ts","sourceRoot":"","sources":["../../../src/lib/types/parse-result.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAE9C;;GAEG;AACH,MAAM,WAAW,WAAW;IAC1B,yCAAyC;IACzC,SAAS,EAAE,QAAQ,EAAE,CAAC;IACtB,uCAAuC;IACvC,OAAO,EAAE,MAAM,CAAC;CACjB"}
@@ -0,0 +1,13 @@
1
+ import type { Option } from './option.js';
2
+ /**
3
+ * Represents a selector with its options
4
+ */
5
+ export interface Selector {
6
+ /** Selector name (e.g., "Environment") */
7
+ name: string;
8
+ /** Line number where the selector is defined (1-based) */
9
+ line: number;
10
+ /** All options belonging to this selector */
11
+ options: Option[];
12
+ }
13
+ //# sourceMappingURL=selector.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"selector.d.ts","sourceRoot":"","sources":["../../../src/lib/types/selector.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAE1C;;GAEG;AACH,MAAM,WAAW,QAAQ;IACvB,0CAA0C;IAC1C,IAAI,EAAE,MAAM,CAAC;IACb,0DAA0D;IAC1D,IAAI,EAAE,MAAM,CAAC;IACb,6CAA6C;IAC7C,OAAO,EAAE,MAAM,EAAE,CAAC;CACnB"}
package/package.json ADDED
@@ -0,0 +1,37 @@
1
+ {
2
+ "name": "@lsst/pik-core",
3
+ "version": "0.0.1",
4
+ "description": "Core library for parsing and switching @pik config markers",
5
+ "type": "module",
6
+ "license": "MIT",
7
+ "author": "Yurii Tatar <lsst25@gmail.com>",
8
+ "repository": {
9
+ "type": "git",
10
+ "url": "git+https://github.com/lsst25/pik.git",
11
+ "directory": "packages/pik-core"
12
+ },
13
+ "keywords": [
14
+ "config",
15
+ "configuration",
16
+ "switch",
17
+ "toggle",
18
+ "environment"
19
+ ],
20
+ "main": "./dist/index.js",
21
+ "module": "./dist/index.js",
22
+ "types": "./dist/index.d.ts",
23
+ "exports": {
24
+ "./package.json": "./package.json",
25
+ ".": {
26
+ "@pik/source": "./src/index.ts",
27
+ "types": "./dist/index.d.ts",
28
+ "import": "./dist/index.js",
29
+ "default": "./dist/index.js"
30
+ }
31
+ },
32
+ "files": [
33
+ "dist",
34
+ "!**/*.tsbuildinfo"
35
+ ],
36
+ "dependencies": {}
37
+ }