@lsst/pik-core 0.6.5 → 0.6.6

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.js CHANGED
@@ -46,6 +46,25 @@ class CommentStyle {
46
46
  const ext = extension.replace(/^\./, "").toLowerCase();
47
47
  return CommentStyle.styles[ext] ?? CommentStyle.defaultStyle;
48
48
  }
49
+ /**
50
+ * Get comment style for a file path, handling dotfiles like .env correctly.
51
+ *
52
+ * Unlike fromExtension(), this method properly handles:
53
+ * - `.env` files (where extname returns '')
54
+ * - `.env.local`, `.env.development`, etc. (where extname returns '.local', '.development')
55
+ */
56
+ static fromFilePath(filePath) {
57
+ const basename = filePath.split(/[/\\]/).pop() ?? "";
58
+ if (basename === ".env" || basename.startsWith(".env.")) {
59
+ return CommentStyle.styles["env"] ?? CommentStyle.defaultStyle;
60
+ }
61
+ const lastDot = basename.lastIndexOf(".");
62
+ if (lastDot > 0) {
63
+ const ext = basename.slice(lastDot + 1).toLowerCase();
64
+ return CommentStyle.styles[ext] ?? CommentStyle.defaultStyle;
65
+ }
66
+ return CommentStyle.defaultStyle;
67
+ }
49
68
  /**
50
69
  * Register a custom comment style for an extension
51
70
  */
@@ -93,6 +112,12 @@ class Parser {
93
112
  static forExtension(extension) {
94
113
  return new Parser(CommentStyle.fromExtension(extension));
95
114
  }
115
+ /**
116
+ * Create a parser for a file path, correctly handling dotfiles like .env
117
+ */
118
+ static forFilePath(filePath) {
119
+ return new Parser(CommentStyle.fromFilePath(filePath));
120
+ }
96
121
  /**
97
122
  * Parse content string for pik selectors and options
98
123
  */
@@ -213,6 +238,13 @@ class CommentManipulator {
213
238
  const { blockOpen, blockClose } = this.commentStyle;
214
239
  return trimmed.startsWith(blockOpen) && trimmed.includes(blockClose);
215
240
  }
241
+ /**
242
+ * Check if a line is a line comment (not a block comment)
243
+ */
244
+ isLineComment(line) {
245
+ const trimmed = line.trimStart();
246
+ return trimmed.startsWith(this.commentStyle.lineComment);
247
+ }
216
248
  /**
217
249
  * Comment out a line if not already commented.
218
250
  * Uses the same comment style as the original if block-commented,
@@ -234,30 +266,48 @@ class CommentManipulator {
234
266
  return `${indent}${this.commentStyle.lineComment} ${trimmed}`;
235
267
  }
236
268
  /**
237
- * Uncomment a line if commented (handles both line and block comments)
269
+ * Uncomment a block comment
270
+ * @throws Error if the line is not a block comment
238
271
  */
239
- uncommentLine(line) {
272
+ uncommentBlockComment(line) {
273
+ if (!this.isBlockCommented(line)) {
274
+ throw new Error("Expected line to be a block comment");
275
+ }
240
276
  const trimmed = line.trimStart();
241
277
  const indent = line.slice(0, line.length - trimmed.length);
242
- if (this.commentStyle.hasBlockComments) {
243
- const { blockOpen, blockClose } = this.commentStyle;
244
- if (trimmed.startsWith(blockOpen)) {
245
- const afterOpen = trimmed.slice(blockOpen.length);
246
- const closeIndex = afterOpen.indexOf(blockClose);
247
- if (closeIndex !== -1) {
248
- const content2 = afterOpen.slice(0, closeIndex).trim();
249
- const rest = afterOpen.slice(closeIndex + blockClose.length);
250
- return `${indent}${content2}${rest}`;
251
- }
252
- }
253
- }
254
- if (!trimmed.startsWith(this.commentStyle.lineComment)) {
255
- return line;
278
+ const { blockOpen, blockClose } = this.commentStyle;
279
+ const afterOpen = trimmed.slice(blockOpen.length);
280
+ const closeIndex = afterOpen.indexOf(blockClose);
281
+ const content = afterOpen.slice(0, closeIndex).trim();
282
+ const rest = afterOpen.slice(closeIndex + blockClose.length);
283
+ return `${indent}${content}${rest}`;
284
+ }
285
+ /**
286
+ * Uncomment a line comment
287
+ * @throws Error if the line is not a line comment
288
+ */
289
+ uncommentLineComment(line) {
290
+ if (!this.isLineComment(line)) {
291
+ throw new Error("Expected line to be a line comment");
256
292
  }
293
+ const trimmed = line.trimStart();
294
+ const indent = line.slice(0, line.length - trimmed.length);
257
295
  const withoutComment = trimmed.slice(this.commentStyle.lineComment.length);
258
296
  const content = withoutComment.startsWith(" ") ? withoutComment.slice(1) : withoutComment;
259
297
  return `${indent}${content}`;
260
298
  }
299
+ /**
300
+ * Uncomment a line if commented (handles both line and block comments)
301
+ */
302
+ uncommentLine(line) {
303
+ if (this.isBlockCommented(line)) {
304
+ return this.uncommentBlockComment(line);
305
+ }
306
+ if (this.isLineComment(line)) {
307
+ return this.uncommentLineComment(line);
308
+ }
309
+ return line;
310
+ }
261
311
  }
262
312
  class Switcher extends CommentManipulator {
263
313
  /**
@@ -279,6 +329,12 @@ class SingleSwitcher extends Switcher {
279
329
  static forExtension(extension) {
280
330
  return new SingleSwitcher(CommentStyle.fromExtension(extension));
281
331
  }
332
+ /**
333
+ * Create a switcher for a file path, correctly handling dotfiles like .env
334
+ */
335
+ static forFilePath(filePath) {
336
+ return new SingleSwitcher(CommentStyle.fromFilePath(filePath));
337
+ }
282
338
  /**
283
339
  * Switch to a specific option, deactivating all others
284
340
  */
@@ -13,12 +13,26 @@ export declare abstract class CommentManipulator {
13
13
  * Check if a line uses block comment style
14
14
  */
15
15
  protected isBlockCommented(line: string): boolean;
16
+ /**
17
+ * Check if a line is a line comment (not a block comment)
18
+ */
19
+ private isLineComment;
16
20
  /**
17
21
  * Comment out a line if not already commented.
18
22
  * Uses the same comment style as the original if block-commented,
19
23
  * otherwise uses line comment style.
20
24
  */
21
25
  protected commentLine(line: string, useBlockStyle?: boolean): string;
26
+ /**
27
+ * Uncomment a block comment
28
+ * @throws Error if the line is not a block comment
29
+ */
30
+ private uncommentBlockComment;
31
+ /**
32
+ * Uncomment a line comment
33
+ * @throws Error if the line is not a line comment
34
+ */
35
+ private uncommentLineComment;
22
36
  /**
23
37
  * Uncomment a line if commented (handles both line and block comments)
24
38
  */
@@ -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;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
+ {"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;;OAEG;IACH,OAAO,CAAC,aAAa;IAKrB;;;;OAIG;IACH,SAAS,CAAC,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,aAAa,UAAQ,GAAG,MAAM;IAwBlE;;;OAGG;IACH,OAAO,CAAC,qBAAqB;IAoB7B;;;OAGG;IACH,OAAO,CAAC,oBAAoB;IAiB5B;;OAEG;IACH,SAAS,CAAC,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM;CAa9C"}
@@ -12,6 +12,10 @@ export declare class Parser {
12
12
  * Create a parser for a specific file extension
13
13
  */
14
14
  static forExtension(extension: string): Parser;
15
+ /**
16
+ * Create a parser for a file path, correctly handling dotfiles like .env
17
+ */
18
+ static forFilePath(filePath: string): Parser;
15
19
  /**
16
20
  * Parse content string for pik selectors and options
17
21
  */
@@ -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;IAuDnC;;;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,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,MAAM,CAAC,WAAW,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM;IAI5C;;OAEG;IACH,KAAK,CAAC,OAAO,EAAE,MAAM,GAAG,WAAW;IAuDnC;;;OAGG;IACH,OAAO,CAAC,kBAAkB;IA6B1B;;OAEG;IACH,OAAO,CAAC,eAAe;CAkBxB"}
@@ -8,6 +8,10 @@ export declare class SingleSwitcher extends Switcher {
8
8
  * Create a switcher for a specific file extension
9
9
  */
10
10
  static forExtension(extension: string): SingleSwitcher;
11
+ /**
12
+ * Create a switcher for a file path, correctly handling dotfiles like .env
13
+ */
14
+ static forFilePath(filePath: string): SingleSwitcher;
11
15
  /**
12
16
  * Switch to a specific option, deactivating all others
13
17
  */
@@ -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;CAyBxE"}
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,WAAW,CAAC,QAAQ,EAAE,MAAM,GAAG,cAAc;IAIpD;;OAEG;IACH,MAAM,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,QAAQ,EAAE,UAAU,EAAE,MAAM,GAAG,MAAM;CAyBxE"}
@@ -21,6 +21,14 @@ export declare class CommentStyle {
21
21
  * Get comment style for a file extension
22
22
  */
23
23
  static fromExtension(extension: string): CommentStyle;
24
+ /**
25
+ * Get comment style for a file path, handling dotfiles like .env correctly.
26
+ *
27
+ * Unlike fromExtension(), this method properly handles:
28
+ * - `.env` files (where extname returns '')
29
+ * - `.env.local`, `.env.development`, etc. (where extname returns '.local', '.development')
30
+ */
31
+ static fromFilePath(filePath: string): CommentStyle;
24
32
  /**
25
33
  * Register a custom comment style for an extension
26
34
  */
@@ -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;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"}
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;;;;;;OAMG;IACH,MAAM,CAAC,YAAY,CAAC,QAAQ,EAAE,MAAM,GAAG,YAAY;IAkBnD;;OAEG;IACH,MAAM,CAAC,QAAQ,CAAC,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,YAAY,GAAG,IAAI;CAI9D"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lsst/pik-core",
3
- "version": "0.6.5",
3
+ "version": "0.6.6",
4
4
  "description": "Core library for parsing and switching @pik config markers",
5
5
  "type": "module",
6
6
  "license": "MIT",