@zmdb/compiler 1.0.0-beta.1
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/LICENSE +674 -0
- package/README.md +40 -0
- package/dist/codegen/index.d.ts +50 -0
- package/dist/codegen/index.d.ts.map +1 -0
- package/dist/codegen/index.js +364 -0
- package/dist/codegen/index.js.map +1 -0
- package/dist/codegen/scan.d.ts +105 -0
- package/dist/codegen/scan.d.ts.map +1 -0
- package/dist/codegen/scan.js +450 -0
- package/dist/codegen/scan.js.map +1 -0
- package/dist/codegen/witness.d.ts +76 -0
- package/dist/codegen/witness.d.ts.map +1 -0
- package/dist/codegen/witness.js +690 -0
- package/dist/codegen/witness.js.map +1 -0
- package/dist/config/contract.d.ts +41 -0
- package/dist/config/contract.d.ts.map +1 -0
- package/dist/config/contract.js +5 -0
- package/dist/config/contract.js.map +1 -0
- package/dist/config/index.d.ts +53 -0
- package/dist/config/index.d.ts.map +1 -0
- package/dist/config/index.js +277 -0
- package/dist/config/index.js.map +1 -0
- package/dist/config/index.zmdb.generated.d.ts +12 -0
- package/dist/config/index.zmdb.generated.js +28 -0
- package/dist/config/index.zmdb.witness.d.ts +3 -0
- package/dist/config/index.zmdb.witness.d.ts.map +1 -0
- package/dist/config/index.zmdb.witness.js +20 -0
- package/dist/config/index.zmdb.witness.js.map +1 -0
- package/dist/configured-plugin.d.ts +11 -0
- package/dist/configured-plugin.d.ts.map +1 -0
- package/dist/configured-plugin.js +27 -0
- package/dist/configured-plugin.js.map +1 -0
- package/dist/emit/index.d.ts +103 -0
- package/dist/emit/index.d.ts.map +1 -0
- package/dist/emit/index.js +1356 -0
- package/dist/emit/index.js.map +1 -0
- package/dist/errors.d.ts +7 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/errors.js +2 -0
- package/dist/errors.js.map +1 -0
- package/dist/index.d.ts +46 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +254 -0
- package/dist/index.js.map +1 -0
- package/dist/lint/ast.d.ts +17 -0
- package/dist/lint/ast.d.ts.map +1 -0
- package/dist/lint/ast.js +77 -0
- package/dist/lint/ast.js.map +1 -0
- package/dist/lint/host-types.d.ts +9 -0
- package/dist/lint/host-types.d.ts.map +1 -0
- package/dist/lint/host-types.js +2 -0
- package/dist/lint/host-types.js.map +1 -0
- package/dist/lint/index.d.ts +23 -0
- package/dist/lint/index.d.ts.map +1 -0
- package/dist/lint/index.js +53 -0
- package/dist/lint/index.js.map +1 -0
- package/dist/lint/rules/no-distributed-nullable-tags.d.ts +3 -0
- package/dist/lint/rules/no-distributed-nullable-tags.d.ts.map +1 -0
- package/dist/lint/rules/no-distributed-nullable-tags.js +71 -0
- package/dist/lint/rules/no-distributed-nullable-tags.js.map +1 -0
- package/dist/lint/rules/no-empty-patch.d.ts +3 -0
- package/dist/lint/rules/no-empty-patch.d.ts.map +1 -0
- package/dist/lint/rules/no-empty-patch.js +26 -0
- package/dist/lint/rules/no-empty-patch.js.map +1 -0
- package/dist/lint/rules/no-interpolated-sql.d.ts +3 -0
- package/dist/lint/rules/no-interpolated-sql.d.ts.map +1 -0
- package/dist/lint/rules/no-interpolated-sql.js +35 -0
- package/dist/lint/rules/no-interpolated-sql.js.map +1 -0
- package/dist/lint/rules/no-unbounded-find.d.ts +3 -0
- package/dist/lint/rules/no-unbounded-find.d.ts.map +1 -0
- package/dist/lint/rules/no-unbounded-find.js +26 -0
- package/dist/lint/rules/no-unbounded-find.js.map +1 -0
- package/dist/lint/rules/no-unknown-json-column.d.ts +3 -0
- package/dist/lint/rules/no-unknown-json-column.d.ts.map +1 -0
- package/dist/lint/rules/no-unknown-json-column.js +35 -0
- package/dist/lint/rules/no-unknown-json-column.js.map +1 -0
- package/dist/lint/rules/require-sql-on-number.d.ts +3 -0
- package/dist/lint/rules/require-sql-on-number.d.ts.map +1 -0
- package/dist/lint/rules/require-sql-on-number.js +34 -0
- package/dist/lint/rules/require-sql-on-number.js.map +1 -0
- package/dist/lint/types.d.ts +12 -0
- package/dist/lint/types.d.ts.map +1 -0
- package/dist/lint/types.js +2 -0
- package/dist/lint/types.js.map +1 -0
- package/dist/metro/metro.d.ts +22 -0
- package/dist/metro/metro.d.ts.map +1 -0
- package/dist/metro/metro.js +242 -0
- package/dist/metro/metro.js.map +1 -0
- package/dist/protobuf/decode.d.ts +20 -0
- package/dist/protobuf/decode.d.ts.map +1 -0
- package/dist/protobuf/decode.js +289 -0
- package/dist/protobuf/decode.js.map +1 -0
- package/dist/protobuf/descriptor.d.ts +16 -0
- package/dist/protobuf/descriptor.d.ts.map +1 -0
- package/dist/protobuf/descriptor.js +303 -0
- package/dist/protobuf/descriptor.js.map +1 -0
- package/dist/protobuf/encode.d.ts +20 -0
- package/dist/protobuf/encode.d.ts.map +1 -0
- package/dist/protobuf/encode.js +203 -0
- package/dist/protobuf/encode.js.map +1 -0
- package/dist/protobuf/grpc-ir.d.ts +16 -0
- package/dist/protobuf/grpc-ir.d.ts.map +1 -0
- package/dist/protobuf/grpc-ir.js +2 -0
- package/dist/protobuf/grpc-ir.js.map +1 -0
- package/dist/protobuf/plan.d.ts +42 -0
- package/dist/protobuf/plan.d.ts.map +1 -0
- package/dist/protobuf/plan.js +158 -0
- package/dist/protobuf/plan.js.map +1 -0
- package/dist/reflect/callsites.d.ts +40 -0
- package/dist/reflect/callsites.d.ts.map +1 -0
- package/dist/reflect/callsites.js +153 -0
- package/dist/reflect/callsites.js.map +1 -0
- package/dist/reflect/index.d.ts +106 -0
- package/dist/reflect/index.d.ts.map +1 -0
- package/dist/reflect/index.js +1421 -0
- package/dist/reflect/index.js.map +1 -0
- package/dist/reflect/session.d.ts +118 -0
- package/dist/reflect/session.d.ts.map +1 -0
- package/dist/reflect/session.js +228 -0
- package/dist/reflect/session.js.map +1 -0
- package/dist/testing/index.d.ts +69 -0
- package/dist/testing/index.d.ts.map +1 -0
- package/dist/testing/index.js +210 -0
- package/dist/testing/index.js.map +1 -0
- package/dist/transform/index.d.ts +74 -0
- package/dist/transform/index.d.ts.map +1 -0
- package/dist/transform/index.js +572 -0
- package/dist/transform/index.js.map +1 -0
- package/dist/unplugin/index.d.ts +53 -0
- package/dist/unplugin/index.d.ts.map +1 -0
- package/dist/unplugin/index.js +130 -0
- package/dist/unplugin/index.js.map +1 -0
- package/dist/unplugin/inline-bench.d.ts +29 -0
- package/dist/unplugin/inline-bench.d.ts.map +1 -0
- package/dist/unplugin/inline-bench.js +82 -0
- package/dist/unplugin/inline-bench.js.map +1 -0
- package/package.json +110 -0
- package/src/codegen/index.ts +451 -0
- package/src/codegen/scan.ts +574 -0
- package/src/codegen/witness.ts +819 -0
- package/src/config/contract.ts +48 -0
- package/src/config/index.ts +384 -0
- package/src/config/index.zmdb.generated.d.ts +12 -0
- package/src/config/index.zmdb.generated.js +28 -0
- package/src/config/index.zmdb.witness.ts +22 -0
- package/src/configured-plugin.ts +35 -0
- package/src/emit/index.ts +1496 -0
- package/src/errors.ts +6 -0
- package/src/index.ts +336 -0
- package/src/lint/ast.ts +96 -0
- package/src/lint/host-types.ts +9 -0
- package/src/lint/index.ts +80 -0
- package/src/lint/rules/no-distributed-nullable-tags.ts +76 -0
- package/src/lint/rules/no-empty-patch.ts +26 -0
- package/src/lint/rules/no-interpolated-sql.ts +45 -0
- package/src/lint/rules/no-unbounded-find.ts +26 -0
- package/src/lint/rules/no-unknown-json-column.ts +36 -0
- package/src/lint/rules/require-sql-on-number.ts +34 -0
- package/src/lint/types.ts +11 -0
- package/src/metro/metro.ts +313 -0
- package/src/protobuf/decode.ts +375 -0
- package/src/protobuf/descriptor.ts +353 -0
- package/src/protobuf/encode.ts +277 -0
- package/src/protobuf/grpc-ir.ts +17 -0
- package/src/protobuf/plan.ts +244 -0
- package/src/reflect/callsites.ts +198 -0
- package/src/reflect/index.ts +1723 -0
- package/src/reflect/session.ts +276 -0
- package/src/testing/index.ts +298 -0
- package/src/transform/index.ts +690 -0
- package/src/unplugin/index.ts +182 -0
- package/src/unplugin/inline-bench.ts +92 -0
package/README.md
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
# @zmdb/compiler
|
|
2
|
+
|
|
3
|
+
`@zmdb/compiler` is zmdb's single TypeScript front end. It owns reflection, AOT emission, project compilation, unplugin and Metro adapters, lint rules, testing helpers, and canonical project-config
|
|
4
|
+
loading.
|
|
5
|
+
|
|
6
|
+
Part of **[zmdb](https://github.com/ambasta/zmdb)**. Application runtime code imports its published runtime owner; generated code never imports this package.
|
|
7
|
+
|
|
8
|
+
## Install
|
|
9
|
+
|
|
10
|
+
```bash
|
|
11
|
+
yarn add --dev @zmdb/compiler@1.0.0-beta.1 typescript@^7.0.2
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
> **Prerelease** (`1.0.0-beta.1`). Requires **Node.js 26+**. Published modules are ESM; Node.js 26 also supports synchronous `require('@zmdb/compiler/metro')` from a CommonJS Metro configuration.
|
|
15
|
+
|
|
16
|
+
## Choose a compilation route
|
|
17
|
+
|
|
18
|
+
- Use the sole `zmdb` executable from `@zmdb/cli` for `zmdb codegen --project tsconfig.json`.
|
|
19
|
+
- Use `compileProject({ project })` to collect artifacts without changing the project, then `writeCompileResult(result)` to publish them. Its `{ check: true }` option reports stale artifacts without
|
|
20
|
+
writing them. `watchCodegen` provides the retained-session watch API.
|
|
21
|
+
- Use the root `zmdbAot` function for an async build plugin that loads the project's zmdb config. The synchronous `@zmdb/compiler/unplugin` entry accepts explicit project and naming options when the
|
|
22
|
+
caller owns configuration.
|
|
23
|
+
- Select `@zmdb/compiler/metro` for Metro or `@zmdb/compiler/lint` for Oxlint, installing that adapter's optional peers.
|
|
24
|
+
|
|
25
|
+
Configuration belongs to this package: `@zmdb/compiler/config` loads it and `@zmdb/compiler/config/contract` provides `defineConfig` and its structural types. The product facade exposes the curated
|
|
26
|
+
compiler and config APIs through `zmdb/compiler` and `zmdb/config`.
|
|
27
|
+
|
|
28
|
+
## Entry points
|
|
29
|
+
|
|
30
|
+
`@zmdb/compiler`, `@zmdb/compiler/config`, `@zmdb/compiler/config/contract`, `@zmdb/compiler/emit`, `@zmdb/compiler/errors`, `@zmdb/compiler/lint`, `@zmdb/compiler/metro`, `@zmdb/compiler/reflect`,
|
|
31
|
+
`@zmdb/compiler/testing`, `@zmdb/compiler/transform`, `@zmdb/compiler/unplugin`
|
|
32
|
+
|
|
33
|
+
Generated application JavaScript imports runtime helpers from the source's published runtime owner, such as `zmdb`, `@zmdb/validator`, or `@zmdb/protobuf`; it never imports this package. Install the
|
|
34
|
+
runtime owners used by your application as runtime dependencies and keep compiler setup in the build environment.
|
|
35
|
+
|
|
36
|
+
TypeScript is a required peer. Oxlint, Metro, and Metro's Babel transformer are optional peers used only by the matching explicit subpaths.
|
|
37
|
+
|
|
38
|
+
## License
|
|
39
|
+
|
|
40
|
+
GNU General Public License v3.0 or later (GPL-3.0-or-later) — see [LICENSE](./LICENSE).
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { type NamingStrategyConfig } from '@zmdb/schema/naming';
|
|
2
|
+
import { ReflectSession } from '../reflect/session.js';
|
|
3
|
+
export interface CodegenOptions {
|
|
4
|
+
/** Path to the `tsconfig.json` that defines what to generate for. */
|
|
5
|
+
readonly project: string;
|
|
6
|
+
/** Exact project members to compile. Omit to scan the complete project. */
|
|
7
|
+
readonly files?: readonly string[];
|
|
8
|
+
/** Report what would change and write nothing. */
|
|
9
|
+
readonly check?: boolean | undefined;
|
|
10
|
+
/** Where progress goes. Defaults to nowhere, so a library caller stays quiet. */
|
|
11
|
+
readonly log?: ((line: string) => void) | undefined;
|
|
12
|
+
/**
|
|
13
|
+
* An already-open session, as the plugin takes. The caller keeps ownership, closing
|
|
14
|
+
* included.
|
|
15
|
+
*
|
|
16
|
+
* A caller that already has the project loaded should not pay to load it again — that is
|
|
17
|
+
* REQ-TF-11's whole point, and it applies to a tool driving `codegen` just as much as to
|
|
18
|
+
* the build it is part of. It is also what makes the claim observable: the session records
|
|
19
|
+
* its snapshot updates, so `verify:build-budget` can watch a 64-module run and see that the
|
|
20
|
+
* project is opened once.
|
|
21
|
+
*/
|
|
22
|
+
readonly session?: ReflectSession | undefined;
|
|
23
|
+
/** A named or custom build-time strategy, resolved once for this run. */
|
|
24
|
+
readonly naming?: NamingStrategyConfig;
|
|
25
|
+
}
|
|
26
|
+
export interface CodegenResult {
|
|
27
|
+
/** Absolute paths written, or — under `--check` — that would have been. */
|
|
28
|
+
readonly written: readonly string[];
|
|
29
|
+
/** Absolute paths deleted, because their source stopped validating anything. */
|
|
30
|
+
readonly deleted: readonly string[];
|
|
31
|
+
/** Everything that stopped a file from being generated, formatted for a terminal. */
|
|
32
|
+
readonly problems: readonly string[];
|
|
33
|
+
readonly ok: boolean;
|
|
34
|
+
}
|
|
35
|
+
export declare function codegen(options: CodegenOptions): CodegenResult;
|
|
36
|
+
export interface WatchOptions extends CodegenOptions {
|
|
37
|
+
/** Quiet period after a change before regenerating. Editors save in bursts. */
|
|
38
|
+
readonly debounceMs?: number | undefined;
|
|
39
|
+
/** Resolves when the watch should stop. Omit to watch until the process ends. */
|
|
40
|
+
readonly until?: Promise<unknown> | undefined;
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Regenerate on every save, on one compiler session.
|
|
44
|
+
*
|
|
45
|
+
* The session is the whole reason this is not "rerun project compilation from a file watcher":
|
|
46
|
+
* reopening the project per keystroke re-reads the config and re-walks the import graph, which
|
|
47
|
+
* is the expensive half of a build. `ReflectSession.refresh` re-checks only what changed.
|
|
48
|
+
*/
|
|
49
|
+
export declare function watchCodegen(options: WatchOptions): Promise<CodegenResult>;
|
|
50
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/codegen/index.ts"],"names":[],"mappings":"AA+BA,OAAO,EAAiB,KAAK,oBAAoB,EAAE,MAAM,qBAAqB,CAAC;AAG/E,OAAO,EAAE,cAAc,EAAyB,MAAM,uBAAuB,CAAC;AAa9E,MAAM,WAAW,cAAc;IAC7B,qEAAqE;IACrE,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,2EAA2E;IAC3E,QAAQ,CAAC,KAAK,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IACnC,kDAAkD;IAClD,QAAQ,CAAC,KAAK,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;IACrC,iFAAiF;IACjF,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC,GAAG,SAAS,CAAC;IACpD;;;;;;;;;OASG;IACH,QAAQ,CAAC,OAAO,CAAC,EAAE,cAAc,GAAG,SAAS,CAAC;IAC9C,yEAAyE;IACzE,QAAQ,CAAC,MAAM,CAAC,EAAE,oBAAoB,CAAC;CACxC;AAED,MAAM,WAAW,aAAa;IAC5B,2EAA2E;IAC3E,QAAQ,CAAC,OAAO,EAAE,SAAS,MAAM,EAAE,CAAC;IACpC,gFAAgF;IAChF,QAAQ,CAAC,OAAO,EAAE,SAAS,MAAM,EAAE,CAAC;IACpC,qFAAqF;IACrF,QAAQ,CAAC,QAAQ,EAAE,SAAS,MAAM,EAAE,CAAC;IACrC,QAAQ,CAAC,EAAE,EAAE,OAAO,CAAC;CACtB;AAiBD,wBAAgB,OAAO,CAAC,OAAO,EAAE,cAAc,GAAG,aAAa,CAK9D;AAuQD,MAAM,WAAW,YAAa,SAAQ,cAAc;IAClD,+EAA+E;IAC/E,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACzC,iFAAiF;IACjF,QAAQ,CAAC,KAAK,CAAC,EAAE,OAAO,CAAC,OAAO,CAAC,GAAG,SAAS,CAAC;CAC/C;AAED;;;;;;GAMG;AACH,wBAAsB,YAAY,CAAC,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,aAAa,CAAC,CA6DhF"}
|
|
@@ -0,0 +1,364 @@
|
|
|
1
|
+
// The no-bundler AOT project compiler.
|
|
2
|
+
//
|
|
3
|
+
// The unplugin gets the type information for free — a bundler hands it a module, it asks the
|
|
4
|
+
// compiler about the type arguments in it, and it hands back rewritten source that only the
|
|
5
|
+
// bundler ever sees. A project built by plain `tsc`, or run straight off `node --strip-types`,
|
|
6
|
+
// has nowhere to put that step, and REQ-AV-3 says the compiled path may not be a reward for
|
|
7
|
+
// choosing a particular bundler. So this writes the rewrite down.
|
|
8
|
+
//
|
|
9
|
+
// Per source file that validates anything, three files (see `./witness.ts` for why three)
|
|
10
|
+
// and one edit to the source: `is<User>(data)` becomes `zmdbIsUser(data)`, imported from a
|
|
11
|
+
// generated module. The result is checked in, so a clone of the repository builds the fast
|
|
12
|
+
// path with no tool at all in the way.
|
|
13
|
+
//
|
|
14
|
+
// ## The order matters, and it is not the obvious one
|
|
15
|
+
//
|
|
16
|
+
// Every witness is written *before* any of them is transformed. The reason is cost: telling
|
|
17
|
+
// the compiler about a new file is a snapshot update, and a snapshot update per file would
|
|
18
|
+
// make a hundred-file project a hundred re-checks. Two updates for the whole run is the
|
|
19
|
+
// difference between this being usable and being a thing people turn off (REQ-TF-11).
|
|
20
|
+
//
|
|
21
|
+
// ## `--check` writes nothing, and still checks everything
|
|
22
|
+
//
|
|
23
|
+
// A check that had to write the witnesses to verify them would be a check that dirties the
|
|
24
|
+
// tree it is auditing. It does not have to: the witness is a pure function of the scan, so a
|
|
25
|
+
// stale one is caught by comparing text. And if every witness matches, then the compiled
|
|
26
|
+
// modules are derivable from files already on disk — the transform runs against those, and
|
|
27
|
+
// its output is compared the same way.
|
|
28
|
+
import { existsSync, mkdirSync, readFileSync, rmSync, writeFileSync } from 'node:fs';
|
|
29
|
+
import { dirname, isAbsolute, relative, resolve, sep } from 'node:path';
|
|
30
|
+
import { resolveNaming } from '@zmdb/schema/naming';
|
|
31
|
+
import { CALL_OWNERS, STRICT_OWNER_CALLEES } from '../reflect/callsites.js';
|
|
32
|
+
import { ReflectSession } from '../reflect/session.js';
|
|
33
|
+
import { CALLEES, transformFile } from '../transform/index.js';
|
|
34
|
+
import { scan } from './scan.js';
|
|
35
|
+
import { artifactPaths, generatedModules, isGeneratedPath, quoteStyle, rewriteSource, witnessSource, } from './witness.js';
|
|
36
|
+
/**
|
|
37
|
+
* Cheap pre-filter: does this file import any package that owns a transformed call?
|
|
38
|
+
* Looking for the owner rather than a callee spelling preserves the fast path for aliases.
|
|
39
|
+
*/
|
|
40
|
+
const OWNER_SPECIFIERS = [...new Set(Object.values(CALL_OWNERS).flat())];
|
|
41
|
+
const MENTIONS_OWNER = new RegExp(`\\bfrom\\s+['"](?:${OWNER_SPECIFIERS.map(specifier => specifier.replaceAll(/[.*+?^${}()|[\]\\]/g, '\\$&')).join('|')})['"]`);
|
|
42
|
+
const MENTIONS_FORWARDED_CALL = new RegExp(`\\b(?:${[...CALLEES]
|
|
43
|
+
.filter(callee => !STRICT_OWNER_CALLEES.has(callee))
|
|
44
|
+
.map(callee => callee.replaceAll(/[.*+?^${}()|[\]\\]/g, '\\$&'))
|
|
45
|
+
.join('|')})\\s*<`);
|
|
46
|
+
export function codegen(options) {
|
|
47
|
+
const project = resolve(options.project);
|
|
48
|
+
if (options.session)
|
|
49
|
+
return run(options.session, project, options);
|
|
50
|
+
using session = ReflectSession.open({ project });
|
|
51
|
+
return run(session, project, options);
|
|
52
|
+
}
|
|
53
|
+
function run(session, project, options) {
|
|
54
|
+
const root = dirname(project);
|
|
55
|
+
const log = options.log ?? (() => undefined);
|
|
56
|
+
const check = options.check === true;
|
|
57
|
+
const reflect = { naming: resolveNaming(options.naming) };
|
|
58
|
+
const problems = [];
|
|
59
|
+
const written = [];
|
|
60
|
+
const deleted = [];
|
|
61
|
+
const show = (path) => relative(root, path) || path;
|
|
62
|
+
const selected = options.files === undefined ? undefined : new Set(options.files.map(file => pathKey(file)));
|
|
63
|
+
const tsExtensions = session.compilerOptions()['allowImportingTsExtensions'] === true;
|
|
64
|
+
// -- Phase 1: what to generate ---------------------------------------------
|
|
65
|
+
const candidates = [];
|
|
66
|
+
for (const fileName of session.sourceFileNames()) {
|
|
67
|
+
if (selected !== undefined && !selected.has(pathKey(fileName)))
|
|
68
|
+
continue;
|
|
69
|
+
if (!isCandidate(fileName, root))
|
|
70
|
+
continue;
|
|
71
|
+
const paths = artifactPaths(fileName);
|
|
72
|
+
const hadWitness = existsSync(paths.witness);
|
|
73
|
+
let code;
|
|
74
|
+
try {
|
|
75
|
+
code = readFileSync(fileName, 'utf8');
|
|
76
|
+
}
|
|
77
|
+
catch {
|
|
78
|
+
// In the program but not on disk. A virtual file from another tool's plugin, or a race
|
|
79
|
+
// with a delete; either way there is nothing here to rewrite.
|
|
80
|
+
continue;
|
|
81
|
+
}
|
|
82
|
+
if (!hadWitness && !MENTIONS_OWNER.test(code) && !MENTIONS_FORWARDED_CALL.test(code))
|
|
83
|
+
continue;
|
|
84
|
+
const sourceFile = session.sourceFile(fileName);
|
|
85
|
+
if (!sourceFile) {
|
|
86
|
+
problems.push(`${show(fileName)}: in the project's file list but the compiler has no parse of it`);
|
|
87
|
+
continue;
|
|
88
|
+
}
|
|
89
|
+
if (sourceFile.text !== code) {
|
|
90
|
+
problems.push(`${show(fileName)}: changed on disk since the project loaded; run again`);
|
|
91
|
+
continue;
|
|
92
|
+
}
|
|
93
|
+
const witnessFile = hadWitness ? session.sourceFile(paths.witness) : undefined;
|
|
94
|
+
if (hadWitness && !witnessFile) {
|
|
95
|
+
problems.push(`${show(paths.witness)}: exists but is not part of ${show(project)}. ` +
|
|
96
|
+
'The witness has to be typechecked, so the project must include it.');
|
|
97
|
+
continue;
|
|
98
|
+
}
|
|
99
|
+
const scanned = scan({ checker: session.checker, sourceFile, witnessFile, tsExtensions });
|
|
100
|
+
for (const refusal of scanned.refusals) {
|
|
101
|
+
problems.push(`${show(fileName)}: cannot generate for \`${refusal.typeText}\` — ${refusal.reason}`);
|
|
102
|
+
}
|
|
103
|
+
if (scanned.refusals.length > 0)
|
|
104
|
+
continue;
|
|
105
|
+
const sourceName = show(fileName);
|
|
106
|
+
const style = quoteStyle(sourceFile);
|
|
107
|
+
candidates.push({
|
|
108
|
+
fileName,
|
|
109
|
+
sourceFile,
|
|
110
|
+
code,
|
|
111
|
+
paths,
|
|
112
|
+
hadWitness,
|
|
113
|
+
style,
|
|
114
|
+
entries: scanned.entries,
|
|
115
|
+
sites: scanned.sites,
|
|
116
|
+
typeImports: scanned.typeImports,
|
|
117
|
+
calleeSources: scanned.calleeSources,
|
|
118
|
+
witness: scanned.entries.length === 0
|
|
119
|
+
? ''
|
|
120
|
+
: witnessSource({
|
|
121
|
+
sourceName,
|
|
122
|
+
entries: scanned.entries,
|
|
123
|
+
typeImports: scanned.typeImports,
|
|
124
|
+
calleeSources: scanned.calleeSources,
|
|
125
|
+
style,
|
|
126
|
+
}),
|
|
127
|
+
});
|
|
128
|
+
}
|
|
129
|
+
// -- Phase 2: the witnesses, then one snapshot update ---------------------
|
|
130
|
+
const created = [];
|
|
131
|
+
const refreshed = [];
|
|
132
|
+
const stale = new Set();
|
|
133
|
+
for (const candidate of candidates) {
|
|
134
|
+
if (candidate.witness.length === 0)
|
|
135
|
+
continue;
|
|
136
|
+
const current = candidate.hadWitness ? readFileSync(candidate.paths.witness, 'utf8') : undefined;
|
|
137
|
+
if (current === candidate.witness)
|
|
138
|
+
continue;
|
|
139
|
+
if (check) {
|
|
140
|
+
// Without the right witness on disk there is nothing to transform, so this file's
|
|
141
|
+
// compiled modules are not examined further — the answer is already "stale".
|
|
142
|
+
written.push(candidate.paths.witness);
|
|
143
|
+
stale.add(candidate);
|
|
144
|
+
continue;
|
|
145
|
+
}
|
|
146
|
+
mkdirSync(dirname(candidate.paths.witness), { recursive: true });
|
|
147
|
+
writeFileSync(candidate.paths.witness, candidate.witness);
|
|
148
|
+
written.push(candidate.paths.witness);
|
|
149
|
+
(candidate.hadWitness ? refreshed : created).push(candidate.paths.witness);
|
|
150
|
+
}
|
|
151
|
+
if (created.length > 0)
|
|
152
|
+
session.created(created);
|
|
153
|
+
if (refreshed.length > 0)
|
|
154
|
+
session.refresh(refreshed);
|
|
155
|
+
// -- Phase 3: the compiled modules and the rewrite ------------------------
|
|
156
|
+
for (const candidate of candidates) {
|
|
157
|
+
if (stale.has(candidate))
|
|
158
|
+
continue;
|
|
159
|
+
if (candidate.witness.length === 0) {
|
|
160
|
+
// The source stopped validating. Its artifacts are removed rather than left behind:
|
|
161
|
+
// a witness with no referent is a validator for code that is gone.
|
|
162
|
+
for (const path of [candidate.paths.witness, candidate.paths.js, candidate.paths.dts]) {
|
|
163
|
+
if (!existsSync(path))
|
|
164
|
+
continue;
|
|
165
|
+
deleted.push(path);
|
|
166
|
+
if (!check)
|
|
167
|
+
rmSync(path);
|
|
168
|
+
}
|
|
169
|
+
const rewritten = rewriteSource({
|
|
170
|
+
sourceFile: candidate.sourceFile,
|
|
171
|
+
code: candidate.code,
|
|
172
|
+
sites: [],
|
|
173
|
+
specifier: candidate.paths.specifier,
|
|
174
|
+
entries: [],
|
|
175
|
+
calleeSources: candidate.calleeSources,
|
|
176
|
+
style: candidate.style,
|
|
177
|
+
});
|
|
178
|
+
emit(candidate.fileName, rewritten);
|
|
179
|
+
continue;
|
|
180
|
+
}
|
|
181
|
+
const diagnostics = session.diagnostics(candidate.paths.witness);
|
|
182
|
+
if (diagnostics.length > 0) {
|
|
183
|
+
const first = diagnostics[0];
|
|
184
|
+
problems.push(`${show(candidate.paths.witness)}: does not typecheck (TS${String(first?.code ?? 0)}: ${first?.text ?? ''}). ` +
|
|
185
|
+
'A type read out of a file that does not compile is a guess.');
|
|
186
|
+
continue;
|
|
187
|
+
}
|
|
188
|
+
const errorModule = candidate.calleeSources.get('assert') ??
|
|
189
|
+
candidate.calleeSources.get('assertShallow') ??
|
|
190
|
+
candidate.calleeSources.get('assertEquals') ??
|
|
191
|
+
'@zmdb/validator';
|
|
192
|
+
const transformed = transformFile(candidate.paths.witness, candidate.witness, {
|
|
193
|
+
session,
|
|
194
|
+
reflect,
|
|
195
|
+
emit: { errorModule },
|
|
196
|
+
});
|
|
197
|
+
if (transformed.diagnostics.length > 0) {
|
|
198
|
+
for (const diagnostic of transformed.diagnostics) {
|
|
199
|
+
const where = diagnostic.path ? ` at \`${diagnostic.path}\`` : '';
|
|
200
|
+
problems.push(`${show(candidate.fileName)}: ${diagnostic.callee ?? 'the transform'} refused${where} — ${diagnostic.reason}`);
|
|
201
|
+
}
|
|
202
|
+
continue;
|
|
203
|
+
}
|
|
204
|
+
if (!transformed.changed) {
|
|
205
|
+
problems.push(`${show(candidate.paths.witness)}: the transform left every call in place, so nothing was compiled`);
|
|
206
|
+
continue;
|
|
207
|
+
}
|
|
208
|
+
const modules = generatedModules({
|
|
209
|
+
sourceName: show(candidate.fileName),
|
|
210
|
+
entries: candidate.entries,
|
|
211
|
+
typeImports: candidate.typeImports,
|
|
212
|
+
calleeSources: candidate.calleeSources,
|
|
213
|
+
style: candidate.style,
|
|
214
|
+
transformed: transformed.code,
|
|
215
|
+
});
|
|
216
|
+
emit(candidate.paths.js, modules.js);
|
|
217
|
+
emit(candidate.paths.dts, modules.dts);
|
|
218
|
+
emit(candidate.fileName, rewriteSource({
|
|
219
|
+
sourceFile: candidate.sourceFile,
|
|
220
|
+
code: candidate.code,
|
|
221
|
+
sites: candidate.sites,
|
|
222
|
+
specifier: candidate.paths.specifier,
|
|
223
|
+
entries: candidate.entries,
|
|
224
|
+
calleeSources: candidate.calleeSources,
|
|
225
|
+
style: candidate.style,
|
|
226
|
+
}));
|
|
227
|
+
}
|
|
228
|
+
function emit(path, text) {
|
|
229
|
+
let current;
|
|
230
|
+
try {
|
|
231
|
+
current = readFileSync(path, 'utf8');
|
|
232
|
+
}
|
|
233
|
+
catch {
|
|
234
|
+
current = undefined;
|
|
235
|
+
}
|
|
236
|
+
if (current === text)
|
|
237
|
+
return;
|
|
238
|
+
written.push(path);
|
|
239
|
+
if (check)
|
|
240
|
+
return;
|
|
241
|
+
mkdirSync(dirname(path), { recursive: true });
|
|
242
|
+
writeFileSync(path, text);
|
|
243
|
+
}
|
|
244
|
+
for (const path of written)
|
|
245
|
+
log(`${check ? 'stale' : 'wrote'} ${show(path)}`);
|
|
246
|
+
for (const path of deleted)
|
|
247
|
+
log(`${check ? 'orphan' : 'removed'} ${show(path)}`);
|
|
248
|
+
return {
|
|
249
|
+
written,
|
|
250
|
+
deleted,
|
|
251
|
+
problems,
|
|
252
|
+
ok: problems.length === 0 && (!check || (written.length === 0 && deleted.length === 0)),
|
|
253
|
+
};
|
|
254
|
+
}
|
|
255
|
+
function pathKey(path) {
|
|
256
|
+
const value = resolve(path);
|
|
257
|
+
return process.platform === 'win32' ? value.toLowerCase() : value;
|
|
258
|
+
}
|
|
259
|
+
/** Files this run may rewrite: the project's own TypeScript, minus what it generated. */
|
|
260
|
+
function isCandidate(fileName, root) {
|
|
261
|
+
if (fileName.includes(`${sep}node_modules${sep}`) || fileName.includes('/node_modules/'))
|
|
262
|
+
return false;
|
|
263
|
+
if (/\.d\.[cm]?ts$/.test(fileName))
|
|
264
|
+
return false;
|
|
265
|
+
if (!/\.[cm]?tsx?$/.test(fileName))
|
|
266
|
+
return false;
|
|
267
|
+
if (isGeneratedPath(fileName))
|
|
268
|
+
return false;
|
|
269
|
+
// A project can reference files above its own directory; rewriting one would edit a
|
|
270
|
+
// package this run was not pointed at.
|
|
271
|
+
const inside = relative(root, fileName);
|
|
272
|
+
return inside.length > 0 && !inside.startsWith('..') && !isAbsolute(inside);
|
|
273
|
+
}
|
|
274
|
+
/**
|
|
275
|
+
* Regenerate on every save, on one compiler session.
|
|
276
|
+
*
|
|
277
|
+
* The session is the whole reason this is not "rerun project compilation from a file watcher":
|
|
278
|
+
* reopening the project per keystroke re-reads the config and re-walks the import graph, which
|
|
279
|
+
* is the expensive half of a build. `ReflectSession.refresh` re-checks only what changed.
|
|
280
|
+
*/
|
|
281
|
+
export async function watchCodegen(options) {
|
|
282
|
+
const { watch } = await import('node:fs/promises');
|
|
283
|
+
const project = resolve(options.project);
|
|
284
|
+
const root = dirname(project);
|
|
285
|
+
const log = options.log ?? (() => undefined);
|
|
286
|
+
const borrowed = options.session;
|
|
287
|
+
const session = borrowed ?? ReflectSession.open({ project });
|
|
288
|
+
const controller = new AbortController();
|
|
289
|
+
let timer;
|
|
290
|
+
let last;
|
|
291
|
+
let failure;
|
|
292
|
+
const pending = new Set();
|
|
293
|
+
const stop = () => {
|
|
294
|
+
controller.abort();
|
|
295
|
+
};
|
|
296
|
+
void options.until?.then(stop, stop);
|
|
297
|
+
const flush = () => {
|
|
298
|
+
timer = undefined;
|
|
299
|
+
if (controller.signal.aborted)
|
|
300
|
+
return;
|
|
301
|
+
const changed = [...pending];
|
|
302
|
+
pending.clear();
|
|
303
|
+
if (changed.length === 0)
|
|
304
|
+
return;
|
|
305
|
+
try {
|
|
306
|
+
const live = changed.filter(path => existsSync(path));
|
|
307
|
+
const created = live.filter(path => session.sourceFile(path) === undefined);
|
|
308
|
+
const refreshed = live.filter(path => session.sourceFile(path) !== undefined);
|
|
309
|
+
const gone = changed.filter(path => !existsSync(path));
|
|
310
|
+
if (created.length > 0)
|
|
311
|
+
session.created(created);
|
|
312
|
+
if (refreshed.length > 0)
|
|
313
|
+
session.refresh(refreshed);
|
|
314
|
+
if (gone.length > 0)
|
|
315
|
+
session.deleted(gone);
|
|
316
|
+
last = run(session, project, options);
|
|
317
|
+
report(last, log);
|
|
318
|
+
}
|
|
319
|
+
catch (error) {
|
|
320
|
+
failure = error;
|
|
321
|
+
stop();
|
|
322
|
+
}
|
|
323
|
+
};
|
|
324
|
+
try {
|
|
325
|
+
last = run(session, project, options);
|
|
326
|
+
report(last, log);
|
|
327
|
+
try {
|
|
328
|
+
for await (const event of watch(root, { recursive: true, signal: controller.signal })) {
|
|
329
|
+
const name = typeof event.filename === 'string' ? resolve(root, event.filename) : undefined;
|
|
330
|
+
if (name === undefined || !isCandidate(name, root))
|
|
331
|
+
continue;
|
|
332
|
+
pending.add(name);
|
|
333
|
+
if (timer !== undefined)
|
|
334
|
+
clearTimeout(timer);
|
|
335
|
+
timer = setTimeout(flush, options.debounceMs ?? 60);
|
|
336
|
+
}
|
|
337
|
+
}
|
|
338
|
+
catch (error) {
|
|
339
|
+
if (!(error instanceof Error) || error.name !== 'AbortError')
|
|
340
|
+
throw error;
|
|
341
|
+
}
|
|
342
|
+
if (failure !== undefined)
|
|
343
|
+
throw failure;
|
|
344
|
+
return last;
|
|
345
|
+
}
|
|
346
|
+
finally {
|
|
347
|
+
stop();
|
|
348
|
+
if (timer !== undefined)
|
|
349
|
+
clearTimeout(timer);
|
|
350
|
+
pending.clear();
|
|
351
|
+
if (borrowed === undefined)
|
|
352
|
+
session.close();
|
|
353
|
+
}
|
|
354
|
+
}
|
|
355
|
+
function report(result, log) {
|
|
356
|
+
for (const problem of result.problems)
|
|
357
|
+
log(`error: ${problem}`);
|
|
358
|
+
if (result.problems.length === 0) {
|
|
359
|
+
log(result.written.length === 0 && result.deleted.length === 0
|
|
360
|
+
? 'up to date'
|
|
361
|
+
: `generated ${String(result.written.length)} artifact(s); deleted ${String(result.deleted.length)}`);
|
|
362
|
+
}
|
|
363
|
+
}
|
|
364
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/codegen/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
import type { Node, SourceFile } from 'typescript/unstable/ast';
|
|
2
|
+
import type { Checker } from 'typescript/unstable/sync';
|
|
3
|
+
import { type CallSite } from '../reflect/callsites.js';
|
|
4
|
+
/** How a name got into a module's scope, in a form that can be written down again. */
|
|
5
|
+
export interface ImportBinding {
|
|
6
|
+
readonly specifier: string;
|
|
7
|
+
readonly kind: 'default' | 'named' | 'namespace';
|
|
8
|
+
/** The name in the exporting module. Only meaningful for `named`. */
|
|
9
|
+
readonly original: string;
|
|
10
|
+
}
|
|
11
|
+
/** Everything about one module that the witness generator needs, all of it syntactic. */
|
|
12
|
+
export interface ModuleFacts {
|
|
13
|
+
/** Local binding name → the import that introduced it. */
|
|
14
|
+
readonly imports: ReadonlyMap<string, ImportBinding>;
|
|
15
|
+
/** Names this module declares itself, type or value. */
|
|
16
|
+
readonly locals: ReadonlySet<string>;
|
|
17
|
+
/** Names this module exports, however it exports them. */
|
|
18
|
+
readonly exported: ReadonlySet<string>;
|
|
19
|
+
}
|
|
20
|
+
/** One thing the generated module will export, and the call it comes from. */
|
|
21
|
+
export interface Entry {
|
|
22
|
+
readonly callee: string;
|
|
23
|
+
/** The type argument, verbatim from the source it was read in. */
|
|
24
|
+
readonly typeText: string;
|
|
25
|
+
/** The non-default shallow depth, when this call carries one. */
|
|
26
|
+
readonly depthText?: string;
|
|
27
|
+
/** Literal value arguments captured into a zero-argument generated artifact. */
|
|
28
|
+
readonly argumentsText?: readonly string[];
|
|
29
|
+
/** The export name in the generated module. Derived, so it is stable across runs. */
|
|
30
|
+
readonly name: string;
|
|
31
|
+
}
|
|
32
|
+
/** A call site in a source file, paired with the entry it maps onto. */
|
|
33
|
+
export interface SiteEntry {
|
|
34
|
+
readonly site: CallSite;
|
|
35
|
+
readonly entry: Entry;
|
|
36
|
+
}
|
|
37
|
+
/** What the codegen could not do, and which name made it impossible. */
|
|
38
|
+
export interface ScanRefusal {
|
|
39
|
+
readonly typeText: string;
|
|
40
|
+
readonly reason: string;
|
|
41
|
+
}
|
|
42
|
+
export interface ScanResult {
|
|
43
|
+
readonly entries: readonly Entry[];
|
|
44
|
+
/** Sites in the *source* file, in source order, for the rewrite. */
|
|
45
|
+
readonly sites: readonly SiteEntry[];
|
|
46
|
+
readonly refusals: readonly ScanRefusal[];
|
|
47
|
+
/** Module specifier → the names the witness must import from it. */
|
|
48
|
+
readonly typeImports: readonly TypeImport[];
|
|
49
|
+
/** Callee → where the source got it from, so the witness can get it from there too. */
|
|
50
|
+
readonly calleeSources: ReadonlyMap<string, string>;
|
|
51
|
+
}
|
|
52
|
+
export interface TypeImport {
|
|
53
|
+
readonly specifier: string;
|
|
54
|
+
readonly kind: 'default' | 'named' | 'namespace';
|
|
55
|
+
/** `original as local`, or just `local` when they match. */
|
|
56
|
+
readonly local: string;
|
|
57
|
+
readonly original: string;
|
|
58
|
+
}
|
|
59
|
+
/** Import bindings, local declarations and exports of one module. */
|
|
60
|
+
export declare function moduleFacts(sourceFile: SourceFile): ModuleFacts;
|
|
61
|
+
/**
|
|
62
|
+
* The names a type argument depends on, as written.
|
|
63
|
+
*
|
|
64
|
+
* Only the *head* of a reference counts: `ns.T` needs `ns`, `Omit<User, 'id'>` needs
|
|
65
|
+
* `Omit` and `User`, and the `'id'` needs nothing. Collecting every identifier instead
|
|
66
|
+
* would drag in the property names of an inline object type and then refuse the call site
|
|
67
|
+
* because `email` is not importable.
|
|
68
|
+
*/
|
|
69
|
+
export declare function referencedNames(node: Node): ReadonlySet<string>;
|
|
70
|
+
/**
|
|
71
|
+
* A stable export name for one entry.
|
|
72
|
+
*
|
|
73
|
+
* Stability is the requirement, not beauty: the name is written into the user's source, so
|
|
74
|
+
* it has to come out the same on every run or the codegen produces a diff per invocation.
|
|
75
|
+
* It is derived only from the callee and the type text, both of which are in the source.
|
|
76
|
+
*/
|
|
77
|
+
export declare function exportName(callee: string, typeText: string, taken: ReadonlySet<string>, depthText?: string, identityText?: string): string;
|
|
78
|
+
export interface ScanInput {
|
|
79
|
+
readonly checker: Checker;
|
|
80
|
+
readonly sourceFile: SourceFile;
|
|
81
|
+
/** The previous run's witness, when there is one. See `scan` for why it is read. */
|
|
82
|
+
readonly witnessFile?: SourceFile | undefined;
|
|
83
|
+
/**
|
|
84
|
+
* Whether the project lets a relative import name a `.ts` file
|
|
85
|
+
* (`allowImportingTsExtensions`). Only consulted for a file that has no relative import to
|
|
86
|
+
* copy the style from; see `relativeExtension`.
|
|
87
|
+
*/
|
|
88
|
+
readonly tsExtensions?: boolean | undefined;
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* Everything the generator needs for one source file.
|
|
92
|
+
*
|
|
93
|
+
* Two inputs rather than one, because the rewrite is destructive: after a run the source
|
|
94
|
+
* says `zmdbIsUser(data)` and the `is<User>` that produced it is gone. The witness keeps
|
|
95
|
+
* it — and keeps it in a form the compiler checks, so a renamed or deleted `User` is a
|
|
96
|
+
* build error in a generated file rather than a validator that quietly describes a type
|
|
97
|
+
* nobody declares any more. So the entry set is the union of the two, and an entry the
|
|
98
|
+
* source has stopped referencing is dropped, which is what stops the witness accumulating
|
|
99
|
+
* validators for code that no longer exists.
|
|
100
|
+
*/
|
|
101
|
+
export declare function scan(input: ScanInput): ScanResult;
|
|
102
|
+
/** Whether `text` uses `name` as an identifier, rather than as part of a longer one. */
|
|
103
|
+
export declare function referencesName(text: string, name: string): boolean;
|
|
104
|
+
export declare function basename(path: string): string;
|
|
105
|
+
//# sourceMappingURL=scan.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scan.d.ts","sourceRoot":"","sources":["../../src/codegen/scan.ts"],"names":[],"mappings":"AAgBA,OAAO,KAAK,EAAE,IAAI,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAC;AAqBhE,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,0BAA0B,CAAC;AAExD,OAAO,EAAmC,KAAK,QAAQ,EAAE,MAAM,yBAAyB,CAAC;AAGzF,sFAAsF;AACtF,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,IAAI,EAAE,SAAS,GAAG,OAAO,GAAG,WAAW,CAAC;IACjD,qEAAqE;IACrE,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;CAC3B;AAED,yFAAyF;AACzF,MAAM,WAAW,WAAW;IAC1B,0DAA0D;IAC1D,QAAQ,CAAC,OAAO,EAAE,WAAW,CAAC,MAAM,EAAE,aAAa,CAAC,CAAC;IACrD,wDAAwD;IACxD,QAAQ,CAAC,MAAM,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;IACrC,0DAA0D;IAC1D,QAAQ,CAAC,QAAQ,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;CACxC;AAED,8EAA8E;AAC9E,MAAM,WAAW,KAAK;IACpB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,kEAAkE;IAClE,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,iEAAiE;IACjE,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAC5B,gFAAgF;IAChF,QAAQ,CAAC,aAAa,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAC3C,qFAAqF;IACrF,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;CACvB;AAED,wEAAwE;AACxE,MAAM,WAAW,SAAS;IACxB,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAC;IACxB,QAAQ,CAAC,KAAK,EAAE,KAAK,CAAC;CACvB;AAED,wEAAwE;AACxE,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;CACzB;AAED,MAAM,WAAW,UAAU;IACzB,QAAQ,CAAC,OAAO,EAAE,SAAS,KAAK,EAAE,CAAC;IACnC,oEAAoE;IACpE,QAAQ,CAAC,KAAK,EAAE,SAAS,SAAS,EAAE,CAAC;IACrC,QAAQ,CAAC,QAAQ,EAAE,SAAS,WAAW,EAAE,CAAC;IAC1C,oEAAoE;IACpE,QAAQ,CAAC,WAAW,EAAE,SAAS,UAAU,EAAE,CAAC;IAC5C,uFAAuF;IACvF,QAAQ,CAAC,aAAa,EAAE,WAAW,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACrD;AAED,MAAM,WAAW,UAAU;IACzB,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,IAAI,EAAE,SAAS,GAAG,OAAO,GAAG,WAAW,CAAC;IACjD,4DAA4D;IAC5D,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;CAC3B;AAmBD,qEAAqE;AACrE,wBAAgB,WAAW,CAAC,UAAU,EAAE,UAAU,GAAG,WAAW,CA8E/D;AAED;;;;;;;GAOG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,IAAI,GAAG,WAAW,CAAC,MAAM,CAAC,CAgB/D;AAkCD;;;;;;GAMG;AACH,wBAAgB,UAAU,CACxB,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,MAAM,EAChB,KAAK,EAAE,WAAW,CAAC,MAAM,CAAC,EAC1B,SAAS,CAAC,EAAE,MAAM,EAClB,YAAY,CAAC,EAAE,MAAM,GACpB,MAAM,CA0BR;AA4DD,MAAM,WAAW,SAAS;IACxB,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;IAC1B,QAAQ,CAAC,UAAU,EAAE,UAAU,CAAC;IAChC,oFAAoF;IACpF,QAAQ,CAAC,WAAW,CAAC,EAAE,UAAU,GAAG,SAAS,CAAC;IAC9C;;;;OAIG;IACH,QAAQ,CAAC,YAAY,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;CAC7C;AA4BD;;;;;;;;;;GAUG;AACH,wBAAgB,IAAI,CAAC,KAAK,EAAE,SAAS,GAAG,UAAU,CAyJjD;AAED,wFAAwF;AACxF,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAGlE;AAED,wBAAgB,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAG7C"}
|