@fluojs/cli 1.1.0 → 3.0.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.ko.md +183 -22
- package/README.md +186 -22
- package/dist/cli.d.ts +5 -4
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +128 -35
- package/dist/commands/diagnostics.d.ts +35 -0
- package/dist/commands/diagnostics.d.ts.map +1 -1
- package/dist/commands/diagnostics.js +60 -0
- package/dist/commands/generate.d.ts +1 -49
- package/dist/commands/generate.d.ts.map +1 -1
- package/dist/commands/generate.js +1 -214
- package/dist/commands/inspect.d.ts +5 -7
- package/dist/commands/inspect.d.ts.map +1 -1
- package/dist/commands/inspect.js +85 -65
- package/dist/commands/migrate.d.ts.map +1 -1
- package/dist/commands/migrate.js +27 -15
- package/dist/commands/migration-transform-tokens.d.ts +15 -0
- package/dist/commands/migration-transform-tokens.d.ts.map +1 -0
- package/dist/commands/migration-transform-tokens.js +41 -0
- package/dist/commands/new.d.ts +0 -6
- package/dist/commands/new.d.ts.map +1 -1
- package/dist/commands/new.js +42 -96
- package/dist/commands/output-path-safety.d.ts +14 -0
- package/dist/commands/output-path-safety.d.ts.map +1 -0
- package/dist/commands/output-path-safety.js +34 -0
- package/dist/commands/scripts.d.ts +1 -1
- package/dist/commands/scripts.d.ts.map +1 -1
- package/dist/commands/scripts.js +13 -7
- package/dist/commands/typegen-artifact.d.ts +54 -0
- package/dist/commands/typegen-artifact.d.ts.map +1 -0
- package/dist/commands/typegen-artifact.js +117 -0
- package/dist/commands/typegen-generation-child.d.ts +2 -0
- package/dist/commands/typegen-generation-child.d.ts.map +1 -0
- package/dist/commands/typegen-generation-child.js +59 -0
- package/dist/commands/typegen-generation-process.d.ts +46 -0
- package/dist/commands/typegen-generation-process.d.ts.map +1 -0
- package/dist/commands/typegen-generation-process.js +131 -0
- package/dist/commands/typegen-generation-protocol.d.ts +16 -0
- package/dist/commands/typegen-generation-protocol.d.ts.map +1 -0
- package/dist/commands/typegen-generation-protocol.js +35 -0
- package/dist/commands/typegen-isolated-source.d.ts +10 -0
- package/dist/commands/typegen-isolated-source.d.ts.map +1 -0
- package/dist/commands/typegen-isolated-source.js +75 -0
- package/dist/commands/typegen-options.d.ts +20 -0
- package/dist/commands/typegen-options.d.ts.map +1 -0
- package/dist/commands/typegen-options.js +71 -0
- package/dist/commands/typegen-source.d.ts +59 -0
- package/dist/commands/typegen-source.d.ts.map +1 -0
- package/dist/commands/typegen-source.js +183 -0
- package/dist/commands/typegen-watch.d.ts +46 -0
- package/dist/commands/typegen-watch.d.ts.map +1 -0
- package/dist/commands/typegen-watch.js +212 -0
- package/dist/commands/typegen.d.ts +29 -0
- package/dist/commands/typegen.d.ts.map +1 -0
- package/dist/commands/typegen.js +119 -0
- package/dist/dev-runner/node-restart-runner.d.ts +6 -0
- package/dist/dev-runner/node-restart-runner.d.ts.map +1 -1
- package/dist/dev-runner/node-restart-runner.js +64 -13
- package/dist/fixtures/inspect-react-app.module.d.ts +4 -0
- package/dist/fixtures/inspect-react-app.module.d.ts.map +1 -0
- package/dist/fixtures/inspect-react-app.module.js +32 -0
- package/dist/fixtures/typegen-react-app.module.d.ts +4 -0
- package/dist/fixtures/typegen-react-app.module.d.ts.map +1 -0
- package/dist/fixtures/typegen-react-app.module.js +33 -0
- package/dist/generate-command.d.ts +50 -0
- package/dist/generate-command.d.ts.map +1 -0
- package/dist/generate-command.js +214 -0
- package/dist/index.d.ts +6 -5
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +6 -5
- package/dist/new/install.js +1 -1
- package/dist/new/package-spec-resolver.d.ts.map +1 -1
- package/dist/new/package-spec-resolver.js +50 -59
- package/dist/new/prompt.d.ts +1 -0
- package/dist/new/prompt.d.ts.map +1 -1
- package/dist/new/prompt.js +40 -12
- package/dist/new/published-internal-dependencies.d.ts +20 -0
- package/dist/new/published-internal-dependencies.d.ts.map +1 -0
- package/dist/new/published-internal-dependencies.js +20 -0
- package/dist/new/react-vite-ssr-scaffold.d.ts +19 -0
- package/dist/new/react-vite-ssr-scaffold.d.ts.map +1 -0
- package/dist/new/react-vite-ssr-scaffold.js +108 -0
- package/dist/new/resolver.d.ts +2 -2
- package/dist/new/resolver.d.ts.map +1 -1
- package/dist/new/resolver.js +5 -1
- package/dist/new/scaffold.d.ts.map +1 -1
- package/dist/new/scaffold.js +177 -54
- package/dist/new/starter-profiles.d.ts +8 -4
- package/dist/new/starter-profiles.d.ts.map +1 -1
- package/dist/new/starter-profiles.js +52 -18
- package/dist/new/templates/react-vite-ssr/README.md.ejs +74 -0
- package/dist/new/templates/react-vite-ssr/playwright.config.ts.ejs +26 -0
- package/dist/new/templates/react-vite-ssr/src/app.test.ts.ejs +82 -0
- package/dist/new/templates/react-vite-ssr/src/app.ts.ejs +91 -0
- package/dist/new/templates/react-vite-ssr/src/entry-client.tsx.ejs +29 -0
- package/dist/new/templates/react-vite-ssr/src/entry-server.tsx.ejs +52 -0
- package/dist/new/templates/react-vite-ssr/src/load-manifest.test.ts.ejs +55 -0
- package/dist/new/templates/react-vite-ssr/src/load-manifest.ts.ejs +53 -0
- package/dist/new/templates/react-vite-ssr/src/main.ts.ejs +18 -0
- package/dist/new/templates/react-vite-ssr/src/page.tsx.ejs +43 -0
- package/dist/new/templates/react-vite-ssr/src/react-app.test.tsx.ejs +67 -0
- package/dist/new/templates/react-vite-ssr/src/react-app.tsx.ejs +46 -0
- package/dist/new/templates/react-vite-ssr/src/styles.css.ejs +25 -0
- package/dist/new/templates/react-vite-ssr/src/styles.d.ts.ejs +1 -0
- package/dist/new/templates/react-vite-ssr/tests/production-hydration.spec.ts.ejs +54 -0
- package/dist/new/templates/react-vite-ssr/tsconfig.json.ejs +16 -0
- package/dist/new/templates/react-vite-ssr/vite.client.config.ts.ejs +24 -0
- package/dist/new/templates/react-vite-ssr/vite.server.config.ts.ejs +17 -0
- package/dist/new/templates/react-vite-ssr/vitest.config.ts.ejs +10 -0
- package/dist/new/types.d.ts +4 -2
- package/dist/new/types.d.ts.map +1 -1
- package/dist/public-generate.d.ts +2 -0
- package/dist/public-generate.d.ts.map +1 -0
- package/dist/public-generate.js +1 -0
- package/dist/public-inspect.d.ts +13 -0
- package/dist/public-inspect.d.ts.map +1 -0
- package/dist/public-inspect.js +16 -0
- package/dist/public-new.d.ts +13 -0
- package/dist/public-new.d.ts.map +1 -0
- package/dist/public-new.js +16 -0
- package/dist/public-typegen.d.ts +14 -0
- package/dist/public-typegen.d.ts.map +1 -0
- package/dist/public-typegen.js +17 -0
- package/dist/run-cli.d.ts +2 -1
- package/dist/run-cli.d.ts.map +1 -1
- package/dist/studio/sidecar.d.ts.map +1 -1
- package/dist/studio/sidecar.js +106 -14
- package/dist/transforms/nestjs-migrate.d.ts +4 -1
- package/dist/transforms/nestjs-migrate.d.ts.map +1 -1
- package/dist/transforms/nestjs-migrate.js +625 -65
- package/dist/typegen-contract.d.ts +10 -0
- package/dist/typegen-contract.d.ts.map +1 -0
- package/dist/typegen-contract.js +9 -0
- package/dist/usage.d.ts +19 -0
- package/dist/usage.d.ts.map +1 -0
- package/dist/usage.js +178 -0
- package/package.json +19 -10
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
/** Scheduler used to debounce typegen filesystem bursts deterministically. */
|
|
2
|
+
export type TypegenWatchScheduler = {
|
|
3
|
+
readonly clear: (handle: number) => void;
|
|
4
|
+
readonly set: (callback: () => void, delayMs: number) => number;
|
|
5
|
+
};
|
|
6
|
+
/** Signal registration boundary owned by one typegen watch invocation. */
|
|
7
|
+
export type TypegenWatchSignalTarget = {
|
|
8
|
+
readonly off: (signal: 'SIGINT' | 'SIGTERM', listener: () => void) => unknown;
|
|
9
|
+
readonly once: (signal: 'SIGINT' | 'SIGTERM', listener: () => void) => unknown;
|
|
10
|
+
};
|
|
11
|
+
/** Minimal watcher resource acquired by typegen watch mode. */
|
|
12
|
+
export type TypegenWatcher = {
|
|
13
|
+
close(): void;
|
|
14
|
+
on(event: 'error', listener: (error: Error) => void): TypegenWatcher;
|
|
15
|
+
};
|
|
16
|
+
/** One child generation owned by a typegen watch coordinator. */
|
|
17
|
+
export type TypegenWatchGeneration = {
|
|
18
|
+
cancel(): void;
|
|
19
|
+
readonly result: Promise<string>;
|
|
20
|
+
};
|
|
21
|
+
type TypegenWatchTarget = (target: string, options: {
|
|
22
|
+
readonly persistent: boolean;
|
|
23
|
+
readonly recursive: boolean;
|
|
24
|
+
}, listener: (event: string, filename: string | Buffer | null) => void) => TypegenWatcher;
|
|
25
|
+
/** Dependencies and callbacks for one bounded typegen watch lifecycle. */
|
|
26
|
+
export type TypegenWatchOptions = {
|
|
27
|
+
readonly commit: (source: string, signal: AbortSignal) => Promise<void>;
|
|
28
|
+
readonly debounceMs?: number;
|
|
29
|
+
readonly modulePath: string;
|
|
30
|
+
readonly onError?: (error: unknown) => void;
|
|
31
|
+
readonly onReady?: (watchRoot: string) => void;
|
|
32
|
+
readonly outputPath: string;
|
|
33
|
+
readonly scheduler?: TypegenWatchScheduler;
|
|
34
|
+
readonly signalTarget?: TypegenWatchSignalTarget;
|
|
35
|
+
readonly startGeneration: () => TypegenWatchGeneration;
|
|
36
|
+
readonly watchTarget?: TypegenWatchTarget;
|
|
37
|
+
};
|
|
38
|
+
/**
|
|
39
|
+
* Watches the application module directory while generating an initial current artifact.
|
|
40
|
+
*
|
|
41
|
+
* @param options Generation, watcher, scheduler, and signal lifecycle dependencies.
|
|
42
|
+
* @returns Exit code `0` after signal shutdown or `1` after an asynchronous watcher failure.
|
|
43
|
+
*/
|
|
44
|
+
export declare function runTypegenWatch(options: TypegenWatchOptions): Promise<number>;
|
|
45
|
+
export {};
|
|
46
|
+
//# sourceMappingURL=typegen-watch.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"typegen-watch.d.ts","sourceRoot":"","sources":["../../src/commands/typegen-watch.ts"],"names":[],"mappings":"AAGA,8EAA8E;AAC9E,MAAM,MAAM,qBAAqB,GAAG;IAClC,QAAQ,CAAC,KAAK,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC;IACzC,QAAQ,CAAC,GAAG,EAAE,CAAC,QAAQ,EAAE,MAAM,IAAI,EAAE,OAAO,EAAE,MAAM,KAAK,MAAM,CAAC;CACjE,CAAC;AAEF,0EAA0E;AAC1E,MAAM,MAAM,wBAAwB,GAAG;IACrC,QAAQ,CAAC,GAAG,EAAE,CAAC,MAAM,EAAE,QAAQ,GAAG,SAAS,EAAE,QAAQ,EAAE,MAAM,IAAI,KAAK,OAAO,CAAC;IAC9E,QAAQ,CAAC,IAAI,EAAE,CAAC,MAAM,EAAE,QAAQ,GAAG,SAAS,EAAE,QAAQ,EAAE,MAAM,IAAI,KAAK,OAAO,CAAC;CAChF,CAAC;AAEF,+DAA+D;AAC/D,MAAM,MAAM,cAAc,GAAG;IAC3B,KAAK,IAAI,IAAI,CAAC;IACd,EAAE,CAAC,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,GAAG,cAAc,CAAC;CACtE,CAAC;AAEF,iEAAiE;AACjE,MAAM,MAAM,sBAAsB,GAAG;IACnC,MAAM,IAAI,IAAI,CAAC;IACf,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC;CAClC,CAAC;AAEF,KAAK,kBAAkB,GAAG,CACxB,MAAM,EAAE,MAAM,EACd,OAAO,EAAE;IAAE,QAAQ,CAAC,UAAU,EAAE,OAAO,CAAC;IAAC,QAAQ,CAAC,SAAS,EAAE,OAAO,CAAA;CAAE,EACtE,QAAQ,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,KAAK,IAAI,KAChE,cAAc,CAAC;AAEpB,0EAA0E;AAC1E,MAAM,MAAM,mBAAmB,GAAG;IAChC,QAAQ,CAAC,MAAM,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,WAAW,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IACxE,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,IAAI,CAAC;IAC5C,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,IAAI,CAAC;IAC/C,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,SAAS,CAAC,EAAE,qBAAqB,CAAC;IAC3C,QAAQ,CAAC,YAAY,CAAC,EAAE,wBAAwB,CAAC;IACjD,QAAQ,CAAC,eAAe,EAAE,MAAM,sBAAsB,CAAC;IACvD,QAAQ,CAAC,WAAW,CAAC,EAAE,kBAAkB,CAAC;CAC3C,CAAC;AAwCF;;;;;GAKG;AACH,wBAAsB,eAAe,CAAC,OAAO,EAAE,mBAAmB,GAAG,OAAO,CAAC,MAAM,CAAC,CA0KnF"}
|
|
@@ -0,0 +1,212 @@
|
|
|
1
|
+
import { watch } from 'node:fs';
|
|
2
|
+
import { basename, dirname, resolve } from 'node:path';
|
|
3
|
+
|
|
4
|
+
/** Scheduler used to debounce typegen filesystem bursts deterministically. */
|
|
5
|
+
|
|
6
|
+
/** Signal registration boundary owned by one typegen watch invocation. */
|
|
7
|
+
|
|
8
|
+
/** Minimal watcher resource acquired by typegen watch mode. */
|
|
9
|
+
|
|
10
|
+
/** One child generation owned by a typegen watch coordinator. */
|
|
11
|
+
|
|
12
|
+
/** Dependencies and callbacks for one bounded typegen watch lifecycle. */
|
|
13
|
+
|
|
14
|
+
const DEFAULT_DEBOUNCE_MS = 100;
|
|
15
|
+
function createDefaultScheduler() {
|
|
16
|
+
let sequence = 0;
|
|
17
|
+
const timers = new Map();
|
|
18
|
+
return {
|
|
19
|
+
clear(handle) {
|
|
20
|
+
const timer = timers.get(handle);
|
|
21
|
+
if (timer !== undefined) {
|
|
22
|
+
clearTimeout(timer);
|
|
23
|
+
timers.delete(handle);
|
|
24
|
+
}
|
|
25
|
+
},
|
|
26
|
+
set(callback, delayMs) {
|
|
27
|
+
sequence += 1;
|
|
28
|
+
const handle = sequence;
|
|
29
|
+
const timer = setTimeout(() => {
|
|
30
|
+
timers.delete(handle);
|
|
31
|
+
callback();
|
|
32
|
+
}, delayMs);
|
|
33
|
+
timers.set(handle, timer);
|
|
34
|
+
return handle;
|
|
35
|
+
}
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
const defaultWatchTarget = (target, options, listener) => watch(target, options, listener);
|
|
39
|
+
function isOwnArtifactEvent(changedPath, outputPath) {
|
|
40
|
+
if (changedPath === outputPath) {
|
|
41
|
+
return true;
|
|
42
|
+
}
|
|
43
|
+
const changedName = basename(changedPath);
|
|
44
|
+
const outputName = basename(outputPath);
|
|
45
|
+
return changedName.startsWith(`.${outputName}.`) && changedName.endsWith('.tmp');
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* Watches the application module directory while generating an initial current artifact.
|
|
50
|
+
*
|
|
51
|
+
* @param options Generation, watcher, scheduler, and signal lifecycle dependencies.
|
|
52
|
+
* @returns Exit code `0` after signal shutdown or `1` after an asynchronous watcher failure.
|
|
53
|
+
*/
|
|
54
|
+
export async function runTypegenWatch(options) {
|
|
55
|
+
const debounceMs = options.debounceMs ?? DEFAULT_DEBOUNCE_MS;
|
|
56
|
+
const onError = options.onError ?? (() => undefined);
|
|
57
|
+
const scheduler = options.scheduler ?? createDefaultScheduler();
|
|
58
|
+
const signalTarget = options.signalTarget ?? process;
|
|
59
|
+
const watchTarget = options.watchTarget ?? defaultWatchTarget;
|
|
60
|
+
const watchRoot = dirname(options.modulePath);
|
|
61
|
+
let activeCommit;
|
|
62
|
+
let activeGeneration;
|
|
63
|
+
let cleanedUp = false;
|
|
64
|
+
let rerunRequested = false;
|
|
65
|
+
let resolved = false;
|
|
66
|
+
let restartTimer;
|
|
67
|
+
let stopping = false;
|
|
68
|
+
let stopCode = 0;
|
|
69
|
+
let watcher;
|
|
70
|
+
let startupComplete = false;
|
|
71
|
+
let resolveResult = () => undefined;
|
|
72
|
+
const result = new Promise(resolvePromise => {
|
|
73
|
+
resolveResult = resolvePromise;
|
|
74
|
+
});
|
|
75
|
+
const cleanup = () => {
|
|
76
|
+
if (cleanedUp) {
|
|
77
|
+
return;
|
|
78
|
+
}
|
|
79
|
+
cleanedUp = true;
|
|
80
|
+
if (restartTimer !== undefined) {
|
|
81
|
+
scheduler.clear(restartTimer);
|
|
82
|
+
restartTimer = undefined;
|
|
83
|
+
}
|
|
84
|
+
watcher?.close();
|
|
85
|
+
signalTarget.off('SIGINT', stopForSignal);
|
|
86
|
+
signalTarget.off('SIGTERM', stopForSignal);
|
|
87
|
+
};
|
|
88
|
+
const settleIfIdle = () => {
|
|
89
|
+
if (!stopping || activeGeneration !== undefined || resolved) {
|
|
90
|
+
return;
|
|
91
|
+
}
|
|
92
|
+
resolved = true;
|
|
93
|
+
resolveResult(stopCode);
|
|
94
|
+
};
|
|
95
|
+
const stop = code => {
|
|
96
|
+
stopCode = Math.max(stopCode, code);
|
|
97
|
+
if (!stopping) {
|
|
98
|
+
stopping = true;
|
|
99
|
+
cleanup();
|
|
100
|
+
activeCommit?.abort();
|
|
101
|
+
activeGeneration?.cancel();
|
|
102
|
+
}
|
|
103
|
+
settleIfIdle();
|
|
104
|
+
};
|
|
105
|
+
function stopForSignal() {
|
|
106
|
+
stop(0);
|
|
107
|
+
}
|
|
108
|
+
const runGeneration = async reportError => {
|
|
109
|
+
let generation;
|
|
110
|
+
try {
|
|
111
|
+
generation = options.startGeneration();
|
|
112
|
+
activeGeneration = generation;
|
|
113
|
+
const source = await generation.result;
|
|
114
|
+
if (!stopping && !rerunRequested) {
|
|
115
|
+
const commit = new AbortController();
|
|
116
|
+
activeCommit = commit;
|
|
117
|
+
try {
|
|
118
|
+
await options.commit(source, commit.signal);
|
|
119
|
+
} finally {
|
|
120
|
+
if (activeCommit === commit) {
|
|
121
|
+
activeCommit = undefined;
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
} catch (error) {
|
|
126
|
+
if (stopping || rerunRequested) {
|
|
127
|
+
return;
|
|
128
|
+
}
|
|
129
|
+
if (reportError) {
|
|
130
|
+
onError(error);
|
|
131
|
+
return;
|
|
132
|
+
}
|
|
133
|
+
throw error;
|
|
134
|
+
} finally {
|
|
135
|
+
if (activeGeneration === generation) {
|
|
136
|
+
activeGeneration = undefined;
|
|
137
|
+
settleIfIdle();
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
};
|
|
141
|
+
const regenerate = () => {
|
|
142
|
+
if (stopping) {
|
|
143
|
+
return;
|
|
144
|
+
}
|
|
145
|
+
if (activeGeneration !== undefined) {
|
|
146
|
+
rerunRequested = true;
|
|
147
|
+
return;
|
|
148
|
+
}
|
|
149
|
+
void (async () => {
|
|
150
|
+
do {
|
|
151
|
+
rerunRequested = false;
|
|
152
|
+
await runGeneration(true);
|
|
153
|
+
} while (rerunRequested && !stopping);
|
|
154
|
+
})();
|
|
155
|
+
};
|
|
156
|
+
const scheduleRegeneration = changedPath => {
|
|
157
|
+
if (stopping || isOwnArtifactEvent(changedPath, options.outputPath)) {
|
|
158
|
+
return;
|
|
159
|
+
}
|
|
160
|
+
if (activeGeneration !== undefined) {
|
|
161
|
+
rerunRequested = true;
|
|
162
|
+
activeCommit?.abort();
|
|
163
|
+
return;
|
|
164
|
+
}
|
|
165
|
+
if (!startupComplete) {
|
|
166
|
+
rerunRequested = true;
|
|
167
|
+
return;
|
|
168
|
+
}
|
|
169
|
+
if (restartTimer !== undefined) {
|
|
170
|
+
scheduler.clear(restartTimer);
|
|
171
|
+
}
|
|
172
|
+
restartTimer = scheduler.set(() => {
|
|
173
|
+
restartTimer = undefined;
|
|
174
|
+
regenerate();
|
|
175
|
+
}, debounceMs);
|
|
176
|
+
};
|
|
177
|
+
try {
|
|
178
|
+
watcher = watchTarget(watchRoot, {
|
|
179
|
+
persistent: true,
|
|
180
|
+
recursive: true
|
|
181
|
+
}, (_event, filename) => {
|
|
182
|
+
const changedPath = filename === null ? watchRoot : resolve(watchRoot, String(filename));
|
|
183
|
+
scheduleRegeneration(changedPath);
|
|
184
|
+
});
|
|
185
|
+
watcher.on('error', error => {
|
|
186
|
+
onError(error);
|
|
187
|
+
stop(1);
|
|
188
|
+
});
|
|
189
|
+
} catch (error) {
|
|
190
|
+
watcher?.close();
|
|
191
|
+
throw error;
|
|
192
|
+
}
|
|
193
|
+
try {
|
|
194
|
+
signalTarget.once('SIGINT', stopForSignal);
|
|
195
|
+
signalTarget.once('SIGTERM', stopForSignal);
|
|
196
|
+
await (async () => {
|
|
197
|
+
do {
|
|
198
|
+
rerunRequested = false;
|
|
199
|
+
await runGeneration(false);
|
|
200
|
+
} while (rerunRequested && !stopping);
|
|
201
|
+
})();
|
|
202
|
+
startupComplete = true;
|
|
203
|
+
if (stopping) {
|
|
204
|
+
return result;
|
|
205
|
+
}
|
|
206
|
+
options.onReady?.(watchRoot);
|
|
207
|
+
} catch (error) {
|
|
208
|
+
cleanup();
|
|
209
|
+
throw error;
|
|
210
|
+
}
|
|
211
|
+
return result;
|
|
212
|
+
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { type ReactTypegenModules } from './typegen-source.js';
|
|
2
|
+
type CliStream = {
|
|
3
|
+
write(message: string): unknown;
|
|
4
|
+
};
|
|
5
|
+
/** Runtime options for the React page typegen command. */
|
|
6
|
+
export interface TypegenCommandRuntimeOptions {
|
|
7
|
+
/** Current working directory for module and output path resolution. */
|
|
8
|
+
readonly cwd?: string;
|
|
9
|
+
/**
|
|
10
|
+
* Optional build-tooling module loader override for tests and editor integrations.
|
|
11
|
+
* Supplying it keeps application evaluation in the caller process and uses the returned
|
|
12
|
+
* namespaces for TypeScript and native modules; omitting it uses isolated generation children.
|
|
13
|
+
*/
|
|
14
|
+
readonly loadReactTypegenModules?: (cwd: string) => Promise<ReactTypegenModules>;
|
|
15
|
+
/** Custom stream for error output. */
|
|
16
|
+
readonly stderr?: CliStream;
|
|
17
|
+
/** Custom stream for standard output. */
|
|
18
|
+
readonly stdout?: CliStream;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Generates, checks, or watches one application-owned React page type artifact.
|
|
22
|
+
*
|
|
23
|
+
* @param argv Command arguments after `typegen`.
|
|
24
|
+
* @param runtime Runtime overrides for module loading and output streams.
|
|
25
|
+
* @returns Process-style command exit code.
|
|
26
|
+
*/
|
|
27
|
+
export declare function runTypegenCommand(argv: readonly string[], runtime?: TypegenCommandRuntimeOptions): Promise<number>;
|
|
28
|
+
export {};
|
|
29
|
+
//# sourceMappingURL=typegen.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"typegen.d.ts","sourceRoot":"","sources":["../../src/commands/typegen.ts"],"names":[],"mappings":"AAcA,OAAO,EAIL,KAAK,mBAAmB,EACzB,MAAM,qBAAqB,CAAC;AAI7B,KAAK,SAAS,GAAG;IACf,KAAK,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC;CACjC,CAAC;AAEF,0DAA0D;AAC1D,MAAM,WAAW,4BAA4B;IAC3C,uEAAuE;IACvE,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,CAAC;IACtB;;;;OAIG;IACH,QAAQ,CAAC,uBAAuB,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC,mBAAmB,CAAC,CAAC;IACjF,sCAAsC;IACtC,QAAQ,CAAC,MAAM,CAAC,EAAE,SAAS,CAAC;IAC5B,yCAAyC;IACzC,QAAQ,CAAC,MAAM,CAAC,EAAE,SAAS,CAAC;CAC7B;AA+BD;;;;;;GAMG;AACH,wBAAsB,iBAAiB,CACrC,IAAI,EAAE,SAAS,MAAM,EAAE,EACvB,OAAO,GAAE,4BAAiC,GACzC,OAAO,CAAC,MAAM,CAAC,CA2EjB"}
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
import { resolve } from 'node:path';
|
|
2
|
+
import { TYPEGEN_EXIT_CODES } from '../typegen-contract.js';
|
|
3
|
+
import { typegenUsage } from '../usage.js';
|
|
4
|
+
import { checkTypegenArtifact, writeTypegenArtifact } from './typegen-artifact.js';
|
|
5
|
+
import { runTypegenGenerationProcess, startTypegenGenerationProcess } from './typegen-generation-process.js';
|
|
6
|
+
import { parseTypegenArgs, TypegenCommandError } from './typegen-options.js';
|
|
7
|
+
import { createTypegenSource, inspectReactTypegenArtifact, loadReactTypegenModules } from './typegen-source.js';
|
|
8
|
+
import { runTypegenWatch } from './typegen-watch.js';
|
|
9
|
+
import { assertOutputDoesNotAliasModule } from './output-path-safety.js';
|
|
10
|
+
|
|
11
|
+
/** Runtime options for the React page typegen command. */
|
|
12
|
+
|
|
13
|
+
function reportCheckResult(check, outputPath, stdout, stderr) {
|
|
14
|
+
switch (check.status) {
|
|
15
|
+
case 'UNCHANGED':
|
|
16
|
+
stdout.write(`UNCHANGED ${outputPath}\n`);
|
|
17
|
+
return TYPEGEN_EXIT_CODES.SUCCESS;
|
|
18
|
+
case 'MISSING':
|
|
19
|
+
stderr.write(`MISSING ${outputPath}: run fluo typegen without --check to create the artifact.\n`);
|
|
20
|
+
return TYPEGEN_EXIT_CODES.MISSING;
|
|
21
|
+
case 'STALE':
|
|
22
|
+
stderr.write(`STALE ${outputPath}: generated React page types differ from the authoritative compiled catalog.\n`);
|
|
23
|
+
return TYPEGEN_EXIT_CODES.STALE;
|
|
24
|
+
case 'MALFORMED':
|
|
25
|
+
stderr.write(`MALFORMED ${outputPath}: the target is not a complete React page typegen artifact.\n`);
|
|
26
|
+
return TYPEGEN_EXIT_CODES.MALFORMED;
|
|
27
|
+
case 'UNSUPPORTED_VERSION':
|
|
28
|
+
stderr.write(`UNSUPPORTED_VERSION ${outputPath}: artifact version ${String(check.version)} is not supported by this CLI.\n`);
|
|
29
|
+
return TYPEGEN_EXIT_CODES.UNSUPPORTED_VERSION;
|
|
30
|
+
default:
|
|
31
|
+
{
|
|
32
|
+
const unreachable = check;
|
|
33
|
+
throw new TypegenCommandError(`Unexpected typegen check result: ${String(unreachable)}`);
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* Generates, checks, or watches one application-owned React page type artifact.
|
|
40
|
+
*
|
|
41
|
+
* @param argv Command arguments after `typegen`.
|
|
42
|
+
* @param runtime Runtime overrides for module loading and output streams.
|
|
43
|
+
* @returns Process-style command exit code.
|
|
44
|
+
*/
|
|
45
|
+
export async function runTypegenCommand(argv, runtime = {}) {
|
|
46
|
+
const cwd = runtime.cwd ?? process.cwd();
|
|
47
|
+
const stdout = runtime.stdout ?? process.stdout;
|
|
48
|
+
const stderr = runtime.stderr ?? process.stderr;
|
|
49
|
+
try {
|
|
50
|
+
if (argv.some(argument => argument === '--help' || argument === '-h')) {
|
|
51
|
+
stdout.write(`${typegenUsage()}\n`);
|
|
52
|
+
return 0;
|
|
53
|
+
}
|
|
54
|
+
const parsed = parseTypegenArgs(argv);
|
|
55
|
+
const modulePath = resolve(cwd, parsed.modulePath);
|
|
56
|
+
const outputPath = resolve(cwd, parsed.outputPath);
|
|
57
|
+
await assertOutputDoesNotAliasModule(modulePath, outputPath);
|
|
58
|
+
const customModules = runtime.loadReactTypegenModules?.(cwd);
|
|
59
|
+
const generateSource = async () => customModules === undefined ? runTypegenGenerationProcess({
|
|
60
|
+
cwd,
|
|
61
|
+
exportName: parsed.exportName,
|
|
62
|
+
modulePath: parsed.modulePath
|
|
63
|
+
}) : createTypegenSource({
|
|
64
|
+
cwd,
|
|
65
|
+
modules: await customModules,
|
|
66
|
+
parsed
|
|
67
|
+
});
|
|
68
|
+
if (parsed.watch) {
|
|
69
|
+
return await runTypegenWatch({
|
|
70
|
+
async commit(source, signal) {
|
|
71
|
+
const action = await writeTypegenArtifact(outputPath, source, undefined, signal);
|
|
72
|
+
stdout.write(`${action} ${outputPath}\n`);
|
|
73
|
+
},
|
|
74
|
+
modulePath,
|
|
75
|
+
onError(error) {
|
|
76
|
+
stderr.write(`ERROR ${outputPath}: ${error instanceof Error ? error.message : String(error)}\n`);
|
|
77
|
+
},
|
|
78
|
+
onReady(watchRoot) {
|
|
79
|
+
stdout.write(`WATCHING ${watchRoot}\n`);
|
|
80
|
+
},
|
|
81
|
+
outputPath,
|
|
82
|
+
startGeneration: customModules === undefined ? () => startTypegenGenerationProcess({
|
|
83
|
+
cwd,
|
|
84
|
+
exportName: parsed.exportName,
|
|
85
|
+
modulePath: parsed.modulePath
|
|
86
|
+
}) : () => {
|
|
87
|
+
let cancelled = false;
|
|
88
|
+
const result = generateSource().then(source => {
|
|
89
|
+
if (cancelled) {
|
|
90
|
+
throw new TypegenCommandError('Typegen generation was cancelled.');
|
|
91
|
+
}
|
|
92
|
+
return source;
|
|
93
|
+
});
|
|
94
|
+
return {
|
|
95
|
+
cancel() {
|
|
96
|
+
if (cancelled) {
|
|
97
|
+
return;
|
|
98
|
+
}
|
|
99
|
+
cancelled = true;
|
|
100
|
+
},
|
|
101
|
+
result
|
|
102
|
+
};
|
|
103
|
+
}
|
|
104
|
+
});
|
|
105
|
+
}
|
|
106
|
+
const source = await generateSource();
|
|
107
|
+
if (parsed.check) {
|
|
108
|
+
const modules = customModules === undefined ? await loadReactTypegenModules(cwd) : await customModules;
|
|
109
|
+
const check = await checkTypegenArtifact(outputPath, source, existingSource => inspectReactTypegenArtifact(modules, existingSource));
|
|
110
|
+
return reportCheckResult(check, outputPath, stdout, stderr);
|
|
111
|
+
}
|
|
112
|
+
const action = await writeTypegenArtifact(outputPath, source);
|
|
113
|
+
stdout.write(`${action} ${outputPath}\n`);
|
|
114
|
+
return TYPEGEN_EXIT_CODES.SUCCESS;
|
|
115
|
+
} catch (error) {
|
|
116
|
+
stderr.write(`${error instanceof Error ? error.message : String(error)}\n`);
|
|
117
|
+
return TYPEGEN_EXIT_CODES.ERROR;
|
|
118
|
+
}
|
|
119
|
+
}
|
|
@@ -19,6 +19,11 @@ type RestartSignalTarget = {
|
|
|
19
19
|
type RestartWatcherFactory = (target: string, optionsOrListener: {
|
|
20
20
|
recursive: boolean;
|
|
21
21
|
} | ((event: string, filename: string | Buffer | null) => void), listener?: (event: string, filename: string | Buffer | null) => void) => FSWatcher;
|
|
22
|
+
type RestartSchedulerHandle = ReturnType<typeof setTimeout> | number;
|
|
23
|
+
type RestartScheduler = {
|
|
24
|
+
clear(handle: RestartSchedulerHandle): void;
|
|
25
|
+
set(callback: () => void, delayMs: number): RestartSchedulerHandle;
|
|
26
|
+
};
|
|
22
27
|
type ContentChangeGate = {
|
|
23
28
|
commitBaseline(paths: Iterable<string>): void;
|
|
24
29
|
hasMeaningfulChange(paths: Iterable<string>): boolean;
|
|
@@ -33,6 +38,7 @@ export type NodeRestartRunnerOptions = {
|
|
|
33
38
|
signalTarget?: RestartSignalTarget;
|
|
34
39
|
spawnChild?: RestartChildSpawner;
|
|
35
40
|
stderr?: RestartRunnerStream;
|
|
41
|
+
restartScheduler?: RestartScheduler;
|
|
36
42
|
stdout?: RestartRunnerStream;
|
|
37
43
|
watchTarget?: RestartWatcherFactory;
|
|
38
44
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"node-restart-runner.d.ts","sourceRoot":"","sources":["../../src/dev-runner/node-restart-runner.ts"],"names":[],"mappings":"AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"node-restart-runner.d.ts","sourceRoot":"","sources":["../../src/dev-runner/node-restart-runner.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,YAAY,EAAS,MAAM,oBAAoB,CAAC;AAE9D,OAAO,EAAc,KAAK,SAAS,EAA8C,MAAM,SAAS,CAAC;AAKjG,KAAK,mBAAmB,GAAG;IACzB,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,KAAK,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC;CACjC,CAAC;AAEF,KAAK,mBAAmB,GAAG,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,OAAO,EAAE;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAC,UAAU,CAAC;IAAC,KAAK,EAAE,SAAS,CAAA;CAAE,KAAK,YAAY,CAAC;AACjJ,2EAA2E;AAC3E,MAAM,MAAM,gBAAgB,GAAG,KAAK,GAAG,oBAAoB,GAAG,MAAM,GAAG,MAAM,CAAC;AAE9E,KAAK,aAAa,GAAG,QAAQ,GAAG,SAAS,CAAC;AAE1C,KAAK,mBAAmB,GAAG;IACzB,GAAG,CAAC,MAAM,EAAE,aAAa,EAAE,QAAQ,EAAE,MAAM,IAAI,GAAG,OAAO,CAAC;IAC1D,IAAI,CAAC,MAAM,EAAE,aAAa,EAAE,QAAQ,EAAE,MAAM,IAAI,GAAG,OAAO,CAAC;CAC5D,CAAC;AAEF,KAAK,qBAAqB,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,iBAAiB,EAAE;IAAE,SAAS,EAAE,OAAO,CAAA;CAAE,GAAG,CAAC,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,KAAK,IAAI,CAAC,EAAE,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,KAAK,IAAI,KAAK,SAAS,CAAC;AAE1O,KAAK,sBAAsB,GAAG,UAAU,CAAC,OAAO,UAAU,CAAC,GAAG,MAAM,CAAC;AAErE,KAAK,gBAAgB,GAAG;IACtB,KAAK,CAAC,MAAM,EAAE,sBAAsB,GAAG,IAAI,CAAC;IAC5C,GAAG,CAAC,QAAQ,EAAE,MAAM,IAAI,EAAE,OAAO,EAAE,MAAM,GAAG,sBAAsB,CAAC;CACpE,CAAC;AAEF,KAAK,iBAAiB,GAAG;IACvB,cAAc,CAAC,KAAK,EAAE,QAAQ,CAAC,MAAM,CAAC,GAAG,IAAI,CAAC;IAC9C,mBAAmB,CAAC,KAAK,EAAE,QAAQ,CAAC,MAAM,CAAC,GAAG,OAAO,CAAC;CACvD,CAAC;AAEF,uFAAuF;AACvF,MAAM,MAAM,wBAAwB,GAAG;IACrC,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;IACnB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,GAAG,EAAE,MAAM,CAAC,UAAU,CAAC;IACvB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,OAAO,CAAC,EAAE,gBAAgB,CAAC;IAC3B,YAAY,CAAC,EAAE,mBAAmB,CAAC;IACnC,UAAU,CAAC,EAAE,mBAAmB,CAAC;IACjC,MAAM,CAAC,EAAE,mBAAmB,CAAC;IAC7B,gBAAgB,CAAC,EAAE,gBAAgB,CAAC;IACpC,MAAM,CAAC,EAAE,mBAAmB,CAAC;IAC7B,WAAW,CAAC,EAAE,qBAAqB,CAAC;CACrC,CAAC;AA6NF;;;;;;GAMG;AACH,wBAAgB,uBAAuB,CAAC,gBAAgB,EAAE,MAAM,EAAE,cAAc,GAAE,MAAM,EAAoB,GAAG,iBAAiB,CAuB/H;AAkFD;;;;;GAKG;AACH,wBAAsB,oBAAoB,CAAC,OAAO,EAAE,wBAAwB,GAAG,OAAO,CAAC,MAAM,CAAC,CAwS7F"}
|
|
@@ -100,7 +100,7 @@ function parseIgnorePatterns(env) {
|
|
|
100
100
|
return normalizeIgnorePatterns([...DEFAULT_IGNORES, ...configured]);
|
|
101
101
|
}
|
|
102
102
|
function matchesSegmentPattern(segment, pattern) {
|
|
103
|
-
if (pattern.startsWith('
|
|
103
|
+
if (pattern.startsWith('*')) {
|
|
104
104
|
return segment.endsWith(pattern.slice(1));
|
|
105
105
|
}
|
|
106
106
|
if (pattern.endsWith('*')) {
|
|
@@ -205,7 +205,7 @@ export function createContentChangeGate(projectDirectory, ignorePatterns = DEFAU
|
|
|
205
205
|
};
|
|
206
206
|
}
|
|
207
207
|
function getWatchTargets(projectDirectory) {
|
|
208
|
-
return [join(projectDirectory, 'src'), ...WATCH_FILES.map(fileName => join(projectDirectory, fileName))
|
|
208
|
+
return [join(projectDirectory, 'src'), ...WATCH_FILES.map(fileName => join(projectDirectory, fileName)).filter(target => existsSync(target))];
|
|
209
209
|
}
|
|
210
210
|
function stopChild(child, shutdownTimeoutMs = DEFAULT_CHILD_SHUTDOWN_TIMEOUT_MS) {
|
|
211
211
|
if (child && child.exitCode === null) {
|
|
@@ -293,12 +293,17 @@ export async function runNodeRestartRunner(options) {
|
|
|
293
293
|
const spawnChild = options.spawnChild ?? spawn;
|
|
294
294
|
const stdout = options.stdout ?? process.stdout;
|
|
295
295
|
const stderr = options.stderr ?? process.stderr;
|
|
296
|
+
const restartScheduler = options.restartScheduler ?? {
|
|
297
|
+
clear: clearTimeout,
|
|
298
|
+
set: setTimeout
|
|
299
|
+
};
|
|
296
300
|
const watchTarget = options.watchTarget ?? watch;
|
|
297
301
|
const appArgs = options.appArgs ?? [];
|
|
298
302
|
const debounceMs = options.debounceMs ?? Number(env.FLUO_DEV_RELOAD_DEBOUNCE_MS ?? DEFAULT_DEBOUNCE_MS);
|
|
299
303
|
const childShutdownTimeoutMs = Number(env.FLUO_DEV_CHILD_SHUTDOWN_TIMEOUT_MS ?? DEFAULT_CHILD_SHUTDOWN_TIMEOUT_MS);
|
|
300
304
|
const ignorePatterns = parseIgnorePatterns(env);
|
|
301
305
|
const gate = createContentChangeGate(projectDirectory, ignorePatterns);
|
|
306
|
+
const sourceDirectory = join(projectDirectory, 'src');
|
|
302
307
|
const watchTargets = getWatchTargets(projectDirectory);
|
|
303
308
|
let child;
|
|
304
309
|
const pendingRestartPaths = new Set();
|
|
@@ -306,6 +311,7 @@ export async function runNodeRestartRunner(options) {
|
|
|
306
311
|
let restartTimer;
|
|
307
312
|
let restarting = false;
|
|
308
313
|
let stopping = false;
|
|
314
|
+
let terminalExitCode;
|
|
309
315
|
const startChild = (resolveExitCode, cleanup) => {
|
|
310
316
|
ensureStudioEpoch(env);
|
|
311
317
|
const appCommand = buildAppCommand(runnerRuntime, env, appArgs);
|
|
@@ -346,7 +352,7 @@ export async function runNodeRestartRunner(options) {
|
|
|
346
352
|
reason: 'fluo dev runner stopped'
|
|
347
353
|
});
|
|
348
354
|
cleanup();
|
|
349
|
-
resolveExitCode(code ?? 0);
|
|
355
|
+
resolveExitCode(terminalExitCode ?? code ?? 0);
|
|
350
356
|
return;
|
|
351
357
|
}
|
|
352
358
|
publishStudioLifecycleEvent(env, runnerRuntime, 'disconnect', {
|
|
@@ -358,10 +364,10 @@ export async function runNodeRestartRunner(options) {
|
|
|
358
364
|
};
|
|
359
365
|
const scheduleRestart = (filePath, resolveExitCode, cleanup) => {
|
|
360
366
|
pendingRestartPaths.add(filePath);
|
|
361
|
-
if (restartTimer) {
|
|
362
|
-
|
|
367
|
+
if (restartTimer !== undefined) {
|
|
368
|
+
restartScheduler.clear(restartTimer);
|
|
363
369
|
}
|
|
364
|
-
restartTimer =
|
|
370
|
+
restartTimer = restartScheduler.set(() => {
|
|
365
371
|
const restartPaths = [...pendingRestartPaths];
|
|
366
372
|
pendingRestartPaths.clear();
|
|
367
373
|
restartTimer = undefined;
|
|
@@ -445,8 +451,8 @@ export async function runNodeRestartRunner(options) {
|
|
|
445
451
|
return;
|
|
446
452
|
}
|
|
447
453
|
cleanedUp = true;
|
|
448
|
-
if (restartTimer) {
|
|
449
|
-
|
|
454
|
+
if (restartTimer !== undefined) {
|
|
455
|
+
restartScheduler.clear(restartTimer);
|
|
450
456
|
restartTimer = undefined;
|
|
451
457
|
}
|
|
452
458
|
pendingRestartPaths.clear();
|
|
@@ -457,11 +463,33 @@ export async function runNodeRestartRunner(options) {
|
|
|
457
463
|
signalTarget.off('SIGINT', stop);
|
|
458
464
|
signalTarget.off('SIGTERM', stop);
|
|
459
465
|
};
|
|
466
|
+
const failFromWatcher = (target, error) => {
|
|
467
|
+
if (stopping || resolved) {
|
|
468
|
+
return;
|
|
469
|
+
}
|
|
470
|
+
terminalExitCode = 1;
|
|
471
|
+
stopping = true;
|
|
472
|
+
stderr.write(`[fluo] watcher failed for ${target}: ${error.message}\n`);
|
|
473
|
+
cleanup();
|
|
474
|
+
const stoppingChild = child;
|
|
475
|
+
if (!stoppingChild || stoppingChild.exitCode !== null) {
|
|
476
|
+
resolveOnce(terminalExitCode);
|
|
477
|
+
return;
|
|
478
|
+
}
|
|
479
|
+
stoppingChild.once('close', () => resolveOnce(1));
|
|
480
|
+
if (!restarting) {
|
|
481
|
+
stopChild(stoppingChild, childShutdownTimeoutMs);
|
|
482
|
+
}
|
|
483
|
+
};
|
|
484
|
+
const registerWatcher = (target, watcher) => {
|
|
485
|
+
watchers.push(watcher);
|
|
486
|
+
watcher.on?.('error', error => failFromWatcher(target, error));
|
|
487
|
+
};
|
|
460
488
|
startChild(resolveExitCode, cleanup);
|
|
461
489
|
const watchedFallbackDirectories = new Set();
|
|
462
490
|
const watchFallbackDirectory = directoryPath => {
|
|
463
491
|
if (watchedFallbackDirectories.has(directoryPath) || shouldIgnorePath(directoryPath, projectDirectory, ignorePatterns)) {
|
|
464
|
-
return;
|
|
492
|
+
return false;
|
|
465
493
|
}
|
|
466
494
|
watchedFallbackDirectories.add(directoryPath);
|
|
467
495
|
const listener = (_event, filename) => {
|
|
@@ -469,14 +497,22 @@ export async function runNodeRestartRunner(options) {
|
|
|
469
497
|
const changedPath = filename ? join(directoryPath, fileName) : directoryPath;
|
|
470
498
|
scheduleRestart(changedPath, resolveExitCode, cleanup);
|
|
471
499
|
for (const nextDirectoryPath of getFallbackWatchDirectories(changedPath, projectDirectory, ignorePatterns)) {
|
|
472
|
-
|
|
500
|
+
if (watchedFallbackDirectories.has(nextDirectoryPath) || shouldIgnorePath(nextDirectoryPath, projectDirectory, ignorePatterns)) {
|
|
501
|
+
continue;
|
|
502
|
+
}
|
|
503
|
+
if (!watchFallbackDirectory(nextDirectoryPath)) {
|
|
504
|
+
failFromWatcher(nextDirectoryPath, new Error('required fallback watcher could not be acquired'));
|
|
505
|
+
return;
|
|
506
|
+
}
|
|
473
507
|
}
|
|
474
508
|
};
|
|
475
509
|
try {
|
|
476
|
-
|
|
510
|
+
registerWatcher(directoryPath, watchTarget(directoryPath, listener));
|
|
511
|
+
return true;
|
|
477
512
|
} catch (error) {
|
|
478
513
|
watchedFallbackDirectories.delete(directoryPath);
|
|
479
514
|
stderr.write(`[fluo] unable to watch ${directoryPath}: ${error instanceof Error ? error.message : String(error)}\n`);
|
|
515
|
+
return false;
|
|
480
516
|
}
|
|
481
517
|
};
|
|
482
518
|
for (const target of watchTargets) {
|
|
@@ -490,16 +526,31 @@ export async function runNodeRestartRunner(options) {
|
|
|
490
526
|
scheduleRestart(stats.isDirectory() ? join(target, fileName) : target, resolveExitCode, cleanup);
|
|
491
527
|
};
|
|
492
528
|
try {
|
|
493
|
-
|
|
529
|
+
registerWatcher(target, watchTarget(target, watchOptions, listener));
|
|
494
530
|
} catch (error) {
|
|
495
531
|
if (!stats.isDirectory()) {
|
|
496
532
|
throw error;
|
|
497
533
|
}
|
|
534
|
+
let sourceCoverageAcquired = false;
|
|
498
535
|
for (const directoryPath of getFallbackWatchDirectories(target, projectDirectory, ignorePatterns)) {
|
|
499
|
-
watchFallbackDirectory(directoryPath)
|
|
536
|
+
if (!watchFallbackDirectory(directoryPath)) {
|
|
537
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
538
|
+
failFromWatcher(target, new Error(`${message}; required fallback watcher could not be acquired`));
|
|
539
|
+
return;
|
|
540
|
+
}
|
|
541
|
+
sourceCoverageAcquired ||= directoryPath === target;
|
|
542
|
+
}
|
|
543
|
+
if (!sourceCoverageAcquired) {
|
|
544
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
545
|
+
failFromWatcher(target, new Error(`${message}; required fallback watcher could not be acquired`));
|
|
546
|
+
return;
|
|
500
547
|
}
|
|
501
548
|
}
|
|
502
549
|
} catch (error) {
|
|
550
|
+
if (target === sourceDirectory) {
|
|
551
|
+
failFromWatcher(target, error instanceof Error ? error : new Error(String(error)));
|
|
552
|
+
return;
|
|
553
|
+
}
|
|
503
554
|
stderr.write(`[fluo] unable to watch ${target}: ${error instanceof Error ? error.message : String(error)}\n`);
|
|
504
555
|
}
|
|
505
556
|
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"inspect-react-app.module.d.ts","sourceRoot":"","sources":["../../src/fixtures/inspect-react-app.module.ts"],"names":[],"mappings":"AASA,kFAAkF;AAClF,qBAAa,SAAS;CAAG"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
let _initProto, _initClass;
|
|
2
|
+
function _applyDecs(e, t, n, r, o, i) { var a, c, u, s, f, l, p, d = Symbol.metadata || Symbol.for("Symbol.metadata"), m = Object.defineProperty, h = Object.create, y = [h(null), h(null)], v = t.length; function g(t, n, r) { return function (o, i) { n && (i = o, o = e); for (var a = 0; a < t.length; a++) i = t[a].apply(o, r ? [i] : []); return r ? i : o; }; } function b(e, t, n, r) { if ("function" != typeof e && (r || void 0 !== e)) throw new TypeError(t + " must " + (n || "be") + " a function" + (r ? "" : " or undefined")); return e; } function applyDec(e, t, n, r, o, i, u, s, f, l, p) { function d(e) { if (!p(e)) throw new TypeError("Attempted to access private element on non-instance"); } var h = [].concat(t[0]), v = t[3], w = !u, D = 1 === o, S = 3 === o, j = 4 === o, E = 2 === o; function I(t, n, r) { return function (o, i) { return n && (i = o, o = e), r && r(o), P[t].call(o, i); }; } if (!w) { var P = {}, k = [], F = S ? "get" : j || D ? "set" : "value"; if (f ? (l || D ? P = { get: _setFunctionName(function () { return v(this); }, r, "get"), set: function (e) { t[4](this, e); } } : P[F] = v, l || _setFunctionName(P[F], r, E ? "" : F)) : l || (P = Object.getOwnPropertyDescriptor(e, r)), !l && !f) { if ((c = y[+s][r]) && 7 !== (c ^ o)) throw Error("Decorating two elements with the same name (" + P[F].name + ") is not supported yet"); y[+s][r] = o < 3 ? 1 : o; } } for (var N = e, O = h.length - 1; O >= 0; O -= n ? 2 : 1) { var T = b(h[O], "A decorator", "be", !0), z = n ? h[O - 1] : void 0, A = {}, H = { kind: ["field", "accessor", "method", "getter", "setter", "class"][o], name: r, metadata: a, addInitializer: function (e, t) { if (e.v) throw new TypeError("attempted to call addInitializer after decoration was finished"); b(t, "An initializer", "be", !0), i.push(t); }.bind(null, A) }; if (w) c = T.call(z, N, H), A.v = 1, b(c, "class decorators", "return") && (N = c);else if (H.static = s, H.private = f, c = H.access = { has: f ? p.bind() : function (e) { return r in e; } }, j || (c.get = f ? E ? function (e) { return d(e), P.value; } : I("get", 0, d) : function (e) { return e[r]; }), E || S || (c.set = f ? I("set", 0, d) : function (e, t) { e[r] = t; }), N = T.call(z, D ? { get: P.get, set: P.set } : P[F], H), A.v = 1, D) { if ("object" == typeof N && N) (c = b(N.get, "accessor.get")) && (P.get = c), (c = b(N.set, "accessor.set")) && (P.set = c), (c = b(N.init, "accessor.init")) && k.unshift(c);else if (void 0 !== N) throw new TypeError("accessor decorators must return an object with get, set, or init properties or undefined"); } else b(N, (l ? "field" : "method") + " decorators", "return") && (l ? k.unshift(N) : P[F] = N); } return o < 2 && u.push(g(k, s, 1), g(i, s, 0)), l || w || (f ? D ? u.splice(-1, 0, I("get", s), I("set", s)) : u.push(E ? P[F] : b.call.bind(P[F])) : m(e, r, P)), N; } function w(e) { return m(e, d, { configurable: !0, enumerable: !0, value: a }); } return void 0 !== i && (a = i[d]), a = h(null == a ? null : a), f = [], l = function (e) { e && f.push(g(e)); }, p = function (t, r) { for (var i = 0; i < n.length; i++) { var a = n[i], c = a[1], l = 7 & c; if ((8 & c) == t && !l == r) { var p = a[2], d = !!a[3], m = 16 & c; applyDec(t ? e : e.prototype, a, m, d ? "#" + p : _toPropertyKey(p), l, l < 2 ? [] : t ? s = s || [] : u = u || [], f, !!t, d, r, t && d ? function (t) { return _checkInRHS(t) === e; } : o); } } }, p(8, 0), p(0, 0), p(8, 1), p(0, 1), l(u), l(s), c = f, v || w(e), { e: c, get c() { var n = []; return v && [w(e = applyDec(e, [t], r, e.name, 5, n)), g(n, 1)]; } }; }
|
|
3
|
+
function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == typeof i ? i : i + ""; }
|
|
4
|
+
function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != typeof i) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
|
|
5
|
+
function _setFunctionName(e, t, n) { "symbol" == typeof t && (t = (t = t.description) ? "[" + t + "]" : ""); try { Object.defineProperty(e, "name", { configurable: !0, value: n ? n + " " + t : t }); } catch (e) {} return e; }
|
|
6
|
+
function _checkInRHS(e) { if (Object(e) !== e) throw TypeError("right-hand side of 'in' should be an object, got " + (null !== e ? typeof e : "null")); return e; }
|
|
7
|
+
import { defineModule } from '@fluojs/runtime';
|
|
8
|
+
import { Path, ReactModule, Router } from '@fluojs/react';
|
|
9
|
+
let _ProductRouter;
|
|
10
|
+
class ProductRouter {
|
|
11
|
+
static {
|
|
12
|
+
({
|
|
13
|
+
e: [_initProto],
|
|
14
|
+
c: [_ProductRouter, _initClass]
|
|
15
|
+
} = _applyDecs(this, [Router('/products')], [[Path('/:productId'), 2, "show"]]));
|
|
16
|
+
}
|
|
17
|
+
constructor() {
|
|
18
|
+
_initProto(this);
|
|
19
|
+
}
|
|
20
|
+
show() {}
|
|
21
|
+
static {
|
|
22
|
+
_initClass();
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
/** Fixture application module used by build-less React route inspection tests. */
|
|
27
|
+
export class AppModule {}
|
|
28
|
+
defineModule(AppModule, {
|
|
29
|
+
imports: [ReactModule.forRoot({
|
|
30
|
+
controllers: [_ProductRouter]
|
|
31
|
+
})]
|
|
32
|
+
});
|