@wp-tester/config 0.1.1 → 0.1.2

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.
Files changed (49) hide show
  1. package/dist/config-file.d.ts +6 -0
  2. package/dist/config-file.d.ts.map +1 -0
  3. package/dist/config-file.js +44 -0
  4. package/dist/config-file.js.map +1 -0
  5. package/dist/config.d.ts +0 -56
  6. package/dist/config.d.ts.map +1 -1
  7. package/dist/config.js +23 -345
  8. package/dist/config.js.map +1 -1
  9. package/dist/environment-resolver.d.ts +26 -0
  10. package/dist/environment-resolver.d.ts.map +1 -0
  11. package/dist/environment-resolver.js +131 -0
  12. package/dist/environment-resolver.js.map +1 -0
  13. package/dist/index.d.ts +7 -3
  14. package/dist/index.d.ts.map +1 -1
  15. package/dist/index.js +6 -2
  16. package/dist/index.js.map +1 -1
  17. package/dist/options/phpunit-detect.d.ts +13 -26
  18. package/dist/options/phpunit-detect.d.ts.map +1 -1
  19. package/dist/options/phpunit-detect.js +51 -32
  20. package/dist/options/phpunit-detect.js.map +1 -1
  21. package/dist/options/phpunit.d.ts.map +1 -1
  22. package/dist/options/phpunit.js +7 -11
  23. package/dist/options/phpunit.js.map +1 -1
  24. package/dist/options/project-root.js +1 -1
  25. package/dist/options/project-root.js.map +1 -1
  26. package/dist/options/project-type.js +1 -1
  27. package/dist/options/project-type.js.map +1 -1
  28. package/dist/options/smoke-tests.js +1 -1
  29. package/dist/options/smoke-tests.js.map +1 -1
  30. package/dist/path-mappers.d.ts +7 -7
  31. package/dist/path-mappers.d.ts.map +1 -1
  32. package/dist/path-mappers.js +10 -10
  33. package/dist/path-mappers.js.map +1 -1
  34. package/dist/path-utils.d.ts +62 -0
  35. package/dist/path-utils.d.ts.map +1 -0
  36. package/dist/path-utils.js +141 -0
  37. package/dist/path-utils.js.map +1 -0
  38. package/dist/resolved-types.d.ts +22 -7
  39. package/dist/resolved-types.d.ts.map +1 -1
  40. package/dist/test-resolver.d.ts +18 -0
  41. package/dist/test-resolver.d.ts.map +1 -0
  42. package/dist/test-resolver.js +107 -0
  43. package/dist/test-resolver.js.map +1 -0
  44. package/dist/tsconfig.tsbuildinfo +1 -1
  45. package/package.json +1 -1
  46. package/dist/phpunit.d.ts +0 -12
  47. package/dist/phpunit.d.ts.map +0 -1
  48. package/dist/phpunit.js +0 -58
  49. package/dist/phpunit.js.map +0 -1
@@ -3,30 +3,30 @@ import { relative, join } from "path";
3
3
  * Maps a host filesystem path to its corresponding VFS path in the playground
4
4
  *
5
5
  * @param hostPath - Absolute path on the host filesystem
6
- * @param config - Resolved config with projectHostPath and projectVFSPath
6
+ * @param projectPath - Resolved path with host and VFS mappings
7
7
  * @returns Corresponding VFS path in the playground
8
8
  *
9
9
  * @example
10
- * hostToVfs('/project/tests/bootstrap.php', resolvedConfig)
10
+ * hostToVfs('/project/tests/bootstrap.php', resolvedPath)
11
11
  * // Returns: '/wordpress/wp-content/plugins/my-plugin/tests/bootstrap.php'
12
12
  */
13
- export function hostToVfs(hostPath, config) {
14
- const relativePath = relative(config.projectHostPath, hostPath);
15
- return join(config.projectVFSPath, relativePath);
13
+ export function hostToVfs(hostPath, projectPath) {
14
+ const relativePath = relative(projectPath.hostPath, hostPath);
15
+ return join(projectPath.vfsPath, relativePath);
16
16
  }
17
17
  /**
18
18
  * Maps a VFS path in the playground to its corresponding host filesystem path
19
19
  *
20
20
  * @param vfsPath - Path in the playground VFS
21
- * @param config - Resolved config with projectHostPath and projectVFSPath
21
+ * @param projectPath - Resolved path with host and VFS mappings
22
22
  * @returns Corresponding absolute path on the host filesystem
23
23
  *
24
24
  * @example
25
- * vfsToHost('/wordpress/wp-content/plugins/my-plugin/tests/bootstrap.php', resolvedConfig)
25
+ * vfsToHost('/wordpress/wp-content/plugins/my-plugin/tests/bootstrap.php', resolvedPath)
26
26
  * // Returns: '/project/tests/bootstrap.php'
27
27
  */
28
- export function vfsToHost(vfsPath, config) {
29
- const relativePath = relative(config.projectVFSPath, vfsPath);
30
- return join(config.projectHostPath, relativePath);
28
+ export function vfsToHost(vfsPath, projectPath) {
29
+ const relativePath = relative(projectPath.vfsPath, vfsPath);
30
+ return join(projectPath.hostPath, relativePath);
31
31
  }
32
32
  //# sourceMappingURL=path-mappers.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"path-mappers.js","sourceRoot":"","sources":["../src/path-mappers.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAGtC;;;;;;;;;;GAUG;AACH,MAAM,UAAU,SAAS,CACvB,QAAgB,EAChB,MAA8B;IAE9B,MAAM,YAAY,GAAG,QAAQ,CAAC,MAAM,CAAC,eAAe,EAAE,QAAQ,CAAC,CAAC;IAChE,OAAO,IAAI,CAAC,MAAM,CAAC,cAAc,EAAE,YAAY,CAAC,CAAC;AACnD,CAAC;AAED;;;;;;;;;;GAUG;AACH,MAAM,UAAU,SAAS,CACvB,OAAe,EACf,MAA8B;IAE9B,MAAM,YAAY,GAAG,QAAQ,CAAC,MAAM,CAAC,cAAc,EAAE,OAAO,CAAC,CAAC;IAC9D,OAAO,IAAI,CAAC,MAAM,CAAC,eAAe,EAAE,YAAY,CAAC,CAAC;AACpD,CAAC"}
1
+ {"version":3,"file":"path-mappers.js","sourceRoot":"","sources":["../src/path-mappers.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAGtC;;;;;;;;;;GAUG;AACH,MAAM,UAAU,SAAS,CAAC,QAAgB,EAAE,WAAyB;IACnE,MAAM,YAAY,GAAG,QAAQ,CAAC,WAAW,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC;IAC9D,OAAO,IAAI,CAAC,WAAW,CAAC,OAAO,EAAE,YAAY,CAAC,CAAC;AACjD,CAAC;AAED;;;;;;;;;;GAUG;AACH,MAAM,UAAU,SAAS,CAAC,OAAe,EAAE,WAAyB;IAClE,MAAM,YAAY,GAAG,QAAQ,CAAC,WAAW,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;IAC5D,OAAO,IAAI,CAAC,WAAW,CAAC,QAAQ,EAAE,YAAY,CAAC,CAAC;AAClD,CAAC"}
@@ -0,0 +1,62 @@
1
+ import type { WPTesterConfig } from "./wp-tester-config.js";
2
+ import type { ResolvedPath } from "./resolved-types.js";
3
+ /**
4
+ * Get the actual working directory, accounting for tools like tsx that may change process.cwd()
5
+ * When running via npx or tsx, INIT_CWD contains the original directory where the command was invoked
6
+ */
7
+ export declare function getWorkingDirectory(): string;
8
+ /**
9
+ * Resolve a path to an absolute path.
10
+ * If the path is already absolute, return it as-is.
11
+ * Otherwise, resolve it relative to the base directory.
12
+ *
13
+ * @param path - Path to resolve (relative or absolute)
14
+ * @param baseDir - Base directory to resolve relative paths from
15
+ * @returns Absolute path
16
+ */
17
+ export declare function resolveAbsolute(path: string, baseDir: string): string;
18
+ export declare function configPath(): string;
19
+ export declare function getSchemaPath(importMetaUrl?: string): string;
20
+ /**
21
+ * Get the absolute config file path.
22
+ *
23
+ * @param config - Path to config file (relative or absolute)
24
+ * @returns Absolute path to the config file
25
+ */
26
+ export declare function getConfigPath(config: string): string;
27
+ /**
28
+ * Normalize a config path to ensure it points to a file, not a directory.
29
+ * If the path is a directory, appends 'wp-tester.json' to it.
30
+ * Used by readConfigFile, resolveConfig, and the test watcher to handle
31
+ * directory paths passed via --config flag.
32
+ *
33
+ * @param configPath - Path to config file or directory (relative or absolute)
34
+ * @returns Absolute path to the config file
35
+ */
36
+ export declare function normalizeConfigPath(configPath: string): string;
37
+ /**
38
+ * Get the config file directory path.
39
+ *
40
+ * @param configPath - Path to config file
41
+ * @returns Directory path where the config file is located
42
+ */
43
+ export declare function getConfigDir(configPath: string): string;
44
+ /**
45
+ * Get the project root directory path.
46
+ *
47
+ * Returns config.projectHostPath if specified (resolved relative to config file or as absolute),
48
+ * otherwise returns the config file's directory.
49
+ *
50
+ * @param config - Config object
51
+ * @param configPath - Optional path to config file (needed to resolve relative projectHostPath)
52
+ * @returns Absolute path to the project root directory
53
+ */
54
+ export declare function getProjectDir(config: WPTesterConfig, configPath?: string): string;
55
+ /**
56
+ * Convert a host path to a ResolvedPath using the project path mapping
57
+ * @param hostPath - Absolute path on host
58
+ * @param projectPath - Project path mapping
59
+ * @returns ResolvedPath with both host and VFS paths
60
+ */
61
+ export declare function toResolvedPath(hostPath: string, projectPath: ResolvedPath): ResolvedPath;
62
+ //# sourceMappingURL=path-utils.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"path-utils.d.ts","sourceRoot":"","sources":["../src/path-utils.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AACzD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAMrD;;;GAGG;AACH,wBAAgB,mBAAmB,IAAI,MAAM,CAE5C;AAED;;;;;;;;GAQG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,MAAM,CAErE;AAED,wBAAgB,UAAU,IAAI,MAAM,CAEnC;AAED,wBAAgB,aAAa,CAAC,aAAa,CAAC,EAAE,MAAM,GAAG,MAAM,CAoC5D;AAED;;;;;GAKG;AACH,wBAAgB,aAAa,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAWpD;AAED;;;;;;;;GAQG;AACH,wBAAgB,mBAAmB,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,CAc9D;AAED;;;;;GAKG;AACH,wBAAgB,YAAY,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,CAEvD;AAED;;;;;;;;;GASG;AACH,wBAAgB,aAAa,CAC3B,MAAM,EAAE,cAAc,EACtB,UAAU,CAAC,EAAE,MAAM,GAClB,MAAM,CAWR;AAED;;;;;GAKG;AACH,wBAAgB,cAAc,CAAC,QAAQ,EAAE,MAAM,EAAE,WAAW,EAAE,YAAY,GAAG,YAAY,CAKxF"}
@@ -0,0 +1,141 @@
1
+ import { existsSync, statSync } from "fs";
2
+ import { join, dirname, resolve, isAbsolute } from "path";
3
+ import { fileURLToPath } from "url";
4
+ import { hostToVfs } from './path-mappers.js';
5
+ /**
6
+ * Get the actual working directory, accounting for tools like tsx that may change process.cwd()
7
+ * When running via npx or tsx, INIT_CWD contains the original directory where the command was invoked
8
+ */
9
+ export function getWorkingDirectory() {
10
+ return process.env.INIT_CWD || process.cwd();
11
+ }
12
+ /**
13
+ * Resolve a path to an absolute path.
14
+ * If the path is already absolute, return it as-is.
15
+ * Otherwise, resolve it relative to the base directory.
16
+ *
17
+ * @param path - Path to resolve (relative or absolute)
18
+ * @param baseDir - Base directory to resolve relative paths from
19
+ * @returns Absolute path
20
+ */
21
+ export function resolveAbsolute(path, baseDir) {
22
+ return isAbsolute(path) ? path : resolve(baseDir, path);
23
+ }
24
+ export function configPath() {
25
+ return join(getWorkingDirectory(), "wp-tester.json");
26
+ }
27
+ export function getSchemaPath(importMetaUrl) {
28
+ // For ESM in production (built files) - use import.meta.url from this module
29
+ // This works when the package is installed via npm or run via npx
30
+ const metaUrl = importMetaUrl || import.meta.url;
31
+ if (metaUrl) {
32
+ const currentDir = dirname(fileURLToPath(metaUrl));
33
+ const schemaPath = join(currentDir, "schema.json");
34
+ if (existsSync(schemaPath)) {
35
+ return schemaPath;
36
+ }
37
+ }
38
+ // For CommonJS (built files)
39
+ if (typeof __dirname !== "undefined") {
40
+ return join(__dirname, "schema.json");
41
+ }
42
+ // For dev mode: try to find the config package
43
+ // Could be in monorepo (packages/config) or installed (node_modules)
44
+ const candidates = [
45
+ // Monorepo from root
46
+ join(process.cwd(), "packages/config/src/schema.json"),
47
+ // Monorepo from a package directory
48
+ join(process.cwd(), "../config/src/schema.json"),
49
+ // Installed package
50
+ join(process.cwd(), "node_modules/@wp-tester/config/dist/schema.json"),
51
+ ];
52
+ for (const candidate of candidates) {
53
+ if (existsSync(candidate)) {
54
+ return candidate;
55
+ }
56
+ }
57
+ // Last resort
58
+ return candidates[candidates.length - 1];
59
+ }
60
+ /**
61
+ * Get the absolute config file path.
62
+ *
63
+ * @param config - Path to config file (relative or absolute)
64
+ * @returns Absolute path to the config file
65
+ */
66
+ export function getConfigPath(config) {
67
+ // Expand tilde (~) to home directory
68
+ if (config.startsWith('~/') || config === '~') {
69
+ const homeDir = process.env.HOME || process.env.USERPROFILE;
70
+ if (!homeDir) {
71
+ throw new Error('Unable to resolve home directory');
72
+ }
73
+ config = config === '~' ? homeDir : join(homeDir, config.slice(2));
74
+ }
75
+ return isAbsolute(config) ? config : resolve(getWorkingDirectory(), config);
76
+ }
77
+ /**
78
+ * Normalize a config path to ensure it points to a file, not a directory.
79
+ * If the path is a directory, appends 'wp-tester.json' to it.
80
+ * Used by readConfigFile, resolveConfig, and the test watcher to handle
81
+ * directory paths passed via --config flag.
82
+ *
83
+ * @param configPath - Path to config file or directory (relative or absolute)
84
+ * @returns Absolute path to the config file
85
+ */
86
+ export function normalizeConfigPath(configPath) {
87
+ const absolutePath = getConfigPath(configPath);
88
+ // Check if path is a directory (synchronous)
89
+ try {
90
+ const stats = statSync(absolutePath);
91
+ if (stats.isDirectory()) {
92
+ return join(absolutePath, 'wp-tester.json');
93
+ }
94
+ }
95
+ catch {
96
+ // If stat fails, assume it's a file path
97
+ }
98
+ return absolutePath;
99
+ }
100
+ /**
101
+ * Get the config file directory path.
102
+ *
103
+ * @param configPath - Path to config file
104
+ * @returns Directory path where the config file is located
105
+ */
106
+ export function getConfigDir(configPath) {
107
+ return dirname(getConfigPath(configPath));
108
+ }
109
+ /**
110
+ * Get the project root directory path.
111
+ *
112
+ * Returns config.projectHostPath if specified (resolved relative to config file or as absolute),
113
+ * otherwise returns the config file's directory.
114
+ *
115
+ * @param config - Config object
116
+ * @param configPath - Optional path to config file (needed to resolve relative projectHostPath)
117
+ * @returns Absolute path to the project root directory
118
+ */
119
+ export function getProjectDir(config, configPath) {
120
+ // Get base directory: config file location or cwd
121
+ const baseDir = configPath ? getConfigDir(configPath) : getWorkingDirectory();
122
+ // If projectHostPath is specified, resolve it relative to base directory
123
+ if (config.projectHostPath) {
124
+ return resolveAbsolute(config.projectHostPath, baseDir);
125
+ }
126
+ // No projectHostPath specified, return base directory
127
+ return baseDir;
128
+ }
129
+ /**
130
+ * Convert a host path to a ResolvedPath using the project path mapping
131
+ * @param hostPath - Absolute path on host
132
+ * @param projectPath - Project path mapping
133
+ * @returns ResolvedPath with both host and VFS paths
134
+ */
135
+ export function toResolvedPath(hostPath, projectPath) {
136
+ return {
137
+ hostPath,
138
+ vfsPath: hostToVfs(hostPath, projectPath),
139
+ };
140
+ }
141
+ //# sourceMappingURL=path-utils.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"path-utils.js","sourceRoot":"","sources":["../src/path-utils.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,IAAI,CAAC;AAC1C,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,OAAO,EAAE,UAAU,EAAE,MAAM,MAAM,CAAC;AAC1D,OAAO,EAAE,aAAa,EAAE,MAAM,KAAK,CAAC;AACpC,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAE3C;;;GAGG;AACH,MAAM,UAAU,mBAAmB;IACjC,OAAO,OAAO,CAAC,GAAG,CAAC,QAAQ,IAAI,OAAO,CAAC,GAAG,EAAE,CAAC;AAC/C,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,UAAU,eAAe,CAAC,IAAY,EAAE,OAAe;IAC3D,OAAO,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,OAAO,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC;AAC1D,CAAC;AAED,MAAM,UAAU,UAAU;IACxB,OAAO,IAAI,CAAC,mBAAmB,EAAE,EAAE,gBAAgB,CAAC,CAAC;AACvD,CAAC;AAED,MAAM,UAAU,aAAa,CAAC,aAAsB;IAClD,6EAA6E;IAC7E,kEAAkE;IAClE,MAAM,OAAO,GAAG,aAAa,IAAI,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC;IACjD,IAAI,OAAO,EAAE,CAAC;QACZ,MAAM,UAAU,GAAG,OAAO,CAAC,aAAa,CAAC,OAAO,CAAC,CAAC,CAAC;QACnD,MAAM,UAAU,GAAG,IAAI,CAAC,UAAU,EAAE,aAAa,CAAC,CAAC;QACnD,IAAI,UAAU,CAAC,UAAU,CAAC,EAAE,CAAC;YAC3B,OAAO,UAAU,CAAC;QACpB,CAAC;IACH,CAAC;IAED,6BAA6B;IAC7B,IAAI,OAAO,SAAS,KAAK,WAAW,EAAE,CAAC;QACrC,OAAO,IAAI,CAAC,SAAS,EAAE,aAAa,CAAC,CAAC;IACxC,CAAC;IAED,+CAA+C;IAC/C,qEAAqE;IACrE,MAAM,UAAU,GAAG;QACjB,qBAAqB;QACrB,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,iCAAiC,CAAC;QACtD,oCAAoC;QACpC,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,2BAA2B,CAAC;QAChD,oBAAoB;QACpB,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,iDAAiD,CAAC;KACvE,CAAC;IAEF,KAAK,MAAM,SAAS,IAAI,UAAU,EAAE,CAAC;QACnC,IAAI,UAAU,CAAC,SAAS,CAAC,EAAE,CAAC;YAC1B,OAAO,SAAS,CAAC;QACnB,CAAC;IACH,CAAC;IAED,cAAc;IACd,OAAO,UAAU,CAAC,UAAU,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;AAC3C,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,aAAa,CAAC,MAAc;IAC1C,qCAAqC;IACrC,IAAI,MAAM,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,MAAM,KAAK,GAAG,EAAE,CAAC;QAC9C,MAAM,OAAO,GAAG,OAAO,CAAC,GAAG,CAAC,IAAI,IAAI,OAAO,CAAC,GAAG,CAAC,WAAW,CAAC;QAC5D,IAAI,CAAC,OAAO,EAAE,CAAC;YACb,MAAM,IAAI,KAAK,CAAC,kCAAkC,CAAC,CAAC;QACtD,CAAC;QACD,MAAM,GAAG,MAAM,KAAK,GAAG,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,EAAE,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;IACrE,CAAC;IAED,OAAO,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,OAAO,CAAC,mBAAmB,EAAE,EAAE,MAAM,CAAC,CAAC;AAC9E,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,UAAU,mBAAmB,CAAC,UAAkB;IACpD,MAAM,YAAY,GAAG,aAAa,CAAC,UAAU,CAAC,CAAC;IAE/C,6CAA6C;IAC7C,IAAI,CAAC;QACH,MAAM,KAAK,GAAG,QAAQ,CAAC,YAAY,CAAC,CAAC;QACrC,IAAI,KAAK,CAAC,WAAW,EAAE,EAAE,CAAC;YACxB,OAAO,IAAI,CAAC,YAAY,EAAE,gBAAgB,CAAC,CAAC;QAC9C,CAAC;IACH,CAAC;IAAC,MAAM,CAAC;QACP,yCAAyC;IAC3C,CAAC;IAED,OAAO,YAAY,CAAC;AACtB,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,YAAY,CAAC,UAAkB;IAC7C,OAAO,OAAO,CAAC,aAAa,CAAC,UAAU,CAAC,CAAC,CAAC;AAC5C,CAAC;AAED;;;;;;;;;GASG;AACH,MAAM,UAAU,aAAa,CAC3B,MAAsB,EACtB,UAAmB;IAEnB,kDAAkD;IAClD,MAAM,OAAO,GAAG,UAAU,CAAC,CAAC,CAAC,YAAY,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,mBAAmB,EAAE,CAAC;IAE9E,yEAAyE;IACzE,IAAI,MAAM,CAAC,eAAe,EAAE,CAAC;QAC3B,OAAO,eAAe,CAAC,MAAM,CAAC,eAAe,EAAE,OAAO,CAAC,CAAC;IAC1D,CAAC;IAED,sDAAsD;IACtD,OAAO,OAAO,CAAC;AACjB,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,cAAc,CAAC,QAAgB,EAAE,WAAyB;IACxE,OAAO;QACL,QAAQ;QACR,OAAO,EAAE,SAAS,CAAC,QAAQ,EAAE,WAAW,CAAC;KAC1C,CAAC;AACJ,CAAC"}
@@ -1,5 +1,5 @@
1
1
  import type { BlueprintV1Declaration } from "@wp-playground/blueprints";
2
- import type { Mount, PHPUnitConfig, Tests, Environment, WPTesterConfig, TestMode, ProjectType, BaseReporterOptions, JsonReporterOptions } from "./wp-tester-config.js";
2
+ import type { Mount, Tests, Environment, WPTesterConfig, TestMode, ProjectType, BaseReporterOptions, JsonReporterOptions } from "./wp-tester-config.js";
3
3
  /**
4
4
  * Resolved reporters configuration.
5
5
  * Supports boolean shorthand for default reporter (true = enable with defaults).
@@ -11,11 +11,19 @@ export interface ResolvedReporters {
11
11
  json?: JsonReporterOptions;
12
12
  }
13
13
  /**
14
- * Resolved PHPUnit configuration with absolute paths and required testMode.
14
+ * Resolved PHPUnit configuration with resolved paths and required testMode.
15
15
  */
16
- export interface ResolvedPHPUnitConfig extends Omit<PHPUnitConfig, 'testMode'> {
16
+ export interface ResolvedPHPUnitConfig {
17
+ /** Path to PHPUnit executable with host and VFS paths */
18
+ phpunitPath: ResolvedPath;
19
+ /** Path to PHPUnit configuration file with host and VFS paths */
20
+ configPath: ResolvedPath;
21
+ /** Path to PHPUnit bootstrap file with host and VFS paths */
22
+ bootstrapPath?: ResolvedPath;
17
23
  /** Test mode (always defined after resolution, defaults to "unit") */
18
24
  testMode: TestMode;
25
+ /** Additional arguments to pass to PHPUnit */
26
+ phpunitArgs?: string[];
19
27
  }
20
28
  /**
21
29
  * Resolved test configuration with resolved PHPUnit config.
@@ -25,6 +33,15 @@ export interface ResolvedTests extends Omit<Tests, 'phpunit'> {
25
33
  /** Allow the test suite to pass when no tests are executed */
26
34
  passWithNoTests?: boolean;
27
35
  }
36
+ /**
37
+ * Resolved path type with a host and VFS path.
38
+ */
39
+ export interface ResolvedPath {
40
+ /** Absolute path on host system */
41
+ hostPath: string;
42
+ /** Absolute path in VFS */
43
+ vfsPath: string;
44
+ }
28
45
  /**
29
46
  * Resolved blueprint with guaranteed preferredVersions.
30
47
  */
@@ -49,10 +66,8 @@ export interface ResolvedEnvironment extends Omit<Environment, 'blueprint' | 'mo
49
66
  * Resolved config with all paths absolute and optional fields set.
50
67
  */
51
68
  export interface ResolvedWPTesterConfig extends Omit<WPTesterConfig, 'projectHostPath' | 'projectVFSPath' | 'projectType' | 'reporters' | 'environments' | 'tests'> {
52
- /** Absolute path to project on host (always defined after resolution) */
53
- projectHostPath: string;
54
- /** VFS path determined by project type or explicit config (always defined after resolution) */
55
- projectVFSPath: string;
69
+ /** Resolved project path with both host and VFS paths */
70
+ projectPath: ResolvedPath;
56
71
  /** Project type (always defined after resolution) */
57
72
  projectType: ProjectType;
58
73
  /** Resolved environments with loaded blueprints */
@@ -1 +1 @@
1
- {"version":3,"file":"resolved-types.d.ts","sourceRoot":"","sources":["../src/resolved-types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,2BAA2B,CAAC;AACxE,OAAO,KAAK,EAAE,KAAK,EAAE,aAAa,EAAE,KAAK,EAAE,WAAW,EAAE,cAAc,EAAE,QAAQ,EAAE,WAAW,EAAE,mBAAmB,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AAEpK;;;GAGG;AACH,MAAM,WAAW,iBAAiB;IAChC,yFAAyF;IACzF,OAAO,CAAC,EAAE,OAAO,GAAG,mBAAmB,CAAC;IACxC,4BAA4B;IAC5B,IAAI,CAAC,EAAE,mBAAmB,CAAC;CAC5B;AAED;;GAEG;AACH,MAAM,WAAW,qBAAsB,SAAQ,IAAI,CAAC,aAAa,EAAE,UAAU,CAAC;IAC5E,sEAAsE;IACtE,QAAQ,EAAE,QAAQ,CAAC;CACpB;AAED;;GAEG;AACH,MAAM,WAAW,aAAc,SAAQ,IAAI,CAAC,KAAK,EAAE,SAAS,CAAC;IAC3D,OAAO,CAAC,EAAE,qBAAqB,CAAC;IAChC,8DAA8D;IAC9D,eAAe,CAAC,EAAE,OAAO,CAAC;CAC3B;AAED;;GAEG;AACH,MAAM,WAAW,iBAAkB,SAAQ,IAAI,CAAC,sBAAsB,EAAE,mBAAmB,CAAC;IAC1F,iFAAiF;IACjF,iBAAiB,EAAE,QAAQ,CAAC,WAAW,CAAC,sBAAsB,CAAC,mBAAmB,CAAC,CAAC,CAAC,CAAC;CACvF;AAED;;GAEG;AACH,MAAM,WAAW,mBAAoB,SAAQ,IAAI,CAAC,WAAW,EAAE,WAAW,GAAG,QAAQ,GAAG,KAAK,GAAG,MAAM,CAAC;IACrG,6FAA6F;IAC7F,SAAS,EAAE,iBAAiB,CAAC;IAC7B,kDAAkD;IAClD,MAAM,EAAE,KAAK,EAAE,CAAC;IAChB,2DAA2D;IAC3D,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC5B,sGAAsG;IACtG,IAAI,EAAE,OAAO,CAAC;CACf;AAED;;GAEG;AACH,MAAM,WAAW,sBAAuB,SAAQ,IAAI,CAAC,cAAc,EAAE,iBAAiB,GAAG,gBAAgB,GAAG,aAAa,GAAG,WAAW,GAAG,cAAc,GAAG,OAAO,CAAC;IACjK,yEAAyE;IACzE,eAAe,EAAE,MAAM,CAAC;IACxB,+FAA+F;IAC/F,cAAc,EAAE,MAAM,CAAC;IACvB,qDAAqD;IACrD,WAAW,EAAE,WAAW,CAAC;IACzB,mDAAmD;IACnD,YAAY,EAAE,mBAAmB,EAAE,CAAC;IACpC,sDAAsD;IACtD,KAAK,EAAE,aAAa,CAAC;IACrB,sFAAsF;IACtF,SAAS,EAAE,iBAAiB,CAAC;CAC9B"}
1
+ {"version":3,"file":"resolved-types.d.ts","sourceRoot":"","sources":["../src/resolved-types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,2BAA2B,CAAC;AACxE,OAAO,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,WAAW,EAAE,cAAc,EAAE,QAAQ,EAAE,WAAW,EAAE,mBAAmB,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AAErJ;;;GAGG;AACH,MAAM,WAAW,iBAAiB;IAChC,yFAAyF;IACzF,OAAO,CAAC,EAAE,OAAO,GAAG,mBAAmB,CAAC;IACxC,4BAA4B;IAC5B,IAAI,CAAC,EAAE,mBAAmB,CAAC;CAC5B;AAED;;GAEG;AACH,MAAM,WAAW,qBAAqB;IACpC,yDAAyD;IACzD,WAAW,EAAE,YAAY,CAAC;IAC1B,iEAAiE;IACjE,UAAU,EAAE,YAAY,CAAC;IACzB,6DAA6D;IAC7D,aAAa,CAAC,EAAE,YAAY,CAAC;IAC7B,sEAAsE;IACtE,QAAQ,EAAE,QAAQ,CAAC;IACnB,8CAA8C;IAC9C,WAAW,CAAC,EAAE,MAAM,EAAE,CAAC;CACxB;AAED;;GAEG;AACH,MAAM,WAAW,aAAc,SAAQ,IAAI,CAAC,KAAK,EAAE,SAAS,CAAC;IAC3D,OAAO,CAAC,EAAE,qBAAqB,CAAC;IAChC,8DAA8D;IAC9D,eAAe,CAAC,EAAE,OAAO,CAAC;CAC3B;AAED;;GAEG;AACH,MAAM,WAAW,YAAY;IAC3B,mCAAmC;IACnC,QAAQ,EAAE,MAAM,CAAC;IACjB,2BAA2B;IAC3B,OAAO,EAAE,MAAM,CAAC;CACjB;AAED;;GAEG;AACH,MAAM,WAAW,iBAAkB,SAAQ,IAAI,CAAC,sBAAsB,EAAE,mBAAmB,CAAC;IAC1F,iFAAiF;IACjF,iBAAiB,EAAE,QAAQ,CAAC,WAAW,CAAC,sBAAsB,CAAC,mBAAmB,CAAC,CAAC,CAAC,CAAC;CACvF;AAED;;GAEG;AACH,MAAM,WAAW,mBAAoB,SAAQ,IAAI,CAAC,WAAW,EAAE,WAAW,GAAG,QAAQ,GAAG,KAAK,GAAG,MAAM,CAAC;IACrG,6FAA6F;IAC7F,SAAS,EAAE,iBAAiB,CAAC;IAC7B,kDAAkD;IAClD,MAAM,EAAE,KAAK,EAAE,CAAC;IAChB,2DAA2D;IAC3D,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC5B,sGAAsG;IACtG,IAAI,EAAE,OAAO,CAAC;CACf;AAED;;GAEG;AACH,MAAM,WAAW,sBAAuB,SAAQ,IAAI,CAAC,cAAc,EAAE,iBAAiB,GAAG,gBAAgB,GAAG,aAAa,GAAG,WAAW,GAAG,cAAc,GAAG,OAAO,CAAC;IACjK,yDAAyD;IACzD,WAAW,EAAE,YAAY,CAAC;IAC1B,qDAAqD;IACrD,WAAW,EAAE,WAAW,CAAC;IACzB,mDAAmD;IACnD,YAAY,EAAE,mBAAmB,EAAE,CAAC;IACpC,sDAAsD;IACtD,KAAK,EAAE,aAAa,CAAC;IACrB,sFAAsF;IACtF,SAAS,EAAE,iBAAiB,CAAC;CAC9B"}
@@ -0,0 +1,18 @@
1
+ import type { Tests } from "./wp-tester-config.js";
2
+ import type { ResolvedTests, ResolvedPath } from "./resolved-types.js";
3
+ /**
4
+ * Resolve PHPUnit arguments to map host paths to VFS paths
5
+ *
6
+ * @param args - Original arguments from config
7
+ * @param projectPath - Project path with host and VFS paths
8
+ * @returns Resolved arguments with paths converted to VFS paths
9
+ */
10
+ export declare function resolvePhpunitArgs(args: string[], projectPath: ResolvedPath): string[];
11
+ /**
12
+ * Resolve PHPUnit config paths and set default testMode
13
+ * @param tests - Tests configuration
14
+ * @param projectPath - Project path with host and VFS paths
15
+ * @returns Resolved tests configuration
16
+ */
17
+ export declare function resolveTests(tests: Tests, projectPath: ResolvedPath): Promise<ResolvedTests>;
18
+ //# sourceMappingURL=test-resolver.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"test-resolver.d.ts","sourceRoot":"","sources":["../src/test-resolver.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,oBAAoB,CAAC;AAChD,OAAO,KAAK,EAAE,aAAa,EAAyB,YAAY,EAAE,MAAM,kBAAkB,CAAC;AA8B3F;;;;;;GAMG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,WAAW,EAAE,YAAY,GAAG,MAAM,EAAE,CAuCtF;AAED;;;;;GAKG;AACH,wBAAsB,YAAY,CAAC,KAAK,EAAE,KAAK,EAAE,WAAW,EAAE,YAAY,GAAG,OAAO,CAAC,aAAa,CAAC,CAyClG"}
@@ -0,0 +1,107 @@
1
+ import { resolveAbsolute, toResolvedPath } from "./path-utils.js";
2
+ import { resolveBootstrapPath } from './options/phpunit-detect.js';
3
+ import { hostToVfs } from './path-mappers.js';
4
+ /**
5
+ * PHPUnit flags that are boolean (do not take a value).
6
+ * If a flag is NOT in this list, we assume it takes a value,
7
+ * and therefore the next argument should NOT be resolved as a path.
8
+ */
9
+ const PHPUNIT_BOOLEAN_FLAGS = new Set([
10
+ '--teamcity', '--debug', '--verbose', '--testdox',
11
+ '--stderr', '--stop-on-error', '--stop-on-failure', '--stop-on-warning',
12
+ '--stop-on-defect', '--stop-on-risky', '--stop-on-skipped', '--stop-on-incomplete',
13
+ '--stop-on-deprecation', '--stop-on-notice',
14
+ '--fail-on-warning', '--fail-on-risky', '--fail-on-incomplete', '--fail-on-skipped',
15
+ '--fail-on-deprecation', '--fail-on-notice',
16
+ '--strict-coverage', '--strict-global-state', '--disallow-test-output',
17
+ '--disallow-resource-usage', '--enforce-time-limit',
18
+ '--process-isolation', '--no-globals-backup', '--static-backup',
19
+ '--no-configuration', '--no-coverage', '--no-logging', '--no-interaction',
20
+ '--no-extensions', '--no-output', '--dont-report-useless-tests',
21
+ '--no-progress',
22
+ '--display-deprecations', '--display-errors', '--display-incomplete',
23
+ '--display-notices', '--display-skipped', '--display-warnings',
24
+ '--strict',
25
+ '--help', '--version',
26
+ '--list-groups', '--list-suites', '--list-tests', '--list-tests-xml',
27
+ ]);
28
+ /**
29
+ * Resolve PHPUnit arguments to map host paths to VFS paths
30
+ *
31
+ * @param args - Original arguments from config
32
+ * @param projectPath - Project path with host and VFS paths
33
+ * @returns Resolved arguments with paths converted to VFS paths
34
+ */
35
+ export function resolvePhpunitArgs(args, projectPath) {
36
+ const resolvedArgs = [];
37
+ for (let i = 0; i < args.length; i++) {
38
+ const arg = args[i];
39
+ // Don't resolve flags
40
+ if (arg.startsWith('-')) {
41
+ resolvedArgs.push(arg);
42
+ continue;
43
+ }
44
+ // Check if the previous argument was a flag that takes a value
45
+ const prevArg = args[i - 1];
46
+ if (prevArg?.startsWith('-') && !prevArg.includes('=')) {
47
+ // If the previous flag is NOT a known boolean flag, assume it takes a value
48
+ const flagName = prevArg.split('=')[0];
49
+ if (!PHPUNIT_BOOLEAN_FLAGS.has(flagName)) {
50
+ resolvedArgs.push(arg); // This is the flag's value, not a path
51
+ continue;
52
+ }
53
+ }
54
+ // Resolve arguments that look like file/directory paths
55
+ const looksLikePath = arg.includes('/') ||
56
+ arg.endsWith('.php') ||
57
+ arg === 'tests' || arg === 'test';
58
+ if (looksLikePath) {
59
+ const absoluteHostPath = resolveAbsolute(arg, projectPath.hostPath);
60
+ const vfsPath = hostToVfs(absoluteHostPath, projectPath);
61
+ resolvedArgs.push(vfsPath);
62
+ continue;
63
+ }
64
+ resolvedArgs.push(arg);
65
+ }
66
+ return resolvedArgs;
67
+ }
68
+ /**
69
+ * Resolve PHPUnit config paths and set default testMode
70
+ * @param tests - Tests configuration
71
+ * @param projectPath - Project path with host and VFS paths
72
+ * @returns Resolved tests configuration
73
+ */
74
+ export async function resolveTests(tests, projectPath) {
75
+ // If no PHPUnit config, return tests as-is (but explicitly typed)
76
+ if (!tests.phpunit) {
77
+ return {
78
+ plugin: tests.plugin,
79
+ theme: tests.theme,
80
+ wp: tests.wp,
81
+ passWithNoTests: tests.passWithNoTests,
82
+ };
83
+ }
84
+ // Resolve PHPUnit config with absolute paths and default testMode
85
+ const phpunit = tests.phpunit;
86
+ const resolvedConfigHostPath = resolveAbsolute(phpunit.configPath, projectPath.hostPath);
87
+ // Resolve bootstrap path using centralized logic
88
+ const bootstrapHostPath = await resolveBootstrapPath(resolvedConfigHostPath, projectPath.hostPath, phpunit.bootstrapPath);
89
+ const resolvedPhpunit = {
90
+ phpunitPath: toResolvedPath(resolveAbsolute(phpunit.phpunitPath, projectPath.hostPath), projectPath),
91
+ configPath: toResolvedPath(resolvedConfigHostPath, projectPath),
92
+ testMode: phpunit.testMode ?? "unit",
93
+ bootstrapPath: bootstrapHostPath ? toResolvedPath(bootstrapHostPath, projectPath) : undefined,
94
+ };
95
+ // Resolve phpunitArgs paths if present
96
+ if (phpunit.phpunitArgs) {
97
+ resolvedPhpunit.phpunitArgs = resolvePhpunitArgs(phpunit.phpunitArgs, projectPath);
98
+ }
99
+ return {
100
+ plugin: tests.plugin,
101
+ theme: tests.theme,
102
+ wp: tests.wp,
103
+ phpunit: resolvedPhpunit,
104
+ passWithNoTests: tests.passWithNoTests,
105
+ };
106
+ }
107
+ //# sourceMappingURL=test-resolver.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"test-resolver.js","sourceRoot":"","sources":["../src/test-resolver.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAC/D,OAAO,EAAE,oBAAoB,EAAE,MAAM,0BAA0B,CAAC;AAChE,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAE3C;;;;GAIG;AACH,MAAM,qBAAqB,GAAG,IAAI,GAAG,CAAC;IACpC,YAAY,EAAE,SAAS,EAAE,WAAW,EAAE,WAAW;IACjD,UAAU,EAAE,iBAAiB,EAAE,mBAAmB,EAAE,mBAAmB;IACvE,kBAAkB,EAAE,iBAAiB,EAAE,mBAAmB,EAAE,sBAAsB;IAClF,uBAAuB,EAAE,kBAAkB;IAC3C,mBAAmB,EAAE,iBAAiB,EAAE,sBAAsB,EAAE,mBAAmB;IACnF,uBAAuB,EAAE,kBAAkB;IAC3C,mBAAmB,EAAE,uBAAuB,EAAE,wBAAwB;IACtE,2BAA2B,EAAE,sBAAsB;IACnD,qBAAqB,EAAE,qBAAqB,EAAE,iBAAiB;IAC/D,oBAAoB,EAAE,eAAe,EAAE,cAAc,EAAE,kBAAkB;IACzE,iBAAiB,EAAE,aAAa,EAAE,6BAA6B;IAC/D,eAAe;IACf,wBAAwB,EAAE,kBAAkB,EAAE,sBAAsB;IACpE,mBAAmB,EAAE,mBAAmB,EAAE,oBAAoB;IAC9D,UAAU;IACV,QAAQ,EAAE,WAAW;IACrB,eAAe,EAAE,eAAe,EAAE,cAAc,EAAE,kBAAkB;CACrE,CAAC,CAAC;AAEH;;;;;;GAMG;AACH,MAAM,UAAU,kBAAkB,CAAC,IAAc,EAAE,WAAyB;IAC1E,MAAM,YAAY,GAAa,EAAE,CAAC;IAElC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACrC,MAAM,GAAG,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;QAEpB,sBAAsB;QACtB,IAAI,GAAG,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;YACxB,YAAY,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;YACvB,SAAS;QACX,CAAC;QAED,+DAA+D;QAC/D,MAAM,OAAO,GAAG,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;QAC5B,IAAI,OAAO,EAAE,UAAU,CAAC,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC;YACvD,4EAA4E;YAC5E,MAAM,QAAQ,GAAG,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;YACvC,IAAI,CAAC,qBAAqB,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,CAAC;gBACzC,YAAY,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,uCAAuC;gBAC/D,SAAS;YACX,CAAC;QACH,CAAC;QAED,wDAAwD;QACxD,MAAM,aAAa,GAAG,GAAG,CAAC,QAAQ,CAAC,GAAG,CAAC;YACjB,GAAG,CAAC,QAAQ,CAAC,MAAM,CAAC;YACpB,GAAG,KAAK,OAAO,IAAI,GAAG,KAAK,MAAM,CAAC;QAExD,IAAI,aAAa,EAAE,CAAC;YAClB,MAAM,gBAAgB,GAAG,eAAe,CAAC,GAAG,EAAE,WAAW,CAAC,QAAQ,CAAC,CAAC;YACpE,MAAM,OAAO,GAAG,SAAS,CAAC,gBAAgB,EAAE,WAAW,CAAC,CAAC;YACzD,YAAY,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;YAC3B,SAAS;QACX,CAAC;QAED,YAAY,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IACzB,CAAC;IAED,OAAO,YAAY,CAAC;AACtB,CAAC;AAED;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,YAAY,CAAC,KAAY,EAAE,WAAyB;IACxE,kEAAkE;IAClE,IAAI,CAAC,KAAK,CAAC,OAAO,EAAE,CAAC;QACnB,OAAO;YACL,MAAM,EAAE,KAAK,CAAC,MAAM;YACpB,KAAK,EAAE,KAAK,CAAC,KAAK;YAClB,EAAE,EAAE,KAAK,CAAC,EAAE;YACZ,eAAe,EAAE,KAAK,CAAC,eAAe;SACvC,CAAC;IACJ,CAAC;IAED,kEAAkE;IAClE,MAAM,OAAO,GAAG,KAAK,CAAC,OAAO,CAAC;IAC9B,MAAM,sBAAsB,GAAG,eAAe,CAAC,OAAO,CAAC,UAAU,EAAE,WAAW,CAAC,QAAQ,CAAC,CAAC;IAEzF,iDAAiD;IACjD,MAAM,iBAAiB,GAAG,MAAM,oBAAoB,CAClD,sBAAsB,EACtB,WAAW,CAAC,QAAQ,EACpB,OAAO,CAAC,aAAa,CACtB,CAAC;IAEF,MAAM,eAAe,GAA0B;QAC7C,WAAW,EAAE,cAAc,CAAC,eAAe,CAAC,OAAO,CAAC,WAAW,EAAE,WAAW,CAAC,QAAQ,CAAC,EAAE,WAAW,CAAC;QACpG,UAAU,EAAE,cAAc,CAAC,sBAAsB,EAAE,WAAW,CAAC;QAC/D,QAAQ,EAAE,OAAO,CAAC,QAAQ,IAAI,MAAM;QACpC,aAAa,EAAE,iBAAiB,CAAC,CAAC,CAAC,cAAc,CAAC,iBAAiB,EAAE,WAAW,CAAC,CAAC,CAAC,CAAC,SAAS;KAC9F,CAAC;IAEF,uCAAuC;IACvC,IAAI,OAAO,CAAC,WAAW,EAAE,CAAC;QACxB,eAAe,CAAC,WAAW,GAAG,kBAAkB,CAAC,OAAO,CAAC,WAAW,EAAE,WAAW,CAAC,CAAC;IACrF,CAAC;IAED,OAAO;QACL,MAAM,EAAE,KAAK,CAAC,MAAM;QACpB,KAAK,EAAE,KAAK,CAAC,KAAK;QAClB,EAAE,EAAE,KAAK,CAAC,EAAE;QACZ,OAAO,EAAE,eAAe;QACxB,eAAe,EAAE,KAAK,CAAC,eAAe;KACvC,CAAC;AACJ,CAAC"}