@fluojs/cli 2.0.1 → 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 +169 -21
- package/README.md +172 -21
- package/dist/cli.d.ts +5 -4
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +127 -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/inspect.d.ts +5 -1
- package/dist/commands/inspect.d.ts.map +1 -1
- package/dist/commands/inspect.js +84 -17
- 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.map +1 -1
- package/dist/commands/new.js +29 -9
- 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.js +2 -2
- 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.map +1 -1
- package/dist/dev-runner/node-restart-runner.js +54 -7
- 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/index.d.ts +6 -5
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -2
- 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 +62 -31
- 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 -0
- package/dist/new/types.d.ts.map +1 -1
- 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 +35 -9
- 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 +6 -0
- package/dist/usage.d.ts.map +1 -1
- package/dist/usage.js +47 -0
- package/package.json +19 -10
|
@@ -0,0 +1,183 @@
|
|
|
1
|
+
import { existsSync } from 'node:fs';
|
|
2
|
+
import { dirname, extname, resolve } from 'node:path';
|
|
3
|
+
import { pathToFileURL } from 'node:url';
|
|
4
|
+
import { tsImport } from 'tsx/esm/api';
|
|
5
|
+
import { TypegenCommandError } from './typegen-options.js';
|
|
6
|
+
|
|
7
|
+
/** Dynamically loaded package surfaces required by typegen. */
|
|
8
|
+
|
|
9
|
+
/** Structural artifact result returned by the React typegen package. */
|
|
10
|
+
|
|
11
|
+
const TYPESCRIPT_MODULE_EXTENSIONS = new Set(['.ts', '.tsx', '.mts', '.cts']);
|
|
12
|
+
const TYPEGEN_MODULE_IDS = ['@fluojs/react', '@fluojs/react/typegen', '@fluojs/runtime'];
|
|
13
|
+
const SILENT_APPLICATION_LOGGER = Object.freeze({
|
|
14
|
+
debug() {},
|
|
15
|
+
error() {},
|
|
16
|
+
log() {},
|
|
17
|
+
warn() {}
|
|
18
|
+
});
|
|
19
|
+
let applicationImportSequence = 0;
|
|
20
|
+
function isModuleNotFoundError(error) {
|
|
21
|
+
return typeof error === 'object' && error !== null && 'code' in error && (error.code === 'MODULE_NOT_FOUND' || error.code === 'ERR_MODULE_NOT_FOUND');
|
|
22
|
+
}
|
|
23
|
+
async function importProjectModule(moduleId, cwd, tsconfig) {
|
|
24
|
+
const importOptions = [{
|
|
25
|
+
parentURL: pathToFileURL(resolve(cwd, 'package.json')).href,
|
|
26
|
+
tsconfig
|
|
27
|
+
}, {
|
|
28
|
+
parentURL: import.meta.url,
|
|
29
|
+
tsconfig: false
|
|
30
|
+
}];
|
|
31
|
+
for (const options of importOptions) {
|
|
32
|
+
try {
|
|
33
|
+
const imported = await tsImport(moduleId, options);
|
|
34
|
+
if (typeof imported !== 'object' || imported === null) {
|
|
35
|
+
throw new TypegenCommandError(`Resolved ${moduleId} to an invalid module namespace.`);
|
|
36
|
+
}
|
|
37
|
+
return imported;
|
|
38
|
+
} catch (error) {
|
|
39
|
+
if (!isModuleNotFoundError(error)) {
|
|
40
|
+
throw error;
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
throw new TypegenCommandError(`Unable to resolve ${moduleId} from the inspected project.`);
|
|
45
|
+
}
|
|
46
|
+
async function importTypeScriptApplicationModule(modulePath) {
|
|
47
|
+
const moduleUrl = pathToFileURL(modulePath).href;
|
|
48
|
+
const tsconfigPath = resolve(dirname(modulePath), 'tsconfig.json');
|
|
49
|
+
return existsSync(tsconfigPath) ? tsImport(moduleUrl, {
|
|
50
|
+
parentURL: import.meta.url,
|
|
51
|
+
tsconfig: tsconfigPath
|
|
52
|
+
}) : tsImport(moduleUrl, {
|
|
53
|
+
parentURL: import.meta.url,
|
|
54
|
+
tsconfig: false
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
function requireNamespace(owner, name) {
|
|
58
|
+
const value = Reflect.get(owner, name);
|
|
59
|
+
if (typeof value !== 'object' || value === null) {
|
|
60
|
+
throw new TypegenCommandError(`Required typegen namespace ${name} is unavailable.`);
|
|
61
|
+
}
|
|
62
|
+
return value;
|
|
63
|
+
}
|
|
64
|
+
async function importNativeApplicationModule(modulePath) {
|
|
65
|
+
applicationImportSequence += 1;
|
|
66
|
+
const source = `import * as application from ${JSON.stringify(pathToFileURL(modulePath).href)};\nexport { application };\n`;
|
|
67
|
+
const graphUrl = `data:text/javascript;charset=utf-8,${encodeURIComponent(source)}#fluo-typegen-${String(applicationImportSequence)}`;
|
|
68
|
+
const graph = await tsImport(graphUrl, import.meta.url);
|
|
69
|
+
return requireNamespace(graph, 'application');
|
|
70
|
+
}
|
|
71
|
+
function requireFunction(owner, name) {
|
|
72
|
+
const value = Reflect.get(owner, name);
|
|
73
|
+
if (typeof value !== 'function') {
|
|
74
|
+
throw new TypegenCommandError(`Required typegen function ${name} is unavailable.`);
|
|
75
|
+
}
|
|
76
|
+
return value;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
/**
|
|
80
|
+
* Loads typegen package entrypoints from the consumer project or CLI installation.
|
|
81
|
+
*
|
|
82
|
+
* @param cwd Consumer project directory used for package resolution.
|
|
83
|
+
* @param tsconfig TypeScript configuration path, or `false` for native package resolution.
|
|
84
|
+
* @returns React, React typegen, and runtime module namespaces.
|
|
85
|
+
*/
|
|
86
|
+
export async function loadReactTypegenModules(cwd, tsconfig = false) {
|
|
87
|
+
const [react, typegen, runtime] = await Promise.all(TYPEGEN_MODULE_IDS.map(moduleId => importProjectModule(moduleId, cwd, tsconfig)));
|
|
88
|
+
return {
|
|
89
|
+
react,
|
|
90
|
+
runtime,
|
|
91
|
+
typegen
|
|
92
|
+
};
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
/**
|
|
96
|
+
* Bootstraps the selected module and generates source from authoritative route descriptors.
|
|
97
|
+
*
|
|
98
|
+
* @param options Parsed command, consumer directory, module namespaces, and native import boundary.
|
|
99
|
+
* @returns Complete deterministic generated source.
|
|
100
|
+
*/
|
|
101
|
+
export async function createTypegenSource(options) {
|
|
102
|
+
const modulePath = resolve(options.cwd, options.parsed.modulePath);
|
|
103
|
+
const importedApplication = TYPESCRIPT_MODULE_EXTENSIONS.has(extname(modulePath)) ? await importTypeScriptApplicationModule(modulePath) : await importNativeApplicationModule(modulePath);
|
|
104
|
+
return generateTypegenSource({
|
|
105
|
+
application: importedApplication,
|
|
106
|
+
modules: options.modules,
|
|
107
|
+
parsed: options.parsed
|
|
108
|
+
});
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
/**
|
|
112
|
+
* Generates source from one already-imported application and its matching tooling namespaces.
|
|
113
|
+
*
|
|
114
|
+
* @param options Application namespace, generation modules, and parsed command selection.
|
|
115
|
+
* @returns Complete deterministic generated source.
|
|
116
|
+
*/
|
|
117
|
+
export async function generateTypegenSource(options) {
|
|
118
|
+
const rootModule = Reflect.get(options.application, options.parsed.exportName);
|
|
119
|
+
if (typeof rootModule !== 'function') {
|
|
120
|
+
throw new TypegenCommandError(`Export "${options.parsed.exportName}" is not a module class constructor.`);
|
|
121
|
+
}
|
|
122
|
+
const factory = Reflect.get(options.modules.runtime, 'FluoFactory');
|
|
123
|
+
if (typeof factory !== 'function') {
|
|
124
|
+
throw new TypegenCommandError('Required runtime FluoFactory is unavailable.');
|
|
125
|
+
}
|
|
126
|
+
const application = await Reflect.apply(requireFunction(factory, 'create'), factory, [rootModule, {
|
|
127
|
+
logger: SILENT_APPLICATION_LOGGER
|
|
128
|
+
}]);
|
|
129
|
+
if (typeof application !== 'object' || application === null) {
|
|
130
|
+
throw new TypegenCommandError('Runtime application bootstrap returned an invalid value.');
|
|
131
|
+
}
|
|
132
|
+
const close = requireFunction(application, 'close');
|
|
133
|
+
try {
|
|
134
|
+
const dispatcher = Reflect.get(application, 'dispatcher');
|
|
135
|
+
if (typeof dispatcher !== 'object' || dispatcher === null) {
|
|
136
|
+
throw new TypegenCommandError('Runtime application dispatcher is unavailable.');
|
|
137
|
+
}
|
|
138
|
+
const descriptors = Reflect.apply(requireFunction(dispatcher, 'describeRoutes'), dispatcher, []);
|
|
139
|
+
if (!Array.isArray(descriptors)) {
|
|
140
|
+
throw new TypegenCommandError('Runtime route descriptors are unavailable.');
|
|
141
|
+
}
|
|
142
|
+
const catalog = Reflect.apply(requireFunction(options.modules.react, 'createReactPageCatalog'), undefined, [descriptors]);
|
|
143
|
+
const source = Reflect.apply(requireFunction(options.modules.typegen, 'generateReactPageTypes'), undefined, [catalog]);
|
|
144
|
+
if (typeof source !== 'string') {
|
|
145
|
+
throw new TypegenCommandError('React page typegen returned an invalid artifact.');
|
|
146
|
+
}
|
|
147
|
+
return source;
|
|
148
|
+
} finally {
|
|
149
|
+
await Reflect.apply(close, application, []);
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
/**
|
|
154
|
+
* Inspects an existing generated source value through the loaded React typegen package.
|
|
155
|
+
*
|
|
156
|
+
* @param modules Loaded React typegen module namespace.
|
|
157
|
+
* @param source Existing artifact source.
|
|
158
|
+
* @returns Parsed current, malformed, or unsupported-version status.
|
|
159
|
+
*/
|
|
160
|
+
export function inspectReactTypegenArtifact(modules, source) {
|
|
161
|
+
const inspection = Reflect.apply(requireFunction(modules.typegen, 'inspectReactPageTypeArtifact'), undefined, [source]);
|
|
162
|
+
if (typeof inspection !== 'object' || inspection === null || !('status' in inspection)) {
|
|
163
|
+
throw new TypegenCommandError('React page typegen artifact inspection returned an invalid result.');
|
|
164
|
+
}
|
|
165
|
+
if (inspection.status === 'malformed') {
|
|
166
|
+
return {
|
|
167
|
+
status: 'malformed'
|
|
168
|
+
};
|
|
169
|
+
}
|
|
170
|
+
if (inspection.status === 'unsupported-version' && 'version' in inspection && typeof inspection.version === 'number') {
|
|
171
|
+
return {
|
|
172
|
+
status: 'unsupported-version',
|
|
173
|
+
version: inspection.version
|
|
174
|
+
};
|
|
175
|
+
}
|
|
176
|
+
if (inspection.status === 'valid' && 'version' in inspection && typeof inspection.version === 'number') {
|
|
177
|
+
return {
|
|
178
|
+
status: 'valid',
|
|
179
|
+
version: inspection.version
|
|
180
|
+
};
|
|
181
|
+
}
|
|
182
|
+
throw new TypegenCommandError('React page typegen artifact inspection returned an invalid result.');
|
|
183
|
+
}
|
|
@@ -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
|
+
}
|
|
@@ -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"}
|