@stratal/testing 0.0.0-canary-ccb3f17 → 0.0.0-canary-e5681b8
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/CHANGELOG.md +603 -0
- package/README.md +137 -36
- package/dist/database/index.d.mts +2 -2
- package/dist/database/index.mjs +2 -2
- package/dist/{database-DeMI4Igi.mjs → database-Rojs69r3.mjs} +112 -60
- package/dist/database-Rojs69r3.mjs.map +1 -0
- package/dist/{decorate-ZDdbRmsv.mjs → decorate-RQD1h28J.mjs} +1 -1
- package/dist/feature-flags/index.mjs +1 -1
- package/dist/{feature-flags-BMYurC1B.mjs → feature-flags-CZ1a4M2g.mjs} +2 -2
- package/dist/{feature-flags-BMYurC1B.mjs.map → feature-flags-CZ1a4M2g.mjs.map} +1 -1
- package/dist/{index-DUScdrKC.d.mts → index-B8Mw1Dxk.d.mts} +46 -33
- package/dist/index-B8Mw1Dxk.d.mts.map +1 -0
- package/dist/{index-Dm6e2N61.d.mts → index-D7FM6EKp.d.mts} +21 -2
- package/dist/index-D7FM6EKp.d.mts.map +1 -0
- package/dist/index.d.mts +55 -28
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +67 -61
- package/dist/index.mjs.map +1 -1
- package/dist/mocks/cloudflare-workers.d.mts +6 -7
- package/dist/mocks/cloudflare-workers.d.mts.map +1 -1
- package/dist/mocks/index.d.mts +1 -1
- package/dist/mocks/index.mjs +1 -1
- package/dist/mocks/noop-rate-limiter-store.d.mts +1 -2
- package/dist/mocks/noop-rate-limiter-store.d.mts.map +1 -1
- package/dist/mocks/zenstack-language.d.mts +21 -21
- package/dist/mocks/zenstack-language.d.mts.map +1 -1
- package/dist/mocks/zenstack-language.mjs +1 -1
- package/dist/mocks/zenstack-language.mjs.map +1 -1
- package/dist/storage/index.d.mts +1 -1
- package/dist/storage/index.mjs +1 -1
- package/dist/{storage-q8RFahgU.mjs → storage-BiGamMA8.mjs} +70 -3
- package/dist/storage-BiGamMA8.mjs.map +1 -0
- package/dist/{test-worker-exports-DMct0Egv.d.mts → test-worker-exports-dCRARYEc.d.mts} +8 -7
- package/dist/test-worker-exports-dCRARYEc.d.mts.map +1 -0
- package/dist/{test-workers-cache-eiGMw9Yj.mjs → test-workers-cache-D02Pt_dE.mjs} +8 -7
- package/dist/{test-workers-cache-eiGMw9Yj.mjs.map → test-workers-cache-D02Pt_dE.mjs.map} +1 -1
- package/dist/vitest-plugin/index.d.mts +9 -9
- package/dist/vitest-plugin/index.d.mts.map +1 -1
- package/dist/vitest-plugin/index.mjs +22 -15
- package/dist/vitest-plugin/index.mjs.map +1 -1
- package/package.json +22 -19
- package/dist/database-DeMI4Igi.mjs.map +0 -1
- package/dist/index-DUScdrKC.d.mts.map +0 -1
- package/dist/index-Dm6e2N61.d.mts.map +0 -1
- package/dist/storage-q8RFahgU.mjs.map +0 -1
- package/dist/test-worker-exports-DMct0Egv.d.mts.map +0 -1
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { t as __decorate } from "./decorate-
|
|
1
|
+
import { t as __decorate } from "./decorate-RQD1h28J.mjs";
|
|
2
2
|
import { Singleton } from "stratal/di";
|
|
3
3
|
//#region src/feature-flags/fake-feature-flag.service.ts
|
|
4
4
|
/**
|
|
@@ -83,4 +83,4 @@ FakeFeatureFlagService = __decorate([Singleton(FEATURE_FLAG_SERVICE_TOKEN)], Fak
|
|
|
83
83
|
//#endregion
|
|
84
84
|
export { FakeFeatureFlagService as n, FEATURE_FLAG_SERVICE_TOKEN as t };
|
|
85
85
|
|
|
86
|
-
//# sourceMappingURL=feature-flags-
|
|
86
|
+
//# sourceMappingURL=feature-flags-CZ1a4M2g.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"feature-flags-
|
|
1
|
+
{"version":3,"file":"feature-flags-CZ1a4M2g.mjs","names":[],"sources":["../src/feature-flags/fake-feature-flag.service.ts"],"sourcesContent":["import { Singleton } from 'stratal/di';\n\n/**\n * Global DI token for the feature-flags service.\n *\n * Mirrors `FEATURE_FLAG_TOKENS.FeatureFlagService` from `@stratal/feature-flags`\n * — `Symbol.for(...)` resolves to the same symbol across packages via the global\n * registry. Declared here so `@stratal/testing` needs no dependency on the\n * optional feature-flags package. Keep this string in sync with\n * `packages/feature-flags/src/feature-flags.tokens.ts`.\n */\nexport const FEATURE_FLAG_SERVICE_TOKEN = Symbol.for('stratal:feature-flags:service')\n\n/** A value a feature flag can resolve to. */\nexport type FlagValue = boolean | string | number | object\n\ninterface FakeFlagDetails<T> {\n flagKey: string\n value: T\n reason: string\n}\n\n/**\n * FakeFeatureFlagService\n *\n * In-memory stand-in for `@stratal/feature-flags`'s request-scoped\n * `FeatureFlagService`, auto-registered by the testing module so feature-gated\n * code resolves without a real Cloudflare Flagship binding (which only exists at\n * runtime). Mirrors the real service's public evaluation surface.\n *\n * Unset flags return the per-call default (or the type's zero value). Configure\n * values with {@link set} / {@link setAll}; access it in tests via\n * `module.featureFlags`.\n *\n * @example\n * ```typescript\n * module.featureFlags.set('new-checkout', true)\n * const enabled = await flags.getBooleanValue('new-checkout') // true\n * ```\n */\n@Singleton(FEATURE_FLAG_SERVICE_TOKEN)\nexport class FakeFeatureFlagService {\n private readonly flags = new Map<string, FlagValue>()\n\n // ==================== CONFIGURATION ====================\n\n /** Set a single flag value. */\n set(flagKey: string, value: FlagValue): this {\n this.flags.set(flagKey, value)\n return this\n }\n\n /** Replace all configured flags with the given map. */\n setAll(flags: Record<string, FlagValue>): this {\n this.reset()\n for (const [key, value] of Object.entries(flags)) this.flags.set(key, value)\n return this\n }\n\n /** Clear every configured flag. */\n reset(): this {\n this.flags.clear()\n return this\n }\n\n // ==================== EVALUATION ====================\n\n async get(flagKey: string, defaultValue?: unknown): Promise<unknown> {\n return Promise.resolve(this.flags.has(flagKey) ? this.flags.get(flagKey) : defaultValue)\n }\n\n async getBooleanValue(flagKey: string, defaultValue = false): Promise<boolean> {\n return this.resolve(flagKey, defaultValue)\n }\n\n async getStringValue(flagKey: string, defaultValue = ''): Promise<string> {\n return this.resolve(flagKey, defaultValue)\n }\n\n async getNumberValue(flagKey: string, defaultValue = 0): Promise<number> {\n return this.resolve(flagKey, defaultValue)\n }\n\n async getObjectValue<T extends object>(flagKey: string, defaultValue: T = {} as T): Promise<T> {\n return this.resolve(flagKey, defaultValue)\n }\n\n async getBooleanDetails(flagKey: string, defaultValue = false): Promise<FakeFlagDetails<boolean>> {\n return this.details(flagKey, await this.getBooleanValue(flagKey, defaultValue))\n }\n\n async getStringDetails(flagKey: string, defaultValue = ''): Promise<FakeFlagDetails<string>> {\n return this.details(flagKey, await this.getStringValue(flagKey, defaultValue))\n }\n\n async getNumberDetails(flagKey: string, defaultValue = 0): Promise<FakeFlagDetails<number>> {\n return this.details(flagKey, await this.getNumberValue(flagKey, defaultValue))\n }\n\n async getObjectDetails<T extends object>(flagKey: string, defaultValue: T = {} as T): Promise<FakeFlagDetails<T>> {\n return this.details(flagKey, await this.getObjectValue(flagKey, defaultValue))\n }\n\n /** Returns every configured flag as a `{ key: value }` map. */\n async all(): Promise<Record<string, FlagValue>> {\n return Promise.resolve(Object.fromEntries(this.flags))\n }\n\n /** Switching Flagship apps is a no-op in the fake. */\n use(): this {\n return this\n }\n\n /** The binding name this instance targets. */\n // oxlint-disable-next-line typescript/class-literal-property-style\n get app(): string {\n return 'fake'\n }\n\n // ==================== INTERNAL ====================\n\n private resolve<T extends FlagValue>(flagKey: string, defaultValue: T): Promise<T> {\n return Promise.resolve(this.flags.has(flagKey) ? (this.flags.get(flagKey) as T) : defaultValue)\n }\n\n private details<T>(flagKey: string, value: T): FakeFlagDetails<T> {\n return { flagKey, value, reason: 'fake' }\n }\n}\n"],"mappings":";;;;;;;;;;;;AAWA,MAAa,6BAA6B,OAAO,IAAI,+BAA+B;AA8B7E,IAAM,yBAAN,MAAM,uBAAuB;CAClC,wBAAyB,IAAI,IAAuB;;CAKpD,IAAI,SAAiB,OAAwB;EAC3C,KAAK,MAAM,IAAI,SAAS,KAAK;EAC7B,OAAO;CACT;;CAGA,OAAO,OAAwC;EAC7C,KAAK,MAAM;EACX,KAAK,MAAM,CAAC,KAAK,UAAU,OAAO,QAAQ,KAAK,GAAG,KAAK,MAAM,IAAI,KAAK,KAAK;EAC3E,OAAO;CACT;;CAGA,QAAc;EACZ,KAAK,MAAM,MAAM;EACjB,OAAO;CACT;CAIA,MAAM,IAAI,SAAiB,cAA0C;EACnE,OAAO,QAAQ,QAAQ,KAAK,MAAM,IAAI,OAAO,IAAI,KAAK,MAAM,IAAI,OAAO,IAAI,YAAY;CACzF;CAEA,MAAM,gBAAgB,SAAiB,eAAe,OAAyB;EAC7E,OAAO,KAAK,QAAQ,SAAS,YAAY;CAC3C;CAEA,MAAM,eAAe,SAAiB,eAAe,IAAqB;EACxE,OAAO,KAAK,QAAQ,SAAS,YAAY;CAC3C;CAEA,MAAM,eAAe,SAAiB,eAAe,GAAoB;EACvE,OAAO,KAAK,QAAQ,SAAS,YAAY;CAC3C;CAEA,MAAM,eAAiC,SAAiB,eAAkB,CAAC,GAAoB;EAC7F,OAAO,KAAK,QAAQ,SAAS,YAAY;CAC3C;CAEA,MAAM,kBAAkB,SAAiB,eAAe,OAA0C;EAChG,OAAO,KAAK,QAAQ,SAAS,MAAM,KAAK,gBAAgB,SAAS,YAAY,CAAC;CAChF;CAEA,MAAM,iBAAiB,SAAiB,eAAe,IAAsC;EAC3F,OAAO,KAAK,QAAQ,SAAS,MAAM,KAAK,eAAe,SAAS,YAAY,CAAC;CAC/E;CAEA,MAAM,iBAAiB,SAAiB,eAAe,GAAqC;EAC1F,OAAO,KAAK,QAAQ,SAAS,MAAM,KAAK,eAAe,SAAS,YAAY,CAAC;CAC/E;CAEA,MAAM,iBAAmC,SAAiB,eAAkB,CAAC,GAAqC;EAChH,OAAO,KAAK,QAAQ,SAAS,MAAM,KAAK,eAAe,SAAS,YAAY,CAAC;CAC/E;;CAGA,MAAM,MAA0C;EAC9C,OAAO,QAAQ,QAAQ,OAAO,YAAY,KAAK,KAAK,CAAC;CACvD;;CAGA,MAAY;EACV,OAAO;CACT;;CAIA,IAAI,MAAc;EAChB,OAAO;CACT;CAIA,QAAqC,SAAiB,cAA6B;EACjF,OAAO,QAAQ,QAAQ,KAAK,MAAM,IAAI,OAAO,IAAK,KAAK,MAAM,IAAI,OAAO,IAAU,YAAY;CAChG;CAEA,QAAmB,SAAiB,OAA8B;EAChE,OAAO;GAAE;GAAS;GAAO,QAAQ;EAAO;CAC1C;AACF;AAxFC,yBAAA,WAAA,CAAA,UAAU,0BAA0B,CAAA,GAAA,sBAAA"}
|
|
@@ -2,10 +2,11 @@
|
|
|
2
2
|
/**
|
|
3
3
|
* Test database isolation helpers.
|
|
4
4
|
*
|
|
5
|
-
* Implements
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
5
|
+
* Implements leased worker databases for parallel runs against Postgres. A
|
|
6
|
+
* migrated **template** database is built once in global setup. Each test file
|
|
7
|
+
* leases one numbered worker database for as long as its isolate lives and
|
|
8
|
+
* receives a fresh clone of the template in it, so a run holds at most as many
|
|
9
|
+
* databases as it runs files at once. See `@stratal/testing/database`.
|
|
9
10
|
*
|
|
10
11
|
* `pg` is imported dynamically so this module loads without it — consumers
|
|
11
12
|
* that don't use a database never pay the dependency.
|
|
@@ -22,36 +23,48 @@ declare const DEFAULT_DB_BINDING = "DB";
|
|
|
22
23
|
declare function deriveAdminConnectionString(connectionString: string): string;
|
|
23
24
|
/** Build a connection string identical to `base` but pointing at `dbName`. */
|
|
24
25
|
declare function buildConnectionString(base: string, dbName: string): string;
|
|
25
|
-
/** The shared prefix for
|
|
26
|
+
/** The shared prefix for worker databases, used as the sweep key. */
|
|
26
27
|
declare function databasePrefix(base: string): string;
|
|
27
28
|
/** Name of the migrated template database cloned per worker. */
|
|
28
29
|
declare function deriveTemplateName(base: string): string;
|
|
29
30
|
/**
|
|
30
|
-
* Name of the database
|
|
31
|
-
*
|
|
32
|
-
* share one — because `@cloudflare/vitest-pool-workers` isolates per file and can
|
|
33
|
-
* run a worker's files concurrently; per-file databases make cross-file
|
|
34
|
-
* contamination impossible by construction. Asserted against Postgres' 63-char
|
|
35
|
-
* identifier limit (keep the base name short so `_f_<token>` fits).
|
|
31
|
+
* Name of the worker database behind lease `slot`. Asserted against Postgres'
|
|
32
|
+
* 63-char identifier limit (keep the base name short so `_w_<slot>` fits).
|
|
36
33
|
*/
|
|
37
|
-
declare function
|
|
34
|
+
declare function deriveWorkerDbName(base: string, slot: number): string;
|
|
38
35
|
/**
|
|
39
|
-
*
|
|
40
|
-
* lock-frugal: it first checks `pg_database`, so the common "already exists" path
|
|
41
|
-
* (every file after a slot's first) never issues `CREATE DATABASE ... TEMPLATE`
|
|
42
|
-
* and never takes the clone lock.
|
|
36
|
+
* Replace worker database `dbName` with a fresh clone of `template`.
|
|
43
37
|
*
|
|
44
38
|
* The clone is serialized across all workers and processes by one Postgres
|
|
45
39
|
* advisory lock keyed on the template. Postgres permits only one
|
|
46
40
|
* `CREATE DATABASE ... TEMPLATE t` at a time — a concurrent one fails with
|
|
47
|
-
* SQLSTATE 55006
|
|
48
|
-
*
|
|
49
|
-
*
|
|
50
|
-
*
|
|
51
|
-
*
|
|
52
|
-
*
|
|
41
|
+
* SQLSTATE 55006 — so without the lock every file starting at once would race
|
|
42
|
+
* and all but one would fail. The lock funnels them one at a time, each
|
|
43
|
+
* blocking *in Postgres* (not busy-waiting) until its turn. A create that still
|
|
44
|
+
* hits a transient 55006 is retried with backoff.
|
|
45
|
+
*
|
|
46
|
+
* `WITH (FORCE)` ends connections the previous lessee's pool left open: its
|
|
47
|
+
* isolate is gone, so nothing will close them.
|
|
48
|
+
*/
|
|
49
|
+
declare function cloneWorkerDatabase(adminConn: string, dbName: string, template: string): Promise<void>;
|
|
50
|
+
/** A worker database leased to the current isolate. */
|
|
51
|
+
interface WorkerDatabaseLease {
|
|
52
|
+
/** The leased database's name (`<base>_w_<slot>`). */
|
|
53
|
+
name: string;
|
|
54
|
+
/** `base` pointed at the leased database. */
|
|
55
|
+
connectionString: string;
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Lease the lowest free worker database for `base` and fill it with a fresh
|
|
59
|
+
* clone of the template.
|
|
60
|
+
*
|
|
61
|
+
* A slot is free when no other session holds its advisory lock. The pool runs
|
|
62
|
+
* each test file in its own isolate and disposes that isolate when the file
|
|
63
|
+
* ends, so a run never holds more slots than it runs files at once — and so
|
|
64
|
+
* never more worker databases. Every lease re-clones, so a file starts from
|
|
65
|
+
* exactly the template, including anything `prepare` baked into it.
|
|
53
66
|
*/
|
|
54
|
-
declare function
|
|
67
|
+
declare function leaseWorkerDatabase(base: string): Promise<WorkerDatabaseLease>;
|
|
55
68
|
/** Options for {@link createTestDatabaseGlobalSetup}. */
|
|
56
69
|
interface TestDatabaseGlobalSetupOptions {
|
|
57
70
|
/** Run migrations against the template connection string. */
|
|
@@ -83,9 +96,9 @@ interface TestDatabaseGlobalSetupOptions {
|
|
|
83
96
|
* Build a Vitest `globalSetup` default export that prepares the test database.
|
|
84
97
|
*
|
|
85
98
|
* Under a Postgres advisory lock (so concurrent setups across CI shards /
|
|
86
|
-
* multiple e2e projects don't clobber each other), sweeps
|
|
99
|
+
* multiple e2e projects don't clobber each other), sweeps unused worker
|
|
87
100
|
* databases, then ensures a migrated (and optionally prepared) template exists
|
|
88
|
-
* — ready to be cloned
|
|
101
|
+
* — ready to be cloned into each leased worker database.
|
|
89
102
|
*
|
|
90
103
|
* **Template reuse.** The template is fingerprinted from the `schema` source(s)
|
|
91
104
|
* + the `migrate` routine + the `prepare` routine, and the fingerprint is
|
|
@@ -98,11 +111,11 @@ interface TestDatabaseGlobalSetupOptions {
|
|
|
98
111
|
*
|
|
99
112
|
* **Concurrency model.** The reuse check + rebuild runs under
|
|
100
113
|
* `pg_advisory_lock(hashtext(<template>))`, so only one process rebuilds the
|
|
101
|
-
* template at a time. The
|
|
102
|
-
*
|
|
103
|
-
* intact
|
|
104
|
-
*
|
|
105
|
-
* the
|
|
114
|
+
* template at a time. The sweep only drops worker databases with **no active
|
|
115
|
+
* connections** and a free lease slot, leaving a sibling process's live databases
|
|
116
|
+
* intact — which is what lets it run at teardown as well as at setup, so a run
|
|
117
|
+
* takes its own databases with it. Teardown deliberately does **not** drop the
|
|
118
|
+
* template: it is shared, and the next run reuses it by fingerprint.
|
|
106
119
|
*
|
|
107
120
|
* @example
|
|
108
121
|
* ```ts
|
|
@@ -116,7 +129,7 @@ interface TestDatabaseGlobalSetupOptions {
|
|
|
116
129
|
* })
|
|
117
130
|
* ```
|
|
118
131
|
*/
|
|
119
|
-
declare function createTestDatabaseGlobalSetup(opts: TestDatabaseGlobalSetupOptions): () => Promise<void
|
|
132
|
+
declare function createTestDatabaseGlobalSetup(opts: TestDatabaseGlobalSetupOptions): () => Promise<() => Promise<void>>;
|
|
120
133
|
//#endregion
|
|
121
134
|
//#region src/database/reset.d.ts
|
|
122
135
|
/** Options controlling which tables a per-test reset truncates. */
|
|
@@ -158,5 +171,5 @@ declare function buildTableDiscoverySql(schemas: string[], preserve: string[]):
|
|
|
158
171
|
*/
|
|
159
172
|
declare function resetWorkerDatabase(connectionString: string, opts?: ResetOptions): Promise<void>;
|
|
160
173
|
//#endregion
|
|
161
|
-
export { BINDING_ENV_VAR as a,
|
|
162
|
-
//# sourceMappingURL=index-
|
|
174
|
+
export { BINDING_ENV_VAR as a, WorkerDatabaseLease as c, createTestDatabaseGlobalSetup as d, databasePrefix as f, leaseWorkerDatabase as g, deriveWorkerDbName as h, resetWorkerDatabase as i, buildConnectionString as l, deriveTemplateName as m, buildTableDiscoverySql as n, DEFAULT_DB_BINDING as o, deriveAdminConnectionString as p, buildTruncateSql as r, TestDatabaseGlobalSetupOptions as s, ResetOptions as t, cloneWorkerDatabase as u };
|
|
175
|
+
//# sourceMappingURL=index-B8Mw1Dxk.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index-B8Mw1Dxk.d.mts","names":[],"sources":["../src/database/test-database.ts","../src/database/reset.ts"],"mappings":";;;;;;;;;;;;;;cAoBa;;cAGA;;;;;;iBAgEG,4BAA4B;;iBAO5B,sBAAsB,cAAc;;iBAOpC,eAAe;;iBAMf,mBAAmB;;;;;iBAUnB,mBAAmB,cAAc;;;;;;;;;;;;;;;iBA0D3B,oBACpB,mBACA,gBACA,mBACC;;UA0Bc;;EAEf;;EAEA;;;;;;;;;;;;iBAqBoB,oBAAoB,eAAe,QAAQ;;UA2LhD;;EAEf,UAAU,oCAAoC;;;;;;EAM9C;;;;;;;;;;;;EAYA,WAAW,oCAAoC;;EAE/C;;EAEA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAwCc,8BACd,MAAM,uCACC,cAAc;;;;UCheN;;EAEf;;;;;;;;EAQA;;;;;;;;iBAac,iBAAiB;EAAU;EAAgB;;;;;;;;;iBAoB3C,uBAAuB,mBAAmB;;;;;;;iBAqBpC,oBAAoB,0BAA0B,OAAM,eAAoB"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { DownloadResult, PresignedUrlResult, StorageConfig, StorageManagerService, StorageService, StreamingBlobPayloadInputTypes, UploadOptions, UploadResult } from "stratal/storage";
|
|
1
|
+
import { DownloadResult, HeadResult, ListOptions, ListResult, PresignedUrlResult, StorageConfig, StorageManagerService, StorageService, StreamingBlobPayloadInputTypes, UploadOptions, UploadResult } from "stratal/storage";
|
|
2
2
|
//#region src/storage/fake-storage.service.d.ts
|
|
3
3
|
/**
|
|
4
4
|
* Stored file representation in memory
|
|
@@ -48,6 +48,25 @@ declare class FakeStorageService extends StorageService {
|
|
|
48
48
|
* Check if a file exists in fake storage
|
|
49
49
|
*/
|
|
50
50
|
exists(path: string): Promise<boolean>;
|
|
51
|
+
/**
|
|
52
|
+
* Delete many files from fake storage
|
|
53
|
+
*/
|
|
54
|
+
deleteMany(paths: string[], disk?: string): Promise<void>;
|
|
55
|
+
/**
|
|
56
|
+
* Read a file's metadata from fake storage, without its contents
|
|
57
|
+
*/
|
|
58
|
+
head(path: string, disk?: string): Promise<HeadResult | null>;
|
|
59
|
+
/**
|
|
60
|
+
* List files in fake storage, one page at a time
|
|
61
|
+
*
|
|
62
|
+
* Truncates after ONE object unless `limit` says otherwise. Real R2 pages at 1000, but no
|
|
63
|
+
* fixture stores 1000 files — matching that number would return everything in one page and let
|
|
64
|
+
* a caller who never follows `cursor` pass every test, then undercount against a real bucket.
|
|
65
|
+
* Paging at one means any listing of two or more objects exercises the loop.
|
|
66
|
+
*
|
|
67
|
+
* Pass `limit` to widen the page when a test is asserting page contents rather than the loop.
|
|
68
|
+
*/
|
|
69
|
+
list(options?: ListOptions, disk?: string): Promise<ListResult>;
|
|
51
70
|
/**
|
|
52
71
|
* Generate a fake presigned download URL
|
|
53
72
|
*/
|
|
@@ -114,4 +133,4 @@ declare class FakeStorageService extends StorageService {
|
|
|
114
133
|
}
|
|
115
134
|
//#endregion
|
|
116
135
|
export { StoredFile as n, FakeStorageService as t };
|
|
117
|
-
//# sourceMappingURL=index-
|
|
136
|
+
//# sourceMappingURL=index-D7FM6EKp.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index-D7FM6EKp.d.mts","names":[],"sources":["../src/storage/fake-storage.service.ts"],"mappings":";;;;;UAwCiB;EACf,SAAS;EACT;EACA;EACA,WAAW;EACX,YAAY;;;;;;;;;;;;;;;;;;;cAqBD,2BAA2B;qBAKjB,gBAAgB;qBAEhB,SAAS;UANtB;EAER,YAEqB,gBAAgB,uBAEhB,SAAS;;;;EAQxB,OACJ,MAAM,gCACN,sBACA,SAAS,eACT,gBACC,QAAQ;;;;EAyBX,SAAS,eAAe,QAAQ;;;;EAyBhC,OAAO,eAAe;;;;EAQtB,OAAO,eAAe;;;;EAUhB,WAAW,iBAAiB,gBAAgB;;;;EAa5C,KAAK,cAAc,gBAAgB,QAAQ;;;;;;;;;;;EAqB3C,KAAK,UAAS,aAAkB,gBAAgB,QAAQ;;;;EAuC9D,wBACE,cACA,qBACC,QAAQ;;;;EAOX,sBACE,cACA,qBACC,QAAQ;;;;EAOX,sBACE,cACA,qBACC,QAAQ;;;;EAOL,cACJ,MAAM,gCACN,cACA,SAAS,KAAK;IAA2B;KACzC,gBACC,QAAQ;;;;;;;EAoBX,aAAa;;;;;;;EAab,cAAc;;;;;;EAYd;;;;;;;EAaA,YAAY;;;;EAUZ,kBAAkB,YAAY;;;;EAO9B;;;;EAOA,QAAQ,eAAe;;;;EAOvB;UAQQ;UAeM"}
|
package/dist/index.d.mts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { t as ResetOptions } from "./index-
|
|
1
|
+
import { t as ResetOptions } from "./index-B8Mw1Dxk.mjs";
|
|
2
2
|
import { n as FakeFeatureFlagService } from "./index-qgWNJRdC.mjs";
|
|
3
|
-
import { t as FakeStorageService } from "./index-
|
|
4
|
-
import { i as TestEmailProvider, n as TestWorkerExports, r as TestWorkersCache } from "./test-worker-exports-
|
|
3
|
+
import { t as FakeStorageService } from "./index-D7FM6EKp.mjs";
|
|
4
|
+
import { i as TestEmailProvider, n as TestWorkerExports, r as TestWorkersCache } from "./test-worker-exports-dCRARYEc.mjs";
|
|
5
5
|
import { Application, ApplicationConfig, Constructor, StratalEnv, StratalExecutionContext } from "stratal";
|
|
6
6
|
import { DynamicModule, InjectionToken, ModuleClass, ModuleOptions } from "stratal/module";
|
|
7
7
|
import { ResolvedEmailMessage } from "stratal/email";
|
|
@@ -28,7 +28,7 @@ import { CommandInput, CommandResult } from "stratal/quarry";
|
|
|
28
28
|
* .assertJsonPath('data.id', userId)
|
|
29
29
|
* ```
|
|
30
30
|
*/
|
|
31
|
-
declare class TestResponse extends Macroable {
|
|
31
|
+
export declare class TestResponse extends Macroable {
|
|
32
32
|
private readonly response;
|
|
33
33
|
private jsonData;
|
|
34
34
|
private textData;
|
|
@@ -191,7 +191,7 @@ declare class TestResponse extends Macroable {
|
|
|
191
191
|
* .send()
|
|
192
192
|
* ```
|
|
193
193
|
*/
|
|
194
|
-
declare class TestHttpRequest extends Macroable {
|
|
194
|
+
export declare class TestHttpRequest extends Macroable {
|
|
195
195
|
protected readonly method: string;
|
|
196
196
|
protected readonly path: string;
|
|
197
197
|
protected readonly module: TestingModule;
|
|
@@ -264,7 +264,7 @@ declare class TestHttpRequest extends Macroable {
|
|
|
264
264
|
* response.assertCreated()
|
|
265
265
|
* ```
|
|
266
266
|
*/
|
|
267
|
-
declare class TestHttpClient {
|
|
267
|
+
export declare class TestHttpClient {
|
|
268
268
|
private readonly module;
|
|
269
269
|
private defaultHeaders;
|
|
270
270
|
private host;
|
|
@@ -329,7 +329,7 @@ declare class TestHttpClient {
|
|
|
329
329
|
* result.assertOutputContains('User created')
|
|
330
330
|
* ```
|
|
331
331
|
*/
|
|
332
|
-
declare class TestCommandResult {
|
|
332
|
+
export declare class TestCommandResult {
|
|
333
333
|
private readonly result;
|
|
334
334
|
constructor(result: CommandResult);
|
|
335
335
|
get exitCode(): number;
|
|
@@ -359,7 +359,7 @@ declare class TestCommandResult {
|
|
|
359
359
|
* result.assertOutputContains('User created')
|
|
360
360
|
* ```
|
|
361
361
|
*/
|
|
362
|
-
declare class TestCommandRequest {
|
|
362
|
+
export declare class TestCommandRequest {
|
|
363
363
|
private readonly commandName;
|
|
364
364
|
private readonly module;
|
|
365
365
|
private _input;
|
|
@@ -396,7 +396,7 @@ interface TestSseEvent {
|
|
|
396
396
|
* await sse.waitForEnd()
|
|
397
397
|
* ```
|
|
398
398
|
*/
|
|
399
|
-
declare class TestSseConnection {
|
|
399
|
+
export declare class TestSseConnection {
|
|
400
400
|
private readonly response;
|
|
401
401
|
private readonly eventQueue;
|
|
402
402
|
private eventWaiters;
|
|
@@ -454,7 +454,7 @@ declare class TestSseConnection {
|
|
|
454
454
|
* const sse = await module.sse('/streaming/sse').actingAs({ id: user.id }).connect()
|
|
455
455
|
* ```
|
|
456
456
|
*/
|
|
457
|
-
declare class TestSseRequest {
|
|
457
|
+
export declare class TestSseRequest {
|
|
458
458
|
private readonly path;
|
|
459
459
|
private readonly module;
|
|
460
460
|
private requestHeaders;
|
|
@@ -497,7 +497,7 @@ declare class TestSseRequest {
|
|
|
497
497
|
* await ws.waitForClose()
|
|
498
498
|
* ```
|
|
499
499
|
*/
|
|
500
|
-
declare class TestWsConnection {
|
|
500
|
+
export declare class TestWsConnection {
|
|
501
501
|
private readonly ws;
|
|
502
502
|
private readonly messageQueue;
|
|
503
503
|
private messageWaiters;
|
|
@@ -556,7 +556,7 @@ declare class TestWsConnection {
|
|
|
556
556
|
* const ws = await module.ws('/ws/chat').actingAs({ id: user.id }).connect()
|
|
557
557
|
* ```
|
|
558
558
|
*/
|
|
559
|
-
declare class TestWsRequest {
|
|
559
|
+
export declare class TestWsRequest {
|
|
560
560
|
private readonly path;
|
|
561
561
|
private readonly module;
|
|
562
562
|
private requestHeaders;
|
|
@@ -614,7 +614,7 @@ declare class TestWsRequest {
|
|
|
614
614
|
* await module.close()
|
|
615
615
|
* ```
|
|
616
616
|
*/
|
|
617
|
-
declare class TestingModule {
|
|
617
|
+
export declare class TestingModule {
|
|
618
618
|
private readonly app;
|
|
619
619
|
private readonly env;
|
|
620
620
|
private readonly ctx;
|
|
@@ -640,6 +640,15 @@ declare class TestingModule {
|
|
|
640
640
|
get http(): TestHttpClient;
|
|
641
641
|
/**
|
|
642
642
|
* Get Inertia test client for making Inertia requests
|
|
643
|
+
*
|
|
644
|
+
* Sends no `X-Inertia-Version`. It used to send `'1'`, which meant any app configuring a real
|
|
645
|
+
* asset version had every request from this client read as a stale client and answered with a
|
|
646
|
+
* version-mismatch 409 — an entire Inertia suite failing on a value the tests never chose. The
|
|
647
|
+
* check needs a version from BOTH sides, so omitting it here leaves the app under test in charge
|
|
648
|
+
* rather than this header.
|
|
649
|
+
*
|
|
650
|
+
* A test that wants the mismatch path asks for it:
|
|
651
|
+
* `module.inertia.withHeaders({ 'X-Inertia-Version': 'stale' })`.
|
|
643
652
|
*/
|
|
644
653
|
get inertia(): TestHttpClient;
|
|
645
654
|
/**
|
|
@@ -768,6 +777,25 @@ interface TestingModuleConfig extends ModuleOptions {
|
|
|
768
777
|
* `initialize()` (before overrides apply).
|
|
769
778
|
*/
|
|
770
779
|
exceptionHandler?: Constructor<ExceptionHandler>;
|
|
780
|
+
/**
|
|
781
|
+
* Trailing-slash canonicalisation. Mirrors `ApplicationConfig.trailingSlash`,
|
|
782
|
+
* so it takes the same bare mode or `{ mode, exclude }` object. Defaults to
|
|
783
|
+
* the framework default, `'ignore'`.
|
|
784
|
+
*
|
|
785
|
+
* A testing module builds its own `Application` and never runs the app's
|
|
786
|
+
* entry file, so an app that canonicalises URLs there only does so in
|
|
787
|
+
* production unless its suite repeats the setting here. Left unset, every
|
|
788
|
+
* route assertion checks a URL shape that configuration would never emit,
|
|
789
|
+
* and neither the 308 redirect nor any `exclude` entry is exercised.
|
|
790
|
+
*/
|
|
791
|
+
trailingSlash?: ApplicationConfig['trailingSlash'];
|
|
792
|
+
/**
|
|
793
|
+
* URI versioning. Mirrors `ApplicationConfig.versioning`, and is subject to
|
|
794
|
+
* the same constraint as {@link TestingModuleConfig.trailingSlash}: unset,
|
|
795
|
+
* routes register at their unversioned path, which an app configuring a
|
|
796
|
+
* version prefix never serves.
|
|
797
|
+
*/
|
|
798
|
+
versioning?: ApplicationConfig['versioning'];
|
|
771
799
|
/**
|
|
772
800
|
* Set to `false` to compile without a `ctx.cache` stub, reproducing a
|
|
773
801
|
* runtime where Workers Caching is genuinely unconfigured. Neither
|
|
@@ -782,7 +810,7 @@ interface TestingModuleConfig extends ModuleOptions {
|
|
|
782
810
|
/**
|
|
783
811
|
* Builder for creating test modules with provider overrides
|
|
784
812
|
*/
|
|
785
|
-
declare class TestingModuleBuilder {
|
|
813
|
+
export declare class TestingModuleBuilder {
|
|
786
814
|
private config;
|
|
787
815
|
private overrides;
|
|
788
816
|
constructor(config: TestingModuleConfig);
|
|
@@ -808,10 +836,9 @@ declare class TestingModuleBuilder {
|
|
|
808
836
|
*/
|
|
809
837
|
compile(): Promise<TestingModule>;
|
|
810
838
|
/**
|
|
811
|
-
* Point this app's Hyperdrive binding at the
|
|
812
|
-
*
|
|
813
|
-
*
|
|
814
|
-
* between tests, not dropped per file. No-op when the consumer didn't opt into
|
|
839
|
+
* Point this app's Hyperdrive binding at the database this file leased,
|
|
840
|
+
* leasing it on the file's first compile. Returns nothing to clean up — the
|
|
841
|
+
* lease ends with the isolate. No-op when the consumer didn't opt into
|
|
815
842
|
* `stratalTest({ database })`; throws if they did but no connection string is
|
|
816
843
|
* configured (a misconfiguration that would otherwise silently skip isolation).
|
|
817
844
|
*/
|
|
@@ -846,7 +873,7 @@ interface ProviderOverrideConfig<T = unknown> {
|
|
|
846
873
|
* .compile()
|
|
847
874
|
* ```
|
|
848
875
|
*/
|
|
849
|
-
declare class ProviderOverrideBuilder<T> {
|
|
876
|
+
export declare class ProviderOverrideBuilder<T> {
|
|
850
877
|
private readonly parent;
|
|
851
878
|
private readonly token;
|
|
852
879
|
constructor(parent: TestingModuleBuilder, token: InjectionToken<T>);
|
|
@@ -919,7 +946,7 @@ declare class ProviderOverrideBuilder<T> {
|
|
|
919
946
|
* .compile()
|
|
920
947
|
* ```
|
|
921
948
|
*/
|
|
922
|
-
declare class Test {
|
|
949
|
+
export declare class Test {
|
|
923
950
|
/**
|
|
924
951
|
* Base modules to include in all test modules
|
|
925
952
|
* Set once in vitest.setup.ts
|
|
@@ -949,11 +976,11 @@ declare class Test {
|
|
|
949
976
|
/**
|
|
950
977
|
* Get value at dot-notation path.
|
|
951
978
|
*/
|
|
952
|
-
declare function getValueAtPath(obj: unknown, path: string): unknown;
|
|
979
|
+
export declare function getValueAtPath(obj: unknown, path: string): unknown;
|
|
953
980
|
/**
|
|
954
981
|
* Check if a path exists in the object (even if value is null/undefined).
|
|
955
982
|
*/
|
|
956
|
-
declare function hasValueAtPath(obj: unknown, path: string): boolean;
|
|
983
|
+
export declare function hasValueAtPath(obj: unknown, path: string): boolean;
|
|
957
984
|
//#endregion
|
|
958
985
|
//#region src/core/http/fetch-mock.types.d.ts
|
|
959
986
|
/**
|
|
@@ -1031,7 +1058,7 @@ interface MockErrorOptions {
|
|
|
1031
1058
|
* })
|
|
1032
1059
|
* ```
|
|
1033
1060
|
*/
|
|
1034
|
-
declare class MockFetch {
|
|
1061
|
+
export declare class MockFetch {
|
|
1035
1062
|
private server;
|
|
1036
1063
|
constructor(handlers?: RequestHandler[]);
|
|
1037
1064
|
/** Start intercepting. Call in beforeAll/beforeEach. */
|
|
@@ -1089,7 +1116,7 @@ declare class MockFetch {
|
|
|
1089
1116
|
* afterAll(() => mock.close())
|
|
1090
1117
|
* ```
|
|
1091
1118
|
*/
|
|
1092
|
-
declare function createMockFetch(handlers?: RequestHandler[]): MockFetch;
|
|
1119
|
+
export declare function createMockFetch(handlers?: RequestHandler[]): MockFetch;
|
|
1093
1120
|
//#endregion
|
|
1094
1121
|
//#region src/auth/acting-as.d.ts
|
|
1095
1122
|
/**
|
|
@@ -1104,7 +1131,7 @@ declare function createMockFetch(handlers?: RequestHandler[]): MockFetch;
|
|
|
1104
1131
|
* const headers = await actingAs.createSessionForUser({ id: 'user-123' })
|
|
1105
1132
|
* ```
|
|
1106
1133
|
*/
|
|
1107
|
-
declare class ActingAs {
|
|
1134
|
+
export declare class ActingAs {
|
|
1108
1135
|
private readonly authService;
|
|
1109
1136
|
constructor(authService: AuthService);
|
|
1110
1137
|
createSessionForUser(user: {
|
|
@@ -1117,7 +1144,7 @@ declare class ActingAs {
|
|
|
1117
1144
|
* Base error class for all test framework errors.
|
|
1118
1145
|
* Extends from Error and allows easy identification via `instanceof`.
|
|
1119
1146
|
*/
|
|
1120
|
-
declare class TestError extends Error {
|
|
1147
|
+
export declare class TestError extends Error {
|
|
1121
1148
|
readonly cause?: Error | undefined;
|
|
1122
1149
|
constructor(message: string, cause?: Error | undefined);
|
|
1123
1150
|
}
|
|
@@ -1127,9 +1154,9 @@ declare class TestError extends Error {
|
|
|
1127
1154
|
* Error thrown when test setup fails.
|
|
1128
1155
|
* Examples: schema creation failure, migration failure, application bootstrap failure.
|
|
1129
1156
|
*/
|
|
1130
|
-
declare class TestSetupError extends TestError {
|
|
1157
|
+
export declare class TestSetupError extends TestError {
|
|
1131
1158
|
constructor(message: string, cause?: Error);
|
|
1132
1159
|
}
|
|
1133
1160
|
//#endregion
|
|
1134
|
-
export {
|
|
1161
|
+
export { HttpResponse, type MockErrorOptions, type MockJsonOptions, type ProviderOverrideConfig, type TestSseEvent, type TestingModuleConfig, http };
|
|
1135
1162
|
//# sourceMappingURL=index.d.mts.map
|
package/dist/index.d.mts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.mts","names":[],"sources":["../src/core/http/test-response.ts","../src/core/http/test-http-request.ts","../src/core/http/test-http-client.ts","../src/core/quarry/test-command-result.ts","../src/core/quarry/test-command-request.ts","../src/core/sse/test-sse-connection.ts","../src/core/sse/test-sse-request.ts","../src/core/ws/test-ws-connection.ts","../src/core/ws/test-ws-request.ts","../src/core/testing-module.ts","../src/core/testing-module-builder.ts","../src/core/override/provider-override-builder.ts","../src/core/test.ts","../src/core/http/path-utils.ts","../src/core/http/fetch-mock.types.ts","../src/core/http/mock-fetch.ts","../src/auth/acting-as.ts","../src/errors/test-error.ts","../src/errors/setup-error.ts"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
1
|
+
{"version":3,"file":"index.d.mts","names":[],"sources":["../src/core/http/test-response.ts","../src/core/http/test-http-request.ts","../src/core/http/test-http-client.ts","../src/core/quarry/test-command-result.ts","../src/core/quarry/test-command-request.ts","../src/core/sse/test-sse-connection.ts","../src/core/sse/test-sse-request.ts","../src/core/ws/test-ws-connection.ts","../src/core/ws/test-ws-request.ts","../src/core/testing-module.ts","../src/core/testing-module-builder.ts","../src/core/override/provider-override-builder.ts","../src/core/test.ts","../src/core/http/path-utils.ts","../src/core/http/fetch-mock.types.ts","../src/core/http/mock-fetch.ts","../src/auth/acting-as.ts","../src/errors/test-error.ts","../src/errors/setup-error.ts"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;qBAiBa,qBAAqB;mBAIH;UAHrB;UACA;EAER,YAA6B,UAAU;;;;MAOnC,OAAO;;;;MAOP;;;;MAOA,WAAW;;;;EAOT,KAAK,gBAAgB,QAAQ;;;;EAU7B,QAAQ;;;;EAYd;;;;EAOA;;;;EAOA;;;;EAOA;;;;EAOA;;;;EAOA;;;;EAOA;;;;EAOA;;;;EAOA;;;;EAOA,aAAa;;;;EAWb;;;;EAeM,WAAW,UAAU,0BAA0B;;;;;;;EAmB/C,eAAe,cAAc,oBAAoB;;;;EAejD,oBAAoB,sBAAsB;;;;;;EAkB1C,qBAAqB,eAAe;;;;;;EAiBpC,sBAAsB,eAAe;;;;;;;EAkBrC,sBACJ,cACA,UAAU,6BACT;;;;;;;EAkBG,uBAAuB,cAAc,oBAAoB;;;;;;;EAuBzD,uBAAuB,cAAc,gBAAgB;;;;;;;EAuBrD,oBAAoB,cAAc,gBAAgB;;;;;;EAsBlD,gBAAgB,cAAc,0BAA0B;;;;EAqB9D,aAAa,cAAc;;;;EAqB3B,oBAAoB;;;;;;;;;;;;;;;;;;;;;;;;;;qBC3VT,wBAAwB;qBAQhB;qBACA;qBAEA,QAAQ;qBACR;YAXV;YACA,gBAAgB;YAChB;IAAgB;;YAChB,gBAAgB,QAAQ,eAAe;IAAQ;QAAiB,QAAQ;YACxE;IAAgB;IAAgB,UAAU;;EAEpD,YACoB,gBACA,cACnB,SAAS,SACU,QAAQ,eACR,sBACnB;IAAgB;IAAgB,UAAU;;;;;EAU3C,SAAS;;;;EAQT,YAAY,SAAS;;;;;;;;EAcrB,WAAW,gBAAgB,WAAW;;;;EAUtC;;;;EAQA,SAAS;IAAQ;;;;;;;EAWX,QAAQ,QAAQ;YA2BN,uBAAuB;;;;;;;;;;;;;;;;;;;;qBC/G3B;mBAMQ;UALX;UACA;UACA;EAER,YACmB,QAAQ,eACzB,sBACA,UAAS,SACT;IAAgB;IAAgB,UAAU;;;;;;;EAY5C,QAAQ,eAAe;;;;EASvB,YAAY,SAAS,yBAAyB;;;;;;;;EAe9C,WAAW,gBAAgB,WAAW,oBAAoB;;;;EAU1D,IAAI,eAAe;;;;EAOnB,KAAK,eAAe;;;;EAOpB,IAAI,eAAe;;;;EAOnB,MAAM,eAAe;;;;EAOrB,OAAO,eAAe;UAId;;;;;;;;;;;;;;;;;;qBC3FG;mBACkB;EAA7B,YAA6B,QAAQ;MAEjC;MAIA;MAIA;EAIJ;EAMA,aAAa;EASb,eAAe;EAKf,qBAAqB;EAMrB,oBAAoB;EAMpB,oBAAoB;EAMpB,mBAAmB;;;;;;;;;;;;;;;;;;qBCpDR;mBAIQ;mBACA;UAJX;EAER,YACmB,qBACA,QAAQ;;;;EAM3B,UAAU,OAAO;;;;EAQX,OAAO,QAAQ;;;;;;;UChCN;EAChB;EACA;EACA;EACA;;;;;;;;;;;;;;qBAeY;mBAMiB;mBALZ;UACT;UACA;UACA;EAER,YAA6B,UAAU;;;;EAOjC,aAAa,mBAAiB,QAAQ;;;;EA4BtC,WAAW,mBAAiB;;;;EAsB5B,cAAc,mBAAiB,QAAQ;;;;EAsCvC,YAAY,UAAU,QAAQ,eAAe,mBAAiB;;;;EAQ9D,gBAAgB,kBAAkB,mBAAiB;;;;EAQnD,oBAAoB,GAAG,UAAU,GAAG,mBAAiB;;;;MASvD,OAAO;UAIH;UAwDA;UA6CA;;;;;;;;;;;;;;;;;;;;;qBCrOI;mBAKM;mBACA;UALV;UACA;EAER,YACkB,cACA,QAAQ;;;;EAM1B,YAAY,SAAS;;;;;EAWrB,WAAW,gBAAgB,WAAW;;;;EAStC,SAAS;IAAQ;;;;;EAQX,WAAW,QAAQ;UA0BX;;;;;;;;;;;;;;;;;;qBC5EF;mBAMiB;mBALZ;UACT;UACA;UACA;EAER,YAA6B,IAAI;;;;EAsBjC,KAAK,eAAe,cAAc;;;;EAOlC,MAAM,eAAe;;;;EAOf,eAAe,mBAAiB,iBAAiB;;;;EAwBjD,aAAa,mBAAiB;IAAU;IAAe;;;;;EAwBvD,cAAc,kBAAkB,mBAAiB;;;;EASjD,aAAa,uBAAuB,mBAAiB;;;;MAUvD,OAAO;;;;;;;;;;;;;;;;;;;;;;qBClGC;mBAKM;mBACA;UALV;UACA;EAER,YACkB,cACA,QAAQ;;;;EAM1B,YAAY,SAAS;;;;;EAWrB,WAAW,gBAAgB,WAAW;;;;EAStC,SAAS;IAAQ;;;;;EAQX,WAAW,QAAQ;UA8BX;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;qBC/CF;mBAKQ;mBACA;mBACA;mBACA;mBACA;mBACA;mBACA;UAVX;mBACS;EAEjB,YACmB,KAAK,aACL,KAAK,YACL,KAAK,yBACL,oBAAmB,0BACnB,eAAc,oBACd,mBAAkB,8BAClB,oBAAmB;;;;;MAUlC,cAAc;;;;EAOlB,IAAI,GAAG,OAAO,eAAe,KAAK;;;;MAO9B,QAAQ;;;;;;;;;;;;;MAkBR,WAAW;;;;MAOX,WAAW;;;;;MAQX,gBAAgB;;;;;;;;;MAYhB,SAAS;;;;;;;;;;;;;;;MAwBT,WAAW;;;;EAaf,GAAG,eAAe;;;;EAOlB,IAAI,eAAe;;;;EAOnB,OAAO,eAAe;;;;MAOlB,eAAe;;;;MAOf,aAAa;;;;EAOX,MAAM,SAAS,UAAU,QAAQ;;;;;;UAiBzB;;;;EAUR,kBAAkB,GAAG,WAAW,WAAW,cAAc,IAAI,QAAQ,KAAK,QAAQ;;;;EAQxF,SAAS;EACT,MAAM,UAAU,gBAAgB,MAAM,IAAI,gBAAgB;;;;;EAUpD,WAAW,OAAO,gBAAgB,OAAM,eAAoB;;;;EAY5D,QAAQ,eAAe,YAAY,YAAY;;;;EAa/C,kBAAkB,eAAe,MAAM,yBAAyB,OAAO,iBAAiB;;;;EAUxF,sBAAsB,eAAe,MAAM,yBAAyB,OAAO,iBAAiB;;;;EAU5F,oBAAoB,eAAe,kBAAkB,OAAO,iBAAiB;;;;EAU7E,SAAS;;;;;;;;;;;;;;;;;;UC/PA,4BAA4B;;EAE3C,MAAM,QAAQ;;EAEd,UAAU;;;;;;;EAOV,mBAAmB,YAAY;;;;;;;;;;;;EAY/B,gBAAgB;;;;;;;EAOhB,aAAa;;;;;;;;;;EAUb;;;;;qBAMW;UAGS;UAFZ;EAER,YAAoB,QAAQ;;;;EAK5B,iBAAiB,GAAG,OAAO,eAAe,KAAK,wBAAwB;;;;;;EASvE,oBAAoB,GAAG,UAAU,uBAAuB;;;;EAQxD,QAAQ,KAAK,QAAQ;UAKP;;;;;;EAaR,WAAW,QAAQ;;;;;;;;UAiLX;;;;UA4CN;;;;;;;UC/VO,uBAAuB;EACtC,OAAO,eAAe;EACtB;EACA,gBAAgB,aAAa,oBAAoB,OAAO,WAAW,cAAc,KAAK,eAAe;;;;;;;;;;;;;;;;;qBAkB1F,wBAAwB;mBAEhB;mBACA;EAFnB,YACmB,QAAQ,sBACR,OAAO,eAAe;;;;;;;;;EAWzC,SAAS,OAAO,IAAI;;;;;;;;;EAgBpB,SAAS,aAAa,oBAAoB,IAAI;;;;;;;;;EAgB9C,WAAW,UAAU,WAAW,cAAc,IAAI;;;;;;;;;;;;;;;;;;;EA0BlD,YAAY,eAAe,eAAe,KAAK;;;;;;;;;;;;;;;;;;;;;;;;qBC7EpC;;;;;iBAKI;;;;;;;SAQR,eAAe,UAAU,cAAc;;;;SAOvC,mBAAmB,cAAc;;;;;;;SAUjC,oBAAoB,QAAQ,sBAAsB;;;;;;;wBClD3C,eAAe,cAAc;;;;wBAiB7B,eAAe,cAAc;;;;;;UCjB5B;;;;;EAKhB;;;;EAKA,UAAU;;;;EAKV;;;;;EAMA;;;;;EAMA;;;;;UAMgB;;;;EAIhB,UAAU;;;;;EAMV;;;;;EAMA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;qBCpBY;UACH;EAER,YAAY,WAAU;;EAKtB;;EAKA;;EAKA;;EAKA,OAAO,UAAU;;;;;;;;;;;;;;EAiBjB,iBAAiB,aAAa,MAAM,qCAAqC,UAAS;;;;;;;;;;;;;;;EAyBlF,UAAU,aAAa,gBAAgB,kBAAkB,UAAS;;;;;;;;;;;;;;;;;;;wBA4BpD,gBAAgB,WAAW,mBAAmB;;;;;;;;;;;;;;;qBCxFjD;mBACkB;EAA7B,YAA6B,aAAa;EAEpC,qBAAqB;IAAQ;MAAe,QAAQ;;;;;;;;qBCpC/C,kBAAkB;WAGX,QAAQ;EAF1B,YACE,iBACgB,QAAQ;;;;;;;;qBCDf,uBAAuB;EAClC,YAAY,iBAAiB,QAAQ"}
|