@rrlab/ts-plugin 0.1.1-git-85e8cd0.0 → 0.1.2-git-c5c6e0f.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.mts CHANGED
@@ -19,6 +19,8 @@ declare class TscService extends ToolService implements TypeChecker {
19
19
  }
20
20
  declare function install(ctx: InstallContext): Promise<InstallResult>;
21
21
  declare function uninstall(ctx: UninstallContext): Promise<UninstallResult>;
22
- declare const ts: (options: void) => import("@rrlab/cli/plugin").Plugin;
22
+ declare const ts: (options?: {
23
+ only?: readonly "tsc"[] | undefined;
24
+ } | undefined) => import("@rrlab/cli/plugin").Plugin;
23
25
  //#endregion
24
26
  export { TOOL_VERSIONS, TscService, ts as default, install, uninstall };
package/dist/index.mjs CHANGED
@@ -1,6 +1,6 @@
1
1
  import fs from "node:fs/promises";
2
2
  import path from "node:path";
3
- import { ToolService, definePlugin } from "@rrlab/cli/plugin";
3
+ import { ToolService, decideScaffold, definePlugin, pickPreset } from "@rrlab/cli/plugin";
4
4
  import { colorize } from "@vlandoss/clibuddy";
5
5
  import { parse } from "comment-json";
6
6
  //#region src/tool-versions.ts
@@ -62,9 +62,17 @@ const PRESETS = {
62
62
  };
63
63
  const DEFAULT_PRESET = "no-dom-app";
64
64
  async function install(ctx) {
65
- const scaffoldDecision = await decideScaffoldAction(ctx, await pathExists(path.join(ctx.appPkg.dirPath, TSCONFIG)));
65
+ const scaffoldDecision = await decideScaffold(ctx, {
66
+ label: TSCONFIG,
67
+ fileExists: await pathExists(path.join(ctx.appPkg.dirPath, TSCONFIG)),
68
+ patchHint: "update extends, keep my other settings"
69
+ });
66
70
  if (scaffoldDecision === "skip") return { devDependencies: { typescript: TOOL_VERSIONS.typescript.install } };
67
- const presetInfo = PRESETS[await pickPreset(ctx)];
71
+ const presetInfo = PRESETS[await pickPreset(ctx, {
72
+ message: "Which kind of TS project do you need?",
73
+ presets: PRESETS,
74
+ defaultPreset: DEFAULT_PRESET
75
+ })];
68
76
  const devDependencies = {
69
77
  typescript: TOOL_VERSIONS.typescript.install,
70
78
  "@rrlab/ts-config": await ctx.release.resolve("@rrlab/ts-config")
@@ -123,51 +131,6 @@ async function uninstall(ctx) {
123
131
  files
124
132
  };
125
133
  }
126
- async function decideScaffoldAction(ctx, fileExists) {
127
- if (!fileExists) {
128
- if (ctx.flags.yes || ctx.flags.nonInteractive) return "create";
129
- const choice = await ctx.prompts.confirm({
130
- message: `Scaffold ${TSCONFIG} with an @rrlab/ts-config preset?`,
131
- initialValue: true
132
- });
133
- if (ctx.prompts.isCancel(choice)) throw new Error("Cancelled by user.");
134
- return choice ? "create" : "skip";
135
- }
136
- if (ctx.flags.yes || ctx.flags.nonInteractive) return "patch";
137
- const choice = await ctx.prompts.select({
138
- message: `${TSCONFIG} already exists. What do you want to do?`,
139
- options: [
140
- {
141
- value: "patch",
142
- label: "Patch — update extends, keep my other settings"
143
- },
144
- {
145
- value: "skip",
146
- label: "Skip — leave it alone"
147
- },
148
- {
149
- value: "overwrite",
150
- label: "Overwrite — replace with a fresh scaffold"
151
- }
152
- ],
153
- initialValue: "patch"
154
- });
155
- if (ctx.prompts.isCancel(choice)) throw new Error("Cancelled by user.");
156
- return choice;
157
- }
158
- async function pickPreset(ctx) {
159
- if (ctx.flags.yes || ctx.flags.nonInteractive) return DEFAULT_PRESET;
160
- const choice = await ctx.prompts.select({
161
- message: "Which kind of TS project do you need?",
162
- options: Object.entries(PRESETS).map(([value, meta]) => ({
163
- value,
164
- label: meta.label
165
- })),
166
- initialValue: DEFAULT_PRESET
167
- });
168
- if (ctx.prompts.isCancel(choice)) throw new Error("Cancelled by user.");
169
- return choice;
170
- }
171
134
  async function pathExists(p) {
172
135
  try {
173
136
  await fs.access(p);
@@ -181,15 +144,7 @@ const ts = definePlugin(() => ({
181
144
  apiVersion: 1,
182
145
  install,
183
146
  uninstall,
184
- async setup({ shell }) {
185
- const svc = new TscService(shell);
186
- try {
187
- await svc.getBinDir();
188
- } catch (_err) {
189
- throw new Error("@rrlab/ts-plugin requires typescript to be installed in the host project. Run: rr plugins add ts (or: pnpm add -D typescript)");
190
- }
191
- return { tsc: svc };
192
- }
147
+ capabilities: ({ shell }) => ({ tsc: new TscService(shell) })
193
148
  }));
194
149
  //#endregion
195
150
  export { TOOL_VERSIONS, TscService, ts as default, install, uninstall };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rrlab/ts-plugin",
3
- "version": "0.1.1-git-85e8cd0.0",
3
+ "version": "0.1.2-git-c5c6e0f.0",
4
4
  "description": "TypeScript plugin for @rrlab/cli — provides the tsc capability.",
5
5
  "homepage": "https://github.com/variableland/dx/tree/main/run-run/ts-plugin#readme",
6
6
  "bugs": {
@@ -38,12 +38,12 @@
38
38
  },
39
39
  "peerDependencies": {
40
40
  "typescript": ">=5.0.0",
41
- "@rrlab/cli": "0.0.3-git-85e8cd0.0"
41
+ "@rrlab/cli": "0.0.4-git-c5c6e0f.0"
42
42
  },
43
43
  "devDependencies": {
44
44
  "typescript": "6.0.3",
45
- "@rrlab/cli": "0.0.3-git-85e8cd0.0",
46
- "@rrlab/tsdown-config": "^0.1.0"
45
+ "@rrlab/tsdown-config": "^0.1.0",
46
+ "@rrlab/cli": "0.0.4-git-c5c6e0f.0"
47
47
  },
48
48
  "scripts": {
49
49
  "build": "tsdown",
package/src/index.ts CHANGED
@@ -1,10 +1,12 @@
1
1
  import fs from "node:fs/promises";
2
2
  import path from "node:path";
3
3
  import {
4
+ decideScaffold,
4
5
  definePlugin,
5
6
  type FileOp,
6
7
  type InstallContext,
7
8
  type InstallResult,
9
+ pickPreset,
8
10
  ToolService,
9
11
  type TypeChecker,
10
12
  type TypeCheckOptions,
@@ -50,18 +52,24 @@ const PRESETS: Record<Preset, PresetInfo> = {
50
52
 
51
53
  const DEFAULT_PRESET: Preset = "no-dom-app";
52
54
 
53
- type ExistingFileAction = "skip" | "patch" | "overwrite";
54
-
55
55
  export async function install(ctx: InstallContext): Promise<InstallResult> {
56
56
  const tsconfigPath = path.join(ctx.appPkg.dirPath, TSCONFIG);
57
57
  const fileExists = await pathExists(tsconfigPath);
58
+ const scaffoldDecision = await decideScaffold(ctx, {
59
+ label: TSCONFIG,
60
+ fileExists,
61
+ patchHint: "update extends, keep my other settings",
62
+ });
58
63
 
59
- const scaffoldDecision = await decideScaffoldAction(ctx, fileExists);
60
64
  if (scaffoldDecision === "skip") {
61
65
  return { devDependencies: { typescript: TOOL_VERSIONS.typescript.install } };
62
66
  }
63
67
 
64
- const preset = await pickPreset(ctx);
68
+ const preset = await pickPreset(ctx, {
69
+ message: "Which kind of TS project do you need?",
70
+ presets: PRESETS,
71
+ defaultPreset: DEFAULT_PRESET,
72
+ });
65
73
  const presetInfo = PRESETS[preset];
66
74
 
67
75
  const devDependencies: Record<string, string> = {
@@ -96,7 +104,6 @@ export async function uninstall(ctx: UninstallContext): Promise<UninstallResult>
96
104
  return { removeDependencies };
97
105
  }
98
106
 
99
- // Read the current tsconfig to decide between full delete and surgical unset.
100
107
  let existing: Record<string, unknown> | undefined;
101
108
  try {
102
109
  const text = await fs.readFile(tsconfigPath, "utf8");
@@ -119,51 +126,6 @@ export async function uninstall(ctx: UninstallContext): Promise<UninstallResult>
119
126
  return { removeDependencies, files };
120
127
  }
121
128
 
122
- async function decideScaffoldAction(
123
- ctx: InstallContext,
124
- fileExists: boolean,
125
- ): Promise<"create" | "patch" | "overwrite" | "skip"> {
126
- if (!fileExists) {
127
- if (ctx.flags.yes || ctx.flags.nonInteractive) return "create";
128
- const choice = await ctx.prompts.confirm({
129
- message: `Scaffold ${TSCONFIG} with an @rrlab/ts-config preset?`,
130
- initialValue: true,
131
- });
132
- if (ctx.prompts.isCancel(choice)) throw new Error("Cancelled by user.");
133
- return choice ? "create" : "skip";
134
- }
135
-
136
- // Existing file. Default to patch for migration safety.
137
- if (ctx.flags.yes || ctx.flags.nonInteractive) return "patch";
138
-
139
- const choice = await ctx.prompts.select<ExistingFileAction>({
140
- message: `${TSCONFIG} already exists. What do you want to do?`,
141
- options: [
142
- { value: "patch", label: "Patch — update extends, keep my other settings" },
143
- { value: "skip", label: "Skip — leave it alone" },
144
- { value: "overwrite", label: "Overwrite — replace with a fresh scaffold" },
145
- ],
146
- initialValue: "patch",
147
- });
148
- if (ctx.prompts.isCancel(choice)) throw new Error("Cancelled by user.");
149
- return choice;
150
- }
151
-
152
- async function pickPreset(ctx: InstallContext): Promise<Preset> {
153
- if (ctx.flags.yes || ctx.flags.nonInteractive) return DEFAULT_PRESET;
154
-
155
- const choice = await ctx.prompts.select<Preset>({
156
- message: "Which kind of TS project do you need?",
157
- options: (Object.entries(PRESETS) as Array<[Preset, PresetInfo]>).map(([value, meta]) => ({
158
- value,
159
- label: meta.label,
160
- })),
161
- initialValue: DEFAULT_PRESET,
162
- });
163
- if (ctx.prompts.isCancel(choice)) throw new Error("Cancelled by user.");
164
- return choice;
165
- }
166
-
167
129
  async function pathExists(p: string): Promise<boolean> {
168
130
  try {
169
131
  await fs.access(p);
@@ -173,23 +135,12 @@ async function pathExists(p: string): Promise<boolean> {
173
135
  }
174
136
  }
175
137
 
176
- const ts = definePlugin<void>(() => ({
138
+ const ts = definePlugin(() => ({
177
139
  name: "ts",
178
140
  apiVersion: 1,
179
141
  install,
180
142
  uninstall,
181
- async setup({ shell }) {
182
- const svc = new TscService(shell);
183
- try {
184
- await svc.getBinDir();
185
- } catch (_err) {
186
- throw new Error(
187
- "@rrlab/ts-plugin requires typescript to be installed in the host project. " +
188
- "Run: rr plugins add ts (or: pnpm add -D typescript)",
189
- );
190
- }
191
- return { tsc: svc };
192
- },
143
+ capabilities: ({ shell }) => ({ tsc: new TscService(shell) }),
193
144
  }));
194
145
 
195
146
  export default ts;