@lsst/pik-core 0.4.1 → 0.4.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.
- package/dist/index.d.ts +2 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +131 -87
- package/dist/lib/config.d.ts +15 -0
- package/dist/lib/config.d.ts.map +1 -0
- package/dist/lib/types/index.d.ts +1 -0
- package/dist/lib/types/index.d.ts.map +1 -1
- package/dist/lib/types/plugin.d.ts +20 -0
- package/dist/lib/types/plugin.d.ts.map +1 -0
- package/package.json +4 -2
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
export type { Option, Selector, ParseResult } from './lib/types/index.js';
|
|
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
4
|
export { Parser } from './lib/parser.js';
|
|
4
5
|
export { Switcher } from './lib/switcher.js';
|
|
5
6
|
export { SingleSwitcher } from './lib/single-switcher.js';
|
package/dist/index.d.ts.map
CHANGED
|
@@ -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,MAAM,sBAAsB,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,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"}
|
package/dist/index.js
CHANGED
|
@@ -1,160 +1,204 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
import { pathToFileURL } from "url";
|
|
2
|
+
import { existsSync } from "fs";
|
|
3
|
+
import { resolve } from "path";
|
|
4
|
+
class CommentStyle {
|
|
5
|
+
constructor(lineComment) {
|
|
6
|
+
this.lineComment = lineComment;
|
|
4
7
|
}
|
|
5
8
|
static styles = {
|
|
6
9
|
// JavaScript/TypeScript
|
|
7
|
-
js: new
|
|
8
|
-
ts: new
|
|
9
|
-
jsx: new
|
|
10
|
-
tsx: new
|
|
11
|
-
mjs: new
|
|
12
|
-
mts: new
|
|
10
|
+
js: new CommentStyle("//"),
|
|
11
|
+
ts: new CommentStyle("//"),
|
|
12
|
+
jsx: new CommentStyle("//"),
|
|
13
|
+
tsx: new CommentStyle("//"),
|
|
14
|
+
mjs: new CommentStyle("//"),
|
|
15
|
+
mts: new CommentStyle("//"),
|
|
13
16
|
// HTML (for script tags)
|
|
14
|
-
html: new
|
|
15
|
-
htm: new
|
|
17
|
+
html: new CommentStyle("//"),
|
|
18
|
+
htm: new CommentStyle("//"),
|
|
16
19
|
// Config files
|
|
17
|
-
yaml: new
|
|
18
|
-
yml: new
|
|
20
|
+
yaml: new CommentStyle("#"),
|
|
21
|
+
yml: new CommentStyle("#"),
|
|
19
22
|
// Shell
|
|
20
|
-
sh: new
|
|
21
|
-
bash: new
|
|
22
|
-
zsh: new
|
|
23
|
+
sh: new CommentStyle("#"),
|
|
24
|
+
bash: new CommentStyle("#"),
|
|
25
|
+
zsh: new CommentStyle("#"),
|
|
23
26
|
// Python
|
|
24
|
-
py: new
|
|
27
|
+
py: new CommentStyle("#"),
|
|
25
28
|
// Env files
|
|
26
|
-
env: new
|
|
29
|
+
env: new CommentStyle("#")
|
|
27
30
|
};
|
|
28
|
-
static defaultStyle = new
|
|
31
|
+
static defaultStyle = new CommentStyle("//");
|
|
29
32
|
/**
|
|
30
33
|
* Get comment style for a file extension
|
|
31
34
|
*/
|
|
32
|
-
static fromExtension(
|
|
33
|
-
const
|
|
34
|
-
return
|
|
35
|
+
static fromExtension(extension) {
|
|
36
|
+
const ext = extension.replace(/^\./, "").toLowerCase();
|
|
37
|
+
return CommentStyle.styles[ext] ?? CommentStyle.defaultStyle;
|
|
35
38
|
}
|
|
36
39
|
/**
|
|
37
40
|
* Register a custom comment style for an extension
|
|
38
41
|
*/
|
|
39
|
-
static register(
|
|
40
|
-
const
|
|
41
|
-
|
|
42
|
+
static register(extension, style) {
|
|
43
|
+
const ext = extension.replace(/^\./, "").toLowerCase();
|
|
44
|
+
CommentStyle.styles[ext] = style;
|
|
42
45
|
}
|
|
43
46
|
}
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
+
function defineConfig(config) {
|
|
48
|
+
return config;
|
|
49
|
+
}
|
|
50
|
+
const CONFIG_FILES = [
|
|
51
|
+
"pik.config.mts",
|
|
52
|
+
"pik.config.ts",
|
|
53
|
+
"pik.config.mjs",
|
|
54
|
+
"pik.config.js",
|
|
55
|
+
".pik.config.mts",
|
|
56
|
+
".pik.config.ts",
|
|
57
|
+
".pik.config.mjs",
|
|
58
|
+
".pik.config.js"
|
|
59
|
+
];
|
|
60
|
+
async function loadConfig(cwd = process.cwd()) {
|
|
61
|
+
for (const configFile of CONFIG_FILES) {
|
|
62
|
+
const configPath = resolve(cwd, configFile);
|
|
63
|
+
if (existsSync(configPath)) {
|
|
64
|
+
const configUrl = pathToFileURL(configPath).href;
|
|
65
|
+
const module = await import(configUrl);
|
|
66
|
+
return module.default;
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
return null;
|
|
70
|
+
}
|
|
71
|
+
class Parser {
|
|
72
|
+
constructor(commentStyle) {
|
|
73
|
+
this.commentStyle = commentStyle;
|
|
47
74
|
}
|
|
48
75
|
static SELECT_REGEX = /@pik:select\s+(\S+)/;
|
|
49
76
|
static OPTION_REGEX = /@pik:option\s+(\S+)/;
|
|
50
77
|
/**
|
|
51
78
|
* Create a parser for a specific file extension
|
|
52
79
|
*/
|
|
53
|
-
static forExtension(
|
|
54
|
-
return new
|
|
80
|
+
static forExtension(extension) {
|
|
81
|
+
return new Parser(CommentStyle.fromExtension(extension));
|
|
55
82
|
}
|
|
56
83
|
/**
|
|
57
84
|
* Parse content string for pik selectors and options
|
|
58
85
|
*/
|
|
59
|
-
parse(
|
|
60
|
-
const
|
|
61
|
-
|
|
62
|
-
let
|
|
63
|
-
for (let
|
|
64
|
-
const
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
86
|
+
parse(content) {
|
|
87
|
+
const lines = content.split("\n");
|
|
88
|
+
const selectors = [];
|
|
89
|
+
let currentSelector = null;
|
|
90
|
+
for (let i = 0; i < lines.length; i++) {
|
|
91
|
+
const line = lines[i];
|
|
92
|
+
const lineNumber = i + 1;
|
|
93
|
+
const selectMatch = line.match(Parser.SELECT_REGEX);
|
|
94
|
+
if (selectMatch) {
|
|
95
|
+
currentSelector = {
|
|
96
|
+
name: selectMatch[1],
|
|
97
|
+
line: lineNumber,
|
|
69
98
|
options: []
|
|
70
|
-
}
|
|
99
|
+
};
|
|
100
|
+
selectors.push(currentSelector);
|
|
71
101
|
continue;
|
|
72
102
|
}
|
|
73
|
-
const
|
|
74
|
-
if (
|
|
75
|
-
const
|
|
76
|
-
name:
|
|
77
|
-
line:
|
|
78
|
-
content:
|
|
79
|
-
isActive: !this.isLineCommented(
|
|
103
|
+
const optionMatch = line.match(Parser.OPTION_REGEX);
|
|
104
|
+
if (optionMatch && currentSelector) {
|
|
105
|
+
const option = {
|
|
106
|
+
name: optionMatch[1],
|
|
107
|
+
line: lineNumber,
|
|
108
|
+
content: line,
|
|
109
|
+
isActive: !this.isLineCommented(line)
|
|
80
110
|
};
|
|
81
|
-
|
|
111
|
+
currentSelector.options.push(option);
|
|
82
112
|
}
|
|
83
113
|
}
|
|
84
|
-
return { selectors
|
|
114
|
+
return { selectors, content };
|
|
85
115
|
}
|
|
86
116
|
/**
|
|
87
117
|
* Check if a line is commented out
|
|
88
118
|
*/
|
|
89
|
-
isLineCommented(
|
|
90
|
-
return
|
|
119
|
+
isLineCommented(line) {
|
|
120
|
+
return line.trimStart().startsWith(this.commentStyle.lineComment);
|
|
91
121
|
}
|
|
92
122
|
}
|
|
93
|
-
class
|
|
94
|
-
constructor(
|
|
95
|
-
this.commentStyle =
|
|
123
|
+
class CommentManipulator {
|
|
124
|
+
constructor(commentStyle) {
|
|
125
|
+
this.commentStyle = commentStyle;
|
|
96
126
|
}
|
|
97
127
|
/**
|
|
98
128
|
* Check if a line is commented out
|
|
99
129
|
*/
|
|
100
|
-
isLineCommented(
|
|
101
|
-
return
|
|
130
|
+
isLineCommented(line) {
|
|
131
|
+
return line.trimStart().startsWith(this.commentStyle.lineComment);
|
|
102
132
|
}
|
|
103
133
|
/**
|
|
104
134
|
* Comment out a line if not already commented
|
|
105
135
|
*/
|
|
106
|
-
commentLine(
|
|
107
|
-
const
|
|
108
|
-
|
|
136
|
+
commentLine(line) {
|
|
137
|
+
const trimmed = line.trimStart();
|
|
138
|
+
if (trimmed.startsWith(this.commentStyle.lineComment)) {
|
|
139
|
+
return line;
|
|
140
|
+
}
|
|
141
|
+
const indent = line.slice(0, line.length - trimmed.length);
|
|
142
|
+
return `${indent}${this.commentStyle.lineComment} ${trimmed}`;
|
|
109
143
|
}
|
|
110
144
|
/**
|
|
111
145
|
* Uncomment a line if commented
|
|
112
146
|
*/
|
|
113
|
-
uncommentLine(
|
|
114
|
-
const
|
|
115
|
-
if (!
|
|
116
|
-
return
|
|
117
|
-
|
|
118
|
-
|
|
147
|
+
uncommentLine(line) {
|
|
148
|
+
const trimmed = line.trimStart();
|
|
149
|
+
if (!trimmed.startsWith(this.commentStyle.lineComment)) {
|
|
150
|
+
return line;
|
|
151
|
+
}
|
|
152
|
+
const indent = line.slice(0, line.length - trimmed.length);
|
|
153
|
+
const withoutComment = trimmed.slice(this.commentStyle.lineComment.length);
|
|
154
|
+
const content = withoutComment.startsWith(" ") ? withoutComment.slice(1) : withoutComment;
|
|
155
|
+
return `${indent}${content}`;
|
|
119
156
|
}
|
|
120
157
|
}
|
|
121
|
-
class
|
|
158
|
+
class Switcher extends CommentManipulator {
|
|
122
159
|
/**
|
|
123
160
|
* Validate that the option exists in the selector
|
|
124
161
|
*/
|
|
125
|
-
validateOption(
|
|
126
|
-
|
|
162
|
+
validateOption(selector, optionName) {
|
|
163
|
+
const option = selector.options.find((o) => o.name === optionName);
|
|
164
|
+
if (!option) {
|
|
127
165
|
throw new Error(
|
|
128
|
-
`Option "${
|
|
166
|
+
`Option "${optionName}" not found in selector "${selector.name}"`
|
|
129
167
|
);
|
|
168
|
+
}
|
|
130
169
|
}
|
|
131
170
|
}
|
|
132
|
-
class
|
|
171
|
+
class SingleSwitcher extends Switcher {
|
|
133
172
|
/**
|
|
134
173
|
* Create a switcher for a specific file extension
|
|
135
174
|
*/
|
|
136
|
-
static forExtension(
|
|
137
|
-
return new
|
|
175
|
+
static forExtension(extension) {
|
|
176
|
+
return new SingleSwitcher(CommentStyle.fromExtension(extension));
|
|
138
177
|
}
|
|
139
178
|
/**
|
|
140
179
|
* Switch to a specific option, deactivating all others
|
|
141
180
|
*/
|
|
142
|
-
switch(
|
|
143
|
-
this.validateOption(
|
|
144
|
-
const
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
const
|
|
148
|
-
|
|
181
|
+
switch(content, selector, optionName) {
|
|
182
|
+
this.validateOption(selector, optionName);
|
|
183
|
+
const lines = content.split("\n");
|
|
184
|
+
for (const option of selector.options) {
|
|
185
|
+
const lineIndex = option.line - 1;
|
|
186
|
+
const line = lines[lineIndex];
|
|
187
|
+
if (option.name === optionName) {
|
|
188
|
+
lines[lineIndex] = this.uncommentLine(line);
|
|
189
|
+
} else {
|
|
190
|
+
lines[lineIndex] = this.commentLine(line);
|
|
191
|
+
}
|
|
149
192
|
}
|
|
150
|
-
return
|
|
151
|
-
`);
|
|
193
|
+
return lines.join("\n");
|
|
152
194
|
}
|
|
153
195
|
}
|
|
154
196
|
export {
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
197
|
+
CommentManipulator,
|
|
198
|
+
CommentStyle,
|
|
199
|
+
Parser,
|
|
200
|
+
SingleSwitcher,
|
|
201
|
+
Switcher,
|
|
202
|
+
defineConfig,
|
|
203
|
+
loadConfig
|
|
160
204
|
};
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Base config interface - plugins extend this via declaration merging
|
|
3
|
+
*/
|
|
4
|
+
export interface PikConfig {
|
|
5
|
+
[pluginName: string]: unknown;
|
|
6
|
+
}
|
|
7
|
+
/**
|
|
8
|
+
* Helper function for type-safe config definition
|
|
9
|
+
*/
|
|
10
|
+
export declare function defineConfig<T extends PikConfig>(config: T): T;
|
|
11
|
+
/**
|
|
12
|
+
* Load pik config from the current directory
|
|
13
|
+
*/
|
|
14
|
+
export declare function loadConfig(cwd?: string): Promise<PikConfig | null>;
|
|
15
|
+
//# sourceMappingURL=config.d.ts.map
|
|
@@ -0,0 +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"}
|
|
@@ -2,4 +2,5 @@ export type { Option } from './option.js';
|
|
|
2
2
|
export type { Selector } from './selector.js';
|
|
3
3
|
export type { ParseResult } from './parse-result.js';
|
|
4
4
|
export { CommentStyle } from './comment-style.js';
|
|
5
|
+
export type { PikPlugin } from './plugin.js';
|
|
5
6
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +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"}
|
|
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;AAClD,YAAY,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import type { Command } from 'commander';
|
|
2
|
+
/**
|
|
3
|
+
* Plugin interface for pik CLI plugins.
|
|
4
|
+
*/
|
|
5
|
+
export interface PikPlugin {
|
|
6
|
+
/** Display name of the plugin */
|
|
7
|
+
name: string;
|
|
8
|
+
/** Short description shown in help and menu */
|
|
9
|
+
description: string;
|
|
10
|
+
/** Command name used to invoke the plugin (e.g., "select", "worktree") */
|
|
11
|
+
command: string;
|
|
12
|
+
/** Alternative command names */
|
|
13
|
+
aliases?: string[];
|
|
14
|
+
/**
|
|
15
|
+
* Register the plugin's commands with the CLI.
|
|
16
|
+
* @param program - The commander program or command to attach to
|
|
17
|
+
*/
|
|
18
|
+
register: (program: Command) => void;
|
|
19
|
+
}
|
|
20
|
+
//# sourceMappingURL=plugin.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"plugin.d.ts","sourceRoot":"","sources":["../../../src/lib/types/plugin.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAEzC;;GAEG;AACH,MAAM,WAAW,SAAS;IACxB,iCAAiC;IACjC,IAAI,EAAE,MAAM,CAAC;IAEb,+CAA+C;IAC/C,WAAW,EAAE,MAAM,CAAC;IAEpB,0EAA0E;IAC1E,OAAO,EAAE,MAAM,CAAC;IAEhB,gCAAgC;IAChC,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;IAEnB;;;OAGG;IACH,QAAQ,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,IAAI,CAAC;CACtC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lsst/pik-core",
|
|
3
|
-
"version": "0.4.
|
|
3
|
+
"version": "0.4.2",
|
|
4
4
|
"description": "Core library for parsing and switching @pik config markers",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
@@ -33,5 +33,7 @@
|
|
|
33
33
|
"dist",
|
|
34
34
|
"!**/*.tsbuildinfo"
|
|
35
35
|
],
|
|
36
|
-
"dependencies": {
|
|
36
|
+
"dependencies": {
|
|
37
|
+
"commander": "^14.0.0"
|
|
38
|
+
}
|
|
37
39
|
}
|