ugly-app 0.1.422 → 0.1.423

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.
@@ -1 +1 @@
1
- {"version":3,"file":"dev.d.ts","sourceRoot":"","sources":["../../src/cli/dev.ts"],"names":[],"mappings":"AA0DA,wBAAsB,MAAM,CAAC,IAAI,GAAE;IAAE,KAAK,EAAE,OAAO,CAAC;IAAC,OAAO,EAAE,OAAO,CAAA;CAAqC,GAAG,OAAO,CAAC,IAAI,CAAC,CAoKzH"}
1
+ {"version":3,"file":"dev.d.ts","sourceRoot":"","sources":["../../src/cli/dev.ts"],"names":[],"mappings":"AA4DA,wBAAsB,MAAM,CAAC,IAAI,GAAE;IAAE,KAAK,EAAE,OAAO,CAAC;IAAC,OAAO,EAAE,OAAO,CAAA;CAAqC,GAAG,OAAO,CAAC,IAAI,CAAC,CA6MzH"}
package/dist/cli/dev.js CHANGED
@@ -1,7 +1,9 @@
1
- import { exec, execSync, spawn } from 'child_process';
1
+ import { exec, execSync } from 'child_process';
2
2
  import fs from 'fs';
3
3
  import net from 'net';
4
4
  import path from 'path';
5
+ import { createRequire } from 'module';
6
+ import concurrently from 'concurrently';
5
7
  /**
6
8
  * Return the PID of the process listening on `port`, or null if none.
7
9
  * Cross-platform; shells out to `lsof` on Unix and `netstat` on Windows.
@@ -127,79 +129,108 @@ export async function runDev(opts = { watch: false, verbose: false }) {
127
129
  console.log(`[ugly-app] NODE_ENV: ${process.env['NODE_ENV']}`);
128
130
  console.log(`[ugly-app] POSTGRES_URL: ${process.env['POSTGRES_URL'] ?? '(default)'}`);
129
131
  }
130
- return new Promise((resolve, reject) => {
131
- const isWin = process.platform === 'win32';
132
- const noFail = (cmd) => isWin ? `(${cmd} || (exit /b 0))` : `${cmd} || true`;
133
- const binDir = path.join(process.cwd(), 'node_modules', '.bin') + path.sep;
134
- const bin = (name) => `"${binDir}${name}"`;
135
- const q = (s) => `"${s.replace(/"/g, '\\"')}"`;
136
- const serverCmd = opts.watch
137
- ? `${bin('tsx')} watch --clear-screen=false --ignore ./client --ignore "**/node_modules/**" server/index.ts`
138
- : `${bin('tsx')} server/index.ts`;
139
- const hasEsw = fs.existsSync(path.join(binDir, 'esw'));
140
- const rawFlag = isWin ? '--raw' : '';
141
- const namesFlag = isWin
142
- ? ''
143
- : hasEsw ? '--names server,tsc,eslint' : '--names server,tsc';
144
- const colorsFlag = isWin
145
- ? ''
146
- : hasEsw ? '--prefix-colors green,yellow,magenta' : '--prefix-colors green,yellow';
147
- const cmd = opts.watch
148
- ? [
149
- bin('concurrently'),
150
- namesFlag,
151
- colorsFlag,
152
- rawFlag,
153
- '--kill-others-on-fail',
154
- '--handle-input',
155
- q(serverCmd),
156
- q(noFail(`${bin('tsc')} --watch --noEmit --preserveWatchOutput`)),
157
- ...(hasEsw ? [q(noFail(`${bin('esw')} --watch --changed server client shared`))] : []),
158
- ].filter(Boolean).join(' ')
159
- : [
160
- bin('concurrently'),
161
- '--names server',
162
- '--prefix-colors green',
163
- rawFlag,
164
- '--kill-others-on-fail',
165
- '--handle-input',
166
- q(serverCmd),
167
- ].filter(Boolean).join(' ');
168
- if (verbose) {
169
- console.log(`[ugly-app] Spawning: ${cmd}`);
132
+ const isWin = process.platform === 'win32';
133
+ const noFail = (cmd) => isWin ? `(${cmd} || (exit /b 0))` : `${cmd} || true`;
134
+ // Resolve a tool's executable JS entry through the project's
135
+ // node_modules graph rather than assuming it's hoisted to
136
+ // `node_modules/.bin/`. Under pnpm-strict, transitive bins (e.g.
137
+ // `concurrently`, which is a dep of ugly-app and not of the user
138
+ // project) never land in the top-level `.bin/`, and the old
139
+ // `node_modules/.bin/<name>` path then exits 127. Resolving the
140
+ // package's `bin` entry via Node module resolution works for npm,
141
+ // yarn, pnpm-strict, and pnpm-shamefully-hoist alike, and also
142
+ // sidesteps Windows shebang issues since we invoke `node <jsfile>`
143
+ // directly.
144
+ function resolveBinJs(pkg, binName) {
145
+ try {
146
+ const fromCwd = path.join(process.cwd(), 'package.json');
147
+ const req = createRequire(fromCwd);
148
+ const pkgJsonPath = req.resolve(`${pkg}/package.json`);
149
+ const pkgJson = JSON.parse(fs.readFileSync(pkgJsonPath, 'utf-8'));
150
+ const pkgDir = path.dirname(pkgJsonPath);
151
+ const binField = pkgJson.bin;
152
+ if (!binField)
153
+ return null;
154
+ const rel = typeof binField === 'string'
155
+ ? binField
156
+ : binField[binName ?? pkgJson.name];
157
+ if (!rel)
158
+ return null;
159
+ return path.join(pkgDir, rel);
170
160
  }
171
- const child = spawn(cmd, [], {
172
- stdio: 'inherit',
173
- cwd: process.cwd(),
174
- shell: true,
175
- });
176
- // Open browser once the server is listening — opt-in only. Most users
177
- // either run ugly-app inside ugly-studio's preview iframe or already
178
- // have the tab open from a previous run, so a system browser window
179
- // popping open on every restart is intrusive. Set UGLY_APP_OPEN_BROWSER=1
180
- // to opt back in.
181
- const openBrowser = process.env['UGLY_APP_OPEN_BROWSER'] === '1';
182
- if (openBrowser) {
183
- const url = `http://localhost:${port}`;
184
- waitForPort(parseInt(port, 10)).then(() => {
185
- const openCmd = process.platform === 'darwin' ? 'open' :
186
- process.platform === 'win32' ? 'start' : 'xdg-open';
187
- exec(`${openCmd} ${url}`);
188
- }).catch(() => { });
161
+ catch {
162
+ return null;
189
163
  }
190
- child.on('error', (err) => {
191
- if (verbose)
192
- console.error('[ugly-app] Spawn error:', err);
193
- reject(err);
164
+ }
165
+ const tsxBin = resolveBinJs('tsx', 'tsx');
166
+ const tscBin = resolveBinJs('typescript', 'tsc');
167
+ const eswBin = resolveBinJs('eslint-watch', 'esw');
168
+ if (!tsxBin) {
169
+ throw new Error(`[ugly-app] Could not resolve 'tsx' from ${process.cwd()}. ` +
170
+ `Run \`npm install\` (or \`pnpm install\`) and try again.`);
171
+ }
172
+ const q = (s) => `"${s.replace(/"/g, '\\"')}"`;
173
+ const node = q(process.execPath);
174
+ const serverCmd = opts.watch
175
+ ? `${node} ${q(tsxBin)} watch --clear-screen=false --ignore ./client --ignore "**/node_modules/**" server/index.ts`
176
+ : `${node} ${q(tsxBin)} server/index.ts`;
177
+ const hasEsw = eswBin !== null;
178
+ const hasTsc = tscBin !== null;
179
+ const commands = [
180
+ { command: serverCmd, name: 'server', prefixColor: 'green' },
181
+ ];
182
+ if (hasTsc) {
183
+ commands.push({
184
+ command: noFail(`${node} ${q(tscBin)} --watch --noEmit --preserveWatchOutput`),
185
+ name: 'tsc',
186
+ prefixColor: 'yellow',
194
187
  });
195
- child.on('close', (code) => {
196
- if (verbose)
197
- console.log(`[ugly-app] Process exited with code ${code}`);
198
- if (code !== 0)
199
- reject(new Error(`dev process exited with code ${code}`));
200
- else
201
- resolve();
188
+ }
189
+ if (opts.watch && hasEsw) {
190
+ commands.push({
191
+ command: noFail(`${node} ${q(eswBin)} --watch --changed server client shared`),
192
+ name: 'eslint',
193
+ prefixColor: 'magenta',
202
194
  });
195
+ }
196
+ // Non-watch mode runs only the server.
197
+ const finalCommands = opts.watch ? commands : commands.slice(0, 1);
198
+ if (verbose) {
199
+ console.log('[ugly-app] Spawning:');
200
+ for (const c of finalCommands) {
201
+ console.log(` [${c.name}] ${c.command}`);
202
+ }
203
+ }
204
+ const { result } = concurrently(finalCommands, {
205
+ killOthers: ['failure'],
206
+ handleInput: true,
207
+ raw: !isWin,
203
208
  });
209
+ // Open browser once the server is listening — opt-in only. Most users
210
+ // either run ugly-app inside ugly-studio's preview iframe or already
211
+ // have the tab open from a previous run, so a system browser window
212
+ // popping open on every restart is intrusive. Set UGLY_APP_OPEN_BROWSER=1
213
+ // to opt back in.
214
+ const openBrowser = process.env['UGLY_APP_OPEN_BROWSER'] === '1';
215
+ if (openBrowser) {
216
+ const url = `http://localhost:${port}`;
217
+ waitForPort(parseInt(port, 10)).then(() => {
218
+ const openCmd = process.platform === 'darwin' ? 'open' :
219
+ process.platform === 'win32' ? 'start' : 'xdg-open';
220
+ exec(`${openCmd} ${url}`);
221
+ }).catch(() => { });
222
+ }
223
+ try {
224
+ await result;
225
+ }
226
+ catch (err) {
227
+ // concurrently rejects with an array of CloseEvent on non-zero exits.
228
+ if (Array.isArray(err)) {
229
+ const failed = err.find((e) => e.exitCode !== 0);
230
+ const code = failed?.exitCode ?? 1;
231
+ throw new Error(`dev process exited with code ${code}`);
232
+ }
233
+ throw err;
234
+ }
204
235
  }
205
236
  //# sourceMappingURL=dev.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"dev.js","sourceRoot":"","sources":["../../src/cli/dev.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"dev.js","sourceRoot":"","sources":["../../src/cli/dev.ts"],"names":[],"mappings":"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"}
@@ -1,2 +1,2 @@
1
- export declare const CLI_VERSION = "0.1.422";
1
+ export declare const CLI_VERSION = "0.1.423";
2
2
  //# sourceMappingURL=version.d.ts.map
@@ -1,3 +1,3 @@
1
1
  // Auto-generated by prebuild — do not edit manually
2
- export const CLI_VERSION = "0.1.422";
2
+ export const CLI_VERSION = "0.1.423";
3
3
  //# sourceMappingURL=version.js.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ugly-app",
3
- "version": "0.1.422",
3
+ "version": "0.1.423",
4
4
  "type": "module",
5
5
  "main": "./dist/server/index.js",
6
6
  "exports": {
package/src/cli/dev.ts CHANGED
@@ -1,7 +1,9 @@
1
- import { exec, execSync, spawn } from 'child_process';
1
+ import { exec, execSync } from 'child_process';
2
2
  import fs from 'fs';
3
3
  import net from 'net';
4
4
  import path from 'path';
5
+ import { createRequire } from 'module';
6
+ import concurrently from 'concurrently';
5
7
  /**
6
8
  * Return the PID of the process listening on `port`, or null if none.
7
9
  * Cross-platform; shells out to `lsof` on Unix and `netstat` on Windows.
@@ -139,85 +141,126 @@ export async function runDev(opts: { watch: boolean; verbose: boolean } = { watc
139
141
  console.log(`[ugly-app] POSTGRES_URL: ${process.env['POSTGRES_URL'] ?? '(default)'}`);
140
142
  }
141
143
 
142
- return new Promise<void>((resolve, reject) => {
143
- const isWin = process.platform === 'win32';
144
- const noFail = (cmd: string) =>
145
- isWin ? `(${cmd} || (exit /b 0))` : `${cmd} || true`;
146
-
147
- const binDir = path.join(process.cwd(), 'node_modules', '.bin') + path.sep;
148
- const bin = (name: string) => `"${binDir}${name}"`;
149
- const q = (s: string) => `"${s.replace(/"/g, '\\"')}"`;
150
-
151
- const serverCmd = opts.watch
152
- ? `${bin('tsx')} watch --clear-screen=false --ignore ./client --ignore "**/node_modules/**" server/index.ts`
153
- : `${bin('tsx')} server/index.ts`;
154
-
155
- const hasEsw = fs.existsSync(path.join(binDir, 'esw'));
156
-
157
- const rawFlag = isWin ? '--raw' : '';
158
- const namesFlag = isWin
159
- ? ''
160
- : hasEsw ? '--names server,tsc,eslint' : '--names server,tsc';
161
- const colorsFlag = isWin
162
- ? ''
163
- : hasEsw ? '--prefix-colors green,yellow,magenta' : '--prefix-colors green,yellow';
164
-
165
- const cmd = opts.watch
166
- ? [
167
- bin('concurrently'),
168
- namesFlag,
169
- colorsFlag,
170
- rawFlag,
171
- '--kill-others-on-fail',
172
- '--handle-input',
173
- q(serverCmd),
174
- q(noFail(`${bin('tsc')} --watch --noEmit --preserveWatchOutput`)),
175
- ...(hasEsw ? [q(noFail(`${bin('esw')} --watch --changed server client shared`))] : []),
176
- ].filter(Boolean).join(' ')
177
- : [
178
- bin('concurrently'),
179
- '--names server',
180
- '--prefix-colors green',
181
- rawFlag,
182
- '--kill-others-on-fail',
183
- '--handle-input',
184
- q(serverCmd),
185
- ].filter(Boolean).join(' ');
186
-
187
- if (verbose) {
188
- console.log(`[ugly-app] Spawning: ${cmd}`);
144
+ const isWin = process.platform === 'win32';
145
+ const noFail = (cmd: string) =>
146
+ isWin ? `(${cmd} || (exit /b 0))` : `${cmd} || true`;
147
+
148
+ // Resolve a tool's executable JS entry through the project's
149
+ // node_modules graph rather than assuming it's hoisted to
150
+ // `node_modules/.bin/`. Under pnpm-strict, transitive bins (e.g.
151
+ // `concurrently`, which is a dep of ugly-app and not of the user
152
+ // project) never land in the top-level `.bin/`, and the old
153
+ // `node_modules/.bin/<name>` path then exits 127. Resolving the
154
+ // package's `bin` entry via Node module resolution works for npm,
155
+ // yarn, pnpm-strict, and pnpm-shamefully-hoist alike, and also
156
+ // sidesteps Windows shebang issues since we invoke `node <jsfile>`
157
+ // directly.
158
+ function resolveBinJs(pkg: string, binName?: string): string | null {
159
+ try {
160
+ const fromCwd = path.join(process.cwd(), 'package.json');
161
+ const req = createRequire(fromCwd);
162
+ const pkgJsonPath = req.resolve(`${pkg}/package.json`);
163
+ const pkgJson = JSON.parse(fs.readFileSync(pkgJsonPath, 'utf-8')) as {
164
+ name: string;
165
+ bin?: string | Record<string, string>;
166
+ };
167
+ const pkgDir = path.dirname(pkgJsonPath);
168
+ const binField = pkgJson.bin;
169
+ if (!binField) return null;
170
+ const rel =
171
+ typeof binField === 'string'
172
+ ? binField
173
+ : binField[binName ?? pkgJson.name];
174
+ if (!rel) return null;
175
+ return path.join(pkgDir, rel);
176
+ } catch {
177
+ return null;
189
178
  }
179
+ }
190
180
 
191
- const child = spawn(cmd, [], {
192
- stdio: 'inherit',
193
- cwd: process.cwd(),
194
- shell: true,
195
- });
181
+ const tsxBin = resolveBinJs('tsx', 'tsx');
182
+ const tscBin = resolveBinJs('typescript', 'tsc');
183
+ const eswBin = resolveBinJs('eslint-watch', 'esw');
196
184
 
197
- // Open browser once the server is listening — opt-in only. Most users
198
- // either run ugly-app inside ugly-studio's preview iframe or already
199
- // have the tab open from a previous run, so a system browser window
200
- // popping open on every restart is intrusive. Set UGLY_APP_OPEN_BROWSER=1
201
- // to opt back in.
202
- const openBrowser = process.env['UGLY_APP_OPEN_BROWSER'] === '1';
203
- if (openBrowser) {
204
- const url = `http://localhost:${port}`;
205
- waitForPort(parseInt(port, 10)).then(() => {
206
- const openCmd =
207
- process.platform === 'darwin' ? 'open' :
208
- process.platform === 'win32' ? 'start' : 'xdg-open';
209
- exec(`${openCmd} ${url}`);
210
- }).catch(() => { /* best effort */ });
211
- }
185
+ if (!tsxBin) {
186
+ throw new Error(
187
+ `[ugly-app] Could not resolve 'tsx' from ${process.cwd()}. ` +
188
+ `Run \`npm install\` (or \`pnpm install\`) and try again.`,
189
+ );
190
+ }
212
191
 
213
- child.on('error', (err) => {
214
- if (verbose) console.error('[ugly-app] Spawn error:', err);
215
- reject(err);
192
+ const q = (s: string) => `"${s.replace(/"/g, '\\"')}"`;
193
+ const node = q(process.execPath);
194
+
195
+ const serverCmd = opts.watch
196
+ ? `${node} ${q(tsxBin)} watch --clear-screen=false --ignore ./client --ignore "**/node_modules/**" server/index.ts`
197
+ : `${node} ${q(tsxBin)} server/index.ts`;
198
+
199
+ const hasEsw = eswBin !== null;
200
+ const hasTsc = tscBin !== null;
201
+
202
+ const commands: { command: string; name: string; prefixColor: string }[] = [
203
+ { command: serverCmd, name: 'server', prefixColor: 'green' },
204
+ ];
205
+ if (hasTsc) {
206
+ commands.push({
207
+ command: noFail(
208
+ `${node} ${q(tscBin!)} --watch --noEmit --preserveWatchOutput`,
209
+ ),
210
+ name: 'tsc',
211
+ prefixColor: 'yellow',
216
212
  });
217
- child.on('close', (code) => {
218
- if (verbose) console.log(`[ugly-app] Process exited with code ${code}`);
219
- if (code !== 0) reject(new Error(`dev process exited with code ${code}`));
220
- else resolve();
213
+ }
214
+ if (opts.watch && hasEsw) {
215
+ commands.push({
216
+ command: noFail(
217
+ `${node} ${q(eswBin!)} --watch --changed server client shared`,
218
+ ),
219
+ name: 'eslint',
220
+ prefixColor: 'magenta',
221
221
  });
222
+ }
223
+ // Non-watch mode runs only the server.
224
+ const finalCommands = opts.watch ? commands : commands.slice(0, 1);
225
+
226
+ if (verbose) {
227
+ console.log('[ugly-app] Spawning:');
228
+ for (const c of finalCommands) {
229
+ console.log(` [${c.name}] ${c.command}`);
230
+ }
231
+ }
232
+
233
+ const { result } = concurrently(finalCommands, {
234
+ killOthers: ['failure'],
235
+ handleInput: true,
236
+ raw: !isWin,
222
237
  });
238
+
239
+ // Open browser once the server is listening — opt-in only. Most users
240
+ // either run ugly-app inside ugly-studio's preview iframe or already
241
+ // have the tab open from a previous run, so a system browser window
242
+ // popping open on every restart is intrusive. Set UGLY_APP_OPEN_BROWSER=1
243
+ // to opt back in.
244
+ const openBrowser = process.env['UGLY_APP_OPEN_BROWSER'] === '1';
245
+ if (openBrowser) {
246
+ const url = `http://localhost:${port}`;
247
+ waitForPort(parseInt(port, 10)).then(() => {
248
+ const openCmd =
249
+ process.platform === 'darwin' ? 'open' :
250
+ process.platform === 'win32' ? 'start' : 'xdg-open';
251
+ exec(`${openCmd} ${url}`);
252
+ }).catch(() => { /* best effort */ });
253
+ }
254
+
255
+ try {
256
+ await result;
257
+ } catch (err) {
258
+ // concurrently rejects with an array of CloseEvent on non-zero exits.
259
+ if (Array.isArray(err)) {
260
+ const failed = err.find((e: { exitCode: number | string }) => e.exitCode !== 0);
261
+ const code = failed?.exitCode ?? 1;
262
+ throw new Error(`dev process exited with code ${code}`);
263
+ }
264
+ throw err;
265
+ }
223
266
  }
@@ -1,2 +1,2 @@
1
1
  // Auto-generated by prebuild — do not edit manually
2
- export const CLI_VERSION = "0.1.422";
2
+ export const CLI_VERSION = "0.1.423";