@lsst/pik-core 0.5.2 → 0.6.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/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # @lsst/pik-core
2
2
 
3
- Core library for parsing and switching `@pik` config markers in source files.
3
+ Core library for pik - provides parsing, switching, config loading, and plugin types.
4
4
 
5
5
  ## Installation
6
6
 
@@ -8,10 +8,12 @@ Core library for parsing and switching `@pik` config markers in source files.
8
8
  npm install @lsst/pik-core
9
9
  ```
10
10
 
11
- ## Usage
11
+ ## Parsing and Switching
12
+
13
+ Parse and switch `@pik` config markers in source files:
12
14
 
13
15
  ```typescript
14
- import { Parser, SingleSwitcher } from '@lsst25/pik-core';
16
+ import { Parser, SingleSwitcher } from '@lsst/pik-core';
15
17
 
16
18
  const content = `
17
19
  // @pik:select Environment
@@ -28,6 +30,55 @@ const switcher = SingleSwitcher.forExtension('ts');
28
30
  const newContent = switcher.switch(content, selectors[0], 'DEV');
29
31
  ```
30
32
 
33
+ ## Config Loading
34
+
35
+ Load pik configuration from project files:
36
+
37
+ ```typescript
38
+ import { loadConfig, defineConfig } from '@lsst/pik-core';
39
+
40
+ // Load config (looks for pik.config.ts, .pik.config.ts, etc.)
41
+ const config = await loadConfig();
42
+
43
+ // Type-safe config definition
44
+ export default defineConfig({
45
+ select: { include: ['src/**/*.ts'] },
46
+ worktree: { baseDir: '../' },
47
+ });
48
+ ```
49
+
50
+ ## Creating Plugins
51
+
52
+ Create custom plugins using the `PikPlugin` interface:
53
+
54
+ ```typescript
55
+ import type { Command } from 'commander';
56
+ import type { PikPlugin } from '@lsst/pik-core';
57
+
58
+ interface MyPluginConfig {
59
+ apiKey: string;
60
+ }
61
+
62
+ export function myPlugin(config: MyPluginConfig): PikPlugin {
63
+ return {
64
+ name: 'My Plugin',
65
+ description: 'Does something cool',
66
+ command: 'my',
67
+ aliases: ['m'],
68
+
69
+ register(program: Command) {
70
+ program
71
+ .command('my')
72
+ .alias('m')
73
+ .description('My custom command')
74
+ .action(() => {
75
+ console.log(`Using: ${config.apiKey}`);
76
+ });
77
+ },
78
+ };
79
+ }
80
+ ```
81
+
31
82
  ## API
32
83
 
33
84
  ### Parser
@@ -55,7 +106,7 @@ const newContent = switcher.switch(content, selector, 'optionName');
55
106
  ### CommentStyle
56
107
 
57
108
  ```typescript
58
- import { CommentStyle } from '@lsst25/pik-core';
109
+ import { CommentStyle } from '@lsst/pik-core';
59
110
 
60
111
  // Get comment style for extension
61
112
  const style = CommentStyle.fromExtension('py'); // { lineComment: '#' }
@@ -64,6 +115,17 @@ const style = CommentStyle.fromExtension('py'); // { lineComment: '#' }
64
115
  CommentStyle.register('custom', new CommentStyle(';;'));
65
116
  ```
66
117
 
118
+ ### isValidPlugin
119
+
120
+ ```typescript
121
+ import { isValidPlugin } from '@lsst/pik-core';
122
+
123
+ // Validate a plugin object
124
+ if (isValidPlugin(obj)) {
125
+ // obj is PikPlugin
126
+ }
127
+ ```
128
+
67
129
  ## Types
68
130
 
69
131
  ```typescript
@@ -79,6 +141,19 @@ interface Option {
79
141
  content: string;
80
142
  isActive: boolean;
81
143
  }
144
+
145
+ interface PikPlugin {
146
+ name: string;
147
+ description: string;
148
+ command: string;
149
+ aliases?: string[];
150
+ register: (program: Command) => void;
151
+ }
152
+
153
+ interface PikConfig {
154
+ plugins?: PikPlugin[];
155
+ [pluginName: string]: unknown;
156
+ }
82
157
  ```
83
158
 
84
159
  ## License
package/dist/index.d.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  export type { Option, Selector, ParseResult, PikPlugin } from './lib/types/index.js';
2
2
  export { CommentStyle } from './lib/types/index.js';
3
- export { defineConfig, loadConfig, type PikConfig } from './lib/config.js';
3
+ export { defineConfig, loadConfig, isValidPlugin, type PikConfig, } from './lib/config.js';
4
4
  export { Parser } from './lib/parser.js';
5
5
  export { Switcher } from './lib/switcher.js';
6
6
  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,QAAQ,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAC;AACrF,OAAO,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AAGpD,OAAO,EAAE,YAAY,EAAE,UAAU,EAAE,KAAK,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAG3E,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"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,YAAY,EAAE,MAAM,EAAE,QAAQ,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAC;AACrF,OAAO,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AAGpD,OAAO,EACL,YAAY,EACZ,UAAU,EACV,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;AAG1D,OAAO,EAAE,kBAAkB,EAAE,MAAM,8BAA8B,CAAC"}
package/dist/index.js CHANGED
@@ -2,8 +2,10 @@ import { pathToFileURL } from "url";
2
2
  import { existsSync } from "fs";
3
3
  import { resolve } from "path";
4
4
  class CommentStyle {
5
- constructor(lineComment) {
5
+ constructor(lineComment, blockOpen, blockClose) {
6
6
  this.lineComment = lineComment;
7
+ this.blockOpen = blockOpen;
8
+ this.blockClose = blockClose;
7
9
  }
8
10
  static styles = {
9
11
  // JavaScript/TypeScript
@@ -13,9 +15,9 @@ class CommentStyle {
13
15
  tsx: new CommentStyle("//"),
14
16
  mjs: new CommentStyle("//"),
15
17
  mts: new CommentStyle("//"),
16
- // HTML (for script tags)
17
- html: new CommentStyle("//"),
18
- htm: new CommentStyle("//"),
18
+ // HTML - supports both // (in script) and <!-- --> (in HTML)
19
+ html: new CommentStyle("//", "<!--", "-->"),
20
+ htm: new CommentStyle("//", "<!--", "-->"),
19
21
  // Config files
20
22
  yaml: new CommentStyle("#"),
21
23
  yml: new CommentStyle("#"),
@@ -29,6 +31,16 @@ class CommentStyle {
29
31
  env: new CommentStyle("#")
30
32
  };
31
33
  static defaultStyle = new CommentStyle("//");
34
+ /** Block comment opening (e.g., "<!--") */
35
+ blockOpen;
36
+ /** Block comment closing (e.g., "-->") */
37
+ blockClose;
38
+ /**
39
+ * Check if this style supports block comments
40
+ */
41
+ get hasBlockComments() {
42
+ return !!(this.blockOpen && this.blockClose);
43
+ }
32
44
  /**
33
45
  * Get comment style for a file extension
34
46
  */
@@ -68,6 +80,13 @@ async function loadConfig(cwd = process.cwd()) {
68
80
  }
69
81
  return null;
70
82
  }
83
+ function isValidPlugin(obj) {
84
+ if (typeof obj !== "object" || obj === null) {
85
+ return false;
86
+ }
87
+ const plugin = obj;
88
+ return typeof plugin.name === "string" && typeof plugin.description === "string" && typeof plugin.command === "string" && typeof plugin.register === "function";
89
+ }
71
90
  class Parser {
72
91
  constructor(commentStyle) {
73
92
  this.commentStyle = commentStyle;
@@ -102,22 +121,71 @@ class Parser {
102
121
  }
103
122
  const optionMatch = line.match(Parser.OPTION_REGEX);
104
123
  if (optionMatch && currentSelector) {
105
- const option = {
106
- name: optionMatch[1],
107
- line: lineNumber,
108
- content: line,
109
- isActive: !this.isLineCommented(line)
110
- };
111
- currentSelector.options.push(option);
124
+ const isStandalone = this.isStandaloneMarker(line);
125
+ if (isStandalone && i + 1 < lines.length) {
126
+ const contentLine = lines[i + 1];
127
+ const option = {
128
+ name: optionMatch[1],
129
+ line: lineNumber,
130
+ contentLine: lineNumber + 1,
131
+ content: contentLine,
132
+ isActive: !this.isLineCommented(contentLine)
133
+ };
134
+ currentSelector.options.push(option);
135
+ } else {
136
+ const option = {
137
+ name: optionMatch[1],
138
+ line: lineNumber,
139
+ contentLine: lineNumber,
140
+ content: line,
141
+ isActive: !this.isLineCommented(line)
142
+ };
143
+ currentSelector.options.push(option);
144
+ }
112
145
  }
113
146
  }
114
147
  return { selectors, content };
115
148
  }
149
+ /**
150
+ * Check if a line contains only a standalone marker (no other content)
151
+ * e.g., "<!-- @pik:option Name -->" or "# @pik:option Name"
152
+ */
153
+ isStandaloneMarker(line) {
154
+ const trimmed = line.trim();
155
+ if (this.commentStyle.hasBlockComments) {
156
+ const { blockOpen, blockClose } = this.commentStyle;
157
+ if (trimmed.startsWith(blockOpen) && trimmed.endsWith(blockClose)) {
158
+ const inner = trimmed.slice(blockOpen.length, -blockClose.length).trim();
159
+ const optionMatch = inner.match(Parser.OPTION_REGEX);
160
+ if (optionMatch && inner === `@pik:option ${optionMatch[1]}`) {
161
+ return true;
162
+ }
163
+ }
164
+ }
165
+ if (trimmed.startsWith(this.commentStyle.lineComment)) {
166
+ const afterComment = trimmed.slice(this.commentStyle.lineComment.length).trim();
167
+ const optionMatch = afterComment.match(Parser.OPTION_REGEX);
168
+ if (optionMatch && afterComment === `@pik:option ${optionMatch[1]}`) {
169
+ return true;
170
+ }
171
+ }
172
+ return false;
173
+ }
116
174
  /**
117
175
  * Check if a line is commented out
118
176
  */
119
177
  isLineCommented(line) {
120
- return line.trimStart().startsWith(this.commentStyle.lineComment);
178
+ const trimmed = line.trimStart();
179
+ if (trimmed.startsWith(this.commentStyle.lineComment)) {
180
+ return true;
181
+ }
182
+ if (this.commentStyle.hasBlockComments) {
183
+ const { blockOpen, blockClose } = this.commentStyle;
184
+ if (trimmed.startsWith(blockOpen) && trimmed.includes(blockClose)) {
185
+ return true;
186
+ }
187
+ }
188
+ return false;
121
189
  }
122
190
  }
123
191
  class CommentManipulator {
@@ -125,31 +193,73 @@ class CommentManipulator {
125
193
  this.commentStyle = commentStyle;
126
194
  }
127
195
  /**
128
- * Check if a line is commented out
196
+ * Check if a line is commented out (line or block comment)
129
197
  */
130
198
  isLineCommented(line) {
131
- return line.trimStart().startsWith(this.commentStyle.lineComment);
199
+ const trimmed = line.trimStart();
200
+ if (trimmed.startsWith(this.commentStyle.lineComment)) {
201
+ return true;
202
+ }
203
+ if (this.commentStyle.hasBlockComments) {
204
+ const { blockOpen, blockClose } = this.commentStyle;
205
+ if (trimmed.startsWith(blockOpen) && trimmed.includes(blockClose)) {
206
+ return true;
207
+ }
208
+ }
209
+ return false;
132
210
  }
133
211
  /**
134
- * Comment out a line if not already commented
212
+ * Check if a line uses block comment style
135
213
  */
136
- commentLine(line) {
214
+ isBlockCommented(line) {
215
+ if (!this.commentStyle.hasBlockComments) {
216
+ return false;
217
+ }
218
+ const trimmed = line.trimStart();
219
+ const { blockOpen, blockClose } = this.commentStyle;
220
+ return trimmed.startsWith(blockOpen) && trimmed.includes(blockClose);
221
+ }
222
+ /**
223
+ * Comment out a line if not already commented.
224
+ * Uses the same comment style as the original if block-commented,
225
+ * otherwise uses line comment style.
226
+ */
227
+ commentLine(line, useBlockStyle = false) {
137
228
  const trimmed = line.trimStart();
138
229
  if (trimmed.startsWith(this.commentStyle.lineComment)) {
139
230
  return line;
140
231
  }
232
+ if (this.isBlockCommented(line)) {
233
+ return line;
234
+ }
141
235
  const indent = line.slice(0, line.length - trimmed.length);
236
+ if (useBlockStyle && this.commentStyle.hasBlockComments) {
237
+ const { blockOpen, blockClose } = this.commentStyle;
238
+ return `${indent}${blockOpen} ${trimmed} ${blockClose}`;
239
+ }
142
240
  return `${indent}${this.commentStyle.lineComment} ${trimmed}`;
143
241
  }
144
242
  /**
145
- * Uncomment a line if commented
243
+ * Uncomment a line if commented (handles both line and block comments)
146
244
  */
147
245
  uncommentLine(line) {
148
246
  const trimmed = line.trimStart();
247
+ const indent = line.slice(0, line.length - trimmed.length);
248
+ if (this.commentStyle.hasBlockComments) {
249
+ const { blockOpen, blockClose } = this.commentStyle;
250
+ if (trimmed.startsWith(blockOpen)) {
251
+ const afterOpen = trimmed.slice(blockOpen.length);
252
+ const closeIndex = afterOpen.indexOf(blockClose);
253
+ if (closeIndex !== -1) {
254
+ const content2 = afterOpen.slice(0, closeIndex).trim();
255
+ const rest = afterOpen.slice(closeIndex + blockClose.length);
256
+ return `${indent}${content2}${rest}`;
257
+ }
258
+ }
259
+ }
149
260
  if (!trimmed.startsWith(this.commentStyle.lineComment)) {
150
261
  return line;
151
262
  }
152
- const indent = line.slice(0, line.length - trimmed.length);
153
263
  const withoutComment = trimmed.slice(this.commentStyle.lineComment.length);
154
264
  const content = withoutComment.startsWith(" ") ? withoutComment.slice(1) : withoutComment;
155
265
  return `${indent}${content}`;
@@ -181,13 +291,17 @@ class SingleSwitcher extends Switcher {
181
291
  switch(content, selector, optionName) {
182
292
  this.validateOption(selector, optionName);
183
293
  const lines = content.split("\n");
294
+ const useBlockStyle = selector.options.some((opt) => {
295
+ const line = lines[opt.contentLine - 1];
296
+ return this.isBlockCommented(line);
297
+ });
184
298
  for (const option of selector.options) {
185
- const lineIndex = option.line - 1;
299
+ const lineIndex = option.contentLine - 1;
186
300
  const line = lines[lineIndex];
187
301
  if (option.name === optionName) {
188
302
  lines[lineIndex] = this.uncommentLine(line);
189
303
  } else {
190
- lines[lineIndex] = this.commentLine(line);
304
+ lines[lineIndex] = this.commentLine(line, useBlockStyle);
191
305
  }
192
306
  }
193
307
  return lines.join("\n");
@@ -200,5 +314,6 @@ export {
200
314
  SingleSwitcher,
201
315
  Switcher,
202
316
  defineConfig,
317
+ isValidPlugin,
203
318
  loadConfig
204
319
  };
@@ -6,15 +6,21 @@ export declare abstract class CommentManipulator {
6
6
  protected readonly commentStyle: CommentStyle;
7
7
  constructor(commentStyle: CommentStyle);
8
8
  /**
9
- * Check if a line is commented out
9
+ * Check if a line is commented out (line or block comment)
10
10
  */
11
11
  protected isLineCommented(line: string): boolean;
12
12
  /**
13
- * Comment out a line if not already commented
13
+ * Check if a line uses block comment style
14
14
  */
15
- protected commentLine(line: string): string;
15
+ protected isBlockCommented(line: string): boolean;
16
16
  /**
17
- * Uncomment a line if commented
17
+ * Comment out a line if not already commented.
18
+ * Uses the same comment style as the original if block-commented,
19
+ * otherwise uses line comment style.
20
+ */
21
+ protected commentLine(line: string, useBlockStyle?: boolean): string;
22
+ /**
23
+ * Uncomment a line if commented (handles both line and block comments)
18
24
  */
19
25
  protected uncommentLine(line: string): string;
20
26
  }
@@ -1 +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"}
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;IAmBhD;;OAEG;IACH,SAAS,CAAC,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO;IAUjD;;;;OAIG;IACH,SAAS,CAAC,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,aAAa,UAAQ,GAAG,MAAM;IAwBlE;;OAEG;IACH,SAAS,CAAC,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM;CAkC9C"}
@@ -1,7 +1,23 @@
1
+ import type { PikPlugin } from './types/plugin.js';
1
2
  /**
2
3
  * Base config interface - plugins extend this via declaration merging
3
4
  */
4
5
  export interface PikConfig {
6
+ /**
7
+ * External plugins to load.
8
+ * Each plugin should be a factory function call that returns a PikPlugin:
9
+ * @example
10
+ * ```ts
11
+ * import { myPlugin } from 'pik-plugin-my';
12
+ *
13
+ * export default {
14
+ * plugins: [
15
+ * myPlugin({ someOption: 'value' }),
16
+ * ],
17
+ * }
18
+ * ```
19
+ */
20
+ plugins?: PikPlugin[];
5
21
  [pluginName: string]: unknown;
6
22
  }
7
23
  /**
@@ -12,4 +28,8 @@ export declare function defineConfig<T extends PikConfig>(config: T): T;
12
28
  * Load pik config from the current directory
13
29
  */
14
30
  export declare function loadConfig(cwd?: string): Promise<PikConfig | null>;
31
+ /**
32
+ * Validate that an object satisfies the PikPlugin interface
33
+ */
34
+ export declare function isValidPlugin(obj: unknown): obj is PikPlugin;
15
35
  //# sourceMappingURL=config.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/lib/config.ts"],"names":[],"mappings":"AAIA;;GAEG;AACH,MAAM,WAAW,SAAS;IACxB,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC;CAC/B;AAED;;GAEG;AACH,wBAAgB,YAAY,CAAC,CAAC,SAAS,SAAS,EAAE,MAAM,EAAE,CAAC,GAAG,CAAC,CAE9D;AAaD;;GAEG;AACH,wBAAsB,UAAU,CAAC,GAAG,GAAE,MAAsB,GAAG,OAAO,CAAC,SAAS,GAAG,IAAI,CAAC,CAYvF"}
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/lib/config.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAC;AAEnD;;GAEG;AACH,MAAM,WAAW,SAAS;IACxB;;;;;;;;;;;;;OAaG;IACH,OAAO,CAAC,EAAE,SAAS,EAAE,CAAC;IACtB,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC;CAC/B;AAED;;GAEG;AACH,wBAAgB,YAAY,CAAC,CAAC,SAAS,SAAS,EAAE,MAAM,EAAE,CAAC,GAAG,CAAC,CAE9D;AAaD;;GAEG;AACH,wBAAsB,UAAU,CAAC,GAAG,GAAE,MAAsB,GAAG,OAAO,CAAC,SAAS,GAAG,IAAI,CAAC,CAYvF;AAED;;GAEG;AACH,wBAAgB,aAAa,CAAC,GAAG,EAAE,OAAO,GAAG,GAAG,IAAI,SAAS,CAa5D"}
@@ -16,6 +16,11 @@ export declare class Parser {
16
16
  * Parse content string for pik selectors and options
17
17
  */
18
18
  parse(content: string): ParseResult;
19
+ /**
20
+ * Check if a line contains only a standalone marker (no other content)
21
+ * e.g., "<!-- @pik:option Name -->" or "# @pik:option Name"
22
+ */
23
+ private isStandaloneMarker;
19
24
  /**
20
25
  * Check if a line is commented out
21
26
  */
@@ -1 +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"}
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;IAuDnC;;;OAGG;IACH,OAAO,CAAC,kBAAkB;IA6B1B;;OAEG;IACH,OAAO,CAAC,eAAe;CAkBxB"}
@@ -1 +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"}
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;CAyBxE"}
@@ -6,9 +6,17 @@ export declare class CommentStyle {
6
6
  readonly lineComment: string;
7
7
  private static readonly styles;
8
8
  private static readonly defaultStyle;
9
+ /** Block comment opening (e.g., "<!--") */
10
+ readonly blockOpen?: string;
11
+ /** Block comment closing (e.g., "-->") */
12
+ readonly blockClose?: string;
9
13
  constructor(
10
14
  /** Line comment prefix (e.g., "//", "#") */
11
- lineComment: string);
15
+ lineComment: string, blockOpen?: string, blockClose?: string);
16
+ /**
17
+ * Check if this style supports block comments
18
+ */
19
+ get hasBlockComments(): boolean;
12
20
  /**
13
21
  * Get comment style for a file extension
14
22
  */
@@ -1 +1 @@
1
- {"version":3,"file":"comment-style.d.ts","sourceRoot":"","sources":["../../../src/lib/types/comment-style.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,qBAAa,YAAY;IA4BrB,4CAA4C;aAC5B,WAAW,EAAE,MAAM;IA5BrC,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,MAAM,CAsB5B;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"}
1
+ {"version":3,"file":"comment-style.d.ts","sourceRoot":"","sources":["../../../src/lib/types/comment-style.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,qBAAa,YAAY;IAiCrB,4CAA4C;aAC5B,WAAW,EAAE,MAAM;IAjCrC,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,MAAM,CAsB5B;IAEF,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,YAAY,CAA0B;IAE9D,2CAA2C;IAC3C,SAAgB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnC,0CAA0C;IAC1C,SAAgB,UAAU,CAAC,EAAE,MAAM,CAAC;;IAGlC,4CAA4C;IAC5B,WAAW,EAAE,MAAM,EACnC,SAAS,CAAC,EAAE,MAAM,EAClB,UAAU,CAAC,EAAE,MAAM;IAMrB;;OAEG;IACH,IAAI,gBAAgB,IAAI,OAAO,CAE9B;IAED;;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"}
@@ -4,9 +4,11 @@
4
4
  export interface Option {
5
5
  /** Option name (e.g., "DEV", "LOCAL") */
6
6
  name: string;
7
- /** Line number (1-based) */
7
+ /** Line number where the marker is (1-based) */
8
8
  line: number;
9
- /** Full content of the line */
9
+ /** Line number where the content is (1-based). Same as `line` for inline markers, next line for standalone markers. */
10
+ contentLine: number;
11
+ /** Full content of the content line */
10
12
  content: string;
11
13
  /** Whether this option is currently active (not commented out) */
12
14
  isActive: boolean;
@@ -1 +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"}
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,gDAAgD;IAChD,IAAI,EAAE,MAAM,CAAC;IACb,uHAAuH;IACvH,WAAW,EAAE,MAAM,CAAC;IACpB,uCAAuC;IACvC,OAAO,EAAE,MAAM,CAAC;IAChB,kEAAkE;IAClE,QAAQ,EAAE,OAAO,CAAC;CACnB"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lsst/pik-core",
3
- "version": "0.5.2",
3
+ "version": "0.6.0",
4
4
  "description": "Core library for parsing and switching @pik config markers",
5
5
  "type": "module",
6
6
  "license": "MIT",